Sfoglia il codice sorgente

feat(credit-balance-management-ui-mt): 添加错误处理和优化测试用例

- 在CreditBalanceDialog中添加API错误处理逻辑
- 优化集成测试用例,分离不同API错误测试
- 清理UserManagement中未使用的导入

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

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
yourname 1 mese fa
parent
commit
1f30cb1737

+ 17 - 3
packages/credit-balance-management-ui-mt/src/components/CreditBalanceDialog.tsx

@@ -1,4 +1,4 @@
-import React, { useState, useMemo } from 'react';
+import React, { useState, useMemo, useEffect } from 'react';
 import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
 import { format } from 'date-fns';
 import {
@@ -109,7 +109,7 @@ export const CreditBalanceDialog: React.FC<CreditBalanceDialogProps> = ({
   });
 
   // 额度查询
-  const { data: balanceData, isLoading: isLoadingBalance, refetch: refetchBalance } = useQuery({
+  const { data: balanceData, isLoading: isLoadingBalance, refetch: refetchBalance, error: balanceError } = useQuery({
     queryKey: ['credit-balance', userId, tenantId],
     queryFn: async () => {
       console.debug('CreditBalanceDialog: 开始获取信用额度数据', { userId, tenantId });
@@ -127,8 +127,15 @@ export const CreditBalanceDialog: React.FC<CreditBalanceDialogProps> = ({
     gcTime: 10 * 60 * 1000,
   });
 
+  // 处理额度查询错误
+  useEffect(() => {
+    if (balanceError) {
+      toast.error(`获取信用额度失败: ${balanceError.message}`);
+    }
+  }, [balanceError]);
+
   // 额度变更记录查询
-  const { data: logsData, isLoading: isLoadingLogs } = useQuery({
+  const { data: logsData, isLoading: isLoadingLogs, error: logsError } = useQuery({
     queryKey: ['credit-balance-logs', userId, logsQueryParams, tenantId],
     queryFn: async () => {
       const res = await creditBalanceClient[':userId'].logs.$get({
@@ -146,6 +153,13 @@ export const CreditBalanceDialog: React.FC<CreditBalanceDialogProps> = ({
     gcTime: 10 * 60 * 1000,
   });
 
+  // 处理额度变更记录查询错误
+  useEffect(() => {
+    if (logsError) {
+      toast.error(`获取额度变更记录失败: ${logsError.message}`);
+    }
+  }, [logsError]);
+
   // 设置额度表单
   const setLimitForm = useForm<SetLimitFormData>({
     resolver: zodResolver(setLimitFormSchema),

+ 23 - 9
packages/credit-balance-management-ui-mt/tests/integration/creditBalanceDialog.integration.test.tsx

@@ -522,7 +522,7 @@ describe('信用额度管理对话框集成测试', () => {
     });
   });
 
-  it('应该处理API错误', async () => {
+  it('应该处理获取信用额度API错误', async () => {
     const { toast } = await import('sonner');
 
     // Mock API error
@@ -541,10 +541,13 @@ describe('信用额度管理对话框集成测试', () => {
 
     // 应该显示错误提示
     await waitFor(() => {
-      expect(toast.error).toHaveBeenCalledWith('获取信用额度失败');
-    });
+      expect(toast.error).toHaveBeenCalledWith('获取信用额度失败: 获取信用额度失败');
+    }, { timeout: 3000 });
+  });
+
+  it('应该处理设置额度API错误', async () => {
+    const { toast } = await import('sonner');
 
-    // 测试设置额度API错误
     const mockBalanceData = {
       id: 1,
       userId: 123,
@@ -556,14 +559,25 @@ describe('信用额度管理对话框集成测试', () => {
       updatedAt: '2024-01-01T00:00:00Z'
     };
 
+    // Mock 成功获取额度数据
     (creditBalanceClient[':userId'].$get as any).mockResolvedValue(
       createMockResponse(200, mockBalanceData)
     );
 
+    // Mock 设置额度API错误
     (creditBalanceClient[':userId'].$put as any).mockRejectedValue(
       new Error('设置额度失败')
     );
 
+    renderWithProviders(
+      <CreditBalanceDialog
+        userId={123}
+        userName="测试用户"
+        open={true}
+        onOpenChange={() => {}}
+      />
+    );
+
     // 等待初始数据加载
     await waitFor(() => {
       expect(screen.getByTestId('total-limit-card')).toBeInTheDocument();
@@ -588,7 +602,7 @@ describe('信用额度管理对话框集成测试', () => {
     fireEvent.click(setLimitButton);
 
     await waitFor(() => {
-      expect(toast.error).toHaveBeenCalledWith('设置额度失败');
+      expect(toast.error).toHaveBeenCalledWith('设置失败: 设置额度失败');
     });
   });
 
@@ -668,8 +682,8 @@ describe('信用额度管理对话框集成测试', () => {
       id: 1,
       userId: 123,
       totalLimit: 10000,
-      usedAmount: 9500, // 使用率95%,应该显示警告
-      availableAmount: 500,
+      usedAmount: 12000, // 使用量超出额度,应该显示欠款警告
+      availableAmount: -2000, // 负值表示欠款
       isEnabled: 1,
       createdAt: '2024-01-01T00:00:00Z',
       updatedAt: '2024-01-01T00:00:00Z'
@@ -694,7 +708,7 @@ describe('信用额度管理对话框集成测试', () => {
     });
 
     // 应该显示欠款警告
-    expect(screen.getByText('高使用率警告')).toBeInTheDocument();
-    expect(screen.getByText('当前信用额度使用率已达到95%,请及时关注用户还款情况。')).toBeInTheDocument();
+    expect(screen.getByText('用户存在欠款')).toBeInTheDocument();
+    expect(screen.getByText(/用户已超出信用额度 ¥2000\.00/)).toBeInTheDocument();
   });
 });

+ 5 - 6
packages/user-management-ui-mt/src/components/UserManagement.tsx

@@ -4,7 +4,6 @@ import { format } from 'date-fns';
 import { Plus, Search, Edit, Trash2, Filter, X } from 'lucide-react';
 import { userClient, userClientManager } from '../api/userClient';
 import type { InferRequestType, InferResponseType } from 'hono/client';
-import { z } from 'zod';
 import { Button } from '@d8d/shared-ui-components/components/ui/button';
 import { Input } from '@d8d/shared-ui-components/components/ui/input';
 import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@d8d/shared-ui-components/components/ui/card';
@@ -17,7 +16,7 @@ import { zodResolver } from '@hookform/resolvers/zod';
 import { toast } from 'sonner';
 import { Skeleton } from '@d8d/shared-ui-components/components/ui/skeleton';
 import { Switch } from '@d8d/shared-ui-components/components/ui/switch';
-import { CreateUserDtoMt, UpdateUserDtoMt, RoleSchemaMt } from '@d8d/user-module-mt/schemas';
+import { CreateUserDtoMt, UpdateUserDtoMt } from '@d8d/user-module-mt/schemas';
 import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@d8d/shared-ui-components/components/ui/select';
 import { Popover, PopoverContent, PopoverTrigger } from '@d8d/shared-ui-components/components/ui/popover';
 import { Calendar } from '@d8d/shared-ui-components/components/ui/calendar';
@@ -38,10 +37,10 @@ const updateUserFormSchema = UpdateUserDtoMt;
 type CreateUserFormData = CreateUserRequest;
 type UpdateUserFormData = UpdateUserRequest;
 // 适配后端返回的字符串日期格式
-type Role = Omit<z.infer<typeof RoleSchemaMt>, 'createdAt' | 'updatedAt'> & {
-  createdAt: string;
-  updatedAt: string;
-};
+// type Role = Omit<z.infer<typeof RoleSchemaMt>, 'createdAt' | 'updatedAt'> & {
+//   createdAt: string;
+//   updatedAt: string;
+// };
 
 
 export const UserManagement = () => {