lyh
2025-06-25 e756af0f5bfd1addbd5d5c145441fb34aad91a28
同步工控网
已添加20个文件
已修改23个文件
2592 ■■■■■ 文件已修改
lxzn-boot-base-core/src/main/java/org/jeecg/common/constant/CommonConstant.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/controller/GuideCardBatchController.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/controller/ProductMixController.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/dto/TransferPackage.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/entity/GuideCardBatch.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/entity/ProductMix.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/listener/FileListener.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/mapper/ProductMixMapper.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/mapper/xml/PermissionStreamNewMapper.xml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/IGuideCardBatchService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/IProductMixService.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/DataImportService.java 204 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/FileFerryService.java 68 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/FullHierarchyTraceService.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/GuideCardBatchServiceImpl.java 224 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ProductMixServiceImpl.java 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/adapter/AssignEquipmentFileStreamAdapter.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/constant/DispatchFileEnum.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/constant/GuideCardBatchEnum.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/controller/AssignEquipmentFileStreamController.java 252 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/controller/DispatchFileController.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/entity/AssignEquipmentFileStream.java 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/mapper/AssignEquipmentFileStreamMapper.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/mapper/xml/AssignEquipmentFileStreamMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/service/IAssignEquipmentFileStreamService.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/service/IDispatchFileService.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/service/impl/AssignEquipmentFileStreamServiceImpl.java 316 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/service/impl/DispatchFileServiceImpl.java 153 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/service/impl/PermissionService.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/vo/AssignEquipmentFileStreamVo.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/vo/GuideCardBatchFlowTaskVo.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/job/ExportToXmlJob.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/ILogTableService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IMdcPassLogService.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/LogTableServiceImpl.java 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/entity/MdcPassLog.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/mapper/MdcPassLogMapper.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/MdcPassLogMapper.xml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/IMdcPassLogService.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/impl/MdcPassLogServiceImpl.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/util/FileUtils.java 194 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-start/src/main/java/org/jeecg/codegenerate/CreateTrigger.java 199 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-module-system/lxzn-system-start/src/main/resources/application-dev.yml 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lxzn-boot-base-core/src/main/java/org/jeecg/common/constant/CommonConstant.java
@@ -171,7 +171,7 @@
     */
    String SUPPLIERTYPE_1 = "1";
    String SUPPLIERTYPE_2 = "2";
   /**
    /**
     * åŒæ­¥å·¥ä½œæµå¼•擎1同步0不同步
     */
    Integer ACT_SYNC_1 = 1;
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/controller/GuideCardBatchController.java
@@ -12,6 +12,7 @@
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.modules.dnc.entity.GuideCardBatch;
import org.jeecg.modules.dnc.service.IGuideCardBatchService;
import org.jeecg.modules.dncFlow.vo.GuideCardBatchFlowTaskVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
@@ -138,6 +139,28 @@
        return Result.OK(guideCardBatch);
    }
     /**
      * å‘起确认流程
      * @param id
      * @return
      */
     @ApiOperation(value="nc文件对应数控程序加工确认表-发起确认流程", notes="nc文件对应数控程序加工确认表-发起确认流程")
     @GetMapping(value = "/startGuideCardBatch")
     public Result<?> startGuideCardBatch(String id){
         return guideCardBatchService.startGuideCardBatch(id);
     }
     /**
      * æµç¨‹èŠ‚ç‚¹å®¡æ ¸
      * @param guideCardBatchFlowTaskVo
      * @return
      */
     @ApiOperation(value="nc文件对应数控程序加工确认表-流程节点审核", notes="nc文件对应数控程序加工确认表-流程节点审核")
     @PostMapping(value = "/auditGuideCardBatch")
     public Result<?> auditGuideCardBatch(@RequestBody GuideCardBatchFlowTaskVo guideCardBatchFlowTaskVo){
         return guideCardBatchService.auditGuideCardBatch(guideCardBatchFlowTaskVo);
     }
    /**
    * å¯¼å‡ºexcel
    *
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/controller/ProductMixController.java
@@ -38,6 +38,18 @@
    }
    /**
     * èŽ·å–å…¨éƒ¨äº§å“æ ‘ï¼ˆåŒ…æ‹¬è®¾å¤‡ç±»ä¸Žnc文件)
     * @return
     */
    @AutoLog(value = "获取全部产品树")
    @ApiOperation(value = "获取全部产品树", notes = "获取全部产品树")
    @GetMapping(value = "/getAllTree")
    public Result<?> getAllTree() {
        List<ProductMix> productMixList = iProductMixService.getProductMixTree();
        return Result.OK(productMixList);
    }
    /**
     * èŽ·å–å…·ä½“å±‚çº§å®žä½“
     * @param id,type
     * @return
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/dto/TransferPackage.java
@@ -1,12 +1,11 @@
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.DocRelative;
import org.jeecg.modules.dnc.entity.*;
@Data
@Builder
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/entity/GuideCardBatch.java
@@ -9,6 +9,7 @@
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
@@ -104,6 +105,7 @@
    /**编写人*/
    @Excel(name = "编写人", width = 15)
    @ApiModelProperty(value = "编写人")
    @Dict(dictTable = "sys_user", dicCode = "username", dicText = "realname")
    private String compiler;
    /**编写日期*/
    @Excel(name = "编写日期", width = 15, format = "yyyy-MM-dd")
@@ -114,6 +116,7 @@
    /**校对人*/
    @Excel(name = "校对人", width = 15)
    @ApiModelProperty(value = "校对人")
    @Dict(dictTable = "sys_user", dicCode = "username", dicText = "realname")
    private String proofreader;
    /**校对日期*/
    @Excel(name = "校对日期", width = 15, format = "yyyy-MM-dd")
@@ -124,6 +127,7 @@
    /**操作者*/
    @Excel(name = "操作者", width = 15)
    @ApiModelProperty(value = "操作者")
    @Dict(dictTable = "sys_user", dicCode = "username", dicText = "realname")
    private String operator;
    /**首检日期*/
    @Excel(name = "首检日期", width = 15, format = "yyyy-MM-dd")
@@ -138,6 +142,7 @@
    /**审批人*/
    @Excel(name = "审批人", width = 15)
    @ApiModelProperty(value = "审批人")
    @Dict(dictTable = "sys_user", dicCode = "username", dicText = "realname")
    private String approver;
    /**审批日期*/
    @Excel(name = "审批日期", width = 15, format = "yyyy-MM-dd")
@@ -147,6 +152,7 @@
    private Date approverTime;
    /**创建人*/
    @ApiModelProperty(value = "创建人")
    @Dict(dictTable = "sys_user", dicCode = "username", dicText = "realname")
    private String createBy;
    /**创建日期*/
    @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/entity/ProductMix.java
@@ -6,6 +6,7 @@
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@@ -13,6 +14,7 @@
import java.util.Date;
import java.util.List;
@Getter
@Data
@NoArgsConstructor
@TableName(value = "nc_product_mix")
@@ -41,20 +43,19 @@
    //展示名称
    private transient String label;
    //类型方便前端展示
    //类型 æ–¹ä¾¿å‰ç«¯å±•示
    private transient Integer type;
    private transient List<ProductMix> children = new ArrayList<>();
    public ProductMix(Long id, Long parentId, String treeName, String treeCode, 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.treeName = treeName;
        this.treeCode = treeCode;
        this.treeCode = trrCode;
        this.type = type;
        this.children = new ArrayList<>();
        this.label="["+treeCode+"]"+treeName;
        this.label="["+ trrCode +"]"+ treeName;
        this.createTime = createTime;
    }
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/listener/FileListener.java
@@ -1,5 +1,4 @@
package org.jeecg.modules.dnc.listener;
import org.apache.commons.io.monitor.FileAlterationListener;
import org.apache.commons.io.monitor.FileAlterationObserver;
import org.jeecg.modules.dnc.dto.TransferPackage;
@@ -8,9 +7,11 @@
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 {
@@ -21,6 +22,7 @@
    @Autowired
    private DataImportService dataImportService;
    @Override
    public void onStart(FileAlterationObserver observer) {
@@ -46,11 +48,13 @@
    public void onFileCreate(File file) {
        String filePath = file.getAbsolutePath();
        log.info("[新建]: {}", filePath);
        if (filePath.endsWith(".ferry")){
            TransferPackage data = fileFerryService.importData(filePath);
            dataImportService.importTransferPackage(data);
            log.info("文件导入完成");
        }
//        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/ProductMixMapper.java
@@ -6,6 +6,23 @@
import org.jeecg.modules.dnc.entity.ProductMix;
public interface ProductMixMapper extends BaseMapper<ProductMix> {
    @Select("SELECT * FROM nc_product_mix WHERE id = #{productId} AND tree_type = 1")
    ProductMix findByProductId(@Param("productId") String productId);
    @Select("SELECT * FROM nc_product_mix WHERE id = #{componentId} AND tree_type = 2")
    ProductMix findByComponentId(@Param("componentId") String componentId);
    @Select("SELECT * FROM nc_product_mix WHERE id = #{partsId} AND tree_type = 3")
    ProductMix findByPartsId(@Param("partsId") String partsId);
    @Select("SELECT * FROM nc_product_mix WHERE id = #{operationId} AND tree_type = 4")
    ProductMix findByOperationId(@Param("operationId") String operationId);
    @Select("SELECT * FROM nc_product_mix WHERE id = #{processId} AND tree_type = 5")
    ProductMix findByProcessId(@Param("operationId") String processId);
    @Select("SELECT * FROM nc_product_mix WHERE id = #{worksiteId} AND tree_type = 6")
    ProductMix findByWorksiteId(@Param("operationId") String worksiteId);
    @Select("SELECT * FROM nc_product_mix WHERE id = #{productId} AND tree_type = 1")
    ProductMix findByProductId(@Param("productId") String productId);
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/mapper/xml/PermissionStreamNewMapper.xml
@@ -5,7 +5,7 @@
        SELECT DISTINCT
            mix.id,
            mix.tree_code,
            mix.tree_name,
                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,
                        mix.tree_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/IGuideCardBatchService.java
@@ -1,7 +1,9 @@
package org.jeecg.modules.dnc.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.dnc.entity.GuideCardBatch;
import org.jeecg.modules.dncFlow.vo.GuideCardBatchFlowTaskVo;
/**
 * @Description: nc文件对应数控程序加工确认表
@@ -24,4 +26,18 @@
     * @return
     */
    boolean importGuideCardBatch(String docId,String attributionId,Integer attributionType);
    /**
     * å‘起确认流程
     * @param id
     * @return
     */
    Result<?> startGuideCardBatch(String id);
    /**
     * æµç¨‹èŠ‚ç‚¹å®¡æ ¸
     * @param guideCardBatchFlowTaskVo
     * @return
     */
    Result<?> auditGuideCardBatch(GuideCardBatchFlowTaskVo guideCardBatchFlowTaskVo);
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/IProductMixService.java
@@ -1,6 +1,8 @@
package org.jeecg.modules.dnc.service;
import cn.hutool.core.lang.tree.Tree;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.dnc.entity.ProductMix;
import java.util.List;
@@ -8,7 +10,7 @@
public interface IProductMixService extends IService<ProductMix> {
    //获取封装产品结构树
    List<ProductMix> getTree();
    public List<ProductMix> getTree();
    /**
     * æŸ¥è¯¢å¯¹åº”id的所有父级(权限分配使用)
@@ -24,4 +26,9 @@
     */
    List<ProductMix> getChildrenList(String id);
    /**
     * æŸ¥è¯¢äº§å“ç»“构树(包括设备类与nc文件)
     * @return
     */
    List<ProductMix> getProductMixTree();
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/DataImportService.java
@@ -1,10 +1,16 @@
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.entity.MdcProduction;
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;
@@ -64,6 +70,48 @@
    @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 {
@@ -109,6 +157,12 @@
            if (transferPackage.getTraceChain() != null&&
                    transferPackage.getTraceChain().getTreePath() != null) {
                saveTreePath(transferPackage.getTraceChain().getTreePath());
            }
            //保存权限
            if (transferPackage.getTraceChain() != null&&
                    transferPackage.getTraceChain().getPermissionStreamNewList() != null) {
                savePermissionStreamNewList(transferPackage.getTraceChain().getPermissionStreamNewList());
            }
            // ä¿å­˜è®¾å¤‡ç±»
@@ -170,8 +224,7 @@
            productMapper.insert(product);
            logger.debug("产品已保存: {}", product.getProductId());
        } else {
            productMapper.updateById(product);
            logger.debug("产品已更新: {}", product.getProductId());
            logger.debug("产品已存在: {}", product.getProductId());
        }
    }
@@ -181,8 +234,7 @@
                componentMapper.insert(component);
                logger.debug("部件已保存: {}", component.getComponentId());
            } else {
                componentMapper.updateById(component);
                logger.debug("部件已更新: {}", component.getComponentId());
                logger.debug("部件已存在: {}", component.getComponentId());
            }
        }
    }
@@ -192,8 +244,7 @@
            partsMapper.insert(parts);
            logger.debug("零件已保存: {}", parts.getPartsId());
        } else {
            partsMapper.updateById(parts);
            logger.debug("零件已更新: {}", parts.getPartsId());
            logger.debug("零件已存在: {}", parts.getPartsId());
        }
    }
@@ -202,8 +253,7 @@
            psvMapper.insert(processSpec);
            logger.debug("工艺规程已保存: {}", processSpec.getId());
        } else {
            psvMapper.updateById(processSpec);
            logger.debug("工艺规程已更新: {}", processSpec.getId());
            logger.debug("工艺规程已存在: {}", processSpec.getId());
        }
    }
@@ -212,8 +262,7 @@
            processMapper.insert(process);
            logger.debug("工序已保存: {}", process.getProcessId());
        } else {
            processMapper.updateById(process);
            logger.debug("工序已更新: {}", process.getProcessId());
            logger.debug("工序已存在: {}", process.getProcessId());
        }
    }
