工控网解析 涉密网产品结构树(添加权限)、nc文件、刀具列表、程序加工确认表
已添加8个文件
已修改12个文件
1046 ■■■■■ 文件已修改
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/dto/ComponentHierarchy.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/dto/ProcessTraceChain.java 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/dto/TransferPackage.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/entity/ProductMix.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/listener/FileListener.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/mapper/xml/PermissionStreamNewMapper.xml 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ComponentInfoSeServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/DataImportService.java 456 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/FileFerryService.java 224 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/PartsInfoServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ProcessSpecVersionServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ProcessStreamServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ProductInfoServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/SecurityService.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/WorkStepServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/utils/CompressionUtils.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/utils/JsonUtils.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/utils/TreeBuilder.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/IMdcProductionService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/impl/MdcProductionServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/dto/ComponentHierarchy.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
package org.jeecg.modules.dnc.dto;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import org.jeecg.modules.dnc.entity.ComponentInfo;
import org.jeecg.modules.dnc.entity.ProductInfo;
import java.util.ArrayList;
import java.util.List;
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class ComponentHierarchy {
    private ProductInfo rootProduct;
    private final List<ComponentInfo> components = new ArrayList<>(); // ä»Žæ ¹éƒ¨ä»¶åˆ°åº•层部件的顺序
    public void addComponentToTop(ComponentInfo component) {
        components.add(0, component);
    }
    public List<ComponentInfo> getComponentsFromTop() {
        return new ArrayList<>(components);
    }
    public ComponentInfo getLeafComponent() {
        return components.isEmpty() ? null : components.get(components.size() - 1);
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/dto/ProcessTraceChain.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,86 @@
package org.jeecg.modules.dnc.dto;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
import lombok.Data;
import org.jeecg.modules.dnc.entity.*;
import java.util.List;
/**
 * @Description: æ¶‰å¯†ç½‘同步工控网需要的数据
 * @Author: lyh
 * @Date:   2025-06-13
 * @Version: V1.0
 * @remark: åŽç»­éœ€è¦å¢žåŠ ï¼Œæ·»åŠ å¯¹åº”å‚æ•°ä¸Žç»“æž„æ•°æ®ï¼Œé‡‡ç”¨JSON序列化与反序列化进行传输,方便传输(加密操作,避免数据污染)
 */
@Data
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
public class ProcessTraceChain {
    /**程序加工确认表*/
    private GuideCardBatch guideCardBatch;
    /**刀具列表*/
    private List<Cutter> cutterList;
    /**文件*/
    private DocFile docFile;
    /**设备文档对应关系*/
    private DocRelative docRelative;
    /**文档*/
    private DocInfo docInfo;
    /**设备类*/
    private DeviceType deviceType;
    /**设备类对应关系*/
    private DeviceManagement deviceManagement;
    /**工步*/
    private WorkStep workStep;
    /**工序*/
    private ProcessStream process;
    /**工艺规程版本*/
    private ProcessSpecVersion processSpec;
    /**零件*/
    private PartsInfo parts;
    /**部件*/
    private ComponentHierarchy componentHierarchy;
    /**产品*/
    private ProductInfo product;
    /**产品树路径*/
    private List<ProductMix> treePath;
    /**权限表*/
    private List<PermissionStreamNew> permissionStreamNewList;
    @JsonCreator
    public ProcessTraceChain(
            @JsonProperty("guideCardBatch") GuideCardBatch guideCardBatch,
            @JsonProperty("cutterList") List<Cutter> cutterList,
            @JsonProperty("docFile") DocFile docFile,
            @JsonProperty("docRelative") DocRelative docRelative,
            @JsonProperty("docInfo") DocInfo docInfo,
            @JsonProperty("deviceType") DeviceType deviceType,
            @JsonProperty("deviceManagement") DeviceManagement deviceManagement,
            @JsonProperty("workStep") WorkStep workStep,
            @JsonProperty("process") ProcessStream process,
            @JsonProperty("processSpec") ProcessSpecVersion processSpec,
            @JsonProperty("parts") PartsInfo parts,
            @JsonProperty("componentHierarchy") ComponentHierarchy componentHierarchy,
            @JsonProperty("product") ProductInfo product,
            @JsonProperty("treePath") List<ProductMix> treePath,
            @JsonProperty("permissionStreamNewList") List<PermissionStreamNew> permissionStreamNewList
    ) {
        this.guideCardBatch = guideCardBatch;
        this.cutterList = cutterList;
        this.docFile = docFile;
        this.docRelative = docRelative;
        this.docInfo = docInfo;
        this.deviceType = deviceType;
        this.deviceManagement = deviceManagement;
        this.workStep = workStep;
        this.process = process;
        this.processSpec = processSpec;
        this.parts = parts;
        this.componentHierarchy = componentHierarchy;
        this.product = product;
        this.treePath = treePath;
        this.permissionStreamNewList = permissionStreamNewList;
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/dto/TransferPackage.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
package org.jeecg.modules.dnc.dto;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
import lombok.Data;
import org.jeecg.modules.dnc.entity.*;
@Data
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class TransferPackage {
    public enum DataType { PROCESS, WORKSTEP }
    private final DataType dataType;
    private final DocRelative docRelative;
    private final ProcessTraceChain traceChain;
    @JsonCreator
    public TransferPackage(
            @JsonProperty("dataType") DataType dataType,
            @JsonProperty("docRelative")  DocRelative docRelative,
            @JsonProperty("traceChain") ProcessTraceChain traceChain
    ) {
        this.dataType = dataType;
        this.docRelative = docRelative;
        this.traceChain = traceChain;
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/entity/ProductMix.java
@@ -29,13 +29,13 @@
    private Long parentId;
    // åç§°
    @TableField(value = "tree_name")
    private String name;
    private String treeName;
    // code
    @TableField(value = "tree_code")
    private String code;
    private String treeCode;
    // ç±»åž‹
    @TableField(value = "tree_type")
    private Integer type;
    private Integer treeType;
    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    @TableField(value = "create_time")
    private Date createTime;
@@ -43,17 +43,19 @@
    //展示名称
    private transient String label;
    //类型 æ–¹ä¾¿å‰ç«¯å±•示
    private transient Integer type;
    private transient List<ProductMix> children = new ArrayList<>();
    public ProductMix(Long id, Long parentId, String name, String code, Integer type, Date createTime) {
    public ProductMix(Long id, Long parentId, String treeName, String trrCode, Integer type, Date createTime) {
        this.id = id;
        this.parentId = parentId;
        this.name = name;
        this.code = code;
        this.treeName = treeName;
        this.treeCode = trrCode;
        this.type = type;
        this.children = new ArrayList<>();
        this.label="["+code+"]"+name;
        this.label="["+ trrCode +"]"+ treeName;
        this.createTime = createTime;
    }
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/listener/FileListener.java
@@ -1,25 +1,26 @@
package org.jeecg.modules.dnc.listener;
import org.apache.commons.io.monitor.FileAlterationListener;
import org.apache.commons.io.monitor.FileAlterationObserver;
import org.jeecg.common.util.FileUtil;
import org.jeecg.modules.dnc.service.IDocInfoService;
import org.jeecg.modules.dnc.utils.file.FileUtilS;
import org.jeecg.modules.message.enums.DeployEnum;
import org.jeecg.modules.dnc.dto.TransferPackage;
import org.jeecg.modules.dnc.service.impl.DataImportService;
import org.jeecg.modules.dnc.service.impl.FileFerryService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.File;
import java.util.Objects;
@Component
public class FileListener implements FileAlterationListener {
    private static final Logger log = LoggerFactory.getLogger(FileListener.class);
    @Autowired
    private IDocInfoService docInfoService;  // æ–‡æ¡£æœåŠ¡
    private FileFerryService fileFerryService;
    @Autowired
    private DataImportService dataImportService;
    @Override
    public void onStart(FileAlterationObserver observer) {
@@ -45,6 +46,13 @@
    public void onFileCreate(File file) {
        String filePath = file.getAbsolutePath();
        log.info("[新建]: {}", filePath);
//        if (filePath.startsWith(fileMonitorConfig.getPaths().get(0))){
            if (filePath.endsWith(".ferry")){
                TransferPackage data = fileFerryService.importData(filePath);
                dataImportService.importTransferPackage(data);
                log.info("文件导入完成");
            }
//        }
    }
    @Override
    public void onFileChange(File file) {
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/mapper/xml/PermissionStreamNewMapper.xml
@@ -4,8 +4,8 @@
    <select id="loadProductMix" resultType="org.jeecg.modules.dnc.entity.ProductMix">
        SELECT DISTINCT
            mix.id,
            mix.tree_code 'code',
                mix.tree_name 'name',
            mix.tree_code,
                mix.tree_name,
            mix.parent_id,
            mix.tree_type AS 'type',
                mix.extend,
@@ -31,8 +31,8 @@
    </select>
    <select id="loadProductMixAll" resultType="org.jeecg.modules.dnc.entity.ProductMix">
        SELECT DISTINCT mix.id,
                        mix.tree_code    'code',
                        mix.tree_name    'name',
                        mix.tree_code ,
                        mix.tree_name ,
                        mix.parent_id,
                        mix.tree_type AS 'type',
                        mix.extend,
@@ -92,8 +92,8 @@
        )
        SELECT DISTINCT
            mix.id,
            mix.tree_code 'code',
            mix.tree_name 'name',
            mix.tree_code,
            mix.tree_name,
            mix.parent_id,
            mix.tree_type AS 'type',
            mix.extend,
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ComponentInfoSeServiceImpl.java
@@ -189,8 +189,8 @@
        boolean b = super.updateById(componentInfo);
        //同步修改结构树
        ProductMix productMix = productMixService.getById(Long.parseLong(id));
        productMix.setName(componentInfo.getComponentName());
        productMix.setCode(componentInfo.getComponentCode());
        productMix.setTreeName(componentInfo.getComponentName());
        productMix.setTreeCode(componentInfo.getComponentCode());
        productMixService.updateById(productMix);
        if(!b)
            return false;
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/DataImportService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,456 @@
package org.jeecg.modules.dnc.service.impl;
import cn.hutool.core.util.StrUtil;
import com.jeecg.weibo.exception.BusinessException;
import liquibase.pro.packaged.S;
import org.jeecg.modules.dnc.dto.ComponentHierarchy;
import org.jeecg.modules.dnc.dto.TransferPackage;
import org.jeecg.modules.dnc.entity.*;
import org.jeecg.modules.dnc.mapper.*;
import org.jeecg.modules.dnc.service.*;
import org.jeecg.modules.system.service.IMdcProductionService;
import org.jeecg.modules.system.service.ISysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class DataImportService {
    private static final Logger logger = LoggerFactory.getLogger(DataImportService.class);
    @Autowired
    private ProductInfoMapper productMapper;
    @Autowired
    private ComponentInfoMapper componentMapper;
    @Autowired
    private PartsInfoMapper partsMapper;
    @Autowired
    private ProcessSpecVersionMapper psvMapper;
    @Autowired
    private ProcessStreamMapper processMapper;
    @Autowired
    private WorkStepMapper workStepMapper;
    @Autowired
    private ProductMixMapper productMixMapper;
    @Autowired
    private PermissionStreamNewMapper permissionStreamNewMapper;
    @Autowired
    private DeviceManagementMapper deviceManagementMapper;
    @Autowired
    private DeviceTypeMapper deviceTypeMapper;
    @Autowired
    private DocInfoMapper docInfoMapper;
    @Autowired
    private DocFileMapper docFileMapper;
    @Autowired
    private DocRelativeMapper docRelativeMapper;
    @Autowired
    private CutterMapper cutterMapper;
    @Autowired
    private GuideCardBatchMapper guideCardBatchMapper;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private IMdcProductionService mdcProductionService;
    @Autowired
    private IProductPermissionService productPermissionService;
    @Autowired
    private IProductDepartmentService productDepartmentService;
    @Autowired
    private IComponentPermissionService componentPermissionService;
    @Autowired
    private IComponentDepartmentService componentDepartmentService;
    @Autowired
    private IPartsPermissionService partsPermissionService;
    @Autowired
    private IPartsDepartmentService partsDepartmentService;
    @Autowired
    private IProcessSpecVersionPermissionService processSpecVersionPermissionService;
    @Autowired
    private IProcessSpecVersionDepartmentService processSpecVersionDepartmentService;
    @Autowired
    private IProcessStreamPermissionService processStreamPermissionService;
    @Autowired
    private IProcessionDepartmentService processionDepartmentService;
    @Autowired
    private IWorkStepPermissionService workStepPermissionService;
    @Autowired
    private IWorkStepDepartmentService workStepDepartmentService;
    @Transactional(rollbackFor = Exception.class)
    public void importTransferPackage(TransferPackage transferPackage) {
        try {
            logger.info("开始导入传输包数据, ç±»åž‹: {}", transferPackage.getDataType());
            // ä¿å­˜äº§å“
            if (transferPackage.getTraceChain() != null &&
                    transferPackage.getTraceChain().getProduct() != null) {
                saveProduct(transferPackage.getTraceChain().getProduct());
            }
            // ä¿å­˜éƒ¨ä»¶å±‚级
            if (transferPackage.getTraceChain() != null &&
                    transferPackage.getTraceChain().getComponentHierarchy() != null) {
                saveComponentHierarchy(transferPackage.getTraceChain().getComponentHierarchy());
            }
            // ä¿å­˜é›¶ä»¶
            if (transferPackage.getTraceChain() != null &&
                    transferPackage.getTraceChain().getParts() != null) {
                saveParts(transferPackage.getTraceChain().getParts());
            }
            // ä¿å­˜å·¥è‰ºè§„程
            if (transferPackage.getTraceChain() != null &&
                    transferPackage.getTraceChain().getProcessSpec() != null) {
                saveProcessSpec(transferPackage.getTraceChain().getProcessSpec());
            }
            // ä¿å­˜å·¥åº
            if (transferPackage.getTraceChain() != null&&
                    transferPackage.getTraceChain().getProcess() != null) {
                saveProcess(transferPackage.getTraceChain().getProcess());
            }
            // ä¿å­˜å·¥æ­¥
            if (transferPackage.getTraceChain() != null&&
                    transferPackage.getTraceChain().getWorkStep() != null) {
                saveWorkSteps(transferPackage.getTraceChain().getWorkStep());
            }
            // ä¿å­˜ç»“构树
            if (transferPackage.getTraceChain() != null&&
                    transferPackage.getTraceChain().getTreePath() != null) {
                saveTreePath(transferPackage.getTraceChain().getTreePath());
            }
            //保存权限
            if (transferPackage.getTraceChain() != null&&
                    transferPackage.getTraceChain().getPermissionStreamNewList() != null) {
                savePermissionStreamNewList(transferPackage.getTraceChain().getPermissionStreamNewList());
            }
            // ä¿å­˜è®¾å¤‡ç±»
            if (transferPackage.getTraceChain() != null&&
                    transferPackage.getTraceChain().getDeviceManagement() != null) {
                saveDeviceManagement(transferPackage.getTraceChain().getDeviceManagement());
            }
            // ä¿å­˜è®¾å¤‡ç±»å¯¹åº”信息
            if (transferPackage.getTraceChain() != null&&
                    transferPackage.getTraceChain().getDeviceType() != null) {
                saveDeviceType(transferPackage.getTraceChain().getDeviceType());
            }
            // ä¿å­˜æ–‡æ¡£
            if (transferPackage.getTraceChain() != null&&
                    transferPackage.getTraceChain().getDocInfo() != null) {
                saveDocInfo(transferPackage.getTraceChain().getDocInfo());
            }
            // ä¿å­˜æ–‡ä»¶
            if (transferPackage.getTraceChain() !=null&&
                    transferPackage.getTraceChain().getDocFile() != null) {
                saveDocFile(transferPackage.getTraceChain().getDocFile());
            }
            // ä¿å­˜æ–‡æ¡£æ–‡ä»¶å¯¹åº”关系
            if (transferPackage.getDocRelative() !=null){
                saveDocRelative(transferPackage.getDocRelative());
            }
            // ä¿å­˜åˆ€å…·ç³»ç»Ÿ
            if (transferPackage.getTraceChain() !=null&&
                    transferPackage.getTraceChain().getCutterList() != null) {
                saveCutterList(transferPackage.getTraceChain().getCutterList());
            }
            //保存数控程序加工确认表
            if (transferPackage.getTraceChain() !=null&&
                    transferPackage.getTraceChain().getGuideCardBatch() != null) {
                saveGuideCardBatch(transferPackage.getTraceChain().getGuideCardBatch());
            }
            logger.info("数据导入成功");
        } catch (DuplicateKeyException e) {
            logger.warn("主键冲突: {}", e.getMessage());
            throw new BusinessException("数据已存在,无法重复导入");
        } catch (DataIntegrityViolationException e) {
            logger.error("数据完整性违反: {}", e.getMessage());
            throw new BusinessException("数据不完整,请检查必填字段");
        } catch (Exception e) {
            logger.error("数据导入失败: {}", e.getMessage(), e);
            throw new BusinessException("数据导入失败: " + e.getMessage());
        }
    }
    private void saveProduct(ProductInfo product) {
        if (productMapper.selectById(product.getProductId()) == null) {
            productMapper.insert(product);
            logger.debug("产品已保存: {}", product.getProductId());
        } else {
            logger.debug("产品已存在: {}", product.getProductId());
        }
    }
    private void saveComponentHierarchy(ComponentHierarchy hierarchy) {
        for (ComponentInfo component : hierarchy.getComponents()) {
            if (componentMapper.selectById(component.getComponentId()) == null) {
                componentMapper.insert(component);
                logger.debug("部件已保存: {}", component.getComponentId());
            } else {
                logger.debug("部件已存在: {}", component.getComponentId());
            }
        }
    }
    private void saveParts(PartsInfo parts) {
        if (partsMapper.selectById(parts.getPartsId()) == null) {
            partsMapper.insert(parts);
            logger.debug("零件已保存: {}", parts.getPartsId());
        } else {
            logger.debug("零件已存在: {}", parts.getPartsId());
        }
    }
    private void saveProcessSpec(ProcessSpecVersion processSpec) {
        if (psvMapper.selectById(processSpec.getId()) == null) {
            psvMapper.insert(processSpec);
            logger.debug("工艺规程已保存: {}", processSpec.getId());
        } else {
            logger.debug("工艺规程已存在: {}", processSpec.getId());
        }
    }
    private void saveProcess(ProcessStream process) {
        if (processMapper.selectById(process.getProcessId()) == null) {
            processMapper.insert(process);
            logger.debug("工序已保存: {}", process.getProcessId());
        } else {
            logger.debug("工序已存在: {}", process.getProcessId());
        }
    }
    private void saveWorkSteps(WorkStep workStep) {
        if (workStepMapper.selectById(workStep.getId()) == null) {
            workStepMapper.insert(workStep);
            logger.debug("工步已保存: {}", workStep.getId());
        } else {
            logger.debug("工步已存在: {}", workStep.getId());
        }
    }
    private void saveTreePath(List<ProductMix> productMixList){
        for (ProductMix productMix : productMixList) {
            if (productMixMapper.selectById(productMix.getId()) == null) {
                productMixMapper.insert(productMix);
                logger.debug("产品组合已保存: {}", productMix.getId());
            } else {
                logger.debug("产品组合已存在: {}", productMix.getId());
            }
        }
    }
    private void savePermissionStreamNewList(List<PermissionStreamNew> permissionStreamNewList) {
        for (PermissionStreamNew permissionStreamNew : permissionStreamNewList) {
            if (permissionStreamNew.getUserId() != null) {
                String id=sysUserService.getUserByName(permissionStreamNew.getUserId()).getId();
                if (id!=null){
                    permissionStreamNew.setUserId(id);
                }
            }
            if (permissionStreamNew.getDepartId() != null) {
                String id=mdcProductionService.findByOrgCode(permissionStreamNew.getDepartId()).getId();
                if (id!=null){
                    permissionStreamNew.setDepartId(id);
                }
            }
            permissionStreamNewMapper.insert(permissionStreamNew);
            logger.debug("权限已保存: {}", permissionStreamNew.getId());
        }
        //分批添加产品、部件、零件、工艺规程、工序、工步权限
        permissionStreamNewList.forEach(item -> {
            switch (item.getBusinessType()){
                case "1":
                    if (StrUtil.isNotEmpty(item.getUserId())){
                        ProductPermission productPermission = new ProductPermission();
                        productPermission.setProductId(item.getBusinessId());
                        productPermission.setUserId(item.getUserId());
                        productPermissionService.save(productPermission);
                    }else {
                        ProductDepartment productDepartment = new ProductDepartment();
                        productDepartment.setProductId(item.getBusinessId());
                        productDepartment.setDepartId(item.getDepartId());
                        productDepartmentService.save(productDepartment);
                    }
                    break;
                case "2":
                    if (StrUtil.isNotEmpty(item.getUserId())){
                        ComponentPermission componentPermission = new ComponentPermission();
                        componentPermission.setComponentId(item.getBusinessId());
                        componentPermission.setUserId(item.getUserId());
                        componentPermissionService.save(componentPermission);
                    }else {
                        ComponentDepartment componentDepartment = new ComponentDepartment();
                        componentDepartment.setComponentId(item.getBusinessId());
                        componentDepartment.setDepartId(item.getDepartId());
                        componentDepartmentService.save(componentDepartment);
                    }
                    break;
                case "3":
                    if (StrUtil.isNotEmpty(item.getUserId())){
                        PartsPermission partsPermission = new PartsPermission();
                        partsPermission.setPartsId(item.getBusinessId());
                        partsPermission.setUserId(item.getUserId());
                        partsPermissionService.save(partsPermission);
                    }else {
                        PartsDepartment partsDepartment = new PartsDepartment();
                        partsDepartment.setPartsId(item.getBusinessId());
                        partsDepartment.setDepartId(item.getDepartId());
                        partsDepartmentService.save(partsDepartment);
                    }
                    break;
                case "4":
                    if (StrUtil.isNotEmpty(item.getUserId())){
                        ProcessSpecVersionPermission processSpecVersionPermission = new ProcessSpecVersionPermission();
                        processSpecVersionPermission.setPsvId(item.getBusinessId());
                        processSpecVersionPermission.setUserId(item.getUserId());
                        processSpecVersionPermissionService.save(processSpecVersionPermission);
                    }else {
                        ProcessSpecVersionDepartment processSpecVersionDepartment = new ProcessSpecVersionDepartment();
                        processSpecVersionDepartment.setPsvId(item.getBusinessId());
                        processSpecVersionDepartment.setDepartId(item.getDepartId());
                        processSpecVersionDepartmentService.save(processSpecVersionDepartment);
                    }
                    break;
                case "5":
                    if (StrUtil.isNotEmpty(item.getUserId())){
                        ProcessionPermission processionPermission = new ProcessionPermission();
                        processionPermission.setProcessId(item.getBusinessId());
                        processionPermission.setUserId(item.getUserId());
                        processStreamPermissionService.save(processionPermission);
                    }else {
                        ProcessionDepartment processionDepartment = new ProcessionDepartment();
                        processionDepartment.setProcessId(item.getBusinessId());
                        processionDepartment.setDepartId(item.getDepartId());
                        processionDepartmentService.save(processionDepartment);
                    }
                    break;
                case  "6":
                    if (StrUtil.isNotEmpty(item.getUserId())){
                        WorkStepPermission workStepPermission = new WorkStepPermission();
                        workStepPermission.setStepId(item.getBusinessId());
                        workStepPermission.setUserId(item.getUserId());
                        workStepPermissionService.save(workStepPermission);
                    }else {
                        WorkStepDepartment workStepDepartment = new WorkStepDepartment();
                        workStepDepartment.setStepId(item.getBusinessId());
                        workStepDepartment.setDepartId(item.getDepartId());
                        workStepDepartmentService.save(workStepDepartment);
                    }
                    break;
                default:
            }
        });
    }
    private void saveDeviceManagement(DeviceManagement deviceManagement) {
        if (deviceManagementMapper.selectById(deviceManagement.getId()) == null) {
            deviceManagementMapper.insert(deviceManagement);
            logger.debug("设备类信息已保存: {}", deviceManagement.getId());
        } else {
            logger.debug("设备类信息已存在: {}", deviceManagement.getId());
        }
    }
    private void saveDeviceType(DeviceType deviceType) {
        if (deviceTypeMapper.selectById(deviceType.getId()) == null) {
            deviceTypeMapper.insert(deviceType);
            logger.debug("设备类已保存: {}", deviceType.getId());
        } else {
            logger.debug("设备类已存在: {}", deviceType.getId());
        }
    }
    private void saveDocInfo(DocInfo docInfo) {
        if (docInfoMapper.selectById(docInfo.getDocId()) == null) {
            docInfoMapper.insert(docInfo);
            logger.debug("文档已保存: {}", docInfo.getDocId());
        } else {
            logger.debug("文档已存在: {}", docInfo.getDocId());
        }
    }
    private void saveDocFile(DocFile docFile) {
        if (docFileMapper.selectById(docFile.getFileId()) == null) {
            docFileMapper.insert(docFile);
            logger.debug("文档文件已保存: {}", docFile.getFileId());
        } else {
            logger.debug("文档文件已存在: {}", docFile.getFileId());
        }
    }
    private void saveDocRelative(DocRelative docRelative) {
        if (docRelativeMapper.selectById(docRelative.getId()) == null) {
            docRelativeMapper.insert(docRelative);
            logger.debug("文档对应关系已保存: {}", docRelative.getId());
        } else {
            logger.debug("文档对应关系已存在: {}", docRelative.getId());
        }
    }
    private void saveCutterList(List<Cutter> cutterList) {
        for (Cutter cutter : cutterList) {
            if (cutterMapper.selectById(cutter.getId()) == null) {
                cutterMapper.insert(cutter);
                logger.debug("刀具已保存: {}", cutter.getId());
            } else {
                cutterMapper.updateById(cutter);
            }
        }
    }
    private void saveGuideCardBatch(GuideCardBatch guideCardBatch) {
        if (guideCardBatchMapper.selectById(guideCardBatch.getId()) == null) {
            guideCardBatchMapper.insert(guideCardBatch);
            logger.debug("刀片批次已保存: {}", guideCardBatch.getId());
        } else {
            logger.debug("刀片批次已存在: {}", guideCardBatch.getId());
        }
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/FileFerryService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,224 @@
package org.jeecg.modules.dnc.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import liquibase.pro.packaged.S;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.modules.dnc.dto.ComponentHierarchy;
import org.jeecg.modules.dnc.dto.TransferPackage;
import org.jeecg.modules.dnc.entity.*;
import org.jeecg.modules.dnc.exception.ExceptionCast;
import org.jeecg.modules.dnc.mapper.DocRelativeMapper;
import org.jeecg.modules.dnc.response.ActivitiCode;
import org.jeecg.modules.dnc.response.DocumentCode;
import org.jeecg.modules.dnc.service.IDocClassificationService;
import org.jeecg.modules.dnc.service.IDocFileService;
import org.jeecg.modules.dnc.service.IDocInfoService;
import org.jeecg.modules.dnc.service.IDocRelativeService;
import org.jeecg.modules.dnc.utils.CompressionUtils;
import org.jeecg.modules.dnc.utils.JsonUtils;
import org.jeecg.modules.dnc.utils.file.FileUtilS;
import org.jeecg.modules.dncFlow.service.IAssignFileStreamService;
import org.jeecg.modules.mdc.entity.MdcEquipment;
import org.jeecg.modules.mdc.mapper.MdcEquipmentMapper;
import org.jeecg.modules.system.service.IMdcProductionService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
@Service
public class FileFerryService {
    private static final Logger logger = LoggerFactory.getLogger(FileFerryService.class);
    @Value("${deploy.secretFolder}")
    private String ferryPath;
    @Value("${fileHomePath}")
    private String fileHomePath;
    @Autowired
    private MdcEquipmentMapper mdcEquipmentMapper;
    @Autowired
    private IMdcProductionService mdcProductionService;
    @Autowired
    private IDocInfoService docInfoService;
    @Autowired
    private IDocClassificationService classificationService;
    @Autowired
    private IDocRelativeService docRelativeService;
    public TransferPackage importData(String filePath) {
        try {
            // 1. è¯»å–文件
            Path path = Paths.get(filePath);
            String fileName = path.getFileName().toString();
            byte[] encrypted = Files.readAllBytes(path);
            logger.debug("读取文件完成, å¤§å°: {} å­—节", encrypted.length);
            // 2. è§£å¯† (当前已注释)
            // byte[] compressed = securityService.decrypt(encrypted);
            // 3. è§£åŽ‹ç¼©
//            byte[] jsonBytes = CompressionUtils.gzipDecompress(encrypted);
            String json = new String(encrypted, StandardCharsets.UTF_8);
            logger.debug("解压缩完成, JSON长度: {} å­—符", json.length());
            // è®°å½•JSON内容用于调试
            logger.trace("原始JSON内容:\n{}", json);
            // 4. JSON反序列化
            logger.debug("开始反序列化...");
            TransferPackage pkg = JsonUtils.fromJson(json, TransferPackage.class);
            // 5. å¤„理文件名 - ç¤ºä¾‹: 10A20250614000026_3102038
            String[] split = fileName.split("_");
            if (split.length < 2) {
                throw new IllegalArgumentException("无效的文件名格式: " + fileName);
            }
            String id = split[0];
            String equipmentId = split[1].split("\\.")[0];
            // æå–前缀和数字部分
            int aIndex = id.indexOf("A");
            if (aIndex == -1 || aIndex == id.length() - 1) {
                throw new IllegalArgumentException("无效的ID格式: " + id);
            }
            String prefix = id.substring(0, aIndex + 1);
            String numericPart = id.substring(aIndex + 1);
            // è®¡ç®—前一个文件名
            long number = Long.parseLong(numericPart);
            number--;  // èŽ·å–å‰ä¸€ä¸ªåºåˆ—å·
            // ä¿æŒç›¸åŒä½æ•°æ ¼å¼
            String newNumeric = String.format("%0" + numericPart.length() + "d", number);
            String ncFileName = prefix + newNumeric + "_" + equipmentId+".NC";
            String ncFilePath = path.getParent().resolve(ncFileName).toString();
            // 6. èŽ·å–æ–‡ä»¶å¤åˆ¶ç›®æ ‡è·¯å¾„
            DocFile docFile = pkg.getTraceChain().getDocFile();
            DocInfo docInfo = pkg.getTraceChain().getDocInfo();
            if (docFile == null) {
                throw new IllegalStateException("传输包中缺少文档文件信息");
            }
            // æž„建目标路径
            String targetDirectory = fileHomePath + docFile.getFilePath();
            String targetPath = Paths.get(targetDirectory, docFile.getFileEncodeName()).toString();
            // ç¡®ä¿ç›®æ ‡ç›®å½•存在
            File targetDir = new File(targetDirectory);
            if (!targetDir.exists() && !targetDir.mkdirs()) {
                throw new IOException("无法创建目标目录: " + targetDirectory);
            }
            // 7. å¤åˆ¶æ–‡ä»¶å¹¶é‡å‘½å
            logger.info("复制文件: {} â†’ {}", ncFilePath, targetPath);
            Path source = Paths.get(ncFilePath);
            Files.copy(source, Paths.get(targetPath), StandardCopyOption.REPLACE_EXISTING);
            // 8. æŸ¥è¯¢è®¾å¤‡id
            MdcEquipment mdcEquipment=mdcEquipmentMapper.selectOne(new QueryWrapper<MdcEquipment>().eq("equipment_id",equipmentId));
            if (mdcEquipment == null) {
                throw new IllegalArgumentException("无效的设备ID: " + equipmentId);
            }
            // 9.传输文件到设备下
            List<String> strings = mdcProductionService.findListParentTreeAll(mdcEquipment.getId());
            if (strings != null && !strings.isEmpty()) {
                DocInfo deviceDoc = docInfoService.getByDocAttrAndDocId(docInfo.getDocId(), 7, mdcEquipment.getId());
                if (deviceDoc == null) {
                    DocClassification classification = classificationService.getByCode("send");
                    if(classification == null)
                        ExceptionCast.cast(DocumentCode.DOC_CLASS_ERROR);
                    DocRelative docRelative = new DocRelative();
                    docRelative.setDocId(docInfo.getDocId());
                    docRelative.setClassificationId(classification.getClassificationId());
                    docRelative.setAttributionType(7);
                    docRelative.setAttributionId(mdcEquipment.getId());
                    docRelativeService.save(docRelative);
                }
                String sendPath = StringUtils.join(strings.toArray(), "/");
                boolean copyFileNc = FileUtilS.copyFileNc(docFile.getFilePath(), sendPath + "/" + mdcEquipment.getEquipmentId(),
                        docFile.getFileEncodeName(),
                        docFile.getFileName(), docFile.getFileSuffix());
                if (!copyFileNc) {
                    ExceptionCast.cast(ActivitiCode.ACT_FILE_ERROR);
                } else {
                    FileUtilS.deleteZipFromToSend(sendPath + "/" + mdcEquipment.getEquipmentId(),
                            docFile.getFileName(), docFile.getFileSuffix());
                }
            } else {
                throw new RuntimeException("文件传输路径获取失败");
            }
            // 10.删除临时NC文件与json文件
            logger.info("删除临时文件: {}", ncFilePath);
            Files.delete(source);
            Files.delete(path);
            return JsonUtils.fromJson(json, TransferPackage.class);
        } catch (NumberFormatException e) {
            throw new RuntimeException("文件名中的数字格式无效: " + e.getMessage(), e);
        } catch (IOException e) {
            throw new RuntimeException("文件操作失败: " + e.getMessage(), e);
        } catch (Exception e) {
            logger.error("文件导入失败 [路径: {}]", filePath, e);
            throw new RuntimeException("文件导入失败: " + e.getMessage(), e);
        }
    }
    private void compressHierarchy(TransferPackage pkg) {
        if (pkg.getTraceChain() == null ||
                pkg.getTraceChain().getComponentHierarchy() == null ||
                pkg.getTraceChain().getComponentHierarchy().getComponents().size() < 4) {
            return;
        }
        ComponentHierarchy hierarchy = pkg.getTraceChain().getComponentHierarchy();
        List<ComponentInfo> compressed = new ArrayList<>();
        // ä¿ç•™æ ¹éƒ¨ä»¶
        compressed.add(hierarchy.getComponents().get(0));
        // ä¿ç•™å…³é”®ä¸­é—´èŠ‚ç‚¹
        int step = Math.max(1, hierarchy.getComponents().size() / 3);
        for (int i = step; i < hierarchy.getComponents().size() - 1; i += step) {
            compressed.add(hierarchy.getComponents().get(i));
        }
        // ä¿ç•™å¶å­éƒ¨ä»¶
        compressed.add(hierarchy.getLeafComponent());
        // æ›´æ–°å±‚级
        hierarchy.getComponents().clear();
        hierarchy.getComponents().addAll(compressed);
    }
    private String generateFilename(TransferPackage.DataType type, String id) {
        return String.format("%s_%s_%d.ferry",
                type.name().toLowerCase(),
                id,
                System.currentTimeMillis());
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/PartsInfoServiceImpl.java
@@ -151,8 +151,8 @@
        boolean b = super.updateById(partsInfo);
        //同步修改结构树
        ProductMix productMix = productMixService.getById(Long.parseLong(id));
        productMix.setName(partsInfo.getPartsName());
        productMix.setCode(partsInfo.getPartsCode());
        productMix.setTreeName(partsInfo.getPartsName());
        productMix.setTreeCode(partsInfo.getPartsCode());
        productMixService.updateById(productMix);
        if(!b)
            return false;
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ProcessSpecVersionServiceImpl.java
@@ -205,8 +205,8 @@
        boolean b = super.updateById(processSpecVersion);
        //同步修改结构树
        ProductMix productMix = productMixService.getById(Long.parseLong(id));
        productMix.setName(processSpecVersion.getProcessSpecVersionName());
        productMix.setCode(processSpecVersion.getProcessSpecVersionCode());
        productMix.setTreeName(processSpecVersion.getProcessSpecVersionName());
        productMix.setTreeCode(processSpecVersion.getProcessSpecVersionCode());
        productMixService.updateById(productMix);
        if(!b)
            return false;
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ProcessStreamServiceImpl.java
@@ -176,8 +176,8 @@
        boolean b = super.updateById(stream);
        //同步修改结构树
        ProductMix productMix = productMixService.getById(Long.parseLong(id));
        productMix.setName(stream.getProcessName());
        productMix.setCode(stream.getProcessCode());
        productMix.setTreeName(stream.getProcessName());
        productMix.setTreeCode(stream.getProcessCode());
        productMixService.updateById(productMix);
        if(!b)
            ExceptionCast.cast(CommonCode.FAIL);
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ProductInfoServiceImpl.java
@@ -164,8 +164,8 @@
        boolean b = super.updateById(productInfo);
        //同步修改结构树
        ProductMix productMix = productMixService.getById(Long.parseLong(id));
        productMix.setName(productInfo.getProductName());
        productMix.setCode(productInfo.getProductNo());
        productMix.setTreeName(productInfo.getProductName());
        productMix.setTreeCode(productInfo.getProductNo());
        productMixService.updateById(productMix);
        if (!b)
            return false;
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/SecurityService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,48 @@
package org.jeecg.modules.dnc.service.impl;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.Security;
@Service
public class SecurityService {
    private static final String ALGORITHM = "SM4/ECB/PKCS5Padding";
    private final String secretKey;
    static {
        Security.addProvider(new BouncyCastleProvider());
    }
    @Autowired
    public SecurityService(@Value("${security.encryption-key}") String secretKey) {
        this.secretKey = secretKey;
    }
    public byte[] encrypt(byte[] data) {
        try {
            Cipher cipher = Cipher.getInstance(ALGORITHM, "BC");
            SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "SM4");
            cipher.init(Cipher.ENCRYPT_MODE, keySpec);
            return cipher.doFinal(data);
        } catch (Exception e) {
            throw new RuntimeException("加密失败", e);
        }
    }
    public byte[] decrypt(byte[] encryptedData) {
        try {
            Cipher cipher = Cipher.getInstance(ALGORITHM, "BC");
            SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "SM4");
            cipher.init(Cipher.DECRYPT_MODE, keySpec);
            return cipher.doFinal(encryptedData);
        } catch (Exception e) {
            throw new RuntimeException("解密失败", e);
        }
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/WorkStepServiceImpl.java
@@ -175,8 +175,8 @@
            ExceptionCast.cast(ProcessInfoCode.WORKSTEP_NOT_EXIST);
        //同步修改结构树
        ProductMix productMix = productMixService.getById(Long.parseLong(id));
        productMix.setName(workStep.getStepName());
        productMix.setCode(workStep.getStepCode());
        productMix.setTreeName(workStep.getStepName());
        productMix.setTreeCode(workStep.getStepCode());
        productMixService.updateById(productMix);
        return super.updateById(workStep);
    }
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/utils/CompressionUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,35 @@
package org.jeecg.modules.dnc.utils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public class CompressionUtils {
    public static byte[] gzipCompress(byte[] data) {
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
             GZIPOutputStream gzip = new GZIPOutputStream(bos)) {
            gzip.write(data);
            gzip.finish();
            return bos.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException("GZIP压缩失败", e);
        }
    }
    public static byte[] gzipDecompress(byte[] compressed) {
        try (ByteArrayInputStream bis = new ByteArrayInputStream(compressed);
             GZIPInputStream gzip = new GZIPInputStream(bis);
             ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
            byte[] buffer = new byte[1024];
            int len;
            while ((len = gzip.read(buffer)) > 0) {
                bos.write(buffer, 0, len);
            }
            return bos.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException("GZIP解压失败", e);
        }
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/utils/JsonUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,48 @@
package org.jeecg.modules.dnc.utils;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.text.SimpleDateFormat;
public class JsonUtils {
    private static final ObjectMapper objectMapper = createObjectMapper();
    private static ObjectMapper createObjectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        // é…ç½®æ—¥æœŸæ ¼å¼
        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        mapper.registerModule(new JavaTimeModule());
        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        // é…ç½®åºåˆ—化选项
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        // é…ç½®ååºåˆ—化选项
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
        mapper.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true);
        return mapper;
    }
    public static String toJson(Object object) {
        try {
            return objectMapper.writeValueAsString(object);
        } catch (Exception e) {
            throw new RuntimeException("JSON序列化失败: " + e.getMessage(), e);
        }
    }
    public static <T> T fromJson(String json, Class<T> valueType) {
        try {
            return objectMapper.readValue(json, valueType);
        } catch (Exception e) {
            throw new RuntimeException("JSON反序列化失败: " + e.getMessage() + "\nJSON内容: " + json, e);
        }
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/utils/TreeBuilder.java
@@ -108,8 +108,8 @@
            ProductMix newNode = new ProductMix(
                    node.getId(),
                    node.getParentId(),
                    node.getName(),
                    node.getCode(),
                    node.getTreeName(),
                    node.getTreeCode(),
                    node.getType(),
                    node.getCreateTime()
            );
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/IMdcProductionService.java
@@ -175,4 +175,11 @@
     * @return
     */
    List<String> findProIdsByUId(String userId, List<String> allProductionIds);
    /**
     * æ ¹æ®äº§çº¿orgCode查询产线
     * @param orgCode
     * @return
     */
    MdcProduction findByOrgCode(String orgCode);
}
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/impl/MdcProductionServiceImpl.java
@@ -627,4 +627,9 @@
            super.update(updateWrapper);
        }
    }
    @Override
    public MdcProduction findByOrgCode(String orgCode){
        return this.baseMapper.selectOne(new LambdaQueryWrapper<MdcProduction>().eq(MdcProduction::getOrgCode, orgCode));
    }
}