|
|
|
|
|
|
|
|
|
window.bulkOperations = {
|
|
selectedKeys: [],
|
|
isBulkDelete: false,
|
|
|
|
|
|
get isAllSelected() {
|
|
const allVisibleKeyIds = this.getAllVisibleKeyIds();
|
|
return allVisibleKeyIds.length > 0 &&
|
|
allVisibleKeyIds.every(id => this.selectedKeys.includes(id));
|
|
},
|
|
|
|
|
|
getAllVisibleKeyIds() {
|
|
const keyElements = document.querySelectorAll('[data-key-id]');
|
|
const keyIds = [];
|
|
keyElements.forEach(el => {
|
|
|
|
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) {
|
|
|
|
this.selectedKeys = this.selectedKeys.filter(id => !allIds.includes(id));
|
|
} else {
|
|
|
|
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;
|
|
},
|
|
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
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;
|
|
}
|
|
};
|
|
|
|
|
|
function initXHRInterceptor() {
|
|
const originalXHROpen = XMLHttpRequest.prototype.open;
|
|
const originalXHRSend = XMLHttpRequest.prototype.send;
|
|
|
|
|
|
XMLHttpRequest.prototype.open = function() {
|
|
this._url = arguments[1];
|
|
originalXHROpen.apply(this, arguments);
|
|
};
|
|
|
|
|
|
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();
|
|
});
|
|
|
|
|
|
function initKeyboardShortcuts() {
|
|
|
|
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';
|
|
});
|
|
});
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function showNotification(message, type = 'info') {
|
|
const event = new CustomEvent('show-notification', {
|
|
detail: { message, type }
|
|
});
|
|
window.dispatchEvent(event);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|