/** * 合同起草服务 * 处理草稿创建、更新等业务逻辑 * 包含文件复制功能(预留 MinIO 实现) */ import { postgrestGet, postgrestPost, postgrestPut, postgrestDelete } from '~/api/postgrest-client'; import type { DraftedContract, CreateDraftRequest } from '~/types/contract-draft'; /** * 生成草稿文件路径 * @param templateFilePath 模板文件路径 * @param userId 用户ID * @param templateId 模板ID * @returns 草稿文件路径 */ export function generateDraftFilePath( templateFilePath: string, userId: number, templateId: number ): string { const timestamp = Date.now(); const fileExtension = templateFilePath.split('.').pop() || 'docx'; const newFileName = `contract_${templateId}_${userId}_${timestamp}.${fileExtension}`; return `drafts/${newFileName}`; } /** * 复制 MinIO 文件(预留实现) * @param sourceFilePath 源文件路径 * @param targetFilePath 目标文件路径 * @param bucket Bucket 名称 * @returns 是否成功 * * TODO: 实现 MinIO 文件复制逻辑 * 1. 安装 minio SDK: npm install minio * 2. 创建 MinIO 客户端实例 * 3. 调用 copyObject 方法复制文件 * * 参考实现: * ```typescript * import { Client } from 'minio'; * * const minioClient = new Client({ * endPoint: process.env.MINIO_ENDPOINT || 'localhost', * port: parseInt(process.env.MINIO_PORT || '9000'), * useSSL: false, * accessKey: process.env.MINIO_ACCESS_KEY || '', * secretKey: process.env.MINIO_SECRET_KEY || '' * }); * * await minioClient.copyObject( * bucket, * targetFilePath, * `/${bucket}/${sourceFilePath}`, * null * ); * ``` */ export async function copyMinioFile( sourceFilePath: string, targetFilePath: string, bucket: string = 'docauditai' ): Promise { try { console.log('[Draft Service] 复制文件(预留实现):', { sourceFilePath, targetFilePath, bucket }); // TODO: 实现 MinIO 文件复制 // 当前为临时实现,直接返回成功 console.warn('[Draft Service] ⚠️ 文件复制功能尚未实现,请实施 MinIO 集成'); return true; } catch (error) { console.error('[Draft Service] 文件复制失败:', error); return false; } } /** * 创建起草合同记录 * @param request 创建请求 * @param userId 用户ID * @param draftFilePath 可选:草稿文件路径(如果不提供,使用模板路径) * @returns 创建的记录 * * 使用场景: * 1. 不传 draftFilePath:直接使用模板文件路径,在原模板上编辑 * 2. 传 draftFilePath:使用复制后的文件路径(由文件复制接口提供) */ export async function createDraftContract( request: CreateDraftRequest, userId: number, draftFilePath?: string, jwt?: string ): Promise { try { // 1. 查询模板信息 const templateResponse = await postgrestGet('contract_templates', { select: 'id,file_path', filter: { id: `eq.${request.templateId}` }, token: jwt }); if (!templateResponse.data || (Array.isArray(templateResponse.data) && templateResponse.data.length === 0)) { throw new Error('模板不存在'); } const template = Array.isArray(templateResponse.data) ? templateResponse.data[0] : templateResponse.data; // 2. 确定使用的文件路径 // 如果没有提供草稿路径,直接使用模板路径(适合直接编辑模板的场景) // 如果提供了草稿路径,使用复制后的文件路径 const finalFilePath = draftFilePath || template.file_path; console.log('[Draft Service] 创建草稿:', { templateId: request.templateId, templatePath: template.file_path, draftPath: draftFilePath, finalPath: finalFilePath, mode: draftFilePath ? '使用复制文件' : '直接使用模板文件' }); // 3. 创建草稿记录 const insertResponse = await postgrestPost('drafted_contracts', { body: { template_id: request.templateId, file_path: finalFilePath, title: request.title, placeholder_values: {}, status: 'draft', created_by: userId }, select: '*', token: jwt }); if (!insertResponse.data) { throw new Error('创建草稿记录失败'); } const draft = Array.isArray(insertResponse.data) ? insertResponse.data[0] : insertResponse.data; return draft as DraftedContract; } catch (error) { console.error('[Draft Service] 创建草稿失败:', error); throw error; } } /** * 删除草稿记录 * @param draftId 草稿ID * @param userId 用户ID * @param jwt JWT token */ export async function deleteDraft( draftId: number, userId: number, jwt?: string ): Promise { try { const response = await postgrestDelete('drafted_contracts', { filter: { id: `eq.${draftId}`, created_by: `eq.${userId}` // 确保只能删除自己的草稿 }, token: jwt }); console.log('[Draft Service] 草稿已删除:', draftId); } catch (error) { console.error('[Draft Service] 删除草稿失败:', error); throw error; } } /** * 获取草稿详情 * @param draftId 草稿ID * @param userId 用户ID * @returns 草稿记录 */ export async function getDraftById( draftId: number, userId: number, jwt?: string ): Promise { try { const response = await postgrestGet('drafted_contracts', { select: '*', filter: { id: `eq.${draftId}`, created_by: `eq.${userId}` }, token: jwt }); if (!response.data || (Array.isArray(response.data) && response.data.length === 0)) { return null; } const draft = Array.isArray(response.data) ? response.data[0] : response.data; return draft as DraftedContract; } catch (error) { console.error('[Draft Service] 获取草稿失败:', error); return null; } }