SpringBoot与Vue前后端交互问题

在vue中找到vue.config.js文件中,加入下列代码:

const { defineConfig } = require('@vue/cli-service')

module.exports = defineConfig({
  devServer: {
    port:8888,//修改前端应用的端口号(可以改为你想改的任意数字,不要与后端冲突就行)
    proxy: {
      // 配置代理,解决跨域问题
      '/api': {
        target: 'http://localhost:8080',  // 后端接口的基础 URL
        changeOrigin: true,  // 是否改变请求头中的 Origin 字段
        pathRewrite: {
          '^/api': ''  // 将请求路径中的 '/api' 替换为空字符串,去除 '/api' 前缀
        }
      }
    }
  }
});

在后端创建CrosConfig文件,导入以下代码

package com.team.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CrosConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("http://localhost:8888/")//端口号需要修改为与前端vue.config.js中相对应的端口号
                .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
                .allowCredentials(true)
                .maxAge(3600)
                .allowedHeaders("*");
    }
}

目录结构为

在前端和后端分别按照以上操作,即可完成前后端交互。

下面是一个示例:

首先创建vue项目

选择手动配置项目

选择Babel、Router、Linter和使用配置文件

配置选择

点击创建项目,创建完成。

将router文件夹下的index.js改为下列代码

import Vue from 'vue'
import VueRouter from 'vue-router'
import ShopView from '../views/ShopMenu.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    redirect: "/shop"
  },
  {
    path:'/shop',
    name:'shop',
    component:ShopView
  }
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

export default router

安装element-ui和axios

npm install element-ui@2.15.3
npm install axios

在main.js中添加下列代码

import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);

在views下创建ShopMenu.vue文件

<template>
    <div>
        <el-form :inline="true" :model="searchForm" class="demo-form-inline">
                        <el-form-item label="名称">
                            <el-input v-model="searchForm.name" placeholder="名称"></el-input>
                        </el-form-item>
                        <el-form-item label="地址">
                            <el-input v-model="searchForm.address" placeholder="地址"></el-input>
                        </el-form-item>
                        <el-form-item label="面积">
                            <el-input v-model="searchForm.size" placeholder="面积"></el-input>
                        </el-form-item>
                        <el-form-item>
                            <el-button type="primary" @click="onSubmit">查询</el-button>
                        </el-form-item>
                    </el-form>

                    <el-row>
                        <el-button type="danger" plain @click="deleteByIds" style="float: left;">批量删除</el-button>
                        <el-button type="primary" plain @click="dialogVisible = true" style="float: left;">新增</el-button>
                    </el-row>

                    <el-dialog title="新增门店" :visible.sync="dialogVisible" width="30%">
                        <el-form ref="form" :model="shopadd" label-width="100px">
                            <el-form-item label="门店名称">
                                <el-input v-model="shopadd.name"></el-input>
                            </el-form-item>
                            <el-form-item label="地址">
                                <el-input v-model="shopadd.address"></el-input>
                            </el-form-item>
                            <el-form-item label="面积">
                                <el-input v-model="shopadd.size" placeholder="(平方米)"></el-input>
                            </el-form-item>
                            <el-form-item>
                                <el-button type="primary" @click="addshop">确定</el-button>
                                <el-button @click="dialogVisible = false">返回</el-button>
                            </el-form-item>
                        </el-form>
                    </el-dialog>

                    <el-table :data="tableData" @selection-change="handleSelectionChange">
                        <el-table-column type="selection" width="55">
                        </el-table-column>
                        <el-table-column prop="name" label="门店名称" width="180"></el-table-column>
                        <el-table-column prop="address" label="地点" width="180"></el-table-column>
                        <el-table-column prop="size" label="面积(平方米)" width="180">
                        </el-table-column>
                        <el-table-column align="center" label="操作">
                            <template slot-scope="scope">
                                <el-button type="primary" size="small" @click="editStore(scope.row.id)">编辑</el-button>
                                <el-button type="danger" size="small" @click="deleteStore(scope.row.id)">删除</el-button>
                            </template>
                        </el-table-column>
                    </el-table>
                    <br>
                    <el-dialog title="修改门店信息" :visible.sync="dialogVisible1" width="30%">
                        <el-form ref="form" :model="shopupdate" label-width="100px">
                            <el-form-item label="门店名称">
                                <el-input v-model="shopupdate.name"></el-input>
                            </el-form-item>
                            <el-form-item label="地址">
                                <el-input v-model="shopupdate.address"></el-input>
                            </el-form-item>
                            <el-form-item label="面积">
                                <el-input v-model="shopupdate.size" placeholder="(平方米)"></el-input>
                            </el-form-item>
                            <el-form-item>
                                <el-button type="primary" @click="updateshop">确定</el-button>
                                <el-button @click="dialogVisible1 = false">返回</el-button>
                            </el-form-item>
                        </el-form>
                    </el-dialog>

                    <!-- 分页条 -->
                    <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
                        :current-page="currentPage" :page-sizes="[5, 10, 15, 20]" :page-size="pageSize"
                        layout="total, sizes, prev, pager, next, jumper" :total="totalCount">
                    </el-pagination>  
    </div>
