Files
multy-stub/server/routers/back-new/features/image/image.controller.js

140 lines
4.6 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 axios = require('axios');
const makeLinks = require('../../shared/hateoas');
const { v4: uuidv4 } = require('uuid');
const qs = require('qs');
require('dotenv').config();
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
// 获取GigaChat access_token严格按官方文档
async function getGigaChatToken() {
const apiKey = process.env.GIGACHAT_API_KEY;
const scope = process.env.GIGACHAT_SCOPE || 'GIGACHAT_API_PERS';
if (!apiKey) throw new Error('GIGACHAT_API_KEY 未配置');
const rqUID = uuidv4();
const auth = Buffer.from(apiKey.trim()).toString('base64');
try {
const resp = await axios.post(
'https://ngw.devices.sberbank.ru:9443/api/v2/oauth',
new URLSearchParams({ scope }),
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json',
'RqUID': rqUID,
'Authorization': `Basic ${auth}`,
},
timeout: 10000,
}
);
if (!resp.data.access_token) {
console.error('GigaChat token响应异常:', resp.data);
throw new Error('GigaChat token响应异常');
}
return resp.data.access_token;
} catch (err) {
if (err.response) {
console.error('获取access_token失败:', err.response.status, err.response.data);
} else {
console.error('获取access_token异常:', err.message);
}
throw new Error('获取access_token失败');
}
}
// 调用chat生成图片描述
async function fetchChatContent(accessToken, prompt) {
try {
const chatResp = await axios.post(
'https://gigachat.devices.sberbank.ru/api/v1/chat/completions',
{
model: "GigaChat",
messages: [
{ role: "system", content: "Ты — Василий Кандинский" },
{ role: "user", content: prompt }
],
stream: false,
function_call: 'auto'
},
{
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json',
'RqUID': uuidv4(),
}
}
);
const content = chatResp.data.choices[0].message.content;
console.log('GigaChat返回内容:', content);
return content;
} catch (err) {
console.error('AI生成图片出错: chat接口失败');
if (err.response) {
console.error('status:', err.response.status);
console.error('headers:', err.response.headers);
console.error('data:', err.response.data);
console.error('config:', err.config);
} else {
console.error('AI生成图片出错:', err.message);
}
throw new Error('chat接口失败: ' + err.message);
}
}
// 获取图片内容
async function fetchImageContent(accessToken, imageId) {
try {
const imageResp = await axios.get(
`https://gigachat.devices.sberbank.ru/api/v1/files/${imageId}/content`,
{
headers: {
'Authorization': `Bearer ${accessToken}`,
'RqUID': uuidv4(),
},
responseType: 'arraybuffer'
}
);
return imageResp.data;
} catch (err) {
console.error('AI生成图片出错: 获取图片内容失败');
if (err.response) {
console.error('status:', err.response.status);
console.error('headers:', err.response.headers);
console.error('data:', err.response.data);
console.error('config:', err.config);
} else {
console.error('AI生成图片出错:', err.message);
}
throw new Error('获取图片内容失败: ' + err.message);
}
}
exports.generate = async (req, res) => {
const { prompt } = req.query;
if (!prompt) {
return res.status(400).json({ error: 'Prompt parameter is required' });
}
let accessToken;
try {
accessToken = await getGigaChatToken();
} catch (e) {
return res.status(500).json({ error: e.message });
}
try {
const content = await fetchChatContent(accessToken, prompt);
const match = content.match(/<img src=\"(.*?)\"/);
if (!match) {
console.error('AI生成图片出错: GigaChat未返回图片标签');
return res.status(500).json({ error: 'No image generated' });
}
const imageId = match[1];
const imageData = await fetchImageContent(accessToken, imageId);
res.set('Content-Type', 'image/jpeg');
res.set('X-HATEOAS', JSON.stringify(makeLinks('/gigachat', { self: '/prompt' })));
res.send(imageData);
} catch (err) {
console.error('AI生成图片出错: 未知错误', err);
res.status(500).json({ error: err.message });
}
};