mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-08-11 21:30:59 +00:00
feat: 异常处理
This commit is contained in:
@@ -28,6 +28,9 @@ class SettingsRouterGroup(group.RouterGroup):
|
|||||||
|
|
||||||
manager = self.ap.settings_mgr.get_manager(manager_name)
|
manager = self.ap.settings_mgr.get_manager(manager_name)
|
||||||
|
|
||||||
|
if manager is None:
|
||||||
|
return self.fail(1, '配置管理器不存在')
|
||||||
|
|
||||||
return self.success(
|
return self.success(
|
||||||
data={
|
data={
|
||||||
"manager": {
|
"manager": {
|
||||||
@@ -44,6 +47,10 @@ class SettingsRouterGroup(group.RouterGroup):
|
|||||||
async def _(manager_name: str) -> str:
|
async def _(manager_name: str) -> str:
|
||||||
data = await quart.request.json
|
data = await quart.request.json
|
||||||
manager = self.ap.settings_mgr.get_manager(manager_name)
|
manager = self.ap.settings_mgr.get_manager(manager_name)
|
||||||
|
|
||||||
|
if manager is None:
|
||||||
|
return self.fail(code=1, msg='配置管理器不存在')
|
||||||
|
|
||||||
# manager.data = data['data']
|
# manager.data = data['data']
|
||||||
for k, v in data['data'].items():
|
for k, v in data['data'].items():
|
||||||
manager.data[k] = v
|
manager.data[k] = v
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ class SettingsManager:
|
|||||||
manager.schema = schema
|
manager.schema = schema
|
||||||
self.managers.append(manager)
|
self.managers.append(manager)
|
||||||
|
|
||||||
def get_manager(self, name: str) -> config_manager.ConfigManager:
|
def get_manager(self, name: str) -> config_manager.ConfigManager | None:
|
||||||
"""获取配置管理器
|
"""获取配置管理器
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -60,7 +60,7 @@ class SettingsManager:
|
|||||||
if m.name == name:
|
if m.name == name:
|
||||||
return m
|
return m
|
||||||
|
|
||||||
raise ValueError(f'配置管理器 {name} 不存在')
|
return None
|
||||||
|
|
||||||
def get_manager_list(self) -> list[config_manager.ConfigManager]:
|
def get_manager_list(self) -> list[config_manager.ConfigManager]:
|
||||||
"""获取配置管理器列表
|
"""获取配置管理器列表
|
||||||
|
|||||||
+40
-2
@@ -1,5 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-app>
|
<v-app>
|
||||||
|
<v-snackbar v-model="snackbar" :color="color" :timeout="timeout" :location="location">
|
||||||
|
{{ text }}
|
||||||
|
</v-snackbar>
|
||||||
|
|
||||||
<v-layout>
|
<v-layout>
|
||||||
<v-navigation-drawer id="navigation-drawer" :width="160" app permanent rail>
|
<v-navigation-drawer id="navigation-drawer" :width="160" app permanent rail>
|
||||||
@@ -8,7 +11,9 @@
|
|||||||
<div id="logo-container">
|
<div id="logo-container">
|
||||||
<v-img id="logo-img" src="@/assets/langbot-logo-block.png" height="32" width="32"></v-img>
|
<v-img id="logo-img" src="@/assets/langbot-logo-block.png" height="32" width="32"></v-img>
|
||||||
|
|
||||||
<div id="version-chip" v-tooltip="proxy.$store.state.version + (proxy.$store.state.debug ? ' (调试模式已启用)' : '')" :style="{ 'background-color': proxy.$store.state.debug ? '#c79a47' : '#1e9ae2' }">
|
<div id="version-chip"
|
||||||
|
v-tooltip="proxy.$store.state.version + (proxy.$store.state.debug ? ' (调试模式已启用)' : '')"
|
||||||
|
:style="{ 'background-color': proxy.$store.state.debug ? '#c79a47' : '#1e9ae2' }">
|
||||||
{{ proxy.$store.state.version }}
|
{{ proxy.$store.state.version }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -45,8 +50,42 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { getCurrentInstance } from 'vue'
|
import { getCurrentInstance } from 'vue'
|
||||||
|
import {provide, ref, watch} from 'vue';
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance()
|
const { proxy } = getCurrentInstance()
|
||||||
|
|
||||||
|
const snackbar = ref(false);
|
||||||
|
const color = ref('success');
|
||||||
|
const text = ref('');
|
||||||
|
const location = ref('top');
|
||||||
|
const timeout = ref(2000);
|
||||||
|
|
||||||
|
function success(content) {
|
||||||
|
snackbar.value = true;
|
||||||
|
color.value = 'success';
|
||||||
|
text.value = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
function error(content) {
|
||||||
|
snackbar.value = true;
|
||||||
|
color.value = 'error';
|
||||||
|
text.value = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
function warning(content) {
|
||||||
|
snackbar.value = true;
|
||||||
|
color.value = 'warning';
|
||||||
|
text.value = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
function info(content) {
|
||||||
|
snackbar.value = true;
|
||||||
|
color.value = 'primary';
|
||||||
|
text.value = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
provide('snackbar', {success, error, warning, info, location, timeout});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@@ -102,5 +141,4 @@ const { proxy } = getCurrentInstance()
|
|||||||
#about-list-item:active {
|
#about-list-item:active {
|
||||||
background-color: #ddd;
|
background-color: #ddd;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -18,6 +18,10 @@
|
|||||||
import PageTitle from '@/components/PageTitle.vue'
|
import PageTitle from '@/components/PageTitle.vue'
|
||||||
import { ref, getCurrentInstance, onMounted, onUnmounted } from 'vue'
|
import { ref, getCurrentInstance, onMounted, onUnmounted } from 'vue'
|
||||||
|
|
||||||
|
import {inject} from "vue";
|
||||||
|
|
||||||
|
const snackbar = inject('snackbar');
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance()
|
const { proxy } = getCurrentInstance()
|
||||||
|
|
||||||
const logContent = ref('')
|
const logContent = ref('')
|
||||||
@@ -38,9 +42,15 @@ const refreshLog = () => {
|
|||||||
start_offset: logPointer.start_offset
|
start_offset: logPointer.start_offset
|
||||||
}
|
}
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
|
if (response.data.code != 0) {
|
||||||
|
snackbar.error(response.data.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
logContent.value += response.data.data.logs
|
logContent.value += response.data.data.logs
|
||||||
logPointer.start_page_number = response.data.data.end_page_number
|
logPointer.start_page_number = response.data.data.end_page_number
|
||||||
logPointer.start_offset = response.data.data.end_offset
|
logPointer.start_offset = response.data.data.end_offset
|
||||||
|
}).catch(error => {
|
||||||
|
snackbar.error(error.message)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,8 @@
|
|||||||
<v-card id="config-tab-content-json" v-if="configType == 'json'">
|
<v-card id="config-tab-content-json" v-if="configType == 'json'">
|
||||||
<textarea id="config-tab-content-json-textarea" @input="onInput" v-model="currentManagerDataEditorString" />
|
<textarea id="config-tab-content-json-textarea" @input="onInput" v-model="currentManagerDataEditorString" />
|
||||||
</v-card>
|
</v-card>
|
||||||
|
|
||||||
|
<div id="config-tab-json-not-valid" v-if="!isJsonValid && configType == 'json'">*JSON 格式不正确: {{ errorMessage }}</div>
|
||||||
</div>
|
</div>
|
||||||
</v-tabs-window-item>
|
</v-tabs-window-item>
|
||||||
</v-tabs-window>
|
</v-tabs-window>
|
||||||
@@ -59,6 +61,10 @@
|
|||||||
import PageTitle from '@/components/PageTitle.vue'
|
import PageTitle from '@/components/PageTitle.vue'
|
||||||
import { ref, getCurrentInstance, onMounted } from 'vue'
|
import { ref, getCurrentInstance, onMounted } from 'vue'
|
||||||
|
|
||||||
|
import {inject} from "vue";
|
||||||
|
|
||||||
|
const snackbar = inject('snackbar');
|
||||||
|
|
||||||
import Vjsf from '@koumoul/vjsf';
|
import Vjsf from '@koumoul/vjsf';
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance()
|
const { proxy } = getCurrentInstance()
|
||||||
@@ -125,6 +131,12 @@ const VJSFOptions = {
|
|||||||
|
|
||||||
const refresh = () => {
|
const refresh = () => {
|
||||||
proxy.$axios.get('/settings').then(response => {
|
proxy.$axios.get('/settings').then(response => {
|
||||||
|
|
||||||
|
if (response.data.code != 0) {
|
||||||
|
snackbar.error(response.data.msg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
managerList.value = response.data.data.managers
|
managerList.value = response.data.data.managers
|
||||||
|
|
||||||
if (proxy.$store.state.settingsPageTab == '') {
|
if (proxy.$store.state.settingsPageTab == '') {
|
||||||
@@ -133,10 +145,14 @@ const refresh = () => {
|
|||||||
fetchCurrentManagerData(proxy.$store.state.settingsPageTab).then(() => {
|
fetchCurrentManagerData(proxy.$store.state.settingsPageTab).then(() => {
|
||||||
firstJumpEditorAfterChangeTab()
|
firstJumpEditorAfterChangeTab()
|
||||||
})
|
})
|
||||||
|
}).catch(error => {
|
||||||
|
snackbar.error(error)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const onTabChange = (tab) => {
|
const onTabChange = (tab) => {
|
||||||
|
isJsonValid.value = true
|
||||||
|
errorMessage.value = ''
|
||||||
fetchCurrentManagerData(tab).then(() => {
|
fetchCurrentManagerData(tab).then(() => {
|
||||||
firstJumpEditorAfterChangeTab()
|
firstJumpEditorAfterChangeTab()
|
||||||
})
|
})
|
||||||
@@ -151,7 +167,13 @@ const firstJumpEditorAfterChangeTab = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const fetchCurrentManagerData = (tab) => {
|
const fetchCurrentManagerData = (tab) => {
|
||||||
return proxy.$axios.get(`/settings/${tab}`).then(response => {
|
return proxy.$axios.get(`/settings/${tab}`).catch(error => {
|
||||||
|
snackbar.error(error)
|
||||||
|
}).then(response => {
|
||||||
|
if (response.data.code != 0) {
|
||||||
|
snackbar.error(response.data.msg)
|
||||||
|
return
|
||||||
|
}
|
||||||
currentManager.value = response.data.data.manager
|
currentManager.value = response.data.data.manager
|
||||||
currentManagerData.value = currentManager.value.data
|
currentManagerData.value = currentManager.value.data
|
||||||
currentManagerDataEditorString.value = JSON.stringify(currentManager.value.data, null, 2)
|
currentManagerDataEditorString.value = JSON.stringify(currentManager.value.data, null, 2)
|
||||||
@@ -159,11 +181,30 @@ const fetchCurrentManagerData = (tab) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isJsonValid = ref(true)
|
||||||
|
const errorMessage = ref('')
|
||||||
|
|
||||||
|
const checkJsonValid = () => {
|
||||||
|
try {
|
||||||
|
JSON.parse(currentManagerDataEditorString.value)
|
||||||
|
isJsonValid.value = true
|
||||||
|
errorMessage.value = ''
|
||||||
|
} catch (error) {
|
||||||
|
isJsonValid.value = false
|
||||||
|
errorMessage.value = error.message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const onInput = () => {
|
const onInput = () => {
|
||||||
modified.value = true
|
modified.value = true
|
||||||
|
checkJsonValid()
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveAndApply = () => {
|
const saveAndApply = () => {
|
||||||
|
if (!isJsonValid.value) {
|
||||||
|
snackbar.error('JSON 格式不正确: ' + errorMessage.value)
|
||||||
|
return
|
||||||
|
}
|
||||||
if (configType.value == 'json') {
|
if (configType.value == 'json') {
|
||||||
currentManagerData.value = JSON.parse(currentManagerDataEditorString.value)
|
currentManagerData.value = JSON.parse(currentManagerDataEditorString.value)
|
||||||
}
|
}
|
||||||
@@ -171,14 +212,23 @@ const saveAndApply = () => {
|
|||||||
proxy.$axios.put(`/settings/${currentManager.value.name}/data`, {
|
proxy.$axios.put(`/settings/${currentManager.value.name}/data`, {
|
||||||
data: currentManagerData.value
|
data: currentManagerData.value
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
|
if (response.data.code != 0) {
|
||||||
|
snackbar.error(response.data.msg)
|
||||||
|
return
|
||||||
|
}
|
||||||
fetchCurrentManagerData(currentManager.value.name)
|
fetchCurrentManagerData(currentManager.value.name)
|
||||||
modified.value = false
|
modified.value = false
|
||||||
|
}).catch(error => {
|
||||||
|
snackbar.error(error)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
if (configType.value == 'json') {
|
if (configType.value == 'json') {
|
||||||
currentManagerData.value = JSON.stringify(currentManager.value.data, null, 2)
|
currentManagerData.value = currentManager.value.data
|
||||||
|
currentManagerDataEditorString.value = JSON.stringify(currentManager.value.data, null, 2)
|
||||||
|
isJsonValid.value = true
|
||||||
|
errorMessage.value = ''
|
||||||
} else {
|
} else {
|
||||||
fetchCurrentManagerData(currentManager.value.name)
|
fetchCurrentManagerData(currentManager.value.name)
|
||||||
}
|
}
|
||||||
@@ -289,4 +339,13 @@ onMounted(async () => {
|
|||||||
line-height: 1.6rem;
|
line-height: 1.6rem;
|
||||||
text-wrap: nowrap;
|
text-wrap: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#config-tab-json-not-valid {
|
||||||
|
margin: 0rem;
|
||||||
|
margin-left: 0.6rem;
|
||||||
|
height: 1.5rem;
|
||||||
|
margin-top: 0.2rem;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
Reference in New Issue
Block a user