Files
TanWenyan d3b9403d64 feat(evaluation): 模块1.1 - 增强评查点分组查询接口
## 主要改进

### 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>
2025-11-25 12:06:48 +08:00

33 KiB
Raw Permalink Blame History

评查点管理 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() 更新时间

外键关系

-- 二级分组外键
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 - 引用法典

数据结构:

{
  "name": string,        // 法律法规名称
  "content": string,     // 法律法规内容
  "articles": string[]   // 条款列表
}

示例:

{
  "name": "中华人民共和国合同法",
  "content": "第十条 当事人订立合同,有书面形式、口头形式和其他形式。",
  "articles": ["第十条", "第十一条"]
}

2. extraction_config - 抽取配置

数据结构:

{
  "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",后端可处理):

{
  "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",后端不处理⚠️:

{
  "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 - 评查设置

数据结构:

{
  "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 规则中的 modeltemperature 字段仅用于前端界面显示和标识
  • 后端实际使用环境配置中的 DEFAULT_LLM_MODEL 和默认温度参数(0.6)
  • 如需切换AI模型,需修改后端配置文件,而非评查点配置

示例1:综合规则配置:

{
  "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评查:

{
  "logicType": "and",
  "customLogic": "",
  "rules": [
    {
      "id": "1",
      "type": "ai",
      "config": {
        "model": "qwen14b",
        "prompt": "请判断以下{文本、印刷体大模型评查-正文-内容}是否包含了时间地点人物事情工具的四要素,仅回答\"符合\"或\"不符合\",并简要说明理由。",
        "temperature": 0.1
      }
    }
  ]
}

Pydantic 数据模型

EvaluationPointBase - 基础模型

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 - 创建请求模型

class EvaluationPointCreate(EvaluationPointBase):
    """创建评查点请求"""
    pass

EvaluationPointUpdate - 更新请求模型

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 - 响应模型

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 - 列表响应模型

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 - 所属地区

响应示例:

{
  "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 等价:

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):

{
  "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

响应示例:

{
  "group_id": 40,
  "count": 15
}

创建接口

5. 创建评查点

接口: POST /api/v3/evaluation-points

功能: 创建新的评查点

请求头:

Authorization: Bearer <JWT_TOKEN>
Content-Type: application/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):

{
  "id": 694,
  "name": "测试评查点-test",
  "code": "test-test",
  ...
  "created_at": "2024-01-15T14:30:00Z",
  "updated_at": "2024-01-15T14:30:00Z"
}

错误响应 (400):

{
  "detail": "评查点编码已存在"
}

错误响应 (404):

{
  "detail": "评查点分组不存在"
}

更新接口

6. 更新评查点

接口: PUT /api/v3/evaluation-points/{id}

功能: 更新指定评查点的信息

路径参数:

参数名 类型 必填 说明
id int 评查点ID

请求头:

Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json

请求体 (Partial Update):

{
  "name": "测试评查点-test(更新)",
  "suggestion_message": "更新后的建议",
  "is_enabled": false
}

字段说明:

  • 所有字段均为可选
  • 只更新提供的字段
  • updated_at 自动更新为当前时间

响应示例 (200 OK):

{
  "id": 693,
  "name": "测试评查点-test(更新)",
  "code": "test-test",
  ...
  "suggestion_message": "更新后的建议",
  "is_enabled": false,
  "updated_at": "2024-01-15T16:00:00Z"
}

错误响应 (404):

{
  "detail": "评查点不存在"
}

错误响应 (400):

{
  "detail": "评查点编码已被其他评查点使用"
}

删除接口

7. 删除评查点

接口: DELETE /api/v3/evaluation-points/{id}

功能: 删除指定评查点

路径参数:

参数名 类型 必填 说明
id int 评查点ID

请求头:

Authorization: Bearer <JWT_TOKEN>

响应示例 (200 OK):

{
  "success": true,
  "message": "评查点删除成功"
}

错误响应 (404):

{
  "detail": "评查点不存在"
}

批量操作接口

8. 批量更新启用状态

接口: PATCH /api/v3/evaluation-points/batch/status

功能: 批量更新多个评查点的启用状态

请求头:

Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json

请求体:

{
  "ids": [693, 694, 695],
  "is_enabled": false
}

响应示例 (200 OK):

{
  "success": true,
  "updated_count": 3,
  "message": "批量更新成功"
}

9. 批量删除评查点

接口: DELETE /api/v3/evaluation-points/batch

功能: 批量删除多个评查点

请求头:

Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json

请求体:

{
  "ids": [693, 694, 695]
}

响应示例 (200 OK):

{
  "success": true,
  "deleted_count": 3,
  "message": "批量删除成功"
}

10. 批量更新分组

接口: PATCH /api/v3/evaluation-points/batch/group

功能: 批量移动评查点到其他分组

请求头:

Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json

请求体:

{
  "ids": [693, 694, 695],
  "evaluation_point_groups_id": 50,
  "evaluation_point_groups_pid": 2
}

响应示例 (200 OK):

{
  "success": true,
  "updated_count": 3,
  "message": "批量移动成功"
}

11. 复制评查点

接口: POST /api/v3/evaluation-points/{id}/copy

功能: 复制现有评查点并创建新的评查点

路径参数:

参数名 类型 必填 说明
id int 源评查点ID

请求体:

{
  "code": "test-test-copy",
  "name": "测试评查点-test(副本)",
  "evaluation_point_groups_id": 40,
  "evaluation_point_groups_pid": 1
}

响应示例 (201 Created):

{
  "id": 700,
  "name": "测试评查点-test(副本)",
  "code": "test-test-copy",
  ...
  "created_at": "2024-01-15T17:00:00Z"
}

错误响应

标准错误响应格式

{
  "detail": "错误描述信息"
}

常见错误码

HTTP 状态码 错误场景 示例
400 请求参数验证失败 {"detail": "评查点名称不能为空"}
401 未授权(JWT无效) {"detail": "未授权访问"}
404 资源不存在 {"detail": "评查点不存在"}
409 资源冲突 {"detail": "评查点编码已存在"}
422 数据验证失败 {"detail": [{"loc": ["body", "risk"], "msg": "必须是high/medium/low"}]}
500 服务器内部错误 {"detail": "服务器错误,请稍后重试"}

使用示例

示例 1: 获取评查点列表(带筛选)

请求:

GET /api/v3/evaluation-points?page=1&page_size=10&risk=low&is_enabled=true&evaluation_point_groups_id=40
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

示例 2: 创建评查点

请求:

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: 批量更新状态

请求:

PATCH /api/v3/evaluation-points/batch/status
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json

{
  "ids": [693, 694, 695],
  "is_enabled": false
}

示例 4: 复制评查点

请求:

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. 查询优化:

    • codeevaluation_point_groups_idevaluation_point_groups_pidriskis_enabledarea 创建索引
    • 使用分页避免一次性加载大量数据
    • JSONB字段查询使用 GIN 索引
  2. 缓存策略:

    • 对不常变化的评查点列表进行缓存(Redis)
    • 缓存键格式: eval_points:group:{group_id}, eval_points:{id}
    • 创建/更新/删除操作时清除相关缓存
  3. 批量操作:

    • 使用批量查询减少数据库连接开销
    • 使用事务确保批量操作的原子性

数据库索引建议

-- 基础索引(已存在)
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