</template>

<script>
import axios from 'axios';
export default {
    name: 'VueShop',
    data() {
        return {
            totalCount: 1000,
            // 当前页码
            currentPage: 1,
            pageSize: 5,
            tableData: [
                {
                    name: '1',
                    address: '北京市',
                    size: '600',
                    id: ''
                },
            ],
            dialogVisible: false,
            dialogVisible1: false,
            searchForm: {
                name: "",
                address: "",
                size: ""
            },
            shopadd: {
                name: "",
                address: "",
                size: ""
            },
            shop: {
                name: "",
                address: "",
                size: ""
            },
            shopupdate: {
                name: "",
                address: "",
                size: ""
            }
        }
    },
    mounted() {
        this.onSubmit();
    },
    methods: {
        onSubmit() {
            const params = {
                name: this.searchForm.name || null,
                address: this.searchForm.address || null,
                size: this.searchForm.size || null,
                pageSize: this.pageSize, // 每页显示条数
                page: this.currentPage // 当前页码
            };
            axios.get('http://localhost:8080/store/select', { params })
                .then(response => {
                    // 处理查询结果
                    console.log(response.data);
                    this.tableData = response.data.rows;
                    this.totalCount = response.data.total;
                })
                .catch(error => {
                    // 处理错误
                    console.error(error);
                });
        },
        logout() {
            this.$router.push({ path: "/login" });
        },
        deleteStore(id) {
            console.log(id);
            this.$confirm('此操作将删除该数据, 是否继续?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                axios.delete(`http://localhost:8080/store/${id}`)
                    .then(response => {
                        // 删除成功后的处理逻辑
                        console.log(response);
                        this.$message.success('门店删除成功');
                        this.onSubmit();
                        // 在此处执行其他逻辑,例如重新加载员工列表等
                    })
                    .catch(error => {
                        // 删除失败后的处理逻辑
                        this.$message.error('门店删除失败');
                        console.error(error);
                    });
            }).catch(() => {
                // 取消删除时的处理逻辑
                this.$message.info('已取消删除');
            });
        },
        editStore(row) {
            console.log(row);
            // 根据id从后端查询门店信息
            axios.get(`http://localhost:8080/store/select/${row}`)
                .then(response => {
                    console.log(response.data);
                    // 将查询到的员工信息回显到编辑表单中
                    this.shopupdate = response.data;
                    this.dialogVisible1 = true; // 打开编辑对话框
                })
                .catch(error => {
                    console.error(error);
                });
        },
        addshop() {
            const params = {
                name: this.shopadd.name,
                address: this.shopadd.address,
                size: this.shopadd.size,
            };

            // 发送添加门店请求
            axios.post('http://localhost:8080/store/add', params)
                .then(response => {
                    // 处理添加门店成功的逻辑
                    console.log('添加门店成功', response);
                    // 关闭对话框
                    this.$message({
                        message: '恭喜你,添加成功',
                        type: 'success'
                    });

                    this.dialogVisible = false;
                    // 清空表单数据
                    this.shopadd = {};
                    // 刷新员工列表等操作
                    // ...
                    this.onSubmit();
                })
                .catch(error => {
                    // 处理添加门店失败的逻辑
                    console.error('添加门店失败', error);
                    // 显示错误提示等操作
                    this.onSubmit();
                    // ...
                });
        },

        deleteByIds() {
            const ids = this.multipleSelection.map(item => item.id);
            console.log(ids);
            this.$confirm('此操作将删除该数据, 是否继续?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                axios.delete(`http://localhost:8080/store/${ids.join(',')}`)
                    .then(response => {
                        // 处理删除成功的逻辑
                        console.log('删除成功', response.data);
                        this.$message({
                            message: '恭喜你,删除成功',
                            type: 'success'
                        });
                        this.onSubmit();
                    })
                    .catch(error => {
                        // 处理删除失败的逻辑
                        console.error('删除失败', error);
                    });
            }).catch(() => {
                this.$message.info('已取消删除');
            })
        },
        updateshop() {
            const requestBody = {
                // 根据后端接口的定义,传递需要更新的门店信息
                name: this.shopupdate.name,
                address: this.shopupdate.address,
                size: this.shopupdate.size,
            };
            axios.put(`http://localhost:8080/store/update/` + this.shopupdate.id, requestBody)
                .then(response => {
                    console.log(response); // 打印响应信息
                    this.dialogVisible1 = false; // 关闭编辑对话框
                    // 刷新表格数据等操作
                    this.onSubmit();
                    this.$message.success('门店信息更新成功!');
                })
                .catch(error => {
                    console.error(error); // 打印错误信息
                    this.$message.error('门店信息更新失败,请重试!');
                });
        },
        handleSizeChange(size) {
            // 处理每页显示条数变更事件
            this.pageSize = size;

            // 这里可以重新调用查询接口获取当前页数据
            // ...
            this.onSubmit();
        },
        handleCurrentChange(currentPage) {
            // 处理页码变更事件
            this.currentPage = currentPage;

            // 这里可以重新调用查询接口获取当前页数据
            // ...
            this.onSubmit();
        },
        handleSelectionChange(val) {
            this.multipleSelection = val;
        }
    }
};
</script>

