<template> <div class="commonfunctions-container"> <div class="title"> <span>常用功能</span> <div class="edit-icon"> <Icon type="ios-create-outline" @click="editModalVisible = true" /> </div> </div> <div class="carousel-wrapper"> <div class="carousel-container"> <div class="arrow arrow-left" v-if="pageNum > 1" @click="switchPage(curPage - 1)" > <Icon type="ios-arrow-back" /> </div> <div class="card-wrapper" ref="cardWrapper"> <CardItem v-for="(item, index) in curPageList" :key="index" :item="item" :style="{width: `${100 / rowIconNum}%`}" > </CardItem> </div> <div class="arrow arrow-right" v-if="pageNum > 1" @click="switchPage(curPage + 1)" > <Icon type="ios-arrow-forward" /> </div> </div> <div class="carousel-indicator" v-if="pageNum > 1"> <div v-for="page,index in Array.from(Array(pageNum))" :key="index" class="block" @click="switchPage(index)" :class="`${index == curPage ? 'block-active' : ''}`" ></div> </div> </div> <Modal v-model="editModalVisible" title="编辑常用功能" @on-ok="handleOk" @on-cancel="handleCancel" class-name="commonfunctions-modal" width="50%" > <Form :label-width="110"> <FormItem label="每行图标数目"> <Input v-model="rowIconNum" /> </FormItem> </Form> <div class="transfer"> <div class="tree-wrapper"> <el-tree :data="appTree" show-checkbox default-expand-all node-key="id" ref="tree" highlight-current :props="defaultProps" @check="handleCheckChange" > </el-tree> </div> <div class="selected-item-wrapper"> <div class="button-group-wrapper"> <Button size="small" :disabled="rightSideClickedNodeIndex == null || rightSideClickedNodeIndex == 0" @click="moveItem(-1)" > 上移 </Button> <Button size="small" :disabled="rightSideClickedNodeIndex == null || rightSideClickedNodeIndex == currentSelectedNodes.length - 1" @click="moveItem(1)" > 下移 </Button> <Button size="small" :disabled="rightSideClickedNodeIndex == null" @click="removeItem" > 移除 </Button> <Button size="small" :disabled="currentSelectedNodes.length == 0" @click="removeAll" > 全部移除 </Button> </div> <div class="item-list"> <div v-for="node,index in currentSelectedNodes" :key="node.id" > <div class="item" @click="rightSideClickedNodeIndex = index" :class="`${rightSideClickedNodeIndex == index ? 'selected-item' : ''}`" > {{node.title}} </div> </div> </div> </div> </div> </Modal> </div> </template> <script> import CardItem from '../components/CardItem.vue' import ResizeObserver from 'resize-observer-polyfill'; export default { props: { itemSetting: { type: Array, default: () => [] }, context: { type: Object, default: () => ({}) }, }, components: { CardItem, }, data() { return { resizeObserver: null, postTemplate: {}, reimburseList: [], rowIconNum: 4, appMap: new Map(), cardWrapperHeight: 118, editModalVisible: false, appTree: [], defaultProps: { children: 'children', label: 'title', }, currentSelectedNodes: [], rightSideClickedNodeIndex: null, curPage: 0, rowNum: 1, pageNum: 0, iconList: [ { value: '#icon-a-46_HOME_E_RBC_changyonggongneng_1', name: '常用功能1', }, { value: '#icon-a-46_HOME_E_RBC_changyonggongneng_2', name: '常用功能2', }, { value: '#icon-a-46_HOME_E_RBC_changyonggongneng_3', name: '常用功能3', }, { value: '#icon-a-46_HOME_E_RBC_changyonggongneng_4', name: '常用功能4', }, { value: '#icon-a-46_HOME_E_RBC_changyonggongneng_5', name: '常用功能5', }, { value: '#icon-a-46_HOME_E_RBC_changyonggongneng_6', name: '常用功能6', }, { value: '#icon-a-46_HOME_E_RBC_changyonggongneng_7', name: '常用功能7', }, { value: '#icon-a-46_HOME_E_RBC_changyonggongneng', name: '常用功能8', }, ], } }, computed: { curPageList() { const pageSize = this.rowIconNum * this.rowNum return this.reimburseList.slice(pageSize * this.curPage, pageSize * (this.curPage + 1)) }, }, watch: { }, created() { }, mounted() { window.GMS.util.nvwa.getRoutes().then((routes) => { this.appTree = [routes.data] this.addApp(routes.data.children) this.getData() }) this.resizeObserver = new ResizeObserver(entries => { for (const entry of entries) { switch(entry.target){ case this.$refs.cardWrapper: this.cardWrapperHeight = this.$refs.cardWrapper.clientHeight || this.$refs.cardWrapper.offsetHeight this.rowNum = Math.floor(this.cardWrapperHeight / 118) if (this.rowNum == 0) this.rowNum = 1 break; } } }); this.resizeObserver.observe(this.$refs.cardWrapper) }, unmounted() { this.resizeObserver.disconnect() }, methods: { getData() { return window.GMS.$http.get('/rbc/workflow/commonFunction/getConfig').then((res) => { const obj = res && res.data && res.data.config || {} this.postTemplate = obj this.rowIconNum = obj.columnNum || 4 const idList = obj.configInfo || [] this.reimburseList = [] this.currentSelectedNodes = [] let i = 0 for (let id of idList) { if (this.appMap.has(id)) { this.currentSelectedNodes.push(this.appMap.get(id)) if (i >= this.iconList.length) i = 0 this.reimburseList.push({ function: this.appMap.get(id), icon: this.iconList[i++].value }) } } this.pageNum = Math.ceil(this.reimburseList.length / this.rowIconNum / this.rowNum) this.$refs.tree.setCheckedKeys(this.currentSelectedNodes.map((o) => o.id)) }) }, updateData() { return window.GMS.$http.post( '/rbc/workflow/commonFunction/update', { ...this.postTemplate, columnNum: this.rowIconNum, configInfo: this.currentSelectedNodes.map((o) => o.id), } ) }, switchPage(index) { if (index < 0) index = 0 if (index > this.pageNum - 1) index = this.pageNum - 1 this.curPage = index }, removeAll() { this.$refs.tree.setCheckedKeys([]) this.currentSelectedNodes = [] this.rightSideClickedNodeIndex = null }, removeItem() { this.$refs.tree.setChecked(this.currentSelectedNodes[this.rightSideClickedNodeIndex].id, false) this.currentSelectedNodes.splice(this.rightSideClickedNodeIndex, 1) this.rightSideClickedNodeIndex = null }, moveItem(distance) { const curItem = this.currentSelectedNodes[this.rightSideClickedNodeIndex] this.currentSelectedNodes[this.rightSideClickedNodeIndex] = this.currentSelectedNodes[this.rightSideClickedNodeIndex + distance] this.currentSelectedNodes[this.rightSideClickedNodeIndex + distance] = curItem this.currentSelectedNodes = [...this.currentSelectedNodes] this.rightSideClickedNodeIndex += distance }, handleCheckChange() { const nodeList = this.$refs.tree.getCheckedNodes(true) for (let i = 0; i < this.currentSelectedNodes.length; ++i) { if (!nodeList.some((o) => o.id == this.currentSelectedNodes[i].id)) { this.currentSelectedNodes.splice(i, 1) ;--i } } for (let i = 0; i < nodeList.length; ++i) { if (!this.currentSelectedNodes.some((o) => o.id == nodeList[i].id)) { this.currentSelectedNodes.push(nodeList[i]) } } }, handleOk() { this.updateData().then(this.getData) }, handleCancel() { this.getData() }, addApp(l = []) { for (let o of l) { if (o.type == 'ROUTE') { this.appMap.set(o.id, o) } else if (o.type == 'GROUP') { this.addApp(o.children) } } }, } } </script> <style lang="less" scoped> .commonfunctions-container { font-family: PingFangSC-Medium, PingFang SC; height: 100%; padding: 16px; border-radius: 6px; border: 1px solid #E5E5E5; overflow: hidden; background-color: white; .title { text-align: left; padding-left: 11px; height: 22px; font-size: 16px; font-weight: 500; color: #0F0F0F; position: relative; line-height: 22px; &::before { content: ''; position: absolute; left: 0; top: ~"calc(50% - 7px)"; width: 3px; height: 14px; background: #5369D8; border-radius: 2px; } .edit-icon { cursor: pointer; font-size: 22px; position: absolute; right: 0; top: 0; } } .carousel-wrapper { height: ~"calc(100% - 22px)"; .carousel-container { width: 100%; height: ~"calc(100% - 15px)"; display: flex; .arrow { color: #909090; width: 25px; font-size: 25px; cursor: pointer; display: flex; flex-direction: column; justify-content: center; } .card-wrapper { flex: 1; display: flex; flex-wrap: wrap; } } .carousel-indicator { height: 15px; display: flex; align-items: center; justify-content: center; .block { width: 35px; height: 8px; margin: 0 5px; position: relative; cursor: pointer; &::before { position: absolute; left: 0; top: ~"calc(50% - 1px)"; width: 35px; height: 2px; background-color: #A0A0A0; border-radius: 1px; content: ''; } } .block-active { &::before { top: ~"calc(50% - 2px)"; height: 4px; border-radius: 2px; background-color: green; } } } } } .commonfunctions-modal { .transfer { display: flex; height: 45vh; .tree-wrapper { width: 50%; height: 100%; overflow: scroll; } .selected-item-wrapper { width: 50%; height: 100%; display: flex; flex-direction: column; .button-group-wrapper { padding-left: 5px; } .item-list { flex: 1; overflow: scroll; padding: 2px 5px; .item { margin: 2px 0; cursor: pointer; } .selected-item { background-color: #00579130; } } } } } </style>