Browse Source

项目代码

main
wanghao 5 days ago
parent
commit
6a97c57af7
  1. 25
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/constant/CaseLegalDocConst.java
  2. 100
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/constant/CaseRiskWarningConst.java
  3. 69
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/controller/CaseRiskWarningController.java
  4. 9
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/dao/CaseActivityLogDao.java
  5. 9
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/dao/CaseFileDao.java
  6. 9
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/dao/CaseLegalDocDao.java
  7. 20
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/dao/CaseRiskWarningDao.java
  8. 21
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/domain/entity/CaseActivityLogEntity.java
  9. 36
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/domain/entity/CaseFileEntity.java
  10. 24
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/domain/entity/CaseLegalDocEntity.java
  11. 31
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/domain/entity/CaseRiskWarningEntity.java
  12. 17
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/domain/form/CaseRiskWarningProcessForm.java
  13. 14
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/domain/form/CaseRiskWarningQueryForm.java
  14. 12
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/domain/vo/CaseRiskWarningStatsVO.java
  15. 34
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/domain/vo/CaseRiskWarningVO.java
  16. 573
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/engine/CaseRiskWarningEngine.java
  17. 138
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/service/CaseRiskWarningService.java
  18. 44
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/constant/CaseSupervisionConst.java
  19. 31
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/controller/CaseNegativeListController.java
  20. 74
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/controller/CaseWeeklyScheduleController.java
  21. 9
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/dao/CaseWeeklyScheduleCaseDao.java
  22. 19
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/dao/CaseWeeklyScheduleDao.java
  23. 9
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/dao/CaseWeeklyScheduleMemberDao.java
  24. 28
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/domain/entity/CaseWeeklyScheduleCaseEntity.java
  25. 31
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/domain/entity/CaseWeeklyScheduleEntity.java
  26. 22
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/domain/entity/CaseWeeklyScheduleMemberEntity.java
  27. 15
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/domain/form/CaseNegativeListQueryForm.java
  28. 33
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/domain/form/CaseWeeklyScheduleCreateForm.java
  29. 13
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/domain/form/CaseWeeklyScheduleQueryForm.java
  30. 20
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/domain/vo/CaseNegativeListVO.java
  31. 21
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/domain/vo/CaseWeeklyScheduleCaseVO.java
  32. 15
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/domain/vo/CaseWeeklyScheduleMemberVO.java
  33. 36
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/domain/vo/CaseWeeklyScheduleVO.java
  34. 76
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/service/CaseNegativeListService.java
  35. 467
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/service/CaseWeeklyScheduleService.java
  36. 40
      economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/support/CaseSupervisionNotifySupport.java
  37. 65
      economic-crime-api/economic-crime-admin/src/main/resources/mapper/business/caserisk/CaseRiskWarningMapper.xml
  38. 46
      economic-crime-api/economic-crime-admin/src/main/resources/mapper/business/casesupervision/CaseWeeklyScheduleMapper.xml
  39. 5
      economic-crime-web/src/api/business/case-management/negative-list-api.js
  40. 10
      economic-crime-web/src/api/business/case-management/risk-warning-api.js
  41. 10
      economic-crime-web/src/api/business/case-management/weekly-schedule-api.js
  42. 30
      economic-crime-web/src/constants/business/case-management/case-supervision-const.js
  43. 42
      economic-crime-web/src/constants/business/case-management/risk-warning-const.js
  44. 159
      economic-crime-web/src/utils/print-weekly-schedule.js
  45. 224
      economic-crime-web/src/views/business/case-management/negative-list.vue
  46. 210
      economic-crime-web/src/views/business/case-management/weekly-schedule-minutes.vue
  47. 598
      economic-crime-web/src/views/business/case-management/weekly-schedule.vue
  48. 34597
      logs/economic-crime/dev/debug/debug.log
  49. 390
      logs/economic-crime/dev/error/error.log
  50. 72
      logs/economic-crime/dev/info/info.log
  51. 1512
      logs/economic-crime/dev/slow-sql/slow-sql.log
  52. 15
      logs/economic-crime/dev/warn/warn.log

25
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/constant/CaseLegalDocConst.java

@ -0,0 +1,25 @@
package net.lab1024.sa.admin.module.business.caserisk.constant;
public final class CaseLegalDocConst {
private CaseLegalDocConst() {
}
public static final String EXTEND_FILING = "extend_filing_deadline";
public static final String SUSPEND_FILING = "suspend_filing";
public static final String EXTEND_SUSPEND_1 = "extend_suspend_1";
public static final String EXTEND_SUSPEND_2 = "extend_suspend_2";
public static final String BAIL_DECISION = "bail_decision";
public static final String SUMMONS_NOTICE = "summons_notice";
public static final String RELEASE_BAIL = "release_bail";
public static final String PROSECUTION_OPINION = "prosecution_opinion";
public static final String DETENTION_NOTICE = "detention_notice";
public static final String CHANGE_DETENTION = "change_detention_term";
public static final String ARREST_REQUEST = "arrest_request";
public static final String ARREST_NOTICE = "arrest_notice";
public static final String CHANGE_INVESTIGATION = "change_investigation_detention";
public static final String RESIDENTIAL_DECISION = "residential_decision";
public static final String RELEASE_RESIDENTIAL = "release_residential";
public static final String DESIGNATED_RESIDENCE = "designated_residence";
public static final String DESIGNATED_NOTICE = "designated_notice";
}

100
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/constant/CaseRiskWarningConst.java

@ -0,0 +1,100 @@
package net.lab1024.sa.admin.module.business.caserisk.constant;
import java.util.LinkedHashMap;
import java.util.Map;
public final class CaseRiskWarningConst {
private CaseRiskWarningConst() {
}
public static final String COLOR_BLUE = "blue";
public static final String COLOR_YELLOW = "yellow";
public static final String COLOR_RED = "red";
public static final String STATUS_OPEN = "open";
public static final String STATUS_HANDLED = "handled";
public static final String STATUS_IGNORED = "ignored";
public static final String STATUS_CLEARED = "cleared";
public static final String RULE_ACCEPT_TIMEOUT = "accept_timeout";
public static final String RULE_FILING_DEADLINE = "filing_deadline";
public static final String RULE_BAIL_SUMMONS = "bail_summons";
public static final String RULE_BAIL_EXPIRE = "bail_expire";
public static final String RULE_ACCEPT_INACTIVITY = "accept_inactivity";
public static final String RULE_FILING_INACTIVITY = "filing_inactivity";
public static final String RULE_DETENTION_NOTICE = "detention_notice";
public static final String RULE_DETENTION_DEADLINE = "detention_deadline";
public static final String RULE_ARREST_NOTICE = "arrest_notice";
public static final String RULE_ARREST_DEADLINE = "arrest_deadline";
public static final String RULE_RESIDENTIAL_EXPIRE = "residential_expire";
public static final String RULE_RESIDENTIAL_SUMMONS = "residential_summons";
public static final String RULE_DESIGNATED_NOTICE = "designated_notice";
public static final String SRC_NORMAL = "normal";
public static final String SRC_ADMIN = "admin";
public static final String SRC_COURT_NORMAL = "court_normal";
public static final String SRC_COURT_FALSE = "court_false";
public static final String SRC_PROCURATORATE = "procuratorate";
public static final String SRC_PROCURATORATE_NOTIFY = "procuratorate_notify";
private static final Map<String, String> COLOR_LABEL = Map.of(
COLOR_BLUE, "普通提醒",
COLOR_YELLOW, "问题预警",
COLOR_RED, "问题通报"
);
private static final Map<String, String> RULE_LABEL = new LinkedHashMap<>();
static {
RULE_LABEL.put(RULE_ACCEPT_TIMEOUT, "审议受案后超24小时未受案");
RULE_LABEL.put(RULE_FILING_DEADLINE, "立案审查期限");
RULE_LABEL.put(RULE_BAIL_SUMMONS, "取保候审传讯");
RULE_LABEL.put(RULE_BAIL_EXPIRE, "取保候审期限");
RULE_LABEL.put(RULE_ACCEPT_INACTIVITY, "受案后无活动日志");
RULE_LABEL.put(RULE_FILING_INACTIVITY, "立案后无活动日志");
RULE_LABEL.put(RULE_DETENTION_NOTICE, "刑事拘留通知书");
RULE_LABEL.put(RULE_DETENTION_DEADLINE, "刑事拘留羁押期限");
RULE_LABEL.put(RULE_ARREST_NOTICE, "逮捕后通知书");
RULE_LABEL.put(RULE_ARREST_DEADLINE, "逮捕后侦查羁押期限");
RULE_LABEL.put(RULE_RESIDENTIAL_EXPIRE, "监视居住期限");
RULE_LABEL.put(RULE_RESIDENTIAL_SUMMONS, "监视居住传讯");
RULE_LABEL.put(RULE_DESIGNATED_NOTICE, "指定居所监视居住通知书");
}
public static String colorLabel(String color) {
return COLOR_LABEL.getOrDefault(color, color);
}
public static String ruleLabel(String rule) {
return RULE_LABEL.getOrDefault(rule, rule);
}
public static Map<String, String> ruleCatalog() {
return RULE_LABEL;
}
public static int colorRank(String color) {
if (COLOR_RED.equals(color)) {
return 3;
}
if (COLOR_YELLOW.equals(color)) {
return 2;
}
if (COLOR_BLUE.equals(color)) {
return 1;
}
return 0;
}
public static String sourceLabel(String sourceType) {
return switch (sourceType == null ? "" : sourceType) {
case SRC_ADMIN -> "行政机关移送经侦案件";
case SRC_COURT_NORMAL -> "人民法院移送普通经侦案件";
case SRC_COURT_FALSE -> "人民法院移送虚假诉讼类经侦案件";
case SRC_PROCURATORATE -> "人民检察院移送经侦案件";
case SRC_PROCURATORATE_NOTIFY -> "人民检察院通知立案案件";
default -> "普通经侦案件";
};
}
}

69
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/controller/CaseRiskWarningController.java

@ -0,0 +1,69 @@
package net.lab1024.sa.admin.module.business.caserisk.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import net.lab1024.sa.admin.constant.AdminSwaggerTagConst;
import net.lab1024.sa.admin.module.business.caserisk.domain.form.CaseRiskWarningProcessForm;
import net.lab1024.sa.admin.module.business.caserisk.domain.form.CaseRiskWarningQueryForm;
import net.lab1024.sa.admin.module.business.caserisk.domain.vo.CaseRiskWarningStatsVO;
import net.lab1024.sa.admin.module.business.caserisk.domain.vo.CaseRiskWarningVO;
import net.lab1024.sa.admin.module.business.caserisk.service.CaseRiskWarningService;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@RestController
@Tag(name = AdminSwaggerTagConst.Business.MANAGER_CASE_RISK)
public class CaseRiskWarningController {
@Resource
private CaseRiskWarningService caseRiskWarningService;
@Operation(summary = "三色预警分页")
@PostMapping("/risk-warning/query")
@SaCheckPermission("risk-warning:query")
public ResponseDTO<PageResult<CaseRiskWarningVO>> query(@RequestBody @Valid CaseRiskWarningQueryForm form) {
return caseRiskWarningService.query(form);
}
@Operation(summary = "三色预警统计")
@GetMapping("/risk-warning/stats")
@SaCheckPermission("risk-warning:view")
public ResponseDTO<CaseRiskWarningStatsVO> stats(@RequestParam(required = false) String ruleCode) {
return caseRiskWarningService.stats(ruleCode);
}
@Operation(summary = "预警规则目录")
@GetMapping("/risk-warning/rules")
@SaCheckPermission("risk-warning:query")
public ResponseDTO<List<Map<String, String>>> rules() {
return caseRiskWarningService.rules();
}
@Operation(summary = "立即扫描刷新")
@PostMapping("/risk-warning/scan")
@SaCheckPermission("risk-warning:query")
public ResponseDTO<String> scan() {
return caseRiskWarningService.scan();
}
@Operation(summary = "处置预警")
@PostMapping("/risk-warning/process")
@SaCheckPermission("risk-warning:process")
public ResponseDTO<String> process(@RequestBody @Valid CaseRiskWarningProcessForm form) {
return caseRiskWarningService.process(form);
}
@Operation(summary = "忽略预警")
@PostMapping("/risk-warning/ignore/{warningId}")
@SaCheckPermission("risk-warning:ignore")
public ResponseDTO<String> ignore(@PathVariable Long warningId) {
return caseRiskWarningService.ignore(warningId);
}
}

9
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/dao/CaseActivityLogDao.java

@ -0,0 +1,9 @@
package net.lab1024.sa.admin.module.business.caserisk.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import net.lab1024.sa.admin.module.business.caserisk.domain.entity.CaseActivityLogEntity;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface CaseActivityLogDao extends BaseMapper<CaseActivityLogEntity> {
}

9
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/dao/CaseFileDao.java

@ -0,0 +1,9 @@
package net.lab1024.sa.admin.module.business.caserisk.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import net.lab1024.sa.admin.module.business.caserisk.domain.entity.CaseFileEntity;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface CaseFileDao extends BaseMapper<CaseFileEntity> {
}

9
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/dao/CaseLegalDocDao.java

@ -0,0 +1,9 @@
package net.lab1024.sa.admin.module.business.caserisk.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import net.lab1024.sa.admin.module.business.caserisk.domain.entity.CaseLegalDocEntity;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface CaseLegalDocDao extends BaseMapper<CaseLegalDocEntity> {
}

20
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/dao/CaseRiskWarningDao.java

@ -0,0 +1,20 @@
package net.lab1024.sa.admin.module.business.caserisk.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import net.lab1024.sa.admin.module.business.caserisk.domain.entity.CaseRiskWarningEntity;
import net.lab1024.sa.admin.module.business.caserisk.domain.form.CaseRiskWarningQueryForm;
import net.lab1024.sa.admin.module.business.caserisk.domain.vo.CaseRiskWarningStatsVO;
import net.lab1024.sa.admin.module.business.caserisk.domain.vo.CaseRiskWarningVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface CaseRiskWarningDao extends BaseMapper<CaseRiskWarningEntity> {
List<CaseRiskWarningVO> query(Page<?> page, @Param("query") CaseRiskWarningQueryForm queryForm);
CaseRiskWarningStatsVO stats(@Param("ruleCode") String ruleCode);
}

21
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/domain/entity/CaseActivityLogEntity.java

@ -0,0 +1,21 @@
package net.lab1024.sa.admin.module.business.caserisk.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@TableName("t_case_activity_log")
public class CaseActivityLogEntity {
@TableId(type = IdType.AUTO)
private Long logId;
private Long caseId;
private LocalDateTime activityTime;
private String activityTitle;
private String operatorName;
private LocalDateTime createTime;
}

36
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/domain/entity/CaseFileEntity.java

@ -0,0 +1,36 @@
package net.lab1024.sa.admin.module.business.caserisk.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@TableName("t_case_file")
public class CaseFileEntity {
@TableId(type = IdType.AUTO)
private Long caseId;
private String caseNo;
private String caseName;
private Long alarmId;
private String caseSource;
private String caseSourceSub;
private String handlerName;
private String bizCategory;
private String createDept;
private String handleDept;
private String caseStatus;
private LocalDateTime reviewDecideTime;
private LocalDateTime acceptTime;
private LocalDateTime filingTime;
private LocalDateTime detentionTime;
private LocalDateTime arrestTime;
private LocalDateTime residentialTime;
private LocalDateTime designatedTime;
private LocalDateTime createTime;
private LocalDateTime updateTime;
private Boolean deletedFlag;
}

24
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/domain/entity/CaseLegalDocEntity.java

@ -0,0 +1,24 @@
package net.lab1024.sa.admin.module.business.caserisk.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@TableName("t_case_legal_doc")
public class CaseLegalDocEntity {
@TableId(type = IdType.AUTO)
private Long docId;
private Long caseId;
private String docType;
private String docName;
private LocalDateTime issueTime;
private Boolean approvedFlag;
private Boolean interrogated;
private Integer seqNo;
private LocalDateTime createTime;
}

31
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/domain/entity/CaseRiskWarningEntity.java

@ -0,0 +1,31 @@
package net.lab1024.sa.admin.module.business.caserisk.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@TableName("t_case_risk_warning")
public class CaseRiskWarningEntity {
@TableId(type = IdType.AUTO)
private Long warningId;
private String warningNo;
private Long caseId;
private String ruleCode;
private String trackKey;
private String color;
private String reason;
private Integer elapsedDays;
private Boolean stickyRed;
private String status;
private String processMeasure;
private String processRemark;
private String processUser;
private LocalDateTime processTime;
private LocalDateTime triggerTime;
private LocalDateTime updateTime;
}

17
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/domain/form/CaseRiskWarningProcessForm.java

@ -0,0 +1,17 @@
package net.lab1024.sa.admin.module.business.caserisk.domain.form;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Data
public class CaseRiskWarningProcessForm {
@NotNull
private Long warningId;
@NotBlank
private String measure;
private String remark;
}

14
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/domain/form/CaseRiskWarningQueryForm.java

@ -0,0 +1,14 @@
package net.lab1024.sa.admin.module.business.caserisk.domain.form;
import lombok.Data;
import net.lab1024.sa.base.common.domain.PageParam;
@Data
public class CaseRiskWarningQueryForm extends PageParam {
private String caseNo;
private String caseName;
private String color;
private String ruleCode;
private String status;
}

12
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/domain/vo/CaseRiskWarningStatsVO.java

@ -0,0 +1,12 @@
package net.lab1024.sa.admin.module.business.caserisk.domain.vo;
import lombok.Data;
@Data
public class CaseRiskWarningStatsVO {
private Long redCount;
private Long yellowCount;
private Long blueCount;
private Long openCount;
}

34
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/domain/vo/CaseRiskWarningVO.java

@ -0,0 +1,34 @@
package net.lab1024.sa.admin.module.business.caserisk.domain.vo;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class CaseRiskWarningVO {
private Long warningId;
private String warningNo;
private Long caseId;
private String caseNo;
private String caseName;
private String caseSource;
private String caseSourceSub;
private String caseSourceName;
private String handlerName;
private String ruleCode;
private String ruleName;
private String trackKey;
private String color;
private String colorName;
private String reason;
private Integer elapsedDays;
private Boolean stickyRed;
private String status;
private String statusName;
private String processMeasure;
private String processRemark;
private String processUser;
private LocalDateTime processTime;
private LocalDateTime triggerTime;
}

573
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/engine/CaseRiskWarningEngine.java

