feat: 為所有四個模組添加「儲存至崗位清單」按鈕
- 崗位基礎資料模組:已有功能,保持不變 - 職務基礎資料模組:新增 saveJobToPositionList() 函式 - 部門職責模組:新增 saveDeptFunctionToPositionList() 函式 - 崗位描述模組:新增 saveJobDescToPositionList() 函式 所有按鈕統一使用紫色漸層樣式,與系統主題一致 支援資料格式轉換並儲存到崗位清單 成功後顯示 toast 訊息並跳轉至崗位清單頁面
This commit is contained in:
181
index.html
181
index.html
@@ -1192,6 +1192,10 @@
|
|||||||
<input type="file" id="jobCSVInput" accept=".csv" style="display: none;" onchange="handleJobCSVImport(event)">
|
<input type="file" id="jobCSVInput" accept=".csv" style="display: none;" onchange="handleJobCSVImport(event)">
|
||||||
</div>
|
</div>
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
|
<button type="button" class="btn btn-success" onclick="saveJobToPositionList()" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);">
|
||||||
|
<svg viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
|
||||||
|
儲存至崗位清單
|
||||||
|
</button>
|
||||||
<button type="button" class="btn btn-primary" onclick="saveJobAndExit()">
|
<button type="button" class="btn btn-primary" onclick="saveJobAndExit()">
|
||||||
<svg viewBox="0 0 24 24"><path d="M17 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V7l-4-4zm-5 16c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm3-10H5V5h10v4z"/></svg>
|
<svg viewBox="0 0 24 24"><path d="M17 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V7l-4-4zm-5 16c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm3-10H5V5h10v4z"/></svg>
|
||||||
保存并退出(S)
|
保存并退出(S)
|
||||||
@@ -1335,6 +1339,10 @@
|
|||||||
<button class="nav-btn" title="最後一筆"><svg viewBox="0 0 24 24"><path d="M5.59 7.41L10.18 12l-4.59 4.59L7 18l6-6-6-6-1.41 1.41zM16 6h2v12h-2V6z"/></svg></button>
|
<button class="nav-btn" title="最後一筆"><svg viewBox="0 0 24 24"><path d="M5.59 7.41L10.18 12l-4.59 4.59L7 18l6-6-6-6-1.41 1.41zM16 6h2v12h-2V6z"/></svg></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
|
<button type="button" class="btn btn-success" onclick="saveDeptFunctionToPositionList()" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);">
|
||||||
|
<svg viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
|
||||||
|
儲存至崗位清單
|
||||||
|
</button>
|
||||||
<button class="btn btn-secondary" onclick="clearDeptFunctionForm()">清除</button>
|
<button class="btn btn-secondary" onclick="clearDeptFunctionForm()">清除</button>
|
||||||
<button class="btn btn-cancel" onclick="cancelDeptFunction()">取消</button>
|
<button class="btn btn-cancel" onclick="cancelDeptFunction()">取消</button>
|
||||||
<button class="btn btn-primary" onclick="saveDeptFunctionAndNew()">存檔續建</button>
|
<button class="btn btn-primary" onclick="saveDeptFunctionAndNew()">存檔續建</button>
|
||||||
@@ -1588,6 +1596,10 @@
|
|||||||
<button class="nav-btn" title="最後一筆"><svg viewBox="0 0 24 24"><path d="M5.59 7.41L10.18 12l-4.59 4.59L7 18l6-6-6-6-1.41 1.41zM16 6h2v12h-2V6z"/></svg></button>
|
<button class="nav-btn" title="最後一筆"><svg viewBox="0 0 24 24"><path d="M5.59 7.41L10.18 12l-4.59 4.59L7 18l6-6-6-6-1.41 1.41zM16 6h2v12h-2V6z"/></svg></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
|
<button type="button" class="btn btn-success" onclick="saveJobDescToPositionList()" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);">
|
||||||
|
<svg viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
|
||||||
|
儲存至崗位清單
|
||||||
|
</button>
|
||||||
<button type="button" class="btn btn-primary" onclick="saveJobDescAndExit()">
|
<button type="button" class="btn btn-primary" onclick="saveJobDescAndExit()">
|
||||||
<svg viewBox="0 0 24 24"><path d="M17 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V7l-4-4zm-5 16c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm3-10H5V5h10v4z"/></svg>
|
<svg viewBox="0 0 24 24"><path d="M17 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V7l-4-4zm-5 16c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm3-10H5V5h10v4z"/></svg>
|
||||||
保存并退出(S)
|
保存并退出(S)
|
||||||
@@ -2740,6 +2752,175 @@ ${contextInfo}
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function saveJobToPositionList() {
|
||||||
|
/**
|
||||||
|
* 職務基礎資料 -> 儲存至崗位清單
|
||||||
|
*/
|
||||||
|
const form = document.getElementById('jobForm');
|
||||||
|
if (!form.checkValidity()) {
|
||||||
|
form.reportValidity();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const formData = getJobFormData();
|
||||||
|
|
||||||
|
// 驗證必填欄位
|
||||||
|
if (!formData.jobCode) {
|
||||||
|
alert('請輸入職務代碼');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!formData.jobName) {
|
||||||
|
alert('請輸入職務名稱');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 將職務資料轉換為崗位資料格式
|
||||||
|
const positionData = {
|
||||||
|
basicInfo: {
|
||||||
|
positionCode: formData.jobCode,
|
||||||
|
positionName: formData.jobName,
|
||||||
|
positionCategory: formData.jobCategoryCode || '',
|
||||||
|
effectiveDate: formData.jobEffectiveDate || new Date().toISOString().split('T')[0],
|
||||||
|
headcount: formData.jobHeadcount || 1,
|
||||||
|
positionLevel: formData.jobLevel || '',
|
||||||
|
positionRemark: formData.jobRemark || ''
|
||||||
|
},
|
||||||
|
recruitInfo: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(API_BASE_URL + '/positions', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(positionData)
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
if (result.success) {
|
||||||
|
showToast(result.message || '職務已成功儲存至崗位清單!');
|
||||||
|
setTimeout(() => {
|
||||||
|
switchModule('positionlist');
|
||||||
|
}, 1500);
|
||||||
|
} else {
|
||||||
|
alert('儲存失敗: ' + (result.error || '未知錯誤'));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('儲存錯誤:', error);
|
||||||
|
alert('儲存失敗: ' + error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function saveDeptFunctionToPositionList() {
|
||||||
|
/**
|
||||||
|
* 部門職責 -> 儲存至崗位清單
|
||||||
|
*/
|
||||||
|
const deptCode = document.getElementById('dept_function_code').value;
|
||||||
|
const deptName = document.getElementById('dept_function_name').value;
|
||||||
|
const deptDesc = document.getElementById('dept_function_desc').value;
|
||||||
|
|
||||||
|
if (!deptCode) {
|
||||||
|
alert('請輸入部門職責編號');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!deptName) {
|
||||||
|
alert('請輸入部門職責名稱');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 將部門職責轉換為崗位資料格式
|
||||||
|
const positionData = {
|
||||||
|
basicInfo: {
|
||||||
|
positionCode: deptCode,
|
||||||
|
positionName: deptName,
|
||||||
|
effectiveDate: new Date().toISOString().split('T')[0],
|
||||||
|
positionDesc: deptDesc || '',
|
||||||
|
positionRemark: '從部門職責轉換'
|
||||||
|
},
|
||||||
|
recruitInfo: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(API_BASE_URL + '/positions', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(positionData)
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
if (result.success) {
|
||||||
|
showToast(result.message || '部門職責已成功儲存至崗位清單!');
|
||||||
|
setTimeout(() => {
|
||||||
|
switchModule('positionlist');
|
||||||
|
}, 1500);
|
||||||
|
} else {
|
||||||
|
alert('儲存失敗: ' + (result.error || '未知錯誤'));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('儲存錯誤:', error);
|
||||||
|
alert('儲存失敗: ' + error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function saveJobDescToPositionList() {
|
||||||
|
/**
|
||||||
|
* 崗位描述 -> 儲存至崗位清單
|
||||||
|
*/
|
||||||
|
const formData = getJobDescFormData();
|
||||||
|
|
||||||
|
// 驗證必填欄位
|
||||||
|
if (!formData.basicInfo.positionCode) {
|
||||||
|
alert('請輸入崗位代碼');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 將崗位描述轉換為崗位資料格式
|
||||||
|
const positionData = {
|
||||||
|
basicInfo: {
|
||||||
|
positionCode: formData.basicInfo.positionCode,
|
||||||
|
positionName: formData.positionInfo.positionName || '',
|
||||||
|
effectiveDate: formData.positionInfo.positionEffectiveDate || new Date().toISOString().split('T')[0],
|
||||||
|
positionDesc: formData.responsibilities.mainResponsibilities || '',
|
||||||
|
positionRemark: formData.responsibilities.positionPurpose || ''
|
||||||
|
},
|
||||||
|
recruitInfo: {
|
||||||
|
minEducation: formData.requirements.education || '',
|
||||||
|
skillReq: formData.requirements.basicSkills || '',
|
||||||
|
workExperience: formData.requirements.workExperienceReq || '',
|
||||||
|
otherReq: formData.requirements.otherRequirements || ''
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(API_BASE_URL + '/positions', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(positionData)
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
if (result.success) {
|
||||||
|
showToast(result.message || '崗位描述已成功儲存至崗位清單!');
|
||||||
|
setTimeout(() => {
|
||||||
|
switchModule('positionlist');
|
||||||
|
}, 1500);
|
||||||
|
} else {
|
||||||
|
alert('儲存失敗: ' + (result.error || '未知錯誤'));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('儲存錯誤:', error);
|
||||||
|
alert('儲存失敗: ' + error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function saveJobAndExit() {
|
function saveJobAndExit() {
|
||||||
const form = document.getElementById('jobForm');
|
const form = document.getElementById('jobForm');
|
||||||
if (!form.checkValidity()) { form.reportValidity(); return; }
|
if (!form.checkValidity()) { form.reportValidity(); return; }
|
||||||
|
|||||||
Reference in New Issue
Block a user