175 lines
5.4 KiB
JavaScript
175 lines
5.4 KiB
JavaScript
/**
|
|
* AI调用记录工具类
|
|
* 用于记录每次AI API调用的详细信息
|
|
*/
|
|
|
|
const Framework = require("../../framework/node-core-framework.js");
|
|
|
|
class AiCallRecorder {
|
|
/**
|
|
* 记录AI调用
|
|
* @param {Object} params - 调用参数
|
|
* @param {Number} params.user_id - 用户ID
|
|
* @param {String} params.sn_code - 设备序列号
|
|
* @param {String} params.service_type - 服务类型
|
|
* @param {String} params.model_name - 模型名称
|
|
* @param {Number} params.prompt_tokens - 输入token数
|
|
* @param {Number} params.completion_tokens - 输出token数
|
|
* @param {Number} params.total_tokens - 总token数
|
|
* @param {String} params.request_content - 请求内容
|
|
* @param {String} params.response_content - 响应内容
|
|
* @param {Number} params.cost_amount - 费用
|
|
* @param {String} params.status - 状态
|
|
* @param {String} params.error_message - 错误信息
|
|
* @param {Number} params.response_time - 响应时间(毫秒)
|
|
* @param {String} params.api_provider - API提供商
|
|
* @param {String} params.business_type - 业务类型
|
|
* @param {Number} params.reference_id - 关联业务ID
|
|
* @returns {Promise<Object>} 记录结果
|
|
*/
|
|
static async record(params) {
|
|
try {
|
|
const models = Framework.getModels();
|
|
const { ai_call_records } = models;
|
|
|
|
if (!ai_call_records) {
|
|
console.error('AI调用记录模型未找到');
|
|
return null;
|
|
}
|
|
|
|
const record = await ai_call_records.create({
|
|
user_id: params.user_id || null,
|
|
sn_code: params.sn_code || null,
|
|
service_type: params.service_type || '',
|
|
model_name: params.model_name || '',
|
|
prompt_tokens: params.prompt_tokens || 0,
|
|
completion_tokens: params.completion_tokens || 0,
|
|
total_tokens: params.total_tokens || 0,
|
|
request_content: params.request_content || null,
|
|
response_content: params.response_content || null,
|
|
cost_amount: params.cost_amount || null,
|
|
status: params.status || 'success',
|
|
error_message: params.error_message || null,
|
|
response_time: params.response_time || null,
|
|
api_provider: params.api_provider || 'openai',
|
|
business_type: params.business_type || null,
|
|
reference_id: params.reference_id || null,
|
|
is_delete: 0,
|
|
create_time: new Date()
|
|
});
|
|
|
|
console.log(`AI调用已记录 - ID: ${record.id}, Model: ${params.model_name}, Tokens: ${params.total_tokens}`);
|
|
return record;
|
|
} catch (error) {
|
|
console.error('记录AI调用失败:', error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 统计用户Token使用量
|
|
* @param {Number} user_id - 用户ID
|
|
* @param {String} startDate - 开始日期 (可选)
|
|
* @param {String} endDate - 结束日期 (可选)
|
|
* @returns {Promise<Object>} 统计结果
|
|
*/
|
|
static async getUserTokenStats(user_id, startDate = null, endDate = null) {
|
|
try {
|
|
const models = Framework.getModels();
|
|
const { ai_call_records, op } = models;
|
|
|
|
const where = {
|
|
user_id,
|
|
is_delete: 0,
|
|
status: 'success'
|
|
};
|
|
|
|
if (startDate && endDate) {
|
|
where.create_time = {
|
|
[op.between]: [new Date(startDate), new Date(endDate)]
|
|
};
|
|
} else if (startDate) {
|
|
where.create_time = {
|
|
[op.gte]: new Date(startDate)
|
|
};
|
|
} else if (endDate) {
|
|
where.create_time = {
|
|
[op.lte]: new Date(endDate)
|
|
};
|
|
}
|
|
|
|
const records = await ai_call_records.findAll({ where });
|
|
|
|
const stats = {
|
|
total_calls: records.length,
|
|
total_prompt_tokens: 0,
|
|
total_completion_tokens: 0,
|
|
total_tokens: 0,
|
|
total_cost: 0
|
|
};
|
|
|
|
records.forEach(record => {
|
|
stats.total_prompt_tokens += record.prompt_tokens || 0;
|
|
stats.total_completion_tokens += record.completion_tokens || 0;
|
|
stats.total_tokens += record.total_tokens || 0;
|
|
stats.total_cost += parseFloat(record.cost_amount || 0);
|
|
});
|
|
|
|
return stats;
|
|
} catch (error) {
|
|
console.error('统计Token使用量失败:', error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 统计设备Token使用量
|
|
* @param {String} sn_code - 设备序列号
|
|
* @param {String} startDate - 开始日期 (可选)
|
|
* @param {String} endDate - 结束日期 (可选)
|
|
* @returns {Promise<Object>} 统计结果
|
|
*/
|
|
static async getDeviceTokenStats(sn_code, startDate = null, endDate = null) {
|
|
try {
|
|
const models = Framework.getModels();
|
|
const { ai_call_records, op } = models;
|
|
|
|
const where = {
|
|
sn_code,
|
|
is_delete: 0,
|
|
status: 'success'
|
|
};
|
|
|
|
if (startDate && endDate) {
|
|
where.create_time = {
|
|
[op.between]: [new Date(startDate), new Date(endDate)]
|
|
};
|
|
}
|
|
|
|
const records = await ai_call_records.findAll({ where });
|
|
|
|
const stats = {
|
|
total_calls: records.length,
|
|
total_prompt_tokens: 0,
|
|
total_completion_tokens: 0,
|
|
total_tokens: 0,
|
|
total_cost: 0
|
|
};
|
|
|
|
records.forEach(record => {
|
|
stats.total_prompt_tokens += record.prompt_tokens || 0;
|
|
stats.total_completion_tokens += record.completion_tokens || 0;
|
|
stats.total_tokens += record.total_tokens || 0;
|
|
stats.total_cost += parseFloat(record.cost_amount || 0);
|
|
});
|
|
|
|
return stats;
|
|
} catch (error) {
|
|
console.error('统计设备Token使用量失败:', error);
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = AiCallRecorder;
|