仓库管理-量具库查询

develop-QA
wusiyu 3 months ago
parent 40ac0fd62f
commit 3dca71367e
  1. 267
      blade-service/blade-wms/src/main/java/org/springblade/wms/controller/StRealtimeStockController.java
  2. 231
      blade-service/blade-wms/src/main/java/org/springblade/wms/excel/StRealtimeStockExcel.java
  3. 73
      blade-service/blade-wms/src/main/java/org/springblade/wms/mapper/StRealtimeStockMapper.java
  4. 352
      blade-service/blade-wms/src/main/java/org/springblade/wms/mapper/StRealtimeStockMapper.xml
  5. 25
      blade-service/blade-wms/src/main/java/org/springblade/wms/pojo/dto/StRealtimeStockDTO.java
  6. 196
      blade-service/blade-wms/src/main/java/org/springblade/wms/pojo/entity/StRealtimeStock.java
  7. 91
      blade-service/blade-wms/src/main/java/org/springblade/wms/pojo/entity/StStorehouse.java
  8. 21
      blade-service/blade-wms/src/main/java/org/springblade/wms/pojo/vo/PrintParentWoLabel.java
  9. 86
      blade-service/blade-wms/src/main/java/org/springblade/wms/pojo/vo/PrintStoresList.java
  10. 41
      blade-service/blade-wms/src/main/java/org/springblade/wms/pojo/vo/PrintWoLabel.java
  11. 54
      blade-service/blade-wms/src/main/java/org/springblade/wms/pojo/vo/StRealtimeStockVO.java
  12. 82
      blade-service/blade-wms/src/main/java/org/springblade/wms/service/IStRealtimeStockService.java
  13. 539
      blade-service/blade-wms/src/main/java/org/springblade/wms/service/impl/StRealtimeStockServiceImpl.java
  14. 39
      blade-service/blade-wms/src/main/java/org/springblade/wms/wrapper/StRealtimeStockWrapper.java

