立体仓出库

This commit is contained in:
mashuai 2025-12-29 17:43:07 +08:00
parent a6e1d9e2b8
commit e620c2254c
12 changed files with 546 additions and 9 deletions

View File

@ -130,4 +130,33 @@ public class MaterialConstants {
*/
public static final String SEND_SUCCESS = "1";
/**
* 立体库测试环境获取token路径
*/
public static final String TEST_TOKEN_URL = "http://192.168.1.124:32400/api/Identity/login/getToken";
/**
* 立体库生产环境获取token路径
*/
public static final String PROD_TOKEN_URL = "http://192.168.1.124:32400/api/Identity/login/getToken";
/**
* 立体库测试环境建立出库单路径
*/
public static final String TEST_CREATE_OUT_URL = "http://192.168.1.124:32400/api/Outbound/createOutbound";
/**
* 立体库生产环境建立出库单路径
*/
public static final String PROD_CREATE_OUT_URL = "http://192.168.1.124:32400/api/Outbound/createOutbound";
/**
* 立体库测试环境建立入库单路径
*/
public static final String TEST_CREATE_IN_URL = "http://192.168.1.124:32400/api/lims/zNXT/docInStorage";
/**
* 立体库生产环境建立入库单路径
*/
public static final String PROD_CREATE_IN_URL = "http://192.168.1.124:32400/api/lims/zNXT/docInStorage";
}

View File

@ -185,4 +185,13 @@ public class LeaseOutDetails extends BaseEntity {
@ApiModelProperty(value = "老规格型号id集合")
private List<String> oldTypeIdList;
@ApiModelProperty(value = "默认0 不是立体库1 立体库")
private Integer isRs;
@ApiModelProperty(value = "物资类型")
private String maTypeName;
@ApiModelProperty(value = "单位名称")
private String unitName;
}

View File

@ -0,0 +1,58 @@
package com.bonus.common.biz.domain.purchase;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* 立体库入库传参dto
* @Author ma_sh
* @create 2025/12/25 12:36
*/
@Data
public class AutomaticInPutDto {
@ApiModelProperty("行号")
private Integer lineNum;
@ApiModelProperty("物料编码")
private String materialCode;
@ApiModelProperty("物料名称")
private String materialName;
@ApiModelProperty("计量单位")
private String unitCode;
@ApiModelProperty("质量枚举0=待检、1=合格、2=不合格")
private Integer qualityResult;
@ApiModelProperty("生产日期")
private Date productionDate;
@ApiModelProperty("失效日期")
private Date expirationDate;
@ApiModelProperty("批次号")
private String batchNo;
@ApiModelProperty("供应商批次号")
private String supplierBatchNo;
@ApiModelProperty("入库数量")
private BigDecimal inQty;
@ApiModelProperty("类型id")
private Long typeId;
@ApiModelProperty(value = "二级明细id")
private String purchaseId;
@ApiModelProperty(value = "待入库数量")
private BigDecimal pendingInputNum;
@ApiModelProperty("设备id")
private Long maId;
}

View File

@ -0,0 +1,51 @@
package com.bonus.common.biz.domain.purchase;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
* 立体库出库传参dto
* @Author ma_sh
* @create 2025/12/25 12:36
*/
@Data
public class AutomaticOutPutDto {
@ApiModelProperty("行号")
private Integer lineNum;
@ApiModelProperty("物料编码")
private String materialCode;
@ApiModelProperty("物料名称")
private String materialName;
@ApiModelProperty("计量单位")
private String unitCode;
@ApiModelProperty("质量枚举0=待检、1=合格、2=不合格")
private Integer qualityResult;
@ApiModelProperty("出库目标站台")
private String outLocNo;
@ApiModelProperty("电芯等级(电芯库使用)")
private String batteryGrade;
@ApiModelProperty("批次号")
private String batchNo;
@ApiModelProperty("主数据上的 IsAppointTray如果是 true那么此字段必填")
private String trayBarcode;
@ApiModelProperty("出库数量")
private BigDecimal outQty;
@ApiModelProperty("类型id")
private Long typeId;
@ApiModelProperty("设备id")
private Long maId;
}

View File

