package com.cf.imes.module.system.service.assemblyconfig;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.cf.imes.framework.common.enums.DeletedCodeEnum;
import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.common.util.Assert.AssertUtils;
import com.cf.imes.framework.common.util.json.JsonUtils;
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cf.imes.framework.mybatis.core.query.LambdaUpdateWrapperX;
import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils;
import com.cf.imes.module.executor.api.ordercomponent.OrderComponentApi;
import com.cf.imes.module.executor.api.ordercomponent.dto.OrderComponentListReqDTO;
import com.cf.imes.module.executor.api.ordercomponent.dto.OrderComponentListRespDTO;
import com.cf.imes.module.system.controller.admin.assemblyconfig.vo.AssemblyConfigImportReqVO;
import com.cf.imes.module.system.controller.admin.assemblyconfig.vo.AssemblyConfigListRespVO;
import com.cf.imes.module.system.controller.admin.assemblyconfig.vo.AssemblyConfigRespVO;
import com.cf.imes.module.system.controller.admin.assemblyconfig.vo.AssemblyConfigSaveReqVO;
import com.cf.imes.module.system.controller.admin.assemblyconfig.vo.AssemblyConfigStructureVO;
import com.cf.imes.module.system.dal.dataobject.assemblyconfig.AssemblyConfigDO;
import com.cf.imes.module.system.dal.dataobject.assemblyconfig.AssemblyConfigNameSeqDO;
import com.cf.imes.module.system.dal.mysql.assemblyconfig.AssemblyConfigMapper;
import com.cf.imes.module.system.dal.mysql.assemblyconfig.AssemblyConfigNameSeqMapper;
import com.cf.imes.module.system.enums.assemblyconfig.AssemblyConfigStatusEnum;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static com.cf.imes.module.system.enums.ErrorCodeConstants.ASSEMBLY_CONFIG_DO_CONFIG_EXIST;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ASSEMBLY_CONFIG_IMPORT_ORDER_COMPONENTS_QUERY_ERROR;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ASSEMBLY_CONFIG_NEW_CONFIG_NAME_EXIST;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ASSEMBLY_CONFIG_NOT_EXIST;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ASSEMBLY_CONFIG_NO_NEED_NEW_CONFIG;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ASSEMBLY_CONFIG_SAVE_TOPNAME_EXIST;

/**
 * 装配设置 ServiceImpl 接口实现类
 *
 * @author Gqr
 * @since 2026/2/25 15:11
 */
@Service
public class AssemblyConfigServiceImpl implements AssemblyConfigService {

    @Resource
    private OrderComponentApi orderComponentApi;

    @Resource
    private AssemblyConfigMapper assemblyConfigMapper;

    @Resource
    private AssemblyConfigNameSeqMapper assemblyConfigNameSeqMapper;

