fix: 修复 Persona Studio 对话无回复 · API代理层新增反向代理 + PM2配置补全 + 模块自检修复
问题根因:Nginx 将所有 /api/* 路由到 api-proxy (port 3721),但 api-proxy 未处理 /api/ps/chat/*, /api/ps/auth/* 等 Persona Studio 后端路由,导致请求返回 404,用户发送消息后无回复。 修复内容: 1. api-proxy.js 新增反向代理,将 /api/ps/chat/*, /api/ps/auth/*, /api/ps/build/*, /api/ps/notify/* 转发到 PS 后端 (port 3002) 2. ecosystem.config.js 补全 api-proxy + persona-studio PM2 配置 3. m15-cloud-drive/ 补全 README.md(模块自检修复) 4. README.md 开发者公告栏更新修复状态 Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
This commit is contained in:
parent
ae0e52029e
commit
df64cb221d
16
README.md
16
README.md
|
|
@ -78,6 +78,8 @@
|
||||||
<!-- BINGSHUO_BULLETIN_START -->
|
<!-- BINGSHUO_BULLETIN_START -->
|
||||||
| 时间 | 检查项 | 状态 |
|
| 时间 | 检查项 | 状态 |
|
||||||
|------|--------|------|
|
|------|--------|------|
|
||||||
|
| 03-10 22:19 | 🔧 Persona Studio 对话修复 · API代理层新增反向代理 · `/api/ps/chat/*`,`/api/ps/auth/*`,`/api/ps/build/*`,`/api/ps/notify/*` → PS后端(port 3002) · PM2 配置补全 · `m15-cloud-drive/` README.md 补全 | 铸渊(冰朔指令) |
|
||||||
|
| 03-10 22:19 | ✅ 铸渊模块自检完成 · 发现 2 个问题 · 自动修复 2 项 | 铸渊自检 |
|
||||||
| 03-10 21:57 | 🔧 系统更新: `.github/` | 铸渊 (Copilot) |
|
| 03-10 21:57 | 🔧 系统更新: `.github/` | 铸渊 (Copilot) |
|
||||||
| 03-10 21:57 | 🔧 系统更新: `scripts/` | 铸渊 (Copilot) |
|
| 03-10 21:57 | 🔧 系统更新: `scripts/` | 铸渊 (Copilot) |
|
||||||
| 03-10 21:54 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 |
|
| 03-10 21:54 | ✅ 📢 更新系统公告区 · 成功 | 冰朔 |
|
||||||
|
|
@ -98,9 +100,12 @@
|
||||||
### 🤖 铸渊自动提醒
|
### 🤖 铸渊自动提醒
|
||||||
|
|
||||||
<!-- BINGSHUO_ALERT_START -->
|
<!-- BINGSHUO_ALERT_START -->
|
||||||
> 🟢 **今日无需冰朔手动干预** · 系统一切正常
|
> 🟢 **铸渊模块自检完成 · 已自动修复 2 项**
|
||||||
>
|
>
|
||||||
> 🗓️ 2026-03-10 · 铸渊自动检测
|
> ✅ `api-proxy.js` 新增 Persona Studio 反向代理 · 修复对话无回复问题
|
||||||
|
> ✅ `m15-cloud-drive/` 补全 README.md
|
||||||
|
>
|
||||||
|
> 🗓️ 2026-03-10 · 铸渊自动修复
|
||||||
<!-- BINGSHUO_ALERT_END -->
|
<!-- BINGSHUO_ALERT_END -->
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -123,12 +128,11 @@
|
||||||
### 🤖 铸渊自动提醒 · 合作者
|
### 🤖 铸渊自动提醒 · 合作者
|
||||||
|
|
||||||
<!-- COLLABORATOR_ALERT_START -->
|
<!-- COLLABORATOR_ALERT_START -->
|
||||||
> 🔴 **以下合作者需要手动干预:**
|
> 🟢 **所有合作者模块自检通过** · 无需手动干预
|
||||||
>
|
>
|
||||||
> **🎨 燕樊(DEV-003):**
|
> ✅ `m15-cloud-drive/` README.md 已由铸渊自动补全
|
||||||
> - ⚠️ `m15-cloud-drive/` 缺少 README.md
|
|
||||||
>
|
>
|
||||||
> 🗓️ 2026-03-10 · 铸渊已发送邮件提醒
|
> 🗓️ 2026-03-10 · 铸渊自动修复
|
||||||
<!-- COLLABORATOR_ALERT_END -->
|
<!-- COLLABORATOR_ALERT_END -->
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,11 @@ curl http://localhost:3721/api/models
|
||||||
| GET | `/api/health` | 健康检查 |
|
| GET | `/api/health` | 健康检查 |
|
||||||
| POST | `/api/ps/apikey/detect-models` | 用户 API Key 模型检测(Persona Studio) |
|
| POST | `/api/ps/apikey/detect-models` | 用户 API Key 模型检测(Persona Studio) |
|
||||||
| POST | `/api/ps/apikey/chat` | 用户 API Key 对话(Persona Studio) |
|
| POST | `/api/ps/apikey/chat` | 用户 API Key 对话(Persona Studio) |
|
||||||
|
| POST | `/api/ps/chat/message` | 知秋对话(→ PS 后端 port 3002) |
|
||||||
|
| GET | `/api/ps/chat/history` | 对话历史(→ PS 后端 port 3002) |
|
||||||
|
| POST | `/api/ps/auth/login` | 开发编号登录(→ PS 后端 port 3002) |
|
||||||
|
| POST | `/api/ps/build/start` | 开发任务触发(→ PS 后端 port 3002) |
|
||||||
|
| POST | `/api/ps/notify/send` | 邮件通知(→ PS 后端 port 3002) |
|
||||||
|
|
||||||
### 环境变量
|
### 环境变量
|
||||||
|
|
||||||
|
|
@ -45,6 +50,7 @@ curl http://localhost:3721/api/models
|
||||||
| `OPENAI_API_KEY` | OpenAI 密钥(需海外服务器) |
|
| `OPENAI_API_KEY` | OpenAI 密钥(需海外服务器) |
|
||||||
| `GEMINI_API_KEY` | Google Gemini 密钥(需海外服务器) |
|
| `GEMINI_API_KEY` | Google Gemini 密钥(需海外服务器) |
|
||||||
| `PROXY_PORT` | 端口(默认 3721) |
|
| `PROXY_PORT` | 端口(默认 3721) |
|
||||||
|
| `PS_PORT` | Persona Studio 后端端口(默认 3002,反向代理目标) |
|
||||||
| `RATE_LIMIT_RPM` | 频率限制(默认 10 次/分钟) |
|
| `RATE_LIMIT_RPM` | 频率限制(默认 10 次/分钟) |
|
||||||
|
|
||||||
### Nginx 配置
|
### Nginx 配置
|
||||||
|
|
|
||||||
|
|
@ -709,6 +709,74 @@ async function handleApiKeyChat(req, res) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════
|
||||||
|
// Persona Studio 后端反向代理
|
||||||
|
// 将 /api/ps/chat/*, /api/ps/auth/*, /api/ps/build/*, /api/ps/notify/*
|
||||||
|
// 转发到 persona-studio 后端服务(默认端口 3002)
|
||||||
|
// ═══════════════════════════════════════════════════════
|
||||||
|
const PS_BACKEND_PORT = parseInt(process.env.PS_PORT || '3002', 10);
|
||||||
|
const PS_PROXY_PATHS = ['/api/ps/chat/', '/api/ps/auth/', '/api/ps/build/', '/api/ps/notify/'];
|
||||||
|
|
||||||
|
function shouldProxyToPersonaStudio(pathname) {
|
||||||
|
return PS_PROXY_PATHS.some(prefix => pathname.startsWith(prefix));
|
||||||
|
}
|
||||||
|
|
||||||
|
function proxyToPersonaStudio(req, res, fullPath) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const options = {
|
||||||
|
hostname: '127.0.0.1',
|
||||||
|
port: PS_BACKEND_PORT,
|
||||||
|
path: fullPath,
|
||||||
|
method: req.method,
|
||||||
|
headers: Object.assign({}, req.headers, {
|
||||||
|
host: '127.0.0.1:' + PS_BACKEND_PORT
|
||||||
|
}),
|
||||||
|
timeout: 60000
|
||||||
|
};
|
||||||
|
|
||||||
|
const proxyReq = http.request(options, (proxyRes) => {
|
||||||
|
// Forward status and headers (preserve CORS headers already set)
|
||||||
|
const headers = {};
|
||||||
|
for (const [key, value] of Object.entries(proxyRes.headers)) {
|
||||||
|
if (!key.startsWith('access-control-')) {
|
||||||
|
headers[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.writeHead(proxyRes.statusCode, headers);
|
||||||
|
proxyRes.pipe(res);
|
||||||
|
proxyRes.on('end', resolve);
|
||||||
|
proxyRes.on('error', reject);
|
||||||
|
});
|
||||||
|
|
||||||
|
proxyReq.on('error', (err) => {
|
||||||
|
console.error('[代理→PS] persona-studio 后端连接失败:', err.message);
|
||||||
|
if (!res.headersSent) {
|
||||||
|
jsonResponse(res, 502, {
|
||||||
|
error: true,
|
||||||
|
code: 'PS_BACKEND_UNAVAILABLE',
|
||||||
|
message: 'Persona Studio 后端服务不可用,请稍后重试'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
proxyReq.on('timeout', () => {
|
||||||
|
proxyReq.destroy();
|
||||||
|
if (!res.headersSent) {
|
||||||
|
jsonResponse(res, 504, {
|
||||||
|
error: true,
|
||||||
|
code: 'PS_BACKEND_TIMEOUT',
|
||||||
|
message: 'Persona Studio 后端响应超时'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Pipe the original request body to the proxy request
|
||||||
|
req.pipe(proxyReq);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════
|
||||||
// HTTP 服务器
|
// HTTP 服务器
|
||||||
// ═══════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════
|
||||||
|
|
@ -737,11 +805,13 @@ const server = http.createServer(async (req, res) => {
|
||||||
await handleDetectModels(req, res);
|
await handleDetectModels(req, res);
|
||||||
} else if (path === '/api/ps/apikey/chat' && req.method === 'POST') {
|
} else if (path === '/api/ps/apikey/chat' && req.method === 'POST') {
|
||||||
await handleApiKeyChat(req, res);
|
await handleApiKeyChat(req, res);
|
||||||
|
} else if (shouldProxyToPersonaStudio(path)) {
|
||||||
|
await proxyToPersonaStudio(req, res, url.pathname + url.search);
|
||||||
} else {
|
} else {
|
||||||
jsonResponse(res, 404, {
|
jsonResponse(res, 404, {
|
||||||
error: true,
|
error: true,
|
||||||
code: 'NOT_FOUND',
|
code: 'NOT_FOUND',
|
||||||
message: '接口不存在。可用接口: POST /api/chat, GET /api/models, GET /api/health, POST /api/ps/apikey/detect-models, POST /api/ps/apikey/chat'
|
message: '接口不存在。可用接口: POST /api/chat, GET /api/models, GET /api/health, POST /api/ps/apikey/detect-models, POST /api/ps/apikey/chat, POST /api/ps/chat/message, GET /api/ps/chat/history, POST /api/ps/auth/login'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
@ -781,11 +851,17 @@ server.listen(PORT, () => {
|
||||||
console.log(' export YUNWU_API_KEY=sk-xxx');
|
console.log(' export YUNWU_API_KEY=sk-xxx');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(`\n Persona Studio 后端代理: http://127.0.0.1:${PS_BACKEND_PORT}`);
|
||||||
|
console.log(' 代理路径: /api/ps/chat/*, /api/ps/auth/*, /api/ps/build/*, /api/ps/notify/*');
|
||||||
|
|
||||||
console.log('\n 可用接口:');
|
console.log('\n 可用接口:');
|
||||||
console.log(' POST /api/chat — 聊天代理(SSE 流式)');
|
console.log(' POST /api/chat — 聊天代理(SSE 流式)');
|
||||||
console.log(' GET /api/models — 列出可用模型');
|
console.log(' GET /api/models — 列出可用模型');
|
||||||
console.log(' GET /api/health — 健康检查');
|
console.log(' GET /api/health — 健康检查');
|
||||||
console.log(' POST /api/ps/apikey/detect-models — 用户 API Key 模型检测');
|
console.log(' POST /api/ps/apikey/detect-models — 用户 API Key 模型检测');
|
||||||
console.log(' POST /api/ps/apikey/chat — 用户 API Key 对话');
|
console.log(' POST /api/ps/apikey/chat — 用户 API Key 对话');
|
||||||
|
console.log(' POST /api/ps/chat/message — 知秋对话(→ PS后端)');
|
||||||
|
console.log(' GET /api/ps/chat/history — 对话历史(→ PS后端)');
|
||||||
|
console.log(' POST /api/ps/auth/login — 登录校验(→ PS后端)');
|
||||||
console.log('');
|
console.log('');
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -25,5 +25,33 @@ module.exports = {
|
||||||
error_file: 'logs/error.log',
|
error_file: 'logs/error.log',
|
||||||
out_file: 'logs/out.log',
|
out_file: 'logs/out.log',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'api-proxy',
|
||||||
|
script: 'backend-integration/api-proxy.js',
|
||||||
|
instances: 1,
|
||||||
|
exec_mode: 'fork',
|
||||||
|
watch: false,
|
||||||
|
env: {
|
||||||
|
NODE_ENV: 'production',
|
||||||
|
PROXY_PORT: 3721,
|
||||||
|
},
|
||||||
|
log_date_format: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
error_file: 'logs/api-proxy-error.log',
|
||||||
|
out_file: 'logs/api-proxy-out.log',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'persona-studio',
|
||||||
|
script: 'persona-studio/backend/server.js',
|
||||||
|
instances: 1,
|
||||||
|
exec_mode: 'fork',
|
||||||
|
watch: false,
|
||||||
|
env: {
|
||||||
|
NODE_ENV: 'production',
|
||||||
|
PS_PORT: 3002,
|
||||||
|
},
|
||||||
|
log_date_format: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
error_file: 'logs/persona-studio-error.log',
|
||||||
|
out_file: 'logs/persona-studio-out.log',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
# M15 云盘系统
|
||||||
|
|
||||||
|
- 负责人:燕樊(DEV-003)
|
||||||
|
- 状态:已毕业
|
||||||
|
- 技术栈:HTML + CSS + JavaScript(纯前端)
|
||||||
|
- 依赖模块:无
|
||||||
|
|
||||||
|
## 功能说明
|
||||||
|
|
||||||
|
HoloLake 网站云盘系统前端界面,提供文件管理交互体验。
|
||||||
|
|
||||||
|
### 包含文件
|
||||||
|
|
||||||
|
| 文件 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `cloud-drive.html` | 云盘主页面 |
|
||||||
|
| `cloud-drive.js` | 交互逻辑(文件夹切换、文件选中、上传等) |
|
||||||
|
| `cloud-drive-style.css` | 样式表 |
|
||||||
|
|
||||||
|
### 核心功能
|
||||||
|
|
||||||
|
- 📁 文件夹切换与导航
|
||||||
|
- 📄 文件列表展示与选中
|
||||||
|
- ⬆️ 文件上传交互
|
||||||
|
- 💾 存储用量展示
|
||||||
Loading…
Reference in New Issue