@@ -222,8 +271,7 @@
            workStepMapper.insert(workStep);
            logger.debug("工步已保存: {}", workStep.getId());
        } else {
            workStepMapper.updateById(workStep);
            logger.debug("工步已更新: {}", workStep.getId());
            logger.debug("工步已存在: {}", workStep.getId());
        }
    }
@@ -233,10 +281,115 @@
                productMixMapper.insert(productMix);
                logger.debug("产品组合已保存: {}", productMix.getId());
            } else {
                productMixMapper.updateById(productMix);
                logger.debug("产品组合已更新: {}", productMix.getId());
                logger.debug("产品组合已存在: {}", productMix.getId());
            }
        }
    }
    private void savePermissionStreamNewList(List<PermissionStreamNew> permissionStreamNewList) {
        for (PermissionStreamNew permissionStreamNew : permissionStreamNewList) {
            if (permissionStreamNewMapper.selectById(permissionStreamNew.getId()) == null) {
                if (permissionStreamNew.getUserId() != null) {
                    String id=sysUserService.getUserByName(permissionStreamNew.getUserId()).getId();
                    if (id!=null){
                        permissionStreamNew.setUserId(id);
                    }
                }
                if (permissionStreamNew.getDepartId() != null) {
                    MdcProduction mdcProduction=mdcProductionService.findByOrgCode(permissionStreamNew.getDepartId());
                    if (mdcProduction!=null){
                        permissionStreamNew.setDepartId(mdcProduction.getId());
                    }
                }
                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) {
@@ -244,8 +397,7 @@
            deviceManagementMapper.insert(deviceManagement);
            logger.debug("设备类信息已保存: {}", deviceManagement.getId());
        } else {
            deviceManagementMapper.updateById(deviceManagement);
            logger.debug("设备类信息已更新: {}", deviceManagement.getId());
            logger.debug("设备类信息已存在: {}", deviceManagement.getId());
        }
    }
@@ -254,8 +406,7 @@
            deviceTypeMapper.insert(deviceType);
            logger.debug("设备类已保存: {}", deviceType.getId());
        } else {
            deviceTypeMapper.updateById(deviceType);
            logger.debug("设备类已更新: {}", deviceType.getId());
            logger.debug("设备类已存在: {}", deviceType.getId());
        }
    }
@@ -264,9 +415,7 @@
            docInfoMapper.insert(docInfo);
            logger.debug("文档已保存: {}", docInfo.getDocId());
        } else {
            docInfo.setDocDispatchStatus(5);
            docInfoMapper.updateById(docInfo);
            logger.debug("文档已更新: {}", docInfo.getDocId());
            logger.debug("文档已存在: {}", docInfo.getDocId());
        }
    }
@@ -275,8 +424,7 @@
            docFileMapper.insert(docFile);
            logger.debug("文档文件已保存: {}", docFile.getFileId());
        } else {
            docFileMapper.updateById(docFile);
            logger.debug("文档文件已更新: {}", docFile.getFileId());
            logger.debug("文档文件已存在: {}", docFile.getFileId());
        }
    }
@@ -285,8 +433,7 @@
            docRelativeMapper.insert(docRelative);
            logger.debug("文档对应关系已保存: {}", docRelative.getId());
        } else {
            docRelativeMapper.updateById(docRelative);
            logger.debug("文档对应关系已更新: {}", docRelative.getId());
            logger.debug("文档对应关系已存在: {}", docRelative.getId());
        }
    }
