# 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<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 考核规则配置设计

```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
<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 新增

```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<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 新增

```java
// 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 监区表迁移

```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
**待评审专家：** 监狱业务专家、系统架构师
