Files
hr-position-system/improve_error_display.py
DonaldFang 方士碩 b2584772c4 feat: 新增崗位描述與清單整合功能 v2.1
主要功能更新:
- 崗位描述保存功能:保存後資料寫入資料庫
- 崗位清單自動刷新:切換模組時自動載入最新資料
- 崗位清單檢視功能:點擊「檢視」按鈕載入對應描述
- 管理者頁面擴充:新增崗位資料管理與匯出功能
- 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>
2025-12-04 12:46:36 +08:00

253 lines
10 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
改進錯誤訊息顯示 - 使錯誤訊息可完整顯示和複製
"""
with open('index.html', 'r', encoding='utf-8') as f:
content = f.read()
# 備份
with open('index.html.backup2', 'w', encoding='utf-8') as f:
f.write(content)
# 找到錯誤處理的 alert 並替換為更好的顯示方式
old_error_handling = ''' } catch (error) {
console.error("Error calling LLM API:", error);
alert(`AI 生成錯誤: ${error.message}\\n\\n請確保\\n1. Flask 後端已啟動 (python app_updated.py)\\n2. 已在 .env 文件中配置 LLM API Key\\n3. 網路連線正常`);
throw error;
}'''
new_error_handling = ''' } catch (error) {
console.error("Error calling LLM API:", error);
// 嘗試解析更詳細的錯誤訊息
let errorDetails = error.message;
try {
// 如果錯誤訊息是 JSON 格式,嘗試美化顯示
const errorJson = JSON.parse(error.message);
errorDetails = JSON.stringify(errorJson, null, 2);
} catch (e) {
// 不是 JSON使用原始訊息
}
// 創建可複製的錯誤對話框
showCopyableError({
title: 'AI 生成錯誤',
message: error.message,
details: errorDetails,
suggestions: [
'Flask 後端已啟動 (python start_server.py)',
'已在 .env 文件中配置有效的 LLM API Key',
'網路連線正常',
'嘗試使用不同的 LLM API (DeepSeek 或 OpenAI)'
]
});
throw error;
}'''
# 替換
new_content = content.replace(old_error_handling, new_error_handling)
if new_content == content:
print("WARNING: Pattern not found, content not changed")
else:
print("SUCCESS: Error handling improved")
# 添加 showCopyableError 函數(如果還沒有)
if 'function showCopyableError' not in new_content:
# 在 </script> 前添加新函數
error_display_function = '''
// 顯示可複製的錯誤訊息
function showCopyableError(options) {
const { title, message, details, suggestions } = options;
// 創建對話框
const modal = document.createElement('div');
modal.style.cssText = `
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.7);
display: flex;
align-items: center;
justify-content: center;
z-index: 10000;
animation: fadeIn 0.3s;
`;
modal.innerHTML = `
<div style="
background: white;
border-radius: 12px;
max-width: 600px;
width: 90%;
max-height: 80vh;
overflow: hidden;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
display: flex;
flex-direction: column;
">
<!-- Header -->
<div style="
background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%);
color: white;
padding: 20px;
display: flex;
align-items: center;
gap: 15px;
">
<span style="font-size: 2rem;">❌</span>
<h3 style="margin: 0; font-size: 1.3rem; flex: 1;">${title}</h3>
<button onclick="this.closest('[style*=\\'position: fixed\\']').remove()" style="
background: rgba(255,255,255,0.2);
border: none;
color: white;
width: 30px;
height: 30px;
border-radius: 50%;
cursor: pointer;
font-size: 1.2rem;
display: flex;
align-items: center;
justify-content: center;
">×</button>
</div>
<!-- Body -->
<div style="
padding: 25px;
overflow-y: auto;
flex: 1;
">
<div style="
color: #333;
line-height: 1.6;
margin-bottom: 20px;
font-size: 1rem;
">${message}</div>
${suggestions && suggestions.length > 0 ? `
<div style="
background: #fff3cd;
border: 1px solid #ffc107;
border-radius: 6px;
padding: 15px;
margin-bottom: 20px;
">
<strong style="color: #856404; display: block; margin-bottom: 10px;">💡 請確保:</strong>
<ul style="margin: 0; padding-left: 20px; color: #856404;">
${suggestions.map(s => `<li style="margin: 5px 0;">${s}</li>`).join('')}
</ul>
</div>
` : ''}
${details ? `
<details style="
background: #f8f9fa;
border: 1px solid #dee2e6;
border-radius: 6px;
padding: 15px;
">
<summary style="
cursor: pointer;
font-weight: 600;
color: #495057;
user-select: none;
margin-bottom: 10px;
">🔍 詳細錯誤訊息(點擊展開)</summary>
<pre id="errorDetailsText" style="
background: white;
padding: 15px;
border-radius: 4px;
overflow-x: auto;
font-size: 0.85rem;
color: #666;
margin: 10px 0 0 0;
white-space: pre-wrap;
word-break: break-word;
max-height: 300px;
overflow-y: auto;
">${details}</pre>
<button onclick="copyErrorDetails()" style="
background: #007bff;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
margin-top: 10px;
font-size: 0.9rem;
">📋 複製錯誤訊息</button>
</details>
` : ''}
</div>
<!-- Footer -->
<div style="
padding: 15px 25px;
border-top: 1px solid #f0f0f0;
display: flex;
justify-content: flex-end;
gap: 10px;
">
<button onclick="this.closest('[style*=\\'position: fixed\\']').remove()" style="
background: #007bff;
color: white;
border: none;
padding: 10px 25px;
border-radius: 6px;
cursor: pointer;
font-size: 0.95rem;
font-weight: 500;
">確定</button>
</div>
</div>
`;
document.body.appendChild(modal);
// 點擊背景關閉
modal.addEventListener('click', (e) => {
if (e.target === modal) {
modal.remove();
}
});
}
// 複製錯誤訊息到剪貼板
function copyErrorDetails() {
const text = document.getElementById('errorDetailsText').textContent;
navigator.clipboard.writeText(text).then(() => {
alert('錯誤訊息已複製到剪貼板!');
}).catch(err => {
// Fallback: 選取文字
const range = document.createRange();
range.selectNode(document.getElementById('errorDetailsText'));
window.getSelection().removeAllRanges();
window.getSelection().addRange(range);
try {
document.execCommand('copy');
alert('錯誤訊息已複製到剪貼板!');
} catch (e) {
alert('複製失敗,請手動選取並複製');
}
});
}
'''
new_content = new_content.replace(' </script>', error_display_function + '\n </script>')
print("Added showCopyableError function")
# 寫回
with open('index.html', 'w', encoding='utf-8') as f:
f.write(new_content)
print("\nDone! Improvements:")
print("1. Error messages now show in a modal dialog")
print("2. Full error details are expandable")
print("3. Error details can be copied to clipboard")
print("4. Better formatting and readability")
print("\nPlease reload the page (Ctrl+F5) to see the changes")