## 主要改进 ### 1. 增强 getRuleGroups 函数 - ✅ 添加完整的分页参数支持 (page, pageSize) - ✅ 添加筛选参数 (name, code, is_enabled, pid) - ✅ 添加排序参数 (orderBy, order) - ✅ 返回总数 (totalCount) - ✅ 支持一级分组和二级分组查询 ### 2. 优化 getChildGroups 函数 - ✅ 内部使用改进后的 getRuleGroups 函数 - ✅ 自动添加评查点数量统计 - ✅ 改进类型安全性 ### 3. 优化 getRuleGroup 函数 - ✅ 确保评查点数量统计准确 - ✅ 改进错误处理 - ✅ 优化类型守卫逻辑 ### 4. 类型定义改进 - ✅ 新增 RuleGroupQueryParams 接口 - ✅ ApiRuleGroup.pid 类型支持 null - ✅ 修复所有 TypeScript 类型错误 ### 5. 创建对接计划文档 - ✅ 详细的 API 对接实施计划 - ✅ 分模块逐步实施策略 - ✅ 验收标准和风险评估 ## 相关文件 - app/api/evaluation_points/rule-groups.ts - docs/evaluation/API对接实施计划.md ## 验收清单 - [x] TypeScript 类型检查通过 - [x] 支持分页、筛选、排序 - [x] 返回评查点数量统计 - [x] 向后兼容现有代码 Co-Authored-By: Claude <noreply@anthropic.com>
18 KiB
评查点分组管理 API 文档 v3
版本: v3 路由前缀:
/api/v3/evaluation-point-groups数据库表:evaluation_point_groups认证方式: JWT Bearer Token
📋 目录
数据模型
数据库表结构 (evaluation_point_groups)
| 字段名 | 类型 | 约束 | 默认值 | 说明 |
|---|---|---|---|---|
id |
INTEGER | PRIMARY KEY | auto_increment | 分组ID(自增主键) |
pid |
INTEGER | NULLABLE | NULL | 父分组ID(NULL/0 表示一级分组) |
code |
VARCHAR(50) | NOT NULL | - | 分组编码(唯一标识) |
name |
VARCHAR(100) | NOT NULL | - | 分组名称 |
description |
TEXT | NULLABLE | NULL | 分组描述 |
is_enabled |
BOOLEAN | NOT NULL | true | 启用状态 |
created_at |
TIMESTAMPTZ | NOT NULL | now() | 创建时间 |
updated_at |
TIMESTAMPTZ | NOT NULL | now() | 更新时间 |
Pydantic 数据模型
EvaluationPointGroupBase - 基础模型
class EvaluationPointGroupBase(BaseModel):
name: str = Field(..., min_length=1, max_length=100, description="分组名称")
code: str = Field(..., min_length=1, max_length=50, pattern=r"^[a-zA-Z0-9_-]+$", description="分组编码")
pid: Optional[int] = Field(None, description="父分组ID (NULL/0表示一级分组)")
description: Optional[str] = Field(None, description="分组描述")
is_enabled: bool = Field(True, description="启用状态")
EvaluationPointGroupCreate - 创建请求模型
class EvaluationPointGroupCreate(EvaluationPointGroupBase):
pass
EvaluationPointGroupUpdate - 更新请求模型
class EvaluationPointGroupUpdate(BaseModel):
name: Optional[str] = Field(None, min_length=1, max_length=100)
code: Optional[str] = Field(None, min_length=1, max_length=50, pattern=r"^[a-zA-Z0-9_-]+$")
pid: Optional[int] = None
description: Optional[str] = None
is_enabled: Optional[bool] = None
EvaluationPointGroupResponse - 响应模型
class EvaluationPointGroupResponse(EvaluationPointGroupBase):
id: int
created_at: datetime
updated_at: datetime
rule_count: Optional[int] = Field(None, description="评查点数量(子分组查询时返回)")
children: Optional[List['EvaluationPointGroupResponse']] = Field(None, description="子分组列表")
class Config:
from_attributes = True
EvaluationPointGroupListResponse - 列表响应模型
class EvaluationPointGroupListResponse(BaseModel):
data: List[EvaluationPointGroupResponse]
total: int
page: int
page_size: int
查询接口
1. 获取一级分组列表
接口: GET /api/v3/evaluation-point-groups
功能: 获取所有一级分组(pid = 0 或 NULL)
请求参数 (Query):
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
page |
int | 否 | 1 | 页码 |
page_size |
int | 否 | 20 | 每页数量(最大100) |
name |
str | 否 | - | 分组名称(模糊搜索) |
code |
str | 否 | - | 分组编码(模糊搜索) |
is_enabled |
bool | 否 | - | 启用状态筛选 |
响应示例:
{
"data": [
{
"id": 1,
"pid": null,
"name": "合同基本要素",
"code": "contract-basic",
"description": "合同基本信息检查",
"is_enabled": true,
"created_at": "2024-01-01T10:00:00Z",
"updated_at": "2024-01-01T10:00:00Z",
"rule_count": null,
"children": null
}
],
"total": 10,
"page": 1,
"page_size": 20
}
SQL 等价:
SELECT * FROM evaluation_point_groups
WHERE (pid = 0 OR pid IS NULL)
AND name ILIKE '%合同%' -- 可选
AND code ILIKE '%basic%' -- 可选
AND is_enabled = true -- 可选
ORDER BY created_at DESC
LIMIT 20 OFFSET 0;
2. 获取所有分组(树形结构)
接口: GET /api/v3/evaluation-point-groups/all
功能: 获取所有分组并构建父子树形结构
请求参数 (Query):
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
include_disabled |
bool | 否 | false | 是否包含禁用的分组 |
with_rule_count |
bool | 否 | true | 是否返回评查点数量 |
响应示例:
{
"data": [
{
"id": 1,
"pid": null,
"name": "合同基本要素",
"code": "contract-basic",
"description": "合同基本信息检查",
"is_enabled": true,
"created_at": "2024-01-01T10:00:00Z",
"updated_at": "2024-01-01T10:00:00Z",
"rule_count": 15,
"children": [
{
"id": 2,
"pid": 1,
"name": "合同主体信息",
"code": "contract-subject",
"description": "检查合同主体信息",
"is_enabled": true,
"created_at": "2024-01-01T11:00:00Z",
"updated_at": "2024-01-01T11:00:00Z",
"rule_count": 5,
"children": null
}
]
}
],
"total": 25,
"page": 1,
"page_size": 1000
}
处理逻辑:
- 查询所有分组(可选过滤禁用状态)
- 筛选一级分组(pid = NULL 或 0)
- 为每个一级分组查找子分组(pid = parent.id)
- 如果
with_rule_count=true,查询每个分组的评查点数量
3. 获取单个分组详情
接口: GET /api/v3/evaluation-point-groups/{id}
功能: 根据 ID 获取分组详情
路径参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
int | 是 | 分组ID |
查询参数 (Query):
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
with_rule_count |
bool | 否 | true | 是否返回评查点数量 |
响应示例:
{
"id": 1,
"pid": null,
"name": "合同基本要素",
"code": "contract-basic",
"description": "合同基本信息检查",
"is_enabled": true,
"created_at": "2024-01-01T10:00:00Z",
"updated_at": "2024-01-01T10:00:00Z",
"rule_count": 15,
"children": null
}
错误响应 (404):
{
"detail": "评查点分组不存在"
}
4. 获取子分组列表
接口: GET /api/v3/evaluation-point-groups/{parent_id}/children
功能: 获取指定父分组下的所有子分组,并附带评查点数量
路径参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
parent_id |
int | 是 | 父分组ID |
查询参数 (Query):
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
page |
int | 否 | 1 | 页码 |
page_size |
int | 否 | 20 | 每页数量 |
is_enabled |
bool | 否 | - | 启用状态筛选 |
响应示例:
{
"data": [
{
"id": 2,
"pid": 1,
"name": "合同主体信息",
"code": "contract-subject",
"description": "检查合同主体信息",
"is_enabled": true,
"created_at": "2024-01-01T11:00:00Z",
"updated_at": "2024-01-01T11:00:00Z",
"rule_count": 5,
"children": null
}
],
"total": 5,
"page": 1,
"page_size": 20
}
SQL 等价:
-- 查询子分组
SELECT * FROM evaluation_point_groups
WHERE pid = 1
AND is_enabled = true -- 可选
ORDER BY created_at DESC
LIMIT 20 OFFSET 0;
-- 查询每个子分组的评查点数量
SELECT COUNT(*) FROM evaluation_points
WHERE evaluation_point_groups_id = 2;
创建接口
5. 创建评查点分组
接口: POST /api/v3/evaluation-point-groups
功能: 创建新的评查点分组(一级或二级)
请求头:
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json
请求体:
{
"name": "合同主体信息",
"code": "contract-subject",
"pid": 1,
"description": "检查合同主体信息的完整性",
"is_enabled": true
}
字段说明:
name: 必填,1-100字符code: 必填,1-50字符,只能包含字母、数字、连字符和下划线pid: 可选,NULL/0 表示一级分组,其他值为父分组IDdescription: 可选,分组描述is_enabled: 可选,默认 true
字段验证规则:
name和code不能为空code必须唯一(数据库约束)code格式:^[a-zA-Z0-9_-]+$- 如果
pid不为 NULL/0,必须引用存在的分组ID
响应示例 (201 Created):
{
"id": 3,
"pid": 1,
"name": "合同主体信息",
"code": "contract-subject",
"description": "检查合同主体信息的完整性",
"is_enabled": true,
"created_at": "2024-01-15T14:30:00Z",
"updated_at": "2024-01-15T14:30:00Z",
"rule_count": 0,
"children": null
}
错误响应 (400):
{
"detail": "分组编码已存在"
}
错误响应 (404):
{
"detail": "父分组不存在"
}
更新接口
6. 更新评查点分组
接口: PUT /api/v3/evaluation-point-groups/{id}
功能: 更新指定分组的信息
路径参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
int | 是 | 分组ID |
请求头:
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json
请求体 (Partial Update):
{
"name": "合同主体信息(更新)",
"code": "contract-subject-v2",
"description": "更新后的描述",
"is_enabled": false
}
字段说明:
- 所有字段均为可选
- 只更新提供的字段
updated_at自动更新为当前时间
响应示例 (200 OK):
{
"id": 3,
"pid": 1,
"name": "合同主体信息(更新)",
"code": "contract-subject-v2",
"description": "更新后的描述",
"is_enabled": false,
"created_at": "2024-01-15T14:30:00Z",
"updated_at": "2024-01-15T16:00:00Z",
"rule_count": 5,
"children": null
}
错误响应 (404):
{
"detail": "评查点分组不存在"
}
错误响应 (400):
{
"detail": "分组编码已被其他分组使用"
}
删除接口
7. 删除评查点分组
接口: DELETE /api/v3/evaluation-point-groups/{id}
功能: 删除指定分组(级联删除子分组和评查点)
路径参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
int | 是 | 分组ID |
请求头:
Authorization: Bearer <JWT_TOKEN>
删除逻辑:
- 查询分组信息,判断是一级还是二级分组
- 如果是一级分组:
- 查询所有子分组
- 删除每个子分组的评查点(
evaluation_points表) - 删除所有子分组
- 删除当前分组的评查点
- 删除当前分组
响应示例 (200 OK):
{
"success": true,
"message": "评查点分组删除成功",
"deleted_groups": 3,
"deleted_points": 15
}
错误响应 (404):
{
"detail": "评查点分组不存在"
}
SQL 执行顺序 (伪代码):
-- 1. 查询分组信息
SELECT * FROM evaluation_point_groups WHERE id = ?;
-- 2. 如果是一级分组,查询所有子分组
SELECT * FROM evaluation_point_groups WHERE pid = ?;
-- 3. 删除所有子分组的评查点
DELETE FROM evaluation_points
WHERE evaluation_point_groups_id IN (
SELECT id FROM evaluation_point_groups WHERE pid = ?
);
-- 4. 删除所有子分组
DELETE FROM evaluation_point_groups WHERE pid = ?;
-- 5. 删除当前分组的评查点
DELETE FROM evaluation_points WHERE evaluation_point_groups_id = ?;
-- 6. 删除当前分组
DELETE FROM evaluation_point_groups WHERE id = ?;
批量操作接口
8. 批量更新启用状态
接口: PATCH /api/v3/evaluation-point-groups/batch/status
功能: 批量更新多个分组的启用状态
请求头:
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json
请求体:
{
"ids": [1, 2, 3],
"is_enabled": false
}
响应示例 (200 OK):
{
"success": true,
"updated_count": 3,
"message": "批量更新成功"
}
9. 批量删除分组
接口: DELETE /api/v3/evaluation-point-groups/batch
功能: 批量删除多个分组(级联删除)
请求头:
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json
请求体:
{
"ids": [1, 2, 3]
}
响应示例 (200 OK):
{
"success": true,
"deleted_groups": 5,
"deleted_points": 25,
"message": "批量删除成功"
}
错误响应
标准错误响应格式
{
"detail": "错误描述信息"
}
常见错误码
| HTTP 状态码 | 错误场景 | 示例 |
|---|---|---|
| 400 | 请求参数验证失败 | {"detail": "分组名称不能为空"} |
| 401 | 未授权(JWT无效) | {"detail": "未授权访问"} |
| 404 | 资源不存在 | {"detail": "评查点分组不存在"} |
| 409 | 资源冲突 | {"detail": "分组编码已存在"} |
| 422 | 数据验证失败 | {"detail": [{"loc": ["body", "code"], "msg": "格式不正确"}]} |
| 500 | 服务器内部错误 | {"detail": "服务器错误,请稍后重试"} |
使用示例
示例 1: 获取一级分组(带分页和筛选)
请求:
GET /api/v3/evaluation-point-groups?page=1&page_size=10&name=合同&is_enabled=true
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
响应:
{
"data": [
{
"id": 1,
"pid": null,
"name": "合同基本要素",
"code": "contract-basic",
"description": "合同基本信息检查",
"is_enabled": true,
"created_at": "2024-01-01T10:00:00Z",
"updated_at": "2024-01-01T10:00:00Z",
"rule_count": null,
"children": null
}
],
"total": 1,
"page": 1,
"page_size": 10
}
示例 2: 创建二级分组
请求:
POST /api/v3/evaluation-point-groups
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json
{
"name": "合同主体信息",
"code": "contract-subject",
"pid": 1,
"description": "检查合同主体信息的完整性",
"is_enabled": true
}
响应:
{
"id": 3,
"pid": 1,
"name": "合同主体信息",
"code": "contract-subject",
"description": "检查合同主体信息的完整性",
"is_enabled": true,
"created_at": "2024-01-15T14:30:00Z",
"updated_at": "2024-01-15T14:30:00Z",
"rule_count": 0,
"children": null
}
示例 3: 获取树形结构
请求:
GET /api/v3/evaluation-point-groups/all?include_disabled=false&with_rule_count=true
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
响应:
{
"data": [
{
"id": 1,
"pid": null,
"name": "合同基本要素",
"code": "contract-basic",
"description": "合同基本信息检查",
"is_enabled": true,
"created_at": "2024-01-01T10:00:00Z",
"updated_at": "2024-01-01T10:00:00Z",
"rule_count": 15,
"children": [
{
"id": 2,
"pid": 1,
"name": "合同主体信息",
"code": "contract-subject",
"description": "检查合同主体信息",
"is_enabled": true,
"created_at": "2024-01-01T11:00:00Z",
"updated_at": "2024-01-01T11:00:00Z",
"rule_count": 5,
"children": null
}
]
}
],
"total": 25,
"page": 1,
"page_size": 1000
}
示例 4: 批量更新状态
请求:
PATCH /api/v3/evaluation-point-groups/batch/status
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json
{
"ids": [1, 2, 3],
"is_enabled": false
}
响应:
{
"success": true,
"updated_count": 3,
"message": "批量更新成功"
}
示例 5: 删除分组(级联删除)
请求:
DELETE /api/v3/evaluation-point-groups/1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
响应:
{
"success": true,
"message": "评查点分组删除成功",
"deleted_groups": 3,
"deleted_points": 15
}
附录
性能优化建议
-
查询优化:
- 为
pid、code、is_enabled字段创建索引 - 使用分页避免一次性加载大量数据
- 树形结构查询时,使用递归查询或批量查询减少数据库往返
- 为
-
缓存策略:
- 对不常变化的分组列表进行缓存(Redis)
- 缓存键格式:
eval_groups:all,eval_groups:{id} - 创建/更新/删除操作时清除相关缓存
-
批量操作:
- 使用批量查询减少数据库连接开销
- 使用事务确保批量操作的原子性
数据库索引建议
-- 为常用查询字段创建索引
CREATE INDEX idx_evaluation_point_groups_pid ON evaluation_point_groups(pid);
CREATE INDEX idx_evaluation_point_groups_code ON evaluation_point_groups(code);
CREATE INDEX idx_evaluation_point_groups_is_enabled ON evaluation_point_groups(is_enabled);
CREATE INDEX idx_evaluation_point_groups_created_at ON evaluation_point_groups(created_at DESC);
-- 为外键创建索引(提升关联查询性能)
CREATE INDEX idx_evaluation_points_group_id ON evaluation_points(evaluation_point_groups_id);
CREATE INDEX idx_evaluation_points_parent_group_id ON evaluation_points(evaluation_point_groups_pid);
与 PostgREST 前端实现的对比
| 功能 | PostgREST 前端实现 | FastAPI 后端实现 |
|---|---|---|
| 认证方式 | 前端传递 JWT | 后端验证 JWT |
| 分页 | 前端手动实现 | 后端自动分页 |
| 树形结构 | 前端构建 | 后端构建(可选) |
| 评查点数量 | 前端并发查询 | 后端一次性返回 |
| 级联删除 | 前端多次调用 | 后端事务处理 |
| 数据验证 | 前端验证 | 前后端双重验证 |
| 错误处理 | 前端解析错误 | 后端统一错误格式 |
文档版本: v1.0 最后更新: 2025-01-21 维护者: DocAuditAI Team