forked from liweijie/education
1、停用教员的同时禁用该教员的账号;
2、教员导入的时候,如果有错误,跳过并返回具体报错行; 3、教研室接口权限添加控制
This commit is contained in:
+32
@@ -0,0 +1,32 @@
|
||||
package com.roomroot.jwgl.dto.faculty;
|
||||
|
||||
import com.roomroot.jwgl.entity.JYB;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 教员(教员表)导入行解析结果。
|
||||
* <p>
|
||||
* 保留 Excel 中的原始行号,便于把校验失败原因定位到具体行。
|
||||
* </p>
|
||||
*/
|
||||
@Data
|
||||
public class TeacherImportRowDTO {
|
||||
|
||||
/**
|
||||
* Excel 行号(1 起始,含表头行)。
|
||||
*/
|
||||
private int rowNum;
|
||||
|
||||
/**
|
||||
* 该行解析出的教员实体。
|
||||
*/
|
||||
private JYB entity;
|
||||
|
||||
public TeacherImportRowDTO() {
|
||||
}
|
||||
|
||||
public TeacherImportRowDTO(int rowNum, JYB entity) {
|
||||
this.rowNum = rowNum;
|
||||
this.entity = entity;
|
||||
}
|
||||
}
|
||||
+34
-12
@@ -3,6 +3,7 @@ package com.roomroot.jwgl.service.impl;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.roomroot.jwgl.dto.faculty.AddTeacherDTO;
|
||||
import com.roomroot.jwgl.dto.faculty.TeacherImportRowDTO;
|
||||
import com.roomroot.jwgl.entity.*;
|
||||
import com.roomroot.jwgl.mapper.*;
|
||||
import com.roomroot.jwgl.mapper.*;
|
||||
@@ -20,6 +21,7 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -320,33 +322,53 @@ public class FacultyServiceImpl implements FacultyService {
|
||||
if (file == null || file.isEmpty()) {
|
||||
throw new BusinessException("导入文件不能为空");
|
||||
}
|
||||
List<JYB> list = ExcelParseUtil.parseJYBExcel(
|
||||
List<TeacherImportRowDTO> rows = ExcelParseUtil.parseJYBExcel(
|
||||
file.getInputStream(), file.getOriginalFilename());
|
||||
if (list.isEmpty()) {
|
||||
if (rows.isEmpty()) {
|
||||
throw new BusinessException("Excel中无有效数据");
|
||||
}
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
JYB entity = list.get(i);
|
||||
// Excel 第 1 行为抬头,故数据行号 = 下标 + 2
|
||||
int rowNo = i + 2;
|
||||
// 第一轮:逐行校验聚合报错(不回写任何数据)
|
||||
List<String> errors = new ArrayList<>();
|
||||
java.util.Set<String> seenJybh = new java.util.HashSet<>();
|
||||
for (TeacherImportRowDTO row : rows) {
|
||||
JYB entity = row.getEntity();
|
||||
int rowNo = row.getRowNum();
|
||||
if (isBlank(entity.getJyxm())) {
|
||||
throw new BusinessException("第 " + rowNo + " 行:教员姓名未填写");
|
||||
errors.add("第 " + rowNo + " 行:教员姓名未填写");
|
||||
}
|
||||
// 教研室代号为非空外键,缺失会直接抛数据库非空约束异常,这里给出可定位的提示
|
||||
if (isBlank(entity.getJysdh())) {
|
||||
throw new BusinessException("第 " + rowNo + " 行:教研室代号未填写");
|
||||
errors.add("第 " + rowNo + " 行:教研室代号未填写");
|
||||
} else if (jysbMapper.selectById(entity.getJysdh().trim()) == null) {
|
||||
errors.add("第 " + rowNo + " 行:教研室代号不存在 " + entity.getJysdh());
|
||||
}
|
||||
// 编号为空自动生成
|
||||
if (!isBlank(entity.getJybh())) {
|
||||
String jybh = entity.getJybh().trim();
|
||||
if (jybMapper.selectById(jybh) != null) {
|
||||
errors.add("第 " + rowNo + " 行:教员编号已存在 " + jybh);
|
||||
} else if (!seenJybh.add(jybh)) {
|
||||
errors.add("第 " + rowNo + " 行:教员编号在文件内重复 " + jybh);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!errors.isEmpty()) {
|
||||
throw new BusinessException("导入失败,共 " + errors.size() + " 行校验未通过:\n"
|
||||
+ String.join("\n", errors));
|
||||
}
|
||||
// 第二轮:全部校验通过才入库(事务内,任一异常整批回滚)
|
||||
for (TeacherImportRowDTO row : rows) {
|
||||
JYB entity = row.getEntity();
|
||||
if (isBlank(entity.getJybh())) {
|
||||
entity.setJybh(nextJybh());
|
||||
} else if (jybMapper.selectById(entity.getJybh().trim()) != null) {
|
||||
throw new BusinessException("第 " + rowNo + " 行:教员编号已存在 " + entity.getJybh());
|
||||
} else {
|
||||
entity.setJybh(entity.getJybh().trim());
|
||||
}
|
||||
entity.setJysdh(entity.getJysdh().trim());
|
||||
// 离职状态等非空列兜底(数据库缺省值在 MyBatis-Plus 下不会生效)
|
||||
applyTeacherDefaults(entity);
|
||||
jybMapper.insert(entity);
|
||||
}
|
||||
return list.size();
|
||||
return rows.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+25
-5
@@ -158,11 +158,18 @@ public class OrgSyncServiceImpl implements OrgSyncService {
|
||||
Long deptId = resolveTeacherDeptId(jyb);
|
||||
|
||||
String name = StringUtils.isBlank(loginName) ? jyb.getJybh() : loginName.trim();
|
||||
SysUser existing = userService.selectUserByUserName(name);
|
||||
if (existing != null) {
|
||||
// 孤儿账号(账号在、映射丢失):复用并回填锚点,不重复建号
|
||||
JYB relink = new JYB();
|
||||
relink.setJybh(jyb.getJybh());
|
||||
relink.setYhbh(existing.getUserId());
|
||||
relink.setBmbh(existing.getDeptId() != null ? existing.getDeptId() : deptId);
|
||||
jybMapper.updateById(relink);
|
||||
return existing.getUserId();
|
||||
}
|
||||
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());
|
||||
@@ -189,10 +196,23 @@ public class OrgSyncServiceImpl implements OrgSyncService {
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void syncTeacherAccount(JYB before, JYB after) {
|
||||
if (before == null || before.getYhbh() == null) {
|
||||
if (before == null) {
|
||||
return;
|
||||
}
|
||||
SysUser user = userService.selectUserById(before.getYhbh());
|
||||
SysUser user = null;
|
||||
if (before.getYhbh() != null) {
|
||||
user = userService.selectUserById(before.getYhbh());
|
||||
}
|
||||
if (user == null && StringUtils.isNotBlank(before.getJybh())) {
|
||||
// 锚点缺失(账号存在但教员表.用户编号未回填):按登录名=教员编号兜底定位孤儿账号并回填
|
||||
user = userService.selectUserByUserName(before.getJybh());
|
||||
if (user != null && !"2".equals(user.getDelFlag())) {
|
||||
JYB relink = new JYB();
|
||||
relink.setJybh(before.getJybh());
|
||||
relink.setYhbh(user.getUserId());
|
||||
jybMapper.updateById(relink);
|
||||
}
|
||||
}
|
||||
if (user == null || "2".equals(user.getDelFlag())) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.roomroot.jwgl.dto.courserunning.SemesterImportDTO;
|
||||
import com.roomroot.jwgl.dto.courserunning.SingleCourseImportDTO;
|
||||
import com.roomroot.jwgl.dto.departmentpersonnel.DepartmentPersonnelCreateDTO;
|
||||
import com.roomroot.jwgl.dto.discipline.MajorImportRowDTO;
|
||||
import com.roomroot.jwgl.dto.faculty.TeacherImportRowDTO;
|
||||
import com.roomroot.jwgl.entity.JXSSJH;
|
||||
import com.roomroot.jwgl.entity.JYB;
|
||||
import com.roomroot.jwgl.entity.JYSB;
|
||||
@@ -401,8 +402,8 @@ public class ExcelParseUtil {
|
||||
* @return 教员实体列表(离职状态由业务层默认填充)
|
||||
* @throws Exception 解析异常
|
||||
*/
|
||||
public static List<JYB> parseJYBExcel(InputStream inputStream, String fileName) throws Exception {
|
||||
List<JYB> result = new ArrayList<>();
|
||||
public static List<TeacherImportRowDTO> parseJYBExcel(InputStream inputStream, String fileName) throws Exception {
|
||||
List<TeacherImportRowDTO> result = new ArrayList<>();
|
||||
Workbook workbook = createWorkbook(inputStream, fileName);
|
||||
try {
|
||||
Sheet sheet = workbook.getSheetAt(0);
|
||||
@@ -425,10 +426,14 @@ public class ExcelParseUtil {
|
||||
entity.setBz(getCellStringValue(row.getCell(9)));
|
||||
entity.setXh(getCellStringValue(row.getCell(10)));
|
||||
entity.setXslx(parseIntCell(row.getCell(11)));
|
||||
// 至少要有姓名才视为有效行
|
||||
if (entity.getJyxm() != null && !entity.getJyxm().isEmpty()) {
|
||||
result.add(entity);
|
||||
// 整行全空的跳过;有任何字段即保留,由业务层逐行校验并聚合报错
|
||||
if (isAllBlank(entity.getJybh(), entity.getJyxm(), entity.getJysdh(),
|
||||
entity.getZc(), entity.getZyjszwdj(), entity.getJylb(),
|
||||
entity.getSjh(), entity.getSfzh(), entity.getBz(), entity.getXh())
|
||||
&& entity.getXb() == null && entity.getXslx() == null) {
|
||||
continue;
|
||||
}
|
||||
result.add(new TeacherImportRowDTO(rowNum + 1, entity));
|
||||
}
|
||||
} finally {
|
||||
workbook.close();
|
||||
@@ -436,6 +441,15 @@ public class ExcelParseUtil {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean isAllBlank(String... values) {
|
||||
for (String v : values) {
|
||||
if (v != null && !v.trim().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析培养方案(专业表)导入 Excel 文件(支持 .xls / .xlsx)。
|
||||
* <p>表头顺序:</p>
|
||||
|
||||
Reference in New Issue
Block a user