package jnpf.tmsService.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import jnpf.base.UserInfo; import jnpf.exception.DataException; import jnpf.permission.OrganizeApi; import jnpf.permission.PositionApi; import jnpf.permission.entity.OrganizeEntity; import jnpf.permission.entity.PositionEntity; import jnpf.tmsEntity.TmsPersonFileEntity; import jnpf.tmsEntity.TmsPersonTrainEntity; import jnpf.tmsEntity.TmsPersonWorkEntity; import jnpf.tmsEntity.archive.TmsTrainArchiveCatalogVO; import jnpf.tmsEntity.archive.TmsTrainArchiveDetailVO; import jnpf.tmsEntity.archive.TmsTrainArchiveProfileVO; import jnpf.tmsEntity.archive.TmsTrainArchiveWorkVO; import jnpf.tmsMapper.TmsPersonFileMapper; import jnpf.tmsMapper.TmsPersonTrainMapper; import jnpf.tmsMapper.TmsPersonWorkMapper; import jnpf.tmsService.TmsTrainArchiveService; import jnpf.util.DateUtil; import jnpf.util.RandomUtil; import jnpf.util.StringUtil; import jnpf.util.UserProvider; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; @Slf4j @Service @RequiredArgsConstructor public class TmsTrainArchiveServiceImpl implements TmsTrainArchiveService { private final TmsPersonFileMapper personFileMapper; private final TmsPersonWorkMapper personWorkMapper; private final TmsPersonTrainMapper personTrainMapper; private final OrganizeApi organizeApi; private final PositionApi positionApi; @Override @Transactional(rollbackFor = Exception.class) public TmsTrainArchiveDetailVO getMine() { UserInfo user = UserProvider.getUser(); if (user == null || StringUtil.isEmpty(user.getUserId())) { throw new DataException("未获取到登录用户"); } String userId = user.getUserId(); TmsPersonFileEntity file = findByUserId(userId); if (file == null) { file = createArchive(user); } TmsTrainArchiveDetailVO detail = new TmsTrainArchiveDetailVO(); detail.setProfile(toProfile(file, user)); detail.setWorkList(loadWorkList(file.getId())); detail.setCatalogList(loadCatalogList(file.getId(), userId)); return detail; } private TmsPersonFileEntity findByUserId(String userId) { LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); qw.eq(TmsPersonFileEntity::getUserId, userId); qw.last("LIMIT 1"); return personFileMapper.selectOne(qw); } private TmsPersonFileEntity createArchive(UserInfo user) { Date now = new Date(); TmsPersonFileEntity entity = new TmsPersonFileEntity(); entity.setId(RandomUtil.uuId()); entity.setArchiveNo(nextArchiveNo()); entity.setArchiveDate(now); entity.setUserId(user.getUserId()); entity.setUserName(user.getUserName()); entity.setDeptId(user.getOrganizeId()); List positionIds = normalizeIds(user.getPositionIds()); if (!positionIds.isEmpty()) { entity.setMainPostId(positionIds.get(0)); if (positionIds.size() > 1) { entity.setPartPostId(positionIds.get(1)); } } entity.setBizStatus("valid"); entity.setCreatorUserId(user.getUserId()); entity.setCreatorTime(now); personFileMapper.insert(entity); return entity; } private List normalizeIds(Object raw) { if (raw == null) { return Collections.emptyList(); } if (raw instanceof List) { List list = (List) raw; List out = new ArrayList<>(); for (Object o : list) { if (o != null && StringUtil.isNotEmpty(String.valueOf(o))) { out.add(String.valueOf(o)); } } return out; } if (raw instanceof String[]) { List out = new ArrayList<>(); for (String s : (String[]) raw) { if (StringUtil.isNotEmpty(s)) { out.add(s); } } return out; } if (raw instanceof String && StringUtil.isNotEmpty((String) raw)) { return Collections.singletonList((String) raw); } return Collections.emptyList(); } /** 档案编号:AR + 年份 + 4 位流水 */ private String nextArchiveNo() { int year = Calendar.getInstance().get(Calendar.YEAR); String prefix = "AR" + year; LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); qw.likeRight(TmsPersonFileEntity::getArchiveNo, prefix); qw.orderByDesc(TmsPersonFileEntity::getArchiveNo); qw.last("LIMIT 1"); TmsPersonFileEntity last = personFileMapper.selectOne(qw); int seq = 1; if (last != null && StringUtil.isNotEmpty(last.getArchiveNo()) && last.getArchiveNo().length() >= prefix.length() + 4) { try { seq = Integer.parseInt(last.getArchiveNo().substring(prefix.length())) + 1; } catch (NumberFormatException ignored) { seq = 1; } } return prefix + String.format("%04d", Math.min(seq, 9999)); } private TmsTrainArchiveProfileVO toProfile(TmsPersonFileEntity file, UserInfo user) { TmsTrainArchiveProfileVO vo = new TmsTrainArchiveProfileVO(); vo.setId(file.getId()); vo.setArchiveNo(file.getArchiveNo()); vo.setArchiveDate(file.getArchiveDate() == null ? null : DateUtil.dateToString(file.getArchiveDate(), "yyyy-MM-dd")); vo.setUserId(file.getUserId()); vo.setUserName(StringUtil.isNotEmpty(file.getUserName()) ? file.getUserName() : user.getUserName()); vo.setDeptName(resolveDeptName(file.getDeptId(), user)); vo.setMainPostName(resolvePostName(file.getMainPostId(), user, true)); vo.setPartPostName(resolvePostName(file.getPartPostId(), user, false)); return vo; } private String resolveDeptName(String deptId, UserInfo user) { if (StringUtil.isNotEmpty(deptId)) { try { OrganizeEntity org = organizeApi.getInfoById(deptId); if (org != null && StringUtil.isNotEmpty(org.getFullName())) { return org.getFullName(); } } catch (Exception e) { log.debug("resolve dept name failed: {}", e.getMessage()); } } if (user != null && StringUtil.isNotEmpty(user.getOrganize())) { return user.getOrganize(); } return "无"; } private String resolvePostName(String postId, UserInfo user, boolean main) { if (StringUtil.isNotEmpty(postId)) { try { PositionEntity pos = positionApi.queryInfoById(postId); if (pos != null && StringUtil.isNotEmpty(pos.getFullName())) { return pos.getFullName(); } } catch (Exception e) { log.debug("resolve post name failed: {}", e.getMessage()); } } if (main && user != null) { List positionIds = normalizeIds(user.getPositionIds()); if (!positionIds.isEmpty()) { try { List list = positionApi.getListByIds(positionIds); if (list != null && !list.isEmpty() && StringUtil.isNotEmpty(list.get(0).getFullName())) { return list.get(0).getFullName(); } } catch (Exception e) { log.debug("resolve main post from user failed: {}", e.getMessage()); } } } return "无"; } private List loadWorkList(String archiveId) { LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); qw.eq(TmsPersonWorkEntity::getForeignId, archiveId); qw.orderByAsc(TmsPersonWorkEntity::getHireDate); List rows = personWorkMapper.selectList(qw); if (rows == null || rows.isEmpty()) { return Collections.emptyList(); } List list = new ArrayList<>(rows.size()); for (TmsPersonWorkEntity row : rows) { TmsTrainArchiveWorkVO vo = new TmsTrainArchiveWorkVO(); vo.setId(row.getId()); vo.setCompanyName(row.getCompanyName()); vo.setPostName(row.getPostName()); vo.setHireDate(row.getHireDate() == null ? null : DateUtil.dateToString(row.getHireDate(), "yyyy-MM-dd")); vo.setLeaveDate(row.getLeaveDate() == null ? null : DateUtil.dateToString(row.getLeaveDate(), "yyyy-MM-dd")); list.add(vo); } return list; } private List loadCatalogList(String archiveId, String userId) { LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); qw.and(w -> w.eq(TmsPersonTrainEntity::getArchiveId, archiveId) .or() .eq(TmsPersonTrainEntity::getUserId, userId)); qw.orderByDesc(TmsPersonTrainEntity::getStartTime); List rows = personTrainMapper.selectList(qw); if (rows == null || rows.isEmpty()) { return Collections.emptyList(); } // 去重:同一 id 只保留一条 return rows.stream() .filter(Objects::nonNull) .collect(Collectors.toMap(TmsPersonTrainEntity::getId, r -> r, (a, b) -> a)) .values() .stream() .sorted((a, b) -> { Date ta = a.getStartTime(); Date tb = b.getStartTime(); if (ta == null && tb == null) return 0; if (ta == null) return 1; if (tb == null) return -1; return tb.compareTo(ta); }) .map(this::toCatalog) .collect(Collectors.toList()); } private TmsTrainArchiveCatalogVO toCatalog(TmsPersonTrainEntity row) { TmsTrainArchiveCatalogVO vo = new TmsTrainArchiveCatalogVO(); vo.setId(row.getId()); vo.setRecordNo(row.getRecordNo()); vo.setTrainType(row.getCategory()); vo.setTrainContent(row.getSubject()); vo.setTrainMode(row.getTrainMode()); vo.setTrainerName(row.getTeacherId()); vo.setEvalMode(row.getEvalMode()); vo.setPassFlag(row.getPassFlag() == null ? "" : row.getPassFlag()); vo.setTrainStart(row.getStartTime() == null ? null : DateUtil.dateToString(row.getStartTime(), "yyyy-MM-dd HH:mm")); vo.setTrainEnd(row.getEndTime() == null ? null : DateUtil.dateToString(row.getEndTime(), "yyyy-MM-dd HH:mm")); return vo; } }