merge: 合并LMS备货区域功能

This commit is contained in:
zhouz
2026-08-10 13:09:01 +08:00
20 changed files with 1289 additions and 0 deletions

View File

@@ -0,0 +1,87 @@
package cn.code.nl.module.lms.controller.admin.stockingivt;
import cn.code.nl.framework.common.pojo.CommonResult;
import cn.code.nl.framework.common.pojo.PageResult;
import cn.code.nl.module.lms.controller.admin.stockingivt.vo.PaperVehicleInventoryRespVO;
import cn.code.nl.module.lms.controller.admin.stockingivt.vo.StockingIvtPageReqVO;
import cn.code.nl.module.lms.controller.admin.stockingivt.vo.StockingIvtRespVO;
import cn.code.nl.module.lms.controller.admin.stockingivt.vo.StockingIvtUpdateReqVO;
import cn.code.nl.module.lms.service.stockingivt.StockingIvtService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import static cn.code.nl.framework.common.pojo.CommonResult.success;
/**
* 备货区域管理接口。
*/
@Tag(name = "管理后台 - 备货区域")
@RestController
@RequestMapping("/lms/stocking-ivt")
@Validated
public class StockingIvtController {
@Resource
private StockingIvtService stockingIvtService;
/**
* 分页查询备货区域。
*/
@GetMapping("/page")
@Operation(summary = "获得备货区域分页")
@PreAuthorize("@ss.hasPermission('lms:stocking-ivt:query')")
public CommonResult<PageResult<StockingIvtRespVO>> getStockingIvtPage(
@Valid StockingIvtPageReqVO pageReqVO) {
return success(stockingIvtService.getStockingIvtPage(pageReqVO));
}
/**
* 查询备货区域详情。
*/
@GetMapping("/get")
@Operation(summary = "获得备货区域详情")
@Parameter(name = "ivtId", description = "库存记录标识", required = true)
@PreAuthorize("@ss.hasPermission('lms:stocking-ivt:query')")
public CommonResult<StockingIvtRespVO> getStockingIvt(
@RequestParam("ivtId") @NotNull Long ivtId) {
return success(stockingIvtService.getStockingIvt(ivtId));
}
/**
* 修改备货区域点位。
*/
@PutMapping("/update")
@Operation(summary = "修改备货区域点位")
@PreAuthorize("@ss.hasPermission('lms:stocking-ivt:update')")
public CommonResult<Boolean> updateStockingIvt(@Valid @RequestBody StockingIvtUpdateReqVO reqVO) {
stockingIvtService.updateStockingIvt(reqVO);
return success(true);
}
/**
* 查询纸管托盘库存。
*/
@GetMapping("/paperVehicleList")
@Operation(summary = "获得纸管托盘库存")
@Parameter(name = "vehicleCode", description = "托盘号", required = true)
@PreAuthorize("@ss.hasPermission('lms:stocking-ivt:query')")
public CommonResult<List<PaperVehicleInventoryRespVO>> getPaperVehicleInventory(
@RequestParam("vehicleCode") @NotEmpty String vehicleCode) {
return success(stockingIvtService.getPaperVehicleInventory(vehicleCode));
}
}

View File

@@ -0,0 +1,25 @@
package cn.code.nl.module.lms.controller.admin.stockingivt.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
/**
* 纸管托盘格位库存响应。
*/
@Schema(description = "管理后台 - 纸管托盘格位库存 Response VO")
@Data
public class PaperVehicleInventoryRespVO {
@Schema(description = "行号")
private Integer rowNum;
@Schema(description = "列号")
private Integer colNum;
@Schema(description = "物料编码")
private String materialCode;
@Schema(description = "物料名称")
private String materialName;
@Schema(description = "数量")
private BigDecimal qty;
}

View File

