|
|
|
@ -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.AccountabilityTargetEnum; |
|
|
|
import com.biutag.supervision.constants.enums.BusinessTypeEnum; |
|
|
|
import com.biutag.supervision.constants.enums.BusinessTypeEnum; |
|
|
|
import com.biutag.supervision.constants.enums.ProblemSourcesEnum; |
|
|
|
import com.biutag.supervision.constants.enums.ProblemSourcesEnum; |
|
|
|
|
|
|
|
import com.biutag.supervision.mapper.ComplaintCollectionMapper; |
|
|
|
import com.biutag.supervision.mapper.MailBlameMapper; |
|
|
|
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.MailBoxSyncDto; |
|
|
|
import com.biutag.supervision.pojo.dto.NegativeDataOnlyDto; |
|
|
|
import com.biutag.supervision.pojo.dto.NegativeDataOnlyDto; |
|
|
|
import com.biutag.supervision.pojo.dto.mail.MailAttachmentDTO; |
|
|
|
import com.biutag.supervision.pojo.dto.mail.MailAttachmentDTO; |
|
|
|
import com.biutag.supervision.pojo.entity.*; |
|
|
|
import com.biutag.supervision.pojo.entity.*; |
|
|
|
import com.biutag.supervision.pojo.entity.mailbox.Mail; |
|
|
|
import com.biutag.supervision.pojo.entity.mailbox.Mail; |
|
|
|
import com.biutag.supervision.pojo.entity.mailbox.MailBlame; |
|
|
|
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.complaintCollection.ComplaintCollectionSourceTableEnum; |
|
|
|
import com.biutag.supervision.pojo.enums.negative.NegativeSourceTypeEnum; |
|
|
|
import com.biutag.supervision.pojo.enums.negative.NegativeSourceTypeEnum; |
|
|
|
import com.biutag.supervision.pojo.param.ComplaintCollection.ComplaintCollectionQueryParam; |
|
|
|
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.mail.MailResourceService; |
|
|
|
import com.biutag.supervision.repository.supExternalDepart.SupExternalDepartResourceService; |
|
|
|
import com.biutag.supervision.repository.supExternalDepart.SupExternalDepartResourceService; |
|
|
|
import com.biutag.supervision.repository.supdepart.SupDepartResourceService; |
|
|
|
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.RequiredArgsConstructor; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
import org.springframework.transaction.support.TransactionTemplate; |
|
|
|
import org.springframework.transaction.support.TransactionTemplate; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.time.LocalDate; |
|
|
|
import java.time.LocalDateTime; |
|
|
|
import java.time.LocalDateTime; |
|
|
|
|
|
|
|
import java.time.format.DateTimeFormatter; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.Collections; |
|
|
|
import java.util.Collections; |
|
|
|
import java.util.List; |
|
|
|
import java.util.List; |
|
|
|
@ -61,11 +69,16 @@ public class MailBoxCaptureService { |
|
|
|
private final SupExternalDepartResourceService supExternalDepartResourceService; |
|
|
|
private final SupExternalDepartResourceService supExternalDepartResourceService; |
|
|
|
private final ComplaintCollectionResourceService complaintCollectionResourceService; |
|
|
|
private final ComplaintCollectionResourceService complaintCollectionResourceService; |
|
|
|
private final MailBlameMapper mailBlameMapper; |
|
|
|
private final MailBlameMapper mailBlameMapper; |
|
|
|
|
|
|
|
private final MailExtensionMapper mailExtensionMapper; |
|
|
|
private final SupPoliceService supPoliceService; |
|
|
|
private final SupPoliceService supPoliceService; |
|
|
|
private final SupDictHandleResultMapingService dictHandleResultMapingService; |
|
|
|
private final SupDictHandleResultMapingService dictHandleResultMapingService; |
|
|
|
private final SupDictProblemTypeMapingService dictProblemTypeMapingService; |
|
|
|
private final SupDictProblemTypeMapingService dictProblemTypeMapingService; |
|
|
|
private final SupDictProblemTypeService problemTypeService; |
|
|
|
private final SupDictProblemTypeService problemTypeService; |
|
|
|
private final TransactionTemplate transactionTemplate; |
|
|
|
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:抓取来信 ====================
|
|
|
|
// ==================== 阶段1:抓取来信 ====================
|
|
|
|
|
|
|
|
|
|
|
|
@ -720,4 +733,190 @@ public class MailBoxCaptureService { |
|
|
|
} |
|
|
|
} |
|
|
|
return ""; |
|
|
|
return ""; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ==================== 延期同步(初核信息) ====================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* 同步延期信息(初核工作开展情况、初核附件) |
|
|
|
|
|
|
|
* 延期数据来源于 mailbox.mail_extension 表 |
|
|
|
|
|
|
|
* - initWorkDes: 初核工作开展情况 <- extensionReason |
|
|
|
|
|
|
|
* - initFile: 初核附件 <- initialVerifyAttachments |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public void syncExtension() { |
|
|
|
|
|
|
|
log.info("【延期同步】开始执行延期信息同步任务"); |
|
|
|
|
|
|
|
long startTimeMillis = System.currentTimeMillis(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
// 1. 查询所有局长信箱来源没有初核的记录
|
|
|
|
|
|
|
|
List<ComplaintCollection> 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<ComplaintCollection> queryAllMailboxRecords() { |
|
|
|
|
|
|
|
LambdaQueryWrapper<ComplaintCollection> 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<Mail> 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<ComplaintCollection> 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<MailExtension> extensions = mailExtensionMapper.selectList( |
|
|
|
|
|
|
|
new LambdaQueryWrapper<MailExtension>() |
|
|
|
|
|
|
|
.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); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|