修复房间奖励
This commit is contained in:
parent
0be921409d
commit
723258a3aa
@ -29,6 +29,7 @@ import {
|
||||
} from "@/shared/ui/AdminListLayout.jsx";
|
||||
import { DataState } from "@/shared/ui/DataState.jsx";
|
||||
import { DataTable } from "@/shared/ui/DataTable.jsx";
|
||||
import { TimeRangeFilter } from "@/shared/ui/TimeRangeFilter.jsx";
|
||||
import { TimeText } from "@/shared/ui/TimeText.jsx";
|
||||
|
||||
const statusOptions = [
|
||||
@ -117,8 +118,8 @@ export function AgencyOpeningPage() {
|
||||
cycleId: cycle.cycleId,
|
||||
title: cycle.title,
|
||||
status: cycle.status || "draft",
|
||||
startMs: millisToInput(cycle.startMs),
|
||||
endMs: millisToInput(cycle.endMs),
|
||||
startMs: cycle.startMs || "",
|
||||
endMs: cycle.endMs || "",
|
||||
minHostCount: String(cycle.minHostCount || 10),
|
||||
maxAgencyAgeDays: String(cycle.maxAgencyAgeDays || 0),
|
||||
rewards: (cycle.rewards?.length ? cycle.rewards : emptyForm.rewards).map((reward) => ({
|
||||
@ -136,12 +137,20 @@ export function AgencyOpeningPage() {
|
||||
if (!abilities.canUpdate && form.cycleId) return;
|
||||
setSaving(true);
|
||||
try {
|
||||
const startMs = Number(form.startMs || 0);
|
||||
const endMs = Number(form.endMs || 0);
|
||||
if (startMs <= 0 || endMs <= 0) {
|
||||
throw new Error("请选择活动开始和结束时间");
|
||||
}
|
||||
if (endMs <= startMs) {
|
||||
throw new Error("结束时间必须晚于开始时间");
|
||||
}
|
||||
const payload = {
|
||||
cycle_id: form.cycleId || undefined,
|
||||
title: form.title.trim(),
|
||||
status: form.status,
|
||||
start_ms: inputToMillis(form.startMs),
|
||||
end_ms: inputToMillis(form.endMs),
|
||||
start_ms: startMs,
|
||||
end_ms: endMs,
|
||||
min_host_count: Number(form.minHostCount || 0),
|
||||
max_agency_age_days: Number(form.maxAgencyAgeDays || 0),
|
||||
rewards: normalizeRewardPayload(form.rewards),
|
||||
@ -421,22 +430,16 @@ export function AgencyOpeningPage() {
|
||||
</MenuItem>
|
||||
))}
|
||||
</TextField>
|
||||
<TextField
|
||||
label="开始时间"
|
||||
required
|
||||
type="datetime-local"
|
||||
value={form.startMs}
|
||||
onChange={(event) => setForm({ ...form, startMs: event.target.value })}
|
||||
InputLabelProps={{ shrink: true }}
|
||||
/>
|
||||
<TextField
|
||||
label="结束时间"
|
||||
required
|
||||
type="datetime-local"
|
||||
value={form.endMs}
|
||||
onChange={(event) => setForm({ ...form, endMs: event.target.value })}
|
||||
InputLabelProps={{ shrink: true }}
|
||||
/>
|
||||
<div className="weekly-star-time-range">
|
||||
<TimeRangeFilter
|
||||
className="weekly-star-time-range__control"
|
||||
label="活动时间"
|
||||
value={{ endMs: form.endMs, startMs: form.startMs }}
|
||||
onChange={(range) =>
|
||||
setForm({ ...form, endMs: range.endMs, startMs: range.startMs })
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<TextField
|
||||
label="主播数必须大于"
|
||||
required
|
||||
@ -548,16 +551,6 @@ function applicationStatusLabel(status) {
|
||||
);
|
||||
}
|
||||
|
||||
function millisToInput(ms) {
|
||||
if (!ms) return "";
|
||||
const local = new Date(ms - new Date(ms).getTimezoneOffset() * 60000);
|
||||
return local.toISOString().slice(0, 16);
|
||||
}
|
||||
|
||||
function inputToMillis(value) {
|
||||
return value ? new Date(value).getTime() : 0;
|
||||
}
|
||||
|
||||
function normalizeRewardPayload(rewards) {
|
||||
const payload = (rewards || []).map((reward, index) => {
|
||||
const thresholdCoinSpent = Number(reward.thresholdCoinSpent || 0);
|
||||
|
||||
@ -40,6 +40,7 @@ export interface RoomTurnoverRewardSettlementDto {
|
||||
settlementId: string;
|
||||
roomId: string;
|
||||
ownerUserId: string;
|
||||
ownerUser?: Record<string, unknown>;
|
||||
periodStartMs: number;
|
||||
periodEndMs: number;
|
||||
coinSpent: number;
|
||||
@ -59,6 +60,8 @@ export interface RoomTurnoverRewardSettlementDto {
|
||||
export interface RoomTurnoverRewardSettlementQuery extends PageQuery {
|
||||
status?: string;
|
||||
keyword?: string;
|
||||
owner_user_keyword?: string;
|
||||
owner_user_id?: string;
|
||||
}
|
||||
|
||||
type RawConfig = RoomTurnoverRewardConfigDto & Record<string, unknown>;
|
||||
@ -141,6 +144,7 @@ function normalizeSettlement(item: RawSettlement): RoomTurnoverRewardSettlementD
|
||||
settlementId: stringValue(item.settlementId ?? item.settlement_id),
|
||||
roomId: stringValue(item.roomId ?? item.room_id),
|
||||
ownerUserId: stringValue(item.ownerUserId ?? item.owner_user_id),
|
||||
ownerUser: objectValue(item.ownerUser ?? item.owner_user),
|
||||
periodStartMs: numberValue(item.periodStartMs ?? item.period_start_ms),
|
||||
periodEndMs: numberValue(item.periodEndMs ?? item.period_end_ms),
|
||||
coinSpent: numberValue(item.coinSpent ?? item.coin_spent),
|
||||
@ -166,3 +170,7 @@ function numberValue(value: unknown) {
|
||||
const number = Number(value || 0);
|
||||
return Number.isFinite(number) ? number : 0;
|
||||
}
|
||||
|
||||
function objectValue(value: unknown) {
|
||||
return value && typeof value === "object" && !Array.isArray(value) ? (value as Record<string, unknown>) : undefined;
|
||||
}
|
||||
|
||||
@ -29,9 +29,13 @@ export function useRoomTurnoverRewardPage() {
|
||||
const [configSaving, setConfigSaving] = useState(false);
|
||||
const [retryingSettlementId, setRetryingSettlementId] = useState("");
|
||||
const [query, setQuery] = useState("");
|
||||
const [ownerUserKeyword, setOwnerUserKeyword] = useState("");
|
||||
const [status, setStatus] = useState("");
|
||||
const [page, setPage] = useState(1);
|
||||
const filters = useMemo(() => ({ keyword: query, status }), [query, status]);
|
||||
const filters = useMemo(
|
||||
() => ({ keyword: query, owner_user_keyword: ownerUserKeyword, status }),
|
||||
[ownerUserKeyword, query, status],
|
||||
);
|
||||
const {
|
||||
data: settlements = emptySettlements,
|
||||
error: settlementsError,
|
||||
@ -83,6 +87,11 @@ export function useRoomTurnoverRewardPage() {
|
||||
setPage(1);
|
||||
};
|
||||
|
||||
const changeOwnerUserKeyword = (value) => {
|
||||
setOwnerUserKeyword(value);
|
||||
setPage(1);
|
||||
};
|
||||
|
||||
const submitConfig = async (event) => {
|
||||
event.preventDefault();
|
||||
if (!abilities.canUpdate) {
|
||||
@ -129,6 +138,7 @@ export function useRoomTurnoverRewardPage() {
|
||||
|
||||
return {
|
||||
abilities,
|
||||
changeOwnerUserKeyword,
|
||||
changeQuery,
|
||||
changeStatus,
|
||||
closeConfigDrawer,
|
||||
@ -138,6 +148,7 @@ export function useRoomTurnoverRewardPage() {
|
||||
configSaving,
|
||||
form,
|
||||
openConfigDrawer,
|
||||
ownerUserKeyword,
|
||||
page,
|
||||
query,
|
||||
reloadConfig,
|
||||
|
||||
@ -4,6 +4,7 @@ import { RoomTurnoverRewardConfigSummary } from "@/features/room-turnover-reward
|
||||
import { useRoomTurnoverRewardPage } from "@/features/room-turnover-reward/hooks/useRoomTurnoverRewardPage.js";
|
||||
import styles from "@/features/room-turnover-reward/room-turnover-reward.module.css";
|
||||
import { AdminActionIconButton, AdminListBody, AdminListPage } from "@/shared/ui/AdminListLayout.jsx";
|
||||
import { AdminUserIdentity } from "@/shared/ui/AdminUserIdentity.jsx";
|
||||
import { DataState } from "@/shared/ui/DataState.jsx";
|
||||
import { DataTable } from "@/shared/ui/DataTable.jsx";
|
||||
import { createOptionsColumnFilter, createTextColumnFilter } from "@/shared/ui/tableFilters.js";
|
||||
@ -23,10 +24,15 @@ const columnsBase = [
|
||||
render: (item) => (
|
||||
<div className={styles.stack}>
|
||||
<span className={styles.name}>{item.roomId || "-"}</span>
|
||||
<span className={styles.meta}>房主 {item.ownerUserId || "-"}</span>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "owner",
|
||||
label: "房主信息",
|
||||
width: "minmax(240px, 0.95fr)",
|
||||
render: (item) => <OwnerUser item={item} />,
|
||||
},
|
||||
{
|
||||
key: "period",
|
||||
label: "周期",
|
||||
@ -122,6 +128,16 @@ export function RoomTurnoverRewardPage() {
|
||||
}),
|
||||
};
|
||||
}
|
||||
if (column.key === "owner") {
|
||||
return {
|
||||
...column,
|
||||
filter: createTextColumnFilter({
|
||||
placeholder: "搜索房主 ID、短号、名称",
|
||||
value: page.ownerUserKeyword,
|
||||
onChange: page.changeOwnerUserKeyword,
|
||||
}),
|
||||
};
|
||||
}
|
||||
if (column.key === "status") {
|
||||
return {
|
||||
...column,
|
||||
@ -155,7 +171,7 @@ export function RoomTurnoverRewardPage() {
|
||||
retrySettlement: page.retrySettlement,
|
||||
}}
|
||||
items={page.settlements.items || []}
|
||||
minWidth="1480px"
|
||||
minWidth="1700px"
|
||||
pagination={
|
||||
total > 0
|
||||
? {
|
||||
@ -184,6 +200,11 @@ export function RoomTurnoverRewardPage() {
|
||||
);
|
||||
}
|
||||
|
||||
function OwnerUser({ item }) {
|
||||
const owner = item.ownerUser || {};
|
||||
return <AdminUserIdentity openInAppUserDetail user={{ ...owner, userId: owner.userId || item.ownerUserId }} />;
|
||||
}
|
||||
|
||||
function settlementStatusBadge(status) {
|
||||
const label = settlementStatusOptions.find(([value]) => value === status)?.[1] || status || "-";
|
||||
const className =
|
||||
|
||||
@ -29,7 +29,6 @@ function emptyForm() {
|
||||
minRobotCount: "6",
|
||||
normalGiftIntervalMs: "10000",
|
||||
ownerRobotUserId: "",
|
||||
roomName: "",
|
||||
visibleRegionId: 0,
|
||||
};
|
||||
}
|
||||
|
||||
@ -153,11 +153,6 @@ export function RoomRobotPage() {
|
||||
onClose={page.closeAction}
|
||||
onSubmit={page.submitCreate}
|
||||
>
|
||||
<TextField
|
||||
label="房间名称"
|
||||
value={page.form.roomName}
|
||||
onChange={(event) => page.setForm({ ...page.form, roomName: event.target.value })}
|
||||
/>
|
||||
<Autocomplete
|
||||
getOptionLabel={robotOptionLabel}
|
||||
isOptionEqualToValue={(option, value) => option.userId === value.userId}
|
||||
|
||||
@ -83,7 +83,6 @@ export const robotRoomCreateSchema = z
|
||||
minRobotCount: z.coerce.number().int().min(1, "机器人数量范围不正确"),
|
||||
normalGiftIntervalMs: z.coerce.number().int().min(1000, "普通礼物频次不正确"),
|
||||
ownerRobotUserId: z.coerce.number().int().positive("请选择房主机器人"),
|
||||
roomName: z.string().trim().max(128, "房间名称不能超过 128 个字符").optional().default(""),
|
||||
visibleRegionId: z.coerce.number().int().min(0, "区域 ID 不正确").default(0),
|
||||
})
|
||||
.refine((value) => value.maxRobotCount >= value.minRobotCount, {
|
||||
|
||||
@ -1048,10 +1048,11 @@
|
||||
.weekly-star-time-range {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.weekly-star-time-range__control {
|
||||
width: min(520px, 100%);
|
||||
width: min(680px, 100%) !important;
|
||||
}
|
||||
|
||||
.weekly-star-config-card-grid {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user