🚧 类型统一
This commit is contained in:
parent
989f9b8a37
commit
3961475421
@ -74,7 +74,7 @@ const unZip = (zipPath: string, targetPath: string) => {
|
|||||||
|
|
||||||
export const initGitHubApi = () => {
|
export const initGitHubApi = () => {
|
||||||
// 版本
|
// 版本
|
||||||
let versions = [];
|
let versions: FrpVersion[] = [];
|
||||||
|
|
||||||
const getVersion = versionId => {
|
const getVersion = versionId => {
|
||||||
return versions.find(f => f.id === versionId);
|
return versions.find(f => f.id === versionId);
|
||||||
|
@ -2,45 +2,22 @@ import Datastore from "nedb";
|
|||||||
import path from "path";
|
import path from "path";
|
||||||
import { app } from "electron";
|
import { app } from "electron";
|
||||||
|
|
||||||
const log = require('electron-log');
|
const log = require("electron-log");
|
||||||
|
|
||||||
const configDB = new Datastore({
|
const configDB = new Datastore({
|
||||||
autoload: true,
|
autoload: true,
|
||||||
filename: path.join(app.getPath("userData"), "config.db")
|
filename: path.join(app.getPath("userData"), "config.db")
|
||||||
});
|
});
|
||||||
|
|
||||||
export type Config = {
|
|
||||||
currentVersion: any;
|
|
||||||
serverAddr: string;
|
|
||||||
serverPort: number;
|
|
||||||
authMethod: string;
|
|
||||||
authToken: string;
|
|
||||||
logLevel: string;
|
|
||||||
logMaxDays: number;
|
|
||||||
tlsConfigEnable: boolean;
|
|
||||||
tlsConfigCertFile: string;
|
|
||||||
tlsConfigKeyFile: string;
|
|
||||||
tlsConfigTrustedCaFile: string;
|
|
||||||
tlsConfigServerName: string;
|
|
||||||
proxyConfigEnable: boolean;
|
|
||||||
proxyConfigProxyUrl: string;
|
|
||||||
systemSelfStart: boolean;
|
|
||||||
systemStartupConnect: boolean;
|
|
||||||
user: string;
|
|
||||||
metaToken: string;
|
|
||||||
transportHeartbeatInterval: number;
|
|
||||||
transportHeartbeatTimeout: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存
|
* 保存
|
||||||
*/
|
*/
|
||||||
export const saveConfig = (
|
export const saveConfig = (
|
||||||
document: Config,
|
document: FrpConfig,
|
||||||
cb?: (err: Error | null, numberOfUpdated: number, upsert: boolean) => void
|
cb?: (err: Error | null, numberOfUpdated: number, upsert: boolean) => void
|
||||||
) => {
|
) => {
|
||||||
document["_id"] = "1";
|
document["_id"] = "1";
|
||||||
log.debug(`保存日志 ${JSON.stringify(document)}`)
|
log.debug(`保存日志 ${JSON.stringify(document)}`);
|
||||||
configDB.update({ _id: "1" }, document, { upsert: true }, cb);
|
configDB.update({ _id: "1" }, document, { upsert: true }, cb);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -49,7 +26,7 @@ export const saveConfig = (
|
|||||||
* @param cb
|
* @param cb
|
||||||
*/
|
*/
|
||||||
export const getConfig = (
|
export const getConfig = (
|
||||||
cb: (err: Error | null, document: Config) => void
|
cb: (err: Error | null, document: FrpConfig) => void
|
||||||
) => {
|
) => {
|
||||||
configDB.findOne({ _id: "1" }, cb);
|
configDB.findOne({ _id: "1" }, cb);
|
||||||
};
|
};
|
||||||
|
@ -1,22 +1,14 @@
|
|||||||
import Datastore from "nedb";
|
import Datastore from "nedb";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { app } from "electron";
|
import { app } from "electron";
|
||||||
const log = require('electron-log');
|
|
||||||
|
const log = require("electron-log");
|
||||||
|
|
||||||
const proxyDB = new Datastore({
|
const proxyDB = new Datastore({
|
||||||
autoload: true,
|
autoload: true,
|
||||||
filename: path.join(app.getPath("userData"), "proxy.db")
|
filename: path.join(app.getPath("userData"), "proxy.db")
|
||||||
});
|
});
|
||||||
|
|
||||||
export type Proxy = {
|
|
||||||
_id: string;
|
|
||||||
name: string;
|
|
||||||
type: string;
|
|
||||||
localIp: string;
|
|
||||||
localPort: number;
|
|
||||||
remotePort: number;
|
|
||||||
customDomains: string[];
|
|
||||||
};
|
|
||||||
/**
|
/**
|
||||||
* 新增代理
|
* 新增代理
|
||||||
* @param proxy
|
* @param proxy
|
||||||
|
@ -9,12 +9,12 @@ const versionDB = new Datastore({
|
|||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增代理
|
* 新增版本
|
||||||
* @param proxy
|
* @param version
|
||||||
* @param cb
|
* @param cb
|
||||||
*/
|
*/
|
||||||
export const insertVersion = (
|
export const insertVersion = (
|
||||||
version: any,
|
version: FrpVersion,
|
||||||
cb?: (err: Error | null, document: any) => void
|
cb?: (err: Error | null, document: any) => void
|
||||||
) => {
|
) => {
|
||||||
log.debug(`新增版本:${JSON.stringify(version)}`);
|
log.debug(`新增版本:${JSON.stringify(version)}`);
|
||||||
@ -26,14 +26,14 @@ export const insertVersion = (
|
|||||||
* @param cb
|
* @param cb
|
||||||
*/
|
*/
|
||||||
export const listVersion = (
|
export const listVersion = (
|
||||||
callback: (err: Error | null, documents: any[]) => void
|
callback: (err: Error | null, documents: FrpVersion[]) => void
|
||||||
) => {
|
) => {
|
||||||
versionDB.find({}, callback);
|
versionDB.find({}, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getVersionById = (
|
export const getVersionById = (
|
||||||
id: string,
|
id: string,
|
||||||
callback: (err: Error | null, document: any) => void
|
callback: (err: Error | null, document: FrpVersion) => void
|
||||||
) => {
|
) => {
|
||||||
versionDB.findOne({id: id}, callback);
|
versionDB.findOne({id: id}, callback);
|
||||||
};
|
};
|
||||||
|
9
src/types/global.d.ts
vendored
9
src/types/global.d.ts
vendored
@ -1,9 +0,0 @@
|
|||||||
declare module 'element-plus/dist/locale/zh-cn.mjs' {
|
|
||||||
const zhLocale: any;
|
|
||||||
export default zhLocale;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module 'element-plus/dist/locale/en.mjs' {
|
|
||||||
const enLocale: any;
|
|
||||||
export default enLocale;
|
|
||||||
}
|
|
@ -7,51 +7,22 @@ import {useDebounceFn} from "@vueuse/core";
|
|||||||
import { clone } from "@/utils/clone";
|
import { clone } from "@/utils/clone";
|
||||||
import { Base64 } from "js-base64";
|
import { Base64 } from "js-base64";
|
||||||
|
|
||||||
|
|
||||||
defineComponent({
|
defineComponent({
|
||||||
name: "Config"
|
name: "Config"
|
||||||
});
|
});
|
||||||
|
|
||||||
type Config = {
|
type ShareLinkConfig = {
|
||||||
currentVersion: string;
|
|
||||||
serverAddr: string;
|
serverAddr: string;
|
||||||
serverPort: number;
|
serverPort: number;
|
||||||
authMethod: string;
|
authMethod: string;
|
||||||
authToken: string;
|
authToken: string;
|
||||||
logLevel: string;
|
|
||||||
logMaxDays: number;
|
|
||||||
tlsConfigEnable: boolean;
|
|
||||||
tlsConfigCertFile: string;
|
|
||||||
tlsConfigKeyFile: string;
|
|
||||||
tlsConfigTrustedCaFile: string;
|
|
||||||
tlsConfigServerName: string;
|
|
||||||
proxyConfigEnable: boolean;
|
|
||||||
proxyConfigProxyUrl: string;
|
|
||||||
systemSelfStart: boolean;
|
|
||||||
systemStartupConnect: boolean;
|
|
||||||
user: string;
|
|
||||||
metaToken: string;
|
|
||||||
transportHeartbeatInterval: number;
|
transportHeartbeatInterval: number;
|
||||||
transportHeartbeatTimeout: number;
|
transportHeartbeatTimeout: number;
|
||||||
|
user: string;
|
||||||
|
metaToken: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type Version = {
|
const defaultFormData = ref<FrpConfig>({
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
type ShareLinkConfig = {
|
|
||||||
serverAddr: string,
|
|
||||||
serverPort: number,
|
|
||||||
authMethod: string,
|
|
||||||
authToken: string,
|
|
||||||
transportHeartbeatInterval: number,
|
|
||||||
transportHeartbeatTimeout: number,
|
|
||||||
user: string,
|
|
||||||
metaToken: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
const defaultFormData = ref<Config>({
|
|
||||||
currentVersion: "",
|
currentVersion: "",
|
||||||
serverAddr: "",
|
serverAddr: "",
|
||||||
serverPort: 7000,
|
serverPort: 7000,
|
||||||
@ -71,11 +42,10 @@ const defaultFormData = ref<Config>({
|
|||||||
user: "",
|
user: "",
|
||||||
metaToken: "",
|
metaToken: "",
|
||||||
transportHeartbeatInterval: 30,
|
transportHeartbeatInterval: 30,
|
||||||
transportHeartbeatTimeout: 90,
|
transportHeartbeatTimeout: 90
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const formData = ref<FrpConfig>(defaultFormData.value);
|
||||||
const formData = ref<Config>(defaultFormData.value);
|
|
||||||
|
|
||||||
const loading = ref(1);
|
const loading = ref(1);
|
||||||
|
|
||||||
@ -92,22 +62,32 @@ const rules = reactive<FormRules>({
|
|||||||
serverPort: [
|
serverPort: [
|
||||||
{ required: true, message: "请输入服务器端口", trigger: "blur" }
|
{ required: true, message: "请输入服务器端口", trigger: "blur" }
|
||||||
],
|
],
|
||||||
user: [
|
user: [{ required: true, message: "请输入用户", trigger: "blur" }],
|
||||||
{required: true, message: "请输入用户", trigger: "blur"}
|
metaToken: [{ required: true, message: "请输入多用户令牌", trigger: "blur" }],
|
||||||
],
|
|
||||||
metaToken: [
|
|
||||||
{required: true, message: "请输入多用户令牌", trigger: "blur"}
|
|
||||||
],
|
|
||||||
authMethod: [{ required: true, message: "请选择验证方式", trigger: "blur" }],
|
authMethod: [{ required: true, message: "请选择验证方式", trigger: "blur" }],
|
||||||
authToken: [{ required: true, message: "请输入 Token 值 ", trigger: "blur" }],
|
authToken: [{ required: true, message: "请输入 Token 值 ", trigger: "blur" }],
|
||||||
logLevel: [{ required: true, message: "请选择日志级别 ", trigger: "blur" }],
|
logLevel: [{ required: true, message: "请选择日志级别 ", trigger: "blur" }],
|
||||||
logMaxDays: [{required: true, message: "请输入日志保留天数 ", trigger: "blur"}],
|
logMaxDays: [
|
||||||
tlsConfigEnable: [{required: true, message: "请选择 TLS 状态", trigger: "change"}],
|
{ required: true, message: "请输入日志保留天数 ", trigger: "blur" }
|
||||||
tlsConfigCertFile: [{required: true, message: "请选择 TLS 证书文件", trigger: "change"}],
|
],
|
||||||
tlsConfigKeyFile: [{required: true, message: "请选择 TLS 密钥文件", trigger: "change"}],
|
tlsConfigEnable: [
|
||||||
tlsConfigTrustedCaFile: [{required: true, message: "请选择 CA 证书文件", trigger: "change"}],
|
{ required: true, message: "请选择 TLS 状态", trigger: "change" }
|
||||||
tlsConfigServerName: [{required: true, message: "请输入 TLS Server 名称", trigger: "blur"}],
|
],
|
||||||
proxyConfigEnable: [{required: true, message: "请选择代理状态", trigger: "change"}],
|
tlsConfigCertFile: [
|
||||||
|
{ required: true, message: "请选择 TLS 证书文件", trigger: "change" }
|
||||||
|
],
|
||||||
|
tlsConfigKeyFile: [
|
||||||
|
{ required: true, message: "请选择 TLS 密钥文件", trigger: "change" }
|
||||||
|
],
|
||||||
|
tlsConfigTrustedCaFile: [
|
||||||
|
{ required: true, message: "请选择 CA 证书文件", trigger: "change" }
|
||||||
|
],
|
||||||
|
tlsConfigServerName: [
|
||||||
|
{ required: true, message: "请输入 TLS Server 名称", trigger: "blur" }
|
||||||
|
],
|
||||||
|
proxyConfigEnable: [
|
||||||
|
{ required: true, message: "请选择代理状态", trigger: "change" }
|
||||||
|
],
|
||||||
proxyConfigProxyUrl: [
|
proxyConfigProxyUrl: [
|
||||||
{ required: true, message: "请输入代理地址", trigger: "change" },
|
{ required: true, message: "请输入代理地址", trigger: "change" },
|
||||||
{
|
{
|
||||||
@ -117,18 +97,17 @@ const rules = reactive<FormRules>({
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
systemSelfStart: [
|
systemSelfStart: [
|
||||||
{required: true, message: "请选择是否开机自启", trigger: "change"},
|
{ required: true, message: "请选择是否开机自启", trigger: "change" }
|
||||||
],
|
],
|
||||||
transportHeartbeatInterval: [
|
transportHeartbeatInterval: [
|
||||||
{required: true, message: "心跳间隔时间不能为空", trigger: "change"},
|
{ required: true, message: "心跳间隔时间不能为空", trigger: "change" }
|
||||||
],
|
],
|
||||||
transportHeartbeatTimeout: [
|
transportHeartbeatTimeout: [
|
||||||
{required: true, message: "心跳超时时间不能为空", trigger: "change"},
|
{ required: true, message: "心跳超时时间不能为空", trigger: "change" }
|
||||||
],
|
]
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const versions = ref<Array<Version>>([]);
|
const versions = ref<Array<FrpVersion>>([]);
|
||||||
const copyServerConfigBase64 = ref();
|
const copyServerConfigBase64 = ref();
|
||||||
const pasteServerConfigBase64 = ref();
|
const pasteServerConfigBase64 = ref();
|
||||||
|
|
||||||
@ -137,7 +116,7 @@ const protocol = ref("frp://");
|
|||||||
|
|
||||||
const visibles = reactive({
|
const visibles = reactive({
|
||||||
copyServerConfig: false,
|
copyServerConfig: false,
|
||||||
pasteServerConfig: false,
|
pasteServerConfig: false
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleSubmit = useDebounceFn(() => {
|
const handleSubmit = useDebounceFn(() => {
|
||||||
@ -156,22 +135,29 @@ const handleLoadVersions = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleAuthMethodChange = e => {
|
const handleAuthMethodChange = e => {
|
||||||
if (e === 'multiuser') {
|
if (e === "multiuser") {
|
||||||
ElMessageBox.alert("多用户插件需要 Frp版本 >= <span class=\"font-black text-[#5A3DAA]\">v0.31.0</span> 请自行选择正确版本", "提示", {
|
ElMessageBox.alert(
|
||||||
|
'多用户插件需要 Frp版本 >= <span class="font-black text-[#5A3DAA]">v0.31.0</span> 请自行选择正确版本',
|
||||||
|
"提示",
|
||||||
|
{
|
||||||
// if you want to disable its autofocus
|
// if you want to disable its autofocus
|
||||||
autofocus: false,
|
autofocus: false,
|
||||||
confirmButtonText: "知道了",
|
confirmButtonText: "知道了",
|
||||||
dangerouslyUseHTMLString: true,
|
dangerouslyUseHTMLString: true
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const checkAndResetVersion = () => {
|
const checkAndResetVersion = () => {
|
||||||
const currentVersion = formData.value.currentVersion;
|
const currentVersion = formData.value.currentVersion;
|
||||||
if (currentVersion && !versions.value.some(item => item.id === currentVersion)) {
|
if (
|
||||||
|
currentVersion &&
|
||||||
|
!versions.value.some(item => item.id === currentVersion)
|
||||||
|
) {
|
||||||
formData.value.currentVersion = "";
|
formData.value.currentVersion = "";
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
ipcRenderer.send("config.getConfig");
|
ipcRenderer.send("config.getConfig");
|
||||||
@ -180,12 +166,14 @@ onMounted(() => {
|
|||||||
const { err, data } = args;
|
const { err, data } = args;
|
||||||
if (!err) {
|
if (!err) {
|
||||||
if (data) {
|
if (data) {
|
||||||
console.log('data', data)
|
console.log("data", data);
|
||||||
if (!data.transportHeartbeatInterval) {
|
if (!data.transportHeartbeatInterval) {
|
||||||
data.transportHeartbeatInterval = defaultFormData.value.transportHeartbeatInterval
|
data.transportHeartbeatInterval =
|
||||||
|
defaultFormData.value.transportHeartbeatInterval;
|
||||||
}
|
}
|
||||||
if (!data.transportHeartbeatTimeout) {
|
if (!data.transportHeartbeatTimeout) {
|
||||||
data.transportHeartbeatTimeout = defaultFormData.value.transportHeartbeatTimeout
|
data.transportHeartbeatTimeout =
|
||||||
|
defaultFormData.value.transportHeartbeatTimeout;
|
||||||
}
|
}
|
||||||
formData.value = data;
|
formData.value = data;
|
||||||
}
|
}
|
||||||
@ -213,19 +201,18 @@ const handleSelectFile = (type: number, ext: string[]) => {
|
|||||||
ipcRenderer.invoke("file.selectFile", ext).then(r => {
|
ipcRenderer.invoke("file.selectFile", ext).then(r => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 1:
|
case 1:
|
||||||
formData.value.tlsConfigCertFile = r[0]
|
formData.value.tlsConfigCertFile = r[0];
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
formData.value.tlsConfigKeyFile = r[0]
|
formData.value.tlsConfigKeyFile = r[0];
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
formData.value.tlsConfigTrustedCaFile = r[0]
|
formData.value.tlsConfigTrustedCaFile = r[0];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
console.log(r)
|
console.log(r);
|
||||||
|
});
|
||||||
})
|
};
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分享配置
|
* 分享配置
|
||||||
@ -239,14 +226,11 @@ const handleCopyServerConfig2Base64 = useDebounceFn(() => {
|
|||||||
transportHeartbeatInterval: formData.value.transportHeartbeatInterval,
|
transportHeartbeatInterval: formData.value.transportHeartbeatInterval,
|
||||||
transportHeartbeatTimeout: formData.value.transportHeartbeatTimeout,
|
transportHeartbeatTimeout: formData.value.transportHeartbeatTimeout,
|
||||||
user: formData.value.user,
|
user: formData.value.user,
|
||||||
metaToken: formData.value.metaToken,
|
metaToken: formData.value.metaToken
|
||||||
};
|
};
|
||||||
const base64str = Base64.encode(
|
const base64str = Base64.encode(JSON.stringify(shareConfig));
|
||||||
JSON.stringify(shareConfig)
|
|
||||||
)
|
|
||||||
copyServerConfigBase64.value = protocol.value + base64str;
|
copyServerConfigBase64.value = protocol.value + base64str;
|
||||||
visibles.copyServerConfig = true;
|
visibles.copyServerConfig = true;
|
||||||
|
|
||||||
}, 300);
|
}, 300);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -262,45 +246,45 @@ const handlePasteServerConfigBase64 = useDebounceFn(() => {
|
|||||||
type: "warning",
|
type: "warning",
|
||||||
message: "链接不正确 请输入正确的链接"
|
message: "链接不正确 请输入正确的链接"
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
if (!pasteServerConfigBase64.value.startsWith(protocol.value)) {
|
if (!pasteServerConfigBase64.value.startsWith(protocol.value)) {
|
||||||
tips()
|
tips();
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
const ciphertext = pasteServerConfigBase64.value.replace("frp://", "")
|
const ciphertext = pasteServerConfigBase64.value.replace("frp://", "");
|
||||||
const plaintext = Base64.decode(ciphertext)
|
const plaintext = Base64.decode(ciphertext);
|
||||||
console.log('plain', plaintext)
|
console.log("plain", plaintext);
|
||||||
let serverConfig: ShareLinkConfig = null;
|
let serverConfig: ShareLinkConfig = null;
|
||||||
try {
|
try {
|
||||||
serverConfig = JSON.parse(plaintext)
|
serverConfig = JSON.parse(plaintext);
|
||||||
} catch {
|
} catch {
|
||||||
tips()
|
tips();
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!serverConfig && !serverConfig.serverAddr) {
|
if (!serverConfig && !serverConfig.serverAddr) {
|
||||||
tips()
|
tips();
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
if (!serverConfig && !serverConfig.serverPort) {
|
if (!serverConfig && !serverConfig.serverPort) {
|
||||||
tips()
|
tips();
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
formData.value.serverAddr = serverConfig.serverAddr
|
formData.value.serverAddr = serverConfig.serverAddr;
|
||||||
formData.value.serverPort = serverConfig.serverPort
|
formData.value.serverPort = serverConfig.serverPort;
|
||||||
formData.value.authMethod = serverConfig.authMethod
|
formData.value.authMethod = serverConfig.authMethod;
|
||||||
formData.value.authToken = serverConfig.authToken
|
formData.value.authToken = serverConfig.authToken;
|
||||||
formData.value.transportHeartbeatInterval = serverConfig.transportHeartbeatInterval
|
formData.value.transportHeartbeatInterval =
|
||||||
formData.value.transportHeartbeatTimeout = serverConfig.transportHeartbeatTimeout
|
serverConfig.transportHeartbeatInterval;
|
||||||
formData.value.user = serverConfig.user
|
formData.value.transportHeartbeatTimeout =
|
||||||
formData.value.metaToken = serverConfig.metaToken
|
serverConfig.transportHeartbeatTimeout;
|
||||||
|
formData.value.user = serverConfig.user;
|
||||||
|
formData.value.metaToken = serverConfig.metaToken;
|
||||||
|
|
||||||
handleSubmit();
|
handleSubmit();
|
||||||
pasteServerConfigBase64.value = "";
|
pasteServerConfigBase64.value = "";
|
||||||
visibles.pasteServerConfig = false;
|
visibles.pasteServerConfig = false;
|
||||||
|
}, 300);
|
||||||
}, 300)
|
|
||||||
|
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
ipcRenderer.removeAllListeners("Config.getConfig.hook");
|
ipcRenderer.removeAllListeners("Config.getConfig.hook");
|
||||||
@ -312,9 +296,7 @@ onUnmounted(() => {
|
|||||||
<div class="main">
|
<div class="main">
|
||||||
<breadcrumb />
|
<breadcrumb />
|
||||||
<div class="app-container-breadcrumb pr-2" v-loading="loading > 0">
|
<div class="app-container-breadcrumb pr-2" v-loading="loading > 0">
|
||||||
<div
|
<div class="w-full bg-white p-4 rounded drop-shadow-lg">
|
||||||
class="w-full bg-white p-4 rounded drop-shadow-lg"
|
|
||||||
>
|
|
||||||
<el-form
|
<el-form
|
||||||
:model="formData"
|
:model="formData"
|
||||||
:rules="rules"
|
:rules="rules"
|
||||||
@ -327,7 +309,6 @@ onUnmounted(() => {
|
|||||||
<div class="h2 flex justify-between">
|
<div class="h2 flex justify-between">
|
||||||
<div>版本选择</div>
|
<div>版本选择</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="Frp版本:" prop="currentVersion">
|
<el-form-item label="Frp版本:" prop="currentVersion">
|
||||||
@ -348,7 +329,11 @@ onUnmounted(() => {
|
|||||||
<iconify-icon-offline class="mr-1" icon="refresh-rounded" />
|
<iconify-icon-offline class="mr-1" icon="refresh-rounded" />
|
||||||
手动刷新
|
手动刷新
|
||||||
</el-link>
|
</el-link>
|
||||||
<el-link class="ml-2" type="primary" @click="$router.replace({ name: 'Download' })">
|
<el-link
|
||||||
|
class="ml-2"
|
||||||
|
type="primary"
|
||||||
|
@click="$router.replace({ name: 'Download' })"
|
||||||
|
>
|
||||||
<IconifyIconOffline class="mr-1" icon="download" />
|
<IconifyIconOffline class="mr-1" icon="download" />
|
||||||
点击这里去下载
|
点击这里去下载
|
||||||
</el-link>
|
</el-link>
|
||||||
@ -359,28 +344,36 @@ onUnmounted(() => {
|
|||||||
<div class="h2 flex justify-between">
|
<div class="h2 flex justify-between">
|
||||||
<div>服务器配置</div>
|
<div>服务器配置</div>
|
||||||
<div class="flex items-center justify-center">
|
<div class="flex items-center justify-center">
|
||||||
<IconifyIconOffline @click="handleCopyServerConfig2Base64"
|
<IconifyIconOffline
|
||||||
class="mr-2 cursor-pointer text-xl font-bold" icon="content-copy"/>
|
@click="handleCopyServerConfig2Base64"
|
||||||
<IconifyIconOffline @click="handlePasteServerConfig4Base64"
|
class="mr-2 cursor-pointer text-xl font-bold"
|
||||||
class="mr-2 cursor-pointer text-xl font-bold" icon="content-paste-go"/>
|
icon="content-copy"
|
||||||
|
/>
|
||||||
|
<IconifyIconOffline
|
||||||
|
@click="handlePasteServerConfig4Base64"
|
||||||
|
class="mr-2 cursor-pointer text-xl font-bold"
|
||||||
|
icon="content-paste-go"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="服务器地址:" prop="serverAddr">
|
<el-form-item label="服务器地址:" prop="serverAddr">
|
||||||
<template #label>
|
<template #label>
|
||||||
<div class="h-full flex items-center mr-1">
|
<div class="h-full flex items-center mr-1">
|
||||||
<el-popover
|
<el-popover placement="top" trigger="hover">
|
||||||
placement="top"
|
|
||||||
trigger="hover"
|
|
||||||
>
|
|
||||||
<template #default>
|
<template #default>
|
||||||
Frps服务端地址 <br/> 支持 <span class="font-black text-[#5A3DAA]">域名</span>、<span
|
Frps服务端地址 <br />
|
||||||
class="font-black text-[#5A3DAA]">IP</span>
|
支持
|
||||||
|
<span class="font-black text-[#5A3DAA]">域名</span
|
||||||
|
>、<span class="font-black text-[#5A3DAA]">IP</span>
|
||||||
</template>
|
</template>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<IconifyIconOffline class="text-base" color="#5A3DAA" icon="info"/>
|
<IconifyIconOffline
|
||||||
|
class="text-base"
|
||||||
|
color="#5A3DAA"
|
||||||
|
icon="info"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
@ -408,17 +401,19 @@ onUnmounted(() => {
|
|||||||
<el-form-item label="验证方式:" prop="authMethod">
|
<el-form-item label="验证方式:" prop="authMethod">
|
||||||
<template #label>
|
<template #label>
|
||||||
<div class="h-full flex items-center mr-1">
|
<div class="h-full flex items-center mr-1">
|
||||||
<el-popover
|
<el-popover width="200" placement="top" trigger="hover">
|
||||||
width="200"
|
|
||||||
placement="top"
|
|
||||||
trigger="hover"
|
|
||||||
>
|
|
||||||
<template #default>
|
<template #default>
|
||||||
对应参数:<span class="font-black text-[#5A3DAA]">auth.method</span>
|
对应参数:<span class="font-black text-[#5A3DAA]"
|
||||||
|
>auth.method</span
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<!-- <IconifyIconOffline class="text-base" color="#5A3DAA" icon="info"/>-->
|
<!-- <IconifyIconOffline class="text-base" color="#5A3DAA" icon="info"/>-->
|
||||||
<IconifyIconOffline class="text-base" color="#5A3DAA" icon="info"/>
|
<IconifyIconOffline
|
||||||
|
class="text-base"
|
||||||
|
color="#5A3DAA"
|
||||||
|
icon="info"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
@ -440,16 +435,18 @@ onUnmounted(() => {
|
|||||||
<el-form-item label="令牌:" prop="authToken">
|
<el-form-item label="令牌:" prop="authToken">
|
||||||
<template #label>
|
<template #label>
|
||||||
<div class="h-full flex items-center mr-1">
|
<div class="h-full flex items-center mr-1">
|
||||||
<el-popover
|
<el-popover placement="top" trigger="hover" width="200">
|
||||||
placement="top"
|
|
||||||
trigger="hover"
|
|
||||||
width="200"
|
|
||||||
>
|
|
||||||
<template #default>
|
<template #default>
|
||||||
对应参数:<span class="font-black text-[#5A3DAA]">auth.token</span>
|
对应参数:<span class="font-black text-[#5A3DAA]"
|
||||||
|
>auth.token</span
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<IconifyIconOffline class="text-base" color="#5A3DAA" icon="info"/>
|
<IconifyIconOffline
|
||||||
|
class="text-base"
|
||||||
|
color="#5A3DAA"
|
||||||
|
icon="info"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
@ -466,40 +463,42 @@ onUnmounted(() => {
|
|||||||
<el-form-item label="用户:" prop="user">
|
<el-form-item label="用户:" prop="user">
|
||||||
<template #label>
|
<template #label>
|
||||||
<div class="h-full flex items-center mr-1">
|
<div class="h-full flex items-center mr-1">
|
||||||
<el-popover
|
<el-popover placement="top" trigger="hover">
|
||||||
placement="top"
|
|
||||||
trigger="hover"
|
|
||||||
>
|
|
||||||
<template #default>
|
<template #default>
|
||||||
对应参数:<span class="font-black text-[#5A3DAA]">user</span>
|
对应参数:<span class="font-black text-[#5A3DAA]"
|
||||||
|
>user</span
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<IconifyIconOffline class="text-base" color="#5A3DAA" icon="info"/>
|
<IconifyIconOffline
|
||||||
|
class="text-base"
|
||||||
|
color="#5A3DAA"
|
||||||
|
icon="info"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
用户:
|
用户:
|
||||||
</template>
|
</template>
|
||||||
<el-input
|
<el-input placeholder="请输入用户" v-model="formData.user" />
|
||||||
placeholder="请输入用户"
|
|
||||||
v-model="formData.user"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12" v-if="formData.authMethod === 'multiuser'">
|
<el-col :span="12" v-if="formData.authMethod === 'multiuser'">
|
||||||
<el-form-item label="用户令牌:" prop="metaToken">
|
<el-form-item label="用户令牌:" prop="metaToken">
|
||||||
<template #label>
|
<template #label>
|
||||||
<div class="h-full flex items-center mr-1">
|
<div class="h-full flex items-center mr-1">
|
||||||
<el-popover
|
<el-popover width="200" placement="top" trigger="hover">
|
||||||
width="200"
|
|
||||||
placement="top"
|
|
||||||
trigger="hover"
|
|
||||||
>
|
|
||||||
<template #default>
|
<template #default>
|
||||||
对应参数:<span class="font-black text-[#5A3DAA]">metadatas.token</span>
|
对应参数:<span class="font-black text-[#5A3DAA]"
|
||||||
|
>metadatas.token</span
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<IconifyIconOffline class="text-base" color="#5A3DAA" icon="info"/>
|
<IconifyIconOffline
|
||||||
|
class="text-base"
|
||||||
|
color="#5A3DAA"
|
||||||
|
icon="info"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
@ -513,27 +512,38 @@ onUnmounted(() => {
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="心跳间隔:" prop="transportHeartbeatInterval">
|
<el-form-item
|
||||||
|
label="心跳间隔:"
|
||||||
|
prop="transportHeartbeatInterval"
|
||||||
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
<div class="h-full flex items-center mr-1">
|
<div class="h-full flex items-center mr-1">
|
||||||
<el-popover
|
<el-popover width="300" placement="top" trigger="hover">
|
||||||
width="300"
|
|
||||||
placement="top"
|
|
||||||
trigger="hover"
|
|
||||||
>
|
|
||||||
<template #default>
|
<template #default>
|
||||||
多长向服务端发发送一次心跳包 单位: <span class="font-black text-[#5A3DAA]">秒</span> <br/>
|
多长向服务端发发送一次心跳包 单位:
|
||||||
对应参数:<span class="font-black text-[#5A3DAA]">transport.heartbeatInterval</span>
|
<span class="font-black text-[#5A3DAA]">秒</span> <br />
|
||||||
|
对应参数:<span class="font-black text-[#5A3DAA]"
|
||||||
|
>transport.heartbeatInterval</span
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<IconifyIconOffline class="text-base" color="#5A3DAA" icon="info"/>
|
<IconifyIconOffline
|
||||||
|
class="text-base"
|
||||||
|
color="#5A3DAA"
|
||||||
|
icon="info"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
心跳间隔:
|
心跳间隔:
|
||||||
</template>
|
</template>
|
||||||
<el-input-number class="w-full" v-model="formData.transportHeartbeatInterval" :min="1" :max="10"
|
<el-input-number
|
||||||
controls-position="right"/>
|
class="w-full"
|
||||||
|
v-model="formData.transportHeartbeatInterval"
|
||||||
|
:min="1"
|
||||||
|
:max="10"
|
||||||
|
controls-position="right"
|
||||||
|
/>
|
||||||
<!-- <el-input-->
|
<!-- <el-input-->
|
||||||
<!-- placeholder="请输入心跳间隔"-->
|
<!-- placeholder="请输入心跳间隔"-->
|
||||||
<!-- type="number"-->
|
<!-- type="number"-->
|
||||||
@ -548,24 +558,32 @@ onUnmounted(() => {
|
|||||||
<el-form-item label="心跳超时:" prop="transportHeartbeatTimeout">
|
<el-form-item label="心跳超时:" prop="transportHeartbeatTimeout">
|
||||||
<template #label>
|
<template #label>
|
||||||
<div class="h-full flex items-center mr-1">
|
<div class="h-full flex items-center mr-1">
|
||||||
<el-popover
|
<el-popover width="300" placement="top" trigger="hover">
|
||||||
width="300"
|
|
||||||
placement="top"
|
|
||||||
trigger="hover"
|
|
||||||
>
|
|
||||||
<template #default>
|
<template #default>
|
||||||
心跳超时时间 单位: <span class="font-black text-[#5A3DAA]">秒</span> <br/>
|
心跳超时时间 单位:
|
||||||
对应参数:<span class="font-black text-[#5A3DAA]">transport.heartbeatTimeout</span>
|
<span class="font-black text-[#5A3DAA]">秒</span> <br />
|
||||||
|
对应参数:<span class="font-black text-[#5A3DAA]"
|
||||||
|
>transport.heartbeatTimeout</span
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<IconifyIconOffline class="text-base" color="#5A3DAA" icon="info"/>
|
<IconifyIconOffline
|
||||||
|
class="text-base"
|
||||||
|
color="#5A3DAA"
|
||||||
|
icon="info"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
心跳超时:
|
心跳超时:
|
||||||
</template>
|
</template>
|
||||||
<el-input-number class="w-full" v-model="formData.transportHeartbeatTimeout" :min="1" :max="10"
|
<el-input-number
|
||||||
controls-position="right"/>
|
class="w-full"
|
||||||
|
v-model="formData.transportHeartbeatTimeout"
|
||||||
|
:min="1"
|
||||||
|
:max="10"
|
||||||
|
controls-position="right"
|
||||||
|
/>
|
||||||
<!-- <el-input-->
|
<!-- <el-input-->
|
||||||
<!-- placeholder="请输入心跳超时时间"-->
|
<!-- placeholder="请输入心跳超时时间"-->
|
||||||
<!-- :min="0"-->
|
<!-- :min="0"-->
|
||||||
@ -581,27 +599,35 @@ onUnmounted(() => {
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="是否启用TSL:" prop="tlsConfigEnable">
|
<el-form-item label="是否启用TSL:" prop="tlsConfigEnable">
|
||||||
<el-switch active-text="开"
|
<el-switch
|
||||||
|
active-text="开"
|
||||||
inline-prompt
|
inline-prompt
|
||||||
inactive-text="关"
|
inactive-text="关"
|
||||||
v-model="formData.tlsConfigEnable"/>
|
v-model="formData.tlsConfigEnable"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<template v-if="formData.tlsConfigEnable">
|
<template v-if="formData.tlsConfigEnable">
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="TLS证书文件:" prop="tlsConfigCertFile" label-width="180">
|
<el-form-item
|
||||||
|
label="TLS证书文件:"
|
||||||
|
prop="tlsConfigCertFile"
|
||||||
|
label-width="180"
|
||||||
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
<div class="h-full flex items-center mr-1">
|
<div class="h-full flex items-center mr-1">
|
||||||
<el-popover
|
<el-popover width="260" placement="top" trigger="hover">
|
||||||
width="260"
|
|
||||||
placement="top"
|
|
||||||
trigger="hover"
|
|
||||||
>
|
|
||||||
<template #default>
|
<template #default>
|
||||||
对应参数:<span class="font-black text-[#5A3DAA]">transport.tls.certFile</span>
|
对应参数:<span class="font-black text-[#5A3DAA]"
|
||||||
|
>transport.tls.certFile</span
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<IconifyIconOffline class="text-base" color="#5A3DAA" icon="info"/>
|
<IconifyIconOffline
|
||||||
|
class="text-base"
|
||||||
|
color="#5A3DAA"
|
||||||
|
icon="info"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
@ -613,23 +639,34 @@ onUnmounted(() => {
|
|||||||
placeholder="请选择TLS证书文件"
|
placeholder="请选择TLS证书文件"
|
||||||
readonly
|
readonly
|
||||||
/>
|
/>
|
||||||
<el-button class="ml-2" type="primary" @click="handleSelectFile(1, ['crt'])">选择</el-button>
|
<el-button
|
||||||
|
class="ml-2"
|
||||||
|
type="primary"
|
||||||
|
@click="handleSelectFile(1, ['crt'])"
|
||||||
|
>选择</el-button
|
||||||
|
>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="TLS密钥文件:" prop="tlsConfigKeyFile" label-width="180">
|
<el-form-item
|
||||||
|
label="TLS密钥文件:"
|
||||||
|
prop="tlsConfigKeyFile"
|
||||||
|
label-width="180"
|
||||||
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
<div class="h-full flex items-center mr-1">
|
<div class="h-full flex items-center mr-1">
|
||||||
<el-popover
|
<el-popover width="260" placement="top" trigger="hover">
|
||||||
width="260"
|
|
||||||
placement="top"
|
|
||||||
trigger="hover"
|
|
||||||
>
|
|
||||||
<template #default>
|
<template #default>
|
||||||
对应参数:<span class="font-black text-[#5A3DAA]">transport.tls.keyFile</span>
|
对应参数:<span class="font-black text-[#5A3DAA]"
|
||||||
|
>transport.tls.keyFile</span
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<IconifyIconOffline class="text-base" color="#5A3DAA" icon="info"/>
|
<IconifyIconOffline
|
||||||
|
class="text-base"
|
||||||
|
color="#5A3DAA"
|
||||||
|
icon="info"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
@ -641,23 +678,34 @@ onUnmounted(() => {
|
|||||||
placeholder="请选择 TLS 密钥文件"
|
placeholder="请选择 TLS 密钥文件"
|
||||||
readonly
|
readonly
|
||||||
/>
|
/>
|
||||||
<el-button class="ml-2" type="primary" @click="handleSelectFile(2, ['key'])">选择</el-button>
|
<el-button
|
||||||
|
class="ml-2"
|
||||||
|
type="primary"
|
||||||
|
@click="handleSelectFile(2, ['key'])"
|
||||||
|
>选择</el-button
|
||||||
|
>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="CA证书文件:" prop="tlsConfigTrustedCaFile" label-width="180">
|
<el-form-item
|
||||||
|
label="CA证书文件:"
|
||||||
|
prop="tlsConfigTrustedCaFile"
|
||||||
|
label-width="180"
|
||||||
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
<div class="h-full flex items-center mr-1">
|
<div class="h-full flex items-center mr-1">
|
||||||
<el-popover
|
<el-popover width="310" placement="top" trigger="hover">
|
||||||
width="310"
|
|
||||||
placement="top"
|
|
||||||
trigger="hover"
|
|
||||||
>
|
|
||||||
<template #default>
|
<template #default>
|
||||||
对应参数:<span class="font-black text-[#5A3DAA]">transport.tls.trustedCaFile</span>
|
对应参数:<span class="font-black text-[#5A3DAA]"
|
||||||
|
>transport.tls.trustedCaFile</span
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<IconifyIconOffline class="text-base" color="#5A3DAA" icon="info"/>
|
<IconifyIconOffline
|
||||||
|
class="text-base"
|
||||||
|
color="#5A3DAA"
|
||||||
|
icon="info"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
@ -669,23 +717,34 @@ onUnmounted(() => {
|
|||||||
placeholder="请选择CA证书文件"
|
placeholder="请选择CA证书文件"
|
||||||
readonly
|
readonly
|
||||||
/>
|
/>
|
||||||
<el-button class="ml-2" type="primary" @click="handleSelectFile(3, ['crt'])">选择</el-button>
|
<el-button
|
||||||
|
class="ml-2"
|
||||||
|
type="primary"
|
||||||
|
@click="handleSelectFile(3, ['crt'])"
|
||||||
|
>选择</el-button
|
||||||
|
>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="TLS Server 名称:" prop="tlsConfigServerName" label-width="180">
|
<el-form-item
|
||||||
|
label="TLS Server 名称:"
|
||||||
|
prop="tlsConfigServerName"
|
||||||
|
label-width="180"
|
||||||
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
<div class="h-full flex items-center mr-1">
|
<div class="h-full flex items-center mr-1">
|
||||||
<el-popover
|
<el-popover width="300" placement="top" trigger="hover">
|
||||||
width="300"
|
|
||||||
placement="top"
|
|
||||||
trigger="hover"
|
|
||||||
>
|
|
||||||
<template #default>
|
<template #default>
|
||||||
对应参数:<span class="font-black text-[#5A3DAA]">transport.tls.serverName</span>
|
对应参数:<span class="font-black text-[#5A3DAA]"
|
||||||
|
>transport.tls.serverName</span
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<IconifyIconOffline class="text-base" color="#5A3DAA" icon="info"/>
|
<IconifyIconOffline
|
||||||
|
class="text-base"
|
||||||
|
color="#5A3DAA"
|
||||||
|
icon="info"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
@ -703,10 +762,12 @@ onUnmounted(() => {
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="是否启动代理:" prop="proxyConfigEnable">
|
<el-form-item label="是否启动代理:" prop="proxyConfigEnable">
|
||||||
<el-switch active-text="开"
|
<el-switch
|
||||||
|
active-text="开"
|
||||||
inline-prompt
|
inline-prompt
|
||||||
inactive-text="关"
|
inactive-text="关"
|
||||||
v-model="formData.proxyConfigEnable"/>
|
v-model="formData.proxyConfigEnable"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<template v-if="formData.proxyConfigEnable">
|
<template v-if="formData.proxyConfigEnable">
|
||||||
@ -714,23 +775,27 @@ onUnmounted(() => {
|
|||||||
<el-form-item label="代理地址:" prop="proxyConfigProxyUrl">
|
<el-form-item label="代理地址:" prop="proxyConfigProxyUrl">
|
||||||
<template #label>
|
<template #label>
|
||||||
<div class="h-full flex items-center mr-1">
|
<div class="h-full flex items-center mr-1">
|
||||||
<el-popover
|
<el-popover width="300" placement="top" trigger="hover">
|
||||||
width="300"
|
|
||||||
placement="top"
|
|
||||||
trigger="hover"
|
|
||||||
>
|
|
||||||
<template #default>
|
<template #default>
|
||||||
对应参数:<span class="font-black text-[#5A3DAA]">transport.proxyURL</span>
|
对应参数:<span class="font-black text-[#5A3DAA]"
|
||||||
|
>transport.proxyURL</span
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<IconifyIconOffline class="text-base" color="#5A3DAA" icon="info"/>
|
<IconifyIconOffline
|
||||||
|
class="text-base"
|
||||||
|
color="#5A3DAA"
|
||||||
|
icon="info"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
代理地址:
|
代理地址:
|
||||||
</template>
|
</template>
|
||||||
<el-input v-model="formData.proxyConfigProxyUrl"
|
<el-input
|
||||||
placeholder="http://user:pwd@192.168.1.128:8080"/>
|
v-model="formData.proxyConfigProxyUrl"
|
||||||
|
placeholder="http://user:pwd@192.168.1.128:8080"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</template>
|
</template>
|
||||||
@ -750,7 +815,11 @@ onUnmounted(() => {
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="日志保留天数:" prop="logMaxDays">
|
<el-form-item label="日志保留天数:" prop="logMaxDays">
|
||||||
<el-input-number class="!w-full" controls-position="right" v-model="formData.logMaxDays"/>
|
<el-input-number
|
||||||
|
class="!w-full"
|
||||||
|
controls-position="right"
|
||||||
|
v-model="formData.logMaxDays"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
@ -760,49 +829,59 @@ onUnmounted(() => {
|
|||||||
<el-form-item label="开机自启:" prop="systemSelfStart">
|
<el-form-item label="开机自启:" prop="systemSelfStart">
|
||||||
<template #label>
|
<template #label>
|
||||||
<div class="h-full flex items-center mr-1">
|
<div class="h-full flex items-center mr-1">
|
||||||
<el-popover
|
<el-popover placement="top" trigger="hover">
|
||||||
placement="top"
|
|
||||||
trigger="hover"
|
|
||||||
>
|
|
||||||
<template #default>
|
<template #default>
|
||||||
开机自动启动 <br/><span class="font-black text-[#5A3DAA]">Frpc Desktop</span>
|
开机自动启动 <br /><span
|
||||||
|
class="font-black text-[#5A3DAA]"
|
||||||
|
>Frpc Desktop</span
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<IconifyIconOffline class="text-base" color="#5A3DAA" icon="info"/>
|
<IconifyIconOffline
|
||||||
|
class="text-base"
|
||||||
|
color="#5A3DAA"
|
||||||
|
icon="info"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
开机自启:
|
开机自启:
|
||||||
</template>
|
</template>
|
||||||
<el-switch active-text="开"
|
<el-switch
|
||||||
|
active-text="开"
|
||||||
inline-prompt
|
inline-prompt
|
||||||
inactive-text="关"
|
inactive-text="关"
|
||||||
v-model="formData.systemSelfStart"/>
|
v-model="formData.systemSelfStart"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="自动连接:" prop="systemStartupConnect">
|
<el-form-item label="自动连接:" prop="systemStartupConnect">
|
||||||
<template #label>
|
<template #label>
|
||||||
<div class="h-full flex items-center mr-1">
|
<div class="h-full flex items-center mr-1">
|
||||||
<el-popover
|
<el-popover placement="top" trigger="hover">
|
||||||
placement="top"
|
|
||||||
trigger="hover"
|
|
||||||
>
|
|
||||||
<template #default>
|
<template #default>
|
||||||
启动软件后是否<span class="font-black text-[#5A3DAA]">自动连接</span>服务器
|
启动软件后是否<span class="font-black text-[#5A3DAA]"
|
||||||
|
>自动连接</span
|
||||||
|
>服务器
|
||||||
</template>
|
</template>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<IconifyIconOffline class="text-base" color="#5A3DAA" icon="info"/>
|
<IconifyIconOffline
|
||||||
|
class="text-base"
|
||||||
|
color="#5A3DAA"
|
||||||
|
icon="info"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
自动连接:
|
自动连接:
|
||||||
</template>
|
</template>
|
||||||
<el-switch active-text="开"
|
<el-switch
|
||||||
|
active-text="开"
|
||||||
inline-prompt
|
inline-prompt
|
||||||
inactive-text="关"
|
inactive-text="关"
|
||||||
v-model="formData.systemStartupConnect"/>
|
v-model="formData.systemStartupConnect"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
@ -818,47 +897,73 @@ onUnmounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-dialog v-model="visibles.copyServerConfig" title="复制链接" width="500" top="5%">
|
<el-dialog
|
||||||
<el-alert class="mb-4" title="生成内容包含服务器密钥等内容 请妥善保管 且链接仅在Frpc-Desktop中可用" type="warning"
|
v-model="visibles.copyServerConfig"
|
||||||
:closable="false"/>
|
title="复制链接"
|
||||||
<el-input class="h-30" v-model="copyServerConfigBase64" type="textarea" :rows="8"></el-input>
|
width="500"
|
||||||
|
top="5%"
|
||||||
|
>
|
||||||
|
<el-alert
|
||||||
|
class="mb-4"
|
||||||
|
title="生成内容包含服务器密钥等内容 请妥善保管 且链接仅在Frpc-Desktop中可用"
|
||||||
|
type="warning"
|
||||||
|
:closable="false"
|
||||||
|
/>
|
||||||
|
<el-input
|
||||||
|
class="h-30"
|
||||||
|
v-model="copyServerConfigBase64"
|
||||||
|
type="textarea"
|
||||||
|
:rows="8"
|
||||||
|
></el-input>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<el-dialog v-model="visibles.pasteServerConfig" title="导入链接" width="500" top="5%">
|
<el-dialog
|
||||||
<el-input class="h-30"
|
v-model="visibles.pasteServerConfig"
|
||||||
|
title="导入链接"
|
||||||
|
width="500"
|
||||||
|
top="5%"
|
||||||
|
>
|
||||||
|
<el-input
|
||||||
|
class="h-30"
|
||||||
v-model="pasteServerConfigBase64"
|
v-model="pasteServerConfigBase64"
|
||||||
type="textarea" placeholder="frp://......"
|
type="textarea"
|
||||||
:rows="8"></el-input>
|
placeholder="frp://......"
|
||||||
|
:rows="8"
|
||||||
|
></el-input>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
|
<el-button
|
||||||
<el-button plain type="primary" @click="handlePasteServerConfigBase64">
|
plain
|
||||||
<IconifyIconOffline class="cursor-pointer mr-2" icon="label-important-rounded"/>
|
type="primary"
|
||||||
|
@click="handlePasteServerConfigBase64"
|
||||||
|
>
|
||||||
|
<IconifyIconOffline
|
||||||
|
class="cursor-pointer mr-2"
|
||||||
|
icon="label-important-rounded"
|
||||||
|
/>
|
||||||
导 入
|
导 入
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
.h2 {
|
.h2 {
|
||||||
color: #5A3DAA;
|
color: #5a3daa;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
|
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB",
|
||||||
|
"Microsoft YaHei", "微软雅黑", Arial, sans-serif;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
padding: 6px 10px 6px 15px;
|
padding: 6px 10px 6px 15px;
|
||||||
border-left: 5px solid #5A3DAA;
|
border-left: 5px solid #5a3daa;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background-color: #EEEBF6;
|
background-color: #eeebf6;
|
||||||
margin-bottom: 18px;
|
margin-bottom: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-input {
|
.button-input {
|
||||||
width: calc(100% - 68px);
|
width: calc(100% - 68px);
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -11,20 +11,7 @@ defineComponent({
|
|||||||
name: "Download"
|
name: "Download"
|
||||||
});
|
});
|
||||||
|
|
||||||
type Asset = {
|
const versions = ref<Array<FrpVersion>>([]);
|
||||||
name: string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Version = {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
published_at: string;
|
|
||||||
download_completed: boolean;
|
|
||||||
absPath: string;
|
|
||||||
assets: Asset[]
|
|
||||||
};
|
|
||||||
|
|
||||||
const versions = ref<Array<Version>>([]);
|
|
||||||
const loading = ref(1);
|
const loading = ref(1);
|
||||||
const downloadPercentage = ref(0);
|
const downloadPercentage = ref(0);
|
||||||
const downloading = ref<Map<string, number>>(new Map<string, number>());
|
const downloading = ref<Map<string, number>>(new Map<string, number>());
|
||||||
@ -40,7 +27,7 @@ const handleLoadVersions = () => {
|
|||||||
* 下载
|
* 下载
|
||||||
* @param version
|
* @param version
|
||||||
*/
|
*/
|
||||||
const handleDownload = useDebounceFn((version: Version) => {
|
const handleDownload = useDebounceFn((version: FrpVersion) => {
|
||||||
ipcRenderer.send("github.download", version.id);
|
ipcRenderer.send("github.download", version.id);
|
||||||
downloading.value.set(version.id, 0);
|
downloading.value.set(version.id, 0);
|
||||||
}, 300);
|
}, 300);
|
||||||
@ -49,7 +36,7 @@ const handleDownload = useDebounceFn((version: Version) => {
|
|||||||
* 删除下载
|
* 删除下载
|
||||||
* @param version
|
* @param version
|
||||||
*/
|
*/
|
||||||
const handleDeleteVersion = useDebounceFn((version: Version) => {
|
const handleDeleteVersion = useDebounceFn((version: FrpVersion) => {
|
||||||
ipcRenderer.send("github.deleteVersion", {
|
ipcRenderer.send("github.deleteVersion", {
|
||||||
id: version.id,
|
id: version.id,
|
||||||
absPath: version.absPath
|
absPath: version.absPath
|
||||||
@ -61,8 +48,8 @@ const handleInitDownloadHook = () => {
|
|||||||
loading.value--;
|
loading.value--;
|
||||||
versions.value = args.map(m => {
|
versions.value = args.map(m => {
|
||||||
m.published_at = moment(m.published_at).format("YYYY-MM-DD HH:mm:ss")
|
m.published_at = moment(m.published_at).format("YYYY-MM-DD HH:mm:ss")
|
||||||
return m as Version;
|
return m as FrpVersion;
|
||||||
}) as Array<Version>;
|
}) as Array<FrpVersion>;
|
||||||
console.log(versions, 'versions')
|
console.log(versions, 'versions')
|
||||||
});
|
});
|
||||||
// 进度监听
|
// 进度监听
|
||||||
@ -75,7 +62,7 @@ const handleInitDownloadHook = () => {
|
|||||||
});
|
});
|
||||||
ipcRenderer.on("Download.frpVersionDownloadOnCompleted", (event, args) => {
|
ipcRenderer.on("Download.frpVersionDownloadOnCompleted", (event, args) => {
|
||||||
downloading.value.delete(args);
|
downloading.value.delete(args);
|
||||||
const version: Version | undefined = versions.value.find(
|
const version: FrpVersion | undefined = versions.value.find(
|
||||||
f => f.id === args
|
f => f.id === args
|
||||||
);
|
);
|
||||||
if (version) {
|
if (version) {
|
||||||
|
@ -7,27 +7,10 @@ import {clone} from "@/utils/clone";
|
|||||||
import { useDebounceFn } from "@vueuse/core";
|
import { useDebounceFn } from "@vueuse/core";
|
||||||
import IconifyIconOffline from "@/components/IconifyIcon/src/iconifyIconOffline";
|
import IconifyIconOffline from "@/components/IconifyIcon/src/iconifyIconOffline";
|
||||||
|
|
||||||
|
|
||||||
defineComponent({
|
defineComponent({
|
||||||
name: "Proxy"
|
name: "Proxy"
|
||||||
});
|
});
|
||||||
|
|
||||||
type Proxy = {
|
|
||||||
_id: string;
|
|
||||||
name: string;
|
|
||||||
type: string;
|
|
||||||
localIp: string;
|
|
||||||
localPort: number;
|
|
||||||
remotePort: number;
|
|
||||||
customDomains: string[];
|
|
||||||
};
|
|
||||||
|
|
||||||
type LocalPort = {
|
|
||||||
protocol: string;
|
|
||||||
ip: string;
|
|
||||||
port: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 代理列表
|
* 代理列表
|
||||||
*/
|
*/
|
||||||
@ -52,25 +35,48 @@ const edit = ref({
|
|||||||
visible: false
|
visible: false
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
const defaultForm = ref<Proxy>({
|
||||||
* 表单内容
|
|
||||||
*/
|
|
||||||
const editForm = ref<Proxy>({
|
|
||||||
_id: "",
|
_id: "",
|
||||||
name: "",
|
name: "",
|
||||||
type: "http",
|
type: "http",
|
||||||
localIp: "",
|
localIp: "",
|
||||||
localPort: 8080,
|
localPort: 8080,
|
||||||
remotePort: 8080,
|
remotePort: 8080,
|
||||||
customDomains: [""]
|
customDomains: [""],
|
||||||
|
stcpModel: "visitor",
|
||||||
|
serverName: "",
|
||||||
|
secretKey: "",
|
||||||
|
bindAddr: "",
|
||||||
|
bindPort: null
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表单内容
|
||||||
|
*/
|
||||||
|
const editForm = ref<Proxy>(defaultForm.value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 代理类型
|
||||||
|
*/
|
||||||
|
const proxyTypes = ref(["http", "https", "tcp", "udp", "stcp"]);
|
||||||
|
|
||||||
|
const stcpModels = ref([
|
||||||
|
{
|
||||||
|
label: "访问者",
|
||||||
|
value: "visitor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "被访问者",
|
||||||
|
value: "visited"
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单校验
|
* 表单校验
|
||||||
*/
|
*/
|
||||||
const editFormRules = reactive<FormRules>({
|
const editFormRules = reactive<FormRules>({
|
||||||
name: [
|
name: [
|
||||||
{required: true, message: "请输入名称", trigger: "blur"},
|
{ required: true, message: "请输入名称", trigger: "blur" }
|
||||||
// {
|
// {
|
||||||
// pattern: /^[a-zA-Z]+$/,
|
// pattern: /^[a-zA-Z]+$/,
|
||||||
// message: "名称只能是英文",
|
// message: "名称只能是英文",
|
||||||
@ -87,7 +93,23 @@ const editFormRules = reactive<FormRules>({
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
localPort: [{ required: true, message: "请输入本地端口", trigger: "blur" }],
|
localPort: [{ required: true, message: "请输入本地端口", trigger: "blur" }],
|
||||||
remotePort: [{required: true, message: "请输入远程端口", trigger: "blur"}]
|
remotePort: [{ required: true, message: "请输入远程端口", trigger: "blur" }],
|
||||||
|
stcpModel: [{ required: true, message: "请选择stcp模式", trigger: "blur" }],
|
||||||
|
secretKey: [
|
||||||
|
{ required: true, message: "请输入stcp共享密钥", trigger: "blur" }
|
||||||
|
],
|
||||||
|
serverName: [
|
||||||
|
{ required: true, message: "请输入stcp被访问者代理名称", trigger: "blur" }
|
||||||
|
],
|
||||||
|
bindAddr: [
|
||||||
|
{ required: true, message: "请输入绑定的地址", trigger: "blur" },
|
||||||
|
{
|
||||||
|
pattern: /^[\w-]+(\.[\w-]+)+$/,
|
||||||
|
message: "请输入正确的内网地址",
|
||||||
|
trigger: "blur"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
bindPort: [{ required: true, message: "请输入绑定的端口", trigger: "blur" }]
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -147,15 +169,7 @@ const handleDeleteProxy = (proxy: Proxy) => {
|
|||||||
* 重置表单
|
* 重置表单
|
||||||
*/
|
*/
|
||||||
const handleResetForm = () => {
|
const handleResetForm = () => {
|
||||||
editForm.value = {
|
editForm.value = defaultForm.value;
|
||||||
_id: "",
|
|
||||||
name: "",
|
|
||||||
type: "http",
|
|
||||||
localIp: "",
|
|
||||||
localPort: 0,
|
|
||||||
remotePort: 0,
|
|
||||||
customDomains: [""]
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -186,8 +200,8 @@ const handleInitHook = () => {
|
|||||||
ipcRenderer.on("local.getLocalPorts.hook", (event, args) => {
|
ipcRenderer.on("local.getLocalPorts.hook", (event, args) => {
|
||||||
loading.value.localPorts--;
|
loading.value.localPorts--;
|
||||||
localPorts.value = args.data;
|
localPorts.value = args.data;
|
||||||
console.log('本地端口', localPorts.value)
|
console.log("本地端口", localPorts.value);
|
||||||
})
|
});
|
||||||
// ipcRenderer.on("Proxy.updateProxy.hook", (event, args) => {
|
// ipcRenderer.on("Proxy.updateProxy.hook", (event, args) => {
|
||||||
// loading.value.form--;
|
// loading.value.form--;
|
||||||
// const { err } = args;
|
// const { err } = args;
|
||||||
@ -236,40 +250,38 @@ const handleOpenUpdate = (proxy: Proxy) => {
|
|||||||
|
|
||||||
const handleLoadLocalPorts = () => {
|
const handleLoadLocalPorts = () => {
|
||||||
loading.value.localPorts = 1;
|
loading.value.localPorts = 1;
|
||||||
ipcRenderer.send("local.getLocalPorts")
|
ipcRenderer.send("local.getLocalPorts");
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
const handleSelectLocalPort = useDebounceFn((port: number) => {
|
const handleSelectLocalPort = useDebounceFn((port: number) => {
|
||||||
editForm.value.localPort = port;
|
editForm.value.localPort = port;
|
||||||
handleCloseLocalPortDialog();
|
handleCloseLocalPortDialog();
|
||||||
})
|
});
|
||||||
|
|
||||||
const handleCloseLocalPortDialog = () => {
|
const handleCloseLocalPortDialog = () => {
|
||||||
listPortsVisible.value = false;
|
listPortsVisible.value = false;
|
||||||
}
|
};
|
||||||
|
|
||||||
const handleOpenLocalPortDialog = () => {
|
const handleOpenLocalPortDialog = () => {
|
||||||
listPortsVisible.value = true;
|
listPortsVisible.value = true;
|
||||||
handleLoadLocalPorts();
|
handleLoadLocalPorts();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
interface RestaurantItem {
|
interface RestaurantItem {
|
||||||
value: string
|
value: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const commonIp = ref<Array<RestaurantItem>>([])
|
const commonIp = ref<Array<RestaurantItem>>([]);
|
||||||
|
|
||||||
const handleIpFetchSuggestions = (queryString: string, cb: any) => {
|
const handleIpFetchSuggestions = (queryString: string, cb: any) => {
|
||||||
const results = queryString
|
const results = queryString
|
||||||
? commonIp.value.filter(f => {
|
? commonIp.value.filter(f => {
|
||||||
return f.value.toLowerCase().indexOf(queryString.toLowerCase()) !== -1
|
return f.value.toLowerCase().indexOf(queryString.toLowerCase()) !== -1;
|
||||||
})
|
})
|
||||||
: commonIp.value
|
: commonIp.value;
|
||||||
console.log(results, 'results')
|
console.log(results, "results");
|
||||||
cb(commonIp.value)
|
cb(commonIp.value);
|
||||||
}
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
handleInitHook();
|
handleInitHook();
|
||||||
@ -295,7 +307,7 @@ onUnmounted(() => {
|
|||||||
<IconifyIconOffline icon="add" />
|
<IconifyIconOffline icon="add" />
|
||||||
</div>
|
</div>
|
||||||
</breadcrumb>
|
</breadcrumb>
|
||||||
<div class="app-container-breadcrumb" v-loading="loading.list > 0">
|
<div class="app-container-breadcrumb pr-2" 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
|
||||||
@ -330,7 +342,8 @@ onUnmounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<el-dropdown size="small">
|
<el-dropdown size="small">
|
||||||
<a href="javascript:void(0)"
|
<a
|
||||||
|
href="javascript:void(0)"
|
||||||
class="text-xl text-[#ADADAD] hover:text-[#5A3DAA]"
|
class="text-xl text-[#ADADAD] hover:text-[#5A3DAA]"
|
||||||
>
|
>
|
||||||
<IconifyIconOffline icon="more-vert" />
|
<IconifyIconOffline icon="more-vert" />
|
||||||
@ -386,7 +399,7 @@ onUnmounted(() => {
|
|||||||
<el-dialog
|
<el-dialog
|
||||||
v-model="edit.visible"
|
v-model="edit.visible"
|
||||||
:title="edit.title"
|
:title="edit.title"
|
||||||
width="500"
|
class="sm:w-[500px] md:w-[600px] lg:w-[800px]"
|
||||||
top="5%"
|
top="5%"
|
||||||
>
|
>
|
||||||
<el-form
|
<el-form
|
||||||
@ -400,19 +413,77 @@ onUnmounted(() => {
|
|||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="代理类型:" prop="type">
|
<el-form-item label="代理类型:" prop="type">
|
||||||
<el-radio-group v-model="editForm.type">
|
<el-radio-group v-model="editForm.type">
|
||||||
<el-radio label="http" model-value="http"/>
|
<el-radio-button
|
||||||
<el-radio label="https" model-value="https"/>
|
v-for="p in proxyTypes"
|
||||||
<el-radio label="tcp" model-value="tcp"/>
|
:key="p"
|
||||||
<el-radio label="udp" model-value="udp"/>
|
:label="p"
|
||||||
<!-- <el-radio label="stcp" model-value="stcp" />-->
|
:value="p"
|
||||||
|
/>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<template v-if="editForm.type === 'stcp'">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="stcp模式:" prop="stcpModel">
|
||||||
|
<el-radio-group v-model="editForm.stcpModel">
|
||||||
|
<el-radio
|
||||||
|
v-for="p in stcpModels"
|
||||||
|
:key="p.value"
|
||||||
|
:label="p.label"
|
||||||
|
:value="p.value"
|
||||||
|
/>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="代理名称:" prop="name">
|
<el-form-item label="共享密钥:" prop="secretKey">
|
||||||
<el-input v-model="editForm.name" placeholder="代理名称" clearable/>
|
<template #label>
|
||||||
|
<div class="inline-block">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="mr-1">
|
||||||
|
<el-popover placement="top" trigger="hover" width="300">
|
||||||
|
<template #default>
|
||||||
|
对应参数:<span class="font-black text-[#5A3DAA]"
|
||||||
|
>secretKey</span
|
||||||
|
>
|
||||||
|
只有访问者与被访问者共享密钥一致的用户才能访问该服务
|
||||||
|
</template>
|
||||||
|
<template #reference>
|
||||||
|
<IconifyIconOffline
|
||||||
|
class="text-base"
|
||||||
|
color="#5A3DAA"
|
||||||
|
icon="info"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-popover>
|
||||||
|
</div>
|
||||||
|
共享密钥:
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<el-input
|
||||||
|
type="password"
|
||||||
|
v-model="editForm.secretKey"
|
||||||
|
placeholder="密钥"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
</template>
|
||||||
|
<el-col :span="editForm.stcpModel === 'visitor' ? 12 : 24">
|
||||||
|
<el-form-item label="代理名称:" prop="name">
|
||||||
|
<el-input
|
||||||
|
v-model="editForm.name"
|
||||||
|
placeholder="代理名称"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<template
|
||||||
|
v-if="
|
||||||
|
editForm.type !== 'stcp' ||
|
||||||
|
(editForm.type === 'stcp' && editForm.stcpModel === 'visited')
|
||||||
|
"
|
||||||
|
>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="内网地址:" prop="localIp">
|
<el-form-item label="内网地址:" prop="localIp">
|
||||||
<!-- <el-autocomplete-->
|
<!-- <el-autocomplete-->
|
||||||
@ -421,7 +492,11 @@ onUnmounted(() => {
|
|||||||
<!-- clearable-->
|
<!-- clearable-->
|
||||||
<!-- placeholder="127.0.0.1"-->
|
<!-- placeholder="127.0.0.1"-->
|
||||||
<!-- />-->
|
<!-- />-->
|
||||||
<el-input v-model="editForm.localIp" placeholder="127.0.0.1" clearable/>
|
<el-input
|
||||||
|
v-model="editForm.localIp"
|
||||||
|
placeholder="127.0.0.1"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
@ -434,12 +509,21 @@ onUnmounted(() => {
|
|||||||
v-model="editForm.localPort"
|
v-model="editForm.localPort"
|
||||||
controls-position="right"
|
controls-position="right"
|
||||||
/>
|
/>
|
||||||
<el-button class="ml-[10px]" plain type="primary" @click="handleOpenLocalPortDialog">
|
<el-button
|
||||||
<IconifyIconOffline class="cursor-pointer mr-2" icon="bring-your-own-ip-rounded"/>
|
class="ml-[10px]"
|
||||||
|
plain
|
||||||
|
type="primary"
|
||||||
|
@click="handleOpenLocalPortDialog"
|
||||||
|
>
|
||||||
|
<IconifyIconOffline
|
||||||
|
class="cursor-pointer mr-2"
|
||||||
|
icon="bring-your-own-ip-rounded"
|
||||||
|
/>
|
||||||
本地端口
|
本地端口
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
</template>
|
||||||
<template v-if="editForm.type === 'tcp' || editForm.type === 'udp'">
|
<template v-if="editForm.type === 'tcp' || editForm.type === 'udp'">
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="外网端口:" prop="remotePort">
|
<el-form-item label="外网端口:" prop="remotePort">
|
||||||
@ -480,15 +564,18 @@ onUnmounted(() => {
|
|||||||
<div class="inline-block">
|
<div class="inline-block">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="mr-1">
|
<div class="mr-1">
|
||||||
<el-popover
|
<el-popover placement="top" trigger="hover">
|
||||||
placement="top"
|
|
||||||
trigger="hover"
|
|
||||||
>
|
|
||||||
<template #default>
|
<template #default>
|
||||||
对应参数:<span class="font-black text-[#5A3DAA]">customDomains</span>
|
对应参数:<span class="font-black text-[#5A3DAA]"
|
||||||
|
>customDomains</span
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<IconifyIconOffline class="text-base" color="#5A3DAA" icon="info"/>
|
<IconifyIconOffline
|
||||||
|
class="text-base"
|
||||||
|
color="#5A3DAA"
|
||||||
|
icon="info"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
@ -537,16 +624,117 @@ onUnmounted(() => {
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</template>
|
</template>
|
||||||
|
<template
|
||||||
|
v-if="editForm.type === 'stcp' && editForm.stcpModel === 'visitor'"
|
||||||
|
>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="被访问者代理名称:" prop="serverName">
|
||||||
|
<el-input
|
||||||
|
type="text"
|
||||||
|
v-model="editForm.serverName"
|
||||||
|
placeholder="stcp被访问者代理名称"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="绑定地址:" prop="bindAddr">
|
||||||
|
<template #label>
|
||||||
|
<div class="inline-block">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="mr-1">
|
||||||
|
<el-popover placement="top" trigger="hover" width="300">
|
||||||
|
<template #default>
|
||||||
|
对应参数:<span class="font-black text-[#5A3DAA]"
|
||||||
|
>bindAddr</span
|
||||||
|
>
|
||||||
|
要将被访问者的服务绑定到本地哪个<span
|
||||||
|
class="font-black text-[#5A3DAA]"
|
||||||
|
>IP</span
|
||||||
|
>
|
||||||
|
<br />
|
||||||
|
仅本机访问:<span class="font-black text-[#5A3DAA]"
|
||||||
|
>127.0.0.1</span
|
||||||
|
>
|
||||||
|
<br />
|
||||||
|
支持局域网其他设备访问:<span
|
||||||
|
class="font-black text-[#5A3DAA]"
|
||||||
|
>0.0.0.0</span
|
||||||
|
>
|
||||||
|
<br />
|
||||||
|
</template>
|
||||||
|
<template #reference>
|
||||||
|
<IconifyIconOffline
|
||||||
|
class="text-base"
|
||||||
|
color="#5A3DAA"
|
||||||
|
icon="info"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-popover>
|
||||||
|
</div>
|
||||||
|
绑定地址:
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<el-input
|
||||||
|
type="text"
|
||||||
|
v-model="editForm.bindAddr"
|
||||||
|
placeholder="127.0.0.1"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="绑定端口:" prop="bindPort">
|
||||||
|
<template #label>
|
||||||
|
<div class="inline-block">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="mr-1">
|
||||||
|
<el-popover placement="top" trigger="hover" width="300">
|
||||||
|
<template #default>
|
||||||
|
对应参数:<span class="font-black text-[#5A3DAA]"
|
||||||
|
>bindAddr</span
|
||||||
|
>
|
||||||
|
要将被访问者的服务绑定到本地哪个<span
|
||||||
|
class="font-black text-[#5A3DAA]"
|
||||||
|
>端口</span
|
||||||
|
>
|
||||||
|
<br />
|
||||||
|
请自行确保端口未被占用
|
||||||
|
</template>
|
||||||
|
<template #reference>
|
||||||
|
<IconifyIconOffline
|
||||||
|
class="text-base"
|
||||||
|
color="#5A3DAA"
|
||||||
|
icon="info"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-popover>
|
||||||
|
</div>
|
||||||
|
绑定端口:
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<el-input-number
|
||||||
|
v-model="editForm.bindPort"
|
||||||
|
placeholder="8080"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</template>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<div class="w-full flex justify-end">
|
<div class="w-full flex justify-end">
|
||||||
<el-button @click="edit.visible = false">
|
<el-button @click="edit.visible = false">
|
||||||
<iconify-icon-offline class="cursor-pointer mr-2" icon="cancel-presentation"/>
|
<iconify-icon-offline
|
||||||
|
class="cursor-pointer mr-2"
|
||||||
|
icon="cancel-presentation"
|
||||||
|
/>
|
||||||
关 闭
|
关 闭
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button plain type="primary" @click="handleSubmit"
|
<el-button plain type="primary" @click="handleSubmit">
|
||||||
>
|
<IconifyIconOffline
|
||||||
<IconifyIconOffline class="cursor-pointer mr-2" icon="save-rounded"/>
|
class="cursor-pointer mr-2"
|
||||||
|
icon="save-rounded"
|
||||||
|
/>
|
||||||
保 存
|
保 存
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
@ -556,24 +744,30 @@ onUnmounted(() => {
|
|||||||
</el-form>
|
</el-form>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<el-dialog v-model="listPortsVisible"
|
<el-dialog v-model="listPortsVisible" title="本地端口" width="600" top="5%">
|
||||||
title="本地端口"
|
<el-table
|
||||||
width="600"
|
:data="localPorts"
|
||||||
top="5%">
|
stripe
|
||||||
<el-table :data="localPorts" stripe
|
|
||||||
v-loading="loading.localPorts"
|
v-loading="loading.localPorts"
|
||||||
border height="400">
|
border
|
||||||
|
height="400"
|
||||||
|
>
|
||||||
<el-table-column label="协议" :width="60" prop="protocol" />
|
<el-table-column label="协议" :width="60" prop="protocol" />
|
||||||
<el-table-column label="IP" prop="ip" />
|
<el-table-column label="IP" prop="ip" />
|
||||||
<el-table-column label="端口" :width="80" prop="port" />
|
<el-table-column label="端口" :width="80" prop="port" />
|
||||||
<el-table-column label="操作" :width="80">
|
<el-table-column label="操作" :width="80">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button type="text" @click="handleSelectLocalPort(scope.row.port)">
|
<el-button
|
||||||
<IconifyIconOffline class="cursor-pointer mr-2" icon="gesture-select"/>
|
type="text"
|
||||||
|
@click="handleSelectLocalPort(scope.row.port)"
|
||||||
|
>
|
||||||
|
<IconifyIconOffline
|
||||||
|
class="cursor-pointer mr-2"
|
||||||
|
icon="gesture-select"
|
||||||
|
/>
|
||||||
选择
|
选择
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
80
types/global.d.ts
vendored
Normal file
80
types/global.d.ts
vendored
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
declare module 'element-plus/dist/locale/zh-cn.mjs' {
|
||||||
|
const zhLocale: any;
|
||||||
|
export default zhLocale;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module 'element-plus/dist/locale/en.mjs' {
|
||||||
|
const enLocale: any;
|
||||||
|
export default enLocale;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 代理配置类型
|
||||||
|
*/
|
||||||
|
type Proxy = {
|
||||||
|
_id: string;
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
localIp: string;
|
||||||
|
localPort: number;
|
||||||
|
remotePort: number;
|
||||||
|
customDomains: string[];
|
||||||
|
stcpModel: string;
|
||||||
|
serverName: string;
|
||||||
|
secretKey: string;
|
||||||
|
bindAddr: string;
|
||||||
|
bindPort: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 本地端口类型
|
||||||
|
*/
|
||||||
|
type LocalPort = {
|
||||||
|
protocol: string;
|
||||||
|
ip: string;
|
||||||
|
port: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 版本类型
|
||||||
|
*/
|
||||||
|
type FrpVersion = {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
published_at: string;
|
||||||
|
download_completed: boolean;
|
||||||
|
absPath: string;
|
||||||
|
assets: Asset[]
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全局配置
|
||||||
|
*/
|
||||||
|
type FrpConfig = {
|
||||||
|
currentVersion: string;
|
||||||
|
serverAddr: string;
|
||||||
|
serverPort: number;
|
||||||
|
authMethod: string;
|
||||||
|
authToken: string;
|
||||||
|
logLevel: string;
|
||||||
|
logMaxDays: number;
|
||||||
|
tlsConfigEnable: boolean;
|
||||||
|
tlsConfigCertFile: string;
|
||||||
|
tlsConfigKeyFile: string;
|
||||||
|
tlsConfigTrustedCaFile: string;
|
||||||
|
tlsConfigServerName: string;
|
||||||
|
proxyConfigEnable: boolean;
|
||||||
|
proxyConfigProxyUrl: string;
|
||||||
|
systemSelfStart: boolean;
|
||||||
|
systemStartupConnect: boolean;
|
||||||
|
user: string;
|
||||||
|
metaToken: string;
|
||||||
|
transportHeartbeatInterval: number;
|
||||||
|
transportHeartbeatTimeout: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
export {};
|
Loading…
Reference in New Issue
Block a user