@ -0,0 +1,267 @@
package org.springblade.wms.controller;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.write.handler.WriteHandler;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import jakarta.servlet.http.HttpServletRequest;
import lombok.AllArgsConstructor;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.log.annotation.ApiLog;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.annotation.IsAdmin;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.TemplateUtil;
import org.springblade.wms.pojo.entity.StRealtimeStock;
import org.springblade.wms.pojo.entity.StStorehouse;
import org.springblade.wms.pojo.vo.PrintParentWoLabel;
import org.springblade.wms.pojo.vo.PrintStoresList;
import org.springblade.wms.pojo.vo.PrintWoLabel;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.wms.pojo.vo.StRealtimeStockVO;
import org.springblade.wms.excel.StRealtimeStockExcel;
import org.springblade.wms.wrapper.StRealtimeStockWrapper;
import org.springblade.wms.service.IStRealtimeStockService;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.excel.util.ExcelUtil;
import org.springblade.core.tool.constant.BladeConstant;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import jakarta.servlet.http.HttpServletResponse;
import static org.springblade.core.excel.util.ExcelUtil.export;
/**
* @version 1.0
* @program: jonhon-mes-svr
* @ClassName StRealtimeStockController
* @description: 仓库实时结余表 控制器
* @autor: WuSiYu
* @create 2025-12-15 15:04
**/
/**
* 仓库实时结余表 控制器
*
* @author BladeX
* @since 2025-12-15
*/
@RestController
@AllArgsConstructor
@RequestMapping("/stRealtimeStock")
@Tag(name = "仓库实时结余表", description = "仓库实时结余表接口")
@Slf4j
public class StRealtimeStockController extends BladeController {
private final IStRealtimeStockService stRealtimeStockService;
/**
* 仓库实时结余表 详情
*/
@GetMapping("/detail")
@ApiOperationSupport(order = 1)
@Operation(summary = "详情", description = "传入stRealtimeStock")
public R<StRealtimeStockVO> detail(StRealtimeStock stRealtimeStock) {
StRealtimeStock detail = stRealtimeStockService.getOne(Condition.getQueryWrapper(stRealtimeStock));
return R.data(StRealtimeStockWrapper.build().entityVO(detail));
}
/**
* 仓库实时结余表 分页
*/
@GetMapping("/list")
@ApiOperationSupport(order = 2)
@Operation(summary = "分页", description = "传入stRealtimeStock")
public R<IPage<StRealtimeStockVO>> list(@Parameter(hidden = true) @RequestParam Map<String, Object> stRealtimeStock, Query query) {
IPage<StRealtimeStock> pages = stRealtimeStockService.page(Condition.getPage(query), Condition.getQueryWrapper(stRealtimeStock, StRealtimeStock.class));
return R.data(StRealtimeStockWrapper.build().pageVO(pages));
}
/**
* 仓库实时结余表 自定义分页
*/
@GetMapping("/page")
@ApiOperationSupport(order = 3)
@Operation(summary = "分页", description = "传入stRealtimeStock")
public R<IPage<StRealtimeStockVO>> page(StRealtimeStockVO stRealtimeStock, Query query) {
IPage<StRealtimeStockVO> pages = stRealtimeStockService.selectStRealtimeStockPage(Condition.getPage(query), stRealtimeStock);
return R.data(pages);
}
/**
* 量具库存表 分页
*/
@GetMapping("/pageToolsData")
@ApiOperationSupport(order = 3)
@Operation(summary = "分页加载量具库存数据", description = "传入stRealtimeStock,默认过滤量具类型仓库,按sumNum排序")
public R<IPage<StRealtimeStockVO>> pageToolsData(StRealtimeStockVO stRealtimeStock, Query query) {
if (StrUtil.isBlank(query.getAscs()) && StrUtil.isBlank(query.getDescs())) {
query.setDescs("sumNum"); // 默认按sumNum降序排序
}
IPage<StRealtimeStockVO> pages = stRealtimeStockService.selectToolsStockPage(Condition.getPage(query), stRealtimeStock);
return R.data(pages);
}
/**
* 仓库实时结余表 新增
*/
@PostMapping("/save")
@ApiOperationSupport(order = 4)
@Operation(summary = "新增", description = "传入stRealtimeStock")
public R save(@Valid @RequestBody StRealtimeStock stRealtimeStock) {
return R.status(stRealtimeStockService.save(stRealtimeStock));
}
/**
* 仓库实时结余表 修改
*/
@PostMapping("/update")
@ApiOperationSupport(order = 5)
@Operation(summary = "修改", description = "传入stRealtimeStock")
public R update(@Valid @RequestBody StRealtimeStock stRealtimeStock) {
return R.status(stRealtimeStockService.updateById(stRealtimeStock));
}
/**
* 仓库实时结余表 新增或修改
*/
@PostMapping("/submit")
@ApiOperationSupport(order = 6)
@Operation(summary = "新增或修改", description = "传入stRealtimeStock")
public R submit(@Valid @RequestBody StRealtimeStock stRealtimeStock) {
return R.status(stRealtimeStockService.saveOrUpdate(stRealtimeStock));
}
/**
* 仓库实时结余表 删除
*/
@PostMapping("/remove")
@ApiOperationSupport(order = 7)
@Operation(summary = "逻辑删除", description = "传入ids")
public R remove(@Parameter(description = "主键集合", required = true) @RequestParam String ids) {
return R.status(stRealtimeStockService.deleteLogic(Func.toLongList(ids)));
}
/**
* 仓库实时结余表 打印标签
*/
@PostMapping("/printWoLabel")
@ApiOperationSupport(order = 8)
@Operation(summary = "打印标签", description = "传入rlsIdList(主键集合)、quantity(打印数量)、exportType(导出类型)")
public void printLabel(
@Parameter(hidden = true) @RequestBody JSONObject data,
@Parameter(hidden = true) HttpServletRequest request,
@Parameter(hidden = true) HttpServletResponse response
) throws Exception {
// 解析请求参数
List<Long> rlsIdList = JSONArray.parseArray(data.getString("rlsIdList"), Long.class);
Short quantity = data.getShort("quantity");
Short exportType = data.getShort("exportType");
// 调用服务层获取打印数据
List<PrintParentWoLabel> list = stRealtimeStockService.printPrintWoLabel(rlsIdList, quantity);
// 构建导出参数
Map<String, Object> map = new HashMap<>(1);
// 调用导出方法
export(response, "打印标签" + DateUtil.time(), "打印标签数据表", list, PrintParentWoLabel.class);
}
/**
* 仓库实时结余表 打印
*/
@PostMapping("/print")
@ApiOperationSupport(order = 9)
@Operation(summary = "打印流程卡", description = "传入idArr(主键集合)、exportType(导出类型)、reportId(报表ID)")
public void print(
@Parameter(description = "打印参数(idArr:主键集合, exportType:导出类型, reportId:报表ID)", required = true)
@RequestBody JSONObject data,
@Parameter(hidden = true) HttpServletRequest request,
@Parameter(hidden = true) HttpServletResponse response
) {
try {
// 解析主键集合
List<Long> idArr = JSONArray.parseArray(data.getString("idArr"), Long.class);
// 解析导出类型
Short exportType = data.getShort("exportType");
// 校验主键集合非空
if (Func.isNotEmpty(idArr)) {
// 解析报表ID
String reportId = data.getString("reportId");
// 校验报表ID非空
if (Func.isNotBlank(reportId)) {
// 调用服务层获取打印数据
List<PrintStoresList> list = stRealtimeStockService.printStRealtimeStockList(idArr);
// 执行导出打印
export(response, "流程卡打印","reportId", list, PrintStoresList.class);
}
}
} catch (Exception e) {
log.error("仓库实时结余表打印异常", e);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
@RequestMapping(
value = {"/listprintData"},
method = {RequestMethod.POST}
)
@ApiOperationSupport(order = 10)
@Operation(summary = "获取打印数据列表", description = "传入idArr(主键集合)获取打印数据")
public R<List<PrintStoresList>> listprintData(
@Parameter(description = "请求参数(idArr:主键集合)", required = true)
@RequestBody JSONObject data
) {
try {
List<Long> idArr = JSONArray.parseArray(Func.toStr(data.get("idArr")), Long.class);
if (Func.isEmpty(idArr)) {
return R.fail("主键集合idArr不能为空");
}
List<PrintStoresList> list = stRealtimeStockService.printStRealtimeStockList(idArr);
return R.data(list);
} catch (Exception e) {
log.error("获取打印数据异常", e);
return R.fail("获取打印数据失败:" + e.getMessage());
}
}
/**
* 导出数据
*/
@IsAdmin
@GetMapping("/export-stRealtimeStock")
@ApiOperationSupport(order = 11)
@Operation(summary = "导出数据", description = "传入stRealtimeStock")
public void exportStRealtimeStock(@Parameter(hidden = true) @RequestParam Map<String, Object> stRealtimeStock, BladeUser bladeUser, HttpServletResponse response) {
QueryWrapper<StRealtimeStock> queryWrapper = Condition.getQueryWrapper(stRealtimeStock, StRealtimeStock.class);
//if (!AuthUtil.isAdministrator()) {
// queryWrapper.lambda().eq(StRealtimeStock::getTenantId, bladeUser.getTenantId());
//}
//queryWrapper.lambda().eq(StRealtimeStockEntity::getIsDeleted, BladeConstant.DB_NOT_DELETED);
List<StRealtimeStockExcel> list = stRealtimeStockService.exportStRealtimeStock(queryWrapper);
export(response, "仓库实时结余表数据" + DateUtil.time(), "仓库实时结余表数据表", list, StRealtimeStockExcel.class);
}
}

@ -0,0 +1,231 @@
package org.springblade.wms.excel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* @version 1.0
* @program: jonhon-mes-svr
* @ClassName StRealtimeStockExcel
* @description: 仓库实时结余表 Excel实体类
* @autor: WuSiYu
* @create 2025-12-15 14:51
**/
@Data
@ColumnWidth(25)
@HeadRowHeight(20)
@ContentRowHeight(18)
public class StRealtimeStockExcel implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@ColumnWidth(20)
@ExcelProperty("主键")
private Long id;
/**
* 租户ID默认值000000
*/
@ColumnWidth(20)
@ExcelProperty("租户ID(默认值:000000)")
private String tenantId;
/**
* 是否已删除默认值0
*/
@ColumnWidth(20)
@ExcelProperty("是否已删除(默认值:0)")
private Long isDeleted;
/**
* 库房ID
*/
@ColumnWidth(20)
@ExcelProperty("库房ID")
private Long shId;
/**
* 物料ID关联st_goods表
*/
@ColumnWidth(20)
@ExcelProperty("物料ID(关联st_goods表)")
private Long goodsId;
/**
* 库位ID
*/
@ColumnWidth(20)
@ExcelProperty("库位ID")
private Long slId;
/**
* 批次号
*/
@ColumnWidth(20)
@ExcelProperty("批次号")
private String piNo;
/**
* 库存数量
*/
@ColumnWidth(20)
@ExcelProperty("库存数量")
private Double quantity;
/**
* 金额-单价
*/
@ColumnWidth(20)
@ExcelProperty("金额-单价")
private Double balanceMoney;
/**
* 质量等级
*/
@ColumnWidth(20)
@ExcelProperty("质量等级")
private String quantityLevel;
/**
* 过期/报废日期
*/
@ColumnWidth(20)
@ExcelProperty("过期/报废日期")
private Date scrapCycle;
/**
* 质量编号
*/
@ColumnWidth(20)
@ExcelProperty("质量编号")
private String checkCode;
/**
* 是否模架物料1=/0=
*/
@ColumnWidth(20)
@ExcelProperty("是否模架物料(1=是/0=否)")
private Boolean moldBaseMaterial;
/**
* 模架物料库存对应模架库存ID
*/
@ColumnWidth(20)
@ExcelProperty("模架物料库存对应模架库存ID")
private Long moldRlsId;
/**
* 是否停用1=/0=
*/
@ColumnWidth(20)
@ExcelProperty("是否停用(1=是/0=否)")
private Boolean stopUse;
/**
* 累计次数
*/
@ColumnWidth(20)
@ExcelProperty("累计次数")
private Long sumNum;
/**
* 库存来源1=采购/2=生产/3=调拨等
*/
@ColumnWidth(20)
@ExcelProperty("库存来源(1=采购/2=生产/3=调拨等)")
private Long stockSource;
/**
* 待保养次数
*/
@ColumnWidth(20)
@ExcelProperty("待保养次数")
private Long stayMaintainNum;
/**
* 物料状态
*/
@ColumnWidth(20)
@ExcelProperty("物料状态")
private Long goodsStatus;
/**
* 分厂类型
*/
@ColumnWidth(20)
@ExcelProperty("分厂类型")
private Long facilityType;
/**
* 分厂ID
*/
@ColumnWidth(20)
@ExcelProperty("分厂ID")
private Long deptId;
/**
* 条码号
*/
@ColumnWidth(20)
@ExcelProperty("条码号")
private String barCode;
/**
* 占用数量
*/
@ColumnWidth(20)
@ExcelProperty("占用数量")
private Double occupyQuantity;
/**
* 炉批号
*/
@ColumnWidth(20)
@ExcelProperty("炉批号")
private String stovePiNo;
/**
* 到期送检是否申请
*/
@ColumnWidth(20)
@ExcelProperty("到期送检是否申请")
private Boolean applyFor;
/**
* 供方代码
*/
@ColumnWidth(20)
@ExcelProperty("供方代码")
private String splyCode;
/**
* 限用标记
*/
@ColumnWidth(20)
@ExcelProperty("限用标记")
private Long limitUseFlag;
/**
* ERP入库时间
*/
@ColumnWidth(20)
@ExcelProperty("ERP入库时间")
private Date erpStorageTime;
/**
* 是否印字
*/
@ColumnWidth(20)
@ExcelProperty("是否印字")
private Boolean printMark;
/**
* 粉重
*/
@ColumnWidth(20)
@ExcelProperty("粉重")
private String powderWeight;
/**
* 材料号
*/
@ColumnWidth(20)
@ExcelProperty("材料号")
private String materialNo;
/**
* 厚度
*/
@ColumnWidth(20)
@ExcelProperty("厚度")
private String thickness;
/**
* 备注
*/
@ColumnWidth(20)
@ExcelProperty("备注")
private String memo;
}

@ -0,0 +1,73 @@
package org.springblade.wms.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.ibatis.annotations.Param;
import org.springblade.wms.excel.StRealtimeStockExcel;
import org.springblade.wms.pojo.entity.StRealtimeStock;
import org.springblade.wms.pojo.vo.StRealtimeStockVO;
import java.util.List;
/**
* @version 1.0
* @program: jonhon-mes-svr
* @ClassName StRealtimeStockMapper
* @description: 仓库实时结余表 Mapper 接口
* @autor: WuSiYu
* @create 2025-12-15 15:00
**/
public interface StRealtimeStockMapper extends BaseMapper<StRealtimeStock> {
/**
* 自定义分页
*
* @param page 分页参数
* @param stRealtimeStock 查询参数
* @return List<StRealtimeStockVO>
*/
List<StRealtimeStockVO> selectStRealtimeStockPage(IPage page, StRealtimeStockVO stRealtimeStock);
/**
* 获取导出数据
*
* @param queryWrapper 查询条件
* @return List<StRealtimeStockExcel>
*/
List<StRealtimeStockExcel> exportStRealtimeStock(@Param("ew") Wrapper<StRealtimeStock> queryWrapper);
Double getByShId(@Param("shId") Long shId);
Double getQuantityBySlId(@Param("slId") Long slId);
StRealtimeStock getBySlId(@Param("slId") Long slId);
Boolean findBySlId(@Param("slId") Long slId);
Double findPriceByParams(Long goodsId, String checkNo);
IPage<StRealtimeStockVO> selectByGoodsIdShId(Long goodsId, Long shId, String deptId);
IPage<StRealtimeStockVO> selectGoodsOut(IPage<StRealtimeStockVO> page, String filterValue, Long shId, Long goodsId);
StRealtimeStock getFirstByGoodsCodeAndDeptId(String goodsCode, String deptId);
StRealtimeStock getByBarCode(String barCode);
StRealtimeStock getByGoodsCode(String barCode);
StRealtimeStock getSynchById(Long rlsId);
List<StRealtimeStockVO> selectStockGoodsPage(IPage<StRealtimeStockVO> page, StRealtimeStockVO stRealtimeStock);
boolean checkRealTimeLock(String woCode, String rlsId);
void updateRealTimeLock(String woCode, String string, double doubleValue);
List<StRealtimeStockVO> selectToolsStockPage(IPage<StRealtimeStockVO> page, StRealtimeStockVO stRealtimeStock);
}

@ -0,0 +1,352 @@
<?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="org.springblade.wms.mapper.StRealtimeStockMapper">
<!-- 通用查询映射结果 -->
<resultMap id="stRealtimeStockResultMap" type="org.springblade.wms.pojo.entity.StRealtimeStock">
<result column="ID" property="id"/>
<result column="TENANT_ID" property="tenantId"/>
<result column="CREATE_USER" property="createUser"/>
<result column="CREATE_DEPT" property="createDept"/>
<result column="CREATE_TIME" property="createTime"/>
<result column="UPDATE_USER" property="updateUser"/>
<result column="UPDATE_TIME" property="updateTime"/>
<result column="STATUS" property="status"/>
<result column="IS_DELETED" property="isDeleted"/>
<result column="SH_ID" property="shId"/>
<result column="GOODS_ID" property="goodsId"/>
<result column="SL_ID" property="slId"/>
<result column="PI_NO" property="piNo"/>
<result column="QUANTITY" property="quantity"/>
<result column="BALANCE_MONEY" property="balanceMoney"/>
<result column="QUANTITY_LEVEL" property="quantityLevel"/>
<result column="SCRAP_CYCLE" property="scrapCycle"/>
<result column="CHECK_CODE" property="checkCode"/>
<result column="MOLD_BASE_MATERIAL" property="moldBaseMaterial"/>
<result column="MOLD_RLS_ID" property="moldRlsId"/>
<result column="STOP_USE" property="stopUse"/>
<result column="SUM_NUM" property="sumNum"/>
<result column="STOCK_SOURCE" property="stockSource"/>
<result column="STAY_MAINTAIN_NUM" property="stayMaintainNum"/>
<result column="GOODS_STATUS" property="goodsStatus"/>
<result column="FACILITY_TYPE" property="facilityType"/>
<result column="DEPT_ID" property="deptId"/>
<result column="BAR_CODE" property="barCode"/>
<result column="OCCUPY_QUANTITY" property="occupyQuantity"/>
<result column="STOVE_PI_NO" property="stovePiNo"/>
<result column="APPLY_FOR" property="applyFor"/>
<result column="SPLY_CODE" property="splyCode"/>
<result column="LIMIT_USE_FLAG" property="limitUseFlag"/>
<result column="ERP_STORAGE_TIME" property="erpStorageTime"/>
<result column="PRINT_MARK" property="printMark"/>
<result column="POWDER_WEIGHT" property="powderWeight"/>
<result column="MATERIAL_NO" property="materialNo"/>
<result column="THICKNESS" property="thickness"/>
<result column="MEMO" property="memo"/>
</resultMap>
<select id="selectStRealtimeStockPage" resultMap="stRealtimeStockResultMap">
select * from ST_REALTIME_STOCK where is_deleted = 0
</select>
<select id="exportStRealtimeStock" resultType="org.springblade.wms.excel.StRealtimeStockExcel">
SELECT * FROM ST_REALTIME_STOCK ${ew.customSqlSegment}
</select>
<!-- <select id="selectStockWithGoods" resultMap="stockWithGoodsMap">-->
<!-- SELECT rls.*,-->
<!-- g.id AS g_id,-->
<!-- g.create_user AS g_create_user,-->
<!-- g.create_dept AS g_create_dept,-->
<!-- g.create_time AS g_create_time,-->
<!-- g.update_user AS g_update_user,-->
<!-- g.update_time AS g_update_time,-->
<!-- g.status AS g_status,-->
<!-- g.is_deleted AS g_is_deleted,-->
<!-- g.goods_code AS g_goods_code,-->
<!-- g.goods_name AS g_goods_name,-->
<!-- g.max_num AS g_max_num,-->
<!-- g.min_num AS g_min_num,-->
<!-- g.purchase_quantity AS g_purchase_quantity,-->
<!-- g.must_check AS g_must_check,-->
<!-- g.used AS g_used,-->
<!-- g.num_acc AS g_num_acc,-->
<!-- g.made_in AS g_made_in,-->
<!-- g.price AS g_price,-->
<!-- g.grade AS g_grade,-->
<!-- g.source AS g_source,-->
<!-- g.prt_type AS g_prt_type,-->
<!-- g.release_no AS g_release_no,-->
<!-- g.release_no_time AS g_release_no_time,-->
<!-- g.material_model AS g_material_model,-->
<!-- g.weight AS g_weight,-->
<!-- g.unit_name AS g_unit_name,-->
<!-- g.product_category AS g_product_category,-->
<!-- g.specifications AS g_specifications,-->
<!-- g.product_tech_spec AS g_product_tech_spec,-->
<!-- g.density AS g_density,-->
<!-- g.drawing_no AS g_drawing_no,-->
<!-- g.ecn_no AS g_ecn_no,-->
<!-- g.end_item AS g_end_item,-->
<!-- g.priority AS g_priority,-->
<!-- g.part_link AS g_part_link,-->
<!-- g.cavity_no AS g_cavity_no,-->
<!-- g.dept_id AS g_dept_id,-->
<!-- g.gc_id AS g_gc_id,-->
<!-- g.part_revision_status AS g_part_revision_status,-->
<!-- g.trade_mark AS g_trade_mark,-->
<!-- g.remark AS g_remark,-->
<!-- g.lock_quantity AS g_lock_quantity,-->
<!-- g.ontheway_quantity AS g_ontheway_quantity,-->
<!-- g.current_quantity AS g_current_quantity,-->
<!-- g.goods_type AS g_goods_type,-->
<!-- g.mat_big_classify AS g_mat_big_classify,-->
<!-- g.mat_small_classify AS g_mat_small_classify,-->
<!-- g.check_code AS g_check_code,-->
<!-- g.batch AS g_batch,-->
<!-- g.section_area AS g_section_area,-->
<!-- g.material_property AS g_material_property,-->
<!-- g.pdm_unit AS g_pdm_unit,-->
<!-- g.process_approval AS g_process_approval,-->
<!-- g.min_warning AS g_min_warning-->
<!-- FROM st_realtime_stock rls-->
<!-- LEFT JOIN st_goods g ON rls.goods_id = g.id-->
<!-- WHERE rls.id = #{id}-->
<!-- </select>-->
<!-- <resultMap id="stockWithGoodsMap" type="org.springblade.wms.pojo.entity.StRealtimeStock">-->
<!-- &lt;!&ndash; 库存自身主键、外键 &ndash;&gt;-->
<!-- <id property="id" column="id"/>-->
<!-- <result property="goodsId" column="goods_id"/>-->
<!-- &lt;!&ndash; 其他库存字段可自动映射 &ndash;&gt;-->
<!-- &lt;!&ndash; 一对一:把 g_ 前缀的列整体丢进已有的 stGoodsResultMap &ndash;&gt;-->
<!-- <association property="stGoods"-->
<!-- resultMap="org.springblade.wms.mapper.StGoodsMapper.stGoodsResultMap"-->
<!-- columnPrefix="g_"/>-->
<!-- </resultMap>-->
<select id="getByShId" resultType="java.lang.Double">
SELECT NVL(SUM(QUANTITY), 0)
FROM ST_REALTIME_STOCK
WHERE SH_ID = #{shId}
</select>
<select id="getQuantityBySlId" resultType="java.lang.Double">
SELECT NVL(SUM(QUANTITY), 0)
FROM ST_REALTIME_STOCK
WHERE SL_ID = #{slId}
</select>
<select id="getBySlId" resultMap="stRealtimeStockResultMap">
SELECT *
FROM (
SELECT *
FROM ST_REALTIME_STOCK
WHERE SL_ID = #{slId}
AND QUANTITY = 0
ORDER BY CREATE_TIME DESC
)
WHERE ROWNUM = 1
FOR UPDATE
</select>
<select id="findBySlId" resultType="java.lang.Boolean">
SELECT CASE
WHEN COUNT(1) > 0 THEN 0
ELSE 1
END
FROM (
SELECT 1
FROM ST_REALTIME_STOCK
WHERE SL_ID = #{slId}
AND ROWNUM = 1
FOR UPDATE
)
</select>
<select id="findPriceByParams" resultType="java.lang.Double">
SELECT NVL((
SELECT BALANCE_MONEY
FROM ST_REALTIME_STOCK
WHERE GOODS_ID = #{goodsId}
AND CHECK_CODE = #{checkNo}
ORDER BY CREATE_TIME DESC
FETCH FIRST 1 ROW ONLY
), 0) FROM DUAL
</select>
<select id="selectByGoodsIdShId" resultMap="stRealtimeStockResultMap">
SELECT rls.id,
rls.pi_no,
rls.quantity,
rls.sl_id,
sl.location
FROM st_realtime_stock rls
JOIN st_storage_location sl ON rls.sl_id = sl.id
WHERE rls.goods_id = #{goodsId}
AND rls.sh_id = #{shId}
<if test="deptId != null">
AND rls.dept_id = #{deptId}
</if>
</select>
<select id="selectGoodsOut" resultType="org.springblade.wms.pojo.vo.StRealtimeStockVO">
SELECT
s.id, s.goods_id, s.quantity,
g.lock_quantity, g.ontheway_quantity, g.current_quantity, g.specifications,
s.pi_no, s.sl_id, s.bar_code, s.scrap_cycle, s.check_code, s.sply_code,
g.goods_code, g.goods_name,
w.sh_name, w.id as sh_id,
l.location
FROM st_realtime_stock s
-- 关联物料表(原有)
LEFT JOIN st_goods g ON s.goods_id = g.id
-- 新增:关联库房表(根据 sh_id 查库房名称)
LEFT JOIN st_storehouse w ON s.sh_id = w.id
-- 新增:关联库位表(根据 sl_id 查库位号)
LEFT JOIN st_storage_location l ON s.sl_id = l.id
WHERE s.is_deleted = 0
AND s.quantity > 0
<if test="filterValue != null and filterValue != ''">
AND (g.goods_code LIKE '%' || #{filterValue} || '%'
OR g.goods_name LIKE '%' || #{filterValue} || '%')
</if>
<if test="shId != null"> AND s.sh_id = #{shId} </if>
<if test="goodsId != null"> AND s.goods_id = #{goodsId} </if>
<!-- <if test="deptId != null"> AND s.dept_id = #{deptId} </if>-->
ORDER BY s.pi_no ASC
</select>
<select id="getFirstByGoodsCodeAndDeptId" resultMap="stRealtimeStockResultMap">
SELECT *
FROM (
SELECT *
FROM ST_REALTIME_STOCK r
JOIN ST_GOODS g ON r.GOODS_ID = g.ID
WHERE g.GOODS_CODE = #{goodsCode}
AND r.QUANTITY > 0
AND r.STOP_USE = 0
AND r.DEPT_ID = #{deptId}
AND r.SH_CODE NOT IN ('LJJCP001', 'MJCP001')
ORDER BY r.CREATE_TIME ASC
)
WHERE ROWNUM = 1
FOR UPDATE
</select>
<select id="getByBarCode" resultMap="stRealtimeStockResultMap">
SELECT *
FROM (
SELECT *
FROM ST_REALTIME_STOCK
WHERE BAR_CODE = #{barCode}
AND QUANTITY > 0
ORDER BY ID ASC
)
WHERE ROWNUM = 1
</select>
<select id="getByGoodsCode" resultMap="stRealtimeStockResultMap">
SELECT *
FROM (
SELECT r.*
FROM ST_REALTIME_STOCK r
JOIN ST_GOODS g ON r.GOODS_ID = g.ID
WHERE g.GOODS_CODE = #{barCode}
AND r.QUANTITY > 0
ORDER BY r.ID ASC
)
WHERE ROWNUM = 1
</select>
<select id="getSynchById" resultMap="stRealtimeStockResultMap">
SELECT *
FROM ST_REALTIME_STOCK
WHERE ID = #{rlsId}
AND ROWNUM = 1
FOR UPDATE
</select>
<select id="selectStockGoodsPage" resultType="org.springblade.wms.pojo.vo.StRealtimeStockVO">
SELECT
g.goods_id ,
g.goods_code ,
g.goods_name ,
g.material_model ,
g.specifications ,
g.is_deleted ,
s.quantity ,
s.occupy_quantity ,
s.current_quantity ,
s.dept_id
FROM st_realtime_stock s
LEFT JOIN st_goods g ON s.goods_id = g.id
<where>
<!-- 1. 固定条件:物料未删除 -->
AND g.is_deleted = 0
<!-- 2. 可用库存 > 0 (quantity - zyQuantity > 0) -->
AND (s.quantity - s.occupy_quantity) > 0
<!-- 3. 部门ID过滤(deptId对应factoryId) -->
<if test="deptId != null">
AND s.dept_id = #{deptId}
</if>
<!-- 4. 物料编码模糊查询 -->
<if test="goodsCode != null and goodsCode != ''">
AND g.goods_code LIKE '%' || #{goodsCode} || '%'
</if>
<!-- 5. 物料名称模糊查询 -->
<if test="goodsName != null and goodsName != ''">
AND g.goods_name LIKE '%' || #{goodsName} || '%'
</if>
<!-- 6. 物料标记模糊查询 -->
<if test="materialModel != null and materialModel != ''">
AND g.material_model LIKE '%' || #{materialModel} || '%'
</if>
<!-- 7. 规格模糊查询 -->
<if test="specifications != null and specifications != ''">
AND g.specifications LIKE '%' || #{specifications} || '%'
</if>
</where>
<!-- 排序:默认按goodsId升序(对齐原逻辑) -->
ORDER BY g.goods_id ASC
</select>
<select id="checkRealTimeLock" resultType="java.lang.Boolean">
SELECT CASE
WHEN COUNT(1) > 0 THEN 1
ELSE 0
END
FROM ST_REALTIME_STOCK_LOCK
WHERE STATUS = 0
AND WO_NO = #{woCode}
AND ID = #{id}
</select>
<update id="updateRealTimeLock">
UPDATE ST_REALTIME_STOCK_LOCK
SET OCCUPY_QUANTITY = OCCUPY_QUANTITY + #{doubleValue},
STATUS = CASE
WHEN ZY_QUANTITY + #{doubleValue} = 0 THEN 1
ELSE 0
END
WHERE WO_NO = #{woNo}
AND ID = #{id}
</update>
<select id="selectToolsStockPage" resultMap="stRealtimeStockResultMap">
SELECT
s.*
FROM st_realtime_stock s
LEFT JOIN st_storehouse h ON s.sh_id = h.id
<where>
s.is_deleted = 0
AND h.is_deleted = 0
<!-- 2. 固定条件:量具库(对应 StStorehouse.TYPE_RULE = 5) -->
AND h.type = 5
</where>
</select>
</mapper>

@ -0,0 +1,25 @@
package org.springblade.wms.pojo.dto;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springblade.wms.pojo.entity.StRealtimeStock;
import java.io.Serial;
/**
* @version 1.0
* @program: jonhon-mes-svr
* @ClassName StRealtimeStockDTO
* @description: 仓库实时结余表 数据传输对象实体类
* @autor: WuSiYu
* @create 2025-12-15 14:48
**/
@Data
@EqualsAndHashCode(callSuper = true)
public class StRealtimeStockDTO extends StRealtimeStock {
@Serial
private static final long serialVersionUID = 1L;
}

@ -0,0 +1,196 @@
package org.springblade.wms.pojo.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springblade.core.tenant.mp.TenantEntity;
import org.springblade.wms.mapper.StGoodsMapper;
import org.springframework.data.annotation.Transient;
import java.io.Serial;
import java.util.Date;
/**
* @version 1.0
* @program: jonhon-mes-svr
* @ClassName StRealtimeStock
* @description: 仓库实时结余表 实体类
* @autor: WuSiYu
* @create 2025-12-15 14:45
**/
@Data
@TableName("ST_REALTIME_STOCK")
@Schema(description = "StRealtimeStock对象")
@EqualsAndHashCode(callSuper = true)
public class StRealtimeStock extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 库房ID
*/
@Schema(description = "库房ID")
private Long shId;
/**
* 物料ID关联st_goods表
*/
@Schema(description = "物料ID(关联st_goods表)")
@TableField("goods_id")
private Long goodsId;
/**
* 库位ID
*/
@Schema(description = "库位ID")
private Long slId;
/**
* 批次号
*/
@Schema(description = "批次号")
private String piNo;
/**
* 库存数量
*/
@Schema(description = "库存数量")
private Double quantity;
/**
* 金额-单价
*/
@Schema(description = "金额-单价")
private Double balanceMoney;
/**
* 质量等级
*/
@Schema(description = "质量等级")
private String quantityLevel;
/**
* 过期/报废日期
*/
@Schema(description = "过期/报废日期")
private Date scrapCycle;
/**
* 质量编号
*/
@Schema(description = "质量编号")
private String checkCode;
/**
* 是否模架物料1=/0=
*/
@Schema(description = "是否模架物料(1=是/0=否)")
private Boolean moldBaseMaterial;
/**
* 模架物料库存对应模架库存ID
*/
@Schema(description = "模架物料库存对应模架库存ID")
private Long moldRlsId;
/**
* 是否停用1=/0=
*/
@Schema(description = "是否停用(1=是/0=否)")
private Boolean stopUse;
/**
* 累计次数
*/
@Schema(description = "累计次数")
private Long sumNum;
/**
* 库存来源1=采购/2=生产/3=调拨等
*/
@Schema(description = "库存来源(1=采购/2=生产/3=调拨等)")
private Long stockSource;
/**
* 待保养次数
*/
@Schema(description = "待保养次数")
private Long stayMaintainNum;
/**
* 物料状态
*/
@Schema(description = "物料状态")
private Long goodsStatus;
/**
* 分厂类型
*/
@Schema(description = "分厂类型")
private Long facilityType;
/**
* 分厂ID
*/
@Schema(description = "分厂ID")
private String deptId;
/**
* 条码号
*/
@Schema(description = "条码号")
private String barCode;
/**
* 占用数量
*/
@Schema(description = "占用数量")
private Double occupyQuantity;
/**
* 炉批号
*/
@Schema(description = "炉批号")
private String stovePiNo;
/**
* 到期送检是否申请
*/
@Schema(description = "到期送检是否申请")
private Boolean applyFor;
/**
* 供方代码
*/
@Schema(description = "供方代码")
private String splyCode;
/**
* 限用标记
*/
@Schema(description = "限用标记")
private Long limitUseFlag;
/**
* ERP入库时间
*/
@Schema(description = "ERP入库时间")
private Date erpStorageTime;
/**
* 是否印字
*/
@Schema(description = "是否印字")
private Boolean printMark;
/**
* 粉重
*/
@Schema(description = "粉重")
private String powderWeight;
/**
* 材料号
*/
@Schema(description = "材料号")
private String materialNo;
/**
* 厚度
*/
@Schema(description = "厚度")
private String thickness;
/**
* 备注
*/
@Schema(description = "备注")
private String memo;
/**
* 保管员
*/
// @Transient
// private String keeper;
// @Transient
private Double outQuantity;
}

@ -0,0 +1,91 @@
package org.springblade.wms.pojo.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springblade.core.tenant.mp.TenantEntity;
import java.io.Serial;
/**
* @version 1.0
* @program: jonhon-mes-svr
* @ClassName StStorehouse
* @description: 库房维护表 实体类
* @autor: WuSiYu
* @create 2025-12-18 14:16
**/
@Data
@TableName("ST_STOREHOUSE")
@Schema(description = "StStorehouse对象")
@EqualsAndHashCode(callSuper = true)
public class StStorehouse extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 库房编号
*/
@Schema(description = "库房编号")
private String shCode;
/**
* 库房名称
*/
@Schema(description = "库房名称")
private String shName;
/**
* 所属分类
*/
@Schema(description = "所属分类")
private Short type;
/**
* 工装分类
*/
@Schema(description = "工装分类")
private Short toolingType;
/**
* 库房层级
*/
@Schema(description = "库房层级")
private String shLevel;
/**
* 部门ID
*/
@Schema(description = "部门ID")
private String deptId;
/**
* 保管员ID
*/
@Schema(description = "保管员ID")
private Long saveUser;
/**
* 类别说明
*/
@Schema(description = "类别说明")
private String memo;
// 模具库
public static final Short TYPE_MOLD = 0;
// 材料库
public static final Short TYPE_PART = 1;
// 刀具库
public static final Short TYPE_TOOL = 2;
// 工装库
public static final Short TYPE_WORK = 3;
// 电极库
public static final Short TYPE_ELECTRODE = 4;
// 量具库
public static final Short TYPE_RULE = 5;
// 夹具库
public static final Short TYPE_JIA_JU = 6;
public static Short TOOLING_TYPE_MOLD = 0;//模具
public static Short TOOLING_TYPE_TOOL = 1;//工装
public static Short TOOLING_TYPE_RULE = 2;//量具
}

