From a1be0e4abdbd848db5dc3bf88ae668a62f59c0fa Mon Sep 17 00:00:00 2001 From: wenshijun Date: Wed, 21 Jan 2026 19:21:07 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=A5=E5=BA=93=E7=9B=B8=E5=85=B3=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/MoveRecordController.java | 2 - .../wisdom/controller/RkBillController.java | 5 +- .../wisdom/controller/RkInfoController.java | 2 +- .../wisdom/controller/RkRecordController.java | 21 ++ .../zg/project/wisdom/domain/MoveRecord.java | 183 ++++++++++---- .../com/zg/project/wisdom/domain/RkBill.java | 24 ++ .../com/zg/project/wisdom/domain/RkInfo.java | 173 ++++++++++--- .../zg/project/wisdom/domain/RkRecord.java | 52 +++- .../project/wisdom/mapper/RkBillMapper.java | 13 + .../project/wisdom/mapper/RkInfoMapper.java | 7 + .../project/wisdom/mapper/RkRecordMapper.java | 29 +++ .../wisdom/service/IRkRecordService.java | 10 + .../service/impl/MoveRecordServiceImpl.java | 173 ++++++------- .../service/impl/RkBillServiceImpl.java | 63 +++-- .../service/impl/RkInfoServiceImpl.java | 16 +- .../service/impl/RkRecordServiceImpl.java | 149 +++++++++++- .../mybatis/wisdom/MoveRecordMapper.xml | 72 ++++-- .../resources/mybatis/wisdom/RkBillMapper.xml | 145 ++++++----- .../resources/mybatis/wisdom/RkInfoMapper.xml | 228 +++++++++++------- .../mybatis/wisdom/RkRecordMapper.xml | 46 +++- 20 files changed, 1051 insertions(+), 362 deletions(-) diff --git a/src/main/java/com/zg/project/wisdom/controller/MoveRecordController.java b/src/main/java/com/zg/project/wisdom/controller/MoveRecordController.java index 5dc7ee3..4aed02b 100644 --- a/src/main/java/com/zg/project/wisdom/controller/MoveRecordController.java +++ b/src/main/java/com/zg/project/wisdom/controller/MoveRecordController.java @@ -31,7 +31,6 @@ public class MoveRecordController extends BaseController @Autowired private IMoveRecordService moveRecordService; - /** * 新增移库记录 */ @@ -43,7 +42,6 @@ public class MoveRecordController extends BaseController return AjaxResult.success("移库成功"); } - /** * 查询移库记录列表 */ diff --git a/src/main/java/com/zg/project/wisdom/controller/RkBillController.java b/src/main/java/com/zg/project/wisdom/controller/RkBillController.java index 01c2cf2..a549f9d 100644 --- a/src/main/java/com/zg/project/wisdom/controller/RkBillController.java +++ b/src/main/java/com/zg/project/wisdom/controller/RkBillController.java @@ -40,9 +40,8 @@ public class RkBillController extends BaseController * 查询库存单据列表 */ @PreAuthorize("@ss.hasPermi('wisdom:bill:list')") - @GetMapping("/list") - public TableDataInfo list(RkBill rkBill) - { + @PostMapping("/list") + public TableDataInfo list(@RequestBody RkBill rkBill) { startPage(); List list = rkBillService.selectRkBillList(rkBill); return getDataTable(list); diff --git a/src/main/java/com/zg/project/wisdom/controller/RkInfoController.java b/src/main/java/com/zg/project/wisdom/controller/RkInfoController.java index 53c6a2d..bb1d6e7 100644 --- a/src/main/java/com/zg/project/wisdom/controller/RkInfoController.java +++ b/src/main/java/com/zg/project/wisdom/controller/RkInfoController.java @@ -85,7 +85,7 @@ public class RkInfoController extends BaseController */ @PreAuthorize("@ss.hasPermi('wisdom:stock:edit')") @Log(title = "库存单据明细", businessType = BusinessType.UPDATE) - @PutMapping + @PostMapping("/update") public AjaxResult edit(@RequestBody RkInfo rkInfo) { return toAjax(rkInfoService.updateRkInfo(rkInfo)); diff --git a/src/main/java/com/zg/project/wisdom/controller/RkRecordController.java b/src/main/java/com/zg/project/wisdom/controller/RkRecordController.java index 529a592..8098f7b 100644 --- a/src/main/java/com/zg/project/wisdom/controller/RkRecordController.java +++ b/src/main/java/com/zg/project/wisdom/controller/RkRecordController.java @@ -111,4 +111,25 @@ public class RkRecordController extends BaseController { return toAjax(rkRecordService.deleteRkRecordByIds(ids)); } + + /** + * 撤销入库(回退为预入库) + */ + @PreAuthorize("@ss.hasPermi('wisdom:record:rollback')") + @Log(title = "入库撤销", businessType = BusinessType.UPDATE) + @PostMapping("/rollback") + public AjaxResult rollback(@RequestBody RkRecord record) { + return toAjax(rkRecordService.rollbackToPreIn(record.getIds())); + } + + /** + * 一键入库(批量完成入库) + */ + @PreAuthorize("@ss.hasPermi('wisdom:record:finish')") + @Log(title = "一键入库", businessType = BusinessType.UPDATE) + @PostMapping("/finish") + public AjaxResult finish(@RequestBody RkRecord record) { + return toAjax(rkRecordService.finishIn(record.getIds())); + } + } diff --git a/src/main/java/com/zg/project/wisdom/domain/MoveRecord.java b/src/main/java/com/zg/project/wisdom/domain/MoveRecord.java index 6fec24a..45d7537 100644 --- a/src/main/java/com/zg/project/wisdom/domain/MoveRecord.java +++ b/src/main/java/com/zg/project/wisdom/domain/MoveRecord.java @@ -20,9 +20,8 @@ public class MoveRecord extends BaseEntity { /** 主键ID */ private Long id; - /** 关联的库存单据ID */ - @Excel(name = "库存单据ID") - private Long rkId; + /** 关联库存表ID(rk_info.id) */ + private Long rkInfoId; /** 实物ID */ @Excel(name = "实物ID") @@ -59,6 +58,7 @@ public class MoveRecord extends BaseEntity { /** 操作人 */ private String movedBy; + /** 操作人名称 */ @Excel(name = "操作人名称") private String movedByName; @@ -94,76 +94,173 @@ public class MoveRecord extends BaseEntity { @Excel(name = "供应商名称") private String gysMc; - // Getters and Setters + // ==================== Getter / Setter ==================== - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public Long getId() { + return id; + } - public Long getRkId() { return rkId; } - public void setRkId(Long rkId) { this.rkId = rkId; } + public void setId(Long id) { + this.id = id; + } - public String getEntityId() { return entityId; } - public void setEntityId(String entityId) { this.entityId = entityId; } + public Long getRkInfoId() { + return rkInfoId; + } - public String getFromCangku() { return fromCangku; } - public void setFromCangku(String fromCangku) { this.fromCangku = fromCangku; } + public void setRkInfoId(Long rkInfoId) { + this.rkInfoId = rkInfoId; + } - public String getFromPcode() { return fromPcode; } - public void setFromPcode(String fromPcode) { this.fromPcode = fromPcode; } + public String getEntityId() { + return entityId; + } - public String getFromTrayCode() { return fromTrayCode; } - public void setFromTrayCode(String fromTrayCode) { this.fromTrayCode = fromTrayCode; } + public void setEntityId(String entityId) { + this.entityId = entityId; + } - public String getToCangku() { return toCangku; } - public void setToCangku(String toCangku) { this.toCangku = toCangku; } + public String getFromCangku() { + return fromCangku; + } - public String getToPcode() { return toPcode; } - public void setToPcode(String toPcode) { this.toPcode = toPcode; } + public void setFromCangku(String fromCangku) { + this.fromCangku = fromCangku; + } - public String getToTrayCode() { return toTrayCode; } - public void setToTrayCode(String toTrayCode) { this.toTrayCode = toTrayCode; } + public String getFromPcode() { + return fromPcode; + } - public String getMoveReason() { return moveReason; } - public void setMoveReason(String moveReason) { this.moveReason = moveReason; } + public void setFromPcode(String fromPcode) { + this.fromPcode = fromPcode; + } + + public String getFromTrayCode() { + return fromTrayCode; + } + + public void setFromTrayCode(String fromTrayCode) { + this.fromTrayCode = fromTrayCode; + } + + public String getToCangku() { + return toCangku; + } + + public void setToCangku(String toCangku) { + this.toCangku = toCangku; + } + + public String getToPcode() { + return toPcode; + } + + public void setToPcode(String toPcode) { + this.toPcode = toPcode; + } + + public String getToTrayCode() { + return toTrayCode; + } + + public void setToTrayCode(String toTrayCode) { + this.toTrayCode = toTrayCode; + } + + public String getMoveReason() { + return moveReason; + } + + public void setMoveReason(String moveReason) { + this.moveReason = moveReason; + } + + public String getMovedBy() { + return movedBy; + } + + public void setMovedBy(String movedBy) { + this.movedBy = movedBy; + } - public String getMovedBy() { return movedBy; } - public void setMovedBy(String movedBy) { this.movedBy = movedBy; } public String getMovedByName() { return movedByName; } + public void setMovedByName(String movedByName) { this.movedByName = movedByName; } - public Date getMovedAt() { return movedAt; } - public void setMovedAt(Date movedAt) { this.movedAt = movedAt; } + public Date getMovedAt() { + return movedAt; + } - public String getIsDelete() { return isDelete; } - public void setIsDelete(String isDelete) { this.isDelete = isDelete; } + public void setMovedAt(Date movedAt) { + this.movedAt = movedAt; + } - public String getFromCangkuName() { return fromCangkuName; } - public void setFromCangkuName(String fromCangkuName) { this.fromCangkuName = fromCangkuName; } + public String getIsDelete() { + return isDelete; + } - public String getToCangkuName() { return toCangkuName; } - public void setToCangkuName(String toCangkuName) { this.toCangkuName = toCangkuName; } + public void setIsDelete(String isDelete) { + this.isDelete = isDelete; + } - public String getXmNo() { return xmNo; } - public void setXmNo(String xmNo) { this.xmNo = xmNo; } + public String getFromCangkuName() { + return fromCangkuName; + } - public String getXmMs() { return xmMs; } - public void setXmMs(String xmMs) { this.xmMs = xmMs; } + public void setFromCangkuName(String fromCangkuName) { + this.fromCangkuName = fromCangkuName; + } - public String getWlMs() { return wlMs; } - public void setWlMs(String wlMs) { this.wlMs = wlMs; } + public String getToCangkuName() { + return toCangkuName; + } - public String getGysMc() { return gysMc; } - public void setGysMc(String gysMc) { this.gysMc = gysMc; } + public void setToCangkuName(String toCangkuName) { + this.toCangkuName = toCangkuName; + } + + public String getXmNo() { + return xmNo; + } + + public void setXmNo(String xmNo) { + this.xmNo = xmNo; + } + + public String getXmMs() { + return xmMs; + } + + public void setXmMs(String xmMs) { + this.xmMs = xmMs; + } + + public String getWlMs() { + return wlMs; + } + + public void setWlMs(String wlMs) { + this.wlMs = wlMs; + } + + public String getGysMc() { + return gysMc; + } + + public void setGysMc(String gysMc) { + this.gysMc = gysMc; + } @Override public String toString() { return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) .append("id", getId()) - .append("rkId", getRkId()) + .append("rkInfoId", getRkInfoId()) .append("entityId", getEntityId()) .append("fromCangku", getFromCangku()) .append("fromPcode", getFromPcode()) diff --git a/src/main/java/com/zg/project/wisdom/domain/RkBill.java b/src/main/java/com/zg/project/wisdom/domain/RkBill.java index 5ab6f94..b23b4bc 100644 --- a/src/main/java/com/zg/project/wisdom/domain/RkBill.java +++ b/src/main/java/com/zg/project/wisdom/domain/RkBill.java @@ -1,6 +1,7 @@ package com.zg.project.wisdom.domain; import java.util.Date; +import java.util.List; import com.fasterxml.jackson.annotation.JsonFormat; import org.apache.commons.lang3.builder.ToStringBuilder; @@ -63,6 +64,9 @@ public class RkBill extends BaseEntity { @Excel(name = "操作类型", readConverterExp = "0=入库,1=出库,2=借料出库,3=还料入库") private String bizType; + /** 业务类型列表(查询用) */ + private List bizTypeList; + /** 出入库时间 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @Excel(name = "出入库时间") @@ -113,6 +117,10 @@ public class RkBill extends BaseEntity { @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date endDate; + /** 备注 */ + @Excel(name = "备注") + private String remark; + // ================= getter / setter ================= public Long getId() { @@ -195,6 +203,14 @@ public class RkBill extends BaseEntity { this.bizType = bizType; } + public List getBizTypeList() { + return bizTypeList; + } + + public void setBizTypeList(List bizTypeList) { + this.bizTypeList = bizTypeList; + } + public Date getOperationTime() { return operationTime; } @@ -299,6 +315,14 @@ public class RkBill extends BaseEntity { this.endDate = endDate; } + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + // ================= toString ================= @Override diff --git a/src/main/java/com/zg/project/wisdom/domain/RkInfo.java b/src/main/java/com/zg/project/wisdom/domain/RkInfo.java index 7ae2d00..cd500c2 100644 --- a/src/main/java/com/zg/project/wisdom/domain/RkInfo.java +++ b/src/main/java/com/zg/project/wisdom/domain/RkInfo.java @@ -7,6 +7,7 @@ import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import com.zg.framework.aspectj.lang.annotation.Excel; import com.zg.framework.web.domain.BaseEntity; +import org.springframework.format.annotation.DateTimeFormat; /** * 库存单据明细对象 rk_info @@ -22,43 +23,66 @@ public class RkInfo extends BaseEntity private Long id; /** 业务操作类型(0入库,1出库,2借料出库,3还料入库) */ - @Excel(name = "业务操作类型", readConverterExp = "0=入库,1=出库,2=借料出库,3=还料入库") + @Excel(name = "业务类型", readConverterExp = "0=入库,1=出库,2=借料出库,3=还料入库") private String bizType; /** 出入库类型 */ - @Excel(name = "出入库类型") +// @Excel(name = "出入库类型") private String operationType; + /** 出入库类型名称(联表) */ + @Excel(name = "出入库类型名称") + private String operationTypeName; + /** 执行状态(0预入/预出,1已完成) */ @Excel(name = "执行状态", readConverterExp = "0=预入/预出,1=已完成") private String execStatus; /** 物资类型 */ - @Excel(name = "物资类型") +// @Excel(name = "物资类型") private String wlType; + /** 物资类型名称 */ + @Excel(name = "物资类型名称") + private String wlTypeName; + /** 所属仓库 */ - @Excel(name = "所属仓库") +// @Excel(name = "所属仓库") private String cangku; + /** 小仓名称 */ + @Excel(name = "仓库名称") + private String warehouseName; + + /** 大仓编码 */ + private String parentWarehouseCode; + + /** 大仓名称 */ + @Excel(name = "大仓名称") + private String parentWarehouseName; + /** 出入库时间 */ - @JsonFormat(pattern = "yyyy-MM-dd") - @Excel(name = "出入库时间", width = 30, dateFormat = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + @Excel(name = "出入库时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") private Date operationTime; /** 库龄(天) */ @Excel(name = "库龄(天)") private Long stockAge; - /** 出入库理货员 */ -// @Excel(name = "出入库理货员") + /** 出入库理货员ID */ private Integer operator; + + /** 出入库理货员 */ + @Excel(name = "出入库理货员") + private String operatorName; + /** 是否已出库(0已入库,1已出库) */ - @Excel(name = "是否已出库", readConverterExp = "0=已入库,1已出库") + @Excel(name = "是否已出库", readConverterExp = "0=已入库,1=已出库") private String isChuku; - /** 0:入库待审核,1已通过,2已驳回,3出库待审核 */ - @Excel(name = "0:入库待审核,1已通过,2已驳回,3出库待审核") + /** 审核状态(0入库待审核,1已通过,2已驳回,3出库待审核) */ + @Excel(name = "审核状态", readConverterExp = "0=入库待审核,1=已通过,2=已驳回,3=出库待审核") private String status; /** 单据号 */ @@ -78,11 +102,11 @@ public class RkInfo extends BaseEntity private String xmMs; /** 出库项目号(借用方项目) */ - @Excel(name = "出库项目号", readConverterExp = "借=用方项目") + @Excel(name = "出库项目号") private String xmNoCk; /** 出库项目描述(借用方项目描述) */ - @Excel(name = "出库项目描述", readConverterExp = "借=用方项目描述") + @Excel(name = "出库项目描述") private String xmMsCk; /** 物料号 */ @@ -155,12 +179,12 @@ public class RkInfo extends BaseEntity /** 借用时间 */ @JsonFormat(pattern = "yyyy-MM-dd") - @Excel(name = "借用时间", width = 30, dateFormat = "yyyy-MM-dd") + @Excel(name = "借用时间", width = 20, dateFormat = "yyyy-MM-dd") private Date borrowTime; /** 归还时间 */ @JsonFormat(pattern = "yyyy-MM-dd") - @Excel(name = "归还时间", width = 30, dateFormat = "yyyy-MM-dd") + @Excel(name = "归还时间", width = 20, dateFormat = "yyyy-MM-dd") private Date returnTime; /** 是否移库过(0否 1是) */ @@ -168,45 +192,51 @@ public class RkInfo extends BaseEntity private String hasMoved; /** 是否借料(0否,1是,2已归还) */ - @Excel(name = "是否借料", readConverterExp = "0=否,1是,2已归还") + @Excel(name = "是否借料", readConverterExp = "0=否,1=是,2=已归还") private String isBorrowed; - /** 是否删除(0 表示正常,1 表示已删除) */ - @Excel(name = "是否删除", readConverterExp = "0=,表=示正常,1,表=示已删除") + /** 是否删除(0正常,1已删除) */ +// @Excel(name = "是否删除", readConverterExp = "0=正常,1=已删除") private String isDelete; - /** 供应计划ID(对应供应计划表主键) */ - @Excel(name = "供应计划ID", readConverterExp = "对=应供应计划表主键") + /** 供应计划ID */ + @Excel(name = "供应计划ID") private Long gysJhId; - /** $column.columnComment */ - @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + /** rdid */ private Long rdid; - /** $column.columnComment */ - @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + /** rdidCk */ private Long rdidCk; - /** $column.columnComment */ - @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + /** sid */ private Long sid; /** 是否需要配送(0否,1是,2配送中,3配送完成) */ - @Excel(name = "是否需要配送(0否,1是,2配送中,3配送完成)") private String isDelivery; /** 封样编号1 */ - @Excel(name = "封样编号1") private String fycde1; /** 封样编号2 */ - @Excel(name = "封样编号2") private String fycde2; - /** 1已更新 */ - @Excel(name = "1已更新") + /** 是否已更新 */ private Long isUpdate; + /** 备注 */ + @Excel(name = "备注") + private String remark; + + /** 查询开始时间 */ + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date startDate; + + /** 查询结束时间 */ + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date endDate; public void setId(Long id) { this.id = id; @@ -237,6 +267,14 @@ public class RkInfo extends BaseEntity return operationType; } + public String getOperationTypeName() { + return operationTypeName; + } + + public void setOperationTypeName(String operationTypeName) { + this.operationTypeName = operationTypeName; + } + public String getExecStatus() { return execStatus; } @@ -256,6 +294,14 @@ public class RkInfo extends BaseEntity return wlType; } + public String getWlTypeName() { + return wlTypeName; + } + + public void setWlTypeName(String wlTypeName) { + this.wlTypeName = wlTypeName; + } + public void setCangku(String cangku) { this.cangku = cangku; @@ -266,6 +312,30 @@ public class RkInfo extends BaseEntity return cangku; } + public String getWarehouseName() { + return warehouseName; + } + + public void setWarehouseName(String warehouseName) { + this.warehouseName = warehouseName; + } + + public String getParentWarehouseCode() { + return parentWarehouseCode; + } + + public void setParentWarehouseCode(String parentWarehouseCode) { + this.parentWarehouseCode = parentWarehouseCode; + } + + public String getParentWarehouseName() { + return parentWarehouseName; + } + + public void setParentWarehouseName(String parentWarehouseName) { + this.parentWarehouseName = parentWarehouseName; + } + public void setOperationTime(Date operationTime) { this.operationTime = operationTime; @@ -292,6 +362,15 @@ public class RkInfo extends BaseEntity this.operator = operator; } + public String getOperatorName() { + return operatorName; + } + + public void setOperatorName(String operatorName) { + this.operatorName = operatorName; + } + + public void setIsChuku(String isChuku) { this.isChuku = isChuku; @@ -672,18 +751,48 @@ public class RkInfo extends BaseEntity return isUpdate; } + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + public Date getStartDate() { + return startDate; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + public Date getEndDate() { + return endDate; + } + + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) .append("id", getId()) .append("bizType", getBizType()) .append("operationType", getOperationType()) + .append("operationTypeName", operationTypeName) .append("execStatus", getExecStatus()) .append("wlType", getWlType()) + .append("wlTypeName", wlTypeName) .append("cangku", getCangku()) + .append("warehouseName", getWarehouseName()) + .append("parentWarehouseCode", getParentWarehouseCode()) + .append("parentWarehouseName", getParentWarehouseName()) .append("operationTime", getOperationTime()) .append("stockAge", getStockAge()) .append("operator", operator) + .append("operatorName", operatorName) .append("isChuku", getIsChuku()) .append("status", getStatus()) .append("remark", getRemark()) @@ -727,6 +836,8 @@ public class RkInfo extends BaseEntity .append("fycde1", getFycde1()) .append("fycde2", getFycde2()) .append("isUpdate", getIsUpdate()) + .append("startDate", startDate) + .append("endDate", endDate) .toString(); } } diff --git a/src/main/java/com/zg/project/wisdom/domain/RkRecord.java b/src/main/java/com/zg/project/wisdom/domain/RkRecord.java index c6a5fb4..a6fd686 100644 --- a/src/main/java/com/zg/project/wisdom/domain/RkRecord.java +++ b/src/main/java/com/zg/project/wisdom/domain/RkRecord.java @@ -2,11 +2,14 @@ package com.zg.project.wisdom.domain; import java.math.BigDecimal; import java.util.Date; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonFormat; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import com.zg.framework.aspectj.lang.annotation.Excel; import com.zg.framework.web.domain.BaseEntity; +import org.springframework.format.annotation.DateTimeFormat; /** * 出入库记录对象 rk_record @@ -21,10 +24,11 @@ public class RkRecord extends BaseEntity /** 主键ID */ private Long id; + /** 批量操作ID集合(不落库) */ + private List ids; /** 业务类型 */ - @Excel(name = "业务类型") + @Excel(name = "业务类型", readConverterExp = "0=入库,1=出库,2=借料出库,3=还料入库") private String bizType; - /** 出入库类型 */ // @Excel(name = "出入库类型") private String operationType; @@ -33,9 +37,12 @@ public class RkRecord extends BaseEntity @Excel(name = "出入库类型名称") private String operationTypeName; + /** 施工队 */ + @Excel(name = "施工队") + private String teamCode; /** 执行状态(0预入/预出,1已完成) */ - @Excel(name = "执行状态", readConverterExp = "0=预入/预出,1=已完成") + @Excel(name = "执行状态", readConverterExp = "0=预操作,1=已完成") private String execStatus; /** 物资类型 */ @@ -75,7 +82,7 @@ public class RkRecord extends BaseEntity private String operatorName; /** 是否已出库(0已入库,1已出库) */ - @Excel(name = "是否已出库", readConverterExp = "0=已入库,1已出库") +// @Excel(name = "是否已出库", readConverterExp = "0=已入库,1已出库") private String isChuku; /** 0:入库待审核,1已通过,2已驳回,3出库待审核 */ @@ -174,10 +181,6 @@ public class RkRecord extends BaseEntity @Excel(name = "实物ID") private String entityId; - /** 施工队 */ - @Excel(name = "施工队") - private String teamCode; - /** 借用时间 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") // @Excel(name = "借用时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") @@ -233,15 +236,19 @@ public class RkRecord extends BaseEntity private Long isUpdate; /** 入库 / 出库开始时间(查询用) */ - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date startDate; - /** 入库 / 出库结束时间(查询用) */ - @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date endDate; /** 对应 rk_info 主键ID */ private Long rkInfoId; + /** 备注 */ + @Excel(name = "备注") + private String remark; public void setId(Long id) { @@ -253,6 +260,14 @@ public class RkRecord extends BaseEntity return id; } + public java.util.List getIds() { + return ids; + } + + public void setIds(java.util.List ids) { + this.ids = ids; + } + public void setBizType(String bizType) { this.bizType = bizType; } @@ -760,6 +775,14 @@ public class RkRecord extends BaseEntity this.startDate = startDate; } + public Date getEndDate() { + return endDate; + } + + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + public Long getRkInfoId() { return rkInfoId; } @@ -767,11 +790,18 @@ public class RkRecord extends BaseEntity public void setRkInfoId(Long rkInfoId) { this.rkInfoId = rkInfoId; } + public String getRemark() { + return remark; + } + public void setRemark(String remark) { + this.remark = remark; + } @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) .append("id", getId()) + .append("ids", ids) .append("bizType", getBizType()) .append("operationType", getOperationType()) .append("operationTypeName", operationTypeName) diff --git a/src/main/java/com/zg/project/wisdom/mapper/RkBillMapper.java b/src/main/java/com/zg/project/wisdom/mapper/RkBillMapper.java index 4050eb2..72535d6 100644 --- a/src/main/java/com/zg/project/wisdom/mapper/RkBillMapper.java +++ b/src/main/java/com/zg/project/wisdom/mapper/RkBillMapper.java @@ -2,6 +2,7 @@ package com.zg.project.wisdom.mapper; import java.util.List; import com.zg.project.wisdom.domain.RkBill; +import io.lettuce.core.dynamic.annotation.Param; /** * 库存单据Mapper接口 @@ -65,4 +66,16 @@ public interface RkBillMapper * @return */ RkBill selectByBillNo(String billNo); + + /** + * 修改执行状态 + * @param billNo + * @param execStatus + * @return + */ + void updateExecStatusByBillNo( + @Param("billNo") String billNo, + @Param("execStatus") String execStatus + ); + } diff --git a/src/main/java/com/zg/project/wisdom/mapper/RkInfoMapper.java b/src/main/java/com/zg/project/wisdom/mapper/RkInfoMapper.java index b05a2f3..5187d3d 100644 --- a/src/main/java/com/zg/project/wisdom/mapper/RkInfoMapper.java +++ b/src/main/java/com/zg/project/wisdom/mapper/RkInfoMapper.java @@ -2,6 +2,7 @@ package com.zg.project.wisdom.mapper; import java.util.List; import com.zg.project.wisdom.domain.RkInfo; +import io.lettuce.core.dynamic.annotation.Param; /** * 库存单据明细Mapper接口 @@ -58,4 +59,10 @@ public interface RkInfoMapper * @return 结果 */ public int deleteRkInfoByIds(Long[] ids); + + /** + * 修改库存明细执行状态 + */ + int updateExecStatusByIds(@Param("ids") List ids, + @Param("execStatus") String execStatus); } diff --git a/src/main/java/com/zg/project/wisdom/mapper/RkRecordMapper.java b/src/main/java/com/zg/project/wisdom/mapper/RkRecordMapper.java index 8ef5238..71b990c 100644 --- a/src/main/java/com/zg/project/wisdom/mapper/RkRecordMapper.java +++ b/src/main/java/com/zg/project/wisdom/mapper/RkRecordMapper.java @@ -1,7 +1,11 @@ package com.zg.project.wisdom.mapper; +import java.util.Date; import java.util.List; + +import com.zg.project.wisdom.domain.RkInfo; import com.zg.project.wisdom.domain.RkRecord; +import io.lettuce.core.dynamic.annotation.Param; /** * 出入库记录Mapper接口 @@ -66,4 +70,29 @@ public interface RkRecordMapper * @return 结果 */ public int deleteRkRecordByIds(Long[] ids); + + /** + * 修改执行状态 + * + * @param ids 出入库记录主键 + * @param execStatus 执行状态 + * @return 结果 + */ + + int updateExecStatusByIds(@Param("ids") List ids, + @Param("execStatus") String execStatus); + /** + * 根据ID列表查询记录列表 + * + * @param ids ID列表 + * @return 记录列表 + */ + List selectRkRecordByIds(@Param("ids") List ids); + + /** + * 根据单据ID更新记录 + * + * @param rkInfo 单据信息 + */ + void updateByRkInfo(RkInfo rkInfo); } diff --git a/src/main/java/com/zg/project/wisdom/service/IRkRecordService.java b/src/main/java/com/zg/project/wisdom/service/IRkRecordService.java index 03aefb6..a4c3eaa 100644 --- a/src/main/java/com/zg/project/wisdom/service/IRkRecordService.java +++ b/src/main/java/com/zg/project/wisdom/service/IRkRecordService.java @@ -66,4 +66,14 @@ public interface IRkRecordService * @return 结果 */ public int deleteRkRecordById(Long id); + + /** + * 批量将指定入库记录回退为预入库 + */ + int rollbackToPreIn(List recordIds); + + /** + * 批量将指定入库记录完成入库 + */ + int finishIn(List ids); } diff --git a/src/main/java/com/zg/project/wisdom/service/impl/MoveRecordServiceImpl.java b/src/main/java/com/zg/project/wisdom/service/impl/MoveRecordServiceImpl.java index d58696c..ad9faac 100644 --- a/src/main/java/com/zg/project/wisdom/service/impl/MoveRecordServiceImpl.java +++ b/src/main/java/com/zg/project/wisdom/service/impl/MoveRecordServiceImpl.java @@ -11,11 +11,13 @@ import com.zg.common.utils.SecurityUtils; import com.zg.project.information.domain.PcdeDetail; import com.zg.project.information.mapper.PcdeDetailMapper; import com.zg.project.wisdom.domain.RkInfo; +import com.zg.project.wisdom.domain.RkRecord; import com.zg.project.wisdom.domain.dto.MoveRequestDTO; import com.zg.project.wisdom.domain.dto.MoveTargetItem; import com.zg.project.wisdom.mapper.MoveRecordMapper; import com.zg.project.wisdom.domain.MoveRecord; import com.zg.project.wisdom.mapper.RkInfoMapper; +import com.zg.project.wisdom.mapper.RkRecordMapper; import com.zg.project.wisdom.service.IMoveRecordService; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -37,6 +39,9 @@ public class MoveRecordServiceImpl implements IMoveRecordService @Autowired private RkInfoMapper rkInfoMapper; + @Autowired + private RkRecordMapper rkRecordMapper; + @Autowired private PcdeDetailMapper pcdeDetailMapper; /** @@ -120,7 +125,7 @@ public class MoveRecordServiceImpl implements IMoveRecordService @Transactional(rollbackFor = Exception.class) public void processMove(MoveRequestDTO dto) { - // 0. 基本校验 + // ========= 0. 基本校验 ========= if (dto == null || dto.getFromRkId() == null) { throw new ServiceException("原库存ID不能为空"); } @@ -128,128 +133,125 @@ public class MoveRecordServiceImpl implements IMoveRecordService throw new ServiceException("目标位置列表不能为空"); } - // 1. 查询原始库存记录 + // ========= 1. 查询原库存 ========= RkInfo original = rkInfoMapper.selectRkInfoById(dto.getFromRkId()); if (original == null || "1".equals(original.getIsDelete())) { throw new ServiceException("原库存不存在或已删除"); } - // 2. 计算目标总数量 - BigDecimal totalQty = dto.getTargets().stream() + BigDecimal originQty = original.getRealQty(); + if (originQty == null) { + throw new ServiceException("原库存数量为空"); + } + + // ========= 2. 计算移库总量 ========= + BigDecimal moveTotalQty = dto.getTargets().stream() .map(MoveTargetItem::getRealQty) .reduce(BigDecimal.ZERO, BigDecimal::add); - // 3. 原始库存数量 - BigDecimal realQty = original.getRealQty(); - if (realQty == null) { - throw new ServiceException("原库存数量为空,无法进行比较"); + if (moveTotalQty.compareTo(originQty) > 0) { + throw new ServiceException("移库数量不能大于原库存数量"); } - if (totalQty.compareTo(realQty) > 0) { - throw new ServiceException("拆分总数量不能大于原库存数量"); + Long userId = SecurityUtils.getUserId(); + String username = userId.toString(); + Date now = DateUtils.getNowDate(); + + // ========= 3. 快照(只用于拷贝字段) ========= + RkInfo snapshot = new RkInfo(); + BeanUtils.copyProperties(original, snapshot); + + // ========= 4. 查询原 rk_record(用于同步更新) ========= + RkRecord originRecord = rkRecordMapper.selectRkRecordById(original.getId()); + if (originRecord == null) { + throw new ServiceException("未找到对应的出入库记录"); } - // 4. 操作信息 - String username = dto.getMovedBy(); - Date now = DateUtils.parseDate(dto.getMovedAt()); + // ================== 一、全量移库 ================== + if (dto.getTargets().size() == 1 && moveTotalQty.compareTo(originQty) == 0) { - // ===== 情况一:整库移库(单目标 + 数量相等)===== - if (dto.getTargets().size() == 1 && totalQty.compareTo(realQty) == 0) { MoveTargetItem target = dto.getTargets().get(0); - // 移库前快照 - RkInfo snapshot = new RkInfo(); - BeanUtils.copyProperties(original, snapshot); - - // 更新原库存位置 + // 1️⃣ rk_info:更新库位 original.setCangku(target.getToCangku()); original.setPcode(target.getToPcode()); original.setTrayCode(target.getToTrayCode()); original.setHasMoved("1"); - original.setUpdateBy(username); original.setUpdateTime(now); rkInfoMapper.updateRkInfo(original); - // 移库记录 + // 2️⃣ rk_record:同步更新库位 + originRecord.setCangku(target.getToCangku()); + originRecord.setPcode(target.getToPcode()); + originRecord.setTrayCode(target.getToTrayCode()); + originRecord.setHasMoved("1"); + originRecord.setUpdateBy(username); + originRecord.setUpdateTime(now); + rkRecordMapper.updateRkRecord(originRecord); + + // 3️⃣ move_record:记录移库流水(绑定原 rk_info.id) moveRecordMapper.insertMoveRecord( - createMoveRecord(snapshot, target, dto) + createMoveRecord(original, target, dto) ); + return; } - // ===== 情况二 / 三:拆分移库 ===== - List insertList = new ArrayList<>(); + // ================== 二、部分移库 ================== - // 来源快照(用于日志 & 新库存模板) - RkInfo fromSnapshot = new RkInfo(); - BeanUtils.copyProperties(original, fromSnapshot); + // 1️⃣ 原 rk_info 扣减数量 + original.setRealQty(originQty.subtract(moveTotalQty)); + original.setHasMoved("1"); + original.setUpdateBy(username); + original.setUpdateTime(now); + rkInfoMapper.updateRkInfo(original); - // 情况三:部分移库(原库存减少) - if (totalQty.compareTo(realQty) < 0) { - original.setRealQty(realQty.subtract(totalQty)); - original.setHasMoved("1"); - original.setUpdateBy(username); - original.setUpdateTime(now); - rkInfoMapper.updateRkInfo(original); - } else { - // 情况二:原库存刚好用完(但目标多个) - rkInfoMapper.deleteRkInfoById(original.getId()); - } + // 2️⃣ 原 rk_record 扣减数量 + originRecord.setRealQty( + originRecord.getRealQty().subtract(moveTotalQty) + ); + originRecord.setHasMoved("1"); + originRecord.setUpdateBy(username); + originRecord.setUpdateTime(now); + rkRecordMapper.updateRkRecord(originRecord); - // 新增目标库存 + // 3️⃣ 新增目标库存 + 新增目标记录 for (MoveTargetItem target : dto.getTargets()) { + + // —— 新 rk_info RkInfo newInfo = new RkInfo(); - - // 以移库前快照为模板 - BeanUtils.copyProperties(fromSnapshot, newInfo, "id"); - + BeanUtils.copyProperties(snapshot, newInfo, "id"); newInfo.setCangku(target.getToCangku()); newInfo.setPcode(target.getToPcode()); newInfo.setTrayCode(target.getToTrayCode()); newInfo.setRealQty(target.getRealQty()); newInfo.setHasMoved("1"); - newInfo.setCreateBy(username); newInfo.setCreateTime(now); newInfo.setUpdateBy(username); newInfo.setUpdateTime(now); + rkInfoMapper.insertRkInfo(newInfo); - insertList.add(newInfo); + // —— 新 rk_record + RkRecord newRecord = new RkRecord(); + BeanUtils.copyProperties(originRecord, newRecord, "id"); + newRecord.setCangku(target.getToCangku()); + newRecord.setPcode(target.getToPcode()); + newRecord.setTrayCode(target.getToTrayCode()); + newRecord.setRealQty(target.getRealQty()); + newRecord.setHasMoved("1"); + newRecord.setCreateBy(username); + newRecord.setCreateTime(now); + newRecord.setUpdateBy(username); + newRecord.setUpdateTime(now); + rkRecordMapper.insertRkRecord(newRecord); - // 移库记录 + // —— move_record:绑定新生成的 rk_info.id moveRecordMapper.insertMoveRecord( - createMoveRecord(fromSnapshot, target, dto) + createMoveRecord(newInfo, target, dto) ); } - -// if (!insertList.isEmpty()) { -// rkInfoMapper.batchInsertRkInfo(insertList); -// } - } - - /** - * 校验库位与仓库(小仓)关系: - * - 库位必须存在 - * - 库位所属小仓 warehouse_code == 目标仓库编码 toCangku - */ - private void validatePcodeWarehouseRelation(String pcode, String warehouseCode) { - if (org.apache.commons.lang3.StringUtils.isBlank(pcode)) { - throw new ServiceException("目标库位不能为空"); - } - if (org.apache.commons.lang3.StringUtils.isBlank(warehouseCode)) { - throw new ServiceException("目标仓库不能为空"); - } - - PcdeDetail detail = pcdeDetailMapper.selectByPcode(pcode); - if (detail == null) { - throw new ServiceException("目标库位不存在:" + pcode); - } - - // - if (!warehouseCode.equals(detail.getWarehouseCode())) { - throw new ServiceException("目标库位【" + pcode + "】不属于仓库【" + warehouseCode + "】,请检查移库目标设置"); - } } /** @@ -260,10 +262,18 @@ public class MoveRecordServiceImpl implements IMoveRecordService * @param dto 请求参数 * @return 构建后的移库记录 */ - private MoveRecord createMoveRecord(RkInfo info, MoveTargetItem target, MoveRequestDTO dto) { + private MoveRecord createMoveRecord(RkInfo info, + MoveTargetItem target, + MoveRequestDTO dto) { + Long userId = SecurityUtils.getUserId(); + Date now = DateUtils.getNowDate(); + MoveRecord record = new MoveRecord(); - record.setRkId(info.getId()); + + // ★ 关键:绑定 rk_info.id + record.setRkInfoId(info.getId()); + record.setEntityId(info.getEntityId()); record.setFromCangku(info.getCangku()); record.setFromPcode(info.getPcode()); @@ -273,15 +283,16 @@ public class MoveRecordServiceImpl implements IMoveRecordService record.setToTrayCode(target.getToTrayCode()); record.setMoveReason(dto.getMoveReason()); record.setMovedBy(userId.toString()); - record.setMovedAt(DateUtils.getNowDate()); + record.setMovedAt(now); record.setIsDelete("0"); record.setCreateBy(userId.toString()); + record.setCreateTime(now); record.setUpdateBy(userId.toString()); - record.setCreateTime(DateUtils.getNowDate()); - record.setUpdateTime(DateUtils.getNowDate()); + record.setUpdateTime(now); return record; } + } diff --git a/src/main/java/com/zg/project/wisdom/service/impl/RkBillServiceImpl.java b/src/main/java/com/zg/project/wisdom/service/impl/RkBillServiceImpl.java index 3126318..5559947 100644 --- a/src/main/java/com/zg/project/wisdom/service/impl/RkBillServiceImpl.java +++ b/src/main/java/com/zg/project/wisdom/service/impl/RkBillServiceImpl.java @@ -8,6 +8,8 @@ import java.util.Map; import com.zg.common.utils.DateUtils; import com.zg.common.utils.SecurityUtils; import com.zg.common.utils.StringUtils; +import com.zg.project.information.domain.PcdeDetail; +import com.zg.project.information.mapper.PcdeDetailMapper; import com.zg.project.wisdom.domain.GysJh; import com.zg.project.wisdom.domain.RkInfo; import com.zg.project.wisdom.domain.RkRecord; @@ -47,6 +49,9 @@ public class RkBillServiceImpl implements IRkBillService @Autowired private GysJhMapper gysJhMapper; + @Autowired + private PcdeDetailMapper pcdeDetailMapper; + /** * 查询库存单据 * @@ -102,18 +107,18 @@ public class RkBillServiceImpl implements IRkBillService } bill.setBillNo(billNo); - bill.setBizType("0"); // 入库 + bill.setBizType("0"); // 入库 bill.setOperationTime(now); bill.setCreateTime(now); bill.setCreateBy(userId); bill.setIsDelete("0"); - // operator:如果前端没传,默认当前登录人(Integer) + // operator:默认当前登录人 if (bill.getOperator() == null) { bill.setOperator(Integer.valueOf(userId)); } - // execStatus:前端优先,默认 1 + // execStatus:默认已完成 if (StringUtils.isBlank(bill.getExecStatus())) { bill.setExecStatus("1"); } @@ -123,14 +128,24 @@ public class RkBillServiceImpl implements IRkBillService // ================== 2. 明细 + 事件 + 供应计划 ================== for (RkInfo info : dto.getRkInfoList()) { + // ===== ① 根据 pcode 查询 pcde_detail,获取 encoded_id ===== + if (StringUtils.isNotBlank(info.getPcode())) { + + PcdeDetail pcde = pcdeDetailMapper.selectByPcode(info.getPcode()); + if (pcde == null) { + throw new RuntimeException("库位不存在:" + info.getPcode()); + } + + info.setPcodeId(pcde.getEncodedId()); + } + // ---------- rk_info ---------- info.setBillNo(billNo); info.setBizType(bill.getBizType()); info.setOperationType(bill.getOperationType()); info.setOperationTime(bill.getOperationTime()); - info.setOperator(bill.getOperator()); // Integer + info.setOperator(bill.getOperator()); info.setWlType(bill.getWlType()); - info.setRemark(bill.getRemark()); info.setCangku(bill.getCangku()); info.setIsChuku("0"); @@ -147,6 +162,7 @@ public class RkBillServiceImpl implements IRkBillService // ---------- rk_record ---------- RkRecord record = buildInRkRecord(bill, info, now); record.setExecStatus(bill.getExecStatus()); + record.setPcodeId(info.getPcodeId()); rkRecordMapper.insertRkRecord(record); @@ -194,18 +210,17 @@ public class RkBillServiceImpl implements IRkBillService RkRecord record = new RkRecord(); - // ① 明细 → 事件快照 + // ① 明细 → 事件快照(包含 remark) BeanUtils.copyProperties(info, record); record.setId(null); - // ② 主单 → 事件上下文 + // ② 主单 → 事件上下文(不包含 remark) record.setBillNo(bill.getBillNo()); record.setBizType(bill.getBizType()); record.setOperationType(bill.getOperationType()); record.setOperationTime(bill.getOperationTime()); - record.setOperator(bill.getOperator()); // Integer + record.setOperator(bill.getOperator()); record.setWlType(bill.getWlType()); - record.setRemark(bill.getRemark()); record.setCangku(bill.getCangku()); // ③ 状态字段 @@ -241,13 +256,13 @@ public class RkBillServiceImpl implements IRkBillService String billNo = dto.getRkBill().getBillNo(); Date now = DateUtils.getNowDate(); - // ================== 1. 查主单(存在性校验 + 不可改字段来源) ================== + // ================== 1. 查主单 ================== RkBill bill = rkBillMapper.selectByBillNo(billNo); if (bill == null) { throw new RuntimeException("单据不存在:" + billNo); } - // ================== 2. execStatus 以【前端传入】为准 ================== + // ================== 2. execStatus 规则 ================== String execStatus = dto.getRkBill().getExecStatus(); if (StringUtils.isBlank(execStatus)) { execStatus = bill.getExecStatus(); @@ -256,10 +271,21 @@ public class RkBillServiceImpl implements IRkBillService // ================== 3. 追加明细 ================== for (RkInfo info : dto.getRkInfoList()) { + // ===== ① 根据 pcode 查询 pcde_detail → encoded_id(关键新增) ===== + if (StringUtils.isNotBlank(info.getPcode())) { + + PcdeDetail pcde = pcdeDetailMapper.selectByPcode(info.getPcode()); + if (pcde == null) { + throw new RuntimeException("库位不存在:" + info.getPcode()); + } + + info.setPcodeId(pcde.getEncodedId()); + } + // ---------- 基础关联 ---------- info.setBillNo(bill.getBillNo()); - // ---------- 类型信息(不可由前端随意改) ---------- + // ---------- 类型信息(来源于主单,不信前端) ---------- info.setOperationType(bill.getOperationType()); info.setBizType(bill.getBizType()); info.setWlType(bill.getWlType()); @@ -279,8 +305,7 @@ public class RkBillServiceImpl implements IRkBillService info.setHasMoved("0"); info.setIsBorrowed("0"); - // ---------- 备注(关键新增) ---------- - // 明细备注优先,其次单据备注 + // ---------- 备注 ---------- String finalRemark = info.getRemark(); if (StringUtils.isBlank(finalRemark)) { finalRemark = bill.getRemark(); @@ -295,24 +320,26 @@ public class RkBillServiceImpl implements IRkBillService // ---------- 插入 rk_info ---------- rkInfoMapper.insertRkInfo(info); - // ---------- rk_record:事件流水 ---------- + // ---------- rk_record ---------- RkRecord record = buildInRkRecord(bill, info, now); record.setExecStatus(execStatus); record.setRkInfoId(info.getId()); - // ⭐ 同步备注到事件表(非常重要) + // ⭐ encoded_id 同步 + record.setPcodeId(info.getPcodeId()); + + // ⭐ 备注同步 record.setRemark(finalRemark); rkRecordMapper.insertRkRecord(record); - // ---------- 供应计划处理 ---------- + // ---------- 供应计划 ---------- handleGysJhAfterInStock(info); } return 1; } - /** * 修改库存单据 * diff --git a/src/main/java/com/zg/project/wisdom/service/impl/RkInfoServiceImpl.java b/src/main/java/com/zg/project/wisdom/service/impl/RkInfoServiceImpl.java index 0c8cdd6..b88f47a 100644 --- a/src/main/java/com/zg/project/wisdom/service/impl/RkInfoServiceImpl.java +++ b/src/main/java/com/zg/project/wisdom/service/impl/RkInfoServiceImpl.java @@ -2,11 +2,13 @@ package com.zg.project.wisdom.service.impl; import java.util.List; import com.zg.common.utils.DateUtils; +import com.zg.project.wisdom.mapper.RkRecordMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.zg.project.wisdom.mapper.RkInfoMapper; import com.zg.project.wisdom.domain.RkInfo; import com.zg.project.wisdom.service.IRkInfoService; +import org.springframework.transaction.annotation.Transactional; /** * 库存单据明细Service业务层处理 @@ -20,6 +22,9 @@ public class RkInfoServiceImpl implements IRkInfoService @Autowired private RkInfoMapper rkInfoMapper; + @Autowired + private RkRecordMapper rkRecordMapper; + /** * 查询库存单据明细 * @@ -64,12 +69,19 @@ public class RkInfoServiceImpl implements IRkInfoService * @return 结果 */ @Override + @Transactional(rollbackFor = Exception.class) public int updateRkInfo(RkInfo rkInfo) { rkInfo.setUpdateTime(DateUtils.getNowDate()); - return rkInfoMapper.updateRkInfo(rkInfo); - } + // ① 更新 rk_info + int rows = rkInfoMapper.updateRkInfo(rkInfo); + + // ② 同步更新 rk_record(按 rk_info_id) + rkRecordMapper.updateByRkInfo(rkInfo); + + return rows; + } /** * 批量删除库存单据明细 * diff --git a/src/main/java/com/zg/project/wisdom/service/impl/RkRecordServiceImpl.java b/src/main/java/com/zg/project/wisdom/service/impl/RkRecordServiceImpl.java index 4524128..ba353aa 100644 --- a/src/main/java/com/zg/project/wisdom/service/impl/RkRecordServiceImpl.java +++ b/src/main/java/com/zg/project/wisdom/service/impl/RkRecordServiceImpl.java @@ -1,12 +1,22 @@ package com.zg.project.wisdom.service.impl; import java.util.List; +import java.util.Objects; +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.wisdom.domain.RkInfo; +import com.zg.project.wisdom.mapper.RkBillMapper; +import com.zg.project.wisdom.mapper.RkInfoMapper; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.zg.project.wisdom.mapper.RkRecordMapper; import com.zg.project.wisdom.domain.RkRecord; import com.zg.project.wisdom.service.IRkRecordService; +import org.springframework.transaction.annotation.Transactional; /** * 出入库记录Service业务层处理 @@ -20,6 +30,12 @@ public class RkRecordServiceImpl implements IRkRecordService @Autowired private RkRecordMapper rkRecordMapper; + @Autowired + private RkInfoMapper rkInfoMapper; + + @Autowired + private RkBillMapper rkBillMapper; + /** * 查询出入库记录 * @@ -70,12 +86,39 @@ public class RkRecordServiceImpl implements IRkRecordService * @return 结果 */ @Override + @Transactional(rollbackFor = Exception.class) public int updateRkRecord(RkRecord rkRecord) { + // 1. 更新时间 rkRecord.setUpdateTime(DateUtils.getNowDate()); - return rkRecordMapper.updateRkRecord(rkRecord); - } + // 2. 更新 rk_record + int rows = rkRecordMapper.updateRkRecord(rkRecord); + if (rows <= 0) { + throw new RuntimeException("更新出入库记录失败"); + } + + // 3. 同步更新 rk_info + Long rkInfoId = rkRecord.getRkInfoId(); + if (rkInfoId == null) { + throw new RuntimeException("rkInfoId 为空,无法同步更新库存表"); + } + + // 4. 将 record 中的字段映射到 info + RkInfo rkInfo = new RkInfo(); + BeanUtils.copyProperties(rkRecord, rkInfo); + + // ⚠️ 关键:主键必须用 rk_info.id + rkInfo.setId(rkInfoId); + rkInfo.setUpdateTime(DateUtils.getNowDate()); + + int infoRows = rkInfoMapper.updateRkInfo(rkInfo); + if (infoRows <= 0) { + throw new RuntimeException("同步更新库存表失败"); + } + + return rows; + } /** * 批量删除出入库记录 * @@ -99,4 +142,106 @@ public class RkRecordServiceImpl implements IRkRecordService { return rkRecordMapper.deleteRkRecordById(id); } + + @Override + @Transactional(rollbackFor = Exception.class) + public int rollbackToPreIn(List recordIds) { + + if (recordIds == null || recordIds.isEmpty()) { + throw new ServiceException("撤销记录ID不能为空"); + } + + // 1️⃣ 查 records + List recordList = rkRecordMapper.selectRkRecordByIds(recordIds); + if (recordList == null || recordList.isEmpty()) { + throw new ServiceException("入库记录不存在"); + } + + // 2️⃣ rk_record 批量回退 exec_status = 0 + rkRecordMapper.updateExecStatusByIds(recordIds, "0"); + + // 3️⃣ rk_info 批量回退 exec_status = 0 + List rkInfoIds = recordList.stream() + .map(RkRecord::getRkInfoId) + .filter(Objects::nonNull) + .distinct() + .collect(Collectors.toList()); + if (!rkInfoIds.isEmpty()) { + rkInfoMapper.updateExecStatusByIds(rkInfoIds, "0"); + } + + // 4️⃣ rk_bill:保持原 Mapper 方法不变,按 billNo 去重后循环调用 + List billNos = recordList.stream() + .map(RkRecord::getBillNo) + .filter(StringUtils::isNotBlank) + .distinct() + .collect(Collectors.toList()); + + for (String billNo : billNos) { + rkBillMapper.updateExecStatusByBillNo(billNo, "0"); + } + + return recordIds.size(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public int finishIn(List recordIds) { + + if (recordIds == null || recordIds.isEmpty()) { + throw new ServiceException("入库记录ID不能为空"); + } + + // 1️⃣ 查询 rk_record + List recordList = + rkRecordMapper.selectRkRecordByIds(recordIds); + + if (recordList == null || recordList.isEmpty()) { + throw new ServiceException("入库记录不存在"); + } + + // ================== ① 只保留「预入库」记录 ================== + List preRecordList = recordList.stream() + .filter(r -> "0".equals(r.getExecStatus())) + .collect(Collectors.toList()); + + // ================== ② 如果没有可完成的数据,才报错 ================== + if (preRecordList.isEmpty()) { + throw new ServiceException("所选入库记录均已完成,无需重复入库"); + } + + // ================== ③ 后续逻辑全部基于 preRecordList ================== + + List preRecordIds = preRecordList.stream() + .map(RkRecord::getId) + .collect(Collectors.toList()); + + // 2️⃣ rk_record.exec_status = 1 + rkRecordMapper.updateExecStatusByIds(preRecordIds, "1"); + + // 3️⃣ rk_info.exec_status = 1 + List rkInfoIds = preRecordList.stream() + .map(RkRecord::getRkInfoId) + .filter(Objects::nonNull) + .distinct() + .collect(Collectors.toList()); + + if (!rkInfoIds.isEmpty()) { + rkInfoMapper.updateExecStatusByIds(rkInfoIds, "1"); + } + + // 4️⃣ rk_bill.exec_status = 1 + List billNos = preRecordList.stream() + .map(RkRecord::getBillNo) + .filter(StringUtils::isNotBlank) + .distinct() + .collect(Collectors.toList()); + + for (String billNo : billNos) { + rkBillMapper.updateExecStatusByBillNo(billNo, "1"); + } + + return preRecordIds.size(); + } + } diff --git a/src/main/resources/mybatis/wisdom/MoveRecordMapper.xml b/src/main/resources/mybatis/wisdom/MoveRecordMapper.xml index d0162ab..c026414 100644 --- a/src/main/resources/mybatis/wisdom/MoveRecordMapper.xml +++ b/src/main/resources/mybatis/wisdom/MoveRecordMapper.xml @@ -5,10 +5,13 @@ - + - + + + + @@ -25,25 +28,46 @@ + + - + - SELECT id, rk_id, entity_id, from_cangku, from_pcode, from_tray_code, - to_cangku, to_pcode, to_tray_code, move_reason, moved_by, moved_at, - create_by, create_time, update_by, update_time, is_delete + SELECT + id, + rk_info_id, + entity_id, + from_cangku, + from_pcode, + from_tray_code, + to_cangku, + to_pcode, + to_tray_code, + move_reason, + moved_by, + moved_at, + create_by, + create_time, + update_by, + update_time, + is_delete FROM move_record - + + INSERT INTO move_record ( - rk_id, + rk_info_id, entity_id, from_cangku, from_pcode, @@ -60,7 +84,7 @@ update_time, is_delete ) VALUES ( - #{rkId}, + #{rkInfoId}, #{entityId}, #{fromCangku}, #{fromPcode}, @@ -79,20 +103,20 @@ ) - + - - WHERE id = #{id} - - + + UPDATE move_record - rk_id = #{rkId}, + rk_info_id = #{rkInfoId}, entity_id = #{entityId}, from_cangku = #{fromCangku}, from_pcode = #{fromPcode}, @@ -143,12 +170,11 @@ WHERE id = #{id} - + DELETE FROM move_record WHERE id = #{id} - DELETE FROM move_record WHERE id IN diff --git a/src/main/resources/mybatis/wisdom/RkBillMapper.xml b/src/main/resources/mybatis/wisdom/RkBillMapper.xml index 5437c1e..d2e7453 100644 --- a/src/main/resources/mybatis/wisdom/RkBillMapper.xml +++ b/src/main/resources/mybatis/wisdom/RkBillMapper.xml @@ -6,30 +6,30 @@ - - - + + + - - - + + + - + - - + + - - - + + + - - + + - - - - + + + + @@ -49,44 +49,25 @@ rb.is_delivery, rb.is_delete, - -- 物资类型 mt.type_name AS wl_type_name, - - -- 出 / 入库类型名称 COALESCE(sit.type_name, sot.type_name) AS operation_type_name, - - -- 操作人 su.nick_name AS operator_name, - - -- 小仓 wh.warehouse_name AS warehouse_name, - - -- 大仓(冗余字段) wh.parent_warehouse_name AS parent_warehouse_name FROM rk_bill rb - - -- 仓库(小仓) LEFT JOIN warehouse_info wh ON rb.cangku = wh.warehouse_code AND wh.status = 1 - - -- 物资类型 LEFT JOIN material_type mt ON rb.wl_type = mt.type_code AND mt.status = 1 - - -- 入库类型 LEFT JOIN stock_in_type sit ON rb.operation_type = sit.type_code AND sit.status = 1 - - -- 出库类型 LEFT JOIN stock_out_type sot ON rb.operation_type = sot.type_code AND (sot.is_delete = '0' OR sot.is_delete IS NULL) - - -- 操作人 LEFT JOIN sys_user su ON rb.operator = su.user_id @@ -95,24 +76,67 @@ @@ -150,7 +174,6 @@ LIMIT 1 - UPDATE rk_bill - wl_type = #{wlType}, - cangku = #{cangku}, + wl_type = #{wlType}, + cangku = #{cangku}, bill_no = #{billNo}, - operation_type = #{operationType}, - biz_type = #{bizType}, + operation_type = #{operationType}, + biz_type = #{bizType}, operation_time = #{operationTime}, - exec_status = #{execStatus}, + exec_status = #{execStatus}, operator = #{operator}, - team_code = #{teamCode}, + team_code = #{teamCode}, remark = #{remark}, - is_delivery = #{isDelivery}, - is_delete = #{isDelete}, + is_delivery = #{isDelivery}, + is_delete = #{isDelete}, WHERE id = #{id} + + UPDATE rk_bill + SET exec_status = #{execStatus} + WHERE bill_no = #{billNo} + + DELETE FROM rk_bill WHERE id = #{id} diff --git a/src/main/resources/mybatis/wisdom/RkInfoMapper.xml b/src/main/resources/mybatis/wisdom/RkInfoMapper.xml index 392b3a7..df39edd 100644 --- a/src/main/resources/mybatis/wisdom/RkInfoMapper.xml +++ b/src/main/resources/mybatis/wisdom/RkInfoMapper.xml @@ -2,17 +2,25 @@ + + + + + + + + @@ -59,116 +67,114 @@ - + - select - id, - operation_type, - biz_type, - wl_type, - cangku, - operation_time, - operator, - is_chuku, - status, - exec_status, - remark, - bill_no, - xj, - xm_no, - xm_ms, - xm_no_ck, - xm_ms_ck, - wl_no, - wl_ms, - gys_no, - gys_mc, - jh_amt, - ht_dj, - sap_no, - xh, - jh_qty, - ht_qty, - dw, - real_qty, - pcode, - pcode_id, - tray_code, - entity_id, - team_code, - borrow_time, - return_time, - has_moved, - is_borrowed, - create_by, - create_time, - update_by, - update_time, - is_delete, - gys_jh_id, - rdid, - rdid_ck, - sid, - is_delivery, - fycde_1, - fycde_2, - is_update, - /* 新增库龄计算 */ - DATEDIFF(CURRENT_DATE, operation_time) AS stock_age -- 库龄(天) - from rk_info + SELECT + ri.*, + + /* 出入库类型名称 */ + COALESCE(sit.type_name, sot.type_name) AS operation_type_name, + + /* 物资类型名称 */ + mt.type_name AS wl_type_name, + + /* 仓库信息 */ + wh.warehouse_name, + wh.parent_warehouse_code, + wh.parent_warehouse_name, + + /* 理货员 */ + su.nick_name AS operator_name, + + /* 库龄 */ + DATEDIFF(CURRENT_DATE, ri.operation_time) AS stock_age + + FROM rk_info ri + + LEFT JOIN stock_in_type sit ON ri.operation_type = sit.type_code + LEFT JOIN stock_out_type sot ON ri.operation_type = sot.type_code + LEFT JOIN material_type mt ON ri.wl_type = mt.type_code + LEFT JOIN warehouse_info wh ON ri.cangku = wh.warehouse_code + LEFT JOIN sys_user su ON ri.operator = su.user_id - - - delete from rk_info where id = #{id} - - - - delete from rk_info - where id in - - #{item} - - - - + + + + DELETE FROM rk_info WHERE id = #{id} + - + + DELETE FROM rk_info + WHERE id IN + + #{item} + + + + - insert into rk_info ( + INSERT INTO rk_info ( operation_type, biz_type, wl_type, cangku, operation_time, operator, is_chuku, status, exec_status, remark, bill_no, xj, xm_no, xm_ms, xm_no_ck, xm_ms_ck, @@ -186,7 +192,7 @@ is_update, create_by, create_time, is_delete ) - values ( + VALUES ( #{operationType}, #{bizType}, #{wlType}, #{cangku}, #{operationTime}, #{operator}, #{isChuku}, #{status}, #{execStatus}, #{remark}, #{billNo}, #{xj}, #{xmNo}, #{xmMs}, #{xmNoCk}, #{xmMsCk}, @@ -206,19 +212,69 @@ ) - + - update rk_info + UPDATE rk_info operation_type = #{operationType}, biz_type = #{bizType}, wl_type = #{wlType}, cangku = #{cangku}, + operation_time = #{operationTime}, + operator = #{operator}, + is_chuku = #{isChuku}, status = #{status}, exec_status = #{execStatus}, + remark = #{remark}, + bill_no = #{billNo}, + xj = #{xj}, + xm_no = #{xmNo}, + xm_ms = #{xmMs}, + xm_no_ck = #{xmNoCk}, + xm_ms_ck = #{xmMsCk}, + wl_no = #{wlNo}, + wl_ms = #{wlMs}, + gys_no = #{gysNo}, + gys_mc = #{gysMc}, + jh_amt = #{jhAmt}, + ht_dj = #{htDj}, + sap_no = #{sapNo}, + xh = #{xh}, + jh_qty = #{jhQty}, + ht_qty = #{htQty}, + dw = #{dw}, + real_qty = #{realQty}, + pcode = #{pcode}, + pcode_id = #{pcodeId}, + tray_code = #{trayCode}, + entity_id = #{entityId}, + team_code = #{teamCode}, + borrow_time = #{borrowTime}, + return_time = #{returnTime}, + has_moved = #{hasMoved}, + is_borrowed = #{isBorrowed}, + gys_jh_id = #{gysJhId}, + rdid = #{rdid}, + rdid_ck = #{rdidCk}, + sid = #{sid}, + is_delivery = #{isDelivery}, + fycde_1 = #{fycde1}, + fycde_2 = #{fycde2}, + is_update = #{isUpdate}, update_by = #{updateBy}, update_time = #{updateTime}, + is_delete = #{isDelete}, - where id = #{id} + WHERE id = #{id} + + + UPDATE rk_info + SET exec_status = #{execStatus} + WHERE id IN + + #{id} + + + diff --git a/src/main/resources/mybatis/wisdom/RkRecordMapper.xml b/src/main/resources/mybatis/wisdom/RkRecordMapper.xml index d35e9dd..d240406 100644 --- a/src/main/resources/mybatis/wisdom/RkRecordMapper.xml +++ b/src/main/resources/mybatis/wisdom/RkRecordMapper.xml @@ -194,7 +194,6 @@ AND rr.operation_time >= #{startDate} - AND rr.operation_time <= #{endDate} @@ -216,6 +215,15 @@ ORDER BY rr.operation_time ASC + + + + UPDATE rk_record + SET exec_status = #{execStatus} + WHERE id IN + + #{id} + + + + + UPDATE rk_record + + xj = #{xj}, + xm_no = #{xmNo}, + xm_ms = #{xmMs}, + + wl_no = #{wlNo}, + wl_ms = #{wlMs}, + + gys_no = #{gysNo}, + gys_mc = #{gysMc}, + + cangku = #{cangku}, + pcode = #{pcode}, + pcode_id = #{pcodeId}, + tray_code = #{trayCode}, + + team_code = #{teamCode}, + remark = #{remark}, + + update_by = #{updateBy}, + update_time = NOW() + + WHERE rk_info_id = #{id} + + DELETE FROM rk_record WHERE id = #{id}