diff --git a/electron/api/frpc.ts b/electron/api/frpc.ts index e620f49..e61ecd9 100644 --- a/electron/api/frpc.ts +++ b/electron/api/frpc.ts @@ -72,6 +72,12 @@ ${config.authMethod === 'multiuser' ? ` user = "${config.user}" metadatas.token = "${config.metaToken}" ` : ""} +${config.transportHeartbeatInterval ? ` +transport.heartbeatInterval = ${config.transportHeartbeatInterval} +` : ""} +${config.transportHeartbeatTimeout ? ` +transport.heartbeatTimeout = ${config.transportHeartbeatTimeout} +` : ""} log.to = "frpc.log" @@ -135,6 +141,14 @@ ${config.authMethod === 'multiuser' ? ` user = ${config.user} meta_token = ${config.metaToken} ` : ""} + +${config.transportHeartbeatInterval ? ` +heartbeat_interval = ${config.transportHeartbeatInterval} +` : ""} +${config.transportHeartbeatTimeout ? ` +heartbeat_timeout = ${config.transportHeartbeatTimeout} +` : ""} + log_file = "frpc.log" log_level = ${config.logLevel} log_max_days = ${config.logMaxDays} diff --git a/electron/storage/config.ts b/electron/storage/config.ts index ca2e7bf..5c41b6c 100644 --- a/electron/storage/config.ts +++ b/electron/storage/config.ts @@ -28,6 +28,8 @@ export type Config = { systemStartupConnect: boolean; user: string; metaToken: string; + transportHeartbeatInterval: number; + transportHeartbeatTimeout: number; }; /** diff --git a/src/views/config/index.vue b/src/views/config/index.vue index f666d04..1b2399b 100644 --- a/src/views/config/index.vue +++ b/src/views/config/index.vue @@ -6,6 +6,7 @@ import Breadcrumb from "@/layout/compoenets/Breadcrumb.vue"; import {useDebounceFn} from "@vueuse/core"; import {clone} from "@/utils/clone"; import {Icon} from "@iconify/vue"; +import {Base64} from "js-base64"; defineComponent({ name: "Config" @@ -30,6 +31,8 @@ type Config = { systemStartupConnect: boolean; user: string; metaToken: string; + transportHeartbeatInterval: number; + transportHeartbeatTimeout: number; }; type Version = { @@ -37,7 +40,18 @@ type Version = { name: string; } -const formData = ref({ +type ShareLinkConfig = { + serverAddr: string, + serverPort: number, + authMethod: string, + authToken: string, + transportHeartbeatInterval: number, + transportHeartbeatTimeout: number, + user: string, + metaToken: string, +} + +const defaultFormData = ref({ currentVersion: "", serverAddr: "", serverPort: 7000, @@ -55,9 +69,14 @@ const formData = ref({ systemSelfStart: false, systemStartupConnect: false, user: "", - metaToken: "" + metaToken: "", + transportHeartbeatInterval: 30, + transportHeartbeatTimeout: 90, }); + +const formData = ref(defaultFormData.value); + const loading = ref(1); const rules = reactive({ @@ -99,12 +118,27 @@ const rules = reactive({ ], systemSelfStart: [ {required: true, message: "请选择是否开机自启", trigger: "change"}, - ] + ], + transportHeartbeatInterval: [ + {required: true, message: "心跳间隔时间不能为空", trigger: "change"}, + ], + transportHeartbeatTimeout: [ + {required: true, message: "心跳超时时间不能为空", trigger: "change"}, + ], + }); const versions = ref>([]); +const copyServerConfigBase64 = ref(); +const pasteServerConfigBase64 = ref(); const formRef = ref(); + +const visibles = reactive({ + copyServerConfig: false, + pasteServerConfig: false, +}); + const handleSubmit = useDebounceFn(() => { if (!formRef.value) return; formRef.value.validate(valid => { @@ -138,6 +172,13 @@ onMounted(() => { const {err, data} = args; if (!err) { if (data) { + console.log('data', data) + if (!data.transportHeartbeatInterval) { + data.transportHeartbeatInterval = defaultFormData.value.transportHeartbeatInterval + } + if (!data.transportHeartbeatTimeout) { + data.transportHeartbeatTimeout = defaultFormData.value.transportHeartbeatTimeout + } formData.value = data; } } @@ -177,6 +218,78 @@ const handleSelectFile = (type: number, ext: string[]) => { }) } +/** + * 分享配置 + */ +const handleCopyServerConfig2Base64 = useDebounceFn(() => { + const shareConfig: ShareLinkConfig = { + serverAddr: formData.value.serverAddr, + serverPort: formData.value.serverPort, + authMethod: formData.value.authMethod, + authToken: formData.value.authToken, + transportHeartbeatInterval: formData.value.transportHeartbeatInterval, + transportHeartbeatTimeout: formData.value.transportHeartbeatTimeout, + user: formData.value.user, + metaToken: formData.value.metaToken, + }; + const base64str = Base64.encode( + JSON.stringify(shareConfig) + ) + copyServerConfigBase64.value = base64str; + visibles.copyServerConfig = true; + +}, 300); + +/** + * 导入配置 + */ +const handlePasteServerConfig4Base64 = useDebounceFn(() => { + visibles.pasteServerConfig = true; +}, 300); + +const handlePasteServerConfigBase64 = useDebounceFn(() => { + const plain = Base64.decode(pasteServerConfigBase64.value) + console.log('plain', plain) + let serverConfig: ShareLinkConfig = null; + try { + serverConfig = JSON.parse(plain) + } catch { + ElMessage({ + type: "warning", + message: "链接不正确 请输入正确的链接" + }); + return; + } + + if (!serverConfig && !serverConfig.serverAddr) { + ElMessage({ + type: "warning", + message: "链接不正确 请输入正确的链接" + }); + return; + } + if (!serverConfig && !serverConfig.serverPort) { + ElMessage({ + type: "warning", + message: "链接不正确 请输入正确的链接" + }); + return; + } + formData.value.serverAddr = serverConfig.serverAddr + formData.value.serverPort = serverConfig.serverPort + formData.value.authMethod = serverConfig.authMethod + formData.value.authToken = serverConfig.authToken + formData.value.transportHeartbeatInterval = serverConfig.transportHeartbeatInterval + formData.value.transportHeartbeatTimeout = serverConfig.transportHeartbeatTimeout + formData.value.user = serverConfig.user + formData.value.metaToken = serverConfig.metaToken + + handleSubmit(); + visibles.pasteServerConfig = false; + +}, 300) + + onUnmounted(() => { ipcRenderer.removeAllListeners("Config.getConfig.hook"); ipcRenderer.removeAllListeners("Config.saveConfig.hook"); @@ -236,7 +349,16 @@ onUnmounted(() => { -
服务器配置
+
+
服务器配置
+
+ + +
+
+
@@ -366,7 +488,7 @@ onUnmounted(() => { trigger="hover" > +
日志配置
@@ -622,6 +809,25 @@ onUnmounted(() => { + + + + + + + + + + + @@ -642,4 +848,5 @@ onUnmounted(() => { .button-input { width: calc(100% - 68px); } +