perf: 使用 json-editor-vue 作为json编辑器

This commit is contained in:
Junyan Qin 2024-11-10 11:46:41 +08:00
parent 0fe161cd7f
commit 9336abff8b
No known key found for this signature in database
GPG Key ID: 22FE3AFADC710CEB
7 changed files with 958 additions and 31 deletions

View File

@ -38,7 +38,8 @@ class SettingsRouterGroup(group.RouterGroup):
"description": manager.description, "description": manager.description,
"schema": manager.schema, "schema": manager.schema,
"file": manager.file.config_file_name, "file": manager.file.config_file_name,
"data": manager.data "data": manager.data,
"doc_link": manager.doc_link
} }
} }
) )

View File

@ -24,6 +24,9 @@ class ConfigManager:
data: dict = None data: dict = None
"""配置数据""" """配置数据"""
doc_link: str = None
"""配置文件文档链接"""
def __init__(self, cfg_file: file_model.ConfigFile) -> None: def __init__(self, cfg_file: file_model.ConfigFile) -> None:
self.file = cfg_file self.file = cfg_file
self.data = {} self.data = {}

View File

@ -27,6 +27,7 @@ class SettingsManager:
description: str, description: str,
manager: config_manager.ConfigManager, manager: config_manager.ConfigManager,
schema: dict=None, schema: dict=None,
doc_link: str=None,
) -> None: ) -> None:
"""注册配置管理器 """注册配置管理器
@ -44,6 +45,7 @@ class SettingsManager:
manager.name = name manager.name = name
manager.description = description manager.description = description
manager.schema = schema manager.schema = schema
manager.doc_link = doc_link
self.managers.append(manager) self.managers.append(manager)
def get_manager(self, name: str) -> config_manager.ConfigManager | None: def get_manager(self, name: str) -> config_manager.ConfigManager | None:

View File

@ -28,35 +28,40 @@ class LoadConfigStage(stage.BootingStage):
name="command.json", name="command.json",
description="命令配置", description="命令配置",
manager=ap.command_cfg, manager=ap.command_cfg,
schema=schema.CONFIG_COMMAND_SCHEMA schema=schema.CONFIG_COMMAND_SCHEMA,
doc_link="https://qchatgpt.rockchin.top/config/function/command.html"
) )
ap.settings_mgr.register_manager( ap.settings_mgr.register_manager(
name="pipeline.json", name="pipeline.json",
description="消息处理流水线配置", description="消息处理流水线配置",
manager=ap.pipeline_cfg, manager=ap.pipeline_cfg,
schema=schema.CONFIG_PIPELINE_SCHEMA schema=schema.CONFIG_PIPELINE_SCHEMA,
doc_link="https://qchatgpt.rockchin.top/config/function/pipeline.html"
) )
ap.settings_mgr.register_manager( ap.settings_mgr.register_manager(
name="platform.json", name="platform.json",
description="消息平台配置", description="消息平台配置",
manager=ap.platform_cfg, manager=ap.platform_cfg,
schema=schema.CONFIG_PLATFORM_SCHEMA schema=schema.CONFIG_PLATFORM_SCHEMA,
doc_link="https://qchatgpt.rockchin.top/config/function/platform.html"
) )
ap.settings_mgr.register_manager( ap.settings_mgr.register_manager(
name="provider.json", name="provider.json",
description="大模型能力配置", description="大模型能力配置",
manager=ap.provider_cfg, manager=ap.provider_cfg,
schema=schema.CONFIG_PROVIDER_SCHEMA schema=schema.CONFIG_PROVIDER_SCHEMA,
doc_link="https://qchatgpt.rockchin.top/config/function/provider.html"
) )
ap.settings_mgr.register_manager( ap.settings_mgr.register_manager(
name="system.json", name="system.json",
description="系统配置", description="系统配置",
manager=ap.system_cfg, manager=ap.system_cfg,
schema=schema.CONFIG_SYSTEM_SCHEMA schema=schema.CONFIG_SYSTEM_SCHEMA,
doc_link="https://qchatgpt.rockchin.top/config/function/system.html"
) )
ap.plugin_setting_meta = await config.load_json_config("plugins/plugins.json", "templates/plugin-settings.json") ap.plugin_setting_meta = await config.load_json_config("plugins/plugins.json", "templates/plugin-settings.json")

927
web/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,7 @@
"axios": "^1.7.7", "axios": "^1.7.7",
"codemirror": "^5.65.18", "codemirror": "^5.65.18",
"core-js": "^3.37.1", "core-js": "^3.37.1",
"json-editor-vue": "^0.17.3",
"roboto-fontface": "*", "roboto-fontface": "*",
"vue": "^3.4.31", "vue": "^3.4.31",
"vuedraggable": "^4.1.0", "vuedraggable": "^4.1.0",

View File

