物流改写

liweidong
绫Umbrella 3 weeks ago
parent 74b0d1bd27
commit 3d9a31d22d
  1. 9
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/logistics/pojo/entity/OrderBind.java
  2. 258
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/logistics/pojo/entity/PrWorkOrder.java
  3. 242
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/logistics/pojo/entity/PrWorkPlan.java
  4. 19
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/logistics/pojo/entity/Station.java
  5. 42
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/logistics/pojo/entity/StationCenter.java
  6. 7
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/logistics/pojo/vo/BoxbarcodeDetailsVO.java
  7. 4
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/logistics/pojo/vo/BsWorkCenterVO.java
  8. 2
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/logistics/pojo/vo/QuantityLocationVO.java
  9. 3
      blade-service-api/blade-desk-api/src/main/java/org/springblade/desk/logistics/pojo/vo/StationVO.java
  10. 4
      blade-service/blade-desk/src/main/java/org/springblade/desk/dashboard/service/IBsWorkCenterService.java
  11. 21
      blade-service/blade-desk/src/main/java/org/springblade/desk/dashboard/service/impl/BsWorkCenterServiceImpl.java
  12. 1
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/controller/OrderBoxController.java
  13. 41
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/mapper/PrWorkOrderMapper.java
  14. 8
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/mapper/PrWorkOrderMapper.xml
  15. 41
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/mapper/PrWorkPlanMapper.java
  16. 8
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/mapper/PrWorkPlanMapper.xml
  17. 41
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/mapper/StationCenterMapper.java
  18. 8
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/mapper/StationCenterMapper.xml
  19. 4
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/mapper/StationMapper.java
  20. 40
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/mapper/StationMapper.xml
  21. 41
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/IPrWorkOrderService.java
  22. 39
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/IPrWorkPlanService.java
  23. 39
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/IStationCenterService.java
  24. 4
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/IStationService.java
  25. 489
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/IOrderBoxServiceImpl.java
  26. 24
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/OrderBindServiceImpl.java
  27. 51
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/PrWorkOrderServiceImpl.java
  28. 46
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/PrWorkPlanServiceImpl.java
  29. 49
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/StationCenterServiceImpl.java
  30. 6
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/StationServiceImpl.java
  31. 21
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/StorageMonitoringServiceImpl.java
  32. 2
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/TaskExecuteRecordServiceImpl.java

@ -4,6 +4,7 @@ package org.springblade.desk.logistics.pojo.entity;
* @author: liweidong
* @create: 2026-03-03
*/
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@ -79,6 +80,14 @@ public class OrderBind extends BaseEntity {
@Schema(description = "箱条码")
private String boxBarcode;
/**
* 作业中心id
*/
@Schema(description = "作业中心id")
@TableField("WC_ID")
private Long wcID;
@Schema(description = "流程卡号")
private String cardNo;
/**
* 获取状态描述
* @return 状态描述

@ -0,0 +1,258 @@
package org.springblade.desk.logistics.pojo.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springblade.core.mp.base.BaseEntity;
import java.io.Serial;
import java.math.BigDecimal;
import java.util.Date;
/**
* 物流任务实体类
*
* @author: liweidong
* @create: 2026-03-03
*/
@Data
@TableName("PR_WORK_ORDER")
@Schema(description = "车间订单->视图")
@EqualsAndHashCode(callSuper = true)
public class PrWorkOrder extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID主键
*/
@Schema(description = "ID主键")
private Long id;
@Schema(description = "工单ID")
@TableField("WO_ID")
private Long woId;
@Schema(description = "生产订单ID")
@TableField("YO_ID")
private Long yoId;
@Schema(description = "路线卡号")
@TableField("CARD_NO")
private String cardNo;
@Schema(description = "批次号")
@TableField("BATCH_NO")
private String batchNo;
@Schema(description = "工单号")
@TableField("WO_CODE")
private String woCode;
@Schema(description = "生产数量")
@TableField("MAKE_QTY")
private BigDecimal makeQty;
@Schema(description = "计划结束时间")
@TableField("PLAN_END_DATE")
private Date planEndDate;
@Schema(description = "工单计划ID")
@TableField("WP_ID")
private Long wpId;
@Schema(description = "入库数量")
@TableField("INVENTORY_QTY")
private BigDecimal inventoryQty;
@Schema(description = "运行状态")
@TableField("RUN_STATUS")
private Integer runStatus;
@Schema(description = "领料状态")
@TableField("PICKING_STATUS")
private Integer pickingStatus;
@Schema(description = "OEM标识")
@TableField("OEM")
private String oem;
@Schema(description = "优先级")
@TableField("PRIORITY")
private Integer priority;
@Schema(description = "创建时间")
@TableField("CREATE_TIME")
private Date createTime;
@Schema(description = "工单路线ID")
@TableField("WOR_ID")
private Long worId;
@Schema(description = "审批状态")
@TableField("APPROVAL_STATUS")
private Integer approvalStatus;
@Schema(description = "报废数量")
@TableField("SCRAP_QTY")
private BigDecimal scrapQty;
@Schema(description = "外协出库")
@TableField("OEM_OUT")
private String oemOut;
@Schema(description = "外协类型")
@TableField("OEM_TYPE")
private String oemType;
@Schema(description = "返工单号")
@TableField("REWORK_CODE")
private String reworkCode;
@Schema(description = "返工顺序")
@TableField("REWORK_NO")
private Long reworkNo;
@Schema(description = "计划员")
@TableField("PLANNER")
private String planner;
@Schema(description = "调度员")
@TableField("DISPATCHER")
private String dispatcher;
@Schema(description = "打印标识")
@TableField("PRINT_FLAG")
private Integer printFlag;
@Schema(description = "下发时间")
@TableField("SEND_DOWN_TIME")
private Date sendDownTime;
@Schema(description = "打印人")
@TableField("PRINT_MAN")
private String printMan;
@Schema(description = "入库时间")
@TableField("PUT_STORE_TIME")
private Date putStoreTime;
@Schema(description = "返工备注")
@TableField("REWORK_MEMO")
private String reworkMemo;
@Schema(description = "需求日期")
@TableField("DEMAND_DATE")
private Date demandDate;
@Schema(description = "打印时间")
@TableField("PRINT_TIME")
private Date printTime;
@Schema(description = "打印编码")
@TableField("PRINT_CODE")
private String printCode;
@Schema(description = "交接时间")
@TableField("HANDOVER_TIME")
private Date handoverTime;
@Schema(description = "关闭时间")
@TableField("CLOSE_TIME")
private Date closeTime;
@Schema(description = "关闭人")
@TableField("CLOSE_MAN")
private String closeMan;
@Schema(description = "任务单ID")
@TableField("TS_ID")
private Long tsId;
@Schema(description = "OCID")
@TableField("OC_ID")
private Long ocId;
@Schema(description = "检验数量")
@TableField("TEST_QTY")
private BigDecimal testQty;
@Schema(description = "损耗数量")
@TableField("LOSS_QTY")
private BigDecimal lossQty;
@Schema(description = "镀层单定额")
@TableField("PLATE_SINGLE_QUOTA")
private BigDecimal plateSingleQuota;
@Schema(description = "推送标识")
@TableField("PUSH_FLAG")
private Integer pushFlag;
@Schema(description = "镀层物料编码")
@TableField("PLATE_GOODS_CODE")
private String plateGoodsCode;
@Schema(description = "PGRID")
@TableField("PGR_ID")
private Long pgrId;
@Schema(description = "定额异常")
@TableField("QUOTA_EXCEPTIONAL")
private Integer quotaExceptional;
@Schema(description = "MES路线卡号")
@TableField("MES_CARD_NO")
private String mesCardNo;
@Schema(description = "接收时间")
@TableField("RECEPTION_TIME")
private Date receptionTime;
@Schema(description = "出库时间")
@TableField("OUT_TIME")
private Date outTime;
@Schema(description = "协同标识")
@TableField("COLLABORATE")
private String collaborate;
@Schema(description = "最后入库时间")
@TableField("LAST_INSTORE_TIME")
private Date lastInstoreTime;
@Schema(description = "满足周期")
@TableField("MEET_CYCLE")
private BigDecimal meetCycle;
@Schema(description = "备注")
@TableField("MEMO")
private String memo;
@Schema(description = "排产状态")
@TableField("SCHED_STATUS")
private Integer schedStatus;
@Schema(description = "读取状态")
@TableField("READ_STATUS")
private Integer readStatus;
@Schema(description = "质检返工单号")
@TableField("QC_REWORK_CODE")
private String qcReworkCode;
@Schema(description = "旧运行状态")
@TableField("OLD_RUN_STATUS")
private Integer oldRunStatus;
@Schema(description = "重新入库")
@TableField("RE_IN_STORE")
private Integer reInStore;
@Schema(description = "计划开始时间")
@TableField("PLAN_START_DATE")
private Date planStartDate;
}