@ -0,0 +1,21 @@
package org.springblade.wms.pojo.vo;
import lombok.Data;
/**
* @version 1.0
* @program: jonhon-mes-svr
* @ClassName PrintParentWoLabel
* @description: 库存打印标签数据模型()
* @autor: WuSiYu
* @create 2025-12-17 09:50
**/
@Data
public class PrintParentWoLabel {
private PrintWoLabel plOne;
private PrintWoLabel plTwo;
private PrintWoLabel plThree;
private PrintWoLabel plFour;
}

@ -0,0 +1,86 @@
package org.springblade.wms.pojo.vo;
import lombok.Data;
import java.io.Serializable;
/**
* @version 1.0
* @program: jonhon-mes-svr
* @ClassName PrintStoresList
* @description:
* @autor: WuSiYu
* @create 2025-12-17 18:01
**/
@Data
public class PrintStoresList implements java.io.Serializable {
/**
* 供货单位
*/
private String supplier;
/**
* 物料信息
*/
private String materialMess;
/**
* 物料编码
*/
private String materialCode;
/**
* 入库日期
*/
private String inStore;
/**
* 库位号
*/
private String locator;
/**
* 单位
*/
private String unit;
/**
* 检验编号
*/
private String testCode;
/**
* 到期日期
*/
private String matureDate;
/**
* 批次号
*/
private String batchNo;
/**
* 生产标识
*/
private String identification;
/**
* 炉批号
*/
private String heatNo;
/**
* 日期
*/
private String date;
/**
* 摘要
*/
private String memo;
/**
* 收入数
*/
private String income;
/**
* 发出数
*/
private String issueNum;
/**
* 结存数
*/
private String balance;
/**
* 经手人
*/
private String handledBy;
}

