添加bigdecimal序列号

添加移库单向列表
This commit is contained in:
2026-02-02 18:10:54 +08:00
parent e7528a6fde
commit 009901d5ee
32 changed files with 692 additions and 163 deletions

View File

@@ -68,28 +68,28 @@ public class AutoInventoryController extends BaseController {
/** /**
* 开始匹配 * 开始匹配
*/ */
// @PostMapping("/match") @PostMapping("/match")
// @ApiOperation("开始匹配") @ApiOperation("开始匹配")
// public AjaxResult match(@RequestBody QueryDTO dto) { public AjaxResult match(@RequestBody QueryDTO dto) {
// // 停止盘点 // 停止盘点
// rfidService.stopScan(dto.getDeviceId()); rfidService.stopScan(dto.getDeviceId());
//
// dto.setScanType(1); dto.setScanType(1);
//
// rkInfoService.matchWithStatus(dto); rkInfoService.matchWithStatus(dto);
//
// return AjaxResult.success(); return AjaxResult.success();
// } }
/** /**
* 匹配后图表统计 * 匹配后图表统计
*/ */
// @PostMapping("/chart") @PostMapping("/chart")
// @ApiOperation("匹配后图表统计") @ApiOperation("匹配后图表统计")
// public AjaxResult chart(@RequestBody QueryDTO dto) { public AjaxResult chart(@RequestBody QueryDTO dto) {
// ChartDataVO vo = rkInfoService.matchWithAll(dto); ChartDataVO vo = rkInfoService.matchWithAll(dto);
// return AjaxResult.success(vo); return AjaxResult.success(vo);
// } }
/** /**

View File

@@ -50,15 +50,15 @@ public class InventoryMatchScanController extends BaseController {
* @param matchScan * @param matchScan
* @return * @return
*/ */
// @GetMapping("/countList") @GetMapping("/countList")
// public TableDataInfo countList(InventoryMatchScan matchScan) { public TableDataInfo countList(InventoryMatchScan matchScan) {
// // 开启分页 // 开启分页
// startPage(); startPage();
// // 调用 service 层查询数据 // 调用 service 层查询数据
// List<RkInfoMatchVO> list = inventoryMatchScanService.selectMatchScanCountList(matchScan); List<RkInfoMatchVO> list = inventoryMatchScanService.selectMatchScanCountList(matchScan);
// // 返回分页后的结果 // 返回分页后的结果
// return getDataTable(list); return getDataTable(list);
// } }
/** /**

View File

@@ -19,5 +19,6 @@ public interface InventoryMatchScanService {
List<InventoryMatchScan> selectInventoryMatchScanList(InventoryMatchScan matchScan); List<InventoryMatchScan> selectInventoryMatchScanList(InventoryMatchScan matchScan);
// List<RkInfoMatchVO> selectMatchScanCountList(InventoryMatchScan matchScan); List<RkInfoMatchVO> selectMatchScanCountList(InventoryMatchScan matchScan);
} }

View File

@@ -56,22 +56,22 @@ public class InventoryMatchScanServiceImpl implements InventoryMatchScanService
return mapper.selectInventoryMatchScanList(matchScan); return mapper.selectInventoryMatchScanList(matchScan);
} }
// @Override @Override
// public List<RkInfoMatchVO> selectMatchScanCountList(InventoryMatchScan param) { public List<RkInfoMatchVO> selectMatchScanCountList(InventoryMatchScan param) {
// // 状态=2只查扫描表中的数据 // 状态=2只查扫描表中的数据
// if ("2".equals(param.getStatus())) { if ("2".equals(param.getStatus())) {
// return mapper.selectOnlyFromMatchScan(param); return mapper.selectOnlyFromMatchScan(param);
// } }
// // 状态=1查询指定仓库下未被扫描的库位 // 状态=1查询指定仓库下未被扫描的库位
// else if ("1".equals(param.getStatus())) { else if ("1".equals(param.getStatus())) {
// // ✅ 根据任务ID取 sceneId再按 scene 查询“未被扫描”的库位 // ✅ 根据任务ID取 sceneId再按 scene 查询“未被扫描”的库位
// String sceneId = taskMapper.getSceneByTaskId(param.getTaskId()); String sceneId = taskMapper.getSceneByTaskId(param.getTaskId());
// return rkInfoMapper.getUnscannedPcodeByScene(sceneId, param.getTaskId()); return rkInfoMapper.getUnscannedPcodeByScene(sceneId, param.getTaskId());
// } }
// // 其它情况:返回扫描表和库存表的关联数据 // 其它情况:返回扫描表和库存表的关联数据
// else { else {
// return mapper.selectJoinRkInfo(param); return mapper.selectJoinRkInfo(param);
// } }
// } }
} }

View File

@@ -22,14 +22,14 @@ public class StatisticsController extends BaseController {
* @param taskId * @param taskId
* @return * @return
*/ */
// @GetMapping("/count") @GetMapping("/count")
// public AjaxResult conuntGetByTaskId(@RequestParam("taskId") String taskId) public AjaxResult conuntGetByTaskId(@RequestParam("taskId") String taskId)
// { {
//
// String warehouse = taskService.getWhByTaskId(taskId); String warehouse = taskService.getWhByTaskId(taskId);
//
// int count = rkInfoService.countGetByWh(warehouse); int count = rkInfoService.countGetByWh(warehouse);
//
// return AjaxResult.success(count); return AjaxResult.success(count);
// } }
} }

View File

@@ -0,0 +1,22 @@
package com.zg.project.wisdom.config;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.math.BigDecimal;
public class BigDecimalSerializer extends JsonSerializer<BigDecimal> {
@Override
public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializers)
throws IOException {
if (value == null) {
gen.writeNull();
} else {
// 保持数字类型不带引号不补0、不截断
gen.writeNumber(value.stripTrailingZeros().toPlainString());
}
}
}

View File

@@ -113,4 +113,15 @@ public class RkInfoController extends BaseController
return AjaxResult.success(stockStatistic); return AjaxResult.success(stockStatistic);
} }
/**
*
* @param pcode
* @return
*/
@GetMapping("/pcode/{pcode}")
public AjaxResult listRkInfoByPcode(@PathVariable String pcode) {
List<RkInfo> rows = rkInfoService.listRkInfoByPcode(pcode);
return AjaxResult.success(rows);
}
} }

View File

@@ -165,13 +165,6 @@ public class RkRecordController extends BaseController
return toAjax(rkRecordService.deletePreOutRecords(ids)); return toAjax(rkRecordService.deletePreOutRecords(ids));
} }
/**
* 出入库统计(同时返回)
*/
@PostMapping("/statistic")
public AjaxResult statistic(@RequestBody RkRecord query) {
return AjaxResult.success(rkRecordService.getRecordStatistic(query));
}
/** /**
* 出入库统计,返回总数 * 出入库统计,返回总数
*/ */

View File

