用户靓号白名单

This commit is contained in:
zhx 2026-06-30 10:52:45 +08:00
parent 7d08e7cfca
commit 7080538a00
5 changed files with 19 additions and 10 deletions

View File

@ -22,6 +22,7 @@ export interface IPWhitelistDto {
export interface UserWhitelistDto {
whitelistId: number;
userId: string;
displayUserId: string;
enabled: boolean;
createdAtMs: number;
updatedAtMs: number;
@ -124,6 +125,7 @@ function normalizeUserWhitelist(item: RawUserWhitelist): UserWhitelistDto {
return {
whitelistId: numberValue(item.whitelistId ?? item.whitelist_id),
userId: stringValue(item.userId ?? item.user_id),
displayUserId: stringValue(item.displayUserId ?? item.display_user_id),
enabled: Boolean(item.enabled),
createdAtMs: numberValue(item.createdAtMs ?? item.created_at_ms),
updatedAtMs: numberValue(item.updatedAtMs ?? item.updated_at_ms),

View File

@ -113,6 +113,7 @@ export function useRegionBlockPage() {
saved || {
whitelistId: `draft-user-${index}-${userID}`,
userId: userID,
displayUserId: "",
createdAtMs: 0,
enabled: true,
updatedAtMs: 0,
@ -182,7 +183,7 @@ export function useRegionBlockPage() {
setUserIDInput("");
setDirty(true);
} catch (err) {
showValidationError(err, showToast, "用户 ID 参数不正确");
showValidationError(err, showToast, "用户 ID/短 ID/靓号参数不正确");
}
};

View File

@ -105,8 +105,8 @@ export function RegionBlockPage() {
<TextField
className={styles.userInput}
disabled={!page.abilities.canUpdate || page.saving}
label="用户ID白名单"
placeholder="900025"
label="用户ID/短ID/靓号白名单"
placeholder="900025 或 VIP2026"
size="small"
value={page.userIDInput}
onChange={(event) => page.setUserIDInput(event.target.value)}
@ -144,11 +144,11 @@ export function RegionBlockPage() {
/>
</div>
<div className={styles.tableGroup}>
<h2 className={styles.tableTitle}>用户ID白名单</h2>
<h2 className={styles.tableTitle}>用户ID/短ID/靓号白名单</h2>
<DataTable
columns={userWhitelistColumns}
items={page.draftWhitelistUserItems}
minWidth="720px"
minWidth="860px"
rowKey={(item) => item.whitelistId || item.userId}
/>
</div>
@ -241,10 +241,16 @@ function buildUserWhitelistColumns(page) {
return [
{
key: "userId",
label: "用户ID",
label: "内部用户ID",
width: "minmax(220px, 1fr)",
render: (item) => <KeywordCell item={{ keyword: item.userId, enabled: item.enabled }} />,
},
{
key: "displayUserId",
label: "当前短ID/靓号",
width: "minmax(180px, 0.8fr)",
render: (item) => item.displayUserId || (String(item.whitelistId || "").startsWith("draft-user-") ? "保存后解析" : "-"),
},
{
key: "updatedAtMs",
label: "更新时间",

View File

@ -21,7 +21,7 @@
}
.userInput {
flex: 0 1 220px;
flex: 0 1 280px;
}
.tableGroup {

View File

@ -16,9 +16,9 @@ export const regionBlockIPSchema = z
export const regionBlockUserIDSchema = z
.string()
.trim()
.min(1, "请输入用户 ID")
.max(20, "用户 ID 不能超过 20 位")
.regex(/^[1-9]\d*$/, "请输入正确的用户 ID");
.min(1, "请输入用户 ID/短 ID/靓号")
.max(64, "用户 ID/短 ID/靓号不能超过 64 个字符")
.refine((value) => !/\s/.test(value), "用户 ID/短 ID/靓号不能包含空白");
export const regionBlockReplaceSchema = z.object({
keywords: z.array(regionBlockKeywordSchema).max(200, "最多配置 200 个屏蔽词"),