@ -0,0 +1,573 @@
package net.lab1024.sa.admin.module.business.caserisk.engine;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.annotation.Resource;
import net.lab1024.sa.admin.module.business.alarm.constant.AlarmCaseSourceConst;
import net.lab1024.sa.admin.module.business.caserisk.constant.CaseLegalDocConst;
import net.lab1024.sa.admin.module.business.caserisk.constant.CaseRiskWarningConst;
import net.lab1024.sa.admin.module.business.caserisk.dao.CaseActivityLogDao;
import net.lab1024.sa.admin.module.business.caserisk.dao.CaseFileDao;
import net.lab1024.sa.admin.module.business.caserisk.dao.CaseLegalDocDao;
import net.lab1024.sa.admin.module.business.caserisk.dao.CaseRiskWarningDao;
import net.lab1024.sa.admin.module.business.caserisk.domain.entity.CaseActivityLogEntity;
import net.lab1024.sa.admin.module.business.caserisk.domain.entity.CaseFileEntity;
import net.lab1024.sa.admin.module.business.caserisk.domain.entity.CaseLegalDocEntity;
import net.lab1024.sa.admin.module.business.caserisk.domain.entity.CaseRiskWarningEntity;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
@Component
public class CaseRiskWarningEngine {
@Resource
private CaseFileDao caseFileDao;
@Resource
private CaseLegalDocDao caseLegalDocDao;
@Resource
private CaseActivityLogDao caseActivityLogDao;
@Resource
private CaseRiskWarningDao caseRiskWarningDao;
@Transactional(rollbackFor = Exception.class)
public int scanAll() {
List<CaseFileEntity> cases = caseFileDao.selectList(new LambdaQueryWrapper<CaseFileEntity>()
.eq(CaseFileEntity::getDeletedFlag, false));
int count = 0;
for (CaseFileEntity caseFile : cases) {
scanCase(caseFile);
count++;
}
return count;
}
public void scanCase(CaseFileEntity caseFile) {
List<CaseLegalDocEntity> docs = caseLegalDocDao.selectList(new LambdaQueryWrapper<CaseLegalDocEntity>()
.eq(CaseLegalDocEntity::getCaseId, caseFile.getCaseId())
.orderByAsc(CaseLegalDocEntity::getIssueTime));
LocalDateTime lastActivity = lastActivityTime(caseFile);
LocalDateTime now = LocalDateTime.now();
scanAcceptTimeout(caseFile, now);
scanFilingDeadline(caseFile, docs, now);
scanBail(caseFile, docs, now);
scanAcceptInactivity(caseFile, lastActivity, now);
scanFilingInactivity(caseFile, lastActivity, now);
scanDetention(caseFile, docs, now);
scanArrest(caseFile, docs, now);
scanResidential(caseFile, docs, now);
scanDesignated(caseFile, docs, now);
}
private void scanAcceptTimeout(CaseFileEntity caseFile, LocalDateTime now) {
if (caseFile.getReviewDecideTime() == null) {
return;
}
boolean acceptedInTime = caseFile.getAcceptTime() != null
&& ChronoUnit.HOURS.between(caseFile.getReviewDecideTime(), caseFile.getAcceptTime()) <= 24;
if (acceptedInTime) {
return;
}
long hours = ChronoUnit.HOURS.between(caseFile.getReviewDecideTime(), now);
if (caseFile.getAcceptTime() == null && hours <= 24) {
return;
}
raise(caseFile, CaseRiskWarningConst.RULE_ACCEPT_TIMEOUT, "main",
CaseRiskWarningConst.COLOR_RED,
"案件类警情经审议决定受案后,超24小时未在系统内受案",
(int) ChronoUnit.DAYS.between(caseFile.getReviewDecideTime().toLocalDate(), now.toLocalDate()));
}
private void scanFilingDeadline(CaseFileEntity caseFile, List<CaseLegalDocEntity> docs, LocalDateTime now) {
if (caseFile.getAcceptTime() == null || caseFile.getFilingTime() != null) {
return;
}
String sourceType = resolveSourceType(caseFile);
boolean allowExtend = !CaseRiskWarningConst.SRC_COURT_NORMAL.equals(sourceType)
&& !CaseRiskWarningConst.SRC_COURT_FALSE.equals(sourceType)
&& !CaseRiskWarningConst.SRC_PROCURATORATE_NOTIFY.equals(sourceType);
boolean allowSuspend = !CaseRiskWarningConst.SRC_PROCURATORATE_NOTIFY.equals(sourceType);
int extendCount = allowExtend ? countApproved(docs, CaseLegalDocConst.EXTEND_FILING) : 0;
int[] base = filingThresholds(sourceType, extendCount);
String track = "round-" + extendCount;
CaseLegalDocEntity suspend = allowSuspend ? latest(docs, CaseLegalDocConst.SUSPEND_FILING) : null;
if (suspend != null) {
LocalDateTime suspendAt = suspend.getIssueTime();
boolean ext1 = hasDocWithinDays(docs, CaseLegalDocConst.EXTEND_SUSPEND_1, suspendAt, 30);
boolean ext2 = hasDocWithinDays(docs, CaseLegalDocConst.EXTEND_SUSPEND_2, suspendAt, 60);
int resumeDay;
int[] suspendTh;
if (ext2) {
resumeDay = 91;
suspendTh = new int[]{70, 80, 91};
} else if (ext1) {
resumeDay = 61;
suspendTh = new int[]{40, 50, 61};
} else {
resumeDay = 31;
suspendTh = new int[]{20, 25, 31};
}
int suspendDays = days(suspendAt, now);
if (suspendDays < resumeDay) {
String color = thresholdColor(suspendDays, suspendTh[0], suspendTh[1], Integer.MAX_VALUE);
if (color != null) {
raise(caseFile, CaseRiskWarningConst.RULE_FILING_DEADLINE, "suspend",
color,
CaseRiskWarningConst.sourceLabel(sourceType)
+ "已中止立案审查,自中止通知书之日起第" + suspendDays + "日",
suspendDays);
}
return;
}
}
int elapsed = days(caseFile.getAcceptTime(), now);
String color = thresholdColor(elapsed, base[0], base[1], base[2]);
if (color == null) {
clearIfNotRed(caseFile.getCaseId(), CaseRiskWarningConst.RULE_FILING_DEADLINE, track);
return;
}
String extra = extendCount == 0 ? "基础审查期限"
: (extendCount == 1 ? "第一次延长立案期限后" : "第二次延长立案期限后");
raise(caseFile, CaseRiskWarningConst.RULE_FILING_DEADLINE, track, color,
CaseRiskWarningConst.sourceLabel(sourceType) + extra
+ ",受案后第" + elapsed + "日(蓝" + base[0] + "/黄" + base[1] + "/红" + base[2] + ")",
elapsed);
}
private void scanBail(CaseFileEntity caseFile, List<CaseLegalDocEntity> docs, LocalDateTime now) {
CaseLegalDocEntity bail = latest(docs, CaseLegalDocConst.BAIL_DECISION);
if (bail == null) {
return;
}
if (hasApproved(docs, CaseLegalDocConst.RELEASE_BAIL) || hasApproved(docs, CaseLegalDocConst.PROSECUTION_OPINION)) {
clearIfNotRed(caseFile.getCaseId(), CaseRiskWarningConst.RULE_BAIL_EXPIRE, "main");
} else {
int months = monthsFloor(bail.getIssueTime(), now);
String color = null;
if (months >= 12) {
color = CaseRiskWarningConst.COLOR_RED;
} else if (months >= 11) {
color = CaseRiskWarningConst.COLOR_YELLOW;
} else if (months >= 10) {
color = CaseRiskWarningConst.COLOR_BLUE;
}
if (color != null) {
raise(caseFile, CaseRiskWarningConst.RULE_BAIL_EXPIRE, "main", color,
"取保候审决定书制作后满" + months + "个月,未制作解除取保候审决定书或起诉意见书",
days(bail.getIssueTime(), now));
}
}
int elapsedMonths = monthsFloor(bail.getIssueTime(), now);
if (elapsedMonths < 1) {
return;
}
List<Integer> missing = new ArrayList<>();
for (int m = 1; m <= elapsedMonths && m <= 24; m++) {
LocalDateTime start = bail.getIssueTime().plusMonths(m - 1L);
LocalDateTime end = bail.getIssueTime().plusMonths(m);
boolean has = docs.stream().anyMatch(d -> CaseLegalDocConst.SUMMONS_NOTICE.equals(d.getDocType())
&& Boolean.TRUE.equals(d.getInterrogated())
&& !d.getIssueTime().isBefore(start)
&& d.getIssueTime().isBefore(end));
if (!has) {
missing.add(m);
}
}
if (missing.isEmpty()) {
clearIfNotRed(caseFile.getCaseId(), CaseRiskWarningConst.RULE_BAIL_SUMMONS, "main");
return;
}
int lastMissing = missing.get(missing.size() - 1);
int consecutive = 0;
for (int i = missing.size() - 1; i >= 0; i--) {
if (missing.get(i) == lastMissing - consecutive) {
consecutive++;
} else {
break;
}
}
String color;
String reason;
if (consecutive >= 3 && lastMissing >= 3) {
color = CaseRiskWarningConst.COLOR_RED;
reason = "取保候审后连续三个月未制作传讯通知书并讯问";
} else if (lastMissing >= 3) {
color = CaseRiskWarningConst.COLOR_YELLOW;
reason = "取保候审满三个月后,当月未制作传讯通知书并讯问";
} else if (lastMissing == 2) {
color = CaseRiskWarningConst.COLOR_YELLOW;
reason = "取保候审两个月内未制作传讯通知书并讯问";
} else {
color = CaseRiskWarningConst.COLOR_BLUE;
reason = "取保候审一个月内未制作传讯通知书并讯问";
}
raise(caseFile, CaseRiskWarningConst.RULE_BAIL_SUMMONS, "main", color, reason,
days(bail.getIssueTime(), now));
}
private void scanAcceptInactivity(CaseFileEntity caseFile, LocalDateTime lastActivity, LocalDateTime now) {
if (caseFile.getAcceptTime() == null || caseFile.getFilingTime() != null) {
return;
}
LocalDateTime base = lastActivity != null ? lastActivity : caseFile.getAcceptTime();
int elapsed = days(base, now);
String color = thresholdColor(elapsed, 20, 30, 50);
if (color == null) {
clearIfNotRed(caseFile.getCaseId(), CaseRiskWarningConst.RULE_ACCEPT_INACTIVITY, "main");
return;
}
raise(caseFile, CaseRiskWarningConst.RULE_ACCEPT_INACTIVITY, "main", color,
"案件受案后" + elapsed + "日无活动日志", elapsed);
}
private void scanFilingInactivity(CaseFileEntity caseFile, LocalDateTime lastActivity, LocalDateTime now) {
if (caseFile.getFilingTime() == null) {
return;
}
LocalDateTime base = lastActivity != null && lastActivity.isAfter(caseFile.getFilingTime())
? lastActivity : caseFile.getFilingTime();
int elapsed = days(base, now);
String color = thresholdColor(elapsed, 30, 60, 90);
if (color == null) {
clearIfNotRed(caseFile.getCaseId(), CaseRiskWarningConst.RULE_FILING_INACTIVITY, "main");
return;
}
raise(caseFile, CaseRiskWarningConst.RULE_FILING_INACTIVITY, "main", color,
"案件立案后" + elapsed + "日无活动日志", elapsed);
}
private void scanDetention(CaseFileEntity caseFile, List<CaseLegalDocEntity> docs, LocalDateTime now) {
if (caseFile.getDetentionTime() == null) {
return;
}
boolean hasNotice = hasApproved(docs, CaseLegalDocConst.DETENTION_NOTICE);
if (!hasNotice && ChronoUnit.HOURS.between(caseFile.getDetentionTime(), now) >= 24) {
raise(caseFile, CaseRiskWarningConst.RULE_DETENTION_NOTICE, "main",
CaseRiskWarningConst.COLOR_RED,
"刑事拘留后24小时内系统内未制作拘留通知书",
days(caseFile.getDetentionTime(), now));
}
int elapsed = days(caseFile.getDetentionTime(), now);
boolean change7 = hasDocWithinDays(docs, CaseLegalDocConst.CHANGE_DETENTION, caseFile.getDetentionTime(), 7);
boolean arrestReq30 = hasDocWithinDays(docs, CaseLegalDocConst.ARREST_REQUEST, caseFile.getDetentionTime(), 30);
if (change7) {
String color = thresholdColor(elapsed, 20, 25, 31);
if (color != null) {
raise(caseFile, CaseRiskWarningConst.RULE_DETENTION_DEADLINE, "extended", color,
"刑拘后7日内已变更羁押期限,自刑拘之日起第" + elapsed + "日", elapsed);
}
} else {
String color = thresholdColor(elapsed, 3, 5, 8);
if (color != null) {
raise(caseFile, CaseRiskWarningConst.RULE_DETENTION_DEADLINE, "base", color,
"刑事拘留后第" + elapsed + "日(未变更羁押期限)", elapsed);
}
}
if (arrestReq30) {
String color = null;
if (elapsed >= 38) {
color = CaseRiskWarningConst.COLOR_RED;
} else if (elapsed >= 36) {
color = CaseRiskWarningConst.COLOR_YELLOW;
}
if (color != null) {
raise(caseFile, CaseRiskWarningConst.RULE_DETENTION_DEADLINE, "arrest-request", color,
"30日内已制作提请批准逮捕书,刑拘后第" + elapsed + "日", elapsed);
}
}
}
private void scanArrest(CaseFileEntity caseFile, List<CaseLegalDocEntity> docs, LocalDateTime now) {
if (caseFile.getArrestTime() == null) {
return;
}
boolean hasNotice = hasApproved(docs, CaseLegalDocConst.DETENTION_NOTICE)
|| hasApproved(docs, CaseLegalDocConst.ARREST_NOTICE);
if (!hasNotice && ChronoUnit.HOURS.between(caseFile.getArrestTime(), now) >= 24) {
raise(caseFile, CaseRiskWarningConst.RULE_ARREST_NOTICE, "main",
CaseRiskWarningConst.COLOR_RED,
"逮捕后24小时内系统内未制作拘留通知书",
days(caseFile.getArrestTime(), now));
}
int elapsed = days(caseFile.getArrestTime(), now);
boolean extIn2m = hasDocWithinDays(docs, CaseLegalDocConst.CHANGE_INVESTIGATION, caseFile.getArrestTime(), 60);
boolean extIn3m = hasDocBetweenDays(docs, CaseLegalDocConst.CHANGE_INVESTIGATION, caseFile.getArrestTime(), 61, 90);
boolean extIn45 = hasDocBetweenDays(docs, CaseLegalDocConst.CHANGE_INVESTIGATION, caseFile.getArrestTime(), 91, 150);
String track;
int[] th;
String desc;
if (extIn45) {
track = "m7";
th = new int[]{190, 200, 210};
desc = "第4、5个月内延长侦查羁押期限后,七个月届满";
} else if (extIn3m) {
track = "m5";
th = new int[]{130, 140, 150};
desc = "第三个月内延长侦查羁押期限后,五个月届满";
} else if (extIn2m) {
track = "m3";
th = new int[]{70, 80, 90};
desc = "两个月内延长侦查羁押期限后,三个月届满";
} else {
track = "m2";
th = new int[]{40, 50, 60};
desc = "逮捕后两个月侦查羁押期限";
}
String color = thresholdColor(elapsed, th[0], th[1], th[2]);
if (color != null) {
raise(caseFile, CaseRiskWarningConst.RULE_ARREST_DEADLINE, track, color,
desc + ",逮捕后第" + elapsed + "日", elapsed);
}
}
private void scanResidential(CaseFileEntity caseFile, List<CaseLegalDocEntity> docs, LocalDateTime now) {
LocalDateTime start = caseFile.getResidentialTime();
if (start == null) {
CaseLegalDocEntity decision = latest(docs, CaseLegalDocConst.RESIDENTIAL_DECISION);
if (decision != null) {
start = decision.getIssueTime();
}
}
if (start == null) {
return;
}
final LocalDateTime startTime = start;
if (!hasApproved(docs, CaseLegalDocConst.RELEASE_RESIDENTIAL)
&& !hasApproved(docs, CaseLegalDocConst.PROSECUTION_OPINION)) {
int months = monthsFloor(startTime, now);
String color = null;
if (months >= 6) {
color = CaseRiskWarningConst.COLOR_RED;
} else if (months >= 5) {
color = CaseRiskWarningConst.COLOR_YELLOW;
} else if (months >= 4) {
color = CaseRiskWarningConst.COLOR_BLUE;
}
if (color != null) {
raise(caseFile, CaseRiskWarningConst.RULE_RESIDENTIAL_EXPIRE, "main", color,
"监视居住满" + months + "个月,未制作解除监视居住决定书或起诉意见书",
days(startTime, now));
}
}
int elapsedMonths = monthsFloor(startTime, now);
if (elapsedMonths < 1) {
return;
}
boolean anySummons = docs.stream().anyMatch(d -> CaseLegalDocConst.SUMMONS_NOTICE.equals(d.getDocType())
&& Boolean.TRUE.equals(d.getInterrogated())
&& !d.getIssueTime().isBefore(startTime));
if (anySummons) {
clearIfNotRed(caseFile.getCaseId(), CaseRiskWarningConst.RULE_RESIDENTIAL_SUMMONS, "main");
return;
}
String color;
if (elapsedMonths >= 3) {
color = CaseRiskWarningConst.COLOR_RED;
} else if (elapsedMonths >= 2) {
color = CaseRiskWarningConst.COLOR_YELLOW;
} else {
color = CaseRiskWarningConst.COLOR_BLUE;
}
raise(caseFile, CaseRiskWarningConst.RULE_RESIDENTIAL_SUMMONS, "main", color,
"监视居住后" + elapsedMonths + "个月内未制作传讯通知书并讯问",
days(startTime, now));
}
private void scanDesignated(CaseFileEntity caseFile, List<CaseLegalDocEntity> docs, LocalDateTime now) {
LocalDateTime start = caseFile.getDesignatedTime();
if (start == null) {
CaseLegalDocEntity decision = latest(docs, CaseLegalDocConst.DESIGNATED_RESIDENCE);
if (decision != null) {
start = decision.getIssueTime();
}
}
if (start == null) {
return;
}
if (hasApproved(docs, CaseLegalDocConst.DESIGNATED_NOTICE)) {
return;
}
if (ChronoUnit.HOURS.between(start, now) >= 24) {
raise(caseFile, CaseRiskWarningConst.RULE_DESIGNATED_NOTICE, "main",
CaseRiskWarningConst.COLOR_RED,
"指定居所监视居住后24小时内未制作指定监视居住通知书",
days(start, now));
}
}
private void raise(CaseFileEntity caseFile, String rule, String track, String color, String reason, int days) {
CaseRiskWarningEntity exists = caseRiskWarningDao.selectOne(new LambdaQueryWrapper<CaseRiskWarningEntity>()
.eq(CaseRiskWarningEntity::getCaseId, caseFile.getCaseId())
.eq(CaseRiskWarningEntity::getRuleCode, rule)
.eq(CaseRiskWarningEntity::getTrackKey, track)
.orderByDesc(CaseRiskWarningEntity::getWarningId)
.last("LIMIT 1"));
LocalDateTime now = LocalDateTime.now();
if (exists != null && Boolean.TRUE.equals(exists.getStickyRed())) {
exists.setReason(reason);
exists.setElapsedDays(days);
exists.setUpdateTime(now);
caseRiskWarningDao.updateById(exists);
return;
}
if (exists != null) {
if (CaseRiskWarningConst.colorRank(color) < CaseRiskWarningConst.colorRank(exists.getColor())
&& CaseRiskWarningConst.COLOR_RED.equals(exists.getColor())) {
return;
}
exists.setColor(higher(exists.getColor(), color));
exists.setReason(reason);
exists.setElapsedDays(days);
exists.setStatus(CaseRiskWarningConst.STATUS_OPEN);
exists.setUpdateTime(now);
if (CaseRiskWarningConst.COLOR_RED.equals(exists.getColor())) {
exists.setStickyRed(true);
}
caseRiskWarningDao.updateById(exists);
return;
}
CaseRiskWarningEntity entity = new CaseRiskWarningEntity();
entity.setWarningNo("YJ" + caseFile.getCaseId() + "-" + rule + "-" + track);
entity.setCaseId(caseFile.getCaseId());
entity.setRuleCode(rule);
entity.setTrackKey(track);
entity.setColor(color);
entity.setReason(reason);
entity.setElapsedDays(days);
entity.setStickyRed(CaseRiskWarningConst.COLOR_RED.equals(color));
entity.setStatus(CaseRiskWarningConst.STATUS_OPEN);
entity.setTriggerTime(now);
entity.setUpdateTime(now);
caseRiskWarningDao.insert(entity);
}
private void clearIfNotRed(Long caseId, String rule, String track) {
CaseRiskWarningEntity exists = caseRiskWarningDao.selectOne(new LambdaQueryWrapper<CaseRiskWarningEntity>()
.eq(CaseRiskWarningEntity::getCaseId, caseId)
.eq(CaseRiskWarningEntity::getRuleCode, rule)
.eq(CaseRiskWarningEntity::getTrackKey, track)
.orderByDesc(CaseRiskWarningEntity::getWarningId)
.last("LIMIT 1"));
if (exists == null || Boolean.TRUE.equals(exists.getStickyRed())
|| CaseRiskWarningConst.COLOR_RED.equals(exists.getColor())) {
return;
}
exists.setStatus(CaseRiskWarningConst.STATUS_CLEARED);
exists.setUpdateTime(LocalDateTime.now());
caseRiskWarningDao.updateById(exists);
}
private String higher(String a, String b) {
return CaseRiskWarningConst.colorRank(a) >= CaseRiskWarningConst.colorRank(b) ? a : b;
}
private String thresholdColor(int elapsed, int blue, int yellow, int red) {
if (elapsed >= red) {
return CaseRiskWarningConst.COLOR_RED;
}
if (elapsed >= yellow) {
return CaseRiskWarningConst.COLOR_YELLOW;
}
if (elapsed >= blue) {
return CaseRiskWarningConst.COLOR_BLUE;
}
return null;
}
private int[] filingThresholds(String sourceType, int extendCount) {
if (extendCount >= 2) {
return new int[]{40, 50, 61};
}
if (extendCount == 1) {
return new int[]{20, 25, 31};
}
return switch (sourceType) {
case CaseRiskWarningConst.SRC_ADMIN -> new int[]{3, 7, 11};
case CaseRiskWarningConst.SRC_COURT_NORMAL -> new int[]{5, 8, 11};
case CaseRiskWarningConst.SRC_COURT_FALSE -> new int[]{20, 25, 31};
case CaseRiskWarningConst.SRC_PROCURATORATE_NOTIFY -> new int[]{7, 10, 16};
default -> new int[]{3, 5, 8};
};
}
public static String resolveSourceType(CaseFileEntity caseFile) {
String source = StringUtils.defaultString(caseFile.getCaseSource());
String sub = StringUtils.defaultString(caseFile.getCaseSourceSub());
if (AlarmCaseSourceConst.ADMIN_TRANSFER.equals(source)) {
return CaseRiskWarningConst.SRC_ADMIN;
}
if (AlarmCaseSourceConst.isCourtFalse(source, sub)) {
return CaseRiskWarningConst.SRC_COURT_FALSE;
}
if (AlarmCaseSourceConst.isCourtSource(source)) {
return CaseRiskWarningConst.SRC_COURT_NORMAL;
}
if (AlarmCaseSourceConst.PROCURATORATE_NOTIFY.equals(source)) {
return CaseRiskWarningConst.SRC_PROCURATORATE_NOTIFY;
}
if (AlarmCaseSourceConst.PROSECUTORATE_TRANSFER.equals(source)) {
return CaseRiskWarningConst.SRC_PROCURATORATE;
}
return CaseRiskWarningConst.SRC_NORMAL;
}
private LocalDateTime lastActivityTime(CaseFileEntity caseFile) {
CaseActivityLogEntity last = caseActivityLogDao.selectOne(new LambdaQueryWrapper<CaseActivityLogEntity>()
.eq(CaseActivityLogEntity::getCaseId, caseFile.getCaseId())
.orderByDesc(CaseActivityLogEntity::getActivityTime)
.last("LIMIT 1"));
return last == null ? null : last.getActivityTime();
}
private int countApproved(List<CaseLegalDocEntity> docs, String type) {
return (int) docs.stream()
.filter(d -> type.equals(d.getDocType()) && !Boolean.FALSE.equals(d.getApprovedFlag()))
.count();
}
private boolean hasApproved(List<CaseLegalDocEntity> docs, String type) {
return docs.stream().anyMatch(d -> type.equals(d.getDocType()) && !Boolean.FALSE.equals(d.getApprovedFlag()));
}
private CaseLegalDocEntity latest(List<CaseLegalDocEntity> docs, String type) {
return docs.stream()
.filter(d -> type.equals(d.getDocType()) && !Boolean.FALSE.equals(d.getApprovedFlag()))
.max(Comparator.comparing(CaseLegalDocEntity::getIssueTime))
.orElse(null);
}
private boolean hasDocWithinDays(List<CaseLegalDocEntity> docs, String type, LocalDateTime from, int withinDays) {
return docs.stream().anyMatch(d -> type.equals(d.getDocType())
&& !Boolean.FALSE.equals(d.getApprovedFlag())
&& !d.getIssueTime().isBefore(from)
&& days(from, d.getIssueTime()) <= withinDays);
}
private boolean hasDocBetweenDays(List<CaseLegalDocEntity> docs, String type, LocalDateTime from, int fromDay, int toDay) {
return docs.stream().anyMatch(d -> type.equals(d.getDocType())
&& !Boolean.FALSE.equals(d.getApprovedFlag())
&& days(from, d.getIssueTime()) >= fromDay
&& days(from, d.getIssueTime()) <= toDay);
}
private int days(LocalDateTime from, LocalDateTime to) {
return (int) ChronoUnit.DAYS.between(from.toLocalDate(), to.toLocalDate());
}
private int monthsFloor(LocalDateTime from, LocalDateTime to) {
LocalDate start = from.toLocalDate();
LocalDate end = to.toLocalDate();
int months = (int) ChronoUnit.MONTHS.between(start, end);
return Math.max(months, 0);
}
}

