package com.cf.imes.module.executor.util.fileConversion.admin.api.webcad;//package com.cf.imes.module.executor.util.fileConversion.admin.api.webcad;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import com.cf.imes.framework.id.core.util.SnowflakeIdWorker3rd;
import com.cf.imes.module.executor.controller.admin.orderParts.vo.OrderPartsRemark;
import com.cf.imes.module.executor.controller.admin.plan.dto.Point;
import com.cf.imes.module.executor.dal.dataobject.goods.GoodsDO;
import com.cf.imes.module.executor.dal.dataobject.order.OrderDO;
import com.cf.imes.module.executor.dal.dataobject.orderBody.OrderBodyDO;
import com.cf.imes.module.executor.dal.dataobject.orderGroup.OrderGroupDO;
import com.cf.imes.module.executor.dal.dataobject.orderItem.OrderItemDO;
import com.cf.imes.module.executor.dal.dataobject.orderParts.OrderPartsDO;
import com.cf.imes.module.executor.dal.dataobject.plate.PlateDO;
import com.cf.imes.module.executor.dal.dataobject.rawgoods.RawGoodsDO;
import com.cf.imes.module.executor.enums.*;
import com.cf.imes.module.executor.util.deviseData.structure.*;
import com.cf.imes.module.system.api.dict.DictDataApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import jakarta.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.*;
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.ORDER_DETAIL_DATE_ERR;

/**
 * 实现数据格式转换
 * 使用自带id
 */
@Slf4j
@Component
public class ApiTypeRealize {

    @Resource
    private IdentifierGenerator identifierGenerator;

    @Resource
    private DictDataApi dictDataApi;

    @Resource
    private SnowflakeIdWorker3rd idWorker;

    @Resource
    private ApiDataAchieve apiDataAchieve;

    private static final int PARTS_PAGE_MAX = 100;

    private static final Integer X = 0;
    private static final Integer Y = 1;
    private static final Integer Z = 2;

    private static final Integer INDEX = 0;

    private static String PART_WIDTH = "width";
    private static String PART_LENGTH = "length";
    private static String PART_THICKNESS = "thickness";
    private static String PART_COLOR = "color";
    private static String PART_MATERIAL = "material";
    private static String PART_CATEGORY_ONE = "封边条";
    private static String PART_CATEGORY_TWO = "五金";
    private static String PART_CATEGORY_THREE = "组件";

    private static String GROUP_LINK_PLATE = "groupList";
    private static String BODY_PLATE_NUMBER = "totalPlateCountMapToBody";
    private static String BODY_IRREGULAR_PLATE_NUMBER = "irregularPlateCountMapToBody";
    private static String GROUP_PLATE_NUMBER  = "totalPlateCountMapToGroup";
    private static String GROUP_IRREGULAR_PLATE_NUMBER = "irregularPlateCountMapToGroup";
    private static String PLATE_DETAILS_REMARKS = "mapPlateDetailsRemarks";


    // api的转换信息获取
    public ApiDataTypeVo apiDataChange(String orderNo, Long orderId, Long organId) throws ExecutionException, InterruptedException {
        // token获取
        JSONObject oauth = apiDataAchieve.getApiToken(organId).get();
        String token = oauth.getJSONObject("info").getString("access_token");


        ConcurrentHashMap<String, CompletableFuture<ApiDataTypeVo>> results = new ConcurrentHashMap<>();

        // 添加各个API调用到映射中，并指定结果字段名
//        results.put("order", CompletableFuture.supplyAsync(() -> orderInfoChange(token, orderId, orderNo, organId)));
        results.put("good", CompletableFuture.supplyAsync(() -> goodsInfoChange(token, orderId, orderNo, organId)));
        results.put("body", CompletableFuture.supplyAsync(() -> bodyInfoChange(token, orderId, orderNo, organId)));
        results.put("group", CompletableFuture.supplyAsync(() -> groupInfoChange(token, orderId, orderNo, organId)));
        results.put("part", CompletableFuture.supplyAsync(() -> partsInfoChange(token, orderId, orderNo, organId)));
        results.put("plateDetail", CompletableFuture.supplyAsync(() -> platesDetailChange(token, orderId, orderNo, organId)));
        results.put("plate", CompletableFuture.supplyAsync(() -> platesInfoChange(token, orderId, orderNo, organId)));

        // 等待所有异步任务完成
        CompletableFuture.allOf(results.values().toArray(new CompletableFuture[6])).join();

//        ApiDataTypeVo order = results.get("order").get();
        ApiDataTypeVo order = orderInfoChange(token, orderId, orderNo, organId);
        ApiDataTypeVo goodsData = results.get("good").get();
        ApiDataTypeVo bodyData = results.get("body").get();
        ApiDataTypeVo groupData = results.get("group").get();
        ApiDataTypeVo partsData = results.get("part").get();
        ApiDataTypeVo plateDetailData = results.get("plateDetail").get();
        ApiDataTypeVo platesData = results.get("plate").get();

//        判断是不是空单
        OrderDO orderDO = order.getOrderDO();
        if (orderDO.getStatus() == 0) {
            return order;
        }

        // 判断生产数据是否可以为空
        if (!platesData.getMapPlatesInfos().isEmpty() && plateDetailData.getMapPlateDetails().isEmpty() ) {
            throw exception(ORDER_DETAIL_DATE_ERR);
//            throw exception(API_MES_ERR, "生产数据信息获取-小板缺少生产数据，导致无法正常导单");
        }

        // 小板数据补充，order_goods_id添加造型相关数据判断获取，以及配件中添加goods_id
        // 用方法实现，小板中添加其他信息，以及更新goods_id
        updateSmallBoardInfo(orderDO,
                goodsData.getMapGoodsDO(),
                plateDetailData.getMapPlateDetails(),
                platesData.getMapPlatesInfos(),
                plateDetailData.getMapPlateDetails());

        Map<String, List<OrderItemDO>> mapItemList = new HashMap<>();
        if (partsData.getMapItemByGroup() != null && partsData.getMapItemByGroup().size() > 0) {
            mergeMaps(mapItemList, partsData.getMapItemByGroup());
        }
//        mergeMaps(mapItemList, partsData.getMapItemByGroup());
        mergeMaps(mapItemList, platesData.getMapItemByGroup());


        // 2、柜体需要添加板的数量，
        Map<String, OrderBodyDO>  mapOrderBodyDO = bodyData.getMapOrderBodyDO(); // String Box_id
        Map<String, Integer> totalPlateCountMapToBody = platesData.getTotalPlateCountMapToBody();
        Map<String, Integer> irregularPlateCountMapToBody = platesData.getIrregularPlateCountMapToBody();

        if (totalPlateCountMapToBody.size() > 0) {
            mapOrderBodyDO.forEach((k, v) -> v.setPlateNum(totalPlateCountMapToBody.get(k)));
        }
        if (irregularPlateCountMapToBody.size() > 0) {
            mapOrderBodyDO.forEach((k, v) -> v.setUnregularNum(irregularPlateCountMapToBody.get(k)));
        }

        Map<String, OrderGroupDO> mapOrderGroupDO = groupData.getMapOrderGroupDO();
        Map<String, Integer> totalPlateCountMapToGroup = platesData.getTotalPlateCountMapToGroup();
        Map<String, Integer> irregularPlateCountMapToGroup = platesData.getIrregularPlateCountMapToGroup();
        if (totalPlateCountMapToGroup.size() > 0) {
            mapOrderGroupDO.forEach((k, v) -> v.setPlateNum(totalPlateCountMapToGroup.get(k)));
        }
        if (irregularPlateCountMapToGroup.size() > 0) {
            mapOrderGroupDO.forEach((k, v) -> v.setUnregularNum(irregularPlateCountMapToGroup.get(k)));
        }
        // order_group中添加order_body_id
        mapOrderGroupDO.forEach((k, v) -> v.setBodyId(mapOrderBodyDO.get(String.valueOf(v.getBodyId())).getId()));

        // item中添加order_body_id
        mapItemList.forEach((k, v) -> {
            // 通过DO中的box_id添加order_body_id 和 roomId
            v.forEach(itemDO -> {
                itemDO.setRoomId(mapOrderBodyDO.get(String.valueOf(itemDO.getBodyId())).getRoomId());
                itemDO.setBodyId(mapOrderBodyDO.get(String.valueOf(itemDO.getBodyId())).getId());
            });

        });
        // item中田间order_group_id
        mapItemList.values().stream()
                .flatMap(List::stream)
                .filter(itemDO -> itemDO.getGroupId() != null)
                .forEach(itemDO -> {
                    String groupIdStr = String.valueOf(itemDO.getGroupId());
                    OrderGroupDO newGroupDO = mapOrderGroupDO.get(groupIdStr);
                    if (newGroupDO != null) {
                        itemDO.setGroupId(newGroupDO.getId());
                    }
                });


        List<OrderItemDO> mapItem = mapItemList.values().stream()
                .flatMap(List::stream) // 将每个 List 转换为流，并将它们扁平化为一个流
                .collect(Collectors.toList()); // 收集结果到一个新的列表中

        // item中配件更换id
        mapItem.forEach(itemDO -> {
            if (itemDO.getPartsId() != null && partsData.getMapPartsInfos() != null) {
                String goodsId = String.valueOf(itemDO.getPartsId());
                OrderPartsDO newPartsDO = partsData.getMapPartsInfos().get(goodsId);
                if (newPartsDO != null) {
                    itemDO.setPartsId(newPartsDO.getId());
                }
            }
        });

        // 结果整理
        ApiDataTypeVo apiDataTypeVo = new ApiDataTypeVo();
        apiDataTypeVo.setOrderDO(orderDO).setMapGoodsDO(goodsData.getMapGoodsDO()).setMapRawGoodsDO(goodsData.getMapRawGoodsDO())
                .setMapOrderBodyDO(mapOrderBodyDO).setMapOrderGroupDO(mapOrderGroupDO).setMapItem(mapItem)
                .setMapPartsInfos(partsData.getMapPartsInfos()).setMapPartRemarks(partsData.getMapPartRemarks())
                .setMapPlateDetails(plateDetailData.getMapPlateDetails()).setMapPlatesInfos(platesData.getMapPlatesInfos());

        return apiDataTypeVo;
    }