@ -0,0 +1,41 @@
package org.springblade.wms.pojo.vo;
import lombok.Data;
import java.io.Serializable;
/**
* @version 1.0
* @program: jonhon-mes-svr
* @ClassName PrintWoLabel
* @description: 库存打印标签数据模型()
* @autor: WuSiYu
* @create 2025-12-17 10:00
**/
@Data
public class PrintWoLabel implements Serializable {
/**
* 条码号
*/
private String rsId;
/**
* 编码
*/
private String code;
/**
* 名称
*/
private String name;
/**
* 检验编号
*/
private String checkCode;
/**
* 日期
*/
private String date;
}

@ -0,0 +1,54 @@
package org.springblade.wms.pojo.vo;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springblade.wms.pojo.entity.StRealtimeStock;
import java.io.Serial;
import java.math.BigDecimal;
import java.util.Date;
/**
* @version 1.0
* @program: jonhon-mes-svr
* @ClassName StRealtimeStockVO
* @description: 仓库实时结余表 视图实体类
* @autor: WuSiYu
* @create 2025-12-15 14:49
**/
@Data
@EqualsAndHashCode(callSuper = true)
public class StRealtimeStockVO extends StRealtimeStock {
@Serial
private static final long serialVersionUID = 1L;
private Long id; // 主键ID
private Long goodsId; // 物料ID
private Double quantity; // 库存数量
private Double lockQuantity;
private Double onthewayQuantity;
private Double currentQuantity;
private String piNo; // 批号
private Long slId; // 库位ID
private String barCode; // 条形码
private Date scrapCycle; // 报废周期
private String checkCode; // 检验码
private String splyCode; // 供应商编码
private String goodsName;
private String shName;
private Long shId;
private String location;
private String specifications;
@TableField(exist = false)
private String filterValue;
private Boolean special; // 特殊标识
private Double syQuantity;
@TableField(exist = false)
private String goodsCodeAndGoodsName;
}

