<template>
	<div class="page-container">
		<div class="content-container">
			<div class="main">
				<div class="table-nav">
					<div class="tags">
						<div class="tag" :class="{ activeClass: over == 1 }" @click="getRole">角色</div>
						<div class="tag" :class="{ activeClass: over == 2 }" @click="getFunctionalAuthority">功能权限</div>
						<div class="tag" :class="{ activeClass: over == 3 }" @click="getHeaderPermission">表头权限</div>
					</div>
					<div class="actions">
						<el-button type="primary" icon="el-icon-plus" size="mini " @click="handleAdd" v-show="roleShow" v-hasPermi="['system:role:add']">添加</el-button>
					</div>
				</div>

				<!-- 角色列表 -->
				<el-table v-loading="loading" :data="roleList" :cell-style="{ cursor: 'pointer' }" border @row-click="roleLineClick" v-show="roleShow">
					<el-table-column label="名称" prop="roleName" width="200">
						<template slot-scope="scope">
							<a href="javascript:void(0);" class="linked" @click="roleLineDbclick(scope.row)">{{ scope.row.roleName }}</a>
						</template>
					</el-table-column>
					<el-table-column label="描述" prop="remark" />
					<el-table-column align="center" label="创建时间" prop="createTime" width="200">
						<template slot-scope="scope">
							<span>{{ parseTime(scope.row.createTime) }}</span>
						</template>
					</el-table-column>
					<el-table-column align="center" label="状态" width="117" prop="status">
						<template slot-scope="scope">
							<span>{{ scope.row.status == 0 ? '正常' : '停用' }}</span>
						</template>
					</el-table-column>
					<el-table-column align="center" label="操作" class-name="small-padding fixed-width" width="300">
						<template slot-scope="scope">
							<el-button size="mini" type="text" icon="el-icon-edit" v-hasPermi="['system:role:edit']" @click="handleUpdate(scope.row)">修改</el-button>
							<el-button size="mini" type="text" icon="el-icon-remove-outline" @click="handleStatusChange(scope.row)">{{ scope.row.status == '0' ? '禁用' : '启用' }}</el-button>
							<el-button size="mini" type="text" icon="el-icon-delete-solid" v-hasPermi="['system:role:remove']" @click="handleDelete(scope.row)">删除</el-button>
						</template>
					</el-table-column>
				</el-table>

				<!-- 功能权限列表 -->
				<el-table
					v-loading="loading"
					:data="FuncListTree"
					row-key="menuId"
					:tree-props="{ children: 'children' }"
					border
					:cell-style="{ cursor: 'pointer' }"
					@row-click="functionalLineClick"
					v-show="functionalShow"
				>
					<el-table-column label="名称" prop="menuName" width="200">
						<template slot-scope="scope">
							<a href="javascript:void(0);" class="linked" @click="functionalLineDbclick(scope.row)">{{ scope.row.menuName }}</a>
						</template>
					</el-table-column>
					<el-table-column label="描述" prop="remark" width="231" />
					<el-table-column label="权限" prop="createTime" width="55" align="center">
						<template slot-scope="scope">
							<span><input type="checkbox" :checked="isChecked(scope.row)" @change="handleCheckedTreeConnect($event, 'menu', scope.row)" /></span>
						</template>
					</el-table-column>
					<el-table-column label="操作" class-name="small-padding fixed-width">
						<template slot-scope="scope">
							<el-button
								size="mini"
								type="text"
								:style="{ color: checkedKeys.includes(item.menuId) ? '#409EFF' : '#909399' }"
								v-for="(item, index) in btnListss(scope.row.menuId)"
								:key="index"
								@click="updateBtn(item, scope.row)"
								><span>{{ item.menuName }}</span>
							</el-button>
						</template>
					</el-table-column>
				</el-table>

				<!-- 表头权限列表 -->
				<el-table v-loading="loading" :data="headList" border :cell-style="{ cursor: 'pointer' }" @row-click="headlLineClick" v-show="headShow">
					<el-table-column label="列表名称" width="200">{{ listName }}</el-table-column>
					<el-table-column label="列名称" prop="columnName" width="200" />
					<el-table-column label="状态" class-name="small-padding fixed-width">
						<template slot-scope="scope">
							<el-button
								size="mini"
								:disabled="disabled"
								type="text"
								icon="el-icon-remove-outline"
								:style="{ color: scope.row.isShow == 0 ? '#409EFF' : '#909399' }"
								@click="showOrHide(scope.row)"
								>显示</el-button
							>
						</template>
					</el-table-column>
				</el-table>

				<pagination v-show="total > 0 && roleShow" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />

				<!-- 添加或修改角色配置对话框 -->
				<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
					<el-form ref="form" :model="form" :rules="rules" label-width="100px">
						<el-form-item label="角色名称" prop="roleName">
							<el-input v-model="form.roleName" placeholder="请输入角色名称" />
						</el-form-item>
						<el-form-item label="状态">
							<el-radio-group v-model="form.status">
								<el-radio v-for="dict in dict.type.sys_normal_disable" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
							</el-radio-group>
						</el-form-item>
						<el-form-item label="描述">
							<el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
						</el-form-item>
					</el-form>
					<div slot="footer" class="dialog-footer">
						<el-button size="small" type="primary" @click="submitForm">确 定</el-button>
						<el-button size="small" @click="cancel">取 消</el-button>
					</div>
				</el-dialog>
			</div>
		</div>
	</div>