@@ -4,6 +4,8 @@ import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.zg.project.wisdom.config.BigDecimalSerializer;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
import com.zg.framework.aspectj.lang.annotation.Excel; import com.zg.framework.aspectj.lang.annotation.Excel;
@@ -73,6 +75,7 @@ public class GysJh extends BaseEntity
/** 合同数量 */ /** 合同数量 */
@Excel(name = "合同数量") @Excel(name = "合同数量")
@JsonSerialize(using = BigDecimalSerializer.class)
private BigDecimal htQty; private BigDecimal htQty;
/** SAP订单编号 */ /** SAP订单编号 */
@@ -81,10 +84,12 @@ public class GysJh extends BaseEntity
/** 计划交货数量 */ /** 计划交货数量 */
@Excel(name = "计划交货数量") @Excel(name = "计划交货数量")
@JsonSerialize(using = BigDecimalSerializer.class)
private BigDecimal jhQty; private BigDecimal jhQty;
/** 已入库数量(累计) */ /** 已入库数量(累计) */
@Excel(name = "已入库数量") @Excel(name = "已入库数量")
@JsonSerialize(using = BigDecimalSerializer.class)
private BigDecimal realQty; private BigDecimal realQty;
/** /**

View File

@@ -1,7 +1,9 @@
package com.zg.project.wisdom.domain; package com.zg.project.wisdom.domain;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.zg.framework.web.domain.BaseEntity; import com.zg.framework.web.domain.BaseEntity;
import com.zg.framework.aspectj.lang.annotation.Excel; import com.zg.framework.aspectj.lang.annotation.Excel;
import com.zg.project.wisdom.config.BigDecimalSerializer;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
@@ -10,9 +12,6 @@ import java.util.Date;
/** /**
* 移库记录对象 move_record * 移库记录对象 move_record
*
* @author zg
* @date 2025-06-20
*/ */
public class MoveRecord extends BaseEntity { public class MoveRecord extends BaseEntity {
@@ -27,12 +26,16 @@ public class MoveRecord extends BaseEntity {
/** 移库生成的新库存IDrk_info.id用于撤销移库 */ /** 移库生成的新库存IDrk_info.id用于撤销移库 */
private Long newRkInfoId; private Long newRkInfoId;
/** ================= 新增上级移库记录ID ================= */
private Long parentMoveId;
/** 实物ID */ /** 实物ID */
@Excel(name = "实物ID") @Excel(name = "实物ID")
private String entityId; private String entityId;
/** 实际移库数量 */ /** 实际移库数量 */
@Excel(name = "移库数量") @Excel(name = "移库数量")
@JsonSerialize(using = BigDecimalSerializer.class)
private BigDecimal realQty; private BigDecimal realQty;
/** 原仓库 */ /** 原仓库 */
@@ -70,7 +73,7 @@ public class MoveRecord extends BaseEntity {
@Excel(name = "操作人名称") @Excel(name = "操作人名称")
private String movedByName; private String movedByName;
/** 操作时间(移库时间) */ /** 操作时间 */
@Excel(name = "操作时间", dateFormat = "yyyy-MM-dd HH:mm:ss") @Excel(name = "操作时间", dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date movedAt; private Date movedAt;
@@ -104,6 +107,14 @@ public class MoveRecord extends BaseEntity {
// ==================== Getter / Setter ==================== // ==================== Getter / Setter ====================
public Long getParentMoveId() {
return parentMoveId;
}
public void setParentMoveId(Long parentMoveId) {
this.parentMoveId = parentMoveId;
}
public Long getId() { public Long getId() {
return id; return id;
} }
@@ -286,6 +297,7 @@ public class MoveRecord extends BaseEntity {
.append("id", getId()) .append("id", getId())
.append("rkInfoId", getRkInfoId()) .append("rkInfoId", getRkInfoId())
.append("newRkInfoId", getNewRkInfoId()) .append("newRkInfoId", getNewRkInfoId())
.append("parentMoveId", getParentMoveId())
.append("entityId", getEntityId()) .append("entityId", getEntityId())
.append("realQty", getRealQty()) .append("realQty", getRealQty())
.append("fromCangku", getFromCangku()) .append("fromCangku", getFromCangku())
@@ -298,17 +310,7 @@ public class MoveRecord extends BaseEntity {
.append("movedBy", getMovedBy()) .append("movedBy", getMovedBy())
.append("movedByName", getMovedByName()) .append("movedByName", getMovedByName())
.append("movedAt", getMovedAt()) .append("movedAt", getMovedAt())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("isDelete", getIsDelete()) .append("isDelete", getIsDelete())
.append("fromCangkuName", getFromCangkuName())
.append("toCangkuName", getToCangkuName())
.append("xmNo", getXmNo())
.append("xmMs", getXmMs())
.append("wlMs", getWlMs())
.append("gysMc", getGysMc())
.toString(); .toString();
} }
} }

View File

@@ -3,6 +3,8 @@ package com.zg.project.wisdom.domain;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.zg.project.wisdom.config.BigDecimalSerializer;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
import com.zg.framework.aspectj.lang.annotation.Excel; import com.zg.framework.aspectj.lang.annotation.Excel;
@@ -127,10 +129,12 @@ public class RkInfo extends BaseEntity
/** 计划交货金额 */ /** 计划交货金额 */
@Excel(name = "计划交货金额") @Excel(name = "计划交货金额")
@JsonSerialize(using = BigDecimalSerializer.class)
private BigDecimal jhAmt; private BigDecimal jhAmt;
/** 合同单价 */ /** 合同单价 */
@Excel(name = "合同单价") @Excel(name = "合同单价")
@JsonSerialize(using = BigDecimalSerializer.class)
private BigDecimal htDj; private BigDecimal htDj;
/** SAP订单编号 */ /** SAP订单编号 */
@@ -143,10 +147,12 @@ public class RkInfo extends BaseEntity
/** 计划交货数量 */ /** 计划交货数量 */
@Excel(name = "计划交货数量") @Excel(name = "计划交货数量")
@JsonSerialize(using = BigDecimalSerializer.class)
private BigDecimal jhQty; private BigDecimal jhQty;
/** 合同数量 */ /** 合同数量 */
@Excel(name = "合同数量") @Excel(name = "合同数量")
@JsonSerialize(using = BigDecimalSerializer.class)
private BigDecimal htQty; private BigDecimal htQty;
/** 计量单位 */ /** 计量单位 */
@@ -155,6 +161,7 @@ public class RkInfo extends BaseEntity
/** 实际入库数量 */ /** 实际入库数量 */
@Excel(name = "实际入库数量") @Excel(name = "实际入库数量")
@JsonSerialize(using = BigDecimalSerializer.class)
private BigDecimal realQty; private BigDecimal realQty;
/** 库位码 */ /** 库位码 */

View File

@@ -5,6 +5,8 @@ import java.util.Date;
import java.util.List; import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.zg.project.wisdom.config.BigDecimalSerializer;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
import com.zg.framework.aspectj.lang.annotation.Excel; import com.zg.framework.aspectj.lang.annotation.Excel;
@@ -142,10 +144,12 @@ public class RkRecord extends BaseEntity
/** 计划交货金额 */ /** 计划交货金额 */
@Excel(name = "计划交货金额") @Excel(name = "计划交货金额")
@JsonSerialize(using = BigDecimalSerializer.class)
private BigDecimal jhAmt; private BigDecimal jhAmt;
/** 合同单价 */ /** 合同单价 */
@Excel(name = "合同单价") @Excel(name = "合同单价")
@JsonSerialize(using = BigDecimalSerializer.class)
private BigDecimal htDj; private BigDecimal htDj;
/** SAP订单编号 */ /** SAP订单编号 */
@@ -158,10 +162,12 @@ public class RkRecord extends BaseEntity
/** 计划交货数量 */ /** 计划交货数量 */
@Excel(name = "计划交货数量") @Excel(name = "计划交货数量")
@JsonSerialize(using = BigDecimalSerializer.class)
private BigDecimal jhQty; private BigDecimal jhQty;
/** 合同数量 */ /** 合同数量 */
@Excel(name = "合同数量") @Excel(name = "合同数量")
@JsonSerialize(using = BigDecimalSerializer.class)
private BigDecimal htQty; private BigDecimal htQty;
/** 计量单位 */ /** 计量单位 */
@@ -169,7 +175,8 @@ public class RkRecord extends BaseEntity
private String dw; private String dw;
/** 实际入库数量 */ /** 实际入库数量 */
@Excel(name = "实际入库数量") @Excel(name = "实际出/入库数量")
@JsonSerialize(using = BigDecimalSerializer.class)
private BigDecimal realQty; private BigDecimal realQty;
/** 库位码 */ /** 库位码 */
@@ -227,9 +234,8 @@ public class RkRecord extends BaseEntity
private Long sid; private Long sid;
/** 是否需要配送(0否,1是,2配送中,3配送完成) */ /** 是否需要配送(0否,1是,2配送中,3配送完成) */
@Excel(name = "是否需要配送(0否,1是,2配送中,3配送完成)") @Excel(name = "是否需要配送", readConverterExp = "0=否,1=是,2=配送中,3=配送完成")
private String isDelivery; private String isDelivery;
/** 封样编号1 */ /** 封样编号1 */
// @Excel(name = "封样编号1") // @Excel(name = "封样编号1")
private String fycde1; private String fycde1;

View File

@@ -1,5 +1,7 @@
package com.zg.project.wisdom.domain.vo; package com.zg.project.wisdom.domain.vo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.zg.project.wisdom.config.BigDecimalSerializer;
import com.zg.project.wisdom.domain.AuditSignature; import com.zg.project.wisdom.domain.AuditSignature;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -29,6 +31,7 @@ public class AuditSignatureVo extends AuditSignature {
private String wlNo; private String wlNo;
/** 实际入库数量 */ /** 实际入库数量 */
@JsonSerialize(using = BigDecimalSerializer.class)
private BigDecimal realQty; private BigDecimal realQty;
/** 计量单位 */ /** 计量单位 */

View File

@@ -1,6 +1,8 @@
// com.zg.project.wisdom.domain.vo.GysJhUndeliveredSummaryVO // com.zg.project.wisdom.domain.vo.GysJhUndeliveredSummaryVO
package com.zg.project.wisdom.domain.vo; package com.zg.project.wisdom.domain.vo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.zg.project.wisdom.config.BigDecimalSerializer;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal; import java.math.BigDecimal;
@@ -14,5 +16,6 @@ public class GysJhUndeliveredSummaryVO {
/** 总数量jh_qty 合计,表示剩余未到数量) */ /** 总数量jh_qty 合计,表示剩余未到数量) */
private Long totalQty; private Long totalQty;
/** 总金额ht_dj * jh_qty 合计) */ /** 总金额ht_dj * jh_qty 合计) */
@JsonSerialize(using = BigDecimalSerializer.class)
private BigDecimal amountPlan; private BigDecimal amountPlan;
} }

View File

@@ -1,5 +1,7 @@
package com.zg.project.wisdom.domain.vo; package com.zg.project.wisdom.domain.vo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.zg.project.wisdom.config.BigDecimalSerializer;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal; import java.math.BigDecimal;
@@ -17,6 +19,7 @@ public class HomeKpiVO {
private Integer monthInProjectCount; private Integer monthInProjectCount;
/** 月入库金额 */ /** 月入库金额 */
@JsonSerialize(using = BigDecimalSerializer.class)
private BigDecimal monthInAmount; private BigDecimal monthInAmount;
/** 月出库条数 */ /** 月出库条数 */
@@ -26,5 +29,6 @@ public class HomeKpiVO {
private Integer monthOutProjectCount; private Integer monthOutProjectCount;
/** 月出库金额 */ /** 月出库金额 */
@JsonSerialize(using = BigDecimalSerializer.class)
private BigDecimal monthOutAmount; private BigDecimal monthOutAmount;
} }

View File

@@ -1,5 +1,7 @@
package com.zg.project.wisdom.domain.vo; package com.zg.project.wisdom.domain.vo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.zg.project.wisdom.config.BigDecimalSerializer;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal; import java.math.BigDecimal;
@@ -8,6 +10,7 @@ public class PlanToMtdVO {
private String wlNo; // 物料号 private String wlNo; // 物料号
private String wlMs; // 物料描述 private String wlMs; // 物料描述
private String dw; // 单位 private String dw; // 单位
@JsonSerialize(using = BigDecimalSerializer.class)
private BigDecimal htDj; // 合同单价 private BigDecimal htDj; // 合同单价
} }

View File

@@ -1,5 +1,7 @@
package com.zg.project.wisdom.domain.vo; package com.zg.project.wisdom.domain.vo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.zg.project.wisdom.config.BigDecimalSerializer;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal; import java.math.BigDecimal;
@@ -14,12 +16,14 @@ public class StockStatisticGroupVO {
private String groupValue; private String groupValue;
/** 总金额 */ /** 总金额 */
@JsonSerialize(using = BigDecimalSerializer.class)
private BigDecimal totalAmount; private BigDecimal totalAmount;
/** 使用库位数 */ /** 使用库位数 */
private Integer locationCount; private Integer locationCount;
/** 总数量 */ /** 总数量 */
@JsonSerialize(using = BigDecimalSerializer.class)
private BigDecimal totalQuantity; private BigDecimal totalQuantity;
/** 项目数(去重 xm_no */ /** 项目数(去重 xm_no */

View File

@@ -1,5 +1,7 @@
package com.zg.project.wisdom.domain.vo; package com.zg.project.wisdom.domain.vo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.zg.project.wisdom.config.BigDecimalSerializer;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal; import java.math.BigDecimal;
@@ -14,6 +16,7 @@ public class StockStatisticVO {
private Integer locationCount; private Integer locationCount;
/** 库存总数量 */ /** 库存总数量 */
@JsonSerialize(using = BigDecimalSerializer.class)
private BigDecimal totalQuantity; private BigDecimal totalQuantity;
/** 项目总数(去重 xm_no */ /** 项目总数(去重 xm_no */

View File

@@ -59,4 +59,21 @@ public interface MoveRecordMapper
* @return 结果 * @return 结果
*/ */
void insertMoveRecord(MoveRecord moveRecord); void insertMoveRecord(MoveRecord moveRecord);
/**
* 根据入库信息id查询移库记录id
*
* @param rkInfoId 入库信息id
* @return 移库记录id
*/
Long selectLastMoveIdByRkInfoId(Long rkInfoId);
/**
* 根据移库记录id查询子移库记录数量
*
* @param moveRecordId 移库记录id
* @return 子移库记录数量
*/
int countByParentMoveId(Long moveRecordId);
} }

View File

@@ -3,6 +3,9 @@ package com.zg.project.wisdom.mapper;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import com.zg.project.inventory.domain.vo.PcdeCntVO;
import com.zg.project.inventory.domain.vo.RkInfoMatchVO;
import com.zg.project.wisdom.domain.RkInfo; import com.zg.project.wisdom.domain.RkInfo;
import com.zg.project.wisdom.domain.vo.StockStatisticVO; import com.zg.project.wisdom.domain.vo.StockStatisticVO;
import io.lettuce.core.dynamic.annotation.Param; import io.lettuce.core.dynamic.annotation.Param;
@@ -108,4 +111,48 @@ public interface RkInfoMapper
*/ */
StockStatisticVO selectStockStatisticByCondition(RkInfo query); StockStatisticVO selectStockStatisticByCondition(RkInfo query);
/**
* 1⃣ 正常匹配的数据
* 扫描到 & 当前库存中 & 属于当前场景
*/
List<RkInfo> getByPcodeIdList(@Param("list") List<String> pcdeIds,
@Param("sceneId") String sceneId);
/**
* 2⃣ 未盘点的数据
* 当前库存中 & 未出现在扫描结果中
*/
List<RkInfo> getMissedPcodeIds(@Param("list") List<String> pcdeIds,
@Param("sceneId") String sceneId);
/**
* 3⃣ 异常数据(批量)
* 扫描到,但在当前库存中不存在
*/
List<String> getNotExistsPcodeIds(@Param("list") List<String> pcdeIds,
@Param("sceneId") String sceneId);
/**
* 图表统计:每个库位有多少个货物
* @param ids
* @return
*/
List<PcdeCntVO> selectPcdeCntFromRkInfo(List<String> ids);
/**
* 根据所属仓库查询所有的库位号和库位对应的货物数量
* @param
* @return
*/
List<RkInfoMatchVO> getUnscannedPcodeByScene(@org.apache.ibatis.annotations.Param("sceneId") String sceneId,
@org.apache.ibatis.annotations.Param("taskId") String taskId);
/**
* 获取指定仓库的盘点数据
* @param warehouse
* @return
*/
int countGetByWh(@org.apache.ibatis.annotations.Param("warehouse") String warehouse);
List<RkInfo> listRkInfoByPcode(String pcode);
} }

View File

@@ -123,15 +123,6 @@ public interface RkRecordMapper
*/ */
RkRecord selectRkRecordByRkInfoId(@Param("rkInfoId") Long rkInfoId); RkRecord selectRkRecordByRkInfoId(@Param("rkInfoId") Long rkInfoId);
/**
* 入库统计
*/
StockStatisticVO selectInRecordStatistic(RkRecord query);
/**
* 出库统计
*/
StockStatisticVO selectOutRecordStatistic(RkRecord query);
/** /**
* 借出入库 * 借出入库
@@ -154,5 +145,4 @@ public interface RkRecordMapper
* */ * */
StockStatisticVO selectRecordStatisticByCondition(RkRecord query); StockStatisticVO selectRecordStatisticByCondition(RkRecord query);
} }