@ -30,7 +30,9 @@ public enum MaMachineStatusEnum {
SCRAP_TO_AUDIT(10, "报废待审核"),
RETURNED_MATERIAL(11, "退料暂存"),
// 信息采集
INFORMATION_COLLECTION(-1, "信息采集待入库");
INFORMATION_COLLECTION(-1, "信息采集待入库"),
// 待上架
TO_UPLOAD(19, "待上架");
private final Integer status;
private final String statusName;

View File

@ -0,0 +1,244 @@
package com.bonus.common.biz.utils;
import com.alibaba.fastjson2.JSONObject;
import com.bonus.common.biz.constant.MaterialConstants;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
/**
* @author bonus
*/
public class AutomaticHttpHelper {
public static final String KEY = "$jqgcYouote@c103";
public static String sendHttpPost(String url, String JSONBody) throws Exception {
System.out.println("JSONBody-=========:" + JSONBody);
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Content-Type", "application/json; charset=UTF-8");
httpPost.setEntity(new StringEntity(JSONBody,StandardCharsets.UTF_8));
CloseableHttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
String responseContent = EntityUtils.toString(entity, StandardCharsets.UTF_8);
response.close();
httpClient.close();
return responseContent;
}
public static String sendHttpPostPushCost(String url, String JSONBody) throws Exception {
// 获取token
String token = getToken();
if (StringHelper.isEmpty(token)) {
System.err.println("token获取失败-=========:");
return null;
}
System.err.println("JSONBody-=========:" + JSONBody);
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Content-Type", "application/json;charset=UTF-8");
httpPost.addHeader("Authorization", token);
httpPost.setEntity(new StringEntity(JSONBody, StandardCharsets.UTF_8));
CloseableHttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
String responseContent = EntityUtils.toString(entity, StandardCharsets.UTF_8);
response.close();
httpClient.close();
return responseContent;
}
public static String sendHttpPost(String url,String token,String content,String intelligentAppKey) throws Exception {
System.out.println("JSONBody-=========:" + content);
try (CloseableHttpClient client = HttpClients.createDefault()) {
HttpPost post = new HttpPost(url);
post.setHeader("token", token);
post.setHeader("appKey", intelligentAppKey);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addBinaryBody("params", content.getBytes());
post.setEntity(builder.build());
CloseableHttpResponse response = client.execute(post);
HttpEntity entity = response.getEntity();
String responseContent = EntityUtils.toString(entity, StandardCharsets.UTF_8);
response.close();
return responseContent;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static String doPost(String urlString,String param) {
HttpURLConnection connection = null;
InputStream is = null;
OutputStream os = null;
BufferedReader br = null;
String result = null;
try {
URL url = new URL(urlString);
// 通过远程url连接对象打开连接
connection = (HttpURLConnection) url.openConnection();
// 设置连接请求方式
connection.setRequestMethod("POST");
// 设置连接主机服务器超时时间15000毫秒
connection.setConnectTimeout(15000);
// 设置读取主机服务器返回数据超时时间60000毫秒
connection.setReadTimeout(60000);
// 默认值为false当向远程服务器传送数据/写数据时需要设置为true
connection.setDoOutput(true);
// 默认值为true当前向远程服务读取数据时设置为true该参数可有可无
connection.setDoInput(true);
// 设置传入参数的格式:请求参数应该是 name1=value1&name2=value2 的形式
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
// 设置鉴权信息Authorization: Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0
connection.setRequestProperty("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0");
// 通过连接对象获取一个输出流
os = connection.getOutputStream();
// 通过输出流对象将参数写出去/传输出去,它是通过字节数组写出的
os.write(param.getBytes());
// 通过连接对象获取一个输入流向远程读取
if (connection.getResponseCode() == 200) {
is = connection.getInputStream();
// 对输入流对象进行包装:charset根据工作项目组的要求来设置
br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
StringBuffer sbf = new StringBuffer();
String temp = null;
// 循环遍历一行一行读取数据
while ((temp = br.readLine()) != null) {
sbf.append(temp);
sbf.append("\r\n");
}
result = sbf.toString();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭资源
if (null != br) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != os) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != is) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 断开与远程地址url的连接
connection.disconnect();
}
return result;
}
// public static String getIotToken() {
// Map<String,Object> map=new HashMap<>();
// String redisCode = null;
// map.put("type", UserConstants.IOT_TYPE);
// map.put("from",UserConstants.IOT_FROM);
// map.put("username",UserConstants.IOT_USERNAME);
// //采用md5加密
// map.put("password",UserConstants.IOT_PASSWORD);
// String param = JSON.toJSONString(map);
// String resultUser = HttpHelper.doPost(HttpStatus.LOGIN_URL,param);
// if (resultUser == null){
// throw new RuntimeException("返回数据为空!!");
// }
// JSONObject object = JSONObject.parseObject(resultUser);
// if ("0".equals(object.getString("status"))){
// redisCode = object.getString("token");
// }else {
// throw new RuntimeException("返回数据为空!!");
// }
// return redisCode;
// }
/**
* 获取token
*
* @return
*/
private static String getToken() {
// 立体库本地测试token路径
String tokenUrl = MaterialConstants.TEST_TOKEN_URL;
// 立体库生产环境token路径
//String tokenUrl = MaterialConstants.PROD_TOKEN_URL;
try {
String userName = "ZNXT";
String password = "123456";
JSONObject data = new JSONObject();
data.put("userName", userName);
data.put("password", password);
String body = JSONObject.toJSONString(data);
String result = AutomaticHttpHelper.sendHttpPostForToken(tokenUrl, body);
System.err.println("dataString-=========:" + result);
if (!StringHelper.isEmpty(result)) {
JSONObject object = JSONObject.parseObject(result);
String code = object.getString("code");
if ("0".equals(code)) {
String token = object.getString("data");
return token;
}
} else {
return null;
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
return null;
}
return null;
}
/**
* 不带鉴权的请求
* @param url
* @param JSONBody
* @return
* @throws Exception
*/
public static String sendHttpPostForToken(String url, String JSONBody) throws Exception {
System.err.println("JSONBody-=========:" + JSONBody);
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Content-Type", "application/json");
httpPost.setEntity(new StringEntity(JSONBody));
CloseableHttpResponse response = httpClient.execute(httpPost);
// System.out.println(response.getStatusLine().getStatusCode() + "\n");
HttpEntity entity = response.getEntity();
String responseContent = EntityUtils.toString(entity, "UTF-8");
// System.out.println(responseContent);
response.close();
httpClient.close();
return responseContent;
}
}

View File

@ -216,6 +216,10 @@ public class LeaseApplyDetails extends BaseEntity {
@ApiModelProperty(value = "领料物资名称汇总")
private String maTypeNames;
@ApiModelProperty(value = "默认0 不是立体库1 立体库")
private Integer isRs;
public LeaseApplyDetails(Long id, Long parentId, Long typeId, BigDecimal preNum, BigDecimal auditNum, BigDecimal alNum, String status, Long companyId) {
this.id = id;
this.parentId = parentId;

View File

@ -247,4 +247,26 @@ public interface LeaseApplyDetailsMapper {
* @return
*/
LeaseApplyDetails getPublishNum(LeaseApplyDetails detail);
/**
* 修改领用任务详细
* @param record
* @return
*/
int updateLeaseNum(LeaseOutDetails record);
/**
* 更新 (ma_machine 设备表)的状态为待上架
* @param record
* @param status
* @return
*/
int updateMaMachineStatus(@Param("record") LeaseOutDetails record, @Param("status") Integer status);
/**
* 修改发布表状态
* @param record
* @return
*/
int updateLeaseApplyStatus(LeaseOutDetails record);
}

View File

@ -100,7 +100,7 @@ public interface ILeaseApplyInfoService {
* @param leaseOutRequestVo 领料出库
* @return 结果
*/
AjaxResult leaseOut(LeaseOutRequestVo leaseOutRequestVo);
AjaxResult leaseOut(LeaseOutRequestVo leaseOutRequestVo) throws Exception;
/**

View File

@ -4,11 +4,17 @@ import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;
import com.alibaba.fastjson.JSONObject;
import com.bonus.common.biz.constant.GlobalConstants;
import com.bonus.common.biz.domain.purchase.AutomaticInPutDto;
import com.bonus.common.biz.domain.purchase.AutomaticOutPutDto;
import com.bonus.common.biz.domain.repair.RepairInputDetails;
import com.bonus.common.biz.enums.*;
import com.bonus.common.biz.utils.AutomaticHttpHelper;
import com.bonus.material.basic.domain.BmAgreementInfo;
import com.bonus.material.basic.mapper.BmAgreementInfoMapper;
import com.bonus.material.common.mapper.SelectMapper;
@ -218,10 +224,12 @@ public class LeaseApplyInfoServiceImpl implements ILeaseApplyInfoService {
BigDecimal outNum = leaseApplyDetailsMapper.getOutNum(detail);
detail.setAlNum(outNum);
detail.setOutNum(detail.getPreNum().subtract(outNum));
if (detail.getPreNum().compareTo(detail.getAlNum()) == 0) {
detail.setStatus("2");
} else {
detail.setStatus("1");
if (!"3".equals(detail.getStatus())) {
if (detail.getPreNum().compareTo(detail.getAlNum()) == 0) {
detail.setStatus("2");
} else {
detail.setStatus("1");
}
}
//查询类型的库存和总待出库数量
LeaseApplyDetails pendingOutNum = mapper.selectPendingOutNum(detail);
@ -1863,7 +1871,7 @@ public class LeaseApplyInfoServiceImpl implements ILeaseApplyInfoService {
* @return 结果
*/
@Override
public AjaxResult leaseOut(LeaseOutRequestVo leaseOutRequestVo) {
public AjaxResult leaseOut(LeaseOutRequestVo leaseOutRequestVo) throws Exception {
// 判断库存是否充足
if (!CollectionUtils.isEmpty(leaseOutRequestVo.getLeaseOutDetailsList())) {
LeaseOutDetails leaseOutDetails = leaseOutRequestVo.getLeaseOutDetailsList().get(0);
@ -1897,6 +1905,81 @@ public class LeaseApplyInfoServiceImpl implements ILeaseApplyInfoService {
return AjaxResult.error("该设备已出库,请勿重复操作");
}
}
// 判断是否为立体仓出库
if (leaseOutDetails.getIsRs() != null && leaseOutDetails.getIsRs() == 1) {
// 向第三方发送出库请求创建出库单
Integer manageType = null;
ArrayList<AutomaticOutPutDto> list = new ArrayList<>();
if (leaseOutDetails.getManageType().equals(MaTypeManageTypeEnum.NUMBER_DEVICE.getTypeId())) {
// 数量出库
manageType = 1;
AutomaticOutPutDto automaticOutPutDto = new AutomaticOutPutDto();
automaticOutPutDto.setMaterialName(leaseOutDetails.getMaTypeName());
automaticOutPutDto.setUnitCode(leaseOutDetails.getUnitName());
automaticOutPutDto.setOutQty(leaseOutDetails.getInputNum());
automaticOutPutDto.setLineNum(1);
automaticOutPutDto.setTypeId(leaseOutDetails.getTypeId());
list.add(automaticOutPutDto);
} else {
manageType = 0;
// 编码出库
for (int i = 0; i < leaseOutRequestVo.getLeaseOutDetailsList().size(); i++) {
AutomaticOutPutDto automaticOutPutDto = new AutomaticOutPutDto();
automaticOutPutDto.setMaterialName(leaseOutDetails.getMaTypeName());
automaticOutPutDto.setUnitCode(leaseOutDetails.getUnitName());
automaticOutPutDto.setOutQty(BigDecimal.ONE);
automaticOutPutDto.setLineNum(i + 1);
automaticOutPutDto.setTypeId(leaseOutRequestVo.getLeaseOutDetailsList().get( i).getTypeId());
automaticOutPutDto.setMaterialCode(leaseOutRequestVo.getLeaseOutDetailsList().get( i).getMaCode());
automaticOutPutDto.setMaId(leaseOutRequestVo.getLeaseOutDetailsList().get( i).getMaId());
list.add(automaticOutPutDto);
}
}
Map<String, Object> map = new HashMap<>();
map.put("ExternalNo", leaseOutDetails.getCode());
map.put("publishTask", leaseOutDetails.getPublishTask());
map.put("leaseUnitId", leaseOutDetails.getLeaseUnitId());
map.put("leaseProjectId", leaseOutDetails.getLeaseProjectId());
map.put("oldTypeIdList", leaseOutDetails.getOldTypeIdList());
map.put("taskId", leaseOutDetails.getTaskId());
map.put("manageType", manageType);
map.put("parentId", leaseOutDetails.getParentId());
// 是否指定托盘出库true=指定托盘false= 不指定托盘
map.put("IsAppointTray", false);
map.put("OutDes", "领料出库");
map.put("DtlList", list);
String body = JSONObject.toJSONString(map);
// 立体库本地建立出库单接口路径
String url = MaterialConstants.TEST_CREATE_OUT_URL;
// 立体库生产建立出库单接口路径
//String url = MaterialConstants.TEST_CREATE_OUT_URL;
String data = AutomaticHttpHelper.sendHttpPostPushCost(url, body);
if (StringUtils.isEmpty(data)) {
return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), "立体仓出库单创建失败");
}
JSONObject object = JSONObject.parseObject(data);
String code = object.getString("code");
if ("0".equals(code)) {
for (LeaseOutDetails record : leaseOutRequestVo.getLeaseOutDetailsList()) {
record.setStatus("3");
// 首先更新领料任务详情表的领料数及状态lease_apply_details
if (StringUtils.isNotBlank(record.getPublishTask())) {
// 领用,修改发布表状态为待上架
leaseApplyDetailsMapper.updateLeaseApplyStatus(record);
} else {
// 领料办理
leaseApplyDetailsMapper.updateLeaseNum(record);
}
if (record.getMaId() != null) {
// 更新 (ma_machine 设备表)的状态为待上架
leaseApplyDetailsMapper.updateMaMachineStatus(record, MaMachineStatusEnum.TO_UPLOAD.getStatus());
}
}
return AjaxResult.success("立体仓出库单创建成功");
} else {
return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), "立体仓出库单创建失败");
}
}
}
}
for (LeaseOutDetails bean : leaseOutRequestVo.getLeaseOutDetailsList()) {
@ -1924,6 +2007,9 @@ public class LeaseApplyInfoServiceImpl implements ILeaseApplyInfoService {
System.out.println("发布出库的领料单位不是班组,No");
}
}
if (bean.getMaId() != null && bean.getInputNum() != null) {
bean.setOutNum(bean.getInputNum());
}
AjaxResult ajaxResult = leaseOutDetailsService.leaseOut(bean);
if (ajaxResult.isError()) {
return ajaxResult;

View File

@ -803,6 +803,9 @@ public class LeaseOutDetailsServiceImpl implements ILeaseOutDetailsService {
.collect(Collectors.toList());
record.setOldTypeIdList(oldTypeIdList);
}
// 领用,解除发布表待上架状态
record.setStatus("1");
leaseApplyDetailsMapper.updateLeaseApplyStatus(record);
List<LeaseApplyDetails> allList = leaseApplyDetailsMapper.getLeasePublishApplyDetails(record);
// 出库数量
BigDecimal outNum = record.getOutNum();

View File

@ -90,7 +90,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
mt4.type_id as firstId,
su.sign_url as signUrl,
su.sign_type as signType,
IFNULL(lad.pre_num,0) as pendingPublishNum
IFNULL(lad.pre_num,0) as pendingPublishNum,
mt.is_rs as isRs
from
lease_apply_details lad
left join
@ -310,6 +311,32 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
id = #{id}
</update>
<update id="updateLeaseNum">
UPDATE
lease_apply_details
SET
status = #{status}
WHERE
parent_id = #{record.parentId} and type_id = #{record.typeId}
</update>
<update id="updateMaMachineStatus">
UPDATE
ma_machine
SET
ma_status = #{status}
WHERE
ma_id = #{record.maId}
</update>
<update id="updateLeaseApplyStatus">
update lease_publish_details
set status = #{status}
where parent_id = #{parentId}
and publish_task = #{publishTask}
and new_type = #{typeId}
</update>
<select id="getOutboundNum" resultType="com.bonus.material.lease.domain.LeaseApplyDetails">
SELECT id, parent_id as parentId, type_id as typeId, pre_num as preNum, al_num as alNum, `status`, remark
FROM lease_apply_details
@ -560,7 +587,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
mt4.type_id as firstId,
su.sign_url as signUrl,
su.sign_type as signType,
GROUP_CONCAT(lpd.type_id) as oldTypeId
GROUP_CONCAT(lpd.type_id) as oldTypeId,
mt.is_rs as isRs,
lpd.status as status
FROM
lease_publish_details lpd
LEFT JOIN ma_type mt ON lpd.new_type = mt.type_id