refactor llm config
This commit is contained in:
@@ -19,6 +19,7 @@ const socketStore = useSocketStore()
|
||||
|
||||
const showMenu = ref(false)
|
||||
const isManualPaused = ref(false)
|
||||
const menuDefaultTab = ref<'save' | 'load' | 'create' | 'delete' | 'llm'>('load')
|
||||
|
||||
onMounted(async () => {
|
||||
// 初始化 Socket 连接
|
||||
@@ -28,6 +29,15 @@ onMounted(async () => {
|
||||
window.addEventListener('keydown', handleKeydown)
|
||||
})
|
||||
|
||||
// 导出方法供 socket store 调用
|
||||
function openLLMConfig() {
|
||||
menuDefaultTab.value = 'llm'
|
||||
showMenu.value = true
|
||||
}
|
||||
|
||||
// 暴露给全局以便 socket store 可以调用
|
||||
;(window as any).__openLLMConfig = openLLMConfig
|
||||
|
||||
onUnmounted(() => {
|
||||
socketStore.disconnect()
|
||||
window.removeEventListener('keydown', handleKeydown)
|
||||
@@ -115,7 +125,8 @@ watch([showMenu, isManualPaused], ([menuVisible, manualPaused]) => {
|
||||
</div>
|
||||
|
||||
<SystemMenu
|
||||
:visible="showMenu"
|
||||
:visible="showMenu"
|
||||
:default-tab="menuDefaultTab"
|
||||
@close="handleMenuClose"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -8,11 +8,13 @@ const API_BASE = import.meta.env.VITE_API_TARGET || '';
|
||||
|
||||
export class ApiError extends Error {
|
||||
public status: number;
|
||||
public response: { data: any };
|
||||
|
||||
constructor(status: number, message: string) {
|
||||
constructor(status: number, message: string, responseData?: any) {
|
||||
super(message);
|
||||
this.status = status;
|
||||
this.name = 'ApiError';
|
||||
this.response = { data: responseData || {} };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +23,21 @@ async function request<T>(path: string, options: RequestInit = {}): Promise<T> {
|
||||
const response = await fetch(url, options);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new ApiError(response.status, `Request failed: ${response.statusText}`);
|
||||
// 尝试解析错误响应的 JSON
|
||||
let errorData = null;
|
||||
let errorMessage = `Request failed: ${response.statusText}`;
|
||||
|
||||
try {
|
||||
errorData = await response.json();
|
||||
// 如果后端返回了 detail 字段,使用它作为错误消息
|
||||
if (errorData?.detail) {
|
||||
errorMessage = errorData.detail;
|
||||
}
|
||||
} catch {
|
||||
// 如果解析失败,使用默认错误消息
|
||||
}
|
||||
|
||||
throw new ApiError(response.status, errorMessage, errorData);
|
||||
}
|
||||
|
||||
// 假设后端总是返回 JSON
|
||||
|
||||
@@ -7,29 +7,36 @@ import LLMConfigPanel from './game/panels/system/LLMConfigPanel.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
visible: boolean
|
||||
defaultTab?: 'save' | 'load' | 'create' | 'delete' | 'llm'
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'close'): void
|
||||
}>()
|
||||
|
||||
const activeTab = ref<'save' | 'load' | 'create' | 'delete' | 'llm'>('load')
|
||||
const activeTab = ref<'save' | 'load' | 'create' | 'delete' | 'llm'>(props.defaultTab || 'load')
|
||||
|
||||
function switchTab(tab: typeof activeTab.value) {
|
||||
activeTab.value = tab
|
||||
}
|
||||
|
||||
// Reset tab when reopening
|
||||
// 监听 defaultTab 变化
|
||||
watch(() => props.defaultTab, (newTab) => {
|
||||
if (newTab) {
|
||||
activeTab.value = newTab
|
||||
}
|
||||
})
|
||||
|
||||
// 当菜单打开时,如果有 defaultTab 就使用它
|
||||
watch(() => props.visible, (val) => {
|
||||
if (val) {
|
||||
// Do not reset activeTab to keep user context, or reset if preferred
|
||||
// activeTab.value = 'load'
|
||||
if (val && props.defaultTab) {
|
||||
activeTab.value = props.defaultTab
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="visible" class="system-menu-overlay" @click.self="emit('close')">
|
||||
<div v-if="visible" class="system-menu-overlay">
|
||||
<div class="system-menu">
|
||||
<div class="menu-header">
|
||||
<h2>系统菜单</h2>
|
||||
|
||||
@@ -42,6 +42,37 @@ export const useSocketStore = defineStore('socket', () => {
|
||||
uiStore.refreshDetail();
|
||||
}
|
||||
}
|
||||
// ===== 处理 LLM 配置要求消息 =====
|
||||
else if (data.type === 'llm_config_required') {
|
||||
console.warn('LLM 配置要求:', data.error);
|
||||
|
||||
// 显示错误提示
|
||||
const message = data.error || 'LLM 连接失败,请配置';
|
||||
|
||||
// 通过全局方法打开 LLM 配置界面
|
||||
if ((window as any).__openLLMConfig) {
|
||||
(window as any).__openLLMConfig();
|
||||
}
|
||||
|
||||
// 可以选择在这里显示一个提示消息
|
||||
// 需要引入 message API 或者通过其他方式
|
||||
setTimeout(() => {
|
||||
alert(`${message}\n\n请在打开的配置界面中完成 LLM 设置。`);
|
||||
}, 500);
|
||||
}
|
||||
// ===== 处理游戏重新初始化消息 =====
|
||||
else if (data.type === 'game_reinitialized') {
|
||||
console.log('游戏重新初始化:', data.message);
|
||||
|
||||
// 刷新世界状态
|
||||
worldStore.initialize().catch(console.error);
|
||||
|
||||
// 显示成功提示
|
||||
setTimeout(() => {
|
||||
alert(data.message || 'LLM 配置成功,游戏已重新初始化');
|
||||
}, 300);
|
||||
}
|
||||
// ===== LLM 消息处理结束 =====
|
||||
});
|
||||
|
||||
// Connect socket
|
||||
|
||||
Reference in New Issue
Block a user