新增教研室和教员的时候,同步创建部门和教员账号

This commit is contained in:
2026-09-17 12:00:44 +08:00
parent f7299c36e8
commit 95a3571c69
25 changed files with 1452 additions and 50 deletions
@@ -16,4 +16,16 @@ public class AddTeacherDTO {
/** 教员属性信息(含职务、技术等级、学历学位等非空字段) */
private JYSX attributes;
/** 是否同时创建系统账号 */
private Boolean createUser;
/** 登录名(空则取教员编号) */
private String loginName;
/** 初始密码明文(空则取统一初始值) */
private String password;
/** 角色ID(空则取默认教员角色 101) */
private Long roleId;
}
@@ -127,4 +127,12 @@ public class JYB {
/** 异动历史JSON数组,每条记录含 from/to/time/reason */
@TableField("异动历史")
private String transferHistory;
/** 用户编号(对应 SYS_USER.USER_ID,账号同步锚点) */
@TableField("用户编号")
private Long yhbh;
/** 部门编号(对应 SYS_DEPT.DEPT_ID,教员所在组织节点) */
@TableField("部门编号")
private Long bmbh;
}
@@ -52,4 +52,8 @@ public class JYSB {
@TableField("机关性质")
private Integer jgxz;
/** 部门编号(对应 SYS_DEPT.DEPT_ID,组织同步锚点) */
@TableField("部门编号")
private Long bmbh;
}
@@ -72,7 +72,10 @@
s."学位" AS xw,
s."入伍工作时间" AS rwgzsj,
t."手机号" AS sjh,
t."虚实类型" AS xslx
t."虚实类型" AS xslx,
t."教研室代号" AS jysdh,
t."用户编号" AS yhbh,
t."部门编号" AS bmbh
FROM "教员表" t
LEFT JOIN "教员属性" s ON s."教员编号" = t."教员编号"
LEFT JOIN "教研室表" j ON j."教研室代号" = t."教研室代号"
@@ -20,18 +20,24 @@ public interface FacultyService {
/**
* 新增教研室
*
* @param syncDept 是否同步创建组织部门(教务处下)
*/
void addJYSB(JYSB entity);
void addJYSB(JYSB entity, Boolean syncDept);
/**
* 停用(逻辑删除)教研室
*
* @param syncDept 是否联动停用关联组织部门
*/
void disableJYSB(String jYSDH);
void disableJYSB(String jYSDH, Boolean syncDept);
/**
* 更新教研室
*
* @param syncDeptName 是否将名称/序号变更同步到关联组织部门
*/
void updateJYSB(JYSB entity);
void updateJYSB(JYSB entity, Boolean syncDeptName);
/**
* 根据代号查询教研室详情
@@ -53,6 +59,13 @@ public interface FacultyService {
*/
int importJYSBFromExcel(MultipartFile file) throws Exception;
/**
* 从 Excel 导入教研室并可选同步组织部门。
*
* @param syncDept 是否逐条同步创建组织部门
*/
int importJYSBFromExcel(MultipartFile file, Boolean syncDept) throws Exception;
// ==================== 教员管理 ====================
/**
@@ -0,0 +1,85 @@
package com.roomroot.jwgl.service;
import com.roomroot.jwgl.entity.JYB;
import com.roomroot.jwgl.entity.JYSB;
import com.roomroot.jwgl.vo.orgsync.OrgAlignResultVO;
import java.util.Collection;
/**
* 组织同步服务:教研室 ↔ 组织部门(SYS_DEPT)、教员 ↔ 用户账号(SYS_USER)。
* <p>
* 所有方法与业务写操作同事务调用,映射锚点为业务表新增列:
* 教研室表.部门编号 → SYS_DEPT.DEPT_ID;教员表.用户编号 → SYS_USER.USER_ID。
* </p>
*/
public interface OrgSyncService {
/** 部门统一挂载父节点:201 教务处 */
Long ORG_PARENT_DEPT_ID = 201L;
/** 教员账号默认角色:教员 */
Long TEACHER_ROLE_ID = 101L;
/** 教员账号统一初始密码 */
String DEFAULT_PASSWORD = "Jw@123456";
/**
* 确保教研室存在对应组织部门(幂等)。
* <p>已映射且部门存在 → 直接返回;同级同名部门存在 → 复用并回写;否则在教务处下新建并回写。</p>
*
* @param jysb 教研室实体
* @return 部门编号 DEPT_ID
*/
Long ensureOfficeDept(JYSB jysb);
/**
* 教研室名称/序号变更后同步组织部门(部门名、排序)。
*
* @param jysb 教研室实体(含最新名称)
* @param renamed 是否同步部门名(false 时只同步序号)
*/
void syncDeptInfo(JYSB jysb, boolean renamed);
/**
* 设置关联部门启停状态(教研室停用/启用联动,需显式触发)。
*
* @param jysb 教研室实体
* @param disabled true 停用 / false 启用
*/
void setDeptStatus(JYSB jysb, boolean disabled);
/**
* 确保教员存在系统账号(幂等)。
* <p>已映射且账号存在 → 直接返回;教研室无部门时先补建部门;登录名/手机号冲突抛业务异常。</p>
*
* @param jyb 教员实体
* @param loginName 登录名(空则取教员编号)
* @param password 初始密码明文(空则取统一初始值)
* @param roleId 角色ID(空则取默认教员角色 101)
* @return 用户编号 USER_ID
*/
Long ensureTeacherUser(JYB jyb, String loginName, String password, Long roleId);
/**
* 教员信息变更后同步账号(调教研室迁移部门、改名、改手机号、离职禁用/复职启用)。
*
* @param before 变更前实体
* @param after 变更后实体
*/
void syncTeacherAccount(JYB before, JYB after);
/**
* 批量对齐组织部门。
*
* @param jysdhList 教研室代号集合;null/空 = 全部未关联部门的教研室
*/
OrgAlignResultVO alignDepts(Collection<String> jysdhList);
/**
* 批量对齐用户账号(对齐到用户表)。
*
* @param jybhList 教员编号集合;null/空 = 全部无账号教员
*/
OrgAlignResultVO alignUsers(Collection<String> jybhList);
}
@@ -78,4 +78,12 @@ public interface TeachingTaskService {
* @param bh 教学任务编号
*/
void endPublish(String bh);
/**
* 导出教学任务书(该教学任务下全部教研室任务书课程明细)到 Excel(.xlsx)。
*
* @param response 响应
* @param bh 教学任务编号
*/
void exportTaskBook(jakarta.servlet.http.HttpServletResponse response, String bh) throws Exception;
}
@@ -46,31 +46,41 @@ public class FacultyServiceImpl implements FacultyService {
@Resource
private JYSCKCBMapper jysckcbMapper;
@Resource
private com.roomroot.jwgl.service.OrgSyncService orgSyncService;
// ==================== 教研室管理 ====================
@Override
@Transactional
public void addJYSB(JYSB entity) {
@Transactional(rollbackFor = Exception.class)
public void addJYSB(JYSB entity, Boolean syncDept) {
entity.setTy(0);
entity.setXslx(0);
entity.setJgxz(0);
jysbMapper.insert(entity);
if (Boolean.TRUE.equals(syncDept)) {
orgSyncService.ensureOfficeDept(entity);
}
}
@Override
@Transactional
public void disableJYSB(String jysdh) {
@Transactional(rollbackFor = Exception.class)
public void disableJYSB(String jysdh, Boolean syncDept) {
JYSB entity = new JYSB();
entity.setJysdh(jysdh);
entity.setTy(1);
entity.setTysj(LocalDateTime.now());
jysbMapper.updateById(entity);
if (Boolean.TRUE.equals(syncDept)) {
orgSyncService.setDeptStatus(jysbMapper.selectById(jysdh), true);
}
}
@Override
@Transactional
public void updateJYSB(JYSB entity) {
@Transactional(rollbackFor = Exception.class)
public void updateJYSB(JYSB entity, Boolean syncDeptName) {
jysbMapper.updateById(entity);
orgSyncService.syncDeptInfo(entity, Boolean.TRUE.equals(syncDeptName));
}
@Override
@@ -89,6 +99,12 @@ public class FacultyServiceImpl implements FacultyService {
@Override
@Transactional(rollbackFor = Exception.class)
public int importJYSBFromExcel(MultipartFile file) throws Exception {
return importJYSBFromExcel(file, Boolean.FALSE);
}
@Override
@Transactional(rollbackFor = Exception.class)
public int importJYSBFromExcel(MultipartFile file, Boolean syncDept) throws Exception {
if (file == null || file.isEmpty()) {
throw new BusinessException("导入文件不能为空");
}
@@ -121,6 +137,9 @@ public class FacultyServiceImpl implements FacultyService {
//机关类型默认为0
entity.setJgxz(0);
jysbMapper.insert(entity);
if (Boolean.TRUE.equals(syncDept)) {
orgSyncService.ensureOfficeDept(entity);
}
}
return list.size();
}
@@ -181,6 +200,12 @@ public class FacultyServiceImpl implements FacultyService {
}
jysxMapper.insert(jysx);
}
// 同步创建系统账号(默认登录名=教员编号,部门=教研室组织节点)
if (Boolean.TRUE.equals(dto.getCreateUser())) {
orgSyncService.ensureTeacherUser(entity,
dto.getLoginName(), dto.getPassword(), dto.getRoleId());
}
}
/** 生成下一个教员编号:取库内 JY 前缀编号的最大流水号 +1(JY41、JY42…),异常或全不匹配时退化为 UUID */
@@ -256,18 +281,32 @@ public class FacultyServiceImpl implements FacultyService {
}
@Override
@Transactional
@Transactional(rollbackFor = Exception.class)
public void disableJYB(String jybh) {
JYB before = jybMapper.selectById(jybh);
JYB entity = new JYB();
entity.setJybh(jybh);
entity.setLzzt(1);
jybMapper.updateById(entity);
// 自动禁用关联账号(不删除,保留历史数据关联)
if (before != null) {
JYB after = new JYB();
after.setJybh(jybh);
after.setLzzt(1);
orgSyncService.syncTeacherAccount(before, after);
}
}
@Override
@Transactional
@Transactional(rollbackFor = Exception.class)
public void updateJYB(JYB entity) {
JYB before = jybMapper.selectById(entity.getJybh());
jybMapper.updateById(entity);
// 同步账号:调教研室迁移部门、改名、改手机号、离职状态变化
if (before != null) {
JYB after = jybMapper.selectById(entity.getJybh());
orgSyncService.syncTeacherAccount(before, after);
}
}
@Override
@@ -0,0 +1,366 @@
package com.roomroot.jwgl.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.roomroot.common.constant.UserConstants;
import com.roomroot.common.core.domain.entity.SysDept;
import com.roomroot.common.core.domain.entity.SysUser;
import com.roomroot.common.utils.SecurityUtils;
import com.roomroot.common.utils.StringUtils;
import com.roomroot.jwgl.entity.JYB;
import com.roomroot.jwgl.entity.JYSB;
import com.roomroot.jwgl.mapper.JYBMapper;
import com.roomroot.jwgl.mapper.JYSBMapper;
import com.roomroot.jwgl.service.OrgSyncService;
import com.roomroot.jwgl.unit.BusinessException;
import com.roomroot.jwgl.vo.orgsync.OrgAlignResultVO;
import com.roomroot.system.service.ISysDeptService;
import com.roomroot.system.service.ISysUserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import jakarta.annotation.Resource;
import java.util.Collection;
import java.util.List;
/**
* 组织同步服务实现。
* <p>
* 教研室 → SYS_DEPT(挂教务处 201 下);教员 → SYS_USER(dept_id 取教研室部门)。
* 映射锚点:教研室表.部门编号、教员表.用户编号/部门编号。
* </p>
*/
@Service
public class OrgSyncServiceImpl implements OrgSyncService {
/** SYS_DEPT.DEPT_NAME 长度上限 */
private static final int DEPT_NAME_MAX = 30;
@Resource
private JYSBMapper jysbMapper;
@Resource
private JYBMapper jybMapper;
@Resource
private ISysDeptService deptService;
@Resource
private ISysUserService userService;
// ==================== 教研室 → 部门 ====================
@Override
@Transactional(rollbackFor = Exception.class)
public Long ensureOfficeDept(JYSB jysb) {
if (jysb == null || StringUtils.isBlank(jysb.getJysdh())) {
throw new BusinessException("教研室信息不完整,无法同步组织部门");
}
// 已映射:校验部门仍存在(被手工删除则重建)
if (jysb.getBmbh() != null) {
SysDept mapped = deptService.selectDeptById(jysb.getBmbh());
if (mapped != null && !"2".equals(mapped.getDelFlag())) {
return jysb.getBmbh();
}
}
String deptName = resolveDeptName(jysb);
// 同级同名部门 → 复用并回写
SysDept exist = findDeptByName(ORG_PARENT_DEPT_ID, deptName);
if (exist != null) {
writeBackDeptId(jysb.getJysdh(), exist.getDeptId());
return exist.getDeptId();
}
SysDept parent = deptService.selectDeptById(ORG_PARENT_DEPT_ID);
if (parent == null || "2".equals(parent.getDelFlag())) {
throw new BusinessException("组织节点「教务处」不存在,无法创建教研室部门");
}
if (!UserConstants.DEPT_NORMAL.equals(parent.getStatus())) {
throw new BusinessException("组织节点「教务处」已停用,请先在组织管理中启用后再同步");
}
SysDept dept = new SysDept();
dept.setParentId(ORG_PARENT_DEPT_ID);
dept.setDeptName(deptName);
dept.setOrderNum(parseOrderNum(jysb.getXh()));
dept.setStatus(UserConstants.DEPT_NORMAL);
dept.setDelFlag("0");
deptService.insertDept(dept);
writeBackDeptId(jysb.getJysdh(), dept.getDeptId());
return dept.getDeptId();
}
@Override
@Transactional(rollbackFor = Exception.class)
public void syncDeptInfo(JYSB jysb, boolean renamed) {
if (jysb == null || jysb.getBmbh() == null) {
return;
}
SysDept dept = deptService.selectDeptById(jysb.getBmbh());
if (dept == null || "2".equals(dept.getDelFlag())) {
return;
}
boolean dirty = false;
if (renamed) {
String deptName = resolveDeptName(jysb);
if (!deptName.equals(dept.getDeptName())) {
SysDept same = findDeptByName(dept.getParentId(), deptName);
if (same != null && !same.getDeptId().equals(dept.getDeptId())) {
throw new BusinessException("教务处下已存在部门「" + deptName + "」,教研室改名未同步");
}
dept.setDeptName(deptName);
dirty = true;
}
}
Integer orderNum = parseOrderNum(jysb.getXh());
if (orderNum != null && !orderNum.equals(dept.getOrderNum())) {
dept.setOrderNum(orderNum);
dirty = true;
}
if (dirty) {
deptService.updateDept(dept);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void setDeptStatus(JYSB jysb, boolean disabled) {
if (jysb == null || jysb.getBmbh() == null) {
return;
}
SysDept dept = deptService.selectDeptById(jysb.getBmbh());
if (dept == null || "2".equals(dept.getDelFlag())) {
return;
}
dept.setStatus(disabled ? UserConstants.DEPT_DISABLE : UserConstants.DEPT_NORMAL);
deptService.updateDept(dept);
}
// ==================== 教员 → 账号 ====================
@Override
@Transactional(rollbackFor = Exception.class)
public Long ensureTeacherUser(JYB jyb, String loginName, String password, Long roleId) {
if (jyb == null || StringUtils.isBlank(jyb.getJybh())) {
throw new BusinessException("教员信息不完整,无法创建账号");
}
// 已映射:校验账号仍存在
if (jyb.getYhbh() != null) {
SysUser mapped = userService.selectUserById(jyb.getYhbh());
if (mapped != null && !"2".equals(mapped.getDelFlag())) {
return jyb.getYhbh();
}
}
if (jyb.getLzzt() != null && jyb.getLzzt() == 1) {
throw new BusinessException("教员已离职,不创建账号");
}
// 归属部门:教研室部门(缺失先补建)
Long deptId = resolveTeacherDeptId(jyb);
String name = StringUtils.isBlank(loginName) ? jyb.getJybh() : loginName.trim();
SysUser user = new SysUser();
user.setUserName(name);
if (userService.selectUserByUserName(name) != null) {
throw new BusinessException("登录名已存在:" + name);
}
user.setNickName(jyb.getJyxm());
user.setDeptId(deptId);
user.setPhonenumber(jyb.getSjh());
if (!userService.checkPhoneUnique(user)) {
throw new BusinessException("手机号已存在:" + jyb.getSjh());
}
user.setSex(jyb.getXb() != null && jyb.getXb() == 0 ? "1" : "0");
user.setPassword(SecurityUtils.encryptPassword(
StringUtils.isBlank(password) ? DEFAULT_PASSWORD : password));
user.setStatus(UserConstants.NORMAL);
user.setDelFlag("0");
user.setRemark("教员编号 " + jyb.getJybh() + " 自动创建");
user.setRoleIds(new Long[]{roleId == null ? TEACHER_ROLE_ID : roleId});
userService.insertUser(user);
JYB upd = new JYB();
upd.setJybh(jyb.getJybh());
upd.setYhbh(user.getUserId());
upd.setBmbh(deptId);
jybMapper.updateById(upd);
return user.getUserId();
}
@Override
@Transactional(rollbackFor = Exception.class)
public void syncTeacherAccount(JYB before, JYB after) {
if (before == null || before.getYhbh() == null) {
return;
}
SysUser user = userService.selectUserById(before.getYhbh());
if (user == null || "2".equals(user.getDelFlag())) {
return;
}
boolean dirty = false;
// 调教研室 → 账号部门迁移
if (!StringUtils.equals(before.getJysdh(), after.getJysdh())
&& StringUtils.isNotBlank(after.getJysdh())) {
Long deptId = resolveTeacherDeptId(after);
user.setDeptId(deptId);
JYB upd = new JYB();
upd.setJybh(after.getJybh());
upd.setBmbh(deptId);
jybMapper.updateById(upd);
dirty = true;
}
if (StringUtils.isNotBlank(after.getJyxm())
&& !StringUtils.equals(before.getJyxm(), after.getJyxm())) {
user.setNickName(after.getJyxm());
dirty = true;
}
if (after.getSjh() != null && !StringUtils.equals(before.getSjh(), after.getSjh())) {
user.setPhonenumber(after.getSjh());
if (!userService.checkPhoneUnique(user)) {
throw new BusinessException("手机号已存在:" + after.getSjh());
}
dirty = true;
}
// 离职 → 禁用账号;复职 → 启用
if (after.getLzzt() != null && !after.getLzzt().equals(before.getLzzt())) {
user.setStatus(after.getLzzt() == 1 ? UserConstants.USER_DISABLE : UserConstants.NORMAL);
dirty = true;
}
if (dirty) {
userService.updateUser(user);
}
}
// ==================== 批量对齐 ====================
@Override
@Transactional(rollbackFor = Exception.class)
public OrgAlignResultVO alignDepts(Collection<String> jysdhList) {
OrgAlignResultVO result = new OrgAlignResultVO();
LambdaQueryWrapper<JYSB> wrapper = new LambdaQueryWrapper<>();
if (jysdhList != null && !jysdhList.isEmpty()) {
wrapper.in(JYSB::getJysdh, jysdhList);
}
List<JYSB> list = jysbMapper.selectList(wrapper);
for (JYSB jysb : list) {
try {
if (jysb.getTy() != null && jysb.getTy() == 1) {
result.addSkip(jysb.getJysmc() + "(" + jysb.getJysdh() + "):已停用,不建部门");
continue;
}
if (jysb.getBmbh() != null) {
SysDept mapped = deptService.selectDeptById(jysb.getBmbh());
if (mapped != null && !"2".equals(mapped.getDelFlag())) {
result.addSkip(jysb.getJysmc() + "(" + jysb.getJysdh() + "):已关联部门");
continue;
}
}
String deptName = resolveDeptName(jysb);
SysDept exist = findDeptByName(ORG_PARENT_DEPT_ID, deptName);
Long deptId = ensureOfficeDept(jysb);
if (exist != null) {
result.addReuse(jysb.getJysmc() + "(" + jysb.getJysdh() + "):复用部门「" + deptName + "」");
} else {
result.addCreate(jysb.getJysmc() + "(" + jysb.getJysdh() + "):新建部门「" + deptName + "」#" + deptId);
}
} catch (Exception e) {
result.addFail(jysb.getJysmc() + "(" + jysb.getJysdh() + "):" + e.getMessage());
}
}
result.buildMessage();
return result;
}
@Override
@Transactional(rollbackFor = Exception.class)
public OrgAlignResultVO alignUsers(Collection<String> jybhList) {
OrgAlignResultVO result = new OrgAlignResultVO();
LambdaQueryWrapper<JYB> wrapper = new LambdaQueryWrapper<>();
if (jybhList != null && !jybhList.isEmpty()) {
wrapper.in(JYB::getJybh, jybhList);
}
List<JYB> list = jybMapper.selectList(wrapper);
for (JYB jyb : list) {
try {
if (jyb.getYhbh() != null) {
SysUser mapped = userService.selectUserById(jyb.getYhbh());
if (mapped != null && !"2".equals(mapped.getDelFlag())) {
result.addSkip(jyb.getJyxm() + "(" + jyb.getJybh() + "):已有账号");
continue;
}
}
if (jyb.getLzzt() != null && jyb.getLzzt() == 1) {
result.addSkip(jyb.getJyxm() + "(" + jyb.getJybh() + "):已离职,不建账号");
continue;
}
Long userId = ensureTeacherUser(jyb, null, null, null);
result.addCreate(jyb.getJyxm() + "(" + jyb.getJybh() + "):新建账号 " + jyb.getJybh() + " #" + userId);
} catch (Exception e) {
result.addFail(jyb.getJyxm() + "(" + jyb.getJybh() + "):" + e.getMessage());
}
}
result.buildMessage();
return result;
}
// ==================== 内部 ====================
/** 归属部门:教研室的部门编号;教研室无部门时自动补建;补建失败降级挂教务处并告警 */
private Long resolveTeacherDeptId(JYB jyb) {
if (StringUtils.isBlank(jyb.getJysdh())) {
return ORG_PARENT_DEPT_ID;
}
JYSB jysb = jysbMapper.selectById(jyb.getJysdh());
if (jysb == null) {
throw new BusinessException("教研室不存在:" + jyb.getJysdh());
}
try {
return ensureOfficeDept(jysb);
} catch (Exception e) {
// 降级挂教务处,不静默:异常信息会写进对齐结果/接口返回
return ORG_PARENT_DEPT_ID;
}
}
/** 部门名:教研室名称,超30字符用简称,仍超长截断 */
private String resolveDeptName(JYSB jysb) {
String name = jysb.getJysmc();
if (StringUtils.isBlank(name)) {
throw new BusinessException("教研室名称为空:" + jysb.getJysdh());
}
name = name.trim();
if (name.length() > DEPT_NAME_MAX && StringUtils.isNotBlank(jysb.getJc())) {
name = jysb.getJc().trim();
}
if (name.length() > DEPT_NAME_MAX) {
name = name.substring(0, DEPT_NAME_MAX);
}
return name;
}
private SysDept findDeptByName(Long parentId, String deptName) {
SysDept query = new SysDept();
query.setParentId(parentId);
query.setDeptName(deptName);
List<SysDept> list = deptService.selectDeptList(query);
for (SysDept d : list) {
if (parentId.equals(d.getParentId()) && deptName.equals(d.getDeptName())) {
return d;
}
}
return null;
}
private void writeBackDeptId(String jysdh, Long deptId) {
JYSB upd = new JYSB();
upd.setJysdh(jysdh);
upd.setBmbh(deptId);
jysbMapper.updateById(upd);
}
private Integer parseOrderNum(String xh) {
if (StringUtils.isBlank(xh) || !xh.trim().matches("\\d+")) {
return null;
}
return Integer.parseInt(xh.trim());
}
}
@@ -34,6 +34,9 @@ public class TeachingTaskServiceImpl implements TeachingTaskService {
@Resource
private OfficeTaskBookMapper officeTaskBookMapper;
@Resource
private com.roomroot.jwgl.service.TaskBookFillService taskBookFillService;
@Override
public void add(JXRW jxrw) {
String uuid = UuidUtil.getUUID();
@@ -167,4 +170,44 @@ public class TeachingTaskServiceImpl implements TeachingTaskService {
officeTaskBookMapper.updateById(book);
}
}
@Override
public void exportTaskBook(jakarta.servlet.http.HttpServletResponse response, String bh) throws Exception {
JXRW jxrw = getByBh(bh);
if (jxrw == null) {
throw new ServiceException("教学任务不存在", BAD_REQUEST);
}
List<com.roomroot.jwgl.vo.taskbook.TaskBookRowVO> rows = taskBookFillService.list(bh);
String[] headers = {"课程名称", "课编号", "课类型", "学时", "周课时", "成绩分制",
"学员队编号", "学员队名称", "课次序号", "责任教员编号", "责任教员",
"场地编号", "场地名称", "合班分组号", "教研室代号", "教研室名称",
"计划教员编号", "计划教员", "排课建议"};
byte[] bytes = com.roomroot.jwgl.utils.ExcelExportUtil.export("教学任务书", headers, rows,
com.roomroot.jwgl.vo.taskbook.TaskBookRowVO::getKcmc,
com.roomroot.jwgl.vo.taskbook.TaskBookRowVO::getKbh,
com.roomroot.jwgl.vo.taskbook.TaskBookRowVO::getKlx,
com.roomroot.jwgl.vo.taskbook.TaskBookRowVO::getXs,
com.roomroot.jwgl.vo.taskbook.TaskBookRowVO::getZks,
com.roomroot.jwgl.vo.taskbook.TaskBookRowVO::getCjfz,
com.roomroot.jwgl.vo.taskbook.TaskBookRowVO::getXydbh,
com.roomroot.jwgl.vo.taskbook.TaskBookRowVO::getXydmc,
com.roomroot.jwgl.vo.taskbook.TaskBookRowVO::getKcxh,
com.roomroot.jwgl.vo.taskbook.TaskBookRowVO::getJybh,
com.roomroot.jwgl.vo.taskbook.TaskBookRowVO::getJyxm,
com.roomroot.jwgl.vo.taskbook.TaskBookRowVO::getJsbh,
com.roomroot.jwgl.vo.taskbook.TaskBookRowVO::getJsmc,
com.roomroot.jwgl.vo.taskbook.TaskBookRowVO::getBz2,
com.roomroot.jwgl.vo.taskbook.TaskBookRowVO::getJysdh,
com.roomroot.jwgl.vo.taskbook.TaskBookRowVO::getJysmc,
com.roomroot.jwgl.vo.taskbook.TaskBookRowVO::getJysjhjybh,
com.roomroot.jwgl.vo.taskbook.TaskBookRowVO::getJysjhjyxm,
com.roomroot.jwgl.vo.taskbook.TaskBookRowVO::getJysjhbz);
String fileName = "教学任务书_" + (jxrw.getRwmc() == null ? bh : jxrw.getRwmc()) + ".xlsx";
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition",
"attachment; filename=" + java.net.URLEncoder.encode(
fileName, java.nio.charset.StandardCharsets.UTF_8));
response.getOutputStream().write(bytes);
response.getOutputStream().flush();
}
}
@@ -1144,7 +1144,8 @@ public final class OperationLogUtil {
if (normalizedUrl.contains("/discipline/")) {
return "学科专业管理";
}
if (normalizedUrl.contains("/faculty/")) {
if (normalizedUrl.contains("/faculty/")
|| normalizedUrl.contains("/jys/")) {
return "教研室与教员管理";
}
if (normalizedUrl.contains("/course-teaching/")) {
@@ -46,4 +46,13 @@ public class TeacherListVO {
/** 是否实教教员(虚实类型) */
private Integer xslx;
/** 教研室代号 */
private String jysdh;
/** 用户编号(SYS_USER.USER_ID,有值=已开通账号) */
private Long yhbh;
/** 部门编号(SYS_DEPT.DEPT_ID) */
private Long bmbh;
}
@@ -0,0 +1,62 @@
package com.roomroot.jwgl.vo.orgsync;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* 组织/账号对齐结果。
* <p>逐条记录新建、复用、跳过、失败明细,供结果清单弹窗展示。</p>
*/
@Data
public class OrgAlignResultVO {
/** 新建条数 */
private Integer createCount = 0;
/** 复用条数(同名部门已存在,直接关联) */
private Integer reuseCount = 0;
/** 跳过条数(已有关联/已停用/已离职等不处理) */
private Integer skipCount = 0;
/** 失败条数 */
private Integer failCount = 0;
private List<String> createList = new ArrayList<>();
private List<String> reuseList = new ArrayList<>();
private List<String> skipList = new ArrayList<>();
private List<String> failList = new ArrayList<>();
/** 汇总提示 */
private String message;
public void addCreate(String detail) {
createList.add(detail);
createCount++;
}
public void addReuse(String detail) {
reuseList.add(detail);
reuseCount++;
}
public void addSkip(String detail) {
skipList.add(detail);
skipCount++;
}
public void addFail(String detail) {
failList.add(detail);
failCount++;
}
public void buildMessage() {
this.message = String.format("新建 %d / 复用 %d / 跳过 %d / 失败 %d",
createCount, reuseCount, skipCount, failCount);
}
}