Files
ln-bi/src/server/index.ts
kkfluous e8f1604c11
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
feat: 全局反馈系统 + 各模块底部统一动态提示
- 新增 components/RotatingFooterHint:统一文案+蓝色脉冲,4 秒轮换
- 新增 components/FeedbackFab:右下角悬浮按钮(渐变 + 心形信封 + 黄色脉冲点),
  点击打开 4 步引导式弹窗
    Step 1 选类型(💡新维度 / 🐛bug / 🎨界面 / 📝其他)
    Step 2 描述需求 + 选当前板块(chip)
    Step 3 留联系方式(可选)+ 提交概览
    Step 4 ❤️ 成功页(弹簧 √ 动画)
  顶部 spring 进度条,底部上一步/下一步,下拉手柄,背景点击或 X 关闭
- 后端 routes/feedback:bi_user_feedback 表(自动建表,含 status 字段)
  POST /api/feedback/submit + GET /api/feedback/list
- Shell 全局挂载 FeedbackFab,自动从 hash 检测当前模块
- 各模块底部追加 RotatingFooterHint:
  AssetsModule / MileageModule / SchedulingModule / EleImportPage
  HydrogenOverview / HydrogenDaily / ElectricOverview / ElectricDaily
  (HydrogenOverview 旧的内嵌实现已替换为共享组件)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 13:50:39 +08:00

48 lines
1.7 KiB
TypeScript

import { serve } from '@hono/node-server';
import { serveStatic } from '@hono/node-server/serve-static';
import { Hono } from 'hono';
import { cors } from 'hono/cors';
import dotenv from 'dotenv';
import vehiclesRouter from './routes/vehicles.js';
import mileageRouter from './routes/mileage/index.js';
import schedulingRouter from './routes/scheduling/index.js';
import energyRouter from './routes/energy/index.js';
import eleRouter from './routes/ele/index.js';
import feedbackRouter from './routes/feedback/index.js';
import { ensureSchedulingTables } from './routes/scheduling/db-schema.js';
import authRouter from './auth/login.js';
import { authMiddleware } from './auth/middleware.js';
dotenv.config();
const app = new Hono();
app.use('/api/*', cors());
// Auth 路由(不需要中间件)
app.route('/api/auth', authRouter);
// Auth 中间件(保护后续所有 /api/* 路由)
app.use('/api/*', authMiddleware);
app.route('/api/vehicles', vehiclesRouter);
app.route('/api/mileage', mileageRouter);
app.route('/api/scheduling', schedulingRouter);
app.route('/api/energy', energyRouter);
app.route('/api/ele', eleRouter);
app.route('/api/feedback', feedbackRouter);
app.get('/api/health', (c) => c.json({ status: 'ok', time: new Date().toISOString() }));
// Serve static files in production
app.use('/*', serveStatic({ root: './dist' }));
app.use('/*', serveStatic({ root: './dist', path: 'index.html' }));
const port = Number(process.env.SERVER_PORT) || 3001;
console.log(`Server starting on port ${port}...`);
ensureSchedulingTables().catch(e => console.error('scheduling bootstrap error:', e));
serve({ fetch: app.fetch, port }, () => {
console.log(`Server running at http://localhost:${port}`);
});