🏗️ refactor configuration management and implement system service features

This commit is contained in:
刘嘉伟 2025-02-24 16:38:39 +08:00
parent 6d9f9269b7
commit ff8b01c360
16 changed files with 391 additions and 260 deletions

View File

@ -1,27 +0,0 @@
import { app, ipcMain, shell } from "electron";
import { logError, logInfo, LogModule, logWarn } from "../utils/log";
export const initCommonApi = () => {
ipcMain.on("common.openUrl", async (event, args) => {
if (args) {
logInfo(LogModule.APP, `Attempting to open URL: ${args}`);
try {
await shell.openExternal(args);
logInfo(LogModule.APP, `Successfully opened URL: ${args}`);
} catch (error) {
logError(
LogModule.APP,
`Failed to open URL: ${args}. Error: ${error.message}`
);
}
} else {
logWarn(LogModule.APP, "No URL provided to open.");
}
});
ipcMain.on("common.relaunch", () => {
logInfo(LogModule.APP, "Application is relaunching.");
app.relaunch();
app.quit();
});
};

View File

@ -0,0 +1,80 @@
import BaseController from "./BaseController";
import ServerService from "../service/ServerService";
import { success } from "../utils/response";
import PathUtils from "../utils/PathUtils";
import fs from "fs";
import FrpcProcessService from "../service/FrpcProcessService";
import SystemService from "../service/SystemService";
class ConfigController extends BaseController {
private readonly _serverService: ServerService;
private readonly _systemService: SystemService;
private readonly _frpcProcessService: FrpcProcessService;
constructor(
serverService: ServerService,
systemService: SystemService,
frpcProcessService: FrpcProcessService
) {
super();
this._serverService = serverService;
this._systemService = systemService;
this._frpcProcessService = frpcProcessService;
}
saveConfig(req: ControllerParam) {
this._serverService.saveServerConfig(req.args).then(() => {
req.event.reply(req.channel, success());
});
}
getServerConfig(req: ControllerParam) {
this._serverService.getServerConfig().then(data => {
req.event.reply(req.channel, success(data));
});
}
openAppData(req: ControllerParam) {
this._systemService.openLocalPath(PathUtils.getAppData()).then(data => {
req.event.reply(req.channel, success(data));
});
}
async resetAllConfig(req: ControllerParam) {
// await this._serverDao.truncate();
// await this._proxyDao.truncate();
// await this._versionDao.truncate();
await this._frpcProcessService.stopFrpcProcess();
fs.rmSync(PathUtils.getDataBaseStoragePath(), {
recursive: true,
force: true
});
fs.rmSync(PathUtils.getDownloadStoragePath(), {
recursive: true,
force: true
});
fs.rmSync(PathUtils.getVersionStoragePath(), {
recursive: true,
force: true
});
fs.rmSync(PathUtils.getFrpcLogStoragePath(), {
recursive: true,
force: true
});
req.event.reply(req.channel, success());
}
exportConfig(req: ControllerParam) {
this._systemService.openDirectory().then(folder => {
this._serverService.genTomlConfig(folder.filePaths[0]).then(() => {
req.event.reply(req.channel, success());
});
});
}
}
export default ConfigController;

View File

