mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2026-02-13 00:10:27 +00:00
refactor: webui
This commit is contained in:
@@ -3,11 +3,12 @@
|
||||
<div>
|
||||
<t-divider content="面板关于信息" align="left" />
|
||||
<t-alert theme="success" message="NapCat.WebUi is running" />
|
||||
|
||||
<t-list class="list">
|
||||
<t-list-item class="list-item">
|
||||
<span class="item-label">开发人员:</span>
|
||||
<span class="item-content"><t-link href="mailto:nanaeonn@outlook.com">Mlikiowa</t-link></span>
|
||||
<span class="item-content">
|
||||
<t-link href="mailto:nanaeonn@outlook.com">Mlikiowa</t-link>
|
||||
</span>
|
||||
</t-list-item>
|
||||
<t-list-item class="list-item">
|
||||
<span class="item-label">版本信息:</span>
|
||||
@@ -22,15 +23,11 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
joinQQGroup() {
|
||||
// 加入QQ群的逻辑
|
||||
window.open('https://jq.qq.com/?_wv=1027&k=123456789', '_blank');
|
||||
}
|
||||
}
|
||||
}
|
||||
<script setup lang="ts">
|
||||
const joinQQGroup = () => {
|
||||
// 加入QQ群的逻辑
|
||||
window.open('https://jq.qq.com/?_wv=1027&k=123456789', '_blank');
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@@ -59,11 +56,11 @@ export default {
|
||||
flex: 2;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-end; /* 添加这一行 */
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.tag-item {
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -1,18 +1,28 @@
|
||||
<template>
|
||||
<t-space>
|
||||
<t-tabs v-model="value" theme="card" :addable="true" @add="showAddTabDialog" @remove="removeTab">
|
||||
<t-tab-panel v-for="data in panelData" :key="data.value" :value="data.value" :label="data.label"
|
||||
:removable="data.removable">
|
||||
<t-tabs v-model="value" :addable="true" theme="card" @add="showAddTabDialog" @remove="removeTab">
|
||||
<t-tab-panel
|
||||
v-for="data in panelData"
|
||||
:key="data.value"
|
||||
:label="data.label"
|
||||
:removable="data.removable"
|
||||
:value="data.value"
|
||||
>
|
||||
<component :is="data.component" :config="data.config" />
|
||||
</t-tab-panel>
|
||||
</t-tabs>
|
||||
</t-space>
|
||||
<t-dialog :visible.sync="isDialogVisible" header="添加新选项卡" @confirm="addTab" @close="isDialogVisible = false">
|
||||
<t-form :model="newTab" ref="form">
|
||||
<t-form-item label="名称" name="name" :rules="[{ required: true, message: '请输入名称' }]">
|
||||
<t-dialog
|
||||
v-model:visible="isDialogVisible"
|
||||
header="添加新选项卡"
|
||||
@close="isDialogVisible = false"
|
||||
@confirm="addTab"
|
||||
>
|
||||
<t-form ref="form" :model="newTab">
|
||||
<t-form-item :rules="[{ required: true, message: '请输入名称' }]" label="名称" name="name">
|
||||
<t-input v-model="newTab.name" />
|
||||
</t-form-item>
|
||||
<t-form-item label="类型" name="type" :rules="[{ required: true, message: '请选择类型' }]">
|
||||
<t-form-item :rules="[{ required: true, message: '请选择类型' }]" label="类型" name="type">
|
||||
<t-select v-model="newTab.type">
|
||||
<t-option value="httpServers">HTTP 服务器</t-option>
|
||||
<t-option value="httpClients">HTTP 客户端</t-option>
|
||||
@@ -24,55 +34,61 @@
|
||||
</t-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, shallowRef, onMounted, watch, nextTick } from 'vue';
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, ref, shallowRef, watch } from 'vue';
|
||||
import { defaultOnebotConfig, mergeOnebotConfigs } from '../../../src/onebot/config/config';
|
||||
import { QQLoginManager } from '../backend/shell';
|
||||
import { QQLoginManager } from '@/backend/shell';
|
||||
import HttpServerComponent from './network/HttpServerComponent.vue';
|
||||
import HttpClientComponent from './network/HttpClientComponent.vue';
|
||||
import WebsocketServerComponent from './network/WebsocketServerComponent.vue';
|
||||
import WebsocketClientComponent from './network/WebsocketClientComponent.vue';
|
||||
|
||||
let id = 0;
|
||||
const value = ref('first');
|
||||
const panelData = ref([]);
|
||||
const isDialogVisible = ref(false);
|
||||
const newTab = ref({ name: '', type: '' });
|
||||
interface PanelData {
|
||||
value: string;
|
||||
label: string;
|
||||
removable: boolean;
|
||||
component: any;
|
||||
config: { name: string };
|
||||
}
|
||||
|
||||
const componentMap = {
|
||||
'httpServers': shallowRef(HttpServerComponent),
|
||||
'httpClients': shallowRef(HttpClientComponent),
|
||||
'websocketServers': shallowRef(WebsocketServerComponent),
|
||||
'websocketClients': shallowRef(WebsocketClientComponent),
|
||||
let id = 0;
|
||||
const value = ref<string>('first');
|
||||
const panelData = ref<PanelData[]>([]);
|
||||
const isDialogVisible = ref<boolean>(false);
|
||||
const newTab = ref<{ name: string; type: string }>({ name: '', type: '' });
|
||||
|
||||
const componentMap: Record<string, any> = {
|
||||
httpServers: shallowRef(HttpServerComponent),
|
||||
httpClients: shallowRef(HttpClientComponent),
|
||||
websocketServers: shallowRef(WebsocketServerComponent),
|
||||
websocketClients: shallowRef(WebsocketClientComponent),
|
||||
};
|
||||
|
||||
const getOB11Config = async () => {
|
||||
const getOB11Config = async (): Promise<any | undefined> => {
|
||||
const storedCredential = localStorage.getItem('auth');
|
||||
if (!storedCredential) {
|
||||
console.error('No stored credential found');
|
||||
return;
|
||||
}
|
||||
const loginManager = new QQLoginManager(storedCredential);
|
||||
const config = await loginManager.GetOB11Config();
|
||||
return config;
|
||||
return await loginManager.GetOB11Config();
|
||||
};
|
||||
|
||||
const setOB11Config = async (config) => {
|
||||
const setOB11Config = async (config: any): Promise<boolean> => {
|
||||
const storedCredential = localStorage.getItem('auth');
|
||||
if (!storedCredential) {
|
||||
console.error('No stored credential found');
|
||||
return false;
|
||||
}
|
||||
const loginManager = new QQLoginManager(storedCredential);
|
||||
const result = await loginManager.SetOB11Config(config);
|
||||
return result;
|
||||
return await loginManager.SetOB11Config(config);
|
||||
};
|
||||
|
||||
const log = (message, data) => {
|
||||
const log = (message: string, data: any) => {
|
||||
console.log(message, data);
|
||||
};
|
||||
|
||||
const createPanel = (type, name, id) => {
|
||||
const createPanel = (type: string, name: string, id: number): PanelData => {
|
||||
return {
|
||||
value: `${type}-${id}`,
|
||||
label: name,
|
||||
@@ -82,10 +98,10 @@ const createPanel = (type, name, id) => {
|
||||
};
|
||||
};
|
||||
|
||||
const generatePanels = (networkConfig) => {
|
||||
const panels = [];
|
||||
const generatePanels = (networkConfig: any): PanelData[] => {
|
||||
const panels: PanelData[] = [];
|
||||
Object.keys(networkConfig).forEach((key) => {
|
||||
networkConfig[key].forEach((config, index) => {
|
||||
networkConfig[key].forEach((config: any, index: number) => {
|
||||
const component = componentMap[key];
|
||||
if (!component) {
|
||||
console.error(`No component found for key: ${key}`);
|
||||
@@ -100,6 +116,7 @@ const generatePanels = (networkConfig) => {
|
||||
const loadConfig = async () => {
|
||||
try {
|
||||
const userConfig = await getOB11Config();
|
||||
if (!userConfig) return;
|
||||
const mergedConfig = mergeOnebotConfigs(defaultOnebotConfig, userConfig);
|
||||
const networkConfig = mergedConfig.network;
|
||||
log('networkConfig:', networkConfig);
|
||||
@@ -130,7 +147,11 @@ const addTab = async () => {
|
||||
value.value = newPanel.value; // 强制重新渲染选项卡
|
||||
};
|
||||
|
||||
const removeTab = ({ value: val, index }) => {
|
||||
const closeDialog = () => {
|
||||
isDialogVisible.value = false;
|
||||
};
|
||||
|
||||
const removeTab = ({ value: val, index }: { value: string; index: number }) => {
|
||||
if (index < 0) return false;
|
||||
panelData.value.splice(index, 1);
|
||||
if (panelData.value.length === 0) return;
|
||||
@@ -140,8 +161,8 @@ const removeTab = ({ value: val, index }) => {
|
||||
};
|
||||
|
||||
const syncConfig = async () => {
|
||||
const networkConfig = {};
|
||||
panelData.value.forEach(panel => {
|
||||
const networkConfig: Record<string, any[]> = {};
|
||||
panelData.value.forEach((panel) => {
|
||||
const key = panel.value.split('-')[0];
|
||||
if (!networkConfig[key]) {
|
||||
networkConfig[key] = [];
|
||||
@@ -149,6 +170,7 @@ const syncConfig = async () => {
|
||||
networkConfig[key].push(panel.config);
|
||||
});
|
||||
const userConfig = await getOB11Config();
|
||||
if (!userConfig) return;
|
||||
const mergedConfig = mergeOnebotConfigs(defaultOnebotConfig, userConfig);
|
||||
mergedConfig.network = networkConfig;
|
||||
await setOB11Config(mergedConfig);
|
||||
@@ -159,4 +181,4 @@ watch(panelData, syncConfig, { deep: true });
|
||||
onMounted(() => {
|
||||
loadConfig();
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
|
||||
@@ -4,4 +4,4 @@
|
||||
<t-divider content="其余配置" align="left" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@@ -1,29 +1,42 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3>HTTP Client 配置</h3>
|
||||
<t-form>
|
||||
<t-form-item label="URL">
|
||||
<t-input v-model="config.url" />
|
||||
</t-form-item>
|
||||
<t-form-item label="消息格式">
|
||||
<t-input v-model="config.messagePostFormat" />
|
||||
</t-form-item>
|
||||
<t-form-item label="报告自身消息">
|
||||
<t-checkbox v-model="config.reportSelfMessage" />
|
||||
</t-form-item>
|
||||
<t-form-item label="Token">
|
||||
<t-input v-model="config.token" />
|
||||
</t-form-item>
|
||||
<t-form-item label="调试模式">
|
||||
<t-checkbox v-model="config.debug" />
|
||||
</t-form-item>
|
||||
</t-form>
|
||||
</div>
|
||||
<div>
|
||||
<h3>HTTP Client 配置</h3>
|
||||
<t-form>
|
||||
<t-form-item label="URL">
|
||||
<t-input v-model="config.url" />
|
||||
</t-form-item>
|
||||
<t-form-item label="消息格式">
|
||||
<t-input v-model="config.messagePostFormat" />
|
||||
</t-form-item>
|
||||
<t-form-item label="报告自身消息">
|
||||
<t-checkbox v-model="config.reportSelfMessage" />
|
||||
</t-form-item>
|
||||
<t-form-item label="Token">
|
||||
<t-input v-model="config.token" />
|
||||
</t-form-item>
|
||||
<t-form-item label="调试模式">
|
||||
<t-checkbox v-model="config.debug" />
|
||||
</t-form-item>
|
||||
</t-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineProps } from 'vue';
|
||||
defineProps({
|
||||
config: Object,
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
|
||||
interface HttpClientConfig {
|
||||
url: string;
|
||||
messagePostFormat: string;
|
||||
reportSelfMessage: boolean;
|
||||
token: string;
|
||||
debug: boolean;
|
||||
}
|
||||
|
||||
const config = ref<HttpClientConfig>({
|
||||
url: '',
|
||||
messagePostFormat: '',
|
||||
reportSelfMessage: false,
|
||||
token: '',
|
||||
debug: false,
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
|
||||
@@ -1,38 +1,57 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3>HTTP Server 配置</h3>
|
||||
<t-form>
|
||||
<t-form-item label="端口">
|
||||
<t-input v-model.number="config.port" type="number" />
|
||||
</t-form-item>
|
||||
<t-form-item label="主机">
|
||||
<t-input v-model="config.host" type="text" />
|
||||
</t-form-item>
|
||||
<t-form-item label="启用 CORS">
|
||||
<t-checkbox v-model="config.enableCors" />
|
||||
</t-form-item>
|
||||
<t-form-item label="启用 WebSocket">
|
||||
<t-checkbox v-model="config.enableWebsocket" />
|
||||
</t-form-item>
|
||||
<t-form-item label="消息格式">
|
||||
<t-input v-model="config.messagePostFormat" type="text" />
|
||||
</t-form-item>
|
||||
<t-form-item label="报告自身消息">
|
||||
<t-checkbox v-model="config.reportSelfMessage" />
|
||||
</t-form-item>
|
||||
<t-form-item label="Token">
|
||||
<t-input v-model="config.token" type="text" />
|
||||
</t-form-item>
|
||||
<t-form-item label="调试模式">
|
||||
<t-checkbox v-model="config.debug" />
|
||||
</t-form-item>
|
||||
</t-form>
|
||||
</div>
|
||||
<div>
|
||||
<h3>HTTP Server 配置</h3>
|
||||
<t-form>
|
||||
<t-form-item label="端口">
|
||||
<t-input v-model.number="config.port" type="number" />
|
||||
</t-form-item>
|
||||
<t-form-item label="主机">
|
||||
<t-input v-model="config.host" type="text" />
|
||||
</t-form-item>
|
||||
<t-form-item label="启用 CORS">
|
||||
<t-checkbox v-model="config.enableCors" />
|
||||
</t-form-item>
|
||||
<t-form-item label="启用 WebSocket">
|
||||
<t-checkbox v-model="config.enableWebsocket" />
|
||||
</t-form-item>
|
||||
<t-form-item label="消息格式">
|
||||
<t-input v-model="config.messagePostFormat" type="text" />
|
||||
</t-form-item>
|
||||
<t-form-item label="报告自身消息">
|
||||
<t-checkbox v-model="config.reportSelfMessage" />
|
||||
</t-form-item>
|
||||
<t-form-item label="Token">
|
||||
<t-input v-model="config.token" type="text" />
|
||||
</t-form-item>
|
||||
<t-form-item label="调试模式">
|
||||
<t-checkbox v-model="config.debug" />
|
||||
</t-form-item>
|
||||
</t-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineProps } from 'vue';
|
||||
defineProps({
|
||||
config: Object,
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
|
||||
interface HttpServerConfig {
|
||||
port: number;
|
||||
host: string;
|
||||
enableCors: boolean;
|
||||
enableWebsocket: boolean;
|
||||
messagePostFormat: string;
|
||||
reportSelfMessage: boolean;
|
||||
token: string;
|
||||
debug: boolean;
|
||||
}
|
||||
|
||||
const config = ref<HttpServerConfig>({
|
||||
port: 8080,
|
||||
host: '',
|
||||
enableCors: false,
|
||||
enableWebsocket: false,
|
||||
messagePostFormat: '',
|
||||
reportSelfMessage: false,
|
||||
token: '',
|
||||
debug: false,
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
|
||||
@@ -1,32 +1,47 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3>WebSocket Client 配置</h3>
|
||||
<t-form>
|
||||
<t-form-item label="URL">
|
||||
<t-input v-model="config.url" />
|
||||
</t-form-item>
|
||||
<t-form-item label="消息格式">
|
||||
<t-input v-model="config.messagePostFormat" />
|
||||
</t-form-item>
|
||||
<t-form-item label="报告自身消息">
|
||||
<t-checkbox v-model="config.reportSelfMessage" />
|
||||
</t-form-item>
|
||||
<t-form-item label="Token">
|
||||
<t-input v-model="config.token" />
|
||||
</t-form-item>
|
||||
<t-form-item label="调试模式">
|
||||
<t-checkbox v-model="config.debug" />
|
||||
</t-form-item>
|
||||
<t-form-item label="心跳间隔">
|
||||
<t-input v-model.number="config.heartInterval" type="number" />
|
||||
</t-form-item>
|
||||
</t-form>
|
||||
</div>
|
||||
<div>
|
||||
<h3>WebSocket Client 配置</h3>
|
||||
<t-form>
|
||||
<t-form-item label="URL">
|
||||
<t-input v-model="config.url" />
|
||||
</t-form-item>
|
||||
<t-form-item label="消息格式">
|
||||
<t-input v-model="config.messagePostFormat" />
|
||||
</t-form-item>
|
||||
<t-form-item label="报告自身消息">
|
||||
<t-checkbox v-model="config.reportSelfMessage" />
|
||||
</t-form-item>
|
||||
<t-form-item label="Token">
|
||||
<t-input v-model="config.token" />
|
||||
</t-form-item>
|
||||
<t-form-item label="调试模式">
|
||||
<t-checkbox v-model="config.debug" />
|
||||
</t-form-item>
|
||||
<t-form-item label="心跳间隔">
|
||||
<t-input v-model.number="config.heartInterval" type="number" />
|
||||
</t-form-item>
|
||||
</t-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineProps } from 'vue';
|
||||
defineProps({
|
||||
config: Object,
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
|
||||
interface WsClientConfig {
|
||||
url: string;
|
||||
messagePostFormat: string;
|
||||
reportSelfMessage: boolean;
|
||||
token: string;
|
||||
debug: boolean;
|
||||
heartInterval: number;
|
||||
}
|
||||
|
||||
const config = ref<WsClientConfig>({
|
||||
url: '',
|
||||
messagePostFormat: '',
|
||||
reportSelfMessage: false,
|
||||
token: '',
|
||||
debug: false,
|
||||
heartInterval: 0,
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
|
||||
@@ -1,38 +1,57 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3>WebSocket Server 配置</h3>
|
||||
<t-form>
|
||||
<t-form-item label="主机">
|
||||
<t-input v-model="config.host" />
|
||||
</t-form-item>
|
||||
<t-form-item label="端口">
|
||||
<t-input v-model.number="config.port" type="number" />
|
||||
</t-form-item>
|
||||
<t-form-item label="消息格式">
|
||||
<t-input v-model="config.messagePostFormat" />
|
||||
</t-form-item>
|
||||
<t-form-item label="报告自身消息">
|
||||
<t-checkbox v-model="config.reportSelfMessage" />
|
||||
</t-form-item>
|
||||
<t-form-item label="Token">
|
||||
<t-input v-model="config.token" />
|
||||
</t-form-item>
|
||||
<t-form-item label="启用推送事件">
|
||||
<t-checkbox v-model="config.enablePushEvent" />
|
||||
</t-form-item>
|
||||
<t-form-item label="调试模式">
|
||||
<t-checkbox v-model="config.debug" />
|
||||
</t-form-item>
|
||||
<t-form-item label="心跳间隔">
|
||||
<t-input v-model.number="config.heartInterval" type="number" />
|
||||
</t-form-item>
|
||||
</t-form>
|
||||
</div>
|
||||
<div>
|
||||
<h3>WebSocket Server 配置</h3>
|
||||
<t-form>
|
||||
<t-form-item label="主机">
|
||||
<t-input v-model="config.host" />
|
||||
</t-form-item>
|
||||
<t-form-item label="端口">
|
||||
<t-input v-model.number="config.port" type="number" />
|
||||
</t-form-item>
|
||||
<t-form-item label="消息格式">
|
||||
<t-input v-model="config.messagePostFormat" />
|
||||
</t-form-item>
|
||||
<t-form-item label="报告自身消息">
|
||||
<t-checkbox v-model="config.reportSelfMessage" />
|
||||
</t-form-item>
|
||||
<t-form-item label="Token">
|
||||
<t-input v-model="config.token" />
|
||||
</t-form-item>
|
||||
<t-form-item label="启用推送事件">
|
||||
<t-checkbox v-model="config.enablePushEvent" />
|
||||
</t-form-item>
|
||||
<t-form-item label="调试模式">
|
||||
<t-checkbox v-model="config.debug" />
|
||||
</t-form-item>
|
||||
<t-form-item label="心跳间隔">
|
||||
<t-input v-model.number="config.heartInterval" type="number" />
|
||||
</t-form-item>
|
||||
</t-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineProps } from 'vue';
|
||||
defineProps({
|
||||
config: Object,
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
|
||||
interface WsServerConfig {
|
||||
host: string;
|
||||
port: number;
|
||||
messagePostFormat: string;
|
||||
reportSelfMessage: boolean;
|
||||
token: string;
|
||||
enablePushEvent: boolean;
|
||||
debug: boolean;
|
||||
heartInterval: number;
|
||||
}
|
||||
|
||||
const config = ref<WsServerConfig>({
|
||||
host: '',
|
||||
port: 8080,
|
||||
messagePostFormat: '',
|
||||
reportSelfMessage: false,
|
||||
token: '',
|
||||
enablePushEvent: false,
|
||||
debug: false,
|
||||
heartInterval: 0,
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user