基于Springboot+Vue3的简易教学管理系统

news2025/7/18 14:35:24

 作品展示

基于Springboot+Vue3的简易信息教学管理系统

第1章  系统设计

1.1  系统功能模块设计

该系统实现的功能模块包括:

教师端:

  1. 学生信息管理:添加、删除、修改以及查询学生信息    √
  2. 课程信息管理:添加、删除、修改以及查询课程信息    √
  3. 教师信息管理:添加、删除、修改以及查询教师信息    √
  4. 选课信息管理:添加、删除、修改以及查询选课信息    √
  5. 教师教课管理:添加、删除、修改以及查询教师教课信息√
  6. 学生成绩管理:添加、删除、修改以及查询课程成绩    √

学生端:

  1. 学生信息管理:查询学生信息    √
  2. 课程信息管理:查询课程信息    √
  3. 教师信息管理:查询教师信息    √
  4. 选课信息管理:添加、删除、修改以及查询选课信息    √
  5. 学成成绩管理:查询课程成绩    √

其中,从接口角度出发,系统设计模块如图 1所示:

1 简易教学管理系统接口图

该系统对用户身份做了校验,主要分为教师端和学生端,划分出了不同权限。

图 2 简易教学信息管理系统权限划分图

同时,还可以从功能角度出发画图,其中,教师端的学生信息管理、课程信息管理、教师信息管理、学生端的学生信息管理、教师信息管理、选课信息管理、学生成绩管理如下所示:

图3 系统功能模块结构(学生端)

1.2  数据库设计

1.2.1 数据库概念结构设计

概念设计通过E-R图(实体-联系图)来直观地确定实体对象、属性及对象间的联系。

(1)课程实体E-R图

6 课程实体E-R图

(2)学生实体E-R图

该实体包括学生id,学生姓名,学生年龄,学生手机号等属性,如图 7所示。

7 学生实体E-R图

(3)老师实体E-R图

该实体包括老师id,老师姓名,老师年龄,老师研究方向等属性,如图 8所示。

8 老师实体E-R图

(4)老师授课信息实体E-R图

该实体包括老师授课信息id,课程id,老师id等属性,如图 9所示。

9 老师授课信息实体E-R图 

1.2.2 物理结构设计

(1)课程表

课程表包含课程id,课程名,课程学分等字段。如表 1所示。

1 课程表

表名

course(课程表)

字段中文

字段名

类型

长度

id主键

id

varchar

50

课程名

name

varchar

20

课程学分

credits

decimal

4

(2)学生表

学生表包括学生id,学生姓名,学生年龄,学生手机号等字段,如表 2所示。

2 学生表

表名

student(学生表)

字段中文

字段名

类型

长度

id主键

id

varchar

50

学生姓名

name

varchar

10

学生年龄

age

int

学生手机号

phone

varchar

255

(3)老师表

老师表包括老师id,老师姓名,老师年龄,老师研究方向等字段,如表 3所示。

3 老师表

表名

teacher(老师表)

字段中文

字段名

类型

长度

id主键

id

varchar

50

老师姓名

name

varchar

10

老师年龄

age

int

老师研究方向

profession

varchar

255

(4)老师课程关系表

老师课程关系表包括老师授课信息id,课程id,老师id等字段,如表 4所示。

4 老师课程关系表

表名

tea_course_relation(老师课程关系表)

字段中文

字段名

类型

长度

id主键

id

varchar

50

老师表id

teacher_id

varchar

50

课程表id

course_id

varchar

50

(5)学生课程关系表

学生课程关系表包括学生选课信息id,学生id,老师id,课程id,课程分数等,表 5如所示。

5 学生课程关系表

表名

stu_course_relation(学生课程关系表)

字段中文

字段名

类型

长度

id主键

id

varchar

50

学生表id

stu_id

varchar

50

课程表id

course_id

varchar

50

老师表id

teacher_id

varchar

50

课程成绩

course_score

decimal

4

第2章  详细设计

2.1  登录功能模块详细设计

        登录界面一共是两个输入框,分别是选择角色和输入角色id,其中,选择角色是一个下拉列表,可以选择教师或者角色,再输入教师id或学生id,如果数据库中,id存在,那么就跳转到相应教师端或学生端的界面。

图 11 登录功能模块流程图

登录界面实现图如下:

图 12 登录界面

图 13 登录界面-下拉选项

2.2  首页详细设计

  首页做了一个数据统计,但数据统计并没有重写获取学生、教师、课程总数的接口,而是直接调用了一直写的三个分页接口,从分页接口中拿totalNum,从而实现首页数据的获取

图 14 首页几个Echarts实现的流程图

首页实现图如下所示:

图 15 首页

2.3 搜索功能详细设计(以学生管理功能模块为例)

这里的搜索做的是分页查询,因此可以集成多个查询条件到一个接口,根据不同的查询条件查询,精准定位需要的数据。

图 16 搜索功能

2.4 删除单条

删除的逻辑比较简单,在这里不过多赘述:

图 17 查询单条数据

2.5 批量删除多条

批量删除多条数据这里,在前端用逗号分割了序号,拼接成String类型数据,把String传入后端,又在后端层面对String做了解析。这样做的好处是,对传参做了统一管理,方面接口的书写。

图 18 批量删除流程图

2.6 保存功能(新增、修改)

        保存功能合并了新增和修改接口,因为两个接口除了一个是带有id的数据,另一个是UUID自动生成的数据以外,没什么太大区别,虽然在mapper层还是分开写的update、insert接口,但在controller层是合并在一起的,所以这里的流程图就统一画了。

图 19 保存功能流程图

第3章  系统实现

3.1 学生管理功能模块

3.1.1学生管理功能实体类dto

package site.lyweb.domain.dto;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import org.apache.ibatis.annotations.Param;

import java.io.Serializable;
import java.math.BigDecimal;

/**
 * 
 * @TableName stu_course_relation
 */
@Data
public class StudentCourseDTO implements Serializable {

    //student_course_relation表的id
    private String id;

    //student表的几个字段
    private String studentName;

    private Integer studentAge;

    private String studentPhone;

    //course表的几个字段
    private String courseName;

    private BigDecimal courseCredits;

    //teacher表的几个字段
    private String teacherName;

    private Integer teacherAge;

    private String teacherProfession;

    private BigDecimal courseScore;
    private static final long serialVersionUID = 1L;
}

3.1.2学生管理功能实体类query

package site.lyweb.domain.query;

import lombok.Data;

/**
 * 
 * @TableName teacher
 */
@Data
public class StudentQuery {

    private String id;

    private String name;

    private Integer startAge;

    private Integer endAge;

    private String phone;

}

3.1.3 学生管理功能实体类po

package site.lyweb.domain.dto;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.io.Serializable;

/**
 * 
 * @TableName student
 */
@TableName(value ="student")
@Data
public class Student implements Serializable {
    /**
     * 主键
     */
    @TableId
    private String id;

    /**
     * 
     */
    private String name;

    /**
     * 
     */
    private Integer age;

    /**
     * 
     */
    private String phone;

    @TableField(exist = false)
    private static final long serialVersionUID = 1L;

    @Override
    public boolean equals(Object that) {
        if (this == that) {
            return true;
        }
        if (that == null) {
            return false;
        }
        if (getClass() != that.getClass()) {
            return false;
        }
        Student other = (Student) that;
        return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
            && (this.getName() == null ? other.getName() == null : this.getName().equals(other.getName()))
            && (this.getAge() == null ? other.getAge() == null : this.getAge().equals(other.getAge()))
            && (this.getPhone() == null ? other.getPhone() == null : this.getPhone().equals(other.getPhone()));
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
        result = prime * result + ((getName() == null) ? 0 : getName().hashCode());
        result = prime * result + ((getAge() == null) ? 0 : getAge().hashCode());
        result = prime * result + ((getPhone() == null) ? 0 : getPhone().hashCode());
        return result;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(" [");
        sb.append("Hash = ").append(hashCode());
        sb.append(", id=").append(id);
        sb.append(", name=").append(name);
        sb.append(", age=").append(age);
        sb.append(", phone=").append(phone);
        sb.append(", serialVersionUID=").append(serialVersionUID);
        sb.append("]");
        return sb.toString();
    }
}

