dk-function.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. <!-- @desc:功能权限 @auth:周兴 @time:2022/12/28 14:47 -->
  2. <template>
  3. <DkModal
  4. :loading="loading"
  5. width="1000px"
  6. v-model="visible"
  7. ref="modal_function"
  8. :title="title"
  9. @modalOk="modalOk"
  10. @modalCancel="modalCancel"
  11. @on-cancel="modalCancel"
  12. :saveFlag="true"
  13. >
  14. <DkTabs v-model="tabValue" :options="tabList" >
  15. <div style="height: 600px;overflow:auto" v-for="(item, index) of appList" :key="index" :slot="item.appCode">
  16. <div class="main-class">
  17. <el-collapse v-model="model" @change="handleChange(null)">
  18. <dk-el-collapse-item v-for="(it,index) in parentData.filter(f => f.appCode == item.appCode)" :key="index" :title="it[name]" :name="it.id"
  19. :ref="'collapseItem_' + it.id" :id="it.id" :checked="it.checked" v-if="tabValue==item.appCode"
  20. @on-change="handleChangeCheckbox" :disabled="disabled">
  21. <div v-for="(tIt,tIndex) in data.filter(item=>item.parentId == it.id)" :key="tIndex">
  22. <!--子级-->
  23. <MasterSlaveCheckbox v-if="tIt[funcFlag]" :item="tIt" :name="name" :checked="tIt.checked" :disabled="disabled"
  24. :child-data="data.filter(item=>item.parentId == tIt.id)"></MasterSlaveCheckbox>
  25. <!--父级-->
  26. <div v-else>
  27. <el-collapse v-model="model" @change="handleChange(tIt.id)">
  28. <dk-el-collapse-item :ref="'collapseItem_' + tIt.id" class="child-item-collapse"
  29. :title="'\u3000\u3000' + tIt[name]"
  30. :name="tIt.id" :id="tIt.id" :checked="tIt.checked"
  31. @on-change="handleChangeCheckbox" :disabled="disabled">
  32. <div v-for="(cIt,cIndex) in data.filter(item=>item.parentId == tIt.id)"
  33. :key="cIndex">
  34. <MasterSlaveCheckbox :item="cIt" :name="name" :disabled="disabled"
  35. :child-data="data.filter(item=>item.parentId == cIt.id)"></MasterSlaveCheckbox>
  36. </div>
  37. </dk-el-collapse-item>
  38. </el-collapse>
  39. </div>
  40. </div>
  41. </dk-el-collapse-item>
  42. </el-collapse>
  43. </div>
  44. </div>
  45. </DkTabs>
  46. <div class="choose-all-class">
  47. <Button type="primary" size="small" @click="selectAll" :disabled="disabled">{{ vm.$t('allChoose') }}</Button>
  48. <Button type="default" size="small" @click="unSelectAll" style="margin-left: 2px" :disabled="disabled">
  49. {{ vm.$t('allNoChoose') }}
  50. </Button>
  51. <Button type="default" size="small" @click="expandAll" style="margin-left: 2px">
  52. {{ vm.$t('expand') }}
  53. </Button>
  54. <Button type="default" size="small" @click="collapseAll" style="margin-left: 2px">
  55. {{ vm.$t('collapse') }}
  56. </Button>
  57. </div>
  58. </DkModal>
  59. </template>
  60. <script>
  61. import MasterSlaveCheckbox from './master-slave-checkbox'
  62. import DkElCollapseItem from './dk-el-collapse-item'
  63. import {button as buttonList} from "@/locale/lang/zh-CN";
  64. export default {
  65. name: 'dk-function',
  66. components: {MasterSlaveCheckbox, DkElCollapseItem},
  67. data() {
  68. const vm = window.vm;
  69. let self = this;
  70. return {
  71. self: self,
  72. documentKeyDownContent: Object,
  73. vm: vm,
  74. title: '',
  75. funcFlag: 'flgMenu',
  76. name: 'menuName',
  77. // funcFlag:'funcFlag',
  78. // name:'funcName',
  79. loading: false,
  80. visible: false,//显示控制,
  81. okFunc: () => {
  82. },//确定回调
  83. model: [],
  84. collapseFlag: true,
  85. parentData: [],
  86. webData: [],
  87. appData: [],
  88. data: [],
  89. collapseItems: [],
  90. collapseIds: [],
  91. disabled: false,
  92. tabValue: 'CP-WEB',
  93. tabOptions: null,
  94. appList: [],
  95. tabList: []
  96. }
  97. },
  98. watch: {
  99. visible(n, o) {
  100. if (!n) {
  101. //回复快捷键
  102. document.onkeydown = this.documentKeyDownContent;
  103. }
  104. },
  105. },
  106. methods: {
  107. /**
  108. * @desc : 全选
  109. * @author : 周兴
  110. * @date : 2022/12/29 12:51
  111. */
  112. selectAll() {
  113. this.data.filter(f => f.appCode == this.tabValue).updateAll('checked', true);
  114. this.$forceUpdate()
  115. },
  116. /**
  117. * @desc : 全不选
  118. * @author : 周兴
  119. * @date : 2022/12/29 12:51
  120. */
  121. unSelectAll() {
  122. this.data.filter(f => f.appCode == this.tabValue).updateAll('checked', false);
  123. this.$forceUpdate()
  124. },
  125. /**
  126. * @desc : 展开所有节点
  127. * @author : 周兴
  128. * @date : 2022/12/29 13:01
  129. */
  130. expandAll() {
  131. this.model = this.data.map(it => it.id)
  132. this.handleChange(null);
  133. },
  134. /**
  135. * @desc : 收缩所有节点
  136. * @author : 周兴
  137. * @date : 2022/12/29 13:01
  138. */
  139. collapseAll() {
  140. this.model = []
  141. this.handleChange(null);
  142. },
  143. /**
  144. * @desc : 获取节点的ref
  145. * @author : 周兴
  146. * @date : 2022/12/29 13:54
  147. */
  148. getCollapseItems() {
  149. let items = this.data.filter(it => !it[this.funcFlag]);
  150. if (items && items.length > 0) {
  151. items.forEach(it => {
  152. this.collapseItems.push('collapseItem_' + it.id)
  153. this.collapseIds.push(it.id)
  154. })
  155. }
  156. },
  157. /**
  158. * @desc : 点击保存
  159. * @author : 周兴
  160. * @date : 2022/12/29 11:38
  161. */
  162. modalOk() {
  163. let data = this.data.filter(it => it.checked);
  164. console.log('dds',data)
  165. this.okFunc(data,this)
  166. // this.visible = false;
  167. },
  168. /**
  169. * @desc : 关闭
  170. * @author : 周兴
  171. * @date : 2022/12/30 9:09
  172. */
  173. modalCancel() {
  174. this.unSelectAll();
  175. this.visible = false;
  176. },
  177. /**
  178. * @desc : 重新计算位置
  179. * @author : 周兴
  180. * @date : 2022/12/29 16:02
  181. */
  182. handleChange(id) {
  183. this.$nextTick(() => {
  184. if (this.collapseItems && this.collapseItems.length > 0) {
  185. let index = 0;
  186. if (id) {
  187. index = this.collapseItems.findIndex(item => item == 'collapseItem_' + id)
  188. }
  189. for (let i = index + 1; i < this.collapseItems.length; i++) {
  190. let it = this.collapseItems[i]
  191. if (this.$refs[it] && this.$refs[it].length > 0) {
  192. this.$refs[it][0].itemTop = null;
  193. setTimeout(() => {
  194. this.$refs[it][0].countCheckboxLocation();
  195. }, 400)
  196. }
  197. }
  198. }
  199. })
  200. },
  201. /**
  202. * @desc : 勾选节点上的选择框
  203. * @author : 周兴
  204. * @date : 2022/12/29 16:52
  205. */
  206. handleChangeCheckbox(checked, id) {
  207. let item = {id: id, checked: checked};
  208. let filterRows = this.data.filter(it => it.id === id);
  209. if (filterRows && filterRows.length > 0) {
  210. filterRows[0].checked = checked;
  211. }
  212. this.data.update(item, 'id', 'checked', 'parentId');
  213. this.$forceUpdate()
  214. },
  215. /**
  216. * @desc : 监听全局键盘按钮按下的事件
  217. * @author : 周兴
  218. * @date : 2022/3/4 16:57
  219. */
  220. addKeyBoardEvent() {
  221. let code = 0
  222. let self = this
  223. this.documentKeyDownContent = document.onkeydown;
  224. document.onkeydown = function (e) {
  225. const evn = e || event
  226. const key = evn.keyCode || evn.which || evn.charCode
  227. // alt:code = 18
  228. if (key === 18) {
  229. code = 18
  230. }
  231. // Q:code = 81 查询
  232. let btList = Object.values(self.$config.button);
  233. btList.forEach(forIt => {
  234. if (code === 18 && forIt.hotKey?.toLowerCase() === e.key.toLowerCase()) {
  235. e.returnValue = false
  236. if (self.$refs[forIt.name]) {
  237. self.$refs[forIt.name].$el.click()
  238. }
  239. }
  240. })
  241. }
  242. // 监听全局键盘按钮松开的事件
  243. document.onkeyup = function (e) {
  244. const evn = e || event
  245. const key = evn.keyCode || evn.which || evn.charCode
  246. if (key === 18) {
  247. code = 0
  248. }
  249. // 一秒钟失效,避免因为按了alt+tab之后再回来,按其他什么英文字母都不好使了的问题
  250. setTimeout(() => {
  251. code = 0
  252. }, 1000)
  253. }
  254. },
  255. /**
  256. * @desc : 获取应用
  257. * @author : 洪旭东
  258. * @date : 2023-06-30 15:02
  259. */
  260. getApplication() {
  261. this.excute(this.$service.commonService, this.$service.commonService.getApplication, {}).then(res => {
  262. if (res.code === this.$config.SUCCESS_CODE) {
  263. let data = res.data.filter(it=>it.appCode != 'DK-WEB')
  264. this.appList = data
  265. this.tabList = data.map(m => {return {
  266. label: m.appName,
  267. name: m.appCode
  268. }})
  269. }
  270. })
  271. },
  272. },
  273. mounted() {
  274. this.addKeyBoardEvent() // 增加快捷键
  275. // 先过滤顶级
  276. this.parentData = this.data?.filter(it => !it.parentId);
  277. this.webData = this.parentData.filter(f => f.appCode == 'CP-WEB')
  278. this.appData = this.parentData.filter(f => f.appCode == 'CP-WXP')
  279. if (this.collapseFlag) {
  280. this.model = this.data.map(it => it.id)
  281. } else {
  282. this.model = []
  283. }
  284. this.$nextTick(() => {
  285. this.getCollapseItems();
  286. })
  287. this.getApplication()
  288. }
  289. }
  290. </script>
  291. <style scoped>
  292. .main-class {
  293. overflow: hidden;
  294. border-top: 1px solid #b6b6b6;
  295. border-left: 1px solid #b6b6b6;
  296. border-right: 1px solid #b6b6b6;
  297. }
  298. .choose-all-class {
  299. /*position: absolute;*/
  300. /*bottom: 66px;*/
  301. /*left: 8px;*/
  302. padding-top: 5px;
  303. }
  304. .item-check-box {
  305. position: absolute;
  306. }
  307. .ivu-collapse-content {
  308. padding: 0 !important;
  309. }
  310. /deep/ .el-collapse {
  311. border-radius: 10px;
  312. }
  313. /deep/ .el-collapse-item__header {
  314. height: 40px;
  315. background: #f5f7fa;
  316. padding-left: 10px;
  317. /*border-right: 1px solid #b6b6b6;*/
  318. border-top:1px solid #b6b6b6;
  319. border-bottom: 1px solid #b6b6b6;
  320. }
  321. /deep/ .el-collapse-item__content {
  322. padding-bottom: 0;
  323. }
  324. /deep/ .el-collapse {
  325. border-radius: 0;
  326. border: none;
  327. }
  328. /deep/ .el-collapse-item__wrap {
  329. border-bottom: 0;
  330. }
  331. .child-item-collapse > /deep/ .el-collapse-item__wrap .el-collapse-item__content {
  332. border-bottom: 1px solid #b6b6b6;
  333. }
  334. </style>