This commit is contained in:
董海洋
2026-05-24 11:04:24 +08:00
parent d105f7471b
commit 79d34f17c5
+77 -42
View File
@@ -3,10 +3,36 @@ const fetch = require('node-fetch');
const router = new Router(); const router = new Router();
// NVIDIA API 配置 // NVIDIA API 配置NVCF 云 API
const NVIDIA_API_KEY = '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'; const NVIDIA_API_KEY = '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';
const NVIDIA_API_URL = 'https://integrate.api.nvidia.com/v1/chat/completions'; const NVIDIA_API_URL = 'https://integrate.api.nvidia.com/v1/chat/completions';
// Mock 数据(用于测试或网络不可用时)
const mockProducts = [
{ name: '可口可乐', category: '饮料', description: '经典碳酸饮料,清爽解渴,330ml罐装', suggestedPrice: 3.5 },
{ name: '乐事薯片', category: '零食', description: '香脆可口,原味薯片,75g包装', suggestedPrice: 8.9 },
{ name: '维达纸巾', category: '日用品', description: '三层加厚,柔软亲肤,10包家庭装', suggestedPrice: 25.9 },
{ name: '康师傅方便面', category: '食品', description: '红烧牛肉面口味,12桶整箱装', suggestedPrice: 39.9 },
{ name: '农夫山泉', category: '饮料', description: '天然矿泉水,550ml瓶装,12瓶/箱', suggestedPrice: 24.0 },
{ name: '奥利奥饼干', category: '零食', description: '夹心饼干,巧克力口味,388g家庭装', suggestedPrice: 18.9 },
];
// 获取随机 Mock 数据
function getMockProduct(keywords) {
let product = mockProducts[Math.floor(Math.random() * mockProducts.length)];
if (keywords) {
const keyword = keywords.toLowerCase();
const matched = mockProducts.find(p =>
p.name.toLowerCase().includes(keyword) ||
p.category.toLowerCase().includes(keyword)
);
if (matched) product = matched;
}
return { ...product };
}
// 生成商品信息的 API // 生成商品信息的 API
router.post('/generate-product', async (ctx) => { router.post('/generate-product', async (ctx) => {
try { try {
@@ -41,59 +67,68 @@ router.post('/generate-product', async (ctx) => {
"suggestedPrice": 建议售价(数字) "suggestedPrice": 建议售价(数字)
}`; }`;
// 调用 NVIDIA API
const response = await fetch(NVIDIA_API_URL, {
method: 'POST',
headers: {
'Authorization': `Bearer ${NVIDIA_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'deepseek-ai/deepseek-v4-pro',
messages: [
{
role: 'user',
content: prompt
}
],
temperature: 0.7,
max_tokens: 500
})
});
if (!response.ok) {
const errorText = await response.text();
console.error('NVIDIA API Error:', response.status, errorText);
throw new Error(`API 调用失败: ${response.status}`);
}
const data = await response.json();
const aiResponse = data.choices[0].message.content;
// 解析 JSON 响应
let productInfo; let productInfo;
let useMock = false;
try { try {
// 清理响应文本,只保留 JSON 部分 // 调用 NVIDIA NVCF 云 APIOpenAI 兼容格式)
const response = await fetch(NVIDIA_API_URL, {
method: 'POST',
headers: {
'Authorization': `Bearer ${NVIDIA_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'deepseek-ai/deepseek-v4-pro',
messages: [
{
role: 'user',
content: prompt
}
],
temperature: 0.7,
max_tokens: 500
}),
timeout: 60000 // 60秒超时
});
if (!response.ok) {
const errorText = await response.text();
console.error('NVIDIA API Error:', response.status, errorText);
throw new Error(`API 调用失败: ${response.status}`);
}
const data = await response.json();
const aiResponse = data.choices?.[0]?.message?.content;
if (!aiResponse) {
console.log('API 返回为空');
throw new Error('API 返回为空');
}
// 解析 JSON 响应
const jsonMatch = aiResponse.match(/\{[\s\S]*\}/); const jsonMatch = aiResponse.match(/\{[\s\S]*\}/);
if (jsonMatch) { if (jsonMatch) {
productInfo = JSON.parse(jsonMatch[0]); productInfo = JSON.parse(jsonMatch[0]);
} else { } else {
console.log('无法解析 JSON');
throw new Error('无法解析 AI 响应'); throw new Error('无法解析 AI 响应');
} }
} catch (parseError) {
console.error('JSON 解析失败:', aiResponse); } catch (apiError) {
// 如果解析失败,提供默认值 console.error('NVIDIA API 调用异常:', apiError.message);
productInfo = { console.log('切换到 Mock 模式');
name: keywords || '新商品', useMock = true;
category: '其他', }
description: '商品描述',
suggestedPrice: 0 // 使用 Mock 数据作为备用
}; if (useMock) {
productInfo = getMockProduct(keywords);
} }
ctx.body = { ctx.body = {
code: 200, code: 200,
message: '生成成功', message: useMock ? '使用模拟数据生成' : '生成成功',
data: productInfo data: productInfo
}; };