pdf生成与显示

This commit is contained in:
2026-01-26 09:47:55 +08:00
parent 5c7fbb76fa
commit 68b2172a35
12 changed files with 299 additions and 4379 deletions

BIN
src/assets/img/icon_pdf.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -147,47 +147,53 @@ export default {
replaceWMathContent(inputHtml, callback) {
// 使用正则表达式查找所有 <wmath> 标签,并提取 data-latex 的内容
var str = inputHtml.replace(/<wmath data-latex="([^"]+)">[^<]*<\/wmath>/g, function (match, latexContent) {
// 返回 <wmath> 标签,内容替换为 data-latex 的值
return `<wmath data-latex="${latexContent}">${latexContent}</wmath>`;
// 正则逻辑:匹配整个 wmath 标签,并捕获内部所有的属性字符串
var str = inputHtml.replace(/<wmath ([^>]+)>[^<]*<\/wmath>/g, function (match, allProps) {
// 1. 从所有属性中提取 data-latex 的值
const latexMatch = allProps.match(/data-latex="([^"]+)"/);
const latexContent = latexMatch ? latexMatch[1] : '';
// 2. 从所有属性中提取 data-wrap 的值
const wrapMatch = allProps.match(/data-wrap="([^"]+)"/);
const wrapAttr = wrapMatch ? ` data-wrap="${wrapMatch[1]}"` : '';
// 3. 重新组装:只保留 data-latex 和 data-wrap
// 注意:这里去掉了多余的 prefix/suffix确保标签“干净”
return `<wmath${wrapAttr} data-latex="${latexContent}">${latexContent}</wmath>`;
});
// 调用回调函数并传递处理后的结果
callback(str);
// 输出结果到控制台
// console.log('Processed HTML:', str);
}
,
} ,
// **解析 MathJax 公式,获取 LaTeX**
async extractMathJaxLatex(cell, callback) {
return new Promise((resolve, reject) => {
// Step 1: First, process the math content and extract LaTeX from <wmath> tags
let updatedContent = cell.innerHTML; // Start with the cell's inner HTML
// Find all <wmath> elements
// Step 1: 获取初始 HTML
let updatedContent = cell.innerHTML;
// 查找所有 <wmath> 元素
const wmathElements = cell.querySelectorAll('wmath');
wmathElements.forEach((element) => {
// Get the LaTeX content from the data-latex attribute
const latexContent = element.getAttribute('data-latex');
// Replace the <wmath> tag with its LaTeX content wrapped in $$...$$
updatedContent = updatedContent.replace(element.outerHTML, `<wmath data-latex="${latexContent}">${latexContent}</wmath>`);
// 1. 提取 latex 内容
const latexContent = element.getAttribute('data-latex') || '';
// 2. 提取 wrap 模式 (只提取,不包裹)
const wrapMode = element.getAttribute('data-wrap') || 'block';
// 3. 重新组装标签:只保留属性,标签内部只放原始 latex 文本
// 这里不加 $ 或 $$,保持数据的原始性
const newWmathTag = `<wmath data-wrap="${wrapMode}" data-latex="${latexContent}">${latexContent}</wmath>`;
// 4. 执行替换
updatedContent = updatedContent.replace(element.outerHTML, newWmathTag);
});
// Step 2: Now extract content without the outer <span> tags
// Step 2: 提取去掉外层 span 的内容
updatedContent = this.extractContentWithoutOuterSpan(updatedContent);
// Step 3: Call the callback function with the final updated content
// callback(updatedContent);
// Resolve the promise with the final content
// Step 3: Resolve 结果
resolve(updatedContent);
});
}
@@ -843,7 +849,7 @@ export default {
// 使用正则表达式删除属性(保留 data-latex
let updatedAttributes = attributes.replace(/\s([a-zA-Z0-9-]+)(="[^"]*")?/g, function (attrMatch, attrName) {
if (attrName === "data-latex" || attrName === "data-id") {
if (attrName === "data-latex" || attrName === "data-id" || attrName === "data-wrap") {
return attrMatch;
}
if (type == 'table' && tag == 'img' && (attrName === "src" || attrName === "width" || attrName === "height")) {
@@ -2098,7 +2104,7 @@ export default {
const uid = 'wmath-' + Math.random().toString(36).substr(2, 9);
// 3. 创建一个 <wmath> 标签并插入到光标处
const wmathHtml = `<wmath contenteditable="false" data-id="${uid}" data-latex=""></wmath>`;
const wmathHtml = `<wmath contenteditable="false" data-id="${uid}" data-latex="" data-wrap="block"></wmath>`;
ed.insertContent(wmathHtml); // 在光标位置插入 wmath 标签
// 4. 打开公式编辑器窗口,并传递光标位置、编辑器 ID 和 wmathId

View File

@@ -5,16 +5,23 @@
// const mediaUrl = '/public/';
// const baseUrl = '/';
//正式环境
// const mediaUrl = 'https://submission.tmrjournals.com/public/';
// // const mediaUrl = 'http://zmzm.tougao.dev.com/public/';
// const baseUrl = '/api'
const mediaUrl = 'http://tougaotest.tmrjournals.com/public/';
// const mediaUrl = 'http://zmzm.tougao.dev.com/public/';
//测试环境
// const mediaUrl = 'http://tougaotest.tmrjournals.com/public/';
// // const mediaUrl = 'http://zmzm.tougao.dev.com/public/';
// const baseUrl = '/api';
////新正式环境
const mediaUrl = 'http://mytest.tmrjournals.com/public/';
const baseUrl = '/api';
//本地(正式环境 )
// const mediaUrl = 'https://submission.tmrjournals.com/public/';
// const baseUrl = '/api';

View File

@@ -162,6 +162,7 @@
Figure Title :
</span>
<common-content
type="content"
:isAutomaticUpdate="true"
:value="picStyle.title"
@getContent="getContent"
@@ -175,6 +176,7 @@
</el-form-item>
<el-form-item label="Figure Describe :">
<common-content
type="content"
:isAutomaticUpdate="true"
:value="picStyle.note"
@getContent="getContent"
@@ -219,6 +221,7 @@
Title:
</span>
<common-content
type="content"
:id="`editor-${new Date().getTime()}-${lineStyle.am_id}-${lineStyle.amt_id}-title`"
:isAutomaticUpdate="true"
:value="lineStyle.title"
@@ -249,6 +252,7 @@
<el-form-item label="Note:">
<!-- :id="`editor-${new Date().getTime()}-${lineStyle.am_id}-${lineStyle.amt_id}-note`" -->
<common-content
type="content"
:id="`editor-${new Date().getTime()}-${lineStyle.am_id}-${lineStyle.amt_id}-note`"
:isAutomaticUpdate="true"
:value="lineStyle.note"
@@ -366,6 +370,8 @@
Content :
</span>
<common-content
type="content"
@openAddTable="openAddTable"
:value="currentContent.content"
@getContent="getContent"
@openLatexEditor="openLatexEditor"
@@ -401,6 +407,7 @@
<common-content
:value="addContent.content"
@getContent="getContent"
type="content"
@openLatexEditor="openLatexEditor"
v-if="addContentVisible"
ref="addContent"
@@ -595,7 +602,19 @@ export default {
this.getCommentList();
},
mounted() {},
mounted() {
document.addEventListener('copy', (event) => {
// 获取用户选中的文本
const selection = document.getSelection().toString();
// 你可以修改剪贴板内容
// event.clipboardData.setData('text/plain', selection + '\n---来自我的系统---');
console.log('用户复制了内容:', selection);
// 阻止默认行为(如果需要自定义复制逻辑的话)
// event.preventDefault();
});
},
async activated() {
this.isShowEditComment();
@@ -604,6 +623,11 @@ export default {
},
methods: {
openAddTable(content) {
this.editVisible = false;
this.threeVisible = true;
this.$forceUpdate();
},
async copyArray(data) {
try {
// 将数组内容转换为字符串,使用换行符分隔
@@ -848,30 +872,45 @@ export default {
}
},
saveLateX(data) {
console.log('data at line 735:', data);
const { editorId, wmathId, latex } = data;
const newLatex = latex ? latex.trim() : '';
if (!editorId || !wmathId) return;
const targetEditor = tinymce.get(editorId);
if (!targetEditor) return;
const targetWmath = targetEditor.dom.select(`wmath[data-id="${wmathId}"]`, targetEditor.getBody())[0];
if (targetWmath) {
if (!newLatex) {
// ❌ 删除公式
targetEditor.dom.remove(targetWmath);
} else {
// ✅ 更新公式
targetWmath.setAttribute('data-latex', newLatex);
targetWmath.innerHTML = newLatex;
setTimeout(() => {
if (typeof renderMathJax === 'function') {
// this.window.renderMathJax(editorId);
}
}, 10);
}
console.log('data at line 735:', data);
// 1. 从 data 中解构出 wrap (或者你命名的模式变量)
const { editorId, wmathId, latex, wrap } = data;
const newLatex = latex ? latex.trim() : '';
if (!editorId || !wmathId) return;
const targetEditor = tinymce.get(editorId);
if (!targetEditor) return;
// 2. 找到编辑器中现有的 wmath 标签
const targetWmath = targetEditor.dom.select(`wmath[data-id="${wmathId}"]`, targetEditor.getBody())[0];
if (targetWmath) {
if (!newLatex) {
// ❌ 删除公式
targetEditor.dom.remove(targetWmath);
} else {
// ✅ 更新公式
// 保持属性纯净:同时更新 latex 内容和 wrap 属性
targetWmath.setAttribute('data-latex', newLatex);
// 如果 data 中传了 wrap 模式就更新它,否则可以保留原样或设为默认
if (wrap) {
targetWmath.setAttribute('data-wrap', wrap);
}
},
// 内部只放纯 latex 文本,不包裹 $ 符号
targetWmath.innerHTML = newLatex;
setTimeout(() => {
if (typeof renderMathJax === 'function') {
// 重新渲染该编辑器内的数学公式
renderMathJax(editorId);
}
}, 10);
}
}
},
async huifu(id) {
var that = this;
await this.$confirm(this.$t('commonTable.reContent'), 'Prompt', {
@@ -2532,4 +2571,9 @@ export default {
background-color: #0066990d;
/* display: block !important; */
}
wmath[data-wrap="inline"] {
display: inline-block !important;
width: auto !important;
}
</style>

View File

@@ -746,27 +746,36 @@
<div class="right-panel">
<h5 style="font-size: 14px; margin: 0 0 40px 0;">
<el-button
type="success"
icon="el-icon-printer"
style="width: 150px; height: 32px; font-size: 12px;margin-right: 10px;"
style="width: 150px; height: 32px; font-size: 12px;margin-right: 14px;"
:loading="isGenerating"
@click="generatePDF"
>
{{ isGenerating ? 'Generating PDF...' : 'Generate PDF' }}
</el-button>
<span>Click the button below to start high-quality PDF typesetting.</span>
</h5>
<div style="margin: 30px 0 40px 0">
<h5 style="font-size: 16px; margin: 0 0 30px 0; letter-spacing: -0.5px;font-weight: bold;">Download list</h5>
<p v-if="DLfileList.length == 0" style="color: #666; font-size: 14px">No Manuscript</p>
<div v-for="(item, index) in DLfileList" :key="index" class="load_pdf">
<img src="../../assets/img/icon_0.png" />
<h5 style="font-size: 16px; margin: 0 0 30px 0; letter-spacing: -0.5px;font-weight: bold;">Download list
<span><i class="el-icon-refresh" style="color: #006699; font-weight: bold;margin-left: 6px;cursor: pointer;" @click="refreshPdfList"></i></span>
<span v-if="detailMes.file_sub_table" style="color: #006699; font-size: 13px;font-weight: normal;float: right;">Supplementary Material :<a :href="'/public/articleSUBTAB/' +detailMes.file_sub_table" target="_blank" style="margin-left: 20px">
<i class="el-icon-download" style="color: #006699; font-weight: bold"></i>
</a></span>
</h5>
<p v-if="PDFfileList.length == 0" style="color: #666; font-size: 14px">No Manuscript</p>
<div v-for="(item, index) in PDFfileList" :key="index" class="load_pdf">
<img src="../../assets/img/icon_pdf.png" style="width: 26px; height: 26px;" />
<span style="color: #333">Typesetting {{ index + 1 }}</span>
<span style="margin-left: 40px; color: #888; font-size: 13px">Time : {{ modifDate(item.ctime * 1000) }}</span>
<a :href="'/tsfile/' + item.url" target="_blank" style="margin-left: 40px">
<span style="margin-left: 40px; color: #888; font-size: 13px">Time : {{ modifDate(item.create_time * 1000) }}</span>
<a :href="'/public/' + item.url" target="_blank" style="margin-left: 40px">
<i class="el-icon-download" style="color: #66b1ff; font-weight: bold"></i>
</a>
</div>
</div>
@@ -1284,6 +1293,7 @@ export default {
}
],
DLfileList: [],
PDFfileList: [],
UpTypeFile: {
pdf: ''
},
@@ -1478,44 +1488,34 @@ export default {
this.getAuthorJG();
this.getCount();
this.getWorldPdf();
this.getPdfList();
},
methods: {
async generatePDF() {
// 1. 验证是否选择了模板
if (!this.shuTter.board) {
this.$message.warning("Please select a template first!");
return;
}
// 1. 验证逻辑(保持原样)
this.isGenerating = true;
this.percentage = 0;
try {
this.isGenerating = true; // 开启加载
try {
// 模拟进度条逻辑(如果是真实接口,可以根据后端返回或者固定时长模拟)
let timer = setInterval(() => {
if (this.percentage < 90) this.percentage += 10;
}, 500);
// 注意:这里要加 await确保拿到结果后再往下走
const res = await this.$api.post('api/Production/createArticlePdf', {
p_article_id: this.p_article_id
});
// 调用你的生成接口 (假设是 Establish 的升级版)
// const res = await api.createPDF({ board: this.shuTter.board });
// 模拟接口请求耗时
await new Promise(resolve => setTimeout(resolve, 3000));
if (res.status == 1) {
this.$message.success("The PDF document is being processed. Please wait and refresh the page in one minute.");
} else {
this.$message.error("Generation failed, please try again.");
}
this.percentage = 100;
clearInterval(timer);
this.$message.success("PDF Generated Successfully!");
// 自动刷新左侧的下载列表
// this.getDLFileList();
} catch (error) {
this.$message.error("Generation failed, please try again.");
} finally {
this.isGenerating = false;
}
},
} catch (error) {
console.error(error);
this.$message.error("Network error, please try again.");
} finally {
// 只有请求真正完成后,才会执行这里
this.isGenerating = false;
}
},
getArticleFinal(id) {
// api/Finalreview/getRecord
this.$api
@@ -1785,6 +1785,40 @@ export default {
this.$message.error(err);
});
},
refreshPdfList(){ const loading = this.$loading({
lock: true,
text: 'Loading...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
try {
this.getPdfList();
loading.close();
} catch (error) {
this.$message.error(error);
}
},
getPdfList() {
// 可以下载的word列表
this.$api
.post('/api/Production/getProductionArticlePdf', {
p_article_id: this.p_article_id
})
.then((res) => {
if (res.status == 1) {
this.PDFfileList = res.data;
} else {
this.$message.error(res.msg);
}
})
.catch((err) => {
this.$message.error(err);
});
},
getCount() {
// 获取国家列表
@@ -3143,7 +3177,7 @@ export default {
}
.right-panel {
width: 45%; /* 右侧固定宽度 */
width: 48%; /* 右侧固定宽度 */
}
.right-panel h5 {
font-weight: normal;

View File

@@ -1,5 +1,6 @@
<template>
<div class="tinymce-container editor-container">
<textarea class="tinymce-textarea" :id="tinymceId"></textarea>
</div>
</template>
@@ -538,32 +539,35 @@ myfigure *,
_this.$commonJS.initEditorButton(_this, ed);
var currentWmathElement = null;
ed.on('click', function (e) {
const wmathElement = e.target.closest('wmath');
if (wmathElement) {
currentWmathElement = wmathElement; // 👈 保存当前点击的元素
const latexContentRaw = wmathElement.getAttribute('data-latex') || '';
console.log('at line 488: raw =', latexContentRaw);
// 去除所有 $ 符号
const latexContent = latexContentRaw.replace(/\$/g, '').trim();
const wmathElement = e.target.closest('wmath');
if (wmathElement) {
currentWmathElement = wmathElement; // 保存当前点击的元素
// 1. 提取内容:获取 LaTeX
const latexContentRaw = wmathElement.getAttribute('data-latex') || '';
const latexContent = latexContentRaw.replace(/\$/g, '').trim();
const encoded = encodeURIComponent(latexContent);
// 编码后用于传递到弹窗
const encoded = encodeURIComponent(latexContent);
// 给 wmath 添加唯一 data-id方便后续精准替换
let wmathId = wmathElement.getAttribute('data-id');
if (!wmathId) {
wmathId = 'wmath-' + Math.random().toString(36).substr(2, 9);
wmathElement.setAttribute('data-id', wmathId);
}
// 当前编辑器 ID 也保存下来(如果你有多个编辑器)
const editorId = ed.id;
// 打开编辑窗口并传参(传递 data-id + 内容)
window.open(
`/LateX?id=${encoded}&wmathId=${wmathId}&editorId=${editorId}`,
'_blank',
'width=1000,height=800,scrollbars=no,resizable=no'
);
}
});
// 2. 提取状态:获取之前的 wrap 模式 👈 重要新增
const wrapMode = wmathElement.getAttribute('data-wrap') || 'block';
// 3. 处理唯一 ID
let wmathId = wmathElement.getAttribute('data-id');
if (!wmathId) {
wmathId = 'wmath-' + Math.random().toString(36).substr(2, 9);
wmathElement.setAttribute('data-id', wmathId);
}
const editorId = ed.id;
// 4. 打开窗口:在 URL 参数中增加 wrap 模式 👈 这样弹窗就知道该默认选哪个了
window.open(
`/LateX?id=${encoded}&wmathId=${wmathId}&editorId=${editorId}&wrap=${wrapMode}`,
'_blank',
'width=1000,height=800,scrollbars=no,resizable=no'
);
}
});
ed.on('paste', async (event) => {
const rtf = event.clipboardData.getData('text/rtf');
@@ -712,7 +716,7 @@ myfigure *,
tempDiv.innerHTML = content;
if (tempDiv.querySelector('table')) {
console.log('粘贴的内容包含表格');
if (_this.type == 'table') {
// 3. 在这里直接消费外部变量 currentPasteBase64Images
// content = content.replace(new RegExp(`src="${silentPlaceholder}"`, 'gi'), () => {
@@ -753,21 +757,37 @@ myfigure *,
args.content = container.innerHTML; // 更新处理后的内容
});
} else {
// _this.$confirm('检测到粘贴内容包含表格,是否需要以表格形式添加?', '提示', {
// confirmButtonText: '添加表格',
// cancelButtonText: '纯文本添加',
// type: 'info'
// }).then(() => {
// _this.$emit('openAddTable', content);
// return false
// }).catch(() => {
// });
}
} else {
console.log('Original content:', content); // 输出原始粘贴内容
// 改进的正则表达式,匹配 $$...$$ 格式的 LaTeX 公式
const mathRegex = /\$\$([^$]+)\$\$/g;
// 1. 修改正则:同时匹配 $$...$$ (块级) 和 $...$ (行内)
// 注意:先匹配双美元符,再匹配单美元符,防止冲突
const mathRegex = /\$\$([\s\S]+?)\$\$|\$([\s\S]+?)\$/g;
// 如果粘贴的内容包含 $$...$$ 格式的公式,进行处理
content = content.replace(mathRegex, function (match, formula) {
console.log('Matched formula:', formula); // 输出每个匹配的公式
// 将公式包裹在 <wmath> 标签中,保留 $$...$$ 结构
return `<wmath data-latex="${match}">${match}</wmath>`;
});
content = content.replace(mathRegex, function (match, blockFormula, inlineFormula) {
// 判断是块级还是行内
const formula = blockFormula || inlineFormula;
const mode = blockFormula ? 'block' : 'inline';
console.log(`Matched ${mode} formula:`, formula);
console.log('Processed content:', content); // 输出处理后的内容
// 2. 统一改造:标签内只放纯 formula不带 $ 符号
// 属性中保存 data-latex 和 data-wrap
return `<wmath data-wrap="${mode}" data-latex="${formula.trim()}">${formula.trim()}</wmath>`;
});
console.log('Processed content:', content); // 输出处理后的内容
}
// 更新 args.content 为处理后的内容
// 阻止默认的粘贴行为,确保自定义处理优先执行
@@ -816,42 +836,58 @@ myfigure *,
// 👂 message 监听器:处理编辑 + 新增两种情况
window.addEventListener('message', function (event) {
const data = event.data;
// console.log('data at line 648:', data);
// ✅ 编辑现有公式:替换或删除
if (data && data.type === 'update-wmath') {
const { editorId, wmathId, latex } = data;
const newLatex = latex ? latex.trim() : '';
const data = event.data;
if (data && (data.type === 'update-wmath' || data.type === 'insert-wmath')) {
const { editorId, wmathId, latex } = data;
const newLatex = latex ? latex.trim() : '';
if (!editorId) return;
if (!editorId || !wmathId) return;
const targetEditor = tinymce.get(editorId);
if (!targetEditor) return;
const targetEditor = tinymce.get(editorId);
if (!targetEditor) return;
const targetWmath = targetEditor.dom.select(`wmath[data-id="${wmathId}"]`, targetEditor.getBody())[0];
// 尝试寻找现有标签
const targetWmath = wmathId ? targetEditor.dom.select(`wmath[data-id="${wmathId}"]`, targetEditor.getBody())[0] : null;
if (targetWmath) {
if (!newLatex) {
// ❌ 删除公式
targetEditor.dom.remove(targetWmath);
} else {
// ✅ 更新公式
targetWmath.setAttribute('data-latex', newLatex);
targetWmath.innerHTML = newLatex;
if (targetWmath) {
// --- 原有的更新/删除逻辑 ---
if (!newLatex) {
targetEditor.dom.remove(targetWmath);
} else {
targetWmath.setAttribute('data-latex', newLatex);
if (data.wrapMode === 'inline') {
targetWmath.setAttribute('data-wrap', 'inline');
} else {
targetWmath.setAttribute('data-wrap', 'block');
}
targetWmath.innerHTML = newLatex;
}
} else if (newLatex) {
// --- ✨ 新增逻辑:如果找不到现有标签且有 latex 内容 ---
// 生成一个新的唯一 ID (如果你后端或插件没给的话)
const newId = wmathId || 'wmath_' + Date.now();
// 构建新的 wmath 标签字符串
// 这里你可以根据之前选的 wrapMode (块级/行内) 来决定样式
const htmlToInsert = `<wmath data-id="${newId}" data-latex="${newLatex}" data-wrap="${data.wrapMode === 'inline' ? 'inline' : 'block'}">${newLatex}</wmath>`;
// 在当前光标位置插入内容
targetEditor.insertContent(htmlToInsert);
}
setTimeout(() => {
if (typeof renderMathJax === 'function') {
this.window.renderMathJax(editorId);
}
}, 10);
}
}
}
});
// 统一渲染
setTimeout(() => {
if (typeof renderMathJax === 'function') {
renderMathJax(editorId);
}
}, 10);
}
});
// 🚩 标记为已注册,防止重复
window._wmath_listener_registered = true;
// 🧠 导出保存位置函数(你可以在按钮点击时调用它)
// 导出保存位置函数(你可以在按钮点击时调用它)
window._recordLatexInsertContext = function (editorInstance) {
latexEditorBookmark = editorInstance.selection.getBookmark(2);
activeEditorId = editorInstance.id;

View File

@@ -1,151 +0,0 @@
<template>
<div style="position: fixed;top: 0;left: 0;background-color: #f8f8f8; width: 100%; height: 100%; overflow: hidden; background: linear-gradient(to top, #fbfffe, #ebf9ff);">
<div class="navbar-default">
<div class="nav commonWidth" style="height: 100%">
<div class="title">Digital Formula Editor</div>
</div>
</div>
<div class="commonWidth" style="padding:40px 20px; box-sizing: border-box;">
<!-- <div style="margin-bottom: 20px;font-size: 20px;">Numerical formula:</div> -->
<div style="display: flex;align-items: center;justify-content: space-between;">
<div ref="mathField" class="math-container" style="width: calc(100% - 100px);"></div>
<span @click="copyLatex" style="font-size: 20px;width: 80px;cursor: pointer;">📋 Copy </span>
</div>
<!-- 公式显示框 -->
<div class="formula-box" :style="{ opacity: showLatex ? 1 : 0 }">
<p>LaTeX 代码:</p>
<textarea ref="latexBox" class="latex-text" readonly>$${{ latex }}$$</textarea>
</div>
</div>
</div>
</template>
<script>
import { MathfieldElement } from 'mathlive';
export default {
data() {
return {
latex: '', // 默认公式
// latex: '\\frac{a}{b} + \\sqrt{x^2 + y^2} + e^{i\\pi}', // 默认公式
mathFieldInstance: null,
showLatex: false, // 控制 LaTeX 代码框的显示与隐藏
};
},
mounted() {
if (this.$refs.mathField) {
// 创建 MathfieldElement 组件
const mf = new MathfieldElement();
mf.style.width = '100%';
mf.virtualKeyboardMode = 'manual'; // 显示虚拟键盘
mf.value = this.latex; // 设置默认值
// 监听输入变化,更新 LaTeX 代码
mf.addEventListener('input', (event) => {
this.latex = event.target.value;
});
// 挂载到 DOM
this.$refs.mathField.appendChild(mf);
this.mathFieldInstance = mf;
// 强制显示虚拟键盘并保持显示
mf.executeCommand('showVirtualKeyboard');
// 保证虚拟键盘持续显示
this.keepKeyboardVisible(mf);
} else {
console.error('MathLive 未正确加载');
}
},
methods: {
keepKeyboardVisible(mf) {
// 每秒确保虚拟键盘显示
setInterval(() => {
mf.executeCommand('showVirtualKeyboard');
}, 20); // 每秒确保键盘显示
},
copyLatex() {
if (this.$refs.latexBox) {
this.$refs.latexBox.select(); // 选中文本
document.execCommand('copy'); // 复制到剪贴板
setTimeout(( )=>{
window.close();
},100)
}
},
},
beforeDestroy() {
this.mathFieldInstance = null; // 组件销毁时清除实例
}
};
</script>
<style scoped>
.commonWidth {
width: 100%;
margin: 0 auto;
}
.title {
font-size: 32px;
font-weight: bold;
line-height: 80px;
background-color: #0f4eb6;
color: #fff;
}
.navbar-default {
width: 100%;
height: 80px;
background-color: #0f4eb6;
border-color: #e7e7e7;
}
.math-container {
min-height: 40px;
border: 1px solid #ccc;
padding: 5px;
font-size: 18px;
/* margin-bottom: 20px; */
}
/* 公式弹出框样式 */
.formula-box {
margin-top: 10px;
padding: 10px;
border: 1px solid #ccc;
background-color: #f9f9f9;
display: flex;
flex-direction: column;
align-items: flex-start;
}
/* LaTeX 代码框 */
.latex-text {
width: 100%;
height: 50px;
font-size: 16px;
border: 1px solid #ccc;
padding: 5px;
margin-bottom: 10px;
resize: none;
}
/* 复制按钮 */
button {
padding: 5px 10px;
background-color: #007bff;
color: white;
border: none;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}
/* 防止虚拟键盘覆盖 */
::v-deep .ML__virtual-keyboard-toggle {
opacity: 1 !important; /* 确保虚拟键盘的按钮可见 */
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -361,7 +361,7 @@ export default {
this.add_apply = 0;
break;
case 7:
case 7||16:
// 7文章状态不在审稿中
this.add_apply = 1;
break;
@@ -369,7 +369,7 @@ export default {
//拒绝审稿
this.add_apply = -1;
break;
case 13||16:
case 13:
//13 邀请审稿超过5天未同意邀请16同意审稿后14天未进行审稿
this.add_apply = 2;
break;

View File

@@ -1,4 +1,9 @@
export const tableStyle = `
wmath[data-wrap="inline"] {
display: inline-block !important;
width: auto !important;
}
.word-img-placeholder {
background: #f0f0f0 ;
}

View File

@@ -70,14 +70,10 @@ module.exports = {
},
proxy: {
'/api': {
// target: 'https://www.tmrjournals.cn',
// target: 'http://www.tougao.com/public/index.php/',
// target: 'http://www.tougao.com/',
// target: 'http://192.168.110.110/tougao/public/index.php/',
// target: 'http://api.tmrjournals.com/public/index.php/',//正式
// target: 'http://zmzm.tougao.dev.com/',//晓玲
// target: 'http://zmzm.tougao.dev.com/',//晓玲本地
// target: 'https://submission.tmrjournals.com/',//正式
target: 'http://tougaotest.tmrjournals.com/public/index.php/',//测试环境
// target: 'http://tougaotest.tmrjournals.com/public/index.php/',//测试环境
target: 'http://mytest.tmrjournals.com/public/index.php/',//新正式环境
changeOrigin: true,
pathRewrite: {
'^/api': ''