🚧 类型统一
This commit is contained in:
parent
989f9b8a37
commit
3961475421
@ -74,7 +74,7 @@ const unZip = (zipPath: string, targetPath: string) => {
|
||||
|
||||
export const initGitHubApi = () => {
|
||||
// 版本
|
||||
let versions = [];
|
||||
let versions: FrpVersion[] = [];
|
||||
|
||||
const getVersion = versionId => {
|
||||
return versions.find(f => f.id === versionId);
|
||||
|
@ -1,47 +1,24 @@
|
||||
import Datastore from "nedb";
|
||||
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({
|
||||
autoload: true,
|
||||
filename: path.join(app.getPath("userData"), "config.db")
|
||||
autoload: true,
|
||||
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 = (
|
||||
document: Config,
|
||||
cb?: (err: Error | null, numberOfUpdated: number, upsert: boolean) => void
|
||||
document: FrpConfig,
|
||||
cb?: (err: Error | null, numberOfUpdated: number, upsert: boolean) => void
|
||||
) => {
|
||||
document["_id"] = "1";
|
||||
log.debug(`保存日志 ${JSON.stringify(document)}`)
|
||||
configDB.update({_id: "1"}, document, {upsert: true}, cb);
|
||||
document["_id"] = "1";
|
||||
log.debug(`保存日志 ${JSON.stringify(document)}`);
|
||||
configDB.update({ _id: "1" }, document, { upsert: true }, cb);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -49,7 +26,7 @@ export const saveConfig = (
|
||||
* @param cb
|
||||
*/
|
||||
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 path from "path";
|
||||
import { app } from "electron";
|
||||
const log = require('electron-log');
|
||||
|
||||
const log = require("electron-log");
|
||||
|
||||
const proxyDB = new Datastore({
|
||||
autoload: true,
|
||||
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
|
||||
|
@ -9,12 +9,12 @@ const versionDB = new Datastore({
|
||||
});
|
||||
|
||||
/**
|
||||
* 新增代理
|
||||
* @param proxy
|
||||
* 新增版本
|
||||
* @param version
|
||||
* @param cb
|
||||
*/
|
||||
export const insertVersion = (
|
||||
version: any,
|
||||
version: FrpVersion,
|
||||
cb?: (err: Error | null, document: any) => void
|
||||
) => {
|
||||
log.debug(`新增版本:${JSON.stringify(version)}`);
|
||||
@ -26,14 +26,14 @@ export const insertVersion = (
|
||||
* @param cb
|
||||
*/
|
||||
export const listVersion = (
|
||||
callback: (err: Error | null, documents: any[]) => void
|
||||
callback: (err: Error | null, documents: FrpVersion[]) => void
|
||||
) => {
|
||||
versionDB.find({}, callback);
|
||||
};
|
||||
|
||||
export const getVersionById = (
|
||||
id: string,
|
||||
callback: (err: Error | null, document: any) => void
|
||||
callback: (err: Error | null, document: FrpVersion) => void
|
||||
) => {
|
||||
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;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -11,20 +11,7 @@ defineComponent({
|
||||
name: "Download"
|
||||
});
|
||||
|
||||
type Asset = {
|
||||
name: string
|
||||
}
|
||||
|
||||
type Version = {
|
||||
id: string;
|
||||
name: string;
|
||||
published_at: string;
|
||||
download_completed: boolean;
|
||||
absPath: string;
|
||||
assets: Asset[]
|
||||
};
|
||||
|
||||
const versions = ref<Array<Version>>([]);
|
||||
const versions = ref<Array<FrpVersion>>([]);
|
||||
const loading = ref(1);
|
||||
const downloadPercentage = ref(0);
|
||||
const downloading = ref<Map<string, number>>(new Map<string, number>());
|
||||
@ -40,7 +27,7 @@ const handleLoadVersions = () => {
|
||||
* 下载
|
||||
* @param version
|
||||
*/
|
||||
const handleDownload = useDebounceFn((version: Version) => {
|
||||
const handleDownload = useDebounceFn((version: FrpVersion) => {
|
||||
ipcRenderer.send("github.download", version.id);
|
||||
downloading.value.set(version.id, 0);
|
||||
}, 300);
|
||||
@ -49,7 +36,7 @@ const handleDownload = useDebounceFn((version: Version) => {
|
||||
* 删除下载
|
||||
* @param version
|
||||
*/
|
||||
const handleDeleteVersion = useDebounceFn((version: Version) => {
|
||||
const handleDeleteVersion = useDebounceFn((version: FrpVersion) => {
|
||||
ipcRenderer.send("github.deleteVersion", {
|
||||
id: version.id,
|
||||
absPath: version.absPath
|
||||
@ -61,8 +48,8 @@ const handleInitDownloadHook = () => {
|
||||
loading.value--;
|
||||
versions.value = args.map(m => {
|
||||
m.published_at = moment(m.published_at).format("YYYY-MM-DD HH:mm:ss")
|
||||
return m as Version;
|
||||
}) as Array<Version>;
|
||||
return m as FrpVersion;
|
||||
}) as Array<FrpVersion>;
|
||||
console.log(versions, 'versions')
|
||||
});
|
||||
// 进度监听
|
||||
@ -75,7 +62,7 @@ const handleInitDownloadHook = () => {
|
||||
});
|
||||
ipcRenderer.on("Download.frpVersionDownloadOnCompleted", (event, args) => {
|
||||
downloading.value.delete(args);
|
||||
const version: Version | undefined = versions.value.find(
|
||||
const version: FrpVersion | undefined = versions.value.find(
|
||||
f => f.id === args
|
||||
);
|
||||
if (version) {
|
||||
|
@ -1,33 +1,16 @@
|
||||
<script lang="ts" setup>
|
||||
import {defineComponent, onMounted, onUnmounted, reactive, ref} from "vue";
|
||||
import { defineComponent, onMounted, onUnmounted, reactive, ref } from "vue";
|
||||
import Breadcrumb from "@/layout/compoenets/Breadcrumb.vue";
|
||||
import {ElMessage, FormInstance, FormRules} from "element-plus";
|
||||
import {ipcRenderer} from "electron";
|
||||
import {clone} from "@/utils/clone";
|
||||
import {useDebounceFn} from "@vueuse/core";
|
||||
import { ElMessage, FormInstance, FormRules } from "element-plus";
|
||||
import { ipcRenderer } from "electron";
|
||||
import { clone } from "@/utils/clone";
|
||||
import { useDebounceFn } from "@vueuse/core";
|
||||
import IconifyIconOffline from "@/components/IconifyIcon/src/iconifyIconOffline";
|
||||
|
||||
|
||||
defineComponent({
|
||||
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,42 +35,81 @@ const edit = ref({
|
||||
visible: false
|
||||
});
|
||||
|
||||
/**
|
||||
* 表单内容
|
||||
*/
|
||||
const editForm = ref<Proxy>({
|
||||
const defaultForm = ref<Proxy>({
|
||||
_id: "",
|
||||
name: "",
|
||||
type: "http",
|
||||
localIp: "",
|
||||
localPort: 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>({
|
||||
name: [
|
||||
{required: true, message: "请输入名称", trigger: "blur"},
|
||||
{ required: true, message: "请输入名称", trigger: "blur" }
|
||||
// {
|
||||
// pattern: /^[a-zA-Z]+$/,
|
||||
// message: "名称只能是英文",
|
||||
// trigger: "blur"
|
||||
// }
|
||||
],
|
||||
type: [{required: true, message: "请选择类型", trigger: "blur"}],
|
||||
type: [{ required: true, message: "请选择类型", trigger: "blur" }],
|
||||
localIp: [
|
||||
{required: true, message: "请输入内网地址", trigger: "blur"},
|
||||
{ required: true, message: "请输入内网地址", trigger: "blur" },
|
||||
{
|
||||
pattern: /^[\w-]+(\.[\w-]+)+$/,
|
||||
message: "请输入正确的内网地址",
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
localPort: [{required: true, message: "请输入本地端口", trigger: "blur"}],
|
||||
remotePort: [{required: true, message: "请输入远程端口", trigger: "blur"}]
|
||||
localPort: [{ 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 = () => {
|
||||
editForm.value = {
|
||||
_id: "",
|
||||
name: "",
|
||||
type: "http",
|
||||
localIp: "",
|
||||
localPort: 0,
|
||||
remotePort: 0,
|
||||
customDomains: [""]
|
||||
};
|
||||
editForm.value = defaultForm.value;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -164,7 +178,7 @@ const handleResetForm = () => {
|
||||
const handleInitHook = () => {
|
||||
const InsertOrUpdateHook = (message: string, args: any) => {
|
||||
loading.value.form--;
|
||||
const {err} = args;
|
||||
const { err } = args;
|
||||
if (!err) {
|
||||
ElMessage({
|
||||
type: "success",
|
||||
@ -186,8 +200,8 @@ const handleInitHook = () => {
|
||||
ipcRenderer.on("local.getLocalPorts.hook", (event, args) => {
|
||||
loading.value.localPorts--;
|
||||
localPorts.value = args.data;
|
||||
console.log('本地端口', localPorts.value)
|
||||
})
|
||||
console.log("本地端口", localPorts.value);
|
||||
});
|
||||
// ipcRenderer.on("Proxy.updateProxy.hook", (event, args) => {
|
||||
// loading.value.form--;
|
||||
// const { err } = args;
|
||||
@ -203,13 +217,13 @@ const handleInitHook = () => {
|
||||
// });
|
||||
ipcRenderer.on("Proxy.getProxys.hook", (event, args) => {
|
||||
loading.value.list--;
|
||||
const {err, data} = args;
|
||||
const { err, data } = args;
|
||||
if (!err) {
|
||||
proxys.value = data;
|
||||
}
|
||||
});
|
||||
ipcRenderer.on("Proxy.deleteProxyById.hook", (event, args) => {
|
||||
const {err, data} = args;
|
||||
const { err, data } = args;
|
||||
if (!err) {
|
||||
handleLoadProxys();
|
||||
ElMessage({
|
||||
@ -236,40 +250,38 @@ const handleOpenUpdate = (proxy: Proxy) => {
|
||||
|
||||
const handleLoadLocalPorts = () => {
|
||||
loading.value.localPorts = 1;
|
||||
ipcRenderer.send("local.getLocalPorts")
|
||||
}
|
||||
|
||||
ipcRenderer.send("local.getLocalPorts");
|
||||
};
|
||||
|
||||
const handleSelectLocalPort = useDebounceFn((port: number) => {
|
||||
editForm.value.localPort = port;
|
||||
handleCloseLocalPortDialog();
|
||||
})
|
||||
});
|
||||
|
||||
const handleCloseLocalPortDialog = () => {
|
||||
listPortsVisible.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const handleOpenLocalPortDialog = () => {
|
||||
listPortsVisible.value = true;
|
||||
handleLoadLocalPorts();
|
||||
};
|
||||
|
||||
|
||||
interface RestaurantItem {
|
||||
value: string
|
||||
value: string;
|
||||
}
|
||||
|
||||
const commonIp = ref<Array<RestaurantItem>>([])
|
||||
const commonIp = ref<Array<RestaurantItem>>([]);
|
||||
|
||||
const handleIpFetchSuggestions = (queryString: string, cb: any) => {
|
||||
const results = queryString
|
||||
? commonIp.value.filter(f => {
|
||||
return f.value.toLowerCase().indexOf(queryString.toLowerCase()) !== -1
|
||||
? commonIp.value.filter(f => {
|
||||
return f.value.toLowerCase().indexOf(queryString.toLowerCase()) !== -1;
|
||||
})
|
||||
: commonIp.value
|
||||
console.log(results, 'results')
|
||||
cb(commonIp.value)
|
||||
}
|
||||
: commonIp.value;
|
||||
console.log(results, "results");
|
||||
cb(commonIp.value);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
handleInitHook();
|
||||
@ -289,31 +301,31 @@ onUnmounted(() => {
|
||||
<div class="main">
|
||||
<breadcrumb>
|
||||
<div
|
||||
class="cursor-pointer h-[36px] w-[36px] bg-[#5f3bb0] rounded text-white flex justify-center items-center"
|
||||
@click="handleOpenInsert"
|
||||
class="cursor-pointer h-[36px] w-[36px] bg-[#5f3bb0] rounded text-white flex justify-center items-center"
|
||||
@click="handleOpenInsert"
|
||||
>
|
||||
<IconifyIconOffline icon="add"/>
|
||||
<IconifyIconOffline icon="add" />
|
||||
</div>
|
||||
</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">
|
||||
<el-row :gutter="20">
|
||||
<el-col
|
||||
v-for="proxy in proxys"
|
||||
:key="proxy._id"
|
||||
:lg="6"
|
||||
:md="8"
|
||||
:sm="12"
|
||||
:xl="6"
|
||||
:xs="24"
|
||||
class="mb-[20px]"
|
||||
v-for="proxy in proxys"
|
||||
:key="proxy._id"
|
||||
:lg="6"
|
||||
:md="8"
|
||||
:sm="12"
|
||||
:xl="6"
|
||||
:xs="24"
|
||||
class="mb-[20px]"
|
||||
>
|
||||
<div class="bg-white w-full rounded drop-shadow-xl p-4">
|
||||
<div class="w-full flex justify-between">
|
||||
<div class="flex">
|
||||
<div
|
||||
class="w-12 h-12 rounded mr-4 flex justify-center items-center font-bold"
|
||||
:class="proxy.type"
|
||||
class="w-12 h-12 rounded mr-4 flex justify-center items-center font-bold"
|
||||
:class="proxy.type"
|
||||
>
|
||||
<span class="text-white text-sm">{{ proxy.type }}</span>
|
||||
</div>
|
||||
@ -330,24 +342,25 @@ onUnmounted(() => {
|
||||
</div>
|
||||
<div>
|
||||
<el-dropdown size="small">
|
||||
<a href="javascript:void(0)"
|
||||
class="text-xl text-[#ADADAD] hover:text-[#5A3DAA]"
|
||||
<a
|
||||
href="javascript:void(0)"
|
||||
class="text-xl text-[#ADADAD] hover:text-[#5A3DAA]"
|
||||
>
|
||||
<IconifyIconOffline icon="more-vert"/>
|
||||
<IconifyIconOffline icon="more-vert" />
|
||||
</a>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item @click="handleOpenUpdate(proxy)">
|
||||
<IconifyIconOffline
|
||||
icon="edit"
|
||||
class="primary-text text-[14px]"
|
||||
icon="edit"
|
||||
class="primary-text text-[14px]"
|
||||
/>
|
||||
<span class="ml-1">修 改</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click="handleDeleteProxy(proxy)">
|
||||
<IconifyIconOffline
|
||||
icon="delete-rounded"
|
||||
class="text-red-500 text-[14px]"
|
||||
icon="delete-rounded"
|
||||
class="text-red-500 text-[14px]"
|
||||
/>
|
||||
<span class="ml-1">删 除</span>
|
||||
</el-dropdown-item>
|
||||
@ -376,93 +389,164 @@ onUnmounted(() => {
|
||||
</el-row>
|
||||
</template>
|
||||
<div
|
||||
v-else
|
||||
class="w-full h-full bg-white rounded p-2 overflow-hidden drop-shadow-xl flex justify-center items-center"
|
||||
v-else
|
||||
class="w-full h-full bg-white rounded p-2 overflow-hidden drop-shadow-xl flex justify-center items-center"
|
||||
>
|
||||
<el-empty description="暂无代理"/>
|
||||
<el-empty description="暂无代理" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-dialog
|
||||
v-model="edit.visible"
|
||||
:title="edit.title"
|
||||
width="500"
|
||||
top="5%"
|
||||
v-model="edit.visible"
|
||||
:title="edit.title"
|
||||
class="sm:w-[500px] md:w-[600px] lg:w-[800px]"
|
||||
top="5%"
|
||||
>
|
||||
<el-form
|
||||
v-loading="loading.form"
|
||||
label-position="top"
|
||||
:model="editForm"
|
||||
:rules="editFormRules"
|
||||
ref="editFormRef"
|
||||
v-loading="loading.form"
|
||||
label-position="top"
|
||||
:model="editForm"
|
||||
:rules="editFormRules"
|
||||
ref="editFormRef"
|
||||
>
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="代理类型:" prop="type">
|
||||
<el-radio-group v-model="editForm.type">
|
||||
<el-radio label="http" model-value="http"/>
|
||||
<el-radio label="https" model-value="https"/>
|
||||
<el-radio label="tcp" model-value="tcp"/>
|
||||
<el-radio label="udp" model-value="udp"/>
|
||||
<!-- <el-radio label="stcp" model-value="stcp" />-->
|
||||
<el-radio-button
|
||||
v-for="p in proxyTypes"
|
||||
:key="p"
|
||||
:label="p"
|
||||
:value="p"
|
||||
/>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<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-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="共享密钥:" prop="secretKey">
|
||||
<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-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-input
|
||||
v-model="editForm.name"
|
||||
placeholder="代理名称"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="内网地址:" prop="localIp">
|
||||
<!-- <el-autocomplete-->
|
||||
<!-- v-model="editForm.localIp"-->
|
||||
<!-- :fetch-suggestions="handleIpFetchSuggestions"-->
|
||||
<!-- clearable-->
|
||||
<!-- placeholder="127.0.0.1"-->
|
||||
<!-- />-->
|
||||
<el-input v-model="editForm.localIp" placeholder="127.0.0.1" clearable/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="内网端口:" prop="localPort">
|
||||
<el-input-number
|
||||
<template
|
||||
v-if="
|
||||
editForm.type !== 'stcp' ||
|
||||
(editForm.type === 'stcp' && editForm.stcpModel === 'visited')
|
||||
"
|
||||
>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="内网地址:" prop="localIp">
|
||||
<!-- <el-autocomplete-->
|
||||
<!-- v-model="editForm.localIp"-->
|
||||
<!-- :fetch-suggestions="handleIpFetchSuggestions"-->
|
||||
<!-- clearable-->
|
||||
<!-- placeholder="127.0.0.1"-->
|
||||
<!-- />-->
|
||||
<el-input
|
||||
v-model="editForm.localIp"
|
||||
placeholder="127.0.0.1"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="内网端口:" prop="localPort">
|
||||
<el-input-number
|
||||
placeholder="8080"
|
||||
class="local-port-input"
|
||||
:min="0"
|
||||
:max="65535"
|
||||
v-model="editForm.localPort"
|
||||
controls-position="right"
|
||||
/>
|
||||
<el-button class="ml-[10px]" plain type="primary" @click="handleOpenLocalPortDialog">
|
||||
<IconifyIconOffline class="cursor-pointer mr-2" icon="bring-your-own-ip-rounded"/>
|
||||
本地端口
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
/>
|
||||
<el-button
|
||||
class="ml-[10px]"
|
||||
plain
|
||||
type="primary"
|
||||
@click="handleOpenLocalPortDialog"
|
||||
>
|
||||
<IconifyIconOffline
|
||||
class="cursor-pointer mr-2"
|
||||
icon="bring-your-own-ip-rounded"
|
||||
/>
|
||||
本地端口
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</template>
|
||||
<template v-if="editForm.type === 'tcp' || editForm.type === 'udp'">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="外网端口:" prop="remotePort">
|
||||
<el-input-number
|
||||
:min="0"
|
||||
:max="65535"
|
||||
placeholder="8080"
|
||||
v-model="editForm.remotePort"
|
||||
controls-position="right"
|
||||
:min="0"
|
||||
:max="65535"
|
||||
placeholder="8080"
|
||||
v-model="editForm.remotePort"
|
||||
controls-position="right"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</template>
|
||||
<template
|
||||
v-if="editForm.type === 'http' || editForm.type === 'https'"
|
||||
v-if="editForm.type === 'http' || editForm.type === 'https'"
|
||||
>
|
||||
<el-col :span="24">
|
||||
<el-form-item
|
||||
v-for="(d, di) in editForm.customDomains"
|
||||
:key="'domain' + di"
|
||||
:label="di === 0 ? '自定义域名:' : ''"
|
||||
:prop="`customDomains.${di}`"
|
||||
:rules="[
|
||||
v-for="(d, di) in editForm.customDomains"
|
||||
:key="'domain' + di"
|
||||
:label="di === 0 ? '自定义域名:' : ''"
|
||||
:prop="`customDomains.${di}`"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: `自定义域名不能为空`,
|
||||
@ -480,73 +564,177 @@ onUnmounted(() => {
|
||||
<div class="inline-block">
|
||||
<div class="flex items-center">
|
||||
<div class="mr-1">
|
||||
<el-popover
|
||||
placement="top"
|
||||
trigger="hover"
|
||||
>
|
||||
<el-popover placement="top" trigger="hover">
|
||||
<template #default>
|
||||
对应参数:<span class="font-black text-[#5A3DAA]">customDomains</span>
|
||||
对应参数:<span class="font-black text-[#5A3DAA]"
|
||||
>customDomains</span
|
||||
>
|
||||
</template>
|
||||
<template #reference>
|
||||
<IconifyIconOffline class="text-base" color="#5A3DAA" icon="info"/>
|
||||
<IconifyIconOffline
|
||||
class="text-base"
|
||||
color="#5A3DAA"
|
||||
icon="info"
|
||||
/>
|
||||
</template>
|
||||
</el-popover>
|
||||
</div>
|
||||
自定义域名:
|
||||
</div>
|
||||
</div>
|
||||
<!-- <el-popover-->
|
||||
<!-- placement="top"-->
|
||||
<!-- trigger="hover"-->
|
||||
<!-- >-->
|
||||
<!-- <template #default>-->
|
||||
<!-- 对应参数:<span class="font-black text-[#5A3DAA]">customDomains</span>-->
|
||||
<!-- </template>-->
|
||||
<!-- <template #reference>-->
|
||||
<!-- <IconifyIconOffline class="text-base" color="#5A3DAA" icon="info"/>-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-popover>-->
|
||||
<!-- <div class="flex items-center inin">-->
|
||||
<!-- <div class="h-full flex items-center mr-1">-->
|
||||
<!-- -->
|
||||
<!-- </div>-->
|
||||
<!-- <div>自定义域名:</div>-->
|
||||
<!-- </div>-->
|
||||
<!-- <el-popover-->
|
||||
<!-- placement="top"-->
|
||||
<!-- trigger="hover"-->
|
||||
<!-- >-->
|
||||
<!-- <template #default>-->
|
||||
<!-- 对应参数:<span class="font-black text-[#5A3DAA]">customDomains</span>-->
|
||||
<!-- </template>-->
|
||||
<!-- <template #reference>-->
|
||||
<!-- <IconifyIconOffline class="text-base" color="#5A3DAA" icon="info"/>-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-popover>-->
|
||||
<!-- <div class="flex items-center inin">-->
|
||||
<!-- <div class="h-full flex items-center mr-1">-->
|
||||
<!-- -->
|
||||
<!-- </div>-->
|
||||
<!-- <div>自定义域名:</div>-->
|
||||
<!-- </div>-->
|
||||
</template>
|
||||
<el-input
|
||||
class="domain-input"
|
||||
placeholder="github.com"
|
||||
v-model="editForm.customDomains[di]"
|
||||
class="domain-input"
|
||||
placeholder="github.com"
|
||||
v-model="editForm.customDomains[di]"
|
||||
/>
|
||||
<el-button
|
||||
class="ml-[10px]"
|
||||
type="primary"
|
||||
plain
|
||||
@click="handleAddDomain"
|
||||
class="ml-[10px]"
|
||||
type="primary"
|
||||
plain
|
||||
@click="handleAddDomain"
|
||||
>
|
||||
<IconifyIconOffline icon="add"/>
|
||||
<IconifyIconOffline icon="add" />
|
||||
</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
@click="handleDeleteDomain(di)"
|
||||
:disabled="editForm.customDomains.length === 1"
|
||||
type="danger"
|
||||
plain
|
||||
@click="handleDeleteDomain(di)"
|
||||
:disabled="editForm.customDomains.length === 1"
|
||||
>
|
||||
<IconifyIconOffline icon="delete-rounded"/>
|
||||
<IconifyIconOffline icon="delete-rounded" />
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</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-form-item>
|
||||
<div class="w-full flex justify-end">
|
||||
<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 plain type="primary" @click="handleSubmit"
|
||||
>
|
||||
<IconifyIconOffline class="cursor-pointer mr-2" icon="save-rounded"/>
|
||||
<el-button plain type="primary" @click="handleSubmit">
|
||||
<IconifyIconOffline
|
||||
class="cursor-pointer mr-2"
|
||||
icon="save-rounded"
|
||||
/>
|
||||
保 存
|
||||
</el-button>
|
||||
</div>
|
||||
@ -556,24 +744,30 @@ onUnmounted(() => {
|
||||
</el-form>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="listPortsVisible"
|
||||
title="本地端口"
|
||||
width="600"
|
||||
top="5%">
|
||||
<el-table :data="localPorts" stripe
|
||||
v-loading="loading.localPorts"
|
||||
border height="400">
|
||||
<el-table-column label="协议" :width="60" prop="protocol"/>
|
||||
<el-table-column label="IP" prop="ip"/>
|
||||
<el-table-column label="端口" :width="80" prop="port"/>
|
||||
<el-dialog v-model="listPortsVisible" title="本地端口" width="600" top="5%">
|
||||
<el-table
|
||||
:data="localPorts"
|
||||
stripe
|
||||
v-loading="loading.localPorts"
|
||||
border
|
||||
height="400"
|
||||
>
|
||||
<el-table-column label="协议" :width="60" prop="protocol" />
|
||||
<el-table-column label="IP" prop="ip" />
|
||||
<el-table-column label="端口" :width="80" prop="port" />
|
||||
<el-table-column label="操作" :width="80">
|
||||
<template #default="scope">
|
||||
<el-button type="text" @click="handleSelectLocalPort(scope.row.port)">
|
||||
<IconifyIconOffline class="cursor-pointer mr-2" icon="gesture-select"/>
|
||||
<el-button
|
||||
type="text"
|
||||
@click="handleSelectLocalPort(scope.row.port)"
|
||||
>
|
||||
<IconifyIconOffline
|
||||
class="cursor-pointer mr-2"
|
||||
icon="gesture-select"
|
||||
/>
|
||||
选择
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</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