Files
tunnel-cloud-web/src/views/user/index.vue

851 lines
21 KiB
Vue

<template>
<div class="tunnel-bgc">
<div class="box-top">
<div class="back-tunnel" @click="handleGoHome">
<div class="back-icon"></div>
<span>返回</span>
</div>
<tunnel-title/>
<div class="all-del-btn">
<!-- <div class="all-btn" @click="handleAll">-->
<!-- 全选-->
<!-- </div>-->
<!-- <div class="all-btn del-btn" @click="handleDelete">-->
<!-- 删除-->
<!-- </div>-->
</div>
</div>
<div class="user-content">
<div class="user-box">
<div class="user-top">
<div class="search-box">
<div>
<el-input
v-model="username"
clearable
placeholder="输入搜索内容"
@clear="getInfo"
/>
</div>
<el-button type="primary" :icon="Search" style="margin-left: 20px" @click="getInfo">搜索</el-button>
</div>
<div>用户管理</div>
<div class="all-del-btn">
<div class="add-btn" @click="handleAddUser">添加用户</div>
<div class="all-btn del-btn" @click="handleDelete">
删除
</div>
</div>
</div>
<div class="device-table">
<el-table stripe ref="multipleTable" @select="handleSelect"
style="border-bottom: 1px #06e5e5 solid;background-color: #011c29;--el-table-border-color: none;margin-top: 80px;"
:header-cell-style="{backgroundColor: '#064B66',color: '#fff',fontSize: '40px',borderBottom: 'none' }"
:cell-style="{textAlign: 'center',borderBottom: 'none'}" :data="userData">
<el-table-column type="selection" width="80"/>
<el-table-column prop="userName" label="账户" align="center"/>
<el-table-column prop="nickName" label="昵称" align="center"/>
<el-table-column prop="roleName" label="身份" align="center"/>
<el-table-column prop="phoneNumber" label="电话号码" align="center"/>
<el-table-column prop="state" label="状态" align="center">
<template #default="scope">
{{ scope.row.state == "1" ? '启用' : '停用' }}
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button link type="primary" size="large" style="font-size: 40px;color: #17E1E2;"
@click="handleEditUser(scope.row)">
修改
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
<el-dialog :close-on-click-modal="false" v-model="isVisited" width="1658px">
<div class="user-title">
<span>{{ title }}</span>
</div>
<el-form :model="form" :label-position="right" :rules="formRules" ref="formInstance" label-width="240px">
<el-form-item label="当前站点">
<div class="current-site">{{ currentSite }}<span v-if="showAdmin">如果需要切换站点,请返回首屏切换</span></div>
</el-form-item>
<el-form-item label="输入用户名" prop="userName">
<el-input v-model="form.userName" placeholder="请输入用户名"/>
</el-form-item>
<el-form-item label="输入密码" v-if="title==='添加用户'" prop="password">
<el-input type="password" show-password v-model="form.password" placeholder="请输入密码"/>
</el-form-item>
<el-form-item label="输入昵称" prop="nickName">
<el-input v-model="form.nickName" placeholder="请输入昵称"/>
</el-form-item>
<el-form-item label="输入电话号码" prop="phoneNumber">
<el-input v-model="form.phoneNumber" placeholder="输入电话号码"/>
</el-form-item>
<el-form-item label="是否启用">
<el-radio-group v-model="form.state">
<el-radio label="1">启用</el-radio>
<el-radio label="0">停用</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="选择身份" prop="roleId">
<el-radio-group v-model="form.roleId" @change="(val) => {
if (val >3){
getTunnel()
}}">
<el-radio v-for="item in radioList" :label="item.value" :key="item.value">{{ item.label }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="选择隧道" v-if="form.roleId>3" prop="tunnelList">
<div class="user-select">
<el-select
v-model="form.tunnelList"
multiple
filterable
clearable
placeholder="请选择隧道"
:fit-input-width="true"
:teleported="false"
>
<el-option
v-for="item in tunnelList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
</el-form-item>
</el-form>
<template #footer>
<div class="btns">
<div class="cancel-btn" @click="isVisited=false">
取消
</div>
<div class="sure-btn" @click="handleSubmit(formInstance)">
确定
</div>
</div>
</template>
</el-dialog>
<div class="pagination">
<span @click="firstPage" v-if="showFirst">首页</span>
<el-pagination background v-model:current-page="pageInfo.pageNum" v-model:page-size="pageInfo.pageSize"
:total="total" prev-text="上一页" next-text="下一页" layout="prev, pager, next"
@current-change="handleCurrentChange" :hide-on-single-page="true"/>
<span @click="lastPage" v-if="showFirst">尾页</span>
</div>
</div>
</template>
<script setup>
import {Search} from '@element-plus/icons-vue'
import {addUser, editUser, getUser, getRoleOption, deleteUser, getUserDetail} from "@/api/user";
import {ElLoading, ElMessage, ElMessageBox} from "element-plus";
import {getTunnelOption} from "@/api/tunnel";
import TunnelTitle from "@/components/tunnelTitle/index.vue";
const router = useRouter()
const title = ref('添加用户')
const siteId = reactive(router.currentRoute.value.params.siteId)
const currentSite = ref(localStorage.getItem('site'))
const username = ref()
const userIds = ref()
const showFirst = ref(true)
const formInstance = ref()
const userData = ref([])
const pageInfo = reactive({
pageNum: 1,
pageSize: 10
});
const total = ref(10);
const isVisited = ref(false);
const showAdmin = ref(false);
const form = ref({
password: '',
userName: '',
nickName: '',
phoneNumber: '',
state: '1',
roleId: 3,
tunnelList: [1]
});
const validateName = (rule, value) => {
const reg = /^[A-Za-z0-9]+$/;
return reg.test(value);
}
const formRules = ref({
userName: [
{required: true, message: '请输入用户名', trigger: ['blur', 'change']},
{validator: validateName, message: '请输入英文、数字、英文数字组合的用户名', trigger: ['blur', 'change']}
],
password: [{required: true, message: '请输入密码', trigger: ['blur', 'change']}],
nickName: [{required: true, message: '请输入昵称', trigger: ['blur', 'change']}],
roleId: [{required: true, message: '请选择身份', trigger: ['blur', 'change']}],
tunnelList: [{required: true, message: '请选择隧道', trigger: ['blur', 'change']}]
})
const radioList = ref([])
const tunnelList = ref([])
const multipleTable = ref()
onMounted(() => {
showAdmin.value = localStorage.getItem('userId') == 2;
})
const handleGoHome = () => {
router.push('/' + 'userToHome/' + siteId)
}
const getTunnel = () => {
getTunnelOption(siteId).then(res => {
if (res.code === 1000) {
tunnelList.value = res.data
}
})
}
const handleAddUser = () => {
reset()
title.value = '添加用户'
isVisited.value = true
nextTick(() => {
// 清空校验
formInstance.value.clearValidate()
})
}
const handleEditUser = (row) => {
reset()
const loading = ElLoading.service({
lock: true,
text: '正在加载系统资源...',
background: 'rgba(0, 0, 0, 0.7)',
customClass:'allLoading'
})
getUserDetail(row.userId).then(res => {
if (res.code === 1000) {
getTunnel()
form.value = res.data.user
form.value.roleId = res.data.roleIds[0]
form.value.tunnelList = res.data.user.tunnelList
title.value = '修改用户'
isVisited.value = true
}
loading.close()
})
}
const handleDelete = () => {
if (userIds.value === undefined) {
ElMessage.warning('请先选择用户进行删除')
} else {
ElMessageBox.confirm(`是否确认删除该用户吗?`, '系统提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteUser(userIds.value).then(res => {
if (res.code === 1000) {
ElMessage.success(res.msg)
getInfo()
}
})
})
}
}
const reset = () => {
form.value = {
password: '',
userName: '',
nickName: '',
phoneNumber: '',
state: '1',
roleId: 3,
tunnelList: []
}
}
const getRoleOptionInfo = () => {
getRoleOption().then(res => {
if (res.code === 1000) {
radioList.value = res.data
}
})
}
getRoleOptionInfo()
const getInfo = () => {
const loading = ElLoading.service({
lock: true,
text: '正在加载系统资源...',
background: 'rgba(0, 0, 0, 0.7)',
customClass:'allLoading'
})
getUser({
siteId: siteId,
userName: username.value,
...pageInfo
}).then(res => {
if (res.code === 1000) {
userData.value = res.data.rows
total.value = res.data.total
showFirst.value = total.value / pageInfo.pageSize >= 1;
}
loading.close()
})
}
getInfo()
const firstPage = () => {
pageInfo.pageNum = 1
getInfo()
}
const lastPage = () => {
pageInfo.pageNum = total.value / pageInfo.pageSize
getInfo()
}
//点击页码进行分页功能
const handleCurrentChange = (val) => {
pageInfo.pageNum = val
getInfo()
}
const handleSubmit = (formInstance) => {
if (!formInstance) return;
formInstance.validate((valid) => {
if (!valid) return;
const data = {
siteId: siteId,
nickName: form.value.nickName,
password: form.value.password,
phoneNumber: form.value.phoneNumber,
state: form.value.state,
userName: form.value.userName,
roleIds: [form.value.roleId],
tunnelList: form.value.tunnelList
}
if (title.value === '添加用户') {
addUser(data).then(res => {
if (res.code === 1000) {
getInfo()
isVisited.value = false
ElMessage.success(res.msg)
} else {
ElMessage.warning(res.msg)
}
})
} else {
const editData = {
userId: form.value.userId,
...data
}
editUser(editData).then(res => {
if (res.code === 1000) {
getInfo()
isVisited.value = false
ElMessage.success(res.msg)
} else {
ElMessage.warning(res.msg)
}
})
}
})
}
const handleSelect = async (selection, row) => {
if (selection.length !== 0) {
// disabled.value = false
userIds.value = row.userId
if (selection.length > 1) {
const del_row = selection.shift();
multipleTable.value.toggleRowSelection(del_row, false);
}
} else {
// disabled.value = true
}
}
</script>
<style lang="scss">
.user-select {
.el-select__wrapper.is-hovering {
.el-select__suffix {
.el-icon {
font-size: 40px;
}
}
}
.el-select__wrapper {
min-height: 75px;
height: auto !important;
background-color: transparent;
border: 1px solid #08B7B8;
font-size: 35px;
width: 476px;
}
.el-select__placeholder.is-transparent {
height: 54px;
line-height: 54px;
}
.el-select__selected-item {
//height: 54px;
//line-height: 54px;
.el-tag {
max-width: none !important;
height: 55px;
font-size: 43px;
.el-icon {
font-size: 51px;
width: auto;
height: auto;
}
}
}
.el-select__caret {
font-size: 35px !important;
}
.el-select-dropdown__item.is-hovering {
background-color: #064B66 !important;
}
.el-select-dropdown.is-multiple .el-select-dropdown__item.is-selected:after {
width: 42px;
height: 42px;
}
.el-input {
min-height: 75px;
height: auto !important;
}
.el-form-item.is-error .el-input__wrapper {
box-shadow: none;
}
.el-select__popper {
margin-top: -12px !important;
background: #072247 !important;
border: 1px solid #0F82AF !important;
}
.el-popper {
width: auto;
min-width: auto;
margin-left: 0;
box-sizing: border-box;
}
.el-popper__arrow::before {
display: none;
}
.el-select-dropdown__item {
font-size: 38px !important;
height: 60px !important;
line-height: 60px !important;
> span {
color: #FFFFFF;
}
}
.el-select .el-input .el-select__caret {
font-size: 35px !important;
}
.el-select-dropdown__item.hover, .el-select-dropdown__item:hover {
background-color: #064B66 !important;
}
.el-select-dropdown.is-multiple .el-select-dropdown__item.selected {
background-color: #064B66 !important;
}
.el-select-tags-wrapper {
.el-tag {
padding: 28px 20px !important;
font-size: 35px;
.el-icon {
width: 40px;
height: 40px;
font-size: 40px !important;
}
}
}
}
</style>
<style scoped lang="scss">
:deep(.el-select__tags .el-tag--info) {
background-color: #05FEFF;
color: #000;
}
:deep(.el-form-item__error) {
font-size: 35px;
}
:deep(.el-input .el-input__password) {
font-size: 60px;
}
:deep(.el-input__clear) {
font-size: 40px;
}
.current-site {
font-size: 41px;
color: #FFFFFF;
margin-top: 12px;
> span {
font-size: 38px !important;
color: darkgray !important;
margin-left: 20px;
}
}
:deep(.el-table__header-wrapper .el-checkbox) {
display: none
}
:deep(.el-radio-group) {
margin-top: 10px;
}
:deep(.el-radio__label) {
color: #FFFFFF;
font-size: 38px;
}
:deep(.el-radio__inner) {
width: 40px;
height: 40px;
border-radius: 25px;
border: 4px solid #05FEFF;
background-color: transparent;
}
:deep(.el-radio__input.is-checked+.el-radio__label) {
color: #FFFFFF;
}
:deep(.el-radio__input.is-checked .el-radio__inner ) {
background: #064B66;
border-color: #05FEFF !important;
}
:deep(.el-radio__inner::after) {
width: 18px;
height: 18px;
background: #05FEFF;
}
.user-title {
display: flex;
justify-content: center;
margin: 0 0 60px 0;
font-size: 50px;
color: #FFFFFF;
}
:deep(.el-table__empty-block) {
background: #064B66;
font-size: 30px;
min-height: 200px;
}
.tunnel-bgc {
padding: 85px 0 0 0;
width: 100%;
height: 100%;
background-image: url('@/assets/images/tunnel/sd_bj.png');
.box-top {
display: flex;
justify-content: space-between;
.back-tunnel {
cursor: pointer;
margin: 0 0 0 70px;
display: flex;
align-items: center;
width: 178px;
height: 70px;
line-height: 70px;
border-radius: 11px;
border: 2px solid #08B7B8;
font-size: 38px;
color: #FFFFFF;
.back-icon {
margin-right: 20px;
margin-left: 23px;
width: 33px;
height: 33px;
background-image: url('@/assets/images/site/zdgl_icon_fh.png');
}
}
}
.all-del-btn {
display: flex;
.del-btn {
width: 168px;
height: 60px;
background: #08B7B8;
border-radius: 11px;
}
.all-btn {
cursor: pointer;
padding-left: 53px;
width: 178px;
height: 70px;
line-height: 70px;
border-radius: 11px;
border: 2px solid #08B7B8;
color: #FFFFFF;
font-size: 38px;
&:last-child {
margin-left: 40px;
}
}
}
.user-content {
display: flex;
justify-content: center;
margin-top: 247px;
.user-box {
display: flex;
flex-direction: column;
width: 2194px;
height: 1480px;
background: #064B66;
border-radius: 20px;
border: 2px solid #05FEFF;
box-sizing: border-box;
padding: 73px 58px;
.user-top {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
> div:nth-child(2) {
margin-left: -250px;
height: 61px;
font-size: 46px;
font-weight: bold;
color: #FFFFFF;
line-height: 61px;
}
.add-btn {
cursor: pointer;
width: 180px;
height: 70px;
line-height: 70px;
background: #08B7B8;
border-radius: 6px;
color: #FFFFFF;
font-size: 38px;
padding-left: 19px;
//margin-left: 20px;
}
.search-box {
display: flex;
:deep(.el-button) {
width: 140px;
height: 70px;
background: #08B7B8;
border-radius: 6px;
border: none;
font-size: 38px;
color: #FFFFFF;
}
//:deep(.el-input__wrapper) {
// width: 300px;
// height: 70px;
// border-radius: 6px;
// border: 1px solid #05FEFF;
// background-color: transparent;
// font-size: 38px;
//
// .el-input__inner {
// height: 70px;
// line-height: 70px;
// color: #FFFFFF;
// }
//}
}
}
:deep(.el-table--fit) {
width: 2110px !important;
}
:deep(.cell) {
height: 80px;
line-height: 80px;
color: #fff;
font-size: 38px;
}
:deep(.el-table tr) {
background-color: #1C5971;
}
:deep(.el-table--enable-row-hover .el-table__body tr:hover>td.el-table__cell) {
background-color: #1C5971;
}
:deep(.el-table__row--striped) {
background-color: #13849C !important;
}
:deep(.el-table--striped .el-table__body tr.el-table__row--striped td.el-table__cell) {
background-color: #13849C !important;
}
:deep(.el-table__inner-wrapper::before) {
display: none;
}
}
}
:deep(.el-dialog) {
border: 2px solid #05FEFF;
background: #0D6578;
border-radius: 20px;
padding: 30px 40px;
box-sizing: border-box;
margin: 458px auto 0 auto;
.el-dialog__header {
padding: 0;
display: none;
}
}
:deep(.el-form-item) {
margin-top: 40px;
}
:deep(.el-form-item__label) {
font-size: 38px;
font-family: MicrosoftYaHei;
color: #FFFFFF;
margin-right: 12px;
line-height: 50px;
}
:deep(.el-input) {
height: 75px;
.el-input__wrapper {
background-color: transparent;
border: 1px solid #08B7B8;
.el-input__inner {
height: auto;
color: #fff;
font-size: 38px;
}
}
}
.pagination {
position: absolute;
left: 50%;
transform: translate(-50%, -50%);
bottom: 90px;
display: flex;
align-items: center;
color: #60DDDE;
font-size: 38px;
font-weight: bold;
:deep(.el-pagination.is-background ) {
.btn-next,.btn-prev {
background-color: transparent;
}
.el-pager {
li {
margin: 0 0 0 40px;
}
li.is-active {
background-color: #60DDDE;
}
}
}
> span:first-child {
cursor: pointer;
margin-right: 60px;
}
> span:last-child {
cursor: pointer;
margin-left: 71px;
}
:deep(.btn-prev) {
background-color: transparent;
font-size: 38px;
font-family: MicrosoftYaHei, MicrosoftYaHei;
font-weight: bold;
color: #60DDDE;
margin-right: 20px;
}
:deep(.btn-next) {
background-color: transparent;
font-size: 38px;
font-family: MicrosoftYaHei, MicrosoftYaHei;
font-weight: bold;
color: #60DDDE;
margin-left: 30px;
}
:deep(.el-pager li.is-active ) {
width: 70px;
height: 70px;
background: #60DDDE;
border-radius: 50%;
color: #071F40;
font-size: 38px;
font-family: MicrosoftYaHei, MicrosoftYaHei;
font-weight: bold;
}
:deep(.el-pager li) {
margin-left: 40px;
}
:deep(.el-pager li:not(.is-active) ) {
width: 70px;
height: 70px;
border: 1px solid #60DDDE;
border-radius: 50%;
background-color: transparent;
font-size: 38px;
font-family: MicrosoftYaHei, MicrosoftYaHei;
font-weight: bold;
color: #60DDDE;
}
}
}
</style>