init: WordFileParse docx→HTML 解析服务(含 Word EQ 域公式修复)

服务:Spring Boot 3.2 + docx4j 8.3.9,POST /api/v3/server_office_file/file/parse
      接受 .docx,返回 HTML(公式 → LaTeX,图片 → RustFS 外链)

公式支持三类来源:
- OMML(Word 2007+ 公式)      → Python omml_mathml2latex
- MathType OLE 对象            → Ruby mathtype2mathml → MathML → LaTeX
- Word EQ 域(老教辅主力)      → EqToLatexUtil(本次新增)

本次改动:
1. 新增 java-svc/.../core/EqToLatexUtil.java:
   移植自 jby backend-services office-core,EQ 语法 → LaTeX
   (\f→\dfrac、\r→\sqrt、\i→\int/\sum/\prod、\s→^{}/_{}、\b→\left\right、
     \a→array、\x→\boxed/\overline、\o\al 堆叠、圈码、化学符号、极限、连等式)
   品牌标记 JBYU* → WPU*,与采集端一致
2. CtoMathFinder:接上 EQ 分支(原为 not-ported 桩),域代码经
   EqToLatexUtil.convert 转 LaTeX 写入 eqLatexMap(WPEQNUM 占位符)
3. WordParseUtil.dealPlaceholder:EQ 的 LaTeX 同样加 \( \) 包裹
   (原先因 WPEQNUM 例外不加包裹,前端/MathJax 不渲染)

修前症状:教辅 Word 里分式/方程组/上下标整段丢失(如 {−1/3, 1} 变成 {-,1})
修后实测:46 份教辅 2908 处 EQ 域全部还原,公式总数 2954 处、零未包裹残留

安全:application.yml(含 RustFS 密钥)不入库,提供 application.yml.example;
      OssService 的 @Value 默认密钥已清空
This commit is contained in:
2026-09-29 09:43:13 +08:00
commit 3271fee5cc
360 changed files with 86082 additions and 0 deletions

View File

