permissionList.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. <template>
  2. <div v-loading="loading" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0.8)" class="permissionList">
  3. <div class="permissionList_tree">
  4. <div class="permissionList_tree_head flex">
  5. <div class="permissionList_tree_head_list">名称</div>
  6. <div class="permissionList_tree_head_list">类型</div>
  7. <div class="permissionList_tree_head_list">行权限</div>
  8. <div class="permissionList_tree_head_list">操作</div>
  9. </div>
  10. <div class="permissionList_tree_body">
  11. <el-scrollbar style="height: 100%" :horizontal="false">
  12. <el-tree ref="tree" :data="data" show-checkbox node-key="pageconfigurationid" default-expand-all :expand-on-click-node="false" @check="checkChange">
  13. <template slot-scope="{node,data}">
  14. <div class="custom-tree-node flex">
  15. <div class="custom-tree-node-list">{{data.pagename}}</div>
  16. <div class="custom-tree-node-list">{{data.pagetype}}</div>
  17. <div class="custom-tree-node-list">
  18. <el-tooltip class="item" effect="dark" :content="data.selectcolumnlist" placement="top">
  19. <div class="tmsg">{{ data.selectcolumnlist }}</div>
  20. </el-tooltip>
  21. </div>
  22. <div class="custom-tree-node-list">
  23. <template v-if="data.pagetype == 'table'">
  24. <el-button size="mini" type="text" @click="details(node, data)">行权限</el-button>
  25. </template>
  26. </div>
  27. </div>
  28. </template>
  29. </el-tree>
  30. </el-scrollbar>
  31. </div>
  32. </div>
  33. <div class="permissionList_dialog">
  34. <!--高级查询-->
  35. <PublicPageDialog dialog-title="行权限" dialogSize="600px" :dialog-drawer="advancedDrawer" @handleClose="advancedDrawer = false" @handleSubmit="advancedTable('advancedDialogForm')">
  36. <AdvancedQuery ref="advancedDialogForm" :select-options="selectOptions" :ad-list="false" :ad-dep="adDep" @getAdvancedQueryData="getAdvancedQueryData" />
  37. </PublicPageDialog>
  38. </div>
  39. </div>
  40. </template>
  41. <script>
  42. import PublicPageDialog from '@/components/PublicPageDialog'
  43. import AdvancedQuery from '@/components/AdvancedQuery'
  44. import { mapGetters } from 'vuex'
  45. import { listToTree } from '@/utils/validate'
  46. import { Query, newData, modifyData, moveData, getAuthorization, authorization } from "@/api/webApi"
  47. import { formatChange } from '@/utils/validate'
  48. export default {
  49. name: 'Permissionlist',
  50. props: {
  51. listMap: {
  52. type: Object,
  53. default: () => new Object()
  54. },
  55. treeMap: {
  56. type: Object,
  57. default: () => new Object()
  58. }
  59. },
  60. components: { PublicPageDialog, AdvancedQuery },
  61. data () {
  62. return {
  63. advancedDrawer: false,
  64. loading: false,
  65. ischeck: false,
  66. data: [],
  67. defaultProps: {
  68. children: 'children',
  69. label: 'pagename'
  70. },
  71. defaultKeys: [],
  72. nodeKey: 'pageconfigurationid',
  73. adDep: 1,
  74. dataKey: 'pagename',
  75. checkDatas: [],
  76. queryItem: {},
  77. tableKey: '',
  78. rowData: {},
  79. selectOptions: [],
  80. queryId: 6,
  81. allAuthData: [],
  82. }
  83. },
  84. watch: {
  85. listMap: {
  86. handler (row) {
  87. if (Object.keys(row).length) {
  88. const queryItem = _.cloneDeep(row)
  89. if (queryItem.children) delete queryItem.children
  90. this.queryItem = queryItem
  91. this.restDataRow(queryItem)
  92. }
  93. },
  94. deep: true,
  95. immediate: true
  96. },
  97. treeMap: {
  98. handler (obj) {
  99. if (Object.keys(obj).length) {
  100. const { serviceid, pagename } = obj
  101. this.queryAllAuthData(serviceid, pagename)
  102. }
  103. },
  104. deep: true,
  105. immediate: true
  106. }
  107. },
  108. computed: {
  109. ...mapGetters(['authArrs'])
  110. },
  111. methods: {
  112. async queryAllAuthData (serviceid, pagename) {
  113. this.loading = true;
  114. const datacontent = { filter: { 1: 1 } }
  115. try {
  116. const { code, returnData } = await Query({
  117. serviceid,
  118. datacontent,
  119. event: '0',
  120. page: 1,
  121. size: 9999,
  122. });
  123. if (code == 0 && returnData?.length) {
  124. this.allAuthData = _.cloneDeep(returnData)
  125. this.setAuthData([], returnData)
  126. } else {
  127. this.$message.error(`获取${pagename}数据失败`);
  128. }
  129. } catch (error) {
  130. this.$message.error(`获取${pagename}数据失败`);
  131. }
  132. this.loading = false;
  133. },
  134. disableTreeData (arr = []) {
  135. if (!arr.length) return
  136. const alldata = _.cloneDeep(arr)
  137. const isdata = _.cloneDeep(this.authArrs)
  138. const nodata = this.findRepetData(alldata, isdata)
  139. if (nodata?.length) {
  140. alldata.map(item => {
  141. nodata.map(ci => {
  142. if (item.pageconfigurationid == ci.pageconfigurationid) {
  143. item.disabled = true
  144. }
  145. })
  146. })
  147. }
  148. return alldata
  149. },
  150. restDataRow (queryItem = this.queryItem) {
  151. this.ischeck = true
  152. this.checkDatas = []
  153. this.$refs.tree.setCheckedKeys([])
  154. this.queryTreeData(queryItem, '权限')
  155. },
  156. //高级查询-提交
  157. advancedTable (refName) {
  158. this.$refs[refName].advancedQueryHandler()
  159. },
  160. getAdvancedQueryData (dataRules) {
  161. const ndata = this.checkDatas?.at(-1)
  162. const nitem = ndata.filter(item => item.pageconfigurationid == this.rowData.pageconfigurationid)
  163. const { id, supergroupid, type } = this.queryItem
  164. const { pageconfigurationid, serviceid, selectcolumnlist = '', insetcolumnlist = '', updatecolumnlist = '', filterset = '' } = nitem[0]
  165. const rowData = {
  166. pageconfigurationid,
  167. serviceid,
  168. selectcolumnlist,
  169. insetcolumnlist,
  170. updatecolumnlist,
  171. filterset
  172. }
  173. rowData.selectcolumnlist = JSON.stringify(dataRules)
  174. if (type == 1) {
  175. rowData.userid = id
  176. this.queryId = 7
  177. } else {
  178. rowData.usergroupid = id
  179. this.queryId = 6
  180. }
  181. this.sendCheckData('edit', [rowData])
  182. this.advancedDrawer = false
  183. },
  184. formatRowAuth (nstr, arr) {
  185. if (!nstr || !arr) return []
  186. const nitem = JSON.parse(nstr)
  187. const tableValues = [...arr]
  188. if (nitem?.length && tableValues?.length) {
  189. const htmls = []
  190. const ndatas = [...nitem]
  191. tableValues.map(({ pagename, pagecode }) => {
  192. ndatas.map(({ column, comparator, connector, value }) => {
  193. if (pagecode == column) {
  194. const comparatorfh = comparator == '=' ? '等于' : '不等于'
  195. const connectorfh = connector == 'and' ? '并且' : connector == 'or' ? '或者' : ''
  196. const str = pagename + comparatorfh + value + connectorfh
  197. htmls.push(str)
  198. }
  199. })
  200. })
  201. return htmls
  202. }
  203. },
  204. //打开行权限
  205. details (node, data) {
  206. if (!this.ischeck) {
  207. this.$message.error('请先选中左边的权限树后再操作')
  208. this.$refs.tree.setCheckedKeys([])
  209. return
  210. }
  211. if (!this.checkDatas.length) {
  212. this.$message.error('请先勾选权限后再操作')
  213. return
  214. }
  215. const ndata = _.cloneDeep(data)
  216. const { pageconfigurationid } = ndata
  217. const nitem = this.checkDatas?.at(-1).filter(item => item.pageconfigurationid == pageconfigurationid)
  218. if (!nitem.length) {
  219. this.$message.error('请先勾选权限后再操作')
  220. return
  221. }
  222. this.adDep = Math.random()
  223. this.rowData = ndata
  224. sessionStorage.setItem('tableColumns', JSON.stringify({ tableKey: pageconfigurationid, tableValues: ndata.children }))
  225. this.$store.dispatch('auth/changeAuthMsg', ndata.children)
  226. if (data.selectcolumnmsg) {
  227. this.selectOptions = JSON.parse(data.selectcolumnmsg)
  228. }
  229. this.advancedDrawer = true
  230. },
  231. //初始化数据
  232. setAuthData (arrs = [], returnData = []) {
  233. const narrs = _.cloneDeep(arrs)
  234. const ndata = _.cloneDeep(returnData)
  235. if (narrs.length) {
  236. ndata.map(item => {
  237. narrs.map(ci => {
  238. if (item.pageconfigurationid == ci.pageconfigurationid && ci.selectcolumnlist) {
  239. const tableColumnArrs = ndata.filter(item => item['superiorid'] == ci.pageconfigurationid && item['pagetype'] == 'column')
  240. const htmls = this.formatRowAuth(ci.selectcolumnlist, tableColumnArrs)
  241. item.selectcolumnmsg = ci.selectcolumnlist
  242. item.selectcolumnlist = htmls.join('')
  243. }
  244. })
  245. })
  246. }
  247. const alldata = this.disableTreeData(ndata)
  248. const treeMenu = listToTree([...alldata], 'superiorid', 'pageconfigurationid')
  249. this.data = treeMenu
  250. },
  251. //勾选已有权限
  252. checkAuthData (ndata) {
  253. const returnData = _.cloneDeep(ndata)
  254. if (ndata?.length) {
  255. const ids = []
  256. ndata.map(({ pageconfigurationid }) => {
  257. ids.push(pageconfigurationid)
  258. })
  259. this.$refs.tree.setCheckedKeys(ids)
  260. const treeDatas = this.$refs.tree.getCheckedNodes().concat(this.$refs.tree.getHalfCheckedNodes())
  261. const res = this.findRepetData(treeDatas, returnData)
  262. if (res?.length) {
  263. res.map((item) => {
  264. if (item.pageconfigurationid) {
  265. this.$refs.tree.setChecked(item.pageconfigurationid, false, false);
  266. }
  267. })
  268. }
  269. this.checkDatas.push(ndata)
  270. }
  271. },
  272. //获取当前用户组/用户已有权限
  273. async queryTreeData (dataContent, pagename) {
  274. this.loading = true;
  275. try {
  276. const { code, returnData } = await getAuthorization({ datacontent: dataContent });
  277. if (code == 0) {
  278. const ndata = _.cloneDeep(returnData)
  279. this.setAuthData(ndata, this.allAuthData)
  280. this.$nextTick(() => {
  281. this.checkAuthData(ndata)
  282. })
  283. } else {
  284. this.$message.error(`获取${pagename}数据失败`);
  285. }
  286. } catch (error) {
  287. this.$message.error(`获取${pagename}数据失败`);
  288. }
  289. this.loading = false;
  290. },
  291. checkChange () {
  292. if (!this.ischeck) {
  293. this.$message.error('请先选中左边的权限树后再操作')
  294. this.$refs.tree.setCheckedKeys([])
  295. return
  296. }
  297. const checks = this.$refs.tree.getCheckedNodes() //选中
  298. const halfchecks = this.$refs.tree.getHalfCheckedNodes() //半选中
  299. const allchecks = [...checks, ...halfchecks]
  300. this.checkDatas.push(allchecks)
  301. this.isAddorDel()
  302. },
  303. isAddorDel () {
  304. const ndatas = _.cloneDeep(this.checkDatas)
  305. if (ndatas.length == 1) {
  306. this.sendCheckData('add', ndatas[0])
  307. } else {
  308. const [nitems1, nitems2] = [ndatas.at(-1), ndatas.at(-2)]
  309. if (nitems1.length > nitems2.length) {
  310. const res = this.findRepetData(nitems1, nitems2)
  311. this.sendCheckData('add', res)
  312. } else {
  313. const res = this.findRepetData(nitems1, nitems2)
  314. this.sendCheckData('del', res)
  315. }
  316. }
  317. },
  318. findRepetData (nitems1, nitems2) {
  319. const key = 'pageconfigurationid'
  320. const res = [...nitems1, ...nitems2].filter(
  321. (item) =>
  322. !(
  323. nitems1.some((p) => item[key] == p[key]) &&
  324. nitems2.some((c) => item[key] == c[key])
  325. )
  326. )
  327. return res
  328. },
  329. //发送新增编辑删除数据
  330. sendCheckData (types, data) {
  331. const event = types == 'add' ? 1 : types == 'edit' ? 2 : 3
  332. const querys = []
  333. const items = _.cloneDeep(data)
  334. const { id, type } = this.queryItem
  335. if (types == 'edit') {
  336. items.map(item => {
  337. if (item.children) delete item.children
  338. })
  339. const params = {
  340. serviceid: this.queryId,
  341. datacontent: [
  342. {
  343. filter: {
  344. pageconfigurationid: items[0].pageconfigurationid
  345. },
  346. value: items[0]
  347. }
  348. ],
  349. event,
  350. }
  351. type == 1 ? params.datacontent[0].filter.userid = items[0].userid : params.datacontent[0].filter.usergroupid = items[0].usergroupid
  352. querys.push(modifyData(params))
  353. } else {
  354. const ids = []
  355. items.map(item => {
  356. if (item.children) delete item.children
  357. ids.push(item.pageconfigurationid)
  358. })
  359. const params = {
  360. id,
  361. type,
  362. datacontent: ids,
  363. event
  364. }
  365. querys.push(authorization(params))
  366. }
  367. this.getAnscyData(querys, types)
  368. },
  369. //获取异步数据
  370. async getAnscyData (allResult, types) {
  371. if (!allResult.length) return
  372. this.loading = true
  373. const results = await Promise.allSettled(allResult)
  374. results.map((item) => {
  375. const { status, value } = item
  376. if (status == 'fulfilled') {
  377. const { code } = value
  378. if (code == 0) {
  379. if (types == 'edit') this.restDataRow()
  380. this.$message.success('操作成功')
  381. } else {
  382. this.$message.error('操作失败')
  383. }
  384. } else {
  385. this.$message.error('网络错误')
  386. }
  387. })
  388. this.loading = false
  389. }
  390. }
  391. }
  392. </script>
  393. <style lang="scss" scoped>
  394. .permissionList {
  395. height: 100%;
  396. &_tree {
  397. height: 100%;
  398. &_head {
  399. height: 42px;
  400. line-height: 42px;
  401. background-color: #f0f6ff;
  402. font-size: 16px;
  403. font-size: 600;
  404. &_list {
  405. padding: 0 20px;
  406. width: 25%;
  407. }
  408. }
  409. ::v-deep &_body {
  410. height: calc(100% - 52px);
  411. .el-scrollbar__wrap {
  412. overflow-x: hidden;
  413. }
  414. .is-horizontal {
  415. display: none;
  416. }
  417. .el-tree-node {
  418. &__content {
  419. height: 49px;
  420. border-top: 1px solid #d6d4d4;
  421. }
  422. }
  423. .custom-tree-node {
  424. width: 100%;
  425. line-height: 28px;
  426. &-list {
  427. padding-right: 20px;
  428. width: 25%;
  429. &:last-child {
  430. padding-right: 0;
  431. }
  432. }
  433. .tmsg {
  434. white-space: nowrap;
  435. text-overflow: ellipsis;
  436. overflow: hidden;
  437. }
  438. }
  439. }
  440. }
  441. }
  442. </style>