View File

@@ -1,6 +1,9 @@
package com.zg.project.wisdom.service; package com.zg.project.wisdom.service;
import java.util.List; import java.util.List;
import com.zg.project.inventory.domain.dto.QueryDTO;
import com.zg.project.inventory.domain.vo.ChartDataVO;
import com.zg.project.wisdom.domain.RkInfo; import com.zg.project.wisdom.domain.RkInfo;
import com.zg.project.wisdom.domain.vo.StockStatisticVO; import com.zg.project.wisdom.domain.vo.StockStatisticVO;
@@ -66,5 +69,31 @@ public interface IRkInfoService
StockStatisticVO getStockStatistic(RkInfo query); StockStatisticVO getStockStatistic(RkInfo query);
/**
* 盘点开始匹配
* @param dto
* @return
*/
void matchWithStatus(QueryDTO dto);
/**
* 图表统计:每个库位有多少个货物
* @param dto
* @return
*/
ChartDataVO matchWithAll(QueryDTO dto);
/**
* 统计指定仓库的库存数量
* @param warehouse
* @return
*/
int countGetByWh(String warehouse);
/**
* 按库位查询货物数量
* @param pcode
* @return
*/
List<RkInfo> listRkInfoByPcode(String pcode);
} }

View File

@@ -93,8 +93,6 @@ public interface IRkRecordService
*/ */
int deletePreOutRecords(Long[] ids); int deletePreOutRecords(Long[] ids);
RecordStatisticVO getRecordStatistic(RkRecord query);
/** /**
* 出入库总数统计 * 出入库总数统计
*/ */

