🏗️ refactor frpc process management and integrate Pinia for state handling

This commit is contained in:
刘嘉伟 2025-02-25 15:57:11 +08:00
parent 711af4a31a
commit 7a58500a92
9 changed files with 104 additions and 55 deletions

View File

@ -83,6 +83,7 @@
"isbinaryfile": "4.0.10", "isbinaryfile": "4.0.10",
"js-base64": "^3.7.7", "js-base64": "^3.7.7",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"pinia": "^3.0.1",
"smol-toml": "^1.3.1", "smol-toml": "^1.3.1",
"snowflakify": "^1.0.5", "snowflakify": "^1.0.5",
"tar": "^6.2.0", "tar": "^6.2.0",

View File

@ -2,15 +2,17 @@
import { computed, defineComponent, onMounted, ref } from "vue"; import { computed, defineComponent, onMounted, ref } from "vue";
import router from "@/router"; import router from "@/router";
import { RouteRecordRaw } from "vue-router"; import { RouteRecordRaw } from "vue-router";
import pkg from "../../../package.json";
import Intro from "@/intro"; import Intro from "@/intro";
import "intro.js/introjs.css"; import "intro.js/introjs.css";
import confetti from "canvas-confetti/src/confetti.js"; import confetti from "canvas-confetti/src/confetti.js";
import { useFrpcProcessStore } from "@/store/frpcProcess";
import pkg from "../../../package.json";
defineComponent({ defineComponent({
name: "AppMain" name: "AppMain"
}); });
const frpcProcessStore = useFrpcProcessStore();
const routes = ref<Array<RouteRecordRaw>>([]); const routes = ref<Array<RouteRecordRaw>>([]);
const guideSteps = ref({ const guideSteps = ref({
Home: { Home: {
@ -93,11 +95,14 @@ onMounted(() => {
<template> <template>
<div class="left-menu-container drop-shadow-xl"> <div class="left-menu-container drop-shadow-xl">
<div class="logo-container"> <div class="logo-container">
<img <!-- <img-->
src="/logo/only/128x128.png" <!-- src="/logo/only/128x128.png"-->
class="logo animate__animated animate__bounceInLeft" <!-- class="logo animate__animated animate__bounceInLeft"-->
alt="Logo" <!-- alt="Logo"-->
/> <!-- />-->
<!-- <el-badge :value="'v1.1.2'" class="logo" type="primary" :offset="[-10, 42]">-->
<img src="/logo/only/128x128.png" class="logo" alt="Logo" />
<!-- </el-badge>-->
</div> </div>
<ul class="menu-container"> <ul class="menu-container">
<!-- enter-active-class="animate__animated animate__bounceIn"--> <!-- enter-active-class="animate__animated animate__bounceIn"-->
@ -119,18 +124,24 @@ onMounted(() => {
</li> </li>
</ul> </ul>
<div class="menu-footer mb-2"> <div class="menu-footer mb-2">
<!-- <div--> <!-- <el-tag-->
<!-- class="menu animate__animated"--> <!-- :type="frpcProcessStore.running ? 'primary' : 'warning'"-->
<!-- @click="handleOpenGitHubReleases"--> <!-- effect="light"-->
<!-- :data-step="guideSteps.Version?.step"--> <!-- size="small"-->
<!-- :data-intro="guideSteps.Version?.intro"--> <!-- >{{ frpcProcessStore.running ? "运行中" : "已断开" }}-->
<!-- data-position="top"--> <!-- </el-tag>-->
<!-- >--> <!-- <div-->
<!-- <IconifyIconOffline--> <!-- class="menu animate__animated"-->
<!-- class="animate__animated"--> <!-- @click="handleOpenGitHubReleases"-->
<!-- icon="attach-money-rounded"--> <!-- :data-step="guideSteps.Version?.step"-->
<!-- ></IconifyIconOffline>--> <!-- :data-intro="guideSteps.Version?.intro"-->
<!-- </div>--> <!-- data-position="top"-->
<!-- >-->
<!-- <IconifyIconOffline-->
<!-- class="animate__animated"-->
<!-- icon="attach-money-rounded"-->
<!-- ></IconifyIconOffline>-->
<!-- </div>-->
<div <div
class="version animate__animated" class="version animate__animated"
@click="handleOpenGitHubReleases" @click="handleOpenGitHubReleases"

View File

@ -1,22 +1,42 @@
import {createApp} from "vue"; import { createApp } from "vue";
import App from "./App.vue"; import App from "./App.vue";
import router from "./router"; import router from "./router";
import "./styles/index.scss"; import "./styles/index.scss";
import 'animate.css'; import "animate.css";
import ElementPlus from "element-plus"; import ElementPlus from "element-plus";
import { import {
IconifyIconOffline, IconifyIconOffline,
IconifyIconOnline, IconifyIconOnline
} from "./components/IconifyIcon"; } from "./components/IconifyIcon";
import { createPinia } from "pinia";
import { on, onListener } from "@/utils/ipcUtils";
import { ipcRouters, listeners } from "../electron/core/IpcRouter";
import { useFrpcProcessStore } from "@/store/frpcProcess";
const pinia = createPinia();
const app = createApp(App); const app = createApp(App);
app.component("IconifyIconOffline", IconifyIconOffline); app.component("IconifyIconOffline", IconifyIconOffline);
app.component("IconifyIconOnline", IconifyIconOnline); app.component("IconifyIconOnline", IconifyIconOnline);
app
.use(router)
.use(ElementPlus)
.use(pinia)
.mount("#app")
.$nextTick(() => {
postMessage({ payload: "removeLoading" }, "*");
app.use(router) const frpcProcessStore = useFrpcProcessStore();
.use(ElementPlus)
.mount("#app") onListener(listeners.watchFrpcProcess, data => {
.$nextTick(() => { console.log("watchFrpcProcess", data);
postMessage({payload: "removeLoading"}, "*"); frpcProcessStore.setRunning(data);
}); });
on(ipcRouters.LAUNCH.getStatus, data => {
console.log("getStatus", data);
frpcProcessStore.setRunning(data);
});
});

18
src/store/frpcProcess.ts Normal file
View File

@ -0,0 +1,18 @@
import { defineStore } from "pinia";
import { send } from "@/utils/ipcUtils";
import { ipcRouters } from "../../electron/core/IpcRouter";
export const useFrpcProcessStore = defineStore("frpcProcess", {
state: () => ({ isRunning: false }),
getters: {
running: state => state.isRunning
},
actions: {
setRunning(running: boolean) {
this.isRunning = running;
},
refreshRunning() {
send(ipcRouters.LAUNCH.getStatus);
}
}
});

View File

@ -6,7 +6,7 @@ $danger-color: #F56C6C;
background: $main-bg; background: $main-bg;
width: calc(100% - 60px); width: calc(100% - 60px);
height: 100vh; height: 100vh;
padding: 20px; padding: 15px;
.main { .main {
@ -27,7 +27,7 @@ $danger-color: #F56C6C;
.breadcrumb-left { .breadcrumb-left {
color: $primary-color; color: $primary-color;
font-size: 36px; font-size: 36px;
height: 30px; height: 32px;
svg { svg {
vertical-align: top; vertical-align: top;

View File

@ -159,7 +159,7 @@ onUnmounted(() => {
<!-- <breadcrumb> --> <!-- <breadcrumb> -->
<breadcrumb> <breadcrumb>
<div class="flex"> <div class="flex">
<div class="h-full flex items-center justify-center mr-4"> <div class="h-full flex items-center justify-center mr-3">
<span class="text-sm font-bold">下载源 </span> <span class="text-sm font-bold">下载源 </span>
<el-select <el-select
class="w-40" class="w-40"
@ -194,7 +194,7 @@ onUnmounted(() => {
<div class="app-container-breadcrumb pr-2" v-loading="loading > 0"> <div class="app-container-breadcrumb pr-2" v-loading="loading > 0">
<div class="w-full"> <div class="w-full">
<template v-if="versions && versions.length > 0"> <template v-if="versions && versions.length > 0">
<el-row :gutter="20"> <el-row :gutter="15">
<!-- <el-col :span="24">--> <!-- <el-col :span="24">-->
<!-- <div class="h2 flex justify-between !mb-[10px]">--> <!-- <div class="h2 flex justify-between !mb-[10px]">-->
<!-- <div>镜像源</div>--> <!-- <div>镜像源</div>-->
@ -218,7 +218,7 @@ onUnmounted(() => {
:sm="12" :sm="12"
:xl="6" :xl="6"
:xs="12" :xs="12"
class="mb-[20px]" class="mb-[15px]"
> >
<div <div
class="w-full download-card bg-white rounded p-4 drop-shadow flex justify-between items-center animate__animated" class="w-full download-card bg-white rounded p-4 drop-shadow flex justify-between items-center animate__animated"

View File

@ -4,12 +4,16 @@ import Breadcrumb from "@/layout/compoenets/Breadcrumb.vue";
import { useDebounceFn } from "@vueuse/core"; import { useDebounceFn } from "@vueuse/core";
import { on, onListener, removeRouterListeners2, send } from "@/utils/ipcUtils"; import { on, onListener, removeRouterListeners2, send } from "@/utils/ipcUtils";
import { ipcRouters, listeners } from "../../../electron/core/IpcRouter"; import { ipcRouters, listeners } from "../../../electron/core/IpcRouter";
import { useFrpcProcessStore } from "@/store/frpcProcess";
defineComponent({ defineComponent({
name: "Home" name: "Home"
}); });
const running = ref(false); const frpcProcessStore = useFrpcProcessStore();
// const running = ref(false);
const loading = ref(false); const loading = ref(false);
const handleStartFrpc = () => { const handleStartFrpc = () => {
@ -22,7 +26,7 @@ const handleStopFrpc = () => {
const handleButtonClick = useDebounceFn(() => { const handleButtonClick = useDebounceFn(() => {
loading.value = true; loading.value = true;
if (running.value) { if (frpcProcessStore.running) {
handleStopFrpc(); handleStopFrpc();
} else { } else {
handleStartFrpc(); handleStartFrpc();
@ -30,22 +34,18 @@ const handleButtonClick = useDebounceFn(() => {
}, 300); }, 300);
onMounted(() => { onMounted(() => {
onListener(listeners.watchFrpcProcess, data => {
console.log("watchFrpcProcess", data);
running.value = data;
});
on(ipcRouters.LAUNCH.getStatus, data => {
running.value = data;
});
on(ipcRouters.LAUNCH.launch, () => { on(ipcRouters.LAUNCH.launch, () => {
send(ipcRouters.LAUNCH.getStatus); // send(ipcRouters.LAUNCH.getStatus);
frpcProcessStore.refreshRunning();
loading.value = false; loading.value = false;
}); });
on(ipcRouters.LAUNCH.terminate, () => { on(ipcRouters.LAUNCH.terminate, () => {
send(ipcRouters.LAUNCH.getStatus); // send(ipcRouters.LAUNCH.getStatus);
frpcProcessStore.refreshRunning();
loading.value = false; loading.value = false;
}); });
// ipcRenderer.on("Home.frpc.start.error.hook", (event, args) => { // ipcRenderer.on("Home.frpc.start.error.hook", (event, args) => {
@ -65,7 +65,7 @@ onMounted(() => {
onUnmounted(() => { onUnmounted(() => {
// ipcRenderer.removeAllListeners("Home.frpc.start.error.hook"); // ipcRenderer.removeAllListeners("Home.frpc.start.error.hook");
removeRouterListeners2(listeners.watchFrpcProcess); // removeRouterListeners2(listeners.watchFrpcProcess);
}); });
</script> </script>
@ -82,19 +82,19 @@ onUnmounted(() => {
> >
<transition name="fade"> <transition name="fade">
<div <div
v-show="running" v-show="frpcProcessStore.running"
class="z-0 rounded-full opacity-20 left-circle bg-[#5A3DAA] w-full h-full animation-rotate-1" class="z-0 rounded-full opacity-20 left-circle bg-[#5A3DAA] w-full h-full animation-rotate-1"
/> />
</transition> </transition>
<transition name="fade"> <transition name="fade">
<div <div
v-show="running" v-show="frpcProcessStore.running"
class="z-0 rounded-full opacity-20 right-circle top-[10px] bg-[#5A3DAA] w-full h-full animation-rotate-2" class="z-0 rounded-full opacity-20 right-circle top-[10px] bg-[#5A3DAA] w-full h-full animation-rotate-2"
/> />
</transition> </transition>
<transition name="fade"> <transition name="fade">
<div <div
v-show="running" v-show="frpcProcessStore.running"
class="z-0 rounded-full opacity-20 top-circle bg-[#5A3DAA] w-full h-full animation-rotate-3" class="z-0 rounded-full opacity-20 top-circle bg-[#5A3DAA] w-full h-full animation-rotate-3"
/> />
</transition> </transition>
@ -109,7 +109,7 @@ onUnmounted(() => {
<transition name="fade"> <transition name="fade">
<div class="font-bold text-2xl text-center"> <div class="font-bold text-2xl text-center">
<IconifyIconOffline <IconifyIconOffline
v-if="running" v-if="frpcProcessStore.running"
class="text-[#7EC050] inline-block relative top-1" class="text-[#7EC050] inline-block relative top-1"
icon="check-circle-rounded" icon="check-circle-rounded"
/> />
@ -118,7 +118,7 @@ onUnmounted(() => {
class="text-[#E47470] inline-block relative top-1" class="text-[#E47470] inline-block relative top-1"
icon="error" icon="error"
/> />
Frpc {{ running ? "已启动" : "已断开" }} Frpc {{ frpcProcessStore.running ? "已启动" : "已断开" }}
</div> </div>
</transition> </transition>
<!-- <el-button--> <!-- <el-button-->
@ -130,7 +130,7 @@ onUnmounted(() => {
<!-- </el-button>--> <!-- </el-button>-->
<div class="w-full justify-center text-center"> <div class="w-full justify-center text-center">
<el-link <el-link
v-if="running" v-if="frpcProcessStore.running"
type="primary" type="primary"
@click="$router.replace({ name: 'Logger' })" @click="$router.replace({ name: 'Logger' })"
>查看日志</el-link >查看日志</el-link
@ -141,7 +141,7 @@ onUnmounted(() => {
@click="handleButtonClick" @click="handleButtonClick"
size="large" size="large"
:disabled="loading" :disabled="loading"
>{{ running ? "断 开" : "启 动" }} >{{ frpcProcessStore.running ? "断 开" : "启 动" }}
</el-button> </el-button>
<!-- <div--> <!-- <div-->
<!-- class="w-full h-8 bg-[#563EA4] rounded flex justify-center items-center text-white font-bold cursor-pointer"--> <!-- class="w-full h-8 bg-[#563EA4] rounded flex justify-center items-center text-white font-bold cursor-pointer"-->

View File

@ -8,7 +8,6 @@ import { ipcRouters, listeners } from "../../../electron/core/IpcRouter";
import { import {
on, on,
onListener, onListener,
removeAllListeners,
removeRouterListeners, removeRouterListeners,
removeRouterListeners2, removeRouterListeners2,
send send

View File

@ -601,7 +601,7 @@ onUnmounted(() => {
</breadcrumb> </breadcrumb>
<div class="app-container-breadcrumb" v-loading="loading.list > 0"> <div class="app-container-breadcrumb" v-loading="loading.list > 0">
<template v-if="proxys && proxys.length > 0"> <template v-if="proxys && proxys.length > 0">
<el-row :gutter="20"> <el-row :gutter="15">
<el-col <el-col
v-for="proxy in proxys" v-for="proxy in proxys"
:key="proxy._id" :key="proxy._id"
@ -610,13 +610,13 @@ onUnmounted(() => {
:sm="12" :sm="12"
:xl="6" :xl="6"
:xs="12" :xs="12"
class="mb-[20px]" class="mb-[15px]"
> >
<div class="bg-white w-full rounded drop-shadow-xl p-4"> <div class="bg-white w-full rounded drop-shadow-xl p-4">
<div class="w-full flex justify-between"> <div class="w-full flex justify-between">
<div class="flex"> <div class="flex">
<div <div
class="w-12 h-12 rounded mr-4 flex justify-center items-center font-bold" class="w-12 h-12 rounded mr-3 flex justify-center items-center font-bold"
:class="proxy.type" :class="proxy.type"
> >
<span class="text-white text-sm">{{ proxy.type }}</span> <span class="text-white text-sm">{{ proxy.type }}</span>