138
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/caserisk/service/CaseRiskWarningService.java

@ -0,0 +1,138 @@
package net.lab1024.sa.admin.module.business.caserisk.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import net.lab1024.sa.admin.module.business.caserisk.constant.CaseRiskWarningConst;
import net.lab1024.sa.admin.module.business.caserisk.dao.CaseRiskWarningDao;
import net.lab1024.sa.admin.module.business.caserisk.domain.entity.CaseRiskWarningEntity;
import net.lab1024.sa.admin.module.business.caserisk.domain.form.CaseRiskWarningProcessForm;
import net.lab1024.sa.admin.module.business.caserisk.domain.form.CaseRiskWarningQueryForm;
import net.lab1024.sa.admin.module.business.caserisk.domain.vo.CaseRiskWarningStatsVO;
import net.lab1024.sa.admin.module.business.caserisk.domain.vo.CaseRiskWarningVO;
import net.lab1024.sa.admin.module.business.caserisk.engine.CaseRiskWarningEngine;
import net.lab1024.sa.admin.module.system.login.domain.RequestEmployee;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartPageUtil;
import net.lab1024.sa.base.common.util.SmartRequestUtil;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@Service
public class CaseRiskWarningService {
@Resource
private CaseRiskWarningDao caseRiskWarningDao;
@Resource
private CaseRiskWarningEngine caseRiskWarningEngine;
public ResponseDTO<PageResult<CaseRiskWarningVO>> query(CaseRiskWarningQueryForm form) {
caseRiskWarningEngine.scanAll();
Page<?> page = SmartPageUtil.convert2PageQuery(form);
List<CaseRiskWarningVO> list = caseRiskWarningDao.query(page, form);
list.forEach(this::decorate);
return ResponseDTO.ok(SmartPageUtil.convert2PageResult(page, list));
}
public ResponseDTO<CaseRiskWarningStatsVO> stats(String ruleCode) {
CaseRiskWarningStatsVO vo = caseRiskWarningDao.stats(ruleCode);
if (vo == null) {
vo = new CaseRiskWarningStatsVO();
vo.setRedCount(0L);
vo.setYellowCount(0L);
vo.setBlueCount(0L);
vo.setOpenCount(0L);
}
return ResponseDTO.ok(vo);
}
public ResponseDTO<List<Map<String, String>>> rules() {
List<Map<String, String>> list = new ArrayList<>();
CaseRiskWarningConst.ruleCatalog().forEach((code, name) -> {
Map<String, String> item = new LinkedHashMap<>();
item.put("code", code);
item.put("name", name);
list.add(item);
});
return ResponseDTO.ok(list);
}
public ResponseDTO<String> scan() {
int n = caseRiskWarningEngine.scanAll();
return ResponseDTO.ok("已扫描 " + n + " 件案件并刷新三色预警");
}
@Scheduled(cron = "0 0 * * * ?")
public void scheduledScan() {
caseRiskWarningEngine.scanAll();
}
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> process(CaseRiskWarningProcessForm form) {
CaseRiskWarningEntity entity = caseRiskWarningDao.selectById(form.getWarningId());
if (entity == null) {
return ResponseDTO.userErrorParam("预警不存在");
}
RequestEmployee user = (RequestEmployee) SmartRequestUtil.getRequestUser();
entity.setProcessMeasure(form.getMeasure());
entity.setProcessRemark(form.getRemark());
entity.setProcessUser(user == null ? null : user.getActualName());
entity.setProcessTime(LocalDateTime.now());
entity.setUpdateTime(LocalDateTime.now());
if (Boolean.TRUE.equals(entity.getStickyRed()) || CaseRiskWarningConst.COLOR_RED.equals(entity.getColor())) {
entity.setStickyRed(true);
entity.setStatus(CaseRiskWarningConst.STATUS_OPEN);
caseRiskWarningDao.updateById(entity);
return ResponseDTO.ok("已备案处置说明。红色通报不可消除、不可重置。");
}
entity.setStatus(CaseRiskWarningConst.STATUS_HANDLED);
caseRiskWarningDao.updateById(entity);
return ResponseDTO.ok("处置成功");
}
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> ignore(Long warningId) {
CaseRiskWarningEntity entity = caseRiskWarningDao.selectById(warningId);
if (entity == null) {
return ResponseDTO.userErrorParam("预警不存在");
}
if (Boolean.TRUE.equals(entity.getStickyRed()) || CaseRiskWarningConst.COLOR_RED.equals(entity.getColor())) {
return ResponseDTO.userErrorParam("红色通报不可忽略、不可消除");
}
entity.setStatus(CaseRiskWarningConst.STATUS_IGNORED);
entity.setUpdateTime(LocalDateTime.now());
caseRiskWarningDao.updateById(entity);
return ResponseDTO.ok("已忽略");
}
private void decorate(CaseRiskWarningVO vo) {
vo.setRuleName(CaseRiskWarningConst.ruleLabel(vo.getRuleCode()));
vo.setColorName(CaseRiskWarningConst.colorLabel(vo.getColor()));
vo.setCaseSourceName(CaseRiskWarningConst.sourceLabel(CaseRiskWarningEngine.resolveSourceType(
toFile(vo))));
if (CaseRiskWarningConst.STATUS_OPEN.equals(vo.getStatus())) {
vo.setStatusName(Boolean.TRUE.equals(vo.getStickyRed()) ? "已通报" : "待处理");
} else if (CaseRiskWarningConst.STATUS_HANDLED.equals(vo.getStatus())) {
vo.setStatusName("已处置");
} else if (CaseRiskWarningConst.STATUS_IGNORED.equals(vo.getStatus())) {
vo.setStatusName("已忽略");
} else {
vo.setStatusName(vo.getStatus());
}
}
private net.lab1024.sa.admin.module.business.caserisk.domain.entity.CaseFileEntity toFile(CaseRiskWarningVO vo) {
net.lab1024.sa.admin.module.business.caserisk.domain.entity.CaseFileEntity file =
new net.lab1024.sa.admin.module.business.caserisk.domain.entity.CaseFileEntity();
file.setCaseSource(vo.getCaseSource());
file.setCaseSourceSub(vo.getCaseSourceSub());
return file;
}
}

44
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/constant/CaseSupervisionConst.java

@ -0,0 +1,44 @@
package net.lab1024.sa.admin.module.business.casesupervision.constant;
public final class CaseSupervisionConst {
private CaseSupervisionConst() {
}
public static final String BIZ_CATEGORY_ECONOMIC = "经侦";
public static final String POLICE_STATION_KEYWORD = "派出所";
public static final String CASE_STATUS_PENDING_FILING = "pending_filing";
public static final String CASE_STATUS_INVESTIGATING = "investigating";
public static final String CASE_STATUS_CLOSED = "closed";
public static final String CASE_STATUS_WITHDRAWN = "withdrawn";
public static final String SCHEDULE_DRAFT = "draft";
public static final String SCHEDULE_PENDING_CONFIRM = "pending_confirm";
public static final String SCHEDULE_CONFIRMED = "confirmed";
public static String caseStatusName(String status) {
if (status == null) {
return "-";
}
return switch (status) {
case CASE_STATUS_PENDING_FILING -> "待立案";
case CASE_STATUS_INVESTIGATING -> "侦查中";
case CASE_STATUS_CLOSED -> "已结案";
case CASE_STATUS_WITHDRAWN -> "已撤销";
default -> status;
};
}
public static String scheduleStatusName(String status) {
if (status == null) {
return "-";
}
return switch (status) {
case SCHEDULE_DRAFT -> "草稿";
case SCHEDULE_PENDING_CONFIRM -> "待确认";
case SCHEDULE_CONFIRMED -> "已锁定";
default -> status;
};
}
}

31
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/controller/CaseNegativeListController.java

@ -0,0 +1,31 @@
package net.lab1024.sa.admin.module.business.casesupervision.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import net.lab1024.sa.admin.constant.AdminSwaggerTagConst;
import net.lab1024.sa.admin.module.business.casesupervision.domain.form.CaseNegativeListQueryForm;
import net.lab1024.sa.admin.module.business.casesupervision.domain.vo.CaseNegativeListVO;
import net.lab1024.sa.admin.module.business.casesupervision.service.CaseNegativeListService;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Tag(name = AdminSwaggerTagConst.Business.MANAGER_CASE_SUPERVISION)
public class CaseNegativeListController {
@Resource
private CaseNegativeListService caseNegativeListService;
@Operation(summary = "负面清单巡查分页")
@PostMapping("/negative-list/query")
@SaCheckPermission("negative-list:query")
public ResponseDTO<PageResult<CaseNegativeListVO>> query(@RequestBody @Valid CaseNegativeListQueryForm form) {
return caseNegativeListService.query(form);
}
}

74
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/controller/CaseWeeklyScheduleController.java

@ -0,0 +1,74 @@
package net.lab1024.sa.admin.module.business.casesupervision.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import net.lab1024.sa.admin.constant.AdminSwaggerTagConst;
import net.lab1024.sa.admin.module.business.casesupervision.domain.form.CaseNegativeListQueryForm;
import net.lab1024.sa.admin.module.business.casesupervision.domain.form.CaseWeeklyScheduleCreateForm;
import net.lab1024.sa.admin.module.business.casesupervision.domain.form.CaseWeeklyScheduleQueryForm;
import net.lab1024.sa.admin.module.business.casesupervision.domain.vo.CaseNegativeListVO;
import net.lab1024.sa.admin.module.business.casesupervision.domain.vo.CaseWeeklyScheduleVO;
import net.lab1024.sa.admin.module.business.casesupervision.service.CaseNegativeListService;
import net.lab1024.sa.admin.module.business.casesupervision.service.CaseWeeklyScheduleService;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Tag(name = AdminSwaggerTagConst.Business.MANAGER_CASE_SUPERVISION)
public class CaseWeeklyScheduleController {
@Resource
private CaseWeeklyScheduleService caseWeeklyScheduleService;
@Resource
private CaseNegativeListService caseNegativeListService;
@Operation(summary = "周调度分页")
@PostMapping("/weekly-schedule/query")
@SaCheckPermission("weekly-schedule:query")
public ResponseDTO<PageResult<CaseWeeklyScheduleVO>> query(@RequestBody @Valid CaseWeeklyScheduleQueryForm form) {
return caseWeeklyScheduleService.query(form);
}
@Operation(summary = "周调度详情")
@GetMapping("/weekly-schedule/{scheduleId}")
@SaCheckPermission("weekly-schedule:view")
public ResponseDTO<CaseWeeklyScheduleVO> detail(@PathVariable Long scheduleId) {
return caseWeeklyScheduleService.detail(scheduleId);
}
@Operation(summary = "周调度选案搜索")
@PostMapping("/weekly-schedule/search-case")
@SaCheckPermission("weekly-schedule:add")
public ResponseDTO<PageResult<CaseNegativeListVO>> searchCase(@RequestBody @Valid CaseNegativeListQueryForm form) {
return caseNegativeListService.query(form);
}
@Operation(summary = "新增周调度")
@PostMapping("/weekly-schedule/create")
@SaCheckPermission("weekly-schedule:add")
public ResponseDTO<Long> create(@RequestBody @Valid CaseWeeklyScheduleCreateForm form) {
return caseWeeklyScheduleService.create(form);
}
@Operation(summary = "推送周调度")
@PostMapping("/weekly-schedule/push/{scheduleId}")
@SaCheckPermission("weekly-schedule:push")
public ResponseDTO<String> push(@PathVariable Long scheduleId) {
return caseWeeklyScheduleService.push(scheduleId);
}
@Operation(summary = "确认周调度")
@PostMapping("/weekly-schedule/confirm/{scheduleId}")
@SaCheckPermission("weekly-schedule:confirm")
public ResponseDTO<String> confirm(@PathVariable Long scheduleId) {
return caseWeeklyScheduleService.confirm(scheduleId);
}
}

9
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/dao/CaseWeeklyScheduleCaseDao.java

@ -0,0 +1,9 @@
package net.lab1024.sa.admin.module.business.casesupervision.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import net.lab1024.sa.admin.module.business.casesupervision.domain.entity.CaseWeeklyScheduleCaseEntity;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface CaseWeeklyScheduleCaseDao extends BaseMapper<CaseWeeklyScheduleCaseEntity> {
}

19
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/dao/CaseWeeklyScheduleDao.java

@ -0,0 +1,19 @@
package net.lab1024.sa.admin.module.business.casesupervision.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import net.lab1024.sa.admin.module.business.casesupervision.domain.entity.CaseWeeklyScheduleEntity;
import net.lab1024.sa.admin.module.business.casesupervision.domain.form.CaseWeeklyScheduleQueryForm;
import net.lab1024.sa.admin.module.business.casesupervision.domain.vo.CaseWeeklyScheduleVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface CaseWeeklyScheduleDao extends BaseMapper<CaseWeeklyScheduleEntity> {
List<CaseWeeklyScheduleVO> query(Page<?> page, @Param("query") CaseWeeklyScheduleQueryForm queryForm);
String selectMaxScheduleNo(@Param("prefix") String prefix);
}

9
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/dao/CaseWeeklyScheduleMemberDao.java

@ -0,0 +1,9 @@
package net.lab1024.sa.admin.module.business.casesupervision.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import net.lab1024.sa.admin.module.business.casesupervision.domain.entity.CaseWeeklyScheduleMemberEntity;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface CaseWeeklyScheduleMemberDao extends BaseMapper<CaseWeeklyScheduleMemberEntity> {
}

28
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/domain/entity/CaseWeeklyScheduleCaseEntity.java

@ -0,0 +1,28 @@
package net.lab1024.sa.admin.module.business.casesupervision.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@TableName("t_case_weekly_schedule_case")
public class CaseWeeklyScheduleCaseEntity {
@TableId(type = IdType.AUTO)
private Long itemId;
private Long scheduleId;
private Long caseId;
private String caseNo;
private String caseName;
private String createDept;
private String handleDept;
private String handlerName;
private String caseStatus;
private LocalDateTime acceptTime;
private String itemContent;
private Integer sortNo;
private LocalDateTime createTime;
}

31
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/domain/entity/CaseWeeklyScheduleEntity.java

@ -0,0 +1,31 @@
package net.lab1024.sa.admin.module.business.casesupervision.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@TableName("t_case_weekly_schedule")
public class CaseWeeklyScheduleEntity {
@TableId(type = IdType.AUTO)
private Long scheduleId;
private String scheduleNo;
private String scheduleContent;
private LocalDateTime meetingTime;
private String meetingPlace;
private String scheduleUnit;
private String hostName;
private String recorderName;
private String status;
private Long createUserId;
private String createUserName;
private LocalDateTime pushTime;
private LocalDateTime lockTime;
private LocalDateTime createTime;
private LocalDateTime updateTime;
private Boolean deletedFlag;
}

22
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/domain/entity/CaseWeeklyScheduleMemberEntity.java

@ -0,0 +1,22 @@
package net.lab1024.sa.admin.module.business.casesupervision.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@TableName("t_case_weekly_schedule_member")
public class CaseWeeklyScheduleMemberEntity {
@TableId(type = IdType.AUTO)
private Long memberId;
private Long scheduleId;
private Long employeeId;
private String employeeName;
private Boolean confirmedFlag;
private LocalDateTime confirmTime;
private LocalDateTime createTime;
}

15
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/domain/form/CaseNegativeListQueryForm.java

@ -0,0 +1,15 @@
package net.lab1024.sa.admin.module.business.casesupervision.domain.form;
import lombok.Data;
import net.lab1024.sa.base.common.domain.PageParam;
@Data
public class CaseNegativeListQueryForm extends PageParam {
private String caseNo;
private String caseName;
private String caseStatus;
private String handleDept;
private String acceptTimeBegin;
private String acceptTimeEnd;
}

33
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/domain/form/CaseWeeklyScheduleCreateForm.java

@ -0,0 +1,33 @@
package net.lab1024.sa.admin.module.business.casesupervision.domain.form;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
@Data
public class CaseWeeklyScheduleCreateForm {
@NotEmpty(message = "请勾选调度案件")
private List<Long> caseIdList;
/** 与 caseIdList 同序的逐案调度内容 */
private List<String> itemContentList;
private String scheduleContent;
private LocalDateTime meetingTime;
private String meetingPlace;
private String scheduleUnit;
private String hostName;
private String recorderName;
private List<Long> memberIdList;
private Boolean pushFlag;
}

13
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/domain/form/CaseWeeklyScheduleQueryForm.java

@ -0,0 +1,13 @@
package net.lab1024.sa.admin.module.business.casesupervision.domain.form;
import lombok.Data;
import net.lab1024.sa.base.common.domain.PageParam;
@Data
public class CaseWeeklyScheduleQueryForm extends PageParam {
private String scheduleNo;
private String status;
private Boolean pendingMine;
private Long currentUserId;
}

20
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/domain/vo/CaseNegativeListVO.java

@ -0,0 +1,20 @@
package net.lab1024.sa.admin.module.business.casesupervision.domain.vo;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class CaseNegativeListVO {
private Long caseId;
private String caseNo;
private String caseName;
private String createDept;
private String handleDept;
private String handlerName;
private String caseStatus;
private String caseStatusName;
private LocalDateTime acceptTime;
private Boolean policeStationFlag;
}

21
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/domain/vo/CaseWeeklyScheduleCaseVO.java

@ -0,0 +1,21 @@
package net.lab1024.sa.admin.module.business.casesupervision.domain.vo;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class CaseWeeklyScheduleCaseVO {
private Long itemId;
private Long caseId;
private String caseNo;
private String caseName;
private String createDept;
private String handleDept;
private String handlerName;
private String caseStatus;
private String caseStatusName;
private LocalDateTime acceptTime;
private String itemContent;
}

15
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/domain/vo/CaseWeeklyScheduleMemberVO.java

@ -0,0 +1,15 @@
package net.lab1024.sa.admin.module.business.casesupervision.domain.vo;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class CaseWeeklyScheduleMemberVO {
private Long memberId;
private Long employeeId;
private String employeeName;
private Boolean confirmedFlag;
private LocalDateTime confirmTime;
}

36
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/domain/vo/CaseWeeklyScheduleVO.java

@ -0,0 +1,36 @@
package net.lab1024.sa.admin.module.business.casesupervision.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
@Data
public class CaseWeeklyScheduleVO {
private Long scheduleId;
private String scheduleNo;
private String scheduleContent;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime meetingTime;
private String meetingPlace;
private String scheduleUnit;
private String hostName;
private String recorderName;
private String status;
private String statusName;
private Long createUserId;
private String createUserName;
private LocalDateTime pushTime;
private LocalDateTime lockTime;
private LocalDateTime createTime;
private Integer caseCount;
private Integer memberCount;
private Integer confirmedCount;
private Boolean canPush;
private Boolean canConfirm;
private Boolean canPrint;
private List<CaseWeeklyScheduleCaseVO> caseList;
private List<CaseWeeklyScheduleMemberVO> memberList;
}

76
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/service/CaseNegativeListService.java

@ -0,0 +1,76 @@
package net.lab1024.sa.admin.module.business.casesupervision.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import net.lab1024.sa.admin.module.business.caserisk.dao.CaseFileDao;
import net.lab1024.sa.admin.module.business.caserisk.domain.entity.CaseFileEntity;
import net.lab1024.sa.admin.module.business.casesupervision.constant.CaseSupervisionConst;
import net.lab1024.sa.admin.module.business.casesupervision.domain.form.CaseNegativeListQueryForm;
import net.lab1024.sa.admin.module.business.casesupervision.domain.vo.CaseNegativeListVO;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartPageUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class CaseNegativeListService {
@Resource
private CaseFileDao caseFileDao;
public ResponseDTO<PageResult<CaseNegativeListVO>> query(CaseNegativeListQueryForm form) {
LambdaQueryWrapper<CaseFileEntity> wrapper = buildWrapper(form);
Page<CaseFileEntity> page = new Page<>(form.getPageNum(), form.getPageSize());
Page<CaseFileEntity> result = caseFileDao.selectPage(page, wrapper);
List<CaseNegativeListVO> list = result.getRecords().stream().map(this::toVo).collect(Collectors.toList());
return ResponseDTO.ok(SmartPageUtil.convert2PageResult(page, list));
}
private LambdaQueryWrapper<CaseFileEntity> buildWrapper(CaseNegativeListQueryForm form) {
LambdaQueryWrapper<CaseFileEntity> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CaseFileEntity::getDeletedFlag, Boolean.FALSE);
wrapper.eq(CaseFileEntity::getBizCategory, CaseSupervisionConst.BIZ_CATEGORY_ECONOMIC);
if (StringUtils.isNotBlank(form.getCaseNo())) {
wrapper.like(CaseFileEntity::getCaseNo, form.getCaseNo().trim());
}
if (StringUtils.isNotBlank(form.getCaseName())) {
wrapper.like(CaseFileEntity::getCaseName, form.getCaseName().trim());
}
if (StringUtils.isNotBlank(form.getCaseStatus())) {
wrapper.eq(CaseFileEntity::getCaseStatus, form.getCaseStatus());
}
if (StringUtils.isNotBlank(form.getHandleDept())) {
wrapper.like(CaseFileEntity::getHandleDept, form.getHandleDept().trim());
}
if (StringUtils.isNotBlank(form.getAcceptTimeBegin())) {
wrapper.ge(CaseFileEntity::getAcceptTime, LocalDate.parse(form.getAcceptTimeBegin()).atStartOfDay());
}
if (StringUtils.isNotBlank(form.getAcceptTimeEnd())) {
wrapper.lt(CaseFileEntity::getAcceptTime, LocalDate.parse(form.getAcceptTimeEnd()).plusDays(1).atStartOfDay());
}
wrapper.orderByDesc(CaseFileEntity::getAcceptTime);
wrapper.orderByDesc(CaseFileEntity::getCaseId);
return wrapper;
}
private CaseNegativeListVO toVo(CaseFileEntity entity) {
CaseNegativeListVO vo = new CaseNegativeListVO();
vo.setCaseId(entity.getCaseId());
vo.setCaseNo(entity.getCaseNo());
vo.setCaseName(entity.getCaseName());
vo.setCreateDept(entity.getCreateDept());
vo.setHandleDept(entity.getHandleDept());
vo.setHandlerName(entity.getHandlerName());
vo.setCaseStatus(entity.getCaseStatus());
vo.setCaseStatusName(CaseSupervisionConst.caseStatusName(entity.getCaseStatus()));
vo.setAcceptTime(entity.getAcceptTime());
vo.setPoliceStationFlag(StringUtils.contains(entity.getHandleDept(), CaseSupervisionConst.POLICE_STATION_KEYWORD));
return vo;
}
}

