From d5a7674a9a6c88c705a4521ded2a672c57d02656 Mon Sep 17 00:00:00 2001 From: Wenyan Date: Tue, 25 Nov 2025 20:10:30 +0800 Subject: [PATCH] =?UTF-8?q?feat(rule-groups):=20=E6=B7=BB=E5=8A=A0=20FastA?= =?UTF-8?q?PI=20v3=20=E8=AF=84=E6=9F=A5=E7=82=B9=E5=88=86=E7=BB=84?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增功能: - 添加 9 个 FastAPI v3 接口函数到 rule-groups.ts - 导入 apiRequest 用于调用后端 API 接口列表: 1. getEvaluationPointGroups - 获取一级分组列表 (GET /api/v3/evaluation-point-groups) 2. getAllEvaluationPointGroups - 获取树形结构 (GET /api/v3/evaluation-point-groups/all) 3. getEvaluationPointGroup - 获取单个分组详情 (GET /api/v3/evaluation-point-groups/{id}) 4. getEvaluationPointGroupChildren - 获取子分组列表 (GET /api/v3/evaluation-point-groups/{parent_id}/children) 5. createEvaluationPointGroup - 创建分组 (POST /api/v3/evaluation-point-groups) 6. updateEvaluationPointGroup - 更新分组 (PUT /api/v3/evaluation-point-groups/{id}) 7. deleteEvaluationPointGroup - 删除分组 (DELETE /api/v3/evaluation-point-groups/{id}) 8. batchUpdateEvaluationPointGroupStatus - 批量更新状态 (PATCH /api/v3/evaluation-point-groups/batch/status) 9. batchDeleteEvaluationPointGroups - 批量删除 (DELETE /api/v3/evaluation-point-groups/batch) 技术细节: - 新增 EvaluationPointGroupResponse 接口定义响应格式 - 新增 convertApiGroupToRuleGroup 转换函数 - 所有函数支持 JWT token 认证 - 统一的错误处理和日志输出 - 保留旧的 PostgREST 函数作为备份 相关文档: - docs/evaluation/evaluation_point_groups.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- app/api/evaluation_points/rule-groups.ts | 521 ++++++++++++++++++++++- 1 file changed, 520 insertions(+), 1 deletion(-) diff --git a/app/api/evaluation_points/rule-groups.ts b/app/api/evaluation_points/rule-groups.ts index 84ba814..e8b8273 100644 --- a/app/api/evaluation_points/rule-groups.ts +++ b/app/api/evaluation_points/rule-groups.ts @@ -1,4 +1,5 @@ import { postgrestGet, postgrestPost, postgrestPut, postgrestDelete, type PostgrestParams } from '../postgrest-client'; +import { apiRequest } from '../axios-client'; import { formatDate } from '../../utils'; /** @@ -1137,4 +1138,522 @@ export async function batchDeleteRuleGroups( }] }; } -} \ No newline at end of file +} + +// ======================================== +// FastAPI v3 接口函数(新版) +// ======================================== + +/** + * FastAPI v3 响应数据格式 + */ +interface EvaluationPointGroupResponse { + id: number; + pid: number | null; + name: string; + code: string; + description: string | null; + is_enabled: boolean; + created_at: string; + updated_at: string; + rule_count?: number | null; + children?: EvaluationPointGroupResponse[] | null; +} + +interface EvaluationPointGroupListResponse { + data: EvaluationPointGroupResponse[]; + total: number; + page: number; + page_size: number; +} + +/** + * 转换 API 响应数据为前端格式 + */ +function convertApiGroupToRuleGroup(apiGroup: EvaluationPointGroupResponse): RuleGroup { + return { + id: String(apiGroup.id), + pid: apiGroup.pid !== null ? String(apiGroup.pid) : '0', + name: apiGroup.name, + code: apiGroup.code, + description: apiGroup.description || undefined, + is_enabled: apiGroup.is_enabled, + createdAt: apiGroup.created_at, + ruleCount: apiGroup.rule_count !== null && apiGroup.rule_count !== undefined ? apiGroup.rule_count : undefined, + children: apiGroup.children ? apiGroup.children.map(convertApiGroupToRuleGroup) : undefined + }; +} + +/** + * 1. 获取一级分组列表(FastAPI v3) + * @param params 查询参数 + * @param token JWT token + * @returns 一级分组列表 + */ +export async function getEvaluationPointGroups( + params?: RuleGroupQueryParams, + token?: string +): Promise<{data: RuleGroup[]; totalCount?: number; error?: never} | {data?: never; error: string; status?: number}> { + try { + const { + page = 1, + pageSize = 20, + name, + code, + is_enabled, + orderBy = 'created_at', + order = 'desc' + } = params || {}; + + // 构建查询参数 + const queryParams = new URLSearchParams(); + queryParams.append('page', String(page)); + queryParams.append('page_size', String(pageSize)); + if (name) queryParams.append('name', name); + if (code) queryParams.append('code', code); + if (is_enabled !== undefined) queryParams.append('is_enabled', String(is_enabled)); + + const url = `/api/v3/evaluation-point-groups?${queryParams.toString()}`; + + const response = await apiRequest(url, { + method: 'GET', + headers: token ? { 'Authorization': `Bearer ${token}` } : {} + }); + + if (response.error) { + return { error: response.error, status: response.status }; + } + + if (response.data) { + const ruleGroups = response.data.data.map(convertApiGroupToRuleGroup); + return { + data: ruleGroups, + totalCount: response.data.total + }; + } + + return { error: '获取一级分组列表失败:返回数据格式不正确', status: 500 }; + } catch (error) { + console.error('❌ 获取一级分组列表出错:', error); + return { + error: error instanceof Error ? error.message : '获取一级分组列表失败', + status: 500 + }; + } +} + +/** + * 2. 获取所有分组(树形结构)(FastAPI v3) + * @param includeDisabled 是否包含禁用的分组 + * @param withRuleCount 是否返回评查点数量 + * @param token JWT token + * @returns 树形分组结构 + */ +export async function getAllEvaluationPointGroups( + includeDisabled: boolean = false, + withRuleCount: boolean = true, + token?: string +): Promise<{data: RuleGroup[]; error?: never} | {data?: never; error: string; status?: number}> { + try { + const queryParams = new URLSearchParams(); + queryParams.append('include_disabled', String(includeDisabled)); + queryParams.append('with_rule_count', String(withRuleCount)); + + const url = `/api/v3/evaluation-point-groups/all?${queryParams.toString()}`; + + const response = await apiRequest(url, { + method: 'GET', + headers: token ? { 'Authorization': `Bearer ${token}` } : {} + }); + + if (response.error) { + return { error: response.error, status: response.status }; + } + + if (response.data) { + const ruleGroups = response.data.data.map(convertApiGroupToRuleGroup); + return { data: ruleGroups }; + } + + return { error: '获取分组树形结构失败:返回数据格式不正确', status: 500 }; + } catch (error) { + console.error('❌ 获取分组树形结构出错:', error); + return { + error: error instanceof Error ? error.message : '获取分组树形结构失败', + status: 500 + }; + } +} + +/** + * 3. 获取单个分组详情(FastAPI v3) + * @param id 分组ID + * @param withRuleCount 是否返回评查点数量 + * @param token JWT token + * @returns 分组详情 + */ +export async function getEvaluationPointGroup( + id: string, + withRuleCount: boolean = true, + token?: string +): Promise<{data: RuleGroup; error?: never} | {data?: never; error: string; status?: number}> { + try { + const queryParams = new URLSearchParams(); + queryParams.append('with_rule_count', String(withRuleCount)); + + const url = `/api/v3/evaluation-point-groups/${id}?${queryParams.toString()}`; + + const response = await apiRequest(url, { + method: 'GET', + headers: token ? { 'Authorization': `Bearer ${token}` } : {} + }); + + if (response.error) { + return { error: response.error, status: response.status }; + } + + if (response.data) { + const ruleGroup = convertApiGroupToRuleGroup(response.data); + return { data: ruleGroup }; + } + + return { error: '获取分组详情失败:返回数据格式不正确', status: 500 }; + } catch (error) { + console.error('❌ 获取分组详情出错:', error); + return { + error: error instanceof Error ? error.message : '获取分组详情失败', + status: 500 + }; + } +} + +/** + * 4. 获取子分组列表(FastAPI v3) + * @param parentId 父分组ID + * @param params 查询参数 + * @param token JWT token + * @returns 子分组列表 + */ +export async function getEvaluationPointGroupChildren( + parentId: string, + params?: { page?: number; pageSize?: number; is_enabled?: boolean }, + token?: string +): Promise<{data: RuleGroup[]; totalCount?: number; error?: never} | {data?: never; error: string; status?: number}> { + try { + const { + page = 1, + pageSize = 20, + is_enabled + } = params || {}; + + const queryParams = new URLSearchParams(); + queryParams.append('page', String(page)); + queryParams.append('page_size', String(pageSize)); + if (is_enabled !== undefined) queryParams.append('is_enabled', String(is_enabled)); + + const url = `/api/v3/evaluation-point-groups/${parentId}/children?${queryParams.toString()}`; + + const response = await apiRequest(url, { + method: 'GET', + headers: token ? { 'Authorization': `Bearer ${token}` } : {} + }); + + if (response.error) { + return { error: response.error, status: response.status }; + } + + if (response.data) { + const ruleGroups = response.data.data.map(convertApiGroupToRuleGroup); + return { + data: ruleGroups, + totalCount: response.data.total + }; + } + + return { error: '获取子分组列表失败:返回数据格式不正确', status: 500 }; + } catch (error) { + console.error('❌ 获取子分组列表出错:', error); + return { + error: error instanceof Error ? error.message : '获取子分组列表失败', + status: 500 + }; + } +} + +/** + * 5. 创建评查点分组(FastAPI v3) + * @param groupData 分组数据 + * @param token JWT token + * @returns 创建后的分组数据 + */ +export async function createEvaluationPointGroup( + groupData: RuleGroupCreateUpdateDto, + token?: string +): Promise<{data: RuleGroup; error?: never} | {data?: never; error: string; status?: number}> { + try { + // 转换为 API 格式 + const apiGroup = { + name: groupData.name, + code: groupData.code, + pid: groupData.pid === null || groupData.pid === '0' ? null : Number(groupData.pid), + description: groupData.description || null, + is_enabled: groupData.is_enabled !== undefined ? groupData.is_enabled : true + }; + + const response = await apiRequest( + '/api/v3/evaluation-point-groups', + { + method: 'POST', + body: JSON.stringify(apiGroup), + headers: { + 'Content-Type': 'application/json', + ...(token ? { 'Authorization': `Bearer ${token}` } : {}) + } + } + ); + + if (response.error) { + return { error: response.error, status: response.status }; + } + + if (response.data) { + const ruleGroup = convertApiGroupToRuleGroup(response.data); + console.log('✅ createEvaluationPointGroup 成功:', ruleGroup); + return { data: ruleGroup }; + } + + return { error: '创建分组失败:返回数据格式不正确', status: 500 }; + } catch (error) { + console.error('❌ 创建分组出错:', error); + return { + error: error instanceof Error ? error.message : '创建分组失败', + status: 500 + }; + } +} + +/** + * 6. 更新评查点分组(FastAPI v3) + * @param id 分组ID + * @param groupData 更新的分组数据(部分更新) + * @param token JWT token + * @returns 更新后的分组数据 + */ +export async function updateEvaluationPointGroup( + id: string, + groupData: Partial, + token?: string +): Promise<{data: RuleGroup; error?: never} | {data?: never; error: string; status?: number}> { + try { + // 转换为 API 格式 + const apiGroup: Partial<{ + name: string; + code: string; + pid: number | null; + description: string | null; + is_enabled: boolean; + }> = {}; + + if (groupData.name !== undefined) apiGroup.name = groupData.name; + if (groupData.code !== undefined) apiGroup.code = groupData.code; + if (groupData.pid !== undefined) { + apiGroup.pid = groupData.pid === null || groupData.pid === '0' ? null : Number(groupData.pid); + } + if (groupData.description !== undefined) apiGroup.description = groupData.description || null; + if (groupData.is_enabled !== undefined) apiGroup.is_enabled = groupData.is_enabled; + + const response = await apiRequest( + `/api/v3/evaluation-point-groups/${id}`, + { + method: 'PUT', + body: JSON.stringify(apiGroup), + headers: { + 'Content-Type': 'application/json', + ...(token ? { 'Authorization': `Bearer ${token}` } : {}) + } + } + ); + + if (response.error) { + return { error: response.error, status: response.status }; + } + + if (response.data) { + const ruleGroup = convertApiGroupToRuleGroup(response.data); + console.log('✅ updateEvaluationPointGroup 成功:', ruleGroup); + return { data: ruleGroup }; + } + + return { error: '更新分组失败:返回数据格式不正确', status: 500 }; + } catch (error) { + console.error('❌ 更新分组出错:', error); + return { + error: error instanceof Error ? error.message : '更新分组失败', + status: 500 + }; + } +} + +/** + * 7. 删除评查点分组(FastAPI v3) + * @param id 分组ID + * @param token JWT token + * @returns 删除结果 + */ +export async function deleteEvaluationPointGroup( + id: string, + token?: string +): Promise<{success: boolean; message?: string; deleted_groups?: number; deleted_points?: number; error?: never} | {success: false; error: string; status?: number}> { + try { + const response = await apiRequest<{ + success: boolean; + message: string; + deleted_groups: number; + deleted_points: number; + }>( + `/api/v3/evaluation-point-groups/${id}`, + { + method: 'DELETE', + headers: token ? { 'Authorization': `Bearer ${token}` } : {} + } + ); + + if (response.error) { + return { success: false, error: response.error, status: response.status }; + } + + if (response.data) { + console.log('✅ deleteEvaluationPointGroup 成功:', response.data); + return { + success: response.data.success, + message: response.data.message, + deleted_groups: response.data.deleted_groups, + deleted_points: response.data.deleted_points + }; + } + + return { success: false, error: '删除分组失败:返回数据格式不正确', status: 500 }; + } catch (error) { + console.error('❌ 删除分组出错:', error); + return { + success: false, + error: error instanceof Error ? error.message : '删除分组失败', + status: 500 + }; + } +} + +/** + * 8. 批量更新分组启用状态(FastAPI v3) + * @param ids 分组ID列表 + * @param is_enabled 启用状态 + * @param token JWT token + * @returns 批量更新结果 + */ +export async function batchUpdateEvaluationPointGroupStatus( + ids: string[], + is_enabled: boolean, + token?: string +): Promise<{success: boolean; updated_count?: number; message?: string; error?: never} | {success: false; error: string; status?: number}> { + try { + const requestBody = { + ids: ids.map(id => Number(id)), + is_enabled + }; + + const response = await apiRequest<{ + success: boolean; + updated_count: number; + message: string; + }>( + '/api/v3/evaluation-point-groups/batch/status', + { + method: 'PATCH', + body: JSON.stringify(requestBody), + headers: { + 'Content-Type': 'application/json', + ...(token ? { 'Authorization': `Bearer ${token}` } : {}) + } + } + ); + + if (response.error) { + return { success: false, error: response.error, status: response.status }; + } + + if (response.data) { + console.log('✅ batchUpdateEvaluationPointGroupStatus 成功:', response.data); + return { + success: response.data.success, + updated_count: response.data.updated_count, + message: response.data.message + }; + } + + return { success: false, error: '批量更新状态失败:返回数据格式不正确', status: 500 }; + } catch (error) { + console.error('❌ 批量更新状态出错:', error); + return { + success: false, + error: error instanceof Error ? error.message : '批量更新状态失败', + status: 500 + }; + } +} + +/** + * 9. 批量删除分组(FastAPI v3) + * @param ids 分组ID列表 + * @param token JWT token + * @returns 批量删除结果 + */ +export async function batchDeleteEvaluationPointGroups( + ids: string[], + token?: string +): Promise<{success: boolean; deleted_groups?: number; deleted_points?: number; message?: string; error?: never} | {success: false; error: string; status?: number}> { + try { + const requestBody = { + ids: ids.map(id => Number(id)) + }; + + const response = await apiRequest<{ + success: boolean; + deleted_groups: number; + deleted_points: number; + message: string; + }>( + '/api/v3/evaluation-point-groups/batch', + { + method: 'DELETE', + body: JSON.stringify(requestBody), + headers: { + 'Content-Type': 'application/json', + ...(token ? { 'Authorization': `Bearer ${token}` } : {}) + } + } + ); + + if (response.error) { + return { success: false, error: response.error, status: response.status }; + } + + if (response.data) { + console.log('✅ batchDeleteEvaluationPointGroups 成功:', response.data); + return { + success: response.data.success, + deleted_groups: response.data.deleted_groups, + deleted_points: response.data.deleted_points, + message: response.data.message + }; + } + + return { success: false, error: '批量删除分组失败:返回数据格式不正确', status: 500 }; + } catch (error) { + console.error('❌ 批量删除分组出错:', error); + return { + success: false, + error: error instanceof Error ? error.message : '批量删除分组失败', + status: 500 + }; + } +}