优化代码

This commit is contained in:
2026-06-15 22:32:59 +08:00
parent 907342adb4
commit 61200a3a77
4 changed files with 212 additions and 0 deletions

BIN
extLib/poi-ooxml-5.4.1.jar Normal file

Binary file not shown.

View File

@@ -22,6 +22,7 @@
<bean id="esignCallbackFlowBizService" class="com.seeyon.apps.esign.service.EsignCallbackFlowBizService"/>
<!-- 注入数组类型的Bean -->
<bean id="esignPluginApi" class="com.seeyon.apps.esign.EsignPluginApi"/>
<bean id="a4CheckNode" class="com.seeyon.apps.esign.node.A4CheckNode" />
<bean name="contractCreateService" class="com.seeyon.apps.esign.service.ContractCreateService">
<property name="signParamBuildFactories">
<list>

View File

@@ -0,0 +1,76 @@
package com.seeyon.apps.esign.node;
import com.seeyon.apps.common.workflow.node.ACommonSuperNode;
import com.seeyon.apps.esign.constants.EsignConfigConstants;
import com.seeyon.apps.esign.constants.FlowFormFieldConstants;
import com.seeyon.apps.esign.utils.DocumentA4Checker;
import com.seeyon.apps.esign.utils.FileUtil;
import com.seeyon.apps.ext.workflow.vo.FieldDataVo;
import com.seeyon.apps.ext.workflow.vo.FormDataVo;
import com.seeyon.apps.ext.workflow.vo.SuperNodeContext;
import com.seeyon.cap4.form.bean.FormDataMasterBean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.File;
import java.util.List;
public class A4CheckNode extends ACommonSuperNode {
private static final Log log = LogFactory.getLog(A4CheckNode.class);
@Override
public String getPluginId() {
return EsignConfigConstants.getPluginId();
}
@Override
public String getFormParse() {
return "";
}
@Override
public SuperNodeContext proceed(String s, FormDataVo formDataVo, FormDataMasterBean formDataMasterBean) throws Exception {
SuperNodeContext context = new SuperNodeContext();
context.setNeedSave(true);
log.info("进入文件A4格式校验超级节点");
try {
FieldDataVo fieldData = formDataVo.getFieldData(FlowFormFieldConstants.CONTRACT_APPROVAL_ATTACHMENT);
String attachmentId = fieldData.getStringValue();
if (attachmentId == null) throw new RuntimeException("合同文件不能为空");
String tempDir = System.getProperty("java.io.tmpdir");
File file = null;
FileUtil fileUtil = new FileUtil();
List<String> paths = fileUtil.fieldFileDownload(Long.parseLong(attachmentId), tempDir + File.separator + "oafile" + File.separator);
for (String path : paths) {
file = new File(path);
boolean firstPageA4 = DocumentA4Checker.isFirstPageA4(file);
if (!firstPageA4) {
String errMsg = "上传的附件中" + file.getName() +"非标准A4格式的请修改后再上传(标准A4为21:29)";
formDataVo.getNewFieldDataMap().put("合同审批附件格式校验结果", errMsg);
return context.back(errMsg);
}
file.delete();
}
return context.success("文件A4格式校验通过");
} catch (Exception e) {
log.error("校验产生错误", e);
e.printStackTrace();
context.setErrMsg("校验产生错误: " + e.getMessage());
return context.back("校验产生错误: " + e.getMessage());
}
}
@Override
public String getNodeId() {
return "nd_20260512";
}
@Override
public String getNodeName() {
return "A4格式校验节点";
}
}

View File

@@ -0,0 +1,135 @@
package com.seeyon.apps.esign.utils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.Section;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageSz;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STPageOrientation;
import java.io.*;
import java.util.Optional;
public class DocumentA4Checker {
// A4标准磅值 宽595 高842允许误差5pt
private static final float A4_WIDTH = 595.0f;
private static final float A4_HEIGHT = 842.0f;
private static final float TOLERANCE = 5.0f;
// twips 转 pt /20
private static final float TWIPS_TO_PT = 20.0f;
public static boolean isFirstPageA4(File file) {
if (file == null || !file.exists() || !file.isFile()) {
return false;
}
String fileName = Optional.ofNullable(file.getName()).orElse("");
String suffix = getFileSuffix(fileName).toLowerCase();
try {
switch (suffix) {
case "pdf":
try (InputStream in = new FileInputStream(file)) {
return checkPdfFirstPageA4(in);
}
case "doc":
// 先尝试 doc 解析,若文件实际为 OOXML 则回退到 docx
try (InputStream in = new FileInputStream(file)) {
return checkDocFirstPageA4(in);
} catch (IllegalArgumentException e) {
try (InputStream in = new FileInputStream(file)) {
return isDocxA4Portrait(in);
}
}
case "docx":
try (InputStream in = new FileInputStream(file)) {
return isDocxA4Portrait(in);
}
default:
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 校验 PDF 第一页是否竖版 A4
*/
private static boolean checkPdfFirstPageA4(InputStream in) throws IOException {
try (PDDocument document = PDDocument.load(in)) {
if (document.getNumberOfPages() == 0) return false;
PDPage page = document.getPage(0);
float w = page.getMediaBox().getWidth();
float h = page.getMediaBox().getHeight();
return Math.abs(w - A4_WIDTH) <= TOLERANCE
&& Math.abs(h - A4_HEIGHT) <= TOLERANCE;
}
}
/**
* 校验 doc 第一页是否竖版 A4
*/
private static boolean checkDocFirstPageA4(InputStream in) throws IOException {
try (HWPFDocument doc = new HWPFDocument(in)) {
Section section = doc.getRange().getSection(0);
int widthTwips = section.getPageWidth();
int heightTwips = section.getPageHeight();
float widthPt = widthTwips / 20f;
float heightPt = heightTwips / 20f;
return Math.abs(widthPt - A4_WIDTH) <= TOLERANCE
&& Math.abs(heightPt - A4_HEIGHT) <= TOLERANCE;
}
}
/**
* 校验 docx 第一页是否竖版 A4POI 5.x 兼容版)
*/
public static boolean isDocxA4Portrait(InputStream in) throws IOException {
try (XWPFDocument docx = new XWPFDocument(in)) {
CTSectPr sectPr = docx.getDocument().getBody().getSectPr();
if (sectPr == null || sectPr.getPgSz() == null) {
// 没有设置页面大小 → 默认认为是A4Word默认行为
return true;
}
CTPageSz pgSz = sectPr.getPgSz();
// 判断是否横向
if (pgSz.getOrient() != null) {
STPageOrientation.Enum orient = pgSz.getOrient();
if (STPageOrientation.LANDSCAPE.equals(orient)) {
return false;
}
}
// 兼容 BigInteger 和 BigDecimal 两种实现
Number wTwips = (Number) pgSz.getW();
Number hTwips = (Number) pgSz.getH();
if (wTwips == null || hTwips == null) {
return false;
}
float wPt = wTwips.floatValue() / TWIPS_TO_PT;
float hPt = hTwips.floatValue() / TWIPS_TO_PT;
return Math.abs(wPt - A4_WIDTH) <= TOLERANCE
&& Math.abs(hPt - A4_HEIGHT) <= TOLERANCE;
}
}
private static String getFileSuffix(String fileName) {
int idx = fileName.lastIndexOf('.');
return idx == -1 ? "" : fileName.substring(idx + 1);
}
}