CSAPP/src/index.ts

214 lines
7.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { WebviewTag } from 'electron';
import { TabGroup, Tab } from 'electron-tabs';
import { MenuItem, ApiResponse, EIACDesktopApi } from './EIAC_Desktop_Api';
const tabGroup: TabGroup = document.querySelector('tab-group') as TabGroup;
// Check login status
function checkLoginStatus() {
const cookie = window.electronAPI.getSessionStorage('cookie');
if (!cookie) {
window.location.href = 'login.html';
return;
}
// Show user information
const userInfo = document.getElementById('userInfo');
if (userInfo) {
userInfo.textContent = '欢迎使用';
}
}
// Handle logout
function handleLogout() {
window.electronAPI.removeSessionStorage('cookie');
window.location.href = 'login.html';
}
// Get menu list
async function getMenuList(): Promise<MenuItem[]> {
try {
const response: ApiResponse<MenuItem[]> = await EIACDesktopApi.Menu.GetMenuAsync();
if (response.status === 0) {
const menuList: MenuItem[] = response.data;
return menuList;
} else {
throw new Error(response.msg || '获取菜单列表失败');
}
} catch (error) {
console.error('获取菜单列表失败:', error);
throw error;
}
}
// Modify the createMenuItem function to handle new tab creation
function createMenuItem(item: MenuItem, menuList: MenuItem[]): HTMLLIElement {
const li = document.createElement('li');
li.className = 'menu-item';
const icon = document.createElement('img');
icon.src = item.IconConfig._1x.Default;
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) {
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;
// Create new tab
await addTab(tabGroup, item);
});
}
return li;
}
// Render menu
function renderMenu(menuList: MenuItem[]) {
const menuContainer = document.getElementById('menuList');
if (!menuContainer) return;
menuList.forEach(item => {
const menuItem = createMenuItem(item, menuList);
menuContainer.appendChild(menuItem);
if (item.Children) {
const subMenu = document.createElement('ul');
subMenu.className = 'submenu';
item.Children.forEach(child => {
const childItem = createMenuItem(child, menuList);
subMenu.appendChild(childItem);
});
menuContainer.appendChild(subMenu);
}
});
}
// 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
async function initialize() {
// Check login status
checkLoginStatus();
try {
const menuList = await getMenuList();
renderMenu(menuList);
// Create initial tab
const firstMenuItem = menuList[0];
await addTab(tabGroup, firstMenuItem);
// Bind logout event
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);
} catch (error) {
console.error('初始化失败:', error);
}
}
// 页面加载完成后初始化
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
});
});