Files
wireguard-dashboard/web/src/views/setting/index.vue
coward db065073e2
All checks were successful
continuous-integration/drone/tag Build is passing
:zap:修复一下页面配置更改时无法修改配置描述
2024-10-16 14:37:16 +08:00

515 lines
14 KiB
Vue

<template>
<AppPage>
<n-card>
<n-tabs default-value="Server" justify-content="space-evenly" type="line" @update-value="tabChange">
<n-tab-pane name="Server" tab="服务端">
<n-form
ref="serverFormRef"
:model="serverFormModel"
:rules="serverFormRules"
>
<n-form-item label="IP段" path="ipScope" :rule="{
required: true,
type: 'array',
message: 'IP段不能为空',
trigger: ['change','blur']
}">
<n-select
v-model:value="serverFormModel.ipScope"
filterable
multiple
tag
placeholder="输入,按回车确认"
:show-arrow="false"
:show="false"
/>
</n-form-item>
<n-form-item label="监听端口" path="listenPort" :rule="[
{
required: true,
type: 'number',
message: '监听端口不能为空',
trigger: ['change','blur']
},
{
min: 1120,
type: 'number',
message: '端口最低设置为1120',
trigger: ['change','blur']
},
{
max: 65535,
type: 'number',
message: '端口最高设置为65535',
trigger: ['change','blur']
}
]">
<n-input-number :min="1120" :max="65535" v-model:value="serverFormModel.listenPort"/>
</n-form-item>
<n-form-item label="私钥" path="privateKey">
<n-input v-model:value="serverFormModel.privateKey"/>
</n-form-item>
<n-form-item label="公钥" path="publicKey">
<n-input v-model:value="serverFormModel.publicKey"/>
</n-form-item>
<n-form-item label="上行脚本" path="postUpScript">
<n-input v-model:value="serverFormModel.postUpScript"/>
</n-form-item>
<n-form-item label="下行脚本" path="postDownScript">
<n-input v-model:value="serverFormModel.postDownScript"/>
</n-form-item>
<n-form-item>
<n-button type="info" @click="updateServerConf">确认</n-button>
</n-form-item>
</n-form>
</n-tab-pane>
<n-tab-pane name="Global" tab="全局">
<n-form
ref="globalFormRef"
:model="globalFormModel"
:rules="globalFormRules"
>
<n-form-item label="公网IP" path="endpointAddress" class="pid">
<n-input v-model:value="globalFormModel.endpointAddress"/>
<n-button style="margin-top: 5px" size="small" type="warning" @click="getPublicAddr">获取地址</n-button>
</n-form-item>
<n-form-item label="DNS" path="dnsServer" :rule="{
required: true,
type: 'array',
message: 'dns不能为空',
trigger: ['change','blur']
}">
<n-select
v-model:value="globalFormModel.dnsServer"
filterable
multiple
tag
placeholder="输入,按回车确认"
:show-arrow="false"
:show="false"
/>
</n-form-item>
<n-form-item label="MTU" path="MTU" :rule="[
{
required: true,
type: 'number',
message: 'MTU不能为空',
trigger: ['change','blur']
},
{
min: 1120,
type: 'number',
message: 'MTU最低设置为100',
trigger: ['change','blur']
},
{
max: 3000,
type: 'number',
message: 'MTU最高设置为3000',
trigger: ['change','blur']
}
]">
<n-input-number :min="100" :max="3000" v-model:value="globalFormModel.MTU"/>
</n-form-item>
<n-form-item label="persistentKeepalive" path="persistentKeepalive" :rule="[
{
required: true,
type: 'number',
message: 'persistentKeepalive不能为空',
trigger: ['change','blur']
},
{
min: 15,
type: 'number',
message: 'persistentKeepalive最低设置为15',
trigger: ['change','blur']
},
{
max: 300,
type: 'number',
message: 'persistentKeepalive最高设置为300',
trigger: ['change','blur']
}
]">
<n-input-number :min="15" :max="300" v-model:value="globalFormModel.persistentKeepalive"/>
</n-form-item>
<n-form-item label="firewallMark" path="firewallMark">
<n-input v-model:value="globalFormModel.firewallMark"/>
</n-form-item>
<n-form-item label="table" path="table">
<n-input v-model:value="globalFormModel.table"/>
</n-form-item>
<n-form-item label="configPath" path="configFilePath">
<n-input v-model:value="globalFormModel.configFilePath"/>
</n-form-item>
<n-form-item>
<n-button type="info" @click="updateGlobalConf">确认</n-button>
</n-form-item>
</n-form>
</n-tab-pane>
<n-tab-pane name="Other" tab="其他">
<n-button style="float:right;margin-bottom: 10px" size="small" type="info" @click="showAddModal = !showAddModal">添加</n-button>
<n-data-table
:columns="tableColumns"
:data="taleData.data"
/>
</n-tab-pane>
</n-tabs>
</n-card>
<n-modal
:title="editFormModel.describe"
v-model:show="showEditModal"
preset="card"
style="width: 30%"
>
<n-form
ref="editFormRef"
:model="editFormModel"
>
<n-form-item v-for="(item,index) in editFormModel.data" :label="index">
<n-input v-if="typeof item === 'string'" v-model:value="editFormModel.data[index]"/>
<n-input-number v-else-if="typeof item === 'number'" v-model:value="editFormModel.data[index]"/>
<n-radio-group v-else-if="typeof item === 'boolean'" :value="editFormModel.data[index]">
<n-radio :value="true" :checked="editFormModel.data[index] === true" @change="editFormModel.data[index] = true"></n-radio>
<n-radio :value="false" :checked="editFormModel.data[index] === false" @change="editFormModel.data[index] = false"></n-radio>
</n-radio-group>
</n-form-item>
<n-form-item label="配置描述">
<n-input v-model:value="editFormModel.describe" />
</n-form-item>
<n-form-item>
<n-button type="info" @click="updateSetting">确认</n-button>
</n-form-item>
</n-form>
</n-modal>
<n-modal
title="添加"
v-model:show="showAddModal"
preset="card"
style="width: 30%"
>
<n-form :model="addFormModel" ref="addFormRef">
<n-form-item label="Code">
<n-input v-model:value="addFormModel.code"></n-input>
</n-form-item>
<n-form-item label="选项">
<n-dynamic-input v-model:value="addFormModel.data" preset="pair" key-placeholder="" value-placeholder=""/>
</n-form-item>
<n-form-item label="描述">
<n-input v-model:value="addFormModel.describe"></n-input>
</n-form-item>
<n-form-item>
<n-button type="info" @click="addSetting">确认</n-button>
</n-form-item>
</n-form>
</n-modal>
</AppPage>
</template>
<script setup>
// 服务端配置表单ref
import AppPage from '@/components/page/AppPage.vue'
import api from '@/views/setting/api'
import { NButton } from 'naive-ui'
import { renderIcon } from '@/utils'
import event from '@/utils/event/event'
const { $bus } = event();
const tabCode = ref("")
// 表头
const tableColumns = [
{
title: 'code',
key: 'code',
align: 'center',
titleAlign: 'center',
},
{
title: "描述",
key: "describe",
align: 'center',
titleAlign: 'center',
},
{
title: '操作',
key: 'action',
align: 'center',
titleAlign: 'center',
render: (row) => {
return [
h(NButton, {
size: 'small',
color: '#4389DA',
onClick: () => listBtn(row, "EDIT")
}, {
icon: renderIcon('mingcute:edit-line', { size: 14 }),
}),
h(NButton, {
size: 'small',
style: 'margin-left: 5px',
color: '#ED1518',
onClick: () => listBtn(row, "DELETE")
}, {
icon: renderIcon('icon-park-outline:delete', { size: 14 }),
})
]
}
}
]
const taleData = ref({
data: []
})
// 服务端表单ref
const serverFormRef = ref(null)
// 全局设置表单ref
const globalFormRef = ref(null)
// 编辑模态框表单ref
const editFormRef = ref(null)
// 添加模态框表单ref
const addFormRef = ref(null)
// 编辑模态框展示
const showEditModal = ref(false)
// 添加模态框展示
const showAddModal = ref(false)
// 服务端表单数据
const serverFormModel = ref({
ipScope: [],
listenPort: 51820,
privateKey: '',
publicKey: '',
postUpScript: '',
postDownScript: ''
})
// 全局设置表单数据
const globalFormModel = ref({
MTU: 1450,
configFilePath: '',
dnsServer: [],
endpointAddress: '',
firewallMark: '',
persistentKeepalive: 15,
table: ''
})
// 编辑表单数据
const editFormModel = ref({
code: '',
data: '',
describe: ''
})
// 添加表单数据
const addFormModel = ref({
code: '',
data: [
{
key: '',
value: ''
}
],
describe: ''
})
// 服务端表单数据验证
const serverFormRules = {
privateKey: [
{ required: true, message: '密钥不能为空', trigger: 'blur' }
],
publicKey: [
{ required: true, message: '公钥不能为空', trigger: 'blur' }
]
}
// 全局表单数据验证
const globalFormRules = {
endpointAddress: [
{ required: true, message: '公网IP不能为空', trigger: 'blur' }
],
configFilePath: [
{ required: true, message: '文件地址不能为空', trigger: 'blur' }
]
}
// 获取服务端配置
async function getServerConfig () {
const res = await api.getSetting({
code: "WG_SERVER"
})
if (res.data.code === 200) {
serverFormModel.value = JSON.parse(res.data.data)
}
}
// 获取全局配置
async function getGlobalConfig () {
const res = await api.getSetting({
code: "WG_SETTING"
})
if (res.data.code === 200) {
globalFormModel.value = JSON.parse(res.data.data)
}
}
// 更改服务端配置
async function updateServerConf() {
serverFormRef.value?.validate(async (errors) => {
if (errors) {
return errors
}
const res = await api.setSetting({
code: "WG_SERVER",
data: JSON.stringify(serverFormModel.value)
})
if (res.data.code === 200) {
await getServerConfig()
$message.success("操作成功")
}
})
}
// 更改全局配置
async function updateGlobalConf() {
globalFormRef.value?.validate(async (errors) => {
if (errors) {
return errors
}
const res = await api.setSetting({
code: "WG_SETTING",
data: JSON.stringify(globalFormModel.value)
})
if (res.data.code === 200) {
await getGlobalConfig()
$message.success("操作成功")
}
})
}
// 获取公网IP地址
async function getPublicAddr() {
const res = await api.publicAddr()
if (res.data.code === 200) {
globalFormModel.value.endpointAddress = res.data.data
}
}
// 获取全部配置
function allSetting() {
api.allSettings().then(res => {
if (res.data.code === 200) {
taleData.value.data = res.data.data
}
})
}
// tab切换事件
function tabChange(code) {
switch (code) {
case "Server":
getServerConfig()
tabCode.value = "Server"
break;
case "Global":
getGlobalConfig()
tabCode.value = "Global"
break;
case "Other":
allSetting()
tabCode.value = "Other"
break;
}
}
// 列表操作按钮
function listBtn(row,code) {
switch (code) {
case "EDIT":
showEditModal.value = true
editFormModel.value.describe = row.describe
editFormModel.value.data = JSON.parse(row.data)
editFormModel.value.code = row.code
break;
case "DELETE":
$dialog.confirm({
type: 'warning',
title: '删除',
content: `是否删除设置:【${row.describe}】?`,
async confirm() {
const res = await api.delSetting(row.code)
if (res.data.code === 200) {
$message.success("操作成功")
allSetting()
}
},
})
break;
}
}
// 更改配置信息
async function updateSetting() {
const res = await api.setSetting({
code: editFormModel.value.code,
data: JSON.stringify(editFormModel.value.data),
describe: editFormModel.value.describe
})
if (res.data.code === 200) {
showEditModal.value = false
allSetting()
}
}
// 添加设置
async function addSetting() {
const dataObj = {}
for (const item of addFormModel.value.data) {
dataObj[item.key] = item.value
}
const addFormData = {
code: addFormModel.value.code,
data: JSON.stringify(dataObj),
describe: addFormModel.value.describe
}
const res = await api.setSetting(addFormData)
if (res.data.code === 200) {
showAddModal.value = false
addFormModel.value = {
code: '',
data: [
{
key: '',
value: ''
}
],
describe: ''
}
allSetting()
}
}
$bus.on("refreshSetting",value => {
if (value) {
if (tabCode.value === "" || tabCode.value === undefined) {
getServerConfig()
} else {
switch (tabCode.value) {
case "Server":
getServerConfig()
break;
case "Global":
getGlobalConfig()
break;
}
}
}
})
getServerConfig()
</script>
<style lang="scss">
.pid .n-form-item-blank {
display: inline;
}
</style>