|
|
@@ -1019,6 +1019,83 @@ CREATE INDEX idx_goods_mt_tenant_id ON goods_mt(tenant_id);
|
|
|
8. **UI组件测试**: 使用data-testid进行元素定位,比placeholder/role更准确稳定
|
|
|
9. **FormField mock**: 正确处理render函数,确保子组件正确渲染
|
|
|
|
|
|
+10. **RPC客户端架构设计**
|
|
|
+ - **问题**: 独立包中需要统一的RPC客户端管理机制
|
|
|
+ - **解决方案**: 实现单例模式的RPC客户端管理器,支持延迟初始化和重置功能
|
|
|
+ - **关键设计**:
|
|
|
+ - 使用单例模式确保全局唯一的客户端实例
|
|
|
+ - 支持延迟初始化,避免循环依赖
|
|
|
+ - 提供reset方法用于测试和重新初始化
|
|
|
+ - 使用Hono的InferRequestType和InferResponseType进行类型安全
|
|
|
+ - **效果**: 提供稳定的RPC客户端架构,支持独立包和主应用的统一调用
|
|
|
+
|
|
|
+### RPC客户端最佳实践
|
|
|
+
|
|
|
+1. **客户端管理器设计**
|
|
|
+```typescript
|
|
|
+// 单例模式确保全局唯一实例
|
|
|
+class UserClientManager {
|
|
|
+ private static instance: UserClientManager;
|
|
|
+ private client: ReturnType<typeof rpcClient<typeof userRoutes>> | null = null;
|
|
|
+
|
|
|
+ // 初始化客户端
|
|
|
+ public init(baseUrl: string = '/'): ReturnType<typeof rpcClient<typeof userRoutes>> {
|
|
|
+ return this.client = rpcClient<typeof userRoutes>(baseUrl);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取客户端实例(延迟初始化)
|
|
|
+ public get(): ReturnType<typeof rpcClient<typeof userRoutes>> {
|
|
|
+ if (!this.client) {
|
|
|
+ return this.init()
|
|
|
+ }
|
|
|
+ return this.client;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 重置客户端(用于测试或重新初始化)
|
|
|
+ public reset(): void {
|
|
|
+ this.client = null;
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+2. **类型安全调用**
|
|
|
+```typescript
|
|
|
+// 使用Hono类型推断确保类型安全
|
|
|
+type CreateUserRequest = InferRequestType<typeof userClient.index.$post>['json'];
|
|
|
+type UpdateUserRequest = InferRequestType<typeof userClient[':id']['$put']>['json'];
|
|
|
+type UserResponse = InferResponseType<typeof userClient.index.$get, 200>['data'][0];
|
|
|
+
|
|
|
+// 直接使用后端定义的schema
|
|
|
+const createUserFormSchema = CreateUserDto;
|
|
|
+const updateUserFormSchema = UpdateUserDto;
|
|
|
+```
|
|
|
+
|
|
|
+3. **API调用模式**
|
|
|
+```typescript
|
|
|
+// 使用客户端管理器进行API调用
|
|
|
+const res = await userClientManager.get().index.$get({
|
|
|
+ query: {
|
|
|
+ page: searchParams.page,
|
|
|
+ pageSize: searchParams.limit,
|
|
|
+ keyword: searchParams.keyword,
|
|
|
+ filters: Object.keys(filterParams).length > 0 ? JSON.stringify(filterParams) : undefined
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+// 创建用户
|
|
|
+const res = await userClientManager.get().index.$post({
|
|
|
+ json: data
|
|
|
+});
|
|
|
+```
|
|
|
+
|
|
|
+4. **主应用集成**
|
|
|
+```typescript
|
|
|
+// 在主应用中初始化客户端
|
|
|
+import { userClientManager } from '@d8d/user-management-ui/api';
|
|
|
+
|
|
|
+userClientManager.init('/api/v1/users');
|
|
|
+```
|
|
|
+
|
|
|
## 总结
|
|
|
|
|
|
多租户复制包方案为用户提供了明确的实施路径:
|
|
|
@@ -1040,4 +1117,4 @@ via [Happy](https://happy.engineering)
|
|
|
**Co-Authored-By: Claude <noreply@anthropic.com>**
|
|
|
**Co-Authored-By: Happy <yesreply@happy.engineering>**
|
|
|
|
|
|
-**最后更新**: 2025-11-15 (添加管理界面独立包故事)
|
|
|
+**最后更新**: 2025-11-16 (添加RPC客户端架构设计和最佳实践)
|