| | |
| | | }; |
| | | |
| | | // 判断指定标签页是否可以关闭左侧标签 |
| | | // const canCloseLeftForTab = (tabPath) => { |
| | | // const tabIndex = tabs.findIndex(tab => tab.path === tabPath); |
| | | // if (tabIndex <= 0) { |
| | | // return false; // 没有左侧标签或这是第一个标签 |
| | | // } |
| | | // // 检查左侧是否有可关闭的标签(排除dashboard) |
| | | // return tabs.slice(0, tabIndex).some(tab => tab.closable); |
| | | // }; |
| | | const canCloseLeftForTab = (tabPath) => { |
| | | const tabIndex = tabs.findIndex(tab => tab.path === tabPath || isSameResource(tab.path, tabPath)); |
| | | if (tabIndex <= 0) { |
| | | return false; // 没有左侧标签或这是第一个标签 |
| | | } |
| | | // 检查左侧是否有可关闭的标签(排除dashboard) |
| | | return tabs.slice(0, tabIndex).some(tab => tab.closable); |
| | | }; |
| | | |
| | | // 判断指定标签页是否可以关闭右侧标签 |
| | | // const canCloseRightForTab = (tabPath) => { |
| | | // const tabIndex = tabs.findIndex(tab => tab.path === tabPath); |
| | | // if (tabIndex < 0 || tabIndex >= tabs.length - 1) { |
| | | // return false; // 没有右侧标签或这是最后一个标签 |
| | | // } |
| | | // // 检查右侧是否有可关闭的标签 |
| | | // return tabs.slice(tabIndex + 1).some(tab => tab.closable); |
| | | // }; |
| | | const canCloseRightForTab = (tabPath) => { |
| | | const tabIndex = tabs.findIndex(tab => tab.path === tabPath || isSameResource(tab.path, tabPath)); |
| | | if (tabIndex < 0 || tabIndex >= tabs.length - 1) { |
| | | return false; // 没有右侧标签或这是最后一个标签 |
| | | } |
| | | // 检查右侧是否有可关闭的标签 |
| | | return tabs.slice(tabIndex + 1).some(tab => tab.closable); |
| | | }; |
| | | |
| | | return ( |
| | | <Box |
| | |
| | | display: 'inline-flex', |
| | | alignItems: 'center', |
| | | justifyContent: 'center', |
| | | p: 0.25, |
| | | p: 0.35, |
| | | ml: 0.5, |
| | | borderRadius: '50%', |
| | | cursor: 'pointer', |
| | | color: 'inherit', |
| | | '&:hover': { |
| | | backgroundColor: 'rgba(0, 0, 0, 0.1)', |
| | | color: '#d32f2f', |
| | | }, |
| | | }} |
| | | > |
| | | <CloseIcon sx={{ fontSize: 14 }} /> |
| | | <CloseIcon sx={{ fontSize: 16 }} /> |
| | | </Box> |
| | | </Tooltip> |
| | | )} |
| | |
| | | sx: { py: 0 }, |
| | | }} |
| | | > |
| | | {/* 关闭当前标签 |
| | | {contextMenuTab && contextMenuTab.closable && ( |
| | | <MenuItem |
| | | onClick={handleCloseCurrentTab} |
| | |
| | | {t('ra.action.close', '关闭当前标签')} |
| | | </MenuItem> |
| | | )} |
| | | */} |
| | | {contextMenuTab && canCloseLeftForTab(contextMenuTab.path) && ( |
| | | <MenuItem onClick={handleCloseLeftTabs}> |
| | | <MenuItem |
| | | onClick={handleCloseLeftTabs} |
| | | sx={{ |
| | | fontSize: '0.8125rem', |
| | | py: 0.75, |
| | | px: 1.5, |
| | | minHeight: 'auto', |
| | | }} |
| | | > |
| | | {t('ra.action.closeLeft', '关闭左侧标签')} |
| | | </MenuItem> |
| | | )} |
| | | {contextMenuTab && canCloseRightForTab(contextMenuTab.path) && ( |
| | | <MenuItem onClick={handleCloseRightTabs}> |
| | | <MenuItem |
| | | onClick={handleCloseRightTabs} |
| | | sx={{ |
| | | fontSize: '0.8125rem', |
| | | py: 0.75, |
| | | px: 1.5, |
| | | minHeight: 'auto', |
| | | }} |
| | | > |
| | | {t('ra.action.closeRight', '关闭右侧标签')} |
| | | </MenuItem> |
| | | )} |
| | |
| | | top: 48, |
| | | left: sidebarWidth + 5, |
| | | right: 0, |
| | | zIndex: 1100, |
| | | zIndex: 1350, // 高于 Dialog(1300),避免菜单内弹窗遮盖标签页 |
| | | transition: (theme) => |
| | | theme.transitions.create('left', { |
| | | easing: theme.transitions.easing.sharp, |
| | |
| | | } |
| | | if (task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_IN.type)) { |
| | | locWorking.setAnfme(taskItem.getAnfme()); |
| | | } else if (task.getTaskType().equals(TaskType.TASK_TYPE_PICK_IN.type) && taskItem.getQty() != null && taskItem.getQty().compareTo(0.0) > 0) { |
| | | // 拣料再入库:入库数量为本次拣料数量(taskItem.qty),保证与出库扣减一致 |
| | | locWorking.setAnfme(taskItem.getQty()); |
| | | } |
| | | BeanUtils.copyProperties(locWorking, locItem); |
| | | locItem.setWorkQty(0.0).setQty(0.0).setLocCode(loc.getCode()).setLocId(loc.getId()).setId(null).setUpdateBy(loginUserId).setUpdateTime(new Date()); |
| | |
| | | throw new CoolException("数据错误:任务明细为空!!"); |
| | | } |
| | | |
| | | // 拣料入库:在生成拣料入库单时扣减原库位数量,不依赖出库完成时库位状态为R |
| | | if (TaskType.TASK_TYPE_PICK_IN.type.equals(type)) { |
| | | subtractLocItemByTaskItems(loc, taskItems, SystemAuthUtils.getLoginUserId()); |
| | | } |
| | | |
| | | tempLocs.forEach(working -> { |
| | | taskItems.forEach(taskItem -> { |
| | | if (Objects.equals(taskItem.getFieldsIndex(), working.getFieldsIndex())) { |
| | |
| | | .setQty(0.0) |
| | | .setLocId(loc1.getId()) |
| | | .setLocCode(loc1.getCode()); |
| | | // 拣料再入库:目标库位数量应为本次拣料数量(taskItem.qty),不是原库位剩余数量(taskItem.anfme) |
| | | if (TaskType.TASK_TYPE_PICK_IN.type.equals(task.getTaskType()) && taskItem.getQty() != null && taskItem.getQty().compareTo(0.0) > 0) { |
| | | itemWorking.setAnfme(taskItem.getQty()); |
| | | } |
| | | workings.add(itemWorking); |
| | | }); |
| | | |
| | |
| | | } |
| | | return; // 跳过后续处理 |
| | | } else { |
| | | // 库位明细不为空但状态不是R,记录错误但不抛出异常,让定时任务继续处理其他任务 |
| | | // 库位明细不为空但状态不是R,跳过处理 |
| | | logger.error("任务{}的库位{}状态为{},不是R.出库预约状态,但库位明细不为空,跳过处理。任务编码:{},库位编码:{}", |
| | | task.getId(), loc.getCode(), loc.getUseStatus(), task.getTaskCode(), loc.getCode()); |
| | | return; // 跳过处理,避免异常中断定时任务 |
| | | return; |
| | | } |
| | | } |
| | | |
| | |
| | | if (task.getTaskType().equals(TaskType.TASK_TYPE_OUT.type)) { |
| | | // 全版出库:不删除库位明细,等待PDA快速拣货确认时再删除 |
| | | // subtractLocItem(loc); // 已移除,改为在completeFullOutStock中删除 |
| | | } else { |
| | | // 部分出库(如拣料出库):根据TaskItem数量扣减库位明细 |
| | | } else if (!TaskType.TASK_TYPE_PICK_AGAIN_OUT.type.equals(task.getTaskType())) { |
| | | // 部分出库(如盘点出库):根据TaskItem数量扣减库位明细;拣料出库在生成拣料入库单时扣减 |
| | | subtractLocItemByTaskItems(loc, taskItems, loginUserId); |
| | | } |
| | | } catch (Exception e) { |