Selaa lähdekoodia

技术员领料

home 2 vuotta sitten
vanhempi
commit
0a2c315dde

+ 119 - 0
hx-common/common-tool/src/main/java/com/fjhx/utils/BigDecimalUtil.java

@@ -0,0 +1,119 @@
+package com.fjhx.utils;
+
+import org.springblade.core.log.exception.ServiceException;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+/**
+ * 精确的浮点数运算
+ */
+public class BigDecimalUtil {
+
+    private BigDecimalUtil() {
+    }
+
+    /**
+     * 值保留几位小数
+     */
+    public static BigDecimal keepDecimals(Object value, int scale) {
+        return (objToBigDecimal(value)).divide(BigDecimal.ONE, scale, RoundingMode.HALF_UP);
+    }
+
+    /**
+     * 默认保留2位小数
+     */
+    public static BigDecimal keepDecimals(Object value) {
+        return (objToBigDecimal(value)).divide(BigDecimal.ONE, 2, RoundingMode.HALF_UP);
+    }
+
+    /**
+     * 结果值
+     */
+    private BigDecimal bigDecimal;
+
+    /**
+     * 初始化
+     */
+    public static BigDecimalUtil init() {
+        BigDecimalUtil bigDecimalUtil = new BigDecimalUtil();
+        bigDecimalUtil.bigDecimal = BigDecimal.ZERO;
+        return bigDecimalUtil;
+    }
+
+    /**
+     * 初始化
+     */
+    public static BigDecimalUtil init(Object value) {
+        BigDecimalUtil bigDecimalUtil = new BigDecimalUtil();
+        bigDecimalUtil.bigDecimal = objToBigDecimal(value);
+        return bigDecimalUtil;
+    }
+
+    /**
+     * 加法运算
+     */
+    public BigDecimalUtil add(Object value) {
+        bigDecimal = bigDecimal.add(objToBigDecimal(value));
+        return this;
+    }
+
+    /**
+     * 减法运算
+     */
+    public BigDecimalUtil subtract(Object value) {
+        bigDecimal = bigDecimal.subtract(objToBigDecimal(value));
+        return this;
+    }
+
+    /**
+     * 乘法运算
+     */
+    public BigDecimalUtil multiply(Object value) {
+        bigDecimal = bigDecimal.multiply(objToBigDecimal(value));
+        return this;
+    }
+
+    /**
+     * 除法运算
+     */
+    public BigDecimalUtil divide(Object value, int scale) {
+        bigDecimal = bigDecimal.divide(objToBigDecimal(value), scale, RoundingMode.HALF_UP);
+        return this;
+    }
+
+    /**
+     * 获取计算结果值
+     */
+    public BigDecimal getValue() {
+        return bigDecimal;
+    }
+
+    /**
+     * 获取计算结果值,并指定保留位数
+     */
+    public BigDecimal getValue(int scale) {
+        return keepDecimals(bigDecimal, scale);
+    }
+
+    private static BigDecimal objToBigDecimal(Object value) {
+        BigDecimal bd;
+        if (value instanceof BigDecimal) {
+            bd = (BigDecimal) value;
+        } else if (value instanceof String) {
+            bd = new BigDecimal((String) value);
+        } else if (value instanceof Float) {
+            bd = BigDecimal.valueOf((float) value);
+        } else if (value instanceof Double) {
+            bd = BigDecimal.valueOf((Double) value);
+        } else if (value instanceof Integer) {
+            bd = BigDecimal.valueOf((Integer) value);
+        } else if (value instanceof Long) {
+            bd = BigDecimal.valueOf((Long) value);
+        } else {
+            throw new ServiceException("未知的计算类型");
+        }
+        return bd;
+    }
+
+}

+ 89 - 74
hx-service-api/storage-api/src/main/java/com/fjhx/entity/scheduling/entity/Scheduling.java

@@ -16,17 +16,13 @@
  */
 package com.fjhx.entity.scheduling.entity;
 
-import java.math.BigDecimal;
 import com.baomidou.mybatisplus.annotation.TableName;