@ -0,0 +1,82 @@
package org.springblade.wms.service;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.core.mp.base.BaseService;
import org.springblade.core.secure.BladeUser;
import org.springblade.wms.excel.StRealtimeStockExcel;
import org.springblade.wms.pojo.entity.StRealtimeStock;
import org.springblade.wms.pojo.entity.StStockInoutRecord;
import org.springblade.wms.pojo.entity.StStorageLocation;
import org.springblade.wms.pojo.entity.StStoreBill;
import org.springblade.wms.pojo.vo.PrintParentWoLabel;
import org.springblade.wms.pojo.vo.PrintStoresList;
import org.springblade.wms.pojo.vo.StRealtimeStockVO;
import java.util.List;
/**
* @version 1.0
* @program: jonhon-mes-svr
* @ClassName IStRealtimeStockService
* @description: 仓库实时结余表 服务类
* @autor: WuSiYu
* @create 2025-12-15 14:56
**/
public interface IStRealtimeStockService extends BaseService<StRealtimeStock> {
/**
* 自定义分页
*
* @param page 分页参数
* @param stRealtimeStock 查询参数
* @return IPage<StRealtimeStockVO>
*/
IPage<StRealtimeStockVO> selectStRealtimeStockPage(IPage<StRealtimeStockVO> page, StRealtimeStockVO stRealtimeStock);
/**
* 导出数据
*
* @param queryWrapper 查询条件
* @return List<StRealtimeStockExcel>
*/
List<StRealtimeStockExcel> exportStRealtimeStock(Wrapper<StRealtimeStock> queryWrapper);
List<PrintParentWoLabel> printPrintWoLabel(List<Long> rlsIdList, Short quantity);
List<PrintStoresList> printStRealtimeStockList(List<Long> idArr);
Double getByShId(Long keyId);
Double getQuantityBySlId(Long slId);
StRealtimeStock getBySlId(Long slId);
boolean findBySlId(Long slId);
void updateLocation(Long id, StStorageLocation lo);
List<Long> reviseRealTimeStock(List<StStockInoutRecord> inoutList, List<StRealtimeStock> stockList, List<String> splyCodeList);
Double findPriceByParams(Long goodsId, String checkNo);
IPage<StRealtimeStockVO> selectByGoodsIdShId(Long goodsId, Long shId, String deptId);
// IPage<StRealtimeStockVO> selectGoodsOut(String filterValue, Long shId, Long goodsId, String deptId, Integer current, Integer size);
StRealtimeStock getFirstByGoodsCodeAndDeptId(String goodsCode, String deptId);
StRealtimeStock getByBarCode(String barCode);
StRealtimeStock getByGoodsCode(String barCode);
IPage<StRealtimeStockVO> selectGoodsOut(String filterValue, Long shId, Long goodsId, IPage<StRealtimeStockVO> page);
void stockProcessing(List<StStoreBill> storeBillList, Short billsourceBorrow, BladeUser user) throws Exception ;
IPage<StRealtimeStockVO> selectStockGoodsPage(IPage<StRealtimeStockVO> page, StRealtimeStockVO stRealtimeStock);
IPage<StRealtimeStockVO> selectToolsStockPage(IPage<StRealtimeStockVO> page, StRealtimeStockVO stRealtimeStock);
}

