rsf-admin/.env
@@ -1,3 +1,3 @@ VITE_BASE_IP=192.168.4.24 VITE_BASE_IP=127.0.0.1 # VITE_BASE_IP=47.76.147.249 VITE_BASE_PORT=8080 rsf-admin/src/page/taskItemLog/TaskItemLogList.jsx
@@ -111,6 +111,7 @@ }} title={"menu.taskItemLog"} filters={filters} empty={false} sort={{ field: "create_time", order: "desc" }} actions={( <TopToolbar> rsf-admin/src/page/taskLog/TaskLogList.jsx
@@ -110,7 +110,7 @@ marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0, }} title={"menu.taskLog"} empty={<EmptyData onClick={() => { setCreateDialog(true) }} />} empty={false} filters={filters} sort={{ field: "create_time", order: "desc" }} actions={( rsf-server/src/main/java/com/vincent/rsf/server/api/controller/MobileController.java
@@ -234,7 +234,7 @@ @ApiOperation("任务上架") @PreAuthorize("hasAuthority('manager:qlyInspect:update')") @PostMapping("/task/stock") @PostMapping("/task/public/{code}") public R taskToLocs(@PathVariable String code) throws Exception { if (Objects.isNull(code)) { return R.error("参数不能为空!!"); rsf-server/src/main/java/com/vincent/rsf/server/api/entity/dto/TaskQueueDto.java
@@ -1,6 +1,5 @@ package com.vincent.rsf.server.api.entity.dto; import com.vincent.rsf.server.manager.entity.Loc; import com.vincent.rsf.server.manager.entity.Task; import com.vincent.rsf.server.manager.entity.TaskItem; import io.swagger.annotations.ApiModel; @@ -14,7 +13,7 @@ @Data @Accessors(chain = true) @ApiModel(value = "TaskQueueDto", description = "任务信息") public class TaskQueueDto implements Serializable { public class TaskQueueDto implements Serializable{ @ApiModelProperty("任务主单") private Task task; rsf-server/src/main/java/com/vincent/rsf/server/api/entity/enums/OrderType.java
@@ -12,7 +12,8 @@ ORDER_PURCHASE_IN("purchase", "采购入库单"), ORDER_OUT("out", "出库单"), ORDER_IN("in", "入库单"), ORDER_RECEIPT("receipt", "收货单") ORDER_RECEIPT("receipt", "收货单"), ORDER_PLAT_IN("plat in", "平库入库单"), ; rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/MobileServiceImpl.java
@@ -6,6 +6,7 @@ import com.vincent.rsf.framework.exception.CoolException; import com.vincent.rsf.server.api.controller.params.*; import com.vincent.rsf.server.api.entity.dto.*; import com.vincent.rsf.server.api.entity.enums.OrderType; import com.vincent.rsf.server.api.entity.enums.OrderWorkType; import com.vincent.rsf.server.api.service.MobileService; import com.vincent.rsf.server.common.config.ConfigProperties; @@ -201,7 +202,7 @@ List<ReceiptDetlsDto> receipts = params.getReceipts(); List<WarehouseAreasItem> allOrders = new ArrayList<>(); double receiptQty = receipts.stream().mapToDouble(ReceiptDetlsDto::getReceiptQty).sum(); Double receiptQty = receipts.stream().mapToDouble(ReceiptDetlsDto::getReceiptQty).sum(); String asnCode = receipts.stream().findFirst().get().getAsnCode(); @@ -210,7 +211,9 @@ if (Objects.isNull(asnOrder)) { throw new CoolException("数据错误:主单不存在!!"); } asnOrder.setQty(receiptQty); /**收货数量累加,1. 会出超收情况 2. 会有收货不足情况*/ Double rcptedQty = asnOrder.getQty() + receiptQty; asnOrder.setQty(rcptedQty); if (!asnOrderMapper.updateById(asnOrder)) { throw new CoolException("已收货数量修改失败!!"); @@ -234,40 +237,14 @@ if (Objects.isNull(orderItem)) { throw new CoolException("通知单明细不存在!!"); } if (Objects.isNull(dto.getReceiptQty()) || Double.compare(dto.getReceiptQty(), 0.0) == 0) { throw new CoolException("收货数量不能为零!!"); } orderItem.setQty(dto.getReceiptQty()) .setProdTime(dto.getProdTime()); if (asnOrderItemMapper.updateById(orderItem) < 1) { throw new CoolException("通知单明细数量修改失败!!"); } WarehouseAreasItem item = new WarehouseAreasItem(); // SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // String format = null; // if (Objects.isNull(dto.getProdTime())) { // format = dateFormat.format(dto.getProdTime()); // if (Objects.isNull(dto.getReceiptQty()) || Double.compare(dto.getReceiptQty(), 0.0) == 0) { // throw new CoolException("收货数量不能为零!!"); // } item.setBarcode(dto.getBarcode()) .setAreaName(areasItem.getName()) .setAreaId(areasItem.getId()) .setProdTime(dto.getProdTime()) .setWeight(dto.getWeigth()) Double itemRcptQty = dto.getReceiptQty() + orderItem.getQty(); orderItem.setQty(itemRcptQty) .setSplrBatch(dto.getSplrBatch()) .setStockUnit(dto.getStockUnit()) .setBatch(SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_RECEIPT_BATCH, dto)) .setAnfme(dto.getReceiptQty()) .setSplrBtch(dto.getSplrBatch()) .setMatnrCode(matnr.getCode()) .setMatnrId(matnr.getId()) .setMatnrName(matnr.getName()) //库存单位为最小单位 .setUnit(dto.getStockUnit()) .setStockUnit(dto.getStockUnit()) .setWeight(matnr.getWeight()) .setShipperId(matnr.getShipperId()); //TODO 供应商标识未设置,标识由PO单供应商编码转换 .setProdTime(dto.getProdTime()); if (!Objects.isNull(fields)) { if (!Objects.isNull(dto.getExtendFields())) { @@ -286,76 +263,65 @@ .setValue(extendFields.get(key).toString()) .setUuid(uuid16); fieldsItems.add(fieldsItem); //唯一标识入库 item.setFieldsIndex(uuid16); } }); }); if (!fieldsItemService.saveBatch(fieldsItems)) { throw new CoolException("扩展字段保存失败!!"); } orderItem.setFieldsIndex(uuid16); } } if (asnOrderItemMapper.updateById(orderItem) < 1) { throw new CoolException("通知单明细数量修改失败!!"); } WarehouseAreasItem item = new WarehouseAreasItem(); // SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // String format = null; // if (Objects.isNull(dto.getProdTime())) { // format = dateFormat.format(dto.getProdTime()); // } item.setBarcode(dto.getBarcode()) .setAreaName(areasItem.getName()) .setAreaId(areasItem.getId()) .setProdTime(dto.getProdTime()) .setWeight(dto.getWeigth()) .setStockUnit(dto.getStockUnit()) .setBatch(SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_RECEIPT_BATCH, dto)) .setAnfme(itemRcptQty) .setSplrBtch(dto.getSplrBatch()) .setMatnrCode(matnr.getCode()) .setMatnrId(matnr.getId()) .setMatnrName(matnr.getName()) //库存单位为最小单位 .setUnit(dto.getStockUnit()) .setStockUnit(dto.getStockUnit()) .setWeight(matnr.getWeight()) .setFieldsIndex(orderItem.getFieldsIndex()) .setShipperId(matnr.getShipperId()); //TODO 供应商标识未设置,标识由PO单供应商编码转换 allOrders.add(item); }); if (!warehouseAreasItemService.saveBatch(allOrders)) { throw new CoolException("收货失败!!"); } //获取采购数量 double purQty = receipts.stream().mapToDouble(ReceiptDetlsDto::getPurQty).sum(); BigDecimal subtract = BigDecimal.valueOf(receiptQty).subtract(BigDecimal.valueOf(purQty)); //判断已收货数量是否小于等于采购数量 if (subtract.compareTo(new BigDecimal("0.0")) <= 0) { asnOrder.setRleStatus(Short.valueOf("1")); //日志表操作 operateOrderLogs(asnOrder); } // //获取采购数量 // double purQty = receipts.stream().mapToDouble(ReceiptDetlsDto::getPurQty).sum(); // // BigDecimal subtract = BigDecimal.valueOf(receiptQty).subtract(BigDecimal.valueOf(purQty)); // //判断已收货数量是否小于等于采购数量 // if (subtract.compareTo(new BigDecimal("0.0")) <= 0) { // asnOrder.setRleStatus(Short.valueOf("1")); // //日志表操作 // operateOrderLogs(asnOrder); // } return R.ok("操作成功"); } /** * @author Ryan * @description 删除原主单及明细,加入历史档 * @param * @return * @time 2025/3/19 19:53 */ private void operateOrderLogs(AsnOrder asnOrder) { if (!asnOrderMapper.removeById(asnOrder.getId())) { throw new CoolException("原单据删除失败!!"); } AsnOrderLog orderLog = new AsnOrderLog(); BeanUtils.copyProperties(asnOrder, orderLog); orderLog.setAsnId(asnOrder.getId()); if (!asnOrderLogService.save(orderLog)) { throw new CoolException("主单历史档添加失败!!"); } List<AsnOrderItemLog> logs = new ArrayList<>(); List<AsnOrderItem> items = asnOrderItemMapper.selectList(new LambdaQueryWrapper<AsnOrderItem>().eq(AsnOrderItem::getAsnId, asnOrder.getId())); items.forEach(item -> { AsnOrderItemLog itemLog = new AsnOrderItemLog(); BeanUtils.copyProperties(item, itemLog); itemLog.setAsnItemId(itemLog.getId()) .setAsnId(item.getAsnId()); logs.add(itemLog); }); if (!asnOrderItemLogService.saveBatch(logs)) { throw new CoolException("通知单明细历史档保存失败!!"); } if (asnOrderItemMapper.delete(new LambdaQueryWrapper<AsnOrderItem>().eq(AsnOrderItem::getAsnId, asnOrder.getId())) < 1) { throw new CoolException("原单据明细删除失败!!"); } } /** * @author Ryan @@ -624,7 +590,10 @@ throw new CoolException("单据明细不能为空!!"); } Long OrderId = params.getItemList().stream().findFirst().get().getAsnId(); AsnOrder order = asnOrderMapper.getOne(new LambdaQueryWrapper<AsnOrder>().eq(AsnOrder::getId, OrderId)); /**获取平库订单*/ AsnOrder order = asnOrderMapper.getOne(new LambdaQueryWrapper<AsnOrder>() .eq(AsnOrder::getId, OrderId) .eq(AsnOrder::getType, OrderType.ORDER_PLAT_IN.type)); if (Objects.isNull(order)) { throw new CoolException("单据不存在!!"); } @@ -681,7 +650,7 @@ throw new CoolException("拖盘任务不存在!!"); } List<TaskItem> taskItems = taskItemService.list(new LambdaQueryWrapper<TaskItem>().eq(TaskItem::getTaskId, task.getId())); if (!taskItems.isEmpty()) { if (taskItems.isEmpty()) { throw new CoolException("拖盘任务明细不存在!!"); } TaskQueueDto queueDto = new TaskQueueDto(); rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/AsnOrderController.java
@@ -190,4 +190,19 @@ } return R.ok(asnOrderService.batchUpdate(params, getLoginUserId())); } @ApiOperation("一键收货") @PostMapping("/asnOrder/complete/{id}") @PreAuthorize("hasAuthority('manager:asnOrder:update')") public R completeOrder(@PathVariable Long id) { if (Objects.isNull(id)) { return R.error("参数不能为空!!"); } return asnOrderService.completeOrder(id, getLoginUserId()); } } rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/AsnOrder.java
@@ -210,6 +210,18 @@ // null // 备注 // ); public String getExceStatus$() { if (Cools.isEmpty(this.exceStatus)){ return ""; } DictDataService dictDataService = SpringUtils.getBean(DictDataService.class); DictData dictData = dictDataService.getOne(new LambdaQueryWrapper<DictData>().eq(DictData::getDictTypeCode, DictTypeCode.DICT_ASN_EXCE_STATUS).eq(DictData::getValue, this.exceStatus)); if (Objects.isNull(dictData)) { return null; } return dictData.getLabel(); } public String getType$(){ if (Cools.isEmpty(this.type)){ return ""; rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/AsnOrderLog.java
@@ -112,6 +112,9 @@ @ApiModelProperty(value= "状态 1: 正常 0: 冻结 ") private Integer status; @ApiModelProperty("执行状态") private Short exceStatus; /** * 是否删除 1: 是 0: 否 */ rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Task.java
@@ -34,10 +34,8 @@ @Data @Accessors(chain = true) @TableName("man_task") @ApiModel(value = "Task", description = "任务档") public class Task implements Serializable { private static final long serialVersionUID = 1L; /** * ID */ rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/TaskItem.java
@@ -31,10 +31,8 @@ @Data @Accessors(chain = true) @TableName("man_task_item") @ApiModel(value = "TaskItem", description = "任务档明细") public class TaskItem implements Serializable { private static final long serialVersionUID = 1L; /** * ID */ rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/PakinIOStatus.java
New file @@ -0,0 +1,27 @@ package com.vincent.rsf.server.manager.enums; /** * @author Ryan * @version 1.0 * @title PakinIOStatus * @description * @create 2025/4/7 08:48 */ public enum PakinIOStatus { //质检状态 PAKIN_IO_STATUS_HOLD("0", "待入库"), QLY_ISPT_STAS_DONE("1", "组拖完成"), QLY_ISPT_STAS_TASK_EXCE("2", "任务执行中"), QLY_ISPT_STAS_TASK_DONE("3", "任务完成") ; PakinIOStatus(String val, String desc) { this.val = val; this.desc = desc; } public String val; public String desc; } rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/ScheduleJobs.java
@@ -68,7 +68,7 @@ */ @Scheduled(cron = "0 0/05 * * * ? ") @Transactional(rollbackFor = Exception.class) public void genAsnOrder() { public synchronized void genAsnOrder() { //判断是否开启自动生成ASN单据 if (!flowProperties.getFlagAutoAsn()) { return; rsf-server/src/main/java/com/vincent/rsf/server/manager/service/AsnOrderService.java
@@ -21,4 +21,5 @@ boolean batchUpdate(BatchUpdateParam params, Long loginUserId); R completeOrder(Long id, Long loginUserId); } rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderServiceImpl.java
@@ -11,15 +11,20 @@ import com.vincent.rsf.server.manager.controller.params.AsnOrderAndItemsParams; import com.vincent.rsf.server.manager.controller.params.BatchUpdateParam; import com.vincent.rsf.server.manager.entity.AsnOrderItem; import com.vincent.rsf.server.manager.entity.AsnOrderItemLog; import com.vincent.rsf.server.manager.entity.AsnOrderLog; import com.vincent.rsf.server.manager.mapper.AsnOrderMapper; import com.vincent.rsf.server.manager.entity.AsnOrder; import com.vincent.rsf.server.manager.mapper.PurchaseMapper; import com.vincent.rsf.server.manager.service.AsnOrderItemLogService; import com.vincent.rsf.server.manager.service.AsnOrderItemService; import com.vincent.rsf.server.manager.service.AsnOrderLogService; import com.vincent.rsf.server.manager.service.AsnOrderService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.vincent.rsf.server.system.constant.SerialRuleCode; import com.vincent.rsf.server.system.mapper.SerialRuleMapper; import com.vincent.rsf.server.system.utils.SerialRuleUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -46,6 +51,10 @@ private PurchaseMapper purchaseMapper; @Autowired private AsnOrderItemService asnOrderItemService; @Autowired private AsnOrderLogService asnOrderLogService; @Autowired private AsnOrderItemLogService asnOrderItemLogService; @Resource private SerialRuleMapper serialRuleMapper; @@ -171,6 +180,75 @@ .set(!Objects.isNull(order.getWkType()), AsnOrder::getWkType, order.getWkType()) .set(!Objects.isNull(order.getExceStatus()), AsnOrder::getExceStatus, order.getExceStatus()) .set(AsnOrder::getUpdateBy, userId)); } /** * @param id * @param loginUserId * @return * @author Ryan * @description 一键收货 * @time 2025/4/3 15:45 */ @Override @Transactional(rollbackFor = Exception.class) public R completeOrder(Long id, Long loginUserId) { AsnOrder asnOrder = this.getById(id); if (Objects.isNull(asnOrder)) { throw new CoolException("单据不存在!!"); } //一键加入历史档 try { operateOrderLogs(asnOrder); } catch (Exception e) { throw new CoolException("收货完成失败!!"); } return R.ok("收货成功!!"); } /** * @author Ryan * @description 删除原主单及明细,加入历史档 * @param * @return * @time 2025/3/19 19:53 */ @Transactional(rollbackFor = Exception.class) private void operateOrderLogs(AsnOrder asrder) throws Exception{ if (Objects.isNull(asrder) || Objects.isNull(asrder.getId())) { throw new CoolException("参数不能为空!!"); } AsnOrder order = this.getById(asrder.getId()); AsnOrderLog orderLog = new AsnOrderLog(); order.setExceStatus(Short.valueOf("2")); BeanUtils.copyProperties(order, orderLog); orderLog.setId(null); orderLog.setAsnId(order.getId()); if (!this.saveOrUpdate(order)) { throw new CoolException("状态修改失败!!"); } if (!asnOrderLogService.save(orderLog)) { throw new CoolException("主单历史档添加失败!!"); } List<AsnOrderItemLog> logs = new ArrayList<>(); List<AsnOrderItem> items = asnOrderItemService.list(new LambdaQueryWrapper<AsnOrderItem>().eq(AsnOrderItem::getAsnId, order.getId())); items.forEach(item -> { AsnOrderItemLog itemLog = new AsnOrderItemLog(); BeanUtils.copyProperties(item, itemLog); itemLog.setAsnItemId(itemLog.getId()) .setAsnId(item.getAsnId()); logs.add(itemLog); }); if (!asnOrderItemLogService.saveBatch(logs)) { throw new CoolException("通知单明细历史档保存失败!!"); } if (!asnOrderItemService.remove(new LambdaQueryWrapper<AsnOrderItem>().eq(AsnOrderItem::getAsnId, order.getId()))) { throw new CoolException("原单据明细删除失败!!"); } if (!this.removeById(asrder.getId())) { throw new CoolException("原单据删除失败!!"); } } } rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/QlyInspectServiceImpl.java
@@ -1,6 +1,7 @@ package com.vincent.rsf.server.manager.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.vincent.rsf.framework.common.R; import com.vincent.rsf.framework.exception.CoolException; import com.vincent.rsf.server.manager.controller.params.IsptOrderParam; @@ -171,6 +172,9 @@ throw new CoolException("明细保存失败!!"); } } if (!asnOrderService.update(new LambdaUpdateWrapper<AsnOrder>().in(AsnOrder::getId, param.getIds()).set(AsnOrder::getNtyStatus, 1))) { throw new CoolException("报检状态修改失败!!"); } return R.ok("保存成功!!"); } } rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/TaskServiceImpl.java
@@ -8,6 +8,7 @@ import com.vincent.rsf.framework.exception.CoolException; import com.vincent.rsf.server.api.entity.enums.TaskType; import com.vincent.rsf.server.manager.entity.*; import com.vincent.rsf.server.manager.enums.PakinIOStatus; import com.vincent.rsf.server.manager.mapper.TaskMapper; import com.vincent.rsf.server.manager.service.*; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -67,7 +68,9 @@ } /**获取组拖*/ List<Long> ids = waitPakin.stream().map(WaitPakin::getId).collect(Collectors.toList()); List<WaitPakin> waitPakins = waitPakinService.list(new LambdaQueryWrapper<WaitPakin>().in(WaitPakin::getId, ids)); List<WaitPakin> waitPakins = waitPakinService.list(new LambdaQueryWrapper<WaitPakin>() .in(WaitPakin::getId, ids) .eq(WaitPakin::getIoStatus, Short.parseShort(PakinIOStatus.QLY_ISPT_STAS_DONE.val))); if (waitPakins.isEmpty()) { throw new CoolException("组拖信息不存在!!"); } @@ -118,6 +121,9 @@ } }); waitPakinService.update(new LambdaUpdateWrapper<WaitPakin>() .in(WaitPakin::getId, ids) .set(WaitPakin::getIoStatus, PakinIOStatus.QLY_ISPT_STAS_TASK_EXCE.val)); return R.ok("任务生成完毕!"); } rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/WaitPakinServiceImpl.java
@@ -6,6 +6,7 @@ import com.vincent.rsf.server.manager.controller.params.PakinItem; import com.vincent.rsf.server.manager.controller.params.WaitPakinParam; 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.service.*; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -79,7 +80,7 @@ } pakin.setCode(ruleCode) //状态修改为入库中 .setIoStatus(Short.parseShort("1")) .setIoStatus(Short.parseShort(PakinIOStatus.QLY_ISPT_STAS_DONE.val)) .setAnfme(sum) .setBarcode(waitPakin.getBarcode()); if (!this.save(pakin)) { rsf-server/src/main/java/com/vincent/rsf/server/system/constant/DictTypeCode.java
@@ -49,4 +49,9 @@ */ public final static String DICT_INSPECT_RESULT = "sys_inspect_result"; /** * ASN订单执行状态 */ public final static String DICT_ASN_EXCE_STATUS = "sys_asn_exce_status"; } rsf-server/src/main/resources/application-dev.yml
@@ -12,11 +12,10 @@ matching-strategy: ANT_PATH_MATCHER datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://192.168.4.24:3306/rsf?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai username: root url: jdbc:mysql://47.76.147.249:3306/rsf?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai # username: root # url: jdbc:mysql://localhost:3306/rsf?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai # username: rsf username: rsf password: 34821015 type: com.alibaba.druid.pool.DruidDataSource druid: