yangys
2025-09-02 2689c8fec95018952784bd8d032afb5a194a6616
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/ApproveTableService.java
@@ -1,40 +1,27 @@
package org.springblade.mdm.flow.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.HistoryService;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.task.api.Task;
import org.springblade.core.mp.base.BizServiceImpl;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.oss.OssTemplate;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.mdm.basesetting.machine.MachineService;
import org.springblade.mdm.basesetting.machine.service.MachineService;
import org.springblade.mdm.basesetting.machine.entity.Machine;
import org.springblade.mdm.commons.service.ParamService;
import org.springblade.mdm.commons.support.TemplatedPdfWriter;
import org.springblade.mdm.flow.constants.FlowContants;
import org.springblade.mdm.flow.entity.ApproveRecord;
import org.springblade.mdm.flow.mapper.ApproveRecordMapper;
import org.springblade.mdm.flow.vo.ApproveRecordVO;
import org.springblade.mdm.program.entity.NcNode;
import org.springblade.mdm.program.entity.NcProgram;
import org.springblade.mdm.program.entity.ProcessProgRef;
import org.springblade.mdm.flow.vo.ApproveTableInfo;
import org.springblade.mdm.program.service.NcNodeService;
import org.springblade.mdm.program.service.NcProgramService;
import org.springblade.mdm.program.service.ProcessProgRefService;
import org.springframework.beans.BeanUtils;
import org.springblade.system.feign.IUserClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.*;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
/**
 * 审批记录,用于查询执行轨迹
 *
@@ -42,232 +29,145 @@
 */
