add:增加库区策略

This commit is contained in:
2025-11-25 20:12:13 +08:00
parent b3b9761884
commit a62bcf4338
27 changed files with 310 additions and 350 deletions

View File

@@ -22,6 +22,7 @@ import org.springframework.context.ApplicationContextAware;
import org.springframework.core.env.Environment;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author Jie
@@ -154,4 +155,9 @@ public class SpringContextHolder implements ApplicationContextAware, DisposableB
}
SpringContextHolder.addCallback = false;
}
public static <T> Map<String,T> getBeansOfType(Class<T> requiredType) {
assertContextInjected();
return applicationContext.getBeansOfType(requiredType);
}
}

View File

@@ -6,6 +6,9 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import org.nl.common.domain.query.PageQuery;
import org.nl.wms.basedata_manage.service.dao.Structattr;
import org.nl.wms.basedata_manage.service.dto.MdPbStoragevehicleextDto;
import org.nl.wms.basedata_manage.service.dto.StrategyStructMaterialVO;
import org.nl.wms.basedata_manage.service.dto.StrategyStructParam;
import org.nl.wms.warehouse_management.service.dao.IOStorInv;
import org.springframework.data.domain.Pageable;
@@ -111,4 +114,14 @@ public interface IStructattrService extends IService<Structattr> {
*/
Structattr getByCode(String struct_code);
/**
* 入库规则
*/
List<Structattr> inBoundSectDiv(StrategyStructParam param);
/**
* 出库规则
*/
List<MdPbStoragevehicleextDto> outBoundSectDiv(StrategyStructParam param);
}

View File

@@ -127,25 +127,12 @@
mater.material_id,
mater.material_code,
mater.material_name,
mater.material_spec,
late.quality_time,
late.produce_time,
late.quality_type,
late.quality_type AS old_quality_type,
late.bake_num,
false AS edit,
(
CASE late.quality_type
WHEN '1' THEN '待检'
WHEN '2' THEN '合格'
WHEN '3' THEN '不合格'
END
) AS quality_name
mater.material_spec
FROM
md_pb_storagevehicleext ext
INNER JOIN st_ivt_structattr attr ON ext.storagevehicle_code = attr.storagevehicle_code
INNER JOIN md_me_materialbase mater ON mater.material_id = ext.material_id
LEFT JOIN md_pb_groupplate late ON late.material_id = ext.material_id and late.pcsn = ext.pcsn and late.storagevehicle_code = ext.storagevehicle_code
LEFT JOIN md_pb_groupplate late ON late.material_id = ext.material_id and late.pcsn = ext.pcsn and late.vehicle_code = ext.storagevehicle_code
<where>
1 = 1
<if test="param.stor_id != null and param.stor_id != ''">
@@ -208,12 +195,11 @@
st.sect_name,
st.struct_id,
st.struct_code,
st.struct_name,
TIMESTAMPDIFF(DAY,CURDATE(),late.quality_time) AS quality_day
st.struct_name
FROM
md_pb_storagevehicleext ex
INNER JOIN st_ivt_structattr st on ex.storagevehicle_code = st.storagevehicle_code
INNER JOIN md_pb_groupplate late on ex.storagevehicle_code = late.storagevehicle_code
INNER JOIN md_pb_groupplate late on ex.storagevehicle_code = late.vehicle_code
AND ex.material_id = late.material_id AND ex.pcsn = late.pcsn AND late.status = '2'
<where>
ex.material_id = #{material_id}
@@ -230,7 +216,7 @@
st.sect_id = #{sect_code}
</if>
</where>
ORDER BY quality_day,ex.insert_time,ex.canuse_qty
ORDER BY ex.insert_time
</select>
<select id="erpQueryIvt" resultType="com.alibaba.fastjson.JSONObject">

View File

