89fc5a4db0f0af7cc2e92e25017ef6d95fc14d68..fc588c6e5ccac038cab378931d9bac3033e28f98
2025-07-04 yangys
增加产品型号
fc588c 对比 | 目录
2025-07-04 yangys
dnc导出修改
9858d9 对比 | 目录
2025-07-04 yangys
dnc导出修改&node字段调整
d0e196 对比 | 目录
已修改14个文件
已删除1个文件
已添加11个文件
757 ■■■■■ 文件已修改
blade-service/blade-mdm/pom.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/commons/vo/IdsVO.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/controller/DispatchController.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/controller/FlowMgrController.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/entity/ApproveRecord.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/StartDispatcher.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/mapper/ApproveRecordMapper.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/mapper/ApproveRecordMapper.xml 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/ApproveRecordService.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/CureFlowService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/vo/ApproveRecordVO.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/vo/TaskAssignVO.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/controller/DncSendBackController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/controller/NcProgramController.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/controller/NcProgramExchangeController.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/controller/NcProgramExportDNCController.java 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/entity/NcNode.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcProgramApprovedService.java 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcProgramExchangeService.java 53 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/utils/CustomBinaryReader.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/utils/CustomBinaryWriter.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/utils/FileExchangeUtil.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/resources/processesbpmn/dispatch.bpmn20.xml 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/test/java/org/springblade/mdm/utils/CustomBinaryReaderTest.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/test/java/org/springblade/mdm/utils/CustomBinaryWriterTest.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/sql/mdm/mdm.mysql.all.create.sql 36 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/pom.xml
@@ -80,6 +80,11 @@
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springblade</groupId>
            <artifactId>blade-core-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--<dependency>
            <groupId>org.springblade</groupId>
            <artifactId>blade-starter-transaction</artifactId>
