♥️作者:小宋1021
🤵♂️个人主页:小宋1021主页
♥️坚持分析平时学习到的项目以及学习到的软件开发知识,和大家一起努力呀!!!
🎈🎈加油! 加油! 加油! 加油
🎈欢迎评论 💬点赞👍🏻 收藏 📂加关注+!
目录
updateTimeTableStudyStudent方法:
TimeTableStudyStudentServiceImpl实现类:
TimeTableStudyStudentSaveReqVO:
场景:课程和学生是一对多的关系,每一个课程对应多个学生,在学生上完课之后要做一个消课记录,“已到”就是消课成功,“未到”就是没有消课。通过数据库里面的消课状态字段来记录,0:未消 1:已消。
这就需要前端传一个id的数组,后端遍历这个id数组,去改变每一条id下的消课状态属性。
我们来看看是怎么实现的。
编辑
编辑
编辑
前端:
列表项:
<el-table-column label="序号" type="index" header-align="center" align="center" width="60px" fixed /> <el-table-column type="selection" width="55" @change="handleSelectionChange" /> <el-table-column label="学生姓名" align="center" prop="stsStudentName" /> <el-table-column label="手机号" align="center" prop="stsPhone" /> <!-- <el-table-column label="上课时间" align="center" prop="firstClassStartTime" /> --> <el-table-column label="请假状态" align="center" prop="leavelStatus" width="100px"> <template #default="scope"> <dict-tag :type="DICT_TYPE.STUDY_LEAVE_STATUS" :value="scope.row.leavelStatus" /> </template> </el-table-column> <el-table-column label="消课状态" align="center" prop="usedStatus" width="100px"> <template #default="scope"> <dict-tag :type="DICT_TYPE.STUDY_CANCEL_CLASS_STATUS" :value="scope.row.usedStatus" /> </template> </el-table-column> </el-table>
在这里加了多选框方便选择多个学员,还给这个多选框设置了一个点击事件@change="handleSelectionChange
点击事件:
const handleSelectionChange = (val: TimeTableVO[]) => { id.value = [] for (let i = 0; i < val.length; i++) { id.value.push(val[i]) } }
定义了一个id的数组,然后遍历TimeTableVO,把TimeTableVO依次push到id数组里面
按钮:
<el-button type="primary" plain @click="submitForm" > 已到 </el-button> <el-button type="primary" plain @click="submitForm2" > 未到 </el-button>
每个按钮都有一个提交的点击事件,是为了把id数组提交给后台进行修改。
按钮点击事件:
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调 const message = useMessage() // 消息弹窗 const submitForm=async ()=>{ const ids = []; id.value.forEach(itemProps => { ids.push(itemProps.id) }); // tableData.id = id.value await TimeTableStudyStudentApi.updateTimeTableStudyStudent({ids:ids,type:"1"}) //传递给父组件 dialogVisible.value = false; emit('success') }
遍历数组,拿到id然后赋值给已经定义好的ids数组里面然后调用TimeTableStudyStudentApi里面的updateTimeTableStudyStudent方法,其实就是编辑方法。
updateTimeTableStudyStudent方法:
// 修改全部学员 updateTimeTableStudyStudent: async (data) => { return await request.put({ url: `/study/time-table-study-student/update` , data }) },
后端:
后端就是正常的updateById方法,稍作修改即可
Service层:
/** * 更新上课学生(与课表是N对1) * * @param 更新信息 */ void updateTimeTableStudyStudent(@Valid TimeTableStudyStudentSaveReqVO studyStudentSaveReqVO); /** * 更新上课学生(与课表是N对1) * * @param 更新信息 */ void updateTimeTableStudyStudentCancel(@Valid TimeTableStudyStudentSaveReqVO studyStudentSaveReqVO);
上边是消课把0置为1,下边是未到把1置为0(未到的作用是防止消课人员点错)
TimeTableStudyStudentServiceImpl实现类:
@Override public void updateTimeTableStudyStudent(TimeTableStudyStudentSaveReqVO studyStudentSaveReqVO) { studyStudentSaveReqVO.getIds().stream().forEach(id -> { TimeTableStudyStudentDO student = this.getTimeTableStudyStudent(id); student.setUsedStatus(1); // 假设只需要更新 usedStatus // updateObjList.add(timeTableStudyStudentDO); timeTableStudyStudentMapper.updateById(student); }); }
用stream流对id进行foreach循环,新建一个student实体,防止覆盖数据库里的所有数据,这样的话只会覆盖当前数据的消课字段,把消课字段变成1,不会影响其他数据。通过timeTableStudyStudentMapper.updateById(student); MybatisPlus进行更新对数据库进行插入。
要注意的是TimeTableStudyStudentSaveReqVO这个类要有id的集合和type这两个字段才可以
TimeTableStudyStudentSaveReqVO:
package com.todod.education.module.study.controller.admin.timetablestudystudent.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.util.*; import jakarta.validation.constraints.*; @Schema(description = "管理后台 - 上课学生(与课表是N对1)新增/修改 Request VO") @Data public class TimeTableStudyStudentSaveReqVO { private List<Long> ids; private String type; }
实体类:
package com.todod.education.module.study.dal.dataobject.timetablestudystudent; import lombok.*; import java.util.*; import java.time.LocalDateTime; import java.time.LocalDateTime; import java.time.LocalDateTime; import com.baomidou.mybatisplus.annotation.*; import com.todod.education.framework.mybatis.core.dataobject.BaseDO; /** * 上课学生(与课表是N对1) DO * * @author 平台管理员 */ @TableName("study_time_table_study_student") @KeySequence("study_time_table_study_student_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) @Builder @NoArgsConstructor @AllArgsConstructor public class TimeTableStudyStudentDO extends BaseDO { /** * 主键 */ @TableId private Long id; /** * 课表外键 */ private Long studyTimeTableId; /** * 学生外键 */ private Long studyStudentId; /** * 消课/操作人 */ private String operator; /** * 消课/操作时间 */ private LocalDateTime operateTime; /** * 消课状态(0:未到;1:实到,默认未到) */ private Integer usedStatus; /** * 请假状态(0:未请假;1:已请假,默认未请假) */ private Short leavelStatus; /** * 预留字段 */ private String reserveContent; /** * 备注 */ private String remark; }
controller层:
@PutMapping("/update") @Operation(summary = "更新上课学生(与课表是N对1)") // @PreAuthorize("@ss.hasPermission('study:time-table-study-student:update')") public CommonResult<Boolean> updateTimeTableStudyStudent(@Valid @RequestBody TimeTableStudyStudentSaveReqVO studyStudentSaveReqVO) { timeTableStudyStudentService.updateTimeTableStudyStudent(studyStudentSaveReqVO); return success(true); } @PutMapping("/updateCancel") @Operation(summary = "更新上课学生(与课表是N对1)") // @PreAuthorize("@ss.hasPermission('study:time-table-study-student:update')") public CommonResult<Boolean> updateTimeTableStudyStudentCancel(@Valid @RequestBody TimeTableStudyStudentSaveReqVO studyStudentSaveReqVO) { timeTableStudyStudentService.updateTimeTableStudyStudentCancel(studyStudentSaveReqVO); return success(true); }
注意传值。
前端全部代码:
<template> <Dialog title="消课" v-model="dialogVisible"> <div> <el-descriptions class="margin-top" :column="2" :size="size" > <el-descriptions-item label="班级名称:"> {{list.className}} </el-descriptions-item> <el-descriptions-item label="班级类型:"> {{getDictLabel(DICT_TYPE.COURSE_TYPE,list.classType) }} </el-descriptions-item> <el-descriptions-item label="上课时间:"> {{list.classDate}} {{list.classStartTime }} - {{ list.classDate }} {{ list.classEndTime }} </el-descriptions-item> <el-descriptions-item label="班级课程:"> {{list.courseName }} </el-descriptions-item> <el-descriptions-item label="授课老师:"> {{list.teacherName }} </el-descriptions-item> </el-descriptions> </div> <ContentWrap> <el-button type="primary" plain @click="submitForm" > 已到 </el-button> <el-button type="primary" plain @click="submitForm2" > 未到 </el-button> <el-table v-loading="loading" :data="list2" :stripe="true" :show-overflow-tooltip="true" @selection-change="handleSelectionChange" > <el-table-column label="序号" type="index" header-align="center" align="center" width="60px" fixed /> <el-table-column type="selection" width="55" @change="handleSelectionChange" /> <el-table-column label="学生姓名" align="center" prop="stsStudentName" /> <el-table-column label="手机号" align="center" prop="stsPhone" /> <!-- <el-table-column label="上课时间" align="center" prop="firstClassStartTime" /> --> <el-table-column label="请假状态" align="center" prop="leavelStatus" width="100px"> <template #default="scope"> <dict-tag :type="DICT_TYPE.STUDY_LEAVE_STATUS" :value="scope.row.leavelStatus" /> </template> </el-table-column> <el-table-column label="消课状态" align="center" prop="usedStatus" width="100px"> <template #default="scope"> <dict-tag :type="DICT_TYPE.STUDY_CANCEL_CLASS_STATUS" :value="scope.row.usedStatus" /> </template> </el-table-column> </el-table> <!-- 分页 --> <Pagination :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize" @pagination="getList" /> </ContentWrap> </Dialog> </template> <script setup lang="ts"> import { dateFormatter } from '@/utils/formatTime' import { getStrDictOptions,getDictLabel, DICT_TYPE } from '@/utils/dict' import { TimeTableStudyStudentApi, TimeTableStudyStudentVO } from '@/api/study/timetablestudystudent' import { ref,onMounted } from 'vue'; import { TimeTableApi, TimeTableVO } from '@/api/study/timetable' import { itemProps } from '@/layout/components/HeaderMenu/src/props'; import { C } from '@fullcalendar/core/internal-common'; /** 消课记录 列表 */ defineOptions({ name: 'CancleClass' }) const dialogVisible = ref(false) // 弹窗的是否展示 const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用 const loading = ref(true) // 列表的加载中 const list = ref([]) // 列表的数据 const list2 = ref([]) // 列表的数据 const total = ref(0) // 列表的总页数 const queryParams = reactive({ pageNo: 1, pageSize: 10, }) const formData = ref({ id: undefined, studentId: undefined }) const props = defineProps({ classId: { type: Number } }) const formRef = ref() // 表单 Ref const id = ref([]) const handleSelectionChange = (val: TimeTableVO[]) => { id.value = [] for (let i = 0; i < val.length; i++) { id.value.push(val[i]) } } const student = ref([]) /** 打开弹窗 */ const open = async (type: string, id?: number,courseId?: number, students?: Array ) => { dialogVisible.value = true console.log(courseId,'asdsad') resetForm() // 修改时,设置数据 if (id) { formLoading.value = true try { const data = await TimeTableApi.selectDetail(id) const data2 = await TimeTableApi.selectDetail2(id) student.value = students list.value = data[0] list2.value = data2 } finally { formLoading.value = false } } } defineExpose({ open }) // 提供 open 方法,用于打开弹窗 const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调 const message = useMessage() // 消息弹窗 const submitForm=async ()=>{ const ids = []; id.value.forEach(itemProps => { ids.push(itemProps.id) }); // tableData.id = id.value await TimeTableStudyStudentApi.updateTimeTableStudyStudent({ids:ids,type:"1"}) //传递给父组件 dialogVisible.value = false; emit('success') } const submitForm2=async ()=>{ console.log("sdfsdfsdf",id.value.length) const ids = []; id.value.forEach(itemProps => { ids.push(itemProps.id) }); // tableData.id = id.value await TimeTableStudyStudentApi.updateTimeTableStudyStudentCancel({ids:ids,type:"0"}) //传递给父组件 dialogVisible.value = false; emit('success') } const getList = async () => { loading.value = true try { const data = await TimeTableApi.selectDetail(98) list.value = data } finally { loading.value = false } } const resetForm = () => { formData.value = { id: undefined, studentId: undefined } formRef.value?.resetFields() } /** 查询列表 */ // const getList = async () => { // } onMounted(() => { getList() }) </script> <style scoped lang="scss"> :deep(.el-dialog__body){ width: 1000px !important; height: 1000px !important; } </style>
TimeTableVO:
import request from '@/config/axios' // 课表排课 VO export interface TimeTableVO { id: number[] // 主键 studyCourseId: number //课程id studyClassId: number //班级id way_enum: string //排课方式 startDate: string //开始日期 repeat_enum: string //重复方式 times: [] //上课时间 end_enum: string //结束方式 endDate: string //结束日期 hrTeacherId: number //上课老师 content: string //上课内容 dates: [] //上课日期 weekTimes:[] //按星期安排时间 num: number //按次数结束 studentIds: number[]//学员id } // 课表排课 API export const TimeTableApi = { // 查询课表排课分页 getTimeTablePage: async (params: any) => { return await request.get({ url: `/study/time-table/page`, params }) }, // 查询课表排课分页 getTimeTablePage2: async (params: any) => { return await request.get({ url: `/study/time-table/page2`, params }) }, // 查询课表排课详情 getTimeTable: async (id: number) => { return await request.get({ url: `/study/time-table/get?id=` + id }) }, // 查询消课信息详情 selectDetail: async (id: number) => { return await request.gets({ url: `/study/time-table/cancelListDetail?id=` + id }) }, // 查询消课信息详情 selectDetail2: async (id: number) => { return await request.gets({ url: `/study/time-table/cancelListDetail2?id=` + id }) }, // 查询消课信息详情 selectDetail3: async (id: number) => { return await request.gets({ url: `/study/time-table/cancelListDetail3?id=` + id }) }, // 查询消课信息详情 selectDetail4: async (id: number) => { return await request.gets({ url: `/study/time-table/cancelListDetail4?id=` + id }) }, // 新增课表排课 createTimeTable: async (data: TimeTableVO) => { return await request.post({ url: `/study/time-table/create`, data }) }, // 修改课表排课 updateTimeTable: async (data: TimeTableVO) => { return await request.put({ url: `/study/time-table/update`, data }) }, // 删除课表排课 deleteTimeTable: async (id: number) => { return await request.delete({ url: `/study/time-table/delete?id=` + id }) }, // 导出课表排课 Excel exportTimeTable: async (params) => { return await request.download({ url: `/study/time-table/export-excel`, params }) }, }
要记得把id设定为number类型的数组哦。
如果有问题欢迎我们一起沟通,祝大家万事顺意。