fix: 1. 重新对齐交叉评查的接口。

2. 确认评查结果的接口对接。 3. 新增评查点适配省级创建的响应数据和其他用户创建的单条响应数据。  4. 文档列表的文档类型通过通用的查询接口查询文档类型。优化加载状态的时机。
This commit is contained in:
2025-12-11 11:16:50 +08:00
parent ba517d7b9c
commit d8bba607fc
18 changed files with 3435 additions and 1086 deletions
+741
View File
@@ -0,0 +1,741 @@
# 评查审核接口对接文档
> 版本:v1.0
> 更新时间:2024-12-10
> 模块:评查审核(Evaluation Audit
---
## 一、接口总览
| 序号 | 接口名称 | 方法 | 路径 | 功能说明 |
| ---- | ------------ | --------- | ----------------------------------------------- | ---------------------------- |
| 1 | 更新评查结果 | `PATCH` | `/admin/v2/evaluation/results/{result_id}` | 修改评查结果的通过状态和说明 |
| 2 | 创建审核状态 | `POST` | `/admin/v2/evaluation/audit-status` | 记录人工审核操作 |
| 3 | 更新审核状态 | `PATCH` | `/admin/v2/evaluation/audit-status/{id}` | 更新已有的审核状态记录 |
| 4 | 确认文档审核 | `PATCH` | `/admin/v2/evaluation/documents/{id}/confirm` | 确认文档整体审核完成 |
---
## 二、通用说明
### 2.1 请求头
所有接口都需要携带 JWT Token:
```http
Authorization: Bearer <your_jwt_token>
Content-Type: application/json
```
### 2.2 基础路径
```
开发环境: http://localhost:8000
生产环境: https://your-domain.com
```
### 2.3 通用响应格式
**成功响应**
```json
{
"success": true,
"message": "操作成功",
"data": { ... }
}
```
**错误响应**
```json
{
"detail": "错误信息"
}
```
### 2.4 HTTP 状态码
| 状态码 | 说明 |
| ------ | -------------- |
| 200 | 请求成功 |
| 400 | 请求参数错误 |
| 403 | 无权限访问 |
| 404 | 资源不存在 |
| 500 | 服务器内部错误 |
---
## 三、接口详细说明
---
### 3.1 更新评查结果
**功能说明**:人工审核时,修改某个评查点的评查结果(通过/不通过)和说明信息。
#### 请求信息
| 项目 | 说明 |
| -------- | --------------------------------------------- |
| 请求路径 | `/admin/v2/evaluations/results/{result_id}` |
| 请求方法 | `PATCH` |
| 权限要求 | 用户必须对该文档有访问权限 |
#### 路径参数
| 参数名 | 类型 | 必填 | 说明 |
| --------- | ------- | ---- | ----------------------------------------- |
| result_id | integer | 是 | 评查结果IDevaluation_results 表的主键) |
#### 请求体参数
| 参数名 | 类型 | 必填 | 说明 |
| ----------- | ------ | ---- | ----------------------------------------- |
| result | string | 否 | 评查结果,可选值:`"pass"` / `"fail"` |
| message | string | 否 | 评查结果说明(人工审核备注) |
| final_score | float | 否 | 最终分数(人工修正后的分数) |
#### 请求示例
```http
PATCH /admin/v2/evaluation/results/123
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json
{
"result": "pass",
"message": "",
"final_score": 100.0
}
```
#### 响应示例
**成功响应** (200)
```json
{
"success": true,
"message": "评查结果更新成功",
"data": {
"result_id": 123,
"updated_fields": ["evaluated_results", "final_score"]
}
}
```
**错误响应** (404)
```json
{
"detail": "评查结果 123 不存在"
}
```
**错误响应** (403)
```json
{
"detail": "无权修改此评查结果"
}
```
#### 业务逻辑
```
1. 接收请求,验证 JWT Token
2. 根据 result_id 查询 evaluation_results 表
3. 获取该评查结果关联的 document_id
4. 验证当前用户是否有权限访问该文档:
- 是文档上传者
- 或是交叉评查任务的参与者
5. 更新 evaluation_results 表:
- evaluated_results.result = 请求的 result
- evaluated_results.message = 请求的 message
- final_score = 请求的 final_score
6. 返回更新结果
```
#### 数据库变更
更新 `evaluation_results` 表:
- `evaluated_results` (JSONB): 更新其中的 `result``message` 字段
- `final_score` (float): 更新最终分数
---
### 3.2 创建审核状态
**功能说明**:记录用户对某个评查点的人工审核操作,用于追踪审核历史。
#### 请求信息
| 项目 | 说明 |
| -------- | -------------------------------------- |
| 请求路径 | `/admin/v2/evaluations/audit-status` |
| 请求方法 | `POST` |
| 权限要求 | 用户必须对该文档有访问权限 |
#### 请求体参数
| 参数名 | 类型 | 必填 | 说明 |
| -------------------- | ------- | ---- | ------------------------------------ |
| document_id | integer | 是 | 文档ID |
| evaluation_point_id | integer | 是 | 评查点ID |
| evaluation_result_id | integer | 是 | 评查结果ID |
| edit_audit_status | integer | 是 | 审核状态:`0`=未审核,`1`=已审核 |
| message | string | 否 | 操作记录文本(最大255字符) |
#### 请求示例
```http
POST /admin/v2/evaluation/audit-status
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json
{
"document_id": 456,
"evaluation_point_id": 789,
"evaluation_result_id": 123,
"edit_audit_status": 1,
"message": ""
}
```
#### 响应示例
**成功响应** (200)
```json
{
"id": 1,
"user_id": 10,
"document_id": 456,
"evaluation_point_id": 789,
"evaluation_result_id": 123,
"edit_audit_status": 1,
"message": "已完成人工审核,确认通过",
"created_at": "2024-12-10T10:30:00+08:00",
"updated_at": "2024-12-10T10:30:00+08:00"
}
```
**错误响应** (403)
```json
{
"detail": "无权操作此文档的审核状态"
}
```
#### 业务逻辑
```
1. 接收请求,验证 JWT Token
2. 验证当前用户是否有权限访问 document_id 对应的文档
3. 在 audit_status 表中插入新记录:
- user_id = 当前登录用户ID(自动填充)
- document_id = 请求的 document_id
- evaluation_point_id = 请求的 evaluation_point_id
- evaluation_result_id = 请求的 evaluation_result_id
- edit_audit_status = 请求的 edit_audit_status
- message = 请求的 message
4. 返回创建的记录
```
#### 数据库变更
`audit_status` 表中插入新记录
#### 前端使用场景
当用户点击"通过"或"不通过"按钮时:
1. 先调用 **3.1 更新评查结果** 更新结果
2. 再调用 **3.2 创建审核状态** 记录操作
---
### 3.3 更新审核状态
**功能说明**:更新已有的审核状态记录,用于"重新审核"等场景。
#### 请求信息
| 项目 | 说明 |
| -------- | -------------------------------------------------------- |
| 请求路径 | `/admin/v2/evaluations/audit-status/{audit_status_id}` |
| 请求方法 | `PATCH` |
| 权限要求 | 用户必须是该记录的创建者,或对关联文档有访问权限 |
#### 路径参数
| 参数名 | 类型 | 必填 | 说明 |
| --------------- | ------- | ---- | ----------------------------------- |
| audit_status_id | integer | 是 | 审核状态IDaudit_status 表的主键) |
#### 请求体参数
| 参数名 | 类型 | 必填 | 说明 |
| ----------------- | ------- | ---- | ------------------------------------ |
| edit_audit_status | integer | 否 | 审核状态:`0`=未审核,`1`=已审核 |
| message | string | 否 | 操作记录文本(最大255字符) |
#### 请求示例
```http
PATCH /admin/v2/evaluation/audit-status/1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json
{
"edit_audit_status": 1,
"message": ""
}
```
#### 响应示例
**成功响应** (200)
```json
{
"success": true,
"message": "审核状态更新成功",
"data": {
"audit_status_id": 1,
"updated_fields": ["edit_audit_status", "message"]
}
}
```
**错误响应** (404)
```json
{
"detail": "审核状态记录 1 不存在"
}
```
#### 业务逻辑
```
1. 接收请求,验证 JWT Token
2. 根据 audit_status_id 查询 audit_status 表
3. 验证权限:
- 如果是自己创建的记录,允许更新
- 如果不是自己的记录,检查是否有关联文档的访问权限
4. 更新 audit_status 表对应记录
5. 返回更新结果
```
#### 数据库变更
更新 `audit_status` 表:
- `edit_audit_status`: 审核状态
- `message`: 操作记录
- `updated_at`: 自动更新(数据库触发器)
---
### 3.4 确认文档审核完成
**功能说明**:确认整个文档的审核完成,更新文档的审核状态字段。
#### 请求信息
| 项目 | 说明 |
| -------- | --------------------------------------------------------- |
| 请求路径 | `/admin/v2/evaluations/documents/{document_id}/confirm` |
| 请求方法 | `PATCH` |
| 权限要求 | 用户必须对该文档有访问权限 |
#### 路径参数
| 参数名 | 类型 | 必填 | 说明 |
| ----------- | ------- | ---- | ------ |
| document_id | integer | 是 | 文档ID |
#### 请求体参数
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
| ------------ | ------- | ---- | ------ | ------------------------ |
| audit_status | integer | 否 | 1 | 审核状态:`1`=审核完成 |
#### 请求示例
```http
PATCH /admin/v2/evaluation/documents/456/confirm
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json
{
"audit_status": 1
}
```
或者使用默认值(不传请求体):
```http
PATCH /admin/v2/evaluation/documents/456/confirm
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json
{}
```
#### 响应示例
**成功响应** (200)
```json
{
"success": true,
"message": "文档审核确认成功",
"data": {
"document_id": 456,
"audit_status": 1
}
}
```
**错误响应** (403)
```json
{
"detail": "无权确认此文档的审核状态"
}
```
#### 业务逻辑
```
1. 接收请求,验证 JWT Token
2. 验证当前用户是否有权限访问 document_id 对应的文档
3. 更新 documents 表的 audit_status 字段
4. 返回更新结果
```
#### 数据库变更
更新 `documents` 表:
- `audit_status`: 设置为 1(审核完成)
---
## 四、完整业务流程
### 4.1 人工审核单个评查点
```mermaid
sequenceDiagram
participant 前端
participant 后端
participant 数据库
前端->>后端: PATCH /results/{id} (修改评查结果)
后端->>数据库: 验证权限
后端->>数据库: 更新 evaluation_results
后端-->>前端: 返回成功
前端->>后端: POST /audit-status (记录审核操作)
后端->>数据库: 插入 audit_status
后端-->>前端: 返回创建的记录
```
### 4.2 确认文档整体审核完成
```mermaid
sequenceDiagram
participant 前端
participant 后端
participant 数据库
Note over 前端: 用户完成所有评查点审核后
前端->>后端: PATCH /documents/{id}/confirm
后端->>数据库: 验证权限
后端->>数据库: 更新 documents.audit_status = 1
后端-->>前端: 返回成功
```
### 4.3 前端调用示例(TypeScript/Axios
```typescript
import axios from 'axios';
const API_BASE = '/admin/v2/evaluation';
// 获取 JWT Token
const getToken = () => localStorage.getItem('token');
// 创建 axios 实例
const api = axios.create({
headers: {
'Content-Type': 'application/json',
},
});
// 添加请求拦截器
api.interceptors.request.use((config) => {
const token = getToken();
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
/**
* 更新评查结果
* @param resultId 评查结果ID
* @param data 更新数据
*/
export async function updateEvaluationResult(
resultId: number,
data: {
result?: 'pass' | 'fail';
message?: string;
final_score?: number;
}
) {
const response = await api.patch(`${API_BASE}/results/${resultId}`, data);
return response.data;
}
/**
* 创建审核状态记录
* @param data 审核状态数据
*/
export async function createAuditStatus(data: {
document_id: number;
evaluation_point_id: number;
evaluation_result_id: number;
edit_audit_status: 0 | 1;
message?: string;
}) {
const response = await api.post(`${API_BASE}/audit-status`, data);
return response.data;
}
/**
* 更新审核状态记录
* @param auditStatusId 审核状态ID
* @param data 更新数据
*/
export async function updateAuditStatus(
auditStatusId: number,
data: {
edit_audit_status?: 0 | 1;
message?: string;
}
) {
const response = await api.patch(`${API_BASE}/audit-status/${auditStatusId}`, data);
return response.data;
}
/**
* 确认文档审核完成
* @param documentId 文档ID
*/
export async function confirmDocumentReview(documentId: number) {
const response = await api.patch(`${API_BASE}/documents/${documentId}/confirm`, {
audit_status: 1,
});
return response.data;
}
// ============================================
// 业务场景示例
// ============================================
/**
* 场景1:用户点击"通过"按钮
*/
async function handlePassClick(
documentId: number,
evaluationPointId: number,
evaluationResultId: number
) {
try {
// 1. 更新评查结果为"通过"
await updateEvaluationResult(evaluationResultId, {
result: 'pass',
message: '人工审核通过',
final_score: 100,
});
// 2. 记录审核操作
await createAuditStatus({
document_id: documentId,
evaluation_point_id: evaluationPointId,
evaluation_result_id: evaluationResultId,
edit_audit_status: 1,
message: '用户确认通过',
});
console.log('审核成功');
} catch (error) {
console.error('审核失败:', error);
}
}
/**
* 场景2:用户点击"不通过"按钮
*/
async function handleFailClick(
documentId: number,
evaluationPointId: number,
evaluationResultId: number,
reason: string
) {
try {
// 1. 更新评查结果为"不通过"
await updateEvaluationResult(evaluationResultId, {
result: 'fail',
message: reason,
final_score: 0,
});
// 2. 记录审核操作
await createAuditStatus({
document_id: documentId,
evaluation_point_id: evaluationPointId,
evaluation_result_id: evaluationResultId,
edit_audit_status: 1,
message: `用户确认不通过: ${reason}`,
});
console.log('审核成功');
} catch (error) {
console.error('审核失败:', error);
}
}
/**
* 场景3:用户完成所有评查点审核,点击"确认完成"
*/
async function handleConfirmAllClick(documentId: number) {
try {
await confirmDocumentReview(documentId);
console.log('文档审核确认成功');
} catch (error) {
console.error('确认失败:', error);
}
}
```
---
## 五、数据库表结构参考
### 5.1 evaluation_results 表
| 字段名 | 类型 | 说明 |
| --------------------------- | --------------- | -------------------------------------------- |
| id | integer | 主键 |
| document_id | integer | 文档ID |
| evaluation_point_id | integer | 评查点ID |
| status | varchar(20) | 状态 |
| extracted_results | jsonb | 抽取结果 |
| rules_results | jsonb | 规则判断结果 |
| **evaluated_results** | **jsonb** | **评查结果(包含 result 和 message** |
| **final_score** | **float** | **最终分数** |
| machine_score | float | 机器评查分数 |
| created_at | timestamp | 创建时间 |
| updated_at | timestamp | 更新时间 |
**evaluated_results 字段结构**
```json
{
"result": "pass", // 评查结果:pass/fail
"message": "说明信息" // 评查结果说明
}
```
### 5.2 audit_status 表
| 字段名 | 类型 | 说明 |
| --------------------------- | ---------------------- | ---------------------------------- |
| id | integer | 主键 |
| user_id | integer | 操作用户ID |
| document_id | integer | 文档ID |
| evaluation_point_id | integer | 评查点ID |
| evaluation_result_id | integer | 评查结果ID |
| **edit_audit_status** | **integer** | **审核状态(0=未审核,1=已审核)** |
| **message** | **varchar(255)** | **操作记录文本** |
| created_at | timestamp | 创建时间 |
| updated_at | timestamp | 更新时间 |
### 5.3 documents 表(相关字段)
| 字段名 | 类型 | 说明 |
| ---------------------- | ----------------- | ---------------------------------- |
| id | integer | 主键 |
| **audit_status** | **integer** | **审核状态(0=待审核,1=已完成)** |
| ... | ... | 其他字段省略 |
---
## 六、错误处理
### 6.1 常见错误码
| HTTP 状态码 | detail 示例 | 原因 | 解决方案 |
| ----------- | ----------------------- | ------------------ | ---------------------------------------- |
| 403 | "无权修改此评查结果" | 用户无权访问该文档 | 检查用户是否是文档上传者或交叉评查参与者 |
| 404 | "评查结果 123 不存在" | 评查结果ID不存在 | 检查传入的 result_id 是否正确 |
| 404 | "审核状态记录 1 不存在" | 审核状态ID不存在 | 检查传入的 audit_status_id 是否正确 |
| 422 | "field required" | 缺少必填字段 | 检查请求体是否包含所有必填字段 |
| 500 | "更新评查结果失败: ..." | 服务器内部错误 | 查看服务器日志排查问题 |
### 6.2 前端错误处理示例
```typescript
try {
await updateEvaluationResult(resultId, data);
} catch (error) {
if (axios.isAxiosError(error)) {
const status = error.response?.status;
const detail = error.response?.data?.detail;
switch (status) {
case 403:
alert('您没有权限执行此操作');
break;
case 404:
alert('记录不存在,请刷新页面后重试');
break;
case 422:
alert('请求参数错误,请检查输入');
break;
default:
alert(`操作失败: ${detail || '未知错误'}`);
}
}
}
```
---
## 七、注意事项
1. **权限验证**:所有接口都会验证用户对文档的访问权限,前端无需额外处理权限逻辑
2. **字段更新**:PATCH 接口只更新传入的字段,未传入的字段保持不变
3. **操作顺序**:建议先调用"更新评查结果",再调用"创建审核状态"
4. **审核状态值**
- `edit_audit_status = 0`:未审核(按钮显示"通过/不通过"
- `edit_audit_status = 1`:已审核(按钮显示"重新审核")
5. **文档 audit_status**
- `audit_status = 0`:待人工确认
- `audit_status = 1`:审核完成
---
## 八、联系方式
如有问题,请联系后端开发人员。