调整分组配置

This commit is contained in:
chaoszhu 2024-07-19 10:52:09 +08:00
parent 483f17a591
commit 514c9499e6
10 changed files with 155 additions and 89 deletions

View File

@ -1,30 +1,30 @@
const { readHostList, writeHostList, readSSHRecord, writeSSHRecord } = require('../utils')
async function getHostList({ res }) {
console.log('get - host - list')
// console.log('get-host-list')
const data = await readHostList()
res.success({ data })
}
async function saveHost({ res, request }) {
let { body: { host: newHost, name, expired, expiredNotify, group, consoleUrl, remark } } = request
console.log(request)
let { body: { host: newHost, name, index, expired, expiredNotify, group, consoleUrl, remark } } = request
// console.log(request)
if (!newHost || !name) return res.fail({ msg: 'missing params: name or host' })
let hostList = await readHostList()
if (hostList?.some(({ host }) => host === newHost)) return res.fail({ msg: `主机${ newHost }已存在` })
if (!Array.isArray(hostList)) hostList = []
hostList.push({ host: newHost, name, expired, expiredNotify, group, consoleUrl, remark })
hostList.push({ host: newHost, name, index, expired, expiredNotify, group, consoleUrl, remark })
await writeHostList(hostList)
res.success()
}
async function updateHost({ res, request }) {
let { body: { host: newHost, name: newName, oldHost, expired, expiredNotify, group, consoleUrl, remark } } = request
let { body: { host: newHost, name: newName, index, oldHost, expired, expiredNotify, group, consoleUrl, remark } } = request
if (!newHost || !newName || !oldHost) return res.fail({ msg: '参数错误' })
let hostList = await readHostList()
if (!hostList.some(({ host }) => host === oldHost)) return res.fail({ msg: `主机${ newHost }不存在` })
let targetIdx = hostList.findIndex(({ host }) => host === oldHost)
hostList.splice(targetIdx, 1, { name: newName, host: newHost, expired, expiredNotify, group, consoleUrl, remark })
hostList.splice(targetIdx, 1, { name: newName, host: newHost, index, expired, expiredNotify, group, consoleUrl, remark })
writeHostList(hostList)
res.success()
}
@ -46,26 +46,27 @@ async function removeHost({ res, request }) {
res.success({ data: `${ host }已移除, ${ flag ? '并移除ssh记录' : '' }` })
}
async function updateHostSort({ res, request }) {
let { body: { list } } = request
if (!list) return res.fail({ msg: '参数错误' })
let hostList = await readHostList()
if (hostList.length !== list.length) return res.fail({ msg: '失败: host数量不匹配' })
let sortResult = []
for (let i = 0; i < list.length; i++) {
const curHost = list[i]
let temp = hostList.find(({ host }) => curHost.host === host)
if (!temp) return res.fail({ msg: `查找失败: ${ curHost.name }` })
sortResult.push(temp)
}
writeHostList(sortResult)
res.success({ msg: 'success' })
}
// 原手动排序接口-废弃
// async function updateHostSort({ res, request }) {
// let { body: { list } } = request
// if (!list) return res.fail({ msg: '参数错误' })
// let hostList = await readHostList()
// if (hostList.length !== list.length) return res.fail({ msg: '失败: host数量不匹配' })
// let sortResult = []
// for (let i = 0; i < list.length; i++) {
// const curHost = list[i]
// let temp = hostList.find(({ host }) => curHost.host === host)
// if (!temp) return res.fail({ msg: `查找失败: ${ curHost.name }` })
// sortResult.push(temp)
// }
// writeHostList(sortResult)
// res.success({ msg: 'success' })
// }
module.exports = {
getHostList,
saveHost,
updateHost,
removeHost,
updateHostSort
removeHost
// updateHostSort
}

View File

