d3b9403d64
## 主要改进 ### 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>
1308 lines
33 KiB
Markdown
1308 lines
33 KiB
Markdown
# 评查点管理 API 文档 v3
|
||
|
||
> **版本**: v3
|
||
> **路由前缀**: `/api/v3/evaluation-points`
|
||
> **数据库表**: `evaluation_points`
|
||
> **认证方式**: JWT Bearer Token
|
||
|
||
---
|
||
|
||
## 📋 目录
|
||
|
||
1. [数据模型](#数据模型)
|
||
2. [查询接口](#查询接口)
|
||
3. [创建接口](#创建接口)
|
||
4. [更新接口](#更新接口)
|
||
5. [删除接口](#删除接口)
|
||
6. [批量操作接口](#批量操作接口)
|
||
7. [错误响应](#错误响应)
|
||
8. [使用示例](#使用示例)
|
||
|
||
---
|
||
|
||
## 数据模型
|
||
|
||
### 数据库表结构 (`evaluation_points`)
|
||
|
||
| 字段名 | 类型 | 约束 | 默认值 | 说明 |
|
||
|--------|------|------|--------|------|
|
||
| `id` | INTEGER | PRIMARY KEY | auto_increment | 评查点ID(自增主键) |
|
||
| `code` | VARCHAR(100) | UNIQUE, NOT NULL | - | 评查点编码(唯一标识) |
|
||
| `name` | VARCHAR(100) | NOT NULL | - | 评查点名称 |
|
||
| `evaluation_point_groups_id` | INTEGER | FOREIGN KEY | NULL | 所属二级分组ID |
|
||
| `evaluation_point_groups_pid` | INTEGER | FOREIGN KEY | NULL | 所属一级分组ID |
|
||
| `risk` | VARCHAR(10) | NOT NULL | - | 风险等级(high/medium/low) |
|
||
| `description` | TEXT | NULLABLE | NULL | 评查点描述 |
|
||
| `is_enabled` | BOOLEAN | NOT NULL | true | 启用状态 |
|
||
| `references_laws` | JSONB | NOT NULL | - | 引用法典(JSON结构) |
|
||
| `extraction_config` | JSONB | NOT NULL | - | 抽取配置(JSON结构) |
|
||
| `evaluation_config` | JSONB | NOT NULL | - | 评查设置(JSON结构) |
|
||
| `pass_message` | TEXT | NULLABLE | NULL | 通过提示 |
|
||
| `fail_message` | TEXT | NULLABLE | NULL | 不通过提示 |
|
||
| `suggestion_message` | TEXT | NULLABLE | NULL | 建议信息 |
|
||
| `suggestion_message_type` | VARCHAR(20) | NOT NULL | 'warning' | 建议信息类型(info/warning/error) |
|
||
| `post_action` | VARCHAR(50) | NULLABLE | NULL | 评查后动作类型(none/manual/replace) |
|
||
| `action_config` | TEXT | NULLABLE | NULL | 动作配置 |
|
||
| `score` | NUMERIC(5,2) | NOT NULL | 0.00 | 评查点得分 |
|
||
| `area` | VARCHAR(20) | NULLABLE | NULL | 所属地区 |
|
||
| `created_at` | TIMESTAMPTZ | NOT NULL | now() | 创建时间 |
|
||
| `updated_at` | TIMESTAMPTZ | NOT NULL | now() | 更新时间 |
|
||
|
||
### 外键关系
|
||
|
||
```sql
|
||
-- 二级分组外键
|
||
FOREIGN KEY (evaluation_point_groups_id)
|
||
REFERENCES evaluation_point_groups(id)
|
||
ON UPDATE CASCADE ON DELETE SET NULL
|
||
|
||
-- 一级分组外键
|
||
FOREIGN KEY (evaluation_point_groups_pid)
|
||
REFERENCES evaluation_point_groups(id)
|
||
ON UPDATE CASCADE ON DELETE SET NULL
|
||
```
|
||
|
||
---
|
||
|
||
## JSONB 字段结构详解
|
||
|
||
### 1. `references_laws` - 引用法典
|
||
|
||
**数据结构**:
|
||
|
||
```typescript
|
||
{
|
||
"name": string, // 法律法规名称
|
||
"content": string, // 法律法规内容
|
||
"articles": string[] // 条款列表
|
||
}
|
||
```
|
||
|
||
**示例**:
|
||
|
||
```json
|
||
{
|
||
"name": "中华人民共和国合同法",
|
||
"content": "第十条 当事人订立合同,有书面形式、口头形式和其他形式。",
|
||
"articles": ["第十条", "第十一条"]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 2. `extraction_config` - 抽取配置
|
||
|
||
**数据结构**:
|
||
|
||
```typescript
|
||
{
|
||
"llm": { // LLM抽取配置
|
||
"fields": string[], // 抽取字段列表
|
||
"prompt_setting": {
|
||
"type": string, // 提示词类型:"system" 或 "llm_default_prompt"
|
||
"template": "" // 固定为空字符串
|
||
}
|
||
},
|
||
"vlm": { // VLM视觉抽取配置
|
||
"fields": Array<{
|
||
"name": string, // 字段名称
|
||
"type": string // 字段级提示词类型 (vlm_default_prompt/vlm_handwriting_prompt/等)
|
||
}>,
|
||
"prompt_setting": {
|
||
"type": string, // 提示词类型:"system" 或 "vlm_default_prompt"
|
||
"template": "" // 固定为空字符串
|
||
}
|
||
},
|
||
"regex": { // 正则表达式抽取配置
|
||
"fields": Array<{
|
||
"field": string, // 字段名称(完整路径,如:文书名-章节-字段名)
|
||
"pattern": string // 正则表达式
|
||
}>
|
||
}
|
||
}
|
||
```
|
||
|
||
**重要说明**:
|
||
- **prompt_setting.type 支持两种值**:
|
||
- `"system"` - 旧格式,后端抽取模块识别并处理(推荐)
|
||
- `"llm_default_prompt"` / `"vlm_default_prompt"` - 前端新格式,**后端不处理**
|
||
- ⚠️ **兼容性警告**:如果使用 `llm_default_prompt` / `vlm_default_prompt`,抽取模块将**忽略该配置**
|
||
- **推荐使用** `"system"` 确保后端正确处理
|
||
- `vlm.fields[].type` 是字段级的提示词类型,与 `prompt_setting.type` 不同
|
||
- `template` 字段固定为空字符串 `""`
|
||
- 前端界面保存时使用 `llm_default_prompt` / `vlm_default_prompt`,但建议改为 `system`
|
||
|
||
**示例1:推荐格式(使用 "system",后端可处理)**:
|
||
|
||
```json
|
||
{
|
||
"llm": {
|
||
"fields": ["合同封面-合同名称", "合同封面-合同编号", "合同正文-合同名称"],
|
||
"prompt_setting": {
|
||
"type": "system",
|
||
"template": ""
|
||
}
|
||
},
|
||
"vlm": {
|
||
"fields": [
|
||
{
|
||
"name": "证据复制(提取)单-居民身份证-姓名",
|
||
"type": "vlm_default_prompt"
|
||
},
|
||
{
|
||
"name": "立案报告表-负责人意见-签名(有/无)",
|
||
"type": "vlm_handwriting_prompt"
|
||
}
|
||
],
|
||
"prompt_setting": {
|
||
"type": "system",
|
||
"template": ""
|
||
}
|
||
},
|
||
"regex": {
|
||
"fields": [
|
||
{
|
||
"field": "行政处罚事先告知书-正文-权利告知",
|
||
"pattern": "(?:享有|陈述|权|申辩|权).{0,40}(日).{0,40}(?:视为|放弃|权利)"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
**示例2:前端新格式(使用 "llm_default_prompt",后端不处理⚠️)**:
|
||
|
||
```json
|
||
{
|
||
"llm": {
|
||
"fields": ["test-llm"],
|
||
"prompt_setting": {
|
||
"type": "llm_default_prompt",
|
||
"template": ""
|
||
}
|
||
},
|
||
"vlm": {
|
||
"fields": [
|
||
{
|
||
"name": "test-vlm",
|
||
"type": "vlm_default_prompt"
|
||
}
|
||
],
|
||
"prompt_setting": {
|
||
"type": "vlm_default_prompt",
|
||
"template": ""
|
||
}
|
||
},
|
||
"regex": {
|
||
"fields": [
|
||
{
|
||
"field": "test-zz",
|
||
"pattern": "\\d{4}[-/年](0?[1-9]|1[0-2])[-/月](0?[1-9]|[12][0-9]|3[01])[日]?"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
⚠️ **注意**:示例2的格式虽然可以保存到数据库,但抽取模块会忽略 `prompt_setting.type != "system"` 的配置,导致这些字段不会被抽取!
|
||
|
||
---
|
||
|
||
### 3. `evaluation_config` - 评查设置
|
||
|
||
**数据结构**:
|
||
|
||
```typescript
|
||
{
|
||
"logicType": string, // 逻辑类型 (and/or/custom)
|
||
"customLogic": string, // 自定义逻辑表达式
|
||
"rules": Array<{ // 评查规则列表
|
||
"id": string, // 规则ID
|
||
"type": string, // 规则类型 (exists/consistency/logic/regex/ai)
|
||
"config": {
|
||
// exists 规则配置
|
||
"logic"?: string, // 逻辑运算符 (and/or)
|
||
"fields"?: string[], // 字段列表
|
||
|
||
// consistency 规则配置
|
||
"pairs"?: Array<{ // 字段对列表
|
||
"sourceField": string,
|
||
"targetField": string,
|
||
"compareMethod": string // 比较方法 (exact/fuzzy/contains)
|
||
}>,
|
||
|
||
// logic 规则配置
|
||
"conditions"?: Array<{ // 条件列表
|
||
"field": string, // 字段名
|
||
"operator": string, // 运算符 (eq/neq/gt/lt/contains等)
|
||
"value": any // 比较值
|
||
}>,
|
||
|
||
// regex 规则配置
|
||
"field"?: string, // 目标字段
|
||
"pattern"?: string, // 正则表达式
|
||
"matchType"?: string, // 匹配类型 (match/search/fullmatch)
|
||
|
||
// ai 规则配置
|
||
"model"?: string, // AI模型标识 (deepseek/qwen14b/qwen32b等) - 仅用于前端显示,后端使用统一配置的LLM模型
|
||
"prompt"?: string, // AI提示词(支持字段占位符 {字段名})
|
||
"temperature"?: number, // 温度参数 (0.0-1.0) - 仅用于前端显示,后端使用默认配置
|
||
|
||
// 通用配置
|
||
"selectedFields"?: string[] // 选中的字段列表(可选)
|
||
}
|
||
}>
|
||
}
|
||
```
|
||
|
||
**评查规则类型说明**:
|
||
|
||
| 规则类型 | 说明 | config字段 | 界面显示 |
|
||
|---------|------|-----------|----------|
|
||
| `exists` | 字段存在性检查 | `logic`, `fields` | 字段存在性 |
|
||
| `consistency` | 字段一致性检查 | `logic`, `pairs` (sourceField, targetField, compareMethod) | 字段一致性 |
|
||
| `logic` | 逻辑条件判断 | `logic`, `conditions` (field, operator, value) | 逻辑判断 |
|
||
| `regex` | 正则表达式匹配 | `field`, `pattern`, `matchType` | 正则匹配 |
|
||
| `ai` | AI智能评查 | `model`(仅标识), `prompt`, `temperature`(仅标识), `selectedFields` | AI评查(大模型) |
|
||
|
||
**重要说明**:
|
||
- `ai` 规则中的 `model` 和 `temperature` 字段**仅用于前端界面显示和标识**
|
||
- 后端实际使用环境配置中的 `DEFAULT_LLM_MODEL` 和默认温度参数(0.6)
|
||
- 如需切换AI模型,需修改后端配置文件,而非评查点配置
|
||
|
||
**示例1:综合规则配置**:
|
||
|
||
```json
|
||
{
|
||
"logicType": "and",
|
||
"customLogic": "",
|
||
"rules": [
|
||
{
|
||
"id": "1",
|
||
"type": "exists",
|
||
"config": {
|
||
"logic": "and",
|
||
"fields": ["合同封面-有效期限", "合同封面-签订日期", "合同正文-合同生效"]
|
||
}
|
||
},
|
||
{
|
||
"id": "2",
|
||
"type": "consistency",
|
||
"config": {
|
||
"logic": "and",
|
||
"pairs": [
|
||
{
|
||
"sourceField": "合同封面-合同名称",
|
||
"targetField": "合同正文-合同名称",
|
||
"compareMethod": "exact"
|
||
}
|
||
]
|
||
}
|
||
},
|
||
{
|
||
"id": "3",
|
||
"type": "ai",
|
||
"config": {
|
||
"model": "deepseek",
|
||
"prompt": "请判断{合同落款-甲方-签订日期}和{合同落款-乙方-签订日期}中较晚的日期即为{合同正文-合同生效}起始日期,{合同封面-有效期限}有明确日期范围的情况下,{合同落款-甲方-签订日期}和{合同落款-乙方-签订日期}与{合同封面-有效期限}明确日期范围上限差值是否小于3天,小于3天为不符合,若{合同落款-甲方-签订日期}或{合同落款-乙方-签订日期}大于{合同封面-有效期限}明确日期范围上限,则提示"倒签风险"\n仅回答\"符合\"、\"不符合\"或"不符合(倒签风险)",并简要说明理由。",
|
||
"temperature": 0.1,
|
||
"selectedFields": []
|
||
}
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
**示例2:纯AI评查**:
|
||
|
||
```json
|
||
{
|
||
"logicType": "and",
|
||
"customLogic": "",
|
||
"rules": [
|
||
{
|
||
"id": "1",
|
||
"type": "ai",
|
||
"config": {
|
||
"model": "qwen14b",
|
||
"prompt": "请判断以下{文本、印刷体大模型评查-正文-内容}是否包含了时间地点人物事情工具的四要素,仅回答\"符合\"或\"不符合\",并简要说明理由。",
|
||
"temperature": 0.1
|
||
}
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Pydantic 数据模型
|
||
|
||
### `EvaluationPointBase` - 基础模型
|
||
|
||
```python
|
||
class ReferencesLaw(BaseModel):
|
||
"""法律法规引用"""
|
||
name: str = Field(default="", description="法律法规名称")
|
||
content: str = Field(default="", description="法律法规内容")
|
||
articles: List[str] = Field(default_factory=list, description="条款列表")
|
||
|
||
class LLMExtractionConfig(BaseModel):
|
||
"""LLM抽取配置"""
|
||
fields: List[str] = Field(default_factory=list, description="抽取字段列表")
|
||
prompt_setting: Dict[str, str] = Field(
|
||
default_factory=lambda: {"type": "llm_default_prompt", "template": ""}
|
||
)
|
||
|
||
class VLMField(BaseModel):
|
||
"""VLM字段配置"""
|
||
name: str
|
||
type: str = "vlm_default_prompt"
|
||
|
||
class VLMExtractionConfig(BaseModel):
|
||
"""VLM抽取配置"""
|
||
fields: List[VLMField] = Field(default_factory=list)
|
||
prompt_setting: Dict[str, str] = Field(
|
||
default_factory=lambda: {"type": "vlm_default_prompt", "template": ""}
|
||
)
|
||
|
||
class RegexField(BaseModel):
|
||
"""正则表达式字段"""
|
||
field: str
|
||
pattern: str
|
||
|
||
class RegexExtractionConfig(BaseModel):
|
||
"""正则表达式抽取配置"""
|
||
fields: List[RegexField] = Field(default_factory=list)
|
||
|
||
class ExtractionConfig(BaseModel):
|
||
"""完整抽取配置"""
|
||
llm: LLMExtractionConfig = Field(default_factory=LLMExtractionConfig)
|
||
vlm: VLMExtractionConfig = Field(default_factory=VLMExtractionConfig)
|
||
regex: RegexExtractionConfig = Field(default_factory=RegexExtractionConfig)
|
||
|
||
class EvaluationRule(BaseModel):
|
||
"""评查规则"""
|
||
id: str
|
||
type: str # exists/consistency/range/format/ai
|
||
config: Dict[str, Any]
|
||
|
||
class EvaluationConfig(BaseModel):
|
||
"""评查配置"""
|
||
logicType: str = Field("and", description="逻辑类型 (and/or/custom)")
|
||
customLogic: str = Field("", description="自定义逻辑表达式")
|
||
rules: List[EvaluationRule] = Field(default_factory=list)
|
||
|
||
class EvaluationPointBase(BaseModel):
|
||
"""评查点基础模型"""
|
||
name: str = Field(..., min_length=1, max_length=100)
|
||
code: str = Field(..., min_length=1, max_length=100, pattern=r"^[a-zA-Z0-9_-]+$")
|
||
risk: str = Field(..., pattern=r"^(high|medium|low)$")
|
||
is_enabled: bool = Field(True)
|
||
description: Optional[str] = None
|
||
|
||
evaluation_point_groups_id: int = Field(..., description="二级分组ID")
|
||
evaluation_point_groups_pid: int = Field(..., description="一级分组ID")
|
||
|
||
references_laws: ReferencesLaw = Field(default_factory=ReferencesLaw)
|
||
extraction_config: ExtractionConfig = Field(default_factory=ExtractionConfig)
|
||
evaluation_config: EvaluationConfig = Field(default_factory=EvaluationConfig)
|
||
|
||
pass_message: str = Field(default="文档检查通过,符合规范要求。")
|
||
fail_message: str = Field(default="文档存在以下问题,请修改后重新提交。")
|
||
suggestion_message: Optional[str] = None
|
||
suggestion_message_type: str = Field(default="warning", pattern=r"^(info|warning|error)$")
|
||
post_action: Optional[str] = Field(None, pattern=r"^(none|manual|replace)$")
|
||
action_config: Optional[str] = None
|
||
score: float = Field(default=0.00, ge=0, le=100)
|
||
```
|
||
|
||
### `EvaluationPointCreate` - 创建请求模型
|
||
|
||
```python
|
||
class EvaluationPointCreate(EvaluationPointBase):
|
||
"""创建评查点请求"""
|
||
pass
|
||
```
|
||
|
||
### `EvaluationPointUpdate` - 更新请求模型
|
||
|
||
```python
|
||
class EvaluationPointUpdate(BaseModel):
|
||
"""更新评查点请求(所有字段可选)"""
|
||
name: Optional[str] = Field(None, min_length=1, max_length=100)
|
||
code: Optional[str] = Field(None, min_length=1, max_length=100)
|
||
risk: Optional[str] = Field(None, pattern=r"^(high|medium|low)$")
|
||
is_enabled: Optional[bool] = None
|
||
description: Optional[str] = None
|
||
|
||
evaluation_point_groups_id: Optional[int] = None
|
||
evaluation_point_groups_pid: Optional[int] = None
|
||
|
||
references_laws: Optional[ReferencesLaw] = None
|
||
extraction_config: Optional[ExtractionConfig] = None
|
||
evaluation_config: Optional[EvaluationConfig] = None
|
||
|
||
pass_message: Optional[str] = None
|
||
fail_message: Optional[str] = None
|
||
suggestion_message: Optional[str] = None
|
||
suggestion_message_type: Optional[str] = Field(None, pattern=r"^(info|warning|error)$")
|
||
post_action: Optional[str] = Field(None, pattern=r"^(none|manual|replace)$")
|
||
action_config: Optional[str] = None
|
||
score: Optional[float] = Field(None, ge=0, le=100)
|
||
```
|
||
|
||
### `EvaluationPointResponse` - 响应模型
|
||
|
||
```python
|
||
class EvaluationPointResponse(BaseModel):
|
||
"""评查点响应"""
|
||
id: int
|
||
name: str
|
||
code: str
|
||
risk: str
|
||
is_enabled: bool
|
||
description: Optional[str]
|
||
|
||
evaluation_point_groups_id: int
|
||
evaluation_point_groups_pid: int
|
||
|
||
references_laws: Dict[str, Any]
|
||
extraction_config: Dict[str, Any]
|
||
evaluation_config: Dict[str, Any]
|
||
|
||
pass_message: str
|
||
fail_message: str
|
||
suggestion_message: Optional[str]
|
||
suggestion_message_type: str
|
||
post_action: Optional[str]
|
||
action_config: Optional[str]
|
||
score: float
|
||
area: Optional[str]
|
||
|
||
created_at: datetime
|
||
updated_at: datetime
|
||
|
||
class Config:
|
||
from_attributes = True
|
||
```
|
||
|
||
### `EvaluationPointListResponse` - 列表响应模型
|
||
|
||
```python
|
||
class EvaluationPointListResponse(BaseModel):
|
||
"""评查点列表响应"""
|
||
data: List[EvaluationPointResponse]
|
||
total: int
|
||
page: int
|
||
page_size: int
|
||
```
|
||
|
||
---
|
||
|
||
## 查询接口
|
||
|
||
### 1. 获取评查点列表
|
||
|
||
**接口**: `GET /api/v3/evaluation-points`
|
||
|
||
**功能**: 获取评查点列表,支持分页和多条件筛选
|
||
|
||
**请求参数** (Query):
|
||
|
||
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|
||
|--------|------|------|--------|------|
|
||
| `page` | int | 否 | 1 | 页码 |
|
||
| `page_size` | int | 否 | 20 | 每页数量(最大100) |
|
||
| `name` | str | 否 | - | 评查点名称(模糊搜索) |
|
||
| `code` | str | 否 | - | 评查点编码(模糊搜索) |
|
||
| `risk` | str | 否 | - | 风险等级(high/medium/low) |
|
||
| `is_enabled` | bool | 否 | - | 启用状态 |
|
||
| `evaluation_point_groups_id` | int | 否 | - | 二级分组ID |
|
||
| `evaluation_point_groups_pid` | int | 否 | - | 一级分组ID |
|
||
| `area` | str | 否 | - | 所属地区 |
|
||
|
||
**响应示例**:
|
||
|
||
```json
|
||
{
|
||
"data": [
|
||
{
|
||
"id": 693,
|
||
"name": "测试评查点-test",
|
||
"code": "test-test",
|
||
"risk": "low",
|
||
"is_enabled": true,
|
||
"description": "",
|
||
"evaluation_point_groups_pid": 1,
|
||
"evaluation_point_groups_id": 40,
|
||
"references_laws": {
|
||
"name": "",
|
||
"content": "",
|
||
"articles": []
|
||
},
|
||
"extraction_config": {
|
||
"llm": {
|
||
"fields": ["test-llm"],
|
||
"prompt_setting": {
|
||
"type": "llm_default_prompt",
|
||
"template": ""
|
||
}
|
||
},
|
||
"vlm": {
|
||
"fields": [
|
||
{
|
||
"name": "test-vlm",
|
||
"type": "vlm_default_prompt"
|
||
}
|
||
],
|
||
"prompt_setting": {
|
||
"type": "vlm_default_prompt",
|
||
"template": ""
|
||
}
|
||
},
|
||
"regex": {
|
||
"fields": [
|
||
{
|
||
"field": "test-zz",
|
||
"pattern": "\\d{4}[-/年](0?[1-9]|1[0-2])[-/月](0?[1-9]|[12][0-9]|3[01])[日]?"
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"evaluation_config": {
|
||
"logicType": "and",
|
||
"customLogic": "",
|
||
"rules": [
|
||
{
|
||
"id": "1",
|
||
"type": "exists",
|
||
"config": {
|
||
"logic": "and",
|
||
"fields": ["test-llm"]
|
||
}
|
||
},
|
||
{
|
||
"id": "2",
|
||
"type": "consistency",
|
||
"config": {
|
||
"logic": "and",
|
||
"pairs": [
|
||
{
|
||
"sourceField": "test-vlm",
|
||
"targetField": "test-zz",
|
||
"compareMethod": "exact"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
]
|
||
},
|
||
"pass_message": "文档检查通过,符合规范要求。",
|
||
"fail_message": "文档存在以下问题,请修改后重新提交。",
|
||
"suggestion_message": "你觉得呢",
|
||
"suggestion_message_type": "warning",
|
||
"post_action": "manual",
|
||
"action_config": "测试评查后动作的文本输入",
|
||
"score": 1.00,
|
||
"area": null,
|
||
"created_at": "2024-01-15T14:30:00Z",
|
||
"updated_at": "2024-01-15T14:30:00Z"
|
||
}
|
||
],
|
||
"total": 50,
|
||
"page": 1,
|
||
"page_size": 20
|
||
}
|
||
```
|
||
|
||
**SQL 等价**:
|
||
|
||
```sql
|
||
SELECT * FROM evaluation_points
|
||
WHERE name ILIKE '%test%' -- 可选
|
||
AND code ILIKE '%test%' -- 可选
|
||
AND risk = 'low' -- 可选
|
||
AND is_enabled = true -- 可选
|
||
AND evaluation_point_groups_id = 40 -- 可选
|
||
AND evaluation_point_groups_pid = 1 -- 可选
|
||
AND area = '梅州' -- 可选
|
||
ORDER BY created_at DESC
|
||
LIMIT 20 OFFSET 0;
|
||
```
|
||
|
||
---
|
||
|
||
### 2. 获取单个评查点详情
|
||
|
||
**接口**: `GET /api/v3/evaluation-points/{id}`
|
||
|
||
**功能**: 根据 ID 获取评查点详情
|
||
|
||
**路径参数**:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| `id` | int | 是 | 评查点ID |
|
||
|
||
**响应示例**: 同上(单个对象)
|
||
|
||
**错误响应** (404):
|
||
|
||
```json
|
||
{
|
||
"detail": "评查点不存在"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 3. 获取指定分组的评查点列表
|
||
|
||
**接口**: `GET /api/v3/evaluation-points/group/{group_id}`
|
||
|
||
**功能**: 获取指定分组下的所有评查点
|
||
|
||
**路径参数**:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| `group_id` | int | 是 | 分组ID(可以是一级或二级分组) |
|
||
|
||
**查询参数** (Query):
|
||
|
||
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|
||
|--------|------|------|--------|------|
|
||
| `page` | int | 否 | 1 | 页码 |
|
||
| `page_size` | int | 否 | 20 | 每页数量 |
|
||
| `is_enabled` | bool | 否 | - | 启用状态筛选 |
|
||
|
||
**响应示例**: 同第1个接口
|
||
|
||
---
|
||
|
||
### 4. 获取评查点数量统计
|
||
|
||
**接口**: `GET /api/v3/evaluation-points/count/{group_id}`
|
||
|
||
**功能**: 获取指定分组的评查点数量
|
||
|
||
**路径参数**:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| `group_id` | int | 是 | 分组ID |
|
||
|
||
**响应示例**:
|
||
|
||
```json
|
||
{
|
||
"group_id": 40,
|
||
"count": 15
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 创建接口
|
||
|
||
### 5. 创建评查点
|
||
|
||
**接口**: `POST /api/v3/evaluation-points`
|
||
|
||
**功能**: 创建新的评查点
|
||
|
||
**请求头**:
|
||
|
||
```
|
||
Authorization: Bearer <JWT_TOKEN>
|
||
Content-Type: application/json
|
||
```
|
||
|
||
**请求体**:
|
||
|
||
```json
|
||
{
|
||
"name": "测试评查点-test",
|
||
"code": "test-test",
|
||
"risk": "low",
|
||
"is_enabled": true,
|
||
"description": "",
|
||
"evaluation_point_groups_pid": 1,
|
||
"evaluation_point_groups_id": 40,
|
||
"references_laws": {
|
||
"name": "",
|
||
"content": "",
|
||
"articles": []
|
||
},
|
||
"extraction_config": {
|
||
"llm": {
|
||
"fields": ["test-llm"],
|
||
"prompt_setting": {
|
||
"type": "llm_default_prompt",
|
||
"template": ""
|
||
}
|
||
},
|
||
"vlm": {
|
||
"fields": [
|
||
{
|
||
"name": "test-vlm",
|
||
"type": "vlm_default_prompt"
|
||
}
|
||
],
|
||
"prompt_setting": {
|
||
"type": "vlm_default_prompt",
|
||
"template": ""
|
||
}
|
||
},
|
||
"regex": {
|
||
"fields": [
|
||
{
|
||
"field": "test-zz",
|
||
"pattern": "\\d{4}[-/年](0?[1-9]|1[0-2])[-/月](0?[1-9]|[12][0-9]|3[01])[日]?"
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"evaluation_config": {
|
||
"logicType": "and",
|
||
"customLogic": "",
|
||
"rules": [
|
||
{
|
||
"id": "1",
|
||
"type": "exists",
|
||
"config": {
|
||
"logic": "and",
|
||
"fields": ["test-llm"]
|
||
}
|
||
},
|
||
{
|
||
"id": "2",
|
||
"type": "consistency",
|
||
"config": {
|
||
"logic": "and",
|
||
"pairs": [
|
||
{
|
||
"sourceField": "test-vlm",
|
||
"targetField": "test-zz",
|
||
"compareMethod": "exact"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
]
|
||
},
|
||
"pass_message": "文档检查通过,符合规范要求。",
|
||
"fail_message": "文档存在以下问题,请修改后重新提交。",
|
||
"suggestion_message": "你觉得呢",
|
||
"suggestion_message_type": "warning",
|
||
"post_action": "manual",
|
||
"action_config": "测试评查后动作的文本输入",
|
||
"score": 1
|
||
}
|
||
```
|
||
|
||
**字段验证规则**:
|
||
|
||
1. **必填字段**: `name`, `code`, `risk`, `evaluation_point_groups_id`, `evaluation_point_groups_pid`
|
||
2. **唯一性约束**: `code` 必须唯一
|
||
3. **枚举值验证**:
|
||
- `risk`: `high` | `medium` | `low`
|
||
- `suggestion_message_type`: `info` | `warning` | `error`
|
||
- `post_action`: `none` | `manual` | `replace`
|
||
4. **外键验证**:
|
||
- `evaluation_point_groups_id` 必须存在于 `evaluation_point_groups` 表
|
||
- `evaluation_point_groups_pid` 必须存在于 `evaluation_point_groups` 表
|
||
5. **JSONB默认值**:
|
||
- `references_laws`: `{"name": "", "content": "", "articles": []}`
|
||
- `extraction_config`: 完整的默认结构
|
||
- `evaluation_config`: `{"logicType": "and", "customLogic": "", "rules": []}`
|
||
|
||
**响应示例** (201 Created):
|
||
|
||
```json
|
||
{
|
||
"id": 694,
|
||
"name": "测试评查点-test",
|
||
"code": "test-test",
|
||
...
|
||
"created_at": "2024-01-15T14:30:00Z",
|
||
"updated_at": "2024-01-15T14:30:00Z"
|
||
}
|
||
```
|
||
|
||
**错误响应** (400):
|
||
|
||
```json
|
||
{
|
||
"detail": "评查点编码已存在"
|
||
}
|
||
```
|
||
|
||
**错误响应** (404):
|
||
|
||
```json
|
||
{
|
||
"detail": "评查点分组不存在"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 更新接口
|
||
|
||
### 6. 更新评查点
|
||
|
||
**接口**: `PUT /api/v3/evaluation-points/{id}`
|
||
|
||
**功能**: 更新指定评查点的信息
|
||
|
||
**路径参数**:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| `id` | int | 是 | 评查点ID |
|
||
|
||
**请求头**:
|
||
|
||
```
|
||
Authorization: Bearer <JWT_TOKEN>
|
||
Content-Type: application/json
|
||
```
|
||
|
||
**请求体** (Partial Update):
|
||
|
||
```json
|
||
{
|
||
"name": "测试评查点-test(更新)",
|
||
"suggestion_message": "更新后的建议",
|
||
"is_enabled": false
|
||
}
|
||
```
|
||
|
||
**字段说明**:
|
||
|
||
- 所有字段均为可选
|
||
- 只更新提供的字段
|
||
- `updated_at` 自动更新为当前时间
|
||
|
||
**响应示例** (200 OK):
|
||
|
||
```json
|
||
{
|
||
"id": 693,
|
||
"name": "测试评查点-test(更新)",
|
||
"code": "test-test",
|
||
...
|
||
"suggestion_message": "更新后的建议",
|
||
"is_enabled": false,
|
||
"updated_at": "2024-01-15T16:00:00Z"
|
||
}
|
||
```
|
||
|
||
**错误响应** (404):
|
||
|
||
```json
|
||
{
|
||
"detail": "评查点不存在"
|
||
}
|
||
```
|
||
|
||
**错误响应** (400):
|
||
|
||
```json
|
||
{
|
||
"detail": "评查点编码已被其他评查点使用"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 删除接口
|
||
|
||
### 7. 删除评查点
|
||
|
||
**接口**: `DELETE /api/v3/evaluation-points/{id}`
|
||
|
||
**功能**: 删除指定评查点
|
||
|
||
**路径参数**:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| `id` | int | 是 | 评查点ID |
|
||
|
||
**请求头**:
|
||
|
||
```
|
||
Authorization: Bearer <JWT_TOKEN>
|
||
```
|
||
|
||
**响应示例** (200 OK):
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"message": "评查点删除成功"
|
||
}
|
||
```
|
||
|
||
**错误响应** (404):
|
||
|
||
```json
|
||
{
|
||
"detail": "评查点不存在"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 批量操作接口
|
||
|
||
### 8. 批量更新启用状态
|
||
|
||
**接口**: `PATCH /api/v3/evaluation-points/batch/status`
|
||
|
||
**功能**: 批量更新多个评查点的启用状态
|
||
|
||
**请求头**:
|
||
|
||
```
|
||
Authorization: Bearer <JWT_TOKEN>
|
||
Content-Type: application/json
|
||
```
|
||
|
||
**请求体**:
|
||
|
||
```json
|
||
{
|
||
"ids": [693, 694, 695],
|
||
"is_enabled": false
|
||
}
|
||
```
|
||
|
||
**响应示例** (200 OK):
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"updated_count": 3,
|
||
"message": "批量更新成功"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 9. 批量删除评查点
|
||
|
||
**接口**: `DELETE /api/v3/evaluation-points/batch`
|
||
|
||
**功能**: 批量删除多个评查点
|
||
|
||
**请求头**:
|
||
|
||
```
|
||
Authorization: Bearer <JWT_TOKEN>
|
||
Content-Type: application/json
|
||
```
|
||
|
||
**请求体**:
|
||
|
||
```json
|
||
{
|
||
"ids": [693, 694, 695]
|
||
}
|
||
```
|
||
|
||
**响应示例** (200 OK):
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"deleted_count": 3,
|
||
"message": "批量删除成功"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 10. 批量更新分组
|
||
|
||
**接口**: `PATCH /api/v3/evaluation-points/batch/group`
|
||
|
||
**功能**: 批量移动评查点到其他分组
|
||
|
||
**请求头**:
|
||
|
||
```
|
||
Authorization: Bearer <JWT_TOKEN>
|
||
Content-Type: application/json
|
||
```
|
||
|
||
**请求体**:
|
||
|
||
```json
|
||
{
|
||
"ids": [693, 694, 695],
|
||
"evaluation_point_groups_id": 50,
|
||
"evaluation_point_groups_pid": 2
|
||
}
|
||
```
|
||
|
||
**响应示例** (200 OK):
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"updated_count": 3,
|
||
"message": "批量移动成功"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 11. 复制评查点
|
||
|
||
**接口**: `POST /api/v3/evaluation-points/{id}/copy`
|
||
|
||
**功能**: 复制现有评查点并创建新的评查点
|
||
|
||
**路径参数**:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| `id` | int | 是 | 源评查点ID |
|
||
|
||
**请求体**:
|
||
|
||
```json
|
||
{
|
||
"code": "test-test-copy",
|
||
"name": "测试评查点-test(副本)",
|
||
"evaluation_point_groups_id": 40,
|
||
"evaluation_point_groups_pid": 1
|
||
}
|
||
```
|
||
|
||
**响应示例** (201 Created):
|
||
|
||
```json
|
||
{
|
||
"id": 700,
|
||
"name": "测试评查点-test(副本)",
|
||
"code": "test-test-copy",
|
||
...
|
||
"created_at": "2024-01-15T17:00:00Z"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 错误响应
|
||
|
||
### 标准错误响应格式
|
||
|
||
```json
|
||
{
|
||
"detail": "错误描述信息"
|
||
}
|
||
```
|
||
|
||
### 常见错误码
|
||
|
||
| HTTP 状态码 | 错误场景 | 示例 |
|
||
|------------|---------|------|
|
||
| 400 | 请求参数验证失败 | `{"detail": "评查点名称不能为空"}` |
|
||
| 401 | 未授权(JWT无效) | `{"detail": "未授权访问"}` |
|
||
| 404 | 资源不存在 | `{"detail": "评查点不存在"}` |
|
||
| 409 | 资源冲突 | `{"detail": "评查点编码已存在"}` |
|
||
| 422 | 数据验证失败 | `{"detail": [{"loc": ["body", "risk"], "msg": "必须是high/medium/low"}]}` |
|
||
| 500 | 服务器内部错误 | `{"detail": "服务器错误,请稍后重试"}` |
|
||
|
||
---
|
||
|
||
## 使用示例
|
||
|
||
### 示例 1: 获取评查点列表(带筛选)
|
||
|
||
**请求**:
|
||
|
||
```http
|
||
GET /api/v3/evaluation-points?page=1&page_size=10&risk=low&is_enabled=true&evaluation_point_groups_id=40
|
||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
```
|
||
|
||
---
|
||
|
||
### 示例 2: 创建评查点
|
||
|
||
**请求**:
|
||
|
||
```http
|
||
POST /api/v3/evaluation-points
|
||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"name": "合同名称一致性检查",
|
||
"code": "contract-name-consistency",
|
||
"risk": "medium",
|
||
"is_enabled": true,
|
||
"description": "检查合同封面和正文中的合同名称是否一致",
|
||
"evaluation_point_groups_pid": 1,
|
||
"evaluation_point_groups_id": 33,
|
||
"references_laws": {
|
||
"name": "中华人民共和国合同法",
|
||
"content": "第十条 当事人订立合同,有书面形式、口头形式和其他形式。",
|
||
"articles": ["第十条"]
|
||
},
|
||
"extraction_config": {
|
||
"llm": {
|
||
"fields": ["合同封面-合同名称", "合同正文-合同名称"],
|
||
"prompt_setting": {
|
||
"type": "llm_default_prompt",
|
||
"template": ""
|
||
}
|
||
},
|
||
"vlm": {
|
||
"fields": [],
|
||
"prompt_setting": {
|
||
"type": "vlm_default_prompt",
|
||
"template": ""
|
||
}
|
||
},
|
||
"regex": {
|
||
"fields": []
|
||
}
|
||
},
|
||
"evaluation_config": {
|
||
"logicType": "and",
|
||
"customLogic": "",
|
||
"rules": [
|
||
{
|
||
"id": "1",
|
||
"type": "exists",
|
||
"config": {
|
||
"logic": "and",
|
||
"fields": ["合同封面-合同名称", "合同正文-合同名称"]
|
||
}
|
||
},
|
||
{
|
||
"id": "2",
|
||
"type": "consistency",
|
||
"config": {
|
||
"logic": "and",
|
||
"pairs": [
|
||
{
|
||
"sourceField": "合同封面-合同名称",
|
||
"targetField": "合同正文-合同名称",
|
||
"compareMethod": "exact"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
]
|
||
},
|
||
"pass_message": "合同名称一致",
|
||
"fail_message": "合同封面和正文中的合同名称不一致",
|
||
"suggestion_message": "请确保合同封面和正文中的合同名称完全一致",
|
||
"suggestion_message_type": "warning",
|
||
"post_action": "manual",
|
||
"action_config": "",
|
||
"score": 2
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 示例 3: 批量更新状态
|
||
|
||
**请求**:
|
||
|
||
```http
|
||
PATCH /api/v3/evaluation-points/batch/status
|
||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"ids": [693, 694, 695],
|
||
"is_enabled": false
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 示例 4: 复制评查点
|
||
|
||
**请求**:
|
||
|
||
```http
|
||
POST /api/v3/evaluation-points/693/copy
|
||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"code": "test-test-copy",
|
||
"name": "测试评查点-test(副本)",
|
||
"evaluation_point_groups_id": 40,
|
||
"evaluation_point_groups_pid": 1
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 附录
|
||
|
||
### 性能优化建议
|
||
|
||
1. **查询优化**:
|
||
- 为 `code`、`evaluation_point_groups_id`、`evaluation_point_groups_pid`、`risk`、`is_enabled`、`area` 创建索引
|
||
- 使用分页避免一次性加载大量数据
|
||
- JSONB字段查询使用 GIN 索引
|
||
|
||
2. **缓存策略**:
|
||
- 对不常变化的评查点列表进行缓存(Redis)
|
||
- 缓存键格式: `eval_points:group:{group_id}`, `eval_points:{id}`
|
||
- 创建/更新/删除操作时清除相关缓存
|
||
|
||
3. **批量操作**:
|
||
- 使用批量查询减少数据库连接开销
|
||
- 使用事务确保批量操作的原子性
|
||
|
||
### 数据库索引建议
|
||
|
||
```sql
|
||
-- 基础索引(已存在)
|
||
CREATE UNIQUE INDEX evaluation_points_code_key ON evaluation_points(code);
|
||
CREATE INDEX idx_evaluation_points_area ON evaluation_points(area);
|
||
|
||
-- 推荐新增索引
|
||
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);
|
||
CREATE INDEX idx_evaluation_points_risk ON evaluation_points(risk);
|
||
CREATE INDEX idx_evaluation_points_is_enabled ON evaluation_points(is_enabled);
|
||
CREATE INDEX idx_evaluation_points_created_at ON evaluation_points(created_at DESC);
|
||
|
||
-- JSONB字段索引(用于复杂查询)
|
||
CREATE INDEX idx_evaluation_points_extraction_config ON evaluation_points USING GIN (extraction_config);
|
||
CREATE INDEX idx_evaluation_points_evaluation_config ON evaluation_points USING GIN (evaluation_config);
|
||
CREATE INDEX idx_evaluation_points_references_laws ON evaluation_points USING GIN (references_laws);
|
||
```
|
||
|
||
### 前端PostgREST vs 后端FastAPI对比
|
||
|
||
| 功能 | PostgREST 前端实现 | FastAPI 后端实现 |
|
||
|------|-------------------|-----------------|
|
||
| 认证方式 | 前端传递 JWT | 后端验证 JWT |
|
||
| 数据验证 | 前端验证 | 前后端双重验证 |
|
||
| JSONB处理 | 前端序列化 | 后端自动处理 |
|
||
| 批量操作 | 前端多次调用 | 后端事务处理 |
|
||
| 复制功能 | 前端实现 | 后端一次性完成 |
|
||
| 错误处理 | 前端解析错误 | 后端统一错误格式 |
|
||
| 分组验证 | 前端验证 | 后端外键约束验证 |
|
||
|
||
---
|
||
|
||
**文档版本**: v1.0
|
||
**最后更新**: 2025-01-21
|
||
**维护者**: DocAuditAI Team
|