    // 用方法实现，小板中添加其他信息，以及更新goods_id
    private void updateSmallBoardInfo(OrderDO orderDO,
                                      Map<String, GoodsDO> mapGoodsDO,
                                      Map<String, PlateDetail> mapPlateDetails,
                                      Map<String, PlateDO> mapPlatesInfos,
                                      Map<String, PlateDetail> mapPlateDetailsRemarks) {
//        这里需要修改

        // 第一步判断是否存在需要进行数据添加的小板
        if (mapPlatesInfos == null || mapPlatesInfos.isEmpty()) {
            log.error("小板信息:{}" , PLATE_DATA_ERROR);
//            throw exception(PLATE_DATA_ERROR);
        }
        if (mapPlateDetails == null || mapPlateDetails.isEmpty()) {
            log.error("小板信息:{}" , PLATE_PRODUCE_DATA_ERROR);
//            throw exception(PLATE_PRODUCE_DATA_ERROR);
        }
        if (mapGoodsDO == null || mapGoodsDO.isEmpty()) {
            log.error("板材信息:{}" , GOODS_DATA_ERROR);
//            throw exception(GOODS_DATA_ERROR);
        }
        mapPlatesInfos.forEach((k, v) -> {
            // 判断是否有造型数据可以进行整合
            if (mapPlateDetails.get(k) == null) { // 使用的blockNO
                return;
            }
            // goods_id更换
            GoodsDO goodsDO = mapGoodsDO.get(String.valueOf(v.getGoodsId()));
            v.setGoodsId(goodsDO.getId());

            // 累加goods板件数量和面积
            goodsDO.setPlateNum(goodsDO.getPlateNum() + 1);
            goodsDO.setArea(goodsDO.getArea() + v.getArea().doubleValue());

            // 累加生产单的板件数量和面积
            orderDO.setPlateNum(orderDO.getPlateNum() + 1);
            orderDO.setArea(orderDO.getArea() + v.getArea().doubleValue());

            // 添加其他信息
            // 获取小板对应的造型信息
            PlateDetail plateDetail = mapPlateDetails.get(k);
            if (plateDetail == null) {
                throw exception(ORDER_DETAIL_DATE_ERR);
            }
            plateDetail.setPlateId(v.getId())
                    .setExtraRemark(mapPlateDetailsRemarks.get(k).getExtraRemark())
                    .setSpecialRemarkDei(mapPlateDetailsRemarks.get(k).getSpecialRemarkDei())
                    .setExtraHandleRemark(mapPlateDetailsRemarks.get(k).getExtraHandleRemark())
                    .setDrillsRemark(mapPlateDetailsRemarks.get(k).getDrillsRemark())
                    .setInfoRemark(mapPlateDetailsRemarks.get(k).getInfoRemark())
                    .setRemarkJsonDei(mapPlateDetailsRemarks.get(k).getRemarkJsonDei());

            v.setHoleFace(plateDetail.getTypographicFace())
                    .setWidth(plateDetail.getPlateWidth())
                    .setHeight(plateDetail.getPlateLength())
                    .setOffsetX(plateDetail.getOffsetX())
                    .setOffsetY(plateDetail.getOffsetY());

            if (plateDetail.getThroughModelCount() != null
                    && plateDetail.getThroughModelCount() > 0){
                v.setFilterType(v.getFilterType() + ",1");
            }
            if (plateDetail.getThroughHoleCount() != null
                    && plateDetail.getThroughHoleCount() > 0){
                v.setFilterType(v.getFilterType() + ",2");
            }
            if (plateDetail.getHas2DModel() != null
                    && plateDetail.getHas2DModel()){
                v.setFilterType(v.getFilterType() + ",4");
            }

            BigDecimal splitHeight = v.getSplitHeight();
            BigDecimal splitWidth = v.getSplitWidth();
            BigDecimal splitThickness = v.getSplitThickness();

            // 拆分尺寸为0，则取成品尺寸
            if (BigDecimal.ZERO.compareTo(splitHeight) == 0 || BigDecimal.ZERO.compareTo(splitWidth) == 0 || BigDecimal.ZERO.compareTo(splitThickness) == 0) {
                v.setSplitHeight(v.getHeight())
                        .setSplitWidth(v.getWidth())
                        .setSplitThickness(v.getThickness());
            }

        });
    }
    /**
     * order信息获取加信息转换
     */
    public ApiDataTypeVo orderInfoChange(String token,
                                         Long orderId,
                                         String orderNo,
                                         Long organId){
        // 订单获取
        JSONObject order = apiDataAchieve.getApiOrder(token, orderNo)
                .getJSONArray(ProduceApiConstants.DATA).getJSONObject(INDEX);


        // 检验数据合法性
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate orderDate = LocalDate.parse(order.getString(ProduceApiConstants.OL_START_DATE), formatter);
        LocalDate deliveryDate = LocalDate.parse(order.getString(ProduceApiConstants.OL_END_DATE), formatter);
        if (deliveryDate.isBefore(orderDate)) {
            // 将 deliveryDate 设置为 orderDate 后的第 30 天
            deliveryDate = orderDate.plusMonths(1);
        }
        String orderRemark = "[" + orderNo + "]; ";

        OrderDO orderDO = OrderDO.builder()
                .id(orderId)
                .apiOrderId(orderNo)
                .parentNo(0L)
                .orderDate(orderDate.atStartOfDay())
                .deliveryDate(deliveryDate.atStartOfDay())
                .orderType(OrderTypeEnum.MAIN_ORDER.getStatus())
                .dataType(DataTypeEnum.API_IMPORT.getStatus())
                .customOrderNo(order.getString(ProduceApiConstants.OL_CUSTOM_ORDER_NO))
                .customer(order.getString(ProduceApiConstants.OL_CUSTOMER_NAME))
                .address(order.getString(ProduceApiConstants.OL_CUSTOMER_ADDRESS))
                .phoneNumber(order.getString(ProduceApiConstants.OL_CUSTOMER_PHONE))
                .dealer(order.getString(ProduceApiConstants.OL_STORE_NAME))
                .dealerPhoneNumber(order.getString(ProduceApiConstants.OL_STORE_PHONE))
                .salesman(order.getString(ProduceApiConstants.OL_NICK_NAME))
                .splitter(order.getString(ProduceApiConstants.OL_CD_NICK_NAME))
                .remark(orderRemark + order.getString(ProduceApiConstants.OL_COMMENTS))
                .organId(organId)
                .build();

        Integer submitState = order.getInteger(ProduceApiConstants.OL_ORDER_STATUS);
        if (submitState == 1){
            orderDO.setStatus(OrderStatusEnum.EMPTY.getStatus());
        }else {
            orderDO.setStatus(OrderStatusEnum.NEW_ORDER.getStatus());
        }
        return new ApiDataTypeVo().setOrderDO(orderDO);



    }


    /**
     * 设计商品快照 和 设计商品信息
     */
    public ApiDataTypeVo goodsInfoChange(String token,
                                         Long orderId,
                                         String orderNo,
                                         Long organId){

        JSONObject goodsMessage = apiDataAchieve.getApiGoodsMessage(token, orderNo); // 全部信息

        Map<String, RawGoodsDO> rawGoodsDOS = new HashMap<>();
        Map<String, GoodsDO> goodsDOS = new HashMap<>();

        JSONArray goodsLists = goodsMessage.getJSONArray(ProduceApiConstants.LIST);
        if (goodsLists == null || goodsLists.isEmpty()) {
            return new ApiDataTypeVo().setMapRawGoodsDO(rawGoodsDOS).setMapGoodsDO(goodsDOS);
        }




        for (int i = 0; i < goodsLists.size(); i++) {
            JSONObject good = goodsLists.getJSONObject(i);

            Long goodsId = good.getLong(ProduceApiConstants.G_DOOR_ID);
            String goodsSn = null;
            if (goodsId != null) {
                goodsSn = getGoodsSn(good.getLong(ProduceApiConstants.G_DOOR_ID), token);
            }

            RawGoodsDO rawGoodsDO = RawGoodsDO.builder()
                    .id((Long) identifierGenerator.nextId(null))
                    .orderId(orderId)
                    .rawGoodsId(goodsSn)
                    .goodsName(good.getString(ProduceApiConstants.G_GOODS_NAME))
                    .material(good.getString(ProduceApiConstants.G_MATERIAL))
                    .color(good.getString(ProduceApiConstants.G_COLOR))
                    .colorBlack(good.getString(ProduceApiConstants.G_COLOR))
                    .texture(getTexture( good.getJSONObject(ProduceApiConstants.G_EXTRA_PROP)))
                    .thickness(good.getDouble(ProduceApiConstants.G_THICKNESS))
                    .brand(good.getString(ProduceApiConstants.G_BRAND))
                    .spec(good.getString(ProduceApiConstants.G_SPEC))
                    .price(good.getDouble(ProduceApiConstants.G_PRICE))
                    .organId(organId)
                    .build();
            rawGoodsDOS.put(good.getString(ProduceApiConstants.G_DOOR_ID), rawGoodsDO);

            GoodsDO goodsDO = GoodsDO.builder()
                    .id((Long) identifierGenerator.nextId(null))
                    .orderId(orderId)
                    .rawGoodsId(String.valueOf(rawGoodsDO.getId()))
                    .goodsId(goodsSn)
                    .goodsName(good.getString(ProduceApiConstants.G_GOODS_NAME))
                    .material(good.getString(ProduceApiConstants.G_MATERIAL))
                    .color(good.getString(ProduceApiConstants.G_COLOR))
                    .colorBlack(good.getString(ProduceApiConstants.G_COLOR))
                    .texture(getTexture( good.getJSONObject(ProduceApiConstants.G_EXTRA_PROP)))
                    .width(BigDecimal.valueOf(good.getDouble(ProduceApiConstants.G_WIDTH)))
                    .height(BigDecimal.valueOf(good.getDouble(ProduceApiConstants.G_HEIGHT)))
                    .thickness(BigDecimal.valueOf(good.getDouble(ProduceApiConstants.G_THICKNESS)))
                    .brand(good.getString(ProduceApiConstants.G_BRAND))
                    .spec(good.getString(ProduceApiConstants.G_SPEC))
                    .price(good.getDouble(ProduceApiConstants.G_PRICE))
                    .organId(organId)
                    .build();
            goodsDOS.put(good.getString(ProduceApiConstants.G_DOOR_ID), goodsDO);

        }


//        map.put(FieldConstants.RAW_GOODS, rawGoodsDOS);
//        map.put(FieldConstants.GOODS, goodsDOS);
        return new ApiDataTypeVo().setMapRawGoodsDO(rawGoodsDOS).setMapGoodsDO(goodsDOS);

    }


