import { apiRequest } from '../axios-client'; import { formatDate } from '../../utils'; // 提示词模板接口(数据库格式) export interface PromptTemplate { id: number; template_name: string; template_code: string | null; template_type: string; description: string | null; template_content: string; template_abbreviation: string | null; variables: Record | null; status: number; version: string; created_by: number | null; created_by_username?: string; // 创建者用户名 created_at: string; updated_at: string; is_active?: boolean; } // 提示词模板前端接口 export interface PromptTemplateUI { id: string; template_name: string; template_type: 'LLM_Extraction' | 'VLM_Extraction' | 'Evaluation' | 'Summary' | 'Common'; description: string; template_content: string; variables: Record; // 变量定义 status: 'active' | 'inactive' | 'system'; version: string; created_by: number; created_by_username?: string; // 创建者用户名 created_at: string; updated_at: string; template_code?: string; // 模板代码 template_abbreviation?: string; // 模板简称 } // 搜索参数接口 export interface PromptSearchParams { name?: string; type?: string; status?: string; page?: number; pageSize?: number; } // API 响应格式 interface ApiResponse { code: number; message: string; data: T; } // 列表响应格式 interface ListResponse { total: number; page: number; page_size: number; items: PromptTemplate[]; } // 类型选项 interface TypeOption { value: string; label: string; count: number; } // 默认的模板类型列表(当没有指定类型时使用) const DEFAULT_TEMPLATE_TYPES = [ 'LLM_Extraction', 'VLM_Extraction', 'Evaluation', 'Summary', 'Common' ]; /** * 构建请求选项(包括 JWT token) * @param method HTTP 方法 * @param data 请求数据(可选) * @param jwt JWT token(可选) * @returns 请求选项 */ function buildRequestOptions(method: 'GET' | 'POST' | 'PUT' | 'DELETE', data?: unknown, jwt?: string) { const options: { method: string; data?: unknown; headers?: Record; } = { method, }; if (data !== undefined) { options.data = data; } // 如果提供了 JWT token(服务端调用时),添加到 headers if (jwt) { options.headers = { 'Authorization': `Bearer ${jwt}`, }; } return options; } /** * 将API状态值转换为UI状态值 * @param status API状态值(数字) * @returns UI状态值(字符串) */ function mapStatusToUI(status: number): 'active' | 'inactive' | 'system' { switch(status) { case 0: return 'inactive'; case 1: return 'active'; case 2: return 'system'; default: return 'inactive'; } } /** * 将UI状态值转换为API状态值 * @param status UI状态值(字符串) * @returns API状态值(数字) */ function mapStatusToAPI(status: string): number { switch(status) { case 'active': return 1; case 'inactive': return 0; case 'system': return 2; default: return 0; } } /** * 将数据库模板转换为UI模板 * @param template 数据库模板 * @returns UI模板 */ export function convertToUITemplate(template: PromptTemplate): PromptTemplateUI { return { id: template.id ? template.id.toString() : '', template_name: template.template_name, template_type: template.template_type as "LLM_Extraction" | "VLM_Extraction" | "Evaluation" | "Summary" | "Common", description: template.description || '', template_content: template.template_content, variables: template.variables || {}, status: mapStatusToUI(template.status), version: template.version, created_by: template.created_by || 0, created_by_username: template.created_by_username, created_at: formatDate(template.created_at), updated_at: formatDate(template.updated_at), template_code: template.template_code || undefined, template_abbreviation: template.template_abbreviation || undefined }; } /** * 获取提示词模板列表 * @param searchParams 搜索参数 * @param frontendJWT JWT token (可选,已由 axios-client 自动处理) * @returns 提示词模板列表和总数 */ export async function getPromptTemplates(searchParams: PromptSearchParams = {}, frontendJWT?: string): Promise<{ data?: { templates: PromptTemplateUI[], total: number }; error?: string; status?: number; }> { try { const page = searchParams.page || 1; const pageSize = searchParams.pageSize || 10; // 构建查询参数 const params: Record = { page, page_size: pageSize, }; // 添加筛选条件 if (searchParams.name) { params.search = searchParams.name; } // 模板类型:如果指定了类型则使用指定的,否则使用默认的 5 个类型 if (searchParams.type) { params.template_type = searchParams.type; } else { // 没有指定类型时,默认只查询这 5 个类型 params.template_type = DEFAULT_TEMPLATE_TYPES.join(','); } if (searchParams.status) { params.status = mapStatusToAPI(searchParams.status); } // 发送API请求 const response = await apiRequest>( '/api/v3/prompt-templates', buildRequestOptions('GET', undefined, frontendJWT), params ); if (response.error) { console.error('API返回错误:', response.error); return { error: response.error, status: response.status }; } // 检查响应数据 if (!response.data) { console.error('响应数据为空'); return { error: '获取提示词模板数据失败', status: 500 }; } // 解析响应数据 const apiResponse = response.data; // 支持 code=0 (成功) 和 code=200 (成功) 两种格式 if (apiResponse.code !== 0 && apiResponse.code !== 200) { console.error('API返回非成功状态码:', apiResponse.code, apiResponse.message); return { error: apiResponse.message || '获取提示词模板失败', status: response.status }; } const listData = apiResponse.data; if (!listData || !listData.items) { console.error('列表数据格式错误:', listData); return { error: '获取提示词模板数据失败', status: 500 }; } // 返回转换后的数据 return { data: { templates: listData.items.map(convertToUITemplate), total: listData.total || 0 } }; } catch (error) { console.error('获取提示词模板出错:', error); return { error: error instanceof Error ? error.message : '获取提示词模板失败', status: 500 }; } } /** * 获取提示词模板详情 * @param id 模板ID * @param frontendJWT JWT token (可选,已由 axios-client 自动处理) * @returns 提示词模板详情 */ export async function getPromptTemplate(id: string, frontendJWT?: string): Promise<{ data?: PromptTemplateUI; error?: string; status?: number; }> { try { if (!id) { return { error: '模板ID不能为空', status: 400 }; } const response = await apiRequest>( `/api/v3/prompt-templates/${id}`, buildRequestOptions('GET', undefined, frontendJWT) ); if (response.error) { return { error: response.error, status: response.status }; } if (!response.data) { return { error: '获取提示词模板详情失败', status: 500 }; } const apiResponse = response.data; // 支持 code=0 (成功) 和 code=200 (成功) 两种格式 if (apiResponse.code !== 0 && apiResponse.code !== 200) { return { error: apiResponse.message || '获取提示词模板详情失败', status: response.status }; } if (!apiResponse.data) { return { error: '未找到指定模板', status: 404 }; } return { data: convertToUITemplate(apiResponse.data) }; } catch (error) { console.error('获取提示词模板详情失败:', error); return { error: error instanceof Error ? error.message : '获取提示词模板详情失败', status: 500 }; } } /** * 创建提示词模板 * @param template 提示词模板数据 * @param userId 当前用户ID * @param frontendJWT JWT token (可选,已由 axios-client 自动处理) * @returns 创建的提示词模板 */ export async function createPromptTemplate(template: Partial, userId: number, frontendJWT?: string): Promise<{ data?: PromptTemplateUI; error?: string; status?: number; }> { try { // 验证必填字段 if (!template.template_name || !template.template_type || !template.template_content) { return { error: '模板名称、类型和内容不能为空', status: 400 }; } if (!userId) { return { error: '用户ID不能为空', status: 400 }; } // 准备API数据 const apiTemplate = { template_name: template.template_name, template_code: template.template_code || `custom_${Date.now()}`, // 如果没有提供 code,自动生成 template_type: template.template_type, description: template.description || null, template_content: template.template_content, template_abbreviation: template.template_abbreviation || null, variables: template.variables || {}, status: mapStatusToAPI(template.status || 'active'), }; const response = await apiRequest>( '/api/v3/prompt-templates', buildRequestOptions('POST', apiTemplate, frontendJWT) ); if (response.error) { return { error: response.error, status: response.status }; } if (!response.data) { return { error: '创建提示词模板失败', status: 500 }; } const apiResponse = response.data; // 支持 code=0 (成功) 和 code=200 (成功) 两种格式 if (apiResponse.code !== 0 && apiResponse.code !== 200) { return { error: apiResponse.message || '创建提示词模板失败', status: response.status }; } if (!apiResponse.data) { return { error: '创建提示词模板失败', status: 500 }; } return { data: convertToUITemplate(apiResponse.data) }; } catch (error) { console.error('创建提示词模板失败:', error); return { error: error instanceof Error ? error.message : '创建提示词模板失败', status: 500 }; } } /** * 更新提示词模板 * @param id 模板ID * @param template 提示词模板数据 * @param frontendJWT JWT token (可选,已由 axios-client 自动处理) * @returns 更新后的提示词模板 */ export async function updatePromptTemplate(id: string, template: Partial, frontendJWT?: string): Promise<{ data?: PromptTemplateUI; error?: string; status?: number; }> { try { if (!id) { return { error: '模板ID不能为空', status: 400 }; } // 准备API数据(只传需要更新的字段) const apiTemplate: Record = {}; if (template.template_name !== undefined) { apiTemplate.template_name = template.template_name; } if (template.template_code !== undefined) { apiTemplate.template_code = template.template_code; } if (template.template_type !== undefined) { apiTemplate.template_type = template.template_type; } if (template.description !== undefined) { apiTemplate.description = template.description; } if (template.template_content !== undefined) { apiTemplate.template_content = template.template_content; } if (template.template_abbreviation !== undefined) { apiTemplate.template_abbreviation = template.template_abbreviation; } if (template.variables !== undefined) { apiTemplate.variables = template.variables; } if (template.status !== undefined) { apiTemplate.status = mapStatusToAPI(template.status); } const response = await apiRequest>( `/api/v3/prompt-templates/${id}`, buildRequestOptions('PUT', apiTemplate, frontendJWT) ); if (response.error) { return { error: response.error, status: response.status }; } if (!response.data) { return { error: '更新提示词模板失败', status: 500 }; } const apiResponse = response.data; // 支持 code=0 (成功) 和 code=200 (成功) 两种格式 if (apiResponse.code !== 0 && apiResponse.code !== 200) { return { error: apiResponse.message || '更新提示词模板失败', status: response.status }; } if (!apiResponse.data) { return { error: '更新提示词模板失败', status: 500 }; } return { data: convertToUITemplate(apiResponse.data) }; } catch (error) { console.error('更新提示词模板失败:', error); return { error: error instanceof Error ? error.message : '更新提示词模板失败', status: 500 }; } } /** * 删除提示词模板 * @param id 模板ID * @param frontendJWT JWT token (可选,已由 axios-client 自动处理) * @returns 成功或失败信息 */ export async function deletePromptTemplate(id: string, frontendJWT?: string): Promise<{ success?: boolean; error?: string; status?: number; }> { try { if (!id) { return { error: '模板ID不能为空', status: 400 }; } const response = await apiRequest>( `/api/v3/prompt-templates/${id}`, buildRequestOptions('DELETE', undefined, frontendJWT) ); if (response.error) { return { error: response.error, status: response.status }; } if (!response.data) { return { error: '删除提示词模板失败', status: 500 }; } const apiResponse = response.data; // 支持 code=0 (成功) 和 code=200 (成功) 两种格式 if (apiResponse.code !== 0 && apiResponse.code !== 200) { return { error: apiResponse.message || '删除提示词模板失败', status: response.status }; } return { success: true }; } catch (error) { console.error('删除提示词模板失败:', error); return { error: error instanceof Error ? error.message : '删除提示词模板失败', status: 500 }; } } /** * 获取指定类型的提示词模板选项 * @param templateType 模板类型(如 'VLM_Extraction', 'LLM_Extraction' 等) * @param frontendJWT JWT token (可选,已由 axios-client 自动处理) * @returns 模板选项列表 { value: template_code, label: template_abbreviation } */ export async function getPromptTemplateOptions(templateType: string, frontendJWT?: string): Promise<{ data?: Array<{ value: string; label: string }>; error?: string; status?: number; }> { try { if (!templateType) { return { error: '模板类型不能为空', status: 400 }; } // 使用列表接口,筛选指定类型并只获取需要的字段 const params = { template_type: templateType, page: 1, page_size: 500, // 获取足够多的选项 }; const response = await apiRequest>( '/api/v3/prompt-templates', buildRequestOptions('GET', undefined, frontendJWT), params ); if (response.error) { console.error('获取提示词模板选项失败:', response.error); return { error: response.error, status: response.status }; } if (!response.data) { console.error('提取提示词模板选项数据失败'); return { error: '获取提示词模板选项失败', status: 500 }; } const apiResponse = response.data; // 支持 code=0 (成功) 和 code=200 (成功) 两种格式 if (apiResponse.code !== 0 && apiResponse.code !== 200) { return { error: apiResponse.message || '获取提示词模板选项失败', status: response.status }; } const listData = apiResponse.data; if (!listData || !listData.items) { return { error: '获取提示词模板选项失败', status: 500 }; } // 转换为选项格式 const options = listData.items .filter(item => item.template_code && item.template_abbreviation) // 只保留有 code 和 abbreviation 的 .map(item => ({ value: item.template_code!, label: item.template_abbreviation! })); return { data: options }; } catch (error) { console.error('获取提示词模板选项出错:', error); return { error: error instanceof Error ? error.message : '获取提示词模板选项失败', status: 500 }; } } /** * 获取提示词模板类型列表 * @param frontendJWT JWT token (可选,已由 axios-client 自动处理) * @returns 类型选项列表 */ export async function getPromptTemplateTypes(frontendJWT?: string): Promise<{ data?: TypeOption[]; error?: string; status?: number; }> { try { const response = await apiRequest>( '/api/v3/prompt-templates/types', buildRequestOptions('GET', undefined, frontendJWT) ); if (response.error) { console.error('获取提示词模板类型失败:', response.error); return { error: response.error, status: response.status }; } if (!response.data) { console.error('提取提示词模板类型数据失败'); return { error: '获取提示词模板类型失败', status: 500 }; } const apiResponse = response.data; // 支持 code=0 (成功) 和 code=200 (成功) 两种格式 if (apiResponse.code !== 0 && apiResponse.code !== 200) { return { error: apiResponse.message || '获取提示词模板类型失败', status: response.status }; } if (!apiResponse.data || !apiResponse.data.items) { return { error: '获取提示词模板类型失败', status: 500 }; } return { data: apiResponse.data.items }; } catch (error) { console.error('获取提示词模板类型出错:', error); return { error: error instanceof Error ? error.message : '获取提示词模板类型失败', status: 500 }; } } /** * 复制提示词模板 * @param id 原模板ID * @param newCode 新模板代码(可选) * @param frontendJWT JWT token (可选,已由 axios-client 自动处理) * @returns 复制后的新模板 */ export async function duplicatePromptTemplate(id: string, newCode?: string, frontendJWT?: string): Promise<{ data?: PromptTemplateUI; error?: string; status?: number; }> { try { if (!id) { return { error: '模板ID不能为空', status: 400 }; } const params = newCode ? { new_code: newCode } : undefined; const response = await apiRequest>( `/api/v3/prompt-templates/${id}/duplicate`, buildRequestOptions('POST', undefined, frontendJWT), params ); if (response.error) { return { error: response.error, status: response.status }; } if (!response.data) { return { error: '复制提示词模板失败', status: 500 }; } const apiResponse = response.data; // 支持 code=0 (成功) 和 code=200 (成功) 两种格式 if (apiResponse.code !== 0 && apiResponse.code !== 200) { return { error: apiResponse.message || '复制提示词模板失败', status: response.status }; } if (!apiResponse.data) { return { error: '复制提示词模板失败', status: 500 }; } return { data: convertToUITemplate(apiResponse.data) }; } catch (error) { console.error('复制提示词模板出错:', error); return { error: error instanceof Error ? error.message : '复制提示词模板失败', status: 500 }; } }