-import java.time.LocalDateTime;
-import java.io.Serializable;
-import java.util.Date;
-
-import com.fjhx.base.BasicEntity;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
 
 /**
  * 仓库实体类
@@ -39,73 +35,92 @@ import io.swagger.annotations.ApiModelProperty;
 @ApiModel(value = "Scheduling对象", description = "仓库")
 public class Scheduling {
 
-	private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ApiModelProperty(value = "主键ID")
+    private String id;
+    /**
+     * 是否删除
+     */
+    @ApiModelProperty(value = "是否删除")
+    private Integer isDelete;
+    /**
+     * 排班日期
+     */
+    @ApiModelProperty(value = "排班日期")
+    private Date planDate;
+    /**
+     * 喷印人员工号
+     */
+    @ApiModelProperty(value = "喷印人员工号")
+    private String printer;
+    /**
+     * 打纸人员工号
+     */
+    @ApiModelProperty(value = "打纸人员工号")
+    private String paperMan;
+    /**
+     * 物料编码
+     */
+    @ApiModelProperty(value = "物料编码")
+    private String materialCode;
+    /**
+     * 物料长度
+     */
+    @ApiModelProperty(value = "物料长度")
+    private BigDecimal materialQuantity;
+    /**
+     * 转印纸编码
+     */
+    @ApiModelProperty(value = "转印纸编码")
+    private String paperCode;
+    /**
+     * 转印纸长度
+     */
+    @ApiModelProperty(value = "转印纸长度")
+    private BigDecimal paperQuantity;
+    /**
+     * 创建时间
+     */
+    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+    /**
+     * 修改时间
+     */
+    @ApiModelProperty(value = "修改时间")
+    private Date updateTime;
+    /**
+     * 创建人
+     */
+    @ApiModelProperty(value = "创建人")
+    private String createUser;
+    /**
+     * 修改人
+     */
+    @ApiModelProperty(value = "修改人")
+    private String updateUser;
+
+    /**
+     * 喷印人员领料状态(0 未领取 1已领取)
+     */
+    private Integer materialStatus;
+
+    /**
+     * 打纸人员领料状态(0 未领取 1已领取)
+     */
+    private Integer paperStatus;
 
-	/**
-	* 主键ID
-	*/
-	@ApiModelProperty(value = "主键ID")
-	private String id;
-	/**
-	* 是否删除
-	*/
-	@ApiModelProperty(value = "是否删除")
-	private Integer isDelete;
-	/**
-	* 排班日期
-	*/
-	@ApiModelProperty(value = "排班日期")
-	private Date planDate;
-	/**
-	* 喷印人员工号
-	*/
-	@ApiModelProperty(value = "喷印人员工号")
-	private String printer;
-	/**
-	* 打纸人员工号
-	*/
-	@ApiModelProperty(value = "打纸人员工号")
-	private String paperMan;
-	/**
-	* 物料编码
-	*/
-	@ApiModelProperty(value = "物料编码")
-	private String materialCode;
-	/**
-	* 物料长度
-	*/
-	@ApiModelProperty(value = "物料长度")
-	private BigDecimal materialQuantity;
-	/**
-	* 转印纸编码
-	*/
-	@ApiModelProperty(value = "转印纸编码")
-	private String paperCode;
-	/**
-	* 转印纸长度
-	*/
-	@ApiModelProperty(value = "转印纸长度")
-	private BigDecimal paperQuantity;
-	/**
-	* 创建时间
-	*/
-	@ApiModelProperty(value = "创建时间")
-	private Date createTime;
-	/**
-	* 修改时间
-	*/
-	@ApiModelProperty(value = "修改时间")
-	private Date updateTime;
-	/**
-	* 创建人
-	*/
-	@ApiModelProperty(value = "创建人")
-	private String createUser;
-	/**
-	* 修改人
-	*/
-	@ApiModelProperty(value = "修改人")
-	private String updateUser;
+    /**
+     * 喷印人员推荐领料rfid
+     */
+    private String materialRfid;
 
+    /**
+     * 打纸人员推荐领料rfid
+     */
+    private String paperRfid;
 
 }

+ 115 - 0
hx-service-api/storage-api/src/main/java/com/fjhx/params/stock/PickingTrackingNumStatisticsResult.java

