feat(admin): 完善玩家管理与角色配置
This commit is contained in:
@@ -86,12 +86,6 @@ type PlayBatchSwitchGroup = {
|
||||
match: (row: PlayConfigItemRow) => boolean;
|
||||
};
|
||||
|
||||
const TRADITIONAL_PLAY_CODES = new Set([
|
||||
"big", "small", "pos_4a", "pos_4b", "pos_4c", "pos_4d", "pos_4e", "four_any", "four_top", "four_lower",
|
||||
"pos_3a", "pos_3lower", "pos_3b", "pos_3c", "pos_3d", "pos_3e",
|
||||
"pos_2a", "pos_2b", "pos_2c", "pos_2d", "pos_2e", "pos_2any",
|
||||
]);
|
||||
|
||||
const PLAY_BATCH_SWITCH_GROUPS: PlayBatchSwitchGroup[] = [
|
||||
{
|
||||
key: "d2",
|
||||
@@ -118,8 +112,8 @@ const PLAY_BATCH_SWITCH_GROUPS: PlayBatchSwitchGroup[] = [
|
||||
match: (row) => row.category === "box",
|
||||
},
|
||||
{
|
||||
key: "jackpot",
|
||||
match: (row) => row.category === "jackpot" || row.play_code.includes("jackpot"),
|
||||
key: "attribute",
|
||||
match: (row) => row.category === "attribute",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -273,7 +267,7 @@ export function PlayConfigDocScreen() {
|
||||
|
||||
const orderedRows = useMemo(
|
||||
() =>
|
||||
draftRows.filter((row) => TRADITIONAL_PLAY_CODES.has(row.play_code)).sort(
|
||||
[...draftRows].sort(
|
||||
(a, b) => a.display_order - b.display_order || a.play_code.localeCompare(b.play_code),
|
||||
),
|
||||
[draftRows],
|
||||
@@ -342,6 +336,7 @@ export function PlayConfigDocScreen() {
|
||||
setDraftRows((prev) =>
|
||||
prev.map((row) => (group.match(row) ? { ...row, is_enabled: enabled } : row)),
|
||||
);
|
||||
toast.success(t("play.batchSwitchSavedLocal", { ns: "config" }));
|
||||
}
|
||||
|
||||
const batchSwitchStates = useMemo(
|
||||
@@ -582,47 +577,59 @@ export function PlayConfigDocScreen() {
|
||||
) : null}
|
||||
</div>
|
||||
{isDraft ? (
|
||||
<ConfigChipGroup label={t("play.batchSwitchesTitle", { ns: "config" })}>
|
||||
{batchSwitchStates.map((group) => {
|
||||
const groupOn = group.allEnabled;
|
||||
const isPartial =
|
||||
group.total > 0 && group.enabledCount > 0 && group.enabledCount < group.total;
|
||||
return (
|
||||
<label
|
||||
key={group.key}
|
||||
className="inline-flex cursor-pointer items-center gap-2 rounded-md border border-border/60 px-2.5 py-1.5 text-sm"
|
||||
>
|
||||
<span>{group.label}</span>
|
||||
<Checkbox
|
||||
checked={groupOn}
|
||||
indeterminate={isPartial}
|
||||
disabled={saving || group.total === 0 || confirmBusy}
|
||||
aria-label={t("play.aria.batchGroupSwitch", {
|
||||
ns: "config",
|
||||
group: group.label,
|
||||
})}
|
||||
onCheckedChange={(checked) => {
|
||||
const enable = checked === true;
|
||||
const action = enable
|
||||
? t("play.batchSwitchEnable", { ns: "config" })
|
||||
: t("play.batchSwitchDisable", { ns: "config" });
|
||||
requestConfirm({
|
||||
title: t("play.batchSwitchConfirmTitle", { ns: "config", action }),
|
||||
description: t("play.batchSwitchConfirmDescription", {
|
||||
ns: "config",
|
||||
action,
|
||||
group: group.label,
|
||||
count: group.total,
|
||||
}),
|
||||
confirmVariant: enable ? "default" : "destructive",
|
||||
onConfirm: () => applyBatchSwitch(group, enable),
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</label>
|
||||
);
|
||||
})}
|
||||
</ConfigChipGroup>
|
||||
<div className="space-y-1.5">
|
||||
<ConfigChipGroup label={t("play.batchSwitchesTitle", { ns: "config" })}>
|
||||
{batchSwitchStates.map((group) => {
|
||||
const groupOn = group.allEnabled;
|
||||
const isPartial =
|
||||
group.total > 0 && group.enabledCount > 0 && group.enabledCount < group.total;
|
||||
return (
|
||||
<label
|
||||
key={group.key}
|
||||
className="inline-flex cursor-pointer items-center gap-2 rounded-md border border-border/60 px-2.5 py-1.5 text-sm"
|
||||
>
|
||||
<span>{group.label}</span>
|
||||
<span className="text-xs tabular-nums text-muted-foreground">
|
||||
{t("play.batchEnabledCount", {
|
||||
ns: "config",
|
||||
enabledCount: group.enabledCount,
|
||||
total: group.total,
|
||||
})}
|
||||
</span>
|
||||
<Checkbox
|
||||
checked={groupOn}
|
||||
indeterminate={isPartial}
|
||||
disabled={saving || group.total === 0 || confirmBusy}
|
||||
aria-label={t("play.aria.batchGroupSwitch", {
|
||||
ns: "config",
|
||||
group: group.label,
|
||||
})}
|
||||
onCheckedChange={(checked) => {
|
||||
const enable = checked === true;
|
||||
const action = enable
|
||||
? t("play.batchSwitchEnable", { ns: "config" })
|
||||
: t("play.batchSwitchDisable", { ns: "config" });
|
||||
requestConfirm({
|
||||
title: t("play.batchSwitchConfirmTitle", { ns: "config", action }),
|
||||
description: t("play.batchSwitchConfirmDescription", {
|
||||
ns: "config",
|
||||
action,
|
||||
group: group.label,
|
||||
count: group.total,
|
||||
}),
|
||||
confirmVariant: enable ? "default" : "destructive",
|
||||
onConfirm: () => applyBatchSwitch(group, enable),
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</label>
|
||||
);
|
||||
})}
|
||||
</ConfigChipGroup>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{t("play.batchSwitchesDesc", { ns: "config" })}
|
||||
</p>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
Reference in New Issue
Block a user