添加bigdecimal序列号
添加移库单向列表
This commit is contained in:
@@ -68,28 +68,28 @@ public class AutoInventoryController extends BaseController {
|
||||
/**
|
||||
* 开始匹配
|
||||
*/
|
||||
// @PostMapping("/match")
|
||||
// @ApiOperation("开始匹配")
|
||||
// public AjaxResult match(@RequestBody QueryDTO dto) {
|
||||
// // 停止盘点
|
||||
// rfidService.stopScan(dto.getDeviceId());
|
||||
//
|
||||
// dto.setScanType(1);
|
||||
//
|
||||
// rkInfoService.matchWithStatus(dto);
|
||||
//
|
||||
// return AjaxResult.success();
|
||||
// }
|
||||
@PostMapping("/match")
|
||||
@ApiOperation("开始匹配")
|
||||
public AjaxResult match(@RequestBody QueryDTO dto) {
|
||||
// 停止盘点
|
||||
rfidService.stopScan(dto.getDeviceId());
|
||||
|
||||
dto.setScanType(1);
|
||||
|
||||
rkInfoService.matchWithStatus(dto);
|
||||
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 匹配后图表统计
|
||||
*/
|
||||
// @PostMapping("/chart")
|
||||
// @ApiOperation("匹配后图表统计")
|
||||
// public AjaxResult chart(@RequestBody QueryDTO dto) {
|
||||
// ChartDataVO vo = rkInfoService.matchWithAll(dto);
|
||||
// return AjaxResult.success(vo);
|
||||
// }
|
||||
@PostMapping("/chart")
|
||||
@ApiOperation("匹配后图表统计")
|
||||
public AjaxResult chart(@RequestBody QueryDTO dto) {
|
||||
ChartDataVO vo = rkInfoService.matchWithAll(dto);
|
||||
return AjaxResult.success(vo);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -50,15 +50,15 @@ public class InventoryMatchScanController extends BaseController {
|
||||
* @param matchScan
|
||||
* @return
|
||||
*/
|
||||
// @GetMapping("/countList")
|
||||
// public TableDataInfo countList(InventoryMatchScan matchScan) {
|
||||
// // 开启分页
|
||||
// startPage();
|
||||
// // 调用 service 层查询数据
|
||||
// List<RkInfoMatchVO> list = inventoryMatchScanService.selectMatchScanCountList(matchScan);
|
||||
// // 返回分页后的结果
|
||||
// return getDataTable(list);
|
||||
// }
|
||||
@GetMapping("/countList")
|
||||
public TableDataInfo countList(InventoryMatchScan matchScan) {
|
||||
// 开启分页
|
||||
startPage();
|
||||
// 调用 service 层查询数据
|
||||
List<RkInfoMatchVO> list = inventoryMatchScanService.selectMatchScanCountList(matchScan);
|
||||
// 返回分页后的结果
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,5 +19,6 @@ public interface InventoryMatchScanService {
|
||||
|
||||
List<InventoryMatchScan> selectInventoryMatchScanList(InventoryMatchScan matchScan);
|
||||
|
||||
// List<RkInfoMatchVO> selectMatchScanCountList(InventoryMatchScan matchScan);
|
||||
List<RkInfoMatchVO> selectMatchScanCountList(InventoryMatchScan matchScan);
|
||||
|
||||
}
|
||||
|
||||
@@ -56,22 +56,22 @@ public class InventoryMatchScanServiceImpl implements InventoryMatchScanService
|
||||
return mapper.selectInventoryMatchScanList(matchScan);
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public List<RkInfoMatchVO> selectMatchScanCountList(InventoryMatchScan param) {
|
||||
// // 状态=2:只查扫描表中的数据
|
||||
// if ("2".equals(param.getStatus())) {
|
||||
// return mapper.selectOnlyFromMatchScan(param);
|
||||
// }
|
||||
// // 状态=1:查询指定仓库下未被扫描的库位
|
||||
// else if ("1".equals(param.getStatus())) {
|
||||
// // ✅ 根据任务ID取 sceneId,再按 scene 查询“未被扫描”的库位
|
||||
// String sceneId = taskMapper.getSceneByTaskId(param.getTaskId());
|
||||
// return rkInfoMapper.getUnscannedPcodeByScene(sceneId, param.getTaskId());
|
||||
// }
|
||||
// // 其它情况:返回扫描表和库存表的关联数据
|
||||
// else {
|
||||
// return mapper.selectJoinRkInfo(param);
|
||||
// }
|
||||
// }
|
||||
@Override
|
||||
public List<RkInfoMatchVO> selectMatchScanCountList(InventoryMatchScan param) {
|
||||
// 状态=2:只查扫描表中的数据
|
||||
if ("2".equals(param.getStatus())) {
|
||||
return mapper.selectOnlyFromMatchScan(param);
|
||||
}
|
||||
// 状态=1:查询指定仓库下未被扫描的库位
|
||||
else if ("1".equals(param.getStatus())) {
|
||||
// ✅ 根据任务ID取 sceneId,再按 scene 查询“未被扫描”的库位
|
||||
String sceneId = taskMapper.getSceneByTaskId(param.getTaskId());
|
||||
return rkInfoMapper.getUnscannedPcodeByScene(sceneId, param.getTaskId());
|
||||
}
|
||||
// 其它情况:返回扫描表和库存表的关联数据
|
||||
else {
|
||||
return mapper.selectJoinRkInfo(param);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,14 +22,14 @@ public class StatisticsController extends BaseController {
|
||||
* @param taskId
|
||||
* @return
|
||||
*/
|
||||
// @GetMapping("/count")
|
||||
// public AjaxResult conuntGetByTaskId(@RequestParam("taskId") String taskId)
|
||||
// {
|
||||
//
|
||||
// String warehouse = taskService.getWhByTaskId(taskId);
|
||||
//
|
||||
// int count = rkInfoService.countGetByWh(warehouse);
|
||||
//
|
||||
// return AjaxResult.success(count);
|
||||
// }
|
||||
@GetMapping("/count")
|
||||
public AjaxResult conuntGetByTaskId(@RequestParam("taskId") String taskId)
|
||||
{
|
||||
|
||||
String warehouse = taskService.getWhByTaskId(taskId);
|
||||
|
||||
int count = rkInfoService.countGetByWh(warehouse);
|
||||
|
||||
return AjaxResult.success(count);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,4 +113,15 @@ public class RkInfoController extends BaseController
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -165,13 +165,6 @@ public class RkRecordController extends BaseController
|
||||
return toAjax(rkRecordService.deletePreOutRecords(ids));
|
||||
}
|
||||
|
||||
/**
|
||||
* 出入库统计(同时返回)
|
||||
*/
|
||||
@PostMapping("/statistic")
|
||||
public AjaxResult statistic(@RequestBody RkRecord query) {
|
||||
return AjaxResult.success(rkRecordService.getRecordStatistic(query));
|
||||
}
|
||||
/**
|
||||
* 出入库统计,返回总数
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,8 @@ import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
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.ToStringStyle;
|
||||
import com.zg.framework.aspectj.lang.annotation.Excel;
|
||||
@@ -73,6 +75,7 @@ public class GysJh extends BaseEntity
|
||||
|
||||
/** 合同数量 */
|
||||
@Excel(name = "合同数量")
|
||||
@JsonSerialize(using = BigDecimalSerializer.class)
|
||||
private BigDecimal htQty;
|
||||
|
||||
/** SAP订单编号 */
|
||||
@@ -81,10 +84,12 @@ public class GysJh extends BaseEntity
|
||||
|
||||
/** 计划交货数量 */
|
||||
@Excel(name = "计划交货数量")
|
||||
@JsonSerialize(using = BigDecimalSerializer.class)
|
||||
private BigDecimal jhQty;
|
||||
|
||||
/** 已入库数量(累计) */
|
||||
@Excel(name = "已入库数量")
|
||||
@JsonSerialize(using = BigDecimalSerializer.class)
|
||||
private BigDecimal realQty;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.zg.project.wisdom.domain;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.zg.framework.web.domain.BaseEntity;
|
||||
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.ToStringStyle;
|
||||
|
||||
@@ -10,9 +12,6 @@ import java.util.Date;
|
||||
|
||||
/**
|
||||
* 移库记录对象 move_record
|
||||
*
|
||||
* @author zg
|
||||
* @date 2025-06-20
|
||||
*/
|
||||
public class MoveRecord extends BaseEntity {
|
||||
|
||||
@@ -27,12 +26,16 @@ public class MoveRecord extends BaseEntity {
|
||||
/** 移库生成的新库存ID(rk_info.id,用于撤销移库) */
|
||||
private Long newRkInfoId;
|
||||
|
||||
/** ================= 新增:上级移库记录ID ================= */
|
||||
private Long parentMoveId;
|
||||
|
||||
/** 实物ID */
|
||||
@Excel(name = "实物ID")
|
||||
private String entityId;
|
||||
|
||||
/** 实际移库数量 */
|
||||
@Excel(name = "移库数量")
|
||||
@JsonSerialize(using = BigDecimalSerializer.class)
|
||||
private BigDecimal realQty;
|
||||
|
||||
/** 原仓库 */
|
||||
@@ -70,7 +73,7 @@ public class MoveRecord extends BaseEntity {
|
||||
@Excel(name = "操作人名称")
|
||||
private String movedByName;
|
||||
|
||||
/** 操作时间(移库时间) */
|
||||
/** 操作时间 */
|
||||
@Excel(name = "操作时间", dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date movedAt;
|
||||
|
||||
@@ -104,6 +107,14 @@ public class MoveRecord extends BaseEntity {
|
||||
|
||||
// ==================== Getter / Setter ====================
|
||||
|
||||
public Long getParentMoveId() {
|
||||
return parentMoveId;
|
||||
}
|
||||
|
||||
public void setParentMoveId(Long parentMoveId) {
|
||||
this.parentMoveId = parentMoveId;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
@@ -286,6 +297,7 @@ public class MoveRecord extends BaseEntity {
|
||||
.append("id", getId())
|
||||
.append("rkInfoId", getRkInfoId())
|
||||
.append("newRkInfoId", getNewRkInfoId())
|
||||
.append("parentMoveId", getParentMoveId())
|
||||
.append("entityId", getEntityId())
|
||||
.append("realQty", getRealQty())
|
||||
.append("fromCangku", getFromCangku())
|
||||
@@ -298,17 +310,7 @@ public class MoveRecord extends BaseEntity {
|
||||
.append("movedBy", getMovedBy())
|
||||
.append("movedByName", getMovedByName())
|
||||
.append("movedAt", getMovedAt())
|
||||
.append("createBy", getCreateBy())
|
||||
.append("createTime", getCreateTime())
|
||||
.append("updateBy", getUpdateBy())
|
||||
.append("updateTime", getUpdateTime())
|
||||
.append("isDelete", getIsDelete())
|
||||
.append("fromCangkuName", getFromCangkuName())
|
||||
.append("toCangkuName", getToCangkuName())
|
||||
.append("xmNo", getXmNo())
|
||||
.append("xmMs", getXmMs())
|
||||
.append("wlMs", getWlMs())
|
||||
.append("gysMc", getGysMc())
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.zg.project.wisdom.domain;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
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.ToStringStyle;
|
||||
import com.zg.framework.aspectj.lang.annotation.Excel;
|
||||
@@ -127,10 +129,12 @@ public class RkInfo extends BaseEntity
|
||||
|
||||
/** 计划交货金额 */
|
||||
@Excel(name = "计划交货金额")
|
||||
@JsonSerialize(using = BigDecimalSerializer.class)
|
||||
private BigDecimal jhAmt;
|
||||
|
||||
/** 合同单价 */
|
||||
@Excel(name = "合同单价")
|
||||
@JsonSerialize(using = BigDecimalSerializer.class)
|
||||
private BigDecimal htDj;
|
||||
|
||||
/** SAP订单编号 */
|
||||
@@ -143,10 +147,12 @@ public class RkInfo extends BaseEntity
|
||||
|
||||
/** 计划交货数量 */
|
||||
@Excel(name = "计划交货数量")
|
||||
@JsonSerialize(using = BigDecimalSerializer.class)
|
||||
private BigDecimal jhQty;
|
||||
|
||||
/** 合同数量 */
|
||||
@Excel(name = "合同数量")
|
||||
@JsonSerialize(using = BigDecimalSerializer.class)
|
||||
private BigDecimal htQty;
|
||||
|
||||
/** 计量单位 */
|
||||
@@ -155,6 +161,7 @@ public class RkInfo extends BaseEntity
|
||||
|
||||
/** 实际入库数量 */
|
||||
@Excel(name = "实际入库数量")
|
||||
@JsonSerialize(using = BigDecimalSerializer.class)
|
||||
private BigDecimal realQty;
|
||||
|
||||
/** 库位码 */
|
||||
|
||||
@@ -5,6 +5,8 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
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.ToStringStyle;
|
||||
import com.zg.framework.aspectj.lang.annotation.Excel;
|
||||
@@ -142,10 +144,12 @@ public class RkRecord extends BaseEntity
|
||||
|
||||
/** 计划交货金额 */
|
||||
@Excel(name = "计划交货金额")
|
||||
@JsonSerialize(using = BigDecimalSerializer.class)
|
||||
private BigDecimal jhAmt;
|
||||
|
||||
/** 合同单价 */
|
||||
@Excel(name = "合同单价")
|
||||
@JsonSerialize(using = BigDecimalSerializer.class)
|
||||
private BigDecimal htDj;
|
||||
|
||||
/** SAP订单编号 */
|
||||
@@ -158,10 +162,12 @@ public class RkRecord extends BaseEntity
|
||||
|
||||
/** 计划交货数量 */
|
||||
@Excel(name = "计划交货数量")
|
||||
@JsonSerialize(using = BigDecimalSerializer.class)
|
||||
private BigDecimal jhQty;
|
||||
|
||||
/** 合同数量 */
|
||||
@Excel(name = "合同数量")
|
||||
@JsonSerialize(using = BigDecimalSerializer.class)
|
||||
private BigDecimal htQty;
|
||||
|
||||
/** 计量单位 */
|
||||
@@ -169,7 +175,8 @@ public class RkRecord extends BaseEntity
|
||||
private String dw;
|
||||
|
||||
/** 实际入库数量 */
|
||||
@Excel(name = "实际入库数量")
|
||||
@Excel(name = "实际出/入库数量")
|
||||
@JsonSerialize(using = BigDecimalSerializer.class)
|
||||
private BigDecimal realQty;
|
||||
|
||||
/** 库位码 */
|
||||
@@ -227,9 +234,8 @@ public class RkRecord extends BaseEntity
|
||||
private Long sid;
|
||||
|
||||
/** 是否需要配送(0否,1是,2配送中,3配送完成) */
|
||||
@Excel(name = "是否需要配送(0否,1是,2配送中,3配送完成)")
|
||||
@Excel(name = "是否需要配送", readConverterExp = "0=否,1=是,2=配送中,3=配送完成")
|
||||
private String isDelivery;
|
||||
|
||||
/** 封样编号1 */
|
||||
// @Excel(name = "封样编号1")
|
||||
private String fycde1;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
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 lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@@ -29,6 +31,7 @@ public class AuditSignatureVo extends AuditSignature {
|
||||
private String wlNo;
|
||||
|
||||
/** 实际入库数量 */
|
||||
@JsonSerialize(using = BigDecimalSerializer.class)
|
||||
private BigDecimal realQty;
|
||||
|
||||
/** 计量单位 */
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// com.zg.project.wisdom.domain.vo.GysJhUndeliveredSummaryVO
|
||||
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 java.math.BigDecimal;
|
||||
|
||||
@@ -14,5 +16,6 @@ public class GysJhUndeliveredSummaryVO {
|
||||
/** 总数量(jh_qty 合计,表示剩余未到数量) */
|
||||
private Long totalQty;
|
||||
/** 总金额(ht_dj * jh_qty 合计) */
|
||||
@JsonSerialize(using = BigDecimalSerializer.class)
|
||||
private BigDecimal amountPlan;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
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 java.math.BigDecimal;
|
||||
@@ -17,6 +19,7 @@ public class HomeKpiVO {
|
||||
private Integer monthInProjectCount;
|
||||
|
||||
/** 月入库金额 */
|
||||
@JsonSerialize(using = BigDecimalSerializer.class)
|
||||
private BigDecimal monthInAmount;
|
||||
|
||||
/** 月出库条数 */
|
||||
@@ -26,5 +29,6 @@ public class HomeKpiVO {
|
||||
private Integer monthOutProjectCount;
|
||||
|
||||
/** 月出库金额 */
|
||||
@JsonSerialize(using = BigDecimalSerializer.class)
|
||||
private BigDecimal monthOutAmount;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
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 java.math.BigDecimal;
|
||||
@@ -8,6 +10,7 @@ public class PlanToMtdVO {
|
||||
private String wlNo; // 物料号
|
||||
private String wlMs; // 物料描述
|
||||
private String dw; // 单位
|
||||
@JsonSerialize(using = BigDecimalSerializer.class)
|
||||
private BigDecimal htDj; // 合同单价
|
||||
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
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 java.math.BigDecimal;
|
||||
@@ -14,12 +16,14 @@ public class StockStatisticGroupVO {
|
||||
private String groupValue;
|
||||
|
||||
/** 总金额 */
|
||||
@JsonSerialize(using = BigDecimalSerializer.class)
|
||||
private BigDecimal totalAmount;
|
||||
|
||||
/** 使用库位数 */
|
||||
private Integer locationCount;
|
||||
|
||||
/** 总数量 */
|
||||
@JsonSerialize(using = BigDecimalSerializer.class)
|
||||
private BigDecimal totalQuantity;
|
||||
|
||||
/** 项目数(去重 xm_no) */
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
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 java.math.BigDecimal;
|
||||
@@ -14,6 +16,7 @@ public class StockStatisticVO {
|
||||
private Integer locationCount;
|
||||
|
||||
/** 库存总数量 */
|
||||
@JsonSerialize(using = BigDecimalSerializer.class)
|
||||
private BigDecimal totalQuantity;
|
||||
|
||||
/** 项目总数(去重 xm_no) */
|
||||
|
||||
@@ -59,4 +59,21 @@ public interface MoveRecordMapper
|
||||
* @return 结果
|
||||
*/
|
||||
void insertMoveRecord(MoveRecord moveRecord);
|
||||
|
||||
/**
|
||||
* 根据入库信息id查询移库记录id
|
||||
*
|
||||
* @param rkInfoId 入库信息id
|
||||
* @return 移库记录id
|
||||
*/
|
||||
Long selectLastMoveIdByRkInfoId(Long rkInfoId);
|
||||
|
||||
/**
|
||||
* 根据移库记录id查询子移库记录数量
|
||||
*
|
||||
* @param moveRecordId 移库记录id
|
||||
* @return 子移库记录数量
|
||||
*/
|
||||
int countByParentMoveId(Long moveRecordId);
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,9 @@ package com.zg.project.wisdom.mapper;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
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.vo.StockStatisticVO;
|
||||
import io.lettuce.core.dynamic.annotation.Param;
|
||||
@@ -108,4 +111,48 @@ public interface RkInfoMapper
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -123,15 +123,6 @@ public interface RkRecordMapper
|
||||
*/
|
||||
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);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package com.zg.project.wisdom.service;
|
||||
|
||||
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.vo.StockStatisticVO;
|
||||
|
||||
@@ -66,5 +69,31 @@ public interface IRkInfoService
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -93,8 +93,6 @@ public interface IRkRecordService
|
||||
*/
|
||||
int deletePreOutRecords(Long[] ids);
|
||||
|
||||
|
||||
RecordStatisticVO getRecordStatistic(RkRecord query);
|
||||
/**
|
||||
* 出入库总数统计
|
||||
*/
|
||||
|
||||
@@ -120,7 +120,6 @@ public class MoveRecordServiceImpl implements IMoveRecordService
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void processMove(MoveRequestDTO dto) {
|
||||
|
||||
/* ====================== 0. 基础校验 ====================== */
|
||||
if (dto == null || dto.getFromRkId() == null) {
|
||||
throw new ServiceException("原库存ID不能为空");
|
||||
}
|
||||
@@ -151,16 +150,18 @@ public class MoveRecordServiceImpl implements IMoveRecordService
|
||||
String userId = String.valueOf(SecurityUtils.getUserId());
|
||||
Date now = DateUtils.getNowDate();
|
||||
|
||||
/* ====================== 3. 原库存快照 ====================== */
|
||||
/* ====================== 3. 查询上一条移库记录 ====================== */
|
||||
Long lastMoveId = moveRecordMapper.selectLastMoveIdByRkInfoId(dto.getFromRkId());
|
||||
|
||||
/* ====================== 4. 原库存快照 ====================== */
|
||||
RkInfo snapshot = new RkInfo();
|
||||
BeanUtils.copyProperties(original, snapshot);
|
||||
|
||||
/* ====================== 4. 全量移库(不拆分) ====================== */
|
||||
/* ====================== 5. 全量移库 ====================== */
|
||||
if (dto.getTargets().size() == 1 && moveTotalQty.compareTo(originQty) == 0) {
|
||||
|
||||
MoveTargetItem target = dto.getTargets().get(0);
|
||||
|
||||
// 4.1 更新原库存(仅换库位)
|
||||
original.setCangku(target.getToCangku());
|
||||
original.setPcode(target.getToPcode());
|
||||
original.setTrayCode(target.getToTrayCode());
|
||||
@@ -169,10 +170,13 @@ public class MoveRecordServiceImpl implements IMoveRecordService
|
||||
original.setUpdateTime(now);
|
||||
rkInfoMapper.updateRkInfo(original);
|
||||
|
||||
// 4.2 移库流水(全量移库,无新库存)
|
||||
MoveRecord record = new MoveRecord();
|
||||
record.setRkInfoId(snapshot.getId());
|
||||
record.setNewRkInfoId(null); // ✅ 关键:全量移库没有新库存
|
||||
record.setNewRkInfoId(null);
|
||||
|
||||
// ★★ 新增关键 ★★
|
||||
record.setParentMoveId(lastMoveId);
|
||||
|
||||
record.setEntityId(snapshot.getEntityId());
|
||||
record.setRealQty(originQty);
|
||||
|
||||
@@ -198,16 +202,14 @@ public class MoveRecordServiceImpl implements IMoveRecordService
|
||||
return;
|
||||
}
|
||||
|
||||
/* ====================== 5. 部分移库(拆分库存) ====================== */
|
||||
/* ====================== 6. 部分移库 ====================== */
|
||||
|
||||
// 5.1 原库存扣减数量
|
||||
original.setRealQty(originQty.subtract(moveTotalQty));
|
||||
original.setHasMoved("1");
|
||||
original.setUpdateBy(userId);
|
||||
original.setUpdateTime(now);
|
||||
rkInfoMapper.updateRkInfo(original);
|
||||
|
||||
// 5.2 生成新库存 + 移库流水
|
||||
for (MoveTargetItem target : dto.getTargets()) {
|
||||
|
||||
/* ---------- 新库存 ---------- */
|
||||
@@ -227,10 +229,14 @@ public class MoveRecordServiceImpl implements IMoveRecordService
|
||||
|
||||
rkInfoMapper.insertRkInfo(newInfo);
|
||||
|
||||
/* ---------- 移库流水(重点) ---------- */
|
||||
/* ---------- 移库流水 ---------- */
|
||||
MoveRecord record = new MoveRecord();
|
||||
record.setRkInfoId(snapshot.getId()); // 原库存
|
||||
record.setNewRkInfoId(newInfo.getId()); // ✅ 关键:新库存ID
|
||||
record.setRkInfoId(snapshot.getId());
|
||||
record.setNewRkInfoId(newInfo.getId());
|
||||
|
||||
// ★★ 新增关键 ★★
|
||||
record.setParentMoveId(lastMoveId);
|
||||
|
||||
record.setEntityId(snapshot.getEntityId());
|
||||
record.setRealQty(target.getRealQty());
|
||||
|
||||
@@ -273,10 +279,16 @@ public class MoveRecordServiceImpl implements IMoveRecordService
|
||||
throw new ServiceException("移库记录不存在或已撤销");
|
||||
}
|
||||
|
||||
/* ====================== 2. 关键:校验是否有子移库 ====================== */
|
||||
int childCount = moveRecordMapper.countByParentMoveId(moveRecordId);
|
||||
if (childCount > 0) {
|
||||
throw new ServiceException("该移库已产生后续移库,请先撤销后续移库");
|
||||
}
|
||||
|
||||
Long originRkInfoId = record.getRkInfoId();
|
||||
Long newRkInfoId = record.getNewRkInfoId();
|
||||
|
||||
/* ====================== 2. 查询原库存 ====================== */
|
||||
/* ====================== 3. 查询原库存 ====================== */
|
||||
RkInfo origin = rkInfoMapper.selectRkInfoById(originRkInfoId);
|
||||
if (origin == null || "1".equals(origin.getIsDelete())) {
|
||||
throw new ServiceException("原库存不存在或已删除,无法撤销");
|
||||
@@ -285,12 +297,11 @@ public class MoveRecordServiceImpl implements IMoveRecordService
|
||||
String userId = String.valueOf(SecurityUtils.getUserId());
|
||||
Date now = DateUtils.getNowDate();
|
||||
|
||||
/* ====================== 3. 分情况处理 ====================== */
|
||||
/* ====================== 4. 分情况处理 ====================== */
|
||||
|
||||
// ---------- 情况一:全量移库 ----------
|
||||
// -------- 全量移库 --------
|
||||
if (newRkInfoId == null) {
|
||||
|
||||
// 回滚库位
|
||||
origin.setCangku(record.getFromCangku());
|
||||
origin.setPcode(record.getFromPcode());
|
||||
origin.setTrayCode(record.getFromTrayCode());
|
||||
@@ -299,25 +310,31 @@ public class MoveRecordServiceImpl implements IMoveRecordService
|
||||
origin.setUpdateTime(now);
|
||||
|
||||
rkInfoMapper.updateRkInfo(origin);
|
||||
|
||||
}
|
||||
// ---------- 情况二:部分移库 ----------
|
||||
// -------- 部分移库 --------
|
||||
else {
|
||||
|
||||
/* 3.1 原库存回补数量 */
|
||||
BigDecimal qty = record.getRealQty();
|
||||
if (qty == null || qty.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
throw new ServiceException("移库数量异常,无法撤销");
|
||||
}
|
||||
|
||||
// 回补数量
|
||||
origin.setRealQty(origin.getRealQty().add(qty));
|
||||
|
||||
// 恢复位置
|
||||
origin.setCangku(record.getFromCangku());
|
||||
origin.setPcode(record.getFromPcode());
|
||||
origin.setTrayCode(record.getFromTrayCode());
|
||||
|
||||
origin.setHasMoved("0");
|
||||
origin.setUpdateBy(userId);
|
||||
origin.setUpdateTime(now);
|
||||
origin.setHasMoved("0");
|
||||
|
||||
rkInfoMapper.updateRkInfo(origin);
|
||||
|
||||
/* 3.2 删除移库生成的新库存 */
|
||||
// 删除新库存
|
||||
RkInfo newInfo = rkInfoMapper.selectRkInfoById(newRkInfoId);
|
||||
if (newInfo != null && !"1".equals(newInfo.getIsDelete())) {
|
||||
newInfo.setIsDelete("1");
|
||||
@@ -327,10 +344,11 @@ public class MoveRecordServiceImpl implements IMoveRecordService
|
||||
}
|
||||
}
|
||||
|
||||
/* ====================== 4. 标记移库记录已撤销 ====================== */
|
||||
/* ====================== 5. 标记移库记录已撤销 ====================== */
|
||||
record.setIsDelete("1");
|
||||
record.setUpdateBy(userId);
|
||||
record.setUpdateTime(now);
|
||||
moveRecordMapper.updateMoveRecord(record);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -598,6 +598,7 @@ public class RkBillServiceImpl implements IRkBillService
|
||||
record.setOperationTime(bill.getOperationTime());
|
||||
record.setOperator(bill.getOperator());
|
||||
record.setTeamCode(bill.getTeamCode());
|
||||
record.setIsDelivery(bill.getIsDelivery());
|
||||
|
||||
/* ================== ✅ 关键修复 ================== */
|
||||
// 仓库必须来源于【库存快照】,而不是 bill
|
||||
|
||||
@@ -1,7 +1,21 @@
|
||||
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.stream.Collectors;
|
||||
|
||||
import com.zg.common.exception.ServiceException;
|
||||
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.mapper.RkRecordMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -26,6 +40,12 @@ public class RkInfoServiceImpl implements IRkInfoService
|
||||
@Autowired
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -795,14 +795,6 @@ public class RkRecordServiceImpl implements IRkRecordService
|
||||
|
||||
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
|
||||
|
||||
43
src/main/java/com/zg/project/wisdom/utils/DecimalUtil.java
Normal file
43
src/main/java/com/zg/project/wisdom/utils/DecimalUtil.java
Normal 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());
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,11 @@
|
||||
|
||||
<mapper namespace="com.zg.project.inventory.AutoInventory.mapper.InventoryMatchScanMapper">
|
||||
|
||||
<!--
|
||||
批量插入盘点匹配扫描记录
|
||||
用于将一批扫描记录批量插入到库存匹配扫描表中
|
||||
@param list 扫描记录列表,包含任务ID、设备ID、物资编码、时间、扫描类型和状态
|
||||
-->
|
||||
<insert id="insertBatch">
|
||||
INSERT INTO inventory_match_scan (task_id, device_id, pcode, tme, scan_type, status)
|
||||
VALUES
|
||||
@@ -12,16 +17,33 @@
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<!--
|
||||
查询所有盘点匹配扫描记录
|
||||
获取库存匹配扫描表中的所有记录
|
||||
@return InventoryMatchScan 扫描记录实体列表
|
||||
-->
|
||||
<select id="getAll" resultType="com.zg.project.inventory.domain.entity.InventoryMatchScan">
|
||||
SELECT * FROM inventory_match_scan
|
||||
</select>
|
||||
|
||||
<!--
|
||||
查询所有库存匹配扫描记录并关联SOD表
|
||||
左连接SOD表,获取与扫描记录匹配的物资信息,仅返回剩余数量大于0的记录
|
||||
@return Sod 物资信息实体列表
|
||||
-->
|
||||
<select id="getAllSod" resultType="com.zg.project.inventory.domain.entity.Sod">
|
||||
SELECT * FROM inventory_match_scan i
|
||||
LEFT JOIN sod s ON i.pcde = s.fycde_1
|
||||
WHERE s.rmn > 0
|
||||
</select>
|
||||
|
||||
<!--
|
||||
按任务统计物资编码数量
|
||||
根据任务名称和状态筛选扫描记录,关联SOD表统计每个物资编码的出现次数,仅统计剩余数量大于0的物资
|
||||
@param taskName 任务名称(模糊查询,可选)
|
||||
@param status 扫描状态(可选)
|
||||
@return PcdeCountVO 物资编码统计信息,包含物资编码和出现次数
|
||||
-->
|
||||
<select id="getPcdeCountByTask" resultType="com.zg.project.inventory.domain.vo.PcdeCountVO">
|
||||
SELECT
|
||||
s.pcde,
|
||||
@@ -43,6 +65,14 @@
|
||||
GROUP BY s.pcde
|
||||
</select>
|
||||
|
||||
<!--
|
||||
按任务名称分组查询扫描历史记录(分页)
|
||||
根据多个条件筛选扫描记录,按任务名称分组,返回每个任务的最新时间和扫描类型,支持分页查询
|
||||
@param dto 查询条件对象,包含设备ID、任务名称、物资编码、时间范围、扫描类型和状态
|
||||
@param limit 每页记录数
|
||||
@param offset 偏移量
|
||||
@return InventoryMatchScanSimpleVO 扫描记录简单视图列表
|
||||
-->
|
||||
<select id="getGroupedHistoryList" resultType="com.zg.project.inventory.domain.vo.InventoryMatchScanSimpleVO">
|
||||
SELECT
|
||||
task_name AS taskName,
|
||||
@@ -75,6 +105,12 @@
|
||||
LIMIT #{limit} OFFSET #{offset}
|
||||
</select>
|
||||
|
||||
<!--
|
||||
统计分组后的任务数量
|
||||
根据查询条件统计不同任务名称的数量,用于分页查询的总数计算
|
||||
@param dto 查询条件对象,包含设备ID、任务名称、物资编码、时间范围、扫描类型和状态
|
||||
@return int 任务名称数量
|
||||
-->
|
||||
<select id="countGroupedHistory" resultType="int">
|
||||
SELECT COUNT(DISTINCT task_name)
|
||||
FROM inventory_match_scan
|
||||
@@ -101,6 +137,13 @@
|
||||
</where>
|
||||
</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
|
||||
i.id,
|
||||
@@ -132,6 +175,12 @@
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<!--
|
||||
条件查询盘点匹配扫描记录列表(多表关联)
|
||||
关联入库信息表和盘点任务表,获取完整的扫描记录信息,支持多个条件筛选并按时间倒序排列
|
||||
@param param 查询条件对象,包含任务ID、设备ID、物资编码、状态、扫描类型和时间
|
||||
@return InventoryMatchScan 扫描记录实体列表
|
||||
-->
|
||||
<select id="selectInventoryMatchScanList"
|
||||
resultType="com.zg.project.inventory.domain.entity.InventoryMatchScan"
|
||||
parameterType="com.zg.project.inventory.domain.entity.InventoryMatchScan">
|
||||
@@ -171,6 +220,12 @@
|
||||
ORDER BY i.tme DESC
|
||||
</select>
|
||||
|
||||
<!--
|
||||
仅从扫描表中查询物资编码(用于匹配对比)
|
||||
根据条件查询扫描记录中的物资编码,实际数量字段置空,用于与入库信息进行匹配对比
|
||||
@param param 查询条件对象,包含任务ID、设备ID和状态
|
||||
@return RkInfoMatchVO 入库信息匹配视图列表,包含物资编码和实际数量(NULL)
|
||||
-->
|
||||
<select id="selectOnlyFromMatchScan"
|
||||
parameterType="InventoryMatchScan"
|
||||
resultType="com.zg.project.inventory.domain.vo.RkInfoMatchVO">
|
||||
@@ -192,6 +247,12 @@
|
||||
ORDER BY i.tme DESC
|
||||
</select>
|
||||
|
||||
<!--
|
||||
关联入库信息查询物资的实际入库数量
|
||||
根据扫描表中的物资编码,查询入库信息表中的实际入库数量汇总,用于盘点数量对比
|
||||
@param param 查询条件对象,包含任务ID、设备ID和状态
|
||||
@return RkInfoMatchVO 入库信息匹配视图列表,包含物资编码和实际入库数量汇总
|
||||
-->
|
||||
<select id="selectJoinRkInfo"
|
||||
parameterType="InventoryMatchScan"
|
||||
resultType="com.zg.project.inventory.domain.vo.RkInfoMatchVO">
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
<!-- 关键字段 -->
|
||||
<result property="rkInfoId" column="rk_info_id"/>
|
||||
<result property="newRkInfoId" column="new_rk_info_id"/>
|
||||
|
||||
<result property="parentMoveId" column="parent_move_id"/>
|
||||
|
||||
<result property="entityId" column="entity_id"/>
|
||||
|
||||
<!-- 数量 -->
|
||||
@@ -55,6 +58,10 @@
|
||||
id,
|
||||
rk_info_id,
|
||||
new_rk_info_id,
|
||||
|
||||
-- ★★★ 新增字段 ★★★
|
||||
parent_move_id,
|
||||
|
||||
entity_id,
|
||||
real_qty,
|
||||
from_cangku,
|
||||
@@ -82,6 +89,9 @@
|
||||
INSERT INTO move_record (
|
||||
rk_info_id,
|
||||
new_rk_info_id,
|
||||
|
||||
parent_move_id,
|
||||
|
||||
entity_id,
|
||||
real_qty,
|
||||
from_cangku,
|
||||
@@ -101,6 +111,9 @@
|
||||
) VALUES (
|
||||
#{rkInfoId},
|
||||
#{newRkInfoId},
|
||||
|
||||
#{parentMoveId},
|
||||
|
||||
#{entityId},
|
||||
#{realQty},
|
||||
#{fromCangku},
|
||||
@@ -172,6 +185,9 @@
|
||||
<set>
|
||||
<if test="rkInfoId != null">rk_info_id = #{rkInfoId},</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="realQty != null">real_qty = #{realQty},</if>
|
||||
<if test="fromCangku != null">from_cangku = #{fromCangku},</if>
|
||||
@@ -203,4 +219,20 @@
|
||||
</foreach>
|
||||
</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>
|
||||
|
||||
@@ -389,5 +389,116 @@
|
||||
AND is_delete = '0'
|
||||
</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>
|
||||
|
||||
@@ -590,70 +590,35 @@
|
||||
COUNT(DISTINCT rr.pcode) AS locationCount,
|
||||
IFNULL(SUM(rr.real_qty), 0) AS totalQuantity
|
||||
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 >= #{startDate}
|
||||
</if>
|
||||
<if test="endDate != null">
|
||||
AND rr.operation_time <= #{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>
|
||||
rr.is_delete = 0
|
||||
AND rr.exec_status = 1
|
||||
AND rr.biz_type = 1 <!-- 出库 -->
|
||||
|
||||
<!-- 已修复:String 不可用 size() -->
|
||||
<if test="operationType != null and operationType != ''">
|
||||
AND rr.operation_type LIKE CONCAT('%', #{operationType}, '%')
|
||||
AND rr.operation_type = #{operationType}
|
||||
</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 >= #{startDate}
|
||||
</if>
|
||||
|
||||
<if test="endDate != null">
|
||||
AND rr.operation_time <= #{endDate}
|
||||
</if>
|
||||
|
||||
Reference in New Issue
Block a user