feat: 补全皮肤站管理台用户页
Sync source to CNB / Sync Git ref (push) Skipped

- 用户列表:搜索(用户名/邮箱/UUID)、分页、封禁状态、注册时间
- 编辑用户:用户名、邮箱、QQ、密码、权限组、封禁状态
- 绑定玩家:展示 Mojang / StarLight 来源与旧内服适配标记
- Bot 管理:查看状态、修改机器人用户名、使 Token 失效、封禁/解封 Bot 创建
- 频率限制:滑块与数字输入设置丢包频率,支持保存与取消
- 管理审计:按用户或全局查看,游标分页加载更早记录
- 邀请码:按邮箱生成邀请码并复制
- 补充对应 API 与类型定义,中英文各补 39 个文案
This commit is contained in:
AxTps committed 2026-10-18 11:18:55 +08:00
1 parent 7b3a5212e6
commit fbcbb803ac
4 files changed
+1257 -243

No files matched your search

@@ -1902,3 +1902,116 @@ export function skinSiteUpdateReviewPaperAdmin(
{ method: 'PUT', body: data },
)
}
export interface SkinSiteBotInfo {
exists: boolean
username?: string | null
active: boolean
creationBanned: boolean
tokenHint?: string | null
createdAt?: number | null
updatedAt?: number | null
}
export interface SkinSiteUserFrequencyLimit {
dropPercent?: number | null
}
export type SkinSiteUserAdminAuditAction =
| 'USER_UPDATED'
| 'USER_DELETED'
| 'RATE_LIMIT_UPDATED'
| 'BOT_USERNAME_UPDATED'
| 'BOT_TOKEN_INVALIDATED'
| 'BOT_CREATION_BANNED'
| 'BOT_CREATION_UNBANNED'
export interface SkinSiteUserAdminAuditChange {
field: string
before?: string | null
after?: string | null
}
export interface SkinSiteUserAdminAuditInfo {
id: number
actorUuid: string
actorName: string
targetUuid: string
targetName: string
action: SkinSiteUserAdminAuditAction
changes: SkinSiteUserAdminAuditChange[]
createdAt: number
}
export interface SkinSiteUserAdminAuditPage {
items: SkinSiteUserAdminAuditInfo[]
nextCursor?: number | null
}
export interface SkinSiteInviteCode {
email: string
code: string
}
export function skinSiteAdminBotInfo(
userUuid: string,
): Promise<SkinSiteResponse<SkinSiteBotInfo>> {
return skinSiteRequest<SkinSiteBotInfo>('admin/users/' + encodeURIComponent(userUuid) + '/bot')
}
export function skinSiteAdminRenameBot(
userUuid: string,
username: string,
): Promise<SkinSiteResponse<SkinSiteBotInfo>> {
return skinSiteRequest<SkinSiteBotInfo>(
'admin/users/' + encodeURIComponent(userUuid) + '/bot/username',
{ method: 'POST', body: { username } },
)
}
export function skinSiteAdminInvalidateBotToken(
userUuid: string,
): Promise<SkinSiteResponse<SkinSiteBotInfo>> {
return skinSiteRequest<SkinSiteBotInfo>(
'admin/users/' + encodeURIComponent(userUuid) + '/bot/invalidate',
{ method: 'POST' },
)
}
export function skinSiteAdminSetBotCreationBanned(
userUuid: string,
banned: boolean,
): Promise<SkinSiteResponse<SkinSiteBotInfo>> {
return skinSiteRequest<SkinSiteBotInfo>(
'admin/users/' + encodeURIComponent(userUuid) + '/bot/ban',
{ method: 'POST', body: { banned } },
)
}
export function skinSiteAdminUpdateUserFrequencyLimit(
userUuid: string,
dropPercent: number | null,
): Promise<SkinSiteResponse<SkinSiteUserFrequencyLimit>> {
return skinSiteRequest<SkinSiteUserFrequencyLimit>(
'admin/users/' + encodeURIComponent(userUuid) + '/frequency-limit',
{ method: 'POST', body: { dropPercent } },
)
}
export function skinSiteAdminUserAudit(params?: {
targetUuid?: string
before?: number
}): Promise<SkinSiteResponse<SkinSiteUserAdminAuditPage>> {
const query = new URLSearchParams()
if (params?.targetUuid) query.set('targetUuid', params.targetUuid)
if (params?.before) query.set('before', String(params.before))
const suffix = query.size > 0 ? '?' + query.toString() : ''
return skinSiteRequest<SkinSiteUserAdminAuditPage>('admin/users/audit' + suffix)
}
export function skinSiteAdminInviteUser(email: string): Promise<SkinSiteResponse<SkinSiteInviteCode>> {
return skinSiteRequest<SkinSiteInviteCode>('admin/inviteCode', {
method: 'POST',
body: { email },
})
}