浏览代码

📝 docs(prd): update multi-tenant integration plan with UI implementation details
- add detailed implementation steps for tenant UI package integration
- include bash commands for directory copying and file modifications
- add code examples for tenant routes and authentication provider

♻️ refactor(module): adjust internal module import paths in core modules
- update auth-module-mt imports in file-module-mt routes to use relative paths
- fix user-module-mt imports in auth-module-mt middleware to use relative paths
- replace package imports with relative paths for better internal module referencing

yourname 1 月之前
父节点
当前提交
37e2aa32f5

+ 62 - 1
docs/prd/epic-008-server-web-multi-tenant-integration.md

@@ -102,7 +102,7 @@ packages/
 
 3. **Story 3:** 租户模块集成到server - 将租户模块包(@d8d/tenant-module-mt)集成到server中,包括租户管理路由、超级管理员认证和租户数据隔离功能,确保server能够支持租户管理操作
 
-4. **Story 4:** 租户UI包集成到Web - 将多租户UI包集成到Web应用中,包括租户管理界面、租户切换功能和租户感知的UI组件,确保Web应用能够支持多租户操作和界面展示
+4. **Story 4:** 租户UI包集成到Web - 复制`web/src/client/admin`目录为`web/src/client/tenant`,在tenant目录中集成多租户UI包,替换原有的auth provider、登录页等组件,确保Web应用能够支持多租户操作和界面展示
 
 ### 阶段 3: 系统集成和验证
 
@@ -190,6 +190,67 @@ import { GoodsManagement } from '@d8d/goods-management-ui-mt'  // 改为多租
 }
 ```
 
+### 租户UI包集成实施步骤
+
+```bash
+# 1. 复制admin目录为tenant目录
+cp -r web/src/client/admin web/src/client/tenant
+
+# 2. 修改tenant目录中的关键文件
+# - web/src/client/tenant/index.tsx: 替换AuthProvider为租户专用的AuthProvider
+# - web/src/client/tenant/hooks/AuthProvider.tsx: 实现租户感知的认证逻辑
+# - web/src/client/tenant/pages/Login.tsx: 添加租户选择功能
+# - web/src/client/tenant/routes.tsx: 添加租户管理路由
+
+# 3. 集成租户管理UI包
+# - 在routes.tsx中添加租户管理路由
+# - 在api_init.ts中初始化租户管理客户端
+```
+
+```typescript
+// web/src/client/tenant/routes.tsx - 添加租户管理路由
+import { TenantManagement } from '@d8d/tenant-management-ui-mt';
+
+// 在路由配置中添加
+{
+  path: 'tenants',
+  element: <TenantManagement />,  // 租户管理界面
+},
+
+// web/src/client/tenant/hooks/AuthProvider.tsx - 租户感知的认证
+const handleLogin = async (username: string, password: string, tenantId?: number): Promise<void> => {
+  // 添加租户ID到登录请求
+  const response = await authClient.login.$post({
+    json: {
+      username,
+      password,
+      tenantId
+    }
+  });
+  // ... 其他登录逻辑
+};
+
+// web/src/client/tenant/pages/Login.tsx - 添加租户选择
+const [selectedTenant, setSelectedTenant] = useState<number | null>(null);
+
+// 在表单中添加租户选择器
+<FormField
+  control={form.control}
+  name="tenantId"
+  render={({ field }) => (
+    <FormItem>
+      <FormLabel>选择租户</FormLabel>
+      <FormControl>
+        <TenantSelect
+          value={field.value}
+          onChange={field.onChange}
+        />
+      </FormControl>
+    </FormItem>
+  )}
+/>
+```
+
 ### API客户端初始化
 
 ```typescript

+ 2 - 2
packages/core-module-mt/auth-module-mt/src/middleware/auth.middleware.mt.ts

@@ -1,10 +1,10 @@
 import { Context, Next } from 'hono';
 import { AuthService } from '../services/index.mt';
-import { UserServiceMt } from '@d8d/core-module-mt/user-module-mt';
+import { UserServiceMt } from '../../../user-module-mt/src/services/index.mt';
 import { AppDataSource } from '@d8d/shared-utils';
 import { AuthContext } from '@d8d/shared-types';
 import { parseWithAwait } from '@d8d/shared-utils';
