Bladeren bron

【华信科】【富勒WMS对接】【入库确认】

wuyx 9 maanden geleden
bovenliggende
commit
ad2fec1f74

+ 44 - 0
src/main/java/com/uas/eis/controller/ERPWMSController.java

@@ -0,0 +1,44 @@
+package com.uas.eis.controller;
+
+import com.uas.eis.entity.vwms.req.BaseReq;
+import com.uas.eis.entity.vwms.req.IOConfirm;
+import com.uas.eis.sdk.entity.WMSApiResult;
+import com.uas.eis.service.ERPWMSService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.io.IOException;
+
+
+/**
+ * @author wuyx
+ * @email wuyx@usoftchina.com
+ */
+@RestController
+public class ERPWMSController {
+    @Autowired
+    private ERPWMSService erpwmsService;
+
+    /**
+     * 出入库确认
+     * 入库订单确认 openapi.entryorder.confirm
+     * ● http://{openapiUrl}?method=openapi.entryorder.confirm&timestamp=2015-04-26%2000:00:07&format=xml&app_key={app_key}&v=2.0&sign=D06D88CB34B2EC0E5C9BAB396C9542B6&sign_method=md5&customerId={customerId}
+     *
+     */
+    @RequestMapping(value="/wms",method=RequestMethod.POST)
+    @ResponseBody
+    public WMSApiResult IOConfirm(String method,HttpServletRequest request) throws IOException {
+        // 从request属性中获取缓存的请求体
+        String cachedBody = (String) request.getAttribute("cachedRequestBody");
+        // 使用Jackson将JSON字符串转换为BaseReq<IOConfirm>对象
+        ObjectMapper objectMapper = new ObjectMapper();
+        BaseReq<IOConfirm> ioConfirmBaseReq = objectMapper.readValue(cachedBody,
+                objectMapper.getTypeFactory().constructParametricType(BaseReq.class, IOConfirm.class));
+        return erpwmsService.IOConfirm(method, ioConfirmBaseReq);
+    }
+
+
+}

+ 1 - 1
src/main/java/com/uas/eis/core/WebAppConfig.java

