初始化项目
This commit is contained in:
@@ -0,0 +1,309 @@
|
||||
<template>
|
||||
<a-modal
|
||||
title="新增角色"
|
||||
:width="720"
|
||||
:visible="visible"
|
||||
:confirmLoading="confirmLoading"
|
||||
:maskClosable="false"
|
||||
@ok="handleSubmit"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<a-spin :spinning="confirmLoading">
|
||||
<a-form :form="form">
|
||||
<a-form-item label="角色名称" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-input
|
||||
v-decorator="['role_name', {rules: [{required: true, min: 2, message: '请输入至少2个字符'}]}]"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="上级角色" :labelCol="labelCol" :wrapperCol="wrapperCol">
|
||||
<a-tree-select
|
||||
:treeData="roleListTree"
|
||||
:dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
allowClear
|
||||
v-decorator="['parent_id']"
|
||||
></a-tree-select>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
label="菜单权限"
|
||||
:labelCol="labelCol"
|
||||
:wrapperCol="wrapperCol"
|
||||
extra="设置该角色有权操作的功能"
|
||||
>
|
||||
<a-tree
|
||||
ref="MenuTree"
|
||||
v-model="checkedKeys"
|
||||
checkable
|
||||
checkStrictly
|
||||
:treeData="menuListTreeData"
|
||||
:autoExpandParent="false"
|
||||
@check="onCheckedMenu"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="排序" :labelCol="labelCol" :wrapperCol="wrapperCol" extra="数字越小越靠前">
|
||||
<a-input-number
|
||||
:min="0"
|
||||
v-decorator="['sort', {initialValue: 100, rules: [{required: true, message: '请输入至少1个数字'}]}]"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as Api from '@/api/store/role'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
// 角色列表
|
||||
roleList: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
// 菜单列表
|
||||
menuList: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
// 对话框标题
|
||||
title: '',
|
||||
// 标签布局属性
|
||||
labelCol: {
|
||||
span: 7
|
||||
},
|
||||
// 输入框布局属性
|
||||
wrapperCol: {
|
||||
span: 13
|
||||
},
|
||||
// modal(对话框)是否可见
|
||||
visible: false,
|
||||
// modal(对话框)确定按钮 loading
|
||||
confirmLoading: false,
|
||||
// 当前表单元素
|
||||
form: this.$form.createForm(this),
|
||||
// 上级角色列表
|
||||
roleListTree: [],
|
||||
// 菜单列表 树状结构
|
||||
menuListTreeData: [],
|
||||
// 当前选中的keys
|
||||
checkedKeys: {
|
||||
checked: [],
|
||||
halfChecked: []
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
/**
|
||||
* 显示对话框
|
||||
*/
|
||||
add () {
|
||||
// 显示窗口
|
||||
this.visible = true
|
||||
// 获取角色列表
|
||||
this.getRoleList()
|
||||
// 获取API权限列表
|
||||
this.getMenuList()
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取菜单列表
|
||||
*/
|
||||
getMenuList () {
|
||||
const { menuList } = this
|
||||
this.menuListTreeData = this.formatTreeDataForMenuList(menuList)
|
||||
},
|
||||
|
||||
// 节点选中事件
|
||||
onCheckedMenu (checkedKeys, { checked, node }) {
|
||||
// 寻找当前选择的节点
|
||||
const { menuListTreeData } = this
|
||||
const nodeData = this.findNode(node.eventKey, menuListTreeData)
|
||||
// 选择节点时联动所有子节点
|
||||
this.onCheckChilds(checked, nodeData)
|
||||
// 选择节点时联动所有父节点
|
||||
this.onCheckParents(checked, nodeData)
|
||||
},
|
||||
|
||||
// 寻找指定的的节点
|
||||
findNode (key, list) {
|
||||
for (let index = 0; index < list.length; index++) {
|
||||
const item = list[index]
|
||||
if (item.key === key) {
|
||||
return item
|
||||
} else if (item.children) {
|
||||
const result = this.findNode(key, item.children)
|
||||
if (result) {
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
},
|
||||
|
||||
// 选择节点时联动所有父节点
|
||||
onCheckParents (checked, node) {
|
||||
// 查找所有父节点(方法)
|
||||
const { menuListTreeData } = this
|
||||
const findParentKeys = (parentKey) => {
|
||||
let keys = []
|
||||
const parent = this.findNode(parentKey, menuListTreeData)
|
||||
if (!parent) {
|
||||
return keys
|
||||
}
|
||||
keys.push(parent.key)
|
||||
if (parent.children) {
|
||||
const arr = findParentKeys(parent.parentKey)
|
||||
arr.length && (keys = keys.concat(arr))
|
||||
}
|
||||
return keys
|
||||
}
|
||||
// 查找所有父节点
|
||||
const parentKeys = findParentKeys(node.parentKey)
|
||||
// 设置为选中
|
||||
if (checked && parentKeys.length) {
|
||||
this.checkedKeys.checked = _.union(this.checkedKeys.checked, parentKeys)
|
||||
}
|
||||
},
|
||||
|
||||
// 选择节点时联动所有子节点
|
||||
onCheckChilds (checked, node) {
|
||||
// 获取当前节点的所有子级ID
|
||||
const childKeys = node.children ? this.getAllMenuKeys(node.children) : []
|
||||
if (childKeys.length) {
|
||||
this.checkedKeys.checked = checked ? _.union(this.checkedKeys.checked, childKeys) : _.difference(this.checkedKeys.checked, childKeys)
|
||||
}
|
||||
},
|
||||
|
||||
// 获取菜单列表中所有子级的id
|
||||
getAllMenuKeys (list) {
|
||||
let keysArr = []
|
||||
list.forEach(item => {
|
||||
keysArr.push(item.key)
|
||||
if (item.children && item.children.length) {
|
||||
const childrenArr = this.getAllMenuKeys(item.children)
|
||||
childrenArr.length && (keysArr = keysArr.concat(childrenArr))
|
||||
}
|
||||
})
|
||||
return keysArr
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取角色列表
|
||||
*/
|
||||
getRoleList () {
|
||||
const { roleList } = this
|
||||
// 格式化角色列表
|
||||
const selectList = this.formatTreeForRoleList(roleList)
|
||||
// 顶级角色
|
||||
selectList.unshift({
|
||||
title: '顶级角色',
|
||||
key: 0,
|
||||
value: 0
|
||||
})
|
||||
this.roleListTree = selectList
|
||||
},
|
||||
|
||||
/**
|
||||
* 格式化角色列表
|
||||
*/
|
||||
formatTreeForRoleList (list) {
|
||||
const data = []
|
||||
list.forEach(item => {
|
||||
// 新的元素
|
||||
const netItem = {
|
||||
title: item.role_name,
|
||||
key: item.role_id,
|
||||
value: item.role_id
|
||||
}
|
||||
// 递归整理子集
|
||||
if (item.children && item.children.length) {
|
||||
netItem['children'] = this.formatTreeForRoleList(item['children'])
|
||||
}
|
||||
data.push(netItem)
|
||||
})
|
||||
return data
|
||||
},
|
||||
|
||||
// 格式化菜单列表
|
||||
formatTreeDataForMenuList (list) {
|
||||
const data = []
|
||||
list.forEach(item => {
|
||||
// 新的元素
|
||||
const netItem = {
|
||||
title: item.name,
|
||||
key: item.menu_id,
|
||||
parentKey: item.parent_id
|
||||
}
|
||||
// 递归整理子集
|
||||
if (item.children && item.children.length) {
|
||||
netItem['children'] = this.formatTreeDataForMenuList(item['children'])
|
||||
}
|
||||
data.push(netItem)
|
||||
})
|
||||
return data
|
||||
},
|
||||
|
||||
/**
|
||||
* 确认按钮
|
||||
*/
|
||||
handleSubmit (e) {
|
||||
e.preventDefault()
|
||||
// 表单验证
|
||||
const { form: { validateFields } } = this
|
||||
validateFields((errors, values) => {
|
||||
// 提交到后端api
|
||||
if (!errors) {
|
||||
this.onFormSubmit({ ...values, menus: this.getCheckedKeys() })
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取所有选中的节点(菜单)
|
||||
*/
|
||||
getCheckedKeys () {
|
||||
const { $refs: { MenuTree } } = this
|
||||
return [
|
||||
...MenuTree.getCheckedKeys(),
|
||||
...MenuTree.getHalfCheckedKeys()
|
||||
]
|
||||
},
|
||||
|
||||
/**
|
||||
* 关闭对话框事件
|
||||
*/
|
||||
handleCancel () {
|
||||
this.visible = false
|
||||
this.form.resetFields()
|
||||
const { $refs: { MenuTree } } = this
|
||||
MenuTree.clearExpandedKeys()
|
||||
this.checkedKeys.checked = []
|
||||
},
|
||||
|
||||
/**
|
||||
* 提交到后端api
|
||||
*/
|
||||
onFormSubmit (values) {
|
||||
this.confirmLoading = true
|
||||
Api.add({ form: values })
|
||||
.then((result) => {
|
||||
// 显示成功
|
||||
this.$message.success(result.message, 1.5)
|
||||
// 关闭对话框事件
|
||||
this.handleCancel()
|
||||
// 通知父端组件提交完成了
|
||||
this.$emit('handleSubmit', values)
|
||||
})
|
||||
.finally((result) => {
|
||||
this.confirmLoading = false
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user