3.1.4 学生管理功能mapper层

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="site.lyweb.mapper.StudentMapper">

    <resultMap id="BaseResultMap" type="site.lyweb.domain.dto.Student">
            <id property="id" column="id" jdbcType="BIGINT"/>
            <result property="name" column="name" jdbcType="VARCHAR"/>
            <result property="age" column="age" jdbcType="INTEGER"/>
            <result property="phone" column="phone" jdbcType="VARCHAR"/>
    </resultMap>

    <sql id="Base_Column_List">
        id,name,age,
        phone
    </sql>
    <select id="selectByCount" resultType="java.lang.Integer">
        select
        count(0)
        from student t
        <where>
            <if test="id != null">
                and t.id = #{id, jdbcType=INTEGER}
            </if>
            <if test="name != null">
                and t.name = #{name,jdbcType=VARCHAR}
            </if>
            <if test="startAge != null">
                <![CDATA[    and t.age >= #{startAge, jdbcType=VARCHAR}    ]]>
            </if>
            <if test="endAge != null">
                <![CDATA[    and t.age <= #{endAge, jdbcType=VARCHAR}    ]]>
            </if>
            <if test="phone != null">
                and t.phone = #{phone,jdbcType=VARCHAR}
            </if>
        </where>
    </select>

    <select id="selectByPage" parameterType="java.lang.Integer" resultType="site.lyweb.domain.dto.Student">
        select *
        from student t
        <where>
            <if test="id != null">
                and t.id = #{id, jdbcType=INTEGER}
            </if>
            <if test="name != null">
                and t.name = #{name,jdbcType=VARCHAR}
            </if>
            <if test="startAge != null">
                <![CDATA[    and t.age >= #{startAge, jdbcType=VARCHAR}    ]]>
            </if>
            <if test="endAge != null">
                <![CDATA[    and t.age <= #{endAge, jdbcType=VARCHAR}    ]]>
            </if>
            <if test="phone != null">
                and t.phone = #{phone,jdbcType=VARCHAR}
            </if>
        </where>
    </select>
</mapper>

3.1.5 学生管理功能mapper层接口

package site.lyweb.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import site.lyweb.domain.dto.Student;
import site.lyweb.domain.dto.Teacher;
import site.lyweb.domain.query.StudentQuery;
import site.lyweb.domain.query.TeacherQuery;

import java.util.List;

/**
* @author 深山老林
* @description 针对表【student】的数据库操作Mapper
* @createDate 2024-06-19 20:53:31
* @Entity generator.domain.Student
*/
public interface StudentMapper extends BaseMapper<Student> {

    int selectByCount(StudentQuery studentQuery);

    List<Student> selectByPage(StudentQuery studentQuery);
}

3.1.6 学生管理功能service层

package site.lyweb.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import site.lyweb.constant.Constant;
import site.lyweb.domain.dto.*;
import site.lyweb.domain.query.StudentQuery;
import site.lyweb.domain.query.TeacherQuery;
import site.lyweb.mapper.StudentMapper;
import site.lyweb.service.StudentService;
import site.lyweb.utils.ExtBeanUtils;

import java.util.List;

/**
* @author 深山老林
* @description 针对表【student】的数据库操作Service实现
* @createDate 2024-06-19 20:53:31
*/
@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student>
    implements StudentService {

    @Resource
    private StudentMapper studentMapper;
    /**
     * 分页 + 搜索
     *
     * @param current
     * @param studentQuery
     * @return
     */
    @Override
    public PageDTO<StudentDTO> getStudentByPage(Integer current, StudentQuery studentQuery) {
        //分页查询分两个查询,1、查符合条件的数据总条数;2、查询当前页的数据
        int totalRow = studentMapper.selectByCount(studentQuery);
        int start = (current - 1) * Constant.PAGE_SIZE;
        List<Student> studentList = studentMapper.selectByPage(studentQuery);
        int totalPage = totalRow / Constant.PAGE_SIZE;
        if (totalRow % Constant.PAGE_SIZE > 0) { //如果除不尽,总页数就需要加1
            totalPage ++;
        }
        //需要把 List<TUser> 转换为 List<UserInfoDTO>
        List<StudentDTO> studentDTOList = ExtBeanUtils.copyPropertiesForList(studentList, StudentDTO.class);

        return new PageDTO<>(current, Constant.PAGE_SIZE, totalRow, totalPage, studentDTOList);

    }

}

3.1.7 学生管理功能service层接口

package site.lyweb.service;

import com.baomidou.mybatisplus.extension.service.IService;
import site.lyweb.domain.dto.PageDTO;
import site.lyweb.domain.dto.Student;
import site.lyweb.domain.dto.StudentDTO;
import site.lyweb.domain.dto.TeacherDTO;
import site.lyweb.domain.query.StudentQuery;
import site.lyweb.domain.query.TeacherQuery;

/**
* @author 深山老林
* @description 针对表【student】的数据库操作Service
* @createDate 2024-06-19 20:53:31
*/
public interface StudentService extends IService<Student> {
    PageDTO<StudentDTO> getStudentByPage(Integer current, StudentQuery studentQuery);
}

3.1.8 学生管理功能controller层

package site.lyweb.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import site.lyweb.domain.dto.PageDTO;
import site.lyweb.domain.dto.Student;
import site.lyweb.domain.dto.StudentDTO;
import site.lyweb.domain.dto.TeacherDTO;
import site.lyweb.domain.query.StudentQuery;
import site.lyweb.domain.query.TeacherQuery;
import site.lyweb.result.RestResult;
import site.lyweb.service.StudentService;
import site.lyweb.utils.UUIDUtils;

import java.util.Arrays;
import java.util.List;

/**
 * @Author 林瑶
 * @Description TODO
 * @Date 2024/6/19 21:02
 */
@CrossOrigin
@RestController
@Tag(name="学生管理模块")
@Slf4j
@RequestMapping("/student")
public class StudentController {
    @Resource
    private StudentService studentService;

    /**
     * 根据id查找学生信息表中信息
     */
    @Operation(summary = "根据id查找学生信息表中信息")
    @Parameters({
            @Parameter(name = "id",description = "id(主键)",in = ParameterIn.PATH)
    })
    @GetMapping("/stu_info/getById/{id}")
    public RestResult queryStudentById(@PathVariable("id") String id){
        Student byId = studentService.getById(id);

        return RestResult.SUCCESS(byId);
    }
    /**
     * 查找全部学生信息表中信息
     */
    @Operation(summary = "查找全部学生信息表中信息")
    @GetMapping("/stu_info/getAll")
    public RestResult queryStudentAll(){
        return RestResult.SUCCESS(studentService.list());
    }
    /**
     * 根据id删除学生信息表中信息
     */
    @Operation(summary = "根据id删除学生信息表中信息")
    @Parameters({
            @Parameter(name = "id",description = "id(主键)",in = ParameterIn.PATH)
    })
    @PostMapping("/stu_info/del/{id}")
    public RestResult delStudentById(@PathVariable("id") String id){
        return studentService.removeById(id) ?RestResult.SUCCESS():RestResult.FAIL();
    }

    /**
     * 保存学生信息表中信息
     */
    @Operation(summary = "保存学生信息表中信息")
    @PostMapping("/stu_info/edit")
    @Parameters({
            @Parameter(name = "id",description = "id(主键)",in = ParameterIn.QUERY),
            @Parameter(name = "name",description = "姓名",in = ParameterIn.QUERY),
            @Parameter(name = "age",description = "年龄",in = ParameterIn.QUERY),
            @Parameter(name = "phone",description = "手机号",in = ParameterIn.QUERY),
    })
    public RestResult editStudent(Student student){
        if(student!=null){
            //有id:修改,无id:添加
            if(student.getId()!=null && !student.getId().isEmpty()){
                return studentService.updateById(student)?RestResult.SUCCESS("修改成功:"+student):RestResult.FAIL();
            }else{
                student.setId(UUIDUtils.getUUID());
                return studentService.save(student)?RestResult.SUCCESS("添加成功:"+student):RestResult.FAIL();
            }
        }
        return RestResult.FAIL("传入学生对象为空,保存失败");
    }
    /**
     * 分页查询学生列表数据
     *
     * @return
     */

    @Operation(summary = "分页查询学生列表数据")
    @GetMapping(value = "/stu_info/getStudentByPage")
    public RestResult getStudentByPage( StudentQuery studentQuery) {


        //分页查询的结果用PageDTO进行封装
        PageDTO<StudentDTO> pageDTO = studentService.getStudentByPage(0, studentQuery);

        //有的时候,查询可以不判断成功与失败,不管查没查到数据,都返回200,页面上去控制显示
        return RestResult.SUCCESS(pageDTO);
    }
    /**
     * 根据id批量学生信息表中信息
     */
    @Operation(summary = "根据ids删除学生信息表中信息")
    @Parameters({
            @Parameter(name = "ids",description = "id(主键)",in = ParameterIn.PATH)
    })
    @CrossOrigin
    @PostMapping("/stu_info/batchDel/{ids}")
    public RestResult batchDelStudentById(@PathVariable("ids") String ids){
        //ids = "1,2,5,7,10,12" , ids.split(",")是把ids转成数组, Arrays.asList()是把数组转成List
        List<String> idList = Arrays.asList(ids.split(","));

        return  studentService.removeBatchByIds(idList) ? RestResult.SUCCESS() : RestResult.FAIL();
    }


}

3.1.9 学生管理功能前端主页面(教师端)

<template>
  <el-form :inline="true" :model="studentSearchQuery" class="demo-form-inline">
    <el-form-item label="学生姓名">
      <el-input v-model="studentSearchQuery.name" placeholder="请输入学生姓名" clearable />
    </el-form-item>
    <el-form-item label="年龄区间左">
      <el-input v-model="studentSearchQuery.startAge" placeholder="请输入最小年龄" clearable />
    </el-form-item>    
    <el-form-item label="年龄区间右">
      <el-input v-model="studentSearchQuery.endAge" placeholder="请输入最大年龄" clearable />
    </el-form-item>    
    <el-form-item label="学生手机号">
      <el-input v-model="studentSearchQuery.phone" placeholder="请输入学生手机号" clearable />
    </el-form-item>

    <el-form-item>
      <el-button type="primary" @click="onSarch">搜 索</el-button>
      <el-button type="primary" plain @click="onReset">重 置</el-button>
    </el-form-item>
  </el-form>
  <br/><br/>

  <el-button type="primary" @click="addStudent">增加学生信息</el-button>
  <el-button type="danger" @click="batchDelStudent">批量删除</el-button>
  <br/><br/>

  <el-table
      ref="multipleTableRef"
      :data="studentList"
      style="width: 100%"
      @selection-change="handleSelectionChange">
    <el-table-column type="selection" width="55" />
    <el-table-column type="index" label="序号" width="60" />
    <el-table-column property="name" label="姓名" width="200"/>
    <el-table-column property="age" label="年龄" />
    <el-table-column property="phone" label="手机号" />
    <el-table-column label="操作" width="230">
      <template #default="scope"><!--vue插槽-->
        <el-button type="success" @click="edit(scope.row.id)">编辑</el-button>
        <el-button type="danger" @click="del(scope.row.id)">删除</el-button>
      </template>
    </el-table-column>
  </el-table>
  <br/>

  <el-pagination background
                 layout="prev, pager, next"
                 :page-size="pageSize"
                 :total="totalRow"
                 @prev-click="page"
                 @next-click="page"
                 @current-change="page"/>

</template>

<script>
import {doPost, doGet} from "@/http/axios-http";
import {message, messageConfirm} from "@/http/message";

export default {

  //注入reload
  inject : ['reload'],

  data() {
    return {
      //学生搜索条件对象,初始值是空
      studentSearchQuery : {},
      //学生列表list对象数据,初始值是空
      studentList : [{}],
      //每页显示多少条
      pageSize : 0,
      //总共有多少条
      totalRow : 0,
      //勾选了哪些学生id,默认值是空
      studentIdArray : []
    }
  },

  //页面渲染时触发该钩子函数
  mounted() {
    // this.loadAllUser();
    this.getData();
  },

  methods : {
    //查询学生列表数据
    getData() {
      doGet('/student/stu_info/getStudentByPage',this.studentSearchQuery).then(resp => {
        console.log(resp)
        if (resp.data.code === 200) {
          this.studentList = resp.data.data.dataList;
          this.pageSize = resp.data.data.pageSize;
          this.totalRow = resp.data.data.totalRow;
        }
      })
    },

    //搜索
    onSarch() {
      this.getData();
    },
    //重置
    onReset() {
      this.studentSearchQuery = {};
    },

    //录入市场学生
    addStudent() {
      //跳转路由
      this.$router.push({path : "/teacherDash/student_info/add"});
      //window.location.href = "/dashboard/student/add";
    },

    //编辑市场学生
    edit(id) {
      console.log(id);
      this.$router.push({path : "/teacherDash/student_info/edit/" + id});
    },

    //删除学生
    del(id) {
      //首先提示用户是否确定要删除
      messageConfirm("您是否确定要删除此数据?").then(() => { //当你点“确定”,执行该函
        doPost("/student/stu_info/del/" + id, {}).then(resp => {
          if (resp.data.code === 200) {
            //删除成功
            message("删除成功", "success");
            //刷新页面
            this.reload();
          } else {
            message("删除失败,原因:" + resp.data.msg, "error");
          }
        })
      }).catch(error => { //当你点“取消”,执行该函数
        message("删除错误:"+error, "warning");
        
      });
    },

    //批量删除学生
    batchDelStudent() {
      //用户没有选数据,要提示一下
      if (this.studentIdArray.length <= 0) {
        message("请选择要删除的数据", "warning");
        return;
      }
      //1、拿到选择的id
      let ids = this.studentIdArray.join(",");  //得到:ids = "1,2,5,7,10,12"
      //2、把这些id的数据删除
      messageConfirm("您是否确定要删除这些数据?").then(() => { //当你点“确定”,执行该函
        doPost("/student/stu_info/batchDel/" + ids, {}).then(resp => {
          if (resp.data.code === 200) {
            //删除成功
            message("删除成功", "success");
            //刷新页面
            this.reload();
          } else {
            //删除失败
            message("删除失败,原因:" + resp.data.msg, "error");
          }
        })
      }).catch(() => { //当你点“取消”,执行该函数
        message("删除已取消", "warning");
      });
    },

    //勾选或取消复选框时触发该函数
    handleSelectionChange(selection) {
      //勾选或取消复选框时,先把用户id的数组清空
      this.studentIdArray = [];
      selection.forEach( (student) => {
        this.studentIdArray.push(student.id);
      });
    }
  }
}

</script>

<style>

</style>


3.1.10 学生管理功能前端添加页面(教师端)

<template>
  <el-form
      label-width="80px"
      style="max-width: 95%;">

    <el-form-item label="学生姓名">
      <el-input v-model="studentQuery.name" @blur="checkName"/>
      <span style="color: red;"> {{formError.nameMsg}} </span>
    </el-form-item>

    <el-form-item label="学生年龄">
      <el-input v-model="studentQuery.age" @blur="checkAge"/>
      <span style="color: red;"> {{formError.ageMsg}} </span>
    </el-form-item>

    <el-form-item label="手机号">
      <el-input v-model="studentQuery.phone" @blur="checkPhone"/>
      <span style="color: red;"> {{formError.phoneMsg}} </span>
    </el-form-item>

    <el-form-item>
      <el-input type="hidden" v-model="studentQuery.id"/>
      <el-button type="primary" @click="addStudentSubmit">提 交</el-button>
      <el-button type="success" plain @click="back">返 回</el-button>
    </el-form-item>
  </el-form>
</template>

<script>
import {doGet, doPost, doPut} from "@/http/axios-http";
import {message} from "@/http/message";

export default {

  data() {
    return {
      //学生对象,初始值是空
      studentQuery : {},
      //form表单错误对象,初始值是空
      formError : {},
    }
  },

  mounted() {
    //根据路由id加载市场学生数据
    this.loadActivity();
  },

  methods : {
    //返回
    back() {
      //回退到上一次访问的页面
      //this.$router.go(-1);
      //精确地回到某个页面
      this.$router.push({path : "/teacherDash/student_info"})
    },

    //录入市场学生(提交保存)
    addStudentSubmit() {
      //表单提交,使用formData提交表单
      let formData = new FormData();
      for (let field in this.studentQuery) {
        formData.append(field, this.studentQuery[field]);
      }

      if (this.studentQuery.id) { //this.studentQuery对象有id,说明的做了一次查询,那么就修改
        doPost("/student/stu_info/edit", formData).then(resp => {
          if (resp.data.code === 200) {
            //提示一下
            message("编辑学生信息成功", "success");
            //跳转到学生列表页
            this.$router.push({path : "/teacherDash/student_info"})
          } else {
            //提示一下
            message("编辑学生信息失败,原因:" + resp.data.msg, "error");
          }
        })
      } else {
        doPost("/student/stu_info/edit", formData).then(resp => {
          console.log(resp)
          if (resp.data.code === 200) {
            //提示一下
            message("录入学生信息成功", "success");
            //跳转到学生列表页
            this.$router.push({path : "/teacherDash/student_info"})
          } else {
            //提示一下
            message("录入学生信息失败,原因:" + resp.data.msg, "error");
          }
        })
      }
    },

    //根据路由id加载市场学生数据
    loadActivity() {
      let id = this.$route.params.id;
      if (id) {
        //编辑需要把数据查出来
        doGet("/student/stu_info/getById/" + id, {}).then(resp => {
          this.studentQuery = resp.data.data;
        })
      }
    }
  }
}
</script>

3.1.11 学生管理功能前端主页面(学生端)

<template>
  <el-form :inline="true" :model="studentSearchQuery" class="demo-form-inline">
    <el-form-item label="学生姓名">
      <el-input v-model="studentSearchQuery.name" placeholder="请输入学生姓名" clearable />
    </el-form-item>
    <el-form-item label="年龄区间左">
      <el-input v-model="studentSearchQuery.startAge" placeholder="请输入最小年龄" clearable />
    </el-form-item>    
    <el-form-item label="年龄区间右">
      <el-input v-model="studentSearchQuery.endAge" placeholder="请输入最大年龄" clearable />
    </el-form-item>    
    <el-form-item label="学生手机号">
      <el-input v-model="studentSearchQuery.phone" placeholder="请输入学生手机号" clearable />
    </el-form-item>

    <el-form-item>
      <el-button type="primary" @click="onSarch">搜 索</el-button>
      <el-button type="primary" plain @click="onReset">重 置</el-button>
    </el-form-item>
  </el-form>
  <br/><br/>

  <el-table
      ref="multipleTableRef"
      :data="studentList"
      style="width: 100%"
      @selection-change="handleSelectionChange">
    <el-table-column type="selection" width="55" />
    <el-table-column type="index" label="序号" width="60" />
    <el-table-column property="name" label="姓名" width="200"/>
    <el-table-column property="age" label="年龄" />
    <el-table-column property="phone" label="手机号" />
    <el-table-column label="操作" width="230">
      <template #default="scope"><!--vue插槽-->
        <el-button type="success" @click="edit(scope.row.id)" disabled="true">编辑</el-button>
        <el-button type="danger" @click="del(scope.row.id)" disabled="true">删除</el-button>
      </template>
    </el-table-column>
  </el-table>
  <br/>

  <el-pagination background
                 layout="prev, pager, next"
                 :page-size="pageSize"
                 :total="totalRow"
                 @prev-click="page"
                 @next-click="page"
                 @current-change="page"/>

</template>

<script>
import {doPost, doGet} from "@/http/axios-http";
import {message, messageConfirm} from "@/http/message";

export default {

  //注入reload
  inject : ['reload'],

  data() {
    return {
      //学生搜索条件对象,初始值是空
      studentSearchQuery : {},
      //学生列表list对象数据,初始值是空
      studentList : [{}],
      //每页显示多少条
      pageSize : 0,
      //总共有多少条
      totalRow : 0,
      //勾选了哪些学生id,默认值是空
      studentIdArray : []
    }
  },

  //页面渲染时触发该钩子函数
  mounted() {
    // this.loadAllUser();
    this.getData();
  },

  methods : {
    //查询学生列表数据
    getData() {
      doGet('/student/stu_info/getStudentByPage',this.studentSearchQuery).then(resp => {
        console.log(resp)
        if (resp.data.code === 200) {
          this.studentList = resp.data.data.dataList;
          this.pageSize = resp.data.data.pageSize;
          this.totalRow = resp.data.data.totalRow;
        }
      })
    },

    //搜索
    onSarch() {
      this.getData();
    },
    //重置
    onReset() {
      this.studentSearchQuery = {};
    },

    //录入市场学生
    addStudent() {
      //跳转路由
      this.$router.push({path : "/teacherDash/student_info/add"});
      //window.location.href = "/dashboard/student/add";
    },

    //编辑市场学生
    edit(id) {
      console.log(id);
      this.$router.push({path : "/teacherDash/student_info/edit/" + id});
    },

    //删除学生
    del(id) {
      //首先提示用户是否确定要删除
      messageConfirm("您是否确定要删除此数据?").then(() => { //当你点“确定”,执行该函
        doPost("/student/stu_info/del/" + id, {}).then(resp => {
          if (resp.data.code === 200) {
            //删除成功
            message("删除成功", "success");
            //刷新页面
            this.reload();
          } else {
            message("删除失败,原因:" + resp.data.msg, "error");
          }
        })
      }).catch(error => { //当你点“取消”,执行该函数
        message("删除错误:"+error, "warning");
        
      });
    },

    //批量删除学生
    batchDelStudent() {
      //用户没有选数据,要提示一下
      if (this.studentIdArray.length <= 0) {
        message("请选择要删除的数据", "warning");
        return;
      }
      //1、拿到选择的id
      let ids = this.studentIdArray.join(",");  //得到:ids = "1,2,5,7,10,12"
      //2、把这些id的数据删除
      messageConfirm("您是否确定要删除这些数据?").then(() => { //当你点“确定”,执行该函
        doPost("/student/stu_info/batchDel/" + ids, {}).then(resp => {
          if (resp.data.code === 200) {
            //删除成功
            message("删除成功", "success");
            //刷新页面
            this.reload();
          } else {
            //删除失败
            message("删除失败,原因:" + resp.data.msg, "error");
          }
        })
      }).catch(() => { //当你点“取消”,执行该函数
        message("删除已取消", "warning");
      });
    },

    //勾选或取消复选框时触发该函数
    handleSelectionChange(selection) {
      //勾选或取消复选框时,先把用户id的数组清空
      this.studentIdArray = [];
      selection.forEach( (student) => {
        this.studentIdArray.push(student.id);
      });
    }
  }
}
</script>
<style>
</style>


3.2教师管理功能模块

3.2.1 教师管理功能实体类dto

package site.lyweb.domain.dto;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.io.Serializable;

/**
 * 
 * @TableName teacher
 */
@Data
public class TeacherDTO implements Serializable {

    private String id;

    private String name;

    private Integer age;

    private String profession;

    private static final long serialVersionUID = 1L;
}

3.2.2 教师管理功能实体类query

package site.lyweb.domain.query;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.io.Serializable;

/**
 * 
 * @TableName teacher
 */
@Data
public class TeacherQuery {

    private String id;

    private String name;

    private Integer startAge;

    private Integer endAge;

    private String profession;


}

3.2.3 教师管理功能实体类po

package site.lyweb.domain.dto;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.io.Serializable;

/**
 * 
 * @TableName teacher
 */
@TableName(value ="teacher")
@Data
public class Teacher implements Serializable {
    /**
     * 
     */
    @TableId
    private String id;

    /**
     * 
     */
    private String name;

    /**
     * 
     */
    private Integer age;

    /**
     * 
     */
    private String profession;

    @TableField(exist = false)
    private static final long serialVersionUID = 1L;

    @Override
    public boolean equals(Object that) {
        if (this == that) {
            return true;
        }
        if (that == null) {
            return false;
        }
        if (getClass() != that.getClass()) {
            return false;
        }
        Teacher other = (Teacher) that;
        return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
            && (this.getName() == null ? other.getName() == null : this.getName().equals(other.getName()))
            && (this.getAge() == null ? other.getAge() == null : this.getAge().equals(other.getAge()))
            && (this.getProfession() == null ? other.getProfession() == null : this.getProfession().equals(other.getProfession()));
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
        result = prime * result + ((getName() == null) ? 0 : getName().hashCode());
        result = prime * result + ((getAge() == null) ? 0 : getAge().hashCode());
        result = prime * result + ((getProfession() == null) ? 0 : getProfession().hashCode());
        return result;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(" [");
        sb.append("Hash = ").append(hashCode());
        sb.append(", id=").append(id);
        sb.append(", name=").append(name);
        sb.append(", age=").append(age);
        sb.append(", profession=").append(profession);
        sb.append(", serialVersionUID=").append(serialVersionUID);
        sb.append("]");
        return sb.toString();
    }
}

3.2.4 教师管理功能mapper层

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="site.lyweb.mapper.TeacherMapper">

    <resultMap id="BaseResultMap" type="site.lyweb.domain.dto.Teacher">
            <id property="id" column="id" jdbcType="BIGINT"/>
            <result property="name" column="name" jdbcType="VARCHAR"/>
            <result property="age" column="age" jdbcType="INTEGER"/>
            <result property="profession" column="profession" jdbcType="VARCHAR"/>
    </resultMap>

    <sql id="Base_Column_List">
        id,name,age,
        profession
    </sql>
    <select id="selectByCount" resultType="java.lang.Integer">
        select
        count(0)
        from teacher t
        <where>
            <if test="id != null">
                and t.id = #{id, jdbcType=INTEGER}
            </if>
            <if test="name != null">
                and t.name = #{name,jdbcType=VARCHAR}
            </if>
            <if test="startAge != null">
                <![CDATA[    and t.age >= #{startAge, jdbcType=VARCHAR}    ]]>
            </if>
            <if test="endAge != null">
                <![CDATA[    and t.age <= #{endAge, jdbcType=VARCHAR}    ]]>
            </if>
            <if test="profession != null">
                and t.profession = #{profession,jdbcType=VARCHAR}
            </if>
        </where>
    </select>

    <select id="selectByPage" parameterType="java.lang.Integer" resultType="site.lyweb.domain.dto.Teacher">
        select *
        from teacher t
        <where>
            <if test="id != null">
                and t.id = #{id, jdbcType=INTEGER}
            </if>
            <if test="name != null">
                and t.name = #{name,jdbcType=VARCHAR}
            </if>
            <if test="startAge != null">
                <![CDATA[    and t.age >= #{startAge, jdbcType=VARCHAR}    ]]>
            </if>
            <if test="endAge != null">
                <![CDATA[    and t.age <= #{endAge, jdbcType=VARCHAR}    ]]>
            </if>
            <if test="profession != null">
                and t.profession = #{profession,jdbcType=VARCHAR}
            </if>
        </where>
    </select>
</mapper>

3.2.5 教师管理功能mapper层接口

package site.lyweb.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import site.lyweb.domain.dto.Teacher;
import site.lyweb.domain.query.TeacherQuery;

import java.util.List;

/**
* @author 深山老林
* @description 针对表【teacher】的数据库操作Mapper
* @createDate 2024-06-19 20:53:32
* @Entity generator.domain.Teacher
*/
public interface TeacherMapper extends BaseMapper<Teacher> {

    int selectByCount(TeacherQuery teacherQuery);

    List<Teacher> selectByPage( TeacherQuery teacherQuery);

}

3.2.6 教师管理功能service层

package site.lyweb.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import site.lyweb.constant.Constant;
import site.lyweb.domain.dto.PageDTO;
import site.lyweb.domain.dto.Teacher;
import site.lyweb.domain.dto.TeacherDTO;
import site.lyweb.domain.query.TeacherQuery;
import site.lyweb.mapper.TeacherMapper;
import site.lyweb.service.TeacherService;
import site.lyweb.utils.ExtBeanUtils;

import java.lang.annotation.Target;
import java.util.List;

/**
* @author 深山老林
* @description 针对表【teacher】的数据库操作Service实现
* @createDate 2024-06-19 20:53:32
*/
@Service
public class TeacherServiceImpl extends ServiceImpl<TeacherMapper, Teacher>
    implements TeacherService {
    @Resource
    private TeacherMapper teacherMapper;
    /**
     * 分页 + 搜索
     *
     * @param current
     * @param teacherQuery
     * @return
     */
    @Override
    public PageDTO<TeacherDTO> getTeacherByPage(Integer current, TeacherQuery teacherQuery) {
        //分页查询分两个查询,1、查符合条件的数据总条数;2、查询当前页的数据
        int totalRow = teacherMapper.selectByCount(teacherQuery);
        int start = (current - 1) * Constant.PAGE_SIZE;
        List<Teacher> teacherList = teacherMapper.selectByPage(teacherQuery);
        int totalPage = totalRow / Constant.PAGE_SIZE;
        if (totalRow % Constant.PAGE_SIZE > 0) { //如果除不尽,总页数就需要加1
            totalPage ++;
        }
        //需要把 List<TUser> 转换为 List<UserInfoDTO>
        List<TeacherDTO> teacherDTOList = ExtBeanUtils.copyPropertiesForList(teacherList, TeacherDTO.class);

        return new PageDTO<>(current, Constant.PAGE_SIZE, totalRow, totalPage, teacherDTOList);

    }
}

3.2.7 教师管理功能service层接口

package site.lyweb.service;

import site.lyweb.domain.dto.PageDTO;
import com.baomidou.mybatisplus.extension.service.IService;
import site.lyweb.domain.dto.Teacher;
import site.lyweb.domain.dto.TeacherDTO;
import site.lyweb.domain.query.TeacherQuery;

/**
* @author 深山老林
* @description 针对表【teacher】的数据库操作Service
* @createDate 2024-06-19 20:53:32
*/
public interface TeacherService extends IService<Teacher> {

    PageDTO<TeacherDTO> getTeacherByPage(Integer current, TeacherQuery teacherQuery);
}

3.2.8 教师管理功能controller层

package site.lyweb.controller;

import site.lyweb.domain.dto.PageDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import site.lyweb.domain.dto.Teacher;
import site.lyweb.domain.dto.TeacherDTO;
import site.lyweb.domain.query.TeacherQuery;
import site.lyweb.result.RestResult;
import site.lyweb.service.TeacherService;
import site.lyweb.utils.UUIDUtils;

import java.util.Arrays;
import java.util.List;

/**
 * @Author 林瑶
 * @Description TODO
 * @Date 2024/6/20 0:32
 */
@CrossOrigin(origins = "*")
@RestController
@Tag(name="教师管理模块")
@Slf4j
@RequestMapping("/teacher")
public class TeacherController {
    @Resource
    private TeacherService teacherService;
    /**
     * 分页查询老师列表数据
     *
     * @return
     */

    @Operation(summary = "分页查询老师列表数据")
    @GetMapping(value = "/tea_info/getTeacherByPage")
    public RestResult getTeacherByPage( TeacherQuery teacherQuery) {


        //分页查询的结果用PageDTO进行封装
        PageDTO<TeacherDTO> pageDTO = teacherService.getTeacherByPage(0, teacherQuery);

        //有的时候,查询可以不判断成功与失败,不管查没查到数据,都返回200,页面上去控制显示
        return RestResult.SUCCESS(pageDTO);
    }
    /**
     * 根据id查找老师信息表中信息
     */
    @Operation(summary = "根据id查找老师信息表中信息")
    @Parameters({
            @Parameter(name = "id",description = "id(主键)",in = ParameterIn.PATH)
    })
    @GetMapping("/tea_info/getById/{id}")
    public RestResult queryStudentById(@PathVariable("id") String id){
        Teacher byId = teacherService.getById(id);

        return RestResult.SUCCESS(byId);
    }
    /**
     * 查找全部老师信息表中信息
     */
    @Operation(summary = "查找全部老师信息表中信息")
    @GetMapping("/tea_info/getAll")
    public RestResult queryStudentAll(){
        return RestResult.SUCCESS(teacherService.list());
    }
    /**
     * 根据id删除老师信息表中信息
     */
    @Operation(summary = "根据id删除老师信息表中信息")
    @Parameters({
            @Parameter(name = "id",description = "id(主键)",in = ParameterIn.PATH)
    })
    @CrossOrigin
    @PostMapping("/tea_info/del/{id}")
    public RestResult delStudentById(@PathVariable("id") String id){
        return teacherService.removeById(id) ?RestResult.SUCCESS():RestResult.FAIL();
    }
    /**
     * 根据id批量老师信息表中信息
     */
    @Operation(summary = "根据ids删除老师信息表中信息")
    @Parameters({
            @Parameter(name = "ids",description = "id(主键)",in = ParameterIn.PATH)
    })
    @CrossOrigin
    @PostMapping("/tea_info/batchDel/{ids}")
    public RestResult batchDelStudentById(@PathVariable("ids") String ids){
        //ids = "1,2,5,7,10,12" , ids.split(",")是把ids转成数组, Arrays.asList()是把数组转成List
        List<String> idList = Arrays.asList(ids.split(","));

        return  teacherService.removeBatchByIds(idList) ? RestResult.SUCCESS() : RestResult.FAIL();
    }
    /**
     * 保存老师信息表中信息
     */
    @Operation(summary = "保存老师信息表中信息")
    @PostMapping("/tea_info/edit")
    @Parameters({
            @Parameter(name = "id",description = "id(主键)",in = ParameterIn.QUERY),
            @Parameter(name = "name",description = "姓名",in = ParameterIn.QUERY),
            @Parameter(name = "age",description = "年龄",in = ParameterIn.QUERY),
            @Parameter(name = "profession",description = "研究方向",in = ParameterIn.QUERY),
    })
    public RestResult editStudent(Teacher teacher){
        if(teacher!=null){
            //有id:修改,无id:添加
            if(teacher.getId()!=null && !teacher.getId().isEmpty()){
                return teacherService.updateById(teacher)?RestResult.SUCCESS("修改成功:"+teacher):RestResult.FAIL();
            }else{
                teacher.setId(UUIDUtils.getUUID());
                return teacherService.save(teacher)?RestResult.SUCCESS("添加成功:"+teacher):RestResult.FAIL();
            }
        }
        return RestResult.FAIL("传入老师对象为空,保存失败");
    }
}

3.2.9 教师管理功能前端主页面(教师端)

<template>
  <el-form :inline="true" :model="teacherSearchQuery" class="demo-form-inline">
    <el-form-item label="老师名称">
      <el-input v-model="teacherSearchQuery.name" placeholder="请输入老师名称" clearable />
    </el-form-item>
    <el-form-item label="年龄区间左">
      <el-input v-model="teacherSearchQuery.startAge" placeholder="请输入最小年龄" clearable />
    </el-form-item>    
    <el-form-item label="年龄区间右">
      <el-input v-model="teacherSearchQuery.endAge" placeholder="请输入最大年龄" clearable />
    </el-form-item>    
    <el-form-item label="研究方向">
      <el-input v-model="teacherSearchQuery.profession" placeholder="请输入老师的研究方向" clearable />
    </el-form-item>

    <el-form-item>
      <el-button type="primary" @click="onSarch">搜 索</el-button>
      <el-button type="primary" plain @click="onReset">重 置</el-button>
    </el-form-item>
  </el-form>
  <br/><br/>

  <el-button type="primary" @click="addTeacher">增加老师信息</el-button>
  <el-button type="danger" @click="batchDelTeacher">批量删除</el-button>
  <br/><br/>

  <el-table
      ref="multipleTableRef"
      :data="teacherList"
      style="width: 100%"
      @selection-change="handleSelectionChange">
    <el-table-column type="selection" width="55" />
    <el-table-column type="index" label="序号" width="60" />
    <el-table-column property="name" label="姓名" width="200"/>
    <el-table-column property="age" label="年龄" />
    <el-table-column property="profession" label="研究方向" />
    <el-table-column label="操作" width="230">
      <template #default="scope"><!--vue插槽-->
        <el-button type="success" @click="edit(scope.row.id)">编辑</el-button>
        <el-button type="danger" @click="del(scope.row.id)">删除</el-button>
      </template>
    </el-table-column>
  </el-table>
  <br/>

  <el-pagination background
                 layout="prev, pager, next"
                 :page-size="pageSize"
                 :total="totalRow"
                 @prev-click="page"
                 @next-click="page"
                 @current-change="page"/>

</template>

<script>
import {doPost, doGet} from "@/http/axios-http";
import {message, messageConfirm} from "@/http/message";

export default {

  //注入reload
  inject : ['reload'],

  data() {
    return {
      //老师搜索条件对象,初始值是空
      teacherSearchQuery : {},
      //老师列表list对象数据,初始值是空
      teacherList : [{}],
      //每页显示多少条
      pageSize : 0,
      //总共有多少条
      totalRow : 0,
      //勾选了哪些老师id,默认值是空
      teacherIdArray : []
    }
  },

  //页面渲染时触发该钩子函数
  mounted() {
    // this.loadAllUser();
    this.getData();
  },

  methods : {
    //查询市场老师列表数据
    getData() {
      doGet('/teacher/tea_info/getTeacherByPage',this.teacherSearchQuery).then(resp => {
        console.log(resp)
        if (resp.data.code === 200) {
          this.teacherList = resp.data.data.dataList;
          this.pageSize = resp.data.data.pageSize;
          this.totalRow = resp.data.data.totalRow;
        }
      })
    },

    //搜索
    onSarch() {
      this.getData();
    },
    //重置
    onReset() {
      this.teacherSearchQuery = {};
    },

    //录入市场老师
    addTeacher() {
      //跳转路由
      this.$router.push({path : "/teacherDash/teacher_info/add"});
      //window.location.href = "/dashboard/teacher/add";
    },

    //编辑市场老师
    edit(id) {
      console.log(id);
      this.$router.push({path : "/teacherDash/teacher_info/edit/" + id});
    },

    //删除老师
    del(id) {
      //首先提示用户是否确定要删除
      messageConfirm("您是否确定要删除此数据?").then(() => { //当你点“确定”,执行该函
        doPost("/teacher/tea_info/del/" + id, {}).then(resp => {
          if (resp.data.code === 200) {
            //删除成功
            message("删除成功", "success");
            //刷新页面
            this.reload();
          } else {
            message("删除失败,原因:" + resp.data.msg, "error");
          }
        })
      }).catch(error => { //当你点“取消”,执行该函数
        message("删除错误:"+error, "warning");
        
      });
    },

    //批量删除老师
    batchDelTeacher() {
      //用户没有选数据,要提示一下
      if (this.teacherIdArray.length <= 0) {
        message("请选择要删除的数据", "warning");
        return;
      }
      //1、拿到选择的id
      let ids = this.teacherIdArray.join(",");  //得到:ids = "1,2,5,7,10,12"
      //2、把这些id的数据删除
      messageConfirm("您是否确定要删除这些数据?").then(() => { //当你点“确定”,执行该函
        doPost("/teacher/tea_info/batchDel/" + ids, {}).then(resp => {
          if (resp.data.code === 200) {
            //删除成功
            message("删除成功", "success");
            //刷新页面
            this.reload();
          } else {
            //删除失败
            message("删除失败,原因:" + resp.data.msg, "error");
          }
        })
      }).catch(() => { //当你点“取消”,执行该函数
        message("删除已取消", "warning");
      });
    },

    //勾选或取消复选框时触发该函数
    handleSelectionChange(selection) {
      //勾选或取消复选框时,先把用户id的数组清空
      this.teacherIdArray = [];
      selection.forEach( (teacher) => {
        this.teacherIdArray.push(teacher.id);
      });
    }
  }
}

</script>

<style>

</style>


3.2.10 教师管理功能前端添加页面(教师端)

<template>
  <el-form
      label-width="80px"
      style="max-width: 95%;">

    <el-form-item label="老师姓名">
      <el-input v-model="teacherQuery.name" @blur="checkName"/>
      <span style="color: red;"> {{formError.nameMsg}} </span>
    </el-form-item>

    <el-form-item label="老师年龄">
      <el-input v-model="teacherQuery.age" @blur="checkAge"/>
      <span style="color: red;"> {{formError.ageMsg}} </span>
    </el-form-item>

    <el-form-item label="老师研究方向">
      <el-input v-model="teacherQuery.profession" @blur="checkProfession"/>
      <span style="color: red;"> {{formError.professionMsg}} </span>
    </el-form-item>

    <el-form-item>
      <el-input type="hidden" v-model="teacherQuery.id"/>
      <el-button type="primary" @click="addTeacherSubmit">提 交</el-button>
      <el-button type="success" plain @click="back">返 回</el-button>
    </el-form-item>
  </el-form>
</template>

<script>
import {doGet, doPost, doPut} from "@/http/axios-http";
import {message} from "@/http/message";

export default {

  data() {
    return {
      //老师对象,初始值是空
      teacherQuery : {},
      //form表单错误对象,初始值是空
      formError : {},
    }
  },

  mounted() {
    //根据路由id加载市场老师数据
    this.loadActivity();
  },

  methods : {
    //返回
    back() {
      //回退到上一次访问的页面
      //this.$router.go(-1);
      //精确地回到某个页面
      this.$router.push({path : "/teacherDash/teacher_info"})
    },

    //录入市场老师(提交保存)
    addTeacherSubmit() {
      //表单提交,使用formData提交表单
      let formData = new FormData();
      for (let field in this.teacherQuery) {
        formData.append(field, this.teacherQuery[field]);
      }

      if (this.teacherQuery.id) { //this.teacherQuery对象有id,说明的做了一次查询,那么就修改
        doPost("/teacher/tea_info/edit", formData).then(resp => {
          if (resp.data.code === 200) {
            //提示一下
            message("编辑老师信息成功", "success");
            //跳转到老师列表页
            this.$router.push({path : "/teacherDash/teacher_info"})
          } else {
            //提示一下
            message("编辑老师信息失败,原因:" + resp.data.msg, "error");
          }
        })
      } else {
        doPost("/teacher/tea_info/edit", formData).then(resp => {
          console.log(resp)
          if (resp.data.code === 200) {
            //提示一下
            message("录入老师信息成功", "success");
            //跳转到老师列表页
            this.$router.push({path : "/teacherDash/teacher_info"})
          } else {
            //提示一下
            message("录入老师信息失败,原因:" + resp.data.msg, "error");
          }
        })
      }
    },

    //根据路由id加载市场老师数据
    loadActivity() {
      let id = this.$route.params.id;
      if (id) {
        //编辑需要把数据查出来
        doGet("/teacher/tea_info/getById/" + id, {}).then(resp => {
          this.teacherQuery = resp.data.data;
        })
      }
    }
  }
}
</script>

3.2.11 教师管理功能前端主页面(学生端)

<template>
  <el-form :inline="true" :model="teacherSearchQuery" class="demo-form-inline">
    <el-form-item label="老师名称">
      <el-input v-model="teacherSearchQuery.name" placeholder="请输入老师名称" clearable />
    </el-form-item>
    <el-form-item label="年龄区间左">
      <el-input v-model="teacherSearchQuery.startAge" placeholder="请输入最小年龄" clearable />
    </el-form-item>    
    <el-form-item label="年龄区间右">
      <el-input v-model="teacherSearchQuery.endAge" placeholder="请输入最大年龄" clearable />
    </el-form-item>    
    <el-form-item label="研究方向">
      <el-input v-model="teacherSearchQuery.profession" placeholder="请输入老师的研究方向" clearable />
    </el-form-item>

    <el-form-item>
      <el-button type="primary" @click="onSarch">搜 索</el-button>
      <el-button type="primary" plain @click="onReset">重 置</el-button>
    </el-form-item>
  </el-form>
  <br/><br/>

  <el-table
      ref="multipleTableRef"
      :data="teacherList"
      style="width: 100%"
      @selection-change="handleSelectionChange">
    <el-table-column type="selection" width="55" />
    <el-table-column type="index" label="序号" width="60" />
    <el-table-column property="name" label="姓名" width="200"/>
    <el-table-column property="age" label="年龄" />
    <el-table-column property="profession" label="研究方向" />
    <el-table-column label="操作" width="230">
      <template #default="scope"><!--vue插槽-->
        <el-button type="success" @click="edit(scope.row.id)" disabled=true>编辑</el-button>
        <el-button type="danger" @click="del(scope.row.id)" disabled=true>删除</el-button>
      </template>
    </el-table-column>
  </el-table>
  <br/>

  <el-pagination background
                 layout="prev, pager, next"
                 :page-size="pageSize"
                 :total="totalRow"
                 @prev-click="page"
                 @next-click="page"
                 @current-change="page"/>

</template>

<script>
import {doPost, doGet} from "@/http/axios-http";
import {message, messageConfirm} from "@/http/message";

export default {

  //注入reload
  inject : ['reload'],

  data() {
    return {
      //老师搜索条件对象,初始值是空
      teacherSearchQuery : {},
      //老师列表list对象数据,初始值是空
      teacherList : [{}],
      //每页显示多少条
      pageSize : 0,
      //总共有多少条
      totalRow : 0,
      //勾选了哪些老师id,默认值是空
      teacherIdArray : []
    }
  },

  //页面渲染时触发该钩子函数
  mounted() {
    // this.loadAllUser();
    this.getData();
  },

  methods : {
    //查询市场老师列表数据
    getData() {
      doGet('/teacher/tea_info/getTeacherByPage',this.teacherSearchQuery).then(resp => {
        console.log(resp)
        if (resp.data.code === 200) {
          this.teacherList = resp.data.data.dataList;
          this.pageSize = resp.data.data.pageSize;
          this.totalRow = resp.data.data.totalRow;
        }
      })
    },

    //搜索
    onSarch() {
      this.getData();
    },
    //重置
    onReset() {
      this.teacherSearchQuery = {};
    },

    //录入市场老师
    addTeacher() {
      //跳转路由
      this.$router.push({path : "/teacherDash/teacher_info/add"});
      //window.location.href = "/dashboard/teacher/add";
    },

    //编辑市场老师
    edit(id) {
      console.log(id);
      this.$router.push({path : "/teacherDash/teacher_info/edit/" + id});
    },

    //删除老师
    del(id) {
      //首先提示用户是否确定要删除
      messageConfirm("您是否确定要删除此数据?").then(() => { //当你点“确定”,执行该函
        doPost("/teacher/tea_info/del/" + id, {}).then(resp => {
          if (resp.data.code === 200) {
            //删除成功
            message("删除成功", "success");
            //刷新页面
            this.reload();
          } else {
            message("删除失败,原因:" + resp.data.msg, "error");
          }
        })
      }).catch(error => { //当你点“取消”,执行该函数
        message("删除错误:"+error, "warning");
        
      });
    },

    //批量删除老师
    batchDelTeacher() {
      //用户没有选数据,要提示一下
      if (this.teacherIdArray.length <= 0) {
        message("请选择要删除的数据", "warning");
        return;
      }
      //1、拿到选择的id
      let ids = this.teacherIdArray.join(",");  //得到:ids = "1,2,5,7,10,12"
      //2、把这些id的数据删除
      messageConfirm("您是否确定要删除这些数据?").then(() => { //当你点“确定”,执行该函
        doPost("/teacher/tea_info/batchDel/" + ids, {}).then(resp => {
          if (resp.data.code === 200) {
            //删除成功
            message("删除成功", "success");
            //刷新页面
            this.reload();
          } else {
            //删除失败
            message("删除失败,原因:" + resp.data.msg, "error");
          }
        })
      }).catch(() => { //当你点“取消”,执行该函数
        message("删除已取消", "warning");
      });
    },

    //勾选或取消复选框时触发该函数
    handleSelectionChange(selection) {
      //勾选或取消复选框时,先把用户id的数组清空
      this.teacherIdArray = [];
      selection.forEach( (teacher) => {
        this.teacherIdArray.push(teacher.id);
      });
    }
  }
}

</script>

<style>

</style>


3.3课程管理功能模块

3.3.1 课程管理功能实体类dto

package site.lyweb.domain.dto;

import lombok.Data;

import java.io.Serializable;
import java.math.BigDecimal;

/**
 * 
 * @TableName teacher
 */
@Data
public class CourseDTO implements Serializable {

    private String id;

    private String name;

    private BigDecimal credits;

    private static final long serialVersionUID = 1L;
}

3.3.2 课程管理功能实体类query

package site.lyweb.domain.query;

import lombok.Data;

import java.math.BigDecimal;

/**
 * 
 * @TableName teacher
 */
@Data
public class CourseQuery {

    private String id;

    private String name;

    private BigDecimal startCredits;

    private BigDecimal endCredits;

}

3.3.3 课程管理功能实体类po

package site.lyweb.domain.dto;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.io.Serializable;
import java.math.BigDecimal;

/**
 * 
 * @TableName course
 */
@TableName(value ="course")
@Data
public class Course implements Serializable {
    /**
     * 
     */
    @TableId
    private String id;

    /**
     * 
     */
    private String name;

    /**
     * 
     */
    private BigDecimal credits;

    @TableField(exist = false)
    private static final long serialVersionUID = 1L;

    @Override
    public boolean equals(Object that) {
        if (this == that) {
            return true;
        }
        if (that == null) {
            return false;
        }
        if (getClass() != that.getClass()) {
            return false;
        }
        Course other = (Course) that;
        return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
            && (this.getName() == null ? other.getName() == null : this.getName().equals(other.getName()))
            && (this.getCredits() == null ? other.getCredits() == null : this.getCredits().equals(other.getCredits()));
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
        result = prime * result + ((getName() == null) ? 0 : getName().hashCode());
        result = prime * result + ((getCredits() == null) ? 0 : getCredits().hashCode());
        return result;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(" [");
        sb.append("Hash = ").append(hashCode());
        sb.append(", id=").append(id);
        sb.append(", name=").append(name);
        sb.append(", credits=").append(credits);
        sb.append(", serialVersionUID=").append(serialVersionUID);
        sb.append("]");
        return sb.toString();
    }
}

3.3.4 课程管理功能mapper层

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="site.lyweb.mapper.CourseMapper">

    <resultMap id="BaseResultMap" type="site.lyweb.domain.dto.Course">
            <id property="id" column="id" jdbcType="VARCHAR"/>
            <result property="name" column="name" jdbcType="VARCHAR"/>
            <result property="credits" column="credits" jdbcType="DECIMAL"/>
    </resultMap>

    <sql id="Base_Column_List">
        id,name,credits
    </sql>
    <select id="selectByCount" resultType="java.lang.Integer">
        select
        count(0)
        from course t
        <where>
            <if test="id != null">
                and t.id = #{id, jdbcType=INTEGER}
            </if>
            <if test="name != null">
                and t.name = #{name,jdbcType=VARCHAR}
            </if>
            <if test="startCredits != null">
                <![CDATA[    and t.credits >= #{startCredits, jdbcType=VARCHAR}    ]]>
            </if>
            <if test="endCredits != null">
                <![CDATA[    and t.credits <= #{endCredits, jdbcType=VARCHAR}    ]]>
            </if>

        </where>
    </select>

    <select id="selectByPage" parameterType="java.lang.Integer" resultType="site.lyweb.domain.dto.Course">
        select *
        from course t
        <where>
            <if test="id != null">
                and t.id = #{id, jdbcType=INTEGER}
            </if>
            <if test="name != null">
                and t.name = #{name,jdbcType=VARCHAR}
            </if>
            <if test="startCredits != null">
                <![CDATA[    and t.credits >= #{startCredits, jdbcType=VARCHAR}    ]]>
            </if>
            <if test="endCredits != null">
                <![CDATA[    and t.credits <= #{endCredits, jdbcType=VARCHAR}    ]]>
            </if>

        </where>
    </select>
</mapper>

3.3.5 课程管理功能mapper层接口

package site.lyweb.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import site.lyweb.domain.dto.Course;
import site.lyweb.domain.dto.Student;
import site.lyweb.domain.query.CourseQuery;
import site.lyweb.domain.query.StudentQuery;

import java.util.List;

/**
* @author 深山老林
* @description 针对表【course】的数据库操作Mapper
* @createDate 2024-06-19 20:53:31
* @Entity generator.domain.Course
*/
public interface CourseMapper extends BaseMapper<Course> {

    int selectByCount(CourseQuery courseQuery);

    List<Course> selectByPage(CourseQuery courseQuery);
}

3.3.6 课程管理功能service层

package site.lyweb.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import site.lyweb.constant.Constant;
import site.lyweb.domain.dto.Course;
import site.lyweb.domain.dto.CourseDTO;
import site.lyweb.domain.dto.PageDTO;
import site.lyweb.domain.query.CourseQuery;
import site.lyweb.mapper.CourseMapper;
import site.lyweb.service.CourseService;
import site.lyweb.utils.ExtBeanUtils;

import java.util.List;

/**
* @author 深山老林
* @description 针对表【course】的数据库操作Service实现
* @createDate 2024-06-19 20:53:31
*/
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course>
    implements CourseService {

    @Resource
    private CourseMapper courseMapper;
    /**
     * 分页 + 搜索
     *
     * @param current
     * @param courseQuery
     * @return
     */
    @Override
    public PageDTO<CourseDTO> getCourseByPage(Integer current, CourseQuery courseQuery) {
        //分页查询分两个查询,1、查符合条件的数据总条数;2、查询当前页的数据
        int totalRow = courseMapper.selectByCount(courseQuery);
        int start = (current - 1) * Constant.PAGE_SIZE;
        List<Course> courseList = courseMapper.selectByPage(courseQuery);
        int totalPage = totalRow / Constant.PAGE_SIZE;
        if (totalRow % Constant.PAGE_SIZE > 0) { //如果除不尽,总页数就需要加1
            totalPage ++;
        }
        //需要把 List<TUser> 转换为 List<UserInfoDTO>
        List<CourseDTO> courseDTOList = ExtBeanUtils.copyPropertiesForList(courseList, CourseDTO.class);

        return new PageDTO<>(current, Constant.PAGE_SIZE, totalRow, totalPage, courseDTOList);

    }
}

3.3.7 课程管理功能service层接口

package site.lyweb.service;

import com.baomidou.mybatisplus.extension.service.IService;
import site.lyweb.domain.dto.Course;
import site.lyweb.domain.dto.CourseDTO;
import site.lyweb.domain.dto.PageDTO;
import site.lyweb.domain.dto.StudentDTO;
import site.lyweb.domain.query.CourseQuery;
import site.lyweb.domain.query.StudentQuery;

/**
* @author 深山老林
* @description 针对表【course】的数据库操作Service
* @createDate 2024-06-19 20:53:31
*/
public interface CourseService extends IService<Course> {

    PageDTO<CourseDTO> getCourseByPage(Integer current, CourseQuery courseQuery);
}

3.3.8 课程管理功能controller层

package site.lyweb.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import site.lyweb.domain.dto.Course;
import site.lyweb.domain.dto.CourseDTO;
import site.lyweb.domain.dto.PageDTO;
import site.lyweb.domain.query.CourseQuery;
import site.lyweb.result.RestResult;
import site.lyweb.service.CourseService;
import site.lyweb.utils.UUIDUtils;

import java.util.Arrays;
import java.util.List;

/**
 * @Author 林瑶
 * @Description TODO
 * @Date 2024/6/20 0:01
 */
@CrossOrigin
@RestController
@Tag(name="课程管理模块")
@Slf4j
@RequestMapping("/course")
public class CourseController {
    @Resource
    private CourseService courseService;

    /**
     * 根据id查找课程信息表中信息
     */
    @Operation(summary = "根据id查找课程信息表中信息")
    @Parameters({
            @Parameter(name = "id",description = "id(主键)",in = ParameterIn.PATH)
    })
    @GetMapping("/course_info/getById/{id}")
    public RestResult queryCourseById(@PathVariable("id") String id){
        Course byId = courseService.getById(id);

        return RestResult.SUCCESS(byId);
    }
    /**
     * 查找全部课程信息表中信息
     */
    @Operation(summary = "查找全部课程信息表中信息")
    @GetMapping("/course_info/getAll")
    public RestResult queryCourseAll(){
        return RestResult.SUCCESS(courseService.list());
    }
    /**
     * 根据id删除课程信息表中信息
     */
    @Operation(summary = "根据id删除学生课程表中信息")
    @Parameters({
            @Parameter(name = "id",description = "id(主键)",in = ParameterIn.PATH)
    })
    @PostMapping("/course_info/del/{id}")
    public RestResult delCourseById(@PathVariable("id") String id){
        return courseService.removeById(id) ?RestResult.SUCCESS("删除学生信息表中信息成功"):RestResult.FAIL("删除学生信息表中信息失败");
    }

    /**
     * 保存课程信息表中信息
     */
    @Operation(summary = "保存课程信息表中信息")
    @PostMapping("/course_info/edit")
    @Parameters({
            @Parameter(name = "id",description = "id(主键)",in = ParameterIn.QUERY),
            @Parameter(name = "name",description = "课程名",in = ParameterIn.QUERY),
            @Parameter(name = "credits",description = "学分",in = ParameterIn.QUERY),
    })
    public RestResult editCourse(Course course){
        if(course!=null){
            //有id:修改,无id:添加
            if(course.getId()!=null && !course.getId().isEmpty()){
                return courseService.updateById(course)?RestResult.SUCCESS("修改成功:"+course):RestResult.FAIL();
            }else{
                course.setId(UUIDUtils.getUUID());
                return courseService.save(course)?RestResult.SUCCESS("添加成功:"+course):RestResult.FAIL();
            }
        }
        return RestResult.FAIL("传入学生对象为空,保存失败");
    }

    /**
     * 分页查询课程列表数据
     *
     * @return
     */

    @Operation(summary = "分页查询课程列表数据")
    @GetMapping(value = "/course_info/getCourseByPage")
    public RestResult getCourseByPage( CourseQuery courseQuery) {


        //分页查询的结果用PageDTO进行封装
        PageDTO<CourseDTO> pageDTO = courseService.getCourseByPage(0, courseQuery);

        //有的时候,查询可以不判断成功与失败,不管查没查到数据,都返回200,页面上去控制显示
        return RestResult.SUCCESS(pageDTO);
    }
    /**
     * 根据id批量课程信息表中信息
     */
    @Operation(summary = "根据ids删除课程信息表中信息")
    @Parameters({
            @Parameter(name = "ids",description = "id(主键)",in = ParameterIn.PATH)
    })
    @CrossOrigin
    @PostMapping("/course_info/batchDel/{ids}")
    public RestResult batchDelCourseById(@PathVariable("ids") String ids){
        //ids = "1,2,5,7,10,12" , ids.split(",")是把ids转成数组, Arrays.asList()是把数组转成List
        List<String> idList = Arrays.asList(ids.split(","));

        return  courseService.removeBatchByIds(idList) ? RestResult.SUCCESS() : RestResult.FAIL();
    }
}

3.3.9 课程管理功能前端主页面(教师端)

<template>
  <el-form :inline="true" :model="courseSearchQuery" class="demo-form-inline">
    <el-form-item label="课程名称">
      <el-input v-model="courseSearchQuery.name" placeholder="请输入课程名称" clearable />
    </el-form-item>
    <el-form-item label="学分区间左">
      <el-input v-model="courseSearchQuery.startCredits" placeholder="请输入最小学分" clearable />
    </el-form-item>    
    <el-form-item label="学分区间右">
      <el-input v-model="courseSearchQuery.endCredits" placeholder="请输入最大学分" clearable />
    </el-form-item>

    <el-form-item>
      <el-button type="primary" @click="onSarch">搜 索</el-button>
      <el-button type="primary" plain @click="onReset">重 置</el-button>
    </el-form-item>
  </el-form>
  <br/><br/>

  <el-button type="primary" @click="addCourse">增加课程信息</el-button>
  <el-button type="danger" @click="batchDelCourse">批量删除</el-button>
  <br/><br/>

  <el-table
      ref="multipleTableRef"
      :data="courseList"
      style="width: 100%"
      @selection-change="handleSelectionChange">
    <el-table-column type="selection" width="55" />
    <el-table-column type="index" label="序号" width="200" />
    <el-table-column property="name" label="课程名称" width="400"/>
    <el-table-column property="credits" label="学分" />
    <el-table-column label="操作" width="230">
      <template #default="scope"><!--vue插槽-->
        <el-button type="success" @click="edit(scope.row.id)">编辑</el-button>
        <el-button type="danger" @click="del(scope.row.id)">删除</el-button>
      </template>
    </el-table-column>
  </el-table>
  <br/>

  <el-pagination background
                 layout="prev, pager, next"
                 :page-size="pageSize"
                 :total="totalRow"
                 @prev-click="page"
                 @next-click="page"
                 @current-change="page"/>

</template>

<script>
import {doPost, doGet} from "@/http/axios-http";
import {message, messageConfirm} from "@/http/message";

export default {

  //注入reload
  inject : ['reload'],

  data() {
    return {
      //课程搜索条件对象,初始值是空
      courseSearchQuery : {},
      //课程列表list对象数据,初始值是空
      courseList : [{}],
      //每页显示多少条
      pageSize : 0,
      //总共有多少条
      totalRow : 0,
      //勾选了哪些课程id,默认值是空
      courseIdArray : []
    }
  },

  //页面渲染时触发该钩子函数
  mounted() {
    // this.loadAllUser();
    this.getData();
  },

  methods : {
    //查询课程列表数据
    getData() {
      doGet('/course/course_info/getCourseByPage',this.courseSearchQuery).then(resp => {
        console.log(resp)
        if (resp.data.code === 200) {
          this.courseList = resp.data.data.dataList;
          this.pageSize = resp.data.data.pageSize;
          this.totalRow = resp.data.data.totalRow;
        }
      })
    },

    //搜索
    onSarch() {
      this.getData();
    },
    //重置
    onReset() {
      this.courseSearchQuery = {};
    },

    //录入课程
    addCourse() {
      //跳转路由
      this.$router.push({path : "/teacherDash/course_info/add"});
      //window.location.href = "/dashboard/course/add";
    },

    //编辑课程
    edit(id) {
      console.log(id);
      this.$router.push({path : "/teacherDash/course_info/edit/" + id});
    },

    //删除课程
    del(id) {
      //首先提示用户是否确定要删除
      messageConfirm("您是否确定要删除此数据?").then(() => { //当你点“确定”,执行该函
        doPost("/course/course_info/del/" + id, {}).then(resp => {
          if (resp.data.code === 200) {
            //删除成功
            message("删除成功", "success");
            //刷新页面
            this.reload();
          } else {
            message("删除失败,原因:" + resp.data.msg, "error");
          }
        })
      }).catch(error => { //当你点“取消”,执行该函数
        message("删除错误:"+error, "warning");
        
      });
    },

    //批量删除课程
    batchDelCourse() {
      //用户没有选数据,要提示一下
      if (this.courseIdArray.length <= 0) {
        message("请选择要删除的数据", "warning");
        return;
      }
      //1、拿到选择的id
      let ids = this.courseIdArray.join(",");  //得到:ids = "1,2,5,7,10,12"
      //2、把这些id的数据删除
      messageConfirm("您是否确定要删除这些数据?").then(() => { //当你点“确定”,执行该函
        doPost("/course/course_info/batchDel/" + ids, {}).then(resp => {
          if (resp.data.code === 200) {
            //删除成功
            message("删除成功", "success");
            //刷新页面
            this.reload();
          } else {
            //删除失败
            message("删除失败,原因:" + resp.data.msg, "error");
          }
        })
      }).catch(() => { //当你点“取消”,执行该函数
        message("删除已取消", "warning");
      });
    },

    //勾选或取消复选框时触发该函数
    handleSelectionChange(selection) {
      //勾选或取消复选框时,先把用户id的数组清空
      this.courseIdArray = [];
      selection.forEach( (course) => {
        this.courseIdArray.push(course.id);
      });
    }
  }
}

</script>

<style>

</style>


3.3.10 课程管理功能前端添加页面(学生端)

<template>
  <el-form
      label-width="80px"
      style="max-width: 95%;">

    <el-form-item label="课程名称">
      <el-input v-model="courseQuery.name" @blur="checkName"/>
      <span style="color: red;"> {{formError.nameMsg}} </span>
    </el-form-item>

    <el-form-item label="课程学分">
      <el-input v-model="courseQuery.credits" @blur="checkCredits"/>
      <span style="color: red;"> {{formError.creditsMsg}} </span>
    </el-form-item>

    <el-form-item>
      <el-input type="hidden" v-model="courseQuery.id"/>
      <el-button type="primary" @click="addCourseSubmit">提 交</el-button>
      <el-button type="success" plain @click="back">返 回</el-button>
    </el-form-item>
  </el-form>
</template>

<script>
import {doGet, doPost, doPut} from "@/http/axios-http";
import {message} from "@/http/message";

export default {

  data() {
    return {
      //课程对象,初始值是空
      courseQuery : {},
      //form表单错误对象,初始值是空
      formError : {},
    }
  },

  mounted() {
    //根据路由id加载课程数据
    this.loadActivity();
  },

  methods : {
    //返回
    back() {
      //回退到上一次访问的页面
      //this.$router.go(-1);
      //精确地回到某个页面
      this.$router.push({path : "/teacherDash/course_info"})
    },

    //录入课程(提交保存)
    addCourseSubmit() {
      //表单提交,使用formData提交表单
      let formData = new FormData();
      for (let field in this.courseQuery) {
        formData.append(field, this.courseQuery[field]);
      }

      if (this.courseQuery.id) { //this.courseQuery对象有id,说明的做了一次查询,那么就修改
        doPost("/course/course_info/edit", formData).then(resp => {
          if (resp.data.code === 200) {
            //提示一下
            message("编辑课程信息成功", "success");
            //跳转到课程列表页
            this.$router.push({path : "/teacherDash/course_info"})
          } else {
            //提示一下
            message("编辑课程信息失败,原因:" + resp.data.msg, "error");
          }
        })
      } else {
        doPost("/course/course_info/edit", formData).then(resp => {
          console.log(resp)
          if (resp.data.code === 200) {
            //提示一下
            message("录入课程信息成功", "success");
            //跳转到课程列表页
            this.$router.push({path : "/teacherDash/course_info"})
          } else {
            //提示一下
            message("录入课程信息失败,原因:" + resp.data.msg, "error");
          }
        })
      }
    },

    //根据路由id加载课程数据
    loadActivity() {
      let id = this.$route.params.id;
      if (id) {
        //编辑需要把数据查出来
        doGet("/course/course_info/getById/" + id, {}).then(resp => {
          this.courseQuery = resp.data.data;
        })
      }
    }
  }
}
</script>

3.3.11 课程管理功能前端主页面(学生端)

<template>
  <el-form :inline="true" :model="courseSearchQuery" class="demo-form-inline">
    <el-form-item label="课程名称">
      <el-input v-model="courseSearchQuery.name" placeholder="请输入课程名称" clearable />
    </el-form-item>
    <el-form-item label="学分区间左">
      <el-input v-model="courseSearchQuery.startCredits" placeholder="请输入最小学分" clearable />
    </el-form-item>    
    <el-form-item label="学分区间右">
      <el-input v-model="courseSearchQuery.endCredits" placeholder="请输入最大学分" clearable />
    </el-form-item>

    <el-form-item>
      <el-button type="primary" @click="onSarch">搜 索</el-button>
      <el-button type="primary" plain @click="onReset">重 置</el-button>
    </el-form-item>
  </el-form>
  <br/><br/>

  <el-table
      ref="multipleTableRef"
      :data="courseList"
      style="width: 100%"
      @selection-change="handleSelectionChange">
    <el-table-column type="selection" width="55" />
    <el-table-column type="index" label="序号" width="200" />
    <el-table-column property="name" label="课程名称" width="400"/>
    <el-table-column property="credits" label="学分" />
    <el-table-column label="操作" width="230">
      <template #default="scope"><!--vue插槽-->
        <el-button type="success" @click="edit(scope.row.id)" disabled="true">编辑</el-button>
        <el-button type="danger" @click="del(scope.row.id)" disabled="true">删除</el-button>
      </template>
    </el-table-column>
  </el-table>
  <br/>

  <el-pagination background
                 layout="prev, pager, next"
                 :page-size="pageSize"
                 :total="totalRow"
                 @prev-click="page"
                 @next-click="page"
                 @current-change="page"/>

</template>

<script>
import {doPost, doGet} from "@/http/axios-http";
import {message, messageConfirm} from "@/http/message";

export default {

  //注入reload
  inject : ['reload'],

  data() {
    return {
      //课程搜索条件对象,初始值是空
      courseSearchQuery : {},
      //课程列表list对象数据,初始值是空
      courseList : [{}],
      //每页显示多少条
      pageSize : 0,
      //总共有多少条
      totalRow : 0,
      //勾选了哪些课程id,默认值是空
      courseIdArray : []
    }
  },

  //页面渲染时触发该钩子函数
  mounted() {
    // this.loadAllUser();
    this.getData();
  },

  methods : {
    //查询课程列表数据
    getData() {
      doGet('/course/course_info/getCourseByPage',this.courseSearchQuery).then(resp => {
        console.log(resp)
        if (resp.data.code === 200) {
          this.courseList = resp.data.data.dataList;
          this.pageSize = resp.data.data.pageSize;
          this.totalRow = resp.data.data.totalRow;
        }
      })
    },

    //搜索
    onSarch() {
      this.getData();
    },
    //重置
    onReset() {
      this.courseSearchQuery = {};
    },

    //录入课程
    addCourse() {
      //跳转路由
      this.$router.push({path : "/teacherDash/course_info/add"});
      //window.location.href = "/dashboard/course/add";
    },

    //编辑课程
    edit(id) {
      console.log(id);
      this.$router.push({path : "/teacherDash/course_info/edit/" + id});
    },

    //删除课程
    del(id) {
      //首先提示用户是否确定要删除
      messageConfirm("您是否确定要删除此数据?").then(() => { //当你点“确定”,执行该函
        doPost("/course/course_info/del/" + id, {}).then(resp => {
          if (resp.data.code === 200) {
            //删除成功
            message("删除成功", "success");
            //刷新页面
            this.reload();
          } else {
            message("删除失败,原因:" + resp.data.msg, "error");
          }
        })
      }).catch(error => { //当你点“取消”,执行该函数
        message("删除错误:"+error, "warning");
        
      });
    },

    //批量删除课程
    batchDelCourse() {
      //用户没有选数据,要提示一下
      if (this.courseIdArray.length <= 0) {
        message("请选择要删除的数据", "warning");
        return;
      }
      //1、拿到选择的id
      let ids = this.courseIdArray.join(",");  //得到:ids = "1,2,5,7,10,12"
      //2、把这些id的数据删除
      messageConfirm("您是否确定要删除这些数据?").then(() => { //当你点“确定”,执行该函
        doPost("/course/course_info/batchDel/" + ids, {}).then(resp => {
          if (resp.data.code === 200) {
            //删除成功
            message("删除成功", "success");
            //刷新页面
            this.reload();
          } else {
            //删除失败
            message("删除失败,原因:" + resp.data.msg, "error");
          }
        })
      }).catch(() => { //当你点“取消”,执行该函数
        message("删除已取消", "warning");
      });
    },

    //勾选或取消复选框时触发该函数
    handleSelectionChange(selection) {
      //勾选或取消复选框时,先把用户id的数组清空
      this.courseIdArray = [];
      selection.forEach( (course) => {
        this.courseIdArray.push(course.id);
      });
    }
  }
}
</script>
<style>
</style>

3.4学生选课管理功能模块

3.4.1 学生选课管理功能实体类dto

package site.lyweb.domain.dto;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import org.apache.ibatis.annotations.Param;

import java.io.Serializable;
import java.math.BigDecimal;

/**
 *
 * @TableName stu_course_relation
 */

@Data
public class StudentCourseDTO implements Serializable {

    //student_course_relation表的id
   
private String id;

    //student表的几个字段
   
private String studentName;

    private Integer studentAge;

    private String studentPhone;

    //course表的几个字段
   
private String courseName;

    private BigDecimal courseCredits;

    //teacher表的几个字段
   
private String teacherName;

    private Integer teacherAge;

    private String teacherProfession;

    private BigDecimal courseScore;
    private static final long serialVersionUID = 1L;
}

3.4.2 学生选课管理功能实体类query

package site.lyweb.domain.query;

import lombok.Data;
import org.apache.ibatis.annotations.Param;

import java.io.Serializable;
import java.math.BigDecimal;

/**
 *
 * @TableName stu_course_relation
 */

@Data
public class StudentCourseQuery{

    //student_course_relation表的id
   
private String id;

    //student表的几个字段
   
private String studentName;

    private Integer studentStartAge;

    private Integer studentEndAge;

    private String studentPhone;

    //course表的几个字段
   
private String courseName;

    private BigDecimal courseStartCredits;

    private BigDecimal courseEndCredits;

    //teacher表的几个字段
   
private String teacherName;

    private Integer teacherStartAge;

    private Integer teacherEndAge;

    private String teacherProfession;

    private BigDecimal courseScore;
}

3.4.3 学生选课管理功能实体类po

package site.lyweb.domain.dto;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Objects;

/**
 *
 * @TableName teacher
 */

@Data
public class StudentCourse implements Serializable {

    //student_course_relation表的id
   
@TableId
    private String id;

    //student表的几个字段
   
private String studentName;

    private Integer studentAge;

    private String studentPhone;

    //course表的几个字段
   
private String courseName;

    private BigDecimal courseCredits;

    //teacher表的几个字段
   
private String teacherName;

    private Integer teacherAge;

    private String teacherProfession;

    private BigDecimal courseScore;

    @TableField(exist = false)
    private static final long serialVersionUID = 1L;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        StudentCourse that = (StudentCourse) o;
        return Objects.equals(id, that.id) && Objects.equals(studentName, that.studentName) && Objects.equals(studentAge, that.studentAge) && Objects.equals(studentPhone, that.studentPhone) && Objects.equals(courseName, that.courseName) && Objects.equals(courseCredits, that.courseCredits) && Objects.equals(teacherName, that.teacherName) && Objects.equals(teacherAge, that.teacherAge) && Objects.equals(teacherProfession, that.teacherProfession);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, studentName, studentAge, studentPhone, courseName, courseCredits, teacherName, teacherAge, teacherProfession);
    }

    @Override
    public String toString() {
        return "StudentCourse{" +
                "id='" + id + '\'' +
                ", studentName='" + studentName + '\'' +
                ", studentAge=" + studentAge +
                ", studentPhone='" + studentPhone + '\'' +
                ", courseName='" + courseName + '\'' +
                ", courseCredits=" + courseCredits +
                ", teacherName='" + teacherName + '\'' +
                ", teacherAge=" + teacherAge +
                ", teacherProfession='" + teacherProfession + '\'' +
                '}';
    }
}

3.4.4 学生选课管理功能mapper层

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="site.lyweb.mapper.StudentCourseMapper">

    <select id="selectByCount" resultType="java.lang.Integer">
        select
        count(0)
        from stu_course_relation t1
        left join teacher t2
            on t1.teacher_id = t2.id
        left join course t3
            on t1.course_id = t3.id
        left join student t4
            on t1.stu_id = t4.id
        
<where>
            <if test="id != null">
                and t1.id = #{id, jdbcType=VARCHAR}
           
</if>
            <!--teacher:老师姓名-->
           
<if test="teacherName != null">
                and t2.name = #{teacherName,jdbcType=VARCHAR}
           
</if>
            <!--teacher:年龄区间-->
           
<if test="teacherStartAge != null">
                <![CDATA[    and t2.age >= #{teacherStartAge, jdbcType=INTEGER}    ]]>
            </if>
            <if test="teacherEndAge != null">
                <![CDATA[    and t2.age <= #{teacherEndAge, jdbcType=INTEGER}    ]]>
            </if>
            <!--teacher:专业-->
           
<if test="teacherProfession != null">
                and t2.profession = #{teacherProfession,jdbcType=VARCHAR}
           
</if>
            <!--course:课程名-->
           
<if test="courseName != null">
                and t3.name = #{courseName,jdbcType=VARCHAR}
           
</if>
            <!--course:学分区间-->
           
<if test="courseStartCredits != null">
                <![CDATA[    and t3.credits >= #{courseStartCredits, jdbcType=DECIMAL}    ]]>
            </if>
            <if test="courseEndCredits != null">
                <![CDATA[    and t3.credits <= #{courseEndCredits, jdbcType=DECIMAL}    ]]>
            </if>
            <!--student:学生姓名-->
           
<if test="studentName != null">
                and t4.name = #{studentName,jdbcType=VARCHAR}
           
</if>
            <!--student:年龄区间-->
           
<if test="studentStartAge != null">
                <![CDATA[    and t4.age >= #{studentStartAge, jdbcType=INTEGER}    ]]>
            </if>
            <if test="studentEndAge != null">
                <![CDATA[    and t4.age <= #{studentEndAge, jdbcType=INTEGER}    ]]>
            </if>
            <!--student:手机号-->
           
<if test="studentPhone != null">
                and t4.phone = #{studentPhone,jdbcType=VARCHAR}
            </if>
        </where>
    </select>

    <select id="selectByPage" parameterType="java.lang.String" resultType="site.lyweb.domain.dto.StudentCourse">
        select t1.id,
                t2.name teacherName,t2.age teacherAge,t2.profession teacherProfession,
                t3.name courseName,t3.credits courseCredits,
                t4.name studentName,t4.age studentAge,t4.phone studentPhone
        from stu_course_relation t1
        left join teacher t2
        on t1.teacher_id = t2.id
        left join course t3
        on t1.course_id = t3.id
        left join student t4
        on t1.stu_id = t4.id
       
<where>
            <if test="id != null">
                and t1.id = #{id, jdbcType=VARCHAR}
           
</if>
            <!--teacher:老师姓名-->
           
<if test="teacherName != null">
                and t2.name = #{teacherName,jdbcType=VARCHAR}
           
</if>
            <!--teacher:年龄区间-->
           
<if test="teacherStartAge != null">
                <![CDATA[    and t2.age >= #{teacherStartAge, jdbcType=INTEGER}    ]]>
            </if>
            <if test="teacherEndAge != null">
                <![CDATA[    and t2.age <= #{teacherEndAge, jdbcType=INTEGER}    ]]>
            </if>
            <!--teacher:专业-->
           
<if test="teacherProfession != null">
                and t2.profession = #{teacherProfession,jdbcType=VARCHAR}
           
</if>
            <!--course:课程名-->
           
<if test="courseName != null">
                and t3.name = #{courseName,jdbcType=VARCHAR}
           
</if>
            <!--course:学分区间-->
           
<if test="courseStartCredits != null">
                <![CDATA[    and t3.credits >= #{courseStartCredits, jdbcType=DECIMAL}    ]]>
            </if>
            <if test="courseEndCredits != null">
                <![CDATA[    and t3.credits <= #{courseEndCredits, jdbcType=DECIMAL}    ]]>
            </if>
            <!--student:学生姓名-->
           
<if test="studentName != null">
                and t4.name = #{studentName,jdbcType=VARCHAR}
           
</if>
            <!--student:年龄区间-->
           
<if test="studentStartAge != null">
                <![CDATA[    and t4.age >= #{studentStartAge, jdbcType=INTEGER}    ]]>
            </if>
            <if test="studentEndAge != null">
                <![CDATA[    and t4.age <= #{studentEndAge, jdbcType=INTEGER}    ]]>
            </if>
            <!--student:手机号-->
           
<if test="studentPhone != null">
                and t4.phone = #{studentPhone,jdbcType=VARCHAR}
            </if>
        </where>
    </select>
    <!--批量删除-->
   
<delete id="removeBatchByIds">
        delete from stu_course_relation
        where id in
       
<foreach collection="idList" item="id" open="(" separator="," close=")">
            #{id, jdbcType=VARCHAR}
        </foreach>
    </delete>
    <!--根据id删除-->
   
<delete id="removeById" parameterType="java.lang.String">
        delete from stu_course_relation
        where id = #{id,jdbcType=VARCHAR}
   
</delete>
    <!--插入数据-->
   
<insert id="insert">
        insert into stu_course_relation (id,stu_id,course_id,teacher_id,course_score)
            values(#{id,jdbcType=VARCHAR},#{studentId,jdbcType=VARCHAR},#{courseId,jdbcType=VARCHAR},
            #{teacherId,jdbcType=VARCHAR},#{courseScore,jdbcType=DECIMAL});
   
</insert>
    <!--更新数据-->
   
<update id="update">
        update stu_course_relation
        set
            stu_id = #{studentId,jdbcType=VARCHAR},
            course_id = #{courseId,jdbcType=VARCHAR},
            teacher_id = #{teacherId,jdbcType=VARCHAR},
            course_score = #{courseScore,jdbcType=DECIMAL}
        where id = #{id,jdbcType=VARCHAR}
   
</update>

    <select id="getById" resultType="site.lyweb.domain.dto.StuCourseRelation">
        select * from stu_course_relation
        where id = #{id,jdbcType=VARCHAR}
   
</select>
</mapper>

3.4.5 学生选课管理功能mapper层接口

package site.lyweb.mapper;

import org.apache.ibatis.annotations.Param;
import site.lyweb.domain.dto.StuCourseRelation;
import site.lyweb.domain.dto.TeaCourseRelation;
import site.lyweb.domain.dto.StudentCourse;
import site.lyweb.domain.query.StudentCourseQuery;

import java.math.BigDecimal;
import java.util.List;

/**
 * @author
深山老林
 
* @description 针对表【student】的数据库操作Mapper
 * @createDate 2024-06-19 20:53:32
 * @Entity generator.domain.Student
 */

public interface StudentCourseMapper {

    int selectByCount(StudentCourseQuery studentCourseQuery);

    List<StudentCourse> selectByPage(StudentCourseQuery studentCourseQuery);

    boolean removeBatchByIds(List<String> idList);

    boolean removeById(String id);

    boolean insert(@Param("id") String id,@Param("studentId") String studentId,
                   @Param("courseId") String courseId,@Param("teacherId")String teacherId,
                   @Param("courseScore") BigDecimal courseScore);

    boolean update(@Param("id") String id,@Param("studentId") String studentId,
                   @Param("courseId") String courseId,@Param("teacherId")String teacherId,
                   @Param("courseScore") BigDecimal courseScore);

    StuCourseRelation getById(String id);
}



 

3.4.6 学生选课管理功能service层

package site.lyweb.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import site.lyweb.constant.Constant;
import site.lyweb.domain.dto.*;
import site.lyweb.domain.query.StudentQuery;
import site.lyweb.domain.query.TeacherQuery;
import site.lyweb.mapper.StudentMapper;
import site.lyweb.service.StudentService;
import site.lyweb.utils.ExtBeanUtils;

import java.util.List;

/**
* @author
深山老林
* @description 针对表【student】的数据库操作Service实现
* @createDate 2024-06-19 20:53:31
*/

@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student>
    implements StudentService {

    @Resource
    private StudentMapper studentMapper;
    /**
     *
分页 + 搜索
    
*
     * @param
current
    
* @param studentQuery
    
* @return
     */
   
@Override
    public PageDTO<StudentDTO> getStudentByPage(Integer current, StudentQuery studentQuery) {
        //分页查询分两个查询,1、查符合条件的数据总条数;2、查询当前页的数据
       
int totalRow = studentMapper.selectByCount(studentQuery);
        int start = (current - 1) * Constant.PAGE_SIZE;
        List<Student> studentList = studentMapper.selectByPage(studentQuery);
        int totalPage = totalRow / Constant.PAGE_SIZE;
        if (totalRow % Constant.PAGE_SIZE > 0) { //如果除不尽,总页数就需要加1
           
totalPage ++;
        }
        //需要把 List<TUser> 转换为 List<UserInfoDTO>
       
List<StudentDTO> studentDTOList = ExtBeanUtils.copyPropertiesForList(studentList, StudentDTO.class);

        return new PageDTO<>(current, Constant.PAGE_SIZE, totalRow, totalPage, studentDTOList);

    }

}

3.4.7 学生选课管理功能service层接口

package site.lyweb.service;

import site.lyweb.domain.dto.PageDTO;
import site.lyweb.domain.dto.StuCourseRelation;
import site.lyweb.domain.dto.TeaCourseRelation;
import site.lyweb.domain.dto.StudentCourseDTO;
import site.lyweb.domain.query.StudentCourseQuery;

import java.math.BigDecimal;
import java.util.List;

/**
 * @author
深山老林
 
* @description 针对表【student】的数据库操作Service
 * @createDate 2024-06-19 20:53:32
 */

public interface StudentCourseService {

    PageDTO<StudentCourseDTO> getStudentCourseByPage(Integer current, StudentCourseQuery studentCourseQuery);

    boolean removeBatchByIds(List<String> idList);

    boolean removeById(String id);

    boolean save(String id, String studentId, String courseId, String teacherId, BigDecimal courseScore);

    StuCourseRelation getById(String id);
}

3.4.8 学生选课管理功能controller层

package site.lyweb.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import site.lyweb.domain.dto.PageDTO;
import site.lyweb.domain.dto.StuCourseRelation;
import site.lyweb.domain.dto.TeaCourseRelation;
import site.lyweb.domain.dto.StudentCourseDTO;
import site.lyweb.domain.query.StudentCourseQuery;
import site.lyweb.result.RestResult;
import site.lyweb.service.StudentCourseService;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;

/**
 * @Author
林瑶
 
* @Description TODO
 
* @Date 2024/6/20 2:21
 */

@CrossOrigin(origins = "*")
@RestController
@Tag(name="学生选课管理模块")
@Slf4j
@RequestMapping("/student_course")
public class StudentCourseController {
    @Resource
    private StudentCourseService studentCourseService;
    /**
     *
分页查询学生选课列表数据
    
*
     * @return
     */

   
@Operation(summary = "分页查询学生选课列表数据")
    @GetMapping(value = "/student_course_info/getStudentCourseByPage")
    public RestResult getStudentCourseByPage( StudentCourseQuery studentCourseQuery) {


        //分页查询的结果用PageDTO进行封装
       
PageDTO<StudentCourseDTO> pageDTO = studentCourseService.getStudentCourseByPage(0, studentCourseQuery);

        //有的时候,查询可以不判断成功与失败,不管查没查到数据,都返回200,页面上去控制显示
       
return RestResult.SUCCESS(pageDTO);
    }
    /**
     *
根据id批量学生选课信息表中信息
    
*/
   
@Operation(summary = "根据ids删除学生选课信息表中信息")
    @Parameters({
            @Parameter(name = "ids",description = "id(主键)",in = ParameterIn.PATH)
    })
    @CrossOrigin
    @PostMapping("/student_course_info/batchDel/{ids}")
    public RestResult batchDelStudentCourseById(@PathVariable("ids") String ids){
        //ids = "1,2,5,7,10,12" , ids.split(",")是把ids转成数组, Arrays.asList()是把数组转成List
       
List<String> idList = Arrays.asList(ids.split(","));
        return  studentCourseService.removeBatchByIds(idList) ? RestResult.SUCCESS() : RestResult.FAIL();
    }
    /**
     *
根据id学生选课信息表中信息
    
*/
   
@Operation(summary = "根据id删除学生选课信息表中信息")
    @Parameters({
            @Parameter(name = "id",description = "id(主键)",in = ParameterIn.PATH)
    })
    @CrossOrigin
    @PostMapping("/student_course_info/del/{id}")
    public RestResult delStudentCourseById(@PathVariable("id") String id){
        return  studentCourseService.removeById(id) ? RestResult.SUCCESS() : RestResult.FAIL();
    }
    /**
     *
保存学生选课信息表中信息
    
*/
   
@Operation(summary = "保存学生选课信息表中信息")
    @PostMapping("/student_course_info/save")
    @Parameters({
            @Parameter(name = "id",description = "id(主键)",in = ParameterIn.QUERY),
            @Parameter(name = "stuId",description = "学生id",in = ParameterIn.QUERY),
            @Parameter(name = "courseId",description = "课程id",in = ParameterIn.QUERY),
            @Parameter(name = "teacherId",description = "老师id",in = ParameterIn.QUERY),
    })
    public RestResult saveStudentCourse(StuCourseRelation stuCourseRelation){
        String id = stuCourseRelation.getId();
        String studentId = stuCourseRelation.getStuId();
        String courseId = stuCourseRelation.getCourseId();
        String teacherId = stuCourseRelation.getTeacherId();
        BigDecimal courseScore = stuCourseRelation.getCourseScore();
        System.out.println("看看正确嘛:"+stuCourseRelation);
        return studentCourseService.save(id,studentId,courseId,teacherId,courseScore)?RestResult.SUCCESS("保存学生选课信息表中信息成功"):RestResult.FAIL("保存学生选课信息表中信息失败");
    }
    /**
     *
根据id查询选课信息表中信息
    
*/
   
@Operation(summary = "根据id查询学生选课信息表中信息")
    @Parameters({
            @Parameter(name = "id",description = "id(主键)",in = ParameterIn.PATH)
    })
    @CrossOrigin
    @GetMapping("/student_course_info/get/{id}")
    public RestResult getStudentCourseById(@PathVariable("id") String id){
        try{
            return RestResult.SUCCESS(studentCourseService.getById(id)) ;
        }catch (Exception e){
            e.printStackTrace();
            return RestResult.FAIL("查询失败");
        }

    }
}

3.4.9 学生选课管理功能前端主页面(教师端)

<template>

  <el-form :inline="true" :model="studentCourseSearchQuery" class="demo-form-inline">

    <el-form-item label="学生名称">

      <el-select

          v-model="studentCourseSearchQuery.studentName"

          placeholder="请选择学生姓名"

          style="width: 160px"

          clearable>

        <el-option

            v-for="item in studentOptions"

            :key="item.id"

            :label="item.name"

            :value="item.name"/>

      </el-select>

    </el-form-item>

    <el-form-item label="学生年龄区间左">

      <el-input v-model="studentCourseSearchQuery.studentStartAge" placeholder="请输入最小年龄" clearable  

      style="width: 160px"/>

    </el-form-item>    

    <el-form-item label="学生年龄区间右">

      <el-input v-model="studentCourseSearchQuery.studentEndAge" placeholder="请输入最大年龄" clearable  

      style="width: 160px"/>

    </el-form-item>    

    <el-form-item label="学生手机号">

      <el-input v-model="studentCourseSearchQuery.studentPhone" placeholder="请输入学生的手机号" clearable />

    </el-form-item>

    <el-form-item label="课程名称">

      <el-select

          v-model="studentCourseSearchQuery.courseName"

          placeholder="请选择课程名称"

          style="width: 160px"

          clearable>

        <el-option

            v-for="item in courseOptions"

            :key="item.id"

            :label="item.name"

            :value="item.name"/>

      </el-select>

    </el-form-item>

    <el-form-item label="课程学分区间左">

      <el-input v-model="studentCourseSearchQuery.courseStartCredits" placeholder="请输入最小学分" clearable

      style="width: 160px"/>

    </el-form-item>    

    <el-form-item label="课程学分区间右">

      <el-input v-model="studentCourseSearchQuery.courseEndCredits" placeholder="请输入最大学分" clearable

      style="width: 160px"/>

    </el-form-item>

    <br/>

    <el-form-item label="老师名称">

      <el-select

          v-model="studentCourseSearchQuery.teacherName"

          placeholder="请选择老师姓名"

          style="width: 160px"

          clearable>

        <el-option

            v-for="item in teacherOptions"

            :key="item.id"

            :label="item.name"

            :value="item.name"/>

      </el-select>

    </el-form-item>

    <el-form-item label="老师年龄区间左">

      <el-input v-model="studentCourseSearchQuery.teacherStartAge" placeholder="请输入最小年龄" clearable

      style="width: 160px"/>

    </el-form-item>    

    <el-form-item label="老师年龄区间右">

      <el-input v-model="studentCourseSearchQuery.teacherEndAge" placeholder="请输入最大年龄" clearable

      style="width: 160px"/>

    </el-form-item>

    <el-form-item label="老师研究方向">

      <el-input v-model="studentCourseSearchQuery.teacherProfession" placeholder="请输入老师的研究方向" clearable />

    </el-form-item>

    <el-form-item>

      <el-button type="primary" @click="onSarch">搜 索</el-button>

      <el-button type="primary" plain @click="onReset">重 置</el-button>

    </el-form-item>

  </el-form>

  <br/><br/>

  <el-button type="primary" @click="addStudentCourse">增加学生选课信息</el-button>

  <el-button type="danger" @click="batchDelStudentCourse">批量删除</el-button>

  <br/><br/>

  <el-table

      ref="multipleTableRef"

      :data="studentCourseList"

      style="width: 100%"

      @selection-change="handleSelectionChange">

    <el-table-column type="selection" width="55" />

    <el-table-column type="index" label="序号" width="60" />

    <el-table-column property="studentName" label="学生姓名"/>

    <el-table-column property="studentAge" label="学生年龄" />

    <el-table-column property="studentPhone" label="学生手机号" />

    <el-table-column property="courseName" label="学生名" />

    <el-table-column property="courseCredits" label="学生学分" />

    <el-table-column property="teacherName" label="老师姓名"/>

    <el-table-column property="teacherAge" label="老师年龄" />

    <el-table-column property="teacherProfession" label="老师研究方向" />

    <el-table-column label="操作" width="230">

      <template #default="scope"><!--vue插槽-->

        <el-button type="success" @click="edit(scope.row.id)">编辑</el-button>

        <el-button type="danger" @click="del(scope.row.id)">删除</el-button>

      </template>

    </el-table-column>

  </el-table>

  <br/>

  <el-pagination background

                 layout="prev, pager, next"

                 :page-size="pageSize"

                 :total="totalRow"

                 @prev-click="page"

                 @next-click="page"

                 @current-change="page"/>

</template>

<script>

import {doPost, doGet} from "@/http/axios-http";

import {message, messageConfirm} from "@/http/message";

export default {

  //注入reload

  inject : ['reload'],

  data() {

    return {

      //学生选课搜索条件对象,初始值是空

      studentCourseSearchQuery : {},

      //学生选课列表list对象数据,初始值是空

      studentCourseList : [{}],

      //每页显示多少条

      pageSize : 0,

      //总共有多少条

      totalRow : 0,

      //勾选了哪些学生选课id,默认值是空

      studentCourseIdArray : [],

      studentOptions:[{}],

      courseOptions:[{}],

      teacherOptions:[{}],

    }

  },

  //页面渲染时触发该钩子函数

  mounted() {

    this.getData();

    this.loadAllStudent();

    this.loadAllCourse();

    this.loadAllTeacher();

  },

  methods : {

    loadAllStudent(){

      doGet('/student/stu_info/getAll').then(resp=>{

        console.log(resp.data)

        if(resp.data.code==200){

          this.studentOptions = resp.data.data;

        }else {

            //提示一下

            message("拿到学生信息失败,原因:" + resp.data.msg, "error");

          }

      })

    },

    loadAllCourse(){

      doGet('/course/course_info/getAll').then(resp=>{

        console.log(resp)

        if(resp.data.code==200){

          this.courseOptions = resp.data.data

        }else {

            //提示一下

            message("拿到课程信息失败,原因:" + resp.data.msg, "error");

          }

      })

    },

    loadAllTeacher(){

      doGet('/teacher/tea_info/getAll').then(resp=>{

        console.log(resp)

        if(resp.data.code==200){

          this.teacherOptions = resp.data.data

        }else {

            //提示一下

            message("拿到老师信息失败,原因:" + resp.data.msg, "error");

          }

      })

    },

    //查询学生选课列表数据

    getData() {

      doGet('/student_course/student_course_info/getStudentCourseByPage',this.studentCourseSearchQuery).then(resp => {

        console.log(resp)

        if (resp.data.code === 200) {

          this.studentCourseList = resp.data.data.dataList;

          this.pageSize = resp.data.data.pageSize;

          this.totalRow = resp.data.data.totalRow;

        }

      })

    },

    //搜索

    onSarch() {

      this.getData();

    },

    //重置

    onReset() {

      this.studentCourseSearchQuery = {};

    },

    //录入市场学生选课

    addStudentCourse() {

      //跳转路由

      this.$router.push({path : "/teacherDash/student_course_info/add"});

      //window.location.href = "/dashboard/studentCourse/add";

    },

    //编辑市场学生选课

    edit(id) {

      console.log(id);

      this.$router.push({path : "/teacherDash/student_course_info/edit/" + id});

    },

    //删除学生选课

    del(id) {

      //首先提示用户是否确定要删除

      messageConfirm("您是否确定要删除此数据?").then(() => { //当你点“确定”,执行该函

        doPost("/student_course/student_course_info/del/" + id, {}).then(resp => {

          if (resp.data.code === 200) {

            //删除成功

            message("删除成功", "success");

            //刷新页面

            this.reload();

          } else {

            message("删除失败,原因:" + resp.data.msg, "error");

          }

        })

      }).catch(error => { //当你点“取消”,执行该函数

        message("删除错误:"+error, "warning");

       

      });

    },

    //批量删除学生选课

    batchDelStudentCourse() {

      //用户没有选数据,要提示一下

      if (this.studentCourseIdArray.length <= 0) {

        message("请选择要删除的数据", "warning");

        return;

      }

      //1、拿到选择的id

      let ids = this.studentCourseIdArray.join(",");  //得到:ids = "1,2,5,7,10,12"

      //2、把这些id的数据删除

      messageConfirm("您是否确定要删除这些数据?").then(() => { //当你点“确定”,执行该函

        doPost("/student_course/student_course_info/batchDel/" + ids, {}).then(resp => {

          if (resp.data.code === 200) {

            //删除成功

            message("删除成功", "success");

            //刷新页面

            this.reload();

          } else {

            //删除失败

            message("删除失败,原因:" + resp.data.msg, "error");

          }

        })

      }).catch(() => { //当你点“取消”,执行该函数

        message("删除已取消", "warning");

      });

    },

    //勾选或取消复选框时触发该函数

    handleSelectionChange(selection) {

      //勾选或取消复选框时,先把用户id的数组清空

      this.studentCourseIdArray = [];

      selection.forEach( (studentCourse) => {

        this.studentCourseIdArray.push(studentCourse.id);

      });

    }

  }

}

</script>

<style>

</style>

3.4.10 学生选课管理功能前端添加页面(教师端)

<template>

  <el-form

      label-width="80px"

      style="max-width: 95%;">

    <el-form-item label="老师姓名">

      <el-select

          v-model="studentCourseQuery.teacherId"

          placeholder="请选择授课老师"

          style="width: 100%"

          clearable>

        <el-option

            v-for="item in teacherOptions"

            :key="item.id"

            :label="item.name"

            :value="item.id"/>

      </el-select>

    </el-form-item>

    <el-form-item label="课程名称">

      <el-select

          v-model="studentCourseQuery.courseId"

          placeholder="请选择课程名称"

          style="width: 100%"

          clearable>

        <el-option

            v-for="item in courseOptions"

            :key="item.id"

            :label="item.name"

            :value="item.id"/>

      </el-select>

    </el-form-item>

    <el-form-item>

      <el-input type="hidden" v-model="studentCourseQuery.id"/>

      <el-button type="primary" @click="addTeacherSubmit">提 交</el-button>

      <el-button type="success" plain @click="back">返 回</el-button>

    </el-form-item>

  </el-form>

</template>

<script>

import {doGet, doPost} from "@/http/axios-http";

import {message} from "@/http/message";

export default {

  data() {

    return {

      //老师对象,初始值是空

      studentCourseQuery : {},

      //form表单错误对象,初始值是空

      formError : {},

      studentOptions:[{}],

      teacherOptions:[{}],

      courseOptions:[{}],

      teacherCourseOptions:[{}],

      teacherCourseRelation:{}

    }

  },

  mounted() {

    //根据路由id加载市场老师数据

    this.loadTeacherCourse();

    this.loadAllTeacher();

    this.loadAllCourse();

    this.loadAllStudent();

  },

  methods : {

    getCourseNameById(courseId,teacherId){

      //拿到课程名

      doGet('/course/course_info/getById/'+courseId).then(resp=>{

        this.teacherCourseRelation.courseName = resp.data.name

      })

      //拿到老师名

      doGet('/teacher/tea_info/getById/'+teacherId).then(resp=>{

        this.teacherCourseRelation.teacherName = resp.data.name

      })

      //分页查询一下

      doGet('/teacher_course/teacher_course_info/getTeacherCourseByPage',{

        teacherName:this.teacherCourseRelation.teacherName,

        courseName:this.teacherCourseRelation.courseName

      }).then(resp=>{

        this.teacherCourseOptions = resp.data.data

      })

      //把结果置换回来

      this.teacherCourseOptions.courseId = courseId

      this.teacherCourseOptions.teacherId = teacherId

    },

    loadAllStudent(){

      doGet('/student/stu_info/getAll').then(resp=>{

        console.log(resp.data)

        if(resp.data.code==200){

          this.studentOptions = resp.data.data;

        }else {

            //提示一下

            message("拿到学生信息失败,原因:" + resp.data.msg, "error");

          }

      })

    },

    loadAllTeacher(){

      doGet('/teacher/tea_info/getAll').then(resp=>{

        console.log(resp.data)

        if(resp.data.code==200){

          this.teacherOptions = resp.data.data;

        }else {

            //提示一下

            message("拿到老师信息失败,原因:" + resp.data.msg, "error");

          }

      })

    },

    loadAllCourse(){

      doGet('/course/course_info/getAll').then(resp=>{

        console.log(resp)

        if(resp.data.code==200){

          this.courseOptions = resp.data.data

        }else {

            //提示一下

            message("拿到课程信息失败,原因:" + resp.data.msg, "error");

          }

      })

    },

    //返回

    back() {

      //回退到上一次访问的页面

      //this.$router.go(-1);

      //精确地回到某个页面

      this.$router.push({path : "/studentDash/student_course_info"})

    },

    //录入老师(提交保存)

    addTeacherSubmit() {

      this.userInfo = JSON.parse(localStorage.getItem("userInfo"))

      this.studentCourseQuery.stuId = this.userInfo.id

      this.studentCourseQuery.courseScore = 0

      //表单提交,使用formData提交表单

      let formData = new FormData();

      for (let field in this.studentCourseQuery) {

        formData.append(field, this.studentCourseQuery[field]);

      }

      if (this.studentCourseQuery.id) { //this.studentCourseQuery对象有id,说明的做了一次查询,那么就修改

        doPost("/student_course/student_course_info/save", formData).then(resp => {

          if (resp.data.code === 200) {

            //提示一下

            message("编辑学生选课信息成功", "success");

            //跳转到老师列表页

            this.$router.push({path : "/studentDash/student_course_info"})

          } else {

            //提示一下

            message("编辑学生选课信息失败,原因:" + resp.data.msg, "error");

          }

        })

      } else {

        doPost("/student_course/student_course_info/save", formData).then(resp => {

          console.log(resp)

          if (resp.data.code === 200) {

            //提示一下

            message("录入学生选课信息成功", "success");

            //跳转到老师授课列表页

            this.$router.push({path : "/studentDash/student_course_info"})

          } else {

            //提示一下

            message("录入学生选课信息失败,原因:" + resp.data.msg, "error");

          }

        })

      }

    },

    //根据路由id加载老师数据

    loadTeacherCourse() {

      let id = this.$route.params.id;

      console.log(id)

      if (id) {

        //编辑需要把数据查出来

        doGet("/student_course/student_course_info/get/" + id).then(resp => {

          this.studentCourseQuery = resp.data.data

        })

      }

    }

  }

}

</script>

3.4.11 学生选课管理功能前端主页面(学生端)

<template>

  <el-form :inline="true" :model="studentCourseSearchQuery" class="demo-form-inline">

    <el-form-item label="课程名称">

      <el-select

          v-model="studentCourseSearchQuery.courseName"

          placeholder="请选择课程名称"

          style="width: 160px"

          clearable>

        <el-option

            v-for="item in courseOptions"

            :key="item.id"

            :label="item.name"

            :value="item.name"/>

      </el-select>

    </el-form-item>

    <el-form-item label="课程学分区间左">

      <el-input v-model="studentCourseSearchQuery.courseStartCredits" placeholder="请输入最小学分" clearable

      style="width: 160px"/>

    </el-form-item>    

    <el-form-item label="课程学分区间右">

      <el-input v-model="studentCourseSearchQuery.courseEndCredits" placeholder="请输入最大学分" clearable

      style="width: 160px"/>

    </el-form-item>

    <br/>

    <el-form-item label="老师名称">

      <el-select

          v-model="studentCourseSearchQuery.teacherName"

          placeholder="请选择老师姓名"

          style="width: 160px"

          clearable>

        <el-option

            v-for="item in teacherOptions"

            :key="item.id"

            :label="item.name"

            :value="item.name"/>

      </el-select>

    </el-form-item>

    <el-form-item label="老师年龄区间左">

      <el-input v-model="studentCourseSearchQuery.teacherStartAge" placeholder="请输入最小年龄" clearable

      style="width: 160px"/>

    </el-form-item>    

    <el-form-item label="老师年龄区间右">

      <el-input v-model="studentCourseSearchQuery.teacherEndAge" placeholder="请输入最大年龄" clearable

      style="width: 160px"/>

    </el-form-item>

    <el-form-item label="老师研究方向">

      <el-input v-model="studentCourseSearchQuery.teacherProfession" placeholder="请输入老师的研究方向" clearable />

    </el-form-item>

    <el-form-item>

      <el-button type="primary" @click="onSarch">搜 索</el-button>

      <el-button type="primary" plain @click="onReset">重 置</el-button>

    </el-form-item>

  </el-form>

  <br/><br/>

  <el-button type="primary" @click="addStudentCourse">增加学生选课信息</el-button>

  <el-button type="danger" @click="batchDelStudentCourse">批量删除</el-button>

  <br/><br/>

  <el-table

      ref="multipleTableRef"

      :data="studentCourseList"

      style="width: 100%"

      @selection-change="handleSelectionChange">

    <el-table-column type="selection" width="55" />

    <el-table-column type="index" label="序号" width="60" />

    <el-table-column property="studentName" label="学生姓名"/>

    <el-table-column property="courseName" label="课程名" />

    <el-table-column property="courseCredits" label="学生学分" />

    <el-table-column property="teacherName" label="老师姓名"/>

    <el-table-column property="teacherAge" label="老师年龄" />

    <el-table-column property="teacherProfession" label="老师研究方向" />

    <el-table-column label="操作" width="230">

      <template #default="scope"><!--vue插槽-->

        <el-button type="success" @click="edit(scope.row.id)">编辑</el-button>

        <el-button type="danger" @click="del(scope.row.id)">删除</el-button>

      </template>

    </el-table-column>

  </el-table>

  <br/>

  <el-pagination background

                 layout="prev, pager, next"

                 :page-size="pageSize"

                 :total="totalRow"

                 @prev-click="page"

                 @next-click="page"

                 @current-change="page"/>

</template>

<script>

import {doPost, doGet} from "@/http/axios-http";

import {message, messageConfirm} from "@/http/message";

export default {

  //注入reload

  inject : ['reload'],

  data() {

    return {

      //学生选课搜索条件对象,初始值是空

      studentCourseSearchQuery : {},

      //学生选课列表list对象数据,初始值是空

      studentCourseList : [{}],

      //每页显示多少条

      pageSize : 0,

      //总共有多少条

      totalRow : 0,

      //勾选了哪些学生选课id,默认值是空

      studentCourseIdArray : [],

      studentOptions:[{}],

      courseOptions:[{}],

      teacherOptions:[{}],

      userInfo:{}

    }

  },

  //页面渲染时触发该钩子函数

  mounted() {

    this.getData();

    this.loadAllCourse();

    this.loadAllTeacher();

  },

  methods : {

    loadAllCourse(){

      doGet('/course/course_info/getAll').then(resp=>{

        console.log(resp)

        if(resp.data.code==200){

          this.courseOptions = resp.data.data

        }else {

            //提示一下

            message("拿到课程信息失败,原因:" + resp.data.msg, "error");

          }

      })

    },

    loadAllTeacher(){

      doGet('/teacher/tea_info/getAll').then(resp=>{

        console.log(resp)

        if(resp.data.code==200){

          this.teacherOptions = resp.data.data

        }else {

            //提示一下

            message("拿到老师信息失败,原因:" + resp.data.msg, "error");

          }

      })

    },

    //查询学生选课列表数据

    getData() {

      this.userInfo = JSON.parse(localStorage.getItem("userInfo"))

      this.studentCourseSearchQuery.studentName = this.userInfo.name

      doGet('/student_course/student_course_info/getStudentCourseByPage',this.studentCourseSearchQuery).then(resp => {

        console.log(resp)

        if (resp.data.code === 200) {

          this.studentCourseList = resp.data.data.dataList;

          this.pageSize = resp.data.data.pageSize;

          this.totalRow = resp.data.data.totalRow;

        }

      })

     

    },

    //搜索

    onSarch() {

      this.getData();

    },

    //重置

    onReset() {

      this.studentCourseSearchQuery = {};

    },

    //录入市场学生选课

    addStudentCourse() {

      //跳转路由

      this.$router.push({path : "/studentDash/student_course_info/add"});

      //window.location.href = "/dashboard/studentCourse/add";

    },

    //编辑市场学生选课

    edit(id) {

      console.log(id);

      this.$router.push({path : "/studentDash/student_course_info/edit/" + id});

    },

    //删除学生选课

    del(id) {

      //首先提示用户是否确定要删除

      messageConfirm("您是否确定要删除此数据?").then(() => { //当你点“确定”,执行该函

        doPost("/student_course/student_course_info/del/" + id, {}).then(resp => {

          if (resp.data.code === 200) {

            //删除成功

            message("删除成功", "success");

            //刷新页面

            this.reload();

          } else {

            message("删除失败,原因:" + resp.data.msg, "error");

          }

        })

      }).catch(error => { //当你点“取消”,执行该函数

        message("删除错误:"+error, "warning");

       

      });

    },

    //批量删除学生选课

    batchDelStudentCourse() {

      //用户没有选数据,要提示一下

      if (this.studentCourseIdArray.length <= 0) {

        message("请选择要删除的数据", "warning");

        return;

      }

      //1、拿到选择的id

      let ids = this.studentCourseIdArray.join(",");  //得到:ids = "1,2,5,7,10,12"

      //2、把这些id的数据删除

      messageConfirm("您是否确定要删除这些数据?").then(() => { //当你点“确定”,执行该函

        doPost("/student_course/student_course_info/batchDel/" + ids, {}).then(resp => {

          if (resp.data.code === 200) {

            //删除成功

            message("删除成功", "success");

            //刷新页面

            this.reload();

          } else {

            //删除失败

            message("删除失败,原因:" + resp.data.msg, "error");

          }

        })

      }).catch(() => { //当你点“取消”,执行该函数

        message("删除已取消", "warning");

      });

    },

    //勾选或取消复选框时触发该函数

    handleSelectionChange(selection) {

      //勾选或取消复选框时,先把用户id的数组清空

      this.studentCourseIdArray = [];

      selection.forEach( (studentCourse) => {

        this.studentCourseIdArray.push(studentCourse.id);

      });

    }

  }

}

</script>

<style>

</style>

3.4.12 学生选课管理功能前端添加页面(学生端)

<template>

  <el-form

      label-width="80px"

      style="max-width: 95%;">

    <el-form-item label="老师姓名">

      <el-select

          v-model="studentCourseQuery.teacherId"

          placeholder="请选择授课老师"

          style="width: 100%"

          clearable>

        <el-option

            v-for="item in teacherOptions"

            :key="item.id"

            :label="item.name"

            :value="item.id"/>

      </el-select>

    </el-form-item>

    <el-form-item label="课程名称">

      <el-select

          v-model="studentCourseQuery.courseId"

          placeholder="请选择课程名称"

          style="width: 100%"

          clearable>

        <el-option

            v-for="item in courseOptions"

            :key="item.id"

            :label="item.name"

            :value="item.id"/>

      </el-select>

    </el-form-item>

    <el-form-item>

      <el-input type="hidden" v-model="studentCourseQuery.id"/>

      <el-button type="primary" @click="addTeacherSubmit">提 交</el-button>

      <el-button type="success" plain @click="back">返 回</el-button>

    </el-form-item>

  </el-form>

</template>

<script>

import {doGet, doPost} from "@/http/axios-http";

import {message} from "@/http/message";

export default {

  data() {

    return {

      //老师对象,初始值是空

      studentCourseQuery : {},

      //form表单错误对象,初始值是空

      formError : {},

      studentOptions:[{}],

      teacherOptions:[{}],

      courseOptions:[{}],

      teacherCourseOptions:[{}],

      teacherCourseRelation:{}

    }

  },

  mounted() {

    //根据路由id加载市场老师数据

    this.loadTeacherCourse();

    this.loadAllTeacher();

    this.loadAllCourse();

    this.loadAllStudent();

  },

  methods : {

    getCourseNameById(courseId,teacherId){

      //拿到课程名

      doGet('/course/course_info/getById/'+courseId).then(resp=>{

        this.teacherCourseRelation.courseName = resp.data.name

      })

      //拿到老师名

      doGet('/teacher/tea_info/getById/'+teacherId).then(resp=>{

        this.teacherCourseRelation.teacherName = resp.data.name

      })

      //分页查询一下

      doGet('/teacher_course/teacher_course_info/getTeacherCourseByPage',{

        teacherName:this.teacherCourseRelation.teacherName,

        courseName:this.teacherCourseRelation.courseName

      }).then(resp=>{

        this.teacherCourseOptions = resp.data.data

      })

      //把结果置换回来

      this.teacherCourseOptions.courseId = courseId

      this.teacherCourseOptions.teacherId = teacherId

    },

    loadAllStudent(){

      doGet('/student/stu_info/getAll').then(resp=>{

        console.log(resp.data)

        if(resp.data.code==200){

          this.studentOptions = resp.data.data;

        }else {

            //提示一下

            message("拿到学生信息失败,原因:" + resp.data.msg, "error");

          }

      })

    },

    loadAllTeacher(){

      doGet('/teacher/tea_info/getAll').then(resp=>{

        console.log(resp.data)

        if(resp.data.code==200){

          this.teacherOptions = resp.data.data;

        }else {

            //提示一下

            message("拿到老师信息失败,原因:" + resp.data.msg, "error");

          }

      })

    },

    loadAllCourse(){

      doGet('/course/course_info/getAll').then(resp=>{

        console.log(resp)

        if(resp.data.code==200){

          this.courseOptions = resp.data.data

        }else {

            //提示一下

            message("拿到课程信息失败,原因:" + resp.data.msg, "error");

          }

      })

    },

    //返回

    back() {

      //回退到上一次访问的页面

      //this.$router.go(-1);

      //精确地回到某个页面

      this.$router.push({path : "/studentDash/student_course_info"})

    },

    //录入老师(提交保存)

    addTeacherSubmit() {

      this.userInfo = JSON.parse(localStorage.getItem("userInfo"))

      this.studentCourseQuery.stuId = this.userInfo.id

      this.studentCourseQuery.courseScore = 0

      //表单提交,使用formData提交表单

      let formData = new FormData();

      for (let field in this.studentCourseQuery) {

        formData.append(field, this.studentCourseQuery[field]);

      }

      if (this.studentCourseQuery.id) { //this.studentCourseQuery对象有id,说明的做了一次查询,那么就修改

        doPost("/student_course/student_course_info/save", formData).then(resp => {

          if (resp.data.code === 200) {

            //提示一下

            message("编辑学生选课信息成功", "success");

            //跳转到老师列表页

            this.$router.push({path : "/studentDash/student_course_info"})

          } else {

            //提示一下

            message("编辑学生选课信息失败,原因:" + resp.data.msg, "error");

          }

        })

      } else {

        doPost("/student_course/student_course_info/save", formData).then(resp => {

          console.log(resp)

          if (resp.data.code === 200) {

            //提示一下

            message("录入学生选课信息成功", "success");

            //跳转到老师授课列表页

            this.$router.push({path : "/studentDash/student_course_info"})

          } else {

            //提示一下

            message("录入学生选课信息失败,原因:" + resp.data.msg, "error");

          }

        })

      }

    },

    //根据路由id加载老师数据

    loadTeacherCourse() {

      let id = this.$route.params.id;

      console.log(id)

      if (id) {

        //编辑需要把数据查出来

        doGet("/student_course/student_course_info/get/" + id).then(resp => {

          this.studentCourseQuery = resp.data.data

        })

      }

    }

  }

}

</script>

3.5教师授课管理功能模块

3.5.1 教师授课管理功能实体类dto

package site.lyweb.domain.dto;

import lombok.Data;

import java.io.Serializable;
import java.math.BigDecimal;

/**
 *
 * @TableName teacher
 */

@Data
public class TeacherCourseDTO implements Serializable {

    private String id;

    private String teacherName;

    private Integer age;

    private String profession;

    private String courseName;

    private BigDecimal credits;

    private static final long serialVersionUID = 1L;
}

3.5.2教师授课管理功能实体类query

package site.lyweb.domain.query;

import lombok.Data;

import java.math.BigDecimal;

/**
 *
 * @TableName teacher
 */

@Data
public class TeacherCourseQuery {

    private String id;

    private String teacherName;

    private Integer startAge;

    private Integer endAge;

    private String profession;

    private String courseName;

    private BigDecimal startCredits;

    private BigDecimal endCredits;

}

3.5.3教师授课管理功能实体类po

package site.lyweb.domain.dto;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Objects;

/**
 *
 * @TableName teacher
 */

@Data
public class TeacherCourse implements Serializable {

    @TableId
    private String id;

    private String teacherName;

    private Integer age;

    private String profession;

    private String courseName;

    private BigDecimal credits;

    @TableField(exist = false)
    private static final long serialVersionUID = 1L;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        TeacherCourse that = (TeacherCourse) o;
        return Objects.equals(id, that.id) && Objects.equals(teacherName, that.teacherName) && Objects.equals(age, that.age) && Objects.equals(profession, that.profession) && Objects.equals(courseName, that.courseName) && Objects.equals(credits, that.credits);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, teacherName, age, profession, courseName, credits);
    }

    @Override
    public String toString() {
        return "TeacherCourse{" +
                "id='" + id + '\'' +
                ", teacherName='" + teacherName + '\'' +
                ", age=" + age +
                ", profession='" + profession + '\'' +
                ", courseName='" + courseName + '\'' +
                ", credits=" + credits +
                '}';
    }
}

3.5.4教师授课管理功能mapper层

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="site.lyweb.mapper.TeacherCourseMapper">

    <select id="selectByCount" resultType="java.lang.Integer">
        select
        count(0)
        from tea_course_relation t1
        left join teacher t2
        on t1.teacher_id = t2.id
        left join course t3
        on t1.course_id = t3.id
       
<where>
            <if test="id != null">
                and t1.id = #{id, jdbcType=VARCHAR}
           
</if>
            <!--老师姓名-->
           
<if test="teacherName != null">
                and t2.name = #{teacherName,jdbcType=VARCHAR}
           
</if>
            <!--年龄区间-->
            
<if test="startAge != null">
                <![CDATA[    and t2.age >= #{startAge, jdbcType=INTEGER}    ]]>
            </if>
            <if test="endAge != null">
                <![CDATA[    and t2.age <= #{endAge, jdbcType=INTEGER}    ]]>
            </if>
            <!--专业-->
           
<if test="profession != null">
                and t2.profession = #{profession,jdbcType=VARCHAR}
           
</if>
            <!--课程名-->
           
<if test="courseName != null">
                and t3.name = #{courseName,jdbcType=VARCHAR}
           
</if>
            <!--学分区间-->
           
<if test="startCredits != null">
                <![CDATA[    and t3.credits >= #{startCredits, jdbcType=DECIMAL}    ]]>
            </if>
            <if test="endCredits != null">
                <![CDATA[    and t3.credits <= #{endCredits, jdbcType=DECIMAL}    ]]>
            </if>
        </where>
    </select>

    <select id="selectByPage" parameterType="java.lang.String" resultType="site.lyweb.domain.dto.TeacherCourse">
        select t1.id,t2.name teacherName,t2.age,t2.profession,
                t3.name courseName,t3.credits
        from tea_course_relation t1
        left join teacher t2
        on t1.teacher_id = t2.id
        left join course t3
        on t1.course_id = t3.id
       
<where>
            <if test="id != null">
                and t1.id = #{id, jdbcType=VARCHAR}
           
</if>
            <!--老师姓名-->
           
<if test="teacherName != null">
                and t2.name = #{teacherName,jdbcType=VARCHAR}
           
</if>
            <!--年龄区间-->
           
<if test="startAge != null">
                <![CDATA[    and t2.age >= #{startAge, jdbcType=INTEGER}    ]]>
            </if>
            <if test="endAge != null">
                <![CDATA[    and t2.age <= #{endAge, jdbcType=INTEGER}    ]]>
            </if>
            <!--专业-->
           
<if test="profession != null">
                and t2.profession = #{profession,jdbcType=VARCHAR}
           
</if>
            <!--课程名-->
           
<if test="courseName != null">
                and t3.name = #{courseName,jdbcType=VARCHAR}
           
</if>
            <!--学分区间-->
           
<if test="startCredits != null">
                <![CDATA[    and t3.credits >= #{startCredits, jdbcType=DECIMAL}    ]]>
            </if>
            <if test="endCredits != null">
                <![CDATA[    and t3.credits <= #{endCredits, jdbcType=DECIMAL}    ]]>
            </if>
        </where>
    </select>
    <!--批量删除-->
   
<delete id="removeBatchByIds">
        delete from tea_course_relation
        where id in
       
<foreach collection="idList" item="id" open="(" separator="," close=")">
            #{id, jdbcType=VARCHAR}
        </foreach>
    </delete>
    <!--根据id删除-->
   
<delete id="removeById" parameterType="java.lang.String">
        delete from tea_course_relation
        where id = #{id,jdbcType=VARCHAR}
   
</delete>
    <!--插入数据-->
   
<insert id="insert" parameterType="java.lang.String">
        insert into tea_course_relation (id,teacher_id,course_id)
            values(#{id,jdbcType=VARCHAR},#{teacherId,jdbcType=VARCHAR},#{courseId,jdbcType=VARCHAR});
   
</insert>
    <!--更新数据-->
   
<update id="update" parameterType="java.lang.String">
        update tea_course_relation
        set
            teacher_id = #{teacherId,jdbcType=VARCHAR},
            course_id = #{courseId,jdbcType=VARCHAR}
        where id = #{id,jdbcType=VARCHAR}
   
</update>

    <select id="getById" resultType="site.lyweb.domain.dto.TeaCourseRelation">
        select * from tea_course_relation
        where id = #{id,jdbcType=VARCHAR}
   
</select>
</mapper>

3.5.5教师授课管理功能mapper层接口

package site.lyweb.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import site.lyweb.domain.dto.TeaCourseRelation;
import site.lyweb.domain.dto.Teacher;
import site.lyweb.domain.dto.TeacherCourse;
import site.lyweb.domain.query.TeacherCourseQuery;
import site.lyweb.domain.query.TeacherQuery;

import java.util.List;

/**
* @author
深山老林
* @description 针对表【teacher】的数据库操作Mapper
* @createDate 2024-06-19 20:53:32
* @Entity generator.domain.Teacher
*/

public interface TeacherCourseMapper {

    int selectByCount(TeacherCourseQuery teacherCourseQuery);

    List<TeacherCourse> selectByPage(TeacherCourseQuery teacherCourseQuery);

    boolean removeBatchByIds(List<String> idList);

    boolean removeById(String id);

    boolean insert(@Param("id") String id,@Param("teacherId") String teacherId,@Param("courseId") String courseId);

    boolean update(@Param("id") String id,@Param("teacherId") String teacherId,@Param("courseId") String courseId);

    TeaCourseRelation getById(String id);
}



 

3.5.6教师授课管理功能service层

package site.lyweb.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import site.lyweb.constant.Constant;
import site.lyweb.domain.dto.*;
import site.lyweb.domain.query.TeacherCourseQuery;
import site.lyweb.domain.query.TeacherQuery;
import site.lyweb.mapper.TeacherCourseMapper;
import site.lyweb.mapper.TeacherMapper;
import site.lyweb.service.TeacherCourseService;
import site.lyweb.service.TeacherService;
import site.lyweb.utils.ExtBeanUtils;
import site.lyweb.utils.UUIDUtils;

import java.util.List;

/**
* @author
深山老林
* @description 针对表【teacher】的数据库操作Service实现
* @createDate 2024-06-19 20:53:32
*/

@Service
public class TeacherCourseServiceImpl implements TeacherCourseService {
    @Resource
    private TeacherCourseMapper teacherCourseMapper;
    /**
     *
分页 + 搜索
    
*
     * @param
current
    
* @param teacherCourseQuery
    
* @return
     */
   
@Override
    public PageDTO<TeacherCourseDTO> getTeacherCourseByPage(Integer current, TeacherCourseQuery teacherCourseQuery) {
        //分页查询分两个查询,1、查符合条件的数据总条数;2、查询当前页的数据
       
int totalRow = teacherCourseMapper.selectByCount(teacherCourseQuery);
        int start = (current - 1) * Constant.PAGE_SIZE;
        List<TeacherCourse> teacherCoursesList = teacherCourseMapper.selectByPage(teacherCourseQuery);
        int totalPage = totalRow / Constant.PAGE_SIZE;
        if (totalRow % Constant.PAGE_SIZE > 0) { //如果除不尽,总页数就需要加1
           
totalPage ++;
        }
        //需要把 List<TUser> 转换为 List<UserInfoDTO>
       
List<TeacherCourseDTO> teacherCoursesDTOList = ExtBeanUtils.copyPropertiesForList(teacherCoursesList, TeacherCourseDTO.class);

        return new PageDTO<>(current, Constant.PAGE_SIZE, totalRow, totalPage, teacherCoursesDTOList);

    }

    @Override
    public boolean removeBatchByIds(List<String> idList) {
        try {
            return teacherCourseMapper.removeBatchByIds(idList);
        } catch (Exception e) {
            // 可以根据具体情况处理异常,比如记录日志或者抛出自定义异常
           
e.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean removeById(String id) {
        try {
            return teacherCourseMapper.removeById(id);
        } catch (Exception e) {
            // 可以根据具体情况处理异常,比如记录日志或者抛出自定义异常
           
e.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean save(String id, String teacherId, String courseId) {
        try {
            //id:插入方法
           
if(id==null || id.isEmpty()){
                id = UUIDUtils.getUUID();
                return teacherCourseMapper.insert(id, teacherId, courseId);
            } else {
                return teacherCourseMapper.update(id, teacherId, courseId);
            }
        } catch (Exception e) {
            // 可以根据具体情况处理异常,比如记录日志或者抛出自定义异常
           
e.printStackTrace();
            return false;
        }
    }

    @Override
    public TeaCourseRelation getById(String id) {
        try {
            return teacherCourseMapper.getById(id);
        } catch (Exception e) {
            // 可以根据具体情况处理异常,比如记录日志或者抛出自定义异常
           
e.printStackTrace();
            return null;
        }
    }
}

3.5.7教师授课管理功能service层接口

package site.lyweb.service;

import com.baomidou.mybatisplus.extension.service.IService;
import site.lyweb.domain.dto.*;
import site.lyweb.domain.query.TeacherCourseQuery;
import site.lyweb.domain.query.TeacherQuery;

import java.util.List;

/**
* @author
深山老林
* @description 针对表【teacher】的数据库操作Service
* @createDate 2024-06-19 20:53:32
*/

public interface TeacherCourseService  {

    PageDTO<TeacherCourseDTO> getTeacherCourseByPage(Integer current, TeacherCourseQuery teacherCourseQuery);

    boolean removeBatchByIds(List<String> idList);

    boolean removeById(String id);

    boolean save(String id,String teacherId,String courseId);

    TeaCourseRelation getById(String id);
}

3.5.8教师授课管理功能controller层

package site.lyweb.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import site.lyweb.domain.dto.PageDTO;
import site.lyweb.domain.dto.TeaCourseRelation;
import site.lyweb.domain.dto.Teacher;
import site.lyweb.domain.dto.TeacherCourseDTO;
import site.lyweb.domain.query.TeacherCourseQuery;
import site.lyweb.result.RestResult;
import site.lyweb.service.TeacherCourseService;
import site.lyweb.utils.UUIDUtils;

import java.util.Arrays;
import java.util.List;

/**
 * @Author
林瑶
 
* @Description TODO
 
* @Date 2024/6/20 2:21
 */

@CrossOrigin(origins = "*")
@RestController
@Tag(name="教师选课管理模块")
@Slf4j
@RequestMapping("/teacher_course")
public class TeacherCourseController {
    @Resource
    private TeacherCourseService teacherCourseService;
    /**
     *
分页查询教师选课列表数据
    
*
     * @return
     */

   
@Operation(summary = "分页查询教师选课列表数据")
    @GetMapping(value = "/teacher_course_info/getTeacherCourseByPage")
    public RestResult getTeacherCourseByPage( TeacherCourseQuery teacherCourseQuery) {


        //分页查询的结果用PageDTO进行封装
       
PageDTO<TeacherCourseDTO> pageDTO = teacherCourseService.getTeacherCourseByPage(0, teacherCourseQuery);

        //有的时候,查询可以不判断成功与失败,不管查没查到数据,都返回200,页面上去控制显示
       
return RestResult.SUCCESS(pageDTO);
    }
    /**
     *
根据id批量教师选课信息表中信息
    
*/
   
@Operation(summary = "根据ids删除教师选课信息表中信息")
    @Parameters({
            @Parameter(name = "ids",description = "id(主键)",in = ParameterIn.PATH)
    })
    @CrossOrigin
    @PostMapping("/teacher_course_info/batchDel/{ids}")
    public RestResult batchDelTeacherCourseById(@PathVariable("ids") String ids){
        //ids = "1,2,5,7,10,12" , ids.split(",")是把ids转成数组, Arrays.asList()是把数组转成List
       
List<String> idList = Arrays.asList(ids.split(","));
        return  teacherCourseService.removeBatchByIds(idList) ? RestResult.SUCCESS() : RestResult.FAIL();
    }
    /**
     *
根据id教师选课信息表中信息
    
*/
   
@Operation(summary = "根据id删除教师选课信息表中信息")
    @Parameters({
            @Parameter(name = "id",description = "id(主键)",in = ParameterIn.PATH)
    })
    @CrossOrigin
    @PostMapping("/teacher_course_info/del/{id}")
    public RestResult delTeacherCourseById(@PathVariable("id") String id){
        return  teacherCourseService.removeById(id) ? RestResult.SUCCESS() : RestResult.FAIL();
    }
    /**
     *
保存老师选课信息表中信息
    
*/
   
@Operation(summary = "保存老师选课信息表中信息")
    @PostMapping("/teacher_course_info/save")
    @Parameters({
            @Parameter(name = "id",description = "id(主键)",in = ParameterIn.QUERY),
            @Parameter(name = "teacherId",description = "老师id",in = ParameterIn.QUERY),
            @Parameter(name = "courseId",description = "课程id",in = ParameterIn.QUERY),
    })
    public RestResult saveTeacherCoruse(TeaCourseRelation teaCourseRelation){
        String id = teaCourseRelation.getId();
        String teacherId = teaCourseRelation.getTeacherId();
        String courseId = teaCourseRelation.getCourseId();
        return teacherCourseService.save(id,teacherId,courseId)?RestResult.SUCCESS("保存老师选课信息表中信息成功"):RestResult.FAIL("保存老师选课信息表中信息失败");
    }
    /**
     *
根据id查询选课信息表中信息
    
*/
   
@Operation(summary = "根据id查询教师选课信息表中信息")
    @Parameters({
            @Parameter(name = "id",description = "id(主键)",in = ParameterIn.PATH)
    })
    @CrossOrigin
    @GetMapping("/teacher_course_info/get/{id}")
    public RestResult getTeacherCourseById(@PathVariable("id") String id){
        try{
            return RestResult.SUCCESS(teacherCourseService.getById(id)) ;
        }catch (Exception e){
            e.printStackTrace();
            return RestResult.FAIL("查询失败");
        }

    }
}

3.5.9 教师授课管理功能前端主页面(教师端)

<template>

  <el-form :inline="true" :model="teacherCourseSearchQuery" class="demo-form-inline">

    <el-form-item label="老师名称">

      <el-select

          v-model="teacherCourseSearchQuery.teacherName"

          placeholder="请选择授课老师"

          style="width: 200px"

          clearable>

        <el-option

            v-for="item in teacherOptions"

            :key="item.id"

            :label="item.name"

            :value="item.name"/>

      </el-select>

    </el-form-item>

    <el-form-item label="年龄区间左">

      <el-input v-model="teacherCourseSearchQuery.startAge" placeholder="请输入最小年龄" clearable />

    </el-form-item>    

    <el-form-item label="年龄区间右">

      <el-input v-model="teacherCourseSearchQuery.endAge" placeholder="请输入最大年龄" clearable />

    </el-form-item>    

    <el-form-item label="研究方向">

      <el-input v-model="teacherCourseSearchQuery.profession" placeholder="请输入老师的研究方向" clearable />

    </el-form-item>

    <el-form-item label="课程名称">

      <el-select

          v-model="teacherCourseSearchQuery.courseName"

          placeholder="请选择课程名称"

          style="width: 200px"

          clearable>

        <el-option

            v-for="item in courseOptions"

            :key="item.id"

            :label="item.name"

            :value="item.name"/>

      </el-select>

    </el-form-item>

    <el-form-item label="学分区间左">

      <el-input v-model="teacherCourseSearchQuery.startCredits" placeholder="请输入最小学分" clearable />

    </el-form-item>    

    <el-form-item label="学分区间右">

      <el-input v-model="teacherCourseSearchQuery.endCredits" placeholder="请输入最大学分" clearable />

    </el-form-item>

    <el-form-item>

      <el-button type="primary" @click="onSarch">搜 索</el-button>

      <el-button type="primary" plain @click="onReset">重 置</el-button>

    </el-form-item>

  </el-form>

  <br/><br/>

  <el-button type="primary" @click="addTeacherCourse">增加教师选课信息</el-button>

  <el-button type="danger" @click="batchDelTeacherCourse">批量删除</el-button>

  <br/><br/>

  <el-table

      ref="multipleTableRef"

      :data="teacherCourseList"

      style="width: 100%"

      @selection-change="handleSelectionChange">

    <el-table-column type="selection" width="55" />

    <el-table-column type="index" label="序号" width="60" />

    <el-table-column property="teacherName" label="老师姓名" width="200"/>

    <el-table-column property="age" label="年龄" />

    <el-table-column property="profession" label="研究方向" />

    <el-table-column property="courseName" label="课程名" />

    <el-table-column property="credits" label="课程学分" />

    <el-table-column label="操作" width="230">

      <template #default="scope"><!--vue插槽-->

        <el-button type="success" @click="edit(scope.row.id)">编辑</el-button>

        <el-button type="danger" @click="del(scope.row.id)">删除</el-button>

      </template>

    </el-table-column>

  </el-table>

  <br/>

  <el-pagination background

                 layout="prev, pager, next"

                 :page-size="pageSize"

                 :total="totalRow"

                 @prev-click="page"

                 @next-click="page"

                 @current-change="page"/>

</template>

<script>

import {doPost, doGet} from "@/http/axios-http";

import {message, messageConfirm} from "@/http/message";

export default {

  //注入reload

  inject : ['reload'],

  data() {

    return {

      //教师选课搜索条件对象,初始值是空

      teacherCourseSearchQuery : {},

      //教师选课列表list对象数据,初始值是空

      teacherCourseList : [{}],

      //每页显示多少条

      pageSize : 0,

      //总共有多少条

      totalRow : 0,

      //勾选了哪些教师选课id,默认值是空

      teacherCourseIdArray : [],

      teacherOptions:[{}],

      courseOptions:[{}]

    }

  },

  //页面渲染时触发该钩子函数

  mounted() {

    this.getData();

    this.loadAllTeacher();

    this.loadAllCourse();

  },

  methods : {

    loadAllTeacher(){

      doGet('/teacher/tea_info/getAll').then(resp=>{

        console.log(resp.data)

        if(resp.data.code==200){

          this.teacherOptions = resp.data.data;

        }else {

            //提示一下

            message("拿到老师信息失败,原因:" + resp.data.msg, "error");

          }

      })

    },

    loadAllCourse(){

      doGet('/course/course_info/getAll').then(resp=>{

        console.log(resp)

        if(resp.data.code==200){

          this.courseOptions = resp.data.data

        }else {

            //提示一下

            message("拿到课程信息失败,原因:" + resp.data.msg, "error");

          }

      })

    },

    //查询市场教师选课列表数据

    getData() {

      doGet('/teacher_course/teacher_course_info/getTeacherCourseByPage',this.teacherCourseSearchQuery).then(resp => {

        console.log(resp)

        if (resp.data.code === 200) {

          this.teacherCourseList = resp.data.data.dataList;

          this.pageSize = resp.data.data.pageSize;

          this.totalRow = resp.data.data.totalRow;

        }

      })

    },

    //搜索

    onSarch() {

      this.getData();

    },

    //重置

    onReset() {

      this.teacherCourseSearchQuery = {};

    },

    //录入市场教师选课

    addTeacherCourse() {

      //跳转路由

      this.$router.push({path : "/teacherDash/teacher_course_info/add"});

      //window.location.href = "/dashboard/teacherCourse/add";

    },

    //编辑市场教师选课

    edit(id) {

      console.log(id);

      this.$router.push({path : "/teacherDash/teacher_course_info/edit/" + id});

    },

    //删除教师选课

    del(id) {

      //首先提示用户是否确定要删除

      messageConfirm("您是否确定要删除此数据?").then(() => { //当你点“确定”,执行该函

        doPost("/teacher_course/teacher_course_info/del/" + id, {}).then(resp => {

          if (resp.data.code === 200) {

            //删除成功

            message("删除成功", "success");

            //刷新页面

            this.reload();

          } else {

            message("删除失败,原因:" + resp.data.msg, "error");

          }

        })

      }).catch(error => { //当你点“取消”,执行该函数

        message("删除错误:"+error, "warning");

       

      });

    },

    //批量删除教师选课

    batchDelTeacherCourse() {

      //用户没有选数据,要提示一下

      if (this.teacherCourseIdArray.length <= 0) {

        message("请选择要删除的数据", "warning");

        return;

      }

      //1、拿到选择的id

      let ids = this.teacherCourseIdArray.join(",");  //得到:ids = "1,2,5,7,10,12"

      //2、把这些id的数据删除

      messageConfirm("您是否确定要删除这些数据?").then(() => { //当你点“确定”,执行该函

        doPost("/teacher_course/teacher_course_info/batchDel/" + ids, {}).then(resp => {

          if (resp.data.code === 200) {

            //删除成功

            message("删除成功", "success");

            //刷新页面

            this.reload();

          } else {

            //删除失败

            message("删除失败,原因:" + resp.data.msg, "error");

          }

        })

      }).catch(() => { //当你点“取消”,执行该函数

        message("删除已取消", "warning");

      });

    },

    //勾选或取消复选框时触发该函数

    handleSelectionChange(selection) {

      //勾选或取消复选框时,先把用户id的数组清空

      this.teacherCourseIdArray = [];

      selection.forEach( (teacherCourse) => {

        this.teacherCourseIdArray.push(teacherCourse.id);

      });

    }

  }

}

</script>

<style>

</style>

3.5.10教师授课管理功能前端添加页面(教师端)

<template>

  <el-form

      label-width="80px"

      style="max-width: 95%;">

    <el-form-item label="老师姓名">

      <el-select

          v-model="teacherCourseQuery.teacherId"

          placeholder="请选择授课老师"

          style="width: 100%"

          clearable>

        <el-option

            v-for="item in teacherOptions"

            :key="item.id"

            :label="item.name"

            :value="item.id"/>

      </el-select>

    </el-form-item>

    <el-form-item label="课程名称">

      <el-select

          v-model="teacherCourseQuery.courseId"

          placeholder="请选择课程名称"

          style="width: 100%"

          clearable>

        <el-option

            v-for="item in courseOptions"

            :key="item.id"

            :label="item.name"

            :value="item.id"/>

      </el-select>

    </el-form-item>

    <el-form-item>

      <el-input type="hidden" v-model="teacherCourseQuery.id"/>

      <el-button type="primary" @click="addTeacherSubmit">提 交</el-button>

      <el-button type="success" plain @click="back">返 回</el-button>

    </el-form-item>

  </el-form>

</template>

<script>

import {doGet, doPost} from "@/http/axios-http";

import {message} from "@/http/message";

export default {

  data() {

    return {

      //老师对象,初始值是空

      teacherCourseQuery : {},

      //form表单错误对象,初始值是空

      formError : {},

      teacherOptions:[{}],

      courseOptions:[{}]

    }

  },

  mounted() {

    //根据路由id加载市场老师数据

    this.loadTeacherCourse();

    this.loadAllTeacher();

    this.loadAllCourse();

  },

  methods : {

    loadAllTeacher(){

      doGet('/teacher/tea_info/getAll').then(resp=>{

        console.log(resp.data)

        if(resp.data.code==200){

          this.teacherOptions = resp.data.data;

        }else {

            //提示一下

            message("拿到老师信息失败,原因:" + resp.data.msg, "error");

          }

      })

    },

    loadAllCourse(){

      doGet('/course/course_info/getAll').then(resp=>{

        console.log(resp)

        if(resp.data.code==200){

          this.courseOptions = resp.data.data

        }else {

            //提示一下

            message("拿到课程信息失败,原因:" + resp.data.msg, "error");

          }

      })

    },

    //返回

    back() {

      //回退到上一次访问的页面

      //this.$router.go(-1);

      //精确地回到某个页面

      this.$router.push({path : "/teacherDash/teacher_course_info"})

    },

    //录入市场老师(提交保存)

    addTeacherSubmit() {

      //表单提交,使用formData提交表单

      let formData = new FormData();

      for (let field in this.teacherCourseQuery) {

        formData.append(field, this.teacherCourseQuery[field]);

      }

      if (this.teacherCourseQuery.id) { //this.teacherCourseQuery对象有id,说明的做了一次查询,那么就修改

        doPost("/teacher_course/teacher_course_info/save", formData).then(resp => {

          if (resp.data.code === 200) {

            //提示一下

            message("编辑老师授课信息成功", "success");

            //跳转到老师列表页

            this.$router.push({path : "/teacherDash/teacher_course_info"})

          } else {

            //提示一下

            message("编辑老师授课信息失败,原因:" + resp.data.msg, "error");

          }

        })

      } else {

        doPost("/teacher_course/teacher_course_info/save", formData).then(resp => {

          console.log(resp)

          if (resp.data.code === 200) {

            //提示一下

            message("录入老师授课信息成功", "success");

            //跳转到老师授课列表页

            this.$router.push({path : "/teacherDash/teacher_course_info"})

          } else {

            //提示一下

            message("录入老师授课信息失败,原因:" + resp.data.msg, "error");

          }

        })

      }

    },

    //根据路由id加载市场老师数据

    loadTeacherCourse() {

      let id = this.$route.params.id;

      console.log(id)

      if (id) {

        //编辑需要把数据查出来

        doGet("/teacher_course/teacher_course_info/get/" + id).then(resp => {

          this.teacherCourseQuery = resp.data.data

        })

      }

    }

  }

}

</script>

3.6学生成绩管理功能模块

3.6.1 学生成绩管理功能实体类dto

package site.lyweb.domain.dto;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Objects;

/**
 *
 * @TableName teacher
 */

@Data
public class CourseScoreDTO implements Serializable {

    private String id;

    private String courseName;

    private BigDecimal courseCredits;

    private String teacherName;

    private String studentName;


    private BigDecimal courseScore;

    private static final long serialVersionUID = 1L;


}

3.6.2学生成绩管理功能实体类query

package site.lyweb.domain.query;

import lombok.Data;

import java.io.Serializable;
import java.math.BigDecimal;

/**
 *
 * @TableName teacher
 */

@Data
public class CourseScoreQuery{

    private String id;

    private String courseName;

    private BigDecimal minCourseCredits;

    private BigDecimal maxCourseCredits;

    private String teacherName;

    private String studentName;

    private BigDecimal minCourseScore;

    private BigDecimal maxCourseScore;

}

3.6.3学生成绩管理功能实体类po

package site.lyweb.domain.dto;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Objects;

/**
 *
 * @TableName teacher
 */

@Data
public class CourseScore implements Serializable {

    //student_course_relation表的id
   
@TableId
    private String id;

    //course表的几个字段
   
private String courseName;

    private BigDecimal courseCredits;

    //teacher表的几个字段
   
private String teacherName;

    //student表的几个字段
   
private String studentName;


    private BigDecimal courseScore;

    @TableField(exist = false)
    private static final long serialVersionUID = 1L;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        CourseScore that = (CourseScore) o;
        return Objects.equals(id, that.id) && Objects.equals(courseName, that.courseName) && Objects.equals(courseCredits, that.courseCredits) && Objects.equals(teacherName, that.teacherName) && Objects.equals(studentName, that.studentName) && Objects.equals(courseScore, that.courseScore);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, courseName, courseCredits, teacherName, studentName, courseScore);
    }

    @Override
    public String toString() {
        return "CourseScore{" +
                "id='" + id + '\'' +
                ", courseName='" + courseName + '\'' +
                ", courseCredits=" + courseCredits +
                ", teacherName='" + teacherName + '\'' +
                ", studentName='" + studentName + '\'' +
                ", courseScore=" + courseScore +
                '}';
    }
}

3.6.4学生成绩管理功能mapper层

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="site.lyweb.mapper.CourseScoreMapper">

    <select id="selectByCount" resultType="java.lang.Integer">
        select
        count(0)
        from stu_course_relation t1
        left join teacher t2
        on t1.teacher_id = t2.id
        left join course t3
        on t1.course_id = t3.id
        left join student t4
        on t1.stu_id = t4.id
       
<where>
            <if test="id != null">
                and t1.id = #{id, jdbcType=VARCHAR}
           
</if>
            <!--teacher:老师姓名-->
           
<if test="teacherName != null">
                and t2.name = #{teacherName,jdbcType=VARCHAR}
           
</if>
            <!--course:课程名-->
           
<if test="courseName != null">
                and t3.name = #{courseName,jdbcType=VARCHAR}
           
</if>
            <!--course:学分区间-->
           
<if test="minCourseCredits != null">
                <![CDATA[    and t3.credits >= #{minCourseCredits, jdbcType=DECIMAL}    ]]>
            </if>
            <if test="maxCourseCredits != null">
                <![CDATA[    and t3.credits <= #{maxCourseCredits, jdbcType=DECIMAL}    ]]>
            </if>
            <!--student:学生姓名-->
           
<if test="studentName != null">
                and t4.name = #{studentName,jdbcType=VARCHAR}
           
</if>
            <!--student:成绩-->
           
<if test="minCourseScore != null">
                <![CDATA[    and t1.score >= #{minCourseScore, jdbcType=INTEGER}    ]]>
            </if>
            <if test="maxCourseScore != null">
                <![CDATA[    and t1.score <= #{maxCourseScore, jdbcType=INTEGER}    ]]>
            </if>
        </where>
    </select>

    <select id="selectByPage" parameterType="java.lang.String" resultType="site.lyweb.domain.dto.CourseScore">
        select t1.id,
                t3.name courseName,t3.credits courseCredits,
                t2.name teacherName,
                t4.name studentName,
                t1.course_score courseScore
        from stu_course_relation t1
        left join teacher t2
        on t1.teacher_id = t2.id
        left join course t3
        on t1.course_id = t3.id
        left join student t4
        on t1.stu_id = t4.id
       
<where>
            <if test="id != null">
                and t1.id = #{id, jdbcType=VARCHAR}
           
</if>
            <!--teacher:老师姓名-->
           
<if test="teacherName != null">
                and t2.name = #{teacherName,jdbcType=VARCHAR}
           
</if>
            <!--course:课程名-->
           
<if test="courseName != null">
                and t3.name = #{courseName,jdbcType=VARCHAR}
           
</if>
            <!--course:学分区间-->
           
<if test="minCourseCredits != null">
                <![CDATA[    and t3.credits >= #{minCourseCredits, jdbcType=DECIMAL}    ]]>
            </if>
            <if test="maxCourseCredits != null">
                <![CDATA[    and t3.credits <= #{maxCourseCredits, jdbcType=DECIMAL}    ]]>
            </if>
            <!--student:学生姓名-->
           
<if test="studentName != null">
                and t4.name = #{studentName,jdbcType=VARCHAR}
           
</if>
            <!--student:成绩-->
           
<if test="minCourseScore != null">
                <![CDATA[    and t1.score >= #{minCourseScore, jdbcType=DECIMAL}    ]]>
            </if>
            <if test="maxCourseScore != null">
                <![CDATA[    and t1.score <= #{maxCourseScore, jdbcType=DECIMAL}    ]]>
            </if>
        </where>
    </select>

    <delete id="updateCourseScore">
    </delete>
</mapper>

3.6.5学生成绩管理功能mapper层接口

package site.lyweb.mapper;

import org.apache.ibatis.annotations.Param;
import site.lyweb.domain.dto.CourseScore;
import site.lyweb.domain.dto.StuCourseRelation;
import site.lyweb.domain.dto.StudentCourse;
import site.lyweb.domain.query.CourseScoreQuery;
import site.lyweb.domain.query.StudentCourseQuery;

import java.math.BigDecimal;
import java.util.List;

/**
 * @author
深山老林
 
* @description 针对表【student】的数据库操作Mapper
 * @createDate 2024-06-19 20:53:32
 * @Entity generator.domain.Student
 */

public interface CourseScoreMapper {

    int selectByCount(CourseScoreQuery courseScoreQuery);

    List<CourseScore> selectByPage(CourseScoreQuery courseScoreQuery);

    boolean updateCourseScore(String id, BigDecimal courseScore);
}



 

3.6.6学生成绩管理功能service层

package site.lyweb.service.impl;

import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import site.lyweb.constant.Constant;
import site.lyweb.domain.dto.*;
import site.lyweb.domain.query.CourseScoreQuery;
import site.lyweb.domain.query.StudentCourseQuery;
import site.lyweb.mapper.CourseScoreMapper;
import site.lyweb.mapper.StudentCourseMapper;
import site.lyweb.service.CourseScoreService;
import site.lyweb.service.StudentCourseService;
import site.lyweb.utils.ExtBeanUtils;
import site.lyweb.utils.UUIDUtils;

import java.math.BigDecimal;
import java.util.List;

/**
 * @author
深山老林
 
* @description 针对表【student】的数据库操作Service实现
 
* @createDate 2024-06-19 20:53:32
 */

@Service
public class CourseScoreServiceImpl implements CourseScoreService {
    @Resource
    private CourseScoreMapper courseScoreMapper;
    /**
     *
分页 + 搜索
    
*
     * @param
current
    
* @param courseScoreQuery
    
* @return
     */
   
@Override
    public PageDTO<CourseScoreDTO> getCourseScoreByPage(Integer current, CourseScoreQuery courseScoreQuery) {
        //分页查询分两个查询,1、查符合条件的数据总条数;2、查询当前页的数据
       
int totalRow = courseScoreMapper.selectByCount(courseScoreQuery);
        int start = (current - 1) * Constant.PAGE_SIZE;
        List<CourseScore> courseScoresList = courseScoreMapper.selectByPage(courseScoreQuery);
        int totalPage = totalRow / Constant.PAGE_SIZE;
        if (totalRow % Constant.PAGE_SIZE > 0) { //如果除不尽,总页数就需要加1
           
totalPage ++;
        }
        //需要把 List<TUser> 转换为 List<UserInfoDTO>
       
List<CourseScoreDTO> courseScoreDTOList = ExtBeanUtils.copyPropertiesForList(courseScoresList, CourseScoreDTO.class);

        return new PageDTO<>(current, Constant.PAGE_SIZE, totalRow, totalPage, courseScoreDTOList);

    }

    @Override
    public boolean updateCourseScore(String id,BigDecimal courseScore) {
        try{
            return courseScoreMapper.updateCourseScore(id,courseScore);
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }

    }


}



 

3.6.7学生成绩管理功能service层接口

package site.lyweb.service;

import site.lyweb.domain.dto.CourseScoreDTO;
import site.lyweb.domain.dto.PageDTO;
import site.lyweb.domain.dto.StuCourseRelation;
import site.lyweb.domain.dto.StudentCourseDTO;
import site.lyweb.domain.query.CourseScoreQuery;
import site.lyweb.domain.query.StudentCourseQuery;

import java.math.BigDecimal;
import java.util.List;

/**
 * @author
深山老林
 
* @description 针对表【student】的数据库操作Service
 * @createDate 2024-06-19 20:53:32
 */

public interface CourseScoreService {

    PageDTO<CourseScoreDTO> getCourseScoreByPage(Integer current, CourseScoreQuery courseScoreQuery);

    boolean updateCourseScore(String id,BigDecimal courseScore);
}

3.6.8学生成绩管理功能controller层

package site.lyweb.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import site.lyweb.domain.dto.PageDTO;
import site.lyweb.domain.dto.StuCourseRelation;
import site.lyweb.domain.dto.CourseScoreDTO;
import site.lyweb.domain.query.CourseScoreQuery;
import site.lyweb.result.RestResult;
import site.lyweb.service.CourseScoreService;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;

/**
 * @Author
林瑶
 
* @Description TODO
 
* @Date 2024/6/20 2:21
 */

@CrossOrigin(origins = "*")
@RestController
@Tag(name="学生成绩管理模块")
@Slf4j
@RequestMapping("/course_score")
public class CourseScoreController {
    @Resource
    private CourseScoreService courseScoreService;
    /**
     *
分页查询学生成绩管理数据
    
*
     * @return
     */

   
@Operation(summary = "分页查询学生成绩管理数据")
    @GetMapping(value = "/course_score_info/getCourseScoreByPage")
    public RestResult getCourseScoreByPage( CourseScoreQuery courseScoreQuery) {


        //分页查询的结果用PageDTO进行封装
       
PageDTO<CourseScoreDTO> pageDTO = courseScoreService.getCourseScoreByPage(0, courseScoreQuery);

        //有的时候,查询可以不判断成功与失败,不管查没查到数据,都返回200,页面上去控制显示
       
return RestResult.SUCCESS(pageDTO);
    }

    @Operation(summary = "修改学生成绩")
    @PostMapping(value = "/course_score_info/updateCourseScore")
    public RestResult updateCourseScore(StuCourseRelation stuCourseRelation){
        String id = stuCourseRelation.getId();
        BigDecimal courseScore = stuCourseRelation.getCourseScore();
        return courseScoreService.updateCourseScore(id,courseScore)?RestResult.SUCCESS("成绩修改成功!"):RestResult.FAIL();
    }


}

3.6.9学生成绩管理功能前端主页面(教师端)

<template>

  <el-form :inline="true" :model="courseScoreSearchQuery" class="demo-form-inline">

    <el-form-item label="课程名称">

      <el-select

          v-model="courseScoreSearchQuery.courseName"

          placeholder="请选择课程名称"

          style="width: 200px"

          clearable>

        <el-option

            v-for="item in courseOptions"

            :key="item.id"

            :label="item.name"

            :value="item.name"/>

      </el-select>

    </el-form-item>

    <el-form-item label="课程学分区间" style="width: 300px;">

      <el-input v-model="courseScoreSearchQuery.minCourseCredits" placeholder="最小学分" clearable style="width: 45%;"/>

      <p>-</p>

      <el-input v-model="courseScoreSearchQuery.maxCourseCredits" placeholder="最大学分" clearable style="width: 45%;"/>

    </el-form-item>    

    <el-form-item label="老师名称">

      <el-select

          v-model="courseScoreSearchQuery.teacherName"

          placeholder="请选择授课老师"

          style="width: 200px"

          clearable>

        <el-option

            v-for="item in teacherOptions"

            :key="item.id"

            :label="item.name"

            :value="item.name"/>

      </el-select>

    </el-form-item>

    <el-form-item label="课程分数区间" style="width: 300px;">

      <el-input v-model="courseScoreSearchQuery.minCourseScore" placeholder="最低分" clearable style="width: 45%;"/>

      <p>-</p>

      <el-input v-model="courseScoreSearchQuery.maxCourseScore" placeholder="最高分" clearable style="width: 45%;"/>

    </el-form-item>    

   

    <el-form-item>

      <el-button type="primary" @click="onSarch">搜 索</el-button>

      <el-button type="primary" plain @click="onReset">重 置</el-button>

    </el-form-item>

  </el-form>

  <br/><br/>

  <el-button type="primary" @click="addCourseScore">录入学生成绩</el-button>

  <el-button type="danger" @click="batchDelCourseScore">批量删除学生成绩</el-button>

  <br/><br/>

  <el-table

      ref="multipleTableRef"

      :data="courseScoreList"

      style="width: 100%"

      @selection-change="handleSelectionChange">

    <el-table-column type="selection" width="55" />

    <el-table-column type="index" label="序号" width="60" />

    <el-table-column property="courseName" label="课程名" />

    <el-table-column property="courseCredits" label="课程学分" />

    <el-table-column property="teacherName" label="老师姓名" width="200"/>

    <el-table-column property="studentName" label="学生姓名" width="200"/>

    <el-table-column property="courseScore" label="课程分数" />

    <el-table-column label="操作" width="230">

      <template #default="scope"><!--vue插槽-->

        <el-button type="success" @click="edit(scope.row.id)">编辑</el-button>

        <el-button type="danger" @click="del(scope.row.id)">删除</el-button>

      </template>

    </el-table-column>

  </el-table>

  <br/>

  <el-pagination background

                 layout="prev, pager, next"

                 :page-size="pageSize"

                 :total="totalRow"

                 @prev-click="page"

                 @next-click="page"

                 @current-change="page"/>

</template>

<script>

import {doPost, doGet} from "@/http/axios-http";

import {message, messageConfirm} from "@/http/message";

export default {

  //注入reload

  inject : ['reload'],

  data() {

    return {

      //成绩管理搜索条件对象,初始值是空

      courseScoreSearchQuery : {},

      //成绩管理列表list对象数据,初始值是空

      courseScoreList : [{}],

      //每页显示多少条

      pageSize : 0,

      //总共有多少条

      totalRow : 0,

      //勾选了哪些成绩管理id,默认值是空

      courseScoreIdArray : [],

      teacherOptions:[{}],

      courseOptions:[{}],

      courseScoreRelation:{}

    }

  },

  //页面渲染时触发该钩子函数

  mounted() {

    this.getData();

    this.loadAllTeacher();

    this.loadAllCourse();

  },

  methods : {

    loadAllTeacher(){

      doGet('/teacher/tea_info/getAll').then(resp=>{

        console.log(resp.data)

        if(resp.data.code==200){

          this.teacherOptions = resp.data.data;

        }else {

            //提示一下

            message("拿到老师信息失败,原因:" + resp.data.msg, "error");

          }

      })

    },

    loadAllCourse(){

      doGet('/course/course_info/getAll').then(resp=>{

        console.log(resp)

        if(resp.data.code==200){

          this.courseOptions = resp.data.data

        }else {

            //提示一下

            message("拿到课程信息失败,原因:" + resp.data.msg, "error");

          }

      })

    },

    //查询成绩管理列表数据

    getData() {

      doGet('/course_score/course_score_info/getCourseScoreByPage',this.courseScoreSearchQuery).then(resp => {

        console.log(resp)

        if (resp.data.code === 200) {

          this.courseScoreList = resp.data.data.dataList;

          this.pageSize = resp.data.data.pageSize;

          this.totalRow = resp.data.data.totalRow;

        }

      })

    },

    //搜索

    onSarch() {

      this.getData();

    },

    //重置

    onReset() {

      this.courseScoreSearchQuery = {};

    },

    //录入成绩管理

    addCourseScore() {

      //跳转路由

      this.$router.push({path : "/teacherDash/course_score_info/add"});

      //window.location.href = "/dashboard/courseScore/add";

    },

    //编辑成绩管理

    edit(id) {

      console.log(id);

      this.$router.push({path : "/teacherDash/course_score_info/edit/" + id});

    },

  //删除学生选课

  del(id) {

      //首先提示用户是否确定要删除

      messageConfirm("您是否确定要删除此数据?").then(() => { //当你点“确定”,执行该函

        doPost("/student_course/student_course_info/del/" + id, {}).then(resp => {

          if (resp.data.code === 200) {

            //删除成功

            message("删除成功", "success");

            //刷新页面

            this.reload();

          } else {

            message("删除失败,原因:" + resp.data.msg, "error");

          }

        })

      }).catch(error => { //当你点“取消”,执行该函数

        message("删除错误:"+error, "warning");

       

      });

    },

    //批量删除学生选课

    batchDelCourseScore() {

      //用户没有选数据,要提示一下

      if (this.courseScoreIdArray.length <= 0) {

        message("请选择要删除的数据", "warning");

        return;

      }

      //1、拿到选择的id

      let ids = this.courseScoreIdArray.join(",");  //得到:ids = "1,2,5,7,10,12"

      //2、把这些id的数据删除

      messageConfirm("您是否确定要删除这些数据?").then(() => { //当你点“确定”,执行该函

        doPost("/student_course/student_course_info/batchDel/" + ids, {}).then(resp => {

          if (resp.data.code === 200) {

            //删除成功

            message("删除成功", "success");

            //刷新页面

            this.reload();

          } else {

            //删除失败

            message("删除失败,原因:" + resp.data.msg, "error");

          }

        })

      }).catch(() => { //当你点“取消”,执行该函数

        message("删除已取消", "warning");

      });

    },

    //勾选或取消复选框时触发该函数

    handleSelectionChange(selection) {

      //勾选或取消复选框时,先把用户id的数组清空

      this.courseScoreIdArray = [];

      selection.forEach( (courseScore) => {

        this.courseScoreIdArray.push(courseScore.id);

      });

    }

  }

}

</script>

<style>

</style>

3.6.10学生成绩管理功能前端添加页面(学生端)

<template>

  <el-form

      label-width="80px"

      style="max-width: 95%;">

    <el-form-item label="老师姓名">

      <el-select

          v-model="courseScoreQuery.teacherId"

          placeholder="请选择授课老师"

          style="width: 100%"

          clearable>

        <el-option

            v-for="item in teacherOptions"

            :key="item.id"

            :label="item.name"

            :value="item.id"/>

      </el-select>

    </el-form-item>

    <el-form-item label="课程名称">

      <el-select

          v-model="courseScoreQuery.courseId"

          placeholder="请选择课程名称"

          style="width: 100%"

          clearable>

        <el-option

            v-for="item in courseOptions"

            :key="item.id"

            :label="item.name"

            :value="item.id"/>

      </el-select>

    </el-form-item>

    <el-form-item label="学生姓名">

      <el-select

          v-model="courseScoreQuery.stuId"

          placeholder="请选择学生姓名"

          style="width: 100%"

          clearable>

        <el-option

            v-for="item in studentOptions"

            :key="item.id"

            :label="item.name"

            :value="item.id"/>

      </el-select>

    </el-form-item>

    <el-form-item label="课程分数" style="width: 300px;">

      <el-input v-model="courseScoreQuery.courseScore" placeholder="课程分数" clearable/>

    </el-form-item>  

    <el-form-item>

      <el-input type="hidden" v-model="courseScoreQuery.id"/>

      <el-button type="primary" @click="addTeacherSubmit">提 交</el-button>

      <el-button type="success" plain @click="back">返 回</el-button>

    </el-form-item>

  </el-form>

</template>

<script>

import {doGet, doPost} from "@/http/axios-http";

import {message} from "@/http/message";

export default {

  data() {

    return {

      //老师对象,初始值是空

      courseScoreQuery : {},

      //form表单错误对象,初始值是空

      formError : {},

      teacherOptions:[{}],

      courseOptions:[{}],

      studentOptions:[{}]

    }

  },

  mounted() {

    //根据路由id加载市场老师数据

    this.loadTeacherCourse();

    this.loadAllTeacher();

    this.loadAllCourse();

    this.loadAllStudent();

  },

  methods : {

    loadAllStudent(){

      doGet('/student/stu_info/getAll').then(resp=>{

        console.log(resp.data)

        if(resp.data.code==200){

          this.studentOptions = resp.data.data;

        }else {

            //提示一下

            message("拿到学生信息失败,原因:" + resp.data.msg, "error");

          }

      })

    },

    loadAllTeacher(){

      doGet('/teacher/tea_info/getAll').then(resp=>{

        console.log(resp.data)

        if(resp.data.code==200){

          this.teacherOptions = resp.data.data;

        }else {

            //提示一下

            message("拿到老师信息失败,原因:" + resp.data.msg, "error");

          }

      })

    },

    loadAllCourse(){

      doGet('/course/course_info/getAll').then(resp=>{

        console.log(resp)

        if(resp.data.code==200){

          this.courseOptions = resp.data.data

        }else {

            //提示一下

            message("拿到课程信息失败,原因:" + resp.data.msg, "error");

          }

      })

    },

    //返回

    back() {

      //回退到上一次访问的页面

      //this.$router.go(-1);

      //精确地回到某个页面

      this.$router.push({path : "/teacherDash/course_score_info"})

    },

  //录入老师(提交保存)

  addTeacherSubmit() {

      //表单提交,使用formData提交表单

      let formData = new FormData();

      for (let field in this.courseScoreQuery) {

        formData.append(field, this.courseScoreQuery[field]);

      }

      if (this.courseScoreQuery.id) { //this.courseScoreQuery对象有id,说明的做了一次查询,那么就修改

        doPost("/student_course/student_course_info/save", formData).then(resp => {

          if (resp.data.code === 200) {

            //提示一下

            message("编辑学生选课信息成功", "success");

            //跳转到老师列表页

            this.$router.push({path : "/teacherDash/course_score_info"})

          } else {

            //提示一下

            message("编辑学生选课信息失败,原因:" + resp.data.msg, "error");

          }

        })

      } else {

        doPost("/student_course/student_course_info/save", formData).then(resp => {

          console.log(resp)

          if (resp.data.code === 200) {

            //提示一下

            message("录入学生选课信息成功", "success");

            //跳转到老师授课列表页

            this.$router.push({path : "/teacherDash/course_score_info"})

          } else {

            //提示一下

            message("录入学生选课信息失败,原因:" + resp.data.msg, "error");

          }

        })

      }

    },

    //根据路由id加载市场老师数据

    loadTeacherCourse() {

      let id = this.$route.params.id;

      console.log(id)

      if (id) {

        //编辑需要把数据查出来

        doGet("/student_course/student_course_info/get/" + id).then(resp => {

          this.courseScoreQuery = resp.data.data

        })

      }

    }

  }

}

</script>

3.6.11学生成绩管理功能前端主页面(学生端)

<template>

  <el-form :inline="true" :model="courseScoreSearchQuery" class="demo-form-inline">

    <el-form-item label="课程名称">

      <el-select

          v-model="courseScoreSearchQuery.courseName"

          placeholder="请选择课程名称"

          style="width: 200px"

          clearable>

        <el-option

            v-for="item in courseOptions"

            :key="item.id"

            :label="item.name"

            :value="item.name"/>

      </el-select>

    </el-form-item>

    <el-form-item label="课程学分区间" style="width: 300px;">

      <el-input v-model="courseScoreSearchQuery.minCourseCredits" placeholder="最小学分" clearable style="width: 45%;"/>

      <p>-</p>

      <el-input v-model="courseScoreSearchQuery.maxCourseCredits" placeholder="最大学分" clearable style="width: 45%;"/>

    </el-form-item>    

    <el-form-item label="老师名称">

      <el-select

          v-model="courseScoreSearchQuery.teacherName"

          placeholder="请选择授课老师"

          style="width: 200px"

          clearable>

        <el-option

            v-for="item in teacherOptions"

            :key="item.id"

            :label="item.name"

            :value="item.name"/>

      </el-select>

    </el-form-item>

    <el-form-item label="课程分数区间" style="width: 300px;">

      <el-input v-model="courseScoreSearchQuery.minCourseScore" placeholder="最低分" clearable style="width: 45%;"/>

      <p>-</p>

      <el-input v-model="courseScoreSearchQuery.maxCourseScore" placeholder="最高分" clearable style="width: 45%;"/>

    </el-form-item>    

   

    <el-form-item>

      <el-button type="primary" @click="onSarch">搜 索</el-button>

      <el-button type="primary" plain @click="onReset">重 置</el-button>

    </el-form-item>

  </el-form>

  <br/><br/>

  <el-table

      ref="multipleTableRef"

      :data="courseScoreList"

      style="width: 100%"

      @selection-change="handleSelectionChange">

    <el-table-column type="selection" width="55" />

    <el-table-column type="index" label="序号" width="60" />

    <el-table-column property="studentName" label="学生姓名" width="150"/>

    <el-table-column property="courseName" label="课程名" />

    <el-table-column property="courseCredits" label="课程学分" />

    <el-table-column property="teacherName" label="老师姓名" width="200"/>

    <el-table-column property="courseScore" label="课程分数" />

    <el-table-column label="操作" width="230">

      <template #default="scope"><!--vue插槽-->

        <el-button type="success" @click="edit(scope.row.id)" disabled="true">编辑</el-button>

        <el-button type="danger" @click="del(scope.row.id)" disabled="true">删除</el-button>

      </template>

    </el-table-column>

  </el-table>

  <br/>

  <el-pagination background

                 layout="prev, pager, next"

                 :page-size="pageSize"

                 :total="totalRow"

                 @prev-click="page"

                 @next-click="page"

                 @current-change="page"/>

</template>

<script>

import {doPost, doGet} from "@/http/axios-http";

import {message, messageConfirm} from "@/http/message";

export default {

  //注入reload

  inject : ['reload'],

  data() {

    return {

      //成绩管理搜索条件对象,初始值是空

      courseScoreSearchQuery : {},

      //成绩管理列表list对象数据,初始值是空

      courseScoreList : [{}],

      //每页显示多少条

      pageSize : 0,

      //总共有多少条

      totalRow : 0,

      //勾选了哪些成绩管理id,默认值是空

      courseScoreIdArray : [],

      teacherOptions:[{}],

      courseOptions:[{}],

      courseScoreRelation:{}

    }

  },

  //页面渲染时触发该钩子函数

  mounted() {

    this.getData();

    this.loadAllTeacher();

    this.loadAllCourse();

  },

  methods : {

    loadAllTeacher(){

      doGet('/teacher/tea_info/getAll').then(resp=>{

        console.log(resp.data)

        if(resp.data.code==200){

          this.teacherOptions = resp.data.data;

        }else {

            //提示一下

            message("拿到老师信息失败,原因:" + resp.data.msg, "error");

          }

      })

    },

    loadAllCourse(){

      doGet('/course/course_info/getAll').then(resp=>{

        console.log(resp)

        if(resp.data.code==200){

          this.courseOptions = resp.data.data

        }else {

            //提示一下

            message("拿到课程信息失败,原因:" + resp.data.msg, "error");

          }

      })

    },

    //查询成绩管理列表数据

    getData() {

      this.userInfo = JSON.parse(localStorage.getItem("userInfo"))

      this.courseScoreSearchQuery.studentName = this.userInfo.name

      doGet('/course_score/course_score_info/getCourseScoreByPage',this.courseScoreSearchQuery).then(resp => {

        console.log(resp)

        if (resp.data.code === 200) {

          this.courseScoreList = resp.data.data.dataList;

          this.pageSize = resp.data.data.pageSize;

          this.totalRow = resp.data.data.totalRow;

        }

      })

    },

    //搜索

    onSarch() {

      this.getData();

    },

    //重置

    onReset() {

      this.courseScoreSearchQuery = {};

    },

    //录入成绩管理

    addCourseScore() {

      //跳转路由

      this.$router.push({path : "/teacherDash/course_score_info/add"});

      //window.location.href = "/dashboard/courseScore/add";

    },

    //编辑成绩管理

    edit(id) {

      console.log(id);

      this.$router.push({path : "/teacherDash/course_score_info/edit/" + id});

    },

  //删除学生选课

  del(id) {

      //首先提示用户是否确定要删除

      messageConfirm("您是否确定要删除此数据?").then(() => { //当你点“确定”,执行该函

        doPost("/student_course/student_course_info/del/" + id, {}).then(resp => {

          if (resp.data.code === 200) {

            //删除成功

            message("删除成功", "success");

            //刷新页面

            this.reload();

          } else {

            message("删除失败,原因:" + resp.data.msg, "error");

          }

        })

      }).catch(error => { //当你点“取消”,执行该函数

        message("删除错误:"+error, "warning");

       

      });

    },

    //批量删除学生选课

    batchDelCourseScore() {

      //用户没有选数据,要提示一下

      if (this.courseScoreIdArray.length <= 0) {

        message("请选择要删除的数据", "warning");

        return;

      }

      //1、拿到选择的id

      let ids = this.courseScoreIdArray.join(",");  //得到:ids = "1,2,5,7,10,12"

      //2、把这些id的数据删除

      messageConfirm("您是否确定要删除这些数据?").then(() => { //当你点“确定”,执行该函

        doPost("/student_course/student_course_info/batchDel/" + ids, {}).then(resp => {

          if (resp.data.code === 200) {

            //删除成功

            message("删除成功", "success");

            //刷新页面

            this.reload();

          } else {

            //删除失败

            message("删除失败,原因:" + resp.data.msg, "error");

          }

        })

      }).catch(() => { //当你点“取消”,执行该函数

        message("删除已取消", "warning");

      });

    },

    //勾选或取消复选框时触发该函数

    handleSelectionChange(selection) {

      //勾选或取消复选框时,先把用户id的数组清空

      this.courseScoreIdArray = [];

      selection.forEach( (courseScore) => {

        this.courseScoreIdArray.push(courseScore.id);

      });

    }

  }

}

</script>

<style>

</style>

第4章  测试

4.1 教师端-学生管理模块测试

4.1.1 学生添加功能测试

点击添加按钮,录入学生姓名、年龄、手机号,并点击提交按钮。

图 20 学生添加功能

弹出“录入学生信息成功”,同时发现界面上多出了一条数据,证明录入成功。

图 21 添加成功

4.1.2 学生删除功能(删除单条)

点击第4条数据:“李四”那一行的“删除”按钮,弹出系统提示框

 

图 22 删除单条学生数据

点击确定后,回到学生信息界面,同时弹出“删除成功”,观察数据,“李四”那条数据已经消失,证明删除成功。

图 23 删除成功

4.1.3 学生删除功能(批量删除)

勾选上1、5条数据,点击上方“批量删除”按钮,弹出系统提示框

图 24 批量删除学生信息

弹出“删除成功”,同时发现,张三和张章的数据没了,证明删除成功

图 25 删除成功

4.1.4 学生修改功能

点击张四旁边的修改按钮,带着那一条数据原有的所有信息,回显到了添加界面的输入框中,现在你可以对数据进行修改了。

图 26 修改学生信息

修改张四的手机号为16444444444,点击提交后,数据修改成功。

图 27 修改成功

4.1.5 学生查询功能

在学生姓名那栏输入姓名:林瑶,点击搜索,查询到了符合条件的数据。

图 28 按姓名查询

在学生手机号那栏输入:18888888888,点击搜索,查询到了符合条件的数据。

图 29 按手机号查询

第5章  总结

5.1  总结

        这次的Java课设难度比较低,限定了题目,所以写一天就写完了。6月24早上答辩,我6月23号早上10点才开始写,先是花了1个小时搭了一下数据库,配置了一下前后端框架,又花了一个小时,把登录界面搭了出来,配色和背景我选了好久,最终才敲定了用天科大logo背景+浅蓝底色。12点左右,吃了个饭,回去接着写。

        想着先从简单的写起,就选择了学生表的增删改查,有MybatisPlus加持,后端接口我只需要写分页查询的就好了,但也不简单,mysql和sqlserver还是有一丢丢区别的,比如分页的sql语句,在mysql中是limit a,b,在sqlserver里就变成between...and...了,还有模糊查询,在mysql中用like和%就可以搞定,但在sqlserver中又没法做了,以及sqlserver的连接,我平时都用的主机直接连,但要配置到后端里,就又得找到好几个参数了。这还只是后端的问题,前端也遇到了一些比较抽象的问题,比如,我后端明明打了@CrossOrigin注解,但就是会出现跨域问题,可无论是配代理服务器,还是修改请求header,都解决不了。后来实在没办法了还去咨询了京东的前端大佬,大佬很仔细的给我找bug,最后发现,是后端的Post请求,我前端在发的时候写成Get了,emm有点抽象。

        所以第一个学生表的CRUD我写了整整5个小时,到下午5点了刚好吃晚饭。因为已经做了一张表了,剩下俩就是照猫画虎了,我也耍了点小聪明,在命名的时候没有乱命名,全部统一成了驼峰命名法,所以在做老师表和课程表的时候,我只需要拷贝到记事本里,再全局替换student为teacher或者course就行了,我注释也写的都挺明白了,一看就会,所以后面两张表才写1个小时就写完了。

        写完单表的,就要开始写多表的了。比如学生课程表,这里我就没法用mybatisplus了,所有增删改查就都得手写,幸好没什么复杂的功能,所以也没写多久,一下就弄完了。就是有一个问题,在设置数据库的时候,我使用了外键关联,这就导致了无法delete,这个问题的解决方法有写触发器、这一段代码忽略外键影响等,我最后选择了取消外键,这个确实会出现很多问题。

        最后,从8点写到11点多了,才完成学生选课功能,但给我写兴奋了,一点不想睡,于是,就又吭哧吭哧就把教师选课的功能给做完了,最后成绩管理那个功能有点迷,不就是一个字段吗,怎么还有增删改查了,最后规划了一下,给设置成了修改成绩这一个字段了,所以这个是最后最好写的一个模块。

        大概做到早上4点,基本功能全弄完了,还是觉得不太满意,没做分权限心理不舒服,于是又基于现有模块,把分权限弄完了。完事还是觉得丑,又加了几个echarts表格,终于,看着顺眼多了。

        最后,早上6点左右的时候,完成了整个系统,测了一下,非常完美,于是安心睡下了。躺了大概一两个小时,就去答辩了。

        总之,这次课设写的还算比较顺利,最终完成的效果我也比较满意,除了少睡了一天觉以外,其他都挺好的。

5.2  不足之处

    1.给出的几张数据库表有些问题,如:主键id类型不统一,导致无法关联等。

    2.虽然对每一个模块都做了所有字段的查询,但对于一些字符串为参数的查询,并没有实现模糊查询,因为sqlserver语法不熟练。

    3.分页查询固定是1页,没做分页效果。

    4.正常来说应该是3个权限:管理员、老师、学生,但这里只做了老师和学生两个权限了,老师是全部权限。

    5.首页echarts只统计了系统使用人数,但还可以统计分数、年龄分布、各专业人数的,但时间有限,就没做了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1990007.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

智慧图书馆:构建高效视频智能管理方案,提升图书馆个性化服务

一、背景分析 随着信息技术的飞速发展&#xff0c;智慧图书馆作为现代公共文化服务的重要载体&#xff0c;正逐步从传统的纸质阅读空间向数字化、智能化方向转型。其中&#xff0c;视频智能管理方案作为智慧图书馆安全管理体系的重要组成部分&#xff0c;不仅能够有效提升图书…

深入浅出Mysql 第二期

从更新语句中看日志系统 探究技术的本质&#xff0c;享受技术的乐趣&#xff01;由于时间原因以及自己的原因导致拖更了&#xff0c;不过没关系&#xff0c;我保证后面每天一更&#xff0c;周末休息&#xff01;好了&#xff0c;闲话少说&#xff0c;今天我们通过一个更新操作…

数组案例练习进阶版---对数组中的元素进行排序(冒泡法)

在上篇文章中&#xff0c;我们一起学习了常用排序法中的选择排序法&#xff0c;今天&#xff0c;我们将一起来学习新的排序方法——冒泡法排序 那么首先&#xff0c;什么是冒泡法呢&#xff1f; 首先&#xff0c;第一列&#xff0c;我们有四个大小不一的球&#xff0c;我们称最…

4款ai 制作 ppt工具帮你提高工作效率

在这个高度重视可视化展示的环境当中&#xff0c;PPT在许多的场合中都骑着非常重要的作用&#xff0c;但PPT制作过程却常常令人感到烦恼。而最近我发现了4个堪称神器的PPT制作工具&#xff0c;可以分享给大家。 1、笔灵 ppt 直通车&#xff1a;https://ibiling.cn/ppt-zone 这…

数据结构与算法 - 红黑树

一、概述 1. 历史 红黑树是一种自平衡二叉查找树&#xff0c;最早由一名叫Rudolf Bayer的德国计算机科学家于1972年发明。然而&#xff0c;最初的树形结构不是现在的红黑树&#xff0c;而是一种称为B树的结构&#xff0c;它是一种多叉树&#xff0c;可以用于在磁盘上存储大量…

美国司法部对谷歌反垄断案的最新进展,Google每年给苹果200亿?

本文首发于公众号“AntDream”&#xff0c;欢迎微信搜索“AntDream”或扫描文章底部二维码关注&#xff0c;和我一起每天进步一点点 美国司法部对谷歌反垄断案的前因和最新进展 美国司法部对谷歌的反垄断案是一个复杂且历时长久的法律过程&#xff0c;其核心争议在于谷歌是否利…

CentOS 7.6 安装 Weblogic

注&#xff1a;本教程是以虚拟机作为安装环境&#xff0c;如果您公司需要安装 Weblogic 服务器&#xff0c;请先以虚拟机模拟安装一遍&#xff0c;否则出现失误&#xff0c;概不负责&#x1f601;。 一、环境 虚拟机&#xff1a;VMware Workstation 16 Linux&#xff1a;Cent…

@Autowired提示:Field injection is not recommended

1、问题 在项目升级版本过程中&#xff0c;Autowired提示Field injection is not recommendedField injection is not recommended Inspection info: Reports injected or autowired fields in Spring components. The quick-fix suggests the recommended constructor-based d…

Linux 下查看 CPU 使用率

目录 一、什么是 CPU 使用率二、查看 CPU 利用率1、使用 top 查看2、用 pidstat 查看3、用 ps 查看4、用 htop 查看5、用 nmon 查看6、用 atop 查看7、用 glances 查看8、用 vmstat 查看9、用 sar 查看10、dstat11、iostat 三、总结 CPU 使用率是最直观和最常用的系统性能指标&…

Linux下自动监控进程运行状态

目录 背景应用举例1、使用crontab脚本监控服务2、使用shell脚本监控服务2.1 编写自定义监控脚本2.2 运行脚本 背景 假设有一个服务需要长期运行&#xff0c;但可能会由于某种原因导致服务意外停止&#xff0c;不能及时发现&#xff0c;某天来到公司后发现出问题了才意识到服务…

【linux】curl命令用法

curl命令认识 curl命令其实在平常工作中就已经在使用了&#xff0c;但是一直没有系统看过&#xff0c;就在这记录下&#xff0c;以后要用的话&#xff0c;可以在这儿查阅。 curl命令写的更清楚一点其实是cURL&#xff08;client url&#xff0c;客户端URL或者command url命令…

时间复杂度计算方法以及常见题型

时间复杂度是衡量算法运行时间随输入规模增长而增长快慢的一种度量方式。它并不是指算法在特定硬件上的实际运行时间&#xff0c;而是算法在理想环境下执行时间的增长趋势。计算时间复杂度时&#xff0c;我们主要关注算法中执行次数最多的操作&#xff08;即基本操作&#xff0…

算法板子:匈牙利算法——二分图的最大匹配

目录 1. 基础概念 &#xff08;1&#xff09;二分图的概念 &#xff08;2&#xff09; 匈牙利算法的作用 2. 代码 1. 基础概念 &#xff08;1&#xff09;二分图的概念 顶点集 V 分为两个集合&#xff0c;且图中每条边依附的两个顶点都分属于这两个子集&#xff0c;也就是第…

了解反向代理如何工作吗?

在当今数字化时代&#xff0c;网络通讯扮演着重要的角色&#xff0c;而代理技术为网络通讯提供了更多的灵活性和安全性。作为两种重要的代理技术&#xff0c;代理服务器和反向代理的运行原理和用途各有不同。本文将重点介绍反向代理的运行原理&#xff0c;深入探讨其在网络通讯…

运动耳机哪款好?多方位实测五大风靡网络的爆款,第一款竟然连奥运冠军都在用

随着健康意识的提升&#xff0c;将骨传导耳机作为运动伴侣的国人日益增多&#xff0c;其市场年度销售额已突破新高。然而&#xff0c;作为深耕运动装备领域多年的专家&#xff0c;我深感有责任告诫广大运动爱好者&#xff0c;在选择骨传导耳机时&#xff0c;务必保持警惕&#…

PD虚拟机共享文件夹 PD虚拟机共享蓝牙设备怎么设置 PD虚拟机如何共享文件

PD虚拟机&#xff08;Parallels Desktop&#xff09;是为有双系统使用需求人士设计的Mac系统软件。PD虚拟机可以在Mac电脑中设置Windows系统的应用软件。有了PD虚拟机的帮助&#xff0c;大家可以直接在Mac系统中使用其他如Windows的虚拟机系统&#xff0c;除此以外&#xff0c;…

软件RAID配置实战(2个案例场景)

文章目录 3、软件RAID管理-mdadm工具安装mdadm组件格式示例选项说明mdadm命令其它常用选项 4、相关查询命令查看创建RAID的进度查看RAID磁盘详细信息查看文件系统的磁盘空间使用情况 5、RAID配置示例场景1&#xff1a;RAID5步骤 场景2&#xff1a;RAID10步骤 6、移除RAID阵列 接…

031_java.util.concurrent.CopyOnWriteArrayList

继承体系 CopyOnWriteArrayList存在的目的是为了解决在高并发下list的读写。设计上希望只阻塞写行为&#xff0c;不会阻塞读行为。CopyOnWriteArrayList设计就基于此&#xff0c;在内部含有ReentrantLock用作修改时加锁&#xff0c;CopyOnWriteArrayList下有很多可以写方法&…

三种向量相似度计量方法——欧式距离、余弦相似度、皮尔逊相关系数

1、欧式距离 欧氏距离在机器学习可以清晰展示不同对象的相似程度。 欧式距离是最直观的距离度量方法之一&#xff0c;它衡量两个点之间的直线距离, 较小的欧式距离意味着较高的相似度。 分类——K近邻算法&#xff08;KNN&#xff09;&#xff1a;需要对一个新的样本进行分类…

IIS6 PUT漏洞

一.漏洞描述 IIS Server 在 Web 服务扩展中开启了 WebDAV &#xff0c;配置了可以写⼊的权限&#xff0c;造成任意⽂件上传 1.1环境搭建 环境 fofa&#xff1a;"IIS-6.0" 本地搭建2003 server 1.2漏洞复现 1.开启 WebDAV 和写权限&#xff1a; 1.3 漏洞复现 使…