/** * UI - UI 操作函式 * 包含模組切換、預覽更新、表單資料收集 */ import { showToast } from './utils.js'; import { categoryMap, natureMap, jobCategoryMap } from './config.js'; // ==================== 模組切換 ==================== /** * 切換頁面模組 * @param {string} moduleName - 模組名稱(position/job/jobdesc/positionlist/deptfunction/admin) */ export function switchModule(moduleName) { document.querySelectorAll('.module-btn').forEach(b => { b.classList.remove('active', 'job-active', 'desc-active'); }); document.querySelectorAll('.module-content').forEach(c => c.classList.remove('active')); const targetBtn = document.querySelector(`.module-btn[data-module="${moduleName}"]`); if (targetBtn) { targetBtn.classList.add('active'); if (moduleName === 'job') targetBtn.classList.add('job-active'); if (moduleName === 'jobdesc') targetBtn.classList.add('desc-active'); } const targetModule = document.getElementById('module-' + moduleName); if (targetModule) { targetModule.classList.add('active'); } // 自動刷新崗位清單(需要從其他模組匯入) if (moduleName === 'positionlist' && typeof window.loadPositionList === 'function') { window.loadPositionList(); } updatePreview(); } // ==================== 表單資料收集 ==================== /** * 收集崗位表單資料 * @returns {Object} - 崗位資料(分為 basicInfo 和 recruitInfo) */ export function getPositionFormData() { const form = document.getElementById('positionForm'); const formData = new FormData(form); const data = { basicInfo: {}, recruitInfo: {} }; const basicFields = ['positionCode', 'positionName', 'positionCategory', 'positionCategoryName', 'positionNature', 'positionNatureName', 'headcount', 'positionLevel', 'effectiveDate', 'positionDesc', 'positionRemark']; const recruitFields = ['minEducation', 'requiredGender', 'salaryRange', 'workExperience', 'minAge', 'maxAge', 'jobType', 'recruitPosition', 'jobTitle', 'jobDesc', 'positionReq', 'titleReq', 'majorReq', 'skillReq', 'langReq', 'otherReq', 'superiorPosition', 'recruitRemark']; basicFields.forEach(field => { const value = formData.get(field); if (value) data.basicInfo[field] = value; }); recruitFields.forEach(field => { const value = formData.get(field); if (value) data.recruitInfo[field] = value; }); return data; } /** * 收集職務表單資料 * @returns {Object} - 職務資料 */ export function getJobFormData() { const form = document.getElementById('jobForm'); const formData = new FormData(form); const data = {}; const fields = ['jobCategoryCode', 'jobCategoryName', 'jobCode', 'jobName', 'jobNameEn', 'jobEffectiveDate', 'jobHeadcount', 'jobSortOrder', 'jobRemark', 'jobLevel']; fields.forEach(field => { const value = formData.get(field); if (value) data[field] = value; }); data.hasAttendanceBonus = document.getElementById('hasAttendanceBonus').checked; data.hasHousingAllowance = document.getElementById('hasHousingAllowance').checked; return data; } /** * 收集崗位描述表單資料 * @returns {Object} - 崗位描述資料 */ export function getJobDescFormData() { const form = document.getElementById('jobDescForm'); if (!form) return {}; const formData = new FormData(form); const data = { basicInfo: {}, positionInfo: {}, responsibilities: {}, requirements: {} }; // Basic Info ['empNo', 'empName', 'positionCode', 'versionDate'].forEach(field => { const el = document.getElementById('jd_' + field); if (el && el.value) data.basicInfo[field] = el.value; }); // Position Info ['positionName', 'department', 'positionEffectiveDate', 'directSupervisor', 'positionGradeJob', 'reportTo', 'directReports', 'workLocation', 'empAttribute'].forEach(field => { const el = document.getElementById('jd_' + field); if (el && el.value) data.positionInfo[field] = el.value; }); // Purpose & Responsibilities const purpose = document.getElementById('jd_positionPurpose'); if (purpose && purpose.value) data.responsibilities.positionPurpose = purpose.value; const mainResp = document.getElementById('jd_mainResponsibilities'); if (mainResp && mainResp.value) data.responsibilities.mainResponsibilities = mainResp.value; // Requirements ['education', 'basicSkills', 'professionalKnowledge', 'workExperienceReq', 'otherRequirements'].forEach(field => { const el = document.getElementById('jd_' + field); if (el && el.value) data.requirements[field] = el.value; }); return data; } /** * 收集部門職責表單資料 * @returns {Object} - 部門職責資料 */ export function getDeptFunctionFormData() { const form = document.getElementById('deptFunctionForm'); if (!form) return {}; const formData = new FormData(form); const data = {}; const fields = ['deptFunctionCode', 'deptFunctionName', 'deptFunctionBU', 'deptFunctionDept', 'deptManager', 'deptMission', 'deptVision', 'deptCoreFunctions', 'deptKPIs']; fields.forEach(field => { const value = formData.get(field); if (value) data[field] = value; }); return data; } // ==================== 預覽更新 ==================== /** * 更新 JSON 預覽 */ export function updatePreview() { const activeBtn = document.querySelector('.module-btn.active'); if (!activeBtn) return; const activeModule = activeBtn.dataset.module; let data; if (activeModule === 'position') { data = { module: '崗位基礎資料', ...getPositionFormData() }; } else if (activeModule === 'job') { data = { module: '職務基礎資料', ...getJobFormData() }; } else if (activeModule === 'jobdesc') { data = { module: '崗位描述', ...getJobDescFormData() }; } else if (activeModule === 'deptfunction') { data = { module: '部門職責', ...getDeptFunctionFormData() }; } else { return; // 其他模組不顯示預覽 } const previewEl = document.getElementById('jsonPreview'); if (previewEl) { previewEl.textContent = JSON.stringify(data, null, 2); } } // ==================== 表單邏輯輔助函式 ==================== /** * 更新崗位類別中文名稱 */ export function updateCategoryName() { const category = document.getElementById('positionCategory').value; document.getElementById('positionCategoryName').value = categoryMap[category] || ''; updatePreview(); } /** * 更新崗位性質中文名稱 */ export function updateNatureName() { const nature = document.getElementById('positionNature').value; document.getElementById('positionNatureName').value = natureMap[nature] || ''; updatePreview(); } /** * 更新職務類別中文名稱 */ export function updateJobCategoryName() { const category = document.getElementById('jobCategoryCode').value; document.getElementById('jobCategoryName').value = jobCategoryMap[category] || ''; updatePreview(); } /** * 修改崗位編號 */ export function changePositionCode() { const currentCode = document.getElementById('positionCode').value; const newCode = prompt('請輸入新的崗位編號:', currentCode); if (newCode && newCode !== currentCode) { document.getElementById('positionCode').value = newCode; showToast('崗位編號已更改!'); updatePreview(); } } /** * 修改職務編號 */ export function changeJobCode() { const currentCode = document.getElementById('jobCode').value; const newCode = prompt('請輸入新的職務編號:', currentCode); if (newCode && newCode !== currentCode) { document.getElementById('jobCode').value = newCode; showToast('職務編號已更改!'); updatePreview(); } } // ==================== 模態框函式(待整合)==================== /** * 開啟專業科目選擇模態框 */ export function openMajorModal() { const modal = document.getElementById('majorModal'); if (modal) { modal.classList.add('show'); } } /** * 關閉專業科目選擇模態框 */ export function closeMajorModal() { const modal = document.getElementById('majorModal'); if (modal) { modal.classList.remove('show'); } } /** * 確認選擇專業科目 */ export function confirmMajor() { const selected = []; document.querySelectorAll('#majorModal input[type="checkbox"]:checked').forEach(cb => { selected.push(cb.value); }); document.getElementById('majorReq').value = selected.join(', '); closeMajorModal(); updatePreview(); } // 將函式掛載到 window 上以便內聯事件處理器使用 if (typeof window !== 'undefined') { window.switchModule = switchModule; window.updateCategoryName = updateCategoryName; window.updateNatureName = updateNatureName; window.updateJobCategoryName = updateJobCategoryName; window.changePositionCode = changePositionCode; window.changeJobCode = changeJobCode; window.openMajorModal = openMajorModal; window.closeMajorModal = closeMajorModal; window.confirmMajor = confirmMajor; window.updatePreview = updatePreview; }