PointsExchangeRecordsModal.tsx 10.4 KB
import { postIntegralUserExchangeRecords } from '@/services';
import { formatDateTime } from '@/utils';
import { Button, DatePicker, Empty, Modal, Space, Table, Tabs } from 'antd';
import React, { useEffect, useState } from 'react';
import '../index.less';

interface PointsExchangeRecordsModalProps {
  setVisible: (visible: boolean) => void;
  userInfoObj: {
    uid: string;
    phone?: string;
    nickname?: string;
    realName?: string;
    [key: string]: any;
  };
  onClose: () => void;
}

interface RecordItem {
  createByName: string | null;
  createTime: string;
  delta: number;
  remark: string | null;
  sourceId: string | null;
}

interface RecordsData {
  exchangeRecords: RecordItem[];
  collectedRecords: RecordItem[];
  pendingRecords: RecordItem[];
}

const PointsExchangeRecordsModal: React.FC<PointsExchangeRecordsModalProps> = ({
  setVisible,
  userInfoObj,
  onClose,
}) => {
  const [activeTab, setActiveTab] = useState<string>('1');
  const [loading, setLoading] = useState<boolean>(false);
  const [recordsData, setRecordsData] = useState<RecordsData>({
    exchangeRecords: [],
    collectedRecords: [],
    pendingRecords: [],
  });

  // Add date range state for each tab
  const [exchangeStartTime, setExchangeStartTime] = useState<string | null>(
    null,
  );
  const [exchangeEndTime, setExchangeEndTime] = useState<string | null>(null);
  const [collectedStartTime, setCollectedStartTime] = useState<string | null>(
    null,
  );
  const [collectedEndTime, setCollectedEndTime] = useState<string | null>(null);
  const [pendingStartTime, setPendingStartTime] = useState<string | null>(null);
  const [pendingEndTime, setPendingEndTime] = useState<string | null>(null);

  const uid = userInfoObj?.uid;
  const phone = userInfoObj?.phone;

  // Function to fetch records data from API with date parameters
  const fetchRecordsData = async (
    params: {
      startTime?: string | null;
      endTime?: string | null;
      tabKey?: string;
    } = {},
  ) => {
    try {
      setLoading(true);
      const { startTime, endTime, tabKey } = params;

      // Prepare API request data
      const requestData: any = {
        id: Number(uid),
        phone: phone,
      };

      // Add date range if provided
      if (startTime) requestData.startTime = startTime;
      if (endTime) requestData.endTime = endTime;

      const response = await postIntegralUserExchangeRecords({
        data: requestData,
      });

      if (response && response.data) {
        // Update only the data for the active tab if tabKey is provided
        if (tabKey) {
          setRecordsData((prevData) => {
            const newData = { ...prevData };

            if (tabKey === '1') {
              newData.exchangeRecords = response.data.exchangeRecords || [];
            } else if (tabKey === '2') {
              newData.collectedRecords = response.data.collectedRecords || [];
            } else if (tabKey === '3') {
              newData.pendingRecords = response.data.pendingRecords || [];
            }

            return newData;
          });
        } else {
          // Update all data if no specific tab is targeted
          setRecordsData({
            exchangeRecords: response.data.exchangeRecords || [],
            collectedRecords: response.data.collectedRecords || [],
            pendingRecords: response.data.pendingRecords || [],
          });
        }
      }
    } catch (error) {
      console.error('Failed to fetch exchange records:', error);
    } finally {
      setLoading(false);
    }
  };

  // Fetch records data when component mounts
  useEffect(() => {
    if (uid || phone) {
      fetchRecordsData();
    }
  }, [uid, phone]);

  // Exchange records columns
  const exchangeRecordsColumns = [
    {
      title: '兑换日期',
      dataIndex: 'createTime',
      key: 'createTime',
      width: 160,
      render: (text: string) => formatDateTime(text),
    },
    {
      title: '扣除积分',
      dataIndex: 'delta',
      key: 'delta',
      width: 100,
      render: (delta: number) => (
        <span style={{ color: delta < 0 ? 'green' : 'red' }}>{delta}</span>
      ),
    },
    {
      title: '操作人',
      dataIndex: 'createByName',
      key: 'createByName',
      width: 100,
      render: (text: string | null) => text || '-',
    },
    {
      title: '积分用途',
      dataIndex: 'remark',
      key: 'remark',
      render: (text: string | null) => text || '-',
    },
  ];

  // Collected records columns
  const collectedRecordsColumns = [
    {
      title: '订单号',
      dataIndex: 'sourceId',
      key: 'sourceId',
      render: (text: string | null) => text || '-',
    },
    {
      title: '领取积分',
      dataIndex: 'delta',
      key: 'delta',
      render: (delta: number) => (
        <span style={{ color: delta > 0 ? 'green' : 'red' }}>{delta}</span>
      ),
    },
    {
      title: '领取日期',
      dataIndex: 'createTime',
      key: 'createTime',
      render: (text: string) => formatDateTime(text),
    },
  ];

  // Pending records columns
  const pendingRecordsColumns = [
    {
      title: '订单号',
      dataIndex: 'sourceId',
      key: 'sourceId',
      render: (text: string | null) => text || '-',
    },
    {
      title: '领取积分',
      dataIndex: 'delta',
      key: 'delta',
      render: (delta: number) => (
        <span style={{ color: delta > 0 ? 'green' : 'red' }}>{delta}</span>
      ),
    },
    {
      title: '过期日期',
      dataIndex: 'createTime',
      key: 'createTime',
      render: (text: string) => formatDateTime(text),
    },
  ];

  // Tab items
  const tabItems = [
    {
      key: '1',
      label: '兑换记录',
      children: (
        <>
          <div
            style={{ marginBottom: 16, display: 'flex', alignItems: 'center' }}
          >
            <span>兑换日期:</span>
            <Space>
              <DatePicker
                placeholder="开始日期"
                onChange={(date, dateString) =>
                  setExchangeStartTime(dateString)
                }
                style={{ width: 150 }}
              />
              <DatePicker
                placeholder="结束日期"
                onChange={(date, dateString) => setExchangeEndTime(dateString)}
                style={{ width: 150 }}
              />
              <Button
                type="primary"
                onClick={() =>
                  fetchRecordsData({
                    startTime: exchangeStartTime,
                    endTime: exchangeEndTime,
                    tabKey: '1',
                  })
                }
              >
                查询
              </Button>
            </Space>
          </div>
          <Table
            columns={exchangeRecordsColumns}
            dataSource={recordsData.exchangeRecords.map((item, index) => ({
              ...item,
              key: `exchange-${index}`,
            }))}
            pagination={{ pageSize: 5 }}
            loading={loading && activeTab === '1'}
            locale={{
              emptyText: <Empty description="暂无兑换记录" />,
            }}
          />
        </>
      ),
    },
    {
      key: '2',
      label: '已领取积分',
      children: (
        <>
          <div
            style={{ marginBottom: 16, display: 'flex', alignItems: 'center' }}
          >
            <span>领取日期:</span>
            <Space>
              <DatePicker
                placeholder="开始日期"
                onChange={(date, dateString) =>
                  setCollectedStartTime(dateString)
                }
                style={{ width: 150 }}
              />
              <DatePicker
                placeholder="结束日期"
                onChange={(date, dateString) => setCollectedEndTime(dateString)}
                style={{ width: 150 }}
              />
              <Button
                type="primary"
                onClick={() =>
                  fetchRecordsData({
                    startTime: collectedStartTime,
                    endTime: collectedEndTime,
                    tabKey: '2',
                  })
                }
              >
                查询
              </Button>
            </Space>
          </div>
          <Table
            columns={collectedRecordsColumns}
            dataSource={recordsData.collectedRecords.map((item, index) => ({
              ...item,
              key: `collected-${index}`,
            }))}
            pagination={{ pageSize: 5 }}
            loading={loading && activeTab === '2'}
            locale={{
              emptyText: <Empty description="暂无已领取积分记录" />,
            }}
          />
        </>
      ),
    },
    {
      key: '3',
      label: '待领取积分',
      children: (
        <>
          <div
            style={{ marginBottom: 16, display: 'flex', alignItems: 'center' }}
          >
            <span>过期日期:</span>
            <Space>
              <DatePicker
                placeholder="开始日期"
                onChange={(date, dateString) => setPendingStartTime(dateString)}
                style={{ width: 150 }}
              />
              <DatePicker
                placeholder="结束日期"
                onChange={(date, dateString) => setPendingEndTime(dateString)}
                style={{ width: 150 }}
              />
              <Button
                type="primary"
                onClick={() =>
                  fetchRecordsData({
                    startTime: pendingStartTime,
                    endTime: pendingEndTime,
                    tabKey: '3',
                  })
                }
              >
                查询
              </Button>
            </Space>
          </div>
          <Table
            columns={pendingRecordsColumns}
            dataSource={recordsData.pendingRecords.map((item, index) => ({
              ...item,
              key: `pending-${index}`,
            }))}
            pagination={{ pageSize: 5 }}
            loading={loading && activeTab === '3'}
            locale={{
              emptyText: <Empty description="暂无待领取积分记录" />,
            }}
          />
        </>
      ),
    },
  ];

  return (
    <Modal
      open={true}
      title="积分兑换记录"
      width={1000}
      onCancel={() => {
        setVisible(false);
        onClose();
      }}
      footer={null}
      destroyOnClose
    >
      <Tabs
        activeKey={activeTab}
        onChange={(key) => setActiveTab(key)}
        items={tabItems}
      />
    </Modal>
  );
};

export default PointsExchangeRecordsModal;