feat: refactor agent manager, media library, and player UX
- Split admin users page into player/tier-1/tier-2 tabs with affiliation labels and context-specific create dialogs - Add media library with uploaded_files migration, list/delete unused files API, and admin nav route - Enforce player username format (alphanumeric 3-32) on frontend and backend via shared package - Improve admin dialog/panel styling; refine player parlay and match bet card kickoff display Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -119,6 +119,7 @@ export * from './betting-rules';
|
||||
export * from './locale';
|
||||
export * from './builtinPlayers';
|
||||
export * from './playerLocale';
|
||||
export * from './playerUsername';
|
||||
|
||||
export interface ApiResponse<T = unknown> {
|
||||
success: boolean;
|
||||
|
||||
19
packages/shared/src/playerUsername.ts
Normal file
19
packages/shared/src/playerUsername.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
/** 玩家用户名:仅英文字母与数字,3–32 位 */
|
||||
export const PLAYER_USERNAME_PATTERN = /^[a-zA-Z0-9]{3,32}$/;
|
||||
|
||||
export const PLAYER_USERNAME_RULE_MESSAGE =
|
||||
'玩家用户名仅可使用英文字母和数字(3–32 位),不可含中文或特殊符号';
|
||||
|
||||
export function isValidPlayerUsername(username: string): boolean {
|
||||
return PLAYER_USERNAME_PATTERN.test(username.trim());
|
||||
}
|
||||
|
||||
export function assertPlayerUsername(username: string): void {
|
||||
const trimmed = username.trim();
|
||||
if (!trimmed) {
|
||||
throw new Error('玩家用户名不能为空');
|
||||
}
|
||||
if (!isValidPlayerUsername(trimmed)) {
|
||||
throw new Error(PLAYER_USERNAME_RULE_MESSAGE);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user