Files
services/routes/ai.js
T
董海洋 5674ef016e api
2026-05-24 18:18:44 +08:00

136 lines
3.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const Router = require('koa-router');
const fetch = require('node-fetch');
const router = new Router();
// NVIDIA API 配置(NVCF 云 API
const NVIDIA_API_KEY = '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';
const NVIDIA_API_URL = 'https://integrate.api.nvidia.com/v1/chat/completions';
// 生成商品信息的 API
router.post('/generate-product', async (ctx) => {
try {
const { imageUrl, keywords } = ctx.request.body;
if (!imageUrl && !keywords) {
ctx.status = 400;
ctx.body = {
code: 400,
message: '请提供商品图片或关键词'
};
return;
}
let prompt = '你是一个专业的便利店商品管理助手。';
if (imageUrl) {
prompt += `\n请分析这张商品图片:${imageUrl}`;
}
if (keywords) {
prompt += `\n关键词:${keywords}`;
}
prompt += `
请生成商品的详细信息,返回JSON格式,不要包含其他内容:
{
"name": "商品名称(简洁明了,2-10字)",
"category": "商品分类(请从以下选择:饮料,零食,日用品,食品,烟酒,其他)",
"description": "商品详细描述(50-100字,突出产品特点)",
"suggestedPrice": 建议售价(数字)
}`;
const response = await fetch(NVIDIA_API_URL, {
method: 'POST',
headers: {
'Authorization': `Bearer ${NVIDIA_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'deepseek-v4-flash',
messages: [
{
role: 'user',
content: prompt
}
],
temperature: 0.7,
max_tokens: 500
}),
timeout: 30000
});
if (!response.ok) {
const errorText = await response.text();
console.error('NVIDIA API Error:', response.status, errorText);
let errorMsg = 'AI 服务调用失败';
if (response.status === 401) {
errorMsg = 'API Key 无效,请检查密钥配置';
} else if (response.status === 403) {
errorMsg = 'API 调用被拒绝,请检查账户权限';
} else if (response.status === 429) {
errorMsg = 'API 调用次数超限,请稍后重试';
} else if (response.status === 503) {
errorMsg = 'AI 服务暂时不可用,请稍后重试';
}
ctx.status = response.status;
ctx.body = {
code: response.status,
message: errorMsg
};
return;
}
const data = await response.json();
const aiResponse = data.choices?.[0]?.message?.content;
if (!aiResponse) {
ctx.status = 500;
ctx.body = {
code: 500,
message: 'AI 服务返回为空'
};
return;
}
const jsonMatch = aiResponse.match(/\{[\s\S]*\}/);
if (!jsonMatch) {
ctx.status = 500;
ctx.body = {
code: 500,
message: '无法解析 AI 响应格式'
};
return;
}
const productInfo = JSON.parse(jsonMatch[0]);
ctx.body = {
code: 200,
message: '生成成功',
data: productInfo
};
} catch (error) {
console.error('生成商品信息失败:', error);
let errorMsg = '生成失败,请稍后重试';
if (error.message.includes('timeout')) {
errorMsg = 'AI 服务响应超时,请检查网络或稍后重试';
} else if (error.message.includes('ENOTFOUND')) {
errorMsg = '无法连接到 AI 服务,请检查网络设置';
} else if (error.message.includes('ECONNRESET')) {
errorMsg = 'AI 服务连接中断,请稍后重试';
}
ctx.status = 503;
ctx.body = {
code: 503,
message: errorMsg
};
}
});
module.exports = router.routes();