Просмотр исходного кода

fix: 修复 SSR 环境 TypeORM 实体加载问题

将 TypeORM 实体加载方式从 glob 模式改为类导入,解决 Vite SSR 环境下的 .ts 文件加载错误。

- 新增 packages/server/src/entities.ts 集中导出所有实体类
- data-source.ts 使用类导入而非 glob 通配符
- 添加缺失的路由导入

问题根因:Node.js ESM 无法直接加载 .ts 文件,而 glob 模式依赖 TypeORM 在运行时加载。
解决方案:使用类导入让 Vite SSR 处理 TypeScript 编译,将编译后的类传给 TypeORM。

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
yourname 6 дней назад
Родитель
Сommit
1791181a2c
3 измененных файлов с 57 добавлено и 15 удалено
  1. 6 15
      packages/server/src/data-source.ts
  2. 36 0
      packages/server/src/entities.ts
  3. 15 0
      packages/server/src/index.ts

+ 6 - 15
packages/server/src/data-source.ts

@@ -1,19 +1,13 @@
 import "reflect-metadata"
 import "reflect-metadata"
 import { DataSource } from "typeorm"
 import { DataSource } from "typeorm"
 import process from 'node:process'
 import process from 'node:process'
+import * as entities from './entities'
 
 
 /**
 /**
- * TypeORM 迁移数据源配置
+ * TypeORM 数据源配置
  *
  *
- * 此文件专用于 TypeORM 迁移 CLI 命令:
- * - pnpm migration:show
- * - pnpm migration:run
- * - pnpm migration:revert
- *
- * 注意:
- * - 使用 glob 模式加载实体,避免循环依赖
- * - 关闭自动同步(synchronize: false)
- * - 迁移通过 glob 模式加载
+ * 使用类导入方式加载实体,让 Vite SSR 正确处理 TypeScript 编译
+ * 实体内部已使用字符串语法解决循环依赖问题
  */
  */
 export const AppDataSource = new DataSource({
 export const AppDataSource = new DataSource({
   type: "postgres",
   type: "postgres",
@@ -22,11 +16,8 @@ export const AppDataSource = new DataSource({
   username: process.env.DB_USERNAME || "postgres",
   username: process.env.DB_USERNAME || "postgres",
   password: process.env.DB_PASSWORD || "",
   password: process.env.DB_PASSWORD || "",
   database: process.env.DB_DATABASE || "postgres",
   database: process.env.DB_DATABASE || "postgres",
-  // 使用 glob 模式加载实体,避免循环依赖
-  entities: [
-    "../allin-packages/*/src/entities/*.ts",
-    "../packages/*/src/entities/*.ts",
-  ],
+  // 使用类导入方式,Vite SSR 会处理 TypeScript 编译
+  entities: Object.values(entities),
   migrations: [
   migrations: [
     "./migrations/*[0-9].ts",  // 只匹配数字时间戳开头的迁移文件,排除 index.ts
     "./migrations/*[0-9].ts",  // 只匹配数字时间戳开头的迁移文件,排除 index.ts
   ],
   ],

+ 36 - 0
packages/server/src/entities.ts

@@ -0,0 +1,36 @@
+/**
+ * TypeORM 实体类集中导出
+ *
+ * 统一导出所有实体类,供 data-source.ts 使用
+ * 只包含 packages/server 实际依赖的包中的实体
+ * 使用 pnpm workspace 包名导入
+ * 使用类导入而非 glob 模式,让 Vite SSR 正确处理 TypeScript 编译
+ */
+
+// allin-packages 实体(使用 @d8d/allin-* 包名)
+export { Platform } from '@d8d/allin-platform-module';
+export { Channel } from '@d8d/allin-channel-module';
+export { Company } from '@d8d/allin-company-module';
+export {
+  DisabledPerson,
+  DisabledBankCard,
+  DisabledPhoto,
+  DisabledRemark,
+  DisabledVisit,
+  DisabledPersonGuardianPhone
+} from '@d8d/allin-disability-module';
+export {
+  OrderPerson,
+  OrderPersonAsset,
+  EmploymentOrder
+} from '@d8d/allin-order-module';
+export { SalaryLevel } from '@d8d/allin-salary-module';
+
+// packages 核心模块实体(使用 @d8d/core-module/xxx/entities)
+export { UserEntity, Role } from '@d8d/core-module/user-module/entities';
+export { File } from '@d8d/core-module/file-module/entities';
+export { SystemConfig } from '@d8d/core-module/system-config-module/entities';
+
+// packages 业务模块实体
+export { AreaEntity } from '@d8d/geo-areas';
+export { BankName } from '@d8d/bank-names-module';

+ 15 - 0
packages/server/src/index.ts

@@ -9,6 +9,21 @@ import { AppDataSource } from './data-source'
 import { Hono } from 'hono'
 import { Hono } from 'hono'
 import { databaseBackup } from './utils/backup'
 import { databaseBackup } from './utils/backup'
 
 
+// 导入区域相关路由
+import { areasRoutes, adminAreasRoutes } from '@d8d/geo-areas'
+
+// 导入 allin 模块路由
+import { channelRoutes } from '@d8d/allin-channel-module'
+import { companyRoutes, companyEnterpriseRoutes } from '@d8d/allin-company-module'
+import { disabledPersonRoutes, personExtensionRoutes, talentPersonalInfoRoutes } from '@d8d/allin-disability-module'
+import { orderRoutes, enterpriseOrderRoutes, talentEmploymentRoutes } from '@d8d/allin-order-module'
+import { platformRoutes } from '@d8d/allin-platform-module'
+import { salaryRoutes } from '@d8d/allin-salary-module'
+import { statisticsRoutes } from '@d8d/allin-statistics-module'
+
+// 导入其他模块路由
+import { bankNameRoutes } from '@d8d/bank-names-module'
+
 // 使用 data-source.ts 中定义的 AppDataSource(包含所有实体和迁移配置)
 // 使用 data-source.ts 中定义的 AppDataSource(包含所有实体和迁移配置)
 if(!AppDataSource || !AppDataSource.isInitialized) {
 if(!AppDataSource || !AppDataSource.isInitialized) {
   await AppDataSource.initialize();
   await AppDataSource.initialize();