Files
newapi-dashboard/server/routes/sites.ts
LAMCLOD f6036cab66 feat: newapi-dashboard 全栈项目初始化
为 new-api (LLM API 网关) 构建独立前端管理面板:
- React 18 + TypeScript + Vite + Ant Design 5 前端
- Node.js + Express + better-sqlite3 BFF 后端
- 登录页: 站点选择器 + UserID + AccessToken 认证
- 仪表盘: 用户信息、额度环形图、7天趋势图、模型饼图、令牌概览、日志时间线
- 账单页: 筛选日志表格、模型消耗柱状图、充值记录、CSV/PDF 导出(HMAC签名)
- 管理员站点管理: 站点 CRUD
- API 代理: 多站点切换,会话管理

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 18:00:28 +08:00

42 lines
1.5 KiB
TypeScript

import { Router, Request, Response } from 'express'
import db from '../db.js'
const router = Router()
// GET /api/sites — list all sites (public, for login page)
router.get('/', (_req: Request, res: Response) => {
const sites = db.prepare('SELECT id, name, url, created_at, updated_at FROM sites ORDER BY id').all()
res.json({ success: true, data: sites })
})
// POST /api/sites — create site
router.post('/', (req: Request, res: Response) => {
const { name, url } = req.body
if (!name || !url) {
res.json({ success: false, message: '站点名称和 URL 不能为空' })
return
}
const result = db.prepare('INSERT INTO sites (name, url) VALUES (?, ?)').run(name, url.replace(/\/+$/, ''))
const site = db.prepare('SELECT * FROM sites WHERE id = ?').get(result.lastInsertRowid)
res.json({ success: true, data: site })
})
// PUT /api/sites/:id — update site
router.put('/:id', (req: Request, res: Response) => {
const { name, url } = req.body
const { id } = req.params
db.prepare("UPDATE sites SET name = ?, url = ?, updated_at = datetime('now') WHERE id = ?")
.run(name, url.replace(/\/+$/, ''), id)
const site = db.prepare('SELECT * FROM sites WHERE id = ?').get(id)
res.json({ success: true, data: site })
})
// DELETE /api/sites/:id — delete site
router.delete('/:id', (req: Request, res: Response) => {
const { id } = req.params
db.prepare('DELETE FROM sites WHERE id = ?').run(id)
res.json({ success: true })
})
export default router