# XL监狱综合管理平台 - 监区犯人管理改造设计方案 > 文档版本:v2.0 > 创建日期:2026-01-14 > 状态:待实施 > 评审专家:监狱业务专家 --- ## 一、背景说明 ### 1.1 项目概述 XL监狱综合管理平台是面向监狱管理的信息化系统,基于芋道源码(yudao-boot-mini)进行二次开发,实现罪犯管理、教育改造、考核评估等业务的规范化、智能化。 ### 1.2 文档目的 本设计文档用于指导系统改造,主要解决以下问题: 1. 监区层级关系缺失(扁平结构改为树形结构) 2. 核心业务流程不完整(出监/移交/调监) 3. 考核评估功能不完善 4. 数据联动逻辑缺失 --- ## 二、现状问题分析 ### 2.1 监区管理问题 | 问题 | 现状 | 影响 | |-----|------|------| | 层级缺失 | 监区为扁平结构,无父子关系 | 无法表达"监区→分监区"层级 | | 人数不同步 | current_count 为手动维护字段 | 数据不一致风险 | | 特殊监区混淆 | 用 type 区分"医院/禁闭室" | 与普通监区并列不合理 | ### 2.2 服刑人员管理问题 | 问题 | 现状 | 影响 | |-----|------|------| | 出监功能缺失 | 无释放/移交登记功能 | 业务流程不闭环 | | 调监无记录 | 虽有 prisoner_area_log 表但无功能 | 位置变更无法追溯 | | 释放无预警 | 临近释放无提醒机制 | 可能漏放 | ### 2.3 计分考核问题 | 问题 | 现状 | 影响 | |-----|------|------| | 规则未配置 | 无考核规则配置功能 | 考核标准不统一 | | 自动计算缺失 | 月度汇总需手动计算 | 工作量大、易出错 | | 公示功能缺失 | 无考核结果公示模块 | 透明度不足 | --- ## 三、监区层级设计方案 ### 3.1 中国监狱组织架构参考 ``` ┌─────────────────────────────────────────────────────────┐ │ 监狱(行政单位) │ ├─────────────────────────────────────────────────────────┤ │ 职能科室:办公室、政治处、刑罚执行科、狱政管理科、教育改造科等 │ ├─────────────────────────────────────────────────────────┤ │ 监区(大队) │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ 一监区 │ │ 二监区 │ │ 医院监区│ │ 禁闭室 │ │ │ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │一分监区 │ │二分监区 │ │ 医疗区 │ │ 禁闭室 │ │ │ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ │ │ ┌─────────────────────────────────────────────┐ │ │ │ 监室(101、102、201...) │ │ │ └─────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────┘ ``` ### 3.2 数据结构设计 #### 3.2.1 监区信息表(改造) ```sql -- 改造后的 prison_area 表 CREATE TABLE IF NOT EXISTS `prison_area` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '监区ID', `name` varchar(100) NOT NULL COMMENT '监区名称', `code` varchar(50) NOT NULL COMMENT '监区编码(唯一)', `parent_id` bigint NOT NULL DEFAULT 0 COMMENT '父级ID,0表示顶级监区', `level` tinyint NOT NULL DEFAULT 1 COMMENT '级别:1-监区(大队) 2-分监区(中队)', `type` tinyint NOT NULL DEFAULT 1 COMMENT '类型:1-普通 2-严管 3-集训 4-出监 5-医院 6-禁闭室', `capacity` int NOT NULL DEFAULT 0 COMMENT '容纳人数', `current_count` int NOT NULL DEFAULT 0 COMMENT '当前人数(自动计算)', `sort` int NOT NULL DEFAULT 0 COMMENT '排序', `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态:1-启用 2-禁用', `remark` varchar(500) DEFAULT NULL COMMENT '备注', `creator` varchar(64) DEFAULT '' COMMENT '创建者', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updater` varchar(64) DEFAULT '' COMMENT '更新者', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`), UNIQUE KEY `uk_code` (`code`), KEY `idx_parent_id` (`parent_id`), KEY `idx_level` (`level`), KEY `idx_type` (`type`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='监区信息表'; ``` **字段变更说明**: | 字段 | 原设计 | 新设计 | 说明 | |-----|-------|-------|------| | parent_id | 无 | 新增 | 父级ID,支持树形结构 | | level | 无 | 新增 | 区分监区/分监区 | | type | 1-普通 2-严管 3-医院 4-禁闭 | 1-普通 2-严管 3-集训 4-出监 5-医院 6-禁闭 | 细化特殊监区类型 | #### 3.2.2 监室信息表(改造) ```sql -- 改造后的 prison_cell 表(无变更,关联分监区) CREATE TABLE IF NOT EXISTS `prison_cell` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '监室ID', `area_id` bigint NOT NULL COMMENT '所属监区ID(关联分监区,即 level=2 的记录)', `name` varchar(100) NOT NULL COMMENT '监室名称', `code` varchar(50) NOT NULL COMMENT '监室编码(唯一)', `bed_count` int NOT NULL DEFAULT 0 COMMENT '床位数量', `current_count` int NOT NULL DEFAULT 0 COMMENT '当前人数', `sort` int NOT NULL DEFAULT 0 COMMENT '排序', `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态:1-启用 2-禁用', `remark` varchar(500) DEFAULT NULL COMMENT '备注', `creator` varchar(64) DEFAULT '' COMMENT '创建者', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updater` varchar(64) DEFAULT '' COMMENT '更新者', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`), UNIQUE KEY `uk_code` (`code`), KEY `idx_area_id` (`area_id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='监室信息表'; ``` **说明**:监室关联的是分监区(level=2),通过分监区的 parent_id 可追溯到监区。 #### 3.2.3 服刑人员表(补充字段) ```sql -- prison_prisoner 表需要补充的字段 ALTER TABLE `prison_prisoner` ADD COLUMN `photo` varchar(500) DEFAULT NULL COMMENT '照片URL' AFTER `idCard`, ADD COLUMN `release_type` tinyint DEFAULT NULL COMMENT '释放类型:1-刑满 2-假释 3-暂予监外执行 4-减刑 5-移交 6-死亡' AFTER `releaseDate`, ADD COLUMN `release_reason` varchar(500) DEFAULT NULL COMMENT '释放原因' AFTER `release_type`; ``` #### 3.2.4 新增:罪犯区域变动记录表 ```sql -- 新增:罪犯区域变动记录表(用于调监追溯) CREATE TABLE IF NOT EXISTS `prison_prisoner_area_log` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '记录ID', `prisoner_id` bigint NOT NULL COMMENT '罪犯ID', `prisoner_no` varchar(50) NOT NULL COMMENT '罪犯编号', `from_area_id` bigint DEFAULT NULL COMMENT '原监区ID', `from_cell_id` bigint DEFAULT NULL COMMENT '原监室ID', `to_area_id` bigint NOT NULL COMMENT '新监区ID', `to_cell_id` bigint NOT NULL COMMENT '新监室ID', `change_type` tinyint NOT NULL COMMENT '变动类型:1-入监分配 2-调监 3-出监 4-移交转入 5-移交转出', `change_reason` varchar(500) DEFAULT NULL COMMENT '变动原因', `operator_id` bigint DEFAULT NULL COMMENT '操作人ID', `operator_name` varchar(50) DEFAULT NULL COMMENT '操作人姓名', `operate_time` datetime NOT NULL COMMENT '操作时间', `creator` varchar(64) DEFAULT '' COMMENT '创建者', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`), KEY `idx_prisoner_id` (`prisoner_id`), KEY `idx_prisoner_no` (`prisoner_no`), KEY `idx_operate_time` (`operate_time`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='罪犯区域变动记录表'; ``` #### 3.2.5 新增:释放登记记录表 ```sql -- 新增:释放登记记录表 CREATE TABLE IF NOT EXISTS `prison_prisoner_release` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '记录ID', `prisoner_id` bigint NOT NULL COMMENT '罪犯ID', `prisoner_no` varchar(50) NOT NULL COMMENT '罪犯编号', `prisoner_name` varchar(50) NOT NULL COMMENT '罪犯姓名', `release_type` tinyint NOT NULL COMMENT '释放类型:1-刑满释放 2-假释 3-暂予监外执行 4-减刑 5-法院裁定释放 6-死亡 7-其他', `release_reason` varchar(500) DEFAULT NULL COMMENT '释放原因', `court_name` varchar(100) DEFAULT NULL COMMENT '裁定法院(假释/减刑时)', `judgment_no` varchar(50) DEFAULT NULL COMMENT '裁定书编号', `actual_release_date` date NOT NULL COMMENT '实际释放日期', `handover_person` varchar(100) DEFAULT NULL COMMENT '交接人', `handover_unit` varchar(200) DEFAULT NULL COMMENT '交接单位(移交时)', `certificate_type` tinyint DEFAULT NULL COMMENT '证件类型:1-身份证 2-户口簿 3-其他', `certificate_no` varchar(50) DEFAULT NULL COMMENT '证件号码', `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态:1-待释放 2-已释放 3-已取消', `remark` varchar(500) DEFAULT NULL COMMENT '备注', `operator_id` bigint DEFAULT NULL COMMENT '操作人ID', `operator_name` varchar(50) DEFAULT NULL COMMENT '操作人姓名', `creator` varchar(64) DEFAULT '' COMMENT '创建者', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updater` varchar(64) DEFAULT '' COMMENT '更新者', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`), KEY `idx_prisoner_id` (`prisoner_id`), KEY `idx_release_type` (`release_type`), KEY `idx_actual_release_date` (`actual_release_date`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='释放登记记录表'; ``` #### 3.2.6 新增:考核规则配置表 ```sql -- 新增:考核规则配置表 CREATE TABLE IF NOT EXISTS `prison_score_rule` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '规则ID', `category` tinyint NOT NULL COMMENT '类别:1-劳动改造 2-教育改造 3-日常行为 4-卫生纪律 5-加分项 6-扣分项', `item_name` varchar(100) NOT NULL COMMENT '项目名称', `item_code` varchar(50) NOT NULL COMMENT '项目编码(唯一)', `score` decimal(5,2) NOT NULL COMMENT '分值(加分正数,扣分负数)', `max_daily_score` decimal(5,2) DEFAULT NULL COMMENT '日最高分限制', `max_monthly_score` decimal(5,2) DEFAULT NULL COMMENT '月最高分限制', `description` varchar(500) DEFAULT NULL COMMENT '规则说明', `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态:1-启用 2-禁用', `sort` int NOT NULL DEFAULT 0 COMMENT '排序', `creator` varchar(64) DEFAULT '' COMMENT '创建者', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updater` varchar(64) DEFAULT '' COMMENT '更新者', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`), UNIQUE KEY `uk_item_code` (`item_code`), KEY `idx_category` (`category`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='考核规则配置表'; ``` #### 3.2.7 新增:考核记录明细表 ```sql -- 新增:考核记录明细表(日常考核) CREATE TABLE IF NOT EXISTS `prison_score_detail` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '记录ID', `prisoner_id` bigint NOT NULL COMMENT '罪犯ID', `prisoner_no` varchar(50) NOT NULL COMMENT '罪犯编号', `record_date` date NOT NULL COMMENT '记录日期', `rule_id` bigint NOT NULL COMMENT '规则ID', `score` decimal(5,2) NOT NULL COMMENT '得分', `score_type` tinyint NOT NULL COMMENT '类型:1-加分 2-扣分', `remark` varchar(500) DEFAULT NULL COMMENT '备注', `recorder_id` bigint NOT NULL COMMENT '记录人ID', `recorder_name` varchar(50) DEFAULT NULL COMMENT '记录人姓名', `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态:1-有效 2-作废', `creator` varchar(64) DEFAULT '' COMMENT '创建者', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`), KEY `idx_prisoner_date` (`prisoner_id`, `record_date`), KEY `idx_rule_id` (`rule_id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='考核记录明细表'; ``` ### 3.3 字典配置 ```sql -- 新增字典数据 INSERT INTO system_dict_data (dict_code, dict_sort, parent_code, dict_label, dict_value, status, create_time) VALUES -- 监区级别 ('prj_area_level', 1, NULL, '监区(大队)', '1', 0, NOW()), ('prj_area_level', 2, NULL, '分监区(中队)', '2', 0, NOW()), -- 监区类型(改造后) ('prj_area_type', 1, NULL, '普通监区', '1', 0, NOW()), ('prj_area_type', 2, NULL, '严管监区', '2', 0, NOW()), ('prj_area_type', 3, NULL, '集训监区', '3', 0, NOW()), ('prj_area_type', 4, NULL, '出监监区', '4', 0, NOW()), ('prj_area_type', 5, NULL, '医院监区', '5', 0, NOW()), ('prj_area_type', 6, NULL, '禁闭室', '6', 0, NOW()), -- 释放类型 ('prj_release_type', 1, NULL, '刑满释放', '1', 0, NOW()), ('prj_release_type', 2, NULL, '假释', '2', 0, NOW()), ('prj_release_type', 3, NULL, '暂予监外执行', '3', 0, NOW()), ('prj_release_type', 4, NULL, '减刑', '4', 0, NOW()), ('prj_release_type', 5, NULL, '法院裁定释放', '5', 0, NOW()), ('prj_release_type', 6, NULL, '死亡', '6', 0, NOW()), ('prj_release_type', 7, NULL, '其他', '7', 0, NOW()), -- 变动类型 ('prj_area_change_type', 1, NULL, '入监分配', '1', 0, NOW()), ('prj_area_change_type', 2, NULL, '调监', '2', 0, NOW()), ('prj_area_change_type', 3, NULL, '出监', '3', 0, NOW()), ('prj_area_change_type', 4, NULL, '移交转入', '4', 0, NOW()), ('prj_area_change_type', 5, NULL, '移交转出', '5', 0, NOW()), -- 考核类别 ('prj_score_category', 1, NULL, '劳动改造', '1', 0, NOW()), ('prj_score_category', 2, NULL, '教育改造', '2', 0, NOW()), ('prj_score_category', 3, NULL, '日常行为', '3', 0, NOW()), ('prj_score_category', 4, NULL, '卫生纪律', '4', 0, NOW()), ('prj_score_category', 5, NULL, '加分项', '5', 0, NOW()), ('prj_score_category', 6, NULL, '扣分项', '6', 0, NOW()); ``` --- ## 四、功能改造清单 ### 4.1 P0 - 核心功能(必须完成) | 序号 | 模块 | 功能 | 改造类型 | 预估工时 | 优先级 | |-----|------|-----|---------|---------|-------| | 1 | 监区管理 | 树形结构展示 | 新增 | 4h | P0 | | 2 | 监区管理 | 父级关联配置 | 新增 | 2h | P0 | | 3 | 监区管理 | 人数自动同步 | 新增 | 4h | P0 | | 4 | 服刑人员 | 释放登记功能 | 新增 | 6h | P0 | | 5 | 服刑人员 | 移交登记功能 | 新增 | 6h | P0 | | 6 | 服刑人员 | 调监记录功能 | 新增 | 4h | P0 | | 7 | 服刑人员 | 余刑预警提醒 | 新增 | 4h | P0 | | 8 | 服刑人员 | 照片字段补充 | 改造 | 2h | P0 | | 9 | 服刑人员 | 释放类型字段 | 改造 | 2h | P0 | | 10 | 考核管理 | 考核规则配置 | 新增 | 6h | P0 | | 11 | 考核管理 | 日常考核录入 | 新增 | 4h | P0 | | 12 | 考核管理 | 月度自动汇总 | 新增 | 4h | P0 | | 13 | 考核管理 | 考核等级评定 | 新增 | 2h | P0 | ### 4.2 P1 - 重要功能(计划完成) | 序号 | 模块 | 功能 | 改造类型 | 预估工时 | 优先级 | |-----|------|-----|---------|---------|-------| | 1 | 监区管理 | 监区人数统计报表 | 新增 | 4h | P1 | | 2 | 监区管理 | 层级数据导出 | 改造 | 2h | P1 | | 3 | 服刑人员 | 批量入监登记 | 新增 | 4h | P1 | | 4 | 服刑人员 | 罪犯详情页 | 新增 | 4h | P1 | | 5 | 服刑人员 | 位置历史轨迹 | 新增 | 4h | P1 | | 6 | 考核管理 | 考核结果公示 | 新增 | 4h | P1 | | 7 | 考核管理 | 考核趋势图表 | 新增 | 4h | P1 | | 8 | 考核管理 | 减刑假释关联 | 新增 | 4h | P1 | | 9 | 消费管理 | 消费限额配置 | 新增 | 2h | P1 | | 10 | 消费管理 | 消费异常预警 | 新增 | 4h | P1 | --- ## 五、详细功能设计 ### 5.1 监区管理功能设计 #### 5.1.1 树形展示逻辑 ```typescript // 前端展示数据结构 interface AreaNode { id: number; name: string; code: string; level: number; // 1-监区 2-分监区 type: number; capacity: number; currentCount: number; children?: AreaNode[]; // 子节点 } ``` **展示效果**: ``` 🔍 搜索:[监区名称____] [类型▽] [状态▽] [搜索] [重置] [+新增监区] 📋 监区列表(树形) ▼ 一监区 (A01) | 普通 | 容量: 320 | 当前: 285 ├── ▼ 一监区一分监区 (A01-01) | 普通 | 容量: 85 | 当前: 78 │ ├── 101监室 | 床位: 10 | 当前: 8 │ └── 102监室 | 床位: 10 | 当前: 9 ├── ▼ 一监区二分监区 (A01-02) | 普通 | 容量: 80 | 当前: 72 │ ├── 201监室 | 床位: 10 | 当前: 7 │ └── 202监室 | 床位: 10 | 当前: 8 └── ▼ 一监区三分监区 (A01-03) | 普通 | 容量: 80 | 当前: 70 ├── 301监室 | 床位: 10 | 当前: 6 └── 302监室 | 床位: 10 | 当前: 8 ▼ 二监区 (A02) | 严管 | 容量: 200 | 当前: 156 └── ... ``` #### 5.1.2 人数自动同步逻辑 ```java // 人数同步服务 @Service public class AreaCountSyncService { @Resource private PrisonerMapper prisonerMapper; @Transactional public void syncAreaCount(Long areaId) { // 统计该监区(含子监区)下的罪犯数量 Integer count = prisonerMapper.countByAreaIdOrChildren(areaId); // 更新监区当前人数 areaMapper.updateCurrentCount(areaId, count); } /** * 罪犯监区变更时触发人数同步 */ public void onPrisonerAreaChange(Long prisonerId, Long oldAreaId, Long newAreaId) { // 1. 同步原监区人数 syncAreaCount(oldAreaId); // 2. 同步新监区人数 syncAreaCount(newAreaId); // 3. 同步到顶层监区 Long topAreaId = getTopAreaId(newAreaId); syncAreaCount(topAreaId); } } ``` ### 5.2 释放登记功能设计 #### 5.2.1 释放类型与流程 ``` ┌─────────────────────────────────────────────────────────────┐ │ 释放登记流程 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 选择罪犯 ──→ 选择释放类型 ──→ 填写释放信息 ──→ 确认提交 │ │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ │ │ 列表选择 1. 刑满释放 释放日期 状态更新 │ │ 2. 假释 交接信息 监区变更 │ │ 3. 暂予监外执行 证件信息 日志记录 │ │ 4. 减刑 备注 │ │ 5. 法院裁定 │ │ 6. 死亡 │ │ 7. 其他 │ │ │ └─────────────────────────────────────────────────────────────┘ ``` #### 5.2.2 释放登记表单 ```typescript interface ReleaseForm { prisonerId: number; // 罪犯ID prisonerNo: string; // 罪犯编号(只读) prisonerName: string; // 罪犯姓名(只读) releaseType: number; // 释放类型(必选) releaseReason: string; // 释放原因 actualReleaseDate: string; // 实际释放日期(必填) // 假释/减刑时需填写 courtName?: string; // 裁定法院 judgmentNo?: string; // 裁定书编号 // 移交时需填写 handoverUnit?: string; // 交接单位 handoverPerson?: string; // 交接人 // 证件信息 certificateType?: number; // 证件类型 certificateNo?: string; // 证件号码 remark?: string; // 备注 } ``` ### 5.3 调监功能设计 #### 5.3.1 调监流程 ``` ┌─────────────────────────────────────────────────────────────┐ │ 调监流程 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 选择罪犯 ──→ 选择目标监区/监室 ──→ 填写原因 ──→ 确认提交 │ │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ │ │ 列表选择 目标监区下拉框 调监原因 状态更新 │ │ (含分监区) 选择/填写 监区变更 │ │ 日志记录 │ │ 人数同步 │ │ │ └─────────────────────────────────────────────────────────────┘ ``` #### 5.3.2 调监校验规则 ```java @Service public class TransferService { /** * 调监前校验 */ public void validateTransfer(Long prisonerId, Long targetCellId) { Prisoner prisoner = prisonerService.getById(prisonerId); Cell targetCell = cellService.getById(targetCellId); // 1. 校验目标监室是否可用 if (targetCell.getStatus() != 1) { throw new ServiceException("目标监室已禁用"); } // 2. 校验床位是否已满 if (targetCell.getCurrentCount() >= targetCell.getBedCount()) { throw new ServiceException("目标监室床位已满"); } // 3. 校验严管犯不能调入普通监区 if (prisoner.getSupervisionLevel() == SupervisionLevelEnum.STRICT && targetCell.getArea().getType() != AreaTypeEnum.STRICT) { throw new ServiceException("严管级罪犯不能调入普通监区"); } } /** * 执行调监 */ @Transactional public void doTransfer(Long prisonerId, Long targetCellId, String reason, Long operatorId) { // 1. 校验 validateTransfer(prisonerId, targetCellId); // 2. 获取原位置 Prisoner prisoner = prisonerService.getById(prisonerId); Long oldAreaId = prisoner.getPrisonAreaId(); Long oldCellId = prisoner.getPrisonCellId(); // 3. 更新罪犯位置 Cell targetCell = cellService.getById(targetCellId); prisoner.setPrisonAreaId(targetCell.getAreaId()); prisoner.setPrisonCellId(targetCellId); prisonerService.update(prisoner); // 4. 记录变动日志 prisonerAreaLogService.createLog(prisonerId, oldAreaId, oldCellId, targetCell.getAreaId(), targetCellId, ChangeTypeEnum.TRANSFER, reason, operatorId); // 5. 同步人数 areaCountSyncService.onPrisonerAreaChange(prisonerId, oldAreaId, targetCell.getAreaId()); } } ``` ### 5.4 余刑预警设计 ```java @Service public class ReminderService { /** * 定时任务:检查即将释放的罪犯 * 每天凌晨执行 */ @Scheduled(cron = "0 0 2 * * ?") public void checkUpcomingRelease() { // 1. 查询30天内即将释放的罪犯 LocalDate now = LocalDate.now(); LocalDate thirtyDaysLater = now.plusDays(30); List upcomingList = prisonerMapper.selectList( Wrapper.lambdaQuery() .lt(Prisoner::getReleaseDate, thirtyDaysLater) .gt(Prisoner::getReleaseDate, now) .eq(Prisoner::getStatus, PrisonerStatusEnum.IMPRISONED) ); // 2. 发送预警通知 for (Prisoner prisoner : upcomingList) { long daysLeft = ChronoUnit.DAYS.between(now, prisoner.getReleaseDate()); String message = String.format("罪犯[%s]还有%d天即将释放", prisoner.getName(), daysLeft); // 发送系统通知(可根据需求扩展为短信、邮件等) notifyService.sendWarning(message, NotifyType.RELEASE_REMINDER); } // 3. 查询超期未释放的罪犯(异常情况) List overdueList = prisonerMapper.selectList( Wrapper.lambdaQuery() .lt(Prisoner::getReleaseDate, now) .eq(Prisoner::getStatus, PrisonerStatusEnum.IMPRISONED) ); for (Prisoner prisoner : overdueList) { String message = String.format("警告:罪犯[%s]已过释放日期但仍未释放!", prisoner.getName()); notifyService.sendUrgent(message, NotifyType.RELEASE_OVERDUE); } } } ``` ### 5.5 考核规则配置设计 ```sql -- 考核规则示例数据 INSERT INTO prison_score_rule (category, item_name, item_code, score, description, status) VALUES -- 劳动改造(加分项) (1, '超额完成生产任务', 'LD_001', 2.00, '完成生产任务120%以上', 1), (1, '完成生产任务', 'LD_002', 1.00, '完成生产任务100%-120%', 1), (1, '基本完成生产任务', 'LD_003', 0.50, '完成生产任务80%-100%', 1), -- 教育改造(加分项) (2, '参加义务劳动', 'JY_001', 1.00, '参加监狱组织的义务劳动', 1), (2, '阅读指定书籍', 'JY_002', 0.50, '完成指定书籍阅读并写心得', 1), (2, '考试合格', 'JY_003', 1.00, '教育考试分数60分以上', 1), -- 日常行为(加分项) (3, '获得表扬', 'RC_001', 2.00, '获得监狱/监区表扬', 1), (3, '主动报告隐患', 'RC_002', 1.00, '主动报告安全隐患', 1), -- 卫生纪律(扣分项) (4, '内务不整洁', 'WS_001', -0.50, '个人内务检查不合格', 1), (4, '违规吸烟', 'WS_002', -2.00, '在禁烟区域吸烟', 1), -- 扣分项(通用) (6, '打架斗殴', 'KO_001', -5.00, '打架斗殴(未造成伤害)', 1), (6, '打架致伤', 'KO_002', -10.00, '打架致他人伤害', 1), (6, '私藏违禁品', 'KO_003', -10.00, '私藏违禁物品', 1), (6, '脱离监管视线', 'KO_004', -3.00, '脱离民警监管视线', 1); ``` --- ## 六、菜单权限设计 ### 6.1 菜单结构调整 ```sql -- 监狱综合管理父菜单(已有) SELECT @prisonParentId := id FROM system_menu WHERE name = '监狱综合管理'; -- 1. 监区信息管理(改造) UPDATE system_menu SET name = '监区信息管理', path = 'area', component = 'views/prison/area/index.vue' WHERE parent_id = @prisonParentId AND name = '监区信息管理'; -- 2. 新增:释放登记管理菜单 INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, status, component_name) VALUES ('释放登记管理', '', 2, 3, @prisonParentId, 'release', 'ep:document-checked', 'views/prison/release/index.vue', 0, 'Release'); SELECT @releaseParentId := LAST_INSERT_ID(); INSERT INTO system_menu (name, permission, type, sort, parent_id) VALUES ('释放登记查询', 'prison:release:query', 3, 1, @releaseParentId), ('释放登记创建', 'prison:release:create', 3, 2, @releaseParentId), ('释放登记导出', 'prison:release:export', 3, 3, @releaseParentId); -- 3. 新增:调监管理菜单(合并到服刑人员管理) INSERT INTO system_menu (name, permission, type, sort, parent_id) VALUES ('服刑人员调监', 'prison:prisoner:transfer', 3, 4, (SELECT id FROM system_menu WHERE parent_id = @prisonParentId AND name = '服刑人员管理')); -- 4. 新增:考核规则配置菜单 INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, status, component_name) VALUES ('考核规则配置', '', 2, 9, @prisonParentId, 'score-rule', 'ep:setting', 'views/prison/score-rule/index.vue', 0, 'ScoreRule'); SELECT @scoreRuleParentId := LAST_INSERT_ID(); INSERT INTO system_menu (name, permission, type, sort, parent_id) VALUES ('考核规则查询', 'prison:score-rule:query', 3, 1, @scoreRuleParentId), ('考核规则创建', 'prison:score-rule:create', 3, 2, @scoreRuleParentId), ('考核规则更新', 'prison:score-rule:update', 3, 3, @scoreRuleParentId), ('考核规则删除', 'prison:score-rule:delete', 3, 4, @scoreRuleParentId); ``` --- ## 七、前端改造点 ### 7.1 监区管理页面改造 **文件**:`frontend/src/views/prison/area/index.vue` **改造点**: 1. 使用 Element Plus Tree 组件展示层级结构 2. 新增/编辑时增加父级选择和级别选择 3. 移除原有的监区类型(医院/禁闭室独立为同级) ```vue ``` ### 7.2 新增页面 | 页面 | 路径 | 功能 | |-----|------|-----| | 释放登记列表 | `views/prison/release/index.vue` | 释放登记CRUD | | 释放登记表单 | `views/prison/release/ReleaseForm.vue` | 释放登记弹窗 | | 考核规则列表 | `views/prison/score-rule/index.vue` | 规则配置CRUD | | 考核规则表单 | `views/prison/score-rule/ScoreRuleForm.vue` | 规则编辑弹窗 | | 考核录入 | `views/prison/score-record/index.vue` | 日常考核录入 | | 调监弹窗 | `views/prison/prisoner/TransferDialog.vue` | 调监操作 | ### 7.3 API 新增 ```typescript // api/prison/release/index.ts export interface Release { id: number; prisonerId: number; prisonerNo: string; prisonerName: string; releaseType: number; releaseReason: string; actualReleaseDate: string; courtName?: string; judgmentNo?: string; status: number; } export const ReleaseApi = { getReleasePage: (params) => request.get({ url: '/prison/release/page', params }), getRelease: (id) => request.get({ url: `/prison/release/get?id=${id}` }), createRelease: (data) => request.post({ url: '/prison/release/create', data }), exportRelease: (params) => request.download({ url: '/prison/release/export-excel', params }) } // api/prison/score-rule/index.ts export const ScoreRuleApi = { getRulePage: (params) => request.get({ url: '/prison/score-rule/page', params }), createRule: (data) => request.post({ url: '/prison/score-rule/create', data }), updateRule: (data) => request.put({ url: '/prison/score-rule/update', data }), deleteRule: (id) => request.delete({ url: `/prison/score-rule/delete?id=${id}` }), getRuleByCategory: (category) => request.get({ url: `/prison/score-rule/list-by-category?category=${category}` }) } // api/prison/prisoner/index.ts 新增 export const PrisonerApi = { // ... 现有方法 // 调监 transfer: (data: { prisonerId: number; targetCellId: number; reason: string }) => request.put({ url: '/prison/prisoner/transfer', data }), // 罪犯详情 getDetail: (id: number) => request.get({ url: `/prison/prisoner/get-detail?id=${id}` }), // 获取位置历史 getAreaHistory: (id: number) => request.get({ url: `/prison/prisoner/get-area-history?id=${id}` }) } ``` --- ## 八、后端改造点 ### 8.1 Controller 新增 | Controller | 路径 | 功能 | |-----------|------|-----| | ReleaseController | controller/admin/release/ | 释放登记CRUD | | ScoreRuleController | controller/admin/scorerule/ | 考核规则CRUD | | PrisonerController 新增 | controller/admin/prisoner/ | 调监接口 | ### 8.2 Service 新增/改造 ```java // 新增:释放登记服务 public interface ReleaseService { PageResult page(ReleasePageReqVO vo); Long create(ReleaseSaveReqVO vo); void update(ReleaseSaveReqVO vo); ReleaseRespVO get(Long id); void doRelease(Long id, Long operatorId); // 执行释放 void cancelRelease(Long id, Long operatorId); // 取消释放 } // 新增:调监服务 public interface TransferService { void validateTransfer(Long prisonerId, Long targetCellId); void doTransfer(Long prisonerId, Long targetCellId, String reason, Long operatorId); } // 改造:AreaService public interface AreaService { // 原有方法... // 新增:获取树形结构 List getAreaTree(); // 新增:获取子监区列表 List getChildAreas(Long parentId); // 新增:同步人数 void syncCurrentCount(Long areaId); } // 改造:AreaServiceImpl - 人数同步逻辑 @Service public class AreaServiceImpl implements AreaService { @Resource private PrisonerMapper prisonerMapper; @Override @Transactional public void syncCurrentCount(Long areaId) { // 递归同步所有子监区 List children = getChildAreas(areaId); int totalCount = 0; for (AreaDO child : children) { syncCurrentCount(child.getId()); totalCount += child.getCurrentCount(); } // 统计罪犯数量(当前监区的罪犯 + 子监区的罪犯) Integer count = prisonerMapper.countByAreaIdOrChildren(areaId); // 更新 updateCurrentCount(areaId, count); } } ``` ### 8.3 Mapper 新增 ```java // PrisonerMapper 新增方法 public interface PrisonerMapper extends BaseMapper { /** * 统计某监区(含子监区)下的罪犯数量 */ Integer countByAreaIdOrChildren(@Param("areaId") Long areaId); /** * 查询即将释放的罪犯 */ List selectUpcomingRelease(@Param("startDate") LocalDate startDate, @Param("endDate") LocalDate endDate); /** * 查询超过释放日期仍未释放的罪犯 */ List selectOverdueRelease(@Param("date") LocalDate date); } ``` --- ## 九、数据库迁移脚本 ### 9.1 监区表迁移 ```sql -- 1. 添加新字段 ALTER TABLE `prison_area` ADD COLUMN `parent_id` bigint NOT NULL DEFAULT 0 COMMENT '父级ID,0表示顶级监区' AFTER `code`, ADD COLUMN `level` tinyint NOT NULL DEFAULT 1 COMMENT '级别:1-监区(大队) 2-分监区(中队)' AFTER `parent_id`; -- 2. 更新现有数据(将原来的监区设置为顶级,分监区暂不处理) -- 假设原有的都是监区(大队)级别 UPDATE `prison_area` SET `level` = 1, `parent_id` = 0; -- 3. 更新字典(删除旧的,增加新的) DELETE FROM system_dict_data WHERE dict_code = 'PRISON_AREA_TYPE'; INSERT INTO system_dict_data (dict_code, dict_sort, dict_label, dict_value, status) VALUES ('PRISON_AREA_TYPE', 1, '普通监区', '1', 0), ('PRISON_AREA_TYPE', 2, '严管监区', '2', 0), ('PRISON_AREA_TYPE', 3, '集训监区', '3', 0), ('PRISON_AREA_TYPE', 4, '出监监区', '4', 0), ('PRISON_AREA_TYPE', 5, '医院监区', '5', 0), ('PRISON_AREA_TYPE', 6, '禁闭室', '6', 0); ``` ### 9.2 创建新表 ```sql -- 1. 创建罪犯区域变动记录表 CREATE TABLE IF NOT EXISTS `prison_prisoner_area_log` ( `id` bigint NOT NULL AUTO_INCREMENT, `prisoner_id` bigint NOT NULL, `prisoner_no` varchar(50) NOT NULL, `from_area_id` bigint DEFAULT NULL, `from_cell_id` bigint DEFAULT NULL, `to_area_id` bigint NOT NULL, `to_cell_id` bigint NOT NULL, `change_type` tinyint NOT NULL, `change_reason` varchar(500) DEFAULT NULL, `operator_id` bigint DEFAULT NULL, `operator_name` varchar(50) DEFAULT NULL, `operate_time` datetime NOT NULL, `creator` varchar(64) DEFAULT '', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `deleted` bit(1) NOT NULL DEFAULT b'0', `tenant_id` bigint NOT NULL DEFAULT 0, PRIMARY KEY (`id`), KEY `idx_prisoner_id` (`prisoner_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 2. 创建释放登记记录表 CREATE TABLE IF NOT EXISTS `prison_prisoner_release` ( `id` bigint NOT NULL AUTO_INCREMENT, `prisoner_id` bigint NOT NULL, `prisoner_no` varchar(50) NOT NULL, `prisoner_name` varchar(50) NOT NULL, `release_type` tinyint NOT NULL, `release_reason` varchar(500) DEFAULT NULL, `court_name` varchar(100) DEFAULT NULL, `judgment_no` varchar(50) DEFAULT NULL, `actual_release_date` date NOT NULL, `handover_person` varchar(100) DEFAULT NULL, `handover_unit` varchar(200) DEFAULT NULL, `certificate_type` tinyint DEFAULT NULL, `certificate_no` varchar(50) DEFAULT NULL, `status` tinyint NOT NULL DEFAULT 1, `remark` varchar(500) DEFAULT NULL, `operator_id` bigint DEFAULT NULL, `operator_name` varchar(50) DEFAULT NULL, `creator` varchar(64) DEFAULT '', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `updater` varchar(64) DEFAULT '', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `deleted` bit(1) NOT NULL DEFAULT b'0', `tenant_id` bigint NOT NULL DEFAULT 0, PRIMARY KEY (`id`), KEY `idx_prisoner_id` (`prisoner_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 3. 创建考核规则配置表 CREATE TABLE IF NOT EXISTS `prison_score_rule` ( `id` bigint NOT NULL AUTO_INCREMENT, `category` tinyint NOT NULL, `item_name` varchar(100) NOT NULL, `item_code` varchar(50) NOT NULL, `score` decimal(5,2) NOT NULL, `max_daily_score` decimal(5,2) DEFAULT NULL, `max_monthly_score` decimal(5,2) DEFAULT NULL, `description` varchar(500) DEFAULT NULL, `status` tinyint NOT NULL DEFAULT 1, `sort` int NOT NULL DEFAULT 0, `creator` varchar(64) DEFAULT '', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `updater` varchar(64) DEFAULT '', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `deleted` bit(1) NOT NULL DEFAULT b'0', `tenant_id` bigint NOT NULL DEFAULT 0, PRIMARY KEY (`id`), UNIQUE KEY `uk_item_code` (`item_code`), KEY `idx_category` (`category`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 4. 创建考核记录明细表 CREATE TABLE IF NOT EXISTS `prison_score_detail` ( `id` bigint NOT NULL AUTO_INCREMENT, `prisoner_id` bigint NOT NULL, `prisoner_no` varchar(50) NOT NULL, `record_date` date NOT NULL, `rule_id` bigint NOT NULL, `score` decimal(5,2) NOT NULL, `score_type` tinyint NOT NULL, `remark` varchar(500) DEFAULT NULL, `recorder_id` bigint NOT NULL, `recorder_name` varchar(50) DEFAULT NULL, `status` tinyint NOT NULL DEFAULT 1, `creator` varchar(64) DEFAULT '', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `deleted` bit(1) NOT NULL DEFAULT b'0', `tenant_id` bigint NOT NULL DEFAULT 0, PRIMARY KEY (`id`), KEY `idx_prisoner_date` (`prisoner_id`, `record_date`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ``` ### 9.3 服刑人员表补充字段 ```sql ALTER TABLE `prison_prisoner` ADD COLUMN `photo` varchar(500) DEFAULT NULL COMMENT '照片URL' AFTER `idCard`, ADD COLUMN `release_type` tinyint DEFAULT NULL COMMENT '释放类型:1-刑满 2-假释 3-暂予监外执行 4-减刑 5-移交 6-死亡' AFTER `releaseDate`, ADD COLUMN `release_reason` varchar(500) DEFAULT NULL COMMENT '释放原因' AFTER `release_type`; ``` --- ## 十、实施计划 ### 10.1 第一阶段:基础数据改造(P0) | 序号 | 任务 | 文件/位置 | 负责人 | |-----|------|----------|-------| | 1 | 监区表结构改造 | `AreaDO.java` + SQL | | | 2 | 监区树形展示 | `area/index.vue` | | | 3 | 监区新增/编辑表单改造 | `AreaForm.vue` | | | 4 | 人数同步服务 | `AreaCountSyncService.java` | | | 5 | 新增字典数据 | SQL脚本 | | ### 10.2 第二阶段:核心业务功能(P0) | 序号 | 任务 | 文件/位置 | 负责人 | |-----|------|----------|-------| | 1 | 释放登记模块后端 | `ReleaseController.java`, `ReleaseService.java` | | | 2 | 释放登记模块前端 | `release/index.vue`, `ReleaseForm.vue` | | | 3 | 调监功能后端 | `PrisonerController.transfer()`, `TransferService.java` | | | 4 | 调监功能前端 | `TransferDialog.vue` | | | 5 | 余刑预警定时任务 | `ReminderService.java` | | | 6 | 罪犯照片和释放类型字段 | `PrisonerDO.java` | | ### 10.3 第三阶段:考核管理(P0) | 序号 | 任务 | 文件/位置 | 负责人 | |-----|------|----------|-------| | 1 | 考核规则模块后端 | `ScoreRuleController.java`, `ScoreRuleService.java` | | | 2 | 考核规则模块前端 | `score-rule/index.vue`, `ScoreRuleForm.vue` | | | 3 | 考核记录明细表及服务 | `ScoreDetailService.java` | | | 4 | 日常考核录入页面 | `score-record/index.vue` | | | 5 | 月度汇总自动计算 | `ScoreMonthly汇总任务` | | ### 10.4 第四阶段:统计与优化(P1) | 序号 | 任务 | 文件/位置 | 负责人 | |-----|------|----------|-------| | 1 | 监区人数统计报表 | 新增页面 | | | 2 | 罪犯位置历史轨迹 | `prisoner/detail.vue` | | | 3 | 考核结果公示 | `score/public.vue` | | | 4 | 批量入监导入 | `prisoner/import.vue` | | | 5 | 消费限额配置 | `consumption/limit.vue` | | --- ## 十一、验收标准 ### 功能验收 - [ ] 监区支持树形层级展示 - [ ] 新增监区时可以选择父级和级别 - [ ] 监区人数随罪犯位置变更自动同步 - [ ] 支持释放登记(刑满/假释/暂外/减刑等) - [ ] 支持调监操作并自动记录日志 - [ ] 释放前30天有预警提醒 - [ ] 支持考核规则配置 - [ ] 支持日常考核录入 - [ ] 月度考核自动汇总计算 ### 数据验收 - [ ] 监区层级关系正确 - [ ] 监区人数统计准确 - [ ] 罪犯位置历史记录完整 - [ ] 释放记录状态流转正确 --- ## 附录 ### A. 相关文件清单 | 类型 | 文件路径 | |-----|---------| | 后端-DO | `dal/dataobject/area/AreaDO.java` | | 后端-DO | `dal/dataobject/PrisonerDO.java` (改造) | | 后端-Service | `service/area/AreaService.java` (改造) | | 后端-Service | `service/area/impl/AreaServiceImpl.java` (改造) | | 后端-Controller | `controller/admin/area/PrisonAreaController.java` (改造) | | 后端-Controller | `controller/admin/release/PrisonerReleaseController.java` (新增) | | 后端-Controller | `controller/admin/scorerule/ScoreRuleController.java` (新增) | | 前端-页面 | `views/prison/area/index.vue` (改造) | | 前端-页面 | `views/prison/area/AreaForm.vue` (改造) | | 前端-页面 | `views/prison/release/index.vue` (新增) | | 前端-页面 | `views/prison/release/ReleaseForm.vue` (新增) | | 前端-API | `api/prison/area/index.ts` (改造) | | 前端-API | `api/prison/release/index.ts` (新增) | | 前端-API | `api/prison/score-rule/index.ts` (新增) | ### B. 技术债务 1. 监区人数同步需要分布式锁(多实例部署时) 2. 大数据量下树形查询性能优化 3. 定期归档历史变动记录 --- **文档创建:** Claude AI **待评审专家:** 监狱业务专家、系统架构师