@ -0,0 +1,242 @@
package org.springblade.desk.logistics.pojo.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springblade.core.mp.base.BaseEntity;
import java.io.Serial;
import java.math.BigDecimal;
import java.util.Date;
/**
* 物流任务实体类
*
* @author: liweidong
* @create: 2026-03-03
*/
@Data
@TableName("PR_WORK_PLAN")
@Schema(description = "车间订单序号->视图")
@EqualsAndHashCode(callSuper = true)
public class PrWorkPlan extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID主键
*/
@Schema(description = "ID主键")
private Long id;
@Schema(description = "工单计划ID")
@TableField("WP_ID")
private Long wpId;
@Schema(description = "工序计划ID")
@TableField("WPP_ID")
private Long wppId;
@Schema(description = "产品ID")
@TableField("PID")
private Long pid;
@Schema(description = "排序")
@TableField("ORDERS")
private Integer orders;
@Schema(description = "是否需要检验")
@TableField("NEED_CHECK")
private Integer needCheck;
@Schema(description = "准备工时")
@TableField("PREPARE_HOUR")
private BigDecimal prepareHour;
@Schema(description = "加工工时")
@TableField("MAKE_HOUR")
private BigDecimal makeHour;
@Schema(description = "面积数量")
@TableField("AREA_QUANTITY")
private BigDecimal areaQuantity;
@Schema(description = "加工备注")
@TableField("MAKE_MEMO")
private String makeMemo;
@Schema(description = "报工工时")
@TableField("PS_HOUR")
private BigDecimal psHour;
@Schema(description = "设备ID")
@TableField("MAC_ID")
private Long macId;
@Schema(description = "外协标识")
@TableField("OEM")
private String oem;
@Schema(description = "计划开始时间")
@TableField("START_TIME")
private Date startTime;
@Schema(description = "计划结束时间")
@TableField("END_TIME")
private Date endTime;
@Schema(description = "实际开始时间")
@TableField("FACT_START_TIME")
private Date factStartTime;
@Schema(description = "实际结束时间")
@TableField("FACT_END_TIME")
private Date factEndTime;
@Schema(description = "效率")
@TableField("RATE")
private BigDecimal rate;
@Schema(description = "当前状态")
@TableField("CUR_STATUS")
private Integer curStatus;
@Schema(description = "是否锁定")
@TableField("LOCKED")
private Integer locked;
@Schema(description = "外协工单ID")
@TableField("OT_ID")
private Long otId;
@Schema(description = "报工设备")
@TableField("REC_MAC")
private String recMac;
@Schema(description = "报工时间")
@TableField("REC_TIME")
private Date recTime;
@Schema(description = "报工人")
@TableField("REC_MAN")
private String recMan;
@Schema(description = "报工状态")
@TableField("REC_STATUS")
private Integer recStatus;
@Schema(description = "报工排序")
@TableField("REC_ORDERS")
private Integer recOrders;
@Schema(description = "下单时间")
@TableField("ORDER_TIME")
private Date orderTime;
@Schema(description = "备注")
@TableField("MEMO")
private String memo;
@Schema(description = "单位工时")
@TableField("UNIT_HOUR")
private BigDecimal unitHour;
@Schema(description = "报工输出")
@TableField("REC_OUT")
private String recOut;
@Schema(description = "预览工单ID")
@TableField("PREVIEW_WP_ID")
private Long previewWpId;
@Schema(description = "下一个工单ID")
@TableField("NEXT_WP_ID")
private Long nextWpId;
@Schema(description = "计划工时")
@TableField("PLAN_TIME")
private BigDecimal planTime;
@Schema(description = "子项物料号")
@TableField("SUB_PI_NO")
private String subPiNo;
@Schema(description = "外协状态")
@TableField("OEM_STATUS")
private Integer oemStatus;
@Schema(description = "来源")
@TableField("COME_FROM")
private String comeFrom;
@Schema(description = "工作中心ID")
@TableField("WC_ID")
private Long wcId;
@Schema(description = "物料编号")
@TableField("PI_NO")
private String piNo;
@Schema(description = "创建时间")
@TableField("CREATE_TIME")
private Date createTime;
@Schema(description = "更新时间")
@TableField("UPDATE_TIME")
private Date updateTime;
@Schema(description = "旧状态")
@TableField("OLD_STATUS")
private Integer oldStatus;
@Schema(description = "检验工序")
@TableField("CHECK_PROCESS")
private Integer checkProcess;
@Schema(description = "超交数量")
@TableField("OVER_QUANTITY")
private BigDecimal overQuantity;
@Schema(description = "TOOL库工序计划ID")
@TableField("TOOL_WPP_ID")
private Long toolWppId;
@Schema(description = "实际报工工时")
@TableField("ACTURAL_PS_HOUR")
private BigDecimal acturalPsHour;
@Schema(description = "退回原因")
@TableField("BACK_REASON")
private String backReason;
@Schema(description = "是否跳过")
@TableField("SKIP")
private Integer skip;
@Schema(description = "待排标识")
@TableField("WAITING_FLAG")
private Integer waitingFlag;
@Schema(description = "待排操作人")
@TableField("WAITING_FLAG_MAN")
private String waitingFlagMan;
@Schema(description = "调整排产人")
@TableField("ADJUST_SCHEDULE_MAN")
private String adjustScheduleMan;
@Schema(description = "调整排产时间")
@TableField("ADJUST_SCHEDULE_DATE")
private Date adjustScheduleDate;
@Schema(description = "自动生产标识")
@TableField("AUTO_PRODUCTION")
private Integer autoProduction;
@Schema(description = "设备面")
@TableField("MAC_SURFACE")
private String macSurface;
}