<style lang="scss" scoped>

</style>

后端用springboot创建

不会用springboot创建项目的可以看   2020版IDEA创建springboot项目

 

创建完项目后数据库的配置 在application.properties文件中添加如下代码

#数据库连接
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/scheduling
spring.datasource.username=root
spring.datasource.password=123456

#开启mybatis的日志输出
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

#开启数据库表字段 到 实体类属性的驼峰映射
mybatis.configuration.map-underscore-to-camel-case=true

在pom.xml文件中导入lombok和pageHelper

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.4.2</version>
        </dependency>

后端目录结构

StoreController

package com.ysk.controller;


import com.ysk.pojo.PageBean;
import com.ysk.pojo.Result;
import com.ysk.pojo.Store;
import com.ysk.service.StoreService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Slf4j
@RestController
@RequestMapping("/store")
public class StoreController {

    @Autowired
    private StoreService storeService;

    @GetMapping("/select")
    public PageBean page(@RequestParam(defaultValue = "1") Integer page,
                         @RequestParam(defaultValue = "5") Integer pageSize,
                         String name, String address, Double size){

        log.info("分页查询,参数:{},{},{},{},{}", page, pageSize,name,address,size);
        PageBean pageBean = storeService.page(page, pageSize,name,address,size);
        return pageBean;
    }

    @PostMapping("/add")
    public Result save(@RequestBody Store store){
        log.info("新增门店,stuff:{}",store);
        storeService.save(store);
        return Result.success();
    }


    //批量删除
    @DeleteMapping("/{ids}")
    public Result delete(@PathVariable List<Integer> ids){
        storeService.delete(ids);
        return Result.success();
    }

    @GetMapping("/select/{id}")
    public Store getStoreById(@PathVariable Integer id) {
        // 在这里可以根据 userId 和 userName 进行身份验证或其他操作
        // 假设 userService 提供了获取用户信息的方法
        return storeService.getByStoreId(id);
    }

