| | |
| | | import java.time.YearMonth; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.ArrayList; |
| | | import java.util.regex.Matcher; |
| | | import java.util.regex.Pattern; |
| | | import java.util.Base64; |
| | | import java.util.HashMap; |
| | | import java.util.LinkedHashSet; |
| | |
| | | throw new ErrorException("未找到被监督员:" + superviseDetails.getSupervisee()); |
| | | } |
| | | superviseDetails.setSupervisedUserId(user.getId()); |
| | | // 格式化时间 |
| | | superviseDetails.setSuperviseTime(detailsUpload.getSuperviseTime()); |
| | | // 统一日期格式,避免 Excel 把 2026-03-15 存成 2026/3/15 后无法解析 |
| | | superviseDetails.setSuperviseTime(normalizeSuperviseTime(detailsUpload.getSuperviseTime())); |
| | | |
| | | detailsUploadList.add(superviseDetails); |
| | | } |
| | |
| | | } |
| | | |
| | | /** |
| | | * 统一监督日期格式为 yyyy.M: |
| | | * 2026-03-15 / 2026/3/15 / 2026.3.15 / 2026年3月15日 -> 2026.3; |
| | | * 已经是 2026.3 或 "3月、12月" 等写法保持原样。 |
| | | */ |
| | | private static String normalizeSuperviseTime(String superviseTime) { |
| | | if (StringUtils.isBlank(superviseTime)) { |
| | | return superviseTime; |
| | | } |
| | | String text = superviseTime.trim(); |
| | | Matcher matcher = Pattern.compile("^(\\d{4})\\s*[./年-]\\s*(\\d{1,2})(?:\\s*[./月-]\\s*(\\d{1,2})\\s*日?)?$") |
| | | .matcher(text); |
| | | if (matcher.matches()) { |
| | | int month = Integer.parseInt(matcher.group(2)); |
| | | if (month >= 1 && month <= 12) { |
| | | return matcher.group(1) + "." + month; |
| | | } |
| | | } |
| | | return text; |
| | | } |
| | | |
| | | /** |
| | | * 解析监督日期对应的年月,兼容历史数据中的完整日期写法。 |
| | | */ |
| | | private static YearMonth parseSuperviseYearMonth(String superviseTime, String fallbackYear) { |
| | | if (StringUtils.isNotBlank(superviseTime)) { |
| | | String first = superviseTime.split("[、,,;;]+")[0].trim(); |
| | | Matcher fullDate = Pattern.compile("(\\d{4})\\s*[./年-]\\s*(\\d{1,2})").matcher(first); |
| | | if (fullDate.find()) { |
| | | int month = Integer.parseInt(fullDate.group(2)); |
| | | if (month >= 1 && month <= 12) { |
| | | return YearMonth.of(Integer.parseInt(fullDate.group(1)), month); |
| | | } |
| | | } |
| | | // "3月、12月" 这类没有年份的写法,使用计划年度 |
| | | Matcher monthOnly = Pattern.compile("^(\\d{1,2})").matcher(first); |
| | | if (monthOnly.find()) { |
| | | int month = Integer.parseInt(monthOnly.group(1)); |
| | | if (month >= 1 && month <= 12) { |
| | | int year = LocalDate.now().getYear(); |
| | | if (StringUtils.isNotBlank(fallbackYear)) { |
| | | Matcher yearMatcher = Pattern.compile("(\\d{4})").matcher(fallbackYear); |
| | | if (yearMatcher.find()) { |
| | | year = Integer.parseInt(yearMatcher.group(1)); |
| | | } |
| | | } |
| | | return YearMonth.of(year, month); |
| | | } |
| | | } |
| | | } |
| | | return YearMonth.now(); |
| | | } |
| | | |
| | | /** |
| | | * 监督频次: 按监督时间中的月份个数计算, 如 "2026.3" -> "1次/年", "3月、12月" -> "2次/年" |
| | | */ |
| | | private static String buildSuperviseFrequency(String superviseTime) { |
| | |
| | | return ""; |
| | | } |
| | | int count = 0; |
| | | for (String part : superviseTime.split("[、,,;;/\\s]+")) { |
| | | for (String part : normalizeSuperviseTime(superviseTime).split("[、,,;;/\\s]+")) { |
| | | if (part.matches(".*\\d.*")) { |
| | | count++; |
| | | } |
| | |
| | | } |
| | | StringBuilder sb = new StringBuilder(); |
| | | for (String part : superviseTime.split("[、,,;;]+")) { |
| | | String s = part.trim(); |
| | | String s = normalizeSuperviseTime(part.trim()); |
| | | if (s.isEmpty()) { |
| | | continue; |
| | | } |
| | |
| | | if (detailsRecord == null) { |
| | | // 查询详情信息 |
| | | QualitySuperviseDetails qualitySuperviseDetails = qualitySuperviseDetailsMapper.selectById(superviseDetailsId); |
| | | QualitySupervise qualitySupervise = baseMapper.selectById(qualitySuperviseDetails.getSuperviseId()); |
| | | // 查询上一个月第一条的记录信息, 判断被监督人去另外一个 |
| | | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.M"); |
| | | YearMonth yearMonth = YearMonth.parse(qualitySuperviseDetails.getSuperviseTime(), formatter); |
| | | // 监督日期兼容 2026.3 / 2026-03-15 / 2026/3/15 / 2026年3月15日 等写法 |
| | | YearMonth yearMonth = parseSuperviseYearMonth(qualitySuperviseDetails.getSuperviseTime(), |
| | | qualitySupervise == null ? null : qualitySupervise.getSuperviseYear()); |
| | | YearMonth previousYearMonth = yearMonth.minusMonths(1); |
| | | |
| | | LocalDate startDate = previousYearMonth.atDay(1); |
| | |
| | | |
| | | String supervisor = null; |
| | | |
| | | if (laseRecord != null) { |
| | | // 查询计划获取另一个监督员 |
| | | QualitySupervise qualitySupervise = baseMapper.selectById(qualitySuperviseDetails.getSuperviseId()); |
| | | if (StringUtils.isNotBlank(qualitySupervise.getRecordUserIds())) { |
| | | List<String> recordUserIds = StrUtil.split(qualitySupervise.getRecordUserIds(), ','); |
| | | List<User> users = userMapper.selectList(Wrappers.<User>lambdaQuery() |
| | | .in(User::getId, recordUserIds)); |
| | | if (CollectionUtils.isNotEmpty(users) && users.size() == 2) { |
| | | // 判断是否一样, 一样获取另外一个 |
| | | if (users.get(0).getName().equals(laseRecord.getSupervisor())) { |
| | | supervisor = users.get(1).getName(); |
| | | } else { |
| | | supervisor = users.get(0).getName(); |
| | | } |
| | | |
| | | // 计划指定的监督员:首次填写时默认带出第一位;有上月记录时两位监督员交替 |
| | | if (qualitySupervise != null && StringUtils.isNotBlank(qualitySupervise.getRecordUserIds())) { |
| | | List<String> recordUserIds = StrUtil.split(qualitySupervise.getRecordUserIds(), ','); |
| | | List<User> users = userMapper.selectList(Wrappers.<User>lambdaQuery() |
| | | .in(User::getId, recordUserIds)); |
| | | if (CollectionUtils.isNotEmpty(users)) { |
| | | if (laseRecord != null && users.size() > 1 |
| | | && users.get(0).getName().equals(laseRecord.getSupervisor())) { |
| | | supervisor = users.get(1).getName(); |
| | | } else { |
| | | supervisor = users.get(0).getName(); |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | /** |
| | | * 被监督人员确认监督记录(程序4.2.5: 被监督对象对监督记录真实性提出确认意见) |
| | | */ |
| | | @Override |
| | | public boolean confirmSuperviseRecord(QualitySuperviseDetailsRecord input) { |
| | | if (input == null || input.getSuperviseDetailsId() == null) { |
| | | throw new ErrorException("缺少监督详细信息id"); |
| | | } |
| | | QualitySuperviseDetailsRecord record = qualitySuperviseDetailsRecordMapper.selectOne( |
| | | Wrappers.<QualitySuperviseDetailsRecord>lambdaQuery() |
| | | .eq(QualitySuperviseDetailsRecord::getSuperviseDetailsId, input.getSuperviseDetailsId()) |
| | | .last("limit 1")); |
| | | if (record == null) { |
| | | throw new ErrorException("监督员尚未提交监督记录,无法确认"); |
| | | } |
| | | Integer userId = SecurityUtils.getUserId().intValue(); |
| | | User user = userMapper.selectById(userId); |
| | | if (user == null) { |
| | | throw new ErrorException("当前用户不存在"); |
| | | } |
| | | // 只有被监督人员本人才可以确认 |
| | | boolean isSupervisee = StrUtil.split(record.getTestMember(), '、').stream() |
| | | .map(String::trim) |
| | | .anyMatch(name -> name.equals(user.getName())); |
| | | if (!isSupervisee) { |
| | | QualitySuperviseDetails detail = qualitySuperviseDetailsMapper.selectById(input.getSuperviseDetailsId()); |
| | | isSupervisee = detail != null && userId.equals(detail.getSupervisedUserId()); |
| | | } |
| | | if (!isSupervisee) { |
| | | throw new ErrorException("只有被监督人员可以确认监督记录"); |
| | | } |
| | | String opinion = StringUtils.isBlank(input.getConfirmOpinion()) |
| | | ? "对监督记录真实性表示认可。" : input.getConfirmOpinion().trim(); |
| | | qualitySuperviseDetailsRecordMapper.update(null, |
| | | Wrappers.<QualitySuperviseDetailsRecord>lambdaUpdate() |
| | | .eq(QualitySuperviseDetailsRecord::getSuperviseDetailsRecordId, |
| | | record.getSuperviseDetailsRecordId()) |
| | | .set(QualitySuperviseDetailsRecord::getConfirmOpinion, opinion)); |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * 导出监督记录表(日常监督检查记录表) |
| | | * @param superviseDetailsId |
| | | * @param response |
| | |
| | | put("qualityUrl", signatureOrTransparent(recordDto.getRatifyUserId())); |
| | | put("qualityDateStr", recordDto.getRatifyTime() != null ? |
| | | recordDto.getRatifyTime().format(RECORD_DATE_FORMATTER) : ""); |
| | | // 程序4.2.5: 被监督人员对监督记录真实性的确认意见, 未确认时沿用纸张表的默认表述 |
| | | put("confirmOpinionText", StringUtils.isNotBlank(recordDto.getConfirmOpinion()) |
| | | ? recordDto.getConfirmOpinion() : "对监督记录真实性表示认可。"); |
| | | put("superviseMethodText", StringUtils.isNotBlank(recordDto.getSuperviseMethod()) |
| | | ? recordDto.getSuperviseMethod() : ""); |
| | | }}); |
| | | |
| | | try { |
| | |
| | | } |
| | | |
| | | /** |
| | | * 监督内容(9项, 按纸张表横排顺序) |
| | | * 监督内容(9项, 与受控记录表 LMSY-CX29-JL02 的横排顺序、文字完全一致) |
| | | */ |
| | | private static final String[] SUPERVISE_CONTENT_ITEMS = { |
| | | "人员持证及培训", "设施及环境条件", "检测方法", |