bug修复20260106

This commit is contained in:
2026-01-06 14:19:58 +08:00
parent 048d52b449
commit f3d993b33a
14 changed files with 241 additions and 47 deletions

View File

@@ -15,7 +15,6 @@
<packaging>jar</packaging>
<name>zg</name>
<url>http://www.zg.vip</url>
<description>智慧实物管理系统</description>
<!-- ======================= -->

View File

@@ -33,7 +33,7 @@ public class GysJhController extends BaseController
@Autowired
private IGysJhService gysJhService;
/**A
/**
* 查询供应计划列表
*/
@PreAuthorize("@ss.hasPermi('plan:jh:list')")
@@ -52,10 +52,8 @@ public class GysJhController extends BaseController
*/
// @PreAuthorize("@ss.hasPermi('plan:jh:list')")
@GetMapping("/getBySapNo")
public AjaxResult getBySapNo(String sapNo)
{
List<GysJh> list = gysJhService.getBySapNo(sapNo);
return success(list);
public AjaxResult getBySapNo(@RequestParam String sapNo) {
return gysJhService.getBySapNo(sapNo);
}
/**

View File

@@ -6,11 +6,10 @@ import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import com.github.pagehelper.PageHelper;
import com.zg.common.utils.StringUtils;
import com.zg.project.wisdom.domain.dto.*;
import com.zg.project.wisdom.domain.vo.DeliveryBillVO;
import com.zg.project.wisdom.domain.vo.PcodeQtyVO;
import com.zg.project.wisdom.service.QwenOcrRemoteService;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@@ -117,7 +116,7 @@ public class RkInfoController extends BaseController
{
List<RkInfo> list = rkInfoService.selectRkInfoList(rkInfo);
ExcelUtil<RkInfo> util = new ExcelUtil<RkInfo>(RkInfo.class);
util.exportExcel(response, list, "库存单据主数据");
util.exportExcel(response, list, "数据导出");
}
/**
@@ -152,6 +151,19 @@ public class RkInfoController extends BaseController
return toAjax(rkInfoService.updateRkInfo(rkInfo));
}
/**
* 根据出库单据号修改库存单据
*/
@PreAuthorize("@ss.hasPermi('wisdom:stock:edit')")
@Log(title = "库存单据-按出库单号修改", businessType = BusinessType.UPDATE)
@PostMapping("/updateByBillNoCk")
public AjaxResult updateByBillNoCk(@RequestBody RkInfo rkInfo) {
if (StringUtils.isBlank(rkInfo.getBillNoCk())) {
return AjaxResult.error("出库单据号 billNoCk 不能为空");
}
return toAjax(rkInfoService.updateRkInfoByBillNoCk(rkInfo));
}
/**
* 删除库存单据主
*/

View File

@@ -1,6 +1,9 @@
package com.zg.project.wisdom.domain;
import java.math.BigDecimal;
import java.util.Date;
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;
@@ -77,7 +80,7 @@ public class GysJh extends BaseEntity
private String dw;
/** 0未到货1已入库2部分入库 */
@Excel(name = "0未到货1已入库2部分入库")
@Excel(name = "0未到货,1已入库,2部分入库")
private String status;
/** 身份码 */
@@ -89,9 +92,17 @@ public class GysJh extends BaseEntity
private String remark;
/** 是否删除0正常 1删除 */
@Excel(name = "是否删除", readConverterExp = "0=正常,1=删除")
// @Excel(name = "是否删除", readConverterExp = "0=正常,1=删除")
private String isDelete;
/** 查询开始时间yyyy-MM-dd HH:mm:ss */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date beginTime;
/** 查询结束时间yyyy-MM-dd HH:mm:ss */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date endTime;
public void setId(Long id)
{
this.id = id;
@@ -278,6 +289,23 @@ public class GysJh extends BaseEntity
return isDelete;
}
public Date getBeginTime() {
return beginTime;
}
public void setBeginTime(Date beginTime) {
this.beginTime = beginTime;
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)

View File

@@ -29,8 +29,12 @@ public class RkInfo extends BaseEntity {
@TableField(exist = false)
private List<Long> ids;
/** 是否已出库0已入库1已出库2待审批3借料出库4入库撤销5出库撤销 */
@Excel(name = "库存状态", readConverterExp = "0=已入库,1=已出库,2=待审批,3=借料出库,4=入库撤销,5=出库撤销")
private String isChuku;
/** 供应计划ID对应供应计划表主键 */
@Excel(name = "供应计划ID")
// @Excel(name = "供应计划ID")
private Long gysJhId;
/** 审批人ID非数据库字段 */
@@ -70,7 +74,7 @@ public class RkInfo extends BaseEntity {
/** 所属大仓编码 */
@TableField(exist = false)
@Excel(name = "所属大仓编码")
// @Excel(name = "所属大仓编码")
private String parentWarehouseCode;
/** 所属大仓名称 */
@@ -111,10 +115,6 @@ public class RkInfo extends BaseEntity {
/** 理货员名称(联查显示用,导出专用) */
private String lihuoYName;
/** 是否已出库0已入库1已出库2待审批3借料出库4入库撤销5出库撤销 */
@Excel(name = "是否已出库", readConverterExp = "0已入库1已出库2待审批3借料出库4入库撤销5出库撤销")
private String isChuku;
/** 单据号 */
@Excel(name = "单据号")
private String billNo;
@@ -124,11 +124,11 @@ public class RkInfo extends BaseEntity {
private String billNoCk;
/** 是否需要配送(0否 1是 2配送中 3配送完成) */
@Excel(name = "是否需要配送", readConverterExp = "0=否,1=是,2=配送中,3=配送完成")
// @Excel(name = "是否需要配送", readConverterExp = "0=否,1=是,2=配送中,3=配送完成")
private String isDelivery;
/** 县局 */
@Excel(name = "县局")
// @Excel(name = "县局")
private String xj;
/** 项目号 */
@@ -139,10 +139,10 @@ public class RkInfo extends BaseEntity {
@Excel(name = "库存项目描述")
private String xmMs;
@Excel(name = "领取方项目号")
// @Excel(name = "领取方项目号")
private String xmNoCk;
@Excel(name = "领取方项目描述")
// @Excel(name = "领取方项目描述")
private String xmMsCk;
/** 物料号 */
@@ -174,7 +174,7 @@ public class RkInfo extends BaseEntity {
private String sapNo;
/** 行号 */
@Excel(name = "行号")
// @Excel(name = "行号")
private String xh;
/** 计划交货数量 */
@@ -198,7 +198,7 @@ public class RkInfo extends BaseEntity {
private String pcode;
/** 库位主键IDpcde_detail.id */
@Excel(name = "库位主键ID")
// @Excel(name = "库位主键ID")
private String pcodeId;
/** 托盘码 */
@@ -206,7 +206,7 @@ public class RkInfo extends BaseEntity {
private String trayCode;
/** 实物ID */
@Excel(name = "实物ID")
// @Excel(name = "实物ID")
private String entityId;
/** 一货一图 - 货物照片URL非表字段 */
@@ -227,21 +227,21 @@ public class RkInfo extends BaseEntity {
private String teamName;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "领用时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "出库时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date lyTime;
@Excel(name = "出库备注")
private String ckRemark;
@Excel(name = "出库备注")
// @Excel(name = "审核状态")
private String status;
/** 是否移库过0否 1是 */
@Excel(name = "是否移库过")
// @Excel(name = "是否移库过")
private String hasMoved;
/** 是否借料0否 1是 2已归还 */
@Excel(name = "是否借料", readConverterExp = "0=否,1=是,2=已归还")
// @Excel(name = "是否借料", readConverterExp = "0=否,1=是,2=已归还")
private String isBorrowed;
/** 签字图片URLimage_type = sign非表字段 */

View File

@@ -14,6 +14,9 @@ public class RefundRequestDTO {
/** 新库位码 */
private String pcode;
/** 新仓库 */
private String warehouseCode;
/** 入库类型 */
private String rkType;
}

View File

@@ -34,12 +34,12 @@ public interface RkInfoMapper
/**
* 使用 selectRkInfoVo 作为子查询,外层按 bill_no 分组聚合
* 不新增 resultMap / VO直接用 RkInfoResult 映射需要的字段
*/
List<RkInfo> selectGroupedByBill(@Param("q") RkInfoQueryDTO query,
@Param("needAudit") Integer needAudit);
/**
* 修改库存单据主
*
@@ -48,6 +48,14 @@ public interface RkInfoMapper
*/
public int updateRkInfo(RkInfo rkInfo);
/**
* 根据出库单据号更新库存单据
*
* @param rkInfo 库存单据
* @return 影响行数
*/
int updateByBillNoCk(RkInfo rkInfo);
/**
* 删除库存单据主
*
@@ -107,7 +115,7 @@ public interface RkInfoMapper
List<RkInfo> selectTopOverdueStock(@Param("limit") int limit);
/**
* 出库操作
*
* @param update
*/
void updateById(RkInfo update);
@@ -230,6 +238,7 @@ public interface RkInfoMapper
Long selectPcde(RkInfo query);
int updateBillInfo(RkInfo query);
/**

View File

@@ -1,6 +1,8 @@
package com.zg.project.wisdom.service;
import java.util.List;
import com.zg.framework.web.domain.AjaxResult;
import com.zg.project.wisdom.domain.GysJh;
import com.zg.project.wisdom.domain.dto.ExcelFieldMapping;
import org.springframework.web.multipart.MultipartFile;
@@ -74,7 +76,7 @@ public interface IGysJhService
* @param sapNo
* @return
*/
List<GysJh> getBySapNo(String sapNo);
AjaxResult getBySapNo(String sapNo);
/**
* 按字段映射导入供应计划

View File

@@ -46,6 +46,14 @@ public interface IRkInfoService
*/
public int updateRkInfo(RkInfo rkInfo);
/**
* 根据出库单据号修改库存单据
*
* @param rkInfo 库存单据
* @return 影响行数
*/
int updateRkInfoByBillNoCk(RkInfo rkInfo);
/**
* 批量删除库存单据主
*
@@ -164,6 +172,7 @@ public interface IRkInfoService
Long selectPcde(RkInfo query);
public int updateBillInfo(RkInfo rkInfo);
/**

View File

@@ -8,6 +8,7 @@ import com.zg.common.exception.ServiceException;
import com.zg.common.utils.DateUtils;
import com.zg.common.utils.SecurityUtils;
import com.zg.common.utils.StringUtils;
import com.zg.framework.web.domain.AjaxResult;
import com.zg.project.wisdom.domain.dto.ExcelFieldMapping;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
@@ -162,10 +163,39 @@ public class GysJhServiceImpl implements IGysJhService
* @return
*/
@Override
public List<GysJh> getBySapNo(String sapNo) {
return gysJhMapper.getBySapNo(sapNo);
public AjaxResult getBySapNo(String sapNo) {
List<GysJh> list = gysJhMapper.getBySapNo(sapNo);
AjaxResult result = AjaxResult.success(list);
if (list == null || list.isEmpty()) {
return result;
}
// 找出已入库(status=1)的物料号,去重、过滤空值
List<String> inStockWlNos = list.stream()
.filter(x -> x != null && "1".equals(String.valueOf(x.getStatus()).trim()))
.map(GysJh::getWlNo)
.filter(wlNo -> wlNo != null && !wlNo.trim().isEmpty())
.map(String::trim)
.distinct()
.collect(java.util.stream.Collectors.toList());
if (!inStockWlNos.isEmpty()) {
result.put("warn", true);
result.put("inStockWlNos", inStockWlNos);
// 组装提示文案(可根据前端展示需要调整长度)
String msg = "该 SAP 订单号下,以下物料号已入库过,请注意:"
+ String.join("", inStockWlNos);
result.put("msg", msg);
}
return result;
}
@Override
@Transactional(rollbackFor = Exception.class)

View File

@@ -2,6 +2,8 @@ package com.zg.project.wisdom.service.impl;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
@@ -181,6 +183,7 @@ public class RkInfoServiceImpl implements IRkInfoService
boolean needAudit = "1".equals(configService.selectConfigByKey("rk.audit.enabled"));
// 直接传给 Mapper不改 DTO 结构,走多参数方式
return rkInfoMapper.selectGroupedByBill(query, needAudit ? 1 : 0);
// return rkInfoMapper.selectGroupedByBillSimple(query);
}
@Override
@@ -233,6 +236,42 @@ public class RkInfoServiceImpl implements IRkInfoService
return rkInfoMapper.updateRkInfo(rkInfo);
}
@Override
@Transactional(rollbackFor = Exception.class)
public int updateRkInfoByBillNoCk(RkInfo rkInfo) {
// ====== 基础校验 ======
if (StringUtils.isBlank(rkInfo.getBillNoCk())) {
throw new ServiceException("出库单据号 billNoCk 不能为空");
}
// 通用审计字段
rkInfo.setUpdateTime(DateUtils.getNowDate());
rkInfo.setUpdateBy(SecurityUtils.getUserId().toString());
// ====== 仓库 + 库位校验(保持与你 updateRkInfo 完全一致) ======
String warehouseCode = rkInfo.getWarehouseCode();
if (StringUtils.isBlank(warehouseCode)) {
warehouseCode = rkInfo.getCangku();
}
String pcode = rkInfo.getPcode();
if (StringUtils.isNotBlank(warehouseCode) && StringUtils.isNotBlank(pcode)) {
PcRkInfoBatchDTO tmpDto = new PcRkInfoBatchDTO();
tmpDto.setWarehouseCode(warehouseCode);
PcRkInfoItemDTO item = new PcRkInfoItemDTO();
item.setPcode(pcode);
tmpDto.setRkList(Collections.singletonList(item));
validateWarehouseAndPcode(tmpDto);
}
// ====== 按 bill_no_ck 批量更新 ======
return rkInfoMapper.updateByBillNoCk(rkInfo);
}
/**
* 批量处理撤销入库 / 撤销出库的逻辑(不是通用删除接口)
*
@@ -1237,8 +1276,6 @@ public class RkInfoServiceImpl implements IRkInfoService
@Override
public int refundMaterial(RefundRequestDTO dto) {
Long originalId = dto.getOriginalId();
String newPcode = dto.getPcode();
// 1. 查原出库记录
RkInfo original = rkInfoMapper.selectRkInfoById(originalId);
if (original == null || "1".equals(original.getIsDelete())) {
@@ -1250,9 +1287,11 @@ public class RkInfoServiceImpl implements IRkInfoService
BeanUtils.copyProperties(original, newEntry);
newEntry.setId(null);
newEntry.setIsChuku("0");
newEntry.setPcode(newPcode);
newEntry.setPcode(dto.getPcode());
newEntry.setCangku(dto.getWarehouseCode());
newEntry.setRkType(dto.getRkType());
newEntry.setRkTime(DateUtils.getNowDate());
newEntry.setBorrowTime(original.getBorrowTime());
newEntry.setBillNo(BillNoUtil.generateTodayBillNo("RK", rkInfoMapper));
newEntry.setCreateBy(SecurityUtils.getUserId().toString());
newEntry.setCreateTime(DateUtils.getNowDate());
@@ -1270,6 +1309,8 @@ public class RkInfoServiceImpl implements IRkInfoService
update.setReturnTime(DateUtils.getNowDate());
update.setUpdateBy(getUsername());
update.setUpdateTime(DateUtils.getNowDate());
update.setPcode(dto.getPcode());
update.setCangku(dto.getWarehouseCode());
rkInfoMapper.updateById(update);
return rows;
@@ -1331,10 +1372,20 @@ public class RkInfoServiceImpl implements IRkInfoService
return rkInfoMapper.listRkInfoByPcode(pcode);
}
@Override
public List<RkInfo> selectAllRkInfo(RkInfo query) {
return rkInfoMapper.selectAllRkInfo(query);
List<RkInfo> list = rkInfoMapper.selectAllRkInfo(query);
Instant now = Instant.now();
for (RkInfo ri : list) {
Date rkTime = ri.getRkTime();
if (rkTime != null) {
long days = Duration.between(rkTime.toInstant(), now).toDays();
ri.setStockAge(days);
}
}
return list;
}
@Override
@@ -1346,6 +1397,7 @@ public class RkInfoServiceImpl implements IRkInfoService
public Long selectPcde(RkInfo query) {
return rkInfoMapper.selectPcde(query);
}
@Override
public int updateBillInfo(RkInfo query) {
return rkInfoMapper.updateBillInfo(query);

View File

@@ -188,7 +188,7 @@ mqtt:
# MQTT 客户端 ID在 EMQX 中唯一)
# 建议:系统名 + 模块名,避免重复
clientId: zg-wms-backend
clientId: zg-wms-backend-test
# MQTT 账号EMQX Dashboard 中配置)
username: demo02

View File

@@ -59,11 +59,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="status != null and status != ''">
and status = #{status}
</if>
and (status is null or trim(status) != '1')
<!-- and (status is null or trim(status) != '1') -->
<if test="isDelete != null and isDelete != ''">
and is_delete = #{isDelete}
</if>
<!-- 按创建时间筛选create_time 在 [beginTime, endTime] -->
<if test="beginTime != null">
and create_time <![CDATA[>=]]> #{beginTime}
</if>
<if test="endTime != null">
and create_time <![CDATA[<]]> #{endTime}
</if>
</where>
</select>
@@ -75,7 +81,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="getBySapNo" parameterType="java.lang.String" resultMap="GysJhResult">
<include refid="selectGysJhVo"/>
WHERE sap_no = #{sapNo}
AND status != '1'
</select>
<!-- 【已注释】唯一性校验查询基于SAP订单号、项目号、物料号判断是否已存在 -->

View File

@@ -181,7 +181,7 @@
sap_no, xh, jh_qty, ht_qty, dw, real_qty,
pcode, tray_code, entity_id,
ck_lihuo_y, ck_type, team_code, ck_remark,
ly_time, bill_no_ck, has_moved,
ly_time, bill_no_ck, has_moved, borrow_time,
gys_jh_id,
status,
create_by, create_time, update_by, update_time, is_delete
@@ -192,7 +192,7 @@
#{sapNo}, #{xh}, #{jhQty}, #{htQty}, #{dw}, #{realQty},
#{pcode}, #{trayCode}, #{entityId},
#{ckLihuoY}, #{ckType}, #{teamCode}, #{ckRemark},
#{lyTime}, #{billNoCk}, #{hasMoved},
#{lyTime}, #{billNoCk}, #{hasMoved}, #{borrowTime},
#{gysJhId},
#{status},
#{createBy}, #{createTime}, #{updateBy}, #{updateTime}, #{isDelete}
@@ -870,6 +870,42 @@
WHERE id = #{id}
</update>
<update id="updateByBillNoCk" parameterType="com.zg.project.wisdom.domain.RkInfo">
UPDATE rk_info
<trim prefix="SET" suffixOverrides=",">
<if test="rkType != null">rk_type = #{rkType},</if>
<if test="wlType != null">wl_type = #{wlType},</if>
<if test="cangku != null and cangku != ''">
cangku = #{cangku},
</if>
<if test="rkTime != null">rk_time = #{rkTime},</if>
<if test="lihuoY != null">lihuo_y = #{lihuoY},</if>
<if test="isChuku != null">is_chuku = #{isChuku},</if>
<if test="isBorrowed != null">is_borrowed = #{isBorrowed},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="xmNoCk != null">xm_no_ck = #{xmNoCk},</if>
<if test="xmMsCk != null">xm_ms_ck = #{xmMsCk},</if>
<if test="ckLihuoY != null">ck_lihuo_y = #{ckLihuoY},</if>
<if test="ckType != null">ck_type = #{ckType},</if>
<if test="teamCode != null">team_code = #{teamCode},</if>
<if test="ckRemark != null">ck_remark = #{ckRemark},</if>
<if test="lyTime != null">ly_time = #{lyTime},</if>
<if test="borrowTime != null">borrow_time = #{borrowTime},</if>
<if test="returnTime != null">return_time = #{returnTime},</if>
<if test="isDelivery != null">is_delivery = #{isDelivery},</if>
<if test="hasMoved != null">has_moved = #{hasMoved},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
</trim>
WHERE bill_no_ck = #{billNoCk}
AND is_delete = '0'
</update>
<update id="deleteRkInfoById" parameterType="Long">
update rk_info
<set>
@@ -905,6 +941,8 @@
<if test="lyTime != null">ly_time = #{lyTime},</if>
<if test="borrowTime != null">borrow_time = #{borrowTime},</if>
<if test="returnTime != null">return_time = #{returnTime},</if>
<if test="pcode != null and pcode != ''">pcode = #{pcode},</if>
<if test="cangku != null and cangku != ''">cangku = #{cangku},</if>
<if test="status != null">status = #{status},</if>
<if test="realQty != null">real_qty = #{realQty},</if>
</set>
@@ -988,10 +1026,20 @@
<where>
(ri.is_delete = '0' OR ri.is_delete = 0 OR ri.is_delete IS NULL)
<if test="isChuku != null and isChuku != ''">
<if test="isChukuList != null and isChukuList.size() > 0">
AND ri.is_chuku IN
<foreach collection="isChukuList"
item="item"
open="("
separator=","
close=")">
#{item}
</foreach>
</if>
<if test="(isChukuList == null or isChukuList.size() == 0)
and isChuku != null">
AND ri.is_chuku = #{isChuku}
</if>
<if test="warehouseCode != null and warehouseCode != ''">
AND ri.cangku = #{warehouseCode}
</if>
@@ -1214,7 +1262,6 @@
</if>
</where>
</select>
<select id="selectDeliveryCkList"
parameterType="com.zg.project.wisdom.domain.RkInfo"
resultMap="RkInfoResult">