View File

@@ -120,7 +120,6 @@ public class MoveRecordServiceImpl implements IMoveRecordService
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void processMove(MoveRequestDTO dto) { public void processMove(MoveRequestDTO dto) {
/* ====================== 0. 基础校验 ====================== */
if (dto == null || dto.getFromRkId() == null) { if (dto == null || dto.getFromRkId() == null) {
throw new ServiceException("原库存ID不能为空"); throw new ServiceException("原库存ID不能为空");
} }
@@ -151,16 +150,18 @@ public class MoveRecordServiceImpl implements IMoveRecordService
String userId = String.valueOf(SecurityUtils.getUserId()); String userId = String.valueOf(SecurityUtils.getUserId());
Date now = DateUtils.getNowDate(); Date now = DateUtils.getNowDate();
/* ====================== 3. 原库存快照 ====================== */ /* ====================== 3. 查询上一条移库记录 ====================== */
Long lastMoveId = moveRecordMapper.selectLastMoveIdByRkInfoId(dto.getFromRkId());
/* ====================== 4. 原库存快照 ====================== */
RkInfo snapshot = new RkInfo(); RkInfo snapshot = new RkInfo();
BeanUtils.copyProperties(original, snapshot); BeanUtils.copyProperties(original, snapshot);
/* ====================== 4. 全量移库(不拆分) ====================== */ /* ====================== 5. 全量移库 ====================== */
if (dto.getTargets().size() == 1 && moveTotalQty.compareTo(originQty) == 0) { if (dto.getTargets().size() == 1 && moveTotalQty.compareTo(originQty) == 0) {
MoveTargetItem target = dto.getTargets().get(0); MoveTargetItem target = dto.getTargets().get(0);
// 4.1 更新原库存(仅换库位)
original.setCangku(target.getToCangku()); original.setCangku(target.getToCangku());
original.setPcode(target.getToPcode()); original.setPcode(target.getToPcode());
original.setTrayCode(target.getToTrayCode()); original.setTrayCode(target.getToTrayCode());
@@ -169,10 +170,13 @@ public class MoveRecordServiceImpl implements IMoveRecordService
original.setUpdateTime(now); original.setUpdateTime(now);
rkInfoMapper.updateRkInfo(original); rkInfoMapper.updateRkInfo(original);
// 4.2 移库流水(全量移库,无新库存)
MoveRecord record = new MoveRecord(); MoveRecord record = new MoveRecord();
record.setRkInfoId(snapshot.getId()); record.setRkInfoId(snapshot.getId());
record.setNewRkInfoId(null); // ✅ 关键:全量移库没有新库存 record.setNewRkInfoId(null);
// ★★ 新增关键 ★★
record.setParentMoveId(lastMoveId);
record.setEntityId(snapshot.getEntityId()); record.setEntityId(snapshot.getEntityId());
record.setRealQty(originQty); record.setRealQty(originQty);
@@ -198,16 +202,14 @@ public class MoveRecordServiceImpl implements IMoveRecordService
return; return;
} }
/* ====================== 5. 部分移库(拆分库存) ====================== */ /* ====================== 6. 部分移库 ====================== */
// 5.1 原库存扣减数量
original.setRealQty(originQty.subtract(moveTotalQty)); original.setRealQty(originQty.subtract(moveTotalQty));
original.setHasMoved("1"); original.setHasMoved("1");
original.setUpdateBy(userId); original.setUpdateBy(userId);
original.setUpdateTime(now); original.setUpdateTime(now);
rkInfoMapper.updateRkInfo(original); rkInfoMapper.updateRkInfo(original);
// 5.2 生成新库存 + 移库流水
for (MoveTargetItem target : dto.getTargets()) { for (MoveTargetItem target : dto.getTargets()) {
/* ---------- 新库存 ---------- */ /* ---------- 新库存 ---------- */
@@ -227,10 +229,14 @@ public class MoveRecordServiceImpl implements IMoveRecordService
rkInfoMapper.insertRkInfo(newInfo); rkInfoMapper.insertRkInfo(newInfo);
/* ---------- 移库流水(重点) ---------- */ /* ---------- 移库流水 ---------- */
MoveRecord record = new MoveRecord(); MoveRecord record = new MoveRecord();
record.setRkInfoId(snapshot.getId()); // 原库存 record.setRkInfoId(snapshot.getId());
record.setNewRkInfoId(newInfo.getId()); // ✅ 关键新库存ID record.setNewRkInfoId(newInfo.getId());
// ★★ 新增关键 ★★
record.setParentMoveId(lastMoveId);
record.setEntityId(snapshot.getEntityId()); record.setEntityId(snapshot.getEntityId());
record.setRealQty(target.getRealQty()); record.setRealQty(target.getRealQty());
@@ -273,10 +279,16 @@ public class MoveRecordServiceImpl implements IMoveRecordService
throw new ServiceException("移库记录不存在或已撤销"); throw new ServiceException("移库记录不存在或已撤销");
} }
/* ====================== 2. 关键:校验是否有子移库 ====================== */
int childCount = moveRecordMapper.countByParentMoveId(moveRecordId);
if (childCount > 0) {
throw new ServiceException("该移库已产生后续移库,请先撤销后续移库");
}
Long originRkInfoId = record.getRkInfoId(); Long originRkInfoId = record.getRkInfoId();
Long newRkInfoId = record.getNewRkInfoId(); Long newRkInfoId = record.getNewRkInfoId();
/* ====================== 2. 查询原库存 ====================== */ /* ====================== 3. 查询原库存 ====================== */
RkInfo origin = rkInfoMapper.selectRkInfoById(originRkInfoId); RkInfo origin = rkInfoMapper.selectRkInfoById(originRkInfoId);
if (origin == null || "1".equals(origin.getIsDelete())) { if (origin == null || "1".equals(origin.getIsDelete())) {
throw new ServiceException("原库存不存在或已删除,无法撤销"); throw new ServiceException("原库存不存在或已删除,无法撤销");
@@ -285,12 +297,11 @@ public class MoveRecordServiceImpl implements IMoveRecordService
String userId = String.valueOf(SecurityUtils.getUserId()); String userId = String.valueOf(SecurityUtils.getUserId());
Date now = DateUtils.getNowDate(); Date now = DateUtils.getNowDate();
/* ====================== 3. 分情况处理 ====================== */ /* ====================== 4. 分情况处理 ====================== */
// ---------- 情况一:全量移库 ---------- // -------- 全量移库 --------
if (newRkInfoId == null) { if (newRkInfoId == null) {
// 回滚库位
origin.setCangku(record.getFromCangku()); origin.setCangku(record.getFromCangku());
origin.setPcode(record.getFromPcode()); origin.setPcode(record.getFromPcode());
origin.setTrayCode(record.getFromTrayCode()); origin.setTrayCode(record.getFromTrayCode());
@@ -299,25 +310,31 @@ public class MoveRecordServiceImpl implements IMoveRecordService
origin.setUpdateTime(now); origin.setUpdateTime(now);
rkInfoMapper.updateRkInfo(origin); rkInfoMapper.updateRkInfo(origin);
} }
// ---------- 情况二:部分移库 ---------- // -------- 部分移库 --------
else { else {
/* 3.1 原库存回补数量 */
BigDecimal qty = record.getRealQty(); BigDecimal qty = record.getRealQty();
if (qty == null || qty.compareTo(BigDecimal.ZERO) <= 0) { if (qty == null || qty.compareTo(BigDecimal.ZERO) <= 0) {
throw new ServiceException("移库数量异常,无法撤销"); throw new ServiceException("移库数量异常,无法撤销");
} }
// 回补数量
origin.setRealQty(origin.getRealQty().add(qty)); origin.setRealQty(origin.getRealQty().add(qty));
// 恢复位置
origin.setCangku(record.getFromCangku());
origin.setPcode(record.getFromPcode());
origin.setTrayCode(record.getFromTrayCode());
origin.setHasMoved("0"); origin.setHasMoved("0");
origin.setUpdateBy(userId); origin.setUpdateBy(userId);
origin.setUpdateTime(now); origin.setUpdateTime(now);
origin.setHasMoved("0");
rkInfoMapper.updateRkInfo(origin); rkInfoMapper.updateRkInfo(origin);
/* 3.2 删除移库生成的新库存 */ // 删除新库存
RkInfo newInfo = rkInfoMapper.selectRkInfoById(newRkInfoId); RkInfo newInfo = rkInfoMapper.selectRkInfoById(newRkInfoId);
if (newInfo != null && !"1".equals(newInfo.getIsDelete())) { if (newInfo != null && !"1".equals(newInfo.getIsDelete())) {
newInfo.setIsDelete("1"); newInfo.setIsDelete("1");
@@ -327,10 +344,11 @@ public class MoveRecordServiceImpl implements IMoveRecordService
} }
} }
/* ====================== 4. 标记移库记录已撤销 ====================== */ /* ====================== 5. 标记移库记录已撤销 ====================== */
record.setIsDelete("1"); record.setIsDelete("1");
record.setUpdateBy(userId); record.setUpdateBy(userId);
record.setUpdateTime(now); record.setUpdateTime(now);
moveRecordMapper.updateMoveRecord(record); moveRecordMapper.updateMoveRecord(record);
} }
} }