467
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/service/CaseWeeklyScheduleService.java

@ -0,0 +1,467 @@
package net.lab1024.sa.admin.module.business.casesupervision.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import net.lab1024.sa.admin.module.business.caserisk.dao.CaseFileDao;
import net.lab1024.sa.admin.module.business.caserisk.domain.entity.CaseFileEntity;
import net.lab1024.sa.admin.module.business.casesupervision.constant.CaseSupervisionConst;
import net.lab1024.sa.admin.module.business.casesupervision.dao.CaseWeeklyScheduleCaseDao;
import net.lab1024.sa.admin.module.business.casesupervision.dao.CaseWeeklyScheduleDao;
import net.lab1024.sa.admin.module.business.casesupervision.dao.CaseWeeklyScheduleMemberDao;
import net.lab1024.sa.admin.module.business.casesupervision.domain.entity.CaseWeeklyScheduleCaseEntity;
import net.lab1024.sa.admin.module.business.casesupervision.domain.entity.CaseWeeklyScheduleEntity;
import net.lab1024.sa.admin.module.business.casesupervision.domain.entity.CaseWeeklyScheduleMemberEntity;
import net.lab1024.sa.admin.module.business.casesupervision.domain.form.CaseWeeklyScheduleCreateForm;
import net.lab1024.sa.admin.module.business.casesupervision.domain.form.CaseWeeklyScheduleQueryForm;
import net.lab1024.sa.admin.module.business.casesupervision.domain.vo.CaseWeeklyScheduleCaseVO;
import net.lab1024.sa.admin.module.business.casesupervision.domain.vo.CaseWeeklyScheduleMemberVO;
import net.lab1024.sa.admin.module.business.casesupervision.domain.vo.CaseWeeklyScheduleVO;
import net.lab1024.sa.admin.module.business.casesupervision.support.CaseSupervisionNotifySupport;
import net.lab1024.sa.admin.module.system.employee.dao.EmployeeDao;
import net.lab1024.sa.admin.module.system.employee.domain.vo.EmployeeVO;
import net.lab1024.sa.admin.module.system.login.domain.RequestEmployee;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartPageUtil;
import net.lab1024.sa.base.common.util.SmartRequestUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
@Service
public class CaseWeeklyScheduleService {
@Resource
private CaseWeeklyScheduleDao caseWeeklyScheduleDao;
@Resource
private CaseWeeklyScheduleCaseDao caseWeeklyScheduleCaseDao;
@Resource
private CaseWeeklyScheduleMemberDao caseWeeklyScheduleMemberDao;
@Resource
private CaseFileDao caseFileDao;
@Resource
private EmployeeDao employeeDao;
@Resource
private CaseSupervisionNotifySupport caseSupervisionNotifySupport;
public ResponseDTO<PageResult<CaseWeeklyScheduleVO>> query(CaseWeeklyScheduleQueryForm form) {
RequestEmployee user = currentUser();
form.setCurrentUserId(user == null ? null : user.getEmployeeId());
Page<?> page = SmartPageUtil.convert2PageQuery(form);
List<CaseWeeklyScheduleVO> list = caseWeeklyScheduleDao.query(page, form);
decorateList(list, form.getCurrentUserId());
return ResponseDTO.ok(SmartPageUtil.convert2PageResult(page, list));
}
public ResponseDTO<CaseWeeklyScheduleVO> detail(Long scheduleId) {
CaseWeeklyScheduleEntity entity = caseWeeklyScheduleDao.selectById(scheduleId);
if (entity == null || Boolean.TRUE.equals(entity.getDeletedFlag())) {
return ResponseDTO.userErrorParam("调度记录不存在");
}
RequestEmployee user = currentUser();
Long userId = user == null ? null : user.getEmployeeId();
CaseWeeklyScheduleVO vo = toBaseVo(entity);
vo.setCaseList(loadCases(scheduleId));
vo.setMemberList(loadMembers(scheduleId));
vo.setCaseCount(vo.getCaseList().size());
vo.setMemberCount(vo.getMemberList().size());
vo.setConfirmedCount((int) vo.getMemberList().stream().filter(m -> Boolean.TRUE.equals(m.getConfirmedFlag())).count());
decorateFlags(vo, userId, vo.getMemberList());
return ResponseDTO.ok(vo);
}
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<Long> create(CaseWeeklyScheduleCreateForm form) {
RequestEmployee user = currentUser();
if (user == null) {
return ResponseDTO.userErrorParam("请先登录");
}
List<CaseFileEntity> files = loadEconomicCases(form.getCaseIdList());
if (files.size() != uniqueIds(form.getCaseIdList()).size()) {
return ResponseDTO.userErrorParam("存在无效或非经侦案件,请重新勾选");
}
boolean push = Boolean.TRUE.equals(form.getPushFlag());
String joinedContent = joinScheduleContent(files, form.getItemContentList(), form.getScheduleContent());
if (push) {
ResponseDTO<String> pushCheck = validatePush(joinedContent, form.getMemberIdList());
if (!Boolean.TRUE.equals(pushCheck.getOk())) {
return ResponseDTO.userErrorParam(pushCheck.getMsg());
}
}
LocalDateTime now = LocalDateTime.now();
CaseWeeklyScheduleEntity entity = new CaseWeeklyScheduleEntity();
entity.setScheduleNo(nextScheduleNo());
entity.setScheduleContent(StringUtils.trimToEmpty(joinedContent));
entity.setMeetingTime(form.getMeetingTime());
entity.setMeetingPlace(StringUtils.trimToNull(form.getMeetingPlace()));
entity.setScheduleUnit(StringUtils.defaultIfBlank(StringUtils.trimToNull(form.getScheduleUnit()), user.getDepartmentName()));
entity.setHostName(StringUtils.trimToNull(form.getHostName()));
entity.setRecorderName(StringUtils.trimToNull(form.getRecorderName()));
entity.setStatus(CaseSupervisionConst.SCHEDULE_DRAFT);
entity.setCreateUserId(user.getEmployeeId());
entity.setCreateUserName(user.getActualName());
entity.setCreateTime(now);
entity.setUpdateTime(now);
entity.setDeletedFlag(Boolean.FALSE);
caseWeeklyScheduleDao.insert(entity);
int sort = 0;
List<String> itemContents = form.getItemContentList();
for (CaseFileEntity file : files) {
CaseWeeklyScheduleCaseEntity item = new CaseWeeklyScheduleCaseEntity();
item.setScheduleId(entity.getScheduleId());
item.setCaseId(file.getCaseId());
item.setCaseNo(file.getCaseNo());
item.setCaseName(file.getCaseName());
item.setCreateDept(file.getCreateDept());
item.setHandleDept(file.getHandleDept());
item.setHandlerName(file.getHandlerName());
item.setCaseStatus(file.getCaseStatus());
item.setAcceptTime(file.getAcceptTime());
item.setItemContent(itemContentAt(itemContents, sort));
item.setSortNo(sort++);
item.setCreateTime(now);
caseWeeklyScheduleCaseDao.insert(item);
}
saveMembers(entity.getScheduleId(), form.getMemberIdList(), now);
if (push) {
ResponseDTO<String> pushed = doPush(entity);
if (!Boolean.TRUE.equals(pushed.getOk())) {
return ResponseDTO.userErrorParam(pushed.getMsg());
}
}
return ResponseDTO.ok(entity.getScheduleId());
}
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> push(Long scheduleId) {
CaseWeeklyScheduleEntity entity = caseWeeklyScheduleDao.selectById(scheduleId);
if (entity == null || Boolean.TRUE.equals(entity.getDeletedFlag())) {
return ResponseDTO.userErrorParam("调度记录不存在");
}
RequestEmployee user = currentUser();
if (user == null || !Objects.equals(user.getEmployeeId(), entity.getCreateUserId())) {
return ResponseDTO.userErrorParam("仅创建人可推送");
}
return doPush(entity);
}
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> confirm(Long scheduleId) {
CaseWeeklyScheduleEntity entity = caseWeeklyScheduleDao.selectById(scheduleId);
if (entity == null || Boolean.TRUE.equals(entity.getDeletedFlag())) {
return ResponseDTO.userErrorParam("调度记录不存在");
}
if (!CaseSupervisionConst.SCHEDULE_PENDING_CONFIRM.equals(entity.getStatus())) {
return ResponseDTO.userErrorParam("当前状态不可确认");
}
RequestEmployee user = currentUser();
if (user == null) {
return ResponseDTO.userErrorParam("请先登录");
}
LambdaQueryWrapper<CaseWeeklyScheduleMemberEntity> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CaseWeeklyScheduleMemberEntity::getScheduleId, scheduleId);
wrapper.eq(CaseWeeklyScheduleMemberEntity::getEmployeeId, user.getEmployeeId());
CaseWeeklyScheduleMemberEntity member = caseWeeklyScheduleMemberDao.selectOne(wrapper);
if (member == null) {
return ResponseDTO.userErrorParam("您不在参加调度人员名单中");
}
if (Boolean.TRUE.equals(member.getConfirmedFlag())) {
return ResponseDTO.userErrorParam("您已确认");
}
LocalDateTime now = LocalDateTime.now();
member.setConfirmedFlag(Boolean.TRUE);
member.setConfirmTime(now);
caseWeeklyScheduleMemberDao.updateById(member);
List<CaseWeeklyScheduleMemberEntity> members = listMembers(scheduleId);
boolean allConfirmed = members.stream().allMatch(m -> Boolean.TRUE.equals(m.getConfirmedFlag()));
if (allConfirmed) {
entity.setStatus(CaseSupervisionConst.SCHEDULE_CONFIRMED);
entity.setLockTime(now);
entity.setUpdateTime(now);
caseWeeklyScheduleDao.updateById(entity);
notifyLocked(entity, members);
return ResponseDTO.ok("已确认,调度记录已锁定");
}
entity.setUpdateTime(now);
caseWeeklyScheduleDao.updateById(entity);
return ResponseDTO.ok("确认成功,等待其余人员确认");
}
private ResponseDTO<String> doPush(CaseWeeklyScheduleEntity entity) {
if (!CaseSupervisionConst.SCHEDULE_DRAFT.equals(entity.getStatus())) {
return ResponseDTO.userErrorParam("仅草稿可推送");
}
if (StringUtils.isBlank(entity.getScheduleContent())) {
return ResponseDTO.userErrorParam("请输入调度内容");
}
List<CaseWeeklyScheduleMemberEntity> members = listMembers(entity.getScheduleId());
if (CollectionUtils.isEmpty(members)) {
return ResponseDTO.userErrorParam("请勾选参加调度人员");
}
long caseCount = caseWeeklyScheduleCaseDao.selectCount(new LambdaQueryWrapper<CaseWeeklyScheduleCaseEntity>()
.eq(CaseWeeklyScheduleCaseEntity::getScheduleId, entity.getScheduleId()));
if (caseCount <= 0) {
return ResponseDTO.userErrorParam("请勾选调度案件");
}
LocalDateTime now = LocalDateTime.now();
entity.setStatus(CaseSupervisionConst.SCHEDULE_PENDING_CONFIRM);
entity.setPushTime(now);
entity.setUpdateTime(now);
caseWeeklyScheduleDao.updateById(entity);
for (CaseWeeklyScheduleMemberEntity member : members) {
caseSupervisionNotifySupport.notifySchedulePush(member.getEmployeeId(), entity.getScheduleNo(), entity.getScheduleId());
}
return ResponseDTO.ok("已推送,等待参加人员确认");
}
private void saveMembers(Long scheduleId, List<Long> memberIdList, LocalDateTime now) {
if (CollectionUtils.isEmpty(memberIdList)) {
return;
}
Set<Long> ids = new LinkedHashSet<>(memberIdList);
ids.remove(null);
if (ids.isEmpty()) {
return;
}
List<EmployeeVO> employees = employeeDao.getEmployeeByIds(ids);
Map<Long, EmployeeVO> map = employees.stream().collect(Collectors.toMap(EmployeeVO::getEmployeeId, Function.identity(), (a, b) -> a));
for (Long employeeId : ids) {
EmployeeVO employee = map.get(employeeId);
CaseWeeklyScheduleMemberEntity member = new CaseWeeklyScheduleMemberEntity();
member.setScheduleId(scheduleId);
member.setEmployeeId(employeeId);
member.setEmployeeName(employee == null ? String.valueOf(employeeId) : employee.getActualName());
member.setConfirmedFlag(Boolean.FALSE);
member.setCreateTime(now);
caseWeeklyScheduleMemberDao.insert(member);
}
}
private Set<Long> uniqueIds(List<Long> caseIdList) {
Set<Long> ids = new LinkedHashSet<>();
if (CollectionUtils.isEmpty(caseIdList)) {
return ids;
}
for (Long id : caseIdList) {
if (id != null) {
ids.add(id);
}
}
return ids;
}
private List<CaseFileEntity> loadEconomicCases(List<Long> caseIdList) {
Set<Long> ids = uniqueIds(caseIdList);
if (ids.isEmpty()) {
return List.of();
}
List<CaseFileEntity> files = caseFileDao.selectList(new LambdaQueryWrapper<CaseFileEntity>()
.in(CaseFileEntity::getCaseId, ids)
.eq(CaseFileEntity::getDeletedFlag, Boolean.FALSE)
.eq(CaseFileEntity::getBizCategory, CaseSupervisionConst.BIZ_CATEGORY_ECONOMIC));
Map<Long, CaseFileEntity> map = files.stream().collect(Collectors.toMap(CaseFileEntity::getCaseId, Function.identity(), (a, b) -> a));
List<CaseFileEntity> ordered = new ArrayList<>();
for (Long id : ids) {
CaseFileEntity file = map.get(id);
if (file != null) {
ordered.add(file);
}
}
return ordered;
}
private ResponseDTO<String> validatePush(String content, List<Long> memberIdList) {
if (StringUtils.isBlank(content)) {
return ResponseDTO.userErrorParam("请输入调度内容");
}
if (CollectionUtils.isEmpty(memberIdList)) {
return ResponseDTO.userErrorParam("请勾选参加调度人员");
}
return ResponseDTO.ok();
}
private String itemContentAt(List<String> itemContents, int index) {
if (itemContents == null || index < 0 || index >= itemContents.size()) {
return null;
}
return StringUtils.trimToNull(itemContents.get(index));
}
private String joinScheduleContent(List<CaseFileEntity> files, List<String> itemContents, String fallback) {
StringBuilder builder = new StringBuilder();
if (CollectionUtils.isNotEmpty(files)) {
for (int i = 0; i < files.size(); i++) {
String itemContent = itemContentAt(itemContents, i);
if (StringUtils.isBlank(itemContent)) {
continue;
}
if (builder.length() > 0) {
builder.append('\n');
}
builder.append(itemContent.trim());
}
}
if (builder.length() > 0) {
return builder.toString();
}
return StringUtils.trimToEmpty(fallback);
}
private String nextScheduleNo() {
String prefix = "DD" + LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE);
String max = caseWeeklyScheduleDao.selectMaxScheduleNo(prefix);
int seq = 1;
if (StringUtils.isNotBlank(max) && max.length() > prefix.length()) {
try {
seq = Integer.parseInt(max.substring(prefix.length())) + 1;
} catch (NumberFormatException ignored) {
seq = 1;
}
}
return prefix + String.format("%03d", seq);
}
private void decorateList(List<CaseWeeklyScheduleVO> list, Long currentUserId) {
if (CollectionUtils.isEmpty(list)) {
return;
}
List<Long> ids = list.stream().map(CaseWeeklyScheduleVO::getScheduleId).toList();
List<CaseWeeklyScheduleMemberEntity> mine = List.of();
if (currentUserId != null) {
mine = caseWeeklyScheduleMemberDao.selectList(new LambdaQueryWrapper<CaseWeeklyScheduleMemberEntity>()
.in(CaseWeeklyScheduleMemberEntity::getScheduleId, ids)
.eq(CaseWeeklyScheduleMemberEntity::getEmployeeId, currentUserId));
}
Map<Long, CaseWeeklyScheduleMemberEntity> mineMap = mine.stream()
.collect(Collectors.toMap(CaseWeeklyScheduleMemberEntity::getScheduleId, Function.identity(), (a, b) -> a));
for (CaseWeeklyScheduleVO vo : list) {
vo.setStatusName(CaseSupervisionConst.scheduleStatusName(vo.getStatus()));
vo.setCanPrint(CaseSupervisionConst.SCHEDULE_CONFIRMED.equals(vo.getStatus()));
vo.setCanPush(CaseSupervisionConst.SCHEDULE_DRAFT.equals(vo.getStatus())
&& currentUserId != null
&& Objects.equals(currentUserId, vo.getCreateUserId()));
CaseWeeklyScheduleMemberEntity self = mineMap.get(vo.getScheduleId());
vo.setCanConfirm(CaseSupervisionConst.SCHEDULE_PENDING_CONFIRM.equals(vo.getStatus())
&& self != null
&& !Boolean.TRUE.equals(self.getConfirmedFlag()));
}
}
private void decorateFlags(CaseWeeklyScheduleVO vo, Long currentUserId, List<CaseWeeklyScheduleMemberVO> members) {
vo.setStatusName(CaseSupervisionConst.scheduleStatusName(vo.getStatus()));
vo.setCanPrint(CaseSupervisionConst.SCHEDULE_CONFIRMED.equals(vo.getStatus()));
vo.setCanPush(CaseSupervisionConst.SCHEDULE_DRAFT.equals(vo.getStatus())
&& currentUserId != null
&& Objects.equals(currentUserId, vo.getCreateUserId()));
boolean memberPending = CollectionUtils.isNotEmpty(members) && members.stream()
.anyMatch(m -> m != null && currentUserId != null
&& Objects.equals(currentUserId, m.getEmployeeId())
&& !Boolean.TRUE.equals(m.getConfirmedFlag()));
vo.setCanConfirm(CaseSupervisionConst.SCHEDULE_PENDING_CONFIRM.equals(vo.getStatus()) && memberPending);
}
private CaseWeeklyScheduleVO toBaseVo(CaseWeeklyScheduleEntity entity) {
CaseWeeklyScheduleVO vo = new CaseWeeklyScheduleVO();
vo.setScheduleId(entity.getScheduleId());
vo.setScheduleNo(entity.getScheduleNo());
vo.setScheduleContent(entity.getScheduleContent());
vo.setMeetingTime(entity.getMeetingTime());
vo.setMeetingPlace(entity.getMeetingPlace());
vo.setScheduleUnit(entity.getScheduleUnit());
vo.setHostName(entity.getHostName());
vo.setRecorderName(entity.getRecorderName());
vo.setStatus(entity.getStatus());
vo.setCreateUserId(entity.getCreateUserId());
vo.setCreateUserName(entity.getCreateUserName());
vo.setPushTime(entity.getPushTime());
vo.setLockTime(entity.getLockTime());
vo.setCreateTime(entity.getCreateTime());
return vo;
}
private List<CaseWeeklyScheduleCaseVO> loadCases(Long scheduleId) {
List<CaseWeeklyScheduleCaseEntity> list = caseWeeklyScheduleCaseDao.selectList(
new LambdaQueryWrapper<CaseWeeklyScheduleCaseEntity>()
.eq(CaseWeeklyScheduleCaseEntity::getScheduleId, scheduleId)
.orderByAsc(CaseWeeklyScheduleCaseEntity::getSortNo)
.orderByAsc(CaseWeeklyScheduleCaseEntity::getItemId));
List<CaseWeeklyScheduleCaseVO> result = new ArrayList<>();
for (CaseWeeklyScheduleCaseEntity item : list) {
CaseWeeklyScheduleCaseVO vo = new CaseWeeklyScheduleCaseVO();
vo.setItemId(item.getItemId());
vo.setCaseId(item.getCaseId());
vo.setCaseNo(item.getCaseNo());
vo.setCaseName(item.getCaseName());
vo.setCreateDept(item.getCreateDept());
vo.setHandleDept(item.getHandleDept());
vo.setHandlerName(item.getHandlerName());
vo.setCaseStatus(item.getCaseStatus());
vo.setCaseStatusName(CaseSupervisionConst.caseStatusName(item.getCaseStatus()));
vo.setAcceptTime(item.getAcceptTime());
vo.setItemContent(item.getItemContent());
result.add(vo);
}
return result;
}
private List<CaseWeeklyScheduleMemberVO> loadMembers(Long scheduleId) {
return toMemberVoList(listMembers(scheduleId));
}
private List<CaseWeeklyScheduleMemberEntity> listMembers(Long scheduleId) {
return caseWeeklyScheduleMemberDao.selectList(new LambdaQueryWrapper<CaseWeeklyScheduleMemberEntity>()
.eq(CaseWeeklyScheduleMemberEntity::getScheduleId, scheduleId)
.orderByAsc(CaseWeeklyScheduleMemberEntity::getMemberId));
}
private List<CaseWeeklyScheduleMemberVO> toMemberVoList(List<CaseWeeklyScheduleMemberEntity> list) {
List<CaseWeeklyScheduleMemberVO> result = new ArrayList<>();
if (CollectionUtils.isEmpty(list)) {
return result;
}
for (CaseWeeklyScheduleMemberEntity item : list) {
if (item == null) {
continue;
}
CaseWeeklyScheduleMemberVO vo = new CaseWeeklyScheduleMemberVO();
vo.setMemberId(item.getMemberId());
vo.setEmployeeId(item.getEmployeeId());
vo.setEmployeeName(item.getEmployeeName());
vo.setConfirmedFlag(item.getConfirmedFlag());
vo.setConfirmTime(item.getConfirmTime());
result.add(vo);
}
return result;
}
private void notifyLocked(CaseWeeklyScheduleEntity entity, List<CaseWeeklyScheduleMemberEntity> members) {
Set<Long> receivers = members.stream().map(CaseWeeklyScheduleMemberEntity::getEmployeeId).collect(Collectors.toCollection(LinkedHashSet::new));
if (entity.getCreateUserId() != null) {
receivers.add(entity.getCreateUserId());
}
for (Long employeeId : receivers) {
caseSupervisionNotifySupport.notifyScheduleLocked(employeeId, entity.getScheduleNo(), entity.getScheduleId());
}
}
private RequestEmployee currentUser() {
return (RequestEmployee) SmartRequestUtil.getRequestUser();
}
}