@@ -0,0 +1,115 @@
+package com.fjhx.params.stock;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+@Data
+public class PickingTrackingNumStatisticsResult implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 指定领料
+     */
+    private int appointNum;
+
+    /**
+     * 实际领料卷数
+     */
+    private int actualNum;
+
+    /**
+     * 指定未领料
+     */
+    private int appointNotClaimedNum;
+
+    /**
+     * 额外领料卷数
+     */
+    private int additionalNum;
+
+    /**
+     * 排班米数
+     */
+    private BigDecimal planMeter;
+
+    /**
+     * 指定米数
+     */
+    private BigDecimal appointMeter;
+
+    /**
+     * 实际领料米数
+     */
+    private BigDecimal actualMeter;
+
+    /**
+     * 排班面积
+     */
+    private BigDecimal planArea;
+
+    /**
+     * 指定面积
+     */
+    private BigDecimal appointArea;
+
+    /**
+     * 实际领料面积
+     */
+    private BigDecimal actualArea;
+
+    /**
+     * 指定产出比
+     */
+    private BigDecimal appointOutputRatio;
+
+    /**
+     * 实际产出比
+     */
+    private BigDecimal actualOutputRatio;
+
+    /**
+     * 实际产出比
+     */
+    private BigDecimal outputRatioDifference;
+
+
+    public BigDecimal getPlanMeter() {
+        return planMeter == null ? BigDecimal.ZERO : planMeter;
+    }
+
+    public BigDecimal getAppointMeter() {
+        return appointMeter == null ? BigDecimal.ZERO : appointMeter;
+    }
+
+    public BigDecimal getActualMeter() {
+        return actualMeter == null ? BigDecimal.ZERO : actualMeter;
+    }
+
+    public BigDecimal getPlanArea() {
+        return planArea == null ? BigDecimal.ZERO : planArea;
+    }
+
+    public BigDecimal getAppointArea() {
+        return appointArea == null ? BigDecimal.ZERO : appointArea;
+    }
+
+    public BigDecimal getActualArea() {
+        return actualArea == null ? BigDecimal.ZERO : actualArea;
+    }
+
+    public BigDecimal getAppointOutputRatio() {
+        return appointOutputRatio == null ? BigDecimal.ZERO : appointOutputRatio;
+    }
+
+    public BigDecimal getActualOutputRatio() {
+        return actualOutputRatio == null ? BigDecimal.ZERO : actualOutputRatio;
+    }
+
+    public BigDecimal getOutputRatioDifference() {
+        return outputRatioDifference == null ? BigDecimal.ZERO : outputRatioDifference;
+    }
+
+}

+ 0 - 17
hx-service-api/storage-api/src/main/java/com/fjhx/params/stock/StockAttachmentEx.java

