lbq
2 天以前 a0c27199b7e512dc4087b80e3808f5fb1a081f0d
openapi,外部接口更新
7个文件已修改
1个文件已添加
602 ■■■■■ 已修改文件
rsf-open-api/src/main/java/com/vincent/rsf/openApi/controller/phyz/ERPController.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-open-api/src/main/java/com/vincent/rsf/openApi/controller/phyz/MESController.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-open-api/src/main/java/com/vincent/rsf/openApi/entity/phyz/ErpReportParams.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-open-api/src/main/java/com/vincent/rsf/openApi/entity/phyz/Station.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/phyz/ErpReportService.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/phyz/impl/ErpReportServiceImpl.java 457 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/phyz/impl/MesReportServiceImpl.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-open-api/src/main/java/com/vincent/rsf/openApi/utils/SslUtils.java 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-open-api/src/main/java/com/vincent/rsf/openApi/controller/phyz/ERPController.java
@@ -7,7 +7,6 @@
import com.vincent.rsf.openApi.entity.dto.CommonResponse;
import com.vincent.rsf.openApi.entity.phyz.*;
import com.vincent.rsf.openApi.service.phyz.ErpReportService;
import com.vincent.rsf.server.manager.controller.params.AsnOrderAndItemsParams;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
@@ -28,6 +27,8 @@
@Api("银座新工厂(五期)ERP接口")
@Slf4j
public class ERPController {
    public static JSONArray map = new JSONArray();
    @Resource
    private ErpReportService erpReportService;
@@ -115,6 +116,9 @@
        JSONArray params = paramsFormat(objParams);
        List<Order> orderList = JSON.parseArray(params.toJSONString(), Order.class);
        // 数据处理,转发server
        for (Order order : orderList) {
            erpReportService.addOrderToServer(order);
        }
        return CommonResponse.ok();
    }
@@ -132,8 +136,6 @@
        JSONArray params = paramsFormat(objParams);
        List<Order> orderList = JSON.parseArray(params.toJSONString(), Order.class);
        // 数据处理,转发server
        AsnOrderAndItemsParams asnOrderAndItemsParams = new AsnOrderAndItemsParams();
        // asnOrder/items/save
        return CommonResponse.ok();
    }
@@ -179,7 +181,10 @@
                    "    \"stockOrgId\": \"ORG001\"\n" +
                    "  }\n" +
                    "]";
            return CommonResponse.ok(JSONArray.parseArray(x, InventoryDetails.class));
            if (map == null || map.isEmpty()) {
                map = JSON.parseArray(x);
            }
            return CommonResponse.ok(JSONArray.parseArray(map.toJSONString(), InventoryDetails.class));
        }
        InventoryQueryCondition condition = JSON.parseObject(params.toJSONString(), InventoryQueryCondition.class);
