warrior 3 ساعت پیش
والد
کامیت
a56216f3e6
3فایلهای تغییر یافته به همراه211 افزوده شده و 2 حذف شده
  1. 127 0
      api/README.md
  2. 82 0
      api/routes.ts
  3. 2 2
      server.ts

+ 127 - 0
api/README.md

@@ -0,0 +1,127 @@
+# API 路由自动加载说明
+
+## 功能说明
+
+路由加载器会自动扫描 `./api/` 目录下的所有 `routes*.ts` 文件,并根据文件路径和名称自动挂载到 Express 应用。
+
+## 目录结构规范
+
+```
+api/
+└── module/
+    └── user/
+        ├── routes.ts          -> 挂载到 /api/user
+        └── routes-admin.ts    -> 挂载到 /api/user/admin
+```
+
+## 路由挂载规则
+
+### 1. 基础路由 (routes.ts)
+- **文件路径**: `./api/module/user/routes.ts`
+- **挂载路径**: `/api/user`
+- **规则**: 使用父目录名称作为路由路径
+
+### 2. 子路由 (routes-xxx.ts)
+- **文件路径**: `./api/module/user/routes-admin.ts`
+- **挂载路径**: `/api/user/admin`
+- **规则**: `routes-` 后面的部分作为子路径
+
+## 路由文件编写规范
+
+每个路由文件必须导出一个 Express Router 实例:
+
+```typescript
+import express from "npm:express";
+
+const router = express.Router();
+
+// 定义路由
+router.get("/", (req, res) => {
+  res.json({ message: "Hello" });
+});
+
+// 必须使用 default export
+export default router;
+```
+
+## 示例
+
+### 示例 1: 用户基础 API
+
+**文件**: `./api/module/user/routes.ts`
+
+```typescript
+import express from "npm:express";
+
+const router = express.Router();
+
+// GET /api/user
+router.get("/", (req, res) => {
+  res.json({ message: "User API" });
+});
+
+// GET /api/user/list
+router.get("/list", (req, res) => {
+  res.json({ users: [] });
+});
+
+export default router;
+```
+
+### 示例 2: 用户管理 API
+
+**文件**: `./api/module/user/routes-admin.ts`
+
+```typescript
+import express from "npm:express";
+
+const router = express.Router();
+
+// GET /api/user/admin
+router.get("/", (req, res) => {
+  res.json({ message: "Admin API" });
+});
+
+// POST /api/user/admin/create
+router.post("/create", (req, res) => {
+  res.json({ message: "Create user" });
+});
+
+export default router;
+```
+
+## 注意事项
+
+1. **文件命名**: 必须以 `routes` 开头,扩展名为 `.ts`
+2. **导出方式**: 必须使用 `export default` 导出路由
+3. **目录结构**: 路由文件必须放在至少两级子目录下(如 `api/module/xxx/`)
+4. **路径冲突**: 避免创建路径冲突的路由文件
+
+## 启动日志
+
+服务器启动时会显示加载的路由信息:
+
+```
+🔍 正在扫描路由文件...
+📦 找到 2 个路由文件:
+   ⏳ 加载: /api/user <- /path/to/api/module/user/routes.ts
+   ✅ 已挂载: /api/user
+   ⏳ 加载: /api/user/admin <- /path/to/api/module/user/routes-admin.ts
+   ✅ 已挂载: /api/user/admin
+🎉 路由加载完成!
+```
+
+## 测试路由
+
+启动服务器后,可以使用以下命令测试路由:
+
+```bash
+# 测试基础路由
+curl http://localhost:3000/api/user
+
+# 测试子路由
+curl http://localhost:3000/api/user/admin
+
+# 测试具体接口
+curl http://localhost:3000/api/user/list
+```

+ 82 - 0
api/routes.ts

@@ -0,0 +1,82 @@
+/**
+ * API 路由主入口
+ * 手动加载并挂载所有子路由模块
+ */
+import express from 'npm:express';
+
+// 创建主路由
+const router = express.Router();
+
+console.log('[API Routes] Initializing...');
+
+// Debug middleware
+router.use((req, res, next) => {
+  console.log(`[API Router] Hit: ${req.method} ${req.url} (Original: ${req.originalUrl})`);
+  next();
+});
+
+router.get('/ping', (req, res) => {
+  res.json({ message: 'pong' });
+});
+
+let createSpApiRouter;
+try {
+  ({ createSpApiRouter } = await globalThis.loadModule(
+    "https://repos.fmode.cn/x/fmode-amazon-sp-api/0.0.7/fmode-amazon-sp-api.min.js?code=xxxxxxx"
+  ));
+} catch (e) {
+  console.warn("[API Routes] CDN 加载失败, 使用本地模块回退", e);
+  // ({ createSpApiRouter } = await import("../modules/fmode-amazon-sp-api/src/mod.ts"));
+}
+
+// 本地开发模式加载
+//const { createSpApiRouter } = await import("../modules/fmode-amazon-sp-api/src/mod.ts");
+
+// 挂载 SP-API 路由
+router.use('/amazon', createSpApiRouter());
+
+let createSorftimeRouter;
+try {
+  ({ createSorftimeRouter } = await globalThis.loadModule(
+    'https://repos.fmode.cn/x/fmode-sorftime-api/0.0.1/fmode-sorftime-api.min.js?code=xxxxxxx'
+  ));
+} catch (e) {
+  console.warn("[API Routes] CDN 加载失败, 使用本地模块回退", e);
+  // ({ createSorftimeRouter } = await import('../modules/fmode-sorftime-api/src/mod.ts'));
+}
+
+router.use('/sorftime', createSorftimeRouter());
+
+let createTikHubRoutes;
+try {
+  ({ createTikHubRoutes } = await globalThis.loadModule(
+    'https://repos.fmode.cn/x/fmode-tikhub-api/0.0.1/fmode-tikhub-api.min.js?code=xxxxxxx'
+  ));
+} catch (e) {
+  console.warn("[API Routes] CDN 加载失败, 使用本地模块回退", e);
+  // ({ createTikHubRoutes } = await import('../modules/fmode-tikhub-api/src/mod.ts'));
+}
+
+router.use(
+  '/tikhub',
+  createTikHubRoutes({
+    basePath: '/api/tikhub',
+    apiKey: 'tKIbAsEM8X+GmE2vHqGW7D/ICwK1Q5V4viKFrWiPB6HholGdLFqZJmmyNw=='
+  })
+);
+router.get('/', (req, res) => {
+  res.json({
+    message: 'API Routes Loaded Successfully',
+    version: '1.0.0',
+    timestamp: new Date().toISOString(),
+    availableRoutes: [
+      '/api/amazon',
+      '/api/amazon/test',
+      '/api/sorftime',
+      '/api/sorftime/test',
+      '/api/tikhub',
+      '/api/tikhub/health'
+    ]
+  });
+});
+export default router;

+ 2 - 2
server.ts

@@ -8,7 +8,7 @@ const Parse = require('parse/node');
 
 Parse.initialize('hb-voc');
 
-Parse.serverURL = 'http://hb-server.fmode.cn/parse';
+Parse.serverURL = 'https://partyvoc.com//parse';
 
 Parse.masterKey = 'hb2026pallt';
 
@@ -30,7 +30,7 @@ function getConfig() {
       parse: {
         port: 3000,
         appId: 'hb-voc',
-        serverURL: 'http://hb-server.fmode.cn/parse'
+        serverURL: 'https://partyvoc.com//parse'
       }
     };
   }