View File

@@ -598,6 +598,7 @@ public class RkBillServiceImpl implements IRkBillService
record.setOperationTime(bill.getOperationTime()); record.setOperationTime(bill.getOperationTime());
record.setOperator(bill.getOperator()); record.setOperator(bill.getOperator());
record.setTeamCode(bill.getTeamCode()); record.setTeamCode(bill.getTeamCode());
record.setIsDelivery(bill.getIsDelivery());
/* ================== ✅ 关键修复 ================== */ /* ================== ✅ 关键修复 ================== */
// 仓库必须来源于【库存快照】,而不是 bill // 仓库必须来源于【库存快照】,而不是 bill

View File

@@ -1,7 +1,21 @@
package com.zg.project.wisdom.service.impl; package com.zg.project.wisdom.service.impl;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import com.zg.common.exception.ServiceException;
import com.zg.common.utils.DateUtils; import com.zg.common.utils.DateUtils;
import com.zg.common.utils.StringUtils;
import com.zg.project.inventory.AutoInventory.mapper.InventoryMatchScanMapper;
import com.zg.project.inventory.Task.mapper.InventoryTaskMapper;
import com.zg.project.inventory.domain.dto.QueryDTO;
import com.zg.project.inventory.domain.entity.InventoryMatchScan;
import com.zg.project.inventory.domain.vo.ChartDataVO;
import com.zg.project.inventory.domain.vo.PcdeCntVO;
import com.zg.project.wisdom.domain.vo.StockStatisticVO; import com.zg.project.wisdom.domain.vo.StockStatisticVO;
import com.zg.project.wisdom.mapper.RkRecordMapper; import com.zg.project.wisdom.mapper.RkRecordMapper;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -26,6 +40,12 @@ public class RkInfoServiceImpl implements IRkInfoService
@Autowired @Autowired
private RkRecordMapper rkRecordMapper; private RkRecordMapper rkRecordMapper;
@Autowired
private InventoryTaskMapper taskMapper;
@Autowired
private InventoryMatchScanMapper matchScanMapper;
/** /**
* 查询库存单据明细 * 查询库存单据明细
* *
@@ -112,4 +132,142 @@ public class RkInfoServiceImpl implements IRkInfoService
public StockStatisticVO getStockStatistic(RkInfo query) { public StockStatisticVO getStockStatistic(RkInfo query) {
return rkInfoMapper.selectStockStatisticByCondition(query); return rkInfoMapper.selectStockStatisticByCondition(query);
} }
@Override
@Transactional(rollbackFor = Exception.class)
public void matchWithStatus(QueryDTO dto) {
/* ================== 1. 基础参数校验 ================== */
List<String> pcdeIds = dto.getIds();
if (pcdeIds == null || pcdeIds.isEmpty()) {
return;
}
String taskId = dto.getTaskId();
String sceneId = taskMapper.selectSceneIdById(taskId);
if (sceneId == null || sceneId.trim().isEmpty()) {
throw new ServiceException("匹配失败缺少场景ID");
}
int scanType = dto.getScanType() != null ? dto.getScanType() : 0;
String deviceId = dto.getDeviceId();
if (scanType == 1 && StringUtils.isBlank(deviceId)) {
throw new ServiceException("自动盘点必须传递设备ID");
}
/* ================== 2. 三类盘点数据匹配 ================== */
// 1⃣ 正常:扫描到 & 当前库存存在
List<RkInfo> matchedAll =
rkInfoMapper.getByPcodeIdList(pcdeIds, sceneId);
matchedAll.forEach(r -> r.setStatus("0"));
// 2⃣ 未盘:库存中存在但未扫描
List<RkInfo> missedAll =
rkInfoMapper.getMissedPcodeIds(pcdeIds, sceneId);
missedAll.forEach(r -> r.setStatus("1"));
// 3⃣ 异常:扫描到但库存中不存在(批量)
List<String> errorIds =
rkInfoMapper.getNotExistsPcodeIds(pcdeIds, sceneId);
List<RkInfo> errorAll = errorIds.stream().map(id -> {
RkInfo r = new RkInfo();
r.setPcodeId(id);
r.setStatus("2");
return r;
}).collect(Collectors.toList());
/* ================== 3. 扫描结果落库 ================== */
String tmeStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
List<InventoryMatchScan> toSave = new ArrayList<>();
for (RkInfo r : matchedAll) {
toSave.add(buildScanRecord(taskId, r.getPcode(), "0", deviceId, tmeStr, scanType));
}
for (RkInfo r : missedAll) {
toSave.add(buildScanRecord(taskId, r.getPcode(), "1", deviceId, tmeStr, scanType));
}
for (RkInfo r : errorAll) {
toSave.add(buildScanRecord(taskId, r.getPcodeId(), "2", deviceId, tmeStr, scanType));
}
if (!toSave.isEmpty()) {
matchScanMapper.insertBatch(toSave);
}
/* ================== 4. 更新任务状态 ================== */
taskMapper.updateStatus(taskId, "1");
}
/**
* 封装一个盘点扫描记录
*
* @param taskId 任务 ID
* @param pcode 库位编码 ID
* @param status 盘点状态0=匹配成功1=未盘点2=错误)
* @param deviceId 设备 ID自动盘点时才有
* @param tme 扫描时间
* @param scanType 扫描类型0=手动盘点1=自动盘点)
* @return 封装好的 InventoryMatchScan 对象
*/
private InventoryMatchScan buildScanRecord(String taskId, String pcode, String status,
String deviceId, String tme, int scanType) {
InventoryMatchScan record = new InventoryMatchScan();
record.setPcode(pcode);
record.setTaskId(taskId);
record.setStatus(status);
// 自动盘点时才保存设备 ID
if (scanType == 1 && deviceId != null) {
record.setDeviceId(deviceId);
}
record.setTme(tme);
record.setScanType(scanType);
return record;
}
/**
* 图表统计:每个库位有多少个货物
* @param dto
* @return
*/
@Override
public ChartDataVO matchWithAll(QueryDTO dto) {
List<String> ids = dto.getIds();
if (ids == null || ids.isEmpty()) {
return new ChartDataVO(Collections.emptyList(),
Collections.emptyList(),
0L);
}
List<PcdeCntVO> rows = rkInfoMapper.selectPcdeCntFromRkInfo(ids);
List<String> pcdeList = new ArrayList<>(rows.size());
List<Long> fycdeCntList = new ArrayList<>(rows.size());
for (PcdeCntVO r : rows) {
pcdeList.add(r.getPcde());
fycdeCntList.add(r.getCnt());
}
return new ChartDataVO(pcdeList, fycdeCntList, (long) rows.size());
}
@Override
public int countGetByWh(String warehouse) {
return rkInfoMapper.countGetByWh(warehouse);
}
@Override
public List<RkInfo> listRkInfoByPcode(String pcode) {
return rkInfoMapper.listRkInfoByPcode(pcode);
}
} }

