'use client'; // 点列表里的手机号 → 抽屉列出该用户「同类型」的全部记录(反馈页=全部反馈;低价审核页=全部上报)。 // 顶部汇总该用户的「提交/上报总计」+「奖励总计」;复用各自的 list 接口按 user_id 过滤(无需新后端接口)。 import { useEffect, useState } from 'react'; import { Drawer, Empty, Space, Spin, Statistic, Table, Typography } from 'antd'; import type { ColumnsType } from 'antd/es/table'; import { api } from '@/lib/api'; import type { CursorPage } from '@/lib/types'; const { Text } = Typography; interface Props { open: boolean; onClose: () => void; userId: number | null; phone: string | null; endpoint: string; // 列表接口,按 user_id 过滤,如 /admin/api/feedbacks columns: ColumnsType; recordLabel: string; // 「反馈」/「低价上报」,用于标题与空态文案 countLabel: string; // 顶部计数卡标题,如「提交总计」/「上报总计」 rewardLabel: string; // 顶部奖励卡标题,如「提交奖励总计」/「上报奖励总计」 rewardOf: (item: T) => number; // 单条已发奖励金币(未采纳/未通过返回 0) rewardSuffix?: string; // 第二个汇总卡单位,默认「金币」;领券场景可传「张」(领到券张数)等 } export default function UserRecordsDrawer({ open, onClose, userId, phone, endpoint, columns, recordLabel, countLabel, rewardLabel, rewardOf, rewardSuffix = '金币', }: Props) { const [items, setItems] = useState([]); const [total, setTotal] = useState(0); const [loading, setLoading] = useState(false); useEffect(() => { if (!open || userId == null) return; let alive = true; setLoading(true); api .get>(endpoint, { params: { user_id: userId, limit: 100, sort_by: 'created_at', sort_order: 'desc' }, }) .then((r) => { if (!alive) return; setItems(r.data.items); setTotal(r.data.total ?? r.data.items.length); }) .catch(() => { if (!alive) return; setItems([]); setTotal(0); }) .finally(() => { if (alive) setLoading(false); }); return () => { alive = false; }; }, [open, userId, endpoint]); // 奖励总计在已加载记录上累加(单用户记录数远小于 100 上限,够用) const rewardTotal = items.reduce((sum, it) => sum + rewardOf(it), 0); return ( 用户 #{userId ?? '-'} 的全部{recordLabel} {phone ? ( {phone} ) : null} } width={760} open={open} onClose={onClose} destroyOnHidden > {loading ? ( ) : ( <> {items.length === 0 ? ( ) : ( rowKey="id" size="small" columns={columns} dataSource={items} pagination={false} /> )} )} ); }