import EditOutlined from "@mui/icons-material/EditOutlined"; import RefreshOutlined from "@mui/icons-material/RefreshOutlined"; import SaveOutlined from "@mui/icons-material/SaveOutlined"; import Drawer from "@mui/material/Drawer"; import TextField from "@mui/material/TextField"; import { useMemo } from "react"; import { useVipConfigPage } from "@/features/vip-config/hooks/useVipConfigPage.js"; import styles from "@/features/vip-config/vip-config.module.css"; import { AdminListBody, AdminListPage } from "@/shared/ui/AdminListLayout.jsx"; import { AdminSwitch } from "@/shared/ui/AdminSwitch.jsx"; import { Button } from "@/shared/ui/Button.jsx"; import { DataState } from "@/shared/ui/DataState.jsx"; import { DataTable } from "@/shared/ui/DataTable.jsx"; import { ResourceGroupSelectField } from "@/shared/ui/ResourceGroupSelectDrawer.jsx"; import { formatMillis } from "@/shared/utils/time.js"; export function VipConfigPage() { const page = useVipConfigPage(); const levels = page.config.levels || []; const resourceLabels = useMemo(() => groupLabelMap(page.resourceGroups), [page.resourceGroups]); const columns = useMemo(() => vipColumns(resourceLabels), [resourceLabels]); return (
{levels.length || 10} {page.activeCount}
{page.abilities.canUpdate ? ( ) : null}
item.level} />
); } function VipConfigDrawer({ page }) { const disabled = !page.abilities.canUpdate || page.saving || page.loading; return (

VIP配置

等级配置
{(page.form.levels || []).map((level) => (
VIP{level.level} page.updateLevel(level.level, { status: event.target.checked ? "active" : "disabled", }) } />
page.updateLevel(level.level, { name: event.target.value }) } /> page.updateLevel(level.level, { priceCoin: event.target.value }) } /> page.updateLevel(level.level, { durationDays: event.target.value }) } /> page.updateLevel(level.level, { rewardResourceGroupId: value }) } /> page.updateLevel(level.level, { sortOrder: event.target.value }) } />
))}
); } function vipColumns(resourceLabels) { return [ { key: "level", label: "等级", render: (item) => , width: "minmax(120px, 0.5fr)", }, { key: "status", label: "状态", render: (item) => ( {item.status === "active" ? "启用" : "停用"} ), width: "minmax(100px, 0.45fr)", }, { key: "price", label: "购买金币", render: (item) => formatNumber(item.priceCoin), width: "minmax(140px, 0.6fr)", }, { key: "gate", label: "购买门槛", render: () => "直接购买", width: "minmax(180px, 0.8fr)", }, { key: "reward", label: "奖励资源组", render: (item) => resourceLabels[String(item.rewardResourceGroupId)] || `资源组 #${item.rewardResourceGroupId || "-"}`, width: "minmax(220px, 1fr)", }, { key: "duration", label: "有效期", render: (item) => `${Math.round(Number(item.durationMs || 0) / 86400000)} 天`, width: "minmax(110px, 0.45fr)", }, { key: "updatedAtMs", label: "更新时间", render: (item) => formatMillis(item.updatedAtMs), width: "minmax(170px, 0.75fr)", }, ]; } function SummaryItem({ children, label }) { return (
{label} {children}
); } function Stack({ primary, secondary }) { return (
{primary || "-"} {secondary || "-"}
); } function groupLabelMap(groups) { return (groups || []).reduce((labels, group) => { labels[String(group.groupId)] = group.name || group.groupCode || `资源组 #${group.groupId}`; return labels; }, {}); } function formatNumber(value) { const number = Number(value || 0); return Number.isFinite(number) ? number.toLocaleString("zh-CN") : "-"; }