@@ -0,0 +1,26 @@
package cn.code.nl.module.lms.controller.admin.stockingivt.vo;
import cn.code.nl.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 备货区域分页请求。
*/
@Schema(description = "管理后台 - 备货区域分页 Request VO")
@Data
public class StockingIvtPageReqVO extends PageParam {
@Schema(description = "点位编码")
private String pointCode;
@Schema(description = "点位名称")
private String pointName;
@Schema(description = "托盘号")
private String vehicleCode;
@Schema(description = "点位类型")
private String pointType;
@Schema(description = "点位状态")
private String ivtStatus;
@Schema(description = "是否启用")
private String isUsed;
}

View File

@@ -0,0 +1,39 @@
package cn.code.nl.module.lms.controller.admin.stockingivt.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 备货区域响应。
*/
@Schema(description = "管理后台 - 备货区域 Response VO")
@Data
public class StockingIvtRespVO {
@Schema(description = "库存记录标识")
private Long ivtId;
@Schema(description = "点位编码")
private String pointCode;
@Schema(description = "点位名称")
private String pointName;
@Schema(description = "托盘号")
private String vehicleCode;
@Schema(description = "点位类型")
private String pointType;
@Schema(description = "点位状态")
private String ivtStatus;
@Schema(description = "位置")
private String pointLocation;
@Schema(description = "顺序号")
private Integer sortSeq;
@Schema(description = "是否启用")
private String isUsed;
@Schema(description = "备注")
private String remark;
@Schema(description = "修改人")
private String updater;
@Schema(description = "修改时间")
private LocalDateTime updateTime;
}

View File

@@ -0,0 +1,36 @@
package cn.code.nl.module.lms.controller.admin.stockingivt.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* 备货区域修改请求。
*/
@Schema(description = "管理后台 - 备货区域修改 Request VO")
@Data
public class StockingIvtUpdateReqVO {
@Schema(description = "库存记录标识", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "库存记录标识不能为空")
private Long ivtId;
@Schema(description = "托盘号")
private String vehicleCode;
@Schema(description = "点位类型", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "点位类型不能为空")
private String pointType;
@Schema(description = "点位状态", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "点位状态不能为空")
private String ivtStatus;
@Schema(description = "位置")
private String pointLocation;
@Schema(description = "顺序号", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "顺序号不能为空")
private Integer sortSeq;
@Schema(description = "是否启用", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "是否启用不能为空")
private String isUsed;
@Schema(description = "备注")
private String remark;
}

View File

@@ -0,0 +1,31 @@
package cn.code.nl.module.lms.dal.dataobject.stockingivt;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.math.BigDecimal;
/**
* 纸管托盘库存数据对象。
*/
@TableName("lms_base_papervehicle")
@Data
public class PaperVehicleDO {
/** 库存记录标识。 */
@TableId
private String ivtId;
/** 托盘号。 */
private String vehicleCode;
/** 行号。 */
private Integer rowNum;
/** 列号。 */
private Integer colNum;
/** 物料编码。 */
private String materialCode;
/** 物料名称。 */
private String materialName;
/** 数量。 */
private BigDecimal qty;
}

View File

@@ -0,0 +1,40 @@
package cn.code.nl.module.lms.dal.dataobject.stockingivt;
import cn.code.nl.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 备货区域点位数据对象。
*/
@TableName("lms_ivt_stockingivt")
@Data
@EqualsAndHashCode(callSuper = true)
public class StockingIvtDO extends BaseDO {
/** 库存记录标识。 */
@TableId
private Long ivtId;
/** 点位编码。 */
private String pointCode;
/** 点位名称。 */
private String pointName;
/** 托盘号。 */
private String vehicleCode;
/** 生产区域。 */
private String productArea;
/** 点位类型。 */
private String pointType;
/** 点位状态。 */
private String ivtStatus;
/** 位置。 */
private String pointLocation;
/** 顺序号。 */
private Integer sortSeq;
/** 是否启用。 */
private String isUsed;
/** 备注。 */
private String remark;
}