40
economic-crime-api/economic-crime-admin/src/main/java/net/lab1024/sa/admin/module/business/casesupervision/support/CaseSupervisionNotifySupport.java

@ -0,0 +1,40 @@
package net.lab1024.sa.admin.module.business.casesupervision.support;
import jakarta.annotation.Resource;
import net.lab1024.sa.base.common.enumeration.UserTypeEnum;
import net.lab1024.sa.base.module.support.message.constant.MessageTypeEnum;
import net.lab1024.sa.base.module.support.message.domain.MessageSendForm;
import net.lab1024.sa.base.module.support.message.service.MessageService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
@Component
public class CaseSupervisionNotifySupport {
@Resource
private MessageService messageService;
public void notifySchedulePush(Long receiverUserId, String scheduleNo, Long scheduleId) {
notifyUser(receiverUserId, "周调度待确认",
"调度记录【" + scheduleNo + "】已推送,请确认调度内容。", scheduleId);
}
public void notifyScheduleLocked(Long receiverUserId, String scheduleNo, Long scheduleId) {
notifyUser(receiverUserId, "周调度已锁定",
"调度记录【" + scheduleNo + "】已全部确认并锁定,可打印。", scheduleId);
}
private void notifyUser(Long receiverUserId, String title, String content, Long dataId) {
if (receiverUserId == null || StringUtils.isBlank(title) || StringUtils.isBlank(content)) {
return;
}
MessageSendForm form = new MessageSendForm();
form.setMessageType(MessageTypeEnum.MAIL.getValue());
form.setReceiverUserType(UserTypeEnum.ADMIN_EMPLOYEE.getValue());
form.setReceiverUserId(receiverUserId);
form.setTitle(title);
form.setContent(content);
form.setDataId(dataId);
messageService.sendMessage(form);
}
}

65
economic-crime-api/economic-crime-admin/src/main/resources/mapper/business/caserisk/CaseRiskWarningMapper.xml

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="net.lab1024.sa.admin.module.business.caserisk.dao.CaseRiskWarningDao">
<select id="query" resultType="net.lab1024.sa.admin.module.business.caserisk.domain.vo.CaseRiskWarningVO">
SELECT
w.warning_id AS warningId,
w.warning_no AS warningNo,
w.case_id AS caseId,
c.case_no AS caseNo,
c.case_name AS caseName,
c.case_source AS caseSource,
c.case_source_sub AS caseSourceSub,
c.handler_name AS handlerName,
w.rule_code AS ruleCode,
w.track_key AS trackKey,
w.color AS color,
w.reason AS reason,
w.elapsed_days AS elapsedDays,
w.sticky_red AS stickyRed,
w.status AS status,
w.process_measure AS processMeasure,
w.process_remark AS processRemark,
w.process_user AS processUser,
w.process_time AS processTime,
w.trigger_time AS triggerTime
FROM t_case_risk_warning w
INNER JOIN t_case_file c ON c.case_id = w.case_id AND c.deleted_flag = FALSE
<where>
w.status IN ('open', 'handled', 'ignored')
<if test="query.caseNo != null and query.caseNo != ''">
AND c.case_no ILIKE '%' || #{query.caseNo} || '%'
</if>
<if test="query.caseName != null and query.caseName != ''">
AND c.case_name ILIKE '%' || #{query.caseName} || '%'
</if>
<if test="query.color != null and query.color != ''">
AND w.color = #{query.color}
</if>
<if test="query.ruleCode != null and query.ruleCode != ''">
AND w.rule_code = #{query.ruleCode}
</if>
<if test="query.status != null and query.status != ''">
AND w.status = #{query.status}
</if>
</where>
ORDER BY
CASE w.color WHEN 'red' THEN 1 WHEN 'yellow' THEN 2 ELSE 3 END,
w.trigger_time DESC
</select>
<select id="stats" resultType="net.lab1024.sa.admin.module.business.caserisk.domain.vo.CaseRiskWarningStatsVO">
SELECT
COALESCE(SUM(CASE WHEN color = 'red' AND status IN ('open', 'handled', 'ignored') THEN 1 ELSE 0 END), 0) AS redCount,
COALESCE(SUM(CASE WHEN color = 'yellow' AND status = 'open' THEN 1 ELSE 0 END), 0) AS yellowCount,
COALESCE(SUM(CASE WHEN color = 'blue' AND status = 'open' THEN 1 ELSE 0 END), 0) AS blueCount,
COALESCE(SUM(CASE WHEN status = 'open' THEN 1 ELSE 0 END), 0) AS openCount
FROM t_case_risk_warning
<where>
<if test="ruleCode != null and ruleCode != ''">
AND rule_code = #{ruleCode}
</if>
</where>
</select>
</mapper>

46
economic-crime-api/economic-crime-admin/src/main/resources/mapper/business/casesupervision/CaseWeeklyScheduleMapper.xml

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="net.lab1024.sa.admin.module.business.casesupervision.dao.CaseWeeklyScheduleDao">
<select id="query" resultType="net.lab1024.sa.admin.module.business.casesupervision.domain.vo.CaseWeeklyScheduleVO">
SELECT
s.schedule_id AS scheduleId,
s.schedule_no AS scheduleNo,
s.schedule_content AS scheduleContent,
s.status AS status,
s.create_user_id AS createUserId,
s.create_user_name AS createUserName,
s.push_time AS pushTime,
s.lock_time AS lockTime,
s.create_time AS createTime,
(SELECT COUNT(1) FROM t_case_weekly_schedule_case c WHERE c.schedule_id = s.schedule_id) AS caseCount,
(SELECT COUNT(1) FROM t_case_weekly_schedule_member m WHERE m.schedule_id = s.schedule_id) AS memberCount,
(SELECT COUNT(1) FROM t_case_weekly_schedule_member m WHERE m.schedule_id = s.schedule_id AND m.confirmed_flag = TRUE) AS confirmedCount
FROM t_case_weekly_schedule s
<where>
s.deleted_flag = FALSE
<if test="query.scheduleNo != null and query.scheduleNo != ''">
AND s.schedule_no ILIKE '%' || #{query.scheduleNo} || '%'
</if>
<if test="query.status != null and query.status != ''">
AND s.status = #{query.status}
</if>
<if test="query.pendingMine != null and query.pendingMine == true and query.currentUserId != null">
AND s.status = 'pending_confirm'
AND EXISTS (
SELECT 1 FROM t_case_weekly_schedule_member m
WHERE m.schedule_id = s.schedule_id
AND m.employee_id = #{query.currentUserId}
AND COALESCE(m.confirmed_flag, FALSE) = FALSE
)
</if>
</where>
ORDER BY s.create_time DESC, s.schedule_id DESC
</select>
<select id="selectMaxScheduleNo" resultType="java.lang.String">
SELECT MAX(schedule_no)
FROM t_case_weekly_schedule
WHERE schedule_no LIKE #{prefix} || '%'
</select>
</mapper>

5
economic-crime-web/src/api/business/case-management/negative-list-api.js

@ -0,0 +1,5 @@
import { getRequest, postRequest } from '/@/lib/axios';
export const negativeListApi = {
query: (param) => postRequest('/negative-list/query', param),
};

10
economic-crime-web/src/api/business/case-management/risk-warning-api.js

@ -0,0 +1,10 @@
import { getRequest, postRequest } from '/@/lib/axios';
export const riskWarningApi = {
query: (param) => postRequest('/risk-warning/query', param),
stats: (ruleCode) => getRequest('/risk-warning/stats', { ruleCode }),
rules: () => getRequest('/risk-warning/rules'),
scan: () => postRequest('/risk-warning/scan'),
process: (param) => postRequest('/risk-warning/process', param),
ignore: (id) => postRequest(`/risk-warning/ignore/${id}`),
};

10
economic-crime-web/src/api/business/case-management/weekly-schedule-api.js

@ -0,0 +1,10 @@
import { getRequest, postRequest } from '/@/lib/axios';
export const weeklyScheduleApi = {
query: (param) => postRequest('/weekly-schedule/query', param),
searchCase: (param) => postRequest('/weekly-schedule/search-case', param),
detail: (id) => getRequest(`/weekly-schedule/${id}`),
create: (param) => postRequest('/weekly-schedule/create', param),
push: (id) => postRequest(`/weekly-schedule/push/${id}`),
confirm: (id) => postRequest(`/weekly-schedule/confirm/${id}`),
};

30
economic-crime-web/src/constants/business/case-management/case-supervision-const.js

@ -0,0 +1,30 @@
export const CASE_STATUS_ENUM = {
PENDING_FILING: { value: 'pending_filing', desc: '待立案' },
INVESTIGATING: { value: 'investigating', desc: '侦查中' },
CLOSED: { value: 'closed', desc: '已结案' },
WITHDRAWN: { value: 'withdrawn', desc: '已撤销' },
};
export const WEEKLY_SCHEDULE_STATUS_ENUM = {
DRAFT: { value: 'draft', desc: '草稿' },
PENDING_CONFIRM: { value: 'pending_confirm', desc: '待确认' },
CONFIRMED: { value: 'confirmed', desc: '已锁定' },
};
export function getCaseStatusName(status) {
return Object.values(CASE_STATUS_ENUM).find((item) => item.value === status)?.desc || status || '-';
}
export function getWeeklyScheduleStatusName(status) {
return Object.values(WEEKLY_SCHEDULE_STATUS_ENUM).find((item) => item.value === status)?.desc || status || '-';
}
export function getWeeklyScheduleStatusColor(status) {
if (status === 'confirmed') {
return 'success';
}
if (status === 'pending_confirm') {
return 'warning';
}
return 'default';
}

42
economic-crime-web/src/constants/business/case-management/risk-warning-const.js

@ -0,0 +1,42 @@
export const RISK_COLOR_ENUM = {
RED: { value: 'red', desc: '问题通报', tag: 'error' },
YELLOW: { value: 'yellow', desc: '问题预警', tag: 'warning' },
BLUE: { value: 'blue', desc: '普通提醒', tag: 'processing' },
};
export const RISK_STATUS_ENUM = {
OPEN: { value: 'open', desc: '待处理' },
HANDLED: { value: 'handled', desc: '已处置' },
IGNORED: { value: 'ignored', desc: '已忽略' },
};
export const RISK_RULE_OPTIONS = [
{ value: 'accept_timeout', desc: '审议受案后超24小时未受案', path: '/case-management/risk-warning/accept-timeout' },
{ value: 'filing_deadline', desc: '立案审查期限', path: '/case-management/risk-warning/filing-deadline' },
{ value: 'bail_summons', desc: '取保候审传讯', path: '/case-management/risk-warning/bail-summons' },
{ value: 'bail_expire', desc: '取保候审期限', path: '/case-management/risk-warning/bail-expire' },
{ value: 'accept_inactivity', desc: '受案后无活动日志', path: '/case-management/risk-warning/accept-inactivity' },
{ value: 'filing_inactivity', desc: '立案后无活动日志', path: '/case-management/risk-warning/filing-inactivity' },
{ value: 'detention_notice', desc: '刑事拘留通知书', path: '/case-management/risk-warning/detention-notice' },
{ value: 'detention_deadline', desc: '刑事拘留羁押期限', path: '/case-management/risk-warning/detention-deadline' },
{ value: 'arrest_notice', desc: '逮捕后通知书', path: '/case-management/risk-warning/arrest-notice' },
{ value: 'arrest_deadline', desc: '逮捕后侦查羁押期限', path: '/case-management/risk-warning/arrest-deadline' },
{ value: 'residential_expire', desc: '监视居住期限', path: '/case-management/risk-warning/residential-expire' },
{ value: 'residential_summons', desc: '监视居住传讯', path: '/case-management/risk-warning/residential-summons' },
{ value: 'designated_notice', desc: '指定居所监视居住通知书', path: '/case-management/risk-warning/designated-notice' },
];
export function resolveRiskRuleByPath(path) {
if (!path) {
return null;
}
return RISK_RULE_OPTIONS.find((item) => item.path === path) || null;
}
export function getRiskColorLabel(color) {
return Object.values(RISK_COLOR_ENUM).find((item) => item.value === color)?.desc || color || '-';
}
export function getRiskColorTag(color) {
return Object.values(RISK_COLOR_ENUM).find((item) => item.value === color)?.tag || 'default';
}

159
economic-crime-web/src/utils/print-weekly-schedule.js

@ -0,0 +1,159 @@
import dayjs from 'dayjs';
const PRINT_FRAME_ID = 'weekly-schedule-print-frame';
const CN_ORDINAL = [
'一', '二', '三', '四', '五', '六', '七', '八', '九', '十',
'十一', '十二', '十三', '十四', '十五', '十六', '十七', '十八', '十九', '二十',
];
export function chineseOrdinal(index0) {
return CN_ORDINAL[index0] || String(index0 + 1);
}
export function minutesTitleUnit(unit) {
const raw = String(unit || '').trim();
if (!raw) {
return 'XX单位';
}
const stripped = raw.replace(/^铜陵市公安局/, '').trim();
return stripped || 'XX单位';
}
function escapeHtml(value) {
return String(value ?? '')
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
}
export function formatMinutesTime(value) {
if (!value) {
return '';
}
return dayjs(value).isValid() ? dayjs(value).format('YYYY-MM-DD HH:mm') : String(value);
}
function memberNames(record = {}) {
const members = Array.isArray(record.memberList) ? record.memberList : [];
return members.map((item) => item.employeeName || item.actualName || '-').filter(Boolean).join('、');
}
function hasAnyItemContent(cases) {
return cases.some((item) => String(item.itemContent || '').trim());
}
function buildCaseBlocks(record = {}) {
const cases = Array.isArray(record.caseList) ? record.caseList : [];
if (!cases.length) {
return `<div class="red case-item">
<div>一、XX案</div>
<div>案件编号:XX</div>
<div>主办民警:XX</div>
<div>调度内容:</div>
</div>`;
}
const showLegacy = !hasAnyItemContent(cases) && String(record.scheduleContent || '').trim();
const blocks = cases.map((item, index) => {
const content = String(item.itemContent || '').trim();
return `<div class="red case-item">
<div>${chineseOrdinal(index)}、${escapeHtml(item.caseName || 'XX案')}</div>
<div>案件编号:${escapeHtml(item.caseNo || 'XX')}</div>
<div>主办民警:${escapeHtml(item.handlerName || 'XX')}</div>
<div>调度内容:${content ? `<pre>${escapeHtml(content)}</pre>` : ''}</div>
</div>`;
});
if (showLegacy) {
blocks.push(`<div class="red case-item"><pre>${escapeHtml(record.scheduleContent)}</pre></div>`);
}
return blocks.join('');
}
function buildPrintHtml(record = {}) {
const unit = minutesTitleUnit(record.scheduleUnit);
return `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>铜陵市公安局 ${escapeHtml(unit)}案件调度会议纪要</title>
<style>
@page { size: A4; margin: 16mm 14mm; }
body { font-family: SimSun, 'Songti SC', serif; color: #111; margin: 0; }
h1 { text-align: center; font-size: 22px; font-weight: 700; margin: 0 0 18px; letter-spacing: 1px; }
table { width: 100%; border-collapse: collapse; table-layout: fixed; }
th, td { border: 1px solid #111; padding: 8px 10px; font-size: 14px; vertical-align: middle; }
th { width: 18%; font-weight: 700; text-align: center; white-space: nowrap; }
td { width: 32%; min-height: 36px; }
.red { color: #c41d1d; }
.content-cell { vertical-align: top; min-height: 280px; padding: 12px 14px; line-height: 1.8; }
.case-item { margin-bottom: 16px; }
.case-item pre { margin: 4px 0 0; font-family: SimSun, serif; white-space: pre-wrap; word-break: break-word; }
.sign-cell { height: 72px; }
.note { margin-top: 14px; font-size: 13px; }
</style>
</head>
<body>
<h1>铜陵市公安局 <span class="red">${escapeHtml(unit)}</span>案件调度会议纪要</h1>
<table>
<colgroup>
<col style="width:18%" />
<col style="width:32%" />
<col style="width:18%" />
<col style="width:32%" />
</colgroup>
<tr>
<th class="red">会议时间</th>
<td>${escapeHtml(formatMinutesTime(record.meetingTime))}</td>
<th class="red">会议地点</th>
<td>${escapeHtml(record.meetingPlace || '')}</td>
</tr>
<tr>
<th class="red">调度单位</th>
<td colspan="3">${escapeHtml(record.scheduleUnit || '')}</td>
</tr>
<tr>
<th class="red">会议主持人</th>
<td>${escapeHtml(record.hostName || '')}</td>
<th class="red">会议记录人</th>
<td>${escapeHtml(record.recorderName || '')}</td>
</tr>
<tr>
<th class="red">会议参与人员</th>
<td colspan="3">${escapeHtml(memberNames(record))}</td>
</tr>
<tr>
<th>调度内容</th>
<td colspan="3" class="content-cell">${buildCaseBlocks(record)}</td>
</tr>
<tr>
<th class="red">参会人员签名</th>
<td colspan="3" class="sign-cell"></td>
</tr>
</table>
<div class="note">注:此表交案管室存档,参会人员可自行复印留存。</div>
</body>
</html>`;
}
export function printWeeklySchedule(record) {
const html = buildPrintHtml(record);
let frame = document.getElementById(PRINT_FRAME_ID);
if (!frame) {
frame = document.createElement('iframe');
frame.id = PRINT_FRAME_ID;
frame.style.position = 'fixed';
frame.style.right = '0';
frame.style.bottom = '0';
frame.style.width = '0';
frame.style.height = '0';
frame.style.border = '0';
document.body.appendChild(frame);
}
const doc = frame.contentWindow.document;
doc.open();
doc.write(html);
doc.close();
frame.contentWindow.focus();
frame.contentWindow.print();
}

224
economic-crime-web/src/views/business/case-management/negative-list.vue

