import Add from "@mui/icons-material/Add"; import EditOutlined from "@mui/icons-material/EditOutlined"; import Inventory2Outlined from "@mui/icons-material/Inventory2Outlined"; import FormControlLabel from "@mui/material/FormControlLabel"; import MenuItem from "@mui/material/MenuItem"; import Switch from "@mui/material/Switch"; import TextField from "@mui/material/TextField"; import { AdminFormDialog } from "@/shared/ui/AdminFormDialog.jsx"; import { DataState } from "@/shared/ui/DataState.jsx"; import { DataTable } from "@/shared/ui/DataTable.jsx"; import { UploadField } from "@/shared/ui/UploadField.jsx"; import { AdminActionIconButton, AdminFilterResetButton, AdminListBody, AdminListPage, AdminRowActions, AdminListToolbar, } from "@/shared/ui/AdminListLayout.jsx"; import { PaginationBar } from "@/shared/ui/PaginationBar.jsx"; import { createOptionsColumnFilter, createTextColumnFilter } from "@/shared/ui/tableFilters.js"; import { formatMillis } from "@/shared/utils/time.js"; import { grantStrategyLabels, resourceStatusFilters, resourceTypeFilters, resourceTypeLabels, } from "@/features/resources/constants.js"; import { useResourceListPage } from "@/features/resources/hooks/useResourcePages.js"; import styles from "@/features/resources/resources.module.css"; const resourceTypeOptions = resourceTypeFilters.filter(([value]) => value); const baseColumns = [ { key: "resource", label: "资源", width: "minmax(260px, 1.5fr)", render: (resource) => , }, { key: "type", label: "类型", width: "minmax(120px, 0.7fr)", render: (resource) => resourceTypeLabels[resource.resourceType] || resource.resourceType || "-", }, { key: "grant", label: "发放规则", width: "minmax(170px, 1fr)", render: (resource) => , }, { key: "scopes", label: "使用范围", width: "minmax(180px, 1fr)", render: (resource) => , }, { key: "status", label: "状态", width: "minmax(92px, 0.55fr)", }, { key: "time", label: "更新时间", width: "minmax(170px, 0.9fr)", render: (resource) => formatMillis(resource.updatedAtMs || resource.createdAtMs), }, { key: "actions", label: "操作", width: "minmax(76px, 0.4fr)", }, ]; export function ResourceListPage() { const page = useResourceListPage(); const items = page.data.items || []; const total = page.data.total || 0; const createDisabled = !page.abilities.canCreate || !page.abilities.canUpload; const columns = baseColumns.map((column) => column.key === "resource" ? { ...column, filter: createTextColumnFilter({ placeholder: "搜索资源名称、资源编码", value: page.query, onChange: page.changeQuery, }), } : column.key === "type" ? { ...column, filter: createOptionsColumnFilter({ options: resourceTypeFilters, placeholder: "搜索类型", value: page.resourceType, onChange: page.changeResourceType, }), } : column.key === "status" ? { ...column, filter: createOptionsColumnFilter({ options: resourceStatusFilters, placeholder: "搜索状态", value: page.status, onChange: page.changeStatus, }), render: (resource) => , } : column.key === "actions" ? { ...column, render: (resource) => , } : column, ); return ( } actions={ page.abilities.canCreate ? ( ) : null } /> resource.resourceId} /> {total > 0 ? ( ) : null} ); } function ResourceRowActions({ page, resource }) { return ( page.openEditResource(resource)} > ); } function ResourceFormDialog({ disabled, form, loading, mode, onClose, onSubmit, open, setForm, uploadDisabled }) { const submitDisabled = disabled || loading; return ( setForm({ ...form, name: event.target.value })} /> setForm({ ...form, resourceCode: event.target.value })} /> setForm({ ...form, resourceType: event.target.value, walletAssetAmount: "" })} > {resourceTypeOptions.map(([value, label]) => ( {label} ))} {form.resourceType === "coin" ? ( setForm({ ...form, walletAssetAmount: event.target.value })} /> ) : null} setForm({ ...form, previewUrl })} /> setForm({ ...form, assetUrl })} /> setForm({ ...form, enabled: event.target.checked })} /> } label={form.enabled ? "启用" : "禁用"} /> ); } function ResourceIdentity({ resource }) { const preview = imageURL(resource.previewUrl || resource.assetUrl); return (
{preview ? : }
{resource.name || "-"} {resource.resourceCode || resource.resourceId}
); } function GrantInfo({ resource }) { const strategy = grantStrategyLabels[resource.grantStrategy] || resource.grantStrategy || "-"; if (resource.walletAssetType || resource.walletAssetAmount) { return (
{strategy} {resource.walletAssetType || "-"} {formatNumber(resource.walletAssetAmount)}
); } return strategy; } function ResourceStatusSwitch({ page, resource }) { const checked = resource.status === "active"; return ( page.toggleResource(resource, event.target.checked)} /> ); } function TagList({ values = [] }) { const items = values.filter(Boolean); if (!items.length) { return "-"; } return (
{items.map((value) => ( {value} ))}
); } function imageURL(value) { const url = String(value || "").trim(); if (!url) { return ""; } return /\.(avif|gif|jpe?g|png|webp)(\?|#|$)/i.test(url) ? url : ""; } function formatNumber(value) { return Number(value || 0).toLocaleString("zh-CN"); }