View File

@@ -0,0 +1,49 @@
package cn.code.nl.module.lms.dal.mysql.stockingivt;
import cn.code.nl.framework.common.pojo.PageResult;
import cn.code.nl.framework.mybatis.core.mapper.BaseMapperX;
import cn.code.nl.framework.mybatis.core.util.MyBatisUtils;
import cn.code.nl.module.lms.controller.admin.stockingivt.vo.StockingIvtPageReqVO;
import cn.code.nl.module.lms.dal.dataobject.stockingivt.PaperVehicleDO;
import cn.code.nl.module.lms.dal.dataobject.stockingivt.StockingIvtDO;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 备货区域 Mapper。
*/
@Mapper
public interface StockingIvtMapper extends BaseMapperX<StockingIvtDO> {
/**
* 分页查询备货区域。
*/
default PageResult<StockingIvtDO> selectStockingIvtPage(StockingIvtPageReqVO reqVO) {
Page<StockingIvtDO> page = selectStockingIvtPage(MyBatisUtils.buildPage(reqVO), reqVO);
return new PageResult<>(page.getRecords(), page.getTotal());
}
/**
* 执行备货区域分页 SQL。
*/
Page<StockingIvtDO> selectStockingIvtPage(Page<StockingIvtDO> page,
@Param("reqVO") StockingIvtPageReqVO reqVO);
/**
* 根据标识查询备货区域点位。
*/
StockingIvtDO selectStockingIvtById(@Param("ivtId") Long ivtId);
/**
* 更新备货区域点位的可编辑字段。
*/
int updateStockingIvt(StockingIvtDO updateObj);
/**
* 根据托盘号查询纸管库存。
*/
List<PaperVehicleDO> selectPaperVehicleList(@Param("vehicleCode") String vehicleCode);
}

View File

@@ -0,0 +1,36 @@
package cn.code.nl.module.lms.service.stockingivt;
import cn.code.nl.framework.common.pojo.PageResult;
import cn.code.nl.module.lms.controller.admin.stockingivt.vo.PaperVehicleInventoryRespVO;
import cn.code.nl.module.lms.controller.admin.stockingivt.vo.StockingIvtPageReqVO;
import cn.code.nl.module.lms.controller.admin.stockingivt.vo.StockingIvtRespVO;
import cn.code.nl.module.lms.controller.admin.stockingivt.vo.StockingIvtUpdateReqVO;
import jakarta.validation.Valid;
import java.util.List;
/**
* 备货区域服务。
*/
public interface StockingIvtService {
/**
* 分页查询备货区域。
*/
PageResult<StockingIvtRespVO> getStockingIvtPage(StockingIvtPageReqVO reqVO);
/**
* 查询备货区域详情。
*/
StockingIvtRespVO getStockingIvt(Long ivtId);
/**
* 修改备货区域点位。
*/
void updateStockingIvt(@Valid StockingIvtUpdateReqVO reqVO);
/**
* 查询纸管托盘库存。
*/
List<PaperVehicleInventoryRespVO> getPaperVehicleInventory(String vehicleCode);
}

View File

