52 changed files with 3543 additions and 36586 deletions
@ -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"; |
|||
} |
|||
@ -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 -> "普通经侦案件"; |
|||
}; |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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> { |
|||
} |
|||
@ -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> { |
|||
} |
|||
@ -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> { |
|||
} |
|||
@ -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); |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
@ -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; |
|||
}; |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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> { |
|||
} |
|||
@ -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); |
|||
} |
|||
@ -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> { |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
@ -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(); |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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> |
|||
@ -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> |
|||
@ -0,0 +1,5 @@ |
|||
import { getRequest, postRequest } from '/@/lib/axios'; |
|||
|
|||
export const negativeListApi = { |
|||
query: (param) => postRequest('/negative-list/query', param), |
|||
}; |
|||
@ -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}`), |
|||
}; |
|||
@ -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}`), |
|||
}; |
|||
@ -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'; |
|||
} |
|||
@ -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'; |
|||
} |
|||
@ -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, '&') |
|||
.replace(/</g, '<') |
|||
.replace(/>/g, '>') |
|||
.replace(/"/g, '"'); |
|||
} |
|||
|
|||
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(); |
|||
} |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
File diff suppressed because it is too large
@ -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) ~[?:?] |
|||
@ -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) |
|||
File diff suppressed because it is too large
@ -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…
Reference in new issue