|
package org.springblade.mdm.flow.service;
|
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.lang3.StringUtils;
|
import org.flowable.engine.HistoryService;
|
import org.flowable.engine.history.HistoricProcessInstance;
|
import org.flowable.engine.runtime.ProcessInstance;
|
import org.flowable.task.api.history.HistoricTaskInstance;
|
import org.springblade.core.tool.api.R;
|
import org.springblade.core.tool.utils.DateUtil;
|
import org.springblade.core.tool.utils.Func;
|
import org.springblade.mdm.basesetting.machine.MachineService;
|
import org.springblade.mdm.basesetting.machine.entity.Machine;
|
import org.springblade.mdm.flow.constants.FlowContants;
|
import org.springblade.mdm.flow.vo.ApproveTableInfo;
|
import org.springblade.mdm.program.entity.NcNode;
|
import org.springblade.mdm.program.entity.NcProgramApproved;
|
import org.springblade.mdm.program.service.NcNodeService;
|
import org.springblade.mdm.program.service.NcProgramApprovedService;
|
import org.springblade.system.feign.IUserClient;
|
import org.springblade.system.pojo.entity.User;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
|
import java.io.IOException;
|
import java.io.OutputStream;
|
import java.util.Date;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.Optional;
|
|
import com.itextpdf.text.*;
|
import com.itextpdf.text.pdf.*;
|
/**
|
* 审批记录,用于查询执行轨迹
|
*
|
* @author yangys
|
*/
|
@Slf4j
|
@Service
|
public class ApproveTableService {
|
@Autowired
|
private FlowCommonService flowCommonService;
|
@Autowired
|
private NcNodeService ncNodeService;
|
@Autowired
|
private MachineService machineService;
|
@Autowired
|
private HistoryService historyService;
|
@Autowired
|
private IUserClient useClient;
|
@Autowired
|
private NcProgramApprovedService programApprovedService;
|
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);
|
}
|
|
public void exportApproveTable(String processInstanceId, OutputStream os) throws DocumentException, IOException {
|
|
BaseFont bfChinese = getBaseFont();
|
|
Document document = new Document(PageSize.B5.rotate());
|
PdfWriter.getInstance(document, os);
|
|
document.open();
|
|
FlowProgramProperties props = flowCommonService.getProgramPropertiesFromHis(processInstanceId);
|
|
ApproveTableInfo appInfo = getApproveInfo(props);
|
Machine machine;
|
String machineCode = props.getMachineCode();
|
machine = machineService.getByCode(machineCode);
|
|
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();
|
}
|
|
|
|
/**
|
* 打印一个步骤(编制/校对)
|
* @param document
|
* @param bfChinese
|
* @param props
|
* @param machine
|
* @param flag
|
* @param approveInfo
|
* @throws DocumentException
|
* @throws IOException
|
*/
|
void printPage(Document document, BaseFont bfChinese, FlowProgramProperties props, Machine machine, int flag, ApproveTableInfo approveInfo) throws DocumentException, IOException {
|
Font tipFont = new Font(bfChinese, 10, Font.NORMAL);
|
Paragraph tip = new Paragraph("艺表6", tipFont);
|
tip.setAlignment(Element.ALIGN_RIGHT);
|
tip.setSpacingAfter(-5); // 段后间距
|
tip.setIndentationRight(220f);
|
|
// 设置行距(行间距)
|
//mixedParagraph.setLeading(24f); // 绝对行距
|
//mixedParagraph.setLeading(1.5f, 2f);
|
// 也可以使用相对行距:mixedParagraph.setLeading(1.5f, 24f);
|
// 第一个参数是文本高度的倍数,第二个参数是额外的固定行距
|
|
Font titleFont = new Font(bfChinese, 14, Font.NORMAL);
|
Paragraph title = new Paragraph("数控程序审批单", titleFont);
|
//title.setLeading(40f, 0f);
|
tip.setSpacingBefore(-0.5f);
|
title.setSpacingAfter(10); // 段后间距
|
title.setAlignment(Element.ALIGN_CENTER);
|
title.setPaddingTop(-0.6f);
|
|
Paragraph mixedParagraph = new Paragraph();
|
mixedParagraph.add(tip);
|
mixedParagraph.add(title);
|
mixedParagraph.setSpacingAfter(10);
|
document.add(mixedParagraph);
|
|
|
//document.add(title);
|
// 创建表格(4列)
|
PdfPTable table = new PdfPTable(5);
|
table.setWidths(new float[]{1.5f, 1.4f, 1.4f, 1.4f, 1.5f});
|
|
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));
|
|
|
table.addCell(getCell(props.getDrawingNo(), ft));//零组件号
|
|
table.addCell(getCell(props.getProcessNo(), ft));//工序号
|
|
table.addCell(getCell(props.getCraftEdition(), ft));//工艺版次
|
table.addCell(getCell(machine.getName(), ft));//机床型号
|
table.addCell(getCell(approveInfo.getTeamLeaderName(), ft));//负责人,工段负责人派出时间
|
|
//中间大格
|
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 = check;
|
Date programDate = approveInfo.getProgrammingDate(); //TODO 查询时间
|
Date checkDate = approveInfo.getCheckDate();
|
|
Phrase p;
|
if (1 == flag) {
|
p = new Phrase(" " + approveInfo.getProgrammerName() + " ", underLineFt);
|
} else {
|
p = new Phrase(" " + approveInfo.getCheckerName() + " ", underLineFt);
|
}
|
line2Para.add(p);
|
|
Phrase p2 = new Phrase("负责数控程序(编制");
|
if (flag == 1) {
|
p2.add(block2);
|
p2.add(new Chunk(" 校对", ft));
|
p2.add(block1);
|
} else {
|
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(check);//固定是仿真
|
fangzhen.add(" 否");
|
fangzhen.add(square);
|
fangzhen.add(")\n\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 = getCell("00001", ft);
|
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");
|
}
|
|
String approveDateStr = " ";
|
if (approveInfo.getApproveDate() != null) {
|
approveDateStr = DateUtil.format(approveInfo.getApproveDate(), "yyyy-MM-dd");
|
}
|
table.addCell(getCell(approveInfo.getProgrammerName()+" " +pDateStr, ft));//编制/日期
|
table.addCell(getCell(approveInfo.getCheckerName()+" " +checkDateStr, ft));
|
table.addCell(getCell(approveInfo.getSeniorName()+" " +approveDateStr, ft));
|
|
PdfPCell sendPathCell = getCell("数控程序传输路径:" + (machine.getProgSendDir() == null ? "" : machine.getProgSendDir()), ft);// PdfPCell();
|
sendPathCell.setHorizontalAlignment(Element.ALIGN_LEFT);
|
sendPathCell.setColspan(5);
|
table.addCell(sendPathCell);
|
|
// 设置表格宽度占页面宽度的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;
|
}
|
|
ApproveTableInfo getApproveInfo(FlowProgramProperties props){
|
//编制
|
R<User> leaderR = useClient.userInfoById(props.getTeamLeaderId());
|
String leaderName = "";
|
if (leaderR.isSuccess()) {
|
leaderName = leaderR.getData().getName();
|
}
|
//编制
|
R<User> programmerR = useClient.userInfoById(props.getProgrammerId());
|
String programmerName = "";
|
if (programmerR.isSuccess()) {
|
programmerName = programmerR.getData().getName();
|
}
|
Machine machine;
|
String machineCode = props.getMachineCode();
|
machine = machineService.getByCode(machineCode);
|
|
//校对
|
R<User> checkerR = useClient.userInfoById(props.getCheckerId());
|
String checkerName = "";
|
if (checkerR.isSuccess()) {
|
checkerName = checkerR.getData().getName();
|
}
|
//审核
|
R<User> seniorR = useClient.userInfoById(props.getCheckerId());
|
String senioirName = "";
|
if (seniorR.isSuccess()) {
|
senioirName = seniorR.getData().getName();
|
}
|
ApproveTableInfo appInfo = new ApproveTableInfo();
|
appInfo.setTeamLeaderName(leaderName);
|
appInfo.setProgrammerName(programmerName);
|
appInfo.setCheckerName(checkerName);
|
appInfo.setSeniorName(senioirName);
|
|
//获取时间信息
|
List<HistoricTaskInstance> hisTasks = historyService.createHistoricTaskInstanceQuery()
|
.processInstanceId(props.getProcessInstanceId()).orderByTaskCreateTime().desc().list();
|
|
for(HistoricTaskInstance task : hisTasks){
|
if(appInfo.getProgrammingDate()== null && task.getTaskDefinitionKey().contains("program")){
|
appInfo.setProgrammingDate(task.getEndTime());
|
}
|
|
if(appInfo.getCheckDate()== null && task.getTaskDefinitionKey().contains("check")){
|
appInfo.setCheckDate(task.getEndTime());
|
}
|
|
if(appInfo.getApproveDate()== null && task.getTaskDefinitionKey().contains("approve")){
|
appInfo.setApproveDate(task.getEndTime());
|
}
|
}
|
|
//查询数控程序编号
|
Optional<NcProgramApproved> appOpt = programApprovedService.lambdaQuery().eq(NcProgramApproved::getProcessInstanceId, props.getProcessInstanceId()).oneOpt();
|
if(appOpt.isEmpty()){
|
appInfo.setProgramNo("(未生成)");
|
}else{
|
NcNode programPkgNameNode = this.ncNodeService.getById(appOpt.get().getNcNodeId());
|
appInfo.setProgramNo(programPkgNameNode.getProgramNo());
|
}
|
return appInfo;
|
}
|
|
}
|