mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2024-11-21 09:36:35 +00:00
feat: 移除无用代码
This commit is contained in:
parent
e98bfaac11
commit
83f28795f2
@ -14,8 +14,8 @@
|
|||||||
<span class="item-label">版本信息:</span>
|
<span class="item-label">版本信息:</span>
|
||||||
<span class="item-content">
|
<span class="item-content">
|
||||||
<t-tag class="tag-item" theme="success"> WebUi: 1.0.0 </t-tag>
|
<t-tag class="tag-item" theme="success"> WebUi: 1.0.0 </t-tag>
|
||||||
<t-tag class="tag-item" theme="success"> NapCat: 1.0.0 </t-tag>
|
<t-tag class="tag-item" theme="success"> NapCat: 4.?.? </t-tag>
|
||||||
<t-tag class="tag-item" theme="success"> Tdesign: 1.0.0 </t-tag>
|
<t-tag class="tag-item" theme="success"> Tdesign: 1.10.3 </t-tag>
|
||||||
</span>
|
</span>
|
||||||
</t-list-item>
|
</t-list-item>
|
||||||
</t-list>
|
</t-list>
|
||||||
|
@ -1,47 +1,52 @@
|
|||||||
<template>
|
<template>
|
||||||
<t-space class="full-space">
|
<t-space class="full-space">
|
||||||
|
<template v-if="clientPanelData.length > 0">
|
||||||
<t-tabs v-model="activeTab" :addable="true" theme="card" @add="showAddTabDialog" @remove="removeTab" class="full-tabs">
|
<t-tabs v-model="activeTab" :addable="true" theme="card" @add="showAddTabDialog" @remove="removeTab" class="full-tabs">
|
||||||
<t-tab-panel
|
<t-tab-panel
|
||||||
v-for="(config, idx) in clientPanelData"
|
v-for="(config, idx) in clientPanelData"
|
||||||
:key="idx"
|
:key="idx"
|
||||||
:label="config.name"
|
:label="config.name"
|
||||||
:removable="true"
|
:removable="true"
|
||||||
:value="idx"
|
:value="idx"
|
||||||
class="full-tab-panel"
|
class="full-tab-panel"
|
||||||
>
|
>
|
||||||
<component :is="resolveDynamicComponent(getComponent(config.key))" :config="config.data" />
|
<component :is="resolveDynamicComponent(getComponent(config.key))" :config="config.data" />
|
||||||
<div class="button-container">
|
<div class="button-container">
|
||||||
<t-button @click="saveConfig" style="width: 100px; height: 40px;">保存</t-button>
|
<t-button @click="saveConfig" style="width: 100px; height: 40px;">保存</t-button>
|
||||||
</div>
|
</div>
|
||||||
</t-tab-panel>
|
</t-tab-panel>
|
||||||
</t-tabs>
|
</t-tabs>
|
||||||
<t-dialog
|
</template>
|
||||||
v-model:visible="isDialogVisible"
|
<template v-else>
|
||||||
header="添加新选项卡"
|
<EmptyStateComponent :showAddTabDialog="showAddTabDialog" />
|
||||||
@close="isDialogVisible = false"
|
</template>
|
||||||
@confirm="addTab"
|
<t-dialog
|
||||||
>
|
v-model:visible="isDialogVisible"
|
||||||
<t-form ref="form" :model="newTab">
|
header="添加网络配置"
|
||||||
<t-form-item :rules="[{ required: true, message: '请输入名称' }]" label="名称" name="name">
|
@close="isDialogVisible = false"
|
||||||
<t-input v-model="newTab.name" />
|
@confirm="addTab"
|
||||||
</t-form-item>
|
>
|
||||||
<t-form-item :rules="[{ required: true, message: '请选择类型' }]" label="类型" name="type">
|
<t-form ref="form" :model="newTab">
|
||||||
<t-select v-model="newTab.type">
|
<t-form-item :rules="[{ required: true, message: '请输入名称' }]" label="名称" name="name">
|
||||||
<t-option value="httpServers">HTTP 服务器</t-option>
|
<t-input v-model="newTab.name" />
|
||||||
<t-option value="httpClients">HTTP 客户端</t-option>
|
</t-form-item>
|
||||||
<t-option value="websocketServers">WebSocket 服务器</t-option>
|
<t-form-item :rules="[{ required: true, message: '请选择类型' }]" label="类型" name="type">
|
||||||
<t-option value="websocketClients">WebSocket 客户端</t-option>
|
<t-select v-model="newTab.type">
|
||||||
</t-select>
|
<t-option value="httpServers">HTTP 服务器</t-option>
|
||||||
</t-form-item>
|
<t-option value="httpClients">HTTP 客户端</t-option>
|
||||||
</t-form>
|
<t-option value="websocketServers">WebSocket 服务器</t-option>
|
||||||
</t-dialog>
|
<t-option value="websocketClients">WebSocket 客户端</t-option>
|
||||||
|
</t-select>
|
||||||
|
</t-form-item>
|
||||||
|
</t-form>
|
||||||
|
</t-dialog>
|
||||||
</t-space>
|
</t-space>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, resolveDynamicComponent, nextTick, Ref, onMounted, reactive, Reactive } from 'vue';
|
import { ref, resolveDynamicComponent, nextTick, Ref, onMounted, reactive, Reactive } from 'vue';
|
||||||
import { MessagePlugin } from 'tdesign-vue-next';
|
import { MessagePlugin } from 'tdesign-vue-next';
|
||||||
import {
|
import {
|
||||||
httpServerDefaultConfigs,
|
httpServerDefaultConfigs,
|
||||||
httpClientDefaultConfigs,
|
httpClientDefaultConfigs,
|
||||||
websocketServerDefaultConfigs,
|
websocketServerDefaultConfigs,
|
||||||
@ -53,139 +58,140 @@ import {
|
|||||||
NetworkConfig,
|
NetworkConfig,
|
||||||
OneBotConfig,
|
OneBotConfig,
|
||||||
mergeOneBotConfigs,
|
mergeOneBotConfigs,
|
||||||
} from '../../../src/onebot/config/config';
|
} from '../../../src/onebot/config/config';
|
||||||
import { QQLoginManager } from '@/backend/shell';
|
import { QQLoginManager } from '@/backend/shell';
|
||||||
import HttpServerComponent from '@/pages/network/HttpServerComponent.vue';
|
import HttpServerComponent from '@/pages/network/HttpServerComponent.vue';
|
||||||
import HttpClientComponent from '@/pages/network/HttpClientComponent.vue';
|
import HttpClientComponent from '@/pages/network/HttpClientComponent.vue';
|
||||||
import WebsocketServerComponent from '@/pages/network/WebsocketServerComponent.vue';
|
import WebsocketServerComponent from '@/pages/network/WebsocketServerComponent.vue';
|
||||||
import WebsocketClientComponent from '@/pages/network/WebsocketClientComponent.vue';
|
import WebsocketClientComponent from '@/pages/network/WebsocketClientComponent.vue';
|
||||||
|
import EmptyStateComponent from '@/pages/network/EmptyStateComponent.vue';
|
||||||
type ConfigKey = 'httpServers' | 'httpClients' | 'websocketServers' | 'websocketClients';
|
|
||||||
|
type ConfigKey = 'httpServers' | 'httpClients' | 'websocketServers' | 'websocketClients';
|
||||||
type ConfigUnion = HttpClientConfig | HttpServerConfig | WebsocketServerConfig | WebsocketClientConfig;
|
|
||||||
|
type ConfigUnion = HttpClientConfig | HttpServerConfig | WebsocketServerConfig | WebsocketClientConfig;
|
||||||
const defaultConfigs: Record<ConfigKey, ConfigUnion> = {
|
|
||||||
|
const defaultConfigs: Record<ConfigKey, ConfigUnion> = {
|
||||||
httpServers: httpServerDefaultConfigs,
|
httpServers: httpServerDefaultConfigs,
|
||||||
httpClients: httpClientDefaultConfigs,
|
httpClients: httpClientDefaultConfigs,
|
||||||
websocketServers: websocketServerDefaultConfigs,
|
websocketServers: websocketServerDefaultConfigs,
|
||||||
websocketClients: websocketClientDefaultConfigs,
|
websocketClients: websocketClientDefaultConfigs,
|
||||||
};
|
};
|
||||||
|
|
||||||
const componentMap: Record<
|
const componentMap: Record<
|
||||||
ConfigKey,
|
ConfigKey,
|
||||||
| typeof HttpServerComponent
|
| typeof HttpServerComponent
|
||||||
| typeof HttpClientComponent
|
| typeof HttpClientComponent
|
||||||
| typeof WebsocketServerComponent
|
| typeof WebsocketServerComponent
|
||||||
| typeof WebsocketClientComponent
|
| typeof WebsocketClientComponent
|
||||||
> = {
|
> = {
|
||||||
httpServers: HttpServerComponent,
|
httpServers: HttpServerComponent,
|
||||||
httpClients: HttpClientComponent,
|
httpClients: HttpClientComponent,
|
||||||
websocketServers: WebsocketServerComponent,
|
websocketServers: WebsocketServerComponent,
|
||||||
websocketClients: WebsocketClientComponent,
|
websocketClients: WebsocketClientComponent,
|
||||||
};
|
};
|
||||||
|
|
||||||
interface ClientPanel {
|
interface ClientPanel {
|
||||||
name: string;
|
name: string;
|
||||||
key: ConfigKey;
|
key: ConfigKey;
|
||||||
data: Ref<ConfigUnion>;
|
data: Ref<ConfigUnion>;
|
||||||
}
|
}
|
||||||
|
|
||||||
type ComponentKey = keyof typeof componentMap;
|
type ComponentKey = keyof typeof componentMap;
|
||||||
|
|
||||||
// TODO: store these state in global store (aka pinia)
|
// TODO: store these state in global store (aka pinia)
|
||||||
const activeTab = ref<number>(0);
|
const activeTab = ref<number>(0);
|
||||||
const isDialogVisible = ref(false);
|
const isDialogVisible = ref(false);
|
||||||
const newTab = ref<{ name: string; type: ComponentKey }>({ name: '', type: 'httpServers' });
|
const newTab = ref<{ name: string; type: ComponentKey }>({ name: '', type: 'httpServers' });
|
||||||
const clientPanelData: Reactive<Array<ClientPanel>> = reactive([]);
|
const clientPanelData: Reactive<Array<ClientPanel>> = reactive([]);
|
||||||
|
|
||||||
const getComponent = (type: ComponentKey) => {
|
const getComponent = (type: ComponentKey) => {
|
||||||
return componentMap[type];
|
return componentMap[type];
|
||||||
};
|
};
|
||||||
|
|
||||||
const getOB11Config = async (): Promise<OneBotConfig | undefined> => {
|
const getOB11Config = async (): Promise<OneBotConfig | undefined> => {
|
||||||
const storedCredential = localStorage.getItem('auth');
|
const storedCredential = localStorage.getItem('auth');
|
||||||
if (!storedCredential) {
|
if (!storedCredential) {
|
||||||
console.error('No stored credential found');
|
console.error('No stored credential found');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const loginManager = new QQLoginManager(storedCredential);
|
const loginManager = new QQLoginManager(storedCredential);
|
||||||
return await loginManager.GetOB11Config();
|
return await loginManager.GetOB11Config();
|
||||||
};
|
};
|
||||||
|
|
||||||
const setOB11Config = async (config: OneBotConfig): Promise<boolean> => {
|
const setOB11Config = async (config: OneBotConfig): Promise<boolean> => {
|
||||||
const storedCredential = localStorage.getItem('auth');
|
const storedCredential = localStorage.getItem('auth');
|
||||||
if (!storedCredential) {
|
if (!storedCredential) {
|
||||||
console.error('No stored credential found');
|
console.error('No stored credential found');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const loginManager = new QQLoginManager(storedCredential);
|
const loginManager = new QQLoginManager(storedCredential);
|
||||||
return await loginManager.SetOB11Config(config);
|
return await loginManager.SetOB11Config(config);
|
||||||
};
|
};
|
||||||
|
|
||||||
const addToPanel = <T extends ConfigUnion>(configs: T[], key: ConfigKey) => {
|
const addToPanel = <T extends ConfigUnion>(configs: T[], key: ConfigKey) => {
|
||||||
configs.forEach((config) => clientPanelData.push({ name: config.name, data: config, key: key }));
|
configs.forEach((config) => clientPanelData.push({ name: config.name, data: config, key: key }));
|
||||||
};
|
};
|
||||||
|
|
||||||
const addConfigDataToPanel = (data: NetworkConfig) => {
|
const addConfigDataToPanel = (data: NetworkConfig) => {
|
||||||
Object.entries(data).forEach(([key, configs]) => {
|
Object.entries(data).forEach(([key, configs]) => {
|
||||||
if (key in defaultConfigs) {
|
if (key in defaultConfigs) {
|
||||||
addToPanel(configs as ConfigUnion[], key as ConfigKey);
|
addToPanel(configs as ConfigUnion[], key as ConfigKey);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const parsePanelData = (): NetworkConfig => {
|
const parsePanelData = (): NetworkConfig => {
|
||||||
return {
|
return {
|
||||||
websocketClients: clientPanelData
|
websocketClients: clientPanelData
|
||||||
.filter((panel) => panel.key === 'websocketClients')
|
.filter((panel) => panel.key === 'websocketClients')
|
||||||
.map((panel) => panel.data as WebsocketClientConfig),
|
.map((panel) => panel.data as WebsocketClientConfig),
|
||||||
websocketServers: clientPanelData
|
websocketServers: clientPanelData
|
||||||
.filter((panel) => panel.key === 'websocketServers')
|
.filter((panel) => panel.key === 'websocketServers')
|
||||||
.map((panel) => panel.data as WebsocketServerConfig),
|
.map((panel) => panel.data as WebsocketServerConfig),
|
||||||
httpClients: clientPanelData
|
httpClients: clientPanelData
|
||||||
.filter((panel) => panel.key === 'httpClients')
|
.filter((panel) => panel.key === 'httpClients')
|
||||||
.map((panel) => panel.data as HttpClientConfig),
|
.map((panel) => panel.data as HttpClientConfig),
|
||||||
httpServers: clientPanelData
|
httpServers: clientPanelData
|
||||||
.filter((panel) => panel.key === 'httpServers')
|
.filter((panel) => panel.key === 'httpServers')
|
||||||
.map((panel) => panel.data as HttpServerConfig),
|
.map((panel) => panel.data as HttpServerConfig),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadConfig = async () => {
|
const loadConfig = async () => {
|
||||||
try {
|
try {
|
||||||
const userConfig = await getOB11Config();
|
const userConfig = await getOB11Config();
|
||||||
if (!userConfig) return;
|
if (!userConfig) return;
|
||||||
const mergedConfig = mergeOneBotConfigs(userConfig);
|
const mergedConfig = mergeOneBotConfigs(userConfig);
|
||||||
addConfigDataToPanel(mergedConfig.network);
|
addConfigDataToPanel(mergedConfig.network);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error loading config:', error);
|
console.error('Error loading config:', error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// It's better to "saveConfig" instead of using deep watch
|
// It's better to "saveConfig" instead of using deep watch
|
||||||
const saveConfig = async () => {
|
const saveConfig = async () => {
|
||||||
const config = parsePanelData();
|
const config = parsePanelData();
|
||||||
const userConfig = await getOB11Config();
|
const userConfig = await getOB11Config();
|
||||||
if (!userConfig) return;
|
if (!userConfig) return;
|
||||||
userConfig.network = config;
|
userConfig.network = config;
|
||||||
const success = await setOB11Config(userConfig);
|
const success = await setOB11Config(userConfig);
|
||||||
if (success) {
|
if (success) {
|
||||||
MessagePlugin.success('配置保存成功');
|
MessagePlugin.success('配置保存成功');
|
||||||
} else {
|
} else {
|
||||||
MessagePlugin.error('配置保存失败');
|
MessagePlugin.error('配置保存失败');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const showAddTabDialog = () => {
|
const showAddTabDialog = () => {
|
||||||
newTab.value = { name: '', type: 'httpServers' };
|
newTab.value = { name: '', type: 'httpServers' };
|
||||||
isDialogVisible.value = true;
|
isDialogVisible.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const addTab = async () => {
|
const addTab = async () => {
|
||||||
const { name, type } = newTab.value;
|
const { name, type } = newTab.value;
|
||||||
if (clientPanelData.some(panel => panel.name === name)) {
|
if (clientPanelData.some(panel => panel.name === name)) {
|
||||||
MessagePlugin.error('选项卡名称已存在');
|
MessagePlugin.error('选项卡名称已存在');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const defaultConfig = structuredClone(defaultConfigs[type]);
|
const defaultConfig = structuredClone(defaultConfigs[type]);
|
||||||
defaultConfig.name = name;
|
defaultConfig.name = name;
|
||||||
@ -194,74 +200,45 @@ const addTab = async () => {
|
|||||||
await nextTick();
|
await nextTick();
|
||||||
activeTab.value = clientPanelData.length - 1;
|
activeTab.value = clientPanelData.length - 1;
|
||||||
MessagePlugin.success('选项卡添加成功');
|
MessagePlugin.success('选项卡添加成功');
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeTab = async (payload: { value: string; index: number; e: PointerEvent }) => {
|
const removeTab = async (payload: { value: string; index: number; e: PointerEvent }) => {
|
||||||
clientPanelData.splice(payload.index, 1);
|
clientPanelData.splice(payload.index, 1);
|
||||||
activeTab.value = Math.max(0, activeTab.value - 1);
|
activeTab.value = Math.max(0, activeTab.value - 1);
|
||||||
await saveConfig();
|
await saveConfig();
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadConfig();
|
loadConfig();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.full-space {
|
.full-space {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.full-tabs {
|
.full-tabs {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.full-tab-panel {
|
.full-tab-panel {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-container {
|
.button-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<style scoped>
|
|
||||||
.full-space {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: flex-start;
|
|
||||||
justify-content: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.full-tabs {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.full-tab-panel {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-container {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
</style>
|
|
22
napcat.webui/src/pages/network/EmptyStateComponent.vue
Normal file
22
napcat.webui/src/pages/network/EmptyStateComponent.vue
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<template>
|
||||||
|
<div class="empty-state">
|
||||||
|
<p>当前没有网络配置</p>
|
||||||
|
<t-button @click="showAddTabDialog">添加网络配置</t-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { defineProps } from 'vue';
|
||||||
|
defineProps<{ showAddTabDialog: () => void }>();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.empty-state {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
267
napcat.webui/src/pages/new/NetWork.old.vue
Normal file
267
napcat.webui/src/pages/new/NetWork.old.vue
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
<template>
|
||||||
|
<t-space class="full-space">
|
||||||
|
<t-tabs v-model="activeTab" :addable="true" theme="card" @add="showAddTabDialog" @remove="removeTab" class="full-tabs">
|
||||||
|
<t-tab-panel
|
||||||
|
v-for="(config, idx) in clientPanelData"
|
||||||
|
:key="idx"
|
||||||
|
:label="config.name"
|
||||||
|
:removable="true"
|
||||||
|
:value="idx"
|
||||||
|
class="full-tab-panel"
|
||||||
|
>
|
||||||
|
<component :is="resolveDynamicComponent(getComponent(config.key))" :config="config.data" />
|
||||||
|
<div class="button-container">
|
||||||
|
<t-button @click="saveConfig" style="width: 100px; height: 40px;">保存</t-button>
|
||||||
|
</div>
|
||||||
|
</t-tab-panel>
|
||||||
|
</t-tabs>
|
||||||
|
<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 :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>
|
||||||
|
<t-option value="websocketServers">WebSocket 服务器</t-option>
|
||||||
|
<t-option value="websocketClients">WebSocket 客户端</t-option>
|
||||||
|
</t-select>
|
||||||
|
</t-form-item>
|
||||||
|
</t-form>
|
||||||
|
</t-dialog>
|
||||||
|
</t-space>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, resolveDynamicComponent, nextTick, Ref, onMounted, reactive, Reactive } from 'vue';
|
||||||
|
import { MessagePlugin } from 'tdesign-vue-next';
|
||||||
|
import {
|
||||||
|
httpServerDefaultConfigs,
|
||||||
|
httpClientDefaultConfigs,
|
||||||
|
websocketServerDefaultConfigs,
|
||||||
|
websocketClientDefaultConfigs,
|
||||||
|
HttpClientConfig,
|
||||||
|
HttpServerConfig,
|
||||||
|
WebsocketClientConfig,
|
||||||
|
WebsocketServerConfig,
|
||||||
|
NetworkConfig,
|
||||||
|
OneBotConfig,
|
||||||
|
mergeOneBotConfigs,
|
||||||
|
} from '../../../../src/onebot/config/config';
|
||||||
|
import { QQLoginManager } from '@/backend/shell';
|
||||||
|
import HttpServerComponent from '@/pages/network/HttpServerComponent.vue';
|
||||||
|
import HttpClientComponent from '@/pages/network/HttpClientComponent.vue';
|
||||||
|
import WebsocketServerComponent from '@/pages/network/WebsocketServerComponent.vue';
|
||||||
|
import WebsocketClientComponent from '@/pages/network/WebsocketClientComponent.vue';
|
||||||
|
|
||||||
|
type ConfigKey = 'httpServers' | 'httpClients' | 'websocketServers' | 'websocketClients';
|
||||||
|
|
||||||
|
type ConfigUnion = HttpClientConfig | HttpServerConfig | WebsocketServerConfig | WebsocketClientConfig;
|
||||||
|
|
||||||
|
const defaultConfigs: Record<ConfigKey, ConfigUnion> = {
|
||||||
|
httpServers: httpServerDefaultConfigs,
|
||||||
|
httpClients: httpClientDefaultConfigs,
|
||||||
|
websocketServers: websocketServerDefaultConfigs,
|
||||||
|
websocketClients: websocketClientDefaultConfigs,
|
||||||
|
};
|
||||||
|
|
||||||
|
const componentMap: Record<
|
||||||
|
ConfigKey,
|
||||||
|
| typeof HttpServerComponent
|
||||||
|
| typeof HttpClientComponent
|
||||||
|
| typeof WebsocketServerComponent
|
||||||
|
| typeof WebsocketClientComponent
|
||||||
|
> = {
|
||||||
|
httpServers: HttpServerComponent,
|
||||||
|
httpClients: HttpClientComponent,
|
||||||
|
websocketServers: WebsocketServerComponent,
|
||||||
|
websocketClients: WebsocketClientComponent,
|
||||||
|
};
|
||||||
|
|
||||||
|
interface ClientPanel {
|
||||||
|
name: string;
|
||||||
|
key: ConfigKey;
|
||||||
|
data: Ref<ConfigUnion>;
|
||||||
|
}
|
||||||
|
|
||||||
|
type ComponentKey = keyof typeof componentMap;
|
||||||
|
|
||||||
|
// TODO: store these state in global store (aka pinia)
|
||||||
|
const activeTab = ref<number>(0);
|
||||||
|
const isDialogVisible = ref(false);
|
||||||
|
const newTab = ref<{ name: string; type: ComponentKey }>({ name: '', type: 'httpServers' });
|
||||||
|
const clientPanelData: Reactive<Array<ClientPanel>> = reactive([]);
|
||||||
|
|
||||||
|
const getComponent = (type: ComponentKey) => {
|
||||||
|
return componentMap[type];
|
||||||
|
};
|
||||||
|
|
||||||
|
const getOB11Config = async (): Promise<OneBotConfig | undefined> => {
|
||||||
|
const storedCredential = localStorage.getItem('auth');
|
||||||
|
if (!storedCredential) {
|
||||||
|
console.error('No stored credential found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const loginManager = new QQLoginManager(storedCredential);
|
||||||
|
return await loginManager.GetOB11Config();
|
||||||
|
};
|
||||||
|
|
||||||
|
const setOB11Config = async (config: OneBotConfig): Promise<boolean> => {
|
||||||
|
const storedCredential = localStorage.getItem('auth');
|
||||||
|
if (!storedCredential) {
|
||||||
|
console.error('No stored credential found');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const loginManager = new QQLoginManager(storedCredential);
|
||||||
|
return await loginManager.SetOB11Config(config);
|
||||||
|
};
|
||||||
|
|
||||||
|
const addToPanel = <T extends ConfigUnion>(configs: T[], key: ConfigKey) => {
|
||||||
|
configs.forEach((config) => clientPanelData.push({ name: config.name, data: config, key: key }));
|
||||||
|
};
|
||||||
|
|
||||||
|
const addConfigDataToPanel = (data: NetworkConfig) => {
|
||||||
|
Object.entries(data).forEach(([key, configs]) => {
|
||||||
|
if (key in defaultConfigs) {
|
||||||
|
addToPanel(configs as ConfigUnion[], key as ConfigKey);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const parsePanelData = (): NetworkConfig => {
|
||||||
|
return {
|
||||||
|
websocketClients: clientPanelData
|
||||||
|
.filter((panel) => panel.key === 'websocketClients')
|
||||||
|
.map((panel) => panel.data as WebsocketClientConfig),
|
||||||
|
websocketServers: clientPanelData
|
||||||
|
.filter((panel) => panel.key === 'websocketServers')
|
||||||
|
.map((panel) => panel.data as WebsocketServerConfig),
|
||||||
|
httpClients: clientPanelData
|
||||||
|
.filter((panel) => panel.key === 'httpClients')
|
||||||
|
.map((panel) => panel.data as HttpClientConfig),
|
||||||
|
httpServers: clientPanelData
|
||||||
|
.filter((panel) => panel.key === 'httpServers')
|
||||||
|
.map((panel) => panel.data as HttpServerConfig),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadConfig = async () => {
|
||||||
|
try {
|
||||||
|
const userConfig = await getOB11Config();
|
||||||
|
if (!userConfig) return;
|
||||||
|
const mergedConfig = mergeOneBotConfigs(userConfig);
|
||||||
|
addConfigDataToPanel(mergedConfig.network);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error loading config:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// It's better to "saveConfig" instead of using deep watch
|
||||||
|
const saveConfig = async () => {
|
||||||
|
const config = parsePanelData();
|
||||||
|
const userConfig = await getOB11Config();
|
||||||
|
if (!userConfig) return;
|
||||||
|
userConfig.network = config;
|
||||||
|
const success = await setOB11Config(userConfig);
|
||||||
|
if (success) {
|
||||||
|
MessagePlugin.success('配置保存成功');
|
||||||
|
} else {
|
||||||
|
MessagePlugin.error('配置保存失败');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const showAddTabDialog = () => {
|
||||||
|
newTab.value = { name: '', type: 'httpServers' };
|
||||||
|
isDialogVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const addTab = async () => {
|
||||||
|
const { name, type } = newTab.value;
|
||||||
|
if (clientPanelData.some(panel => panel.name === name)) {
|
||||||
|
MessagePlugin.error('选项卡名称已存在');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const defaultConfig = structuredClone(defaultConfigs[type]);
|
||||||
|
defaultConfig.name = name;
|
||||||
|
clientPanelData.push({ name, data: defaultConfig, key: type });
|
||||||
|
isDialogVisible.value = false;
|
||||||
|
await nextTick();
|
||||||
|
activeTab.value = clientPanelData.length - 1;
|
||||||
|
MessagePlugin.success('选项卡添加成功');
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeTab = async (payload: { value: string; index: number; e: PointerEvent }) => {
|
||||||
|
clientPanelData.splice(payload.index, 1);
|
||||||
|
activeTab.value = Math.max(0, activeTab.value - 1);
|
||||||
|
await saveConfig();
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
loadConfig();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.full-space {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.full-tabs {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.full-tab-panel {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style scoped>
|
||||||
|
.full-space {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.full-tabs {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.full-tab-panel {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -45,7 +45,6 @@ try {
|
|||||||
sed -i "s/\\"version\\": \\"${currentVersion}\\"/\\"version\\": \\"${targetVersion}\\"/g" package.json
|
sed -i "s/\\"version\\": \\"${currentVersion}\\"/\\"version\\": \\"${targetVersion}\\"/g" package.json
|
||||||
sed -i "s/\\"version\\": \\"${manifestCurrentVersion}\\"/\\"version\\": \\"${targetVersion}\\"/g" manifest.json
|
sed -i "s/\\"version\\": \\"${manifestCurrentVersion}\\"/\\"version\\": \\"${targetVersion}\\"/g" manifest.json
|
||||||
sed -i "s/napCatVersion = '.*'/napCatVersion = '${targetVersion}'/g" ./src/common/version.ts
|
sed -i "s/napCatVersion = '.*'/napCatVersion = '${targetVersion}'/g" ./src/common/version.ts
|
||||||
sed -i "s/SettingButton(\\"V.*\\", \\"napcat-update-button\\", \\"secondary\\")/SettingButton(\\"V${targetVersion}\\", \\"napcat-update-button\\", \\"secondary\\")/g" ./static/assets/renderer.js
|
|
||||||
git add .
|
git add .
|
||||||
git commit -m "release: v${targetVersion}"
|
git commit -m "release: v${targetVersion}"
|
||||||
git push -u origin main`;
|
git push -u origin main`;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user