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.

742 lines
24 KiB

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