    @Override
    public void importAssemblyConfigFromOrders(AssemblyConfigImportReqVO reqVO) {
        Long organId = SecurityFrameworkUtils.getUserOrganId();

        // 1、获取订单列表下的所有部件
        OrderComponentListReqDTO orderComponentListReqDTO = new OrderComponentListReqDTO();
        orderComponentListReqDTO.setOrderIds(reqVO.getOrderIds());
        CommonResult<List<OrderComponentListRespDTO>> orderComponentListResult = orderComponentApi.getOrderComponentList(orderComponentListReqDTO);
        if (orderComponentListResult.isError()) {
            throw new ServiceException(ASSEMBLY_CONFIG_IMPORT_ORDER_COMPONENTS_QUERY_ERROR);
        }

        List<OrderComponentListRespDTO> orderComponentList = orderComponentListResult.getData();
        if (CollUtil.isEmpty(orderComponentList)) {
            return;
        }
        // 2、构建树 + 排序 + 生成结构hash
        List<AssemblyConfigStructureVO> roots = buildTreeAndComputeHash(orderComponentList);

        // 3、按 name 分组去重（同名、同结构只保留一条）
        Map<String, Map<String, AssemblyConfigStructureVO>> uniqueMap = new LinkedHashMap<>();
        for (AssemblyConfigStructureVO node : roots) {
            uniqueMap.computeIfAbsent(node.getName(), k -> new LinkedHashMap<>())
                    .putIfAbsent(node.getStructureHash(), node);
        }

        List<AssemblyConfigStructureVO> dedupedList = uniqueMap.values().stream()
                .flatMap(m -> m.values().stream())
                .toList();

        // 4、查询数据库已存在的结构
        List<String> names = dedupedList.stream()
                .map(AssemblyConfigStructureVO::getName)
                .distinct()
                .toList();

        List<AssemblyConfigDO> existConfigs = assemblyConfigMapper.selectList(
                new LambdaQueryWrapper<AssemblyConfigDO>()
                        .eq(AssemblyConfigDO::getOrganId, organId)
                        .in(AssemblyConfigDO::getComponentName, names)
                        .eq(AssemblyConfigDO::getDeleted, 0)
        );

        Map<String, Set<String>> existHashMap = existConfigs.stream()
                .collect(Collectors.groupingBy(
                        AssemblyConfigDO::getComponentName,
                        Collectors.mapping(AssemblyConfigDO::getStructureHash, Collectors.toSet())
                ));

        // 5、过滤数据库已存在的结构
        List<AssemblyConfigStructureVO> needImportList = dedupedList.stream()
                .filter(node -> {
                    Set<String> hashes = existHashMap.get(node.getName());
                    return hashes == null || !hashes.contains(node.getStructureHash());
                })
                .toList();

        if (needImportList.isEmpty()) return;

        // 6、批量生成 AssemblyConfigDO 并插入
        List<AssemblyConfigDO> importDOList = needImportList.stream()
                .map(node -> {
                    AssemblyConfigDO configDO = new AssemblyConfigDO();
                    configDO.setOrganId(organId);
                    configDO.setSourceComponentId(node.getSourceComponentId());
                    configDO.setComponentName(node.getName());
                    configDO.setBaseName(node.getName());
                    configDO.setStructureHash(node.getStructureHash());
                    configDO.setStructureJson(JsonUtils.zipString(JsonUtils.toJsonString(node)));
                    configDO.setStatus(AssemblyConfigStatusEnum.IMPORT.getStatus());
                    return configDO;
                })
                .toList();

        assemblyConfigMapper.insert(importDOList);
    }


    /**
     * 构建树 + 排序 + 生成结构 hash
     *
     * @param list
     * @return
     */
    private List<AssemblyConfigStructureVO> buildTreeAndComputeHash(List<OrderComponentListRespDTO> list) {
        if (list == null || list.isEmpty()) return Collections.emptyList();

        Map<Long, AssemblyConfigStructureVO> map = new HashMap<>(list.size());
        List<AssemblyConfigStructureVO> roots = new ArrayList<>();

        // 1、初始化节点
        for (OrderComponentListRespDTO node : list) {
            AssemblyConfigStructureVO vo = new AssemblyConfigStructureVO();
            vo.setName(node.getName());
            vo.setChildren(new ArrayList<>());
            map.put(node.getId(), vo);
        }

        // 2、组装树 + 设置 sourceComponentId
        for (OrderComponentListRespDTO node : list) {
            AssemblyConfigStructureVO vo = map.get(node.getId());
            if (node.getPid() == 0) {
                vo.setSourceComponentId(node.getId());
                roots.add(vo);
            } else {
                AssemblyConfigStructureVO parent = map.get(node.getPid());
                if (parent != null) parent.getChildren().add(vo);
            }
        }

        // 3、递归排序 + 生成 hash
        for (AssemblyConfigStructureVO root : roots) {
            buildAndSetRootHash(root);
        }

        return roots;
    }

    /**
     * 递归排序 children + 生成结构 hash
     *
     * @param root
     */
    private void buildAndSetRootHash(AssemblyConfigStructureVO root) {

        sortRecursively(root);

        String structureStr = buildStructureString(root);

        root.setStructureHash(
                DigestUtil.sha256Hex(structureStr)
        );

        root.setProcess(true);
    }

    /**
     * 递归排序
     *
     * @param node
     */
    private void sortRecursively(AssemblyConfigStructureVO node) {

        List<AssemblyConfigStructureVO> children = node.getChildren();

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

        children.sort(
                Comparator.comparing(
                        AssemblyConfigStructureVO::getName
                )
        );

        for (AssemblyConfigStructureVO child : children) {
            sortRecursively(child);
        }
    }

    /**
     * 构建结构字符串（name + children）
     *
     * @param node
     * @return
     */
    private String buildStructureString(
            AssemblyConfigStructureVO node) {

        StringBuilder sb = new StringBuilder();

        sb.append(node.getName());

        List<AssemblyConfigStructureVO> children = node.getChildren();

        if (children != null && !children.isEmpty()) {

            sb.append("(");

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

                if (i > 0) {
                    sb.append(",");
                }

                sb.append(
                        buildStructureString(children.get(i))
                );
            }

            sb.append(")");
        }

