104 lines
3.9 KiB
JavaScript
104 lines
3.9 KiB
JavaScript
import CloseOutlined from "@mui/icons-material/CloseOutlined";
|
|
import Drawer from "@mui/material/Drawer";
|
|
import IconButton from "@mui/material/IconButton";
|
|
import { DataState } from "@/shared/ui/DataState.jsx";
|
|
import { DataTable } from "@/shared/ui/DataTable.jsx";
|
|
import { formatMillis } from "@/shared/utils/time.js";
|
|
import styles from "@/features/red-packets/red-packets.module.css";
|
|
|
|
const claimColumns = [
|
|
{
|
|
key: "userId",
|
|
label: "用户",
|
|
width: "minmax(120px, 0.7fr)",
|
|
render: (claim) => claim.userId || "-",
|
|
},
|
|
{
|
|
key: "amount",
|
|
label: "金额",
|
|
width: "minmax(120px, 0.7fr)",
|
|
render: (claim) => `${formatNumber(claim.amount)} 金币`,
|
|
},
|
|
{
|
|
key: "status",
|
|
label: "状态",
|
|
width: "minmax(100px, 0.55fr)",
|
|
render: (claim) => claimStatusLabel(claim.status),
|
|
},
|
|
{
|
|
key: "createdAt",
|
|
label: "领取时间",
|
|
width: "minmax(180px, 0.9fr)",
|
|
render: (claim) => formatMillis(claim.createdAtMs),
|
|
},
|
|
];
|
|
|
|
export function RedPacketDetailDrawer({ loading, onClose, open, packet }) {
|
|
return (
|
|
<Drawer anchor="right" open={open} onClose={onClose}>
|
|
<div className="form-drawer">
|
|
<div className="form-drawer__section-title">
|
|
<h2>红包详情</h2>
|
|
<IconButton aria-label="关闭" size="small" onClick={onClose}>
|
|
<CloseOutlined fontSize="small" />
|
|
</IconButton>
|
|
</div>
|
|
<DataState loading={loading} reportPageLoading={false}>
|
|
{packet ? (
|
|
<div className={styles.detailPanel}>
|
|
<InfoRow label="红包 ID" value={packet.packetId} />
|
|
<InfoRow label="房间" value={packet.roomId || "-"} />
|
|
<InfoRow label="发送人" value={packet.senderUserId || "-"} />
|
|
<InfoRow label="类型" value={packetTypeLabel(packet.packetType)} />
|
|
<InfoRow label="状态" value={packetStatusLabel(packet.status)} />
|
|
<InfoRow label="金额" value={`${formatNumber(packet.totalAmount)} 金币`} />
|
|
<InfoRow label="剩余" value={`${formatNumber(packet.remainingAmount)} / ${packet.remainingCount} 个`} />
|
|
<InfoRow label="开启时间" value={formatMillis(packet.openAtMs)} />
|
|
<InfoRow label="过期时间" value={formatMillis(packet.expiresAtMs)} />
|
|
<DataTable
|
|
columns={claimColumns}
|
|
emptyLabel="暂无领取记录"
|
|
fixedEdges={false}
|
|
items={packet.claims || []}
|
|
minWidth="620px"
|
|
rowKey={(claim) => claim.claimId}
|
|
/>
|
|
</div>
|
|
) : null}
|
|
</DataState>
|
|
</div>
|
|
</Drawer>
|
|
);
|
|
}
|
|
|
|
function InfoRow({ label, value }) {
|
|
return (
|
|
<div className={styles.summaryItem}>
|
|
<span className={styles.summaryLabel}>{label}</span>
|
|
<span className={styles.summaryValue}>{value}</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function packetTypeLabel(type) {
|
|
return type === "delayed" ? "延迟红包" : "普通红包";
|
|
}
|
|
|
|
function packetStatusLabel(status) {
|
|
const labels = {
|
|
active: "进行中",
|
|
finished: "已抢完",
|
|
refunded: "已退款",
|
|
waiting_open: "待开启",
|
|
};
|
|
return labels[status] || status || "-";
|
|
}
|
|
|
|
function claimStatusLabel(status) {
|
|
return status === "claimed" ? "已领取" : status || "-";
|
|
}
|
|
|
|
function formatNumber(value) {
|
|
return new Intl.NumberFormat("zh-CN").format(Number(value || 0));
|
|
}
|