View File

@@ -795,14 +795,6 @@ public class RkRecordServiceImpl implements IRkRecordService
return deleteCount; return deleteCount;
} }
@Override
public RecordStatisticVO getRecordStatistic(RkRecord query) {
RecordStatisticVO vo = new RecordStatisticVO();
vo.setInStatistic(rkRecordMapper.selectInRecordStatistic(query));
vo.setOutStatistic(rkRecordMapper.selectOutRecordStatistic(query));
return vo;
}
@Override @Override

View File

@@ -0,0 +1,43 @@
package com.zg.project.wisdom.utils;
import java.math.BigDecimal;
import java.math.RoundingMode;
public class DecimalUtil {
private DecimalUtil() {
}
/**
* 核心方法:去除多余小数 0不补、不截
*
* @param value BigDecimal
* @return String用于返回给前端 / 导出 / 业务使用)
*/
public static String toPlain(BigDecimal value) {
if (value == null) {
return null;
}
return value.stripTrailingZeros().toPlainString();
}
/**
* 用于数值计算后再次规范化
*/
public static BigDecimal normalize(BigDecimal value) {
if (value == null) {
return null;
}
return value.stripTrailingZeros();
}
/**
* 字符串安全转 BigDecimal避免 double 精度问题)
*/
public static BigDecimal parse(String value) {
if (value == null || value.trim().isEmpty()) {
return null;
}
return new BigDecimal(value.trim());
}
}

View File