@Slf4j
@Service
@AllArgsConstructor
public class ApproveTableService{
   private final FlowCommonService flowCommonService;
   private final ApproveRecordService approveRecordService;
   private final NcNodeService ncNodeService;
   private final MachineService machineService;
   private final HistoryService historyService;
   private static final String UNCHECK_BOX = "☐";
   private static final String CHECKED_BOX = "☑";
   static Chunk square = new Chunk("o", new Font(Font.FontFamily.ZAPFDINGBATS, 12)); // 空方框
   static Chunk check = new Chunk("4", new Font(Font.FontFamily.ZAPFDINGBATS, 12)); // 带勾方框
   //static SimpleDateFormat
public class ApproveTableService {
   @Autowired
   private FlowCommonService flowCommonService;
   @Autowired
   private NcNodeService ncNodeService;
   @Autowired
   private MachineService machineService;
   @Autowired
   private IUserClient useClient;
   @Autowired
   private ParamService paramService;
   @Autowired
   private OssTemplate ossTemplate;
   @Autowired
   private ApproveInfoQueryService approveInfoQueryService;
   //private static final String UNCHECK_BOX = "☐";
   //private static final String CHECKED_BOX = "☑";
   //static Chunk square = new Chunk("o", new Font(Font.FontFamily.ZAPFDINGBATS, 12)); // 空方框
   //static Chunk check = new Chunk("4", new Font(Font.FontFamily.ZAPFDINGBATS, 12)); // 带勾方框
   /*
   BaseFont getBaseFont() throws DocumentException, IOException {
      return BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
   }
   Font getChineseFont() throws DocumentException, IOException {
      BaseFont bfChinese = getBaseFont();
      return new Font(bfChinese, 12, Font.NORMAL);
   }
   /**
    * 导出审批确认表
    * @param processInstanceId
    */
   public void exportApproveTable(String processInstanceId, OutputStream os) throws DocumentException, IOException {
   }*/
      BaseFont bfChinese =  getBaseFont();
   public void exportApproveTable(String processInstanceId, OutputStream os) throws IOException, DocumentException {
      FlowProgramProperties props = flowCommonService.getProgramPropertiesFromHis(processInstanceId);
      TemplatedPdfWriter pdfWriter = new TemplatedPdfWriter(getTemplateBytes());
      pdfWriter.write(getPdfData(props),os);
   }
   /**
    * 获取pdf模板的字节数组
    * @return 模板字节数组
    * @throws IOException
    */
   private byte[] getTemplateBytes() throws IOException {
      String tplOssName = paramService.approveTableTemplateOssFileName();
      try (InputStream inputStream = this.ossTemplate.statFileStream(tplOssName)) {
         return inputStream.readAllBytes();
      }
   }
   /**
    * 获取填充数据
    */
   Map<String,String> getPdfData(FlowProgramProperties props){
      ApproveTableInfo approveInfo = approveInfoQueryService.getApproveInfo(props);
      Machine machine;
      String machineCode = props.getMachineCode();
      machine = machineService.getByCode(machineCode);
      Map<String,String> pdfData = new HashMap<>();
      pdfData.put("drawingNo",props.getDrawingNo());
      pdfData.put("processNo",props.getProcessNo());
      pdfData.put("craftEdition",props.getCraftEdition());
      pdfData.put("machineMode",machine.getName());
      String DATE_PATTERN = "yyyy-M-d";
      String dispatchDateStr = " ";
      if (approveInfo.getDispatchDate() != null) {
         dispatchDateStr = DateUtil.format(approveInfo.getDispatchDate(), DATE_PATTERN);
      }
      pdfData.put("teamLeader",approveInfo.getTeamLeaderName()+"/"+dispatchDateStr);
      if(StringUtils.equals(props.getHasCuredProgram(),FlowContants.Y)){
         pdfData.put("fuzeren",approveInfo.getCheckerName());
         pdfData.put("checkY","Y");//固化,属于校对任务
      }else{
         pdfData.put("fuzeren",approveInfo.getProgrammerName());//负责人
         pdfData.put("programY","Y");//其他,属于编制任务
      }
      pdfData.put("fangzhenY","Y");
      pdfData.put("programNo",approveInfo.getProgramNo());
      Date programDate = approveInfo.getCheckDate();
      Date checkDate = approveInfo.getCheckDate();
      String pDateStr = " ";
      if (programDate != null) {
         pDateStr = DateUtil.format(programDate, DATE_PATTERN);
      }
      String checkDateStr = " ";
      if (checkDate != null) {
         checkDateStr = DateUtil.format(programDate, DATE_PATTERN);
      }
      String approveDateStr = " ";
      if (approveInfo.getApproveDate() != null) {
         approveDateStr = DateUtil.format(approveInfo.getApproveDate(), DATE_PATTERN);
      }
      pdfData.put("programmer",approveInfo.getProgrammerName()+"/"+pDateStr);
      pdfData.put("checker",approveInfo.getCheckerName()+"/"+checkDateStr);
      pdfData.put("senior",approveInfo.getSeniorName()+"/"+approveDateStr);
      pdfData.put("sendDir",machine.getProgSendDir()!=null?machine.getProgSendDir():"");
      return pdfData;
   }
   /*
   public void exportApproveTableOld(String processInstanceId, OutputStream os) throws DocumentException, IOException {
      BaseFont bfChinese = getBaseFont();
      Document document = new Document(PageSize.B5.rotate());
      PdfWriter.getInstance(document,os);
      PdfWriter.getInstance(document, os);
      document.open();
      List<ApproveRecord> records = approveRecordService.lambdaQuery().eq(ApproveRecord::getProcessInstanceId, processInstanceId).orderByAsc(ApproveRecord::getCreateTime).list();
      for(int i=0;i<records.size();i++){
      FlowProgramProperties props = flowCommonService.getProgramPropertiesFromHis(processInstanceId);
         ApproveRecord record = records.get(i);
         if(record.getNcNodeId() ==null){
            //continue;
         }
      ApproveTableInfo appInfo = getApproveInfo(props);
      Machine machine;
      String machineCode = props.getMachineCode();
      machine = machineService.getByCode(machineCode);
         HistoricProcessInstance ins = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).includeProcessVariables().singleResult();
         List<HistoricActivityInstance> activitiys = historyService.createHistoricActivityInstanceQuery()
            .processInstanceId(processInstanceId)
            .list();
         printStep(document,bfChinese,record,ins);
         if(i<records.size()-1){
            document.newPage();
         }
      }
      int flag = props.getProcessDefinitionKey().equals(FlowContants.TRY_PROCESS_KEY)?1:2;
      printPage(document, bfChinese, props, machine, flag, appInfo);
      //document.newPage();
      //printPage(document, bfChinese, props, machine, 2, appInfo);
      document.close();
   }
   void printStep(Document document,BaseFont bfChinese,ApproveRecord record,HistoricProcessInstance ins) throws DocumentException, IOException {
      NcNode programPackageNode;
      Machine machine;
      Map<String,Object> vars = ins.getProcessVariables();
      //activitiy.stream().filter(HistoricActivityInstance::get)
      if(record.getNcNodeId() !=null ) {
         //programPackageNode = ncNodeService.getById(record.getNcNodeId());
         String machineCode = String.valueOf(vars.get(FlowContants.MACHINE_CODE));
         //machine = machineService.getByCode(programPackageNode.getMachineCode());
         machine = machineService.getByCode(machineCode);
      }else{
         programPackageNode = new NcNode();
         machine = new Machine();
      }
      Font titleFont = new Font(bfChinese, 14, Font.NORMAL);
      Paragraph title = new Paragraph("数控程序编制审批单",titleFont);
      title.setAlignment(Element.ALIGN_CENTER);
      title.setLeading(40f, 0f);
      title.setSpacingAfter(10); // 段后间距
      document.add(title);
      // 创建表格(4列)
      PdfPTable table = new PdfPTable(5);
      table.setWidths(new float[]{2,1.2f, 1.2f, 1.2f,2});
      Font ft = this.getChineseFont();
      // 添加表头
      PdfPCell tempCell = new PdfPCell();//getCell("零组件号");
      tempCell.setHorizontalAlignment(Element.ALIGN_CENTER);
      tempCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
      Phrase pt1 = new Phrase("零组件号",ft);
      tempCell.setPhrase(pt1);
      //tempCell.addElement(pt1);
      //
      table.addCell(tempCell);
      table.addCell(getCell("工序号",ft));
      table.addCell(getCell("工艺版次",ft));
      table.addCell(getCell("机床型号",ft));
      table.addCell(getCell("工段负责人/单元负\n责人派出时间",ft));
      //PdfPCell cell12 = new PdfPCell();
      //cell12.setColspan(2);
      //cell12.addElement(new Phrase(ncProgram.getDrawingNo()));
      String drawingNo = vars.get(FlowContants.DRAWING_NO)+"";
      table.addCell(getCell(drawingNo,ft));//零组件号
      String processNo = vars.get(FlowContants.PROCESS_NO)+"";
      table.addCell(getCell(processNo,ft));//工序号
      String craftEdition = vars.get(FlowContants.CRAFT_EDITION)+"";
      table.addCell(getCell(craftEdition,ft));//工艺版次
      table.addCell(getCell(machine.getName(),ft));//机床型号
      table.addCell("");//负责人,工段负责人派出时间
      //中间大格
      PdfPCell cell = new PdfPCell();
      cell.setColspan(5);
      cell.setCalculatedHeight(400);
      Paragraph mainPara1 = new Paragraph();
      mainPara1.setLeading(30f, 0f);
      mainPara1.setFont(ft);
      mainPara1.setAlignment(Element.ALIGN_LEFT); // 对齐方式
      mainPara1.setIndentationLeft(20); // 左缩进(像素)
      mainPara1.setIndentationRight(20); // 右缩进
      mainPara1.setSpacingBefore(10); // 段前间距
      mainPara1.setSpacingAfter(10); // 段后间距
      mainPara1.add("数控程序编制任务安排:\n");
      cell.addElement(mainPara1);
      Paragraph line2Para = new Paragraph();
      line2Para.setLeading(30f, 0f);
      line2Para.setFont(ft);
      line2Para.setAlignment(Element.ALIGN_LEFT); // 对齐方式
      line2Para.setIndentationLeft(40); // 左缩进(像素)
      line2Para.add("请");
      Font underLineFt = new Font(bfChinese, 12, Font.UNDERLINE);
      String personName = record.getUserNickname();
      Chunk block1 = square;
      Chunk block2 = square;
      Date programDate = null;
      Date checkDate = null;
      if(StringUtils.equals(record.getTaskDefinitionKey(),"programmingTask")){
         block1 = check;
         programDate = record.getCreateTime();
      }else if(StringUtils.equals(record.getTaskDefinitionKey(),"check")){
         block2 = check;
         checkDate = record.getCreateTime();
      }
      Phrase p = new Phrase("       "+personName+"        ",underLineFt);
      line2Para.add(p);
      Phrase p2 = new Phrase("负责数控程序(编制");
      p2.add(block1);
      p2.add(new Chunk("   校对",ft));
      p2.add(block2);
      p2.add(new Chunk(")",ft));
      line2Para.add(p2);
      cell.addElement(line2Para);
      Paragraph fangzhen = new Paragraph();
      fangzhen.setAlignment(Element.ALIGN_LEFT); // 对齐方式
      fangzhen.setIndentationLeft(20); // 左缩进(像素)
      fangzhen.setIndentationRight(20); // 右缩进
      fangzhen.setSpacingBefore(10); // 段前间距
      fangzhen.setSpacingAfter(10); // 段后间距
      fangzhen.setFont(ft);
      fangzhen.setLeading(30f, 0f);
      fangzhen.add("是否需要仿真(是");
      fangzhen.add(square);
      fangzhen.add(";否");
      fangzhen.add(square);
      fangzhen.add(")\n");
      cell.addElement(fangzhen);
      table.addCell(cell);
      //下一行
      PdfPCell cell21 = getCell("数控程序编号",ft);// PdfPCell();
      cell21.setColspan(2);
      //cell21.setPhrase(new Phrase("数控程序编号",ft));
      table.addCell(cell21);
      table.addCell(getCell("编制/日期",ft));
      table.addCell(getCell("校对/日期",ft));
      table.addCell(getCell("批准/日期",ft));
      PdfPCell cell2 = new PdfPCell();
      cell2.setColspan(2);
      //cell2.addElement(new Phrase(programPackageNode.getProgramNo(),ft));//数控程序编号
      cell2.addElement(new Phrase("00001",ft));
      table.addCell(cell2);
      String pDateStr = " ";
      if(programDate!=null){
         pDateStr = DateUtil.format(programDate,"yyyy-MM-dd");
      }
      String checkDateStr = " ";
      if(checkDate!=null){
         checkDateStr = DateUtil.format(programDate,"yyyy-MM-dd");
      }
      table.addCell(getCell(pDateStr,ft));//编制日期
      table.addCell(getCell(checkDateStr,ft));
      table.addCell(getCell(" ",ft));
      // 设置表格宽度占页面宽度的100%
      table.setWidthPercentage(100);
      // 添加表格到文档
      document.add(table);
      Phrase lastPhrase = new Phrase("注:工段派工应预先计划、合理安排数控程序编制。立加、数铣、数车等单道工序程序(两轴程序)需提前1个工作日,卧式加工中心单道工序(含多轴程序)需提前3个工作日。 ",ft);
      document.add(lastPhrase);
   }
   PdfPCell getCell(String text,Font font) throws DocumentException, IOException {
      PdfPCell cell = new PdfPCell();
      cell.setPadding(10);
      cell.setHorizontalAlignment(Element.ALIGN_CENTER);
      cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
      if(StringUtils.isNotBlank(text)){
         Phrase p = new Phrase(text,font);
         p.setLeading(25);
         cell.setPhrase(p);
      }
      return cell;
   }
   */
}