增加对udp的支持

This commit is contained in:
刘嘉伟 2024-08-11 15:12:45 +08:00
parent ff1b7fbb35
commit b2f7d8adb3
2 changed files with 96 additions and 88 deletions

View File

@ -49,6 +49,7 @@ localPort = ${m.localPort}
`; `;
switch (m.type) { switch (m.type) {
case "tcp": case "tcp":
case "udp":
toml += `remotePort = ${m.remotePort}`; toml += `remotePort = ${m.remotePort}`;
break; break;
case "http": case "http":
@ -117,6 +118,7 @@ local_port = ${m.localPort}
`; `;
switch (m.type) { switch (m.type) {
case "tcp": case "tcp":
case "udp":
ini += `remote_port = ${m.remotePort}`; ini += `remote_port = ${m.remotePort}`;
break; break;
case "http": case "http":

View File

@ -1,10 +1,10 @@
<script lang="ts" setup> <script lang="ts" setup>
import { defineComponent, onMounted, onUnmounted, reactive, ref } from "vue"; import {defineComponent, onMounted, onUnmounted, reactive, ref} from "vue";
import { Icon } from "@iconify/vue"; import {Icon} from "@iconify/vue";
import Breadcrumb from "@/layout/compoenets/Breadcrumb.vue"; import Breadcrumb from "@/layout/compoenets/Breadcrumb.vue";
import { ElMessage, FormInstance, FormRules } from "element-plus"; import {ElMessage, FormInstance, FormRules} from "element-plus";
import { ipcRenderer } from "electron"; import {ipcRenderer} from "electron";
import { clone } from "@/utils/clone"; import {clone} from "@/utils/clone";
defineComponent({ defineComponent({
name: "Proxy" name: "Proxy"
@ -58,24 +58,24 @@ const editForm = ref<Proxy>({
*/ */
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: "",
// trigger: "blur" // trigger: "blur"
// } // }
], ],
type: [{ required: true, message: "请选择类型", trigger: "blur" }], type: [{required: true, message: "请选择类型", trigger: "blur"}],
localIp: [ localIp: [
{ required: true, message: "请输入内网地址", trigger: "blur" }, {required: true, message: "请输入内网地址", trigger: "blur"},
{ {
pattern: /^[\w-]+(\.[\w-]+)+$/, pattern: /^[\w-]+(\.[\w-]+)+$/,
message: "请输入正确的内网地址", message: "请输入正确的内网地址",
trigger: "blur" trigger: "blur"
} }
], ],
localPort: [{ required: true, message: "请输入本地端口", trigger: "blur" }], localPort: [{required: true, message: "请输入本地端口", trigger: "blur"}],
remotePort: [{ required: true, message: "请输入远程端口", trigger: "blur" }] remotePort: [{required: true, message: "请输入远程端口", trigger: "blur"}]
}); });
/** /**
@ -152,7 +152,7 @@ const handleResetForm = () => {
const handleInitHook = () => { const handleInitHook = () => {
const InsertOrUpdateHook = (message: string, args: any) => { const InsertOrUpdateHook = (message: string, args: any) => {
loading.value.form--; loading.value.form--;
const { err } = args; const {err} = args;
if (!err) { if (!err) {
ElMessage({ ElMessage({
type: "success", type: "success",
@ -185,13 +185,13 @@ const handleInitHook = () => {
// }); // });
ipcRenderer.on("Proxy.getProxys.hook", (event, args) => { ipcRenderer.on("Proxy.getProxys.hook", (event, args) => {
loading.value.list--; loading.value.list--;
const { err, data } = args; const {err, data} = args;
if (!err) { if (!err) {
proxys.value = data; proxys.value = data;
} }
}); });
ipcRenderer.on("Proxy.deleteProxyById.hook", (event, args) => { ipcRenderer.on("Proxy.deleteProxyById.hook", (event, args) => {
const { err, data } = args; const {err, data} = args;
if (!err) { if (!err) {
handleLoadProxys(); handleLoadProxys();
ElMessage({ ElMessage({
@ -233,65 +233,65 @@ onUnmounted(() => {
<div class="main"> <div class="main">
<breadcrumb> <breadcrumb>
<div <div
class="cursor-pointer h-[36px] w-[36px] bg-[#5f3bb0] rounded text-white flex justify-center items-center" class="cursor-pointer h-[36px] w-[36px] bg-[#5f3bb0] rounded text-white flex justify-center items-center"
@click="handleOpenInsert" @click="handleOpenInsert"
> >
<Icon icon="material-symbols:add" /> <Icon icon="material-symbols:add"/>
</div> </div>
</breadcrumb> </breadcrumb>
<div class="app-container-breadcrumb" v-loading="loading.list > 0"> <div class="app-container-breadcrumb" v-loading="loading.list > 0">
<template v-if="proxys && proxys.length > 0"> <template v-if="proxys && proxys.length > 0">
<el-row :gutter="20"> <el-row :gutter="20">
<el-col <el-col
v-for="proxy in proxys" v-for="proxy in proxys"
:key="proxy._id" :key="proxy._id"
:lg="6" :lg="6"
:md="8" :md="8"
:sm="12" :sm="12"
:xl="6" :xl="6"
:xs="24" :xs="24"
class="mb-[20px]" class="mb-[20px]"
> >
<div class="bg-white w-full rounded drop-shadow-xl p-4"> <div class="bg-white w-full rounded drop-shadow-xl p-4">
<div class="w-full flex justify-between"> <div class="w-full flex justify-between">
<div class="flex"> <div class="flex">
<div <div
class="w-12 h-12 rounded mr-4 flex justify-center items-center" class="w-12 h-12 rounded mr-4 flex justify-center items-center"
:class="proxy.type" :class="proxy.type"
> >
<span class="text-white text-sm">{{ proxy.type }}</span> <span class="text-white text-sm">{{ proxy.type }}</span>
</div> </div>
<div class="h-12 relative"> <div class="h-12 relative">
<div class="text-sm font-bold">{{ proxy.name }}</div> <div class="text-sm font-bold">{{ proxy.name }}</div>
<!-- <el-tag--> <!-- <el-tag-->
<!-- size="small"--> <!-- size="small"-->
<!-- class="absolute bottom-0"--> <!-- class="absolute bottom-0"-->
<!-- type="success"--> <!-- type="success"-->
<!-- effect="plain"--> <!-- effect="plain"-->
<!-- >正常--> <!-- >正常-->
<!-- </el-tag>--> <!-- </el-tag>-->
</div> </div>
</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]"
> >
<Icon icon="material-symbols:more-vert" /> <Icon icon="material-symbols:more-vert"/>
</a> </a>
<template #dropdown> <template #dropdown>
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item @click="handleOpenUpdate(proxy)"> <el-dropdown-item @click="handleOpenUpdate(proxy)">
<Icon <Icon
icon="material-symbols:edit" icon="material-symbols:edit"
class="primary-text text-[14px]" class="primary-text text-[14px]"
/> />
<span class="ml-1"> </span> <span class="ml-1"> </span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item @click="handleDeleteProxy(proxy)"> <el-dropdown-item @click="handleDeleteProxy(proxy)">
<Icon <Icon
icon="material-symbols:delete-rounded" icon="material-symbols:delete-rounded"
class="text-red-500 text-[14px]" class="text-red-500 text-[14px]"
/> />
<span class="ml-1"> </span> <span class="ml-1"> </span>
</el-dropdown-item> </el-dropdown-item>
@ -320,81 +320,83 @@ onUnmounted(() => {
</el-row> </el-row>
</template> </template>
<div <div
v-else v-else
class="w-full h-full bg-white rounded p-2 overflow-hidden drop-shadow-xl flex justify-center items-center" 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>
</div> </div>
<el-dialog <el-dialog
v-model="edit.visible" v-model="edit.visible"
:title="edit.title" :title="edit.title"
class="w-[400px]" class="w-[400px]"
top="30px" top="30px"
> >
<el-form <el-form
v-loading="loading.form" v-loading="loading.form"
label-position="top" label-position="top"
:model="editForm" :model="editForm"
:rules="editFormRules" :rules="editFormRules"
ref="editFormRef" ref="editFormRef"
> >
<el-row :gutter="10"> <el-row :gutter="10">
<el-col :span="24"> <el-col :span="24">
<el-form-item label="代理类型:" prop="proxyType"> <el-form-item label="代理类型:" prop="proxyType">
<el-radio-group v-model="editForm.type"> <el-radio-group v-model="editForm.type">
<el-radio label="http" model-value="http" /> <el-radio label="http" model-value="http"/>
<el-radio label="https" model-value="https" /> <el-radio label="https" model-value="https"/>
<el-radio label="tcp" model-value="tcp" /> <el-radio label="tcp" model-value="tcp"/>
<el-radio label="udp" model-value="udp"/>
<!-- <el-radio label="stcp" model-value="stcp" />-->
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="24"> <el-col :span="24">
<el-form-item label="代理名称:" prop="proxyName"> <el-form-item label="代理名称:" prop="proxyName">
<el-input v-model="editForm.name" placeholder="代理名称" /> <el-input v-model="editForm.name" placeholder="代理名称"/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="16"> <el-col :span="16">
<el-form-item label="内网地址:" prop="localIp"> <el-form-item label="内网地址:" prop="localIp">
<el-input v-model="editForm.localIp" placeholder="127.0.0.1" /> <el-input v-model="editForm.localIp" placeholder="127.0.0.1"/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="内网端口:" prop="localPort"> <el-form-item label="内网端口:" prop="localPort">
<el-input-number <el-input-number
placeholder="8080" placeholder="8080"
class="!w-full" class="!w-full"
:min="0" :min="0"
:max="65535" :max="65535"
v-model="editForm.localPort" v-model="editForm.localPort"
controls-position="right" controls-position="right"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<template v-if="editForm.type === 'tcp'"> <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">
<el-input-number <el-input-number
:min="0" :min="0"
:max="65535" :max="65535"
placeholder="8080" placeholder="8080"
v-model="editForm.remotePort" v-model="editForm.remotePort"
controls-position="right" controls-position="right"
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
</template> </template>
<template <template
v-if="editForm.type === 'http' || editForm.type === 'https'" v-if="editForm.type === 'http' || editForm.type === 'https'"
> >
<el-col :span="24"> <el-col :span="24">
<el-form-item <el-form-item
v-for="(d, di) in editForm.customDomains" v-for="(d, di) in editForm.customDomains"
:key="'domain' + di" :key="'domain' + di"
:label="di === 0 ? '自定义域名:' : ''" :label="di === 0 ? '自定义域名:' : ''"
:prop="`customDomains.${di}`" :prop="`customDomains.${di}`"
:rules="[ :rules="[
{ {
required: true, required: true,
message: `自定义域名不能为空`, message: `自定义域名不能为空`,
@ -409,28 +411,28 @@ onUnmounted(() => {
]" ]"
> >
<el-input <el-input
class="domain-input" class="domain-input"
placeholder="github.com" placeholder="github.com"
v-model="editForm.customDomains[di]" v-model="editForm.customDomains[di]"
/> />
<!-- <div class="domain-input-button !bg-[#67c23a]">--> <!-- <div class="domain-input-button !bg-[#67c23a]">-->
<!-- <Icon icon="material-symbols:add" />--> <!-- <Icon icon="material-symbols:add" />-->
<!-- </div>--> <!-- </div>-->
<el-button <el-button
class="ml-[10px]" class="ml-[10px]"
type="primary" type="primary"
plain plain
@click="handleAddDomain" @click="handleAddDomain"
> >
<Icon icon="material-symbols:add" /> <Icon icon="material-symbols:add"/>
</el-button> </el-button>
<el-button <el-button
type="danger" type="danger"
plain plain
@click="handleDeleteDomain(di)" @click="handleDeleteDomain(di)"
:disabled="editForm.customDomains.length === 1" :disabled="editForm.customDomains.length === 1"
> >
<Icon icon="material-symbols:delete-rounded" /> <Icon icon="material-symbols:delete-rounded"/>
</el-button> </el-button>
<!-- <div class="domain-input-button !bg-[#d3585b]">--> <!-- <div class="domain-input-button !bg-[#d3585b]">-->
<!-- <Icon icon="material-symbols:delete-rounded" />--> <!-- <Icon icon="material-symbols:delete-rounded" />-->
@ -443,7 +445,7 @@ onUnmounted(() => {
<div class="w-full flex justify-end"> <div class="w-full flex justify-end">
<el-button @click="edit.visible = false"> </el-button> <el-button @click="edit.visible = false"> </el-button>
<el-button plain type="primary" @click="handleSubmit" <el-button plain type="primary" @click="handleSubmit"
> >
</el-button> </el-button>
</div> </div>
</el-form-item> </el-form-item>
@ -467,6 +469,10 @@ onUnmounted(() => {
background: #5f3bb0; background: #5f3bb0;
} }
.udp {
background: #5ec7fe;
}
.domain-input { .domain-input {
width: calc(100% - 115px); width: calc(100% - 115px);
} }