【学生管理系统】学生管理(重点)

2年前其他教程5886
【学生管理系统】学生管理(重点) 陶然同学 于2022-10-18 14:37:36发布 567 收藏 9 分类专栏: 学生管理系统 文章标签: java spring boot spring 学生管理系统 专栏收录该内容 6 篇文章 0 订阅 订阅专栏

目录

4. 学生管理

4.1 需求

4.1.1 查询所有

4.1.2 添加:基本信息

4.1.3 添加:级联城市

4.1.4 添加:选课

4.2 环境搭建

4.2.1 前端环境

4.2.2 学生后端环境(9020)

4.2.3 课程后端环境(9030)

4.3 查询所有

4.3.1 基本功能:后端实现

4.3.2 基本功能:前端实现

4.3.3 班级:后端实现

4.3.4 班级:前端实现

4.3.5 选课详情:后端实现

4.3.6 选课详情:前端实现

4.5 添加

4.5.0 分析

4.5.1 基本操作

4.5.2 级联城市

4.5.2 选课

4. 6 修改

4.6.1 分析

4.5.2 查询详情

4.5.3 更新添加功能

4. 学生管理 4.1 需求 4.1.1 查询所有

 

4.1.2 添加:基本信息

 

4.1.3 添加:级联城市

 

 

4.1.4 添加:选课

 

4.2 环境搭建 4.2.1 前端环境

4.2.2 学生后端环境(9020)

项目名:nacos-nuxt-student-service-student

pom文件

yml文件

启动类

拷贝配置类

基本结构

pom文件

​    <dependencies>        <!--web起步依赖-->        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-web</artifactId>        </dependency>        <!-- nacos 客户端 -->        <dependency>            <groupId>com.alibaba.nacos</groupId>            <artifactId>nacos-client</artifactId>        </dependency> ​        <!-- nacos 服务发现 -->        <dependency>            <groupId>com.alibaba.cloud</groupId>            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>        </dependency> ​        <!--swagger2-->        <dependency>            <groupId>io.springfox</groupId>            <artifactId>springfox-swagger2</artifactId>        </dependency>        <dependency>            <groupId>io.springfox</groupId>            <artifactId>springfox-swagger-ui</artifactId>        </dependency> ​        <!-- feign 远程调用 -->        <dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-starter-openfeign</artifactId>        </dependency> ​        <!--测试-->        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-test</artifactId>        </dependency> ​        <!-- mybatis plus-->        <dependency>            <groupId>com.baomidou</groupId>            <artifactId>mybatis-plus-boot-starter</artifactId>        </dependency>        <!-- mysql驱动 -->        <dependency>            <groupId>mysql</groupId>            <artifactId>mysql-connector-java</artifactId>        </dependency>        <!--自定义项目-->        <dependency>            <groupId>com.czxy</groupId>            <artifactId>nacos-nuxt-student-domain</artifactId>        </dependency> ​        <!-- redis 启动器 -->        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-data-redis</artifactId>        </dependency>        <!-- JavaMail 启动器 -->        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-mail</artifactId>        </dependency>        <!-- MQ 启动器 -->        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-amqp</artifactId>        </dependency> ​        <!-- fastjson -->        <dependency>            <groupId>com.alibaba</groupId>            <artifactId>fastjson</artifactId>        </dependency> ​        <!--开发者工具-->        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-devtools</artifactId>            <optional>true</optional>        </dependency> ​        <!--jwt工具-->        <dependency>            <groupId>io.jsonwebtoken</groupId>            <artifactId>jjwt</artifactId>        </dependency>        <!--joda 时间工具类 -->        <dependency>            <groupId>joda-time</groupId>            <artifactId>joda-time</artifactId>        </dependency>        <!--JavaBean工具类,用于JavaBean数据封装-->        <dependency>            <groupId>commons-beanutils</groupId>            <artifactId>commons-beanutils</artifactId>        </dependency> ​    </dependencies> ​

yml文件

# 服务端口号 server: port: 9020 # 服务名 spring: application:   name: student-service datasource:   driverClassName: com.mysql.jdbc.Driver   url: jdbc:mysql://127.0.0.1:3306/cloud_es_student?useUnicode=true&characterEncoding=utf8   username: root   password: 1234   druid:    #druid 连接池配置     initial-size: 1       #初始化连接池大小     min-idle: 1           #最小连接数     max-active: 20        #最大连接数     test-on-borrow: true  #获取连接时候验证,会影响性能 cloud:   nacos:     discovery:       server-addr: 127.0.0.1:8848   #nacos服务地址 ​ #开启log4j打印SQL语句 logging: level:   com:     czxy:       student:         mapper: debug ​ # mp日志打印 mybatis-plus: configuration:   log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config:   db-config:     logic-delete-value: 1     logic-not-delete-value: 0 ​ sc: jwt:   secret: sc@Login(Auth}*^31)&czxy% # 登录校验的密钥   pubKeyPath: D:/rsa/rsa.pub # 公钥地址   priKeyPath: D:/rsa/rsa.pri # 私钥地址   expire: 360 # 过期时间,单位分钟

启动类

package com.czxy; ​ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; ​ /** * @author 桐叔 * @email liangtong@itcast.cn * @description */ @SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class StudentServiceApplication {    public static void main(String[] args) {        SpringApplication.run(StudentServiceApplication.class, args);   } } ​

配置类

 

基本结构

 

4.2.3 课程后端环境(9030)

项目名:nacos-nuxt-student-service-course

 

4.3 查询所有 4.3.1 基本功能:后端实现

编写Vo

编写controller

编写service

编写Vo

