🏗️ refactor UI components and enhance form handling with lodash integration

This commit is contained in:
刘嘉伟 2025-02-25 15:14:54 +08:00
parent 64c9623019
commit 711af4a31a
8 changed files with 44 additions and 48 deletions

View File

@ -1,7 +1,6 @@
import ProxyRepository from "../repository/ProxyRepository"; import ProxyRepository from "../repository/ProxyRepository";
import Component from "../core/annotation/Component";
const { exec, spawn } = require("child_process"); const { exec } = require("child_process");
class ProxyService { class ProxyService {

View File

@ -82,6 +82,7 @@
"intro.js": "^8.0.0-beta.1", "intro.js": "^8.0.0-beta.1",
"isbinaryfile": "4.0.10", "isbinaryfile": "4.0.10",
"js-base64": "^3.7.7", "js-base64": "^3.7.7",
"lodash": "^4.17.21",
"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

@ -8,10 +8,11 @@ $danger-color: #F56C6C;
height: 100vh; height: 100vh;
padding: 20px; padding: 20px;
.main { .main {
height: 100%; height: 100%;
width: 100%; width: 100%;
overflow: hidden; //overflow: hidden;
} }
.app-container-breadcrumb { .app-container-breadcrumb {

View File

@ -1,19 +0,0 @@
export function clone<T>(value: T): T {
/** 空 */
if (!value) return value;
/** 数组 */
if (Array.isArray(value))
return value.map(item => clone(item)) as unknown as T;
/** 日期 */
if (value instanceof Date) return new Date(value) as unknown as T;
/** 普通对象 */
if (typeof value === "object") {
return Object.fromEntries(
Object.entries(value).map(([k, v]: [string, any]) => {
return [k, clone(v)];
})
) as unknown as T;
}
/** 基本类型 */
return value;
}

View File

@ -4,12 +4,11 @@ import { ipcRenderer } from "electron";
import { ElMessage, ElMessageBox, FormInstance, FormRules } from "element-plus"; import { ElMessage, ElMessageBox, FormInstance, FormRules } from "element-plus";
import Breadcrumb from "@/layout/compoenets/Breadcrumb.vue"; import Breadcrumb from "@/layout/compoenets/Breadcrumb.vue";
import { useDebounceFn } from "@vueuse/core"; import { useDebounceFn } from "@vueuse/core";
import { clone } from "@/utils/clone";
import { Base64 } from "js-base64"; import { Base64 } from "js-base64";
import IconifyIconOffline from "@/components/IconifyIcon/src/iconifyIconOffline"; import IconifyIconOffline from "@/components/IconifyIcon/src/iconifyIconOffline";
import { on, removeRouterListeners, send } from "@/utils/ipcUtils"; import { on, removeRouterListeners, send } from "@/utils/ipcUtils";
import { ipcRouters } from "../../../electron/core/IpcRouter"; import { ipcRouters } from "../../../electron/core/IpcRouter";
import confetti from "canvas-confetti/src/confetti.js"; import _ from "lodash";
defineComponent({ defineComponent({
name: "Config" name: "Config"
@ -201,7 +200,7 @@ const handleSubmit = useDebounceFn(() => {
formRef.value.validate(valid => { formRef.value.validate(valid => {
if (valid) { if (valid) {
loading.value = 1; loading.value = 1;
const data = clone(formData.value); const data = _.cloneDeep(formData.value);
send(ipcRouters.SERVER.saveConfig, data); send(ipcRouters.SERVER.saveConfig, data);
} }
}); });
@ -362,7 +361,7 @@ onMounted(() => {
}); });
}); });
on(ipcRouters.SERVER.exportConfig, (data) => { on(ipcRouters.SERVER.exportConfig, data => {
ElMessageBox.alert(`配置路径:${data}`, `🎉 导出成功`); ElMessageBox.alert(`配置路径:${data}`, `🎉 导出成功`);
// // // //
// confetti({ // confetti({

View File

@ -174,7 +174,7 @@ onUnmounted(() => {
/> />
</el-select> </el-select>
</div> </div>
<el-button class="mr-2" type="primary" @click="handleImportFrp"> <el-button type="primary" @click="handleImportFrp">
<IconifyIconOffline icon="unarchive" /> <IconifyIconOffline icon="unarchive" />
</el-button> </el-button>
</div> </div>
@ -221,7 +221,7 @@ onUnmounted(() => {
class="mb-[20px]" class="mb-[20px]"
> >
<div <div
class="w-full download-card bg-white rounded p-4 drop-shadow flex justify-between items-center" class="w-full download-card bg-white rounded p-4 drop-shadow flex justify-between items-center animate__animated"
> >
<div class="left"> <div class="left">
<div class="mb-2 flex items-center justify-center"> <div class="mb-2 flex items-center justify-center">
@ -316,4 +316,8 @@ onUnmounted(() => {
.download-card { .download-card {
border-left: 5px solid #5a3daa; border-left: 5px solid #5a3daa;
} }
.download-card:hover {
//animation: pulse 0.5s;
}
</style> </style>

View File

@ -10,6 +10,7 @@ defineComponent({
}); });
const running = ref(false); const running = ref(false);
const loading = ref(false);
const handleStartFrpc = () => { const handleStartFrpc = () => {
send(ipcRouters.LAUNCH.launch); send(ipcRouters.LAUNCH.launch);
@ -20,6 +21,7 @@ const handleStopFrpc = () => {
}; };
const handleButtonClick = useDebounceFn(() => { const handleButtonClick = useDebounceFn(() => {
loading.value = true;
if (running.value) { if (running.value) {
handleStopFrpc(); handleStopFrpc();
} else { } else {
@ -39,10 +41,12 @@ onMounted(() => {
on(ipcRouters.LAUNCH.launch, () => { on(ipcRouters.LAUNCH.launch, () => {
send(ipcRouters.LAUNCH.getStatus); send(ipcRouters.LAUNCH.getStatus);
loading.value = false;
}); });
on(ipcRouters.LAUNCH.terminate, () => { on(ipcRouters.LAUNCH.terminate, () => {
send(ipcRouters.LAUNCH.getStatus); send(ipcRouters.LAUNCH.getStatus);
loading.value = false;
}); });
// ipcRenderer.on("Home.frpc.start.error.hook", (event, args) => { // ipcRenderer.on("Home.frpc.start.error.hook", (event, args) => {
// if (args) { // if (args) {
@ -132,12 +136,19 @@ onUnmounted(() => {
>查看日志</el-link >查看日志</el-link
> >
</div> </div>
<div <el-button
class="w-full h-8 bg-[#563EA4] rounded flex justify-center items-center text-white font-bold cursor-pointer" type="primary"
@click="handleButtonClick" @click="handleButtonClick"
> size="large"
{{ running ? "断 开" : "启 动" }} :disabled="loading"
</div> >{{ running ? "断 开" : "启 动" }}
</el-button>
<!-- <div-->
<!-- class="w-full h-8 bg-[#563EA4] rounded flex justify-center items-center text-white font-bold cursor-pointer"-->
<!-- >-->
<!-- </div>-->
</div> </div>
</div> </div>
</div> </div>

View File

@ -10,13 +10,13 @@ import {
import Breadcrumb from "@/layout/compoenets/Breadcrumb.vue"; import Breadcrumb from "@/layout/compoenets/Breadcrumb.vue";
import { ElMessage, FormInstance, FormRules } from "element-plus"; import { ElMessage, FormInstance, FormRules } from "element-plus";
import { ipcRenderer } from "electron"; import { ipcRenderer } from "electron";
import { clone } from "@/utils/clone";
import { useClipboard, useDebounceFn } from "@vueuse/core"; import { useClipboard, useDebounceFn } from "@vueuse/core";
import IconifyIconOffline from "@/components/IconifyIcon/src/iconifyIconOffline"; import IconifyIconOffline from "@/components/IconifyIcon/src/iconifyIconOffline";
import commonIps from "./commonIp.json"; import commonIps from "./commonIp.json";
import path from "path"; import path from "path";
import { on, removeRouterListeners, send } from "@/utils/ipcUtils"; import { on, removeRouterListeners, send } from "@/utils/ipcUtils";
import { ipcRouters } from "../../../electron/core/IpcRouter"; import { ipcRouters } from "../../../electron/core/IpcRouter";
import _ from "lodash";
defineComponent({ defineComponent({
name: "Proxy" name: "Proxy"
@ -77,7 +77,7 @@ const defaultForm: FrpcProxy = {
/** /**
* 表单内容 * 表单内容
*/ */
const editForm = ref<FrpcProxy>(defaultForm); const editForm = ref<FrpcProxy>(_.cloneDeep(defaultForm));
/** /**
* 代理类型 * 代理类型
@ -280,11 +280,12 @@ const handleSubmit = async () => {
return; return;
} }
loading.value.form = 1; loading.value.form = 1;
const data = clone(editForm.value); const data = _.cloneDeep(editForm.value);
console.log("submit", data);
if (data._id) { if (data._id) {
send(ipcRouters.PROXY.createProxy, data);
} else {
send(ipcRouters.PROXY.modifyProxy, data); send(ipcRouters.PROXY.modifyProxy, data);
} else {
send(ipcRouters.PROXY.createProxy, data);
} }
} }
}); });
@ -325,7 +326,7 @@ const handleDeleteProxy = (proxy: FrpcProxy) => {
* 重置表单 * 重置表单
*/ */
const handleResetForm = () => { const handleResetForm = () => {
editForm.value = defaultForm; editForm.value = _.cloneDeep(defaultForm);
}; };
const handleOpenInsert = () => { const handleOpenInsert = () => {
@ -336,10 +337,10 @@ const handleOpenInsert = () => {
}; };
const handleOpenUpdate = (proxy: FrpcProxy) => { const handleOpenUpdate = (proxy: FrpcProxy) => {
editForm.value = clone(proxy); editForm.value = _.cloneDeep(proxy);
if (!editForm.value.fallbackTimeoutMs) { // if (!editForm.value.fallbackTimeoutMs) {
editForm.value.fallbackTimeoutMs = defaultForm.fallbackTimeoutMs; // editForm.value.fallbackTimeoutMs = defaultForm.fallbackTimeoutMs;
} // }
edit.value = { edit.value = {
title: "修改代理", title: "修改代理",
visible: true visible: true
@ -361,6 +362,7 @@ const handleLoadLocalPorts = () => {
const handleSelectLocalPort = useDebounceFn((port: number) => { const handleSelectLocalPort = useDebounceFn((port: number) => {
editForm.value.localPort = port?.toString(); editForm.value.localPort = port?.toString();
editForm.value.localIP = "127.0.0.1";
handleCloseLocalPortDialog(); handleCloseLocalPortDialog();
}); });
@ -539,12 +541,10 @@ onMounted(() => {
}; };
on(ipcRouters.PROXY.createProxy, data => { on(ipcRouters.PROXY.createProxy, data => {
console.log("data", data);
insertOrUpdateHook("新增成功"); insertOrUpdateHook("新增成功");
}); });
on(ipcRouters.PROXY.modifyProxy, data => { on(ipcRouters.PROXY.modifyProxy, data => {
console.log("data", data);
insertOrUpdateHook("修改成功"); insertOrUpdateHook("修改成功");
}); });
@ -595,11 +595,11 @@ onUnmounted(() => {
<!-- <coming-soon />--> <!-- <coming-soon />-->
<div class="main"> <div class="main">
<breadcrumb> <breadcrumb>
<el-button class="mr-2" type="primary" @click="handleOpenInsert"> <el-button type="primary" @click="handleOpenInsert">
<IconifyIconOffline icon="add" /> <IconifyIconOffline icon="add" />
</el-button> </el-button>
</breadcrumb> </breadcrumb>
<div class="app-container-breadcrumb pr-2" 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="20">
<el-col <el-col
@ -803,7 +803,7 @@ onUnmounted(() => {
v-model="edit.visible" v-model="edit.visible"
direction="rtl" direction="rtl"
size="60%" size="60%"
@close="editForm = defaultForm" @close="editForm = _.cloneDeep(defaultForm)"
> >
<!-- <el-dialog--> <!-- <el-dialog-->
<!-- v-model="edit.visible"--> <!-- v-model="edit.visible"-->