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>
This commit is contained in:
329
app.py
329
app.py
@@ -27,12 +27,23 @@ except ImportError:
|
||||
print("Warning: llm_config not found. LLM features will be disabled.")
|
||||
LLM_ENABLED = False
|
||||
|
||||
# Import hierarchy data
|
||||
try:
|
||||
from import_hierarchy_data import import_to_memory
|
||||
hierarchy_data = import_to_memory()
|
||||
HIERARCHY_ENABLED = True
|
||||
print("Hierarchy data loaded successfully.")
|
||||
except Exception as e:
|
||||
print(f"Warning: Could not load hierarchy data: {e}")
|
||||
hierarchy_data = None
|
||||
HIERARCHY_ENABLED = False
|
||||
|
||||
app = Flask(__name__, static_folder='.')
|
||||
app.config['JSON_AS_ASCII'] = False # 確保 JSON 正確處理中文
|
||||
CORS(app)
|
||||
|
||||
# 模擬資料庫 (實際應用中應使用 MySQL/PostgreSQL)
|
||||
positions_db = {}
|
||||
HR_position_positions_db = {}
|
||||
|
||||
# 預設崗位資料
|
||||
default_positions = {
|
||||
@@ -76,10 +87,10 @@ default_positions = {
|
||||
}
|
||||
}
|
||||
|
||||
positions_db.update(default_positions)
|
||||
HR_position_positions_db.update(default_positions)
|
||||
|
||||
# 職務資料庫
|
||||
jobs_db = {}
|
||||
HR_position_jobs_db = {}
|
||||
|
||||
# 預設職務資料
|
||||
default_jobs = {
|
||||
@@ -102,10 +113,10 @@ default_jobs = {
|
||||
}
|
||||
}
|
||||
|
||||
jobs_db.update(default_jobs)
|
||||
HR_position_jobs_db.update(default_jobs)
|
||||
|
||||
# 崗位描述資料庫
|
||||
position_descriptions_db = {}
|
||||
HR_position_descriptions_db = {}
|
||||
|
||||
# 預設崗位描述資料
|
||||
default_descriptions = {
|
||||
@@ -123,7 +134,7 @@ default_descriptions = {
|
||||
}
|
||||
}
|
||||
|
||||
position_descriptions_db.update(default_descriptions)
|
||||
HR_position_descriptions_db.update(default_descriptions)
|
||||
|
||||
|
||||
# ==================== 靜態頁面 ====================
|
||||
@@ -267,7 +278,7 @@ def import_positions_csv():
|
||||
continue
|
||||
|
||||
# 檢查是否已存在
|
||||
if position_code in positions_db:
|
||||
if position_code in HR_position_positions_db:
|
||||
errors.append(f"第 {row_num} 列: 崗位編號 {position_code} 已存在")
|
||||
error_count += 1
|
||||
continue
|
||||
@@ -313,7 +324,7 @@ def import_positions_csv():
|
||||
'updatedAt': now
|
||||
}
|
||||
|
||||
positions_db[position_code] = new_position
|
||||
HR_position_positions_db[position_code] = new_position
|
||||
success_count += 1
|
||||
|
||||
except Exception as e:
|
||||
@@ -349,7 +360,7 @@ def get_positions():
|
||||
search = request.args.get('search', '', type=str)
|
||||
|
||||
# 過濾搜尋
|
||||
filtered = list(positions_db.values())
|
||||
filtered = list(HR_position_positions_db.values())
|
||||
if search:
|
||||
filtered = [
|
||||
p for p in filtered
|
||||
@@ -378,7 +389,7 @@ def get_positions():
|
||||
@app.route('/api/positions/<position_id>', methods=['GET'])
|
||||
def get_position(position_id):
|
||||
"""獲取單一崗位資料"""
|
||||
if position_id not in positions_db:
|
||||
if position_id not in HR_position_positions_db:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '找不到該崗位資料'
|
||||
@@ -386,7 +397,7 @@ def get_position(position_id):
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'data': positions_db[position_id]
|
||||
'data': HR_position_positions_db[position_id]
|
||||
})
|
||||
|
||||
|
||||
@@ -425,7 +436,7 @@ def create_position():
|
||||
position_code = basic_info['positionCode']
|
||||
|
||||
# 檢查是否已存在
|
||||
if position_code in positions_db:
|
||||
if position_code in HR_position_positions_db:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': f'崗位編號 {position_code} 已存在'
|
||||
@@ -441,7 +452,7 @@ def create_position():
|
||||
'updatedAt': now
|
||||
}
|
||||
|
||||
positions_db[position_code] = new_position
|
||||
HR_position_positions_db[position_code] = new_position
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
@@ -465,7 +476,7 @@ def update_position(position_id):
|
||||
}
|
||||
"""
|
||||
try:
|
||||
if position_id not in positions_db:
|
||||
if position_id not in HR_position_positions_db:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '找不到該崗位資料'
|
||||
@@ -479,7 +490,7 @@ def update_position(position_id):
|
||||
}), 400
|
||||
|
||||
# 更新資料
|
||||
existing = positions_db[position_id]
|
||||
existing = HR_position_positions_db[position_id]
|
||||
|
||||
if 'basicInfo' in data:
|
||||
existing['basicInfo'].update(data['basicInfo'])
|
||||
@@ -505,13 +516,13 @@ def update_position(position_id):
|
||||
def delete_position(position_id):
|
||||
"""刪除崗位資料"""
|
||||
try:
|
||||
if position_id not in positions_db:
|
||||
if position_id not in HR_position_positions_db:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '找不到該崗位資料'
|
||||
}), 404
|
||||
|
||||
deleted = positions_db.pop(position_id)
|
||||
deleted = HR_position_positions_db.pop(position_id)
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
@@ -532,7 +543,7 @@ def change_position_code(position_id):
|
||||
Request body: { newCode: "新編號" }
|
||||
"""
|
||||
try:
|
||||
if position_id not in positions_db:
|
||||
if position_id not in HR_position_positions_db:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '找不到該崗位資料'
|
||||
@@ -547,19 +558,19 @@ def change_position_code(position_id):
|
||||
'error': '請提供新的崗位編號'
|
||||
}), 400
|
||||
|
||||
if new_code in positions_db:
|
||||
if new_code in HR_position_positions_db:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': f'崗位編號 {new_code} 已存在'
|
||||
}), 409
|
||||
|
||||
# 更新編號
|
||||
position = positions_db.pop(position_id)
|
||||
position = HR_position_positions_db.pop(position_id)
|
||||
position['id'] = new_code
|
||||
position['basicInfo']['positionCode'] = new_code
|
||||
position['updatedAt'] = datetime.now().isoformat()
|
||||
|
||||
positions_db[new_code] = position
|
||||
HR_position_positions_db[new_code] = position
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
@@ -662,7 +673,7 @@ def import_jobs_csv():
|
||||
continue
|
||||
|
||||
# 檢查是否已存在
|
||||
if job_code in jobs_db:
|
||||
if job_code in HR_position_jobs_db:
|
||||
errors.append(f"第 {row_num} 列: 職務編號 {job_code} 已存在")
|
||||
error_count += 1
|
||||
continue
|
||||
@@ -687,7 +698,7 @@ def import_jobs_csv():
|
||||
'updatedAt': now
|
||||
}
|
||||
|
||||
jobs_db[job_code] = new_job
|
||||
HR_position_jobs_db[job_code] = new_job
|
||||
success_count += 1
|
||||
|
||||
except Exception as e:
|
||||
@@ -725,7 +736,7 @@ def get_jobs():
|
||||
category = request.args.get('category', '', type=str)
|
||||
|
||||
# 過濾搜尋
|
||||
filtered = list(jobs_db.values())
|
||||
filtered = list(HR_position_jobs_db.values())
|
||||
if search:
|
||||
filtered = [
|
||||
j for j in filtered
|
||||
@@ -759,7 +770,7 @@ def get_jobs():
|
||||
@app.route('/api/jobs/<job_id>', methods=['GET'])
|
||||
def get_job(job_id):
|
||||
"""獲取單一職務資料"""
|
||||
if job_id not in jobs_db:
|
||||
if job_id not in HR_position_jobs_db:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '找不到該職務資料'
|
||||
@@ -767,7 +778,7 @@ def get_job(job_id):
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'data': jobs_db[job_id]
|
||||
'data': HR_position_jobs_db[job_id]
|
||||
})
|
||||
|
||||
|
||||
@@ -814,7 +825,7 @@ def create_job():
|
||||
job_code = data['jobCode']
|
||||
|
||||
# 檢查是否已存在
|
||||
if job_code in jobs_db:
|
||||
if job_code in HR_position_jobs_db:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': f'職務編號 {job_code} 已存在'
|
||||
@@ -829,7 +840,7 @@ def create_job():
|
||||
'updatedAt': now
|
||||
}
|
||||
|
||||
jobs_db[job_code] = new_job
|
||||
HR_position_jobs_db[job_code] = new_job
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
@@ -847,7 +858,7 @@ def create_job():
|
||||
def update_job(job_id):
|
||||
"""更新職務資料"""
|
||||
try:
|
||||
if job_id not in jobs_db:
|
||||
if job_id not in HR_position_jobs_db:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '找不到該職務資料'
|
||||
@@ -861,7 +872,7 @@ def update_job(job_id):
|
||||
}), 400
|
||||
|
||||
# 更新資料
|
||||
existing = jobs_db[job_id]
|
||||
existing = HR_position_jobs_db[job_id]
|
||||
existing.update(data)
|
||||
existing['updatedAt'] = datetime.now().isoformat()
|
||||
|
||||
@@ -881,13 +892,13 @@ def update_job(job_id):
|
||||
def delete_job(job_id):
|
||||
"""刪除職務資料"""
|
||||
try:
|
||||
if job_id not in jobs_db:
|
||||
if job_id not in HR_position_jobs_db:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '找不到該職務資料'
|
||||
}), 404
|
||||
|
||||
deleted = jobs_db.pop(job_id)
|
||||
deleted = HR_position_jobs_db.pop(job_id)
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
@@ -908,7 +919,7 @@ def change_job_code(job_id):
|
||||
Request body: { newCode: "新編號" }
|
||||
"""
|
||||
try:
|
||||
if job_id not in jobs_db:
|
||||
if job_id not in HR_position_jobs_db:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '找不到該職務資料'
|
||||
@@ -923,19 +934,19 @@ def change_job_code(job_id):
|
||||
'error': '請提供新的職務編號'
|
||||
}), 400
|
||||
|
||||
if new_code in jobs_db:
|
||||
if new_code in HR_position_jobs_db:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': f'職務編號 {new_code} 已存在'
|
||||
}), 409
|
||||
|
||||
# 更新編號
|
||||
job = jobs_db.pop(job_id)
|
||||
job = HR_position_jobs_db.pop(job_id)
|
||||
job['id'] = new_code
|
||||
job['jobCode'] = new_code
|
||||
job['updatedAt'] = datetime.now().isoformat()
|
||||
|
||||
jobs_db[new_code] = job
|
||||
HR_position_jobs_db[new_code] = job
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
@@ -1040,14 +1051,14 @@ def get_position_descriptions():
|
||||
"""獲取所有崗位描述"""
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'data': list(position_descriptions_db.values())
|
||||
'data': list(HR_position_descriptions_db.values())
|
||||
})
|
||||
|
||||
|
||||
@app.route('/api/position-descriptions/<position_code>', methods=['GET'])
|
||||
def get_position_description(position_code):
|
||||
"""獲取單一崗位描述"""
|
||||
if position_code not in position_descriptions_db:
|
||||
if position_code not in HR_position_descriptions_db:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '找不到該崗位描述'
|
||||
@@ -1055,7 +1066,7 @@ def get_position_description(position_code):
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'data': position_descriptions_db[position_code]
|
||||
'data': HR_position_descriptions_db[position_code]
|
||||
})
|
||||
|
||||
|
||||
@@ -1087,7 +1098,7 @@ def create_position_description():
|
||||
}), 400
|
||||
|
||||
# 檢查崗位是否存在(暫時註解,允許直接新增描述)
|
||||
# if position_code not in positions_db:
|
||||
# if position_code not in HR_position_positions_db:
|
||||
# return jsonify({
|
||||
# 'success': False,
|
||||
# 'error': f'崗位編號 {position_code} 不存在,請先建立崗位基礎資料'
|
||||
@@ -1096,14 +1107,14 @@ def create_position_description():
|
||||
now = datetime.now().isoformat()
|
||||
|
||||
# 如果已存在則更新,否則新增
|
||||
if position_code in position_descriptions_db:
|
||||
position_descriptions_db[position_code].update({
|
||||
if position_code in HR_position_descriptions_db:
|
||||
HR_position_descriptions_db[position_code].update({
|
||||
**data,
|
||||
'updatedAt': now
|
||||
})
|
||||
message = '崗位描述更新成功'
|
||||
else:
|
||||
position_descriptions_db[position_code] = {
|
||||
HR_position_descriptions_db[position_code] = {
|
||||
'id': position_code,
|
||||
**data,
|
||||
'createdAt': now,
|
||||
@@ -1114,7 +1125,7 @@ def create_position_description():
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'message': message,
|
||||
'data': position_descriptions_db[position_code]
|
||||
'data': HR_position_descriptions_db[position_code]
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
@@ -1128,7 +1139,7 @@ def create_position_description():
|
||||
def update_position_description(position_code):
|
||||
"""更新崗位描述"""
|
||||
try:
|
||||
if position_code not in position_descriptions_db:
|
||||
if position_code not in HR_position_descriptions_db:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '找不到該崗位描述'
|
||||
@@ -1141,7 +1152,7 @@ def update_position_description(position_code):
|
||||
'error': '請提供有效的 JSON 資料'
|
||||
}), 400
|
||||
|
||||
position_descriptions_db[position_code].update({
|
||||
HR_position_descriptions_db[position_code].update({
|
||||
**data,
|
||||
'updatedAt': datetime.now().isoformat()
|
||||
})
|
||||
@@ -1149,7 +1160,7 @@ def update_position_description(position_code):
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'message': '崗位描述更新成功',
|
||||
'data': position_descriptions_db[position_code]
|
||||
'data': HR_position_descriptions_db[position_code]
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
@@ -1163,13 +1174,13 @@ def update_position_description(position_code):
|
||||
def delete_position_description(position_code):
|
||||
"""刪除崗位描述"""
|
||||
try:
|
||||
if position_code not in position_descriptions_db:
|
||||
if position_code not in HR_position_descriptions_db:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '找不到該崗位描述'
|
||||
}), 404
|
||||
|
||||
deleted = position_descriptions_db.pop(position_code)
|
||||
deleted = HR_position_descriptions_db.pop(position_code)
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
@@ -1201,8 +1212,8 @@ def get_position_list():
|
||||
|
||||
# 組合崗位資料和描述
|
||||
combined_list = []
|
||||
for position_code, position in positions_db.items():
|
||||
description = position_descriptions_db.get(position_code, {})
|
||||
for position_code, position in HR_position_positions_db.items():
|
||||
description = HR_position_descriptions_db.get(position_code, {})
|
||||
|
||||
combined = {
|
||||
'positionCode': position_code,
|
||||
@@ -1214,7 +1225,7 @@ def get_position_list():
|
||||
'effectiveDate': position['basicInfo'].get('effectiveDate', ''),
|
||||
'minEducation': position['recruitInfo'].get('minEducation', ''),
|
||||
'salaryRange': position['recruitInfo'].get('salaryRange', ''),
|
||||
'hasDescription': position_code in position_descriptions_db,
|
||||
'hasDescription': position_code in HR_position_descriptions_db,
|
||||
'jobDuties': description.get('jobDuties', ''),
|
||||
'requiredSkills': description.get('requiredSkills', ''),
|
||||
'workEnvironment': description.get('workEnvironment', ''),
|
||||
@@ -1262,8 +1273,8 @@ def export_position_list():
|
||||
|
||||
# 組合所有崗位資料
|
||||
rows = []
|
||||
for position_code, position in positions_db.items():
|
||||
description = position_descriptions_db.get(position_code, {})
|
||||
for position_code, position in HR_position_positions_db.items():
|
||||
description = HR_position_descriptions_db.get(position_code, {})
|
||||
|
||||
row = [
|
||||
position_code,
|
||||
@@ -1477,6 +1488,198 @@ def generate_llm_text():
|
||||
}), 500
|
||||
|
||||
|
||||
# ==================== 組織階層 API ====================
|
||||
|
||||
@app.route('/api/hierarchy/business-units', methods=['GET'])
|
||||
def get_business_units():
|
||||
"""獲取所有事業體"""
|
||||
if not HIERARCHY_ENABLED:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '組織階層功能未啟用'
|
||||
}), 503
|
||||
|
||||
business_list = [
|
||||
{'id': v['id'], 'code': v['code'], 'name': v['name']}
|
||||
for v in hierarchy_data['business_units'].values()
|
||||
]
|
||||
business_list.sort(key=lambda x: x['id'])
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'data': business_list
|
||||
})
|
||||
|
||||
|
||||
@app.route('/api/hierarchy/divisions', methods=['GET'])
|
||||
def get_divisions():
|
||||
"""獲取處級單位,可按事業體篩選"""
|
||||
if not HIERARCHY_ENABLED:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '組織階層功能未啟用'
|
||||
}), 503
|
||||
|
||||
business_name = request.args.get('business', '', type=str)
|
||||
|
||||
if business_name:
|
||||
# 根據事業體篩選處級單位
|
||||
division_names = hierarchy_data['businessToDivision'].get(business_name, [])
|
||||
division_list = [
|
||||
hierarchy_data['divisions'][name]
|
||||
for name in division_names
|
||||
if name in hierarchy_data['divisions']
|
||||
]
|
||||
else:
|
||||
division_list = list(hierarchy_data['divisions'].values())
|
||||
|
||||
division_list.sort(key=lambda x: x['id'])
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'data': division_list
|
||||
})
|
||||
|
||||
|
||||
@app.route('/api/hierarchy/departments', methods=['GET'])
|
||||
def get_departments():
|
||||
"""獲取部級單位,可按處級單位篩選"""
|
||||
if not HIERARCHY_ENABLED:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '組織階層功能未啟用'
|
||||
}), 503
|
||||
|
||||
division_name = request.args.get('division', '', type=str)
|
||||
|
||||
if division_name:
|
||||
# 根據處級單位篩選部級單位
|
||||
dept_names = hierarchy_data['divisionToDepartment'].get(division_name, [])
|
||||
dept_list = [
|
||||
hierarchy_data['departments'][name]
|
||||
for name in dept_names
|
||||
if name in hierarchy_data['departments']
|
||||
]
|
||||
else:
|
||||
dept_list = list(hierarchy_data['departments'].values())
|
||||
|
||||
dept_list.sort(key=lambda x: x['id'])
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'data': dept_list
|
||||
})
|
||||
|
||||
|
||||
@app.route('/api/hierarchy/positions', methods=['GET'])
|
||||
def get_hierarchy_positions():
|
||||
"""獲取崗位名稱,可按部級單位篩選"""
|
||||
if not HIERARCHY_ENABLED:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '組織階層功能未啟用'
|
||||
}), 503
|
||||
|
||||
department_name = request.args.get('department', '', type=str)
|
||||
|
||||
if department_name:
|
||||
# 根據部級單位篩選崗位
|
||||
positions = hierarchy_data['departmentToPosition'].get(department_name, [])
|
||||
else:
|
||||
# 返回所有不重複的崗位名稱
|
||||
all_positions = set()
|
||||
for pos_list in hierarchy_data['departmentToPosition'].values():
|
||||
all_positions.update(pos_list)
|
||||
positions = sorted(list(all_positions))
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'data': positions
|
||||
})
|
||||
|
||||
|
||||
@app.route('/api/hierarchy/full', methods=['GET'])
|
||||
def get_full_hierarchy():
|
||||
"""獲取完整階層資料"""
|
||||
if not HIERARCHY_ENABLED:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '組織階層功能未啟用'
|
||||
}), 503
|
||||
|
||||
page = request.args.get('page', 1, type=int)
|
||||
size = request.args.get('size', 50, type=int)
|
||||
business = request.args.get('business', '', type=str)
|
||||
division = request.args.get('division', '', type=str)
|
||||
department = request.args.get('department', '', type=str)
|
||||
|
||||
# 篩選資料
|
||||
filtered = hierarchy_data['organization_positions']
|
||||
|
||||
if business:
|
||||
filtered = [r for r in filtered if r['business'] == business]
|
||||
if division:
|
||||
filtered = [r for r in filtered if r['division'] == division]
|
||||
if department:
|
||||
filtered = [r for r in filtered if r['department'] == department]
|
||||
|
||||
# 分頁
|
||||
total = len(filtered)
|
||||
start = (page - 1) * size
|
||||
end = start + size
|
||||
paginated = filtered[start:end]
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'data': paginated,
|
||||
'pagination': {
|
||||
'page': page,
|
||||
'size': size,
|
||||
'total': total,
|
||||
'totalPages': (total + size - 1) // size
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@app.route('/api/hierarchy/cascade', methods=['GET'])
|
||||
def get_cascade_data():
|
||||
"""獲取級聯選擇資料"""
|
||||
if not HIERARCHY_ENABLED:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '組織階層功能未啟用'
|
||||
}), 503
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'data': {
|
||||
'businessToDivision': hierarchy_data['businessToDivision'],
|
||||
'divisionToDepartment': hierarchy_data['divisionToDepartment'],
|
||||
'departmentToPosition': hierarchy_data['departmentToPosition']
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@app.route('/api/hierarchy/stats', methods=['GET'])
|
||||
def get_hierarchy_stats():
|
||||
"""獲取組織階層統計"""
|
||||
if not HIERARCHY_ENABLED:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': '組織階層功能未啟用'
|
||||
}), 503
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'data': {
|
||||
'businessUnitsCount': len(hierarchy_data['business_units']),
|
||||
'divisionsCount': len(hierarchy_data['divisions']),
|
||||
'departmentsCount': len(hierarchy_data['departments']),
|
||||
'organizationPositionsCount': len(hierarchy_data['organization_positions'])
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
# ==================== 錯誤處理 ====================
|
||||
|
||||
@app.errorhandler(404)
|
||||
@@ -1529,6 +1732,15 @@ if __name__ == '__main__':
|
||||
║ GET /api/llm/test-all - 測試所有 API ║
|
||||
║ POST /api/llm/generate - 生成文字 ║
|
||||
║ ║
|
||||
║ 組織階層 API: ║
|
||||
║ GET /api/hierarchy/business-units - 獲取事業體 ║
|
||||
║ GET /api/hierarchy/divisions - 獲取處級單位 ║
|
||||
║ GET /api/hierarchy/departments - 獲取部級單位 ║
|
||||
║ GET /api/hierarchy/positions - 獲取崗位名稱 ║
|
||||
║ GET /api/hierarchy/full - 完整階層資料 ║
|
||||
║ GET /api/hierarchy/cascade - 級聯選擇資料 ║
|
||||
║ GET /api/hierarchy/stats - 組織統計 ║
|
||||
║ ║
|
||||
║ 按 Ctrl+C 停止伺服器 ║
|
||||
╚══════════════════════════════════════════════════════════════╝
|
||||
""")
|
||||
@@ -1543,5 +1755,14 @@ if __name__ == '__main__':
|
||||
else:
|
||||
print("[!] LLM 功能未啟用 (llm_config.py 未找到)")
|
||||
|
||||
if HIERARCHY_ENABLED:
|
||||
print("[OK] 組織階層功能已啟用")
|
||||
print(f" - 事業體: {len(hierarchy_data['business_units'])} 筆")
|
||||
print(f" - 處級單位: {len(hierarchy_data['divisions'])} 筆")
|
||||
print(f" - 部級單位: {len(hierarchy_data['departments'])} 筆")
|
||||
print(f" - 組織崗位關聯: {len(hierarchy_data['organization_positions'])} 筆")
|
||||
else:
|
||||
print("[!] 組織階層功能未啟用")
|
||||
|
||||
print()
|
||||
app.run(host='0.0.0.0', port=5000, debug=True)
|
||||
|
||||
Reference in New Issue
Block a user