1、优化产品结构树以及设备结构树、列表右键菜单重复右键后出现window菜单问题
2、优化产品结构树节点删除后的loading展示时机
3、优化产品以及设备结构树权限配置获取列表时的loading展示时机
| | |
| | | <a-tree blockNode show-icon :expandedKeys.sync="expandedKeys" |
| | | :selectedKeys="selectedKeys" :treeData="treeDataSource" :autoExpandParent="autoExpandParent" |
| | | @select="handleTreeSelect" @expand="handleTreeExpand" @rightClick="handleTreeRightClick"> |
| | | <template slot="title" slot-scope="{ title, parentId, entity, key:treeKey,equipmentId,type}"> |
| | | <DeviceStructureTreeContextMenu ref="contextMenuRef" |
| | | :treeParams="{title,treeKey,searchValue,equipmentId,entity,type,param:currentDeviceDocClassCode}"/> |
| | | <template slot="title" slot-scope="{ title }"> |
| | | <span v-if="title.indexOf(searchValue) > -1"> |
| | | {{ title.substr(0, title.indexOf(searchValue)) }} |
| | | <span class="replaceSearch">{{ searchValue }}</span> |
| | | {{ title.substr(title.indexOf(searchValue) + searchValue.length) }} |
| | | </span> |
| | | <span v-else>{{ title }}</span> |
| | | </template> |
| | | |
| | | <a-icon slot="switcherIcon" type="down"/> |
| | |
| | | |
| | | <!--权限配置弹窗--> |
| | | <AssignPermissionModal :currentTreeNodeInfo="rightClickSelected" @submitSuccess="getTreeDataByApi"/> |
| | | <!--产品结构树基本右键菜单(空白处触发)--> |
| | | |
| | | <!--设备结构树树节点右键菜单(树节点触发)--> |
| | | <device-structure-tree-context-menu ref="mainContextmenuRef" :treeParams="rightClickSelected"/> |
| | | |
| | | <!--设备结构树基本右键菜单(空白处触发)--> |
| | | <DeviceStructureBaseContextMenu ref="baseContextmenuRef"/> |
| | | </a-card> |
| | | </template> |
| | |
| | | const record = node.dataRef |
| | | // 若右键时当前右侧展示层级为设备层级且当前右键树层级同为设备层级时则在触发右键菜单功能时同时触发左键选中功能 |
| | | if (this.currentSelected.type === 2 && record.type === 2) this.handleTreeSelect([record.key], { node }) |
| | | this.rightClickSelected = Object.assign({}, record) |
| | | this.rightClickSelected = Object.assign({ param: this.currentDeviceDocClassCode }, record) |
| | | this.openMainContextMenu(event) |
| | | }, |
| | | |
| | | /** |
| | |
| | | */ |
| | | handleTreeExpand(expandedKeys) { |
| | | this.expandedKeys = this.beforeSearchExpandedKeys = expandedKeys |
| | | console.log('beforeSearchExpandedKeys', this.beforeSearchExpandedKeys) |
| | | this.autoExpandParent = false |
| | | }, |
| | | |
| | |
| | | }, |
| | | |
| | | /** |
| | | * 打开树节点菜单事件 |
| | | * @param event 树节点事件对象 |
| | | */ |
| | | openMainContextMenu(event) { |
| | | this.$refs.mainContextmenuRef.menuStyle.top = event.clientY + 'px' |
| | | this.$refs.mainContextmenuRef.menuStyle.left = event.clientX + 'px' |
| | | this.$refs.mainContextmenuRef.menuVisible = true |
| | | document.body.addEventListener('click', this.handleMainContextMenuClose) |
| | | }, |
| | | |
| | | /** |
| | | * 树所在父元素的右键事件 |
| | | * @param event 事件对象 |
| | | */ |
| | | openBaseContextMenu(event) { |
| | | event.preventDefault() |
| | | if (event.target.id !== 'tree-container') return |
| | | if (this.$refs.mainContextmenuRef) this.$refs.mainContextmenuRef.menuVisible = false |
| | | this.$refs.baseContextmenuRef.menuStyle.top = event.clientY + 'px' |
| | | this.$refs.baseContextmenuRef.menuStyle.left = event.clientX + 'px' |
| | | this.$refs.baseContextmenuRef.menuVisible = true |
| | |
| | | } else { |
| | | treeNode.slots = { icon: 'device' } |
| | | } |
| | | }, |
| | | |
| | | // 控制主要右键菜单关闭 |
| | | handleMainContextMenuClose() { |
| | | if (this.$refs.mainContextmenuRef) this.$refs.mainContextmenuRef.menuVisible = false |
| | | document.body.removeEventListener('click', this.handleMainContextMenuClose) |
| | | }, |
| | | |
| | | // 控制基础右键菜单关闭 |
| | |
| | | width: 8px; |
| | | } |
| | | |
| | | .replaceSearch { |
| | | color: #40a9ff; |
| | | font-weight: bold; |
| | | background-color: rgb(204, 204, 204); |
| | | } |
| | | |
| | | @media screen and (min-width: 1920px) { |
| | | .tree_con { |
| | | height: 748px !important; |
| | |
| | | <template> |
| | | <a-dropdown :trigger="['contextmenu']"> |
| | | <span v-if="treeParams.title.indexOf(treeParams.searchValue) > -1">{{ treeParams.title.substr(0, treeParams.title.indexOf(treeParams.searchValue)) }}<span |
| | | class="replaceSearch">{{ treeParams.searchValue }}</span>{{ treeParams.title.substr(treeParams.title.indexOf(treeParams.searchValue) + treeParams.searchValue.length) }}</span> |
| | | <span v-else>{{ treeParams.title }}</span> |
| | | <template #overlay> |
| | | <a-menu @click="({ key: menuKey }) => onContextMenuClick(treeParams.treeKey, menuKey)" |
| | | @contextmenu="event=>event.preventDefault()"> |
| | | <a-menu-item v-for="item in defaultContextMenuList[getCurrentMenuLevel]" :key="item.code" v-has="item.code"> |
| | | <a-icon :type="item.icon"/> |
| | | {{item.label}} |
| | | <a-menu :style="menuStyle" @click="menuItemClick" v-if="menuVisible" mode="vertical" @contextmenu="menuContextMenu"> |
| | | <template v-for="menuItem in defaultContextMenuList[getCurrentMenuLevel]"> |
| | | <a-menu-item :key="menuItem.code" v-has="menuItem.code"> |
| | | <a-icon :type="menuItem.icon"/> |
| | | {{ menuItem.label }} |
| | | </a-menu-item> |
| | | </a-menu> |
| | | </template> |
| | | </a-dropdown> |
| | | </a-menu> |
| | | </template> |
| | | |
| | | <script> |
| | |
| | | }, |
| | | data() { |
| | | return { |
| | | menuVisible: false, |
| | | menuStyle: { |
| | | position: 'fixed', |
| | | top: 0, |
| | | left: 0, |
| | | border: '1px solid #eee', |
| | | boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15)', |
| | | zIndex: 999 |
| | | }, |
| | | defaultContextMenuList: { |
| | | //车间 |
| | | workshop: [ |
| | |
| | | } |
| | | }, |
| | | methods: { |
| | | onContextMenuClick(treeKey, menuKey) { |
| | | menuItemClick({ key }) { |
| | | const menuKey = key |
| | | const level = this.getCurrentMenuLevel |
| | | const { param } = this.treeParams |
| | | const treeNodeInfo = Object.assign({}, this.treeParams, { param }) |
| | | console.log('treeNodeInfo++++++++++++++++++++++++++++', treeNodeInfo) |
| | | const treeNodeInfo = Object.assign({ treeKey: this.treeParams.key }, this.treeParams) |
| | | if (treeNodeInfo.type === 2) treeNodeInfo.type = 7 |
| | | // 设备结构树节点中的设备层级为2,但在产品结构树中将设备层级的type设置为7,因此在此处设置为7 |
| | | const menuKeyArray = menuKey.split('_') |
| | |
| | | } else { |
| | | methodName = 'handle' + menuKeyArray.map(item => item[0].toUpperCase() + item.slice(1)).join('') |
| | | } |
| | | console.log('methodName------------------------------------', methodName) |
| | | console.log('treeParams------------------------------------', this.treeParams) |
| | | const modalTitle = this.defaultContextMenuList[level].find(item => item.code === menuKey).label |
| | | |
| | | this.$bus.$emit('treeMenuItemMethodTrigger', { methodName, modalTitle, treeNodeInfo }) |
| | | }, |
| | | |
| | | /** |
| | | * 避免单次重复右键后关闭菜单或打开window菜单 |
| | | * @param event 事件对象 |
| | | */ |
| | | menuContextMenu(event) { |
| | | event.preventDefault() |
| | | event.stopPropagation() |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .replaceSearch { |
| | | color: #40a9ff; |
| | | font-weight: bold; |
| | | background-color: rgb(204, 204, 204); |
| | | } |
| | | |
| | | </style> |
| | |
| | | |
| | | // 调用接口获取所有用户列表 |
| | | getAllUsersListByApi() { |
| | | this.$nextTick(() => { |
| | | this.$refs.userPermissionTransferRef.spinning = true |
| | | this.allUsersList = [] |
| | | this.$refs.userPermissionTransferRef.targetKeys = [] |
| | | }) |
| | | dncApi.getAllUsersListApi() |
| | | .then(res => { |
| | | if (res.success) { |
| | |
| | | |
| | | // 调用接口获取所有车间列表 |
| | | getAllDepartmentsListByApi() { |
| | | this.allTreeKeys = [] |
| | | this.allTreeKeys = this.allDepartmentsList = [] |
| | | this.$nextTick(() => { |
| | | this.$refs.departPermissionTransferRef.targetKeys = this.$refs.departPermissionTransferRef.dataSource = [] |
| | | this.$refs.departPermissionTransferRef.spinning = true |
| | | }) |
| | | dncApi.getAllDepartmentsListApi() |
| | | .then(res => { |
| | | if (res.success) { |
| | |
| | | |
| | | // 调用接口获取所有用户列表 |
| | | getAllUsersListByApi() { |
| | | this.$nextTick(() => { |
| | | this.allUsersList = [] |
| | | this.$refs.userPermissionTransferRef.spinning = true |
| | | }) |
| | | dncApi.getAllUsersListApi() |
| | | .then(res => { |
| | | if (res.success) { |
| | |
| | | <script> |
| | | import dncApi from '@/api/dnc' |
| | | |
| | | const transferDataSource = [] |
| | | |
| | | export default { |
| | | name: 'DepartPermissionTransfer', |
| | | components: {}, |
| | |
| | | export default { |
| | | name: 'ProductStructureBaseContextMenu', |
| | | components: {}, |
| | | props: { |
| | | tableRowInfo: { |
| | | type: Object |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | menuVisible: false, |
| | |
| | | boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15)', |
| | | zIndex: 999 |
| | | }, |
| | | currentMenuLevel: '', |
| | | baseContextMenuList: [ |
| | | { label: '刷新', code: 'tree_reload', icon: 'reload', isHasPermission: false, isCommonMethod: false }, |
| | | { label: '添加产品', code: 'product_add', icon: 'plus', isHasPermission: true, isCommonMethod: false } |
| | |
| | | }, |
| | | methods: { |
| | | menuItemClick({ key }) { |
| | | console.log('menuKey', key) |
| | | const isCommonMethod = this.baseContextMenuList.find(item => item.code === key).isCommonMethod |
| | | const modalTitle = this.baseContextMenuList.find(item => item.code === key).label |
| | | const menuKeyArray = key.split('_') |
| | |
| | | :selectedKeys="selectedKeys" :treeData="treeDataSource" :autoExpandParent="autoExpandParent" |
| | | @select="handleTreeSelect" @expand="handleTreeExpand" @rightClick="handleTreeRightClick"> |
| | | <template slot="title" slot-scope="{ label, parentId, key:treeKey,type}"> |
| | | <ProductStructureTreeContextMenu ref="contextMenuRef" |
| | | :treeParams="{label,treeKey,searchValue,type}"/> |
| | | <span v-if="label.indexOf(searchValue) > -1"> |
| | | {{label.substr(0, label.indexOf(searchValue))}} |
| | | <span class="replaceSearch">{{searchValue}}</span> |
| | | {{label.substr(label.indexOf(searchValue) + searchValue.length)}} |
| | | </span> |
| | | <span v-else>{{ label }}</span> |
| | | </template> |
| | | |
| | | <a-icon slot="switcherIcon" type="down"/> |
| | |
| | | @submitSuccess="modalFormSubmitSuccess"/> |
| | | <!--引用部件--> |
| | | <NcComponentBorrowModal :currentBorrowInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess"/> |
| | | |
| | | <!--产品结构树右键菜单(树节点触发)--> |
| | | <product-structure-tree-context-menu ref="mainContextmenuRef" :treeParams="rightClickSelected"/> |
| | | |
| | | <!--产品结构树基本右键菜单(空白处触发)--> |
| | | <ProductStructureBaseContextMenu ref="baseContextmenuRef"/> |
| | | |
| | |
| | | |
| | | /** |
| | | * 树节点右键单击节点时触发 |
| | | * @param event 事件对象 |
| | | * @param node 节点对象 |
| | | */ |
| | | handleTreeRightClick({ node }) { |
| | | handleTreeRightClick({ event, node }) { |
| | | if (this.$refs.baseContextmenuRef) this.$refs.baseContextmenuRef.menuVisible = false |
| | | const that = this |
| | | const record = node.dataRef |
| | |
| | | message: '消息', |
| | | description: '暂无该节点详细信息' |
| | | }) |
| | | return |
| | | } |
| | | this.openMainContextMenu(event) |
| | | } else { |
| | | that.$notification.error({ |
| | | message: '消息', |
| | |
| | | okType: 'danger', |
| | | cancelText: '取消', |
| | | onOk: () => { |
| | | if (!url.delete) { |
| | | this.$message.error('请设置url.delete属性!') |
| | | return |
| | | } |
| | | that.loading = true |
| | | deleteAction(url.delete + `/${id}/${type}`) |
| | | .then((res) => { |
| | | if (res.success) { |
| | |
| | | }) |
| | | }, |
| | | |
| | | // 树节点右键单击菜单中删除按钮时触发 |
| | | // 发送nc程序至三维工艺 |
| | | handleSendNcToPlm() { |
| | | const that = this |
| | | const { rightClickSelected: { id, type }, $confirm, url, $notification } = that |
| | |
| | | }, |
| | | |
| | | /** |
| | | * 打开树节点菜单事件 |
| | | * @param event 树节点事件对象 |
| | | */ |
| | | openMainContextMenu(event) { |
| | | this.$refs.mainContextmenuRef.menuStyle.top = event.clientY + 'px' |
| | | this.$refs.mainContextmenuRef.menuStyle.left = event.clientX + 'px' |
| | | this.$refs.mainContextmenuRef.menuVisible = true |
| | | document.body.addEventListener('click', this.handleMainContextMenuClose) |
| | | }, |
| | | |
| | | /** |
| | | * 树所在父元素的右键事件 |
| | | * @param event 事件对象 |
| | | */ |
| | | openBaseContextMenu(event) { |
| | | event.preventDefault() |
| | | if (event.target.id !== 'tree-container') return |
| | | if (this.$refs.mainContextmenuRef) this.$refs.mainContextmenuRef.menuVisible = false |
| | | this.$refs.baseContextmenuRef.menuStyle.top = event.clientY + 'px' |
| | | this.$refs.baseContextmenuRef.menuStyle.left = event.clientX + 'px' |
| | | this.$refs.baseContextmenuRef.menuVisible = true |
| | |
| | | break |
| | | default: |
| | | } |
| | | }, |
| | | |
| | | // 控制主要右键菜单关闭 |
| | | handleMainContextMenuClose() { |
| | | if (this.$refs.mainContextmenuRef) this.$refs.mainContextmenuRef.menuVisible = false |
| | | document.body.removeEventListener('click', this.handleMainContextMenuClose) |
| | | }, |
| | | |
| | | // 控制基础右键菜单关闭 |
| | |
| | | align-items: center; |
| | | } |
| | | |
| | | .replaceSearch { |
| | | color: #40a9ff; |
| | | font-weight: bold; |
| | | background-color: rgb(204, 204, 204); |
| | | } |
| | | |
| | | @media screen and (min-width: 1920px) { |
| | | .tree_con { |
| | | height: 748px !important; |
| | |
| | | <template> |
| | | <a-dropdown :trigger="['contextmenu']"> |
| | | <span v-if="treeParams.label.indexOf(treeParams.searchValue) > -1">{{ |
| | | treeParams.label.substr(0, treeParams.label.indexOf(treeParams.searchValue)) |
| | | }}<span |
| | | class="replaceSearch">{{ |
| | | treeParams.searchValue |
| | | }}</span>{{ |
| | | treeParams.label.substr(treeParams.label.indexOf(treeParams.searchValue) + treeParams.searchValue.length) |
| | | }}</span> |
| | | <span v-else>{{ treeParams.label }}</span> |
| | | <template #overlay> |
| | | <a-menu @click="({ key: menuKey }) => onContextMenuClick(treeParams.treeKey, menuKey)" |
| | | @contextmenu="event=>event.preventDefault()"> |
| | | <a-menu-item v-for="item in defaultContextMenuList[getCurrentMenuLevel]" :key="item.code" v-has="item.code"> |
| | | <a-icon :type="item.icon"/> |
| | | {{ item.label }} |
| | | <a-menu :style="menuStyle" @click="menuItemClick" v-if="menuVisible" mode="vertical" @contextmenu="menuContextMenu"> |
| | | <template v-for="menuItem in defaultContextMenuList[getCurrentMenuLevel]"> |
| | | <a-menu-item :key="menuItem.code" v-has="menuItem.code"> |
| | | <a-icon :type="menuItem.icon"/> |
| | | {{ menuItem.label }} |
| | | </a-menu-item> |
| | | </a-menu> |
| | | </template> |
| | | </a-dropdown> |
| | | </a-menu> |
| | | </template> |
| | | |
| | | <script> |
| | |
| | | }, |
| | | data() { |
| | | return { |
| | | menuVisible: false, |
| | | menuStyle: { |
| | | position: 'fixed', |
| | | top: 0, |
| | | left: 0, |
| | | border: '1px solid #eee', |
| | | boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15)', |
| | | zIndex: 999 |
| | | }, |
| | | defaultContextMenuList: { |
| | | //产品 |
| | | product: [ |
| | |
| | | case 6: |
| | | return 'processStep' |
| | | } |
| | | }, |
| | | // getCurrentDocClassCode() { |
| | | // switch (+this.treeParams.type) { |
| | | // case 1: |
| | | // return 'OTHER' |
| | | // case 2: |
| | | // return 'OTHER' |
| | | // case 3: |
| | | // return 'OTHER' |
| | | // case 4: |
| | | // return 'OTHER' |
| | | // case 5: |
| | | // return 'NC' |
| | | // case 6: |
| | | // return 'NC' |
| | | // } |
| | | // } |
| | | } |
| | | }, |
| | | methods: { |
| | | onContextMenuClick(treeKey, menuKey) { |
| | | menuItemClick({ key }) { |
| | | const menuKey = key |
| | | const level = this.getCurrentMenuLevel |
| | | console.log('level---------------------', level) |
| | | const treeNodeInfo = Object.assign({}, this.treeParams) |
| | | console.log('treeNodeInfo******************', treeNodeInfo) |
| | | const treeNodeInfo = Object.assign({ treeKey: this.treeParams.key }, this.treeParams) |
| | | console.log('treeNodeInfo', treeNodeInfo) |
| | | const menuKeyArray = menuKey.split('_') |
| | | const isCommonMethod = this.defaultContextMenuList[level].find(item => item.code === menuKey).isCommonMethod |
| | | // product_add => handleAdd 触发对应组件事件 |
| | |
| | | } else { |
| | | methodName = 'handle' + menuKeyArray.map(item => item[0].toUpperCase() + item.slice(1)).join('') |
| | | } |
| | | console.log('methodName', methodName) |
| | | const modalTitle = this.defaultContextMenuList[level].find(item => item.code === menuKey).label |
| | | this.$bus.$emit('treeMenuItemMethodTrigger', { methodName, modalTitle, treeNodeInfo }) |
| | | }, |
| | | |
| | | /** |
| | | * 避免单次重复右键后关闭菜单或打开window菜单 |
| | | * @param event 事件对象 |
| | | */ |
| | | menuContextMenu(event) { |
| | | event.preventDefault() |
| | | event.stopPropagation() |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .replaceSearch { |
| | | color: #40a9ff; |
| | | font-weight: bold; |
| | | background-color: rgb(204, 204, 204); |
| | | /deep/ .ant-menu-item { |
| | | height: 32px; |
| | | line-height: 32px; |
| | | } |
| | | |
| | | </style> |
| | |
| | | <template> |
| | | <a-menu :style="menuStyle" @click="menuItemClick" v-if="menuVisible" mode="vertical"> |
| | | <a-menu :style="menuStyle" @click="menuItemClick" v-if="menuVisible" mode="vertical" @contextmenu="menuContextMenu"> |
| | | <template v-for="menuItem in defaultContextMenuList[tableRowInfo.param]"> |
| | | <a-menu-item :key="menuItem.code" v-has="menuItem.code" v-if="menuItem.subMenu.length===0"> |
| | | <a-icon :type="menuItem.icon"/> |
| | |
| | | modalTitle, |
| | | tableRowInfo: this.tableRowInfo |
| | | }) |
| | | }, |
| | | |
| | | /** |
| | | * 避免单次重复右键后关闭菜单或打开window菜单 |
| | | * @param event 事件对象 |
| | | */ |
| | | menuContextMenu(event) { |
| | | event.preventDefault() |
| | | event.stopPropagation() |
| | | } |
| | | } |
| | | } |