package com.cf.imes.module.executor.util.fileConversion.admin.files.xml;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.common.utils.StringUtils;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import com.cf.imes.framework.id.core.util.SnowflakeIdWorker3rd;
import com.cf.imes.framework.mybatis.core.generator.SnowFlakeGenerator;
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.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.util.deviseData.structure.*;
import com.cf.imes.module.executor.util.fileConversion.admin.files.xml.VO.*;
import com.cf.imes.module.system.api.dict.DictDataApi;
import com.cf.imes.module.system.api.dict.dto.DictDataRespDTO;
import com.cf.imes.module.executor.enums.DictTypeConstants;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Component;

import jakarta.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;


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

    @Resource
    SnowflakeIdWorker3rd idWorker;

    @Resource
    private DictDataApi dictDataApi;

    final String NOT_ASSIGNED = "未命名";
    final String NOT_ASSIGNED_CODE = "未命编号";
    final String ROOM_ID = "roomId";
    final String BODY_ID = "bodyId";
    final String GROUP_ID = "groupId";

    @Resource
    private SnowFlakeGenerator snowFlakeGenerator;

    @Resource
    private IdentifierGenerator identifierGenerator;

    // 房间基点坐标转换
    public Map<String, Map<String, BasePosition>> bodyBasePositionChange(RoomXmlVOS roomXmlVOS) {
        Map<String, Map<String, BasePosition>> roomInfos = new HashMap<>();
        if (roomXmlVOS != null && roomXmlVOS.getRoomXmlVOList() != null && roomXmlVOS.getRoomXmlVOList().size() > 0) {
            Map<String, BasePosition> basePositions = new HashMap<>();
            for (RoomXmlVO roomXmlVO : roomXmlVOS.getRoomXmlVOList()) {
                for (BoxXmlVO boxXmlVO : roomXmlVO.getBoxXmlVOList()) {
                    BasePosition basePosition = BasePosition.builder()
                            .basePointX(Double.valueOf(boxXmlVO.getBasePointX() == null ? "0" : boxXmlVO.getBasePointX()))
                            .basePointY(Double.valueOf(boxXmlVO.getBasePointY() == null ? "0" : boxXmlVO.getBasePointY()))
                            .basePointZ(Double.valueOf(boxXmlVO.getBasePointZ() == null ? "0" : boxXmlVO.getBasePointZ()))
                            .axisXrotate(Double.valueOf(boxXmlVO.getAxisXrotate() == null ? "0" : boxXmlVO.getAxisXrotate()))
                            .axisYrotate(Double.valueOf(boxXmlVO.getAxisYrotate() == null ? "0" : boxXmlVO.getAxisYrotate()))
                            .axisZrotate(Double.valueOf(boxXmlVO.getAxisZrotate() == null ? "0" : boxXmlVO.getAxisZrotate()))
                            .build();
                    basePositions.put(boxXmlVO.getCode(), basePosition);
                }
                roomInfos.put(roomXmlVO.getCode(), basePositions);
            }
        }
        return roomInfos;
    }

    // 柜体基点坐标转换
    public Map<String, BasePosition> roomBasePositionChange(RoomXmlVOS roomXmlVOS) {
        Map<String, BasePosition> basePositions = new HashMap<>();
        if (roomXmlVOS != null && roomXmlVOS.getRoomXmlVOList() != null && !roomXmlVOS.getRoomXmlVOList().isEmpty()) {
            for (RoomXmlVO roomXmlVO : roomXmlVOS.getRoomXmlVOList()) {
                basePositions.put(roomXmlVO.getCode(), BasePosition.builder()

                        .basePointX(Double.valueOf(roomXmlVO.getBasePointX()))
                        .basePointY(Double.valueOf(roomXmlVO.getBasePointY()))
                        .basePointZ(Double.valueOf(roomXmlVO.getBasePointZ()))
                        .axisXrotate(Double.valueOf(roomXmlVO.getAxisXrotate()))
                        .axisYrotate(Double.valueOf(roomXmlVO.getAxisYrotate()))
                        .axisZrotate(Double.valueOf(roomXmlVO.getAxisZrotate()))
                        .build());
            }
        }
        return basePositions;
    }

    // 房间柜体信息转换
    public Map<String, Map<String, OrderBodyDO>> bodyInfoChange(RoomXmlVOS roomXmlVOS, Long orderId, Long organId) {
        Map<String, Map<String, OrderBodyDO>> roomInfos = new HashMap<>();

        if (roomXmlVOS == null || roomXmlVOS.getRoomXmlVOList() == null || roomXmlVOS.getRoomXmlVOList().isEmpty()) {
            return roomInfos;
        }

        for (RoomXmlVO roomXmlVO : roomXmlVOS.getRoomXmlVOList()) {
            Map<String, OrderBodyDO> bodyInfos = new HashMap<>();
            Long roomId = (Long) snowFlakeGenerator.nextId(null);

            setDefaultsForRoomXmlVO(roomXmlVO);
            if (roomXmlVO.getBoxXmlVOList() == null || roomXmlVO.getBoxXmlVOList().isEmpty()) {
                BoxXmlVO boxXmlVO = new BoxXmlVO();
                setDefaultsForBoxXmlVO(boxXmlVO);
                List<BoxXmlVO> boxXmlVOList = new ArrayList<>();
                boxXmlVOList.add(boxXmlVO);
                roomXmlVO.setBoxXmlVOList(boxXmlVOList);
            }
            for (BoxXmlVO boxXmlVO : roomXmlVO.getBoxXmlVOList()) {
                setDefaultsForBoxXmlVO(boxXmlVO);
                OrderBodyDO orderBodyDO = createOrderBodyDO(boxXmlVO, roomId, orderId, organId, roomXmlVO.getName());
                bodyInfos.put(boxXmlVO.getCode(), orderBodyDO);
            }
            roomInfos.put(roomXmlVO.getCode(), bodyInfos);
        }

        return roomInfos;
    }

    private void setDefaultsForRoomXmlVO(RoomXmlVO roomXmlVO) {

        if (roomXmlVO.getCode() == null) {
            if (roomXmlVO.getName() == null) {
                roomXmlVO.setCode(NOT_ASSIGNED_CODE);
            } else {
                roomXmlVO.setCode(NOT_ASSIGNED_CODE + roomXmlVO.getName());
            }
        }
        if (roomXmlVO.getName() == null) {
            roomXmlVO.setName(NOT_ASSIGNED);
        }
    }

    private void setDefaultsForBoxXmlVO(BoxXmlVO boxXmlVO) {

        if (boxXmlVO.getCode() == null) {
            if (boxXmlVO.getName() == null) {
                boxXmlVO.setCode(NOT_ASSIGNED_CODE);
            } else {
                boxXmlVO.setCode(NOT_ASSIGNED_CODE + boxXmlVO.getName());
            }
        }
        if (boxXmlVO.getName() == null || boxXmlVO.getName().isEmpty()) {
            boxXmlVO.setName(NOT_ASSIGNED);
        }
    }

    private OrderBodyDO createOrderBodyDO(BoxXmlVO boxXmlVO, Long roomId, Long orderId, Long organId, String roomName) {
        return OrderBodyDO.builder()
                .id((Long) identifierGenerator.nextId(null))
                .organId(organId)
                .orderId(orderId)
                .roomId(roomId)
                .roomName(roomName) // 假设 BoxXmlVO 中有 roomName 字段
                .name(boxXmlVO.getName())
                .width(Double.parseDouble(boxXmlVO.getWidth() == null ? "0" : boxXmlVO.getWidth()))
                .height(Double.parseDouble(boxXmlVO.getHeight() == null ? "0" : boxXmlVO.getHeight()))
                .depth(Double.parseDouble(boxXmlVO.getLength() == null ? "0" : boxXmlVO.getLength()))
                .plateNum(0)
                .unregularNum(0)
                .build();
    }

    // 加工组信息转换
    public Map<String, OrderGroupDO> groupInfoChange(GroupXmlVOS groupXmlVOS, Long orderId, Long organId) {
        Map<String, OrderGroupDO> groupInfos = new HashMap<>();
        if (groupXmlVOS == null || groupXmlVOS.getGroupXmlVOList() == null || groupXmlVOS.getGroupXmlVOList().isEmpty()) {
            return groupInfos;
        }

        List<GroupXmlVO> groupXmlVOList = groupXmlVOS.getGroupXmlVOList();
        for (GroupXmlVO groupXmlVO : groupXmlVOList) {
            if (groupXmlVO.getName() == null) {
                groupXmlVO.setName(NOT_ASSIGNED);
            }
            if (groupXmlVO.getCode() == null) {
                groupXmlVO.setCode(groupXmlVO.getName() == null ? NOT_ASSIGNED_CODE : (NOT_ASSIGNED_CODE + " + " + groupXmlVO.getName()));
            } else if (groupXmlVO.getName() == null) {
                groupXmlVO.setCode(NOT_ASSIGNED + " + " + groupXmlVO.getCode());
            }
            OrderGroupDO groupDO = OrderGroupDO.builder()
                    .id((Long) identifierGenerator.nextId(null))
                    .organId(organId)
                    .orderId(orderId)
                    .bodyId(0L)
                    .groupTypeId(0L)
                    .groupTypeName(NOT_ASSIGNED)
                    .name(groupXmlVO.getName())
                    .height(Double.parseDouble(groupXmlVO.getHeight()))
                    .width(Double.parseDouble(groupXmlVO.getWidth()))
                    .depth(Double.parseDouble(groupXmlVO.getLength()))
                    .plateNum(0)
                    .unregularNum(0)
                    .build();
            groupInfos.put(groupXmlVO.getCode(), groupDO);
        }
        return groupInfos;
    }

    private void isEmptyAndAdd(Supplier<String> getName, Consumer<String> setName, Supplier<String> getCode, Consumer<String> setCode) {
        String name = getName.get();
        String code = getCode.get();

        if (StringUtils.isEmpty(name) && StringUtils.isEmpty(code)) {
            setName.accept(NOT_ASSIGNED);
            setCode.accept(NOT_ASSIGNED_CODE);
        }
        if (StringUtils.isEmpty(code) && !StringUtils.isEmpty(name)){
            setCode.accept(NOT_ASSIGNED_CODE + " + " + name);
        }
        if (!StringUtils.isEmpty(code) && StringUtils.isEmpty(name)){
            setName.accept(NOT_ASSIGNED + " + " + code);
        }
    }

    // 板材信息转换
    public Map<String, Object> goodsInfoChange(OrderXmlVO orderXmlVO, Long orderId, Long organId) {
        Map<String, Object> map = new HashMap<>();

        List<Object> rawGoodsDOs = new ArrayList<>();
        List<Object> goodsDOs = new ArrayList<>();

        List<Object> plateDOs = new ArrayList<>();
        List<Object> plateDetail = new ArrayList<>();

        // 房间柜体
        Map<String, Map<String, OrderBodyDO>> roomInfos = bodyInfoChange(orderXmlVO.getRoomXmlVOS(), orderId, organId); // roomInfos 这个在跟着一起变
        // 房间基点
        Map<String, BasePosition> roomBasePositions = roomBasePositionChange(orderXmlVO.getRoomXmlVOS());
        // 柜体基点
        Map<String, Map<String, BasePosition>> boxBasePositions = bodyBasePositionChange(orderXmlVO.getRoomXmlVOS());
        // 加工组
        Map<String, OrderGroupDO> groupInfos = groupInfoChange(orderXmlVO.getGroupXmlVOS(), orderId, organId);  // groupInfos 这个在跟着一起变

        Map<String, Object> itemInfos = new HashMap<>();

        Map<String, Object> orderPartsRemarks = new HashMap<>();
        Map<String, Object> partsDOInfos = new HashMap<>();


        if (orderXmlVO.getMaterialXmlVO() == null) {
            return map;
        }

        MaterialXmlVO materialXmlVO = orderXmlVO.getMaterialXmlVO();
        Map<String, List<EdgingXmlVO>> edgingMap;
        Map<String, List<HardwareXmlVO>> hardwareMap;
        Map<String, List<AssemblyXmlVO>> assemblyMap;
        // 配件
        if (materialXmlVO.getAccessoryXmlVO() != null ) {
            AccessoryXmlVO accessoryXmlVO = materialXmlVO.getAccessoryXmlVO();
            if (accessoryXmlVO.getEdgingXmlVOS() != null && accessoryXmlVO.getEdgingXmlVOS().getEdgingXmlVOList() != null && !accessoryXmlVO.getEdgingXmlVOS().getEdgingXmlVOList().isEmpty()) {
                List<EdgingXmlVO> edgingList = accessoryXmlVO.getEdgingXmlVOS().getEdgingXmlVOList();
                edgingList.forEach(edgingXmlVO -> {
                    isEmptyAndAdd(edgingXmlVO::getRoomName, edgingXmlVO::setRoomName, edgingXmlVO::getRoomCode, edgingXmlVO::setRoomCode);

                    isEmptyAndAdd(edgingXmlVO::getBoxName, edgingXmlVO::setBoxName, edgingXmlVO::getBoxCode, edgingXmlVO::setBoxCode);

                });
                // 以itemCode为条件进行分组，成map
                edgingMap = edgingList.stream().collect(Collectors.groupingBy(EdgingXmlVO::getItemCode));
                // 遍历map
                edgingMap.forEach((key, value) -> {
                    if (key == null) { // 没有itemCode
                        Map<String, List<EdgingXmlVO>> edgingMapWithNull = value.stream().collect(Collectors.groupingBy(edgingXmlVO ->
                                edgingXmlVO.getManufacturer() + edgingXmlVO.getBrand() + edgingXmlVO.getName() + edgingXmlVO.getMaterial() +
                                        edgingXmlVO.getSpecs() + edgingXmlVO.getColor() + edgingXmlVO.getWidth() + edgingXmlVO.getThickness()));

                        edgingMap.putAll(edgingMapWithNull);

                    }
                });
            } else {
                edgingMap = null;
            }
            if (accessoryXmlVO.getHardwareXmlVOS() != null && accessoryXmlVO.getHardwareXmlVOS().getHardwareXmlVOList() != null && !accessoryXmlVO.getHardwareXmlVOS().getHardwareXmlVOList().isEmpty()) {
                List<HardwareXmlVO> hardwareXmlVOS = accessoryXmlVO.getHardwareXmlVOS().getHardwareXmlVOList();
                hardwareXmlVOS.forEach(hardwareXmlVO -> {
                    isEmptyAndAdd(hardwareXmlVO::getRoomName, hardwareXmlVO::setRoomName, hardwareXmlVO::getRoomCode, hardwareXmlVO::setRoomCode);

                    isEmptyAndAdd(hardwareXmlVO::getBoxName, hardwareXmlVO::setBoxName, hardwareXmlVO::getBoxCode, hardwareXmlVO::setBoxCode);

                });
                // 以itemCode为条件进行分组，成map
                hardwareMap = hardwareXmlVOS.stream().collect(Collectors.groupingBy(HardwareXmlVO::getItemCode));
                // 遍历map
                hardwareMap.forEach((key, value) -> {
                    if (key == null) { //没有itemCode
                        Map<String, List<HardwareXmlVO>> hardwareMapWithNull = value.stream().collect(Collectors.groupingBy(hardwareXmlVO ->
                                hardwareXmlVO.getManufacturer() + hardwareXmlVO.getBrand() + hardwareXmlVO.getName() + hardwareXmlVO.getMaterial() +
                                        hardwareXmlVO.getSpecs() + hardwareXmlVO.getColor() + hardwareXmlVO.getType()));

                        hardwareMap.putAll(hardwareMapWithNull);
                    }
                });
            } else {
                hardwareMap = null;
            }
        } else {
            hardwareMap = null;
            edgingMap = null;
        }

        if (materialXmlVO.getAssemblieXmlVOS() != null) {
            AssemblieXmlVOS assemblieXmlVOS = materialXmlVO.getAssemblieXmlVOS();
            if (assemblieXmlVOS.getAssemblyXmlVOList() != null && !assemblieXmlVOS.getAssemblyXmlVOList().isEmpty()) {
                List<AssemblyXmlVO> assemblyList = assemblieXmlVOS.getAssemblyXmlVOList();
                assemblyList.forEach(assemblyXmlVO -> {
                    isEmptyAndAdd(assemblyXmlVO::getRoomName, assemblyXmlVO::setRoomName, assemblyXmlVO::getRoomCode, assemblyXmlVO::setRoomCode);

                    isEmptyAndAdd(assemblyXmlVO::getBoxName, assemblyXmlVO::setBoxName, assemblyXmlVO::getBoxCode, assemblyXmlVO::setBoxCode);


                });
                assemblyMap = assemblieXmlVOS.getAssemblyXmlVOList().stream().collect(Collectors.groupingBy(AssemblyXmlVO::getItemCode));
                assemblyMap.forEach((key, value) -> {
                    if (key == null) { // 没有itemCode
                        Map<String, List<AssemblyXmlVO>> assemblyMapWithNull = value.stream().collect(Collectors.groupingBy(assemblyXmlVO ->
                                assemblyXmlVO.getManufacturer() + assemblyXmlVO.getBrand() + assemblyXmlVO.getName() + assemblyXmlVO.getMaterial() +
                                        assemblyXmlVO.getSpecs() + assemblyXmlVO.getColor() + assemblyXmlVO.getType()));

                        assemblyMap.putAll(assemblyMapWithNull);
                    }
                });
            } else {
                assemblyMap = null;
            }
        } else {
            assemblyMap = null;
        }

        Map<String, Map<String, Object>> partInfoAll = goodsInfoChange(organId, orderId, edgingMap, hardwareMap, assemblyMap, roomInfos, groupInfos);
        itemInfos.putAll(partInfoAll.get("orderItemMap"));
        orderPartsRemarks.putAll(partInfoAll.get("orderPartsRemarks"));
        partsDOInfos.putAll(partInfoAll.get("orderPartsDOMap"));

            if (materialXmlVO.getPlateXmlVOS() != null) {
                PlateXmlVOS plateXmlVOS = materialXmlVO.getPlateXmlVOS();

                // 板材
                if (plateXmlVOS.getPlateXmlVOList() != null && !plateXmlVOS.getPlateXmlVOList().isEmpty()) {
                    for (PlateXmlVO plateXmlVO : plateXmlVOS.getPlateXmlVOList()) {
                        if (StringUtils.equals(plateXmlVO.getGrained().trim(), "无")) {
                            plateXmlVO.setGrained("false");
                        } else if (StringUtils.equals(plateXmlVO.getGrained().trim(), "有")) {
                            plateXmlVO.setGrained("true");
                        }

                        Long rawGoodsId = (Long) identifierGenerator.nextId(null);
                        Long goodsId = (Long) identifierGenerator.nextId(null);
                        rawGoodsDOs.add(RawGoodsDO.builder()
                                .id(rawGoodsId)
                                .organId(organId)
                                .orderId(orderId)
                                .rawGoodsId(plateXmlVO.getItemCode())
                                .goodsName(plateXmlVO.getName())
                                .material(plateXmlVO.getMaterial())
                                .color(plateXmlVO.getCoatingObverse())
                                .colorBlack(plateXmlVO.getCoatingReverse())
                                .texture(Boolean.valueOf(plateXmlVO.getGrained()))
                                .thickness(Double.parseDouble(plateXmlVO.getThickness()))
                                .brand(plateXmlVO.getBrand())
                                .spec(plateXmlVO.getSpecs())
                                .build());

                        GoodsDO goodsDO = GoodsDO.builder()
                                .id(goodsId)
                                .organId(organId)
                                .orderId(orderId)
                                .rawGoodsId(String.valueOf(rawGoodsId))
                                .goodsId(plateXmlVO.getItemCode())
                                .goodsName(plateXmlVO.getName())
                                .material(plateXmlVO.getMaterial())
                                .color(plateXmlVO.getCoatingObverse())
                                .colorBlack(plateXmlVO.getCoatingReverse())
                                .texture(Boolean.valueOf(plateXmlVO.getGrained()))
                                .width(BigDecimal.valueOf(Double.parseDouble(plateXmlVO.getWidth())))
                                .height(BigDecimal.valueOf(Double.parseDouble(plateXmlVO.getLength())))
                                .thickness(BigDecimal.valueOf(Double.parseDouble(plateXmlVO.getThickness())))
                                .brand(plateXmlVO.getBrand())
                                .spec(plateXmlVO.getSpecs())
                                .remark(plateXmlVO.getMemo())
                                .build();
                        goodsDOs.add(goodsDO);

                        // 小板信息

                        plateInfoChange(plateDetail, organId, orderId, goodsId, plateXmlVO.getBlockXmlVOS(), plateDOs, itemInfos, partsDOInfos, roomInfos, groupInfos, boxBasePositions, roomBasePositions);

                    }

                }
            }


//        取map中的值
        List<Object> orderBodyDOList = roomInfos.values().stream()
                .flatMap(innerMap -> innerMap.values().stream())
                .collect(Collectors.toList());


        List<Object> groupDOList = new ArrayList<>(groupInfos.values());
        List<Object> itemDOList = new ArrayList<>(itemInfos.values());
        List<Object> partDOList = new ArrayList<>(partsDOInfos.values());
        List<Object> partRemarks = new ArrayList<>(orderPartsRemarks.values());

        map.put(FieldConstants.RAW_GOODS, rawGoodsDOs);
        map.put(FieldConstants.GOODS, goodsDOs);
        map.put(FieldConstants.BODY, orderBodyDOList);
        map.put(FieldConstants.GROUP, groupDOList);
        map.put(FieldConstants.PLATE, plateDOs);
        map.put(FieldConstants.PARTS, partDOList);
        map.put(FieldConstants.ITEM, itemDOList);
        map.put(FieldConstants.PLATE_DETAIL, plateDetail);
        map.put(FieldConstants.PARTS_REMARK, partRemarks);

        return map;
    }

    // groupCodes提取code
    private String[] getGroupCode(String groupCode) {
        if (groupCode == null) {
            return new String[]{};
        }
        groupCode = groupCode.replaceAll("\\[|\\]", "");
        return groupCode.split(",");
    }

    // id得到
    private Map<String, Long> getId(PositionVO positionVO,
                                    Map<String, Map<String, OrderBodyDO>> roomInfos,
                                    Map<String, OrderGroupDO> groupInfos,
                                    Double plateNum,
                                    Double unregularNum,
                                    Long orderId,
                                    Long organId) {
        Map<String, Long> map = new HashMap<>();
        OrderGroupDO orderGroupDO;

        String roomNo = positionVO.getRoomCode(); //
        Map<String, OrderBodyDO> bodyMap = roomInfos.computeIfAbsent(roomNo, k -> new HashMap<>());

        String boxNo = positionVO.getBoxCode();
        OrderBodyDO bodyDO = bodyMap.get(boxNo);
        plateNum = plateNum + unregularNum;
        if (bodyDO != null) {
            bodyDO.setPlateNum((int) (bodyDO.getPlateNum() + plateNum))
                    .setUnregularNum((int) (bodyDO.getUnregularNum() + unregularNum));
        } else {
            Long roomId = (Long) identifierGenerator.nextId(null);
            if (!bodyMap.isEmpty()) {
                Set<String> keys = bodyMap.keySet();
                String key = keys.iterator().next();
                OrderBodyDO value = bodyMap.get(key);
                roomId = value.getRoomId();
            }
            bodyDO = OrderBodyDO.builder()
                    .id((Long) identifierGenerator.nextId(null))
                    .organId(organId)
                    .orderId(orderId)
                    .roomId(roomId)
                    .roomName(positionVO.getRoomName())
                    .name(positionVO.getBoxName())
                    .width(0.0)
                    .height(0.0)
                    .depth(0.0)
                    .plateNum((int) Math.round(plateNum))
                    .unregularNum((int) Math.round(unregularNum))
                    .build();
            bodyMap.put(boxNo, bodyDO);
        }

        Long bodyId = bodyDO.getId();
        Long groupId;
        // 加工组
        if ((positionVO.getGroupCode() != null && !positionVO.getGroupCode().isEmpty())
                || (positionVO.getGroupName() != null && !positionVO.getGroupName().isEmpty())) {
            orderGroupDO = groupInfos.get(positionVO.getGroupCode());
            if (orderGroupDO != null) {
                orderGroupDO.setBodyId(bodyId).setGroupTypeId(bodyId).setPlateNum((int) (orderGroupDO.getPlateNum() + plateNum))
                        .setUnregularNum((int) (orderGroupDO.getUnregularNum() + unregularNum));
            } else {
                orderGroupDO = OrderGroupDO.builder()
                        .id((Long) identifierGenerator.nextId(null))
                        .organId(organId)
                        .orderId(orderId)
                        .bodyId(bodyId)
                        .groupTypeId(bodyId)
                        .name(positionVO.getGroupName())
                        .width(0.0)
                        .height(0.0)
                        .depth(0.0)
                        .multiNum(0)
                        .plateNum((int) Math.round(plateNum))
                        .unregularNum((int) Math.round(unregularNum))
                        .build();
                groupInfos.put(positionVO.getGroupCode(), orderGroupDO);
            }
            groupId = orderGroupDO.getId();
        } else {
            groupId = 0L;
        }

        map.put(ROOM_ID, bodyDO.getRoomId());
        map.put(BODY_ID, bodyId);
        map.put(GROUP_ID, groupId);
        return map;
    }

    // 备注信息提取，判断长度是否超过255，超过255则截取255，并保存在备注中
    private String getRemark(List<RemarkXmlVO> finalRemarkXmlVOS) {
        StringBuilder sb = new StringBuilder();
        for (RemarkXmlVO remarkXmlVO : finalRemarkXmlVOS) {
            String info = remarkXmlVO.getInfo();
            if (info.length() > 255) {
                info = info.substring(0, 255);
            }
            sb.append(info);
        }
        return sb.toString();
    }

    public Map<String, Map<String, Object>> goodsInfoChange(Long organId, Long orderId, Map<String, List<EdgingXmlVO>> edgingMp, Map<String, List<HardwareXmlVO>> hardwareMp,
                                                            Map<String, List<AssemblyXmlVO>> assemblyMp,
                                                            Map<String, Map<String, OrderBodyDO>> roomInfos, Map<String, OrderGroupDO> groupInfos) { //这里的配件不存在String为null的情况

        Map<String, Map<String, Object>> map = new HashMap<>();
        Map<String, Object> orderItemMap = new HashMap<>();
        Map<String, Object> orderPartsDOMap = new HashMap<>();
        Map<String, Object> orderPartsRemarks = new HashMap<>();


        if (edgingMp != null) {
            for (String key : edgingMp.keySet()) {
                Long partsId = (Long) identifierGenerator.nextId(null);
                EdgingXmlVO edgingXmlVO = edgingMp.get(key).get(0);
                OrderPartsDO orderPartsDO = OrderPartsDO.builder()
                        .id(partsId)
                        .organId(organId)
                        .orderId(orderId)
                        .goodsId(edgingXmlVO.getItemCode())
                        .name(edgingXmlVO.getName())
                        .color(edgingXmlVO.getColor())
                        .material(edgingXmlVO.getMaterial())
                        .category("封边条")
                        .type("封边条")
                        .width(Double.valueOf(edgingXmlVO.getWidth()))
                        .length(Double.valueOf(edgingXmlVO.getLength()))
                        .thickness(Double.valueOf(edgingXmlVO.getThickness()))
                        .brand(edgingXmlVO.getBrand())
                        .factory(edgingXmlVO.getManufacturer())
                        .spec(edgingXmlVO.getSpecs())
                        .unit(edgingXmlVO.getUnit())
                        .isComposite(false)
                        .build();

                // 属性相同的配件的集合，可能存在房间 柜体 加工组 不同
                Map<String, List<EdgingXmlVO>> edgingGroupById = edgingMp.get(key).stream().collect(
                        Collectors.groupingBy(
                                edgingVO -> edgingVO.getRoomCode() + edgingVO.getBoxCode() + edgingVO.getGroupCode()
                        ));
                List<RemarkXmlVO> finalRemarkXmlVOS = new ArrayList<>();
                edgingGroupById.forEach((keysCode, value) -> {
                    PositionVO positionVO = PositionVO.builder()
                            .roomName(value.get(0).getRoomName())
                            .roomCode(value.get(0).getRoomCode())
                            .boxName(value.get(0).getBoxName())
                            .boxCode(value.get(0).getBoxCode())
                            .groupName(value.get(0).getGroupName())
                            .groupCode(value.get(0).getGroupCode())
                            .moduleName(value.get(0).getModuleName())
                            .moduleCode(value.get(0).getModuleCode())
                            .build();

                    double partsNum = 0.0;
                    Map<String, Long> idMap = getId(positionVO, roomInfos, groupInfos, 0.0, 0.0, orderId, organId);
                    for (EdgingXmlVO edgingVO : value) {
                        partsNum = partsNum + Double.parseDouble(edgingVO.getCount());

                        if (edgingVO.getRemarkXmlVOS() != null && edgingVO.getRemarkXmlVOS().getRemarkXmlVOList() != null && !edgingVO.getRemarkXmlVOS().getRemarkXmlVOList().isEmpty()) {
                            finalRemarkXmlVOS.addAll(edgingVO.getRemarkXmlVOS().getRemarkXmlVOList());
                        }
                    }
                    orderItemMap.put(key, OrderItemDO.builder()
                            .id((Long) identifierGenerator.nextId(null))
                            .organId(organId)
                            .orderId(orderId)
                            .type(2)
                            .partsId(partsId)
                            .groupId(idMap.get(GROUP_ID))
                            .roomId(idMap.get(ROOM_ID))
                            .bodyId(idMap.get(BODY_ID))
                            .num(partsNum)
                            .build());
                });

                orderPartsDO.setRemark(getRemark(finalRemarkXmlVOS));
                orderPartsDOMap.put(key, orderPartsDO);

                if (!finalRemarkXmlVOS.isEmpty()) {
                    orderPartsRemarks.put(key, OrderPartsRemark.builder()
                            .partsId(partsId)
                            .orderId(orderId)
                            .remark(finalRemarkXmlVOS.toString())
                            .build());
                }

            }
        }

        if (hardwareMp != null) { // 五金
            for (String key : hardwareMp.keySet()) {
                Long partsId = (Long) identifierGenerator.nextId(null);
                HardwareXmlVO hardwareXmlVO = hardwareMp.get(key).get(0);
                OrderPartsDO orderPartsDO = OrderPartsDO.builder()
                        .id(partsId)
                        .organId(organId)
                        .orderId(orderId)
                        .goodsId(hardwareXmlVO.getItemCode())
                        .name(hardwareXmlVO.getName())
                        .color(hardwareXmlVO.getColor())
                        .material(hardwareXmlVO.getMaterial())
                        .category("五金")
                        .type(hardwareXmlVO.getType())
                        .width(Double.valueOf(hardwareXmlVO.getWidth()))
                        .length(Double.valueOf(hardwareXmlVO.getLength()))
                        .thickness(Double.valueOf(hardwareXmlVO.getThickness()))
                        .brand(hardwareXmlVO.getBrand())
                        .factory(hardwareXmlVO.getManufacturer())
                        .spec(hardwareXmlVO.getSpecs())
                        .unit(hardwareXmlVO.getUnit())
                        .isComposite(false)
                        .subparts(hardwareXmlVO.getSubCodes())
                        .build();



                // 属性相同的配件的集合，可能存在房间 柜体 加工组 不同
                Map<String, List<HardwareXmlVO>> hardwareGroupById = hardwareMp.get(key).stream().collect(
                        Collectors.groupingBy(
                                hardwareVO -> hardwareVO.getRoomCode() + hardwareVO.getBoxCode() + hardwareVO.getGroupCode()
                        ));
                List<RemarkXmlVO> finalRemarkXmlVOS = new ArrayList<>();
                hardwareGroupById.forEach((keysCode, value) -> {
                    PositionVO positionVO = PositionVO.builder()
                            .roomName(value.get(0).getRoomName())
                            .roomCode(value.get(0).getRoomCode())
                            .boxName(value.get(0).getBoxName())
                            .boxCode(value.get(0).getBoxCode())
                            .groupName(value.get(0).getGroupName())
                            .groupCode(value.get(0).getGroupCode())
                            .moduleName(value.get(0).getModuleName())
                            .moduleCode(value.get(0).getModuleCode())
                            .build();

                    double partsNum = 0.0;
                    Map<String, Long> idMap = getId(positionVO, roomInfos, groupInfos, 0.0, 0.0, orderId, organId);
                    for (HardwareXmlVO hardwareVO : value) {
                        partsNum = partsNum + Double.parseDouble(hardwareVO.getCount());

                        if (hardwareVO.getRemarkXmlVOS() != null && hardwareVO.getRemarkXmlVOS().getRemarkXmlVOList() != null && !hardwareVO.getRemarkXmlVOS().getRemarkXmlVOList().isEmpty()) {
                            finalRemarkXmlVOS.addAll(hardwareVO.getRemarkXmlVOS().getRemarkXmlVOList());
                        }
                    }
                    orderItemMap.put(key, OrderItemDO.builder()
                            .id((Long) identifierGenerator.nextId(null))
                            .organId(organId)
                            .orderId(orderId)
                            .type(2)
                            .partsId(partsId)
                            .groupId(idMap.get(GROUP_ID))
                            .roomId(idMap.get(ROOM_ID))
                            .bodyId(idMap.get(BODY_ID))
                            .num(partsNum)
                            .build());
                });

                orderPartsDO.setRemark(getRemark(finalRemarkXmlVOS));
                orderPartsDOMap.put(key, orderPartsDO);

                if (!finalRemarkXmlVOS.isEmpty()) {
                    orderPartsRemarks.put(key, OrderPartsRemark.builder()
                            .partsId(partsId)
                            .orderId(orderId)
                            .remark(finalRemarkXmlVOS.toString())
                            .build());
                }

            }
        }

        if (assemblyMp != null) { // 组件
            for (String key : assemblyMp.keySet()) {
                Long partsId = (Long) identifierGenerator.nextId(null);
                AssemblyXmlVO assemblyXmlVO = assemblyMp.get(key).get(0);
                OrderPartsDO orderPartsDO = OrderPartsDO.builder()
                        .id(partsId)
                        .organId(organId)
                        .orderId(orderId)
                        .goodsId(assemblyXmlVO.getItemCode())
                        .name(assemblyXmlVO.getName())
                        .color(assemblyXmlVO.getColor())
                        .material(assemblyXmlVO.getMaterial())
                        .category("组件")
                        .type(assemblyXmlVO.getType())
                        .width(Double.valueOf(assemblyXmlVO.getWidth()))
                        .length(Double.valueOf(assemblyXmlVO.getLength()))
                        .thickness(Double.valueOf(assemblyXmlVO.getHeight()))
                        .brand(assemblyXmlVO.getBrand())
                        .factory(assemblyXmlVO.getManufacturer())
                        .spec(assemblyXmlVO.getSpecs())
                        .unit(assemblyXmlVO.getUnit())
                        .isComposite(true)
                        .subparts(assemblyXmlVO.getSubCodes())
                        .build();


                // 属性相同的配件的集合，可能存在房间 柜体 加工组 不同
                Map<String, List<AssemblyXmlVO>> assemblyGroupById = assemblyMp.get(key).stream().collect(
                        Collectors.groupingBy(
                                assemblyVO -> assemblyVO.getRoomCode() + assemblyVO.getBoxCode() + assemblyVO.getGroupCode()
                        ));
                List<RemarkXmlVO> finalRemarkXmlVOS = new ArrayList<>();
                assemblyGroupById.forEach((keysCode, value) -> {
                    PositionVO positionVO = PositionVO.builder()
                            .roomName(value.get(0).getRoomName())
                            .roomCode(value.get(0).getRoomCode())
                            .boxName(value.get(0).getBoxName())
                            .boxCode(value.get(0).getBoxCode())
                            .groupName(value.get(0).getGroupName())
                            .groupCode(value.get(0).getGroupCode())
                            .moduleName(value.get(0).getModuleName())
                            .moduleCode(value.get(0).getModuleCode())
                            .build();

                    double partsNum = 0.0;
                    Map<String, Long> idMap = getId(positionVO, roomInfos, groupInfos, 0.0, 0.0, orderId, organId);
                    for (AssemblyXmlVO assemblyVO : value) {
                        partsNum = partsNum + Double.parseDouble(assemblyVO.getCount());

                        if (assemblyVO.getRemarkXmlVOS() != null && assemblyVO.getRemarkXmlVOS().getRemarkXmlVOList() != null && !assemblyVO.getRemarkXmlVOS().getRemarkXmlVOList().isEmpty()) {
                            finalRemarkXmlVOS.addAll(assemblyVO.getRemarkXmlVOS().getRemarkXmlVOList());
                        }
                    }
                    orderItemMap.put(key, OrderItemDO.builder()
                            .id((Long) identifierGenerator.nextId(null))
                            .organId(organId)
                            .orderId(orderId)
                            .type(2)
                            .partsId(partsId)
                            .groupId(idMap.get(GROUP_ID))
                            .roomId(idMap.get(ROOM_ID))
                            .bodyId(idMap.get(BODY_ID))
                            .num(partsNum)
                            .build());
                });

                orderPartsDO.setRemark(getRemark(finalRemarkXmlVOS));
                orderPartsDOMap.put(key, orderPartsDO);

                if (!finalRemarkXmlVOS.isEmpty()) {
                    orderPartsRemarks.put(key, OrderPartsRemark.builder()
                            .partsId(partsId)
                            .orderId(orderId)
                            .remark(finalRemarkXmlVOS.toString())
                            .build());
                }

            }
        }

        map.put("orderItemMap", orderItemMap);
        map.put("orderPartsDOMap", orderPartsDOMap);
        map.put("orderPartsRemarks", orderPartsRemarks);
        return map;
    }


    public List<Object> plateInfoChange(List<Object> plateDetails,
                                        Long organId,
                                        Long orderId,
                                        Long goodsId,
                                        BlockXmlVOS blockXmlVOS,
                                        List<Object> plateDOs,
                                        Map<String, Object> orderItemMap,
                                        Map<String, Object> partsDO,
                                        Map<String, Map<String, OrderBodyDO>> roomInfos,
                                        Map<String, OrderGroupDO> groupInfos,
                                        Map<String, Map<String, BasePosition>> boxBasePositionMap,
                                        Map<String, BasePosition> roomBasePositions) {
        if (ObjectUtil.isNotNull(blockXmlVOS) && CollUtil.isNotEmpty(blockXmlVOS.getBlockXmlVOList())) {
            for (BlockXmlVO blockXmlVO : blockXmlVOS.getBlockXmlVOList()) {

                long plateNo = idWorker.nextId();
                long obtainingTime = idWorker.obtainingTime();
                Long plateId = (Long) identifierGenerator.nextId(null);

                // 成品面积
                Double length = changeUnit(blockXmlVO.getLength(), blockXmlVO.getUnit(),DictTypeConstants.UNIT_LENGTH);
                Double width = changeUnit(blockXmlVO.getWidth(), blockXmlVO.getUnit(),DictTypeConstants.UNIT_LENGTH);
                BigDecimal area = BigDecimal.valueOf((length / 1000) * (width / 1000));

                // 开料面积
                Double lengthCutting = changeUnit(blockXmlVO.getCuttingWidth(), blockXmlVO.getUnit(),DictTypeConstants.UNIT_LENGTH);
                Double widthCutting = changeUnit(blockXmlVO.getCuttingLength(), blockXmlVO.getUnit(),DictTypeConstants.UNIT_LENGTH);
                BigDecimal cuttingAcreage = BigDecimal.valueOf((lengthCutting / 1000) * (widthCutting / 1000));
                // 开门类型获取
                int doorType = Integer.parseInt(dictDataApi.parseDictData(DictTypeConstants.DOOR_OPENING_DIRECTIONS, blockXmlVO.getOpenDirection()).getData().getValue());

                // 板材数量获取
                double plateNum = 0.0;
                double unregularNum = 0.0;
                if (convertToBoolean(blockXmlVO.getUnregular())) {
                    unregularNum = 1.0;
                } else {
                    plateNum = 1.0;
                }
                PositionVO positionVO = PositionVO.builder()
                        .roomName(blockXmlVO.getRoomName())
                        .roomCode(blockXmlVO.getRoomCode())
                        .boxName(blockXmlVO.getBoxName())
                        .boxCode(blockXmlVO.getBoxCode())
                        .groupName(blockXmlVO.getGroupName())
                        .groupCode(blockXmlVO.getGroupCodes())
                        .moduleName(blockXmlVO.getModuleName())
                        .moduleCode(blockXmlVO.getModuleCode())
                        .build();

                Map<String, Long> idMap = getId(positionVO, roomInfos, groupInfos, plateNum, unregularNum, orderId, organId);

                // 柜体基点坐标
                BasePosition boxBasePoint = null;
                if (boxBasePositionMap.get(blockXmlVO.getRoomCode()) != null){
                    if (boxBasePositionMap.get(blockXmlVO.getRoomCode()).get(blockXmlVO.getBoxCode()) != null){
                        boxBasePoint = boxBasePositionMap.get(blockXmlVO.getRoomCode()).get(blockXmlVO.getBoxCode()).setBasePoint(String.valueOf(idMap.get("bodyId")));
                    }
                }

                // 房间基点坐标
                BasePosition roomBasePoint = null;
                if (roomBasePositions.get(blockXmlVO.getRoomCode()) != null){
                    roomBasePoint = roomBasePositions.get(blockXmlVO.getRoomCode()).setBasePoint(String.valueOf(idMap.get("roomId")));
                }
                // 板类型
                int plateType = Integer.parseInt(dictDataApi.parseDictData(DictTypeConstants.PLATE_TYPE, blockXmlVO.getType()).getData().getValue());
                PlateDO plateDO = PlateDO.builder()
                        .id(plateId)
                        .organId(organId)
                        .orderId(orderId)
                        .name(blockXmlVO.getName())
                        .plateNo((obtainingTime) + Long.toString(plateNo).substring(2))
                        .type(plateType)
                        .goodsId(goodsId)
                        .width(BigDecimal.valueOf(Double.parseDouble(blockXmlVO.getWidth())))
                        .height(BigDecimal.valueOf(Double.parseDouble(blockXmlVO.getLength())))
                        .thickness(BigDecimal.valueOf(Double.parseDouble(blockXmlVO.getThickness())))
                        .splitHeight(BigDecimal.valueOf(Double.parseDouble(blockXmlVO.getLength())))
                        .splitThickness(BigDecimal.valueOf(Double.parseDouble(blockXmlVO.getThickness())))
                        .splitWidth(BigDecimal.valueOf(Double.parseDouble(blockXmlVO.getWidth())))
                        .area(area)
                        .texture(Integer.valueOf(dictDataApi.parseDictData(DictTypeConstants.GRAIN_TYPE, blockXmlVO.getTexture()).getData().getValue()))
                        .holeFace(Integer.valueOf(dictDataApi.parseDictData(DictTypeConstants.TYPOGRAPHY_TYPE, blockXmlVO.getLayoutFace()).getData().getValue()))
                        .isDoor(doorType != 0)
                        .openDoorType(doorType)
                        .isSpecialShaped(convertToBoolean(blockXmlVO.getUnregular()))
                        .roomName(positionVO.getRoomName())
                        .bodyName(positionVO.getBoxName())
                        .customPlateNoBuilder(new StringBuilder())
                        .build();

                orderItemMap.put(blockXmlVO.getProductionCode(), OrderItemDO.builder()
                        .id((Long) identifierGenerator.nextId(null))
                        .organId(organId)
                        .orderId(orderId)
                        .type(1)
                        .plateId(plateId)
                        .groupId(idMap.get(GROUP_ID))
                        .roomId(idMap.get(ROOM_ID))
                        .bodyId(idMap.get(BODY_ID))
                        .num(1.0)
                        .build());

                // 基点坐标获取
                BasePosition plateBasePosition = BasePosition.builder()
//                        .basePoint(blockXmlVO.getProductionCode())
                        .basePoint(String.valueOf(plateId))
                        .basePointX(Double.valueOf(blockXmlVO.getBasePointX()))
                        .basePointY(Double.valueOf(blockXmlVO.getBasePointY()))
                        .basePointZ(Double.valueOf(blockXmlVO.getBasePointZ()))
                        .axisXrotate(Double.valueOf(blockXmlVO.getAxisXrotate()))
                        .axisYrotate(Double.valueOf(blockXmlVO.getAxisYrotate()))
                        .axisZrotate(Double.valueOf(blockXmlVO.getAxisZrotate()))
                        .build();
                PlateDetail plateDetail = PlateDetail.builder()
                        .organId(organId)
                        .orderId(orderId)
                        .plateId(plateId)
                        .plateNo(plateDO.getPlateNo())
                        .name(plateDO.getName())
                        .customPlateNo(blockXmlVO.getDesignCode())
                        .roomNo(blockXmlVO.getRoomCode())
                        .roomsName(blockXmlVO.getRoomName())
                        .bodyNo(blockXmlVO.getBoxCode())
                        .bodyName(blockXmlVO.getBoxName())
                        .groupNo(blockXmlVO.getGroupCodes())
                        .groupName(blockXmlVO.getGroupName())
                        .has2DModel(false)
                        .has3DModel(false)
                        .texture(plateDO.getTexture())
                        .typographicFace(plateDO.getHoleFace())
                        .openDoorType(plateDO.getOpenDoorType())
                        .boardType(blockXmlVO.getType())
                        .multiNum(Integer.valueOf(blockXmlVO.getMultipleNumber()))
                        .plateWidth(plateDO.getWidth())
                        .plateLength(plateDO.getHeight())
                        .acreage(plateDO.getArea())
                        .roomBasePosition(roomBasePoint)
                        .bodyBasePosition(boxBasePoint)
                        .plateBasePosition(plateBasePosition)
                        .splitLength(BigDecimal.valueOf(Long.parseLong(blockXmlVO.getCuttingLength())))
                        .splitWidth(BigDecimal.valueOf(Long.parseLong(blockXmlVO.getCuttingWidth())))
                        .sealAcreage(cuttingAcreage)
                        .pointDetail(new ArrayList<>())
                        .rawPointDetail(new ArrayList<>())
                        .basePointDetail(new ArrayList<>())
                        .holeCount(new HashMap<>())
                        .holeDetail(new ArrayList<>())
                        .contourCount(new HashMap<>())
                        .contourDetail(new ArrayList<>())
                        .sideHoleDetail(new ArrayList<>())
                        .sideRemark(new HashMap<>())
                        .plateExtraRemark(new JSONObject())
                        .isUnRegular(plateDO.getIsSpecialShaped())
                        .build();
                // 小板、es 封边值
                addSealEdge(plateDO, plateDetail, blockXmlVO.getOutlineXmlVO(), partsDO, roomInfos, groupInfos, orderItemMap);
                // 偏移量 不含封边
                addPointDetail(plateDO, plateDetail, blockXmlVO.getCuttingOutlineXmlVO());
                addPointDetail(plateDO, plateDetail, blockXmlVO.getRawOutlineXmlVO()); // 坯料
                // 孔数据
                addHole(plateDO, plateDetail, blockXmlVO.getHoleXmlVOS());
                // 造型数据 (槽）, 加孤岛信息
                addContourDetail(plateDO, plateDetail, blockXmlVO.getGrooveXmlVOS(), blockXmlVO.getIsletXmlVOS());
                // 造型数据（孤岛）
//                addIslandDetail(plateDetail, blockXmlVO.getIsletXmlVOS());
                // 小板关联配件
                addParts(plateDetail, blockXmlVO.getCorrelationXmlVOS(),partsDO);
                // 小板备注信息
                addRemark(plateDO, plateDetail, blockXmlVO);


                plateDOs.add(plateDO);
                plateDetails.add(plateDetail);
            }

        }
        return plateDetails;
    }


    // 小板关联配件添加
    private void addParts(PlateDetail plateDetail, CorrelationXmlVOS correlationXmlVOS, Map<String, Object> partsDOMap) {
        List<PartsInfo> partsInfos = new ArrayList<>();
        if (correlationXmlVOS != null && correlationXmlVOS.getCorrelationXmlVOList() != null && correlationXmlVOS.getCorrelationXmlVOList().size() > 0) {
            for (CorrelationXmlVO correlationXmlVO : correlationXmlVOS.getCorrelationXmlVOList()) {
                String partCode;
                if (correlationXmlVO.getItemCode() == null) {
                    partCode = correlationXmlVO.getName() + correlationXmlVO.getColor() + correlationXmlVO.getMaterial() + correlationXmlVO.getSpecs()
                            + correlationXmlVO.getMaterial() + correlationXmlVO.getBrand() + correlationXmlVO.getType();
                } else {
                    partCode = correlationXmlVO.getItemCode();
                }
                // 获取配件信息
                OrderPartsDO orderPartsDO = (OrderPartsDO) partsDOMap.get(partCode);
                // 板件上面添加配件信息
                partsInfos.add(PartsInfo.builder()
                        .id(orderPartsDO.getId())
                        .name(orderPartsDO.getName())
                        .partNum(Double.valueOf(correlationXmlVO.getCount()))
                        .unit(orderPartsDO.getUnit())
                        .build());

            }
            plateDetail.setPartsInfos(partsInfos);
        }
    }

    // 是否转换布尔值
    public Boolean convertToBoolean(String str) {
        Boolean isTrue = false;
        switch (str) {
            case "是":
                isTrue = true;
                break;
            default:
                isTrue = false;
                break;
        }
        return isTrue;
    }

    // 封边值相关信息添加 (原始点明细)
    private void addSealEdge(PlateDO plateDO, PlateDetail plateDetail, OutlineXmlVO outlineXmlVO, Map<String, Object> partsDOMap,
                             Map<String, Map<String, OrderBodyDO>> roomInfos, Map<String, OrderGroupDO> groupInfos, Map<String, Object> orderItemMap) {
        BigDecimal sealLeft = BigDecimal.valueOf(0);
        BigDecimal sealRight = BigDecimal.valueOf(0);
        BigDecimal sealUp = BigDecimal.valueOf(0);
        BigDecimal sealDown = BigDecimal.valueOf(0);

        if (outlineXmlVO != null && outlineXmlVO.getPointXmlVOList() != null && !outlineXmlVO.getPointXmlVOList().isEmpty()) {
            ExtraVO extraVO = ExtraVO.builder()
                    .edgeRemarks(new ArrayList<>())
                    .rectSealDetail(new ArrayList<>())
                    .build();
            int indexId = 0;
            for (PointXmlVO pointXmlVO : outlineXmlVO.getPointXmlVOList()) {
                if (!(pointXmlVO.getItemCode() == null && pointXmlVO.getEdgingName() == null && pointXmlVO.getEdgingColor() == null
                        && pointXmlVO.getEdgingMaterial() == null && (pointXmlVO.getEdgingThickness() == null || pointXmlVO.getEdgingThickness().trim().equals("0")))) {
                    double x = Double.parseDouble(pointXmlVO.getPointX());
                    double y = Double.parseDouble(pointXmlVO.getPointY());
                    BigDecimal size = new BigDecimal(pointXmlVO.getEdgingThickness());
                    // 封边条信息获取
                    String item = pointXmlVO.getItemCode();
                    if (StringUtils.isEmpty(item)){
                        item = pointXmlVO.getEdgingName() + pointXmlVO.getEdgingColor() + pointXmlVO.getEdgingMaterial() + pointXmlVO.getEdgingWidth() + pointXmlVO.getEdgingThickness();
                    }
                    String kItem = item;
                    partsDOMap.forEach((k, v) -> {
                        if (StringUtils.isEmpty(kItem)) {
                            Long partId = (Long) identifierGenerator.nextId(null);
                            if (k.contains(kItem)){ // 存在
                                OrderPartsDO orderPartsDO = (OrderPartsDO) v;
                                partId = orderPartsDO.getId();
                            }
                            // 则表明配件需要新加，item需要新加，body和group需要修改或是新增
                            OrderPartsDO orderPartsDO = OrderPartsDO.builder()
                                    .id(partId)
                                    .name(pointXmlVO.getEdgingName())
                                    .type("封边条")
                                    .organId(plateDO.getOrganId())
                                    .orderId(plateDO.getOrderId())
                                    .material(pointXmlVO.getEdgingMaterial())
                                    .unit(pointXmlVO.getCountUnit())
                                    .isComposite(false)
                                    .build();
                            partsDOMap.put(kItem, orderPartsDO);
                            PositionVO positionVO = PositionVO.builder()
                                    .roomName(plateDetail.getRoomsName())
                                    .roomCode(plateDetail.getRoomNo())
                                    .boxName(plateDetail.getBodyName())
                                    .boxCode(plateDetail.getBodyNo())
                                    .groupName(plateDetail.getGroupName())
                                    .groupCode(plateDetail.getGroupNo())
                                    .build();
                            // 存在，直接添加item、body、group
                            Map<String, Long> idMap = getId(positionVO, roomInfos, groupInfos, 0.0, 0.0, plateDO.getOrderId(), plateDO.getOrganId());
                            // 封边总长度单位换算
                            Double count = changeUnit(pointXmlVO.getCount(), pointXmlVO.getCountUnit(),DictTypeConstants.UNIT_LENGTH);
                            orderItemMap.put(kItem, OrderItemDO.builder()
                                    .id((Long) identifierGenerator.nextId(null))
                                    .organId(plateDO.getOrganId())
                                    .orderId(plateDO.getOrderId())
                                    .type(2)
                                    .partsId(orderPartsDO.getId())
                                    .groupId(idMap.get(GROUP_ID))
                                    .roomId(idMap.get(ROOM_ID))
                                    .bodyId(idMap.get(BODY_ID))
                                    .num(count)
                                    .build());
                        }

                    });

                    if (!plateDO.getIsSpecialShaped()) {
                        if (x == 0 && y == 0) {
                            sealDown = size;
                        }
                        if (x != 0 && y == 0) {
                            sealRight = size;
                        }
                        if (x != 0 && y != 0) {
                            sealUp = size;
                        }
                        if (x == 0 && y != 0) {
                            sealLeft = size;
                        }
                    }

                    plateDetail.getRawPointDetail().add(PointDetail.builder()
//                        .id(pointXmlVO.getId())
                            .pointX(x)
                            .pointY(y)
                            .curve(Double.parseDouble(pointXmlVO.getCurvature()))
                            .radius(Double.parseDouble(pointXmlVO.getRadius()))
                            .sealSize(size)
                            .build());
                    extraVO.getEdgeRemarks().add(pointXmlVO.getRemark());
                    extraVO.getRectSealDetail().add(RectSealVO.builder()
                            .pointID(String.valueOf(indexId))
                            .reservedEdge(pointXmlVO.getScale())
                            .sealColor(pointXmlVO.getEdgingColor())
                            .sealSize(pointXmlVO.getEdgingThickness())
                            .build());
                    indexId++;
                }

            }
            String jsonString = JSON.toJSONString(extraVO);
            JSONObject jsonObject = JSON.parseObject(jsonString);
            plateDetail.setPlateExtraRemark(jsonObject);
        }
        plateDetail.setSealUp(sealUp).setSealDown(sealDown).setSealLeft(sealLeft).setSealRight(sealRight);
        plateDO.setSealUp(sealUp).setSealDown(sealDown).setSealLeft(sealLeft).setSealRight(sealRight);
    }

    // 点明细（不含封边）
    private void addPointDetail(PlateDO plateDO, PlateDetail plateDetail, CuttingOutlineXmlVO cuttingOutlineXmlVO) {
        if (cuttingOutlineXmlVO != null) {
            plateDO.setOffsetX(BigDecimal.valueOf(Double.parseDouble(cuttingOutlineXmlVO.getReferenceOffsetX()))).
                    setOffsetY(BigDecimal.valueOf(Double.parseDouble(cuttingOutlineXmlVO.getReferenceOffsetY())));
            plateDetail.setOffsetX(plateDO.getOffsetX()).setOffsetY(plateDO.getOffsetY());
            if (cuttingOutlineXmlVO.getPointXmlVOList() != null && cuttingOutlineXmlVO.getPointXmlVOList().size() > 0) {
                for (PointXmlVO pointXmlVO : cuttingOutlineXmlVO.getPointXmlVOList()) {
                    plateDetail.getPointDetail().add(PointDetail.builder()
//                            .id(pointXmlVO.getId())
                            .pointX(Double.parseDouble(pointXmlVO.getPointX()))
                            .pointY(Double.parseDouble(pointXmlVO.getPointY()))
                            .curve(Double.parseDouble(pointXmlVO.getCurvature()))
                            .radius(Double.parseDouble(pointXmlVO.getRadius()))
                            .process(pointXmlVO.getProcess())
                            .build());
                }
            }
        }
    }

    // 坯料
    private void addPointDetail(PlateDO plateDO, PlateDetail plateDetail, RawOutlineXmlVO rawOutlineXmlVO) {
        if (rawOutlineXmlVO != null) {
//            if (rawOutlineXmlVO.getReferenceOffsetX() == null) {
//                rawOutlineXmlVO.setReferenceOffsetX("0");
//            }
//            if (rawOutlineXmlVO.getReferenceOffsetY() == null) {
//                rawOutlineXmlVO.setReferenceOffsetY("0");
//            }
//            plateDO.setOffsetX(BigDecimal.valueOf(Double.parseDouble(rawOutlineXmlVO.getReferenceOffsetX()))).
//                    setOffsetY(BigDecimal.valueOf(Double.parseDouble(rawOutlineXmlVO.getReferenceOffsetY())));
//            plateDetail.setOffsetX(plateDO.getOffsetX()).setOffsetY(plateDO.getOffsetY());
            if (rawOutlineXmlVO.getPointXmlVOList() != null && rawOutlineXmlVO.getPointXmlVOList().size() > 0) {
                for (PointXmlVO pointXmlVO : rawOutlineXmlVO.getPointXmlVOList()) {
                    plateDetail.getBasePointDetail().add(PointDetail.builder()
//                            .id(pointXmlVO.getId())
                            .pointX(Double.parseDouble(pointXmlVO.getPointX()))
                            .pointY(Double.parseDouble(pointXmlVO.getPointY()))
                            .curve(Double.parseDouble(pointXmlVO.getCurvature()))
                            .radius(Double.parseDouble(pointXmlVO.getRadius()))
                            .process(pointXmlVO.getProcess())
                            .build());
                }
            }
        }
    }

    // 孔
    private void addHole(PlateDO plateDO, PlateDetail plateDetail, HoleXmlVOS holeXmlVOS) {
        if (holeXmlVOS == null || holeXmlVOS.getHoleXmlVOList() == null || holeXmlVOS.getHoleXmlVOList().isEmpty()) {
            return;
        }

        Map<String, Integer> holeCountMap = extractHoleCount(holeXmlVOS);
        updatePlateDetailHoleCount(plateDetail, holeCountMap);
        updatePlateDOHoleCount(plateDO, holeXmlVOS);
        updatePlateDOFilterTypeIfThroughHolesExist(plateDO, holeXmlVOS);
        addHoleDetailsToPlateDetail(plateDetail, holeXmlVOS.getHoleXmlVOList());
    }

    private Map<String, Integer> extractHoleCount(HoleXmlVOS holeXmlVOS) {
        Map<String, Integer> holeCountMap = new HashMap<>();
        holeCountMap.put("count", Integer.valueOf(holeXmlVOS.getCount()));
        holeCountMap.put("countFaceA", Integer.valueOf(holeXmlVOS.getCountFaceA()));
        holeCountMap.put("countFaceB", Integer.valueOf(holeXmlVOS.getCountFaceB()));
        holeCountMap.put("countSide", Integer.valueOf(holeXmlVOS.getCountSide()));
        holeCountMap.put("countSideL", Integer.valueOf(holeXmlVOS.getCountSideL()));
        holeCountMap.put("countSideD", Integer.valueOf(holeXmlVOS.getCountSideD()));
        holeCountMap.put("countSideR", Integer.valueOf(holeXmlVOS.getCountSideR()));
        holeCountMap.put("countSideU", Integer.valueOf(holeXmlVOS.getCountSideU()));
        holeCountMap.put("countBevelled", Integer.valueOf(holeXmlVOS.getCountBevelled()));
        holeCountMap.put("countLocking", Integer.valueOf(holeXmlVOS.getCountLocking()));
        holeCountMap.put("countBuildIn", Integer.valueOf(holeXmlVOS.getCountBuildIn()));
        holeCountMap.put("countHinge", Integer.valueOf(holeXmlVOS.getCountHinge()));
        holeCountMap.put("countThrough", Integer.valueOf(holeXmlVOS.getCountThrough()));
        return holeCountMap;
    }

    private void updatePlateDetailHoleCount(PlateDetail plateDetail, Map<String, Integer> holeCountMap) {
        plateDetail.getHoleCount().putAll(holeCountMap);
    }

    private void updatePlateDOHoleCount(PlateDO plateDO, HoleXmlVOS holeXmlVOS) {
        plateDO.setFrontHoleCount(Integer.valueOf(holeXmlVOS.getCountFaceA()));
        plateDO.setBackHoleCount(Integer.valueOf(holeXmlVOS.getCountFaceB()));
        plateDO.setSideHoleCount(Integer.valueOf(holeXmlVOS.getCountSide()));
    }

    private void updatePlateDOFilterTypeIfThroughHolesExist(PlateDO plateDO, HoleXmlVOS holeXmlVOS) {
        if (holeXmlVOS.getCountThrough() != null && Integer.parseInt(holeXmlVOS.getCountThrough()) > 0) {
            plateDO.setFilterType(plateDO.getFilterType() + ",2");
        }
    }

    private void addHoleDetailsToPlateDetail(PlateDetail plateDetail, List<HoleXmlVO> holeXmlVOList) {
        for (HoleXmlVO holeXmlVO : holeXmlVOList) {
            HoleDetail holeDetail = createHoleDetail(holeXmlVO);
            plateDetail.getHoleDetail().add(holeDetail);
        }
    }

    private HoleDetail createHoleDetail(HoleXmlVO holeXmlVO) {
        DictDataRespDTO faceType = dictDataApi.parseDictData(DictTypeConstants.HOLE_FACE, holeXmlVO.getFace()).getData();
        Integer faceTypeValue = faceType != null ? Integer.parseInt(faceType.getValue()) : 2;
        Integer direction = Integer.valueOf(dictDataApi.parseDictData(DictTypeConstants.HOLE_DIRECTION, holeXmlVO.getDirection()).getData().getValue());
//        DictDataRespDTO holeType = holeXmlVO.getType() == null ? null : dictDataApi.parseDictData(DictTypeConstants.HOLE_TYPE, holeXmlVO.getType()).getData();
        Double radius = holeXmlVO.getDiameter() != null ? Double.parseDouble(holeXmlVO.getDiameter()) / 2 : 0;
        Double depth = holeXmlVO.getDepth() != null ? Double.parseDouble(holeXmlVO.getDepth()) : 0;

        return HoleDetail.builder()
                .holeName(holeXmlVO.getName())
                .faceType(faceTypeValue)
                .direction(direction)
                .holeTypeStr(holeXmlVO.getType())
                .radius(radius)
                .depth(depth)
                .startX(holeXmlVO.getStartX() != null ? Double.parseDouble(holeXmlVO.getStartX()) : 0)
                .startY(holeXmlVO.getStartY() != null ? Double.parseDouble(holeXmlVO.getStartY()) : 0)
                .startZ(holeXmlVO.getStartZ() != null ? Double.parseDouble(holeXmlVO.getStartZ()) : 0)
                .endX(holeXmlVO.getEndX() != null ? Double.parseDouble(holeXmlVO.getEndX()) : 0)
                .endY(holeXmlVO.getEndY() != null ? Double.parseDouble(holeXmlVO.getEndY()) : 0)
                .endZ(holeXmlVO.getEndZ() != null ? Double.parseDouble(holeXmlVO.getEndZ()) : 0)
                .build();
    }

    // 造型
    private void addContourDetail(PlateDO plateDO, PlateDetail plateDetail, GrooveXmlVOS grooveXmlVOS, IsletXmlVOS isletXmlVOS) {
        if (grooveXmlVOS == null || ObjectUtils.allNull(grooveXmlVOS)) {
            return;
        }

        Map<String, Integer> contourCount = extractContourCount(grooveXmlVOS);
        updatePlateDetailWithContourCount(plateDetail, contourCount);
        updatePlateDOWithContourCount(plateDO, grooveXmlVOS);
        updatePlateDOFilterTypeIfThroughGroovesExist(plateDO, grooveXmlVOS);

        if (grooveXmlVOS.getGrooveXmlVOList() != null && !grooveXmlVOS.getGrooveXmlVOList().isEmpty()) {
            addGrooveDetailsToPlateDetail(plateDetail, grooveXmlVOS.getGrooveXmlVOList(), isletXmlVOS);
        }
    }

    private Map<String, Integer> extractContourCount(GrooveXmlVOS grooveXmlVOS) {
        Map<String, Integer> contourCount = new HashMap<>();
        contourCount.put("count", Integer.valueOf(grooveXmlVOS.getCount()));
        contourCount.put("countFaceA", Integer.valueOf(grooveXmlVOS.getCountFaceA()));
        contourCount.put("countFaceB", Integer.valueOf(grooveXmlVOS.getCountFaceB()));
        contourCount.put("countSide", Integer.valueOf(grooveXmlVOS.getCountSide()));
        contourCount.put("countSideL", Integer.valueOf(grooveXmlVOS.getCountSideL()));
        contourCount.put("countSideD", Integer.valueOf(grooveXmlVOS.getCountSideD()));
        contourCount.put("countSideR", Integer.valueOf(grooveXmlVOS.getCountSideR()));
        contourCount.put("countSideU", Integer.valueOf(grooveXmlVOS.getCountSideU()));
        contourCount.put("countBevelled", Integer.valueOf(grooveXmlVOS.getCountBevelled()));
        contourCount.put("countRectangle", Integer.valueOf(grooveXmlVOS.getCountRectangle()));
        contourCount.put("count2V", Integer.valueOf(grooveXmlVOS.getCount2V()));
        contourCount.put("count3D", Integer.valueOf(grooveXmlVOS.getCount3D()));
        contourCount.put("countThrough", Integer.valueOf(grooveXmlVOS.getCountThrough()));
        return contourCount;
    }

    private void updatePlateDetailWithContourCount(PlateDetail plateDetail, Map<String, Integer> contourCount) {
        plateDetail.getContourCount().putAll(contourCount);
        plateDetail.setHas2DModel(contourCount.getOrDefault("count2V", 0) > 0);
        plateDetail.setHas3DModel(contourCount.getOrDefault("count3D", 0) > 0);
    }

    private void updatePlateDOWithContourCount(PlateDO plateDO, GrooveXmlVOS grooveXmlVOS) {
        plateDO.setFrontModelCount(Integer.valueOf(grooveXmlVOS.getCountFaceA()));
        plateDO.setBackModelCount(Integer.valueOf(grooveXmlVOS.getCountFaceB()));
    }

    private void updatePlateDOFilterTypeIfThroughGroovesExist(PlateDO plateDO, GrooveXmlVOS grooveXmlVOS) {
        if (grooveXmlVOS.getCountThrough() != null && Integer.parseInt(grooveXmlVOS.getCountThrough()) > 0) {
            plateDO.setFilterType(plateDO.getFilterType() + ",1");
        }
    }

    private void addGrooveDetailsToPlateDetail(PlateDetail plateDetail, List<GrooveXmlVO> grooveXmlVOList, IsletXmlVOS isletXmlVOS) {
        for (GrooveXmlVO grooveXmlVO : grooveXmlVOList) {
//            int faceType = parseFaceType(grooveXmlVO.getFace());
            ModelDetail modelDetail = createModelDetail(grooveXmlVO, isletXmlVOS);
            plateDetail.getContourDetail().add(modelDetail);
        }
    }

    private int parseFaceType(String face) {
        int faceType = Integer.parseInt(dictDataApi.parseDictData(DictTypeConstants.HOLE_FACE, face).getData().getValue());
        return faceType == 0 || faceType == 1 ? faceType : 2;
    }

    private ModelDetail createModelDetail(GrooveXmlVO grooveXmlVO, IsletXmlVOS isletXmlVOS) {
        // 槽内孤岛id转换
        String[] subIDs = null;
        if (grooveXmlVO.getSubIDs() != null) {
            subIDs = Arrays.stream(grooveXmlVO.getSubIDs().split(",")).map(String::valueOf).toArray(String[]::new);
        }
        return ModelDetail.builder()
                .modelID(Integer.valueOf(grooveXmlVO.getId()))
                .subIDs(subIDs)
                .type(grooveXmlVO.getType())
                .grooveFace(grooveXmlVO.getFace())
                .width(Double.parseDouble(grooveXmlVO.getWidth()))
                .length(Double.parseDouble(grooveXmlVO.getLength()))
                .depth(Double.parseDouble(grooveXmlVO.getDepth()))
                .knifeName(grooveXmlVO.getToolName())
                .toolNo(grooveXmlVO.getToolNo())
                .knifeRadius(Double.parseDouble(grooveXmlVO.getToolDiameter()) / 2)
                .round(Double.parseDouble(grooveXmlVO.getRound()))
                .redundance(Double.parseDouble(grooveXmlVO.getRedundance()))
                .tangentAngle(Double.parseDouble(grooveXmlVO.getTangentAngle()))
                .originModeling(getOriginModelingData(grooveXmlVO, subIDs, isletXmlVOS))
                .pointList(addPointDetail(grooveXmlVO.getPointXmlVOS()))
                .offSetList(addOffSetDetail(grooveXmlVO.getOffsetLineXmlVOS()))
                .mode(grooveXmlVO.getMode())
                .build();
    }

    // 造像轮廓数据
    private IOriginModelingData getOriginModelingData(GrooveXmlVO grooveXmlVO, String[] subIDs, IsletXmlVOS isletXmlVOS) {
        // 孤岛信息
        List<List<IContourData>> holes = null;
        if (subIDs != null && isletXmlVOS != null && isletXmlVOS.getIsletXmlVOList() != null) {
            holes = new ArrayList<>();
            // 孤岛信息整合
            Map<String, IsletXmlVO> isletMap = isletXmlVOS.getIsletXmlVOList().stream().collect(Collectors.toMap(IsletXmlVO::getId, Function.identity()));
            // 遍历subIDs
            for (String subID : subIDs) {
                // 获取孤岛信息
                List<IContourData> hole = getHole(subID, isletMap);
                holes.add(hole);
            }

        }
        return IOriginModelingData.builder()
                .knifeRadius(Double.parseDouble(grooveXmlVO.getToolDiameter()) / 2)
                .direction(grooveXmlVO.getDirection())
                .outline(addOutlineDetail(grooveXmlVO.getOutlineXmlVO()))
                .holes(holes)
                .addLen(Double.valueOf(grooveXmlVO.getLengthExtend()))
                .addDepth(Double.valueOf(grooveXmlVO.getDepthExtend()))
                .addWidth(Double.valueOf(grooveXmlVO.getWidthExtend()))
                .build();
    }

    // 孤岛信息
    private List<IContourData> getHole(String subID, Map<String, IsletXmlVO> isletMap) {
        return isletMap.get(subID).getPointXmlVOS().getPointXmlVOList().stream().map(pointXmlVO -> IContourData.builder()
                .pts(new Point(Double.parseDouble(pointXmlVO.getPointX()), Double.parseDouble(pointXmlVO.getPointY()), Double.parseDouble(pointXmlVO.getPointZ())))
                .buls(Double.parseDouble(pointXmlVO.getCurvature())).radius(Double.parseDouble(pointXmlVO.getRadius())).build()).collect(Collectors.toList());
    }
    // 原始造型(外)轮廓信息
    private List<IContourData> addOutlineDetail(OutlineXmlVO outlineXmlVO) {
        if (outlineXmlVO == null || outlineXmlVO.getPointXmlVOList() == null) {
            return null;
        }
        return outlineXmlVO.getPointXmlVOList().stream().map(pointXmlVO -> IContourData.builder()
                .pts(new Point(Double.parseDouble(pointXmlVO.getPointX()), Double.parseDouble(pointXmlVO.getPointY()), Double.parseDouble(pointXmlVO.getPointZ())))
                .buls(Double.parseDouble(pointXmlVO.getCurvature()))
                .radius(Double.parseDouble(pointXmlVO.getRadius()))
                .build()).collect(Collectors.toList());
    }
    // 点列表的赋值
    private List<PointList> addPointDetail(PointXmlVOS pointXmlVOS) {
        List<PointList> pointLists = new ArrayList<>();
        if (pointXmlVOS != null && pointXmlVOS.getPointXmlVOList() != null && !pointXmlVOS.getPointXmlVOList().isEmpty()) {
            for (PointXmlVO pointXmlVO : pointXmlVOS.getPointXmlVOList()) {
                pointLists.add(PointList.builder()
//                        .pointId(Integer.valueOf(pointXmlVO.getId()))
                        .pointX(Double.parseDouble(pointXmlVO.getPointX()))
                        .pointY(Double.parseDouble(pointXmlVO.getPointY()))
                        .pointZ(Double.parseDouble(pointXmlVO.getPointZ()))
                        .radius(Double.parseDouble(pointXmlVO.getRadius()))
//                        .curve(Double.parseDouble(pointXmlVO.getCurvature()))
                        .holeRadius(Double.parseDouble(pointXmlVO.getRadius()))
                        .build());
            }
        }
        return pointLists;
    }

    // 偏移量列表
    private List<OffSetList> addOffSetDetail(OffsetLineXmlVOS offsetLineXmlVOS) {
        List<OffSetList> offSetList = new ArrayList<>();
        if (offsetLineXmlVOS != null && offsetLineXmlVOS.getOffsetLineXmlVOList() != null && offsetLineXmlVOS.getOffsetLineXmlVOList().size() > 0) {
            for (OffsetLineXmlVO offsetLineXmlVO : offsetLineXmlVOS.getOffsetLineXmlVOList()) {
                offSetList.add(OffSetList.builder()
//                        .id(offsetLineXmlVO.getId())
                        .value(Double.parseDouble(offsetLineXmlVO.getOffset()))
                        .depth(Double.parseDouble(offsetLineXmlVO.getDepth()))
                        .angle(Double.parseDouble(offsetLineXmlVO.getTangentAngle()))
                        .name(offsetLineXmlVO.getToolName())
                        .radius(Double.parseDouble(offsetLineXmlVO.getToolDiameter()) / 2)
                        .build());
            }
        }
        return offSetList;
    }

    // 小板备注
    private void addRemark(PlateDO plateDO, PlateDetail plateDetail, BlockXmlVO blockXmlVO) {
        if (blockXmlVO.getRemarkXmlVOS() != null && blockXmlVO.getRemarkXmlVOS().getRemarkXmlVOList() != null
                && !blockXmlVO.getRemarkXmlVOS().getRemarkXmlVOList().isEmpty()) {
            for (RemarkXmlVO remarkXmlVO : blockXmlVO.getRemarkXmlVOS().getRemarkXmlVOList()) {
                plateDetail.getSideRemark().put(remarkXmlVO.getName(), remarkXmlVO.getInfo());
            }
            plateDO.setRemark(JSON.toJSONString(plateDetail.getSideRemark()));
        }
    }

    // 长度面积数值按单位转换
    public Double changeUnit(String lengthStr, String unit, String type) {
        DictDataRespDTO dictData = dictDataApi.parseDictData(type, unit).getData();
        Double length = Double.parseDouble(lengthStr);
        return length * Double.parseDouble(dictData.getValue());
    }
}
