diff --git a/src/assets/img/repeat.png b/src/assets/img/repeat.png new file mode 100644 index 0000000..709024b Binary files /dev/null and b/src/assets/img/repeat.png differ diff --git a/src/common/js/commonJS.js b/src/common/js/commonJS.js index 6ff51a2..3d6c7f9 100644 --- a/src/common/js/commonJS.js +++ b/src/common/js/commonJS.js @@ -22,7 +22,7 @@ export default { var txt = document.createElement('textarea'); txt.innerHTML = html; return txt.value; - }, + }, //去掉最外层自定义的span标签 extractContentWithoutOuterSpan(cell) { var str = '' @@ -52,12 +52,12 @@ export default { const regex = /\[(\d+(?:–\d+)?(?:, ?\d+(?:–\d+)?)*)\]/g; str = str.replace(//g, '').replace(/<\/blue>/g, ''); // 先去掉所有的 标签 - + if (regex.test(str)) { - str = str.replace(regex, function(match) { + str = str.replace(regex, function (match) { // 提取出方括号中的内容,并进行匹配 const content = match.slice(1, match.length - 1); // 去掉方括号 - + // 判断是否符合条件,纯数字、逗号后有空格、连字符 if (/^\d+$/.test(content) || /, ?/.test(content) || /–/.test(content)) { return `${match}`; // 如果符合条件则加上蓝色标签 @@ -65,8 +65,8 @@ export default { return match; // 如果不符合条件,则保持原样 }); } - - + + // 如果没有 标签,直接返回原始 HTML 内容 @@ -295,18 +295,18 @@ export default { formattedText = capitalizeFirstLetter(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) { + formattedText = formattedText.replace(regex, function (match) { // 提取出方括号中的内容,并进行匹配 const content = match.slice(1, match.length - 1); // 去掉方括号 - + // 判断是否符合条件,纯数字、逗号后有空格、连字符 if (/^\d+$/.test(content) || /, ?/.test(content) || /–/.test(content)) { return `${match}`; // 如果符合条件则加上蓝色标签 @@ -315,10 +315,10 @@ export default { }); } console.log("After replacement:", formattedText); // 调试:查看替换后的文本 - - - + + + paragraphText += formattedText; } @@ -366,7 +366,7 @@ export default { } }, transformHtmlString(inputHtml) { - + inputHtml = inputHtml.replace(/(<[^>]+) style="[^"]*"/g, '$1'); // 移除style属性 inputHtml = inputHtml.replace(/(<[^>]+) class="[^"]*"/g, '$1'); // 移除class属性 @@ -386,6 +386,41 @@ export default { }, + cleanAndParseWordContent(content) { + // 1️⃣ 解析成

段落数组 + let tempDiv = document.createElement('div'); + tempDiv.innerHTML = content; // 解析 HTML 内容 + let paragraphs = tempDiv.querySelectorAll("p"); // 选取所有

作为数据项 + + // 2️⃣ 将