@ -0,0 +1,224 @@
<!--
* 负面清单巡查:自动抓取业务系统分类为经侦的案件;办案单位含「派出所」标红
-->
<template>
<div class="negative-list-container">
<a-form class="smart-query-form">
<a-row class="smart-query-form-row" v-privilege="'negative-list:query'">
<a-form-item label="案件编号" class="smart-query-form-item">
<a-input style="width: 180px" v-model:value="queryForm.caseNo" placeholder="请输入案件编号" allowClear />
</a-form-item>
<a-form-item label="案件名称" class="smart-query-form-item">
<a-input style="width: 180px" v-model:value="queryForm.caseName" placeholder="请输入案件名称" allowClear />
</a-form-item>
<a-form-item label="办案单位" class="smart-query-form-item">
<a-input style="width: 160px" v-model:value="queryForm.handleDept" placeholder="请输入办案单位" allowClear />
</a-form-item>
<a-form-item label="案件状态" class="smart-query-form-item">
<a-select style="width: 120px" v-model:value="queryForm.caseStatus" placeholder="请选择" allowClear>
<a-select-option v-for="item in statusOptions" :key="item.value" :value="item.value">{{ item.desc }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="受案时间" class="smart-query-form-item">
<a-range-picker
style="width: 240px"
v-model:value="queryForm.timeRange"
:placeholder="['开始日期', '结束日期']"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
/>
</a-form-item>
<a-form-item class="smart-query-form-item">
<a-button-group>
<a-button type="primary" @click="onSearch" v-privilege="'negative-list:query'">
<template #icon><SearchOutlined /></template>
查询
</a-button>
<a-button @click="resetQuery" v-privilege="'negative-list:query'">
<template #icon><ReloadOutlined /></template>
重置
</a-button>
</a-button-group>
</a-form-item>
</a-row>
</a-form>
<div class="section-card">
<a-row class="smart-table-btn-block">
<div class="smart-table-operate-block">
<span class="hint-text">业务系统分类为「经侦」的案件;办案单位含「派出所」的记录标红</span>
</div>
<div class="smart-table-setting-block">
<TableOperator v-model="columns" :tableId="TABLE_ID_CONST.BUSINESS.CASE.NEGATIVE_LIST" :refresh="queryData" />
</div>
</a-row>
<a-table
size="small"
:dataSource="tableData"
:columns="columns"
rowKey="caseId"
:scroll="{ x: 1200 }"
bordered
:pagination="false"
:loading="tableLoading"
:customRow="customRow"
>
<template #bodyCell="{ record, column }">
<template v-if="column.dataIndex === 'handleDept'">
<span :class="{ 'handle-dept-alert': record.policeStationFlag }">{{ record.handleDept || '-' }}</span>
</template>
<template v-else-if="column.dataIndex === 'caseStatus'">
<a-tag>{{ record.caseStatusName || getCaseStatusName(record.caseStatus) }}</a-tag>
</template>
<template v-else-if="column.dataIndex === 'acceptTime'">
{{ formatTime(record.acceptTime) }}
</template>
</template>
</a-table>
<div class="smart-query-table-page">
<a-pagination
showSizeChanger
showQuickJumper
show-less-items
:pageSizeOptions="PAGE_SIZE_OPTIONS"
v-model:current="queryForm.pageNum"
v-model:pageSize="queryForm.pageSize"
:total="pagination.total"
@change="onPageChange"
@showSizeChange="onPageChange"
:show-total="(total) => `共${total}条`"
/>
</div>
</div>
</div>
</template>
<script setup>
import { reactive, ref, onMounted } from 'vue';
import { SearchOutlined, ReloadOutlined } from '@ant-design/icons-vue';
import _ from 'lodash';
import dayjs from 'dayjs';
import TableOperator from '/@/components/support/table-operator/index.vue';
import { PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
import { TABLE_ID_CONST } from '/@/constants/support/table-id-const';
import { smartSentry } from '/@/lib/smart-sentry';
import { negativeListApi } from '/@/api/business/case-management/negative-list-api.js';
import { CASE_STATUS_ENUM, getCaseStatusName } from '/@/constants/business/case-management/case-supervision-const.js';
const statusOptions = Object.values(CASE_STATUS_ENUM);
const columns = ref([
{ title: '案件名称', dataIndex: 'caseName', width: 220, ellipsis: true },
{ title: '案件编号', dataIndex: 'caseNo', width: 180 },
{ title: '创建单位', dataIndex: 'createDept', width: 180, ellipsis: true },
{ title: '办案单位', dataIndex: 'handleDept', width: 200, ellipsis: true },
{ title: '案件状态', dataIndex: 'caseStatus', width: 100, align: 'center' },
{ title: '受案时间', dataIndex: 'acceptTime', width: 160 },
]);
const queryFormState = {
caseNo: '',
caseName: '',
handleDept: '',
caseStatus: undefined,
timeRange: null,
acceptTimeBegin: undefined,
acceptTimeEnd: undefined,
pageNum: 1,
pageSize: 10,
};
const queryForm = reactive(_.cloneDeep(queryFormState));
const tableLoading = ref(false);
const tableData = ref([]);
const pagination = reactive({ total: 0 });
function applyTimeRange() {
if (queryForm.timeRange && queryForm.timeRange.length === 2) {
queryForm.acceptTimeBegin = queryForm.timeRange[0];
queryForm.acceptTimeEnd = queryForm.timeRange[1];
} else {
queryForm.acceptTimeBegin = undefined;
queryForm.acceptTimeEnd = undefined;
}
}
function resetQuery() {
const pageSize = queryForm.pageSize;
Object.assign(queryForm, _.cloneDeep(queryFormState));
queryForm.pageSize = pageSize;
queryData();
}
function onSearch() {
queryForm.pageNum = 1;
queryData();
}
async function queryData() {
applyTimeRange();
tableLoading.value = true;
try {
const res = await negativeListApi.query(queryForm);
tableData.value = res.data?.list || [];
pagination.total = res.data?.total || 0;
} catch (e) {
smartSentry.captureError(e);
} finally {
tableLoading.value = false;
}
}
function onPageChange(page, pageSize) {
queryForm.pageNum = page;
queryForm.pageSize = pageSize;
queryData();
}
function customRow(record) {
return {
class: record.policeStationFlag ? 'police-station-row' : '',
};
}
function formatTime(value) {
if (!value) {
return '-';
}
return dayjs(value).isValid() ? dayjs(value).format('YYYY-MM-DD HH:mm') : value;
}
onMounted(() => {
queryData();
});
</script>
<style lang="less" scoped>
.negative-list-container {
padding: 16px;
.section-card {
background: white;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
padding: 16px;
margin-bottom: 16px;
}
.hint-text {
color: #8c8c8c;
font-size: 13px;
}
:deep(.police-station-row) {
color: #cf1322;
td {
color: #cf1322 !important;
}
}
.handle-dept-alert {
font-weight: 600;
}
}
</style>

210
economic-crime-web/src/views/business/case-management/weekly-schedule-minutes.vue

@ -0,0 +1,210 @@
<!-- 案件调度会议纪要纸面模板 -->
<template>
<div class="minutes-paper">
<h3 class="minutes-title">
铜陵市公安局
<span class="red-field">{{ minutesTitleUnit(form.scheduleUnit) }}</span>
案件调度会议纪要
</h3>
<table class="minutes-table">
<colgroup>
<col class="col-label" />
<col class="col-value" />
<col class="col-label" />
<col class="col-value" />
</colgroup>
<tbody>
<tr>
<th class="red-field">会议时间</th>
<td>
<a-date-picker
v-if="editable"
v-model:value="form.meetingTime"
show-time
value-format="YYYY-MM-DD HH:mm:ss"
format="YYYY-MM-DD HH:mm"
placeholder="请选择"
style="width: 100%"
/>
<span v-else>{{ formatMinutesTime(form.meetingTime) || ' ' }}</span>
</td>
<th class="red-field">会议地点</th>
<td>
<a-input v-if="editable" v-model:value="form.meetingPlace" placeholder="请输入会议地点" allowClear />
<span v-else>{{ form.meetingPlace || ' ' }}</span>
</td>
</tr>
<tr>
<th class="red-field">调度单位</th>
<td colspan="3">
<a-input v-if="editable" v-model:value="form.scheduleUnit" placeholder="请输入调度单位" allowClear />
<span v-else>{{ form.scheduleUnit || ' ' }}</span>
</td>
</tr>
<tr>
<th class="red-field">会议主持人</th>
<td>
<a-input v-if="editable" v-model:value="form.hostName" placeholder="请输入主持人" allowClear />
<span v-else>{{ form.hostName || ' ' }}</span>
</td>
<th class="red-field">会议记录人</th>
<td>
<a-input v-if="editable" v-model:value="form.recorderName" placeholder="请输入记录人" allowClear />
<span v-else>{{ form.recorderName || ' ' }}</span>
</td>
</tr>
<tr>
<th class="red-field">会议参与人员</th>
<td colspan="3">{{ memberText || (editable ? '请在下方勾选参加调度人员' : ' ') }}</td>
</tr>
<tr>
<th>调度内容</th>
<td colspan="3" class="content-cell">
<div v-if="!cases.length" class="red-field sample-block">
<div>一、XX案</div>
<div>案件编号:XX</div>
<div>主办民警:XX</div>
<div>调度内容:</div>
<div class="empty-hint">勾选左侧案件后自动填入并标红</div>
</div>
<div v-for="(item, index) in cases" :key="item.caseId || item.itemId || index" class="case-item">
<div class="red-field">{{ chineseOrdinal(index) }}、{{ item.caseName || 'XX案' }}</div>
<div class="red-field">案件编号:{{ item.caseNo || 'XX' }}</div>
<div class="red-field">主办民警:{{ item.handlerName || 'XX' }}</div>
<div class="red-field">调度内容:</div>
<a-textarea
v-if="editable"
v-model:value="item.itemContent"
:rows="3"
placeholder="请手动输入该案调度内容"
/>
<pre v-else class="red-field item-content">{{ item.itemContent || fallbackContent(index) }}</pre>
</div>
</td>
</tr>
<tr>
<th class="red-field">参会人员签名</th>
<td colspan="3" class="sign-cell"></td>
</tr>
</tbody>
</table>
<p class="minutes-note">注:此表交案管室存档,参会人员可自行复印留存。</p>
</div>
</template>
<script setup>
import { computed } from 'vue';
import { chineseOrdinal, minutesTitleUnit, formatMinutesTime } from '/@/utils/print-weekly-schedule.js';
const props = defineProps({
editable: { type: Boolean, default: false },
form: { type: Object, required: true },
cases: { type: Array, default: () => [] },
members: { type: Array, default: () => [] },
});
const memberText = computed(() => (props.members || [])
.map((item) => item.employeeName || item.actualName)
.filter(Boolean)
.join('、'));
function fallbackContent(index) {
if (index !== 0) {
return '';
}
const cases = props.cases || [];
const hasItem = cases.some((item) => String(item.itemContent || '').trim());
if (hasItem) {
return '';
}
return props.form?.scheduleContent || '';
}
</script>
<style lang="less" scoped>
.minutes-paper {
background: #fff;
padding: 8px 4px 0;
}
.minutes-title {
text-align: center;
font-size: 18px;
font-weight: 700;
letter-spacing: 1px;
margin: 0 0 12px;
}
.minutes-table {
width: 100%;
border-collapse: collapse;
table-layout: fixed;
th,
td {
border: 1px solid #111;
padding: 8px 10px;
font-size: 13px;
vertical-align: middle;
}
th {
width: 18%;
text-align: center;
font-weight: 700;
white-space: nowrap;
background: #fff;
}
td {
width: 32%;
}
.col-label {
width: 18%;
}
.col-value {
width: 32%;
}
}
.red-field {
color: #c41d1d;
font-weight: 600;
}
.content-cell {
vertical-align: top;
min-height: 180px;
}
.sample-block,
.case-item {
line-height: 1.8;
margin-bottom: 12px;
}
.item-content {
margin: 4px 0 0;
white-space: pre-wrap;
font-family: inherit;
}
.sign-cell {
height: 56px;
}
.empty-hint {
color: #8c8c8c;
font-weight: 400;
font-size: 12px;
margin-top: 4px;
}
.minutes-note {
margin: 10px 0 0;
font-size: 12px;
color: #434343;
}
</style>

598
economic-crime-web/src/views/business/case-management/weekly-schedule.vue

@ -0,0 +1,598 @@
<!--
* 周调度:勾选案件生成标红模板,手填调度内容,推送人员全员确认后锁定可打印
-->
<template>
<div class="weekly-schedule-container">
<a-form class="smart-query-form">
<a-row class="smart-query-form-row" v-privilege="'weekly-schedule:query'">
<a-form-item label="调度编号" class="smart-query-form-item">
<a-input style="width: 180px" v-model:value="queryForm.scheduleNo" placeholder="请输入调度编号" allowClear />
</a-form-item>
<a-form-item label="状态" class="smart-query-form-item">
<a-select style="width: 140px" v-model:value="queryForm.status" placeholder="请选择" allowClear>
<a-select-option v-for="item in statusOptions" :key="item.value" :value="item.value">{{ item.desc }}</a-select-option>
</a-select>
</a-form-item>
<a-form-item class="smart-query-form-item">
<a-button-group>
<a-button type="primary" @click="onSearch" v-privilege="'weekly-schedule:query'">
<template #icon><SearchOutlined /></template>
查询
</a-button>
<a-button @click="resetQuery" v-privilege="'weekly-schedule:query'">
<template #icon><ReloadOutlined /></template>
重置
</a-button>
</a-button-group>
</a-form-item>
</a-row>
</a-form>
<div class="section-card">
<a-row class="smart-table-btn-block">
<div class="smart-table-operate-block">
<a-button type="primary" v-privilege="'weekly-schedule:add'" @click="openCreate">
<template #icon><PlusOutlined /></template>
新增
</a-button>
<a-radio-group v-model:value="listTab" button-style="solid" class="list-tab" @change="onTabChange">
<a-radio-button :value="false">全部</a-radio-button>
<a-radio-button :value="true">待我确认</a-radio-button>
</a-radio-group>
</div>
<div class="smart-table-setting-block">
<TableOperator v-model="columns" :tableId="TABLE_ID_CONST.BUSINESS.CASE.WEEKLY_SCHEDULE" :refresh="queryData" />
</div>
</a-row>
<a-table
size="small"
:dataSource="tableData"
:columns="columns"
rowKey="scheduleId"
:scroll="{ x: 1200 }"
bordered
:pagination="false"
:loading="tableLoading"
>
<template #bodyCell="{ record, column }">
<template v-if="column.dataIndex === 'status'">
<a-tag :color="getWeeklyScheduleStatusColor(record.status)">{{ record.statusName || getWeeklyScheduleStatusName(record.status) }}</a-tag>
</template>
<template v-else-if="column.dataIndex === 'progress'">
{{ record.confirmedCount || 0 }}/{{ record.memberCount || 0 }}
</template>
<template v-else-if="column.dataIndex === 'createTime'">
{{ formatTime(record.createTime) }}
</template>
<template v-else-if="column.dataIndex === 'action'">
<div class="smart-table-operate">
<a-button type="link" size="small" v-privilege="'weekly-schedule:view'" @click="openDetail(record)">查看</a-button>
<a-button type="link" size="small" v-if="record.canPush" v-privilege="'weekly-schedule:push'" @click="handlePush(record)">推送</a-button>
<a-popconfirm title="确认调度内容后不可更改,确定确认?" ok-text="确定" cancel-text="取消" @confirm="handleConfirm(record)">
<a-button type="link" size="small" v-if="record.canConfirm" v-privilege="'weekly-schedule:confirm'">确认</a-button>
</a-popconfirm>
<a-button type="link" size="small" v-if="record.canPrint" v-privilege="'weekly-schedule:print'" @click="handlePrint(record)">打印</a-button>
</div>
</template>
</template>
</a-table>
<div class="smart-query-table-page">
<a-pagination
showSizeChanger
showQuickJumper
show-less-items
:pageSizeOptions="PAGE_SIZE_OPTIONS"
v-model:current="queryForm.pageNum"
v-model:pageSize="queryForm.pageSize"
:total="pagination.total"
@change="onPageChange"
@showSizeChange="onPageChange"
:show-total="(total) => `共${total}条`"
/>
</div>
</div>
<a-modal
v-model:open="createVisible"
title="新增周调度"
:width="1180"
:maskClosable="false"
:confirm-loading="createLoading"
@cancel="closeCreate"
>
<div class="create-layout">
<div class="create-left">
<a-form layout="inline" class="case-search-form">
<a-form-item label="案件名称">
<a-input v-model:value="caseQuery.caseName" placeholder="关键字模糊搜索" allowClear style="width: 160px" />
</a-form-item>
<a-form-item label="案件编号">
<a-input v-model:value="caseQuery.caseNo" placeholder="案件编号" allowClear style="width: 140px" />
</a-form-item>
<a-form-item>
<a-button type="primary" @click="searchCases">搜索</a-button>
</a-form-item>
</a-form>
<a-table
size="small"
:dataSource="caseTableData"
:columns="caseColumns"
rowKey="caseId"
:pagination="false"
:loading="caseLoading"
:row-selection="{ selectedRowKeys: selectedCaseIds, onChange: onSelectCases }"
:scroll="{ y: 280 }"
bordered
/>
<div class="smart-query-table-page">
<a-pagination
size="small"
:pageSize="caseQuery.pageSize"
v-model:current="caseQuery.pageNum"
:total="casePagination.total"
@change="onCasePageChange"
:show-total="(total) => `共${total}条`"
/>
</div>
</div>
<div class="create-right">
<div class="paper-preview">
<WeeklyScheduleMinutes
:form="createForm"
:cases="selectedCases"
:members="selectedMembers"
editable
/>
</div>
<div class="member-block">
<div class="member-header">
<span>参加调度人员</span>
<a-button size="small" @click="openEmployeeSelect">选择人员</a-button>
</div>
<div class="member-tags">
<a-tag v-for="item in selectedMembers" :key="item.employeeId" closable @close="removeMember(item.employeeId)">
{{ item.actualName }}
</a-tag>
<span v-if="!selectedMembers.length" class="empty-hint">请勾选参加调度人员进行推送</span>
</div>
</div>
</div>
</div>
<template #footer>
<a-button @click="closeCreate">取消</a-button>
<a-button @click="submitCreate(false)" :loading="createLoading" v-privilege="'weekly-schedule:add'">保存草稿</a-button>
<a-button type="primary" @click="submitCreate(true)" :loading="createLoading" v-privilege="'weekly-schedule:push'">推送</a-button>
</template>
</a-modal>
<EmployeeTableSelectModal ref="selectEmployeeModal" @selectData="onSelectEmployees" />
<a-drawer v-model:open="detailVisible" title="周调度详情" placement="right" :width="780">
<div class="paper-preview" v-if="currentRecord">
<div class="meta-line">调度编号:{{ currentRecord.scheduleNo }} 状态:{{ currentRecord.statusName }} 创建人:{{ currentRecord.createUserName || '-' }}</div>
<WeeklyScheduleMinutes
:form="currentRecord"
:cases="currentRecord.caseList || []"
:members="currentRecord.memberList || []"
/>
<div class="content-label">确认进度</div>
<a-tag v-for="item in currentRecord.memberList || []" :key="item.employeeId" :color="item.confirmedFlag ? 'success' : 'warning'">
{{ item.employeeName }}{{ item.confirmedFlag ? '(已确认)' : '(待确认)' }}
</a-tag>
<div class="detail-actions">
<a-popconfirm v-if="currentRecord.canConfirm" title="确认调度内容后不可更改,确定确认?" @confirm="handleConfirm(currentRecord)">
<a-button type="primary" v-privilege="'weekly-schedule:confirm'">确认</a-button>
</a-popconfirm>
<a-button v-if="currentRecord.canPush" v-privilege="'weekly-schedule:push'" @click="handlePush(currentRecord)">推送</a-button>
<a-button v-if="currentRecord.canPrint" v-privilege="'weekly-schedule:print'" @click="printWeeklySchedule(currentRecord)">打印</a-button>
</div>
</div>
</a-drawer>
</div>
</template>
<script setup>
import { reactive, ref, onMounted } from 'vue';
import { message } from 'ant-design-vue';
import { SearchOutlined, ReloadOutlined, PlusOutlined } from '@ant-design/icons-vue';
import _ from 'lodash';
import dayjs from 'dayjs';
import TableOperator from '/@/components/support/table-operator/index.vue';
import EmployeeTableSelectModal from '/@/components/system/employee-table-select-modal/index.vue';
import { PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
import { TABLE_ID_CONST } from '/@/constants/support/table-id-const';
import { smartSentry } from '/@/lib/smart-sentry';
import { weeklyScheduleApi } from '/@/api/business/case-management/weekly-schedule-api.js';
import { employeeApi } from '/@/api/system/employee-api';
import {
WEEKLY_SCHEDULE_STATUS_ENUM,
getWeeklyScheduleStatusName,
getWeeklyScheduleStatusColor,
} from '/@/constants/business/case-management/case-supervision-const.js';
import { printWeeklySchedule } from '/@/utils/print-weekly-schedule.js';
import WeeklyScheduleMinutes from './weekly-schedule-minutes.vue';
import { useUserStore } from '/@/store/modules/system/user';
const statusOptions = Object.values(WEEKLY_SCHEDULE_STATUS_ENUM);
const listTab = ref(false);
const columns = ref([
{ title: '调度编号', dataIndex: 'scheduleNo', width: 160 },
{ title: '调度内容', dataIndex: 'scheduleContent', width: 260, ellipsis: true },
{ title: '案件数', dataIndex: 'caseCount', width: 80, align: 'center' },
{ title: '确认进度', dataIndex: 'progress', width: 100, align: 'center' },
{ title: '状态', dataIndex: 'status', width: 100, align: 'center' },
{ title: '创建人', dataIndex: 'createUserName', width: 100 },
{ title: '创建时间', dataIndex: 'createTime', width: 160 },
{ title: '操作', dataIndex: 'action', fixed: 'right', width: 200 },
]);
const queryFormState = {
scheduleNo: '',
status: undefined,
pendingMine: false,
pageNum: 1,
pageSize: 10,
};
const queryForm = reactive(_.cloneDeep(queryFormState));
const tableLoading = ref(false);
const tableData = ref([]);
const pagination = reactive({ total: 0 });
const createVisible = ref(false);
const createLoading = ref(false);
const userStore = useUserStore();
const createForm = reactive({
meetingTime: undefined,
meetingPlace: '',
scheduleUnit: '',
hostName: '',
recorderName: '',
});
const selectedCases = ref([]);
const selectedMembers = ref([]);
const employeeMap = ref([]);
const selectEmployeeModal = ref();
const caseQuery = reactive({ caseNo: '', caseName: '', pageNum: 1, pageSize: 8 });
const caseTableData = ref([]);
const casePagination = reactive({ total: 0 });
const caseLoading = ref(false);
const caseColumns = [
{ title: '案件名称', dataIndex: 'caseName', ellipsis: true },
{ title: '案件编号', dataIndex: 'caseNo', width: 140 },
{ title: '主办民警', dataIndex: 'handlerName', width: 90 },
{ title: '办案单位', dataIndex: 'handleDept', width: 130, ellipsis: true },
];
const selectedCaseIds = ref([]);
const detailVisible = ref(false);
const currentRecord = ref(null);
function resetQuery() {
const pageSize = queryForm.pageSize;
Object.assign(queryForm, _.cloneDeep(queryFormState));
queryForm.pageSize = pageSize;
listTab.value = false;
queryData();
}
function onSearch() {
queryForm.pageNum = 1;
queryData();
}
function onTabChange() {
queryForm.pendingMine = listTab.value;
queryForm.pageNum = 1;
queryData();
}
async function queryData() {
queryForm.pendingMine = listTab.value;
tableLoading.value = true;
try {
const res = await weeklyScheduleApi.query(queryForm);
tableData.value = res.data?.list || [];
pagination.total = res.data?.total || 0;
} catch (e) {
smartSentry.captureError(e);
} finally {
tableLoading.value = false;
}
}
function onPageChange(page, pageSize) {
queryForm.pageNum = page;
queryForm.pageSize = pageSize;
queryData();
}
function emptyCreateForm() {
createForm.meetingTime = undefined;
createForm.meetingPlace = '';
createForm.scheduleUnit = userStore.departmentName || '';
createForm.hostName = '';
createForm.recorderName = '';
}
async function openCreate() {
emptyCreateForm();
selectedCases.value = [];
selectedCaseIds.value = [];
selectedMembers.value = [];
createVisible.value = true;
await loadEmployees();
await searchCases();
}
function closeCreate() {
createVisible.value = false;
}
async function searchCases() {
caseQuery.pageNum = 1;
await loadCasePage();
}
async function loadCasePage() {
caseLoading.value = true;
try {
const res = await weeklyScheduleApi.searchCase(caseQuery);
caseTableData.value = res.data?.list || [];
casePagination.total = res.data?.total || 0;
} catch (e) {
smartSentry.captureError(e);
} finally {
caseLoading.value = false;
}
}
function onCasePageChange(page) {
caseQuery.pageNum = page;
loadCasePage();
}
function onSelectCases(keys) {
const map = new Map(selectedCases.value.map((item) => [item.caseId, item]));
caseTableData.value.forEach((row) => {
const existing = map.get(row.caseId);
map.set(row.caseId, {
...row,
itemContent: existing?.itemContent || '',
});
});
selectedCases.value = keys.map((id) => map.get(id)).filter(Boolean);
selectedCaseIds.value = keys;
}
async function loadEmployees() {
try {
const res = await employeeApi.queryAll();
employeeMap.value = res.data || [];
} catch (e) {
smartSentry.captureError(e);
}
}
function openEmployeeSelect() {
selectEmployeeModal.value?.showModal(selectedMembers.value.map((item) => item.employeeId));
}
function onSelectEmployees(ids) {
const list = selectedMembers.value.slice();
(ids || []).forEach((id) => {
if (list.some((item) => item.employeeId === id)) {
return;
}
const emp = employeeMap.value.find((item) => item.employeeId === id);
list.push({ employeeId: id, actualName: emp?.actualName || String(id) });
});
selectedMembers.value = list;
}
function removeMember(employeeId) {
selectedMembers.value = selectedMembers.value.filter((item) => item.employeeId !== employeeId);
}
async function submitCreate(pushFlag) {
if (!selectedCases.value.length) {
message.warning('请勾选调度案件');
return;
}
const itemContentList = selectedCases.value.map((item) => item.itemContent || '');
if (pushFlag && !itemContentList.some((text) => String(text).trim())) {
message.warning('请输入调度内容');
return;
}
if (pushFlag && !selectedMembers.value.length) {
message.warning('请勾选参加调度人员');
return;
}
createLoading.value = true;
try {
await weeklyScheduleApi.create({
caseIdList: selectedCases.value.map((item) => item.caseId),
itemContentList,
meetingTime: createForm.meetingTime,
meetingPlace: createForm.meetingPlace,
scheduleUnit: createForm.scheduleUnit,
hostName: createForm.hostName,
recorderName: createForm.recorderName,
memberIdList: selectedMembers.value.map((item) => item.employeeId),
pushFlag,
});
message.success(pushFlag ? '已推送,等待参加人员确认' : '草稿已保存');
closeCreate();
queryData();
} catch (e) {
smartSentry.captureError(e);
} finally {
createLoading.value = false;
}
}
async function openDetail(record) {
try {
const res = await weeklyScheduleApi.detail(record.scheduleId);
currentRecord.value = res.data;
detailVisible.value = true;
} catch (e) {
smartSentry.captureError(e);
}
}
async function handlePush(record) {
try {
const res = await weeklyScheduleApi.push(record.scheduleId);
message.success(res.msg || res.data || '已推送');
queryData();
if (detailVisible.value) {
openDetail(record);
}
} catch (e) {
smartSentry.captureError(e);
}
}
async function handleConfirm(record) {
try {
const res = await weeklyScheduleApi.confirm(record.scheduleId);
message.success(res.msg || res.data || '确认成功');
queryData();
if (detailVisible.value) {
openDetail(record);
}
} catch (e) {
smartSentry.captureError(e);
}
}
async function handlePrint(record) {
try {
const res = await weeklyScheduleApi.detail(record.scheduleId);
printWeeklySchedule(res.data);
} catch (e) {
smartSentry.captureError(e);
}
}
function formatTime(value) {
if (!value) {
return '-';
}
return dayjs(value).isValid() ? dayjs(value).format('YYYY-MM-DD HH:mm') : value;
}
onMounted(() => {
queryData();
});
</script>
<style lang="less" scoped>
.weekly-schedule-container {
padding: 16px;
.section-card {
background: white;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
padding: 16px;
margin-bottom: 16px;
}
.list-tab {
margin-left: 12px;
}
:deep(.smart-table-operate) {
display: flex;
gap: 4px;
flex-wrap: wrap;
}
}
.create-layout {
display: flex;
gap: 16px;
min-height: 460px;
}
.create-left,
.create-right {
flex: 1;
min-width: 0;
}
.case-search-form {
margin-bottom: 8px;
}
.paper-preview {
border: 1px solid #e8e8e8;
border-radius: 6px;
padding: 12px;
background: #fafafa;
max-height: 560px;
overflow: auto;
}
.case-block {
border: 1px solid #f0f0f0;
background: #fff;
padding: 8px 12px;
margin-bottom: 8px;
line-height: 1.9;
}
.label {
display: inline-block;
width: 80px;
color: #595959;
}
.red-field {
color: #cf1322;
font-weight: 600;
}
.content-label {
margin: 8px 0 6px;
font-weight: 600;
}
.content-text {
white-space: pre-wrap;
min-height: 48px;
}
.empty-hint {
color: #8c8c8c;
font-size: 13px;
}
.member-block {
margin-top: 12px;
}
.member-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
.member-tags {
min-height: 32px;
}
.meta-line {
line-height: 2;
}
.detail-actions {
margin-top: 16px;
display: flex;
gap: 8px;
}
</style>

34597
logs/economic-crime/dev/debug/debug.log

File diff suppressed because it is too large

390
logs/economic-crime/dev/error/error.log

@ -1,390 +0,0 @@
[2026-10-15 09:02:01,784][ERROR][redisson-timer-4-1] Unable to send PING command over channel: [id: 0x923387bc, L:/198.18.0.1:56382 - R:8.162.3.203/8.162.3.203:6379] (PingConnectionHandler.java:92)
org.redisson.client.RedisTimeoutException: Command execution timeout for command: (PING), params: [], Redis client: [addr=redis://8.162.3.203:6379]
at org.redisson.client.RedisConnection.lambda$async$0(RedisConnection.java:244) ~[redisson-3.17.7.jar:3.17.7]
at io.netty.util.HashedWheelTimer$HashedWheelTimeout.run(HashedWheelTimer.java:715) ~[netty-common-4.1.101.Final.jar:4.1.101.Final]
at io.netty.util.concurrent.ImmediateExecutor.execute(ImmediateExecutor.java:34) ~[netty-common-4.1.101.Final.jar:4.1.101.Final]
at io.netty.util.HashedWheelTimer$HashedWheelTimeout.expire(HashedWheelTimer.java:703) ~[netty-common-4.1.101.Final.jar:4.1.101.Final]
at io.netty.util.HashedWheelTimer$HashedWheelBucket.expireTimeouts(HashedWheelTimer.java:790) ~[netty-common-4.1.101.Final.jar:4.1.101.Final]
at io.netty.util.HashedWheelTimer$Worker.run(HashedWheelTimer.java:503) ~[netty-common-4.1.101.Final.jar:4.1.101.Final]
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.101.Final.jar:4.1.101.Final]
at java.lang.Thread.run(Thread.java:1583) ~[?:?]
[2026-10-15 09:02:01,788][ERROR][redisson-timer-4-1] Unable to send PING command over channel: [id: 0x1e26a95e, L:/198.18.0.1:56384 - R:8.162.3.203/8.162.3.203:6379] (PingConnectionHandler.java:92)
org.redisson.client.RedisTimeoutException: Command execution timeout for command: (PING), params: [], Redis client: [addr=redis://8.162.3.203:6379]
at org.redisson.client.RedisConnection.lambda$async$0(RedisConnection.java:244) ~[redisson-3.17.7.jar:3.17.7]
at io.netty.util.HashedWheelTimer$HashedWheelTimeout.run(HashedWheelTimer.java:715) ~[netty-common-4.1.101.Final.jar:4.1.101.Final]
at io.netty.util.concurrent.ImmediateExecutor.execute(ImmediateExecutor.java:34) ~[netty-common-4.1.101.Final.jar:4.1.101.Final]
at io.netty.util.HashedWheelTimer$HashedWheelTimeout.expire(HashedWheelTimer.java:703) ~[netty-common-4.1.101.Final.jar:4.1.101.Final]
at io.netty.util.HashedWheelTimer$HashedWheelBucket.expireTimeouts(HashedWheelTimer.java:790) ~[netty-common-4.1.101.Final.jar:4.1.101.Final]
at io.netty.util.HashedWheelTimer$Worker.run(HashedWheelTimer.java:503) ~[netty-common-4.1.101.Final.jar:4.1.101.Final]
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.101.Final.jar:4.1.101.Final]
at java.lang.Thread.run(Thread.java:1583) ~[?:?]
[2026-10-15 09:02:01,885][ERROR][redisson-timer-4-1] Unable to send PING command over channel: [id: 0x07f0b4e0, L:/198.18.0.1:56388 - R:8.162.3.203/8.162.3.203:6379] (PingConnectionHandler.java:92)
org.redisson.client.RedisTimeoutException: Command execution timeout for command: (PING), params: [], Redis client: [addr=redis://8.162.3.203:6379]
at org.redisson.client.RedisConnection.lambda$async$0(RedisConnection.java:244) ~[redisson-3.17.7.jar:3.17.7]
at io.netty.util.HashedWheelTimer$HashedWheelTimeout.run(HashedWheelTimer.java:715) ~[netty-common-4.1.101.Final.jar:4.1.101.Final]
at io.netty.util.concurrent.ImmediateExecutor.execute(ImmediateExecutor.java:34) ~[netty-common-4.1.101.Final.jar:4.1.101.Final]
at io.netty.util.HashedWheelTimer$HashedWheelTimeout.expire(HashedWheelTimer.java:703) ~[netty-common-4.1.101.Final.jar:4.1.101.Final]
at io.netty.util.HashedWheelTimer$HashedWheelBucket.expireTimeouts(HashedWheelTimer.java:790) ~[netty-common-4.1.101.Final.jar:4.1.101.Final]
at io.netty.util.HashedWheelTimer$Worker.run(HashedWheelTimer.java:503) ~[netty-common-4.1.101.Final.jar:4.1.101.Final]
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.101.Final.jar:4.1.101.Final]
at java.lang.Thread.run(Thread.java:1583) ~[?:?]
[2026-10-15 10:59:56,453][ERROR][Druid-ConnectionPool-Create-900327013] create connection SQLException, url: jdbc:kingbase8://8.162.3.203:54321/economic_crime_dev?currentSchema=public&clientEncoding=utf8&socketTimeout=30000&loginTimeout=30, errorCode 0, state 08001 (DruidDataSource.java:2916)
com.kingbase8.util.KSQLException: The _connection attempt failed.Reason:null
at com.kingbase8.Driver$ConnectThread.getResult(Driver.java:491) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.connect(Driver.java:312) ~[kingbase8-8.6.0.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:132) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1687) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1803) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2914) ~[druid-1.2.23.jar:?]
Caused by: java.io.EOFException
at com.kingbase8.core.KBStream.receiveChar(KBStream.java:587) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.enableSSL(ConnectionFactoryImpl.java:568) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:207) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:280) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.ConnectionFactory.openConnection(ConnectionFactory.java:65) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:336) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:548) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.makeConnection(Driver.java:576) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.access$100(Driver.java:52) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver$ConnectThread.run(Driver.java:440) ~[kingbase8-8.6.0.jar:?]
at java.lang.Thread.run(Thread.java:1583) ~[?:?]
[2026-10-15 11:00:00,146][ERROR][Druid-ConnectionPool-Create-900327013] create connection SQLException, url: jdbc:kingbase8://8.162.3.203:54321/economic_crime_dev?currentSchema=public&clientEncoding=utf8&socketTimeout=30000&loginTimeout=30, errorCode 0, state 08001 (DruidDataSource.java:2916)
com.kingbase8.util.KSQLException: The _connection attempt failed.Reason:null
at com.kingbase8.Driver$ConnectThread.getResult(Driver.java:491) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.connect(Driver.java:312) ~[kingbase8-8.6.0.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:132) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1687) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1803) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2914) ~[druid-1.2.23.jar:?]
Caused by: java.io.EOFException
at com.kingbase8.core.KBStream.receiveChar(KBStream.java:587) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.enableSSL(ConnectionFactoryImpl.java:568) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:207) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:280) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.ConnectionFactory.openConnection(ConnectionFactory.java:65) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:336) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:548) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.makeConnection(Driver.java:576) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.access$100(Driver.java:52) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver$ConnectThread.run(Driver.java:440) ~[kingbase8-8.6.0.jar:?]
at java.lang.Thread.run(Thread.java:1583) ~[?:?]
[2026-10-15 11:16:19,344][ERROR][Druid-ConnectionPool-Create-900327013] create connection SQLException, url: jdbc:kingbase8://8.162.3.203:54321/economic_crime_dev?currentSchema=public&clientEncoding=utf8&socketTimeout=30000&loginTimeout=30, errorCode 0, state 08001 (DruidDataSource.java:2916)
com.kingbase8.util.KSQLException: The _connection attempt failed.Reason:null
at com.kingbase8.Driver$ConnectThread.getResult(Driver.java:491) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.connect(Driver.java:312) ~[kingbase8-8.6.0.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:132) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1687) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1803) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2914) ~[druid-1.2.23.jar:?]
Caused by: java.io.EOFException
at com.kingbase8.core.KBStream.receiveChar(KBStream.java:587) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.enableSSL(ConnectionFactoryImpl.java:568) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:207) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:280) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.ConnectionFactory.openConnection(ConnectionFactory.java:65) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:336) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:548) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.makeConnection(Driver.java:576) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.access$100(Driver.java:52) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver$ConnectThread.run(Driver.java:440) ~[kingbase8-8.6.0.jar:?]
at java.lang.Thread.run(Thread.java:1583) ~[?:?]
[2026-10-15 11:16:21,587][ERROR][Druid-ConnectionPool-Create-900327013] create connection SQLException, url: jdbc:kingbase8://8.162.3.203:54321/economic_crime_dev?currentSchema=public&clientEncoding=utf8&socketTimeout=30000&loginTimeout=30, errorCode 0, state 08001 (DruidDataSource.java:2916)
com.kingbase8.util.KSQLException: The _connection attempt failed.Reason:null
at com.kingbase8.Driver$ConnectThread.getResult(Driver.java:491) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.connect(Driver.java:312) ~[kingbase8-8.6.0.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:132) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1687) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1803) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2914) ~[druid-1.2.23.jar:?]
Caused by: java.io.EOFException
at com.kingbase8.core.KBStream.receiveChar(KBStream.java:587) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.enableSSL(ConnectionFactoryImpl.java:568) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:207) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:280) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.ConnectionFactory.openConnection(ConnectionFactory.java:65) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:336) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:548) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.makeConnection(Driver.java:576) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.access$100(Driver.java:52) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver$ConnectThread.run(Driver.java:440) ~[kingbase8-8.6.0.jar:?]
at java.lang.Thread.run(Thread.java:1583) ~[?:?]
[2026-10-15 11:31:22,346][ERROR][Druid-ConnectionPool-Create-900327013] create connection SQLException, url: jdbc:kingbase8://8.162.3.203:54321/economic_crime_dev?currentSchema=public&clientEncoding=utf8&socketTimeout=30000&loginTimeout=30, errorCode 0, state 08001 (DruidDataSource.java:2916)
com.kingbase8.util.KSQLException: The _connection attempt failed.Reason:null
at com.kingbase8.Driver$ConnectThread.getResult(Driver.java:491) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.connect(Driver.java:312) ~[kingbase8-8.6.0.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:132) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1687) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1803) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2914) ~[druid-1.2.23.jar:?]
Caused by: java.io.EOFException
at com.kingbase8.core.KBStream.receiveChar(KBStream.java:587) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.enableSSL(ConnectionFactoryImpl.java:568) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:207) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:280) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.ConnectionFactory.openConnection(ConnectionFactory.java:65) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:336) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:548) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.makeConnection(Driver.java:576) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.access$100(Driver.java:52) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver$ConnectThread.run(Driver.java:440) ~[kingbase8-8.6.0.jar:?]
at java.lang.Thread.run(Thread.java:1583) ~[?:?]
[2026-10-15 11:48:37,816][ERROR][Druid-ConnectionPool-Create-900327013] create connection SQLException, url: jdbc:kingbase8://8.162.3.203:54321/economic_crime_dev?currentSchema=public&clientEncoding=utf8&socketTimeout=30000&loginTimeout=30, errorCode 0, state 08001 (DruidDataSource.java:2916)
com.kingbase8.util.KSQLException: The _connection attempt failed.Reason:null
at com.kingbase8.Driver$ConnectThread.getResult(Driver.java:491) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.connect(Driver.java:312) ~[kingbase8-8.6.0.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:132) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1687) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1803) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2914) ~[druid-1.2.23.jar:?]
Caused by: java.io.EOFException
at com.kingbase8.core.KBStream.receiveChar(KBStream.java:587) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.enableSSL(ConnectionFactoryImpl.java:568) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:207) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:280) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.ConnectionFactory.openConnection(ConnectionFactory.java:65) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:336) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:548) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.makeConnection(Driver.java:576) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.access$100(Driver.java:52) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver$ConnectThread.run(Driver.java:440) ~[kingbase8-8.6.0.jar:?]
at java.lang.Thread.run(Thread.java:1583) ~[?:?]
[2026-10-15 11:48:41,519][ERROR][Druid-ConnectionPool-Create-900327013] create connection SQLException, url: jdbc:kingbase8://8.162.3.203:54321/economic_crime_dev?currentSchema=public&clientEncoding=utf8&socketTimeout=30000&loginTimeout=30, errorCode 0, state 08001 (DruidDataSource.java:2916)
com.kingbase8.util.KSQLException: The _connection attempt failed.Reason:null
at com.kingbase8.Driver$ConnectThread.getResult(Driver.java:491) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.connect(Driver.java:312) ~[kingbase8-8.6.0.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:132) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1687) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1803) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2914) ~[druid-1.2.23.jar:?]
Caused by: java.io.EOFException
at com.kingbase8.core.KBStream.receiveChar(KBStream.java:587) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.enableSSL(ConnectionFactoryImpl.java:568) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:207) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:280) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.ConnectionFactory.openConnection(ConnectionFactory.java:65) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:336) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:548) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.makeConnection(Driver.java:576) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.access$100(Driver.java:52) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver$ConnectThread.run(Driver.java:440) ~[kingbase8-8.6.0.jar:?]
at java.lang.Thread.run(Thread.java:1583) ~[?:?]
[2026-10-15 12:05:35,339][ERROR][Druid-ConnectionPool-Create-900327013] create connection SQLException, url: jdbc:kingbase8://8.162.3.203:54321/economic_crime_dev?currentSchema=public&clientEncoding=utf8&socketTimeout=30000&loginTimeout=30, errorCode 0, state 08001 (DruidDataSource.java:2916)
com.kingbase8.util.KSQLException: The _connection attempt failed.Reason:null
at com.kingbase8.Driver$ConnectThread.getResult(Driver.java:491) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.connect(Driver.java:312) ~[kingbase8-8.6.0.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:132) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1687) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1803) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2914) ~[druid-1.2.23.jar:?]
Caused by: java.io.EOFException
at com.kingbase8.core.KBStream.receiveChar(KBStream.java:587) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.enableSSL(ConnectionFactoryImpl.java:568) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:207) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:280) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.ConnectionFactory.openConnection(ConnectionFactory.java:65) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:336) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:548) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.makeConnection(Driver.java:576) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.access$100(Driver.java:52) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver$ConnectThread.run(Driver.java:440) ~[kingbase8-8.6.0.jar:?]
at java.lang.Thread.run(Thread.java:1583) ~[?:?]
[2026-10-15 12:17:19,118][ERROR][Druid-ConnectionPool-Create-900327013] create connection SQLException, url: jdbc:kingbase8://8.162.3.203:54321/economic_crime_dev?currentSchema=public&clientEncoding=utf8&socketTimeout=30000&loginTimeout=30, errorCode 0, state 08001 (DruidDataSource.java:2916)
com.kingbase8.util.KSQLException: The _connection attempt failed.Reason:null
at com.kingbase8.Driver$ConnectThread.getResult(Driver.java:491) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.connect(Driver.java:312) ~[kingbase8-8.6.0.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:132) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1687) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1803) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2914) ~[druid-1.2.23.jar:?]
Caused by: java.io.EOFException
at com.kingbase8.core.KBStream.receiveChar(KBStream.java:587) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.enableSSL(ConnectionFactoryImpl.java:568) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:207) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:280) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.ConnectionFactory.openConnection(ConnectionFactory.java:65) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:336) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:548) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.makeConnection(Driver.java:576) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.access$100(Driver.java:52) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver$ConnectThread.run(Driver.java:440) ~[kingbase8-8.6.0.jar:?]
at java.lang.Thread.run(Thread.java:1583) ~[?:?]
[2026-10-15 12:17:23,476][ERROR][Druid-ConnectionPool-Create-900327013] create connection SQLException, url: jdbc:kingbase8://8.162.3.203:54321/economic_crime_dev?currentSchema=public&clientEncoding=utf8&socketTimeout=30000&loginTimeout=30, errorCode 0, state 08001 (DruidDataSource.java:2916)
com.kingbase8.util.KSQLException: The _connection attempt failed.Reason:null
at com.kingbase8.Driver$ConnectThread.getResult(Driver.java:491) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.connect(Driver.java:312) ~[kingbase8-8.6.0.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:132) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1687) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1803) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2914) ~[druid-1.2.23.jar:?]
Caused by: java.io.EOFException
at com.kingbase8.core.KBStream.receiveChar(KBStream.java:587) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.enableSSL(ConnectionFactoryImpl.java:568) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:207) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:280) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.ConnectionFactory.openConnection(ConnectionFactory.java:65) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:336) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:548) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.makeConnection(Driver.java:576) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.access$100(Driver.java:52) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver$ConnectThread.run(Driver.java:440) ~[kingbase8-8.6.0.jar:?]
at java.lang.Thread.run(Thread.java:1583) ~[?:?]
[2026-10-15 12:19:09,482][ERROR][Druid-ConnectionPool-Create-900327013] create connection SQLException, url: jdbc:kingbase8://8.162.3.203:54321/economic_crime_dev?currentSchema=public&clientEncoding=utf8&socketTimeout=30000&loginTimeout=30, errorCode 0, state 08001 (DruidDataSource.java:2916)
com.kingbase8.util.KSQLException: The _connection attempt failed.Reason:null
at com.kingbase8.Driver$ConnectThread.getResult(Driver.java:491) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.connect(Driver.java:312) ~[kingbase8-8.6.0.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:132) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1687) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1803) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2914) ~[druid-1.2.23.jar:?]
Caused by: java.io.EOFException
at com.kingbase8.core.KBStream.receiveChar(KBStream.java:587) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.enableSSL(ConnectionFactoryImpl.java:568) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:207) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:280) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.ConnectionFactory.openConnection(ConnectionFactory.java:65) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:336) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:548) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.makeConnection(Driver.java:576) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.access$100(Driver.java:52) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver$ConnectThread.run(Driver.java:440) ~[kingbase8-8.6.0.jar:?]
at java.lang.Thread.run(Thread.java:1583) ~[?:?]
[2026-10-15 12:19:13,365][ERROR][Druid-ConnectionPool-Create-900327013] create connection SQLException, url: jdbc:kingbase8://8.162.3.203:54321/economic_crime_dev?currentSchema=public&clientEncoding=utf8&socketTimeout=30000&loginTimeout=30, errorCode 0, state 08001 (DruidDataSource.java:2916)
com.kingbase8.util.KSQLException: The _connection attempt failed.Reason:null
at com.kingbase8.Driver$ConnectThread.getResult(Driver.java:491) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.connect(Driver.java:312) ~[kingbase8-8.6.0.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:132) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1687) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1803) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2914) ~[druid-1.2.23.jar:?]
Caused by: java.io.EOFException
at com.kingbase8.core.KBStream.receiveChar(KBStream.java:587) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.enableSSL(ConnectionFactoryImpl.java:568) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:207) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:280) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.ConnectionFactory.openConnection(ConnectionFactory.java:65) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:336) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:548) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.makeConnection(Driver.java:576) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.access$100(Driver.java:52) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver$ConnectThread.run(Driver.java:440) ~[kingbase8-8.6.0.jar:?]
at java.lang.Thread.run(Thread.java:1583) ~[?:?]
[2026-10-15 12:19:17,005][ERROR][Druid-ConnectionPool-Create-900327013] create connection SQLException, url: jdbc:kingbase8://8.162.3.203:54321/economic_crime_dev?currentSchema=public&clientEncoding=utf8&socketTimeout=30000&loginTimeout=30, errorCode 0, state 08001 (DruidDataSource.java:2916)
com.kingbase8.util.KSQLException: The _connection attempt failed.Reason:null
at com.kingbase8.Driver$ConnectThread.getResult(Driver.java:491) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.connect(Driver.java:312) ~[kingbase8-8.6.0.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:132) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1687) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1803) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2914) ~[druid-1.2.23.jar:?]
Caused by: java.io.EOFException
at com.kingbase8.core.KBStream.receiveChar(KBStream.java:587) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.enableSSL(ConnectionFactoryImpl.java:568) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:207) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:280) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.ConnectionFactory.openConnection(ConnectionFactory.java:65) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:336) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:548) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.makeConnection(Driver.java:576) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.access$100(Driver.java:52) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver$ConnectThread.run(Driver.java:440) ~[kingbase8-8.6.0.jar:?]
at java.lang.Thread.run(Thread.java:1583) ~[?:?]
[2026-10-15 12:19:20,603][ERROR][Druid-ConnectionPool-Create-900327013] create connection SQLException, url: jdbc:kingbase8://8.162.3.203:54321/economic_crime_dev?currentSchema=public&clientEncoding=utf8&socketTimeout=30000&loginTimeout=30, errorCode 0, state 08001 (DruidDataSource.java:2916)
com.kingbase8.util.KSQLException: The _connection attempt failed.Reason:null
at com.kingbase8.Driver$ConnectThread.getResult(Driver.java:491) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.connect(Driver.java:312) ~[kingbase8-8.6.0.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:132) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1687) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1803) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2914) ~[druid-1.2.23.jar:?]
Caused by: java.io.EOFException
at com.kingbase8.core.KBStream.receiveChar(KBStream.java:587) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.enableSSL(ConnectionFactoryImpl.java:568) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:207) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:280) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.ConnectionFactory.openConnection(ConnectionFactory.java:65) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:336) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:548) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.makeConnection(Driver.java:576) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.access$100(Driver.java:52) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver$ConnectThread.run(Driver.java:440) ~[kingbase8-8.6.0.jar:?]
at java.lang.Thread.run(Thread.java:1583) ~[?:?]
[2026-10-15 12:19:25,112][ERROR][Druid-ConnectionPool-Create-900327013] create connection SQLException, url: jdbc:kingbase8://8.162.3.203:54321/economic_crime_dev?currentSchema=public&clientEncoding=utf8&socketTimeout=30000&loginTimeout=30, errorCode 0, state 08001 (DruidDataSource.java:2916)
com.kingbase8.util.KSQLException: The _connection attempt failed.Reason:null
at com.kingbase8.Driver$ConnectThread.getResult(Driver.java:491) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.connect(Driver.java:312) ~[kingbase8-8.6.0.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:132) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:244) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:126) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1687) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1803) ~[druid-1.2.23.jar:?]
at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2914) ~[druid-1.2.23.jar:?]
Caused by: java.io.EOFException
at com.kingbase8.core.KBStream.receiveChar(KBStream.java:587) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.enableSSL(ConnectionFactoryImpl.java:568) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:207) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:280) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.core.ConnectionFactory.openConnection(ConnectionFactory.java:65) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:336) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.jdbc.KbConnection.<init>(KbConnection.java:548) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.makeConnection(Driver.java:576) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver.access$100(Driver.java:52) ~[kingbase8-8.6.0.jar:?]
at com.kingbase8.Driver$ConnectThread.run(Driver.java:440) ~[kingbase8-8.6.0.jar:?]
at java.lang.Thread.run(Thread.java:1583) ~[?:?]

