bug修复

This commit is contained in:
liumengyu
2026-08-28 17:34:56 +08:00
parent a43561af8d
commit 770d32a625
23 changed files with 464 additions and 42 deletions
@@ -2,6 +2,7 @@ package com.roomroot.jwgl.service;
import com.roomroot.jwgl.entity.XYXX;
import com.roomroot.jwgl.entity.XYDB;
import com.roomroot.jwgl.entity.PXRW;
import com.roomroot.jwgl.entity.XYXJYDSQB;
import com.roomroot.jwgl.entity.XYXJYJJGB;
import com.roomroot.jwgl.entity.XYXJYJTJB;
@@ -23,7 +24,7 @@ import java.util.List;
*/
public interface StudentRecordsService {
/** 新增学员 */
/** 新增学员。编号后台生成 UUID;学号按当前班次在学员队期表的学号前缀、学号位数顺序生成。 */
void add(XYXX xyxx);
/** 删除学员(退学处理) */
@@ -47,8 +48,8 @@ public interface StudentRecordsService {
// ========== 学员课程成绩查询 ==========
/** 分页查询学员的课程成绩列表(按学员编号、年度筛选,年度为空默认最新年度) */
PageResult<XYKCCJ> pageCourseGrades(PageQuery query, String xybh, Integer nd);
/** 分页查询学员的课程成绩列表(按课程编号、学员队编号、学号、年度筛选) */
PageResult<XYKCCJ> pageCourseGrades(PageQuery query, String kcbh, String xydbh, String xh, Integer nd);
/** 分页查询学员的课程过程成绩列表(按学员编号、年度筛选,年度为空默认最新年度) */
PageResult<XYKCGCCJ> pageCourseProcessGrades(PageQuery query, String xybh, Integer nd);
@@ -127,4 +128,11 @@ public interface StudentRecordsService {
/** 从 Excel(.xls/.xlsx) 批量导入学员信息 */
int importStudents(MultipartFile file) throws Exception;
/**
* 按主体培训任务标志查询培训任务。
*
* @param ztpxrw 主体培训任务:0-否,1-是
*/
List<PXRW> listTrainingTasks(Integer ztpxrw);
}
@@ -1,6 +1,8 @@
package com.roomroot.jwgl.service;
import com.roomroot.jwgl.entity.ZYJXJHB;
import com.roomroot.jwgl.unit.PageQuery;
import com.roomroot.jwgl.unit.PageResult;
import java.util.List;
@@ -53,13 +55,15 @@ public interface ZYJXJHBService {
List<ZYJXJHB> list();
/**
* 根据专业代号和停用标识查询
* 分页查询专业教学计划。
* <p>专业代号、停用标识可选,传了才作为等值条件过滤;不传则查询全部。</p>
*
* @param zydh 专业代号
* @param ty 停用标识(0-正常,1-停用)
* @return 列表
* @param query 分页参数
* @param zydh 专业代号(可选)
* @param ty 停用标识(可选,0-正常,1-停用)
* @return 分页结果
*/
List<ZYJXJHB> listByZydhAndTy(String zydh, Integer ty);
PageResult<ZYJXJHB> pageByZydhAndTy(PageQuery query, String zydh, Integer ty);
/** 从 Excel(.xls/.xlsx) 导入专业教学计划 */
int importZYJXJHBFromExcel(org.springframework.web.multipart.MultipartFile file) throws Exception;
@@ -44,6 +44,7 @@ public class DisciplineServiceImpl implements DisciplineService {
@Transactional
public void add(XKZYXX entity) {
entity.setTy(0);
entity.setBsh(UuidUtil.getUUID());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
entity.setTysj(sdf.format(new Date()));
xkzyxxMapper.insert(entity);
@@ -39,7 +39,6 @@ public class SemesterCalendarServiceImpl implements SemesterCalendarService {
XQXLB query = new XQXLB();
//将日期分为年度和月日
LocalDate date = LocalDate.parse(dateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
int nd = date.getYear();
String md = String.format("%02d%02d", date.getMonthValue(), date.getDayOfMonth());
query.setJqsj(md);
@@ -81,6 +80,7 @@ public class SemesterCalendarServiceImpl implements SemesterCalendarService {
@Override
public void update(XQXLB xqxlb) {
xqxlbMapper.updateById(xqxlb);
}
@@ -7,6 +7,8 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.roomroot.common.exception.ServiceException;
import com.roomroot.jwgl.entity.XYXX;
import com.roomroot.jwgl.entity.XYDB;
import com.roomroot.jwgl.entity.XYDQB;
import com.roomroot.jwgl.entity.PXRW;
import com.roomroot.jwgl.entity.XYXJYDSQB;
import com.roomroot.jwgl.entity.XYXJYJJGB;
import com.roomroot.jwgl.entity.XYXJYJTJB;
@@ -14,6 +16,8 @@ import com.roomroot.jwgl.entity.XYKCCJ;
import com.roomroot.jwgl.entity.XYKCGCCJ;
import com.roomroot.jwgl.mapper.XYXXMapper;
import com.roomroot.jwgl.mapper.XYDBMapper;
import com.roomroot.jwgl.mapper.XYDQBMapper;
import com.roomroot.jwgl.mapper.PXRWMapper;
import com.roomroot.jwgl.mapper.XYXJYDSQBMapper;
import com.roomroot.jwgl.mapper.XYXJYJJGBMapper;
import com.roomroot.jwgl.mapper.XYXJYJTJBMapper;
@@ -24,6 +28,8 @@ import com.roomroot.jwgl.unit.PageQuery;
import com.roomroot.jwgl.unit.PageResult;
import com.roomroot.jwgl.utils.ExcelParseUtil;
import com.roomroot.jwgl.utils.JwglRoleHelper;
import com.roomroot.jwgl.utils.UuidUtil;
import com.roomroot.jwgl.vo.StudentListEchoVO;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
@@ -39,7 +45,10 @@ import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static com.roomroot.jwgl.utils.BasicManagementConstants.FORBIDDEN;
@@ -56,6 +65,12 @@ public class StudentRecordsServiceImpl implements StudentRecordsService {
@Resource
private XYDBMapper xydbMapper;
@Resource
private XYDQBMapper xydqbMapper;
@Resource
private PXRWMapper pxrwMapper;
@Resource
private XYXJYDSQBMapper xyxjydsqbMapper;
@@ -78,12 +93,112 @@ public class StudentRecordsServiceImpl implements StudentRecordsService {
@Transactional
public void add(XYXX xyxx) {
denyStudentWrite();
if (xyxx == null) {
throw new ServiceException("学员信息不能为空");
}
String classId = trimToNull(xyxx.getDqbzbh());
if (classId == null) {
throw new ServiceException("当前班次编号不能为空");
}
xyxx.setDqbzbh(classId);
xyxx.setBh(UuidUtil.getOriginalUUID());
XYDQB period = findPeriodByClassId(classId);
if (period == null) {
throw new ServiceException("未找到当前班次对应的学员队期,无法生成学号");
}
xyxx.setXh(generateStudentNumber(period, classId));
if (trimToNull(xyxx.getXydqbh()) == null) {
xyxx.setXydqbh(period.getBh());
}
xyxx.setTxzt(0);
xyxx.setLjzt(0);
xyxx.setFbzt(0);
xyxxMapper.insert(xyxx);
}
/**
* 按当前班次在学员队期表中的学号前缀、学号位数,顺序生成不重复学号。
*/
private String generateStudentNumber(XYDQB period, String classId) {
String prefix = period.getXhqz() == null ? "" : period.getXhqz().trim();
int digits = (period.getXhws() == null || period.getXhws() <= 0) ? 3 : period.getXhws();
int seq = maxSequence(prefix, digits, classId) + 1;
int max = (int) Math.pow(10, digits) - 1;
while (seq <= max) {
String studentNo = prefix + padNumber(seq, digits);
Long exists = xyxxMapper.selectCount(new LambdaQueryWrapper<XYXX>().eq(XYXX::getXh, studentNo));
if (exists == null || exists == 0) {
return studentNo;
}
seq++;
}
throw new ServiceException("该班次学号已用尽,请调整学员队期的学号位数");
}
private XYDQB findPeriodByClassId(String classId) {
return xydqbMapper.selectOne(new LambdaQueryWrapper<XYDQB>()
.eq(XYDQB::getXydbh, classId)
.orderByDesc(XYDQB::getRxrq)
.last("LIMIT 1"));
}
private int maxSequence(String prefix, int digits, String classId) {
LambdaQueryWrapper<XYXX> wrapper = new LambdaQueryWrapper<>();
if (!prefix.isEmpty()) {
wrapper.likeRight(XYXX::getXh, prefix);
} else {
wrapper.eq(XYXX::getDqbzbh, classId);
}
wrapper.select(XYXX::getXh);
List<XYXX> list = xyxxMapper.selectList(wrapper);
int max = 0;
int prefixLen = prefix.length();
int expectedLen = prefixLen + digits;
for (XYXX row : list) {
if (row == null || row.getXh() == null) {
continue;
}
String xh = row.getXh().trim();
if (!xh.startsWith(prefix) || xh.length() != expectedLen) {
continue;
}
String suffix = xh.substring(prefixLen);
if (!isDigits(suffix)) {
continue;
}
int value = Integer.parseInt(suffix);
if (value > max) {
max = value;
}
}
return max;
}
private String padNumber(int value, int digits) {
String text = String.valueOf(value);
if (text.length() >= digits) {
return text;
}
StringBuilder builder = new StringBuilder(digits);
for (int i = text.length(); i < digits; i++) {
builder.append('0');
}
builder.append(text);
return builder.toString();
}
private boolean isDigits(String text) {
if (text == null || text.isEmpty()) {
return false;
}
for (int i = 0; i < text.length(); i++) {
if (!Character.isDigit(text.charAt(i))) {
return false;
}
}
return true;
}
@Override
@Transactional
public void delete(String bh) {
@@ -115,10 +230,51 @@ public class StudentRecordsServiceImpl implements StudentRecordsService {
}
Page<XYXX> page = new Page<>(query.getPageNum(), query.getPageSize());
Page<XYXX> result = xyxxMapper.selectPage(page, buildQueryWrapper(filter));
fillListEcho(result.getRecords());
return new PageResult<>(result.getRecords(), result.getTotal(),
query.getPageNum(), query.getPageSize());
}
/**
* 当前班次编号关联学员队表、专业表、学员课程成绩,回显年级、专业、班次、考试情况、不及格门数、管理机构。
*/
private void fillListEcho(List<XYXX> records) {
if (records == null || records.isEmpty()) {
return;
}
List<String> ids = new ArrayList<>();
for (XYXX row : records) {
if (row != null && row.getBh() != null && !row.getBh().isEmpty()) {
ids.add(row.getBh());
}
}
if (ids.isEmpty()) {
return;
}
List<StudentListEchoVO> echos = xyxxMapper.selectEchoByStudentIds(ids);
if (echos == null || echos.isEmpty()) {
return;
}
Map<String, StudentListEchoVO> byId = new HashMap<>();
for (StudentListEchoVO echo : echos) {
if (echo != null && echo.getBh() != null) {
byId.put(echo.getBh(), echo);
}
}
for (XYXX row : records) {
StudentListEchoVO echo = byId.get(row.getBh());
if (echo == null) {
continue;
}
row.setNj(echo.getNj());
row.setZy(echo.getZy());
row.setBc(echo.getBc());
row.setKsqk(echo.getKsqk());
row.setBjgms(echo.getBjgms() == null ? 0 : echo.getBjgms());
row.setGljg(echo.getGljg());
}
}
/**
* 全字段动态查询条件。
* <p>
@@ -135,6 +291,10 @@ public class StudentRecordsServiceImpl implements StudentRecordsService {
// 需要模糊匹配的字段(属性名)
Set<String> fuzzyFields = Set.of("xm", "lxdh", "txdz");
for (Field field : XYXX.class.getDeclaredFields()) {
TableField tableField = field.getAnnotation(TableField.class);
if (tableField != null && !tableField.exist()) {
continue;
}
Object value = getFieldValue(field, query);
if (value == null || !(value instanceof String) || ((String) value).isEmpty()) {
continue;
@@ -191,13 +351,14 @@ public class StudentRecordsServiceImpl implements StudentRecordsService {
// ========== 学员课程成绩查询 ==========
@Override
public PageResult<XYKCCJ> pageCourseGrades(PageQuery query, String xybh, Integer nd) {
String studentId = xybh;
public PageResult<XYKCCJ> pageCourseGrades(PageQuery query, String kcbh, String xydbh, String xh, Integer nd) {
String selfStudentId = null;
if (jwglRoleHelper.isStudent()) {
studentId = jwglRoleHelper.requireStudentId();
selfStudentId = jwglRoleHelper.requireStudentId();
}
Page<XYKCCJ> page = new Page<>(query.getPageNum(), query.getPageSize());
Page<XYKCCJ> result = xykccjMapper.selectPageByCondition(page, studentId, nd);
Page<XYKCCJ> result = xykccjMapper.selectPageByCondition(
page, trimToNull(kcbh), trimToNull(xydbh), trimToNull(xh), nd, selfStudentId);
return new PageResult<>(result.getRecords(), result.getTotal(),
query.getPageNum(), query.getPageSize());
}
@@ -387,6 +548,7 @@ public class StudentRecordsServiceImpl implements StudentRecordsService {
@Transactional
public void addApplication(XYXJYDSQB entity) {
LocalDateTime now = LocalDateTime.now();
entity.setBh(UuidUtil.getUUID());
entity.setCjsj(now);
entity.setXgsj(now);
// 状态默认待审核(0)
@@ -668,7 +830,24 @@ public class StudentRecordsServiceImpl implements StudentRecordsService {
return list.size();
}
@Override
public List<PXRW> listTrainingTasks(Integer ztpxrw) {
if (ztpxrw == null || (ztpxrw != 0 && ztpxrw != 1)) {
throw new ServiceException("主体培训任务只能为 0 或 1");
}
List<PXRW> list = pxrwMapper.selectByZtpxrw(ztpxrw);
return list == null ? new ArrayList<>() : list;
}
private String nvl(String value) {
return value == null ? "" : value;
}
private String trimToNull(String value) {
if (value == null) {
return null;
}
String text = value.trim();
return text.isEmpty() ? null : text;
}
}
@@ -2,9 +2,12 @@ package com.roomroot.jwgl.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.roomroot.jwgl.entity.ZYJXJHB;
import com.roomroot.jwgl.mapper.ZYJXJHBMapper;
import com.roomroot.jwgl.service.ZYJXJHBService;
import com.roomroot.jwgl.unit.PageQuery;
import com.roomroot.jwgl.unit.PageResult;
import com.roomroot.jwgl.utils.UuidUtil;
import org.springframework.stereotype.Service;
@@ -65,11 +68,19 @@ public class ZYJXJHBServiceImpl implements ZYJXJHBService {
}
@Override
public List<ZYJXJHB> listByZydhAndTy(String zydh, Integer ty) {
public PageResult<ZYJXJHB> pageByZydhAndTy(PageQuery query, String zydh, Integer ty) {
Page<ZYJXJHB> page = new Page<>(query.getPageNum(), query.getPageSize());
LambdaQueryWrapper<ZYJXJHB> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ZYJXJHB::getZydh, zydh)
.eq(ZYJXJHB::getTy, ty);
return zyjxjhbMapper.selectList(wrapper);
if (zydh != null && !zydh.isEmpty()) {
wrapper.eq(ZYJXJHB::getZydh, zydh);
}
if (ty != null) {
wrapper.eq(ZYJXJHB::getTy, ty);
}
wrapper.orderByAsc(ZYJXJHB::getZydh);
Page<ZYJXJHB> result = zyjxjhbMapper.selectPage(page, wrapper);
return new PageResult<>(result.getRecords(), result.getTotal(),
query.getPageNum(), query.getPageSize());
}
@Override