@ -45,10 +45,10 @@
</div> </div>
<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" /> <JsonEditorVue id="config-tab-content-json-json-editor-vue" v-model="currentManagerData" mode="text" @change="onInput"/>
</v-card> </v-card>
<div id="config-tab-json-not-valid" v-if="!isJsonValid && configType == 'json'">*JSON 格式不正确: {{ errorMessage }}</div> <div id="config-tab-json-doc-link" v-if="configType == 'json' && currentManagerDocLink != undefined && currentManagerDocLink != ''">*配置文件格式请查看 <a :href="currentManagerDocLink" target="_blank">文档</a></div>
</div> </div>
</v-tabs-window-item> </v-tabs-window-item>
</v-tabs-window> </v-tabs-window>
@ -65,6 +65,8 @@ import {inject} from "vue";
const snackbar = inject('snackbar'); const snackbar = inject('snackbar');
import JsonEditorVue from 'json-editor-vue';
import Vjsf from '@koumoul/vjsf'; import Vjsf from '@koumoul/vjsf';
const { proxy } = getCurrentInstance() const { proxy } = getCurrentInstance()
@ -72,8 +74,9 @@ const { proxy } = getCurrentInstance()
const managerList = ref([]) const managerList = ref([])
const configType = ref('json') // ui or json const configType = ref('json') // ui or json
const currentManager = ref(null) const currentManager = ref(null)
const currentManagerName = ref('')
const currentManagerDocLink = ref('')
const currentManagerData = ref({}) const currentManagerData = ref({})
const currentManagerDataEditorString = ref('')
const currentManagerSchema = ref(null) const currentManagerSchema = ref(null)
const modified = ref(false) const modified = ref(false)
@ -175,9 +178,10 @@ const fetchCurrentManagerData = (tab) => {
return return
} }
currentManager.value = response.data.data.manager currentManager.value = response.data.data.manager
currentManagerName.value = currentManager.value.name
currentManagerData.value = currentManager.value.data currentManagerData.value = currentManager.value.data
currentManagerDataEditorString.value = JSON.stringify(currentManager.value.data, null, 2)
currentManagerSchema.value = currentManager.value.schema currentManagerSchema.value = currentManager.value.schema
currentManagerDocLink.value = currentManager.value.doc_link
}) })
} }
@ -186,7 +190,7 @@ const errorMessage = ref('')
const checkJsonValid = () => { const checkJsonValid = () => {
try { try {
JSON.parse(currentManagerDataEditorString.value) JSON.parse(currentManagerData.value)
isJsonValid.value = true isJsonValid.value = true
errorMessage.value = '' errorMessage.value = ''
} catch (error) { } catch (error) {
@ -201,12 +205,15 @@ const onInput = () => {
} }
const saveAndApply = () => { const saveAndApply = () => {
if (configType.value == 'json') {
checkJsonValid()
}
if (!isJsonValid.value) { if (!isJsonValid.value) {
snackbar.error('JSON 格式不正确: ' + errorMessage.value) snackbar.error('JSON 格式不正确: ' + errorMessage.value)
return return
} }
if (configType.value == 'json') { if (configType.value == 'json') {
currentManagerData.value = JSON.parse(currentManagerDataEditorString.value) currentManagerData.value = JSON.parse(currentManagerData.value)
} }
proxy.$axios.put(`/settings/${currentManager.value.name}/data`, { proxy.$axios.put(`/settings/${currentManager.value.name}/data`, {
@ -227,7 +234,6 @@ const saveAndApply = () => {
const reset = () => { const reset = () => {
if (configType.value == 'json') { if (configType.value == 'json') {
currentManagerData.value = currentManager.value.data currentManagerData.value = currentManager.value.data
currentManagerDataEditorString.value = JSON.stringify(currentManager.value.data, null, 2)
isJsonValid.value = true isJsonValid.value = true
errorMessage.value = '' errorMessage.value = ''
modified.value = false modified.value = false
@ -330,27 +336,17 @@ onMounted(async () => {
margin-top: 1rem; margin-top: 1rem;
} }
#config-tab-content-json-textarea { #config-tab-content-json-json-editor-vue {
width: 100%;
height: 100%; height: 100%;
resize: none; width: 100%;
padding: 0.6rem;
background-color: #f0f0f0;
border: none;
outline: none;
appearance: none;
/*字间隔增大*/
letter-spacing: 0.05rem;
line-height: 1.6rem;
text-wrap: nowrap;
} }
#config-tab-json-not-valid { #config-tab-json-doc-link {
margin: 0rem; margin: 0rem;
margin-left: 0.6rem; margin-left: 0.6rem;
height: 1.5rem; height: 1.5rem;
margin-top: 0.2rem; margin-top: 0.2rem;
font-size: 0.8rem; font-size: 0.8rem;
color: red; color: rgb(26, 98, 214);
} }
</style> </style>