@@ -4,6 +4,11 @@
<mapper namespace="com.zg.project.inventory.AutoInventory.mapper.InventoryMatchScanMapper"> <mapper namespace="com.zg.project.inventory.AutoInventory.mapper.InventoryMatchScanMapper">
<!--
批量插入盘点匹配扫描记录
用于将一批扫描记录批量插入到库存匹配扫描表中
@param list 扫描记录列表包含任务ID、设备ID、物资编码、时间、扫描类型和状态
-->
<insert id="insertBatch"> <insert id="insertBatch">
INSERT INTO inventory_match_scan (task_id, device_id, pcode, tme, scan_type, status) INSERT INTO inventory_match_scan (task_id, device_id, pcode, tme, scan_type, status)
VALUES VALUES
@@ -12,16 +17,33 @@
</foreach> </foreach>
</insert> </insert>
<!--
查询所有盘点匹配扫描记录
获取库存匹配扫描表中的所有记录
@return InventoryMatchScan 扫描记录实体列表
-->
<select id="getAll" resultType="com.zg.project.inventory.domain.entity.InventoryMatchScan"> <select id="getAll" resultType="com.zg.project.inventory.domain.entity.InventoryMatchScan">
SELECT * FROM inventory_match_scan SELECT * FROM inventory_match_scan
</select> </select>
<!--
查询所有库存匹配扫描记录并关联SOD表
左连接SOD表获取与扫描记录匹配的物资信息仅返回剩余数量大于0的记录
@return Sod 物资信息实体列表
-->
<select id="getAllSod" resultType="com.zg.project.inventory.domain.entity.Sod"> <select id="getAllSod" resultType="com.zg.project.inventory.domain.entity.Sod">
SELECT * FROM inventory_match_scan i SELECT * FROM inventory_match_scan i
LEFT JOIN sod s ON i.pcde = s.fycde_1 LEFT JOIN sod s ON i.pcde = s.fycde_1
WHERE s.rmn > 0 WHERE s.rmn > 0
</select> </select>
<!--
按任务统计物资编码数量
根据任务名称和状态筛选扫描记录关联SOD表统计每个物资编码的出现次数仅统计剩余数量大于0的物资
@param taskName 任务名称(模糊查询,可选)
@param status 扫描状态(可选)
@return PcdeCountVO 物资编码统计信息,包含物资编码和出现次数
-->
<select id="getPcdeCountByTask" resultType="com.zg.project.inventory.domain.vo.PcdeCountVO"> <select id="getPcdeCountByTask" resultType="com.zg.project.inventory.domain.vo.PcdeCountVO">
SELECT SELECT
s.pcde, s.pcde,
@@ -43,6 +65,14 @@
GROUP BY s.pcde GROUP BY s.pcde
</select> </select>
<!--
按任务名称分组查询扫描历史记录(分页)
根据多个条件筛选扫描记录,按任务名称分组,返回每个任务的最新时间和扫描类型,支持分页查询
@param dto 查询条件对象包含设备ID、任务名称、物资编码、时间范围、扫描类型和状态
@param limit 每页记录数
@param offset 偏移量
@return InventoryMatchScanSimpleVO 扫描记录简单视图列表
-->
<select id="getGroupedHistoryList" resultType="com.zg.project.inventory.domain.vo.InventoryMatchScanSimpleVO"> <select id="getGroupedHistoryList" resultType="com.zg.project.inventory.domain.vo.InventoryMatchScanSimpleVO">
SELECT SELECT
task_name AS taskName, task_name AS taskName,
@@ -75,6 +105,12 @@
LIMIT #{limit} OFFSET #{offset} LIMIT #{limit} OFFSET #{offset}
</select> </select>
<!--
统计分组后的任务数量
根据查询条件统计不同任务名称的数量,用于分页查询的总数计算
@param dto 查询条件对象包含设备ID、任务名称、物资编码、时间范围、扫描类型和状态
@return int 任务名称数量
-->
<select id="countGroupedHistory" resultType="int"> <select id="countGroupedHistory" resultType="int">
SELECT COUNT(DISTINCT task_name) SELECT COUNT(DISTINCT task_name)
FROM inventory_match_scan FROM inventory_match_scan
@@ -101,6 +137,13 @@
</where> </where>
</select> </select>
<!--
根据任务名称查询扫描记录及关联的SOD物资信息
左连接SOD表获取物资详细信息支持按任务名称和状态筛选当状态不为2时仅返回剩余数量大于0的记录
@param taskName 任务名称(模糊查询,可选)
@param status 扫描状态可选当不为2时会额外筛选rmn>0的记录
@return InventoryMatchScanVO 扫描记录详细信息列表,包含扫描信息和物资信息
-->
<select id="getByTaskName" resultType="com.zg.project.inventory.domain.vo.InventoryMatchScanVO"> <select id="getByTaskName" resultType="com.zg.project.inventory.domain.vo.InventoryMatchScanVO">
SELECT SELECT
i.id, i.id,
@@ -132,6 +175,12 @@
</if> </if>
</select> </select>
<!--
条件查询盘点匹配扫描记录列表(多表关联)
关联入库信息表和盘点任务表,获取完整的扫描记录信息,支持多个条件筛选并按时间倒序排列
@param param 查询条件对象包含任务ID、设备ID、物资编码、状态、扫描类型和时间
@return InventoryMatchScan 扫描记录实体列表
-->
<select id="selectInventoryMatchScanList" <select id="selectInventoryMatchScanList"
resultType="com.zg.project.inventory.domain.entity.InventoryMatchScan" resultType="com.zg.project.inventory.domain.entity.InventoryMatchScan"
parameterType="com.zg.project.inventory.domain.entity.InventoryMatchScan"> parameterType="com.zg.project.inventory.domain.entity.InventoryMatchScan">
@@ -171,6 +220,12 @@
ORDER BY i.tme DESC ORDER BY i.tme DESC
</select> </select>
<!--
仅从扫描表中查询物资编码(用于匹配对比)
根据条件查询扫描记录中的物资编码,实际数量字段置空,用于与入库信息进行匹配对比
@param param 查询条件对象包含任务ID、设备ID和状态
@return RkInfoMatchVO 入库信息匹配视图列表包含物资编码和实际数量NULL
-->
<select id="selectOnlyFromMatchScan" <select id="selectOnlyFromMatchScan"
parameterType="InventoryMatchScan" parameterType="InventoryMatchScan"
resultType="com.zg.project.inventory.domain.vo.RkInfoMatchVO"> resultType="com.zg.project.inventory.domain.vo.RkInfoMatchVO">
@@ -192,6 +247,12 @@
ORDER BY i.tme DESC ORDER BY i.tme DESC
</select> </select>
<!--
关联入库信息查询物资的实际入库数量
根据扫描表中的物资编码,查询入库信息表中的实际入库数量汇总,用于盘点数量对比
@param param 查询条件对象包含任务ID、设备ID和状态
@return RkInfoMatchVO 入库信息匹配视图列表,包含物资编码和实际入库数量汇总
-->
<select id="selectJoinRkInfo" <select id="selectJoinRkInfo"
parameterType="InventoryMatchScan" parameterType="InventoryMatchScan"
resultType="com.zg.project.inventory.domain.vo.RkInfoMatchVO"> resultType="com.zg.project.inventory.domain.vo.RkInfoMatchVO">

View File

