目的:多表联查获取到每个班级里面所有的学生上课的信息。点击消课插入到消课主表和消课子表,主表记录班级信息,消课人员信息,上课时间。子表记录上课学员的信息,学员姓名、手机号、班级名称、班级类型、上课时间、老师名称
前端:
<template><Dialog :title="dialogTitle" v-model="dialogVisible">
<!-- 列表 --><ContentWrap><el-buttontype="primary"plain@click="submitForm">消课</el-button><el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true"@selection-change="handleSelectionChange"><el-table-columnlabel="序号"type="index"header-align="center"align="center"width="60px"fixed/><el-table-column type="selection" width="55" /><el-table-column label="班级名称" align="center" prop="className" /><el-table-column label="班级类型" align="center" prop="classType" width="100px"><template #default="scope"><dict-tag :type="DICT_TYPE.COURSE_TYPE" :value="scope.row.classType" /></template></el-table-column><el-table-column label="学生姓名" align="center" prop="stsStudentName" /><el-table-column label="手机号" align="center" prop="stsPhone" /><el-table-column label="所报课程" align="center" prop="courseName" /><el-table-column label="上课时间" align="center" prop="firstClassStartTime" /><!-- <el-table-columnlabel="上课时间"align="center"prop="classTime":formatter="dateFormatter"width="180px"/> --><el-table-column label="授课教师" align="center" prop="teacherName" /></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 { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { CancleClassApi, CancleClassVO } from '@/api/study/cancleclass'
import { ref } from 'vue';/** 消课记录 列表 */
defineOptions({ name: 'CancleClass' })
const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const loading = ref(true) // 列表的加载中
const list = ref([]) // 列表的数据
const queryParams = reactive({
pageNo: 1,
pageSize: 10,})
const formData = ref({id: undefined,studentId: undefined
})const emit = defineEmits(['clickChild'])
const studentId = ref([])
const handleSelectionChange = (val: CancleClassVO[]) => {studentId.value = []for (let i = 0; i < val.length; i++) {studentId.value.push(val[i])}
}
const submitForm=async ()=>{const tableData = formData.value as unknown as CancleClassVOtableData.studentId = studentId.valueawait CancleClassApi.createCancleClass(tableData)//传递给父组件dialogVisible.value = false;
}
const open = async (type: string, classId?: number) => {dialogVisible.value = trueloading.value = true
try {const data = await CancleClassApi.getCancleClassDetail(classId)list.value = data
} finally {loading.value = false
}
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
/** 查询列表 */
// const getList = async () => {// }// onMounted(() => {
// getList()
// })
</script>
<style scoped lang="scss">:deep(.el-dialog__body){width: 1000px !important;height: 1000px !important;
}
</style>
关键:
const formData = ref({id: undefined,studentId: undefined
})const studentId = ref([])
const handleSelectionChange = (val: CancleClassVO[]) => {studentId.value = []for (let i = 0; i < val.length; i++) {studentId.value.push(val[i])}
}
const submitForm=async ()=>{const tableData = formData.value as unknown as CancleClassVOtableData.studentId = studentId.valueawait CancleClassApi.createCancleClass(tableData)//传递给父组件dialogVisible.value = false;
}
index.ts
import request from '@/config/axios'// 消课记录 VO
export interface CancleClassVO {id: number // 主键idclassName: string // 班级名称classType: string // 班级类型reportCourse: string // 所报课程classTime: Date // 上课时间classTeacher: string // 授课教师cancelClassPerson: string // 消课人cancelClassTime: Date // 消课时间studentName: string // 学员姓名phone: string // 手机号arrivedNum: number // 实到人数arrivingNum: number // 应到人数rollCallPerson: string // 点名操作人员rollCallTime: Date // 店面时间operaName: string // 操作人operaTime: Date // 操作时间operaType: string // 操作类型operaExplain: string // 操作说明studentId: any
}// 消课记录 API
export const CancleClassApi = {// 查询消课记录分页getCancleClassPage: async (params: any) => {return await request.get({ url: `/study/cancle-class/page`, params })},// 查询消课记录分页getCancleClassPage2: async (params: any) => {return await request.get({ url: `/study/cancle-class/page2`, params })},// 查询消课记录详情getCancleClass: async (id: number) => {return await request.get({ url: `/study/cancle-class/get?id=` + id })},// 查询消课记录详情getCancleClass2: async (id: number) => {return await request.get({ url: `/study/cancle-class/get2?id=` + id })},// 查询消课记录详情getCancleClassDetail: async (id: number) => {return await request.gets({ url: `/study/cancle-class/findByIds?id=` + id })},// 查询消课记录详情2getFindDetail: async (id: number) => {return await request.gets({ url: `/study/cancle-class/findDetail?id=` + id })},// 新增消课记录createCancleClass: async (data: CancleClassVO) => {return await request.post({ url: `/study/cancle-class/create`, data })},// 修改消课记录updateCancleClass: async (data: CancleClassVO) => {return await request.put({ url: `/study/cancle-class/update`, data })},// 删除消课记录deleteCancleClass: async (id: number) => {return await request.delete({ url: `/study/cancle-class/delete?id=` + id })},// 导出消课记录 ExcelexportCancleClass: async (params) => {return await request.download({ url: `/study/cancle-class/export-excel`, params })},
}
关键:
studentId: any
解析:通过遍历studentId来往后端传值,传的是对象的数组,后端通过studentId来遍历插入值
通过const tableData = formData.value as unknown as CancleClassVO映射往后端传值
// 消课记录 VO
export interface CancleClassVO {id: number // 主键idclassName: string // 班级名称classType: string // 班级类型reportCourse: string // 所报课程classTime: Date // 上课时间classTeacher: string // 授课教师cancelClassPerson: string // 消课人cancelClassTime: Date // 消课时间studentName: string // 学员姓名phone: string // 手机号arrivedNum: number // 实到人数arrivingNum: number // 应到人数rollCallPerson: string // 点名操作人员rollCallTime: Date // 店面时间operaName: string // 操作人operaTime: Date // 操作时间operaType: string // 操作类型operaExplain: string // 操作说明studentId: any
}
调用新增方法往后台插入值
await CancleClassApi.createCancleClass(tableData)
后端:
不仅要给主表建实体类,保存回显方法,还要给子表建立相应的实体类,保存回显方法。
项目架构:
controller:
实体类:
Mapper:
Service和实现类:
主表
实体类:
package com.todod.education.module.study.dal.dataobject.cancleclass;import lombok.*;import java.sql.Time;
import java.time.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
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;/*** 消课记录 DO** @author 平台管理员*/
@TableName("study_cancle_class")
@KeySequence("study_cancle_class_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CancleClassDO extends BaseDO {/*** 主键id*/@TableIdprivate Long id;/*** 班级id*/private Long classId;/*** 课程id*/private Long courseId;/*** 学员姓名*/@TableField(exist = false)private String stsStudentName;/*** 手机号*/@TableField(exist = false)private String stsPhone;/*** 班级名称*/@TableField(exist = false)private String className;/*** 班级类型*/@TableField(exist = false)private String classType;/*** 所报课程*/@TableField(exist = false)private String courseNames;/*** 所报课程*/@TableField(exist = false)private String courseName;/*** 授课教师*/@TableField(exist = false)private String teacherNames;/*** 授课教师*/@TableField(exist = false)private String teacherName;/*** 上课时间*/@TableField(exist = false)private Time firstClassStartTime;/*** 上课日期*/@TableField(exist = false)private Date firstClassDate;/*** 消课人*/private String cancelClassPerson;/*** 消课时间*/private LocalDateTime cancelClassTime;/*** 实到人数*/private Integer arrivedNum;/*** 应到人数*/private Integer arrivingNum;/*** 点名操作人员*/private String rollCallPerson;/*** 点名时间*/private LocalDateTime rollCallTime;/*** 操作人*/private String operaName;/*** 操作时间*/private LocalDateTime operaTime;/*** 操作类型*/private String operaType;/*** 操作说明*/private String operaExplain;}
由于多表联查所以在这个表里的实体类映射的时候,很多字段是从别的表里获取的,所以要加上这句话
@TableField(exist = false)
否则会去数据库里查相应字段报错。
controller:
package com.todod.education.module.study.controller.admin.cancleclass;import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;import jakarta.validation.constraints.*;
import jakarta.validation.*;
import jakarta.servlet.http.*;
import java.util.*;
import java.io.IOException;import com.todod.education.framework.common.pojo.PageParam;
import com.todod.education.framework.common.pojo.PageResult;
import com.todod.education.framework.common.pojo.CommonResult;
import com.todod.education.framework.common.util.object.BeanUtils;
import static com.todod.education.framework.common.pojo.CommonResult.success;import com.todod.education.framework.excel.core.util.ExcelUtils;import com.todod.education.framework.apilog.core.annotation.ApiAccessLog;
import static com.todod.education.framework.apilog.core.enums.OperateTypeEnum.*;import com.todod.education.module.study.controller.admin.cancleclass.vo.*;
import com.todod.education.module.study.dal.dataobject.cancleclass.CancleClassDO;
import com.todod.education.module.study.service.cancleclass.CancleClassService;@Tag(name = "管理后台 - 消课记录")
@RestController
@RequestMapping("/study/cancle-class")
@Validated
public class CancleClassController {@Resourceprivate CancleClassService cancleClassService;@PostMapping("/create")@Operation(summary = "创建消课记录")@PreAuthorize("@ss.hasPermission('study:cancle-class:create')")public CommonResult<Long> createCancleClass(@Valid @RequestBody CancleClassSaveReqVO createReqVO) {return success(cancleClassService.createCancleClass(createReqVO));}@PutMapping("/update")@Operation(summary = "更新消课记录")@PreAuthorize("@ss.hasPermission('study:cancle-class:update')")public CommonResult<Boolean> updateCancleClass(@Valid @RequestBody CancleClassSaveReqVO updateReqVO) {cancleClassService.updateCancleClass(updateReqVO);return success(true);}@DeleteMapping("/delete")@Operation(summary = "删除消课记录")@Parameter(name = "id", description = "编号", required = true)@PreAuthorize("@ss.hasPermission('study:cancle-class:delete')")public CommonResult<Boolean> deleteCancleClass(@RequestParam("id") Long id) {cancleClassService.deleteCancleClass(id);return success(true);}@GetMapping("/get")@Operation(summary = "获得消课记录")@Parameter(name = "id", description = "编号", required = true, example = "1024")@PreAuthorize("@ss.hasPermission('study:cancle-class:query')")public CommonResult<CancleClassRespVO> getCancleClass(@RequestParam("id") Long id) {CancleClassDO cancleClass = cancleClassService.getCancleClass(id);return success(BeanUtils.toBean(cancleClass, CancleClassRespVO.class));}@GetMapping("/findByIds")public List<CancleClassDO> findUsersByIds(@RequestParam Long id) {return cancleClassService.selectCheck(id);}@GetMapping("/findDetail")public List<CancleClassDO> findDetail(@RequestParam Long id) {return cancleClassService.selectDetail(id);}@GetMapping("/get2")@Operation(summary = "获得消课记录2")@Parameter(name = "id", description = "编号", required = true, example = "1024")@PreAuthorize("@ss.hasPermission('study:cancle-class:query')")public CommonResult<CancleClassRespVO> getCancleClass2(@RequestParam("id") Long id) {CancleClassDO cancleClass = cancleClassService.getCancleClass2(id);return success(BeanUtils.toBean(cancleClass, CancleClassRespVO.class));}@GetMapping("/page")@Operation(summary = "获得消课记录分页")@PreAuthorize("@ss.hasPermission('study:cancle-class:query')")public CommonResult<PageResult<CancleClassRespVO>> getCancleClassPage(@Valid CancleClassPageReqVO pageReqVO) {PageResult<CancleClassDO> pageResult = cancleClassService.getCancleClassPage(pageReqVO);return success(BeanUtils.toBean(pageResult, CancleClassRespVO.class));}@GetMapping("/page2")@Operation(summary = "获得消课记录分页2")@PreAuthorize("@ss.hasPermission('study:cancle-class:query')")public CommonResult<PageResult<CancleClassRespVO>> getCancleClassPage2(@Valid CancleClassPageReqVO pageReqVO) {PageResult<CancleClassDO> pageResult = cancleClassService.getCancleClassPage2(pageReqVO);return success(BeanUtils.toBean(pageResult, CancleClassRespVO.class));}@GetMapping("/export-excel")@Operation(summary = "导出消课记录 Excel")@PreAuthorize("@ss.hasPermission('study:cancle-class:export')")@ApiAccessLog(operateType = EXPORT)public void exportCancleClassExcel(@Valid CancleClassPageReqVO pageReqVO,HttpServletResponse response) throws IOException {pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);List<CancleClassDO> list = cancleClassService.getCancleClassPage(pageReqVO).getList();// 导出 ExcelExcelUtils.write(response, "消课记录.xls", "数据", CancleClassRespVO.class,BeanUtils.toBean(list, CancleClassRespVO.class));}}
主要看create新增方法,插入主表子表有这一个新增方法即可
CancleClassSaveReqVO:
package com.todod.education.module.study.controller.admin.cancleclass.vo;import com.todod.education.module.study.dal.dataobject.cancleclass.CancleClassInfoDO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import jakarta.validation.constraints.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;@Schema(description = "管理后台 - 消课记录新增/修改 Request VO")
@Data
public class CancleClassSaveReqVO {@Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "4886")private Long id;@Schema(description = "学员id", requiredMode = Schema.RequiredMode.REQUIRED, example = "4886")private List<CancleClassInfoDO> studentId;@Schema(description = "课程id", requiredMode = Schema.RequiredMode.REQUIRED, example = "4886")private Long courseId;@Schema(description = "班级id", requiredMode = Schema.RequiredMode.REQUIRED, example = "4886")private Long classId;@Schema(description = "上课时间")private LocalDateTime classTime;@Schema(description = "消课人")private String cancelClassPerson;@Schema(description = "消课时间")private LocalDateTime cancelClassTime;@Schema(description = "实到人数")private Integer arrivedNum;@Schema(description = "应到人数")private Integer arrivingNum;@Schema(description = "点名操作人员")private String rollCallPerson;@Schema(description = "点名时间")private LocalDateTime rollCallTime;@Schema(description = "操作人", example = "王五")private String operaName;@Schema(description = "操作时间")private LocalDateTime operaTime;@Schema(description = "操作类型", example = "2")private String operaType;@Schema(description = "操作说明")private String operaExplain;}
CancleClassRespVO:
package com.todod.education.module.study.controller.admin.cancleclass.vo;import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;import java.sql.Time;
import java.time.LocalTime;
import java.util.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;@Schema(description = "管理后台 - 消课记录 Response VO")
@Data
@ExcelIgnoreUnannotated
public class CancleClassRespVO {@Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "18505")private Long id;@Schema(description = "学员id", requiredMode = Schema.RequiredMode.REQUIRED, example = "18505")private Long studentId;@Schema(description = "班级id", requiredMode = Schema.RequiredMode.REQUIRED, example = "18505")private Long classId;@Schema(description = "课程id", requiredMode = Schema.RequiredMode.REQUIRED, example = "18505")private Long courseId;@Schema(description = "学员姓名", example = "芋艿")private String stsStudentName;@Schema(description = "手机号")private String stsPhone;@Schema(description = "班级名称", example = "李四")@ExcelProperty("班级名称")private String className;@Schema(description = "班级类型", example = "1")@ExcelProperty("班级类型")private String classType;@Schema(description = "所报课程")@ExcelProperty("所报课程")private String courseNames;@Schema(description = "所报课程")@ExcelProperty("所报课程")private String courseName;@Schema(description = "上课时间")private Time firstClassStartTime;@Schema(description = "上课日期")private Date firstClassDate;@Schema(description = "授课教师")@ExcelProperty("授课教师")private String teacherNames;@Schema(description = "授课教师")@ExcelProperty("授课教师")private String teacherName;@Schema(description = "消课人")@ExcelProperty("消课人")private String cancelClassPerson;@Schema(description = "消课时间")@ExcelProperty("消课时间")private LocalDateTime cancelClassTime;@Schema(description = "创建时间")@ExcelProperty("创建时间")private LocalDateTime createTime;@Schema(description = "操作人", example = "王五")private String operaName;@Schema(description = "操作时间")private LocalDateTime operaTime;@Schema(description = "操作类型", example = "2")private String operaType;@Schema(description = "操作说明")private String operaExplain;@Schema(description = "实到人数")private Integer arrivedNum;@Schema(description = "应到人数")private Integer arrivingNum;@Schema(description = "点名操作人员")private String rollCallPerson;@Schema(description = "点名时间")private LocalDateTime rollCallTime;
}
CancleClassPageReqVO:
package com.todod.education.module.study.controller.admin.cancleclass.vo;import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import com.todod.education.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;import static com.todod.education.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;@Schema(description = "管理后台 - 消课记录分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CancleClassPageReqVO extends PageParam {@Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "18505")private Long id;@Schema(description = "班级名称", example = "李四")private String className;@Schema(description = "上课时间")@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)private LocalDateTime[] classTime;@Schema(description = "消课时间")@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)private LocalDateTime[] cancelClassTime;@Schema(description = "创建时间")@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)private LocalDateTime[] createTime;@Schema(description = "所报课程", example = "李四")private String courseName;@Schema(description = "学员姓名")private String stsStudentName;@Schema(description = "手机号")private String stsPhone;
}
Mapper:
package com.todod.education.module.study.dal.mysql.cancleclass;import java.util.*;import com.baomidou.mybatisplus.core.metadata.IPage;
import com.todod.education.framework.common.pojo.PageResult;
import com.todod.education.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.todod.education.framework.mybatis.core.mapper.BaseMapperX;
import com.todod.education.module.study.controller.admin.entranceexam.vo.EntranceExamPageReqVO;
import com.todod.education.module.study.dal.dataobject.cancleclass.CancleClassDO;
import com.todod.education.module.study.dal.dataobject.entranceexam.EntranceExamDO;
import org.apache.ibatis.annotations.Mapper;
import com.todod.education.module.study.controller.admin.cancleclass.vo.*;
import org.apache.ibatis.annotations.Param;/*** 消课记录 Mapper** @author 平台管理员*/
@Mapper
public interface CancleClassMapper extends BaseMapperX<CancleClassDO> {default PageResult<CancleClassDO> selectPage(CancleClassPageReqVO reqVO) {return selectPage(reqVO, new LambdaQueryWrapperX<CancleClassDO>().likeIfPresent(CancleClassDO::getClassName, reqVO.getClassName()).betweenIfPresent(CancleClassDO::getCancelClassTime, reqVO.getCancelClassTime()).betweenIfPresent(CancleClassDO::getCreateTime, reqVO.getCreateTime()).orderByDesc(CancleClassDO::getId));}IPage<CancleClassDO> fetchPageResults(IPage<CancleClassDO> page, @Param("queryEntry") CancleClassPageReqVO pageReqVO);List<CancleClassDO> selectCheck(@Param("id") Long id);List<CancleClassDO> selectDetail(@Param("id") Long id);}
Service:
package com.todod.education.module.study.service.cancleclass;import java.util.*;
import jakarta.validation.*;
import com.todod.education.module.study.controller.admin.cancleclass.vo.*;
import com.todod.education.module.study.dal.dataobject.cancleclass.CancleClassDO;
import com.todod.education.framework.common.pojo.PageResult;
import com.todod.education.framework.common.pojo.PageParam;/*** 消课记录 Service 接口** @author 平台管理员*/
public interface CancleClassService {/*** 创建消课记录** @param createReqVO 创建信息* @return 编号*/Long createCancleClass(@Valid CancleClassSaveReqVO createReqVO);/*** 更新消课记录** @param updateReqVO 更新信息*/void updateCancleClass(@Valid CancleClassSaveReqVO updateReqVO);/*** 删除消课记录** @param id 编号*/void deleteCancleClass(Long id);/*** 获得消课记录** @param id 编号* @return 消课记录*/CancleClassDO getCancleClass(Long id);/*** 获得消课记录** @param id 编号* @return 消课记录*/CancleClassDO getCancleClass2(Long id);/*** 获得消课记录分页** @param pageReqVO 分页查询* @return 消课记录分页*/PageResult<CancleClassDO> getCancleClassPage(CancleClassPageReqVO pageReqVO);/*** 获得消课记录分页2** @param pageReqVO 分页查询* @return 消课记录分页*/PageResult<CancleClassDO> getCancleClassPage2(CancleClassPageReqVO pageReqVO);List<CancleClassDO> selectCheck(Long id);List<CancleClassDO> selectDetail(Long id);}
实现类:
package com.todod.education.module.study.service.cancleclass;import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mzt.logapi.context.LogRecordContext;
import com.mzt.logapi.service.impl.DiffParseFunction;
import com.mzt.logapi.starter.annotation.LogRecord;
import com.todod.education.module.study.controller.admin.monthexam.vo.MonthExamPageReqVO;
import com.todod.education.module.study.controller.admin.plan.vo.PlanSaveReqVO;
import com.todod.education.module.study.dal.dataobject.cancleclass.CancleClassInfoDO;
import com.todod.education.module.study.dal.dataobject.monthexam.MonthExamDO;
import com.todod.education.module.study.dal.dataobject.plan.PlanDO;
import com.todod.education.module.study.dal.mysql.cancleclass.CancleClassInfoMapper;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;import java.util.*;
import com.todod.education.module.study.controller.admin.cancleclass.vo.*;
import com.todod.education.module.study.dal.dataobject.cancleclass.CancleClassDO;
import com.todod.education.framework.common.pojo.PageResult;
import com.todod.education.framework.common.pojo.PageParam;
import com.todod.education.framework.common.util.object.BeanUtils;import com.todod.education.module.study.dal.mysql.cancleclass.CancleClassMapper;import static com.todod.education.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.todod.education.module.study.enums.ErrorCodeConstants.*;
import static com.todod.education.module.system.enums.LogRecordConstants.*;/*** 消课记录 Service 实现类** @author 平台管理员*/
@Service
@Validated
public class CancleClassServiceImpl implements CancleClassService {@Resourceprivate CancleClassMapper cancleClassMapper;@Resourceprivate CancleClassInfoMapper cancleClassInfoMapper;@Override@LogRecord(type = STUDY_CANCLE_CLASS_TYPE, subType = STUDY_CANCLE_CLASS_SUB_TYPE, bizNo = "{{#cancleClass.id}}",success = STUDY_CANCLE_CLASS_CREATE_SUCCESS)public Long createCancleClass(CancleClassSaveReqVO createReqVO) {if(createReqVO.getStudentId().size() == 0){throw exception(CANCLE_CLASS_NOT_EXISTS);}// 插入CancleClassDO cancleClass = BeanUtils.toBean(createReqVO, CancleClassDO.class);cancleClassMapper.insert(cancleClass);List<CancleClassInfoDO> studentIds = createReqVO.getStudentId();for (CancleClassInfoDO studentId : studentIds) {CancleClassInfoDO cancleClassInfoDO = new CancleClassInfoDO();cancleClassInfoDO.setStudentId(studentId.getStudentId());cancleClassInfoDO.setStudentName(studentId.getStudentName());cancleClassInfoDO.setStudentPhone(studentId.getStudentPhone());cancleClassInfoDO.setClassType(studentId.getClassType());cancleClassInfoDO.setClassName(studentId.getClassName());cancleClassInfoDO.setCourseName(studentId.getCourseName());cancleClassInfoDO.setTeacherName(studentId.getTeacherName());cancleClassInfoDO.setClassStartTime(studentId.getClassStartTime());cancleClassInfoDO.setId(studentId.getId());cancleClassInfoMapper.insert(cancleClassInfoDO);}// 3. 记录操作日志上下文LogRecordContext.putVariable("cancleClass", cancleClass);return cancleClass.getId();}// @Override
// @LogRecord(type = STUDY_CANCLE_CLASS_TYPE, subType = STUDY_CANCLE_CLASS_SUB_TYPE, bizNo = "{{#cancleClass.id}}",
// success = STUDY_CANCLE_CLASS_CREATE_SUCCESS)
// public Long createCancleClass(CancleClassSaveReqVO createReqVO) {
// // 插入
// CancleClassDO cancleClass = BeanUtils.toBean(createReqVO, CancleClassDO.class);
// cancleClassMapper.insert(cancleClass);
//
// // 3. 记录操作日志上下文
// LogRecordContext.putVariable("cancleClass", cancleClass);
//
// // 返回
// return cancleClass.getId();
// }@Override@LogRecord(type = STUDY_PLAN_TYPE, subType = STUDY_CANCLE_CLASS_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}",success = STUDY_CANCLE_CLASS_UPDATE_SUCCESS)public void updateCancleClass(CancleClassSaveReqVO updateReqVO) {// 校验存在validateCancleClassExists(updateReqVO.getId());CancleClassDO oldCancleClassDO = cancleClassMapper.selectById(updateReqVO.getId());// 更新CancleClassDO updateObj = BeanUtils.toBean(updateReqVO, CancleClassDO.class);cancleClassMapper.updateById(updateObj);// 3. 记录操作日志上下文LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldCancleClassDO, PlanSaveReqVO.class));LogRecordContext.putVariable("cancleClass", oldCancleClassDO);}@Override@LogRecord(type = STUDY_PLAN_TYPE, subType = STUDY_CANCLE_CLASS_DELETE_SUB_TYPE, bizNo = "{{#id}}",success = STUDY_CANCLE_CLASS_DELETE_SUCCESS)public void deleteCancleClass(Long id) {// 校验存在validateCancleClassExists(id);CancleClassDO oldCancleClassDO = cancleClassMapper.selectById(id);// 删除cancleClassMapper.deleteById(id);// 3. 记录操作日志上下文LogRecordContext.putVariable("cancleClass", oldCancleClassDO);}private void validateCancleClassExists(Long id) {if (cancleClassMapper.selectById(id) == null) {throw exception(CANCLE_CLASS_NOT_EXISTS);}}@Overridepublic CancleClassDO getCancleClass(Long id) {return cancleClassMapper.selectById(id);}@Overridepublic CancleClassDO getCancleClass2(Long id) {return cancleClassMapper.selectById(id);}@Overridepublic PageResult<CancleClassDO> getCancleClassPage(CancleClassPageReqVO pageReqVO) {return cancleClassMapper.selectPage(pageReqVO);}@Overridepublic PageResult<CancleClassDO> getCancleClassPage2(CancleClassPageReqVO pageReqVO) {IPage<CancleClassDO> page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());cancleClassMapper.fetchPageResults(page, pageReqVO);return new PageResult<>(page.getRecords(), page.getTotal());}@Overridepublic List<CancleClassDO> selectCheck(Long id) {return cancleClassMapper.selectCheck(id);}@Overridepublic List<CancleClassDO> selectDetail(Long id) {return cancleClassMapper.selectDetail(id);}}
XML文件:
<?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="com.todod.education.module.study.dal.mysql.cancleclass.CancleClassMapper"><select id="fetchPageResults" resultType="com.todod.education.module.study.dal.dataobject.cancleclass.CancleClassDO">SELECT tcm.class_name,tcm.id AS class_id,tcm.class_type,tcmc.teacherNames,tcmc.courseNames,tcms.students,FIRST_VALUE(stt.class_start_time) OVER (PARTITION BY tcm.id ORDER BY stt.class_date) AS first_class_start_time,FIRST_VALUE(stt.class_date) OVER (PARTITION BY tcm.id ORDER BY stt.class_date) AS first_class_start_dateFROM teach_class_manage tcmINNER JOIN (SELECT tcmc.class_id,string_agg(htm.teacher_name, ',') AS teacherNames,string_agg(tcm.course_name, ',') AS courseNamesFROM teach_class_manage_course tcmcINNER JOIN hr_teacher_manage htm ON htm."id" = tcmc.teacher_idINNER JOIN teach_course_manage tcm ON tcm."id" = tcmc.course_idGROUP BY tcmc.class_id) tcmc ON tcm."id" = tcmc.class_idLEFT JOIN (SELECT tcms.class_id,COALESCE(COUNT(*), 0) AS studentsFROM teach_class_manage_student tcmsGROUP BY tcms.class_id) tcms ON tcm."id" = tcms.class_idLEFT JOIN study_time_table stt ON stt.study_course_id = ANY(ARRAY(SELECT tcmc2.course_id FROM teach_class_manage_course tcmc2 WHERE tcmc2.class_id = tcm.id))WHERE 1 = 1 AND tcm.deleted = 0<if test=" queryEntry.stsStudentName != null and queryEntry.stsStudentName != '' and queryEntry.stsStudentName != 'null' ">AND ss.sts_student_name like '%${queryEntry.stsStudentName}'</if>ORDER BYtcm.create_time desc</select><select id="selectCheck" resultType="com.todod.education.module.study.dal.dataobject.cancleclass.CancleClassDO">SELECTtcm.class_name,tcm.class_type,ss.sts_student_name,FIRST_VALUE(stt.class_start_time) OVER (PARTITION BY tcm.id ORDER BY stt.class_date) AS first_class_start_time,
-- FIRST_VALUE(stt.class_date) OVER (PARTITION BY tcm.id ORDER BY stt.class_date) AS first_class_start_datess.sts_phone,tcs.student_id,tcmc.course_id,tcm2.course_name,htm.teacher_nameFROMteach_class_manage tcmJOIN teach_class_manage_student tcs ON tcm.id = tcs.class_idJOIN study_student ss ON tcs.student_id = ss.idJOIN teach_class_manage_course tcmc ON tcm.id = tcmc.class_idJOIN teach_course_manage tcm2 ON tcmc.course_id = tcm2.idJOIN hr_teacher_manage htm ON tcmc.teacher_id = htm.idLEFT JOIN study_time_table stt ON stt.study_course_id = ANY(ARRAY(SELECT tcmc2.course_id FROM teach_class_manage_course tcmc2 WHERE tcmc2.class_id = tcm.id))WHEREtcm.id = #{id}ORDER BYtcs.student_id, tcmc.course_id;</select><select id="selectDetail" resultType="com.todod.education.module.study.dal.dataobject.cancleclass.CancleClassDO">SELECTtcm.class_name,tcm.id AS class_id,tcm.class_type,tcmc.teacherNames,tcmc.courseNames,tcms.students,FIRST_VALUE(stt.class_start_time) OVER (PARTITION BY tcm.id ORDER BY stt.class_date) AS first_class_start_time,FIRST_VALUE(stt.class_date) OVER (PARTITION BY tcm.id ORDER BY stt.class_date) AS first_class_start_dateFROMteach_class_manage tcmINNER JOIN (SELECTtcmc.class_id,string_agg(htm.teacher_name, ',') AS teacherNames,string_agg(tcm.course_name, ',') AS courseNamesFROMteach_class_manage_course tcmcINNER JOIN hr_teacher_manage htm ON htm.id = tcmc.teacher_idINNER JOIN teach_course_manage tcm ON tcm.id = tcmc.course_idGROUP BYtcmc.class_id) tcmc ON tcm.id = tcmc.class_idLEFT JOIN (SELECTtcms.class_id,COALESCE(COUNT(*), 0) AS studentsFROMteach_class_manage_student tcmsGROUP BYtcms.class_id) tcms ON tcm.id = tcms.class_idLEFT JOIN study_time_table stt ON stt.study_course_id IN (SELECT tcmc2.course_id FROM teach_class_manage_course tcmc2 WHERE tcmc2.class_id = tcm.id)WHEREtcm.deleted = 0AND tcm.id = 9 -- 替换为实际的参数或变量ORDER BYtcm.create_time DESC;</select></mapper>
从表
CancleClassInfoSaveReqVO:
package com.todod.education.module.study.controller.admin.cancleclass.vo;import com.alibaba.excel.annotation.ExcelProperty;
import com.todod.education.module.study.dal.dataobject.cancleclass.CancleClassInfoDO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;import java.sql.Time;
import java.time.LocalDateTime;
import java.util.List;@Schema(description = "管理后台 - 消课记录新增/修改 Request VO")
@Data
public class CancleClassInfoSaveReqVO {@Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "4886")private Long id;@Schema(description = "学员id", example = "21490")private List<CancleClassInfoDO> studentId;@Schema(description = "学员姓名", example = "芋艿")private String studentName;@Schema(description = "手机号")private String studentPhone;@Schema(description = "班级名称", example = "李四")@ExcelProperty("班级名称")private String className;@Schema(description = "班级类型", example = "1")@ExcelProperty("班级类型")private String classType;@Schema(description = "所报课程")@ExcelProperty("所报课程")private String courseName;@Schema(description = "上课时间")@ExcelProperty("上课时间")private Time classStartTime;@Schema(description = "授课教师")@ExcelProperty("授课教师")private String teacherName;@Schema(description = "操作人", example = "王五")private String operaName;@Schema(description = "操作时间")private LocalDateTime operaTime;@Schema(description = "操作类型", example = "2")private String operaType;@Schema(description = "操作说明")private String operaExplain;}
关键
@Schema(description = "学员id", example = "21490")
private List<CancleClassInfoDO> studentId;
要把学员id定义成一个list对象集合,用来往子表批量插入学生的数据
CancleClassInfoRespVO:
package com.todod.education.module.study.controller.admin.cancleclass.vo;import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;import java.sql.Time;
import java.time.LocalDateTime;@Schema(description = "管理后台 - 消课记录 Response VO")
@Data
@ExcelIgnoreUnannotated
public class CancleClassInfoRespVO {@Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "18505")private Long id;@Schema(description = "学员姓名", example = "芋艿")private String studentName;@Schema(description = "手机号")private String studentPhone;@Schema(description = "班级名称", example = "李四")@ExcelProperty("班级名称")private String className;@Schema(description = "班级类型", example = "1")@ExcelProperty("班级类型")private String classType;@Schema(description = "所报课程")@ExcelProperty("所报课程")private String courseName;@Schema(description = "上课时间")@ExcelProperty("上课时间")private Time classStartTime;@Schema(description = "授课教师")@ExcelProperty("授课教师")private String teacherName;@Schema(description = "创建时间")@ExcelProperty("创建时间")private LocalDateTime createTime;@Schema(description = "操作人", example = "王五")private String operaName;@Schema(description = "操作时间")private LocalDateTime operaTime;@Schema(description = "操作类型", example = "2")private String operaType;@Schema(description = "操作说明")private String operaExplain;}
实现类:
package com.todod.education.module.study.dal.dataobject.cancleclass;import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.todod.education.framework.mybatis.core.dataobject.BaseDO;
import lombok.*;import java.sql.Time;
import java.time.LocalDateTime;/*** 消课记录 DO** @author 平台管理员*/
@TableName("study_cancle_class_info")
@KeySequence("study_cancle_class_info_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CancleClassInfoDO extends BaseDO {/*** 主键id*/@TableIdprivate Long id;private Long studentId;/*** 学员姓名*/private String studentName;/*** 手机号*/private String studentPhone;/*** 班级名称*/private String className;/*** 班级类型*/private String classType;/*** 所报课程*/private String courseName;/*** 授课教师*/private String teacherName;/*** 上课时间*/private Time classStartTime;/*** 操作人*/private String operaName;/*** 操作时间*/private LocalDateTime operaTime;/*** 操作类型*/private String operaType;/*** 操作说明*/private String operaExplain;}
关键:
@Override@LogRecord(type = STUDY_CANCLE_CLASS_TYPE, subType = STUDY_CANCLE_CLASS_SUB_TYPE, bizNo = "{{#cancleClass.id}}",success = STUDY_CANCLE_CLASS_CREATE_SUCCESS)public Long createCancleClass(CancleClassSaveReqVO createReqVO) {if(createReqVO.getStudentId().size() == 0){throw exception(CANCLE_CLASS_NOT_EXISTS);}// 插入CancleClassDO cancleClass = BeanUtils.toBean(createReqVO, CancleClassDO.class);cancleClassMapper.insert(cancleClass);List<CancleClassInfoDO> studentIds = createReqVO.getStudentId();for (CancleClassInfoDO studentId : studentIds) {CancleClassInfoDO cancleClassInfoDO = new CancleClassInfoDO();cancleClassInfoDO.setStudentId(studentId.getStudentId());cancleClassInfoDO.setStudentName(studentId.getStudentName());cancleClassInfoDO.setStudentPhone(studentId.getStudentPhone());cancleClassInfoDO.setClassType(studentId.getClassType());cancleClassInfoDO.setClassName(studentId.getClassName());cancleClassInfoDO.setCourseName(studentId.getCourseName());cancleClassInfoDO.setTeacherName(studentId.getTeacherName());cancleClassInfoDO.setClassStartTime(studentId.getClassStartTime());cancleClassInfoDO.setId(studentId.getId());cancleClassInfoMapper.insert(cancleClassInfoDO);}// 3. 记录操作日志上下文LogRecordContext.putVariable("cancleClass", cancleClass);return cancleClass.getId();}
主表插入:
// 插入 CancleClassDO cancleClass = BeanUtils.toBean(createReqVO, CancleClassDO.class); cancleClassMapper.insert(cancleClass);
直接用Mapper以及mybatis-plus插入到数据库里面
子表插入:
List<CancleClassInfoDO> studentIds = createReqVO.getStudentId(); for (CancleClassInfoDO studentId : studentIds) {CancleClassInfoDO cancleClassInfoDO = new CancleClassInfoDO();cancleClassInfoDO.setStudentId(studentId.getStudentId());cancleClassInfoDO.setStudentName(studentId.getStudentName());cancleClassInfoDO.setStudentPhone(studentId.getStudentPhone());cancleClassInfoDO.setClassType(studentId.getClassType());cancleClassInfoDO.setClassName(studentId.getClassName());cancleClassInfoDO.setCourseName(studentId.getCourseName());cancleClassInfoDO.setTeacherName(studentId.getTeacherName());cancleClassInfoDO.setClassStartTime(studentId.getClassStartTime());cancleClassInfoDO.setId(studentId.getId());cancleClassInfoMapper.insert(cancleClassInfoDO); }
List<CancleClassInfoDO> studentIds = createReqVO.getStudentId();
遍历前端传过来的studentId,往子表里插入数据
for (CancleClassInfoDO studentId : studentIds) {
CancleClassInfoDO cancleClassInfoDO = new CancleClassInfoDO();
cancleClassInfoDO.setStudentId(studentId.getStudentId());
cancleClassInfoDO.setStudentName(studentId.getStudentName());
cancleClassInfoDO.setStudentPhone(studentId.getStudentPhone());
cancleClassInfoDO.setClassType(studentId.getClassType());
cancleClassInfoDO.setClassName(studentId.getClassName());
cancleClassInfoDO.setCourseName(studentId.getCourseName());
cancleClassInfoDO.setTeacherName(studentId.getTeacherName());
cancleClassInfoDO.setClassStartTime(studentId.getClassStartTime());
cancleClassInfoDO.setId(studentId.getId());
cancleClassInfoMapper.insert(cancleClassInfoDO);
}
CancleClassInfoDO cancleClassInfoDO = new CancleClassInfoDO();
新建一个CancleClassInfoDO 实体类对象。
cancleClassInfoDO.setStudentId(studentId.getStudentId());
cancleClassInfoDO.setStudentName(studentId.getStudentName());
cancleClassInfoDO.setStudentPhone(studentId.getStudentPhone());
cancleClassInfoDO.setClassType(studentId.getClassType());
cancleClassInfoDO.setClassName(studentId.getClassName());
cancleClassInfoDO.setCourseName(studentId.getCourseName());
cancleClassInfoDO.setTeacherName(studentId.getTeacherName());
cancleClassInfoDO.setClassStartTime(studentId.getClassStartTime());
cancleClassInfoDO.setId(studentId.getId());
往数据库插入数据
cancleClassInfoMapper.insert(cancleClassInfoDO);