feat: implement QR code scan login system with admin control
- Add scan login service with Redis-based token management - Add scan login API routes for token generation and validation - Add QRCodeLogin component for PC-side QR code display - Add EntryQRCode component for mass login scenarios - Add ScanLoginView for mobile-side login form - Add localStorage persistence for user identity - Add logout functionality to mobile client - Add auto-redirect for logged-in users - Add admin console control for QR code display on big screen - Add socket event forwarding from admin to screen display Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -34,6 +34,15 @@ export const SOCKET_EVENTS = {
|
||||
ADMIN_EMERGENCY_RESET: 'admin:emergency_reset',
|
||||
ADMIN_STATE_SYNC: 'admin:state_sync',
|
||||
ADMIN_MUSIC_CONTROL: 'admin:music_control',
|
||||
|
||||
// Scan login events
|
||||
SCAN_SUBSCRIBE: 'scan:subscribe',
|
||||
SCAN_UNSUBSCRIBE: 'scan:unsubscribe',
|
||||
SCAN_STATUS_UPDATE: 'scan:status_update',
|
||||
|
||||
// QR code display control events
|
||||
DISPLAY_SHOW_ENTRY_QR: 'display:show_entry_qr',
|
||||
DISPLAY_HIDE_QR: 'display:hide_qr',
|
||||
} as const;
|
||||
|
||||
export const SOCKET_ROOMS = {
|
||||
|
||||
@@ -3,3 +3,4 @@ export * from './socket.types';
|
||||
export * from './vote.types';
|
||||
export * from './draw.types';
|
||||
export * from './admin.types';
|
||||
export * from './scan-login.types';
|
||||
|
||||
66
packages/shared/src/types/scan-login.types.ts
Normal file
66
packages/shared/src/types/scan-login.types.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
// Scan login types
|
||||
|
||||
export type ScanLoginStatus = 'pending' | 'scanned' | 'confirmed' | 'expired';
|
||||
|
||||
export interface ScanTokenData {
|
||||
scanToken: string;
|
||||
pcSocketId: string;
|
||||
status: ScanLoginStatus;
|
||||
createdAt: number;
|
||||
expiresAt: number;
|
||||
userInfo?: {
|
||||
userId: string;
|
||||
userName: string;
|
||||
department: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface GenerateScanTokenResponse {
|
||||
success: boolean;
|
||||
data?: {
|
||||
scanToken: string;
|
||||
qrCodeUrl: string;
|
||||
expiresAt: number;
|
||||
};
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export interface ValidateTokenResponse {
|
||||
success: boolean;
|
||||
data?: {
|
||||
valid: boolean;
|
||||
status: ScanLoginStatus;
|
||||
expiresAt: number;
|
||||
};
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export interface ScanConfirmPayload {
|
||||
scanToken: string;
|
||||
userName: string;
|
||||
department: string;
|
||||
}
|
||||
|
||||
export interface ScanConfirmResponse {
|
||||
success: boolean;
|
||||
data?: {
|
||||
sessionToken: string;
|
||||
userId: string;
|
||||
};
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export interface ScanStatusUpdatePayload {
|
||||
scanToken: string;
|
||||
status: ScanLoginStatus;
|
||||
userInfo?: {
|
||||
userId: string;
|
||||
userName: string;
|
||||
department: string;
|
||||
sessionToken: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface ScanSubscribePayload {
|
||||
scanToken: string;
|
||||
}
|
||||
Reference in New Issue
Block a user