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

♻️ refactor(expenses): 优化费用管理页面代码结构

- 替换日志库,从自定义logger迁移到debug库
- 优化API请求处理,增加响应状态检查和JSON解析
- 修正ID类型,将string统一改为number类型
- 优化表单 onChange 处理逻辑,使用 getValueFromEvent 替代
- 移除金额输入框的precision属性,允许更灵活的金额输入
- 调整刷新按钮点击事件处理方式,使用箭头函数包裹refetch调用
- 优化费用记录编辑时foreignAmount的处理逻辑
yourname 8 месяцев назад
Родитель
Сommit
2461007ba7
1 измененных файлов с 23 добавлено и 19 удалено
  1. 23 19
      src/client/admin/pages/Expenses.tsx

+ 23 - 19
src/client/admin/pages/Expenses.tsx

@@ -10,9 +10,10 @@ import { formatCurrency, formatDate } from '@/client/utils/utils';
 import { logger } from '@/client/utils/logger';
 
 // 定义日志记录器
-const apiLogger = logger('frontend:api:expenses');
-const errorLogger = logger('frontend:error:expenses');
-const uiLogger = logger('frontend:ui:expenses');
+import debug from 'debug';
+const apiLogger = debug('frontend:api:expenses');
+const errorLogger = debug('frontend:error:expenses');
+const uiLogger = debug('frontend:ui:expenses');
 
 // 定义类型
 type ExpenseItem = InferResponseType<typeof expenseClient.$get, 200>['data'][0];
@@ -48,9 +49,11 @@ const Expenses: React.FC = () => {
     queryKey: ['clients'],
     queryFn: async () => {
       apiLogger('Fetching clients list');
-      const response = await clientClient.$get({ query: { page: 1, pageSize: 1000 } }) as Promise<InferResponseType<typeof clientClient.$get, 200>>;
-      apiLogger(`Fetched ${response.data.length} clients`);
-      return response;
+      const response = await clientClient.$get({ query: { page: 1, pageSize: 1000 } });
+      if (!response.ok) throw new Error('Failed to fetch clients');
+      const data = await response.json();
+      apiLogger(`Fetched ${data.data.length} clients`);
+      return data;
     },
     onSuccess: (result) => {
       setClients(result.data);
@@ -74,9 +77,11 @@ const Expenses: React.FC = () => {
     if (filters.dateRange?.[0]) queryParams.startDate = filters.dateRange[0].format('YYYY-MM-DD');
     if (filters.dateRange?.[1]) queryParams.endDate = filters.dateRange[1].format('YYYY-MM-DD');
     
-    const response = await expenseClient.$get({ query: queryParams }) as Promise<ExpenseListResponse>;
-    apiLogger(`Fetched ${response.data.length} expenses, total: ${response.pagination.total}`);
-    return response;
+    const response = await expenseClient.$get({ query: queryParams });
+    if (!response.ok) throw new Error('Failed to fetch expenses');
+    const data = await response.json();
+    apiLogger(`Fetched ${data.data.length} expenses, total: ${data.pagination.total}`);
+    return data;
   };
 
   const { data, isLoading: isExpensesLoading, refetch } = useQuery({
@@ -111,7 +116,7 @@ const Expenses: React.FC = () => {
 
   // 更新费用记录
   const updateExpense = useMutation({
-    mutationFn: ({ id, data }: { id: string; data: UpdateExpenseRequest }) => expenseClient[':id'].$put({ param: { id }, json: data }),
+    mutationFn: ({ id, data }: { id: number; data: UpdateExpenseRequest }) => expenseClient[':id'].$put({ param: { id }, json: data }),
     onSuccess: () => {
       apiLogger('Expense updated successfully');
       antdMessage.success('费用记录更新成功');
@@ -125,7 +130,7 @@ const Expenses: React.FC = () => {
 
   // 删除费用记录
   const deleteExpense = useMutation({
-    mutationFn: (id: string) => expenseClient[':id'].$delete({ param: { id } }),
+    mutationFn: (id: number) => expenseClient[':id'].$delete({ param: { id } }),
     onSuccess: () => {
       apiLogger('Expense deleted successfully');
       antdMessage.success('费用记录删除成功');
@@ -188,7 +193,7 @@ const Expenses: React.FC = () => {
         invoiceNumber: record.invoiceNumber,
         currency: record.currency || 'CNY',
         exchangeRate: record.exchangeRate || 1,
-        foreignAmount: record.foreignAmount ? parseFloat(record.foreignAmount) : undefined,
+        foreignAmount: record.foreignAmount,
       });
     } else {
       setEditingKey(null);
@@ -370,7 +375,7 @@ const Expenses: React.FC = () => {
             type="link" 
             danger 
             icon={<DeleteOutlined />} 
-            onClick={() => handleDelete(record.id.toString())}
+            onClick={() => handleDelete(record.id)}
           >
             删除
           </Button>
@@ -424,7 +429,7 @@ const Expenses: React.FC = () => {
           </Button>
           <Button 
             icon={<ReloadOutlined />} 
-            onClick={refetch}
+            onClick={() => refetch()}
             loading={isExpensesLoading}
           >
             刷新
@@ -466,7 +471,7 @@ const Expenses: React.FC = () => {
               label="客户"
               name="clientId"
               initialValue={filters.clientId}
-              onChange={([value]) => setFilters(prev => ({ ...prev, clientId: value }))}
+              getValueFromEvent={(value) => { setFilters(prev => ({ ...prev, clientId: value })); return value; }}
             >
               <Select placeholder="请选择客户" style={{ width: '100%' }}>
                 {clients.map(client => (
@@ -481,7 +486,7 @@ const Expenses: React.FC = () => {
               label="费用类型"
               name="type"
               initialValue={filters.type}
-              onChange={([value]) => setFilters(prev => ({ ...prev, type: value }))}
+              getValueFromEvent={(value) => { setFilters(prev => ({ ...prev, type: value })); return value; }}
             >
               <Select placeholder="请选择费用类型" style={{ width: '100%' }}>
                 {expenseTypeOptions.map(option => (
@@ -496,7 +501,7 @@ const Expenses: React.FC = () => {
               label="费用状态"
               name="status"
               initialValue={filters.status}
-              onChange={([value]) => setFilters(prev => ({ ...prev, status: value }))}
+              getValueFromEvent={(value) => { setFilters(prev => ({ ...prev, status: value })); return value; }}
             >
               <Select placeholder="请选择费用状态" style={{ width: '100%' }}>
                 {expenseStatusOptions.map(option => (
@@ -511,7 +516,7 @@ const Expenses: React.FC = () => {
               label="日期范围"
               name="dateRange"
               initialValue={filters.dateRange}
-              onChange={([value]) => setFilters(prev => ({ ...prev, dateRange: value }))}
+              getValueFromEvent={(value) => { setFilters(prev => ({ ...prev, dateRange: value })); return value; }}
               className="md:col-span-3"
             >
               <DatePicker.RangePicker 
@@ -626,7 +631,6 @@ const Expenses: React.FC = () => {
               <Input 
                 type="number" 
                 placeholder="请输入费用金额" 
-                precision={2}
                 style={{ width: '100%' }}
               />
             </Form.Item>