入库条码打印修改 生成入库作业 手动完成入库作业

This commit is contained in:
liuhanqing
2025-09-16 15:22:58 +08:00
parent 5049b8e79f
commit 7a87a99e05
11 changed files with 173 additions and 192 deletions

View File

@@ -9,5 +9,6 @@ import lombok.NoArgsConstructor;
@NoArgsConstructor
public class RequestEnter {
private String trayCode;
private String spec;
private String size;
private String entranceId;
}

View File

@@ -3,6 +3,7 @@ package com.ruoyi.api.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.api.domain.ReMaterialParam;
import com.ruoyi.api.domain.RequestEnter;
@@ -20,6 +21,7 @@ import com.ruoyi.bas.container.service.IBasContainerService;
import com.ruoyi.bas.tag.domain.BasTag;
import com.ruoyi.bas.tag.service.IBasTagService;
import com.ruoyi.bas.taskNo.service.IBasTaskNoService;
import com.ruoyi.bas.warehouse.domain.BasWarehouse;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.SecurityUtils;
@@ -40,6 +42,7 @@ import com.ruoyi.out.tagTask.service.ITagTaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
@@ -77,6 +80,7 @@ public class ToWmsServiceImpl implements IToWmsService {
@Override
@Transactional(rollbackFor = Exception.class)
public AjaxResult requestEnterByTrayCode(RequestEnter requestEnter) {
if (StrUtil.isEmpty(requestEnter.getTrayCode())) {
return AjaxResult.error("托盘条码不能为空");
@@ -92,36 +96,88 @@ public class ToWmsServiceImpl implements IToWmsService {
String v = split[3].substring(2);
String hz = split[4].substring(3);
String ph = split[5].substring(3);
String nw = split[6].substring(5);
String gw = split[7].substring(5);
String bm = split[8].substring(2, split[8].length() - 1);
String[] decode = ProcodeUtils.decode(bm);
String nw = split[6].substring(5, split[6].length() - 2);
String gw = split[7].substring(5, split[7].length() - 2);
String productId = split[8].substring(10);
String bm = split[9].substring(2, split[9].length() - 1);
String[] decode = ProcodeUtils.decode(bm);
String erpBill = decode[0];
String xh = decode[1];
String jx = decode[2];
String fx = decode[3];
String xlh = decode[4];
log.info("二维码详情 model:{},color:{},serial:{},v:{},hz:{},ph:{},nw:{},gw:{},erpBill:{},xh:{},jx:{},fx:{},xlh:{}", model, color, serial, v, hz, ph, nw, gw,erpBill, xh, jx, fx, xlh);
log.info("二维码详情 productId:{} model:{},color:{},serial:{},v:{},hz:{},ph:{},nw:{},gw:{},erpBill:{},xh:{},jx:{},fx:{},xlh:{}",productId, model, color, serial, v, hz, ph, nw, gw, erpBill, xh, jx, fx, xlh);
BasProduct basProductParam = new BasProduct();
basProductParam.setSpare4(xlh);
basProductParam.setProductId(productId);
List<BasProduct> basProducts = basProductService.selectBasProductList(basProductParam);
if (CollUtil.isEmpty(basProducts)) {
return AjaxResult.error("物料信息不存在");
}
BasProduct basProduct = basProducts.get(0);
if (!basProduct.getSpec().equals(requestEnter.getSpec())){
/*if (!basProduct.getSpec().equals(requestEnter.getSize())) {
return AjaxResult.error("规格不一致");
}
}*/
//生成作业
MydoJob mydoJob = new MydoJob();
mydoJob.setJobId(basJobIdService.getJobId("RK"));
mydoJob.setStatus("1");
mydoJob.setTaskNo(Convert.toStr(basTaskNoService.getTaskNo("1")));
mydoJob.setDepartmentId(Convert.toStr(SecurityUtils.getDeptId()));
mydoJob.setTrayCode(requestEnter.getTrayCode());
//mydoJob.setDepartmentId(Convert.toStr(SecurityUtils.getDeptId()));
mydoJob.setInOrOut("1");
mydoJob.setExecutionPhase("1");
mydoJob.setTrayCode(basJobIdService.getJobId("TP"));
mydoJob.setWarehouseId("01");
BasCargoSpace basCargoSpaceParam = new BasCargoSpace();
//todo 根据包装方式 主要包装方式 描述 长 宽 高 包装材积 判断巷道1 还是巷道2
switch (requestEnter.getSize()) {
case "1":
mydoJob.setRoadwayId("1");
break;
case "2":
mydoJob.setRoadwayId("2");
break;
case "4":
break;
default:
return AjaxResult.error("规格不存在");
}
//根据巷道查找货位
basCargoSpaceParam.setWarehouseId(mydoJob.getWarehouseId());
basCargoSpaceParam.setRoadwayId(mydoJob.getRoadwayId());
BasCargoSpace basCargoSpace = basCargoSpaceService.selectEmptyCargoSpaceByWarehouseId(basCargoSpaceParam);
if (ObjUtil.isNull(basCargoSpace)) {
return AjaxResult.error("没有货位");
}
mydoJob.setCargoSpaceId(basCargoSpace.getCargoSpaceId());
mydoJob.setEntranceId(requestEnter.getEntranceId());
mydoJobService.insertMydoJob(mydoJob);
//生成子作业
MydoJobDetail mydoJobDetail = new MydoJobDetail();
mydoJobDetail.setJobDetailId(mydoJob.getJobId() + "-1");
mydoJobDetail.setJobId(mydoJob.getJobId());
mydoJobDetail.setCreateTime(new Date());
mydoJobDetail.setProductGuid(basProduct.getProductGuid());
mydoJobDetail.setProductId(basProduct.getProductId());
mydoJobDetail.setInQuantity("1");
mydoJobDetail.setSpare1(xh);
mydoJobDetail.setSpare2(nw);
mydoJobDetail.setSpare3(color);
mydoJobDetail.setSpare4(xlh);
mydoJobDetail.setSpare5(v);
mydoJobDetail.setSpare6(hz);
mydoJobDetail.setSpare7(ph);
mydoJobDetail.setSpare8(gw);
mydoJobDetail.setSpare9(fx);
mydoJobDetail.setUnit(jx);
mydoJobDetail.setSpec(basProduct.getSpec());
mydoJobDetailService.insertMydoJobDetail(mydoJobDetail);
//修改货位状态
basCargoSpace.setStatus("3");
basCargoSpaceService.updateBasCargoSpace(basCargoSpace);
return AjaxResult.success();
}
@@ -246,7 +302,10 @@ public class ToWmsServiceImpl implements IToWmsService {
//重新分配货位
MydoJob mydoJob = mydoJobService.selectMydoJobByJobId(reMaterialParam.getJobId());
String warehouseId = mydoJob.getWarehouseId();
BasCargoSpace basCargoSpace = basCargoSpaceService.selectEmptyCargoSpaceByWarehouseId(warehouseId);
BasCargoSpace basCargoSpaceParam = new BasCargoSpace();
basCargoSpaceParam.setWarehouseId(warehouseId);
basCargoSpaceParam.setRoadwayId(mydoJob.getRoadwayId());
BasCargoSpace basCargoSpace = basCargoSpaceService.selectEmptyCargoSpaceByWarehouseId(basCargoSpaceParam);
if (basCargoSpace == null) {
log.error("没有空货位");
return AjaxResult.error(MessageUtils.message("error.message20"));

View File

@@ -2,6 +2,7 @@ package com.ruoyi.bas.cargoSpace.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.bas.cargoSpace.domain.BasCargoSpace;
import com.ruoyi.bas.warehouse.domain.BasWarehouse;
import java.util.List;
import java.util.Map;
@@ -74,5 +75,5 @@ public interface BasCargoSpaceMapper extends BaseMapper<BasCargoSpace>
* @param warehouseId
* @return
*/
BasCargoSpace selectEmptyCargoSpaceByWarehouseId(String warehouseId);
BasCargoSpace selectEmptyCargoSpaceByWarehouseId(BasCargoSpace basWarehouse);
}

View File

@@ -2,6 +2,7 @@ package com.ruoyi.bas.cargoSpace.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.bas.cargoSpace.domain.BasCargoSpace;
import com.ruoyi.bas.warehouse.domain.BasWarehouse;
import java.util.List;
@@ -66,5 +67,5 @@ public interface IBasCargoSpaceService extends IService<BasCargoSpace>
* @param warehouseId
* @return
*/
BasCargoSpace selectEmptyCargoSpaceByWarehouseId(String warehouseId);
BasCargoSpace selectEmptyCargoSpaceByWarehouseId(BasCargoSpace basWarehouse);
}

View File

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.bas.cargoSpace.domain.BasCargoSpace;
import com.ruoyi.bas.cargoSpace.mapper.BasCargoSpaceMapper;
import com.ruoyi.bas.cargoSpace.service.IBasCargoSpaceService;
import com.ruoyi.bas.warehouse.domain.BasWarehouse;
import com.ruoyi.common.annotation.DataScope;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
@@ -96,8 +97,8 @@ public class BasCargoSpaceServiceImpl extends ServiceImpl<BasCargoSpaceMapper,Ba
}
@Override
public BasCargoSpace selectEmptyCargoSpaceByWarehouseId(String warehouseId) {
return basCargoSpaceMapper.selectEmptyCargoSpaceByWarehouseId(warehouseId);
public BasCargoSpace selectEmptyCargoSpaceByWarehouseId(BasCargoSpace basWarehouse) {
return basCargoSpaceMapper.selectEmptyCargoSpaceByWarehouseId(basWarehouse);
}

View File

@@ -206,9 +206,9 @@ public class MydoJobServiceImpl implements IMydoJobService {
}
//通知wcs
AjaxResult ajaxResult = iToWcsService.cancelTaskByTaskNo(job.getTaskNo());
if (ajaxResult.isSuccess()){
if (ajaxResult.isSuccess()) {
return AjaxResult.success();
}else {
} else {
throw new RuntimeException(Convert.toStr(ajaxResult.get("msg")));
}
}
@@ -230,176 +230,61 @@ public class MydoJobServiceImpl implements IMydoJobService {
*/
@Override
@Transactional(rollbackFor = Exception.class)
public AjaxResult manualCompleted(MydoJob mydoJob,int type) {
public AjaxResult manualCompleted(MydoJob mydoJob, int type) {
String jobId = mydoJob.getJobId();
MydoJob job = selectMydoJobByJobId(jobId);
if (job == null) {
return AjaxResult.warn(MessageUtils.message("warn.message"));
return AjaxResult.warn("任务不存在");
}
if (type == 0){
AjaxResult ajaxResult = iToWcsService.cancelTaskByTaskNo(job.getTaskNo());
if (type == 0) {
//todo 取消堆垛机任务 或者 agv任务
/*AjaxResult ajaxResult = iToWcsService.cancelTaskByTaskNo(job.getTaskNo());
if (!ajaxResult.isSuccess()){
return AjaxResult.error(MessageUtils.message("error.message17"));
}
return AjaxResult.error("");
}*/
}
BasWarehouse basWarehouse = basWarehouseService.selectBasWarehouseByWarehouseId(job.getWarehouseId());
if("2".equals(basWarehouse.getWarehouseType())) {
if ("1".equals(job.getStatus()) || "2".equals(job.getStatus())) {
return AjaxResult.warn(MessageUtils.message("warn.message13"));
}
}
if ("1".equals(job.getInOrOut()) || "4".equals(job.getInOrOut())) {
//空料箱入库 托盘垛入库
//入库作业
MydoJobDetail param = new MydoJobDetail();
param.setJobId(jobId);
List<MydoJobDetail> mydoJobDetails = mydoJobDetailService.selectMydoJobDetailList(param);
BasCargoSpace basCargoSpace = basCargoSpaceService.selectBasCargoSpaceByCargoSpaceId(job.getCargoSpaceId());
if (CollUtil.isNotEmpty(mydoJobDetails)) {
List<BasStock> list = new ArrayList<>();
for (MydoJobDetail mydoJobDetail : mydoJobDetails) {
//正常库存
list.add(getStockByInStockinDetail(mydoJobDetail, job, "1"));
//入库任务
MydoJobDetail param = new MydoJobDetail();
param.setJobId(jobId);
List<MydoJobDetail> mydoJobDetails = mydoJobDetailService.selectMydoJobDetailList(param);
BasCargoSpace basCargoSpace = basCargoSpaceService.selectBasCargoSpaceByCargoSpaceId(job.getCargoSpaceId());
if (CollUtil.isNotEmpty(mydoJobDetails)) {
List<BasStock> list = new ArrayList<>();
for (MydoJobDetail mydoJobDetail : mydoJobDetails) {
if ("2".equals(mydoJob.getInOrOut()) || "3".equals(mydoJob.getInOrOut())) {
//修改单据实际数量 2-退料入库 3-其它入库
String inOrOutDId = mydoJobDetail.getInOrOutDId();
InStockinDetail inStockinDetail = inStockinDetailService.selectInStockinDetailByStockinDetailId(inOrOutDId);
inStockinDetail.setAssignNum(Convert.toStr(Convert.toBigDecimal(inStockinDetail.getAssignNum()).add(Convert.toBigDecimal(mydoJobDetail.getInQuantity()))));
inStockinDetailService.updateInStockinDetail(inStockinDetail);
}
//修改货位状态
basCargoSpace.setStatus("2");
basCargoSpace.setTrayCode(job.getTrayCode());
basCargoSpace.setCargoSpaceId(job.getCargoSpaceId());
basCargoSpaceService.updateBasCargoSpace(basCargoSpace);
//插入库存信息
basStockService.insertBasStockList(list);
//结束任务
mydoJob.setStatus("4");
mydoJob.setFinishTime(DateUtil.formatDateTime(DateUtil.date()));
updateMydoJob(mydoJob);
// 插入任务历史表 删除任务
insertHistory(mydoJob.getJobId());
return AjaxResult.success();
} else {
return AjaxResult.warn(MessageUtils.message("warn.message2"));
//正常库存
list.add(getStockByInStockinDetail(mydoJobDetail, job, "1"));
}
} else if ("2".equals(job.getInOrOut()) || "3".equals(job.getInOrOut())) {
//ctu物料入库 高架库入库
//入库作业
MydoJobDetail param = new MydoJobDetail();
param.setJobId(jobId);
List<MydoJobDetail> mydoJobDetails = mydoJobDetailService.selectMydoJobDetailList(param);
BasCargoSpace basCargoSpace = basCargoSpaceService.selectBasCargoSpaceByCargoSpaceId(job.getCargoSpaceId());
if (CollUtil.isNotEmpty(mydoJobDetails)) {
List<BasStock> list = new ArrayList<>();
//查找是否存在异常信息
OutExceptionRecord outExceptionRecordParam = new OutExceptionRecord();
outExceptionRecordParam.setTrayCode(job.getTrayCode());
outExceptionRecordParam.setWarehouseId(job.getWarehouseId());
List<OutExceptionRecord> outExceptionRecords = outExceptionRecordService.selectOutExceptionRecordList(outExceptionRecordParam);
for (MydoJobDetail mydoJobDetail : mydoJobDetails) {
if (job.getJobId().startsWith("RK")){
//修改单据实际数量 物料入库 高架库入库
String inOrOutDId = mydoJobDetail.getInOrOutDId();
InStockinDetail inStockinDetail = inStockinDetailService.selectInStockinDetailByStockinDetailId(inOrOutDId);
inStockinDetail.setAssignNum(Convert.toStr(Convert.toBigDecimal(inStockinDetail.getAssignNum()).add(Convert.toBigDecimal(mydoJobDetail.getInQuantity()))));
inStockinDetailService.updateInStockinDetail(inStockinDetail);
}
Optional<OutExceptionRecord> first = outExceptionRecords.stream().filter(x -> x.getTrayCode().equals(job.getTrayCode()) && x.getProductId().equals(mydoJobDetail.getProductId())).findFirst();
if (first.isPresent()) {
//生成异常库存
BasStock stockByInStockinDetail = getStockByInStockinDetail(mydoJobDetail, job, "3");
list.add(stockByInStockinDetail);
//修改异常记录中的库存id
OutExceptionRecord outExceptionRecord = first.get();
outExceptionRecord.setStockId(stockByInStockinDetail.getStockId());
outExceptionRecordService.updateOutExceptionRecord(outExceptionRecord);
} else {
//正常库存
list.add(getStockByInStockinDetail(mydoJobDetail, job, "1"));
}
}
//删除异常库存记录
List<Long> collect = outExceptionRecords.stream().map(OutExceptionRecord::getOutGuid).collect(Collectors.toList());
if (CollUtil.isNotEmpty(collect)) {
for (Long id : collect) {
outExceptionRecordService.deleteOutExceptionRecordByOutGuid(id);
}
//修改货位状态
basCargoSpace.setStatus("2");
basCargoSpace.setTrayCode(job.getTrayCode());
basCargoSpace.setCargoSpaceId(job.getCargoSpaceId());
basCargoSpaceService.updateBasCargoSpace(basCargoSpace);
}
//修改货位状态
basCargoSpace.setStatus("2");
basCargoSpace.setTrayCode(job.getTrayCode());
basCargoSpace.setCargoSpaceId(job.getCargoSpaceId());
basCargoSpaceService.updateBasCargoSpace(basCargoSpace);
//插入库存信息
basStockService.insertBasStockList(list);
//插入库存信息
basStockService.insertBasStockList(list);
//结束任务
mydoJob.setStatus("4");
mydoJob.setFinishTime(DateUtil.formatDateTime(DateUtil.date()));
updateMydoJob(mydoJob);
// 插入任务历史表 删除任务
insertHistory(mydoJob.getJobId());
//结束任务
mydoJob.setStatus("4");
mydoJob.setFinishTime(DateUtil.formatDateTime(DateUtil.date()));
updateMydoJob(mydoJob);
// 插入任务历史表 删除任务
insertHistory(mydoJob.getJobId());
return AjaxResult.success();
} else {
return AjaxResult.warn(MessageUtils.message("warn.message2"));
}
} else if ("5".equals(job.getInOrOut()) || "6".equals(job.getInOrOut())) {
//盘点 ctu入库 高架库入库
//入库作业
MydoJobDetail param = new MydoJobDetail();
param.setJobId(jobId);
List<MydoJobDetail> mydoJobDetails = mydoJobDetailService.selectMydoJobDetailList(param);
BasCargoSpace basCargoSpace = basCargoSpaceService.selectBasCargoSpaceByCargoSpaceId(job.getCargoSpaceId());
if (CollUtil.isNotEmpty(mydoJobDetails)) {
List<BasStock> list = new ArrayList<>();
//todo 插入回传表
//查询盘点信息中的异常信息
CheckDifferenceRecord checkDifferenceRecordParam = new CheckDifferenceRecord();
checkDifferenceRecordParam.setTrayCode(job.getTrayCode());
checkDifferenceRecordParam.setWarehouseId(job.getWarehouseId());
List<CheckDifferenceRecord> checkDifferenceRecords = checkDifferenceRecordService.selectCheckDifferenceRecordList(checkDifferenceRecordParam);
for (MydoJobDetail mydoJobDetail : mydoJobDetails) {
//如果存在盘点异常信息 根据托盘条码和物料id 筛选异常信息
Optional<CheckDifferenceRecord> first = checkDifferenceRecords.stream().filter(x -> x.getTrayCode().equals(job.getTrayCode()) && x.getProductId().equals(mydoJobDetail.getProductId())).findFirst();
if (first.isPresent()) {
//生成盘点待审批库存
BasStock stockByInStockinDetail = getStockByInStockinDetail(mydoJobDetail, job, "2");
list.add(stockByInStockinDetail);
//修改异常记录中的库存id
CheckDifferenceRecord checkDifferenceRecord = first.get();
checkDifferenceRecord.setStockId(stockByInStockinDetail.getStockId());
checkDifferenceRecordService.updateCheckDifferenceRecord(checkDifferenceRecord);
} else {
//正常库存
list.add(getStockByInStockinDetail(mydoJobDetail, job, "1"));
}
}
//修改货位状态
basCargoSpace.setStatus("2");
basCargoSpace.setTrayCode(job.getTrayCode());
basCargoSpace.setCargoSpaceId(job.getCargoSpaceId());
basCargoSpaceService.updateBasCargoSpace(basCargoSpace);
//插入库存信息
basStockService.insertBasStockList(list);
//结束任务
mydoJob.setStatus("4");
mydoJob.setFinishTime(DateUtil.formatDateTime(DateUtil.date()));
updateMydoJob(mydoJob);
// 插入任务历史表 删除任务
insertHistory(mydoJob.getJobId());
return AjaxResult.success();
} else {
return AjaxResult.warn(MessageUtils.message("warn.message2"));
}
return AjaxResult.success();
} else {
return AjaxResult.warn(MessageUtils.message("warn.message3"));
return AjaxResult.warn("不存在子作业");
}
}
private BasStock getStockByInStockinDetail(MydoJobDetail mydoJobDetail, MydoJob mydoJob, String productStatus) {
@@ -432,7 +317,7 @@ public class MydoJobServiceImpl implements IMydoJobService {
MydoJob job = selectMydoJobByJobId(jobId);
BasWarehouse basWarehouse = basWarehouseService.selectBasWarehouseByWarehouseId(job.getWarehouseId());
if("2".equals(basWarehouse.getWarehouseType()) && Integer.parseInt(job.getStatus())<3){
if ("2".equals(basWarehouse.getWarehouseType()) && Integer.parseInt(job.getStatus()) < 3) {
log.error("只能完成正执行的作业");
return AjaxResult.error(MessageUtils.message("error.message14"));
}
@@ -487,9 +372,9 @@ public class MydoJobServiceImpl implements IMydoJobService {
insertHistory(jobId);
//通知wcs
AjaxResult ajaxResult = iToWcsService.cancelTaskByTaskNo(job.getTaskNo());
if (ajaxResult.isSuccess()){
if (ajaxResult.isSuccess()) {
return AjaxResult.success();
}else {
} else {
throw new RuntimeException(Convert.toStr(ajaxResult.get("msg")));
}
}
@@ -503,7 +388,7 @@ public class MydoJobServiceImpl implements IMydoJobService {
}
@Override
public AjaxResult pointOut(String[] stockIds,String exitId) {
public AjaxResult pointOut(String[] stockIds, String exitId) {
HashMap<String, Object> map = new HashMap<>();
String msg = "";
String Stringbuilder = "";

View File

@@ -180,8 +180,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="selectEmptyCargoSpaceByWarehouseId" resultType="com.ruoyi.bas.cargoSpace.domain.BasCargoSpace">
SELECT TOP 1 cargo_space_id as cargoSpaceId
FROM bas_cargo_space
WHERE warehouse_id = #{warehouseId}
AND status = '1'
WHERE status = '1'
<if test="warehouseId != null">
and warehouse_id = #{warehouseId}
</if>
<if test="roadwayId != null">
and roadway_id = #{roadwayId}
</if>
ORDER BY the_platoon, the_column, the_floor
</select>

View File

@@ -228,6 +228,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="spare2 != null">spare2,</if>
<if test="spare3 != null">spare3,</if>
<if test="spare4 != null">spare4,</if>
<if test="spare5 != null">spare5,</if>
<if test="spare6 != null">spare6,</if>
<if test="spare7 != null">spare7,</if>
<if test="spare8 != null">spare8,</if>
<if test="spare9 != null">spare9,</if>
<if test="spec != null">spec,</if>
<if test="unit != null">unit,</if>
<if test="pickQuantity != null">pick_quantity,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
@@ -257,6 +264,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="spare2 != null">#{spare2},</if>
<if test="spare3 != null">#{spare3},</if>
<if test="spare4 != null">#{spare4},</if>
<if test="spare5 != null">#{spare5},</if>
<if test="spare6 != null">#{spare6},</if>
<if test="spare7 != null">#{spare7},</if>
<if test="spare8 != null">#{spare8},</if>
<if test="spare9 != null">#{spare9},</if>
<if test="spec != null">#{spec},</if>
<if test="unit != null">#{unit},</if>
<if test="pickQuantity != null">#{pick_quantity},</if>
</trim>
</insert>