require("dotenv").config(); const express = require("express"); const helmet = require("helmet"); const rateLimit = require("express-rate-limit"); const app = express(); app.use(helmet()); app.use(express.json({ limit: "1mb" })); app.use(express.static("public")); const DEEPSEEK_API_KEY = process.env.DEEPSEEK_API_KEY; const BASE_URL = process.env.DEEPSEEK_BASE_URL || "https://api.deepseek.com"; if (!DEEPSEEK_API_KEY) { console.error("Missing env: DEEPSEEK_API_KEY"); process.exit(1); } // 只对 API 做限流(防止被刷) app.use("/api/", rateLimit({ windowMs: 60 * 1000, max: 60, standardHeaders: true, legacyHeaders: false, })); app.get("/api/health", (req, res) => { res.json({ ok: true }); }); // Chat API:假设已经由 Nginx Basic Auth 保护了整个站点 app.post("/api/chat", async (req, res) => { try { const { model, messages, temperature } = req.body || {}; if (!model || !Array.isArray(messages)) { return res.status(400).json({ error: "model/messages required" }); } const r = await fetch(`${BASE_URL}/v1/chat/completions`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${DEEPSEEK_API_KEY}`, }, body: JSON.stringify({ model, // deepseek-chat / deepseek-reasoner messages, temperature: typeof temperature === "number" ? temperature : 0.7, }), }); const data = await r.json(); if (!r.ok) { // 把 DeepSeek 返回透出,方便你排障(不会暴露 API key) return res.status(r.status).json(data); } const reply = data?.choices?.[0]?.message?.content ?? ""; return res.json({ reply }); } catch (e) { return res.status(500).json({ error: String(e) }); } }); // 只监听本机回环:外网只能走 Nginx(更安全) app.listen(3000, "127.0.0.1", () => { console.log("DS WebUI listening on 127.0.0.1:3000"); });