forked from liweijie/education
课表申请功能重写 bug修复
This commit is contained in:
+4
-84
@@ -18,7 +18,6 @@ import com.roomroot.jwgl.dto.courserunning.StudentLeaveApplyDTO;
|
||||
import com.roomroot.jwgl.dto.courserunning.StudentLeaveAuditDTO;
|
||||
import com.roomroot.jwgl.dto.courserunning.StudentLeaveQueryDTO;
|
||||
import com.roomroot.jwgl.dto.courserunning.OperationAnalysisQueryDTO;
|
||||
import com.roomroot.jwgl.dto.courserunning.ScheduleAdjustStrategyDTO;
|
||||
import com.roomroot.jwgl.unit.PageResult;
|
||||
import com.roomroot.jwgl.vo.courserunning.AdjustableLessonVO;
|
||||
import com.roomroot.jwgl.vo.courserunning.CourseRunningImportResultVO;
|
||||
@@ -37,7 +36,6 @@ import com.roomroot.jwgl.vo.courserunning.OperationOverviewVO;
|
||||
import com.roomroot.jwgl.vo.courserunning.CourseCompletionByDeptVO;
|
||||
import com.roomroot.jwgl.vo.courserunning.VenueUsageRateVO;
|
||||
import com.roomroot.jwgl.vo.courserunning.ScheduleAdjustTrendVO;
|
||||
import com.roomroot.jwgl.vo.courserunning.ScheduleAdjustStrategyVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -215,101 +213,23 @@ public interface CourseRunningImportService {
|
||||
/**
|
||||
* 教研室审批调课申请。
|
||||
* <p>
|
||||
* 教研室审批教员提交的调课申请,包含同意、发回、拒绝三种处理方式。
|
||||
* 同意时同步更新课次数据,发回时记录发回原因,拒绝时标记申请为已拒绝。
|
||||
* 教研室审批调课申请。点审批即已查收,审批人同时记为查收人。
|
||||
* 同意后写回课次;发回、拒绝也记为已查收。
|
||||
* </p>
|
||||
*
|
||||
* @param dto 教研室审批参数
|
||||
*/
|
||||
void auditByTeachingOffice(ScheduleAdjustAuditDTO dto);
|
||||
|
||||
/**
|
||||
* 教研室查收调课申请。
|
||||
* <p>
|
||||
* 教研室查收调课申请,标记查收状态和查收时间。
|
||||
* </p>
|
||||
*
|
||||
* @param ssdksqbh 调课申请编号
|
||||
* @param csrbh 查收人编号
|
||||
*/
|
||||
void receiveByTeachingOffice(String ssdksqbh, String csrbh);
|
||||
|
||||
/**
|
||||
* 教学系审批调课申请。
|
||||
* <p>
|
||||
* 教学系审批教研室已同意的调课申请,包含同意、发回、拒绝三种处理方式。
|
||||
* 教学系同意后流转到机关审批。
|
||||
* </p>
|
||||
*
|
||||
* @param dto 教学系审批参数
|
||||
*/
|
||||
void auditByTeachingDepartment(ScheduleAdjustAuditDTO dto);
|
||||
|
||||
/**
|
||||
* 机关审批调课申请。
|
||||
* <p>
|
||||
* 机关审批教研室已同意的调课申请,包含同意、发回、拒绝三种处理方式。
|
||||
* 机关全部同意后调课申请最终生效,课次按调整后的内容执行。
|
||||
* </p>
|
||||
*
|
||||
* @param dto 机关审批参数
|
||||
*/
|
||||
void auditByAuthority(ScheduleAdjustAuditDTO dto);
|
||||
|
||||
/**
|
||||
* 机关查收调课申请。
|
||||
* <p>
|
||||
* 机关查收调课申请,标记查收状态和查收时间。
|
||||
* </p>
|
||||
*
|
||||
* @param ssdksqbh 调课申请编号
|
||||
* @param jgbh 机关编号
|
||||
* @param csrbh 查收人编号
|
||||
*/
|
||||
void receiveByAuthority(String ssdksqbh, String jgbh, String csrbh);
|
||||
|
||||
/**
|
||||
* 撤销调课申请。
|
||||
* <p>
|
||||
* 教员撤销自己提交的、未经过审批的调课申请。
|
||||
* 软删除调课申请,标记删除状态为1。
|
||||
* 教员撤销未经过审批的调课申请。列表已按登录教员过滤。
|
||||
* </p>
|
||||
*
|
||||
* @param ssdksqbh 调课申请编号
|
||||
* @param sqjybh 申请教员编号(用于权限校验)
|
||||
*/
|
||||
void cancelScheduleAdjust(String ssdksqbh, String sqjybh);
|
||||
|
||||
// ==================== 调课策略管理 ====================
|
||||
|
||||
/**
|
||||
* 查询调课策略列表。
|
||||
* <p>
|
||||
* 支持按策略类型筛选,返回所有策略(含停用)。
|
||||
* </p>
|
||||
*
|
||||
* @param cllx 策略类型:TIME_LIMIT/AUTO_APPROVE,为空时查询全部
|
||||
* @return 调课策略列表
|
||||
*/
|
||||
List<ScheduleAdjustStrategyVO> listScheduleAdjustStrategies(String cllx);
|
||||
|
||||
/**
|
||||
* 保存调课策略(新增或修改)。
|
||||
* <p>
|
||||
* 策略编号为空时执行新增,非空时执行修改。
|
||||
* </p>
|
||||
*
|
||||
* @param dto 策略参数
|
||||
* @return 策略编号
|
||||
*/
|
||||
String saveScheduleAdjustStrategy(ScheduleAdjustStrategyDTO dto);
|
||||
|
||||
/**
|
||||
* 删除调课策略。
|
||||
*
|
||||
* @param clbh 策略编号
|
||||
*/
|
||||
void deleteScheduleAdjustStrategy(String clbh);
|
||||
void cancelScheduleAdjust(String ssdksqbh);
|
||||
|
||||
// ==================== 教学保障管理 ====================
|
||||
|
||||
|
||||
@@ -76,6 +76,16 @@ public interface FacultyService {
|
||||
*/
|
||||
JYB getJYBById(String jYBH);
|
||||
|
||||
/**
|
||||
* 从 Excel(.xls/.xlsx) 导入教员
|
||||
*/
|
||||
int importJYBFromExcel(MultipartFile file) throws Exception;
|
||||
|
||||
/**
|
||||
* 导出教员到 Excel(.xlsx)
|
||||
*/
|
||||
void exportJYBExcel(jakarta.servlet.http.HttpServletResponse response) throws Exception;
|
||||
|
||||
/**
|
||||
* 分页条件查询教员列表
|
||||
*/
|
||||
|
||||
+6
@@ -53,4 +53,10 @@ public interface TrainingProgramService {
|
||||
* @return 分页结果
|
||||
*/
|
||||
PageResult<ZYB> pageList(PageQuery query, ZYB cond);
|
||||
|
||||
/** 从 Excel(.xls/.xlsx) 导入培养方案(专业) */
|
||||
int importZYBFromExcel(org.springframework.web.multipart.MultipartFile file) throws Exception;
|
||||
|
||||
/** 导出培养方案(专业)到 Excel(.xlsx) */
|
||||
void exportZYBExcel(jakarta.servlet.http.HttpServletResponse response) throws Exception;
|
||||
}
|
||||
|
||||
@@ -60,4 +60,10 @@ public interface ZYJXJHBService {
|
||||
* @return 列表
|
||||
*/
|
||||
List<ZYJXJHB> listByZydhAndTy(String zydh, Integer ty);
|
||||
|
||||
/** 从 Excel(.xls/.xlsx) 导入专业教学计划 */
|
||||
int importZYJXJHBFromExcel(org.springframework.web.multipart.MultipartFile file) throws Exception;
|
||||
|
||||
/** 导出专业教学计划到 Excel(.xlsx) */
|
||||
void exportZYJXJHBExcel(jakarta.servlet.http.HttpServletResponse response) throws Exception;
|
||||
}
|
||||
|
||||
+106
-645
@@ -112,12 +112,6 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
|
||||
@Resource
|
||||
private KCBMapper kcbMapper;
|
||||
|
||||
/**
|
||||
* 实施_调课申请审批 Mapper,用于调课申请审批记录的数据访问。
|
||||
*/
|
||||
@Resource
|
||||
private SSDKSQSPMapper ssdksqspMapper;
|
||||
|
||||
/**
|
||||
* 调课申请_教室 Mapper,用于调课申请中教室关联的数据访问。
|
||||
*/
|
||||
@@ -196,12 +190,6 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
|
||||
@Resource
|
||||
private OperationAnalysisMapper operationAnalysisMapper;
|
||||
|
||||
/**
|
||||
* 调课策略 Mapper,用于调课时间段限制策略与免审批策略的数据访问。
|
||||
*/
|
||||
@Resource
|
||||
private ScheduleAdjustStrategyMapper scheduleAdjustStrategyMapper;
|
||||
|
||||
/**
|
||||
* 教员表数据访问接口,用于审批时根据教员编号查询教研室代号。
|
||||
*/
|
||||
@@ -533,16 +521,17 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
|
||||
* @param operationContent 操作内容描述
|
||||
*/
|
||||
private void recordOperationLog(String targetId, String operationType, String operationContent) {
|
||||
// 创建日志实体
|
||||
KCJXYX_CZRZ log = new KCJXYX_CZRZ();
|
||||
log.setBh(UuidUtil.getOriginalUUID()); // 生成唯一编号
|
||||
log.setTybh(targetId); // 目标编号
|
||||
log.setCzlx(operationType); // 操作类型
|
||||
log.setCznr(operationContent); // 操作内容
|
||||
log.setCzsj(LocalDateTime.now()); // 操作时间
|
||||
|
||||
// 写入数据库
|
||||
kcjxyxCzrzMapper.insert(log);
|
||||
try {
|
||||
KCJXYX_CZRZ log = new KCJXYX_CZRZ();
|
||||
log.setBh(UuidUtil.getOriginalUUID());
|
||||
log.setTybh(targetId);
|
||||
log.setCzlx(operationType);
|
||||
log.setCznr(operationContent);
|
||||
log.setCzsj(LocalDateTime.now());
|
||||
kcjxyxCzrzMapper.insert(log);
|
||||
} catch (Exception ignored) {
|
||||
// 操作日志表缺失或字段不匹配时,不影响调课主流程
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 教学实施计划填写 ====================
|
||||
@@ -895,7 +884,6 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
|
||||
query.getNd(),
|
||||
query.getJyspzzt(),
|
||||
query.getJyscszt(),
|
||||
query.getJgspzt(),
|
||||
query.getSczt(),
|
||||
cjsjStartStr,
|
||||
cjsjEndStr
|
||||
@@ -910,61 +898,22 @@ 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);
|
||||
return ssdksqMapper.selectAdjustableLessons(jwglRoleHelper.requireTeacherId(), 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 teacherId = jwglRoleHelper.findTeacherId();
|
||||
if (StringUtils.isNotEmpty(teacherId)) {
|
||||
return teacherId.trim();
|
||||
}
|
||||
String username = SecurityUtils.getUsername();
|
||||
if (StringUtils.isNotEmpty(username)) {
|
||||
return username;
|
||||
@@ -987,37 +936,17 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
|
||||
*/
|
||||
@Override
|
||||
public ScheduleAdjustDetailVO getScheduleAdjustDetail(String ssdksqbh) {
|
||||
// 步骤1:校验调课申请编号参数
|
||||
if (ssdksqbh == null || ssdksqbh.trim().isEmpty()) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "调课申请编号不能为空");
|
||||
}
|
||||
|
||||
// 步骤2:查询调课申请主表信息
|
||||
ScheduleAdjustDetailVO detail = ssdksqMapper.selectDetailById(ssdksqbh);
|
||||
if (detail == null) {
|
||||
throw new BusinessException(BasicManagementConstants.NOT_FOUND, "未找到该调课申请");
|
||||
}
|
||||
SSDKSQ apply = ssdksqMapper.selectById(ssdksqbh);
|
||||
if (apply != null) {
|
||||
assertCanViewScheduleAdjust(apply);
|
||||
}
|
||||
|
||||
// 步骤3:查询关联的机关审批记录列表
|
||||
detail.setAuditList(ssdksqspMapper.selectBySsdksqbh(ssdksqbh));
|
||||
|
||||
// 步骤4:查询关联的新教室列表
|
||||
detail.setRoomList(dksqjsMapper.selectByDksqbh(ssdksqbh));
|
||||
|
||||
// 步骤5:查询关联的新辅助教员列表
|
||||
detail.setTeacherList(dksqfzjyMapper.selectByDksqbh(ssdksqbh));
|
||||
|
||||
// 步骤6:查询关联的新学员队列表
|
||||
detail.setTeamList(dksqxydMapper.selectByDksqbh(ssdksqbh));
|
||||
|
||||
// 步骤7:查询关联的新保障明细列表
|
||||
detail.setSupportList(dksqbzmxMapper.selectByDksqbh(ssdksqbh));
|
||||
|
||||
// 步骤8:返回调课申请完整详情
|
||||
return detail;
|
||||
}
|
||||
|
||||
@@ -1036,30 +965,11 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String submitScheduleAdjust(ScheduleAdjustApplyDTO dto) {
|
||||
if (dto == null) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "调课申请参数不能为空");
|
||||
}
|
||||
if (jwglRoleHelper.isDepartmentPersonnel()) {
|
||||
throw new BusinessException(BasicManagementConstants.FORBIDDEN, "机关人员仅可查看和审批,不能提交调课申请");
|
||||
}
|
||||
if (jwglRoleHelper.isResearchOffice()) {
|
||||
throw new BusinessException(BasicManagementConstants.FORBIDDEN, "教研室仅可查看和审批本室申请,不能提交调课申请");
|
||||
}
|
||||
if (StringUtils.isEmpty(dto.getSskcbbh())) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "课次编号不能为空");
|
||||
}
|
||||
if (dto.getSy() == null || dto.getSy().trim().isEmpty()) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "调课事由不能为空");
|
||||
}
|
||||
|
||||
String teacherId = jwglRoleHelper.requireTeacherId();
|
||||
SSKCB lesson = sskcbMapper.selectById(dto.getSskcbbh().trim());
|
||||
if (lesson == null) {
|
||||
if (lesson == null || (lesson.getSczt() != null && lesson.getSczt() == 1)) {
|
||||
throw new BusinessException(BasicManagementConstants.NOT_FOUND, "课次不存在");
|
||||
}
|
||||
if (lesson.getSczt() != null && lesson.getSczt() == 1) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "该课次已删除,不允许申请调课");
|
||||
}
|
||||
|
||||
AdjustableLessonVO picked = null;
|
||||
List<AdjustableLessonVO> mine = ssdksqMapper.selectAdjustableLessons(teacherId, lesson.getNd());
|
||||
@@ -1072,59 +982,55 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
|
||||
}
|
||||
}
|
||||
if (picked == null) {
|
||||
throw new BusinessException(BasicManagementConstants.FORBIDDEN, "只能对自己任课的课次申请调课");
|
||||
throw new BusinessException(BasicManagementConstants.NOT_FOUND, "课次不存在");
|
||||
}
|
||||
|
||||
validateScheduleAdjustTimeLimitStrategy(dto.getRq());
|
||||
boolean autoApproved = matchAutoApproveStrategy();
|
||||
|
||||
SSDKSQ apply = new SSDKSQ();
|
||||
String ssdksqbh = UuidUtil.getOriginalUUID();
|
||||
apply.setBh(ssdksqbh);
|
||||
apply.setSskcbbh(lesson.getBh());
|
||||
apply.setXydrwbh(StringUtils.isNotEmpty(dto.getXydrwbh()) ? dto.getXydrwbh() : picked.getXydrwbh());
|
||||
apply.setKbh(StringUtils.isNotEmpty(dto.getKbh()) ? dto.getKbh() : picked.getKbh());
|
||||
apply.setKcbbh(StringUtils.isNotEmpty(dto.getKcbbh()) ? dto.getKcbbh() : picked.getKcbbh());
|
||||
apply.setJysdh(picked.getJysdh());
|
||||
apply.setYjsbh(picked.getJsbh());
|
||||
apply.setXjsbh(resolveNewClassroom(dto));
|
||||
apply.setSqjybh(teacherId);
|
||||
apply.setSy(dto.getSy());
|
||||
apply.setYdsjap(resolveYdsjap(lesson));
|
||||
apply.setZxzt(0);
|
||||
apply.setYszt(0);
|
||||
apply.setXydrwbh(cut(StringUtils.isNotEmpty(dto.getXydrwbh()) ? dto.getXydrwbh() : picked.getXydrwbh(), 50));
|
||||
apply.setKbh(cut(StringUtils.isNotEmpty(dto.getKbh()) ? dto.getKbh() : picked.getKbh(), 50));
|
||||
apply.setKcbbh(cut(StringUtils.isNotEmpty(dto.getKcbbh()) ? dto.getKcbbh() : picked.getKcbbh(), 50));
|
||||
apply.setJysdh(cut(picked.getJysdh(), 50));
|
||||
apply.setYjsbh(cut(picked.getJsbh(), 50));
|
||||
apply.setXjsbh(cut(resolveNewClassroom(dto), 50));
|
||||
apply.setSqjybh(cut(teacherId, 50));
|
||||
apply.setSy(cut(dto.getSy(), 200));
|
||||
apply.setRq(dto.getRq());
|
||||
apply.setJc(dto.getJc());
|
||||
apply.setNd(dto.getNd() != null ? dto.getNd() : lesson.getNd());
|
||||
apply.setJxnr(dto.getJxnr());
|
||||
apply.setJc(dto.getJc() != null ? dto.getJc() : 0);
|
||||
apply.setNd(dto.getNd() != null ? dto.getNd() : (lesson.getNd() != null ? lesson.getNd() : 0));
|
||||
apply.setJxnr(cut(dto.getJxnr(), 500));
|
||||
apply.setJxyd(dto.getJxyd());
|
||||
apply.setJxff(dto.getJxff());
|
||||
String jxff = cut(dto.getJxff(), 50);
|
||||
apply.setJxff(jxff == null ? "" : jxff);
|
||||
apply.setJxbzbz(dto.getJxbzbz());
|
||||
apply.setYcxx(dto.getYcxx());
|
||||
String originalDesc = buildOriginalScheduleDesc(lesson);
|
||||
if (dto.getBz() != null && !dto.getBz().trim().isEmpty()) {
|
||||
apply.setBz(dto.getBz() + " | " + originalDesc);
|
||||
} else {
|
||||
apply.setBz(originalDesc);
|
||||
}
|
||||
if (autoApproved) {
|
||||
apply.setBz((apply.getBz() == null ? "" : apply.getBz() + " | ") + "[免审批策略自动通过]");
|
||||
apply.setJyspzzt(1);
|
||||
} else {
|
||||
apply.setJyspzzt(0);
|
||||
}
|
||||
apply.setBz(cut(dto.getBz(), 50));
|
||||
apply.setJyspzzt(0);
|
||||
apply.setJyscszt(0);
|
||||
apply.setSczt(0);
|
||||
apply.setFhzt(0);
|
||||
apply.setDk(1);
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
apply.setCjsj(now);
|
||||
apply.setCjsj(LocalDateTime.now());
|
||||
ssdksqMapper.insert(apply);
|
||||
|
||||
if (dto.getRoomList() != null && !dto.getRoomList().isEmpty()) {
|
||||
for (AdjustRoomDTO roomDto : dto.getRoomList()) {
|
||||
if (StringUtils.isEmpty(roomDto.getJsbh())) {
|
||||
continue;
|
||||
}
|
||||
DKSQJS roomEntity = new DKSQJS();
|
||||
roomEntity.setBh(UuidUtil.getOriginalUUID());
|
||||
roomEntity.setDksqbh(ssdksqbh);
|
||||
roomEntity.setJsbh(roomDto.getJsbh());
|
||||
roomEntity.setBz(roomDto.getBz());
|
||||
roomEntity.setNd(apply.getNd());
|
||||
roomEntity.setRq(apply.getRq());
|
||||
roomEntity.setJc(apply.getJc());
|
||||
dksqjsMapper.insert(roomEntity);
|
||||
}
|
||||
} else if (StringUtils.isNotEmpty(apply.getXjsbh())) {
|
||||
@@ -1132,44 +1038,61 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
|
||||
roomEntity.setBh(UuidUtil.getOriginalUUID());
|
||||
roomEntity.setDksqbh(ssdksqbh);
|
||||
roomEntity.setJsbh(apply.getXjsbh());
|
||||
roomEntity.setNd(apply.getNd());
|
||||
roomEntity.setRq(apply.getRq());
|
||||
roomEntity.setJc(apply.getJc());
|
||||
dksqjsMapper.insert(roomEntity);
|
||||
}
|
||||
if (dto.getTeacherList() != null && !dto.getTeacherList().isEmpty()) {
|
||||
for (AdjustTeacherDTO teacherDto : dto.getTeacherList()) {
|
||||
if (StringUtils.isEmpty(teacherDto.getFzjybh())) {
|
||||
continue;
|
||||
}
|
||||
DKSQFZJY teacherEntity = new DKSQFZJY();
|
||||
teacherEntity.setBh(UuidUtil.getOriginalUUID());
|
||||
teacherEntity.setDksqbh(ssdksqbh);
|
||||
teacherEntity.setFzjybh(teacherDto.getFzjybh());
|
||||
teacherEntity.setZjy(teacherDto.getZjy());
|
||||
teacherEntity.setZjy(teacherDto.getZjy() == null ? 0 : teacherDto.getZjy());
|
||||
teacherEntity.setBz(teacherDto.getBz());
|
||||
teacherEntity.setNd(apply.getNd());
|
||||
teacherEntity.setRq(apply.getRq());
|
||||
teacherEntity.setJc(apply.getJc());
|
||||
dksqfzjyMapper.insert(teacherEntity);
|
||||
}
|
||||
}
|
||||
if (dto.getTeamList() != null && !dto.getTeamList().isEmpty()) {
|
||||
for (AdjustTeamDTO teamDto : dto.getTeamList()) {
|
||||
if (StringUtils.isEmpty(teamDto.getXydbh())) {
|
||||
continue;
|
||||
}
|
||||
DKSQXYD teamEntity = new DKSQXYD();
|
||||
teamEntity.setBh(UuidUtil.getOriginalUUID());
|
||||
teamEntity.setDksqbh(ssdksqbh);
|
||||
teamEntity.setXydbh(teamDto.getXydbh());
|
||||
teamEntity.setNd(apply.getNd());
|
||||
teamEntity.setRq(apply.getRq());
|
||||
teamEntity.setJc(apply.getJc());
|
||||
dksqxydMapper.insert(teamEntity);
|
||||
}
|
||||
}
|
||||
if (dto.getSupportList() != null && !dto.getSupportList().isEmpty()) {
|
||||
for (AdjustSupportDTO supportDto : dto.getSupportList()) {
|
||||
if (StringUtils.isEmpty(supportDto.getBztgmxbh()) || supportDto.getSl() == null) {
|
||||
continue;
|
||||
}
|
||||
DKSQBZMX supportEntity = new DKSQBZMX();
|
||||
supportEntity.setBh(UuidUtil.getOriginalUUID());
|
||||
supportEntity.setSqbh(ssdksqbh);
|
||||
supportEntity.setBztgmxbh(supportDto.getBztgmxbh());
|
||||
supportEntity.setSl(supportDto.getSl());
|
||||
supportEntity.setBz(supportDto.getBz());
|
||||
supportEntity.setNd(apply.getNd());
|
||||
supportEntity.setRq(apply.getRq());
|
||||
supportEntity.setJc(apply.getJc());
|
||||
dksqbzmxMapper.insert(supportEntity);
|
||||
}
|
||||
}
|
||||
|
||||
if (autoApproved) {
|
||||
applyApprovedSchedule(apply);
|
||||
}
|
||||
|
||||
recordOperationLog(ssdksqbh, "申请", "提交调课申请:" + ssdksqbh);
|
||||
return ssdksqbh;
|
||||
}
|
||||
@@ -1203,6 +1126,32 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
|
||||
return kcbMapper.selectOne(wrapper);
|
||||
}
|
||||
|
||||
private int resolveYdsjap(SSKCB lesson) {
|
||||
if (lesson == null) {
|
||||
return 0;
|
||||
}
|
||||
if (lesson.getJhsjap() != null) {
|
||||
return lesson.getJhsjap();
|
||||
}
|
||||
if (lesson.getRq() != null) {
|
||||
return lesson.getRq().getYear() * 10000
|
||||
+ lesson.getRq().getMonthValue() * 100
|
||||
+ lesson.getRq().getDayOfMonth();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private String cut(String value, int max) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
String text = value.trim();
|
||||
if (text.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return text.length() <= max ? text : text.substring(0, max);
|
||||
}
|
||||
|
||||
private String resolveNewClassroom(ScheduleAdjustApplyDTO dto) {
|
||||
if (StringUtils.isNotEmpty(dto.getXjsbh())) {
|
||||
return dto.getXjsbh().trim();
|
||||
@@ -1217,8 +1166,8 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
|
||||
/**
|
||||
* 教研室审批调课申请。
|
||||
* <p>
|
||||
* 教研室审批教员提交的调课申请,包含同意、发回、拒绝三种处理方式。
|
||||
* 同意时同步更新课次数据,发回时记录发回原因,拒绝时标记申请为已拒绝。
|
||||
* 教研室审批调课申请。点审批即已查收,审批人同时记为查收人。
|
||||
* 同意后写回课次;发回、拒绝也记为已查收。
|
||||
* </p>
|
||||
*
|
||||
* @param dto 教研室审批参数
|
||||
@@ -1226,26 +1175,6 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void auditByTeachingOffice(ScheduleAdjustAuditDTO dto) {
|
||||
if (dto == null) {
|
||||
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())) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "审批角色不正确,应为jys");
|
||||
}
|
||||
if (dto.getSpzt() == null
|
||||
|| (dto.getSpzt() != 1 && dto.getSpzt() != 2 && dto.getSpzt() != 3)) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "审批结果不正确,应为1(同意)、2(发回)或3(拒绝)");
|
||||
}
|
||||
|
||||
SSDKSQ apply = ssdksqMapper.selectById(dto.getSsdksqbh());
|
||||
if (apply == null) {
|
||||
throw new BusinessException(BasicManagementConstants.NOT_FOUND, "调课申请不存在");
|
||||
@@ -1253,17 +1182,6 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
|
||||
if (apply.getSczt() != null && apply.getSczt() == 1) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "该调课申请已撤销,不允许审批");
|
||||
}
|
||||
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, "只能审批本教研室的调课申请");
|
||||
}
|
||||
}
|
||||
if (apply.getJyspzzt() != null && apply.getJyspzzt() != 0) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "该调课申请已审批,无需重复审批");
|
||||
}
|
||||
@@ -1273,275 +1191,36 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
|
||||
apply.setJyspzzt(dto.getSpzt());
|
||||
apply.setJyspzrbh(auditor);
|
||||
apply.setJyspzsj(now);
|
||||
apply.setJyscszt(1);
|
||||
apply.setJyscsrbh(auditor);
|
||||
apply.setJyscssj(now);
|
||||
apply.setFhyj(dto.getFhyj());
|
||||
if (dto.getSpzt() != null && dto.getSpzt() == 2) {
|
||||
if (dto.getSpzt() == 2) {
|
||||
apply.setFhzt(1);
|
||||
apply.setFhsj(now);
|
||||
}
|
||||
ssdksqMapper.updateById(apply);
|
||||
|
||||
recordOperationLog(apply.getBh(), "教研室审批", "教研室审批调课申请:" + apply.getBh()
|
||||
+ ",审批结果:" + dto.getSpzt() + ",审批意见:" + dto.getFhyj());
|
||||
}
|
||||
|
||||
/**
|
||||
* 教研室查收调课申请。
|
||||
* <p>
|
||||
* 教研室查收调课申请,标记查收状态和查收时间。
|
||||
* </p>
|
||||
*
|
||||
* @param ssdksqbh 调课申请编号
|
||||
* @param csrbh 查收人编号
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void receiveByTeachingOffice(String ssdksqbh, String csrbh) {
|
||||
// 步骤1:校验参数
|
||||
if (ssdksqbh == null || ssdksqbh.trim().isEmpty()) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "调课申请编号不能为空");
|
||||
}
|
||||
if (csrbh == null || csrbh.trim().isEmpty()) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "查收人编号不能为空");
|
||||
}
|
||||
|
||||
// 步骤2:查询调课申请实体
|
||||
SSDKSQ apply = ssdksqMapper.selectById(ssdksqbh);
|
||||
if (apply == null) {
|
||||
throw new BusinessException(BasicManagementConstants.NOT_FOUND, "调课申请不存在");
|
||||
}
|
||||
|
||||
// 步骤3:校验是否已查收,避免重复查收
|
||||
if (apply.getJyscszt() != null && apply.getJyscszt() == 1) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "该调课申请已查收,无需重复查收");
|
||||
}
|
||||
|
||||
// 步骤4:更新查收状态和查收时间
|
||||
apply.setJyscszt(1); // 教研室查收状态:已查收
|
||||
apply.setJyscsrbh(csrbh); // 教研室查收人编号
|
||||
apply.setJyscssj(LocalDateTime.now()); // 教研室查收时间
|
||||
apply.setUpdateTime(LocalDateTime.now()); // 更新时间
|
||||
ssdksqMapper.updateById(apply);
|
||||
|
||||
// 步骤5:记录查收操作日志
|
||||
recordOperationLog(apply.getBh(), "教研室查收", "教研室查收调课申请:" + apply.getBh());
|
||||
}
|
||||
|
||||
/**
|
||||
* 教学系审批调课申请。
|
||||
* <p>
|
||||
* 教学系审批教研室已同意的调课申请,包含同意、发回、拒绝三种处理方式。
|
||||
* 教学系同意后流转到机关审批,构成三级审批流程(教研室→教学系→机关)。
|
||||
* </p>
|
||||
*
|
||||
* @param dto 教学系审批参数
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void auditByTeachingDepartment(ScheduleAdjustAuditDTO dto) {
|
||||
// 步骤1:校验审批参数
|
||||
if (dto == null) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "审批参数不能为空");
|
||||
}
|
||||
if (!"jxx".equals(dto.getAuditRole())) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "审批角色不正确,应为jxx");
|
||||
}
|
||||
if (dto.getSpzt() == null
|
||||
|| (dto.getSpzt() != 1 && dto.getSpzt() != 2 && dto.getSpzt() != 3)) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "审批结果不正确,应为1(同意)、2(发回)或3(拒绝)");
|
||||
}
|
||||
|
||||
// 步骤2:查询调课申请实体
|
||||
SSDKSQ apply = ssdksqMapper.selectById(dto.getSsdksqbh());
|
||||
if (apply == null) {
|
||||
throw new BusinessException(BasicManagementConstants.NOT_FOUND, "调课申请不存在");
|
||||
}
|
||||
if (apply.getSczt() != null && apply.getSczt() == 1) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "该调课申请已撤销,不允许审批");
|
||||
}
|
||||
|
||||
// 步骤3:校验教研室是否已同意,教学系审批应在教研室同意之后进行
|
||||
if (apply.getJyspzzt() == null || apply.getJyspzzt() != 1) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "教研室未同意或未审批,无法进行教学系审批");
|
||||
}
|
||||
|
||||
// 步骤4:校验教学系是否已审批,避免重复审批
|
||||
if (apply.getJxxspzzt() != null && apply.getJxxspzzt() != 0) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "该调课申请教学系已审批,无需重复审批");
|
||||
}
|
||||
|
||||
// 步骤5:更新调课申请主表的教学系审批状态
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
apply.setJxxspzzt(dto.getSpzt()); // 教学系审批状态
|
||||
apply.setJxxspzrbh(dto.getSprbh()); // 教学系审批人编号
|
||||
apply.setJxxspzsj(now); // 教学系审批时间
|
||||
apply.setFhyj(dto.getFhyj()); // 发回意见
|
||||
apply.setUpdateTime(now); // 更新时间
|
||||
ssdksqMapper.updateById(apply);
|
||||
|
||||
// 步骤6:根据审批结果执行不同的后续处理
|
||||
if (dto.getSpzt() == 3) {
|
||||
// 拒绝:恢复课次原数据,标记申请最终结束
|
||||
restoreLessonSchedule(apply);
|
||||
} else if (dto.getSpzt() == 2) {
|
||||
// 发回:发回教研室,课次保留调整后数据,由教研室重新处理
|
||||
} else {
|
||||
// 同意:流转到机关审批
|
||||
}
|
||||
|
||||
// 步骤7:记录教学系审批操作日志
|
||||
recordOperationLog(apply.getBh(), "教学系审批", "教学系审批调课申请:" + apply.getBh()
|
||||
+ ",审批结果:" + dto.getSpzt() + ",审批意见:" + dto.getFhyj());
|
||||
}
|
||||
|
||||
/**
|
||||
* 机关审批调课申请。
|
||||
* <p>
|
||||
* 机关审批教研室已同意的调课申请,包含同意、发回、拒绝三种处理方式。
|
||||
* 机关全部同意后调课申请最终生效,课次按调整后的内容执行。
|
||||
* </p>
|
||||
*
|
||||
* @param dto 机关审批参数
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void auditByAuthority(ScheduleAdjustAuditDTO dto) {
|
||||
// 步骤1:校验审批参数
|
||||
if (dto == null) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "审批参数不能为空");
|
||||
}
|
||||
if (!"jg".equals(dto.getAuditRole())) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "审批角色不正确,应为jg");
|
||||
}
|
||||
if (dto.getSpzt() == null
|
||||
|| (dto.getSpzt() != 1 && dto.getSpzt() != 2 && dto.getSpzt() != 3)) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "审批结果不正确");
|
||||
}
|
||||
if (jwglRoleHelper.isTeacher() || jwglRoleHelper.isResearchOffice()) {
|
||||
throw new BusinessException(BasicManagementConstants.FORBIDDEN, "仅机关人员可进行终审");
|
||||
}
|
||||
if (!jwglRoleHelper.isAdmin() && !jwglRoleHelper.isDepartmentPersonnel()) {
|
||||
throw new BusinessException(BasicManagementConstants.FORBIDDEN, "仅机关人员可进行终审");
|
||||
}
|
||||
|
||||
SSDKSQ apply = ssdksqMapper.selectById(dto.getSsdksqbh());
|
||||
if (apply == null) {
|
||||
throw new BusinessException(BasicManagementConstants.NOT_FOUND, "调课申请不存在");
|
||||
}
|
||||
if (apply.getSczt() != null && apply.getSczt() == 1) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "该调课申请已撤销,不允许审批");
|
||||
}
|
||||
if (apply.getJyspzzt() == null || apply.getJyspzzt() != 1) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "教研室未同意,无法进行机关审批");
|
||||
}
|
||||
|
||||
String jgbh = StringUtils.isNotEmpty(dto.getJgbh()) ? dto.getJgbh() : "JG";
|
||||
String auditor = StringUtils.isNotEmpty(dto.getSprbh()) ? dto.getSprbh() : currentOperatorId();
|
||||
|
||||
SSDKSQSP audit = new SSDKSQSP();
|
||||
audit.setBh(UuidUtil.getOriginalUUID());
|
||||
audit.setSsdksqbh(dto.getSsdksqbh());
|
||||
audit.setJgbh(jgbh);
|
||||
audit.setSprbh(auditor);
|
||||
audit.setSpsj(LocalDateTime.now());
|
||||
audit.setSpzt(dto.getSpzt());
|
||||
audit.setFhyj(dto.getFhyj());
|
||||
audit.setNd(apply.getNd());
|
||||
audit.setCreateTime(LocalDateTime.now());
|
||||
audit.setUpdateTime(LocalDateTime.now());
|
||||
ssdksqspMapper.insert(audit);
|
||||
|
||||
if (dto.getSpzt() == 1) {
|
||||
applyApprovedSchedule(apply);
|
||||
}
|
||||
|
||||
recordOperationLog(apply.getBh(), "机关审批", "机关审批调课申请:" + apply.getBh()
|
||||
+ ",机关编号:" + jgbh
|
||||
recordOperationLog(apply.getBh(), "教研室审批", "教研室审批调课申请:" + apply.getBh()
|
||||
+ ",审批结果:" + dto.getSpzt() + ",审批意见:" + dto.getFhyj());
|
||||
}
|
||||
|
||||
/**
|
||||
* 机关查收调课申请。
|
||||
* <p>
|
||||
* 机关查收调课申请,标记查收状态和查收时间。
|
||||
* </p>
|
||||
*
|
||||
* @param ssdksqbh 调课申请编号
|
||||
* @param jgbh 机关编号
|
||||
* @param csrbh 查收人编号
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void receiveByAuthority(String ssdksqbh, String jgbh, String csrbh) {
|
||||
// 步骤1:校验参数
|
||||
if (ssdksqbh == null || ssdksqbh.trim().isEmpty()) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "调课申请编号不能为空");
|
||||
}
|
||||
if (jgbh == null || jgbh.trim().isEmpty()) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "机关编号不能为空");
|
||||
}
|
||||
if (csrbh == null || csrbh.trim().isEmpty()) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "查收人编号不能为空");
|
||||
}
|
||||
|
||||
// 步骤2:查询调课申请实体
|
||||
SSDKSQ apply = ssdksqMapper.selectById(ssdksqbh);
|
||||
if (apply == null) {
|
||||
throw new BusinessException(BasicManagementConstants.NOT_FOUND, "调课申请不存在");
|
||||
}
|
||||
|
||||
// 步骤3:检查当前机关是否已查收
|
||||
LambdaQueryWrapper<SSDKSQSP> checkWrapper = new LambdaQueryWrapper<>();
|
||||
checkWrapper.eq(SSDKSQSP::getSsdksqbh, ssdksqbh);
|
||||
checkWrapper.eq(SSDKSQSP::getJgbh, jgbh);
|
||||
checkWrapper.eq(SSDKSQSP::getCszt, 1);
|
||||
if (ssdksqspMapper.selectCount(checkWrapper) > 0) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "当前机关已查收该调课申请,无需重复查收");
|
||||
}
|
||||
|
||||
// 步骤4:构建并保存机关查收记录
|
||||
SSDKSQSP receive = new SSDKSQSP();
|
||||
receive.setBh(UuidUtil.getOriginalUUID());
|
||||
receive.setSsdksqbh(ssdksqbh);
|
||||
receive.setJgbh(jgbh);
|
||||
receive.setCsrbh(csrbh);
|
||||
receive.setCszt(1);
|
||||
receive.setCssj(LocalDateTime.now());
|
||||
receive.setNd(apply.getNd());
|
||||
receive.setCreateTime(LocalDateTime.now());
|
||||
receive.setUpdateTime(LocalDateTime.now());
|
||||
ssdksqspMapper.insert(receive);
|
||||
|
||||
// 步骤5:记录查收操作日志
|
||||
recordOperationLog(apply.getBh(), "机关查收", "机关查收调课申请:" + apply.getBh()
|
||||
+ ",机关编号:" + jgbh);
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤销调课申请。
|
||||
* <p>
|
||||
* 教员撤销自己提交的、未经过审批的调课申请。
|
||||
* 软删除调课申请,标记删除状态为1。
|
||||
* 事务保证主表软删除与课次原数据恢复的一致性。
|
||||
* 教员撤销未经过审批的调课申请。列表已按登录教员过滤。
|
||||
* </p>
|
||||
*
|
||||
* @param ssdksqbh 调课申请编号
|
||||
* @param sqjybh 申请教员编号(用于权限校验)
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void cancelScheduleAdjust(String ssdksqbh, String sqjybh) {
|
||||
if (jwglRoleHelper.isDepartmentPersonnel() || jwglRoleHelper.isResearchOffice()) {
|
||||
throw new BusinessException(BasicManagementConstants.FORBIDDEN, "仅申请教员本人可撤销调课申请");
|
||||
}
|
||||
if (ssdksqbh == null || ssdksqbh.trim().isEmpty()) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "调课申请编号不能为空");
|
||||
}
|
||||
String teacherId = jwglRoleHelper.requireTeacherId();
|
||||
if (sqjybh != null && !sqjybh.trim().isEmpty() && !teacherId.equals(sqjybh.trim())) {
|
||||
throw new BusinessException(BasicManagementConstants.FORBIDDEN, "仅申请教员本人可撤销该调课申请");
|
||||
}
|
||||
sqjybh = teacherId;
|
||||
|
||||
public void cancelScheduleAdjust(String ssdksqbh) {
|
||||
SSDKSQ apply = ssdksqMapper.selectById(ssdksqbh);
|
||||
if (apply == null) {
|
||||
throw new BusinessException(BasicManagementConstants.NOT_FOUND, "调课申请不存在");
|
||||
@@ -1549,29 +1228,19 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
|
||||
if (apply.getSczt() != null && apply.getSczt() == 1) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "该调课申请已撤销,无需重复撤销");
|
||||
}
|
||||
if (!sqjybh.equals(apply.getSqjybh())) {
|
||||
throw new BusinessException(BasicManagementConstants.FORBIDDEN, "仅申请教员本人可撤销该调课申请");
|
||||
if (apply.getJyspzzt() != null && apply.getJyspzzt() != 0) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "该调课申请已审批,不允许撤销");
|
||||
}
|
||||
if (apply.getJyspzzt() != null && apply.getJyspzzt() == 1) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "该调课申请教研室已同意,不允许撤销");
|
||||
}
|
||||
|
||||
apply.setSczt(1);
|
||||
apply.setJyscszt(0);
|
||||
apply.setJyscsrbh(null);
|
||||
apply.setJyscssj(null);
|
||||
ssdksqMapper.updateById(apply);
|
||||
recordOperationLog(apply.getBh(), "撤销", "撤销调课申请:" + apply.getBh());
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建原日期节次描述。
|
||||
* <p>
|
||||
* 根据课次实体生成原日期节次的字符串描述,便于调课申请中保留原信息。
|
||||
* </p>
|
||||
*
|
||||
* @param lesson 课次实体
|
||||
* @return 原日期节次描述
|
||||
*/
|
||||
/**
|
||||
* 机关终审同意后,将调整结果写回学员队任务表、课程表,以及可选的实施课次。
|
||||
* 教研室同意后,将调整结果写回课次、学员队任务表和课程表。
|
||||
*/
|
||||
private void applyApprovedSchedule(SSDKSQ apply) {
|
||||
if (apply == null || StringUtils.isEmpty(apply.getSskcbbh())) {
|
||||
@@ -1642,28 +1311,6 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复课次原数据。
|
||||
* <p>
|
||||
* 当调课申请被拒绝或撤销时,恢复课次到申请前的原始数据。
|
||||
* 实际业务中通常需要从历史快照恢复,此处简化为清空日期节次。
|
||||
* </p>
|
||||
*
|
||||
* @param apply 调课申请实体
|
||||
*/
|
||||
private void restoreLessonSchedule(SSDKSQ apply) {
|
||||
// 步骤1:查询课次实体
|
||||
SSKCB lesson = sskcbMapper.selectById(apply.getSskcbbh());
|
||||
if (lesson == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 步骤2:清空课次因调课而设置的日期节次(恢复原状)
|
||||
lesson.setRq(null);
|
||||
lesson.setJc(null);
|
||||
sskcbMapper.updateById(lesson);
|
||||
}
|
||||
|
||||
// ==================== 教学保障管理 ====================
|
||||
|
||||
/**
|
||||
@@ -2971,192 +2618,6 @@ public class CourseRunningImportServiceImpl implements CourseRunningImportServic
|
||||
return value == null ? "" : String.valueOf(value);
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 调课策略管理实现(时间段限制策略 + 免审批策略)
|
||||
// ============================================================
|
||||
|
||||
/** 策略类型常量:时间段限制 */
|
||||
private static final String STRATEGY_TIME_LIMIT = "TIME_LIMIT";
|
||||
/** 策略类型常量:免审批 */
|
||||
private static final String STRATEGY_AUTO_APPROVE = "AUTO_APPROVE";
|
||||
/** 星期中文描述 */
|
||||
private static final String[] WEEK_DAY_NAMES = {"周日", "周一", "周二", "周三", "周四", "周五", "周六"};
|
||||
|
||||
@Override
|
||||
public List<ScheduleAdjustStrategyVO> listScheduleAdjustStrategies(String cllx) {
|
||||
LambdaQueryWrapper<ScheduleAdjustStrategy> wrapper = new LambdaQueryWrapper<>();
|
||||
if (cllx != null && !cllx.trim().isEmpty()) {
|
||||
wrapper.eq(ScheduleAdjustStrategy::getCllx, cllx);
|
||||
}
|
||||
wrapper.orderByDesc(ScheduleAdjustStrategy::getGxsj);
|
||||
List<ScheduleAdjustStrategy> list = scheduleAdjustStrategyMapper.selectList(wrapper);
|
||||
|
||||
List<ScheduleAdjustStrategyVO> result = new ArrayList<>();
|
||||
if (list == null) {
|
||||
return result;
|
||||
}
|
||||
for (ScheduleAdjustStrategy strategy : list) {
|
||||
result.add(buildStrategyVO(strategy));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String saveScheduleAdjustStrategy(ScheduleAdjustStrategyDTO dto) {
|
||||
if (!STRATEGY_TIME_LIMIT.equals(dto.getCllx()) && !STRATEGY_AUTO_APPROVE.equals(dto.getCllx())) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST,
|
||||
"策略类型不正确,应为 TIME_LIMIT 或 AUTO_APPROVE");
|
||||
}
|
||||
if (STRATEGY_TIME_LIMIT.equals(dto.getCllx())) {
|
||||
if (dto.getJzxq() != null && (dto.getJzxq() < 0 || dto.getJzxq() > 6)) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST,
|
||||
"截止星期取值范围为0-6(0=周日,6=周六)");
|
||||
}
|
||||
}
|
||||
if (dto.getSxkssj() != null && dto.getSxjssj() != null
|
||||
&& dto.getSxkssj().isAfter(dto.getSxjssj())) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST,
|
||||
"生效开始时间不能晚于生效结束时间");
|
||||
}
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
if (dto.getClbh() == null || dto.getClbh().trim().isEmpty()) {
|
||||
ScheduleAdjustStrategy strategy = new ScheduleAdjustStrategy();
|
||||
strategy.setClbh(UuidUtil.getOriginalUUID());
|
||||
strategy.setClmc(dto.getClmc());
|
||||
strategy.setCllx(dto.getCllx());
|
||||
strategy.setSfqy(dto.getSfqy() == null ? 1 : dto.getSfqy());
|
||||
strategy.setJzxq(dto.getJzxq());
|
||||
strategy.setJzjc(dto.getJzjc());
|
||||
strategy.setSxkssj(dto.getSxkssj());
|
||||
strategy.setSxjssj(dto.getSxjssj());
|
||||
strategy.setBz(dto.getBz());
|
||||
strategy.setCjsj(now);
|
||||
strategy.setGxsj(now);
|
||||
scheduleAdjustStrategyMapper.insert(strategy);
|
||||
return strategy.getClbh();
|
||||
} else {
|
||||
ScheduleAdjustStrategy existing = scheduleAdjustStrategyMapper.selectById(dto.getClbh());
|
||||
if (existing == null) {
|
||||
throw new BusinessException(BasicManagementConstants.NOT_FOUND, "调课策略不存在");
|
||||
}
|
||||
existing.setClmc(dto.getClmc());
|
||||
existing.setCllx(dto.getCllx());
|
||||
existing.setSfqy(dto.getSfqy() == null ? 1 : dto.getSfqy());
|
||||
existing.setJzxq(dto.getJzxq());
|
||||
existing.setJzjc(dto.getJzjc());
|
||||
existing.setSxkssj(dto.getSxkssj());
|
||||
existing.setSxjssj(dto.getSxjssj());
|
||||
existing.setBz(dto.getBz());
|
||||
existing.setGxsj(now);
|
||||
scheduleAdjustStrategyMapper.updateById(existing);
|
||||
return existing.getClbh();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteScheduleAdjustStrategy(String clbh) {
|
||||
if (clbh == null || clbh.trim().isEmpty()) {
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST, "策略编号不能为空");
|
||||
}
|
||||
ScheduleAdjustStrategy existing = scheduleAdjustStrategyMapper.selectById(clbh);
|
||||
if (existing == null) {
|
||||
throw new BusinessException(BasicManagementConstants.NOT_FOUND, "调课策略不存在");
|
||||
}
|
||||
scheduleAdjustStrategyMapper.deleteById(clbh);
|
||||
}
|
||||
|
||||
/** 调课时间段策略校验:超过截止星期时不允许调整下周课程 */
|
||||
private void validateScheduleAdjustTimeLimitStrategy(LocalDateTime newDate) {
|
||||
if (newDate == null) {
|
||||
return;
|
||||
}
|
||||
LambdaQueryWrapper<ScheduleAdjustStrategy> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(ScheduleAdjustStrategy::getCllx, STRATEGY_TIME_LIMIT);
|
||||
wrapper.eq(ScheduleAdjustStrategy::getSfqy, 1);
|
||||
List<ScheduleAdjustStrategy> strategies = scheduleAdjustStrategyMapper.selectList(wrapper);
|
||||
|
||||
if (strategies == null || strategies.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
int currentDayOfWeek = now.getDayOfWeek().getValue();
|
||||
boolean isFutureWeek = newDate.toLocalDate().isAfter(now.toLocalDate().plusDays(7));
|
||||
|
||||
for (ScheduleAdjustStrategy strategy : strategies) {
|
||||
if (strategy.getSxkssj() != null && now.isBefore(strategy.getSxkssj())) {
|
||||
continue;
|
||||
}
|
||||
if (strategy.getSxjssj() != null && now.isAfter(strategy.getSxjssj())) {
|
||||
continue;
|
||||
}
|
||||
Integer deadlineDay = strategy.getJzxq();
|
||||
if (deadlineDay == null) {
|
||||
continue;
|
||||
}
|
||||
int deadlineDayOfWeek = (deadlineDay == 0) ? 7 : deadlineDay;
|
||||
if (isFutureWeek && currentDayOfWeek > deadlineDayOfWeek) {
|
||||
String dayName = (deadlineDay >= 0 && deadlineDay <= 6) ? WEEK_DAY_NAMES[deadlineDay] : String.valueOf(deadlineDay);
|
||||
throw new BusinessException(BasicManagementConstants.BAD_REQUEST,
|
||||
"根据调课策略[" + strategy.getClmc() + "]," + dayName + "之后不允许调整下周课程");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 判断当前是否命中免审批策略 */
|
||||
private boolean matchAutoApproveStrategy() {
|
||||
LambdaQueryWrapper<ScheduleAdjustStrategy> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(ScheduleAdjustStrategy::getCllx, STRATEGY_AUTO_APPROVE);
|
||||
wrapper.eq(ScheduleAdjustStrategy::getSfqy, 1);
|
||||
List<ScheduleAdjustStrategy> strategies = scheduleAdjustStrategyMapper.selectList(wrapper);
|
||||
|
||||
if (strategies == null || strategies.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
for (ScheduleAdjustStrategy strategy : strategies) {
|
||||
boolean inRange = true;
|
||||
if (strategy.getSxkssj() != null && now.isBefore(strategy.getSxkssj())) {
|
||||
inRange = false;
|
||||
}
|
||||
if (strategy.getSxjssj() != null && now.isAfter(strategy.getSxjssj())) {
|
||||
inRange = false;
|
||||
}
|
||||
if (inRange) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** 组装调课策略展示VO */
|
||||
private ScheduleAdjustStrategyVO buildStrategyVO(ScheduleAdjustStrategy strategy) {
|
||||
ScheduleAdjustStrategyVO vo = new ScheduleAdjustStrategyVO();
|
||||
vo.setClbh(strategy.getClbh());
|
||||
vo.setClmc(strategy.getClmc());
|
||||
vo.setCllx(strategy.getCllx());
|
||||
vo.setCllxDesc(STRATEGY_TIME_LIMIT.equals(strategy.getCllx()) ? "时间段限制" :
|
||||
(STRATEGY_AUTO_APPROVE.equals(strategy.getCllx()) ? "免审批" : strategy.getCllx()));
|
||||
vo.setSfqy(strategy.getSfqy());
|
||||
vo.setSfqyDesc(strategy.getSfqy() != null && strategy.getSfqy() == 1 ? "启用" : "停用");
|
||||
vo.setJzxq(strategy.getJzxq());
|
||||
if (strategy.getJzxq() != null && strategy.getJzxq() >= 0 && strategy.getJzxq() <= 6) {
|
||||
vo.setJzxqDesc(WEEK_DAY_NAMES[strategy.getJzxq()]);
|
||||
}
|
||||
vo.setJzjc(strategy.getJzjc());
|
||||
vo.setSxkssj(strategy.getSxkssj());
|
||||
vo.setSxjssj(strategy.getSxjssj());
|
||||
vo.setBz(strategy.getBz());
|
||||
vo.setCjsj(strategy.getCjsj());
|
||||
vo.setGxsj(strategy.getGxsj());
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据教员编号自动解析其归属的实施_机关编号。
|
||||
* <p>
|
||||
|
||||
+47
@@ -9,6 +9,7 @@ import com.roomroot.jwgl.service.FacultyService;
|
||||
import com.roomroot.jwgl.unit.BusinessException;
|
||||
import com.roomroot.jwgl.unit.PageQuery;
|
||||
import com.roomroot.jwgl.unit.PageResult;
|
||||
import com.roomroot.jwgl.utils.ExcelExportUtil;
|
||||
import com.roomroot.jwgl.utils.ExcelParseUtil;
|
||||
import com.roomroot.jwgl.utils.UuidUtil;
|
||||
import com.roomroot.jwgl.vo.faculty.TeacherListVO;
|
||||
@@ -160,6 +161,52 @@ public class FacultyServiceImpl implements FacultyService {
|
||||
return jybMapper.selectById(jybh);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int importJYBFromExcel(MultipartFile file) throws Exception {
|
||||
if (file == null || file.isEmpty()) {
|
||||
throw new BusinessException("导入文件不能为空");
|
||||
}
|
||||
List<JYB> list = ExcelParseUtil.parseJYBExcel(
|
||||
file.getInputStream(), file.getOriginalFilename());
|
||||
if (list.isEmpty()) {
|
||||
throw new BusinessException("Excel中无有效数据");
|
||||
}
|
||||
for (JYB entity : list) {
|
||||
// 编号为空自动生成
|
||||
if (entity.getJybh() == null || entity.getJybh().isEmpty()) {
|
||||
entity.setJybh(UuidUtil.getUUID());
|
||||
}
|
||||
// 离职状态默认 0
|
||||
if (entity.getLzzt() == null) {
|
||||
entity.setLzzt(0);
|
||||
}
|
||||
jybMapper.insert(entity);
|
||||
}
|
||||
return list.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportJYBExcel(jakarta.servlet.http.HttpServletResponse response) throws Exception {
|
||||
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<JYB> w =
|
||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>();
|
||||
w.eq(JYB::getLzzt, 0).orderByAsc(JYB::getXh);
|
||||
List<JYB> list = jybMapper.selectList(w);
|
||||
|
||||
String[] headers = {"教员编号", "教员姓名", "教研室代号", "职称", "专业技术职务等级", "教员类别",
|
||||
"性别", "手机号", "身份证号", "备注", "序号", "虚实类型"};
|
||||
byte[] bytes = ExcelExportUtil.export("教员", headers, list,
|
||||
JYB::getJybh, JYB::getJyxm, JYB::getJysdh, JYB::getZc,
|
||||
JYB::getZyjszwdj, JYB::getJylb, JYB::getXb, JYB::getSjh,
|
||||
JYB::getSfzh, JYB::getBz, JYB::getXh, JYB::getXslx);
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
response.setHeader("Content-Disposition",
|
||||
"attachment; filename=" + java.net.URLEncoder.encode(
|
||||
"教员列表.xlsx", java.nio.charset.StandardCharsets.UTF_8));
|
||||
response.getOutputStream().write(bytes);
|
||||
response.getOutputStream().flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<TeacherListVO> pageJYBDetail(PageQuery query, JYB cond) {
|
||||
Page<TeacherListVO> page = new Page<>(query.getPageNum(), query.getPageSize());
|
||||
|
||||
+41
@@ -73,4 +73,45 @@ public class TrainingProgramServiceImpl implements TrainingProgramService {
|
||||
return new PageResult<>(result.getRecords(), result.getTotal(),
|
||||
query.getPageNum(), query.getPageSize());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int importZYBFromExcel(org.springframework.web.multipart.MultipartFile file) throws Exception {
|
||||
if (file == null || file.isEmpty()) {
|
||||
throw new RuntimeException("导入文件不能为空");
|
||||
}
|
||||
java.util.List<ZYB> list = com.roomroot.jwgl.utils.ExcelParseUtil.parseZYBExcel(
|
||||
file.getInputStream(), file.getOriginalFilename());
|
||||
if (list.isEmpty()) {
|
||||
throw new RuntimeException("Excel中无有效数据");
|
||||
}
|
||||
for (ZYB entity : list) {
|
||||
if (entity.getZydh() == null || entity.getZydh().isEmpty()) {
|
||||
entity.setZydh(com.roomroot.jwgl.utils.UuidUtil.getUUID());
|
||||
}
|
||||
if (entity.getTy() == null) {
|
||||
entity.setTy(false);
|
||||
}
|
||||
zybMapper.insert(entity);
|
||||
}
|
||||
return list.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportZYBExcel(jakarta.servlet.http.HttpServletResponse response) throws Exception {
|
||||
java.util.List<ZYB> list = zybMapper.selectList(
|
||||
new LambdaQueryWrapper<ZYB>().orderByAsc(ZYB::getZydh));
|
||||
String[] headers = {"专业代号", "专业名称", "专业代码", "专业版本", "培训类型", "培训层次",
|
||||
"学年制", "学期数", "专业方向", "专业备注", "学员类别", "简称", "培训类型2"};
|
||||
byte[] bytes = com.roomroot.jwgl.utils.ExcelExportUtil.export("培养方案", headers, list,
|
||||
ZYB::getZydh, ZYB::getZymc, ZYB::getZydm, ZYB::getZybb, ZYB::getPxlx,
|
||||
ZYB::getPxcc, ZYB::getXnz, ZYB::getXqs, ZYB::getZyfx, ZYB::getZybz,
|
||||
ZYB::getXylb, ZYB::getJc, ZYB::getPxlx2);
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
response.setHeader("Content-Disposition",
|
||||
"attachment; filename=" + java.net.URLEncoder.encode(
|
||||
"培养方案.xlsx", java.nio.charset.StandardCharsets.UTF_8));
|
||||
response.getOutputStream().write(bytes);
|
||||
response.getOutputStream().flush();
|
||||
}
|
||||
}
|
||||
|
||||
+39
@@ -71,4 +71,43 @@ public class ZYJXJHBServiceImpl implements ZYJXJHBService {
|
||||
.eq(ZYJXJHB::getTy, ty);
|
||||
return zyjxjhbMapper.selectList(wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
@org.springframework.transaction.annotation.Transactional(rollbackFor = Exception.class)
|
||||
public int importZYJXJHBFromExcel(org.springframework.web.multipart.MultipartFile file) throws Exception {
|
||||
if (file == null || file.isEmpty()) {
|
||||
throw new RuntimeException("导入文件不能为空");
|
||||
}
|
||||
List<ZYJXJHB> list = com.roomroot.jwgl.utils.ExcelParseUtil.parseZYJXJHBExcel(
|
||||
file.getInputStream(), file.getOriginalFilename());
|
||||
if (list.isEmpty()) {
|
||||
throw new RuntimeException("Excel中无有效数据");
|
||||
}
|
||||
for (ZYJXJHB entity : list) {
|
||||
if (entity.getTy() == null) {
|
||||
entity.setTy(0);
|
||||
}
|
||||
zyjxjhbMapper.insert(entity);
|
||||
}
|
||||
return list.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportZYJXJHBExcel(jakarta.servlet.http.HttpServletResponse response) throws Exception {
|
||||
List<ZYJXJHB> list = zyjxjhbMapper.selectList(
|
||||
new LambdaQueryWrapper<ZYJXJHB>().orderByAsc(ZYJXJHB::getZydh));
|
||||
String[] headers = {"专业代号", "课编号", "学期第次", "课类型", "学时", "学分", "周课时",
|
||||
"课程定位", "模块", "成绩分制", "理论学时", "实践学时", "考试课时", "教研室代号", "简称"};
|
||||
byte[] bytes = com.roomroot.jwgl.utils.ExcelExportUtil.export("专业教学计划", headers, list,
|
||||
ZYJXJHB::getZydh, ZYJXJHB::getKbh, ZYJXJHB::getXqdc, ZYJXJHB::getKlx,
|
||||
ZYJXJHB::getXs, ZYJXJHB::getXf, ZYJXJHB::getZks, ZYJXJHB::getKcdw,
|
||||
ZYJXJHB::getMk, ZYJXJHB::getCjfz, ZYJXJHB::getLlxs, ZYJXJHB::getSjxs,
|
||||
ZYJXJHB::getKsks, ZYJXJHB::getJysdh, ZYJXJHB::getJc);
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
response.setHeader("Content-Disposition",
|
||||
"attachment; filename=" + java.net.URLEncoder.encode(
|
||||
"专业教学计划.xlsx", java.nio.charset.StandardCharsets.UTF_8));
|
||||
response.getOutputStream().write(bytes);
|
||||
response.getOutputStream().flush();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user