Преглед изворни кода

✨ feat(stock-api): add stock history data formatting and calculation

- implement data formatting to match API schema requirements
- add calculation for zd (涨跌额), zde (涨跌幅), zf (振幅) fields
- format transaction time to YYYY-MM-DD format using dayjs

🔧 chore(server): enable global request logging middleware

- uncomment and enable Hono logger middleware to log all requests
yourname пре 7 месеци
родитељ
комит
f14b6bcabb
2 измењених фајлова са 51 додато и 3 уклоњено
  1. 1 1
      server.js
  2. 50 2
      src/server/api/stock-data/history/[code]/get.ts

+ 1 - 1
server.js

@@ -18,7 +18,7 @@ import { Server } from 'socket.io';
 const app = new Hono();// API路由
 
 // 全局使用 Hono 日志中间件(记录所有请求)
-// app.use('*', logger());
+app.use('*', logger());
 app.use('*', cors(
   // {
   //   origin: ['http://localhost:3000'],

+ 50 - 2
src/server/api/stock-data/history/[code]/get.ts

@@ -5,6 +5,7 @@ import { StockDataService } from '@/server/modules/stock/stock-data.service';
 import { AuthContext } from '@/server/types/context';
 import { authMiddleware } from '@/server/middleware/auth.middleware';
 import { ErrorSchema } from '@/server/utils/errorHandler';
+import dayjs from 'dayjs';
 
 // 路径参数Schema
 const GetStockHistoryParams = z.object({
@@ -120,9 +121,56 @@ const app = new OpenAPIHono<AuthContext>().openapi(routeDef, async (c) => {
     const { code } = c.req.valid('param');
     const service = new StockDataService(AppDataSource);
     
-    const data = await service.getStockHistory(code);
+    const rawData = await service.getStockHistory(code);
     
-    return c.json({ data }, 200);
+    // 转换服务输出格式为schema要求的格式
+    const formattedData = rawData.map(item => ({
+      d: dayjs(item.t).format('YYYY-MM-DD') ,                    // 交易时间 -> 日期
+      o: item.o,                    // 开盘价
+      h: item.h,                    // 最高价
+      l: item.l,                    // 最低价
+      c: item.c,                    // 收盘价
+      v: item.v,                    // 成交量
+      e: item.a,                    // 成交额 -> 成交额
+      zf: 0,                        // 振幅 (计算值)
+      hs: 0,                        // 换手率 (计算值)
+      zd: 0,                        // 涨跌额 (计算值)
+      zde: 0,                       // 涨跌幅 (计算值)
+      ud: new Date().toISOString()  // 最后更新时间
+    }));
+    
+    // 计算衍生字段
+    const processedData = formattedData.map((item, index, array) => {
+      if (index === 0) {
+        // 第一条数据无法计算涨跌
+        return {
+          ...item,
+          zd: 0,
+          zde: 0,
+          zf: 0
+        };
+      }
+      
+      const prevItem = array[index - 1];
+      const zd = item.c - prevItem.c;  // 涨跌额
+      const zde = prevItem.c !== 0 ? (zd / prevItem.c) * 100 : 0;  // 涨跌幅百分比
+      const zf = prevItem.c !== 0 ? ((item.h - item.l) / prevItem.c) * 100 : 0;  // 振幅百分比
+      
+      return {
+        ...item,
+        zd: parseFloat(zd.toFixed(2)),
+        zde: parseFloat(zde.toFixed(2)),
+        zf: parseFloat(zf.toFixed(2))
+      };
+    });
+    
+    // 设置换手率为0(需要从其他数据源获取)
+    const finalData = processedData.map(item => ({
+      ...item,
+      hs: 0
+    }));
+    
+    return c.json({ data: finalData }, 200);
   } catch (error) {
     const { code = 500, message = '获取股票历史数据失败' } = error as Error & { code?: number };
     return c.json({ code, message }, 500);