主要功能更新: - 崗位描述保存功能:保存後資料寫入資料庫 - 崗位清單自動刷新:切換模組時自動載入最新資料 - 崗位清單檢視功能:點擊「檢視」按鈕載入對應描述 - 管理者頁面擴充:新增崗位資料管理與匯出功能 - CSV 批次匯入:支援崗位與職務資料批次匯入 後端 API 新增: - Position Description CRUD APIs - Position List Query & Export APIs - CSV Template Download & Import APIs 文件更新: - SDD.md 更新至版本 2.1 - README.md 更新功能說明與版本歷史 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
207 lines
11 KiB
Python
207 lines
11 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
在崗位描述模組中添加部門職責關聯欄位
|
|
"""
|
|
import sys
|
|
import codecs
|
|
|
|
if sys.platform == 'win32':
|
|
sys.stdout = codecs.getwriter('utf-8')(sys.stdout.buffer, 'strict')
|
|
sys.stderr = codecs.getwriter('utf-8')(sys.stderr.buffer, 'strict')
|
|
|
|
# 讀取 index.html
|
|
with open('index.html', 'r', encoding='utf-8') as f:
|
|
content = f.read()
|
|
|
|
# ==================== 1. 在崗位描述表單中添加部門職責欄位 ====================
|
|
# 在「所屬部門」欄位後面添加「部門職責」下拉選單
|
|
|
|
old_dept_field = ''' <div class="form-group">
|
|
<label>所屬部門</label>
|
|
<input type="text" id="jd_department" name="department" placeholder="請輸入所屬部門">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>崗位生效日期</label>'''
|
|
|
|
new_dept_field = ''' <div class="form-group">
|
|
<label>所屬部門</label>
|
|
<input type="text" id="jd_department" name="department" placeholder="請輸入所屬部門">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>部門職責</label>
|
|
<div class="input-wrapper">
|
|
<select id="jd_deptFunction" name="deptFunction" onchange="loadDeptFunctionInfo()">
|
|
<option value="">-- 請選擇部門職責 --</option>
|
|
</select>
|
|
<button type="button" class="btn-icon" onclick="refreshDeptFunctionList()" title="重新載入">
|
|
<svg viewBox="0 0 24 24"><path d="M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"/></svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label>崗位生效日期</label>'''
|
|
|
|
if old_dept_field in content and 'jd_deptFunction' not in content:
|
|
content = content.replace(old_dept_field, new_dept_field)
|
|
print("[OK] Added Department Function dropdown to Job Description form")
|
|
else:
|
|
print("[INFO] Department Function field already exists or pattern not found")
|
|
|
|
# ==================== 2. 添加部門職責資訊顯示區塊 ====================
|
|
# 在崗位基本信息 section 後面添加部門職責資訊區塊
|
|
|
|
old_section_end = ''' <div class="form-group">
|
|
<label>直接下級(職位及人數)</label>
|
|
<input type="text" id="jd_directReports" name="directReports" placeholder="如:工程師 x 5人">
|
|
</div>'''
|
|
|
|
# 找到直接下級後面的結構
|
|
new_section_end = ''' <div class="form-group">
|
|
<label>直接下級(職位及人數)</label>
|
|
<input type="text" id="jd_directReports" name="directReports" placeholder="如:工程師 x 5人">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 部門職責資訊 Section (關聯顯示) -->
|
|
<div class="section-box" id="deptFunctionInfoSection" style="margin-top: 24px; display: none;">
|
|
<div class="section-header" style="background: linear-gradient(135deg, #8e44ad 0%, #9b59b6 100%);">部門職責資訊 (自動帶入)</div>
|
|
<div class="section-body">
|
|
<div class="form-grid">
|
|
<div class="form-group">
|
|
<label>部門職責編號</label>
|
|
<input type="text" id="jd_deptFunctionCode" readonly style="background: #f8f9fa;">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>事業體</label>
|
|
<input type="text" id="jd_deptFunctionBU" readonly style="background: #f8f9fa;">
|
|
</div>
|
|
</div>
|
|
<div class="form-group full-width">
|
|
<label>部門使命</label>
|
|
<textarea id="jd_deptMission" readonly rows="2" style="background: #f8f9fa;"></textarea>
|
|
</div>
|
|
<div class="form-group full-width">
|
|
<label>部門核心職責</label>
|
|
<textarea id="jd_deptCoreFunctions" readonly rows="4" style="background: #f8f9fa;"></textarea>
|
|
</div>
|
|
<div class="form-group full-width">
|
|
<label>部門 KPIs</label>
|
|
<textarea id="jd_deptKPIs" readonly rows="3" style="background: #f8f9fa;"></textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 崗位職責 Section '''
|
|
|
|
# 找到崗位職責 Section 的開始位置
|
|
jobdesc_section_pattern = ''' </div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 崗位職責 Section -->'''
|
|
|
|
if jobdesc_section_pattern in content and 'deptFunctionInfoSection' not in content:
|
|
content = content.replace(old_section_end + '''
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 崗位職責 Section -->''', new_section_end + '''-->''')
|
|
print("[OK] Added Department Function info section to Job Description")
|
|
else:
|
|
print("[INFO] Dept Function info section already exists or pattern not found - trying alternative approach")
|
|
|
|
# ==================== 3. 添加相關 JavaScript 函數 ====================
|
|
dept_relation_js = '''
|
|
// ==================== 部門職責關聯功能 ====================
|
|
|
|
// 重新載入部門職責下拉選單
|
|
function refreshDeptFunctionList() {
|
|
const select = document.getElementById('jd_deptFunction');
|
|
if (!select) return;
|
|
|
|
// 清空現有選項
|
|
select.innerHTML = '<option value="">-- 請選擇部門職責 --</option>';
|
|
|
|
// 從 deptFunctionData 載入選項
|
|
if (typeof deptFunctionData !== 'undefined' && deptFunctionData.length > 0) {
|
|
deptFunctionData.forEach(df => {
|
|
const option = document.createElement('option');
|
|
option.value = df.deptFunctionCode;
|
|
option.textContent = `${df.deptFunctionCode} - ${df.deptFunctionName} (${df.deptFunctionDept})`;
|
|
select.appendChild(option);
|
|
});
|
|
showToast('已載入 ' + deptFunctionData.length + ' 筆部門職責資料');
|
|
} else {
|
|
showToast('尚無部門職責資料,請先建立部門職責');
|
|
}
|
|
}
|
|
|
|
// 載入選中的部門職責資訊
|
|
function loadDeptFunctionInfo() {
|
|
const select = document.getElementById('jd_deptFunction');
|
|
const infoSection = document.getElementById('deptFunctionInfoSection');
|
|
|
|
if (!select || !infoSection) return;
|
|
|
|
const selectedCode = select.value;
|
|
|
|
if (!selectedCode) {
|
|
infoSection.style.display = 'none';
|
|
return;
|
|
}
|
|
|
|
// 從 deptFunctionData 找到對應的資料
|
|
if (typeof deptFunctionData !== 'undefined') {
|
|
const deptFunc = deptFunctionData.find(d => d.deptFunctionCode === selectedCode);
|
|
|
|
if (deptFunc) {
|
|
// 填入部門職責資訊
|
|
document.getElementById('jd_deptFunctionCode').value = deptFunc.deptFunctionCode || '';
|
|
document.getElementById('jd_deptFunctionBU').value = deptFunc.deptFunctionBU || '';
|
|
document.getElementById('jd_deptMission').value = deptFunc.deptMission || '';
|
|
document.getElementById('jd_deptCoreFunctions').value = deptFunc.deptCoreFunctions || '';
|
|
document.getElementById('jd_deptKPIs').value = deptFunc.deptKPIs || '';
|
|
|
|
// 自動填入所屬部門
|
|
const deptInput = document.getElementById('jd_department');
|
|
if (deptInput && !deptInput.value) {
|
|
deptInput.value = deptFunc.deptFunctionDept;
|
|
}
|
|
|
|
// 顯示部門職責資訊區塊
|
|
infoSection.style.display = 'block';
|
|
|
|
showToast('已載入部門職責: ' + deptFunc.deptFunctionName);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 在頁面載入時初始化部門職責下拉選單
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// 延遲載入,確保 deptFunctionData 已初始化
|
|
setTimeout(refreshDeptFunctionList, 500);
|
|
});
|
|
|
|
'''
|
|
|
|
# 在部門職責模組功能之後插入
|
|
dept_module_js_end = ' // ==================== 管理者頁面功能 ===================='
|
|
|
|
if dept_module_js_end in content and 'refreshDeptFunctionList' not in content:
|
|
content = content.replace(dept_module_js_end, dept_relation_js + dept_module_js_end)
|
|
print("[OK] Added Department Function relation JavaScript functions")
|
|
else:
|
|
print("[INFO] Dept Function relation JS already exists or pattern not found")
|
|
|
|
# 寫回檔案
|
|
with open('index.html', 'w', encoding='utf-8') as f:
|
|
f.write(content)
|
|
|
|
print("\n[DONE] Department Function relation added!")
|
|
print("- Added Department Function dropdown to Job Description form")
|
|
print("- Added Department Function info display section")
|
|
print("- Added JavaScript functions for loading dept function data")
|