Răsfoiți Sursa

Enhance UserListPage with wallet balance filter and sorting functionality

- Added a checkbox filter to display users with wallet balance, improving user query capabilities.
- Updated the user list query interface to include a new property for filtering by wallet balance.
- Enhanced the table sorting functionality to support sorting by wallet balance, providing better data organization.
- Refactored the pagination change handler to accommodate sorting logic for improved user experience.
0es 2 săptămâni în urmă
părinte
comite
c95dc96b14

+ 8 - 10
src/app/(dashboard)/order/list/page.tsx

@@ -483,16 +483,6 @@ const OrderListPage: React.FC = () => {
               <Select.Option value={8}>用户取消</Select.Option>
             </Select>
           </Form.Item>
-          <Form.Item>
-            <Button
-              type="link"
-              className="p-0"
-              onClick={() => setFilterExpanded((v) => !v)}
-              icon={filterExpanded ? <UpOutlined /> : <DownOutlined />}
-            >
-              {filterExpanded ? "收起筛选项" : "展开筛选项"}
-            </Button>
-          </Form.Item>
           {filterExpanded && (
             <>
               <Form.Item label="退款申请中" name="refundApply">
@@ -543,6 +533,14 @@ const OrderListPage: React.FC = () => {
           </Form.Item>
           <Form.Item style={{ marginLeft: "auto" }}>
             <Space>
+              <Button
+                type="link"
+                className="p-0"
+                onClick={() => setFilterExpanded((v) => !v)}
+                icon={filterExpanded ? <UpOutlined /> : <DownOutlined />}
+              >
+                {filterExpanded ? "收起筛选项" : "展开筛选项"}
+              </Button>
               <Button
                 type="primary"
                 icon={<SearchOutlined />}

+ 48 - 5
src/app/(dashboard)/user/list/page.tsx

@@ -1,8 +1,8 @@
 "use client";
 
 import {
-  DownOutlined,
   DownloadOutlined,
+  DownOutlined,
   EditOutlined,
   EyeOutlined,
   LockOutlined,
@@ -17,6 +17,7 @@ import {
   App,
   Button,
   Card,
+  Checkbox,
   Col,
   DatePicker,
   Descriptions,
@@ -34,6 +35,7 @@ import {
   Tag,
 } from "antd";
 import type { ColumnsType, TablePaginationConfig } from "antd/es/table";
+import type { SorterResult } from "antd/es/table/interface";
 import type React from "react";
 import { useEffect, useState } from "react";
 import AudioUpload from "@/components/AudioUpload";
@@ -125,6 +127,7 @@ const UserListPage: React.FC = () => {
       email: values.email?.trim?.() || undefined,
       nickname: values.nickname?.trim?.() || undefined,
       playmate: values.playmate ?? undefined,
+      walletHasBalance: values.walletHasBalance === true ? true : undefined,
       regChannel: values.regChannel?.trim?.() || undefined,
       startDay: startDay || undefined,
       endDay: endDay || undefined,
@@ -137,6 +140,7 @@ const UserListPage: React.FC = () => {
     setQueryParams({
       pageSize: 20,
       pageIndex: 1,
+      sort: undefined,
     });
   };
 
@@ -185,13 +189,29 @@ const UserListPage: React.FC = () => {
     }
   };
 
-  // Pagination change handler
-  const handleTableChange = (pagination: TablePaginationConfig) => {
-    setQueryParams({
+  // Pagination and sort change handler
+  const handleTableChange = (
+    pagination: TablePaginationConfig,
+    _filters: unknown,
+    sorter:
+      | SorterResult<UserInfoAdminDTO>
+      | SorterResult<UserInfoAdminDTO>[],
+  ) => {
+    const newQueryParams: UserInfoAdminQuery = {
       ...queryParams,
       pageIndex: pagination.current || 1,
       pageSize: pagination.pageSize || 20,
-    });
+    };
+    const singleSorter = Array.isArray(sorter) ? sorter[0] : sorter;
+    if (singleSorter?.field && singleSorter?.order) {
+      newQueryParams.sort = {
+        field: singleSorter.field as string,
+        order: singleSorter.order === "ascend" ? 1 : -1,
+      };
+    } else {
+      newQueryParams.sort = undefined;
+    }
+    setQueryParams(newQueryParams);
   };
 
   // Format gender
@@ -498,6 +518,26 @@ const UserListPage: React.FC = () => {
       width: 180,
       render: formatDate,
     },
+    ...(queryParams.walletHasBalance
+      ? [
+          {
+            title: "钱包余额(金币)",
+            dataIndex: "walletGoldCoinAmount",
+            key: "walletGoldCoinAmount",
+            width: 140,
+            fixed: "right" as const,
+            sorter: true,
+            sortOrder:
+              queryParams.sort?.field === "walletGoldCoinAmount"
+                ? (queryParams.sort?.order === 1
+                    ? "ascend"
+                    : "descend") as "ascend" | "descend"
+                : undefined,
+            render: (val: number | undefined) =>
+              val != null ? String(val) : "-",
+          },
+        ]
+      : []),
     {
       title: "操作",
       key: "action",
@@ -581,6 +621,9 @@ const UserListPage: React.FC = () => {
               ]}
             />
           </Form.Item>
+          <Form.Item label="有余额用户" name="walletHasBalance" valuePropName="checked">
+            <Checkbox>仅显示有余额</Checkbox>
+          </Form.Item>
           <Form.Item label="创建时间" name="createdAtRange">
             <DatePicker.RangePicker
               allowClear

+ 6 - 0
src/types/api/user.ts

@@ -47,6 +47,8 @@ export interface UserInfoAdminDTO {
   photos: string[];
   cover: string;
   voiceBar: string;
+  /** Wallet gold coin amount (when walletHasBalance filter is used) */
+  walletGoldCoinAmount?: number;
 }
 
 // User list query request
@@ -70,6 +72,10 @@ export interface UserInfoAdminQuery {
    * Registration channel
    */
   regChannel?: string;
+  /**
+   * Filter by users with wallet balance (true = has balance only)
+   */
+  walletHasBalance?: boolean;
 }
 
 // User list page response