From 36f42cba03980b7599d44f23f6cdf9e975f82004 Mon Sep 17 00:00:00 2001 From: buaixuexideshitongxue <2936013465@qq.com> Date: Wed, 29 Apr 2026 18:28:24 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=88=9D=E6=A0=B8=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E5=88=9D=E6=AD=A5=E5=AE=8C=E6=88=90=EF=BC=8C?= =?UTF-8?q?=E5=BE=85=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../supervision/job/MailBoxCaptureJob.java | 11 +- .../mapper/MailExtensionMapper.java | 16 ++ .../supervision/pojo/entity/mailbox/Mail.java | 85 ++++++++ .../pojo/entity/mailbox/MailExtension.java | 41 ++++ .../service/MailBoxCaptureService.java | 199 ++++++++++++++++++ 5 files changed, 351 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/biutag/supervision/mapper/MailExtensionMapper.java create mode 100644 src/main/java/com/biutag/supervision/pojo/entity/mailbox/MailExtension.java diff --git a/src/main/java/com/biutag/supervision/job/MailBoxCaptureJob.java b/src/main/java/com/biutag/supervision/job/MailBoxCaptureJob.java index 3397d21..a9127a5 100644 --- a/src/main/java/com/biutag/supervision/job/MailBoxCaptureJob.java +++ b/src/main/java/com/biutag/supervision/job/MailBoxCaptureJob.java @@ -40,10 +40,19 @@ public class MailBoxCaptureJob { * 阶段2:同步涉及人和核查附件 * 每天凌晨3点执行 */ - @Scheduled(cron = "0 0 3 * * ?") + @Scheduled(cron = "0 0 4 * * ?") public void syncBlameAndFilesForCompletedMails() { LocalDateTime start = LocalDate.now().minusDays(1).atStartOfDay(); LocalDateTime end = LocalDate.now().atStartOfDay(); mailBoxCaptureService.syncBlameAndFiles(start, end); } + + /** + * 阶段3:同步延期信息(初核工作开展情况、初核附件) + * 每天凌晨4点执行 + */ + @Scheduled(cron = "0 0 3 * * ?") + public void syncExtension() { + mailBoxCaptureService.syncExtension(); + } } diff --git a/src/main/java/com/biutag/supervision/mapper/MailExtensionMapper.java b/src/main/java/com/biutag/supervision/mapper/MailExtensionMapper.java new file mode 100644 index 0000000..e717b40 --- /dev/null +++ b/src/main/java/com/biutag/supervision/mapper/MailExtensionMapper.java @@ -0,0 +1,16 @@ +package com.biutag.supervision.mapper; + +import com.baomidou.dynamic.datasource.annotation.DS; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.biutag.supervision.pojo.entity.mailbox.MailExtension; + +/** + * @ClassName MailExtensionMapper + * @Description 局长信箱延期表Mapper + * @Author auto-generate + * @Date 2026/4/29 + */ +@DS("mailbox") +public interface MailExtensionMapper extends BaseMapper { + +} diff --git a/src/main/java/com/biutag/supervision/pojo/entity/mailbox/Mail.java b/src/main/java/com/biutag/supervision/pojo/entity/mailbox/Mail.java index a4115f3..af65add 100644 --- a/src/main/java/com/biutag/supervision/pojo/entity/mailbox/Mail.java +++ b/src/main/java/com/biutag/supervision/pojo/entity/mailbox/Mail.java @@ -405,4 +405,89 @@ public class Mail { */ private LocalDateTime secondDistributeTime; + /** + * 数据来源 import - 导入 + */ + private String dataType; + + /** + * 下发督查人员 + */ + private String dispatchedInspectors; + + /** + * 下发督查人员警号 + */ + private Integer dispatchedInspectorEmpNo; + + /** + * 是否取得联系 + */ + private String invalidationContactFlag; + + /** + * 无效判定佐证材料 + */ + private String invalidationAttachments; + + /** + * 是否重复来信 + */ + private Boolean repeat; + + /** + * 所队专班签收时间 + */ + private LocalDateTime threeSignTime; + + /** + * 提交办理时间 + */ + private LocalDateTime submitCompletionTime; + + /** + * 警种类型 + */ + private String policeType; + + /** + * 案件事件 + */ + private String caseIncident; + + /** + * 案件事件名称1 + */ + private String caseIncidentName1; + + /** + * 案件事件名称2 + */ + private String caseIncidentName2; + + /** + * 案件事件名称 + */ + private String caseIncidentName; + + /** + * 诉求 + */ + private String claim; + + /** + * 诉求名称 + */ + private String claimName; + + /** + * 诉求名称1 + */ + private String claimName1; + + /** + * 诉求名称2 + */ + private String claimName2; + } diff --git a/src/main/java/com/biutag/supervision/pojo/entity/mailbox/MailExtension.java b/src/main/java/com/biutag/supervision/pojo/entity/mailbox/MailExtension.java new file mode 100644 index 0000000..192c388 --- /dev/null +++ b/src/main/java/com/biutag/supervision/pojo/entity/mailbox/MailExtension.java @@ -0,0 +1,41 @@ +package com.biutag.supervision.pojo.entity.mailbox; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalDateTime; + +/** + * @ClassName MailExtension + * @Description 局长信箱延期表 + * @Author auto-generate + * @Date 2026/4/29 + */ +@Getter +@Setter +@TableName("mail_extension") +@Schema(description = "局长信箱延期表") +public class MailExtension { + + @Schema(description = "主键ID") + @TableId + private String id; + + @Schema(description = "信件ID") + private String mailId; + + @Schema(description = "延期天数") + private Integer days; + + @Schema(description = "延期理由") + private String extensionReason; + + @Schema(description = "创建时间") + private LocalDateTime createTime; + + @Schema(description = "初核材料(附件)") + private String initialVerifyAttachments; +} diff --git a/src/main/java/com/biutag/supervision/service/MailBoxCaptureService.java b/src/main/java/com/biutag/supervision/service/MailBoxCaptureService.java index c5dd30a..b10d780 100644 --- a/src/main/java/com/biutag/supervision/service/MailBoxCaptureService.java +++ b/src/main/java/com/biutag/supervision/service/MailBoxCaptureService.java @@ -8,13 +8,17 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.biutag.supervision.constants.enums.AccountabilityTargetEnum; import com.biutag.supervision.constants.enums.BusinessTypeEnum; import com.biutag.supervision.constants.enums.ProblemSourcesEnum; +import com.biutag.supervision.mapper.ComplaintCollectionMapper; import com.biutag.supervision.mapper.MailBlameMapper; +import com.biutag.supervision.mapper.MailExtensionMapper; import com.biutag.supervision.pojo.dto.MailBoxSyncDto; import com.biutag.supervision.pojo.dto.NegativeDataOnlyDto; import com.biutag.supervision.pojo.dto.mail.MailAttachmentDTO; import com.biutag.supervision.pojo.entity.*; import com.biutag.supervision.pojo.entity.mailbox.Mail; import com.biutag.supervision.pojo.entity.mailbox.MailBlame; +import com.biutag.supervision.pojo.entity.mailbox.MailExtension; +import com.biutag.supervision.pojo.enums.complaintCollection.ComplaintCollectionInitialEnum; import com.biutag.supervision.pojo.enums.complaintCollection.ComplaintCollectionSourceTableEnum; import com.biutag.supervision.pojo.enums.negative.NegativeSourceTypeEnum; import com.biutag.supervision.pojo.param.ComplaintCollection.ComplaintCollectionQueryParam; @@ -26,12 +30,16 @@ import com.biutag.supervision.repository.complaintCollection.ComplaintCollection import com.biutag.supervision.repository.mail.MailResourceService; import com.biutag.supervision.repository.supExternalDepart.SupExternalDepartResourceService; import com.biutag.supervision.repository.supdepart.SupDepartResourceService; +import com.biutag.supervision.service.complaintCollection.ComplaintCollectionService; +import com.biutag.supervision.util.TimeUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.support.TransactionTemplate; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -61,11 +69,16 @@ public class MailBoxCaptureService { private final SupExternalDepartResourceService supExternalDepartResourceService; private final ComplaintCollectionResourceService complaintCollectionResourceService; private final MailBlameMapper mailBlameMapper; + private final MailExtensionMapper mailExtensionMapper; private final SupPoliceService supPoliceService; private final SupDictHandleResultMapingService dictHandleResultMapingService; private final SupDictProblemTypeMapingService dictProblemTypeMapingService; private final SupDictProblemTypeService problemTypeService; private final TransactionTemplate transactionTemplate; + private final ComplaintCollectionMapper complaintCollectionMapper; + private final ComplaintCollectionService complaintCollectionService; + private static final DateTimeFormatter INITIAL_REVIEW_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + private static final int CHECK_LIMIT_DAYS = 4; // ==================== 阶段1:抓取来信 ==================== @@ -720,4 +733,190 @@ public class MailBoxCaptureService { } return ""; } + + // ==================== 延期同步(初核信息) ==================== + + /** + * 同步延期信息(初核工作开展情况、初核附件) + * 延期数据来源于 mailbox.mail_extension 表 + * - initWorkDes: 初核工作开展情况 <- extensionReason + * - initFile: 初核附件 <- initialVerifyAttachments + */ + public void syncExtension() { + log.info("【延期同步】开始执行延期信息同步任务"); + long startTimeMillis = System.currentTimeMillis(); + + try { + // 1. 查询所有局长信箱来源没有初核的记录 + List mailBoxList = queryAllMailboxRecords(); + if (CollectionUtil.isEmpty(mailBoxList)) { + log.info("【延期同步】无局长信箱记录"); + return; + } + log.info("【延期同步】查询到局长信箱数量:{}", mailBoxList.size()); + + // 2. 遍历处理 + int successCount = 0; + int skipCount = 0; + int failCount = 0; + + for (ComplaintCollection cc : mailBoxList) { + try { + String originId = cc.getOriginId(); + // 查询延期信息(可扩展:后续可能来自多个来源) + MailExtension extension = fetchExtensionInfo(originId); + if (extension == null) { + // 无延期记录(直接办结),只计算初核状态 + log.debug("【延期同步】无延期数据,直接计算初核状态:originId=" + originId); + syncInitialStatusForDirectCompletion(cc.getOriginId(), cc.getId()); + skipCount++; + continue; + } + + // 找到信件 + Mail mail = getMailByOriginId(originId); + ComplaintCollection complaintCollection = getComplaintCollectionByOriginId(originId); + // 初核计算 + syncInitialStatusWithExtension(mail, complaintCollection, extension); + successCount++; + } catch (Exception e) { + failCount++; + log.error("【延期同步】处理失败: ccId={}, error={}", cc.getId(), e.getMessage(), e); + } + } + + long cost = System.currentTimeMillis() - startTimeMillis; + log.info("【延期同步】完成,总数:{},成功:{},跳过:{},失败:{},耗时:{}ms", + mailBoxList.size(), successCount, skipCount, failCount, cost); + } catch (Exception e) { + log.error("【延期同步】任务执行过程中发生严重异常", e); + throw e; + } + } + + /** + * 查询所有局长信箱来源并初核情况是空的记录 + */ + private List queryAllMailboxRecords() { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.isNotNull(ComplaintCollection::getGwf3); + queryWrapper.eq(ComplaintCollection::getProblemSourcesCode, ComplaintCollectionSourceTableEnum.MAYOR_MAILBOX.getCode()); + return complaintCollectionMapper.selectList(queryWrapper); + } + + /** + * 根据 originId 获取 Mail + * + * @param originId 原始信件ID + * @return Mail 实体 + */ + private Mail getMailByOriginId(String originId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(Mail::getId, originId); + Mail mail = mailService.getOne(queryWrapper); + if (mail == null) { + log.warn("【延期同步】未找到 Mail:originId={}", originId); + } + return mail; + } + + /** + * 根据 originId 获取 ComplaintCollection + * + * @param originId 原始信件ID + * @return ComplaintCollection 实体 + */ + private ComplaintCollection getComplaintCollectionByOriginId(String originId) { + ComplaintCollectionQueryParam queryParam = new ComplaintCollectionQueryParam(); + queryParam.setOriginId(originId); + List list = complaintCollectionResourceService.query(queryParam); + if (CollectionUtil.isEmpty(list)) { + throw new IllegalArgumentException(String.format("未找到对应投诉举报数据,编号%s", originId)); + } + return list.get(0); + } + + /** + * 有延期记录时,同步初核状态 + * + * @param mail 邮件实体 + * @param cc 归集记录 + * @param extension 延期信息 + */ + private void syncInitialStatusWithExtension(Mail mail, ComplaintCollection cc, MailExtension extension) { + long maxSeconds = CHECK_LIMIT_DAYS * TimeUtil.SECONDS_OF_A_DAY; + long remainingAtInitial = TimeUtil.getRemainingDuration(mail.getMailTime(), extension.getCreateTime(), maxSeconds); + String initialReviewStatus = (remainingAtInitial < 0) ? + ComplaintCollectionInitialEnum.TIMEOUT_UPLOAD.getCode() : ComplaintCollectionInitialEnum.UPLOADED.getCode(); + + ComplaintCollectionUpdateParam updateParam = new ComplaintCollectionUpdateParam(); + updateParam.setId(cc.getId()); + updateParam.setGwf2(String.valueOf(extension.getCreateTime())); + updateParam.setGwf3(initialReviewStatus); + updateParam.setInitWorkDes(extension.getExtensionReason()); + updateParam.setInitFile(extension.getInitialVerifyAttachments()); + complaintCollectionResourceService.updateSelectiveById(updateParam); + } + + /** + * 获取延期信息(扩展点:后续可支持多个来源) + * 拿最早的那次记录 + * @param originId 原始信件ID + * @return 延期信息,未找到返回 null + */ + private MailExtension fetchExtensionInfo(String originId) { + // ========== 扩展点:后续可在此添加其他初核信息来源 ========== + // 目前仅从 mail_extension 表获取延期信息,取创建时间最早的那条 + List extensions = mailExtensionMapper.selectList( + new LambdaQueryWrapper() + .eq(MailExtension::getMailId, originId) + .orderByAsc(MailExtension::getCreateTime) + .last("LIMIT 1") + ); + return CollectionUtil.isEmpty(extensions) ? null : extensions.get(0); + } + + /** + * 无延期记录时(直接办结),计算初核状态 + * - 初核时间(gwf2)= submit_completion_time(提交办理时间) + * - 若 submit_completion_time 为空,则跳过(说明未办结也未申请延期) + * + * @param originId 原始信件ID + * @param ccId 归集记录ID + */ + private void syncInitialStatusForDirectCompletion(String originId, String ccId) { + // 1. 查询 Mail + Mail mail = getMailByOriginId(originId); + if (mail == null) { + return; + } + + // 2. 检查是否有 submit_completion_time + LocalDateTime submitCompletionTime = mail.getSubmitCompletionTime(); + if (submitCompletionTime == null) { + // 未办结也未申请延期,跳过本次计算 + log.debug("【延期同步】无延期且未提交办理时间,跳过:originId={}", originId); + return; + } + + // 3. 用 submit_completion_time 计算初核状态 + LocalDateTime mailTime = mail.getMailTime(); + long maxSeconds = CHECK_LIMIT_DAYS * TimeUtil.SECONDS_OF_A_DAY; + long remainingAtInitial = TimeUtil.getRemainingDuration(mailTime, submitCompletionTime, maxSeconds); + String initialReviewStatus = (remainingAtInitial < 0) ? + ComplaintCollectionInitialEnum.TIMEOUT_UPLOAD.getCode() : + ComplaintCollectionInitialEnum.UPLOADED.getCode(); + + // 4. 更新 + ComplaintCollectionUpdateParam updateParam = new ComplaintCollectionUpdateParam(); + updateParam.setId(ccId); + updateParam.setGwf2(String.valueOf(submitCompletionTime)); + updateParam.setGwf3(initialReviewStatus); + updateParam.setInitWorkDes("直接办结"); + complaintCollectionResourceService.updateSelectiveById(updateParam); + + log.debug("【延期同步】无延期记录,初核状态计算完成:originId={}, status={}", + originId, initialReviewStatus); + } + }