@@ -0,0 +1,129 @@
package cn.code.nl.module.lms.service.stockingivt;
import cn.code.nl.framework.common.pojo.PageResult;
import cn.code.nl.module.lms.controller.admin.stockingivt.vo.PaperVehicleInventoryRespVO;
import cn.code.nl.module.lms.controller.admin.stockingivt.vo.StockingIvtPageReqVO;
import cn.code.nl.module.lms.controller.admin.stockingivt.vo.StockingIvtRespVO;
import cn.code.nl.module.lms.controller.admin.stockingivt.vo.StockingIvtUpdateReqVO;
import cn.code.nl.module.lms.dal.dataobject.stockingivt.PaperVehicleDO;
import cn.code.nl.module.lms.dal.dataobject.stockingivt.StockingIvtDO;
import cn.code.nl.module.lms.dal.mysql.stockingivt.StockingIvtMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static cn.code.nl.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.code.nl.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.code.nl.module.lms.enums.ErrorCodeConstants.PAPER_VEHICLE_POSITION_DUPLICATED;
import static cn.code.nl.module.lms.enums.ErrorCodeConstants.PAPER_VEHICLE_POSITION_OUT_OF_RANGE;
import static cn.code.nl.module.lms.enums.ErrorCodeConstants.STOCKING_IVT_NOT_EXISTS;
/**
* 备货区域服务实现。
*/
@Service
@Validated
public class StockingIvtServiceImpl implements StockingIvtService {
@Resource
private StockingIvtMapper stockingIvtMapper;
/**
* 分页查询备货区域。
*/
@Override
public PageResult<StockingIvtRespVO> getStockingIvtPage(StockingIvtPageReqVO reqVO) {
PageResult<StockingIvtDO> pageResult = stockingIvtMapper.selectStockingIvtPage(reqVO);
List<StockingIvtRespVO> list = new ArrayList<>(pageResult.getList().size());
for (StockingIvtDO stockingIvt : pageResult.getList()) {
list.add(convertStockingIvt(stockingIvt));
}
return new PageResult<>(list, pageResult.getTotal());
}
/**
* 查询备货区域详情。
*/
@Override
public StockingIvtRespVO getStockingIvt(Long ivtId) {
StockingIvtDO stockingIvt = stockingIvtMapper.selectStockingIvtById(ivtId);
if (stockingIvt == null) {
throw exception(STOCKING_IVT_NOT_EXISTS);
}
return convertStockingIvt(stockingIvt);
}
/**
* 修改备货区域点位。
*/
@Override
public void updateStockingIvt(StockingIvtUpdateReqVO reqVO) {
if (stockingIvtMapper.selectStockingIvtById(reqVO.getIvtId()) == null) {
throw exception(STOCKING_IVT_NOT_EXISTS);
}
StockingIvtDO updateObj = new StockingIvtDO();
updateObj.setIvtId(reqVO.getIvtId());
updateObj.setVehicleCode(reqVO.getVehicleCode());
updateObj.setPointType(reqVO.getPointType());
updateObj.setIvtStatus(reqVO.getIvtStatus());
updateObj.setPointLocation(reqVO.getPointLocation());
updateObj.setSortSeq(reqVO.getSortSeq());
updateObj.setIsUsed(reqVO.getIsUsed());
updateObj.setRemark(reqVO.getRemark());
updateObj.setUpdater(String.valueOf(getLoginUserId()));
stockingIvtMapper.updateStockingIvt(updateObj);
}
/**
* 查询并校验纸管托盘库存。
*/
@Override
public List<PaperVehicleInventoryRespVO> getPaperVehicleInventory(String vehicleCode) {
List<PaperVehicleDO> inventoryList = stockingIvtMapper.selectPaperVehicleList(vehicleCode);
List<PaperVehicleInventoryRespVO> result = new ArrayList<>(inventoryList.size());
Set<String> positions = new HashSet<>();
for (PaperVehicleDO inventory : inventoryList) {
String position = inventory.getRowNum() + ":" + inventory.getColNum();
if (inventory.getRowNum() < 1 || inventory.getRowNum() > 5
|| inventory.getColNum() < 1 || inventory.getColNum() > 5) {
throw exception(PAPER_VEHICLE_POSITION_OUT_OF_RANGE, position);
}
if (!positions.add(position)) {
throw exception(PAPER_VEHICLE_POSITION_DUPLICATED, position);
}
PaperVehicleInventoryRespVO item = new PaperVehicleInventoryRespVO();
item.setRowNum(inventory.getRowNum());
item.setColNum(inventory.getColNum());
item.setMaterialCode(inventory.getMaterialCode());
item.setMaterialName(inventory.getMaterialName());
item.setQty(inventory.getQty());
result.add(item);
}
return result;
}
/**
* 将备货区域数据对象转换为响应对象。
*/
private StockingIvtRespVO convertStockingIvt(StockingIvtDO stockingIvt) {
StockingIvtRespVO response = new StockingIvtRespVO();
response.setIvtId(stockingIvt.getIvtId());
response.setPointCode(stockingIvt.getPointCode());
response.setPointName(stockingIvt.getPointName());
response.setVehicleCode(stockingIvt.getVehicleCode());
response.setPointType(stockingIvt.getPointType());
response.setIvtStatus(stockingIvt.getIvtStatus());
response.setPointLocation(stockingIvt.getPointLocation());
response.setSortSeq(stockingIvt.getSortSeq());
response.setIsUsed(stockingIvt.getIsUsed());
response.setRemark(stockingIvt.getRemark());
response.setUpdater(stockingIvt.getUpdater());
response.setUpdateTime(stockingIvt.getUpdateTime());
return response;
}
}

