const express = require('express'); const axios = require('axios'); const authMiddleware = require('../middleware/auth'); const { buildInternalHeaders } = require('../middleware/internalSign'); const router = express.Router(); const PYTHON_URL = () => process.env.PYTHON_BACKEND_URL || 'http://localhost:3001'; /** * 通用代理函数:带 HMAC 签名转发到 Python */ async function forwardToPython(pythonPath, queryString, body, userId, res, userInfo = {}) { const url = `${PYTHON_URL()}${pythonPath}${queryString ? `?${queryString}` : ''}`; const headers = { 'Content-Type': 'application/json', ...buildInternalHeaders(userId, userInfo), }; console.log('[→ Python]', url); console.log('[→ Headers]', JSON.stringify(headers, null, 2)); console.log('[→ Body]', JSON.stringify(body, null, 2)); try { const resp = await axios.post(url, body, { headers, timeout: 30000 }); return res.status(resp.status).json(resp.data); } catch (err) { if (err.response) { return res.status(err.response.status).json(err.response.data); } console.error('[aiProxy] 转发失败:', err.message); return res.status(502).json({ code: 502, message: `无法连接 Python 后端: ${err.message}` }); } } // POST /api/ai/getScenes router.post('/getScenes', authMiddleware, async (req, res) => { await forwardToPython('/getScenes', 'Action=getScenes', req.body, req.user.userId, res, req.user); }); // POST /api/ai/proxy?Action=StartVoiceChat|StopVoiceChat router.post('/proxy', authMiddleware, async (req, res) => { const action = req.query.Action; if (!action) { return res.status(400).json({ code: 400, message: 'Action 参数不能为空' }); } await forwardToPython('/proxy', `Action=${action}`, req.body, req.user.userId, res, req.user); }); // POST /api/ai/session/history — 存储历史对话上下文到 Python(start 前调用) router.post('/session/history', authMiddleware, async (req, res) => { await forwardToPython('/api/session/history', '', req.body, req.user.userId, res, req.user); }); module.exports = router;