优化
This commit is contained in:
@@ -21,7 +21,8 @@ public enum EsignConfigConstants {
|
|||||||
ESIGN_APP_SECRETMAP("325c8cc6c2a303d6cf1fb5657a16e591","e签宝appIDSecret映射"),
|
ESIGN_APP_SECRETMAP("325c8cc6c2a303d6cf1fb5657a16e591","e签宝appIDSecret映射"),
|
||||||
ENABLEANTIFAKESIGN("","是否加盖防伪章"),
|
ENABLEANTIFAKESIGN("","是否加盖防伪章"),
|
||||||
FIXAPPUNIT("true","是否固定要用的E签宝应用主体单位"),
|
FIXAPPUNIT("true","是否固定要用的E签宝应用主体单位"),
|
||||||
FIXAPPUNITNAME("","固定要用的E签宝应用主体单位名称")
|
FIXAPPUNITNAME("","固定要用的E签宝应用主体单位名称"),
|
||||||
|
SIGNPARAM_LOG_URL("","E签宝参数记录路径"),
|
||||||
;
|
;
|
||||||
|
|
||||||
private String defaultValue;
|
private String defaultValue;
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ import java.util.Map;
|
|||||||
|
|
||||||
public class EsignParamRecordUtils {
|
public class EsignParamRecordUtils {
|
||||||
|
|
||||||
public static void saveEsignParamRecord(Map<String,Object> params) {
|
public static void saveEsignParamRecord(String logFileUrl,Map<String,Object> params) {
|
||||||
try {
|
try {
|
||||||
String str = "/home/seeyon/Seeyon/A8/ApacheJetspeed/logs_sy";
|
String str = logFileUrl;
|
||||||
String date = DateUtil.format(new Date(), "yyyyMMddHHmmss");
|
String date = DateUtil.format(new Date(), "yyyyMMddHHmmss");
|
||||||
FileUtils.writeStringToFile(new File(str+"/esignParams/" + date + ".json"), JsonUtils.toJSONString(params), "UTF-8");
|
FileUtils.writeStringToFile(new File(str+ File.separator + "esignParams" + File.separator + date + ".json"), JsonUtils.toJSONString(params), "UTF-8");
|
||||||
}catch (Exception e){
|
}catch (Exception e){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ public class A4CheckNode extends ACommonSuperNode {
|
|||||||
String errMsg = "上传的附件中" + file.getName() +"非标准A4格式的,请修改后再上传(标准A4为21:29)";
|
String errMsg = "上传的附件中" + file.getName() +"非标准A4格式的,请修改后再上传(标准A4为21:29)";
|
||||||
formDataVo.getNewFieldDataMap().put("合同审批附件格式校验结果", errMsg);
|
formDataVo.getNewFieldDataMap().put("合同审批附件格式校验结果", errMsg);
|
||||||
return context.back(errMsg);
|
return context.back(errMsg);
|
||||||
|
}else {
|
||||||
|
formDataVo.getNewFieldDataMap().put("合同审批附件格式校验结果", "");
|
||||||
}
|
}
|
||||||
file.delete();
|
file.delete();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ public class EsignMultipleSignerNode extends ACommonSuperNode {
|
|||||||
aParty.setPartyId("甲方");
|
aParty.setPartyId("甲方");
|
||||||
aParty.setSignOrder(2);
|
aParty.setSignOrder(2);
|
||||||
aParty.setSignerType(SignerType.ORG);
|
aParty.setSignerType(SignerType.ORG);
|
||||||
aParty.setSealId(getStringField(formDataVo,"选择甲方印章"));
|
aParty.setSealId(getStringField(formDataVo,"甲方印章ID"));
|
||||||
aParty.setAutoSign(doAutoSign);
|
aParty.setAutoSign(doAutoSign);
|
||||||
OrgInfo orgInfo = new OrgInfo();
|
OrgInfo orgInfo = new OrgInfo();
|
||||||
aParty.setOrgInfo(orgInfo);
|
aParty.setOrgInfo(orgInfo);
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ public class EsignOneSignerNode extends ACommonSuperNode {
|
|||||||
aParty.setSignOrder(2);
|
aParty.setSignOrder(2);
|
||||||
aParty.setSignerType(SignerType.ORG);
|
aParty.setSignerType(SignerType.ORG);
|
||||||
aParty.setAutoSign(doAutoSign);
|
aParty.setAutoSign(doAutoSign);
|
||||||
aParty.setSealId(getStringField(formDataVo,"选择甲方印章"));
|
aParty.setSealId(getStringField(formDataVo,"甲方印章ID"));
|
||||||
OrgInfo orgInfo = new OrgInfo();
|
OrgInfo orgInfo = new OrgInfo();
|
||||||
orgInfo.setOrgName(orgName);
|
orgInfo.setOrgName(orgName);
|
||||||
aParty.setOrgInfo(orgInfo);
|
aParty.setOrgInfo(orgInfo);
|
||||||
|
|||||||
@@ -321,7 +321,7 @@ public class DefaultSignerBuilder implements SignerBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询文件总页数
|
* 查询文件总页数,查询失败或页数为0时返回默认值10
|
||||||
*/
|
*/
|
||||||
private Integer getFileTotalPage(String fileId, String appId) {
|
private Integer getFileTotalPage(String fileId, String appId) {
|
||||||
try {
|
try {
|
||||||
@@ -336,14 +336,18 @@ public class DefaultSignerBuilder implements SignerBuilder {
|
|||||||
EsignBaseResp resp = JsonUtils.parseObject(respStr, EsignBaseResp.class);
|
EsignBaseResp resp = JsonUtils.parseObject(respStr, EsignBaseResp.class);
|
||||||
|
|
||||||
if (!"0".equals(String.valueOf(resp.getCode()))) {
|
if (!"0".equals(String.valueOf(resp.getCode()))) {
|
||||||
throw new RuntimeException("查询文件上传状态失败:" + resp.getMessage());
|
return 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, Object> data = (Map<String, Object>) resp.getData();
|
Map<String, Object> data = (Map<String, Object>) resp.getData();
|
||||||
Object pageCount = data.get("fileTotalPageCount");
|
Object pageCount = data.get("fileTotalPageCount");
|
||||||
return pageCount == null ? 10 : Integer.parseInt(String.valueOf(pageCount));
|
if (pageCount == null) {
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
int pages = Integer.parseInt(String.valueOf(pageCount));
|
||||||
|
return pages > 0 ? pages : 10;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("获取文件页数异常", e);
|
return 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.seeyon.aicloud.common.JsonUtils;
|
|||||||
import com.seeyon.apps.esign.config.EsignConfigProvider;
|
import com.seeyon.apps.esign.config.EsignConfigProvider;
|
||||||
import com.seeyon.apps.esign.constants.EsignApiUrl;
|
import com.seeyon.apps.esign.constants.EsignApiUrl;
|
||||||
import com.seeyon.apps.esign.constants.EsignConfigConstants;
|
import com.seeyon.apps.esign.constants.EsignConfigConstants;
|
||||||
|
import com.seeyon.apps.esign.logfile.EsignParamRecordUtils;
|
||||||
import com.seeyon.apps.esign.po.esignapi.EsignApiHeader;
|
import com.seeyon.apps.esign.po.esignapi.EsignApiHeader;
|
||||||
import com.seeyon.apps.esign.po.esignapi.EsignBaseResp;
|
import com.seeyon.apps.esign.po.esignapi.EsignBaseResp;
|
||||||
import com.seeyon.apps.esign.utils.HttpClient;
|
import com.seeyon.apps.esign.utils.HttpClient;
|
||||||
@@ -42,6 +43,7 @@ public class EsignByTemplateService {
|
|||||||
esignApiHeader.token(tokenCacheManager.getToken(appId)).appId(appId);
|
esignApiHeader.token(tokenCacheManager.getToken(appId)).appId(appId);
|
||||||
String url = configProvider.getBizConfigByKey(EsignConfigConstants.ESIGN_HOST) + EsignApiUrl.SIGN_BY_FILE_URL;
|
String url = configProvider.getBizConfigByKey(EsignConfigConstants.ESIGN_HOST) + EsignApiUrl.SIGN_BY_FILE_URL;
|
||||||
log.info("合同发起入参: " + jsonBody);
|
log.info("合同发起入参: " + jsonBody);
|
||||||
|
EsignParamRecordUtils.saveEsignParamRecord(configProvider.getBizConfigByKey(EsignConfigConstants.SIGNPARAM_LOG_URL),params);
|
||||||
String respStr = HttpClient.httpPostRaw(url, jsonBody, esignApiHeader.convert2Headers(), "UTF-8");
|
String respStr = HttpClient.httpPostRaw(url, jsonBody, esignApiHeader.convert2Headers(), "UTF-8");
|
||||||
EsignBaseResp esignBaseResp = JsonUtils.parseObject(respStr, EsignBaseResp.class);
|
EsignBaseResp esignBaseResp = JsonUtils.parseObject(respStr, EsignBaseResp.class);
|
||||||
Map<String,Object> dataMap = (Map<String, Object>) esignBaseResp.getData();
|
Map<String,Object> dataMap = (Map<String, Object>) esignBaseResp.getData();
|
||||||
|
|||||||
@@ -4,13 +4,16 @@ import org.apache.pdfbox.pdmodel.PDDocument;
|
|||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
import org.apache.poi.hwpf.HWPFDocument;
|
import org.apache.poi.hwpf.HWPFDocument;
|
||||||
import org.apache.poi.hwpf.usermodel.Section;
|
import org.apache.poi.hwpf.usermodel.Section;
|
||||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
import org.w3c.dom.Document;
|
||||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageSz;
|
import org.w3c.dom.Element;
|
||||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
|
import org.w3c.dom.Node;
|
||||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STPageOrientation;
|
import org.w3c.dom.NodeList;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipInputStream;
|
||||||
|
|
||||||
public class DocumentA4Checker {
|
public class DocumentA4Checker {
|
||||||
|
|
||||||
@@ -60,7 +63,7 @@ public class DocumentA4Checker {
|
|||||||
/**
|
/**
|
||||||
* 校验 PDF 第一页是否竖版 A4
|
* 校验 PDF 第一页是否竖版 A4
|
||||||
*/
|
*/
|
||||||
private static boolean checkPdfFirstPageA4(InputStream in) throws IOException {
|
private static boolean checkPdfFirstPageA4(InputStream in) throws Exception {
|
||||||
try (PDDocument document = PDDocument.load(in)) {
|
try (PDDocument document = PDDocument.load(in)) {
|
||||||
if (document.getNumberOfPages() == 0) return false;
|
if (document.getNumberOfPages() == 0) return false;
|
||||||
|
|
||||||
@@ -76,7 +79,7 @@ public class DocumentA4Checker {
|
|||||||
/**
|
/**
|
||||||
* 校验 doc 第一页是否竖版 A4
|
* 校验 doc 第一页是否竖版 A4
|
||||||
*/
|
*/
|
||||||
private static boolean checkDocFirstPageA4(InputStream in) throws IOException {
|
private static boolean checkDocFirstPageA4(InputStream in) throws Exception {
|
||||||
try (HWPFDocument doc = new HWPFDocument(in)) {
|
try (HWPFDocument doc = new HWPFDocument(in)) {
|
||||||
Section section = doc.getRange().getSection(0);
|
Section section = doc.getRange().getSection(0);
|
||||||
|
|
||||||
@@ -92,42 +95,87 @@ public class DocumentA4Checker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验 docx 第一页是否竖版 A4(POI 5.x 兼容版)
|
* 校验 docx 第一页是否竖版 A4
|
||||||
|
* 直接读取 ZIP 中的 word/document.xml,不依赖 POI ooxml 模块
|
||||||
*/
|
*/
|
||||||
public static boolean isDocxA4Portrait(InputStream in) throws IOException {
|
public static boolean isDocxA4Portrait(InputStream in) {
|
||||||
try (XWPFDocument docx = new XWPFDocument(in)) {
|
try {
|
||||||
CTSectPr sectPr = docx.getDocument().getBody().getSectPr();
|
byte[] docXml = extractDocXml(in);
|
||||||
if (sectPr == null || sectPr.getPgSz() == null) {
|
if (docXml == null) {
|
||||||
// 没有设置页面大小 → 默认认为是A4(Word默认行为)
|
|
||||||
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float wPt = wTwips.floatValue() / TWIPS_TO_PT;
|
// 不启用 namespace-aware,元素名带 w: 前缀(如 w:pgSz)
|
||||||
float hPt = hTwips.floatValue() / TWIPS_TO_PT;
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||||
|
Document doc = factory.newDocumentBuilder()
|
||||||
|
.parse(new ByteArrayInputStream(docXml));
|
||||||
|
|
||||||
|
// 递归搜索 w:pgSz 元素(sectPr 下的页面尺寸定义)
|
||||||
|
Element pgSz = findElement(doc.getDocumentElement(), "w:pgSz");
|
||||||
|
if (pgSz == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
String orient = pgSz.getAttribute("w:orient");
|
||||||
|
if ("landscape".equalsIgnoreCase(orient)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
String wStr = pgSz.getAttribute("w:w");
|
||||||
|
String hStr = pgSz.getAttribute("w:h");
|
||||||
|
if (wStr == null || wStr.isEmpty() || hStr == null || hStr.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float wPt = Long.parseLong(wStr) / TWIPS_TO_PT;
|
||||||
|
float hPt = Long.parseLong(hStr) / TWIPS_TO_PT;
|
||||||
|
|
||||||
return Math.abs(wPt - A4_WIDTH) <= TOLERANCE
|
return Math.abs(wPt - A4_WIDTH) <= TOLERANCE
|
||||||
&& Math.abs(hPt - A4_HEIGHT) <= TOLERANCE;
|
&& Math.abs(hPt - A4_HEIGHT) <= TOLERANCE;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从 docx ZIP 中提取 word/document.xml 的字节内容
|
||||||
|
*/
|
||||||
|
private static byte[] extractDocXml(InputStream in) throws IOException {
|
||||||
|
try (ZipInputStream zis = new ZipInputStream(in)) {
|
||||||
|
ZipEntry entry;
|
||||||
|
while ((entry = zis.getNextEntry()) != null) {
|
||||||
|
if ("word/document.xml".equals(entry.getName())) {
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
byte[] buf = new byte[4096];
|
||||||
|
int len;
|
||||||
|
while ((len = zis.read(buf)) != -1) {
|
||||||
|
bos.write(buf, 0, len);
|
||||||
|
}
|
||||||
|
return bos.toByteArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递归查找指定 tagName 的元素
|
||||||
|
*/
|
||||||
|
private static Element findElement(Node node, String tagName) {
|
||||||
|
if (node.getNodeType() == Node.ELEMENT_NODE && tagName.equals(node.getNodeName())) {
|
||||||
|
return (Element) node;
|
||||||
|
}
|
||||||
|
NodeList children = node.getChildNodes();
|
||||||
|
for (int i = 0; i < children.getLength(); i++) {
|
||||||
|
Element result = findElement(children.item(i), tagName);
|
||||||
|
if (result != null) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private static String getFileSuffix(String fileName) {
|
private static String getFileSuffix(String fileName) {
|
||||||
int idx = fileName.lastIndexOf('.');
|
int idx = fileName.lastIndexOf('.');
|
||||||
return idx == -1 ? "" : fileName.substring(idx + 1);
|
return idx == -1 ? "" : fileName.substring(idx + 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user