@@ -293,9 +298,9 @@
    // region 测试推送功能
    @ApiOperation("登录")
    @PostMapping("/loginBySign")
    public CommonResponse loginBySign(@RequestBody Object objParams) {
    public CommonResponse loginBySign() {
        try {
            erpReportService.loginBySign();
            return CommonResponse.ok(erpReportService.loginBySign());
        } catch (Exception e) {
            log.error("erp, loginBySign", e);
        }
@@ -306,7 +311,7 @@
    @PostMapping("/reportInOrOutBound")
    public CommonResponse reportInOrOutBound(@RequestBody Object objParams) {
        try {
            erpReportService.reportInOrOutBound(objParams);
            return erpReportService.reportInOrOutBound(objParams);
        } catch (Exception e) {
            log.error("erp, reportInOrOutBound", e);
        }
rsf-open-api/src/main/java/com/vincent/rsf/openApi/controller/phyz/MESController.java
@@ -2,6 +2,7 @@
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.vincent.rsf.framework.exception.CoolException;
import com.vincent.rsf.openApi.entity.dto.CommonResponse;
import com.vincent.rsf.openApi.entity.phyz.*;
@@ -38,7 +39,17 @@
            throw new CoolException("参数不能为空!!");
        }
        // 返回模拟数据
        if (SIMULATED_DATA_ENABLE.equals("0")) {
        if (SIMULATED_DATA_ENABLE.equals("1")) {
            JSONArray params = paramsFormat(objParams);
            List<MatPreparationOrder> orders = JSON.parseArray(params.toJSONString(), MatPreparationOrder.class);
            JSONArray array = ERPController.map;
            for (int i = 0; i < ERPController.map.size(); i++) {
                JSONObject obj = array.getJSONObject(i);
                obj.put("orderNo", orders.get(0).getOrderNo());
                obj.put("matNr", orders.get(0).getOrderItems().get(0).getMatNr());
            }
            ERPController.map = array;
            return CommonResponse.ok();
        }
@@ -55,7 +66,7 @@
            throw new CoolException("参数不能为空!!");
        }
        // 返回模拟数据
        if (SIMULATED_DATA_ENABLE.equals("0")) {
        if (SIMULATED_DATA_ENABLE.equals("1")) {
            return CommonResponse.ok();
        }
rsf-open-api/src/main/java/com/vincent/rsf/openApi/entity/phyz/ErpReportParams.java
@@ -1,5 +1,6 @@
package com.vincent.rsf.openApi.entity.phyz;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import lombok.Data;
@@ -20,6 +21,7 @@
    // 日期
    @JsonProperty("FDate")
    @JSONField(name = "FDate")
    private String FDate;
    // 单据类型,
@@ -28,22 +30,27 @@
    //“C”:生产退料单
    //“D”生产入库单
    @JsonProperty("F_OHDL_BillnoType")
    @JSONField(name = "F_OHDL_BillnoType")
    private String F_OHDL_BillnoType;
    // 库存组织{"FNumber": "100"}
    @JsonProperty("FStockOrgId")
    @JSONField(name = "FStockOrgId")
    private Object FStockOrgId;
    // 生产组织{"FNumber": "200"}
    @JsonProperty("FPrdOrgId")
    @JSONField(name = "FPrdOrgId")
    private Object FPrdOrgId;
    // 生产计划号
    @JsonProperty("F_OHDL_ProPlan")
    @JSONField(name = "F_OHDL_ProPlan")
    private String F_OHDL_ProPlan;
    // 单据体明细数据包
    @JsonProperty("FEntity")
    @JSONField(name = "FEntity")
    private List<FEntityItem> FEntity;
    // 单据体明细
@@ -51,54 +58,67 @@
        // 物料信息{"FNumber": ""}
        @JsonProperty("FMaterialId")
        @JSONField(name = "FMaterialId")
        private Object FMaterialId;
        // 计量单位信息{"FNumber": "PCS"}
        @JsonProperty("FUnitID")
        @JSONField(name = "FUnitID")
        private Object FUnitID;
        // 申请数量
        @JsonProperty("FAppQty")
        @JSONField(name = "FAppQty")
        private Double FAppQty;
        // 实际数量
        @JsonProperty("FActualQty")
        @JSONField(name = "FActualQty")
        private Double FActualQty;
        // 仓库信息{"FNumber": ""}
        @JsonProperty("FStockId")
        @JSONField(name = "FStockId")
        private Object FStockId;
        // 车间{"FNumber": ""}
        @JsonProperty("F_OHDL_BworkShop")
        @JSONField(name = "F_OHDL_BworkShop")
        private Object F_OHDL_BworkShop;
        // 托盘
        @JsonProperty("F_OHDL_Pallet")
        @JSONField(name = "F_OHDL_Pallet")
        private String F_OHDL_Pallet;
        // 接驳点位
        @JsonProperty("F_OHDL_ConPoint")
        @JSONField(name = "F_OHDL_ConPoint")
        private String F_OHDL_ConPoint;
        // 计划跟踪号
        @JsonProperty("F_OHDL_PlanNo")
        @JSONField(name = "F_OHDL_PlanNo")
        private String F_OHDL_PlanNo;
        // 生产订单编号
        @JsonProperty("F_OHDL_MONo")
        @JSONField(name = "F_OHDL_MONo")
        private String F_OHDL_MONo;
        // 生产订单ID
        @JsonProperty("F_OHDL_MOId")
        @JSONField(name = "F_OHDL_MOId")
        private String F_OHDL_MOId;
        // 生产订单行号
        @JsonProperty("F_OHDL_MOLine")
        @JSONField(name = "F_OHDL_MOLine")
        private String F_OHDL_MOLine;
        // 生产订单行ID
        @JsonProperty("F_OHDL_MOLineId")
        @JSONField(name = "F_OHDL_MOLineId")
        private String F_OHDL_MOLineId;
    }
rsf-open-api/src/main/java/com/vincent/rsf/openApi/entity/phyz/Station.java
@@ -44,4 +44,8 @@
    @JsonProperty("CreatedBy")
    @JSONField(name = "CreatedBy")
    private String createdBy;
    // 是否可用
    @JsonProperty("IsValid")
    @JSONField(name = "IsValid")
    private boolean isValid;
}
rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/phyz/ErpReportService.java
@@ -1,13 +1,17 @@
package com.vincent.rsf.openApi.service.phyz;
import com.alibaba.fastjson.JSONObject;
import com.vincent.rsf.openApi.entity.dto.CommonResponse;
import com.vincent.rsf.openApi.entity.phyz.Order;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
public interface ErpReportService {
    void loginBySign() throws UnsupportedEncodingException, NoSuchAlgorithmException;
    int addOrderToServer(Order order);
    JSONObject loginBySign() throws UnsupportedEncodingException, NoSuchAlgorithmException;
    CommonResponse reportInOrOutBound(Object params);
}
rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/phyz/impl/ErpReportServiceImpl.java
@@ -1,5 +1,6 @@
package com.vincent.rsf.openApi.service.phyz.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
@@ -8,25 +9,43 @@
import com.fasterxml.jackson.databind.cfg.CoercionInputShape;
import com.vincent.rsf.framework.exception.CoolException;
import com.vincent.rsf.openApi.config.PlatformProperties;
import com.vincent.rsf.openApi.entity.constant.WmsConstant;
import com.vincent.rsf.openApi.entity.dto.CommonResponse;
import com.vincent.rsf.openApi.entity.phyz.ErpReportParams;
import com.vincent.rsf.openApi.entity.phyz.Order;
import com.vincent.rsf.openApi.service.WmsErpService;
import com.vincent.rsf.openApi.service.phyz.ErpReportService;
import com.vincent.rsf.openApi.utils.ParamsMapUtils;
import com.vincent.rsf.openApi.utils.SslUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.client.config.RequestConfig;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.lang.reflect.Field;
import java.security.cert.X509Certificate;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Objects;
import java.util.*;
@Slf4j
@Service
@@ -34,8 +53,14 @@
    private static String ERP_REPORT_URL;
    private CloseableHttpClient httpClient;
    @Resource
    private PlatformProperties.ErpApi erpApi;
    @Resource
    private PlatformProperties.WmsApi wmsApi;
    @Resource
    private WmsErpService wmsErpService;
    @Resource
    private RestTemplate restTemplate;
@@ -47,16 +72,88 @@
    // 登录参数依次为账套ID、用户名、应用ID、时间戳、签名信息、语言ID
    public void loginBySign() throws UnsupportedEncodingException, NoSuchAlgorithmException {
        String url = ERP_REPORT_URL + "/Kingdee.BOS.WebApi.ServicesStub.AuthService.LoginBySign.common.kdsvc";
        JSONObject params = new JSONObject();
        params.put("parameters", loginParams());
        JSONObject result = postRequest(url, params, false);
    public int addOrderToServer(Order order) {
        if (Objects.isNull(order.getOrderNo()) || order.getOrderNo().isEmpty()) {
            throw new CoolException("订单号不能为空!!");
        }
        /**WMS基础配置链接*/
        String wmsUrl = wmsApi.getHost() + ":" + wmsApi.getPort() + WmsConstant.MODIFY_ORDER_DETLS;
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json");
        headers.add("api-version", "v2.0");
        List<Map<String, Object>> maps = new ArrayList<>();
        Map<String, Object> mapParams = new HashMap<>();
//        mapParams.put("orderNo", params.getOrderNo());
//        mapParams.put("anfme", params.getAnfme());
//        mapParams.put("type", params.getType());
//        mapParams.put("wkType", params.getWkType());
//        mapParams.put("exceStatus", params.getExceStatus());
//        mapParams.put("orderItems", params.getOrderItems());
//        maps.add(mapParams);
        JSONObject params = JSONObject.parseObject(JSON.toJSONString(order));
        JSONObject mappedData = ParamsMapUtils.apiMaps("erp", "orderId", params);
        mapParams = objectToMap(mappedData);
        maps.add(mapParams);
        log.info("修改订单信息及状态: {}, 请求参数: {}", wmsUrl, JSONArray.toJSONString(maps));
        HttpEntity<List<Map<String, Object>>> httpEntity = new HttpEntity<>(maps, headers);
        // asnOrder/items/save
        ResponseEntity<String> exchange = restTemplate.exchange(wmsUrl, HttpMethod.POST, httpEntity, String.class);
        log.info("订单修改返回结果: {}", exchange);
        if (Objects.isNull(exchange.getBody())) {
            throw new CoolException("查询失败!!");
        } else {
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.coercionConfigDefaults().setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsEmpty);
            try {
                CommonResponse result = objectMapper.readValue(exchange.getBody(), CommonResponse.class);
                if (result.getCode() == 200) {
//                    JSONObject object = JSONObject.parseObject(JSONObject.toJSONString(result.getData()));
                    return 1;
                } else {
                    return 0;
//                    throw new CoolException("查询失败!!");
                }
            } catch (JsonProcessingException e) {
                return 0;
//                throw new CoolException(e.getMessage());
            }
    }
    // 入/出库任务完成上报
//        ErpOpParams erpOpParams = new ErpOpParams();
//        erpOpParams.set
//
//        wmsErpService.updateOrderDetl(ErpOpParams params);
//        CommonResponse updateOrderDetl()
//
//        asnOrderService.saveOrderAndItems(params, getLoginUserId());
    }
    public static Map<String, Object> objectToMap(Object obj) {
        Map<String, Object> map = new HashMap<>();
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true); // 设置私有字段也可以访问
            try {
                map.put(field.getName(), field.get(obj));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return map;
    }
    /**
     * 入/出库任务完成上报
     *
     * @param params
     * @return
     */
    public CommonResponse reportInOrOutBound(Object params) {
        if (Objects.isNull(params)) {
            throw new CoolException("入/出库任务信息参数不能为空!!");
@@ -64,12 +161,131 @@
        // TODO:参数转换
        ErpReportParams erpReportParams = new ErpReportParams();
        if (params instanceof ErpReportParams) {
        erpReportParams = (ErpReportParams) params;
        } else if (params instanceof java.util.Map) {
            java.util.Map<String, Object> paramMap = (java.util.Map<String, Object>) params;
        String erpUrl = ERP_REPORT_URL + "/Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Save.common.kdsvc";
        log.info("Erp入/出库任务完成上报: {}, 请求参数: {}", erpUrl, JSONObject.toJSONString(erpReportParams));
            // 设置基本属性
            erpReportParams.setFDate((String) paramMap.get("FDate"));
            erpReportParams.setF_OHDL_BillnoType((String) paramMap.get("F_OHDL_BillnoType"));
            erpReportParams.setFStockOrgId(paramMap.get("FStockOrgId"));
            erpReportParams.setFPrdOrgId(paramMap.get("FPrdOrgId"));
            erpReportParams.setF_OHDL_ProPlan((String) paramMap.get("F_OHDL_ProPlan"));
            // 处理FEntity列表
            Object fEntityObj = paramMap.get("FEntity");
            if (fEntityObj instanceof java.util.List) {
                java.util.List<?> fEntityList = (java.util.List<?>) fEntityObj;
                java.util.List<ErpReportParams.FEntityItem> entityItems = new java.util.ArrayList<>();
                for (Object item : fEntityList) {
                    if (item instanceof java.util.Map) {
                        java.util.Map<String, Object> itemMap = (java.util.Map<String, Object>) item;
                        ErpReportParams.FEntityItem entityItem = new ErpReportParams.FEntityItem();
                        // 使用反射设置属性值
        try {
            JSONObject jsonObject = postRequest(erpUrl, erpReportParams, true);
                            // 使用反射直接访问字段并设置值
                            java.lang.reflect.Field field;
                            field = entityItem.getClass().getDeclaredField("FMaterialId");
                            field.setAccessible(true);
                            field.set(entityItem, itemMap.get("FMaterialId"));
                            field = entityItem.getClass().getDeclaredField("FUnitID");
                            field.setAccessible(true);
                            field.set(entityItem, itemMap.get("FUnitID"));
                            // 处理数值类型
                            Object fAppQty = itemMap.get("FAppQty");
                            if (fAppQty instanceof Number) {
                                field = entityItem.getClass().getDeclaredField("FAppQty");
                                field.setAccessible(true);
                                field.set(entityItem, ((Number) fAppQty).doubleValue());
                            } else if (fAppQty != null) {
                                field = entityItem.getClass().getDeclaredField("FAppQty");
                                field.setAccessible(true);
                                field.set(entityItem, Double.parseDouble(fAppQty.toString()));
                            }
                            Object fActualQty = itemMap.get("FActualQty");
                            if (fActualQty instanceof Number) {
                                field = entityItem.getClass().getDeclaredField("FActualQty");
                                field.setAccessible(true);
                                field.set(entityItem, ((Number) fActualQty).doubleValue());
                            } else if (fActualQty != null) {
                                field = entityItem.getClass().getDeclaredField("FActualQty");
                                field.setAccessible(true);
                                field.set(entityItem, Double.parseDouble(fActualQty.toString()));
                            }
                            field = entityItem.getClass().getDeclaredField("FStockId");
                            field.setAccessible(true);
                            field.set(entityItem, itemMap.get("FStockId"));
                            field = entityItem.getClass().getDeclaredField("F_OHDL_BworkShop");
                            field.setAccessible(true);
                            field.set(entityItem, itemMap.get("F_OHDL_BworkShop"));
                            field = entityItem.getClass().getDeclaredField("F_OHDL_Pallet");
                            field.setAccessible(true);
                            field.set(entityItem, (String) itemMap.get("F_OHDL_Pallet"));
                            field = entityItem.getClass().getDeclaredField("F_OHDL_ConPoint");
                            field.setAccessible(true);
                            field.set(entityItem, (String) itemMap.get("F_OHDL_ConPoint"));
                            field = entityItem.getClass().getDeclaredField("F_OHDL_PlanNo");
                            field.setAccessible(true);
                            field.set(entityItem, (String) itemMap.get("F_OHDL_PlanNo"));
                            field = entityItem.getClass().getDeclaredField("F_OHDL_MONo");
                            field.setAccessible(true);
                            field.set(entityItem, (String) itemMap.get("F_OHDL_MONo"));
                            field = entityItem.getClass().getDeclaredField("F_OHDL_MOId");
                            field.setAccessible(true);
                            field.set(entityItem, (String) itemMap.get("F_OHDL_MOId"));
                            field = entityItem.getClass().getDeclaredField("F_OHDL_MOLine");
                            field.setAccessible(true);
                            field.set(entityItem, (String) itemMap.get("F_OHDL_MOLine"));
                            field = entityItem.getClass().getDeclaredField("F_OHDL_MOLineId");
                            field.setAccessible(true);
                            field.set(entityItem, (String) itemMap.get("F_OHDL_MOLineId"));
                        } catch (Exception e) {
                            log.error("设置FEntityItem属性时发生错误: " + e.getMessage());
                            throw new CoolException("设置FEntityItem属性失败: " + e.getMessage());
                        }
                        entityItems.add(entityItem);
                    } else if (item instanceof ErpReportParams.FEntityItem) {
                        entityItems.add((ErpReportParams.FEntityItem) item);
                    }
                }
                erpReportParams.setFEntity(entityItems);
            }
        } else {
            throw new CoolException("无法处理的参数类型: " + params.getClass().getName());
        }
        JSONObject model = new JSONObject();
        model.put("Model", erpReportParams);
        JSONObject data = new JSONObject();
        data.put("data", model);
        data.put("formid", "ke3d5adc0bbe64eceafd5891400adf40e");
        try {
            JSONObject loginResult = loginBySign();
            if (loginResult.getInteger("LoginResultType") == 1) {
                String erpUrl = ERP_REPORT_URL + "/Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Save.common.kdsvc";
                log.info("Erp入/出库任务完成上报: {}, 请求参数: {}", erpUrl, JSONObject.toJSONString(data));
                String result2 = httpPostExample(erpUrl, data.toJSONString());
                JSONObject jsonObject = JSONObject.parseObject(result2);
                log.info("Erp入/出库任务完成上报返回" + jsonObject.toJSONString());
            boolean sendSuccess = jsonObject.getJSONObject("Result").getJSONObject("ResponseStatus").getBoolean("IsSuccess");
            // TODO:转换后返回
@@ -83,10 +299,34 @@
                }
                return CommonResponse.error(errorMsg);
            }
        } catch (Exception e) {
            log.error("Erp入/出库任务上报响应失败", e);
            throw new CoolException("Erp解析响应失败:" + e.getMessage());
        }
        } catch (Exception e) {
            log.error("loginBySign", e);
        }
//        try {
//            JSONObject jsonObject = postRequest(erpUrl, data, true);
//            log.info(jsonObject.toJSONString());
//            boolean sendSuccess = jsonObject.getJSONObject("Result").getJSONObject("ResponseStatus").getBoolean("IsSuccess");
//
//            // TODO:转换后返回
//            if (sendSuccess) {
//                return CommonResponse.ok();
//            } else {
//                JSONArray errors = jsonObject.getJSONObject("Result").getJSONObject("ResponseStatus").getJSONArray("Errors");
//                String errorMsg = "";
//                for (int i = 0; i < errors.size(); i++) {
//                    errorMsg += errors.getJSONObject(i).getString("Message") + " ";
//                }
//                return CommonResponse.error(errorMsg);
//            }
//        } catch (Exception e) {
//            log.error("Erp入/出库任务上报响应失败", e);
//            throw new CoolException("Erp解析响应失败:" + e.getMessage());
//        }
        return null;
    }
