mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2024-11-21 09:36:35 +00:00
feat: 渲染网络配置
This commit is contained in:
parent
a668bfbc13
commit
5c81b60b58
@ -1,13 +1,57 @@
|
||||
export class QQLoginManager {
|
||||
private retCredential: string;
|
||||
private apiprefix: string;
|
||||
|
||||
constructor(retCredential: string) {
|
||||
constructor(retCredential: string, apiprefix: string = 'http://127.0.0.1:6099/api') {
|
||||
this.retCredential = retCredential;
|
||||
this.apiprefix = apiprefix;
|
||||
}
|
||||
public async GetOB11Config(): Promise<any> {
|
||||
try {
|
||||
const ConfigResponse = await fetch(`${this.apiprefix}/OB11Config/GetConfig`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: 'Bearer ' + this.retCredential,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
if (ConfigResponse.status == 200) {
|
||||
const ConfigResponseJson = await ConfigResponse.json();
|
||||
if (ConfigResponseJson.code == 0) {
|
||||
return ConfigResponseJson?.data;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error getting OB11 config:", error);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
public async SetOB11Config(config: any): Promise<boolean> {
|
||||
try {
|
||||
const ConfigResponse = await fetch(`${this.apiprefix}/OB11Config/SetConfig`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: 'Bearer ' + this.retCredential,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ config: JSON.stringify(config) }),
|
||||
});
|
||||
if (ConfigResponse.status == 200) {
|
||||
const ConfigResponseJson = await ConfigResponse.json();
|
||||
if (ConfigResponseJson.code == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error setting OB11 config:", error);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public async checkQQLoginStatus(): Promise<boolean> {
|
||||
try {
|
||||
let QQLoginResponse = await fetch('../api/QQLogin/CheckLoginStatus', {
|
||||
let QQLoginResponse = await fetch(`${this.apiprefix}/QQLogin/CheckLoginStatus`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': "Bearer " + this.retCredential,
|
||||
@ -28,7 +72,7 @@ export class QQLoginManager {
|
||||
|
||||
public async checkWebUiLogined(): Promise<boolean> {
|
||||
try {
|
||||
let LoginResponse = await fetch('../api/auth/check', {
|
||||
let LoginResponse = await fetch(`${this.apiprefix}/auth/check`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': "Bearer " + this.retCredential,
|
||||
@ -37,7 +81,6 @@ export class QQLoginManager {
|
||||
});
|
||||
if (LoginResponse.status == 200) {
|
||||
let LoginResponseJson = await LoginResponse.json();
|
||||
//console.log(LoginResponseJson);
|
||||
if (LoginResponseJson.code == 0) {
|
||||
return true;
|
||||
}
|
||||
@ -50,7 +93,7 @@ export class QQLoginManager {
|
||||
|
||||
public async loginWithToken(token: string): Promise<string | null> {
|
||||
try {
|
||||
let loginResponse = await fetch('../api/auth/login', {
|
||||
let loginResponse = await fetch(`${this.apiprefix}/auth/login`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
@ -71,7 +114,7 @@ export class QQLoginManager {
|
||||
|
||||
public async getQQLoginQrcode(): Promise<string> {
|
||||
try {
|
||||
let QQLoginResponse = await fetch('../api/QQLogin/GetQQLoginQrcode', {
|
||||
let QQLoginResponse = await fetch(`${this.apiprefix}/QQLogin/GetQQLoginQrcode`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': "Bearer " + this.retCredential,
|
||||
@ -92,7 +135,7 @@ export class QQLoginManager {
|
||||
|
||||
public async getQQQuickLoginList(): Promise<string[]> {
|
||||
try {
|
||||
let QQLoginResponse = await fetch('../api/QQLogin/GetQuickLoginList', {
|
||||
let QQLoginResponse = await fetch(`${this.apiprefix}/QQLogin/GetQuickLoginList`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': "Bearer " + this.retCredential,
|
||||
@ -113,7 +156,7 @@ export class QQLoginManager {
|
||||
|
||||
public async setQuickLogin(uin: string): Promise<{ result: boolean, errMsg: string }> {
|
||||
try {
|
||||
let QQLoginResponse = await fetch('../api/QQLogin/SetQuickLogin', {
|
||||
let QQLoginResponse = await fetch(`${this.apiprefix}/QQLogin/SetQuickLogin`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': "Bearer " + this.retCredential,
|
||||
|
@ -20,7 +20,10 @@ import {
|
||||
Alert as TAlert,
|
||||
Tag as TTag,
|
||||
ListItem as TListItem,
|
||||
|
||||
Tabs as TTabs,
|
||||
TabPanel as TTabPanel,
|
||||
Space as TSpace,
|
||||
Checkbox as TCheckbox,
|
||||
} from 'tdesign-vue-next';
|
||||
import { router } from './router';
|
||||
import 'tdesign-vue-next/es/style/index.css';
|
||||
@ -46,4 +49,8 @@ app.use(TList);
|
||||
app.use(TAlert);
|
||||
app.use(TTag);
|
||||
app.use(TListItem);
|
||||
app.use(TTabs);
|
||||
app.use(TTabPanel);
|
||||
app.use(TSpace);
|
||||
app.use(TCheckbox);
|
||||
app.mount('#app');
|
@ -1,6 +1,113 @@
|
||||
<template>
|
||||
<div class="network-config">
|
||||
<h1>网络配置面板</h1>
|
||||
<p>这里显示面板的网络配置面板。</p>
|
||||
</div>
|
||||
<t-space>
|
||||
<t-tabs v-model="value" theme="card" :addable="true" @add="addTab" @remove="removeTab">
|
||||
<t-tab-panel v-for="data in panelData" :key="data.value" :value="data.value" :label="data.label"
|
||||
:removable="data.removable">
|
||||
<component :is="data.component" :config="data.config" />
|
||||
</t-tab-panel>
|
||||
</t-tabs>
|
||||
</t-space>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { defaultOnebotConfig, mergeOnebotConfigs } from '../../../src/onebot/config/config';
|
||||
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 componentMap = {
|
||||
'httpServers': HttpServerComponent,
|
||||
'httpClients': HttpClientComponent,
|
||||
'websocketServers': WebsocketServerComponent,
|
||||
'websocketClients': WebsocketClientComponent,
|
||||
};
|
||||
|
||||
const getOB11Config = async () => {
|
||||
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;
|
||||
};
|
||||
|
||||
const setOB11Config = async (config) => {
|
||||
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;
|
||||
};
|
||||
|
||||
const loadConfig = async () => {
|
||||
try {
|
||||
const userConfig = await getOB11Config();
|
||||
const mergedConfig = mergeOnebotConfigs(defaultOnebotConfig, userConfig);
|
||||
const networkConfig = mergedConfig.network;
|
||||
console.log('networkConfig:', networkConfig); // 添加日志输出
|
||||
const panels = [];
|
||||
|
||||
Object.keys(networkConfig).forEach((key) => {
|
||||
networkConfig[key].forEach((config, index) => {
|
||||
const component = componentMap[key];
|
||||
if (!component) {
|
||||
console.error(`No component found for key: ${key}`);
|
||||
return;
|
||||
}
|
||||
panels.push({
|
||||
value: `${key}-${index}`,
|
||||
label: `${config.name}`,
|
||||
component,
|
||||
config,
|
||||
removable: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
console.log('panels:', panels); // 添加日志输出
|
||||
panelData.value = panels;
|
||||
if (panels.length > 0) {
|
||||
value.value = panels[0].value;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error loading config:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const addTab = () => {
|
||||
panelData.value.push({
|
||||
value: `new-${id}`,
|
||||
label: `新选项卡${id + 1}`,
|
||||
removable: true,
|
||||
component: null,
|
||||
config: {},
|
||||
});
|
||||
value.value = `new-${id}`;
|
||||
id += 1;
|
||||
};
|
||||
|
||||
const removeTab = ({ value: val, index }) => {
|
||||
if (index < 0) return false;
|
||||
panelData.value.splice(index, 1);
|
||||
if (panelData.value.length === 0) return;
|
||||
if (value.value === val) {
|
||||
value.value = panelData.value[Math.max(index - 1, 0)].value;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
loadConfig();
|
||||
});
|
||||
</script>
|
29
napcat.webui/src/pages/network/HttpClientComponent.vue
Normal file
29
napcat.webui/src/pages/network/HttpClientComponent.vue
Normal file
@ -0,0 +1,29 @@
|
||||
<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>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineProps } from 'vue';
|
||||
defineProps({
|
||||
config: Object,
|
||||
});
|
||||
</script>
|
38
napcat.webui/src/pages/network/HttpServerComponent.vue
Normal file
38
napcat.webui/src/pages/network/HttpServerComponent.vue
Normal file
@ -0,0 +1,38 @@
|
||||
<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>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineProps } from 'vue';
|
||||
defineProps({
|
||||
config: Object,
|
||||
});
|
||||
</script>
|
32
napcat.webui/src/pages/network/WebsocketClientComponent.vue
Normal file
32
napcat.webui/src/pages/network/WebsocketClientComponent.vue
Normal file
@ -0,0 +1,32 @@
|
||||
<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>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineProps } from 'vue';
|
||||
defineProps({
|
||||
config: Object,
|
||||
});
|
||||
</script>
|
38
napcat.webui/src/pages/network/WebsocketServerComponent.vue
Normal file
38
napcat.webui/src/pages/network/WebsocketServerComponent.vue
Normal file
@ -0,0 +1,38 @@
|
||||
<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>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineProps } from 'vue';
|
||||
defineProps({
|
||||
config: Object,
|
||||
});
|
||||
</script>
|
@ -36,6 +36,13 @@ export async function InitWebUi(logger: LogWrapper, pathWrapper: NapCatPathWrapp
|
||||
// 配置静态文件服务,提供./static目录下的文件服务,访问路径为/webui
|
||||
app.use(config.prefix + '/webui', express.static(pathWrapper.staticPath));
|
||||
//挂载API接口
|
||||
// 添加CORS支持
|
||||
app.use((req, res, next) => {
|
||||
res.header('Access-Control-Allow-Origin', '*');
|
||||
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
||||
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
|
||||
next();
|
||||
});
|
||||
app.use(config.prefix + '/api', ALLRouter);
|
||||
app.listen(config.port, config.host, async () => {
|
||||
log(`[NapCat] [WebUi] Current WebUi is running at http://${config.host}:${config.port}${config.prefix}`);
|
||||
|
15
src/webui/src/api/BaseInfo.ts
Normal file
15
src/webui/src/api/BaseInfo.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { RequestHandler } from 'express';
|
||||
import { WebUiDataRuntime } from '../helper/Data';
|
||||
|
||||
export const LogFileListHandler: RequestHandler = async (req, res) => {
|
||||
res.send({
|
||||
code: 0,
|
||||
data: {
|
||||
uin: 0,
|
||||
nick: 'NapCat',
|
||||
avatar: 'https://q1.qlogo.cn/g?b=qq&nk=0&s=640',
|
||||
status: 'online',
|
||||
boottime: Date.now()
|
||||
}
|
||||
});
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user