98 lines
4.2 KiB
JavaScript
98 lines
4.2 KiB
JavaScript
import EditOutlined from "@mui/icons-material/EditOutlined";
|
|
import RefreshOutlined from "@mui/icons-material/RefreshOutlined";
|
|
import { AdminActionIconButton } from "@/shared/ui/AdminListLayout.jsx";
|
|
import { Button } from "@/shared/ui/Button.jsx";
|
|
import { formatMillis } from "@/shared/utils/time.js";
|
|
import {
|
|
atmosphereLevelOptions,
|
|
controlStrengthOptions,
|
|
jackpotStrategyOptions,
|
|
luckyGiftConfigScopeLabel,
|
|
noviceStrengthOptions,
|
|
optionLabel,
|
|
payoutStyleOptions,
|
|
poolModeOptions,
|
|
} from "@/features/lucky-gift/constants.js";
|
|
import { formFromConfig } from "@/features/lucky-gift/configModel.js";
|
|
import styles from "@/features/lucky-gift/lucky-gift.module.css";
|
|
|
|
export function LuckyGiftConfigSummary({ canUpdate, config, configLoading, onEdit, onRefresh }) {
|
|
const form = formFromConfig(config);
|
|
|
|
return (
|
|
<section className={styles.summaryPanel}>
|
|
<div className={styles.summaryScrollArea}>
|
|
<div className={styles.summaryContent}>
|
|
<div className={styles.summaryHeader}>
|
|
<span className={styles.title}>幸运礼物配置</span>
|
|
<span className={styles.meta}>{luckyGiftConfigScopeLabel}</span>
|
|
</div>
|
|
<div className={styles.summaryItems}>
|
|
<ConfigStatus config={config} loading={configLoading} />
|
|
<SummaryItem label="RTP">{formatPercent(config?.targetRTPPPM)}</SummaryItem>
|
|
<SummaryItem label="控制强度">
|
|
{optionLabel(controlStrengthOptions, form.controlStrength)}
|
|
</SummaryItem>
|
|
<SummaryItem label="奖池模式">{optionLabel(poolModeOptions, form.poolMode)}</SummaryItem>
|
|
<SummaryItem label="新手保护">
|
|
{optionLabel(noviceStrengthOptions, form.noviceStrength)}
|
|
</SummaryItem>
|
|
<SummaryItem label="中奖体感">{optionLabel(payoutStyleOptions, form.payoutStyle)}</SummaryItem>
|
|
<SummaryItem label="大奖策略">
|
|
{optionLabel(jackpotStrategyOptions, form.jackpotStrategy)}
|
|
</SummaryItem>
|
|
<SummaryItem label="房间爆点">
|
|
{optionLabel(atmosphereLevelOptions, form.atmosphereLevel)}
|
|
</SummaryItem>
|
|
<SummaryItem label="更新时间">
|
|
{config?.updatedAtMs ? formatMillis(config.updatedAtMs) : configLoading ? "加载中" : "-"}
|
|
</SummaryItem>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className={styles.summaryActions}>
|
|
<AdminActionIconButton disabled={configLoading} label="刷新配置" type="button" onClick={onRefresh}>
|
|
<RefreshOutlined fontSize="small" />
|
|
</AdminActionIconButton>
|
|
<Button
|
|
disabled={!canUpdate || configLoading}
|
|
startIcon={<EditOutlined fontSize="small" />}
|
|
type="button"
|
|
variant="primary"
|
|
onClick={onEdit}
|
|
>
|
|
编辑配置
|
|
</Button>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|
|
|
|
function SummaryItem({ children, label }) {
|
|
return (
|
|
<div className={styles.summaryItem}>
|
|
<span className={styles.summaryLabel}>{label}</span>
|
|
<span className={styles.summaryValue}>{children}</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function ConfigStatus({ config, loading }) {
|
|
return (
|
|
<span
|
|
className={[
|
|
"status-badge",
|
|
config?.enabled ? "status-badge--running" : loading ? "status-badge--warning" : "status-badge--stopped",
|
|
].join(" ")}
|
|
>
|
|
<span className="status-point" />
|
|
{config?.enabled ? "已开启" : loading ? "加载中" : "已关闭"}
|
|
</span>
|
|
);
|
|
}
|
|
|
|
function formatPercent(ppm) {
|
|
const value = Number(ppm || 0) / 10_000;
|
|
return `${value.toFixed(2).replace(/\.?0+$/, "")}%`;
|
|
}
|