72
logs/economic-crime/dev/info/info.log

@ -1,72 +0,0 @@
[2026-10-15 08:51:45,962][INFO ][main] ip2region 初始化成功 (Ip2RegionListener.java:30)
[2026-10-15 08:51:45,978][INFO ][background-preinit] HV000001: Hibernate Validator 6.2.5.Final (Version.java:21)
[2026-10-15 08:51:45,999][INFO ][main] Starting AdminApplication using Java 21.0.11 on MswangdeMacBook-Air.local with PID 34134 (/Users/wang/sanduoyun/developspace/economic-crime/economic-crime-api/economic-crime-admin/target/classes started by wang in /Users/wang/sanduoyun/developspace/economic-crime) (StartupInfoLogger.java:55)
[2026-10-15 08:51:46,000][INFO ][main] The following 1 profile is active: "dev" (SpringApplication.java:638)
[2026-10-15 08:51:46,483][INFO ][main] Multiple Spring Data modules found, entering strict repository configuration mode (RepositoryConfigurationDelegate.java:262)
[2026-10-15 08:51:46,484][INFO ][main] Bootstrapping Spring Data Redis repositories in DEFAULT mode. (RepositoryConfigurationDelegate.java:132)
[2026-10-15 08:51:46,501][INFO ][main] Finished Spring Data repository scanning in 12 ms. Found 0 Redis repository interfaces. (RepositoryConfigurationDelegate.java:201)
[2026-10-15 08:51:46,825][INFO ][main] Bean 'mybatisPlusConfig' of type [net.lab1024.sa.base.config.MybatisPlusConfig$$EnhancerBySpringCGLIB$$1bc72e5b] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) (PostProcessorRegistrationDelegate.java:376)
[2026-10-15 08:51:46,830][INFO ][main] Bean 'paginationInterceptor' of type [com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) (PostProcessorRegistrationDelegate.java:376)
[2026-10-15 08:51:46,832][INFO ][main] Bean 'myBatisPlugin' of type [net.lab1024.sa.admin.module.system.datascope.MyBatisPlugin] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) (PostProcessorRegistrationDelegate.java:376)
[2026-10-15 08:51:46,835][INFO ][main] Bean 'dataSourceConfig' of type [net.lab1024.sa.base.config.DataSourceConfig$$EnhancerBySpringCGLIB$$600eefef] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) (PostProcessorRegistrationDelegate.java:376)
[2026-10-15 08:51:46,837][INFO ][main] Bean 'jdkRegexpMethodPointcut' of type [org.springframework.aop.support.JdkRegexpMethodPointcut] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) (PostProcessorRegistrationDelegate.java:376)
[2026-10-15 08:51:46,838][INFO ][main] Bean 'defaultPointcutAdvisor' of type [org.springframework.aop.support.DefaultPointcutAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) (PostProcessorRegistrationDelegate.java:376)
[2026-10-15 08:51:47,611][INFO ][main] {dataSource-1} inited (DruidDataSource.java:1002)
[2026-10-15 08:51:47,616][INFO ][main] Bean 'druidDataSource' of type [com.alibaba.druid.pool.DruidDataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) (PostProcessorRegistrationDelegate.java:376)
[2026-10-15 08:51:48,006][INFO ][main] Bean 'sqlSessionFactory' of type [org.apache.ibatis.session.defaults.DefaultSqlSessionFactory] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) (PostProcessorRegistrationDelegate.java:376)
[2026-10-15 08:51:48,008][INFO ][main] Bean 'org.springframework.boot.autoconfigure.sql.init.DataSourceInitializationConfiguration' of type [org.springframework.boot.autoconfigure.sql.init.DataSourceInitializationConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) (PostProcessorRegistrationDelegate.java:376)
[2026-10-15 08:51:48,013][INFO ][main] Bean 'spring.sql.init-org.springframework.boot.autoconfigure.sql.init.SqlInitializationProperties' of type [org.springframework.boot.autoconfigure.sql.init.SqlInitializationProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) (PostProcessorRegistrationDelegate.java:376)
[2026-10-15 08:51:48,015][INFO ][main] Bean 'dataSourceScriptDatabaseInitializer' of type [org.springframework.boot.autoconfigure.sql.init.SqlDataSourceScriptDatabaseInitializer] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) (PostProcessorRegistrationDelegate.java:376)
[2026-10-15 08:51:48,018][INFO ][main] Bean 'mybatis-plus-com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties' of type [com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) (PostProcessorRegistrationDelegate.java:376)
[2026-10-15 08:51:48,021][INFO ][main] Bean 'mybatisDatabaseIdProviderConfig' of type [net.lab1024.sa.base.config.MybatisDatabaseIdProviderConfig$$EnhancerBySpringCGLIB$$77f9ae8] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) (PostProcessorRegistrationDelegate.java:376)
[2026-10-15 08:51:48,022][INFO ][main] Bean 'databaseIdProvider' of type [org.apache.ibatis.mapping.VendorDatabaseIdProvider] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) (PostProcessorRegistrationDelegate.java:376)
[2026-10-15 08:51:48,024][INFO ][main] Bean 'com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration' of type [com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) (PostProcessorRegistrationDelegate.java:376)
[2026-10-15 08:51:48,026][INFO ][main] Bean 'sqlSessionTemplate' of type [org.mybatis.spring.SqlSessionTemplate] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) (PostProcessorRegistrationDelegate.java:376)
[2026-10-15 08:51:48,028][INFO ][main] Bean 'reloadItemDao' of type [org.mybatis.spring.mapper.MapperFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) (PostProcessorRegistrationDelegate.java:376)
[2026-10-15 08:51:48,030][INFO ][main] Bean 'reloadItemDao' of type [jdk.proxy2.$Proxy122] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) (PostProcessorRegistrationDelegate.java:376)
[2026-10-15 08:51:48,036][INFO ][main] Bean 'reloadResultDao' of type [org.mybatis.spring.mapper.MapperFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) (PostProcessorRegistrationDelegate.java:376)
[2026-10-15 08:51:48,037][INFO ][main] Bean 'reloadResultDao' of type [jdk.proxy2.$Proxy124] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) (PostProcessorRegistrationDelegate.java:376)
[2026-10-15 08:51:48,041][INFO ][main] Bean 'reloadCommand' of type [net.lab1024.sa.base.module.support.reload.ReloadCommand] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) (PostProcessorRegistrationDelegate.java:376)
[2026-10-15 08:51:48,166][INFO ][main] Tomcat initialized with port(s): 1024 (http) (TomcatWebServer.java:108)
[2026-10-15 08:51:48,170][INFO ][main] Initializing ProtocolHandler ["http-nio-1024"] (DirectJDKLog.java:173)
[2026-10-15 08:51:48,170][INFO ][main] Starting service [Tomcat] (DirectJDKLog.java:173)
[2026-10-15 08:51:48,170][INFO ][main] Starting Servlet engine: [Apache Tomcat/9.0.83] (DirectJDKLog.java:173)
[2026-10-15 08:51:48,233][INFO ][main] Initializing Spring embedded WebApplicationContext (DirectJDKLog.java:173)
[2026-10-15 08:51:48,234][INFO ][main] Root WebApplicationContext: initialization completed in 2217 ms (ServletWebServerApplicationContext.java:292)
[2026-10-15 08:51:48,538][INFO ][main] Reflections took 78 ms to scan 2 urls, producing 26 keys and 8402 values (Reflections.java:232)
[2026-10-15 08:51:48,661][INFO ][main] ################# 系统配置缓存初始化完毕:2 ################### (ConfigService.java:58)
[2026-10-15 08:51:48,934][INFO ][main] Redisson 3.17.7 (Version.java:41)
[2026-10-15 08:51:49,127][INFO ][redisson-netty-2-10] 1 connections initialized for 8.162.3.203/8.162.3.203:6379 (ConnectionPool.java:161)
[2026-10-15 08:51:49,804][INFO ][redisson-netty-2-19] 24 connections initialized for 8.162.3.203/8.162.3.203:6379 (ConnectionPool.java:161)
[2026-10-15 08:51:50,888][INFO ][main] ==== SmartJob ==== client-manager init (SmartJobClientManager.java:67)
[2026-10-15 08:51:51,111][INFO ][main] 不需要登录的URL:[/login, /login/sendEmailCode/{loginName}, /login/getTwoFactorLoginFlag, /login/getCaptcha] (UrlConfig.java:134)
[2026-10-15 08:51:51,182][INFO ][main] 本地文件访问目录: /Users/wang/sanduoyun/developspace/economic-crime/economic-crime-api/upload (FileConfig.java:105)
[2026-10-15 08:51:51,241][INFO ][main] 【warm-flow】,加载完成 (BeanConfig.java:152)
[2026-10-15 08:51:51,489][INFO ][main] Exposing 1 endpoint(s) beneath base path '/actuator' (EndpointLinksResolver.java:58)
[2026-10-15 08:51:51,538][INFO ][main] Starting ProtocolHandler ["http-nio-1024"] (DirectJDKLog.java:173)
[2026-10-15 08:51:51,542][INFO ][main] Tomcat started on port(s): 1024 (http) with context path '' (TomcatWebServer.java:220)
[2026-10-15 08:51:51,556][INFO ][main] SmartJob polling scheduled after application context refreshed (SmartJobPollingStarter.java:32)
[2026-10-15 08:51:51,558][INFO ][main] Started AdminApplication in 5.815 seconds (JVM running for 6.361) (StartupInfoLogger.java:61)
[2026-10-15 08:51:51,602][INFO ][RMI TCP Connection(2)-127.0.0.1] Initializing Spring DispatcherServlet 'dispatcherServlet' (DirectJDKLog.java:173)
[2026-10-15 08:51:51,602][INFO ][RMI TCP Connection(2)-127.0.0.1] Initializing Servlet 'dispatcherServlet' (FrameworkServlet.java:525)
[2026-10-15 08:51:51,604][INFO ][RMI TCP Connection(2)-127.0.0.1] Completed initialization in 2 ms (FrameworkServlet.java:547)
[2026-10-15 08:52:01,609][INFO ][SmartJobLauncher-0] ==== SmartJob ==== job list empty (SmartJobLauncher.java:93)
[2026-10-15 08:53:01,644][INFO ][SmartJobLauncher-0] ==== SmartJob ==== job list empty (SmartJobLauncher.java:93)
[2026-10-15 08:53:46,750][INFO ][http-nio-1024-exec-3] 审核表决已提交未齐票,alarmId=20,seat=legal,result=agree (AlarmReportService.java:805)
[2026-10-15 08:54:01,685][INFO ][SmartJobLauncher-0] ==== SmartJob ==== job list empty (SmartJobLauncher.java:93)
[2026-10-15 08:55:01,721][INFO ][SmartJobLauncher-0] ==== SmartJob ==== job list empty (SmartJobLauncher.java:93)
[2026-10-15 09:02:19,543][INFO ][SmartJobLauncher-0] ==== SmartJob ==== job list empty (SmartJobLauncher.java:93)
[2026-10-15 09:03:19,581][INFO ][SmartJobLauncher-0] ==== SmartJob ==== job list empty (SmartJobLauncher.java:93)
[2026-10-15 09:04:19,614][INFO ][SmartJobLauncher-0] ==== SmartJob ==== job list empty (SmartJobLauncher.java:93)
[2026-10-15 09:05:19,690][INFO ][SmartJobLauncher-0] ==== SmartJob ==== job list empty (SmartJobLauncher.java:93)
[2026-10-15 09:06:19,761][INFO ][SmartJobLauncher-0] ==== SmartJob ==== job list empty (SmartJobLauncher.java:93)
[2026-10-15 09:07:19,838][INFO ][SmartJobLauncher-0] ==== SmartJob ==== job list empty (SmartJobLauncher.java:93)
[2026-10-15 09:08:19,878][INFO ][SmartJobLauncher-0] ==== SmartJob ==== job list empty (SmartJobLauncher.java:93)
[2026-10-15 09:09:19,918][INFO ][SmartJobLauncher-0] ==== SmartJob ==== job list empty (SmartJobLauncher.java:93)
[2026-10-15 09:10:19,989][INFO ][SmartJobLauncher-0] ==== SmartJob ==== job list empty (SmartJobLauncher.java:93)
[2026-10-15 09:11:20,058][INFO ][SmartJobLauncher-0] ==== SmartJob ==== job list empty (SmartJobLauncher.java:93)
[2026-10-15 09:12:20,099][INFO ][SmartJobLauncher-0] ==== SmartJob ==== job list empty (SmartJobLauncher.java:93)
[2026-10-15 09:13:20,141][INFO ][SmartJobLauncher-0] ==== SmartJob ==== job list empty (SmartJobLauncher.java:93)
[2026-10-15 09:14:20,183][INFO ][SmartJobLauncher-0] ==== SmartJob ==== job list empty (SmartJobLauncher.java:93)
[2026-10-15 09:15:20,218][INFO ][SmartJobLauncher-0] ==== SmartJob ==== job list empty (SmartJobLauncher.java:93)
[2026-10-15 11:00:00,147][INFO ][Druid-ConnectionPool-Create-900327013] {dataSource-1} failContinuous is true (DruidAbstractDataSource.java:1900)