blade-service/blade-mdm/src/main/java/org/springblade/mdm/commons/vo/IdsVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package org.springblade.mdm.commons.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
@Setter
@Getter
public class IdsVO {
    @Schema(description = "id数组")
    private Long[] ids;
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/controller/DispatchController.java
@@ -6,12 +6,16 @@
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.support.Kv;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.mdm.flow.entity.ApproveRecord;
import org.springblade.mdm.flow.excution.StartDispatcher;
import org.springblade.mdm.flow.service.ApproveRecordService;
import org.springblade.mdm.flow.vo.TaskAssignVO;
import org.springblade.mdm.program.service.ProcessProgRefService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -20,6 +24,8 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Slf4j
@@ -34,6 +40,9 @@
    private TaskService taskService;
    @Autowired
    private ProcessProgRefService processProgRefService;
    @Autowired
    private ApproveRecordService approveRecordService;
    /**
     * æ–°å¢ž
     */
@@ -61,9 +70,12 @@
        //加入审批用户
        variables.put("approveUserNickName",AuthUtil.getNickName());
        if(variables.containsKey("assignee")){
            addApproveRecord(taskId,processInstanceId,comment,programIds,variables);
            //指定了下一步执行人
            taskService.complete(taskId, variables);
            return R.success("流程提交成功");
        }else {
            // å®Œæˆä»»åŠ¡,给默认用户
@@ -71,4 +83,30 @@
        }
    }
    void addApproveRecord(String taskId, String processInstanceId, String comment,String programIds,Map<String, Object> variables){
        List<Long> programIdList = new ArrayList<>();
        if(programIds != null){
            programIdList = Func.toLongList(programIds);
        }else{
            programIdList.add(null);
        }
        Task task = taskService.createTaskQuery()
            .taskId(taskId)
            .singleResult();
        for(Long programId : programIdList){
            ApproveRecord rec = new ApproveRecord();
            rec.setTaskName(task.getName());
            rec.setComment(comment);
            rec.setNcProgramId(programId);
            rec.setOperateResult(variables.get("approve")+"");//审批结果
            rec.setOperateTime(DateUtil.now());
            rec.setProcessInstanceId(processInstanceId);
            rec.setUserId(AuthUtil.getUserId());
            rec.setUserNickname(AuthUtil.getNickName());
            approveRecordService.save(rec);
        }
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/controller/FlowMgrController.java
@@ -17,6 +17,7 @@
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.mdm.basesetting.machine.vo.MachineExcelVO;
import org.springblade.mdm.flow.service.ApproveRecordService;
import org.springblade.mdm.flow.service.FlowBusinessService;
import org.springblade.mdm.flow.vo.FlowVO;
import org.springblade.mdm.flow.vo.OvertimeTaskExcelVO;
@@ -42,6 +43,7 @@
    @Autowired
    private HistoryService historyService;
    @GetMapping("overtime-list")
    @ApiOperationSupport(order = 3)
@@ -71,7 +73,7 @@
    }
    @Operation(summary = "流程轨迹", description = "流程轨迹")
    @Operation(summary = "流程执行轨迹", description = "流程执行轨迹")
    @GetMapping("process-trace")
    public R<List<TaskTraceVO>> processTrace(String processInstanceId){
        List<TaskTraceVO> result = new ArrayList<>();
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/entity/ApproveRecord.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
package org.springblade.mdm.flow.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Getter;
import lombok.Setter;
import org.springblade.core.mp.base.BizEntity;
import java.time.LocalDate;
import java.util.Date;
/**
 * æ•°æŽ§ç¨‹åºå®¡æ‰¹è®°å½•
 */
@Setter
@Getter
@TableName("mdm_approve_record")
public class ApproveRecord extends BizEntity {
    private String processInstanceId;
    /**
     * ä»»åŠ¡åç§°
     */
    private String taskName;
    /**
     * å¤‡æ³¨
     */
    private String comment;
    /**
     * æ•°æŽ§ç¨‹åºid,这个可能不需要,可以根据关联表mdm_process_prog_ref来获取
     */
    private Long ncProgramId;
    private Long userId;
    /**
     * å®¡æ‰¹ç”¨æˆ·å§“名
     */
    private String userNickname;
    /**
     * è¿‡æœŸæ—¥æœŸ
     */
    private Date operateTime;
    /**
     * èŠ‚ç‚¹ç±»åž‹ï¼šå­—å…¸
      */
    private String operateResult;
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/StartDispatcher.java
@@ -50,7 +50,7 @@
        vars.put("partNo",startVO.getPartNo());
        vars.put("partNoEdition",startVO.getPartNoEdition());
        vars.put("planLockDays",startVO.getPlanLockDays());
        vars.put("productModel",startVO.getProductModel());
        //零组件代码
        String partNo = generatePartNo(startVO);
        vars.put("partNo",partNo);
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/mapper/ApproveRecordMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package org.springblade.mdm.flow.mapper;
import org.springblade.core.mp.mapper.BladeMapper;
import org.springblade.mdm.flow.entity.ApproveRecord;
import org.springblade.mdm.flow.vo.ApproveRecordVO;
import org.springblade.mdm.program.entity.NcNode;
import org.springblade.mdm.program.vo.NcNodeVO;
import java.util.List;
public interface ApproveRecordMapper extends BladeMapper<ApproveRecord> {
    List<ApproveRecordVO> listByNcProgramId(Long ncProgramId);
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/mapper/ApproveRecordMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
<?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.springblade.mdm.flow.mapper.ApproveRecordMapper">
    <resultMap id="BaseResultMap" type="org.springblade.mdm.flow.entity.ApproveRecord">
        <id column="id" property="id"/>
        <result column="status" property="status"/>
        <result column="create_time" property="createTime"/>
        <result column="update_time" property="updateTime"/>
        <result column="is_deleted" property="isDeleted"/>
    </resultMap>
    <sql id="all_columns">id,tenant_id,nc_program_id,process_instances_id,operate_time,operate_result,user_id,user_nickname,status,create_dept,is_deleted,create_time,create_user,update_time,update_user</sql>
    <select id="listByNcProgramId" resultType="org.springblade.mdm.flow.vo.ApproveRecordVO">
        select <include refid="all_columns"/> FROM mdm_approve_record
        WHERE  nc_program_id = ${ncProgramId} and is_deleted = 0 order by create_time desc
    </select>
</mapper>
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/ApproveRecordService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
package org.springblade.mdm.flow.service;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.mp.base.BizServiceImpl;
import org.springblade.mdm.flow.entity.ApproveRecord;
import org.springblade.mdm.flow.mapper.ApproveRecordMapper;
import org.springblade.mdm.flow.vo.ApproveRecordVO;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * å®¡æ‰¹è®°å½•,用于查询执行轨迹
 *
 * @author yangys
 */
@Slf4j
@Service
@AllArgsConstructor
public class ApproveRecordService extends BizServiceImpl<ApproveRecordMapper, ApproveRecord> {
    public List<ApproveRecordVO> listByNcProgramId(Long ncProgramId) {
        return this.getBaseMapper().listByNcProgramId(ncProgramId);
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/CureFlowService.java
@@ -48,12 +48,12 @@
     */
    public void start(long programId){
        Map<String, Object> vars = new HashMap<>();
        //NcProgram prog = ncProgramService.getById(programId);
        NcProgram prog = ncProgramService.getById(programId);
        NcNode progNode = ncNodeService.getById(programId);
        Machine machine = machineService.getByCode(progNode.getMachineCode());
        vars.put("machineCode",machine.getCode());
        vars.put("machineMode",machine.getName());
        vars.put("processEdition",progNode.getProcessEdition());
        vars.put("processEdition",prog.getProcessEdition());
        vars.put("programId",programId);
        vars.put("program",progNode);
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/vo/ApproveRecordVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
package org.springblade.mdm.flow.vo;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import org.springblade.core.mp.base.BizEntity;
import org.springblade.mdm.commons.vo.BaseVO;
import java.util.Date;
/**
 * æ•°æŽ§ç¨‹åºå®¡æ‰¹è®°å½•
 */
@Setter
@Getter
public class ApproveRecordVO extends BaseVO {
    private String processInstanceId;
    /**
     * æ•°æŽ§ç¨‹åºid
     */
    @Schema(description = "数控程序id")
    private Long ncProgramId;
    @Schema(description = "用户id")
    private Long userId;
    @Schema(description = "审批用户姓名")
    private String userNickname;
    @Schema(description = "审批日期")
    private Date operateTime;
    @Schema(description = "审批结果")
    private String operateResult;
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/vo/TaskAssignVO.java
@@ -17,7 +17,8 @@
    private String processNo;
    @Schema(description = "工序名称")
    private String processName;
    @Schema(description = "产品型号")
    private String productModel;
    @Schema(description = "工序版次")
    private String processEdition;
@@ -37,4 +38,5 @@
    private LocalDate planStartTime;
    @Schema(description = "主制分工表ID")
    private long producePlanId;
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/controller/DncSendBackController.java
@@ -42,7 +42,7 @@
     */
    @PostMapping("upload")
    @ApiOperationSupport(order = 1)
    @Operation(summary = "上传文件", description = "上传DNC回传文件")
    @Operation(summary = "DNC回传文件导入,上传文件", description = "上传DNC回传文件")
    public R<Void> dncSendBackUpload(@RequestParam MultipartFile file) {
        try {
            ncProgramExchangeService.dncSendBackUpload(file);
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/controller/NcProgramController.java
@@ -7,17 +7,25 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.task.Comment;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springblade.core.tenant.annotation.NonDS;
import org.springblade.core.tool.api.R;
import org.springblade.mdm.flow.service.ApproveRecordService;
import org.springblade.mdm.flow.vo.ApproveRecordVO;
import org.springblade.mdm.flow.vo.TaskTraceVO;
import org.springblade.mdm.program.entity.NcProgram;
import org.springblade.mdm.program.service.NcProgramService;
import org.springblade.mdm.program.service.ProcessProgRefService;
import org.springblade.mdm.program.vo.NcNodeProgramQueryVO;
import org.springblade.mdm.program.vo.NcProgramUploadVO;
import org.springblade.mdm.program.vo.NcProgramVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.List;
/**
@@ -35,6 +43,9 @@
    private final NcProgramService ncProgramService;
    private final ProcessProgRefService ncProcessProgRefService;
    private final ApproveRecordService approveRecordService;
    @PostMapping("/upload")
    @Operation(summary = "上传文件", description = "上传程序/附件文件")
    public R<Boolean> upload(NcProgramUploadVO uploadVO) {
@@ -92,4 +103,12 @@
    public R<List<NcProgramVO>> listByProcess(@Parameter(description="所属节点ID")@RequestParam String processInstanceId) {
        return R.data(ncProcessProgRefService.listByProcess(processInstanceId));
    }
    @Operation(summary = "操作日志", description = "程序操作日志,即审批记录,在主页点击某一个程序后的下方标签显示")
    @GetMapping("approve-records")
    public R<List<ApproveRecordVO>> processTrace1(@Parameter(description = "程序id") Long ncProgramId){
        List<TaskTraceVO> result = new ArrayList<>();
        return R.data(approveRecordService.listByNcProgramId(ncProgramId));
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/controller/NcProgramExchangeController.java
ÎļþÒÑɾ³ý
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/controller/NcProgramExportDNCController.java
@@ -3,22 +3,24 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.tenant.annotation.NonDS;
import org.springblade.core.tool.api.R;
import org.springblade.mdm.commons.vo.IdsVO;
import org.springblade.mdm.program.service.NcProgramApprovedService;
import org.springblade.mdm.program.service.NcProgramService;
import org.springblade.mdm.program.vo.NcNodeProgramQueryVO;
import org.springblade.mdm.program.vo.NcProgramExportDncPageVO;
import org.springblade.mdm.program.vo.NcProgramExportDncQueryVO;
import org.springblade.mdm.program.vo.NcProgramVO;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
/**
 * ç¨‹åºæ¶‰å¯†ç½‘-工控网交换接口
@@ -44,9 +46,17 @@
    @PostMapping("/export-dnc")
    @Operation(summary = "数控程序导出dnc", description = "数控程序导出到工控网")
    public void exportDnc(Long nodeId, HttpServletResponse response) {
    public void exportDnc(@RequestBody @Parameter(description = "审批表id数组") IdsVO vo, HttpServletResponse response) {
        if(vo.getIds() == null || vo.getIds().length == 0) {
            throw new ServiceException("未选择文件导出");
        }
        try {
            ncProgramApprovedService.exportDnc(vo.getIds(),response.getOutputStream());
        } catch (IOException e) {
            log.error("导出DNC异常", e);
            throw new RuntimeException(e);
        }
        //return R.<Boolean>status(true);
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/entity/NcNode.java
@@ -34,12 +34,12 @@
    /**
     * å·¥åºç‰ˆæ¬¡
     */
    private String processEdition;
    //private String processEdition;
    /**
     * å·¥è‰ºç‰ˆæ¬¡
     */
    private String craftEdition;
    //private String craftEdition;
    /**
     * é›¶ç»„件号/图号
     */
@@ -47,7 +47,7 @@
    /**
     * å›¾å·ç‰ˆæ¬¡
     */
    private String partNoEdition;
    //private String partNoEdition;
    /**
     * æ˜¯å¦å›ºåŒ–
@@ -56,11 +56,11 @@
    /**
     * è¿‡æœŸæ—¥æœŸ
     */
    private LocalDate expireDate;
    //private LocalDate expireDate;
    /**
     * æ˜¯å¦é”å®š
     */
    private Integer isLocked;
    //private Integer isLocked;
    /**
     * èŠ‚ç‚¹ç±»åž‹ï¼šå­—å…¸
      */
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcProgramApprovedService.java
@@ -1,18 +1,41 @@
package org.springblade.mdm.program.service;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.archivers.zip.ZipUtil;
import org.apache.commons.lang3.StringUtils;
import org.springblade.core.mp.base.BizEntity;
import org.springblade.core.mp.base.BizServiceImpl;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.oss.OssTemplate;
import org.springblade.core.tool.utils.Func;
import org.springblade.mdm.flow.entity.ApproveRecord;
import org.springblade.mdm.flow.service.ApproveRecordService;
import org.springblade.mdm.program.entity.NcNode;
import org.springblade.mdm.program.entity.NcProgram;
import org.springblade.mdm.program.entity.NcProgramApproved;
import org.springblade.mdm.program.mapper.NcProgramApprovedMapper;
import org.springblade.mdm.program.vo.DncSendBackData;
import org.springblade.mdm.program.vo.NcProgramExportDncPageVO;
import org.springblade.mdm.program.vo.NcProgramExportDncQueryVO;
import org.springblade.mdm.utils.CustomBinaryWriter;
import org.springframework.stereotype.Service;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
 * ä¸‹å‘/回传程序统计
@@ -23,8 +46,10 @@
@Service
@AllArgsConstructor
public class NcProgramApprovedService extends BizServiceImpl<NcProgramApprovedMapper, NcProgramApproved> {
    private final NcProgramService progService;
    private final OssTemplate ossTemplate;
    private final ApproveRecordService approvedService;
    private final NcNodeService ncNodeService;
    /**
     * åˆ†é¡µæŸ¥è¯¢
     * @param query æŸ¥è¯¢å‚æ•°
@@ -37,5 +62,191 @@
        return page;
    }
    /**
     * å¯¼å‡ºdnc
     * @param approvedIdArr å¾…导出审批表id数组
     */
    public void exportDnc(Long[] approvedIdArr, OutputStream os) throws IOException {
        ZipOutputStream zipOut = new ZipOutputStream(os);
        ArrayList<Long> programIdList = new ArrayList<Long>();
        for (Long approvedId : approvedIdArr) {
            NcProgramApproved approved = this.getById(approvedId);
            programIdList.add(approved.getNcProgramId());
            NcProgram prog = progService.getById(approved.getNcProgramId());
            String filename = prog.getOssName();
            InputStream inputStream = ossTemplate.statFileStream(filename);
            addInputStreamToZip(zipOut, inputStream, prog.getName());
        }
        addDataJson(zipOut, programIdList);
    }
    /**
     * å¯¼å…¥æ•°æ®æ–‡ä»¶
     * @param zipOut
     */
    void addDataJson(ZipOutputStream zipOut, List<Long> programIdList) throws IOException {
        addProgramDataJson(zipOut, programIdList);
        addApproveRecordDataJson(zipOut, programIdList);
        addNcNodeDataJson(zipOut, programIdList);
    }
    /**
     * å¯¼å…¥ç¨‹åºè®°å½•
     * @param zipOut
     * @param programIdList
     */
    void addProgramDataJson(ZipOutputStream zipOut, List<Long> programIdList) throws IOException {
        LambdaQueryWrapper<NcProgram> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(NcProgram::getId, programIdList);
        List<NcProgram> programList = progService.list(queryWrapper);
        JSONArray jsonArray = new JSONArray();
        for(NcProgram program : programList){
            JSONObject recObj = new JSONObject();
            recObj.put("id", program.getId());
            recObj.put("code", program.getCode());
            recObj.put("ossName",program.getOssName());
            recObj.put("isTextFile",program.getIsTextFile());
            recObj.put("category",program.getCategory());
            recObj.put("description",program.getDescription());
            recObj.put("name",program.getName());
            recObj.put("partNo",program.getPartNo());
            recObj.put("ncNodeId",program.getNcNodeId());
            recObj.put("url",program.getUrl());
            recObj.put("isCured",program.getIsCured());
            recObj.put("isLocked",program.getIsLocked());
            recObj.put("isTest",program.getIsTest());
            recObj.put("machineCode",program.getMachineCode());
            recObj.put("processEdition",program.getProcessEdition());
            recObj.put("taskAssignTime",program.getTaskAssignTime());
            addSuperProperties(recObj,program);
            jsonArray.add(recObj);
        }
        addInputStreamToZip(zipOut,new ByteArrayInputStream(jsonArray.toJSONString().getBytes(StandardCharsets.UTF_8)),"exp_mdm_nc_program.json");
    }
    /**
     * å¯¼å…¥å®¡æ‰¹è®°å½•
     * @param zipOut
     * @param programIdList
     */
    void addApproveRecordDataJson(ZipOutputStream zipOut, List<Long> programIdList) throws IOException {
        LambdaQueryWrapper<ApproveRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(ApproveRecord::getNcProgramId, programIdList);
        List<ApproveRecord> records = approvedService.list(queryWrapper);
        JSONArray jsonArray = new JSONArray();
        for(ApproveRecord record : records){
            JSONObject recObj = new JSONObject();
            recObj.put("id", record.getId());
            recObj.put("comment", record.getComment());
            recObj.put("userId",record.getUserId());
            recObj.put("userNickname",record.getUserNickname());
            recObj.put("operateTime",record.getOperateTime());
            recObj.put("operateResult",record.getOperateResult());
            recObj.put("taskName",record.getTaskName());
            recObj.put("ncProgramId",record.getNcProgramId());
            recObj.put("processInstanceId",record.getProcessInstanceId());
            addSuperProperties(recObj,record);
            jsonArray.add(recObj);
        }
        addInputStreamToZip(zipOut,new ByteArrayInputStream(jsonArray.toJSONString().getBytes(StandardCharsets.UTF_8)),"exp_mdm_approve_record.json");
    }
    /**
     * å¯¼å…¥èŠ‚ç‚¹
     * @param zipOut
     * @param programIdList
     */
    void addNcNodeDataJson(ZipOutputStream zipOut, List<Long> programIdList) throws IOException {
        LambdaQueryWrapper<NcProgram> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(NcProgram::getId, programIdList);
        List<NcProgram> programs = progService.list(queryWrapper);
        JSONArray jsonArray = new JSONArray();
        ArrayList<Long> exportNodeIdList     = new ArrayList<>();
        for(NcProgram program : programs){
            JSONObject recObj = new JSONObject();
            if(!exportNodeIdList.contains(program.getNcNodeId())){
                exportNodeIdList.add(program.getNcNodeId());
            }
            NcNode ncNode = ncNodeService.getById(program.getNcNodeId());
            if(StringUtils.isNotEmpty(ncNode.getParentIds())){
                List<Long> pids = Func.toLongList(ncNode.getParentIds());
                for(Long nodeId : pids){
                    if(!exportNodeIdList.contains(nodeId)){
                        exportNodeIdList.add(nodeId);
                    }
                }
            }
        }
        LambdaQueryWrapper<NcNode> nodeQueryWrapper = new LambdaQueryWrapper<>();
        nodeQueryWrapper.in(NcNode::getId, exportNodeIdList);
        List<NcNode> nodeList =ncNodeService.list(nodeQueryWrapper);
        for(NcNode node : nodeList){
            JSONObject recObj = new JSONObject();
            recObj.put("id", node.getId());
            recObj.put("nodeType", node.getNodeType());
            recObj.put("machineCode",node.getMachineCode());
            recObj.put("parentId",node.getParentId());
            recObj.put("description",node.getDescription());
            recObj.put("name",node.getName());
            recObj.put("remark",node.getRemark());
            recObj.put("partNo",node.getPartNo());
            recObj.put("parentIds",node.getParentIds());
            recObj.put("processName",node.getProcessName());
            addSuperProperties(recObj,node);
            jsonArray.add(recObj);
        }
        addInputStreamToZip(zipOut,new ByteArrayInputStream(jsonArray.toJSONString().getBytes(StandardCharsets.UTF_8)),"exp_mdm_nc_node.json");
    }
    void addSuperProperties(JSONObject recObj, BizEntity entity){
        recObj.put("tenantId",entity.getTenantId());
        recObj.put("createTime",entity.getCreateTime());
        recObj.put("updateTime",entity.getUpdateTime());
        recObj.put("createUser",entity.getCreateUser());
        recObj.put("updateUser",entity.getUpdateUser());
        recObj.put("status",entity.getStatus());
        recObj.put("createDept",entity.getCreateDept());
    }
    public void addInputStreamToZip(ZipOutputStream zipOut, InputStream inputStream, String entryName)
        throws IOException {
        // åˆ›å»ºæ–°çš„ ZIP æ¡ç›®
        ZipEntry zipEntry = new ZipEntry(entryName);
        zipOut.putNextEntry(zipEntry);
        // å°†è¾“入流写入 ZIP è¾“出流
        byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer)) >= 0) {
            zipOut.write(buffer, 0, length);
        }
        // å…³é—­å½“前条目
        zipOut.closeEntry();
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcProgramExchangeService.java
@@ -11,21 +11,25 @@
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.utils.FileUtil;
import org.springblade.mdm.basesetting.machine.vo.MachineVO;
import org.springblade.mdm.program.entity.NcProgramExchange;
import org.springblade.mdm.program.mapper.NcProgramExchangeMapper;
import org.springblade.mdm.program.vo.DncSendBackData;
import org.springblade.mdm.utils.CustomBinaryReader;
import org.springblade.mdm.utils.FileExchangeUtil;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
/**
 * ä¸‹å‘/回传程序统计
 * ç¨‹åºäº¤æ¢ï¼ˆdnc导入/导出)
 *
 * @author yangys
 */
@@ -36,16 +40,16 @@
    /**
     * dnc回传文件上传
     * @param file
     * @param file æ–‡ä»¶
     * @return
     */
    public void dncSendBackUpload(MultipartFile file) {
        List<DncSendBackData> list=new ArrayList<>();
    public List<DncSendBackData> dncSendBackUpload(MultipartFile file) {
        List<DncSendBackData> list ;
        try {
            String fileName = file.getOriginalFilename();
            InputStream fileInputStream = file.getInputStream();
            byte[] bytes = FileUtil.copyToByteArray(fileInputStream);
            //InputStream fileInputStream = file.getInputStream();
            InputStream zipFileInputStream = FileExchangeUtil.convertFileToZip(file.getInputStream());
            byte[] bytes = FileUtil.copyToByteArray(zipFileInputStream);
            list = parseDncZipFromByteArray(bytes);
            for(DncSendBackData dncSendBackData:list){
                NcProgramExchange exchange=new NcProgramExchange();
@@ -57,10 +61,36 @@
        } catch (IOException e) {
            log.error("上传dnc文件失败",e);
            list = Collections.emptyList();
        }
        return list;
    }
    InputStream convertFileToZip(InputStream inputStream) throws IOException {
        File tempFile = createTempFile();
        FileOutputStream fos = new FileOutputStream(tempFile);
        CustomBinaryReader.read(inputStream,fos);
        FileInputStream dInstream = new FileInputStream(tempFile);
        return dInstream;
    }
    /**
     * åˆ›å»ºä¸€ä¸ªä¸´æ—¶æ–‡ä»¶
     * @return
     * @throws IOException
     */
    File createTempFile() throws IOException {
        Path tempDir = Paths.get(System.getProperty("java.io.tmpdir"));
        // åœ¨ä¸´æ—¶ç›®å½•中创建文件
        String tfilename = "t"+System.currentTimeMillis();
        Path tempFile = Files.createTempFile(tempDir, tfilename, ".tmp");
        System.out.println("创建的临时文件: " + tempFile);
        return tempFile.toFile();
    }
    public static List<DncSendBackData> parseDncZipFromByteArray(byte[] zipData) throws IOException {
        //List<DncSendBackData> datas = new ArrayList<>();
        List<DncSendBackData> datas  = ZipFileDirectoryScanner.getFilesInDirectoryRecursive(zipData, "");
@@ -107,6 +137,7 @@
     * @param query æŸ¥è¯¢å‚æ•°
     * @return
     */
    public IPage<DncSendBackData> dncSendBackPageQuery(Query query) {
        IPage<DncSendBackData> page = this.getBaseMapper().dncSendBackpageQuery(Condition.getPage(query),query);
blade-service/blade-mdm/src/main/java/org/springblade/mdm/utils/CustomBinaryReader.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,37 @@
package org.springblade.mdm.utils;
import java.io.*;
import java.util.Arrays;
public class CustomBinaryReader {
    /**
     * ä»Žè¾“入流读取数据到输出流
     * @param inputStream
     * @param os
     * @throws IOException
     */
    public static void read(InputStream inputStream, OutputStream os) throws IOException {
        byte[] buffer = new byte[1024];
        try (DataInputStream in = new DataInputStream(
            new BufferedInputStream(inputStream))) {
            // è¯»å–并验证Magic Number
            byte[] magic = new byte[4];
            in.readFully(magic);
            if (!Arrays.equals(magic, CustomBinaryWriter.MAGIC_NUMBER)) {
                throw new RuntimeException("不是有效的自定义文件格式");
            }
            // è¯»å–版本号
            short version = in.readShort();
            if (version > CustomBinaryWriter.VERSION) {
                throw new RuntimeException("不支持的版本: " + version);
            }
            while(in.read(buffer) != -1){
                os.write(buffer);
            }
        }
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/utils/CustomBinaryWriter.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
package org.springblade.mdm.utils;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class CustomBinaryWriter {
    static final byte[] MAGIC_NUMBER = {'M', 'D', 'M', '1'};
    static final short VERSION = 1;
    /**
     * å°†è¾“入流中的内容写入输出流
     * @param outputStream
     * @param ins
     * @throws IOException
     */
    public static void write(OutputStream outputStream, InputStream ins) throws IOException {
        byte[] buffer = new byte[1024];
        try (DataOutputStream out = new DataOutputStream(outputStream)) {
            // å†™å…¥æ–‡ä»¶å¤´
            out.write(MAGIC_NUMBER);
            out.writeShort(VERSION);
            while(ins.read(buffer) != -1) {
                out.write(buffer);
            }
        }
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/utils/FileExchangeUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,30 @@
package org.springblade.mdm.utils;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class FileExchangeUtil {
    public static InputStream convertFileToZip(InputStream inputStream) throws IOException {
        File tempFile = createTempFile();
        FileOutputStream fos = new FileOutputStream(tempFile);
        CustomBinaryReader.read(inputStream,fos);
        FileInputStream dInstream = new FileInputStream(tempFile);
        return dInstream;
    }
    public static File createTempFile() throws IOException {
        Path tempDir = Paths.get(System.getProperty("java.io.tmpdir"));
        // åœ¨ä¸´æ—¶ç›®å½•中创建文件
        String tfilename = "t"+System.currentTimeMillis();
        Path tempFile = Files.createTempFile(tempDir, tfilename, ".tmp");
        System.out.println("创建的临时文件: " + tempFile);
        return tempFile.toFile();
    }
}
blade-service/blade-mdm/src/main/resources/processesbpmn/dispatch.bpmn20.xml
@@ -3,10 +3,14 @@
  <process id="dispatch" name="任务派工" isExecutable="true">
    <startEvent id="start" name="开始"/>
    <sequenceFlow id="sid-c1619263-d1ff-4106-9315-f9ab9a3bee71" sourceRef="start" targetRef="teamLeaderTask"/>
    <userTask id="teamLeaderTask" name="专业组长" flowable:assignee="${teamLeader}"/>
    <userTask id="programmingTask" name="编制" flowable:assignee="${assignee}"/>
    <userTask id="check" name="校对" flowable:assignee="${assignee}"/>
    <userTask id="approveTask" name="高师审批" flowable:assignee="${assignee}"/>
    <userTask id="teamLeaderTask" name="任务分派" flowable:assignee="${teamLeader}">
      <documentation>专业组长任务分派</documentation>
    </userTask>
    <userTask id="programmingTask" name="数控程序编写" flowable:assignee="${assignee}"/>
    <userTask id="check" name="数控程序校对" flowable:assignee="${assignee}"/>
    <userTask id="approveTask" name="数控程序审批" flowable:assignee="${assignee}">
      <documentation>高师数控程序审批</documentation>
    </userTask>
    <endEvent id="approveEnd" name="审批完成">
      <extensionElements>
        <flowable:executionListener expression="${dispatchFinishListener.handle(execution)}" event="end"/>
blade-service/blade-mdm/src/test/java/org/springblade/mdm/utils/CustomBinaryReaderTest.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
package org.springblade.mdm.utils;
import org.junit.jupiter.api.Test;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CustomBinaryReaderTest {
    //@Test
    public void testRead() throws IOException {
        FileInputStream fis = new FileInputStream("d:/myd.bin");
        FileOutputStream fos = new FileOutputStream("d:/ddddreadout.zip");
        CustomBinaryReader.read(fis,fos);
    }
}
blade-service/blade-mdm/src/test/java/org/springblade/mdm/utils/CustomBinaryWriterTest.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package org.springblade.mdm.utils;
import org.junit.jupiter.api.Test;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CustomBinaryWriterTest {
    //@Test
    public void testWrite() throws IOException {
        FileOutputStream fos = new FileOutputStream("d:/myd.bin");
        FileInputStream fis = new FileInputStream("d:/dddd.zip");
        CustomBinaryWriter.write(fos,fis);
    }
}
doc/sql/mdm/mdm.mysql.all.create.sql
@@ -74,7 +74,7 @@
   `description` varchar(100) NOT NULL COMMENT '描述',
   `remark` varchar(200) NOT NULL COMMENT '备注',
   `parent_id` bigint DEFAULT NULL COMMENT '上级节点ID',
   `parent_ids` varchar(100) DEFAULT NULL COMMENT '上级节点ID集合,id逗号分隔',
   `parent_ids` varchar(200) DEFAULT NULL COMMENT '上级节点ID集合,id逗号分隔',
   `node_type` varchar(20) DEFAULT NULL COMMENT '节点类型:业务字典定义',
   `status` int DEFAULT NULL COMMENT '业务状态',
   `create_dept` bigint DEFAULT NULL COMMENT '创建单位',
@@ -111,13 +111,16 @@
  `code` varchar(100) NULL COMMENT '程序编号',
  `name` varchar(100) NOT NULL COMMENT '程序名称',
  `oss_name` varchar(100) NULL COMMENT 'oss中的文件名',
  `category` varchar(2) NULL COMMENT '文件分类',
  `category` varchar(20) NULL COMMENT '文件分类',
  `process_name` varchar(20) NULL COMMENT '工序名称',
  `remark` varchar(100) NULL COMMENT '备注',
  `is_text_file` int DEFAULT NULL COMMENT '是否文本文件',
  `url` varchar(400) NOT NULL COMMENT '文件地址',
  `machine_code` varchar(100) DEFAULT NULL COMMENT '设备编号/机床编号',
  `part_no` varchar(100) NULL COMMENT '零组件编号/图号',
  `part_no_edition` varchar(100) NULL COMMENT '图号版次',
  `craft_edition` varchar(20) NULL COMMENT '设计版次',
  `description` varchar(100) NULL COMMENT '描述',
  `is_cured` int DEFAULT NULL COMMENT '是否固化,1是;0否',
  `expire_date` date DEFAULT NULL COMMENT '到期时间,根据有效期时长计算而来',
  `process_edition` varchar(40) DEFAULT NULL COMMENT '工序版次,升版就是变更改该字段,需要保留历史记录',
@@ -135,15 +138,38 @@
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='数控程序';
/**
  æµç¨‹å®¡æ‰¹è®°å½•表,审批过程中记录
 */
DROP TABLE IF EXISTS `mdm_approve_record`;
CREATE TABLE `mdm_approve_record` (
   `id` bigint NOT NULL,
   `tenant_id` varchar(6) DEFAULT NULL COMMENT '所属租户',
   `nc_program_id` bigint NULL COMMENT '程序id。未选择程序之前是null',
   `process_instance_id` varchar(64) DEFAULT NULL COMMENT '流程实例id',
   `task_name` varchar(100) DEFAULT NULL COMMENT '任务名称',
   `operate_time` datetime DEFAULT NULL COMMENT '审批时间',
   `operate_result` varchar(20) DEFAULT NULL COMMENT '审批结果',
   `user_id` bigint NOT NULL COMMENT '审批用户id',
   `user_nickname` varchar(100) NOT NULL COMMENT '审批用户姓名',
   `comment` varchar(100) NOT NULL COMMENT '审批备注',
   `status` int DEFAULT NULL COMMENT '业务状态',
   `create_dept` bigint DEFAULT NULL COMMENT '创建单位',
   `is_deleted` int DEFAULT NULL,
   `create_time` datetime DEFAULT NULL COMMENT '创建时间',
   `create_user` bigint DEFAULT NULL COMMENT '创建人',
   `update_time` datetime DEFAULT NULL COMMENT '更新时间',
   `update_user` bigint DEFAULT NULL COMMENT '更新人',
   PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='数控程序审批记录';
DROP TABLE IF EXISTS `mdm_nc_program_approved`;
CREATE TABLE `mdm_nc_program_approved` (
   `id` bigint NOT NULL,
   `tenant_id` varchar(6) DEFAULT NULL COMMENT '所属租户',
   `program_name` varchar(100) NOT NULL COMMENT '程序名称',
   `program_id` bigint NOT NULL COMMENT '程序id,指向最新的程序记录',
   `nc_program_id` bigint NOT NULL COMMENT '程序id,指向最新的程序记录',
   `status` int DEFAULT NULL COMMENT '业务状态',
   `exchange_type` int DEFAULT NULL COMMENT '交换类型,1:下发;2:固化(dnc回传)',
   `create_dept` bigint DEFAULT NULL COMMENT '创建单位',
   `is_deleted` int DEFAULT NULL,
   `create_time` datetime DEFAULT NULL COMMENT '创建时间',