    /**
     * 房间柜体信息获取
     */
    public ApiDataTypeVo bodyInfoChange(String token,
                                        Long orderId,
                                        String orderNo,
                                        Long organId){


        JSONObject bodyMessage = apiDataAchieve.getApiBodyMessage(token, orderNo);

        JSONArray bodyLists = bodyMessage.getJSONArray(ProduceApiConstants.LIST);

//        if (bodyLists == null || bodyLists.isEmpty()) {
//            log.error("{}房间柜体信息获取失败",orderNo);
//            throw exception(ORDER_BODY_NOT_EXISTS);
//
//        }

        Map<String, OrderBodyDO> bodyInfos = new HashMap<>();

        if (bodyLists == null || bodyLists.isEmpty()) {
            return new ApiDataTypeVo().setMapOrderBodyDO(bodyInfos);

        }

        for (int i = 0; i < bodyLists.size(); i++) {
            JSONObject body = bodyLists.getJSONObject(i);
            OrderBodyDO bodyInfo = OrderBodyDO.builder()
                    .id((Long) identifierGenerator.nextId(null))
                    .orderId(orderId)
                    .roomId(Long.valueOf(body.getString(ProduceApiConstants.B_ROOM_ID)))
                    .roomName(body.getString(ProduceApiConstants.B_ROOM_NAME))
                    .name(body.getString(ProduceApiConstants.B_NAME))
                    .width(body.getDouble(ProduceApiConstants.B_WIDTH))
                    .height(body.getDouble(ProduceApiConstants.B_HEIGHT))
                    .depth(body.getDouble(ProduceApiConstants.B_DEPTH))
                    .multiNum(0)
                    .plateNum(0)
                    .unregularNum(0)
                    .organId(organId)
                    .build();
            bodyInfos.put(body.getString(ProduceApiConstants.B_BOX_ID), bodyInfo);

        }
        return new ApiDataTypeVo().setMapOrderBodyDO(bodyInfos);
    }


    /**
     * 加工组信息获取
     */
    public ApiDataTypeVo groupInfoChange(String token,
                                         Long orderId,
                                         String orderNo,
                                         Long organId) {

        JSONObject groupMessage = apiDataAchieve.getApiGroupMessage(token, orderNo);

        Map<String, OrderGroupDO> orderGroupDOs = new HashMap<>();// 加工组id 和 加工组信息
        Map<String, List<String>> groupLists = new HashMap<>();// 加工组id 和 详细信息

        if (groupMessage == null || groupMessage.isEmpty() || groupMessage.getJSONArray(ProduceApiConstants.VALUE).isEmpty()) {
            return new ApiDataTypeVo().setMapOrderGroupDO(orderGroupDOs).setMapGroupLists(groupLists);
        }



        JSONArray value = groupMessage.getJSONArray(ProduceApiConstants.VALUE);
        for (int i = 0; i < value.size(); i++) {
            JSONObject group = value.getJSONObject(i);

            OrderGroupDO orderGroup = OrderGroupDO.builder()
                    .id((Long) identifierGenerator.nextId(null))
                    .orderId(orderId)
                    .bodyId(group.getLong(ProduceApiConstants.M_BOX_ID))
                    .groupTypeId(group.getLong(ProduceApiConstants.M_MODULE_TYPE_ID))
                    .groupTypeName(group.getString(ProduceApiConstants.M_MODULE_TYPE_NAME))
                    .name(group.getString(ProduceApiConstants.M_MODULE_TYPE_NAME))
                    .width(group.getDouble(ProduceApiConstants.M_WIDTH))
                    .height(group.getDouble(ProduceApiConstants.M_LENGTH))
                    .depth(group.getDouble(ProduceApiConstants.M_THICKNESS))
                    .multiNum(0)
                    .plateNum(0)
                    .unregularNum(0)
                    .organId(organId)
                    .build();
            groupLists.put(group.getString(ProduceApiConstants.M_MODULE_ID), jsonArrayToList(group.getJSONArray(ProduceApiConstants.M_ITEM_ID_LIST)));
            orderGroupDOs.put(group.getString(ProduceApiConstants.M_MODULE_ID), orderGroup);
        }


        return new ApiDataTypeVo().setMapOrderGroupDO(orderGroupDOs).setMapGroupLists(groupLists);

    }