@ -38,9 +38,14 @@ public class Station extends BaseEntity {
public static final Integer PRE_STATUS_OCCUPIED = 2;
/**
* 状态常量收发-只收
* 状态常量输送线发起
*/
public static final Integer RECEIVE_ONLY = 0;
public static final Integer CONVEYOR_LINE_RECEIVE_ONLY = 0;
/**
* 状态常量站点发起
*/
public static final Integer STATION_RECEIVE_ONLY = 1;
/**
* 状态常量收发-同层
*/
@ -93,11 +98,11 @@ public class Station extends BaseEntity {
*/
@Schema(description = "备注")
private String remark;
/**
* 作业中心ID
*/
@Schema(description = "作业中心ID")
private Long wcId;
// /**
// * 作业中心ID
// */
// @Schema(description = "作业中心ID")
// private Long wcId;
/**
* 站点区域
*/

@ -0,0 +1,42 @@
package org.springblade.desk.logistics.pojo.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springblade.core.mp.base.BaseEntity;
import java.io.Serial;
/**
* 物流站点作业中心绑定实体类
* @author: liweidong
* @create: 2026-03-03
*/
@Data
@TableName("LM_STATION_CENTER")
@Schema(description = "物流站点与作业中心绑定对象")
@EqualsAndHashCode(callSuper = true)
public class StationCenter extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID主键
*/
@Schema(description = "ID主键")
private Long id;
/**
* 作业中心ID
*/
@Schema(description = "作业中心ID")
private Long wcId;
/**
* 站点位置id
*/
@Schema(description = "站点位置")
private Long stationId;
}

@ -44,6 +44,13 @@ public class BoxbarcodeDetailsVO implements Serializable {
*/
@Schema(description = "订单详情数据")
private List<YieldOrder> yieldOrderList;
/**
* 作业中心
*/
@Schema(description = "作业中心名称")
private String wcName;
@Schema(description = "区域名字")
private String stationRegion;

@ -3,10 +3,14 @@ package org.springblade.desk.logistics.pojo.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
@Schema(description = "wslist返回对象")
public class BsWorkCenterVO {
private Long id;
private String wcName;
private List<String> stationRegionList;
}

@ -35,6 +35,8 @@ public class QuantityLocationVO implements Serializable {
*/
@Schema(description = "作业中心名字")
private String wcName;
@Schema(description = "区域名字")
private String stationRegion;

@ -16,5 +16,6 @@ public class StationVO extends Station {
*/
@Schema(description = "作业中心名称")
private String wcName;
@Schema(description = "作业中心id")
private Long wcId;
}

@ -31,6 +31,8 @@ import org.springblade.desk.dashboard.pojo.vo.BsWorkCenterVO;
import org.springblade.desk.dashboard.excel.BsWorkCenterExcel;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.core.mp.base.BaseService;
import org.springblade.desk.logistics.pojo.vo.StationVO;
import java.util.List;
/**
@ -71,5 +73,5 @@ public interface IBsWorkCenterService extends BaseService<BsWorkCenterEntity> {
*/
BsWorkCenterEntity selectBsWorkCenterByWcCode(String wcCode);
List<org.springblade.desk.logistics.pojo.vo.BsWorkCenterVO> getByIds(List<Long> list);
List<org.springblade.desk.logistics.pojo.vo.BsWorkCenterVO> getByIds(List<Long> list, List<StationVO> freeStationList);
}

@ -30,12 +30,14 @@ import org.springblade.desk.dashboard.pojo.vo.BsWorkCenterVO;
import org.springblade.desk.dashboard.excel.BsWorkCenterExcel;
import org.springblade.desk.dashboard.mapper.BsWorkCenterMapper;
import org.springblade.desk.dashboard.service.IBsWorkCenterService;
import org.springblade.desk.logistics.pojo.vo.StationVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.core.mp.base.BaseServiceImpl;
import java.util.List;
import java.util.stream.Collectors;
/**
* 工作中心表 服务实现类
@ -75,8 +77,23 @@ public class BsWorkCenterServiceImpl extends BaseServiceImpl<BsWorkCenterMapper,
}
@Override
public List<org.springblade.desk.logistics.pojo.vo.BsWorkCenterVO> getByIds(List<Long> list) {
return workCenterMapper.selectByIds(list);
public List<org.springblade.desk.logistics.pojo.vo.BsWorkCenterVO> getByIds(List<Long> list, List<StationVO> freeStationList) {
List<org.springblade.desk.logistics.pojo.vo.BsWorkCenterVO> bsWorkCenterVOList = workCenterMapper.selectByIds(list);
for (org.springblade.desk.logistics.pojo.vo.BsWorkCenterVO bsWorkCenterVO : bsWorkCenterVOList) {
Long id = bsWorkCenterVO.getId();
List<String> result = freeStationList.stream()
// 1. 过滤:只保留【指定字段 == 指定值】的数据(值一致才保留)
.filter(item -> item.getWcId()==id)
// 2. 提取你要的字段
.map(StationVO::getStationRegion)
// 3. 自动去重
.distinct()
// 4. 转成集合返回
.collect(Collectors.toList());
bsWorkCenterVO.setStationRegionList(result);
}
return bsWorkCenterVOList;
}
}

@ -83,6 +83,7 @@ public class OrderBoxController extends BladeController {
return iOrderBoxService.returnToWarehouseList();
}
@PostMapping("/box-binding")
@ApiOperationSupport(order = 3)
@Operation(

@ -0,0 +1,41 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.desk.logistics.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springblade.desk.logistics.pojo.entity.PrWorkOrder;
import org.springblade.desk.logistics.pojo.entity.WeighData;
/**
* 任务分派表 Mapper 接口
*
* @author BladeX
* @since 2025-11-12
*/
public interface PrWorkOrderMapper extends BaseMapper<PrWorkOrder> {
}

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace = "org.springblade.desk.logistics.mapper.PrWorkOrderMapper">
</mapper>

@ -0,0 +1,41 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.desk.logistics.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springblade.desk.logistics.pojo.entity.PrWorkOrder;
import org.springblade.desk.logistics.pojo.entity.PrWorkPlan;
/**
* 任务分派表 Mapper 接口
*
* @author BladeX
* @since 2025-11-12
*/
public interface PrWorkPlanMapper extends BaseMapper<PrWorkPlan> {
}

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace = "org.springblade.desk.logistics.mapper.PrWorkPlanMapper">
</mapper>

@ -0,0 +1,41 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.desk.logistics.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springblade.desk.logistics.pojo.entity.PrWorkOrder;
import org.springblade.desk.logistics.pojo.entity.StationCenter;
/**
* 任务分派表 Mapper 接口
*
* @author BladeX
* @since 2025-11-12
*/
public interface StationCenterMapper extends BaseMapper<StationCenter> {
}

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace = "org.springblade.desk.logistics.mapper.StationCenterMapper">
</mapper>

@ -3,8 +3,6 @@ package org.springblade.desk.logistics.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.ibatis.annotations.Param;
import org.springblade.desk.dashboard.pojo.vo.DsTaskingVO;
import org.springblade.desk.logistics.pojo.entity.OrderBind;
import org.springblade.desk.logistics.pojo.entity.Station;
import org.springblade.desk.logistics.pojo.vo.StationVO;
@ -17,4 +15,6 @@ public interface StationMapper extends BaseMapper<Station> {
Station selectByStationCode(@Param("StationCode") String StationCode);
List<StationVO> selectStationList(IPage<StationVO> page, @Param("station") Station station);
List<StationVO> getStatusStationList(@Param("stationStatus")Integer stationStatus, @Param("wcId")Long wcId,@Param("status")Integer status, @Param("include")boolean include);
}

@ -16,22 +16,48 @@
</select>
<select id="selectStationList" resultType="org.springblade.desk.logistics.pojo.vo.StationVO">
select id, station_name, station_code, station_status, status, create_user, create_time, create_dept, update_user, update_time, is_deleted, remark, station_position, wc_id
from LM_STATION where IS_DELETED = 0
select l.id, l.station_name, l.station_code, l.station_status, l.status, l.create_user, l.create_time, l.create_dept, l.update_user, l.update_time, l.is_deleted, l.remark, l.station_position, r.WC_ID as wcId
from LM_STATION l left join LM_STATION_CENTER r on l.id = r.STATION_ID
where l.IS_DELETED = 0
<if test="station.stationName != null and station.stationName != ''">
and STATION_NAME = #{station.stationName}
and l.STATION_NAME = #{station.stationName}
</if>
<if test="station.stationCode != null and station.stationCode != ''">
and STATION_CODE = #{station.stationCode}
and l.STATION_CODE = #{station.stationCode}
</if>
<if test="station.stationStatus != null and station.stationStatus != ''">
and STATION_STATUS = #{station.stationStatus}
and l.STATION_STATUS = #{station.stationStatus}
</if>
<if test="station.stationPosition != null and station.stationPosition != ''">
and STATION_POSITION = #{station.stationPosition}
and l.STATION_POSITION = #{station.stationPosition}
</if>
<if test="station.wcId != null and station.wcId != ''">
and WC_ID = #{station.wcId}
and r.WC_ID = #{station.wcId}
</if>
</select>
<select id="getStatusStationList" resultType="org.springblade.desk.logistics.pojo.vo.StationVO">
select l.*, r.WC_ID as wcId
from LM_STATION l
left join LM_STATION_CENTER r on l.id = r.STATION_ID
where l.IS_DELETED = 0
<if test="stationStatus != null and stationStatus != ''">
and l.STATION_STATUS = #{stationStatus}
</if>
<if test="wcId != null and wcId != ''">
and r.WC_ID = #{wcId}
</if>
<!-- 修正:不等于语法错误 + 格式规范 -->
<if test="status != null and status != ''">
<if test="include">
and l.STATUS = #{status}
</if>
<if test="!include">
and l.STATUS != #{status}
</if>
</if>
</select>
</mapper>

@ -0,0 +1,41 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.desk.logistics.service;
import org.springblade.core.mp.base.BaseService;
import org.springblade.desk.logistics.pojo.entity.PrWorkOrder;
import org.springblade.desk.logistics.pojo.entity.WeighData;
import java.math.BigDecimal;
/**
* 车间订单 服务类
*
* @author BladeX
* @since 2025-11-12
*/
public interface IPrWorkOrderService extends BaseService<PrWorkOrder> {
}

@ -0,0 +1,39 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.desk.logistics.service;
import org.springblade.core.mp.base.BaseService;
import org.springblade.desk.logistics.pojo.entity.PrWorkOrder;
import org.springblade.desk.logistics.pojo.entity.PrWorkPlan;
/**
* 车间订单序号 服务类
*
* @author BladeX
* @since 2025-11-12
*/
public interface IPrWorkPlanService extends BaseService<PrWorkPlan> {
}

@ -0,0 +1,39 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.desk.logistics.service;
import org.springblade.core.mp.base.BaseService;
import org.springblade.desk.logistics.pojo.entity.PrWorkOrder;
import org.springblade.desk.logistics.pojo.entity.StationCenter;
/**
* 车间订单 服务类
*
* @author BladeX
* @since 2025-11-12
*/
public interface IStationCenterService extends BaseService<StationCenter> {
}

@ -28,8 +28,6 @@ package org.springblade.desk.logistics.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.core.mp.base.BaseService;
import org.springblade.core.tool.api.R;
import org.springblade.desk.dashboard.pojo.vo.DsTaskingVO;
import org.springblade.desk.logistics.pojo.entity.Location;
import org.springblade.desk.logistics.pojo.entity.Station;
import org.springblade.desk.logistics.pojo.vo.StationVO;
@ -73,4 +71,6 @@ public interface IStationService extends BaseService<Station> {
* @return
*/
boolean updateStation(Station station);
List<StationVO> getStatusStationList(Integer stationStatus, Long wcId,Integer status, boolean include);
}

@ -7,6 +7,7 @@ import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springblade.common.exception.BusinessException;
import org.springblade.core.secure.utils.AuthUtil;
@ -16,14 +17,15 @@ import org.springblade.desk.dashboard.service.IBsWorkCenterService;
import org.springblade.desk.logistics.pojo.dto.BoxBindingDto;
import org.springblade.desk.logistics.pojo.dto.ReturnToWarehouseDto;
import org.springblade.desk.logistics.pojo.entity.*;
import org.springblade.desk.logistics.pojo.vo.BoxbarcodeDetailsVO;
import org.springblade.desk.logistics.pojo.vo.BsWorkCenterVO;
import org.springblade.desk.logistics.pojo.vo.QuantityLocationVO;
import org.springblade.desk.logistics.pojo.vo.StationNameBoxBarcodeVO;
import org.springblade.desk.logistics.pojo.vo.*;
import org.springblade.desk.logistics.service.*;
import org.springblade.desk.logistics.utils.AgvTaskTypeUtil;
import org.springblade.desk.order.pojo.entity.YieldOrder;
import org.springblade.desk.order.service.IYieldOrderService;
import org.springblade.desk.produce.pojo.entity.WorkOrder;
import org.springblade.desk.produce.pojo.entity.WorkPlan;
import org.springblade.desk.produce.service.IWorkOrderService;
import org.springblade.desk.produce.service.IWorkPlanService;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
@ -116,6 +118,12 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
* 任务执行记录服务处理AGV调度任务的生成与执行
*/
private final ITaskExecuteRecordService taskExecuteRecordService;
private final IWorkOrderService workOrderService;
private final IWorkPlanService workPlanService;
private final IPrWorkPlanService prWorkPlanService;
private final IPrWorkOrderService prWorkOrderService;
private final IStationCenterService stationCenterService;
// ========================== 构造器注入 ==========================
@ -138,7 +146,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
ILocationService locationService,
AgvTaskTypeUtil agvTaskTypeUtil,
IBsWorkCenterService bsWorkCenterService,
ITaskExecuteRecordService taskExecuteRecordService) {
ITaskExecuteRecordService taskExecuteRecordService, IWorkOrderService workOrderService, IWorkPlanService workPlanService, IPrWorkPlanService prWorkPlanService, IPrWorkOrderService prWorkOrderService, IStationCenterService stationCenterService) {
this.yieldOrderService = yieldOrderService;
this.taskService = taskService;
this.orderBindService = orderBindService;
@ -147,6 +155,11 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
this.agvTaskTypeUtil = agvTaskTypeUtil;
this.bsWorkCenterService = bsWorkCenterService;
this.taskExecuteRecordService = taskExecuteRecordService;
this.workOrderService = workOrderService;
this.workPlanService = workPlanService;
this.prWorkPlanService = prWorkPlanService;
this.prWorkOrderService = prWorkOrderService;
this.stationCenterService = stationCenterService;
}
// ========================== 核心业务方法 ==========================
@ -214,53 +227,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
* <li>失败R.fail() - 携带具体失败原因参数为空/订单已绑定/重量超限等</li>
* </ul>
*/
@Override
public R<?> boxBinding(BoxBindingDto boxBinding) {
log.info("【箱条码绑定】开始处理 - 绑定参数:{}", boxBinding);
// 1. 基础参数校验
R<?> paramCheckResult = validateBoxBindingParams(boxBinding);
if (!paramCheckResult.isSuccess()) {
return paramCheckResult;
}
String boxBarcode = boxBinding.getBoxBarcode();
List<String> orderCardNoList = boxBinding.getOrderIdList();
// 2. 订单有效性校验
R<?> orderValidResult = validateOrderExist(orderCardNoList);
if (!orderValidResult.isSuccess()) {
return orderValidResult;
}
List<YieldOrder> yieldOrderList = (List<YieldOrder>) orderValidResult.getData();
List<Long> orderIdList = yieldOrderList.stream()
.map(YieldOrder::getId)
.collect(Collectors.toList());
// 3. 校验箱条码是否存在运行中任务
R<?> boxTaskCheckResult = checkBoxBarcodeRunningTask(boxBarcode);
if (!boxTaskCheckResult.isSuccess()) {
return boxTaskCheckResult;
}
// 4. 校验订单是否已绑定
R<?> orderBindCheckResult = checkOrderIdBoundStatus(orderIdList);
if (!orderBindCheckResult.isSuccess()) {
return orderBindCheckResult;
}
// 5. 订单重量校验(超限则拒绝绑定)
BigDecimal totalWeight = calculateOrderTotalWeight(orderIdList);
if (totalWeight.compareTo(MAX_BOX_WEIGHT_THRESHOLD) > 0) {
String errorMsg = String.format("箱条码%s绑定的订单总重量%.2fkg,超过最大阈值%.2fkg",
boxBarcode, totalWeight, MAX_BOX_WEIGHT_THRESHOLD);
log.warn("【箱条码绑定】{}", errorMsg);
return R.fail(errorMsg + ",请重新进行绑定");
}
// 6.
// 6. 保存绑定关系
return saveOrderBoxBinding(boxBarcode, new ArrayList<>(orderIdList));
}
/**
* 查询回库可选工位列表
@ -273,10 +240,8 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
log.info("【回库工位查询】开始查询空闲站点关联工位");
// 1. 查询空闲状态的站点
List<Station> freeStationList = stationService.list(
new LambdaQueryWrapper<Station>().eq(Station::getStationStatus, STATUS_FREE)
);
List<StationVO> freeStationList = stationService.getStatusStationList(STATUS_FREE, null,CONVEYOR_LINE_RECEIVE_ONLY,false);
// 2. 构建返回列表(默认添加输送线回库选项)
List<BsWorkCenterVO> resultList = new ArrayList<>();
BsWorkCenterVO conveyorVO = new BsWorkCenterVO();
@ -287,10 +252,10 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
// 3. 补充空闲站点关联的工位信息
if (!CollectionUtils.isEmpty(freeStationList)) {
List<Long> wcIdList = freeStationList.stream()
.map(Station::getWcId)
.map( StationVO::getWcId)
.distinct()
.collect(Collectors.toList());
List<BsWorkCenterVO> wcVOList = bsWorkCenterService.getByIds(wcIdList);
List<BsWorkCenterVO> wcVOList = bsWorkCenterService.getByIds(wcIdList,freeStationList);
if (!CollectionUtils.isEmpty(wcVOList)) {
resultList.addAll(wcVOList);
log.info("【回库工位查询】查询到{}个空闲工位", wcVOList.size());
@ -383,7 +348,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
Task task = new Task();
// 3. 处理起始站点编码
R<?> startStationResult = handleStartStationCode(returnToWarehouseDto);
R<?> startStationResult = handleStartStationCode(returnToWarehouseDto,agvSend);
if (!startStationResult.isSuccess()) {
return startStationResult;
}
@ -414,7 +379,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
endStationCode = DROPOFF_CONVEYOR_LINE;
} else {
// 5.2 普通工位回库:分配站点/库位
R<?> locationResult = allocateSiteOrLocation(startStationCode, task);
R<?> locationResult = allocateSiteOrLocation(startStationCode, task,agvSend);
if (!locationResult.isSuccess()) {
return locationResult;
}
@ -484,11 +449,11 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
}
// 3. 查询工位ID
Long orderId = orderBindList.get(0).getOrderId();
Long wcId = yieldOrderService.getWcId(orderId);
log.info("【工位ID查询】箱条码{}对应的工位ID:{}", boxBarcode, wcId);
// Long orderId = orderBindList.get(0).getOrderId();
// Long wcId = yieldOrderService.getWcId(orderId);
// log.info("【工位ID查询】箱条码{}对应的工位ID:{}", boxBarcode, wcId);
return R.data(wcId);
return R.data(orderBindList.get(0).getWcID());
}
@ -570,6 +535,26 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
/**
* 计算订单列表总重量
* <p>累加订单的实际称重值过滤null值初始值为0</p>
*
* @param cardNoList 订单ID列表
* @return BigDecimal 订单总重量单位千克
*/
private BigDecimal calculateOrderCardNoTotalWeight(List<String> cardNoList) {
log.info("【订单重量计算】开始计算订单ID列表{}的总重量", cardNoList);
List<YieldOrder> orderList = yieldOrderService.list(
new LambdaQueryWrapper<YieldOrder>().in(YieldOrder::getCardNo, cardNoList)
);
log.info("【订单重量计算】查询到订单列表:{}", orderList);
return orderList.stream()
.map(YieldOrder::getActualWeighing)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
/**
* 保存订单与箱条码的绑定关系
@ -578,7 +563,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
* @param orderIdList 订单ID列表
* @return R<?> 保存结果
*/
private R<?> saveOrderBoxBinding(String boxBarcode, ArrayList<Long> orderIdList) {
private R<?> saveOrderBoxBinding(String boxBarcode, ArrayList<String> orderIdList,Long wcId) {
if (CollectionUtils.isEmpty(orderIdList)) {
return R.fail("订单id不能为空");
}
@ -589,7 +574,8 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
OrderBind bind = new OrderBind();
bind.setBindingStatus(OrderBind.STATUS_BOUND);
bind.setBoxBarcode(boxBarcode);
bind.setOrderId(orderId);
bind.setCardNo(orderId);
bind.setWcID(wcId);
return bind;
})
.collect(Collectors.toList());
@ -611,7 +597,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
* @param dto 回库任务参数DTO
* @return R<String> 处理后的起始站点编码
*/
private R<?> handleStartStationCode(ReturnToWarehouseDto dto) {
private R<?> handleStartStationCode(ReturnToWarehouseDto dto, Boolean agvSend) {
String startStationCode = dto.getStartStationCode();
if (Objects.nonNull(startStationCode) && !startStationCode.isBlank()) {
// 校验站点是否存在
@ -627,7 +613,9 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
}
log.info(String.valueOf(stationList.get(0)));
// 校验站点是否可以发送数据
if (stationList.get(0).getStatus().equals(RECEIVE_ONLY)) {
if (stationList.get(0).getStatus().equals(CONVEYOR_LINE_RECEIVE_ONLY)&&agvSend) {
return R.fail("起始站点站码无法当开始站点编码");
}else if (!stationList.get(0).getStatus().equals(CONVEYOR_LINE_RECEIVE_ONLY)&&!agvSend) {
return R.fail("起始站点站码无法当开始站点编码");
}
return R.data(startStationCode);
@ -683,31 +671,26 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
*
* @param startStationCode
* @param task 任务对象含工位ID
* @param agvSend
* @return R<Task> 分配后的任务对象
*/
private R<Task> allocateSiteOrLocation(String startStationCode, Task task) {
private R<Task> allocateSiteOrLocation(String startStationCode, Task task, Boolean agvSend) {
// 1. 尝试分配空闲站点
List<Station> freeStationList = stationService.list(
new LambdaQueryWrapper<Station>()
.eq(Station::getWcId, task.getWcId())
.eq(Station::getStationStatus, STATUS_FREE)
);
// List<Station> freeStationList = stationService.list(
// new LambdaQueryWrapper<Station>()
// .eq(Station::getWcId, task.getWcId())
// .eq(Station::getStationStatus, STATUS_FREE)
// );
List<StationVO> freeStationList =null;
if (agvSend) {
freeStationList=stationService.getStatusStationList(STATUS_FREE, task.getWcId(), CONVEYOR_LINE_RECEIVE_ONLY, false);
}else {
freeStationList=stationService.getStatusStationList(STATUS_FREE, task.getWcId(), STATION_RECEIVE_ONLY, false);
}
if (!CollectionUtils.isEmpty(freeStationList)) {
Station station = null;
String stationPosition = "";
StationVO station = null;
station = freeStationList.get(0);
if (station.getStatus() == SAME_LAYER) {
station = null;
Station startStation = stationService.list(new LambdaQueryWrapper<Station>().eq(Station::getStationCode, startStationCode)).get(0);
stationPosition = startStation.getStationPosition();
station = findByField(freeStationList, "stationPosition", stationPosition);
}
if (station == null) {
return R.fail("当前班次" + stationPosition + "楼层库位繁忙,请空闲后再试");
}
task.setStationId(station.getId());
// 锁定站点(预占用)
station.setStationStatus(PRE_STATUS_OCCUPIED);
@ -815,12 +798,18 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
log.info("【任务重量计算】箱{}绑定订单列表:{}", boxBarcode, bindList);
if (!CollectionUtils.isEmpty(bindList)) {
List<Long> orderIdList = bindList.stream()
// List<Long> orderIdList = bindList.stream()
// .filter(Objects::nonNull)
// .map(OrderBind::getOrderId)
// .filter(Objects::nonNull)
// .collect(Collectors.toList());
// taskWeight = calculateOrderTotalWeight(orderIdList);
List<String> cardNoList = bindList.stream()
.filter(Objects::nonNull)
.map(OrderBind::getOrderId)
.map(OrderBind::getCardNo)
.filter(Objects::nonNull)
.collect(Collectors.toList());
taskWeight = calculateOrderTotalWeight(orderIdList);
taskWeight = calculateOrderCardNoTotalWeight(cardNoList);
}
}
task.setWeight(taskWeight);
@ -905,17 +894,17 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
* 校验订单是否已绑定
* <p>避免同一订单被重复绑定到不同箱条码</p>
*
* @param orderIdList 订单ID列表
* @param cardNo 订单ID列表
* @return R<?> 校验结果
*/
private R<?> checkOrderIdBoundStatus(List<Long> orderIdList) {
if (CollectionUtils.isEmpty(orderIdList)) {
private R<?> checkOrderIdBoundStatus(List<String> cardNoList) {
if (CollectionUtils.isEmpty(cardNoList)) {
return R.success();
}
// 查询订单绑定记录
List<OrderBind> bindList = orderBindService.list(
new LambdaQueryWrapper<OrderBind>().in(OrderBind::getOrderId, orderIdList)
new LambdaQueryWrapper<OrderBind>().in(OrderBind::getCardNo, cardNoList)
);
if (CollectionUtils.isEmpty(bindList)) {
return R.success();
@ -972,18 +961,17 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
quantityLocationVO.setBoxBarcode(boxBarcode.trim());
quantityLocationVO.setQuantity((long) orderBindList.size()); // Long类型可直接自动装箱,无需强制转换
// 4. 查询作业中心信息(增加wcId空值校验,避免NPE)
Long wcId = yieldOrderService.getWcId(firstOrderBind.getOrderId());
if (wcId == null) {
return R.fail("订单未关联作业中心");
}
BsWorkCenterEntity workCenter = bsWorkCenterService.getById(wcId);
BsWorkCenterEntity workCenter = bsWorkCenterService.getById(firstOrderBind.getWcID());
if (workCenter == null) {
return R.fail("订单所属作业中心异常");
}
quantityLocationVO.setWcName(workCenter.getWcName());
List<StationCenter> stationCenterList = stationCenterService.list(new LambdaQueryWrapper<StationCenter>().eq(StationCenter::getWcId, firstOrderBind.getWcID()));
if (stationCenterList==null||stationCenterList.size()==0) {
return R.fail("获取站点区域有问题");
}
List<Station> stationList = stationService.list(new LambdaQueryWrapper<Station>().eq(Station::getId, stationCenterList.get(0).getStationId()));
quantityLocationVO.setStationRegion(stationList.get(0).getStationRegion());
return R.data(quantityLocationVO);
}
@Override
@ -991,28 +979,67 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
if (StringUtils.isBlank(boxBarcode)) {
return R.fail("箱条码不能为空");
}
List<OrderBind> orderBindList = orderBindService.list(new LambdaQueryWrapper<OrderBind>().eq(OrderBind::getBoxBarcode, boxBarcode).eq(OrderBind::getBindingStatus, OrderBind.STATUS_BOUND));
if (orderBindList==null||orderBindList.size()==0) {
BoxbarcodeDetailsVO boxbarcodeDetailsVO = new BoxbarcodeDetailsVO();
boxbarcodeDetailsVO.setBoxBarcode(boxBarcode);
boxbarcodeDetailsVO.setWeight(new BigDecimal(0));
boxbarcodeDetailsVO.setQuantity(0L);
return R.data(boxbarcodeDetailsVO);
// 查询已绑定的订单绑定记录
List<OrderBind> orderBindList = orderBindService.list(
Wrappers.lambdaQuery(OrderBind.class)
.eq(OrderBind::getBoxBarcode, boxBarcode)
.eq(OrderBind::getBindingStatus, OrderBind.STATUS_BOUND)
);
// 无绑定记录直接返回默认值
if (CollectionUtils.isEmpty(orderBindList)) {
BoxbarcodeDetailsVO defaultVO = new BoxbarcodeDetailsVO();
defaultVO.setBoxBarcode(boxBarcode);
defaultVO.setWeight(BigDecimal.ZERO);
defaultVO.setQuantity(0L);
return R.data(defaultVO);
}
List<Long> orderIdList = orderBindList.stream()
.map(OrderBind::getOrderId)
// 提取公共变量 wcId 为 Long 类型
OrderBind firstBind = orderBindList.get(0);
Long wcId = firstBind.getWcID();
// 提取卡号集合
List<String> cardNoList = orderBindList.stream()
.map(OrderBind::getCardNo)
.collect(Collectors.toList());
BigDecimal totalWeight = calculateOrderTotalWeight(orderIdList);
// 计算总重量 & 查询订单列表
BigDecimal totalWeight = calculateOrderCardNoTotalWeight(cardNoList);
List<YieldOrder> orderList = yieldOrderService.list(
new LambdaQueryWrapper<YieldOrder>().in(YieldOrder::getId, orderIdList)
Wrappers.lambdaQuery(YieldOrder.class)
.in(YieldOrder::getCardNo, cardNoList)
);
// 组装返回对象
BoxbarcodeDetailsVO detailsVO = new BoxbarcodeDetailsVO();
detailsVO.setBoxBarcode(boxBarcode);
detailsVO.setWeight(totalWeight);
detailsVO.setQuantity((long) orderList.size());
detailsVO.setYieldOrderList(orderList);
// ===================== 关键修复:无 Lambda、无报红、空安全 =====================
// 设置工作中心
BsWorkCenterEntity workCenter = bsWorkCenterService.getById(wcId);
if (workCenter != null) {
detailsVO.setWcName(workCenter.getWcName());
}
// 设置工位区域
List<StationCenter> stationCenterList = stationCenterService.list(
new LambdaQueryWrapper<StationCenter>().eq(StationCenter::getWcId, wcId)
);
BoxbarcodeDetailsVO boxbarcodeDetailsVO = new BoxbarcodeDetailsVO();
boxbarcodeDetailsVO.setBoxBarcode(boxBarcode);
boxbarcodeDetailsVO.setWeight(totalWeight);
boxbarcodeDetailsVO.setQuantity((long) orderList.size());
boxbarcodeDetailsVO.setYieldOrderList(orderList);
return R.data(boxbarcodeDetailsVO);
if (stationCenterList!=null||stationCenterList.size()!=0) {
StationCenter stationCenter = stationCenterList.get(0);
Station station = stationService.getById(stationCenter.getStationId());
if (station != null) {
detailsVO.setStationRegion(station.getStationRegion());
}
}
return R.data(detailsVO);
}
@Override
@ -1036,4 +1063,232 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
stationNameBoxBarcodeVO.setBoxbarcodeDetailsVO((BoxbarcodeDetailsVO) boxbarcodeDetailsR.getData());
return R.data(stationNameBoxBarcodeVO);
}
// public R<?> boxBinding1(BoxBindingDto boxBinding) {
// log.info("【箱条码绑定】开始处理 - 绑定参数:{}", boxBinding);
//
// // 1. 基础参数校验
// R<?> paramCheckResult = validateBoxBindingParams(boxBinding);
// if (!paramCheckResult.isSuccess()) {
// return paramCheckResult;
// }
// String boxBarcode = boxBinding.getBoxBarcode();
// List<String> orderCardNoList = boxBinding.getOrderIdList();
//
// // 2. 订单有效性校验
// R<?> orderValidResult = validateOrderExist(orderCardNoList);
// if (!orderValidResult.isSuccess()) {
// return orderValidResult;
// }
// List<YieldOrder> yieldOrderList = (List<YieldOrder>) orderValidResult.getData();
// List<Long> orderIdList = yieldOrderList.stream()
// .map(YieldOrder::getId)
// .collect(Collectors.toList());
//
// // 3. 校验箱条码是否存在运行中任务
// R<?> boxTaskCheckResult = checkBoxBarcodeRunningTask(boxBarcode);
// if (!boxTaskCheckResult.isSuccess()) {
// return boxTaskCheckResult;
// }
//
// // 4. 校验订单是否已绑定
//// R<?> orderBindCheckResult = checkOrderIdBoundStatus(orderIdList);
//// if (!orderBindCheckResult.isSuccess()) {
//// return orderBindCheckResult;
//// }
//
// // 5. 订单重量校验(超限则拒绝绑定)
// BigDecimal totalWeight = calculateOrderTotalWeight(orderIdList);
// if (totalWeight.compareTo(MAX_BOX_WEIGHT_THRESHOLD) > 0) {
// String errorMsg = String.format("箱条码%s绑定的订单总重量%.2fkg,超过最大阈值%.2fkg",
// boxBarcode, totalWeight, MAX_BOX_WEIGHT_THRESHOLD);
// log.warn("【箱条码绑定】{}", errorMsg);
// return R.fail(errorMsg + ",请重新进行绑定");
// }
// // 6.
//
// // 6. 保存绑定关系
// return saveOrderBoxBinding(boxBarcode, new ArrayList<>(orderIdList));
// }
@Override
/**
* 箱条码绑定主入口
* @param boxBinding 绑定请求参数箱条码 + 订单卡号列表
* @return 绑定结果
*/
public R<?> boxBinding(BoxBindingDto boxBinding) {
log.info("【箱条码绑定】开始处理 - 绑定参数:{}", boxBinding);
// 1. 基础参数校验
R<?> paramCheckResult = validateBoxBindingParams(boxBinding);
if (!paramCheckResult.isSuccess()) {
return paramCheckResult;
}
String boxBarcode = boxBinding.getBoxBarcode();
ArrayList<String> orderCardNoList = boxBinding.getOrderIdList();
ArrayList<String> cardNoList = new ArrayList<>(orderCardNoList);
Long wcId = null;
// 2. 查询箱子是否已有绑定记录,获取已绑定的作业中心ID
List<OrderBind> orderBindList = orderBindService.lambdaQuery()
.eq(OrderBind::getBoxBarcode, boxBarcode)
.eq(OrderBind::getBindingStatus, OrderBind.STATUS_BOUND)
.list();
if (orderBindList != null && !orderBindList.isEmpty()) {
wcId = orderBindList.get(0).getWcID();
// 合并已绑定的卡号
orderBindList.forEach(bind -> cardNoList.add(bind.getCardNo()));
}
// 3. 校验所有订单的作业中心是否一致
for (String orderCardNo : orderCardNoList) {
R<?> checkResult = checkOrderWorkCenterConsistency(orderCardNo, wcId);
if (!checkResult.isSuccess()) {
return checkResult;
}
// 从结果中获取最终确定的 wcId(第一次会赋值)
wcId = (Long) checkResult.getData();
}
// 4. 校验箱条码是否存在运行中任务
R<?> boxTaskCheckResult = checkBoxBarcodeRunningTask(boxBarcode);
if (!boxTaskCheckResult.isSuccess()) {
return boxTaskCheckResult;
}
// 5. 校验订单是否已被绑定
R<?> orderBindCheckResult = checkOrderIdBoundStatus(orderCardNoList);
if (!orderBindCheckResult.isSuccess()) {
return orderBindCheckResult;
}
// 6. 校验总重量是否超限
BigDecimal totalWeight = calculateOrderCardNoTotalWeight(cardNoList);
if (totalWeight.compareTo(MAX_BOX_WEIGHT_THRESHOLD) > 0) {
String errorMsg = String.format("箱条码%s绑定的订单总重量%.2fkg,超过最大阈值%.2fkg",
boxBarcode, totalWeight, MAX_BOX_WEIGHT_THRESHOLD);
log.warn("【箱条码绑定】{}", errorMsg);
return R.fail(errorMsg + ",请重新进行绑定");
}
// 7. 校验作业中心是否有配送区域
List<StationCenter> stationCenterList = stationCenterService.lambdaQuery()
.eq(StationCenter::getWcId, wcId)
.list();
if (stationCenterList == null || stationCenterList.isEmpty()) {
return R.fail("作业中心无配送区域");
}
// 8. 执行绑定保存
return saveOrderBoxBinding(boxBarcode, orderCardNoList, wcId);
}
/**
* 校验单个订单的作业中心与箱绑定作业中心是否一致核心逻辑抽离
*/
private R<?> checkOrderWorkCenterConsistency(String orderCardNo, Long currentWcId) {
// ====================== 处理标准工单 ======================
List<WorkOrder> workOrderList = workOrderService.lambdaQuery()
.eq(WorkOrder::getCardNo, orderCardNo)
.list();
if (workOrderList != null && !workOrderList.isEmpty()) {
WorkOrder workOrder = workOrderList.get(0);
List<WorkPlan> workPlanList = workPlanService.lambdaQuery()
.eq(WorkPlan::getWoId, workOrder.getId())
.list();
if (workPlanList == null || workPlanList.isEmpty()) {
log.info("workPlanList");
return R.fail(orderCardNo + "车间订单异常");
}
WorkPlan workPlan = workPlanList.get(0);
Long workCenterId;
// 根据工序状态判断使用当前工序还是下一道工序
if (workPlan.getStatus() > 3) {
workCenterId = workPlan.getWorkCenterId();
} else {
List<WorkPlan> nextWorkPlanList = workPlanService.lambdaQuery()
.eq(WorkPlan::getId, workPlan.getNextWpId())
.list();
if (nextWorkPlanList == null || nextWorkPlanList.isEmpty()) {
return R.fail(orderCardNo + "车间下一工序订单异常");
}
workCenterId = nextWorkPlanList.get(0).getWorkCenterId();
}
return validateWorkCenter(orderCardNo, currentWcId, workCenterId);
}
// ====================== 处理PR工单 ======================
List<PrWorkOrder> prWorkOrderList = prWorkOrderService.lambdaQuery()
.eq(PrWorkOrder::getCardNo, orderCardNo)
.list();
if (prWorkOrderList != null && !prWorkOrderList.isEmpty()) {
PrWorkOrder prWorkOrder = prWorkOrderList.get(0);
List<PrWorkPlan> workPlanList = prWorkPlanService.lambdaQuery()
.eq(PrWorkPlan::getWpId, prWorkOrder.getId())
.list();
if (workPlanList == null || workPlanList.isEmpty()) {
return R.fail(orderCardNo + "车间订单异常");
}
PrWorkPlan workPlan = workPlanList.get(0);
Long workCenterId;
if (workPlan.getStatus() > 3) {
workCenterId = workPlan.getWcId();
} else {
List<PrWorkPlan> nextWorkPlanList = prWorkPlanService.lambdaQuery()
.eq(PrWorkPlan::getId, workPlan.getNextWpId())
.list();
if (nextWorkPlanList == null || nextWorkPlanList.isEmpty()) {
return R.fail(orderCardNo + "车间订单异常");
}
workCenterId = nextWorkPlanList.get(0).getWcId();
}
return validateWorkCenter(orderCardNo, currentWcId, workCenterId);
}
// 未找到任何订单
return R.fail(orderCardNo + "车间订单异常");
}
/**
* 统一校验作业中心空值校验 + 一致性校验
*/
private R<?> validateWorkCenter(String orderCardNo, Long currentWcId, Long workCenterId) {
if (workCenterId == null) {
return R.fail("请注意:" + orderCardNo + "订单未指派作业中心");
}
// 第一次绑定,赋值作业中心
if (currentWcId == null) {
return R.data(workCenterId);
}
// 校验是否与已有作业中心一致
if (!currentWcId.equals(workCenterId)) {
return R.fail(orderCardNo + "作业中心不一致");
}
return R.data(workCenterId);
}
}

@ -45,6 +45,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
@ -81,16 +82,20 @@ public class OrderBindServiceImpl extends BaseServiceImpl<OrderBindMapper, Order
Long id = boxBindingDto.getId();
String boxBarcode = boxBindingDto.getBoxBarcode();
// 优化:使用StringUtils.isEmpty避免空指针,提示更精准
if (id == null && StringUtils.isEmpty(boxBarcode)) {
return R.fail("解绑失败:id和箱条码不能同时为空");
if (boxBindingDto.getOrderIdList() == null && StringUtils.isEmpty(boxBarcode)) {
return R.fail("解绑失败:流程卡号和箱条码不能同时为空");
}
// 2. 分场景处理解绑逻辑(优化:提取方法+减少嵌套+统一返回)
boolean unbindSuccess;
boolean unbindSuccess = false;
if (StringUtils.isNotBlank(boxBarcode)) {
unbindSuccess = unbindByBoxBarcode(boxBarcode);
} else {
unbindSuccess = unbindById(id);
ArrayList<String> orderIdList = boxBindingDto.getOrderIdList();
for (String s : orderIdList) {
unbindSuccess = unbindByCardNo((s));
}
}
// 3. 统一结果返回(优化:消除冗余的if-else)
@ -147,12 +152,13 @@ public class OrderBindServiceImpl extends BaseServiceImpl<OrderBindMapper, Order
* @param id 记录ID
* @return 解绑是否成功
*/
private boolean unbindById(Long id) throws BusinessException {
OrderBind orderBind = getById(id);
if (orderBind == null) {
throw new BusinessException("解绑失败:未查询到ID为[" + id + "]的记录");
private boolean unbindByCardNo(String CardNo) throws BusinessException {
// OrderBind orderBind = getL(id);
List<OrderBind> orderBindList = list(new LambdaQueryWrapper<OrderBind>().eq(OrderBind::getCardNo, CardNo).ne(OrderBind::getBindingStatus, STATUS_UNBINDED));
if (orderBindList == null||orderBindList.size()==0) {
throw new BusinessException("解绑失败:未查询到流程卡号为[" + CardNo + "]的记录");
}
OrderBind orderBind = orderBindList.get(0);
// 优化:赋值逻辑
orderBind.setBindingStatus(STATUS_UNBINDED);
// 可选:补充更新审计字段

@ -0,0 +1,51 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.desk.logistics.service.impl;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.desk.logistics.mapper.PrWorkOrderMapper;
import org.springblade.desk.logistics.mapper.WeighDataMapper;
import org.springblade.desk.logistics.pojo.entity.PrWorkOrder;
import org.springblade.desk.logistics.pojo.entity.WeighData;
import org.springblade.desk.logistics.service.IPrWorkOrderService;
import org.springblade.desk.logistics.service.IWeighDataService;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
/**
* 车间订单 服务实现类
*
* @author BladeX
* @since 2025-11-12
*/
@Service
@Slf4j
public class PrWorkOrderServiceImpl extends BaseServiceImpl<PrWorkOrderMapper, PrWorkOrder> implements IPrWorkOrderService {
}

@ -0,0 +1,46 @@
package org.springblade.desk.logistics.service.impl; /**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.desk.logistics.mapper.PrWorkPlanMapper;
import org.springblade.desk.logistics.pojo.entity.PrWorkPlan;
import org.springblade.desk.logistics.service.IPrWorkPlanService;
import org.springframework.stereotype.Service;
/**
* 车间订单 服务实现类
*
* @author BladeX
* @since 2025-11-12
*/
@Service
@Slf4j
public class PrWorkPlanServiceImpl extends BaseServiceImpl<PrWorkPlanMapper, PrWorkPlan> implements IPrWorkPlanService {
}

@ -0,0 +1,49 @@
package org.springblade.desk.logistics.service.impl; /**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.desk.logistics.mapper.PrWorkPlanMapper;
import org.springblade.desk.logistics.mapper.StationCenterMapper;
import org.springblade.desk.logistics.pojo.entity.PrWorkPlan;
import org.springblade.desk.logistics.pojo.entity.StationCenter;
import org.springblade.desk.logistics.service.IPrWorkPlanService;
import org.springblade.desk.logistics.service.IStationCenterService;
import org.springframework.stereotype.Service;
/**
* 车间订单 服务实现类
*
* @author BladeX
* @since 2025-11-12
*/
@Service
@Slf4j
public class StationCenterServiceImpl extends BaseServiceImpl<StationCenterMapper, StationCenter> implements IStationCenterService {
}

@ -33,7 +33,6 @@ import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.tool.api.R;
import org.springblade.desk.basic.pojo.entity.WorkCenter;
import org.springblade.desk.basic.service.IWorkCenterService;
import org.springblade.desk.dashboard.pojo.vo.DsTaskingVO;
import org.springblade.desk.logistics.mapper.StationMapper;
import org.springblade.desk.logistics.pojo.entity.Station;
import org.springblade.desk.logistics.pojo.vo.StationVO;
@ -118,4 +117,9 @@ public class StationServiceImpl extends BaseServiceImpl<StationMapper, Station>
return true;
}
@Override
public List<StationVO> getStatusStationList(Integer stationStatus, Long wcId,Integer status, boolean include) {
return baseMapper.getStatusStationList(stationStatus,wcId,status,include);
}
}

@ -8,6 +8,7 @@ import org.springblade.desk.logistics.pojo.entity.Location;
import org.springblade.desk.logistics.pojo.entity.Station;
import org.springblade.desk.logistics.pojo.entity.Task;
import org.springblade.desk.logistics.pojo.vo.AgvSchedulingTaskVO;
import org.springblade.desk.logistics.pojo.vo.StationVO;
import org.springblade.desk.logistics.service.*;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@ -67,11 +68,12 @@ public class StorageMonitoringServiceImpl implements IStorageMonitoringService {
* @param locationService 库位服务BeanSpring自动注入
* @param taskExecuteRecordService
*/
public StorageMonitoringServiceImpl(ITaskService taskService, IStationService stationService, ILocationService locationService, ITaskExecuteRecordService taskExecuteRecordService) {
public StorageMonitoringServiceImpl(ITaskService taskService, IStationService stationService, ILocationService locationService, ITaskExecuteRecordService taskExecuteRecordService, IStationCenterService stationCenterService) {
this.taskService = taskService;
this.stationService = stationService;
this.locationService = locationService;
this.taskExecuteRecordService = taskExecuteRecordService;
}
/**
@ -94,10 +96,11 @@ public class StorageMonitoringServiceImpl implements IStorageMonitoringService {
@Override // 实现IStorageMonitoringService接口的抽象方法
public void monitoringStation() {
// ========== 步骤1:查询所有空闲状态的站点 ==========
List<Station> stationList = stationService.list(
new LambdaQueryWrapper<Station>()
.eq(Station::getStationStatus, Station.STATUS_FREE) // 筛选条件:站点状态为空闲
);
// List<Station> stationList = stationService.list(
// new LambdaQueryWrapper<Station>()
// .eq(Station::getStationStatus, Station.STATUS_FREE) // 筛选条件:站点状态为空闲
// );
List<StationVO> stationList = stationService.getStatusStationList(Station.STATUS_FREE, null, null, false);
// 日志打印空闲站点数量,便于监控和问题排查
log.info("【仓储监控】定时任务执行 - 查询到空闲站点数量:{}", stationList == null ? 0 : stationList.size());
@ -110,10 +113,13 @@ public class StorageMonitoringServiceImpl implements IStorageMonitoringService {
// ========== 步骤2:遍历空闲站点处理关联任务 ==========
int processedCount = 0; // 统计成功处理的站点数量
for (Station station : stationList) {
ArrayList<String> stationNameList = new ArrayList<>();
for (StationVO station : stationList) {
// 打印当前处理的站点信息,便于定位单站点异常
log.info("【仓储监控】开始处理站点 - 站点ID:{},工位ID:{}", station.getId(), station.getWcId());
if (stationNameList.contains(station.getStationCode())) {
continue;
}
try {
// ========== 步骤2.1:查询对应工位的待库位任务(按创建时间升序) ==========
List<Task> taskList = taskService.list(
@ -211,6 +217,7 @@ public class StorageMonitoringServiceImpl implements IStorageMonitoringService {
boolean record = taskExecuteRecordService.inboundRecord(ctuSchedulingTask, firstTask,null);
if (record){
taskIdList.add(firstTask.getId());
stationNameList.add(station.getStationCode());
}

@ -83,7 +83,7 @@ public class TaskExecuteRecordServiceImpl extends BaseServiceImpl<TaskExecuteRec
* - 失败R.fail(错误信息)
*/
@Override
public R agvCallback(AGVCallBackDto agvCallBack) {
public R agvCallback(AGVCallBackDto agvCallBack) {
// 记录AGV回调入参,便于问题排查
log.info("agv小车接口调用参数入参:{}", agvCallBack);

Loading…
Cancel
Save