chen.lin
15 小时以前 da15785661f7832cdcb78fb6504752c0cb385e63
入库数量变更
3个文件已修改
82 ■■■■■ 已修改文件
rsf-admin/src/layout/TabsBar.jsx 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/layout/index.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/layout/TabsBar.jsx
@@ -405,24 +405,24 @@
    };
    // 判断指定标签页是否可以关闭左侧标签
    // 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
@@ -481,16 +481,18 @@
                                                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>
                                )}
@@ -562,6 +564,7 @@
                    sx: { py: 0 },
                }}
            >
                {/* 关闭当前标签
                {contextMenuTab && contextMenuTab.closable && (
                    <MenuItem
                        onClick={handleCloseCurrentTab}
@@ -575,13 +578,30 @@
                        {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>
                )}
rsf-admin/src/layout/index.jsx
@@ -33,7 +33,7 @@
        top: 48,
        left: sidebarWidth + 5,
        right: 0,
        zIndex: 1100,
        zIndex: 1350, // 高于 Dialog(1300),避免菜单内弹窗遮盖标签页
        transition: (theme) =>
          theme.transitions.create('left', {
            easing: theme.transitions.easing.sharp,
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java
@@ -873,6 +873,9 @@
            }
            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());
@@ -1304,6 +1307,11 @@
            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())) {
@@ -1376,6 +1384,10 @@
                    .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);
        });
@@ -1431,10 +1443,10 @@
                }
                return; // 跳过后续处理
            } else {
                // 库位明细不为空但状态不是R,记录错误但不抛出异常,让定时任务继续处理其他任务
                // 库位明细不为空但状态不是R,跳过处理
                logger.error("任务{}的库位{}状态为{},不是R.出库预约状态,但库位明细不为空,跳过处理。任务编码:{},库位编码:{}", 
                        task.getId(), loc.getCode(), loc.getUseStatus(), task.getTaskCode(), loc.getCode());
                return; // 跳过处理,避免异常中断定时任务
                return;
            }
        }
        
@@ -1461,8 +1473,8 @@
                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) {