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>
This commit is contained in:
110
quick_fix.py
Normal file
110
quick_fix.py
Normal file
@@ -0,0 +1,110 @@
|
||||
import re
|
||||
|
||||
with open('index.html', 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
# 備份
|
||||
with open('index.html.backup', 'w', encoding='utf-8') as f:
|
||||
f.write(content)
|
||||
print("Backup created: index.html.backup")
|
||||
|
||||
# 舊代碼
|
||||
old = ''' async function callClaudeAPI(prompt) {
|
||||
try {
|
||||
const response = await fetch("https://api.anthropic.com/v1/messages", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: "claude-sonnet-4-20250514",
|
||||
max_tokens: 2000,
|
||||
messages: [
|
||||
{ role: "user", content: prompt }
|
||||
]
|
||||
})
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`API request failed: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
let responseText = data.content[0].text;
|
||||
responseText = responseText.replace(/```json\\n?/g, "").replace(/```\\n?/g, "").trim();
|
||||
return JSON.parse(responseText);
|
||||
} catch (error) {
|
||||
console.error("Error calling Claude API:", error);
|
||||
throw error;
|
||||
}
|
||||
}'''
|
||||
|
||||
# 新代碼
|
||||
new = ''' async function callClaudeAPI(prompt, api = 'gemini') {
|
||||
try {
|
||||
// 調用後端 Flask API,避免 CORS 錯誤
|
||||
const response = await fetch("/api/llm/generate", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
api: api,
|
||||
prompt: prompt,
|
||||
max_tokens: 2000
|
||||
})
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json();
|
||||
throw new Error(errorData.error || `API 請求失敗: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (!data.success) {
|
||||
throw new Error(data.error || 'API 調用失敗');
|
||||
}
|
||||
|
||||
let responseText = data.text;
|
||||
responseText = responseText.replace(/```json\\n?/g, "").replace(/```\\n?/g, "").trim();
|
||||
return JSON.parse(responseText);
|
||||
} 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_content = content.replace(old, new)
|
||||
|
||||
if new_content == content:
|
||||
print("ERROR: Pattern not found, trying alternative method...")
|
||||
# 使用更簡單的替換
|
||||
new_content = content.replace(
|
||||
'const response = await fetch("https://api.anthropic.com/v1/messages", {',
|
||||
'const response = await fetch("/api/llm/generate", {'
|
||||
)
|
||||
new_content = new_content.replace(
|
||||
'async function callClaudeAPI(prompt) {',
|
||||
'async function callClaudeAPI(prompt, api = \'gemini\') {'
|
||||
)
|
||||
|
||||
if new_content != content:
|
||||
print("SUCCESS: Applied simple replacement")
|
||||
else:
|
||||
print("ERROR: Could not fix the file")
|
||||
exit(1)
|
||||
else:
|
||||
print("SUCCESS: Pattern replaced")
|
||||
|
||||
# 寫回
|
||||
with open('index.html', 'w', encoding='utf-8') as f:
|
||||
f.write(new_content)
|
||||
|
||||
print("File updated: index.html")
|
||||
print("\nNext steps:")
|
||||
print("1. Start Flask backend: python app_updated.py")
|
||||
print("2. Reload browser page (Ctrl+F5)")
|
||||
print("3. Test AI generation")
|
||||
Reference in New Issue
Block a user