@@ -0,0 +1,413 @@
/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* com.jby.common.util.SpringContextHolder
* org.apache.commons.lang3.StringUtils
* org.springframework.boot.context.properties.ConfigurationProperties
* org.springframework.cloud.context.config.annotation.RefreshScope
* org.springframework.stereotype.Component
*/
package com.jby.officecore.config;
import com.jby.common.util.SpringContextHolder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
@Component
@RefreshScope
@ConfigurationProperties(prefix="office.core.config")
public class OfficeCoreConfig {
private String tmpPath = "/opt/files/tmp";
private String templatePath;
private Boolean deleteTmpFile = true;
private String foreLatexToMathMlApi = "https://test.xinjiaoyu.com/api/v3/server_node_sheet_new/latex/to-mathml";
private String latexToMathMlApi = "http://172.26.197.220:8050/latex_to_mathml";
private String mathMlToLatexApi = "http://172.26.197.220:8050/mathml_to_latex";
private Boolean mathMlToLatexApiSwitch;
private String mf2SvgApi = "http://test.format.xinjiaoyu.com/server_format/graphic/mf2svg";
private String downloadPdfApi = "https://test.xinjiaoyu.com/api/v3/server_node_sheet_new/office/download";
private String errorBookTemplate = "https://test.xinjiaoyu.com/main/print.html?%s#/downloadNotebook";
private Integer nodeConnectTimeout = 5000;
private Integer nodeSocketTimeout = 30000;
private Long contentLimit = 100000L;
private Double limitRatio = 0.6;
private Integer checkSize = 10;
private Double imageScalingFactor = 0.7;
private String copyrightAddresses = "www.zxxk.com,www.zujuan.com,www.jyeoo.com";
private Boolean newParseVersion;
private Boolean newDownloadVersion;
private Boolean openParseCache = true;
private Map<String, List<String>> cleanStyleMap = new HashMap<String, List<String>>();
private String transformScriptPath = "E:\\IdeaProject\\jby-project\\base_server\\jby-office\\jby-office-transform";
public String getTransformScriptPath() {
return this.isLocal() ? this.transformScriptPath : "/opt/servers/jby-office-transform";
}
public String getPythonCommand() {
return this.isLocal() ? "python" : "python3";
}
private boolean isLocal() {
String env = SpringContextHolder.getActiveProfile();
return StringUtils.isBlank((CharSequence)env) || env.contains("local");
}
public String getTmpPath() {
return this.tmpPath;
}
public String getTemplatePath() {
return this.templatePath;
}
public Boolean getDeleteTmpFile() {
return this.deleteTmpFile;
}
public String getForeLatexToMathMlApi() {
return this.foreLatexToMathMlApi;
}
public String getLatexToMathMlApi() {
return this.latexToMathMlApi;
}
public String getMathMlToLatexApi() {
return this.mathMlToLatexApi;
}
public Boolean getMathMlToLatexApiSwitch() {
return this.mathMlToLatexApiSwitch;
}
public String getMf2SvgApi() {
return this.mf2SvgApi;
}
public String getDownloadPdfApi() {
return this.downloadPdfApi;
}
public String getErrorBookTemplate() {
return this.errorBookTemplate;
}
public Integer getNodeConnectTimeout() {
return this.nodeConnectTimeout;
}
public Integer getNodeSocketTimeout() {
return this.nodeSocketTimeout;
}
public Long getContentLimit() {
return this.contentLimit;
}
public Double getLimitRatio() {
return this.limitRatio;
}
public Integer getCheckSize() {
return this.checkSize;
}
public Double getImageScalingFactor() {
return this.imageScalingFactor;
}
public String getCopyrightAddresses() {
return this.copyrightAddresses;
}
public Boolean getNewParseVersion() {
return this.newParseVersion;
}
public Boolean getNewDownloadVersion() {
return this.newDownloadVersion;
}
public Boolean getOpenParseCache() {
return this.openParseCache;
}
public Map<String, List<String>> getCleanStyleMap() {
return this.cleanStyleMap;
}
public void setTmpPath(String tmpPath) {
this.tmpPath = tmpPath;
}
public void setTemplatePath(String templatePath) {
this.templatePath = templatePath;
}
public void setDeleteTmpFile(Boolean deleteTmpFile) {
this.deleteTmpFile = deleteTmpFile;
}
public void setForeLatexToMathMlApi(String foreLatexToMathMlApi) {
this.foreLatexToMathMlApi = foreLatexToMathMlApi;
}
public void setLatexToMathMlApi(String latexToMathMlApi) {
this.latexToMathMlApi = latexToMathMlApi;
}
public void setMathMlToLatexApi(String mathMlToLatexApi) {
this.mathMlToLatexApi = mathMlToLatexApi;
}
public void setMathMlToLatexApiSwitch(Boolean mathMlToLatexApiSwitch) {
this.mathMlToLatexApiSwitch = mathMlToLatexApiSwitch;
}
public void setMf2SvgApi(String mf2SvgApi) {
this.mf2SvgApi = mf2SvgApi;
}
public void setDownloadPdfApi(String downloadPdfApi) {
this.downloadPdfApi = downloadPdfApi;
}
public void setErrorBookTemplate(String errorBookTemplate) {
this.errorBookTemplate = errorBookTemplate;
}
public void setNodeConnectTimeout(Integer nodeConnectTimeout) {
this.nodeConnectTimeout = nodeConnectTimeout;
}
public void setNodeSocketTimeout(Integer nodeSocketTimeout) {
this.nodeSocketTimeout = nodeSocketTimeout;
}
public void setContentLimit(Long contentLimit) {
this.contentLimit = contentLimit;
}
public void setLimitRatio(Double limitRatio) {
this.limitRatio = limitRatio;
}
public void setCheckSize(Integer checkSize) {
this.checkSize = checkSize;
}
public void setImageScalingFactor(Double imageScalingFactor) {
this.imageScalingFactor = imageScalingFactor;
}
public void setCopyrightAddresses(String copyrightAddresses) {
this.copyrightAddresses = copyrightAddresses;
}
public void setNewParseVersion(Boolean newParseVersion) {
this.newParseVersion = newParseVersion;
}
public void setNewDownloadVersion(Boolean newDownloadVersion) {
this.newDownloadVersion = newDownloadVersion;
}
public void setOpenParseCache(Boolean openParseCache) {
this.openParseCache = openParseCache;
}
public void setCleanStyleMap(Map<String, List<String>> cleanStyleMap) {
this.cleanStyleMap = cleanStyleMap;
}
public void setTransformScriptPath(String transformScriptPath) {
this.transformScriptPath = transformScriptPath;
}
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof OfficeCoreConfig)) {
return false;
}
OfficeCoreConfig other = (OfficeCoreConfig)o;
if (!other.canEqual(this)) {
return false;
}
String this$tmpPath = this.getTmpPath();
String other$tmpPath = other.getTmpPath();
if (this$tmpPath == null ? other$tmpPath != null : !this$tmpPath.equals(other$tmpPath)) {
return false;
}
String this$templatePath = this.getTemplatePath();
String other$templatePath = other.getTemplatePath();
if (this$templatePath == null ? other$templatePath != null : !this$templatePath.equals(other$templatePath)) {
return false;
}
Boolean this$deleteTmpFile = this.getDeleteTmpFile();
Boolean other$deleteTmpFile = other.getDeleteTmpFile();
if (this$deleteTmpFile == null ? other$deleteTmpFile != null : !((Object)this$deleteTmpFile).equals(other$deleteTmpFile)) {
return false;
}
String this$foreLatexToMathMlApi = this.getForeLatexToMathMlApi();
String other$foreLatexToMathMlApi = other.getForeLatexToMathMlApi();
if (this$foreLatexToMathMlApi == null ? other$foreLatexToMathMlApi != null : !this$foreLatexToMathMlApi.equals(other$foreLatexToMathMlApi)) {
return false;
}
String this$latexToMathMlApi = this.getLatexToMathMlApi();
String other$latexToMathMlApi = other.getLatexToMathMlApi();
if (this$latexToMathMlApi == null ? other$latexToMathMlApi != null : !this$latexToMathMlApi.equals(other$latexToMathMlApi)) {
return false;
}
String this$mathMlToLatexApi = this.getMathMlToLatexApi();
String other$mathMlToLatexApi = other.getMathMlToLatexApi();
if (this$mathMlToLatexApi == null ? other$mathMlToLatexApi != null : !this$mathMlToLatexApi.equals(other$mathMlToLatexApi)) {
return false;
}
Boolean this$mathMlToLatexApiSwitch = this.getMathMlToLatexApiSwitch();
Boolean other$mathMlToLatexApiSwitch = other.getMathMlToLatexApiSwitch();
if (this$mathMlToLatexApiSwitch == null ? other$mathMlToLatexApiSwitch != null : !((Object)this$mathMlToLatexApiSwitch).equals(other$mathMlToLatexApiSwitch)) {
return false;
}
String this$mf2SvgApi = this.getMf2SvgApi();
String other$mf2SvgApi = other.getMf2SvgApi();
if (this$mf2SvgApi == null ? other$mf2SvgApi != null : !this$mf2SvgApi.equals(other$mf2SvgApi)) {
return false;
}
String this$downloadPdfApi = this.getDownloadPdfApi();
String other$downloadPdfApi = other.getDownloadPdfApi();
if (this$downloadPdfApi == null ? other$downloadPdfApi != null : !this$downloadPdfApi.equals(other$downloadPdfApi)) {
return false;
}
String this$errorBookTemplate = this.getErrorBookTemplate();
String other$errorBookTemplate = other.getErrorBookTemplate();
if (this$errorBookTemplate == null ? other$errorBookTemplate != null : !this$errorBookTemplate.equals(other$errorBookTemplate)) {
return false;
}
Integer this$nodeConnectTimeout = this.getNodeConnectTimeout();
Integer other$nodeConnectTimeout = other.getNodeConnectTimeout();
if (this$nodeConnectTimeout == null ? other$nodeConnectTimeout != null : !((Object)this$nodeConnectTimeout).equals(other$nodeConnectTimeout)) {
return false;
}
Integer this$nodeSocketTimeout = this.getNodeSocketTimeout();
Integer other$nodeSocketTimeout = other.getNodeSocketTimeout();
if (this$nodeSocketTimeout == null ? other$nodeSocketTimeout != null : !((Object)this$nodeSocketTimeout).equals(other$nodeSocketTimeout)) {
return false;
}
Long this$contentLimit = this.getContentLimit();
Long other$contentLimit = other.getContentLimit();
if (this$contentLimit == null ? other$contentLimit != null : !((Object)this$contentLimit).equals(other$contentLimit)) {
return false;
}
Double this$limitRatio = this.getLimitRatio();
Double other$limitRatio = other.getLimitRatio();
if (this$limitRatio == null ? other$limitRatio != null : !((Object)this$limitRatio).equals(other$limitRatio)) {
return false;
}
Integer this$checkSize = this.getCheckSize();
Integer other$checkSize = other.getCheckSize();
if (this$checkSize == null ? other$checkSize != null : !((Object)this$checkSize).equals(other$checkSize)) {
return false;
}
Double this$imageScalingFactor = this.getImageScalingFactor();
Double other$imageScalingFactor = other.getImageScalingFactor();
if (this$imageScalingFactor == null ? other$imageScalingFactor != null : !((Object)this$imageScalingFactor).equals(other$imageScalingFactor)) {
return false;
}
String this$copyrightAddresses = this.getCopyrightAddresses();
String other$copyrightAddresses = other.getCopyrightAddresses();
if (this$copyrightAddresses == null ? other$copyrightAddresses != null : !this$copyrightAddresses.equals(other$copyrightAddresses)) {
return false;
}
Boolean this$newParseVersion = this.getNewParseVersion();
Boolean other$newParseVersion = other.getNewParseVersion();
if (this$newParseVersion == null ? other$newParseVersion != null : !((Object)this$newParseVersion).equals(other$newParseVersion)) {
return false;
}
Boolean this$newDownloadVersion = this.getNewDownloadVersion();
Boolean other$newDownloadVersion = other.getNewDownloadVersion();
if (this$newDownloadVersion == null ? other$newDownloadVersion != null : !((Object)this$newDownloadVersion).equals(other$newDownloadVersion)) {
return false;
}
Boolean this$openParseCache = this.getOpenParseCache();
Boolean other$openParseCache = other.getOpenParseCache();
if (this$openParseCache == null ? other$openParseCache != null : !((Object)this$openParseCache).equals(other$openParseCache)) {
return false;
}
Map<String, List<String>> this$cleanStyleMap = this.getCleanStyleMap();
Map<String, List<String>> other$cleanStyleMap = other.getCleanStyleMap();
if (this$cleanStyleMap == null ? other$cleanStyleMap != null : !((Object)this$cleanStyleMap).equals(other$cleanStyleMap)) {
return false;
}
String this$transformScriptPath = this.getTransformScriptPath();
String other$transformScriptPath = other.getTransformScriptPath();
return !(this$transformScriptPath == null ? other$transformScriptPath != null : !this$transformScriptPath.equals(other$transformScriptPath));
}
protected boolean canEqual(Object other) {
return other instanceof OfficeCoreConfig;
}
public int hashCode() {
int PRIME = 59;
int result = 1;
String $tmpPath = this.getTmpPath();
result = result * 59 + ($tmpPath == null ? 43 : $tmpPath.hashCode());
String $templatePath = this.getTemplatePath();
result = result * 59 + ($templatePath == null ? 43 : $templatePath.hashCode());
Boolean $deleteTmpFile = this.getDeleteTmpFile();
result = result * 59 + ($deleteTmpFile == null ? 43 : ((Object)$deleteTmpFile).hashCode());
String $foreLatexToMathMlApi = this.getForeLatexToMathMlApi();
result = result * 59 + ($foreLatexToMathMlApi == null ? 43 : $foreLatexToMathMlApi.hashCode());
String $latexToMathMlApi = this.getLatexToMathMlApi();
result = result * 59 + ($latexToMathMlApi == null ? 43 : $latexToMathMlApi.hashCode());
String $mathMlToLatexApi = this.getMathMlToLatexApi();
result = result * 59 + ($mathMlToLatexApi == null ? 43 : $mathMlToLatexApi.hashCode());
Boolean $mathMlToLatexApiSwitch = this.getMathMlToLatexApiSwitch();
result = result * 59 + ($mathMlToLatexApiSwitch == null ? 43 : ((Object)$mathMlToLatexApiSwitch).hashCode());
String $mf2SvgApi = this.getMf2SvgApi();
result = result * 59 + ($mf2SvgApi == null ? 43 : $mf2SvgApi.hashCode());
String $downloadPdfApi = this.getDownloadPdfApi();
result = result * 59 + ($downloadPdfApi == null ? 43 : $downloadPdfApi.hashCode());
String $errorBookTemplate = this.getErrorBookTemplate();
result = result * 59 + ($errorBookTemplate == null ? 43 : $errorBookTemplate.hashCode());
Integer $nodeConnectTimeout = this.getNodeConnectTimeout();
result = result * 59 + ($nodeConnectTimeout == null ? 43 : ((Object)$nodeConnectTimeout).hashCode());
Integer $nodeSocketTimeout = this.getNodeSocketTimeout();
result = result * 59 + ($nodeSocketTimeout == null ? 43 : ((Object)$nodeSocketTimeout).hashCode());
Long $contentLimit = this.getContentLimit();
result = result * 59 + ($contentLimit == null ? 43 : ((Object)$contentLimit).hashCode());
Double $limitRatio = this.getLimitRatio();
result = result * 59 + ($limitRatio == null ? 43 : ((Object)$limitRatio).hashCode());
Integer $checkSize = this.getCheckSize();
result = result * 59 + ($checkSize == null ? 43 : ((Object)$checkSize).hashCode());
Double $imageScalingFactor = this.getImageScalingFactor();
result = result * 59 + ($imageScalingFactor == null ? 43 : ((Object)$imageScalingFactor).hashCode());
String $copyrightAddresses = this.getCopyrightAddresses();
result = result * 59 + ($copyrightAddresses == null ? 43 : $copyrightAddresses.hashCode());
Boolean $newParseVersion = this.getNewParseVersion();
result = result * 59 + ($newParseVersion == null ? 43 : ((Object)$newParseVersion).hashCode());
Boolean $newDownloadVersion = this.getNewDownloadVersion();
result = result * 59 + ($newDownloadVersion == null ? 43 : ((Object)$newDownloadVersion).hashCode());
Boolean $openParseCache = this.getOpenParseCache();
result = result * 59 + ($openParseCache == null ? 43 : ((Object)$openParseCache).hashCode());
Map<String, List<String>> $cleanStyleMap = this.getCleanStyleMap();
result = result * 59 + ($cleanStyleMap == null ? 43 : ((Object)$cleanStyleMap).hashCode());
String $transformScriptPath = this.getTransformScriptPath();
result = result * 59 + ($transformScriptPath == null ? 43 : $transformScriptPath.hashCode());
return result;
}
public String toString() {
return "OfficeCoreConfig(tmpPath=" + this.getTmpPath() + ", templatePath=" + this.getTemplatePath() + ", deleteTmpFile=" + this.getDeleteTmpFile() + ", foreLatexToMathMlApi=" + this.getForeLatexToMathMlApi() + ", latexToMathMlApi=" + this.getLatexToMathMlApi() + ", mathMlToLatexApi=" + this.getMathMlToLatexApi() + ", mathMlToLatexApiSwitch=" + this.getMathMlToLatexApiSwitch() + ", mf2SvgApi=" + this.getMf2SvgApi() + ", downloadPdfApi=" + this.getDownloadPdfApi() + ", errorBookTemplate=" + this.getErrorBookTemplate() + ", nodeConnectTimeout=" + this.getNodeConnectTimeout() + ", nodeSocketTimeout=" + this.getNodeSocketTimeout() + ", contentLimit=" + this.getContentLimit() + ", limitRatio=" + this.getLimitRatio() + ", checkSize=" + this.getCheckSize() + ", imageScalingFactor=" + this.getImageScalingFactor() + ", copyrightAddresses=" + this.getCopyrightAddresses() + ", newParseVersion=" + this.getNewParseVersion() + ", newDownloadVersion=" + this.getNewDownloadVersion() + ", openParseCache=" + this.getOpenParseCache() + ", cleanStyleMap=" + this.getCleanStyleMap() + ", transformScriptPath=" + this.getTransformScriptPath() + ")";
}
}