xlcp/XL监狱综合管理平台-监区犯人管理改造设计方案.md
2026-01-14 22:18:15 +08:00

46 KiB
Raw Blame History

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 监区信息表(改造)

-- 改造后的 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 '父级ID0表示顶级监区',
    `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

改造点

  1. 使用 Element Plus Tree 组件展示层级结构
  2. 新增/编辑时增加父级选择和级别选择
  3. 移除原有的监区类型(医院/禁闭室独立为同级)
<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 '父级ID0表示顶级监区' 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

十一、验收标准

功能验收

  • 监区支持树形层级展示
  • 新增监区时可以选择父级和级别
  • 监区人数随罪犯位置变更自动同步
  • 支持释放登记(刑满/假释/暂外/减刑等)
  • 支持调监操作并自动记录日志
  • 释放前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 待评审专家: 监狱业务专家、系统架构师