后端代码

This commit is contained in:
liumengyu
2026-08-24 17:48:55 +08:00
parent e0485f7366
commit aa4145fd33
419 changed files with 3684 additions and 53031 deletions
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourcePerFileMappings">
<file url="file://$PROJECT_DIR$/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/mapper/SSDKSQMapper.xml" value="a3a7e92a-b8da-4229-8b83-5db11f9db9a9" />
</component>
</project>
@@ -290,19 +290,21 @@ public class CourseRunningController {
/** /**
* 分页查询调课申请列表。 * 分页查询调课申请列表。
* <p>
* 根据查询条件分页查询调课申请列表,支持按实施_课程表编号、申请教员、
* 年度、审批状态、查收状态、删除状态、申请日期范围筛选。
* </p>
*
* @param query 查询参数(包含分页信息和筛选条件)
* @return 分页调课申请列表
*/ */
@GetMapping("/adjust/list") @GetMapping("/adjust/list")
public Result<PageResult<ScheduleAdjustApplyVO>> queryScheduleAdjustList(ScheduleAdjustQueryDTO query) { public Result<PageResult<ScheduleAdjustApplyVO>> queryScheduleAdjustList(ScheduleAdjustQueryDTO query) {
return Result.success(courseRunningImportService.queryScheduleAdjustList(query)); return Result.success(courseRunningImportService.queryScheduleAdjustList(query));
} }
/**
* 查询当前教员可供调课的课次(学员队任务表 + 课表 + 课程表)。
*/
@GetMapping("/adjust/lessons")
public Result<List<AdjustableLessonVO>> listAdjustableLessons(
@RequestParam(value = "nd", required = false) Integer nd) {
return Result.success(courseRunningImportService.listAdjustableLessons(nd));
}
/** /**
* 查询单个调课申请的完整详情。 * 查询单个调课申请的完整详情。
* <p> * <p>
@@ -1,20 +1,41 @@
package com.roomroot.web.controller.jwgl; package com.roomroot.web.controller.jwgl;
import com.roomroot.jwgl.dto.faculty.AddTeacherDTO; import com.roomroot.jwgl.dto.faculty.AddTeacherDTO;
import com.roomroot.jwgl.dto.jys.ElectiveCourseBatchDTO;
import com.roomroot.jwgl.dto.jys.ElectiveCourseQuery;
import com.roomroot.jwgl.dto.jys.ElectiveCourseSaveDTO;
import com.roomroot.jwgl.dto.jys.TeachingTaskQuery;
import com.roomroot.jwgl.dto.jys.TeachingTaskSaveDTO;
import com.roomroot.jwgl.entity.JYB; import com.roomroot.jwgl.entity.JYB;
import com.roomroot.jwgl.entity.JYSB; import com.roomroot.jwgl.entity.JYSB;
import com.roomroot.jwgl.entity.JYSX; import com.roomroot.jwgl.entity.JYSX;
import com.roomroot.jwgl.entity.KB; import com.roomroot.jwgl.entity.KB;
import com.roomroot.jwgl.service.ElectiveCourseService;
import com.roomroot.jwgl.service.FacultyService; import com.roomroot.jwgl.service.FacultyService;
import com.roomroot.jwgl.service.KBService; import com.roomroot.jwgl.service.KBService;
import com.roomroot.jwgl.service.TeachingTaskManageService;
import com.roomroot.jwgl.unit.PageQuery; import com.roomroot.jwgl.unit.PageQuery;
import com.roomroot.jwgl.unit.PageResult; import com.roomroot.jwgl.unit.PageResult;
import com.roomroot.jwgl.unit.Result; import com.roomroot.jwgl.unit.Result;
import com.roomroot.jwgl.vo.faculty.TeacherListVO; import com.roomroot.jwgl.vo.faculty.TeacherListVO;
import com.roomroot.jwgl.vo.jys.ElectiveCourseVO;
import com.roomroot.jwgl.vo.jys.TeachingOfficeBookCourseVO;
import com.roomroot.jwgl.vo.jys.TeachingOfficeBookVO;
import com.roomroot.jwgl.vo.jys.TeachingTaskDetailVO;
import com.roomroot.jwgl.vo.jys.TeachingTaskSquadVO;
import com.roomroot.jwgl.vo.jys.TeachingTaskVO;
import com.roomroot.jwgl.unit.PageQuery;
import com.roomroot.jwgl.unit.PageResult;
import com.roomroot.jwgl.unit.Result;
import com.roomroot.jwgl.vo.faculty.TeacherListVO;
import com.roomroot.jwgl.vo.jys.ElectiveCourseVO;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/** /**
* 教研室管理(教研室管理 * 教研室管理(教研室管理
* 教员管理 * 教员管理
@@ -32,6 +53,12 @@ public class JYSController {
@Resource @Resource
private KBService kbService; private KBService kbService;
@Resource
private ElectiveCourseService electiveCourseService;
@Resource
private TeachingTaskManageService teachingTaskManageService;
// ======================== 教研室管理 ======================== // ======================== 教研室管理 ========================
/** /**
@@ -303,4 +330,233 @@ public class JYSController {
cond.setJc(jc); cond.setJc(jc);
return Result.success(kbService.pageList(new PageQuery(pageNum, pageSize), cond)); return Result.success(kbService.pageList(new PageQuery(pageNum, pageSize), cond));
} }
// ======================== 选修课管理 ========================
/**
* 分页查询选修课。
* <p>
* 联查学员队任务表、学员队表、课表,课类型含“选修”。
* 支持按授课教员、课程科目名称、可选班次年级、选修班名称、选择课状态、培训层次筛选。
* </p>
*/
@GetMapping("/elective/list")
public Result<PageResult<ElectiveCourseVO>> listElective(
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "20") Integer pageSize,
@RequestParam(required = false) String jyxm,
@RequestParam(required = false) String kmc,
@RequestParam(required = false) String kxbcnj,
@RequestParam(required = false) String xxbmc,
@RequestParam(required = false) String xkzt,
@RequestParam(required = false) String pxcc) {
ElectiveCourseQuery cond = new ElectiveCourseQuery();
cond.setJyxm(jyxm);
cond.setKmc(kmc);
cond.setKxbcnj(kxbcnj);
cond.setXxbmc(xxbmc);
cond.setXkzt(xkzt);
cond.setPxcc(pxcc);
return Result.success(electiveCourseService.pageList(new PageQuery(pageNum, pageSize), cond));
}
/**
* 新建选修课。
*/
@PostMapping("/elective/add")
public Result<Void> addElective(@RequestBody ElectiveCourseSaveDTO dto) {
electiveCourseService.add(dto);
return Result.success();
}
/**
* 所选批量开放报名。
*/
@PostMapping("/elective/batch-open")
public Result<Integer> batchOpenElective(@RequestBody ElectiveCourseBatchDTO dto) {
int count = electiveCourseService.batchOpenRegistration(dto == null ? null : dto.getBhList());
return Result.success("已开放报名 " + count + " 条", count);
}
/**
* 所选批量取消开放报名。
*/
@PostMapping("/elective/batch-cancel-open")
public Result<Integer> batchCancelOpenElective(@RequestBody ElectiveCourseBatchDTO dto) {
int count = electiveCourseService.batchCancelOpenRegistration(dto == null ? null : dto.getBhList());
return Result.success("已取消开放报名 " + count + " 条", count);
}
/**
* 批量停止报名。
*/
@PostMapping("/elective/batch-stop")
public Result<Integer> batchStopElective(@RequestBody ElectiveCourseBatchDTO dto) {
int count = electiveCourseService.batchStopRegistration(dto == null ? null : dto.getBhList());
return Result.success("已停止报名 " + count + " 条", count);
}
/**
* 所选批量根据学员反向确定班次范围。
*/
@PostMapping("/elective/batch-reverse-range")
public Result<Integer> batchReverseRangeElective(@RequestBody ElectiveCourseBatchDTO dto) {
int count = electiveCourseService.batchReverseClassRange(dto == null ? null : dto.getBhList());
return Result.success("已根据学员反向确定班次范围 " + count + " 条", count);
}
/**
* 下载选修班列表。
*/
@GetMapping("/elective/export")
public void exportElective(
@RequestParam(required = false) String jyxm,
@RequestParam(required = false) String kmc,
@RequestParam(required = false) String kxbcnj,
@RequestParam(required = false) String xxbmc,
@RequestParam(required = false) String xkzt,
@RequestParam(required = false) String pxcc,
HttpServletResponse response) {
ElectiveCourseQuery cond = new ElectiveCourseQuery();
cond.setJyxm(jyxm);
cond.setKmc(kmc);
cond.setKxbcnj(kxbcnj);
cond.setXxbmc(xxbmc);
cond.setXkzt(xkzt);
cond.setPxcc(pxcc);
electiveCourseService.exportClassList(cond, response);
}
/**
* 下载选修班学员名单 Excel。
*/
@GetMapping("/elective/students/export-excel")
public void exportElectiveStudentExcel(@RequestParam("bhList") List<String> bhList,
HttpServletResponse response) {
electiveCourseService.exportStudentExcel(bhList, response);
}
/**
* 下载选修班学员名单 Word。
*/
@GetMapping("/elective/students/export-word")
public void exportElectiveStudentWord(@RequestParam("bhList") List<String> bhList,
HttpServletResponse response) {
electiveCourseService.exportStudentWord(bhList, response);
}
/**
* 上传选修课数据。
*/
@PostMapping("/elective/import")
public Result<Integer> importElective(@RequestParam("file") MultipartFile file) throws Exception {
int count = electiveCourseService.importData(file);
return Result.success("导入成功,共" + count + "条", count);
}
// ======================== 教学任务管理 ========================
/**
* 分页查询教学任务列表。
* <p>含教研室数、学员队数、合班前后课程任务数和学时。未传年度时按当前学期。</p>
*/
@GetMapping("/task/list")
public Result<PageResult<TeachingTaskVO>> listTask(
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "20") Integer pageSize,
@RequestParam(required = false) String rwmc,
@RequestParam(required = false) Integer nd,
@RequestParam(required = false) Integer xqdc,
@RequestParam(required = false) String zt) {
TeachingTaskQuery cond = new TeachingTaskQuery();
cond.setRwmc(rwmc);
cond.setNd(nd);
cond.setXqdc(xqdc);
cond.setZt(zt);
return Result.success(teachingTaskManageService.pageList(new PageQuery(pageNum, pageSize), cond));
}
/**
* 教学任务详情(含教研室任务书、学员队两个页签)。
*/
@GetMapping("/task/get")
public Result<TeachingTaskDetailVO> getTask(@RequestParam("bh") String bh) {
return Result.success(teachingTaskManageService.getDetail(bh));
}
/**
* 新增教学任务。
* <p>机关发布;关联学员队后按专业教学计划和课表归属教研室生成教研室任务书。</p>
*/
@PostMapping("/task/add")
public Result<Void> addTask(@RequestBody TeachingTaskSaveDTO dto) {
teachingTaskManageService.add(dto);
return Result.success();
}
/**
* 编辑教学任务。
*/
@PostMapping("/task/update")
public Result<Void> updateTask(@RequestBody TeachingTaskSaveDTO dto) {
teachingTaskManageService.update(dto);
return Result.success();
}
/**
* 删除教学任务(同时逻辑删除教研室任务书,并解除学员队关联)。
*/
@PostMapping("/task/delete")
public Result<Void> deleteTask(@RequestParam("bh") String bh) {
teachingTaskManageService.delete(bh);
return Result.success();
}
/**
* 发布教学任务,并同步发布关联的教研室任务书。
*/
@PostMapping("/task/publish")
public Result<Integer> publishTask(@RequestParam("bh") String bh) {
int count = teachingTaskManageService.publish(bh);
return Result.success("已发布,同步教研室任务书 " + count + " 份", count);
}
/**
* 教研室任务书列表。
*/
@GetMapping("/task/office-book/list")
public Result<List<TeachingOfficeBookVO>> listTaskOfficeBooks(@RequestParam("jxrwbh") String jxrwbh) {
return Result.success(teachingTaskManageService.listOfficeBooks(jxrwbh));
}
/**
* 教研室任务书详细(该教研室在本任务下的课程任务)。
*/
@GetMapping("/task/office-book/courses")
public Result<List<TeachingOfficeBookCourseVO>> listTaskOfficeBookCourses(
@RequestParam("jxrwbh") String jxrwbh,
@RequestParam("jysdh") String jysdh) {
return Result.success(teachingTaskManageService.listOfficeBookCourses(jxrwbh, jysdh));
}
/**
* 教学任务已关联学员队。
*/
@GetMapping("/task/squad/list")
public Result<List<TeachingTaskSquadVO>> listTaskSquads(@RequestParam("jxrwbh") String jxrwbh) {
return Result.success(teachingTaskManageService.listBoundSquads(jxrwbh));
}
/**
* 某学期可选学员队(未占用或占用当前任务)。年度、学期第次为空时取当前学期。
*/
@GetMapping("/task/squad/available")
public Result<List<TeachingTaskSquadVO>> listAvailableTaskSquads(
@RequestParam(required = false) Integer nd,
@RequestParam(required = false) Integer xqdc,
@RequestParam(required = false) String jxrwbh) {
return Result.success(teachingTaskManageService.listAvailableSquads(nd, xqdc, jxrwbh));
}
} }
@@ -1,8 +1,14 @@
package com.roomroot.web.controller.jwgl; package com.roomroot.web.controller.jwgl;
import com.roomroot.jwgl.dto.kcb.TimetableQuery;
import com.roomroot.jwgl.entity.KCB; import com.roomroot.jwgl.entity.KCB;
import com.roomroot.jwgl.service.KCBService; import com.roomroot.jwgl.service.KCBService;
import com.roomroot.jwgl.unit.PageQuery;
import com.roomroot.jwgl.unit.PageResult;
import com.roomroot.jwgl.unit.Result; import com.roomroot.jwgl.unit.Result;
import com.roomroot.jwgl.vo.kcb.ClassTimetableVO;
import com.roomroot.jwgl.vo.kcb.DailyWeeklyTimetableVO;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
@@ -69,4 +75,52 @@ public class KCBController {
public Result<List<KCB>> list() { public Result<List<KCB>> list() {
return Result.success(kcbService.list()); return Result.success(kcbService.list());
} }
/**
* 今日课表。未传年度时按当前时间取本学期,可按队别班次筛选。
*/
@GetMapping("/today/list")
public Result<List<DailyWeeklyTimetableVO>> listToday(TimetableQuery cond) {
return Result.success(kcbService.listToday(cond));
}
/**
* 本周课表(周一至周日)。未传年度时按当前时间取本学期,可按队别班次筛选。
*/
@GetMapping("/week/list")
public Result<List<DailyWeeklyTimetableVO>> listWeek(TimetableQuery cond) {
return Result.success(kcbService.listWeek(cond));
}
/**
* 班次课表。未传年度时按当前时间取本学期,可按队别班次筛选。
*/
@GetMapping("/class/list")
public Result<PageResult<ClassTimetableVO>> listClass(PageQuery query, TimetableQuery cond) {
return Result.success(kcbService.pageClassTimetable(query, cond));
}
/**
* 下载学期教学实施计划 Excel。
*/
@GetMapping("/class/export-plan")
public void exportSemesterPlan(TimetableQuery cond, HttpServletResponse response) {
kcbService.exportSemesterPlan(cond, response);
}
/**
* 下载学期成绩表 Excel。
*/
@GetMapping("/class/export-grades")
public void exportSemesterGrades(TimetableQuery cond, HttpServletResponse response) {
kcbService.exportSemesterGrades(cond, response);
}
/**
* 班次课程列表另存 Excel。
*/
@GetMapping("/class/export-courses")
public void exportClassCourses(TimetableQuery cond, HttpServletResponse response) {
kcbService.exportClassCourses(cond, response);
}
} }
@@ -25,6 +25,10 @@ public class SemesterController {
*/ */
@PostMapping("/add") @PostMapping("/add")
public Result<Void> add(@RequestBody XQ xq) { public Result<Void> add(@RequestBody XQ xq) {
if (semesterService.getById(xq.getNd()) != null) {
return Result.error(400, "该年度已存在,不能重复添加");
}
semesterService.add(xq); semesterService.add(xq);
return Result.success(); return Result.success();
} }
@@ -0,0 +1,34 @@
package com.roomroot.web.controller.jwtest;
import com.roomroot.jwgl.mapper.TestPkMapper;
import com.roomroot.jwgl.unit.Result;
import com.roomroot.jwgl.vo.jwtest.PkLessonVO;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 排课测试接口。
*/
@RestController
@RequestMapping("/jwtest/pk")
public class TestPkController {
@Resource
private TestPkMapper testPkMapper;
/**
* 全查排课记录,无筛选条件。
* <p>
* 回显:课堂名称、课程名称、教师名称、班级名称、教室名称、
* 上课日期、开始时间、结束时间、学年学期、周次、应到人数。
* </p>
*/
@GetMapping("/all")
public Result<List<PkLessonVO>> all() {
return Result.success(testPkMapper.selectAll());
}
}
@@ -100,7 +100,7 @@ public class SecurityConfig
.authorizeHttpRequests((requests) -> { .authorizeHttpRequests((requests) -> {
permitAllUrl.getUrls().forEach(url -> requests.requestMatchers(url).permitAll()); permitAllUrl.getUrls().forEach(url -> requests.requestMatchers(url).permitAll());
// 对于登录login 注册register 验证码captchaImage 允许匿名访问 // 对于登录login 注册register 验证码captchaImage 允许匿名访问
requests.requestMatchers("/login", "/register", "/captchaImage","/jys/teacher/list").permitAll() requests.requestMatchers("/login", "/register", "/captchaImage","/jwtest/pk/all").permitAll()
// 静态资源,可匿名访问 // 静态资源,可匿名访问
.requestMatchers(HttpMethod.GET, "/", "/*.html", "/**.html", "/**.css", "/**.js", "/profile/**").permitAll() .requestMatchers(HttpMethod.GET, "/", "/*.html", "/**.html", "/**.css", "/**.js", "/profile/**").permitAll()
.requestMatchers("/swagger-ui.html", "/v3/api-docs/**", "/swagger-ui/**", "/druid/**").permitAll() .requestMatchers("/swagger-ui.html", "/v3/api-docs/**", "/swagger-ui/**", "/druid/**").permitAll()
@@ -17,7 +17,7 @@ import java.util.List;
public class ScheduleAdjustApplyDTO { public class ScheduleAdjustApplyDTO {
/** /**
* 实施_课程表编号,必填,标识需要调整的课次。 * 实施_课程表编号,必填,对应实施_调课申请.实施_课程表编号。
*/ */
@NotBlank(message = "课次编号不能为空") @NotBlank(message = "课次编号不能为空")
@Size(max = 50, message = "课次编号不能超过50个字符") @Size(max = 50, message = "课次编号不能超过50个字符")
@@ -49,12 +49,35 @@ public class ScheduleAdjustApplyDTO {
private Integer nd; private Integer nd;
/** /**
* 申请教员编号,必填,标识提交申请的教员。 * 申请教员编号,教员提交时由服务端按登录人写入,前端可不传。
*/ */
@NotBlank(message = "申请教员编号不能为空")
@Size(max = 50, message = "申请教员编号不能超过50个字符") @Size(max = 50, message = "申请教员编号不能超过50个字符")
private String sqjybh; private String sqjybh;
/**
* 学员队任务表编号,由服务端根据实施课次反查,前端可不传。
*/
@Size(max = 50, message = "学员队任务编号不能超过50个字符")
private String xydrwbh;
/**
* 课表.课编号。
*/
@Size(max = 50, message = "课编号不能超过50个字符")
private String kbh;
/**
* 课程表编号。
*/
@Size(max = 50, message = "课程表编号不能超过50个字符")
private String kcbbh;
/**
* 拟调整教室编号。
*/
@Size(max = 50, message = "教室编号不能超过50个字符")
private String xjsbh;
/** /**
* 调课后教学内容,调整后的本节课教学主题或知识点。 * 调课后教学内容,调整后的本节课教学主题或知识点。
*/ */
@@ -41,14 +41,13 @@ public class ScheduleAdjustAuditDTO {
private String fhyj; private String fhyj;
/** /**
* 审批人编号,必填,标识审批人身份。 * 审批人编号,不传时由服务端取当前登录人。
*/ */
@NotBlank(message = "审批人编号不能为空")
@Size(max = 50, message = "审批人编号不能超过50个字符") @Size(max = 50, message = "审批人编号不能超过50个字符")
private String sprbh; private String sprbh;
/** /**
* 机关编号,机关审批时必填,标识审批机关。 * 机关编号,机关审批时可选。
*/ */
@Size(max = 50, message = "机关编号不能超过50个字符") @Size(max = 50, message = "机关编号不能超过50个字符")
private String jgbh; private String jgbh;
@@ -52,6 +52,21 @@ public class ScheduleAdjustQueryDTO extends PageQuery {
*/ */
private Integer sczt; private Integer sczt;
/**
* 教研室代号,教研室角色由服务端强制写入,前端不必传。
*/
private String jysdh;
/**
* 学员队任务表编号。
*/
private String xydrwbh;
/**
* 课编号。
*/
private String kbh;
/** /**
* 申请日期范围开始。 * 申请日期范围开始。
*/ */
@@ -0,0 +1,15 @@
package com.roomroot.jwgl.dto.jys;
import lombok.Data;
import java.util.List;
/**
* 选修课批量操作参数。
*/
@Data
public class ElectiveCourseBatchDTO {
/** 学员队任务编号列表 */
private List<String> bhList;
}
@@ -0,0 +1,62 @@
package com.roomroot.jwgl.dto.jys;
import com.roomroot.common.annotation.Excel;
import lombok.Data;
/**
* 选修课数据文件导入行。
*/
@Data
public class ElectiveCourseImportDTO {
@Excel(name = "授课教员")
private String jyxm;
@Excel(name = "课程科目名称")
private String kmc;
@Excel(name = "可选班次年级")
private String kxbcnj;
@Excel(name = "选修班名称")
private String xxbmc;
@Excel(name = "选择课状态")
private String xkzt;
@Excel(name = "培训层次")
private String pxcc;
@Excel(name = "教材")
private String jcmc;
@Excel(name = "教学场地")
private String jsmc;
@Excel(name = "计划学时")
private Integer jhxs;
@Excel(name = "运行学时")
private Integer yxxs;
@Excel(name = "学分")
private Float xf;
@Excel(name = "开课日期")
private String kkrq;
@Excel(name = "结课日期")
private String jkrq;
@Excel(name = "报名开始日期")
private String bmkssj;
@Excel(name = "报名结束日期")
private String bmjssj;
@Excel(name = "计划人数")
private Integer jhrs;
@Excel(name = "要求说明")
private String yqsm;
}
@@ -0,0 +1,33 @@
package com.roomroot.jwgl.dto.jys;
import lombok.Data;
import java.util.List;
/**
* 选修课管理查询条件。
*/
@Data
public class ElectiveCourseQuery {
/** 授课教员姓名(模糊) */
private String jyxm;
/** 课程科目名称(模糊) */
private String kmc;
/** 可选班次年级(模糊,匹配年级或可选队列班次) */
private String kxbcnj;
/** 选修班名称(模糊) */
private String xxbmc;
/** 选择课状态:拟制 / 开放报名 / 停止报名 */
private String xkzt;
/** 培训层次 */
private String pxcc;
/** 任务编号列表(学员名单导出时使用) */
private List<String> bhList;
}
@@ -0,0 +1,70 @@
package com.roomroot.jwgl.dto.jys;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 新建选修课。
* <p>写入学员队任务表(课类型含“选修”),并同步拼班信息中的报名日期与要求说明。</p>
*/
@Data
public class ElectiveCourseSaveDTO {
/** 年度,空则取当前年 */
private Integer nd;
/** 学员队编号(选修班),与选修班名称二选一 */
private String xydbh;
/** 选修班名称。学员队编号为空时按名称查找或新建选修班 */
private String xxbmc;
/** 年级(新建选修班时使用) */
private String nj;
/** 课编号 */
private String kbh;
/** 学期第次 */
private Integer xqdc;
/** 授课教员编号 */
private String jybh;
/** 教室编号 */
private String jsbh;
/** 计划人数 */
private Integer rs;
/** 计划学时 */
private Integer xs;
/** 学分 */
private Float xf;
/** 教研室代号 */
private String jysdh;
/** 备注 */
private String bz;
/** 要求说明 */
private String yqsm;
/** 显示可选队列班次 */
private String kxdlbc;
/** 开课日期 */
private LocalDateTime kkrq;
/** 结课日期 */
private LocalDateTime jkrq;
/** 报名开始日期 */
private LocalDateTime bmkssj;
/** 报名结束日期 */
private LocalDateTime bmjssj;
}
@@ -0,0 +1,22 @@
package com.roomroot.jwgl.dto.jys;
import lombok.Data;
/**
* 教学任务列表查询条件。
*/
@Data
public class TeachingTaskQuery {
/** 任务名称(模糊) */
private String rwmc;
/** 年度,空则本学期年度 */
private Integer nd;
/** 学期第次 */
private Integer xqdc;
/** 状态:上报 / 发布 */
private String zt;
}
@@ -0,0 +1,32 @@
package com.roomroot.jwgl.dto.jys;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
/**
* 新增 / 编辑教学任务。
* <p>机关发布教学任务,并关联学员队(班次);教研室任务书按课程归属教研室自动生成。</p>
*/
@Data
public class TeachingTaskSaveDTO {
/** 编号,编辑时必填 */
private String bh;
/** 年度,空则取当前学期 */
private Integer nd;
/** 学期第次,空则取当前学期 */
private Integer xqdc;
/** 任务名称 */
private String rwmc;
/** 结束时间 */
private LocalDateTime jssj;
/** 关联的学员队年度学期基本信息编号 */
private List<String> xydxqbhList;
}
@@ -0,0 +1,23 @@
package com.roomroot.jwgl.dto.kcb;
import lombok.Data;
/**
* 今日 / 本周 / 班次课表查询条件。
* <p>未传年度、学期时按当前时间取本学期。</p>
*/
@Data
public class TimetableQuery {
/** 年度,空则本学期年度 */
private Integer nd;
/** 学期第次,空则本学期序号 */
private Integer xqdc;
/** 学员队编号(队别班次) */
private String xydbh;
/** 学员队名称(队别班次模糊) */
private String xydmc;
}
@@ -3,6 +3,7 @@ package com.roomroot.jwgl.entity;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;
import com.roomroot.jwgl.unit.BaseEntity; import com.roomroot.jwgl.unit.BaseEntity;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -24,163 +25,144 @@ public class SSDKSQ extends BaseEntity {
private String bh; private String bh;
/** /**
* 实施_课程表编号 * 实施_课程表编号(原表主关联:指向实施_课程表)
*/ */
@TableField("实施_课程表编号")
private String sskcbbh; private String sskcbbh;
/** @TableField("预调时间安排")
* 预调时间安排
*/
private Integer ydsjap; private Integer ydsjap;
/** @TableField("创建时间")
* 创建时间
*/
private LocalDateTime cjsj; private LocalDateTime cjsj;
/** @TableField("执行人编号")
* 执行人编号
*/
private String zxrbh; private String zxrbh;
/** @TableField("执行时间")
* 执行时间
*/
private LocalDateTime zxsj; private LocalDateTime zxsj;
/** @TableField("执行状态")
* 执行状态
*/
private Integer zxzt; private Integer zxzt;
/** @TableField("事由")
* 事由
*/
private String sy; private String sy;
/** @TableField("教研室批准状态")
* 教研室批准状态
*/
private Integer jyspzzt; private Integer jyspzzt;
/** @TableField("教研室批准时间")
* 教研室批准时间
*/
private LocalDateTime jyspzsj; private LocalDateTime jyspzsj;
/** @TableField("教研室批准人编号")
* 教研室批准人编号
*/
private String jyspzrbh; private String jyspzrbh;
/** /** 原表无此列 */
* 教学系批准状态 @TableField(exist = false)
*/
private Integer jxxspzzt; private Integer jxxspzzt;
/** @TableField(exist = false)
* 教学系批准时间
*/
private LocalDateTime jxxspzsj; private LocalDateTime jxxspzsj;
/** @TableField(exist = false)
* 教学系批准人编号
*/
private String jxxspzrbh; private String jxxspzrbh;
/** @TableField("备注")
* 备注
*/
private String bz; private String bz;
/** @TableField("申请教员编号")
* 申请教员编号
*/
private String sqjybh; private String sqjybh;
/** @TableField("延时状态")
* 延时状态
*/
private Integer yszt; private Integer yszt;
/** @TableField("教研室查收状态")
* 教研室查收状态
*/
private Integer jyscszt; private Integer jyscszt;
/** @TableField("教研室查收时间")
* 教研室查收时间
*/
private LocalDateTime jyscssj; private LocalDateTime jyscssj;
/** @TableField("教研室查收人编号")
* 教研室查收人编号
*/
private String jyscsrbh; private String jyscsrbh;
/** @TableField("删除状态")
* 删除状态
*/
private Integer sczt; private Integer sczt;
/** @TableField("发回状态")
* 发回状态
*/
private Integer fhzt; private Integer fhzt;
/** @TableField("发回意见")
* 发回意见
*/
private String fhyj; private String fhyj;
/** @TableField("发回时间")
* 发回时间
*/
private LocalDateTime fhsj; private LocalDateTime fhsj;
/** @TableField("调课")
* 调课
*/
private Integer dk; private Integer dk;
/** @TableField("年度")
* 年度
*/
private Integer nd; private Integer nd;
/** /** 拟调整后的上课日期 */
* 日期 @TableField("日期")
*/
private LocalDateTime rq; private LocalDateTime rq;
/** /** 拟调整后的节次 */
* 节次 @TableField("节次")
*/
private Integer jc; private Integer jc;
/** @TableField("教学内容")
* 教学内容
*/
private String jxnr; private String jxnr;
/** @TableField("教学要点")
* 教学要点
*/
private String jxyd; private String jxyd;
/** @TableField("教学方法")
* 教学方法
*/
private String jxff; private String jxff;
/** @TableField("教学保障备注")
* 教学保障备注
*/
private String jxbzbz; private String jxbzbz;
/** @TableField("用车信息")
* 用车信息
*/
private String ycxx; private String ycxx;
/** 学员队任务表编号 */
@TableField("学员队任务编号")
private String xydrwbh;
/** 课表.课编号 */
@TableField("课编号")
private String kbh;
/** 课程表编号 */
@TableField("课程表编号")
private String kcbbh;
/** 申请教员所属教研室代号,用于教研室数据范围过滤 */
@TableField("教研室代号")
private String jysdh;
/** 原教室编号 */
@TableField("原教室编号")
private String yjsbh;
/** 拟调整教室编号 */
@TableField("新教室编号")
private String xjsbh;
@TableField(exist = false)
private LocalDateTime createTime;
@TableField(exist = false)
private LocalDateTime updateTime;
@TableField(exist = false)
private String createBy;
@TableField(exist = false)
private String updateBy;
@TableField(exist = false)
private Integer delFlag;
} }
@@ -92,22 +92,38 @@ public class JwglApiAccessInterceptor implements HandlerInterceptor {
if (startsWithAny(path, "/getInfo", "/getRouters", "/logout", "/system/user/profile")) { if (startsWithAny(path, "/getInfo", "/getRouters", "/logout", "/system/user/profile")) {
return true; return true;
} }
// 通知已读属于个人操作,布局顶栏会调用。
if (HttpMethod.POST.matches(method)
&& startsWithAny(path, "/system/notice/markRead", "/system/notice/markReadAll")) {
return true;
}
if (!HttpMethod.GET.matches(method)) { if (!HttpMethod.GET.matches(method)) {
return false; return false;
} }
return startsWithAny(path, return startsWithAny(path,
// 学期列表 / 学期校历(只读;新增、修改、删除仍拦截)
"/semester",
"/xqxlb", "/xqxlb",
"/kcb",
"/studentTeamOutputSchedule",
"/classCalendar", "/classCalendar",
// 本人课表
"/kcb/today",
"/kcb/week",
"/kcb/class",
"/studentTeamOutputSchedule",
"/course-running/plan/list", "/course-running/plan/list",
"/course-running/plan/detail", "/course-running/plan/detail",
"/course-running/plan/export", "/course-running/plan/export",
// 本人学籍预警、个人信息、成绩
"/student-records/warning-result", "/student-records/warning-result",
"/student-records/warning-condition",
"/student-records/get", "/student-records/get",
"/student-records/list", "/student-records/list",
"/student-records/grades", "/student-records/grades",
"/student-records/process-grades"); "/student-records/process-grades",
// 布局公共只读:字典、参数、通知
"/system/dict/data/type",
"/system/config/configKey",
"/system/notice");
} }
private boolean isTeacherAdjustDenied(String path, String method) { private boolean isTeacherAdjustDenied(String path, String method) {
@@ -0,0 +1,37 @@
package com.roomroot.jwgl.mapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.roomroot.jwgl.dto.jys.ElectiveCourseQuery;
import com.roomroot.jwgl.vo.jys.ElectiveCourseStudentVO;
import com.roomroot.jwgl.vo.jys.ElectiveCourseVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
import java.util.List;
/**
* 选修课管理自定义查询(学员队任务表 + 学员队表 + 课表)。
*/
@Mapper
public interface ElectiveCourseMapper {
Page<ElectiveCourseVO> selectElectiveCoursePage(Page<ElectiveCourseVO> page,
@Param("cond") ElectiveCourseQuery cond);
List<ElectiveCourseVO> selectElectiveCourseList(@Param("cond") ElectiveCourseQuery cond);
List<ElectiveCourseStudentVO> selectElectiveStudents(@Param("xydbh") String xydbh);
List<String> selectOriginalClassNames(@Param("xydbh") String xydbh);
Integer countPinban(@Param("xydbh") String xydbh);
int insertPinban(@Param("xydbh") String xydbh, @Param("zt") String zt,
@Param("jhkssj") LocalDateTime jhkssj, @Param("jhjssj") LocalDateTime jhjssj,
@Param("yqsm") String yqsm, @Param("bmdtj") String bmdtj, @Param("bz") String bz);
int updatePinban(@Param("xydbh") String xydbh, @Param("zt") String zt,
@Param("jhkssj") LocalDateTime jhkssj, @Param("jhjssj") LocalDateTime jhjssj,
@Param("yqsm") String yqsm, @Param("bmdtj") String bmdtj);
}
@@ -0,0 +1,201 @@
<?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.roomroot.jwgl.mapper.ElectiveCourseMapper">
<resultMap id="ElectiveCourseResultMap" type="com.roomroot.jwgl.vo.jys.ElectiveCourseVO">
<result column="bh" property="bh"/>
<result column="nd" property="nd"/>
<result column="xydbh" property="xydbh"/>
<result column="kbh" property="kbh"/>
<result column="jybh" property="jybh"/>
<result column="jsbh" property="jsbh"/>
<result column="kmc" property="kmc"/>
<result column="jcmc" property="jcmc"/>
<result column="jyxm" property="jyxm"/>
<result column="jsmc" property="jsmc"/>
<result column="kxdlbc" property="kxdlbc"/>
<result column="jhxs" property="jhxs"/>
<result column="yxxs" property="yxxs"/>
<result column="xf" property="xf"/>
<result column="jhyxxsxf" property="jhyxxsxf"/>
<result column="kkjkrq" property="kkjkrq"/>
<result column="bmrq" property="bmrq"/>
<result column="jhrs" property="jhrs"/>
<result column="yqsm" property="yqsm"/>
<result column="xxbmc" property="xxbmc"/>
<result column="xkzt" property="xkzt"/>
<result column="pxcc" property="pxcc"/>
</resultMap>
<resultMap id="ElectiveStudentResultMap" type="com.roomroot.jwgl.vo.jys.ElectiveCourseStudentVO">
<result column="xxbmc" property="xxbmc"/>
<result column="kmc" property="kmc"/>
<result column="xh_no" property="xhNo"/>
<result column="xm" property="xm"/>
<result column="xb" property="xb"/>
<result column="lxdh" property="lxdh"/>
</resultMap>
<sql id="ElectiveCourseColumns">
t."编号" AS bh,
t."年度" AS nd,
t."学员队编号" AS xydbh,
t."课编号" AS kbh,
t."教员编号" AS jybh,
t."教室编号" AS jsbh,
k."课名称" AS kmc,
(SELECT WM_CONCAT(DISTINCT jc."名称")
FROM "课程教材" kj
LEFT JOIN "教材信息" jc ON jc."编号" = kj."教材编号"
WHERE kj."课编号" = t."课编号") AS jcmc,
jy."教员姓名" AS jyxm,
(SELECT MAX(js."教室名称") FROM "教室表" js WHERE js."教室编号" = t."教室编号") AS jsmc,
COALESCE(pb."白名单条件", xyd."学员队名称") AS kxdlbc,
COALESCE(sskc.jhxs, t."学时", k."学时") AS jhxs,
sskc.yxxs AS yxxs,
COALESCE(sskc.xf, t."学分", k."学分") AS xf,
(NVL(TO_CHAR(COALESCE(sskc.jhxs, t."学时", k."学时")), '-')
|| ' / ' || NVL(TO_CHAR(sskc.yxxs), '-')
|| ' / ' || NVL(TO_CHAR(COALESCE(sskc.xf, t."学分", k."学分")), '-')) AS jhyxxsxf,
CASE
WHEN COALESCE(xq.kxrq, xyd."入学日期") IS NULL THEN NULL
ELSE TO_CHAR(COALESCE(xq.kxrq, xyd."入学日期"), 'YYYY-MM-DD')
|| ' ~ '
|| NVL(TO_CHAR(COALESCE(xq.jsrq, xyd."毕业日期"), 'YYYY-MM-DD'), '-')
END AS kkjkrq,
CASE
WHEN COALESCE(pb."计划开始时间", q."入学日期") IS NULL THEN NULL
ELSE TO_CHAR(COALESCE(pb."计划开始时间", q."入学日期"), 'YYYY-MM-DD')
|| ' ~ '
|| NVL(TO_CHAR(COALESCE(pb."计划结束时间", q."结束注册时间"), 'YYYY-MM-DD'), '-')
END AS bmrq,
COALESCE(t."人数", xyd."学员队人数") AS jhrs,
pb."要求说明" AS yqsm,
xyd."学员队名称" AS xxbmc,
COALESCE(pb."状态",
CASE t."选择" WHEN 1 THEN '开放报名' WHEN 2 THEN '停止报名' ELSE '拟制' END) AS xkzt,
k."培训层次" AS pxcc
</sql>
<sql id="ElectiveCourseFromWhere">
FROM "学员队任务表" t
INNER JOIN "学员队表" xyd ON t."学员队编号" = xyd."学员队编号"
INNER JOIN "课表" k ON t."课编号" = k."课编号"
LEFT JOIN "教员表" jy ON t."教员编号" = jy."教员编号"
LEFT JOIN "学员队拼班信息" pb ON pb."学员队编号" = t."学员队编号"
LEFT JOIN "学员队期表" q ON q."学员队编号" = t."学员队编号"
LEFT JOIN (
SELECT "学员队编号", "年度", "学期第次",
MIN("开学日期") AS kxrq, MAX("结束日期") AS jsrq
FROM "学员队年度学期基本信息表"
GROUP BY "学员队编号", "年度", "学期第次"
) xq ON xq."学员队编号" = t."学员队编号"
AND xq."年度" = t."年度"
AND xq."学期第次" = t."学期第次"
LEFT JOIN (
SELECT "科目编号", "教员编号", "年度",
MAX("学时") AS jhxs, MAX("运行学时") AS yxxs, MAX("学分") AS xf
FROM "实施_课程"
GROUP BY "科目编号", "教员编号", "年度"
) sskc ON sskc."科目编号" = t."课编号"
AND (sskc."教员编号" = t."教员编号" OR t."教员编号" IS NULL)
AND (sskc."年度" = t."年度" OR t."年度" IS NULL)
<where>
t."课类型" LIKE '%选修%'
AND (t.DEL_FLAG = 0 OR t.DEL_FLAG IS NULL)
<if test="cond != null and cond.jyxm != null and cond.jyxm != ''">
AND jy."教员姓名" LIKE CONCAT('%', #{cond.jyxm}, '%')
</if>
<if test="cond != null and cond.kmc != null and cond.kmc != ''">
AND k."课名称" LIKE CONCAT('%', #{cond.kmc}, '%')
</if>
<if test="cond != null and cond.kxbcnj != null and cond.kxbcnj != ''">
AND (xyd."年级" LIKE CONCAT('%', #{cond.kxbcnj}, '%')
OR pb."白名单条件" LIKE CONCAT('%', #{cond.kxbcnj}, '%')
OR xyd."学员队名称" LIKE CONCAT('%', #{cond.kxbcnj}, '%'))
</if>
<if test="cond != null and cond.xxbmc != null and cond.xxbmc != ''">
AND xyd."学员队名称" LIKE CONCAT('%', #{cond.xxbmc}, '%')
</if>
<if test="cond != null and cond.xkzt != null and cond.xkzt != ''">
AND COALESCE(pb."状态",
CASE t."选择" WHEN 1 THEN '开放报名' WHEN 2 THEN '停止报名' ELSE '拟制' END) = #{cond.xkzt}
</if>
<if test="cond != null and cond.pxcc != null and cond.pxcc != ''">
AND k."培训层次" = #{cond.pxcc}
</if>
<if test="cond != null and cond.bhList != null and cond.bhList.size() &gt; 0">
AND t."编号" IN
<foreach collection="cond.bhList" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</if>
</where>
</sql>
<select id="selectElectiveCoursePage" resultMap="ElectiveCourseResultMap">
SELECT
<include refid="ElectiveCourseColumns"/>
<include refid="ElectiveCourseFromWhere"/>
ORDER BY t."年度" DESC, t."编号"
</select>
<select id="selectElectiveCourseList" resultMap="ElectiveCourseResultMap">
SELECT
<include refid="ElectiveCourseColumns"/>
<include refid="ElectiveCourseFromWhere"/>
ORDER BY t."年度" DESC, t."编号"
</select>
<select id="selectElectiveStudents" resultMap="ElectiveStudentResultMap">
SELECT
xyd."学员队名称" AS xxbmc,
NULL AS kmc,
s."学号" AS xh_no,
s."姓名" AS xm,
s."性别" AS xb,
s."联系电话" AS lxdh
FROM "学员信息表" s
LEFT JOIN "学员队期表" q ON q."编号" = s."学员队期编号"
LEFT JOIN "学员队表" xyd ON xyd."学员队编号" = #{xydbh}
WHERE s."当前班次编号" = #{xydbh}
OR q."学员队编号" = #{xydbh}
ORDER BY s."学号"
</select>
<select id="selectOriginalClassNames" resultType="java.lang.String">
SELECT DISTINCT COALESCE(orig."学员队名称", prev."学员队名称")
FROM "学员信息表" s
LEFT JOIN "学员队期表" q ON q."编号" = s."学员队期编号"
LEFT JOIN "学员队表" orig
ON orig."学员队编号" = q."学员队编号"
AND orig."学员队编号" != #{xydbh}
LEFT JOIN "学员队表" prev ON prev."学员队编号" = s."上一个部别编号"
WHERE (s."当前班次编号" = #{xydbh} OR q."学员队编号" = #{xydbh})
AND COALESCE(orig."学员队名称", prev."学员队名称") IS NOT NULL
</select>
<select id="countPinban" resultType="java.lang.Integer">
SELECT COUNT(1) FROM "学员队拼班信息" WHERE "学员队编号" = #{xydbh}
</select>
<insert id="insertPinban">
INSERT INTO "学员队拼班信息"(
"学员队编号", "状态", "计划开始时间", "计划结束时间", "要求说明", "白名单条件", "备注"
) VALUES (
#{xydbh}, #{zt}, #{jhkssj}, #{jhjssj}, #{yqsm}, #{bmdtj}, #{bz}
)
</insert>
<update id="updatePinban">
UPDATE "学员队拼班信息"
<set>
<if test="zt != null">"状态" = #{zt},</if>
<if test="jhkssj != null">"计划开始时间" = #{jhkssj},</if>
<if test="jhjssj != null">"计划结束时间" = #{jhjssj},</if>
<if test="yqsm != null">"要求说明" = #{yqsm},</if>
<if test="bmdtj != null">"白名单条件" = #{bmdtj},</if>
</set>
WHERE "学员队编号" = #{xydbh}
</update>
</mapper>
@@ -6,6 +6,7 @@ import com.roomroot.jwgl.entity.JYB;
import com.roomroot.jwgl.vo.faculty.TeacherListVO; import com.roomroot.jwgl.vo.faculty.TeacherListVO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
/** /**
* 教员表 Mapper * 教员表 Mapper
@@ -27,4 +28,9 @@ public interface JYBMapper extends BaseMapper<JYB> {
/** 教员列表双表联查分页 */ /** 教员列表双表联查分页 */
Page<TeacherListVO> selectTeacherPageList(Page<TeacherListVO> page, @Param("jyb") JYB cond); Page<TeacherListVO> selectTeacherPageList(Page<TeacherListVO> page, @Param("jyb") JYB cond);
@Select("SELECT TRIM(b.\"教员编号\") FROM \"教员登录表\" b "
+ "JOIN \"登录信息表\" a ON TRIM(a.\"编号\") = TRIM(b.\"登录信息编号\") "
+ "WHERE TRIM(a.\"账号\") = #{username}")
String selectTeacherIdByAccount(@Param("username") String username);
} }
@@ -0,0 +1,28 @@
package com.roomroot.jwgl.mapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.roomroot.jwgl.dto.kcb.TimetableQuery;
import com.roomroot.jwgl.vo.kcb.ClassTimetableVO;
import com.roomroot.jwgl.vo.kcb.DailyWeeklyTimetableVO;
import com.roomroot.jwgl.vo.kcb.SemesterGradeExportVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 今日 / 本周 / 班次课表查询。
*/
@Mapper
public interface KcbTimetableMapper {
List<DailyWeeklyTimetableVO> selectLessonTimetable(@Param("cond") TimetableQuery cond,
@Param("startDate") String startDate, @Param("endDate") String endDate);
Page<ClassTimetableVO> selectClassTimetable(Page<ClassTimetableVO> page,
@Param("cond") TimetableQuery cond);
List<ClassTimetableVO> selectClassTimetableList(@Param("cond") TimetableQuery cond);
List<SemesterGradeExportVO> selectSemesterGrades(@Param("cond") TimetableQuery cond);
}
@@ -0,0 +1,170 @@
<?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.roomroot.jwgl.mapper.KcbTimetableMapper">
<sql id="LessonTeamFilter">
<if test="cond != null and cond.xydbh != null and cond.xydbh != ''">
AND EXISTS (
SELECT 1 FROM "实施_课程表_学员队" txf
WHERE txf."实施_课程表编号" = s."编号"
AND txf."学员队编号" = #{cond.xydbh}
)
</if>
<if test="cond != null and cond.xydmc != null and cond.xydmc != ''">
AND EXISTS (
SELECT 1 FROM "实施_课程表_学员队" txf
INNER JOIN "学员队表" xydf ON xydf."学员队编号" = txf."学员队编号"
WHERE txf."实施_课程表编号" = s."编号"
AND xydf."学员队名称" LIKE CONCAT('%', #{cond.xydmc}, '%')
)
</if>
<if test="cond != null and cond.xqdc != null">
AND EXISTS (
SELECT 1 FROM "实施_课程学员队" cxf
WHERE cxf."实施_课程编号" = c."编号"
AND cxf."学期第次" = #{cond.xqdc}
)
</if>
</sql>
<select id="selectLessonTimetable" resultType="com.roomroot.jwgl.vo.kcb.DailyWeeklyTimetableVO">
SELECT
s."编号" AS bh,
TO_CHAR(s."日期", 'YYYY-MM-DD') || ' 第' || CAST(s."节次" AS VARCHAR) || '节' AS sksj,
MAX(k."课名称") AS kc,
MAX(jys."教研室名称") AS zrdw,
WM_CONCAT(DISTINCT xyd."学员队名称") AS bc,
COALESCE(WM_CONCAT(DISTINCT jyf."教员姓名"), MAX(jy."教员姓名")) AS jy,
COALESCE(WM_CONCAT(DISTINCT js."教室名称"), MAX(js2."教室名称")) AS cd,
TRIM(NVL(MAX(s."教学内容"), '')
|| CASE
WHEN MAX(s."教学方法") IS NOT NULL AND MAX(s."教学方法") != ''
THEN ' / ' || MAX(s."教学方法")
ELSE ''
END) AS jxnrxff,
COALESCE(MAX(s."教务备注"), MAX(s."教员备注"), MAX(
(SELECT MAX(kcb."备注") FROM "课程表" kcb
WHERE kcb."年度" = s."年度"
AND kcb."教员编号" = c."教员编号"
AND kcb."课次序号" = c."教员课次序号")
)) AS bz
FROM "实施_课程表" s
LEFT JOIN "实施_课程" c ON CAST(c."编号" AS CHAR(36)) = TRIM(s."实施_课程编号")
LEFT JOIN "课表" k ON (k."课编号" = c."科目编号" OR k."科目代码" = c."科目编号")
LEFT JOIN "教研室表" jys ON jys."教研室代号" = k."教研室代号"
LEFT JOIN "教员表" jy ON jy."教员编号" = c."教员编号"
LEFT JOIN "实施_课程表_学员队" tx ON tx."实施_课程表编号" = s."编号"
LEFT JOIN "学员队表" xyd ON xyd."学员队编号" = tx."学员队编号"
LEFT JOIN "实施_课程表_教室" jsx ON jsx."实施_课程表编号" = s."编号"
LEFT JOIN "教室表" js ON js."教室编号" = jsx."教室编号"
LEFT JOIN "教室表" js2 ON js2."教室编号" = c."教室编号"
LEFT JOIN "实施_课程表_辅助教员" fz ON fz."实施_课程表编号" = s."编号"
LEFT JOIN "教员表" jyf ON jyf."教员编号" = fz."辅助教员编号"
WHERE COALESCE(s."删除状态", 0) = 0
<if test="cond != null and cond.nd != null">
AND s."年度" = #{cond.nd}
</if>
<if test="startDate != null and startDate != ''">
AND TO_CHAR(s."日期", 'YYYY-MM-DD') &gt;= #{startDate}
</if>
<if test="endDate != null and endDate != ''">
AND TO_CHAR(s."日期", 'YYYY-MM-DD') &lt;= #{endDate}
</if>
<include refid="LessonTeamFilter"/>
GROUP BY s."编号", s."日期", s."节次", s."年度", c."教员编号", c."教员课次序号"
ORDER BY s."日期", s."节次", s."编号"
</select>
<sql id="ClassTimetableWhere">
WHERE 1 = 1
<if test="cond != null and cond.nd != null">
AND COALESCE(cx."年度", c."年度") = #{cond.nd}
</if>
<if test="cond != null and cond.xqdc != null">
AND cx."学期第次" = #{cond.xqdc}
</if>
<if test="cond != null and cond.xydbh != null and cond.xydbh != ''">
AND cx."学员队编号" = #{cond.xydbh}
</if>
<if test="cond != null and cond.xydmc != null and cond.xydmc != ''">
AND xyd."学员队名称" LIKE CONCAT('%', #{cond.xydmc}, '%')
</if>
</sql>
<sql id="ClassTimetableSelect">
SELECT
c."编号" AS sskcbh,
(NVL(k."课名称", c."科目编号")
|| ' / '
|| NVL(TO_CHAR(c."课程课时系数"), '-')) AS kcmcksxs,
(NVL(zjy."教员姓名", '-')
|| ' / '
|| NVL(TO_CHAR(c."教员课次序号"),
TO_CHAR((SELECT COUNT(1) FROM "实施_课程表" t
WHERE CAST(c."编号" AS CHAR(36)) = TRIM(t."实施_课程编号")
AND COALESCE(t."删除状态", 0) = 0)))) AS zrjykc,
c."学时" AS jhxs,
c."运行学时" AS yxxs,
COALESCE(k."考核方式", c."成绩分制") AS khlxfs,
sjy."教员姓名" AS ssjy,
(NVL(TO_CHAR(cx."人数"), NVL(TO_CHAR(xyd."学员队人数"), '-'))
|| ' / '
|| NVL((SELECT WM_CONCAT(DISTINCT js."教室名称")
FROM "实施_课程表" t
LEFT JOIN "实施_课程表_教室" jsx ON jsx."实施_课程表编号" = t."编号"
LEFT JOIN "教室表" js ON js."教室编号" = jsx."教室编号"
WHERE CAST(c."编号" AS CHAR(36)) = TRIM(t."实施_课程编号")
AND COALESCE(t."删除状态", 0) = 0),
NVL(js0."教室名称", '-'))) AS rscd,
(SELECT WM_CONCAT(DISTINCT sq."事由")
FROM "实施_调课申请" sq
INNER JOIN "实施_课程表" t ON t."编号" = sq."实施_课程表编号"
WHERE CAST(c."编号" AS CHAR(36)) = TRIM(t."实施_课程编号")) AS ssjhbg
FROM "实施_课程" c
INNER JOIN "实施_课程学员队" cx ON cx."实施_课程编号" = c."编号"
LEFT JOIN "学员队表" xyd ON xyd."学员队编号" = cx."学员队编号"
LEFT JOIN "课表" k ON (k."课编号" = c."科目编号" OR k."科目代码" = c."科目编号")
LEFT JOIN "教员表" zjy ON zjy."教员编号" = c."责任教员编号"
LEFT JOIN "教员表" sjy ON sjy."教员编号" = c."教员编号"
LEFT JOIN "教室表" js0 ON js0."教室编号" = c."教室编号"
</sql>
<select id="selectClassTimetable" resultType="com.roomroot.jwgl.vo.kcb.ClassTimetableVO">
<include refid="ClassTimetableSelect"/>
<include refid="ClassTimetableWhere"/>
ORDER BY k."课名称", c."编号"
</select>
<select id="selectClassTimetableList" resultType="com.roomroot.jwgl.vo.kcb.ClassTimetableVO">
<include refid="ClassTimetableSelect"/>
<include refid="ClassTimetableWhere"/>
ORDER BY k."课名称", c."编号"
</select>
<select id="selectSemesterGrades" resultType="com.roomroot.jwgl.vo.kcb.SemesterGradeExportVO">
SELECT
s."学号" AS xh,
s."姓名" AS xm,
COALESCE(k."课名称", g."科目编号") AS kcmc,
g."平时成绩" AS pscj,
g."考试成绩" AS kscj,
g."最终成绩" AS zzcj,
g."考试情况" AS ksqk,
g."年度" AS nd
FROM "学员课程成绩" g
LEFT JOIN "学员信息表" s ON s."编号" = g."学员编号"
LEFT JOIN "课表" k ON (k."课编号" = g."科目编号" OR k."科目代码" = g."科目编号")
LEFT JOIN "学员队表" xyd ON xyd."学员队编号" = g."学员队编号"
WHERE 1 = 1
<if test="cond != null and cond.nd != null">
AND g."年度" = #{cond.nd}
</if>
<if test="cond != null and cond.xydbh != null and cond.xydbh != ''">
AND g."学员队编号" = #{cond.xydbh}
</if>
<if test="cond != null and cond.xydmc != null and cond.xydmc != ''">
AND xyd."学员队名称" LIKE CONCAT('%', #{cond.xydmc}, '%')
</if>
ORDER BY s."学号", k."课名称"
</select>
</mapper>
@@ -3,58 +3,45 @@ package com.roomroot.jwgl.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.roomroot.jwgl.entity.SSDKSQ; import com.roomroot.jwgl.entity.SSDKSQ;
import com.roomroot.jwgl.vo.courserunning.AdjustableLessonVO;
import com.roomroot.jwgl.vo.courserunning.ScheduleAdjustApplyVO; import com.roomroot.jwgl.vo.courserunning.ScheduleAdjustApplyVO;
import com.roomroot.jwgl.vo.courserunning.ScheduleAdjustDetailVO; import com.roomroot.jwgl.vo.courserunning.ScheduleAdjustDetailVO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.util.List;
/** /**
* 实施_调课申请 Mapper。 * 实施_调课申请 Mapper。
* <p>
* 提供调课申请数据的CRUD操作及调课管理相关的自定义查询。
* </p>
*/ */
@Mapper @Mapper
public interface SSDKSQMapper extends BaseMapper<SSDKSQ> { public interface SSDKSQMapper extends BaseMapper<SSDKSQ> {
/** /**
* 分页查询调课申请列表。 * 分页查询调课申请列表。
* <p>
* 支持按实施_课程表编号、申请教员编号、年度、教研室审批状态、
* 教研室查收状态、删除状态和申请日期范围筛选。
* 关联课程表获取课程名称,关联教员表获取申请教员姓名。
* </p>
*
* @param page MyBatis-Plus 分页对象
* @param sskcbbh 实施_课程表编号
* @param sqjybh 申请教员编号
* @param nd 年度
* @param jyspzzt 教研室审批状态
* @param jyscszt 教研室查收状态
* @param sczt 删除状态
* @param cjsjStart 申请日期范围开始
* @param cjsjEnd 申请日期范围结束
* @return 分页调课申请列表
*/ */
Page<ScheduleAdjustApplyVO> selectPageList( Page<ScheduleAdjustApplyVO> selectPageList(
Page<ScheduleAdjustApplyVO> page, Page<ScheduleAdjustApplyVO> page,
@Param("sskcbbh") String sskcbbh, @Param("sskcbbh") String sskcbbh,
@Param("xydrwbh") String xydrwbh,
@Param("kbh") String kbh,
@Param("sqjybh") String sqjybh, @Param("sqjybh") String sqjybh,
@Param("jysdh") String jysdh,
@Param("nd") Integer nd, @Param("nd") Integer nd,
@Param("jyspzzt") Integer jyspzzt, @Param("jyspzzt") Integer jyspzzt,
@Param("jyscszt") Integer jyscszt, @Param("jyscszt") Integer jyscszt,
@Param("jgspzt") Integer jgspzt,
@Param("sczt") Integer sczt, @Param("sczt") Integer sczt,
@Param("cjsjStart") String cjsjStart, @Param("cjsjStart") String cjsjStart,
@Param("cjsjEnd") String cjsjEnd); @Param("cjsjEnd") String cjsjEnd);
/** /**
* 根据调课申请编号查询调课申请详情。 * 根据调课申请编号查询详情。
* <p>
* 关联课程表获取课程名称,关联教员表获取申请教员姓名。
* </p>
*
* @param ssdksqbh 调课申请编号
* @return 调课申请详情
*/ */
ScheduleAdjustDetailVO selectDetailById(@Param("ssdksqbh") String ssdksqbh); ScheduleAdjustDetailVO selectDetailById(@Param("ssdksqbh") String ssdksqbh);
/**
* 查询可供调课的课次(学员队任务表 + 课表 + 课程表)。
*/
List<AdjustableLessonVO> selectAdjustableLessons(@Param("jybh") String jybh, @Param("nd") Integer nd);
} }
@@ -2,11 +2,17 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.roomroot.jwgl.mapper.SSDKSQMapper"> <mapper namespace="com.roomroot.jwgl.mapper.SSDKSQMapper">
<!-- 调课申请列表结果映射 -->
<resultMap id="ScheduleAdjustApplyMap" type="com.roomroot.jwgl.vo.courserunning.ScheduleAdjustApplyVO"> <resultMap id="ScheduleAdjustApplyMap" type="com.roomroot.jwgl.vo.courserunning.ScheduleAdjustApplyVO">
<result column="调课申请编号" property="ssdksqbh"/> <result column="调课申请编号" property="ssdksqbh"/>
<result column="实施_课程表编号" property="sskcbbh"/> <result column="实施_课程表编号" property="sskcbbh"/>
<result column="学员队任务编号" property="xydrwbh"/>
<result column="课编号" property="kbh"/>
<result column="课程表编号" property="kcbbh"/>
<result column="课程名称" property="kcmc"/> <result column="课程名称" property="kcmc"/>
<result column="学员队名称" property="xydmc"/>
<result column="教研室代号" property="jysdh"/>
<result column="原教室编号" property="yjsbh"/>
<result column="新教室编号" property="xjsbh"/>
<result column="申请教员编号" property="sqjybh"/> <result column="申请教员编号" property="sqjybh"/>
<result column="申请教员姓名" property="sqjyxm"/> <result column="申请教员姓名" property="sqjyxm"/>
<result column="事由" property="sy"/> <result column="事由" property="sy"/>
@@ -16,15 +22,22 @@
<result column="创建时间" property="cjsj"/> <result column="创建时间" property="cjsj"/>
<result column="教研室批准状态" property="jyspzzt"/> <result column="教研室批准状态" property="jyspzzt"/>
<result column="教研室查收状态" property="jyscszt"/> <result column="教研室查收状态" property="jyscszt"/>
<result column="机关审批状态" property="jgspzt"/>
<result column="发回意见" property="fhyj"/> <result column="发回意见" property="fhyj"/>
<result column="删除状态" property="sczt"/> <result column="删除状态" property="sczt"/>
</resultMap> </resultMap>
<!-- 调课申请详情结果映射 -->
<resultMap id="ScheduleAdjustDetailMap" type="com.roomroot.jwgl.vo.courserunning.ScheduleAdjustDetailVO"> <resultMap id="ScheduleAdjustDetailMap" type="com.roomroot.jwgl.vo.courserunning.ScheduleAdjustDetailVO">
<result column="调课申请编号" property="ssdksqbh"/> <result column="调课申请编号" property="ssdksqbh"/>
<result column="实施_课程表编号" property="sskcbbh"/> <result column="实施_课程表编号" property="sskcbbh"/>
<result column="学员队任务编号" property="xydrwbh"/>
<result column="课编号" property="kbh"/>
<result column="课程表编号" property="kcbbh"/>
<result column="课程名称" property="kcmc"/> <result column="课程名称" property="kcmc"/>
<result column="学员队名称" property="xydmc"/>
<result column="教研室代号" property="jysdh"/>
<result column="原教室编号" property="yjsbh"/>
<result column="新教室编号" property="xjsbh"/>
<result column="申请教员编号" property="sqjybh"/> <result column="申请教员编号" property="sqjybh"/>
<result column="申请教员姓名" property="sqjyxm"/> <result column="申请教员姓名" property="sqjyxm"/>
<result column="事由" property="sy"/> <result column="事由" property="sy"/>
@@ -46,14 +59,43 @@
<result column="教研室查收人编号" property="jyscsrbh"/> <result column="教研室查收人编号" property="jyscsrbh"/>
</resultMap> </resultMap>
<!-- 分页查询调课申请列表 --> <resultMap id="AdjustableLessonMap" type="com.roomroot.jwgl.vo.courserunning.AdjustableLessonVO">
<result column="实施_课程表编号" property="sskcbbh"/>
<result column="上课日期" property="rq"/>
<result column="节次" property="jc"/>
<result column="学员队任务编号" property="xydrwbh"/>
<result column="课编号" property="kbh"/>
<result column="课程名称" property="kcmc"/>
<result column="学员队编号" property="xydbh"/>
<result column="学员队名称" property="xydmc"/>
<result column="教员编号" property="jybh"/>
<result column="课次序号" property="kcxh"/>
<result column="教室编号" property="jsbh"/>
<result column="年度" property="nd"/>
<result column="教研室代号" property="jysdh"/>
<result column="课程表编号" property="kcbbh"/>
</resultMap>
<!-- 以实施_调课申请为主表,经实施_课程表关联课表、课程表、学员队任务表 -->
<select id="selectPageList" resultMap="ScheduleAdjustApplyMap"> <select id="selectPageList" resultMap="ScheduleAdjustApplyMap">
SELECT SELECT
a.编号 AS 调课申请编号, a.编号 AS 调课申请编号,
a.实施_课程表编号, a.实施_课程表编号,
c.课名称 AS 课程名称, a.学员队任务编号,
COALESCE(a.课编号, e.科目编号) AS 课编号,
a.课程表编号,
kb.课名称 AS 课程名称,
(
SELECT MAX(xd.学员队名称)
FROM "实施_课程表_学员队" xyd
LEFT JOIN "学员队表" xd ON xd.学员队编号 = xyd.学员队编号
WHERE xyd.实施_课程表编号 = b.编号
) AS 学员队名称,
COALESCE(a.教研室代号, j.教研室代号) AS 教研室代号,
a.原教室编号,
a.新教室编号,
a.申请教员编号, a.申请教员编号,
j.姓名 AS 申请教员姓名, j.教员姓名 AS 申请教员姓名,
a.事由, a.事由,
a.日期 AS 新日期, a.日期 AS 新日期,
a.节次 AS 新节次, a.节次 AS 新节次,
@@ -61,20 +103,36 @@
a.创建时间, a.创建时间,
a.教研室批准状态, a.教研室批准状态,
a.教研室查收状态, a.教研室查收状态,
(
SELECT MAX(sp.审批状态)
FROM "实施_调课申请审批" sp
WHERE sp.实施_调课申请编号 = a.编号
AND sp.审批状态 IS NOT NULL
) AS 机关审批状态,
a.发回意见, a.发回意见,
a.删除状态 a.删除状态
FROM "实施_调课申请" a FROM "实施_调课申请" a
LEFT JOIN "实施_课程表" b ON a.实施_课程表编号 = b.编号 LEFT JOIN "实施_课程表" b ON TRIM(b.编号) = TRIM(a.实施_课程表编号)
LEFT JOIN "实施_课程" e ON b.实施_课程编号 = e.编号 LEFT JOIN "实施_课程" e ON CAST(e.编号 AS CHAR(36)) = TRIM(b.实施_课程编号)
LEFT JOIN "课程表" c ON e.课编号 = c.课编号 LEFT JOIN "课表" kb ON kb.课编号 = COALESCE(NULLIF(TRIM(a.课编号), ''), e.科目编号)
LEFT JOIN "教员表" j ON a.申请教员编号 = j.编号 LEFT JOIN "教员表" j ON TRIM(j.教员编号) = TRIM(a.申请教员编号)
LEFT JOIN "课程表" kcb ON TRIM(kcb.编号) = TRIM(a.课程表编号)
WHERE 1=1 WHERE 1=1
<if test="sskcbbh != null and sskcbbh != ''"> <if test="sskcbbh != null and sskcbbh != ''">
AND a.实施_课程表编号 = #{sskcbbh} AND a.实施_课程表编号 = #{sskcbbh}
</if> </if>
<if test="xydrwbh != null and xydrwbh != ''">
AND a.学员队任务编号 = #{xydrwbh}
</if>
<if test="kbh != null and kbh != ''">
AND COALESCE(a.课编号, e.科目编号) = #{kbh}
</if>
<if test="sqjybh != null and sqjybh != ''"> <if test="sqjybh != null and sqjybh != ''">
AND a.申请教员编号 = #{sqjybh} AND a.申请教员编号 = #{sqjybh}
</if> </if>
<if test="jysdh != null and jysdh != ''">
AND COALESCE(a.教研室代号, j.教研室代号) = #{jysdh}
</if>
<if test="nd != null"> <if test="nd != null">
AND a.年度 = #{nd} AND a.年度 = #{nd}
</if> </if>
@@ -84,6 +142,14 @@
<if test="jyscszt != null"> <if test="jyscszt != null">
AND a.教研室查收状态 = #{jyscszt} AND a.教研室查收状态 = #{jyscszt}
</if> </if>
<if test="jgspzt != null">
AND (
SELECT MAX(sp.审批状态)
FROM "实施_调课申请审批" sp
WHERE sp.实施_调课申请编号 = a.编号
AND sp.审批状态 IS NOT NULL
) = #{jgspzt}
</if>
<if test="sczt != null"> <if test="sczt != null">
AND a.删除状态 = #{sczt} AND a.删除状态 = #{sczt}
</if> </if>
@@ -96,14 +162,25 @@
ORDER BY a.创建时间 DESC ORDER BY a.创建时间 DESC
</select> </select>
<!-- 根据调课申请编号查询详情 -->
<select id="selectDetailById" resultMap="ScheduleAdjustDetailMap"> <select id="selectDetailById" resultMap="ScheduleAdjustDetailMap">
SELECT SELECT
a.编号 AS 调课申请编号, a.编号 AS 调课申请编号,
a.实施_课程表编号, a.实施_课程表编号,
c.课名称 AS 课程名称, a.学员队任务编号,
COALESCE(a.课编号, e.科目编号) AS 课编号,
a.课程表编号,
kb.课名称 AS 课程名称,
(
SELECT MAX(xd.学员队名称)
FROM "实施_课程表_学员队" xyd
LEFT JOIN "学员队表" xd ON xd.学员队编号 = xyd.学员队编号
WHERE xyd.实施_课程表编号 = b.编号
) AS 学员队名称,
COALESCE(a.教研室代号, j.教研室代号) AS 教研室代号,
a.原教室编号,
a.新教室编号,
a.申请教员编号, a.申请教员编号,
j.姓名 AS 申请教员姓名, j.教员姓名 AS 申请教员姓名,
a.事由, a.事由,
a.日期 AS 新日期, a.日期 AS 新日期,
a.节次 AS 新节次, a.节次 AS 新节次,
@@ -122,11 +199,70 @@
a.教研室查收时间, a.教研室查收时间,
a.教研室查收人编号 a.教研室查收人编号
FROM "实施_调课申请" a FROM "实施_调课申请" a
LEFT JOIN "实施_课程表" b ON a.实施_课程表编号 = b.编号 LEFT JOIN "实施_课程表" b ON TRIM(b.编号) = TRIM(a.实施_课程表编号)
LEFT JOIN "实施_课程" e ON b.实施_课程编号 = e.编号 LEFT JOIN "实施_课程" e ON CAST(e.编号 AS CHAR(36)) = TRIM(b.实施_课程编号)
LEFT JOIN "课程表" c ON e.课编号 = c.课编号 LEFT JOIN "课表" kb ON kb.课编号 = COALESCE(NULLIF(TRIM(a.课编号), ''), e.科目编号)
LEFT JOIN "教员表" j ON a.申请教员编号 = j.编号 LEFT JOIN "教员表" j ON TRIM(j.教员编号) = TRIM(a.申请教员编号)
WHERE a.编号 = #{ssdksqbh} WHERE a.编号 = #{ssdksqbh}
</select> </select>
<!-- 教员可选课次:实施_课程表 + 课表 + 课程表 + 学员队任务表 -->
<select id="selectAdjustableLessons" resultMap="AdjustableLessonMap">
SELECT
b.编号 AS 实施_课程表编号,
b.日期 AS 上课日期,
b.节次,
(
SELECT MAX(rw.编号)
FROM "学员队任务表" rw
WHERE rw.课编号 = e.科目编号
AND rw.教员编号 = e.教员编号
AND rw.年度 = b.年度
AND COALESCE(rw.DEL_FLAG, 0) = 0
) AS 学员队任务编号,
e.科目编号 AS 课编号,
COALESCE(kb.课名称, (
SELECT MAX(k2.课名称) FROM "课表" k2 WHERE k2.科目代码 = e.科目编号
)) AS 课程名称,
(
SELECT MAX(xyd.学员队编号)
FROM "实施_课程表_学员队" xyd
WHERE xyd.实施_课程表编号 = b.编号
) AS 学员队编号,
(
SELECT MAX(xd.学员队名称)
FROM "实施_课程表_学员队" xyd
LEFT JOIN "学员队表" xd ON xd.学员队编号 = xyd.学员队编号
WHERE xyd.实施_课程表编号 = b.编号
) AS 学员队名称,
e.教员编号,
e.教员课次序号 AS 课次序号,
COALESCE(e.教室编号, (
SELECT MAX(js.教室编号)
FROM "实施_课程表_教室" js
WHERE js.实施_课程表编号 = b.编号
)) AS 教室编号,
b.年度,
jy.教研室代号,
(
SELECT MAX(kcb.编号)
FROM "课程表" kcb
WHERE kcb.教员编号 = e.教员编号
AND kcb.课次序号 = e.教员课次序号
AND kcb.年度 = e.年度
) AS 课程表编号
FROM "实施_课程表" b
JOIN "实施_课程" e ON CAST(e.编号 AS CHAR(36)) = TRIM(b.实施_课程编号)
LEFT JOIN "课表" kb ON kb.课编号 = e.科目编号
LEFT JOIN "教员表" jy ON TRIM(jy.教员编号) = TRIM(e.教员编号)
WHERE COALESCE(b.删除状态, 0) = 0
<if test="jybh != null and jybh != ''">
AND e.教员编号 = #{jybh}
</if>
<if test="nd != null">
AND b.年度 = #{nd}
</if>
ORDER BY b.年度 DESC, b.日期 DESC, b.节次 ASC
</select>
</mapper> </mapper>
@@ -2,10 +2,17 @@ package com.roomroot.jwgl.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.roomroot.jwgl.dto.jys.TeachingTaskQuery;
import com.roomroot.jwgl.entity.JXRW; import com.roomroot.jwgl.entity.JXRW;
import com.roomroot.jwgl.vo.jys.TeachingOfficeBookCourseVO;
import com.roomroot.jwgl.vo.jys.TeachingOfficeBookVO;
import com.roomroot.jwgl.vo.jys.TeachingTaskSquadVO;
import com.roomroot.jwgl.vo.jys.TeachingTaskVO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.util.List;
/** /**
* 教学任务 Mapper * 教学任务 Mapper
*/ */
@@ -20,4 +27,31 @@ public interface TeachingTaskMapper extends BaseMapper<JXRW> {
* @return 分页结果 * @return 分页结果
*/ */
Page<JXRW> selectPageList(Page<JXRW> page, @Param("jxrw") JXRW jxrw); Page<JXRW> selectPageList(Page<JXRW> page, @Param("jxrw") JXRW jxrw);
/**
* 教学任务管理分页(含教研室数、学员队数、合班前后课程任务/学时)。
*/
Page<TeachingTaskVO> selectManagePage(Page<TeachingTaskVO> page, @Param("cond") TeachingTaskQuery cond);
/**
* 教研室任务书列表(含课程任务数、完成指定数)。
*/
List<TeachingOfficeBookVO> selectOfficeBooks(@Param("jxrwbh") String jxrwbh);
/**
* 教学任务已关联学员队。
*/
List<TeachingTaskSquadVO> selectBoundSquads(@Param("jxrwbh") String jxrwbh);
/**
* 某学期可选学员队(未占用或占用当前任务)。
*/
List<TeachingTaskSquadVO> selectAvailableSquads(@Param("nd") Integer nd,
@Param("xqdc") Integer xqdc, @Param("jxrwbh") String jxrwbh);
/**
* 教研室任务书课程明细。
*/
List<TeachingOfficeBookCourseVO> selectOfficeBookCourses(@Param("jxrwbh") String jxrwbh,
@Param("jysdh") String jysdh);
} }
@@ -38,4 +38,194 @@
ORDER BY 编号 ORDER BY 编号
</select> </select>
<sql id="CourseTaskJoin">
FROM "学员队任务表" r
INNER JOIN "学员队年度学期基本信息表" s ON s."编号" = r."学员队学期编号"
WHERE s."教学任务编号" = t."编号"
AND NVL(r.DEL_FLAG, 0) = 0
AND NVL(s.DEL_FLAG, 0) = 0
</sql>
<select id="selectManagePage" resultType="com.roomroot.jwgl.vo.jys.TeachingTaskVO">
SELECT
t."编号" AS bh,
t."任务名称" AS rwmc,
t."年度" AS nd,
(SELECT MAX(s0."学期第次")
FROM "学员队年度学期基本信息表" s0
WHERE s0."教学任务编号" = t."编号"
AND NVL(s0.DEL_FLAG, 0) = 0) AS xqdc,
t."状态" AS zt,
t."发布时间" AS fbsj,
t."创建时间" AS cjsj,
t."结束时间" AS jssj,
(SELECT COUNT(1)
FROM "教研室任务书" b
WHERE b."教学任务编号" = t."编号"
AND NVL(b.DEL_FLAG, 0) = 0) AS jyss,
(SELECT COUNT(1)
FROM "学员队年度学期基本信息表" s
WHERE s."教学任务编号" = t."编号"
AND NVL(s.DEL_FLAG, 0) = 0) AS xyds,
(SELECT COUNT(1)
FROM "学员队任务表" r
INNER JOIN "学员队年度学期基本信息表" s ON s."编号" = r."学员队学期编号"
WHERE s."教学任务编号" = t."编号"
AND NVL(r.DEL_FLAG, 0) = 0
AND NVL(s.DEL_FLAG, 0) = 0) AS hbqkcrws,
(SELECT NVL(SUM(r."学时"), 0)
FROM "学员队任务表" r
INNER JOIN "学员队年度学期基本信息表" s ON s."编号" = r."学员队学期编号"
WHERE s."教学任务编号" = t."编号"
AND NVL(r.DEL_FLAG, 0) = 0
AND NVL(s.DEL_FLAG, 0) = 0) AS hbqzxs,
(SELECT COUNT(1) FROM (
SELECT CASE
WHEN r."课次序号" IS NULL THEN r."编号"
ELSE TO_CHAR(r."课次序号")
END AS gid
FROM "学员队任务表" r
INNER JOIN "学员队年度学期基本信息表" s ON s."编号" = r."学员队学期编号"
WHERE s."教学任务编号" = t."编号"
AND NVL(r.DEL_FLAG, 0) = 0
AND NVL(s.DEL_FLAG, 0) = 0
GROUP BY CASE
WHEN r."课次序号" IS NULL THEN r."编号"
ELSE TO_CHAR(r."课次序号")
END
) g) AS hbhkcrws,
(SELECT NVL(SUM(g.mx), 0) FROM (
SELECT MAX(r."学时") AS mx
FROM "学员队任务表" r
INNER JOIN "学员队年度学期基本信息表" s ON s."编号" = r."学员队学期编号"
WHERE s."教学任务编号" = t."编号"
AND NVL(r.DEL_FLAG, 0) = 0
AND NVL(s.DEL_FLAG, 0) = 0
GROUP BY CASE
WHEN r."课次序号" IS NULL THEN r."编号"
ELSE TO_CHAR(r."课次序号")
END
) g) AS hbhzxs
FROM "教学任务" t
<where>
AND NVL(t.DEL_FLAG, 0) = 0
<if test="cond != null and cond.rwmc != null and cond.rwmc != ''">
AND t."任务名称" LIKE CONCAT('%', #{cond.rwmc}, '%')
</if>
<if test="cond != null and cond.nd != null">
AND t."年度" = #{cond.nd}
</if>
<if test="cond != null and cond.zt != null and cond.zt != ''">
AND t."状态" = #{cond.zt}
</if>
<if test="cond != null and cond.xqdc != null">
AND EXISTS (
SELECT 1 FROM "学员队年度学期基本信息表" sx
WHERE sx."教学任务编号" = t."编号"
AND sx."学期第次" = #{cond.xqdc}
AND NVL(sx.DEL_FLAG, 0) = 0
)
</if>
</where>
ORDER BY t."创建时间" DESC, t."编号" DESC
</select>
<select id="selectOfficeBooks" resultType="com.roomroot.jwgl.vo.jys.TeachingOfficeBookVO">
SELECT
b."编号" AS bh,
b."教学任务编号" AS jxrwbh,
b."教研室代号" AS jysdh,
j."教研室名称" AS jysmc,
b."状态" AS zt,
b."上报时间" AS sbsj,
(SELECT COUNT(1)
FROM "学员队任务表" r
INNER JOIN "学员队年度学期基本信息表" s ON s."编号" = r."学员队学期编号"
WHERE s."教学任务编号" = b."教学任务编号"
AND r."教研室代号" = b."教研室代号"
AND NVL(r.DEL_FLAG, 0) = 0
AND NVL(s.DEL_FLAG, 0) = 0) AS xydkcrws,
(SELECT COUNT(1)
FROM "学员队任务表" r
INNER JOIN "学员队年度学期基本信息表" s ON s."编号" = r."学员队学期编号"
WHERE s."教学任务编号" = b."教学任务编号"
AND r."教研室代号" = b."教研室代号"
AND r."教研室计划教员编号" IS NOT NULL
AND r."教研室计划教员编号" != ''
AND NVL(r.DEL_FLAG, 0) = 0
AND NVL(s.DEL_FLAG, 0) = 0) AS wczds
FROM "教研室任务书" b
LEFT JOIN "教研室表" j ON j."教研室代号" = b."教研室代号"
WHERE b."教学任务编号" = #{jxrwbh}
AND NVL(b.DEL_FLAG, 0) = 0
ORDER BY b."教研室代号"
</select>
<sql id="SquadSelect">
SELECT
s."编号" AS xydxqbh,
s."学员队编号" AS xydbh,
d."学员队名称" AS xydmc,
d."年级" AS nj,
d."专业代号" AS zydh,
z."专业名称" AS zymc,
d."学员队人数" AS xydrs,
s."年度" AS nd,
s."学期第次" AS xqdc,
s."开学日期" AS kxrq,
s."结束日期" AS jsrq,
CASE
WHEN s."教学任务编号" IS NOT NULL
AND s."教学任务编号" != ''
AND (#{jxrwbh} IS NULL OR s."教学任务编号" != #{jxrwbh})
THEN 1 ELSE 0
END AS occupied
FROM "学员队年度学期基本信息表" s
LEFT JOIN "学员队表" d ON d."学员队编号" = s."学员队编号"
LEFT JOIN "专业表" z ON z."专业代号" = d."专业代号"
</sql>
<select id="selectBoundSquads" resultType="com.roomroot.jwgl.vo.jys.TeachingTaskSquadVO">
<include refid="SquadSelect"/>
WHERE s."教学任务编号" = #{jxrwbh}
AND NVL(s.DEL_FLAG, 0) = 0
ORDER BY d."年级", d."学员队名称"
</select>
<select id="selectAvailableSquads" resultType="com.roomroot.jwgl.vo.jys.TeachingTaskSquadVO">
<include refid="SquadSelect"/>
WHERE NVL(s.DEL_FLAG, 0) = 0
AND s."年度" = #{nd}
AND s."学期第次" = #{xqdc}
AND (
s."教学任务编号" IS NULL
OR s."教学任务编号" = ''
OR (#{jxrwbh} IS NOT NULL AND s."教学任务编号" = #{jxrwbh})
)
ORDER BY d."年级", d."学员队名称"
</select>
<select id="selectOfficeBookCourses" resultType="com.roomroot.jwgl.vo.jys.TeachingOfficeBookCourseVO">
SELECT
r."编号" AS rwbh,
r."课编号" AS kbh,
k."课名称" AS kmc,
r."课类型" AS klx,
r."学时" AS xs,
r."学员队编号" AS xydbh,
d."学员队名称" AS xydmc,
r."教研室计划教员编号" AS jysjhjybh,
jy."教员姓名" AS jysjhjyxm
FROM "学员队任务表" r
INNER JOIN "学员队年度学期基本信息表" s ON s."编号" = r."学员队学期编号"
LEFT JOIN "课表" k ON k."课编号" = r."课编号"
LEFT JOIN "学员队表" d ON d."学员队编号" = r."学员队编号"
LEFT JOIN "教员表" jy ON jy."教员编号" = r."教研室计划教员编号"
WHERE s."教学任务编号" = #{jxrwbh}
AND r."教研室代号" = #{jysdh}
AND NVL(r.DEL_FLAG, 0) = 0
AND NVL(s.DEL_FLAG, 0) = 0
ORDER BY d."学员队名称", k."课名称"
</select>
</mapper> </mapper>
@@ -0,0 +1,18 @@
package com.roomroot.jwgl.mapper;
import com.roomroot.jwgl.vo.jwtest.PkLessonVO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 排课测试全查。
*/
@Mapper
public interface TestPkMapper {
/**
* 查询全部排课记录,无筛选条件。
*/
List<PkLessonVO> selectAll();
}
@@ -0,0 +1,67 @@
<?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.roomroot.jwgl.mapper.TestPkMapper">
<!--
排课全查:实施_课程表为课次主表,关联课表、教员表、学员队表、教室表。
开始/结束时间取节次时间表;学年学期、周次按学期开学日期推算;应到人数优先课次绑定人数。
不做业务筛选。
-->
<select id="selectAll" resultType="com.roomroot.jwgl.vo.jwtest.PkLessonVO">
SELECT
COALESCE(NULLIF(TRIM(MAX(s."教学内容")), ''), MAX(k."课名称")) AS ktmc,
MAX(k."课名称") AS kcmc,
MAX(jy."教员姓名") AS jymc,
WM_CONCAT(DISTINCT xyd."学员队名称") AS bjmc,
MAX(js."教室名称") AS jsmc,MAX(jxlb.教学楼名称) AS jxlmc,
TO_CHAR(s."日期", 'YYYY-MM-DD') AS skrq,
MAX(jc."开始时间") AS kssj,
MAX(jc."结束时间") AS jssj,
CASE
WHEN EXTRACT(MONTH FROM MAX(xq."开学日期")) >= 8
THEN EXTRACT(YEAR FROM MAX(xq."开学日期")) || '-' || (EXTRACT(YEAR FROM MAX(xq."开学日期")) + 1)
ELSE (EXTRACT(YEAR FROM MAX(xq."开学日期")) - 1) || '-' || EXTRACT(YEAR FROM MAX(xq."开学日期"))
END
|| '学年第'
|| TRIM(LEADING '0' FROM SUBSTR(CAST(MAX(xq."年度") AS VARCHAR), 5, 2))
|| '学期' AS xnxq,
CAST(
FLOOR((TRUNC(s."日期") - TRUNC(MAX(xq."开学日期"))) / 7) + 1
AS INT
) AS zc,
(
SELECT SUM(t2."人数")
FROM "实施_课程表_学员队" t2
WHERE TRIM(t2."实施_课程表编号") = TRIM(s."编号")
) AS ydrs,
MAX(NVL(TO_CHAR(kcb."备注"), NVL(s."教务备注", s."教员备注"))) AS bz
FROM "实施_课程表_学员队" tx
INNER JOIN "实施_课程表" s
ON TRIM(s."编号") = TRIM(tx."实施_课程表编号")
LEFT JOIN "实施_课程" c
ON REPLACE(LOWER(TRIM(CAST(c."编号" AS CHAR(36)))), '-', '')
= REPLACE(LOWER(TRIM(s."实施_课程编号")), '-', '')
LEFT JOIN "课表" k
ON k."课编号" = c."科目编号"
LEFT JOIN "课程表" kcb
ON kcb."年度" = s."年度"
AND kcb."安排时间" = s."计划时间安排"
AND TRIM(kcb."教员编号") = TRIM(c."教员编号")
LEFT JOIN "教员表" jy
ON TRIM(jy."教员编号") = TRIM(NVL(kcb."授课教员编号", c."教员编号"))
LEFT JOIN "学员队表" xyd
ON xyd."学员队编号" = tx."学员队编号"
LEFT JOIN "教室表" js
ON js."教室编号" = NVL(kcb."教室编号", c."教室编号")
LEFT JOIN "节次时间表" jc
ON TRIM(jc."节次索引") = TRIM(CAST(s."节次" AS VARCHAR))
LEFT JOIN "学期" xq
ON CAST(xq."年度" AS VARCHAR) = CAST(s."年度" AS VARCHAR)
AND TRUNC(s."日期") &gt;= TRUNC(xq."开学日期")
AND TRUNC(s."日期") &lt;= TRUNC(xq."结束日期")
LEFT JOIN "教学楼表" jxlb on jxlb.教学楼代号=js.教学楼代号
WHERE NVL(s."删除状态", 0) = 0
GROUP BY s."编号", s."日期", s."节次", s."年度"
</select>
</mapper>
@@ -20,6 +20,7 @@ import com.roomroot.jwgl.dto.courserunning.StudentLeaveQueryDTO;
import com.roomroot.jwgl.dto.courserunning.OperationAnalysisQueryDTO; import com.roomroot.jwgl.dto.courserunning.OperationAnalysisQueryDTO;
import com.roomroot.jwgl.dto.courserunning.ScheduleAdjustStrategyDTO; import com.roomroot.jwgl.dto.courserunning.ScheduleAdjustStrategyDTO;
import com.roomroot.jwgl.unit.PageResult; import com.roomroot.jwgl.unit.PageResult;
import com.roomroot.jwgl.vo.courserunning.AdjustableLessonVO;
import com.roomroot.jwgl.vo.courserunning.CourseRunningImportResultVO; import com.roomroot.jwgl.vo.courserunning.CourseRunningImportResultVO;
import com.roomroot.jwgl.vo.courserunning.ScheduleAdjustApplyVO; import com.roomroot.jwgl.vo.courserunning.ScheduleAdjustApplyVO;
import com.roomroot.jwgl.vo.courserunning.ScheduleAdjustDetailVO; import com.roomroot.jwgl.vo.courserunning.ScheduleAdjustDetailVO;
@@ -178,6 +179,14 @@ public interface CourseRunningImportService {
*/ */
PageResult<ScheduleAdjustApplyVO> queryScheduleAdjustList(ScheduleAdjustQueryDTO query); PageResult<ScheduleAdjustApplyVO> queryScheduleAdjustList(ScheduleAdjustQueryDTO query);
/**
* 查询当前教员可供调课的课次,关联学员队任务表、课表、课程表。
*
* @param nd 年度,可空
* @return 可选课次列表
*/
List<AdjustableLessonVO> listAdjustableLessons(Integer nd);
/** /**
* 查询单个调课申请的完整详情。 * 查询单个调课申请的完整详情。
* <p> * <p>
@@ -0,0 +1,40 @@
package com.roomroot.jwgl.service;
import com.roomroot.jwgl.dto.jys.ElectiveCourseQuery;
import com.roomroot.jwgl.dto.jys.ElectiveCourseSaveDTO;
import com.roomroot.jwgl.unit.PageQuery;
import com.roomroot.jwgl.unit.PageResult;
import com.roomroot.jwgl.vo.jys.ElectiveCourseVO;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* 选修课管理。
* <p>数据来源:学员队任务表 INNER JOIN 学员队表 INNER JOIN 课表,课类型含“选修”。</p>
*/
public interface ElectiveCourseService {
PageResult<ElectiveCourseVO> pageList(PageQuery query, ElectiveCourseQuery cond);
void add(ElectiveCourseSaveDTO dto);
int batchOpenRegistration(List<String> bhList);
int batchCancelOpenRegistration(List<String> bhList);
int batchStopRegistration(List<String> bhList);
int batchReverseClassRange(List<String> bhList);
void exportClassList(ElectiveCourseQuery cond, HttpServletResponse response);
void exportStudentExcel(List<String> bhList, HttpServletResponse response);
void exportStudentWord(List<String> bhList, HttpServletResponse response);
void downloadTemplate(HttpServletResponse response);
int importData(MultipartFile file) throws Exception;
}
@@ -1,6 +1,12 @@
package com.roomroot.jwgl.service; package com.roomroot.jwgl.service;
import com.roomroot.jwgl.dto.kcb.TimetableQuery;
import com.roomroot.jwgl.entity.KCB; import com.roomroot.jwgl.entity.KCB;
import com.roomroot.jwgl.unit.PageQuery;
import com.roomroot.jwgl.unit.PageResult;
import com.roomroot.jwgl.vo.kcb.ClassTimetableVO;
import com.roomroot.jwgl.vo.kcb.DailyWeeklyTimetableVO;
import jakarta.servlet.http.HttpServletResponse;
import java.util.List; import java.util.List;
@@ -51,4 +57,34 @@ public interface KCBService {
* @return 所有数据列表 * @return 所有数据列表
*/ */
List<KCB> list(); List<KCB> list();
/**
* 今日课表。未传年度时按当前时间取本学期。
*/
List<DailyWeeklyTimetableVO> listToday(TimetableQuery cond);
/**
* 本周课表(周一至周日)。未传年度时按当前时间取本学期。
*/
List<DailyWeeklyTimetableVO> listWeek(TimetableQuery cond);
/**
* 班次课表。未传年度时按当前时间取本学期,可按队别班次筛选。
*/
PageResult<ClassTimetableVO> pageClassTimetable(PageQuery query, TimetableQuery cond);
/**
* 下载学期教学实施计划(课次明细 Excel)。
*/
void exportSemesterPlan(TimetableQuery cond, HttpServletResponse response);
/**
* 下载学期成绩表 Excel。
*/
void exportSemesterGrades(TimetableQuery cond, HttpServletResponse response);
/**
* 班次课程列表另存 Excel。
*/
void exportClassCourses(TimetableQuery cond, HttpServletResponse response);
} }
@@ -0,0 +1,39 @@
package com.roomroot.jwgl.service;
import com.roomroot.jwgl.dto.jys.TeachingTaskQuery;
import com.roomroot.jwgl.dto.jys.TeachingTaskSaveDTO;
import com.roomroot.jwgl.unit.PageQuery;
import com.roomroot.jwgl.unit.PageResult;
import com.roomroot.jwgl.vo.jys.TeachingOfficeBookCourseVO;
import com.roomroot.jwgl.vo.jys.TeachingOfficeBookVO;
import com.roomroot.jwgl.vo.jys.TeachingTaskDetailVO;
import com.roomroot.jwgl.vo.jys.TeachingTaskSquadVO;
import com.roomroot.jwgl.vo.jys.TeachingTaskVO;
import java.util.List;
/**
* 教学任务管理(机关发布,关联教研室任务书与学员队,供排课使用)。
*/
public interface TeachingTaskManageService {
PageResult<TeachingTaskVO> pageList(PageQuery query, TeachingTaskQuery cond);
TeachingTaskDetailVO getDetail(String bh);
void add(TeachingTaskSaveDTO dto);
void update(TeachingTaskSaveDTO dto);
void delete(String bh);
int publish(String bh);
List<TeachingOfficeBookVO> listOfficeBooks(String jxrwbh);
List<TeachingOfficeBookCourseVO> listOfficeBookCourses(String jxrwbh, String jysdh);
List<TeachingTaskSquadVO> listBoundSquads(String jxrwbh);
List<TeachingTaskSquadVO> listAvailableSquads(Integer nd, Integer xqdc, String jxrwbh);
}
@@ -2,17 +2,18 @@ package com.roomroot.jwgl.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.roomroot.common.utils.SecurityUtils;
import com.roomroot.common.utils.StringUtils;
import com.roomroot.jwgl.dto.courserunning.*; import com.roomroot.jwgl.dto.courserunning.*;
import com.roomroot.jwgl.entity.*; import com.roomroot.jwgl.entity.*;
import com.roomroot.jwgl.mapper.*; import com.roomroot.jwgl.mapper.*;
import com.roomroot.jwgl.vo.courserunning.*;
import com.roomroot.jwgl.mapper.*;
import com.roomroot.jwgl.service.CourseRunningImportService; import com.roomroot.jwgl.service.CourseRunningImportService;
import com.roomroot.jwgl.service.DictDataService; import com.roomroot.jwgl.service.DictDataService;
import com.roomroot.jwgl.unit.BusinessException; import com.roomroot.jwgl.unit.BusinessException;
import com.roomroot.jwgl.unit.PageResult; import com.roomroot.jwgl.unit.PageResult;
import com.roomroot.jwgl.utils.BasicManagementConstants; import com.roomroot.jwgl.utils.BasicManagementConstants;
import com.roomroot.jwgl.utils.ExcelExportUtil; import com.roomroot.jwgl.utils.ExcelExportUtil;
import com.roomroot.jwgl.utils.JwglRoleHelper;
import com.roomroot.jwgl.utils.UuidUtil; import com.roomroot.jwgl.utils.UuidUtil;
import com.roomroot.jwgl.validator.StudentLeaveValidator; import com.roomroot.jwgl.validator.StudentLeaveValidator;
import com.roomroot.jwgl.vo.courserunning.*; import com.roomroot.jwgl.vo.courserunning.*;
@@ -102,6 +103,15 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
@Resource @Resource
private SSDKSQMapper ssdksqMapper; private SSDKSQMapper ssdksqMapper;
@Resource
private JwglRoleHelper jwglRoleHelper;
@Resource
private StudentTeamTaskMapper studentTeamTaskMapper;
@Resource
private KCBMapper kcbMapper;
/** /**
* 实施_调课申请审批 Mapper,用于调课申请审批记录的数据访问。 * 实施_调课申请审批 Mapper,用于调课申请审批记录的数据访问。
*/ */
@@ -863,35 +873,33 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
*/ */
@Override @Override
public PageResult<ScheduleAdjustApplyVO> queryScheduleAdjustList(ScheduleAdjustQueryDTO query) { public PageResult<ScheduleAdjustApplyVO> queryScheduleAdjustList(ScheduleAdjustQueryDTO query) {
// 步骤1:校验查询参数,确保分页参数有效
if (query == null) { if (query == null) {
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "查询参数不能为空"); throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "查询参数不能为空");
} }
if (query.getPageNum() == null || query.getPageSize() == null) { if (query.getPageNum() == null || query.getPageSize() == null) {
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "分页参数不能为空"); throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "分页参数不能为空");
} }
applyScheduleAdjustDataScope(query);
// 步骤2:构建MyBatis-Plus分页对象
Page<ScheduleAdjustApplyVO> page = new Page<>(query.getPageNum(), query.getPageSize()); Page<ScheduleAdjustApplyVO> page = new Page<>(query.getPageNum(), query.getPageSize());
// 步骤3:将日期范围转换为字符串格式,便于XML中直接拼接SQL
String cjsjStartStr = query.getCjsjStart() != null ? query.getCjsjStart().format(DATE_TIME_FORMATTER) : null; String cjsjStartStr = query.getCjsjStart() != null ? query.getCjsjStart().format(DATE_TIME_FORMATTER) : null;
String cjsjEndStr = query.getCjsjEnd() != null ? query.getCjsjEnd().format(DATE_TIME_FORMATTER) : null; String cjsjEndStr = query.getCjsjEnd() != null ? query.getCjsjEnd().format(DATE_TIME_FORMATTER) : null;
// 步骤4:调用Mapper执行分页查询,关联课程表和教员表
Page<ScheduleAdjustApplyVO> resultPage = ssdksqMapper.selectPageList( Page<ScheduleAdjustApplyVO> resultPage = ssdksqMapper.selectPageList(
page, page,
query.getSskcbbh(), query.getSskcbbh(),
query.getXydrwbh(),
query.getKbh(),
query.getSqjybh(), query.getSqjybh(),
query.getJysdh(),
query.getNd(), query.getNd(),
query.getJyspzzt(), query.getJyspzzt(),
query.getJyscszt(), query.getJyscszt(),
query.getJgspzt(),
query.getSczt(), query.getSczt(),
cjsjStartStr, cjsjStartStr,
cjsjEndStr cjsjEndStr
); );
// 步骤5:封装分页结果并返回
return new PageResult<>( return new PageResult<>(
resultPage.getRecords(), resultPage.getRecords(),
resultPage.getTotal(), resultPage.getTotal(),
@@ -900,6 +908,73 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
); );
} }
@Override
public List<AdjustableLessonVO> listAdjustableLessons(Integer nd) {
if (jwglRoleHelper.isDepartmentPersonnel()) {
throw new BusinessException(BasicManagementConstants.FORBIDDEN, "机关人员仅可查看和审批调课申请");
}
if (jwglRoleHelper.isResearchOffice()) {
throw new BusinessException(BasicManagementConstants.FORBIDDEN, "教研室仅可查看和审批本室调课申请");
}
String teacherId = jwglRoleHelper.requireTeacherId();
return ssdksqMapper.selectAdjustableLessons(teacherId, nd);
}
private void applyScheduleAdjustDataScope(ScheduleAdjustQueryDTO query) {
if (jwglRoleHelper.isAdmin() || jwglRoleHelper.isDepartmentPersonnel()) {
return;
}
if (jwglRoleHelper.isResearchOffice()) {
query.setJysdh(jwglRoleHelper.requireResearchOfficeId());
query.setSqjybh(null);
return;
}
if (jwglRoleHelper.isTeacher()) {
query.setSqjybh(jwglRoleHelper.requireTeacherId());
query.setJysdh(null);
return;
}
throw new BusinessException(BasicManagementConstants.FORBIDDEN, "无权查看调课申请");
}
private void assertCanViewScheduleAdjust(SSDKSQ apply) {
if (jwglRoleHelper.isAdmin() || jwglRoleHelper.isDepartmentPersonnel()) {
return;
}
if (jwglRoleHelper.isResearchOffice()) {
String officeId = jwglRoleHelper.requireResearchOfficeId();
String applyOffice = apply.getJysdh();
if (StringUtils.isEmpty(applyOffice) && StringUtils.isNotEmpty(apply.getSqjybh())) {
JYB teacher = jybMapper.selectById(apply.getSqjybh());
applyOffice = teacher == null ? null : teacher.getJysdh();
}
if (applyOffice == null || !officeId.equals(applyOffice.trim())) {
throw new BusinessException(BasicManagementConstants.FORBIDDEN, "只能查看本教研室的调课申请");
}
return;
}
if (jwglRoleHelper.isTeacher()) {
String teacherId = jwglRoleHelper.requireTeacherId();
if (apply.getSqjybh() == null || !teacherId.equals(apply.getSqjybh().trim())) {
throw new BusinessException(BasicManagementConstants.FORBIDDEN, "只能查看本人提交的调课申请");
}
return;
}
throw new BusinessException(BasicManagementConstants.FORBIDDEN, "无权查看调课申请");
}
private String currentOperatorId() {
try {
String username = SecurityUtils.getUsername();
if (StringUtils.isNotEmpty(username)) {
return username;
}
} catch (Exception ignored) {
// 未登录时由调用方继续校验
}
return null;
}
/** /**
* 查询单个调课申请的完整详情。 * 查询单个调课申请的完整详情。
* <p> * <p>
@@ -922,6 +997,10 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
if (detail == null) { if (detail == null) {
throw new BusinessException(BasicManagementConstants.NOT_FOUND, "未找到该调课申请"); throw new BusinessException(BasicManagementConstants.NOT_FOUND, "未找到该调课申请");
} }
SSDKSQ apply = ssdksqMapper.selectById(ssdksqbh);
if (apply != null) {
assertCanViewScheduleAdjust(apply);
}
// 步骤3:查询关联的机关审批记录列表 // 步骤3:查询关联的机关审批记录列表
detail.setAuditList(ssdksqspMapper.selectBySsdksqbh(ssdksqbh)); detail.setAuditList(ssdksqspMapper.selectBySsdksqbh(ssdksqbh));
@@ -957,22 +1036,24 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public String submitScheduleAdjust(ScheduleAdjustApplyDTO dto) { public String submitScheduleAdjust(ScheduleAdjustApplyDTO dto) {
// 步骤1:校验调课申请参数
if (dto == null) { if (dto == null) {
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "调课申请参数不能为空"); throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "调课申请参数不能为空");
} }
if (dto.getSskcbbh() == null || dto.getSskcbbh().trim().isEmpty()) { if (jwglRoleHelper.isDepartmentPersonnel()) {
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "课次编号不能为空"); throw new BusinessException(BasicManagementConstants.FORBIDDEN, "机关人员仅可查看和审批,不能提交调课申请");
} }
if (dto.getSqjybh() == null || dto.getSqjybh().trim().isEmpty()) { if (jwglRoleHelper.isResearchOffice()) {
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "申请教员编号不能为空"); throw new BusinessException(BasicManagementConstants.FORBIDDEN, "教研室仅可查看和审批本室申请,不能提交调课申请");
}
if (StringUtils.isEmpty(dto.getSskcbbh())) {
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "课次编号不能为空");
} }
if (dto.getSy() == null || dto.getSy().trim().isEmpty()) { if (dto.getSy() == null || dto.getSy().trim().isEmpty()) {
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "调课事由不能为空"); throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "调课事由不能为空");
} }
// 步骤2:查询课次实体,校验课次是否存在 String teacherId = jwglRoleHelper.requireTeacherId();
SSKCB lesson = sskcbMapper.selectById(dto.getSskcbbh()); SSKCB lesson = sskcbMapper.selectById(dto.getSskcbbh().trim());
if (lesson == null) { if (lesson == null) {
throw new BusinessException(BasicManagementConstants.NOT_FOUND, "课次不存在"); throw new BusinessException(BasicManagementConstants.NOT_FOUND, "课次不存在");
} }
@@ -980,58 +1061,63 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "该课次已删除,不允许申请调课"); throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "该课次已删除,不允许申请调课");
} }
// 调课时间段策略校验 AdjustableLessonVO picked = null;
validateScheduleAdjustTimeLimitStrategy(dto.getRq()); List<AdjustableLessonVO> mine = ssdksqMapper.selectAdjustableLessons(teacherId, lesson.getNd());
if (mine != null) {
for (AdjustableLessonVO item : mine) {
if (lesson.getBh().equals(item.getSskcbbh())) {
picked = item;
break;
}
}
}
if (picked == null) {
throw new BusinessException(BasicManagementConstants.FORBIDDEN, "只能对自己任课的课次申请调课");
}
// 判断是否命中免审批策略 validateScheduleAdjustTimeLimitStrategy(dto.getRq());
boolean autoApproved = matchAutoApproveStrategy(); boolean autoApproved = matchAutoApproveStrategy();
// 步骤3:构建并保存调课申请主表实体
SSDKSQ apply = new SSDKSQ(); SSDKSQ apply = new SSDKSQ();
String ssdksqbh = UuidUtil.getOriginalUUID(); // 生成唯一调课申请编号 String ssdksqbh = UuidUtil.getOriginalUUID();
apply.setBh(ssdksqbh); apply.setBh(ssdksqbh);
apply.setSskcbbh(dto.getSskcbbh()); // 课次编号 apply.setSskcbbh(lesson.getBh());
apply.setSqjybh(dto.getSqjybh()); // 申请教员编号 apply.setXydrwbh(StringUtils.isNotEmpty(dto.getXydrwbh()) ? dto.getXydrwbh() : picked.getXydrwbh());
apply.setSy(dto.getSy()); // 调课事由 apply.setKbh(StringUtils.isNotEmpty(dto.getKbh()) ? dto.getKbh() : picked.getKbh());
apply.setRq(dto.getRq()); // 新日期 apply.setKcbbh(StringUtils.isNotEmpty(dto.getKcbbh()) ? dto.getKcbbh() : picked.getKcbbh());
apply.setJc(dto.getJc()); // 新节次 apply.setJysdh(picked.getJysdh());
apply.setNd(dto.getNd()); // 年度 apply.setYjsbh(picked.getJsbh());
apply.setJxnr(dto.getJxnr()); // 教学内容 apply.setXjsbh(resolveNewClassroom(dto));
apply.setJxyd(dto.getJxyd()); // 教学要点 apply.setSqjybh(teacherId);
apply.setJxff(dto.getJxff()); // 教学方法 apply.setSy(dto.getSy());
apply.setJxbzbz(dto.getJxbzbz()); // 教学保障备注 apply.setRq(dto.getRq());
apply.setYcxx(dto.getYcxx()); // 用车信息 apply.setJc(dto.getJc());
apply.setBz(dto.getBz()); // 备注 apply.setNd(dto.getNd() != null ? dto.getNd() : lesson.getNd());
// 将原日期节次描述追加到备注中(ydsjap字段类型为Integer,用于存储其他业务数据) apply.setJxnr(dto.getJxnr());
apply.setJxyd(dto.getJxyd());
apply.setJxff(dto.getJxff());
apply.setJxbzbz(dto.getJxbzbz());
apply.setYcxx(dto.getYcxx());
String originalDesc = buildOriginalScheduleDesc(lesson); String originalDesc = buildOriginalScheduleDesc(lesson);
if (dto.getBz() != null && !dto.getBz().trim().isEmpty()) { if (dto.getBz() != null && !dto.getBz().trim().isEmpty()) {
apply.setBz(dto.getBz() + " | " + originalDesc); apply.setBz(dto.getBz() + " | " + originalDesc);
} else { } else {
apply.setBz(originalDesc); apply.setBz(originalDesc);
} }
// 命中免审批策略时在备注追加标记,便于教务人员识别
if (autoApproved) { if (autoApproved) {
apply.setBz((apply.getBz() == null ? "" : apply.getBz() + " | ") + "[免审批策略自动通过]"); apply.setBz((apply.getBz() == null ? "" : apply.getBz() + " | ") + "[免审批策略自动通过]");
}
// 审批状态初始化:未审批、未查收、未删除
if (autoApproved) {
// 命中免审批策略:教研室和教学系审批状态直接设为已通过,跳过三级审批
apply.setJyspzzt(1); apply.setJyspzzt(1);
apply.setJxxspzzt(1);
} else { } else {
apply.setJyspzzt(0); apply.setJyspzzt(0);
} }
apply.setJyscszt(0); apply.setJyscszt(0);
apply.setSczt(0); apply.setSczt(0);
// 时间字段 apply.setFhzt(0);
apply.setDk(1);
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();
apply.setCreateTime(now); apply.setCjsj(now);
apply.setUpdateTime(now);
// 步骤4:插入调课申请主表数据
ssdksqMapper.insert(apply); ssdksqMapper.insert(apply);
// 步骤5:保存新教室关联数据
if (dto.getRoomList() != null && !dto.getRoomList().isEmpty()) { if (dto.getRoomList() != null && !dto.getRoomList().isEmpty()) {
for (AdjustRoomDTO roomDto : dto.getRoomList()) { for (AdjustRoomDTO roomDto : dto.getRoomList()) {
DKSQJS roomEntity = new DKSQJS(); DKSQJS roomEntity = new DKSQJS();
@@ -1041,9 +1127,13 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
roomEntity.setBz(roomDto.getBz()); roomEntity.setBz(roomDto.getBz());
dksqjsMapper.insert(roomEntity); dksqjsMapper.insert(roomEntity);
} }
} else if (StringUtils.isNotEmpty(apply.getXjsbh())) {
DKSQJS roomEntity = new DKSQJS();
roomEntity.setBh(UuidUtil.getOriginalUUID());
roomEntity.setDksqbh(ssdksqbh);
roomEntity.setJsbh(apply.getXjsbh());
dksqjsMapper.insert(roomEntity);
} }
// 步骤6:保存新辅助教员关联数据
if (dto.getTeacherList() != null && !dto.getTeacherList().isEmpty()) { if (dto.getTeacherList() != null && !dto.getTeacherList().isEmpty()) {
for (AdjustTeacherDTO teacherDto : dto.getTeacherList()) { for (AdjustTeacherDTO teacherDto : dto.getTeacherList()) {
DKSQFZJY teacherEntity = new DKSQFZJY(); DKSQFZJY teacherEntity = new DKSQFZJY();
@@ -1055,8 +1145,6 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
dksqfzjyMapper.insert(teacherEntity); dksqfzjyMapper.insert(teacherEntity);
} }
} }
// 步骤7:保存新学员队关联数据
if (dto.getTeamList() != null && !dto.getTeamList().isEmpty()) { if (dto.getTeamList() != null && !dto.getTeamList().isEmpty()) {
for (AdjustTeamDTO teamDto : dto.getTeamList()) { for (AdjustTeamDTO teamDto : dto.getTeamList()) {
DKSQXYD teamEntity = new DKSQXYD(); DKSQXYD teamEntity = new DKSQXYD();
@@ -1066,8 +1154,6 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
dksqxydMapper.insert(teamEntity); dksqxydMapper.insert(teamEntity);
} }
} }
// 步骤8:保存新保障明细关联数据
if (dto.getSupportList() != null && !dto.getSupportList().isEmpty()) { if (dto.getSupportList() != null && !dto.getSupportList().isEmpty()) {
for (AdjustSupportDTO supportDto : dto.getSupportList()) { for (AdjustSupportDTO supportDto : dto.getSupportList()) {
DKSQBZMX supportEntity = new DKSQBZMX(); DKSQBZMX supportEntity = new DKSQBZMX();
@@ -1080,19 +1166,54 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
} }
} }
// 步骤9:更新课次数据,将日期节次替换为调整后的新值 if (autoApproved) {
lesson.setRq(dto.getRq()); applyApprovedSchedule(apply);
lesson.setJc(dto.getJc()); }
lesson.setBdsj(now);
sskcbMapper.updateById(lesson);
// 步骤10:记录调课申请操作日志
recordOperationLog(ssdksqbh, "申请", "提交调课申请:" + ssdksqbh); recordOperationLog(ssdksqbh, "申请", "提交调课申请:" + ssdksqbh);
// 步骤11:返回调课申请编号
return ssdksqbh; return ssdksqbh;
} }
private XYDRWB findRelatedTeamTask(SSKC course, SSKCB lesson) {
if (course == null || StringUtils.isEmpty(course.getKmbh()) || lesson == null) {
return null;
}
List<SSKCBXYD> teams = sskcbxyMapper.selectBySskcbh(lesson.getBh());
String teamId = (teams == null || teams.isEmpty()) ? null : teams.get(0).getXydbh();
LambdaQueryWrapper<XYDRWB> wrapper = new LambdaQueryWrapper<XYDRWB>()
.eq(XYDRWB::getKbh, course.getKmbh())
.eq(XYDRWB::getJybh, course.getJybh())
.eq(lesson.getNd() != null, XYDRWB::getNd, lesson.getNd());
if (StringUtils.isNotEmpty(teamId)) {
wrapper.eq(XYDRWB::getXydbh, teamId);
}
wrapper.last("LIMIT 1");
return studentTeamTaskMapper.selectOne(wrapper);
}
private KCB findRelatedScheduleSlot(SSKC course) {
if (course == null || StringUtils.isEmpty(course.getJybh()) || course.getJykcxh() == null) {
return null;
}
LambdaQueryWrapper<KCB> wrapper = new LambdaQueryWrapper<KCB>()
.eq(KCB::getJybh, course.getJybh())
.eq(KCB::getKcxh, course.getJykcxh())
.eq(course.getNd() != null, KCB::getNd, course.getNd())
.last("LIMIT 1");
return kcbMapper.selectOne(wrapper);
}
private String resolveNewClassroom(ScheduleAdjustApplyDTO dto) {
if (StringUtils.isNotEmpty(dto.getXjsbh())) {
return dto.getXjsbh().trim();
}
if (dto.getRoomList() != null && !dto.getRoomList().isEmpty()
&& StringUtils.isNotEmpty(dto.getRoomList().get(0).getJsbh())) {
return dto.getRoomList().get(0).getJsbh().trim();
}
return null;
}
/** /**
* 教研室审批调课申请。 * 教研室审批调课申请。
* <p> * <p>
@@ -1105,10 +1226,18 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void auditByTeachingOffice(ScheduleAdjustAuditDTO dto) { public void auditByTeachingOffice(ScheduleAdjustAuditDTO dto) {
// 步骤1:校验审批参数
if (dto == null) { if (dto == null) {
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "审批参数不能为空"); throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "审批参数不能为空");
} }
if (jwglRoleHelper.isTeacher()) {
throw new BusinessException(BasicManagementConstants.FORBIDDEN, "教员无权审批调课申请");
}
if (jwglRoleHelper.isDepartmentPersonnel() && !jwglRoleHelper.isAdmin()) {
throw new BusinessException(BasicManagementConstants.FORBIDDEN, "机关人员请使用机关审批,不办理教研室审批");
}
if (!jwglRoleHelper.isAdmin() && !jwglRoleHelper.isResearchOffice()) {
throw new BusinessException(BasicManagementConstants.FORBIDDEN, "仅教研室可进行一审");
}
if (!"jys".equals(dto.getAuditRole())) { if (!"jys".equals(dto.getAuditRole())) {
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "审批角色不正确,应为jys"); throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "审批角色不正确,应为jys");
} }
@@ -1117,7 +1246,6 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "审批结果不正确,应为1(同意)、2(发回)或3(拒绝)"); throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "审批结果不正确,应为1(同意)、2(发回)或3(拒绝)");
} }
// 步骤2:查询调课申请实体,校验申请是否存在
SSDKSQ apply = ssdksqMapper.selectById(dto.getSsdksqbh()); SSDKSQ apply = ssdksqMapper.selectById(dto.getSsdksqbh());
if (apply == null) { if (apply == null) {
throw new BusinessException(BasicManagementConstants.NOT_FOUND, "调课申请不存在"); throw new BusinessException(BasicManagementConstants.NOT_FOUND, "调课申请不存在");
@@ -1125,33 +1253,33 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
if (apply.getSczt() != null && apply.getSczt() == 1) { if (apply.getSczt() != null && apply.getSczt() == 1) {
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "该调课申请已撤销,不允许审批"); throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "该调课申请已撤销,不允许审批");
} }
if (jwglRoleHelper.isResearchOffice()) {
// 步骤3:校验申请是否已审批,避免重复审批 String officeId = jwglRoleHelper.requireResearchOfficeId();
String applyOffice = apply.getJysdh();
if (StringUtils.isEmpty(applyOffice) && StringUtils.isNotEmpty(apply.getSqjybh())) {
JYB teacher = jybMapper.selectById(apply.getSqjybh());
applyOffice = teacher == null ? null : teacher.getJysdh();
}
if (applyOffice == null || !officeId.equals(applyOffice.trim())) {
throw new BusinessException(BasicManagementConstants.FORBIDDEN, "只能审批本教研室的调课申请");
}
}
if (apply.getJyspzzt() != null && apply.getJyspzzt() != 0) { if (apply.getJyspzzt() != null && apply.getJyspzzt() != 0) {
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "该调课申请已审批,无需重复审批"); throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "该调课申请已审批,无需重复审批");
} }
// 步骤4:更新调课申请主表的教研室审批状态
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();
apply.setJyspzzt(dto.getSpzt()); // 教研室审批状态 String auditor = StringUtils.isNotEmpty(dto.getSprbh()) ? dto.getSprbh() : currentOperatorId();
apply.setJyspzrbh(dto.getSprbh()); // 教研室审批人编号 apply.setJyspzzt(dto.getSpzt());
apply.setJyspzsj(now); // 教研室审批时间 apply.setJyspzrbh(auditor);
apply.setFhyj(dto.getFhyj()); // 发回意见 apply.setJyspzsj(now);
apply.setUpdateTime(now); // 更新时间 apply.setFhyj(dto.getFhyj());
if (dto.getSpzt() != null && dto.getSpzt() == 2) {
apply.setFhzt(1);
apply.setFhsj(now);
}
ssdksqMapper.updateById(apply); ssdksqMapper.updateById(apply);
// 步骤5:根据审批结果执行不同的后续处理
if (dto.getSpzt() == 3) {
// 拒绝:恢复课次原数据,标记申请最终结束
restoreLessonSchedule(apply);
} else if (dto.getSpzt() == 2) {
// 发回:发回教员修改,课次保留调整后数据,由教员重新申请
// 此处无需修改课次数据
} else {
// 同意:课次数据已由申请时更新,无需重复处理
}
// 步骤6:记录审批操作日志
recordOperationLog(apply.getBh(), "教研室审批", "教研室审批调课申请:" + apply.getBh() recordOperationLog(apply.getBh(), "教研室审批", "教研室审批调课申请:" + apply.getBh()
+ ",审批结果:" + dto.getSpzt() + ",审批意见:" + dto.getFhyj()); + ",审批结果:" + dto.getSpzt() + ",审批意见:" + dto.getFhyj());
} }
@@ -1288,11 +1416,13 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
|| (dto.getSpzt() != 1 && dto.getSpzt() != 2 && dto.getSpzt() != 3)) { || (dto.getSpzt() != 1 && dto.getSpzt() != 2 && dto.getSpzt() != 3)) {
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "审批结果不正确"); throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "审批结果不正确");
} }
if (dto.getJgbh() == null || dto.getJgbh().trim().isEmpty()) { if (jwglRoleHelper.isTeacher() || jwglRoleHelper.isResearchOffice()) {
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "机关编号不能为空"); throw new BusinessException(BasicManagementConstants.FORBIDDEN, "仅机关人员可进行终审");
}
if (!jwglRoleHelper.isAdmin() && !jwglRoleHelper.isDepartmentPersonnel()) {
throw new BusinessException(BasicManagementConstants.FORBIDDEN, "仅机关人员可进行终审");
} }
// 步骤2:查询调课申请实体
SSDKSQ apply = ssdksqMapper.selectById(dto.getSsdksqbh()); SSDKSQ apply = ssdksqMapper.selectById(dto.getSsdksqbh());
if (apply == null) { if (apply == null) {
throw new BusinessException(BasicManagementConstants.NOT_FOUND, "调课申请不存在"); throw new BusinessException(BasicManagementConstants.NOT_FOUND, "调课申请不存在");
@@ -1300,23 +1430,18 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
if (apply.getSczt() != null && apply.getSczt() == 1) { if (apply.getSczt() != null && apply.getSczt() == 1) {
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "该调课申请已撤销,不允许审批"); throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "该调课申请已撤销,不允许审批");
} }
// 步骤3:校验教研室是否已同意,机关审批应在教研室同意之后进行
if (apply.getJyspzzt() == null || apply.getJyspzzt() != 1) { if (apply.getJyspzzt() == null || apply.getJyspzzt() != 1) {
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "教研室未同意或未审批,无法进行机关审批"); throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "教研室未同意,无法进行机关审批");
} }
// 步骤4:校验教学系是否已同意,机关审批应在教学系同意之后进行(三级审批) String jgbh = StringUtils.isNotEmpty(dto.getJgbh()) ? dto.getJgbh() : "JG";
if (apply.getJxxspzzt() == null || apply.getJxxspzzt() != 1) { String auditor = StringUtils.isNotEmpty(dto.getSprbh()) ? dto.getSprbh() : currentOperatorId();
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "教学系未同意或未审批,无法进行机关审批");
}
// 步骤5:构建并保存机关审批记录
SSDKSQSP audit = new SSDKSQSP(); SSDKSQSP audit = new SSDKSQSP();
audit.setBh(UuidUtil.getOriginalUUID()); audit.setBh(UuidUtil.getOriginalUUID());
audit.setSsdksqbh(dto.getSsdksqbh()); audit.setSsdksqbh(dto.getSsdksqbh());
audit.setJgbh(dto.getJgbh()); audit.setJgbh(jgbh);
audit.setSprbh(dto.getSprbh()); audit.setSprbh(auditor);
audit.setSpsj(LocalDateTime.now()); audit.setSpsj(LocalDateTime.now());
audit.setSpzt(dto.getSpzt()); audit.setSpzt(dto.getSpzt());
audit.setFhyj(dto.getFhyj()); audit.setFhyj(dto.getFhyj());
@@ -1325,19 +1450,12 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
audit.setUpdateTime(LocalDateTime.now()); audit.setUpdateTime(LocalDateTime.now());
ssdksqspMapper.insert(audit); ssdksqspMapper.insert(audit);
// 步骤5:根据审批结果执行不同的后续处理 if (dto.getSpzt() == 1) {
if (dto.getSpzt() == 3) { applyApprovedSchedule(apply);
// 拒绝:恢复课次原数据,标记申请最终结束
restoreLessonSchedule(apply);
} else if (dto.getSpzt() == 2) {
// 发回:发回教研室或教员,课次保留调整后数据
} else {
// 同意:课次数据已由申请时更新,无需重复处理
} }
// 步骤6:记录机关审批操作日志
recordOperationLog(apply.getBh(), "机关审批", "机关审批调课申请:" + apply.getBh() recordOperationLog(apply.getBh(), "机关审批", "机关审批调课申请:" + apply.getBh()
+ ",机关编号:" + dto.getJgbh() + ",机关编号:" + jgbh
+ ",审批结果:" + dto.getSpzt() + ",审批意见:" + dto.getFhyj()); + ",审批结果:" + dto.getSpzt() + ",审批意见:" + dto.getFhyj());
} }
@@ -1412,44 +1530,34 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void cancelScheduleAdjust(String ssdksqbh, String sqjybh) { public void cancelScheduleAdjust(String ssdksqbh, String sqjybh) {
// 步骤1:校验参数 if (jwglRoleHelper.isDepartmentPersonnel() || jwglRoleHelper.isResearchOffice()) {
throw new BusinessException(BasicManagementConstants.FORBIDDEN, "仅申请教员本人可撤销调课申请");
}
if (ssdksqbh == null || ssdksqbh.trim().isEmpty()) { if (ssdksqbh == null || ssdksqbh.trim().isEmpty()) {
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "调课申请编号不能为空"); throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "调课申请编号不能为空");
} }
if (sqjybh == null || sqjybh.trim().isEmpty()) { String teacherId = jwglRoleHelper.requireTeacherId();
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "申请教员编号不能为空"); if (sqjybh != null && !sqjybh.trim().isEmpty() && !teacherId.equals(sqjybh.trim())) {
throw new BusinessException(BasicManagementConstants.FORBIDDEN, "仅申请教员本人可撤销该调课申请");
} }
sqjybh = teacherId;
// 步骤2:查询调课申请实体
SSDKSQ apply = ssdksqMapper.selectById(ssdksqbh); SSDKSQ apply = ssdksqMapper.selectById(ssdksqbh);
if (apply == null) { if (apply == null) {
throw new BusinessException(BasicManagementConstants.NOT_FOUND, "调课申请不存在"); throw new BusinessException(BasicManagementConstants.NOT_FOUND, "调课申请不存在");
} }
// 步骤3:校验是否已删除,避免重复撤销
if (apply.getSczt() != null && apply.getSczt() == 1) { if (apply.getSczt() != null && apply.getSczt() == 1) {
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "该调课申请已撤销,无需重复撤销"); throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "该调课申请已撤销,无需重复撤销");
} }
// 步骤4:校验权限,仅申请教员本人可撤销
if (!sqjybh.equals(apply.getSqjybh())) { if (!sqjybh.equals(apply.getSqjybh())) {
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "仅申请教员本人可撤销该调课申请"); throw new BusinessException(BasicManagementConstants.FORBIDDEN, "仅申请教员本人可撤销该调课申请");
} }
// 步骤5:校验审批状态,已审批通过的申请不允许撤销
if (apply.getJyspzzt() != null && apply.getJyspzzt() == 1) { if (apply.getJyspzzt() != null && apply.getJyspzzt() == 1) {
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "该调课申请教研室已同意,不允许撤销"); throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "该调课申请教研室已同意,不允许撤销");
} }
// 步骤6:软删除调课申请主表 apply.setSczt(1);
apply.setSczt(1); // 删除状态:已删除
apply.setUpdateTime(LocalDateTime.now()); // 更新时间
ssdksqMapper.updateById(apply); ssdksqMapper.updateById(apply);
// 步骤7:恢复课次原数据
restoreLessonSchedule(apply);
// 步骤8:记录撤销操作日志
recordOperationLog(apply.getBh(), "撤销", "撤销调课申请:" + apply.getBh()); recordOperationLog(apply.getBh(), "撤销", "撤销调课申请:" + apply.getBh());
} }
@@ -1462,6 +1570,63 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
* @param lesson 课次实体 * @param lesson 课次实体
* @return 原日期节次描述 * @return 原日期节次描述
*/ */
/**
* 机关终审同意后,将调整结果写回学员队任务表、课程表,以及可选的实施课次。
*/
private void applyApprovedSchedule(SSDKSQ apply) {
if (apply == null || StringUtils.isEmpty(apply.getSskcbbh())) {
return;
}
SSKCB lesson = sskcbMapper.selectById(apply.getSskcbbh());
if (lesson != null) {
lesson.setRq(apply.getRq());
lesson.setJc(apply.getJc());
lesson.setBdsj(LocalDateTime.now());
if (StringUtils.isNotEmpty(apply.getJxnr())) {
lesson.setJxnr(apply.getJxnr());
}
if (StringUtils.isNotEmpty(apply.getJxyd())) {
lesson.setJxyd(apply.getJxyd());
}
if (StringUtils.isNotEmpty(apply.getJxff())) {
lesson.setJxff(apply.getJxff());
}
sskcbMapper.updateById(lesson);
}
String newRoom = apply.getXjsbh();
if (StringUtils.isEmpty(newRoom)) {
List<AdjustRoomVO> applyRooms = dksqjsMapper.selectByDksqbh(apply.getBh());
if (applyRooms != null && !applyRooms.isEmpty()) {
newRoom = applyRooms.get(0).getJsbh();
}
}
XYDRWB task = StringUtils.isNotEmpty(apply.getXydrwbh())
? studentTeamTaskMapper.selectById(apply.getXydrwbh())
: findRelatedTeamTask(null, lesson);
if (task != null && StringUtils.isNotEmpty(newRoom)) {
task.setJsbh(newRoom);
studentTeamTaskMapper.updateById(task);
}
KCB slot = StringUtils.isNotEmpty(apply.getKcbbh())
? kcbMapper.selectById(apply.getKcbbh())
: null;
if (slot != null) {
if (StringUtils.isNotEmpty(newRoom)) {
slot.setJsbh(newRoom);
}
if (apply.getRq() != null) {
int packed = apply.getRq().getYear() * 10000
+ apply.getRq().getMonthValue() * 100
+ apply.getRq().getDayOfMonth();
slot.setApsj(packed);
}
kcbMapper.updateById(slot);
}
}
private String buildOriginalScheduleDesc(SSKCB lesson) { private String buildOriginalScheduleDesc(SSKCB lesson) {
if (lesson == null) { if (lesson == null) {
return ""; return "";
@@ -0,0 +1,534 @@
package com.roomroot.jwgl.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.roomroot.common.exception.ServiceException;
import com.roomroot.common.utils.StringUtils;
import com.roomroot.common.utils.file.FileUtils;
import com.roomroot.common.utils.poi.ExcelUtil;
import com.roomroot.jwgl.dto.jys.ElectiveCourseImportDTO;
import com.roomroot.jwgl.dto.jys.ElectiveCourseQuery;
import com.roomroot.jwgl.dto.jys.ElectiveCourseSaveDTO;
import com.roomroot.jwgl.entity.JSB;
import com.roomroot.jwgl.entity.JYB;
import com.roomroot.jwgl.entity.KB;
import com.roomroot.jwgl.entity.XYDB;
import com.roomroot.jwgl.entity.XYDQB;
import com.roomroot.jwgl.entity.XYDRWB;
import com.roomroot.jwgl.mapper.ClassRoomMapper;
import com.roomroot.jwgl.mapper.ElectiveCourseMapper;
import com.roomroot.jwgl.mapper.JYBMapper;
import com.roomroot.jwgl.mapper.KBMapper;
import com.roomroot.jwgl.mapper.StudentTeamTaskMapper;
import com.roomroot.jwgl.mapper.XYDBMapper;
import com.roomroot.jwgl.mapper.XYDQBMapper;
import com.roomroot.jwgl.service.ElectiveCourseService;
import com.roomroot.jwgl.unit.PageQuery;
import com.roomroot.jwgl.unit.PageResult;
import com.roomroot.jwgl.utils.UuidUtil;
import com.roomroot.jwgl.vo.jys.ElectiveCourseStudentVO;
import com.roomroot.jwgl.vo.jys.ElectiveCourseVO;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.OutputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import static com.roomroot.jwgl.utils.BasicManagementConstants.BAD_REQUEST;
import static com.roomroot.jwgl.utils.BasicManagementConstants.NOT_FOUND;
/**
* 选修课管理实现。
*/
@Service
public class ElectiveCourseServiceImpl implements ElectiveCourseService {
private static final String COURSE_TYPE_ELECTIVE = "选修";
private static final String STATUS_DRAFT = "拟制";
private static final String STATUS_OPEN = "开放报名";
private static final String STATUS_STOP = "停止报名";
private static final String CLASS_TYPE_ELECTIVE = "选修班";
private static final int FLAG_DRAFT = 0;
private static final int FLAG_OPEN = 1;
private static final int FLAG_STOP = 2;
@Resource
private ElectiveCourseMapper electiveCourseMapper;
@Resource
private StudentTeamTaskMapper studentTeamTaskMapper;
@Resource
private XYDBMapper xydbMapper;
@Resource
private KBMapper kbMapper;
@Resource
private JYBMapper jybMapper;
@Resource
private ClassRoomMapper classRoomMapper;
@Resource
private XYDQBMapper xydqbMapper;
@Override
public PageResult<ElectiveCourseVO> pageList(PageQuery query, ElectiveCourseQuery cond) {
ElectiveCourseQuery filter = normalizeQuery(cond);
int pageNum = query.getPageNum() == null ? 1 : query.getPageNum();
int pageSize = query.getPageSize() == null ? 20 : query.getPageSize();
Page<ElectiveCourseVO> page = new Page<>(pageNum, pageSize);
Page<ElectiveCourseVO> result = electiveCourseMapper.selectElectiveCoursePage(page, filter);
fillSerial(result.getRecords(), pageNum, pageSize);
return new PageResult<>(result.getRecords(), result.getTotal(), pageNum, pageSize);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void add(ElectiveCourseSaveDTO dto) {
if (dto == null) {
throw new ServiceException("选修课信息不能为空", BAD_REQUEST);
}
KB course = requireCourse(dto.getKbh());
String xydbh = resolveTeamId(dto.getXydbh(), dto.getXxbmc(), dto.getNj(), true);
XYDRWB task = new XYDRWB();
task.setBh(UuidUtil.getOriginalUUID());
task.setDelFlag(0);
task.setNd(dto.getNd() != null ? dto.getNd() : LocalDate.now().getYear());
task.setXydbh(xydbh);
task.setKbh(course.getKbh());
task.setXqdc(dto.getXqdc());
task.setJybh(blankToNull(dto.getJybh()));
task.setJsbh(blankToNull(dto.getJsbh()));
task.setRs(dto.getRs());
task.setXs(dto.getXs() != null ? dto.getXs() : course.getXs());
task.setXf(dto.getXf() != null ? dto.getXf() : course.getXf());
task.setKlx(ensureElectiveType(null));
task.setJysdh(StringUtils.isNotEmpty(dto.getJysdh()) ? dto.getJysdh() : course.getJysdh());
task.setBz(dto.getBz());
task.setXz(FLAG_DRAFT);
studentTeamTaskMapper.insert(task);
upsertPinban(xydbh, STATUS_DRAFT, dto.getBmkssj(), dto.getBmjssj(),
dto.getYqsm(), dto.getKxdlbc(), dto.getBz());
updateTeamDates(xydbh, dto.getKkrq(), dto.getJkrq());
}
@Override
@Transactional(rollbackFor = Exception.class)
public int batchOpenRegistration(List<String> bhList) {
return changeStatus(bhList, STATUS_OPEN, FLAG_OPEN, 1, false);
}
@Override
@Transactional(rollbackFor = Exception.class)
public int batchCancelOpenRegistration(List<String> bhList) {
return changeStatus(bhList, STATUS_DRAFT, FLAG_DRAFT, 0, false);
}
@Override
@Transactional(rollbackFor = Exception.class)
public int batchStopRegistration(List<String> bhList) {
return changeStatus(bhList, STATUS_STOP, FLAG_STOP, 0, true);
}
@Override
@Transactional(rollbackFor = Exception.class)
public int batchReverseClassRange(List<String> bhList) {
List<XYDRWB> tasks = loadElectiveTasks(bhList);
int count = 0;
Set<String> handled = new LinkedHashSet<>();
for (XYDRWB task : tasks) {
if (!handled.add(task.getXydbh())) {
continue;
}
List<String> names = electiveCourseMapper.selectOriginalClassNames(task.getXydbh());
if (names == null || names.isEmpty()) {
throw new ServiceException("选修班暂无学员,无法根据学员反向确定班次范围", BAD_REQUEST);
}
upsertPinban(task.getXydbh(), null, null, null, null, String.join(";", names), null);
count++;
}
return count;
}
@Override
public void exportClassList(ElectiveCourseQuery cond, HttpServletResponse response) {
List<ElectiveCourseVO> list = electiveCourseMapper.selectElectiveCourseList(normalizeQuery(cond));
fillSerial(list, 1, list == null ? 0 : list.size());
ExcelUtil<ElectiveCourseVO> util = new ExcelUtil<>(ElectiveCourseVO.class);
util.exportExcel(response, list, "选修班列表");
}
@Override
public void exportStudentExcel(List<String> bhList, HttpServletResponse response) {
List<ElectiveCourseStudentVO> students = loadStudents(bhList);
ExcelUtil<ElectiveCourseStudentVO> util = new ExcelUtil<>(ElectiveCourseStudentVO.class);
util.exportExcel(response, students, "选修班学员名单");
}
@Override
public void exportStudentWord(List<String> bhList, HttpServletResponse response) {
List<ElectiveCourseStudentVO> students = loadStudents(bhList);
try (XWPFDocument doc = new XWPFDocument(); OutputStream os = response.getOutputStream()) {
response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
FileUtils.setAttachmentResponseHeader(response, "选修班学员名单.docx");
writeStudentWord(doc, students);
doc.write(os);
os.flush();
} catch (ServiceException e) {
throw e;
} catch (Exception e) {
throw new ServiceException("导出Word失败:" + e.getMessage(), BAD_REQUEST);
}
}
@Override
public void downloadTemplate(HttpServletResponse response) {
ExcelUtil<ElectiveCourseImportDTO> util = new ExcelUtil<>(ElectiveCourseImportDTO.class);
util.importTemplateExcel(response, "选修课数据");
}
@Override
@Transactional(rollbackFor = Exception.class)
public int importData(MultipartFile file) throws Exception {
if (file == null || file.isEmpty()) {
throw new ServiceException("导入文件不能为空", BAD_REQUEST);
}
ExcelUtil<ElectiveCourseImportDTO> util = new ExcelUtil<>(ElectiveCourseImportDTO.class);
List<ElectiveCourseImportDTO> rows = util.importExcel(file.getInputStream());
if (rows == null || rows.isEmpty()) {
throw new ServiceException("Excel中无有效数据", BAD_REQUEST);
}
int count = 0;
for (int i = 0; i < rows.size(); i++) {
ElectiveCourseImportDTO row = rows.get(i);
int line = i + 2;
if (StringUtils.isEmpty(row.getKmc())) {
throw new ServiceException("第" + line + "行课程科目名称未填写", BAD_REQUEST);
}
if (StringUtils.isEmpty(row.getXxbmc())) {
throw new ServiceException("第" + line + "行选修班名称未填写", BAD_REQUEST);
}
KB course = kbMapper.selectOne(new LambdaQueryWrapper<KB>().eq(KB::getKmc, row.getKmc().trim()));
if (course == null) {
throw new ServiceException("第" + line + "行课程科目名称不存在:" + row.getKmc(), NOT_FOUND);
}
String jybh = null;
if (StringUtils.isNotEmpty(row.getJyxm())) {
JYB teacher = jybMapper.selectOne(new LambdaQueryWrapper<JYB>().eq(JYB::getJyxm, row.getJyxm().trim()));
if (teacher == null) {
throw new ServiceException("第" + line + "行授课教员不存在:" + row.getJyxm(), NOT_FOUND);
}
jybh = teacher.getJybh();
}
String jsbh = null;
if (StringUtils.isNotEmpty(row.getJsmc())) {
JSB room = classRoomMapper.selectOne(new LambdaQueryWrapper<JSB>().eq(JSB::getJsmc, row.getJsmc().trim()));
if (room == null) {
throw new ServiceException("第" + line + "行教学场地不存在:" + row.getJsmc(), NOT_FOUND);
}
jsbh = room.getJsbh();
}
String xydbh = resolveTeamId(null, row.getXxbmc().trim(), row.getKxbcnj(), true);
XYDRWB task = new XYDRWB();
task.setBh(UuidUtil.getOriginalUUID());
task.setDelFlag(0);
task.setNd(LocalDate.now().getYear());
task.setXydbh(xydbh);
task.setKbh(course.getKbh());
task.setJybh(jybh);
task.setJsbh(jsbh);
task.setRs(row.getJhrs());
task.setXs(row.getJhxs() != null ? row.getJhxs() : course.getXs());
task.setXf(row.getXf() != null ? row.getXf() : course.getXf());
task.setKlx(ensureElectiveType(null));
task.setJysdh(course.getJysdh());
task.setXz(statusToFlag(row.getXkzt()));
studentTeamTaskMapper.insert(task);
upsertPinban(xydbh, normalizeStatus(row.getXkzt()), parseDateTime(row.getBmkssj()),
parseDateTime(row.getBmjssj()), row.getYqsm(), row.getKxbcnj(), null);
updateTeamDates(xydbh, parseDateTime(row.getKkrq()), parseDateTime(row.getJkrq()));
count++;
}
return count;
}
private int changeStatus(List<String> bhList, String status, int xzFlag, Integer allowRegister, boolean stopNow) {
List<XYDRWB> tasks = loadElectiveTasks(bhList);
Set<String> teams = new LinkedHashSet<>();
for (XYDRWB task : tasks) {
task.setXz(xzFlag);
studentTeamTaskMapper.updateById(task);
teams.add(task.getXydbh());
}
for (String xydbh : teams) {
upsertPinban(xydbh, status, null, null, null, null, null);
updatePeriodRegister(xydbh, allowRegister, stopNow);
}
return tasks.size();
}
private List<XYDRWB> loadElectiveTasks(List<String> bhList) {
if (bhList == null || bhList.isEmpty()) {
throw new ServiceException("请先选择选修课", BAD_REQUEST);
}
List<XYDRWB> tasks = new ArrayList<>();
for (String bh : bhList) {
if (StringUtils.isEmpty(bh)) {
continue;
}
XYDRWB task = studentTeamTaskMapper.selectById(bh);
if (task == null) {
throw new ServiceException("选修课不存在", NOT_FOUND);
}
if (task.getKlx() == null || !task.getKlx().contains(COURSE_TYPE_ELECTIVE)) {
throw new ServiceException("所选记录不是选修课", BAD_REQUEST);
}
tasks.add(task);
}
if (tasks.isEmpty()) {
throw new ServiceException("请先选择选修课", BAD_REQUEST);
}
return tasks;
}
private List<ElectiveCourseStudentVO> loadStudents(List<String> bhList) {
List<XYDRWB> tasks = loadElectiveTasks(bhList);
List<ElectiveCourseStudentVO> students = new ArrayList<>();
Set<String> teams = new LinkedHashSet<>();
for (XYDRWB task : tasks) {
if (!teams.add(task.getXydbh())) {
continue;
}
KB course = kbMapper.selectById(task.getKbh());
List<ElectiveCourseStudentVO> rows = electiveCourseMapper.selectElectiveStudents(task.getXydbh());
if (rows == null) {
continue;
}
for (ElectiveCourseStudentVO row : rows) {
if (course != null) {
row.setKmc(course.getKmc());
}
students.add(row);
}
}
if (students.isEmpty()) {
throw new ServiceException("所选选修班暂无学员", BAD_REQUEST);
}
for (int i = 0; i < students.size(); i++) {
students.get(i).setXh(i + 1);
}
return students;
}
private void upsertPinban(String xydbh, String zt, LocalDateTime start, LocalDateTime end,
String yqsm, String bmdtj, String bz) {
Integer exists = electiveCourseMapper.countPinban(xydbh);
if (exists == null || exists == 0) {
electiveCourseMapper.insertPinban(xydbh, zt == null ? STATUS_DRAFT : zt, start, end, yqsm, bmdtj, bz);
} else {
electiveCourseMapper.updatePinban(xydbh, zt, start, end, yqsm, bmdtj);
}
}
private String resolveTeamId(String xydbh, String xxbmc, String nj, boolean createIfMissing) {
if (StringUtils.isNotEmpty(xydbh)) {
XYDB exists = xydbMapper.selectById(xydbh);
if (exists == null) {
throw new ServiceException("选修班不存在", NOT_FOUND);
}
return xydbh;
}
if (StringUtils.isEmpty(xxbmc)) {
throw new ServiceException("选修班编号或名称不能为空", BAD_REQUEST);
}
XYDB team = xydbMapper.selectOne(new LambdaQueryWrapper<XYDB>().eq(XYDB::getXydmc, xxbmc.trim()));
if (team != null) {
return team.getXydbh();
}
if (!createIfMissing) {
throw new ServiceException("选修班不存在:" + xxbmc, NOT_FOUND);
}
XYDB created = new XYDB();
created.setXydbh(UuidUtil.getOriginalUUID());
created.setXydmc(xxbmc.trim());
created.setNj(blankToNull(nj));
created.setXydlx(CLASS_TYPE_ELECTIVE);
created.setXslx(0);
xydbMapper.insert(created);
return created.getXydbh();
}
private KB requireCourse(String kbh) {
if (StringUtils.isEmpty(kbh)) {
throw new ServiceException("课程科目不能为空", BAD_REQUEST);
}
KB course = kbMapper.selectById(kbh);
if (course == null) {
throw new ServiceException("课程科目不存在", NOT_FOUND);
}
return course;
}
private void updateTeamDates(String xydbh, LocalDateTime start, LocalDateTime end) {
if (start == null && end == null) {
return;
}
XYDB patch = new XYDB();
patch.setXydbh(xydbh);
if (start != null) {
patch.setRxrq(start);
}
if (end != null) {
patch.setByrq(end);
}
xydbMapper.updateById(patch);
}
private void updatePeriodRegister(String xydbh, Integer allowRegister, boolean stopNow) {
List<XYDQB> periods = xydqbMapper.selectList(new LambdaQueryWrapper<XYDQB>().eq(XYDQB::getXydbh, xydbh));
if (periods == null || periods.isEmpty()) {
return;
}
for (XYDQB period : periods) {
LambdaUpdateWrapper<XYDQB> update = new LambdaUpdateWrapper<XYDQB>()
.eq(XYDQB::getBh, period.getBh())
.set(XYDQB::getYxzc, allowRegister);
if (stopNow) {
update.set(XYDQB::getJszcsj, LocalDateTime.now());
}
xydqbMapper.update(null, update);
}
}
private ElectiveCourseQuery normalizeQuery(ElectiveCourseQuery cond) {
ElectiveCourseQuery filter = cond == null ? new ElectiveCourseQuery() : cond;
filter.setJyxm(blankToNull(filter.getJyxm()));
filter.setKmc(blankToNull(filter.getKmc()));
filter.setKxbcnj(blankToNull(filter.getKxbcnj()));
filter.setXxbmc(blankToNull(filter.getXxbmc()));
filter.setPxcc(normalizeNone(filter.getPxcc()));
filter.setXkzt(normalizeNone(filter.getXkzt()));
return filter;
}
private void fillSerial(List<ElectiveCourseVO> records, int pageNum, int pageSize) {
if (records == null) {
return;
}
int start = Math.max(pageNum - 1, 0) * Math.max(pageSize, 0);
for (int i = 0; i < records.size(); i++) {
records.get(i).setXh(start + i + 1);
}
}
private void writeStudentWord(XWPFDocument doc, List<ElectiveCourseStudentVO> students) {
XWPFParagraph title = doc.createParagraph();
title.setAlignment(ParagraphAlignment.CENTER);
XWPFRun titleRun = title.createRun();
titleRun.setText("选修班学员名单");
titleRun.setBold(true);
titleRun.setFontSize(16);
XWPFTable table = doc.createTable(students.size() + 1, 7);
String[] headers = {"序号", "选修班名称", "课程", "学号", "姓名", "性别", "联系电话"};
XWPFTableRow headerRow = table.getRow(0);
for (int i = 0; i < headers.length; i++) {
setCellText(headerRow.getCell(i), headers[i]);
}
for (int i = 0; i < students.size(); i++) {
ElectiveCourseStudentVO row = students.get(i);
XWPFTableRow tableRow = table.getRow(i + 1);
setCellText(tableRow.getCell(0), String.valueOf(row.getXh()));
setCellText(tableRow.getCell(1), nvl(row.getXxbmc()));
setCellText(tableRow.getCell(2), nvl(row.getKmc()));
setCellText(tableRow.getCell(3), nvl(row.getXhNo()));
setCellText(tableRow.getCell(4), nvl(row.getXm()));
setCellText(tableRow.getCell(5), nvl(row.getXb()));
setCellText(tableRow.getCell(6), nvl(row.getLxdh()));
}
}
private void setCellText(XWPFTableCell cell, String text) {
cell.removeParagraph(0);
XWPFParagraph paragraph = cell.addParagraph();
XWPFRun run = paragraph.createRun();
run.setText(text == null ? "" : text);
run.setFontSize(11);
}
private String ensureElectiveType(String klx) {
if (StringUtils.isEmpty(klx)) {
return COURSE_TYPE_ELECTIVE;
}
return klx.contains(COURSE_TYPE_ELECTIVE) ? klx : klx + COURSE_TYPE_ELECTIVE;
}
private String normalizeStatus(String status) {
String value = normalizeNone(status);
if (value == null) {
return STATUS_DRAFT;
}
if (STATUS_OPEN.equals(value) || STATUS_STOP.equals(value) || STATUS_DRAFT.equals(value)) {
return value;
}
return STATUS_DRAFT;
}
private int statusToFlag(String status) {
String value = normalizeStatus(status);
if (STATUS_OPEN.equals(value)) {
return FLAG_OPEN;
}
if (STATUS_STOP.equals(value)) {
return FLAG_STOP;
}
return FLAG_DRAFT;
}
private String normalizeNone(String value) {
String trimmed = blankToNull(value);
if (trimmed == null || "无".equals(trimmed)) {
return null;
}
return trimmed;
}
private String blankToNull(String value) {
return StringUtils.isEmpty(value) ? null : value.trim();
}
private String nvl(String value) {
return value == null ? "" : value;
}
private LocalDateTime parseDateTime(String text) {
String value = blankToNull(text);
if (value == null) {
return null;
}
try {
if (value.length() <= 10) {
if (value.contains("/")) {
return LocalDate.parse(value, DateTimeFormatter.ofPattern("yyyy/MM/dd")).atStartOfDay();
}
return LocalDate.parse(value, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atStartOfDay();
}
return LocalDateTime.parse(value, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
} catch (Exception e) {
throw new ServiceException("日期格式不正确:" + text, BAD_REQUEST);
}
}
}
@@ -1,13 +1,30 @@
package com.roomroot.jwgl.service.impl; package com.roomroot.jwgl.service.impl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.roomroot.common.utils.StringUtils;
import com.roomroot.common.utils.poi.ExcelUtil;
import com.roomroot.jwgl.dto.kcb.TimetableQuery;
import com.roomroot.jwgl.entity.KCB; import com.roomroot.jwgl.entity.KCB;
import com.roomroot.jwgl.mapper.KCBMapper; import com.roomroot.jwgl.mapper.KCBMapper;
import com.roomroot.jwgl.mapper.KcbTimetableMapper;
import com.roomroot.jwgl.mapper.SystemInitializationMapper;
import com.roomroot.jwgl.service.KCBService; import com.roomroot.jwgl.service.KCBService;
import com.roomroot.jwgl.unit.PageQuery;
import com.roomroot.jwgl.unit.PageResult;
import com.roomroot.jwgl.utils.UuidUtil; import com.roomroot.jwgl.utils.UuidUtil;
import com.roomroot.jwgl.utils.JwglRoleHelper;
import com.roomroot.jwgl.vo.kcb.ClassTimetableVO;
import com.roomroot.jwgl.vo.kcb.DailyWeeklyTimetableVO;
import com.roomroot.jwgl.vo.kcb.SemesterGradeExportVO;
import com.roomroot.jwgl.vo.systeminitialization.SemesterInitializationVO;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List; import java.util.List;
/** /**
@@ -16,9 +33,20 @@ import java.util.List;
@Service @Service
public class KCBServiceImpl implements KCBService { public class KCBServiceImpl implements KCBService {
private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
@Resource @Resource
private KCBMapper kcbMapper; private KCBMapper kcbMapper;
@Resource
private KcbTimetableMapper kcbTimetableMapper;
@Resource
private SystemInitializationMapper systemInitializationMapper;
@Resource
private JwglRoleHelper jwglRoleHelper;
@Override @Override
public void add(KCB kcb) { public void add(KCB kcb) {
if (kcb.getCjsj() == null) { if (kcb.getCjsj() == null) {
@@ -56,4 +84,108 @@ public class KCBServiceImpl implements KCBService {
return kcbMapper.selectList(null); return kcbMapper.selectList(null);
} }
@Override
public List<DailyWeeklyTimetableVO> listToday(TimetableQuery cond) {
TimetableQuery filter = prepareFilter(cond);
String today = LocalDate.now().format(DATE_FORMAT);
return kcbTimetableMapper.selectLessonTimetable(filter, today, today);
}
@Override
public List<DailyWeeklyTimetableVO> listWeek(TimetableQuery cond) {
TimetableQuery filter = prepareFilter(cond);
LocalDate today = LocalDate.now();
LocalDate monday = today.with(DayOfWeek.MONDAY);
LocalDate sunday = today.with(DayOfWeek.SUNDAY);
return kcbTimetableMapper.selectLessonTimetable(filter,
monday.format(DATE_FORMAT), sunday.format(DATE_FORMAT));
}
@Override
public PageResult<ClassTimetableVO> pageClassTimetable(PageQuery query, TimetableQuery cond) {
TimetableQuery filter = prepareFilter(cond);
int pageNum = (query == null || query.getPageNum() == null) ? 1 : query.getPageNum();
int pageSize = (query == null || query.getPageSize() == null) ? 20 : query.getPageSize();
Page<ClassTimetableVO> page = new Page<>(pageNum, pageSize);
Page<ClassTimetableVO> result = kcbTimetableMapper.selectClassTimetable(page, filter);
return new PageResult<>(result.getRecords(), result.getTotal(), pageNum, pageSize);
}
@Override
public void exportSemesterPlan(TimetableQuery cond, HttpServletResponse response) {
TimetableQuery filter = prepareFilter(cond);
String[] range = resolveSemesterDateRange(filter);
List<DailyWeeklyTimetableVO> list = kcbTimetableMapper.selectLessonTimetable(filter, range[0], range[1]);
ExcelUtil<DailyWeeklyTimetableVO> util = new ExcelUtil<>(DailyWeeklyTimetableVO.class);
util.exportExcel(response, list, "学期教学实施计划");
}
@Override
public void exportSemesterGrades(TimetableQuery cond, HttpServletResponse response) {
TimetableQuery filter = prepareFilter(cond);
List<SemesterGradeExportVO> list = kcbTimetableMapper.selectSemesterGrades(filter);
ExcelUtil<SemesterGradeExportVO> util = new ExcelUtil<>(SemesterGradeExportVO.class);
util.exportExcel(response, list, "学期成绩表");
}
@Override
public void exportClassCourses(TimetableQuery cond, HttpServletResponse response) {
TimetableQuery filter = prepareFilter(cond);
List<ClassTimetableVO> list = kcbTimetableMapper.selectClassTimetableList(filter);
ExcelUtil<ClassTimetableVO> util = new ExcelUtil<>(ClassTimetableVO.class);
util.exportExcel(response, list, "班次课程列表");
}
/**
* 未传年度时按当前学期填充;队别班次名称去空白。
* 学员强制只看本人所在学员队课表。
*/
private TimetableQuery prepareFilter(TimetableQuery cond) {
TimetableQuery filter = cond == null ? new TimetableQuery() : cond;
if (jwglRoleHelper.isStudent()) {
filter.setXydbh(jwglRoleHelper.requireStudentTeamId());
filter.setXydmc(null);
} else {
if (StringUtils.isNotEmpty(filter.getXydbh())) {
filter.setXydbh(filter.getXydbh().trim());
}
if (StringUtils.isNotEmpty(filter.getXydmc())) {
filter.setXydmc(filter.getXydmc().trim());
}
}
if (filter.getNd() != null) {
return filter;
}
SemesterInitializationVO semester = systemInitializationMapper.selectCurrentSemester();
if (semester != null && semester.getYear() != null) {
filter.setNd(semester.getYear());
if (filter.getXqdc() == null) {
filter.setXqdc(semester.getSequenceNumber());
}
} else {
filter.setNd(LocalDate.now().getYear());
}
return filter;
}
/**
* 本学期用开学/结束日期;查其他年度时退回该年 1 月 1 日至 12 月 31 日。
*/
private String[] resolveSemesterDateRange(TimetableQuery filter) {
SemesterInitializationVO semester = systemInitializationMapper.selectCurrentSemester();
if (semester != null && semester.getStartAt() != null && semester.getEndAt() != null
&& filter.getNd() != null && filter.getNd().equals(semester.getYear())
&& (filter.getXqdc() == null || filter.getXqdc().equals(semester.getSequenceNumber()))) {
return new String[]{
semester.getStartAt().toLocalDate().format(DATE_FORMAT),
semester.getEndAt().toLocalDate().format(DATE_FORMAT)
};
}
LocalDate now = LocalDate.now();
int year = filter.getNd() == null ? now.getYear() : filter.getNd();
LocalDate start = LocalDate.of(year, 1, 1);
LocalDate end = LocalDate.of(year, 12, 31);
return new String[]{start.format(DATE_FORMAT), end.format(DATE_FORMAT)};
}
} }
@@ -39,10 +39,8 @@ public class SemesterServiceImpl extends ServiceImpl<SemesterMapper, XQ> impleme
if(insert > 0){ if(insert > 0){
LocalDateTime kxrq = xq.getKxrq(); LocalDateTime kxrq = xq.getKxrq();
LocalDateTime jsrq = xq.getJsrq(); LocalDateTime jsrq = xq.getJsrq();
String startDate = localDateTimeToDateStr(kxrq); String startDate = localDateTimeToDateStr(kxrq);
String endDate = localDateTimeToDateStr(jsrq); String endDate = localDateTimeToDateStr(jsrq);
semesterCalendarService.add(startDate, endDate); semesterCalendarService.add(startDate, endDate);
} }
} }
@@ -0,0 +1,412 @@
package com.roomroot.jwgl.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.roomroot.common.exception.ServiceException;
import com.roomroot.common.utils.StringUtils;
import com.roomroot.jwgl.dto.jys.TeachingTaskQuery;
import com.roomroot.jwgl.dto.jys.TeachingTaskSaveDTO;
import com.roomroot.jwgl.entity.JXRW;
import com.roomroot.jwgl.entity.JYSRWS;
import com.roomroot.jwgl.entity.KB;
import com.roomroot.jwgl.entity.XYDB;
import com.roomroot.jwgl.entity.XYDNDXQJBXXB;
import com.roomroot.jwgl.entity.XYDRWB;
import com.roomroot.jwgl.entity.ZYJXJHB;
import com.roomroot.jwgl.mapper.ClassSemesterMapper;
import com.roomroot.jwgl.mapper.KBMapper;
import com.roomroot.jwgl.mapper.OfficeTaskBookMapper;
import com.roomroot.jwgl.mapper.StudentTeamTaskMapper;
import com.roomroot.jwgl.mapper.SystemInitializationMapper;
import com.roomroot.jwgl.mapper.TeachingTaskMapper;
import com.roomroot.jwgl.mapper.XYDBMapper;
import com.roomroot.jwgl.mapper.ZYJXJHBMapper;
import com.roomroot.jwgl.service.StudentTeamTaskService;
import com.roomroot.jwgl.service.TeachingTaskManageService;
import com.roomroot.jwgl.unit.PageQuery;
import com.roomroot.jwgl.unit.PageResult;
import com.roomroot.jwgl.utils.UuidUtil;
import com.roomroot.jwgl.vo.jys.TeachingOfficeBookCourseVO;
import com.roomroot.jwgl.vo.jys.TeachingOfficeBookVO;
import com.roomroot.jwgl.vo.jys.TeachingTaskDetailVO;
import com.roomroot.jwgl.vo.jys.TeachingTaskSquadVO;
import com.roomroot.jwgl.vo.jys.TeachingTaskVO;
import com.roomroot.jwgl.vo.systeminitialization.SemesterInitializationVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import jakarta.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import static com.roomroot.jwgl.utils.BasicManagementConstants.BAD_REQUEST;
import static com.roomroot.jwgl.utils.BasicManagementConstants.CONFLICT;
import static com.roomroot.jwgl.utils.BasicManagementConstants.NOT_FOUND;
/**
* 教学任务管理实现。
*/
@Service
public class TeachingTaskManageServiceImpl implements TeachingTaskManageService {
private static final String STATUS_DRAFT = "上报";
private static final String STATUS_PUBLISHED = "发布";
private static final String OFFICE_STATUS_UNREPORTED = "未上报";
private static final String OFFICE_STATUS_PUBLISHED = "发布";
@Resource
private TeachingTaskMapper teachingTaskMapper;
@Resource
private OfficeTaskBookMapper officeTaskBookMapper;
@Resource
private ClassSemesterMapper classSemesterMapper;
@Resource
private XYDBMapper xydbMapper;
@Resource
private KBMapper kbMapper;
@Resource
private ZYJXJHBMapper zyjxjhbMapper;
@Resource
private StudentTeamTaskMapper studentTeamTaskMapper;
@Resource
private StudentTeamTaskService studentTeamTaskService;
@Resource
private SystemInitializationMapper systemInitializationMapper;
@Override
public PageResult<TeachingTaskVO> pageList(PageQuery query, TeachingTaskQuery cond) {
TeachingTaskQuery filter = cond == null ? new TeachingTaskQuery() : cond;
if (StringUtils.isNotEmpty(filter.getRwmc())) {
filter.setRwmc(filter.getRwmc().trim());
}
int pageNum = query == null || query.getPageNum() == null ? 1 : query.getPageNum();
int pageSize = query == null || query.getPageSize() == null ? 20 : query.getPageSize();
Page<TeachingTaskVO> result = teachingTaskMapper.selectManagePage(new Page<>(pageNum, pageSize), filter);
if (result.getRecords() != null) {
for (TeachingTaskVO row : result.getRecords()) {
fillSemesterName(row);
}
}
return new PageResult<>(result.getRecords(), result.getTotal(), pageNum, pageSize);
}
@Override
public TeachingTaskDetailVO getDetail(String bh) {
if (StringUtils.isEmpty(bh)) {
throw new ServiceException("教学任务编号不能为空", BAD_REQUEST);
}
JXRW entity = teachingTaskMapper.selectById(bh);
if (entity == null || Integer.valueOf(1).equals(entity.getDelFlag())) {
throw new ServiceException("教学任务不存在", NOT_FOUND);
}
TeachingTaskVO vo = toSimpleVo(entity);
List<TeachingTaskSquadVO> squads = listBoundSquads(bh);
if (!squads.isEmpty() && squads.get(0).getXqdc() != null) {
vo.setXqdc(squads.get(0).getXqdc());
}
fillSemesterName(vo);
TeachingTaskDetailVO detail = new TeachingTaskDetailVO();
detail.setTask(vo);
detail.setOfficeBooks(listOfficeBooks(bh));
detail.setSquads(squads);
return detail;
}
@Transactional(rollbackFor = Exception.class)
@Override
public void add(TeachingTaskSaveDTO dto) {
if (dto == null || StringUtils.isEmpty(dto.getRwmc())) {
throw new ServiceException("任务名称不能为空", BAD_REQUEST);
}
fillSemester(dto);
JXRW entity = new JXRW();
entity.setBh(UuidUtil.getOriginalUUID());
entity.setRwmc(dto.getRwmc().trim());
entity.setNd(dto.getNd());
entity.setZt(STATUS_DRAFT);
entity.setCjsj(LocalDateTime.now());
entity.setJssj(dto.getJssj() != null ? dto.getJssj() : defaultEndTime(dto.getNd(), dto.getXqdc()));
entity.setDelFlag(0);
teachingTaskMapper.insert(entity);
bindSquads(entity.getBh(), dto.getNd(), dto.getXqdc(), dto.getXydxqbhList());
generateCourseTasksAndOfficeBooks(entity.getBh());
}
@Transactional(rollbackFor = Exception.class)
@Override
public void update(TeachingTaskSaveDTO dto) {
if (dto == null || StringUtils.isEmpty(dto.getBh())) {
throw new ServiceException("教学任务编号不能为空", BAD_REQUEST);
}
if (StringUtils.isEmpty(dto.getRwmc())) {
throw new ServiceException("任务名称不能为空", BAD_REQUEST);
}
JXRW entity = teachingTaskMapper.selectById(dto.getBh());
if (entity == null || Integer.valueOf(1).equals(entity.getDelFlag())) {
throw new ServiceException("教学任务不存在", NOT_FOUND);
}
fillSemester(dto);
entity.setRwmc(dto.getRwmc().trim());
if (dto.getJssj() != null) {
entity.setJssj(dto.getJssj());
}
teachingTaskMapper.updateById(entity);
bindSquads(entity.getBh(), dto.getNd(), dto.getXqdc(), dto.getXydxqbhList());
generateCourseTasksAndOfficeBooks(entity.getBh());
}
@Transactional(rollbackFor = Exception.class)
@Override
public void delete(String bh) {
if (StringUtils.isEmpty(bh)) {
throw new ServiceException("教学任务编号不能为空", BAD_REQUEST);
}
JXRW entity = teachingTaskMapper.selectById(bh);
if (entity == null || Integer.valueOf(1).equals(entity.getDelFlag())) {
return;
}
entity.setDelFlag(1);
teachingTaskMapper.updateById(entity);
List<JYSRWS> books = officeTaskBookMapper.selectList(new LambdaQueryWrapper<JYSRWS>()
.eq(JYSRWS::getJxrwbh, bh)
.eq(JYSRWS::getDelFlag, 0));
for (JYSRWS book : books) {
book.setDelFlag(1);
officeTaskBookMapper.updateById(book);
}
classSemesterMapper.update(null, new LambdaUpdateWrapper<XYDNDXQJBXXB>()
.eq(XYDNDXQJBXXB::getJxrwbh, bh)
.set(XYDNDXQJBXXB::getJxrwbh, null));
}
@Transactional(rollbackFor = Exception.class)
@Override
public int publish(String bh) {
if (StringUtils.isEmpty(bh)) {
throw new ServiceException("教学任务编号不能为空", BAD_REQUEST);
}
JXRW entity = teachingTaskMapper.selectById(bh);
if (entity == null || Integer.valueOf(1).equals(entity.getDelFlag())) {
throw new ServiceException("教学任务不存在", NOT_FOUND);
}
if (STATUS_PUBLISHED.equals(entity.getZt())) {
throw new ServiceException("该教学任务已发布", CONFLICT);
}
generateCourseTasksAndOfficeBooks(bh);
entity.setZt(STATUS_PUBLISHED);
entity.setFbsj(LocalDateTime.now());
teachingTaskMapper.updateById(entity);
List<JYSRWS> books = officeTaskBookMapper.selectList(new LambdaQueryWrapper<JYSRWS>()
.eq(JYSRWS::getJxrwbh, bh)
.eq(JYSRWS::getDelFlag, 0));
for (JYSRWS book : books) {
book.setZt(OFFICE_STATUS_PUBLISHED);
officeTaskBookMapper.updateById(book);
}
return books.size();
}
@Override
public List<TeachingOfficeBookVO> listOfficeBooks(String jxrwbh) {
if (StringUtils.isEmpty(jxrwbh)) {
return new ArrayList<>();
}
List<TeachingOfficeBookVO> list = teachingTaskMapper.selectOfficeBooks(jxrwbh);
return list == null ? new ArrayList<>() : list;
}
@Override
public List<TeachingOfficeBookCourseVO> listOfficeBookCourses(String jxrwbh, String jysdh) {
if (StringUtils.isEmpty(jxrwbh) || StringUtils.isEmpty(jysdh)) {
throw new ServiceException("教学任务编号和教研室代号不能为空", BAD_REQUEST);
}
List<TeachingOfficeBookCourseVO> list = teachingTaskMapper.selectOfficeBookCourses(jxrwbh, jysdh);
return list == null ? new ArrayList<>() : list;
}
@Override
public List<TeachingTaskSquadVO> listBoundSquads(String jxrwbh) {
if (StringUtils.isEmpty(jxrwbh)) {
return new ArrayList<>();
}
List<TeachingTaskSquadVO> list = teachingTaskMapper.selectBoundSquads(jxrwbh);
return list == null ? new ArrayList<>() : list;
}
@Override
public List<TeachingTaskSquadVO> listAvailableSquads(Integer nd, Integer xqdc, String jxrwbh) {
if (nd == null || xqdc == null) {
SemesterInitializationVO semester = systemInitializationMapper.selectCurrentSemester();
if (semester == null || semester.getYear() == null || semester.getSequenceNumber() == null) {
throw new ServiceException("未设置当前学期,请指定年度和学期第次", BAD_REQUEST);
}
nd = semester.getYear();
xqdc = semester.getSequenceNumber();
}
List<TeachingTaskSquadVO> list = teachingTaskMapper.selectAvailableSquads(nd, xqdc, jxrwbh);
return list == null ? new ArrayList<>() : list;
}
private void fillSemester(TeachingTaskSaveDTO dto) {
if (dto.getNd() != null && dto.getXqdc() != null) {
return;
}
SemesterInitializationVO semester = systemInitializationMapper.selectCurrentSemester();
if (semester == null || semester.getYear() == null) {
if (dto.getNd() == null) {
throw new ServiceException("请选择学期", BAD_REQUEST);
}
return;
}
if (dto.getNd() == null) {
dto.setNd(semester.getYear());
}
if (dto.getXqdc() == null) {
dto.setXqdc(semester.getSequenceNumber());
}
}
private LocalDateTime defaultEndTime(Integer nd, Integer xqdc) {
if (nd == null || xqdc == null) {
return null;
}
SemesterInitializationVO semester = systemInitializationMapper.selectSemesterByKey(nd, xqdc);
return semester == null ? null : semester.getEndAt();
}
private void fillSemesterName(TeachingTaskVO row) {
if (row == null || row.getNd() == null || row.getXqdc() == null) {
return;
}
SemesterInitializationVO semester = systemInitializationMapper.selectSemesterByKey(row.getNd(), row.getXqdc());
if (semester != null && StringUtils.isNotEmpty(semester.getSemesterName())) {
row.setXqmc(semester.getSemesterName());
} else {
row.setXqmc(row.getNd() + "年第" + row.getXqdc() + "学期");
}
}
private TeachingTaskVO toSimpleVo(JXRW entity) {
TeachingTaskVO vo = new TeachingTaskVO();
vo.setBh(entity.getBh());
vo.setRwmc(entity.getRwmc());
vo.setNd(entity.getNd());
vo.setZt(entity.getZt());
vo.setFbsj(entity.getFbsj());
vo.setCjsj(entity.getCjsj());
vo.setJssj(entity.getJssj());
return vo;
}
private void bindSquads(String jxrwbh, Integer nd, Integer xqdc, List<String> xydxqbhList) {
classSemesterMapper.update(null, new LambdaUpdateWrapper<XYDNDXQJBXXB>()
.eq(XYDNDXQJBXXB::getJxrwbh, jxrwbh)
.set(XYDNDXQJBXXB::getJxrwbh, null));
if (CollectionUtils.isEmpty(xydxqbhList)) {
return;
}
for (String xydxqbh : xydxqbhList) {
if (StringUtils.isEmpty(xydxqbh)) {
continue;
}
XYDNDXQJBXXB semester = classSemesterMapper.selectById(xydxqbh);
if (semester == null || Integer.valueOf(1).equals(semester.getDelFlag())) {
throw new ServiceException("学员队学期信息不存在:" + xydxqbh, NOT_FOUND);
}
if (nd != null && semester.getNd() != null && !nd.equals(semester.getNd())) {
throw new ServiceException("所选学员队不属于该学期", BAD_REQUEST);
}
if (xqdc != null && semester.getXqdc() != null && !xqdc.equals(semester.getXqdc())) {
throw new ServiceException("所选学员队不属于该学期", BAD_REQUEST);
}
if (StringUtils.isNotEmpty(semester.getJxrwbh()) && !jxrwbh.equals(semester.getJxrwbh())) {
throw new ServiceException("学员队已被其他教学任务占用", CONFLICT);
}
semester.setJxrwbh(jxrwbh);
classSemesterMapper.updateById(semester);
}
}
private void generateCourseTasksAndOfficeBooks(String jxrwbh) {
List<XYDNDXQJBXXB> squads = classSemesterMapper.selectList(new LambdaQueryWrapper<XYDNDXQJBXXB>()
.eq(XYDNDXQJBXXB::getJxrwbh, jxrwbh)
.eq(XYDNDXQJBXXB::getDelFlag, 0));
for (XYDNDXQJBXXB squad : squads) {
if (StringUtils.isEmpty(squad.getXydbh()) || squad.getXqdc() == null) {
continue;
}
try {
studentTeamTaskService.autoGenerateRequiredCourses(squad.getXydbh(), squad.getXqdc());
} catch (Exception ignored) {
// 课程任务已存在或计划缺失时,仍继续生成教研室任务书
}
}
Set<String> jysdhSet = collectOfficeCodes(squads);
for (String jysdh : jysdhSet) {
Long exist = officeTaskBookMapper.selectCount(new LambdaQueryWrapper<JYSRWS>()
.eq(JYSRWS::getJxrwbh, jxrwbh)
.eq(JYSRWS::getJysdh, jysdh)
.eq(JYSRWS::getDelFlag, 0));
if (exist != null && exist > 0) {
continue;
}
JYSRWS book = new JYSRWS();
book.setBh(UuidUtil.getOriginalUUID());
book.setJxrwbh(jxrwbh);
book.setJysdh(jysdh);
book.setZt(OFFICE_STATUS_UNREPORTED);
book.setDelFlag(0);
officeTaskBookMapper.insert(book);
}
}
private Set<String> collectOfficeCodes(List<XYDNDXQJBXXB> squads) {
Set<String> codes = new LinkedHashSet<>();
List<String> xydxqbhList = new ArrayList<>();
for (XYDNDXQJBXXB squad : squads) {
xydxqbhList.add(squad.getBh());
if (StringUtils.isEmpty(squad.getXydbh()) || squad.getXqdc() == null) {
continue;
}
XYDB xyd = xydbMapper.selectById(squad.getXydbh());
if (xyd == null || StringUtils.isEmpty(xyd.getZydh())) {
continue;
}
List<ZYJXJHB> plans = zyjxjhbMapper.selectList(new LambdaQueryWrapper<ZYJXJHB>()
.eq(ZYJXJHB::getZydh, xyd.getZydh())
.eq(ZYJXJHB::getXqdc, squad.getXqdc())
.eq(ZYJXJHB::getTy, 0));
for (ZYJXJHB plan : plans) {
if (StringUtils.isNotEmpty(plan.getJysdh())) {
codes.add(plan.getJysdh());
continue;
}
if (StringUtils.isEmpty(plan.getKbh())) {
continue;
}
KB kb = kbMapper.selectById(plan.getKbh());
if (kb != null && StringUtils.isNotEmpty(kb.getJysdh())) {
codes.add(kb.getJysdh());
}
}
}
if (!xydxqbhList.isEmpty()) {
List<XYDRWB> tasks = studentTeamTaskMapper.selectList(new LambdaQueryWrapper<XYDRWB>()
.in(XYDRWB::getXydxqbh, xydxqbhList)
.eq(XYDRWB::getDelFlag, 0));
for (XYDRWB task : tasks) {
if (StringUtils.isNotEmpty(task.getJysdh())) {
codes.add(task.getJysdh());
}
}
}
return codes;
}
}
@@ -9,9 +9,11 @@ import com.roomroot.common.exception.ServiceException;
import com.roomroot.common.utils.SecurityUtils; import com.roomroot.common.utils.SecurityUtils;
import com.roomroot.common.utils.StringUtils; import com.roomroot.common.utils.StringUtils;
import com.roomroot.jwgl.entity.JYB; import com.roomroot.jwgl.entity.JYB;
import com.roomroot.jwgl.entity.XYDQB;
import com.roomroot.jwgl.entity.XYXX; import com.roomroot.jwgl.entity.XYXX;
import com.roomroot.jwgl.mapper.JYBMapper; import com.roomroot.jwgl.mapper.JYBMapper;
import com.roomroot.jwgl.mapper.JYSDLBMapper; import com.roomroot.jwgl.mapper.JYSDLBMapper;
import com.roomroot.jwgl.mapper.XYDQBMapper;
import com.roomroot.jwgl.mapper.XYXXMapper; import com.roomroot.jwgl.mapper.XYXXMapper;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -40,6 +42,9 @@ public class JwglRoleHelper {
@Resource @Resource
private JYSDLBMapper jysdlbMapper; private JYSDLBMapper jysdlbMapper;
@Resource
private XYDQBMapper xydqbMapper;
public boolean isAdmin() { public boolean isAdmin() {
try { try {
if (SecurityUtils.isAdmin()) { if (SecurityUtils.isAdmin()) {
@@ -112,6 +117,34 @@ public class JwglRoleHelper {
return studentId; return studentId;
} }
/**
* 当前学员所属学员队编号。课表按班次过滤时使用。
*/
public String requireStudentTeamId() {
String teamId = findStudentTeamId();
if (StringUtils.isEmpty(teamId)) {
throw new ServiceException("当前学员未分班,无法查看课表", FORBIDDEN);
}
return teamId;
}
public String findStudentTeamId() {
try {
String studentId = findStudentId();
if (StringUtils.isEmpty(studentId)) {
return null;
}
XYXX student = xyxxMapper.selectById(studentId);
if (student == null || StringUtils.isEmpty(student.getXydqbh())) {
return null;
}
XYDQB period = xydqbMapper.selectById(student.getXydqbh());
return period == null ? null : period.getXydbh();
} catch (Exception ignored) {
return null;
}
}
public String findTeacherId() { public String findTeacherId() {
try { try {
String username = SecurityUtils.getUsername(); String username = SecurityUtils.getUsername();
@@ -24,8 +24,29 @@ public class ScheduleAdjustApplyVO {
*/ */
private String sskcbbh; private String sskcbbh;
/** 学员队任务表编号 */
private String xydrwbh;
/** 课编号 */
private String kbh;
/** 课程表编号 */
private String kcbbh;
/** 学员队名称 */
private String xydmc;
/** 教研室代号 */
private String jysdh;
/** 原教室编号 */
private String yjsbh;
/** 拟调整教室编号 */
private String xjsbh;
/** /**
* 课程名称,关联课程表获取。 * 课程名称,关联课表获取。
*/ */
private String kcmc; private String kcmc;
@@ -26,6 +26,27 @@ public class ScheduleAdjustDetailVO {
*/ */
private String sskcbbh; private String sskcbbh;
/** 学员队任务表编号 */
private String xydrwbh;
/** 课编号 */
private String kbh;
/** 课程表编号 */
private String kcbbh;
/** 学员队名称 */
private String xydmc;
/** 教研室代号 */
private String jysdh;
/** 原教室编号 */
private String yjsbh;
/** 拟调整教室编号 */
private String xjsbh;
/** /**
* 课程名称。 * 课程名称。
*/ */
@@ -0,0 +1,45 @@
package com.roomroot.jwgl.vo.jwtest;
import lombok.Data;
/**
* 排课全查明细(课堂、课程、教师、班级、教室及上课时间)。
*/
@Data
public class PkLessonVO {
/** 课堂名称 */
private String ktmc;
/** 课程名称 */
private String kcmc;
/** 教学楼名称 */
private String jxlmc;
/** 教师名称 */
private String jymc;
/** 班级名称 */
private String bjmc;
/** 教室名称 */
private String jsmc;
/** 上课日期 */
private String skrq;
/** 开始时间 */
private String kssj;
/** 结束时间 */
private String jssj;
/** 学年学期 */
private String xnxq;
/** 周次 */
private Integer zc;
/** 应到人数 */
private Integer ydrs;
}
@@ -0,0 +1,32 @@
package com.roomroot.jwgl.vo.jys;
import com.roomroot.common.annotation.Excel;
import lombok.Data;
/**
* 选修班学员名单行。
*/
@Data
public class ElectiveCourseStudentVO {
@Excel(name = "序号", sort = 1)
private Integer xh;
@Excel(name = "选修班名称", sort = 2)
private String xxbmc;
@Excel(name = "课程", sort = 3)
private String kmc;
@Excel(name = "学号", sort = 4)
private String xhNo;
@Excel(name = "姓名", sort = 5)
private String xm;
@Excel(name = "性别", sort = 6)
private String xb;
@Excel(name = "联系电话", sort = 7)
private String lxdh;
}
@@ -0,0 +1,80 @@
package com.roomroot.jwgl.vo.jys;
import com.roomroot.common.annotation.Excel;
import lombok.Data;
/**
* 选修课管理列表行。
*/
@Data
public class ElectiveCourseVO {
/** 学员队任务编号 */
private String bh;
/** 年度 */
private Integer nd;
/** 学员队编号 */
private String xydbh;
/** 课编号 */
private String kbh;
/** 教员编号 */
private String jybh;
/** 教室编号 */
private String jsbh;
@Excel(name = "序号", sort = 1)
private Integer xh;
@Excel(name = "课程", sort = 2)
private String kmc;
@Excel(name = "教材", sort = 3)
private String jcmc;
@Excel(name = "实施教员", sort = 4)
private String jyxm;
@Excel(name = "教学场地", sort = 5)
private String jsmc;
@Excel(name = "显示可选队列班次", sort = 6, width = 28)
private String kxdlbc;
/** 计划学时 */
private Integer jhxs;
/** 运行学时 */
private Integer yxxs;
/** 学分 */
private Float xf;
@Excel(name = "计划学时/运行学时/学分", sort = 7, width = 24)
private String jhyxxsxf;
@Excel(name = "开课结课日期", sort = 8, width = 24)
private String kkjkrq;
@Excel(name = "报名日期", sort = 9, width = 24)
private String bmrq;
@Excel(name = "计划人数", sort = 10)
private Integer jhrs;
@Excel(name = "要求说明", sort = 11, width = 24)
private String yqsm;
@Excel(name = "选修班名称", sort = 12)
private String xxbmc;
@Excel(name = "选择课状态", sort = 13)
private String xkzt;
@Excel(name = "培训层次", sort = 14)
private String pxcc;
}
@@ -0,0 +1,28 @@
package com.roomroot.jwgl.vo.jys;
import lombok.Data;
/**
* 教研室任务书课程明细。
*/
@Data
public class TeachingOfficeBookCourseVO {
private String rwbh;
private String kbh;
private String kmc;
private String klx;
private Integer xs;
private String xydbh;
private String xydmc;
private String jysjhjybh;
private String jysjhjyxm;
}
@@ -0,0 +1,32 @@
package com.roomroot.jwgl.vo.jys;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 教研室任务书列表行。
*/
@Data
public class TeachingOfficeBookVO {
private String bh;
private String jxrwbh;
private String jysdh;
private String jysmc;
private String zt;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime sbsj;
/** 学员队课程任务数 */
private Integer xydkcrws;
/** 完成指定数(已指定计划教员的课程任务数) */
private Integer wczds;
}
@@ -0,0 +1,19 @@
package com.roomroot.jwgl.vo.jys;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* 教学任务详情(含教研室任务书、学员队两个页签数据)。
*/
@Data
public class TeachingTaskDetailVO {
private TeachingTaskVO task;
private List<TeachingOfficeBookVO> officeBooks = new ArrayList<>();
private List<TeachingTaskSquadVO> squads = new ArrayList<>();
}
@@ -0,0 +1,41 @@
package com.roomroot.jwgl.vo.jys;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.time.LocalDate;
/**
* 教学任务关联的学员队(班次)行。
*/
@Data
public class TeachingTaskSquadVO {
/** 学员队年度学期基本信息编号 */
private String xydxqbh;
private String xydbh;
private String xydmc;
private String nj;
private String zydh;
private String zymc;
private Integer xydrs;
private Integer nd;
private Integer xqdc;
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private LocalDate kxrq;
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private LocalDate jsrq;
/** 是否已被其他教学任务占用 */
private Integer occupied;
}
@@ -0,0 +1,53 @@
package com.roomroot.jwgl.vo.jys;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 教学任务列表行。
*/
@Data
public class TeachingTaskVO {
private String bh;
private String rwmc;
private Integer nd;
private Integer xqdc;
/** 学期名称,如 2026年春季学期 */
private String xqmc;
private String zt;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime fbsj;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime cjsj;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime jssj;
/** 教研室数 */
private Integer jyss;
/** 学员队数 */
private Integer xyds;
/** 合班前课程任务数 */
private Integer hbqkcrws;
/** 合班前总学时数 */
private Integer hbqzxs;
/** 合班后课程任务数 */
private Integer hbhkcrws;
/** 合班后总学时数 */
private Integer hbhzxs;
}
@@ -0,0 +1,38 @@
package com.roomroot.jwgl.vo.kcb;
import com.roomroot.common.annotation.Excel;
import lombok.Data;
/**
* 班次课表行。
*/
@Data
public class ClassTimetableVO {
/** 实施_课程编号 */
private String sskcbh;
@Excel(name = "课程名称/课时系数", sort = 1, width = 28)
private String kcmcksxs;
@Excel(name = "责任教员/课次", sort = 2, width = 20)
private String zrjykc;
@Excel(name = "计划学时", sort = 3)
private Integer jhxs;
@Excel(name = "运行学时", sort = 4)
private Integer yxxs;
@Excel(name = "考核类型方式", sort = 5, width = 16)
private String khlxfs;
@Excel(name = "实施教员", sort = 6, width = 16)
private String ssjy;
@Excel(name = "人数/场地", sort = 7, width = 22)
private String rscd;
@Excel(name = "实施计划变更", sort = 8, width = 28)
private String ssjhbg;
}
@@ -0,0 +1,38 @@
package com.roomroot.jwgl.vo.kcb;
import com.roomroot.common.annotation.Excel;
import lombok.Data;
/**
* 今日课表、本周课表、学期教学实施计划行。
*/
@Data
public class DailyWeeklyTimetableVO {
/** 实施_课程表编号 */
private String bh;
@Excel(name = "上课时间", sort = 1, width = 22)
private String sksj;
@Excel(name = "课程", sort = 2, width = 20)
private String kc;
@Excel(name = "责任单位", sort = 3, width = 18)
private String zrdw;
@Excel(name = "班次", sort = 4, width = 24)
private String bc;
@Excel(name = "教员", sort = 5, width = 16)
private String jy;
@Excel(name = "场地", sort = 6, width = 18)
private String cd;
@Excel(name = "教学内容方法", sort = 7, width = 28)
private String jxnrxff;
@Excel(name = "备注", sort = 8, width = 20)
private String bz;
}
@@ -0,0 +1,35 @@
package com.roomroot.jwgl.vo.kcb;
import com.roomroot.common.annotation.Excel;
import lombok.Data;
/**
* 学期成绩表导出行。
*/
@Data
public class SemesterGradeExportVO {
@Excel(name = "学号", sort = 1)
private String xh;
@Excel(name = "姓名", sort = 2)
private String xm;
@Excel(name = "课程", sort = 3, width = 20)
private String kcmc;
@Excel(name = "平时成绩", sort = 4)
private Float pscj;
@Excel(name = "考试成绩", sort = 5)
private Float kscj;
@Excel(name = "最终成绩", sort = 6)
private Float zzcj;
@Excel(name = "考试情况", sort = 7)
private String ksqk;
@Excel(name = "年度", sort = 8)
private Integer nd;
}
-22
View File
@@ -1,22 +0,0 @@
# 告诉EditorConfig插件,这是根文件,不用继续往上查找
root = true
# 匹配全部文件
[*]
# 设置字符集
charset = utf-8
# 缩进风格,可选space、tab
indent_style = space
# 缩进的空格数
indent_size = 2
# 结尾换行符,可选lf、cr、crlf
end_of_line = lf
# 在文件结尾插入新行
insert_final_newline = true
# 删除一行中的前后空格
trim_trailing_whitespace = true
# 匹配md结尾的文件
[*.md]
insert_final_newline = false
trim_trailing_whitespace = false
-11
View File
@@ -1,11 +0,0 @@
# 页面标题
VUE_APP_TITLE = 教学管理信息系统
# 开发环境配置
ENV = 'development'
# 智慧教学管理系统/开发环境
VUE_APP_BASE_API = '/api'
# 路由懒加载
VUE_CLI_BABEL_TRANSPILE_MODULES = true
-8
View File
@@ -1,8 +0,0 @@
# 页面标题
VUE_APP_TITLE = 教学管理信息系统
# 生产环境配置
ENV = 'production'
# 智慧教学管理系统/生产环境
VUE_APP_BASE_API = '/prod-api'
-12
View File
@@ -1,12 +0,0 @@
# 页面标题
VUE_APP_TITLE = 教学管理信息系统
BABEL_ENV = production
NODE_ENV = production
# 测试环境配置
ENV = 'staging'
# 智慧教学管理系统/测试环境
VUE_APP_BASE_API = '/stage-api'
-23
View File
@@ -1,23 +0,0 @@
.DS_Store
node_modules/
dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
**/*.log
tests/**/coverage/
tests/e2e/reports
selenium-debug.log
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.local
package-lock.json
yarn.lock
-30
View File
@@ -1,30 +0,0 @@
## 开发
```bash
# 克隆项目
git clone https://gitee.com/y_project/RuoYi-Vue
# 进入项目目录
cd ruoyi-ui
# 安装依赖
npm install
# 建议不要直接使用 cnpm 安装依赖,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题
npm install --registry=https://registry.npmmirror.com
# 启动服务
npm run dev
```
浏览器访问 http://localhost:80
## 发布
```bash
# 构建测试环境
npm run build:stage
# 构建生产环境
npm run build:prod
```
-13
View File
@@ -1,13 +0,0 @@
module.exports = {
presets: [
// https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app
'@vue/cli-plugin-babel/preset'
],
'env': {
'development': {
// babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require().
// This plugin can significantly increase the speed of hot updates, when you have a large number of pages.
'plugins': ['dynamic-import-node']
}
}
}
-71
View File
@@ -1,71 +0,0 @@
{
"name": "roomroot",
"version": "3.9.2",
"description": "教学管理信息系统",
"author": "教务",
"license": "MIT",
"scripts": {
"dev": "vue-cli-service serve",
"build:prod": "vue-cli-service build",
"build:stage": "vue-cli-service build --mode staging",
"preview": "node build/index.js --preview"
},
"keywords": [
"vue",
"admin",
"dashboard",
"element-ui",
"boilerplate",
"admin-template",
"management-system"
],
"repository": {
"type": "git",
"url": "https://gitee.com/y_project/roomroot-Vue.git"
},
"dependencies": {
"@riophae/vue-treeselect": "0.4.0",
"axios": "0.30.3",
"clipboard": "2.0.8",
"core-js": "3.37.1",
"echarts": "5.4.0",
"element-ui": "2.15.14",
"file-saver": "2.0.5",
"fuse.js": "6.4.3",
"highlight.js": "9.18.5",
"js-beautify": "1.13.0",
"js-cookie": "3.0.1",
"jsencrypt": "3.0.0-rc.1",
"nprogress": "0.2.0",
"quill": "2.0.2",
"screenfull": "5.0.2",
"sortablejs": "1.10.2",
"vue": "2.6.12",
"vue-count-to": "1.0.13",
"vue-cropper": "0.5.5",
"vue-router": "3.4.9",
"vuedraggable": "2.24.3",
"vuex": "3.6.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "4.4.6",
"@vue/cli-service": "4.4.6",
"babel-plugin-dynamic-import-node": "2.3.3",
"chalk": "4.1.0",
"compression-webpack-plugin": "6.1.2",
"connect": "3.6.6",
"sass": "1.32.13",
"sass-loader": "10.1.1",
"script-ext-html-webpack-plugin": "2.1.5",
"svg-sprite-loader": "5.1.1",
"vue-template-compiler": "2.6.12"
},
"engines": {
"node": ">=8.9",
"npm": ">= 3.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions"
]
}
Binary file not shown.
File diff suppressed because one or more lines are too long
-208
View File
@@ -1,208 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= webpackConfig.name %></title>
<!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
<style>
html,
body,
#app {
height: 100%;
margin: 0px;
padding: 0px;
}
.chromeframe {
margin: 0.2em 0;
background: #ccc;
color: #000;
padding: 0.2em 0;
}
#loader-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 999999;
}
#loader {
display: block;
position: relative;
left: 50%;
top: 50%;
width: 150px;
height: 150px;
margin: -75px 0 0 -75px;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #FFF;
-webkit-animation: spin 2s linear infinite;
-ms-animation: spin 2s linear infinite;
-moz-animation: spin 2s linear infinite;
-o-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
z-index: 1001;
}
#loader:before {
content: "";
position: absolute;
top: 5px;
left: 5px;
right: 5px;
bottom: 5px;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #FFF;
-webkit-animation: spin 3s linear infinite;
-moz-animation: spin 3s linear infinite;
-o-animation: spin 3s linear infinite;
-ms-animation: spin 3s linear infinite;
animation: spin 3s linear infinite;
}
#loader:after {
content: "";
position: absolute;
top: 15px;
left: 15px;
right: 15px;
bottom: 15px;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #FFF;
-moz-animation: spin 1.5s linear infinite;
-o-animation: spin 1.5s linear infinite;
-ms-animation: spin 1.5s linear infinite;
-webkit-animation: spin 1.5s linear infinite;
animation: spin 1.5s linear infinite;
}
@-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-ms-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes spin {
0% {
-webkit-transform: rotate(0deg);
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-ms-transform: rotate(360deg);
transform: rotate(360deg);
}
}
#loader-wrapper .loader-section {
position: fixed;
top: 0;
width: 51%;
height: 100%;
background: #7171C6;
z-index: 1000;
-webkit-transform: translateX(0);
-ms-transform: translateX(0);
transform: translateX(0);
}
#loader-wrapper .loader-section.section-left {
left: 0;
}
#loader-wrapper .loader-section.section-right {
right: 0;
}
.loaded #loader-wrapper .loader-section.section-left {
-webkit-transform: translateX(-100%);
-ms-transform: translateX(-100%);
transform: translateX(-100%);
-webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
}
.loaded #loader-wrapper .loader-section.section-right {
-webkit-transform: translateX(100%);
-ms-transform: translateX(100%);
transform: translateX(100%);
-webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
}
.loaded #loader {
opacity: 0;
-webkit-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
}
.loaded #loader-wrapper {
visibility: hidden;
-webkit-transform: translateY(-100%);
-ms-transform: translateY(-100%);
transform: translateY(-100%);
-webkit-transition: all 0.3s 1s ease-out;
transition: all 0.3s 1s ease-out;
}
.no-js #loader-wrapper {
display: none;
}
.no-js h1 {
color: #222222;
}
#loader-wrapper .load_title {
font-family: 'Open Sans';
color: #FFF;
font-size: 19px;
width: 100%;
text-align: center;
z-index: 9999999999999;
position: absolute;
top: 60%;
opacity: 1;
line-height: 30px;
}
#loader-wrapper .load_title span {
font-weight: normal;
font-style: italic;
font-size: 13px;
color: #FFF;
opacity: 0.5;
}
</style>
</head>
<body>
<div id="app">
<div id="loader-wrapper">
<div id="loader"></div>
<div class="loader-section section-left"></div>
<div class="loader-section section-right"></div>
<div class="load_title">正在加载系统资源,请耐心等待</div>
</div>
</div>
</body>
</html>
-2
View File
@@ -1,2 +0,0 @@
User-agent: *
Disallow: /
File diff suppressed because one or more lines are too long
-11
View File
@@ -1,11 +0,0 @@
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
export default {
name: "App"
}
</script>
-42
View File
@@ -1,42 +0,0 @@
import request from '@/utils/request'
// ======================== 课时补助核算:课时统计 / 课时费统计 ========================
// 接口前缀 /ks,经 vue.config.js 代理转发为 /api/ks;返回行为 HourStatisticsVO。
// 分页查询课时统计(支持 nd 年度、xq 学期序号、jyxm 教员姓名)
export function listHourStatistics(query) {
return request({
url: '/ks/hour-stat/list',
method: 'get',
params: query
})
}
// 导出课时统计 Excel(返回 Blob,文件名 课时统计.xlsx)
export function exportHourStatistics(query) {
return request({
url: '/ks/hour-stat/export',
method: 'get',
params: query,
responseType: 'blob'
})
}
// 分页查询课时费统计(支持 nd、xq、jyxm、ksfbzbh 课时费标准编号)
export function listFeeStatistics(query) {
return request({
url: '/ks/fee-stat/list',
method: 'get',
params: query
})
}
// 导出课时费统计 Excel(返回 Blob,文件名 课时费统计.xlsx)
export function exportFeeStatistics(query) {
return request({
url: '/ks/fee-stat/export',
method: 'get',
params: query,
responseType: 'blob'
})
}
@@ -1,69 +0,0 @@
import request from '@/utils/request'
// ======================== 联教联训管理(课时补助项目) ========================
// 接口前缀 /ks,经 vue.config.js 代理转发为 /api/ks;后端实体为 KSBZXM。
// 新增联教联训(编号为空时后端自动生成 UUID)
export function addJointTraining(data) {
return request({
url: '/ks/yjlx/add',
method: 'post',
data: data
})
}
// 删除联教联训
export function deleteJointTraining(bh) {
return request({
url: '/ks/yjlx/delete',
method: 'post',
params: { bh: bh }
})
}
// 修改联教联训
export function updateJointTraining(data) {
return request({
url: '/ks/yjlx/update',
method: 'post',
data: data
})
}
// 按编号查询联教联训详情
export function getJointTraining(bh) {
return request({
url: '/ks/yjlx/get',
method: 'get',
params: { bh: bh }
})
}
// 分页查询联教联训列表(支持名称模糊)
export function listJointTraining(query) {
return request({
url: '/ks/yjlx/list',
method: 'get',
params: query
})
}
// 导入联教联训 Excel(multipart,字段名 file)
export function importJointTraining(file) {
const formData = new FormData()
formData.append('file', file)
return request({
url: '/ks/yjlx/import',
method: 'post',
data: formData
})
}
// 导出联教联训到 Excel(返回 Blob)
export function exportJointTraining() {
return request({
url: '/ks/yjlx/export',
method: 'get',
responseType: 'blob'
})
}
-87
View File
@@ -1,87 +0,0 @@
import request from '@/utils/request'
// ======================== 方案管理:课时费方案 / 课时方案 ========================
// 接口前缀 /ks,经 vue.config.js 代理转发为 /api/ks。
// ---------- 课时费方案(KSFBZ) ----------
// 分页列表(名称模糊)
export function listFeeStandard(query) {
return request({
url: '/ks/fee-standard/list',
method: 'get',
params: query
})
}
// 详情
export function getFeeStandard(bh) {
return request({
url: '/ks/fee-standard/get',
method: 'get',
params: { bh: bh }
})
}
// 新增(编号为空时后端自动生成 UUID)
export function addFeeStandard(data) {
return request({
url: '/ks/fee-standard/add',
method: 'post',
data: data
})
}
// 编辑(编号必传)
export function updateFeeStandard(data) {
return request({
url: '/ks/fee-standard/update',
method: 'post',
data: data
})
}
// 删除
export function deleteFeeStandard(bh) {
return request({
url: '/ks/fee-standard/delete',
method: 'post',
params: { bh: bh }
})
}
// ---------- 课时方案(KSXSFA) ----------
// 分页列表(名称模糊)
export function listCoefficientPlan(query) {
return request({
url: '/ks/coefficient-plan/list',
method: 'get',
params: query
})
}
// 详情
export function getCoefficientPlan(bh) {
return request({
url: '/ks/coefficient-plan/get',
method: 'get',
params: { bh: bh }
})
}
// 新增(编号为空时后端自动生成 UUID)
export function addCoefficientPlan(data) {
return request({
url: '/ks/coefficient-plan/add',
method: 'post',
data: data
})
}
// 编辑(编号必传)
export function updateCoefficientPlan(data) {
return request({
url: '/ks/coefficient-plan/update',
method: 'post',
data: data
})
}
-125
View File
@@ -1,125 +0,0 @@
import request from '@/utils/request'
// ======================== 教学日志核心(以 api.txt 为准) ========================
// 接口前缀 /log,经 vue.config.js 代理转发为 /api/log(axios baseURL 为 /api)。
// 分页条件查询教学日志列表(待上报视图)
// 支持参数:pageNum pageSize ksrq jsrq kcmc jys jxff skjy rzzt pxqb gdqk gdxxqk rwlb
export function getTeachingLogList(query) {
return request({
url: '/log/teaching-log/list',
method: 'get',
params: query
})
}
// 分页条件查询已上报的教学日志列表(状态固定为「已上报」)
export function getReportedTeachingLogList(query) {
return request({
url: '/log/teaching-log/reported/list',
method: 'get',
params: query
})
}
// 分页条件查询已审核的教学日志列表(状态固定为「已审核」)
export function getAuditedTeachingLogList(query) {
return request({
url: '/log/teaching-log/audited/list',
method: 'get',
params: query
})
}
// 新增教学日志(请求体为 SSKCB_RZ 实体)
export function addTeachingLog(data) {
return request({
url: '/log/teaching-log/add',
method: 'post',
data: data
})
}
// 编辑教学日志(请求体为 SSKCB_RZ 实体,bh 必传)
export function updateTeachingLog(data) {
return request({
url: '/log/teaching-log/update',
method: 'post',
data: data
})
}
// 根据编号查询教学日志详情
export function getTeachingLogByBh(bh) {
return request({
url: '/log/teaching-log/get',
method: 'get',
params: { bh: bh }
})
}
// 提交教学日志审核,接口形态:POST /log/teaching-log/submit?bh=&targetStatus=
export function submitTeachingLog(bh, targetStatus) {
return request({
url: '/log/teaching-log/submit',
method: 'post',
params: { bh: bh, targetStatus: targetStatus }
})
}
// 审核通过教学日志,接口形态:GET /log/teaching-log/approve?bh=&feedback=
export function approveTeachingLog(bh, feedback) {
return request({
url: '/log/teaching-log/approve',
method: 'get',
params: { bh: bh, feedback: feedback }
})
}
// 退回教学日志(撤回重填),接口形态:POST /log/teaching-log/reject?bh=&thyj=
export function rejectTeachingLog(bh, thyj) {
return request({
url: '/log/teaching-log/reject',
method: 'post',
params: { bh: bh, thyj: thyj }
})
}
// 根据课表自动创建教学日志,接口形态:POST /log/teaching-log/auto-create?tybh=
export function autoCreateTeachingLog(tybh) {
return request({
url: '/log/teaching-log/auto-create',
method: 'post',
params: { tybh: tybh }
})
}
// 批量导入教学日志 Excel,接口形态:POST /log/teaching-log/import-excel(multipart,字段名 file)
export function importTeachingLogExcel(file) {
const formData = new FormData()
formData.append('file', file)
return request({
url: '/log/teaching-log/import-excel',
method: 'post',
data: formData
})
}
// 导出教学日志 Excel(返回 Blob),接口形态:GET /log/teaching-log/export
export function exportTeachingLog(query) {
return request({
url: '/log/teaching-log/export',
method: 'get',
params: query,
responseType: 'blob'
})
}
// 下载导入模板(返回 Blob),接口形态:GET /log/teaching-log/download-template
export function downloadTeachingLogTemplate() {
return request({
url: '/log/teaching-log/download-template',
method: 'get',
responseType: 'blob'
})
}
-58
View File
@@ -1,58 +0,0 @@
import request from '@/utils/request'
// 登录方法
export function login(username, password, code, uuid) {
const data = {
username,
password,
code,
uuid
}
return request({
url: '/login',
headers: {
isToken: false,
repeatSubmit: false
},
method: 'post',
data: data
})
}
// 注册方法
export function register(data) {
return request({
url: '/register',
headers: {
isToken: false
},
method: 'post',
data: data
})
}
// 获取用户详细信息
export function getInfo() {
return request({
url: '/getInfo',
method: 'get'
})
}
// 解锁屏幕
export function unlockScreen(password) {
return request({
url: '/unlockscreen',
method: 'post',
data: { password }
})
}
// 退出方法
export function logout() {
return request({
url: '/logout',
method: 'post'
})
}
-9
View File
@@ -1,9 +0,0 @@
import request from '@/utils/request'
// 获取路由
export const getRouters = () => {
return request({
url: '/getRouters',
method: 'get'
})
}
-57
View File
@@ -1,57 +0,0 @@
import request from '@/utils/request'
// 查询缓存详细
export function getCache() {
return request({
url: '/monitor/cache',
method: 'get'
})
}
// 查询缓存名称列表
export function listCacheName() {
return request({
url: '/monitor/cache/getNames',
method: 'get'
})
}
// 查询缓存键名列表
export function listCacheKey(cacheName) {
return request({
url: '/monitor/cache/getKeys/' + cacheName,
method: 'get'
})
}
// 查询缓存内容
export function getCacheValue(cacheName, cacheKey) {
return request({
url: '/monitor/cache/getValue/' + cacheName + '/' + cacheKey,
method: 'get'
})
}
// 清理指定名称缓存
export function clearCacheName(cacheName) {
return request({
url: '/monitor/cache/clearCacheName/' + cacheName,
method: 'delete'
})
}
// 清理指定键名缓存
export function clearCacheKey(cacheKey) {
return request({
url: '/monitor/cache/clearCacheKey/' + cacheKey,
method: 'delete'
})
}
// 清理全部缓存
export function clearCacheAll() {
return request({
url: '/monitor/cache/clearCacheAll',
method: 'delete'
})
}
-71
View File
@@ -1,71 +0,0 @@
import request from '@/utils/request'
// 查询定时任务调度列表
export function listJob(query) {
return request({
url: '/monitor/job/list',
method: 'get',
params: query
})
}
// 查询定时任务调度详细
export function getJob(jobId) {
return request({
url: '/monitor/job/' + jobId,
method: 'get'
})
}
// 新增定时任务调度
export function addJob(data) {
return request({
url: '/monitor/job',
method: 'post',
data: data
})
}
// 修改定时任务调度
export function updateJob(data) {
return request({
url: '/monitor/job',
method: 'put',
data: data
})
}
// 删除定时任务调度
export function delJob(jobId) {
return request({
url: '/monitor/job/' + jobId,
method: 'delete'
})
}
// 任务状态修改
export function changeJobStatus(jobId, status) {
const data = {
jobId,
status
}
return request({
url: '/monitor/job/changeStatus',
method: 'put',
data: data
})
}
// 定时任务立即执行一次
export function runJob(jobId, jobGroup) {
const data = {
jobId,
jobGroup
}
return request({
url: '/monitor/job/run',
method: 'put',
data: data
})
}
-26
View File
@@ -1,26 +0,0 @@
import request from '@/utils/request'
// 查询调度日志列表
export function listJobLog(query) {
return request({
url: '/monitor/jobLog/list',
method: 'get',
params: query
})
}
// 删除调度日志
export function delJobLog(jobLogId) {
return request({
url: '/monitor/jobLog/' + jobLogId,
method: 'delete'
})
}
// 清空调度日志
export function cleanJobLog() {
return request({
url: '/monitor/jobLog/clean',
method: 'delete'
})
}
-43
View File
@@ -1,43 +0,0 @@
import request from '@/utils/request'
// 查询登录日志列表
export function list(query) {
return request({
url: '/monitor/logininfor/list',
method: 'get',
params: query
})
}
// 查询首页登录日志列表
export function homeList(query) {
return request({
url: '/monitor/logininfor/homeList',
method: 'get',
params: query
})
}
// 删除登录日志
export function delLogininfor(infoId) {
return request({
url: '/monitor/logininfor/' + infoId,
method: 'delete'
})
}
// 解锁用户登录状态
export function unlockLogininfor(userName) {
return request({
url: '/monitor/logininfor/unlock/' + userName,
method: 'get'
})
}
// 清空登录日志
export function cleanLogininfor() {
return request({
url: '/monitor/logininfor/clean',
method: 'delete'
})
}
-18
View File
@@ -1,18 +0,0 @@
import request from '@/utils/request'
// 查询在线用户列表
export function list(query) {
return request({
url: '/monitor/online/list',
method: 'get',
params: query
})
}
// 强退用户
export function forceLogout(tokenId) {
return request({
url: '/monitor/online/' + tokenId,
method: 'delete'
})
}
-26
View File
@@ -1,26 +0,0 @@
import request from '@/utils/request'
// 查询操作日志列表
export function list(query) {
return request({
url: '/monitor/operlog/list',
method: 'get',
params: query
})
}
// 删除操作日志
export function delOperlog(operId) {
return request({
url: '/monitor/operlog/' + operId,
method: 'delete'
})
}
// 清空操作日志
export function cleanOperlog() {
return request({
url: '/monitor/operlog/clean',
method: 'delete'
})
}
-9
View File
@@ -1,9 +0,0 @@
import request from '@/utils/request'
// 获取服务信息
export function getServer() {
return request({
url: '/monitor/server',
method: 'get'
})
}
-34
View File
@@ -1,34 +0,0 @@
import request from '@/utils/request'
// ======================== 教学实施计划导入 ========================
// 接口前缀 /teachingPlan,经 vue.config.js 代理转发为 /api/teachingPlan。
// 分页查询教学实施计划列表
// 支持参数:pageNum pageSize nd kcmc bc zrdw skjy ytgjc ybdr(与后端 Mapper 一致)
export function listTeachingPlan(query) {
return request({
url: '/teachingPlan/list',
method: 'get',
params: query
})
}
// 导入教学实施计划 Excel(multipart,字段名 file),返回导入条数
export function importTeachingPlan(file) {
const formData = new FormData()
formData.append('file', file)
return request({
url: '/teachingPlan/import',
method: 'post',
data: formData
})
}
// 下载教学实施计划导入模板(返回 Blob)
export function downloadTeachingPlanTemplate() {
return request({
url: '/teachingPlan/template',
method: 'get',
responseType: 'blob'
})
}
@@ -1,49 +0,0 @@
import request from '@/utils/request'
// ======================== 学员学籍异动申请(实体 XYXJYDSQB) ========================
// 列表查询仅支持 bh / xybh / sqlx / zt 四个等值筛选。
// 分页查询学籍异动申请列表
export function listApplication(query) {
return request({
url: '/student-records/application/list',
method: 'get',
params: query
})
}
// 查询学籍异动申请详情(bh 异动申请编号)
export function getApplication(bh) {
return request({
url: '/student-records/application/get',
method: 'get',
params: { bh: bh }
})
}
// 新增学籍异动申请(请求体 XYXJYDSQB 实体;bh 需前端传入,创建/修改时间后端自动维护)
export function addApplication(data) {
return request({
url: '/student-records/application/add',
method: 'post',
data: data
})
}
// 编辑学籍异动申请(bh 异动申请编号必传,请求体 XYXJYDSQB 实体)
export function updateApplication(data) {
return request({
url: '/student-records/application/update',
method: 'post',
data: data
})
}
// 删除学籍异动申请(bh 异动申请编号)
export function delApplication(bh) {
return request({
url: '/student-records/application/delete',
method: 'post',
params: { bh: bh }
})
}
@@ -1,105 +0,0 @@
import request from '@/utils/request'
// ======================== 班历管理(实体 XYDRWB 学员队任务表) ========================
// 接口依据:api2.txt「班次学期日历(班历)」分组 + StudentTeamTaskController
// 每个班次学期(xydxqbh)下挂若干条课程任务记录:
// bh 编号、nd 年度、xydbh 学员队编号、kbh 课编号、xqdc 学期第次、jybh 教员编号、kcxh 课次序号、
// jsbh 教室编号、rs 人数、zks 周课时、xs 学时、klx 课类型、jc 简称、ksdd 考试地点、ksbh 考试编号、
// jysdh 教研室代号、jysjhjybh 教研室计划教员编号、jysjhbz 教研室计划备注、jhkcxh 计划课次序号、
// xhbs 序号标识、xydxqbh 学员队学期编号、bz 备注、xf 学分、cjsj/bdsj/kbbdsj 时间、
// ksks 考试课时、bz2 编组、cjfz 成绩分制、bjrxypjf 不计入学员平均分、llxs 理论学时、sjxs 实践学时、
// ksksbxs 考试课时不显示、pdxh 配档序号、pdqsz 配档起始周、pdaz 配档按周、pdzzksj 配档占正课时间、
// pdbz 配档编组、pdtbykxxbz 配当同班异课选修编组、pdzdyxsfbsj 配档自定义学时分布数据、
// pdqyzdyxs 配档启用自定义学时
// 查询某班次学期下的全部班历记录(xydxqbh 学员队学期编号)
export function listClassCalendar(xydxqbh) {
return request({
url: '/classCalendar/all',
method: 'get',
params: { xydxqbh: xydxqbh }
})
}
// 根据主键查询班历记录
export function getClassCalendar(bh) {
return request({
url: '/classCalendar/get',
method: 'get',
params: { bh: bh }
})
}
// 更新班历记录(请求体 XYDRWB,bh 必传)
export function updateClassCalendar(data) {
return request({
url: '/classCalendar/update',
method: 'post',
data: data
})
}
// 选定区域设置应用于其它班次(请求体 { sourceBhList: 源记录编号, targetBhList: 目标班次学期编号 })
export function batchCopyCalendar(data) {
return request({
url: '/classCalendar/batchCopy',
method: 'post',
data: data
})
}
// 整个班历应用于其它班次(请求体 { sourceXydxqbh: 源班次学期编号, targetBhList: 目标班次学期编号 })
export function batchCopyCalendarBySemester(data) {
return request({
url: '/classCalendar/batchCopyBySemester',
method: 'post',
data: data
})
}
// ======================== 学员队任务表操作(/studentTeamTask) ========================
// 新增班历记录(请求体 XYDRWB;bh 留空后端生成 UUID)
export function addTeamTask(data) {
return request({
url: '/studentTeamTask/add',
method: 'post',
data: data
})
}
// 删除班历记录(bh 编号)
export function delTeamTask(bh) {
return request({
url: '/studentTeamTask/delete',
method: 'post',
params: { bh: bh }
})
}
// 批量预设合班(请求体 { bhList },按年度排序生成统一课次序号)
export function batchPresetMerge(bhList) {
return request({
url: '/studentTeamTask/batchPresetMerge',
method: 'post',
data: { bhList: bhList }
})
}
// 批量预设拆班(请求体 { bhList },清空课次序号)
export function batchPresetSplit(bhList) {
return request({
url: '/studentTeamTask/batchPresetSplit',
method: 'post',
data: { bhList: bhList }
})
}
// 自动生成必修课程(按学员队+学期第次从专业教学计划生成班历记录)
export function autoGenerateRequiredCourses(xydbh, xqdc) {
return request({
url: '/studentTeamTask/autoGenerateRequiredCourses',
method: 'post',
params: { xydbh: xydbh, xqdc: xqdc }
})
}
-117
View File
@@ -1,117 +0,0 @@
import request from '@/utils/request'
// ======================== 班次学期管理(实体 XYDNDXQJBXXB 学员队年度学期基本信息表) ========================
// 接口依据:api1.txt「班次学期」分组,实际后端位于 StudentRecordsController (/student-records/semester/*)
// 列表仅支持 xydbh(学员队编号)模糊筛选,无年度筛选,前端需本地过滤
// 新增 bh 留空由后端生成 UUID;字段 nd 年度、xydbh 学员队编号、kxrq 开学日期、jsrq 结束日期、
// xqdc 学期第次、zyjsbh 专用教室编号、jxrwbh 教学任务编号、bdsj 变动时间、bz 备注、
// xhbs 序号标识、ysbbh 预设编班号、jclb 节次类别、xtms 系统模式、kfjypk 开放教员排课(0/1)、
// jsonzd、fxbgscsj 分析报告生成时间、fxbgwd1bh/fxbgwd2bh/fxbgwd3bh 分析报告文档编号
// 分页查询班次学期列表(支持 xydbh 模糊)
export function listSemester(query) {
return request({
url: '/student-records/semester/list',
method: 'get',
params: query
})
}
// 查询所有有效班次学期(DEL_FLAG = 0)
export function allSemester() {
return request({
url: '/student-records/semester/all',
method: 'get'
})
}
// 查询班次学期详情(bh 编号)
export function getSemester(bh) {
return request({
url: '/student-records/semester/get',
method: 'get',
params: { bh: bh }
})
}
// 新增班次学期(请求体 XYDNDXQJBXXB;bh 留空后端生成 UUID,delFlag 后端置 0)
export function addSemester(data) {
return request({
url: '/student-records/semester/add',
method: 'post',
data: data
})
}
// 编辑班次学期(bh 编号必传,请求体 XYDNDXQJBXXB)
export function updateSemester(data) {
return request({
url: '/student-records/semester/update',
method: 'post',
data: data
})
}
// 删除班次学期(逻辑删除并级联删除其班历记录)
export function delSemester(bh) {
return request({
url: '/student-records/semester/delete',
method: 'post',
params: { bh: bh }
})
}
// 批量删除班次学期(请求体为编号数组)
export function batchDeleteSemester(bhList) {
return request({
url: '/student-records/semester/batchDelete',
method: 'post',
data: bhList
})
}
// 批量设定学期日期(请求体 { bhList, xqkssj, xqjssj })
export function batchUpdateDateRange(data) {
return request({
url: '/student-records/semester/batchUpdateDateRange',
method: 'post',
data: data
})
}
// 批量修改开放教员排课状态(请求体 { bhList, kfjypk },0-否 1-是)
export function batchUpdateKfjypk(data) {
return request({
url: '/student-records/semester/batchUpdateKfjypk',
method: 'post',
data: data
})
}
// 批量修改学期第次(请求体 { bhList, xqdc })
export function batchUpdateXqdc(data) {
return request({
url: '/student-records/semester/batchUpdateXqdc',
method: 'post',
data: data
})
}
// 批量设置教学任务(请求体 { bhList, jxrwbh })
export function batchUpdateJxrwbh(data) {
return request({
url: '/student-records/semester/batchUpdateJxrwbh',
method: 'post',
data: data
})
}
// 批量创建班次学期(按时间范围筛选可建班的学员队;xqdc 传 春季学期/夏季学期/秋季学期)
// 参数:startTime 起始日、endTime 截止日、nd 年度、xqdc 学期
export function batchAddFromElective(params) {
return request({
url: '/student-records/semester/batchAddFromElective',
method: 'post',
params: params
})
}
@@ -1,84 +0,0 @@
import request from '@/utils/request'
// 分页查询学员信息列表(姓名/联系电话/通信地址支持模糊查询,其余实体字段可作为查询条件)
export function listStudentRecord(query) {
return request({
url: '/student-records/list',
method: 'get',
params: query
})
}
// 查询学员信息详情(bh 编号必传)
export function getStudentRecord(bh) {
return request({
url: '/student-records/get',
method: 'get',
params: { bh: bh }
})
}
// 新增学员信息
export function addStudentRecord(data) {
return request({
url: '/student-records/add',
method: 'post',
data: data
})
}
// 修改学员信息(bh 编号必传)
export function updateStudentRecord(data) {
return request({
url: '/student-records/update',
method: 'post',
data: data
})
}
// 删除学员信息(bh 编号)
export function delStudentRecord(bh) {
return request({
url: '/student-records/delete',
method: 'post',
params: { bh: bh }
})
}
// 分页查询学员课程成绩(xybh 学员编号必传;nd 年度可选)
export function listStudentGrades(query) {
return request({
url: '/student-records/grades',
method: 'get',
params: query
})
}
// 分页查询学员课程过程成绩(xybh 学员编号必传;nd 年度可选)
export function listStudentProcessGrades(query) {
return request({
url: '/student-records/process-grades',
method: 'get',
params: query
})
}
// 导出学员课程成绩 Excel(xybh 学员编号必传)
export function exportStudentGrades(xybh) {
return request({
url: '/student-records/export-grades',
method: 'get',
params: { xybh: xybh },
responseType: 'blob'
})
}
// 导出学员课程过程成绩 Excel(xybh 学员编号必传)
export function exportStudentProcessGrades(xybh) {
return request({
url: '/student-records/export-process-grades',
method: 'get',
params: { xybh: xybh },
responseType: 'blob'
})
}
-70
View File
@@ -1,70 +0,0 @@
import request from '@/utils/request'
// ======================== 班次(学员队)管理(实体 XYDB) ========================
// 分页列表查询条件为 XYDB 实体字段。
// 分页查询学员队列表
export function listTeam(query) {
return request({
url: '/student-records/team/list',
method: 'get',
params: query
})
}
// 查询学员队详情(xydbh 学员队编号)
export function getTeam(xydbh) {
return request({
url: '/student-records/team/get',
method: 'get',
params: { xydbh: xydbh }
})
}
// 新增学员队(请求体 XYDB)
export function addTeam(data) {
return request({
url: '/student-records/team/add',
method: 'post',
data: data
})
}
// 编辑学员队(xydbh 学员队编号必传,请求体 XYDB)
export function updateTeam(data) {
return request({
url: '/student-records/team/update',
method: 'post',
data: data
})
}
// 删除学员队(xydbh 学员队编号)
export function delTeam(xydbh) {
return request({
url: '/student-records/team/delete',
method: 'post',
params: { xydbh: xydbh }
})
}
// 导入学员队 Excel(multipart,字段名 file)
export function importTeam(file) {
const formData = new FormData()
formData.append('file', file)
return request({
url: '/student-records/team/import',
method: 'post',
data: formData
})
}
// 导出学员队 Excel(查询条件为 XYDB 实体)
export function exportTeam(query) {
return request({
url: '/student-records/team/export',
method: 'get',
params: query,
responseType: 'blob'
})
}
@@ -1,37 +0,0 @@
import request from '@/utils/request'
// 分页查询预警条件列表
export function listWarningCondition(query) {
return request({
url: '/student-records/warning-condition/list',
method: 'get',
params: query
})
}
// 查询预警条件详情
export function getWarningCondition(bh) {
return request({
url: '/student-records/warning-condition/get',
method: 'get',
params: { bh: bh }
})
}
// 新增预警条件
export function addWarningCondition(data) {
return request({
url: '/student-records/warning-condition/add',
method: 'post',
data: data
})
}
// 修改预警条件
export function updateWarningCondition(data) {
return request({
url: '/student-records/warning-condition/update',
method: 'post',
data: data
})
}
@@ -1,21 +0,0 @@
import request from '@/utils/request'
// ======================== 学员学籍预警结果(实体 XYXJYJGJG,查询:实体类) ========================
// 分页查询预警结果列表
export function listWarningResult(query) {
return request({
url: '/student-records/warning-result/list',
method: 'get',
params: query
})
}
// 查询预警结果详情(bh 预警结果编号)
export function getWarningResult(bh) {
return request({
url: '/student-records/warning-result/get',
method: 'get',
params: { bh: bh }
})
}
@@ -1,46 +0,0 @@
import request from '@/utils/request'
// 分页查询学科专业列表
export function listDiscipline(query) {
return request({
url: '/discipline/list',
method: 'get',
params: query
})
}
// 查询学科专业详情
export function getDiscipline(bsh) {
return request({
url: '/discipline/get',
method: 'get',
params: { bsh: bsh }
})
}
// 新增学科专业
export function addDiscipline(data) {
return request({
url: '/discipline/add',
method: 'post',
data: data
})
}
// 编辑学科专业
export function updateDiscipline(data) {
return request({
url: '/discipline/update',
method: 'post',
data: data
})
}
// 停用学科专业
export function disableDiscipline(bsh) {
return request({
url: '/discipline/disable',
method: 'post',
params: { bsh: bsh }
})
}
-56
View File
@@ -1,56 +0,0 @@
import request from '@/utils/request'
// 分页查询专业列表
export function listMajor(query) {
return request({
url: '/discipline/major/list',
method: 'get',
params: query
})
}
// 查询专业详情
export function getMajor(zydh) {
return request({
url: '/discipline/major/get',
method: 'get',
params: { zydh: zydh }
})
}
// 新增专业
export function addMajor(data) {
return request({
url: '/discipline/major/add',
method: 'post',
data: data
})
}
// 修改专业
export function updateMajor(data) {
return request({
url: '/discipline/major/update',
method: 'post',
data: data
})
}
// 删除专业
export function delMajor(zydh) {
return request({
url: '/discipline/major/delete',
method: 'post',
params: { zydh: zydh }
})
}
// 下载人才培养方案课程数据文件模板
export function downloadMajorTemplate() {
return request({
url: '/download/training-program',
method: 'get',
responseType: 'blob',
timeout: 30000
})
}
-60
View File
@@ -1,60 +0,0 @@
import request from '@/utils/request'
// 查询参数列表
export function listConfig(query) {
return request({
url: '/system/config/list',
method: 'get',
params: query
})
}
// 查询参数详细
export function getConfig(configId) {
return request({
url: '/system/config/' + configId,
method: 'get'
})
}
// 根据参数键名查询参数值
export function getConfigKey(configKey) {
return request({
url: '/system/config/configKey/' + configKey,
method: 'get'
})
}
// 新增参数配置
export function addConfig(data) {
return request({
url: '/system/config',
method: 'post',
data: data
})
}
// 修改参数配置
export function updateConfig(data) {
return request({
url: '/system/config',
method: 'put',
data: data
})
}
// 删除参数配置
export function delConfig(configId) {
return request({
url: '/system/config/' + configId,
method: 'delete'
})
}
// 刷新参数缓存
export function refreshCache() {
return request({
url: '/system/config/refreshCache',
method: 'delete'
})
}
-61
View File
@@ -1,61 +0,0 @@
import request from '@/utils/request'
// 查询部门列表
export function listDept(query) {
return request({
url: '/system/dept/list',
method: 'get',
params: query
})
}
// 查询部门列表(排除节点)
export function listDeptExcludeChild(deptId) {
return request({
url: '/system/dept/list/exclude/' + deptId,
method: 'get'
})
}
// 查询部门详细
export function getDept(deptId) {
return request({
url: '/system/dept/' + deptId,
method: 'get'
})
}
// 新增部门
export function addDept(data) {
return request({
url: '/system/dept',
method: 'post',
data: data
})
}
// 修改部门
export function updateDept(data) {
return request({
url: '/system/dept',
method: 'put',
data: data
})
}
// 保存部门排序
export function updateDeptSort(data) {
return request({
url: '/system/dept/updateSort',
method: 'put',
data: data
})
}
// 删除部门
export function delDept(deptId) {
return request({
url: '/system/dept/' + deptId,
method: 'delete'
})
}
-52
View File
@@ -1,52 +0,0 @@
import request from '@/utils/request'
// 查询字典数据列表
export function listData(query) {
return request({
url: '/system/dict/data/list',
method: 'get',
params: query
})
}
// 查询字典数据详细
export function getData(dictCode) {
return request({
url: '/system/dict/data/' + dictCode,
method: 'get'
})
}
// 根据字典类型查询字典数据信息
export function getDicts(dictType) {
return request({
url: '/system/dict/data/type/' + dictType,
method: 'get'
})
}
// 新增字典数据
export function addData(data) {
return request({
url: '/system/dict/data',
method: 'post',
data: data
})
}
// 修改字典数据
export function updateData(data) {
return request({
url: '/system/dict/data',
method: 'put',
data: data
})
}
// 删除字典数据
export function delData(dictCode) {
return request({
url: '/system/dict/data/' + dictCode,
method: 'delete'
})
}
-60
View File
@@ -1,60 +0,0 @@
import request from '@/utils/request'
// 查询字典类型列表
export function listType(query) {
return request({
url: '/system/dict/type/list',
method: 'get',
params: query
})
}
// 查询字典类型详细
export function getType(dictId) {
return request({
url: '/system/dict/type/' + dictId,
method: 'get'
})
}
// 新增字典类型
export function addType(data) {
return request({
url: '/system/dict/type',
method: 'post',
data: data
})
}
// 修改字典类型
export function updateType(data) {
return request({
url: '/system/dict/type',
method: 'put',
data: data
})
}
// 删除字典类型
export function delType(dictId) {
return request({
url: '/system/dict/type/' + dictId,
method: 'delete'
})
}
// 刷新字典缓存
export function refreshCache() {
return request({
url: '/system/dict/type/refreshCache',
method: 'delete'
})
}
// 获取字典选择框列表
export function optionselect() {
return request({
url: '/system/dict/type/optionselect',
method: 'get'
})
}
-69
View File
@@ -1,69 +0,0 @@
import request from '@/utils/request'
// 查询菜单列表
export function listMenu(query) {
return request({
url: '/system/menu/list',
method: 'get',
params: query
})
}
// 查询菜单详细
export function getMenu(menuId) {
return request({
url: '/system/menu/' + menuId,
method: 'get'
})
}
// 查询菜单下拉树结构
export function treeselect() {
return request({
url: '/system/menu/treeselect',
method: 'get'
})
}
// 根据角色ID查询菜单下拉树结构
export function roleMenuTreeselect(roleId) {
return request({
url: '/system/menu/roleMenuTreeselect/' + roleId,
method: 'get'
})
}
// 新增菜单
export function addMenu(data) {
return request({
url: '/system/menu',
method: 'post',
data: data
})
}
// 修改菜单
export function updateMenu(data) {
return request({
url: '/system/menu',
method: 'put',
data: data
})
}
// 保存菜单排序
export function updateMenuSort(data) {
return request({
url: '/system/menu/updateSort',
method: 'put',
data: data
})
}
// 删除菜单
export function delMenu(menuId) {
return request({
url: '/system/menu/' + menuId,
method: 'delete'
})
}
-79
View File
@@ -1,79 +0,0 @@
import request from '@/utils/request'
// 查询公告列表
export function listNotice(query) {
return request({
url: '/system/notice/list',
method: 'get',
params: query
})
}
// 查询公告详细
export function getNotice(noticeId) {
return request({
url: '/system/notice/' + noticeId,
method: 'get'
})
}
// 新增公告
export function addNotice(data) {
return request({
url: '/system/notice',
method: 'post',
data: data
})
}
// 修改公告
export function updateNotice(data) {
return request({
url: '/system/notice',
method: 'put',
data: data
})
}
// 删除公告
export function delNotice(noticeId) {
return request({
url: '/system/notice/' + noticeId,
method: 'delete'
})
}
// 首页顶部公告列表(带已读状态)
export function listNoticeTop() {
return request({
url: '/system/notice/listTop',
method: 'get'
})
}
// 标记公告已读
export function markNoticeRead(noticeId) {
return request({
url: '/system/notice/markRead',
method: 'post',
params: { noticeId }
})
}
// 批量标记已读
export function markNoticeReadAll(ids) {
return request({
url: '/system/notice/markReadAll',
method: 'post',
params: { ids }
})
}
// 查询公告已读用户列表
export function listNoticeReadUsers(query) {
return request({
url: '/system/notice/readUsers/list',
method: 'get',
params: query
})
}
-44
View File
@@ -1,44 +0,0 @@
import request from '@/utils/request'
// 查询岗位列表
export function listPost(query) {
return request({
url: '/system/post/list',
method: 'get',
params: query
})
}
// 查询岗位详细
export function getPost(postId) {
return request({
url: '/system/post/' + postId,
method: 'get'
})
}
// 新增岗位
export function addPost(data) {
return request({
url: '/system/post',
method: 'post',
data: data
})
}
// 修改岗位
export function updatePost(data) {
return request({
url: '/system/post',
method: 'put',
data: data
})
}
// 删除岗位
export function delPost(postId) {
return request({
url: '/system/post/' + postId,
method: 'delete'
})
}
-119
View File
@@ -1,119 +0,0 @@
import request from '@/utils/request'
// 查询角色列表
export function listRole(query) {
return request({
url: '/system/role/list',
method: 'get',
params: query
})
}
// 查询角色详细
export function getRole(roleId) {
return request({
url: '/system/role/' + roleId,
method: 'get'
})
}
// 新增角色
export function addRole(data) {
return request({
url: '/system/role',
method: 'post',
data: data
})
}
// 修改角色
export function updateRole(data) {
return request({
url: '/system/role',
method: 'put',
data: data
})
}
// 角色数据权限
export function dataScope(data) {
return request({
url: '/system/role/dataScope',
method: 'put',
data: data
})
}
// 角色状态修改
export function changeRoleStatus(roleId, status) {
const data = {
roleId,
status
}
return request({
url: '/system/role/changeStatus',
method: 'put',
data: data
})
}
// 删除角色
export function delRole(roleId) {
return request({
url: '/system/role/' + roleId,
method: 'delete'
})
}
// 查询角色已授权用户列表
export function allocatedUserList(query) {
return request({
url: '/system/role/authUser/allocatedList',
method: 'get',
params: query
})
}
// 查询角色未授权用户列表
export function unallocatedUserList(query) {
return request({
url: '/system/role/authUser/unallocatedList',
method: 'get',
params: query
})
}
// 取消用户授权角色
export function authUserCancel(data) {
return request({
url: '/system/role/authUser/cancel',
method: 'put',
data: data
})
}
// 批量取消用户授权角色
export function authUserCancelAll(data) {
return request({
url: '/system/role/authUser/cancelAll',
method: 'put',
params: data
})
}
// 授权用户选择
export function authUserSelectAll(data) {
return request({
url: '/system/role/authUser/selectAll',
method: 'put',
params: data
})
}
// 根据角色ID查询部门树结构
export function deptTreeSelect(roleId) {
return request({
url: '/system/role/deptTree/' + roleId,
method: 'get'
})
}
-136
View File
@@ -1,136 +0,0 @@
import request from '@/utils/request'
import { parseStrEmpty } from "@/utils/roomroot"
// 查询用户列表
export function listUser(query) {
return request({
url: '/system/user/list',
method: 'get',
params: query
})
}
// 查询用户详细
export function getUser(userId) {
return request({
url: '/system/user/' + parseStrEmpty(userId),
method: 'get'
})
}
// 新增用户
export function addUser(data) {
return request({
url: '/system/user',
method: 'post',
data: data
})
}
// 修改用户
export function updateUser(data) {
return request({
url: '/system/user',
method: 'put',
data: data
})
}
// 删除用户
export function delUser(userId) {
return request({
url: '/system/user/' + userId,
method: 'delete'
})
}
// 用户密码重置
export function resetUserPwd(userId, password) {
const data = {
userId,
password
}
return request({
url: '/system/user/resetPwd',
method: 'put',
data: data
})
}
// 用户状态修改
export function changeUserStatus(userId, status) {
const data = {
userId,
status
}
return request({
url: '/system/user/changeStatus',
method: 'put',
data: data
})
}
// 查询用户个人信息
export function getUserProfile() {
return request({
url: '/system/user/profile',
method: 'get'
})
}
// 修改用户个人信息
export function updateUserProfile(data) {
return request({
url: '/system/user/profile',
method: 'put',
data: data
})
}
// 用户密码重置
export function updateUserPwd(oldPassword, newPassword) {
const data = {
oldPassword,
newPassword
}
return request({
url: '/system/user/profile/updatePwd',
method: 'put',
data: data
})
}
// 用户头像上传
export function uploadAvatar(data) {
return request({
url: '/system/user/profile/avatar',
method: 'post',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: data
})
}
// 查询授权角色
export function getAuthRole(userId) {
return request({
url: '/system/user/authRole/' + userId,
method: 'get'
})
}
// 保存授权角色
export function updateAuthRole(data) {
return request({
url: '/system/user/authRole',
method: 'put',
params: data
})
}
// 查询部门下拉树结构
export function deptTreeSelect() {
return request({
url: '/system/user/deptTree',
method: 'get'
})
}
@@ -1,95 +0,0 @@
import request from '@/utils/request'
// 教学场地/教室管理(JSB 教室表 /classroom)
// 接口依据:classroom 控制器(前端 baseURL 为 /api,此处不重复 /api 前缀)
/**
* 新增教室
* POST /classroom/add
* 请求体(JSB):id/jsbh/jsmc 必填,其余字段可空;ty/xslx 为 Boolean
*/
export function addClassroom(data) {
return request({
url: '/classroom/add',
method: 'post',
data
})
}
/**
* 删除教室(不提供批量删除接口)
* POST /classroom/delete
* @param id 教室编号(主键,必填)
*/
export function deleteClassroom(id) {
return request({
url: '/classroom/delete',
method: 'post',
params: { id }
})
}
/**
* 更新教室
* POST /classroom/update
* 请求体(JSB):id 必传
*/
export function updateClassroom(data) {
return request({
url: '/classroom/update',
method: 'post',
data
})
}
/**
* 根据编号查询教室详情
* GET /classroom/get
* @param id 教室编号
*/
export function getClassroom(id) {
return request({
url: '/classroom/get',
method: 'get',
params: { id }
})
}
/**
* 分页查询教室列表
* GET /classroom/list
* 查询参数:jsbh(模糊)、jsmc(模糊)、jxldh(等值)、jxcdlx(等值)、ty(等值)、pageNum、pageSize
* 返回:PageResult<JSB>(records/total)
*/
export function listClassroom(params) {
return request({
url: '/classroom/list',
method: 'get',
params
})
}
/**
* 查询全部教室
* GET /classroom/all
* 返回:List<JSB>(无分页)
*/
export function listAllClassroom() {
return request({
url: '/classroom/all',
method: 'get'
})
}
/**
* 根据教学楼代号查询教室
* GET /classroom/listByJxldh
* @param jxldh 教学楼代号(必填)
*/
export function listClassroomByJxldh(jxldh) {
return request({
url: '/classroom/listByJxldh',
method: 'get',
params: { jxldh }
})
}

Some files were not shown because too many files have changed in this diff Show More