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.

1273 lines
42 KiB

3 weeks ago
1 month ago
3 weeks ago
3 weeks ago
4 weeks ago
1 month ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
2 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
3 weeks ago
3 weeks ago
3 weeks ago
  1. <script setup>
  2. import { ref, onMounted, reactive, computed, watch } from 'vue'
  3. import ElementPlus from 'element-plus'
  4. import { ElMessage, ElMessageBox } from 'element-plus'
  5. import axios from 'axios'
  6. import moment from 'moment'
  7. import {InfoFilled, UserFilled} from '@element-plus/icons-vue'
  8. import _ from 'lodash'
  9. import request from '@/util/http'
  10. import API from '@/util/http'
  11. // 客户明细表格 什么表格???????
  12. const tableData = ref([])
  13. const roleData = ref([])
  14. const total = ref(100)
  15. const roleTotal = ref(100)//角色分页
  16. const checkTab = ref('admin')
  17. // 搜索admin
  18. const admin = ref({
  19. account: '',
  20. market: '',
  21. postiton: ''
  22. })
  23. // 角色搜索
  24. const role = ref({
  25. name: ''
  26. })
  27. // 搜索对象
  28. const getObj = ref({
  29. pageNum: 1,
  30. pageSize: 10
  31. })
  32. // 角色搜索对象
  33. const getRoleObj = ref({
  34. pageNum: 1,
  35. pageSize: 10
  36. })
  37. // 新增用户权限弹窗
  38. const userAddVisible = ref(false)
  39. // 编辑用户权限弹窗
  40. const userEditVisible = ref(false)
  41. //选地区
  42. const market = ref([])
  43. // 选部门
  44. const postiton = ref([])
  45. // 新增用户对象
  46. const userAddObj = ref({})
  47. // 新增角色对象
  48. const permissionAddObj = ref({})
  49. // 新增角色弹窗
  50. const permissionAddVisible = ref(false)
  51. // 新增用户权限对象,机器码要实现存储多个,addMachineIdInput方法实现
  52. const addAdmin = ref({
  53. account: '',
  54. name: '',
  55. market: [],
  56. permission: '',
  57. postiton: '',
  58. machineIds: [''], // 动态添加的机器码输入框
  59. machineId: '',
  60. remark: ''
  61. })
  62. // 新增角色对象
  63. const addRole = ref({
  64. roleName: '',
  65. parentId: null,
  66. checkedKeys: [],
  67. grade: '',
  68. market: ''
  69. })
  70. // 新增角色的权限列表
  71. const permissionSelect = ref()
  72. //这是获取用户信息的接口
  73. const adminData = ref({})
  74. const getAdminData = async function () {
  75. try {
  76. const result = await API({ url: '/admin/userinfo', data: {} })
  77. adminData.value = result
  78. // console.log('请求成功', result)
  79. console.log('管理员用户信息', adminData.value)
  80. } catch (error) {
  81. console.log('请求失败', error)
  82. }
  83. }
  84. // 编辑用户权限对象
  85. const permissionEditObj = ref({
  86. checkedKeys: [],
  87. machineIds: [''],
  88. machineId: '',
  89. password: '',
  90. })
  91. const addMachineIdInput = function () {
  92. if (addAdmin.value.machineIds.length >= 2) {
  93. ElMessage.warning('设备数量已达上限')
  94. return
  95. }
  96. addAdmin.value.machineIds.push('')
  97. }
  98. const UseraddMachineIdInput = function () {
  99. if (permissionEditObj.value.machineIds.length >= 2) {
  100. ElMessage.warning('设备数量已达上限')
  101. return
  102. }
  103. permissionEditObj.value.machineIds.push('')
  104. }
  105. // 删除权限对象
  106. const delObj = ref({})
  107. // 删除角色对象
  108. const delRoleObj = ref({})
  109. const get = async function (val) {
  110. try {
  111. if (typeof val === 'number') {
  112. getObj.value.pageNum = val
  113. }
  114. console.log('搜索参数', getObj.value, admin.value)
  115. const result = await request({
  116. url: '/permission/getPermission',
  117. data: {
  118. ...getObj.value,
  119. permission: {
  120. ...admin.value
  121. }
  122. }
  123. })
  124. tableData.value = result.data.list
  125. console.log('tableData', tableData.value)
  126. total.value = result.data.total
  127. } catch (error) {
  128. console.log('请求失败', error)
  129. }
  130. }
  131. const getRoleList = async function (val) {
  132. try {
  133. if (typeof val === 'number') {
  134. getObj.value.pageNum = val
  135. }
  136. console.log('搜索参数', getObj.value, role.value)
  137. const result = await request({
  138. url: '/role/selectBy',
  139. data: {
  140. ...getRoleObj.value,
  141. roleVo: {
  142. roleName: role.value.name
  143. }
  144. }
  145. })
  146. roleData.value = result.data.list
  147. console.log('roleData', roleData.value)
  148. roleTotal.value = result.data.total
  149. } catch (error) {
  150. console.log('请求失败', error)
  151. }
  152. }
  153. // 试试D老师的方法
  154. const formatPermissions = (tree) => {
  155. if (!tree || tree.length === 0) return '';
  156. return tree.map(menu => {
  157. const mainMenu = menu.menuName;
  158. const subMenus = menu.children?.map(child => child.menuName) || [];
  159. // 如果有子菜单,显示前2个子菜单名称
  160. if (subMenus.length > 0) {
  161. const maxSub = Math.min(2, subMenus.length);
  162. const subText = subMenus.slice(0, maxSub).join('、');
  163. const moreText = subMenus.length > maxSub ? '...' : '';
  164. return `${mainMenu}+${subText}${moreText}`;
  165. }
  166. // 没有子菜单时只显示主菜单
  167. return mainMenu;
  168. }).join('+');
  169. };
  170. const trimJwCode = () => {
  171. if (admin.value.account) {
  172. admin.value.account = admin.value.account.replace(/\s/g, '');
  173. }
  174. }
  175. const search = function () {
  176. trimJwCode();
  177. getObj.value.pageNum = 1
  178. get()
  179. }
  180. const searchRole = function () {
  181. trimJwCode();
  182. getObj.value.pageNum = 1
  183. getRoleList()
  184. }
  185. // 重置
  186. const reset = function () {
  187. admin.value = {}
  188. }
  189. const getArea = async function () {
  190. try {
  191. const result = await request({
  192. url: '/permission/getmarket',
  193. data: {}
  194. })
  195. market.value = result.data
  196. } catch (error) {
  197. console.log('请求失败', error)
  198. }
  199. }
  200. // 获取部门
  201. const getStore = async function () {
  202. try {
  203. const result = await request({
  204. url: '/permission/getposition',
  205. data: {}
  206. })
  207. postiton.value = result.data
  208. } catch (error) {
  209. console.log('请求失败', error)
  210. }
  211. }
  212. // 打开新增用户权限弹窗
  213. const openUserAddVisible = function () {
  214. getRoles()
  215. userAddVisible.value = true
  216. addAdmin.value = {
  217. account: '',
  218. name: '',
  219. market: '',
  220. permission: '',
  221. postiton: '',
  222. machineId: '',
  223. machineIds: [''],
  224. remark: ''
  225. };
  226. }
  227. // 新增角色弹窗
  228. const openPermissionAddVisible = function () {
  229. permissionAddVisible.value = true
  230. getRoles()
  231. getLists()
  232. }
  233. // 关闭新增用户权限弹窗,并刷新表单
  234. const closeUserAddVisible = function () {
  235. addAdmin.value = {
  236. account: '',
  237. name: '',
  238. market: '',
  239. permission: '',
  240. postiton: '',
  241. machineId: '',
  242. machineIds: [''],
  243. remark: ''
  244. };
  245. userAddVisible.value = false;
  246. // 清除表单验证状态
  247. Ref.value.resetFields();
  248. }
  249. const closePermissionAddVisible = function () {
  250. addRole.value = {
  251. roleName: '',
  252. parentId: null,
  253. checkedKeys: [],
  254. grade: '',
  255. market: ''
  256. }
  257. permissionAddVisible.value = false
  258. Ref.value.resetFields();
  259. getRoleList()
  260. }
  261. // 新增用户权限初始化
  262. const userAddInit = function () {
  263. userAddObj.value = {}
  264. openUserAddVisible()
  265. }
  266. // 新增角色初始化
  267. const permissionAddInit = function () {
  268. permissionAddObj.value = {}
  269. openPermissionAddVisible()
  270. }
  271. //新增用户
  272. const permissionAdd = async function () {
  273. Ref.value.validate(async (valid) => {
  274. console.log('addRole', addRole.value)
  275. console.log('valid', valid)
  276. if (valid) {
  277. try {
  278. addAdmin.value.adminFlag = 1
  279. addAdmin.value.status1 = 1
  280. if (addAdmin.value.postiton == '管理员') {
  281. addAdmin.value.postiton == 1
  282. }
  283. const params = {
  284. "account": addAdmin.value.account,//OA号
  285. "adminName": addAdmin.value.name,//姓名
  286. "market": addAdmin.value.market,//地区
  287. "roleId": addAdmin.value.permission,//权限ID
  288. "postiton": addAdmin.value.postiton,//职位
  289. "machineId": addAdmin.value.machineIds[0],//机器码
  290. "remark": addAdmin.value.remark//备注
  291. }
  292. const result = await request({
  293. url: '/permission/addPermission',
  294. data: params
  295. })
  296. console.log(addAdmin.value)
  297. if (result.code == 200) {
  298. ElMessage.success('添加成功')
  299. } else {
  300. ElMessage.error(result.msg)
  301. }
  302. addAdmin.value = {}
  303. get()
  304. closeUserAddVisible()
  305. } catch (error) {
  306. console.log('新增用户权限失败', error)
  307. ElMessage.error('新增用户权限失败')
  308. closeUserAddVisible()
  309. }
  310. } else {
  311. ElMessage({
  312. type: 'error',
  313. message: '请检查输入内容'
  314. })
  315. }
  316. })
  317. }
  318. // 表单验证ref
  319. const Ref = ref(null)
  320. // 使用 _.throttle 并设置 trailing 为 false 实现严格节流,只执行一次
  321. const throttledPermissionAdd = _.throttle(permissionAdd, 5000, {
  322. trailing: false
  323. })
  324. // 权限类别
  325. const permissionList = ref([])
  326. const getRoles = async function () {
  327. try {
  328. const res = await API({ url: '/role/selectAll' })
  329. permissionList.value = res.data.map(item => ({
  330. label: item.roleName,
  331. value: item.id
  332. }))
  333. console.log('权限列表:', permissionList.value)
  334. } catch (error) {
  335. console.error('获取权限列表失败:', error)
  336. }
  337. }
  338. // 打开编辑用户权限弹窗
  339. const openUserEditVisible = function () {
  340. getRoles()
  341. userEditVisible.value = true
  342. }
  343. // 关闭编辑用户权限弹窗
  344. const closeUserEditVisible = function () {
  345. userEditVisible.value = false
  346. }
  347. // 编辑用户权限初始化
  348. const permissionEditInit = async function (row) {
  349. console.log('row', row)
  350. permissionEditObj.value = {}
  351. permissionEditObj.value.id = row.id
  352. permissionEditObj.value.account = row.account
  353. permissionEditObj.value.adminName = row.name
  354. permissionEditObj.value.remark = row.remark
  355. permissionEditObj.value.market = row.market
  356. permissionEditObj.value.password = ''
  357. // 将字符串形式的 market 转换为数组
  358. if (typeof row.market === 'string' && row.market) {
  359. permissionEditObj.value.market = row.market.split(',');
  360. } else {
  361. // 处理空值或非字符串情况
  362. permissionEditObj.value.market = [];
  363. }
  364. permissionEditObj.value.postiton = row.postiton
  365. permissionEditObj.value.roleId = row.roleId
  366. const result = await request({
  367. url: '/role/selectFather',
  368. data: {
  369. id: row.roleId
  370. }
  371. })
  372. console.log('初始查上级权限', result)
  373. permissionEditObj.value.parentId = result.data?.fatherId
  374. permissionEditObj.value.parentName = result.data?.fatherName
  375. console.log('get前', permissionEditObj.value.roleId);
  376. getUserLists(row.roleId)
  377. let machineIdsRef = await request({
  378. url: '/permission/getPermission',
  379. data: {
  380. "pageNum": 1,//页码数
  381. "pageSize": 1,//页条数
  382. "permission": {
  383. account: row.account,//OA号
  384. }
  385. }
  386. })
  387. if (machineIdsRef.data.list[0].machineIds == null || machineIdsRef.data.list[0].machineIds.length == 0) {
  388. permissionEditObj.value.machineIds = ['']
  389. } else {
  390. permissionEditObj.value.machineIds = machineIdsRef.data.list[0].machineIds
  391. }
  392. permissionEditObj.value.machineId = permissionEditObj.value.machineIds[0]
  393. //permissionEditObj.value.permission = row.permission
  394. permissionEditObj.value.roleName = row.roleName
  395. console.log('编辑用户权限', permissionEditObj.value)
  396. console.log('11111111111111', permissionEditObj.value.machineId)
  397. openUserEditVisible()
  398. }
  399. const collectIds = (tree) => {
  400. let ids = [];
  401. tree.forEach((node) => {
  402. ids.push(node.id);
  403. if (node.children && node.children.length > 0) {
  404. ids = ids.concat(collectIds(node.children));
  405. }
  406. });
  407. return ids;
  408. };
  409. // 定义上级角色提示变量
  410. const parentRoleTip = ref('');
  411. //给data数据加上disabled属性,控制是否禁用
  412. function processTreeData(data) {
  413. return data.map(item => ({
  414. ...item,
  415. disabled: item.id != null || item.menuName.includes("敏感权限"), //控制权限显示的条件
  416. children: item.children ? processTreeData(item.children) : []
  417. }));
  418. }
  419. //根据上级角色控制权限列表,选择角色调整上级角色
  420. const getUserLists = async function (selectedRoleId) {
  421. try {
  422. console.log('permissionEditObj.value.roleId:', permissionEditObj.value.roleId)
  423. console.log('selectedRoleId', selectedRoleId);
  424. permissionEditObj.value.parentId = null;
  425. permissionEditObj.value.parentName = '';
  426. permissionEditObj.value.checkedKeys = [];
  427. parentRoleTip.value = '';
  428. const parentRes = await request({
  429. url: '/role/selectFather',
  430. data: { id: selectedRoleId } // 用选中的角色ID请求
  431. });
  432. const parentId = parentRes.data.fatherId;
  433. const parentName = parentRes.data.parentName;
  434. permissionEditObj.value.parentId = parentId;
  435. permissionEditObj.value.parentName = parentName;
  436. if (parentId == null) {
  437. // 无上级角色:显示提示
  438. parentRoleTip.value = '该角色无上级角色';
  439. }
  440. let roleId = permissionEditObj.value.roleId
  441. if (permissionEditObj.value.parentId === null || permissionEditObj.value.parentId === undefined) {
  442. roleId = 2
  443. }
  444. const res = await API({
  445. url: '/menu/tree',
  446. data: { id: roleId }
  447. })
  448. data.value = processTreeData(res.data)
  449. permissionEditObj.value.checkedKeys = collectIds(res.data) || [];
  450. console.log('看看data', data.value)
  451. console.log('看checkedKeys', permissionEditObj.value.checkedKeys)
  452. console.log('parentID:', permissionEditObj.value.parentId, 'roleId:', roleId)
  453. console.log('permissionEditObj.value.roleId:', permissionEditObj.value.roleId)
  454. } catch (error) {
  455. console.log('请求失败', error)
  456. }
  457. }
  458. // 编辑用户权限提交
  459. const permissionEdit = async function () {
  460. const { adminName: userName, roleName: oldRole, roleId: newRoleId } = permissionEditObj.value;
  461. const newRole = permissionList.value.find(item => item.value === newRoleId)?.label || '未知角色';
  462. try {
  463. await ElMessageBox.confirm(
  464. `确认修改权限角色?\n您正在将【${userName}】的权限角色从【${oldRole}】修改为【${newRole}\n变更后,该用户的可操作权限将同步更新为新角色配置,涉及数据访问、功能操作等权限变化,请谨慎确认。`,
  465. '警告',
  466. {
  467. confirmButtonText: '确认',
  468. cancelButtonText: '取消',
  469. type: "warning",
  470. lockScroll: false
  471. }
  472. );
  473. closeUserEditVisible();
  474. const result = await request({
  475. url: '/permission/updateAdmin',
  476. data: {
  477. account: permissionEditObj.value.account,//OA号
  478. adminName: permissionEditObj.value.adminName,//姓名
  479. market: permissionEditObj.value.market,//地区
  480. postiton: permissionEditObj.value.postiton,//职位
  481. roleId: permissionEditObj.value.roleId,//角色id
  482. machineId: permissionEditObj.value.machineIds[0],//机器码
  483. machineIds: permissionEditObj.value.machineIds[1],//机器码
  484. password: permissionEditObj.value.password,//
  485. remark: permissionEditObj.value.remark//备注
  486. }
  487. });
  488. console.log('编辑最后提交数据', permissionEditObj.value);
  489. if (result.code == 200) {
  490. await ElMessageBox.alert(
  491. `用户${userName}的权限角色已更改为【${newRole}`,
  492. '成功',
  493. {
  494. confirmButtonText: '确定',
  495. type: 'success' // 设置为 success 类型
  496. }
  497. );
  498. get();
  499. } else {
  500. ElMessage.error(result.msg)
  501. }
  502. } catch (error) {
  503. console.log('编辑用户权限失败', error)
  504. ElMessage.error('编辑用户权限失败')
  505. closeUserEditVisible()
  506. }
  507. }
  508. const throttledPermissionEdit = _.throttle(permissionEdit, 5000, {
  509. trailing: false
  510. })
  511. // 删除初始化
  512. const del = function (row) {
  513. delObj.value = {}
  514. console.log(row, '删除初始化')
  515. delObj.value.account = row.account
  516. delObj.value.id = row.id
  517. }
  518. // 删除权限
  519. const delConfirm = async function () {
  520. try {
  521. const result = await request({
  522. url: '/permission/deleteAdmin',
  523. data: delObj.value
  524. })
  525. console.log('看看删除对象', delObj.value)
  526. console.log('请求成功1', result)
  527. ElMessage.success('删除权限成功')
  528. delObj.value = {}
  529. get()
  530. } catch (error) {
  531. console.log('删除权限失败', error)
  532. ElMessage.error('删除权限失败')
  533. }
  534. }
  535. // 删除角色初始化
  536. const delRole = function (row) {
  537. delRoleObj.value = {}
  538. console.log(row, '删除初始化')
  539. delRoleObj.value.id = row.id
  540. }
  541. // 删除角色
  542. const delRoleConfirm = async function () {
  543. try {
  544. const result = await request({
  545. url: '/role/delete',
  546. data: delRoleObj.value
  547. })
  548. console.log('看看删除角色对象', delRoleObj.value)
  549. console.log('请求成功2', result)
  550. ElMessage.success('删除权限成功')
  551. delRoleObj.value = {}
  552. getRoleList()
  553. } catch (error) {
  554. console.log('删除权限失败', error)
  555. ElMessage.error('删除权限失败')
  556. }
  557. }
  558. const handleAddRole = async function () {
  559. try {
  560. await new Promise((resolve, reject) => {
  561. Ref.value.validate((valid) => {
  562. if (valid) {
  563. resolve(); // 验证通过,继续执行后续代码
  564. } else {
  565. reject(new Error('请检查并完善表单信息')); // 验证失败,抛出错误
  566. }
  567. });
  568. });
  569. const res = await API({
  570. url: '/role/add',
  571. data: {
  572. "roleName": addRole.value.roleName,
  573. "menuIds": addRole.value.checkedKeys,
  574. "priority": addRole.value.grade,
  575. "fatherId": addRole.value.parentId,
  576. "market": addRole.value.market
  577. }
  578. })
  579. console.log('成功了,看看addRole', addRole.value)
  580. closePermissionAddVisible()
  581. } catch (error) {
  582. console.log('请求失败', error)
  583. console.log('失败,看看addRole', addRole.value);
  584. }
  585. }
  586. // 禁用启用用户权限
  587. const editStatus = async function (row) {
  588. try {
  589. console.log(row)
  590. permissionEditObj.value = {}
  591. permissionEditObj.value.id = row.id
  592. permissionEditObj.value.account = row.account
  593. permissionEditObj.value.adminStatus = row.adminStatus
  594. console.log('修改用户权限状态', permissionEditObj.value)
  595. const result = await request({
  596. url: '/permission/upadatePermission',
  597. data: permissionEditObj.value
  598. })
  599. console.log('请求成功2', result)
  600. ElMessage.success(
  601. permissionEditObj.value.adminStatus == 1 ? '启用成功' : '禁用成功'
  602. )
  603. permissionEditObj.value = {}
  604. get()
  605. } catch (error) {
  606. console.log('修改用户权限失败', error)
  607. }
  608. }
  609. const handlePageSizeChange = function (val) {
  610. getObj.value.pageSize = val
  611. get()
  612. }
  613. const handleCurrentChange = function (val) {
  614. getObj.value.pageNum = val
  615. get()
  616. }
  617. const handleRolePageSizeChange = (val) => {
  618. getRoleObj.value.pageSize = val
  619. getRoleList() // 调用角色管理的查询
  620. }
  621. // 角色管理分页 - 当前页变化
  622. const handleRoleCurrentChange = (val) => {
  623. getRoleObj.value.pageNum = val
  624. getRoleList() // 调用角色管理的查询
  625. }
  626. const data = ref([])
  627. const getLists = async function () {
  628. try {
  629. let roleId = addRole.value.parentId
  630. if (addRole.value.parentId === null || addRole.value.parentId === undefined) {
  631. roleId = 2
  632. }
  633. const res = await API({
  634. url: '/menu/tree',
  635. data: { id: roleId }
  636. })
  637. data.value = res.data
  638. if (addRole.value.parentId != 2) {
  639. data.value = data.value.filter(item => item.id !== 9);
  640. }
  641. console.log('看看data', data.value)
  642. console.log('parentID:', addRole.value.parentId, 'roleId:', roleId)
  643. } catch (error) {
  644. console.log('请求失败', error)
  645. }
  646. }
  647. const handleMarketChange = (values) => {
  648. console.log('values的类型:', typeof values);
  649. console.log('values的值:', values);
  650. //判断是否选择了总部
  651. const hasHeadquarters = values.includes('总部');
  652. if (hasHeadquarters) {
  653. // 如果选择了总部,只保留总部
  654. addAdmin.value.market = ['总部'];
  655. }
  656. console.log('看看现在的地区',addAdmin.value.market);
  657. };
  658. const includeHq = computed(() => {
  659. const i = addAdmin.value.market.includes('总部')
  660. return (item) => i && item != '总部'
  661. })
  662. const EditincludeHq = computed(() => {
  663. const i = permissionEditObj.value.market.includes('总部')
  664. return (item) => i && item != '总部'
  665. })
  666. const EdithandleMarketChange = (values) => {
  667. //判断是否选择了总部
  668. const hasHeadquarters = values.includes('总部');
  669. if (hasHeadquarters) {
  670. // 如果选择了总部,只保留总部
  671. permissionEditObj.value.market = ['总部'];
  672. }
  673. console.log('看看现在的地区',permissionEditObj.value.market);
  674. };
  675. const handleCheckChange = (checkedNodes, { checkedKeys }) => {
  676. addRole.value.checkedKeys = checkedKeys;
  677. }
  678. //点击角色权限菜单树点击展示逻辑
  679. const menuTreeVisible = ref(false);
  680. const currentRoleMenuTree = ref([]);
  681. const currentRoleName = ref('');
  682. const Rolecheckedkeys = ref([])
  683. const showMenuTree = (treeData, roleName) => {
  684. currentRoleMenuTree.value = processTreeData(treeData) || [];
  685. console.log('currentRoleMenuTree.value', currentRoleMenuTree.value);
  686. Rolecheckedkeys.value = collectIds(treeData)
  687. console.log('Rolecheckedkeys', Rolecheckedkeys.value);
  688. currentRoleName.value = roleName || '权限详情';
  689. menuTreeVisible.value = true;
  690. };
  691. // 重置密码弹窗状态
  692. const resetConfirmVisible = ref(false)
  693. // 当前选中的行数据
  694. const currentRow = ref(null)
  695. // 重置密码
  696. const resetPassword = function (row) {
  697. // 显示确认弹窗
  698. currentRow.value = row
  699. resetConfirmVisible.value = true
  700. }
  701. // 确认重置密码
  702. const confirmResetPassword = async function () {
  703. // 处理markets数据
  704. if (typeof adminData.value.markets === 'string' && adminData.value.markets) {
  705. adminData.value.markets = adminData.value.markets.split(',');
  706. } else {
  707. adminData.value.markets = [];
  708. }
  709. console.log("地区",adminData.value.markets[0])
  710. // 权限检查
  711. await getAdminData()
  712. if (adminData.value.markets.includes(currentRow.value.market) || adminData.value.markets === '总部') {
  713. console.log('符合条件,可以操作',adminData.value.markets.includes(currentRow.value.market) || adminData.value.markets === '总部');
  714. const params = {
  715. account: currentRow.value.account,
  716. }
  717. console.log(params);
  718. // 发送请求
  719. try {
  720. const result = await request({
  721. url: '/admin/reset',
  722. method: 'post',
  723. data: params // 直接传递params对象
  724. });
  725. if (result.code === 200) { // 使用严格相等运算符
  726. ElMessage.success('重置密码成功');
  727. resetConfirmVisible.value = false; // 关闭弹窗
  728. } else {
  729. ElMessage.error(result.message || '重置密码失败');
  730. }
  731. } catch (error) {
  732. ElMessage.error('重置密码失败');
  733. console.error('请求错误:', error);
  734. }
  735. } else {
  736. // console.log("为什么不能重置",adminData.value.markets)
  737. ElMessage.error('您没有修改' + currentRow.value.market + '地区的用户密码的权限');
  738. resetConfirmVisible.value = false; // 关闭弹窗
  739. }
  740. }
  741. // 取消重置密码
  742. const cancelResetPassword = function () {
  743. resetConfirmVisible.value = false
  744. }
  745. /*//用户密码重置
  746. const resetPassword = function (row) {
  747. console.log('adminData.value.markets', adminData.value.markets);
  748. // 处理markets数据
  749. if (typeof adminData.value.markets === 'string' && adminData.value.markets) {
  750. adminData.value.markets = adminData.value.markets.split(',');
  751. } else {
  752. adminData.value.markets = [];
  753. }
  754. if (adminData.value.markets.includes(row.market)||adminData.value.markets=='总部') {
  755. console.log('符合条件,可以操作');
  756. // 用then处理确认,catch处理取消和错误
  757. ElMessageBox.confirm(
  758. `确认重置该账号密码?`,
  759. '提示',
  760. {
  761. confirmButtonText: '确认',
  762. cancelButtonText: '取消',
  763. type: "warning",
  764. lockScroll: false
  765. }
  766. ).then(async () => {
  767. // 仅当用户确认时执行
  768. try {
  769. const res = await API({
  770. url: '/admin/reset',
  771. data: { account: row.account }
  772. });
  773. if (res.code === 200) {
  774. ElMessage.success(res.data);
  775. }
  776. } catch (error) {
  777. ElMessage.error('请求失败: ' + (error.message || error));
  778. }
  779. }).catch(() => {
  780. // 取消操作,可选择性添加日志
  781. console.log('用户取消了重置密码操作');
  782. });
  783. }else{
  784. ElMessage.error('您没有修改'+row.market+'地区的用户密码的权限')
  785. }
  786. }*/
  787. const Rolerules = reactive({
  788. roleName: [
  789. { required: true, message: '请输入角色名称', trigger: 'blur' },
  790. { min: 2, max: 20, message: '角色名称长度应在2-20个字符之间', trigger: 'blur' }
  791. ],
  792. market: [
  793. { required: true, message: '请选择所属地区', trigger: 'change' }
  794. ],
  795. grade: [
  796. { required: true, message: '请输入优先级', trigger: 'blur' },
  797. { pattern: /^[1-9]\d{0,2}$/, message: '优先级应为1-999的数字', trigger: 'blur' }
  798. ]
  799. });
  800. // 挂载
  801. onMounted(async function () {
  802. await getAdminData()
  803. await get()
  804. await getArea()
  805. await getStore()
  806. await getRoleList()
  807. })
  808. </script>
  809. <template>
  810. <div style="margin-bottom:20px">
  811. <el-button-group>
  812. <el-button :type="checkTab === 'admin' ? 'primary' : 'default'" @click="checkTab = 'admin'">
  813. 用户管理
  814. </el-button>
  815. <el-button :type="checkTab === 'role' ? 'primary' : 'default'" @click="checkTab = 'role'">
  816. 角色管理
  817. </el-button>
  818. </el-button-group>
  819. </div>
  820. <div v-show="checkTab === 'admin'">
  821. <!-- 用户搜索和展示 -->
  822. <el-row>
  823. <el-col>
  824. <el-card style="margin-bottom: 20px">
  825. <div class="head-card">
  826. <div class="head-card-element">
  827. <el-text class="mx-1" size="large">OA号</el-text>
  828. <el-input v-model="admin.account" style="width: 240px" placeholder="请输入OA号" clearable />
  829. </div>
  830. <div class="head-card-element" style="margin-left: 50px">
  831. <el-text class="mx-1" size="large">所属地区</el-text>
  832. <el-select v-model="admin.market" placeholder="请选择所属地区" style="width: 240px" clearable>
  833. <el-option v-for="item in market" :key="item" :label="item" :value="item" />
  834. </el-select>
  835. </div>
  836. <div class="head-card-element" style="margin-left: 50px">
  837. <el-text class="mx-1" size="large">职位名称</el-text>
  838. <el-select v-model="admin.postiton" placeholder="请选择职位名称" style="width: 240px" clearable>
  839. <el-option v-for="item in postiton" :key="item" :label="item" :value="item" />
  840. </el-select>
  841. </div>
  842. <div class="head-card-btn">
  843. <el-button type="success" @click="reset()">重置</el-button>
  844. <el-button type="primary" @click="search()">查询</el-button>
  845. </div>
  846. </div>
  847. </el-card>
  848. </el-col>
  849. </el-row>
  850. <el-row>
  851. <el-col>
  852. <el-card>
  853. <!-- 展示表单 -->
  854. <div class="add-item">
  855. <el-button style="color: #048efb; border: 1px solid #048efb" @click="userAddInit()">新增用户</el-button>
  856. </div>
  857. <div>
  858. <el-table :data="tableData" style="width: 100%" show-overflow-tooltip>
  859. <el-table-column type="index" label="序号" width="100px" fixed="left">
  860. <template #default="scope">
  861. <span>{{
  862. scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
  863. }}</span>
  864. </template>
  865. </el-table-column>
  866. <el-table-column prop="account" label="OA号" />
  867. <el-table-column prop="name" label="姓名" />
  868. <el-table-column prop="market" label="所属地区" />
  869. <el-table-column prop="postiton" label="职位" />
  870. <el-table-column prop="roleName" label="部门权限">
  871. </el-table-column>
  872. <el-table-column prop="remark" label="备注" />
  873. <el-table-column prop="operation" label="操作" width="280px">
  874. <template #default="scope">
  875. <el-button type="warning" text @click="resetPassword(scope.row)">
  876. 重置密码
  877. </el-button>
  878. <el-button type="primary" text @click="permissionEditInit(scope.row)"
  879. :disabled="scope.row.adminStatus === 0 || scope.row.account === adminData.account">
  880. 修改权限
  881. </el-button>
  882. <el-popconfirm title="确定将此用户删除吗?" @confirm="delConfirm">
  883. <template #reference>
  884. <el-button type="danger" text @click="del(scope.row)"
  885. :disabled="scope.row.adminStatus === 0 || scope.row.account === adminData.account">
  886. 删除
  887. </el-button>
  888. </template>
  889. <template #actions="{ confirm, cancel }">
  890. <el-button size="small" @click="cancel">取消</el-button>
  891. <el-button type="primary" size="small" @click="confirm">
  892. 确定
  893. </el-button>
  894. </template>
  895. </el-popconfirm>
  896. </template>
  897. </el-table-column>
  898. <el-table-column prop="adminStatus" label="状态">
  899. <template #default="scope">
  900. <el-switch v-model="scope.row.adminStatus" :active-value="1" :inactive-value="0" size="large"
  901. :disabled="scope.row.account === adminData.account" @change="editStatus(scope.row)" style="
  902. --el-switch-on-color: #13ce66;
  903. --el-switch-off-color: #ff4949;
  904. " active-text="启用" inactive-text="禁用" inline-prompt />
  905. </template>
  906. </el-table-column>
  907. </el-table>
  908. </div>
  909. <!-- 分页 -->
  910. <div class="pagination" style="margin-top: 20px">
  911. <el-pagination background :page-size="getObj.pageSize" :page-sizes="[5, 10, 20, 50, 100]"
  912. layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handlePageSizeChange"
  913. @current-change="handleCurrentChange"></el-pagination>
  914. </div>
  915. </el-card>
  916. </el-col>
  917. </el-row>
  918. </div>
  919. <div v-show="checkTab === 'role'">
  920. <!-- 角色搜索 -->
  921. <el-card style="margin-bottom: 20px">
  922. <div class="head-card">
  923. <el-text class="mx-1" size="large">角色名称</el-text>
  924. <el-input v-model="role.name" style="width: 240px" placeholder="请输入角色名称" clearable />
  925. <div class="head-card-btn">
  926. <el-button type="success" @click="reset()">重置</el-button>
  927. <el-button type="primary" @click="searchRole()">查询</el-button>
  928. </div>
  929. </div>
  930. </el-card>
  931. <!-- 展示表单 -->
  932. <el-card>
  933. <div class="add-item">
  934. <el-button style="color: #048efb; border: 1px solid #048efb" @click="permissionAddInit()">新增角色</el-button>
  935. </div>
  936. <div>
  937. <el-table :data="roleData" style="width: 100%" show-overflow-tooltip>
  938. <el-table-column type="index" label="序号" width="100px" fixed="left">
  939. <template #default="scope">
  940. <span>{{
  941. scope.$index + 1 + (getRoleObj.pageNum - 1) * getRoleObj.pageSize
  942. }}</span>
  943. </template>
  944. </el-table-column>
  945. <el-table-column prop="roleName" label="角色名称" />
  946. <el-table-column prop="fatherName" label="上级角色" />
  947. <el-table-column prop="priority" label="优先级" />
  948. <el-table-column label="权限范围" show-overflow-tooltip>
  949. <template #default="scope">
  950. <div class="permission-cell" @click="showMenuTree(scope.row.tree, scope.row.roleName)">
  951. {{ formatPermissions(scope.row.tree) }}
  952. </div>
  953. </template>
  954. </el-table-column>
  955. <el-table-column prop="operation" label="操作" width="200px">
  956. <template #default="scope">
  957. <el-popconfirm title="确定将此角色删除吗?" @confirm="delRoleConfirm">
  958. <template #reference>
  959. <el-button type="danger" text @click="delRole(scope.row)"
  960. :disabled="scope.row.id === 1 || scope.row.id === 2">
  961. 删除
  962. </el-button>
  963. </template>
  964. <template #actions="{ confirm, cancel }">
  965. <el-button size="small" @click="cancel">取消</el-button>
  966. <el-button type="primary" size="small" @click="confirm">
  967. 确定
  968. </el-button>
  969. </template>
  970. </el-popconfirm>
  971. </template>
  972. </el-table-column>
  973. </el-table>
  974. </div>
  975. <!-- 分页 -->
  976. <div class="pagination" style="margin-top: 20px">
  977. <el-pagination background :page-size="getObj.pageSize" :page-sizes="[5, 10, 20, 50, 100]"
  978. layout="total, sizes, prev, pager, next, jumper" :total="roleTotal" @size-change="handleRolePageSizeChange"
  979. @current-change="handleRoleCurrentChange"></el-pagination>
  980. </div>
  981. </el-card>
  982. </div>
  983. <!-- 角色菜单树展示 -->
  984. <el-dialog v-model="menuTreeVisible" :title='`权限详情:${currentRoleName}`' width="600px">
  985. <el-tree :data="currentRoleMenuTree" node-key="id" :props="{ label: 'menuName', children: 'children' }"
  986. show-checkbox check-strictly :expand-on-click-node="false"
  987. :default-expanded-keys="currentRoleMenuTree.map(item => item.id)" :default-checked-keys="Rolecheckedkeys" />
  988. <template #footer>
  989. <el-button @click="menuTreeVisible = false" type="primary">关闭</el-button>
  990. </template>
  991. </el-dialog>
  992. <!-- 新增用户权限 -->
  993. <el-dialog v-model="userAddVisible" title="新增用户权限" width="800px" :close-on-click-modal="false">
  994. <template #footer>
  995. <!-- 居中显示 -->
  996. <el-form ref="Ref" :model="addAdmin" label-width="auto" style="max-width: 600px; align-items: center">
  997. <el-form-item prop="account" label="OA号:" required clearable>
  998. <el-input v-model="addAdmin.account" placeholder="请输入OA号" style="width: 220px" />
  999. </el-form-item>
  1000. <el-form-item prop="name" label="用户名:" required clearable>
  1001. <el-input v-model="addAdmin.name" placeholder="请输入用户名" style="width: 220px" />
  1002. </el-form-item>
  1003. <el-form-item prop="market" label="所属地区:" required clearable>
  1004. <el-select multiple v-model="addAdmin.market" placeholder="请选择所属地区" style="width: 440px" clearable
  1005. @change="handleMarketChange">
  1006. <el-option v-for="item in market" :key="item" :label="item" :value="item" :disabled="includeHq(item)" />
  1007. </el-select>
  1008. </el-form-item>
  1009. <el-form-item prop="permission" label="角色名称:" required>
  1010. <el-select v-model="addAdmin.permission" placeholder="请选择角色名称" style="width: 220px" clearable>
  1011. <el-option v-for="item in permissionList" :key="item.value" :label="item.label"
  1012. :value="item.value"></el-option>
  1013. </el-select>
  1014. </el-form-item>
  1015. <el-form-item prop="postiton" label="职位:" required>
  1016. <el-input v-model="addAdmin.postiton" placeholder="请输入职位" style="width: 220px" clearable />
  1017. </el-form-item>
  1018. <el-form-item prop="machineIds" label="机器码:" required>
  1019. <div style="display: flex; align-items: center; flex-wrap: wrap; gap: 10px;">
  1020. <!-- 动态添加的机器码输入框 -->
  1021. <div v-for="(item, index) in addAdmin.machineIds" :key="index" style="margin-left: 10px;">
  1022. <el-input v-model="addAdmin.machineIds[index]" placeholder="请输入机器码"
  1023. style="width: 180px; margin-right: 10px;" />
  1024. </div>
  1025. <el-button type="primary" @click="addMachineIdInput">添加</el-button>
  1026. </div>
  1027. </el-form-item>
  1028. <el-form-item prop="remark" label="备注">
  1029. <el-input v-model="addAdmin.remark" style="width: 300px" :rows="2" maxlength="100" show-word-limit
  1030. type="textarea" />
  1031. </el-form-item>
  1032. </el-form>
  1033. <div>
  1034. <el-button @click="closeUserAddVisible()">取消</el-button>
  1035. <el-button type="primary" @click="throttledPermissionAdd()">
  1036. 提交
  1037. </el-button>
  1038. </div>
  1039. </template>
  1040. </el-dialog>
  1041. <!-- 这是编辑用户权限弹窗 -->
  1042. <el-dialog v-model="userEditVisible" title="编辑用户权限" width="800px" :close-on-click-modal="false">
  1043. <el-form ref="Ref" :model="permissionEditObj" label-width="auto" style="max-width: 600px; align-items: center">
  1044. <el-form-item prop="account" label="用户账号:" clearable>
  1045. <el-input v-model="permissionEditObj.account" placeholder="请输入OA号" style="width: 220px" disabled />
  1046. </el-form-item>
  1047. <el-form-item prop="name" label="用户名称:">
  1048. <el-input v-model="permissionEditObj.adminName" placeholder="请输入用户名" style="width: 220px" disabled />
  1049. </el-form-item>
  1050. <el-form-item prop="market" label="所属地区:" clearable>
  1051. <el-select multiple v-model="permissionEditObj.market" placeholder="请选择所属地区" style="width: 440px" clearable @change="EdithandleMarketChange">
  1052. <el-option v-for="item in market" :key="item" :label="item" :value="item" :disabled="EditincludeHq(item)" />
  1053. </el-select>
  1054. </el-form-item>
  1055. <el-form-item prop="postiton" label="职位:">
  1056. <el-input v-model="permissionEditObj.postiton" placeholder="请输入职位" style="width: 220px" clearable />
  1057. </el-form-item>
  1058. <el-form-item prop="roleName" label="角色名称:">
  1059. <el-select v-model="permissionEditObj.roleId" placeholder="请选择角色" style="width: 220px" @change="getUserLists">
  1060. <el-option v-for="item in permissionList" :key="item.value" :label="item.label"
  1061. :value="item.value"></el-option>
  1062. </el-select>
  1063. </el-form-item>
  1064. <el-form-item prop="parentName" label="上级角色:">
  1065. <el-select v-model="permissionEditObj.parentId" placeholder="无上级角色" :disabled="!!parentRoleTip"
  1066. style="width: 220px">
  1067. <el-option v-if="parentRoleTip" :key="0" :label="parentRoleTip" :value="null" disabled />
  1068. <el-option v-else v-for="item in permissionList" :key="item.value" :label="item.label" disabled
  1069. :value="item.value"></el-option>
  1070. </el-select>
  1071. </el-form-item>
  1072. <el-form-item prop="permissionSelect" label="权限列表:">
  1073. <el-tree :data="data" :disabled="true" show-checkbox node-key="id"
  1074. :props="{ label: 'menuName', children: 'children' }" :default-checked-keys="permissionEditObj.checkedKeys">
  1075. </el-tree>
  1076. </el-form-item>
  1077. <el-form-item prop="machineIds" label="机器码:">
  1078. <div style="display: flex; align-items: center; flex-wrap: wrap; gap: 10px;">
  1079. <!-- 动态添加的机器码输入框 -->
  1080. <div v-for="(item, index) in permissionEditObj.machineIds" :key="index" style="margin-left: 10px;">
  1081. <el-input v-model="permissionEditObj.machineIds[index]" placeholder=""
  1082. style="width: 180px; margin-right: 10px;" />
  1083. </div>
  1084. <el-button type="primary" @click="UseraddMachineIdInput">添加</el-button>
  1085. </div>
  1086. </el-form-item>
  1087. </el-form>
  1088. <div>
  1089. </div>
  1090. <template #footer>
  1091. <div>
  1092. <el-button @click="closeUserEditVisible()">取消</el-button>
  1093. <el-button type="primary" @click="throttledPermissionEdit">
  1094. 提交
  1095. </el-button>
  1096. </div>
  1097. </template>
  1098. </el-dialog>
  1099. <!-- 新增角色 -->
  1100. <el-dialog v-model="permissionAddVisible" title="新增角色" width="800px" :close-on-click-modal="false">
  1101. <template #footer>
  1102. <el-form ref="Ref" :rules="Rolerules" :model="addRole" label-width="auto"
  1103. style="max-width: 600px; align-items: center">
  1104. <el-form-item prop="roleName" label="角色名称:" required>
  1105. <el-input v-model="addRole.roleName" placeholder="请输入用户名" style="width: 220px" />
  1106. </el-form-item>
  1107. <el-form-item prop="market" label="所属地区:" required>
  1108. <el-select v-model="addRole.market" placeholder="请选择所属地区" style="width: 240px" clearable>
  1109. <el-option v-for="item in market" :key="item" :label="item" :value="item" />
  1110. </el-select>
  1111. </el-form-item>
  1112. <el-form-item prop="parentName" label="上级角色:">
  1113. <el-select v-model="addRole.parentId" placeholder="请选择上级角色" style="width: 220px" @change="getLists" clearable>
  1114. <el-option v-for="item in permissionList" :key="item.value" :label="item.label"
  1115. :value="item.value"></el-option>
  1116. </el-select>
  1117. </el-form-item>
  1118. <el-form-item prop="checkedKeys" label="权限列表:" required>
  1119. <el-tree v-if="data.length > 0" :data="data" show-checkbox node-key="id"
  1120. :props="{ label: 'menuName', children: 'children' }" :checked-keys="addRole.checkedKeys"
  1121. @check="handleCheckChange">
  1122. <template #default="{ node, data }">
  1123. <span>{{ node.label }}</span>
  1124. </template>
  1125. </el-tree>
  1126. <div v-else style="display: flex; align-items: center; gap: 8px;">
  1127. <span style="color: #999;">暂无数据</span>
  1128. </div>
  1129. </el-form-item>
  1130. <el-form-item prop="grade" label="优先级:" required>
  1131. <el-input v-model="addRole.grade" placeholder="数字1~999" style="width: 220px" />
  1132. </el-form-item>
  1133. </el-form>
  1134. <div>
  1135. <el-button @click="closePermissionAddVisible()">取消</el-button>
  1136. <el-button type="primary" @click="handleAddRole">
  1137. 提交
  1138. </el-button>
  1139. </div>
  1140. </template>
  1141. </el-dialog>
  1142. <!-- 重置密码确认弹窗 -->
  1143. <el-dialog
  1144. v-model="resetConfirmVisible" width="500px" :close-on-click-modal="false" :before-close="cancelResetPassword"
  1145. >
  1146. <el-row>
  1147. <el-col :span="4" style="margin-top: 20px">
  1148. <el-icon class="dialog-icon" color="#10AEFF" size="50">
  1149. <InfoFilled/>
  1150. </el-icon>
  1151. </el-col>
  1152. <el-col :span="20">
  1153. <h3>提示</h3>
  1154. <p class="dialog-title">确认重置该账号密码</p>
  1155. <p class="dialog-desc">重置后密码为: 123456请通知用户及时修改</p>
  1156. </el-col>
  1157. </el-row>
  1158. <template #footer>
  1159. <div style="align-content: center ; gap: 30px">
  1160. <el-button @click="cancelResetPassword">取消</el-button>
  1161. <el-button type="primary" @click="confirmResetPassword">确定</el-button>
  1162. </div>
  1163. </template>
  1164. </el-dialog>
  1165. </template>
  1166. <style scoped>
  1167. .pagination {
  1168. display: flex;
  1169. }
  1170. .status {
  1171. display: flex;
  1172. }
  1173. .head-card {
  1174. display: flex;
  1175. }
  1176. .head-card-element {
  1177. margin-right: 20px;
  1178. }
  1179. .head-card-btn {
  1180. margin-left: auto;
  1181. }
  1182. /* 新增样式让弹窗内容居中 */
  1183. .el-dialog__body {
  1184. display: flex;
  1185. flex-direction: column;
  1186. align-items: center;
  1187. }
  1188. .el-dialog__footer {
  1189. display: flex;
  1190. flex-direction: column;
  1191. align-items: center;
  1192. }
  1193. .permission-cell {
  1194. cursor: pointer;
  1195. color: #409eff;
  1196. /* 蓝色文字,提示可点击 */
  1197. }
  1198. </style>