This commit is contained in:
2026-02-17 12:29:20 +08:00
parent f6c361dd13
commit 0ab6f52525
4 changed files with 132 additions and 29 deletions

View File

@@ -47,6 +47,9 @@
<a href="#" @click.prevent="currentTab = 'files'" :class="{'bg-blue-600': currentTab === 'files', 'hover:bg-slate-700': currentTab !== 'files'}" class="block py-2.5 px-4 rounded transition duration-200">
<i class="fas fa-folder-open w-6"></i> 文件管理
</a>
<a href="#" @click.prevent="currentTab = 'prompts'" :class="{'bg-blue-600': currentTab === 'prompts', 'hover:bg-slate-700': currentTab !== 'prompts'}" class="block py-2.5 px-4 rounded transition duration-200">
<i class="fas fa-comment-dots w-6"></i> 提示词管理
</a>
<a href="#" @click.prevent="currentTab = 'settings'" :class="{'bg-blue-600': currentTab === 'settings', 'hover:bg-slate-700': currentTab !== 'settings'}" class="block py-2.5 px-4 rounded transition duration-200">
<i class="fas fa-cogs w-6"></i> 系统设置
</a>
@@ -164,6 +167,26 @@
</div>
</div>
<!-- 提示词管理 Prompts -->
<div v-if="currentTab === 'prompts'">
<h2 class="text-2xl font-bold mb-6 text-gray-800 border-b pb-2">提示词管理</h2>
<div class="grid grid-cols-1 gap-6">
<div v-for="(content, key) in prompts" :key="key" class="bg-white rounded-lg shadow p-6">
<div class="flex justify-between items-center mb-4">
<h3 class="text-lg font-bold text-gray-700 flex items-center gap-2">
<span class="bg-blue-100 text-blue-800 text-xs font-medium px-2.5 py-0.5 rounded border border-blue-400 font-mono">{{ key }}</span>
<span class="text-sm font-normal text-gray-500">{{ getPromptDescription(key) }}</span>
</h3>
<button @click="savePrompt(key)" class="bg-green-500 hover:bg-green-600 text-white font-bold py-1 px-3 rounded text-sm transition">
<i class="fas fa-save mr-1"></i> 保存
</button>
</div>
<textarea v-model="prompts[key]" rows="6" class="w-full p-3 border rounded font-mono text-sm bg-gray-50 focus:bg-white focus:outline-none focus:ring-2 focus:ring-blue-500 transition"></textarea>
</div>
</div>
</div>
<!-- 系统设置 Settings -->
<div v-if="currentTab === 'settings'">
<h2 class="text-2xl font-bold mb-6 text-gray-800 border-b pb-2">系统设置</h2>
@@ -266,6 +289,7 @@
lifetime: 3600,
interval: 600
});
const prompts = ref({});
// 检查登录状态
const checkLogin = () => {
@@ -288,6 +312,7 @@
loginError.value = '';
fetchHistory();
fetchSystemInfo();
fetchPrompts();
}
} catch (e) {
loginError.value = '密码错误';
@@ -347,6 +372,38 @@
}
};
const fetchPrompts = async () => {
try {
const res = await axios.get('/admin/api/prompts');
prompts.value = res.data;
} catch (e) {
console.error(e);
}
};
const savePrompt = async (key) => {
try {
const formData = new FormData();
formData.append('key', key);
formData.append('content', prompts.value[key]);
const res = await axios.post('/admin/api/prompts', formData);
alert(res.data.message);
} catch (e) {
alert('保存失败: ' + (e.response?.data?.detail || e.message));
}
};
const getPromptDescription = (key) => {
const map = {
'translate': 'Prompt 翻译 (中文 -> 英文)',
'tarot_card_dual': '塔罗牌识别 (正/逆位对比模式)',
'tarot_card_single': '塔罗牌识别 (单图模式)',
'tarot_spread': '塔罗牌阵识别',
'face_analysis': '人脸/属性分析 (Qwen-VL)'
};
return map[key] || '';
};
const updateModel = async () => {
try {
const formData = new FormData();
@@ -439,6 +496,7 @@
Vue.watch(currentTab, (newTab) => {
if (newTab === 'files') fetchFiles();
if (newTab === 'dashboard') fetchHistory();
if (newTab === 'prompts') fetchPrompts();
});
onMounted(() => {
@@ -452,7 +510,8 @@
viewResult, previewImage, isImage, previewUrl,
formatDate, getTypeBadgeClass, cleaning, deviceInfo,
currentModel, availableModels, updateModel,
cleanupConfig, saveCleanupConfig
cleanupConfig, saveCleanupConfig,
prompts, fetchPrompts, savePrompt, getPromptDescription
};
}
}).mount('#app');