内容转换为数组,处理空标签对 + let parsedData = Array.from(paragraphs).map(p => { + let text = p.innerHTML.trim(); // 获取内容,去除两端空格 + + // 3️⃣ 移除 (Word 复制的无效标签) + text = text.replace(/<\/?o:p>/g, ""); + + // 4️⃣ 移除 style="..."(防止 Word 带入无用样式) + text = text.replace(/\s*style="[^"]*"/g, ""); + + // 5️⃣ 替换 + text = text.replace(//g, "").replace(/<\/strong>/g, ""); + + // 6️⃣ 替换 + text = text.replace(//g, "").replace(/<\/em>/g, ""); + + // 7️⃣ 处理空标签对: 等 + text = text.replace(/<[^>]+>\s*<\/[^>]+>/g, ""); + + // 8️⃣ 如果最终内容为空,则替换为 `""` + return text.trim() === "" ? "" : text; + }); + + console.log(parsedData); // 输出数组,方便调试 + return parsedData; + } + + + , parseTableToArray(tableString, callback) { @@ -1240,7 +1275,7 @@ export default { } }); ed.ui.registry.addButton('addRow', { - icon:'duplicate-row', + icon: 'duplicate-row', text: 'Add Row', // 下拉框标题 onAction: function () { var edSelection = ed.selection; @@ -1257,7 +1292,7 @@ export default { vueInstance.$emit('onAddRow', dataId); } } - + }); // 添加自定义菜单项 ed.ui.registry.addButton('Save', { @@ -1300,7 +1335,7 @@ export default { emTags[i].parentNode.replaceChild(iTag, emTags[i]); } content = div.innerHTML; - + vueInstance.$emit('saveContent', content, dataId); } } @@ -1390,8 +1425,8 @@ export default { } } }); - - + + ed.ui.registry.addButton('commentAdd', { icon: 'comment-add', text: 'Comment Add', @@ -1519,7 +1554,7 @@ export default { ed.setContent(''); } }); - + ed.ui.registry.addButton('customBlue', { text: 'Blue', // 按钮文本 @@ -1537,80 +1572,80 @@ export default { } } }); - + 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')); - - } + // 使用正则将选中的文本中的第一个字母大写 + 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')); - - } + // 使用正则将选中的文本中的第一个字母大写 + 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' }); + // 获取选中的文本,保留 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')); - } + // 确保选中的文本是单个有效的单词,包括空格 + 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('Line', { + text: '−', // 按钮文本 + onAction: function () { + // 插入 `−` 符号到当前光标位置 + ed.insertContent('−'); + } + }); + - ed.ui.registry.addButton('removeBlue', { text: 'Blue', // 按钮文本 onAction: function () { @@ -1660,7 +1695,7 @@ export default { { 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); @@ -1672,7 +1707,7 @@ export default { }); }, 100); // 延迟执行,确保按钮渲染完成 } - + // 通用递归方法 diff --git a/src/components/page/GenerateCharts.vue b/src/components/page/GenerateCharts.vue index 789a97e..7cf1cfe 100644 --- a/src/components/page/GenerateCharts.vue +++ b/src/components/page/GenerateCharts.vue @@ -73,7 +73,7 @@ -

+
+ Save + + +
@@ -400,6 +438,8 @@ export default { ChGtpTxt: '' }, txtVisible: false, + addContentVisible: false, + addContent: {}, lineStyle: {}, contentStyle: {}, lineTable: [], @@ -494,11 +534,13 @@ export default { handleSaveContent() { this.$refs.commonContent.getTinymceContent('content'); }, + handleSaveAddContent() { + this.$refs.addContent.getTinymceContent('addcontent'); + }, async getContent(type, content) { - + console.log('content at line 539:', content); if (type == 'content') { - content = content.replace(/<(?!\/?(img|b|i|sub|sup|span|strong|em |blue)\b)[^>]+>/g, ''); content = content.replace(/\s*style="[^"]*"/g, ''); @@ -522,27 +564,41 @@ export default { // 获取最终修改后的 HTML content = div.innerHTML; - - this.saveContent(content, this.currentContent.am_id); + } else if (type == 'addcontent') { + var hasTable = /[\s\S]*?<\/table>/i.test(content); + + if (hasTable) { + this.$message({ + type: 'warning', + message: 'Table content is not supported!' + }); + return false + } + var list = this.$commonJS.cleanAndParseWordContent(content); + console.log('list at line 569:', list); + + this.saveContentList(list, this.currentId); } else if (type == 'table') { this.saveTable(content); } else if (type == 'comment') { this.addComment(content); } - }, - async saveContent(content, am_id) { - + }, + async saveContent(content, am_id) { var that = this; - var str = content.replace(/^

(.*?)<\/p>$/, '$1') ? content.replace(/^

(.*?)<\/p>$/, '$1') : ''; - if (str == '') { - this.$message({ - type: 'warning', - message: 'Please enter the content!' - }); - } - str= await that.$commonJS.decodeHtml(str) + var str = content.replace(/^

\s*(.*?)\s*<\/p>$/, '$1').trim(); + // var str = content.replace(/^

(.*?)<\/p>$/, '$1') ? content.replace(/^

(.*?)<\/p>$/, '$1') : ''; + console.log('str at line 580:', JSON.stringify(str)); + + // if (str == '') { + // this.$message({ + // type: 'warning', + // message: 'Please enter the content!' + // }); + // } + str = await that.$commonJS.decodeHtml(str); await that.$api .post(that.urlList.editContent, { am_id: am_id, @@ -556,6 +612,28 @@ export default { } }); }, + async saveContentList(content, am_id) { + if (content.length == 0) { + this.$message({ + type: 'warning', + message: 'Please enter the content!' + }); + } + + await this.$api + .post('api/Preaccept/addMoreRow', { + article_id: this.articleId, + am_id: am_id, + rows: content + }) + .then(async (res) => { + if (res.code == 0) { + this.addContentVisible = false; + this.getDate(); + this.getCommentList(); + } + }); + }, deleteComment(comment, index) { console.log('comment at line 480:', comment); if (this.isEditComment) { @@ -582,7 +660,7 @@ export default { .catch(() => {}); } }, - + async huifu(id) { var that = this; await this.$confirm(this.$t('commonTable.reContent'), 'Prompt', { @@ -712,6 +790,56 @@ export default { console.log('err at line 466:', err); }); }, + async onDeletes(dataId) { + await this.$confirm(this.$t('commonTable.removeContent'), 'Prompt', { + confirmButtonText: 'Submit', + cancelButtonText: 'Cancel', + type: 'warning' + }) + .then(async () => { + var that = this; + + await that.$api + .post('/api/Preaccept/delMoreArticleMains', { + ids: dataId + }) + .then(async (res) => { + if (res.code == 0) { + setTimeout(() => { + that.getDate(); + that.getCommentList(); + that.$refs.commonWordHtmlTypeSetting.refresh('img'); + that.$refs.commonWordHtmlTypeSetting.refresh('table'); + that.$forceUpdate(); + }); + } + }); + // this.Main_List.splice( + // this.Main_List.findIndex((item) => item.p_main_id == dataId), + // 1 + // ); + }) + .catch((err) => { + console.log('err at line 466:', err); + }); + }, + async changeSort(type,id) { + var that=this + await that.$api + .post(type=='up'?'/api/Preaccept/upArticleMain':'/api/Preaccept/downArticleMain', { + am_id: id + }) + .then(async (res) => { + if (res.code == 0) { + setTimeout(() => { + that.getDate(); + that.getCommentList(); + + that.$forceUpdate(); + }); + } + }); + }, async addCommentSetting(content) { console.log('content at line 602:', content); await this.$api @@ -850,6 +978,9 @@ export default { async onEditTitle(data) { var url; switch (data.value) { + case 0: + url = 'api/Preaccept/changeNormal'; + break; case 1: url = 'api/Preaccept/changeH1'; break; @@ -962,7 +1093,7 @@ export default { } }, updateChange(content, type) { - console.log('content at line 976:', content) + console.log('content at line 976:', content); var str = this.$commonJS.transformHtmlString(content); if (type == 'imgNote') { this.picStyle.note = str; @@ -1005,13 +1136,19 @@ export default { this.lineStyle.visiTitle = 'Edit Table'; this.threeVisible = true; } else { - data.content = data.content.replace(/]*>/g, '').replace(/<\/span>/g, ''); // 去除span标签 + data.content = data.content.replace(/]*>/g, '').replace(/<\/span>/g, ''); // 去除span标签 this.currentContent = data; - + this.editVisible = true; this.currentId = dataId; } }, + onAddContent(dataId) { + this.addContentVisible = true; + this.addContent = {}; + + this.currentId = dataId; + }, async onDrop(event, dataId) { if (event.dataTransfer.getData('image')) { const draggedImage = JSON.parse(event.dataTransfer.getData('image')); @@ -1330,16 +1467,16 @@ export default { }, // 确定保存图片 - async savePic() { + async savePic() { this.picStyle.picUrl; - var str=this.picStyle.note - str= await this.$commonJS.decodeHtml(str) + var str = this.picStyle.note; + str = await this.$commonJS.decodeHtml(str); if (this.picStyle.visiTitle == 'Edit Figure') { this.$api .post(this.urlList.editImage, { ami_id: this.picStyle.ami_id, url: this.picStyle.picUrl, - note:str + note: str }) .then((res) => { if (res.code == 0) { @@ -1391,16 +1528,16 @@ export default { this.$refs.tinymceChildComment.getContent('comment'); }); }, - async saveTable(content) { + async saveTable(content) { console.log('content at line 998:', content); - var strTitle=this.lineStyle.title - strTitle= await this.$commonJS.decodeHtml(strTitle) - - var strNote=this.lineStyle.note - if(strNote!=''){ - strNote= await this.$commonJS.decodeHtml(strNote) + var strTitle = this.lineStyle.title; + strTitle = await this.$commonJS.decodeHtml(strTitle); + + var strNote = this.lineStyle.note; + if (strNote != '') { + strNote = await this.$commonJS.decodeHtml(strNote); } - + if (content && content.table && content.table.length > 0) { if (this.lineStyle.visiTitle == 'Edit Table') { this.$api diff --git a/src/components/page/ReferenceEditor.vue b/src/components/page/ReferenceEditor.vue index dbd18a7..e5e1056 100644 --- a/src/components/page/ReferenceEditor.vue +++ b/src/components/page/ReferenceEditor.vue @@ -92,6 +92,10 @@

  • - If you want to discard all references and import a new batch of reference information, please click Delete and re-import.

  • +
  • +

    - Please note that if this status exists, + it indicates that the current reference is duplicated .

    +
  • - Please do not forget to recheck all references in the status,especially abbreviated journal title.

  • @@ -100,7 +104,12 @@
    - + + +