用户、角色管理

This commit is contained in:
2023-05-15 17:24:55 +08:00
parent 15b6cfbd84
commit 7df4cc2e79
7 changed files with 520 additions and 79 deletions

View File

@@ -13,7 +13,7 @@
</div> </div>
<div class="dialog_footer"> <div class="dialog_footer">
<button class="button button--primary" @click="toCancle">取消</button> <button class="button button--primary" @click="toCancle">取消</button>
<button class="button button--primary">确定</button> <button class="button button--primary" @click="toSure">确定</button>
</div> </div>
</div> </div>
</div> </div>
@@ -25,7 +25,8 @@
export default { export default {
name: 'jxDialog', name: 'jxDialog',
props: { props: {
title: String title: String,
type: String
}, },
data () { data () {
return { return {
@@ -35,6 +36,11 @@ export default {
methods: { methods: {
toCancle () { toCancle () {
this.active = false this.active = false
this.$emit('toCancle', this.type)
},
toSure () {
this.active = false
this.$emit('toSure', this.type)
} }
} }
} }

View File

@@ -0,0 +1,297 @@
<template>
<div class="right_side">
<div class="buttons_wrapper">
<div class="row">
<button class="button button--primary" @click="showDialog('1')">新增角色</button>
</div>
</div>
<div class="row_2">
<div class="grid_wrapper">
<table>
<tr>
<th width="56px">选中</th>
<th width="100px">角色名称</th>
<th>描述</th>
<th width="115px">创建日期</th>
<th width="75px">操作</th>
</tr>
<tr v-for="(e, i) in datalist" :key="i">
<td>
<div class="radio__input icon_radio_checked"><i class="icon_radio"></i></div>
</td>
<td>超级管理员</td>
<td>垃圾分类几点睡浪费就冷冻机房蓝黛科技弗兰克</td>
<td>2023-05-05 08:50:08</td>
<td>
<div class="row">
<button class="button button--primary grid_button" @click="showDialog('2')">修改</button>
<button class="button button--primary grid_button" @click="showDialog('3')">删除</button>
</div>
</td>
</tr>
</table>
</div>
<div class="tree_wrapper">
<div class="tree_header">
<span>角色名称</span>
<button class="button button--primary grid_button button1">保存</button>
</div>
<div class="tree_body_container">
<div class="tree">
<div class="tree-node is-expanded is-focusable" v-for="(e, i) in tree" :key="i">
<div class="tree-node__content" style="padding-left: 0">
<span class="icon_tree-node__expand icon_caret_right"></span>
<div class="checkbox__input" @click="toCheck(e, tree)">
<i class="icon_checkbox" :class="{'icon_checkbox_checked': e.checked}"></i>
<input type="checkbox" class="checkbox__original" v-model="e.id">
</div>
<span class="tree-node__label">{{e.label}}</span>
</div>
<div class="tree-node__children">
<div class="tree-node is-expanded is-focusable" v-for="(el, j) in e.children" :key="j">
<div class="tree-node__content" style="padding-left: 24px">
<span class="icon_tree-node__expand icon_caret_right"></span>
<div class="checkbox__input" @click="toCheck(el, e.children)">
<i class="icon_checkbox" :class="{'icon_checkbox_checked': el.checked}"></i>
<input type="checkbox" class="checkbox__original" v-model="el.id">
</div>
<span class="tree-node__label">{{el.label}}</span>
</div>
<div class="tree-node__children">
<div class="tree-node is-expanded is-focusable" v-for="(ele, t) in el.children" :key="t">
<div class="tree-node__content" style="padding-left: 48px">
<span class="icon_tree-node__expand icon_caret_right"></span>
<div class="checkbox__input" @click="toCheck(ele, el.children)">
<i class="icon_checkbox" :class="{'icon_checkbox_checked': ele.checked}"></i>
<input type="checkbox" class="checkbox__original" v-model="ele.id">
</div>
<span class="tree-node__label">{{ ele.label }}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<jxDialog
ref="child"
:title="title"
:type="type"
@toSure="toSureDialog"
>
<div v-if="type === '1' || type === '2'" class="form_wraper">
<div class="form">
<div class="form_item">
<div class="form_item__label"><i>*</i>角色名称</div>
<div class="form_item__content">
<input type="text" class="form_item__input">
</div>
</div>
</div>
<div class="form">
<div class="form_item allwidth">
<div class="form_item__label">备注</div>
<div class="form_item__content">
<textarea v-model="remark" style="resize:none;" class="form_item__input form_item__textarea"></textarea>
</div>
</div>
</div>
</div>
<div v-if="type === '3'" class="form_wraper">确定删除该用户吗</div>
</jxDialog>
</div>
</template>
<script>
import jxDialog from '@components/dialog.vue'
export default {
components: {
jxDialog
},
data () {
return {
datalist: [{name: ''}, {name: 'a'}, {name: 'a'}, {name: ''}, {name: 'a'}, {name: 'a'}],
active: false,
type: '',
title: '',
remark: '',
tree: [{
id: '1',
label: '智能搬运车系统',
checked: false,
children: [{
id: '1-1',
label: '首页',
checked: false,
children: [{
id: '1-1-1',
label: '首页',
checked: false
}]
}, {
id: '1-2',
label: '任务管理',
checked: false,
children: [{
id: '1-2-1',
label: '搬运起点',
checked: false
}, {
id: '1-2-2',
label: '任务列表',
checked: false
}, {
id: '1-2-3',
label: '任务操作',
checked: false
}]
}, {
id: '1-3',
label: '故障管理',
checked: false,
children: [{
id: '1-3-1',
label: '故障处理',
checked: false
}]
}, {
id: '1-4',
label: '车辆信息',
checked: false,
children: [{
id: '1-4-1',
label: '车辆状态',
checked: false
}, {
id: '1-4-2',
label: '传感器状态',
checked: false
}, {
id: '1-4-3',
label: 'AGV',
checked: false
}, {
id: '1-5',
label: '示教',
checked: false,
children: [{
id: '1-5-1',
label: '地图',
checked: false
}, {
id: '1-5-2',
label: '绘制路线',
checked: false
}, {
id: '1-5-3',
label: '地图演示',
checked: false
}]
}, {
id: '1-6',
label: '系统管理',
checked: false,
children: [{
id: '1-6-1',
label: '用户管理',
checked: false
}, {
id: '1-6-2',
label: '角色管理',
checked: false
}, {
id: '1-6-3',
label: '系统参数',
checked: false
}, {
id: '1-6-4',
label: '开发者选项',
checked: false
}]
}]
}]
}]
}
},
watch: {
type (val) {
switch (val) {
case '1':
this.title = '添加角色'
break
case '2':
this.title = '修改角色'
break
case '3':
this.title = ''
break
default:
this.title = ''
}
}
},
methods: {
showDialog (type) {
this.type = type
this.$refs.child.active = true
},
toSureDialog (type) {
switch (type) {
case '1':
console.log(type)
break
case '2':
console.log(type)
break
case '3':
console.log(type)
break
default:
console.log(type)
}
},
toCheck (e, arr) {
arr.map(el => {
if (e.id === el.id) {
e.checked = !e.checked
}
})
}
}
}
</script>
<style lang="stylus" scoped>
@import '~@style/mixin'
.row_2
_fj()
_wh(100%, calc(100% - 50px))
.grid_wrapper
_wh(calc(50% - 10px), 100%)
overflow-y auto
.grid_wrapper table td
white-space normal
.button+.button
margin-left 0
margin-top 10px
.tree_wrapper
_wh(calc(50% - 10px), 100%)
overflow-y auto
.tree_header
position relative
z-index 99
background #d7d7d7
_font(14px, 23px, #323232, bold, center)
padding 12px 10px
.button1
position absolute
right 10px
top 10px
.tree_body_container
height calc(100% - 47px)
padding 12px 10px
</style>

View File

@@ -2,7 +2,7 @@
<div class="right_side"> <div class="right_side">
<div class="buttons_wrapper"> <div class="buttons_wrapper">
<div class="row"> <div class="row">
<button class="button button--primary" @click="addData">添加用户</button> <button class="button button--primary" @click="showDialog('1')">添加用户</button>
</div> </div>
</div> </div>
<div class="grid_wrapper"> <div class="grid_wrapper">
@@ -18,83 +18,87 @@
</tr> </tr>
<tr v-for="(e, i) in datalist" :key="i"> <tr v-for="(e, i) in datalist" :key="i">
<td>{{i+1}}</td> <td>{{i+1}}</td>
<td>{{e.name}}</td> <td>admin</td>
<td>{{e.name}}</td> <td>管理员</td>
<td></td> <td>18888888888</td>
<td></td> <td></td>
<td></td> <td>2023-05-05 08:50:08</td>
<td> <td>
<div class="row"> <div class="row">
<button class="button button--primary">修改</button> <button class="button button--primary grid_button" @click="showDialog('2')">修改</button>
<button class="button button--primary">分配角色</button> <button class="button button--primary grid_button" @click="showDialog('3')">重置密码</button>
<button class="button button--primary" @click="setPass">重置密码</button> <button class="button button--primary grid_button" @click="showDialog('4')">删除</button>
<button class="button button--primary">删除</button>
</div> </div>
</td> </td>
</tr> </tr>
</table> </table>
</div> </div>
<jxDialog <jxDialog
ref="child1" ref="child"
title="添加用户"> :title="title"
<div class="form"> :type="type"
<div class="form_item"> @toSure="toSureDialog"
<div class="form_item__label"><i>*</i>用户名</div> >
<div class="form_item__content"> <div v-if="type === '1' || type === '2'" class="form_wraper">
<input type="text" class="form_item__input"> <div class="form">
</div> <div class="form_item">
</div> <div class="form_item__label"><i>*</i>用户名</div>
<div class="form_item"> <div class="form_item__content">
<div class="form_item__label">电话</div> <input type="text" class="form_item__input" v-model="username">
<div class="form_item__content">
<input type="text" class="form_item__input">
</div>
</div>
</div>
<div class="form">
<div class="form_item">
<div class="form_item__label">姓名</div>
<div class="form_item__content">
<input type="text" class="form_item__input">
</div>
</div>
<div class="form_item">
<div class="form_item__label">性别</div>
<div class="form_item__content">
<div class="form_item__radio">
<div class="radio__input"><i class="iconfont icon_radio icon_radio_checked"></i></div>
<div class="radio__label"></div>
</div> </div>
<div class="form_item__radio"> </div>
<div class="radio__input"><i class="iconfont icon_radio"></i></div> <div class="form_item">
<div class="radio__label"></div> <div class="form_item__label">电话</div>
<div class="form_item__content">
<input type="text" class="form_item__input" v-model="phone">
</div>
</div>
</div>
<div class="form">
<div class="form_item">
<div class="form_item__label">姓名</div>
<div class="form_item__content">
<input type="text" class="form_item__input" v-model="name">
</div>
</div>
<div class="form_item">
<div class="form_item__label">性别</div>
<div class="form_item__content">
<div class="form_item__radio" v-for="(e, i) in sexArr" :key="i">
<div class="radio__input" :class="{'icon_radio_checked': e.value === sex}" @click="toRadio(e)">
<i class="icon_radio"></i>
<input type="radio" class="radio__original" v-model="e.value">
</div>
<div class="radio__label">{{ e.label }}</div>
</div>
</div>
</div>
</div>
<div class="form">
<div v-if="type === '1'" class="form_item">
<div class="form_item__label"><i>*</i>密码</div>
<div class="form_item__content">
<input type="text" class="form_item__input" v-model="password">
</div>
</div>
<div class="form_item">
<div class="form_item__label">角色</div>
<div class="form_item__content">
<el-select v-model="value" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="form"> <div v-if="type === '3'" class="form_wraper">确定重置密码吗</div>
<div class="form_item"> <div v-if="type === '4'" class="form_wraper">确定删除该用户吗</div>
<div class="form_item__label"><i>*</i>密码</div>
<div class="form_item__content">
<input type="text" class="form_item__input">
</div>
</div>
<div class="form_item">
<div class="form_item__label">角色</div>
<div class="form_item__content">
<el-select v-model="value" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
</div>
</div>
</jxDialog> </jxDialog>
<jxDialog ref="child2">确定重置密码吗</jxDialog>
</div> </div>
</template> </template>
@@ -106,7 +110,16 @@ export default {
}, },
data () { data () {
return { return {
datalist: [{name: 'a氪金大佬发家里的饭交流交流'}, {name: 'a'}, {name: 'a'}, {name: 'a'}, {name: 'a'}, {name: 'a'}, {name: 'a'}, {name: 'ac'}, {name: 'a'}, {name: 'a'}, {name: 'a'}, {name: 'a'}, {name: 'a'}, {name: 'a'}, {name: 'ad'}], datalist: [{name: ''}, {name: 'a'}, {name: 'a'}, {name: 'a'}, {name: 'a'}, {name: 'a'}, {name: 'a'}],
active: false,
type: '',
title: '',
username: '',
phone: '',
name: '',
sexArr: [{label: '男', value: '1'}, {label: '女', value: '2'}],
sex: '1',
password: '',
options: [{ options: [{
value: '选项1', value: '选项1',
label: '超级管理员' label: '超级管理员'
@@ -120,16 +133,54 @@ export default {
value: '选项4', value: '选项4',
label: '开发人员' label: '开发人员'
}], }],
value: '', value: ''
active: false }
},
watch: {
type (val) {
switch (val) {
case '1':
this.title = '添加用户'
break
case '2':
this.title = '修改用户'
break
case '3':
this.title = ''
break
case '4':
this.title = ''
break
default:
this.title = ''
}
} }
}, },
methods: { methods: {
addData () { showDialog (type) {
this.$refs.child1.active = true this.type = type
this.$refs.child.active = true
}, },
setPass () { toSureDialog (type) {
this.$refs.child2.active = true switch (type) {
case '1':
console.log(type)
break
case '2':
console.log(type)
break
case '3':
console.log(type)
break
case '4':
console.log(type)
break
default:
console.log(type)
}
},
toRadio (e) {
this.sex = e.value
} }
} }
} }

View File

@@ -191,6 +191,8 @@
color: #606266; color: #606266;
font-size: 14px; font-size: 14px;
word-break: break-all; word-break: break-all;
.form_wraper
width 100%
.form .form
width 100% width 100%
_fj(flex-start) _fj(flex-start)
@@ -234,10 +236,13 @@
padding: 0 15px; padding: 0 15px;
transition: border-color .2s cubic-bezier(.645,.045,.355,1); transition: border-color .2s cubic-bezier(.645,.045,.355,1);
width: 100%; width: 100%;
.form_item__textarea
line-height 23px
height 69px
.form_item__radio .form_item__radio
color: #606266; color: #606266;
font-weight: 500; font-weight: 500;
line-height: 1; line-height: 40px;
position: relative; position: relative;
cursor: pointer; cursor: pointer;
display: inline-block; display: inline-block;
@@ -256,14 +261,25 @@
padding: 2px padding: 2px
position: relative; position: relative;
vertical-align: middle; vertical-align: middle;
border 1px solid $gray1 border 1px solid $green1
background-color #fff
border-radius 50% border-radius 50%
.radio__label .radio__label
display: inline-block; display: inline-block;
font-size: 14px; font-size: 14px;
padding-left: 10px; padding-left: 10px;
.icon_radio_checked .icon_radio_checked
color $red2 background-color $green1
.radio__original
opacity: 0;
outline: none;
position: absolute;
z-index: -1;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: 0;
.el-select .el-select
width 100% width 100%
.el-select:hover .el-input__inner, .el-input__inner .el-select:hover .el-input__inner, .el-input__inner
@@ -298,7 +314,6 @@
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap;
text-align: center; text-align: center;
position: sticky; position: sticky;
top: -1px; top: -1px;
@@ -314,7 +329,6 @@
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap;
padding: 12px 10px; padding: 12px 10px;
border-bottom: 1px dashed $gray1; border-bottom: 1px dashed $gray1;
border-right: 1px dashed $gray1; border-right: 1px dashed $gray1;
@@ -333,3 +347,70 @@
position: sticky; position: sticky;
left: 0; left: 0;
z-index: 99; z-index: 99;
.grid_button
padding 6px 12px
// tree
.tree
position: relative;
cursor: default;
background: #fff;
color: #606266;
.tree-node
white-space: nowrap;
outline: none;
.tree-node__content
display: flex;
align-items: center;
height: 26px;
cursor: pointer;
.icon_tree-node__expand
cursor: pointer;
color: #c0c4cc;
font-size: 12px;
transform: rotate(0deg);
transition: transform .3s ease-in-out;
padding: 6px;
&::before
content: '\e65b'
.icon_caret_right
transform rotate(-90deg)
.checkbox__input
color: #606266;
font-weight: 500;
font-size: 12px;
position: relative;
cursor: pointer;
display: inline-block;
white-space: nowrap;
user-select: none;
margin-right: 8px
cursor: pointer;
.icon_checkbox
white-space: nowrap;
cursor: pointer;
outline: none;
display: inline-block;
padding: 2px;
position: relative;
vertical-align: middle;
color #fff
border: 1px solid $green1
background-color: #fff;
border-radius 3px
&::before
content: '\E608'
.icon_checkbox_checked
background-color $green1
.checkbox__original
opacity: 0;
outline: none;
position: absolute;
margin: 0;
width: 0;
height: 0;
z-index: -1;
.tree-node__label
font-size: 14px
.tree-node__children
overflow hidden

View File

@@ -15,6 +15,7 @@
&::before &::before
content '\e659' content '\e659'
.icon_radio .icon_radio
position relative
color #ffffff color #ffffff
&::before &::before
content '\e608' content '\e608'

View File

@@ -2,6 +2,7 @@ $red = #FD6A35
$red1 = #E74F19 $red1 = #E74F19
$red2 = #FA6400 $red2 = #FA6400
$green = #6CBE8B $green = #6CBE8B
$green1 = #00d246
$yellow = #E9B451 $yellow = #E9B451
$blue = #6798ef $blue = #6798ef
$gray = #989EBB $gray = #989EBB

View File

@@ -103,7 +103,11 @@ input::-webkit-input-placeholder {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.allwidth {
width: 100% !important;
}
.fl { .fl {
float: left !important; float: left !important;
} }