@@ -16,6 +16,10 @@ public class StrategyStructParam {
*库区,暂时不用
*/
private String sect_code;
/*
*库区id
*/
private String sect_id;
/**
* 仓位编码
*/

View File

@@ -13,11 +13,13 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.nl.common.domain.query.PageQuery;
import org.nl.common.exception.BadRequestException;
import org.nl.common.utils.IdUtil;
import org.nl.common.utils.MapOf;
import org.nl.common.utils.SecurityUtils;
import org.nl.config.SpringContextHolder;
import org.nl.wms.basedata_manage.enums.BaseDataEnum;
import org.nl.wms.basedata_manage.service.IBsrealStorattrService;
import org.nl.wms.basedata_manage.service.ISectattrService;
@@ -26,10 +28,21 @@ import org.nl.wms.basedata_manage.service.dao.BsrealStorattr;
import org.nl.wms.basedata_manage.service.dao.Sectattr;
import org.nl.wms.basedata_manage.service.dao.Structattr;
import org.nl.wms.basedata_manage.service.dao.mapper.StructattrMapper;
import org.nl.wms.basedata_manage.service.dto.MdPbStoragevehicleextDto;
import org.nl.wms.basedata_manage.service.dto.StrategyStructMaterialVO;
import org.nl.wms.basedata_manage.service.dto.StrategyStructParam;
import org.nl.wms.decision_manage.service.IStSectStrategyService;
import org.nl.wms.decision_manage.service.dao.StSectStrategy;
import org.nl.wms.decision_manage.service.decisioner.Decisioner;
import org.nl.wms.warehouse_management.enums.IOSConstant;
import org.nl.wms.warehouse_management.enums.IOSEnum;
import org.nl.wms.warehouse_management.service.dao.IOStorInv;
import org.nl.wms.warehouse_management.service.dao.IOStorInvDis;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.math.BigDecimal;
@@ -46,6 +59,7 @@ import java.util.stream.Collectors;
* 2025/5/15
*/
@Service
@Slf4j
public class StructattrServiceImpl extends ServiceImpl<StructattrMapper, Structattr> implements IStructattrService {
@Resource
@@ -57,6 +71,9 @@ public class StructattrServiceImpl extends ServiceImpl<StructattrMapper, Structa
@Resource
private ISectattrService iSectattrService;
@Autowired
private IStSectStrategyService iStSectStrategyService;
@Override
public IPage<Structattr> queryAll(Map whereJson, PageQuery page) {
@@ -331,4 +348,82 @@ public class StructattrServiceImpl extends ServiceImpl<StructattrMapper, Structa
return one;
}
/**
* 入库分配
* @param param {
* stor_code仓库编码
* sect_code库区编码
* }
* @return List<Structattr> 返回结果为分配的具体仓位
* 当前分配不会自动锁定货位,分配完成后需要手动锁定货位
*/
@Override
public List<Structattr> inBoundSectDiv(StrategyStructParam param) {
//批号,单据暂时不校验,具体业务具体校验
Assert.noNullElements(new Object[]{param.getStrategyMaters(),param.getStor_code(),param.getSect_code()},"请求参数不能为空");
StSectStrategy one = iStSectStrategyService.getOne(new LambdaQueryWrapper<StSectStrategy>()
.eq(StSectStrategy::getSect_code, param.getSect_code())
.eq(StSectStrategy::getStrategy_type, IOSEnum.STRATEGY_TYPE.code("入库")));
if (one==null){
throw new BadRequestException("当前库区"+param.getSect_code()+"未配置入库规则");
}
List<String> strategy = one.getStrategy();
// 根据条件查询
LambdaQueryWrapper<Structattr> query = new QueryWrapper<Structattr>().lambda()
.eq(Structattr::getIs_used, IOSConstant.IS_DELETE_YES)
.eq(Structattr::getLock_type, IOSEnum.LOCK_TYPE.code("未锁定"))
.eq(Structattr::getSect_code, param.getSect_code())
.eq(Structattr::getIs_delete, IOSConstant.IS_DELETE_NO)
.and(wrapper -> wrapper.isNull(Structattr::getStoragevehicle_code).or().eq(Structattr::getStoragevehicle_code, ""));
List<Structattr> list = this.list(query);
// 执行策略
Map<String, Decisioner> decisionerMap = SpringContextHolder.getBeansOfType(Decisioner.class);
for (String decisionerType : strategy) {
Decisioner decisioner = decisionerMap.get(decisionerType);
log.info("执行入库策略:"+decisioner.strategyConfig.getStrategy_name());
list = decisioner.handler(list, param);
if (CollectionUtils.isEmpty(list)){
throw new BadRequestException("当前策略"+decisioner.strategyConfig.getStrategy_name()+"无可用货位,分配前数量:"+list.size());
}
}
return list;
}
/**
* 出库分配
* @param param根据库区需要物料及数量,单据,批次分配具体货位
* @return 返回结果为仓位--对应--货物组盘物料信息及出库冻结数量
* 当前分配不会自动锁定货位及冻结出库数量,分配完成后需要手动锁定货位并冻结出库数量
* 混料模式下,同一个出库单允许分配到同一个托盘上
*/
@Override
public List<MdPbStoragevehicleextDto> outBoundSectDiv(StrategyStructParam param) {
//只校验仓库,库区
Assert.noNullElements(new Object[]{param.getStor_code(),param.getSect_id(),param.getSect_code()},"请求参数不能为空");
StSectStrategy one = iStSectStrategyService.getOne(new LambdaQueryWrapper<StSectStrategy>()
.eq(StSectStrategy::getSect_code, param.getSect_code())
.eq(StSectStrategy::getStrategy_type, IOSEnum.STRATEGY_TYPE.code("出库")));
if (one==null){
throw new BadRequestException("当前库区"+param.getSect_code()+"未配置出库规则");
}
List<String> strategy = one.getStrategy();
Map<String, Decisioner> decisionerMap = SpringContextHolder.getBeansOfType(Decisioner.class);
List list = null;
for (String decisionerType : strategy) {
Decisioner decisioner = decisionerMap.get(decisionerType);
log.info("执行出入库规则:"+decisioner.strategyConfig.getStrategy_name());
list = decisioner.handler(list, param);
if (CollectionUtils.isEmpty(list)){
throw new BadRequestException("当前策略"+decisioner.strategyConfig.getStrategy_name()+"无可用库存,分配前数量:"+list.size());
}
}
return list;
}
}

View File

@@ -27,7 +27,7 @@ public class StSectStrategy implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
* 主键
*/
@TableId(value = "id", type = IdType.AUTO)
private Integer id;

View File

@@ -1,36 +1,39 @@
package org.nl.wms.decision_manage.service.decisioner.impl.base;
import lombok.extern.slf4j.Slf4j;
import org.nl.wms.basedata_manage.service.IStructattrService;
import org.nl.wms.basedata_manage.service.dto.StrategyStructMaterialVO;
import org.nl.wms.basedata_manage.service.dao.mapper.MdPbStoragevehicleextMapper;
import org.nl.wms.basedata_manage.service.dto.MdPbStoragevehicleextDto;
import org.nl.wms.basedata_manage.service.dto.StrategyMater;
import org.nl.wms.basedata_manage.service.dto.StrategyStructParam;
import org.nl.wms.decision_manage.service.decisioner.Decisioner;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import javax.annotation.Resource;
import java.util.List;
/*
/**
* <p>
* 先进先出策略 实现类
* </p>
*
* @author Liuxy
* @Date 2025/11/21
* 先进先出策略
* @since 2025-11-25
*/
@Service("fifo")
@Slf4j
public class FIFORuleHandler extends Decisioner<StrategyStructMaterialVO, StrategyStructParam> {
public class FIFORuleHandler extends Decisioner<MdPbStoragevehicleextDto, StrategyStructParam> {
/**
* 仓位服务
* 载具扩展属性mapper
*/
@Autowired
private IStructattrService iStructattrService;
@Resource
private MdPbStoragevehicleextMapper mdPbStoragevehicleextMapper;
@Override
public List<StrategyStructMaterialVO> handler(List<StrategyStructMaterialVO> list, StrategyStructParam param) {
public List<MdPbStoragevehicleextDto> handler(List<MdPbStoragevehicleextDto> list, StrategyStructParam param) {
log.info("---------执行fifo出库分配规则---------");
List<StrategyStructMaterialVO> divStruct = new ArrayList<>();
return divStruct;
StrategyMater strategyMater = param.getStrategyMaters().get(0);
return mdPbStoragevehicleextMapper.queryOutAllocation(strategyMater.getPcsn(), strategyMater.getMaterial_id(), param.getSect_id());
}
}

View File

@@ -0,0 +1,34 @@
package org.nl.wms.decision_manage.service.decisioner.impl.base;
import lombok.extern.slf4j.Slf4j;
import org.nl.wms.basedata_manage.service.dao.Structattr;
import org.nl.wms.basedata_manage.service.dto.StrategyStructParam;
import org.nl.wms.decision_manage.service.decisioner.Decisioner;
import org.springframework.stereotype.Service;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
* 就近策略 实现类
* </p>
*
* @author Liuxy
* @since 2025-11-25
*/
@Service("nearby")
@Slf4j
public class NearbyRuleHandler extends Decisioner<Structattr, StrategyStructParam> {
@Override
public List<Structattr> handler(List<Structattr> list, StrategyStructParam param) {
log.info("---------执行nearby入库分配规则---------");
// 根据仓位编码排序
return list.stream()
.sorted(Comparator.comparing(Structattr::getStruct_code))
.collect(Collectors.toList());
}
}

View File

@@ -24,9 +24,7 @@ import org.nl.wms.sch_manage.service.util.AcsTaskDto;
import org.nl.wms.sch_manage.service.util.TaskType;
import org.nl.wms.warehouse_management.enums.IOSConstant;
import org.nl.wms.warehouse_management.enums.IOSEnum;
import org.nl.wms.warehouse_management.service.IStIvtPieceBoxDtlService;
import org.nl.wms.warehouse_management.service.dao.GroupPlate;
import org.nl.wms.warehouse_management.service.dao.StIvtPieceBoxDtl;
import org.nl.wms.warehouse_management.service.dao.mapper.GroupPlateMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -82,12 +80,6 @@ public class EmpVehicleInTask extends AbstractTask {
@Autowired
private PdaPointTask pdaPointTask;
/**
* 拼箱明细服务
*/
@Autowired
private IStIvtPieceBoxDtlService iStIvtPieceBoxDtlService;
@Override
public String create(JSONObject json) {
SchBaseTask task = new SchBaseTask();
@@ -226,18 +218,6 @@ public class EmpVehicleInTask extends AbstractTask {
taskObj.setRemark("已取消");
taskObj.setTask_status(TaskStatus.CANCELED.getCode());
taskService.updateById(taskObj);
// 判断是否是拼箱入库的空载具
if (ObjectUtil.isNotEmpty(taskObj.getExt_group_data())) {
// 更新拼箱明细
iStIvtPieceBoxDtlService.update(
new UpdateWrapper<StIvtPieceBoxDtl>().lambda()
.eq(StIvtPieceBoxDtl::getId, taskObj.getExt_group_data())
.set(StIvtPieceBoxDtl::getIs_get, IOSConstant.IS_DELETE_NO)
.set(StIvtPieceBoxDtl::getIn_task_id, "")
.set(StIvtPieceBoxDtl::getBill_status, IOSEnum.PIECE_DTL_STATUS.code("拼箱中"))
);
}
}
@Override

View File

@@ -110,19 +110,6 @@ public class PdaPointTask extends AbstractTask {
acsTaskDto.setPriority(IOSConstant.ONE);
acsTaskDto.setAgv_system_type(IOSConstant.THREE);
// 如果起点是称重位则是0终点是称重位则是0
if (taskDao.getPoint_code1().equals(IOSConstant.CZW_POINT)) {
acsTaskDto.setIs_get_pause(IOSConstant.ZERO);
} else {
acsTaskDto.setIs_get_pause(IOSConstant.ONE);
}
if (taskDao.getPoint_code2().equals(IOSConstant.CZW_POINT)) {
acsTaskDto.setIs_put_pause(IOSConstant.ZERO);
} else {
acsTaskDto.setIs_put_pause(IOSConstant.ONE);
}
return acsTaskDto;
}

View File

@@ -37,15 +37,6 @@ public class IOSConstant {
*/
public final static String THREE = "3";
/**
* 出入库 入库
*/
public final static String IOS_IO_TYPE_IN = "入库";
/**
* 出入库 出库
*/
public final static String IOS_IO_TYPE_OUT = "出库";
/**
* 创建方式
*/
@@ -81,43 +72,4 @@ public class IOSConstant {
*/
public final static String UPDATE_IVT_TYPE_SUB_CANUSE_IVT = "6";
/**
* 移库任务类编码
*/
public final static String MOVE_CONFIG_TASK = "MoveTask";
/**
* 余料回库任务类编码
*/
public final static String BACK_IN_TASK = "BackInTask";
/**
* 手持定点任务
*/
public final static String PDA_POINT_TASK = "PdaPointTask";
/**
* 主存区编码
*/
public final static String SECT_CODE = "ZC01";
/**
* 称重位
*/
public final static String CZW_POINT = "CZW01";
/**
* 仓库ID
*/
public final static String STOR_ID = "1582991156504039424";
/**
* 库区:合格库区
*/
public final static String SECT_CODE_HG = "1955103578733547520";
/**
* 物料id焊丝盘状
*/
public final static String MATERIAL_HS_PZ = "19456870186461192161";
}

View File

@@ -31,41 +31,36 @@ public enum IOSEnum {
BILL_STATUS(MapOf.of("生成","10", "分配中", "20", "分配完", "30", "完成", "99")),
// 入库业务类型
IN_BILL_TYPE(MapOf.of("收货入库","0001", "退料入库","0002" , "合箱入库","0003"
,"拼箱入库", "0004" ,"拣选回库", "0005", "手工入库", "0009"
IN_BILL_TYPE(MapOf.of( "手工入库", "0009"
)),
// 出库业务类型
OUT_BILL_TYPE(MapOf.of("领料出库","1001", "质检出库","1002" , "退货出库","1003"
,"烘干出库", "1004" ,"手工出库", "1009"
OUT_BILL_TYPE(MapOf.of("手工出库", "1009"
)),
// 移库业务类型
MOVE_BILL_TYPE(MapOf.of("库内移库","2001", "合箱移库","2002", "拼箱移库","2003")),
MOVE_BILL_TYPE(MapOf.of("库内移库","2001")),
// 策略类型
STRATEGY_TYPE(MapOf.of("入库", "1", "出库", "2", "通用", "3")),
// 入库任务配置类编码
IN_CONFIG_CODE(MapOf.of("0001","DetainInTask", "0002", "BackInTask",
"0003", "CombinedBoxInTask", "0004", "PieceBoxInTask", "0005", "SelectBackInTask", "0009", "HandInTask"
IN_CONFIG_CODE(MapOf.of("0009", "HandInTask"
)),
// 出库任务配置类编码
OUT_CONFIG_CODE(MapOf.of("1001","ReceiveOutTask", "1002", "QualityOutTask",
"1003", "BackOutTask", "1004", "HotOutTask", "1009", "HandOutTask"
OUT_CONFIG_CODE(MapOf.of( "1009", "HandOutTask"
)),
// 移库任务配置类编码
MOVE_CONFIG_CODE(MapOf.of("2001","InsideMoveTask", "2002", "CombinedBoxMoveTask",
"2003", "PieceBoxMoveTask", "2004", "CheckMoveTask"
MOVE_CONFIG_CODE(MapOf.of("2001","InsideMoveTask", "2004", "CheckMoveTask"
)),
//入库分配明细状态
INBILL_DIS_STATUS(MapOf.of("未生成", "00", "生成", "01", "执行中", "02", "完成", "99")),
//组盘记录状态
GROUP_PLATE_STATUS(MapOf.of( "组盘", "1", "入库", "2", "出库", "3")),
//合箱记录状态
COMBINED_BOX_STATUS(MapOf.of( "生成", "1", "移库中", "2", "移库完成", "3", "入库中", "4", "完成", "5")),
GROUP_PLATE_STATUS(MapOf.of( "生成", "0","组盘", "1", "入库", "2", "出库", "3")),
// 锁类型
LOCK_TYPE(MapOf.of("未锁定", "0", "入库锁", "1", "出库锁", "2"
@@ -113,12 +108,6 @@ public enum IOSEnum {
// 盘点明细状态
CHECK_DTL_STATUS(MapOf.of("生成", "10", "移库中", "15", "盘点中", "20", "回库中", "30", "完成", "99")),
// 拼箱主表状态
PIECE_MST_STATUS(MapOf.of("生成", "10", "拼箱中", "20", "完成", "99")),
// 拼箱明细表状态
PIECE_DTL_STATUS(MapOf.of("生成", "10", "拼箱中", "20", "完成", "99")),
;
private Map<String, String> code;

View File

@@ -1,40 +0,0 @@
package org.nl.wms.warehouse_management.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.apache.ibatis.annotations.Param;
import org.nl.wms.warehouse_management.service.dao.StIvtPieceBoxDtl;
import org.nl.wms.warehouse_management.service.dto.PieceBoxDtlDto;
import org.nl.wms.warehouse_management.service.dto.PieceBoxMstDto;
import java.util.List;
/**
* <p>
* 拼单信息明细表 服务类
* </p>
*
* @author Liuxy
* @since 2025-08-26
*/
public interface IStIvtPieceBoxDtlService extends IService<StIvtPieceBoxDtl> {
/**
* 新增拼箱明细
* @param dto PieceBoxMstDto
*/
void insertDtl(PieceBoxMstDto dto);
/**
* 获取明细
* @param dto PieceBoxMstDto
* @return List<PieceBoxDtlDto>
*/
List<PieceBoxDtlDto> queryPieceDtl(PieceBoxMstDto dto);
/**
* 根据主表标识查询明细
* @param id 主表标识
* @return List<StIvtPieceBoxDtl>
*/
List<StIvtPieceBoxDtl> getByMstId(String id);
}

View File

@@ -51,6 +51,7 @@
SELECT
gp.*,
gp.qty AS plan_qty,
gp.vehicle_code AS storagevehicle_code,
mtl.material_id,
mtl.material_code,
mtl.material_name,
@@ -73,7 +74,7 @@
</if>
<if test="params.storagevehicle_code != null">
AND
gp.storagevehicle_code LIKE CONCAT('%', #{params.storagevehicle_code}, '%')
gp.vehicle_code LIKE CONCAT('%', #{params.storagevehicle_code}, '%')
</if>
<if test="params.begin_time != null">
AND
@@ -94,7 +95,7 @@
mb.material_name,
mb.material_spec,
mst.bill_code,
late.storagevehicle_code
late.vehicle_code
FROM
st_ivt_iostorinvdtl dtl
LEFT JOIN md_me_materialbase mb ON mb.material_id = dtl.material_id

View File

@@ -27,7 +27,6 @@
mater.material_name,
mater.material_spec,
mater.material_model,
mater.quality_time AS quality_time_day,
supp.supp_name
FROM
md_pb_groupplate late
@@ -48,7 +47,7 @@
<if test="param.storagevehicle_code != null and param.storagevehicle_code != ''">
AND
late.storagevehicle_code LIKE #{param.storagevehicle_code}
late.vehicle_code LIKE #{param.storagevehicle_code}
</if>
<if test="param.status != null and param.status != ''">

View File

@@ -21,10 +21,15 @@ import org.nl.config.IdUtil;
import org.nl.wms.basedata_manage.enums.BaseDataEnum;
import org.nl.wms.basedata_manage.service.IBsrealStorattrService;
import org.nl.wms.basedata_manage.service.IMdPbStoragevehicleextService;
import org.nl.wms.basedata_manage.service.ISectattrService;
import org.nl.wms.basedata_manage.service.IStructattrService;
import org.nl.wms.basedata_manage.service.dao.BsrealStorattr;
import org.nl.wms.basedata_manage.service.dao.Sectattr;
import org.nl.wms.basedata_manage.service.dao.mapper.MdPbStoragevehicleextMapper;
import org.nl.wms.basedata_manage.service.dto.MdPbStoragevehicleextDto;
import org.nl.wms.basedata_manage.service.dto.StrategyMater;
import org.nl.wms.basedata_manage.service.dto.StrategyStructMaterialVO;
import org.nl.wms.basedata_manage.service.dto.StrategyStructParam;
import org.nl.wms.sch_manage.enums.TaskStatus;
import org.nl.wms.sch_manage.service.ISchBaseTaskService;
import org.nl.wms.sch_manage.service.dao.SchBaseTask;
@@ -101,6 +106,12 @@ public class OutBillServiceImpl extends ServiceImpl<IOStorInvMapper, IOStorInv>
@Resource
private IBsrealStorattrService iBsrealStorattrService;
/**
* 库区服务
*/
@Resource
private ISectattrService iSectattrService;
/*
* 明细mapper
*/
@@ -392,33 +403,39 @@ public class OutBillServiceImpl extends ServiceImpl<IOStorInvMapper, IOStorInv>
throw new BadRequestException("当前订单无可分配出库明细");
}
if (ObjectUtil.isEmpty(whereJson.getString("sect_id"))) {
throw new BadRequestException("请选择分配库区");
}
// 查询库区
Sectattr sectDao = iSectattrService.getById(whereJson.getString("sect_id"));
for (int i = 0; i < dtls.size(); i++) {
IOStorInvDtlDto dtl = dtls.get(i);
double unassign_qty = dtl.getUnassign_qty().doubleValue();
String pcsn = dtl.getPcsn();
String material_id = dtl.getMaterial_id();
String sect_code = whereJson.getString("sect_id");
// 如果为空则只查询合格区
if (ObjectUtil.isEmpty(sect_code)) {
sect_code = IOSConstant.SECT_CODE_HG;
}
BigDecimal canuseSum = mdPbStoragevehicleextMapper.queryCanuseSum(pcsn, material_id, sect_code);
BigDecimal canuseSum = mdPbStoragevehicleextMapper.queryCanuseSum(pcsn, material_id, sectDao.getSect_id());
if (ObjectUtil.isEmpty(canuseSum) || canuseSum.doubleValue() < unassign_qty) {
throw new BadRequestException("物料编号:" + dtl.getMaterial_code() + "出库分配数量不满足");
}
/*
* 分配规则:
* 1.优先保质期到期的先出
* 2.按批次先进先出
* 3.相同批次载具量小优先
*/
//出库分配查询货位信息
List<MdPbStoragevehicleextDto> outAllocationList = mdPbStoragevehicleextMapper.queryOutAllocation(pcsn, material_id, sect_code);
// 调用出库分配规则
StrategyMater mater = new StrategyMater();
mater.setQty(BigDecimal.valueOf(unassign_qty));
mater.setPcsn(pcsn);
mater.setMaterial_id(material_id);
List<StrategyMater> list = new ArrayList<>();
list.add(mater);
List<MdPbStoragevehicleextDto> outAllocationList = iStructattrService.outBoundSectDiv(
StrategyStructParam.builder()
.stor_code(ioStorInv.getStor_code())
.sect_id(sectDao.getSect_id())
.sect_code(sectDao.getSect_code())
.strategyMaters(list)
.build()
);
int seq_no = 1;
double allocation_canuse_qty = 0;
@@ -618,32 +635,39 @@ public class OutBillServiceImpl extends ServiceImpl<IOStorInvMapper, IOStorInv>
throw new BadRequestException("当前订单无可分配出库明细");
}
if (ObjectUtil.isEmpty(whereJson.getString("sect_id"))) {
throw new BadRequestException("请选择分配库区");
}
// 查询库区
Sectattr sectDao = iSectattrService.getById(whereJson.getString("sect_id"));
for (int i = 0; i < dtls.size(); i++) {
IOStorInvDtlDto dtl = dtls.get(i);
double unassign_qty = dtl.getUnassign_qty().doubleValue();
String pcsn = dtl.getPcsn();
String material_id = dtl.getMaterial_id();
// 根据物料和批次号查询库存可用
String sect_code = whereJson.getString("sect_id");
// 如果为空则只查询合格区
if (ObjectUtil.isEmpty(sect_code)) {
sect_code = IOSConstant.SECT_CODE_HG;
}
BigDecimal canuseSum = mdPbStoragevehicleextMapper.queryCanuseSum(pcsn, material_id, sect_code);
BigDecimal canuseSum = mdPbStoragevehicleextMapper.queryCanuseSum(pcsn, material_id, sectDao.getSect_id());
if (canuseSum.doubleValue() < unassign_qty) {
if (ObjectUtil.isEmpty(canuseSum) || canuseSum.doubleValue() < unassign_qty) {
throw new BadRequestException("物料编号:" + dtl.getMaterial_code() + "出库分配数量不满足");
}
/*
* 分配规则:
* 1.按批次先进先出
* 2.相同批次载具量小优先
*/
//出库分配查询货位信息
List<MdPbStoragevehicleextDto> outAllocationList = mdPbStoragevehicleextMapper.queryOutAllocation(pcsn, material_id, sect_code);
// 调用出库分配规则
StrategyMater mater = new StrategyMater();
mater.setQty(BigDecimal.valueOf(unassign_qty));
mater.setPcsn(pcsn);
mater.setMaterial_id(material_id);
List<StrategyMater> list = new ArrayList<>();
list.add(mater);
List<MdPbStoragevehicleextDto> outAllocationList = iStructattrService.outBoundSectDiv(
StrategyStructParam.builder()
.stor_code(ioStorInv.getStor_code())
.sect_id(sectDao.getSect_id())
.sect_code(sectDao.getSect_code())
.strategyMaters(list)
.build()
);
int seq_no = 1;
double allocation_canuse_qty = 0;

View File

@@ -21,11 +21,15 @@ import org.nl.common.utils.SecurityUtils;
import org.nl.wms.basedata_manage.enums.BaseDataEnum;
import org.nl.wms.basedata_manage.service.IBsrealStorattrService;
import org.nl.wms.basedata_manage.service.IMdPbStoragevehicleextService;
import org.nl.wms.basedata_manage.service.ISectattrService;
import org.nl.wms.basedata_manage.service.IStructattrService;
import org.nl.wms.basedata_manage.service.dao.BsrealStorattr;
import org.nl.wms.basedata_manage.service.dao.MdPbStoragevehicleinfo;
import org.nl.wms.basedata_manage.service.dao.Sectattr;
import org.nl.wms.basedata_manage.service.dao.Structattr;
import org.nl.wms.basedata_manage.service.dao.mapper.MdPbStoragevehicleinfoMapper;
import org.nl.wms.basedata_manage.service.dto.StrategyMater;
import org.nl.wms.basedata_manage.service.dto.StrategyStructParam;
import org.nl.wms.sch_manage.enums.TaskStatus;
import org.nl.wms.sch_manage.service.ISchBaseTaskService;
import org.nl.wms.sch_manage.service.dao.SchBaseTask;
@@ -76,6 +80,12 @@ public class RawAssistIStorServiceImpl extends ServiceImpl<IOStorInvMapper, IOSt
@Resource
private IStructattrService iStructattrService;
/**
* 库区服务
*/
@Resource
private ISectattrService iSectattrService;
/**
* 明细mapper
*/
@@ -389,8 +399,24 @@ public class RawAssistIStorServiceImpl extends ServiceImpl<IOStorInvMapper, IOSt
JSONObject jo_form = new JSONObject();
Structattr struct = new Structattr();
if (whereJson.containsKey("sect_id")) {
jo_form.put("sect_id", whereJson.get("sect_id"));
// 查询库区
Sectattr sectDao = iSectattrService.getById(MapUtil.getStr(whereJson, "sect_id"));
// 查询仓库
BsrealStorattr storDao = iBsrealStorattrService.getById(sectDao.getStor_id());
// 组织物料数据
StrategyMater strategyDao = new StrategyMater();
strategyDao.setMaterial_id(ioStorInvDis.getMaterial_id());
strategyDao.setPcsn(ioStorInvDis.getPcsn());
strategyDao.setQty(ioStorInvDis.getPlan_qty());
strategyDao.setQty_unit_id(ioStorInvDis.getQty_unit_id());
List<StrategyMater> strategyDaoList = new ArrayList<>();
strategyDaoList.add(strategyDao);
jo_form.put("sect_code", sectDao.getSect_code());
jo_form.put("stor_code",storDao.getStor_code());
jo_form.put("storagevehicle_code", map.get("storagevehicle_code"));
jo_form.put("strategyMaters", strategyDaoList);
// 调用自动分配
struct = this.autoDis(jo_form);
} else {
throw new BadRequestException("请选择需要分配的库区!");
@@ -764,16 +790,14 @@ public class RawAssistIStorServiceImpl extends ServiceImpl<IOStorInvMapper, IOSt
throw new BadRequestException("该载具已在库内【" + mdPbStoragevehicleinfo.getStoragevehicle_code() + "");
}
// 根据库区查询对应库位
List<Structattr> list = iStructattrService.list(new LambdaQueryWrapper<>(Structattr.class)
.eq(Structattr::getSect_id, whereJson.getString("sect_id"))
.eq(Structattr::getLock_type, IOSEnum.LOCK_TYPE.code("未锁定"))
.eq(Structattr::getIs_delete, IOSConstant.IS_DELETE_NO)
.eq(Structattr::getIs_used, IOSConstant.IS_DELETE_YES)
.and(wrapper -> wrapper.isNull(Structattr::getStoragevehicle_code).or().eq(Structattr::getStoragevehicle_code, ""))
.orderByAsc(Structattr::getPlacement_type)
.orderByAsc(Structattr::getStruct_code)
);
// 调用入库策略
List<Structattr> list = iStructattrService.inBoundSectDiv(
StrategyStructParam.builder()
.sect_code(whereJson.getString("sect_code"))
.stor_code(whereJson.getString("stor_code"))
.storagevehicle_code(whereJson.getString("storagevehicle_code"))
.strategyMaters(whereJson.getJSONArray("strategyMaters").toJavaList(StrategyMater.class))
.build());
if (ObjectUtil.isEmpty(list)) {
throw new BadRequestException("未找到满足的仓位");

View File

@@ -185,7 +185,8 @@ public class StIvtCheckmstServiceImpl extends ServiceImpl<StIvtCheckmstMapper, S
// 生成回库任务
JSONObject jsonTask = new JSONObject();
jsonTask.put("point_code1", IOSConstant.CZW_POINT);
// 实际盘点位
jsonTask.put("point_code1", "");
jsonTask.put("point_code2", dtlDao.getStruct_code());
jsonTask.put("vehicle_code", dtlDao.getStoragevehicle_code());
jsonTask.put("contact_task", dtlDao.getTask_id());
@@ -301,7 +302,8 @@ public class StIvtCheckmstServiceImpl extends ServiceImpl<StIvtCheckmstMapper, S
JSONObject jsonTask = new JSONObject();
jsonTask.put("point_code1", dtlDao.getStruct_code());
jsonTask.put("point_code2", IOSConstant.CZW_POINT);
// 实际盘点位
jsonTask.put("point_code2", "");
jsonTask.put("vehicle_code", dtlDao.getStoragevehicle_code());
String task_id = checkMoveTask.create(jsonTask);

View File

@@ -1,86 +0,0 @@
package org.nl.wms.warehouse_management.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.nl.common.exception.BadRequestException;
import org.nl.common.utils.IdUtil;
import org.nl.wms.basedata_manage.service.IStructattrService;
import org.nl.wms.basedata_manage.service.dao.Structattr;
import org.nl.wms.warehouse_management.enums.IOSEnum;
import org.nl.wms.warehouse_management.service.IStIvtPieceBoxDtlService;
import org.nl.wms.warehouse_management.service.dao.StIvtPieceBoxDtl;
import org.nl.wms.warehouse_management.service.dao.mapper.StIvtPieceBoxDtlMapper;
import org.nl.wms.warehouse_management.service.dto.PieceBoxDtlDto;
import org.nl.wms.warehouse_management.service.dto.PieceBoxMstDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
* 拼单信息明细表 服务实现类
* </p>
*
* @author Liuxy
* @since 2025-08-26
*/
@Service
public class StIvtPieceBoxDtlServiceImpl extends ServiceImpl<StIvtPieceBoxDtlMapper, StIvtPieceBoxDtl> implements IStIvtPieceBoxDtlService {
/**
* 仓位服务
*/
@Autowired
private IStructattrService iStructattrService;
@Override
public void insertDtl(PieceBoxMstDto dto) {
List<JSONObject> tableData = dto.getTableData();
// 校验库区是否一致
List<Structattr> attrList = iStructattrService.list(
new QueryWrapper<Structattr>().lambda()
.in(Structattr::getStruct_code, tableData.stream()
.map(row -> row.getString("struct_code"))
.collect(Collectors.toList())
)
);
boolean is_like = attrList.stream()
.allMatch(row -> row.getSect_code().equals(attrList.get(0).getSect_code()));
if (!is_like) {
throw new BadRequestException("拼箱库区不一致,不允许拼箱!");
}
// 需插入的明细记录
List<StIvtPieceBoxDtl> dtlList = new ArrayList<>();
for (JSONObject json : tableData) {
StIvtPieceBoxDtl dtlDao = new StIvtPieceBoxDtl();
dtlDao.setId(IdUtil.getStringId());
dtlDao.setPiece_id(dto.getId());
dtlDao.setMaterial_id(json.getString("material_id"));
dtlDao.setPcsn(json.getString("pcsn"));
dtlDao.setVehicle_code(json.getString("storagevehicle_code"));
dtlDao.setQty(json.getBigDecimal("qty"));
dtlDao.setStruct_code(json.getString("struct_code"));
dtlDao.setBill_status(IOSEnum.PIECE_DTL_STATUS.code("生成"));
dtlList.add(dtlDao);
}
this.saveBatch(dtlList);
}
@Override
public List<PieceBoxDtlDto> queryPieceDtl(PieceBoxMstDto dto) {
return this.baseMapper.queryPieceDtl(dto);
}
@Override
public List<StIvtPieceBoxDtl> getByMstId(String id) {
return this.list(
new QueryWrapper<StIvtPieceBoxDtl>().lambda()
.eq(StIvtPieceBoxDtl::getPiece_id, id)
);
}
}

View File

@@ -79,7 +79,7 @@ public class VehicleOutServiceImpl implements VehicleOutService {
// 创建任务
JSONObject jsonTask = new JSONObject();
jsonTask.put("point_code1", structattr.getStruct_code());
jsonTask.put("point_code2", IOSConstant.CZW_POINT);
jsonTask.put("point_code2", whereJson.getString("point_code"));
jsonTask.put("vehicle_code", structattr.getStoragevehicle_code());
String task_id = empVehicleOutTask.create(jsonTask);
}

View File

@@ -8,12 +8,12 @@ nl:
# port: 3306
# username: root
# password: root
# database: wms_base
# database: huadongyiyao_wms
ip: 192.168.81.251
port: 3306
username: root
password: P@ssw0rd.
database: wms2.0
database: huadongyiyao_wms
redis:
ip: 127.0.0.1
port: 6379

View File

@@ -32,8 +32,8 @@
<el-row>
<el-col :span="8">
<el-form-item label="载具编码" prop="storagevehicle_code">
<el-input v-model="formMst.storagevehicle_code" style="width: 200px;" />
<el-form-item label="载具编码" prop="vehicle_code">
<el-input v-model="formMst.vehicle_code" style="width: 200px;" />
</el-form-item>
</el-col>
@@ -187,7 +187,7 @@ export default {
handler(newValue, oldValue) {
this.dialogVisible = newValue
this.formMst = this.openParam
this.formMst.storagevehicle_code = ''
this.formMst.vehicle_code = ''
this.formMst.pcsn = null
this.formMst.qty = 1
}
@@ -197,7 +197,7 @@ export default {
return {
formMst: {
group_id: null,
storagevehicle_code: null,
vehicle_code: null,
material_id: null,
pcsn: null,
qty_unit_id: null,
@@ -225,7 +225,7 @@ export default {
material_code: [
{ required: true, message: '物料不能为空', trigger: 'blur' }
],
storagevehicle_code: [
vehicle_code: [
{ required: true, message: '载具不能为空', trigger: 'blur' }
],
supp_code: [
@@ -263,7 +263,7 @@ export default {
})
},
copySave() {
if (this.formMst.storagevehicle_code === '') {
if (this.formMst.vehicle_code === '') {
this.crud.notify('载具不能为空!', CRUD.NOTIFICATION_TYPE.INFO)
return
}

View File

@@ -112,8 +112,8 @@
<el-row>
<el-col :span="8">
<el-form-item label="载具编码" prop="storagevehicle_code">
<el-input v-model="form.storagevehicle_code" :disabled="crud.status.edit > 0" @change="checkVehicle" style="width: 200px;" />
<el-form-item label="载具编码" prop="vehicle_code">
<el-input v-model="form.vehicle_code" :disabled="crud.status.edit > 0" @change="checkVehicle" style="width: 200px;" />
</el-form-item>
</el-col>
@@ -232,7 +232,7 @@
@selection-change="crud.selectionChangeHandler"
>
<el-table-column type="selection" width="55" />
<el-table-column prop="storagevehicle_code" label="载具编码" :min-width="flexWidth('storagevehicle_code',crud.data,'载具编码')" />
<el-table-column prop="vehicle_code" label="载具编码" :min-width="flexWidth('vehicle_code',crud.data,'载具编码')" />
<el-table-column prop="material_code" label="物料编码" :min-width="flexWidth('material_code',crud.data,'物料编码')" />
<el-table-column prop="material_name" label="物料名称" :min-width="flexWidth('material_name',crud.data,'物料名称')" />
<el-table-column prop="material_spec" label="物料规格" :min-width="flexWidth('material_spec',crud.data,'物料规格')" />
@@ -240,12 +240,6 @@
<el-table-column prop="status" label="状态" :formatter="formattStatus" :min-width="flexWidth('status',crud.data,'状态')" />
<el-table-column prop="qty" label="组盘重量" :formatter="crud.formatNum3" :min-width="100" />
<el-table-column prop="supp_code" label="供应商" :min-width="flexWidth('supp_code',crud.data,'供应商')" />
<el-table-column prop="quality_time" label="有效日期" :min-width="flexWidth('quality_time',crud.data,'有效日期')" />
<el-table-column prop="produce_time" label="生产日期" :min-width="flexWidth('produce_time',crud.data,'生产日期')" />
<el-table-column prop="bake_num" label="烘干次数" :min-width="flexWidth('bake_num',crud.data,'烘干次数')" />
<el-table-column prop="quality_type" label="品质类型" :formatter="formattQuality" :min-width="flexWidth('quality_type',crud.data,'品质类型')" />
<el-table-column prop="box_type" label="料箱类型" :formatter="formattBoxType" :min-width="flexWidth('box_type',crud.data,'料箱类型')" />
<el-table-column prop="execution_stand" label="执行标准" :min-width="flexWidth('execution_stand',crud.data,'执行标准')" />
<el-table-column prop="remark" label="备注" :min-width="flexWidth('remark',crud.data,'备注')" />
<el-table-column prop="create_name" label="组盘人" :min-width="flexWidth('create_name',crud.data,'组盘人')" />
<el-table-column prop="create_time" label="组盘时间" :min-width="flexWidth('create_time',crud.data,'组盘时间')" />
@@ -285,7 +279,7 @@ import { getLodop } from '@/assets/js/lodop/LodopFuncs'
const defaultForm = {
group_id: null,
storagevehicle_code: null,
vehicle_code: null,
material_id: null,
pcsn: null,
qty_unit_id: null,
@@ -338,7 +332,7 @@ export default {
material_code: [
{ required: true, message: '物料不能为空', trigger: 'blur' }
],
storagevehicle_code: [
vehicle_code: [
{ required: true, message: '载具不能为空', trigger: 'blur' }
],
pcsn: [
@@ -379,9 +373,9 @@ export default {
})
},
checkVehicle(value) {
crudGroup.checkVehicle({ 'storagevehicle_code': value }).then(row => {
crudGroup.checkVehicle({ 'vehicle_code': value }).then(row => {
}).catch(() => {
this.form.storagevehicle_code = ''
this.form.vehicle_code = ''
})
},
formattStatus(row) {

View File

@@ -45,7 +45,7 @@
</el-table-column>
<el-table-column prop="strategy_name" label="策略名称" />
<el-table-column prop="strategy_code" label="策略编码" />
<el-table-column prop="strategy_type" label="决策类型" />
<el-table-column prop="strategy_type" label="决策类型" :formatter="strateyType" />
<el-table-column prop="class_type" label="策略执行器" />
<el-table-column prop="param" show-overflow-tooltip label="参数" />
<el-table-column prop="remark" show-overflow-tooltip label="描述" />
@@ -95,7 +95,7 @@ import pagination from '@crud/Pagination'
export default {
name: 'Strategy',
dicts: [],
dicts: ['STRATEGY_TYPE'],
components: { pagination, crudOperation, rrOperation, udOperation, AddDialog },
mixins: [presenter(), header(), crud()],
cruds() {
@@ -130,6 +130,9 @@ export default {
format_is_used(is_used) {
return is_used==true
},
strateyType(row) {
return this.dict.label.STRATEGY_TYPE[row.strategy_type]
},
changeEnabled(data, val) {
let msg = '此操作将停用,是否继续!'
if (val !== '1') {

View File

@@ -52,7 +52,7 @@
@selection-change="crud.selectionChangeHandler"
>
<el-table-column type="selection" width="55" />
<el-table-column show-overflow-tooltip width="150" prop="storagevehicle_code" label="载具编码" />
<el-table-column show-overflow-tooltip width="150" prop="vehicle_code" label="载具编码" />
<el-table-column show-overflow-tooltip width="150" prop="material_code" label="物料编码" />
<el-table-column show-overflow-tooltip width="150" prop="material_name" label="物料名称" />
<el-table-column show-overflow-tooltip width="150" prop="material_spec" label="物料规格" />
@@ -60,9 +60,6 @@
<el-table-column show-overflow-tooltip width="170" prop="qty" label="数量" />
<el-table-column show-overflow-tooltip width="170" prop="qty_unit_name" label="计量单位名称" />
<el-table-column show-overflow-tooltip width="170" prop="supp_name" label="供应商" />
<el-table-column show-overflow-tooltip width="170" prop="produce_time" label="生产日期" />
<el-table-column show-overflow-tooltip width="100" prop="bake_num" label="烘干次数" />
<el-table-column show-overflow-tooltip width="150" prop="box_type" label="料箱类型" :formatter="formattBoxType"/>
</el-table>
<!--分页组件-->
<pagination />
@@ -88,7 +85,7 @@ const start = new Date()
export default {
name: 'AddDtl',
components: { crudOperation, rrOperation, pagination, DateRangePicker },
dicts: ['BOX_TYPE'],
dicts: [],
cruds() {
return CRUD({
title: '用户',
@@ -149,9 +146,6 @@ export default {
close() {
this.$emit('update:dialogShow', false)
},
formattBoxType(row) {
return this.dict.label.BOX_TYPE[row.box_type]
},
submit() {
this.$emit('update:dialogShow', false)
this.rows = this.$refs.multipleTable.selection

View File

@@ -120,7 +120,7 @@
>
添加库内库存
</el-button>
<el-button
<!--<el-button
slot="left"
class="filter-item"
type="primary"
@@ -129,7 +129,7 @@
@click="queryDtlIos()"
>
添加生产工单
</el-button>
</el-button>-->
</span>
</div>
@@ -163,7 +163,7 @@
</template>
</el-table-column>
<el-table-column prop="qty_unit_name" label="单位" align="center" />
<el-table-column prop="source_bill_code" label="来源单据号" align="center" min-width="150px" show-overflow-tooltip />
<!-- <el-table-column prop="source_bill_code" label="来源单据号" align="center" min-width="150px" show-overflow-tooltip />-->
<el-table-column show-overflow-tooltip prop="remark" label="明细备注" align="center">
<template scope="scope">
<el-input v-model="scope.row.remark" size="mini" />
@@ -178,7 +178,6 @@
</el-table>
<AddDtl :dialog-show.sync="dtlShow" :stor-id="storId" @tableChanged="tableChanged" />
<AddDtlIos :dialog-show.sync="dtlIosShow" :bom-type="bom_type" @tableChanged="tableChanged2" />
</el-dialog>
</template>

View File

@@ -94,9 +94,6 @@
<el-table-column prop="canuse_qty" label="可用数" :formatter="crud.formatNum3" :min-width="100" />
<el-table-column prop="frozen_qty" label="冻结数" :formatter="crud.formatNum3" :min-width="100" />
<el-table-column prop="qty_unit_name" label="计量单位" :min-width="flexWidth('qty_unit_name',crud.data,'计量单位')" />
<el-table-column prop="produce_time" label="生产日期" :min-width="flexWidth('produce_time',crud.data,'生产日期')" />
<el-table-column prop="quality_time" label="有效日期" :min-width="flexWidth('quality_time',crud.data,'有效日期')" />
<el-table-column prop="bake_num" label="烘干次数" :min-width="flexWidth('bake_num',crud.data,'烘干次数')" />
<el-table-column prop="remark" label="备注" :min-width="flexWidth('remark',crud.data,'备注')" />
<el-table-column prop="insert_time" label="入库时间" :min-width="flexWidth('insert_time',crud.data,'入库时间')" />
</el-table>