1512
logs/economic-crime/dev/slow-sql/slow-sql.log

File diff suppressed because it is too large

15
logs/economic-crime/dev/warn/warn.log

@ -1,15 +0,0 @@
[2026-10-15 08:51:47,969][WARN ][main] [net.lab1024.sa.base.module.support.operatelog.OperateLogDao.deleteByIds] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteByIds] (AbstractMethod.java:407)
[2026-10-15 08:51:48,945][WARN ][main] Can not find io.netty.resolver.dns.macos.MacOSDnsServerAddressStreamProvider in the classpath, fallback to system defaults. This may result in incorrect DNS resolutions on MacOS. Check whether you have a dependency on 'io.netty:netty-resolver-dns-native-macos' (DnsServerAddressStreamProviders.java:70)
[2026-10-15 08:51:49,931][WARN ][main] upload-path 配置 [../upload/] 未命中有效目录,自动使用: /Users/wang/sanduoyun/developspace/economic-crime/economic-crime-api/upload (LocalUploadPathResolver.java:34)
[2026-10-15 08:51:51,182][WARN ][main] upload-path 配置 [../upload/] 未命中有效目录,自动使用: /Users/wang/sanduoyun/developspace/economic-crime/economic-crime-api/upload (LocalUploadPathResolver.java:34)
[2026-10-15 08:51:51,468][WARN ][main] Cannot find template location(s): [classpath:/templates/] (please add some templates, check your FreeMarker configuration, or set spring.freemarker.check-template-location=false) (FreeMarkerAutoConfiguration.java:65)
[2026-10-15 08:51:51,547][WARN ][main]
-------------【economic-crime】 服务已成功启动 (economic-crime started successfully)-------------
当前启动环境: dev , 开发环境
返回码初始化: 完成15个返回码初始化
服务本机地址: http://localhost:1024/
服务外网地址: http://198.18.0.1:1024/
Swagger地址: http://localhost:1024/swagger-ui/index.html
knife4j地址: http://localhost:1024/doc.html
-------------------------------------------------------------------------------------
(WebServerListener.java:66)
Loading…
Cancel
Save