This commit is contained in:
zlwu committed 2026-09-02 09:58:57 +08:00
1 parent 8f99ac7482
commit f231386592
44 files changed
+800734 -2509

No files matched your search

@@ -26,16 +26,20 @@ import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.core.DropDownOptions;
import org.dromara.common.excel.core.ExcelResult;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.xg.domain.bo.XgDormCampusBo;
import org.dromara.xg.domain.vo.XgClassMsgImportVo;
import org.dromara.xg.domain.vo.XgClassMsgVo;
import org.dromara.xg.domain.vo.XgSysDeptVo;
import org.dromara.xg.domain.vo.XgDormCampusVo;
import org.dromara.xg.domain.bo.XgClassMsgBo;
import org.dromara.xg.domain.bo.XgClassStatusBo;
import org.dromara.xg.domain.bo.XgClassStatusBatchBo;
import org.dromara.xg.domain.bo.XgClassCampusBatchBo;
import org.dromara.xg.excel.XgClassMsgImportTemplateWriter;
import org.dromara.xg.listener.XgClassMsgImportListener;
import org.dromara.xg.service.IXgClassMsgService;
import org.dromara.xg.service.IXgSysDeptService;
import org.dromara.xg.service.IXgDormCampusService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
@@ -54,6 +58,7 @@ public class XgClassMsgController extends BaseController {
private final IXgClassMsgService xgClassMsgService;
private final IXgSysDeptService xgSysDeptService;
private final IXgDormCampusService xgDormCampusService;
/**
* 查询班级信息-新版列表
@@ -136,6 +141,17 @@ public class XgClassMsgController extends BaseController {
return toAjax(xgClassMsgService.updateClassStatusBatch(bo.getIds(), bo.getClassStatus()));
}
/**
* 批量设置班级所在校区
*/
// @SaCheckPermission("classMsg:classMsg:edit")
@Log(title = "班级信息-新版", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping("/campus/batch")
public R<Void> updateCampusBatch(@Validated @RequestBody XgClassCampusBatchBo bo) {
return toAjax(xgClassMsgService.updateCampusBatch(bo.getIds(), bo.getCampusId()));
}
/**
* 删除班级信息-新版
*
@@ -237,9 +253,22 @@ public class XgClassMsgController extends BaseController {
// 学制常见可选值
DropDownOptions schoolSystemOptions = new DropDownOptions(6, Arrays.asList("2", "3", "4", "5", "6"));
// 所在校区下拉(列 index=10)
List<XgDormCampusVo> campusList = xgDormCampusService.queryList(new XgDormCampusBo());
List<String> campusNames = new ArrayList<>();
if (campusList != null) {
for (XgDormCampusVo campus : campusList) {
if (StringUtils.isNotBlank(campus.getCampusName())) {
campusNames.add(campus.getCampusName());
}
}
}
DropDownOptions campusOptions = new DropDownOptions(10, campusNames);
List<DropDownOptions> options = new ArrayList<>();
options.add(collegeToMajor);
options.add(schoolSystemOptions);
options.add(campusOptions);
return options;
}
@@ -55,6 +55,16 @@ public class XgClassMsg extends TenantEntity {
*/
private String majorName;
/**
* 所在校区ID,关联xg_dorm_campus.id
*/
private Long campusId;
/**
* 所在校区名称
*/
private String campusName;
/**
* 班级代码
*/
@@ -0,0 +1,22 @@
package org.dromara.xg.domain.bo;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.List;
/**
* 班级所在校区批量更新业务对象
*/
@Data
public class XgClassCampusBatchBo {
/** 主键ID集合(雪花ID) */
@NotEmpty(message = "主键ID集合不能为空")
private List<Long> ids;
/** 校区ID,关联 xg_dorm_campus.id */
@NotNull(message = "校区不能为空")
private Long campusId;
}
@@ -48,6 +48,16 @@ public class XgClassMsgBo extends BaseEntity {
*/
private String majorName;
/**
* 所在校区ID,关联xg_dorm_campus.id(选填)
*/
private Long campusId;
/**
* 所在校区名称
*/
private String campusName;
/**
* 班级代码
*/
@@ -99,10 +99,18 @@ public class XgClassMsgImportVo implements Serializable {
@ExcelProperty(value = "班级教室位置", index = 9)
private String classLocation;
/**
* 所在校区(下拉:校区名称,选填)
*/
@ExcelProperty(value = "所在校区", index = 10)
@ColumnWidth(20)
@ExcelNotation(value = "选填,从下拉选择校区名称;留空则不写入校区")
private String campus;
/**
* 班级状态(字典下拉:xg_class_status)
*/
@ExcelProperty(value = "班级状态", index = 10, converter = ExcelDictConvert.class)
@ExcelProperty(value = "班级状态", index = 11, converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "xg_class_status")
@NotBlank(message = "班级状态不能为空")
private String classStatus;
@@ -110,19 +118,19 @@ public class XgClassMsgImportVo implements Serializable {
/**
* 班主任(选填,填写姓名;仅唯一匹配时写入,不影响班级保存)
*/
@ExcelProperty(value = "班主任", index = 11)
@ExcelProperty(value = "班主任", index = 12)
@ExcelNotation(value = "选填,填写姓名。匹配到唯一人员才写入;未匹配或多人同名则不写入,不影响班级导入")
private String classTeacherName;
/**
* 班级描述
*/
@ExcelProperty(value = "班级描述", index = 12)
@ExcelProperty(value = "班级描述", index = 13)
private String classDescription;
/**
* 备注信息
*/
@ExcelProperty(value = "备注信息", index = 13)
@ExcelProperty(value = "备注信息", index = 14)
private String remark;
}
@@ -59,6 +59,17 @@ public class XgClassMsgVo implements Serializable {
@ExcelProperty(value = "专业名称")
private String majorName;
/**
* 所在校区ID
*/
private Long campusId;
/**
* 所在校区名称
*/
@ExcelProperty(value = "所在校区")
private String campusName;
/**
* 班级代码
*/
@@ -19,6 +19,7 @@ import org.dromara.common.excel.core.ExcelListener;
import org.dromara.common.excel.core.ExcelResult;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.xg.domain.XgClassMsg;
import org.dromara.xg.domain.XgDormCampus;
import org.dromara.xg.domain.XgSysDept;
import org.dromara.xg.domain.XgSysUser;
import org.dromara.xg.domain.bo.XgClassMsgBo;
@@ -26,6 +27,7 @@ import org.dromara.xg.domain.bo.XgClassTeacherCounselorRelBo;
import org.dromara.xg.domain.vo.XgClassMsgImportVo;
import org.dromara.xg.domain.vo.XgSysDeptVo;
import org.dromara.xg.mapper.XgClassMsgMapper;
import org.dromara.xg.mapper.XgDormCampusMapper;
import org.dromara.xg.mapper.XgSysDeptMapper;
import org.dromara.xg.mapper.XgSysUserMapper;
import org.dromara.xg.service.IXgClassMsgService;
@@ -50,6 +52,7 @@ public class XgClassMsgImportListener extends AnalysisEventListener<XgClassMsgIm
private final XgSysDeptMapper deptMapper;
private final XgClassMsgMapper classMsgMapper;
private final XgSysUserMapper sysUserMapper;
private final XgDormCampusMapper dormCampusMapper;
private final Long operUserId;
private int successNum = 0;
@@ -64,6 +67,7 @@ public class XgClassMsgImportListener extends AnalysisEventListener<XgClassMsgIm
this.deptMapper = SpringUtils.getBean(XgSysDeptMapper.class);
this.classMsgMapper = SpringUtils.getBean(XgClassMsgMapper.class);
this.sysUserMapper = SpringUtils.getBean(XgSysUserMapper.class);
this.dormCampusMapper = SpringUtils.getBean(XgDormCampusMapper.class);
this.operUserId = LoginHelper.getUserId();
}
@@ -127,6 +131,8 @@ public class XgClassMsgImportListener extends AnalysisEventListener<XgClassMsgIm
bo.setRemark(importVo.getRemark());
bo.setCreateBy(operUserId);
resolveAndFillCampus(bo, importVo.getCampus());
classMsgService.insertByBo(bo);
String teacherTip = bindClassTeacherIfUnique(bo.getId(), importVo.getClassTeacherName());
@@ -201,6 +207,7 @@ public class XgClassMsgImportListener extends AnalysisEventListener<XgClassMsgIm
importVo.getGrade(),
importVo.getClassStatus(),
importVo.getClassLocation(),
importVo.getCampus(),
importVo.getClassDescription(),
importVo.getRemark()
) && importVo.getEnrollmentYear() == null
@@ -208,6 +215,28 @@ public class XgClassMsgImportListener extends AnalysisEventListener<XgClassMsgIm
&& importVo.getIsGraduation() == null;
}
/**
* 按校区名称解析并写入 BO;空则跳过。
*/
private void resolveAndFillCampus(XgClassMsgBo bo, String campusNameRaw) {
String campusName = StringUtils.trim(campusNameRaw);
if (StringUtils.isBlank(campusName)) {
return;
}
LambdaQueryWrapper<XgDormCampus> wrapper = Wrappers.lambdaQuery();
wrapper.eq(XgDormCampus::getCampusName, campusName);
List<XgDormCampus> list = dormCampusMapper.selectList(wrapper);
if (list == null || list.isEmpty()) {
throw new ServiceException("校区不存在:" + campusName);
}
if (list.size() > 1) {
throw new ServiceException("校区名称不唯一:" + campusName);
}
XgDormCampus campus = list.get(0);
bo.setCampusId(campus.getId());
bo.setCampusName(campus.getCampusName());
}
private Long resolveCollegeId(String optionValue) {
Long id = parseOptionId(optionValue);
if (id != null) {
@@ -83,4 +83,13 @@ public interface IXgClassMsgService {
* @return 是否更新成功
*/
Boolean updateClassStatusBatch(Collection<Long> ids, String classStatus);
/**
* 批量更新班级所在校区
*
* @param ids 班级ID集合
* @param campusId 校区ID
* @return 是否更新成功
*/
Boolean updateCampusBatch(Collection<Long> ids, Long campusId);
}
@@ -2,8 +2,8 @@ package org.dromara.xg.service.impl;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.system.domain.SysDept;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -16,9 +16,11 @@ import org.springframework.transaction.annotation.Transactional;
import org.dromara.xg.domain.bo.XgClassMsgBo;
import org.dromara.xg.domain.vo.XgClassMsgVo;
import org.dromara.xg.domain.XgClassMsg;
import org.dromara.xg.domain.XgDormCampus;
import org.dromara.xg.domain.XgStudentMsg;
import org.dromara.xg.domain.XgSysDept;
import org.dromara.xg.mapper.XgClassMsgMapper;
import org.dromara.xg.mapper.XgDormCampusMapper;
import org.dromara.xg.mapper.XgStudentMsgMapper;
import org.dromara.xg.mapper.XgSysDeptMapper;
import org.dromara.xg.service.IXgClassMsgService;
@@ -41,6 +43,7 @@ public class XgClassMsgServiceImpl implements IXgClassMsgService {
private final XgClassMsgMapper baseMapper;
private final XgSysDeptMapper deptMapper;
private final XgStudentMsgMapper studentMsgMapper;
private final XgDormCampusMapper dormCampusMapper;
/**
* 查询班级信息-新版
@@ -94,9 +97,25 @@ public class XgClassMsgServiceImpl implements IXgClassMsgService {
lqw.eq(StringUtils.isNotBlank(bo.getGrade()), XgClassMsg::getGrade, bo.getGrade());
lqw.eq(StringUtils.isNotBlank(bo.getClassStatus()), XgClassMsg::getClassStatus, bo.getClassStatus());
lqw.eq(bo.getClassTeacherId() != null, XgClassMsg::getClassTeacherId, bo.getClassTeacherId());
lqw.eq(bo.getCampusId() != null, XgClassMsg::getCampusId, bo.getCampusId());
return lqw;
}
/**
* 按 campusId 回填 campusName;为空则清空名称
*/
private void fillCampusFields(XgClassMsgBo bo) {
if (bo.getCampusId() == null) {
bo.setCampusName(null);
return;
}
XgDormCampus campus = dormCampusMapper.selectById(bo.getCampusId());
if (campus == null) {
throw new ServiceException("校区不存在或已删除");
}
bo.setCampusName(campus.getCampusName());
}
/**
* 新增班级信息-新版
*
@@ -106,6 +125,7 @@ public class XgClassMsgServiceImpl implements IXgClassMsgService {
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean insertByBo(XgClassMsgBo bo) {
fillCampusFields(bo);
XgClassMsg add = MapstructUtils.convert(bo, XgClassMsg.class);
validEntityBeforeSave(add);
@@ -160,6 +180,7 @@ public class XgClassMsgServiceImpl implements IXgClassMsgService {
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean updateByBo(XgClassMsgBo bo) {
fillCampusFields(bo);
XgClassMsg update = MapstructUtils.convert(bo, XgClassMsg.class);
validEntityBeforeSave(update);
@@ -168,6 +189,15 @@ public class XgClassMsgServiceImpl implements IXgClassMsgService {
updateWrapper.eq(XgClassMsg::getId, update.getId());
boolean result = baseMapper.update(update, updateWrapper) > 0;
// 显式同步校区字段,支持清空(绕过 update 忽略 null 策略)
if (result) {
LambdaUpdateWrapper<XgClassMsg> campusUw = Wrappers.lambdaUpdate();
campusUw.eq(XgClassMsg::getId, update.getId())
.set(XgClassMsg::getCampusId, bo.getCampusId())
.set(XgClassMsg::getCampusName, bo.getCampusName());
baseMapper.update(null, campusUw);
}
// 更新成功后,同步更新部门表信息
if (result) {
// 查询部门信息
@@ -307,4 +337,26 @@ public class XgClassMsgServiceImpl implements IXgClassMsgService {
uw.in(XgClassMsg::getId, ids).set(XgClassMsg::getClassStatus, classStatus);
return baseMapper.update(null, uw) > 0;
}
/**
* 批量更新班级所在校区
*/
@Override
public Boolean updateCampusBatch(Collection<Long> ids, Long campusId) {
if (ids == null || ids.isEmpty()) {
return false;
}
if (campusId == null) {
throw new ServiceException("校区不能为空");
}
XgDormCampus campus = dormCampusMapper.selectById(campusId);
if (campus == null) {
throw new ServiceException("校区不存在或已删除");
}
LambdaUpdateWrapper<XgClassMsg> uw = Wrappers.lambdaUpdate();
uw.in(XgClassMsg::getId, ids)
.set(XgClassMsg::getCampusId, campus.getId())
.set(XgClassMsg::getCampusName, campus.getCampusName());
return baseMapper.update(null, uw) > 0;
}
}
@@ -10,6 +10,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="collegeName" column="college_name"/>
<result property="majorId" column="major_id"/>
<result property="majorName" column="major_name"/>
<result property="campusId" column="campus_id"/>
<result property="campusName" column="campus_name"/>
<result property="classCode" column="class_code"/>
<result property="className" column="class_name"/>
<result property="classType" column="class_type"/>
@@ -65,6 +67,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<sql id="selectXgClassMsgVo">
select c.id, c.college_id, dc.dept_name as college_name, c.major_id, dm.dept_name as major_name,
c.campus_id, c.campus_name,
c.class_code, c.class_name, c.class_type, c.grade, c.enrollment_year,c.school_system, c.graduation_year,
c.training_type, c.degree_type, c.counselor_id, c.counselor_name, c.class_teacher_id,
c.class_teacher_name, c.class_advisor_id, c.class_advisor_name, c.class_monitor_id,