You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

872 lines
28 KiB

  1. <script setup>
  2. import {nextTick, onMounted, reactive, ref} from 'vue'
  3. import {ElMessage} from 'element-plus'
  4. import _ from 'lodash'
  5. import request from '@/util/http'
  6. import API from '@/util/http'
  7. // 客户明细表格 什么表格???????
  8. const tableData = ref([])
  9. const roleData = ref([])
  10. const total = ref(100)
  11. const roleTotal = ref(100)//角色分页
  12. // 搜索admin
  13. const admin = ref({
  14. account: '',
  15. market: '',
  16. postiton: ''
  17. })
  18. // 角色搜索
  19. const role = ref({
  20. name: ''
  21. })
  22. // 搜索对象
  23. const getObj = ref({
  24. pageNum: 1,
  25. pageSize: 10
  26. })
  27. // 角色搜索对象
  28. const getRoleObj = ref({
  29. pageNum: 1,
  30. pageSize: 10
  31. })
  32. //选地区
  33. const market = ref([])
  34. // 选部门
  35. const postiton = ref([])
  36. // 新增角色弹窗
  37. const permissionAddVisible = ref(false)
  38. // 新增角色对象
  39. const addRole = ref({
  40. roleName: '',
  41. parentId: null,
  42. checkedKeys: [],
  43. grade: '',
  44. market: ''
  45. })
  46. const addRoleMarket = ref([])
  47. //这是获取用户信息的接口
  48. const adminData = ref({})
  49. const getAdminData = async function () {
  50. try {
  51. const result = await API({url: '/admin/userinfo', data: {}})
  52. adminData.value = result
  53. console.log('管理员用户信息', adminData.value)
  54. } catch (error) {
  55. console.log('请求失败', error)
  56. }
  57. }
  58. const viewRole = ref([])
  59. const getRolePermission = async function () {
  60. const result = await request({
  61. url: '/menu/tree',
  62. data: {
  63. "id": adminData.value.roleId
  64. }
  65. })
  66. viewRole.value = collectIds(result.data)
  67. console.log('result111', viewRole.value);
  68. }
  69. const get = async function (val) {
  70. try {
  71. if (typeof val === 'number') {
  72. getObj.value.pageNum = val
  73. }
  74. console.log('搜索参数', getObj.value, admin.value)
  75. const result = await request({
  76. url: '/permission/getPermission',
  77. data: {
  78. ...getObj.value,
  79. permission: {
  80. ...admin.value
  81. }
  82. }
  83. })
  84. tableData.value = result.data.list
  85. console.log('tableData', tableData.value)
  86. total.value = result.data.total
  87. } catch (error) {
  88. console.log('请求失败', error)
  89. }
  90. }
  91. const getRoleList = async function (val) {
  92. try {
  93. if (typeof val === 'number') {
  94. getObj.value.pageNum = val
  95. }
  96. console.log('搜索参数', getObj.value, role.value)
  97. const result = await request({
  98. url: '/role/selectBy',
  99. data: {
  100. ...getRoleObj.value,
  101. roleVo: {
  102. roleName: role.value.name
  103. }
  104. }
  105. })
  106. roleData.value = result.data.list
  107. console.log('roleData', roleData.value)
  108. roleTotal.value = result.data.total
  109. } catch (error) {
  110. console.log('请求失败', error)
  111. }
  112. }
  113. // 试试D老师的方法
  114. const formatPermissions = (tree) => {
  115. if (!tree || tree.length === 0) return '';
  116. return tree.map(menu => {
  117. const mainMenu = menu.menuName;
  118. const subMenus = menu.children?.map(child => child.menuName) || [];
  119. // 如果有子菜单,显示前2个子菜单名称
  120. if (subMenus.length > 0) {
  121. const maxSub = Math.min(2, subMenus.length);
  122. const subText = subMenus.slice(0, maxSub).join('、');
  123. const moreText = subMenus.length > maxSub ? '...' : '';
  124. return `${mainMenu}+${subText}${moreText}`;
  125. }
  126. // 没有子菜单时只显示主菜单
  127. return mainMenu;
  128. }).join('+');
  129. };
  130. const trimJwCode = () => {
  131. if (admin.value.account) {
  132. admin.value.account = admin.value.account.replace(/\s/g, '');
  133. }
  134. }
  135. const searchRole = function () {
  136. trimJwCode();
  137. getObj.value.pageNum = 1
  138. getRoleList()
  139. }
  140. // 重置
  141. const reset = function () {
  142. admin.value = {}
  143. role.value.name = ''
  144. get()
  145. getRoleList()
  146. }
  147. const RoleArea = ref([])
  148. const getRoleArea = async function () {
  149. try {
  150. const result = await request({
  151. url: '/general/allRoleMarket',
  152. data: {}
  153. })
  154. RoleArea.value = result.data
  155. } catch (error) {
  156. console.log('请求失败', error)
  157. }
  158. }
  159. const getArea = async function () {
  160. try {
  161. const result = await request({
  162. url: '/general/adminMarkets',
  163. data: {account: adminData.value.account}
  164. })
  165. market.value = result.data
  166. } catch (error) {
  167. console.log('请求失败', error)
  168. }
  169. }
  170. // 获取部门
  171. const getStore = async function () {
  172. try {
  173. const result = await request({
  174. url: '/permission/getposition',
  175. data: {}
  176. })
  177. postiton.value = result.data
  178. } catch (error) {
  179. console.log('请求失败', error)
  180. }
  181. }
  182. // 新增角色弹窗
  183. const openPermissionAddVisible = function () {
  184. permissionAddVisible.value = true
  185. getRoles()
  186. getLists()
  187. }
  188. const closePermissionAddVisible = function () {
  189. addRole.value = {
  190. roleName: '',
  191. parentId: null,
  192. checkedKeys: [],
  193. grade: '',
  194. market: ''
  195. }
  196. permissionAddVisible.value = false
  197. Ref.value.resetFields();
  198. getRoleList()
  199. }
  200. // 新增角色初始化
  201. const permissionAddInit = function () {
  202. openPermissionAddVisible()
  203. }
  204. // 表单验证ref
  205. const Ref = ref(null)
  206. // 权限类别
  207. const permissionList = ref([])
  208. const getRoles = async function () {
  209. try {
  210. const res = await API({url: '/role/selectAll'})
  211. permissionList.value = res.data.map(item => ({
  212. label: item.roleName,
  213. value: item.id
  214. }))
  215. console.log('权限列表:', permissionList.value)
  216. } catch (error) {
  217. console.error('获取权限列表失败:', error)
  218. }
  219. }
  220. const collectIds = (tree) => {
  221. let ids = [];
  222. tree.forEach((node) => {
  223. ids.push(node.id);
  224. if (node.children && node.children.length > 0) {
  225. ids = ids.concat(collectIds(node.children));
  226. }
  227. });
  228. return ids;
  229. };
  230. //给data数据加上disabled属性,控制是否禁用
  231. function processTreeData(data) {
  232. return data.map(item => ({
  233. ...item,
  234. disabled: item.id != null || item.menuName.includes("敏感权限"), //控制权限显示的条件
  235. children: item.children ? processTreeData(item.children) : []
  236. }));
  237. }
  238. const handleAddRole = async function () {
  239. try {
  240. await new Promise((resolve, reject) => {
  241. Ref.value.validate((valid) => {
  242. if (valid) {
  243. resolve(); // 验证通过,继续执行后续代码
  244. } else {
  245. reject(new Error('请检查并完善表单信息')); // 验证失败,抛出错误
  246. }
  247. });
  248. });
  249. addRole.value.roleName = addRole.value.roleName.replace(/\s+/g, '');
  250. console.log('去除角色名空格:', addRole.value.roleName);
  251. // 确保提交时包含所有选中的权限ID(包括父节点)
  252. const finalCheckedKeys = addRole.value.checkedKeys || [];
  253. const res = await API({
  254. url: '/role/add',
  255. data: {
  256. "roleName": addRole.value.roleName,
  257. "menuIds": finalCheckedKeys,
  258. "priority": addRole.value.grade,
  259. "fatherId": addRole.value.parentId,
  260. "market": addRole.value.market
  261. }
  262. })
  263. if (res.code === 200) {
  264. ElMessage.success('角色' + addRole.value.roleName + '添加成功')
  265. console.log('成功了,看看addRole', addRole.value)
  266. console.log('提交的权限ID列表:', finalCheckedKeys);
  267. closePermissionAddVisible()
  268. } else {
  269. ElMessage.error(res.msg)
  270. }
  271. } catch (error) {
  272. console.log('请求失败', error)
  273. console.log('失败,看看addRole', addRole.value);
  274. }
  275. }
  276. const handleRolePageSizeChange = (val) => {
  277. getRoleObj.value.pageSize = val
  278. getRoleList() // 调用角色管理的查询
  279. }
  280. // 角色管理分页 - 当前页变化
  281. const handleRoleCurrentChange = (val) => {
  282. getRoleObj.value.pageNum = val
  283. getRoleList() // 调用角色管理的查询
  284. }
  285. const data = ref([])
  286. const getLists = async function () {
  287. try {
  288. console.log('addRole.value.roleId', addRole.value.roleId);
  289. let roleId = addRole.value.parentId
  290. if (addRole.value.parentId === null || addRole.value.parentId === undefined) {
  291. roleId = 2
  292. }
  293. const res = await API({
  294. url: '/menu/tree',
  295. data: {id: roleId}
  296. })
  297. data.value = res.data
  298. let originalData = res.data.filter(item => item.id !== 9); // 排除权限管理
  299. // 排除金豆菜单
  300. data.value = filterGoldenBeanMenus(originalData);
  301. // data.value = data.value.filter(item => item.id !== 9);
  302. console.log('看看data', data.value)
  303. console.log('parentID:', addRole.value.parentId, 'roleId:', roleId)
  304. /* // 根据地区过滤金豆菜单
  305. if (addRole.value.market !== '总部') {
  306. // 非总部地区:过滤掉金豆相关菜单
  307. originalData = filterGoldenBeanMenus(originalData);
  308. }
  309. data.value = originalData; // 更新菜单树数据*/
  310. if (addRole.value.parentId && addRole.value.parentId !== 2) {
  311. const result = await API({
  312. url: '/general/roleMarket',
  313. data: {id: addRole.value.parentId}
  314. })
  315. if (result.code === 200) {
  316. if (typeof result.data === 'string' && result.data) {
  317. addRoleMarket.value = result.data.split(',');
  318. addRole.value.market = ''
  319. } else if (Array.isArray(result.data)) {
  320. addRoleMarket.value = result.data
  321. addRole.value.market = ''
  322. } else {
  323. addRoleMarket.value = [];
  324. addRole.value.market = ''
  325. }
  326. } else {
  327. ElMessage.error('该上级角色无所属地区')
  328. console.log('该上级角色无所属地区');
  329. }
  330. console.log('addRoleMarket.value', addRoleMarket.value);
  331. } else {
  332. addRoleMarket.value = RoleArea.value
  333. console.log('elseRoleArea', RoleArea);
  334. }
  335. } catch (error) {
  336. console.log('请求失败', error)
  337. }
  338. }
  339. //金豆过滤
  340. const goldenBeanMenuIds = new Set([
  341. 43, 55, 54, // 财务审核 -> 金豆审核
  342. 41, 47, 46, 48, // 充值管理 -> 金豆充值
  343. 42, 50, 49, 52, 51, // 消耗管理 -> 金豆消耗
  344. 45, 53 // 客户账户明细 -> 金豆客户账户明细
  345. ]);
  346. const filterGoldenBeanMenus = (tree) => {
  347. return tree
  348. .filter(item => {
  349. // 排除金豆相关的顶层菜单
  350. if (goldenBeanMenuIds.has(item.id)) {
  351. return false;
  352. }
  353. // 递归处理子菜单
  354. if (item.children && item.children.length > 0) {
  355. item.children = filterGoldenBeanMenus(item.children);
  356. }
  357. return true;
  358. });
  359. };
  360. const handleMarketChange = () => {
  361. getLists(); // 重新获取并过滤菜单树
  362. };
  363. const treeRef = ref(null)
  364. // 处理编辑角色权限时的勾选事件
  365. const handleEditRolePermissionCheck = (checkedNodes, checkedInfo) => {
  366. const {checkedKeys, checkedNodes: allCheckedNodes} = checkedInfo;
  367. // 判断是否有选中的节点
  368. if (allCheckedNodes.length === 0) {
  369. permissionEditRoleObj.value.checkedKeys = [];
  370. return;
  371. }
  372. // 由于设置了 check-strictly="false",Element Plus 会自动处理父子节点联动
  373. // 我们只需要使用 checkedKeys,它已经包含了所有必要的节点ID
  374. permissionEditRoleObj.value.checkedKeys = checkedKeys;
  375. console.log('编辑角色选中的权限ID:', checkedKeys);
  376. console.log('选中的节点数量:', allCheckedNodes.length);
  377. };
  378. const handleCheckChange = async (checkedNodes, checkedInfo) => {
  379. const {checkedKeys, checkedNodes: allCheckedNodes} = checkedInfo;
  380. // 判断是否有选中的节点
  381. if (allCheckedNodes.length === 0) {
  382. addRole.value.checkedKeys = [];
  383. return;
  384. }
  385. // 创建一个Set存储所有需要选中的ID(包括父级)
  386. const allKeys = new Set(checkedKeys);
  387. // 遍历所有选中的节点,为每个节点添加其父级
  388. allCheckedNodes.forEach(node => {
  389. // 为每个选中的节点单独查找父级
  390. selectParentNodes(data.value, node.id, allKeys);
  391. });
  392. // 将Set转换为数组并更新
  393. addRole.value.checkedKeys = Array.from(allKeys);
  394. console.log('新增角色包含所有父级的选中项:', addRole.value.checkedKeys);
  395. };
  396. const selectParentNodes = (treeData, nodeId, checkedKeys) => {
  397. if (!Array.isArray(treeData)) return false;
  398. for (const item of treeData) {
  399. // 先检查子节点
  400. if (item.children && item.children.length > 0) {
  401. const foundInChildren = selectParentNodes(item.children, nodeId, checkedKeys);
  402. if (foundInChildren) {
  403. // 找到子节点后添加当前节点(父节点)
  404. checkedKeys.add(item.id);
  405. return true;
  406. }
  407. }
  408. // 检查当前节点是否为目标节点
  409. if (item.id === nodeId) {
  410. return true;
  411. }
  412. }
  413. return false;
  414. };
  415. //点击角色权限菜单树点击展示逻辑
  416. const menuTreeVisible = ref(false);
  417. const currentRoleMenuTree = ref([]);
  418. const currentRoleName = ref('');
  419. const Rolecheckedkeys = ref([])
  420. const showMenuTree = (treeData, roleName) => {
  421. currentRoleMenuTree.value = processTreeData(treeData) || [];
  422. console.log('currentRoleMenuTree.value', currentRoleMenuTree.value);
  423. Rolecheckedkeys.value = collectIds(treeData)
  424. console.log('Rolecheckedkeys', Rolecheckedkeys.value);
  425. currentRoleName.value = roleName || '权限详情';
  426. menuTreeVisible.value = true;
  427. };
  428. // 编辑角色对象
  429. const permissionEditRoleObj = ref({
  430. id: null,
  431. roleName: '',
  432. market: '',
  433. parentId: null,
  434. parentName: '',
  435. checkedKeys: [],
  436. grade: '',
  437. });
  438. // 编辑角色弹窗
  439. const permissionEditRoleVisible = ref(false);
  440. const collectIds2 = (tree) => {
  441. let ids = [];
  442. tree.forEach((node) => {
  443. // 如果当前节点没有 children 或 children 为空,说明是叶子节点
  444. if (!node.children || node.children.length === 0) {
  445. ids.push(node.id);
  446. } else {
  447. // 如果有 children,递归收集子节点的叶子节点
  448. ids = ids.concat(collectIds2(node.children));
  449. }
  450. });
  451. return ids;
  452. };
  453. // 编辑角色初始化
  454. const permissionEditRoleInit = async function (row) {
  455. console.log('row', row);
  456. console.log('row.tree', row.tree);
  457. permissionEditRoleObj.value = {};
  458. permissionEditRoleObj.value.id = row.id;
  459. permissionEditRoleObj.value.roleName = row.roleName;
  460. permissionEditRoleObj.value.market = row.market;
  461. permissionEditRoleObj.value.parentId = row.fatherId;
  462. permissionEditRoleObj.value.parentName = row.fatherName;
  463. permissionEditRoleObj.value.grade = row.priority;
  464. try {
  465. let roleId = permissionEditRoleObj.value.parentId;
  466. // 如果没有上级角色,设置为管理员的id
  467. if (permissionEditRoleObj.value.parentId === null || permissionEditRoleObj.value.parentId === undefined) {
  468. roleId = 2;
  469. }
  470. // 调用 /tree 接口,使用上级角色 ID 获取权限列表
  471. const res = await API({
  472. url: '/menu/tree',
  473. data: {id: roleId}
  474. });
  475. data.value = res.data;
  476. data.value = data.value.filter(item => item.id !== 9);
  477. data.value = filterGoldenBeanMenus(data.value);
  478. // 收集当前行权限树的叶子节点id(只收集实际选中的叶子节点)
  479. if (row.tree && row.tree.length > 0) {
  480. const leafIds = collectIds2(row.tree);
  481. permissionEditRoleObj.value.checkedKeys = leafIds;
  482. console.log('编辑角色初始化时的权限列表', permissionEditRoleObj.value.checkedKeys);
  483. } else {
  484. permissionEditRoleObj.value.checkedKeys = [];
  485. }
  486. } catch (error) {
  487. console.log('根据上级角色获取权限列表失败', error);
  488. data.value = [];
  489. permissionEditRoleObj.value.checkedKeys = [];
  490. }
  491. console.log('编辑角色', permissionEditRoleObj.value);
  492. permissionEditRoleVisible.value = true;
  493. // 等待DOM更新后手动设置树的选中状态
  494. await nextTick();
  495. if (treeRef.value && permissionEditRoleObj.value.checkedKeys.length > 0) {
  496. treeRef.value.setCheckedKeys(permissionEditRoleObj.value.checkedKeys);
  497. console.log('手动设置树的选中状态:', permissionEditRoleObj.value.checkedKeys);
  498. }
  499. };
  500. // 编辑角色提交
  501. const permissionEditRole = async function () {
  502. try {
  503. await new Promise((resolve, reject) => {
  504. Ref.value.validate((valid) => {
  505. if (valid) {
  506. resolve();
  507. } else {
  508. reject(new Error('请检查并完善表单信息'));
  509. }
  510. });
  511. });
  512. // 确保提交时包含所有选中的权限ID(包括父节点)
  513. let finalCheckedKeys = permissionEditRoleObj.value.checkedKeys || [];
  514. // 为所有选中的节点添加其父节点ID
  515. const allKeys = new Set(finalCheckedKeys);
  516. finalCheckedKeys.forEach(nodeId => {
  517. selectParentNodesForSubmit(data.value, nodeId, allKeys);
  518. });
  519. finalCheckedKeys = Array.from(allKeys);
  520. const res = await API({
  521. url: '/menu/update',
  522. data: {
  523. "id": permissionEditRoleObj.value.id,
  524. "roleName": permissionEditRoleObj.value.roleName,
  525. "menuIds": finalCheckedKeys,
  526. "priority": permissionEditRoleObj.value.grade,
  527. "fatherId": permissionEditRoleObj.value.parentId,
  528. "market": permissionEditRoleObj.value.market
  529. }
  530. });
  531. if (res.code === 200) {
  532. console.log('编辑角色成功', permissionEditRoleObj.value);
  533. console.log('提交的权限ID列表:', finalCheckedKeys);
  534. permissionEditRoleVisible.value = false;
  535. getRoleList();
  536. ElMessage.success('编辑角色成功');
  537. } else if (res.code === 0) {
  538. console.log('角色名重复', permissionEditRoleObj.value);
  539. ElMessage.error('角色名重复');
  540. } else {
  541. console.log('编辑角色失败', res);
  542. ElMessage.error('编辑角色失败');
  543. }
  544. } catch (error) {
  545. console.log('编辑角色失败', error);
  546. console.log('失败,看看permissionEditRoleObj', permissionEditRoleObj.value);
  547. }
  548. };
  549. // 为提交时查找父节点的辅助函数
  550. const selectParentNodesForSubmit = (treeData, nodeId, checkedKeys) => {
  551. if (!Array.isArray(treeData)) return false;
  552. for (const item of treeData) {
  553. // 先检查子节点
  554. if (item.children && item.children.length > 0) {
  555. const foundInChildren = selectParentNodesForSubmit(item.children, nodeId, checkedKeys);
  556. if (foundInChildren) {
  557. // 找到子节点后添加当前节点(父节点)
  558. checkedKeys.add(item.id);
  559. return true;
  560. }
  561. }
  562. // 检查当前节点是否为目标节点
  563. if (item.id === nodeId) {
  564. return true;
  565. }
  566. }
  567. return false;
  568. };
  569. const Rolerules = reactive({
  570. roleName: [
  571. {required: true, message: '请输入角色名称', trigger: 'blur'},
  572. {min: 2, max: 20, message: '角色名称长度应在2-20个字符之间', trigger: 'blur'}
  573. ],
  574. market: [
  575. {required: true, message: '请选择所属地区', trigger: 'change'}
  576. ],
  577. grade: [
  578. {required: true, message: '请输入优先级', trigger: 'blur'},
  579. {pattern: /^[1-9]\d{0,2}$/, message: '优先级应为1-999的数字', trigger: 'blur'}
  580. ],
  581. checkedKeys: [
  582. {
  583. required: true,
  584. message: '请选择权限列表',
  585. trigger: 'change', // 选框变化或提交时触发,可根据实际调整
  586. validator: (rule, value, callback) => {
  587. if (value && value.length > 0) {
  588. callback(); // 有选中项,校验通过
  589. } else {
  590. callback(new Error('请选择权限列表')); // 未选中,抛出错误提示
  591. }
  592. }
  593. }
  594. ]
  595. });
  596. const throttledHandleAddRole = _.throttle(handleAddRole, 5000, {
  597. trailing: false
  598. })
  599. // 挂载
  600. onMounted(async function () {
  601. await getAdminData()
  602. await get()
  603. await getArea()
  604. await getStore()
  605. await getRoleList()
  606. await getRolePermission()
  607. await getRoleArea()
  608. })
  609. </script>
  610. <template>
  611. <div>
  612. <!-- 角色搜索 -->
  613. <el-card style="margin-bottom: 20px;margin-top:10px">
  614. <div class="head-card">
  615. <el-text class="mx-1" size="large">角色名称</el-text>
  616. <el-input v-model="role.name" style="width: 240px" placeholder="请输入角色名称" clearable/>
  617. <div class="head-card-btn">
  618. <el-button type="success" @click="reset()">重置</el-button>
  619. <el-button type="primary" @click="searchRole()">查询</el-button>
  620. </div>
  621. </div>
  622. </el-card>
  623. <!-- 展示表单 -->
  624. <el-card>
  625. <div class="add-item">
  626. <el-button style="color: #048efb; border: 1px solid #048efb" @click="permissionAddInit()">新增角色</el-button>
  627. </div>
  628. <div>
  629. <el-table :data="roleData" style="width: 100%" show-overflow-tooltip>
  630. <el-table-column type="index" label="序号" width="100px" fixed="left">
  631. <template #default="scope">
  632. <span>{{
  633. scope.$index + 1 + (getRoleObj.pageNum - 1) * getRoleObj.pageSize
  634. }}</span>
  635. </template>
  636. </el-table-column>
  637. <el-table-column prop="roleName" label="角色名称"/>
  638. <el-table-column prop="fatherName" label="上级角色"/>
  639. <el-table-column prop="priority" label="优先级"/>
  640. <el-table-column label="权限范围" show-overflow-tooltip>
  641. <template #default="scope">
  642. <div class="permission-cell" @click="showMenuTree(scope.row.tree, scope.row.roleName)">
  643. {{ formatPermissions(scope.row.tree) }}
  644. </div>
  645. </template>
  646. </el-table-column>
  647. <!-- <el-table-column prop="operation" label="操作" width="200px">
  648. <template #default="scope">
  649. <el-popconfirm title="确定将此角色删除吗?" @confirm="delRoleConfirm">
  650. <template #reference>
  651. <el-button type="danger" text @click="delRole(scope.row)"
  652. :disabled="scope.row.id === 1 || scope.row.id === 2">
  653. 删除
  654. </el-button>
  655. </template>
  656. <template #actions="{ confirm, cancel }">
  657. <el-button size="small" @click="cancel">取消</el-button>
  658. <el-button type="primary" size="small" @click="confirm">
  659. 确定
  660. </el-button>
  661. </template>
  662. </el-popconfirm>
  663. </template>
  664. </el-table-column> -->
  665. <el-table-column prop="operation" label="操作" width="200px">
  666. <template #default="scope">
  667. <el-button type="warning" text @click="permissionEditRoleInit(scope.row)" :disabled="scope.row.id === 2">
  668. 编辑
  669. </el-button>
  670. </template>
  671. </el-table-column>
  672. </el-table>
  673. </div>
  674. <!-- 分页 -->
  675. <div class="pagination" style="margin-top: 20px">
  676. <el-pagination background :page-size="getObj.pageSize" :page-sizes="[5, 10, 20, 50, 100]"
  677. layout="total, sizes, prev, pager, next, jumper" :total="roleTotal"
  678. @size-change="handleRolePageSizeChange"
  679. @current-change="handleRoleCurrentChange"></el-pagination>
  680. </div>
  681. </el-card>
  682. </div>
  683. <!-- 角色菜单树展示 -->
  684. <el-dialog v-model="menuTreeVisible" :title='`权限详情:${currentRoleName}`' width="600px">
  685. <el-tree :data="currentRoleMenuTree" node-key="id" :props="{ label: 'menuName', children: 'children' }"
  686. show-checkbox check-strictly :expand-on-click-node="false"
  687. :default-expanded-keys="currentRoleMenuTree.map(item => item.id)" :default-checked-keys="Rolecheckedkeys"/>
  688. <template #footer>
  689. <el-button @click="menuTreeVisible = false" type="primary">关闭</el-button>
  690. </template>
  691. </el-dialog>
  692. <!-- 新增角色 -->
  693. <el-dialog v-model="permissionAddVisible" title="新增角色" width="800px" :close-on-click-modal="false">
  694. <template #footer>
  695. <el-form ref="Ref" :rules="Rolerules" :model="addRole" label-width="auto"
  696. style="max-width: 600px; align-items: center">
  697. <el-form-item prop="roleName" label="角色名称:" required>
  698. <el-input v-model="addRole.roleName" placeholder="请输入角色名称" style="width: 220px"/>
  699. </el-form-item>
  700. <el-form-item prop="parentName" label="上级角色:">
  701. <el-select v-model="addRole.parentId" placeholder="请选择上级角色" style="width: 220px" @change="getLists"
  702. clearable>
  703. <el-option v-for="item in permissionList" :key="item.value" :label="item.label"
  704. :value="item.value"></el-option>
  705. </el-select>
  706. </el-form-item>
  707. <el-form-item prop="market" label="所属地区:" required>
  708. <el-select v-model="addRole.market" placeholder="请选择所属地区" style="width: 220px" clearable @change="handleMarketChange" >
  709. <el-option v-for="item in addRoleMarket" :key="item" :label="item" :value="item"/>
  710. </el-select>
  711. </el-form-item>
  712. <el-form-item prop="checkedKeys" label="权限列表:" required>
  713. <el-tree v-if="data.length > 0" :data="data" show-checkbox node-key="id"
  714. :props="{ label: 'menuName', children: 'children' }" :checked-keys="addRole.checkedKeys"
  715. :check-strictly="false"
  716. @check="handleCheckChange">
  717. <template #default="{ node, data }">
  718. <span>{{ node.label }}</span>
  719. </template>
  720. </el-tree>
  721. <div v-else style="display: flex; align-items: center; gap: 8px;">
  722. <span style="color: #999;">暂无数据</span>
  723. </div>
  724. </el-form-item>
  725. <el-form-item prop="grade" label="优先级:" required>
  726. <el-input v-model="addRole.grade" placeholder="数字1~999" style="width: 220px"/>
  727. </el-form-item>
  728. </el-form>
  729. <div>
  730. <el-button @click="closePermissionAddVisible()">取消</el-button>
  731. <el-button type="primary" @click="throttledHandleAddRole">
  732. 提交
  733. </el-button>
  734. </div>
  735. </template>
  736. </el-dialog>
  737. <!-- 編輯角色彈窗 -->
  738. <el-dialog v-model="permissionEditRoleVisible" title="编辑角色" width="800px" :close-on-click-modal="false">
  739. <template #footer>
  740. <el-form ref="Ref" :rules="Rolerules" :model="permissionEditRoleObj" label-width="auto"
  741. style="max-width: 600px; align-items: center">
  742. <el-form-item prop="roleName" label="角色名称:" required>
  743. <el-input v-model="permissionEditRoleObj.roleName" placeholder="请输入角色名称" style="width: 220px"/>
  744. </el-form-item>
  745. <el-form-item prop="parentName" label="上级角色:">
  746. <el-input v-model="permissionEditRoleObj.parentName" placeholder="无上级角色" disabled style="width: 220px">
  747. <el-option v-for="item in permissionList" :key="item.value" :label="item.label"
  748. :value="item.value"></el-option>
  749. </el-input>
  750. </el-form-item>
  751. <el-form-item prop="market" label="地区" required>
  752. <el-input v-model="permissionEditRoleObj.market" placeholder="请输入所属地区" style="width: 220px" disabled/>
  753. </el-form-item>
  754. <el-form-item prop="checkedKeys" label="权限列表:" required>
  755. <el-tree v-if="data.length > 0" :data="data" show-checkbox node-key="id" ref="treeRef"
  756. :props="{ label: 'menuName', children: 'children' }"
  757. :default-checked-keys="permissionEditRoleObj.checkedKeys"
  758. :check-strictly="false"
  759. @check="handleEditRolePermissionCheck">
  760. <template #default="{ node, data }">
  761. <span>{{ node.label }}</span>
  762. </template>
  763. </el-tree>
  764. <div v-else style="display: flex; align-items: center; gap: 8px;">
  765. <span style="color: #999;">暂无数据</span>
  766. </div>
  767. </el-form-item>
  768. <!-- <el-form-item prop="grade" label="优先级:" required>
  769. <el-input v-model="permissionEditRoleObj.grade" placeholder="数字1~999" style="width: 220px" />
  770. </el-form-item> -->
  771. </el-form>
  772. <div>
  773. <el-button @click="permissionEditRoleVisible = false">取消</el-button>
  774. <el-button type="primary" @click="permissionEditRole">
  775. 提交
  776. </el-button>
  777. </div>
  778. </template>
  779. </el-dialog>
  780. </template>
  781. <style scoped>
  782. .pagination {
  783. display: flex;
  784. }
  785. .head-card {
  786. display: flex;
  787. }
  788. .head-card-btn {
  789. margin-left: auto;
  790. }
  791. .permission-cell {
  792. cursor: pointer;
  793. color: #409eff;
  794. /* 蓝色文字,提示可点击 */
  795. }
  796. </style>