Files
jjx-web/uniCloud-tcb/cloudfunctions/jjxReviewStream/index.js
T

106 lines
2.8 KiB
JavaScript

'use strict';
exports.main = async (event, context) => {
// uniCloud HTTP 触发器:event 本身就是请求信息
// event.httpMethod = 'GET'/'POST'/'OPTIONS'
// event.body = 请求体
// event.headers = 请求头
// context.callbackWaitsForEmptyEventLoop = true 保持连接
const corsHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
'Access-Control-Max-Age': '86400'
};
// 处理 CORS 预检
if (event.httpMethod === 'OPTIONS') {
return {
statusCode: 204,
headers: corsHeaders,
body: ''
};
}
// 设置等待空事件循环(保持 SSE 连接)
context.callbackWaitsForEmptyEventLoop = false;
// 解析请求体
let body = {};
try {
const raw = event.body || '';
if (event.isBase64Encoded) {
body = JSON.parse(Buffer.from(raw, 'base64').toString());
} else {
try { body = JSON.parse(raw); } catch (e) {
const params = new URLSearchParams(raw);
for (const [k, v] of params) body[k] = v;
}
}
} catch (e) {}
const { file_id, user_id, file_name, file_size, record_id } = body;
if (!file_id) {
return {
statusCode: 400,
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
body: JSON.stringify({ error: '缺少 file_id' })
};
}
const COZE_TOKEN = 'sat_OiXlI4Da5Q99fxmul6pNfExmA6hR898UbxBDwrvjZ638APxRSlFnXbz6zyFedKNG';
const BOT_ID = '7689821072762011698';
const objectString = JSON.stringify([
{ type: 'file', file_id: file_id },
{ type: 'text', text: '请审查这份合同' }
]);
// 调用扣子(流式)
try {
const chatRes = await uniCloud.httpclient.request('https://api.coze.cn/v3/chat', {
method: 'POST',
dataType: 'text',
contentType: 'json',
timeout: 300000,
headers: { 'Authorization': 'Bearer ' + COZE_TOKEN },
data: {
bot_id: BOT_ID,
user_id: user_id || 'anonymous',
stream: true,
auto_save_history: true,
additional_messages: [{
role: 'user',
content: objectString,
content_type: 'object_string'
}]
}
});
// 返回 SSE 格式
const text = chatRes.data || '';
const sseBody = text.split('\n').map(line => {
if (line.startsWith('data:')) return line + '\n\n';
return '';
}).join('') + 'data: [DONE]\n\n';
return {
statusCode: 200,
headers: {
...corsHeaders,
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
},
body: sseBody
};
} catch (e) {
return {
statusCode: 500,
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
body: JSON.stringify({ error: e.message })
};
}
};