@ -1,5 +1,5 @@
const { updateSSH, removeSSH, existSSH, getCommand } = require('../controller/ssh')
const { getHostList, saveHost, updateHost, removeHost, updateHostSort } = require('../controller/host')
const { getHostList, saveHost, updateHost, removeHost } = require('../controller/host')
const { login, getpublicKey, updatePwd, getLoginRecord } = require('../controller/user')
const { getSupportEmailList, getUserEmailList, updateUserEmailList, removeUserEmail, pushEmail, getNotifyList, updateNotifyList } = require('../controller/notify')
const { getGroupList, addGroupList, updateGroupList, removeGroup } = require('../controller/group')
@ -46,12 +46,12 @@ const host = [
method: 'post',
path: '/host-remove',
controller: removeHost
},
{
method: 'put',
path: '/host-sort',
controller: updateHostSort
}
// {
// method: 'put',
// path: '/host-sort',
// controller: updateHostSort
// }
]
const user = [
{

View File

@ -4,7 +4,7 @@
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=0,user-scalable=yes">
<title>EasyNode</title>
<script src="//at.alicdn.com/t/c/font_3309550_flid0kihu36.js"></script>
<script src="//at.alicdn.com/t/c/font_3309550_ezojxo1wj3.js"></script>
</head>
<body>

View File

@ -43,9 +43,9 @@ export default {
updatePwd(data) {
return axios({ url: '/pwd', method: 'put', data })
},
updateHostSort(data) {
return axios({ url: '/host-sort', method: 'put', data })
},
// updateHostSort(data) {
// return axios({ url: '/host-sort', method: 'put', data })
// },
getUserEmailList() {
return axios({ url: '/user-email', method: 'get' })
},

View File

@ -1,5 +1,6 @@
<template>
<svg class="icon" aria-hidden="true">
<title v-if="title">{{ title }}</title>
<use :xlink:href="href" />
</svg>
</template>
@ -8,6 +9,12 @@ export default {
name: 'IconSvg',
props: {
name: {
required: true,
type: String,
default: ''
},
title: {
required: false,
type: String,
default: ''
}

View File

@ -7,6 +7,7 @@
:inline="true"
:hide-required-asterisk="true"
label-suffix=""
:show-message="false"
>
<el-form-item label="" prop="name" style="width: 200px;">
<el-input
@ -171,7 +172,7 @@ const getGroupList = () => {
$api.getGroupList()
.then(({ data }) => {
groupList.value = data
groupForm.index = data.length
// groupForm.index = data.length
})
.finally(() => loading.value = false)
}

View File

@ -132,20 +132,32 @@
<span> {{ $tools.formatNetSpeed(netstatInfo.netTotal?.inputMb) || 0 }}</span>
</div>
</div>
<div class="fields terminal">
<el-dropdown class="web-ssh" type="primary" trigger="click">
<!-- <el-button type="primary" @click="handleSSH">Web SSH</el-button> -->
<el-button type="primary">功能</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="handleSSH">连接终端</el-dropdown-item>
<el-dropdown-item v-if="consoleUrl" @click="handleToConsole">控制台</el-dropdown-item>
<el-dropdown-item @click="handleUpdate">修改服务器</el-dropdown-item>
<el-dropdown-item @click="handleRemoveHost"><span style="color: #727272;">移除主机</span></el-dropdown-item>
<el-dropdown-item @click="handleRemoveSSH"><span style="color: #727272;">移除凭证</span></el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<div class="field actions">
<svg-icon
name="icon-zhongduanguanli24"
title="终端"
class="actions-icon"
@click="handleSSH"
/>
<svg-icon
v-show="consoleUrl"
name="icon-a-zu391"
title="服务商控制台"
class="actions-icon"
@click="handleToConsole"
/>
<svg-icon
name="icon-bianji1"
title="编辑"
class="actions-icon"
@click="handleUpdate"
/>
<svg-icon
name="icon-shanchu1"
title="删除"
class="actions-icon"
@click="handleRemoveHost"
/>
</div>
</div>
<SSHForm v-model:show="sshFormVisible" :temp-host="tempHost" :name="name" />
@ -155,6 +167,7 @@
<script setup>
import { ref, computed, getCurrentInstance } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import SSHForm from './ssh-form.vue'
const { proxy: { $api, $tools } } = getCurrentInstance()
@ -208,8 +221,8 @@ const setColor = (num) => {
}
const handleUpdate = () => {
let { expired, expiredNotify, group, consoleUrl, remark } = props.hostInfo
emit('update-host', { name: name.value, host: host.value, expired, expiredNotify, group, consoleUrl, remark })
let { expired, expiredNotify, group, consoleUrl, remark, index } = props.hostInfo
emit('update-host', { name: name.value, host: host.value, index, expired, expiredNotify, group, consoleUrl, remark })
}
const handleToConsole = () => {
@ -353,6 +366,16 @@ const handleRemoveHost = async () => {
}
}
.actions {
.actions-icon {
margin: 0 10px;
width: 16px;
height: 16px;
color: #1989fa;
cursor: pointer;
}
}
.web-ssh {
// ::v-deep has been deprecated. Use :deep(<inner-selector>) instead.

View File

@ -14,6 +14,7 @@
:hide-required-asterisk="true"
label-suffix=""
label-width="100px"
:show-message="false"
>
<transition-group
name="list"
@ -34,27 +35,27 @@
/>
</el-select>
</el-form-item>
<el-form-item key="name" label="主机别名" prop="name">
<el-form-item key="name" label="服务器名称" prop="name">
<el-input
v-model.trim="hostForm.name"
clearable
placeholder="主机别名"
placeholder=""
autocomplete="off"
/>
</el-form-item>
<el-form-item key="host" label="IP/域名" prop="host">
<el-form-item key="host" label="服务器IP" prop="host">
<el-input
v-model.trim="hostForm.host"
clearable
placeholder="IP/域名"
placeholder=""
autocomplete="off"
@keyup.enter="handleSave"
/>
</el-form-item>
<el-form-item key="expired" label="到期时间" prop="expired">
<el-date-picker
v-model="hostForm.expired"
type="date"
style="width: 100%;"
value-format="x"
placeholder="服务器到期时间"
/>
@ -73,11 +74,19 @@
/>
</el-tooltip>
</el-form-item>
<el-form-item key="index" label="序号" prop="index">
<el-input
v-model.trim.number="hostForm.index"
clearable
placeholder="用于服务器列表中排序(填写数字)"
autocomplete="off"
/>
</el-form-item>
<el-form-item key="consoleUrl" label="控制台URL" prop="consoleUrl">
<el-input
v-model.trim="hostForm.consoleUrl"
clearable
placeholder="用于直达服务器控制台"
placeholder="用于直达云服务商控制台"
autocomplete="off"
@keyup.enter="handleSave"
/>
@ -89,7 +98,7 @@
:rows="3"
clearable
autocomplete="off"
placeholder="用于简单记录服务器用途"
placeholder="简单记录服务器用途"
/>
</el-form-item>
</transition-group>
@ -125,6 +134,7 @@ const resetForm = () => ({
group: 'default',
name: '',
host: '',
index: 0,
expired: null,
expiredNotify: false,
consoleUrl: '',
@ -138,6 +148,7 @@ const rules = reactive({
group: { required: true, message: '选择一个分组' },
name: { required: true, message: '输入主机别名', trigger: 'change' },
host: { required: true, message: '输入IP/域名', trigger: 'change' },
index: { required: true, type: 'number', message: '输入数字', trigger: 'change' },
expired: { required: false },
expiredNotify: { required: false },
consoleUrl: { required: false },
@ -174,9 +185,10 @@ const handleClosed = () => {
const setDefaultData = () => {
if (!props.defaultData) return
let { name, host, expired, expiredNotify, consoleUrl, group, remark } = props.defaultData
console.log(props.defaultData)
let { name, host, index, expired, expiredNotify, consoleUrl, group, remark } = props.defaultData
oldHost.value = host
Object.assign(hostForm, { name, host, expired, expiredNotify, consoleUrl, group, remark })
Object.assign(hostForm, { name, host, index, expired, expiredNotify, consoleUrl, group, remark })
}
const handleSave = () => {

View File

@ -1,24 +1,38 @@
<template>
<div class="server_group_collapse">
<el-collapse v-model="activeGroup">
<el-collapse-item v-for="(servers, groupName) in resList" :key="groupName" :name="groupName">
<template #title>
<div class="group_title">
{{ groupName }}
<div class="server_group_container">
<div class="server_group_header">
<el-button type="primary" @click="hostFormVisible = true">添加服务器</el-button>
<el-button type="primary" @click="handleHiddenIP">
{{ hiddenIp ? '显示IP' : '隐藏IP' }}
</el-button>
</div>
<div class="server_group_collapse">
<el-collapse v-model="activeGroup">
<el-collapse-item v-for="(servers, groupName) in resList" :key="groupName" :name="groupName">
<template #title>
<div class="group_title">
{{ groupName }}
</div>
</template>
<div class="host_card_container">
<HostCard
v-for="(item, index) in servers"
:key="index"
:host-info="item"
:hidden-ip="hiddenIp"
@update-list="handleUpdateList"
@update-host="handleUpdateHost"
/>
</div>
</template>
<div class="host_card_container">
<HostCard
v-for="(item, index) in servers"
:key="index"
:host-info="item"
:hidden-ip="hiddenIp"
@update-list="handleUpdateList"
@update-host="handleUpdateHost"
/>
</div>
</el-collapse-item>
</el-collapse>
</el-collapse-item>
</el-collapse>
</div>
<HostForm
v-model:show="hostFormVisible"
:default-data="updateHostData"
@update-list="handleUpdateList"
@closed="updateHostData = null"
/>
</div>
</template>
@ -150,15 +164,23 @@ onBeforeUnmount(() => {
</script>
<style lang="scss" scoped>
.server_group_collapse {
.group_title {
margin: 0 15px;
font-size: 14px;
font-weight: 600;
line-height: 22px;
.server_group_container {
.server_group_header {
padding: 15px;
display: flex;
align-items: center;
justify-content: end;
}
.host_card_container {
padding-top: 25px;
.server_group_collapse {
.group_title {
margin: 0 15px;
font-size: 14px;
font-weight: 600;
line-height: 22px;
}
.host_card_container {
padding-top: 25px;
}
}
}
</style>

View File

@ -10,9 +10,9 @@
<el-tab-pane label="登录日志">
<Record />
</el-tab-pane>
<el-tab-pane label="主机排序" lazy>
<!-- <el-tab-pane label="主机排序" lazy>
<Sort @update-list="emitUpdateList" />
</el-tab-pane>
</el-tab-pane> -->
<el-tab-pane label="全局通知" lazy>
<NotifyList />
</el-tab-pane>
@ -27,7 +27,7 @@
import { computed } from 'vue'
import NotifyList from './components/notify-list.vue'
import EmailList from './components/email-list.vue'
import Sort from './components/sort.vue'
// import Sort from './components/sort.vue'
import Record from './components/record.vue'
// import Group from './components/group.vue'
import Password from './components/password.vue'