diff --git a/src/assets/css/main.css b/src/assets/css/main.css index f0f56e2..7a52444 100644 --- a/src/assets/css/main.css +++ b/src/assets/css/main.css @@ -512,7 +512,7 @@ a { } .kuang_communtion .kuang_communtion_conmt { -/* max-height: 350px; + /* max-height: 350px; overflow-y: auto; */ word-break: normal; } @@ -1072,115 +1072,365 @@ a { line-height: 24px; } */ - .wordTableHtml b span { - font-weight: bold !important; +.wordTableHtml b span { + font-weight: bold !important; } - .wordTableHtml i span { - font-style: italic !important; + +.wordTableHtml i span { + font-style: italic !important; } - .wordTableHtml sub span { - vertical-align: sub; + +.wordTableHtml sub span { + vertical-align: sub; } + .wordTableHtml sup span { - vertical-align: super; + vertical-align: super; } - .wordTableHtml sub { - vertical-align: sub !important; + +.wordTableHtml sub { + vertical-align: sub !important; } - .wordTableHtml sup { - vertical-align: super !important; + +.wordTableHtml sup { + vertical-align: super !important; } - .wordTableHtml span[style*='vertical-align: super'] { - vertical-align: super !important; + +.wordTableHtml span[style*='vertical-align: super'] { + vertical-align: super !important; } - .wordTableHtml span[style*='vertical-align: sub'] { - vertical-align: sub !important; + +.wordTableHtml span[style*='vertical-align: sub'] { + vertical-align: sub !important; } + .wordTableHtml table { - border: 0px !important; - border-collapse: collapse; /* 去除单元格间隙 */ - width: auto; - margin: 0 auto !important; - table-layout: auto; /* 自动调整列宽 */ - text-align: left; - font-family: 'Charis SIL' !important; - font-size: 7.5pt !important; - mso-font-kerning: 1pt !important; - line-height: 10pt !important; - mos-line-height: 10pt !important; + border: 0px !important; + border-bottom: 1px solid #000 !important; + border-collapse: collapse; + /* 去除单元格间隙 */ + width: auto; + margin: 0 auto !important; + table-layout: auto; + /* 自动调整列宽 */ + text-align: left; + font-family: 'Charis SIL' !important; + font-size: 7.5pt !important; + mso-font-kerning: 1pt !important; + line-height: 10pt !important; + mos-line-height: 10pt !important; } + .wordTableHtml table td, -.wordTableHtml table th{ - padding: 5px; - text-align: left !important; - - word-wrap: break-word; /* 长单词自动换行 */ - word-break: break-word; - font-family: 'Charis SIL' !important; - font-size: 7.5pt !important; - mso-font-kerning: 1pt !important; - line-height: 10pt !important; - mos-line-height: 10pt !important; +.wordTableHtml table th { + padding: 5px; + text-align: left !important; + + word-wrap: normal; + /* 长单词自动换行 */ + word-break: normal; + + font-family: 'Charis SIL' !important; + font-size: 7.5pt !important; + mso-font-kerning: 1pt !important; + line-height: 10pt !important; + mos-line-height: 10pt !important; } + .wordTableHtml table tbody tr td { - text-align: left !important; - border-left: none !important; - mso-border-left-alt: none !important; - border-right: none !important; - mso-border-right-alt: none !important; - border-top: none; - mso-border-top-alt: none !important; - border-bottom: none !important; - mso-border-bottom-alt: none !important; - border: 1px dashed #dcdfe6 !important; - border-left: 1px dashed #dcdfe6 !important; - border-right: 1px dashed #dcdfe6 !important; - word-break: keep-all !important; - /* text-align: justify !important; */ + text-align: left !important; + border-left: none !important; + mso-border-left-alt: none !important; + border-right: none !important; + mso-border-right-alt: none !important; + border-top: none; + mso-border-top-alt: none !important; + border-bottom: none !important; + mso-border-bottom-alt: none !important; + border: 1px dashed #dcdfe6 !important; + border-left: 1px dashed #dcdfe6 !important; + border-right: 1px dashed #dcdfe6 !important; + word-break: keep-all !important; + /* text-align: justify !important; */ } + .wordTableHtml table tr td p { - display: flex; - text-align: left !important; - align-items: center; - margin: 0; - font-family: 'Charis SIL' !important; - font-size: 7.5pt !important; - mso-font-kerning: 1pt !important; - line-height: 10pt !important; - mos-line-height: 10pt !important; + display: flex; + text-align: left !important; + align-items: center; + margin: 0; + font-family: 'Charis SIL' !important; + font-size: 7.5pt !important; + mso-font-kerning: 1pt !important; + line-height: 10pt !important; + mos-line-height: 10pt !important; } + .wordTableHtml table span { - color: #000000; - text-align: left !important; - font-family: 'Charis SIL' !important; - font-size: 7.5pt !important; - mso-font-kerning: 1pt !important; - line-height: 10pt !important; - mos-line-height: 10pt !important; + color: #000000; + text-align: left !important; + font-family: 'Charis SIL' !important; + font-size: 7.5pt !important; + mso-font-kerning: 1pt !important; + line-height: 10pt !important; + mos-line-height: 10pt !important; } + .wordTableHtml table .color-highlight { - color: rgb(0, 130, 170) !important; - font-family: 'Charis SIL' !important; - font-size: 7.5pt !important; - mso-font-kerning: 1pt !important; - line-height: 10pt !important; - mos-line-height: 10pt !important; + color: rgb(0, 130, 170) !important; + font-family: 'Charis SIL' !important; + font-size: 7.5pt !important; + mso-font-kerning: 1pt !important; + line-height: 10pt !important; + mos-line-height: 10pt !important; } + .wordTableHtml table blue { - color: rgb(0, 130, 170) !important; - font-family: 'Charis SIL' !important; - font-size: 7.5pt !important; - mso-font-kerning: 1pt !important; - line-height: 10pt !important; - mos-line-height: 10pt !important; + color: rgb(0, 130, 170) !important; + font-family: 'Charis SIL' !important; + font-size: 7.5pt !important; + mso-font-kerning: 1pt !important; + line-height: 10pt !important; + mos-line-height: 10pt !important; } - .wordTableHtml table tr:first-child td { - border-top: 1px solid #000 !important; - - border-bottom: 1px solid #000 !important; - + +.wordTableHtml table tr:first-child td { + border-top: 1px solid #000 !important; + + border-bottom: 1px solid #000 !important; + } - .wordTableHtml table tr:last-of-type td { + +/* 给表格中最后一行表头添加红色下边框 */ +/* 给最后一个 table-header-row 添加红色下边框 */ + + + +.wordTableHtml table tr:last-of-type td { + border-bottom: 1px solid #000 !important; + +} + +/* 给最后一个 table-header-row(第二行)加样式 */ +.wordTableHtml table tr.table-header-row:nth-of-type(2) td { border-bottom: 1px solid #000 !important; - +} + +.word-container b span { + font-weight: bold !important; +} + +.word-container i span { + font-style: italic !important; +} + +.word-container sub span { + vertical-align: sub; +} + +.word-container sup span { + vertical-align: sup; +} + +.word-container sub { + vertical-align: sub !important; +} + +.word-container sup { + vertical-align: sup !important; +} + +.word-container span[style*='vertical-align: super'] { + vertical-align: super !important; +} + +.word-container span[style*='vertical-align: sub'] { + vertical-align: sub !important; +} + +.word-container table { + border: 0px !important; + border-collapse: collapse; + /* 去除单元格间隙 */ + width: auto; + margin: 0 auto !important; + table-layout: auto; + /* 自动调整列宽 */ + text-align: left; + font-family: 'Charis SIL' !important; + font-size: 7.5pt !important; + mso-font-kerning: 1pt !important; + line-height: 10pt !important; + mos-line-height: 10pt !important; +} + +.word-container table td, +.word-container table th { + padding: 5px; + text-align: left !important; + white-space: pre-wrap; + /* 保留换行符并换行 */ + word-wrap: normal; + /* 长单词自动换行 */ + word-break: normal; + font-family: 'Charis SIL' !important; + font-size: 7.5pt !important; + mso-font-kerning: 1pt !important; + line-height: 10pt !important; + mos-line-height: 10pt !important; +} + +.word-container table tbody tr td { + text-align: left !important; + border-left: none !important; + mso-border-left-alt: none !important; + border-right: none !important; + mso-border-right-alt: none !important; + border-top: none; + mso-border-top-alt: none !important; + border-bottom: none !important; + mso-border-bottom-alt: none !important; + border: 1px dashed #dcdfe6 !important; + border-left: 1px dashed #dcdfe6 !important; + border-right: 1px dashed #dcdfe6 !important; + word-break: keep-all !important; + white-space: pre-wrap !important; + /* text-align: justify !important; */ +} + +.word-container table tr td p { + text-align: left !important; + + margin: 0; + font-family: 'Charis SIL' !important; + font-size: 7.5pt !important; + mso-font-kerning: 1pt !important; + line-height: 10pt !important; + mos-line-height: 10pt !important; +} + +.word-container table span { + color: #000000; + text-align: left !important; + font-family: 'Charis SIL' !important; + font-size: 7.5pt !important; + mso-font-kerning: 1pt !important; + line-height: 10pt !important; + mos-line-height: 10pt !important; +} + +.word-container table .color-highlight { + color: rgb(0, 130, 170) !important; + font-family: 'Charis SIL' !important; + font-size: 7.5pt !important; + mso-font-kerning: 1pt !important; + line-height: 10pt !important; + mos-line-height: 10pt !important; +} + +.word-container table tr:first-child td { + /* border-top: 1pt solid #000 !important; + mso-border-top-alt: 0.5pt solid #000 !important; + border-bottom: 1pt solid #000 !important; + mso-border-bottom-alt: 0.5pt solid #000 !important; */ +} + +.word-container table tr:last-of-type { + border-bottom: 1pt solid #000 !important; + mso-border-bottom-alt: 0.5pt solid #000 !important; +} + +.word-container blue { + color: rgb(0, 130, 170) !important; +} + +.tinymce-custom-button-blue { + font-weight: bold !important; + color: #007bff !important; + /* 设置字体颜色 */ +} + +.tinymce-custom-button-commentadd { + font-weight: bold !important; + background-color: #fef0f0 !important; + color: #f56c6c !important; + /* 设置字体颜色 */ + fill: #f56c6c !important; + /* font-size:16px!important; */ + /* 设置字体颜色 */ +} + +.tinymce-custom-button-commentadd svg { + + fill: #f56c6c !important; + +} + +.tinymce-custom-button-delete { + font-weight: bold !important; + background-color: red !important; + color: #fff !important; + /* 设置字体颜色 */ + fill: #fff !important; + /* font-size:16px!important; */ + /* 设置字体颜色 */ +} + +.tinymce-custom-button-delete svg { + + + fill: #fff !important; + +} + +.tinymce-custom-button-edit { + font-weight: bold !important; + background-color: rgb(43, 129, 239) !important; + color: #fff !important; + /* 设置字体颜色 */ + fill: #fff !important; + /* font-size:16px!important; */ + /* 设置字体颜色 */ +} + +.tinymce-custom-button-edit svg { + + + fill: #fff !important; + +} + +.tinymce-custom-button-save { + font-weight: bold !important; + background-color: rgb(19, 188, 32) !important; + color: #fff !important; + /* 设置字体颜色 */ + fill: #fff !important; + /* font-size:16px!important; */ + /* 设置字体颜色 */ +} + +.tinymce-custom-button-addrow { + font-weight: bold !important; + background-color: #cbccd1 !important; + /* color: #fff !important; */ + /* 设置字体颜色 */ + /* fill: #fff !important; */ + /* font-size:16px!important; */ + /* 设置字体颜色 */ +} + +.tinymce-custom-button-save svg { + + + fill: #fff !important; + +} + +.tinymce-custom-button-removeblue { + font-weight: bold !important; + color: #007bff !important; + /* 设置字体颜色 */ + text-decoration: line-through !important; + /* 设置字体颜色 */ } \ No newline at end of file diff --git a/src/assets/img/carriageReturn.png b/src/assets/img/carriageReturn.png new file mode 100644 index 0000000..51c67a7 Binary files /dev/null and b/src/assets/img/carriageReturn.png differ diff --git a/src/assets/img/deleteComment.png b/src/assets/img/deleteComment.png new file mode 100644 index 0000000..a68d095 Binary files /dev/null and b/src/assets/img/deleteComment.png differ diff --git a/src/assets/img/replyComment.png b/src/assets/img/replyComment.png new file mode 100644 index 0000000..dc43ad9 Binary files /dev/null and b/src/assets/img/replyComment.png differ diff --git a/src/assets/img/selectComment.png b/src/assets/img/selectComment.png new file mode 100644 index 0000000..042bd7f Binary files /dev/null and b/src/assets/img/selectComment.png differ diff --git a/src/assets/img/solveComment.png b/src/assets/img/solveComment.png new file mode 100644 index 0000000..3926175 Binary files /dev/null and b/src/assets/img/solveComment.png differ diff --git a/src/assets/img/uploadTable.png b/src/assets/img/uploadTable.png index 73bffa7..efadfe3 100644 Binary files a/src/assets/img/uploadTable.png and b/src/assets/img/uploadTable.png differ diff --git a/src/common/js/commonJS.js b/src/common/js/commonJS.js index 627cd09..6ff51a2 100644 --- a/src/common/js/commonJS.js +++ b/src/common/js/commonJS.js @@ -1,7 +1,8 @@ +import Vue from 'vue'; import JSZip from 'jszip'; import Common from '@/components/common/common' import Tiff from 'tiff.js'; -var mediaUrl = Common.mediaUrl+'articleImage/'; +var mediaUrl = Common.mediaUrl + 'articleImage/'; // var mediaUrl1 = 'https://submission.tmrjournals.com/public/articleImage/'; const fs = require('fs'); @@ -17,13 +18,19 @@ const capitalizeFirstLetter = function (text) { }); }; export default { + decodeHtml(html) { + var txt = document.createElement('textarea'); + txt.innerHTML = html; + return txt.value; + }, //去掉最外层自定义的span标签 extractContentWithoutOuterSpan(cell) { var str = '' // 获取单元格的 HTML 内容 let htmlContent = cell.innerHTML.trim(); + str = this.transformHtmlString(htmlContent) - + // 创建一个临时的 DOM 元素来解析 HTML const div = document.createElement('div'); div.innerHTML = htmlContent; @@ -42,10 +49,26 @@ export default { str = capitalizeFirstLetter(str); // 添加蓝色标签 - const regex = /\[\d+(?:,\d+)*\]/g; + const regex = /\[(\d+(?:–\d+)?(?:, ?\d+(?:–\d+)?)*)\]/g; + + str = str.replace(//g, '').replace(/<\/blue>/g, ''); // 先去掉所有的 标签 + if (regex.test(str)) { - str = `${str}`; + str = str.replace(regex, function(match) { + // 提取出方括号中的内容,并进行匹配 + const content = match.slice(1, match.length - 1); // 去掉方括号 + + // 判断是否符合条件,纯数字、逗号后有空格、连字符 + if (/^\d+$/.test(content) || /, ?/.test(content) || /–/.test(content)) { + return `${match}`; // 如果符合条件则加上蓝色标签 + } + return match; // 如果不符合条件,则保持原样 + }); } + + + + // 如果没有 标签,直接返回原始 HTML 内容 return str; }, @@ -54,7 +77,7 @@ export default { // 创建临时 DOM 容器 const tempDiv = document.createElement("div"); tempDiv.innerHTML = pastedHtml; // 插入粘贴的 HTML 内容 - + // 获取表格 const tables = tempDiv.querySelectorAll("table"); if (tables.length === 0) { @@ -62,31 +85,31 @@ export default { callback([]); return; } - + const allTables = []; // 存储所有表格的二维数组 - + for (const table of tables) { const rows = table.querySelectorAll("tr"); const tableArray = []; // 当前表格的二维数组 - + // 存储合并单元格信息 const mergeMap = {}; - + rows.forEach((row, rowIndex) => { const cells = row.querySelectorAll("td, th"); const rowArray = []; - + let colIndex = 0; - + cells.forEach((cell) => { // 跳过被合并的单元格 while (mergeMap[`${rowIndex},${colIndex}`]) { colIndex++; } - + // 获取单元格内容,如果为空则设置为默认值 let cellText = cell.innerText.trim() || " "; // 处理空值 - + // 处理样式 if (cell.style.fontWeight === "bold") { cellText = `${cellText}`; @@ -100,18 +123,18 @@ export default { if (cell.style.verticalAlign === "sub") { cellText = `${cellText}`; } - + // 检查合并单元格属性 const colspan = parseInt(cell.getAttribute("colspan") || "1", 10); const rowspan = parseInt(cell.getAttribute("rowspan") || "1", 10); - + // 保存当前单元格信息 rowArray[colIndex] = { text: cellText, colspan: colspan, rowspan: rowspan, }; - + // 更新合并单元格信息 if (rowspan > 1 || colspan > 1) { for (let i = 0; i < rowspan; i++) { @@ -121,16 +144,16 @@ export default { } } } - + colIndex++; // 移动到下一列 }); - + tableArray.push(rowArray); // 添加当前行到表格数组 }); - + allTables.push(tableArray); // 添加当前表格到所有表格数组 } - + console.log("解析后的表格数组:", allTables); callback(allTables); // 返回处理后的数组 } catch (error) { @@ -138,7 +161,7 @@ export default { callback([]); } }, - + async extractWordTablesToArrays(file, callback) { const Zip = new JSZip(); try { @@ -272,11 +295,30 @@ export default { formattedText = capitalizeFirstLetter(formattedText); // 添加蓝色标签 - const regex = /\[\d+(?:,\d+)*\]/g; - if (regex.test(formattedText)) { - formattedText = `${formattedText}`; - } + + + const regex = /\[(\d+(?:–\d+)?(?:, ?\d+(?:–\d+)?)*)\]/g; + + formattedText = formattedText.replace(//g, '').replace(/<\/blue>/g, ''); // 先去掉所有的 标签 + + if (regex.test(formattedText)) { + formattedText = formattedText.replace(regex, function(match) { + // 提取出方括号中的内容,并进行匹配 + const content = match.slice(1, match.length - 1); // 去掉方括号 + + // 判断是否符合条件,纯数字、逗号后有空格、连字符 + if (/^\d+$/.test(content) || /, ?/.test(content) || /–/.test(content)) { + return `${match}`; // 如果符合条件则加上蓝色标签 + } + return match; // 如果不符合条件,则保持原样 + }); + } + console.log("After replacement:", formattedText); // 调试:查看替换后的文本 + + + + paragraphText += formattedText; } @@ -324,11 +366,12 @@ export default { } }, transformHtmlString(inputHtml) { + inputHtml = inputHtml.replace(/(<[^>]+) style="[^"]*"/g, '$1'); // 移除style属性 inputHtml = inputHtml.replace(/(<[^>]+) class="[^"]*"/g, '$1'); // 移除class属性 // 2. 删除所有不需要的标签 (除 `strong`, `em`, `sub`, `sup`, `b`, `i` 外的所有标签) - inputHtml = inputHtml.replace(/<(?!\/?(strong|em|sub|sup|b|i))[^>]+>/g, ''); // 删除不需要的标签 + inputHtml = inputHtml.replace(/<(?!\/?(strong|em|sub|sup|b|i|blue))[^>]+>/g, ''); // 删除不需要的标签 // 3. 如果有 `` 和 `` 标签,去掉内部样式并保留内容 inputHtml = inputHtml.replace(/]*>/g, '').replace(/<\/span>/g, ''); // 去除span标签 @@ -444,23 +487,23 @@ export default { console.log('numberingMap at line 232:', numberingMap) // 提取表格 // 获取所有的段落 - const paragraphs = xmlDoc.getElementsByTagName("w:p"); - // 获取所有的表格 - const tables = xmlDoc.getElementsByTagName("w:tbl"); + const paragraphs = xmlDoc.getElementsByTagName("w:p"); + // 获取所有的表格 + const tables = xmlDoc.getElementsByTagName("w:tbl"); - // 找到表格前的段落 - let previousParagraphs = []; - let tableIndex = 0; + // 找到表格前的段落 + let previousParagraphs = []; + let tableIndex = 0; - // 遍历段落,找到第一个表格之前的段落 - for (let i = 0; i < paragraphs.length; i++) { - if (tableIndex < tables.length && paragraphs[i].nextSibling === tables[tableIndex]) { - break; // 找到表格 + // 遍历段落,找到第一个表格之前的段落 + for (let i = 0; i < paragraphs.length; i++) { + if (tableIndex < tables.length && paragraphs[i].nextSibling === tables[tableIndex]) { + break; // 找到表格 + } + previousParagraphs.push(paragraphs[i]); } - previousParagraphs.push(paragraphs[i]); - } -// 将前一段的内容转化为 HTML 或文本 -const previousHtml = this.convertParagraphsToHtml(previousParagraphs); + // 将前一段的内容转化为 HTML 或文本 + const previousHtml = this.convertParagraphsToHtml(previousParagraphs); console.log('tables at line 17:', previousHtml) const tableHtml = this.convertTablesToHtml(tables, numberingMap); console.log('tableHtml at line 18:', tableHtml) @@ -477,45 +520,45 @@ const previousHtml = this.convertParagraphsToHtml(previousParagraphs); callback("

文件解析失败,请检查文件格式。

"); } }, -// 转换段落为 HTML -convertParagraphsToHtml(paragraphs) { - let html = ""; - paragraphs.forEach(p => { - let paragraphHtml = ""; - - // 处理段落中的所有子元素 - const runs = p.getElementsByTagName("w:r"); // 获取段落中的所有文本运行(可能包含上标、下标等) - - Array.from(runs).forEach(run => { - let text = ""; - - // 获取文本内容 - const textNodes = run.getElementsByTagName("w:t"); - Array.from(textNodes).forEach(t => { - text += t.textContent || t.text; + // 转换段落为 HTML + convertParagraphsToHtml(paragraphs) { + let html = ""; + paragraphs.forEach(p => { + let paragraphHtml = ""; + + // 处理段落中的所有子元素 + const runs = p.getElementsByTagName("w:r"); // 获取段落中的所有文本运行(可能包含上标、下标等) + + Array.from(runs).forEach(run => { + let text = ""; + + // 获取文本内容 + const textNodes = run.getElementsByTagName("w:t"); + Array.from(textNodes).forEach(t => { + text += t.textContent || t.text; + }); + + // 检查是否为上标或下标 + const isSuperscript = run.getElementsByTagName("w:vertAlign")[0] ? run.getElementsByTagName("w:vertAlign")[0].getAttribute("w:val") === "superscript" : ""; + const isSubscript = run.getElementsByTagName("w:vertAlign")[0] ? run.getElementsByTagName("w:vertAlign")[0].getAttribute("w:val") === "subscript" : ''; + + if (isSuperscript) { + text = `${text}`; + } else if (isSubscript) { + text = `${text}`; + } + + // 拼接到段落 HTML 中 + paragraphHtml += text; }); - - // 检查是否为上标或下标 - const isSuperscript = run.getElementsByTagName("w:vertAlign")[0]?run.getElementsByTagName("w:vertAlign")[0].getAttribute("w:val") === "superscript":""; - const isSubscript = run.getElementsByTagName("w:vertAlign")[0]?run.getElementsByTagName("w:vertAlign")[0].getAttribute("w:val") === "subscript":''; - if (isSuperscript) { - text = `${text}`; - } else if (isSubscript) { - text = `${text}`; - } - - // 拼接到段落 HTML 中 - paragraphHtml += text; + // 将运行的文本拼接成完整的段落 + html += `

${paragraphHtml}

`; }); - // 将运行的文本拼接成完整的段落 - html += `

${paragraphHtml}

`; - }); - - return html; -} -, + return html; + } + , convertTablesToHtml(tables, numberingMap) { const namespace = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"; let html = ""; @@ -773,7 +816,7 @@ convertParagraphsToHtml(paragraphs) { if (['jpg', 'jpeg', 'png'].includes(extension)) { thumbnailContent = `Image ${index}`; } else if (extension === 'tif') { - thumbnailContent = ``; + thumbnailContent = ``; } else { thumbnailContent = `
{ @@ -1150,6 +1193,487 @@ convertParagraphsToHtml(paragraphs) { }, + initEditorButton(vueInstance, ed) { + + ed.ui.registry.addMenuButton('customDropdown', { + text: 'Set Title', // 下拉框标题 + fetch: function (callback) { + // 定义下拉框的内容 + const items = [ + { + label: 'First level title', + value: 1 + }, + { + label: 'Secondary Title', + value: 2 + }, + { + label: 'Third level title', + value: 3 + } + ]; + const menuItems = items.map((item) => ({ + type: 'menuitem', + text: item.label, + onAction: function () { + var edSelection = ed.selection; + const selectedNode = edSelection.getNode(); // 获取选中的节点 + if (selectedNode) { + // 向上查找最外层的 div + let outerDiv = selectedNode; + while (outerDiv && outerDiv.tagName !== 'DIV') { + outerDiv = outerDiv.parentNode; + } + // 如果找到的 div 节点存在 + if (outerDiv) { + const dataId = outerDiv.getAttribute('main-id'); + vueInstance.$emit('onEditTitle', { + mainId: dataId, + value: item.value + }); + } + } + } + })); + callback(menuItems); + } + }); + ed.ui.registry.addButton('addRow', { + icon:'duplicate-row', + text: 'Add Row', // 下拉框标题 + onAction: function () { + var edSelection = ed.selection; + const selectedNode = edSelection.getNode(); // 获取选中的节点 + let outerDiv = selectedNode; + while (outerDiv && outerDiv.tagName !== 'DIV') { + outerDiv = outerDiv.parentNode; + } + // 如果找到的 div 节点存在 + if (outerDiv) { + const dataId = outerDiv.getAttribute('main-id'); + console.log('dataId at line 1258:', dataId) + + vueInstance.$emit('onAddRow', dataId); + } + } + + }); + // 添加自定义菜单项 + ed.ui.registry.addButton('Save', { + icon: 'checkmark', + text: 'Save', + onAction: function () { + var deleteButtons = document.querySelectorAll('.tox-tinymce-inline'); + var edSelection = ed.selection; + const selectedNode = edSelection.getNode(); // 获取选中的节点 + let outerDiv = selectedNode; + while (outerDiv && outerDiv.tagName !== 'DIV') { + outerDiv = outerDiv.parentNode; + } + // 如果找到的 div 节点存在 + if (outerDiv) { + const dataId = outerDiv.getAttribute('main-id'); + var content; + console.log('outerDiv at line 663:', outerDiv.innerHTML); + content = outerDiv.innerHTML.replace(/<(?!\/?(img|b|i|sub|sup|span|strong|em |blue)\b)[^>]+>/g, ''); + content = content.replace(/<([a-zA-Z]+)>\s*<\/\1>/g, ''); + content = content.replace(/ /g, ' '); + + content = content.replace(/\s*style="[^"]*"/g, ''); + + var div = document.createElement('div'); + div.innerHTML = content; // 将 HTML 字符串加载到 div 中 + // 替换所有 + var strongTags = div.getElementsByTagName('strong'); + for (var i = 0; i < strongTags.length; i++) { + var bTag = document.createElement('b'); + bTag.innerHTML = strongTags[i].innerHTML; // 保留内容 + strongTags[i].parentNode.replaceChild(bTag, strongTags[i]); + } + + // 替换所有 + var emTags = div.getElementsByTagName('em'); + for (var i = 0; i < emTags.length; i++) { + var iTag = document.createElement('i'); + iTag.innerHTML = emTags[i].innerHTML; // 保留内容 + emTags[i].parentNode.replaceChild(iTag, emTags[i]); + } + content = div.innerHTML; + + vueInstance.$emit('saveContent', content, dataId); + } + } + }); + ed.ui.registry.addButton('level1', { + // icon: 'highlight-bg-color', + text: 'First level title', + onAction: function () { + var edSelection = ed.selection; + const selectedNode = edSelection.getNode(); // 获取选中的节点 + let outerDiv = selectedNode; + while (outerDiv && outerDiv.tagName !== 'DIV') { + outerDiv = outerDiv.parentNode; + } + // 如果找到的 div 节点存在 + if (outerDiv) { + const dataId = outerDiv.getAttribute('main-id'); + console.log('dataId at line 1258:', dataId) + vueInstance.$emit('onEditTitle', { + mainId: dataId, + value: 1 + }); + + } + } + }); + ed.ui.registry.addButton('level2', { + // icon: 'highlight-bg-color', + text: 'Second level Title', + onAction: function () { + var edSelection = ed.selection; + const selectedNode = edSelection.getNode(); // 获取选中的节点 + let outerDiv = selectedNode; + while (outerDiv && outerDiv.tagName !== 'DIV') { + outerDiv = outerDiv.parentNode; + } + // 如果找到的 div 节点存在 + if (outerDiv) { + const dataId = outerDiv.getAttribute('main-id'); + console.log('dataId at line 1258:', dataId) + vueInstance.$emit('onEditTitle', { + mainId: dataId, + value: 2 + }); + + } + } + }); + ed.ui.registry.addButton('level3', { + // icon: 'highlight-bg-color', + text: 'Third level title', + onAction: function () { + var edSelection = ed.selection; + const selectedNode = edSelection.getNode(); // 获取选中的节点 + let outerDiv = selectedNode; + while (outerDiv && outerDiv.tagName !== 'DIV') { + outerDiv = outerDiv.parentNode; + } + // 如果找到的 div 节点存在 + if (outerDiv) { + const dataId = outerDiv.getAttribute('main-id'); + console.log('dataId at line 1258:', dataId) + vueInstance.$emit('onEditTitle', { + mainId: dataId, + value: 3 + }); + + } + } + }); + ed.ui.registry.addButton('Edit', { + icon: 'highlight-bg-color', + text: 'Edit', + onAction: function () { + var edSelection = ed.selection; + const selectedNode = edSelection.getNode(); // 获取选中的节点 + let outerDiv = selectedNode; + while (outerDiv && outerDiv.tagName !== 'DIV') { + outerDiv = outerDiv.parentNode; + } + // 如果找到的 div 节点存在 + if (outerDiv) { + const dataId = outerDiv.getAttribute('main-id'); + console.log('dataId at line 1258:', dataId) + + vueInstance.$emit('onEdit', dataId); + } + } + }); + + + ed.ui.registry.addButton('commentAdd', { + icon: 'comment-add', + text: 'Comment Add', + onAction: function () { + var edSelection = ed.selection; + const selectedNode = edSelection.getNode(); // 获取选中的节点 + if (selectedNode) { + // 向上查找最外层的 div + let outerDiv = selectedNode; + while (outerDiv && outerDiv.tagName !== 'DIV') { + outerDiv = outerDiv.parentNode; + } + // 如果找到的 div 节点存在 + if (outerDiv) { + const dataId = outerDiv.getAttribute('main-id'); + const type = outerDiv.getAttribute('type'); + + console.log('type:', type); + + // 获取选中的内容(HTML格式) + let selectedContent = edSelection.getContent({ format: 'html' }); + + // 创建一个临时容器来处理 HTML + const tempDiv = document.createElement('div'); + tempDiv.innerHTML = selectedContent; + + // 检查是否包含 标签 + const hasImage = tempDiv.querySelector('img') !== null; + if (hasImage) { + vueInstance.$message.error(vueInstance.$t('commonTable.selectComment')); + return; // 如果包含图片,停止处理 + } + + // 获取清理后的纯文本内容 + let selectedText = tempDiv.innerText.trim(); // 使用 trim() 清理前后的空格 + + // 处理文本中的多余空格:替换多个连续空格为一个空格 + selectedText = selectedText.replace(/\s+/g, ' '); + + // 确保保留的标签 + const allowedTags = ['sup', 'sub', 'strong', 'em', 'b', 'i', 'blue', 'tr', 'td']; + + // 遍历选中的节点并保留需要的标签 + function preserveTags(node) { + if (node.nodeType === 3) { // 文本节点 + return node.nodeValue; + } + if (node.nodeType === 1 && allowedTags.includes(node.nodeName.toLowerCase())) { + return node.outerHTML; // 保留整个标签 + } + return ''; + } + + let preservedContent = ''; + Array.from(tempDiv.childNodes).forEach((childNode) => { + preservedContent += preserveTags(childNode); + }); + + // 检查选中的内容是否已经包含嵌套批注 + const containsPositionRemark = tempDiv.querySelector('.positionRemarkIndex'); + if (containsPositionRemark) { + vueInstance.$message.error(vueInstance.$t('commonTable.alreadyCommented')); + return; // 如果已有嵌套批注,停止处理 + } + + // 如果内容不为空,发送批注请求 + if (type == 0) { + if (selectedText !== '') { + vueInstance.$emit('onAddComment', { + mainId: dataId, + label: preservedContent // 发送保留标签的内容 + }); + } else { + vueInstance.$message.error(vueInstance.$t('commonTable.selectComment')); + } + } else if (type == 1) { + vueInstance.$emit('onAddComment', { + mainId: dataId, + label: preservedContent // 发送保留标签的内容 + }); + } else if (type == 2) { + vueInstance.$emit('onAddComment', { + mainId: dataId, + label: preservedContent // 发送保留标签的内容 + }); + } + } + } + } + }); + + + + + + + ed.ui.registry.addButton('delete', { + icon: 'remove', + text: 'Delete', + onAction: function () { + var edSelection = ed.selection; + const selectedNode = edSelection.getNode(); // 获取选中的节点 + if (selectedNode) { + // 向上查找最外层的 div + let outerDiv = selectedNode; + while (outerDiv && outerDiv.tagName !== 'DIV') { + outerDiv = outerDiv.parentNode; + } + // 如果找到的 div 节点存在 + if (outerDiv) { + const dataId = outerDiv.getAttribute('main-id'); + vueInstance.$emit('onDelete', dataId); + } + } + + } + }); + + // 定义自定义按钮 + ed.ui.registry.addButton('clearButton', { + text: 'Empty', + + onAction: () => { + // 插入自定义表格到编辑器中 + ed.setContent(''); + } + }); + + + ed.ui.registry.addButton('customBlue', { + text: 'Blue', // 按钮文本 + className: 'custom-button-blue', // 添加自定义类 + // shortcut: "Ctrl+J", + onAction: function () { + // 在选中的文本周围包裹 标签 + var selectedText = ed.selection.getContent(); + console.log('selectedText at line 529:', selectedText); + if (selectedText) { + var wrappedText = `${selectedText}`; + ed.selection.setContent(wrappedText); + } else { + this.$message.error('请选择要添加蓝色的文本'); + } + } + }); + + ed.ui.registry.addButton('myuppercase', { + text: 'A', // 按钮文本 + + onAction: function () { + // 在选中的文本周围包裹 标签 + var selectedText = ed.selection.getContent({ format: 'html' }); + + // 确保选中的文本是单个单词,包括空格 + if (selectedText.trim() && /^[\s\w]+$/.test(selectedText)) { + // 使用正则将选中的文本中的第一个字母大写 + var capitalizedText = selectedText.replace(/(^|\s)([a-zA-Z])/g, function(match, p1, p2) { + return p1 + p2.toUpperCase(); + }); + + // 替换选中的文本,保持空格和其他内容 + ed.selection.setContent(capitalizedText); + } else { + vueInstance.$message.error(vueInstance.$t('commonTable.selectWord')); + + } + } + }); + ed.ui.registry.addButton('myuppercase', { + text: 'A', // 按钮文本 + + onAction: function () { + // 在选中的文本周围包裹 标签 + var selectedText = ed.selection.getContent({ format: 'html' }); + + // 确保选中的文本是单个单词,包括空格 + if (selectedText.trim() && /^[\s\w]+$/.test(selectedText)) { + // 使用正则将选中的文本中的第一个字母大写 + var capitalizedText = selectedText.replace(/(^|\s)([a-zA-Z])/g, function(match, p1, p2) { + return p1 + p2.toUpperCase(); + }); + + // 替换选中的文本,保持空格和其他内容 + ed.selection.setContent(capitalizedText); + } else { + vueInstance.$message.error(vueInstance.$t('commonTable.selectWord')); + + } + } + }); + ed.ui.registry.addButton('myuppercasea', { + text: 'a', // 按钮文本(小写字母) + onAction: function () { + // 获取选中的文本,保留 HTML 格式 + var selectedText = ed.selection.getContent({ format: 'html' }); + + // 确保选中的文本是单个有效的单词,包括空格 + if (selectedText.trim() && /^[\s\w]+$/.test(selectedText)) { + // 使用正则将选中的文本中的第一个字母转换为小写 + var lowercasedText = selectedText.replace(/(^|\s)([a-zA-Z])/g, function(match, p1, p2) { + return p1 + p2.toLowerCase(); + }); + + // 替换选中的文本,保持空格和其他内容 + ed.selection.setContent(lowercasedText); + } else { + vueInstance.$message.error(vueInstance.$t('commonTable.selectWord')); + } + } + }); + ed.ui.registry.addButton('Line', { + text: '−', // 按钮文本 + onAction: function () { + // 插入 `−` 符号到当前光标位置 + ed.insertContent('−'); + } +}); + + + ed.ui.registry.addButton('removeBlue', { + text: 'Blue', // 按钮文本 + onAction: function () { + const range = ed.selection.getRng(); // 获取选区范围 + let startNode = range.startContainer; // 获取选区起始节点 + let closestBlue = null; + + // 向上查找最近的 标签 + while (startNode) { + if (startNode.nodeName && startNode.nodeName.toLowerCase() === 'blue') { + closestBlue = startNode; + break; + } + startNode = startNode.parentNode; + } + if (closestBlue) { + // 如果找到最近的 标签,移除它的外层标签,但保留内容 + const parent = closestBlue.parentNode; + while (closestBlue.firstChild) { + parent.insertBefore(closestBlue.firstChild, closestBlue); + } + parent.removeChild(closestBlue); + } else { + // 未找到 标签,仅移除选中的 标签内容 + const selectedContent = ed.selection.getContent({ format: 'html' }); + + // 使用正则表达式移除选区中的 标签 + const cleanedContent = selectedContent + .replace(/]*>/g, '') // 删除起始标签 + .replace(/<\/blue>/g, ''); // 删除结束标签 + + // 更新选中的内容 + ed.selection.setContent(cleanedContent); + } + } + }); + }, + inTinymceButtonClass() { + setTimeout(function () { + // 使用 querySelectorAll 获取所有符合条件的按钮 + const buttons = [ + { selector: '.tox-tbtn[data-mce-name="commentadd"]', className: 'tinymce-custom-button-commentadd' }, + { selector: '.tox-tbtn[data-mce-name="addrow"]', className: 'tinymce-custom-button-addrow' }, + { selector: '.tox-tbtn[data-mce-name="delete"]', className: 'tinymce-custom-button-delete' }, + { selector: '.tox-tbtn[data-mce-name="edit"]', className: 'tinymce-custom-button-edit' }, + { selector: '.tox-tbtn[data-mce-name="save"]', className: 'tinymce-custom-button-save' }, + { selector: '.tox-tbtn[data-mce-name="customblue"]', className: 'tinymce-custom-button-blue' }, + { selector: '.tox-tbtn[data-mce-name="removeblue"]', className: 'tinymce-custom-button-removeblue' } + ]; + + // 遍历每个按钮并为每个按钮添加类 + buttons.forEach(item => { + const buttonElements = document.querySelectorAll(item.selector); + buttonElements.forEach(button => { + if (!button.classList.contains(item.className)) { // 防止重复添加 + button.classList.add(item.className); + } + }); + }); + }, 100); // 延迟执行,确保按钮渲染完成 + } + + // 通用递归方法 }; diff --git a/src/components/common/Header.vue b/src/components/common/Header.vue index f08432a..822e75a 100644 --- a/src/components/common/Header.vue +++ b/src/components/common/Header.vue @@ -1,45 +1,47 @@ diff --git a/src/components/common/Header2.vue b/src/components/common/Header2.vue new file mode 100644 index 0000000..d4e1f53 --- /dev/null +++ b/src/components/common/Header2.vue @@ -0,0 +1,403 @@ + + + diff --git a/src/components/common/Home.vue b/src/components/common/Home.vue index d48f9ed..97382ae 100644 --- a/src/components/common/Home.vue +++ b/src/components/common/Home.vue @@ -1,23 +1,41 @@ - \ No newline at end of file + diff --git a/src/components/page/GenerateCharts.vue b/src/components/page/GenerateCharts.vue index 469b66e..789a97e 100644 --- a/src/components/page/GenerateCharts.vue +++ b/src/components/page/GenerateCharts.vue @@ -1,15 +1,9 @@ + + + diff --git a/src/components/page/ReferenceEditor.vue b/src/components/page/ReferenceEditor.vue index ba975a5..dbd18a7 100644 --- a/src/components/page/ReferenceEditor.vue +++ b/src/components/page/ReferenceEditor.vue @@ -103,7 +103,7 @@ - + @@ -281,12 +304,12 @@ Typesetting completed
@@ -1001,104 +1026,71 @@ export default { }); }, getWord() { - var htmlContent = ``; - htmlContent += this.mains - .map((item) => { - //批注 - let contentHtml = ''; - var isRemark = ``; +// var htmlContent = ``; +// htmlContent += this.mains +// .map((item) => { +// //批注 +// let contentHtml = ''; +// var isRemark = ``; - // 判断是否是图片 - if (item.type == 1) { - var extension = item.image.url.split('.').pop().toLowerCase(); - if (extension == 'tif') { - contentHtml = ` -

- - ${item.image.note ? item.image.note : ''} -

- `; - } else if (['jpg', 'jpeg', 'png'].includes(extension)) { - contentHtml = ` -

- ${isRemark} - - ${ - item.image.note ? item.image.note : '' - } -

- `; - } else { - contentHtml = ` -

- ${isRemark} - - Figures ( .${item.image.url.split('.').pop().toUpperCase()}) - +// // 判断是否是图片 +// if (item.type == 1) { +// contentHtml = ` +//

+// ${isRemark} +// +// ${ +// item.image.note ? item.image.note : '' +// } +//

+// `; +// } else if (item.type == 2) { +// var tableList = JSON.parse(item.table.table_data); - ${ - item.image.note ? item.image.note : '' - } -

- `; - } - } else if (item.type == 2) { - var tableList = JSON.parse(item.table.table_data); +// contentHtml = ` +//
+// ${isRemark} +// ${item.table.title ? item.table.title : ''} +// +// ${tableList +// .map((row) => { +// return ` +// +// ${row +// .map((cell) => { +// return ` +// +// `; +// }) +// .join('')} +// +// `; +// }) +// .join('')} +//
+// ${cell.text || ''} +//
+// ${item.table.note ? item.table.note : ''} +//
+// `; +// } else { + +// contentHtml = `

${isRemark}${item.content}

`; +// } - contentHtml = ` -
- ${isRemark} - ${item.table.title ? item.table.title : ''} - - ${tableList - .map((row) => { - return ` - - ${row - .map((cell) => { - return ` - - `; - }) - .join('')} - - `; - }) - .join('')} -
- ${cell.text || ''} -
- ${item.table.note ? item.table.note : ''} -
-`; - } else { - contentHtml = `

${isRemark}${item.content}

`; - } +// // 判断是否是表格类型 - // 判断是否是表格类型 - - return contentHtml; - }) - .join(''); - this.htmlContent = htmlContent; +// return contentHtml; +// }) +// .join(''); + this.htmlContent = 'true'; + }, getMainsInfo2(e) { this.loadHtml = true; @@ -1109,11 +1101,12 @@ export default { .then((res) => { this.loadHtml = false; if (res.code == 0) { - // console.log(res,'res') + console.log(res,'res') this.mains = ''; if (res.data.list.length > 0) { this.mains = res.data.list; + console.log('this.mains at line 1108:', this.mains) this.getWord(); } else { this.mains = ''; @@ -1156,37 +1149,42 @@ export default { }, // 文章html弹出层 async htmlContet(e) { + console.log('e at line 1151:', e) + this.htmlContent='' this.articleId = e.article_id; this.tg_article_id = e.tg_article_id; - // this.articleId = '3444'; this.UpHtpFIle.article_id = e.article_id; - this.refersList = await this.getRefersList(); - // this.UpHtpFIle.refers = e.refers this.UpHtpFIle.p_article_id = e.p_article_id; this.UpHtpFIle.doi = e.doi; this.UpHtpFIle.htmlfile = e.file_html; this.UpHtpFIle.title = e.title; this.UpHtpFIle.mains = e.mains; this.UpLoadFile.article_id = e.article_id; - this.html_type = e.html_type; - // this.html_type = 2; - - if (this.html_type == 2) { - if (e.has_html == 1) { - await this.getMainsInfo2(); - - this.HtmlVisible = true; - } else { - this.mains = ''; - this.HtmlVisible = true; - } - } else { - await this.getMainsInfo(e); - this.HtmlVisible = true; - } + await this.$api + .post('api/Publish/getPublishArticleDetail', { + article_id: e.article_id + }) + .then(async (res) => { + if (res.code == 0) { + console.log('res.code at line 1148:', res.code); + this.html_type = res.data.detail.html_type; + if (this.html_type == 2) { + if ( res.data.detail.has_html == 1) { + await this.getMainsInfo2(); + this.HtmlVisible = true; + } else { + this.mains = ''; + this.HtmlVisible = true; + } + } else { + await this.getMainsInfo(e); + this.HtmlVisible = true; + } + } + }); + }, - // 生成html // CreateHtml(){ // const loading = this.$loading({ @@ -1206,6 +1204,7 @@ export default { // this.htmlLayout() // } // }) + // }, // 修改文章html async htmlLayout2(type) { @@ -1217,16 +1216,21 @@ export default { background: 'rgba(0, 0, 0, 0.7)' }); await this.creatMains(); + this.html_type = 2; await this.getMainsInfo2(); loading.close(); } else { this.HtmlVisible = false; - this.$router.push({ - path: '/GenerateCharts', - query: { - id: this.tg_article_id - } - }); + window.open(this.$router.resolve({ path: '/GenerateCharts', + query: { + id: this.tg_article_id + } }).href, '_blank'); + // this.$router.push({ + // path: '/GenerateCharts', + // query: { + // id: this.tg_article_id + // } + // }); } }, htmlLayout() { diff --git a/src/components/page/articleProcess.vue b/src/components/page/articleProcess.vue index 12e5de8..ff88e50 100644 --- a/src/components/page/articleProcess.vue +++ b/src/components/page/articleProcess.vue @@ -1,90 +1,108 @@ - diff --git a/src/components/page/articleReviewerDetail.vue b/src/components/page/articleReviewerDetail.vue index 4569a46..fa0f18a 100644 --- a/src/components/page/articleReviewerDetail.vue +++ b/src/components/page/articleReviewerDetail.vue @@ -1022,13 +1022,14 @@ export default { str = 'With reviewer'; break; case 1: - str = 'Revision'; + str = 'Major'; break; case 2: str = 'Reject'; break; case 3: - str = 'Accept'; + // str = 'Accept'; + str = 'Minor'; break; } return str; diff --git a/src/components/page/comArtHtmlCreatNew copy.vue b/src/components/page/comArtHtmlCreatNew copy.vue new file mode 100644 index 0000000..0743941 --- /dev/null +++ b/src/components/page/comArtHtmlCreatNew copy.vue @@ -0,0 +1,299 @@ + + + + + diff --git a/src/components/page/comArtHtmlCreatNew.vue b/src/components/page/comArtHtmlCreatNew.vue index 0743941..576e917 100644 --- a/src/components/page/comArtHtmlCreatNew.vue +++ b/src/components/page/comArtHtmlCreatNew.vue @@ -1,46 +1,98 @@ diff --git a/src/components/page/components/Tinymce/index copy 2.vue b/src/components/page/components/Tinymce/index copy 2.vue index 3d3a6dc..629a907 100644 --- a/src/components/page/components/Tinymce/index copy 2.vue +++ b/src/components/page/components/Tinymce/index copy 2.vue @@ -68,9 +68,7 @@ const tableStyle = ` b span{ border-top:none;mso-border-top-alt:none !important; border-bottom:none !important; mso-border-bottom-alt:none !important; - border:1px dashed #dcdfe6 !important; - border-left:1px dashed #dcdfe6 !important; - border-right:1px dashed #dcdfe6 !important; + word-break: keep-all !important; text-align: justify !important; // 设置两端对齐 diff --git a/src/components/page/components/Tinymce/index.vue b/src/components/page/components/Tinymce/index.vue index 0eef61e..230150e 100644 --- a/src/components/page/components/Tinymce/index.vue +++ b/src/components/page/components/Tinymce/index.vue @@ -72,7 +72,7 @@ const tableStyle = ` b span{ border-left:1px dashed #dcdfe6 !important; border-right:1px dashed #dcdfe6 !important; word-break: keep-all !important; - text-align: justify !important; // 设置两端对齐 + // text-align: justify !important; // 设置两端对齐 } @@ -107,10 +107,17 @@ const tableStyle = ` b span{ table tr:first-child td { border-top:1.0000pt solid #000 !important;mso-border-top-alt:0.5000pt solid #000 !important;border-bottom:1.0000pt solid #000 !important;mso-border-bottom-alt:0.5000pt solid #000 !important; } - table tr:last-of-type td { + table tr:last-of-type { border-bottom:1.0000pt solid #000 !important;mso-border-bottom-alt:0.5000pt solid #000 !important;; } - + table span blue { + color: rgb(0, 130, 170) !important; + }blue { + color: rgb(0, 130, 170) !important; + } + .wordTableHtml table tr.table-header-row:nth-of-type(2) td { + border-bottom: 1px solid #000 !important; +} `; export default { @@ -133,11 +140,7 @@ export default { }, isEdit: {}, toolbar: { - type: Array, - required: false, - default() { - return []; - } + required: false }, menubar: { default: 'file edit insert view format table ' @@ -154,6 +157,10 @@ export default { }, isShowArtWorkButton: { default: false + }, + wordStyle: { + type: String, + default: '' } }, data() { @@ -262,9 +269,11 @@ export default { this.$forceUpdate(); }, + initTinymce() { - const _this = this; + var _this = this; window.tinymce.init({ + inline: false, // 使用 iframe 模式 selector: `#${this.tinymceId}`, content_css: false, // 禁用默认样式 table_resize_bars: true, // 启用拖动调整功能 @@ -329,17 +338,19 @@ export default { } }, - content_style: `${tableStyle} table span blue { - color: rgb(0, 130, 170) !important; - }blue { - color: rgb(0, 130, 170) !important; - }`, + content_style: ` + ${tableStyle} + ${_this.wordStyle} + + + + + `, formats: { bold: { inline: 'b' }, italic: { inline: 'i' } }, - body_class: 'panel-body ', object_resizing: false, toolbar: this.toolbar.length > 0 ? this.toolbar : toolbar, @@ -347,112 +358,20 @@ export default { statusbar: false, // 关闭底部状态栏 custom_colors: false, color_map: ['0082AA', 'TMR Blue'], - plugins: 'forecolor code paste table image', // 启用 forecolor 和 code 插件 + + plugins: 'texttransform', // 启用 forecolor 和 code 插件 + // plugins: 'forecolor code paste table image mathType searchreplace raw', // 启用 forecolor 和 code 插件 end_container_on_empty_block: true, content_css: 'default', // 加载 TinyMCE 默认样式表 + mathjax: { + // 配置 MathJax 用于渲染数学公式 + path: 'https://cdn.mathjax.org/mathjax/latest/MathJax.js', + config: 'TeX-AMS-MML_HTMLorMML' + }, //设置自定义按钮 myCustomToolbarButton setup(ed) { - // ed.on('change', function () { + _this.$commonJS.initEditorButton(_this, ed); - // var selectedColor = ed.formatter.get('forecolor'); - // console.log('ed.formatter.get at line 355:', ed.formatter) - // console.log('ed.formatter.get at line 355:', selectedColor) - - // // 检查是否选择了蓝色 - // if (selectedColor === '#0082AA') { - // // 蓝色的 hex 值 - // var selectedText = ed.selection.getContent(); // 获取选中的文本 - // if (selectedText) { - // var wrappedText = `${selectedText}`; // 包裹 标签 - // ed.selection.setContent(wrappedText); // 更新内容 - // } - // } - // }); - - ed.ui.registry.addButton('customBlue', { - text: 'Blue', // 按钮文本 - onAction: function () { - // 在选中的文本周围包裹 标签 - var selectedText = ed.selection.getContent(); - var wrappedText = `${selectedText}`; - ed.selection.setContent(wrappedText); - }, - classes: 'custom-colored-tinymce-button' - }); - ed.ui.registry.addButton('removeBlue', { - text: 'Remove Blue', // 按钮文本 - onAction: function () { - const range = ed.selection.getRng(); // 获取选区范围 - let startNode = range.startContainer; // 获取选区起始节点 - let closestBlue = null; - - // 向上查找最近的 标签 - while (startNode) { - if (startNode.nodeName && startNode.nodeName.toLowerCase() === 'blue') { - closestBlue = startNode; - break; - } - startNode = startNode.parentNode; - } - - if (closestBlue) { - // 如果找到最近的 标签,移除它的外层标签,但保留内容 - const parent = closestBlue.parentNode; - while (closestBlue.firstChild) { - parent.insertBefore(closestBlue.firstChild, closestBlue); - } - parent.removeChild(closestBlue); - } else { - // 未找到 标签,仅移除选中的 标签内容 - const selectedContent = ed.selection.getContent({ format: 'html' }); - - // 使用正则表达式移除选区中的 标签 - const cleanedContent = selectedContent - .replace(/]*>/g, '') // 删除起始标签 - .replace(/<\/blue>/g, ''); // 删除结束标签 - - // 更新选中的内容 - ed.selection.setContent(cleanedContent); - } - } - }); - ed.ui.registry.addToggleButton('toggleBlue', { - text: 'Toggle Blue', // 按钮文本 - onAction: function () { - var selectedContent = ed.selection.getContent({ format: 'html' }); // 获取选中内容(HTML 格式) - - // 创建临时 DOM 容器 - var tempDiv = document.createElement('div'); - tempDiv.innerHTML = selectedContent; - - // 检查是否完全被 包裹 - if (tempDiv.childNodes.length === 1 && tempDiv.firstChild.nodeName.toLowerCase() === 'blue') { - // 移除 标签 - var unwrappedContent = tempDiv.firstChild.innerHTML; - ed.selection.setContent(unwrappedContent); // 更新内容 - } else { - // 添加 标签 - var wrappedContent = `${selectedContent}`; - ed.selection.setContent(wrappedContent); // 更新内容 - } - }, - onSetup: function (buttonApi) { - // 更新按钮状态(激活或非激活) - function updateButtonState() { - var selectedContent = ed.selection.getContent({ format: 'html' }); - var tempDiv = document.createElement('div'); - tempDiv.innerHTML = selectedContent; - - buttonApi.setActive( - tempDiv.childNodes.length === 1 && tempDiv.firstChild.nodeName.toLowerCase() === 'blue' - ); - } - - // 监听编辑器中的选区变化 - ed.on('NodeChange', updateButtonState); - ed.on('KeyUp', updateButtonState); // 处理键盘操作导致的内容变化 - } - }); ed.ui.registry.addButton('uploadWord', { text: 'Word', icon: 'import-word', // 使用自定义图标 @@ -478,47 +397,51 @@ export default { } }); - ed.ui.registry.addMenuButton('customDropdown', { - text: _this.$t('commonTable.PaperRotation'), // 下拉框标题 - fetch: function (callback) { - // 定义下拉框的内容 - const items = [..._this.typesettingTypeOptions]; - const menuItems = items.map((item) => ({ - type: 'menuitem', - text: item.label, - onAction: function () { - _this.typesettingType = item.value; - _this.changeTable(); - // ed.execCommand(item.value); // 执行命令 - } - })); - callback(menuItems); - } - }); + // ed.ui.registry.addMenuButton('customDropdown', { + // text: _this.$t('commonTable.PaperRotation'), // 下拉框标题 + // fetch: function (callback) { + // // 定义下拉框的内容 + // const items = [..._this.typesettingTypeOptions]; + // const menuItems = items.map((item) => ({ + // type: 'menuitem', + // text: item.label, + // onAction: function () { + // _this.typesettingType = item.value; + // _this.changeTable(); + // // ed.execCommand(item.value); // 执行命令 + // } + // })); + // callback(menuItems); + // } + // }); ed.on('init', function () { + _this.$commonJS.inTinymceButtonClass(); const editorBody = ed.getBody(); // 创建 MutationObserver 监听内容变化 const observer = new MutationObserver(() => { const currentContent = ed.getContent(); if (_this.isAutomaticUpdate) { - _this.$emit('updateChange', ed.getContent()); + + + // _this.$emit('updateChange', _this.$commonJS.decodeHtml(currentContent)); + _this.$emit('updateChange',currentContent); } }); // 监听子节点和内容的变化 observer.observe(editorBody, { childList: true, subtree: true, characterData: true }); }); - // 定义自定义按钮 - ed.ui.registry.addButton('clearButton', { - text: 'Empty', + // // 定义自定义按钮 + // ed.ui.registry.addButton('clearButton', { + // text: 'Empty', - onAction: () => { - // 插入自定义表格到编辑器中 - ed.setContent(''); - } - }); + // onAction: () => { + // // 插入自定义表格到编辑器中 + // ed.setContent(''); + // } + // }); // 定义自定义按钮 ed.ui.registry.addButton('customButtonExportWord', { @@ -590,13 +513,16 @@ export default { window.tinymce.get(this.tinymceId).setContent(value); }, //获取内容 - getContent(type) { + async getContent(type) { var content = window.tinymce.get(this.tinymceId).getContent(); + content = content.replace(/]*>/g, '').replace(/<\/span>/g, ''); // 去除span标签 + + content = content.replace(//g, '').replace(/<\/strong>/g, ''); content = content.replace(//g, '').replace(/<\/em>/g, ''); content = content.replace(/ /g, ' '); // 将所有   替换为空格 - this.$emit('getContent', type, content); - console.log('window.tinymce.get(this.tinymceId).getContent() at line 431:', content); + this.$emit('getContent', type, content); + }, async export(type, data) { diff --git a/src/components/page/components/html/index.vue b/src/components/page/components/html/index.vue index 77ea5a7..586ea84 100644 --- a/src/components/page/components/html/index.vue +++ b/src/components/page/components/html/index.vue @@ -131,10 +131,12 @@
{ - //批注 - let contentHtml = ''; - var isRemark = ``; +// var htmlContent = ``; +// htmlContent += this.mains +// .map((item) => { +// //批注 +// let contentHtml = ''; +// var isRemark = ``; - // 判断是否是图片 - if (item.type == 1) { - var extension = item.image.url.split('.').pop().toLowerCase(); - if (extension == 'tif') { - contentHtml = ` -

- - ${item.image.note ? item.image.note : ''} -

- `; - } else if (['jpg', 'jpeg', 'png'].includes(extension)) { - contentHtml = ` -

- ${isRemark} - - ${ - item.image.note ? item.image.note : '' - } -

- `; - } else { - contentHtml = ` -

- ${isRemark} - - Figures ( .${item.image.url.split('.').pop().toUpperCase()}) - +// // 判断是否是图片 +// if (item.type == 1) { +// contentHtml = ` +//

+// ${isRemark} +// +// ${ +// item.image.note ? item.image.note : '' +// } +//

+// `; +// } else if (item.type == 2) { +// var tableList = JSON.parse(item.table.table_data); - ${ - item.image.note ? item.image.note : '' - } -

- `; - } - } else if (item.type == 2) { - var tableList = JSON.parse(item.table.table_data); +// contentHtml = ` +//
+// ${isRemark} +// ${item.table.title ? item.table.title : ''} +// +// ${tableList +// .map((row) => { +// return ` +// +// ${row +// .map((cell) => { +// return ` +// +// `; +// }) +// .join('')} +// +// `; +// }) +// .join('')} +//
+// ${cell.text || ''} +//
+// ${item.table.note ? item.table.note : ''} +//
+// `; +// } else { +// contentHtml = `

${isRemark}${item.content}

`; +// } - contentHtml = ` -
- ${isRemark} - ${item.table.title ? item.table.title : ''} - - ${tableList - .map((row) => { - return ` - - ${row - .map((cell) => { - return ` - - `; - }) - .join('')} - - `; - }) - .join('')} -
- ${cell.text || ''} -
- ${item.table.note ? item.table.note : ''} -
-`; - } else { - contentHtml = `

${isRemark}${item.content}

`; - } +// // 判断是否是表格类型 - // 判断是否是表格类型 - - return contentHtml; - }) - .join(''); - this.htmlContent = htmlContent; +// return contentHtml; +// }) +// .join(''); + this.htmlContent = 'true'; + console.log('this.htmlContent at line 820:', this.htmlContent) }, getMainsInfo2(e) { this.loadHtml = true; @@ -910,38 +878,43 @@ export default { }, // 文章html弹出层 async htmlContet(e) { - console.log('e at line 923:', e); + this.htmlContent='' this.articleId = e.article_id; this.tg_article_id = e.tg_article_id; - // this.articleId = '3444'; this.UpHtpFIle.article_id = e.article_id; - this.refersList = await this.getRefersList(); - // this.UpHtpFIle.refers = e.refers this.UpHtpFIle.p_article_id = e.p_article_id; this.UpHtpFIle.doi = e.doi; this.UpHtpFIle.htmlfile = e.file_html; this.UpHtpFIle.title = e.title; this.UpHtpFIle.mains = e.mains; this.UpLoadFile.article_id = e.article_id; - this.html_type = e.html_type; - // this.html_type = 2; - - if (this.html_type == 2) { - if (e.has_html == 1) { - await this.getMainsInfo2(); - - this.HtmlVisible = true; - } else { - this.mains = ''; - this.HtmlVisible = true; - } - } else { - await this.getMainsInfo(e); - this.HtmlVisible = true; - } + await this.$api + .post('api/Publish/getPublishArticleDetail', { + article_id: e.article_id + }) + .then(async (res) => { + if (res.code == 0) { + console.log('res.code at line 1148:', res.code); + this.html_type = res.data.detail.html_type; + if (this.html_type == 2) { + if ( res.data.detail.has_html == 1) { + await this.getMainsInfo2(); + this.HtmlVisible = true; + } else { + this.mains = ''; + this.HtmlVisible = true; + } + } else { + await this.getMainsInfo(e); + this.HtmlVisible = true; + } + } + }); + }, + // 生成html // CreateHtml(){ // const loading = this.$loading({ @@ -972,16 +945,21 @@ export default { background: 'rgba(0, 0, 0, 0.7)' }); await this.creatMains(); + this.html_type=2; await this.getMainsInfo2(); loading.close(); } else { this.HtmlVisible = false; - this.$router.push({ - path: '/GenerateCharts', - query: { - id: this.tg_article_id - } - }); + window.open(this.$router.resolve({ path: '/GenerateCharts', + query: { + id: this.tg_article_id + } }).href, '_blank'); + // this.$router.push({ + // path: '/GenerateCharts', + // query: { + // id: this.tg_article_id + // } + // }); } }, htmlLayout() { diff --git a/src/components/page/components/major/index.vue b/src/components/page/components/major/index.vue new file mode 100644 index 0000000..b9bde93 --- /dev/null +++ b/src/components/page/components/major/index.vue @@ -0,0 +1,201 @@ + + + + + diff --git a/src/components/page/components/major/list.vue b/src/components/page/components/major/list.vue new file mode 100644 index 0000000..03a4f9e --- /dev/null +++ b/src/components/page/components/major/list.vue @@ -0,0 +1,207 @@ + + + + + diff --git a/src/components/page/components/table/comment.vue b/src/components/page/components/table/comment.vue new file mode 100644 index 0000000..8e84e92 --- /dev/null +++ b/src/components/page/components/table/comment.vue @@ -0,0 +1,1022 @@ + + + diff --git a/src/components/page/components/table/content.vue b/src/components/page/components/table/content.vue index 4395049..c1b13aa 100644 --- a/src/components/page/components/table/content.vue +++ b/src/components/page/components/table/content.vue @@ -1,42 +1,51 @@ @@ -111,7 +130,7 @@ td input ::placeholder { ::v-deep .paste-area { height: auto; /* A4纸高度 */ background: white; /* 纸张背景 */ - + /* padding: 25.4mm 19.1mm; //内边距 */ box-sizing: border-box; /* 确保内边距不会影响整体尺寸 */ transform-origin: top left; @@ -141,8 +160,5 @@ td input ::placeholder { overflow-wrap: break-word !important; } .text-container { - } - - diff --git a/src/components/page/components/table/editTable.vue b/src/components/page/components/table/editTable.vue new file mode 100644 index 0000000..3dfb656 --- /dev/null +++ b/src/components/page/components/table/editTable.vue @@ -0,0 +1,1320 @@ + + + diff --git a/src/components/page/components/table/table.vue b/src/components/page/components/table/table.vue index eef8d28..7f58bab 100644 --- a/src/components/page/components/table/table.vue +++ b/src/components/page/components/table/table.vue @@ -2,17 +2,16 @@
- + -
@@ -57,7 +55,9 @@ export default { { label: this.$t('commonTable.typesettingType2'), value: 2, pageWidth: 297 } ], transform: null, - typesettingType: 1 + typesettingType: 1, + wordStyle: ` + ` }; }, mounted() { @@ -76,8 +76,8 @@ export default { text-align: center; table-layout: auto;" >`; - this.tableData.forEach((row) => { - modalContent += ``; + this.tableData.forEach((row,i) => { + modalContent += ``; row.forEach((cell) => { modalContent += ` { console.log('res at line 104:', table); - + this.$emit('getContent', type, { html_data: content, table: table }); }); } else { diff --git a/src/components/page/components/table/word.vue b/src/components/page/components/table/word.vue index b6be21a..ec645cf 100644 --- a/src/components/page/components/table/word.vue +++ b/src/components/page/components/table/word.vue @@ -1,15 +1,347 @@