app-func-form.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. <!--
  2. 应用功能独有表单
  3. @Author: linqian
  4. @Date: 2021-07-11 15:03
  5. -->
  6. <template>
  7. <div>
  8. <transfer-tree
  9. ref="transferTree"
  10. filterable
  11. :titles="['可选资源', '已选资源']"
  12. v-model="selectedValue"
  13. :data="data"
  14. children-name="child"
  15. :open-all="false"
  16. :transfer-open-node="true"
  17. :filter-node-from="handleSearch"
  18. value-name="id"
  19. >
  20. </transfer-tree>
  21. <div v-footer>
  22. <dg-button @click="handleCancel">取消</dg-button>
  23. <dg-button type="primary" @click="handleSubmit">确定</dg-button>
  24. </div>
  25. </div>
  26. </template>
  27. <script>
  28. import transferTree from '@/pages/common/transfer-tree';
  29. import { allAppFuncTree, userHasAuthFunIds } from '@/api/permission-selfhelp-manage';
  30. export default {
  31. props: {
  32. selectKeys: [Array],
  33. // 是否需要过滤父节点
  34. needFilter: {
  35. type: Boolean,
  36. default: false
  37. }
  38. },
  39. components: { transferTree },
  40. data() {
  41. return {
  42. approveContent: this.value,
  43. selectedValue: [],
  44. havefunIdsOnlyChild: [],
  45. havefunIds: [],
  46. data: []
  47. };
  48. },
  49. computed: {},
  50. methods: {
  51. findIndexArray(data, id, indexArray) {
  52. let arr = Array.from(indexArray);
  53. for (let i = 0, len = data.length; i < len; i++) {
  54. arr.push(data[i].label);
  55. if (data[i].id === id) {
  56. return arr;
  57. }
  58. let children = data[i].child;
  59. if (children && children.length) {
  60. let result = this.findIndexArray(children, id, arr);
  61. if (result) return result;
  62. }
  63. arr.pop();
  64. }
  65. return false;
  66. },
  67. // 树节点转成文字
  68. nodeTransferLabel(keys, tree) {
  69. const funcAttr = keys.map((item) => {
  70. return this.findIndexArray(tree, item, []);
  71. });
  72. let attr = [];
  73. for (let i = 0; i < funcAttr.length; i++) {
  74. const element = funcAttr[i].join('/');
  75. attr.push(element);
  76. }
  77. return attr.join('、');
  78. },
  79. handleCancel() {
  80. this.$emit('close');
  81. },
  82. handleSubmit() {
  83. // 申请访问的资源,剔除已经申请过的资源
  84. const applyKeys = this.selectedValue.filter((item) => !this.havefunIdsOnlyChild.includes(item));
  85. const approveContent = this.nodeTransferLabel(applyKeys, this.$refs.transferTree.targetData);
  86. // 撤销的资源, 已有资源与已选资源作比对
  87. const cancelKeys = this.havefunIdsOnlyChild.filter((item) => !this.selectedValue.includes(item));
  88. const cancelContent = this.nodeTransferLabel(cancelKeys, this.data);
  89. // const completeContent = `${approveContent}'\n'${cancelContent}`
  90. // 获取目标树所有的key,包含父节点
  91. const allKeys = this.$refs.transferTree.allKeyValue(false, this.$refs.transferTree.targetData);
  92. // 实际保存的节点,剔除应用节点
  93. const resourceInfos = allKeys
  94. .map((item) => this.$refs.transferTree.$refs['to-tree'].getNode(item).data)
  95. .map((item) => {
  96. return {
  97. appId: item.appId,
  98. funId: item.id
  99. };
  100. })
  101. .filter((item) => item.appId);
  102. // 需要验证重复申请的资源,剔除该用户已经拥有的资源
  103. const validRepeatNode = resourceInfos
  104. .filter((item) => !this.havefunIds.includes(item.funId))
  105. .map((item) => item.funId);
  106. // 已选资源有变更,则可以直接保存,无变更,则需要至少选中一条
  107. // 判断有无变更的标准:resourceInfos的funId 与getSetFunIdsByUser方法返回的已选资源id作匹配
  108. if (applyKeys.length == 0 && cancelKeys.length == 0) {
  109. this.$message.warning('请至少选择一条功能资源!');
  110. } else {
  111. this.$emit('success', approveContent, cancelContent, this.selectedValue, resourceInfos);
  112. }
  113. },
  114. handleSearch(value, data) {
  115. console.log(value, data.label);
  116. if (!value) return true;
  117. return data.label.indexOf(value) !== -1;
  118. },
  119. // 获取申请人已被授权得功能id
  120. getSetFunIdsByUser() {
  121. return new Promise((resolve) => {
  122. const params = {
  123. userId: this.$store.getters.user.id
  124. };
  125. userHasAuthFunIds(params)
  126. .then((res) => {
  127. resolve(res.data.content);
  128. })
  129. .catch(() => resolve([]));
  130. });
  131. },
  132. // 获取全量的菜单树
  133. getAllTree() {
  134. return new Promise((resolve) => {
  135. allAppFuncTree().then((res) => {
  136. resolve(res.data.content);
  137. });
  138. });
  139. },
  140. // 获取子节点,去除父节点key
  141. getChildKeys(data, val) {
  142. let keys = [];
  143. function filterParentKey(_data, key) {
  144. _data.filter((item) => {
  145. if (item.id == key && !item.isTreeNode) {
  146. keys.push(key);
  147. return;
  148. } else {
  149. if (item.child.length > 0) {
  150. filterParentKey(item.child, key);
  151. } else {
  152. return;
  153. }
  154. }
  155. });
  156. }
  157. for (let i = 0; i < val.length; i++) {
  158. const key = val[i];
  159. filterParentKey(data, key);
  160. }
  161. return keys;
  162. }
  163. },
  164. async created() {
  165. this.data = await this.getAllTree();
  166. if (this.type == 'edit') {
  167. // 已有资源,包含了父节点
  168. this.havefunIds = await this.getSetFunIdsByUser();
  169. // 已有资源,只是子节点
  170. this.havefunIdsOnlyChild = this.getChildKeys(this.data, this.havefunIds);
  171. }
  172. const keys = this.selectKeys;
  173. if (this.needFilter && this.havefunIds.length > 0) {
  174. this.selectedValue = [...this.getChildKeys(this.data, keys), ...this.havefunIdsOnlyChild];
  175. } else {
  176. this.selectedValue = keys;
  177. }
  178. },
  179. mounted() {}
  180. };
  181. </script>
  182. <style lang='scss' scoped>
  183. @import url('../index.scss');
  184. </style>