@ -11,9 +11,14 @@ class LaunchController extends BaseController {
}
launch(req: ControllerParam) {
this._frpcProcessService.startFrpcProcess().then(r => {
req.event.reply(req.channel, success());
});
this._frpcProcessService
.startFrpcProcess()
.then(r => {
req.event.reply(req.channel, success());
})
.catch(err => {
console.log(err, "1");
});
}
terminate(req: ControllerParam) {

View File

@ -1,37 +0,0 @@
import BaseController from "./BaseController";
import ServerService from "../service/ServerService";
import { success } from "../utils/response";
import FileService from "../service/FileService";
import PathUtils from "../utils/PathUtils";
class ServerController extends BaseController {
private readonly _serverService: ServerService;
private readonly _fileService: FileService;
constructor(serverService: ServerService, fileService: FileService) {
super();
this._serverService = serverService;
this._fileService = fileService;
}
saveConfig(req: ControllerParam) {
this._serverService.saveServerConfig(req.args).then(() => {
req.event.reply(req.channel, success());
});
}
getServerConfig(req: ControllerParam) {
console.log("get", req.args);
this._serverService.getServerConfig().then(data => {
req.event.reply(req.channel, success(data));
});
}
openAppData(req: ControllerParam) {
this._fileService.openLocalPath(PathUtils.getAppData()).then(data => {
req.event.reply(req.channel, success(data));
});
}
}
export default ServerController;

View File

@ -0,0 +1,36 @@
import SystemService from "../service/SystemService";
import { fail, success } from "../utils/response";
import PathUtils from "../utils/PathUtils";
class SystemController {
private readonly _systemService: SystemService;
constructor(systemService: SystemService) {
this._systemService = systemService;
}
openUrl(req: ControllerParam) {
this._systemService
.openUrl(req.args.url)
.then(() => {
req.event.reply(req.channel, success());
})
.catch(err => {
req.event.reply(req.channel, fail());
});
}
relaunchApp(req: ControllerParam) {
this._systemService.relaunch().then(() => {
req.event.reply(req.channel, success());
});
}
openAppData(req: ControllerParam) {
this._systemService.openLocalPath(PathUtils.getAppData()).then(() => {
req.event.reply(req.channel, success());
});
}
}
export default SystemController;

View File

@ -1,4 +1,4 @@
import ServerController from "../controller/ServerController";
import ConfigController from "../controller/ConfigController";
import ServerDao from "../dao/ServerDao";
import ServerService from "../service/ServerService";
import LogService from "../service/LogService";
@ -6,7 +6,6 @@ import VersionService from "../service/VersionService";
import { BrowserWindow, ipcMain } from "electron";
import LogController from "../controller/LogController";
import VersionController from "../controller/VersionController";
import FileService from "../service/FileService";
import VersionDao from "../dao/VersionDao";
import GitHubService from "../service/GitHubService";
import FrpcProcessService from "../service/FrpcProcessService";
@ -14,16 +13,26 @@ import LaunchController from "../controller/LaunchController";
import ProxyDao from "../dao/ProxyDao";
import ProxyService from "../service/ProxyService";
import ProxyController from "../controller/ProxyController";
import SystemService from "../service/SystemService";
import SystemController from "../controller/SystemController";
export const ipcRouters: IpcRouters = {
SERVER: {
saveConfig: {
path: "server/saveConfig",
controller: "serverController.saveConfig"
controller: "configController.saveConfig"
},
getServerConfig: {
path: "server/getServerConfig",
controller: "serverController.getServerConfig"
controller: "configController.getServerConfig"
},
resetAllConfig: {
path: "server/resetAllConfig",
controller: "configController.resetAllConfig"
},
exportConfig: {
path: "server/exportConfig",
controller: "configController.exportConfig"
}
},
LOG: {
@ -97,6 +106,20 @@ export const ipcRouters: IpcRouters = {
path: "proxy/getLocalPorts",
controller: "proxyController.getLocalPorts"
}
},
SYSTEM: {
openUrl: {
path: "system/openUrl",
controller: "systemController.openUrl"
},
relaunchApp: {
path: "system/relaunchApp",
controller: "systemController.relaunchApp"
},
openAppData: {
path: "system/openAppData",
controller: "systemController.openAppData"
}
}
};
@ -124,40 +147,46 @@ class IpcRouterConfigurate {
const serverDao = new ServerDao();
const versionDao = new VersionDao();
const proxyDao = new ProxyDao();
const fileService = new FileService();
const systemService = new SystemService();
const serverService = new ServerService(serverDao, proxyDao);
const gitHubService = new GitHubService();
const versionService = new VersionService(
versionDao,
fileService,
systemService,
gitHubService
);
const logService = new LogService(fileService);
const logService = new LogService(systemService);
const frpcProcessService = new FrpcProcessService(
serverService,
versionDao
);
const proxyService = new ProxyService(proxyDao);
const serverController = new ServerController(serverService, fileService);
const configController = new ConfigController(
serverService,
systemService,
frpcProcessService
);
const versionController = new VersionController(versionService, versionDao);
const logController = new LogController(logService);
const launchController = new LaunchController(frpcProcessService);
const proxyController = new ProxyController(proxyService, proxyDao);
const systemController = new SystemController(systemService);
this._beans.set("serverDao", serverDao);
this._beans.set("versionDao", versionDao);
this._beans.set("proxyDao", proxyDao);
this._beans.set("fileService", fileService);
this._beans.set("systemService", systemService);
this._beans.set("serverService", serverService);
this._beans.set("versionService", versionService);
this._beans.set("logService", logService);
this._beans.set("proxyService", proxyService);
this._beans.set("frpcProcessService", frpcProcessService);
this._beans.set("serverController", serverController);
this._beans.set("configController", configController);
this._beans.set("versionController", versionController);
this._beans.set("logController", logController);
this._beans.set("launchController", launchController);
this._beans.set("proxyController", proxyController);
this._beans.set("systemController", systemController);
}
/**

View File

@ -24,7 +24,10 @@ class BaseDao<T> {
protected readonly db: Datastore;
constructor(dbName: string) {
const dbFilename = path.join(PathUtils.getDataBaseStoragePath(), `${dbName}-v2.db`);
const dbFilename = path.join(
PathUtils.getDataBaseStoragePath(),
`${dbName}-v2.db`
);
this.db = new Datastore({
autoload: true,
filename: dbFilename
@ -118,6 +121,18 @@ class BaseDao<T> {
});
});
}
truncate() {
return new Promise<void>((resolve, reject) => {
this.db.remove({}, { multi: true }, (err, n) => {
if (err) {
reject(err);
} else {
resolve();
}
});
});
}
}
export default BaseDao;

View File

@ -12,14 +12,9 @@ import { release } from "node:os";
import node_path, { join } from "node:path";
import { initGitHubApi } from "../api/github";
import { initConfigApi } from "../api/config";
import {
initFrpcApi,
startFrpWorkerProcess,
stopFrpcProcess
} from "../api/frpc";
import { startFrpWorkerProcess, stopFrpcProcess } from "../api/frpc";
import { initFileApi } from "../api/file";
import { getConfig } from "../storage/config";
import { initCommonApi } from "../api/common";
import { initLog, logError, logInfo, LogModule } from "../utils/log";
import { maskSensitiveData } from "../utils/desensitize";
import IpcRouterConfigurate from "../core/IpcRouter";
@ -202,8 +197,6 @@ app.whenReady().then(() => {
initFileApi();
logInfo(LogModule.APP, `File API initialized.`);
initCommonApi();
logInfo(LogModule.APP, `Common API initialized.`);
// initUpdaterApi(win);
logInfo(LogModule.APP, `Updater API initialization skipped.`);

View File

@ -30,12 +30,19 @@ class FrpcProcessService {
}
async startFrpcProcess() {
if (this.isRunning()) {
return;
}
const config = await this._serverService.getServerConfig();
if (!config) {
throw new Error("请先进行配置")
}
const version = await this._versionDao.findByGithubReleaseId(
config.frpcVersion
);
// todo genConfigfile.
const configPath = await this._serverService.genTomlConfig();
const configPath = PathUtils.getTomlConfigFilePath();
await this._serverService.genTomlConfig(configPath);
const command = `./${PathUtils.getFrpcFilename()} -c "${configPath}"`;
this._frpcProcess = require("child_process").spawn(command, {
cwd: version.localPath,
@ -48,13 +55,10 @@ class FrpcProcessService {
this._frpcProcess.stderr.on("data", data => {
console.error(`stderr: ${data}`);
});
// this._frpcProcess.on("close",function(code){
// console.log("out code:" + code)
// })
}
async stopFrpcProcess() {
if (this._frpcProcess) {
if (this._frpcProcess && this.isRunning()) {
treeKill(this._frpcProcess.pid, (error: Error) => {
if (error) {
throw error;
@ -63,7 +67,6 @@ class FrpcProcessService {
// clearInterval(this._frpcProcessListener);
}
});
} else {
}
}

View File

@ -1,18 +1,14 @@
import fs from "fs";
import path from "path";
import { app } from "electron";
import FileService from "./FileService";
import { success } from "../utils/response";
import PathUtils from "../utils/PathUtils";
import SystemService from "./SystemService";
class LogService {
private readonly _fileService: FileService;
private readonly _logPath: string = path.join(
app.getPath("userData"),
"frpc.log"
);
private readonly _systemService: SystemService;
private readonly _logPath: string = PathUtils.getFrpcLogFilePath();
constructor(fileService: FileService) {
this._fileService = fileService;
constructor(systemService: SystemService) {
this._systemService = systemService;
}
getFrpLogContent(): Promise<string> {
@ -28,6 +24,11 @@ class LogService {
}
watchFrpcLog(listenerParam: ListenerParam) {
if (!fs.existsSync(this._logPath)) {
setTimeout(() => this.watchFrpcLog(listenerParam), 1000);
return;
}
console.log('watchFrpcLog succcess');
fs.watch(this._logPath, (eventType, filename) => {
if (eventType === "change") {
console.log("change", eventType, listenerParam.channel);
@ -45,7 +46,7 @@ class LogService {
openFrpcLogFile(): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
this._fileService
this._systemService
.openLocalFile(this._logPath)
.then(result => {
resolve(result);

View File

@ -38,7 +38,10 @@ class ServerService extends BaseService<OpenSourceFrpcDesktopServer> {
});
}
async genTomlConfig() {
async genTomlConfig(outputPath: string) {
if (!outputPath) {
return;
}
const server = await this.getServerConfig();
const proxies = await this._proxyDao.findAll();
const enabledProxies = proxies
@ -51,13 +54,12 @@ class ServerService extends BaseService<OpenSourceFrpcDesktopServer> {
const frpcConfig = { ...commonConfig };
frpcConfig.log.to = PathUtils.getFrpcLogFilePath();
const toml = TOML.stringify({ ...frpcConfig, proxies: enabledProxies });
const tomlPath = PathUtils.getTomlConfigFilePath();
fs.writeFileSync(
tomlPath, // 配置文件目录
outputPath, // 配置文件目录
toml, // 配置文件内容
{ flag: "w" }
);
return tomlPath;
}
}

View File

@ -1,16 +1,23 @@
import { dialog, shell } from "electron";
import { app, dialog, shell } from "electron";
import GlobalConstant from "../core/GlobalConstant";
import path from "path";
import fs from "fs";
import zlib from "zlib";
import admZip from "adm-zip";
import GlobalConstant from "../core/GlobalConstant";
// import tar from "tar";
const tar = require("tar");
class FileService {
constructor() {}
class SystemService {
async openUrl(url: string) {
if (url) {
await shell.openExternal(url);
}
}
async relaunch() {
await app.relaunch();
app.quit();
}
openLocalFile(filePath: string) {
return new Promise<boolean>((resolve, reject) => {
@ -100,17 +107,23 @@ class FileService {
});
}
selectLocalFile(name: string, path: any) {
dialog.showOpenDialogSync({
openFile(name: string, ext: any) {
return dialog.showOpenDialogSync({
properties: ["openFile"],
filters: [
{
name: name,
extensions: path
extensions: ext
}
]
});
}
async openDirectory() {
return await dialog.showOpenDialog({
properties: ["openDirectory"]
});
}
}
export default FileService;
export default SystemService;

View File

@ -1,7 +1,6 @@
import VersionDao from "../dao/VersionDao";
import BaseService from "./BaseService";
import GitHubService from "./GitHubService";
import FileService from "./FileService";
import frpReleasesJson from "../json/frp-releases.json";
import { download } from "electron-dl";
import { BrowserWindow, dialog } from "electron";
@ -12,23 +11,24 @@ import SecureUtils from "../utils/SecureUtils";
import PathUtils from "../utils/PathUtils";
import FileUtils from "../utils/FileUtils";
import frpChecksums from "../json/frp_all_sha256_checksums.json";
import SystemService from "./SystemService";
class VersionService extends BaseService<FrpcVersion> {
private readonly _versionDao: VersionDao;
private readonly _fileService: FileService;
private readonly _systemService: SystemService;
private readonly _gitHubService: GitHubService;
private readonly _currFrpArch: Array<string>;
private _versions: Array<FrpcVersion> = [];
constructor(
versionDao: VersionDao,
fileService: FileService,
systemService: SystemService,
gitHubService: GitHubService
) {
super();
this._versionDao = versionDao;
this._gitHubService = gitHubService;
this._fileService = fileService;
this._systemService = systemService;
const nodeVersion = `${process.platform}_${process.arch}`;
this._currFrpArch = GlobalConstant.FRP_ARCH_VERSION_MAPPING[nodeVersion];
}
@ -207,13 +207,13 @@ class VersionService extends BaseService<FrpcVersion> {
);
const ext = path.extname(version.assetName);
if (ext === GlobalConstant.ZIP_EXT) {
this._fileService.decompressZipFile(compressedPath, versionFilePath);
this._systemService.decompressZipFile(compressedPath, versionFilePath);
// todo delete frps and other file.
} else if (
ext === GlobalConstant.GZ_EXT &&
version.assetName.includes(GlobalConstant.TAR_GZ_EXT)
) {
this._fileService.decompressTarGzFile(
this._systemService.decompressTarGzFile(
compressedPath,
versionFilePath,
() => {

View File

@ -1,11 +1,12 @@
<script lang="ts" setup>
import {computed, defineComponent, onMounted, onUnmounted, ref} from "vue";
import {ipcRenderer} from "electron";
import {Icon} from "@iconify/vue";
import { computed, defineComponent, onMounted, onUnmounted, ref } from "vue";
import { ipcRenderer } from "electron";
import { Icon } from "@iconify/vue";
import Breadcrumb from "@/layout/compoenets/Breadcrumb.vue";
import pkg from '../../../package.json';
import {ElMessage, ElMessageBox} from "element-plus";
import pkg from "../../../package.json";
import { ElMessage, ElMessageBox } from "element-plus";
import { send } from "@/utils/ipcUtils";
import { ipcRouters } from "../../../electron/core/IpcRouter";
/**
* 最后一个版本号
@ -17,143 +18,161 @@ const isLastVersion = computed(() => {
return true;
}
// tagName
const tagName = latestVersionInfo.value['tag_name']
console.log(tagName, latestVersionInfo.value, 'tagName')
const tagName = latestVersionInfo.value["tag_name"];
console.log(tagName, latestVersionInfo.value, "tagName");
if (!tagName) {
return true;
}
//
const lastVersion = tagName.replace('v', '').toString();
const lastVersion = tagName.replace("v", "").toString();
const currVersion = pkg.version;
console.log(lastVersion, currVersion, currVersion >= lastVersion, "isLast")
console.log(lastVersion, currVersion, currVersion >= lastVersion, "isLast");
// console.log()
return currVersion >= lastVersion;
// return false;
})
});
/**
* 打开github issues
*/
const handleOpenGitHubIssues = () => {
ipcRenderer.send("common.openUrl", "https://github.com/luckjiawei/frpc-desktop/issues")
}
send(ipcRouters.SYSTEM.openUrl, {
url: "https://github.com/luckjiawei/frpc-desktop/issues"
});
};
/**
* 打开github主页
*/
const handleOpenGitHub = () => {
ipcRenderer.send("common.openUrl", "https://github.com/luckjiawei/frpc-desktop")
}
send(ipcRouters.SYSTEM.openUrl, {
url: "https://github.com/luckjiawei/frpc-desktop"
});
};
/**
* 打开捐赠界面
*/
const handleOpenDonate = () => {
ipcRenderer.send("common.openUrl", "https://jwinks.com/donate")
}
send(ipcRouters.SYSTEM.openUrl, {
url: "https://jwinks.com/donate"
});
};
/**
* 打开文档
*/
const handleOpenDoc = () => {
ipcRenderer.send("common.openUrl", "https://jwinks.com/p/frp")
}
send(ipcRouters.SYSTEM.openUrl, {
url: "https://jwinks.com/p/frp"
});
};
/**
* 获取最后一个版本
*/
const handleGetLastVersion = () => {
ipcRenderer.send("github.getFrpcDesktopLastVersions")
}
ipcRenderer.send("github.getFrpcDesktopLastVersions");
};
const handleOpenNewVersion = () => {
ipcRenderer.send("common.openUrl", latestVersionInfo.value['html_url'])
}
ipcRenderer.send("common.openUrl", latestVersionInfo.value["html_url"]);
};
onMounted(() => {
ipcRenderer.on("github.getFrpcDesktopLastVersionsHook", (event, args) => {
latestVersionInfo.value = args;
console.log(latestVersionInfo.value, '1')
console.log(latestVersionInfo.value, "1");
if (!isLastVersion.value) {
let content = latestVersionInfo.value.body
content = content.replaceAll('\n', '<br/>')
let content = latestVersionInfo.value.body;
content = content.replaceAll("\n", "<br/>");
ElMessageBox.alert(content, `🎉 发现新版本 ${args.name}`, {
showCancelButton: true,
cancelButtonText: "关闭",
dangerouslyUseHTMLString: true,
confirmButtonText: "去下载"
}).then(() => {
handleOpenNewVersion()
})
handleOpenNewVersion();
});
} else {
ElMessage({
message: "当前已是最新版本",
type: "success"
})
});
}
});
handleGetLastVersion();
})
});
onUnmounted(() => {
ipcRenderer.removeAllListeners("github.getFrpcDesktopLastVersionsHook");
})
});
defineComponent({
name: "About"
});
</script>
<template>
<div class="main">
<breadcrumb/>
<breadcrumb />
<div class="app-container-breadcrumb">
<div
class="w-full h-full bg-white p-4 rounded drop-shadow-lg overflow-y-auto flex justify-center items-center flex-col"
class="w-full h-full bg-white p-4 rounded drop-shadow-lg overflow-y-auto flex justify-center items-center flex-col"
>
<img src="/logo/pack/1024x1024.png"
class="w-[95px] h-[95px] mt-[-50px] animate__animated animate__flip" alt="Logo"/>
<img
src="/logo/pack/1024x1024.png"
class="w-[95px] h-[95px] mt-[-50px] animate__animated animate__flip"
alt="Logo"
/>
<div class="mt-[8px] text-2xl">Frpc Desktop</div>
<div class="mt-[8px] text-neutral-400 flex items-center">
<el-link
:class="!isLastVersion? 'line-through': ''"
class="ml-2 font-bold">v{{ pkg.version }}
:class="!isLastVersion ? 'line-through' : ''"
class="ml-2 font-bold"
>v{{ pkg.version }}
</el-link>
<el-link v-if="!isLastVersion && latestVersionInfo"
@click="handleOpenNewVersion"
class="ml-2 text-[#67C23A] font-bold"
type="success">v{{ latestVersionInfo.name }}
<el-link
v-if="!isLastVersion && latestVersionInfo"
@click="handleOpenNewVersion"
class="ml-2 text-[#67C23A] font-bold"
type="success"
>v{{ latestVersionInfo.name }}
</el-link>
<IconifyIconOffline class="ml-1.5 cursor-pointer check-update" icon="refresh-rounded"
@click="handleGetLastVersion"/>
<IconifyIconOffline
class="ml-1.5 cursor-pointer check-update"
icon="refresh-rounded"
@click="handleGetLastVersion"
/>
</div>
<div class="mt-[8px] text-sm text-center">
<p>
🎉 {{ pkg.description }}
</p>
<p>
开机自启 / 可视化配置 / 免费开源
</p>
<p>🎉 {{ pkg.description }}</p>
<p>开机自启 / 可视化配置 / 免费开源</p>
</div>
<div class="mt-[12px]">
<el-button plain type="success" @click="handleOpenDoc">
<IconifyIconOffline class="cursor-pointer mr-2" icon="description"/>
<IconifyIconOffline
class="cursor-pointer mr-2"
icon="description"
/>
使用教程
</el-button>
<el-button plain type="success" @click="handleOpenDonate">
<IconifyIconOffline class="cursor-pointer mr-2" icon="volunteer-activism-sharp"/>
<IconifyIconOffline
class="cursor-pointer mr-2"
icon="volunteer-activism-sharp"
/>
捐赠名单
</el-button>
<el-button plain type="primary" @click="handleOpenGitHub">
<Icon class="cursor-pointer mr-2" icon="logos:github-icon"/>
<Icon class="cursor-pointer mr-2" icon="logos:github-icon" />
仓库地址
</el-button>
<el-button type="danger" plain @click="handleOpenGitHubIssues">
<IconifyIconOffline class="cursor-pointer mr-2" icon="question-mark"/>
<IconifyIconOffline
class="cursor-pointer mr-2"
icon="question-mark"
/>
反馈问题
</el-button>
</div>
@ -164,6 +183,6 @@ defineComponent({
<style lang="scss" scoped>
.check-update:hover {
color: #5F3BB0;
color: #5f3bb0;
}
</style>

View File

@ -9,6 +9,7 @@ import { Base64 } from "js-base64";
import IconifyIconOffline from "@/components/IconifyIcon/src/iconifyIconOffline";
import { on, removeRouterListeners, send } from "@/utils/ipcUtils";
import { ipcRouters } from "../../../electron/core/IpcRouter";
import confetti from "canvas-confetti/src/confetti.js";
defineComponent({
name: "Config"
@ -350,45 +351,40 @@ onMounted(() => {
// ElMessageBox.alert(`${configPath}`, `🎉 `);
// }
// });
// ipcRenderer.on("Config.clearAll.hook", (event, args) => {
// ElMessageBox.alert(" ", ``, {
// closeOnClickModal: false,
// showClose: false,
// confirmButtonText: ""
// }).then(() => {
// ipcRenderer.send("common.relaunch");
// });
// });
// ipcRenderer.on("Config.importConfig.hook", (event, args) => {
// const { success, data } = args;
// if (success) {
// //
// confetti({
// zIndex: 12002,
// particleCount: 200,
// spread: 70,
// origin: { y: 0.6 }
// });
// ElMessageBox.alert("🎉 ", ``, {
// closeOnClickModal: false,
// showClose: false,
// confirmButtonText: ""
// }).then(() => {
// ipcRenderer.send("common.relaunch");
// });
// } else {
// ElMessageBox.alert(data, ``);
// }
// });
//
// ipcRenderer.on("Config.openDataFolder.hook", (event, args) => {
// if (args) {
// ElMessage({
// type: "success",
// message: ""
// });
// }
// });
on(ipcRouters.SERVER.resetAllConfig, () => {
ElMessageBox.alert("重置成功 请重启软件", `提示`, {
closeOnClickModal: false,
showClose: false,
confirmButtonText: "立即重启"
}).then(() => {
send(ipcRouters.SYSTEM.relaunchApp);
});
});
on(ipcRouters.SERVER.exportConfig, () => {
//
confetti({
zIndex: 12002,
particleCount: 200,
spread: 70,
origin: { y: 0.6 }
});
ElMessageBox.alert("🎉 恭喜你,导入成功 请重启软件", `提示`, {
closeOnClickModal: false,
showClose: false,
confirmButtonText: "立即重启"
}).then(() => {
send(ipcRouters.SYSTEM.relaunchApp);
});
});
// ElMessageBox.alert(data, ``);
on(ipcRouters.SYSTEM.openAppData, () => {
ElMessage({
type: "success",
message: "打开数据目录成功"
});
});
});
const handleSelectFile = (type: number, ext: string[]) => {
@ -484,8 +480,9 @@ const handleShowExportDialog = () => {
};
const handleExportConfig = useDebounceFn(() => {
ipcRenderer.send("config.exportConfig", exportConfigType.value);
visibles.exportConfig = false;
send(ipcRouters.SERVER.exportConfig);
// ipcRenderer.send("config.exportConfig", exportConfigType.value);
// visibles.exportConfig = false;
}, 300);
const handleImportConfig = () => {
@ -498,7 +495,7 @@ const handleResetConfig = () => {
cancelButtonText: "取消",
confirmButtonText: "清空"
}).then(() => {
ipcRenderer.send("config.clearAll");
send(ipcRouters.SERVER.resetAllConfig);
});
};
@ -506,18 +503,19 @@ const handleResetConfig = () => {
* 打开数据目录
*/
const handleOpenDataFolder = useDebounceFn(() => {
ipcRenderer.send("config.openDataFolder");
}, 1000);
send(ipcRouters.SYSTEM.openAppData);
}, 300);
onUnmounted(() => {
removeRouterListeners(ipcRouters.SERVER.saveConfig);
removeRouterListeners(ipcRouters.VERSION.getDownloadedVersions);
removeRouterListeners(ipcRouters.SERVER.getServerConfig);
removeRouterListeners(ipcRouters.SERVER.saveConfig);
removeRouterListeners(ipcRouters.SERVER.resetAllConfig);
removeRouterListeners(ipcRouters.VERSION.getDownloadedVersions);
// ipcRenderer.removeAllListeners("Config.exportConfig.hook");
removeRouterListeners(ipcRouters.SERVER.exportConfig);
// ipcRenderer.removeAllListeners("Config.clearAll.hook");
// ipcRenderer.removeAllListeners("Config.openDataFolder.hook");
removeRouterListeners(ipcRouters.SYSTEM.openAppData);
});
</script>
<template>
@ -532,7 +530,7 @@ onUnmounted(() => {
<el-button plain type="primary" @click="handleImportConfig">
<IconifyIconOffline icon="file-open-rounded" />
</el-button>
<el-button plain type="primary" @click="handleShowExportDialog">
<el-button plain type="primary" @click="handleExportConfig">
<IconifyIconOffline icon="file-save-rounded" />
</el-button>
<el-button type="primary" @click="handleSubmit">
@ -1513,38 +1511,38 @@ onUnmounted(() => {
</template>
</el-dialog>
<!-- 配置导出-->
<el-dialog
v-model="visibles.exportConfig"
title="导出配置"
width="500"
top="5%"
>
<el-alert
class="mb-4"
:title="`导出文件名为 frpc-desktop.${exportConfigType} 重复导出则覆盖`"
type="warning"
:closable="false"
/>
<el-form>
<el-form-item label="导出类型">
<el-radio-group v-model="exportConfigType">
<el-radio-button label="toml" value="toml" />
<el-radio-button label="ini" value="ini" />
</el-radio-group>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button plain type="primary" @click="handleExportConfig">
<IconifyIconOffline
class="cursor-pointer mr-2"
icon="downloadRounded"
/>
</el-button>
</div>
</template>
</el-dialog>
<!-- <el-dialog-->
<!-- v-model="visibles.exportConfig"-->
<!-- title="导出配置"-->
<!-- width="500"-->
<!-- top="5%"-->
<!-- >-->
<!-- <el-alert-->
<!-- class="mb-4"-->
<!-- :title="`导出文件名为 frpc-desktop.${exportConfigType} 重复导出则覆盖`"-->
<!-- type="warning"-->
<!-- :closable="false"-->
<!-- />-->
<!-- <el-form>-->
<!-- <el-form-item label="导出类型">-->
<!-- <el-radio-group v-model="exportConfigType">-->
<!-- <el-radio-button label="toml" value="toml" />-->
<!-- <el-radio-button label="ini" value="ini" />-->
<!-- </el-radio-group>-->
<!-- </el-form-item>-->
<!-- </el-form>-->
<!-- <template #footer>-->
<!-- <div class="dialog-footer">-->
<!-- <el-button plain type="primary" @click="handleExportConfig">-->
<!-- <IconifyIconOffline-->
<!-- class="cursor-pointer mr-2"-->
<!-- icon="downloadRounded"-->
<!-- />-->
<!-- -->
<!-- </el-button>-->
<!-- </div>-->
<!-- </template>-->
<!-- </el-dialog>-->
</div>
</template>

1
types/core.d.ts vendored
View File

@ -33,6 +33,7 @@ enum IpcRouterKeys {
VERSION = "VERSION",
LAUNCH = "LAUNCH",
PROXY = "PROXY",
SYSTEM = "SYSTEM",
}
type IpcRouters = Record<