CSAPP/src/index.ts

247 lines
7.7 KiB
TypeScript
Raw Normal View History

import { WebviewTag } from 'electron';
import { TabGroup, Tab } from 'electron-tabs';
2025-04-30 00:05:32 +08:00
// 菜单项
2025-04-30 00:05:32 +08:00
interface MenuItem {
ShowName: string;
Url: string;
IconConfig: IconConfig;
2025-04-30 00:05:32 +08:00
Children: MenuItem[] | null;
}
2025-04-29 18:36:29 +08:00
// 图标配置
interface IconConfig {
_1x: {
Default: string;
Selected: string;
};
_2x: {
Default: string;
Selected: string;
};
}
2025-04-30 00:05:32 +08:00
// API响应接口
interface ApiResponse<T> {
status: number;
code: number;
msg: string;
data: T;
}
2025-04-29 18:36:29 +08:00
const tabGroup: TabGroup = document.querySelector('tab-group') as TabGroup;
// Check login status
2025-04-29 18:36:29 +08:00
function checkLoginStatus() {
const cookie = window.electronAPI.getSessionStorage('cookie');
if (!cookie) {
2025-04-29 18:36:29 +08:00
window.location.href = 'login.html';
return;
}
2025-04-30 00:05:32 +08:00
// Show user information
2025-04-29 18:36:29 +08:00
const userInfo = document.getElementById('userInfo');
if (userInfo) {
userInfo.textContent = '欢迎使用';
}
}
// Handle logout
2025-04-29 18:36:29 +08:00
function handleLogout() {
window.electronAPI.removeSessionStorage('cookie');
2025-04-29 18:36:29 +08:00
window.location.href = 'login.html';
}
// Get menu list
2025-04-30 00:05:32 +08:00
async function getMenuList(): Promise<MenuItem[]> {
try {
const response = await fetch('http://1.12.73.211:8848/EIAC_Desktop_Api/api/Menu/GetMenu', {
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
2025-04-29 18:36:29 +08:00
});
2025-04-30 00:05:32 +08:00
const result = await response.json() as ApiResponse<MenuItem[]>;
if (result.status === 0) {
return result.data;
} else {
throw new Error(result.msg || '获取菜单列表失败');
2025-04-29 18:36:29 +08:00
}
2025-04-30 00:05:32 +08:00
} catch (error) {
console.error('获取菜单列表失败:', error);
2025-04-30 00:05:32 +08:00
throw error;
2025-04-29 18:36:29 +08:00
}
}
// Modify the createMenuItem function to handle new tab creation
function createMenuItem(item: MenuItem, menuList: MenuItem[]): HTMLLIElement {
2025-04-30 00:05:32 +08:00
const li = document.createElement('li');
li.className = 'menu-item';
2025-04-29 18:36:29 +08:00
2025-04-30 00:05:32 +08:00
const icon = document.createElement('img');
icon.src = item.IconConfig._1x.Default;
2025-04-30 00:05:32 +08:00
icon.alt = item.ShowName;
icon.className = 'menu-icon';
const span = document.createElement('span');
span.textContent = item.ShowName;
li.appendChild(icon);
li.appendChild(span);
if (item.Url) {
2025-04-30 17:28:03 +08:00
li.addEventListener('click', async () => {
// Remove active state from other menu items
document.querySelectorAll('.menu-item').forEach(menuItem => {
menuItem.classList.remove('active');
const menuIcon = menuItem.querySelector('.menu-icon') as HTMLImageElement;
if (menuIcon) {
const menuItemData = menuList.find((m: MenuItem) => m.ShowName === menuItem.querySelector('span')?.textContent);
if (menuItemData) {
menuIcon.src = menuItemData.IconConfig._1x.Default;
}
}
});
// Add active state to current menu item
li.classList.add('active');
icon.src = item.IconConfig._1x.Selected;
2025-04-30 17:28:03 +08:00
// Create new tab
await addTab(tabGroup, item);
2025-04-30 00:05:32 +08:00
});
2025-04-29 18:36:29 +08:00
}
2025-04-30 00:05:32 +08:00
return li;
}
// Render menu
2025-04-30 00:05:32 +08:00
function renderMenu(menuList: MenuItem[]) {
const menuContainer = document.getElementById('menuList');
if (!menuContainer) return;
menuList.forEach(item => {
const menuItem = createMenuItem(item, menuList);
2025-04-30 00:05:32 +08:00
menuContainer.appendChild(menuItem);
if (item.Children) {
const subMenu = document.createElement('ul');
subMenu.className = 'submenu';
item.Children.forEach(child => {
const childItem = createMenuItem(child, menuList);
2025-04-30 00:05:32 +08:00
subMenu.appendChild(childItem);
});
menuContainer.appendChild(subMenu);
}
});
2025-04-29 18:36:29 +08:00
}
// Show error modal
function showErrorModal(message: string) {
const errorModal = document.getElementById('errorModal') as HTMLDivElement;
const errorMessage = document.getElementById('errorMessage') as HTMLParagraphElement;
errorMessage.textContent = message;
errorModal.style.display = 'block';
}
async function addTab(tabGroup: TabGroup, menuItem: MenuItem): Promise<Tab> {
const url = menuItem.Url.startsWith("http") ? menuItem.Url : `http://${menuItem.Url}`;
const result = await window.electronAPI.checkUrlAvailable(url);
if (result.ok && result.status >= 200 && result.status < 400) {
console.log('✅ URL 可访问:', result.status);
const cookies: string = window.electronAPI.getSessionStorage('cookie');
await window.electronAPI.setWebviewCookie(url, cookies);
} else {
console.warn('❌ URL 不可访问:', result.error ?? `status ${result.status}`);
showErrorModal(`无法访问 ${url}\r\n异常原因${result.error ?? `status ${result.status}`}\r\n请联系10000技术支持。`);
}
const tab: Tab = tabGroup.addTab({
active: true,
closable: true,
title: menuItem.ShowName,
src: url,
iconURL: menuItem.IconConfig._1x.Default,
webviewAttributes: {
'webpreferences': 'contextIsolation=yes, nodeIntegration=no',
'autosize': 'on',
'allowpopups': true,
},
ready: (tab: Tab) => {
// 在加载完成后,获取标题
tab.once('webview-dom-ready', (detail: string) => {
console.log('webview-dom-ready detail:', detail);
const webview = tab.webview as WebviewTag;
const title = webview.getTitle();
tab.setTitle(title);
console.log('webview-dom-ready title:', title);
});
}
});
return tab;
}
async function bindLogoClickEvent(tabGroup: TabGroup, menuItem: MenuItem) {
const logo = document.getElementById('logo') as HTMLImageElement;
logo.addEventListener('click', async () => {
console.log('logo clicked');
const tab: Tab = await addTab(tabGroup, menuItem);
tab.setPosition(0);
});
}
// Modify the initialize function to create the first tab
2025-04-30 00:05:32 +08:00
async function initialize() {
// Check login status
2025-04-29 18:36:29 +08:00
checkLoginStatus();
2025-04-30 00:05:32 +08:00
try {
const menuList = await getMenuList();
renderMenu(menuList);
// Create initial tab
const firstMenuItem = menuList[0];
await addTab(tabGroup, firstMenuItem);
// Bind logout event
2025-04-30 00:05:32 +08:00
const logoutBtn = document.getElementById('btnLogout');
if (logoutBtn) {
logoutBtn.addEventListener('click', handleLogout);
}
const errorModal = document.getElementById('errorModal') as HTMLDivElement;
const closeErrorModal = document.getElementById('closeErrorModal') as HTMLButtonElement;
// Close button click event
closeErrorModal.addEventListener('click', (event: Event) => {
errorModal.style.display = 'none';
});
// Click outside to close
window.addEventListener('click', (event: Event) => {
if (event.target === errorModal) {
errorModal.style.display = 'none';
}
});
// Listen logo click event
const lastMenuItem = menuList[menuList.length - 1];
await bindLogoClickEvent(tabGroup, lastMenuItem);
2025-04-30 00:05:32 +08:00
} catch (error) {
console.error('初始化失败:', error);
2025-04-29 18:36:29 +08:00
}
}
2025-04-30 00:05:32 +08:00
// 页面加载完成后初始化
2025-04-29 18:36:29 +08:00
document.addEventListener('DOMContentLoaded', initialize);
window.electronAPI.onOpenTab((webContentId: number, url: string) => {
addTab(tabGroup, {
Url: url,
ShowName: '新标签页',
IconConfig: { _1x: { Default: '', Selected: '' }, _2x: { Default: '', Selected: '' } },
Children: null
});
});