    @PutMapping("/update/{id}")
    public Result update(@PathVariable("id") Integer id,@RequestBody Store store){
        Store existingEmp = storeService.getByStoreId(id);
        if (existingEmp != null) {
            existingEmp.setName(store.getName());
            existingEmp.setAddress(store.getAddress());
            existingEmp.setSize(store.getSize());

            storeService.update(existingEmp);
            return Result.success();
        } else {
            return Result.error("门店信息不存在");
        }
    }

    @GetMapping("/data")
    public Store getDataByStore(@RequestParam("id") Integer id){
            return storeService.getByStoreId(id);
    }
}

StoreMapper

package com.ysk.mapper;

import com.ysk.pojo.Store;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.List;

@Mapper
public interface StoreMapper {

    public List<Store> list(String name,String address,Double size);

    @Insert("insert into store(name,address,size) value (#{name},#{address},#{size})")
    public void insert(Store store);

    public void delete(List<Integer> ids);

    @Select("select * from store where id =#{id}")
    public Store getStuffById(Integer id);

    public void update(Store store);
}

PageBean

package com.ysk.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageBean {
    private Long total;
    private List rows;
}

Result

package com.ysk.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {
    private Integer code;//响应码,1 代表成功; 0 代表失败
    private String msg;  //响应信息 描述字符串
    private Object data; //返回的数据

    //增删改 成功响应
    public static Result success(){
        return new Result(1,"success",null);
    }
    //查询 成功响应
    public static Result success(Object data){
        return new Result(1,"success",data);
    }
    //失败响应
    public static Result error(String msg){
        return new Result(0,msg,null);
    }
}

Store

package com.ysk.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor

public class Store {
    //店的id
    private Integer id;

    //用于展示的数据
    private String name;//店的名字
    private String address;//店的地址

    //用于计算的数据
    private Double size;//店的面积

    private Double preDivisorValue;//开店前准备除数的权值

    private Integer freePopulationNum;//店空闲时需要的人数

    private Double aftDivisorValue;//关店后准备除数的权值
    private Integer aftAddValue;//关店后准备加数的权值

    private Integer prePrepareHourNum;//开店之前需要做几小时准备工作
    private Integer aftPrepareHourNum;//关门之后需要做几小时准备工作

    private Double passFlowDivisorValue;//人流量对应店员数的除数权值
}

StoreService

package com.ysk.service;

import com.ysk.pojo.PageBean;
import com.ysk.pojo.Store;
import com.ysk.pojo.PageBean;

import java.util.List;


public interface StoreService {

    //分页查询
    PageBean page(Integer page, Integer pageSize, String name, String address, Double size);

    //新增门店
    public void save(Store store);

    //删除门店
    public void delete(List<Integer> ids);

    public Store getByStoreId(Integer id);

    public void update(Store store);
}

StoreServiceImpl

package com.ysk.service.Impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.ysk.mapper.StoreMapper;
import com.ysk.pojo.PageBean;
import com.ysk.pojo.Store;
import com.ysk.service.StoreService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Slf4j
@Service
public class StoreServiceImpl implements StoreService {


    @Autowired
    private StoreMapper storeMapper;

    @Override
    public PageBean page(Integer page, Integer pageSize, String name, String address, Double size) {
        PageHelper.startPage(page,pageSize);

        List<Store> storeList = storeMapper.list(name,address,size);

        Page<Store> s = (Page<Store>) storeList;
        PageBean pageBean = new PageBean(s.getTotal(),s.getResult());
        return pageBean;
    }

    @Override
    public void save(Store store) {
        storeMapper.insert(store);
    }

    @Override
    public void delete(List<Integer> ids) {
        storeMapper.delete(ids);
    }

    @Override
    public Store getByStoreId(Integer id) {
        return storeMapper.getStuffById(id);
    }

    @Override
    public void update(Store store) {
        storeMapper.update(store);
    }


}

运行结果展示

新增

批量删除

修改

后端代码的地址

https://gitee.com/forget1204/2023-4-24

https://github.com/Yskkkkk/2023-4-24backend

前端代码的地址

https://gitee.com/forget1204/2023-4-24-front-end

https://github.com/Yskkkkk/2023-4-24-front-end

posted @ 2023-04-24 16:24  万事胜意k  阅读(1174)  评论(0编辑  收藏  举报