@@ -96,10 +336,28 @@
    // 盘点结果上报
    // region 登录
    /**
     * 登录,登录参数依次为账套ID、用户名、应用ID、时间戳、签名信息、语言ID
     *
     * @throws UnsupportedEncodingException
     * @throws NoSuchAlgorithmException
     */
    public JSONObject loginBySign() throws UnsupportedEncodingException, NoSuchAlgorithmException {
        String url = ERP_REPORT_URL + "/Kingdee.BOS.WebApi.ServicesStub.AuthService.LoginBySign.common.kdsvc";
        JSONObject params = new JSONObject();
        params.put("parameters", loginParams());
        String result = httpPostExample(url, params.toJSONString());
        return JSONObject.parseObject(result);
    }
    /**
     * 登录参数整理
     *
     * @return
     * @throws UnsupportedEncodingException
     * @throws NoSuchAlgorithmException
     */
    private Object[] loginParams() throws UnsupportedEncodingException, NoSuchAlgorithmException {
        //时间戳
        long timestamp = System.currentTimeMillis() / 1000;
@@ -137,16 +395,16 @@
        }
        return hashString.toString();
    }
    // endregion
    /**
     * 通用HTTP POST请求方法
     *
     * @param url 请求URL
     * @param params 请求参数
     * @param needToken 是否需要token认证
     * @return 响应结果
     */
    public JSONObject postRequest(String url, Object params, boolean needToken) {
    public JSONObject postRequest(String url, Object params) {
        if (StringUtils.isBlank(url)) {
            throw new CoolException("请求URL不能为空!!");
        }
@@ -159,13 +417,21 @@
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json;charset=utf-8");
        if (needToken) {
//            String token = getToken();
//            headers.add("Authorization", "Bearer " + token);
        }
        HttpEntity<Object> httpEntity = new HttpEntity<>(params, headers);
        ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
        // 创建支持忽略SSL证书验证的RestTemplate
        RestTemplate sslRestTemplate = SslUtils.createIgnoreSSLRestTemplate();
        // 设置错误处理器,不抛出异常,而是返回响应体
        sslRestTemplate.setErrorHandler(new org.springframework.web.client.DefaultResponseErrorHandler() {
            @Override
            public boolean hasError(ClientHttpResponse response) throws IOException {
                // 不管状态码如何,都不视为错误
                return false;
            }
        });
        ResponseEntity<String> exchange = sslRestTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
        log.info("Erp POST请求响应结果: {}", exchange);
        if (Objects.isNull(exchange.getBody())) {
@@ -181,4 +447,143 @@
            throw new CoolException("Erp解析响应失败:" + e.getMessage());
        }
    }
    /**
     * HTTP POST请求示例 - 支持HTTPS
     *
     * @param url    请求URL
     * @param params 请求参数
     * @return 响应结果
     */
    public String httpPostExample(String url, String params) {
        if (httpClient == null) {
            httpClient = createHttpsClient();
        }
        HttpPost httpPost = new HttpPost(url);
        try {
            StringEntity entity = new StringEntity(params, "UTF-8");
            httpPost.setEntity(entity);
            httpPost.setHeader("Content-type", "application/json;charset=utf-8");
            httpPost.setHeader("Accept", "application/json");
            return EntityUtils.toString(httpClient.execute(httpPost).getEntity());
        } catch (Exception e) {
            log.error("HTTP POST请求失败: {}", e.getMessage(), e);
            throw new CoolException("HTTP POST请求失败: " + e.getMessage());
        }
    }
    /**
     * 使用RestTemplate的HTTPS POST请求示例
     *
     * @param url    请求URL
     * @param params 请求参数
     * @return 响应结果
     */
    public String httpsPostWithRestTemplate(String url, String params) {
        try {
            log.info("HTTPS POST请求: {}, 请求参数: {}", url, params);
            HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Type", "application/json;charset=utf-8");
            headers.add("Accept", "application/json");
            HttpEntity<String> httpEntity = new HttpEntity<>(params, headers);
            // 使用项目中已有的SSL工具类创建忽略SSL证书验证的RestTemplate
            RestTemplate sslRestTemplate = SslUtils.createIgnoreSSLRestTemplate();
            // 设置错误处理器,不抛出异常,而是返回响应体
            sslRestTemplate.setErrorHandler(new org.springframework.web.client.DefaultResponseErrorHandler() {
                @Override
                public boolean hasError(ClientHttpResponse response) throws IOException {
                    // 不管状态码如何,都不视为错误
                    return false;
                }
            });
            ResponseEntity<String> exchange = sslRestTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
            log.info("HTTPS POST请求响应结果: {}", exchange);
            if (Objects.isNull(exchange.getBody())) {
                throw new CoolException("请求失败!!");
            }
            return exchange.getBody();
        } catch (Exception e) {
            log.error("HTTPS POST请求失败: {}", e.getMessage(), e);
            throw new CoolException("HTTPS POST请求失败: " + e.getMessage());
        }
    }
    /**
     * 创建支持HTTPS的HttpClient
     *
     * @return CloseableHttpClient实例
     */
    private CloseableHttpClient createHttpsClient() {
        try {
            // 创建信任所有证书的TrustManager
            TrustManager[] trustAllCerts = new TrustManager[] {
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() { return null; }
                    public void checkClientTrusted(X509Certificate[] certs, String authType) { }
                    public void checkServerTrusted(X509Certificate[] certs, String authType) { }
                }
            };
            // 初始化SSLContext
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
            // 创建SSL连接管理器
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                    sslContext,
                    (hostname, session) -> true // 允许所有主机名
            );
            // 创建HttpClientBuilder并设置SSL配置
            RequestConfig config = RequestConfig.custom()
                    .setConnectTimeout(30000)  // 连接超时时间
                    .setSocketTimeout(60000)   // 读取超时时间
                    .build();
            return HttpClients.custom()
                    .setSSLSocketFactory(sslsf)
                    .setDefaultRequestConfig(config)
                    .build();
        } catch (Exception e) {
            log.error("创建HTTPS客户端失败: {}", e.getMessage(), e);
            return HttpClients.createDefault(); // 回退到默认客户端
        }
    }
