Compare commits

..

50 Commits

Author SHA1 Message Date
buaixuexideshitongxue 3ce8e1c59f fix:删除原有投诉举报自动作业 7 hours ago
buaixuexideshitongxue 487282c25d fix:加上查重 11 hours ago
buaixuexideshitongxue 06a16970f8 fix:添加初核信息 6 days ago
buaixuexideshitongxue 5501be25ac feat:投诉举报迁移接口 6 days ago
wxc 36dd09b58e fix: 针对直接办结的情况再调用一次initialReviewRequest 6 days ago
buaixuexideshitongxue 2950af746c fix:删除多余代码 7 days ago
buaixuexideshitongxue 0fc7e48b1e Merge branch 'master' into feature/tsjb-1.0 7 days ago
buaixuexideshitongxue 36f42cba03 feat:初核自动作业初步完成,待测试 1 week ago
buaixuexideshitongxue 1ceb785c53 feat:除开初核情况、其余信息同步 1 week ago
buaixuexideshitongxue d8b0a0ad4d feat:加上初核附件 1 week ago
buaixuexideshitongxue 76192b564b feat:加上同步标记 1 week ago
buaixuexideshitongxue 907cbd6f91 feat:投诉举报变为附表,主表位negative 1 week ago
buaixuexideshitongxue e010e5e11c Merge branch 'master' into feature/tsjb-1.0 1 week ago
wxc 7b1bb7537b fix: 完善涉访涉诉流程初核办理 3 weeks ago
buaixuexideshitongxue 2cd5d75736 fix:记录合并代码后,废弃的代码逻辑 3 weeks ago
buaixuexideshitongxue a942dca81e Merge branch 'master' into feature/tsjb-1.0 3 weeks ago
buaixuexideshitongxue 41749b4faf fix:只下发 下发情况的投诉举报 3 weeks ago
buaixuexideshitongxue 40d485676f fix:业务类别名称报错 3 weeks ago
buaixuexideshitongxue d14728ace8 feat:投诉举报历史数据迁移 3 weeks ago
buaixuexideshitongxue 25d312b21a feat:投诉举报历史数据迁移 3 weeks ago
buaixuexideshitongxue c21355020f feat:投诉举报历史数据迁移 3 weeks ago
buaixuexideshitongxue 564c3031f1 feat:投诉举报历史数据迁移 3 weeks ago
buaixuexideshitongxue d219cb12e9 fix--添加问题编号修改 3 weeks ago
buaixuexideshitongxue 2568bc87ad fix--初核保存添加校验 3 weeks ago
wxc f3682d6eff feat: 涉访涉诉流程初核办理 4 weeks ago
buaixuexideshitongxue 8cd6526e5b Merge branch 'master' into feature/tsjb-1.0 4 weeks ago
buaixuexideshitongxue b2882ca308 fix--删除投诉举报不必要的代码 4 weeks ago
buaixuexideshitongxue b652cb8f98 fix:不鉴权 4 weeks ago
wxc 24c762de57 feat: 涉访涉诉流程初核办理 4 weeks ago
buaixuexideshitongxue 4c81d14ec5 fix:添加枚举注释 4 weeks ago
buaixuexideshitongxue 96cd62226c feat:投诉举报修改和删除接入综合查询 4 weeks ago
buaixuexideshitongxue c620ad2194 feat:正常办理流程中同步修改投诉举报涉及单位 4 weeks ago
buaixuexideshitongxue 4072773d70 feat:修改投诉举报同时修改问题信息 4 weeks ago
buaixuexideshitongxue 263cfcf356 fix:初核情况获取失败 4 weeks ago
buaixuexideshitongxue 803bc4ed07 fix:修改业务类别 4 weeks ago
buaixuexideshitongxue db69b41375 fix:修改查询接口 4 weeks ago
buaixuexideshitongxue 9fd3a28803 fix:删除投诉举报确定不要的代码 4 weeks ago
buaixuexideshitongxue dda88d95b0 fix:删除投诉举报确定不要的代码 4 weeks ago
buaixuexideshitongxue 78f9ceae97 feat:立即处理接口返回初核情况 4 weeks ago
buaixuexideshitongxue 54a24d9aee feat:立即处理接口返回初核情况 4 weeks ago
buaixuexideshitongxue 29660583e5 Merge branch 'master' into feature/tsjb-1.0 4 weeks ago
wxc 306dfc38f6 com.biutag.supervision.controller.work.NegativeController#update 4 weeks ago
wxc d420f9d8a3 com.biutag.supervision.controller.work.NegativeController#update 4 weeks ago
wxc fca5555a8f com.biutag.supervision.controller.work.NegativeController#update 4 weeks ago
buaixuexideshitongxue e123ffa0b4 fix:添加涉嫌问题 4 weeks ago
buaixuexideshitongxue 5adff2336d feat:删除的时候删除问题 1 month ago
buaixuexideshitongxue d900d6f0d8 fix:投诉举报查询修改,添加的时候回填问题id 1 month ago
buaixuexideshitongxue dda095eba3 feat:投诉举报数据接入问题流程并加上来源标识 1 month ago
buaixuexideshitongxue 6b6295b328 feat:投诉举报接入问题下发流程后初核接口实现 1 month ago
buaixuexideshitongxue ae379f5289 feat:投诉举报数据录入时生成问题 1 month ago
  1. 4
      src/main/java/com/biutag/supervision/constants/AppConstants.java
  2. 2
      src/main/java/com/biutag/supervision/constants/enums/FlowActionEnum.java
  3. 78
      src/main/java/com/biutag/supervision/controller/data/ComplaintCollectionController.java
  4. 49
      src/main/java/com/biutag/supervision/controller/work/NegativeController.java
  5. 5
      src/main/java/com/biutag/supervision/flow/FlowService.java
  6. 58
      src/main/java/com/biutag/supervision/flow/action/ApplyCompletionAction.java
  7. 21
      src/main/java/com/biutag/supervision/flow/action/ConfirmationCompletionAction.java
  8. 235
      src/main/java/com/biutag/supervision/job/Job.java
  9. 58
      src/main/java/com/biutag/supervision/job/MailBoxCaptureJob.java
  10. 6
      src/main/java/com/biutag/supervision/mapper/ComplaintCollectionMapper.java
  11. 16
      src/main/java/com/biutag/supervision/mapper/MailExtensionMapper.java
  12. 6
      src/main/java/com/biutag/supervision/pojo/domain/NegativeDetail.java
  13. 30
      src/main/java/com/biutag/supervision/pojo/domain/NegativeVo.java
  14. 29
      src/main/java/com/biutag/supervision/pojo/dto/MailBoxSyncDto.java
  15. 361
      src/main/java/com/biutag/supervision/pojo/dto/NegativeDataOnlyDto.java
  16. 4
      src/main/java/com/biutag/supervision/pojo/dto/NegativeDto.java
  17. 34
      src/main/java/com/biutag/supervision/pojo/dto/complaintCollection/ComplaintCollectionPageDTO.java
  18. 3
      src/main/java/com/biutag/supervision/pojo/dto/complaintCollection/ComplaintCollectionRepeatDTO.java
  19. 81
      src/main/java/com/biutag/supervision/pojo/dto/complaintCollection/ExportComplaintCollectionBlameVo.java
  20. 93
      src/main/java/com/biutag/supervision/pojo/dto/complaintCollection/ExportComplaintCollectionExcelVo.java
  21. 6
      src/main/java/com/biutag/supervision/pojo/dto/flow/VerifyData.java
  22. 26
      src/main/java/com/biutag/supervision/pojo/entity/ComplaintCollection.java
  23. 85
      src/main/java/com/biutag/supervision/pojo/entity/mailbox/Mail.java
  24. 8
      src/main/java/com/biutag/supervision/pojo/entity/mailbox/MailBlame.java
  25. 41
      src/main/java/com/biutag/supervision/pojo/entity/mailbox/MailExtension.java
  26. 2
      src/main/java/com/biutag/supervision/pojo/enums/negative/NegativeSourceTypeEnum.java
  27. 12
      src/main/java/com/biutag/supervision/pojo/param/ComplaintCollection/ComplaintCollectionQueryParam.java
  28. 23
      src/main/java/com/biutag/supervision/pojo/param/ComplaintCollection/ComplaintCollectionUpdateParam.java
  29. 5
      src/main/java/com/biutag/supervision/pojo/param/MailQueryParam.java
  30. 32
      src/main/java/com/biutag/supervision/pojo/request/complaintCollection/ComplaintCollectionAddRequest.java
  31. 7
      src/main/java/com/biutag/supervision/pojo/request/complaintCollection/ComplaintCollectionDelRequest.java
  32. 32
      src/main/java/com/biutag/supervision/pojo/request/complaintCollection/ComplaintCollectionDetailRequest.java
  33. 38
      src/main/java/com/biutag/supervision/pojo/request/complaintCollection/ComplaintCollectionInitialReviewRequest.java
  34. 31
      src/main/java/com/biutag/supervision/pojo/request/complaintCollection/ComplaintCollectionInitialReviewSaveRequest.java
  35. 3
      src/main/java/com/biutag/supervision/pojo/request/complaintCollection/ComplaintCollectionPageRequest.java
  36. 7
      src/main/java/com/biutag/supervision/pojo/request/complaintCollection/ComplaintCollectionUpdateRequest.java
  37. 7
      src/main/java/com/biutag/supervision/pojo/transfer/ComplaintCollectionTransfer.java
  38. 13
      src/main/java/com/biutag/supervision/pojo/vo/NegativeQueryVo.java
  39. 85
      src/main/java/com/biutag/supervision/pojo/vo/complaintCollection/ComplaintCollectionDetailVo.java
  40. 79
      src/main/java/com/biutag/supervision/repository/complaintCollection/ComplaintCollectionResourceService.java
  41. 1
      src/main/java/com/biutag/supervision/repository/mail/MailResourceService.java
  42. 927
      src/main/java/com/biutag/supervision/service/MailBoxCaptureService.java
  43. 201
      src/main/java/com/biutag/supervision/service/NegativeService.java
  44. 57
      src/main/java/com/biutag/supervision/service/complaintCollection/ComplaintCollectionService.java
  45. 1635
      src/main/java/com/biutag/supervision/service/complaintCollection/ComplaintCollectionServiceImpl.java
  46. 104
      src/main/java/com/biutag/supervision/util/CheckUtil.java
  47. 8
      src/main/resources/application-prod.yml
  48. 179
      src/main/resources/mapper/ComplaintCollectionMapper.xml

4
src/main/java/com/biutag/supervision/constants/AppConstants.java

@ -34,4 +34,8 @@ public class AppConstants {
public static final String JWPY_DEPART_NAME= "现场督察大队";
// 已办结
public static final String COMPLETED = "1";
}

2
src/main/java/com/biutag/supervision/constants/enums/FlowActionEnum.java

