91 lines
3.6 KiB
JavaScript
91 lines
3.6 KiB
JavaScript
import AddOutlined from "@mui/icons-material/AddOutlined";
|
|
import { useMemo, useState } from "react";
|
|
import { AdminFilterSelect, AdminListToolbar } from "@/shared/ui/AdminListLayout.jsx";
|
|
import { Button } from "@/shared/ui/Button.jsx";
|
|
import { DataTable } from "@/shared/ui/DataTable.jsx";
|
|
import { TimeText } from "@/shared/ui/TimeText.jsx";
|
|
import { formatNumber, formatPercent } from "../format.js";
|
|
import { OpsStatusBadge } from "./OpsStatusBadge.jsx";
|
|
|
|
export function ConfigsView({ apps, luckyGifts, onCreate, onEdit, saving }) {
|
|
const [appFilter, setAppFilter] = useState("");
|
|
|
|
const appOptions = useMemo(
|
|
() => apps.map((item) => [item.app_code ?? item.appCode, `${item.app_name ?? item.appName ?? ""} (${item.app_code ?? item.appCode})`]),
|
|
[apps]
|
|
);
|
|
// 配置列表已在 dashboard 阶段跨应用拉全,应用筛选只做前端过滤,避免重复扇出请求。
|
|
const items = useMemo(
|
|
() => (appFilter ? luckyGifts.filter((config) => config.app_code === appFilter) : luckyGifts),
|
|
[appFilter, luckyGifts]
|
|
);
|
|
|
|
const columns = useMemo(() => buildColumns({ onEdit, saving }), [onEdit, saving]);
|
|
|
|
return (
|
|
<div className="ops-view">
|
|
<AdminListToolbar
|
|
actions={
|
|
<Button disabled={saving} startIcon={<AddOutlined fontSize="small" />} variant="primary" onClick={onCreate}>
|
|
添加配置
|
|
</Button>
|
|
}
|
|
filters={<AdminFilterSelect label="应用" options={[["", "全部应用"], ...appOptions]} value={appFilter} onChange={setAppFilter} />}
|
|
/>
|
|
<DataTable
|
|
columns={columns}
|
|
emptyLabel="暂无幸运礼物配置"
|
|
items={items}
|
|
minWidth="1080px"
|
|
rowKey={(item) => `${item.app_code}:${item.pool_id}:${item.rule_version}`}
|
|
title="幸运礼物配置"
|
|
total={items.length}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function buildColumns({ onEdit, saving }) {
|
|
return [
|
|
{ key: "app_code", label: "应用", width: "minmax(88px, 0.7fr)" },
|
|
{ key: "pool_id", label: "奖池", width: "minmax(110px, 0.9fr)" },
|
|
{
|
|
key: "rule_version",
|
|
label: "版本",
|
|
render: (item) => (item.is_default ? "-" : `v${item.rule_version}`),
|
|
width: "minmax(72px, 0.5fr)"
|
|
},
|
|
{
|
|
key: "enabled",
|
|
label: "状态",
|
|
render: (item) => {
|
|
// 默认草稿是服务端为未配置奖池生成的占位,不参与线上抽奖,必须与"停用"区分开。
|
|
if (item.is_default) {
|
|
return <OpsStatusBadge label="默认草稿" tone="warning" />;
|
|
}
|
|
return item.enabled ? <OpsStatusBadge label="已启用" tone="succeeded" /> : <OpsStatusBadge label="已停用" />;
|
|
},
|
|
width: "minmax(128px, 0.8fr)"
|
|
},
|
|
{ key: "target_rtp_percent", label: "目标 RTP", render: (item) => formatPercent(item.target_rtp_percent) },
|
|
{ key: "pool_rate_percent", label: "奖池回收", render: (item) => formatPercent(item.pool_rate_percent) },
|
|
{ key: "control_band_percent", label: "控制带宽", render: (item) => formatPercent(item.control_band_percent) },
|
|
{ key: "settlement_window_wager", label: "结算窗口流水", render: (item) => formatNumber(item.settlement_window_wager) },
|
|
{
|
|
key: "created_at_ms",
|
|
label: "发布时间",
|
|
render: (item) => (item.is_default ? "-" : <TimeText value={item.created_at_ms} />),
|
|
width: "minmax(176px, 1.1fr)"
|
|
},
|
|
{
|
|
key: "actions",
|
|
label: "操作",
|
|
render: (item) => (
|
|
<Button disabled={saving} size="small" onClick={() => onEdit(item)}>
|
|
{item.is_default ? "发布配置" : "新增版本"}
|
|
</Button>
|
|
)
|
|
}
|
|
];
|
|
}
|