```ts import type { ActionFunctionArgs } from '@remix-run/node'; import type { ConvertRequest, ConvertResponse, Template } from '@shared/types/mod.ts'; import { ERROR_CODES, EXCEL_TEMPLATE_TABLE } from '@shared/types/mod.ts'; import { excelParser } from '~/lib/ExcelParser.server.ts'; import { getApiClient } from '~/lib/ApiClient.server.ts'; /** * 公开的Excel转JSON API接口 * POST /api/v1/convert * * 需要在请求头中提供有效的API密钥: * - X-API-Key: 'YOUR_API_KEY' */ export const action = async ({ request }: ActionFunctionArgs) => { console.log('[ExcelToJSON API] 收到转换请求'); // 只支持POST请求 if (request.method !== 'POST') { console.log('[ExcelToJSON API] 错误: 不支持的请求方法', request.method); return Response.json({ success: false, code: ERROR_CODES.VALIDATION_ERROR, message: '不支持的请求方法,仅支持POST' }, { status: 405 }); } // 验证API密钥 const apiKey = request.headers.get('X-API-Key'); if (!apiKey) { console.log('[ExcelToJSON API] 错误: 缺少API密钥'); return Response.json({ success: false, code: ERROR_CODES.AUTH_ERROR, message: '缺少API密钥,请在请求头中提供X-API-Key' }, { status: 401 }); } // TODO: 在实际生产环境中,应该从数据库或环境变量中获取并验证API密钥 const validApiKey = process.env.API_KEY || 'excel2json-api-key'; if (apiKey !== validApiKey) { console.log('[ExcelToJSON API] 错误: API密钥无效', apiKey); return Response.json({ success: false, code: ERROR_CODES.AUTH_ERROR, message: 'API密钥无效' }, { status: 401 }); } try { // 解析请求数据 const requestData = await request.json() as ConvertRequest; console.log('[ExcelToJSON API] 请求数据:', { templateId: requestData.templateId, hasConfig: !!requestData.config, inputType: requestData.input?.substring(0, 20) + '...' // 只记录输入类型的前20个字符 }); // 验证输入参数 if (!requestData.input) { console.log('[ExcelToJSON API] 错误: 缺少input参数'); return Response.json({ success: false, code: ERROR_CODES.VALIDATION_ERROR, message: '请提供input参数' }, { status: 400 }); } // 获取API客户端 console.log('[ExcelToJSON API] 获取API客户端'); const apiClient = await getApiClient(); // 解析配置 let templateConfig; // 如果提供了templateId,从数据库获取模板配置 if (requestData.templateId) { console.log('[ExcelToJSON API] 正在获取模板,ID:', requestData.templateId); try { const template = await apiClient.database.table(EXCEL_TEMPLATE_TABLE) .where('id', requestData.templateId) .where('is_deleted', 0) .first() as Template; if (!template) { console.log('[ExcelToJSON API] 错误: 模板不存在', requestData.templateId); return Response.json({ success: false, code: ERROR_CODES.NOT_FOUND, message: '模板不存在' }, { status: 404 }); } templateConfig = template.template_config; console.log('[ExcelToJSON API] 成功获取模板配置,工作表数:', templateConfig.sheets?.length); } catch (error) { console.error('[ExcelToJSON API] 获取模板失败:', error); return Response.json({ success: false, code: ERROR_CODES.SERVER_ERROR, message: '获取模板失败' }, { status: 500 }); } } // 如果提供了自定义配置,使用自定义配置 else if (requestData.config) { templateConfig = requestData.config; console.log('[ExcelToJSON API] 使用自定义配置,工作表数:', templateConfig.sheets?.length); } // 如果没有提供模板ID或自定义配置,返回错误 else { console.log('[ExcelToJSON API] 错误: 缺少templateId或config参数'); return Response.json({ success: false, code: ERROR_CODES.VALIDATION_ERROR, message: '请提供templateId或config参数' }, { status: 400 }); } // 将输入转换为ArrayBuffer let buffer: ArrayBuffer; try { console.log('[ExcelToJSON API] 正在获取文件数据'); buffer = await excelParser.getBufferFromUrlOrBase64(requestData.input); console.log('[ExcelToJSON API] 成功获取文件数据,大小:', buffer.byteLength, '字节'); } catch (error) { console.error('[ExcelToJSON API] 获取文件数据失败:', error); return Response.json({ success: false, code: ERROR_CODES.VALIDATION_ERROR, message: '获取文件数据失败,请确保提供了有效的URL或Base64编码' }, { status: 400 }); } // 处理Excel文件 console.log('[ExcelToJSON API] 开始解析Excel文件'); const result = await excelParser.parseExcelBuffer(buffer, templateConfig.sheets); console.log('[ExcelToJSON API] Excel解析完成,总表格数:', result.totalTables, '警告数:', result.warnings.length); // 构造响应 const response: ConvertResponse = { success: true, data: result.exportData, warnings: result.warnings, availableFields: result.availableFieldsBySheet, totalTables: result.totalTables }; // 记录API调用日志(可选) // await apiClient.database.table('api_logs').insert({ // api_key: apiKey, // endpoint: '/api/v1/convert', // created_at: new Date() // }); console.log('[ExcelToJSON API] 转换成功,响应数据大小:', JSON.stringify(response).length, '字节'); return Response.json(response); } catch (error) { console.error('[ExcelToJSON API] 转换失败:', error); return Response.json({ success: false, code: ERROR_CODES.SERVER_ERROR, message: `转换失败: ${error instanceof Error ? error.message : '未知错误'}` }, { status: 500 }); } }; ```