diff --git a/src/main/java/com/biutag/supervision/controller/data/ComplaintCollectionController.java b/src/main/java/com/biutag/supervision/controller/data/ComplaintCollectionController.java index ec2284a..415b514 100644 --- a/src/main/java/com/biutag/supervision/controller/data/ComplaintCollectionController.java +++ b/src/main/java/com/biutag/supervision/controller/data/ComplaintCollectionController.java @@ -89,6 +89,12 @@ public class ComplaintCollectionController { return Result.success(complaintCollectionService.getComplaintCollectionPageNew(request)); } + @Operation(description = "按记录重新同步局长信箱办理结果") + @PostMapping("/refreshMayorMailbox") + public Result refreshMayorMailbox(@RequestBody ComplaintCollectionDetailRequest request) { + return Result.success(mailBoxCaptureService.refreshMayorMailbox(request.getId())); + } + @Operation(description = "是否重复件") @PostMapping("/maileRepeatt") diff --git a/src/main/java/com/biutag/supervision/service/MailBoxCaptureService.java b/src/main/java/com/biutag/supervision/service/MailBoxCaptureService.java index 740d280..fe31e35 100644 --- a/src/main/java/com/biutag/supervision/service/MailBoxCaptureService.java +++ b/src/main/java/com/biutag/supervision/service/MailBoxCaptureService.java @@ -114,7 +114,16 @@ public class MailBoxCaptureService { log.info("【局长信箱抓取新信件】查询到投诉举报信件信件数量:{}", mailList.size()); Map involveProblemMapping = loadMayorMailboxInvolveProblemMapping(); + List sourceMergedMails = loadSourceMergedMails(mailList); Set mergedMailboxOriginIds = loadMergedMailboxOriginIds(); + List pendingMergedMails = sourceMergedMails.stream() + .filter(item -> StrUtil.isNotBlank(item.getId())) + .filter(item -> !mergedMailboxOriginIds.contains(item.getId())) + .toList(); + sourceMergedMails.stream() + .map(MailSource::getId) + .filter(StrUtil::isNotBlank) + .forEach(mergedMailboxOriginIds::add); // 3. 遍历处理 int successCount = 0; @@ -145,7 +154,10 @@ public class MailBoxCaptureService { } } - // 4. 输出统计 + // 4. 将源端合并子件按页面合并规则追加到主件合并历史 + syncMergedMailsToMainHistory(pendingMergedMails); + + // 5. 输出统计 long cost = System.currentTimeMillis() - startTimeMillis; log.info("【局长信箱抓取新信件】完成,总数:{},成功:{},跳过:{},失败:{},耗时:{}ms", mailList.size(), successCount, skipCount, failCount, cost); @@ -311,6 +323,151 @@ public class MailBoxCaptureService { return originIds; } + /** + * 查询本次待抓取邮件中的源端合并子件。 + */ + private List loadSourceMergedMails(List mailList) { + Set mailIds = mailList.stream() + .map(Mail::getId) + .filter(StrUtil::isNotBlank) + .collect(Collectors.toSet()); + if (CollectionUtil.isEmpty(mailIds)) { + return Collections.emptyList(); + } + + Map mergedSourceById = new HashMap<>(); + + MailSourceQueryParam childParam = new MailSourceQueryParam(); + childParam.setIds(mailIds); + childParam.setState("merge"); + mailSourceResourceService.query(childParam).forEach(item -> mergedSourceById.put(item.getId(), item)); + + List result = new ArrayList<>(mergedSourceById.values()); + log.info("【局长信箱抓取新信件】查询到源端合并子件数量:{}", result.size()); + return result; + } + + /** + * 将源端合并子件写入对应主件的 merge_history。 + */ + private void syncMergedMailsToMainHistory(List mergedSources) { + if (CollectionUtil.isEmpty(mergedSources)) { + return; + } + + Map> sourcesByMainId = mergedSources.stream() + .filter(item -> StrUtil.isNotBlank(item.getMailId())) + .collect(Collectors.groupingBy(MailSource::getMailId)); + + for (Map.Entry> entry : sourcesByMainId.entrySet()) { + String mainMailId = entry.getKey(); + try { + Boolean.TRUE.equals(transactionTemplate.execute(status -> + appendMergedMailsToMainHistory(mainMailId, entry.getValue()))); + } catch (Exception e) { + log.error("【局长信箱抓取新信件】同步合并历史失败: mainMailId={}, error={}", + mainMailId, e.getMessage(), e); + } + } + } + + private boolean appendMergedMailsToMainHistory(String mainMailId, List mergedSources) { + ComplaintCollectionQueryParam queryParam = new ComplaintCollectionQueryParam(); + queryParam.setOriginId(mainMailId); + queryParam.setSourceTable(ComplaintCollectionSourceTableEnum.MAYOR_MAILBOX.getCode()); + List mainRecords = complaintCollectionResourceService.query(queryParam); + if (CollectionUtil.isEmpty(mainRecords)) { + log.warn("【局长信箱抓取新信件】未找到合并主件对应的本地记录: mainMailId={}", mainMailId); + return false; + } + + ComplaintCollection mainRecord = mainRecords.get(0); + JSONObject history = new JSONObject(); + JSONArray merges = new JSONArray(); + if (StrUtil.isNotBlank(mainRecord.getMergeHistory())) { + try { + JSONObject existingHistory = JSON.parseObject(mainRecord.getMergeHistory()); + if (existingHistory != null) { + history = existingHistory; + JSONArray existingMerges = existingHistory.getJSONArray("merges"); + if (existingMerges != null) { + merges = existingMerges; + } + } + } catch (Exception e) { + log.warn("【局长信箱抓取新信件】解析主件合并历史失败,保留原数据不更新: mainMailId={}", mainMailId, e); + return false; + } + } + + Set existingOriginIds = new HashSet<>(); + for (Object merge : merges) { + JSONObject mergeRecord = JSON.parseObject(JSON.toJSONString(merge)); + if (mergeRecord != null + && ComplaintCollectionSourceTableEnum.MAYOR_MAILBOX.getCode() + .equals(mergeRecord.getString("sourceTable"))) { + String originId = mergeRecord.getString("originId"); + if (StrUtil.isNotBlank(originId)) { + existingOriginIds.add(originId); + } + } + } + + int appendCount = 0; + for (MailSource mergedSource : mergedSources) { + if (StrUtil.isBlank(mergedSource.getId()) || !existingOriginIds.add(mergedSource.getId())) { + continue; + } + merges.add(buildMergedMailHistory(mergedSource)); + appendCount++; + } + if (appendCount == 0) { + return false; + } + + history.put("merges", merges); + ComplaintCollectionUpdateParam updateParam = new ComplaintCollectionUpdateParam(); + updateParam.setId(mainRecord.getId()); + updateParam.setMergeHistory(history.toJSONString()); + updateParam.setRepeatt("1"); + boolean updated = complaintCollectionResourceService.updateSelectiveByIdForJob(updateParam); + if (!updated) { + throw new IllegalStateException("更新合并主件失败: mainMailId=" + mainMailId); + } + log.info("【局长信箱抓取新信件】合并历史同步成功: mainMailId={}, appendCount={}", + mainMailId, appendCount); + return true; + } + + private Map buildMergedMailHistory(MailSource source) { + Map mergeRecord = new HashMap<>(); + mergeRecord.put("mergeTime", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + mergeRecord.put("sourceTable", ComplaintCollectionSourceTableEnum.MAYOR_MAILBOX.getCode()); + mergeRecord.put("sourceTableSubOne", getSfssSourceTableSubOne(source.getSource())); + mergeRecord.put("originId", source.getId()); + mergeRecord.put("discoveryTime", source.getMailTime()); + mergeRecord.put("businessTypeCode", BusinessTypeEnum.ZFBA.getValue()); + mergeRecord.put("responderName", source.getContactName()); + mergeRecord.put("responderIdCode", source.getContactIdCard()); + mergeRecord.put("responderPhone", source.getContactPhone()); + mergeRecord.put("secondDepartId", source.getInvolvedDeptId()); + mergeRecord.put("secondDepartName", source.getInvolvedDeptName()); + mergeRecord.put("thingDesc", source.getContent()); + mergeRecord.put("files", buildMergeHistoryFiles(source.getAttachments())); + return mergeRecord; + } + + private List> buildMergeHistoryFiles(String attachmentsJson) { + return buildThingFiles(attachmentsJson).stream() + .map(file -> { + Map fileInfo = new HashMap<>(); + fileInfo.put("fileName", file.getFileName()); + fileInfo.put("filePath", file.getFilePath()); + return fileInfo; + }) + .toList(); + } + // ==================== 单位查询 ==================== /** @@ -443,6 +600,95 @@ public class MailBoxCaptureService { return true; } + /** + * 按涉访涉诉记录重新同步局长信箱办理结果。 + * 该入口用于人工刷新,直接按记录处理,不受 blameSyncStatus 限制。 + */ + public String refreshMayorMailbox(String complaintCollectionId) { + if (StrUtil.isBlank(complaintCollectionId)) { + throw new IllegalArgumentException("投诉举报记录ID不能为空"); + } + + ComplaintCollectionQueryParam ccParam = new ComplaintCollectionQueryParam(); + ccParam.setId(complaintCollectionId); + ccParam.setSourceTable(ComplaintCollectionSourceTableEnum.MAYOR_MAILBOX.getCode()); + List ccList = complaintCollectionResourceService.query(ccParam); + if (CollectionUtil.isEmpty(ccList)) { + throw new IllegalArgumentException("未找到对应的局长信箱记录"); + } + + ComplaintCollection cc = ccList.get(0); + if (StrUtil.isBlank(cc.getNegativeId())) { + throw new IllegalStateException("该局长信箱记录尚未关联问题数据,编号:" + cc.getOriginId()); + } + Negative negative = negativeService.getById(cc.getNegativeId()); + if (negative == null) { + throw new IllegalStateException("未找到对应的问题记录,编号:" + cc.getOriginId()); + } + + String sourceMailId = cc.getOriginId(); + if (StrUtil.isBlank(sourceMailId)) { + throw new IllegalStateException("该局长信箱记录的信件编号为空"); + } + MailSourceQueryParam sourceParam = new MailSourceQueryParam(); + sourceParam.setId(sourceMailId); + sourceParam.setState("merge"); + List mailSources = mailSourceResourceService.query(sourceParam); + if (CollectionUtil.isNotEmpty(mailSources)) { + sourceMailId = mailSources.get(0).getMailId(); + } + + MailQueryParam mailParam = new MailQueryParam(); + mailParam.setId(sourceMailId); + mailParam.setMailState("completion"); + List mails = mailResourceService.query(mailParam); + if (CollectionUtil.isEmpty(mails)) { + throw new IllegalStateException("局长信箱中未找到对应的已办结信件,编号:" + sourceMailId); + } + + Mail mail = mails.get(0); + if (!Set.of("属实", "基本属实", "不属实").contains(mail.getVerifyIsTrue())) { + throw new IllegalStateException("局长信箱核查结论为空或无法识别,编号:" + sourceMailId); + } + + List mailBlames = mailBlameMapper.selectList( + new LambdaQueryWrapper().eq(MailBlame::getMailId, mail.getId()) + ); + String oldCheckStatusName = negative.getCheckStatusName(); + String finalSourceMailId = sourceMailId; + + boolean success = Boolean.TRUE.equals(transactionTemplate.execute(status -> { + // 人工刷新按源端当前结果覆盖;源端已清空时也要清理本地旧数据。 + if (CollectionUtil.isEmpty(mailBlames)) { + negativeProblemRelationService.remove(negative.getId()); + blameService.remove(negative.getId()); + } else { + syncBlame(mail, negative.getId(), mailBlames); + } + syncFiles(mail, negative.getId()); + syncCheckStatus(mail, negative); + + List approvedStatus = List.of("非常满意", "基本满意"); + if (approvedStatus.contains(mail.getSatisfactionStatus())) { + cc.setPublicRecognition(ComplaintCollectionPublicApprovalEnum.APPROVED.getCode()); + } else if ("不满意".equals(mail.getSatisfactionStatus())) { + cc.setPublicRecognition(ComplaintCollectionPublicApprovalEnum.NOT_APPROVED.getCode()); + } + updateSyncTag(cc); + return true; + })); + if (!success) { + throw new IllegalStateException("局长信箱办理结果更新失败,编号:" + finalSourceMailId); + } + + String newCheckStatusName = "基本属实".equals(mail.getVerifyIsTrue()) + ? "部分属实" : mail.getVerifyIsTrue(); + String mergeMessage = Objects.equals(cc.getOriginId(), sourceMailId) + ? "" : ",该记录为合并子件,已使用主件" + sourceMailId + "的数据"; + return String.format("更新成功:核查结论由“%s”更新为“%s”%s", + StrUtil.blankToDefault(oldCheckStatusName, "未同步"), newCheckStatusName, mergeMessage); + } + /** * 同步涉及人 */