From 8958f14577c0ead18656236cb74f9f901bc7d5b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B7=91=E5=A9=B7=E9=99=88?= Date: Sat, 7 Mar 2026 16:20:04 +0800 Subject: [PATCH] =?UTF-8?q?Step=203:=20=E5=86=B7=E5=90=AF=E5=8A=A8?= =?UTF-8?q?=E7=83=AD=E8=BA=AB=E6=8E=A5=E5=8F=A3=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/routes/coldstart.js | 134 ++++++++++++++++++++++++++++++++++++ backend/server.js | 4 +- backend/server.js.bak | 38 ++++++++++ 3 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 backend/routes/coldstart.js create mode 100644 backend/server.js.bak diff --git a/backend/routes/coldstart.js b/backend/routes/coldstart.js new file mode 100644 index 00000000..b231b885 --- /dev/null +++ b/backend/routes/coldstart.js @@ -0,0 +1,134 @@ +const express = require('express'); +const axios = require('axios'); +const router = express.Router(); + +// 冷启动热身接口 +router.post('/', async (req, res) => { + try { + // 并行执行四项检查 + const [notion, primary, fallback, feishu] = await Promise.allSettled([ + checkNotion(), + checkPrimaryAPI(), + checkFallbackAPI(), + checkFeishu() + ]); + + const result = { + status: 'ok', + message: '冷启动热身完成', + checks: { + notion_connection: notion.status === 'fulfilled' ? notion.value : false, + primary_api: primary.status === 'fulfilled' ? primary.value : false, + fallback_api: fallback.status === 'fulfilled' ? fallback.value : false, + feishu_connection: feishu.status === 'fulfilled' ? feishu.value : false + }, + timestamp: new Date().toISOString() + }; + + res.json(result); + } catch (err) { + res.status(500).json({ + status: 'error', + message: '冷启动检查失败', + error: err.message + }); + } +}); + +// 检查 Notion 连接 +async function checkNotion() { + try { + const token = process.env.NOTION_TOKEN; + if (!token) return false; + // 轻量检查:读取 Notion 用户信息 + const response = await axios.get('https://api.notion.com/v1/users/me', { + headers: { + 'Authorization': `Bearer ${token}`, + 'Notion-Version': '2022-06-28' + }, + timeout: 5000 + }); + return response.status === 200; + } catch { + return false; + } +} + +// 检查主 API +async function checkPrimaryAPI() { + try { + const key = process.env.PRIMARY_API_KEY; + if (!key) return false; + // 轻量检查:调用一个简单的测试接口 + const response = await axios.post( + 'https://api.deepseek.com/v1/chat/completions', + { + model: 'deepseek-chat', + messages: [{ role: 'user', content: 'ping' }], + max_tokens: 5 + }, + { + headers: { + 'Authorization': `Bearer ${key}`, + 'Content-Type': 'application/json' + }, + timeout: 5000 + } + ); + return response.status === 200; + } catch { + return false; + } +} + +// 检查备用 API +async function checkFallbackAPI() { + try { + const key = process.env.FALLBACK_API_KEY; + if (!key) return false; + const response = await axios.post( + 'https://api.deepseek.com/v1/chat/completions', + { + model: 'deepseek-chat', + messages: [{ role: 'user', content: 'ping' }], + max_tokens: 5 + }, + { + headers: { + 'Authorization': `Bearer ${key}`, + 'Content-Type': 'application/json' + }, + timeout: 5000 + } + ); + return response.status === 200; + } catch { + return false; + } +} + +// 检查飞书连接 +async function checkFeishu() { + try { + const appId = process.env.FEISHU_APP_ID; + const appSecret = process.env.FEISHU_APP_SECRET; + if (!appId || !appSecret) return false; + // 获取 tenant_access_token + const response = await axios.post( + 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal', + { + app_id: appId, + app_secret: appSecret + }, + { + headers: { 'Content-Type': 'application/json' }, + timeout: 5000 + } + ); + return response.data.code === 0; + } catch { + return false; + } +} + +module.exports = router; diff --git a/backend/server.js b/backend/server.js index b58be470..f89f68cf 100644 --- a/backend/server.js +++ b/backend/server.js @@ -10,17 +10,19 @@ app.use(express.json()); const notionRoutes = require('./routes/notion'); const feishuRoutes = require('./routes/feishu'); const routerRoutes = require('./routes/router'); +const coldstartRoutes = require('./routes/coldstart'); app.use('/notion', notionRoutes); app.use('/feishu', feishuRoutes); app.use('/router', routerRoutes); +app.use('/api/coldstart', coldstartRoutes); app.get('/', (req, res) => { res.json({ status: 'ok', message: 'HoloLake 后端服务运行中', version: '0.2.0', - routes: ['/notion/test', '/feishu/test', '/router/test', '/router/chat'] + routes: ['/notion/test', '/feishu/test', '/router/test', '/router/chat', '/api/coldstart'] }); }); diff --git a/backend/server.js.bak b/backend/server.js.bak new file mode 100644 index 00000000..b58be470 --- /dev/null +++ b/backend/server.js.bak @@ -0,0 +1,38 @@ +require('dotenv').config(); +const express = require('express'); +const cors = require('cors'); + +const app = express(); +app.use(cors()); +app.use(express.json()); + +// 路由引入 +const notionRoutes = require('./routes/notion'); +const feishuRoutes = require('./routes/feishu'); +const routerRoutes = require('./routes/router'); + +app.use('/notion', notionRoutes); +app.use('/feishu', feishuRoutes); +app.use('/router', routerRoutes); + +app.get('/', (req, res) => { + res.json({ + status: 'ok', + message: 'HoloLake 后端服务运行中', + version: '0.2.0', + routes: ['/notion/test', '/feishu/test', '/router/test', '/router/chat'] + }); +}); + +const PORT = process.env.PORT || 3000; +// 飞书 Webhook 处理 +app.post('/webhook/feishu', (req, res) => { + console.log('收到飞书请求:', req.body); + if (req.body.challenge) { + return res.json({ challenge: req.body.challenge }); + } + res.json({ message: 'received' }); +}); +app.listen(PORT, () => { + console.log(`🚀 服务启动成功,端口:${PORT}`); +});