修复报错
This commit is contained in:
parent
ac5d3a53d9
commit
2ebacae7c2
@ -4892,10 +4892,10 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"ownerUserId": {
|
"ownerUserId": {
|
||||||
"type": "integer"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"parentBdUserId": {
|
"parentBdUserId": {
|
||||||
"type": "integer"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"regionId": {
|
"regionId": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
@ -4919,7 +4919,7 @@
|
|||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"parentLeaderUserId": {
|
"parentLeaderUserId": {
|
||||||
"type": "integer"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"regionId": {
|
"regionId": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
@ -4934,7 +4934,7 @@
|
|||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"userId": {
|
"userId": {
|
||||||
"type": "integer"
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -4991,7 +4991,7 @@
|
|||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"userId": {
|
"userId": {
|
||||||
"type": "integer"
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -71,7 +71,7 @@ test("loads self game statistics from the big screen switch", async () => {
|
|||||||
|
|
||||||
expect(fetchSelfGameStatisticsOverview).toHaveBeenCalledWith(expect.objectContaining({ appCode: "lalu", gameId: "all" }));
|
expect(fetchSelfGameStatisticsOverview).toHaveBeenCalledWith(expect.objectContaining({ appCode: "lalu", gameId: "all" }));
|
||||||
expect(screen.getByText("Dice / Rock H5 聚合统计")).toBeTruthy();
|
expect(screen.getByText("Dice / Rock H5 聚合统计")).toBeTruthy();
|
||||||
expect(screen.getByText("对局数")).toBeTruthy();
|
expect(screen.getByText("创建局")).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
async function flushEffects() {
|
async function flushEffects() {
|
||||||
|
|||||||
@ -158,11 +158,11 @@ function FilterMenu({ className = "", icon, isOpen, label, loading = false, onSe
|
|||||||
return (
|
return (
|
||||||
<div className={["filter-control", className].filter(Boolean).join(" ")}>
|
<div className={["filter-control", className].filter(Boolean).join(" ")}>
|
||||||
<button aria-expanded={isOpen} className="filter-trigger" disabled={loading} onClick={onToggle} type="button">
|
<button aria-expanded={isOpen} className="filter-trigger" disabled={loading} onClick={onToggle} type="button">
|
||||||
{icon ? <span className="filter-icon">{icon}</span> : null}
|
<span className="filter-label">
|
||||||
<span className="filter-copy">
|
{icon ? <span className="filter-icon">{icon}</span> : null}
|
||||||
<small>{label}</small>
|
<span>{label}</span>
|
||||||
<b>{valueLabel}</b>
|
|
||||||
</span>
|
</span>
|
||||||
|
<span className="filter-value">{valueLabel}</span>
|
||||||
<KeyboardArrowDownOutlined className="filter-chevron" fontSize="small" />
|
<KeyboardArrowDownOutlined className="filter-chevron" fontSize="small" />
|
||||||
</button>
|
</button>
|
||||||
{isOpen ? (
|
{isOpen ? (
|
||||||
@ -201,11 +201,11 @@ function SearchableFilterMenu({ icon, isOpen, label, loading = false, onSelect,
|
|||||||
return (
|
return (
|
||||||
<div className="filter-control filter-control--country">
|
<div className="filter-control filter-control--country">
|
||||||
<button aria-expanded={isOpen} className="filter-trigger" disabled={loading} onClick={onToggle} type="button">
|
<button aria-expanded={isOpen} className="filter-trigger" disabled={loading} onClick={onToggle} type="button">
|
||||||
{icon ? <span className="filter-icon">{icon}</span> : null}
|
<span className="filter-label">
|
||||||
<span className="filter-copy">
|
{icon ? <span className="filter-icon">{icon}</span> : null}
|
||||||
<small>{label}</small>
|
<span>{label}</span>
|
||||||
<b>{valueLabel}</b>
|
|
||||||
</span>
|
</span>
|
||||||
|
<span className="filter-value">{valueLabel}</span>
|
||||||
<KeyboardArrowDownOutlined className="filter-chevron" fontSize="small" />
|
<KeyboardArrowDownOutlined className="filter-chevron" fontSize="small" />
|
||||||
</button>
|
</button>
|
||||||
{isOpen ? (
|
{isOpen ? (
|
||||||
@ -301,14 +301,14 @@ function RangeMenu({ activeValue, isOpen, onSelect, onToggle, range, timeZone })
|
|||||||
return (
|
return (
|
||||||
<div className="filter-control filter-control--range">
|
<div className="filter-control filter-control--range">
|
||||||
<button aria-expanded={isOpen} aria-haspopup="listbox" className="date-range-trigger" onClick={onToggle} type="button">
|
<button aria-expanded={isOpen} aria-haspopup="listbox" className="date-range-trigger" onClick={onToggle} type="button">
|
||||||
<span className="date-range-icon"><CalendarMonthOutlined fontSize="small" /></span>
|
<span className="date-range-label">
|
||||||
<span className="date-range-copy">
|
<CalendarMonthOutlined fontSize="inherit" />
|
||||||
<span className="date-range-label">{activeOption?.label || "时间范围"}</span>
|
<span>{activeOption?.label || "时间范围"}</span>
|
||||||
<span className="date-range-values">
|
</span>
|
||||||
<b>{range.start}</b>
|
<span className="date-range-values">
|
||||||
<i>~</i>
|
<b>{range.start}</b>
|
||||||
<b>{range.end}</b>
|
<i>~</i>
|
||||||
</span>
|
<b>{range.end}</b>
|
||||||
</span>
|
</span>
|
||||||
<KeyboardArrowDownOutlined className="date-range-chevron" fontSize="small" />
|
<KeyboardArrowDownOutlined className="date-range-chevron" fontSize="small" />
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@ -131,13 +131,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.filter-trigger {
|
.filter-trigger {
|
||||||
|
position: relative;
|
||||||
display: grid;
|
display: grid;
|
||||||
min-width: 138px;
|
min-width: 138px;
|
||||||
height: 44px;
|
height: 34px;
|
||||||
grid-template-columns: auto minmax(0, 1fr) auto;
|
grid-template-columns: minmax(0, 1fr) 18px;
|
||||||
align-items: center;
|
align-items: end;
|
||||||
gap: 10px;
|
gap: 0;
|
||||||
padding: 0 12px;
|
padding: 7px 28px 3px 12px;
|
||||||
border: 1px solid rgba(64, 148, 197, 0.48);
|
border: 1px solid rgba(64, 148, 197, 0.48);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background: rgba(7, 29, 48, 0.9);
|
background: rgba(7, 29, 48, 0.9);
|
||||||
@ -167,6 +168,13 @@
|
|||||||
box-shadow: 0 0 0 3px rgba(39, 228, 245, 0.08);
|
box-shadow: 0 0 0 3px rgba(39, 228, 245, 0.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.filter-trigger:hover .filter-label,
|
||||||
|
.filter-trigger[aria-expanded="true"] .filter-label,
|
||||||
|
.date-range-trigger:hover .date-range-label,
|
||||||
|
.date-range-trigger[aria-expanded="true"] .date-range-label {
|
||||||
|
color: #27e4f5;
|
||||||
|
}
|
||||||
|
|
||||||
.filter-trigger:disabled {
|
.filter-trigger:disabled {
|
||||||
cursor: progress;
|
cursor: progress;
|
||||||
opacity: 0.68;
|
opacity: 0.68;
|
||||||
@ -177,10 +185,24 @@
|
|||||||
color: #cbd9e9;
|
color: #cbd9e9;
|
||||||
}
|
}
|
||||||
|
|
||||||
.filter-icon {
|
.filter-label {
|
||||||
display: grid;
|
position: absolute;
|
||||||
min-width: 20px;
|
top: -8px;
|
||||||
place-items: center;
|
left: 10px;
|
||||||
|
display: inline-flex;
|
||||||
|
max-width: calc(100% - 20px);
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0 5px;
|
||||||
|
border-radius: 5px;
|
||||||
|
background: rgba(2, 15, 31, 0.98);
|
||||||
|
color: #7f9bb7;
|
||||||
|
font-size: 10px;
|
||||||
|
font-weight: 760;
|
||||||
|
line-height: 14px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.control-glyph {
|
.control-glyph {
|
||||||
@ -190,38 +212,46 @@
|
|||||||
letter-spacing: 0;
|
letter-spacing: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.filter-copy {
|
.filter-icon {
|
||||||
display: grid;
|
display: inline-grid;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
min-width: 16px;
|
||||||
|
place-items: center;
|
||||||
|
color: #cbd9e9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-label .filter-icon {
|
||||||
|
color: #27e4f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-value {
|
||||||
|
display: block;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
|
||||||
|
|
||||||
.filter-copy small {
|
|
||||||
overflow: hidden;
|
|
||||||
color: #7f9bb7;
|
|
||||||
font-size: 10px;
|
|
||||||
line-height: 1.1;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.filter-copy b {
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
color: #e6f3ff;
|
color: #e6f3ff;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
font-weight: 720;
|
font-weight: 720;
|
||||||
line-height: 1.2;
|
line-height: 18px;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.filter-chevron {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
right: 8px;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
.date-range-trigger {
|
.date-range-trigger {
|
||||||
|
position: relative;
|
||||||
display: grid;
|
display: grid;
|
||||||
width: 336px;
|
width: 318px;
|
||||||
height: 44px;
|
height: 34px;
|
||||||
grid-template-columns: 24px minmax(0, 1fr) 20px;
|
grid-template-columns: minmax(0, 1fr) 18px;
|
||||||
align-items: center;
|
align-items: end;
|
||||||
gap: 10px;
|
gap: 0;
|
||||||
padding: 0 12px;
|
padding: 7px 28px 3px 12px;
|
||||||
border: 1px solid rgba(64, 148, 197, 0.48);
|
border: 1px solid rgba(64, 148, 197, 0.48);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background: rgba(7, 29, 48, 0.9);
|
background: rgba(7, 29, 48, 0.9);
|
||||||
@ -238,49 +268,46 @@
|
|||||||
box-shadow: 0 0 0 3px rgba(39, 228, 245, 0.08);
|
box-shadow: 0 0 0 3px rgba(39, 228, 245, 0.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
.date-range-icon {
|
|
||||||
display: grid;
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
place-items: center;
|
|
||||||
color: #cbd9e9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.date-range-icon svg {
|
|
||||||
width: 19px;
|
|
||||||
height: 19px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.date-range-copy {
|
|
||||||
display: grid;
|
|
||||||
min-width: 0;
|
|
||||||
gap: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.date-range-label {
|
.date-range-label {
|
||||||
|
position: absolute;
|
||||||
|
top: -8px;
|
||||||
|
left: 10px;
|
||||||
|
display: inline-flex;
|
||||||
|
max-width: calc(100% - 20px);
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
padding: 0 5px;
|
||||||
|
border-radius: 5px;
|
||||||
|
background: rgba(2, 15, 31, 0.98);
|
||||||
color: #7f9bb7;
|
color: #7f9bb7;
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
font-weight: 720;
|
font-weight: 760;
|
||||||
line-height: 1.05;
|
line-height: 14px;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.date-range-label svg {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
color: #cbd9e9;
|
||||||
|
}
|
||||||
|
|
||||||
.date-range-values {
|
.date-range-values {
|
||||||
display: grid;
|
display: flex;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
grid-template-columns: minmax(0, auto) 16px minmax(0, auto);
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 7px;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.date-range-values b {
|
.date-range-values b {
|
||||||
|
min-width: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
color: #eaf6ff;
|
color: #eaf6ff;
|
||||||
font-size: 14px;
|
font-size: 13px;
|
||||||
font-weight: 760;
|
font-weight: 760;
|
||||||
line-height: 1.15;
|
line-height: 18px;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
@ -293,8 +320,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.date-range-chevron {
|
.date-range-chevron {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
right: 8px;
|
||||||
color: #cbd9e9;
|
color: #cbd9e9;
|
||||||
justify-self: end;
|
transform: translateY(-50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.filter-popover {
|
.filter-popover {
|
||||||
|
|||||||
@ -155,6 +155,7 @@ export function Header({ activeLabel, isSidebarCollapsed, menuItems = [], onRefr
|
|||||||
<TextField
|
<TextField
|
||||||
className="app-switch"
|
className="app-switch"
|
||||||
disabled={appScope.loading || !appScope.apps.length}
|
disabled={appScope.loading || !appScope.apps.length}
|
||||||
|
label="应用"
|
||||||
select
|
select
|
||||||
size="small"
|
size="small"
|
||||||
value={appScope.appCode}
|
value={appScope.appCode}
|
||||||
@ -172,6 +173,7 @@ export function Header({ activeLabel, isSidebarCollapsed, menuItems = [], onRefr
|
|||||||
</TextField>
|
</TextField>
|
||||||
<TextField
|
<TextField
|
||||||
className="timezone-switch"
|
className="timezone-switch"
|
||||||
|
label="时区"
|
||||||
select
|
select
|
||||||
size="small"
|
size="small"
|
||||||
slotProps={{ htmlInput: { "aria-label": "显示时区" } }}
|
slotProps={{ htmlInput: { "aria-label": "显示时区" } }}
|
||||||
@ -185,8 +187,11 @@ export function Header({ activeLabel, isSidebarCollapsed, menuItems = [], onRefr
|
|||||||
))}
|
))}
|
||||||
</TextField>
|
</TextField>
|
||||||
<button className="search-trigger" type="button" onClick={openSearch}>
|
<button className="search-trigger" type="button" onClick={openSearch}>
|
||||||
<Search fontSize="small" />
|
<span className="search-trigger__label">
|
||||||
<span>搜索菜单、用户、角色...</span>
|
<Search fontSize="inherit" />
|
||||||
|
<span>搜索</span>
|
||||||
|
</span>
|
||||||
|
<span className="search-trigger__value">搜索菜单、用户、角色...</span>
|
||||||
</button>
|
</button>
|
||||||
<IconButton label="刷新" onClick={refresh}>
|
<IconButton label="刷新" onClick={refresh}>
|
||||||
<Refresh fontSize="small" />
|
<Refresh fontSize="small" />
|
||||||
|
|||||||
@ -37,7 +37,7 @@ export interface CumulativeRechargeRewardConfigPayload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface CumulativeRechargeRewardGrantUserDto {
|
export interface CumulativeRechargeRewardGrantUserDto {
|
||||||
userId?: number;
|
userId?: string;
|
||||||
displayUserId?: string;
|
displayUserId?: string;
|
||||||
prettyDisplayUserId?: string;
|
prettyDisplayUserId?: string;
|
||||||
prettyId?: string;
|
prettyId?: string;
|
||||||
@ -52,7 +52,7 @@ export interface CumulativeRechargeRewardGrantDto {
|
|||||||
eventId?: string;
|
eventId?: string;
|
||||||
transactionId?: string;
|
transactionId?: string;
|
||||||
commandId?: string;
|
commandId?: string;
|
||||||
userId: number;
|
userId: string;
|
||||||
user?: CumulativeRechargeRewardGrantUserDto;
|
user?: CumulativeRechargeRewardGrantUserDto;
|
||||||
tierId?: number;
|
tierId?: number;
|
||||||
tierCode?: string;
|
tierCode?: string;
|
||||||
@ -143,9 +143,9 @@ function normalizeGrant(item: RawGrant): CumulativeRechargeRewardGrantDto {
|
|||||||
eventId: stringValue(item.eventId ?? item.event_id),
|
eventId: stringValue(item.eventId ?? item.event_id),
|
||||||
transactionId: stringValue(item.transactionId ?? item.transaction_id),
|
transactionId: stringValue(item.transactionId ?? item.transaction_id),
|
||||||
commandId: stringValue(item.commandId ?? item.command_id),
|
commandId: stringValue(item.commandId ?? item.command_id),
|
||||||
userId: numberValue(item.userId ?? item.user_id),
|
userId: stringValue(item.userId ?? item.user_id),
|
||||||
user: {
|
user: {
|
||||||
userId: numberValue(rawUser.userId ?? rawUser.user_id),
|
userId: stringValue(rawUser.userId ?? rawUser.user_id),
|
||||||
displayUserId: stringValue(rawUser.displayUserId ?? rawUser.display_user_id),
|
displayUserId: stringValue(rawUser.displayUserId ?? rawUser.display_user_id),
|
||||||
prettyDisplayUserId: stringValue(rawUser.prettyDisplayUserId ?? rawUser.pretty_display_user_id),
|
prettyDisplayUserId: stringValue(rawUser.prettyDisplayUserId ?? rawUser.pretty_display_user_id),
|
||||||
prettyId: stringValue(rawUser.prettyId ?? rawUser.pretty_id),
|
prettyId: stringValue(rawUser.prettyId ?? rawUser.pretty_id),
|
||||||
|
|||||||
@ -45,7 +45,7 @@ export interface FirstRechargeRewardConfigPayload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface FirstRechargeRewardClaimUserDto {
|
export interface FirstRechargeRewardClaimUserDto {
|
||||||
userId?: number;
|
userId?: string;
|
||||||
displayUserId?: string;
|
displayUserId?: string;
|
||||||
prettyDisplayUserId?: string;
|
prettyDisplayUserId?: string;
|
||||||
prettyId?: string;
|
prettyId?: string;
|
||||||
@ -58,7 +58,7 @@ export interface FirstRechargeRewardClaimDto {
|
|||||||
eventId?: string;
|
eventId?: string;
|
||||||
transactionId?: string;
|
transactionId?: string;
|
||||||
commandId?: string;
|
commandId?: string;
|
||||||
userId: number;
|
userId: string;
|
||||||
user?: FirstRechargeRewardClaimUserDto;
|
user?: FirstRechargeRewardClaimUserDto;
|
||||||
tierId?: number;
|
tierId?: number;
|
||||||
tierCode?: string;
|
tierCode?: string;
|
||||||
@ -151,9 +151,9 @@ function normalizeClaim(item: RawClaim): FirstRechargeRewardClaimDto {
|
|||||||
eventId: stringValue(item.eventId ?? item.event_id),
|
eventId: stringValue(item.eventId ?? item.event_id),
|
||||||
transactionId: stringValue(item.transactionId ?? item.transaction_id),
|
transactionId: stringValue(item.transactionId ?? item.transaction_id),
|
||||||
commandId: stringValue(item.commandId ?? item.command_id),
|
commandId: stringValue(item.commandId ?? item.command_id),
|
||||||
userId: numberValue(item.userId ?? item.user_id),
|
userId: stringValue(item.userId ?? item.user_id),
|
||||||
user: {
|
user: {
|
||||||
userId: numberValue(rawUser.userId ?? rawUser.user_id),
|
userId: stringValue(rawUser.userId ?? rawUser.user_id),
|
||||||
displayUserId: stringValue(rawUser.displayUserId ?? rawUser.display_user_id),
|
displayUserId: stringValue(rawUser.displayUserId ?? rawUser.display_user_id),
|
||||||
prettyDisplayUserId: stringValue(rawUser.prettyDisplayUserId ?? rawUser.pretty_display_user_id),
|
prettyDisplayUserId: stringValue(rawUser.prettyDisplayUserId ?? rawUser.pretty_display_user_id),
|
||||||
prettyId: stringValue(rawUser.prettyId ?? rawUser.pretty_id),
|
prettyId: stringValue(rawUser.prettyId ?? rawUser.pretty_id),
|
||||||
|
|||||||
@ -305,7 +305,7 @@ export interface TeamSalarySettlePayload {
|
|||||||
cycle_key: string;
|
cycle_key: string;
|
||||||
region_id?: number;
|
region_id?: number;
|
||||||
country_code?: string;
|
country_code?: string;
|
||||||
user_ids?: number[];
|
user_ids?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TeamSalarySettleResult {
|
export interface TeamSalarySettleResult {
|
||||||
|
|||||||
@ -298,8 +298,8 @@ function TeamPendingPanel() {
|
|||||||
// 只从当前页 items 中提取已勾选用户,服务端仍会再次按 user_ids 白名单过滤。
|
// 只从当前页 items 中提取已勾选用户,服务端仍会再次按 user_ids 白名单过滤。
|
||||||
const userIds = items
|
const userIds = items
|
||||||
.filter((item) => selected.has(teamPendingKey(item)))
|
.filter((item) => selected.has(teamPendingKey(item)))
|
||||||
.map((item) => Number(item.userId))
|
.map((item) => String(item.userId || "").trim())
|
||||||
.filter((id) => Number.isFinite(id) && id > 0);
|
.filter((id) => /^[1-9]\d*$/.test(id));
|
||||||
if (!userIds.length) {
|
if (!userIds.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,15 +47,15 @@ test("host org list APIs use generated admin paths and filters", async () => {
|
|||||||
await createBDLeader({
|
await createBDLeader({
|
||||||
commandId: "bd-leader-test",
|
commandId: "bd-leader-test",
|
||||||
positionAlias: "Senior Admin",
|
positionAlias: "Senior Admin",
|
||||||
targetUserId: 1002,
|
targetUserId: "1002",
|
||||||
});
|
});
|
||||||
await updateBDLeaderPositionAlias(1002, {
|
await updateBDLeaderPositionAlias("1002", {
|
||||||
commandId: "bd-leader-position-alias-test",
|
commandId: "bd-leader-position-alias-test",
|
||||||
positionAlias: "Regional Admin",
|
positionAlias: "Regional Admin",
|
||||||
});
|
});
|
||||||
await createCoinSeller({ commandId: "coin-seller-test", reason: "contact", targetUserId: 1001 });
|
await createCoinSeller({ commandId: "coin-seller-test", reason: "contact", targetUserId: "1001" });
|
||||||
await setCoinSellerStatus(1001, { commandId: "coin-seller-status-test", reason: "disable", status: "disabled" });
|
await setCoinSellerStatus("1001", { commandId: "coin-seller-status-test", reason: "disable", status: "disabled" });
|
||||||
await creditCoinSellerStock(1001, {
|
await creditCoinSellerStock("1001", {
|
||||||
coinAmount: 8000000,
|
coinAmount: 8000000,
|
||||||
commandId: "coin-seller-stock-test",
|
commandId: "coin-seller-stock-test",
|
||||||
rechargeAmount: "100.000000",
|
rechargeAmount: "100.000000",
|
||||||
|
|||||||
@ -11,7 +11,15 @@ const commandContactSchema = z.object({
|
|||||||
reason: z.string().trim().max(200, "原因不能超过 200 个字符").optional().default(""),
|
reason: z.string().trim().max(200, "原因不能超过 200 个字符").optional().default(""),
|
||||||
});
|
});
|
||||||
|
|
||||||
const userIdSchema = z.coerce.number().int().positive("请输入有效用户短 ID");
|
const userIdSchema = z.preprocess(
|
||||||
|
(value) => {
|
||||||
|
if (value === null || value === undefined) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return String(value).trim();
|
||||||
|
},
|
||||||
|
z.string().min(1, "请输入有效用户短 ID").regex(/^[1-9]\d*$/, "请输入有效用户短 ID"),
|
||||||
|
);
|
||||||
const entityIdSchema = z.preprocess(
|
const entityIdSchema = z.preprocess(
|
||||||
(value) => {
|
(value) => {
|
||||||
if (value === null || value === undefined) {
|
if (value === null || value === undefined) {
|
||||||
@ -24,14 +32,14 @@ const entityIdSchema = z.preprocess(
|
|||||||
const optionalUserIdSchema = z.preprocess(
|
const optionalUserIdSchema = z.preprocess(
|
||||||
(value) => {
|
(value) => {
|
||||||
if (value === null || value === undefined) {
|
if (value === null || value === undefined) {
|
||||||
return 0;
|
return "0";
|
||||||
}
|
}
|
||||||
if (typeof value === "string" && value.trim() === "") {
|
if (typeof value === "string" && value.trim() === "") {
|
||||||
return 0;
|
return "0";
|
||||||
}
|
}
|
||||||
return value;
|
return String(value).trim();
|
||||||
},
|
},
|
||||||
z.coerce.number().int().min(0, "请输入有效用户短 ID"),
|
z.string().regex(/^(0|[1-9]\d*)$/, "请输入有效用户短 ID"),
|
||||||
);
|
);
|
||||||
const regionIdSchema = z.coerce.number().int().positive("请输入有效区域 ID");
|
const regionIdSchema = z.coerce.number().int().positive("请输入有效区域 ID");
|
||||||
const sortOrderSchema = z.coerce.number().int().min(0, "排序不能小于 0").default(0);
|
const sortOrderSchema = z.coerce.number().int().min(0, "排序不能小于 0").default(0);
|
||||||
|
|||||||
@ -45,7 +45,7 @@ export interface InviteActivityRewardConfigPayload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface InviteActivityRewardClaimUserDto {
|
export interface InviteActivityRewardClaimUserDto {
|
||||||
userId?: number;
|
userId?: string;
|
||||||
displayUserId?: string;
|
displayUserId?: string;
|
||||||
username?: string;
|
username?: string;
|
||||||
avatar?: string;
|
avatar?: string;
|
||||||
@ -55,7 +55,7 @@ export interface InviteActivityRewardClaimDto {
|
|||||||
claimId: string;
|
claimId: string;
|
||||||
appCode?: string;
|
appCode?: string;
|
||||||
cycleKey?: string;
|
cycleKey?: string;
|
||||||
userId: number;
|
userId: string;
|
||||||
user?: InviteActivityRewardClaimUserDto;
|
user?: InviteActivityRewardClaimUserDto;
|
||||||
rewardType?: string;
|
rewardType?: string;
|
||||||
commandId?: string;
|
commandId?: string;
|
||||||
@ -150,9 +150,9 @@ function normalizeClaim(item: RawClaim): InviteActivityRewardClaimDto {
|
|||||||
claimId: stringValue(item.claimId ?? item.claim_id),
|
claimId: stringValue(item.claimId ?? item.claim_id),
|
||||||
appCode: stringValue(item.appCode ?? item.app_code),
|
appCode: stringValue(item.appCode ?? item.app_code),
|
||||||
cycleKey: stringValue(item.cycleKey ?? item.cycle_key),
|
cycleKey: stringValue(item.cycleKey ?? item.cycle_key),
|
||||||
userId: numberValue(item.userId ?? item.user_id),
|
userId: stringValue(item.userId ?? item.user_id),
|
||||||
user: {
|
user: {
|
||||||
userId: numberValue(rawUser.userId ?? rawUser.user_id),
|
userId: stringValue(rawUser.userId ?? rawUser.user_id),
|
||||||
displayUserId: stringValue(rawUser.displayUserId ?? rawUser.display_user_id),
|
displayUserId: stringValue(rawUser.displayUserId ?? rawUser.display_user_id),
|
||||||
username: stringValue(rawUser.username),
|
username: stringValue(rawUser.username),
|
||||||
avatar: stringValue(rawUser.avatar),
|
avatar: stringValue(rawUser.avatar),
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import styles from "@/features/invite-activity-reward/invite-activity-reward.mod
|
|||||||
|
|
||||||
const rewardTypeOptions = [
|
const rewardTypeOptions = [
|
||||||
["recharge", "累计充值"],
|
["recharge", "累计充值"],
|
||||||
["valid_invite", "有效人数"],
|
["valid_invite", "Valid Users"],
|
||||||
];
|
];
|
||||||
|
|
||||||
export function InviteActivityRewardConfigDrawer({
|
export function InviteActivityRewardConfigDrawer({
|
||||||
|
|||||||
@ -25,8 +25,8 @@ export function InviteActivityRewardConfigSummary({ canUpdate, config, configLoa
|
|||||||
<SummaryItem label="累计充值档位">
|
<SummaryItem label="累计充值档位">
|
||||||
{thresholdSummary(rechargeTiers, "thresholdCoinAmount", "金币")}
|
{thresholdSummary(rechargeTiers, "thresholdCoinAmount", "金币")}
|
||||||
</SummaryItem>
|
</SummaryItem>
|
||||||
<SummaryItem label="有效人数档位">
|
<SummaryItem label="Valid Users Tiers">
|
||||||
{thresholdSummary(validInviteTiers, "thresholdValidInviteCount", "人")}
|
{thresholdSummary(validInviteTiers, "thresholdValidInviteCount", "people")}
|
||||||
</SummaryItem>
|
</SummaryItem>
|
||||||
<SummaryItem label="邀请人即时奖励">
|
<SummaryItem label="邀请人即时奖励">
|
||||||
{coinSummary(config?.perInviteInviterRewardCoinAmount)}
|
{coinSummary(config?.perInviteInviterRewardCoinAmount)}
|
||||||
|
|||||||
@ -180,17 +180,16 @@ function payloadFromForm(form) {
|
|||||||
throw new Error("累计充值金币门槛必须大于 0");
|
throw new Error("累计充值金币门槛必须大于 0");
|
||||||
}
|
}
|
||||||
if (rewardType === "valid_invite" && thresholdValidInviteCount <= 0) {
|
if (rewardType === "valid_invite" && thresholdValidInviteCount <= 0) {
|
||||||
throw new Error("有效人数门槛必须大于 0");
|
throw new Error("Valid users threshold must be greater than 0");
|
||||||
}
|
}
|
||||||
if (rewardCoinAmount <= 0) {
|
if (rewardCoinAmount <= 0) {
|
||||||
throw new Error("奖励金币必须大于 0");
|
throw new Error("奖励金币必须大于 0");
|
||||||
}
|
}
|
||||||
const tierCode = String(tier.tierCode || "").trim() || `invite_${rewardType}_${Date.now()}_${index + 1}`;
|
const tierCode = normalizeTierCode(tier.tierCode, rewardType, index);
|
||||||
const tierName =
|
const tierName =
|
||||||
String(tier.tierName || "").trim() ||
|
rewardType === "recharge"
|
||||||
(rewardType === "recharge"
|
? `Cumulative Recharge ${formatNumber(thresholdCoinAmount)} coins`
|
||||||
? `累计充值 ${formatNumber(thresholdCoinAmount)} 金币`
|
: `Valid Users ${formatNumber(thresholdValidInviteCount)} people`;
|
||||||
: `有效邀请 ${formatNumber(thresholdValidInviteCount)} 人`);
|
|
||||||
return {
|
return {
|
||||||
tier_id: Number(tier.tierId || 0),
|
tier_id: Number(tier.tierId || 0),
|
||||||
reward_type: rewardType,
|
reward_type: rewardType,
|
||||||
@ -220,5 +219,13 @@ function payloadFromForm(form) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function formatNumber(value) {
|
function formatNumber(value) {
|
||||||
return new Intl.NumberFormat("zh-CN").format(Number(value || 0));
|
return new Intl.NumberFormat("en-US").format(Number(value || 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeTierCode(value, rewardType, index) {
|
||||||
|
const code = String(value || "").trim();
|
||||||
|
if (code && !/[\u3400-\u9fff]/.test(code)) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
return `invite_${rewardType}_${Date.now()}_${index + 1}`;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const claimStatusOptions = [
|
|||||||
|
|
||||||
const rewardTypeOptions = [
|
const rewardTypeOptions = [
|
||||||
["recharge", "累计充值"],
|
["recharge", "累计充值"],
|
||||||
["valid_invite", "有效人数"],
|
["valid_invite", "Valid Users"],
|
||||||
["invite_inviter", "邀请人即时"],
|
["invite_inviter", "邀请人即时"],
|
||||||
["invite_invitee", "被邀请人即时"],
|
["invite_invitee", "被邀请人即时"],
|
||||||
];
|
];
|
||||||
@ -202,7 +202,7 @@ function claimStatusLabel(status) {
|
|||||||
|
|
||||||
function thresholdLabel(claim) {
|
function thresholdLabel(claim) {
|
||||||
if (claim.rewardType === "valid_invite") {
|
if (claim.rewardType === "valid_invite") {
|
||||||
return `${formatNumber(claim.thresholdValidInviteCount)} 人`;
|
return `${formatNumber(claim.thresholdValidInviteCount)} people`;
|
||||||
}
|
}
|
||||||
if (claim.rewardType === "invite_inviter" || claim.rewardType === "invite_invitee") {
|
if (claim.rewardType === "invite_inviter" || claim.rewardType === "invite_invitee") {
|
||||||
return claim.tierId ? `关联用户 ${claim.tierId}` : "-";
|
return claim.tierId ? `关联用户 ${claim.tierId}` : "-";
|
||||||
@ -214,7 +214,7 @@ function reachedLabel(claim) {
|
|||||||
if (claim.rewardType === "invite_inviter" || claim.rewardType === "invite_invitee") {
|
if (claim.rewardType === "invite_inviter" || claim.rewardType === "invite_invitee") {
|
||||||
return "1 人";
|
return "1 人";
|
||||||
}
|
}
|
||||||
const unit = claim.rewardType === "valid_invite" ? "人" : "金币";
|
const unit = claim.rewardType === "valid_invite" ? "people" : "金币";
|
||||||
return `${formatNumber(claim.reachedValue)} ${unit}`;
|
return `${formatNumber(claim.reachedValue)} ${unit}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -30,7 +30,7 @@ export interface RedPacketClaimDto {
|
|||||||
claimId: string;
|
claimId: string;
|
||||||
commandId?: string;
|
commandId?: string;
|
||||||
packetId: string;
|
packetId: string;
|
||||||
userId: number;
|
userId: string;
|
||||||
amount: number;
|
amount: number;
|
||||||
walletTransactionId?: string;
|
walletTransactionId?: string;
|
||||||
status?: string;
|
status?: string;
|
||||||
@ -43,7 +43,7 @@ export interface RedPacketDto {
|
|||||||
appCode?: string;
|
appCode?: string;
|
||||||
packetId: string;
|
packetId: string;
|
||||||
commandId?: string;
|
commandId?: string;
|
||||||
senderUserId: number;
|
senderUserId: string;
|
||||||
roomId: string;
|
roomId: string;
|
||||||
regionId: number;
|
regionId: number;
|
||||||
packetType: string;
|
packetType: string;
|
||||||
@ -139,7 +139,7 @@ function normalizePacket(item: RawPacket): RedPacketDto {
|
|||||||
appCode: stringValue(item.appCode ?? item.app_code),
|
appCode: stringValue(item.appCode ?? item.app_code),
|
||||||
packetId: stringValue(item.packetId ?? item.packet_id),
|
packetId: stringValue(item.packetId ?? item.packet_id),
|
||||||
commandId: stringValue(item.commandId ?? item.command_id),
|
commandId: stringValue(item.commandId ?? item.command_id),
|
||||||
senderUserId: numberValue(item.senderUserId ?? item.sender_user_id),
|
senderUserId: stringValue(item.senderUserId ?? item.sender_user_id),
|
||||||
roomId: stringValue(item.roomId ?? item.room_id),
|
roomId: stringValue(item.roomId ?? item.room_id),
|
||||||
regionId: numberValue(item.regionId ?? item.region_id),
|
regionId: numberValue(item.regionId ?? item.region_id),
|
||||||
packetType: stringValue(item.packetType ?? item.packet_type),
|
packetType: stringValue(item.packetType ?? item.packet_type),
|
||||||
@ -164,7 +164,7 @@ function normalizeClaim(item: RawClaim): RedPacketClaimDto {
|
|||||||
claimId: stringValue(item.claimId ?? item.claim_id),
|
claimId: stringValue(item.claimId ?? item.claim_id),
|
||||||
commandId: stringValue(item.commandId ?? item.command_id),
|
commandId: stringValue(item.commandId ?? item.command_id),
|
||||||
packetId: stringValue(item.packetId ?? item.packet_id),
|
packetId: stringValue(item.packetId ?? item.packet_id),
|
||||||
userId: numberValue(item.userId ?? item.user_id),
|
userId: stringValue(item.userId ?? item.user_id),
|
||||||
amount: numberValue(item.amount),
|
amount: numberValue(item.amount),
|
||||||
walletTransactionId: stringValue(item.walletTransactionId ?? item.wallet_transaction_id),
|
walletTransactionId: stringValue(item.walletTransactionId ?? item.wallet_transaction_id),
|
||||||
status: stringValue(item.status),
|
status: stringValue(item.status),
|
||||||
|
|||||||
@ -23,7 +23,7 @@ export interface RegistrationRewardConfigPayload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface RegistrationRewardClaimUserDto {
|
export interface RegistrationRewardClaimUserDto {
|
||||||
userId?: number;
|
userId?: string;
|
||||||
displayUserId?: string;
|
displayUserId?: string;
|
||||||
prettyDisplayUserId?: string;
|
prettyDisplayUserId?: string;
|
||||||
prettyId?: string;
|
prettyId?: string;
|
||||||
@ -34,7 +34,7 @@ export interface RegistrationRewardClaimUserDto {
|
|||||||
export interface RegistrationRewardClaimDto {
|
export interface RegistrationRewardClaimDto {
|
||||||
claimId: string;
|
claimId: string;
|
||||||
commandId?: string;
|
commandId?: string;
|
||||||
userId: number;
|
userId: string;
|
||||||
user?: RegistrationRewardClaimUserDto;
|
user?: RegistrationRewardClaimUserDto;
|
||||||
rewardDay?: string;
|
rewardDay?: string;
|
||||||
rewardType?: string;
|
rewardType?: string;
|
||||||
@ -109,9 +109,9 @@ function normalizeClaim(item: RawClaim): RegistrationRewardClaimDto {
|
|||||||
return {
|
return {
|
||||||
claimId: stringValue(item.claimId ?? item.claim_id),
|
claimId: stringValue(item.claimId ?? item.claim_id),
|
||||||
commandId: stringValue(item.commandId ?? item.command_id),
|
commandId: stringValue(item.commandId ?? item.command_id),
|
||||||
userId: numberValue(item.userId ?? item.user_id),
|
userId: stringValue(item.userId ?? item.user_id),
|
||||||
user: {
|
user: {
|
||||||
userId: numberValue(rawUser.userId ?? rawUser.user_id),
|
userId: stringValue(rawUser.userId ?? rawUser.user_id),
|
||||||
displayUserId: stringValue(rawUser.displayUserId ?? rawUser.display_user_id),
|
displayUserId: stringValue(rawUser.displayUserId ?? rawUser.display_user_id),
|
||||||
prettyDisplayUserId: stringValue(rawUser.prettyDisplayUserId ?? rawUser.pretty_display_user_id),
|
prettyDisplayUserId: stringValue(rawUser.prettyDisplayUserId ?? rawUser.pretty_display_user_id),
|
||||||
prettyId: stringValue(rawUser.prettyId ?? rawUser.pretty_id),
|
prettyId: stringValue(rawUser.prettyId ?? rawUser.pretty_id),
|
||||||
|
|||||||
@ -166,7 +166,7 @@ test("resource APIs use generated admin paths", async () => {
|
|||||||
commandId: "resource-group-grant-test",
|
commandId: "resource-group-grant-test",
|
||||||
groupId: 22,
|
groupId: 22,
|
||||||
reason: "manual",
|
reason: "manual",
|
||||||
targetUserId: 1001,
|
targetUserId: "1001",
|
||||||
});
|
});
|
||||||
|
|
||||||
const [listUrl, listInit] = vi.mocked(fetch).mock.calls[0];
|
const [listUrl, listInit] = vi.mocked(fetch).mock.calls[0];
|
||||||
@ -258,7 +258,7 @@ test("resource APIs use generated admin paths", async () => {
|
|||||||
});
|
});
|
||||||
expect(String(grantGroupUrl)).toContain("/api/v1/admin/resource-grants/group");
|
expect(String(grantGroupUrl)).toContain("/api/v1/admin/resource-grants/group");
|
||||||
expect(grantGroupInit?.method).toBe("POST");
|
expect(grantGroupInit?.method).toBe("POST");
|
||||||
expect(JSON.parse(String(grantGroupInit?.body))).toMatchObject({ groupId: 22, targetUserId: 1001 });
|
expect(JSON.parse(String(grantGroupInit?.body))).toMatchObject({ groupId: 22, targetUserId: "1001" });
|
||||||
});
|
});
|
||||||
|
|
||||||
test("resource mp4 layout batch API uses narrow update endpoint", async () => {
|
test("resource mp4 layout batch API uses narrow update endpoint", async () => {
|
||||||
|
|||||||
@ -209,7 +209,7 @@ export interface ResourceGrantOperatorDto {
|
|||||||
prettyId?: string;
|
prettyId?: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
source?: string;
|
source?: string;
|
||||||
userId?: number | string;
|
userId?: string;
|
||||||
username?: string;
|
username?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,7 +218,7 @@ export interface ResourceGrantUserDto {
|
|||||||
displayUserId?: string;
|
displayUserId?: string;
|
||||||
prettyDisplayUserId?: string;
|
prettyDisplayUserId?: string;
|
||||||
prettyId?: string;
|
prettyId?: string;
|
||||||
userId?: number | string;
|
userId?: string;
|
||||||
username?: string;
|
username?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,7 +236,7 @@ export interface ResourceGrantDto {
|
|||||||
reason?: string;
|
reason?: string;
|
||||||
status?: string;
|
status?: string;
|
||||||
targetUser?: ResourceGrantUserDto;
|
targetUser?: ResourceGrantUserDto;
|
||||||
targetUserId?: number | string;
|
targetUserId?: string;
|
||||||
updatedAtMs?: number;
|
updatedAtMs?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,14 +246,14 @@ export interface GrantResourcePayload {
|
|||||||
quantity: number;
|
quantity: number;
|
||||||
reason: string;
|
reason: string;
|
||||||
resourceId: number;
|
resourceId: number;
|
||||||
targetUserId: number | string;
|
targetUserId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GrantResourceGroupPayload {
|
export interface GrantResourceGroupPayload {
|
||||||
commandId: string;
|
commandId: string;
|
||||||
groupId: number;
|
groupId: number;
|
||||||
reason: string;
|
reason: string;
|
||||||
targetUserId: number | string;
|
targetUserId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ResourceGroupItemPayload {
|
export interface ResourceGroupItemPayload {
|
||||||
|
|||||||
@ -389,13 +389,13 @@ export const resourceGrantFormSchema = z
|
|||||||
targetUserId: z.union([z.string(), z.number()]),
|
targetUserId: z.union([z.string(), z.number()]),
|
||||||
})
|
})
|
||||||
.superRefine((value, context) => {
|
.superRefine((value, context) => {
|
||||||
const targetUserId = Number(value.targetUserId);
|
const targetUserId = String(value.targetUserId || "").trim();
|
||||||
const resourceIds = grantResourceIds(value);
|
const resourceIds = grantResourceIds(value);
|
||||||
const groupId = Number(value.groupId || 0);
|
const groupId = Number(value.groupId || 0);
|
||||||
const quantity = Number(value.quantity || 1);
|
const quantity = Number(value.quantity || 1);
|
||||||
const durationDays = Number(value.durationDays || 0);
|
const durationDays = Number(value.durationDays || 0);
|
||||||
|
|
||||||
if (!Number.isInteger(targetUserId) || targetUserId <= 0) {
|
if (!/^[1-9]\d*$/.test(targetUserId)) {
|
||||||
context.addIssue({
|
context.addIssue({
|
||||||
code: "custom",
|
code: "custom",
|
||||||
message: "请输入用户 ID",
|
message: "请输入用户 ID",
|
||||||
|
|||||||
@ -39,7 +39,7 @@ export interface RoomTurnoverRewardConfigPayload {
|
|||||||
export interface RoomTurnoverRewardSettlementDto {
|
export interface RoomTurnoverRewardSettlementDto {
|
||||||
settlementId: string;
|
settlementId: string;
|
||||||
roomId: string;
|
roomId: string;
|
||||||
ownerUserId: number;
|
ownerUserId: string;
|
||||||
periodStartMs: number;
|
periodStartMs: number;
|
||||||
periodEndMs: number;
|
periodEndMs: number;
|
||||||
coinSpent: number;
|
coinSpent: number;
|
||||||
@ -140,7 +140,7 @@ function normalizeSettlement(item: RawSettlement): RoomTurnoverRewardSettlementD
|
|||||||
return {
|
return {
|
||||||
settlementId: stringValue(item.settlementId ?? item.settlement_id),
|
settlementId: stringValue(item.settlementId ?? item.settlement_id),
|
||||||
roomId: stringValue(item.roomId ?? item.room_id),
|
roomId: stringValue(item.roomId ?? item.room_id),
|
||||||
ownerUserId: numberValue(item.ownerUserId ?? item.owner_user_id),
|
ownerUserId: stringValue(item.ownerUserId ?? item.owner_user_id),
|
||||||
periodStartMs: numberValue(item.periodStartMs ?? item.period_start_ms),
|
periodStartMs: numberValue(item.periodStartMs ?? item.period_start_ms),
|
||||||
periodEndMs: numberValue(item.periodEndMs ?? item.period_end_ms),
|
periodEndMs: numberValue(item.periodEndMs ?? item.period_end_ms),
|
||||||
coinSpent: numberValue(item.coinSpent ?? item.coin_spent),
|
coinSpent: numberValue(item.coinSpent ?? item.coin_spent),
|
||||||
|
|||||||
@ -26,7 +26,7 @@ export interface SevenDayCheckInConfigPayload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface SevenDayCheckInClaimUserDto {
|
export interface SevenDayCheckInClaimUserDto {
|
||||||
userId?: number;
|
userId?: string;
|
||||||
displayUserId?: string;
|
displayUserId?: string;
|
||||||
prettyDisplayUserId?: string;
|
prettyDisplayUserId?: string;
|
||||||
prettyId?: string;
|
prettyId?: string;
|
||||||
@ -37,7 +37,7 @@ export interface SevenDayCheckInClaimUserDto {
|
|||||||
export interface SevenDayCheckInClaimDto {
|
export interface SevenDayCheckInClaimDto {
|
||||||
claimId: string;
|
claimId: string;
|
||||||
commandId?: string;
|
commandId?: string;
|
||||||
userId: number;
|
userId: string;
|
||||||
user?: SevenDayCheckInClaimUserDto;
|
user?: SevenDayCheckInClaimUserDto;
|
||||||
cycleNo: number;
|
cycleNo: number;
|
||||||
checkinDay?: string;
|
checkinDay?: string;
|
||||||
@ -121,9 +121,9 @@ function normalizeClaim(item: RawClaim): SevenDayCheckInClaimDto {
|
|||||||
return {
|
return {
|
||||||
claimId: stringValue(item.claimId ?? item.claim_id),
|
claimId: stringValue(item.claimId ?? item.claim_id),
|
||||||
commandId: stringValue(item.commandId ?? item.command_id),
|
commandId: stringValue(item.commandId ?? item.command_id),
|
||||||
userId: numberValue(item.userId ?? item.user_id),
|
userId: stringValue(item.userId ?? item.user_id),
|
||||||
user: {
|
user: {
|
||||||
userId: numberValue(rawUser.userId ?? rawUser.user_id),
|
userId: stringValue(rawUser.userId ?? rawUser.user_id),
|
||||||
displayUserId: stringValue(rawUser.displayUserId ?? rawUser.display_user_id),
|
displayUserId: stringValue(rawUser.displayUserId ?? rawUser.display_user_id),
|
||||||
prettyDisplayUserId: stringValue(rawUser.prettyDisplayUserId ?? rawUser.pretty_display_user_id),
|
prettyDisplayUserId: stringValue(rawUser.prettyDisplayUserId ?? rawUser.pretty_display_user_id),
|
||||||
prettyId: stringValue(rawUser.prettyId ?? rawUser.pretty_id),
|
prettyId: stringValue(rawUser.prettyId ?? rawUser.pretty_id),
|
||||||
|
|||||||
@ -41,7 +41,7 @@ export interface WeeklyStarCyclePayload {
|
|||||||
|
|
||||||
export interface WeeklyStarEntryDto {
|
export interface WeeklyStarEntryDto {
|
||||||
rankNo: number;
|
rankNo: number;
|
||||||
userId: number;
|
userId: string;
|
||||||
score: number;
|
score: number;
|
||||||
firstScoredAtMs: number;
|
firstScoredAtMs: number;
|
||||||
lastScoredAtMs: number;
|
lastScoredAtMs: number;
|
||||||
@ -51,7 +51,7 @@ export interface WeeklyStarSettlementDto {
|
|||||||
settlementId: string;
|
settlementId: string;
|
||||||
cycleId: string;
|
cycleId: string;
|
||||||
rankNo: number;
|
rankNo: number;
|
||||||
userId: number;
|
userId: string;
|
||||||
score: number;
|
score: number;
|
||||||
resourceGroupId: number;
|
resourceGroupId: number;
|
||||||
walletCommandId: string;
|
walletCommandId: string;
|
||||||
@ -161,7 +161,7 @@ function normalizeReward(item: Raw): WeeklyStarRewardDto {
|
|||||||
function normalizeEntry(item: Raw): WeeklyStarEntryDto {
|
function normalizeEntry(item: Raw): WeeklyStarEntryDto {
|
||||||
return {
|
return {
|
||||||
rankNo: numberValue(item.rankNo ?? item.rank_no),
|
rankNo: numberValue(item.rankNo ?? item.rank_no),
|
||||||
userId: numberValue(item.userId ?? item.user_id),
|
userId: stringValue(item.userId ?? item.user_id),
|
||||||
score: numberValue(item.score),
|
score: numberValue(item.score),
|
||||||
firstScoredAtMs: numberValue(item.firstScoredAtMs ?? item.first_scored_at_ms),
|
firstScoredAtMs: numberValue(item.firstScoredAtMs ?? item.first_scored_at_ms),
|
||||||
lastScoredAtMs: numberValue(item.lastScoredAtMs ?? item.last_scored_at_ms),
|
lastScoredAtMs: numberValue(item.lastScoredAtMs ?? item.last_scored_at_ms),
|
||||||
@ -173,7 +173,7 @@ function normalizeSettlement(item: Raw): WeeklyStarSettlementDto {
|
|||||||
settlementId: stringValue(item.settlementId ?? item.settlement_id),
|
settlementId: stringValue(item.settlementId ?? item.settlement_id),
|
||||||
cycleId: stringValue(item.cycleId ?? item.cycle_id),
|
cycleId: stringValue(item.cycleId ?? item.cycle_id),
|
||||||
rankNo: numberValue(item.rankNo ?? item.rank_no),
|
rankNo: numberValue(item.rankNo ?? item.rank_no),
|
||||||
userId: numberValue(item.userId ?? item.user_id),
|
userId: stringValue(item.userId ?? item.user_id),
|
||||||
score: numberValue(item.score),
|
score: numberValue(item.score),
|
||||||
resourceGroupId: numberValue(item.resourceGroupId ?? item.resource_group_id),
|
resourceGroupId: numberValue(item.resourceGroupId ?? item.resource_group_id),
|
||||||
walletCommandId: stringValue(item.walletCommandId ?? item.wallet_command_id),
|
walletCommandId: stringValue(item.walletCommandId ?? item.wallet_command_id),
|
||||||
|
|||||||
10
src/shared/api/generated/schema.d.ts
vendored
10
src/shared/api/generated/schema.d.ts
vendored
@ -3021,8 +3021,8 @@ export interface components {
|
|||||||
joinEnabled?: boolean;
|
joinEnabled?: boolean;
|
||||||
maxHosts?: number;
|
maxHosts?: number;
|
||||||
name?: string;
|
name?: string;
|
||||||
ownerUserId?: number;
|
ownerUserId?: string;
|
||||||
parentBdUserId?: number;
|
parentBdUserId?: string;
|
||||||
regionId?: number;
|
regionId?: number;
|
||||||
status?: string;
|
status?: string;
|
||||||
updatedAtMs?: number;
|
updatedAtMs?: number;
|
||||||
@ -3030,12 +3030,12 @@ export interface components {
|
|||||||
BDProfile: {
|
BDProfile: {
|
||||||
createdAtMs?: number;
|
createdAtMs?: number;
|
||||||
createdByUserId?: number;
|
createdByUserId?: number;
|
||||||
parentLeaderUserId?: number;
|
parentLeaderUserId?: string;
|
||||||
regionId?: number;
|
regionId?: number;
|
||||||
role?: string;
|
role?: string;
|
||||||
status?: string;
|
status?: string;
|
||||||
updatedAtMs?: number;
|
updatedAtMs?: number;
|
||||||
userId: number;
|
userId: string;
|
||||||
};
|
};
|
||||||
CreateUserResult: {
|
CreateUserResult: {
|
||||||
initialPassword?: string;
|
initialPassword?: string;
|
||||||
@ -3057,7 +3057,7 @@ export interface components {
|
|||||||
source?: string;
|
source?: string;
|
||||||
status?: string;
|
status?: string;
|
||||||
updatedAtMs?: number;
|
updatedAtMs?: number;
|
||||||
userId: number;
|
userId: string;
|
||||||
};
|
};
|
||||||
Log: {
|
Log: {
|
||||||
[key: string]: unknown;
|
[key: string]: unknown;
|
||||||
|
|||||||
@ -324,13 +324,13 @@ export interface RechargeBillDto {
|
|||||||
policyVersion?: string;
|
policyVersion?: string;
|
||||||
rechargeType?: string;
|
rechargeType?: string;
|
||||||
sellerRegionId?: number;
|
sellerRegionId?: number;
|
||||||
sellerUserId?: number;
|
sellerUserId?: string;
|
||||||
status?: string;
|
status?: string;
|
||||||
targetRegionId?: number;
|
targetRegionId?: number;
|
||||||
transactionId: string;
|
transactionId: string;
|
||||||
usdMinorAmount: number;
|
usdMinorAmount: number;
|
||||||
user?: RechargeBillUserDto;
|
user?: RechargeBillUserDto;
|
||||||
userId: number;
|
userId: string;
|
||||||
seller?: RechargeBillUserDto;
|
seller?: RechargeBillUserDto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -441,7 +441,7 @@ export interface BDProfileDto {
|
|||||||
displayUserId?: string;
|
displayUserId?: string;
|
||||||
prettyDisplayUserId?: string;
|
prettyDisplayUserId?: string;
|
||||||
prettyId?: string;
|
prettyId?: string;
|
||||||
parentLeaderUserId?: number;
|
parentLeaderUserId?: string;
|
||||||
parentLeaderDisplayUserId?: string;
|
parentLeaderDisplayUserId?: string;
|
||||||
parentLeaderUsername?: string;
|
parentLeaderUsername?: string;
|
||||||
parentLeaderAvatar?: string;
|
parentLeaderAvatar?: string;
|
||||||
@ -452,7 +452,7 @@ export interface BDProfileDto {
|
|||||||
status?: string;
|
status?: string;
|
||||||
subBdCount?: number;
|
subBdCount?: number;
|
||||||
updatedAtMs?: number;
|
updatedAtMs?: number;
|
||||||
userId: number;
|
userId: string;
|
||||||
username?: string;
|
username?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,11 +466,11 @@ export interface AgencyDto {
|
|||||||
ownerAvatar?: string;
|
ownerAvatar?: string;
|
||||||
ownerDisplayUserId?: string;
|
ownerDisplayUserId?: string;
|
||||||
ownerUsername?: string;
|
ownerUsername?: string;
|
||||||
ownerUserId?: number;
|
ownerUserId?: string;
|
||||||
parentBdAvatar?: string;
|
parentBdAvatar?: string;
|
||||||
parentBdDisplayUserId?: string;
|
parentBdDisplayUserId?: string;
|
||||||
parentBdUsername?: string;
|
parentBdUsername?: string;
|
||||||
parentBdUserId?: number;
|
parentBdUserId?: string;
|
||||||
regionId?: number;
|
regionId?: number;
|
||||||
regionName?: string;
|
regionName?: string;
|
||||||
status?: string;
|
status?: string;
|
||||||
@ -484,7 +484,7 @@ export interface HostProfileDto {
|
|||||||
currentAgencyName?: string;
|
currentAgencyName?: string;
|
||||||
currentAgencyOwnerAvatar?: string;
|
currentAgencyOwnerAvatar?: string;
|
||||||
currentAgencyOwnerDisplayUserId?: string;
|
currentAgencyOwnerDisplayUserId?: string;
|
||||||
currentAgencyOwnerUserId?: number;
|
currentAgencyOwnerUserId?: string;
|
||||||
currentAgencyOwnerUsername?: string;
|
currentAgencyOwnerUsername?: string;
|
||||||
currentMembershipId?: number;
|
currentMembershipId?: number;
|
||||||
diamond?: number;
|
diamond?: number;
|
||||||
@ -497,7 +497,7 @@ export interface HostProfileDto {
|
|||||||
source?: string;
|
source?: string;
|
||||||
status?: string;
|
status?: string;
|
||||||
updatedAtMs?: number;
|
updatedAtMs?: number;
|
||||||
userId: number;
|
userId: string;
|
||||||
username?: string;
|
username?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -516,7 +516,7 @@ export interface CoinSellerDto {
|
|||||||
status?: string;
|
status?: string;
|
||||||
totalRechargeUsdtMicro?: number;
|
totalRechargeUsdtMicro?: number;
|
||||||
updatedAtMs?: number;
|
updatedAtMs?: number;
|
||||||
userId: number;
|
userId: string;
|
||||||
username?: string;
|
username?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1038,7 +1038,7 @@ export interface HostCommandPayload {
|
|||||||
|
|
||||||
export interface CreateBDLeaderPayload extends HostCommandPayload {
|
export interface CreateBDLeaderPayload extends HostCommandPayload {
|
||||||
positionAlias?: string;
|
positionAlias?: string;
|
||||||
targetUserId: number;
|
targetUserId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BDLeaderPositionAliasPayload extends HostCommandPayload {
|
export interface BDLeaderPositionAliasPayload extends HostCommandPayload {
|
||||||
@ -1046,8 +1046,8 @@ export interface BDLeaderPositionAliasPayload extends HostCommandPayload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface CreateBDPayload extends HostCommandPayload {
|
export interface CreateBDPayload extends HostCommandPayload {
|
||||||
parentLeaderUserId: number;
|
parentLeaderUserId: string;
|
||||||
targetUserId: number;
|
targetUserId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BDStatusPayload extends HostCommandPayload {
|
export interface BDStatusPayload extends HostCommandPayload {
|
||||||
@ -1056,7 +1056,7 @@ export interface BDStatusPayload extends HostCommandPayload {
|
|||||||
|
|
||||||
export interface CreateCoinSellerPayload extends HostCommandPayload {
|
export interface CreateCoinSellerPayload extends HostCommandPayload {
|
||||||
contact?: string;
|
contact?: string;
|
||||||
targetUserId: number;
|
targetUserId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CoinSellerStatusPayload extends BDStatusPayload {
|
export interface CoinSellerStatusPayload extends BDStatusPayload {
|
||||||
@ -1066,8 +1066,8 @@ export interface CoinSellerStatusPayload extends BDStatusPayload {
|
|||||||
export interface CreateAgencyPayload extends HostCommandPayload {
|
export interface CreateAgencyPayload extends HostCommandPayload {
|
||||||
joinEnabled: boolean;
|
joinEnabled: boolean;
|
||||||
name: string;
|
name: string;
|
||||||
ownerUserId: number;
|
ownerUserId: string;
|
||||||
parentBdUserId: number;
|
parentBdUserId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AgencyJoinEnabledPayload extends HostCommandPayload {
|
export interface AgencyJoinEnabledPayload extends HostCommandPayload {
|
||||||
|
|||||||
@ -1,10 +1,15 @@
|
|||||||
import InputBase from "@mui/material/InputBase";
|
import InputBase from "@mui/material/InputBase";
|
||||||
import Search from "@mui/icons-material/Search";
|
import Search from "@mui/icons-material/Search";
|
||||||
|
|
||||||
export function SearchBox({ autoFocus = false, className = "", onChange, placeholder, value }) {
|
export function SearchBox({ autoFocus = false, className = "", label = "搜索", onChange, placeholder, value }) {
|
||||||
|
const hasValue = value !== undefined && value !== null && String(value).length > 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<label className={["search-box", className].filter(Boolean).join(" ")}>
|
<label className={["search-box", hasValue ? "search-box--active" : "", className].filter(Boolean).join(" ")}>
|
||||||
<Search fontSize="small" />
|
<span className="search-box__label">
|
||||||
|
<Search fontSize="inherit" />
|
||||||
|
<span>{label}</span>
|
||||||
|
</span>
|
||||||
<InputBase
|
<InputBase
|
||||||
autoFocus={autoFocus}
|
autoFocus={autoFocus}
|
||||||
value={value}
|
value={value}
|
||||||
|
|||||||
@ -28,6 +28,7 @@ export function TimeRangeFilter({ className = "", disabled = false, label = "时
|
|||||||
const open = Boolean(anchorEl);
|
const open = Boolean(anchorEl);
|
||||||
const days = useMemo(() => calendarDays(viewDate), [viewDate]);
|
const days = useMemo(() => calendarDays(viewDate), [viewDate]);
|
||||||
const selectedDate = dateForField(draft, activeField, viewDate);
|
const selectedDate = dateForField(draft, activeField, viewDate);
|
||||||
|
const hasRange = Boolean(range.startMs || range.endMs);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!open) {
|
if (!open) {
|
||||||
@ -110,14 +111,17 @@ export function TimeRangeFilter({ className = "", disabled = false, label = "时
|
|||||||
<>
|
<>
|
||||||
<Button
|
<Button
|
||||||
className={[styles.trigger, className].filter(Boolean).join(" ")}
|
className={[styles.trigger, className].filter(Boolean).join(" ")}
|
||||||
endIcon={<KeyboardArrowDownOutlined fontSize="small" />}
|
|
||||||
startIcon={<AccessTimeOutlined fontSize="small" />}
|
|
||||||
aria-expanded={open}
|
aria-expanded={open}
|
||||||
aria-haspopup="dialog"
|
aria-haspopup="dialog"
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onClick={openPopover}
|
onClick={openPopover}
|
||||||
>
|
>
|
||||||
<span className={styles.triggerText}>{displayLabel}</span>
|
<span className={styles.triggerMeta}>
|
||||||
|
<AccessTimeOutlined fontSize="inherit" />
|
||||||
|
<span>{label}</span>
|
||||||
|
</span>
|
||||||
|
<span className={styles.triggerText}>{hasRange ? displayLabel : "不限"}</span>
|
||||||
|
<KeyboardArrowDownOutlined className={styles.triggerChevron} fontSize="small" />
|
||||||
</Button>
|
</Button>
|
||||||
<Popover
|
<Popover
|
||||||
anchorEl={anchorEl}
|
anchorEl={anchorEl}
|
||||||
|
|||||||
@ -1,9 +1,15 @@
|
|||||||
.trigger {
|
.trigger {
|
||||||
|
position: relative;
|
||||||
|
display: inline-grid !important;
|
||||||
|
grid-template-columns: minmax(0, 1fr) 18px;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
justify-content: flex-start !important;
|
align-items: end !important;
|
||||||
|
justify-content: stretch !important;
|
||||||
|
gap: 0 !important;
|
||||||
width: auto;
|
width: auto;
|
||||||
min-width: 132px !important;
|
min-width: 132px !important;
|
||||||
max-width: min(420px, 100%);
|
max-width: min(420px, 100%);
|
||||||
|
padding: 7px 28px 3px var(--control-padding-x) !important;
|
||||||
border-color: var(--border) !important;
|
border-color: var(--border) !important;
|
||||||
background: var(--bg-input-strong) !important;
|
background: var(--bg-input-strong) !important;
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
@ -21,24 +27,50 @@
|
|||||||
transform: none !important;
|
transform: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.trigger :global(.MuiButton-startIcon) {
|
.triggerMeta {
|
||||||
margin-right: var(--space-2);
|
position: absolute;
|
||||||
margin-left: 0;
|
top: -7px;
|
||||||
|
left: var(--space-2);
|
||||||
|
display: inline-flex;
|
||||||
|
max-width: calc(100% - var(--space-4));
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0 var(--space-1);
|
||||||
|
border-radius: 4px;
|
||||||
|
background: var(--bg-card);
|
||||||
|
color: var(--text-tertiary);
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 650;
|
||||||
|
line-height: 14px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.trigger :global(.MuiButton-endIcon) {
|
.trigger:hover .triggerMeta,
|
||||||
margin-right: 0;
|
.trigger:focus-visible .triggerMeta {
|
||||||
margin-left: var(--space-4);
|
color: var(--primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.triggerText {
|
.triggerText {
|
||||||
flex: 0 1 auto;
|
flex: 0 1 auto;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-size: var(--control-font-size);
|
||||||
|
line-height: var(--control-line-height);
|
||||||
text-align: left;
|
text-align: left;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.triggerChevron {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
right: var(--space-2);
|
||||||
|
color: var(--text-tertiary);
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
.paper {
|
.paper {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
|
|||||||
@ -1,16 +1,17 @@
|
|||||||
import MenuItem from "@mui/material/MenuItem";
|
import MenuItem from "@mui/material/MenuItem";
|
||||||
import Select from "@mui/material/Select";
|
import TextField from "@mui/material/TextField";
|
||||||
|
|
||||||
const ranges = ["近 1 小时", "近 24 小时", "近 7 天"];
|
const ranges = ["近 1 小时", "近 24 小时", "近 7 天"];
|
||||||
|
|
||||||
export function TimeRangeSelect({ className = "", onChange, value }) {
|
export function TimeRangeSelect({ className = "", label = "时间", onChange, value }) {
|
||||||
return (
|
return (
|
||||||
<Select
|
<TextField
|
||||||
className={["time-select", className].filter(Boolean).join(" ")}
|
className={["time-select", className].filter(Boolean).join(" ")}
|
||||||
|
label={label}
|
||||||
|
select
|
||||||
value={value}
|
value={value}
|
||||||
onChange={(event) => onChange(event.target.value)}
|
onChange={(event) => onChange(event.target.value)}
|
||||||
size="small"
|
size="small"
|
||||||
sx={{ width: 116, height: 36, fontSize: "var(--admin-font-size)" }}
|
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
>
|
>
|
||||||
{ranges.map((range) => (
|
{ranges.map((range) => (
|
||||||
@ -18,6 +19,6 @@ export function TimeRangeSelect({ className = "", onChange, value }) {
|
|||||||
{range}
|
{range}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</TextField>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -165,11 +165,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.app-switch {
|
.app-switch {
|
||||||
flex: 0 0 156px;
|
flex: 0 0 164px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.timezone-switch {
|
.timezone-switch {
|
||||||
flex: 0 0 124px;
|
flex: 0 0 140px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-switch .MuiOutlinedInput-root,
|
.app-switch .MuiOutlinedInput-root,
|
||||||
@ -202,14 +202,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.search-box {
|
.search-box {
|
||||||
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1 1 420px;
|
flex: 1 1 420px;
|
||||||
min-width: 180px;
|
min-width: 180px;
|
||||||
max-width: 520px;
|
max-width: 520px;
|
||||||
height: var(--control-height);
|
height: var(--control-height);
|
||||||
align-items: center;
|
align-items: flex-end;
|
||||||
gap: var(--space-3);
|
gap: 0;
|
||||||
padding: 0 var(--space-3);
|
padding: 7px var(--control-padding-x) 3px;
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: var(--radius-control);
|
border-radius: var(--radius-control);
|
||||||
background: var(--bg-input);
|
background: var(--bg-input);
|
||||||
@ -222,31 +223,58 @@
|
|||||||
transform var(--motion-base) var(--ease-emphasized);
|
transform var(--motion-base) var(--ease-emphasized);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-box__label {
|
||||||
|
position: absolute;
|
||||||
|
top: -7px;
|
||||||
|
left: var(--space-2);
|
||||||
|
display: inline-flex;
|
||||||
|
max-width: calc(100% - var(--space-4));
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0 var(--space-1);
|
||||||
|
border-radius: 4px;
|
||||||
|
background: var(--bg-card);
|
||||||
|
color: var(--text-tertiary);
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 650;
|
||||||
|
line-height: 14px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
.search-box:focus-within {
|
.search-box:focus-within {
|
||||||
border-color: var(--primary-border-active);
|
border-color: var(--primary-border-active);
|
||||||
background: var(--bg-input-strong);
|
background: var(--bg-input-strong);
|
||||||
transform: translateY(-1px);
|
transform: translateY(-1px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-box svg {
|
.search-box__label svg {
|
||||||
|
flex: 0 0 auto;
|
||||||
transition:
|
transition:
|
||||||
color var(--motion-base) var(--ease-standard),
|
color var(--motion-base) var(--ease-standard),
|
||||||
transform var(--motion-base) var(--ease-emphasized);
|
transform var(--motion-base) var(--ease-emphasized);
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-box:focus-within svg {
|
.search-box:focus-within .search-box__label,
|
||||||
|
.search-box--active .search-box__label {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-box:focus-within .search-box__label svg {
|
||||||
color: var(--primary);
|
color: var(--primary);
|
||||||
transform: scale(1.08);
|
transform: scale(1.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-trigger {
|
.search-trigger {
|
||||||
display: flex;
|
position: relative;
|
||||||
|
display: grid;
|
||||||
width: min(360px, 34vw);
|
width: min(360px, 34vw);
|
||||||
min-width: 260px;
|
min-width: 260px;
|
||||||
height: var(--control-height);
|
height: var(--control-height);
|
||||||
align-items: center;
|
align-items: end;
|
||||||
gap: var(--space-3);
|
gap: 0;
|
||||||
padding: 0 var(--space-3);
|
padding: 7px var(--control-padding-x) 3px;
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: var(--radius-control);
|
border-radius: var(--radius-control);
|
||||||
background: var(--bg-input);
|
background: var(--bg-input);
|
||||||
@ -262,8 +290,36 @@
|
|||||||
transform var(--motion-base) var(--ease-emphasized);
|
transform var(--motion-base) var(--ease-emphasized);
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-trigger span {
|
.search-trigger__label {
|
||||||
|
position: absolute;
|
||||||
|
top: -7px;
|
||||||
|
left: var(--space-2);
|
||||||
|
display: inline-flex;
|
||||||
|
max-width: calc(100% - var(--space-4));
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
padding: 0 var(--space-1);
|
||||||
|
border-radius: 4px;
|
||||||
|
background: var(--bg-card);
|
||||||
|
color: var(--text-tertiary);
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 650;
|
||||||
|
line-height: 14px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-trigger__label svg {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-trigger__value {
|
||||||
|
overflow: hidden;
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-size: var(--control-font-size);
|
||||||
|
font-weight: 650;
|
||||||
|
line-height: var(--control-line-height);
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
@ -276,16 +332,22 @@
|
|||||||
transform: translateY(-1px);
|
transform: translateY(-1px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-trigger:hover .search-trigger__label,
|
||||||
|
.search-trigger:focus-visible .search-trigger__label {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
.search-box input {
|
.search-box input {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 20px;
|
height: var(--control-line-height);
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
border: 0;
|
border: 0;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
font-size: var(--admin-font-size);
|
font-size: var(--control-font-size);
|
||||||
line-height: 20px;
|
font-weight: 650;
|
||||||
|
line-height: var(--control-line-height);
|
||||||
outline: 0;
|
outline: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,15 +355,10 @@
|
|||||||
color: var(--text-tertiary);
|
color: var(--text-tertiary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.time-select {
|
.time-select.MuiTextField-root,
|
||||||
width: 116px;
|
.time-select.MuiFormControl-root {
|
||||||
height: var(--control-height);
|
flex: 0 0 124px;
|
||||||
border: 1px solid var(--border);
|
width: 124px;
|
||||||
border-radius: var(--radius-control);
|
|
||||||
background: var(--bg-input);
|
|
||||||
backdrop-filter: var(--glass-blur);
|
|
||||||
color: var(--text-secondary);
|
|
||||||
-webkit-backdrop-filter: var(--glass-blur);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-button {
|
.icon-button {
|
||||||
|
|||||||
@ -108,6 +108,10 @@
|
|||||||
--admin-control-height: var(--control-height);
|
--admin-control-height: var(--control-height);
|
||||||
--admin-control-font-size: var(--control-font-size);
|
--admin-control-font-size: var(--control-font-size);
|
||||||
--admin-control-line-height: var(--control-line-height);
|
--admin-control-line-height: var(--control-line-height);
|
||||||
|
--admin-floating-label-font-size: 11px;
|
||||||
|
--admin-floating-label-line-height: 14px;
|
||||||
|
--admin-floating-label-offset-x: 9px;
|
||||||
|
--admin-floating-label-offset-y: -7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.region-select.MuiTextField-root,
|
.region-select.MuiTextField-root,
|
||||||
@ -219,12 +223,19 @@
|
|||||||
color: var(--text-tertiary);
|
color: var(--text-tertiary);
|
||||||
font-size: var(--admin-control-font-size);
|
font-size: var(--admin-control-font-size);
|
||||||
line-height: var(--admin-control-line-height);
|
line-height: var(--admin-control-line-height);
|
||||||
transform: translate(12px, 6px) scale(1);
|
letter-spacing: 0;
|
||||||
|
transform: translate(var(--control-padding-x), calc((var(--admin-control-height) - var(--admin-control-line-height)) / 2)) scale(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.MuiTextField-root .MuiInputLabel-outlined.MuiInputLabel-shrink,
|
.MuiTextField-root .MuiInputLabel-outlined.MuiInputLabel-shrink,
|
||||||
.MuiFormControl-root .MuiInputLabel-outlined.MuiInputLabel-shrink {
|
.MuiFormControl-root .MuiInputLabel-outlined.MuiInputLabel-shrink {
|
||||||
transform: translate(12px, -7px) scale(0.75);
|
max-width: calc((100% - 18px) / 0.78);
|
||||||
|
padding: 0 var(--space-1);
|
||||||
|
border-radius: 4px;
|
||||||
|
background: var(--bg-card);
|
||||||
|
font-size: var(--admin-floating-label-font-size);
|
||||||
|
line-height: var(--admin-floating-label-line-height);
|
||||||
|
transform: translate(var(--admin-floating-label-offset-x), var(--admin-floating-label-offset-y)) scale(0.78);
|
||||||
}
|
}
|
||||||
|
|
||||||
.MuiTextField-root .MuiFormLabel-root.Mui-focused,
|
.MuiTextField-root .MuiFormLabel-root.Mui-focused,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user