package com.czxy.student.vo; ​ import lombok.Data; ​ /** * @author 桐叔 * @email liangtong@itcast.cn * @description */ @Data public class StudentVo {    private String classesId;           //班级    private String sname;               //姓名    private String startAge;            //开始年龄    private String endAge;              //结束年龄 } ​

编写controller

 

   @PostMapping("/condition/{size}/{current}")    public BaseResult condition(            @RequestBody StudentVo studentVo,            @PathVariable("size") Integer size,            @PathVariable("current") Integer current           ) {        // 查询        Page<TbStudent> page = tbStudentService.condition(studentVo, size, current); ​        // 返回        return BaseResult.ok("查询成功", page);   }

编写service

接口

Page<TbStudent> condition(StudentVo studentVo, Integer size, Integer current);

实现类

@Override    public Page<TbStudent> condition(StudentVo studentVo, Integer size, Integer current) {        //1 条件        QueryWrapper<TbStudent> queryWrapper = new QueryWrapper<>();        if(StringUtils.isNotBlank(studentVo.getClassesId())) {            queryWrapper.eq("c_id", studentVo.getClassesId());       }        if(StringUtils.isNotBlank(studentVo.getSname())) {            queryWrapper.like("sname", studentVo.getSname());       }        if(StringUtils.isNotBlank(studentVo.getStartAge())) {            queryWrapper.ge("age", studentVo.getStartAge());       }        if(StringUtils.isNotBlank(studentVo.getEndAge())) {            queryWrapper.le("age", studentVo.getEndAge());       } ​        //2 分页        Page<TbStudent> page = new Page<>(current, size); ​        //3 查询        baseMapper.selectPage(page, queryWrapper); ​        //4 关联 ​        //5 返回        return page;   }

4.3.2 基本功能:前端实现

列表

条件

分页

列表

<template>  <div>    <!-- 添加按钮 -->    <el-button type="primary" @click="openStudentDialog">添加</el-button> ​    <!-- 列表start -->    <el-table      :data="studentPage.records"      stripe      style="width: 100%">      <el-table-column        type="selection"        width="55">      </el-table-column>      <el-table-column        prop="sid"        label="学生ID"        fixed        width="180">      </el-table-column>      <el-table-column        prop="cid"        label="班级名称"        fixed        width="180">      </el-table-column>      <el-table-column        prop="sname"        label="学生姓名"        width="180">      </el-table-column>      <el-table-column        prop="age"        label="年龄"        width="180">      </el-table-column>      <el-table-column        prop="birthday"        label="生日"        width="180">      </el-table-column>      <el-table-column        prop="gender"        label="性别"        width="180">        <template slot-scope="scope">          {{scope.row.gender == 1 ? '男': '女'}}        </template>      </el-table-column>      <el-table-column        prop="courseCount"        label="选课数"        width="180">      </el-table-column>      <el-table-column        prop="courseList"        label="选课详情"        width="180">      </el-table-column>      <el-table-column        label="操作"        fixed="right"        width="180">        <template slot-scope="scope">          <el-button size="mini">编辑</el-button>          <el-button size="mini" type="danger">删除</el-button>        </template>      </el-table-column>    </el-table>    <!-- 列表end --> ​ ​    <!-- 弹出框 start -->    <el-dialog title="添加学生" :visible.sync="dialogStudentVisible">      <el-form :model="student" label-width="80px">        <el-form-item label="班级名称">          <el-select v-model="student.cid" placeholder="请选择班级">            <el-option v-for="(classes,index) in classesList" :key="index" :label="classes.cname" :value="classes.cid"></el-option>          </el-select>        </el-form-item>        <el-form-item label="选择城市">          <el-cascader v-model="student.cids" :props="cityProps"></el-cascader>        </el-form-item>        <el-form-item label="姓名">          <el-input v-model="student.sname"></el-input>        </el-form-item>        <el-form-item label="年龄">          <el-input v-model="student.age"></el-input>        </el-form-item>        <el-form-item label="生日">          <el-date-picker            v-model="student.birthday"            value-format="yyyy-MM-dd"            type="date"            placeholder="请选择学生生日">          </el-date-picker>        </el-form-item>        <el-form-item label="性别">          <el-radio-group v-model="student.gender">            <el-radio :label="1">男</el-radio>            <el-radio :label="0">女</el-radio>          </el-radio-group>        </el-form-item>        <el-form-item label="选课">          <el-checkbox-group v-model="student.courseIds">            <el-checkbox v-for="(course,index) in courseList" :key="index" :label="course.cid">{{course.cname}}</el-checkbox>          </el-checkbox-group>        </el-form-item>      </el-form>     {{student}}      <div slot="footer" class="dialog-footer">        <el-button @click="dialogStudentVisible = false">取 消</el-button>        <el-button type="primary" @click="addStudent">确 定</el-button>      </div>    </el-dialog>    <!-- 弹出框 end -->  </div> </template> ​ <script> let _vue = null export default {  data() {    _vue = this                             //缓存vue对象    return {      dialogStudentVisible: false,          //学生弹出框控制变量      student: {        cids: [],        courseIds: []     },      classesList: [],                      //班级列表      cityProps: {                          //城市级联菜单的属性设置        lazy: true,                         //开启        async lazyLoad (node, resolve) {          //加载数据          // 1. 如果 node.root == true 表示第一次加载,也就是省          let parentId = null          if(node.root == true) {            parentId = "0"         } else {            // 其他 - node.value可以获得当前节点的id的值,例如:省的id            parentId = node.value         }          console.info(node) ​          // 2. ajax 查询所有的城市          let { data:baseResult } = await _vue.$axios.get(`/student-service/city/${parentId}`) ​          // 处理查询结果,如果是县,表示是叶子          baseResult.data.forEach(city=>{            city.leaf = node.level >=2         })          // 通过调用resolve将子节点数据返回,通知组件数据加载完成          resolve(baseResult.data);       },        label: 'cityName',        value: 'cid'     },      courseList: [],                       //课程列表      studentVo: {                          //条件        "classesId": "",        "endAge": "",        "sname": "",        "startAge": ""     },      studentPage: {                        //结果 + 分页        size: 3,        current: 1,        total: 0     }   } },    methods: {    openStudentDialog() {      // 查询所有的班级      this.findAllClasses()      // 查询所有的选课      this.findAllCourse() ​      // 控制变量      this.dialogStudentVisible = true   },    async findAllClasses() {      // ajax      let { data: baseResult } = await this.$axios.get('/classes-service/classes')      // 处理      if(baseResult.code == 20000) {        this.classesList = baseResult.data     } else {        this.$message.error(baseResult.message)     }   },    async addStudent() {      // 处理所选城市数据 数组转字符串, [1,2,3] --> 1,2,3      this.student.cityIds = this.student.cids.join(',')      // 发送ajax      let {data:baseResult} = await this.$axios.post('/student-service/student', this.student)      if(baseResult.code == 20000) {        //成功        this.$message.success(baseResult.message)        //刷新列表        this.conditionStudent()        //关闭弹出框        this.dialogStudentVisible = false     } else {        // 失败        this.$message.error(baseResult.message)     }   },    async findAllCourse() {      let {data:baseResult} = await this.$axios.get('/course-service/course')      this.courseList = baseResult.data   },    async conditionStudent() {      // 查询      let url = `/student-service/student/condition/${this.studentPage.size}/${this.studentPage.current}`      let { data: baseResult} = await this.$axios.post(url, this.studentVo)      // 处理结果      this.studentPage = baseResult.data   } },  mounted() {    // 查询所有的学生    this.conditionStudent() }, } </script> ​ <style> ​ </style>

条件

 

   <el-row>      <el-col :span="2">        <!-- 添加按钮 -->        <el-button type="primary" size="mini" @click="openStudentDialog">添加</el-button>      </el-col>      <el-col :span="22">        <!-- 条件查询start -->        <el-form :inline="true" :model="studentVo" size="mini" class="demo-form-inline">          <el-form-item label="班级">            <el-select v-model="studentVo.classesId" placeholder="请选择班级">              <el-option v-for="(classes,index) in classesList" :key="index" :label="classes.cname" :value="classes.cid"></el-option>            </el-select>          </el-form-item>          <el-form-item label="姓名">            <el-input v-model="studentVo.sname" placeholder="请输入姓名"></el-input>          </el-form-item>          <el-form-item label="姓名">            <el-row>              <el-col :span="11">                <el-input v-model="studentVo.startAge" placeholder="请输入开始年龄"></el-input>              </el-col>              <el-col :span="2" style="text-align: center;">-</el-col>              <el-col :span="11">                <el-input v-model="studentVo.endAge" placeholder="请输入结束年龄"></el-input>              </el-col>            </el-row>          </el-form-item>          <el-form-item>            <el-button type="primary" @click="conditionStudent(1)">查询</el-button>          </el-form-item>        </el-form>        <!-- 条件查询end -->      </el-col>    </el-row>

分页

 

   <!-- 分页 start -->    <el-pagination      @size-change="handleSizeChange"      @current-change="handleCurrentChange"      :current-page="studentPage.current"      :page-sizes="[1, 2, 3, 5, 10]"      :page-size="studentPage.size"      layout="total, sizes, prev, pager, next, jumper"      :total="studentPage.total">    </el-pagination>    <!-- 分页 end --> ​ <script> ​ export default {    methods: {   handleSizeChange(val) {     console.log(`每页 ${val} 条`);     this.studentPage.size = val     this.studentPage.current = 1     this.conditionStudent()   },   handleCurrentChange(val) {     console.log(`当前页: ${val}`);     this.studentPage.current = val     this.conditionStudent()   }   } } </script>

4.3.3 班级:后端实现

班级服务:查询详情

学生服务:

检查student对象,是否有班级对象

编写feign调用查询详情

修改service,给student填充班级信息

班级服务:查询详情

 

   @GetMapping("/{cid}")    public BaseResult<TbClass> findById(@PathVariable("cid") Integer cid) {        // 查询详情        TbClass tbClass = tbClassesService.getById(cid);        // 返回        return BaseResult.ok("查询成功", tbClass);   }

学生服务:

检查student对象,是否有班级对象

 

编写feign调用查询详情

 

package com.czxy.student.feign; ​ import com.czxy.domain.TbClass; import com.czxy.vo.BaseResult; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; ​ /** * @author 桐叔 * @email liangtong@itcast.cn * @description */ @FeignClient(value = "classes-service", path = "/classes") public interface ClassesFeign { // 必须有泛型,否则获得的数据不是TbClass而是Map    @GetMapping("/{cid}")    public BaseResult<TbClass> findById(@PathVariable("cid") Integer cid) ; } ​

修改service,给student填充班级信息

   @Override    public Page<TbStudent> condition(StudentVo studentVo, Integer size, Integer current) {        //1 条件        QueryWrapper<TbStudent> queryWrapper = new QueryWrapper<>();        if(StringUtils.isNotBlank(studentVo.getClassesId())) {            queryWrapper.eq("c_id", studentVo.getClassesId());       }        if(StringUtils.isNotBlank(studentVo.getSname())) {            queryWrapper.like("sname", studentVo.getSname());       }        if(StringUtils.isNotBlank(studentVo.getStartAge())) {            queryWrapper.ge("age", studentVo.getStartAge());       }        if(StringUtils.isNotBlank(studentVo.getEndAge())) {            queryWrapper.le("age", studentVo.getEndAge());       } ​        //2 分页        Page<TbStudent> page = new Page<>(current, size); ​        //3 查询        baseMapper.selectPage(page, queryWrapper); ​        //4 关联        page.getRecords().forEach(student -> {            // 4.1 处理对应班级信息            BaseResult<TbClass> classesBaseResult = classesFeign.findById(student.getCid());            TbClass tbClass = classesBaseResult.getData();            student.setTbClass(tbClass); ​       }); ​        //5 返回        return page;   }

4.3.4 班级:前端实现

 

     <el-table-column        label="班级名称"        fixed        width="180">        <template slot-scope="scope">          {{scope.row.tbClass ? scope.row.tbClass.cname : ''}}        </template>      </el-table-column>

4.3.5 选课详情:后端实现

课程服务:查找指定学生的选课

mapper:sql语句多表查询

service

controller

学生服务

编写CourseFeign

修改学生service,完善级联操作

==异常==:先完成添加,再完成查询时,会存在一个服务,编写2个feign情况,启动时会有异常。

 

课程服务:查找指定学生的选课

mapper:sql语句多表查询

package com.czxy.course.mapper; ​ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.czxy.domain.TbCourse; import com.czxy.domain.TbStudent; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; ​ import java.util.List; ​ /** * @author 桐叔 * @email liangtong@itcast.cn * @description */ @Mapper public interface TbCourseMapper extends BaseMapper<TbCourse> { ​    /**     * 查询指定学生的选课     * @author 桐叔     * @email liangtong@itcast.cn     * @return     */    @Select("SELECT c.* FROM tb_course c, tb_student_course sc WHERE c.c_id = sc.c_id AND sc.s_id = #{sid}")    public List<TbCourse> findAllByStudentId(@Param("sid") Integer sid); } ​

service

接口

package com.czxy.course.service; ​ import com.baomidou.mybatisplus.extension.service.IService; import com.czxy.domain.TbCourse; import org.apache.ibatis.annotations.Param; ​ import java.util.List; ​ /** * @author 桐叔 * @email liangtong@itcast.cn * @description */ public interface TbCourseService extends IService<TbCourse> { ​    public List<TbCourse> findAllByStudentId(Integer sid); } ​

实现类

package com.czxy.course.service.impl; ​ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.czxy.course.mapper.TbCourseMapper; import com.czxy.course.service.TbCourseService; import com.czxy.domain.TbCourse; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; ​ import java.util.List; ​ /** * @author 桐叔 * @email liangtong@itcast.cn * @description */ @Service @Transactional public class TbCourseServiceImpl extends ServiceImpl<TbCourseMapper, TbCourse> implements TbCourseService {    @Override    public List<TbCourse> findAllByStudentId(Integer sid) {        return baseMapper.findAllByStudentId(sid);   } } ​

controller

package com.czxy.course.controller; ​ import com.czxy.course.service.TbCourseService; import com.czxy.domain.TbCourse; import com.czxy.vo.BaseResult; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; ​ import javax.annotation.Resource; import java.util.List; ​ /** * @author 桐叔 * @email liangtong@itcast.cn * @description */ @RestController @RequestMapping("/course") public class TbCourseController { ​    @Resource    private TbCourseService tbCourseService; ​    @GetMapping("/student/{sid}")    public BaseResult<List<TbCourse>> findAllByStudentId(@PathVariable("sid") Integer sid) {        // 查询        List<TbCourse> courseList = tbCourseService.findAllByStudentId(sid);        // 返回        return BaseResult.ok("查询成功", courseList);   } ​ } ​

学生服务

编写CourseFeign

 

package com.czxy.student.feign; ​ import com.czxy.domain.TbStudentCourse; import com.czxy.vo.BaseResult; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; ​ /** * @author 桐叔 * @email liangtong@itcast.cn * @description */ //@FeignClient(value = "服务名", path = "controller类路径") @FeignClient(value = "course-service", path = "/course") public interface CourseFeign { ​    @GetMapping("/student/{sid}")    public BaseResult<List<TbCourse>> findAllByStudentId(@PathVariable("sid") Integer sid); } ​

修改学生service,完善级联操作

   @Override    public Page<TbStudent> condition(StudentVo studentVo, Integer size, Integer current) {        //1 条件        QueryWrapper<TbStudent> queryWrapper = new QueryWrapper<>();        if(StringUtils.isNotBlank(studentVo.getClassesId())) {            queryWrapper.eq("c_id", studentVo.getClassesId());       }        if(StringUtils.isNotBlank(studentVo.getSname())) {            queryWrapper.like("sname", studentVo.getSname());       }        if(StringUtils.isNotBlank(studentVo.getStartAge())) {            queryWrapper.ge("age", studentVo.getStartAge());       }        if(StringUtils.isNotBlank(studentVo.getEndAge())) {            queryWrapper.le("age", studentVo.getEndAge());       } ​        //2 分页        Page<TbStudent> page = new Page<>(current, size); ​        //3 查询        baseMapper.selectPage(page, queryWrapper); ​        //4 关联        page.getRecords().forEach(student -> {            // 4.1 处理对应班级信息            BaseResult<TbClass> classesBaseResult = classesFeign.findById(student.getCid());            TbClass tbClass = classesBaseResult.getData();            student.setTbClass(tbClass); ​            // 4.2 课程详情            BaseResult<List<TbCourse>> courseListBaseResult = courseFeign.findAllByStudentId(student.getSid());            List<TbCourse> courseList = courseListBaseResult.getData();            student.setCourseList(courseList);            student.setCourseCount(courseList.size()); ​       }); ​        //5 返回        return page;   }

 

4.3.6 选课详情:前端实现

<template slot-scope="scope">     <el-tag v-for="(course,index) in scope.row.courseList" :key="index">{{course.cname}}</el-tag> </template>

4.5 添加 4.5.0 分析

 

4.5.1 基本操作

1)后端实现:查询所有的班级

 

   /**     * 查询所有     * @author 桐叔     * @email liangtong@itcast.cn     * @return     */    @GetMapping    public BaseResult findAll() {        // 查询所有        List<TbClass> list = tbClassesService.list();        // 返回        return BaseResult.ok("查询成功", list);   }

2)前端实现:班级列表+表单

展示弹出框

填充表单

展示班级列表

展示弹出框

<template>  <div>    <!-- 添加按钮 -->    <el-button type="primary" @click="dialogStudentVisible = true">添加</el-button> ​ ​    <!-- 弹出框 start -->    <el-dialog title="添加学生" :visible.sync="dialogStudentVisible">      <el-form :model="student" label-width="80px">        <el-form-item label="活动名称">          <el-input v-model="student.name" autocomplete="off"></el-input>        </el-form-item>        <el-form-item label="活动区域">          <el-select v-model="student.region" placeholder="请选择活动区域">            <el-option label="区域一" value="shanghai"></el-option>            <el-option label="区域二" value="beijing"></el-option>          </el-select>        </el-form-item>      </el-form>      <div slot="footer" class="dialog-footer">        <el-button @click="dialogStudentVisible = false">取 消</el-button>        <el-button type="primary" @click="dialogStudentVisible = false">确 定</el-button>      </div>    </el-dialog>    <!-- 弹出框 end -->  </div> </template> ​ <script> export default {  data() {    return {      dialogStudentVisible: true,           //学生弹出框控制变量      student: {             }   } },   } </script> ​ <style> ​ </style>

填充表单

<template>  <div>    <!-- 添加按钮 -->    <el-button type="primary" @click="dialogStudentVisible = true">添加</el-button> ​ ​    <!-- 弹出框 start -->    <el-dialog title="添加学生" :visible.sync="dialogStudentVisible">      <el-form :model="student" label-width="80px">        <el-form-item label="班级名称">          <el-select v-model="student.cid" placeholder="请选择班级">            <el-option label="区域一" value="shanghai"></el-option>          </el-select>        </el-form-item>        <el-form-item label="姓名">          <el-input v-model="student.sname"></el-input>        </el-form-item>        <el-form-item label="年龄">          <el-input v-model="student.age"></el-input>        </el-form-item>        <el-form-item label="生日">          <el-date-picker            v-model="student.birthday"            value-format="yyyy-MM-dd"            type="date"            placeholder="请选择学生生日">          </el-date-picker>        </el-form-item>        <el-form-item label="性别">          <el-radio-group v-model="student.gender">            <el-radio :label="1">男</el-radio>            <el-radio :label="0">女</el-radio>          </el-radio-group>        </el-form-item>      </el-form>      {{student}}      <div slot="footer" class="dialog-footer">        <el-button @click="dialogStudentVisible = false">取 消</el-button>        <el-button type="primary" @click="dialogStudentVisible = false">确 定</el-button>      </div>    </el-dialog>    <!-- 弹出框 end -->  </div> </template> ​ <script> export default {  data() {    return {      dialogStudentVisible: true,           //学生弹出框控制变量      student: {             }   } },   } </script> ​ <style> ​ </style>

展示班级列表

<template>  <div>    <!-- 添加按钮 -->    <el-button type="primary" @click="openStudentDialog">添加</el-button> ​ ​    <!-- 弹出框 start -->    <el-dialog title="添加学生" :visible.sync="dialogStudentVisible">      <el-form :model="student" label-width="80px">        <el-form-item label="班级名称">          <el-select v-model="student.cid" placeholder="请选择班级">            <el-option v-for="(classes,index) in classesList" :key="index" :label="classes.cname" :value="classes.cid"></el-option>          </el-select>        </el-form-item>        <el-form-item label="姓名">          <el-input v-model="student.sname"></el-input>        </el-form-item>        <el-form-item label="年龄">          <el-input v-model="student.age"></el-input>        </el-form-item>        <el-form-item label="生日">          <el-date-picker            v-model="student.birthday"            value-format="yyyy-MM-dd"            type="date"            placeholder="请选择学生生日">          </el-date-picker>        </el-form-item>        <el-form-item label="性别">          <el-radio-group v-model="student.gender">            <el-radio :label="1">男</el-radio>            <el-radio :label="0">女</el-radio>          </el-radio-group>        </el-form-item>      </el-form>      {{student}}      <div slot="footer" class="dialog-footer">        <el-button @click="dialogStudentVisible = false">取 消</el-button>        <el-button type="primary" @click="dialogStudentVisible = false">确 定</el-button>      </div>    </el-dialog>    <!-- 弹出框 end -->  </div> </template> ​ <script> export default {  data() {    return {      dialogStudentVisible: false,           //学生弹出框控制变量      student: {             },      classesList: [],                      //班级   } },    methods: {    openStudentDialog() {      // 查询所有的班级      this.findAllClasses() ​      // 控制变量      this.dialogStudentVisible = true   },    async findAllClasses() {      // ajax      let { data: baseResult } = await this.$axios.get('/classes-service/classes')      // 处理      if(baseResult.code == 20000) {        this.classesList = baseResult.data     } else {        this.$message.error(baseResult.message)     }   } }, } </script> ​ <style> ​ </style>

3)后端实现:基本添加

编写service

编写controller

编写service

接口

 

实现类

@Service @Transactional public class TbStudentServiceImpl extends ServiceImpl<TbStudentMapper, TbStudent> implements TbStudentService {    @Override    public boolean addStudent(TbStudent tbStudent) {        // 保存学生基本信息        int result = baseMapper.insert(tbStudent);        return result == 1;   } }

编写controller

package com.czxy.student.controller; ​ import com.czxy.domain.TbStudent; import com.czxy.student.service.TbStudentService; import com.czxy.vo.BaseResult; import org.springframework.web.bind.annotation.*; ​ import javax.annotation.Resource; import java.util.List; ​ /** * @author 桐叔 * @email liangtong@itcast.cn * @description */ @RestController @RequestMapping("/student") public class TbStudentController { ​    @Resource    private TbStudentService tbStudentService; ​    @PostMapping    public BaseResult save(@RequestBody TbStudent tbStudent) {        // 添加        boolean result = tbStudentService.addStudent(tbStudent);        // 提示        if(result) {            return BaseResult.ok("添加成功");       }        return BaseResult.error("添加失败");   } ​ } ​

4)前端实现:基本添加

<template>  <div>    <!-- 添加按钮 -->    <el-button type="primary" @click="openStudentDialog">添加</el-button> ​ ​    <!-- 弹出框 start -->    <el-dialog title="添加学生" :visible.sync="dialogStudentVisible">      <el-form :model="student" label-width="80px">        <el-form-item label="班级名称">          <el-select v-model="student.cid" placeholder="请选择班级">            <el-option v-for="(classes,index) in classesList" :key="index" :label="classes.cname" :value="classes.cid"></el-option>          </el-select>        </el-form-item>        <el-form-item label="姓名">          <el-input v-model="student.sname"></el-input>        </el-form-item>        <el-form-item label="年龄">          <el-input v-model="student.age"></el-input>        </el-form-item>        <el-form-item label="生日">          <el-date-picker            v-model="student.birthday"            value-format="yyyy-MM-dd"            type="date"            placeholder="请选择学生生日">          </el-date-picker>        </el-form-item>        <el-form-item label="性别">          <el-radio-group v-model="student.gender">            <el-radio :label="1">男</el-radio>            <el-radio :label="0">女</el-radio>          </el-radio-group>        </el-form-item>      </el-form>      {{student}}      <div slot="footer" class="dialog-footer">        <el-button @click="dialogStudentVisible = false">取 消</el-button>        <el-button type="primary" @click="addStudent">确 定</el-button>      </div>    </el-dialog>    <!-- 弹出框 end -->  </div> </template> ​ <script> export default {  data() {    return {      dialogStudentVisible: false,           //学生弹出框控制变量      student: {             },      classesList: [],                      //班级   } },    methods: {    openStudentDialog() {      // 查询所有的班级      this.findAllClasses() ​      // 控制变量      this.dialogStudentVisible = true   },    async findAllClasses() {      // ajax      let { data: baseResult } = await this.$axios.get('/classes-service/classes')      // 处理      if(baseResult.code == 20000) {        this.classesList = baseResult.data     } else {        this.$message.error(baseResult.message)     }   },    async addStudent() {      let {data:baseResult} = await this.$axios.post('/student-service/student', this.student)      if(baseResult.code == 20000) {        //成功        this.$message.success(baseResult.message)        //刷新列表        this.conditionStudent()        //关闭弹出框        this.dialogStudentVisible = false     } else {        // 失败        this.$message.error(baseResult.message)     }   },    conditionStudent() { ​   } }, } </script> ​ <style> ​ </style>

4.5.2 级联城市

1)后端实现

 

   @GetMapping("/{parentId}")    public BaseResult findAllByParentId(@PathVariable("parentId") String parentId) { ​        //1 根据父id查询所有城市        QueryWrapper<TbCity> queryWrapper = new QueryWrapper<>();        queryWrapper.eq("parent_id", parentId);        List<TbCity> list = tbCityService.list(queryWrapper); ​        //2 返回结果        return BaseResult.ok("查询成功", list);   }

2)前端实现

异步加载

完善添加

异步加载

 

<el-form-item label="选择城市">          <el-cascader v-model="student.cids" :props="cityProps"></el-cascader>        </el-form-item> cityProps: {                          //城市级联菜单的属性设置        lazy: true,                         //开启        async lazyLoad (node, resolve) {          //加载数据          // 1. 如果 node.root == true 表示第一次加载,也就是省          let parentId = null          if(node.root == true) {            parentId = "0"         } else {            // 其他 - node.value可以获得当前节点的id的值,例如:省的id            parentId = node.value         }          console.info(node) ​          // 2. ajax 查询所有的城市          let { data:baseResult } = await _vue.$axios.get(`/student-service/city/${parentId}`) ​          // 处理查询结果,如果是县,表示是叶子          baseResult.data.forEach(city=>{            city.leaf = node.level >=2         })          // 通过调用resolve将子节点数据返回,通知组件数据加载完成          resolve(baseResult.data);       },        label: 'cityName',        value: 'cid'     },

完善添加

 

<template>  <div>    <!-- 添加按钮 -->    <el-button type="primary" @click="openStudentDialog">添加</el-button> ​ ​    <!-- 弹出框 start -->    <el-dialog title="添加学生" :visible.sync="dialogStudentVisible">      <el-form :model="student" label-width="80px">        <el-form-item label="班级名称">          <el-select v-model="student.cid" placeholder="请选择班级">            <el-option v-for="(classes,index) in classesList" :key="index" :label="classes.cname" :value="classes.cid"></el-option>          </el-select>        </el-form-item>        <el-form-item label="选择城市">          <el-cascader v-model="student.cids" :props="cityProps"></el-cascader>        </el-form-item>        <el-form-item label="姓名">          <el-input v-model="student.sname"></el-input>        </el-form-item>        <el-form-item label="年龄">          <el-input v-model="student.age"></el-input>        </el-form-item>        <el-form-item label="生日">          <el-date-picker            v-model="student.birthday"            value-format="yyyy-MM-dd"            type="date"            placeholder="请选择学生生日">          </el-date-picker>        </el-form-item>        <el-form-item label="性别">          <el-radio-group v-model="student.gender">            <el-radio :label="1">男</el-radio>            <el-radio :label="0">女</el-radio>          </el-radio-group>        </el-form-item>      </el-form>      {{student}}      <div slot="footer" class="dialog-footer">        <el-button @click="dialogStudentVisible = false">取 消</el-button>        <el-button type="primary" @click="addStudent">确 定</el-button>      </div>    </el-dialog>    <!-- 弹出框 end -->  </div> </template> ​ <script> let _vue = null export default {  data() {    _vue = this                             //缓存vue对象    return {      dialogStudentVisible: false,          //学生弹出框控制变量      student: {        cids: []     },      classesList: [],                      //班级      cityProps: {                          //城市级联菜单的属性设置        lazy: true,                         //开启        async lazyLoad (node, resolve) {          //加载数据          // 1. 如果 node.root == true 表示第一次加载,也就是省          let parentId = null          if(node.root == true) {            parentId = "0"         } else {            // 其他 - node.value可以获得当前节点的id的值,例如:省的id            parentId = node.value         }          console.info(node) ​          // 2. ajax 查询所有的城市          let { data:baseResult } = await _vue.$axios.get(`/student-service/city/${parentId}`) ​          // 处理查询结果,如果是县,表示是叶子          baseResult.data.forEach(city=>{            city.leaf = node.level >=2         })          // 通过调用resolve将子节点数据返回,通知组件数据加载完成          resolve(baseResult.data);       },        label: 'cityName',        value: 'cid'     },   } },    methods: {    openStudentDialog() {      // 查询所有的班级      this.findAllClasses() ​      // 控制变量      this.dialogStudentVisible = true   },    async findAllClasses() {      // ajax      let { data: baseResult } = await this.$axios.get('/classes-service/classes')      // 处理      if(baseResult.code == 20000) {        this.classesList = baseResult.data     } else {        this.$message.error(baseResult.message)     }   },    async addStudent() {      // 处理所选城市数据 数组转字符串, [1,2,3] --> 1,2,3      this.student.cityIds = this.student.cids.join(',')      // 发送ajax      let {data:baseResult} = await this.$axios.post('/student-service/student', this.student)      if(baseResult.code == 20000) {        //成功        this.$message.success(baseResult.message)        //刷新列表        this.conditionStudent()        //关闭弹出框        this.dialogStudentVisible = false     } else {        // 失败        this.$message.error(baseResult.message)     }   },    conditionStudent() { ​   } }, } </script> ​ <style> ​ </style>

4.5.2 选课

1)查询所有课程:后端实现

 

package com.czxy.course.controller; ​ import com.czxy.course.service.TbCourseService; import com.czxy.domain.TbCourse; import com.czxy.vo.BaseResult; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; ​ import javax.annotation.Resource; import java.util.List; ​ /** * @author 桐叔 * @email liangtong@itcast.cn * @description */ @RestController @RequestMapping("/course") public class TbCourseController { ​    @Resource    private TbCourseService tbCourseService; ​    @GetMapping    public BaseResult findAll() {        List<TbCourse> list = tbCourseService.list();        return BaseResult.ok("查询成功",list);   } ​ } ​

2)显示所有课程:前端实现

 

<template>  <div>    <!-- 添加按钮 -->    <el-button type="primary" @click="openStudentDialog">添加</el-button> ​ ​    <!-- 弹出框 start -->    <el-dialog title="添加学生" :visible.sync="dialogStudentVisible">      <el-form :model="student" label-width="80px">        <el-form-item label="班级名称">          <el-select v-model="student.cid" placeholder="请选择班级">            <el-option v-for="(classes,index) in classesList" :key="index" :label="classes.cname" :value="classes.cid"></el-option>          </el-select>        </el-form-item>        <el-form-item label="选择城市">          <el-cascader v-model="student.cids" :props="cityProps"></el-cascader>        </el-form-item>        <el-form-item label="姓名">          <el-input v-model="student.sname"></el-input>        </el-form-item>        <el-form-item label="年龄">          <el-input v-model="student.age"></el-input>        </el-form-item>        <el-form-item label="生日">          <el-date-picker            v-model="student.birthday"            value-format="yyyy-MM-dd"            type="date"            placeholder="请选择学生生日">          </el-date-picker>        </el-form-item>        <el-form-item label="性别">          <el-radio-group v-model="student.gender">            <el-radio :label="1">男</el-radio>            <el-radio :label="0">女</el-radio>          </el-radio-group>        </el-form-item>        <el-form-item label="选课">          <el-checkbox-group v-model="student.courseIds">            <el-checkbox v-for="(course,index) in courseList" :key="index" :label="course.cid">{{course.cname}}</el-checkbox>          </el-checkbox-group>        </el-form-item>      </el-form>      {{student}}      <div slot="footer" class="dialog-footer">        <el-button @click="dialogStudentVisible = false">取 消</el-button>        <el-button type="primary" @click="addStudent">确 定</el-button>      </div>    </el-dialog>    <!-- 弹出框 end -->  </div> </template> ​ <script> let _vue = null export default {  data() {    _vue = this                             //缓存vue对象    return {      dialogStudentVisible: false,          //学生弹出框控制变量      student: {        cids: [],        courseIds: []     },      classesList: [],                      //班级列表      cityProps: {                          //城市级联菜单的属性设置        lazy: true,                         //开启        async lazyLoad (node, resolve) {          //加载数据          // 1. 如果 node.root == true 表示第一次加载,也就是省          let parentId = null          if(node.root == true) {            parentId = "0"         } else {            // 其他 - node.value可以获得当前节点的id的值,例如:省的id            parentId = node.value         }          console.info(node) ​          // 2. ajax 查询所有的城市          let { data:baseResult } = await _vue.$axios.get(`/student-service/city/${parentId}`) ​          // 处理查询结果,如果是县,表示是叶子          baseResult.data.forEach(city=>{            city.leaf = node.level >=2         })          // 通过调用resolve将子节点数据返回,通知组件数据加载完成          resolve(baseResult.data);       },        label: 'cityName',        value: 'cid'     },      courseList: [],                       //课程列表   } },    methods: {    openStudentDialog() {      // 查询所有的班级      this.findAllClasses()      // 查询所有的选课      this.findAllCourse() ​      // 控制变量      this.dialogStudentVisible = true   },    async findAllClasses() {      // ajax      let { data: baseResult } = await this.$axios.get('/classes-service/classes')      // 处理      if(baseResult.code == 20000) {        this.classesList = baseResult.data     } else {        this.$message.error(baseResult.message)     }   },    async addStudent() {      // 处理所选城市数据 数组转字符串, [1,2,3] --> 1,2,3      this.student.cityIds = this.student.cids.join(',')      // 发送ajax      let {data:baseResult} = await this.$axios.post('/student-service/student', this.student)      if(baseResult.code == 20000) {        //成功        this.$message.success(baseResult.message)        //刷新列表        this.conditionStudent()        //关闭弹出框        this.dialogStudentVisible = false     } else {        // 失败        this.$message.error(baseResult.message)     }   },    async findAllCourse() {      let {data:baseResult} = await this.$axios.get('/course-service/course')      this.courseList = baseResult.data   },    conditionStudent() { ​   } }, } </script> ​ <style> ​ </style>

3)中间表:后端基本+添加

 

package com.czxy.course.controller; ​ import com.czxy.course.service.TbStudentCourseService; import com.czxy.domain.TbStudentCourse; import com.czxy.vo.BaseResult; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; ​ import javax.annotation.Resource; ​ /** * @author 桐叔 * @email liangtong@itcast.cn * @description */ @RestController @RequestMapping("/stduentCourse") public class TbStudentCourseController { ​    @Resource    private TbStudentCourseService tbStudentCourseService; ​    @PostMapping    public BaseResult save(@RequestBody TbStudentCourse tbStudentCourse) {        // 保存        boolean result = tbStudentCourseService.save(tbStudentCourse);        if(result) {            return BaseResult.ok("添加成功");       }        return BaseResult.error("添加失败");   } ​ } ​

4)修改后端添加(feign远程调用)

在学生服务中

定义选课feign

修改学生添加,保存选课信息

定义选课feign

 

package com.czxy.student.feign; ​ import com.czxy.domain.TbStudentCourse; import com.czxy.vo.BaseResult; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; ​ /** * @author 桐叔 * @email liangtong@itcast.cn * @description */ //@FeignClient(value = "服务名", path = "controller类路径") @FeignClient(value = "course-service", path = "/stduentCourse") public interface StudentCourseFeign { ​    @PostMapping    public BaseResult save(@RequestBody TbStudentCourse tbStudentCourse); } ​

版本1:修改学生添加,保存选课信息

 

package com.czxy.student.service.impl; ​ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.czxy.domain.TbStudent; import com.czxy.domain.TbStudentCourse; import com.czxy.student.feign.StudentCourseFeign; import com.czxy.student.mapper.TbStudentMapper; import com.czxy.student.service.TbStudentService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; ​ import javax.annotation.Resource; ​ /** * @author 桐叔 * @email liangtong@itcast.cn * @description */ @Service @Transactional public class TbStudentServiceImpl extends ServiceImpl<TbStudentMapper, TbStudent> implements TbStudentService {    @Resource    private StudentCourseFeign studentCourseFeign;    @Override    public boolean addStudent(TbStudent tbStudent) {        // 保存学生基本信息        int result = baseMapper.insert(tbStudent); ​        // 保存选课信息        for (Integer courseId : tbStudent.getCourseIds()) {            // 准备选课对象            TbStudentCourse tbStudentCourse = new TbStudentCourse();            tbStudentCourse.setCid(courseId);            tbStudentCourse.setSid(tbStudent.getSid());            // TODO 保存 ,没有处理异常            studentCourseFeign.save(tbStudentCourse);       } ​        return result == 1;   } } ​

版本2:修改学生添加,保存选课信息(课程有错,学生回滚)

package com.czxy.student.service.impl; ​ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.czxy.domain.TbStudent; import com.czxy.domain.TbStudentCourse; import com.czxy.student.feign.StudentCourseFeign; import com.czxy.student.mapper.TbStudentMapper; import com.czxy.student.service.TbStudentService; import com.czxy.vo.BaseResult; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; ​ import javax.annotation.Resource; ​ /** * @author 桐叔 * @email liangtong@itcast.cn * @description */ @Service @Transactional public class TbStudentServiceImpl extends ServiceImpl<TbStudentMapper, TbStudent> implements TbStudentService {    @Resource    private StudentCourseFeign studentCourseFeign;    @Override    public boolean addStudent(TbStudent tbStudent) {        // 保存学生基本信息        int result = baseMapper.insert(tbStudent); ​        // 记录操作结果        boolean flag = result == 1; ​        // 保存选课信息        for (Integer courseId : tbStudent.getCourseIds()) {            // 准备选课对象            TbStudentCourse tbStudentCourse = new TbStudentCourse();            tbStudentCourse.setCid(courseId);            tbStudentCourse.setSid(tbStudent.getSid());            // 保存课程 正确 code == 20000 , 错误 code == 0            BaseResult baseResult = studentCourseFeign.save(tbStudentCourse);            flag &= (baseResult.getCode() == 20000); ​       } ​        // 如果false抛异常 ,解决:课程有错,学生回滚        if(flag == false) {            throw new RuntimeException("添加失败");       }        //TODO 未解决问题:部分课程已经提交,需使用“分布式事务”解决 ​        return flag;   } } ​ 4. 6 修改 4.6.1 分析

 

4.5.2 查询详情

1) 分析

基本数据:只要查询就可以回显(姓名、性别等)

关联数据:

班级:有数据直接回显

城市:需要一个==数组==,存放一组城市数据,目前有的数据为字符串1,2,3。将在前端处理数据。

选课:也需要一个数组,存在一组课程id数据。将在后端处理数据。

2)后端

编写controller

编写service

编写controller

 

   @GetMapping("/{studentId}")    public BaseResult findById(@PathVariable("studentId") Integer studentId) {        // 查询        TbStudent tbStudent = tbStudentService.findById(studentId);        // 返回        return BaseResult.ok("查询详情", tbStudent);   }

编写service

 

TbStudent findById(Integer studentId);

   @Override    public TbStudent findById(Integer studentId) {        //1 学生详情        TbStudent tbStudent = baseMapper.selectById(studentId);        //2 选课信息        BaseResult<List<TbCourse>> tbCourseListBaseResult = courseFeign.findAllByStudentId(studentId);        List<TbCourse> tbCourseList = tbCourseListBaseResult.getData();        tbStudent.setCourseList(tbCourseList);        tbStudent.setCourseIds(tbCourseList.stream().map(course->course.getCid()).collect(Collectors.toList())); ​        //3 返回        return tbStudent;   }

3)前端

 

openStudentDialog(studentId) {      // 查询所有的班级      this.findAllClasses()      // 查询所有的选课      this.findAllCourse() ​      // 修改前查询详情      if(studentId) {        this.findStudentById(studentId)        this.studentDialogTitle = '修改学生'     } else {        this.studentDialogTitle = '添加学生'     } ​      // 控制变量      this.dialogStudentVisible = true ​   },         async findStudentById(sid) {      let {data:baseResult} = await this.$axios.get(`/student-service/student/${sid}`)      // 获得结果      this.student = baseResult.data      // 处理数据:城市 "cityIds": "320000,321300,321322" --> cid : ["320000","321300","321322"]      this.student.cids = this.student.cityIds.split(',')   }

4)级联菜单回显

element ui的级联菜单先渲染组件时,如果有数据,将触发自动查询功能。

步骤:

定义变量,隐藏级联菜单

查询数据成功后,显示菜单

提交数据后,隐藏菜单

【待完善】,点击x后,没有处理

定义变量,隐藏级联菜单

 

查询数据成功后,显示菜单

 

提交数据后,隐藏菜单

 

【待完善】,点击x后,没有处理

4.5.3 更新添加功能

1)学生服务

优化controller

 

修改service

编写feign

修改service

 

编写feign

 

2)课程服务

 

   @DeleteMapping("/delete/student/{sid}")    public BaseResult deleteAllBySid(@PathVariable("sid") Integer sid) {        // 1 设置条件        QueryWrapper<TbStudentCourse> queryWrapper = new QueryWrapper<>();        queryWrapper.eq("s_id", sid); ​        // 2 删除        boolean remove = tbStudentCourseService.remove(queryWrapper); ​        // 3 返回        if(remove) {            return BaseResult.ok("删除成功");       }        return BaseResult.error("删除失败"); ​   } ​

3)修复前端

性别回显

 

添加级联显示

相关文章

Qt设计师的简单使用(ui设计界面的简单使用)

Qt设计师的简单使用(ui设计界面的简单使用)...

Rclone的介绍和使用

Rclone的介绍和使用...

【毕业设计】基于 STM32 的自动泊车系统 -智能小车 - 物联网单片机

【毕业设计】基于 STM32 的自动泊车系统 -智能小车 - 物联网单片机...

『 云原生·Docker』Docker容器相关操作(二)

『 云原生·Docker』Docker容器相关操作(二)...

mysql8.0.30安装配置教程(windows 64位)最详细

mysql8.0.30安装配置教程(windows 64位)最详细...

Linux-安装MySQL(详细教程)

Linux-安装MySQL(详细教程)...