Files
AstrBot/dashboard/src/views/ConfigPage.vue
T

220 lines
8.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup>
import axios from 'axios';
import AstrBotConfig from '@/components/shared/AstrBotConfig.vue';
import WaitingForRestart from '@/components/shared/WaitingForRestart.vue';
import { VueMonacoEditor } from '@guolao/vue-monaco-editor'
</script>
<template>
<v-card style="margin-bottom: 16px;">
<v-card-text style="padding: 0;">
<div>
<v-btn-group variant="outlined" divided>
<v-btn icon="mdi-text-box-edit-outline" style="width: 80px;" :color="editorTab === 0 ? 'primary' : ''"
@click="editorTab = 0">
</v-btn>
<v-btn icon="mdi-code-json" style="width: 80px;" :color="editorTab === 1 ? 'primary' : ''"
@click="configToString(); editorTab = 1;"></v-btn>
</v-btn-group>
<v-btn v-if="editorTab === 1" style="margin-left: 16px;" size="small" @click="configToString()">回到更改前的代码</v-btn>
<v-btn v-if="editorTab === 1 && config_data_has_changed" style="margin-left: 16px;" size="small"
@click="applyStrConfig()">应用此配置</v-btn>
<small v-if="editorTab === 1" style="margin-left: 16px;">💡 `应用此配置` 将配置暂存并应用到可视化如要保存<span
style="font-weight: 1000;"></span>点击右下角保存按钮</small>
</div>
</v-card-text>
</v-card>
<!-- 可视化编辑 -->
<v-card v-if="editorTab === 0">
<v-tabs v-model="tab" align-tabs="left" color="deep-purple-accent-4">
<v-tab v-for="(val, key, index) in metadata" :key="index" :value="index" style="font-weight: 1000; font-size: 15px">
{{ metadata[key]['name'] }}
</v-tab>
</v-tabs>
<v-tabs-window v-model="tab">
<v-tabs-window-item v-for="(val, key, index) in metadata" v-show="index == tab" :key="index">
<v-container fluid>
<v-expansion-panels variant="accordion">
<v-expansion-panel v-for="(val2, key2, index2) in metadata[key]['metadata']">
<v-expansion-panel-title>
<h3>{{metadata[key]['metadata'][key2]['description']}}</h3>
</v-expansion-panel-title>
<v-expansion-panel-text v-if="metadata[key]['metadata'][key2]?.config_template">
<!-- 带有 config_template 的配置项 -->
<v-tabs style="margin-top: 16px;" align-tabs="left" color="deep-purple-accent-4" v-model="config_template_tab">
<v-tab v-for="(item, index) in config_data[key2]" :key="index" :value="index">
{{ item.id }}({{ item.type }})
</v-tab>
<v-menu>
<template v-slot:activator="{ props }">
<v-btn variant="plain" size="large" v-bind="props">
<v-icon>mdi-plus</v-icon>
</v-btn>
</template>
<v-list @update:selected="addFromDefaultConfigTmpl($event, key, key2)">
<v-list-item v-for="(item, index) in metadata[key]['metadata'][key2]?.config_template" :key="index" :value="index">
<v-list-item-title>{{ index }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-tabs>
<v-tabs-window v-model="config_template_tab">
<v-tabs-window-item v-for="(config_item, index) in config_data[key2]" v-show="config_template_tab === index"
:key="index" :value="index">
<v-container>
<AstrBotConfig :metadata="metadata[key]['metadata']" :iterable="config_item" :metadataKey="key2"></AstrBotConfig>
</v-container>
</v-tabs-window-item>
</v-tabs-window>
</v-expansion-panel-text>
<v-expansion-panel-text v-else>
<!-- 如果配置项是一个 object那么 iterable 需要取到这个 object 的值否则取到整个 config_data -->
<AstrBotConfig v-if="metadata[key]['metadata'][key2]['type'] == 'object'" :metadata="metadata[key]['metadata']" :iterable="config_data[key2]" :metadataKey="key2"></AstrBotConfig>
<AstrBotConfig v-else :metadata="metadata[key]['metadata']" :iterable="config_data" :metadataKey="key2"></AstrBotConfig>
</v-expansion-panel-text>
</v-expansion-panel>
</v-expansion-panels>
</v-container>
</v-tabs-window-item>
<div style="margin-left: 16px; padding-bottom: 16px">
<small>不了解配置请见 <a
href="https://astrbot.soulter.top/docs/%E5%BC%80%E5%A7%8B%E4%B8%8A%E6%89%8B/%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6">官方文档</a>
<a
href="https://qm.qq.com/cgi-bin/qm/qr?k=EYGsuUTfe00_iOu9JTXS7_TEpMkXOvwv&jump_from=webapi&authKey=uUEMKCROfsseS+8IzqPjzV3y1tzy4AkykwTib2jNkOFdzezF9s9XknqnIaf3CDft">加群询问</a></small>
</div>
</v-tabs-window>
</v-card>
<!-- 代码编辑 -->
<v-card v-else style="background-color: #1e1e1e;">
<VueMonacoEditor theme="vs-dark" language="json" height="80vh" style="padding-top: 16px; padding-bottom: 16px;"
v-model:value="config_data_str">
</VueMonacoEditor>
</v-card>
<v-btn icon="mdi-content-save" size="x-large" style="position: fixed; right: 52px; bottom: 52px;" color="darkprimary"
@click="updateConfig">
</v-btn>
<v-snackbar :timeout="3000" elevation="24" :color="save_message_success" v-model="save_message_snack">
{{ save_message }}
</v-snackbar>
<WaitingForRestart ref="wfr"></WaitingForRestart>
</template>
<script>
export default {
name: 'ConfigPage',
components: {
AstrBotConfig,
VueMonacoEditor,
WaitingForRestart
},
watch: {
config_data_str: function (val) {
this.config_data_has_changed = true;
}
},
data() {
return {
config_data_has_changed: false,
config_data_str: "",
config_data: {
config: {}
},
fetched: false,
metadata: {},
provider_config_tmpl: {},
adapter_config_tmpl: {}, // 平台适配器
save_message_snack: false,
save_message: "",
save_message_success: "",
namespace: "",
tab: 0,
editorTab: 0, // 0: visual, 1: code
config_template_tab: 0,
}
},
mounted() {
this.getConfig();
},
methods: {
getConfig() {
// 获取配置
axios.get('/api/config/get').then((res) => {
this.config_data = res.data.data.config;
this.fetched = true
this.metadata = res.data.data.metadata;
this.provider_config_tmpl = res.data.data.provider_config_tmpl;
this.adapter_config_tmpl = res.data.data.adapter_config_tmpl;
}).catch((err) => {
save_message = err;
save_message_snack = true;
save_message_success = "error";
});
},
updateConfig() {
if (!this.fetched) return;
axios.post('/api/config/astrbot/update', this.config_data).then((res) => {
if (res.data.status === "ok") {
this.save_message = res.data.message;
this.save_message_snack = true;
this.save_message_success = "success";
this.$refs.wfr.check();
} else {
this.save_message = res.data.message;
this.save_message_snack = true;
this.save_message_success = "error";
}
}).catch((err) => {
this.save_message = err;
this.save_message_snack = true;
this.save_message_success = "error";
});
},
configToString() {
this.config_data_str = JSON.stringify(this.config_data, null, 2);
this.config_data_has_changed = false;
},
applyStrConfig() {
try {
this.config_data = JSON.parse(this.config_data_str);
this.config_data_has_changed = false;
this.save_message_success = "success";
this.save_message = "配置成功应用。如要保存,需再点击右下角保存按钮。";
this.save_message_snack = true;
} catch (e) {
this.save_message_success = "error";
this.save_message = "配置未应用,Json 格式错误。";
this.save_message_snack = true;
}
},
addFromDefaultConfigTmpl(val, group_name, config_item_name) {
console.log(val);
let tmpl = this.metadata[group_name]['metadata'][config_item_name]['config_template'][val];
let new_tmpl_cfg = JSON.parse(JSON.stringify(tmpl));
new_tmpl_cfg.id = "new_" + val + "_" + this.config_data[config_item_name].length;
this.config_data[config_item_name].push(new_tmpl_cfg);
this.config_template_tab = this.config_data[config_item_name].length - 1;
}
},
}
</script>
<style>
.v-tab {
text-transform: none !important;
}
</style>