File size: 4,111 Bytes
033070f
 
 
 
c8f3989
033070f
 
 
 
 
 
 
 
 
c8f3989
033070f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c8f3989
033070f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bb35e88
033070f
 
 
 
 
 
 
 
 
 
c8f3989
033070f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/**
 * 管理员状态管理模块
 */

const INFORADAR_ADMIN_TOKEN_KEY = 'admin_token';
const ADMIN_MODE_KEY = 'is_admin_mode';

export class AdminManager {
    private static instance: AdminManager | null = null;
    private adminToken: string | null = null;
    private isAdminMode: boolean = false;

    private constructor() {
        // 从localStorage恢复状态
        const savedToken = localStorage.getItem(INFORADAR_ADMIN_TOKEN_KEY);
        const savedMode = localStorage.getItem(ADMIN_MODE_KEY);
        
        if (savedToken) {
            this.adminToken = savedToken;
        }
        
        if (savedMode === 'true') {
            this.isAdminMode = true;
        }
    }

    public static getInstance(): AdminManager {
        if (!AdminManager.instance) {
            AdminManager.instance = new AdminManager();
        }
        return AdminManager.instance;
    }

    /**
     * 获取当前admin token
     */
    public getAdminToken(): string | null {
        return this.adminToken;
    }

    /**
     * 检查是否处于管理员模式
     */
    public isInAdminMode(): boolean {
        return this.isAdminMode && this.adminToken !== null;
    }

    /**
     * 设置admin token并进入管理员模式
     * 返回后端的 success / message,方便前端直接展示后端文案
     */
    public async setAdminToken(token: string): Promise<{ success: boolean; message?: string }> {
        try {
            // 验证token(调用后端API)
            const response = await fetch('/api/check_admin', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-Admin-Token': token
                },
                body: JSON.stringify({ token })
            });

            const result = await response.json();
            
            if (result.success) {
                this.adminToken = token;
                this.isAdminMode = true;
                localStorage.setItem(INFORADAR_ADMIN_TOKEN_KEY, token);
                localStorage.setItem(ADMIN_MODE_KEY, 'true');
                return {
                    success: true,
                    message: result.message
                };
            } else {
                // token无效或管理员功能未启用
                this.clearAdminToken();
                return {
                    success: false,
                    // 不自作主张改写文案,优先使用后端 message
                    message: result && typeof result.message === 'string' ? result.message : undefined
                };
            }
        } catch (error) {
            console.error('验证admin token失败:', error);
            this.clearAdminToken();
            // 网络等异常场景单独返回一条通用错误
            return {
                success: false,
                message: 'Request failed, please try again later.'
            };
        }
    }

    /**
     * 清除admin token并退出管理员模式
     */
    public clearAdminToken(): void {
        this.adminToken = null;
        this.isAdminMode = false;
        localStorage.removeItem(INFORADAR_ADMIN_TOKEN_KEY);
        localStorage.removeItem(ADMIN_MODE_KEY);
    }

    /**
     * 监听管理员模式状态变化
     */
    private listeners: Array<(isAdmin: boolean) => void> = [];

    public onAdminModeChange(callback: (isAdmin: boolean) => void): void {
        this.listeners.push(callback);
    }

    private notifyListeners(): void {
        const isAdmin = this.isInAdminMode();
        this.listeners.forEach(callback => callback(isAdmin));
    }

    /**
     * 设置admin token并通知监听器
     */
    public async setAdminTokenAndNotify(token: string): Promise<{ success: boolean; message?: string }> {
        const result = await this.setAdminToken(token);
        this.notifyListeners();
        return result;
    }

    /**
     * 清除admin token并通知监听器
     */
    public clearAdminTokenAndNotify(): void {
        this.clearAdminToken();
        this.notifyListeners();
    }
}