137 lines
4.7 KiB
JavaScript
137 lines
4.7 KiB
JavaScript
module.exports = {
|
|
main: async (event) => {
|
|
let { data = {}, userInfo } = event;
|
|
const { record_id, file_id, user_id, file_name, file_size } = data;
|
|
|
|
if (!record_id || !file_id) return { code: -1, msg: '参数错误' };
|
|
|
|
const COZE_TOKEN = 'sat_OiXlI4Da5Q99fxmul6pNfExmA6hR898UbxBDwrvjZ638APxRSlFnXbz6zyFedKNG';
|
|
const BOT_ID = '7689821072762011698';
|
|
const db = uniCloud.database();
|
|
const _ = db.command;
|
|
|
|
try {
|
|
// 构造请求
|
|
const objectString = JSON.stringify([
|
|
{ type: 'file', file_id: file_id },
|
|
{ type: 'text', text: '请审查这份合同' }
|
|
]);
|
|
|
|
// 调用 Coze 接口(流式模式,等待完整响应,和 Demo 一致)
|
|
const chatRes = await uniCloud.httpclient.request('https://api.coze.cn/v3/chat', {
|
|
method: 'POST',
|
|
dataType: 'text',
|
|
contentType: 'json',
|
|
timeout: 300000, // 5分钟超时
|
|
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 流中提取回答
|
|
let answer = '';
|
|
let conversationId = '';
|
|
const text = chatRes.data || '';
|
|
const lines = text.split('\n');
|
|
for (const line of lines) {
|
|
if (!line.startsWith('data:')) continue;
|
|
const d = line.slice(5).trim();
|
|
if (d === '[DONE]' || d === '"[DONE]"') continue;
|
|
try {
|
|
const p = JSON.parse(d);
|
|
if (p.conversation_id) conversationId = p.conversation_id;
|
|
if (p.type === 'answer' && p.content) answer += p.content;
|
|
if (p.type === 'tool_response' && p.content) {
|
|
try {
|
|
const toolData = JSON.parse(p.content);
|
|
if (toolData.url) answer += '\n\n📎 报告下载:' + toolData.url;
|
|
} catch (e) {
|
|
const urlMatch = p.content.match(/https?:\/\/[^\s\)\]\"\<]+\.pdf[^\s\)\]\"\<]*/i);
|
|
if (urlMatch) answer += '\n\n📎 报告下载:' + urlMatch[0];
|
|
}
|
|
}
|
|
} catch (e) {}
|
|
}
|
|
|
|
if (!answer) {
|
|
answer = '审查未能获取结果,请稍后重试';
|
|
}
|
|
|
|
// 计算消耗积分
|
|
const pointsUsed = Math.max(150, Math.ceil((file_size || 0) / (100 * 1024)) * 150);
|
|
|
|
// 扣积分
|
|
const userPoints = await db.collection('jjx-user-points').doc(user_id).get();
|
|
if (userPoints.data.length && userPoints.data[0].balance >= pointsUsed) {
|
|
await db.collection('jjx-user-points').doc(user_id).update({
|
|
balance: _.inc(-pointsUsed),
|
|
total_spent: _.inc(pointsUsed),
|
|
update_time: new Date()
|
|
});
|
|
|
|
const updatedPoints = await db.collection('jjx-user-points').doc(user_id).get();
|
|
await db.collection('jjx-points-log').add({
|
|
user_id: user_id,
|
|
type: 'spend',
|
|
amount: -pointsUsed,
|
|
balance_after: updatedPoints.data[0] ? updatedPoints.data[0].balance : 0,
|
|
reason: '合同审查 — ' + (file_name || ''),
|
|
biz_type: 'contract_review',
|
|
biz_id: record_id,
|
|
_add_time: new Date()
|
|
});
|
|
}
|
|
|
|
// 从回复中提取 HTML 报告下载链接
|
|
let htmlUrl = '';
|
|
try {
|
|
const linkMatch = answer.match(/\[([^\]]*\.html)\]\((https?:\/\/[^\)]+)\)/);
|
|
if (linkMatch) {
|
|
htmlUrl = linkMatch[2];
|
|
} else {
|
|
const urlMatch = answer.match(/https?:\/\/[^\s\)\]]+\.html[^\s\)\]]*/);
|
|
if (urlMatch) htmlUrl = urlMatch[0];
|
|
}
|
|
} catch (e) {}
|
|
|
|
// 解析 JSON 结构化数据
|
|
let contractInfo = {};
|
|
try {
|
|
const jsonMatch = answer.match(/```json\s*([\s\S]*?)```/);
|
|
if (jsonMatch) contractInfo = JSON.parse(jsonMatch[1].trim());
|
|
} catch (e) {}
|
|
|
|
// 更新审查记录为完成
|
|
await db.collection('jjx-review-records').doc(record_id).update({
|
|
status: 'completed',
|
|
result: answer,
|
|
html_url: htmlUrl,
|
|
contract_info: contractInfo,
|
|
points_used: pointsUsed,
|
|
conversation_id: conversationId || '',
|
|
update_time: new Date()
|
|
});
|
|
|
|
return { code: 0, msg: '审查完成' };
|
|
|
|
} catch (e) {
|
|
// 审查失败,更新记录
|
|
await db.collection('jjx-review-records').doc(record_id).update({
|
|
status: 'failed',
|
|
result: '审查失败: ' + e.message,
|
|
error: e.message,
|
|
update_time: new Date()
|
|
});
|
|
return { code: -1, msg: '审查失败: ' + e.message };
|
|
}
|
|
}
|
|
}; |