</template>

<script>
import {
	listRole,
	getRole,
	delRole,
	addRole,
	updateRole,
	dataScope,
	changeRoleStatus,
	getRoleMenuTreeselect,
	saveRoleMenu,
	getTableHeadList,
	authUserCancelAll,
	setSysTableCfgIsShow
} from '@/api/system/role'
import { treeselect as menuTreeselect, roleMenuTreeselect } from '@/api/system/menu'
import { treeselect as deptTreeselect, roleDeptTreeselect } from '@/api/system/dept'
import pinyin from 'js-pinyin'

export default {
	name: 'Role',
	dicts: ['sys_normal_disable'],
	data() {
		return {
			// 遮罩层
			loading: true,
			// 总条数
			total: 0,
			// 角色表格数据
			roleList: [],
			// 弹出层标题
			title: '',
			// 是否显示弹出层
			open: false,
			// 是否显示弹出层（数据权限）
			openDataScope: false,
			menuExpand: false,
			menuNodeAll: false,
			deptExpand: true,
			deptNodeAll: false,
			// 日期范围
			dateRange: [],
			// 菜单列表
			menuOptions: [],
			// 部门列表
			deptOptions: [],
			// 查询参数
			queryParams: {
				pageNum: 1,
				pageSize: 10,
				roleName: undefined,
				roleKey: undefined,
				status: undefined
			},
			// 表单参数
			form: {},
			form1: {},
			// 表单校验
			rules: {
				roleName: [{ required: true, message: '角色名称不能为空', trigger: 'blur' }]
			},
			roleShow: true,
			functionalShow: false,
			headShow: false,
			over: 1,
			background: '',
			getIndex: null,
			getIndex1: null,
			getIndex2: null,
			functionList: [], // 功能权限列表
			btnList: [], // 功能权限按钮列表
			headList: [],
			FuncList: [],
			FuncListTree: [],
			objRole: {},
			objFun: {},
			btnsLists: [],
			btnsList: [],
			checkedKeys: [],
			checked: false,
			roleId: '',
			listName: '',
			menuId: '',
			checkStatus: -1,
			disabled: false
		}
	},
	created() {
		this.getList()
	},
	filters: {},
	methods: {
		// 角色列表
		getRole() {
			this.getList()
			this.over = 1
			this.roleShow = true
			this.functionalShow = false
			this.headShow = false
		},
		// 功能权限列表
		getFunctionalAuthority() {
			this.getList()
			this.roleLineDbclick(this.objRole)
			this.headShow = false
		},
		// 表头权限；列表
		getHeaderPermission() {
			this.functionalLineDbclick(this.objFun)
			this.getList()
		},
		/** 查询角色列表 */
		getList() {
			this.loading = true
			listRole(this.addDateRange(this.queryParams, this.dateRange)).then((response) => {
				this.roleList = response.rows
				this.total = response.total
				this.loading = false
			})
		},
		// 单击角色表格某一行 行点击事件,这里获取到的行对象(row)是没有index属性的
		roleLineClick(row) {
			this.getIndex = row.index
			this.objRole = row
		},
		//为行对象(row)设置index属性
		tableRowClassName({ row, rowIndex }) {
			row.index = rowIndex
		},
		// 双击角色表格某一行
		roleLineDbclick(row) {
			if (JSON.stringify(row) !== '{}') {
				this.roleId = ''
				this.functionList = []
				this.checkedKeys = []
				this.btnList = []
				this.FuncList = []
				this.FuncListTree = []
				this.roleId = row.roleId
				getRoleMenuTreeselect(row.roleId).then((res) => {
					if (res.code === 200) {
						this.checkedKeys = res.data.checkedKeys
						this.functionList = res.data.menus
						this.btnList = this.functionList.filter((item, index, c) => item.menuType == 'F')
						this.btnsLists = this.functionList.filter((item, index, c) => item.menuType == 'C')
						this.FuncList = this.functionList.filter((item, index, c) => item.menuType == 'M' || item.menuType == 'C')
						this.FuncListTree = this.handleTree(this.FuncList, 'menuId', 'parentId')
					}
				})
				this.functionalShow = true
				this.roleShow = false
				this.over = 2
			} else {
				this.$notify({
					title: '警告',
					message: '请选择角色',
					type: 'warning'
				})
			}
		},
		// 单击功能权限表格某一行
		functionalLineClick(row, event, column) {
			if (row) {
				this.getIndex1 = row.index
				this.objFun = row
			}
		},
		// 双击功能权限表格某一行
		functionalLineDbclick(row, event, column) {
			this.disabled = this.isChecked(row) ? false : true
			this.headList = []
			this.functionalShow = false
			this.headShow = true
			this.over = 3
			this.listName = row.menuName
			this.menuId = row.menuId
			this.checkStatus = this.isChecked(row) ? 0 : 1
			getTableHeadList(this.roleId, row.menuId, this.checkStatus).then((res) => {
				this.headList = res.data
			})
		},
		// 单击表头权限表格某一行
		headlLineClick(row, event, column) {
			this.getIndex2 = row.index
		},
		/** 查询菜单树结构 */
		getMenuTreeselect() {
			menuTreeselect().then((response) => {
				this.menuOptions = response.data
			})
		},
		/** 查询部门树结构 */
		getDeptTreeselect() {
			deptTreeselect().then((response) => {
				this.deptOptions = response.data
			})
		},
		// 所有菜单节点数据
		// getMenuAllCheckedKeys() {
		//   // 目前被选中的菜单节点
		//   let checkedKeys = this.$refs.menu.getCheckedKeys();
		//   // 半选中的菜单节点
		//   let halfCheckedKeys = this.$refs.menu.getHalfCheckedKeys();
		//   checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
		//   return checkedKeys;
		// },
		// // 所有部门节点数据
		// getDeptAllCheckedKeys() {
		//   // 目前被选中的部门节点
		//   let checkedKeys = this.$refs.dept.getCheckedKeys();
		//   // 半选中的部门节点
		//   let halfCheckedKeys = this.$refs.dept.getHalfCheckedKeys();
		//   checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
		//   return checkedKeys;
		// },
		/** 根据角色ID查询菜单树结构 */
		getRoleMenuTreeselect(roleId) {
			return roleMenuTreeselect(roleId).then((response) => {
				this.menuOptions = response.menus
				return response
			})
		},
		/** 根据角色ID查询部门树结构 */
		getRoleDeptTreeselect(roleId) {
			return roleDeptTreeselect(roleId).then((response) => {
				this.deptOptions = response.depts
				return response
			})
		},
		// 角色状态修改
		handleStatusChange(row) {
			let text = row.status === '0' ? '禁用' : '启用'
			this.$modal
				.confirm('确认要"' + text + '""' + row.roleName + '"角色吗？')
				.then(function () {
					row.status = row.status === '0' ? '1' : '0'
					return changeRoleStatus(row.roleId, row.status)
				})
				.then(() => {
					this.$modal.msgSuccess(text + '成功')
				})
				.catch(function () {
					row.status = row.status === '0' ? '1' : '0'
				})
		},
		// 修改功能操作权限
		updateBtn(e, obj1) {
			let obj = {
				menuId: e.menuId,
				roleId: this.roleId
			}
			let arr = []
			arr.push(obj)
			// let parent = this.functionList.find((item) => item.menuId == e.parentId)
			// let parents = []
			// while (parent) {
			// 	parents.push(parent)
			// 	parent = this.functionList.find((item) => item.menuId == parent.parentId)
			// }
			if (this.checkedKeys.includes(e.menuId)) {
				authUserCancelAll(arr).then((res) => {
					if (res.code == 200) {
						this.checkedKeys = this.checkedKeys.filter((item) => item != e.menuId)
						this.$msg({ message: '修改成功' })
					}
				})
			} else {
				// let arrs = []
				// arrs.push(obj)
				// parents.forEach(element => {
				// 	let e = {
				// 		menuId: element.menuId,
				// 		roleId: this.roleId
				// 	}
				// 	arrs.push(e)
				// });
				saveRoleMenu(arr).then((res) => {
					if (res.code == 200) {
						this.checkedKeys.push(e.menuId)
						this.$msg({ message: '修改成功' })
						// this.checkedKeys.push(obj1.menuId)
						// parents.forEach(element => {
						//   this.checkedKeys.push(element.menuId)
						// });
					}
				})
			}

			// let checked = !this.checkedKeys.includes(e.menuId)
			// let obj = {
			// 	menuId: e.menuId,
			// 	roleId: this.roleId
			// }
			// let arr = []
			// arr.push(obj)
			// saveRoleMenu(arr).then((res) => {
			// 		if (res.code == 200) {
			// 			this.checkedKeys.push(e.menuId)
			// 		}
			// 	})
			// if (checked) {
			// 	let sArr = [...this.checkedKeys, e.menuId]
			// 	parents.forEach((p) => {
			// 		if (this.findChildrenIds(p).every((item) => sArr.includes(item))) {
			// 			arr.push({
			// 				menuId: p.menuId,
			// 				roleId: this.roleId
			// 			})
			// 		}
			// 	})
			// } else {
			// 	parents.forEach((p) => {
			// 		arr.push({
			// 			menuId: p.menuId,
			// 			roleId: this.roleId
			// 		})
			// 	})
			// }
			// let req = JSON.stringify(arr)
			// this.form1.json = req
			// if (!checked) {
			// 	authUserCancelAll(arr).then((res) => {
			// 		if (res.code == 200) {
			// 			this.checkedKeys = this.checkedKeys.filter((item) => item != e.menuId)
			// 		}
			// 	})
			// } else {
			// 	saveRoleMenu(arr).then((res) => {
			// 		if (res.code == 200) {
			// 			this.checkedKeys.push(e.menuId)
			// 		}
			// 	})
			// }
		},
		// 表头权限显示
		showOrHide(row) {
			let iss = row.isShow === '1' ? '0' : '1'
			setSysTableCfgIsShow(row.id, iss, this.menuId, this.roleId).then((res) => {
				if (res.code == 200) {
					row.isShow = row.isShow == '1' || row.isShow == null ? '0' : '1'
					this.$msg({ message: '修改成功' })
				}
			})
		},
		// 取消按钮
		cancel() {
			this.open = false
			this.reset()
		},
		// 取消按钮（数据权限）
		cancelDataScope() {
			this.openDataScope = false
			this.reset()
		},
		// 表单重置
		reset() {
			// if (this.$refs.menu != undefined) {
			//   this.$refs.menu.setCheckedKeys([]);
			// }
			;(this.menuExpand = false),
				(this.menuNodeAll = false),
				(this.deptExpand = true),
				(this.deptNodeAll = false),
				(this.form = {
					roleId: undefined,
					roleName: undefined,
					roleKey: undefined,
					roleSort: 0,
					status: '0',
					menuIds: [],
					deptIds: [],
					menuCheckStrictly: true,
					deptCheckStrictly: true,
					remark: undefined
				})
			this.resetForm('form')
		},
		// /** 搜索按钮操作 */
		// handleQuery() {
		// 	this.queryParams.pageNum = 1
		// 	this.getList()
		// },
		// /** 重置按钮操作 */
		// resetQuery() {
		// 	this.dateRange = []
		// 	this.resetForm('queryForm')
		// 	this.handleQuery()
		// },
		// 树权限（展开/折叠）
		// handleCheckedTreeExpand(value, type) {
		// 	if (type == 'menu') {
		// 		let treeList = this.menuOptions
		// 		for (let i = 0; i < treeList.length; i++) {
		// 			this.$refs.menu.store.nodesMap[treeList[i].id].expanded = value
		// 		}
		// 	} else if (type == 'dept') {
		// 		let treeList = this.deptOptions
		// 		for (let i = 0; i < treeList.length; i++) {
		// 			this.$refs.dept.store.nodesMap[treeList[i].id].expanded = value
		// 		}
		// 	}
		// },
		// 树权限（全选/全不选）
		// handleCheckedTreeNodeAll(value, type) {
		//   if (type == 'menu') {
		//     this.$refs.menu.setCheckedNodes(value ? this.menuOptions: []);
		//   } else if (type == 'dept') {
		//     this.$refs.dept.setCheckedNodes(value ? this.deptOptions: []);
		//   }
		// },
		// 树权限（父子联动）
		handleCheckedTreeConnect(e, type, item) {
			let value = e.target.checked
			// if (item.parentId) {

			// }
			// let ms = this.functionList.filter((item, index, c) => item.menuType == 'M')
			// let mss = this.functionList.filter((it, index, c) => it.parentId == item.parentId)
			// let m = ms.filter(i => i.menuId == item.parentId)
			// console.log(mss)
			// let ids = this.findChildrenIds(item)
			// let objs = ids.map((m) => {
			// 	return {
			// 		menuId: m,
			// 		roleId: this.roleId
			// 	}
			// })
			// objs.push({
			// 	menuId: item.menuId,
			// 	roleId: this.roleId
			// })
			if (value) {
				this.checkStatus = 0
				this.disabled = false
				this.checkedKeys.push(item.menuId)
				let obj = {
					menuId: item.menuId,
					roleId: this.roleId
				}
				let arr = []
				arr.push(obj)
				saveRoleMenu(arr).then((res) => {
					if (res.code == 200) {
						this.$msg({ message: '修改成功' })
					}
				})
			} else {
				this.checkedKeys = this.checkedKeys.filter((f) => f != item.menuId)
				this.checkStatus = 1
				this.disabled = true
				let obj = {
					menuId: item.menuId,
					roleId: this.roleId
				}
				let arr = []
				arr.push(obj)
				authUserCancelAll(arr).then((res) => {
					if (res.code == 200) {
						this.$msg({ message: '修改成功' })
					}
				})
			}
		},
		/** 新增按钮操作 */
		handleAdd() {
			this.reset()
			this.getMenuTreeselect()
			this.open = true
			this.title = '添加角色'
		},
		/** 修改按钮操作 */
		handleUpdate(row) {
			this.reset()
			const roleId = row.roleId || this.ids
			// const roleMenu = this.getRoleMenuTreeselect(roleId);
			getRole(roleId).then((response) => {
				this.form = response.data
				this.open = true
				// this.$nextTick(() => {
				//   roleMenu.then(res => {
				//     let checkedKeys = res.checkedKeys
				//     checkedKeys.forEach((v) => {
				//         this.$nextTick(()=>{
				//             this.$refs.menu.setChecked(v, true ,false);
				//         })
				//     })
				//   });
				// });
				this.title = '修改角色'
			})
		},
		/** 选择角色权限范围触发 */
		// dataScopeSelectChange(value) {
		//   if(value !== '2') {
		//     this.$refs.dept.setCheckedKeys([]);
		//   }
		// },
		/** 分配数据权限操作 */
		handleDataScope(row) {
			this.reset()
			const roleDeptTreeselect = this.getRoleDeptTreeselect(row.roleId)
			getRole(row.roleId).then((response) => {
				this.form = response.data
				this.openDataScope = true
				// this.$nextTick(() => {
				//   roleDeptTreeselect.then(res => {
				//     this.$refs.dept.setCheckedKeys(res.checkedKeys);
				//   });
				// });
				this.title = '分配数据权限'
			})
		},
		/** 分配用户操作 */
		// handleAuthUser: function (row) {
		// 	const roleId = row.roleId
		// 	this.$router.push('/system/role-auth/user/' + roleId)
		// },
		/** 提交按钮 */
		submitForm: function () {
			this.$refs['form'].validate((valid) => {
				if (valid) {
					if (this.form.roleId != undefined) {
						// this.form.menuIds = this.getMenuAllCheckedKeys();
						this.form.menuIds = []
						updateRole(this.form).then((response) => {
							console.log(response)
							this.$modal.msgSuccess('修改成功')
							this.open = false
							this.getList()
						})
					} else {
						// this.form.menuIds = this.getMenuAllCheckedKeys();
						let val = this.form.roleName
						this.form.roleKey = pinyin.getFullChars(val)
						addRole(this.form).then((response) => {
							this.$modal.msgSuccess('新增成功')
							this.open = false
							this.getList()
						})
					}
				}
			})
		},
		/** 提交按钮（数据权限） */
		submitDataScope: function () {
			if (this.form.roleId != undefined) {
				this.form.deptIds = this.getDeptAllCheckedKeys()
				dataScope(this.form).then((response) => {
					this.$modal.msgSuccess('修改成功')
					this.openDataScope = false
					this.getList()
				})
			}
		},
		/** 删除按钮操作 */
		handleDelete(row) {
			const roleIds = row.roleId || this.ids
			this.$modal
				.confirm('是否确认删除角色为"' + row.roleName + '"的数据项？')
				.then(function () {
					return delRole(roleIds)
				})
				.then((res) => {
					if (res.code === 200) {
						this.getList()
						this.$modal.msgSuccess('删除成功')
					} else if (res.code === 500) {
						this.getList()
						this.$notify({
							title: '警告',
							message: res.msg,
							type: 'warning'
						})
					}
				})
				.catch(() => {})
		},
		/** 导出按钮操作 */
		// handleExport() {
		// 	this.download(
		// 		'system/role/export',
		// 		{
		// 			...this.queryParams
		// 		},
		// 		`role_${new Date().getTime()}.xlsx`
		// 	)
		// },
		//寻找子id集合
		findIds(parent) {
			if (!parent.children) {
				return
			}
			let res = []
			parent.children.forEach((item) => {
				if (item.menuType == 'C') {
					res.push(item)
				} else {
					res = res.concat(this.findIds(item))
				}
			})
			return res
		},
		//寻找子id集合
		findChildrenIds(parent) {
			if (parent.menuType == 'M') {
				let childIds = this.findIds(parent).map((item) => item.menuId)
				return this.btnList.filter((item) => childIds.includes(item.parentId)).map((item) => item.menuId)
			} else if (parent.menuType == 'C') {
				return this.btnList.filter((item) => item.parentId == parent.menuId).map((item) => item.menuId)
			}
		}
	},
	computed: {
		btnListss() {
			return function (pid) {
				return this.btnList.filter((item) => item.parentId == pid)
			}
		},
		isChecked() {
			return function (obj) {
				// return this.findChildrenIds(obj).length > 0 && this.findChildrenIds(obj).every((item) => this.checkedKeys.includes(item))
				return this.checkedKeys.includes(obj.menuId)
			}
		}
	}
}
</script>
<style scoped>
.activeClass {
	color: #409eff;
}
</style>