@@ -12,6 +12,9 @@
<!-- 关键字段 --> <!-- 关键字段 -->
<result property="rkInfoId" column="rk_info_id"/> <result property="rkInfoId" column="rk_info_id"/>
<result property="newRkInfoId" column="new_rk_info_id"/> <result property="newRkInfoId" column="new_rk_info_id"/>
<result property="parentMoveId" column="parent_move_id"/>
<result property="entityId" column="entity_id"/> <result property="entityId" column="entity_id"/>
<!-- 数量 --> <!-- 数量 -->
@@ -55,6 +58,10 @@
id, id,
rk_info_id, rk_info_id,
new_rk_info_id, new_rk_info_id,
-- ★★★ 新增字段 ★★★
parent_move_id,
entity_id, entity_id,
real_qty, real_qty,
from_cangku, from_cangku,
@@ -82,6 +89,9 @@
INSERT INTO move_record ( INSERT INTO move_record (
rk_info_id, rk_info_id,
new_rk_info_id, new_rk_info_id,
parent_move_id,
entity_id, entity_id,
real_qty, real_qty,
from_cangku, from_cangku,
@@ -101,6 +111,9 @@
) VALUES ( ) VALUES (
#{rkInfoId}, #{rkInfoId},
#{newRkInfoId}, #{newRkInfoId},
#{parentMoveId},
#{entityId}, #{entityId},
#{realQty}, #{realQty},
#{fromCangku}, #{fromCangku},
@@ -172,6 +185,9 @@
<set> <set>
<if test="rkInfoId != null">rk_info_id = #{rkInfoId},</if> <if test="rkInfoId != null">rk_info_id = #{rkInfoId},</if>
<if test="newRkInfoId != null">new_rk_info_id = #{newRkInfoId},</if> <if test="newRkInfoId != null">new_rk_info_id = #{newRkInfoId},</if>
<if test="parentMoveId != null">parent_move_id = #{parentMoveId},</if>
<if test="entityId != null">entity_id = #{entityId},</if> <if test="entityId != null">entity_id = #{entityId},</if>
<if test="realQty != null">real_qty = #{realQty},</if> <if test="realQty != null">real_qty = #{realQty},</if>
<if test="fromCangku != null">from_cangku = #{fromCangku},</if> <if test="fromCangku != null">from_cangku = #{fromCangku},</if>
@@ -203,4 +219,20 @@
</foreach> </foreach>
</delete> </delete>
<select id="selectLastMoveIdByRkInfoId" resultType="java.lang.Long">
SELECT id
FROM move_record
WHERE new_rk_info_id = #{rkInfoId}
AND is_delete = '0'
ORDER BY create_time DESC
LIMIT 1
</select>
<select id="countByParentMoveId" resultType="int">
SELECT COUNT(1)
FROM move_record
WHERE parent_move_id = #{parentMoveId}
AND is_delete = '0'
</select>
</mapper> </mapper>

View File

@@ -389,5 +389,116 @@
AND is_delete = '0' AND is_delete = '0'
</update> </update>
<!-- ========================= 1⃣ 正常匹配 ========================= -->
<select id="getByPcodeIdList" resultMap="RkInfoResult">
SELECT
ri.*
FROM rk_info ri
JOIN pcde_detail pd ON ri.pcode_id = pd.encoded_id
WHERE ri.is_delete = '0'
AND ri.is_chuku = '0'
AND pd.is_delete = '0'
AND pd.scene = #{sceneId}
AND ri.pcode_id IN
<foreach collection="pcdeIds" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
<!-- ========================= 2⃣ 未盘点 ========================= -->
<select id="getMissedPcodeIds" resultMap="RkInfoResult">
SELECT
ri.*
FROM rk_info ri
JOIN pcde_detail pd ON ri.pcode_id = pd.encoded_id
WHERE ri.is_delete = '0'
AND ri.is_chuku = '0'
AND pd.is_delete = '0'
AND pd.scene = #{sceneId}
<if test="pcdeIds != null and pcdeIds.size() > 0">
AND ri.pcode_id NOT IN
<foreach collection="pcdeIds" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</if>
</select>
<!-- ========================= 3⃣ 异常(不存在) ========================= -->
<select id="getNotExistsPcodeIds" resultType="java.lang.String">
SELECT t.pcode_id
FROM (
<foreach collection="pcdeIds" item="id" separator="UNION ALL">
SELECT #{id} AS pcode_id
</foreach>
) t
LEFT JOIN (
SELECT ri.pcode_id
FROM rk_info ri
JOIN pcde_detail pd ON ri.pcode_id = pd.encoded_id
WHERE ri.is_delete = '0'
AND ri.is_chuku = '0'
AND pd.is_delete = '0'
AND pd.scene = #{sceneId}
) s ON t.pcode_id = s.pcode_id
WHERE s.pcode_id IS NULL
</select>
<select id="selectPcdeCntFromRkInfo" resultType="com.zg.project.inventory.domain.vo.PcdeCntVO">
SELECT pcode AS pcde,
COUNT(*) AS cnt
FROM rk_info
WHERE pcode_id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
GROUP BY pcode
</select>
<select id="getUnscannedPcodeByScene"
resultType="com.zg.project.inventory.domain.vo.RkInfoMatchVO">
SELECT
r.pcode AS rkPcode,
COALESCE(SUM(r.real_qty), 0) AS realQty
FROM pcde_detail d
JOIN rk_info r ON r.pcode = d.pcode
LEFT JOIN (
SELECT DISTINCT pcode
FROM inventory_match_scan
WHERE task_id = #{taskId}
AND status = '0'
) s ON s.pcode = r.pcode
WHERE (d.is_delete IS NULL OR d.is_delete = '0')
AND d.scene = #{sceneId}
AND r.is_chuku = '0'
AND s.pcode IS NULL
GROUP BY r.pcode
ORDER BY MAX(r.create_time) DESC
</select>
<select id="countGetByWh" resultType="java.lang.Integer" parameterType="java.lang.String">
SELECT COUNT(1) FROM rk_info
WHERE is_delete = '0'
AND cangku = #{warehouse}
AND is_chuku = '0'
</select>
<select id="listRkInfoByPcode"
parameterType="string"
resultMap="RkInfoResult">
SELECT
t.*,
wh.warehouse_name AS cangku_name,
wh.parent_warehouse_code AS parent_warehouse_code,
wh.parent_warehouse_name AS parent_warehouse_name,
wh.warehouse_code AS warehouse_code,
wh.warehouse_name AS warehouse_name
FROM rk_info t
LEFT JOIN warehouse_info wh
ON wh.warehouse_code = t.cangku
WHERE t.is_delete = 0
AND t.is_chuku = 0
AND t.pcode = #{pcode}
ORDER BY t.operation_time DESC, t.id DESC
</select>
</mapper> </mapper>

View File

@@ -590,70 +590,35 @@
COUNT(DISTINCT rr.pcode) AS locationCount, COUNT(DISTINCT rr.pcode) AS locationCount,
IFNULL(SUM(rr.real_qty), 0) AS totalQuantity IFNULL(SUM(rr.real_qty), 0) AS totalQuantity
FROM rk_record rr FROM rk_record rr
<where>
rr.is_delete = 0
AND rr.exec_status = 1 <!-- 入库 -->
<if test="operationType != null and operationType.size() > 0">
AND rr.operation_type IN
<foreach collection="operationType" item="it" open="(" separator="," close=")">
#{it}
</foreach>
</if>
<if test="xmNo != null and xmNo != ''">
AND rr.xm_no LIKE CONCAT('%', #{xmNo}, '%')
</if>
<if test="wlNo != null and wlNo != ''">
AND rr.wl_no LIKE CONCAT('%', #{wlNo}, '%')
</if>
<if test="pcode != null and pcode != ''">
AND rr.pcode LIKE CONCAT('%', #{pcode}, '%')
</if>
<if test="cangku != null and cangku != ''">
AND rr.cangku LIKE CONCAT('%', #{cangku}, '%')
</if>
<if test="startDate != null">
AND rr.operation_time &gt;= #{startDate}
</if>
<if test="endDate != null">
AND rr.operation_time &lt;= #{endDate}
</if>
</where>
</select>
<!-- 出库统计 -->
<select id="selectOutRecordStatistic"
parameterType="com.zg.project.wisdom.domain.RkRecord"
resultType="com.zg.project.wisdom.domain.vo.StockStatisticVO">
SELECT
IFNULL(SUM(rr.real_qty * rr.ht_dj), 0) AS total_amount,
COUNT(DISTINCT rr.pcode) AS location_count,
IFNULL(SUM(rr.real_qty), 0) AS total_quantity
FROM rk_record rr
<where> <where>
rr.is_delete = 0 rr.is_delete = 0
AND rr.exec_status = 1 AND rr.exec_status = 1
AND rr.biz_type = 1 <!-- 出库 -->
<!-- 已修复String 不可用 size() -->
<if test="operationType != null and operationType != ''"> <if test="operationType != null and operationType != ''">
AND rr.operation_type LIKE CONCAT('%', #{operationType}, '%') AND rr.operation_type = #{operationType}
</if> </if>
<if test="xmNo != null and xmNo != ''"> <if test="xmNo != null and xmNo != ''">
AND rr.xm_no LIKE CONCAT('%', #{xmNo}, '%') AND rr.xm_no LIKE CONCAT('%', #{xmNo}, '%')
</if> </if>
<if test="wlNo != null and wlNo != ''"> <if test="wlNo != null and wlNo != ''">
AND rr.wl_no LIKE CONCAT('%', #{wlNo}, '%') AND rr.wl_no LIKE CONCAT('%', #{wlNo}, '%')
</if> </if>
<if test="pcode != null and pcode != ''"> <if test="pcode != null and pcode != ''">
AND rr.pcode LIKE CONCAT('%', #{pcode}, '%') AND rr.pcode LIKE CONCAT('%', #{pcode}, '%')
</if> </if>
<if test="cangku != null and cangku != ''"> <if test="cangku != null and cangku != ''">
AND rr.cangku LIKE CONCAT('%', #{cangku}, '%') AND rr.cangku LIKE CONCAT('%', #{cangku}, '%')
</if> </if>
<if test="startDate != null"> <if test="startDate != null">
AND rr.operation_time &gt;= #{startDate} AND rr.operation_time &gt;= #{startDate}
</if> </if>
<if test="endDate != null"> <if test="endDate != null">
AND rr.operation_time &lt;= #{endDate} AND rr.operation_time &lt;= #{endDate}
</if> </if>