@@ -1,17 +0,0 @@
-package com.fjhx.params.stock;
-
-import com.fjhx.entity.attachment.StockAttachment;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-/**
- * 业务附件表
- *
- * @author ${author}
- * @since 2022-07-12
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-public class StockAttachmentEx extends StockAttachment {
-
-}

+ 0 - 17
hx-service-api/storage-api/src/main/java/com/fjhx/params/stock/StockWaterEx.java

@@ -1,17 +0,0 @@
-package com.fjhx.params.stock;
-
-import com.fjhx.entity.stock.StockWater;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-/**
- * 出入库
- *
- * @author ${author}
- * @since 2022-07-04
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-public class StockWaterEx extends StockWater {
-
-}

+ 0 - 17
hx-service-api/storage-api/src/main/java/com/fjhx/params/stock/StockWaterVo.java

@@ -1,17 +0,0 @@
-package com.fjhx.params.stock;
-
-import com.fjhx.entity.stock.StockWater;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-/**
- * 出入库
- *
- * @author ${author}
- * @since 2022-07-04
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-public class StockWaterVo extends StockWater {
-
-}

+ 1 - 1
hx-service/storage/src/main/java/com/fjhx/stock/controller/StockAreaController.java

@@ -28,7 +28,7 @@ public class StockAreaController {
     private StockAreaService stockAreaService;
 
     /**
-     * 货架id
+     * 查询1号仓库货架列表
      */
     @PostMapping("/list")
     public R list() {

+ 39 - 1
hx-service/storage/src/main/java/com/fjhx/stock/controller/StockDetailController.java

@@ -1,6 +1,7 @@
 package com.fjhx.stock.controller;
 
 import com.fjhx.entity.stock.StockDetail;
+import com.fjhx.params.stock.PickingTrackingNumStatisticsResult;
 import com.fjhx.stock.service.StockDetailService;
 import org.springblade.core.tenant.annotation.TenantIgnore;
 import org.springblade.core.tool.api.R;
@@ -10,6 +11,7 @@ import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -34,7 +36,7 @@ public class StockDetailController {
      */
     @PostMapping("/getMaterialInfoByQrCode")
     public R getMaterialInfoByQrCode(@RequestBody Map<String, String> condition) {
-        Map<String,Object> result = stockDetailService.getMaterialInfoByQrCode(condition);
+        Map<String, Object> result = stockDetailService.getMaterialInfoByQrCode(condition);
         return R.success(result);
     }
 
@@ -47,5 +49,41 @@ public class StockDetailController {
         return R.success();
     }
 
+    /**
+     * 获取限定领料列表
+     */
+    @PostMapping("/restrictedPicking")
+    public R restrictedPicking(@RequestBody Map<String, String> condition) {
+        List<Map<String, Object>> result = stockDetailService.restrictedPicking(condition);
+        return R.success(result);
+    }
+
+    /**
+     * 提交限定领料列表
+     */
+    @PostMapping("/submitRestrictedPicking")
+    public R submitRestrictedPicking(@RequestBody List<Map<String, String>> condition) {
+        stockDetailService.submitRestrictedPicking(condition);
+        return R.success();
+    }
+
+    /**
+     * 领料追踪用户统计
+     */
+    @PostMapping("/pickingTrackingUserStatistics")
+    public R pickingTrackingUserStatistics(@RequestBody Map<String, String> condition) {
+        List<HashMap<String, Object>> result = stockDetailService.pickingTrackingUserStatistics(condition);
+        return R.success(result);
+    }
+
+    /**
+     * 领料追踪用户统计
+     */
+    @PostMapping("/pickingTrackingNumStatistics")
+    public R pickingTrackingNumStatistics(@RequestBody Map<String, String> condition) {
+        PickingTrackingNumStatisticsResult result = stockDetailService.pickingTrackingNumStatistics(condition);
+        return R.success(result);
+    }
+
 }
 

+ 24 - 2
hx-service/storage/src/main/java/com/fjhx/stock/mapper/StockDetailMapper.java

@@ -1,9 +1,13 @@
 package com.fjhx.stock.mapper;
 
-import com.fjhx.entity.stock.StockDetail;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fjhx.entity.stock.StockDetail;
+import org.apache.ibatis.annotations.MapKey;
 import org.apache.ibatis.annotations.Param;
 
+import java.math.BigDecimal;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -16,6 +20,24 @@ import java.util.Map;
  */
 public interface StockDetailMapper extends BaseMapper<StockDetail> {
 
-    Map<String,Object> getMaterialInfoByQrCode(@Param("qrCode") String qrCode);
+    Map<String, Object> getMaterialInfoByQrCode(@Param("qrCode") String qrCode);
+
+    List<Map<String, Object>> restrictedPicking(@Param("ew") QueryWrapper<Object> wrapper, @Param("jobNo") String jobNo);
+
+    @MapKey("materialCode")
+    Map<String, Map<String, BigDecimal>> getMaterialQuantity(@Param("ew") QueryWrapper<Object> wrapper);
+
+    Map<String, Object> selectRecommendMaterial(@Param("materialCode") String materialCode, @Param("availableQuantity") BigDecimal availableQuantity);
+
+    List<Map<String, Object>> getPlanList(@Param("ew") QueryWrapper<Object> wrapper);
+
+    @MapKey("jobNo")
+    Map<String, Map<String, String>> selectUserByJobNoList(@Param("ew") QueryWrapper<Object> wrapper);
+
+    List<Map<String, Object>> getPlanListByUser(@Param("ew") QueryWrapper<Object> wrapper, @Param("jobNo") String jobNo);
+
+    List<Map<String, Object>> getOutputList(@Param("ew") QueryWrapper<Object> wrapper);
+
+    List<Map<String, Object>> getMaterialWidthByCode(@Param("ew") QueryWrapper<Object> wrapper);
 
 }

+ 92 - 0
hx-service/storage/src/main/java/com/fjhx/stock/mapper/StockDetailMapper.xml

@@ -16,4 +16,96 @@
         where sd.QRCode = #{qrCode}
     </select>
 
+    <select id="restrictedPicking" resultType="java.util.Map">
+        select ss.id,
+               if(ss.printer = #{jobNo} and ss.material_status = 0, m.Code, m2.Code)   materialCode,
+               if(ss.printer = #{jobNo} and ss.material_status = 0, m.Name, m2.Name)   materialName,
+               if(ss.printer = #{jobNo} and ss.material_status = 0, m.Width, m2.Width) materialWidth,
+               if(ss.printer = #{jobNo} and ss.material_status = 0, ss.material_quantity,
+                  ss.paper_quantity)                                                   availableQuantity,
+               if(ss.printer = #{jobNo} and ss.material_status = 0, 1, 2)              type
+        from stock_scheduling ss
+                 left join material m on ss.material_code = m.Code
+                 left join material m2 on ss.paper_code = m2.Code
+            ${ew.customSqlSegment}
+    </select>
+
+    <select id="getMaterialQuantity" resultType="java.util.Map">
+        select s.MaterialCode materialCode, s.Quantity totalQuantity, su.Quantity userQuantity
+        from stock s
+                 left join stockuser su on s.MaterialCode = su.MaterialCode
+            ${ew.customSqlSegment}
+    </select>
+
+    <select id="selectRecommendMaterial" resultType="java.util.Map">
+        select sd.RfidCode rfidCode, sd.Quantity quantity, sa.Name areaName
+        from stock_detail sd
+                 left join stock_area sa on sa.ID = sd.PlaceAreaId
+        where sd.MaterialCode = #{materialCode}
+          and sd.Quantity &gt; #{availableQuantity}
+        order by sd.Quantity
+        limit 1
+    </select>
+
+    <select id="getPlanList" resultType="java.util.Map">
+        (select ss.material_code     code,
+                ss.material_quantity quantity,
+                ss.printer           jobNo
+         from stock_scheduling ss
+             ${ew.customSqlSegment})
+        union
+        (select ss.paper_code     code,
+                ss.paper_quantity quantity,
+                ss.paper_man      jobNo
+         from stock_scheduling ss
+             ${ew.customSqlSegment})
+    </select>
+
+    <select id="selectUserByJobNoList" resultType="java.util.Map">
+        select uu.JobNo    jobNo,
+               uu.RealName userName
+        from u_user uu
+            ${ew.customSqlSegment}
+    </select>
+
+    <select id="getPlanListByUser" resultType="java.util.Map">
+        (
+        select
+        ss.material_code code,
+        ss.material_quantity quantity,
+        ss.material_rfid rfid
+        from stock_scheduling ss
+        ${ew.customSqlSegment}
+        <if test="jobNo neq null and jobNo neq ''">
+            and ss.printer = #{jobNo}
+        </if>
+        )
+        union
+        (
+        select
+        ss.paper_code code,
+        ss.paper_quantity quantity,
+        ss.paper_rfid rfid
+        from stock_scheduling ss
+        ${ew.customSqlSegment}
+        <if test="jobNo neq null and jobNo neq ''">
+            and ss.paper_man = #{jobNo}
+        </if>
+        )
+    </select>
+
+    <select id="getOutputList" resultType="java.util.Map">
+        select sw.MaterialCode materialCode,
+               sw.ChangeNum    changeNum,
+               sw.RfidCode     rfidCode
+        from stock_waterdetial sw
+            ${ew.customSqlSegment}
+    </select>
+
+    <select id="getMaterialWidthByCode" resultType="java.util.Map">
+        select m.Code code, m.Width width
+        from material m
+            ${ew.customSqlSegment};
+    </select>
+
 </mapper>

+ 11 - 1
hx-service/storage/src/main/java/com/fjhx/stock/service/StockDetailService.java

@@ -2,7 +2,9 @@ package com.fjhx.stock.service;
 
 import com.fjhx.base.BaseService;
 import com.fjhx.entity.stock.StockDetail;
+import com.fjhx.params.stock.PickingTrackingNumStatisticsResult;
 
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -16,8 +18,16 @@ import java.util.Map;
  */
 public interface StockDetailService extends BaseService<StockDetail> {
 
-    Map<String,Object> getMaterialInfoByQrCode(Map<String, String> condition);
+    Map<String, Object> getMaterialInfoByQrCode(Map<String, String> condition);
 
     void setAreaId(List<StockDetail> stockDetail);
 
+    List<Map<String, Object>> restrictedPicking(Map<String, String> condition);
+
+    void submitRestrictedPicking(List<Map<String, String>> condition);
+
+    List<HashMap<String, Object>> pickingTrackingUserStatistics(Map<String, String> condition);
+
+    PickingTrackingNumStatisticsResult pickingTrackingNumStatistics(Map<String, String> condition);
+
 }

+ 285 - 2
hx-service/storage/src/main/java/com/fjhx/stock/service/impl/StockDetailServiceImpl.java

@@ -1,15 +1,25 @@
 package com.fjhx.stock.service.impl;
 
+import cn.hutool.core.date.DateUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fjhx.constants.StatusConstant;
+import com.fjhx.entity.scheduling.entity.Scheduling;
 import com.fjhx.entity.stock.StockDetail;
+import com.fjhx.params.stock.PickingTrackingNumStatisticsResult;
+import com.fjhx.scheduling.service.ISchedulingService;
 import com.fjhx.stock.mapper.StockDetailMapper;
 import com.fjhx.stock.service.StockDetailService;
 import com.fjhx.utils.Assert;
+import com.fjhx.utils.BigDecimalUtil;
 import org.springblade.core.tenant.annotation.TenantIgnore;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Map;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -23,6 +33,9 @@ import java.util.Map;
 @TenantIgnore
 public class StockDetailServiceImpl extends ServiceImpl<StockDetailMapper, StockDetail> implements StockDetailService {
 
+    @Autowired
+    private ISchedulingService schedulingService;
+
     @Override
     public Map<String, Object> getMaterialInfoByQrCode(Map<String, String> condition) {
         String qrCode = condition.get("qrCode");
@@ -40,5 +53,275 @@ public class StockDetailServiceImpl extends ServiceImpl<StockDetailMapper, Stock
         updateBatchById(stockDetail);
     }
 
+    @Override
+    public List<Map<String, Object>> restrictedPicking(Map<String, String> condition) {
+
+        String jobNo = condition.get("jobNo");
+
+        QueryWrapper<Object> wrapper = Wrappers.query()
+                .eq("ss.is_delete", StatusConstant.No)
+                .and(q -> q.eq("ss.printer", jobNo).or().eq("ss.paper_man", jobNo))
+                .and(q -> q.eq("ss.material_status", StatusConstant.No).or().eq("ss.paper_status", StatusConstant.No));
+
+        List<Map<String, Object>> list = baseMapper.restrictedPicking(wrapper, jobNo);
+
+        if (list.size() == 0) {
+            return list;
+        }
+
+        // 获取物料编码集合
+        List<String> materialCodeList = list.stream().map(item -> item.get("materialCode").toString()).collect(Collectors.toList());
+
+        // 查询实时库存长度和现场库存长度
+        Map<String, Map<String, BigDecimal>> map = baseMapper.getMaterialQuantity(Wrappers.query().in("s.MaterialCode", materialCodeList));
+
+        for (Map<String, Object> item : list) {
+            String materialCode = item.get("materialCode").toString(); // 物料编码
+            float materialWidth = (float) item.get("materialWidth"); // 门幅
+            BigDecimal availableQuantity = (BigDecimal) item.get("availableQuantity"); // 排班数量
+
+            // 门幅保留0位小数
+            item.put("availableQuantity", BigDecimalUtil.keepDecimals(availableQuantity, 0));
+
+            // 计算排班面积
+            BigDecimal availableArea = BigDecimalUtil.init(availableQuantity).multiply(materialWidth)
+                    .divide(100, 1).getValue();
+            item.put("availableArea", availableArea);
+
+            Map<String, BigDecimal> materialCodeQuantityMap = map.get(materialCode);
+            if (materialCodeQuantityMap == null) {
+                item.put("totalArea", BigDecimal.ZERO);
+                item.put("userArea", BigDecimal.ZERO);
+                continue;
+            }
+
+            // 计算实时库存面积
+            BigDecimal bigDecimal = materialCodeQuantityMap.get("totalQuantity"); // 实时库存长度
+            if (bigDecimal == null) {
+                item.put("totalArea", BigDecimal.ZERO);
+            } else {
+                BigDecimal totalArea = BigDecimalUtil.init(bigDecimal).multiply(materialWidth)
+                        .divide(100, 1).getValue();
+                item.put("totalArea", totalArea);
+            }
+
+            // 计算现场库存面积
+            BigDecimal userQuantity = materialCodeQuantityMap.get("userQuantity");
+            if (userQuantity == null) {
+                item.put("userArea", BigDecimal.ZERO);
+            } else {
+                BigDecimal userArea = BigDecimalUtil.init(userQuantity).multiply(materialWidth)
+                        .divide(100, 1).getValue();
+                item.put("userArea", userArea);
+            }
+
+            // 查询推荐物料
+            Map<String, Object> recommendMaterial = baseMapper.selectRecommendMaterial(materialCode, availableQuantity);
+
+            item.putAll(recommendMaterial);
+        }
+
+        return list;
+    }
+
+    @Override
+    public void submitRestrictedPicking(List<Map<String, String>> condition) {
+
+        List<Scheduling> schedulingList = condition.stream().map(item -> {
+            String id = item.get("id");
+            String type = item.get("type");
+            String rfidCode = item.get("rfidCode");
+
+            Scheduling scheduling = new Scheduling();
+            scheduling.setId(id);
+            if (type.equals("1")) {
+                scheduling.setMaterialStatus(1);
+                scheduling.setMaterialRfid(rfidCode);
+            } else {
+                scheduling.setPaperStatus(1);
+                scheduling.setPaperRfid(rfidCode);
+            }
+            return scheduling;
+        }).collect(Collectors.toList());
+
+        schedulingService.updateBatchById(schedulingList);
+
+    }
+
+    @Override
+    public List<HashMap<String, Object>> pickingTrackingUserStatistics(Map<String, String> condition) {
+
+        // 获取查询条件
+        QueryWrapper<Object> wrapper = pickingTrackingStatisticsGetWrapper("ss.plan_date", condition);
+
+        List<Map<String, Object>> list = baseMapper.getPlanList(wrapper);
+
+        if (list.size() == 0) {
+            HashMap<String, Object> countUserMap = new HashMap<>();
+            countUserMap.put("sum", 0);
+            countUserMap.put("userName", "全部");
+            return Collections.singletonList(countUserMap);
+        }
+
+        // 用户统计
+        return pickingTrackingUserStatistics(list);
+    }
+
+    @Override
+    public PickingTrackingNumStatisticsResult pickingTrackingNumStatistics(Map<String, String> condition) {
+
+        PickingTrackingNumStatisticsResult result = new PickingTrackingNumStatisticsResult();
+
+        // 获取查询条件
+        QueryWrapper<Object> wrapper = pickingTrackingStatisticsGetWrapper("ss.plan_date", condition);
+
+        String jobNo = condition.get("jobNo");
+
+        List<Map<String, Object>> list = baseMapper.getPlanListByUser(wrapper, jobNo);
+
+        if (list.size() == 0) {
+            return result;
+        }
+
+        // 指定领料卷数
+        result.setAppointNum(list.size());
+
+        // 物料编码去重集合
+        List<String> code = list.stream().map(item -> item.get("code").toString()).distinct().collect(Collectors.toList());
+        // 获取物料门幅键值对
+        Map<String, Float> codeWidthMap = getCodeWidthMap(code);
+
+        // 赋值实际领料
+        setActual(result, condition, code, codeWidthMap);
+
+        // 赋值排班领料
+        setPlan(result, list, codeWidthMap);
+
+        return result;
+    }
+
+    /**
+     * 赋值实际领料
+     */
+    private void setActual(PickingTrackingNumStatisticsResult result, Map<String, String> condition, List<String> code, Map<String, Float> codeWidthMap) {
+
+        // 指定物料出库物料集合
+        List<Map<String, Object>> outputList = baseMapper.getOutputList(
+                pickingTrackingStatisticsGetWrapper("sw.CreatedTime", condition)
+                        .in("sw.MaterialCode", code)
+                        .eq("sw.StockChangeType", 20));
+
+        // 实际领料卷数
+        result.setActualNum(outputList.size());
+
+        // 实际领料米数
+        BigDecimal actualMeter = outputList.stream().map(item -> (BigDecimal) item.get("changeNum")).reduce(BigDecimal.ZERO, BigDecimal::add);
+        result.setActualMeter(actualMeter);
+
+        // 实际领料面积
+        BigDecimal actualArea = outputList.stream().map(
+                item -> BigDecimalUtil.init(item.get("quantity")).multiply(codeWidthMap.get(item.get("code").toString())).getValue(2)
+        ).reduce(BigDecimal.ZERO, BigDecimal::add);
+        result.setActualArea(actualArea);
+
+    }
+
+    /**
+     * 赋值排班领料
+     */
+    private void setPlan(PickingTrackingNumStatisticsResult result, List<Map<String, Object>> list, Map<String, Float> codeWidthMap) {
+        // 排班米数
+        BigDecimal planMeter = list.stream().map(item -> (BigDecimal) item.get("quantity")).reduce(BigDecimal.ZERO, BigDecimal::add);
+        result.setPlanMeter(planMeter);
+
+        // 排班面积
+        BigDecimal planArea = list.stream()
+                .map(item -> BigDecimalUtil.init(item.get("quantity")).multiply(codeWidthMap.get(item.get("code").toString())).getValue(2))
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+        result.setPlanArea(planArea);
+    }
+
+
+    /**
+     * 获取物料门幅键值对
+     */
+    private Map<String, Float> getCodeWidthMap(List<String> codeList) {
+        // 查询物料门幅
+        List<Map<String, Object>> list = baseMapper.getMaterialWidthByCode(Wrappers.query().in("m.Code", codeList));
+        return list.stream().collect(Collectors.toMap(
+                item -> item.get("code").toString(),
+                item -> (Float) item.get("width")
+        ));
+    }
+
+
+    /**
+     * 领料追踪统计获取wrapper
+     */
+    private QueryWrapper<Object> pickingTrackingStatisticsGetWrapper(String param, Map<String, String> condition) {
+        String type = condition.get("type");
+        Assert.notEmpty(type, "时间类型不能为空");
+        Date beginTime;
+        Date endTime;
+        Date date = new Date();
+        switch (type) {
+            case "1":
+                beginTime = DateUtil.beginOfDay(date);
+                endTime = DateUtil.endOfDay(date);
+                break;
+            case "2":
+                beginTime = DateUtil.beginOfWeek(date);
+                endTime = DateUtil.endOfWeek(date);
+                break;
+            case "3":
+                beginTime = DateUtil.beginOfMonth(date);
+                endTime = DateUtil.endOfMonth(date);
+                break;
+            case "4":
+                beginTime = DateUtil.beginOfYear(date);
+                endTime = DateUtil.endOfYear(date);
+                break;
+            default:
+                beginTime = DateUtil.parse(condition.get("beginTime"));
+                endTime = DateUtil.parse(condition.get("endTime"));
+        }
+
+        return Wrappers.query().between(param, beginTime, endTime);
+    }
+
+    /**
+     * 领料追踪统计:用户统计
+     */
+    private List<HashMap<String, Object>> pickingTrackingUserStatistics(List<Map<String, Object>> list) {
+        // 统计用户
+        List<String> jobNoList = list.stream().map(item -> item.get("jobNo").toString()).distinct().collect(Collectors.toList());
+
+        Map<String, Map<String, String>> JobNoMap = baseMapper.selectUserByJobNoList(Wrappers.query().in("JobNo", jobNoList));
+        List<HashMap<String, Object>> userList = new ArrayList<>(
+                list.stream().collect(Collectors.toMap(
+                        item -> item.get("jobNo").toString(),
+                        item -> {
+                            HashMap<String, Object> map = new HashMap<>();
+                            String jobNo = item.get("jobNo").toString();
+                            map.put("jobNo", jobNo);
+                            map.put("userName", JobNoMap.get(jobNo).get("userName"));
+                            map.put("sum", 1);
+                            return map;
+                        },
+                        (v1, v2) -> {
+                            v1.put("sum", (Integer) v1.get("sum") + 1);
+                            return v1;
+                        }
+                )).values());
+
+        int sum = userList.stream().mapToInt(item -> (Integer) item.get("sum")).sum();
+        HashMap<String, Object> countUserMap = new HashMap<>();
+        countUserMap.put("sum", sum);
+        countUserMap.put("userName", "全部");
+        userList.add(0, countUserMap);
+
+        return userList;
+    }
+
 
 }