@ -7,6 +7,8 @@ import lombok.Getter;
public enum FlowActionEnum {
FIRST_DISTRIBUTE("first_distribute", "已下发"),
SAVE("save", "保存"),
SECOND_APPROVE("second_approve", "已审批"),
FIRST_APPROVE("first_approve", "已审批");

78
src/main/java/com/biutag/supervision/controller/data/ComplaintCollectionController.java

@ -1,12 +1,12 @@
package com.biutag.supervision.controller.data;
import com.biutag.supervision.job.Job;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.biutag.supervision.pojo.Result;
import com.biutag.supervision.pojo.dto.complaintCollection.ComplaintCollectionPageDTO;
import com.biutag.supervision.pojo.request.complaintCollection.*;
import com.biutag.supervision.pojo.vo.complaintCollection.ComplaintCollectionHandlerDataVo;
import com.biutag.supervision.pojo.vo.complaintCollection.ComplaintCollectionDetailVo;
import com.biutag.supervision.pojo.vo.complaintCollection.ComplaintCollectionMailRepeattVo;
import com.biutag.supervision.pojo.vo.complaintCollection.ComplaintCollectionPageVo;
import com.biutag.supervision.pojo.vo.complaintCollection.ComplaintCollectionWatchDetailVO;
import com.biutag.supervision.service.MailBoxCaptureService;
import com.biutag.supervision.service.complaintCollection.ComplaintCollectionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@ -19,7 +19,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.List;
/**
* @ClassName ComplaintCollectionController
@ -36,7 +35,8 @@ public class ComplaintCollectionController {
private final ComplaintCollectionService complaintCollectionService;
private final Job job;
private final MailBoxCaptureService mailBoxCaptureService;
@Operation(description = "添加")
@PostMapping("/addComplaintCollection")
@ -56,30 +56,32 @@ public class ComplaintCollectionController {
return complaintCollectionService.updateComplaintCollection(request);
}
@Operation(description = "查询")
@PostMapping("/getComplaintCollectionPage")
public Result<ComplaintCollectionPageVo> getComplaintCollectionPage(@RequestBody ComplaintCollectionPageRequest request){
if ("我要信箱".equals(request.getOriginId())){
List<LocalDateTime> discoveryTimeList = request.getDiscoveryTimeList();
job.mailBoxCaptureToComplaintCollection(discoveryTimeList.get(0), discoveryTimeList.get(1));
@PostMapping("/getComplaintCollectionPageNew")
public Result<Page<ComplaintCollectionPageDTO>> getComplaintCollectionPageNew(@RequestBody ComplaintCollectionPageRequest request){
if ("我要迁移".equals(request.getPersonInfo())){
complaintCollectionService.moveNegativeTemp(request);
}
if ("我要更新".equals(request.getOriginId())){
job.updateMailBoxCaptureToComplaintCollection();
if ("局长信箱迁移".equals(request.getPersonInfo())){
complaintCollectionService.migrateMayorMailboxNegative(request);
}
if ("我要下发".equals(request.getPersonInfo())){
complaintCollectionService.addNegativeTemp(request);
}
if ("阶段1".equals(request.getPersonInfo())){
LocalDateTime start = request.getCreateTimeList().get(0);
LocalDateTime end = request.getCreateTimeList().get(1);
mailBoxCaptureService.captureMayorMailbox(start, end);
}
if ("阶段2".equals(request.getPersonInfo())){
LocalDateTime start = request.getCreateTimeList().get(0);
LocalDateTime end = request.getCreateTimeList().get(1);
mailBoxCaptureService.syncBlameAndFiles(start, end);
}
return complaintCollectionService.getComplaintCollectionPage(request);
}
@Operation(description = "办理")
@PostMapping("/addComplaintCollectionBlame")
public Result<Boolean> addComplaintCollectionBlame(@RequestBody ComplaintCollectionAndBlameAddRequest request){
return complaintCollectionService.addComplaintCollectionBlame(request);
}
@Operation(description = "查看详情")
@PostMapping("/watchDetail")
public Result<ComplaintCollectionWatchDetailVO> watchDetail(@RequestBody ComplaintCollectionWatchDetailRequest request){
return complaintCollectionService.watchDetail(request);
return Result.success(complaintCollectionService.getComplaintCollectionPageNew(request));
}
@ -89,11 +91,6 @@ public class ComplaintCollectionController {
return complaintCollectionService.maileRepeatt(request);
}
@Operation(description = "办理页面初始化数据回显")
@PostMapping("/handlerData")
public Result<ComplaintCollectionHandlerDataVo> handlerData(@RequestBody ComplaintCollectionHandlerDataRequest request){
return complaintCollectionService.handlerData(request);
}
@Operation(description = "导出数据")
@PostMapping("/exportData")
@ -101,16 +98,25 @@ public class ComplaintCollectionController {
complaintCollectionService.exportData(request, response);
}
@Operation(description = "办理页面临时保存")
@Operation(description = "办理页面保存:初核反馈")
@PostMapping("/saveInvolveJson")
public Result<Boolean> saveInvolveJson(@RequestBody ComplaintCollectionSaveInvolveJsonRequest request){
public Result<Boolean> saveInvolveJson(@RequestBody ComplaintCollectionInitialReviewSaveRequest request){
return complaintCollectionService.saveInvolveJson(request);
}
@Operation(description = "强制终结")
@PostMapping("/forceTermination")
public Result<Boolean> forceTermination(@RequestBody ComplaintCollectionForceTerminationRequest request){
return complaintCollectionService.forceTermination(request);
@Operation(description = "初核反馈")
@PostMapping("/initialReview")
public Result<Boolean> initialReview(@RequestBody ComplaintCollectionInitialReviewRequest request){
return complaintCollectionService.initialReview(request);
}
@Operation(description = "查询详情(用于修改弹窗回显)")
@PostMapping("/getComplaintCollectionDetail")
public Result<ComplaintCollectionDetailVo> getComplaintCollectionDetail(@RequestBody ComplaintCollectionDetailRequest request){
return complaintCollectionService.getComplaintCollectionDetail(request);
}
}

49
src/main/java/com/biutag/supervision/controller/work/NegativeController.java

@ -1,6 +1,5 @@
package com.biutag.supervision.controller.work;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@ -26,7 +25,6 @@ import com.biutag.supervision.pojo.request.negative.ReportGenerationRequest;
import com.biutag.supervision.pojo.vo.NegativeConfirmationCompletionVo;
import com.biutag.supervision.pojo.vo.NegativeQueryVo;
import com.biutag.supervision.service.*;
import com.biutag.supervision.util.JSON;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
@ -59,7 +57,6 @@ public class NegativeController {
private final NegativeScoreService negativeScoreService;
private final SupDepartService departService;
private final DataCaseVerifService dataCaseVerifService;
@ -108,51 +105,7 @@ public class NegativeController {
@PutMapping
public Result<Boolean> update(@Validated(EditGroup.class) @RequestBody NegativeDto negativeDto) {
if (StrUtil.isBlank(negativeDto.getId())) {
throw new RuntimeException("数据异常,请系统联系管理员【问题ID为空】");
}
LambdaUpdateWrapper<Negative> updateWrapper = new LambdaUpdateWrapper<>();
// 涉及单位
SupDepart depart = departService.getById(negativeDto.getInvolveDepartId());
if (DepartLevelEnum.SECOND.getValue().equals(depart.getLevel())) {
updateWrapper.set(Negative::getSecondInvolveDepartId, depart.getId())
.set(Negative::getThreeInvolveDepartId, null);
} else if (DepartLevelEnum.THREE.getValue().equals(depart.getLevel())) {
updateWrapper.set(Negative::getSecondInvolveDepartId, depart.getPid())
.set(Negative::getThreeInvolveDepartId, depart.getId());
} else {
throw new RuntimeException("涉及单位请选择二级或三级单位");
}
updateWrapper.eq(Negative::getId, negativeDto.getId())
.set(Negative::getProblemSources, negativeDto.getProblemSources())
.set(Negative::getProblemSourcesCode, negativeDto.getProblemSourcesCode())
.set(Negative::getBusinessTypeCode, negativeDto.getBusinessTypeCode())
.set(Negative::getCaseNumber, negativeDto.getCaseNumber())
.set(Negative::getInvolveProblem, JSON.toJSONString(negativeDto.getInvolveProblem()))
.set(Negative::getPoliceType, negativeDto.getPoliceType())
.set(Negative::getPoliceTypeName, negativeDto.getPoliceTypeName())
.set(Negative::getDiscoveryTime, negativeDto.getDiscoveryTime())
.set(Negative::getHappenTime, negativeDto.getHappenTime())
.set(Negative::getResponderName, negativeDto.getResponderName())
.set(Negative::getContactPhone, negativeDto.getContactPhone())
.set(Negative::getThingDesc, negativeDto.getThingDesc())
.set(Negative::getSpecialSupervision, negativeDto.getSpecialSupervision())
.set(Negative::getReportNumber, negativeDto.getReportNumber())
.set(StrUtil.isNotEmpty(negativeDto.getReportId()),Negative::getReportId,negativeDto.getReportId())
.set(Negative::getInvolveDepartId, negativeDto.getInvolveDepartId())
.set(Negative::getInvolveDepartName, depart.getShortName())
// 涉嫌问题
.set(Negative::getInvolveProblem, CollectionUtil.isNotEmpty(negativeDto.getInvolveProblem()) ? String.join(",", negativeDto.getInvolveProblem()) : null)
.set(Negative::getUpdUser, UserContextHolder.getCurrentUser().getNickName())
.set(Negative::getUpdTime, LocalDateTime.now());
if (CollectionUtil.isNotEmpty(negativeDto.getInvolveProblem())) {
updateWrapper.set(Negative::getInvolveProblem, String.join(",", negativeDto.getInvolveProblem()));
} else {
updateWrapper.set(Negative::getInvolveProblem, null);
}
negativeService.update(updateWrapper);
// 更新问题来源
negativeWorkService.update(new LambdaUpdateWrapper<NegativeWork>().set(NegativeWork::getProblemSourcesCode, negativeDto.getProblemSourcesCode()).eq(NegativeWork::getNegativeId, negativeDto.getId()));
negativeService.updateNegative(negativeDto);
return Result.success();
}

5
src/main/java/com/biutag/supervision/flow/FlowService.java

@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.biutag.supervision.common.UserContextHolder;
import com.biutag.supervision.constants.enums.FlowActionEnum;
import com.biutag.supervision.flow.action.Action;
import com.biutag.supervision.pojo.dto.ActionDto;
import com.biutag.supervision.pojo.entity.Negative;
@ -57,6 +58,10 @@ public class FlowService {
);
}
}
// 保存操作不保留操作流程历史
if (FlowActionEnum.SAVE.getKey().equals(actionDto.getActionKey())) {
return true;
}
NegativeWork work = workService.getById(actionDto.getWorkId());
NegativeHistory history = new NegativeHistory().setHistoryId(IdUtil.fastSimpleUUID())

58
src/main/java/com/biutag/supervision/flow/action/ApplyCompletionAction.java

@ -11,7 +11,15 @@ import com.biutag.supervision.constants.enums.*;
import com.biutag.supervision.pojo.dto.ActionDto;
import com.biutag.supervision.pojo.dto.flow.VerifyData;
import com.biutag.supervision.pojo.entity.*;
import com.biutag.supervision.pojo.enums.complaintCollection.ComplaintCollectionInitialEnum;
import com.biutag.supervision.pojo.enums.negative.NegativeSourceTypeEnum;
import com.biutag.supervision.pojo.param.ComplaintCollection.ComplaintCollectionQueryParam;
import com.biutag.supervision.pojo.param.ComplaintCollection.ComplaintCollectionUpdateParam;
import com.biutag.supervision.pojo.request.complaintCollection.ComplaintCollectionInitialReviewRequest;
import com.biutag.supervision.repository.complaintCollection.ComplaintCollectionResourceService;
import com.biutag.supervision.repository.supdepart.SupDepartResourceService;
import com.biutag.supervision.service.*;
import com.biutag.supervision.service.complaintCollection.ComplaintCollectionService;
import com.biutag.supervision.util.JSON;
import com.biutag.supervision.util.TimeUtil;
import jakarta.validation.Validator;
@ -46,6 +54,10 @@ public class ApplyCompletionAction implements Action {
private final Validator validator;
private final ComplaintCollectionResourceService complaintCollectionResourceService;
private final ComplaintCollectionService complaintCollectionService;
@Override
public void next(ActionDto actionDto) {
VerifyData verifyData = BeanUtil.toBean(actionDto.getData(), VerifyData.class);
@ -76,6 +88,9 @@ public class ApplyCompletionAction implements Action {
}
public void updateNegative(Negative negative, VerifyData verifyData) {
// 同步修改投诉举报涉及单位
updateComplaintCollectionInfo(negative, verifyData);
LocalDateTime now = LocalDateTime.now();
String checkStatus = null;
if (CheckStatusEnum.TRUE.getValue().equals(verifyData.getCheckStatusCode())) {
@ -291,4 +306,47 @@ public class ApplyCompletionAction implements Action {
workService.save(work);
}
private void updateComplaintCollectionInfo(Negative negative, VerifyData verifyData) {
ComplaintCollectionQueryParam complaintCollectionQueryParam = new ComplaintCollectionQueryParam();
complaintCollectionQueryParam.setOriginId(negative.getOriginId());
List<ComplaintCollection> complaintCollections = complaintCollectionResourceService.query(complaintCollectionQueryParam);
if (CollectionUtil.isEmpty(complaintCollections)) {
if (NegativeSourceTypeEnum.COMPLAINT_REPORT.getCode().equals(negative.getSourceType())) {
throw new IllegalArgumentException("请联系后台管理员,问题来自投诉举报,但没有对应关联!");
}
return;
}
if (CollectionUtil.size(complaintCollections) > 1) {
throw new IllegalArgumentException("关联多条投诉举报数据,请联系管理员处理");
}
ComplaintCollection complaintCollection = complaintCollections.get(0);
// 未初核
if (ComplaintCollectionInitialEnum.UN_UPLOADED.getCode().equals(complaintCollection.getGwf3())) {
ComplaintCollectionInitialReviewRequest request = new ComplaintCollectionInitialReviewRequest();
request.setComplaintId(complaintCollection.getId());
complaintCollectionService.initialReview(request);
}
ComplaintCollectionUpdateParam complaintCollectionUpdateParam = new ComplaintCollectionUpdateParam();
String involveDepartId = verifyData.getInvolveDepartId();
SupDepart byId = departService.getById(involveDepartId);
if (3==byId.getLevel()){
SupDepart pid = departService.getById(byId.getPid());
complaintCollectionUpdateParam.setSecondDepartId(pid.getId());
complaintCollectionUpdateParam.setSecondDepartName(pid.getShortName());
complaintCollectionUpdateParam.setThirdDepartId(byId.getId());
complaintCollectionUpdateParam.setThirdDepartName(byId.getShortName());
}else if (2==byId.getLevel()){
complaintCollectionUpdateParam.setSecondDepartId(byId.getId());
complaintCollectionUpdateParam.setSecondDepartName(byId.getShortName());
}
complaintCollectionUpdateParam.setId(complaintCollection.getId());
complaintCollectionUpdateParam.setCompletionStatus(verifyData.getCompletionStatus());
complaintCollectionUpdateParam.setPublicRecognition(verifyData.getPublicRecognition());
complaintCollectionResourceService.updateSelectiveById(complaintCollectionUpdateParam);
}
}

21
src/main/java/com/biutag/supervision/flow/action/ConfirmationCompletionAction.java

@ -5,15 +5,17 @@ import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.biutag.supervision.common.UserContextHolder;
import com.biutag.supervision.constants.AppConstants;
import com.biutag.supervision.constants.enums.*;
import com.biutag.supervision.mapper.ComplaintCollectionMapper;
import com.biutag.supervision.pojo.dto.ActionDto;
import com.biutag.supervision.pojo.dto.flow.ConfirmationCompletionData;
import com.biutag.supervision.pojo.entity.Negative;
import com.biutag.supervision.pojo.entity.NegativeApprove;
import com.biutag.supervision.pojo.entity.NegativeScorePolice;
import com.biutag.supervision.pojo.entity.NegativeWork;
import com.biutag.supervision.pojo.entity.*;
import com.biutag.supervision.pojo.model.UserAuth;
import com.biutag.supervision.service.*;
import com.biutag.supervision.service.NegativeApproveService;
import com.biutag.supervision.service.NegativeScorePoliceService;
import com.biutag.supervision.service.NegativeService;
import com.biutag.supervision.service.NegativeWorkService;
import com.biutag.supervision.util.TimeUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
@ -37,6 +39,8 @@ public class ConfirmationCompletionAction implements Action {
private final NegativeApproveService approveService;
private final ComplaintCollectionMapper complaintCollectionMapper;
@Override
public void next(ActionDto actionDto) {
UserAuth user = UserContextHolder.getCurrentUser();
@ -53,6 +57,8 @@ public class ConfirmationCompletionAction implements Action {
updateNegative(negativeId, completionData);
addNegativeScorePolice(negativeId, completionData);
// 更新涉访涉诉状态办理状态
updateComplaintCollectionStatus(negativeId);
}
@ -148,4 +154,9 @@ public class ConfirmationCompletionAction implements Action {
workService.update(doneUpdateWrapper);
}
// 更新为已办结
private void updateComplaintCollectionStatus(String negativeId) {
complaintCollectionMapper.update(new LambdaUpdateWrapper<ComplaintCollection>().eq(ComplaintCollection::getNegativeId, negativeId)
.set(ComplaintCollection::getStatus, AppConstants.COMPLETED));
}
}

235
src/main/java/com/biutag/supervision/job/Job.java

@ -492,239 +492,4 @@ public class Job {
log.info("值班数据录入完成");
}
// 局长信箱数据抓取到涉访涉诉
@Scheduled(cron = "0 0 1 * * ?")
public void mailBoxCaptureToComplaintCollection() {
LocalDateTime start = LocalDate.now().minusDays(1).atStartOfDay();
LocalDateTime end = LocalDate.now().atStartOfDay();
mailBoxCaptureToComplaintCollection(start, end);
}
@Scheduled(cron = "0 0 * * * ?")
public void updateMailBoxCaptureToComplaintCollection() {
log.info("【局长信箱回填】开始同步核查信息到ComplaintCollection...");
ComplaintCollectionQueryParam complaintCollectionQueryParam = new ComplaintCollectionQueryParam();
complaintCollectionQueryParam.setSourceTable("23");
complaintCollectionQueryParam.setStatus("0");
List<ComplaintCollection> collectionList = complaintCollectionResourceService.query(complaintCollectionQueryParam);
if (CollectionUtil.isEmpty(collectionList)) {
log.info("【局长信箱回填】无待同步数据");
return;
}
log.info("【局长信箱回填】获取到待处理 ComplaintCollection 条数:{}", CollectionUtil.size(collectionList));
// 所有局长信箱编号
Set<String> mailIds = collectionList.stream().map(ComplaintCollection::getOriginId).filter(StrUtil::isNotBlank).collect(Collectors.toSet());
if (CollectionUtil.isEmpty(mailIds)) {
log.warn("【局长信箱回填】ComplaintCollection 中无有效 originId");
return;
}
log.info("【局长信箱回填】提取到 originId 数量:{}", mailIds.size());
List<Mail> mailList = mailService.list(new LambdaQueryWrapper<Mail>().in(Mail::getId, mailIds));
if (CollectionUtil.isEmpty(mailList)) {
log.info("【局长信箱回填】Mail 表未查到任何数据");
return;
}
log.info("【局长信箱回填】查询到 Mail 记录条数:{}", mailList.size());
Map<String, Mail> mailMap = mailList.stream().collect(Collectors.toMap(Mail::getId, Function.identity()));
List<ComplaintCollection> toUpdate = new ArrayList<>();
Map<String, List<MailAttachmentDTO>> verifyAttachMap = new HashMap<>();
for (ComplaintCollection cc : collectionList) {
Mail mail = mailMap.get(cc.getOriginId());
if (mail == null) {
log.warn("【局长信箱回填】未找到 Mail,originId={},跳过。", cc.getOriginId());
continue;
}
// if ("属实".equals(mail.getVerifyIsTrue())) {
// cc.setCheckStatus("1");
// cc.setCheckStatusName("属实");
// } else if ("基本属实".equals(mail.getVerifyIsTrue())) {
// cc.setCheckStatus("2");
// cc.setCheckStatusName("部分属实");
// } else if ("不属实".equals(mail.getVerifyIsTrue())) {
// cc.setCheckStatus("5");
// cc.setCheckStatusName("不属实");
// }
if (StrUtil.equalsAny(mail.getSatisfactionStatus(),"非常满意","基本满意")){
cc.setPublicRecognition(ComplaintCollectionPublicApprovalEnum.APPROVED.getCode());
}
if ("不满意".equals(mail.getSatisfactionStatus())){
cc.setPublicRecognition(ComplaintCollectionPublicApprovalEnum.NOT_APPROVED.getCode());
}
cc.setCheckStatusDesc(mail.getCompletionComment());
cc.setProcessingStatus(mail.getMailState());
toUpdate.add(cc);
// 附件
List<MailAttachmentDTO> attachList = parseAttachments(mail.getVerifyAttachments());
if (CollectionUtil.isNotEmpty(attachList)) {
verifyAttachMap.put(cc.getOriginId(), attachList);
}
}
if (CollectionUtil.isEmpty(toUpdate)) {
log.info("【局长信箱回填】无可更新数据");
return;
}
MailBoxCaptureToComplaintCollectionSaveDTO dto = new MailBoxCaptureToComplaintCollectionSaveDTO();
dto.setComplaintCollectionList(toUpdate);
dto.setVerifyAttachMap(verifyAttachMap);
log.info("【局长信箱回填】准备提交更新,更新条数:{},含附件的 originId 数:{}", toUpdate.size(), verifyAttachMap.size());
complaintCollectionServiceJob.saveComplaintAndAttachments(dto);
log.info("【局长信箱回填】处理完成。");
}
public void mailBoxCaptureToComplaintCollection(LocalDateTime start, LocalDateTime end) {
log.info("【局长信箱抓取】时间范围 {} ~ {}", start, end);
long startTimeMillis = System.currentTimeMillis();
log.info("开始抓取局长信箱数据到涉访涉诉--------------------");
log.info("【局长信箱抓取】查询条件:mailFirstCategory in [举报类, 投诉类], 时间范围 {} ~ {}", start, end);
try {
LambdaQueryWrapper<Mail> mailLambdaQueryWrapper = new LambdaQueryWrapper<>();
mailLambdaQueryWrapper.in(Mail::getMailFirstCategory, "举报类", "投诉类");
mailLambdaQueryWrapper.between(Mail::getMailTime, start, end);
List<Mail> mailList = mailService.list(mailLambdaQueryWrapper);
log.info("【局长信箱抓取】查询到 Mail 数量:{}", mailList.size());
if (CollectionUtil.isEmpty(mailList)) {
log.warn("【局长信箱抓取】未查询到任何数据,任务结束");
return;
}
List<ComplaintCollection> complaintCollectionToSave = new ArrayList<>();
Map<String, List<MailAttachmentDTO>> complaintAttachMap = new HashMap<>();
Map<String, List<MailAttachmentDTO>> verifyAttachMap = new HashMap<>();
int successCount = 0;
int failCount = 0;
for (Mail mail : mailList) {
ComplaintCollection complaintCollection = buildComplaintCollection(mail);
// 投诉单位
Integer threeDeptId = mail.getThreeDeptId();
if (threeDeptId == null) {
failCount++;
log.warn("【局长信箱抓取】跳过 mail,threeDeptId 为空,mailId={}, source={}", mail.getId(), mail.getSource());
continue;
}
SupExternalDepartQueryParam threeDepQueryParam = new SupExternalDepartQueryParam();
threeDepQueryParam.setSource("局长信箱");
threeDepQueryParam.setExternalIds(Collections.singleton(String.valueOf(threeDeptId)));
List<SupExternalDepart> supExternalDeparts = supExternalDepartResourceService.query(threeDepQueryParam);
if (CollectionUtil.isEmpty(supExternalDeparts)) {
failCount++;
log.warn("【局长信箱抓取】跳过 mail,未找到 SupExternalDepart,mailId={}, threeDeptId={}", mail.getId(), threeDeptId);
continue;
}
SupExternalDepart supExternalDepart = supExternalDeparts.get(0);
SupDepartQueryParam secondDepartQueryParam = new SupDepartQueryParam();
secondDepartQueryParam.setId(supExternalDepart.getInternalId());
List<SupDepart> threeDeparts = supDepartResourceService.query(secondDepartQueryParam);
if (CollectionUtil.isEmpty(threeDeparts)) {
failCount++;
log.warn("【局长信箱抓取】跳过 mail,未找到对应三级单位,mailId={}, internalId={}", mail.getId(), supExternalDepart.getInternalId());
continue;
}
SupDepart threeDepart = threeDeparts.get(0);
SupDepartQueryParam threeDepartQueryParam = new SupDepartQueryParam();
threeDepartQueryParam.setId(supExternalDepart.getPid());
List<SupDepart> secondDeparts = supDepartResourceService.query(threeDepartQueryParam);
if (CollectionUtil.isEmpty(secondDeparts)) {
failCount++;
log.warn("【局长信箱抓取】跳过 mail,未找对应到二级单位,mailId={}, pid={}", mail.getId(), supExternalDepart.getPid());
continue;
}
SupDepart secondDepart = secondDeparts.get(0);
complaintCollection.setSecondDepartId(secondDepart.getId());
complaintCollection.setSecondDepartName(secondDepart.getShortName());
complaintCollection.setThirdDepartId(threeDepart.getId());
complaintCollection.setThirdDepartName(threeDepart.getShortName());
complaintCollection.setThingDesc(mail.getContent());
complaintCollection.setGwf3(ComplaintCollectionInitialEnum.UN_UPLOADED.getCode());
complaintAttachMap.put(mail.getId(), parseAttachments(mail.getAttachments()));
verifyAttachMap.put(mail.getId(), parseAttachments(mail.getVerifyAttachments()));
complaintCollectionToSave.add(complaintCollection);
successCount++;
}
if (CollectionUtil.isEmpty(complaintCollectionToSave)) {
log.warn("【局长信箱抓取】所有 Mail 均被跳过,无可保存的主数据");
return;
}
MailBoxCaptureToComplaintCollectionSaveDTO mailBoxCaptureToComplaintCollectionSaveDTO = new MailBoxCaptureToComplaintCollectionSaveDTO();
mailBoxCaptureToComplaintCollectionSaveDTO.setComplaintCollectionList(complaintCollectionToSave);
mailBoxCaptureToComplaintCollectionSaveDTO.setComplaintAttachMap(complaintAttachMap);
mailBoxCaptureToComplaintCollectionSaveDTO.setVerifyAttachMap(verifyAttachMap);
complaintCollectionServiceJob.saveComplaintAndAttachments(mailBoxCaptureToComplaintCollectionSaveDTO);
long cost = System.currentTimeMillis() - startTimeMillis;
log.info("【局长信箱抓取】完成,总数:{},成功:{},失败:{},耗时:{}ms", mailList.size(), successCount, failCount, cost);
} catch (Exception e) {
log.error("【局长信箱抓取】任务执行过程中发生严重异常,任务中断", e);
}
}
private String getSfssSourceTableSubOne(String str) {
if ("厅长信箱".equals(str)) {
return "23_tz";
}
if ("mailbox".equals(str)) {
return "23_jz";
}
if ("110_report_complaints".equals(str)) {
return "23_jb";
}
return "";
}
private ComplaintCollection buildComplaintCollection(Mail mail) {
ComplaintCollection complaintCollection = new ComplaintCollection();
complaintCollection.setSourceTable("23");
complaintCollection.setSourceTableSubOne(getSfssSourceTableSubOne(mail.getSource()));
complaintCollection.setOriginId(mail.getId());
complaintCollection.setDiscoveryTime(mail.getMailTime());
complaintCollection.setResponderName(mail.getContactName());
complaintCollection.setResponderPhone(mail.getContactPhone());
complaintCollection.setResponderIdCode(mail.getContactIdCard());
complaintCollection.setThingDesc(mail.getContent());
complaintCollection.setAccountabilityTarget(AccountabilityTargetEnum.PERSONAL.getValue());
// 核查情况
if ("属实".equals(mail.getVerifyIsTrue())) {
complaintCollection.setCheckStatus(InspectCaseEnum.TRUE.getValue());
complaintCollection.setCheckStatusName(InspectCaseEnum.TRUE.getLabel());
} else if ("基本属实".equals(mail.getVerifyIsTrue())) {
complaintCollection.setCheckStatus(InspectCaseEnum.PARTIALLY_TRUE.getValue());
complaintCollection.setCheckStatusName(InspectCaseEnum.PARTIALLY_TRUE.getLabel());
}
complaintCollection.setCheckStatusDesc(mail.getVerifyDetails());
// 状态字段
complaintCollection.setProcessingStatus(mail.getMailState());
complaintCollection.setProblemSources(ProblemSourcesEnum.JZXX.getLabel());
complaintCollection.setProblemSourcesCode(ProblemSourcesEnum.JZXX.getValue());
// complaintCollection.setBusinessTypeCode(BusinessTypeEnum.QT.getValue());
// complaintCollection.setBusinessTypeName(BusinessTypeEnum.QT.getLabel());
complaintCollection.setHandleMethod(ComplaintCollectionHandleMethodEnum.XF.getCode());
complaintCollection.setStatus("0");
complaintCollection.setCreateTime(LocalDateTime.now());
complaintCollection.setCreateBy("自动抓取");
return complaintCollection;
}
private List<MailAttachmentDTO> parseAttachments(String json) {
if (StrUtil.isBlank(json)) {
return Collections.emptyList();
}
try {
List<MailAttachmentDTO> mailAttachmentDTOS = JSON.parseArray(json, MailAttachmentDTO.class);
mailAttachmentDTOS.forEach(item -> {
String filepath = null;
if (StrUtil.isNotBlank(item.getDocxFilepath())){
filepath = "http://65.47.60.145/lan-api/api/file/stream/" + item.getDocxFilepath();
}else {
filepath = "http://65.47.60.145/lan-api/api/file/stream/" + item.getFilepath();
}
item.setFilepath(filepath);
});
return mailAttachmentDTOS;
} catch (Exception e) {
log.warn("【局长信箱抓取】附件 JSON 解析失败,json={}", json, e);
return Collections.emptyList();
}
}
}

58
src/main/java/com/biutag/supervision/job/MailBoxCaptureJob.java

@ -0,0 +1,58 @@
package com.biutag.supervision.job;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDate;
import java.time.LocalDateTime;
import com.biutag.supervision.service.MailBoxCaptureService;
/**
* @ClassName MailBoxCaptureJob
* @Description 局长信箱数据抓取定时任务
* - 阶段1每天2点抓取来信创建 Negative + ComplaintCollection
* - 阶段2每天3点同步涉及人和核查附件
* @Author shihao
* @Date 2026/4/28
*/
@Slf4j
@RequiredArgsConstructor
@Component
public class MailBoxCaptureJob {
private final MailBoxCaptureService mailBoxCaptureService;
/**
* 阶段1抓取来信
* 每天凌晨2点执行
*/
@Scheduled(cron = "0 0 2 * * ?")
public void mailBoxCaptureCompletedToNegative() {
LocalDateTime start = LocalDate.now().minusDays(1).atStartOfDay();
LocalDateTime end = LocalDate.now().atStartOfDay();
mailBoxCaptureService.captureMayorMailbox(start, end);
}
/**
* 阶段2同步涉及人和核查附件
* 每天凌晨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();
}
}

6
src/main/java/com/biutag/supervision/mapper/ComplaintCollectionMapper.java

@ -1,7 +1,12 @@
package com.biutag.supervision.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.biutag.supervision.pojo.dto.complaintCollection.ComplaintCollectionPageDTO;
import com.biutag.supervision.pojo.entity.ComplaintCollection;
import com.biutag.supervision.pojo.param.ComplaintCollection.ComplaintCollectionQueryParam;
import com.biutag.supervision.repository.base.HBaseMapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@ -9,5 +14,6 @@ public interface ComplaintCollectionMapper extends HBaseMapper<ComplaintCollecti
int insertBatch(List<ComplaintCollection> list);
IPage<ComplaintCollectionPageDTO> selectPageWithNegative(Page<ComplaintCollection> page, @Param("param") ComplaintCollectionQueryParam param);
}

16
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<MailExtension> {
}

6
src/main/java/com/biutag/supervision/pojo/domain/NegativeDetail.java

@ -1,6 +1,8 @@
package com.biutag.supervision.pojo.domain;
import com.biutag.supervision.pojo.dto.complaintCollection.ComplaintCollectionPageDTO;
import com.biutag.supervision.pojo.entity.*;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
@ -46,4 +48,8 @@ public class NegativeDetail {
// 认定办结
private Boolean confirmationCompletionFlag = false;
@Schema(description = "投诉举报PageDTO")
private ComplaintCollectionPageDTO complaintCollectionPageDTO;
}

30
src/main/java/com/biutag/supervision/pojo/domain/NegativeVo.java

@ -6,6 +6,7 @@ import com.biutag.supervision.pojo.entity.NegativeScorePolice;
import com.biutag.supervision.pojo.entity.NegativeThingFile;
import com.biutag.supervision.pojo.vo.NegativeFileVo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
@ -264,4 +265,33 @@ public class NegativeVo {
// 经办人
private List<VerifyData.HandlePolice> handlePolices = new ArrayList<>();
/**
* @see com.biutag.supervision.pojo.enums.negative.NegativeSourceTypeEnum
*/
@Schema(description = "来源类型")
private String sourceType;
/**
* @see com.biutag.supervision.pojo.enums.negative.NegativeSourceTypeEnum
*/
@Schema(description = "来源类型名称")
private String sourceTypeDesc;
@Schema(description = "下发单位id")
private String issuingDepartId;
@Schema(description = "下发单位名字")
private String issuingDepartName;
@Schema(description = "最后一次审批节点操作时间")
private LocalDateTime latestProcessTime;
@Schema(description = "2级审批累计时长(秒)")
private Long secondApprovalTime;
@Schema(description = "市局审批累计时长(秒)")
private Long firstApproveTime;
}

29
src/main/java/com/biutag/supervision/pojo/dto/MailBoxSyncDto.java

@ -0,0 +1,29 @@
package com.biutag.supervision.pojo.dto;
import com.biutag.supervision.pojo.entity.ComplaintCollection;
import com.biutag.supervision.pojo.entity.mailbox.Mail;
import com.biutag.supervision.pojo.entity.mailbox.MailBlame;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
/**
* 局长信箱阶段2同步数据DTO
* 用于在循环内传递同步所需的数据
*/
@Getter
@Setter
@Schema(description = "局长信箱阶段2同步数据DTO")
public class MailBoxSyncDto {
@Schema(description = "投诉举报收集表记录")
private ComplaintCollection cc;
@Schema(description = "局长信箱邮件数据")
private Mail mail;
@Schema(description = "涉及人列表")
private List<MailBlame> mailBlames;
}

361
src/main/java/com/biutag/supervision/pojo/dto/NegativeDataOnlyDto.java

@ -0,0 +1,361 @@
package com.biutag.supervision.pojo.dto;
import com.biutag.supervision.constants.enums.ProblemSourcesEnum;
import com.biutag.supervision.pojo.dto.flow.VerifyData;
import com.biutag.supervision.pojo.entity.NegativeBlame;
import com.biutag.supervision.pojo.entity.NegativeFile;
import com.biutag.supervision.pojo.entity.NegativeThingFile;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
/**
* Negative纯数据保存DTO - 所有字段通过传参不写死任何值
*/
@Setter
@Getter
@Schema(description = "Negative纯数据保存DTO")
public class NegativeDataOnlyDto {
// ========== Negative主表所有字段 ==========
@Schema(description = "主键(可传可不传,不传则自动生成)")
private String id;
@Schema(description = "样本来源编号")
private String originId;
@Schema(description = "编号")
private String serialNumber;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
@Schema(description = "问题发生时间")
private LocalDateTime happenTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
@Schema(description = "问题发现时间")
private LocalDateTime discoveryTime;
/**
* @see ProblemSourcesEnum
*/
@Schema(description = "问题来源code")
private String problemSourcesCode;
/**
* @see ProblemSourcesEnum
*/
@Schema(description = "问题来源")
private String problemSources;
@Schema(description = "业务类型code")
private String businessTypeCode;
@Schema(description = "业务类别名称")
private String businessTypeName;
@Schema(description = "涉嫌问题(列表,会转成逗号分隔字符串)")
private List<String> involveProblem = new ArrayList<>();
@Schema(description = "涉及警种名称")
private String policeTypeName;
@Schema(description = "涉及警种")
private String policeType;
@Schema(description = "涉及单位名称")
private String involveDepartName;
@Schema(description = "涉及单位id")
private String involveDepartId;
@Schema(description = "联系电话")
private String contactPhone;
@Schema(description = "反映人姓名")
private String responderName;
@Schema(description = "反映人身份证")
private String responderIdCard;
@Schema(description = "简要描述")
private String thingDesc;
@Schema(description = "填写人姓名")
private String fillName;
@Schema(description = "填写人部门id")
private String fillDepartId;
@Schema(description = "填写人部门名称")
private String fillDeaprtName;
@Schema(description = "审核人姓名")
private String checkName;
@Schema(description = "审核人身份证")
private String checkIdCode;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
@Schema(description = "创建时间(不传则自动填充)")
private LocalDateTime crtTime;
@Schema(description = "更新人姓名")
private String updName;
@Schema(description = "更新人")
private String updUser;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
@Schema(description = "更新时间(不传则自动填充)")
private LocalDateTime updTime;
@Schema(description = "状态")
private String status;
@Schema(description = "备注")
private String remark;
@Schema(description = "预留字段")
private String reserve;
@Schema(description = "核查情况")
private String checkStatus;
@Schema(description = "核查情况名称")
private String checkStatusName;
@Schema(description = "核查结论code")
private String checkStatusCode;
@Schema(description = "完善状态")
private String completeStatus;
@Schema(description = "最后编辑人员")
private String lastEditName;
@Schema(description = "任务ID")
private String taskId;
@Schema(description = "督察主题code")
private String supervisionSubjectCode;
@Schema(description = "督察主题名称")
private String supervisionSubjectName;
@Schema(description = "是否整改code")
private String isRectifyCode;
@Schema(description = "是否整改名称")
private String isRectifyName;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
@Schema(description = "办结时间")
private LocalDateTime completeDate;
@Schema(description = "督察报告id")
private String reportId;
@Schema(description = "流程key")
private String flowKey;
@Schema(description = "主办层级")
private String hostLevel;
@Schema(description = "办理时限")
private String timeLimit;
@Schema(description = "最大签收时长(天)")
private Integer maxSignDuration;
@Schema(description = "最大办理时长(天)")
private Integer maxHandleDuration;
@Schema(description = "最大延期时长(天)")
private Integer maxExtensionDuration;
@Schema(description = "审批流程")
private String approvalFlow;
@Schema(description = "核查情况描述")
private String checkStatusDesc;
@Schema(description = "整改情况描述")
private String rectifyDesc;
@Schema(description = "整改限制天数")
private Integer rectifyRestrictionDays;
@Schema(description = "追责对象")
private String accountabilityTarget;
@Schema(description = "办理状态")
private String processingStatus;
@Schema(description = "延期申请ID")
private Integer negativeExtensionApplyId;
@Schema(description = "是否能申请延期")
private Boolean extensionApplyFlag;
@Schema(description = "延期天数")
private Integer extensionDays;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
@Schema(description = "市局下发时间")
private LocalDateTime firstDistributeTime;
@Schema(description = "是否二级机构办理")
private Boolean isSecondHandle;
@Schema(description = "二级办理单位id")
private String handleSecondDepartId;
@Schema(description = "二级办理单位名称")
private String handleSecondDepartName;
@Schema(description = "三级办理单位id")
private String handleThreeDepartId;
@Schema(description = "三级办理单位名称")
private String handleThreeDepartName;
@Schema(description = "涉及案件/警情编号")
private String caseNumber;
@Schema(description = "办理超时(秒)")
private Long handleTimeout;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
@Schema(description = "申请办结时间")
private LocalDateTime handleTime;
@Schema(description = "当前处理对象")
private String currentProcessingObject;
@Schema(description = "专项督察")
private String specialSupervision;
@Schema(description = "通报期数")
private String reportNumber;
@Schema(description = "核查办理情况")
private String verifySituation;
@Schema(description = "佐证材料情况")
private String verifyFileSituation;
@Schema(description = "单位会签ID")
private Integer countersignApplyId;
@Schema(description = "创建单位层级")
private Integer crtDepartLevel;
@Schema(description = "市局下发意见")
private String firstDistributeComments;
@Schema(description = "是否抽检")
private Boolean spotCheckFlag;
@Schema(description = "抽检结果")
private String spotCheckResult;
@Schema(description = "抽检情况")
private String spotCheckDesc;
@Schema(description = "未整改原因")
private String unrectifyReason;
@Schema(description = "二级部门id")
private String secondInvolveDepartId;
@Schema(description = "三级部门id")
private String threeInvolveDepartId;
@Schema(description = "经办人")
private String handlePolices;
@Schema(description = "剩余办理时间")
private Long handleRemainingTime;
@Schema(description = "样本ID")
private Integer sampleId;
@Schema(description = "下发问题(JSON)")
private List<VerifyData.Problem> problems;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
@Schema(description = "核查时间")
private LocalDateTime verifyTime;
@Schema(description = "项目名称")
private String projectName;
@Schema(description = "涉及问题金额")
private Double involveMoney;
@Schema(description = "化解情况")
private String resolveSituation;
@Schema(description = "当前状态")
private String resolveStatus;
@Schema(description = "接访领导姓名")
private String visitingLeaderName;
@Schema(description = "接访领导工号")
private String visitingLeaderEmpNo;
@Schema(description = "12337办理结果")
private String handleResult12337;
@Schema(description = "12337办理结果分组")
private String handleResult12337Group;
@Schema(description = "涉及人员是否领导班子")
private String verifiedIsLeader;
@Schema(description = "办理结果")
private String processResult;
@Schema(description = "处分处理情况")
private String disciplinaryActionDesc;
@Schema(description = "来源类型")
private String sourceType;
@Schema(description = "来源类型名称")
private String sourceTypeDesc;
@Schema(description = "下发单位id")
private String issuingDepartId;
@Schema(description = "下发单位名称")
private String issuingDepartName;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
@Schema(description = "最后一次审批节点操作时间")
private LocalDateTime latestProcessTime;
@Schema(description = "二级审批累计时长(秒)")
private Long secondApprovalTime;
@Schema(description = "市局审批累计时长(秒)")
private Long firstApproveTime;
// ========== 关联表 ==========
@Schema(description = "涉及人员列表")
private List<NegativeBlame> blames = new ArrayList<>();
@Schema(description = "事件附件列表")
private List<NegativeThingFile> thingFiles = new ArrayList<>();
@Schema(description = "核查附件列表")
private List<NegativeFile> files = new ArrayList<>();
}

4
src/main/java/com/biutag/supervision/pojo/dto/NegativeDto.java

@ -45,6 +45,10 @@ public class NegativeDto {
@NotBlank(message = "业务类别不能为空", groups = {AddGroup.class, EditGroup.class})
private String businessTypeCode;
// @NotBlank(message = "业务类别不能为空", groups = {AddGroup.class, EditGroup.class})
@Schema(description = "业务类别名称")
private String businessTypeName;
private String policeTypeName;

34
src/main/java/com/biutag/supervision/pojo/dto/complaintCollection/ComplaintCollectionPageDTO.java

@ -1,5 +1,6 @@
package com.biutag.supervision.pojo.dto.complaintCollection;
import com.baomidou.mybatisplus.annotation.TableField;
import com.biutag.supervision.pojo.enums.complaintCollection.ComplaintCollectionSourceTableEnum;
import com.biutag.supervision.pojo.enums.complaintCollection.YesOrNoEnum;
import com.biutag.supervision.pojo.vo.FileVo;
@ -161,7 +162,7 @@ public class ComplaintCollectionPageDTO {
@Schema(description = "办结时间")
private LocalDateTime completedTime;
@Schema(description = "责任单位")
@Schema(description = "涉及单位")
private String involveDepartName;
@Schema(description = "接访领导姓名")
@ -205,8 +206,8 @@ public class ComplaintCollectionPageDTO {
private String crxState;
/* ---- MAILBOX/三表统一补充 ---- */
@Schema(description = "核查情况")
private String checkStatus;
@Schema(description = "核查结论代码")
private String checkStatusCode;
@Schema(description = "核查情况名称")
private String checkStatusName;
@ -230,8 +231,14 @@ public class ComplaintCollectionPageDTO {
/* ---- 扩展字段 ---- */
@Schema(description = "自定义1")
private String gwf1;
@Schema(description = "自定义2")
@Schema(description = "自定义2,承接初核时间")
private String gwf2;
/**
* @see com.biutag.supervision.pojo.enums.complaintCollection.ComplaintCollectionInitialEnum
*/
@Schema(description = "自定义3")
private String gwf3;
@Schema(description = "自定义4")
@ -259,9 +266,6 @@ public class ComplaintCollectionPageDTO {
@Schema(description = "群众认可")
private String publicRecognition;
@Schema(description = "状态,显示用,暂无实际意义")
private String status;
@Schema(description = "附件列表")
private List<FileVo> thingFiles = new ArrayList<>();
@ -269,5 +273,21 @@ public class ComplaintCollectionPageDTO {
@Schema(description = "剩余办理时长")
private Long remainingDuration;
@Schema(description = "初核工作开展情况")
@TableField("init_work_des")
private String initWorkDes;
@Schema(description = "初核发现的问题及下步工作计划")
@TableField("init_problem_plan")
private String initProblemPlan;
/**
* 和核查结论保持一致
* @see com.biutag.supervision.constants.enums.CheckStatusEnum
*/
@Schema(description = "初核结论")
@TableField("init_verdict")
private String initVerdict;
}

3
src/main/java/com/biutag/supervision/pojo/dto/complaintCollection/ComplaintCollectionRepeatDTO.java

@ -41,6 +41,9 @@ public class ComplaintCollectionRepeatDTO {
@Schema(description = "内容/正文")
private String thingDesc;
@Schema(description = "xx")
private String negativeId;
}

81
src/main/java/com/biutag/supervision/pojo/dto/complaintCollection/ExportComplaintCollectionBlameVo.java

@ -0,0 +1,81 @@
package com.biutag.supervision.pojo.dto.complaintCollection;
import com.alibaba.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
@Getter
@Setter
public class ExportComplaintCollectionBlameVo {
@ExcelProperty("关联负面清单ID")
private String negativeId;
@ExcelProperty("信件编号")
private String originId;
@ExcelProperty(value = "发现/受理时间", format = "yyyy-MM-dd HH:mm")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
private LocalDateTime discoveryTime;
@ExcelProperty("来源")
private String sourceTablePath;
@ExcelProperty("业务类别")
private String businessTypeName;
@ExcelProperty("涉嫌问题")
private String involveProblemStr;
@ExcelProperty("简要描述")
private String thingDesc;
@ExcelProperty("涉及单位(二级)")
private String secondDepartName;
@ExcelProperty("涉及单位(三级)")
private String thirdDepartName;
@ExcelProperty("核查结论")
private String checkStatusName;
@ExcelProperty("追责对象")
private String accountabilityTarget;
@ExcelProperty("涉及人员姓名")
private String blameName;
@ExcelProperty("警号")
private String blameEmpNo;
@ExcelProperty("身份证")
private String blameIdCode;
@ExcelProperty("人员属性")
private String ivPersonType;
@ExcelProperty("责任追责")
private String handleResultName;
@ExcelProperty("责任领导姓名")
private String leadName;
@ExcelProperty("责任领导警号")
private String leadEmpNo;
@ExcelProperty("责任领导身份证")
private String leadIdCode;
@ExcelProperty("责任领导责任追责")
private String leadHandleResultName;
@ExcelProperty("问题类型")
private String problemType;
@ExcelProperty("督察措施")
private String superviseMeasuresName;
}

93
src/main/java/com/biutag/supervision/pojo/dto/complaintCollection/ExportComplaintCollectionExcelVo.java

@ -0,0 +1,93 @@
package com.biutag.supervision.pojo.dto.complaintCollection;
import com.alibaba.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
@Getter
@Setter
public class ExportComplaintCollectionExcelVo {
@ExcelProperty("关联负面清单ID")
private String negativeId;
@ExcelProperty("信件编号")
private String originId;
@ExcelProperty("来源")
private String sourceTablePath;
@ExcelProperty(value = "发现/受理时间", format = "yyyy-MM-dd HH:mm")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
private LocalDateTime discoveryTime;
@ExcelProperty("业务类别")
private String businessTypeName;
@ExcelProperty("涉嫌问题")
private String involveProblemStr;
@ExcelProperty("简要描述")
private String thingDesc;
@ExcelProperty("投诉反映人")
private String responderName;
@ExcelProperty("联系电话")
private String responderPhone;
@ExcelProperty("涉及警种")
private String policeTypeName;
@ExcelProperty("办理单位(二级)")
private String secondDepartName;
@ExcelProperty("办理单位(三级)")
private String thirdDepartName;
@ExcelProperty("涉及单位")
private String involveDepartName;
@ExcelProperty("核查结论")
private String checkStatusName;
// @ExcelProperty("追责对象")
// private String accountabilityTarget;
// @ExcelProperty("涉及人数")
// private Integer blameNumber;
@ExcelProperty("涉及人员")
private String blameStr;
// @ExcelProperty("责任追责")
// private String handleResultName;
// @ExcelProperty("是否追责")
// private String isHoldAccountable;
// @ExcelProperty("问题类型")
// private String problemTypeList;
@ExcelProperty("办理状态")
private String processingStatus;
@ExcelProperty("办结情况")
private String completionStatus;
@ExcelProperty("群众认可")
private String publicRecognition;
@ExcelProperty("办理方式")
private String handleMethod;
@ExcelProperty("是否重复件")
private String repeatt;
@ExcelProperty("标签")
private String tag;
}

6
src/main/java/com/biutag/supervision/pojo/dto/flow/VerifyData.java

@ -92,6 +92,12 @@ public class VerifyData {
// 处分处理情况
private String disciplinaryActionDesc;
// 办结情况
private String completionStatus;
// 群众认可
private String publicRecognition;
@Setter
@Getter
public static class Blame {

26
src/main/java/com/biutag/supervision/pojo/entity/ComplaintCollection.java

@ -372,5 +372,31 @@ public class ComplaintCollection {
@TableField("status")
private String status;
@Schema(description = "初核工作开展情况")
@TableField("init_work_des")
private String initWorkDes;
@Schema(description = "初核发现的问题及下步工作计划")
@TableField("init_problem_plan")
private String initProblemPlan;
/**
* 和核查结论保持一致
* @see com.biutag.supervision.constants.enums.CheckStatusEnum
*/
@Schema(description = "初核结论")
@TableField("init_verdict")
private String initVerdict;
/**
* 阶段2同步标记0-未同步 1-已同步
*/
@Schema(description = "阶段2同步标记:0-未同步 1-已同步")
@TableField("blame_sync_status")
private String blameSyncStatus;
@Schema(description = "初核附件")
@TableField("init_file")
private String initFile;
}

85
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;
}

8
src/main/java/com/biutag/supervision/pojo/entity/mailbox/MailBlame.java

@ -43,4 +43,12 @@ public class MailBlame {
* 创建时间
*/
private LocalDateTime createTime;
private String leaderEmpNo;
private String leaderName;
private String leaderIdCode;
}

41
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;
}

2
src/main/java/com/biutag/supervision/pojo/enums/negative/NegativeSourceTypeEnum.java

@ -16,6 +16,8 @@ public enum NegativeSourceTypeEnum implements CodeEnum {
MODEL_MARKET("1", "模型超市"),
COMPLAINT_REPORT("2", "投诉举报"),
OTHER_MARKET("99", "未知");

12
src/main/java/com/biutag/supervision/pojo/param/ComplaintCollection/ComplaintCollectionQueryParam.java

@ -74,7 +74,7 @@ public class ComplaintCollectionQueryParam extends BasePage {
@Schema(description = "被投诉二级机构名字")
private String secondDepartName;
@Schema(description = "办理方式")
@Schema(description = "办理方式 0自办 1下发")
private String handleMethod;
@Schema(description = "来件内容")
@ -103,7 +103,7 @@ public class ComplaintCollectionQueryParam extends BasePage {
private String status;
@Schema(description = "信件状态(局)")
private String processingStatus;
private Set<String> processingStatus;
@Schema(description = "核查情况")
private String checkStatus;
@ -124,6 +124,14 @@ public class ComplaintCollectionQueryParam extends BasePage {
private List<LocalDateTime> createTimeList = new ArrayList<>();
@Schema(description = "问题ID")
private String negativeId;
@Schema(description = "问题IDs")
private List<String> negativeIds;
@Schema(description = "阶段2同步标记")
private String blameSyncStatus;
// @Schema(description = "部门ID集合")
// private Set<String> secondDepartIds;

23
src/main/java/com/biutag/supervision/pojo/param/ComplaintCollection/ComplaintCollectionUpdateParam.java

@ -72,8 +72,8 @@ public class ComplaintCollectionUpdateParam {
@Schema(description = "是否领导审批")
private String leadApproval;
@Schema(description = "标签")
private String tag;
// @Schema(description = "标签")
// private String tag;
/**
* @see ComplaintCollectionHandleMethodEnum
@ -151,4 +151,23 @@ public class ComplaintCollectionUpdateParam {
@Schema(description = "初核状态, gwf3承接")
private String gwf3;
@Schema(description = "初核工作开展情况")
private String initWorkDes;
@Schema(description = "初核发现的问题及下步工作计划")
private String initProblemPlan;
@Schema(description = "初核结论")
private String initVerdict;
@Schema(description = "negativeId")
private String negativeId;
@Schema(description = "初核附件")
private String initFile;
@Schema(description = "阶段2同步标记:0-未同步 1-已同步")
private String blameSyncStatus;
}

5
src/main/java/com/biutag/supervision/pojo/param/MailQueryParam.java

@ -73,4 +73,9 @@ public class MailQueryParam extends BasePage{
@Schema(description = "身份证ids")
private Set<String> contactIdCards;
/**
* 信件状态
*/
private String mailState;
}

32
src/main/java/com/biutag/supervision/pojo/request/complaintCollection/ComplaintCollectionAddRequest.java

@ -116,6 +116,32 @@ public class ComplaintCollectionAddRequest implements ParamChecked {
@Schema(description = "附件列表")
private List<FileVo> thingFiles = new ArrayList<>();
// ===== 以下字段用于同步创建 Negative =====
@Schema(description = "主办层级")
private String hostLevel;
@Schema(description = "指定办理单位ID")
private String departId;
@Schema(description = "指定办理单位名称")
private String departName;
@Schema(description = "办理时限")
private String timeLimit;
@Schema(description = "签收时限(天)")
private Integer maxSignDuration;
@Schema(description = "办理时限(天)")
private Integer maxHandleDuration;
@Schema(description = "延期时限(天)")
private Integer maxExtensionDuration;
@Schema(description = "审批流程")
private String approvalFlow;
@Override
public void check() {
trimFields();
@ -152,6 +178,10 @@ public class ComplaintCollectionAddRequest implements ParamChecked {
throw new IllegalArgumentException("是否重复不能为空");
}
if (StrUtil.isBlank(businessTypeCode)) {
throw new IllegalArgumentException("业务类型不能为空");
}
// if (StrUtil.isBlank((leadApproval))) {
// throw new IllegalArgumentException("是否领导审批不能为空");
// }
@ -160,7 +190,7 @@ public class ComplaintCollectionAddRequest implements ParamChecked {
// throw new IllegalArgumentException("标签不能为空");
// }
if (StrUtil.isEmpty(handleMethod)){
throw new IllegalArgumentException("办理方不能为空");
throw new IllegalArgumentException("办理方不能为空");
}
if (CollectionUtil.isNotEmpty(involveProblemIdList)){

7
src/main/java/com/biutag/supervision/pojo/request/complaintCollection/ComplaintCollectionDelRequest.java

@ -21,10 +21,13 @@ public class ComplaintCollectionDelRequest implements ParamChecked {
@Schema(description = "ComplaintCollection自己的Id")
private String id;
@Schema(description = "问题id")
private String negativeId;
@Override
public void check() {
if (StrUtil.isBlank(id)) {
throw new IllegalArgumentException("编号不能为空");
if (StrUtil.isBlank(id) && StrUtil.isBlank(negativeId)) {
throw new IllegalArgumentException("投诉举报id和问题id不能同时为空");
}
}

32
src/main/java/com/biutag/supervision/pojo/request/complaintCollection/ComplaintCollectionDetailRequest.java

@ -0,0 +1,32 @@
package com.biutag.supervision.pojo.request.complaintCollection;
import cn.hutool.core.util.StrUtil;
import com.biutag.supervision.aop.ParamChecked;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
/**
* @ClassName ComplaintCollectionDetailRequest
* @Description 涉访涉诉详情查询请求
* @Author system
* @Date 2026/04/08
*/
@Setter
@Getter
@Schema(description = "涉访涉诉详情查询请求")
public class ComplaintCollectionDetailRequest implements ParamChecked {
@Schema(description = "投诉举报主键ID")
private String id;
@Schema(description = "问题id")
private String negativeId;
@Override
public void check() {
if (StrUtil.isBlank(id) && StrUtil.isBlank(negativeId)) {
throw new IllegalArgumentException("投诉举报主键ID和问题ID不能同时空");
}
}
}

38
src/main/java/com/biutag/supervision/pojo/request/complaintCollection/ComplaintCollectionInitialReviewRequest.java

@ -0,0 +1,38 @@
package com.biutag.supervision.pojo.request.complaintCollection;
import com.biutag.supervision.aop.ParamChecked;
import com.biutag.supervision.util.CheckUtil;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
@Setter
@Getter
@Schema(description = "初核请求")
public class ComplaintCollectionInitialReviewRequest implements ParamChecked {
@Schema(description = "涉访涉诉编号id")
private String complaintId;
@Schema(description = "初核工作开展情况")
private String initWorkDes;
@Schema(description = "初核发现的问题及下步工作计划")
private String initProblemPlan;
@Schema(description = "初核结论")
private String initVerdict;
@Schema(description = "初核附件")
private String initFile;
@Override
public void check() {
CheckUtil.checkNotBlank(complaintId, "涉访涉诉id不能为空");
CheckUtil.checkNotBlank(initWorkDes, "初核工作开展情况不能为空");
CheckUtil.checkNotBlank(initProblemPlan, "初核发现的问题及下步工作计划不能为空");
CheckUtil.checkNotBlank(initVerdict, "初核结论不能为空");
}
}

31
src/main/java/com/biutag/supervision/pojo/request/complaintCollection/ComplaintCollectionInitialReviewSaveRequest.java

@ -0,0 +1,31 @@
package com.biutag.supervision.pojo.request.complaintCollection;
import com.biutag.supervision.aop.ParamChecked;
import com.biutag.supervision.util.CheckUtil;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
@Setter
@Getter
@Schema(description = "初核请求")
public class ComplaintCollectionInitialReviewSaveRequest implements ParamChecked {
@Schema(description = "涉访涉诉编号id")
private String complaintId;
@Schema(description = "初核工作开展情况")
private String initWorkDes;
@Schema(description = "初核发现的问题及下步工作计划")
private String initProblemPlan;
@Schema(description = "初核结论")
private String initVerdict;
@Override
public void check() {
CheckUtil.checkNotNull(complaintId, "投诉编号不能为空!");
}
}

3
src/main/java/com/biutag/supervision/pojo/request/complaintCollection/ComplaintCollectionPageRequest.java

@ -71,9 +71,10 @@ public class ComplaintCollectionPageRequest extends BasePage implements ParamChe
private Set<String> tags;
@Schema(description = "信件状态(局)")
private String processingStatus;
private Set<String> processingStatus;
@Schema(description = "状态")
@Deprecated
private String status;
@Schema(description = "核查情况")

7
src/main/java/com/biutag/supervision/pojo/request/complaintCollection/ComplaintCollectionUpdateRequest.java

@ -74,11 +74,18 @@ public class ComplaintCollectionUpdateRequest implements ParamChecked {
@Schema(description = "附件列表")
private List<FileVo> thingFiles = new ArrayList<>();
@Schema(description = "问题id")
private String negativeId;
@Override
public void check() {
if (StrUtil.isBlank(id)) {
throw new IllegalArgumentException("id不能为空");
}
if (StrUtil.isBlank(negativeId)) {
throw new IllegalArgumentException("问题id不能为空");
}
boolean nothingToUpdate =
discoveryTime == null
&& StrUtil.isBlank(responderName)

7
src/main/java/com/biutag/supervision/pojo/transfer/ComplaintCollectionTransfer.java

@ -9,10 +9,7 @@ import com.biutag.supervision.pojo.entity.ComplaintCollectionCheckFile;
import com.biutag.supervision.pojo.entity.ComplaintCollectionFile;
import com.biutag.supervision.pojo.param.ComplaintCollection.ComplaintCollectionQueryParam;
import com.biutag.supervision.pojo.param.ComplaintCollection.ComplaintCollectionUpdateParam;
import com.biutag.supervision.pojo.request.complaintCollection.ComplaintCollectionAddRequest;
import com.biutag.supervision.pojo.request.complaintCollection.ComplaintCollectionPageRequest;
import com.biutag.supervision.pojo.request.complaintCollection.ComplaintCollectionSaveInvolveJsonRequest;
import com.biutag.supervision.pojo.request.complaintCollection.ComplaintCollectionUpdateRequest;
import com.biutag.supervision.pojo.request.complaintCollection.*;
import com.biutag.supervision.pojo.vo.FileVo;
import com.biutag.supervision.pojo.vo.complaintCollection.ComplaintCollectionPageVo;
import com.biutag.supervision.pojo.vo.complaintCollection.ComplaintCollectionWatchDetailVO;
@ -67,6 +64,8 @@ public interface ComplaintCollectionTransfer {
List<FileVo> complaintCollectionCheckFileToFileVo(List<ComplaintCollectionCheckFile> complaintCollectionCheckFiles);
ComplaintCollectionUpdateParam InitialReviewToUpdateParam(ComplaintCollectionInitialReviewRequest request);
// List<Blame> complaintCollectionBlamesToBlames(List<ComplaintCollectionBlame> pseronalList);

13
src/main/java/com/biutag/supervision/pojo/vo/NegativeQueryVo.java

@ -226,4 +226,17 @@ public class NegativeQueryVo {
@TableField("first_approve_time")
private Long firstApproveTime;
/**
* @see com.biutag.supervision.pojo.enums.negative.NegativeSourceTypeEnum
*/
@Schema(description = "来源类型")
private String sourceType;
/**
* @see com.biutag.supervision.pojo.enums.negative.NegativeSourceTypeEnum
*/
@Schema(description = "来源类型名称")
private String sourceTypeDesc;
}

85
src/main/java/com/biutag/supervision/pojo/vo/complaintCollection/ComplaintCollectionDetailVo.java

@ -0,0 +1,85 @@
package com.biutag.supervision.pojo.vo.complaintCollection;
import com.biutag.supervision.pojo.vo.FileVo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
/**
* @ClassName ComplaintCollectionDetailVo
* @Description 涉访涉诉详情查询响应VO用于修改弹窗数据回显
* @Author system
* @Date 2026/04/08
*/
@Data
@Schema(description = "涉访涉诉详情查询响应VO(用于修改弹窗数据回显)")
public class ComplaintCollectionDetailVo {
@Schema(description = "主键ID")
private String id;
@Schema(description = "来源表类型")
private String sourceTable;
@Schema(description = "来源子类型")
private String sourceTableSubOne;
@Schema(description = "编号")
private String originId;
@Schema(description = "登记/受理时间")
private LocalDateTime discoveryTime;
@Schema(description = "来件人姓名")
private String responderName;
@Schema(description = "身份证号")
private String responderIdCode;
@Schema(description = "联系电话")
private String responderPhone;
@Schema(description = "被投诉二级机构ID")
private String secondDepartId;
@Schema(description = "被投诉二级机构名称")
private String secondDepartName;
@Schema(description = "来件内容")
private String thingDesc;
@Schema(description = "涉嫌问题(逗号分隔)")
private String involveProblem;
@Schema(description = "涉嫌问题ID列表")
private List<String> involveProblemIdList;
@Schema(description = "是否重复件")
private String repeatt;
@Schema(description = "是否领导审批")
private String leadApproval;
@Schema(description = "标签(逗号分隔)")
private String tag;
@Schema(description = "标签列表")
private List<String> tags;
@Schema(description = "办理方式")
private String handleMethod;
@Schema(description = "业务类型code")
private String businessTypeCode;
@Schema(description = "业务类型name")
private String businessTypeName;
@Schema(description = "附件列表")
private List<FileVo> thingFiles;
@Schema(description = "问题ID(negative表)")
private String negativeId;
}

79
src/main/java/com/biutag/supervision/repository/complaintCollection/ComplaintCollectionResourceService.java

@ -40,83 +40,20 @@ public class ComplaintCollectionResourceService extends BaseDAO {
setBatchQuery(param.getId(), param.getIds(), queryWrapper, ComplaintCollection::getId);
setBatchQuery(param.getResponderIdCode(), param.getResponderIdCodes(), queryWrapper, ComplaintCollection::getResponderIdCode);
setBatchQuery(param.getOriginId(), param.getOriginIds(), queryWrapper, ComplaintCollection::getOriginId);
setBatchQuery(param.getNegativeId(), param.getNegativeIds(), queryWrapper, ComplaintCollection::getNegativeId);
queryWrapper.eq(StrUtil.isNotBlank(param.getSourceTable()), ComplaintCollection::getSourceTable, param.getSourceTable());
queryWrapper.eq(StrUtil.isNotBlank(param.getResponderName()), ComplaintCollection::getResponderName, param.getResponderName());
queryWrapper.eq(StrUtil.isNotBlank(param.getResponderPhone()), ComplaintCollection::getResponderPhone, param.getResponderPhone());
queryWrapper.eq(StrUtil.isNotBlank(param.getStatus()), ComplaintCollection::getStatus, param.getStatus());
queryWrapper.in(CollectionUtil.isNotEmpty(param.getInitialReviewFileList()), ComplaintCollection::getGwf3, param.getInitialReviewFileList());
queryWrapper.eq(StrUtil.isNotBlank(param.getHandleMethod()), ComplaintCollection::getHandleMethod, param.getHandleMethod());
queryWrapper.eq(StrUtil.isNotBlank(param.getBlameSyncStatus()), ComplaintCollection::getBlameSyncStatus, param.getBlameSyncStatus());
if (queryWrapper.getExpression() == null || queryWrapper.getExpression().getSqlSegment().isEmpty()) {
return Collections.emptyList();
}
return complaintCollectionMapper.selectList(queryWrapper);
}
public IPage<ComplaintCollection> pageQuery(ComplaintCollectionQueryParam param) {
// 构建分页对象
Page<ComplaintCollection> page = new Page<>(param.getCurrent(), param.getSize());
LambdaQueryWrapper<ComplaintCollection> qw = new LambdaQueryWrapper<>();
setBatchQuery(param.getSourceTable(), param.getSourceTableList(), qw, ComplaintCollection::getSourceTable);
setBatchQuery(param.getSourceTableSubOne(), param.getSourceTableSubOneList(), qw, ComplaintCollection::getSourceTableSubOne);
setBatchLikeQuery(param.getOriginId(), param.getOriginIds(), qw, ComplaintCollection::getOriginId);
setBatchLikeQuery(param.getCheckStatus(), param.getCheckStatusList(),qw, ComplaintCollection::getCheckStatus);
setBatchQuery(param.getSecondDepartId(), param.getSecondDepartIds(), qw, ComplaintCollection::getSecondDepartId);
setBatchQuery(param.getThirdDepartId(), param.getThirdDepartIds(), qw, ComplaintCollection::getThirdDepartId);
if (CollectionUtil.size(param.getDiscoveryTimeList()) == 2
&& param.getDiscoveryTimeList().get(0) != null
&& param.getDiscoveryTimeList().get(1) != null) {
qw.between(ComplaintCollection::getDiscoveryTime, param.getDiscoveryTimeList().get(0), param.getDiscoveryTimeList().get(1));
}
if (CollectionUtil.size(param.getCreateTimeList()) == 2){
qw.between(ComplaintCollection::getCreateTime, param.getCreateTimeList().get(0), param.getCreateTimeList().get(1));
}
// 来件人信息
if (StrUtil.isNotBlank(param.getPersonInfo())) {
String kw = param.getPersonInfo();
qw.and(w -> w.like(ComplaintCollection::getResponderName, kw).or().like(ComplaintCollection::getResponderPhone, kw).or().like(ComplaintCollection::getResponderIdCode, kw));
}
qw.eq(StrUtil.isNotBlank(param.getHandleMethod()), ComplaintCollection::getHandleMethod, param.getHandleMethod());
qw.like(StrUtil.isNotBlank(param.getThingDesc()), ComplaintCollection::getThingDesc, param.getThingDesc());
qw.eq(StrUtil.isNotBlank(param.getRepeatt()), ComplaintCollection::getRepeatt, param.getRepeatt());
qw.eq(StrUtil.isNotBlank(param.getLeadApproval()), ComplaintCollection::getLeadApproval, param.getLeadApproval());
qw.eq(StrUtil.isNotBlank(param.getProcessingStatus()), ComplaintCollection::getProcessingStatus, param.getProcessingStatus());
qw.eq(StrUtil.isNotBlank(param.getStatus()), ComplaintCollection::getStatus, param.getStatus());
qw.in(CollectionUtil.isNotEmpty(param.getInitialReviewFileList()), ComplaintCollection::getGwf3, param.getInitialReviewFileList());
// 来件内容
// 标签(表里如果是逗号字符串 tag="URGENT,NORMAL")
// 语义:命中任意一个标签即可(OR)
if (CollectionUtil.isNotEmpty(param.getTags())) {
qw.and(w -> {
boolean first = true;
for (String t : param.getTags()) {
if (StrUtil.isBlank(t)) continue;
if (first) {
w.apply("FIND_IN_SET({0}, tag)", t);
first = false;
} else {
w.or().apply("FIND_IN_SET({0}, tag)", t);
}
}
});
}
List<String> ids = param.getInvolveProblemIdList();
if (CollectionUtil.isNotEmpty(ids)) {
qw.and(w -> {
ids.forEach(id ->
w.or().apply("FIND_IN_SET({0}, involve_problem)", id)
);
});
}
// 排序
qw.orderByDesc(ComplaintCollection::getDiscoveryTime).orderByDesc(ComplaintCollection::getId);
return complaintCollectionMapper.selectPage(page, qw);
}
public List<ComplaintCollection> pageList(ComplaintCollectionQueryParam param) {
return pageQuery(param).getRecords();
}
public Boolean createComplaintCollection(List<ComplaintCollection> complaintCollectionList) {
innerBatchInsert(complaintCollectionMapper, complaintCollectionList, "添加失败!");
return Boolean.TRUE;
@ -234,8 +171,18 @@ public class ComplaintCollectionResourceService extends BaseDAO {
if (param.getTags() != null){
uw.set(ComplaintCollection::getTag, StringUtils.join(param.getTags(), ",") );
}
if (param.getNegativeId()!=null){
uw.set(ComplaintCollection::getNegativeId, param.getNegativeId());
}
if (param.getBlameSyncStatus()!=null){
uw.set(ComplaintCollection::getBlameSyncStatus, param.getBlameSyncStatus());
}
uw.set(ComplaintCollection::getUpdateBy, UserContextHolder.getCurrentUser().getUserName());
uw.set(ComplaintCollection::getUpdateTime, LocalDateTime.now());
uw.set(StrUtil.isNotBlank(param.getInitWorkDes()), ComplaintCollection::getInitWorkDes, param.getInitWorkDes());
uw.set(StrUtil.isNotBlank(param.getInitProblemPlan()), ComplaintCollection::getInitProblemPlan, param.getInitProblemPlan());
uw.set(StrUtil.isNotBlank(param.getInitVerdict()), ComplaintCollection::getInitVerdict, param.getInitVerdict());
uw.set(StrUtil.isNotBlank(param.getInitFile()), ComplaintCollection::getInitFile, param.getInitFile());
if (uw.getExpression() == null || uw.getExpression().getSqlSegment().isEmpty()) {
throw new IllegalStateException("更新条件不能为空,防止全表更新");
}

1
src/main/java/com/biutag/supervision/repository/mail/MailResourceService.java

@ -39,6 +39,7 @@ public class MailResourceService extends BaseDAO {
queryWrapper.eq(StrUtil.isNotBlank(param.getContactName()), Mail::getContactName, param.getContactName());
queryWrapper.eq(StrUtil.isNotBlank(param.getContactPhone()), Mail::getContactPhone, param.getContactPhone());
queryWrapper.eq(StrUtil.isNotBlank(param.getContent()), Mail::getContent, param.getContent());
queryWrapper.eq(StrUtil.isNotBlank(param.getMailState()), Mail::getMailState, param.getMailState());
if (!param.getMailTime().isEmpty() && param.getMailTime().size() >= 2) {
queryWrapper.between(Mail::getMailTime, param.getMailTime().get(0), param.getMailTime().get(1));
}

927
src/main/java/com/biutag/supervision/service/MailBoxCaptureService.java

@ -0,0 +1,927 @@
package com.biutag.supervision.service;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
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.constants.enums.ProcessingStatusEnum;
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;
import com.biutag.supervision.pojo.param.ComplaintCollection.ComplaintCollectionUpdateParam;
import com.biutag.supervision.pojo.param.MailQueryParam;
import com.biutag.supervision.pojo.param.SupDepartQueryParam;
import com.biutag.supervision.pojo.param.SupExternalDepartQueryParam;
import com.biutag.supervision.repository.complaintCollection.ComplaintCollectionResourceService;
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;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* @ClassName MailBoxCaptureService
* @Description 局长信箱数据抓取业务逻辑
* - 阶段1抓取来信创建 Negative 主表 + 来信附件 + ComplaintCollection
* - 阶段2同步办结后的涉及人和核查附件
* @Author shihao
* @Date 2026/4/28
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class MailBoxCaptureService {
private final NegativeService negativeService;
private final NegativeBlameService blameService;
private final NegativeProblemRelationService negativeProblemRelationService;
private final NegativeFileService fileService;
private final MailService mailService;
private final MailResourceService mailResourceService;
private final SupDepartResourceService supDepartResourceService;
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:抓取来信 ====================
/**
* 抓取来信并创建 ComplaintCollection Negative
*/
public void captureMayorMailbox(LocalDateTime start, LocalDateTime end) {
log.info("【局长信箱抓取新信件】时间范围 {} ~ {}", start, end);
long startTimeMillis = System.currentTimeMillis();
try {
// 1. 查询来信的信件
List<Mail> mailList = queryNewMails(start, end);
if (CollectionUtil.isEmpty(mailList)) {
log.warn("【局长信箱已办结抓取】未查询到任何投诉举报信件数据,任务结束");
return;
}
log.info("【局长信箱抓取新信件】查询到投诉举报信件信件数量:{}", mailList.size());
// 3. 遍历处理
int successCount = 0;
int skipCount = 0;
int failCount = 0;
for (Mail mail : mailList) {
try {
// 每条记录在独立事务中执行
boolean success = Boolean.TRUE.equals(transactionTemplate.execute(status -> {
return doCaptureSingleMail(mail);
}));
if (success) {
successCount++;
log.debug("【局长信箱抓取新信件】处理成功: mailId={}", mail.getId());
} else {
skipCount++;
log.debug("【局长信箱抓取新信件】处理跳过: mailId={}", mail.getId());
}
} catch (Exception e) {
failCount++;
log.error("【局长信箱抓取新信件】处理失败: mailId={}, error={}", mail.getId(), e.getMessage(), e);
}
}
// 4. 输出统计
long cost = System.currentTimeMillis() - startTimeMillis;
log.info("【局长信箱抓取新信件】完成,总数:{},成功:{},跳过:{},失败:{},耗时:{}ms",
mailList.size(), successCount, skipCount, failCount, cost);
} catch (Exception e) {
log.error("【局长信箱抓取新信件】任务执行过程中发生严重异常,任务中断", e);
throw e;
}
}
// ==================== 阶段2:同步涉及人、核查附件、核查情况 ====================
/**
* 同步办结后的涉及人和核查附件
*/
public void syncBlameAndFiles(LocalDateTime start, LocalDateTime end) {
log.info("【阶段2同步】时间范围 {} ~ {}", start, end);
long startTimeMillis = System.currentTimeMillis();
try {
// 1. 从 ComplaintCollection 查询局长信箱记录
List<ComplaintCollection> completedList = queryCompletedMailbox();
if (CollectionUtil.isEmpty(completedList)) {
log.warn("【阶段2同步】未查询到任何需要同步的数据,任务结束");
return;
}
log.info("【阶段2同步】查询到需要同步数量:{}", completedList.size());
// 2. 遍历处理(每条记录独立事务)
int successCount = 0;
int skipCount = 0;
int failCount = 0;
for (ComplaintCollection cc : completedList) {
try {
String originId = cc.getOriginId();
// 查询信件
MailQueryParam param = new MailQueryParam();
param.setId(originId);
param.setMailState("completion");
List<Mail> mailList = mailResourceService.query(param);
if (CollectionUtil.isEmpty(mailList)) {
log.info("【阶段2同步】无对应办结Mail:originId=" + originId);
continue;
}
Mail mail = mailList.get(0);
// 查询涉及人
LambdaQueryWrapper<MailBlame> mailBlameLambdaQueryWrapper = new LambdaQueryWrapper<>();
mailBlameLambdaQueryWrapper.eq(MailBlame::getMailId, mail.getId());
List<MailBlame> mailBlames = mailBlameMapper.selectList(mailBlameLambdaQueryWrapper);
// 构建 DTO
MailBoxSyncDto dto = new MailBoxSyncDto();
dto.setCc(cc);
dto.setMail(mail);
dto.setMailBlames(mailBlames);
// 每条记录在独立事务中执行
boolean success = Boolean.TRUE.equals(transactionTemplate.execute(status -> {
return doSyncSingleRecord(dto);
}));
if (success) {
successCount++;
log.debug("【阶段2同步】处理成功: ccId={}", cc.getId());
} else {
skipCount++;
log.debug("【阶段2同步】处理跳过: ccId={}", cc.getId());
}
} catch (Exception e) {
failCount++;
log.error("【阶段2同步】处理失败: ccId={}, error={}", cc.getId(), e.getMessage(), e);
}
}
// 3. 输出统计
long cost = System.currentTimeMillis() - startTimeMillis;
log.info("【阶段2同步】完成,总数:{},成功:{},跳过:{},失败:{},耗时:{}ms",
completedList.size(), successCount, skipCount, failCount, cost);
} catch (Exception e) {
log.error("【阶段2同步】任务执行过程中发生严重异常,任务中断", e);
throw e;
}
}
// ==================== 查询相关 ====================
/**
* ComplaintCollection 查询局长信箱记录
*/
private List<ComplaintCollection> queryCompletedMailbox() {
ComplaintCollectionQueryParam param = new ComplaintCollectionQueryParam();
param.setSourceTable(ComplaintCollectionSourceTableEnum.MAYOR_MAILBOX.getCode());
param.setBlameSyncStatus("0"); // 未同步
return complaintCollectionResourceService.query(param);
}
/**
* 查询来信时间范围内的信件按来信时间查询
*/
private List<Mail> queryNewMails(LocalDateTime start, LocalDateTime end) {
LambdaQueryWrapper<Mail> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(Mail::getMailLevel, "涉警投诉");
queryWrapper.between(Mail::getMailTime, start, end);
return mailService.list(queryWrapper);
}
/**
* 判重检查检查是否已处理
*/
private boolean isAlreadyProcessed(Mail mail) {
boolean exists = negativeService.exists(mail.getId());
if (exists) {
log.debug("【局长信箱已办结抓取】跳过(已处理): mailId={}", mail.getId());
}
return exists;
}
// ==================== 单位查询 ====================
/**
* 根据外部单位ID查询单位实体外部ID -> 内部ID -> 部门实体
*
* @return 部门实体找不到时返回 null由调用方决定如何处理
*/
private SupDepart getDepartByExternalId(Integer externalId) {
if (externalId == null) {
log.warn("【局长信箱已办结抓取】外部单位ID为空");
return null;
}
// 1. 通过外部ID查询映射表,获取内部ID
SupExternalDepart externalDepart = findExternalDepart(externalId);
if (externalDepart == null) {
log.warn("【局长信箱已办结抓取】未找到SupExternalDepart映射,externalId={}", externalId);
return null;
}
String internalId = externalDepart.getInternalId();
if (StrUtil.isBlank(internalId)) {
log.warn("【局长信箱已办结抓取】SupExternalDepart.internalId为空,externalId={}", externalId);
return null;
}
// 2. 通过内部ID查询部门实体
SupDepart depart = findDepartById(internalId);
if (depart == null) {
log.warn("【局长信箱已办结抓取】未找到单位,internalId={}", internalId);
return null;
}
return depart;
}
/**
* 根据外部ID查询单位映射
*
* @return 单位映射找不到时返回 null
*/
private SupExternalDepart findExternalDepart(Integer externalId) {
SupExternalDepartQueryParam queryParam = new SupExternalDepartQueryParam();
queryParam.setSource("局长信箱");
queryParam.setExternalIds(Collections.singleton(String.valueOf(externalId)));
List<SupExternalDepart> list = supExternalDepartResourceService.query(queryParam);
if (CollectionUtil.isEmpty(list)) {
return null;
}
return list.get(0);
}
/**
* 根据内部ID查询部门
*/
private SupDepart findDepartById(String id) {
SupDepartQueryParam queryParam = new SupDepartQueryParam();
queryParam.setId(id);
List<SupDepart> list = supDepartResourceService.query(queryParam);
if (CollectionUtil.isEmpty(list)) {
return null;
}
return list.get(0);
}
// ==================== 阶段1 抓取方法 ====================
/**
* 单条记录的抓取逻辑独立事务执行
*/
public boolean doCaptureSingleMail(Mail mail) {
// 1. 判重检查
if (isAlreadyProcessed(mail)) {
return false;
}
// 2. 查询单位信息
SupDepart secondDepart = getDepartByExternalId(mail.getSecondDeptId());
SupDepart thirdDepart = getDepartByExternalId(mail.getThreeDeptId());
// 2.1 如果单位信息获取失败,抛出异常触发回滚
if (secondDepart == null || thirdDepart == null) {
throw new RuntimeException("单位映射缺失: mailId=" + mail.getId());
}
// 3. 构建并保存 Negative(阶段1:主表 + 来信附件)
NegativeDataOnlyDto dto = buildNegativeDto(mail, secondDepart, thirdDepart);
Negative negative = negativeService.saveNegativeMain(dto);
negativeService.saveThingFiles(dto, negative.getId());
// 4. 保存 ComplaintCollection
ComplaintCollection cc = buildComplaintCollection(mail, negative.getId(), secondDepart, thirdDepart);
complaintCollectionResourceService.saveOrUpdateComplaintCollection(Collections.singletonList(cc));
return true;
}
// ==================== 阶段2 同步方法 ====================
/**
* 单条记录的同步逻辑独立事务执行
*/
private boolean doSyncSingleRecord(MailBoxSyncDto dto) {
ComplaintCollection cc = dto.getCc();
Mail mail = dto.getMail();
List<MailBlame> mailBlames = dto.getMailBlames();
// 1. 通过 originId 找到对应的 Negative(只有阶段1创建过的才同步)
Negative negative = negativeService.getByOriginId(cc.getOriginId());
if (negative == null) {
log.warn("【阶段2同步】无对应Negative,跳过: originId={}", cc.getOriginId());
return false;
}
// 2. 组装数据并保存
syncBlame(mail, negative.getId(), mailBlames);
syncFiles(mail, negative.getId());
// 3. 同步核查情况到 Negative
syncCheckStatus(mail, negative);
// 4. 更新同步标记(所有同步操作成功后)
updateSyncTag(cc);
return true;
}
/**
* 同步涉及人
*/
private List<NegativeBlame> syncBlame(Mail mail, String negativeId, List<MailBlame> mailBlames) {
// 幂等性检查:已存在则跳过
LambdaQueryWrapper<NegativeBlame> existWrapper = new LambdaQueryWrapper<>();
existWrapper.eq(NegativeBlame::getNegativeId, negativeId);
if (blameService.count(existWrapper) > 0) {
log.info("【阶段2同步】涉及人已存在,跳过: negativeId={}", negativeId);
return Collections.emptyList();
}
// mailBlames 已由调用方在事务外查询好
if (CollectionUtil.isEmpty(mailBlames)) {
return Collections.emptyList();
}
List<NegativeBlame> result = new ArrayList<>();
for (MailBlame blame : mailBlames) {
// 通过姓名+警号查询 SupPolice 获取完整信息
LambdaQueryWrapper<SupPolice> supPoliceLambdaQueryWrapper = new LambdaQueryWrapper<>();
supPoliceLambdaQueryWrapper.eq(SupPolice::getIdCode, blame.getBlameIdCode());
supPoliceLambdaQueryWrapper.last("limit 1");
SupPolice police = supPoliceService.getOne(supPoliceLambdaQueryWrapper);
if (Objects.isNull(police)) {
log.warn("【阶段2同步】未找到该警员的数据! blameName={}, blameEmpNo={}", blame.getBlameName(), blame.getBlameEmpNo());
continue;
}
NegativeBlame negativeBlame = new NegativeBlame();
negativeBlame.setBlameId(IdUtil.getSnowflakeNextIdStr());
negativeBlame.setNegativeId(negativeId);
negativeBlame.setType("personal");
negativeBlame.setBlameEmpNo(police.getEmpNo());
negativeBlame.setBlameIdCode(police.getIdCode());
negativeBlame.setBlameName(police.getName());
negativeBlame.setCrtTime(LocalDateTime.now());
negativeBlame.setUpdTime(LocalDateTime.now());
negativeBlame.setLeadEmpNo(blame.getLeaderEmpNo());
negativeBlame.setLeadName(blame.getLeaderName());
negativeBlame.setLeadIdCode(blame.getLeaderIdCode());
negativeBlame.setIvPersonType(police.getPersonType());
// 责任追究映射
if (StrUtil.isNotBlank(blame.getVerifyPunish())) {
try {
List<String> externalNames = JSON.parseArray(blame.getVerifyPunish(), String.class);
List<SupDictHandleResultMaping> dictHandleResultMapings = dictHandleResultMapingService.list(externalNames);
negativeBlame.setHandleResultCode(
dictHandleResultMapings.stream()
.map(SupDictHandleResultMaping::getInternalId)
.collect(Collectors.joining(","))
);
negativeBlame.setHandleResultName(
dictHandleResultMapings.stream()
.map(SupDictHandleResultMaping::getInternalName)
.collect(Collectors.joining("、"))
);
} catch (Exception e) {
log.warn("【阶段2同步】责任追究映射失败: verifyPunish={}", blame.getVerifyPunish(), e);
}
}
// 查证属实问题映射 - 创建 NegativeProblemRelation
if (StrUtil.isNotBlank(blame.getVerifyProblem())) {
try {
List<String> externalNames = JSON.parseArray(blame.getVerifyProblem(), String.class);
List<SupDictProblemTypeMaping> problemTypeMapings = dictProblemTypeMapingService.list(externalNames);
for (SupDictProblemTypeMaping problemTypeMaping : problemTypeMapings) {
SupDictProblemType threeProblem = problemTypeService.getById(problemTypeMaping.getInternalId());
if (threeProblem == null) {
log.warn("【阶段2同步】未找到三级问题类型: internalId={}", problemTypeMaping.getInternalId());
continue;
}
NegativeProblemRelation problemRelation = new NegativeProblemRelation();
problemRelation.setBlameId(negativeBlame.getBlameId());
problemRelation.setNegativeId(negativeId);
problemRelation.setThreeLevelCode(threeProblem.getId());
problemRelation.setThreeLevelContent(threeProblem.getName());
// 二级
String parentCode = threeProblem.getParentCode();
SupDictProblemType twoProblem = null;
if (StrUtil.isNotBlank(parentCode)) {
twoProblem = problemTypeService.getById(parentCode);
if (twoProblem != null) {
problemRelation.setTwoLevelCode(twoProblem.getId());
problemRelation.setTwoLevelContent(twoProblem.getName());
}
}
// 一级
if (twoProblem != null) {
String twoParentCode = twoProblem.getParentCode();
if (StrUtil.isNotBlank(twoParentCode)) {
SupDictProblemType oneProblem = problemTypeService.getById(twoParentCode);
if (oneProblem != null) {
problemRelation.setOneLevelCode(oneProblem.getId());
problemRelation.setOneLevelContent(oneProblem.getName());
}
}
}
negativeProblemRelationService.save(problemRelation);
}
} catch (Exception e) {
log.warn("【阶段2同步】查证属实问题映射失败: verifyProblem={}", blame.getVerifyProblem(), e);
}
}
// 保存 NegativeBlame
blameService.save(negativeBlame);
result.add(negativeBlame);
log.debug("【阶段2同步】保存涉及人: negativeId={}, blameName={}", negativeId, negativeBlame.getBlameName());
}
return result;
}
/**
* 同步核查情况Mail 表的核查字段 -> Negative
*/
private void syncCheckStatus(Mail mail, Negative negative) {
String checkStatus = null;
String checkStatusName = null;
String checkStatusCode = null;
// 核查情况映射
String verifyIsTrue = mail.getVerifyIsTrue();
if ("属实".equals(verifyIsTrue)) {
checkStatus = "1";
checkStatusName = "属实";
checkStatusCode = "1";
} else if ("基本属实".equals(verifyIsTrue)) {
checkStatus = "2";
checkStatusName = "部分属实";
checkStatusCode = "2";
} else if ("不属实".equals(verifyIsTrue)) {
checkStatus = "3";
checkStatusName = "不属实";
checkStatusCode = "5";
}
// 核查结论(优先 verifyDetails,其次 completionComment)
String checkStatusDesc = null;
if (StrUtil.isNotBlank(mail.getVerifyDetails())) {
checkStatusDesc = mail.getVerifyDetails();
} else if (StrUtil.isNotBlank(mail.getCompletionComment())) {
checkStatusDesc = mail.getCompletionComment();
}
// 只有存在核查情况时才更新
if (checkStatus != null) {
// 防御编程:使用 updateById 确保只更新单条记录
negative.setCheckStatus(checkStatus);
negative.setCheckStatusName(checkStatusName);
negative.setCheckStatusDesc(checkStatusDesc);
negative.setCheckStatusCode(checkStatusCode);
negative.setProcessingStatus(ProcessingStatusEnum.completed.name());
boolean updated = negativeService.updateById(negative);
if (updated) {
log.debug("【阶段2同步】更新核查情况: negativeId={}, checkStatus={}, checkStatusDesc={}",
negative.getId(), checkStatus, checkStatusDesc);
} else {
log.warn("【阶段2同步】更新核查情况失败,Negative不存在或已被删除: negativeId={}", negative.getId());
}
}
}
/**
* 同步涉及人MailBlame -> NegativeBlame组装并保存
* 参照 MailService#saveMailbox for 循环逻辑
*/
/**
* 同步核查附件Mail.verifyAttachments -> NegativeFile组装并保存
*/
private void syncFiles(Mail mail, String negativeId) {
if (StrUtil.isBlank(mail.getVerifyAttachments())) {
return;
}
List<MailAttachmentDTO> attachments = JSON.parseArray(mail.getVerifyAttachments(), MailAttachmentDTO.class);
if (CollectionUtil.isEmpty(attachments)) {
return;
}
// 幂等性检查:如果该 Negative 已有附件,直接跳过
long existingCount = fileService.count(
new LambdaQueryWrapper<NegativeFile>().eq(NegativeFile::getNegtiveId, negativeId)
);
if (existingCount > 0) {
log.info("【阶段2同步】附件已存在,跳过: negativeId={}", negativeId);
return;
}
for (MailAttachmentDTO att : attachments) {
NegativeFile file = new NegativeFile();
file.setFileId(IdUtil.getSnowflakeNextIdStr());
file.setNegtiveId(negativeId);
file.setFileName(StrUtil.isNotBlank(att.getOriginFilename()) ? att.getOriginFilename() : getFileName(att.getFilepath()));
file.setFilePath(buildFileUrl(att));
file.setCrtTime(LocalDateTime.now());
fileService.save(file);
log.debug("【阶段2同步】保存核查附件: negativeId={}, fileName={}", negativeId, file.getFileName());
}
}
/**
* 更新同步标记所有同步操作成功后
*
* @param cc
*/
private void updateSyncTag(ComplaintCollection cc) {
ComplaintCollectionUpdateParam complaintCollectionUpdateParam = new ComplaintCollectionUpdateParam();
complaintCollectionUpdateParam.setId(cc.getId());
complaintCollectionUpdateParam.setBlameSyncStatus("1");
boolean updated = complaintCollectionResourceService.updateSelectiveById(complaintCollectionUpdateParam);
if (!updated) {
throw new RuntimeException("更新blameSyncStatus失败: ccId=" + cc.getId());
}
}
/**
* 构建文件完整URL
*/
private String buildFileUrl(MailAttachmentDTO att) {
String filepath = null;
if (StrUtil.isNotBlank(att.getDocxFilepath())) {
filepath = "http://65.47.60.145/lan-api/api/file/stream/" + att.getDocxFilepath();
} else if (StrUtil.isNotBlank(att.getFilepath())) {
filepath = "http://65.47.60.145/lan-api/api/file/stream/" + att.getFilepath();
}
return filepath;
}
// ==================== 组装 ====================
/**
* 构建 NegativeDataOnlyDto
*/
private NegativeDataOnlyDto buildNegativeDto(Mail mail, SupDepart secondDepart, SupDepart thirdDepart) {
NegativeDataOnlyDto dto = new NegativeDataOnlyDto();
// 基础字段
dto.setOriginId(mail.getId());
dto.setDiscoveryTime(mail.getMailTime());
// 创建时间以来信时间为准
dto.setCrtTime(mail.getMailTime());
dto.setProblemSourcesCode(ProblemSourcesEnum.JZXX.getValue());
dto.setProblemSources(ProblemSourcesEnum.JZXX.getLabel());
// 业务类型(其他)
dto.setBusinessTypeCode(BusinessTypeEnum.QT.getValue());
dto.setBusinessTypeName(BusinessTypeEnum.QT.getLabel());
// 追责对象(涉及个人)
dto.setAccountabilityTarget(AccountabilityTargetEnum.PERSONAL.getValue());
// 反映人信息
dto.setResponderName(mail.getContactName());
dto.setContactPhone(mail.getContactPhone());
// 办理状态(已完成)
dto.setProcessingStatus("completed");
// 来信内容
dto.setThingDesc(mail.getContent());
// 涉及单位设置
dto.setInvolveDepartId(thirdDepart.getId());
dto.setInvolveDepartName(thirdDepart.getName());
// 办理单位设置
dto.setHandleSecondDepartId(secondDepart.getId());
dto.setHandleSecondDepartName(secondDepart.getName());
dto.setHandleThreeDepartId(thirdDepart.getId());
dto.setHandleThreeDepartName(thirdDepart.getName());
// 来信附件
dto.setThingFiles(buildThingFiles(mail.getAttachments()));
// 来源字段
dto.setSourceType(NegativeSourceTypeEnum.COMPLAINT_REPORT.getCode());
dto.setSourceTypeDesc(NegativeSourceTypeEnum.COMPLAINT_REPORT.getDesc());
// dto.setIssuingDepartId("-1");
// dto.setIssuingDepartName("自定抓取");
return dto;
}
/**
* 构建问题附件列表
*/
private List<NegativeThingFile> buildThingFiles(String attachmentsJson) {
List<MailAttachmentDTO> attachments = parseAttachments(attachmentsJson);
if (CollectionUtil.isEmpty(attachments)) {
return Collections.emptyList();
}
List<NegativeThingFile> list = new ArrayList<>();
for (MailAttachmentDTO att : attachments) {
NegativeThingFile file = new NegativeThingFile();
file.setFileName(StrUtil.isNotBlank(att.getOriginFilename()) ? att.getOriginFilename() : getFileName(att.getFilepath()));
file.setFilePath(att.getFilepath());
file.setCreateTime(LocalDateTime.now());
list.add(file);
}
return list;
}
/**
* 解析附件 JSON
*/
private List<MailAttachmentDTO> parseAttachments(String json) {
if (StrUtil.isBlank(json)) {
return Collections.emptyList();
}
try {
List<MailAttachmentDTO> list = JSON.parseArray(json, MailAttachmentDTO.class);
list.forEach(item -> {
String filepath = null;
if (StrUtil.isNotBlank(item.getDocxFilepath())) {
filepath = "http://65.47.60.145/lan-api/api/file/stream/" + item.getDocxFilepath();
} else {
filepath = "http://65.47.60.145/lan-api/api/file/stream/" + item.getFilepath();
}
item.setFilepath(filepath);
});
return list;
} catch (Exception e) {
log.warn("【局长信箱已办结抓取】附件JSON解析失败,json={}", json, e);
return Collections.emptyList();
}
}
/**
* 从路径获取文件名
*/
private String getFileName(String path) {
if (path == null) return null;
int index = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\'));
return index == -1 ? path : path.substring(index + 1);
}
// ==================== ComplaintCollection 组装 ====================
/**
* 构建 ComplaintCollection
*/
private ComplaintCollection buildComplaintCollection(Mail mail, String negativeId, SupDepart secondDepart, SupDepart thirdDepart) {
ComplaintCollection cc = new ComplaintCollection();
// 设置问题编号
cc.setNegativeId(negativeId);
cc.setOriginId(mail.getId());
// 问题来源信息
String sfssSourceTableSubOne = getSfssSourceTableSubOne(mail.getSource());
cc.setSourceTable(ComplaintCollectionSourceTableEnum.MAYOR_MAILBOX.getCode());
cc.setSourceTableSubOne(sfssSourceTableSubOne);
// 单位信息
cc.setSecondDepartId(secondDepart.getId());
cc.setSecondDepartName(secondDepart.getShortName());
cc.setThirdDepartId(thirdDepart.getId());
cc.setThirdDepartName(thirdDepart.getShortName());
// 创建时间用来信时间
cc.setCreateTime(mail.getMailTime());
cc.setCreateBy("自动抓取");
// 身份证
cc.setResponderIdCode(mail.getContactIdCard());
// 初核信息
cc.setGwf3(ComplaintCollectionInitialEnum.UN_UPLOADED.getCode());
return cc;
}
private String getSfssSourceTableSubOne(String str) {
if ("厅长信箱".equals(str)) {
return "23_tz";
}
if ("mailbox".equals(str)) {
return "23_jz";
}
if ("110_report_complaints".equals(str)) {
return "23_jb";
}
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);
}
}

201
src/main/java/com/biutag/supervision/service/NegativeService.java

@ -23,13 +23,17 @@ import com.biutag.supervision.pojo.domain.CountersignApply;
import com.biutag.supervision.pojo.domain.NegativeDetail;
import com.biutag.supervision.pojo.domain.NegativeVo;
import com.biutag.supervision.pojo.dto.ActionDto;
import com.biutag.supervision.pojo.dto.NegativeDataOnlyDto;
import com.biutag.supervision.pojo.dto.NegativeDto;
import com.biutag.supervision.pojo.dto.complaintCollection.ComplaintCollectionPageDTO;
import com.biutag.supervision.pojo.dto.flow.FirstDistributeData;
import com.biutag.supervision.pojo.dto.flow.VerifyData;
import com.biutag.supervision.pojo.dto.jwdc.NegativeApiDto;
import com.biutag.supervision.pojo.entity.*;
import com.biutag.supervision.pojo.model.UserAuth;
import com.biutag.supervision.pojo.request.complaintCollection.ComplaintCollectionPageRequest;
import com.biutag.supervision.pojo.vo.NegativeFileVo;
import com.biutag.supervision.service.complaintCollection.ComplaintCollectionService;
import com.biutag.supervision.util.SpringUtil;
import com.biutag.supervision.util.TimeUtil;
import lombok.RequiredArgsConstructor;
@ -179,11 +183,13 @@ public class NegativeService extends ServiceImpl<NegativeMapper, Negative> {
// 单位会签
detail.setCountersignApplys(countersignApplyService.list(id));
enrichCountersignsWithHistory(detail);
// 初核情况
initDes(detail);
return detail;
}
public Negative getByOriginId(String originId) {
return getOne(new LambdaUpdateWrapper<Negative>().eq(Negative::getOriginId, originId));
return getOne(new LambdaQueryWrapper<Negative>().eq(Negative::getOriginId, originId).last("LIMIT 1"));
}
private final SupDictDataService dictDataService;
@ -483,6 +489,199 @@ public class NegativeService extends ServiceImpl<NegativeMapper, Negative> {
}
}
@Transactional(rollbackFor = Exception.class)
public void updateNegative(NegativeDto negativeDto) {
if (StrUtil.isBlank(negativeDto.getId())) {
throw new RuntimeException("数据异常,请系统联系管理员【问题ID为空】");
}
LambdaUpdateWrapper<Negative> updateWrapper = new LambdaUpdateWrapper<>();
// 涉及单位
SupDepart depart = departService.getById(negativeDto.getInvolveDepartId());
if (DepartLevelEnum.SECOND.getValue().equals(depart.getLevel())) {
updateWrapper.set(Negative::getSecondInvolveDepartId, depart.getId())
.set(Negative::getThreeInvolveDepartId, null);
} else if (DepartLevelEnum.THREE.getValue().equals(depart.getLevel())) {
updateWrapper.set(Negative::getSecondInvolveDepartId, depart.getPid())
.set(Negative::getThreeInvolveDepartId, depart.getId());
} else {
throw new RuntimeException("涉及单位请选择二级或三级单位");
}
updateWrapper.eq(Negative::getId, negativeDto.getId())
.set(Negative::getProblemSources, negativeDto.getProblemSources())
.set(Negative::getProblemSourcesCode, negativeDto.getProblemSourcesCode())
.set(Negative::getBusinessTypeCode, negativeDto.getBusinessTypeCode())
.set(StrUtil.isNotBlank(negativeDto.getBusinessTypeName()), Negative::getBusinessTypeName, negativeDto.getBusinessTypeName())
.set(Negative::getCaseNumber, negativeDto.getCaseNumber())
.set(Negative::getInvolveProblem, com.biutag.supervision.util.JSON.toJSONString(negativeDto.getInvolveProblem()))
.set(Negative::getPoliceType, negativeDto.getPoliceType())
.set(Negative::getPoliceTypeName, negativeDto.getPoliceTypeName())
.set(Negative::getDiscoveryTime, negativeDto.getDiscoveryTime())
.set(Negative::getHappenTime, negativeDto.getHappenTime())
.set(Negative::getResponderName, negativeDto.getResponderName())
.set(Negative::getContactPhone, negativeDto.getContactPhone())
.set(Negative::getThingDesc, negativeDto.getThingDesc())
.set(Negative::getSpecialSupervision, negativeDto.getSpecialSupervision())
.set(Negative::getReportNumber, negativeDto.getReportNumber())
.set(StrUtil.isNotEmpty(negativeDto.getReportId()),Negative::getReportId,negativeDto.getReportId())
.set(Negative::getInvolveDepartId, negativeDto.getInvolveDepartId())
.set(Negative::getInvolveDepartName, depart.getShortName())
// 涉嫌问题
.set(Negative::getInvolveProblem, CollectionUtil.isNotEmpty(negativeDto.getInvolveProblem()) ? String.join(",", negativeDto.getInvolveProblem()) : null)
.set(Negative::getUpdUser, UserContextHolder.getCurrentUser().getNickName())
.set(Negative::getUpdTime, LocalDateTime.now());
if (CollectionUtil.isNotEmpty(negativeDto.getInvolveProblem())) {
updateWrapper.set(Negative::getInvolveProblem, String.join(",", negativeDto.getInvolveProblem()));
} else {
updateWrapper.set(Negative::getInvolveProblem, null);
}
update(updateWrapper);
// 更新问题来源
workService.update(new LambdaUpdateWrapper<NegativeWork>().set(NegativeWork::getProblemSourcesCode, negativeDto.getProblemSourcesCode()).eq(NegativeWork::getNegativeId, negativeDto.getId()));
}
private void initDes(NegativeDetail detail) {
NegativeVo negative = detail.getNegative();
ComplaintCollectionPageRequest complaintCollectionPageRequest = new ComplaintCollectionPageRequest();
complaintCollectionPageRequest.setOriginId(negative.getOriginId());
// 使用 SpringUtil 延迟获取,打破循环依赖
ComplaintCollectionService service = SpringUtil.getBean(ComplaintCollectionService.class);
List<ComplaintCollectionPageDTO> records = service.getComplaintCollectionPagNotAuth(complaintCollectionPageRequest).getRecords();
if (CollectionUtil.isEmpty(records)) {
return;
}
ComplaintCollectionPageDTO complaintCollectionPageDTO = records.get(0);
detail.setComplaintCollectionPageDTO(complaintCollectionPageDTO);
}
/**
* 保存主表数据
*
* @param dto 保存参数
* @return 保存的Negative实体
*/
public Negative saveNegativeMain(NegativeDataOnlyDto dto) {
Negative negative = new Negative();
BeanUtil.copyProperties(dto, negative);
if (StrUtil.isBlank(negative.getId())) {
negative.setId(IdUtil.getSnowflakeNextIdStr());
}
LocalDateTime now = LocalDateTime.now();
if (negative.getCrtTime() == null) {
negative.setCrtTime(now);
}
if (negative.getUpdTime() == null) {
negative.setUpdTime(now);
}
// 处理涉及单位层级
if (StrUtil.isNotBlank(dto.getInvolveDepartId()) && StrUtil.isBlank(negative.getSecondInvolveDepartId()) && StrUtil.isBlank(negative.getThreeInvolveDepartId())) {
SupDepart depart = departService.getById(dto.getInvolveDepartId());
if (depart != null) {
if (DepartLevelEnum.SECOND.getValue().equals(depart.getLevel())) {
negative.setSecondInvolveDepartId(depart.getId());
negative.setThreeInvolveDepartId(null);
} else if (DepartLevelEnum.THREE.getValue().equals(depart.getLevel())) {
negative.setThreeInvolveDepartId(depart.getId());
negative.setSecondInvolveDepartId(depart.getPid());
}
}
}
// 处理列表字段转字符串
if (CollectionUtil.isNotEmpty(dto.getInvolveProblem())) {
negative.setInvolveProblem(String.join(",", dto.getInvolveProblem()));
}
if (CollectionUtil.isNotEmpty(dto.getProblems())) {
negative.setProblems(JSON.toJSONString(dto.getProblems()));
}
save(negative);
return negative;
}
/**
* 保存来信附件
*/
public void saveThingFiles(NegativeDataOnlyDto dto, String negativeId) {
if (dto.getThingFiles().isEmpty()) {
return;
}
LocalDateTime now = LocalDateTime.now();
List<NegativeThingFile> files = dto.getThingFiles().stream().map(item -> {
NegativeThingFile negativeThingFile = new NegativeThingFile();
BeanUtil.copyProperties(item, negativeThingFile);
negativeThingFile.setNegativeId(negativeId);
if (negativeThingFile.getCreateTime() == null) {
negativeThingFile.setCreateTime(now);
}
return negativeThingFile;
}).toList();
thingFileService.saveBatch(files);
}
/**
* 保存涉及人
*/
public void saveBlames(NegativeDataOnlyDto dto, String negativeId) {
if (dto.getBlames().isEmpty()) {
return;
}
LocalDateTime now = LocalDateTime.now();
List<NegativeBlame> blames = dto.getBlames().stream().map(item -> {
NegativeBlame blame = new NegativeBlame();
BeanUtil.copyProperties(item, blame);
blame.setNegativeId(negativeId);
if (blame.getCrtTime() == null) {
blame.setCrtTime(now);
}
return blame;
}).toList();
blameService.saveBatch(blames);
}
/**
* 保存核查附件
*/
public void saveFiles(NegativeDataOnlyDto dto, String negativeId) {
if (dto.getFiles().isEmpty()) {
return;
}
LocalDateTime now = LocalDateTime.now();
List<NegativeFile> files = dto.getFiles().stream().map(item -> {
NegativeFile file = new NegativeFile();
BeanUtil.copyProperties(item, file);
file.setNegtiveId(negativeId);
if (file.getCrtTime() == null) {
file.setCrtTime(now);
}
return file;
}).toList();
fileService.saveBatch(files);
}
/**
* 纯数据保存 - 不触发工作流和历史记录
* 兼容旧方法内部调用拆分的4个方法
*
* @param dto 保存参数
* @return 保存的Negative实体
*/
@Transactional(rollbackFor = Exception.class)
public Negative saveDataOnly(NegativeDataOnlyDto dto) {
Negative negative = saveNegativeMain(dto);
saveThingFiles(dto, negative.getId());
saveBlames(dto, negative.getId());
saveFiles(dto, negative.getId());
return negative;
}
}

57
src/main/java/com/biutag/supervision/service/complaintCollection/ComplaintCollectionService.java

@ -1,10 +1,11 @@
package com.biutag.supervision.service.complaintCollection;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.biutag.supervision.pojo.Result;
import com.biutag.supervision.pojo.dto.complaintCollection.ComplaintCollectionPageDTO;
import com.biutag.supervision.pojo.request.complaintCollection.*;
import com.biutag.supervision.pojo.vo.complaintCollection.ComplaintCollectionHandlerDataVo;
import com.biutag.supervision.pojo.vo.complaintCollection.ComplaintCollectionDetailVo;
import com.biutag.supervision.pojo.vo.complaintCollection.ComplaintCollectionMailRepeattVo;
import com.biutag.supervision.pojo.vo.complaintCollection.ComplaintCollectionPageVo;
import com.biutag.supervision.pojo.vo.complaintCollection.ComplaintCollectionWatchDetailVO;
import jakarta.servlet.http.HttpServletResponse;
@ -16,13 +17,21 @@ import jakarta.servlet.http.HttpServletResponse;
* @Date 2025/12/23 17:24
*/
public interface ComplaintCollectionService {
/**
* 涉访涉诉分页
* 涉访涉诉分页不使用附件查询
*
* @param request
* @return
*/
Result<ComplaintCollectionPageVo> getComplaintCollectionPage(ComplaintCollectionPageRequest request);
Page<ComplaintCollectionPageDTO> getComplaintCollectionPageNew(ComplaintCollectionPageRequest request);
/**
* 不鉴权
*/
Page<ComplaintCollectionPageDTO> getComplaintCollectionPagNotAuth(ComplaintCollectionPageRequest request);
/**
* 涉访涉诉添加
@ -47,53 +56,49 @@ public interface ComplaintCollectionService {
*/
Result<Boolean> updateComplaintCollection(ComplaintCollectionUpdateRequest request);
/**
* 添加涉访涉诉责任人
* @param request
* @return
*/
Result<Boolean> addComplaintCollectionBlame(ComplaintCollectionAndBlameAddRequest request);
/**
* 查看详情
* 是否重复件
* @param request
* @return
*/
Result<ComplaintCollectionWatchDetailVO> watchDetail(ComplaintCollectionWatchDetailRequest request);
Result<ComplaintCollectionMailRepeattVo> maileRepeatt(ComplaintCollectionMailRepeattRequest request);
/**
* 是否重复件
* 数据导出
* @param request
* @param response
* @return
*/
Result<ComplaintCollectionMailRepeattVo> maileRepeatt(ComplaintCollectionMailRepeattRequest request);
void exportData(ComplaintCollectionPageRequest request, HttpServletResponse response);
/**
* 办理详情
* 办理页面保存保存临时办理信息
* @param request
* @return
*/
Result<ComplaintCollectionHandlerDataVo> handlerData(ComplaintCollectionHandlerDataRequest request);
Result<Boolean> saveInvolveJson(ComplaintCollectionInitialReviewSaveRequest request);
/**
* 数据导出
* 初核反馈
* @param request
* @param response
* @return
*/
void exportData(ComplaintCollectionPageRequest request, HttpServletResponse response);
Result<Boolean> initialReview(ComplaintCollectionInitialReviewRequest request);
/**
* 办理页面保存
* 查询详情用于修改弹窗数据回显
* @param request
* @return
*/
Result<Boolean> saveInvolveJson(ComplaintCollectionSaveInvolveJsonRequest request);
Result<ComplaintCollectionDetailVo> getComplaintCollectionDetail(ComplaintCollectionDetailRequest request);
void moveNegativeTemp(ComplaintCollectionPageRequest request);
void addNegativeTemp(ComplaintCollectionPageRequest request);
/**
* 强制终结
* @param request
* @return
* 迁移局长信箱历史数据到 Negative
* 参照 captureMayorMailbox 逻辑直接保存processingStatus=completed不触发下发流程
*/
Result<Boolean> forceTermination(ComplaintCollectionForceTerminationRequest request);
void migrateMayorMailboxNegative(ComplaintCollectionPageRequest request);
}

1635
src/main/java/com/biutag/supervision/service/complaintCollection/ComplaintCollectionServiceImpl.java

File diff suppressed because it is too large Load Diff

104
src/main/java/com/biutag/supervision/util/CheckUtil.java

@ -0,0 +1,104 @@
package com.biutag.supervision.util;
import cn.hutool.core.util.StrUtil;
/**
* 参数校验工具类
* 用于统一校验请求参数中的字符串校验失败抛出 IllegalArgumentException
*/
public class CheckUtil {
/**
* 校验字符串不能为 null 或纯空白字符
*
* @param str 待校验字符串
* @param message 异常信息
* @throws IllegalArgumentException 如果字符串为 null 或空白
*/
public static void checkNotBlank(String str, String message) {
if (StrUtil.isBlank(str)) {
throw new IllegalArgumentException(message);
}
}
/**
* 校验字符串不能为 null允许空字符串
*
* @param str 待校验字符串
* @param message 异常信息
* @throws IllegalArgumentException 如果字符串为 null
*/
public static void checkNotNull(String str, String message) {
if (str == null) {
throw new IllegalArgumentException(message);
}
}
/**
* 校验字符串长度不能超过指定最大值
*
* @param str 待校验字符串
* @param max 最大长度
* @param message 异常信息
* @throws IllegalArgumentException 如果字符串长度超过 max
*/
public static void checkMaxLength(String str, int max, String message) {
if (str != null && str.length() > max) {
throw new IllegalArgumentException(message);
}
}
/**
* 校验字符串长度不能小于指定最小值
*
* @param str 待校验字符串
* @param min 最小长度
* @param message 异常信息
* @throws IllegalArgumentException 如果字符串长度小于 min
*/
public static void checkMinLength(String str, int min, String message) {
if (str != null && str.length() < min) {
throw new IllegalArgumentException(message);
}
}
/**
* 校验字符串长度必须在指定范围内
*
* @param str 待校验字符串
* @param min 最小长度包含
* @param max 最大长度包含
* @param message 异常信息
* @throws IllegalArgumentException 如果字符串长度不在 [min, max] 范围内
*/
public static void checkLengthRange(String str, int min, int max, String message) {
if (str != null && (str.length() < min || str.length() > max)) {
throw new IllegalArgumentException(message);
}
}
/**
* 校验多个字符串是否全部为 null 或纯空白字符即全部为空
* 如果全部为空则抛出 IllegalArgumentException
*
* @param message 异常信息
* @param strings 待校验的字符串数组
* @throws IllegalArgumentException 如果所有字符串均为 null 或空白
*/
public static void checkNotAllBlank(String message, String... strings) {
if (strings == null || strings.length == 0) {
throw new IllegalArgumentException(message);
}
boolean allBlank = true;
for (String str : strings) {
if (StrUtil.isNotBlank(str)) {
allBlank = false;
break;
}
}
if (allBlank) {
throw new IllegalArgumentException(message);
}
}
}

8
src/main/resources/application-prod.yml

@ -94,6 +94,14 @@ fdfs:
tracker-list:
- 65.47.6.110:22122
preview-url: http://65.47.6.110:81
so-timeout: 120000 # socket超时增加到120秒(默认30秒)
connect-timeout: 10000 # 连接超时10秒(默认5秒)
pool:
max-total: 100 # 从池中借出的对象的最大数目
max-wait-millis: 5000 # 获取连接时的最大等待毫秒数
max-total-per-key: 50 # 每个key最大连接数
max-idle-per-key: 10 # 每个key对应的连接池最大空闲连接数
min-idle-per-key: 5 # 每个key对应的连接池最小空闲连接数
negative:
v1-user-url: http://65.47.6.108:8765/admin/current/user

179
src/main/resources/mapper/ComplaintCollectionMapper.xml

@ -146,4 +146,183 @@
</foreach>
</insert>
<select id="selectPageWithNegative" resultType="com.biutag.supervision.pojo.dto.complaintCollection.ComplaintCollectionPageDTO">
SELECT
cc.id AS id,
cc.source_table AS sourceTable,
cc.source_table_sub_one AS sourceTableSubOne,
cc.negative_id AS negativeId,
cc.responder_id_code AS responderIdCode,
cc.repeatt AS repeatt,
cc.lead_approval AS leadApproval,
cc.tag AS tag,
cc.handle_method AS handleMethod,
cc.second_depart_id AS secondDepartId,
cc.second_depart_name AS secondDepartName,
cc.third_depart_id AS thirdDepartId,
cc.third_depart_name AS thirdDepartName,
cc.gwf1 AS gwf1,
cc.gwf2 AS gwf2,
cc.gwf3 AS gwf3,
cc.gwf4 AS gwf4,
cc.gwf5 AS gwf5,
cc.create_by AS createBy,
cc.create_time AS createTime,
cc.update_by AS updateBy,
cc.update_time AS updateTime,
cc.completion_status AS completionStatus,
cc.public_recognition AS publicRecognition,
cc.init_work_des AS initWorkDes,
cc.init_problem_plan AS initProblemPlan,
cc.init_verdict AS initVerdict,
cc.involved_issue AS involvedIssue,
cc.distribution_state AS distributionState,
cc.channel_for_filing_complaints AS channelForFilingComplaints,
cc.acceptance_level AS acceptanceLevel,
cc.initial_petition AS initialPetition,
cc.entanglement_visits AS entanglementVisits,
cc.mass_visits AS massVisits,
cc.police_type AS policeType,
cc.police_type_name AS policeTypeName,
cc.people_number AS peopleNumber,
cc.appeal AS appeal,
cc.business_class AS businessClass,
cc.register_depart_name AS registerDepartName,
cc.transfer_depart AS transferDepart,
cc.handle_depart_name AS handleDepartName,
cc.completed_time AS completedTime,
cc.receiving_leader_name AS receivingLeaderName,
cc.is_mian_responsib AS isMianResponsib,
cc.receiving_depart_name AS receivingDepartName,
cc.petition_type AS petitionType,
cc.petition_processing_status AS petitionProcessingStatus,
cc.happen_time AS happenTime,
cc.is_real AS isReal,
cc.source AS source,
cc.creator AS creator,
cc.source_involve_depart_name AS sourceInvolveDepartName,
cc.outer_id AS outerId,
cc.crx_state AS crxState,
cc.accountability_target AS accountabilityTarget,
cc.crt_time AS crtTime,
-- 从 negative 表取通用字段
n.originId AS originId,
n.discoveryTime AS discoveryTime,
n.responderName AS responderName,
n.contactPhone AS responderPhone,
n.businessTypeCode AS businessTypeCode,
n.businessTypeName AS businessTypeName,
n.thingDesc AS thingDesc,
n.involveProblem AS involveProblem,
n.problemSourcesCode AS problemSourcesCode,
n.problemSources AS problemSources,
n.case_number AS caseNumber,
n.processing_status AS processingStatus,
n.check_status_code AS checkStatusCode,
n.checkStatusName AS checkStatusName,
n.check_status_desc AS checkStatusDesc,
n.involveDepartName AS involveDepartName
FROM complaint_collection cc
LEFT JOIN negative n ON n.id = cc.negative_id
<where>
<if test="param.sourceTable != null and param.sourceTable != ''">
AND cc.source_table = #{param.sourceTable}
</if>
<if test="param.sourceTableList != null and param.sourceTableList.size > 0">
AND cc.source_table IN
<foreach collection="param.sourceTableList" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="param.sourceTableSubOne != null and param.sourceTableSubOne != ''">
AND cc.source_table_sub_one = #{param.sourceTableSubOne}
</if>
<if test="param.sourceTableSubOneList != null and param.sourceTableSubOneList.size > 0">
AND cc.source_table_sub_one IN
<foreach collection="param.sourceTableSubOneList" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="param.originId != null and param.originId != ''">
AND n.originId LIKE CONCAT('%', #{param.originId}, '%')
</if>
<if test="param.originIds != null and param.originIds.size > 0">
AND n.originId IN
<foreach collection="param.originIds" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="param.checkStatus != null and param.checkStatus != ''">
AND cc.check_status = #{param.checkStatus}
</if>
<if test="param.checkStatusList != null and param.checkStatusList.size > 0">
AND cc.check_status IN
<foreach collection="param.checkStatusList" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="param.secondDepartId != null and param.secondDepartId != ''">
AND cc.second_depart_id = #{param.secondDepartId}
</if>
<if test="param.secondDepartIds != null and param.secondDepartIds.size > 0">
AND cc.second_depart_id IN
<foreach collection="param.secondDepartIds" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="param.discoveryTimeList != null and param.discoveryTimeList.size == 2">
AND n.discoveryTime BETWEEN #{param.discoveryTimeList[0]} AND #{param.discoveryTimeList[1]}
</if>
<if test="param.personInfo != null and param.personInfo != ''">
AND (
n.responderName LIKE CONCAT('%', #{param.personInfo}, '%')
OR n.contactPhone LIKE CONCAT('%', #{param.personInfo}, '%')
OR cc.responder_id_code LIKE CONCAT('%', #{param.personInfo}, '%')
)
</if>
<if test="param.handleMethod != null and param.handleMethod != ''">
AND cc.handle_method = #{param.handleMethod}
</if>
<if test="param.thingDesc != null and param.thingDesc != ''">
AND n.thingDesc LIKE CONCAT('%', #{param.thingDesc}, '%')
</if>
<if test="param.repeatt != null and param.repeatt != ''">
AND cc.repeatt = #{param.repeatt}
</if>
<if test="param.leadApproval != null and param.leadApproval != ''">
AND cc.lead_approval = #{param.leadApproval}
</if>
<if test="param.processingStatus != null and param.processingStatus.size > 0">
AND n.processing_status IN
<foreach collection="param.processingStatus" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="param.initialReviewFileList != null and param.initialReviewFileList.size > 0">
AND cc.gwf3 IN
<foreach collection="param.initialReviewFileList" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="param.tags != null and param.tags.size > 0">
AND (
<foreach collection="param.tags" item="tagItem" separator=" OR ">
FIND_IN_SET(#{tagItem}, cc.tag)
</foreach>
)
</if>
<if test="param.involveProblemIdList != null and param.involveProblemIdList.size > 0">
AND (
<foreach collection="param.involveProblemIdList" item="probItem" separator=" OR ">
FIND_IN_SET(#{probItem}, n.involveProblem)
</foreach>
)
</if>
<if test="param.createTimeList != null and param.createTimeList.size == 2">
AND cc.create_time BETWEEN #{param.createTimeList[0]} AND #{param.createTimeList[1]}
</if>
</where>
ORDER BY n.crtTime DESC, cc.id DESC
</select>
</mapper>

Loading…
Cancel
Save