From 05412e477a799178c596b4afc0ed66d613f4a4b5 Mon Sep 17 00:00:00 2001 From: zhx Date: Tue, 23 Jun 2026 14:05:17 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9C=BA=E5=99=A8=E4=BA=BA=E8=BF=9B=E7=9C=9F?= =?UTF-8?q?=E4=BA=BA=E6=88=BF=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contracts/admin-openapi.json | 6 +++ src/features/rooms/hooks/useRobotRoomsPage.js | 2 + src/features/rooms/pages/RoomRobotPage.jsx | 38 ++++++++------- src/features/rooms/rooms.module.css | 46 +++++++++++++------ src/features/rooms/schema.test.ts | 4 +- src/features/rooms/schema.ts | 16 +++++++ src/shared/api/generated/schema.d.ts | 1 + src/shared/api/types.ts | 1 + 8 files changed, 83 insertions(+), 31 deletions(-) diff --git a/contracts/admin-openapi.json b/contracts/admin-openapi.json index 3bfabdc..d96c47a 100644 --- a/contracts/admin-openapi.json +++ b/contracts/admin-openapi.json @@ -5500,6 +5500,12 @@ "type": "object", "required": ["countryCode", "maxRoomCount"], "properties": { + "allowedOwnerIds": { + "items": { + "type": "string" + }, + "type": "array" + }, "countryCode": { "type": "string" }, diff --git a/src/features/rooms/hooks/useRobotRoomsPage.js b/src/features/rooms/hooks/useRobotRoomsPage.js index 20ef30a..dc95faf 100644 --- a/src/features/rooms/hooks/useRobotRoomsPage.js +++ b/src/features/rooms/hooks/useRobotRoomsPage.js @@ -70,6 +70,7 @@ function emptyHumanConfigForm() { function emptyHumanCountryRule(countryOptions = [], existingRules = []) { return { + allowedOwnerIds: "", countryCode: firstAvailableCountryCode(countryOptions, existingRules), maxRoomCount: "1", }; @@ -405,6 +406,7 @@ function humanConfigToForm(config = null) { candidateRoomMaxOnline: String(config.candidateRoomMaxOnline ?? defaults.candidateRoomMaxOnline), countryLimitEnabled: Boolean(config.countryLimitEnabled), countryRules: (config.countryRules || []).map((rule) => ({ + allowedOwnerIds: (rule.allowedOwnerIds || []).map(String).join(","), countryCode: String(rule.countryCode || "").toUpperCase(), maxRoomCount: String(rule.maxRoomCount ?? "1"), })), diff --git a/src/features/rooms/pages/RoomRobotPage.jsx b/src/features/rooms/pages/RoomRobotPage.jsx index 76afd44..89ff28c 100644 --- a/src/features/rooms/pages/RoomRobotPage.jsx +++ b/src/features/rooms/pages/RoomRobotPage.jsx @@ -7,6 +7,7 @@ import MenuItem from "@mui/material/MenuItem"; import TextField from "@mui/material/TextField"; import Tooltip from "@mui/material/Tooltip"; import { Button } from "@/shared/ui/Button.jsx"; +import { IconButton } from "@/shared/ui/IconButton.jsx"; import { AdminFormAmountField, AdminFormDialog, @@ -591,15 +592,6 @@ function HumanConfigDialog({ page }) { > {page.humanConfigForm.countryLimitEnabled ? : null} - -
-
机器人池自动获取
-
- {page.humanConfigForm.countryLimitEnabled - ? "国家配置启用后,只会读取已配置国家的机器人,并限制每个国家同时进入的真人房数量。" - : "系统会读取所有启用的全站机器人,并按机器人账号国家进入同国家真人房间。"} -
-
); } @@ -657,13 +649,27 @@ function HumanCountryRules({ page }) { value={rule.maxRoomCount} onChange={(value) => page.updateHumanCountryRule(index, { maxRoomCount: value })} /> - + + page.updateHumanCountryRule(index, { allowedOwnerIds: event.target.value }) + } + /> + + + page.removeHumanCountryRule(index)} + > + + + + ))} {rows.length === 0 ?
当前无数据
: null} diff --git a/src/features/rooms/rooms.module.css b/src/features/rooms/rooms.module.css index 0e0b2ba..db029a1 100644 --- a/src/features/rooms/rooms.module.css +++ b/src/features/rooms/rooms.module.css @@ -293,15 +293,6 @@ gap: var(--space-2); } -.robotAutoPoolNotice { - display: grid; - gap: var(--space-3); - padding: var(--space-3); - border: 1px solid var(--border); - border-radius: var(--radius-control); - background: var(--bg-card-strong); -} - .countryRulesSection { display: grid; gap: var(--space-3); @@ -321,14 +312,32 @@ .countryRuleRows { display: grid; - gap: var(--space-2); + gap: var(--space-3); } .countryRuleRow { display: grid; - grid-template-columns: minmax(220px, 1fr) minmax(132px, 0.42fr) auto; - align-items: center; - gap: var(--space-2); + grid-template-columns: minmax(0, 1fr) minmax(128px, 160px) auto; + align-items: start; + gap: var(--space-3); +} + +.countryRuleRow > :global(.MuiTextField-root), +.countryRuleRow > :global(.MuiFormControl-root) { + width: 100%; +} + +.countryRuleOwners { + grid-column: 1 / -1; + grid-row: 2; +} + +.countryRuleRemove { + display: inline-flex; + grid-column: 3; + grid-row: 1; + align-self: center; + justify-content: flex-end; } @media (max-width: 720px) { @@ -342,6 +351,17 @@ .countryRuleRow { grid-template-columns: 1fr; } + + .countryRuleOwners { + grid-column: auto; + grid-row: auto; + } + + .countryRuleRemove { + grid-column: auto; + grid-row: auto; + justify-content: flex-start; + } } .rowActions { diff --git a/src/features/rooms/schema.test.ts b/src/features/rooms/schema.test.ts index 729cc87..0d8c796 100644 --- a/src/features/rooms/schema.test.ts +++ b/src/features/rooms/schema.test.ts @@ -41,7 +41,7 @@ describe("human room robot config schema", () => { const payload = parseForm(humanRoomRobotConfigSchema, { candidateRoomMaxOnline: "5", countryLimitEnabled: true, - countryRules: [{ countryCode: "sa", maxRoomCount: "2" }], + countryRules: [{ allowedOwnerIds: "1001, 1002,,1001", countryCode: "sa", maxRoomCount: "2" }], enabled: true, giftIds: ["84"], luckyComboMax: "3", @@ -68,7 +68,7 @@ describe("human room robot config schema", () => { expect(payload.normalGiftIntervalMaxMs).toBe(20000); expect(payload.giftIds).toEqual(["84"]); expect(payload.countryLimitEnabled).toBe(true); - expect(payload.countryRules).toEqual([{ countryCode: "SA", maxRoomCount: 2 }]); + expect(payload.countryRules).toEqual([{ allowedOwnerIds: ["1001", "1002"], countryCode: "SA", maxRoomCount: 2 }]); }); test("rejects duplicated country rules", () => { diff --git a/src/features/rooms/schema.ts b/src/features/rooms/schema.ts index b7788b2..7f67085 100644 --- a/src/features/rooms/schema.ts +++ b/src/features/rooms/schema.ts @@ -12,6 +12,21 @@ const countryCodeSchema = z .trim() .transform((value) => value.toUpperCase()) .refine((value) => /^[A-Z]{2,3}$/.test(value), "国家码不正确"); +const commaSeparatedTextListSchema = z + .union([z.string(), z.array(z.union([z.string(), z.number()]))]) + .optional() + .default("") + .transform((value) => { + const raw = Array.isArray(value) ? value.join(",") : value; + return [ + ...new Set( + String(raw || "") + .split(",") + .map((item) => item.trim()) + .filter(Boolean), + ), + ]; + }); const pinTypeSchema = z .string() .trim() @@ -146,6 +161,7 @@ export const humanRoomRobotConfigSchema = z countryRules: z .array( z.object({ + allowedOwnerIds: commaSeparatedTextListSchema, countryCode: countryCodeSchema, maxRoomCount: z.coerce.number().int().min(1, "国家进房数量不正确"), }), diff --git a/src/shared/api/generated/schema.d.ts b/src/shared/api/generated/schema.d.ts index af25283..f373bfb 100644 --- a/src/shared/api/generated/schema.d.ts +++ b/src/shared/api/generated/schema.d.ts @@ -3350,6 +3350,7 @@ export interface components { userId: string; }; HumanRoomRobotCountryRule: { + allowedOwnerIds?: string[]; countryCode: string; maxRoomCount: number; }; diff --git a/src/shared/api/types.ts b/src/shared/api/types.ts index 6977431..1c2b3cc 100644 --- a/src/shared/api/types.ts +++ b/src/shared/api/types.ts @@ -1061,6 +1061,7 @@ export interface HumanRoomRobotConfigDto { } export interface HumanRoomRobotCountryRuleDto { + allowedOwnerIds?: string[]; countryCode: string; maxRoomCount: number; }