Files
hr-position-system/js/main.js
DonaldFang 方士碩 a6af297623 backup: 完成 HR_position_ 表格前綴重命名與欄位對照表整理
變更內容:
- 所有資料表加上 HR_position_ 前綴
- 整理完整欄位顯示名稱與 ID 對照表
- 模組化 JS 檔案 (admin.js, ai.js, csv.js 等)
- 專案結構優化 (docs/, scripts/, tests/ 等)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 12:05:20 +08:00

207 lines
6.7 KiB
JavaScript

/**
* Main - 主程式
* 初始化應用程式,設定事件監聽器
*/
import { showToast } from './utils.js';
import { switchModule, updatePreview, updateCategoryName, updateNatureName, updateJobCategoryName } from './ui.js';
import { initializeBagTitles } from './ai-bags.js';
// ==================== 初始化 ====================
/**
* 載入用戶信息
*/
function loadUserInfo() {
const currentUser = localStorage.getItem('currentUser');
if (!currentUser) {
return;
}
try {
const userData = JSON.parse(currentUser);
const userName = document.getElementById('userName');
const userRole = document.getElementById('userRole');
const userAvatar = document.getElementById('userAvatar');
if (userName) userName.textContent = userData.name || '使用者';
if (userRole) userRole.textContent = userData.role || '一般使用者';
if (userAvatar) userAvatar.textContent = (userData.name || 'U').charAt(0).toUpperCase();
} catch (e) {
console.error('解析用戶資料失敗:', e);
}
}
/**
* 登出功能
*/
function logout() {
if (confirm('確定要登出嗎?')) {
localStorage.removeItem('currentUser');
window.location.href = 'login.html';
}
}
// ==================== 事件監聽器設置 ====================
/**
* 設置模組切換事件
*/
function setupModuleSwitching() {
document.querySelectorAll('.module-btn').forEach(btn => {
btn.addEventListener('click', () => {
const moduleName = btn.dataset.module;
if (moduleName) {
switchModule(moduleName);
}
});
});
}
/**
* 設置標籤頁切換事件
*/
function setupTabSwitching() {
document.querySelectorAll('.tab-btn').forEach(btn => {
btn.addEventListener('click', () => {
const parent = btn.closest('.form-card');
if (!parent) return;
parent.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
parent.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
btn.classList.add('active');
const targetTab = document.getElementById('tab-' + btn.dataset.tab);
if (targetTab) {
targetTab.classList.add('active');
}
});
});
}
/**
* 設置表單欄位監聽
*/
function setupFormListeners() {
// 監聽所有表單欄位變更,更新預覽
document.querySelectorAll('input, select, textarea').forEach(field => {
field.addEventListener('change', updatePreview);
field.addEventListener('input', updatePreview);
});
// 崗位類別變更 (pos_category)
const positionCategory = document.getElementById('pos_category');
if (positionCategory) {
positionCategory.addEventListener('change', updateCategoryName);
}
// 崗位性質變更 (pos_type)
const positionNature = document.getElementById('pos_type');
if (positionNature) {
positionNature.addEventListener('change', updateNatureName);
}
// 職務類別變更 (job_category)
const jobCategoryCode = document.getElementById('job_category');
if (jobCategoryCode) {
jobCategoryCode.addEventListener('change', updateJobCategoryName);
}
// Toggle 開關變更 (job_hasAttBonus)
const hasAttendanceBonus = document.getElementById('job_hasAttBonus');
if (hasAttendanceBonus) {
hasAttendanceBonus.addEventListener('change', function() {
const label = document.getElementById('attendanceLabel');
if (label) {
label.textContent = this.checked ? '是' : '否';
}
updatePreview();
});
}
// Toggle 開關變更 (job_hasHouseAllow)
const hasHousingAllowance = document.getElementById('job_hasHouseAllow');
if (hasHousingAllowance) {
hasHousingAllowance.addEventListener('change', function() {
const label = document.getElementById('housingLabel');
if (label) {
label.textContent = this.checked ? '是' : '否';
}
updatePreview();
});
}
}
/**
* 設置快捷鍵
*/
function setupKeyboardShortcuts() {
document.addEventListener('keydown', (e) => {
// Ctrl+S 或 Cmd+S: 保存當前模組
if ((e.ctrlKey || e.metaKey) && e.key === 's') {
e.preventDefault();
const activeModule = document.querySelector('.module-btn.active');
if (!activeModule) return;
const moduleName = activeModule.dataset.module;
if (moduleName === 'position' && typeof window.savePositionAndExit === 'function') {
window.savePositionAndExit();
} else if (moduleName === 'job' && typeof window.saveJobAndExit === 'function') {
window.saveJobAndExit();
} else if (moduleName === 'jobdesc' && typeof window.saveJobDescAndExit === 'function') {
window.saveJobDescAndExit();
} else if (moduleName === 'deptfunction' && typeof window.saveDeptFunctionAndExit === 'function') {
window.saveDeptFunctionAndExit();
}
}
// Ctrl+N 或 Cmd+N: 保存並新增下一筆
if ((e.ctrlKey || e.metaKey) && e.key === 'n') {
e.preventDefault();
const activeModule = document.querySelector('.module-btn.active');
if (!activeModule) return;
const moduleName = activeModule.dataset.module;
if (moduleName === 'position' && typeof window.savePositionAndNew === 'function') {
window.savePositionAndNew();
} else if (moduleName === 'job' && typeof window.saveJobAndNew === 'function') {
window.saveJobAndNew();
} else if (moduleName === 'jobdesc' && typeof window.saveJobDescAndNew === 'function') {
window.saveJobDescAndNew();
} else if (moduleName === 'deptfunction' && typeof window.saveDeptFunctionAndNew === 'function') {
window.saveDeptFunctionAndNew();
}
}
});
}
// ==================== DOMContentLoaded 初始化 ====================
document.addEventListener('DOMContentLoaded', () => {
console.log('🚀 HR 系統初始化中...');
// 載入用戶信息
loadUserInfo();
// 設置事件監聽器
setupModuleSwitching();
setupTabSwitching();
setupFormListeners();
setupKeyboardShortcuts();
// 初始化 AI 錦囊標題
initializeBagTitles();
// 初始化預覽
updatePreview();
console.log('✅ HR 系統初始化完成');
});
// ==================== 將函式掛載到 window ====================
if (typeof window !== 'undefined') {
window.logout = logout;
window.loadUserInfo = loadUserInfo;
}