//    /**
//     * 示例:如何使用HTTPS POST方法
//     *
//     * @param url    目标URL
//     * @param jsonData JSON数据
//     * @return 响应结果
//     */
//    public String exampleUsage(String url, String jsonData) {
//        log.info("开始调用HTTPS POST请求示例");
//
//        try {
//            // 方法1: 使用Apache HttpClient
//            String result1 = httpPostExample(url, jsonData);
//            log.info("使用HttpClient的POST请求结果: {}", result1);
//
//            // 方法2: 使用RestTemplate
//            String result2 = httpsPostWithRestTemplate(url, jsonData);
//            log.info("使用RestTemplate的POST请求结果: {}", result2);
//
//            // 根据实际需要选择返回结果
//            return result1;
//        } catch (Exception e) {
//            log.error("HTTPS POST请求示例执行失败: {}", e.getMessage(), e);
//            throw e;
//        }
//    }
}
rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/phyz/impl/MesReportServiceImpl.java
@@ -167,6 +167,7 @@
                    station.setProductionLineCode((String) map.get("ProductionLineCode"));
                    station.setProductionLineName((String) map.get("ProductionLineName"));
                    station.setCreatedBy((String) map.get("CreatedBy"));
                    station.setValid(true);
                    stations.add(station);
                } else if (obj instanceof Station) {
                    stations.add((Station) obj);
@@ -258,7 +259,7 @@
        log.info("Mes POST请求: {}, 请求参数: {}", url, JSONObject.toJSONString(params));
        
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json;charset=utf-8");    //
        headers.add("Content-Type", "application/json;charset=utf-8");
        headers.add("Authorization", "Bearer " + token);
        
        HttpEntity<Object> httpEntity = new HttpEntity<>(params, headers);
rsf-open-api/src/main/java/com/vincent/rsf/openApi/utils/SslUtils.java
New file
@@ -0,0 +1,78 @@
package com.vincent.rsf.openApi.utils;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import javax.net.ssl.*;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
/**
 * SSL工具类,用于创建忽略SSL证书验证的RestTemplate
 */
public class SslUtils {
    /**
     * 创建忽略SSL证书验证的RestTemplate
     *
     * @return RestTemplate实例
     */
    public static RestTemplate createIgnoreSSLRestTemplate() {
        try {
            // 创建信任所有证书的TrustManager
            TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        public X509Certificate[] getAcceptedIssuers() {
                            return null;
                        }
                        public void checkClientTrusted(X509Certificate[] certs, String authType) {
                        }
                        public void checkServerTrusted(X509Certificate[] certs, String authType) {
                        }
                    }
            };
            // 安装信任所有证书的TrustManager
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
            // 创建HttpsURLConnection的工厂
            HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
            // 创建跳过主机名验证的HostnameVerifier
            HostnameVerifier allHostsValid = new HostnameVerifier() {
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            };
            // 安装跳过主机名验证的HostnameVerifier
            HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
            // 创建自定义的ClientHttpRequestFactory
            SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory() {
                @Override
                protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
                    if (connection instanceof HttpsURLConnection) {
                        ((HttpsURLConnection) connection).setSSLSocketFactory(sslContext.getSocketFactory());
                        ((HttpsURLConnection) connection).setHostnameVerifier(allHostsValid);
                    }
                    super.prepareConnection(connection, httpMethod);
                }
            };
            // 创建RestTemplate并设置工厂
            RestTemplate restTemplate = new RestTemplate(factory);
            return restTemplate;
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
            throw new RuntimeException("Failed to create SSL RestTemplate", e);
        }
    }
}