XL监狱综合管理平台 - 监区犯人管理改造设计方案
文档版本:v2.0
创建日期:2026-01-14
状态:待实施
评审专家:监狱业务专家
一、背景说明
1.1 项目概述
XL监狱综合管理平台是面向监狱管理的信息化系统,基于芋道源码(yudao-boot-mini)进行二次开发,实现罪犯管理、教育改造、考核评估等业务的规范化、智能化。
1.2 文档目的
本设计文档用于指导系统改造,主要解决以下问题:
- 监区层级关系缺失(扁平结构改为树形结构)
- 核心业务流程不完整(出监/移交/调监)
- 考核评估功能不完善
- 数据联动逻辑缺失
二、现状问题分析
2.1 监区管理问题
| 问题 |
现状 |
影响 |
| 层级缺失 |
监区为扁平结构,无父子关系 |
无法表达"监区→分监区"层级 |
| 人数不同步 |
current_count 为手动维护字段 |
数据不一致风险 |
| 特殊监区混淆 |
用 type 区分"医院/禁闭室" |
与普通监区并列不合理 |
2.2 服刑人员管理问题
| 问题 |
现状 |
影响 |
| 出监功能缺失 |
无释放/移交登记功能 |
业务流程不闭环 |
| 调监无记录 |
虽有 prisoner_area_log 表但无功能 |
位置变更无法追溯 |
| 释放无预警 |
临近释放无提醒机制 |
可能漏放 |
2.3 计分考核问题
| 问题 |
现状 |
影响 |
| 规则未配置 |
无考核规则配置功能 |
考核标准不统一 |
| 自动计算缺失 |
月度汇总需手动计算 |
工作量大、易出错 |
| 公示功能缺失 |
无考核结果公示模块 |
透明度不足 |
三、监区层级设计方案
3.1 中国监狱组织架构参考
┌─────────────────────────────────────────────────────────┐
│ 监狱(行政单位) │
├─────────────────────────────────────────────────────────┤
│ 职能科室:办公室、政治处、刑罚执行科、狱政管理科、教育改造科等 │
├─────────────────────────────────────────────────────────┤
│ 监区(大队) │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 一监区 │ │ 二监区 │ │ 医院监区│ │ 禁闭室 │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │一分监区 │ │二分监区 │ │ 医疗区 │ │ 禁闭室 │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────┐ │
│ │ 监室(101、102、201...) │ │
│ └─────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
3.2 数据结构设计
3.2.1 监区信息表(改造)
-- 改造后的 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 监室信息表(改造)
-- 改造后的 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 服刑人员表(补充字段)
-- 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 新增:罪犯区域变动记录表
-- 新增:罪犯区域变动记录表(用于调监追溯)
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 新增:释放登记记录表
-- 新增:释放登记记录表
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 新增:考核规则配置表
-- 新增:考核规则配置表
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 新增:考核记录明细表
-- 新增:考核记录明细表(日常考核)
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 字典配置
-- 新增字典数据
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 树形展示逻辑
// 前端展示数据结构
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 人数自动同步逻辑
// 人数同步服务
@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 释放登记表单
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 调监校验规则
@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 余刑预警设计
@Service
public class ReminderService {
/**
* 定时任务:检查即将释放的罪犯
* 每天凌晨执行
*/
@Scheduled(cron = "0 0 2 * * ?")
public void checkUpcomingRelease() {
// 1. 查询30天内即将释放的罪犯
LocalDate now = LocalDate.now();
LocalDate thirtyDaysLater = now.plusDays(30);
List<Prisoner> upcomingList = prisonerMapper.selectList(
Wrapper.<Prisoner>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<Prisoner> overdueList = prisonerMapper.selectList(
Wrapper.<Prisoner>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 考核规则配置设计
-- 考核规则示例数据
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 菜单结构调整
-- 监狱综合管理父菜单(已有)
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
改造点:
- 使用 Element Plus Tree 组件展示层级结构
- 新增/编辑时增加父级选择和级别选择
- 移除原有的监区类型(医院/禁闭室独立为同级)
<template>
<el-tree
:data="treeData"
:props="treeProps"
node-key="id"
default-expand-all
@node-click="handleNodeClick"
>
<template #default="{ node, data }">
<span class="area-tree-node">
<el-icon v-if="data.level === 1"><OfficeBuilding /></el-icon>
<el-icon v-else><Files /></el-icon>
<span>{{ data.name }}</span>
<el-tag size="small" type="info">{{ data.currentCount }}/{{ data.capacity }}</el-tag>
</span>
</template>
</el-tree>
</template>
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 新增
// 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 新增/改造
// 新增:释放登记服务
public interface ReleaseService {
PageResult<ReleaseRespVO> 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<AreaNodeVO> getAreaTree();
// 新增:获取子监区列表
List<AreaRespVO> 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<AreaDO> 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 新增
// PrisonerMapper 新增方法
public interface PrisonerMapper extends BaseMapper<PrisonerDO> {
/**
* 统计某监区(含子监区)下的罪犯数量
*/
Integer countByAreaIdOrChildren(@Param("areaId") Long areaId);
/**
* 查询即将释放的罪犯
*/
List<PrisonerDO> selectUpcomingRelease(@Param("startDate") LocalDate startDate,
@Param("endDate") LocalDate endDate);
/**
* 查询超过释放日期仍未释放的罪犯
*/
List<PrisonerDO> selectOverdueRelease(@Param("date") LocalDate date);
}
九、数据库迁移脚本
9.1 监区表迁移
-- 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 创建新表
-- 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 服刑人员表补充字段
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 |
|
十一、验收标准
功能验收
数据验收
附录
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. 技术债务
- 监区人数同步需要分布式锁(多实例部署时)
- 大数据量下树形查询性能优化
- 定期归档历史变动记录
文档创建: Claude AI
待评审专家: 监狱业务专家、系统架构师