chore(AI):前端逻辑优化
This commit is contained in:
@@ -4,47 +4,46 @@ import { MenuProps, message } from 'ant-design-vue';
|
||||
import { SettingOutlined, UserOutlined, WindowsOutlined } from '@ant-design/icons-vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import * as shell from '@tauri-apps/plugin-shell';
|
||||
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
async function contant() {
|
||||
await invoke("open_url", { url: "https://space.bilibili.com/1728953419" })
|
||||
|
||||
// 打开作者B站空间
|
||||
async function openAuthorBilibili() {
|
||||
await invoke("open_url", { url: "https://space.bilibili.com/1728953419" });
|
||||
}
|
||||
|
||||
//屏蔽右键菜单
|
||||
document.oncontextmenu = function (event: any) {
|
||||
// 屏蔽右键菜单(输入框和文本域除外)
|
||||
document.oncontextmenu = (event: any) => {
|
||||
try {
|
||||
var the = event.srcElement
|
||||
if (
|
||||
!(
|
||||
(the.tagName == 'INPUT' && the.type.toLowerCase() == 'text') ||
|
||||
the.tagName == 'TEXTAREA'
|
||||
)
|
||||
) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
const target = event.srcElement;
|
||||
const isInput = target.tagName === 'INPUT' && target.type.toLowerCase() === 'text';
|
||||
const isTextarea = target.tagName === 'TEXTAREA';
|
||||
return isInput || isTextarea;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/* 启动后端 */
|
||||
message.loading("DeEarthX.Core启动中,此过程中请勿执行任何操作......").then(() => {
|
||||
shell.Command.create("core").spawn().then(() => {
|
||||
fetch("http://localhost:37019/", { method: "GET" }).catch((e) => {
|
||||
router.push('/error')
|
||||
}).then(() => {
|
||||
message.success("DeEarthX.Core 启动成功")
|
||||
})
|
||||
console.log(`DeEarthX V3 Core`)
|
||||
}).catch((e) => {
|
||||
console.log(e)
|
||||
message.error("DeEarthX.Core 启动失败,请检查37019是否被占用!")
|
||||
})
|
||||
})
|
||||
const router = useRouter();
|
||||
const selectedKeys = ref(['main']);
|
||||
const items: MenuProps['items'] = [
|
||||
|
||||
// 启动后端核心服务
|
||||
message.loading("DeEarthX.Core启动中,请勿操作...").then(() => {
|
||||
shell.Command.create("core").spawn()
|
||||
.then(() => {
|
||||
// 检查后端服务是否成功启动
|
||||
fetch("http://localhost:37019/", { method: "GET" })
|
||||
.catch(() => router.push('/error'))
|
||||
.then(() => message.success("DeEarthX.Core 启动成功"));
|
||||
console.log("DeEarthX V3 Core");
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
message.error("DeEarthX.Core 启动失败,请检查37019端口是否被占用!");
|
||||
});
|
||||
});
|
||||
|
||||
// 导航菜单配置
|
||||
const selectedKeys = ref<(string | number)[]>(['main']);
|
||||
const menuItems: MenuProps['items'] = [
|
||||
{
|
||||
key: 'main',
|
||||
icon: h(WindowsOutlined),
|
||||
@@ -63,31 +62,26 @@ const items: MenuProps['items'] = [
|
||||
label: '关于',
|
||||
title: '关于',
|
||||
}
|
||||
]
|
||||
const handleClick: MenuProps['onClick'] = (e) => {
|
||||
switch (e.key) {
|
||||
case 'main':
|
||||
selectedKeys.value[0] = 'main';
|
||||
router.push('/');
|
||||
break;
|
||||
case 'setting':
|
||||
selectedKeys.value[0] = 'setting';
|
||||
router.push('/setting');
|
||||
break;
|
||||
case 'about':
|
||||
selectedKeys.value[0] = 'about';
|
||||
router.push('/about');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
// 菜单点击事件处理
|
||||
const handleMenuClick: MenuProps['onClick'] = (e) => {
|
||||
selectedKeys.value[0] = e.key;
|
||||
const routeMap: Record<string, string> = {
|
||||
main: '/',
|
||||
setting: '/setting',
|
||||
about: '/about'
|
||||
};
|
||||
const route = routeMap[e.key] || '/';
|
||||
router.push(route);
|
||||
};
|
||||
|
||||
// 主题配置
|
||||
const theme = ref({
|
||||
"token": {
|
||||
"colorPrimary": "#67eac3",
|
||||
token: {
|
||||
colorPrimary: '#67eac3',
|
||||
}
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -96,12 +90,12 @@ const theme = ref({
|
||||
<a-page-header class="tw:fixed tw:h-16" style="border: 1px solid rgb(235, 237, 240)" title="DeEarthX"
|
||||
sub-title="V3" :avatar="{ src: './public/dex.png' }">
|
||||
<template #extra>
|
||||
<a-button @click="contant">作者B站</a-button>
|
||||
<a-button @click="openAuthorBilibili">作者B站</a-button>
|
||||
</template>
|
||||
</a-page-header>
|
||||
<div class="tw:flex tw:full tw:h-89/100">
|
||||
<a-menu id="menu" style="width: 144px;" :selectedKeys="selectedKeys" mode="inline" :items="items"
|
||||
@click="handleClick" />
|
||||
<a-menu id="menu" style="width: 144px;" :selectedKeys="selectedKeys" mode="inline" :items="menuItems"
|
||||
@click="handleMenuClick" />
|
||||
<RouterView />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,162 +1,212 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { ref, watch } from 'vue';
|
||||
import { InboxOutlined } from '@ant-design/icons-vue';
|
||||
import { message, notification, StepsProps } from 'ant-design-vue';
|
||||
import type { UploadFile, UploadChangeParam } from 'ant-design-vue';
|
||||
import {sendNotification,} from '@tauri-apps/plugin-notification';
|
||||
import { sendNotification } from '@tauri-apps/plugin-notification';
|
||||
import { SelectProps } from 'ant-design-vue/es/vc-select';
|
||||
interface IWSM {
|
||||
status: "unzip"|"finish"|"changed"|"downloading"|"error",
|
||||
result: any
|
||||
|
||||
// WebSocket消息类型接口
|
||||
interface WebSocketMessage {
|
||||
status: 'unzip' | 'finish' | 'changed' | 'downloading' | 'error';
|
||||
result: any;
|
||||
}
|
||||
/* 进度显示区 */
|
||||
const disp_steps = ref(false);
|
||||
const setyps_current = ref(0);
|
||||
const setps_items: StepsProps['items'] = [{
|
||||
title: '解压整合包',
|
||||
description: '解压内容 下载文件'
|
||||
}, {
|
||||
title: '筛选模组',
|
||||
description: 'DeEarthX的心脏'
|
||||
}, {
|
||||
title: '下载服务端',
|
||||
description: '安装模组加载器服务端'
|
||||
}, {
|
||||
title: '完成',
|
||||
description: '一切就绪!'
|
||||
}]
|
||||
|
||||
/* 进度显示区 */
|
||||
// 进度步骤配置
|
||||
const showSteps = ref(false);
|
||||
const currentStep = ref(0);
|
||||
const stepItems: StepsProps['items'] = [
|
||||
{ title: '解压整合包', description: '解压内容并下载文件' },
|
||||
{ title: '筛选模组', description: 'DeEarthX的核心功能' },
|
||||
{ title: '下载服务端', description: '安装模组加载器服务端' },
|
||||
{ title: '完成', description: '一切就绪!' }
|
||||
];
|
||||
|
||||
/* 获取文件区 */
|
||||
const FileList = ref<UploadFile[]>([]);
|
||||
const isDisabled = ref(false);
|
||||
const BtnisDisabled = ref(false);
|
||||
// 文件上传相关
|
||||
const uploadedFiles = ref<UploadFile[]>([]);
|
||||
const uploadDisabled = ref(false);
|
||||
const startButtonDisabled = ref(false);
|
||||
|
||||
// 阻止默认上传行为
|
||||
function beforeUpload() {
|
||||
return false;
|
||||
}
|
||||
|
||||
function handleChange(info: UploadChangeParam) {
|
||||
// 处理文件上传变更
|
||||
function handleFileChange(info: UploadChangeParam) {
|
||||
if (!info.file.name?.endsWith('.zip') && !info.file.name?.endsWith('.mrpack')) {
|
||||
message.error('只能上传.zip和.mrpack文件');
|
||||
return;
|
||||
}
|
||||
isDisabled.value = true; //禁用
|
||||
uploadDisabled.value = true;
|
||||
}
|
||||
function handleDrop(e: DragEvent) {
|
||||
|
||||
// 处理文件拖拽(预留功能)
|
||||
function handleFileDrop(e: DragEvent) {
|
||||
console.log(e);
|
||||
}
|
||||
function handleUpload() {
|
||||
if (FileList.value.length === 0) {
|
||||
message.warning('请先拖拽或选择文件')
|
||||
return
|
||||
|
||||
// 重置所有状态
|
||||
function resetState() {
|
||||
uploadedFiles.value = [];
|
||||
uploadDisabled.value = false;
|
||||
startButtonDisabled.value = false;
|
||||
showSteps.value = false;
|
||||
currentStep.value = 0;
|
||||
unzipProgress.value = { status: 'active', percent: 0, display: true };
|
||||
downloadProgress.value = { status: 'active', percent: 0, display: true };
|
||||
}
|
||||
if (!FileList.value[0].originFileObj){
|
||||
|
||||
// 模式选择相关
|
||||
const javaAvailable = ref(true);
|
||||
const modeOptions: SelectProps['options'] = [
|
||||
{ label: '开服模式', value: 'server', disabled: !javaAvailable.value },
|
||||
{ label: '上传模式', value: 'upload', disabled: false }
|
||||
];
|
||||
const selectedMode = ref(javaAvailable.value ? 'server' : 'upload');
|
||||
|
||||
// 监听Java可用性变化,更新模式选项
|
||||
watch(javaAvailable, (newValue) => {
|
||||
modeOptions[0].disabled = !newValue;
|
||||
if (!newValue && selectedMode.value === 'server') {
|
||||
selectedMode.value = 'upload';
|
||||
}
|
||||
});
|
||||
|
||||
// 处理模式选择
|
||||
function handleModeSelect(value: string) {
|
||||
selectedMode.value = value;
|
||||
}
|
||||
|
||||
// 进度显示相关
|
||||
interface ProgressStatus {
|
||||
status: 'active' | 'success' | 'exception' | 'normal';
|
||||
percent: number;
|
||||
display: boolean;
|
||||
}
|
||||
const unzipProgress = ref<ProgressStatus>({ status: 'active', percent: 0, display: true });
|
||||
const downloadProgress = ref<ProgressStatus>({ status: 'active', percent: 0, display: true });
|
||||
|
||||
// 运行DeEarthX核心功能
|
||||
async function runDeEarthX(file: Blob) {
|
||||
message.success('开始制作,请勿切换菜单!');
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
|
||||
try {
|
||||
const response = await fetch(`http://localhost:37019/start?mode=${selectedMode.value}`, {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
await response.json();
|
||||
setupWebSocket();
|
||||
} catch (error) {
|
||||
console.error('请求失败:', error);
|
||||
message.error('请求后端服务失败');
|
||||
resetState();
|
||||
}
|
||||
}
|
||||
|
||||
// 设置WebSocket连接
|
||||
function setupWebSocket() {
|
||||
const ws = new WebSocket('ws://localhost:37019/');
|
||||
|
||||
ws.addEventListener('message', (event) => {
|
||||
try {
|
||||
const data = JSON.parse(event.data) as WebSocketMessage;
|
||||
|
||||
// 处理不同状态的消息
|
||||
switch (data.status) {
|
||||
case 'error':
|
||||
handleError(data.result);
|
||||
break;
|
||||
case 'changed':
|
||||
currentStep.value++;
|
||||
break;
|
||||
case 'unzip':
|
||||
updateUnzipProgress(data.result);
|
||||
break;
|
||||
case 'downloading':
|
||||
updateDownloadProgress(data.result);
|
||||
break;
|
||||
case 'finish':
|
||||
handleFinish(data.result);
|
||||
break;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('解析WebSocket消息失败:', error);
|
||||
notification.error({ message: '错误', description: '解析服务器消息失败' });
|
||||
}
|
||||
});
|
||||
|
||||
ws.addEventListener('error', () => {
|
||||
notification.error({ message: '错误', description: 'WebSocket连接失败' });
|
||||
resetState();
|
||||
});
|
||||
}
|
||||
|
||||
// 处理错误消息
|
||||
function handleError(result: any) {
|
||||
if (result === 'jini') {
|
||||
javaAvailable.value = false;
|
||||
message.error('未在系统变量中找到Java!请安装Java,否则开服模式将无法使用!');
|
||||
} else {
|
||||
notification.error({
|
||||
message: 'DeEarthX.Core 遇到致命错误!',
|
||||
description: `请将整个窗口截图发在群里\n错误信息:${result}`
|
||||
});
|
||||
resetState();
|
||||
}
|
||||
}
|
||||
|
||||
// 更新解压进度
|
||||
function updateUnzipProgress(result: { current: number; total: number }) {
|
||||
unzipProgress.value.percent = Math.round((result.current / result.total) * 100);
|
||||
if (result.current === result.total) {
|
||||
unzipProgress.value.status = 'success';
|
||||
setTimeout(() => {
|
||||
unzipProgress.value.display = false;
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新下载进度
|
||||
function updateDownloadProgress(result: { index: number; total: number }) {
|
||||
downloadProgress.value.percent = Math.round((result.index / result.total) * 100);
|
||||
if (downloadProgress.value.percent === 100) {
|
||||
downloadProgress.value.status = 'success';
|
||||
setTimeout(() => {
|
||||
downloadProgress.value.display = false;
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理完成状态
|
||||
function handleFinish(result: number) {
|
||||
const timeSpent = Math.round(result / 1000);
|
||||
currentStep.value++;
|
||||
message.success(`服务端制作完成!共用时${timeSpent}秒!`);
|
||||
sendNotification({ title: 'DeEarthX V3', body: `服务端制作完成!共用时${timeSpent}秒!` });
|
||||
|
||||
// 8秒后自动重置状态
|
||||
setTimeout(resetState, 8000);
|
||||
}
|
||||
|
||||
// 开始处理文件
|
||||
function handleStartProcess() {
|
||||
if (uploadedFiles.value.length === 0) {
|
||||
message.warning('请先拖拽或选择文件');
|
||||
return;
|
||||
}
|
||||
runDeEarthX(FileList.value[0].originFileObj) //获取文件内容
|
||||
BtnisDisabled.value = true; //禁用按钮
|
||||
isDisabled.value = true; //禁用上传
|
||||
disp_steps.value = true; //开始显示进度条
|
||||
}
|
||||
|
||||
function reactFL() {
|
||||
FileList.value = [];
|
||||
isDisabled.value = false;
|
||||
BtnisDisabled.value = false;
|
||||
disp_steps.value = false; //关闭进度条
|
||||
}
|
||||
/* 获取文件区 */
|
||||
function runDeEarthX(data: Blob) {
|
||||
//console.log(data)
|
||||
message.success("开始制作,请勿切换菜单!");
|
||||
const fd = new FormData();
|
||||
fd.append('file', data);
|
||||
console.log(fd.getAll('file'))
|
||||
fetch(`http://localhost:37019/start?mode=${Cselect.value}`,{
|
||||
method:'POST',
|
||||
body:fd
|
||||
}).then(async res=>res.json()).then(()=>{
|
||||
prews()
|
||||
})
|
||||
}
|
||||
const prog = ref({status:"active",percent:0,display:true})
|
||||
const dprog = ref({status:"active",percent:0,display:true})
|
||||
const CanO = ref(true);
|
||||
function prews(){
|
||||
const ws = new WebSocket('ws://localhost:37019/')
|
||||
// ws.addEventListener('message',(wsm)=>{
|
||||
// const _data = JSON.parse(wsm.data) as IWSM
|
||||
// if (_data.status === "changed") {
|
||||
// setyps_current.value ++;
|
||||
// }
|
||||
// logs.value.push({message:_data.result})
|
||||
// })
|
||||
ws.addEventListener('message',(wsm)=>{
|
||||
const _data = JSON.parse(wsm.data) as IWSM
|
||||
//console.log(_data)
|
||||
if (_data.status === "error" && _data.result === "jini") {
|
||||
CanO.value = false;
|
||||
message.error("未在系统变量中找到Java!请安装Java!否则开服模式将无法使用!")
|
||||
}
|
||||
if (_data.status === "changed") { //状态更改
|
||||
setyps_current.value ++;
|
||||
}
|
||||
if (_data.status === "unzip"){ //解压ZIP
|
||||
prog.value.percent = Math.round(((_data.result.current / _data.result.total) * 100))
|
||||
if (_data.result.current === _data.result.total){
|
||||
prog.value.status = "succees"
|
||||
setTimeout(()=>{
|
||||
prog.value.display = false;
|
||||
},2000)
|
||||
}
|
||||
}
|
||||
if (_data.status === "downloading"){ //下载文件
|
||||
dprog.value.percent = Math.round((_data.result.index / _data.result.total) * 100)
|
||||
if(dprog.value.percent === 100){
|
||||
dprog.value.status = "succees"
|
||||
setTimeout(()=>{
|
||||
dprog.value.display = false;
|
||||
},2000)
|
||||
}
|
||||
}
|
||||
if (_data.status === "finish"){
|
||||
console.log(_data.result)
|
||||
const time = Math.round(_data.result / 1000)
|
||||
setyps_current.value ++;
|
||||
message.success(`服务端制作完成!共用时${time}秒!`)
|
||||
sendNotification({ title: 'DeEarthX V3', body: `服务端制作完成!共用时${time}秒!` });
|
||||
setTimeout(()=>{ //恢复状态
|
||||
reactFL()
|
||||
},8*1000)
|
||||
}
|
||||
if (_data.status === "error"){
|
||||
notification.error({
|
||||
message: "DeEarth.X.Core 遇到了一个致命错误!",
|
||||
description:`请将整个窗口截图发在群里\n错误信息:${_data.result}`
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
const file = uploadedFiles.value[0].originFileObj;
|
||||
if (!file) return;
|
||||
|
||||
/* 选择区 */
|
||||
const Moptions = ref<SelectProps['options']>([
|
||||
{
|
||||
label: '开服模式',
|
||||
value: 'server',
|
||||
disabled: CanO.value ? false : true
|
||||
},
|
||||
{
|
||||
label: '上传模式',
|
||||
value: 'upload',
|
||||
disabled: false
|
||||
}
|
||||
])
|
||||
|
||||
const Cselect = ref(CanO ? 'server' : 'upload')
|
||||
|
||||
function handleSelect(value: string) {
|
||||
Cselect.value = value;
|
||||
runDeEarthX(file);
|
||||
startButtonDisabled.value = true;
|
||||
uploadDisabled.value = true;
|
||||
showSteps.value = true;
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
@@ -166,8 +216,8 @@ function handleSelect(value: string) {
|
||||
<h1 class="tw:text-4xl tw:text-center tw:animate-pulse">DeEarthX</h1>
|
||||
<h1 class="tw:text-sm tw:text-gray-500 tw:text-center">让开服变成随时随地的事情!</h1>
|
||||
</div>
|
||||
<a-upload-dragger :disabled="isDisabled" class="tw:w-144 tw:h-48" name="file" action="/" :multiple="false"
|
||||
:before-upload="beforeUpload" @change="handleChange" @drop="handleDrop" v-model:fileList="FileList"
|
||||
<a-upload-dragger :disabled="uploadDisabled" class="tw:w-144 tw:h-48" name="file" action="/" :multiple="false"
|
||||
:before-upload="beforeUpload" @change="handleFileChange" @drop="handleFileDrop" v-model:fileList="uploadedFiles"
|
||||
accept=".zip,.mrpack">
|
||||
<p class="ant-upload-drag-icon">
|
||||
<inbox-outlined></inbox-outlined>
|
||||
@@ -179,31 +229,31 @@ function handleSelect(value: string) {
|
||||
</a-upload-dragger>
|
||||
<a-select
|
||||
ref="select"
|
||||
:options="Moptions"
|
||||
:value="Cselect"
|
||||
:options="modeOptions"
|
||||
:value="selectedMode"
|
||||
style="width: 120px;margin-top: 32px"
|
||||
@select="handleSelect"
|
||||
@select="handleModeSelect"
|
||||
></a-select>
|
||||
<a-button :disabled="BtnisDisabled" type="primary" @click="handleUpload" style="margin-top: 6px">
|
||||
<a-button :disabled="startButtonDisabled" type="primary" @click="handleStartProcess" style="margin-top: 6px">
|
||||
开始
|
||||
</a-button>
|
||||
</div>
|
||||
<div v-if="disp_steps"
|
||||
<div v-if="showSteps"
|
||||
class="tw:fixed tw:bottom-2 tw:ml-4 tw:w-272 tw:h-16 tw:flex tw:justify-center tw:items-center tw:text-sm">
|
||||
<a-steps :current="setyps_current" :items="setps_items" />
|
||||
<a-steps :current="currentStep" :items="stepItems" />
|
||||
</div>
|
||||
<!-- <div class="tw:absolute tw:bottom-20 tw:right-2 tw:h-16 tw:w-16">
|
||||
|
||||
</div> -->
|
||||
<div v-if="disp_steps" ref="logContainer" class="tw:absolute tw:right-2 tw:bottom-20 tw:h-80 tw:w-56 tw:rounded-xl tw:container tw:overflow-y-auto">
|
||||
<div v-if="showSteps" ref="logContainer" class="tw:absolute tw:right-2 tw:bottom-20 tw:h-80 tw:w-56 tw:rounded-xl tw:container tw:overflow-y-auto">
|
||||
<a-card title="制作进度" :bordered="true">
|
||||
<div v-if="prog.display">
|
||||
<div v-if="unzipProgress.display">
|
||||
<h1>解压进度</h1>
|
||||
<a-progress :percent="prog.percent" :status="prog.status" size="small" />
|
||||
<a-progress :percent="unzipProgress.percent" :status="unzipProgress.status" size="small" />
|
||||
</div>
|
||||
<div v-if="dprog.display">
|
||||
<div v-if="downloadProgress.display">
|
||||
<h1>下载进度</h1>
|
||||
<a-progress :percent="dprog.percent" :status="dprog.status" size="small" />
|
||||
<a-progress :percent="downloadProgress.percent" :status="downloadProgress.status" size="small" />
|
||||
</div>
|
||||
</a-card>
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch } from 'vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
/* Config */
|
||||
interface IConfig {
|
||||
|
||||
// 配置接口定义
|
||||
interface AppConfig {
|
||||
mirror: {
|
||||
bmclapi: boolean;
|
||||
mcimirror: boolean;
|
||||
@@ -12,38 +13,61 @@ interface IConfig {
|
||||
dexpub: boolean;
|
||||
mixins: boolean;
|
||||
};
|
||||
oaf: boolean
|
||||
oaf: boolean; // 操作完成后打开目录
|
||||
}
|
||||
const config = ref<IConfig>({ mirror: { bmclapi: false, mcimirror: false }, filter: { hashes: false, dexpub: false, mixins: false }, oaf: false})
|
||||
fetch('http://localhost:37019/config/get', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then(res => res.json()).then(res => config.value = res)
|
||||
|
||||
let first = true;
|
||||
watch(config, (newv) => { //写入Config
|
||||
if (!first) {
|
||||
fetch('http://localhost:37019/config/post', {
|
||||
// 配置状态
|
||||
const config = ref<AppConfig>({
|
||||
mirror: { bmclapi: false, mcimirror: false },
|
||||
filter: { hashes: false, dexpub: false, mixins: false },
|
||||
oaf: false
|
||||
});
|
||||
|
||||
// 从后端加载配置
|
||||
async function loadConfig() {
|
||||
try {
|
||||
const response = await fetch('http://localhost:37019/config/get', {
|
||||
method: 'GET',
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
if (response.ok) {
|
||||
config.value = await response.json();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载配置失败:', error);
|
||||
message.error('加载配置失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 保存配置到后端
|
||||
async function saveConfig(newConfig: AppConfig) {
|
||||
try {
|
||||
const response = await fetch('http://localhost:37019/config/post', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(newv)
|
||||
}).then(res => {
|
||||
if (res.status === 200) {
|
||||
message.success('配置已保存')
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(newConfig)
|
||||
});
|
||||
if (response.ok) {
|
||||
message.success('配置已保存');
|
||||
}
|
||||
})
|
||||
// shell.Command.create('core',['writeconfig',JSON.stringify(newv)]).execute().then(()=>{
|
||||
// message.success('配置已保存')
|
||||
// })
|
||||
console.log(newv)
|
||||
return
|
||||
} catch (error) {
|
||||
console.error('保存配置失败:', error);
|
||||
message.error('保存配置失败');
|
||||
}
|
||||
first = false;
|
||||
}, { deep: true })
|
||||
}
|
||||
|
||||
// 初始化时加载配置
|
||||
loadConfig();
|
||||
|
||||
// 监听配置变化并保存
|
||||
let isInitialLoad = true;
|
||||
watch(config, (newValue) => {
|
||||
if (isInitialLoad) {
|
||||
isInitialLoad = false;
|
||||
return;
|
||||
}
|
||||
saveConfig(newValue);
|
||||
}, { deep: true });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
Reference in New Issue
Block a user