chore: 首次簽入 Thinkyu ASP.NET 專案

- 加入 Visual Studio / ASP.NET .gitignore
- 排除建置輸出、IDE 設定、NuGet packages、大型 MSI 安裝檔
This commit is contained in:
2026-09-10 09:42:37 +08:00
commit 577060bc78
2496 changed files with 501389 additions and 0 deletions
+174
View File
@@ -0,0 +1,174 @@
// ========================================
// Site.Master 選單管理 - 使用 sessionStorage 保持狀態
// ========================================
/**
* 切換側邊欄展開/收合
*/
function toggleSidebar() {
var gridContainer = document.querySelector('.grid-container');
gridContainer.classList.toggle('sidebar-collapsed');
// 儲存側邊欄狀態到 sessionStorage
var isCollapsed = gridContainer.classList.contains('sidebar-collapsed');
sessionStorage.setItem('sidebarCollapsed', isCollapsed);
}
/**
* 切換子選單展開/收合
* @param {Event} event - 點擊事件
* @param {string} menuId - 子選單的 ID
*/
function toggleSubmenu(event, menuId) {
event.preventDefault();
var submenu = document.getElementById(menuId);
var menuLink = event.currentTarget;
var arrow = menuLink.querySelector('.menu-arrow');
if (submenu.style.display === 'block') {
submenu.style.display = 'none';
arrow.textContent = '▼';
} else {
// 關閉其他子選單
var allSubmenus = document.querySelectorAll('.submenu');
var allArrows = document.querySelectorAll('.menu-arrow');
allSubmenus.forEach(function (sm) { sm.style.display = 'none'; });
allArrows.forEach(function (arr) { arr.textContent = '▼'; });
submenu.style.display = 'block';
arrow.textContent = '▲';
}
// 儲存所有子選單的展開狀態到 sessionStorage
saveSubmenuStates();
}
/**
* 儲存所有子選單的展開狀態
*/
function saveSubmenuStates() {
var states = {};
var allSubmenus = document.querySelectorAll('.submenu');
allSubmenus.forEach(function (submenu) {
states[submenu.id] = submenu.style.display === 'block';
});
sessionStorage.setItem('submenuStates', JSON.stringify(states));
}
/**
* 恢復所有子選單的展開狀態
* @returns {boolean} 是否有恢復任何選單狀態
*/
function restoreSubmenuStates() {
var savedStates = sessionStorage.getItem('submenuStates');
if (savedStates) {
try {
var states = JSON.parse(savedStates);
var hasOpenMenu = false;
// 恢復每個子選單的狀態
for (var menuId in states) {
var submenu = document.getElementById(menuId);
if (submenu && states[menuId]) {
submenu.style.display = 'block';
hasOpenMenu = true;
// 更新箭頭方向
var menuItem = submenu.closest('.menu-item');
if (menuItem) {
var arrow = menuItem.querySelector('.menu-arrow');
if (arrow) {
arrow.textContent = '▲';
}
}
}
}
return hasOpenMenu;
} catch (e) {
console.error('恢復選單狀態失敗:', e);
return false;
}
}
return false;
}
/**
* 恢復側邊欄收合狀態
*/
function restoreSidebarState() {
var isCollapsed = sessionStorage.getItem('sidebarCollapsed') === 'true';
if (isCollapsed) {
var gridContainer = document.querySelector('.grid-container');
gridContainer.classList.add('sidebar-collapsed');
}
}
/**
* 初始化選單狀態
*/
function initializeMenuState() {
// 恢復側邊欄狀態
restoreSidebarState();
// 嘗試恢復子選單狀態
var hasRestoredState = restoreSubmenuStates();
// 如果沒有儲存的狀態,則展開第一個選單(預設行為)
if (!hasRestoredState) {
var firstSubmenu = document.getElementById('menu1');
if (firstSubmenu) {
firstSubmenu.style.display = 'block';
var firstArrow = document.querySelector('.menu-list .menu-item:first-child .menu-arrow');
if (firstArrow) {
firstArrow.textContent = '▲';
}
// 儲存預設狀態
saveSubmenuStates();
}
}
}
// ========================================
// 主版面 - 登出功能
// 使用 Scripts/shared.js 提供的服務
// ========================================
/**
* 處理登出
* 使用 Scripts/shared.js -> $api.logout
* 使用 Scripts/shared.js -> $message
* 使用 Scripts/shared.js -> $navigate
*/
async function handleLogout() {
if (!confirm('確定要登出嗎?')) {
return;
}
console.log('[Site.Master] 開始登出');
try {
const response = await window.$api.logout();
if (response.Success) {
console.log('[Site.Master] 登出成功');
window.$message.success('登出成功');
setTimeout(() => window.$navigate.toLogin(), 500);
} else {
console.warn('[Site.Master] 登出失敗: ' + response.Message);
window.$message.error('登出失敗');
}
} catch (error) {
console.error('[Site.Master] 登出錯誤:', error);
// 即使發生錯誤也導向登入頁
window.$navigate.toLogin();
}
}
// ========================================
// 頁面載入時初始化
// ========================================
window.addEventListener('load', function () {
initializeMenuState();
});