rsf-admin/src/page/basicInfo/matnr/PrintModal.jsx
@@ -226,14 +226,6 @@ } })) setData(val) setTimeout(() => { val.forEach((el) => { jsbarcode(`#barcode${el.code}`, el.code, { height: 30 }); }); }, 10); } else { notify(res.data.msg); } @@ -243,8 +235,26 @@ if (rows?.length > 0) { http(); } }, [rows]); // 在数据更新后生成条码 useEffect(() => { if (data.length > 0) { // 等待DOM更新后再生成条码 setTimeout(() => { data.forEach((item) => { const barcodeElement = document.getElementById(`barcode${item.code}`); if (barcodeElement) { try { jsbarcode(`#barcode${item.code}`, item.code, { height: 30 }); } catch (error) { console.error(`生成条码失败: ${item.code}`, error); } } }); }, 100); } }, [data]); return ( @@ -275,8 +285,7 @@ colSpan={9} style={{ border: '1px solid black' }} > {/* <img id={"barcode" + item.code} style={{ width: '70%', verticalAlign: 'middle' }} /> */} <img className="template-code" src={item.barcode} style={{ width: '90%', verticalAlign: 'middle' }} alt="Barcode" /> <img id={`barcode${item.code}`} style={{ width: '90%', verticalAlign: 'middle' }} alt="Barcode" /> <div style={{ letterSpacing: '2px', marginTop: '1px', textAlign: 'center' }}> <span>{item.code}</span> </div> rsf-admin/src/page/warehouseAreas/WarehouseAreasList.jsx
@@ -137,6 +137,7 @@ empty={<EmptyData onClick={() => { setCreateDialog(true) }} />} filters={filters} sort={{ field: "warehouseId", order: "desc" }} // disableSyncWithLocation={false} actions={( <TopToolbar> <FilterButton /> rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/impl/WmsRcsServiceImpl.java
@@ -335,7 +335,7 @@ */ @Override public CommonResponse reportTask(TaskReportParams params) { log.info("RCS回调,请求参数: {}", JSONObject.toJSONString(params)); log.info("任务执行通知上报,请求参数: {}", JSONObject.toJSONString(params)); // 参数校验 if (Objects.isNull(params)) { @@ -362,20 +362,20 @@ // 将任务上报回调转发到WMS系统 String callUrl = wmsApi.getHost() + ":" + wmsApi.getPort() + WmsConstant.callBack; log.info("RCS回调,请求地址: {}, 转换后参数: {}", callUrl, exMsgParams.toJSONString()); log.info("任务执行通知上报,请求地址: {}, 转换后参数: {}", callUrl, exMsgParams.toJSONString()); HttpHeaders headers = new HttpHeaders(); headers.add("Content-Type", "application/json"); headers.add("api-version", "v2.0"); HttpEntity httpEntity = new HttpEntity(exMsgParams, headers); ResponseEntity<String> exchange = restTemplate.exchange(callUrl, HttpMethod.POST, httpEntity, String.class); log.info("RCS回调,响应结果: {}", exchange); log.info("任务执行通知上报,响应结果: {}", exchange); if (Objects.isNull(exchange.getBody())) { // 如果回调失败,返回成功响应(避免RCS重复回调) CommonResponse response = new CommonResponse(); response.setCode(200); response.setMsg("接收成功"); log.warn("RCS回调失败,但返回成功响应,任务编号:{},批次:{}", params.getTaskNo(), params.getBatchNo()); log.warn("任务执行通知上报回调失败,但返回成功响应,任务编号:{},批次:{}", params.getTaskNo(), params.getBatchNo()); return response; } else { ObjectMapper objectMapper = new ObjectMapper(); @@ -384,14 +384,14 @@ try { CommonResponse result = objectMapper.readValue(exchange.getBody(), CommonResponse.class); if (result.getCode() == 200) { log.info("RCS回调上报成功,任务编号:{},批次:{}", params.getTaskNo(), params.getBatchNo()); log.info("任务执行通知上报成功,任务编号:{},批次:{}", params.getTaskNo(), params.getBatchNo()); return result; } else { log.warn("RCS回调上报回调返回非200状态,任务编号:{},批次:{},响应:{}", params.getTaskNo(), params.getBatchNo(), exchange.getBody()); log.warn("任务执行通知上报回调返回非200状态,任务编号:{},批次:{},响应:{}", params.getTaskNo(), params.getBatchNo(), exchange.getBody()); return result; } } catch (JsonProcessingException e) { log.error("RCS回调上报回调响应解析失败,任务编号:{},批次:{},错误:{}", params.getTaskNo(), params.getBatchNo(), e.getMessage()); log.error("任务执行通知上报回调响应解析失败,任务编号:{},批次:{},错误:{}", params.getTaskNo(), params.getBatchNo(), e.getMessage()); // 解析失败时返回成功响应,避免RCS重复回调 CommonResponse response = new CommonResponse(); response.setCode(200); rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/MobileServiceImpl.java
@@ -582,6 +582,44 @@ throw new CoolException("请至少输入一个查询条件:物料编码、ASN单号、跟踪码、批次或票号"); } // 如果扫描物料编码且ASN单号为空,直接从物料信息表获取,不查询收货区 if (!Cools.isEmpty(matnrCode) && Cools.isEmpty(asnCode) && Cools.isEmpty(code) && Cools.isEmpty(batch) && Objects.isNull(fieldIndex)) { logger.info("=== 从物料信息表查询物料信息(不查询收货区) ==="); logger.info("查询参数 - matnrCode: {}", matnrCode); Matnr matnr = matnrMapper.selectOne(new LambdaQueryWrapper<Matnr>() .eq(Matnr::getCode, matnrCode) .eq(Matnr::getDeleted, 0) .last("LIMIT 1")); if (matnr == null) { logger.warn("物料信息表中未找到物料编码: {}", matnrCode); return R.ok(new ArrayList<>()); } // 构造一个虚拟的 WarehouseAreasItem 对象返回物料信息 WarehouseAreasItem item = new WarehouseAreasItem(); item.setMatnrId(matnr.getId()); item.setMatnrCode(matnr.getCode()); item.setMaktx(matnr.getName()); item.setStockUnit(matnr.getStockUnit()); item.setUnit(matnr.getUnit()); item.setAnfme(0.0); // 数量设为0,因为不是从收货区查询的 item.setWorkQty(0.0); item.setQty(0.0); // 设置扩展字段 Map<String, String> fields = FieldsUtils.getFields(matnr.getFieldsIndex()); item.setExtendFields(fields); List<WarehouseAreasItem> resultList = new ArrayList<>(); resultList.add(item); logger.info("从物料信息表返回 1 条物料数据"); return R.ok(resultList); } //TODO 后续需根据策略配置,获取组拖数据。如:混装,按批次混装等 LambdaQueryWrapper<WarehouseAreasItem> queryWrapper = new LambdaQueryWrapper<>(); @@ -685,6 +723,51 @@ logger.warn("数据库查询结果为空,可能原因:1.物料编码不匹配 2.物料未收货至收货区 3.数据已被删除"); } // 如果扫描物料编码加载物料并且ASN单号为空时,从物料信息表获取物料信息并更新 if (!Cools.isEmpty(matnrCode) && Cools.isEmpty(asnCode) && !list.isEmpty()) { // 收集所有唯一的物料编码 Set<String> matnrCodes = list.stream() .map(WarehouseAreasItem::getMatnrCode) .filter(matCode -> !Cools.isEmpty(matCode)) .collect(Collectors.toSet()); // 批量查询物料信息 if (!matnrCodes.isEmpty()) { Map<String, Matnr> matnrMap = new HashMap<>(); for (String matCode : matnrCodes) { Matnr matnr = matnrMapper.selectOne(new LambdaQueryWrapper<Matnr>() .eq(Matnr::getCode, matCode) .eq(Matnr::getDeleted, 0) .last("LIMIT 1")); if (matnr != null) { matnrMap.put(matCode, matnr); } } // 更新列表中的物料信息 list.forEach(item -> { String itemMatnrCode = item.getMatnrCode(); if (!Cools.isEmpty(itemMatnrCode) && matnrMap.containsKey(itemMatnrCode)) { Matnr matnr = matnrMap.get(itemMatnrCode); // 从物料信息表更新物料名称 if (!Cools.isEmpty(matnr.getName())) { item.setMaktx(matnr.getName()); } // 从物料信息表更新库存单位 if (!Cools.isEmpty(matnr.getStockUnit())) { item.setStockUnit(matnr.getStockUnit()); } // 从物料信息表更新单位 if (!Cools.isEmpty(matnr.getUnit())) { item.setUnit(matnr.getUnit()); } logger.debug("已从物料信息表更新物料信息 - matnrCode: {}, name: {}, stockUnit: {}", itemMatnrCode, matnr.getName(), matnr.getStockUnit()); } }); } } list.forEach(item -> { Map<String, String> fields = FieldsUtils.getFields(item.getFieldsIndex()); item.setExtendFields(fields); rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/WcsServiceImpl.java
@@ -581,7 +581,7 @@ log.warn("未处理的事件类型 - 事件类型:{},任务编码:{},任务类型:{}", params.getEventType(), task.getTaskCode(), task.getTaskType()); } log.info("========== RCS回调处理完成 =========="); log.info("========== 任务执行通知上报处理完成 =========="); log.info("处理结果:{}", JSONObject.toJSONString(params)); return R.ok(JSONObject.toJSONString(params)); } rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java
@@ -462,9 +462,6 @@ if (task.getTaskType().equals(TaskType.TASK_TYPE_IN.type)) { //1.入库 complateInstock(task, loginUserId); } else if (task.getTaskType().equals(TaskType.TASK_TYPE_EMPITY_IN.type)) { //10.空托入库 complateEmpityInStock(task, loginUserId); } else if (task.getTaskType().equals(TaskType.TASK_TYPE_PICK_IN.type) || task.getTaskType().equals(TaskType.TASK_TYPE_CHECK_IN.type)) { //53.拣料再入库 //57.盘点再入库 @@ -1797,80 +1794,6 @@ .set(WaitPakin::getUpdateBy, loginUserId) .in(WaitPakin::getId, pakinIds))) { throw new CoolException("组拖状态修改失败!!"); } /**修改库位状态为F.在库*/ if (!locService.update(new LambdaUpdateWrapper<Loc>().set(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_F.type).eq(Loc::getCode, task.getTargLoc()))) { throw new CoolException("库位状态修改失败!!"); } if (!this.update(new LambdaUpdateWrapper<Task>().eq(Task::getId, task.getId()).set(Task::getTaskStatus, TaskStsType.UPDATED_IN.id))) { throw new CoolException("任务状态修改失败!!"); } } /** * 空托入库完成 * * @param task * @param loginUserId */ @Transactional(rollbackFor = Exception.class) public synchronized void complateEmpityInStock(Task task, Long loginUserId) { if (Objects.isNull(task)) { return; } Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getCode, task.getTargLoc())); if (Objects.isNull(loc)) { throw new CoolException("目标库位不存在!"); } if (!loc.getUseStatus().equals(LocStsType.LOC_STS_TYPE_S.type)) { throw new CoolException("当前库位状态不处于S.入库预约,不可执行入库操作!"); } List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId())); if (taskItems.isEmpty()) { throw new CoolException("任务明细不存在!!"); } //更新库位明细 saveLocItem(taskItems, task.getId(), loginUserId); //空托入库不校验组托信息,直接处理任务明细 //如果有任务明细关联了组托,也需要保存入出库明细和移出收货区库存 Map<Long, List<TaskItem>> orderMap = taskItems.stream().collect(Collectors.groupingBy(TaskItem::getSource)); orderMap.keySet().forEach(key -> { // 如果source不为空,说明有关联的组托明细,需要处理 if (key != null && key > 0) { WaitPakinItem pakinItem = waitPakinItemService.getById(key); if (!Objects.isNull(pakinItem)) { List<TaskItem> items = orderMap.get(key); //保存入出库明细 saveStockItems(items, task, pakinItem.getId(), pakinItem.getAsnCode(), pakinItem.getWkType(), pakinItem.getType(), loginUserId); //移出收货区库存, 修改组托状态 removeReceiptStock(pakinItem, loginUserId); } } }); // 处理组托状态(如果有组托关联) Set<Long> pkinItemIds = taskItems.stream() .map(TaskItem::getSource) .filter(source -> source != null && source > 0) .collect(Collectors.toSet()); if (!pkinItemIds.isEmpty()) { List<WaitPakinItem> pakinItems = waitPakinItemService.list(new LambdaQueryWrapper<WaitPakinItem>().in(WaitPakinItem::getId, pkinItemIds)); if (!pakinItems.isEmpty()) { Set<Long> pakinIds = pakinItems.stream().map(WaitPakinItem::getPakinId).collect(Collectors.toSet()); if (!waitPakinService.update(new LambdaUpdateWrapper<WaitPakin>() .set(WaitPakin::getIoStatus, PakinIOStatus.PAKIN_IO_STATUS_TASK_DONE.val) .set(WaitPakin::getUpdateBy, loginUserId) .in(WaitPakin::getId, pakinIds))) { throw new CoolException("组拖状态修改失败!!"); } } } /**修改库位状态为F.在库*/ rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaitPakinServiceImpl.java
@@ -8,6 +8,7 @@ import com.vincent.rsf.server.manager.entity.*; import com.vincent.rsf.server.manager.enums.PakinIOStatus; import com.vincent.rsf.server.manager.mapper.WaitPakinMapper; import com.vincent.rsf.server.manager.mapper.MatnrMapper; import com.vincent.rsf.server.manager.service.*; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.vincent.rsf.server.system.constant.SerialRuleCode; @@ -41,6 +42,8 @@ private TaskService taskService; @Autowired private TaskItemService taskItemService; @Autowired private MatnrMapper matnrMapper; /** @@ -63,34 +66,22 @@ WaitPakin pakin = waitPakinService.getOne(new LambdaQueryWrapper<WaitPakin>() .eq(WaitPakin::getBarcode, waitPakin.getBarcode())); // 如果容器号已经组托过,提示已组托,请更换容器条码 if (!Objects.isNull(pakin)) { throw new CoolException("已组托,请更换容器条码"); } List<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>().eq(Task::getBarcode, waitPakin.getBarcode())); if (!tasks.isEmpty()) { throw new CoolException("当前托盘已有任务档在执行,不能再次组托!!"); } if (!Objects.isNull(pakin)) { List<WaitPakinItem> waitPakinItems = waitPakinItemService.list(new LambdaQueryWrapper<WaitPakinItem>().eq(!Objects.isNull(pakin.getId()) ,WaitPakinItem::getPakinId, pakin.getId())); waitPakinItems.forEach(item -> { for (PakinItem pakinItem : waitPakin.getItems()) { WarehouseAreasItem warehouseAreasItems = warehouseAreasItemService.getById(pakinItem.getId()); if (Objects.isNull(warehouseAreasItems)) { throw new CoolException("物料未送至收货区或已组托完成移出收货区!!"); } // 只在票号不为空时才进行重复检查 if (!Objects.isNull(item.getFieldsIndex()) && !Objects.isNull(warehouseAreasItems.getFieldsIndex()) && item.getFieldsIndex().equals(warehouseAreasItems.getFieldsIndex())) { String crushNo = item.getExtendFields() != null ? item.getExtendFields().get("crushNo") : ""; throw new CoolException("票号:" + crushNo + "已组托,不可重复组托!!"); } } }); } // 检查容器号是否在库存中存在(通过库位表查询) List<Loc> locs = locService.list(new LambdaQueryWrapper<Loc>().eq(Loc::getBarcode, waitPakin.getBarcode())); if (!locs.isEmpty()) { List<String> locCodes = locs.stream().map(Loc::getCode).collect(Collectors.toList()); String join = StringUtils.join(locCodes, ","); throw new CoolException("托盘码:" + waitPakin.getBarcode() + "已被库位:" + join + "使用!!"); throw new CoolException("在库,请更换容器条码"); } double sum = waitPakin.getItems().stream().mapToDouble(PakinItem::getReceiptQty).sum(); WaitPakin waitPakin1 = new WaitPakin(); @@ -115,46 +106,90 @@ List<WaitPakinItem> items = new ArrayList<>(); for (PakinItem pakinItem1 : waitPakin.getItems()) { //不良标签组托 WarehouseAreasItem warehouseAreasItems = warehouseAreasItemService.getById(pakinItem1.getId()); if (null == warehouseAreasItems) { throw new CoolException("物料未送至收货区!!"); } WaitPakinItem pakinItem = new WaitPakinItem(); pakinItem.setAnfme(warehouseAreasItems.getAnfme()) .setPakinId(waitPakin1.getId()) .setSource(warehouseAreasItems.getId()) .setAsnId(warehouseAreasItems.getAsnId()) .setAsnCode(warehouseAreasItems.getAsnCode()) .setAsnItemId(warehouseAreasItems.getAsnItemId()) .setIsptResult(warehouseAreasItems.getIsptResult()) .setPlatItemId(warehouseAreasItems.getPlatItemId()) .setPlatOrderCode(warehouseAreasItems.getPlatOrderCode()) .setPlatWorkCode(warehouseAreasItems.getPlatWorkCode()) .setProjectCode(warehouseAreasItems.getProjectCode()) .setBatch(warehouseAreasItems.getSplrBatch()) .setUnit(warehouseAreasItems.getStockUnit()) .setFieldsIndex(warehouseAreasItems.getFieldsIndex()) .setMatnrId(warehouseAreasItems.getMatnrId()) .setMaktx(warehouseAreasItems.getMaktx()) .setUpdateBy(userId) .setCreateBy(userId) .setMatnrCode(warehouseAreasItems.getMatnrCode()); WkOrder order = asnOrderService.getById(warehouseAreasItems.getAsnId()); if (!Objects.isNull(order)) { pakinItem.setType(null == order.getType() ? null : order.getType()) .setWkType(null == order.getWkType() ? null : Short.parseShort(order.getWkType())); } // 如果ASN单号为空,从物料信息表获取物料信息,不查询收货区 if (StringUtils.isBlank(pakinItem1.getAsnCode())) { if (Objects.isNull(pakinItem1.getMatnrId())) { throw new CoolException("物料ID不能为空!!"); } // 从物料信息表获取物料信息 Matnr matnr = matnrMapper.selectById(pakinItem1.getMatnrId()); if (Objects.isNull(matnr)) { throw new CoolException("物料信息不存在,物料ID:" + pakinItem1.getMatnrId()); } // 设置组托明细信息(不设置source,因为不在收货区) pakinItem.setPakinId(waitPakin1.getId()) .setSource(null) // 不在收货区,source设为null .setAsnId(null) .setAsnCode(null) .setAsnItemId(null) .setIsptResult(null) .setPlatItemId(null) .setPlatOrderCode(null) .setPlatWorkCode(null) .setProjectCode(null) .setBatch(null) .setUnit(matnr.getStockUnit()) .setFieldsIndex(matnr.getFieldsIndex()) .setMatnrId(matnr.getId()) .setMaktx(matnr.getName()) .setUpdateBy(userId) .setCreateBy(userId) .setMatnrCode(matnr.getCode()); // 设置组托数量 if (pakinItem1.getReceiptQty() == null || pakinItem1.getReceiptQty().compareTo(0.0) <= 0) { throw new CoolException("组托数量不能小于等于零!!"); } pakinItem.setAnfme(pakinItem1.getReceiptQty()) .setTrackCode(pakinItem1.getTrackCode()); } else { // 有ASN单号,从收货区获取物料信息 WarehouseAreasItem warehouseAreasItems = warehouseAreasItemService.getById(pakinItem1.getId()); if (null == warehouseAreasItems) { throw new CoolException("物料未送至收货区!!"); } pakinItem.setAnfme(warehouseAreasItems.getAnfme()) .setPakinId(waitPakin1.getId()) .setSource(warehouseAreasItems.getId()) .setAsnId(warehouseAreasItems.getAsnId()) .setAsnCode(warehouseAreasItems.getAsnCode()) .setAsnItemId(warehouseAreasItems.getAsnItemId()) .setIsptResult(warehouseAreasItems.getIsptResult()) .setPlatItemId(warehouseAreasItems.getPlatItemId()) .setPlatOrderCode(warehouseAreasItems.getPlatOrderCode()) .setPlatWorkCode(warehouseAreasItems.getPlatWorkCode()) .setProjectCode(warehouseAreasItems.getProjectCode()) .setBatch(warehouseAreasItems.getSplrBatch()) .setUnit(warehouseAreasItems.getStockUnit()) .setFieldsIndex(warehouseAreasItems.getFieldsIndex()) .setMatnrId(warehouseAreasItems.getMatnrId()) .setMaktx(warehouseAreasItems.getMaktx()) .setUpdateBy(userId) .setCreateBy(userId) .setMatnrCode(warehouseAreasItems.getMatnrCode()); WkOrder order = asnOrderService.getById(warehouseAreasItems.getAsnId()); if (!Objects.isNull(order)) { pakinItem.setType(null == order.getType() ? null : order.getType()) .setWkType(null == order.getWkType() ? null : Short.parseShort(order.getWkType())); } for (PakinItem waitPakinItem : waitPakin.getItems()) { if (waitPakinItem.getId().equals(warehouseAreasItems.getId())) { if (waitPakinItem.getReceiptQty() > warehouseAreasItems.getAnfme() || waitPakinItem.getReceiptQty().compareTo(0.0) <= 0) { throw new CoolException("组托数量不能大于收货数量且不能小于零!!"); for (PakinItem waitPakinItem : waitPakin.getItems()) { if (waitPakinItem.getId().equals(warehouseAreasItems.getId())) { if (waitPakinItem.getReceiptQty() > warehouseAreasItems.getAnfme() || waitPakinItem.getReceiptQty().compareTo(0.0) <= 0) { throw new CoolException("组托数量不能大于收货数量且不能小于零!!"); } pakinItem.setAnfme(waitPakinItem.getReceiptQty()) .setTrackCode(waitPakinItem.getTrackCode()); } pakinItem.setAnfme(waitPakinItem.getReceiptQty()) .setTrackCode(waitPakinItem.getTrackCode()); } } items.add(pakinItem); } @@ -170,6 +205,11 @@ // Double total = Math.round((sum + waitSum) * 100) / 100.0; for (WaitPakinItem pakinItem : items) { // 如果source为空(没有ASN单号,不在收货区),跳过收货区更新 if (Objects.isNull(pakinItem.getSource())) { continue; } WarehouseAreasItem one = warehouseAreasItemService.getOne(new LambdaQueryWrapper<WarehouseAreasItem>() .eq(WarehouseAreasItem::getId, pakinItem.getSource())); if (Objects.isNull(one)) {