@@ -26,7 +26,7 @@ public class WebAppConfig extends WebMvcConfigurationSupport{
 
 	@Override
 	public void addInterceptors(InterceptorRegistry registry){
-		registry.addInterceptor(apiSignLoginInterceptor()).addPathPatterns("/api/**","/mes/**")
+		registry.addInterceptor(apiSignLoginInterceptor()).addPathPatterns("/api/**","/wms/**")
 				.excludePathPatterns("/login", "/erp/**");
 		registry.addInterceptor(new DataSourceInterceptor()).addPathPatterns("/*/**");
 	}

+ 105 - 59
src/main/java/com/uas/eis/core/support/ApiSignLoginInterceptor.java

@@ -1,18 +1,23 @@
 package com.uas.eis.core.support;
 
+import com.uas.eis.config.VwmsConfig;
 import com.uas.eis.entity.ErrorMessage;
 import com.uas.eis.exception.ApiSystemException;
 import com.uas.eis.sdk.entity.ApiResult;
+import com.uas.eis.sdk.entity.WMSApiResult;
 import com.uas.eis.utils.MD5Util;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import java.io.UnsupportedEncodingException;
+import java.io.*;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.*;
 
 @Service
@@ -20,53 +25,60 @@ public class ApiSignLoginInterceptor extends HandlerInterceptorAdapter {
 
     // 签名超时时长,默认时间为5分钟,ms
     private static final int SIGN_EXPIRED_TIME = 5 * 60 * 1000;
-    private static final String ACCESS_KEY = "AccessKey";
-    private static final String ACCESS_SECRET = "AccessSecret";
-    private static final String TIMESTAMP_KEY = "Timestamp";
-    private static final String SIGN_KEY = "Signature";
-    private static final String RequestId = "RequestId";
-    private static Map<String,String> tokenConfig = TokenProperties.getAllProperty();
-    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+    private static final String METHOD = "method";//接口方法名 用于确认接口
+    private static final String TIMESTAMP_KEY = "timestamp";//2025-02-26 00:00:07
+//    private static final String FORMAT = "format";//json
+//    private static final String VERSION_ = "v";//2.0
+    private static final String SIGN_KEY = "sign";//签名 用于签名验证 E58F1B90BCD69FF7DFC7E9DA1831F532
+//    private static final String SIGN_METHOD = "sign_method";//md5
+    private static final String CUSTOMER_ID = "customerId";//用户id HXK
+    private static final String APP_KEY = "app_key";//appkey 用于生成签名 HXK0225
+//    private static final String APP_SECRET = "app_secret";//用于生成签名
+
+    @Autowired
+    private VwmsConfig vwmsConfig;
 
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
 
     @Override
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+        WMSApiResult apiResult = new WMSApiResult();
+        String timestamp = request.getParameter(TIMESTAMP_KEY);
+        String appKey = request.getParameter(APP_KEY);
+        String customerIdIn = request.getParameter(CUSTOMER_ID);
+        String originSign = request.getParameter(SIGN_KEY);
+        String method = request.getParameter(METHOD);
+        String body =  getRequestBody(request);
+        String customerIdSet = vwmsConfig.getCustomerId();
+        String appKeySet = vwmsConfig.getAppKey();
 
-        String timestamp = request.getHeader(TIMESTAMP_KEY);
-        String accessKey = request.getHeader(ACCESS_KEY);
-        String requestId = request.getHeader(RequestId);
-        String originSign = request.getHeader(SIGN_KEY);
-        logger.info("timestamp=="+timestamp);
-        logger.info("accessKey=="+accessKey);
-        logger.info("requestId=="+requestId);
-        logger.info("originSign=="+originSign);
-
-        String accessSecret = tokenConfig.get(accessKey);
-        if (StringUtils.isEmpty(requestId)) {
-            ApiResult apiResult = new ApiResult();
-            apiResult.setCode(ErrorMessage.REQUESTID_ILLEGAL.getCode());
-            apiResult.setMessage(ErrorMessage.REQUESTID_ILLEGAL.getMessage());
-            apiResult.setRequestId(requestId);
+        // 获取所有参数
+        Map<String, String[]> parameterMap = request.getParameterMap();
+        for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
+            logger.info("Parameter: " + entry.getKey() + " = " + Arrays.toString(entry.getValue()));
+        }
+//        logger.info("customerIdSet=="+customerIdSet);
+//        logger.info("appKeySet=="+appKeySet);
+        logger.info("body: " + body);
+        if (StringUtils.isEmpty(customerIdIn)||!customerIdSet.equals(customerIdIn)) {
+            apiResult.setFlag("failure");
+            apiResult.setCode(ErrorMessage.CUSTOMER_ID_ILLEGAL.getCode());
+            apiResult.setMessage(ErrorMessage.CUSTOMER_ID_ILLEGAL.getMessage());
             throw new ApiSystemException(apiResult);
         }
-        if (!StringUtils.isNumeric(timestamp)) {
-            ApiResult apiResult = new ApiResult();
+        if (StringUtils.isEmpty(timestamp)||!isValidTimestampFormat(timestamp)) {
+            apiResult.setFlag("failure");
             apiResult.setCode(ErrorMessage.TIMESTAMP_ILLEGAL.getCode());
             apiResult.setMessage(ErrorMessage.TIMESTAMP_ILLEGAL.getMessage());
-            apiResult.setRequestId(requestId);
             throw new ApiSystemException(apiResult);
         }
-
-        // 检查KEY是否合理
-        if (StringUtils.isEmpty(accessKey) || StringUtils.isEmpty(accessSecret)) {
-            ApiResult apiResult = new ApiResult();
+        if (StringUtils.isEmpty(appKey) ||!appKeySet.equals(appKey)) {
+            apiResult.setFlag("failure");
             apiResult.setCode(ErrorMessage.ACCESSKEY_ILLEGAL.getCode());
             apiResult.setMessage(ErrorMessage.ACCESSKEY_ILLEGAL.getMessage());
-            apiResult.setRequestId(requestId);
             throw new ApiSystemException(apiResult);
         }
-
-        Long ts = Long.valueOf(timestamp);
+        /*Long ts = Long.valueOf(timestamp);
         // 禁止超时签名
         if (System.currentTimeMillis() - ts > SIGN_EXPIRED_TIME) {
             ApiResult apiResult = new ApiResult();
@@ -74,41 +86,75 @@ public class ApiSignLoginInterceptor extends HandlerInterceptorAdapter {
             apiResult.setMessage(ErrorMessage.TIMEOUT_ILLEGAL.getMessage());
             apiResult.setRequestId(requestId);
             throw new ApiSystemException(apiResult);
-        }
-
-        if (!verificationSign(accessKey, accessSecret,timestamp,requestId,originSign)) {
-            ApiResult apiResult = new ApiResult();
-            apiResult.setCode(ErrorMessage.SIGNATURE_ILLEGAL.getCode());
-            apiResult.setMessage(ErrorMessage.SIGNATURE_ILLEGAL.getMessage());
-            apiResult.setRequestId(requestId);
-            throw new ApiSystemException(apiResult);
-        }
+        }*/
+//        if (!verificationSign(method,timestamp,originSign,body)) {
+//            apiResult.setFlag("failure");
+//            apiResult.setCode(ErrorMessage.SIGNATURE_ILLEGAL.getCode());
+//            apiResult.setMessage(ErrorMessage.SIGNATURE_ILLEGAL.getMessage());
+//            throw new ApiSystemException(apiResult);
+//        }
+        // 将缓存体存入request属性中,供后续使用
+        request.setAttribute("cachedRequestBody", body);
+        logger.info("preHandle====End");
         return true;
     }
 
-    private boolean verificationSign(String accessKey, String accessSecret,String timestamp,String requestId,String originSign) throws UnsupportedEncodingException {
+    private String getRequestBody(HttpServletRequest request) throws IOException {
+        StringBuilder stringBuilder = new StringBuilder();
+        BufferedReader bufferedReader = null;
+        try {
+            InputStream inputStream = request.getInputStream();
+            if (inputStream != null) {
+                bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
+                char[] charBuffer = new char[128];
+                int bytesRead;
+                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
+                    stringBuilder.append(charBuffer, 0, bytesRead);
+                }
+            }
+        } finally {
+            if (bufferedReader != null) {
+                bufferedReader.close();
+            }
+        }
+        // 去掉回车和tab符号
+        return stringBuilder.toString().replaceAll("[\\r\\n\\t]", "");
+    }
+    private boolean isValidTimestampFormat(String timestamp) {
+        try {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+            sdf.setLenient(false);  // 严格模式,不允许自动转换
+            sdf.parse(timestamp);
+            return true;
+        } catch (ParseException e) {
+            return false;
+        }
+    }
+    private boolean verificationSign(String method,String timestamp,String originSign,String body) throws UnsupportedEncodingException {
+        String appSecret = vwmsConfig.getAppSecret();
+        String customerId = vwmsConfig.getCustomerId();
+        String appKey = vwmsConfig.getAppKey();
         Map<String, Object> params = new HashMap<String, Object>();
-        params.put(ACCESS_KEY,accessKey);
-        params.put(RequestId,requestId);
+        params.put(APP_KEY,appKey);
+        params.put(CUSTOMER_ID,customerId);
+        params.put("format","json");
+        params.put(METHOD,method);
+        params.put("sign_method","md5");
         params.put(TIMESTAMP_KEY,timestamp);
-        String sign = createSign(params, accessSecret);
-        System.out.println(sign);
+        params.put("v", "2.0");
+        String sign = createSign(params,body, appSecret);
+        System.out.println("传入的sign:"+originSign);
+        System.out.println("生成的sign:"+sign);
         return sign.equals(originSign);
     }
-
-    private String createSign(Map<String, Object> params, String accessSecret) throws UnsupportedEncodingException {
+    //{secretkey}app_key{app_key}customerId{customerId}formatxmlmethod{openapi_name}sign_methodmd5timestamp2015-04-26 00:00:07v2.0{body}{secretkey}
+    private String createSign(Map<String, Object> params,String body, String accessSecret) throws UnsupportedEncodingException {
         Set<String> keysSet = params.keySet();
         Object[] keys = keysSet.toArray();
         Arrays.sort(keys);
         StringBuilder temp = new StringBuilder();
-        boolean first = true;
+        temp.append(accessSecret);
         for (Object key : keys) {
-            if (first) {
-                first = false;
-            } else {
-                temp.append("&");
-            }
-            temp.append(key).append("=");
             Object value = params.get(key);
             String valueString = "";
             if (null != value) {
@@ -116,9 +162,9 @@ public class ApiSignLoginInterceptor extends HandlerInterceptorAdapter {
             }
             temp.append(valueString);
         }
-        temp.append("&").append(ACCESS_SECRET).append("=").append(accessSecret);
-        System.out.println(temp);
-        System.out.println(MD5Util.encrypt32Up(temp.toString()));
+        temp.append(body).append(accessSecret);
+        System.out.println("加密串:"+temp);
+//        System.out.println(MD5Util.encrypt32Up(temp.toString()));
         return MD5Util.encrypt32Up(temp.toString());
     }
 }

+ 2 - 1
src/main/java/com/uas/eis/entity/ErrorMessage.java

@@ -9,10 +9,11 @@ import java.util.Objects;
 public enum ErrorMessage {
     SYS_ILLEGAL("0001","请求异常"),
     TIMESTAMP_ILLEGAL("1001","请求时间戳不合法"),
-    ACCESSKEY_ILLEGAL("1002","加密KEY不合法"),
+    ACCESSKEY_ILLEGAL("1002","app_key不合法"),
     TIMEOUT_ILLEGAL("1003","请求超时"),
     REQUESTID_ILLEGAL("1004","随机字符串不合法"),
     SIGNATURE_ILLEGAL("1005","签名错误"),
+    CUSTOMER_ID_ILLEGAL("1006","customerId不合法"),
     BUSINESS_ILLEGAL("2001","业务异常");
 
     private String code;

+ 1 - 0
src/main/java/com/uas/eis/entity/vwms/entity/Prodiodetail.java

@@ -5,6 +5,7 @@ import lombok.Data;
 @Data
 public class Prodiodetail {
     private Long pdId;
+    private Long pdPiid;
     private String pdPdno;
     private String pdProdcode;
     private String pdProdname;

+ 271 - 0
src/main/java/com/uas/eis/entity/vwms/req/IOConfirm.java

@@ -0,0 +1,271 @@
+package com.uas.eis.entity.vwms.req;
+
+import com.uas.eis.utils.StringUtil;
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+public class IOConfirm {
+    private EntryOrder entryOrder;
+    private OrderLines orderLines;
+    private OrderDetails orderDetails;
+
+    @Data
+    public static class EntryOrder {
+        /** 入库单号 */
+        private String entryOrderCode;
+        /** 货主代码 */
+        private String ownerCode;
+        /** 仓库代码 */
+        private String warehouseCode;
+        /** 仓储系统入库单ID */
+        private String entryOrderId;
+        /** 入库单类型 例如: CGRK=采购入库、DBRK=调拨入库 、THRK=退货入库, QTRK=其他入库等(只传英文代码) */
+        private String entryOrderType;
+        /** 外部业务代码 消息ID, 用于去重, 因为网络等原因导致重复传输, 请求不会被重复处理。一单需要多次确认时条件必填 */
+        private String outBizCode;
+        /** 支持入库单多次收货 多次收货后确认时 0=入库单最终状态确认, 1=入库单中间状态确认, 每次入库传入的数量为增量, 特殊情况, 同一入库单, 如果先收到0, 后又收到1, 允许修改收货的数量 */
+        private Integer confirmType;
+        /** 入库单状态 , PARTFULFILLED=部分收货完成, FULFILLED=收货完成(只传英文代码) */
+        private String status;
+        /** 订单完成时间 YYYY-MM-DD HH:MM:SS */
+        private String orderFinishedTime;
+        /** 收货人 */
+        private String receiver;
+        /** 备注 */
+        private String remark;
+        /** 用户自定义1 */
+        private String userDefined1;
+        /** 用户自定义2 */
+        private String userDefined2;
+        /** 用户自定义3 */
+        private String userDefined3;
+        /** 用户自定义4 */
+        private String userDefined4;
+    }
+
+    @Data
+    public static class OrderLines {
+        private List<OrderLine> orderLine;
+
+        @Data
+        public static class OrderLine {
+            /** 行号 */
+            private Integer lineNo;
+            /** 货品代码 */
+            private String itemCode;
+            /** 仓储系统商品ID */
+            private String itemId;
+            /** 包装单位 */
+            private String packUom;
+            /** 应收货品数量 */
+            private Double planQty;
+            /** 实收数量 */
+            private Double actualQty;
+            /** 实收包装数量 */
+            private Double actualPackUomQty;
+            /** 拒收数量 */
+            private Double rejectQty;
+            /** 拒收原因 */
+            private String rejectReason;
+            /** 序列号,多个序列号用英文逗号隔开 */
+            private String serialno;
+            private Batchs batchs;
+            /** 自定义字段1 */
+            private String customField1;
+            /** 自定义字段2 */
+            private String customField2;
+            /** 自定义字段3 */
+            private String customField3;
+            /** 自定义字段4 */
+            private String customField4;
+            /** 自定义字段5 */
+            private String customField5;
+            /** 自定义字段6 */
+            private String customField6;
+            /** 自定义字段7 */
+            private String customField7;
+            /** 自定义字段8 */
+            private String customField8;
+
+            @Data
+            public static class Batchs {
+                private List<Batch> batch;
+
+                @Data
+                public static class Batch {
+                    /** 实收数量 */
+                    private Double actualQty;
+                    /** 实收包装数量 */
+                    private Double actualPackUomQty;
+                    /** 质量状态 ZP=正品, CC=残次, 默认为ZP */
+                    private String inventoryType;
+                    /** 虚拟仓库 条件必填, 条件为使用虚拟仓库 */
+                    private String virtualWarehouse;
+                    /** 生产日期 YYYY-MM-DD */
+                    private String productDate;
+                    /** 失效日期 YYYY-MM-DD */
+                    private String expireDate;
+                    /** 批次号 */
+                    private String batchCode;
+                    /** 入库日期 YYYY-MM-DD */
+                    private String stockinDate;
+                    /** 自定义批次1 入库批次 */
+                    private String userDefined1;
+                    /** 自定义批次2 */
+                    private String userDefined2;
+                    /** 自定义批次3 品牌*/
+                    private String userDefined3;
+                    /** 自定义批次4 账套*/
+                    private String userDefined4;
+                    /** 容器号 */
+                    private String lpn;
+                }
+            }
+        }
+    }
+
+    @Data
+    public static class OrderDetails {
+        private List<Detail> detail;
+
+        @Data
+        public static class Detail {
+            private String boxNo;
+            private String epc;
+        }
+    }
+    public String getMasterName() {
+        if(orderLines.getOrderLine() !=null){//userDefined4
+            return orderLines.getOrderLine().get(0).getBatchs().getBatch().get(0).getUserDefined4();
+        }else {
+            return null;
+        }
+    }
+public String getGenerateMainSql(String masterCode,Long piid,String inoutno) {
+    if (piid == null||inoutno==null){
+        return null;
+    }
+    StringBuilder sql = new StringBuilder("INSERT INTO ");
+    StringBuilder values = new StringBuilder(" VALUES (");
+
+    sql.append(masterCode).append(".prodiowms (");
+    sql.append("piid, "); values.append(piid).append(", ");
+    sql.append("piinoutno, "); values.append("'").append(inoutno).append("', ");
+    sql.append("entryOrderCode, "); values.append("'").append(StringUtil.nvl(entryOrder.getEntryOrderCode(),"")).append("', ");
+    sql.append("ownerCode, "); values.append("'").append(StringUtil.nvl(entryOrder.getOwnerCode(),"")).append("', ");
+    sql.append("warehouseCode, "); values.append("'").append(StringUtil.nvl(entryOrder.getWarehouseCode(),"")).append("', ");
+    sql.append("entryOrderId, "); values.append("'").append(StringUtil.nvl(entryOrder.getEntryOrderId(),"")).append("', ");
+    sql.append("entryOrderType, "); values.append("'").append(StringUtil.nvl(entryOrder.getEntryOrderType(),"")).append("', ");
+    sql.append("outBizCode, "); values.append("'").append(StringUtil.nvl(entryOrder.getOutBizCode(),"")).append("', ");
+    sql.append("confirmType, "); values.append(StringUtil.nvl(entryOrder.getConfirmType(),"0")).append(", ");
+    sql.append("status, "); values.append("'").append(StringUtil.nvl(entryOrder.getStatus(),"")).append("', ");
+    sql.append("orderFinishedTime, ");
+        values.append((StringUtil.hasText(entryOrder.getOrderFinishedTime())?"to_date('"+entryOrder.getOrderFinishedTime()+"','yyyy-mm-dd hh24:mi:ss'),":"")) ;
+    sql.append("receiver, "); values.append("'").append(StringUtil.nvl(entryOrder.getReceiver(),"")).append("', ");
+    sql.append("remark, "); values.append("'").append(StringUtil.nvl(entryOrder.getRemark(),"")).append("', ");
+    sql.append("userDefined1, "); values.append("'").append(StringUtil.nvl(entryOrder.getUserDefined1(),"")).append("', ");
+    sql.append("userDefined2, "); values.append("'").append(StringUtil.nvl(entryOrder.getUserDefined2(),"")).append("', ");
+    sql.append("userDefined3, "); values.append("'").append(StringUtil.nvl(entryOrder.getUserDefined3(),"")).append("', ");
+    sql.append("userDefined4 "); values.append("'").append(StringUtil.nvl(entryOrder.getUserDefined4(),"")).append("'");
+
+    sql.append(")").append(values).append(")");
+    return sql.toString();
+}
+
+public List<String> getGenerateLinesSql(String masterCode,Long piId) {
+    List<String> sqls = new ArrayList<>();
+    for (OrderLines.OrderLine line : orderLines.getOrderLine()) {
+        sqls.add(getGenerateLinesSql(masterCode,piId,line));
+        for (int i = 0; i < line.getBatchs().getBatch().size(); i++) {
+            OrderLines.OrderLine.Batchs.Batch batch = line.getBatchs().getBatch().get(i);
+            sqls.add(getGenerateBatchsSql(masterCode,piId,line.getLineNo(),(i+1),batch));
+        }
+    }
+    return sqls;
+}
+    public String getGenerateLinesSql(String masterCode,Long piid,OrderLines.OrderLine line) {
+        StringBuilder sql = new StringBuilder();
+        sql.append("MERGE INTO ").append(masterCode).append(".prodiowms_Lines wmsl USING (")
+            .append("SELECT ")
+                .append(piid).append(" PIID, ")
+                .append(line.getLineNo()).append(" LINENO, ")
+                .append("'").append(line.getItemCode()).append("' ITEMCODE, ")
+                .append("'").append(line.getItemId()).append("' ITEMID, ")
+                .append("'").append(StringUtil.nvl(line.getPackUom(),"")).append("' PACKUOM, ")
+                .append("'").append(StringUtil.nvl(line.getPlanQty(),"")).append("' PLANQTY, ")
+                .append(StringUtil.nvl(line.getActualQty(),"0")).append(" ACTUALQTY, ")
+                .append(StringUtil.nvl(line.getActualPackUomQty(),"0")).append(" ACTUALPACKUOMQTY, ")
+                .append(StringUtil.nvl(line.getRejectQty(),"0")).append(" REJECTQTY, ")
+                .append("'").append(StringUtil.nvl(line.getRejectReason(),"")).append("' REJECTREASON, ")
+                .append("'").append(StringUtil.nvl(line.getSerialno(),"")).append("' SERIALNO, ")
+                .append("'").append(StringUtil.nvl(line.getCustomField1(),"")).append("' CUSTOMFIELD1, ")
+                .append("'").append(StringUtil.nvl(line.getCustomField2(),"")).append("' CUSTOMFIELD2, ")
+                .append("'").append(StringUtil.nvl(line.getCustomField3(),"")).append("' CUSTOMFIELD3, ")
+                .append("'").append(StringUtil.nvl(line.getCustomField4(),"")).append("' CUSTOMFIELD4, ")
+                .append("'").append(StringUtil.nvl(line.getCustomField5(),"")).append("' CUSTOMFIELD5, ")
+                .append("'").append(StringUtil.nvl(line.getCustomField6(),"")).append("' CUSTOMFIELD6, ")
+                .append("'").append(StringUtil.nvl(line.getCustomField7(),"")).append("' CUSTOMFIELD7, ")
+                .append("'").append(StringUtil.nvl(line.getCustomField8(),"")).append("' CUSTOMFIELD8 ")
+                .append("FROM dual) doc ON (wmsl.PL_PIID = doc.PIID AND wmsl.LINENO = doc.LINENO AND wmsl.ITEMCODE = doc.ITEMCODE) ")
+                .append("WHEN MATCHED THEN UPDATE SET ")
+                .append("wmsl.ACTUALQTY = doc.ACTUALQTY, ")
+                .append("wmsl.ACTUALPACKUOMQTY = doc.ACTUALPACKUOMQTY, ")
+                .append("wmsl.REJECTQTY = doc.REJECTQTY, ")
+                .append("wmsl.REJECTREASON = doc.REJECTREASON, ")
+                .append("wmsl.SERIALNO = doc.SERIALNO, ")
+                .append("wmsl.CUSTOMFIELD1 = doc.CUSTOMFIELD1, ")
+                .append("wmsl.CUSTOMFIELD2 = doc.CUSTOMFIELD2, ")
+                .append("wmsl.CUSTOMFIELD3 = doc.CUSTOMFIELD3, ")
+                .append("wmsl.CUSTOMFIELD4 = doc.CUSTOMFIELD4, ")
+                .append("wmsl.CUSTOMFIELD5 = doc.CUSTOMFIELD5, ")
+                .append("wmsl.CUSTOMFIELD6 = doc.CUSTOMFIELD6, ")
+                .append("wmsl.CUSTOMFIELD7 = doc.CUSTOMFIELD7, ")
+                .append("wmsl.CUSTOMFIELD8 = doc.CUSTOMFIELD8 ")
+                .append("WHEN NOT MATCHED THEN INSERT (PL_PIID, LINENO, ITEMCODE, ITEMID, PACKUOM, PLANQTY, ACTUALQTY, ACTUALPACKUOMQTY, REJECTQTY, REJECTREASON, SERIALNO, ")
+                .append("CUSTOMFIELD1, CUSTOMFIELD2, CUSTOMFIELD3, CUSTOMFIELD4, CUSTOMFIELD5, CUSTOMFIELD6, CUSTOMFIELD7, CUSTOMFIELD8) ")
+                .append("VALUES (doc.PIID, doc.LINENO, doc.ITEMCODE, doc.ITEMID, doc.PACKUOM, doc.PLANQTY, doc.ACTUALQTY, doc.ACTUALPACKUOMQTY, ")
+                .append("doc.REJECTQTY, doc.REJECTREASON, doc.SERIALNO, doc.CUSTOMFIELD1, doc.CUSTOMFIELD2, doc.CUSTOMFIELD3, doc.CUSTOMFIELD4, doc.CUSTOMFIELD5, ")
+                .append("doc.CUSTOMFIELD6, doc.CUSTOMFIELD7, doc.CUSTOMFIELD8)");
+        return sql.toString();
+    }
+
+    public String getGenerateBatchsSql(String masterCode,Long piid,Integer lineNo,Integer detno,OrderLines.OrderLine.Batchs.Batch batch) {
+        StringBuilder sql = new StringBuilder();
+        sql.append("INSERT INTO ").append(masterCode)
+        .append(".prodiowms_batchs(PB_PIID, PD_DETNO, LINENO, ACTUALQTY, ACTUALPACKUOMQTY, INVENTORYTYPE, VIRTUALWAREHOUSE, PRODUCTDATE, EXPIREDATE, BATCHCODE, STOCKINDATE, USERDEFINED1, USERDEFINED2, USERDEFINED3, USERDEFINED4, LPN) VALUES(");
+        // 添加字段值
+        sql.append(piid).append(", ");
+        sql.append(detno).append(", "); // PD_DETNO
+        sql.append(lineNo).append(", "); // LINENO
+        sql.append(StringUtil.nvl(batch.getActualQty(), "0")).append(", ");
+        sql.append(StringUtil.nvl(batch.getActualPackUomQty(), "0")).append(", ");
+        sql.append("'").append(StringUtil.nvl(batch.getInventoryType(), "")).append("', ");
+        sql.append("'").append(StringUtil.nvl(batch.getVirtualWarehouse(), "")).append("', ");
+        if(StringUtil.hasText(batch.getProductDate())){
+            sql.append("to_date('").append(batch.getProductDate()).append("','yyyy-mm-dd hh24:mi:ss'), ");
+        }else {
+            sql.append("null, ");
+        }
+        if(StringUtil.hasText(batch.getExpireDate())){
+            sql.append("to_date('").append(batch.getExpireDate()).append("','yyyy-mm-dd hh24:mi:ss'), ");
+        }else {
+            sql.append("null, ");
+        }
+        sql.append("'").append(StringUtil.nvl(batch.getBatchCode(), "")).append("', ");
+        if(StringUtil.hasText(batch.getStockinDate())){
+            sql.append("to_date('").append(batch.getStockinDate()).append("','yyyy-mm-dd hh24:mi:ss'), ");
+        }else {
+            sql.append("null, ");
+        }
+        sql.append("'").append(StringUtil.nvl(batch.getUserDefined1(), "")).append("', ");
+        sql.append("'").append(StringUtil.nvl(batch.getUserDefined2(), "")).append("', ");
+        sql.append("'").append(StringUtil.nvl(batch.getUserDefined3(), "")).append("', ");
+        sql.append("'").append(StringUtil.nvl(batch.getUserDefined4(), "")).append("', ");
+        sql.append("'").append(StringUtil.nvl(batch.getLpn(), "")).append("'");
+        sql.append(")");
+        return sql.toString();
+    }
+}

+ 19 - 0
src/main/java/com/uas/eis/exception/ApiSystemException.java

@@ -1,6 +1,7 @@
 package com.uas.eis.exception;
 
 import com.uas.eis.sdk.entity.ApiResult;
+import com.uas.eis.sdk.entity.WMSApiResult;
 
 /**
  * 系统程序执行异常
@@ -16,6 +17,7 @@ public class ApiSystemException extends RuntimeException {
 	private static final long serialVersionUID = 4218425517031998401L;
 
 	private ApiResult apiResult;
+	private WMSApiResult wmsApiResult;
 
 	public ApiSystemException() {
 	}
@@ -24,6 +26,15 @@ public class ApiSystemException extends RuntimeException {
 		super(paramString);
 	}
 
+	public ApiSystemException(WMSApiResult wmsApiResult) {
+		super(wmsApiResult.getMessage());
+		this.wmsApiResult = wmsApiResult;
+	}
+	public ApiSystemException(WMSApiResult wmsApiResult, Throwable paramThrowable) {
+		super(wmsApiResult.getMessage(), paramThrowable);
+		this.wmsApiResult = wmsApiResult;
+	}
+
 	public ApiSystemException(ApiResult apiResult) {
 		super(apiResult.getMessage());
 		this.apiResult = apiResult;
@@ -46,4 +57,12 @@ public class ApiSystemException extends RuntimeException {
 	public void setApiResult(ApiResult apiResult) {
 		this.apiResult = apiResult;
 	}
+
+	public WMSApiResult getWmsApiResult() {
+		return wmsApiResult;
+	}
+
+	public void setWmsApiResult(WMSApiResult wmsApiResult) {
+		this.wmsApiResult = wmsApiResult;
+	}
 }

+ 17 - 8
src/main/java/com/uas/eis/exception/ExceptionHandlerAdvice.java

@@ -2,6 +2,7 @@ package com.uas.eis.exception;
 
 import com.uas.eis.entity.ErrorMessage;
 import com.uas.eis.sdk.entity.ApiResult;
+import com.uas.eis.sdk.entity.WMSApiResult;
 import org.apache.log4j.Logger;
 import org.springframework.http.HttpStatus;
 import org.springframework.ui.ModelMap;
@@ -32,10 +33,11 @@ public class ExceptionHandlerAdvice {
 		ModelMap map = new ModelMap();
 		//logger.error(ex);
 		ex.printStackTrace();
+		map.put("flag", "failure");
 		map.put("code", ErrorMessage.SYS_ILLEGAL.getCode());
 		map.put("message", StringUtils.isEmpty(ex.getMessage())?ErrorMessage.SYS_ILLEGAL.getMessage():ex.getMessage());
-		map.put("requestId",request.getHeader("RequestId"));
-		map.put("data",null);
+//		map.put("requestId",request.getHeader("RequestId"));
+//		map.put("data",null);
 		return map;
 	}
 
@@ -52,10 +54,11 @@ public class ExceptionHandlerAdvice {
 	public ModelMap handleSystemError(SystemException ex, HttpServletRequest request) {
 		ModelMap map = new ModelMap();
 		ApiResult apiResult = ex.getApiResult();
+		map.put("flag", "failure");
 		map.put("code", apiResult.getCode());
 		map.put("message",apiResult.getMessage());
-		map.put("requestId",apiResult.getRequestId());
-		map.put("data",apiResult.getData());
+//		map.put("requestId",apiResult.getRequestId());
+//		map.put("data",apiResult.getData());
 		return map;
 	}
 	
@@ -71,10 +74,16 @@ public class ExceptionHandlerAdvice {
 	public ModelMap handleApiSystemError(ApiSystemException ex, HttpServletRequest request) {
 		ModelMap map = new ModelMap();
 		ApiResult apiResult = ex.getApiResult();
-		map.put("code", apiResult.getCode());
-		map.put("message", apiResult.getMessage());
-		map.put("requestId",apiResult.getRequestId());
-		map.put("data",apiResult.getData());
+		if(apiResult!=null) {
+			map.put("code", apiResult.getCode());
+			map.put("message", apiResult.getMessage());
+			map.put("requestId",apiResult.getRequestId());
+			map.put("data",apiResult.getData());
+		}
+		WMSApiResult wmsApiResult = ex.getWmsApiResult();
+		if(wmsApiResult!=null){
+			map.put("response", wmsApiResult);
+		}
 		return map;
 	}
 

+ 9 - 0
src/main/java/com/uas/eis/sdk/entity/WMSApiResult.java

@@ -0,0 +1,9 @@
+package com.uas.eis.sdk.entity;
+
+import lombok.Data;
+@Data
+public class WMSApiResult {
+    private String flag = "success";
+    private String code = "200";
+    private String message = "success!";
+}

+ 17 - 0
src/main/java/com/uas/eis/service/ERPWMSService.java

@@ -0,0 +1,17 @@
+package com.uas.eis.service;
+
+
+
+import com.uas.eis.entity.vwms.req.BaseReq;
+import com.uas.eis.entity.vwms.req.IOConfirm;
+import com.uas.eis.sdk.entity.WMSApiResult;
+
+import java.util.Map;
+
+/**
+ * @author wuyx
+ * @email wuyx@usoftchina.com
+ */
+public interface ERPWMSService {
+    WMSApiResult IOConfirm(String method, BaseReq<IOConfirm> ioConfirmBaseReq);
+}

+ 67 - 0
src/main/java/com/uas/eis/service/Impl/ERPSWMServiceImpl.java

@@ -0,0 +1,67 @@
+package com.uas.eis.service.Impl;
+
+import com.alibaba.fastjson.JSON;
+import com.uas.eis.dao.BaseDao;
+import com.uas.eis.dao.SqlRowList;
+import com.uas.eis.entity.vwms.req.BaseReq;
+import com.uas.eis.entity.vwms.req.IOConfirm;
+import com.uas.eis.sdk.entity.WMSApiResult;
+import com.uas.eis.service.ERPWMSService;
+import com.uas.eis.utils.BaseUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+/**
+ * @author wuyx
+ * @email wuyx@usoftchina.com
+ */
+@Service
+public class ERPSWMServiceImpl implements ERPWMSService {
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    @Autowired
+    private BaseDao baseDao;
+
+    @Override
+    public WMSApiResult IOConfirm(String method, BaseReq<IOConfirm> ioConfirmBaseReq) {
+        WMSApiResult wmsApiResult = new WMSApiResult();
+        IOConfirm ioConfirm = ioConfirmBaseReq.getRequest();
+        IOConfirm.EntryOrder entryOrder = ioConfirm.getEntryOrder();
+        String masterName = ioConfirm.getMasterName();
+        String masterCode = baseDao.queryForObject("SELECT max(MA_USER) FROM DATACENTER_P.MASTER WHERE MA_ENABLE = 1 and MA_FUNCTION = ?",String.class,masterName);
+        if(masterCode == null){
+            wmsApiResult.setFlag("failure");
+            wmsApiResult.setCode("400");
+            wmsApiResult.setMessage("没有找到对应的账套");
+            return wmsApiResult;
+        }
+        logger.info("IOConfirm-Begin:method {} inoutno {}",method, entryOrder.getEntryOrderCode());
+        SqlRowList piMsg = baseDao.queryForRowSet("select pi_id,pi_inoutno from "+masterCode+".PRODINOUT WHERE PI_INOUTNO = '"+entryOrder.getEntryOrderCode()+"'");
+        if(!piMsg.next()){
+            wmsApiResult.setMessage("没有找到对应的入库单");
+            return wmsApiResult;
+        }
+        Long piId = piMsg.getGeneralLong("pi_id");
+        String inoutno = piMsg.getGeneralString("pi_inoutno");
+        if(piId == null){
+            wmsApiResult.setMessage("没有找到对应的入库单");
+            return wmsApiResult;
+        }
+        List<String> sqls = new ArrayList<>();
+        sqls.add(ioConfirm.getGenerateMainSql(masterCode,piId,inoutno));
+        sqls.addAll(ioConfirm.getGenerateLinesSql(masterCode,piId));
+        baseDao.execute(sqls);
+        //根据下载采集数据分配采集数并自动过账
+        String res = baseDao.callProcedure(masterCode+".DOCWMS_IO_CONFIRM",new Object[] { piId,null });
+        if (res != null && !res.trim().equals("")) {
+            logger.info("IOConfirm-Err: {}",res);
+        }
+        logger.info("IOConfirm-End:method {} inoutno {}",method, entryOrder.getEntryOrderCode());
+        return wmsApiResult;
+    }
+}

+ 14 - 10
src/main/java/com/uas/eis/service/Impl/ERPServiceImpl.java

@@ -878,17 +878,21 @@ public class ERPServiceImpl implements ERPService {
                 new BeanPropertyRowMapper<ProdInout>(ProdInout.class));
         ProdInout prodInOut = prodInOuts.get(0);
         if(!onlyMain){
-            List<Prodiodetail> details = baseDao.getJdbcTemplate().query(
-                    "select min(pd_id) pdId,min(pd_pdno) pdPdno,pd_prodcode pdProdcode,pr_detail pdProdname,pr_brand pdBrandName" +
-                            ",sum(nvl(pd_inqty,0)+nvl(pd_outqty,0)) pdQty" +
-                            ",pd_whcode pdWhcode,wh_description pdWhname,pd_description pdInBatch" +
-                            " from "+master+".prodiodetail LEFT JOIN "+master+".product on pr_code = pd_prodcode left join  "+master+".productbrand on pb_name = pr_brand " +
-                            " left join "+master+".warehouse on wh_Code = pd_whcode " +
-                            " where pd_piid = ? and pb_sendwms = -1 " +
-                            " group by pd_prodcode,pr_detail,pr_brand,pd_whcode,wh_description,pd_description" +
-                            " order by MIN(pd_pdno) ",
-                    new BeanPropertyRowMapper<Prodiodetail>(Prodiodetail.class), prodInOut.getPiId());
+            String detSql = "select pd_piid pdPiid,min(pd_id) pdId,min(pd_pdno) pdPdno,pd_prodcode pdProdcode,pr_detail pdProdname,pr_brand pdBrandName" +
+                    ",sum(nvl(pd_inqty,0)+nvl(pd_outqty,0)) pdQty" +
+                    ",pd_whcode pdWhcode,wh_description pdWhname,pd_description pdInBatch" +
+                    " from "+master+".prodiodetail LEFT JOIN "+master+".product on pr_code = pd_prodcode left join  "+master+".productbrand on pb_name = pr_brand " +
+                    " left join "+master+".warehouse on wh_Code = pd_whcode " +
+                    " where pd_piid = "+prodInOut.getPiId()+" and pb_sendwms = -1 " +
+                    " group by pd_piid,pd_prodcode,pr_detail,pr_brand,pd_whcode,wh_description,pd_description" +
+                    " order by MIN(pd_pdno) ";
+            List<Prodiodetail> details = baseDao.getJdbcTemplate().query(detSql,
+                    new BeanPropertyRowMapper<Prodiodetail>(Prodiodetail.class));
             prodInOut.setDetails(details);
+            //写入 prodiowms_Lines
+            baseDao.execute("delete from "+master+".prodiowms_lines where pl_piid = "+prodInOut.getPiId());
+            baseDao.execute("INSERT INTO "+master+".prodiowms_Lines(PL_ID, PL_PIID,LINENO, ITEMCODE, PLANQTY)" +
+                    "select prodiowms_Lines_seq.nextval,pdPiid,pdPdno,pdProdcode,pdQty from ("+detSql+") ");
         }
         return prodInOut;
     }

+ 5 - 0
src/main/resources/application.yml

@@ -8,3 +8,8 @@ spring:
             enabled: true
     message:
         encoding: UTF-8
+
+    servlet:
+        multipart:
+            max-file-size: 10MB
+            max-request-size: 10MB

+ 4 - 1
src/main/resources/token.properties

@@ -1,2 +1,5 @@
-SECURITY_KEY=435aMe9L5itTrckY35kfcOQvPkBGZtGo
 KEEP=86400000
+app_secret=E58F1B90BCD69FF7DFC7E9DA1831F532
+partner_id=HXK
+app_key=HXK0225
+customerId=HXK

+ 2 - 2
src/test/java/com/uas/eis/UasEisApplicationTests.java

@@ -21,7 +21,7 @@ public class UasEisApplicationTests {
 	public void testSendProd(){
 		// 设置测试数据
 		String master = "HUAXK";
-		String id = "100059574";
+		String id = "100047433";
 		String emCode = "test";
 		String caller = "test";
 		// 调用待测方法
@@ -38,7 +38,7 @@ public class UasEisApplicationTests {
 	@Test
 	public void testSendVend(){
 		String master = "HUAXK";
-		String id = "103917";
+		String id = "98660";
 		String emCode = "test";
 		String caller = "test";
 		Map<String, Object> result = erpService.sendVend(master, id, emCode,caller);