648 lines
23 KiB
Vue
648 lines
23 KiB
Vue
<template>
|
|
<div class="node">
|
|
<el-dialog v-model="nodeVisible" :title="nodeTitle" width="600" @close="closeNodeForm">
|
|
<el-form :model="nodeForm" ref="nodeFormRef" :label-width="100" :rules="nodeFormRules">
|
|
<el-form-item prop="nodeName" :label="nodeKeyEnum['nodeName']">
|
|
<el-input v-model="nodeForm.nodeName" :disabled="nodeFormDisabled" :placeholder="'请输入' + nodeKeyEnum['nodeName']"></el-input>
|
|
</el-form-item>
|
|
<el-form-item prop="nodeIp" :label="nodeKeyEnum['nodeIp']">
|
|
<el-input v-model="nodeForm.nodeIp" :disabled="nodeFormDisabled" :placeholder="'请输入' + nodeKeyEnum['nodeIp']"></el-input>
|
|
</el-form-item>
|
|
<el-form-item prop="orgId" :label="nodeKeyEnum['orgId']">
|
|
<el-tree-select
|
|
v-model="nodeForm.orgId"
|
|
:disabled="nodeFormDisabled"
|
|
lazy
|
|
:load="loadSelectOrgTreeData"
|
|
check-strictly
|
|
:placeholder="'请选择' + nodeKeyEnum['orgId']"
|
|
></el-tree-select>
|
|
</el-form-item>
|
|
</el-form>
|
|
<template #footer>
|
|
<el-button type="primary" @click="submitNodeForm" :disabled="nodeFormDisabled">保存</el-button>
|
|
<el-button @click="closeNodeForm">取消</el-button>
|
|
</template>
|
|
</el-dialog>
|
|
<el-dialog v-model="linkVisible" :title="linkTitle" width="600" @close="closeLinkForm">
|
|
<el-form :model="linkForm" ref="linkFormRef" :label-width="100" :rules="linkFormRules">
|
|
<el-form-item prop="linkName" :label="linkKeyEnum['linkName']">
|
|
<el-input v-model="linkForm.linkName" :placeholder="'请输入' + linkKeyEnum['linkName']"></el-input>
|
|
</el-form-item>
|
|
<el-form-item prop="protocol" :label="linkKeyEnum['protocol']">
|
|
<el-select v-model="linkForm.protocol" :placeholder="'请选择' + linkKeyEnum['protocol']">
|
|
<el-option v-for="item in protocolList" :key="item.value" :label="item.label" :value="item.value"></el-option>
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item prop="params" :label="linkKeyEnum['params']">
|
|
<!-- <el-input v-model="linkForm.params" :placeholder="'请输入' + linkKeyEnum['params']"></el-input> -->
|
|
<el-button @click="openProtocolPart">协议参数</el-button>
|
|
</el-form-item>
|
|
</el-form>
|
|
<template #footer>
|
|
<el-button type="primary" @click="submitLinkForm">保存</el-button>
|
|
<el-button @click="closeLinkForm">取消</el-button>
|
|
</template>
|
|
</el-dialog>
|
|
<Container :has-aside="true">
|
|
<template #asideHeader>
|
|
<div class="treeSearchPart">
|
|
<el-input
|
|
v-model="searchTreeInput"
|
|
class="defaultSearchInput"
|
|
@input="debounceSearchNode"
|
|
clearable
|
|
placeholder="请输入节点名称"
|
|
></el-input>
|
|
<el-tooltip effect="light" content="新增节点" placement="bottom">
|
|
<el-button :icon="Plus" @click="addNode"></el-button>
|
|
</el-tooltip>
|
|
</div>
|
|
</template>
|
|
<template #asideMain>
|
|
<el-tree
|
|
ref="nodeTreeRef"
|
|
:data="treeData"
|
|
:props="replaceTreeProps"
|
|
node-key="id"
|
|
@node-click="nodeClick"
|
|
@node-contextmenu="nodeContextMenu"
|
|
highlight-current
|
|
></el-tree>
|
|
</template>
|
|
<template #mainHeader>
|
|
<div class="mainHeaderCenter">
|
|
<el-input v-model="searchLinkInput" class="defaultSearchInput tableSearchInput" clearable placeholder="请输入链路名称"></el-input>
|
|
<el-button :icon="Search" type="primary" @click="searchLink">查询</el-button>
|
|
</div>
|
|
<el-button :icon="Plus" type="primary" @click="addLinkList">新增</el-button>
|
|
<!-- <div class="mainHeaderRight">
|
|
<el-button :icon="Plus" type="primary" @click="addLinkList">新增</el-button>
|
|
<el-upload :show-file-list="false" :limit="1">
|
|
<template #trigger>
|
|
<el-button :icon="Upload">导入</el-button>
|
|
</template>
|
|
</el-upload>
|
|
<el-button :icon="Download">导出</el-button>
|
|
</div> -->
|
|
</template>
|
|
<template #mainMain>
|
|
<el-table :data="linkTableData" class="tablePart" highlight-current-row>
|
|
<el-table-column prop="linkName" label="链路名称" align="center"></el-table-column>
|
|
<el-table-column prop="protocolName" label="协议类型" align="center"></el-table-column>
|
|
<el-table-column prop="params" label="参数" align="center">
|
|
<template #default="scoped">
|
|
<el-button @click="openParams(scoped.row)">查看参数</el-button>
|
|
</template>
|
|
</el-table-column>
|
|
<!-- <el-table-column prop="nodeName" label="节点名称" align="center"></el-table-column> -->
|
|
<el-table-column fixed="right" label="操作" min-width="80" align="center">
|
|
<template #default="scope">
|
|
<div class="tableOperate">
|
|
<template v-if="scope.row.protocol !== 79">
|
|
<a @click="openlinkPoint(scope.row)">测点</a>
|
|
<a>|</a>
|
|
</template>
|
|
<a @click="editLinkList(scope.row)">编辑</a>
|
|
<a>|</a>
|
|
<el-popconfirm title="确定删除么?" @confirm="delLinkList(scope.row)">
|
|
<template #reference>
|
|
<a>删除</a>
|
|
</template>
|
|
</el-popconfirm>
|
|
</div>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
<div class="mainFooter">
|
|
<el-pagination
|
|
v-model:current-page="paginationOptions.current"
|
|
v-model:page-size="paginationOptions.pageSize"
|
|
:total="paginationOptions.total"
|
|
:page-sizes="paginationOptions.pageSizes"
|
|
background
|
|
:pager-count="7"
|
|
layout="prev, pager, next, jumper,sizes,total"
|
|
@change="changePage"
|
|
></el-pagination>
|
|
</div>
|
|
</template>
|
|
</Container>
|
|
<ContextMenu v-model:visible="nodeContextMenuVisible" :pos="nodeContextMenuPos">
|
|
<template #default>
|
|
<div class="modelOperate">
|
|
<el-button @click="openNode">查看</el-button>
|
|
<!-- <el-button @click="addNode">新增</el-button> -->
|
|
<el-button @click="editNode">编辑</el-button>
|
|
<el-popconfirm @confirm="delNode" title="确认删除?">
|
|
<template #reference>
|
|
<el-button @click.stop>删除</el-button>
|
|
</template>
|
|
</el-popconfirm>
|
|
<el-popconfirm @confirm="submitNodeConfig" title="确认配置下发?">
|
|
<template #reference>
|
|
<el-button @click.stop>配置下发</el-button>
|
|
</template>
|
|
</el-popconfirm>
|
|
</div>
|
|
</template>
|
|
</ContextMenu>
|
|
<ProtocolComponent
|
|
v-model:visible="protocolPartVisible"
|
|
:protocol="linkForm.protocol"
|
|
:params="linkForm.params"
|
|
:disabled="protocolDisabled"
|
|
@submit="getProtocolParams"
|
|
></ProtocolComponent>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ElInput, ElButton, ElTree, ElTable, ElMessage, ElTreeSelect } from 'element-plus'
|
|
import type { FormInstance, TreeInstance } from 'element-plus'
|
|
import { Search, Plus, Upload, Download } from '@element-plus/icons-vue'
|
|
import { ref, nextTick, reactive } from 'vue'
|
|
import { nodeType, nodeKeyEnum, linkType, linkKeyEnum } from '/@/views/backend/node/type'
|
|
import ContextMenu from '/@/views/backend/auth/model/contextMenu.vue'
|
|
import Container from '/@/components/container/index.vue'
|
|
import {
|
|
getNodeListReq,
|
|
addNodeListReq,
|
|
updateNodeListReq,
|
|
delNodeListReq,
|
|
getLinkListReq,
|
|
addLinkListReq,
|
|
updateLinkListReq,
|
|
delLinkListReq,
|
|
downloadNodeReq,
|
|
uploadNodeReq,
|
|
submitNodeConfigReq,
|
|
} from '/@/api/backend/node/request'
|
|
import { getInstitutionalTreeListReq } from '/@/api/backend/org/request'
|
|
import { debounce } from 'lodash-es'
|
|
import ProtocolComponent from './protocol.vue'
|
|
import { useRouter, useRoute } from 'vue-router'
|
|
|
|
const router = useRouter()
|
|
const route = useRoute()
|
|
|
|
const searchTreeInput = ref('')
|
|
|
|
const replaceTreeProps = { label: 'nodeName' }
|
|
const nodeTreeRef = ref<TreeInstance>()
|
|
const treeData = ref<nodeType[]>([])
|
|
let originTreeData: nodeType[] = []
|
|
|
|
const nodeVisible = ref(false)
|
|
const nodeTitle = ref('新增节点')
|
|
const originNodeData: nodeType = {
|
|
id: undefined,
|
|
nodeName: '',
|
|
nodeIp: '',
|
|
orgName: '',
|
|
orgId: '',
|
|
revision: 1,
|
|
}
|
|
const nodeForm = ref<nodeType>(JSON.parse(JSON.stringify(originNodeData)))
|
|
const nodeFormRef = ref<FormInstance>()
|
|
const nodeFormRules = {
|
|
nodeName: [{ required: true, message: '请输入节点名称', trigger: 'blur' }],
|
|
nodeIp: [
|
|
{
|
|
required: true,
|
|
validator: (rule: any, value: any, callback: any) => {
|
|
if (!value) {
|
|
callback(new Error('请输入节点IP'))
|
|
} else if (!/^((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/.test(value)) {
|
|
callback(new Error('请输入正确的IP地址'))
|
|
} else {
|
|
callback()
|
|
}
|
|
},
|
|
trigger: 'blur',
|
|
},
|
|
],
|
|
orgId: [{ required: true, message: '请选择所属组织', trigger: 'blur' }],
|
|
}
|
|
const getTreeData = (orgId: number | string | null) => {
|
|
return new Promise((resolve: (data: { label: string; value: string }[]) => unknown) => {
|
|
getInstitutionalTreeListReq({ parentOrgId: orgId }).then((res) => {
|
|
if (res.data) {
|
|
const result = res.data.map((item) => {
|
|
return {
|
|
label: item.name,
|
|
value: item.id,
|
|
}
|
|
})
|
|
resolve(result)
|
|
} else {
|
|
resolve([])
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
const loadSelectOrgTreeData = (node: any, resolve: any) => {
|
|
if (node.level === 0) {
|
|
return getTreeData(null)
|
|
.then((res) => {
|
|
if (!res.length) {
|
|
node.data.isLeaf = true
|
|
}
|
|
resolve(res)
|
|
})
|
|
.catch((err) => {
|
|
console.log(err)
|
|
})
|
|
}
|
|
console.log(node)
|
|
|
|
getTreeData(node.data.value)
|
|
.then((res) => {
|
|
if (!res.length) {
|
|
node.data.isLeaf = true
|
|
}
|
|
return resolve(res)
|
|
})
|
|
.catch((err) => {
|
|
console.log(err)
|
|
})
|
|
}
|
|
|
|
const nodeContextMenuVisible = ref(false)
|
|
const nodeContextMenuPos = ref({
|
|
x: 0,
|
|
y: 0,
|
|
})
|
|
|
|
const contextMenuTreeData = ref<nodeType>()
|
|
const clickTreeData = ref<nodeType>()
|
|
const nodeClick = (nodeData: nodeType) => {
|
|
clickTreeData.value = nodeData
|
|
getLinkData(nodeData.id!)
|
|
}
|
|
const nodeContextMenu = (event: any, nodeData: nodeType) => {
|
|
nodeContextMenuPos.value.x = event.pageX
|
|
nodeContextMenuPos.value.y = event.pageY
|
|
contextMenuTreeData.value = nodeData
|
|
nodeContextMenuVisible.value = true
|
|
}
|
|
const nodeFormDisabled = ref(false)
|
|
const openNode = () => {
|
|
nodeTitle.value = '查看节点'
|
|
nodeForm.value = JSON.parse(JSON.stringify(contextMenuTreeData.value))
|
|
nodeFormDisabled.value = true
|
|
nodeVisible.value = true
|
|
}
|
|
const addNode = () => {
|
|
nodeTitle.value = '新增节点'
|
|
nodeForm.value = JSON.parse(JSON.stringify(originNodeData))
|
|
nodeFormDisabled.value = false
|
|
nodeVisible.value = true
|
|
}
|
|
const editNode = () => {
|
|
nodeTitle.value = '编辑节点'
|
|
nodeForm.value = JSON.parse(JSON.stringify(contextMenuTreeData.value))
|
|
nodeFormDisabled.value = false
|
|
nodeVisible.value = true
|
|
}
|
|
const delNode = () => {
|
|
delNodeListReq({ id: contextMenuTreeData.value!.id! })
|
|
.then((res) => {
|
|
if (res.success) {
|
|
ElMessage.success(res.msg ?? '删除成功')
|
|
getNodeList()
|
|
} else {
|
|
ElMessage.error(res.msg ?? '删除失败')
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
ElMessage.error(err?.response?.data?.msg ?? '删除失败')
|
|
})
|
|
}
|
|
const submitNodeConfig = () => {
|
|
console.log(clickTreeData.value?.id!)
|
|
|
|
submitNodeConfigReq({ id: clickTreeData.value?.id! })
|
|
.then((res) => {
|
|
if (res.success) {
|
|
ElMessage.success(res.msg ?? '提交成功')
|
|
} else {
|
|
ElMessage.error(res.msg ?? '提交失败')
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
ElMessage.error('提交失败')
|
|
})
|
|
}
|
|
|
|
const submitNodeForm = () => {
|
|
nodeFormRef.value?.validate((valid: boolean) => {
|
|
if (valid) {
|
|
if (nodeTitle.value === '新增节点') {
|
|
addNodeListReq(nodeForm.value)
|
|
.then((res) => {
|
|
if (res.success) {
|
|
ElMessage.success(res.msg ?? '新增成功')
|
|
nodeVisible.value = false
|
|
getNodeList()
|
|
} else {
|
|
ElMessage.error(res.msg ?? '新增失败')
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
ElMessage.error(err?.response?.data?.msg ?? '新增失败')
|
|
})
|
|
} else if (nodeTitle.value === '编辑节点') {
|
|
updateNodeListReq(nodeForm.value)
|
|
.then((res) => {
|
|
if (res.success) {
|
|
ElMessage.success(res.msg ?? '编辑成功')
|
|
nodeVisible.value = false
|
|
getNodeList()
|
|
} else {
|
|
ElMessage.error(res.msg ?? '编辑失败')
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
ElMessage.error(err?.response?.data?.msg ?? '编辑失败')
|
|
})
|
|
}
|
|
}
|
|
})
|
|
}
|
|
const closeNodeForm = () => {
|
|
nodeForm.value = JSON.parse(JSON.stringify(originNodeData))
|
|
nodeFormRef.value?.resetFields()
|
|
nodeVisible.value = false
|
|
}
|
|
|
|
const getNodeList = () => {
|
|
return getNodeListReq()
|
|
.then((res) => {
|
|
if (res.success) {
|
|
treeData.value = res.data!
|
|
originTreeData = res.data!
|
|
clickTreeData.value = res.data![0]
|
|
nextTick(() => {
|
|
nodeTreeRef.value?.setCurrentKey((route.query?.treeKey as string) ?? res.data![0].id)
|
|
getLinkData((route.query?.treeKey as string) ?? res.data![0].id!)
|
|
})
|
|
} else {
|
|
ElMessage.error(res.msg ?? '查询失败')
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
ElMessage.error(err?.response?.data?.msg ?? '查询失败')
|
|
})
|
|
}
|
|
|
|
const searchNode = (val: string) => {
|
|
if (val === '') {
|
|
treeData.value = originTreeData
|
|
return
|
|
}
|
|
const reg = new RegExp(val, 'i')
|
|
treeData.value = originTreeData.filter((item) => reg.test(item.nodeName))
|
|
}
|
|
const debounceSearchNode = debounce(searchNode, 500)
|
|
|
|
const linkVisible = ref(false)
|
|
const linkTitle = ref('新增链路')
|
|
const originLinkData: linkType = {
|
|
id: undefined,
|
|
linkName: '',
|
|
protocol: undefined,
|
|
params: '',
|
|
nodeName: '',
|
|
nodeId: '',
|
|
revision: 1,
|
|
}
|
|
const linkFormRef = ref<FormInstance>()
|
|
const linkForm = ref<linkType>(JSON.parse(JSON.stringify(originLinkData)))
|
|
const linkFormRules = {
|
|
linkName: [{ required: true, message: '请输入' + linkKeyEnum['linkName'], trigger: 'blur' }],
|
|
protocol: [{ required: true, message: '请选择' + linkKeyEnum['protocol'], trigger: 'blur' }],
|
|
params: [{ required: true, message: '请配置' + linkKeyEnum['params'], trigger: 'change' }],
|
|
nodeId: [{ required: true, message: '请输入' + linkKeyEnum['nodeName'], trigger: 'blur' }],
|
|
}
|
|
const linkTableData = ref<linkType[]>([])
|
|
|
|
const searchLinkInput = ref('')
|
|
const searchLink = () => {
|
|
getLinkData(clickTreeData.value!.id!, searchLinkInput.value)
|
|
}
|
|
|
|
const addLinkList = () => {
|
|
linkForm.value = JSON.parse(JSON.stringify(originLinkData))
|
|
linkTitle.value = '新增链路'
|
|
linkForm.value.nodeId = clickTreeData.value?.id!
|
|
linkVisible.value = true
|
|
}
|
|
const editLinkList = (row: linkType) => {
|
|
linkForm.value = JSON.parse(JSON.stringify(row))
|
|
linkTitle.value = '编辑链路'
|
|
linkVisible.value = true
|
|
}
|
|
const closeLinkForm = () => {
|
|
linkForm.value = JSON.parse(JSON.stringify(originLinkData))
|
|
linkFormRef.value?.resetFields()
|
|
linkVisible.value = false
|
|
}
|
|
const delLinkList = (row: linkType) => {
|
|
delLinkListReq({ id: row.id })
|
|
.then((res) => {
|
|
if (res.success) {
|
|
ElMessage.success('删除成功')
|
|
getLinkData(clickTreeData.value!.id!)
|
|
} else {
|
|
ElMessage.error(res.msg ?? '删除失败')
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
ElMessage.error(err?.response?.data?.msg ?? '删除失败')
|
|
})
|
|
}
|
|
const submitLinkForm = () => {
|
|
linkFormRef.value?.validate((valid: boolean) => {
|
|
if (valid) {
|
|
if (linkTitle.value === '新增链路') {
|
|
addLinkListReq(linkForm.value)
|
|
.then((res) => {
|
|
if (res.success) {
|
|
ElMessage.success('新增成功')
|
|
linkVisible.value = false
|
|
getLinkData(clickTreeData.value!.id!)
|
|
} else {
|
|
ElMessage.error(res.msg ?? '新增失败')
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
ElMessage.error(err?.response?.data?.msg ?? '新增失败')
|
|
})
|
|
} else if (linkTitle.value === '编辑链路') {
|
|
updateLinkListReq(linkForm.value)
|
|
.then((res) => {
|
|
if (res.success) {
|
|
ElMessage.success('编辑成功')
|
|
linkVisible.value = false
|
|
getLinkData(clickTreeData.value!.id!)
|
|
} else {
|
|
ElMessage.error(res.msg ?? '编辑失败')
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
ElMessage.error(err?.response?.data?.msg ?? '编辑失败')
|
|
})
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
const paginationOptions = reactive({
|
|
current: 1,
|
|
pageSize: 20,
|
|
total: 0,
|
|
pageSizes: [20, 50, 100],
|
|
})
|
|
|
|
const changePage = () => {
|
|
getLinkData(clickTreeData.value!.id!)
|
|
}
|
|
|
|
const getLinkData = (nodeId: string, linkName?: string) => {
|
|
getLinkListReq({ nodeId, linkName, pageNum: paginationOptions.current, pageSize: paginationOptions.pageSize })
|
|
.then((res) => {
|
|
if (res.rows) {
|
|
linkTableData.value = res.rows.map((item) => {
|
|
return {
|
|
...item,
|
|
protocolName: protocolList.find((i) => i.value === item.protocol)?.label,
|
|
}
|
|
})
|
|
paginationOptions.total = res.total
|
|
} else {
|
|
ElMessage.error(res.msg ?? '查询失败')
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
ElMessage.error(err?.response?.data?.msg ?? '查询失败')
|
|
})
|
|
}
|
|
|
|
const protocolList = [
|
|
// * 代表需要配置的协议
|
|
{ label: 'IEC104从 *', value: 9 },
|
|
{ label: 'MODBUSTCP从 *', value: 17 },
|
|
{ label: 'MODBUS', value: 80 },
|
|
{ label: 'ADS', value: 81 },
|
|
{ label: '故障日志', value: 79 },
|
|
]
|
|
|
|
const protocolPartVisible = ref(false)
|
|
const protocolDisabled = ref(false)
|
|
const getProtocolParams = (val: string) => {
|
|
linkForm.value.params = val
|
|
}
|
|
const openProtocolPart = () => {
|
|
if (linkForm.value.protocol) {
|
|
protocolDisabled.value = false
|
|
protocolPartVisible.value = true
|
|
} else {
|
|
ElMessage.warning('请先选择协议类型')
|
|
}
|
|
}
|
|
const openParams = (data: linkType) => {
|
|
if (data.protocol) {
|
|
protocolDisabled.value = true
|
|
linkForm.value = { ...data }
|
|
protocolPartVisible.value = true
|
|
} else {
|
|
ElMessage.warning('请先设置协议类型')
|
|
}
|
|
}
|
|
const openlinkPoint = (data: linkType) => {
|
|
router.push({
|
|
name: 'univer',
|
|
query: {
|
|
protocol: data.protocol,
|
|
id: data.id,
|
|
prevPath: route.path,
|
|
treeKey: clickTreeData.value?.id,
|
|
},
|
|
})
|
|
}
|
|
|
|
getNodeList()
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
$paginationHeight: 32px;
|
|
|
|
.node {
|
|
width: 100%;
|
|
height: 100%;
|
|
.defaultSearchInput {
|
|
height: 40px;
|
|
}
|
|
.el-button {
|
|
width: 88px;
|
|
height: 40px;
|
|
}
|
|
.treeSearchPart {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
gap: 5px;
|
|
.el-button {
|
|
width: 35px;
|
|
}
|
|
}
|
|
.mainHeaderCenter {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
width: 320px;
|
|
.tableSearchInput {
|
|
width: 220px;
|
|
}
|
|
}
|
|
.tablePart {
|
|
height: calc(100% - $paginationHeight);
|
|
.el-button {
|
|
width: 88px;
|
|
height: 32px;
|
|
}
|
|
}
|
|
.tableOperate {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
a {
|
|
margin: 5px;
|
|
color: #0064aa;
|
|
font-weight: 600;
|
|
&:hover {
|
|
cursor: pointer;
|
|
}
|
|
}
|
|
}
|
|
.mainFooter {
|
|
display: flex;
|
|
justify-content: right;
|
|
background-color: #fff;
|
|
}
|
|
|
|
.modelOperate {
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
width: 80px;
|
|
height: 176px;
|
|
.el-button {
|
|
margin: 0;
|
|
}
|
|
}
|
|
}
|
|
</style>
|