View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.code.nl.module.lms.dal.mysql.stockingivt.StockingIvtMapper">
<sql id="stockingIvtColumns">
ivt_id, point_code, point_name, vehicle_code, product_area, point_type,
ivt_status, point_location, sort_seq, is_used, remark,
creator, create_time, updater, update_time
</sql>
<select id="selectStockingIvtPage"
resultType="cn.code.nl.module.lms.dal.dataobject.stockingivt.StockingIvtDO">
SELECT <include refid="stockingIvtColumns"/>
FROM lms_ivt_stockingivt
<where>
<if test="reqVO.pointCode != null and reqVO.pointCode != ''">
point_code LIKE CONCAT('%', #{reqVO.pointCode}, '%')
</if>
<if test="reqVO.pointName != null and reqVO.pointName != ''">
AND point_name LIKE CONCAT('%', #{reqVO.pointName}, '%')
</if>
<if test="reqVO.vehicleCode != null and reqVO.vehicleCode != ''">
AND vehicle_code LIKE CONCAT('%', #{reqVO.vehicleCode}, '%')
</if>
<if test="reqVO.pointType != null and reqVO.pointType != ''">
AND point_type = #{reqVO.pointType}
</if>
<if test="reqVO.ivtStatus != null and reqVO.ivtStatus != ''">
AND ivt_status = #{reqVO.ivtStatus}
</if>
<if test="reqVO.isUsed != null and reqVO.isUsed != ''">
AND is_used = #{reqVO.isUsed}
</if>
</where>
ORDER BY ivt_id DESC
</select>
<select id="selectStockingIvtById"
resultType="cn.code.nl.module.lms.dal.dataobject.stockingivt.StockingIvtDO">
SELECT <include refid="stockingIvtColumns"/>
FROM lms_ivt_stockingivt
WHERE ivt_id = #{ivtId}
</select>
<update id="updateStockingIvt">
UPDATE lms_ivt_stockingivt
SET vehicle_code = #{vehicleCode},
point_type = #{pointType},
ivt_status = #{ivtStatus},
point_location = #{pointLocation},
sort_seq = #{sortSeq},
is_used = #{isUsed},
remark = #{remark},
updater = #{updater}
WHERE ivt_id = #{ivtId}
</update>
<select id="selectPaperVehicleList"
resultType="cn.code.nl.module.lms.dal.dataobject.stockingivt.PaperVehicleDO">
SELECT ivt_id, vehicle_code,
CAST(row_num AS SIGNED) AS row_num,
CAST(col_num AS SIGNED) AS col_num,
material_code, material_name, qty
FROM lms_base_papervehicle
WHERE vehicle_code = #{vehicleCode}
ORDER BY CAST(row_num AS UNSIGNED), CAST(col_num AS UNSIGNED), ivt_id
</select>
</mapper>