    // 配件相关信息获取 分页获取转换，使用线程
    public ApiDataTypeVo partsInfoChange(String token,
                                         Long orderId,
                                         String orderNo,
                                         Long organId) {

        // 配件api调用参数生成
        JSONObject jsonParts = new JSONObject();
        jsonParts.put(ProduceApiConstants.CURR_PAGE_KEY, 1);
        jsonParts.put(ProduceApiConstants.PAGE_COUNT_KEY, PARTS_PAGE_MAX);
        jsonParts.put(ProduceApiConstants.ORDER_NO_KEY, "N" + orderNo);

        Map<String, OrderPartsDO> partsInfos = new HashMap<>();
        Map<String, List<OrderItemDO>> partsItem = new HashMap<>();
        Map<String, OrderPartsRemark> remarks = new HashMap<>();

        if (apiDataAchieve.getApiPartsMessage(token, orderNo, jsonParts) == null) {
            return new ApiDataTypeVo().setMapPartsInfos(partsInfos).setMapItemByGroup(partsItem).setMapPartRemarks(remarks);
        }

//        if (apiDataAchieve.getApiPartsMessage(token, orderNo, jsonParts) == null) {
//            return new ApiDataTypeVo();
//        }

        Integer pageCount = apiDataAchieve.getApiPartsMessage(token, orderNo, jsonParts).getJSONObject(ProduceApiConstants.VALUE).getInteger(ProduceApiConstants.PAGE_COUNT); // 获取页码总数
        // 根据总页码总数进行多线程循环
//        Map<String, OrderPartsDO> partsInfos = new HashMap<>();
//        Map<String, List<OrderItemDO>> partsItem = new HashMap<>();
//        Map<String, OrderPartsRemark> remarks = new HashMap<>();


        List<CompletableFuture<Map<String, Object>>> futures = new ArrayList<>();
        for (int i = 1; i <= pageCount; i++) {
            JSONObject pageJsonParts = new JSONObject();
            pageJsonParts.put(ProduceApiConstants.CURR_PAGE_KEY, i);
            pageJsonParts.put(ProduceApiConstants.PAGE_COUNT_KEY, PARTS_PAGE_MAX);
            pageJsonParts.put(ProduceApiConstants.ORDER_NO_KEY, "N" + orderNo);

            CompletableFuture<Map<String, Object>> future = CompletableFuture.supplyAsync(() -> {
                JSONObject value = apiDataAchieve.getApiPartsMessage(token, orderNo, pageJsonParts);
                return partsInfoChange(value, orderId, organId, token);
            });

            futures.add(future);
        }

        // 等待所有异步操作完成，并收集结果
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[pageCount])).join();

        // 处理每个CompletableFuture的结果
        for (CompletableFuture<Map<String, Object>> future : futures) {
            try {
                Map<String, Object> result = future.get(); // 获取每个任务的结果

                // 假设partsInfoChange返回的map包含PARTS、ITEM和PARTS_REMARK三个键
                @SuppressWarnings("unchecked")
                Map<String, OrderPartsDO> pagePartsInfos = (Map<String, OrderPartsDO>) result.get(FieldConstants.PARTS);
                @SuppressWarnings("unchecked")
                Map<String, List<OrderItemDO>> pagePartsItem = (Map<String, List<OrderItemDO>>) result.get(FieldConstants.ITEM);
                @SuppressWarnings("unchecked")
                Map<String, OrderPartsRemark> pageRemarks = (Map<String, OrderPartsRemark>) result.get(FieldConstants.PARTS_REMARK);

                // 判断是否存在相同的key
                Set<String> commonKeys = getCommonKeys(pagePartsInfos, partsInfos);
                if (!commonKeys.isEmpty()) { // 存在相同的键
                    commonKeys.forEach(key -> {
                        Long idBefore = partsInfos.get(key).getId();
                        Long idNew = pagePartsInfos.get(key).getId();
                        // 遍历pagePartsItem
                        pagePartsItem.forEach((k, valueList) -> {
                            valueList.stream()
                                    .filter(orderItem -> idNew.equals(orderItem.getPartsId()))
                                    .forEach(orderItem -> orderItem.setPartsId(idBefore));
                        });
                        pagePartsInfos.remove(key);
                    });
                }
                // 合并到最终的结果映射中
                partsInfos.putAll(pagePartsInfos);
                partsItem.putAll(pagePartsItem);
                remarks.putAll(pageRemarks);
            } catch (InterruptedException | ExecutionException e) {
                throw new RuntimeException(e);
            }

        }
        return new ApiDataTypeVo().setMapPartsInfos(partsInfos).setMapItemByGroup(partsItem).setMapPartRemarks(remarks);
    }

    // 配件数据转换
    private Map<String, Object> partsInfoChange(JSONObject partJSONObject,
                                                Long orderId,
                                                Long organId,
                                                String token) {

        Map<String, Object> map = new HashMap<>();
        Map<String, OrderPartsDO> partsInfos = new HashMap<>();
        Map<String, List<OrderItemDO>> partsItem = new HashMap<>();
        Map<String, OrderPartsRemark> remarks = new HashMap<>();

        map.put(FieldConstants.PARTS, partsInfos);
        map.put(FieldConstants.ITEM, partsItem);
        map.put(FieldConstants.PARTS_REMARK, remarks);

        if (partJSONObject == null || partJSONObject.isEmpty() || partJSONObject.getJSONObject(ProduceApiConstants.VALUE).getJSONArray(ProduceApiConstants.LIST).isEmpty()) {
            return map;
        }


        JSONArray partsLists = partJSONObject.getJSONObject(ProduceApiConstants.VALUE).getJSONArray(ProduceApiConstants.LIST);
        for (int i = 0; i < partsLists.size(); i++) {
            JSONObject part = partsLists.getJSONObject(i);
            Long partsId = (Long) identifierGenerator.nextId(null);
            // 这边用的配件详情接口的数据，可能存在多种配件的goodsId相同
            // 配件长宽厚颜色赋值
            Map<String, Object> sizeMap = getPartsSize(part.getJSONObject(ProduceApiConstants.PD_SIZE), part.getJSONObject(ProduceApiConstants.PD_PARTS_SPEC_OB));
            // goods_id转换，需要调用接口
            String goodsId = part.getString(ProduceApiConstants.PD_GOODS_ID);

            String goodsSn = null;
            String key = part.getString(ProduceApiConstants.PD_ITEM_NO);
            // goods_id不为0时，要判断是否有存相同的goods_id，为0时，新增一条order_parts
            if (!goodsId.equals("0")) {
                goodsSn = getGoodsSn(part.getLong(ProduceApiConstants.PD_GOODS_ID), token);
                key = goodsId;
            }


            // item 明细
            List<OrderItemDO> itemList = new ArrayList<>();
            // 公共属性构建
            OrderItemDO item = OrderItemDO.builder()
                    .id((Long) identifierGenerator.nextId(null))
                    .orderId(orderId)
                    .type(OrderItemTypeEnum.PARTS_ITEM.getStatus())
                    .roomId(part.getLong(ProduceApiConstants.PD_ROOM_ID))
                    .bodyId(part.getLong(ProduceApiConstants.PD_BOX_ID))
                    .planId(0L)
                    .packageId(0L)
                    .partsId(partsId)
                    .num(part.getDouble(ProduceApiConstants.PD_NUM))
                    .organId(organId)
                    .build();

            JSONArray moduleIdList = part.getJSONArray(ProduceApiConstants.PD_MODULE_ID_LIST);
            if (moduleIdList != null && !moduleIdList.isEmpty()) {
                for (int j = 0; j < moduleIdList.size(); j++) {
                    Long moduleId = moduleIdList.getLong(j);
                    OrderItemDO moduleItem = copyDO(item) // Assuming toBuilder method exists for OrderItemDO
                            .setId((Long) identifierGenerator.nextId(null))
                            .setGroupId(moduleId);
                    itemList.add(moduleItem);
                }
            } else {
                // 当没有模块ID列表时，直接使用默认的item对象
                itemList.add(item);
            }
            partsItem.put(part.getString(ProduceApiConstants.PD_ITEM_ID), itemList);

            if (partsInfos.get(key) != null) { //有存，下一条
                Long finalPartsId = partsInfos.get(key).getId();
                itemList.forEach(
                        value -> value.setPartsId(finalPartsId)
                );
                continue;
            }

            OrderPartsDO partsInfo = OrderPartsDO.builder()
                    .id(partsId)
                    .orderId(orderId)
                    .goodsId(goodsSn)
                    .name(part.getString(ProduceApiConstants.PD_NAME))
                    .material((String) sizeMap.get(PART_MATERIAL))
                    .category(changePartType(part.getString(ProduceApiConstants.PD_OBJECT_TYPE), part.getBoolean(ProduceApiConstants.PD_IS_COMPOSITE)))
                    .type(changePartType(part.getString(ProduceApiConstants.PD_OBJECT_TYPE), part.getBoolean(ProduceApiConstants.PD_IS_COMPOSITE)))
                    .model(part.getString(ProduceApiConstants.PD_MODEL))
                    .color((String) sizeMap.get(PART_COLOR))
                    .width((Double) sizeMap.get(PART_WIDTH))
                    .length((Double) sizeMap.get(PART_LENGTH))
                    .thickness((Double) sizeMap.get(PART_THICKNESS))
                    .spec(part.getString(ProduceApiConstants.PD_SPEC))
                    .brand(part.getString(ProduceApiConstants.PD_BRAND))
                    .factory(part.getString(ProduceApiConstants.PD_FACTORY))
                    .unit(part.getString(ProduceApiConstants.PD_UNITS))
                    .isComposite(part.getBoolean(ProduceApiConstants.PD_IS_COMPOSITE))
                    .remark(part.getString(ProduceApiConstants.PD_REMARK))
                    .price(part.getDouble(ProduceApiConstants.PD_PRICE))
                    .organId(organId)
                    .build();

            remarks.put(key, partsRemarkChange(part, orderId, partsId));
            partsInfos.put(key, partsInfo);
        }


        return map;
    }

    // 小板造型数据获取
    public ApiDataTypeVo platesDetailChange(String token,
                                            Long orderId,
                                            String orderNo,
                                            Long organId) {

        Map<String, PlateDetail> plateDetails = new HashMap<>();

        JSONObject jsonPlatesDetail = apiDataAchieve.getApiPlateProData(token, orderNo);

        ApiDataTypeVo map = new ApiDataTypeVo().setMapPlateDetails(plateDetails);
        // 获取板件详情数据
        if (jsonPlatesDetail.getJSONObject(ProduceApiConstants.VALUE) == null) {
            return map;
        }



        // 获取 Orders 字段对应的数组
        JSONArray ordersArray = jsonPlatesDetail.getJSONObject(ProduceApiConstants.VALUE).getJSONArray(ProduceApiConstants.OPD_ORDER);
        if (ordersArray == null || ordersArray.isEmpty()) {
            return map;
        }

        for (int i = 0; i < ordersArray.size(); i++) {

            JSONObject order = ordersArray.getJSONObject(i);
            // 获取材料信息
            JSONArray materialJson = order.getJSONArray(ProduceApiConstants.BPD_MATERIALS);
            if (materialJson == null || materialJson.isEmpty()) {
                return map;
            }
            for (int j = 0; j < materialJson.size(); j++) {
                JSONObject material = materialJson.getJSONObject(j);

                // 板件信息
                JSONArray blocks = material.getJSONArray(ProduceApiConstants.BPD_BLOCKS);
                if (blocks == null || blocks.isEmpty()) {
                    return map;
                }
                for (int k = 0; k < blocks.size(); k++) {
                    JSONObject block = blocks.getJSONObject(k);// 每块板

                    PlateDetail plateDetail = PlateDetail.builder()
                            .organId(organId)
                            .orderId(orderId)
                            .bodyNo(block.getString(ProduceApiConstants.BPD_BOX_NO))
                            .plateNo(block.getString(ProduceApiConstants.BPD_BLOCK_NO))
                            .name(block.getString(ProduceApiConstants.BPD_BLOCK_NAME))
                            .customPlateNo(block.getString(ProduceApiConstants.BPD_CUSTOM_BLOCK_NO))
                            .roomsName(block.getString(ProduceApiConstants.BPD_ROOM_NAME))
                            .bodyName(block.getString(ProduceApiConstants.BPD_BOX_NAME))
                            .group(block.getString(ProduceApiConstants.BPD_PROCESS_GROUP_NAME))
                            .multiNum(1)
                            .plateWidth(block.getBigDecimal(ProduceApiConstants.BPD_WIDTH))
                            .plateLength(block.getBigDecimal(ProduceApiConstants.BPD_LENGTH))
                            .acreage(block.getBigDecimal(ProduceApiConstants.BPD_SIZE))
                            .splitWidth(block.getBigDecimal(ProduceApiConstants.BPD_CUTTING_WIDTH))
                            .splitLength(block.getBigDecimal(ProduceApiConstants.BPD_CUTTING_LENGTH))
                            .sealAcreage(block.getBigDecimal(ProduceApiConstants.BPD_CUTTING_SIZE))
                            .isUnRegular(block.getBoolean(ProduceApiConstants.BPD_IS_UN_REGULAR))
                            .sealLeft(block.getBigDecimal(ProduceApiConstants.BPD_BORDER_LEFT))
                            .sealRight(block.getBigDecimal(ProduceApiConstants.BPD_BORDER_RIGHT))
                            .sealUp(block.getBigDecimal(ProduceApiConstants.BPD_BORDER_UPPER))
                            .sealDown(block.getBigDecimal(ProduceApiConstants.BPD_BORDER_UNDER))
                            .texture(block.getInteger(ProduceApiConstants.BPD_WAVE))
                            .typographicFace(Integer.valueOf(block.getString(ProduceApiConstants.BPD_PLACE_FACE)))
                            .openDoorType(Integer.valueOf(block.getString(ProduceApiConstants.BPD_OPEN_DOOR_TYPE)))
                            .offsetX(block.getBigDecimal(ProduceApiConstants.BPD_OFFSET_X))
                            .offsetY(block.getBigDecimal(ProduceApiConstants.BPD_OFFSET_Y))
                            .pointDetail(getPointDetail(block, true))
                            .rawPointDetail(getPointDetail(block, false))
                            .holeDetail(getHoleDetail(block, true))
                            .sideHoleDetail(getHoleDetail(block, false))
                            .contourDetail(getModelDetail(block.getJSONArray(ProduceApiConstants.BPD_MODEL)))
                            .sideDetail(getModelDetail(block.getJSONArray(ProduceApiConstants.BPD_SIDE_MODEL)))
                            .isHXDJX(block.getBoolean(ProduceApiConstants.BPD_IS_HXDJ))
                            .build();

                    if (block.getJSONObject(ProduceApiConstants.BPD_EXTRA_REMARK) != null) {
                        JSONObject extraRemark = block.getJSONObject(ProduceApiConstants.BPD_EXTRA_REMARK).getJSONObject(ProduceApiConstants.BPD_EXTRA);
                        if (extraRemark != null)
                            plateDetail.setBoardType(extraRemark.getString(ProduceApiConstants.BPD_EXTRA_BOARD_TYPE))
                                    .setThroughHoleCount(Double.valueOf(extraRemark.getString(ProduceApiConstants.BPD_EXTRA_THROUGH_HOLE_COUNT)))
                                    .setThroughModelCount(Double.valueOf(extraRemark.getString(ProduceApiConstants.BPD_EXTRA_THROUGH_MODEL_COUNT)))
                                    .setHas2DModel(Boolean.valueOf(extraRemark.getString(ProduceApiConstants.BPD_EXTRA_HAS_2D_MODEL)))
                                    .setHas3DModel(Boolean.valueOf(extraRemark.getString(ProduceApiConstants.BPD_EXTRA_HAS_3D_MODEL)))
                                    .setPlateExtraRemark(block.getJSONObject(ProduceApiConstants.BPD_EXTRA_REMARK))
                                    .setSideRemark(remarkToMap(block))
                                    .setDrillsInfos(getDrillsInfo(block.getJSONObject(ProduceApiConstants.BPD_EXTRA_REMARK)));
                    }
                    plateDetails.put(block.getString(ProduceApiConstants.BPD_BLOCK_NO), plateDetail);
                }

            }

        }


        return map;
    }
    // 小板，大板，造型，item信息获取
    public ApiDataTypeVo platesInfoChange(String token,
                                          Long orderId,
                                          String orderNo,
                                          Long organId) {

        // 配件api调用参数生成
        JSONObject jsonPlates = new JSONObject();
        jsonPlates.put(ProduceApiConstants.CURR_PAGE_KEY, 1);
        jsonPlates.put(ProduceApiConstants.PAGE_COUNT_KEY, PARTS_PAGE_MAX);
        jsonPlates.put(ProduceApiConstants.ORDER_NO_KEY, "N" + orderNo);

        // 根据总页码总数进行多线程循环
        Map<String, PlateDO> plateInfos = new HashMap<>();
        Map<String, List<OrderItemDO>> plateItem = new HashMap<>();
        Map<String, PlateDetail> plateDetailMap = new HashMap<>();

        // 柜体板块片数，柜体异形板片数
        Map<String, Integer> totalPlateCountMapToBody = new HashMap<>();
        Map<String, Integer> irregularPlateCountMapToBody = new HashMap<>();

        // 加工组板块片数，加工组异形板片数
        Map<String, Integer> totalPlateCountMapToGroup = new HashMap<>();
        Map<String, Integer> irregularPlateCountMapToGroup = new HashMap<>();

        ApiDataTypeVo apiDataTypeVo = new ApiDataTypeVo().setMapPlatesInfos(plateInfos).setMapItemByGroup(plateItem)
                .setTotalPlateCountMapToBody(totalPlateCountMapToBody)
                .setIrregularPlateCountMapToBody(irregularPlateCountMapToBody)
                .setTotalPlateCountMapToGroup(totalPlateCountMapToGroup)
                .setIrregularPlateCountMapToGroup(irregularPlateCountMapToGroup)
                .setMapPlateDetails(plateDetailMap);

        if (apiDataAchieve.getApiPlateDetailMessage(token, orderNo, jsonPlates) == null) {
            return apiDataTypeVo;
        }

        Integer pageCount = apiDataAchieve.getApiPlateDetailMessage(token, orderNo, jsonPlates).getJSONObject(ProduceApiConstants.VALUE).getInteger(ProduceApiConstants.PAGE_COUNT); // 获取页码总数


        List<CompletableFuture<Map<String, Object>>> futures = new ArrayList<>();
        JSONObject blocksValue = apiDataAchieve.getApiBlocksMessage(token, orderNo);
        for (int i = 1; i <= pageCount; i++) {
            JSONObject jsonPlate = new JSONObject();
            jsonPlate.put(ProduceApiConstants.CURR_PAGE_KEY, i);
            jsonPlate.put(ProduceApiConstants.PAGE_COUNT_KEY, PARTS_PAGE_MAX);
            jsonPlate.put(ProduceApiConstants.ORDER_NO_KEY, "N" + orderNo);

            CompletableFuture<Map<String, Object>> future = CompletableFuture.supplyAsync(() -> {
                JSONObject value = apiDataAchieve.getApiPlateDetailMessage(token, orderNo, jsonPlate);

                return platesInfoChange(value, blocksValue, orderId, organId);
            });

            futures.add(future);
        }
        // 等待所有异步操作完成，并收集结果
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();

        // 处理每个CompletableFuture的结果
        for (CompletableFuture<Map<String, Object>> future : futures) {
            try {
                Map<String, Object> result = future.get(); // 获取每个任务的结果

                // 假设partsInfoChange返回的map包含PARTS、ITEM和PARTS_REMARK三个键
                @SuppressWarnings("unchecked")
                Map<String, PlateDO> pagePlatesInfos = (Map<String, PlateDO>) result.get(FieldConstants.PLATE);
                @SuppressWarnings("unchecked")
                Map<String, List<OrderItemDO>> pagePlatesItem = (Map<String, List<OrderItemDO>>) result.get(FieldConstants.ITEM);
                @SuppressWarnings("unchecked")
                Map<String, Integer> plateToBody = (Map<String, Integer>) result.get(BODY_PLATE_NUMBER);
                @SuppressWarnings("unchecked")
                Map<String, Integer> irregularPlateToBody = (Map<String, Integer>) result.get(BODY_IRREGULAR_PLATE_NUMBER);
                @SuppressWarnings("unchecked")
                Map<String, Integer> plateToGroup = (Map<String, Integer>) result.get(GROUP_PLATE_NUMBER);
                @SuppressWarnings("unchecked")
                Map<String, Integer> irregularPlateToGroup = (Map<String, Integer>) result.get(GROUP_IRREGULAR_PLATE_NUMBER);
                @SuppressWarnings("unchecked")
                Map<String, PlateDetail> plateDetailMapRemarks = (Map<String, PlateDetail>) result.get(PLATE_DETAILS_REMARKS);

                // 合并到最终的结果映射中
                plateInfos.putAll(pagePlatesInfos);
                plateItem.putAll(pagePlatesItem);

                totalPlateCountMapToBody.putAll(mergeMap(totalPlateCountMapToBody,plateToBody));
                irregularPlateCountMapToBody.putAll(mergeMap(irregularPlateCountMapToBody,irregularPlateToBody));
                totalPlateCountMapToGroup.putAll(mergeMap(totalPlateCountMapToGroup,plateToGroup));
                irregularPlateCountMapToGroup.putAll(mergeMap(irregularPlateCountMapToGroup,irregularPlateToGroup));
                plateDetailMap.putAll(plateDetailMapRemarks);
            } catch (InterruptedException | ExecutionException e) {
                throw new RuntimeException(e);
            }

        }
        return apiDataTypeVo;

    }

    // 小板数据转换
    private Map<String, Object> platesInfoChange(JSONObject platesJSONObject,
                                                 JSONObject blocksJSONObject,
                                                 Long orderId,
                                                 Long organId) {

        Map<String, Object> map = new HashMap<>();
        Map<String, PlateDO> partsInfos = new HashMap<>();
        List<PlateDO> plateList = new ArrayList<>();
        Map<String, List<OrderItemDO>> platesItem = new HashMap<>();
        Map<String, PlateDetail> plateDetailMap = new HashMap<>();

        // 柜体板块片数，柜体异形板片数
        Map<String, Integer> totalPlateCountMapToBody = new HashMap<>();
        Map<String, Integer> irregularPlateCountMapToBody = new HashMap<>();

        // 加工组板块片数，加工组异形板片数
        Map<String, Integer> totalPlateCountMapToGroup = new HashMap<>();
        Map<String, Integer> irregularPlateCountMapToGroup = new HashMap<>();

        map.put(FieldConstants.PLATE, partsInfos);
        map.put(FieldConstants.ITEM, platesItem);

        map.put(BODY_PLATE_NUMBER , totalPlateCountMapToBody);
        map.put(BODY_IRREGULAR_PLATE_NUMBER  , irregularPlateCountMapToBody);
        map.put(GROUP_PLATE_NUMBER , totalPlateCountMapToGroup);
        map.put(GROUP_IRREGULAR_PLATE_NUMBER , irregularPlateCountMapToGroup);
        map.put(PLATE_DETAILS_REMARKS, plateDetailMap);

        if (platesJSONObject == null || platesJSONObject.isEmpty()) {
            log.error("获取板件明细数据失败");
            throw exception(PLATE_PLAN_DATA_ERROR);

        }
        if (blocksJSONObject == null || blocksJSONObject.isEmpty()) {
            log.error("获取板材数据失败");
            throw exception(PLATE_GOOD_DATA_NULL);

        }
        // 板材数据
        Map<String, JSONObject> blocksMap = getBlocksData(blocksJSONObject);


        JSONArray plateLists = platesJSONObject.getJSONObject(ProduceApiConstants.VALUE).getJSONArray(ProduceApiConstants.LIST);



        for (int i = 0; i < plateLists.size(); i++) {

            long plateNo = idWorker.nextId();
            long obtainingTime = idWorker.obtainingTime();

            JSONObject plate = plateLists.getJSONObject(i);

            Integer type = Integer.valueOf(dictDataApi.parseDictData(DictTypeConstants.PLATE_TYPE,
                            plate.getString(ProduceApiConstants.BD_BOARD_TYPE))
                    .getData().getValue());
            Long plateId = (Long) identifierGenerator.nextId(null);

            String remarkJson = plate.getString(ProduceApiConstants.BD_REMARK_JSON).replace("\"", "").trim();
//            去掉[]
            remarkJson = remarkJson.replace("[", "").replace("]", "");
            String remark = !remarkJson.trim().isEmpty() ? remarkJson : "";

            PlateDO plateInfo = PlateDO.builder()
                    .id(plateId)
                    .orderId(orderId)
                    .name(plate.getString(ProduceApiConstants.BD_BOARD_NAME))
                    .plateNo((obtainingTime) + Long.toString(plateNo).substring(2))
                    .type(type)
                    .goodsId(plate.getLong(ProduceApiConstants.BD_GOODS_ID))
                    .splitHeight(BigDecimal.valueOf(plate.getDouble(ProduceApiConstants.BD_SPLIT_HEIGHT)))
                    .splitThickness(BigDecimal.valueOf(plate.getDouble(ProduceApiConstants.BD_SPLIT_THICKNESS)))
                    .splitWidth(BigDecimal.valueOf(plate.getDouble(ProduceApiConstants.BD_SPLIT_WIDTH)))
                    .sealLeft(BigDecimal.valueOf(plate.getDouble(ProduceApiConstants.BD_SEALED_LEFT)))
                    .sealRight(BigDecimal.valueOf(plate.getDouble(ProduceApiConstants.BD_SEALED_RIGHT)))
                    .sealUp(BigDecimal.valueOf(plate.getDouble(ProduceApiConstants.BD_SEALED_UP)))
                    .sealDown(BigDecimal.valueOf(plate.getDouble(ProduceApiConstants.BD_SEALED_DOWN)))
                    .holeArrange(0)  // 排孔类型  值无实际含义，默认初始化值
                    .unregularPointCount(plate.getInteger(ProduceApiConstants.BD_UN_REGULAR_POINT_COUNT))//
                    .frontHoleCount(plate.getInteger(ProduceApiConstants.BD_FRONT_HOLE_COUNT))
                    .sideHoleCount(plate.getInteger(ProduceApiConstants.BD_BACK_HOLE_COUNT))
                    .sideHoleCount(plate.getInteger(ProduceApiConstants.BD_SIDE_HOLE_COUNT))
                    .frontModelCount(plate.getInteger(ProduceApiConstants.BD_FRONT_MODEL_COUNT))
                    .backModelCount(plate.getInteger(ProduceApiConstants.BD_BACK_MODEL_COUNT))
                    .isDoor(plate.getInteger(ProduceApiConstants.BD_OPEN_DOOR_TYPE) != 0)
                    .openDoorType(plate.getInteger(ProduceApiConstants.BD_OPEN_DOOR_TYPE))
                    .isArcAcross(false)
                    .moduleTypeId(0L)
                    .isSculpt(plate.getBoolean(ProduceApiConstants.BD_IS_MODEL))
                    .isSpecialShaped(plate.getBoolean(ProduceApiConstants.BD_IS_UN_REGULAR))
                    .isCancel(false)
                    .filterType("")
                    .remark(remark)
                    .organId(organId)
                    .roomName(plate.getString(ProduceApiConstants.BD_ROOM_NAME))
                    .bodyName(plate.getString(ProduceApiConstants.BD_BOX_NAME)) // 之后再改成名称
                    .customPlateNoBuilder(new StringBuilder())
                    .build();
            partsInfos.put(plate.getString(ProduceApiConstants.BD_BLOCK_NO), plateInfo);
            plateList.add(plateInfo);

            String cabinetId = plate.getString(ProduceApiConstants.BD_BOX_ID);
            boolean isIrregular = plateInfo.getIsSpecialShaped();
            // 柜体
            totalPlateCountMapToBody.put(cabinetId, totalPlateCountMapToBody.getOrDefault(cabinetId, 0) + 1);
            if (isIrregular) {
                irregularPlateCountMapToBody.put(cabinetId, irregularPlateCountMapToBody.getOrDefault(cabinetId, 0) + 1);
            }

            // item 明细
            List<OrderItemDO> itemList = new ArrayList<>();
            // 公共属性构建
            OrderItemDO item = OrderItemDO.builder()
                    .id((Long) identifierGenerator.nextId(null))
                    .orderId(orderId)
                    .type(OrderItemTypeEnum.PLATE_ITEM.getStatus())
                    .roomId(plate.getLong(ProduceApiConstants.BD_BOX_ID))
                    .bodyId(plate.getLong(ProduceApiConstants.BD_BOX_ID))
                    .planId(0L)
                    .packageId(0L)
                    .groupId(0L)
                    .partsId(0L)
                    .plateId(plateId)
                    .num(1.0)
                    .organId(organId)
                    .build();

            JSONArray moduleIdList = plate.getJSONArray(ProduceApiConstants.BD_MODULE_ID_LIST);
            if (moduleIdList != null && !moduleIdList.isEmpty()) {
                for (int j = 0; j < moduleIdList.size(); j++) {

                    String groupId = moduleIdList.getString(j);
                    // 加工组
                    totalPlateCountMapToGroup.put(groupId, totalPlateCountMapToGroup.getOrDefault(groupId, 0) + 1);
                    if (isIrregular) {
                        irregularPlateCountMapToGroup.put(groupId, irregularPlateCountMapToGroup.getOrDefault(groupId, 0) + 1);
                    }

                    Long moduleId = moduleIdList.getLong(j);
                    OrderItemDO moduleItem = copyDO(item) // Assuming toBuilder method exists for OrderItemDO
                            .setId((Long) identifierGenerator.nextId(null))
                            .setGroupId(moduleId);
                    itemList.add(moduleItem);
                }
            } else {
                // 当没有模块ID列表时，直接使用默认的item对象
                itemList.add(item);
            }
            platesItem.put(plate.getString(ProduceApiConstants.BD_ITEM_ID), itemList);

            // 造型数据中的备注信息
            PlateDetail plateDetailInfo = new PlateDetail();
            plateDetailInfo
                    .setExtraRemark(plate.getString(ProduceApiConstants.BD_EXTRA_REMARK).replace("\"", "").trim())
                    .setSpecialRemarkDei(plate.getString(ProduceApiConstants.BD_SPECIAL_REMARK).replace("\"", "").trim())
                    .setExtraHandleRemark(plate.getString(ProduceApiConstants.BD_EXTRA_HANDLE_REMARK).replace("\"", "").trim())
                    .setDrillsRemark(plate.getString(ProduceApiConstants.BD_DRILLS_REMARK).replace("\"", "").trim())
                    .setInfoRemark(plate.getString(ProduceApiConstants.BD_INFO_REMARK).replace("\"", "").trim())
                    .setRemarkJsonDei(remarkJson);
            // 获取板材数据中的
            if (blocksMap.get(plate.getString(ProduceApiConstants.BD_BLOCK_NO)) != null) {
                JSONObject jsonObject = blocksMap.get(plate.getString(ProduceApiConstants.BD_BLOCK_NO));
                plateDetailInfo.setRemarkJson(jsonObject.getString(ProduceApiConstants.BG_REMARK_JSON).replace("\"", "").trim())
                        .setSpecialRemark(jsonObject.getString(ProduceApiConstants.BG_SPECIAL_REMARK).replace("\"", "").trim());

                plateInfo.setThickness(BigDecimal.valueOf(jsonObject.getDouble(ProduceApiConstants.BG_THICKNESS)))
                        .setArea(BigDecimal.valueOf(jsonObject.getDouble(ProduceApiConstants.BG_AREA)))
                        .setTexture(jsonObject.getInteger(ProduceApiConstants.BG_WAVE))
                        .setIsRowHole(jsonObject.getBoolean(ProduceApiConstants.BG_IS_HOLE));

            }
            plateDetailMap.put(plate.getString(ProduceApiConstants.BD_BLOCK_NO), plateDetailInfo);
        }





        return map;
    }


    // map中key重复，value累加
    private Map<String, Integer> mergeMap(Map<String, Integer> allMap, Map<String, Integer> map) {
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            String key = entry.getKey();
            Integer value = entry.getValue();
            allMap.put(key, allMap.getOrDefault(key, 0) + value);
        }
        return allMap;
    }


    //    异形板的开料轮廓 (type 为true，不含封边;其他为,含封边)
    private List<PointDetail> getPointDetail(JSONObject block,
                                             Boolean type) {
        List<PointDetail> pointDetailList = new ArrayList<>();

        if (type) { // 不含封边
            JSONArray pointsJson = block.getJSONArray(ProduceApiConstants.BPD_POINTS);
            if (pointsJson == null || pointsJson.isEmpty()) {
                return pointDetailList;
            }

            for (int i = 0; i < pointsJson.size(); i++) {
                JSONObject point = pointsJson.getJSONObject(i);
                pointDetailList.add(PointDetail.builder()
                        .pointX(Double.valueOf(point.getString(ProduceApiConstants.BPD_POINTS_X)))
                        .pointY(Double.valueOf(point.getString(ProduceApiConstants.BPD_POINTS_Y)))
                        .curve(Double.valueOf(point.getString(ProduceApiConstants.BPD_POINTS_CURVE)))
                        .build());
            }

        } else { // 含封边
            JSONArray orgPointsJson = block.getJSONArray(ProduceApiConstants.BPD_ORG_POINTS);
            if (orgPointsJson == null || orgPointsJson.isEmpty()) {
                return pointDetailList;
            }

            for (int i = 0; i < orgPointsJson.size(); i++) {
                JSONObject rawPoint = orgPointsJson.getJSONObject(i);
                pointDetailList.add(PointDetail.builder()
                        .pointX(Double.valueOf(rawPoint.getString(ProduceApiConstants.BPD_POINTS_X)))
                        .pointY(Double.valueOf(rawPoint.getString(ProduceApiConstants.BPD_POINTS_Y)))
                        .curve(Double.valueOf(rawPoint.getString(ProduceApiConstants.BPD_POINTS_CURVE)))
                        .sealSize(BigDecimal.valueOf(Double.valueOf(rawPoint.getString(ProduceApiConstants.BPD_POINTS_EDGE))))
                        .build());

            }

        }
        return pointDetailList;
    }

    //    孔明细板数据解析 (type 为true，正面;false,侧面)
    private List<HoleDetail> getHoleDetail(JSONObject block,
                                           Boolean type) {
        List<HoleDetail> holeDetails = new ArrayList<>();
        if (type) { // 1，正面
            JSONArray holes = block.getJSONArray(ProduceApiConstants.BPD_HOLES);
            if (holes == null || holes.isEmpty()) {
                return Collections.emptyList();
            }
            for (int i = 0; i < holes.size(); i++) {
                JSONObject hole = holes.getJSONObject(i);
                holeDetails.add(HoleDetail.builder()
                        .id(hole.getString(ProduceApiConstants.BPD_HOLE_ID))
                        .holeType(Integer.valueOf(hole.getString(ProduceApiConstants.BPD_HOLE_TYPE)))
                        .startX(Double.valueOf(hole.getString(ProduceApiConstants.BPD_HOLE_X)))
                        .startY(Double.valueOf(hole.getString(ProduceApiConstants.BPD_HOLE_Y)))
                        .faceType(hole.getInteger(ProduceApiConstants.BPD_HOLE_FACE))
                        .radius(Double.parseDouble(hole.getString(ProduceApiConstants.BPD_HOLE_DIAMETER)) / 2)
                        .depth(Double.valueOf(hole.getString(ProduceApiConstants.BPD_HOLE_DEPTH)))
                        .build());
            }
        } else {
            JSONArray sideHoles = block.getJSONArray(ProduceApiConstants.BPD_SIDE_HOLES);
            if (sideHoles == null || sideHoles.isEmpty()) {
                return Collections.emptyList();
            }
            for (int i = 0; i < sideHoles.size(); i++) {
                JSONObject hole = sideHoles.getJSONObject(i);
                String[] startPoints = splitAndTrim(hole.getString(ProduceApiConstants.BPD_HOLE_START_POINT));
                String[] endPoints = splitAndTrim(hole.getString(ProduceApiConstants.BPD_HOLE_END_POINT));
                try {
                    holeDetails.add(HoleDetail.builder()
                            .startX(Double.valueOf(startPoints[X]))
                            .startY(Double.valueOf(startPoints[Y]))
                            .startZ(Double.valueOf(startPoints[Z]))
                            .endX(Double.valueOf(endPoints[X]))
                            .endY(Double.valueOf(endPoints[Y]))
                            .endZ(Double.valueOf(endPoints[Z]))
                            .faceType(2)
                            .direction(hole.getInteger(ProduceApiConstants.BPD_HOLE_DIRECTION))
                            .radius(Double.parseDouble(hole.getString(ProduceApiConstants.BPD_HOLE_DIAMETER)) / 2)
                            .depth(Double.valueOf(hole.getString(ProduceApiConstants.BPD_HOLE_DEPTH)))
                            .build());
                } catch (Exception e) {
                    log.error("解析孔数据异常", e);
                }

            }

        }

        return holeDetails;
    }

    //    造型明细板数据解析 (type 为1，正面;3,侧面)
    private List<ModelDetail> getModelDetail(JSONArray models) {

        List<ModelDetail> modelDetails =  new ArrayList<>();

        try {
            List<ModelDetail> modelData = getModelData(models);
            if (modelData != null && !modelData.isEmpty()) {
                modelDetails.addAll(modelData);
            }

        } catch (Exception e) {
            // 处理异常，例如记录日志或抛出自定义异常
            log.error("解析造型数据异常", e);
        }

        return modelDetails;
    }

    // 造型数据生成
    private List<ModelDetail> getModelData(JSONArray models) {
        if (models == null || models.isEmpty()) {
            return null;
        }
        List<ModelDetail> modelDetails = new ArrayList<>();

        for (int i = 0; i < models.size(); i++) {
            JSONObject model = models.getJSONObject(i);

            List<PointList> pointLists = new ArrayList<>();
            JSONArray pointsJson = model.getJSONArray(ProduceApiConstants.BPD_MODEL_POINTS);
            if (pointsJson != null && !pointsJson.isEmpty()) {
                for (int j = 0; j < pointsJson.size(); j++) {
                    JSONObject point = pointsJson.getJSONObject(j);
                    String[] points = splitAndTrim(point.getString(ProduceApiConstants.BPD_MODEL_POINTS_POS));
                    pointLists.add(PointList.builder()
                            .pointX(Double.valueOf(points[X]))
                            .pointY(Double.valueOf(points[Y]))
                            .pointZ(Double.valueOf(points[Z]))
                            .curve(Double.valueOf(point.getString(ProduceApiConstants.BPD_MODEL_POINTS_CURVE)))
                            .build());
                }
            }

            List<OffSetList> offSetLists = new ArrayList<>();
            JSONArray offSets = model.getJSONArray(ProduceApiConstants.BPD_MODEL_OFFSET_LIST);
            if (offSets != null && !offSets.isEmpty()) {
                for (int j = 0; j < offSets.size(); j++) {
                    JSONObject offSet = offSets.getJSONObject(j);
                    offSetLists.add(OffSetList.builder()
                            .value(Double.valueOf(offSet.getString(ProduceApiConstants.BPD_MODEL_OFFSET_LIST_VALUE)))
                            .name(offSet.getString(ProduceApiConstants.BPD_MODEL_OFFSET_LIST_NAME))
                            .radius(Double.parseDouble(offSet.getString(ProduceApiConstants.BPD_MODEL_OFFSET_LIST_DIRECTION)) / 2)
                            .angle(Double.valueOf(offSet.getString(ProduceApiConstants.BPD_MODEL_OFFSET_LIST_ANGLE)))
                            .depth(Double.valueOf(offSet.getString(ProduceApiConstants.BPD_MODEL_OFFSET_LIST_DEPTH)))
                            .build());
                }
            }

            modelDetails.add(ModelDetail.builder()
                    .modelID(Integer.valueOf(model.getString(ProduceApiConstants.BPD_MODEL_ID)))
                    .lineID(Integer.valueOf(model.getString(ProduceApiConstants.BPD_MODEL_LINE_ID)))
                    .depth(Double.valueOf(model.getString(ProduceApiConstants.BPD_MODEL_DEPTH)))
                    .faceType(Integer.valueOf(model.getString(ProduceApiConstants.BPD_MODEL_FACE)))
                    .knifeName(model.getString(ProduceApiConstants.BPD_MODEL_TOOL_NO))
                    .knifeRadius(Double.parseDouble(model.getString(ProduceApiConstants.BPD_MODEL_DIAMETER)) / 2)
                    .pointList(pointLists)
                    .offSetList(offSetLists)
                    .originModeling(getOriginModeling(model.getJSONObject(ProduceApiConstants.BPD_MODEL_ORIGIN_MODELING)))
                    .build());
        }

        return modelDetails;
    }

    // 造型 --- OriginModeling
    private IOriginModelingData getOriginModeling(JSONObject originModeling) {

        if (originModeling == null || originModeling.isEmpty()) {
            return null;
        }

        JSONArray outLine = originModeling.getJSONArray(ProduceApiConstants.BPD_MODEL_ORIGIN_MODELING_OUTLINE);
        JSONArray holes = originModeling.getJSONArray(ProduceApiConstants.BPD_MODEL_ORIGIN_MODELING_HOLES);

        return IOriginModelingData.builder()
                .thickness(Double.valueOf(originModeling.getString(ProduceApiConstants.BPD_MODEL_ORIGIN_MODELING_THICKNESS)))
                .knifeRadius(Double.valueOf(originModeling.getString(ProduceApiConstants.BPD_MODEL_ORIGIN_MODELING_KNIFE_RADIUS)))
                .dir(originModeling.getInteger(ProduceApiConstants.BPD_MODEL_ORIGIN_MODELING_DIR))
                .outline(getOutlineOrOutline(outLine))
                .holes(getOutlineOrHoles(holes))
                .addLen(Double.valueOf(originModeling.getString(ProduceApiConstants.BPD_MODEL_ORIGIN_MODELING_ADD_LEN)))
                .addWidth(Double.valueOf(originModeling.getString(ProduceApiConstants.BPD_MODEL_ORIGIN_MODELING_ADD_WIDTH)))
                .addDepth(Double.valueOf(originModeling.getString(ProduceApiConstants.BPD_MODEL_ORIGIN_MODELING_ADD_DEPTH)))
                .build();
    }

    private List<IContourData> getOutlineOrOutline(JSONArray json) {
        if (json == null || json.isEmpty()) {
            return Collections.emptyList();
        }

        List<IContourData> contourDataList = new ArrayList<>();
        for (int i = 0; i < json.size(); i++) {
            JSONObject element = json.getJSONObject(i);
            String[] points = splitAndTrim(element.getString(ProduceApiConstants.BPD_MODEL_ORIGIN_MODELING_OUTLINE_POS));
            Point pointVO = Point.builder()
                    .x(Double.valueOf(points[X]))
                    .y(Double.valueOf(points[Y]))
                    .z(Double.valueOf(points[Z]))
                    .build();
            IContourData iContourDataVO = IContourData.builder()
                    .pts(pointVO)
                    .buls(Double.valueOf(element.getString(ProduceApiConstants.BPD_MODEL_ORIGIN_MODELING_OUTLINE_CURVE)))
                    .build();
            contourDataList.add(iContourDataVO);
        }
        return contourDataList;
    }

    private List<List<IContourData>> getOutlineOrHoles(JSONArray json) {
        List<List<IContourData>> contourDataList = new ArrayList<>();

        if (json == null || json.isEmpty()) {
            return contourDataList;
        }

        for (int i = 0; i < json.size(); i++) {
            JSONArray element = json.getJSONArray(i);
            if (element == null || element.isEmpty()) {
                continue;
            }
            List<IContourData> contourData = new ArrayList<>();
            for (int j = 0; j < element.size(); j++) {
                JSONObject point = element.getJSONObject(j);
                String[] points = splitAndTrim(point.getString(ProduceApiConstants.BPD_MODEL_ORIGIN_MODELING_HOLES_POS));
                Point pointVO = Point.builder()
                        .x(Double.valueOf(points[X]))
                        .y(Double.valueOf(points[Y]))
                        .z(Double.valueOf(points[Z]))
                        .build();
                IContourData iContourDataVO = IContourData.builder()
                        .pts(pointVO)
                        .buls(Double.valueOf(point.getString(ProduceApiConstants.BPD_MODEL_ORIGIN_MODELING_HOLES_CURVE)))
                        .build();
                contourData.add(iContourDataVO);
            }
            contourDataList.add(contourData);
        }
        return contourDataList;
    }

    //    排钻数据
    private List<DrillsInfo> getDrillsInfo(JSONObject block) {
        JSONArray drills = block.getJSONArray(ProduceApiConstants.BPD_DRILLS);

        if (drills == null || drills.isEmpty()) {
            return null;
        }
        List<DrillsInfo> drillsInfos = new ArrayList<>();
        for (int i = 0; i < drills.size(); i++) {
            JSONObject drill = drills.getJSONObject(i);
            drillsInfos.add(DrillsInfo.builder()
                    .name(drill.getString(ProduceApiConstants.BPD_DRILL_NAME))
                    .type(drill.getString(ProduceApiConstants.BPD_DRILL_TYPE))
                    .face(drill.getString(ProduceApiConstants.BPD_DRILL_FACE))
                    .count(Double.valueOf(drill.getString(ProduceApiConstants.BPD_DRILL_COUNT)))
                    .build());
        }
        return drillsInfos;
    }

    //    String[] 以逗号分割,去空格 得到包含X Y Z三位坐标的数组（顺序包含）
    public String[] splitAndTrim(String str) {
        String[] strs = str.split(",");
        for (int i = 0; i < strs.length; i++) {
            strs[i] = strs[i].trim();
        }
        return strs;
    }

    //  将remark转为map
    public Map<String, String> remarkToMap(JSONObject block) {
        String remark = "Remark";
        Map<String, String> map = new HashMap<>();
        for (int i = 1; i < 6; i++) {
            if (block.getString(remark + i) != null && !block.getString(remark + i).isEmpty()) {
                map.put(remark + i, block.getString(remark + i));
            }
        }
        return map;
    }

    /**
     * 配件类型转换
     */
    private String changePartType(String objectType, boolean isComposite) {
        if (PART_CATEGORY_ONE.equals(objectType)) {
            return PART_CATEGORY_ONE;
        } else {
            if (isComposite) {
                return PART_CATEGORY_THREE;
            } else {
                return PART_CATEGORY_TWO;
            }
        }
    }

    /**
     * 配件长宽厚信息转换
     */
    private Map<String,Object> getPartsSize(JSONObject size, JSONObject spec) {
        Map<String,Object> map = new HashMap<>();
        if (size != null && !size.isEmpty()) {
            map.put(PART_WIDTH, size.getDouble(ProduceApiConstants.PD_WIDTH));
            map.put(PART_LENGTH, size.getDouble(ProduceApiConstants.PD_LENGTH));
            map.put(PART_THICKNESS, size.getDouble(ProduceApiConstants.PD_THICKNESS));
        } else {
            map.put(PART_WIDTH, 0.0);
            map.put(PART_LENGTH, 0.0);
            map.put(PART_THICKNESS, 0.0);
        }
        if (spec != null && !spec.isEmpty()) {
            map.put(PART_COLOR, spec.getString(ProduceApiConstants.PD_PARTS_SPEC_COLOR));
            map.put(PART_MATERIAL, spec.getString(ProduceApiConstants.PD_PARTS_SPEC_MATERIAL));
        }
        return map;
    }

    /**
     * 配件备注集合
     */
    private OrderPartsRemark partsRemarkChange(JSONObject value,
                                               Long orderId,
                                               Long partsId) {
        OrderPartsRemark remark = new OrderPartsRemark();
        if (value != null && !value.isEmpty()) {
            remark.setPartsId(partsId);
            remark.setOrderId(orderId);
            remark.setRemark(value.getString(ProduceApiConstants.PD_REMARK));
            remark.setSpecExtras(value.getString(ProduceApiConstants.PD_SPEC_EXTRAS));
            remark.setSpecialRemark(value.getString(ProduceApiConstants.PD_SPECIAL_REMARK));
            remark.setDoorRemark(value.getString(ProduceApiConstants.PD_DOOR_REMARK));
            remark.setHingeRemark(value.getString(ProduceApiConstants.PD_HINGE_REMARK));
        }
        return remark;
    }

    /**
     * 加工组中加工组和板件的关联关系
     */
    public List<String> jsonArrayToList(JSONArray jsonArray) {
        List<String> list = new ArrayList<>();
        for (int i = 0; i < jsonArray.size(); i++) {
            list.add(jsonArray.getString(i));
        }
        return list;
    }

    /**
     * 商品中通过数据库标识id得到编码No
     */
    private String getGoodsSn(Long goodId, String token) {
        String goodsSn;
        try {
            JSONObject jsonGood = apiDataAchieve.getApiGoodsMessage(token, new Long[]{goodId}).get();

            goodsSn = jsonGood.getJSONArray(ProduceApiConstants.DATA).getJSONObject(0).getString(ProduceApiConstants.GD_GOODS_SN);

            return goodsSn;
        } catch (Exception e){
            return null;
        }
    }

    /**
     * @param extraProp: 商品中的额外属性
     * @return Boolean: 是否有纹理
     */
    private Boolean getTexture(JSONObject extraProp) {
        if (extraProp.getString(ProduceApiConstants.G_HAS_WAVE) != null){
            String hasWave = extraProp.getString(ProduceApiConstants.G_HAS_WAVE).trim();
            if (hasWave.equals(ProduceApiConstants.ZERO)){ // 无
                return false;
            }
        }
        return true; // 有
    }

    /**
     * 板材数据转换成 Map<String, Object>
     */
    public Map<String, JSONObject> getBlocksData(JSONObject dataBlocks) {
        Map<String, JSONObject> map = new HashMap<>();
        JSONArray ordersArray = dataBlocks.getJSONArray(ProduceApiConstants.LIST);
        if (ordersArray != null && !ordersArray.isEmpty()) {
            for (int i = 0; i < ordersArray.size(); i++) {
                JSONObject block = ordersArray.getJSONObject(i);
                // 订单号去N
                String blockNo = block.getString(ProduceApiConstants.BG_BLOCK_NO);
                map.put(blockNo, block);
            }
        }

        return map;
    }

    public Map<String, List<OrderItemDO>> mergeMaps(Map<String, List<OrderItemDO>> mergedMap, Map<String, List<OrderItemDO>> map) {

        if (map == null || map.isEmpty()) {
            log.error("明细信息:{}" , CHANGE_DETAILS_ITEM_ERROR);
//            throw exception(CHANGE_DETAILS_ITEM_ERROR);
        }

        // 处理第一个 Map
        for (Map.Entry<String, List<OrderItemDO>> entry : map.entrySet()) {
            String key = entry.getKey();
            List<OrderItemDO> value = entry.getValue();

            // 使用 computeIfAbsent 确保键存在，如果不存在则创建一个新的列表
            mergedMap.computeIfAbsent(key, k -> new ArrayList<>()).addAll(value);
        }
        return mergedMap;
    }

    // copy对象
    public OrderItemDO copyDO(OrderItemDO item) {
        return OrderItemDO.builder()
                .id(item.getId())
                .orderId(item.getOrderId())
                .type(item.getType())
                .roomId(item.getRoomId())
                .bodyId(item.getBodyId())
                .planId(item.getPlanId())
                .packageId(item.getPackageId())
                .groupId(item.getGroupId())
                .partsId(item.getPartsId())
                .plateId(item.getPlateId())
                .num(item.getNum())
                .organId(item.getOrganId())
                .build();
    }

    /**
     * 获取两个 Map 中相同的键。
     *
     * @param map1 第一个 Map
     * @param map2 第二个 Map
     * @return 包含相同键的 Set
     */
    public Set<String> getCommonKeys(Map<String, OrderPartsDO> map1, Map<String, OrderPartsDO> map2) {
        return map1.keySet().stream()
                .filter(map2::containsKey)
                .collect(Collectors.toSet());
    }

}