-import { UserSchemaMt } from '@d8d/core-module-mt/user-module-mt';
+import { UserSchemaMt } from '../../../user-module-mt/src/schemas/index.mt';
 
 export async function authMiddleware(c: Context<AuthContext>, next: Next) {
   try {

+ 1 - 1
packages/core-module-mt/file-module-mt/src/routes/[id]/delete.mt.ts

@@ -3,7 +3,7 @@ import { FileServiceMt } from '../../services/index';
 import { ErrorSchema } from '@d8d/shared-utils';
 import { AppDataSource } from '@d8d/shared-utils';
 import { AuthContext } from '@d8d/shared-types';
-import { authMiddleware } from '@d8d/core-module-mt/auth-module-mt';
+import { authMiddleware } from '../../../../auth-module-mt/src/middleware/index.mt';
 
 // 删除文件路由
 const deleteFileRoute = createRoute({

+ 1 - 1
packages/core-module-mt/file-module-mt/src/routes/[id]/download.mt.ts

@@ -3,7 +3,7 @@ import { FileServiceMt } from '../../services/index';
 import { ErrorSchema } from '@d8d/shared-utils';
 import { AppDataSource } from '@d8d/shared-utils';
 import { AuthContext } from '@d8d/shared-types';
-import { authMiddleware } from '@d8d/core-module-mt/auth-module-mt';
+import { authMiddleware } from '../../../../auth-module-mt/src/middleware/index.mt';
 
 // 获取文件下载URL路由
 const downloadFileRoute = createRoute({

+ 1 - 1
packages/core-module-mt/file-module-mt/src/routes/[id]/get-url.mt.ts

@@ -3,7 +3,7 @@ import { FileServiceMt } from '../../services/index';
 import { ErrorSchema } from '@d8d/shared-utils';
 import { AppDataSource } from '@d8d/shared-utils';
 import { AuthContext } from '@d8d/shared-types';
-import { authMiddleware } from '@d8d/core-module-mt/auth-module-mt';
+import { authMiddleware } from '../../../../auth-module-mt/src/middleware/index.mt';
 
 // 获取文件URL路由
 const getFileUrlRoute = createRoute({

+ 1 - 1
packages/core-module-mt/file-module-mt/src/routes/index.mt.ts

@@ -10,7 +10,7 @@ import { AuthContext } from '@d8d/shared-types';
 import { createCrudRoutes } from '@d8d/shared-crud';
 import { FileMt } from '../entities/file.entity';
 import { FileSchema, CreateFileDto, UpdateFileDto } from '../schemas/file.schema.mt';
-import { authMiddleware } from '@d8d/core-module-mt/auth-module-mt';
+import { authMiddleware } from '../../../auth-module-mt/src/middleware/index.mt';
 
 const fileCrudRoutes = createCrudRoutes({
   entity: FileMt,

+ 1 - 1
packages/core-module-mt/file-module-mt/src/routes/multipart-complete/post.mt.ts

@@ -3,7 +3,7 @@ import { FileServiceMt } from '../../services/index';
 import { ErrorSchema } from '@d8d/shared-utils';
 import { AppDataSource } from '@d8d/shared-utils';
 import { AuthContext } from '@d8d/shared-types';
-import { authMiddleware } from '@d8d/core-module-mt/auth-module-mt';
+import { authMiddleware } from '../../../../auth-module-mt/src/middleware/index.mt';
 
 // 完成分片上传请求Schema
 const CompleteMultipartUploadDto = z.object({

+ 1 - 1
packages/core-module-mt/file-module-mt/src/routes/multipart-policy/post.mt.ts

@@ -3,7 +3,7 @@ import { FileServiceMt } from '../../services/index';
 import { ErrorSchema } from '@d8d/shared-utils';
 import { AppDataSource } from '@d8d/shared-utils';
 import { AuthContext } from '@d8d/shared-types';
-import { authMiddleware } from '@d8d/core-module-mt/auth-module-mt';
+import { authMiddleware } from '../../../../auth-module-mt/src/middleware/index.mt';
 
 // 创建分片上传策略请求Schema
 const CreateMultipartUploadPolicyDto = z.object({

+ 1 - 1
packages/core-module-mt/file-module-mt/src/routes/upload-policy/post.mt.ts

@@ -4,7 +4,7 @@ import { FileSchema, CreateFileDto } from '../../schemas/file.schema.mt';
 import { ErrorSchema } from '@d8d/shared-utils';
 import { AppDataSource } from '@d8d/shared-utils';
 import { AuthContext } from '@d8d/shared-types';
-import { authMiddleware } from '@d8d/core-module-mt/auth-module-mt';
+import { authMiddleware } from '../../../../auth-module-mt/src/middleware/index.mt';
 import { parseWithAwait } from '@d8d/shared-utils';