        return sb.toString();
    }

    @Override
    public List<AssemblyConfigListRespVO> getOrgAssemblyConfigList(String name) {
        Long organId = SecurityFrameworkUtils.getUserOrganId();

        List<AssemblyConfigDO> list = assemblyConfigMapper.selectList(
                new LambdaQueryWrapperX<AssemblyConfigDO>()
                        .eq(AssemblyConfigDO::getOrganId, organId)
                        .likeIfPresent(AssemblyConfigDO::getComponentName, name)
                        .eq(AssemblyConfigDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus())
                        .select(AssemblyConfigDO::getId, AssemblyConfigDO::getComponentName, AssemblyConfigDO::getStatus, AssemblyConfigDO::getSourceComponentId)
        );

        if (list.isEmpty()) {
            return Collections.emptyList();
        }

        return BeanUtil.copyToList(list, AssemblyConfigListRespVO.class);
    }

    @Override
    public AssemblyConfigRespVO getAssemblyConfig(Long configId) {
        Long organId = SecurityFrameworkUtils.getUserOrganId();

        // 1、校验本身
        AssemblyConfigDO assemblyConfigDO = getById(configId, organId);

        // 2、只有已配置才能查看
        AssertUtils.notEquals(assemblyConfigDO.getStatus(), AssemblyConfigStatusEnum.CONFIGURED.getStatus(), ASSEMBLY_CONFIG_NOT_EXIST);

        // 3、解压结构
        AssemblyConfigStructureVO structure = JSON.parseObject(JsonUtils.unzipString(assemblyConfigDO.getStructureJson()), AssemblyConfigStructureVO.class);

        return AssemblyConfigRespVO.builder()
                .id(assemblyConfigDO.getId())
                .componentName(assemblyConfigDO.getComponentName())
                .structure(structure)
                .build();
    }

    /**
     * 查询部件设置
     *
     * @param configId
     * @param organId
     * @return
     */
    private AssemblyConfigDO getById(Long configId, Long organId) {
        AssemblyConfigDO assemblyConfigDO = assemblyConfigMapper.selectOne(
                new LambdaQueryWrapper<AssemblyConfigDO>()
                        .eq(AssemblyConfigDO::getId, configId)
                        .eq(AssemblyConfigDO::getOrganId, organId)
        );
        AssertUtils.notEmpty(assemblyConfigDO, ASSEMBLY_CONFIG_NOT_EXIST);
        return assemblyConfigDO;
    }

    @Override
    public void doConfig(Long configId) {
        Long organId = SecurityFrameworkUtils.getUserOrganId();

        // 1、校验本身
        AssemblyConfigDO assemblyConfigDO = getById(configId, organId);
        String componentName = assemblyConfigDO.getComponentName();
        if (ObjectUtil.equals(assemblyConfigDO.getStatus(), AssemblyConfigStatusEnum.CONFIGURED.getStatus())) {
            return;
        }

        // 2、校验本身以外是否还有重名的顶级部件设置
        boolean exists = assemblyConfigMapper.exists(new LambdaQueryWrapper<AssemblyConfigDO>()
                .eq(AssemblyConfigDO::getOrganId, organId)
                .eq(AssemblyConfigDO::getComponentName, componentName)
                .ne(AssemblyConfigDO::getId, configId)
                .eq(AssemblyConfigDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus())
                .eq(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.CONFIGURED.getStatus())
        );
        AssertUtils.isTrue(exists, ASSEMBLY_CONFIG_DO_CONFIG_EXIST, componentName);

        // 3、生成序号 seq（直接使用 componentName 作为 baseName）
        nextSeq(organId, componentName);

        // 4、更新状态
        assemblyConfigMapper.update(new LambdaUpdateWrapper<AssemblyConfigDO>()
                .eq(AssemblyConfigDO::getId, configId)
                .eq(AssemblyConfigDO::getOrganId, organId)
                .eq(AssemblyConfigDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus())
                .set(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.CONFIGURED.getStatus())
        );
    }

    @Override
    public void newConfig(Long configId) {
        Long organId = SecurityFrameworkUtils.getUserOrganId();

        // 1、校验本身
        AssemblyConfigDO assemblyConfigDO = getById(configId, organId);
        String existName = assemblyConfigDO.getComponentName();

        // 2、校验新的名字是否已有存在的部件
        boolean exists = assemblyConfigMapper.exists(new LambdaQueryWrapper<AssemblyConfigDO>()
                .eq(AssemblyConfigDO::getOrganId, organId)
                .eq(AssemblyConfigDO::getComponentName, existName)
                .ne(AssemblyConfigDO::getId, configId)
                .eq(AssemblyConfigDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus())
                .eq(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.CONFIGURED.getStatus())
        );

        if (exists) {
            // 重名 → 自动生成新名字
            // seq 表里直接用 newName 作为 baseName
            int seq = nextSeq(organId, existName);
            String newName = existName + " " + seq;

            // 再次校验生成的新名字是否意外重复
            boolean newExists = assemblyConfigMapper.exists(new LambdaQueryWrapper<AssemblyConfigDO>()
                    .eq(AssemblyConfigDO::getOrganId, organId)
                    .eq(AssemblyConfigDO::getComponentName, newName)
                    .eq(AssemblyConfigDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus())
                    .eq(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.CONFIGURED.getStatus())
            );
            AssertUtils.isTrue(newExists, ASSEMBLY_CONFIG_NEW_CONFIG_NAME_EXIST, newName);

            // 新名更新到hash和json中
            String structureJson = assemblyConfigDO.getStructureJson();
            AssemblyConfigStructureVO structureVO = JsonUtils.parseObject(JsonUtils.unzipString(structureJson), AssemblyConfigStructureVO.class);
            structureVO.setName(newName);
            String newJson = JsonUtils.zipString(JsonUtils.toJsonString(structureVO));

            // 重算hash
            buildAndSetRootHash(structureVO);
            String newHash = structureVO.getStructureHash();

            // 更新状态和名称
            assemblyConfigMapper.update(new LambdaUpdateWrapperX<AssemblyConfigDO>()
                    .eq(AssemblyConfigDO::getId, configId)
                    .eq(AssemblyConfigDO::getOrganId, organId)
                    .eq(AssemblyConfigDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus())
                    .set(AssemblyConfigDO::getComponentName, newName)
                    .set(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.CONFIGURED.getStatus())
                    .set(AssemblyConfigDO::getStructureHash, newHash)
                    .set(AssemblyConfigDO::getStructureJson, newJson)
            );
        } else {
            throw new ServiceException(ASSEMBLY_CONFIG_NO_NEED_NEW_CONFIG, existName);
        }
    }

    /**
     * 获取下一个编号
     *
     * @param organId
     * @param baseName
     * @return
     */
    public int nextSeq(Long organId, String baseName) {
        AssemblyConfigNameSeqDO assemblyConfigNameSeqDO = new AssemblyConfigNameSeqDO(organId, baseName, null);
        assemblyConfigNameSeqMapper.nextSeq(assemblyConfigNameSeqDO);// 插入或更新 seq 表
        return assemblyConfigNameSeqDO.getNextNo() - 1;        // 真正返回 seq
    }

    @Override
    public void delete(Long configId) {
        Long organId = SecurityFrameworkUtils.getUserOrganId();

        // 1、校验本身
        AssemblyConfigDO assemblyConfigDO = getById(configId, organId);

        // 2、根据状态走不同的删除
        if (ObjectUtil.equals(assemblyConfigDO.getStatus(), AssemblyConfigStatusEnum.CONFIGURED.getStatus())) {
            // 已配置的改成导入
            assemblyConfigMapper.update(new LambdaUpdateWrapper<AssemblyConfigDO>()
                    .eq(AssemblyConfigDO::getId, configId)
                    .eq(AssemblyConfigDO::getOrganId, organId)
                    .eq(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.CONFIGURED.getStatus())
                    .eq(AssemblyConfigDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus())
                    .set(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.IMPORT.getStatus())
                    .set(AssemblyConfigDO::getComponentName, assemblyConfigDO.getBaseName())
            );
        } else {
            // 导入状态的删除
            assemblyConfigMapper.update(new LambdaUpdateWrapper<AssemblyConfigDO>()
                    .eq(AssemblyConfigDO::getId, configId)
                    .eq(AssemblyConfigDO::getOrganId, organId)
                    .eq(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.IMPORT.getStatus())
                    .eq(AssemblyConfigDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus())
                    .set(AssemblyConfigDO::getDeleted, DeletedCodeEnum.DELETED.getStatus())
            );
        }
    }

    @Override
    public void saveConfig(AssemblyConfigSaveReqVO reqVO) {
        Long organId = SecurityFrameworkUtils.getUserOrganId();
        // 1、校验本身
        AssemblyConfigDO assemblyConfigDO = getById(reqVO.getId(), organId);


        AssemblyConfigStructureVO structureVO = reqVO.getConfig();
        String newTopName = structureVO.getName();
        // 2、如果顶级的名称发生改变，需要校验是否重复，并且同步给name
        String needChangeName = null;
        if (!assemblyConfigDO.getComponentName().equals(newTopName)) {
            boolean exists = assemblyConfigMapper.exists(new LambdaQueryWrapper<AssemblyConfigDO>()
                    .eq(AssemblyConfigDO::getOrganId, organId)
                    .eq(AssemblyConfigDO::getComponentName, newTopName)
                    .ne(AssemblyConfigDO::getId, assemblyConfigDO.getId())
                    .eq(AssemblyConfigDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus())
                    .eq(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.CONFIGURED.getStatus())
            );
            AssertUtils.isTrue(exists, ASSEMBLY_CONFIG_SAVE_TOPNAME_EXIST, newTopName);
            needChangeName = newTopName;
        }

        // 3、更新hash和json
        // 生成hash并检查是不是全部不加工
        boolean allNotProcess = computeHashAndCheckProcess(structureVO);
        String structureHash = structureVO.getStructureHash();

        assemblyConfigMapper.update(new LambdaUpdateWrapperX<AssemblyConfigDO>()
                .eq(AssemblyConfigDO::getId, assemblyConfigDO.getId())
                .eq(AssemblyConfigDO::getOrganId, organId)
                .eq(AssemblyConfigDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus())
                .eq(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.CONFIGURED.getStatus())
                .setIfPresent(AssemblyConfigDO::getComponentName, needChangeName)
                .set(AssemblyConfigDO::getStructureHash, structureHash)
                .set(AssemblyConfigDO::getStructureJson, JsonUtils.zipString(JsonUtils.toJsonString(structureVO)))
                .set(AssemblyConfigDO::getNotProcess, allNotProcess)
        );
    }

    /**
     * 生成结构hash、逐级检查是否全部不加工
     *
     * @param node
     * @return true 表示全部不加工
     */
    private boolean computeHashAndCheckProcess(AssemblyConfigStructureVO node) {

        // 当前节点是否不加工
        boolean hasProcessFalse = !node.isProcess();

        List<AssemblyConfigStructureVO> children = node.getChildren();
        if (children != null && !children.isEmpty()) {

            // 1. 按 name 排序保证 hash 稳定
            children.sort(Comparator.comparing(AssemblyConfigStructureVO::getName));

            // 2. 递归子节点
            for (AssemblyConfigStructureVO child : children) {
                if (computeHashAndCheckProcess(child)) {
                    hasProcessFalse = true;
                }
            }
        }

        // 3. 生成结构字符串并 hash
        String structureStr = buildStructureString(node);
        node.setStructureHash(DigestUtil.sha256Hex(structureStr));

        return hasProcessFalse;
    }

    @Override
    public List<AssemblyConfigRespVO> getAssemblyConfigByComponentNameList(List<String> componentNameList) {
        Long organId = SecurityFrameworkUtils.getUserOrganId();

        List<AssemblyConfigDO> assemblyConfigDOS = assemblyConfigMapper.selectList(new LambdaQueryWrapper<AssemblyConfigDO>()
                .eq(AssemblyConfigDO::getOrganId, organId)
                .in(AssemblyConfigDO::getComponentName, componentNameList)
                .eq(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.CONFIGURED.getStatus())
                .eq(AssemblyConfigDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus())
                .select(AssemblyConfigDO::getComponentName, AssemblyConfigDO::getStructureHash, AssemblyConfigDO::getStructureJson)
        );

        return BeanUtil.copyToList(assemblyConfigDOS, AssemblyConfigRespVO.class);
    }

    @Override
    public List<AssemblyConfigRespVO> getNotProcessAssemblyConfigByComponentNameList(List<String> componentNameList) {
        Long organId = SecurityFrameworkUtils.getUserOrganId();

        List<AssemblyConfigDO> assemblyConfigDOS = assemblyConfigMapper.selectList(new LambdaQueryWrapper<AssemblyConfigDO>()
                .eq(AssemblyConfigDO::getOrganId, organId)
                .in(AssemblyConfigDO::getComponentName, componentNameList)
                .eq(AssemblyConfigDO::getStatus, AssemblyConfigStatusEnum.CONFIGURED.getStatus())
                .eq(AssemblyConfigDO::getDeleted, DeletedCodeEnum.NOT_DELETED.getStatus())
                .eq(AssemblyConfigDO::getNotProcess, true)
                .select(AssemblyConfigDO::getComponentName, AssemblyConfigDO::getStructureHash, AssemblyConfigDO::getStructureJson, AssemblyConfigDO::getNotProcess)
        );

        return BeanUtil.copyToList(assemblyConfigDOS, AssemblyConfigRespVO.class);
    }
}