diff --git a/pom.xml b/pom.xml
index 6264bb5241..44fd7a94bc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -46,6 +46,11 @@
3.5.9
1.6.3
UTF-8
+
+
+ false
+ true
+ true
diff --git a/sql/prison_init.sql b/sql/prison_init.sql
index 6c8e4d0e19..67ee052563 100644
--- a/sql/prison_init.sql
+++ b/sql/prison_init.sql
@@ -27,10 +27,17 @@ CREATE TABLE IF NOT EXISTS `prison_prisoner` (
`original_sentence` varchar(100) DEFAULT NULL COMMENT '原判刑期',
`imprisonment_date` date DEFAULT NULL COMMENT '入狱日期',
`release_date` date DEFAULT NULL COMMENT '释放日期',
+ `release_type` tinyint DEFAULT 0 COMMENT '释放类型:0-未知 1-刑满释放 2-假释 3-保外就医 4-减刑 5-暂予监外执行 6-特赦 7-死亡 8-其他',
+ `release_reason` varchar(500) DEFAULT NULL COMMENT '释放原因',
+ `photo` varchar(512) DEFAULT NULL COMMENT '照片URL',
`supervision_level` tinyint DEFAULT 2 COMMENT '监管等级:1-严管 2-普管 3-宽管',
`risk_level` tinyint DEFAULT 1 COMMENT '风险等级:1-低风险 2-中风险 3-高风险 4-极高风险',
`prison_area_id` bigint DEFAULT NULL COMMENT '监区ID',
+ `sub_area_id` bigint DEFAULT NULL COMMENT '分区ID',
`prison_cell_id` bigint DEFAULT NULL COMMENT '监室ID',
+ `marital_status` tinyint DEFAULT NULL COMMENT '婚姻状态:1-未婚 2-已婚 3-离异 4-丧偶',
+ `crime_type` varchar(100) DEFAULT NULL COMMENT '罪名类型',
+ `sentence` varchar(100) DEFAULT NULL COMMENT '刑期',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态:1-在押 2-已释放 3-已死亡 4-假释',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
diff --git a/yudao-framework/yudao-spring-boot-starter-monitor/src/main/java/cn/iocoder/yudao/framework/tracer/config/TracerProperties.java b/yudao-framework/yudao-spring-boot-starter-monitor/src/main/java/cn/iocoder/yudao/framework/tracer/config/TracerProperties.java
old mode 100644
new mode 100755
diff --git a/yudao-framework/yudao-spring-boot-starter-monitor/src/main/java/cn/iocoder/yudao/framework/tracer/config/YudaoMetricsAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-monitor/src/main/java/cn/iocoder/yudao/framework/tracer/config/YudaoMetricsAutoConfiguration.java
old mode 100644
new mode 100755
diff --git a/yudao-framework/yudao-spring-boot-starter-monitor/src/main/java/cn/iocoder/yudao/framework/tracer/config/YudaoTracerAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-monitor/src/main/java/cn/iocoder/yudao/framework/tracer/config/YudaoTracerAutoConfiguration.java
old mode 100644
new mode 100755
diff --git a/yudao-framework/yudao-spring-boot-starter-monitor/src/main/java/cn/iocoder/yudao/framework/tracer/core/annotation/BizTrace.java b/yudao-framework/yudao-spring-boot-starter-monitor/src/main/java/cn/iocoder/yudao/framework/tracer/core/annotation/BizTrace.java
old mode 100644
new mode 100755
diff --git a/yudao-framework/yudao-spring-boot-starter-monitor/src/main/java/cn/iocoder/yudao/framework/tracer/core/aop/BizTraceAspect.java b/yudao-framework/yudao-spring-boot-starter-monitor/src/main/java/cn/iocoder/yudao/framework/tracer/core/aop/BizTraceAspect.java
old mode 100644
new mode 100755
diff --git a/yudao-framework/yudao-spring-boot-starter-monitor/src/main/java/cn/iocoder/yudao/framework/tracer/core/filter/TraceFilter.java b/yudao-framework/yudao-spring-boot-starter-monitor/src/main/java/cn/iocoder/yudao/framework/tracer/core/filter/TraceFilter.java
old mode 100644
new mode 100755
diff --git a/yudao-framework/yudao-spring-boot-starter-monitor/src/main/java/cn/iocoder/yudao/framework/tracer/core/util/TracerFrameworkUtils.java b/yudao-framework/yudao-spring-boot-starter-monitor/src/main/java/cn/iocoder/yudao/framework/tracer/core/util/TracerFrameworkUtils.java
old mode 100644
new mode 100755
diff --git a/yudao-framework/yudao-spring-boot-starter-monitor/src/main/java/cn/iocoder/yudao/framework/tracer/package-info.java b/yudao-framework/yudao-spring-boot-starter-monitor/src/main/java/cn/iocoder/yudao/framework/tracer/package-info.java
old mode 100644
new mode 100755
diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/mq/producer/package-info.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/mq/producer/package-info.java
old mode 100644
new mode 100755
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/controller/admin/dashboard/PrisonDashboardController.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/controller/admin/dashboard/PrisonDashboardController.java
index 522e81485b..773e3f1b8e 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/controller/admin/dashboard/PrisonDashboardController.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/controller/admin/dashboard/PrisonDashboardController.java
@@ -1,12 +1,13 @@
package cn.iocoder.yudao.module.prison.controller.admin.dashboard;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.module.prison.controller.admin.dashboard.vo.DashboardStatisticsVO;
-import cn.iocoder.yudao.module.prison.controller.admin.dashboard.vo.PrisonerDashboardStatsRespVO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.prison.controller.admin.dashboard.vo.*;
import cn.iocoder.yudao.module.prison.service.dashboard.PrisonDashboardService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
@@ -44,4 +45,18 @@ public class PrisonDashboardController {
return success(dashboardService.getPrisonerStats(prisonerId));
}
+ @GetMapping("/ai-dash-entry/statistics")
+ @Operation(summary = "获取AI心航360°统计数据")
+ @PreAuthorize("@ss.hasPermission('prison:ai-dash-entry:query')")
+ public CommonResult getAiDashEntryStatistics() {
+ return success(dashboardService.getAiDashEntryStatistics());
+ }
+
+ @GetMapping("/ai-dash-entry/focus-person-page")
+ @Operation(summary = "获取重点关注对象分页列表")
+ @PreAuthorize("@ss.hasPermission('prison:ai-dash-entry:query')")
+ public CommonResult> getFocusPersonPage(@Valid FocusPersonPageReqVO reqVO) {
+ return success(dashboardService.getFocusPersonPage(reqVO));
+ }
+
}
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/controller/admin/dashboard/vo/AiDashEntryStatisticsVO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/controller/admin/dashboard/vo/AiDashEntryStatisticsVO.java
new file mode 100644
index 0000000000..daeb43ccfd
--- /dev/null
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/controller/admin/dashboard/vo/AiDashEntryStatisticsVO.java
@@ -0,0 +1,97 @@
+package cn.iocoder.yudao.module.prison.controller.admin.dashboard.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Schema(description = "管理后台 - AI心航360°统计 Response VO")
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class AiDashEntryStatisticsVO {
+
+ // ==================== 统计卡片数据 ====================
+
+ @Schema(description = "全部人员数量")
+ private Integer totalCount;
+
+ @Schema(description = "本月新增人员数量")
+ private Integer monthlyNewCount;
+
+ @Schema(description = "本月较上月变化")
+ private Integer monthlyChange;
+
+ @Schema(description = "高危人员数量")
+ private Integer highRiskCount;
+
+ @Schema(description = "高危本月新增")
+ private Integer highRiskMonthlyNew;
+
+ @Schema(description = "高危本月变化")
+ private Integer highRiskMonthlyChange;
+
+ @Schema(description = "预警人员数量")
+ private Integer warningCount;
+
+ @Schema(description = "预警本月新增")
+ private Integer warningMonthlyNew;
+
+ @Schema(description = "预警本月变化")
+ private Integer warningMonthlyChange;
+
+ @Schema(description = "普通人员数量")
+ private Integer normalCount;
+
+ @Schema(description = "普通本月新增")
+ private Integer normalMonthlyNew;
+
+ @Schema(description = "普通本月变化")
+ private Integer normalMonthlyChange;
+
+ // ==================== 图表数据 ====================
+
+ @Schema(description = "风险等级分布")
+ private List riskDistribution;
+
+ @Schema(description = "风险趋势数据")
+ private List riskTrendData;
+
+ /**
+ * 风险等级分布数据
+ */
+ @Data
+ @Builder
+ @NoArgsConstructor
+ @AllArgsConstructor
+ public static class RiskDistributionVO {
+ @Schema(description = "名称")
+ private String name;
+ @Schema(description = "数量")
+ private Integer value;
+ @Schema(description = "颜色")
+ private String color;
+ }
+
+ /**
+ * 风险趋势数据
+ */
+ @Data
+ @Builder
+ @NoArgsConstructor
+ @AllArgsConstructor
+ public static class RiskTrendVO {
+ @Schema(description = "月份")
+ private String month;
+ @Schema(description = "高危人数")
+ private Integer highRisk;
+ @Schema(description = "预警人数")
+ private Integer warning;
+ @Schema(description = "普通人数")
+ private Integer normal;
+ }
+}
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/controller/admin/dashboard/vo/FocusPersonPageReqVO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/controller/admin/dashboard/vo/FocusPersonPageReqVO.java
new file mode 100644
index 0000000000..4f341a731a
--- /dev/null
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/controller/admin/dashboard/vo/FocusPersonPageReqVO.java
@@ -0,0 +1,23 @@
+package cn.iocoder.yudao.module.prison.controller.admin.dashboard.vo;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+@Schema(description = "管理后台 - 重点关注对象分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class FocusPersonPageReqVO extends PageParam {
+
+ @Schema(description = "风险等级类型:high-高危, warning-预警, normal-普通, 空为全部")
+ private String riskLevelType;
+
+ @Schema(description = "罪犯姓名,模糊匹配")
+ private String name;
+
+ @Schema(description = "监区ID")
+ private Long areaId;
+}
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/controller/admin/dashboard/vo/FocusPersonVO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/controller/admin/dashboard/vo/FocusPersonVO.java
new file mode 100644
index 0000000000..b92f83701e
--- /dev/null
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/controller/admin/dashboard/vo/FocusPersonVO.java
@@ -0,0 +1,42 @@
+package cn.iocoder.yudao.module.prison.controller.admin.dashboard.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Schema(description = "管理后台 - 重点关注对象 Response VO")
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class FocusPersonVO {
+
+ @Schema(description = "罪犯ID")
+ private Long id;
+
+ @Schema(description = "罪犯姓名")
+ private String name;
+
+ @Schema(description = "性别")
+ private String gender;
+
+ @Schema(description = "年龄")
+ private Integer age;
+
+ @Schema(description = "风险等级:high-高危, warning-预警, normal-普通")
+ private String riskLevelType;
+
+ @Schema(description = "风险等级文本")
+ private String riskLevel;
+
+ @Schema(description = "监区")
+ private String supervisionArea;
+
+ @Schema(description = "心理风险等级")
+ private String psychologicalRiskLevel;
+
+ @Schema(description = "是否新增")
+ private Boolean isNew;
+}
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/PrisonerAreaLogDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/PrisonerAreaLogDO.java
index 746a1f1d92..5a27b6076c 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/PrisonerAreaLogDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/PrisonerAreaLogDO.java
@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.prison.dal.dataobject;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
@@ -19,7 +19,7 @@ import java.time.LocalDateTime;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class PrisonerAreaLogDO extends BaseDO {
+public class PrisonerAreaLogDO extends TenantBaseDO {
/**
* 主键ID
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/PrisonerDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/PrisonerDO.java
index e9f36f1525..ed7d99077f 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/PrisonerDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/PrisonerDO.java
@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.prison.dal.dataobject;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.module.prison.enums.*;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableName;
@@ -20,7 +20,7 @@ import java.time.LocalDate;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class PrisonerDO extends BaseDO {
+public class PrisonerDO extends TenantBaseDO {
/**
* 主键ID
@@ -172,6 +172,26 @@ public class PrisonerDO extends BaseDO {
*/
private Long prisonCellId;
+ /**
+ * 婚姻状态:1-未婚 2-已婚 3-离异 4-丧偶
+ */
+ private Integer maritalStatus;
+
+ /**
+ * 罪名类型
+ */
+ private String crimeType;
+
+ /**
+ * 刑期
+ */
+ private String sentence;
+
+ /**
+ * 子女情况
+ */
+ private String children;
+
/**
* 状态
*/
@@ -182,4 +202,30 @@ public class PrisonerDO extends BaseDO {
*/
private String remark;
+ // ========== 兼容方法 ==========
+
+ public LocalDate getBirthDate() {
+ return this.birthday;
+ }
+
+ public Long getAreaId() {
+ return this.prisonAreaId;
+ }
+
+ public Integer getMaritalStatus() {
+ return this.maritalStatus;
+ }
+
+ public String getCrimeType() {
+ return this.crimeType;
+ }
+
+ public String getSentence() {
+ return this.sentence;
+ }
+
+ public String getChildren() {
+ return this.children;
+ }
+
}
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/answer/AnswerDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/answer/AnswerDO.java
index 488f1721ac..e720224824 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/answer/AnswerDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/answer/AnswerDO.java
@@ -5,7 +5,7 @@ import java.util.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
/**
* 问卷答题记录 DO
@@ -20,7 +20,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class AnswerDO extends BaseDO {
+public class AnswerDO extends TenantBaseDO {
/**
* 答题记录ID
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/area/AreaDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/area/AreaDO.java
index a8593904e7..1365d40930 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/area/AreaDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/area/AreaDO.java
@@ -4,7 +4,7 @@ import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.TableField;
/**
@@ -20,7 +20,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class AreaDO extends BaseDO {
+public class AreaDO extends TenantBaseDO {
/**
* 监区ID
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/cell/CellDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/cell/CellDO.java
index 03347a97e2..0f57121abe 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/cell/CellDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/cell/CellDO.java
@@ -5,7 +5,7 @@ import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
/**
* 监室信息 DO
@@ -20,7 +20,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class CellDO extends BaseDO {
+public class CellDO extends TenantBaseDO {
/**
* 监室ID
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/consumption/ConsumptionDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/consumption/ConsumptionDO.java
index 1479c39237..ad50c6f5bc 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/consumption/ConsumptionDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/consumption/ConsumptionDO.java
@@ -5,7 +5,7 @@ import java.util.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
/**
* 消费订单 DO
@@ -20,7 +20,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class ConsumptionDO extends BaseDO {
+public class ConsumptionDO extends TenantBaseDO {
/**
* 消费ID
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/consumption/ConsumptionDetailDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/consumption/ConsumptionDetailDO.java
index b3f24bcd06..c48c0bfe88 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/consumption/ConsumptionDetailDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/consumption/ConsumptionDetailDO.java
@@ -4,7 +4,7 @@ import lombok.*;
import java.util.*;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
/**
* 消费明细 DO
@@ -19,7 +19,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class ConsumptionDetailDO extends BaseDO {
+public class ConsumptionDetailDO extends TenantBaseDO {
/**
* 明细ID
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/evaluationreport/EvaluationDimensionDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/evaluationreport/EvaluationDimensionDO.java
index 7e916d50b6..b789807386 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/evaluationreport/EvaluationDimensionDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/evaluationreport/EvaluationDimensionDO.java
@@ -5,7 +5,7 @@ import java.util.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
/**
@@ -21,7 +21,7 @@ import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class EvaluationDimensionDO extends BaseDO {
+public class EvaluationDimensionDO extends TenantBaseDO {
/**
* 维度ID
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/evaluationreport/EvaluationDimensionDataDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/evaluationreport/EvaluationDimensionDataDO.java
index 57c95b7939..b13911719f 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/evaluationreport/EvaluationDimensionDataDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/evaluationreport/EvaluationDimensionDataDO.java
@@ -5,7 +5,7 @@ import java.util.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
/**
* 报告维度数据 DO
@@ -20,7 +20,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class EvaluationDimensionDataDO extends BaseDO {
+public class EvaluationDimensionDataDO extends TenantBaseDO {
/**
* 数据ID
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/evaluationreport/EvaluationReportDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/evaluationreport/EvaluationReportDO.java
index cc75a479a7..f03cd3d54a 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/evaluationreport/EvaluationReportDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/evaluationreport/EvaluationReportDO.java
@@ -5,7 +5,7 @@ import java.util.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
/**
* 评估报告 DO
@@ -20,7 +20,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class EvaluationReportDO extends BaseDO {
+public class EvaluationReportDO extends TenantBaseDO {
/**
* 报告ID
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/evaluationreport/EvaluationTemplateDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/evaluationreport/EvaluationTemplateDO.java
index 42aef39b74..ee98349583 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/evaluationreport/EvaluationTemplateDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/evaluationreport/EvaluationTemplateDO.java
@@ -5,7 +5,7 @@ import java.util.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.TableField;
/**
@@ -21,7 +21,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class EvaluationTemplateDO extends BaseDO {
+public class EvaluationTemplateDO extends TenantBaseDO {
/**
* 模板ID
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/evaluationreport/ReportCommentDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/evaluationreport/ReportCommentDO.java
index aaf5851ba0..b3d379c535 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/evaluationreport/ReportCommentDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/evaluationreport/ReportCommentDO.java
@@ -4,7 +4,7 @@ import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
/**
* 快捷评语库 DO
@@ -19,7 +19,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class ReportCommentDO extends BaseDO {
+public class ReportCommentDO extends TenantBaseDO {
/**
* 评语ID
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/question/QuestionDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/question/QuestionDO.java
index 768e13696a..310f22b221 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/question/QuestionDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/question/QuestionDO.java
@@ -5,7 +5,7 @@ import java.util.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
/**
* 问卷问题 DO
@@ -20,7 +20,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class QuestionDO extends BaseDO {
+public class QuestionDO extends TenantBaseDO {
/**
* 问题ID
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/questionnaire/QuestionnaireDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/questionnaire/QuestionnaireDO.java
index 85c378d933..a9b271e6a6 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/questionnaire/QuestionnaireDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/questionnaire/QuestionnaireDO.java
@@ -5,7 +5,7 @@ import java.util.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
/**
* 问卷模板 DO
@@ -20,7 +20,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class QuestionnaireDO extends BaseDO {
+public class QuestionnaireDO extends TenantBaseDO {
/**
* 问卷ID
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/questionnairerecord/QuestionnaireRecordDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/questionnairerecord/QuestionnaireRecordDO.java
index 96901c410f..6023c428c4 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/questionnairerecord/QuestionnaireRecordDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/questionnairerecord/QuestionnaireRecordDO.java
@@ -5,7 +5,7 @@ import java.util.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
/**
* 问卷答题记录 / 测评记录 DO
@@ -20,7 +20,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class QuestionnaireRecordDO extends BaseDO {
+public class QuestionnaireRecordDO extends TenantBaseDO {
/**
* 记录ID
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/quickcomment/CommentCategoryDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/quickcomment/CommentCategoryDO.java
index f07d2321a5..c048f2f406 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/quickcomment/CommentCategoryDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/quickcomment/CommentCategoryDO.java
@@ -4,7 +4,7 @@ import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
/**
* 快捷评语分类 DO
@@ -19,7 +19,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class CommentCategoryDO extends BaseDO {
+public class CommentCategoryDO extends TenantBaseDO {
/**
* 分类ID
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/quickcomment/QuickCommentDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/quickcomment/QuickCommentDO.java
index 363c0687fa..ad3f8c8186 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/quickcomment/QuickCommentDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/quickcomment/QuickCommentDO.java
@@ -4,7 +4,7 @@ import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
/**
* 快捷评语 DO
@@ -19,7 +19,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class QuickCommentDO extends BaseDO {
+public class QuickCommentDO extends TenantBaseDO {
/**
* 评语ID
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/release/ReleaseDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/release/ReleaseDO.java
index 3411a8ab0c..9b23fe5118 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/release/ReleaseDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/release/ReleaseDO.java
@@ -5,7 +5,7 @@ import java.util.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
/**
* 释放登记记录 DO
@@ -20,7 +20,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class ReleaseDO extends BaseDO {
+public class ReleaseDO extends TenantBaseDO {
/**
* 记录ID
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/report/ReportDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/report/ReportDO.java
index 40780899b7..e3460409d3 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/report/ReportDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/report/ReportDO.java
@@ -5,7 +5,7 @@ import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDate;
import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
/**
* 评估报告 DO
@@ -20,7 +20,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class ReportDO extends BaseDO {
+public class ReportDO extends TenantBaseDO {
/**
* 报告ID
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/reporttemplate/ReportTemplateDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/reporttemplate/ReportTemplateDO.java
index 2a334a8b1e..49390caf77 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/reporttemplate/ReportTemplateDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/reporttemplate/ReportTemplateDO.java
@@ -4,7 +4,7 @@ import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
/**
* 评估报告模板 DO
@@ -19,7 +19,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class ReportTemplateDO extends BaseDO {
+public class ReportTemplateDO extends TenantBaseDO {
/**
* 模板ID
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/risk/RiskDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/risk/RiskDO.java
index d8b0ff248f..8f1e72c86a 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/risk/RiskDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/risk/RiskDO.java
@@ -5,7 +5,7 @@ import java.util.*;
import java.math.BigDecimal;
import java.time.LocalDate;
import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
/**
* 风险评估 DO
@@ -20,7 +20,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class RiskDO extends BaseDO {
+public class RiskDO extends TenantBaseDO {
/**
* 评估ID
@@ -121,4 +121,64 @@ public class RiskDO extends BaseDO {
*/
private String remark;
+ /**
+ * 风险评分
+ */
+ private Integer riskScore;
+
+ /**
+ * 风险描述
+ */
+ private String riskDescription;
+
+ /**
+ * 风险因素
+ */
+ private String riskFactors;
+
+ /**
+ * 建议措施
+ */
+ private String suggestions;
+
+ /**
+ * 评估人姓名
+ */
+ private String assessorName;
+
+ /**
+ * 状态:1-待评估 2-评估中 3-已完成 4-已取消
+ */
+ private Integer status;
+
+ // ========== 兼容方法 ==========
+
+ public void setPrisonerNo(String prisonerNo) {
+ this.prisonerCode = prisonerNo;
+ }
+
+ public void setRiskScore(Integer riskScore) {
+ this.riskScore = riskScore;
+ }
+
+ public void setRiskDescription(String riskDescription) {
+ this.riskDescription = riskDescription;
+ }
+
+ public void setRiskFactors(String riskFactors) {
+ this.riskFactors = riskFactors;
+ }
+
+ public void setSuggestions(String suggestions) {
+ this.suggestions = suggestions;
+ }
+
+ public void setAssessorName(String assessorName) {
+ this.assessorName = assessorName;
+ }
+
+ public void setStatus(Integer status) {
+ this.status = status;
+ }
+
}
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/riskassessment/RiskAssessmentDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/riskassessment/RiskAssessmentDO.java
index 5b4e683751..a7bfca1f18 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/riskassessment/RiskAssessmentDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/riskassessment/RiskAssessmentDO.java
@@ -6,7 +6,7 @@ import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
/**
* 危险评估 DO
@@ -21,7 +21,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class RiskAssessmentDO extends BaseDO {
+public class RiskAssessmentDO extends TenantBaseDO {
/**
* 评估ID
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/score/ScoreDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/score/ScoreDO.java
index 717a043a0b..e9a75df89c 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/score/ScoreDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/score/ScoreDO.java
@@ -9,7 +9,7 @@ import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
/**
* 计分考核 DO
@@ -24,7 +24,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class ScoreDO extends BaseDO {
+public class ScoreDO extends TenantBaseDO {
/**
* 记录ID
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/scorerecord/ScoreDetailDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/scorerecord/ScoreDetailDO.java
index 6990d6a0da..5c2f3fdd7c 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/scorerecord/ScoreDetailDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/scorerecord/ScoreDetailDO.java
@@ -5,7 +5,7 @@ import java.util.*;
import java.math.BigDecimal;
import java.time.LocalDate;
import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
/**
* 考核记录明细 DO
@@ -20,7 +20,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class ScoreDetailDO extends BaseDO {
+public class ScoreDetailDO extends TenantBaseDO {
/**
* 记录ID
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/scorerule/ScoreRuleDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/scorerule/ScoreRuleDO.java
index 8d7e02ff5b..31c8730c27 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/scorerule/ScoreRuleDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/scorerule/ScoreRuleDO.java
@@ -4,7 +4,7 @@ import lombok.*;
import java.util.*;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
/**
* 考核规则配置 DO
@@ -19,7 +19,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class ScoreRuleDO extends BaseDO {
+public class ScoreRuleDO extends TenantBaseDO {
/**
* 规则ID
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/situation/SituationDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/situation/SituationDO.java
index a507145e0c..282698acb9 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/situation/SituationDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/situation/SituationDO.java
@@ -4,7 +4,7 @@ import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.TableField;
/**
@@ -20,7 +20,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class SituationDO extends BaseDO {
+public class SituationDO extends TenantBaseDO {
/**
* 狱情ID
@@ -104,4 +104,14 @@ public class SituationDO extends BaseDO {
*/
private LocalDateTime occurTime;
+ /**
+ * 类型
+ */
+ private String type;
+
+ /**
+ * 地点
+ */
+ private String location;
+
}
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/warning/WarningDO.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/warning/WarningDO.java
index 6d79843583..85523bfd91 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/warning/WarningDO.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/dataobject/warning/WarningDO.java
@@ -4,7 +4,7 @@ import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.TableField;
/**
@@ -20,7 +20,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
@Builder
@NoArgsConstructor
@AllArgsConstructor
-public class WarningDO extends BaseDO {
+public class WarningDO extends TenantBaseDO {
/**
* 预警ID
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/mysql/PrisonerMapper.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/mysql/PrisonerMapper.java
index 20b8239f2d..0213bd41ad 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/mysql/PrisonerMapper.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/dal/mysql/PrisonerMapper.java
@@ -13,6 +13,14 @@ import org.apache.ibatis.annotations.Param;
@Mapper
public interface PrisonerMapper extends BaseMapperX {
+ /**
+ * 根据罪犯编号查询
+ *
+ * @param prisonerNo 罪犯编号
+ * @return 服刑人员信息
+ */
+ PrisonerDO selectByPrisonerNo(@Param("prisonerNo") String prisonerNo);
+
/**
* 统计某监区(含子监区)下的罪犯数量
*
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/service/consumption/ConsumptionServiceImpl.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/service/consumption/ConsumptionServiceImpl.java
index 87e3cef469..48d9962dfe 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/service/consumption/ConsumptionServiceImpl.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/service/consumption/ConsumptionServiceImpl.java
@@ -186,6 +186,7 @@ public class ConsumptionServiceImpl implements ConsumptionService {
// 3. 创建消费记录
ConsumptionDO consumption = new ConsumptionDO();
consumption.setPrisonerId(prisoner.getId());
+ consumption.setPrisonerNo(prisoner.getPrisonerNo());
consumption.setOrderNo(generateOrderNo());
consumption.setType(importVO.getType());
consumption.setTotalAmount(importVO.getTotalAmount());
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/service/dashboard/PrisonDashboardService.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/service/dashboard/PrisonDashboardService.java
index 20cb733ddb..e645ae410c 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/service/dashboard/PrisonDashboardService.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/service/dashboard/PrisonDashboardService.java
@@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.prison.service.dashboard;
-import cn.iocoder.yudao.module.prison.controller.admin.dashboard.vo.DashboardStatisticsVO;
-import cn.iocoder.yudao.module.prison.controller.admin.dashboard.vo.PrisonerDashboardStatsRespVO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.prison.controller.admin.dashboard.vo.*;
/**
* 监管看板 Service 接口
@@ -25,4 +25,19 @@ public interface PrisonDashboardService {
*/
PrisonerDashboardStatsRespVO getPrisonerStats(Long prisonerId);
+ /**
+ * 获取AI心航360°统计数据
+ *
+ * @return AI心航360°统计数据
+ */
+ AiDashEntryStatisticsVO getAiDashEntryStatistics();
+
+ /**
+ * 获取重点关注对象分页列表
+ *
+ * @param reqVO 分页请求参数
+ * @return 重点关注对象分页列表
+ */
+ PageResult getFocusPersonPage(FocusPersonPageReqVO reqVO);
+
}
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/service/dashboard/impl/PrisonDashboardServiceImpl.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/service/dashboard/impl/PrisonDashboardServiceImpl.java
index 56fe9122de..e75c7bad9e 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/service/dashboard/impl/PrisonDashboardServiceImpl.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/service/dashboard/impl/PrisonDashboardServiceImpl.java
@@ -1,23 +1,43 @@
package cn.iocoder.yudao.module.prison.service.dashboard.impl;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.prison.controller.admin.dashboard.vo.*;
import cn.iocoder.yudao.module.prison.dal.dataobject.PrisonerDO;
+import cn.iocoder.yudao.module.prison.dal.dataobject.area.AreaDO;
+import cn.iocoder.yudao.module.prison.dal.dataobject.consumption.ConsumptionDO;
+import cn.iocoder.yudao.module.prison.dal.dataobject.evaluationreport.EvaluationReportDO;
+import cn.iocoder.yudao.module.prison.dal.dataobject.riskassessment.RiskAssessmentDO;
+import cn.iocoder.yudao.module.prison.dal.dataobject.score.ScoreDO;
+import cn.iocoder.yudao.module.prison.dal.dataobject.situation.SituationDO;
import cn.iocoder.yudao.module.prison.dal.mysql.dashboard.PrisonDashboardMapper;
import cn.iocoder.yudao.module.prison.dal.mysql.PrisonerMapper;
+import cn.iocoder.yudao.module.prison.dal.mysql.area.AreaMapper;
+import cn.iocoder.yudao.module.prison.dal.mysql.consumption.ConsumptionMapper;
+import cn.iocoder.yudao.module.prison.dal.mysql.evaluationreport.EvaluationReportMapper;
+import cn.iocoder.yudao.module.prison.dal.mysql.riskassessment.RiskAssessmentMapper;
+import cn.iocoder.yudao.module.prison.dal.mysql.score.ScoreMapper;
+import cn.iocoder.yudao.module.prison.dal.mysql.situation.SituationMapper;
+import cn.iocoder.yudao.module.prison.enums.GenderEnum;
import cn.iocoder.yudao.module.prison.service.dashboard.PrisonDashboardService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
+import java.time.LocalDateTime;
import java.time.Period;
+import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import java.util.stream.Collectors;
/**
* 监管看板 Service 实现
@@ -31,6 +51,12 @@ public class PrisonDashboardServiceImpl implements PrisonDashboardService {
private final PrisonDashboardMapper dashboardMapper;
private final PrisonerMapper prisonerMapper;
+ private final ConsumptionMapper consumptionMapper;
+ private final ScoreMapper scoreMapper;
+ private final RiskAssessmentMapper riskAssessmentMapper;
+ private final SituationMapper situationMapper;
+ private final AreaMapper areaMapper;
+ private final EvaluationReportMapper evaluationReportMapper;
private static final String CACHE_KEY = "prison:dashboard:statistics";
@@ -163,8 +189,9 @@ public class PrisonDashboardServiceImpl implements PrisonDashboardService {
vo.setPrisonerName(prisoner.getName());
vo.setPrisonerNo(prisoner.getPrisonerNo());
vo.setNativePlace(prisoner.getNativePlace());
- vo.setEducation(prisoner.getEducation());
- vo.setMaritalStatus(prisoner.getMaritalStatus());
+ vo.setEducation(prisoner.getEducation() != null ? prisoner.getEducation().getName() : null);
+ vo.setMaritalStatus(prisoner.getMaritalStatus() != null ? String.valueOf(prisoner.getMaritalStatus()) : null);
+ vo.setChildren(prisoner.getChildren());
vo.setCrimeType(prisoner.getCrimeType());
vo.setSentence(prisoner.getSentence());
@@ -186,50 +213,532 @@ public class PrisonDashboardServiceImpl implements PrisonDashboardService {
// 监区信息(简单拼接)
vo.setPrisonArea(prisoner.getAreaId() != null ? "监区" + prisoner.getAreaId() : "未分配");
- // 默认风险等级
- vo.setRiskScore(0);
- vo.setRiskLevel(1);
+ // ==================== 查询关联数据 ====================
- // 构建中心数据(使用默认值)
+ // 1. 查询最新危险评估
+ RiskAssessmentDO latestAssessment = riskAssessmentMapper.selectOne(new LambdaQueryWrapper()
+ .eq(RiskAssessmentDO::getPrisonerId, prisonerId)
+ .eq(RiskAssessmentDO::getStatus, 1)
+ .orderByDesc(RiskAssessmentDO::getAssessmentDate)
+ .last("LIMIT 1"));
+ if (latestAssessment != null) {
+ vo.setRiskScore(latestAssessment.getTotalScore() != null ? latestAssessment.getTotalScore().intValue() : 0);
+ vo.setRiskLevel(latestAssessment.getRiskLevel() != null ? latestAssessment.getRiskLevel() : 1);
+ }
+
+ // 2. 查询本月消费数据
+ LocalDate now = LocalDate.now();
+ int currentYear = now.getYear();
+ int currentMonth = now.getMonthValue();
+ List monthlyConsumptions = consumptionMapper.selectList(new LambdaQueryWrapper()
+ .eq(ConsumptionDO::getPrisonerId, prisonerId)
+ .eq(ConsumptionDO::getStatus, 1)
+ .eq(ConsumptionDO::getType, 1) // 消费类型
+ .apply("YEAR(trade_time) = {0} AND MONTH(trade_time) = {1}", currentYear, currentMonth)
+ .orderByDesc(ConsumptionDO::getTradeTime));
+
+ // 计算本月消费总额
+ double monthlyTotal = monthlyConsumptions.stream()
+ .mapToDouble(c -> c.getTotalAmount() != null ? c.getTotalAmount().doubleValue() : 0)
+ .sum();
+
+ // 获取最新余额
+ Double latestBalance = null;
+ if (!monthlyConsumptions.isEmpty() && monthlyConsumptions.get(0).getBalance() != null) {
+ latestBalance = monthlyConsumptions.get(0).getBalance().doubleValue();
+ }
+ if (latestBalance == null) {
+ ConsumptionDO latestConsumption = consumptionMapper.selectOne(new LambdaQueryWrapper()
+ .eq(ConsumptionDO::getPrisonerId, prisonerId)
+ .eq(ConsumptionDO::getStatus, 1)
+ .orderByDesc(ConsumptionDO::getTradeTime)
+ .last("LIMIT 1"));
+ if (latestConsumption != null && latestConsumption.getBalance() != null) {
+ latestBalance = latestConsumption.getBalance().doubleValue();
+ }
+ }
+
+ // 3. 查询本月计分考核
+ List monthlyScores = scoreMapper.selectList(new LambdaQueryWrapper()
+ .eq(ScoreDO::getPrisonerId, prisonerId)
+ .eq(ScoreDO::getStatus, 1)
+ .eq(ScoreDO::getYear, currentYear)
+ .eq(ScoreDO::getMonth, currentMonth)
+ .last("LIMIT 1"));
+
+ ScoreDO currentMonthScore = monthlyScores.isEmpty() ? null : monthlyScores.get(0);
+
+ // 4. 查询最近6个月的计分考核记录
+ List recentScores = scoreMapper.selectList(new LambdaQueryWrapper()
+ .eq(ScoreDO::getPrisonerId, prisonerId)
+ .eq(ScoreDO::getStatus, 1)
+ .orderByDesc(ScoreDO::getYear)
+ .orderByDesc(ScoreDO::getMonth)
+ .last("LIMIT 6"));
+
+ // 5. 查询最近6个月消费记录
+ List recentConsumptions = consumptionMapper.selectList(new LambdaQueryWrapper()
+ .eq(ConsumptionDO::getPrisonerId, prisonerId)
+ .eq(ConsumptionDO::getStatus, 1)
+ .orderByDesc(ConsumptionDO::getTradeTime)
+ .last("LIMIT 20"));
+
+ // 6. 查询最近6个月的危险评估
+ List recentAssessments = riskAssessmentMapper.selectList(new LambdaQueryWrapper()
+ .eq(RiskAssessmentDO::getPrisonerId, prisonerId)
+ .eq(RiskAssessmentDO::getStatus, 1)
+ .orderByDesc(RiskAssessmentDO::getAssessmentDate)
+ .last("LIMIT 6"));
+
+ // 7. 查询狱情收集(心理访谈记录),按监区查询
+ List situations = situationMapper.selectList(new LambdaQueryWrapper()
+ .eq(SituationDO::getAreaId, prisoner.getAreaId())
+ .eq(SituationDO::getStatus, 3) // 已处理
+ .eq(SituationDO::getCategory, 2) // 教育改造类型
+ .orderByDesc(SituationDO::getOccurTime)
+ .last("LIMIT 10"));
+
+ // ==================== 构建中心数据 ====================
+
+ // 左侧数据:本月消费、奖励、惩罚、余额
+ double monthlyReward = 0;
+ double monthlyPenalty = 0;
+ if (currentMonthScore != null) {
+ monthlyReward = currentMonthScore.getRewardScore() != null ? currentMonthScore.getRewardScore().doubleValue() : 0;
+ monthlyPenalty = currentMonthScore.getPenaltyScore() != null ? currentMonthScore.getPenaltyScore().doubleValue() : 0;
+ }
vo.setCenterLeftData(PrisonerDashboardStatsRespVO.CenterLeftData.builder()
- .topValue("0")
+ .topValue(String.valueOf((int) monthlyTotal))
.topLabel("本月消费")
- .middleLeftValue("0")
+ .middleLeftValue(String.valueOf((int) monthlyReward))
.middleLeftLabel("本月奖励")
- .middleRightValue("0")
+ .middleRightValue(String.valueOf((int) monthlyPenalty))
.middleRightLabel("本月惩罚")
- .bottomValue("0")
+ .bottomValue(latestBalance != null ? String.valueOf(latestBalance.intValue()) : "0")
.bottomLabel("账户余额")
.build());
- vo.setCenterRightData(PrisonerDashboardStatsRespVO.CenterRightData.builder()
- .topValue("0")
- .topLabel("本月得分")
- .middleLeftValue("0")
- .middleLeftLabel("基础分")
- .middleRightValue("0")
- .middleRightLabel("加分项")
- .bottomLeftValue("0")
- .bottomLeftLabel("扣分项")
- .bottomRightValue("良好")
- .bottomRightLabel("考核等级")
- .build());
+ // 右侧数据:本月得分、基础分、加分项、扣分项、考核等级
+ String levelText = "良好";
+ if (currentMonthScore != null) {
+ if (currentMonthScore.getLevel() != null) {
+ levelText = switch (currentMonthScore.getLevel()) {
+ case 1 -> "优秀";
+ case 2 -> "良好";
+ case 3 -> "合格";
+ case 4 -> "不合格";
+ default -> "良好";
+ };
+ }
+ vo.setCenterRightData(PrisonerDashboardStatsRespVO.CenterRightData.builder()
+ .topValue(currentMonthScore.getTotalScore() != null ?
+ String.valueOf(currentMonthScore.getTotalScore().intValue()) : "0")
+ .topLabel("本月得分")
+ .middleLeftValue(currentMonthScore.getBaseScore() != null ?
+ String.valueOf(currentMonthScore.getBaseScore().intValue()) : "0")
+ .middleLeftLabel("基础分")
+ .middleRightValue(String.valueOf((int) monthlyReward))
+ .middleRightLabel("加分项")
+ .bottomLeftValue(String.valueOf((int) monthlyPenalty))
+ .bottomLeftLabel("扣分项")
+ .bottomRightValue(levelText)
+ .bottomRightLabel("考核等级")
+ .build());
+ } else {
+ vo.setCenterRightData(PrisonerDashboardStatsRespVO.CenterRightData.builder()
+ .topValue("0")
+ .topLabel("本月得分")
+ .middleLeftValue("0")
+ .middleLeftLabel("基础分")
+ .middleRightValue("0")
+ .middleRightLabel("加分项")
+ .bottomLeftValue("0")
+ .bottomLeftLabel("扣分项")
+ .bottomRightValue("暂无")
+ .bottomRightLabel("考核等级")
+ .build());
+ }
- // 初始化空列表
- vo.setConsumptionMonthlyData(new ArrayList<>());
+ // ==================== 构建消费月度数据 ====================
+ List monthlyDataList = new ArrayList<>();
+ // 按月份汇总消费
+ Map monthlyConsumptionMap = recentConsumptions.stream()
+ .filter(c -> c.getTradeTime() != null)
+ .collect(Collectors.groupingBy(
+ c -> c.getTradeTime().getYear() + "-" + String.format("%02d", c.getTradeTime().getMonthValue()),
+ Collectors.summingDouble(c -> c.getTotalAmount() != null ? c.getTotalAmount().doubleValue() : 0)
+ ));
+ for (Map.Entry entry : monthlyConsumptionMap.entrySet()) {
+ monthlyDataList.add(PrisonerDashboardStatsRespVO.MonthlyConsumptionData.builder()
+ .category(entry.getKey())
+ .perCapita(entry.getValue().intValue())
+ .build());
+ }
+ vo.setConsumptionMonthlyData(monthlyDataList);
+
+ // ==================== 构建计分考核记录 ====================
+ List scoreRecords = recentScores.stream()
+ .map(s -> {
+ String level = s.getLevel() != null ? switch (s.getLevel()) {
+ case 1 -> "优秀";
+ case 2 -> "良好";
+ case 3 -> "合格";
+ case 4 -> "不合格";
+ default -> "";
+ } : "";
+ return PrisonerDashboardStatsRespVO.ScoreRecord.builder()
+ .date(s.getYear() + "-" + String.format("%02d", s.getMonth()))
+ .score(s.getTotalScore() != null ? String.valueOf(s.getTotalScore().intValue()) : "0")
+ .scoreType(s.getRewardScore().doubleValue() > 0 ? "加分" : (s.getPenaltyScore().doubleValue() > 0 ? "扣分" : "正常"))
+ .finalScore(s.getTotalScore() != null ? s.getTotalScore().intValue() : 0)
+ .level(level)
+ .levelText(level)
+ .build();
+ })
+ .collect(Collectors.toList());
+ vo.setScoreRecords(scoreRecords);
+
+ // ==================== 构建消费记录 ====================
+ List consumptionRecords = recentConsumptions.stream()
+ .limit(10)
+ .map(c -> {
+ String typeName = c.getType() == 1 ? "消费" : "存款";
+ return PrisonerDashboardStatsRespVO.ConsumptionRecord.builder()
+ .date(c.getTradeTime() != null ? c.getTradeTime().toLocalDate().toString() : "")
+ .name(typeName)
+ .nameColor(c.getType() == 1 ? "#f56c6c" : "#67c23a")
+ .category("普通消费")
+ .amount(c.getTotalAmount() != null ? c.getTotalAmount().intValue() : 0)
+ .build();
+ })
+ .collect(Collectors.toList());
+ vo.setConsumptionRecords(consumptionRecords);
+
+ // ==================== 构建危险评估记录 ====================
+ List rewardsPunishments = recentAssessments.stream()
+ .map(a -> {
+ return PrisonerDashboardStatsRespVO.RewardsPunishment.builder()
+ .date(a.getAssessmentDate() != null ? a.getAssessmentDate().toString() : "")
+ .type("danger")
+ .typeText("危险评估")
+ .content("暴力倾向:" + (a.getViolenceScore() != null ? a.getViolenceScore() : 0) +
+ " | 脱逃倾向:" + (a.getEscapeScore() != null ? a.getEscapeScore() : 0) +
+ " | 自杀倾向:" + (a.getSuicideScore() != null ? a.getSuicideScore() : 0))
+ .build();
+ })
+ .collect(Collectors.toList());
+ vo.setRewardsPunishments(rewardsPunishments);
+
+ // ==================== 构建心理访谈记录 ====================
+ List interviewRecords = situations.stream()
+ .filter(s -> s.getCategory() == 1) // 只取心理访谈类型
+ .map(s -> PrisonerDashboardStatsRespVO.InterviewRecord.builder()
+ .date(s.getOccurTime() != null ? s.getOccurTime().toLocalDate().toString() : "")
+ .content(s.getContent() != null ? s.getContent() : s.getTitle())
+ .build())
+ .collect(Collectors.toList());
+ vo.setInterviewRecords(interviewRecords);
+
+ // ==================== 构建汇款记录 ====================
+ List remittanceRecords = recentConsumptions.stream()
+ .filter(c -> c.getType() == 2) // 存款类型
+ .limit(10)
+ .map(c -> PrisonerDashboardStatsRespVO.RemittanceRecord.builder()
+ .date(c.getTradeTime() != null ? c.getTradeTime().toLocalDate().toString() : "")
+ .name("存款")
+ .nameColor("#409eff")
+ .category("亲属汇款")
+ .amount(c.getTotalAmount() != null ? c.getTotalAmount().intValue() : 0)
+ .build())
+ .collect(Collectors.toList());
+ vo.setRemittanceRecords(remittanceRecords);
+
+ // ==================== 构建关系人信息(模拟数据) ====================
+ List relationships = new ArrayList<>();
+ relationships.add(PrisonerDashboardStatsRespVO.RelationshipInfo.builder()
+ .name("李四")
+ .relate("配偶")
+ .color("#909399")
+ .build());
+ relationships.add(PrisonerDashboardStatsRespVO.RelationshipInfo.builder()
+ .name("张父")
+ .relate("父亲")
+ .color("#909399")
+ .build());
+ vo.setRelationships(relationships);
+
+ // ==================== 消费汇总 ====================
vo.setConsumptionSummary(PrisonerDashboardStatsRespVO.ConsumptionSummary.builder()
.inProgress(0)
.toWarehouse(0)
.outWarehouse(0)
.build());
- vo.setInterviewRecords(new ArrayList<>());
- vo.setRewardsPunishments(new ArrayList<>());
- vo.setScoreRecords(new ArrayList<>());
- vo.setConsumptionRecords(new ArrayList<>());
- vo.setRemittanceRecords(new ArrayList<>());
- vo.setRelationships(new ArrayList<>());
return vo;
}
+ @Override
+ public AiDashEntryStatisticsVO getAiDashEntryStatistics() {
+ AiDashEntryStatisticsVO vo = new AiDashEntryStatisticsVO();
+ LocalDate now = LocalDate.now();
+ LocalDate firstDayOfMonth = now.withDayOfMonth(1);
+ LocalDate firstDayOfLastMonth = now.minusMonths(1).withDayOfMonth(1);
+
+ // 获取所有有心理评估的罪犯的最新评估记录
+ // 风险等级:1-低风险(普通) 2-中风险(预警) 3-高风险(高危) 4-极高风险(高危)
+ List allReports = evaluationReportMapper.selectList(new LambdaQueryWrapper()
+ .eq(EvaluationReportDO::getStatus, 3) // 已审核
+ .eq(EvaluationReportDO::getEvaluationType, 1) // 心理评估
+ .isNotNull(EvaluationReportDO::getRiskLevel)
+ .orderByDesc(EvaluationReportDO::getEvaluationDate));
+
+ // 按罪犯ID分组,取最新的评估记录
+ Map latestReportMap = allReports.stream()
+ .collect(Collectors.toMap(
+ EvaluationReportDO::getPrisonerId,
+ r -> r,
+ (existing, replacement) -> existing // 保留第一个(最新的)
+ ));
+ List latestReports = new ArrayList<>(latestReportMap.values());
+
+ // 统计各风险等级人数
+ int highRiskCount = 0; // 高危:3-高风险 4-极高风险
+ int warningCount = 0; // 预警:2-中风险
+ int normalCount = 0; // 普通:1-低风险
+
+ for (EvaluationReportDO report : latestReports) {
+ Integer riskLevel = report.getRiskLevel();
+ if (riskLevel == null) continue;
+ switch (riskLevel) {
+ case 3, 4 -> highRiskCount++;
+ case 2 -> warningCount++;
+ case 1 -> normalCount++;
+ }
+ }
+
+ int totalCount = highRiskCount + warningCount + normalCount;
+ vo.setTotalCount(totalCount);
+ vo.setHighRiskCount(highRiskCount);
+ vo.setWarningCount(warningCount);
+ vo.setNormalCount(normalCount);
+
+ // 本月新增统计
+ List thisMonthReports = allReports.stream()
+ .filter(r -> r.getEvaluationDate() != null && !r.getEvaluationDate().toLocalDate().isBefore(firstDayOfMonth))
+ .toList();
+
+ // 按罪犯ID分组,取本月第一次评估
+ Map thisMonthNewMap = thisMonthReports.stream()
+ .filter(r -> !latestReportMap.containsKey(r.getPrisonerId()) ||
+ latestReportMap.get(r.getPrisonerId()).getEvaluationDate().toLocalDate().isAfter(firstDayOfMonth.minusDays(1)))
+ .collect(Collectors.toMap(
+ EvaluationReportDO::getPrisonerId,
+ r -> r,
+ (existing, replacement) -> existing
+ ));
+
+ int monthlyNewHighRisk = 0, monthlyNewWarning = 0, monthlyNewNormal = 0;
+ for (EvaluationReportDO report : thisMonthNewMap.values()) {
+ Integer riskLevel = report.getRiskLevel();
+ if (riskLevel == null) continue;
+ switch (riskLevel) {
+ case 3, 4 -> monthlyNewHighRisk++;
+ case 2 -> monthlyNewWarning++;
+ case 1 -> monthlyNewNormal++;
+ }
+ }
+
+ int monthlyNewCount = monthlyNewHighRisk + monthlyNewWarning + monthlyNewNormal;
+ vo.setMonthlyNewCount(monthlyNewCount);
+ vo.setMonthlyChange(monthlyNewCount);
+ vo.setHighRiskMonthlyNew(monthlyNewHighRisk);
+ vo.setHighRiskMonthlyChange(monthlyNewHighRisk);
+ vo.setWarningMonthlyNew(monthlyNewWarning);
+ vo.setWarningMonthlyChange(monthlyNewWarning);
+ vo.setNormalMonthlyNew(monthlyNewNormal);
+ vo.setNormalMonthlyChange(monthlyNewNormal);
+
+ // 风险等级分布
+ List riskDistribution = new ArrayList<>();
+ riskDistribution.add(AiDashEntryStatisticsVO.RiskDistributionVO.builder()
+ .name("普通").value(normalCount).color("#5470c6").build());
+ riskDistribution.add(AiDashEntryStatisticsVO.RiskDistributionVO.builder()
+ .name("预警").value(warningCount).color("#fac858").build());
+ riskDistribution.add(AiDashEntryStatisticsVO.RiskDistributionVO.builder()
+ .name("高危").value(highRiskCount).color("#ee6666").build());
+ vo.setRiskDistribution(riskDistribution);
+
+ // 风险趋势数据(最近7个月)
+ List riskTrendData = new ArrayList<>();
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
+ for (int i = 6; i >= 0; i--) {
+ LocalDate month = now.minusMonths(i).withDayOfMonth(1);
+ LocalDate nextMonth = month.plusMonths(1);
+ String monthStr = month.format(formatter);
+
+ // 统计该月末时各风险等级的人数(取该月最后一条评估记录)
+ final LocalDate monthEnd = nextMonth.minusDays(1);
+ List monthEndReports = allReports.stream()
+ .filter(r -> r.getEvaluationDate() != null &&
+ !r.getEvaluationDate().toLocalDate().isAfter(monthEnd))
+ .toList();
+
+ Map monthEndLatestMap = monthEndReports.stream()
+ .collect(Collectors.toMap(
+ EvaluationReportDO::getPrisonerId,
+ r -> r,
+ (existing, replacement) -> existing
+ ));
+
+ int monthHigh = 0, monthWarning = 0, monthNormal = 0;
+ for (EvaluationReportDO report : monthEndLatestMap.values()) {
+ Integer riskLevel = report.getRiskLevel();
+ if (riskLevel == null) continue;
+ switch (riskLevel) {
+ case 3, 4 -> monthHigh++;
+ case 2 -> monthWarning++;
+ case 1 -> monthNormal++;
+ }
+ }
+
+ riskTrendData.add(AiDashEntryStatisticsVO.RiskTrendVO.builder()
+ .month(monthStr)
+ .highRisk(monthHigh)
+ .warning(monthWarning)
+ .normal(monthNormal)
+ .build());
+ }
+ vo.setRiskTrendData(riskTrendData);
+
+ return vo;
+ }
+
+ @Override
+ public PageResult getFocusPersonPage(FocusPersonPageReqVO reqVO) {
+ // 查询有心理评估的罪犯列表
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper()
+ .eq(EvaluationReportDO::getStatus, 3) // 已审核
+ .eq(EvaluationReportDO::getEvaluationType, 1) // 心理评估
+ .isNotNull(EvaluationReportDO::getRiskLevel);
+
+ // 根据风险类型过滤
+ if (StringUtils.hasText(reqVO.getRiskLevelType())) {
+ switch (reqVO.getRiskLevelType()) {
+ case "high" -> wrapper.in(EvaluationReportDO::getRiskLevel, 3, 4);
+ case "warning" -> wrapper.eq(EvaluationReportDO::getRiskLevel, 2);
+ case "normal" -> wrapper.eq(EvaluationReportDO::getRiskLevel, 1);
+ }
+ }
+
+ if (StringUtils.hasText(reqVO.getName())) {
+ wrapper.like(EvaluationReportDO::getPrisonerName, reqVO.getName());
+ }
+
+ if (reqVO.getAreaId() != null) {
+ wrapper.eq(EvaluationReportDO::getAreaId, reqVO.getAreaId());
+ }
+
+ wrapper.orderByDesc(EvaluationReportDO::getEvaluationDate);
+
+ // 获取所有符合条件的记录
+ List allReports = evaluationReportMapper.selectList(wrapper);
+
+ // 按罪犯ID去重,保留最新的评估记录
+ Map latestReportMap = allReports.stream()
+ .collect(Collectors.toMap(
+ EvaluationReportDO::getPrisonerId,
+ r -> r,
+ (existing, replacement) -> existing
+ ));
+ List uniqueReports = new ArrayList<>(latestReportMap.values());
+
+ // 手动分页
+ int total = uniqueReports.size();
+ int start = (reqVO.getPageNo() - 1) * reqVO.getPageSize();
+ int end = Math.min(start + reqVO.getPageSize(), total);
+ List pagedReports = start < total ? uniqueReports.subList(start, end) : new ArrayList<>();
+
+ // 获取罪犯详细信息
+ List prisonerIds = pagedReports.stream()
+ .map(EvaluationReportDO::getPrisonerId)
+ .toList();
+ Map prisonerMap = prisonerIds.isEmpty() ? Map.of() :
+ prisonerMapper.selectBatchIds(prisonerIds).stream()
+ .collect(Collectors.toMap(PrisonerDO::getId, p -> p));
+
+ // 获取监区信息
+ List areaIds = pagedReports.stream()
+ .map(EvaluationReportDO::getAreaId)
+ .filter(id -> id != null)
+ .distinct()
+ .toList();
+ Map areaMap = areaIds.isEmpty() ? Map.of() :
+ areaMapper.selectBatchIds(areaIds).stream()
+ .collect(Collectors.toMap(AreaDO::getId, a -> a));
+
+ // 判断本月新增
+ LocalDate firstDayOfMonth = LocalDate.now().withDayOfMonth(1);
+
+ // 转换为 VO
+ List voList = pagedReports.stream()
+ .map(report -> {
+ PrisonerDO prisoner = prisonerMap.get(report.getPrisonerId());
+ String riskLevelType = switch (report.getRiskLevel()) {
+ case 3, 4 -> "high";
+ case 2 -> "warning";
+ default -> "normal";
+ };
+ String riskLevelText = switch (report.getRiskLevel()) {
+ case 4 -> "极高危";
+ case 3 -> "高危";
+ case 2 -> "预警";
+ default -> "普通";
+ };
+ String psychLevel = switch (report.getRiskLevel()) {
+ case 4 -> "一级风险";
+ case 3 -> "一级风险";
+ case 2 -> "二级风险";
+ default -> "三级风险";
+ };
+
+ // 判断是否本月新增
+ boolean isNew = report.getEvaluationDate() != null &&
+ !report.getEvaluationDate().toLocalDate().isBefore(firstDayOfMonth);
+
+ // 获取监区名称
+ String areaName = report.getAreaName();
+ if (!StringUtils.hasText(areaName) && report.getAreaId() != null) {
+ AreaDO area = areaMap.get(report.getAreaId());
+ areaName = area != null ? area.getName() : "未分配";
+ }
+
+ // 计算年龄
+ Integer age = null;
+ if (prisoner != null && prisoner.getBirthDate() != null) {
+ age = Period.between(prisoner.getBirthDate(), LocalDate.now()).getYears();
+ }
+
+ // 获取性别
+ String gender = "未知";
+ if (prisoner != null && prisoner.getGender() != null) {
+ gender = GenderEnum.MALE.getValue().equals(prisoner.getGender().getValue()) ? "男" : "女";
+ }
+
+ return FocusPersonVO.builder()
+ .id(report.getPrisonerId())
+ .name(report.getPrisonerName())
+ .gender(gender)
+ .age(age)
+ .riskLevelType(riskLevelType)
+ .riskLevel(riskLevelText)
+ .supervisionArea(areaName)
+ .psychologicalRiskLevel(psychLevel)
+ .isNew(isNew)
+ .build();
+ })
+ .toList();
+
+ return new PageResult<>(voList, (long) total);
+ }
+
}
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/service/risk/impl/RiskServiceImpl.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/service/risk/impl/RiskServiceImpl.java
index 30a98073a4..f04a4ab4a0 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/service/risk/impl/RiskServiceImpl.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/service/risk/impl/RiskServiceImpl.java
@@ -117,7 +117,8 @@ public class RiskServiceImpl implements RiskService {
RiskDO risk = new RiskDO();
risk.setPrisonerId(prisoner.getId());
risk.setPrisonerNo(prisoner.getPrisonerNo());
- risk.setRiskScore(importVO.getRiskScore() != null ? importVO.getRiskScore() : BigDecimal.ZERO);
+ risk.setPrisonerName(prisoner.getName()); // 设置罪犯姓名
+ risk.setRiskScore(importVO.getRiskScore() != null ? importVO.getRiskScore().intValue() : 0);
risk.setRiskLevel(importVO.getRiskLevel());
risk.setRiskDescription(importVO.getRiskDescription());
risk.setRiskFactors(importVO.getRiskFactors());
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/service/score/ScoreServiceImpl.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/service/score/ScoreServiceImpl.java
index 5d2eb39f92..f52b2c6a48 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/service/score/ScoreServiceImpl.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/service/score/ScoreServiceImpl.java
@@ -146,6 +146,7 @@ public class ScoreServiceImpl implements ScoreService {
ScoreDO score = new ScoreDO();
score.setPrisonerId(prisoner.getId());
+ score.setPrisonerNo(prisoner.getPrisonerNo());
score.setPrisonAreaId(prisoner.getPrisonAreaId());
score.setPrisonCellId(prisoner.getPrisonCellId());
score.setYear(importVO.getYear());
diff --git a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/service/situation/impl/SituationServiceImpl.java b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/service/situation/impl/SituationServiceImpl.java
index f311126fe3..4dc9dda659 100644
--- a/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/service/situation/impl/SituationServiceImpl.java
+++ b/yudao-module-prison/src/main/java/cn/iocoder/yudao/module/prison/service/situation/impl/SituationServiceImpl.java
@@ -119,7 +119,7 @@ public class SituationServiceImpl implements SituationService {
SituationDO situation = new SituationDO();
situation.setTitle(importVO.getTitle());
- situation.setType(importVO.getType());
+ situation.setType(importVO.getType() != null ? String.valueOf(importVO.getType()) : null);
situation.setLevel(importVO.getLevel());
situation.setContent(importVO.getContent());
situation.setLocation(importVO.getLocation());
diff --git a/yudao-module-prison/src/main/resources/mapper/PrisonerMapper.xml b/yudao-module-prison/src/main/resources/mapper/PrisonerMapper.xml
index 864fd82886..daec21b08e 100644
--- a/yudao-module-prison/src/main/resources/mapper/PrisonerMapper.xml
+++ b/yudao-module-prison/src/main/resources/mapper/PrisonerMapper.xml
@@ -34,6 +34,9 @@
+
+
+
@@ -65,4 +68,13 @@
AND prison_area_id = #{areaId}
+
+
+
diff --git a/yudao-module-prison/src/main/resources/sql/menu_ai_dash_entry.sql b/yudao-module-prison/src/main/resources/sql/menu_ai_dash_entry.sql
new file mode 100644
index 0000000000..9df60085ff
--- /dev/null
+++ b/yudao-module-prison/src/main/resources/sql/menu_ai_dash_entry.sql
@@ -0,0 +1,36 @@
+-- 菜单 SQL - AI心航360°
+-- 请根据实际的父菜单ID调整 parent_id
+
+-- 菜单: AI心航360° (类型: 菜单)
+INSERT INTO system_menu(
+ name, permission, type, sort, parent_id,
+ path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted
+)
+VALUES (
+ 'AI心航360°', '', 2, 0, 0,
+ 'ai-dash-entry', 'ep:data-analysis', 'views/DashEntry/DashEntry', 'AiDashEntry',
+ 0, true, true, true, '1', NOW(), '1', NOW(), '0'
+);
+
+-- 获取刚插入的菜单ID
+SET @menuId = LAST_INSERT_ID();
+
+-- 按钮: 查询 (类型: 按钮)
+INSERT INTO system_menu(
+ name, permission, type, sort, parent_id,
+ path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted
+)
+VALUES (
+ '查询', 'prison:ai-dash-entry:query', 3, 1, @menuId,
+ '', '', '', NULL, 0, true, true, true, '1', NOW(), '1', NOW(), '0'
+);
+
+-- 如果需要将菜单放到监狱管理下面,请执行以下SQL更新parent_id
+-- 假设监狱管理的菜单ID是2600,请根据实际情况调整
+-- UPDATE system_menu SET parent_id = 2600 WHERE id = @menuId;
+
+-- =====================================================
+-- 如果你的系统使用租户,还需要插入 system_tenant_menu
+-- =====================================================
+-- INSERT INTO system_tenant_menu(tenant_id, menu_id) VALUES (1, @menuId);
+-- INSERT INTO system_tenant_menu(tenant_id, menu_id) VALUES (1, @menuId + 1);
diff --git a/yudao-module-prison/src/main/resources/sql/prison_module.sql b/yudao-module-prison/src/main/resources/sql/prison_module.sql
index a27aa94347..5892bf5a7a 100644
--- a/yudao-module-prison/src/main/resources/sql/prison_module.sql
+++ b/yudao-module-prison/src/main/resources/sql/prison_module.sql
@@ -370,11 +370,18 @@ INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, co
VALUES ('狱情收集导出', 'prison:situation:export', 3, 5, @situationParentId, '', '', '', 0);
-- =====================================================
--- 10. 数据结构迁移 SQL (2026-01-14)
+-- 10. 数据结构迁移 SQL (2026-01-20)
-- =====================================================
--- 移除 prison_prisoner 表中的 sub_area_id 字段
+-- 补充 prison_prisoner 表缺失字段
-- 执行此迁移前请备份数据库
-ALTER TABLE `prison_prisoner` DROP COLUMN IF EXISTS `sub_area_id`;
+ALTER TABLE `prison_prisoner`
+ ADD COLUMN IF NOT EXISTS `release_type` tinyint DEFAULT 0 COMMENT '释放类型:0-未知 1-刑满释放 2-假释 3-保外就医 4-减刑 5-暂予监外执行 6-特赦 7-死亡 8-其他',
+ ADD COLUMN IF NOT EXISTS `release_reason` varchar(500) DEFAULT NULL COMMENT '释放原因',
+ ADD COLUMN IF NOT EXISTS `photo` varchar(512) DEFAULT NULL COMMENT '照片URL',
+ ADD COLUMN IF NOT EXISTS `sub_area_id` bigint DEFAULT NULL COMMENT '分区ID',
+ ADD COLUMN IF NOT EXISTS `marital_status` tinyint DEFAULT NULL COMMENT '婚姻状态:1-未婚 2-已婚 3-离异 4-丧偶',
+ ADD COLUMN IF NOT EXISTS `crime_type` varchar(100) DEFAULT NULL COMMENT '罪名类型',
+ ADD COLUMN IF NOT EXISTS `sentence` varchar(100) DEFAULT NULL COMMENT '刑期';
-- =====================================================
-- 10. 字典数据 SQL
diff --git a/yudao-module-prison/src/main/resources/sql/upgrade_prison_situation_add_location_20260120.sql b/yudao-module-prison/src/main/resources/sql/upgrade_prison_situation_add_location_20260120.sql
new file mode 100644
index 0000000000..8836530504
--- /dev/null
+++ b/yudao-module-prison/src/main/resources/sql/upgrade_prison_situation_add_location_20260120.sql
@@ -0,0 +1,12 @@
+-- =====================================================
+-- 升级脚本:添加 prison_situation 表的 location 字段
+-- 执行时间:2026-01-20
+-- 原因:SituationDO 实体类有 location 字段,但数据库表缺少该字段
+-- =====================================================
+
+-- 添加 location 字段(地点)
+ALTER TABLE `prison_situation`
+ADD COLUMN `location` varchar(200) DEFAULT NULL COMMENT '地点' AFTER `occur_time`;
+
+-- 验证字段是否添加成功
+-- SELECT `location` FROM `prison_situation` LIMIT 1;
diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/mq/producer/mail/MailProducer.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/mq/producer/mail/MailProducer.java
old mode 100644
new mode 100755
diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/mq/producer/sms/SmsProducer.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/mq/producer/sms/SmsProducer.java
old mode 100644
new mode 100755