@@ -297,18 +444,17 @@
                logger.debug("刀具已保存: {}", cutter.getId());
            } else {
                cutterMapper.updateById(cutter);
                logger.debug("刀具已更新: {}", cutter.getId());
            }
        }
    }
    private void saveGuideCardBatch(GuideCardBatch guideCardBatch) {
        if (guideCardBatchMapper.selectById(guideCardBatch.getId()) == null) {
            guideCardBatch.setFlowStatus("1");
            guideCardBatchMapper.insert(guideCardBatch);
            logger.debug("程序加工确认表已保存: {}", guideCardBatch.getId());
            logger.debug("刀片批次已保存: {}", guideCardBatch.getId());
        } else {
            guideCardBatchMapper.updateById(guideCardBatch);
            logger.debug("程序加工确认表已更新: {}", guideCardBatch.getId());
            logger.debug("刀片批次已存在: {}", guideCardBatch.getId());
        }
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/FileFerryService.java
@@ -1,13 +1,24 @@
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.ComponentInfo;
import org.jeecg.modules.dnc.entity.DocFile;
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;
@@ -29,9 +40,6 @@
@Service
public class FileFerryService {
    private final DataPackageService dataPackageService;
    private final SecurityService securityService;
    private static final Logger logger = LoggerFactory.getLogger(FileFerryService.class);
    @Value("${deploy.secretFolder}")
@@ -47,19 +55,15 @@
    private IMdcProductionService mdcProductionService;
    @Autowired
    private IDocInfoService docInfoService;
    @Autowired
    private IDocClassificationService classificationService;
    @Autowired
    private IDocRelativeService docRelativeService;
    @Autowired
    private IDocInfoService docInfoService;
    @Autowired
    public FileFerryService(DataPackageService dataPackageService, SecurityService securityService) {
        this.dataPackageService = dataPackageService;
        this.securityService = securityService;
    }
    private DataPackageService dataPackageService;
    public String exportData(TransferPackage.DataType type, String id,String fileName) {
        // 1. èŽ·å–å°è£…æ•°æ®
@@ -87,6 +91,8 @@
            throw new RuntimeException("文件写入失败", e);
        }
    }
    public TransferPackage importData(String filePath) {
        try {
@@ -140,6 +146,7 @@
            // 6. èŽ·å–æ–‡ä»¶å¤åˆ¶ç›®æ ‡è·¯å¾„
            DocFile docFile = pkg.getTraceChain().getDocFile();
            DocInfo docInfo = pkg.getTraceChain().getDocInfo();
            if (docFile == null) {
                throw new IllegalStateException("传输包中缺少文档文件信息");
            }
@@ -159,6 +166,41 @@
            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);
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/FullHierarchyTraceService.java
@@ -6,7 +6,6 @@
import org.jeecg.modules.dnc.entity.*;
import org.jeecg.modules.dnc.mapper.*;
import org.jeecg.modules.dnc.service.IPermissionStreamNewService;
import org.jeecg.modules.system.entity.MdcProduction;
import org.jeecg.modules.system.service.IMdcProductionService;
import org.jeecg.modules.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -47,12 +46,6 @@
    private CutterMapper cutterMapper;
    @Autowired
    private GuideCardBatchMapper guideCardBatchMapper;
    @Autowired
    private IPermissionStreamNewService permissionStreamNewService;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private IMdcProductionService mdcProductionService;
    public ProcessTraceChain traceFromProcess(DocRelative docRelative) {
        ProcessTraceChain chain = initChainWithDocInfo(docRelative);
@@ -67,7 +60,6 @@
        completeChainWithProductInfo(chain);
        List<ProductMix> productMixList=buildFullTreePath(chain);
        chain.setTreePath(productMixList);
        chain.setPermissionStreamNewList(buildFullTreePathPermission(productMixList));
        return chain;
    }
@@ -84,7 +76,6 @@
        completeChainWithProductInfo(chain);
        List<ProductMix> productMixList=buildFullTreePath(chain);
        chain.setTreePath(productMixList);
        chain.setPermissionStreamNewList(buildFullTreePathPermission(productMixList));
        return chain;
    }
@@ -219,22 +210,4 @@
        return path;
    }
    private List<PermissionStreamNew> buildFullTreePathPermission(List<ProductMix> productMixList) {
        List<Long> ids=productMixList.stream().map(ProductMix::getId).collect(Collectors.toList());
        List<PermissionStreamNew> path = permissionStreamNewService
                .list(new QueryWrapper<PermissionStreamNew>().in("business_id",ids)
                        .eq("delete_flag",0));
        path.forEach(item->{
            if (item.getDepartId()!=null){
                MdcProduction mdcProduction=mdcProductionService.getById(item.getDepartId());
                if(mdcProduction!=null){
                    item.setDepartId(item.getDepartId());
                }
            }
            if (item.getUserId()!=null){
                item.setUserId(sysUserService.getById(item.getUserId()).getUsername());
            }
        });
        return path;
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/GuideCardBatchServiceImpl.java
@@ -1,21 +1,39 @@
package org.jeecg.modules.dnc.service.impl;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.shiro.SecurityUtils;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.dnc.constant.DocAttributionTypeEnum;
import org.jeecg.modules.dnc.entity.*;
import org.jeecg.modules.dnc.mapper.GuideCardBatchMapper;
import org.jeecg.modules.dnc.response.ActivitiCode;
import org.jeecg.modules.dnc.response.CommonCode;
import org.jeecg.modules.dnc.response.UcenterCode;
import org.jeecg.modules.dnc.service.*;
import org.jeecg.modules.dnc.utils.ValidateUtil;
import org.jeecg.modules.dncFlow.constant.GuideCardBatchEnum;
import org.jeecg.modules.dncFlow.entity.DispatchFile;
import org.jeecg.modules.dncFlow.vo.GuideCardBatchFlowTaskVo;
import org.jeecg.modules.flowable.apithird.business.entity.FlowMyBusiness;
import org.jeecg.modules.flowable.apithird.business.service.IFlowMyBusinessService;
import org.jeecg.modules.flowable.apithird.service.FlowCallBackServiceI;
import org.jeecg.modules.flowable.apithird.service.FlowCommonService;
import org.jeecg.modules.flowable.service.IFlowDefinitionService;
import org.jeecg.modules.flowable.service.IFlowTaskService;
import org.jeecg.modules.system.service.ISysDictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.util.Date;
import java.util.List;
import javax.annotation.Resource;
import java.util.*;
/**
 * @Description: nc文件对应数控程序加工确认表
@@ -23,8 +41,8 @@
 * @Date:   2025-05-27
 * @Version: V1.0
 */
@Service
public class GuideCardBatchServiceImpl extends ServiceImpl<GuideCardBatchMapper, GuideCardBatch> implements IGuideCardBatchService {
@Service("IGuideCardBatchService")
public class GuideCardBatchServiceImpl extends ServiceImpl<GuideCardBatchMapper, GuideCardBatch> implements IGuideCardBatchService , FlowCallBackServiceI {
    @Autowired
    private ISysDictService sysDictService;
@@ -43,6 +61,17 @@
    @Autowired
    private IDeviceTypeService deviceTypeService;
    @Resource
    private FlowCommonService flowCommonService;
    @Resource
    private IFlowDefinitionService flowDefinitionService;
    @Autowired
    private IFlowTaskService flowTaskService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private IFlowMyBusinessService flowMyBusinessService;
    /**
     * ç”Ÿæˆæµæ°´å·
@@ -126,18 +155,193 @@
            guideCardBatch.setProcessWorkCode(workStep.getStepCode());
            partsInfo=partsInfoService.getById(workStep.getPartsId());
        }
        if (partsInfo==null){
            return false;
        }
        guideCardBatch.setDocId(docId);
        guideCardBatch.setSerialNumber(getSerialNumber("C140"));
        guideCardBatch.setUnit(sysDictService.queryDictTextByKey("unit_code", "C140"));
        guideCardBatch.setDocName(docInfo.getDocName());
        if (partsInfo!=null){
            guideCardBatch.setPartsCode(partsInfo.getPartsCode());
            guideCardBatch.setPartsName(partsInfo.getPartsName());
            guideCardBatch.setMaterielDesp(partsInfo.getStructureType());
        }
        guideCardBatch.setFlowStatus("0");
        guideCardBatch.setPartsCode(partsInfo.getPartsCode());
        guideCardBatch.setPartsName(partsInfo.getPartsName());
        guideCardBatch.setMaterielDesp(partsInfo.getMaterielDesp());
        guideCardBatch.setCompiler(user.getUsername());
        guideCardBatch.setCreateTime(new Date());
        return this.save(guideCardBatch);
    }
    /**
     * å‘起确认流程
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> startGuideCardBatch(String id){
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        //获取程序加工确认表
        GuideCardBatch guideCardBatch=this.getById(id);
        if (guideCardBatch==null) {
            return Result.ok("未找到对应的程序加工确认表");
        }
        //填充数据
        guideCardBatch.setCompiler(user.getUsername());
        guideCardBatch.setCompilerTime(new Date());
        guideCardBatch.setFlowStatus(GuideCardBatchEnum.VERIFY.getCode());
        this.updateById(guideCardBatch);
        System.out.println("程序加工确认表 ç¡®è®¤æµç¨‹ï¼š" + guideCardBatch.getId());
        flowCommonService.initActBusiness("流水号:"+guideCardBatch.getSerialNumber()+" ç¨‹åºåŠ å·¥ç¡®è®¤è¡¨è¿›è¡Œç¡®è®¤æµç¨‹",
                guideCardBatch.getId(), "IGuideCardBatchService", "nc_guide_card_batch", null);
        Map<String, Object> variables = new HashMap<>();
        variables.put("dataId", guideCardBatch.getId());
        variables.put("organization", "用户"+user.getRealname()+"发起流程");
        variables.put("comment",  "用户"+user.getRealname()+"发起流程");
        variables.put("proofreading",true);
        Result result= flowDefinitionService.startProcessInstanceByKey("nc_guide_card_batch", variables);
        if (!result.isSuccess()) {
            guideCardBatch.setCompiler(null);
            guideCardBatch.setCompilerTime(null);
            this.updateById(guideCardBatch);
        }
        return result;
    }
    /**
     * æµç¨‹èŠ‚ç‚¹å®¡æ ¸
     * @param guideCardBatchFlowTaskVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> auditGuideCardBatch(GuideCardBatchFlowTaskVo guideCardBatchFlowTaskVo){
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        try {
            // å‚数校验
            if (!ValidateUtil.validateString(guideCardBatchFlowTaskVo.getTaskId()) || !ValidateUtil.validateString(guideCardBatchFlowTaskVo.getDataId())) {
                return Result.error(CommonCode.INVALID_PARAM.toString());
            }
            String userId = user.getId();
            guideCardBatchFlowTaskVo.setAssignee(user.getUsername());
            if (!ValidateUtil.validateString(userId)) {
                return Result.error(UcenterCode.UCENTER_ACCOUNT_NOT_EXIST.toString());
            }
            // æ•°æ®æŸ¥è¯¢
            GuideCardBatch guideCardBatch = this.getById(guideCardBatchFlowTaskVo.getDataId());
            if (guideCardBatch == null) {
                return Result.error(CommonCode.INVALID_PARAM.toString());
            }
            DocInfo docInfo = docInfoService.getById(guideCardBatch.getDocId());
            if (docInfo == null) {
                return Result.error(ActivitiCode.ACT_DOC_ERROR.toString());
            }
            // 2. æŸ¥è¯¢æµç¨‹ä¸šåŠ¡è®°å½•ï¼ˆå¤„ç†ç©ºç»“æžœï¼‰
            List<FlowMyBusiness> businessList = flowMyBusinessService.list(
                    new QueryWrapper<FlowMyBusiness>()
                            .eq("process_instance_id", guideCardBatchFlowTaskVo.getInstanceId())
            );
            if (businessList.isEmpty()) {
                return Result.error("流程记录不存在");
            }
            FlowMyBusiness flowMyBusiness = businessList.get(0);
            // 3. æ ¡éªŒç”¨æˆ·æ˜¯å¦ä¸ºå€™é€‰å¤„理人
            List<String> todoUsers = JSON.parseArray(flowMyBusiness.getTodoUsers(), String.class);
            if (todoUsers == null || !todoUsers.contains(user.getUsername())) {
                return Result.error("用户无权操作此任务");
            }
            // 4. è®¤é¢†ä»»åŠ¡ï¼ˆå¤„ç†å·²è¢«è®¤é¢†çš„æƒ…å†µï¼‰
            String taskId = flowMyBusiness.getTaskId();
            Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
            if (task == null) {
                return Result.error("任务不存在或已完成");
            }
            if (task.getAssignee() != null && !task.getAssignee().equals(user.getUsername())) {
                return Result.error("任务已被他人认领");
            }
            taskService.claim(taskId, user.getUsername());
            // è®¾ç½®æµç¨‹å˜é‡
            Map<String, Object> values = new HashMap<>();
            values.put("dataId", guideCardBatch.getId());
            values.put("assignee", userId);
            values.put("comment", guideCardBatchFlowTaskVo.getComment());
            values.put("organization", guideCardBatchFlowTaskVo.getComment());
            if (guideCardBatchFlowTaskVo.getCheckType() != null) {
                values.put("checkType", guideCardBatchFlowTaskVo.getCheckType());
            }
            if (guideCardBatchFlowTaskVo.getConfirmType() != null) {
                values.put("confirmType", guideCardBatchFlowTaskVo.getConfirmType());
            }
            if (guideCardBatchFlowTaskVo.getApproveType() != null) {
                values.put("approveType", guideCardBatchFlowTaskVo.getApproveType());
            }
            guideCardBatchFlowTaskVo.setValues(values);
            // å®Œæˆæµç¨‹ä»»åŠ¡
            Result result = flowTaskService.complete(guideCardBatchFlowTaskVo);
            if (result.isSuccess()) {
                if (guideCardBatchFlowTaskVo.getCheckType() != null) {
                    if (guideCardBatchFlowTaskVo.getCheckType()){
                        guideCardBatch.setFlowStatus(GuideCardBatchEnum.CONFIRM.getCode());
                        guideCardBatch.setProofreader(user.getUsername());
                        guideCardBatch.setProofreaderTime(new Date());
                    }else {
                        guideCardBatch.setFlowStatus(GuideCardBatchEnum.PREPARE.getCode());
                    }
                }
                if (guideCardBatchFlowTaskVo.getConfirmType() != null) {
                    if (guideCardBatchFlowTaskVo.getConfirmType()){
                        guideCardBatch.setFlowStatus(GuideCardBatchEnum.APPROVE.getCode());
                        guideCardBatch.setOperator(user.getUsername());
                        guideCardBatch.setInspectionTime(new Date());
                        guideCardBatch.setInspectionOpinion(guideCardBatchFlowTaskVo.getInspectionOpinion());
                    }else {
                        guideCardBatch.setFlowStatus(GuideCardBatchEnum.PREPARE.getCode());
                    }
                }
                if (guideCardBatchFlowTaskVo.getApproveType() != null) {
                    if (guideCardBatchFlowTaskVo.getApproveType()){
                        guideCardBatch.setFlowStatus(GuideCardBatchEnum.COMPLETE.getCode());
                        guideCardBatch.setApprover(user.getUsername());
                        guideCardBatch.setApproverTime(new Date());
                    }else {
                        guideCardBatch.setFlowStatus(GuideCardBatchEnum.PREPARE.getCode());
                        }
                }
                this.updateById(guideCardBatch);
            } else {
                return result;
            }
            return Result.OK("操作成功");
        } catch (Exception e) {
            // è®¾ç½®äº‹åŠ¡å›žæ»š
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.error("操作失败:" + e.getMessage());
        }
    }
    @Override
    public void afterFlowHandle(FlowMyBusiness business) {
        business.getTaskNameId();//接下来审批的节点
        business.getValues();//前端传进来的参数
        business.getActStatus();
    }
    @Override
    public Object getBusinessDataById(String dataId) {
        return this.getById(dataId);
    }
    @Override
    public Map<String, Object> flowValuesOfTask(String taskNameId, Map<String, Object> values) {
        return null;
    }
    @Override
    public List<String> flowCandidateUsernamesOfTask(String taskNameId, Map<String, Object> values) {
        //业务是否干预流程,业务干预,流程干预,指定人员进行处理
        return null;
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dnc/service/impl/ProductMixServiceImpl.java
@@ -1,17 +1,19 @@
package org.jeecg.modules.dnc.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.dnc.entity.ProductMix;
import org.jeecg.modules.dnc.entity.*;
import org.jeecg.modules.dnc.mapper.ProductMixMapper;
import org.jeecg.modules.dnc.service.IPermissionStreamNewService;
import org.jeecg.modules.dnc.service.IProductMixService;
import org.jeecg.modules.dnc.service.*;
import org.jeecg.modules.dnc.utils.TreeBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
@Service
public class ProductMixServiceImpl extends ServiceImpl<ProductMixMapper, ProductMix> implements IProductMixService {
@@ -19,6 +21,21 @@
    @Autowired
    private IPermissionStreamNewService permissionStreamNewService;
    @Autowired
    @Lazy
    private IDeviceTypeService deviceTypeService;
    @Autowired
    @Lazy
    private IDeviceManagementService deviceManagementService;
    @Autowired
    @Lazy
    private IDocInfoService docInfoService;
    @Autowired
    @Lazy
    private IDocRelativeService docRelativeService;
    /**
     * é»˜è®¤ç»“构树查询
     * @return
@@ -111,4 +128,72 @@
        return childrenList;
    }
    /**
     * æŸ¥è¯¢äº§å“ç»“构树(包括设备类与nc文件)
     * @return
     */
    @Override
    public List<ProductMix> getProductMixTree() {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        List<ProductMix> rawData = new ArrayList<>();
        if (loginUser.getUsername().equals("admin")) {
            //不需要权限过滤
            rawData = permissionStreamNewService.loadProductMixAll(loginUser.getId());
        } else {
            //需要权限过滤
            String productIds = loginUser.getProductionIds();
            if (productIds != null && !productIds.isEmpty()) {
                List<String> productIdList = Arrays.asList(productIds.split(","));
                rawData = permissionStreamNewService.loadProductMix(loginUser.getId(), productIdList);
            }
        }
        List<Long> ids = rawData.stream()
                .filter(p -> p.getType() != null)
                .filter(productMix -> productMix.getType() == 5 || productMix.getType() == 6)
                .map(ProductMix::getId)
                .collect(Collectors.toList());
        if (ids.isEmpty()) {
            return rawData;
        }
        //过滤设备类关联信息
        List<DeviceType> deviceTypeList = deviceTypeService.list(new QueryWrapper<DeviceType>()
                .in("attribution_id", ids));
        List<ProductMix> productMixList = new ArrayList<>();
        deviceTypeList.forEach(item->{
            ProductMix productMix = new ProductMix();
            productMix.setId(Long.parseLong(item.getId()));
            productMix.setParentId(Long.parseLong(item.getAttributionId()));
            DeviceManagement deviceManagement=deviceManagementService.getById(item.getDeviceManagementId());
            productMix.setTreeCode(deviceManagement.getDeviceManagementCode());
            productMix.setTreeName(deviceManagement.getDeviceManagementName());
            productMix.setType(7);
            productMixList.add(productMix);
        });
        rawData.addAll(productMixList);
        //过滤文档关联信息
        List<String> deviceTypeIds = deviceTypeList.stream().map(DeviceType::getId).collect(Collectors.toList());
        List<DocRelative> relativeList = docRelativeService.list(new QueryWrapper<DocRelative>()
                .in("attribution_id", deviceTypeIds));
        List<ProductMix> docList = new ArrayList<>();
        relativeList.forEach(item->{
            ProductMix productMix = new ProductMix();
            productMix.setId(Long.parseLong(item.getId()));
            productMix.setParentId(Long.parseLong(item.getAttributionId()));
            DocInfo docInfo = docInfoService.getById(item.getDocId());
            productMix.setTreeCode(docInfo.getDocSuffix());
            productMix.setTreeName(docInfo.getDocName());
            productMix.setType(99);
            docList.add(productMix);
        });
        rawData.addAll(docList);
        TreeBuilder builder = new TreeBuilder();
        TreeBuilder.CleanResult cleanResult = builder.preprocessData(rawData);
        List<ProductMix> sorted = builder.topologicalSort(
                cleanResult.getValidNodes(),
                cleanResult.getNodeMap()
        );
        List<ProductMix> result =builder.assembleTree(sorted, cleanResult.getNodeMap());
        result.sort(Comparator.comparing(ProductMix::getCreateTime, Comparator.nullsLast(Date::compareTo)));
        return result;
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/adapter/AssignEquipmentFileStreamAdapter.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,53 @@
package org.jeecg.modules.dncFlow.adapter;
import org.jeecg.modules.dncFlow.entity.AssignEquipmentFileStream;
import org.jeecg.modules.dncFlow.service.StreamTarget;
public class AssignEquipmentFileStreamAdapter implements StreamTarget {
    private final AssignEquipmentFileStream file;
    public AssignEquipmentFileStreamAdapter(AssignEquipmentFileStream file) {
        this.file = file;
    }
    @Override
    public void setProductId(String productId) {
        file.setProductId(productId);
    }
    @Override
    public void setComponentId(String componentId) {
        file.setComponentId(componentId);
    }
    @Override
    public void setPartsId(String partsId) {
        file.setPartsId(partsId);
    }
    @Override
    public void setProcessId(String processId) {
        file.setProcessId(processId);
    }
    @Override
    public void setPsvId(String psvId) {
        file.setPsvId(psvId);
    }
    @Override
    public void setStepId(String stepId) {
        file.setStepId(stepId);
    }
    @Override
    public void setDeviceTypeId(String deviceTypeId) {
        file.setDeviceTypeId(deviceTypeId);
    }
    @Override
    public String getAttributionId() {
        return file.getAttributionId();
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/constant/DispatchFileEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,36 @@
package org.jeecg.modules.dncFlow.constant;
public enum DispatchFileEnum {
    COMPLETE("1", "编制"),
    VERIFY("2", "校对"),
    APPROVE("3", "批准");
    private String code;
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    DispatchFileEnum() {
    }
    DispatchFileEnum(String code, String name) {
        this.code = code;
        this.name = name;
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/constant/GuideCardBatchEnum.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,41 @@
package org.jeecg.modules.dncFlow.constant;
public enum GuideCardBatchEnum {
    PREPARE("1", "编制"),
    VERIFY("2", "校对"),
    CONFIRM("3", "操作确认"),
    APPROVE("4", "审批"),
    COMPLETE("5", "完成");
    private String code;
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    GuideCardBatchEnum() {
    }
    GuideCardBatchEnum(String code, String name) {
        this.code = code;
        this.name = name;
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/controller/AssignEquipmentFileStreamController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,252 @@
package org.jeecg.modules.dncFlow.controller;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.dnc.entity.DeviceManagement;
import org.jeecg.modules.dnc.entity.DeviceType;
import org.jeecg.modules.dnc.entity.DocInfo;
import org.jeecg.modules.dnc.entity.DocRelative;
import org.jeecg.modules.dnc.service.IDeviceManagementService;
import org.jeecg.modules.dnc.service.IDeviceTypeService;
import org.jeecg.modules.dnc.service.IDocInfoService;
import org.jeecg.modules.dnc.service.IDocRelativeService;
import org.jeecg.modules.dncFlow.entity.AssignEquipmentFileStream;
import org.jeecg.modules.dncFlow.service.IAssignEquipmentFileStreamService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.dncFlow.vo.AssignEquipmentFileStreamVo;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.jeecg.common.system.base.controller.JeecgController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jeecg.common.aspect.annotation.AutoLog;
 /**
 * @Description: DNC-设备结构树指派产品结构树
 * @Author: jeecg-boot
 * @Date:   2025-06-17
 * @Version: V1.0
 */
@Api(tags="DNC-设备结构树指派产品结构树")
@RestController
@RequestMapping("/dncFlow/assignEquipmentFileStream")
@Slf4j
public class AssignEquipmentFileStreamController extends JeecgController<AssignEquipmentFileStream, IAssignEquipmentFileStreamService> {
    @Autowired
    private IAssignEquipmentFileStreamService assignEquipmentFileStreamService;
    @Autowired
    private IDeviceTypeService deviceTypeService;
    @Autowired
    private IDeviceManagementService deviceManagementService;
    @Autowired
    private IDocRelativeService docRelativeService;
    @Autowired
    private IDocInfoService docInfoService;
    /**
     * åˆ†é¡µåˆ—表查询
     *
     * @param assignEquipmentFileStream
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    //@AutoLog(value = "DNC-设备结构树指派产品结构树-分页列表查询")
    @ApiOperation(value="DNC-设备结构树指派产品结构树-分页列表查询", notes="DNC-设备结构树指派产品结构树-分页列表查询")
    @GetMapping(value = "/list")
    public Result<IPage<AssignEquipmentFileStream>> queryPageList(AssignEquipmentFileStream assignEquipmentFileStream,
                                   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
                                   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
                                   HttpServletRequest req) {
        QueryWrapper<AssignEquipmentFileStream> queryWrapper = QueryGenerator.initQueryWrapper(assignEquipmentFileStream, req.getParameterMap());
        Page<AssignEquipmentFileStream> page = new Page<AssignEquipmentFileStream>(pageNo, pageSize);
        IPage<AssignEquipmentFileStream> pageList = assignEquipmentFileStreamService.page(page, queryWrapper);
        return Result.OK(pageList);
    }
     /**
      * æµç¨‹å¯åЍ,保存对应的数据
      * @param assignEquipmentFileStream
      * @return
      */
     @AutoLog(value = "DNC-设备结构树指派产品结构树-流程启动,保存对应的数据")
     @ApiOperation(value="DNC-设备结构树指派产品结构树-流程启动,保存对应的数据", notes="DNC-设备结构树指派产品结构树-流程启动,保存对应的数据")
     @PostMapping(value = "savaFlow")
     public Result<?> saveAssignEquipmentFileStream(@RequestBody AssignEquipmentFileStream assignEquipmentFileStream){
         return assignEquipmentFileStreamService.saveAssignEquipmentFileStream(assignEquipmentFileStream);
     }
     /**
      * æµç¨‹èŠ‚ç‚¹å®¡æ ¸
      * @param assignEquipmentFileStreamVo
      * @return
      */
     @AutoLog(value = "DNC-设备结构树指派产品结构树-流程节点审核")
     @ApiOperation(value="DNC-设备结构树指派产品结构树-流程节点审核", notes="DNC-设备结构树指派产品结构树-流程节点审核")
     @PostMapping(value = "audit")
     public Result<?> auditAssignEquipmentFileStream(@RequestBody AssignEquipmentFileStreamVo assignEquipmentFileStreamVo){
         return assignEquipmentFileStreamService.auditAssignEquipmentFileStream(assignEquipmentFileStreamVo);
     }
    /**
     *   æ·»åŠ 
     *
     * @param assignEquipmentFileStream
     * @return
     */
    @AutoLog(value = "DNC-设备结构树指派产品结构树-添加")
    @ApiOperation(value="DNC-设备结构树指派产品结构树-添加", notes="DNC-设备结构树指派产品结构树-添加")
    //@RequiresPermissions("org.jeecg.modules:nc_assign_equipment_file_stream:add")
    @PostMapping(value = "/add")
    public Result<String> add(@RequestBody AssignEquipmentFileStream assignEquipmentFileStream) {
        assignEquipmentFileStreamService.save(assignEquipmentFileStream);
        return Result.OK("添加成功!");
    }
     /**
      * æŸ¥è¯¢å®¡ç­¾åŸºæœ¬ä¿¡æ¯
      * @param id
      * @return
      */
     @ApiOperation(value = "查询审签基本信息", notes = "查询审签基本信息")
     @GetMapping(value = "/selectVoById")
     public Result<?> selectVoById(@RequestParam(name="id") String id){
         List<AssignEquipmentFileStream> list = assignEquipmentFileStreamService.list(new QueryWrapper<AssignEquipmentFileStream>().eq("id", id));
         if (!list.isEmpty()){
             list.forEach(item->{
                 DeviceType deviceType = deviceTypeService.getById(item.getDeviceTypeId());
                 if (deviceType!=null){
                     DeviceManagement deviceManagement = deviceManagementService.getById(deviceType.getDeviceManagementId());
                     if (deviceManagement!=null){
                         item.setDeviceTypeName(deviceManagement.getDeviceManagementName());
                     }
                 }
                 DocRelative docRelative=docRelativeService.getById(item.getDocId());
                 if (docRelative!=null){
                     DocInfo docInfo = docInfoService.getById(docRelative.getDocId());
                     item.setDocName(docInfo.getDocName());
                 }
             });
             return Result.OK(list);
         }
         return Result.error("未找到对应数据");
     }
    /**
     *  ç¼–辑
     *
     * @param assignEquipmentFileStream
     * @return
     */
    @AutoLog(value = "DNC-设备结构树指派产品结构树-编辑")
    @ApiOperation(value="DNC-设备结构树指派产品结构树-编辑", notes="DNC-设备结构树指派产品结构树-编辑")
    //@RequiresPermissions("org.jeecg.modules:nc_assign_equipment_file_stream:edit")
    @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
    public Result<String> edit(@RequestBody AssignEquipmentFileStream assignEquipmentFileStream) {
        assignEquipmentFileStreamService.updateById(assignEquipmentFileStream);
        return Result.OK("编辑成功!");
    }
    /**
     *   é€šè¿‡id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "DNC-设备结构树指派产品结构树-通过id删除")
    @ApiOperation(value="DNC-设备结构树指派产品结构树-通过id删除", notes="DNC-设备结构树指派产品结构树-通过id删除")
    //@RequiresPermissions("org.jeecg.modules:nc_assign_equipment_file_stream:delete")
    @DeleteMapping(value = "/delete")
    public Result<String> delete(@RequestParam(name="id",required=true) String id) {
        assignEquipmentFileStreamService.removeById(id);
        return Result.OK("删除成功!");
    }
    /**
     *  æ‰¹é‡åˆ é™¤
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "DNC-设备结构树指派产品结构树-批量删除")
    @ApiOperation(value="DNC-设备结构树指派产品结构树-批量删除", notes="DNC-设备结构树指派产品结构树-批量删除")
    //@RequiresPermissions("org.jeecg.modules:nc_assign_equipment_file_stream:deleteBatch")
    @DeleteMapping(value = "/deleteBatch")
    public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
        this.assignEquipmentFileStreamService.removeByIds(Arrays.asList(ids.split(",")));
        return Result.OK("批量删除成功!");
    }
    /**
     * é€šè¿‡id查询
     *
     * @param id
     * @return
     */
    //@AutoLog(value = "DNC-设备结构树指派产品结构树-通过id查询")
    @ApiOperation(value="DNC-设备结构树指派产品结构树-通过id查询", notes="DNC-设备结构树指派产品结构树-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<AssignEquipmentFileStream> queryById(@RequestParam(name="id",required=true) String id) {
        AssignEquipmentFileStream assignEquipmentFileStream = assignEquipmentFileStreamService.getById(id);
        if(assignEquipmentFileStream==null) {
            return Result.error("未找到对应数据");
        }
        return Result.OK(assignEquipmentFileStream);
    }
    /**
    * å¯¼å‡ºexcel
    *
    * @param request
    * @param assignEquipmentFileStream
    */
    //@RequiresPermissions("org.jeecg.modules:nc_assign_equipment_file_stream:exportXls")
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, AssignEquipmentFileStream assignEquipmentFileStream) {
        return super.exportXls(request, assignEquipmentFileStream, AssignEquipmentFileStream.class, "DNC-设备结构树指派产品结构树");
    }
    /**
      * é€šè¿‡excel导入数据
    *
    * @param request
    * @param response
    * @return
    */
    //@RequiresPermissions("nc_assign_equipment_file_stream:importExcel")
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, AssignEquipmentFileStream.class);
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/controller/DispatchFileController.java
@@ -10,6 +10,10 @@
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.modules.dnc.entity.DocInfo;
import org.jeecg.modules.dnc.response.CommonCode;
import org.jeecg.modules.dnc.response.ResponseResult;
import org.jeecg.modules.dnc.service.IDocInfoService;
import org.jeecg.modules.dncFlow.entity.DispatchFile;
import org.jeecg.modules.dncFlow.service.IDispatchFileService;
import org.jeecg.modules.dncFlow.vo.DispatchFileFlowTaskVo;
@@ -40,6 +44,8 @@
    @Autowired
    private IHisWorkTaskService hisWorkTaskService;
    @Autowired
    private IDocInfoService docInfoService;
    /**
     * åˆ†é¡µåˆ—表查询
     *
@@ -231,5 +237,21 @@
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, DispatchFile.class);
    }
     @AutoLog(value = "文档表-定型流程发起")
     @ApiOperation(value = "文档表-定型流程发起", notes = "文档表-定型流程发起")
     @PostMapping("/submitProccess")
     public ResponseResult submitProccess(@RequestBody DispatchFile dispatchFile) {
         dispatchFileService.submitProccess(dispatchFile);
         return new ResponseResult(CommonCode.SUCCESS);
     }
     @AutoLog(value = "文档表-信息查询")
     @ApiOperation(value = "文档表-信息查询", notes = "文档表-信息查询")
     @GetMapping("/queryDocInfoByFlowDataId")
     public Result<DocInfo> queryDocInfoByFlowDataId(@RequestParam("dataId") String dataId) {
         DispatchFile dispatchFile = dispatchFileService.getById(dataId);
         DocInfo docInfo = docInfoService.getById(dispatchFile.getDocId());
         return Result.OK(docInfo);
     }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/entity/AssignEquipmentFileStream.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,133 @@
package org.jeecg.modules.dncFlow.entity;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.jeecg.common.aspect.annotation.Dict;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
 * @Description:
 * @Author: jeecg-boot
 * @Date:   2025-06-17
 * @Version: V1.0
 */
@Data
@TableName("nc_assign_equipment_file_stream")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@ApiModel(value="nc_assign_equipment_file_stream对象", description="DNC-设备结构树指派产品结构树")
public class AssignEquipmentFileStream implements Serializable {
    private static final long serialVersionUID = 1L;
    /**主键*/
    @TableId(type = IdType.ASSIGN_ID)
    @ApiModelProperty(value = "主键")
    private String id;
    /**设备ID*/
    @Excel(name = "设备ID", width = 15)
    @ApiModelProperty(value = "设备ID")
    @Dict(dictTable = "mdc_equipment", dicCode = "id", dicText = "equipment_id")
    private String equipmentId;
    /**设备文档ID*/
    @Excel(name = "设备文档ID", width = 15)
    @ApiModelProperty(value = "设备文档ID")
    @Dict(dictTable = "nc_doc_info", dicCode = "doc_id", dicText = "doc_name")
    private String equipmentDocId;
    /**设备文件ID*/
    @Excel(name = "设备文件ID", width = 15)
    @ApiModelProperty(value = "设备文件ID")
    private String equipmentFileId;
    /**产品ID*/
    @Excel(name = "产品ID", width = 15)
    @ApiModelProperty(value = "产品ID")
    @Dict(dictTable = "nc_product_info", dicCode = "product_id", dicText = "product_name")
    private String productId;
    /**部件ID*/
    @Excel(name = "部件ID", width = 15)
    @ApiModelProperty(value = "部件ID")
    @Dict(dictTable = "nc_component_info", dicCode = "component_id", dicText = "component_name")
    private String componentId;
    /**零件ID*/
    @Excel(name = "零件ID", width = 15)
    @ApiModelProperty(value = "零件ID")
    @Dict(dictTable = "nc_parts_info", dicCode = "parts_id", dicText = "parts_name")
    private String partsId;
    /**工艺规程版本ID*/
    @Excel(name = "工艺规程版本ID", width = 15)
    @ApiModelProperty(value = "工艺规程版本ID")
    @Dict(dictTable = "nc_process_spec_version", dicCode = "id", dicText = "process_spec_version_name")
    private String psvId;
    /**工序ID*/
    @Excel(name = "工序ID", width = 15)
    @ApiModelProperty(value = "工序ID")
    @Dict(dictTable = "nc_process_stream", dicCode = "process_id", dicText = "process_name")
    private String processId;
    /**工步ID*/
    @Excel(name = "工步ID", width = 15)
    @ApiModelProperty(value = "工步ID")
    @Dict(dictTable = "nc_work_step", dicCode = "id", dicText = "step_name")
    private String stepId;
    /**设备类ID*/
    @Excel(name = "设备类ID", width = 15)
    @ApiModelProperty(value = "设备类ID")
    private String deviceTypeId;
    /**产品文档id*/
    @Excel(name = "产品文档id", width = 15)
    @ApiModelProperty(value = "产品文档id")
    @Dict(dictTable = "nc_doc_info", dicCode = "doc_id", dicText = "doc_name")
    private String docId;
    /**指派原因*/
    @Excel(name = "指派原因", width = 15)
    @ApiModelProperty(value = "指派原因")
    private String applyReason;
    /**审核类型*/
    @Excel(name = "审核类型", width = 15)
    @ApiModelProperty(value = "审核类型")
    private String auditType;
    /**审核意见*/
    @Excel(name = "审核意见", width = 15)
    @ApiModelProperty(value = "审核意见")
    private String auditReason;
    /**创建人*/
    @ApiModelProperty(value = "创建人")
    private String createBy;
    /**创建日期*/
    @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    @ApiModelProperty(value = "创建日期")
    private Date createTime;
    /**更新人*/
    @ApiModelProperty(value = "更新人")
    private String updateBy;
    /**更新日期*/
    @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    @ApiModelProperty(value = "更新日期")
    private Date updateTime;
    /**所属部门*/
    @ApiModelProperty(value = "所属部门")
    private String sysOrgCode;
    /**设备类名称*/
    private transient String deviceTypeName;
    /**产品文件名称*/
    private transient String docName;
    /**所属id*/
    private transient String attributionId;
    /**所属type*/
    private transient String attributionType;
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/mapper/AssignEquipmentFileStreamMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
package org.jeecg.modules.dncFlow.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.dncFlow.entity.AssignEquipmentFileStream;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
 * @Description: DNC-设备结构树指派产品结构树
 * @Author: jeecg-boot
 * @Date:   2025-06-17
 * @Version: V1.0
 */
public interface AssignEquipmentFileStreamMapper extends BaseMapper<AssignEquipmentFileStream> {
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/mapper/xml/AssignEquipmentFileStreamMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.modules.dncFlow.mapper.AssignEquipmentFileStreamMapper">
</mapper>
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/service/IAssignEquipmentFileStreamService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,30 @@
package org.jeecg.modules.dncFlow.service;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.dncFlow.entity.AssignEquipmentFileStream;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.dncFlow.vo.AssignEquipmentFileStreamVo;
/**
 * @Description: DNC-设备结构树指派产品结构树
 * @Author: jeecg-boot
 * @Date:   2025-06-17
 * @Version: V1.0
 */
public interface IAssignEquipmentFileStreamService extends IService<AssignEquipmentFileStream> {
    /**
     * æµç¨‹å¯åЍ,保存对应的数据
     * @param assignEquipmentFileStream
     * @return
     */
    Result<?> saveAssignEquipmentFileStream(AssignEquipmentFileStream assignEquipmentFileStream);
    /**
     * æµç¨‹èŠ‚ç‚¹å®¡æ ¸
     * @param assignEquipmentFileStreamVo
     * @return
     */
    Result<?> auditAssignEquipmentFileStream(AssignEquipmentFileStreamVo assignEquipmentFileStreamVo);
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/service/IDispatchFileService.java
@@ -2,6 +2,7 @@
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.dnc.entity.DocInfo;
import org.jeecg.modules.dncFlow.entity.DispatchFile;
import org.jeecg.modules.dncFlow.vo.DispatchFileFlowTaskVo;
@@ -53,5 +54,8 @@
     * @param id
     */
    Result<?> queryDispatchFile(String id);
    /**
     * å®šåž‹æµç¨‹
     */
    Result<?> submitProccess(DispatchFile dispatchFile);
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/service/impl/AssignEquipmentFileStreamServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,316 @@
package org.jeecg.modules.dncFlow.service.impl;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.dnc.constant.DncPassLogPassType;
import org.jeecg.modules.dnc.constant.DocAttributionTypeEnum;
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.response.ActivitiCode;
import org.jeecg.modules.dnc.response.CommonCode;
import org.jeecg.modules.dnc.response.DocumentCode;
import org.jeecg.modules.dnc.response.UcenterCode;
import org.jeecg.modules.dnc.service.*;
import org.jeecg.modules.dnc.service.impl.FileFerryService;
import org.jeecg.modules.dnc.utils.ValidateUtil;
import org.jeecg.modules.dnc.utils.date.DateUtil;
import org.jeecg.modules.dnc.utils.file.FileUtilS;
import org.jeecg.modules.dncFlow.constant.GuideCardBatchEnum;
import org.jeecg.modules.dncFlow.entity.AssignEquipmentFileStream;
import org.jeecg.modules.dncFlow.entity.DispatchFile;
import org.jeecg.modules.dncFlow.mapper.AssignEquipmentFileStreamMapper;
import org.jeecg.modules.dncFlow.service.IAssignEquipmentFileStreamService;
import org.jeecg.modules.dncFlow.vo.AssignEquipmentFileStreamVo;
import org.jeecg.modules.flowable.apithird.business.entity.FlowMyBusiness;
import org.jeecg.modules.flowable.apithird.business.service.IFlowMyBusinessService;
import org.jeecg.modules.flowable.apithird.service.FlowCallBackServiceI;
import org.jeecg.modules.flowable.apithird.service.FlowCommonService;
import org.jeecg.modules.flowable.service.IFlowDefinitionService;
import org.jeecg.modules.flowable.service.IFlowTaskService;
import org.jeecg.modules.mdc.entity.MdcEquipment;
import org.jeecg.modules.mdc.service.IMdcEquipmentService;
import org.jeecg.modules.system.service.IMdcProductionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.NoTransactionException;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import javax.annotation.Resource;
import java.io.File;
import java.util.*;
/**
 * @Description: DNC-设备结构树指派产品结构树
 * @Author: jeecg-boot
 * @Date:   2025-06-17
 * @Version: V1.0
 */
@Service("IAssignEquipmentFileStreamService")
public class AssignEquipmentFileStreamServiceImpl extends ServiceImpl<AssignEquipmentFileStreamMapper, AssignEquipmentFileStream> implements IAssignEquipmentFileStreamService , FlowCallBackServiceI {
    @Autowired
    private IDocInfoService docInfoService;
    @Autowired
    private IDocFileService docFileService;
    @Autowired
    private IMdcEquipmentService mdcEquipmentService;
    @Autowired
    private IGuideCardBatchService iGuideCardBatchService;
    @Resource
    private FlowCommonService flowCommonService;
    @Resource
    private IFlowDefinitionService flowDefinitionService;
    @Autowired
    private IFlowTaskService flowTaskService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private IFlowMyBusinessService flowMyBusinessService;
    @Autowired
    private IDocRelativeService docRelativeService;
    @Autowired
    private IDeviceTypeService deviceTypeService;
    @Autowired
    private PermissionService permissionService;
    /**
     * æµç¨‹å¯åЍ,保存对应的数据
     * @param assignEquipmentFileStream
     * @return
     */
    @Override
    public Result<?> saveAssignEquipmentFileStream(AssignEquipmentFileStream assignEquipmentFileStream){
        //参数校验
        checkParam(assignEquipmentFileStream);
        //获取设备
        MdcEquipment equipment = mdcEquipmentService.getById(assignEquipmentFileStream.getEquipmentId());
        if(equipment==null){
            return Result.error("未发现该设备");
        }
        //获取设备文档信息
        DocInfo docInfo =docInfoService.getById(assignEquipmentFileStream.getEquipmentDocId());
        if(docInfo==null){
            return Result.error("未发现该设备对应文档");
        }
        //获取设备文件信息
        DocFile docFile =docFileService.getById(assignEquipmentFileStream.getEquipmentFileId());
        if(docFile==null){
            return Result.error("未发现该设备对应文件");
        }
        //获取产品文档信息
        DocRelative docRelative=docRelativeService.getById(assignEquipmentFileStream.getDocId());
        //获取对应设备类
        DeviceType deviceType = deviceTypeService.getById(docRelative.getAttributionId());
        if(deviceType!=null){
            assignEquipmentFileStream.setDeviceTypeId(deviceType.getId());
            assignEquipmentFileStream.setAttributionId(deviceType.getAttributionId());
            assignEquipmentFileStream.setAttributionType(deviceType.getAttributionType().toString());
            PermissionStreamNew permissionStreamNew=permissionService.getPermissionStreams(assignEquipmentFileStream);
            if(permissionStreamNew==null){
                return Result.error("用户无权操作此任务");
            }
        }
        DocInfo productDocInfo =docInfoService.getById(docRelative.getDocId());
        if(productDocInfo==null){
            return Result.error("未发现该产品结构树对应文档");
        }
        //获取产品文档信息对应最新程序加工确认表
        List<GuideCardBatch> batches = iGuideCardBatchService.list(
                new QueryWrapper<GuideCardBatch>()
                        .eq("doc_id", productDocInfo.getDocId())
                        .eq("flow_status", GuideCardBatchEnum.COMPLETE.getCode())
                        .orderByDesc("SUBSTRING(serial_number, LEN(serial_number)-3, 4)"));
        if(CollectionUtils.isEmpty(batches)){
            return Result.error("该文档对应的程序加工确认表审批未通过,不能进行升版");
        }
        this.save(assignEquipmentFileStream);
        System.out.println("设备结构树指派产品结构树:" + assignEquipmentFileStream.getId());
        flowCommonService.initActBusiness("设备结构树指派产品结构树:"+docInfo.getDocName()+"->"+productDocInfo.getDocName(),
                assignEquipmentFileStream.getId(), "IAssignEquipmentFileStreamService", "nc_assign_equipment_file_stream", null);
        Map<String, Object> variables = new HashMap<>();
        variables.put("dataId", assignEquipmentFileStream.getId());
        variables.put("organization", assignEquipmentFileStream.getApplyReason());
        variables.put("comment", assignEquipmentFileStream.getApplyReason());
        variables.put("proofreading",true);
        Result result= flowDefinitionService.startProcessInstanceByKey("nc_assign_equipment_file_stream", variables);
        if (!result.isSuccess()) {
            super.removeById(assignEquipmentFileStream.getId());
        }
        return result;
    }
    /**
     * æµç¨‹èŠ‚ç‚¹å®¡æ ¸
     * @param assignEquipmentFileStreamVo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<?> auditAssignEquipmentFileStream(AssignEquipmentFileStreamVo assignEquipmentFileStreamVo){
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        try {
            // å‚数校验
            if (!ValidateUtil.validateString(assignEquipmentFileStreamVo.getTaskId()) || !ValidateUtil.validateString(assignEquipmentFileStreamVo.getDataId())) {
                return Result.error(CommonCode.INVALID_PARAM.toString());
            }
            String userId = user.getId();
            assignEquipmentFileStreamVo.setAssignee(user.getUsername());
            if (!ValidateUtil.validateString(userId)) {
                return Result.error(UcenterCode.UCENTER_ACCOUNT_NOT_EXIST.toString());
            }
            // æ•°æ®æŸ¥è¯¢
            AssignEquipmentFileStream assignEquipmentFileStream = this.getById(assignEquipmentFileStreamVo.getDataId());
            if (assignEquipmentFileStream == null) {
                return Result.error(CommonCode.INVALID_PARAM.toString());
            }
            //获取设备
            MdcEquipment equipment = mdcEquipmentService.getById(assignEquipmentFileStream.getEquipmentId());
            if(equipment==null){
                return Result.error("未发现该设备");
            }
            //获取设备文档信息
            DocInfo docInfo =docInfoService.getById(assignEquipmentFileStream.getEquipmentDocId());
            if(docInfo==null){
                return Result.error("未发现该设备对应文档");
            }
            //获取设备文件信息
            DocFile docFile =docFileService.getById(assignEquipmentFileStream.getEquipmentFileId());
            if(docFile==null){
                return Result.error("未发现该设备对应文件");
            }
            //获取产品文档信息
            DocRelative docRelative=docRelativeService.getById(assignEquipmentFileStream.getDocId());
            DocInfo productDocInfo =docInfoService.getById(docRelative.getDocId());
            if(productDocInfo==null){
                return Result.error("未发现该产品结构树对应文档");
            }
            //获取设备
            MdcEquipment mdcEquipment =mdcEquipmentService.getById(assignEquipmentFileStream.getEquipmentId());
            if (mdcEquipment==null){
                return Result.error("未发现该设备");
            }
            // 2. æŸ¥è¯¢æµç¨‹ä¸šåŠ¡è®°å½•ï¼ˆå¤„ç†ç©ºç»“æžœï¼‰
            List<FlowMyBusiness> businessList = flowMyBusinessService.list(
                    new QueryWrapper<FlowMyBusiness>()
                            .eq("process_instance_id", assignEquipmentFileStreamVo.getInstanceId())
            );
            if (businessList.isEmpty()) {
                return Result.error("流程记录不存在");
            }
            FlowMyBusiness flowMyBusiness = businessList.get(0);
            // 3. æ ¡éªŒç”¨æˆ·æ˜¯å¦ä¸ºå€™é€‰å¤„理人
            List<String> todoUsers = JSON.parseArray(flowMyBusiness.getTodoUsers(), String.class);
            if (todoUsers == null || !todoUsers.contains(user.getUsername())) {
                return Result.error("用户无权操作此任务");
            }
            // 4. è®¤é¢†ä»»åŠ¡ï¼ˆå¤„ç†å·²è¢«è®¤é¢†çš„æƒ…å†µï¼‰
            String taskId = flowMyBusiness.getTaskId();
            Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
            if (task == null) {
                return Result.error("任务不存在或已完成");
            }
            if (task.getAssignee() != null && !task.getAssignee().equals(user.getUsername())) {
                return Result.error("任务已被他人认领");
            }
            taskService.claim(taskId, user.getUsername());
            // è®¾ç½®æµç¨‹å˜é‡
            Map<String, Object> values = new HashMap<>();
            values.put("dataId", assignEquipmentFileStream.getId());
            values.put("assignee", userId);
            values.put("comment", assignEquipmentFileStreamVo.getComment());
            values.put("organization", assignEquipmentFileStreamVo.getComment());
            assignEquipmentFileStreamVo.setValues(values);
            // å®Œæˆæµç¨‹ä»»åŠ¡
            Result result = flowTaskService.complete(assignEquipmentFileStreamVo);
            if (result.isSuccess()) {
                this.updateById(assignEquipmentFileStream);
                if (assignEquipmentFileStreamVo.getAuditType().equals("1")) {
                    //1.产品结构树nc文件进行升版
                    DocFile productDocFile = new DocFile();
                    productDocFile.setDocId(productDocInfo.getDocId());
                    productDocFile.setFileName(docFile.getFileName());
                    productDocFile.setFileEncodeName(docFile.getFileEncodeName());
                    productDocFile.setFilePath(docFile.getFilePath());
                    productDocFile.setFileSize(docFile.getFileSize());
                    productDocFile.setFileSuffix(docFile.getFileSuffix());
                    docFileService.addDocFile(productDocFile);
                    productDocInfo.setPublishVersion(productDocFile.getDocVersion());
                    productDocInfo.setPublishFileId(productDocFile.getFileId());
                    docInfoService.updateById(productDocInfo);
                }
            } else {
                return result;
            }
            return Result.OK("操作成功");
        }  catch (Exception e) {
            try {
                TransactionStatus transactionStatus = TransactionAspectSupport.currentTransactionStatus();
                if (!transactionStatus.isCompleted()) {
                    transactionStatus.setRollbackOnly();
                }
            } catch (NoTransactionException ex) {
                // å¿½ç•¥æ— äº‹åŠ¡çš„å¼‚å¸¸
            }
            log.error("审核失败", e);
            return Result.error("操作失败:" + e.getMessage());
        }
    }
    //传参验证
    public boolean checkParam(AssignEquipmentFileStream assignEquipmentFileStream) {
        if (assignEquipmentFileStream == null) {
            ExceptionCast.cast(CommonCode.INVALID_PARAM);
        }
        if (!ValidateUtil.validateString(assignEquipmentFileStream.getEquipmentId()) || !ValidateUtil.validateString(assignEquipmentFileStream.getDocId())
                || !ValidateUtil.validateString(assignEquipmentFileStream.getEquipmentFileId()) || !ValidateUtil.validateString(assignEquipmentFileStream.getEquipmentDocId())) {
            ExceptionCast.cast(CommonCode.INVALID_PARAM);
        }
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        String userId = user.getId();
        if (!ValidateUtil.validateString(userId)) {
            ExceptionCast.cast(UcenterCode.UCENTER_ACCOUNT_NOT_EXIST);
        }
        return true;
    }
    @Override
    public void afterFlowHandle(FlowMyBusiness business) {
        business.getTaskNameId();//接下来审批的节点
        business.getValues();//前端传进来的参数
        business.getActStatus();
    }
    @Override
    public Object getBusinessDataById(String dataId) {
        return this.getById(dataId);
    }
    @Override
    public Map<String, Object> flowValuesOfTask(String taskNameId, Map<String, Object> values) {
        return null;
    }
    @Override
    public List<String> flowCandidateUsernamesOfTask(String taskNameId, Map<String, Object> values) {
        //业务是否干预流程,业务干预,流程干预,指定人员进行处理
        return null;
    }
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/service/impl/DispatchFileServiceImpl.java
@@ -13,16 +13,21 @@
import org.flowable.task.api.Task;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.dnc.entity.DocInfo;
import org.jeecg.modules.dnc.entity.PermissionStreamNew;
import org.jeecg.modules.dnc.constant.DncPassLogPassType;
import org.jeecg.modules.dnc.constant.DocAttributionTypeEnum;
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.DocInfoMapper;
import org.jeecg.modules.dnc.request.DocInfoQueryRequest;
import org.jeecg.modules.dnc.response.ActivitiCode;
import org.jeecg.modules.dnc.response.CommonCode;
import org.jeecg.modules.dnc.response.UcenterCode;
import org.jeecg.modules.dnc.service.IDocInfoService;
import org.jeecg.modules.dnc.service.*;
import org.jeecg.modules.dnc.service.impl.FileFerryService;
import org.jeecg.modules.dnc.utils.ValidateUtil;
import org.jeecg.modules.dnc.utils.date.DateUtil;
import org.jeecg.modules.dnc.utils.file.FileUtilS;
import org.jeecg.modules.dncFlow.entity.DispatchFile;
import org.jeecg.modules.dncFlow.mapper.DispatchFileMapper;
import org.jeecg.modules.dncFlow.service.IDispatchFileService;
@@ -35,14 +40,23 @@
import org.jeecg.modules.flowable.service.IFlowDefinitionService;
import org.jeecg.modules.flowable.service.IFlowTaskService;
import org.jeecg.modules.flowable.service.IHisWorkTaskService;
import org.jeecg.modules.mdc.entity.MdcEquipment;
import org.jeecg.modules.system.service.IMdcProductionService;
import org.jeecg.modules.system.service.ISysUserRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.*;
/**
@@ -68,13 +82,29 @@
    @Autowired
    private IFlowMyBusinessService flowMyBusinessService;
    @Autowired
    private DocInfoMapper docInfoMapper;
    @Autowired
    private ISysUserRoleService sysUserRoleService;
    @Autowired
    private PermissionService permissionService;
    @Autowired
    private IHisWorkTaskService hisWorkTaskService;
    @Autowired
    private IDeviceTypeService deviceTypeService;
    @Autowired
    private IDeviceManagementService deviceManagementService;
    @Autowired
    private IDncPassLogService dncPassLogService;
    @Autowired
    private IDocFileService docFileService;
    @Autowired
    private IDocRelativeService docRelativeService;
    @Autowired
    @Lazy
    private FileFerryService ferryService;
    @Value("${deploy.secretFolder}")
    private String secretFolder;    //工控网传输nc文件夹
    @Value("${fileHomePath}")
    private String fileHomePath;
    /**
     * æµç¨‹å¯åЍ,保存对应的数据
     * @param dispatchFile
@@ -374,6 +404,31 @@
        List<DocInfo> docInfoList = docInfoService.findList(docInfoQueryRequest);
        return Result.OK(docInfoList);
    }
    /**
     * å‘起定型流程
     */
    @Override
    public Result<?> submitProccess(DispatchFile dispatchFile) {
        checkParam(dispatchFile);
        //获取文件信息
        DocInfo docInfo = docInfoService.getById(dispatchFile.getDocId());
        PermissionStreamNew permissionStreams = getPermissionStreams(dispatchFile);
        if (permissionStreams==null){
            return Result.error("用户没有权限");
        }
        super.save(dispatchFile);
        flowCommonService.initActBusiness(docInfo.getDocName()+"."+docInfo.getDocSuffix()+"文件进行定型",
                dispatchFile.getId(), "IDispatchFileService", "process_rf27duhy", null);
        Map<String, Object> variables = new HashMap<>();
        variables.put("dataId", dispatchFile.getId());
        variables.put("organization", "导入文档默认启动流程");
        variables.put("comment", "导入文档默认启动流程");
        variables.put("proofreading",true);
        Result result= flowDefinitionService.startProcessInstanceByKey("process_rf27duhy", variables);
        if (!result.isSuccess())
            super.removeById(dispatchFile.getId());
        return result;
    }
    private Map<String, Object> setProcessVariables(DispatchFile dispatchFile, String userId, DispatchFileFlowTaskVo dispatchFileFlowTaskVo) {
        Map<String, Object> values = new HashMap<>();
@@ -396,7 +451,7 @@
        return values;
    }
    private void updateStatus(DispatchFile dispatchFile, DocInfo docInfo, DispatchFileFlowTaskVo dispatchFileFlowTaskVo) {
    private void updateStatus(DispatchFile dispatchFile, DocInfo docInfo, DispatchFileFlowTaskVo dispatchFileFlowTaskVo) throws IOException {
        if (StrUtil.isNotBlank(dispatchFileFlowTaskVo.getProofreadStatus())) {
            switch (dispatchFileFlowTaskVo.getProofreadStatus()) {
                case "1":
@@ -427,9 +482,95 @@
        if (dispatchFileFlowTaskVo.getStereotype() != null && dispatchFileFlowTaskVo.getStereotype()) {
            dispatchFile.setCurrentNode("5");
            docInfo.setDocDispatchStatus(5);
            //定型通过
            DeviceType deviceType=deviceTypeService.getById(dispatchFile.getDeviceTypeId());
            DeviceManagement deviceManagement=deviceManagementService.getById(deviceType.getDeviceManagementId());
            DocFile docFile=docFileService.getById(dispatchFile.getFileId());
            DocRelative docRelative=docRelativeService.getOne(new QueryWrapper<DocRelative>().eq("doc_id",docInfo.getDocId())
                    .eq("attribution_id",dispatchFile.getAttributionId()).eq("attribution_type",dispatchFile.getAttributionType()));
            handleFileProcessing(docFile,deviceManagement,secretFolder);
            handleProductTree(docInfo,docRelative,deviceManagement);
        }
    }
    //封装处理文件
    private void handleFileProcessing(DocFile docFile, DeviceManagement deviceManagement, String secretFolder) throws IOException {
        if (!docFile.getFileSuffix().equals("zip") && !docFile.getFileSuffix().equals("rar")) {
            DncPassLog passInfoTxt = new DncPassLog();
            Date dateFirst = DateUtil.getNow();
            passInfoTxt.setDayTime(DateUtil.format(dateFirst,DateUtil.STR_YEARMONTHDAY));
            /*查询最后一条记录*/
            //休眠 500毫秒
            DncPassLog dncPassLog  = dncPassLogService.findDayTime(DateUtil.format(dateFirst,DateUtil.STR_YEARMONTHDAY));
            int fileNc =0;
            if (dncPassLog !=null) {
                fileNc = dncPassLog.getSequenceNumber() + 1;
            } else {
                fileNc =  1;
            }
            //处理文件名称  æ–‡ä»¶è·¯å¾„
            String sequenceNc = String.format("%06d",fileNc);
            DncPassLog passInfoNc = new DncPassLog();
            passInfoNc.setSequenceNumber(fileNc);
            passInfoNc.setSequenceOrder(sequenceNc);
            passInfoNc.setDayTime(DateUtil.format(dateFirst,DateUtil.STR_YEARMONTHDAY));
            passInfoNc.setPassType(DncPassLogPassType.NCFILE.getCode());
            passInfoNc.setPassName(docFile.getFileName());
            try {
                Thread.sleep(1000);
                Date date = new Date();
                passInfoNc.setCreateTime(date);
                System.out.println(DateUtil.format(date,DateUtil.STR_DATE_TIME));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            dncPassLogService.save(passInfoNc);
            // 4. æ‰§è¡Œæ–‡ä»¶æ“ä½œ,后缀为NC
            Path source = Paths.get(fileHomePath+docFile.getFilePath(), docFile.getFileEncodeName());
            String destFileName = "10A" + DateUtil.format(dateFirst,DateUtil.STR_YEARMONTHDAY)+sequenceNc + "_" + deviceManagement.getDeviceManagementCode()+".NC";
            Path destination = Paths.get(secretFolder, destFileName);
            Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING);
        }
    }
    /**
     * å¤„理对应产品结构树、nc文件、刀具列表、程序加工确认表封装
     * @param docInfo
     */
    private void handleProductTree(DocInfo docInfo, DocRelative docRelative, DeviceManagement deviceManagement) {
        /*查询最后一条记录*/
        //休眠 500毫秒
        DncPassLog passInfoTxt = new DncPassLog();
        Date dateFirst = DateUtil.getNow();
        passInfoTxt.setDayTime(DateUtil.format(dateFirst,DateUtil.STR_YEARMONTHDAY));
        DncPassLog dncPassLog  = dncPassLogService.findDayTime(DateUtil.format(dateFirst,DateUtil.STR_YEARMONTHDAY));
        int fileTxt = 0, fileNc =0;
        if (dncPassLog !=null) {
            fileTxt = dncPassLog.getSequenceNumber() + 1;
        } else {
            fileTxt =  1;
        }
        String sequence = String.format("%06d",fileTxt);
        passInfoTxt.setSequenceNumber(fileTxt);
        passInfoTxt.setCreateTime(dateFirst);
        passInfoTxt.setSequenceOrder(sequence);
        System.out.println(DateUtil.format(dateFirst,DateUtil.STR_DATE_TIME));
        passInfoTxt.setPassType(DncPassLogPassType.PRODUCTSTRUCTURE.getCode());
        dncPassLogService.save(passInfoTxt);
        String fileName="10A"+DateUtil.format(dateFirst,DateUtil.STR_YEARMONTHDAY);
        if (Objects.equals(docInfo.getAttributionType(), DocAttributionTypeEnum.PROCESS.getCode())){
            //工序对应设备类
            String filePath = ferryService.exportData(TransferPackage.DataType.PROCESS, docRelative.getId(),fileName+sequence+"_"+deviceManagement.getDeviceManagementCode()+".ferry");
            System.out.println("工序数据已导出: " + filePath);
        }else {
            //工步对应设备类
            String filePath = ferryService.exportData(TransferPackage.DataType.WORKSTEP, docRelative.getId(),fileName+sequence+"_"+deviceManagement.getDeviceManagementCode()+".ferry");
            System.out.println("工步数据已导出: " + filePath);
        }
    }
    //传参验证
    public boolean checkParam(DispatchFile dispatchFile) {
        if (dispatchFile == null) {
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/service/impl/PermissionService.java
@@ -7,8 +7,10 @@
import org.jeecg.modules.dnc.exception.ExceptionCast;
import org.jeecg.modules.dnc.response.ActivitiCode;
import org.jeecg.modules.dnc.service.IDeviceTypeService;
import org.jeecg.modules.dncFlow.adapter.AssignEquipmentFileStreamAdapter;
import org.jeecg.modules.dncFlow.adapter.AssignFileStreamAdapter;
import org.jeecg.modules.dncFlow.adapter.DispatchFileAdapter;
import org.jeecg.modules.dncFlow.entity.AssignEquipmentFileStream;
import org.jeecg.modules.dncFlow.entity.AssignFileStream;
import org.jeecg.modules.dncFlow.entity.DispatchFile;
import org.jeecg.modules.dncFlow.handler.*;
@@ -51,6 +53,10 @@
        return processInternal(new AssignFileStreamAdapter(stream), stream.getAttributionType());
    }
    public PermissionStreamNew getPermissionStreams(AssignEquipmentFileStream stream) {
        return processInternal(new AssignEquipmentFileStreamAdapter(stream), stream.getAttributionType());
    }
    private PermissionStreamNew processInternal(StreamTarget target, String attributionType) {
        LoginUser user = getCurrentUser();
        String resolvedId = resolveAttributionId(target.getAttributionId());
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/vo/AssignEquipmentFileStreamVo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
package org.jeecg.modules.dncFlow.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.jeecg.modules.flowable.domain.vo.FlowTaskVo;
import org.jeecgframework.poi.excel.annotation.Excel;
/**
 * @Description: DNC-设备结构树指派产品结构树
 * @Author: jeecg-boot
 * @Date:   2025-06-17
 * @Version: V1.0
 */
@Data
@ApiModel(value="设备结构树指派产品结构树--请求参数")
public class AssignEquipmentFileStreamVo extends FlowTaskVo {
    /**
     * taskIds
     */
    private String taskIds;
    /**审核类型*/
    @Excel(name = "审核类型", width = 15)
    @ApiModelProperty(value = "审核类型")
    private String auditType;
}
lxzn-module-dnc/src/main/java/org/jeecg/modules/dncFlow/vo/GuideCardBatchFlowTaskVo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,38 @@
package org.jeecg.modules.dncFlow.vo;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import org.jeecg.modules.flowable.domain.vo.FlowTaskVo;
@Data
@ApiModel("程序加工确认表工作流任务相关--请求参数")
public class GuideCardBatchFlowTaskVo extends FlowTaskVo {
    /**
     * taskIds
     */
    private String taskIds;
    /**
     * æ ¡å¯¹ç±»åž‹
     * true:校对通过
     * false:校对不通过
     */
    private Boolean checkType;
    /**
     * ç¡®è®¤ç±»åž‹
     * true:确认通过
     * false:确认不通过
     */
    private Boolean confirmType;
    /**
     * å®¡æ‰¹ç±»åž‹
     * true:审批通过
     * false:审批不通过
     */
    private Boolean approveType;
    /**首检意见*/
    private String inspectionOpinion;
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/job/ExportToXmlJob.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,63 @@
package org.jeecg.modules.mdc.job;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.mdc.service.ILogTableService;
import org.jeecg.modules.mdc.util.ThrowableUtil;
import org.jeecg.modules.quartz.entity.QuartzJob;
import org.jeecg.modules.quartz.entity.SysQuartzLog;
import org.jeecg.modules.quartz.service.IQuartzJobService;
import org.jeecg.modules.quartz.service.ISysQuartzLogService;
import org.jeecg.modules.system.service.ISysAnnouncementService;
import org.quartz.*;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
/**
 * å¯¼å‡ºsql记录到xml文件任务
 * @author Lius
 * @date 2024/12/18 14:53
 */
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
@Slf4j
public class ExportToXmlJob implements Job {
    @Resource
    private ISysQuartzLogService sysQuartzLogService;
    @Resource
    private IQuartzJobService quartzJobService;
    @Resource
    private ISysAnnouncementService sysAnnouncementService;
    @Resource
    private ILogTableService logTableService;
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        SysQuartzLog quartzLog = new SysQuartzLog();
        quartzLog.setCreateTime(new Date());
        List<QuartzJob> byJobClassName = this.quartzJobService.findByJobClassName(this.getClass().getName());
        if (byJobClassName != null && !byJobClassName.isEmpty()) {
            quartzLog.setJobId(byJobClassName.get(0).getId());
        }
        log.info("定时导出同步数据表sql任务 ExportToXmlJob start!  æ—¶é—´:" + DateUtils.now());
        long startTime = System.currentTimeMillis();
        try {
            logTableService.exportDataToXml();
            quartzLog.setIsSuccess(0);
        } catch (Exception e) {
            quartzLog.setIsSuccess(-1);
            quartzLog.setExceptionDetail(ThrowableUtil.getStackTrace(e));
            // å‘送消息通知
            sysAnnouncementService.jobSendMessage("定时导出同步数据表sql任务", quartzLog.getExceptionDetail());
        }
        long endTime = System.currentTimeMillis();
        quartzLog.setExecutionTime(Integer.parseInt(String.valueOf(endTime - startTime)));
        sysQuartzLogService.save(quartzLog);
    }
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/ILogTableService.java
@@ -10,8 +10,8 @@
public interface ILogTableService extends IService<LogTable> {
    /**
     * å¯¼å…¥åŒæ­¥æ•°æ®sql执行到数据库
     * å¯¼å‡ºåŒæ­¥æ•°æ®è¡¨sql到xml文件上传到网闸服务器
     */
    void importXmlToData();
    void exportDataToXml();
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IMdcPassLogService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
package org.jeecg.modules.mdc.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.system.entity.MdcPassLog;
/**
 * @author Lius
 * @date 2024/12/23 15:00
 */
public interface IMdcPassLogService extends IService<MdcPassLog> {
    /**
     * æŸ¥è¯¢ä»Šæ—¥æœ€æ–°ä¸€æ¡ä¼ è¾“日志
     *
     * @param date
     * @return
     */
    MdcPassLog selectTodayLast(String date);
}
lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/LogTableServiceImpl.java
@@ -1,22 +1,25 @@
package org.jeecg.modules.mdc.service.impl;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileReader;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.modules.mdc.entity.LogTable;
import org.jeecg.modules.mdc.mapper.LogTableMapper;
import org.jeecg.modules.mdc.service.ILogTableService;
import org.jeecg.modules.mdc.util.SqlExecutor;
import org.jeecg.modules.mdc.util.DateUtils;
import org.jeecg.modules.system.entity.MdcPassLog;
import org.jeecg.modules.system.service.IMdcPassLogService;
import org.jeecg.modules.system.util.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
 * @author Lius
@@ -29,52 +32,65 @@
    @Value("${fileService.localFilePath}")
    private String localFilePath;
    @Value("${fileService.newFilePath}")
    private String newFilePath;
    @Value("${fileService.failedLocFilePath}")
    private String failedLocFilePath;
    @Resource
    private SqlExecutor sqlExecutor;
    private IMdcPassLogService mdcPassLogService;
    private static final String TYPE = "18";
    /**
     * å¯¼å…¥åŒæ­¥æ•°æ®sql执行到数据库
     * å¯¼å‡ºåŒæ­¥æ•°æ®è¡¨sql到xml文件
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importXmlToData() {
        File[] files = FileUtil.ls(localFilePath);
        List<String> failedSqlList = new ArrayList<>(); // ç”¨äºŽå­˜å‚¨æ‰§è¡Œå¤±è´¥çš„ SQL
        for (File file : files) {
            if (file.isFile()) {
                String loFilePath = localFilePath + file.getName();
                FileReader fileReader = new FileReader(loFilePath);
                List<String> sqlList = fileReader.readLines();
                log.info("成功读取到{}条sql,执行操作", sqlList.size());
                for (String sql : sqlList) {
                    try {
                        sqlExecutor.execute(sql);
                    } catch (Exception e) {
                        failedSqlList.add(sql);
                    }
                }
                if (!failedSqlList.isEmpty()) {
                    try {
                        FileUtil.appendLines(failedSqlList, failedLocFilePath, "UTF-8");
                    } catch (Exception e) {
                        throw new JeecgBootException("数据写入文件失败!");
                    }
                }
    public void exportDataToXml() {
        // step.1 æŸ¥è¯¢æœ€æ–°æ•°æ® æ—¶é—´æ­£åºæŽ’列
        List<LogTable> logTables = this.baseMapper.selectList(new LambdaQueryWrapper<LogTable>().orderByAsc(LogTable::getCreateTime));
        if (logTables != null && !logTables.isEmpty()) {
                if (Integer.parseInt(file.getName().substring(file.getName().length() - 10, file.getName().length() - 4)) == 1) {
                    // åˆ é™¤åŽ†å²æ–‡ä»¶
                    FileUtil.clean(newFilePath);
                }
            // step.2 å¤„理数据
            List<String> sqlList = logTables.stream().map(LogTable::getSqlLog).collect(Collectors.toList());
                // å¤‡ä»½
                FileUtil.move(new File(loFilePath), new File(newFilePath + file.getName()), true);
            // step.3 å†™å…¥æ–‡ä»¶
            // step.3.1 æ–‡ä»¶å‘½å
            String today = DateUtils.format(DateUtils.getNow(), DateUtils.STRDATE);
            MdcPassLog mdcPassLogLast = mdcPassLogService.selectTodayLast(today);
            int sequenceNumber = 1;
            if (mdcPassLogLast != null) {
                sequenceNumber = mdcPassLogLast.getSequenceNumber() + 1;
            }
            // æ–‡ä»¶è·¯å¾„
            String locFilePath = localFilePath + TYPE + today + String.format("%06d", sequenceNumber) + ".xml";
            String listSql = String.join("\n", sqlList);
            try {
                FileUtils.fileWriterSql(locFilePath, listSql);
            } catch (Exception e) {
                throw new JeecgBootException("数据写入文件失败!");
            }
            File[] files = FileUtil.ls(localFilePath);
            for (File file : files) {
                if (file.isFile()) {
                    //顺序号
                    String fileName = file.getName();
                    String sequenceOrder = fileName.substring(fileName.length() - 10, fileName.length() - 4);
                    String dayTime = fileName.substring(fileName.length() - 18, fileName.length() - 10);
                    int sequenceNum = Integer.parseInt(sequenceOrder);
                    // æ’入传输日志
                    MdcPassLog mdcPassLog = new MdcPassLog();
                    mdcPassLog.setPassLogFileName(file.getAbsolutePath());
                    mdcPassLog.setPassName(fileName);
                    mdcPassLog.setDayTime(dayTime);
                    mdcPassLog.setSequenceNumber(sequenceNum);
                    mdcPassLog.setSequenceOrder(sequenceOrder);
                    mdcPassLogService.save(mdcPassLog);
                }
            }
            // step.5 åˆ é™¤å·²ç»å†™å…¥æ–‡ä»¶å¹¶å‘送至网闸的数据
            // step.5.1 åˆ é™¤æ•°æ®åº“数据
            this.baseMapper.delete(new LambdaQueryWrapper<LogTable>().le(LogTable::getCreateTime, logTables.get(logTables.size() - 1).getCreateTime()));
        }
    }
}
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/entity/MdcPassLog.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
package org.jeecg.modules.system.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
 * @author clown
 * * @date 2023/12/12
 */
@Data
@TableName("mdc_pass_log")
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value = "mdc_pass_log对象", description = "发送文件日志表")
public class MdcPassLog implements Serializable {
    private static final long serialVersionUID = -9138730240370211497L;
    @TableId(type = IdType.ASSIGN_ID)
    private String id;
    /**
     * åç§°
     */
    private String passName;
    /**
     * åºå·
     */
    private String sequenceOrder;
    /**
     * æ—¶é—´
     */
    private String dayTime;
    /**
     * ç±»åž‹
     */
    private String passType;
    /**
     * æ–‡ä»¶åç§°
     */
    private String passLogFileName;
    /**
     * é¡ºåºå·
     */
    private Integer sequenceNumber;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    private Date createTime;
}
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/mapper/MdcPassLogMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package org.jeecg.modules.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.system.entity.MdcPassLog;
/**
 * @author Lius
 * @date 2024/12/23 14:59
 */
public interface MdcPassLogMapper extends BaseMapper<MdcPassLog> {
    /**
     * æŸ¥è¯¢ä»Šæ—¥æœ€æ–°ä¸€æ¡ä¼ è¾“日志
     *
     * @param date
     * @return
     */
    MdcPassLog selectTodayLast(@Param("date") String date);
}
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/mapper/xml/MdcPassLogMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.modules.system.mapper.MdcPassLogMapper">
    <select id="selectTodayLast" resultType="org.jeecg.modules.system.entity.MdcPassLog">
        SELECT TOP 1 * FROM mdc_pass_log WHERE day_time = #{date} ORDER BY create_time DESC
    </select>
</mapper>
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/IMdcPassLogService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
package org.jeecg.modules.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.system.entity.MdcPassLog;
/**
 * @author Lius
 * @date 2024/12/23 15:00
 */
public interface IMdcPassLogService extends IService<MdcPassLog> {
    /**
     * æŸ¥è¯¢ä»Šæ—¥æœ€æ–°ä¸€æ¡ä¼ è¾“日志
     *
     * @param date
     * @return
     */
    MdcPassLog selectTodayLast(String date);
}
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/impl/MdcPassLogServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package org.jeecg.modules.system.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.modules.system.entity.MdcPassLog;
import org.jeecg.modules.system.mapper.MdcPassLogMapper;
import org.jeecg.modules.system.service.IMdcPassLogService;
import org.springframework.stereotype.Service;
/**
 * @author Lius
 * @date 2024/12/23 15:00
 */
@Service
public class MdcPassLogServiceImpl extends ServiceImpl<MdcPassLogMapper, MdcPassLog> implements IMdcPassLogService {
    /**
     * æŸ¥è¯¢ä»Šæ—¥æœ€æ–°ä¸€æ¡ä¼ è¾“日志
     *
     * @param date
     * @return
     */
    @Override
    public MdcPassLog selectTodayLast(String date) {
        return this.baseMapper.selectTodayLast(date);
    }
}
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/util/FileUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,194 @@
package org.jeecg.modules.system.util;
import cn.hutool.core.date.DateUtil;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.math.BigDecimal;
/**
 * Created by YangBin on 2017/9/15.
 */
public class FileUtils {
    private static final long MAX_FILE_SIZE = 10 * 1024 * 1024;
    /**
     * èŽ·å–æœåŠ¡å™¨ä¸´æ—¶è·¯å¾„
     *
     * @param request
     * @return
     */
    public static String serverTempPath(HttpServletRequest request) {
        String fsep = System.getProperty("file.separator");
        String path = request.getSession().getServletContext().getRealPath("");
        if (path.lastIndexOf(fsep) == path.length() - 1) {
            path += "upload" + fsep + "voucher" + fsep;
        } else {
            path += fsep + "upload" + fsep + "voucher" + fsep;
        }
        return path;
    }
    public static String serverTempPathIntactReg(HttpServletRequest request) {
        String fsep = System.getProperty("file.separator");
        String path = request.getSession().getServletContext().getRealPath("");
        if (path.lastIndexOf(fsep) == path.length() - 1) {
            path += "upload" + fsep + "log" + fsep + "error" + fsep;
        } else {
            path += fsep + "upload" + fsep + "log" + fsep + "error" + fsep;
        }
        return path;
    }
    public static String serverTempPathProcess(HttpServletRequest request) {
        String fsep = System.getProperty("file.separator");
        String path = request.getSession().getServletContext().getRealPath("");
        if (path.lastIndexOf(fsep) == path.length() - 1) {
            path += "upload" + fsep + "process" + fsep;
        } else {
            path += fsep + "upload" + fsep + "process" + fsep;
        }
        return path;
    }
    public static String changeFileFormatKb(String flow) {
        BigDecimal flows = new BigDecimal(flow);
        if (flows.compareTo(new BigDecimal(0)) > 0 && flows.compareTo(new BigDecimal(1024)) < 0) {//小于1M
            return flows.toString() + "B";
        } else if (flows.compareTo(new BigDecimal(1024)) >= 0) {
            BigDecimal result = flows.divide(new BigDecimal(1024), 2, BigDecimal.ROUND_HALF_UP);
            return result.toString() + "KB";
        } else {
            return "0";
        }
    }
    /**
     * å¾—到项目根目录下的绝对路径(磁盘的物理路径)
     *
     * @param request
     * @param newPath
     * @return
     */
    public static String getFilePath(HttpServletRequest request, String newPath) {
        String fsep = System.getProperty("file.separator");
        String path = request.getSession().getServletContext().getRealPath("/upload");
        path += fsep + newPath;
        return path;
    }
    /**
     * å¾—到项目根目录下的相对路径 ï¼ˆç›¸å¯¹äºŽé¡¹ç›®ä¸ºæ ¹è·¯å¾„)
     *
     * @param newPath
     * @return
     */
    public static String getRelativePath(String newPath) {
        return "/upload/" + newPath;
    }
    /**
     * æ–¹æ³•一:使用 FileWriter å†™æ–‡ä»¶
     *
     * @param filepath æ–‡ä»¶ç›®å½•
     * @param content  å¾…写入内容
     * @throws IOException
     */
    public static void fileWriterSql(String filepath, String content) throws IOException {
        OutputStreamWriter outputStreamWriter = null;
        try {
            File file = new File(filepath);
            if (!file.exists()) {
                file.createNewFile();
            }
            FileOutputStream outputStream = new FileOutputStream(file);
            if (outputStream != null) {
                outputStreamWriter = new OutputStreamWriter(outputStream, "UTF-8");
                outputStreamWriter.write(content);
                outputStreamWriter.flush();
            }
        } catch (IOException e) {
            e.getMessage();
        } finally {
            try {
                if (outputStreamWriter != null) {
                    outputStreamWriter.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        /*
        File file=new File(filepath);
        Writer writer = new OutputStreamWriter(new FileOutputStream(file.getAbsoluteFile()), "UTF-8");
        writer.append(content);
         */
    }
    /**
     * æ–‡ä»¶å¤§å°æ™ºèƒ½è½¬æ¢
     * ä¼šå°†æ–‡ä»¶å¤§å°è½¬æ¢ä¸ºæœ€å¤§æ»¡è¶³å•位
     *
     * @param size(文件大小,单位为B)
     * @return æ–‡ä»¶å¤§å°
     */
    public static String formatFileSize(Long size) {
        String sizeName = null;
        if (1024 * 1024 > size && size >= 1024) {
            sizeName = String.format("%.2f", size.doubleValue() / 1024) + "KB";
        } else if (1024 * 1024 * 1024 > size && size >= 1024 * 1024) {
            sizeName = String.format("%.2f", size.doubleValue() / (1024 * 1024)) + "MB";
        } else if (size >= 1024 * 1024 * 1024) {
            sizeName = String.format("%.2f", size.doubleValue() / (1024 * 1024 * 1024)) + "GB";
        } else {
            sizeName = size.toString() + "B";
        }
        return sizeName;
    }
    /**
     * ä¸Šä¼ æ–‡ä»¶å·¥å…·ç±»
     *
     * @param userPic
     * @param path
     * @param fileName
     * @return
     */
    public static boolean uploadFile(MultipartFile userPic, String path, String fileName) {
        Long fileSize = userPic.getSize();
        if (fileSize > MAX_FILE_SIZE) {
            return false;
        }
        File targetFile = new File(path, fileName);
        if (!targetFile.exists()) {
            targetFile.mkdirs();
        }
        try {
            userPic.transferTo(targetFile);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
    /**
     * é‡å‘½åæ–‡ä»¶å åŠ å…¥æ—¶é—´æˆ³
     *
     * @param fileName
     * @return
     */
    public static String newFileName(String fileName) {
        String suffix = fileName.substring(fileName.lastIndexOf('.'));
        String dateStr = "_" + DateUtil.now();
        String nameFile = fileName.substring(0, fileName.indexOf("."));
        //新文件名
        return nameFile + dateStr + suffix;
    }
}
lxzn-module-system/lxzn-system-start/src/main/java/org/jeecg/codegenerate/CreateTrigger.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,199 @@
package org.jeecg.codegenerate;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
/**
 * @Author: Lius
 * @CreateTime: 2025-06-23
 * @Description: SQL Server è§¦å‘器生成工具
 */
public class CreateTrigger {
    // æ•°æ®åº“连接信息
    private static final String JDBC_URL = "jdbc:sqlserver://192.168.1.118:1433;databaseName=LXZN_TEST_HANGYU_GK";
    private static final String USERNAME = "sa";
    private static final String PASSWORD = "123";
    public static void main(String[] args) {
        String schemaName = "dbo"; // SQL Server é»˜è®¤æž¶æž„
        String logTableName = "log_table"; // æ—¥å¿—表名
        try (Connection connection = DriverManager.getConnection(JDBC_URL, USERNAME, PASSWORD)) {
            // èŽ·å–æŒ‡å®šæž¶æž„ä¸‹çš„æ‰€æœ‰è¡¨
            List<String> tables = getTables(connection, schemaName);
            // ç”Ÿæˆè§¦å‘器 SQL å¹¶ä¿å­˜åˆ°æ–‡ä»¶
            generateTriggersForTables(connection, schemaName, logTableName, tables);
        } catch (SQLException | IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * èŽ·å–æŒ‡å®šæž¶æž„ä¸‹çš„æ‰€æœ‰è¡¨
     */
    private static List<String> getTables(Connection connection, String schemaName) throws SQLException {
        List<String> tables = new ArrayList<>();
        DatabaseMetaData metaData = connection.getMetaData();
        try (ResultSet resultSet = metaData.getTables(null, schemaName, null, new String[]{"TABLE"})) {
            while (resultSet.next()) {
                String tableName = resultSet.getString("TABLE_NAME");
                tables.add(tableName);
            }
        }
        return tables;
    }
    /**
     * èŽ·å–è¡¨çš„å­—æ®µåˆ—è¡¨
     */
    private static List<String> getTableColumns(Connection connection, String schemaName, String tableName) throws SQLException {
        List<String> columns = new ArrayList<>();
        DatabaseMetaData metaData = connection.getMetaData();
        try (ResultSet resultSet = metaData.getColumns(null, schemaName, tableName, null)) {
            while (resultSet.next()) {
                String columnName = resultSet.getString("COLUMN_NAME");
                columns.add(columnName);
            }
        }
        return columns;
    }
    /**
     * èŽ·å–è¡¨çš„ä¸»é”®åˆ—
     */
    private static String getPrimaryKeyColumn(Connection connection, String schemaName, String tableName) throws SQLException {
        DatabaseMetaData metaData = connection.getMetaData();
        try (ResultSet resultSet = metaData.getPrimaryKeys(null, schemaName, tableName)) {
            if (resultSet.next()) {
                return resultSet.getString("COLUMN_NAME");
            }
        }
        return "id"; // é»˜è®¤ä½¿ç”¨id作为主键,如果没有找到主键
    }
    /**
     * ä¸ºæ‰€æœ‰è¡¨ç”Ÿæˆè§¦å‘器
     */
    private static void generateTriggersForTables(Connection connection, String schemaName, String logTableName, List<String> tables) throws SQLException, IOException {
        try (FileWriter writer = new FileWriter("triggers.sql")) {
            for (String tableName : tables) {
                // èŽ·å–è¡¨ç»“æž„ä¿¡æ¯
                List<String> columns = getTableColumns(connection, schemaName, tableName);
                String primaryKey = getPrimaryKeyColumn(connection, schemaName, tableName);
                // ç”Ÿæˆè§¦å‘器 SQL
                String triggerSQL = generateTriggerSQL(schemaName, tableName, logTableName, columns, primaryKey);
                // å°†ç”Ÿæˆçš„触发器 SQL å†™å…¥æ–‡ä»¶
                writer.write("-- è§¦å‘器表: " + tableName + "\n");
                writer.write(triggerSQL);
                writer.write("\n\n");
                // å¦‚果需要,可以直接在数据库中创建触发器
                // createTrigger(connection, triggerSQL);
            }
            System.out.println("成功生成触发器并保存到Triggers.sql中!");
        }
    }
    /**
     * ç”Ÿæˆ SQL Server è§¦å‘器 SQL
     */
    private static String generateTriggerSQL(String schemaName, String tableName, String logTableName, List<String> columns, String primaryKey) {
        StringBuilder triggerSQL = new StringBuilder();
        // è§¦å‘器头部
        triggerSQL.append("CREATE TRIGGER [")
                .append(tableName)
                .append("_trigger]\n")
                .append("ON [")
                .append(schemaName)
                .append("].[").append(tableName).append("]\n")
                .append("AFTER INSERT, UPDATE, DELETE\n")
                .append("AS\n")
                .append("BEGIN\n")
                .append("    SET NOCOUNT ON;\n\n");
        // æ’入操作
        triggerSQL.append("    -- æ’入操作\n")
                .append("    IF EXISTS (SELECT * FROM inserted) AND NOT EXISTS (SELECT * FROM deleted)\n")
                .append("    BEGIN\n")
                .append("        INSERT INTO [").append(logTableName).append("] (action, create_time, sql_log)\n")
                .append("        SELECT 'INSERT', GETDATE(), 'INSERT INTO [").append(tableName).append("] (");
        // æ‹¼æŽ¥å­—段名
        for (int i = 0; i < columns.size(); i++) {
            triggerSQL.append("[").append(columns.get(i)).append("]");
            if (i < columns.size() - 1) {
                triggerSQL.append(", ");
            }
        }
        triggerSQL.append(") VALUES (''' + ");
        // æ‹¼æŽ¥å­—段值
        for (int i = 0; i < columns.size(); i++) {
            triggerSQL.append("ISNULL(CAST(i.").append(columns.get(i)).append(" AS NVARCHAR(MAX)), '') + '''");
            if (i < columns.size() - 1) {
                triggerSQL.append(", ''' + ");
            }
        }
        triggerSQL.append(");'\n")
                .append("        FROM inserted i;\n")
                .append("    END\n\n");
        // æ›´æ–°æ“ä½œ
        triggerSQL.append("    -- æ›´æ–°æ“ä½œ\n")
                .append("    IF EXISTS (SELECT * FROM inserted) AND EXISTS (SELECT * FROM deleted)\n")
                .append("    BEGIN\n")
                .append("        INSERT INTO [").append(logTableName).append("] (action, create_time, sql_log)\n")
                .append("        SELECT 'UPDATE', GETDATE(), 'UPDATE [").append(tableName).append("] SET ");
        // æ‹¼æŽ¥æ›´æ–°å­—段
        for (int i = 0; i < columns.size(); i++) {
            triggerSQL.append("[").append(columns.get(i)).append("] = ''' + ISNULL(CAST(i.").append(columns.get(i)).append(" AS NVARCHAR(MAX)), '') + '''");
            if (i < columns.size() - 1) {
                triggerSQL.append(", ");
            }
        }
        triggerSQL.append(" WHERE [").append(primaryKey).append("] = ''' + ISNULL(CAST(d.").append(primaryKey).append(" AS NVARCHAR(MAX)), '') + ''';'\n")
                .append("        FROM inserted i\n")
                .append("        INNER JOIN deleted d ON i.").append(primaryKey).append(" = d.").append(primaryKey).append(";\n")
                .append("    END\n\n");
        // åˆ é™¤æ“ä½œ
        triggerSQL.append("    -- åˆ é™¤æ“ä½œ\n")
                .append("    IF NOT EXISTS (SELECT * FROM inserted) AND EXISTS (SELECT * FROM deleted)\n")
                .append("    BEGIN\n")
                .append("        INSERT INTO [").append(logTableName).append("] (action, create_time, sql_log)\n")
                .append("        SELECT 'DELETE', GETDATE(), 'DELETE FROM [").append(tableName).append("] WHERE [").append(primaryKey).append("] = ''' + ISNULL(CAST(d.").append(primaryKey).append(" AS NVARCHAR(MAX)), '') + ''';'\n")
                .append("        FROM deleted d;\n")
                .append("    END\n\n");
        triggerSQL.append("END;\n");
        return triggerSQL.toString();
    }
//    /**
//     * åœ¨æ•°æ®åº“中创建触发器
//     */
//    private static void createTrigger(Connection connection, String triggerSQL) throws SQLException {
//        try (Statement statement = connection.createStatement()) {
//            statement.execute(triggerSQL);
//            System.out.println("Trigger created successfully!");
//        }
//    }
}
lxzn-module-system/lxzn-system-start/src/main/resources/application-dev.yml
@@ -126,7 +126,7 @@
        connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
      datasource:
        master:
          url: jdbc:sqlserver://192.168.1.118:1433;databasename=LXZN_TEST_HANGYU;nullCatalogMeansCurrent=true
          url: jdbc:sqlserver://192.168.1.118:1433;databasename=LXZN_TEST_HANGYU_GK;nullCatalogMeansCurrent=true
          username: sa
          password: 123
          driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
@@ -309,7 +309,9 @@
#staticAccessPath: /api/ffile/** # å½“前项目的静态资源访问配置在nginx中
#工控网/涉密网部署相关配置------------通过光盘摆渡
deploy:
    #涉密网传输工控网nc文件夹(指派设备nc文件)
    #工控网/涉密网部署 0为涉密网 1为工控网
    deployType: 0
    #涉密网传输工控网nc文件夹(指派设备nc文件)    å·¥æŽ§ç½‘传输涉密网nc文件夹(解析回传后的nc文件)
    secretFolder: D:\\test\\a
file:
  monitor:
@@ -319,10 +321,13 @@
      - D:\\hy_test\\b
      - D:\\hy_test\\c
    interval: 10000  # ç›‘控间隔(ms)
ferry:
  file:
    path: /data/ferry
    max-file-size: 10MB
security:
  encryption-key: 1234567890abcdef # åŠ è§£å¯†ç§˜é’¥
  encryption-key: 1234567890abcdef
#mdc文件路径配置
fileService:
  localFilePath: D:/data/sql/     #本地文件路径
  newFilePath: D:/data/bak/     #备份文件路径
  failedLocFilePath: D:/data/failed/failed.sql    #失败文件路径