@ -114,7 +114,16 @@ public class MailBoxCaptureService {
log . info ( "【局长信箱抓取新信件】查询到投诉举报信件信件数量:{}" , mailList . size ( ) ) ;
Map < String , String > involveProblemMapping = loadMayorMailboxInvolveProblemMapping ( ) ;
List < MailSource > sourceMergedMails = loadSourceMergedMails ( mailList ) ;
Set < String > mergedMailboxOriginIds = loadMergedMailboxOriginIds ( ) ;
List < MailSource > 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 < MailSource > loadSourceMergedMails ( List < Mail > mailList ) {
Set < String > mailIds = mailList . stream ( )
. map ( Mail : : getId )
. filter ( StrUtil : : isNotBlank )
. collect ( Collectors . toSet ( ) ) ;
if ( CollectionUtil . isEmpty ( mailIds ) ) {
return Collections . emptyList ( ) ;
}
Map < String , MailSource > mergedSourceById = new HashMap < > ( ) ;
MailSourceQueryParam childParam = new MailSourceQueryParam ( ) ;
childParam . setIds ( mailIds ) ;
childParam . setState ( "merge" ) ;
mailSourceResourceService . query ( childParam ) . forEach ( item - > mergedSourceById . put ( item . getId ( ) , item ) ) ;
List < MailSource > result = new ArrayList < > ( mergedSourceById . values ( ) ) ;
log . info ( "【局长信箱抓取新信件】查询到源端合并子件数量:{}" , result . size ( ) ) ;
return result ;
}
/ * *
* 将源端合并子件写入对应主件的 merge_history 。
* /
private void syncMergedMailsToMainHistory ( List < MailSource > mergedSources ) {
if ( CollectionUtil . isEmpty ( mergedSources ) ) {
return ;
}
Map < String , List < MailSource > > sourcesByMainId = mergedSources . stream ( )
. filter ( item - > StrUtil . isNotBlank ( item . getMailId ( ) ) )
. collect ( Collectors . groupingBy ( MailSource : : getMailId ) ) ;
for ( Map . Entry < String , List < MailSource > > 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 < MailSource > mergedSources ) {
ComplaintCollectionQueryParam queryParam = new ComplaintCollectionQueryParam ( ) ;
queryParam . setOriginId ( mainMailId ) ;
queryParam . setSourceTable ( ComplaintCollectionSourceTableEnum . MAYOR_MAILBOX . getCode ( ) ) ;
List < ComplaintCollection > 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 < String > 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 < String , Object > buildMergedMailHistory ( MailSource source ) {
Map < String , Object > 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 < Map < String , String > > buildMergeHistoryFiles ( String attachmentsJson ) {
return buildThingFiles ( attachmentsJson ) . stream ( )
. map ( file - > {
Map < String , String > 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 < ComplaintCollection > 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 < MailSource > mailSources = mailSourceResourceService . query ( sourceParam ) ;
if ( CollectionUtil . isNotEmpty ( mailSources ) ) {
sourceMailId = mailSources . get ( 0 ) . getMailId ( ) ;
}
MailQueryParam mailParam = new MailQueryParam ( ) ;
mailParam . setId ( sourceMailId ) ;
mailParam . setMailState ( "completion" ) ;
List < Mail > 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 < MailBlame > mailBlames = mailBlameMapper . selectList (
new LambdaQueryWrapper < MailBlame > ( ) . 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 < String > 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 ) ;
}
/ * *
* 同步涉及人
* /