@ -0,0 +1,539 @@
package org.springblade.wms.service.impl;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springblade.common.exception.BusinessException;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.secure.BladeUser;
import org.springblade.wms.excel.StRealtimeStockExcel;
import org.springblade.wms.mapper.StGoodsMapper;
import org.springblade.wms.mapper.StRealtimeStockMapper;
import org.springblade.wms.mapper.StStorageLocationMapper;
import org.springblade.wms.pojo.entity.*;
import org.springblade.wms.pojo.vo.PrintParentWoLabel;
import org.springblade.wms.pojo.vo.PrintStoresList;
import org.springblade.wms.pojo.vo.PrintWoLabel;
import org.springblade.wms.pojo.vo.StRealtimeStockVO;
import org.springblade.wms.service.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
/**
* @version 1.0
* @program: jonhon-mes-svr
* @ClassName StRealtimeStockServiceImpl
* @description: 仓库实时结余表 服务实现类
* @autor: WuSiYu
* @create 2025-12-15 14:58
**/
@Service
public class StRealtimeStockServiceImpl extends BaseServiceImpl<StRealtimeStockMapper, StRealtimeStock> implements IStRealtimeStockService {
@Resource
private StRealtimeStockMapper stRealtimeStockMapper;
@Resource
private StGoodsMapper stGoodsMapper;
@Resource
private StStorageLocationMapper stStorageLocationMapper;
@Resource
private IStGoodsService stGoodsService;
@Resource
private IStStoreBillService stStoreBillService;
@Resource
private IStLockGoodsService stLockGoodsService;
@Resource
private IStOtherOutRecordService stOtherOutRecordService;
@Override
public IPage<StRealtimeStockVO> selectStRealtimeStockPage(IPage<StRealtimeStockVO> page, StRealtimeStockVO stRealtimeStock) {
return page.setRecords(baseMapper.selectStRealtimeStockPage(page, stRealtimeStock));
}
@Override
public IPage<StRealtimeStockVO> selectStockGoodsPage(IPage<StRealtimeStockVO> page, StRealtimeStockVO stRealtimeStock) {
return page.setRecords(baseMapper.selectStockGoodsPage(page, stRealtimeStock));
}
@Override
public IPage<StRealtimeStockVO> selectToolsStockPage(IPage<StRealtimeStockVO> page, StRealtimeStockVO stRealtimeStock) {
return page.setRecords(baseMapper.selectToolsStockPage(page, stRealtimeStock));
}
@Override
public List<PrintParentWoLabel> printPrintWoLabel(List<Long> rlsIdList, Short quantity) {
if (rlsIdList == null || rlsIdList.size() == 0) {
return null;
}
List<Long> rlsIdListAll = new ArrayList<>();
for (int i = 0; i < quantity; i++) {
rlsIdListAll.addAll(rlsIdList);
}
rlsIdListAll = rlsIdListAll.stream().sorted(Long::compareTo).collect(Collectors.toList());
Map<Integer, List<Long>> map = new HashMap<>(1);
List<Long> list = null;
Integer num = 0;
int i = 1;
PrintWoLabel printWoLabel;
PrintParentWoLabel printParentWoLabel = null;
StRealtimeStock stRealtimeStock;
List<PrintParentWoLabel> plList = new ArrayList<>();
for (Long id : rlsIdListAll) {
if (!map.containsKey(num)) {
list = new ArrayList<>();
map.put(num, list);
printParentWoLabel = new PrintParentWoLabel();
}
list.add(id);
printWoLabel = new PrintWoLabel();
stRealtimeStock = stRealtimeStockMapper.selectById(id);
printWoLabel.setRsId(String.valueOf(id));
StGoods goods = stGoodsMapper.selectById(stRealtimeStock.getGoodsId());
printWoLabel.setCode(goods.getGoodsCode());
printWoLabel.setName(goods.getGoodsName());
printWoLabel.setCheckCode(stRealtimeStock.getCheckCode());
Date scrapCycle = stRealtimeStock.getScrapCycle();
if (scrapCycle != null) {
printWoLabel.setDate(scrapCycle.toString());
} else {
printWoLabel.setDate("");
}
if (list.size() == 1) {
printParentWoLabel.setPlOne(printWoLabel);
}
if (list.size() == 2) {
printParentWoLabel.setPlTwo(printWoLabel);
}
if (list.size() == 3) {
printParentWoLabel.setPlThree(printWoLabel);
}
if (list.size() == 4) {
printParentWoLabel.setPlFour(printWoLabel);
plList.add(printParentWoLabel);
num++;
} else if (i == rlsIdListAll.size()) {
plList.add(printParentWoLabel);
}
i++;
}
return plList;
}
@Override
public List<PrintStoresList> printStRealtimeStockList(List<Long> idArr) {
List<PrintStoresList> pcdLst = new ArrayList<>();
for (Long rlsId : idArr) {
PrintStoresList psl = new PrintStoresList();
// 组装头
this.makeHead(psl, rlsId);
pcdLst.add(psl);
}
return pcdLst;
}
private void makeHead(PrintStoresList psl, Long rlsId) {
StRealtimeStock sts = this.getById(rlsId);
StGoods goods = stGoodsMapper.selectById(sts.getGoodsId());
psl.setMaterialMess(goods.getGoodsCode() + goods.getGoodsName());
psl.setMaterialCode(goods.getGoodsCode());
psl.setInStore(sts.getCreateTime().toString());
StStorageLocation stStorageLocation = stStorageLocationMapper.selectById(sts.getSlId());
psl.setLocator(stStorageLocation.getLocation());
psl.setUnit(goods.getUnitName());
psl.setTestCode(sts.getCheckCode() != null ? sts.getCheckCode() : "");
psl.setMatureDate(sts.getScrapCycle() != null ? sts.getScrapCycle().toString() : "");
psl.setBatchNo(sts.getPiNo());
psl.setIdentification(goods.getMaterialModel());
psl.setSupplier("");
psl.setHeatNo(sts.getStovePiNo() != null ? sts.getStovePiNo() : "");
psl.setDate(sts.getCreateTime().toString());
psl.setMemo("");
psl.setIncome(goods.getPurchaseQuantity() != null ? goods.getPurchaseQuantity().toString() : "");
DecimalFormat df = new DecimalFormat("#");
psl.setBalance(df.format(sts.getQuantity()));
// psl.setHandledBy(sts.getKeeper());
}
@Override
public Double getByShId(Long shId) {
return stRealtimeStockMapper.getByShId(shId);
}
@Override
public Double getQuantityBySlId(Long slId) {
return stRealtimeStockMapper.getQuantityBySlId(slId);
}
@Override
public StRealtimeStock getBySlId(Long slId) {
return stRealtimeStockMapper.getBySlId(slId);
}
@Override
public boolean findBySlId(Long slId) {
return stRealtimeStockMapper.findBySlId(slId);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateLocation(Long id, StStorageLocation newStorageLocation) {
StRealtimeStock stock = stRealtimeStockMapper.selectById(id);
if (stock == null) {
throw new ServiceException("实时库存不存在,rlsId=" + id);
}
if (newStorageLocation == null || newStorageLocation.getShId() == null) {
throw new ServiceException("目标库位信息不完整");
}
stock.setShId(newStorageLocation.getShId());
stock.setSlId(newStorageLocation.getId());
stRealtimeStockMapper.updateById(stock);
}
@Override
public List<Long> reviseRealTimeStock(List<StStockInoutRecord> inoutList, List<StRealtimeStock> stockList, List<String> splyCodeList) {
// 前置校验:避免空列表和索引越界
if (inoutList == null || inoutList.isEmpty()) {
throw new IllegalArgumentException("StStockInoutRecord出入库记录列表不能为空!");
}
// 校验前两个List长度一致性(保证明细与库存对象一一对应)
if (stockList != null && stockList.size() != inoutList.size()) {
throw new IllegalArgumentException("StStockInoutRecord与StRealtimeStock两个列表长度不一致,无法批量处理!");
}
// 初始化返回集合,收集批量处理的rlsId
List<Long> rlsIdList = new ArrayList<>();
// 遍历出入库记录列表,批量执行核心业务逻辑
for (int i = 0; i < inoutList.size(); i++) {
// 3.1 获取当前索引对应的单个对象
StStockInoutRecord inout = inoutList.get(i);
// 兼容stockList为null的情况,避免空指针
StRealtimeStock stock = (stockList != null && stockList.size() > i) ? stockList.get(i) : null;
// 核心业务逻辑
Double quantity = inout.getQuantity();
Double balanceMoney = inout.getSirMoney() == null ? 0.0 : inout.getSirMoney(); // 字段名若变更需同步调整
if (inout.getInOutSource() < StStockInoutRecord.INOUT_SOURCE_QUOTA_OUT) {
//入库逻辑
if (StStockInoutRecord.INOUT_SOURCE_PURCHASE_RECEIPT.equals(inout.getInOutSource())) {
// 1.减在途
if (!inout.getMoldBaseMaterial()) {
stGoodsService.addOnthewayQuantity(inout.getGoodsId(),
BigDecimal.valueOf(0).subtract(BigDecimal.valueOf(quantity)).doubleValue());
}
// 2.增当前库存
stGoodsService.addCurQuantity(inout.getGoodsId(), quantity);
// } else if (StStockInoutRecord.INOUT_SOURCE_PRODUCE_PURCHASE_RECEIPT.equals(inout.getBillFlag())) {
// //生产入库:增库存
// stGoodsService.addCurQuantity(inout.getGoods().getGoodsId(), quantity);
} else if (StStockInoutRecord.INOUT_SOURCE_OTHER_PURCHASE_RECEIPT.equals(inout.getInOutSource())
|| StStockInoutRecord.INOUT_SOURCE_PRODUCTION_MATERIAL_RETURN.equals(inout.getInOutSource())) {
//其他入库/生产退料:增库存
stGoodsService.addCurQuantity(inout.getGoodsId(), quantity);
} else if (StStockInoutRecord.INOUT_SOURCE_TRANSFER_RECEIPT.equals(inout.getInOutSource())) {
//调拨入库
// 1.减在途
stGoodsService.addOnthewayQuantity(inout.getGoodsId(),
BigDecimal.valueOf(0).subtract(BigDecimal.valueOf(quantity)).doubleValue());
// 2.增当前库存
stGoodsService.addCurQuantity(inout.getGoodsId(), quantity);
} else if (StStockInoutRecord.INOUT_SOURCE_WAREHOUSE_TRANSFER.equals(inout.getInOutSource())) {
//库转移入库
// 1.减在途
if (!inout.getMoldBaseMaterial()) {
stGoodsService.addOnthewayQuantity(inout.getGoodsId(),
BigDecimal.valueOf(0).subtract(BigDecimal.valueOf(quantity)).doubleValue());
}
// 2.增当前库存
stGoodsService.addCurQuantity(inout.getGoodsId(), quantity);
}
// } else {
// //出库逻辑
// if (stock == null) {
// throw new RuntimeException("第" + (i+1) + "条出入库记录对应的出库物料为空,请选择出库物料!");
// }
// stock = stRealtimeStockMapper.getSynchById(stock.getId());
// //当前库位库存小于出库数量
// if (stock.getQuantity() < quantity) {
// throw new RuntimeException("第" + (i+1) + "条出入库记录当前库位库存不足,出库失败!");
// }
// // 获取物料信息
// StGoods stGoods = stGoodsService.getById(inout.getGoodsId());
//
// if (StStockInoutRecord.INOUT_SOURCE_QUOTA_OUT.equals(inout.getInOutSource())) {
// //配额出库
// //1.减锁料
// PvBomRequest pvBomRequest = inout.getBrId();
// if (pvBomRequest != null) {
//
// StLockGoods lockGoods = stLockGoodsService.getByBrId(pvBomRequest.getId());
// //锁料中数量
// Double lockingQuantity = null;
// if (lockGoods != null) {
// lockingQuantity =
// BigDecimal.valueOf(lockGoods.getLockQuantity()).subtract(BigDecimal.valueOf(lockGoods.getOutQuantity())).doubleValue();
// } else {
// lockingQuantity = 0.0;
// }
// if (lockingQuantity < 0) {
// lockingQuantity = 0.0;
// }
// // 判断可用库存是否充足
// Double surplusQuantity =
// stGoods.getCurrentQuantity() + stGoods.getOnthewayQuantity() - stGoods.getLockQuantity();
// if (surplusQuantity < quantity - lockingQuantity) {
// throw new ServiceException(stGoods.getGoodsCode() + "可用库存不足,出库失败");
// }
// if (lockGoods != null) {
// stLockGoodsService.addOutQuantity(quantity, lockGoods.getId());
// }
// if (quantity < lockingQuantity) {
// stGoodsService.addLockQuantity(inout.getGoodsId(),
// BigDecimal.valueOf(0).subtract(BigDecimal.valueOf(quantity)).doubleValue());
// } else {
// stGoodsService.addLockQuantity(inout.getGoodsId(),
// BigDecimal.valueOf(0).subtract(BigDecimal.valueOf(lockingQuantity)).doubleValue());
// }
//
// //2 减库存
// stGoodsService.addCurQuantity(inout.getGoodsId(), BigDecimal.valueOf(0).subtract(BigDecimal.valueOf(quantity)).doubleValue());
// }
//
// } else if (StStockInoutRecord.INOUT_SOURCE_OTHER_OUT.equals(inout.getInOutSource())
// || StStockInoutRecord.INOUT_SOURCE_TOOl_OUT.equals(inout.getInOutSource())) {
// if (StringUtils.isNotBlank(inout.getWoCode()) && stock.getId() != null) {
//// if (!this.checkRealTimeLock(inout.getWoCode(),stock.getId().toString()) && !(inout.getMemo().indexOf("补")!=-1)) {
//// throw new RuntimeException("第" + (i+1) + "条出入库记录热表玻璃饼出库需匹配预占用,此工作订单无预占用!");
//// }
// if (!this.checkRealTimeLock(inout.getWoCode(), stock.getId().toString())) {
// StOtherOutRecord stOtherOutRecord = stOtherOutRecordService.getBySirId(inout.getId());
// if (StringUtils.isNotBlank(stOtherOutRecord.getMemo())) {
// if (!(stOtherOutRecord.getMemo().indexOf("补") != -1)) {
// throw new ServiceException("热表玻璃饼出库需匹配预占用,此工作订单无预占用!");
// }
// } else {
// throw new ServiceException("热表玻璃饼出库需匹配预占用,此工作订单无预占用!");
// }
// }
// }
// //其他出库/刀具出库:校验可用库存并减库存
// Double surplusQuantity =
// stGoods.getCurrentQuantity() + stGoods.getOnthewayQuantity() - stGoods.getLockQuantity();
// if (surplusQuantity < quantity) {
// throw new ServiceException(stGoods.getGoodsCode() + "可用库存不足,出库失败");
// }
// stGoodsService.addCurQuantity(inout.getGoodsId(), BigDecimal.valueOf(0).subtract(BigDecimal.valueOf(quantity)).doubleValue());
// } else if (StStockInoutRecord.INOUT_SOURCE_ASSIGN_OUT.equals(inout.getInOutSource())) {
// if (!stock.getMoldBaseMaterial()) {
// //生产领料出库
//// StUseGoodsDetail detail = stUseGoodsDetailService.queryByAbdId(inout.getAbdId()); // 字段名若变更需调整
//// PvBomRequest pvBomRequest = null;
//// if (detail != null) {
//// pvBomRequest = detail.getPrWorkpiece().getDsSelfParts().getPvBomRequest();
//// }
//
// //1.减锁料
//// if (pvBomRequest != null) {
//// StLockGoods lockGoods = stLockGoodsService.getByBrId(pvBomRequest.getId());
// Double lockingQuantity = null;
// if (lockGoods != null) {
// lockingQuantity =
// BigDecimal.valueOf(lockGoods.getLockQuantity()).subtract(BigDecimal.valueOf(lockGoods.getOutQuantity())).doubleValue();
// } else {
// lockingQuantity = 0.0;
// }
// if (lockingQuantity < 0) {
// lockingQuantity = 0.0;
// }
// // 校验可用库存
// Double surplusQuantity =
// stGoods.getCurrentQuantity() + stGoods.getOnthewayQuantity() - stGoods.getLockQuantity();
// if (surplusQuantity < quantity - lockingQuantity) {
// throw new ServiceException(stGoods.getGoodsCode() + "可用库存不足,出库失败");
// }
// if (lockGoods != null) {
// stLockGoodsService.addOutQuantity(quantity, lockGoods.getId());
// }
// if (quantity < lockingQuantity) {
// stGoodsService.addLockQuantity(inout.getGoodsId(),
// BigDecimal.valueOf(0).subtract(BigDecimal.valueOf(quantity)).doubleValue());
// } else {
// stGoodsService.addLockQuantity(inout.getGoodsId(),
// BigDecimal.valueOf(0).subtract(BigDecimal.valueOf(lockingQuantity)).doubleValue());
// }
// //2.减库存
// stGoodsService.addCurQuantity(inout.getGoodsId(), BigDecimal.valueOf(0).subtract(BigDecimal.valueOf(quantity)).doubleValue());
// }
// }
// }
//
// quantity = BigDecimal.valueOf(0).subtract(BigDecimal.valueOf(quantity)).doubleValue();
}
// 调用底层方法,获取单个rlsId并添加到返回集合
// Long rlsId = this.reviseRealTimeStock(stock, inout, quantity, balanceMoney, splyCode);
// rlsIdList.add(rlsId);
}
//
// // 返回批量处理后的rlsId列表
return rlsIdList;
}
@Transactional(rollbackFor = Exception.class)
public Long reviseRealTimeStock(StRealtimeStock stock,
StStockInoutRecord inout,
Double quantity,
Double balanceMoney,
String splyCode) {
/* 1. 无记录 → 新增 */
if (stock == null) {
StRealtimeStock entity = new StRealtimeStock();
entity.setGoodsId(inout.getGoodsId());
entity.setShId(inout.getShId());
entity.setSlId(inout.getSlId());
entity.setPiNo(inout.getPiNo());
entity.setStovePiNo(inout.getStovePiNo());
entity.setThickness(inout.getThickness());
entity.setQuantity(quantity);
entity.setOccupyQuantity(0D);
entity.setBalanceMoney(balanceMoney);
entity.setCreateTime(Optional.ofNullable(inout.getInOutDate()).orElse(new Date()));
entity.setQuantityLevel(inout.getQuantityLevel());
entity.setScrapCycle(inout.getScrapCycle());
entity.setCheckCode(inout.getCheckNo());
entity.setMoldBaseMaterial(inout.getMoldBaseMaterial());
entity.setBarCode(inout.getBarCode());
entity.setSplyCode(splyCode);
entity.setDeptId(inout.getDeptId());
this.save(entity);
return entity.getId();
}
/* 2. 有记录 → 累加数量 & 更新 */
StRealtimeStock db = baseMapper.getSynchById(stock.getId());
double newQty = NumberUtil.add(BigDecimal.valueOf(db.getQuantity()),
BigDecimal.valueOf(quantity))
.doubleValue();
db.setQuantity(newQty);
db.setBalanceMoney(balanceMoney);
db.setSplyCode(splyCode);
/* 车间订单锁料 */
double newOccupy = NumberUtil
.add(BigDecimal.valueOf(db.getOccupyQuantity()),
BigDecimal.valueOf(quantity))
.doubleValue();
if (StrUtil.isNotBlank(inout.getWoCode()) && newOccupy >= 0) {
db.setOccupyQuantity(newOccupy);
this.updateRealTimeLock(inout.getWoCode(), db.getId(), newOccupy);
}
this.updateById(db);
return db.getId();
}
private void updateRealTimeLock(String woCode, Long id, double doubleValue) {
baseMapper.updateRealTimeLock(woCode, id.toString(), doubleValue);
}
private boolean checkRealTimeLock(String woCode, String rlsId) {
return baseMapper.checkRealTimeLock(woCode, rlsId);
}
@Override
public Double findPriceByParams(Long goodsId, String checkNo) {
return baseMapper.findPriceByParams(goodsId, checkNo);
}
@Override
public IPage<StRealtimeStockVO> selectByGoodsIdShId(Long goodsId, Long shId, String deptId) {
return baseMapper.selectByGoodsIdShId(goodsId, shId, deptId);
}
// @Override
// public IPage<StRealtimeStockVO> selectGoodsOut(String filterValue, Long shId, Long goodsId, String deptId, Integer current, Integer size) {
// int curr = current == null || current < 1 ? 1 : current;
// int sz = size == null || size < 1 ? 10 : size;
// IPage<StRealtimeStockVO> page = new Page<>(curr, sz);
// return baseMapper.selectGoodsOut(page, filterValue, shId, goodsId, deptId);
// }
@Override
public void stockProcessing(List<StStoreBill> sbList, Short status, BladeUser curUserInfo) throws Exception {
StRealtimeStock rs = null;
for (StStoreBill sb : sbList) {
rs = this.getById(sb.getGoodsId());
if(rs == null){
throw new BusinessException("当前物料无可用库存,无法借出!");
}
if (status.equals(StStoreBill.BILLSOURCE_BORROW)) {
Double surplusQuantity = rs.getQuantity() - rs.getOccupyQuantity();
if (sb.getQuantity() > surplusQuantity) {
throw new BusinessException("库存剩余数量不足!");
}
rs.setOccupyQuantity(rs.getOccupyQuantity() + sb.getQuantity());
this.updateById(rs);
} else if (status.equals(StStoreBill.BILLSOURCE_RETURN)) {
if (sb.getBillSource().equals(StStoreBill.BILLSOURCE_RETURN)) {
rs.setSumNum(rs.getSumNum() + sb.getUseNum());
this.updateById(rs);
}
}
sb = stStoreBillService.getById(sb.getId());
sb.setCurStatus(StStoreBill.CURSTATUS_COMPLETE);
stStoreBillService.updateById(sb);
}
}
@Override
public IPage<StRealtimeStockVO> selectGoodsOut(String filterValue, Long shId, Long goodsId, IPage<StRealtimeStockVO> page) {
return this.baseMapper.selectGoodsOut(page, filterValue, shId, goodsId);
}
@Override
public StRealtimeStock getFirstByGoodsCodeAndDeptId(String goodsCode, String deptId) {
return baseMapper.getFirstByGoodsCodeAndDeptId(goodsCode, deptId);
}
@Override
public StRealtimeStock getByBarCode(String barCode) {
return baseMapper.getByBarCode(barCode);
}
@Override
public StRealtimeStock getByGoodsCode(String barCode) {
return baseMapper.getByGoodsCode(barCode);
}
@Override
public List<StRealtimeStockExcel> exportStRealtimeStock (Wrapper < StRealtimeStock > queryWrapper) {
List<StRealtimeStockExcel> stRealtimeStockList = baseMapper.exportStRealtimeStock(queryWrapper);
//stRealtimeStockList.forEach(stRealtimeStock -> {
// stRealtimeStock.setTypeName(DictCache.getValue(DictEnum.YES_NO, StRealtimeStock.getType()));
//});
return stRealtimeStockList;
}
}

@ -0,0 +1,39 @@
package org.springblade.wms.wrapper;
import org.springblade.core.mp.support.BaseEntityWrapper;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.wms.pojo.entity.StRealtimeStock;
import org.springblade.wms.pojo.vo.StRealtimeStockVO;
import java.util.Objects;
/**
* @version 1.0
* @program: jonhon-mes-svr
* @ClassName StRealtimeStockWrapper
* @description: 仓库实时结余表 包装类,返回视图层所需的字段
* @autor: WuSiYu
* @create 2025-12-15 14:54
**/
public class StRealtimeStockWrapper extends BaseEntityWrapper<StRealtimeStock, StRealtimeStockVO> {
public static StRealtimeStockWrapper build() {
return new StRealtimeStockWrapper();
}
@Override
public StRealtimeStockVO entityVO(StRealtimeStock stRealtimeStock) {
StRealtimeStockVO stRealtimeStockVO = Objects.requireNonNull(BeanUtil.copyProperties(stRealtimeStock, StRealtimeStockVO.class));
//User createUser = UserCache.getUser(stRealtimeStock.getCreateUser());
//User updateUser = UserCache.getUser(stRealtimeStock.getUpdateUser());
//stRealtimeStockVO.setCreateUserName(createUser.getName());
//stRealtimeStockVO.setUpdateUserName(updateUser.getName());
return stRealtimeStockVO;
}
}
Loading…
Cancel
Save