File size: 8,167 Bytes
bbb6398
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
// API密钥管理系统 - 主JavaScript文件
// ==============================

// 批量操作模块 - Alpine.js集成
window.bulkOperations = {
    selectedKeys: [], // 存储选中的密钥ID
    isBulkDelete: false, // 标记是否进行批量删除操作
    
    // 计算是否所有可见密钥都被选中
    get isAllSelected() {
        const allVisibleKeyIds = this.getAllVisibleKeyIds();
        return allVisibleKeyIds.length > 0 && 
               allVisibleKeyIds.every(id => this.selectedKeys.includes(id));
    },
    
    // 获取当前页面中所有可见密钥的ID
    getAllVisibleKeyIds() {
        const keyElements = document.querySelectorAll('[data-key-id]');
        const keyIds = [];
        keyElements.forEach(el => {
            // 只收集DOM中可见的元素ID
            if (el.offsetParent !== null) {
                const keyId = el.getAttribute('data-key-id');
                if (keyId) keyIds.push(keyId);
            }
        });
        return keyIds;
    },
    
    // 切换单个密钥的选中状态
    toggleKeySelection(keyId) {
        const index = this.selectedKeys.indexOf(keyId);
        if (index === -1) {
            this.selectedKeys.push(keyId);
        } else {
            this.selectedKeys.splice(index, 1);
        }
    },
    
    // 切换全选/取消全选状态
    toggleSelectAll() {
        const allIds = this.getAllVisibleKeyIds();
        
        if (this.isAllSelected) {
            // 取消全选 - 从选中列表中移除所有可见ID
            this.selectedKeys = this.selectedKeys.filter(id => !allIds.includes(id));
        } else {
            // 全选 - 将所有可见ID添加到选中列表
            const newSelection = [...this.selectedKeys];
            allIds.forEach(id => {
                if (!newSelection.includes(id)) {
                    newSelection.push(id);
                }
            });
            this.selectedKeys = newSelection;
        }
    },
    
    // 执行批量删除操作
    bulkDeleteApiKeys() {
        if (this.selectedKeys.length === 0) return;
        
        this.isBulkDelete = true;
        this.$store.apiKeys.showDeleteConfirm = true;
    },
    
    // 触发批量复制功能 - 调用Alpine.js实例中的方法
    bulkCopyApiKeys() {
        const apiKeyManager = document.querySelector('[x-data]').__x.$data;
        
        if (apiKeyManager && typeof apiKeyManager.bulkCopyApiKeys === 'function') {
            apiKeyManager.bulkCopyApiKeys();
        } else {
            console.error('无法找到Alpine.js实例或批量复制方法');
            showNotification('复制功能初始化失败,请刷新页面重试', 'error');
        }
    }
};

// 认证处理模块
// ==============================

// 检测并处理认证失效情况
function handleAuthenticationError(response) {
    if (response.status === 401) {
        showNotification('会话已过期,正在重定向到登录页面...', 'error');
        
        setTimeout(() => {
            window.location.href = '/login';
        }, 2000);
        
        return true; // 已处理认证错误
    }
    return false; // 非认证错误
}

// 扩展fetch API,添加认证错误处理
const originalFetch = window.fetch;
window.fetch = async function(url, options = {}) {
    try {
        const response = await originalFetch(url, options);
        
        if (handleAuthenticationError(response)) {
            return response; // 认证错误已处理,返回原始响应
        }
        
        return response;
    } catch (error) {
        console.error('Fetch error:', error);
        throw error;
    }
};

// 初始化XMLHttpRequest拦截器处理认证问题
function initXHRInterceptor() {
    const originalXHROpen = XMLHttpRequest.prototype.open;
    const originalXHRSend = XMLHttpRequest.prototype.send;
    
    // 拦截open方法以保存URL
    XMLHttpRequest.prototype.open = function() {
        this._url = arguments[1];
        originalXHROpen.apply(this, arguments);
    };
    
    // 拦截send方法以添加认证检查
    XMLHttpRequest.prototype.send = function() {
        const xhr = this;
        const originalOnReadyStateChange = xhr.onreadystatechange;
        
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4 && xhr.status === 401) {
                showNotification('会话已过期,正在重定向到登录页面...', 'error');
                setTimeout(() => {
                    window.location.href = '/login';
                }, 2000);
            }
            
            if (originalOnReadyStateChange) {
                originalOnReadyStateChange.apply(this, arguments);
            }
        };
        
        originalXHRSend.apply(this, arguments);
    };
}

// 初始化模块
// ==============================
document.addEventListener('DOMContentLoaded', () => {
    initScrollContainers();    // 初始化滚动容器
    initKeyboardShortcuts();   // 设置键盘快捷键
    initBackToTop();           // 设置回到顶部按钮
    initXHRInterceptor();      // 启用XHR拦截器处理认证
});

// 设置键盘快捷键
function initKeyboardShortcuts() {
    // Alt+N: 打开添加密钥模态框
    document.addEventListener('keydown', (e) => {
        if (e.altKey && e.key === 'n') {
            window.dispatchEvent(new CustomEvent('open-add-modal'));
        }
    });
}

// 初始化滚动容器,处理长密钥的滚动显示
function initScrollContainers() {
    const scrollContainers = document.querySelectorAll('.key-scroll-container');
    scrollContainers.forEach(container => {
        // 鼠标悬停时显示滚动条
        container.addEventListener('mouseenter', () => {
            if (container.scrollWidth > container.clientWidth) {
                container.style.overflowX = 'auto';
            }
        });
        
        // 鼠标离开时隐藏滚动条
        container.addEventListener('mouseleave', () => {
            container.style.overflowX = 'hidden';
        });
    });
}

// 工具函数
// ==============================

// 显示通知消息
// message: 通知内容
// type: 通知类型 (success, error, info)
function showNotification(message, type = 'info') {
    const event = new CustomEvent('show-notification', {
        detail: { message, type }
    });
    window.dispatchEvent(event);
}

// UI控件
// ==============================

// 初始化回到顶部按钮功能
function initBackToTop() {
    const backToTopBtn = document.getElementById('backToTop');
    if (!backToTopBtn) return;
    
    const scrollThreshold = 50; // 显示按钮的滚动阈值
    
    // 更新按钮可见性
    const updateButtonVisibility = () => {
        if (window.scrollY > scrollThreshold) {
            backToTopBtn.classList.add('visible');
        } else {
            backToTopBtn.classList.remove('visible');
        }
    };
    
    // 监听滚动事件
    window.addEventListener('scroll', updateButtonVisibility);
    
    // 设置按钮点击行为
    backToTopBtn.addEventListener('click', () => {
        window.scrollTo({
            top: 0,
            behavior: 'smooth'
        });
    });
    
    // 初始状态检查
    updateButtonVisibility();
}

// 应用状态管理
// ==============================

// 重置所有本地存储的应用状态
function resetAppState() {
    // 需要清除的本地存储键
    const stateKeys = [
        'platformStates', 
        'platformFilters', 
        'lastSelectedPlatform'
    ];
    
    // 清除所有状态
    stateKeys.forEach(key => localStorage.removeItem(key));
    
    showNotification('已重置所有浏览状态,刷新页面以应用变更。', 'info');
    
    // 自动刷新页面应用更改
    setTimeout(() => window.location.reload(), 1000);
}

// 导出全局函数
window.resetAppState = resetAppState;