This commit is contained in:
2025-05-29 16:57:07 +08:00
parent 845785686d
commit 5f7f1d992b
18 changed files with 2144 additions and 3696 deletions

View File

@@ -54,6 +54,17 @@ function emuToPixels(emu) {
// 四舍五入并保留两位小数
return (Math.round(emuToPixels * 100) / 100).toFixed(2);
}
function findExtentElement(blipElement) {
let current = blipElement.parentElement;
while (current) {
const extents = current.getElementsByTagName('wp:extent');
if (extents.length > 0) {
return extents[0]; // 找到包含 wp:extent 的节点
}
current = current.parentElement;
}
return null; // 没有找到
}
export default {
isImageValid(base64) {
@@ -79,113 +90,118 @@ export default {
handleFileUpload(event, callback) {
const file = event.target.files[0]; // 获取用户上传的文件
if (file && file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') {
const reader = new FileReader();
reader.onload = (e) => {
// 将文件读取为 ArrayBuffer
const arrayBuffer = e.target.result;
// 使用 JSZip 解析 .docx 文件内容
const zip = new JSZip();
zip.loadAsync(arrayBuffer).then((zip) => {
// 获取 Word 文档的 XML 内容
const documentXml = zip.files['word/document.xml'];
const images = {}; // 用来保存图片的 src 和对应的宽高
if (documentXml) {
documentXml.async("string").then((xmlString) => {
// 使用正则或 XML 解析器提取所有图片的宽高
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlString, "text/xml");
// 查找图片的宽高(通常在 <wp:extent> 标签内)
const imageElements = xmlDoc.getElementsByTagName('wp:extent');
Array.from(imageElements).forEach((imgElement, index) => {
console.log('imgElement at line 78:', imgElement)
// 提取 width 和 height 属性
const widthEmu = imgElement.getAttribute('cx'); // 宽度
const heightEmu = imgElement.getAttribute('cy'); // 高度
if (widthEmu && heightEmu) {
// 转换为像素
const width = emuToPixels(widthEmu);
const height = emuToPixels(heightEmu);
images[index] = { width, height }; // 保存图片的宽高
}
// 这里你可以将宽高传递给回调函数
});
});
}
mammoth.convertToHtml({
arrayBuffer: e.target.result
})
.then((result) => {
console.log('images at line 115:', images)
// 使用正则提取所有表格内容
const tableContent = result.value.match(/<table[\s\S]*?<\/table>/g);
if (tableContent) {
console.log('tableContent at line 20:', tableContent);
// 筛选出包含 <td> 的表格
const validTables = tableContent.filter(table => /<td[\s\S]*?>/g.test(table));
console.log('validTables at line 71:', validTables);
// 提取表格内的图片
validTables.forEach((table, index) => {
console.log('table at line 75:', table)
const imgTags = table.match(/<img[\s\S]*?src="([^"]*)"/g);
console.log('imgTags at line 128:', imgTags)
if (imgTags) {
// 遍历所有图片标签
imgTags.forEach((imgTag, imgIndex) => {
console.log('imgTag at line 128:', imgTag);
const srcMatch = imgTag.match(/src="([^"]*)"/);
if (srcMatch) {
const imageInfo = images[imgIndex]; // 从 images 中查找对应的宽高
if (imageInfo) {
// 构建新的 <img> 标签,保留原来的其他属性
const newImgTag = imgTag.replace(
/<img/,
`<img width="${imageInfo.width}" height="${imageInfo.height}"`
);
table = table.replace(imgTag, newImgTag); // 替换旧标签
}
}
});
}
validTables[index] = table; // 更新该表格内容
});
if (validTables.length > 0) {
console.log('validTables.length at line 147:', validTables)
callback(validTables);
} else {
callback([]);
}
} else {
console.log("没有找到表格内容。");
}
})
.catch((err) => {
console.error('Error parsing Word file:', err);
});;
}).catch((err) => {
console.error("Error loading zip file:", err);
});
};
reader.readAsArrayBuffer(file); // 将文件读取为 ArrayBuffer
} else {
const file = event.target.files[0];
if (!file || file.type !== 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') {
alert('请上传一个有效的 Word 文件');
return;
}
const reader = new FileReader();
reader.onload = (e) => {
const arrayBuffer = e.target.result;
const zip = new JSZip();
zip.loadAsync(arrayBuffer).then(async (zip) => {
const relsXml = await zip.files['word/_rels/document.xml.rels'].async('string');
const docXml = await zip.files['word/document.xml'].async('string');
const parser = new DOMParser();
const relDoc = parser.parseFromString(relsXml, "text/xml");
const docDom = parser.parseFromString(docXml, "text/xml");
const rels = {};
Array.from(relDoc.getElementsByTagName('Relationship')).forEach((rel) => {
const id = rel.getAttribute('Id');
const target = rel.getAttribute('Target'); // e.g., 'media/image1.jpeg'
rels[id] = target;
});
const imageInfoMap = {};
const blips = docDom.getElementsByTagName('a:blip');
Array.from(blips).forEach((blip) => {
const embedId = blip.getAttribute('r:embed');
const extent = findExtentElement(blip);
if (embedId && extent) {
const cx = extent.getAttribute('cx');
const cy = extent.getAttribute('cy');
if (cx && cy) {
const width = emuToPixels(cx);
const height = emuToPixels(cy);
const mediaFile = rels[embedId];
if (mediaFile) {
imageInfoMap[mediaFile] = { width, height };
}
}
}
});
mammoth.convertToHtml({ arrayBuffer },
{
convertImage: mammoth.images.inline(async function (image) {
const contentType = image.contentType.toLowerCase();
// 只允许这三种格式
const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png'];
if (!allowedTypes.includes(contentType)) {
// 跳过不支持的格式(如 image/tiff、image/x-emf 等)
return { src: '' }; // 会从 HTML 中删除这张图片
}
// 读取为 base64 并构造 src
const imageBuffer = await image.read("base64");
const base64Src = `data:${contentType};base64,${imageBuffer}`;
return {
src: base64Src
};
})
})
.then((result) => {
let html = result.value;
// html = html.replace(/<img[^>]+src="data:image\/x-emf[^"]*"[^>]*>/gi, '');
// 替换图片标签中的宽高
const imgTags = html.match(/<img[^>]*src="data:image\/[^"]+image(\d+)\.(png|jpg|jpeg)[^"]*"[^>]*>/gi);
if (imgTags) {
imgTags.forEach((imgTag) => {
const match = imgTag.match(/image(\d+)\.(png|jpg|jpeg)/);
if (match) {
const filename = `media/image${match[1]}.${match[2]}`;
const info = imageInfoMap[filename];
if (info) {
const newImgTag = imgTag.replace(
/<img/,
`<img width="${info.width}" height="${info.height}"`
);
html = html.replace(imgTag, newImgTag);
}
}
});
}
// 提取合法表格
const tableContent = html.match(/<table[\s\S]*?<\/table>/g);
const validTables = tableContent
? tableContent.filter(table => /<td[\s\S]*?>/.test(table))
: [];
callback(validTables);
})
.catch(err => {
console.error('mammoth 转换失败:', err);
});
}).catch(err => {
console.error("Zip 读取失败:", err);
});
};
reader.readAsArrayBuffer(file);
},
extractLatexFromMathJax() {
// 获取所有 MathJax 渲染的公式容器
const mathContainers = document.querySelectorAll('mjx-container');
@@ -193,17 +209,15 @@ export default {
mathContainers.forEach(container => {
// 查找每个渲染公式对应的 MathML 部分
const mathElement = container.querySelector('mjx-math');
console.log('mathElement at line 28:', mathElement)
if (mathElement) {
// 获取 MathJax 渲染的公式对象
const jax = window.MathJax.getJaxFor(mathElement);
console.log('jax at line 32:', jax)
if (jax) {
// 使用 MathJax API 获取公式的 LaTeX 代码
const latex = jax.getLiteral(); // 获取 LaTeX 表达式
console.log('提取到的 LaTeX 公式:', latex); // 输出 LaTeX 代码
} else {
console.warn('MathJax 对象未找到');
}
@@ -232,28 +246,23 @@ export default {
,
// **解析 MathJax 公式,获取 LaTeX**
async extractMathJaxLatex(cell, callback) {
console.log('cell at line 67:', cell)
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
console.log('cell content at the start:', updatedContent);
// Find all <wmath> elements
const wmathElements = cell.querySelectorAll('wmath');
wmathElements.forEach((element) => {
// Get the LaTeX content from the data-latex attribute
const latexContent = element.getAttribute('data-latex');
console.log('LaTeX content from data-latex:', latexContent);
// Replace the <wmath> tag with its LaTeX content wrapped in $$...$$
updatedContent = updatedContent.replace(element.outerHTML, `<wmath data-latex="${latexContent}">${latexContent}</wmath>`);
});
console.log('updatedContent after processing wmath tags:', updatedContent);
// Step 2: Now extract content without the outer <span> tags
updatedContent = this.extractContentWithoutOuterSpan(updatedContent);
console.log('updatedContent after extractContentWithoutOuterSpan:', updatedContent);
// Step 3: Call the callback function with the final updated content
// callback(updatedContent);
@@ -277,7 +286,7 @@ export default {
},
//去掉最外层自定义的span标签
extractContentWithoutOuterSpan(cell) {
console.log('cell at line 90:', cell)
var str = ''
if (!cell) {
return ''
@@ -285,7 +294,6 @@ export default {
// 获取单元格的 HTML 内容
let htmlContent = cell.trim();
console.log('htmlContent at line 94:', htmlContent)
str = this.transformHtmlString(htmlContent, 'table')
@@ -326,8 +334,7 @@ export default {
console.log('str at line 141:', str)
// 如果没有 <span> 标签,直接返回原始 HTML 内容
return str;
},
@@ -413,7 +420,7 @@ export default {
allTables.push(tableArray); // 添加当前表格到所有表格数组
}
console.log("解析后的表格数组:", allTables);
callback(allTables); // 返回处理后的数组
} catch (error) {
console.error("解析粘贴内容失败:", error);
@@ -426,7 +433,6 @@ export default {
const Zip = new JSZip();
const zip = await Zip.loadAsync(file);
console.log("解压后的文件:", Object.keys(zip.files));
const documentFile = zip.file("word/document.xml");
if (!documentFile) {
@@ -438,8 +444,6 @@ export default {
const parser = new DOMParser();
const documentDoc = parser.parseFromString(documentXml, "application/xml");
console.log("解析的 XML 结构:", new XMLSerializer().serializeToString(documentDoc));
const numberingFile = zip.file("word/numbering.xml");
let numberingMap = {};
if (numberingFile) {
@@ -546,7 +550,7 @@ export default {
}
}
console.log('rowspan at line 265:', rowspan)
const currentLevelNumbers = {};
for (const paragraph of paragraphs) {
let listPrefix = "";
@@ -577,7 +581,7 @@ export default {
const embedId = blip.getAttribute("r:embed");
if (embedId) {
textContent += `<img data-embed="${embedId}"/>`;
console.log("✅ 图片 embedId:", embedId);
}
}
}
@@ -585,7 +589,7 @@ export default {
const texts = run.getElementsByTagName("w:t");
for (const text of texts) {
textContent += text.textContent;
@@ -632,7 +636,6 @@ export default {
});
}
console.log("After replacement:", formattedText);
paragraphText += formattedText;
}
@@ -643,7 +646,6 @@ export default {
}
cellText += paragraphText;
console.log('cellText at line 366:', cellText)
}
rowArray.push({
@@ -671,7 +673,6 @@ export default {
allTables.push(tableArray);
}
console.log("解析后的二维数组:", allTables);
callback(allTables);
} catch (error) {
@@ -951,7 +952,7 @@ export default {
let parsedData = Array.from(paragraphs).map(p => {
let text = p.innerHTML.trim(); // 获取内容,去除两端空格
text = replaceNegativeSign(text);
console.log('text at line 756:', text)
text = this.transformHtmlString(text)
// 3⃣ **正确移除 <o:p>Word 复制的无效标签)**
text = text.replace(/<\/?o:p[^>]*>/g, "");
@@ -977,7 +978,7 @@ export default {
return text.trim() === "" ? "" : text;
});
console.log(parsedData); // 输出数组,方便调试
return parsedData;
}
@@ -987,7 +988,6 @@ export default {
async parseTableToArray(tableString, callback) {
console.log('tableString at line 845:', tableString)
const parser = new DOMParser();
const doc = parser.parseFromString(tableString, 'text/html');
const rows = doc.querySelectorAll('table tr'); // 获取所有的行(<tr>
@@ -1008,7 +1008,7 @@ export default {
);
})
);
console.log('result at line 78611:', result)
callback(result)
// 返回处理后的数组
@@ -1095,7 +1095,6 @@ export default {
// 获取编号定义
const numberingMap = this.parseNumbering(numberingDoc);
console.log('numberingMap at line 232:', numberingMap)
// 提取表格
// 获取所有的段落
const paragraphs = xmlDoc.getElementsByTagName("w:p");
@@ -1115,9 +1114,7 @@ export default {
}
// 将前一段的内容转化为 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)
// 更新 HTML 内容
this.htmlContent = tableHtml || "<p>未检测到表格内容。</p>";
@@ -1472,8 +1469,6 @@ export default {
// 保持原比例
this.renderTiffImage(mediaUrl + img.image, `tiff-canvas-modal-${index}`, index, true);
console.log('at line 827:', document.getElementsByClassName('thumbnailBox'))
// 不保持原比例,强制缩放到指定大小
const targetWidth = imgWidth || document.getElementsByClassName('thumbnailBox')[0].offsetWidth; // 使用外层容器宽度
const targetHeight = imgHeight || document.getElementsByClassName('thumbnailBox')[0].offsetHeight; // 使用外层容器高度
this.renderTiffImage(mediaUrl + img.image, `tiff-canvas-${index}`, index, false, targetWidth, targetHeight);
@@ -1866,7 +1861,6 @@ export default {
// 如果找到的 div 节点存在
if (outerDiv) {
const dataId = outerDiv.getAttribute('main-id');
console.log('dataId at line 1258:', dataId)
vueInstance.$emit('onAddRow', dataId);
}
@@ -1889,7 +1883,6 @@ export default {
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(/&nbsp;/g, ' ');
@@ -1932,7 +1925,6 @@ export default {
// 如果找到的 div 节点存在
if (outerDiv) {
const dataId = outerDiv.getAttribute('main-id');
console.log('dataId at line 1258:', dataId)
vueInstance.$emit('onEditTitle', {
mainId: dataId,
value: 1
@@ -1954,7 +1946,6 @@ export default {
// 如果找到的 div 节点存在
if (outerDiv) {
const dataId = outerDiv.getAttribute('main-id');
console.log('dataId at line 1258:', dataId)
vueInstance.$emit('onEditTitle', {
mainId: dataId,
value: 2
@@ -1976,7 +1967,6 @@ export default {
// 如果找到的 div 节点存在
if (outerDiv) {
const dataId = outerDiv.getAttribute('main-id');
console.log('dataId at line 1258:', dataId)
vueInstance.$emit('onEditTitle', {
mainId: dataId,
value: 3
@@ -1998,7 +1988,6 @@ export default {
// 如果找到的 div 节点存在
if (outerDiv) {
const dataId = outerDiv.getAttribute('main-id');
console.log('dataId at line 1258:', dataId)
vueInstance.$emit('onEdit', dataId);
}
@@ -2023,7 +2012,6 @@ export default {
const dataId = outerDiv.getAttribute('main-id');
const type = outerDiv.getAttribute('type');
console.log('type:', type);
// 获取选中的内容HTML格式
let selectedContent = edSelection.getContent({ format: 'html' });
@@ -2142,7 +2130,6 @@ export default {
onAction: function () {
// 在选中的文本周围包裹 <blue> 标签
var selectedText = ed.selection.getContent();
console.log('selectedText at line 529:', selectedText);
if (selectedText) {
var wrappedText = `<blue>${selectedText}</blue>`;
ed.selection.setContent(wrappedText);
@@ -2161,7 +2148,6 @@ export default {
// 1. 获取当前光标位置
const latexEditorBookmark = ed.selection.getBookmark(2); // 获取光标位置
const editorId = ed.id; // 保存当前编辑器 ID
console.log('activeEditorId:', editorId);
// 2. 生成一个随机的 ID用于 wmath 标签
const uid = 'wmath-' + Math.random().toString(36).substr(2, 9);

View File

@@ -382,7 +382,9 @@ const en = {
uploadImageInfo: 'Figures can only upload files in JPG, JPEG, and PNG formats!',
selectComment: 'Please select the text to add annotations to!',
selectWord: 'Please select only a single word',
alreadyCommented: 'There are already annotations in the text, please select again!'
alreadyCommented: 'There are already annotations in the text, please select again!',
Multicolumn:'Multicolumn',
singleRow:"single-row",
},
pendingPayment: {
title: 'Title',
@@ -430,7 +432,10 @@ const en = {
"covered": "Research Fields",
"digest": "Summary",
"research_background": "Research Background",
"research_result": "Research Results",
"research_methods": "Research Method",
"research_result": "Results",
"summarize": "Summarize",
"overview": "Overview",
"highlights": "Highlights",
"discussion": "Discussion",
"prospect": "Future Prospects",
@@ -453,13 +458,13 @@ const en = {
"add_author": "Add Author"
},
AIArticleStatusEn: {
AIArticleStatus: {
1: 'WeChat AI content generated',
2: 'WeChat AI content not generated',
3: 'Draft not created',
3: 'The article has been generated, but the draft box has not been pushed yet',
4: 'Draft created but not published',
10: 'WeChat article published successfully',
11: 'WeChat article publishing in progress',
11: 'WeChat article publishing in progress...',
fail: 'WeChat article publishing failed',
unknown: 'Unknown status'
}

View File

@@ -376,6 +376,8 @@ const zh = {
selectComment: '请选择要添加批注的文本',
selectWord:'请只选中单个单词!',
alreadyCommented:'文本中已有批注内容请重新选择',
Multicolumn:'多列',
singleRow:"单列",
},
pendingPayment: {
title: 'Title',
@@ -423,7 +425,10 @@ const zh = {
"covered": "研究学科",
"digest": "摘要",
"research_background": "研究背景",
"research_result": "研究结果",
"research_methods": "研究方法",
"research_result": "结果",
"summarize": "总结",
"overview": "概述",
"highlights": "研究亮点",
"discussion": "讨论",
"prospect": "前景展望",
@@ -448,13 +453,13 @@ const zh = {
AIArticleStatus: {
1: '公微 AI 内容已生成',
2: '公微 AI 内容未生成',
3: '尚未生成草稿',
3: '文章已生成,尚未推送草稿',
4: '草稿已生成,尚未发布',
10: '公微文章已成功发布',
11: '公微文章正在发布中',
11: '公微文章正在发布中...',
fail: '公微文章发布失败',
unknown: '状态未知'
}
},
}

File diff suppressed because it is too large Load Diff

View File

@@ -196,14 +196,14 @@
:wrapperClosable="false"
:close-on-click-modal="false"
direction="rtl"
size="70%"
size="80vw"
>
<el-form ref="editMes" :model="lineStyle" label-width="80px">
<!-- <common-late-x></common-late-x> -->
<!-- :id="`editor-${new Date().getTime()}-${lineStyle.am_id}-${lineStyle.amt_id}-title`" -->
<el-form-item label="Title:">
<common-content
:id="`editor-${new Date().getTime()}-${lineStyle.am_id}-${lineStyle.amt_id}-title`"
:id="`editor-${new Date().getTime()}-${lineStyle.am_id}-${lineStyle.amt_id}-title`"
:isAutomaticUpdate="true"
:value="lineStyle.title"
@getContent="getContent"
@@ -231,7 +231,7 @@
<el-form-item label="Note:">
<!-- :id="`editor-${new Date().getTime()}-${lineStyle.am_id}-${lineStyle.amt_id}-note`" -->
<common-content
:id="`editor-${new Date().getTime()}-${lineStyle.am_id}-${lineStyle.amt_id}-note`"
:id="`editor-${new Date().getTime()}-${lineStyle.am_id}-${lineStyle.amt_id}-note`"
:isAutomaticUpdate="true"
:value="lineStyle.note"
@getContent="getContent"
@@ -265,31 +265,26 @@
:wrapperClosable="false"
:close-on-click-modal="false"
direction="rtl"
size="70%"
size="80vw"
>
<div v-for="(item, i) in uploadWordTables">
<el-button @click="addUploadWordTable(item)"> 插入Table{{ i + 1 }} </el-button>
<div class="thumbnailTableBox wordTableHtml table_Box pMain myeditabledivTable drop-target">
<!-- 标题部分 -->
<!-- <font class="font" :style="`width: ${item.width ? `${item.width}px` : '100%'}`" style="text-align: center">
<span v-html="highlightText(item.table.title || '', item.checks ? item.checks : [])"></span>
</font> -->
<!-- 表格部分 -->
<table border="1" style="width: 100%; border-collapse: collapse; text-align: center">
<tr v-for="(row, i) in item.table_data" :key="i" :class="{ 'table-header-row': isHeaderRow(i, item.table_data) }">
<td v-for="(cell, i1) in row" :key="i1" :colspan="`${cell.colspan || 1}`" :rowspan="`${cell.rowspan || 1}`">
<span v-html="cell.text"></span>
</td>
</tr>
</table>
<!-- 备注部分 -->
<!-- <font class="font" :style="`width: ${item.width ? `${item.width}px` : '100%'}`">
<span v-html="highlightText(item.table.note || '', item.checks ? item.checks : [])"></span>
</font> -->
<div style="display: flex; flex-wrap: wrap; gap: 10px; justify-content: start">
<div v-for="(item, i) in uploadWordTables" class="uploadWordTableBox">
<el-button @click="addUploadWordTable(item)" size="mini" class="insertTable"> 插入 </el-button>
<div class="thumbnailTableBox wordTableHtml table_Box pMain myeditabledivTable drop-target">
<p style="font-size: 12px;padding: 10px;box-sizing: border-box;">Table {{ i + 1 }}</p>
<table border="1" :style="`width: 800px;zoom:${zoomNum};border-collapse: collapse; text-align: center`">
<tr
v-for="(row, i) in item.table_data"
:key="i"
:class="{ 'table-header-row': isHeaderRow(i, item.table_data) }"
>
<td style="font-size: 20px;"v-for="(cell, i1) in row" :key="i1" :colspan="`${cell.colspan || 1}`" :rowspan="`${cell.rowspan || 1}`">
<span v-html="cell.text"></span>
</td>
</tr>
</table>
</div>
</div>
<!-- <div v-html="v.html_data"></div> -->
</div>
</el-drawer>
<el-dialog
@@ -412,6 +407,7 @@ import bottomTinymce from '@/components/page/components/Tinymce';
export default {
data() {
return {
zoomNum:(window.innerWidth * 0.38) / 850,
uploadWordTables: [],
tablesHtmlVisible: false,
tablesHtml: '',
@@ -574,6 +570,7 @@ export default {
},
methods: {
async copyArray(data) {
try {
// 将数组内容转换为字符串,使用换行符分隔
@@ -588,8 +585,7 @@ export default {
}
},
openLatexEditor(data) {
console.log('data at line 563:', data);
this.showLateX = true;
this.showLateX = true;
this.LateXInfo = data;
},
isShowEditComment() {
@@ -632,10 +628,8 @@ export default {
},
async getContent(type, content) {
console.log('content at line 539:', content);
if (type == 'content') {
content = this.$commonJS.transformHtmlString(content);
console.log('content at line 604:', content);
var div = document.createElement('div');
div.innerHTML = content; // 将 HTML 字符串加载到 div 中
// 替换所有 <strong> 为 <b>
@@ -1137,42 +1131,15 @@ export default {
// 处理文件上传并传递回调函数
this.$commonJS.handleFileUpload(event, function (tables) {
console.log('tables at line 786:', tables);
// 使用 Promise.all 等待所有表格解析完成
Promise.all(
tables.map((table) => {
return new Promise((resolve, reject) => {
// 解析每个表格
that.$commonJS.parseTableToArray(table, (tableList) => {
console.log('res at line 104:', tableList);
// 生成 HTML 内容
// var contentHtml = `
// <div class="thumbnailTableBox wordTableHtml table_Box" style="">
// <table border="1" style="width: auto; border-collapse: collapse; text-align: center;">
// ${tableList
// .map((row) => {
// return `
// <tr>
// ${row
// .map((cell) => {
// return `
// <td colspan="${cell.colspan || 1}" rowspan="${cell.rowspan || 1}">
// <span>${cell.text || ''}</span>
// </td>
// `;
// })
// .join('')}
// </tr>
// `;
// })
// .join('')}
// </table>
// </div>
// `;
// 将解析后的数据和生成的 HTML 返回
resolve({ table_data: tableList, html_data: '' });
});
});
@@ -1182,8 +1149,7 @@ export default {
// 所有表格的解析完成后,处理结果
that.uploadWordTables = result;
that.tablesHtmlVisible = true;
console.log('Processed tables:', that.uploadWordTables);
})
})
.catch((error) => {
console.error('Error processing tables:', error);
});
@@ -1191,16 +1157,14 @@ export default {
const file = event.target.files[0];
if (file) {
// 处理文件逻辑
console.log('处理文件:', file.name);
}
}
// 关键:重置 input 的值
event.target.value = '';
},
async onAddRow(mainId) {
console.log('data at line 886:', mainId);
await this.$api
.post(this.urlList.addRow, {
am_id: mainId,
@@ -1267,11 +1231,10 @@ export default {
addUploadWordTable(data) {
this.lineStyle = { note: '', table: data.table_data, html_data: data.html_data };
this.lineStyle.visiTitle = 'Insert Table';
this.lineStyle.visiTitle = 'Add Table';
this.threeVisible = true;
},
handleImageEdit(data, type) {
console.log('data at line 600:', data);
if (type == 'img') {
var extension = data.url.split('.').pop().toLowerCase();
this.picStyle = {};
@@ -1301,10 +1264,7 @@ export default {
this.picStyle1.title = str;
} else {
this.lineStyle1[type] = str;
}
},
onEdit(dataId) {
this.currentContent = {};
@@ -1761,12 +1721,11 @@ export default {
}
};
var cleanedTableList = content.table ? content.table : [];
console.log('content at line 998:', this.lineStyle);
cleanedTableList = cleanTableData(content.table);
var strTitle = this.lineStyle1.title? this.lineStyle1.title : '';
var strTitle = this.lineStyle1.title ? this.lineStyle1.title : '';
var strNote = this.lineStyle1.note? this.lineStyle1.note : '';
var strNote = this.lineStyle1.note ? this.lineStyle1.note : '';
if (strNote != '') {
strNote = await this.$commonJS.decodeHtml(strNote);
}
@@ -2229,6 +2188,12 @@ export default {
::v-deep .wordTableHtml table span blue {
color: rgb(0, 130, 170) !important;
}
::v-deep .wordTableHtml table span blue sup{
color: rgb(0, 130, 170) !important;
}
::v-deep .wordTableHtml table span blue sub{
color: rgb(0, 130, 170) !important;
}
.toolbar {
display: flex;
align-items: center;
@@ -2310,4 +2275,26 @@ export default {
::-webkit-scrollbar-thumb:hover {
background: #555; /* 滑块悬停时的颜色 */
}
.uploadWordTableBox {
width: 38vw;
position: relative;
height: auto;
overflow: hidden;
padding: 10px;
box-sizing: border-box;
box-shadow: rgba(0, 0, 0, 0.1) 0px 2px 12px 0px;
}
::v-deep .el-drawer__header {
margin-bottom: 0;
padding: 15px;
}
.uploadWordTableBox .insertTable{
/* display: none; */
position: absolute;
right: 10px;
}
.uploadWordTableBox:hover {
background-color: #0066990d;
/* display: block !important; */
}
</style>

View File

@@ -56,9 +56,9 @@
<span>{{ item.npp }}.</span>
<font @click="lookView(item)">{{ item.title }}</font>
<commonOnlineOperations ref="onlineOperations" :data="item" style="display: inline-block;" type="online">
<span @click="htmlContet(item)" class="onlineOperationsButton"><i class="el-icon-notebook-2"></i>Html</span>
<commonOnlineOperations @fresh="fresh" ref="onlineOperations" :data="item" style="display: inline-block" type="online">
<span @click="htmlContet(item)" class="onlineOperationsButton"><i class="el-icon-notebook-2"></i>Html</span>
<!-- <el-button
style="margin-left: 20px; padding: 4px 10px !important"
size="mini"
@@ -70,9 +70,15 @@
Html</el-button
> -->
</commonOnlineOperations>
<span style="font-size: 13px;" :style="{ color: getStatusColor(item.ai_wechat_status) }" v-if="item.ai_wechat_status&&['Article', 'Review', 'Mini Review'].includes(item.type)">
<span
style="font-size: 13px"
:style="{ color: getStatusColor(item.ai_wechat_status) }"
v-if="item.ai_wechat_status && ['Article', 'Review', 'Mini Review'].includes(item.type)"
>
{{ getStatusText(item.ai_wechat_status) }}
</span>
<i class="el-icon-close" style="color: rgb(255, 0, 0); font-weight: bold" v-if="item.ai_wechat_status > 11"> </i>
<i class="el-icon-check" style="color: #67c23a; font-weight: bold" v-if="item.ai_wechat_status == 10"> </i>
<!-- <el-button
style="margin-left: 20px; padding: 4px 10px !important; background: #ccf7e46e !important;color: #00bc66 !important;border-color:#00bc66 !important;"
@@ -159,7 +165,6 @@
</div>
</el-dialog>
<commonHtml ref="htmlRef"></commonHtml>
</div>
</template>
<script>
@@ -170,7 +175,7 @@ import commonOnlineOperations from '@/components/page/components/article/onlineO
export default {
components: {
commonHtml,
commonOnlineOperations
},
data() {
@@ -235,12 +240,12 @@ export default {
// 字段名 ai_wechat_status 1 Ai内容已生成 2ai内容未生成 3未生成草稿 4 已生成草稿未发布 10 发布成功 11 发布中 >11发布失败
if (status == 1) return '#67C23A';
if (status == 2) return '#C0C4CC';
if (status == 3) return '#C0C4CC';
if (status == 3) return '#409EFF';
if (status == 4) return '#ff9800';
if (status == 10) return '#67C23A';
if (status == 11) return '#409eff';
if (status > 11) return 'red';
if (status == 11) return '#79bbff';
if (status > 11) return 'rgb(255, 0, 0)';
return '';
},
htmlContet(data) {
@@ -249,6 +254,13 @@ export default {
this.$refs.htmlRef.htmlContet(data);
});
},
fresh() {
if (this.currentJournal.cycle != 0) {
this.getNoralDate();
} else {
this.getNoralDate0();
}
},
// 获取数据
getDate() {
console.log('at line 189:', localStorage.getItem('U_pointJour'));

View File

@@ -48,9 +48,16 @@
<el-table-column label="Title">
<template slot-scope="scope">
<p v-html="scope.row.title"></p>
<span style="font-size: 13px;" :style="{ color: getStatusColor(scope.row.ai_wechat_status) }" v-if="scope.row.ai_wechat_status&&['Article', 'Review', 'Mini Review'].includes(scope.row.type)">
{{ getStatusText(scope.row.ai_wechat_status) }}
</span>
<span
style="font-size: 13px"
:style="{ color: getStatusColor(scope.row.ai_wechat_status) }"
v-if="scope.row.ai_wechat_status && ['Article', 'Review', 'Mini Review'].includes(scope.row.type)"
>
{{ getStatusText(scope.row.ai_wechat_status) }} </span
>
<i class="el-icon-close" style="color: rgb(255, 0, 0); font-weight: bold" v-if="scope.row.ai_wechat_status>11"> </i>
<i class="el-icon-check" style="color: #67c23a; font-weight: bold" v-if="scope.row.ai_wechat_status==10"> </i>
</template>
</el-table-column>
<el-table-column label="Cite" width="80px" align="center">
@@ -95,7 +102,13 @@
>
<i class="el-icon-edit"></i> Edit</el-button
>
<commonOnlineOperations ref="onlineOperations" :data="scope.row" style="display: inline-block" type="publish">
<commonOnlineOperations
@fresh="getDate()"
ref="onlineOperations"
:data="scope.row"
style="display: inline-block"
type="publish"
>
<el-dropdown-item
><p @click="htmlContet(scope.row)"><i class="el-icon-notebook-2"></i>Html</p></el-dropdown-item
>
@@ -598,12 +611,12 @@ export default {
// 字段名 ai_wechat_status 1 Ai内容已生成 2ai内容未生成 3未生成草稿 4 已生成草稿未发布 10 发布成功 11 发布中 >11发布失败
if (status == 1) return '#67C23A';
if (status == 2) return '#C0C4CC';
if (status == 3) return '#C0C4CC';
if (status == 3) return '#409EFF';
if (status == 4) return '#ff9800';
if (status == 10) return '#67C23A';
if (status == 11) return '#409eff';
if (status > 11) return 'red';
if (status == 11) return '#79bbff';
if (status > 11) return 'rgb(255, 0, 0)';
return '';
},

View File

@@ -115,6 +115,12 @@ const tableStyle = ` b span{
}blue {
color: rgb(0, 130, 170) !important;
}
blue sup {
color: rgb(0, 130, 170) !important;
}
blue sub {
color: rgb(0, 130, 170) !important;
}
.wordTableHtml table tr.table-header-row:nth-of-type(2) td {
border-bottom: 1px solid #000 !important;
}
@@ -310,7 +316,7 @@ export default {
console.log('粘贴的内容包含表格');
if (_this.type == 'table') {
_this.$commonJS.parseTableToArray(content, (tableList) => {
console.log('res at line 104:', tableList);
var contentHtml = `
<div class="thumbnailTableBox wordTableHtml table_Box" style="">
<table border="1" style="width: auto; border-collapse: collapse; text-align: center;">

View File

@@ -135,7 +135,7 @@
<el-button type="primary" @click="RelatVisible = false" plain>Close</el-button>
</span>
</el-dialog>
<commonHtmlWeChatPreview ref="htmlWeChatPreview"></commonHtmlWeChatPreview>
<commonHtmlWeChatPreview ref="htmlWeChatPreview" @fresh="fresh"></commonHtmlWeChatPreview>
</div>
</template>
@@ -272,6 +272,9 @@ export default {
}
},
methods: {
fresh(){
this.$emit('fresh')
},
htmlWeChatPreview(data) {
console.log('data at line 189:', data);
this.$nextTick((e) => {

View File

@@ -63,7 +63,8 @@
border-radius: 50px;
font-size: 16px;
font-weight: 500;
line-height: 40px;cursor: pointer;
line-height: 40px;
cursor: pointer;
"
@click="handleRelease"
type="primary"
@@ -88,57 +89,116 @@
<div style="padding: 20px 20px 0">
<el-form ref="form" :model="ArticleForm" label-width="160px" size="mini" v-if="ArticleForm.ai_article_id">
<el-form-item>
<template #label>
<span @click="handleTitleClick('covered')" class="form_title">
{{ $t('AIhtmlWeChatPreview.covered') + ' :' }}
</span>
</template>
<p v-if="disablePush">{{ ArticleForm.covered }}</p>
<el-input v-else type="textarea" v-model="ArticleForm.covered" :autosize="{ minRows: 1, maxRows: 3 }" />
</el-form-item>
<div v-if="['Article'].includes(articleBaseInfo.type)">
<el-form-item>
<template #label>
<span @click="handleTitleClick('covered')" class="form_title">
{{ $t('AIhtmlWeChatPreview.covered') + ' :' }}
</span>
</template>
<p v-if="disablePush">{{ ArticleForm.covered }}</p>
<el-input
v-else
type="textarea"
v-model="ArticleForm.covered"
:autosize="{ minRows: 1, maxRows: 3 }"
/>
</el-form-item>
<el-form-item>
<template #label>
<span @click="handleTitleClick('digest')" class="form_title">
{{ $t('AIhtmlWeChatPreview.digest') + ' :' }}
</span>
</template>
<p v-if="disablePush">{{ ArticleForm.digest }}</p>
<el-input v-else type="textarea" v-model="ArticleForm.digest" :autosize="{ minRows: 2, maxRows: 10 }" />
</el-form-item>
<el-form-item>
<template #label>
<span @click="handleTitleClick('digest')" class="form_title">
{{ $t('AIhtmlWeChatPreview.digest') + ' :' }}
</span>
</template>
<p v-if="disablePush">{{ ArticleForm.digest }}</p>
<el-input
v-else
type="textarea"
v-model="ArticleForm.digest"
:autosize="{ minRows: 2, maxRows: 10 }"
/>
</el-form-item>
<el-form-item>
<template #label>
<span @click="handleTitleClick('research_background')" class="form_title">
{{ $t('AIhtmlWeChatPreview.research_background') + ' :' }}
</span>
</template>
<p v-if="disablePush">{{ ArticleForm.research_background }}</p>
<el-input
v-else
type="textarea"
v-model="ArticleForm.research_background"
:autosize="{ minRows: 2, maxRows: 5 }"
/>
</el-form-item>
<el-form-item>
<template #label>
<span @click="handleTitleClick('research_background')" class="form_title">
{{ $t('AIhtmlWeChatPreview.research_background') + ' :' }}
</span>
</template>
<p v-if="disablePush">{{ ArticleForm.research_background }}</p>
<el-input
v-else
type="textarea"
v-model="ArticleForm.research_background"
:autosize="{ minRows: 2, maxRows: 5 }"
/>
</el-form-item>
<el-form-item>
<template #label>
<span @click="handleTitleClick('research_method')" class="form_title">
{{ $t('AIhtmlWeChatPreview.research_methods') + ' :' }}
</span>
</template>
<p v-if="disablePush">{{ ArticleForm.research_method }}</p>
<el-input
v-else
type="textarea"
v-model="ArticleForm.research_method"
:autosize="{ minRows: 2, maxRows: 5 }"
/>
</el-form-item>
<el-form-item>
<template #label>
<span @click="handleTitleClick('research_result')" class="form_title">
{{ $t('AIhtmlWeChatPreview.research_result') + ' :' }}
</span>
</template>
<p v-if="disablePush">{{ ArticleForm.research_result }}</p>
<el-input
v-else
type="textarea"
v-model="ArticleForm.research_result"
:autosize="{ minRows: 2, maxRows: 5 }"
/>
</el-form-item>
<el-form-item>
<template #label>
<span @click="handleTitleClick('discussion_results')" class="form_title">
{{ $t('AIhtmlWeChatPreview.research_result') + ' :' }}
</span>
</template>
<p v-if="disablePush">{{ ArticleForm.discussion_results }}</p>
<el-input
v-else
type="textarea"
v-model="ArticleForm.discussion_results"
:autosize="{ minRows: 2, maxRows: 10 }"
/>
</el-form-item>
</div>
<div v-if="[ 'Review', 'Mini Review'].includes(articleBaseInfo.type)">
<el-form-item>
<template #label>
<span @click="handleTitleClick('overview')" class="form_title">
{{ $t('AIhtmlWeChatPreview.overview') + ' :' }}
</span>
</template>
<p v-if="disablePush">{{ ArticleForm.overview }}</p>
<el-input
v-else
type="textarea"
v-model="ArticleForm.overview"
:autosize="{ minRows: 2, maxRows: 10 }"
/>
</el-form-item>
<el-form-item>
<template #label>
<span @click="handleTitleClick('summary')" class="form_title">
{{ $t('AIhtmlWeChatPreview.summarize') + ' :' }}
</span>
</template>
<p v-if="disablePush">{{ ArticleForm.summary }}</p>
<el-input
v-else
type="textarea"
v-model="ArticleForm.summary"
:autosize="{ minRows: 2, maxRows: 10 }"
/>
</el-form-item>
</div>
<el-form-item>
<!-- <el-form-item>
<template #label>
<span @click="handleTitleClick('discussion')" class="form_title">
{{ $t('AIhtmlWeChatPreview.discussion') + ' :' }}
@@ -151,9 +211,9 @@
v-model="ArticleForm.discussion"
:autosize="{ minRows: 2, maxRows: 5 }"
/>
</el-form-item>
</el-form-item> -->
<el-form-item>
<!-- <el-form-item>
<template #label>
<span @click="handleTitleClick('prospect')" class="form_title">
{{ $t('AIhtmlWeChatPreview.prospect') + ' :' }}
@@ -166,7 +226,7 @@
v-model="ArticleForm.prospect"
:autosize="{ minRows: 2, maxRows: 5 }"
/>
</el-form-item>
</el-form-item> -->
<!-- 作者列表 -->
<div style="margin-top: 10px" v-if="ArticleForm.authors && ArticleForm.authors.length > 0">
@@ -299,6 +359,7 @@ import { watch } from 'vue';
export default {
data() {
return {
articleBaseInfo: {},
publish_status: null,
draft_status: null,
stepValue: null,
@@ -625,7 +686,9 @@ export default {
this.ArticleForm.authors.splice(index, 1);
},
async init(data) {
console.log('data at line 641:', data);
this.articleId = data.article_id;
this.articleBaseInfo = { ...data };
// this.articleId = 2673;
// this.stepList = this.stepList.map((e) => (e.status = ''));
await this.getStatus();
@@ -1121,6 +1184,7 @@ export default {
this.createType = '1'; // html生成方式
this.collapseActiveNames = ['html'];
this.stopInterval();
this.$emit('fresh');
},
beforeupload_manuscirpt(file) {

View File

@@ -247,6 +247,9 @@ export default {
this.$message.error(res.data.msg);
loading.close()
}
}).catch((error) => {
console.error('Error:', error);
loading.close()
});
},
getPayPal(id) {

View File

@@ -151,7 +151,7 @@
<div v-else>{{ addForm.company }}</div>
</el-form-item>
<el-form-item label="Major :" prop="major_a">
<!-- <el-form-item label="Major :" prop="major_a">
<el-select
:disabled="email_num == 1 && reviewerForm.major_a != ''"
v-model="addForm.major_a"
@@ -198,7 +198,11 @@
:value="item.major_id"
></el-option>
</el-select>
</el-form-item> -->
<el-form-item label="Research areas :" prop="major" label-width="160px">
<common-major-list :list="majorValueList" @load="(e) => (this.majorValueList = e)"></common-major-list>
</el-form-item>
<el-form-item label="Field :" prop="field">
<el-input v-model="addForm.field" type="textarea" v-if="email_num != 1 || !addForm.field"></el-input>
@@ -337,6 +341,7 @@
export default {
data() {
return {
majorValueList: [],
tableData: [],
reviewerForm: {}, //审稿人信息
checkForm: {
@@ -497,13 +502,29 @@ export default {
trigger: 'blur'
}
],
major_a: [
major: [
{
required: true,
message: 'Please select major',
trigger: 'blur'
validator: (rule, value, callback) => {
console.log('value at line 1202:', this.form);
var major = this.majorValueList.map((item) => item.selectedValue[item.selectedValue.length - 1]).toString(',');
if (major == '') {
callback(new Error('Please select the Research areas'));
} else {
callback();
}
// 如果你需要在此处使用 this 访问 Vue 实例的数据,使用箭头函数保持上下文
// 其他逻辑
}
}
]
// major_a: [
// {
// required: true,
// message: 'Please select major',
// trigger: 'blur'
// }
// ]
},
urlList: {
userList: 'api/Reviewer/researchUser',
@@ -525,6 +546,7 @@ export default {
this.init();
},
init() {
this.majorValueList = [];
this.initMajor();
this.getCountry();
this.addVisible = true;
@@ -685,39 +707,46 @@ export default {
this.fileL_pdf2[0].url =
this.mediaUrl + 'reviewer/' + this.reviewerForm.cvs[this.reviewerForm.cvs.length - 1].cv;
}
this.addForm.major = 1;
this.addForm.major_a = '';
this.addForm.major_b = '';
this.addForm.major_c = '';
this.addForm.majorList = [];
// this.addForm.major = 1;
// this.addForm.major_a = '';
// this.addForm.major_b = '';
// this.addForm.major_c = '';
// this.addForm.majorList = [];
this.reviewerForm.major = res.data.result.major;
this.reviewerForm.major_a = '';
this.reviewerForm.major_b = '';
this.reviewerForm.major_c = '';
this.reviewerForm.majorList = [];
// this.reviewerForm.major = res.data.result.major;
// this.reviewerForm.major_a = '';
// this.reviewerForm.major_b = '';
// this.reviewerForm.major_c = '';
// this.reviewerForm.majorList = [];
if (res.data.result.majorshu != 0 && res.data.result.majorshu != null) {
if (typeof res.data.result.majorshu == 'number') {
this.addForm.majorList.push(res.data.result.majorshu);
this.reviewerForm.majorList.push(res.data.result.majorshu);
} else {
this.addForm.majorList = res.data.result.majorshu.split(',');
this.reviewerForm.majorList = res.data.result.majorshu.split(',');
}
}
if (this.reviewerForm.majorList) {
if (this.reviewerForm.majorList.length >= 1) {
this.reviewerForm.major_a = this.reviewerForm.majorList[0];
}
if (this.reviewerForm.majorList.length >= 2) {
this.reviewerForm.major_b = this.reviewerForm.majorList[1];
}
if (this.reviewerForm.majorList.length == 3) {
this.reviewerForm.major_c = this.reviewerForm.majorList[2];
}
}
// if (res.data.result.majorshu != 0 && res.data.result.majorshu != null) {
// if (typeof res.data.result.majorshu == 'number') {
// this.addForm.majorList.push(res.data.result.majorshu);
// this.reviewerForm.majorList.push(res.data.result.majorshu);
// } else {
// this.addForm.majorList = res.data.result.majorshu.split(',');
// this.reviewerForm.majorList = res.data.result.majorshu.split(',');
// }
// }
this.majorValueList = this.reviewerForm.major_data.map((item) => ({
selectedValue: Array.isArray(item.shu)
? item.shu
: typeof item.shu === 'string'
? item.shu.split(',').map(Number)
: [item.shu]
}));
console.log('this.majorValueList at line 903:', this.majorValueList);
// if (this.reviewerForm.majorList) {
// if (this.reviewerForm.majorList.length >= 1) {
// this.reviewerForm.major_a = this.reviewerForm.majorList[0];
// }
// if (this.reviewerForm.majorList.length >= 2) {
// this.reviewerForm.major_b = this.reviewerForm.majorList[1];
// }
// if (this.reviewerForm.majorList.length == 3) {
// this.reviewerForm.major_c = this.reviewerForm.majorList[2];
// }
// }
// if (this.reviewerForm.major_c != '' || this.reviewerForm.major_c != 0) {
// this.reviewerForm.major = this.reviewerForm.major_c;
// } else if (this.addForm.major_b != '' || this.addForm.major_b != 0) {
@@ -728,7 +757,7 @@ export default {
this.$forceUpdate();
console.log('this.addForm.majorList at line 674:', this.reviewerForm);
this.$nextTick(async () => {
await this.jiLInaoan();
// await this.jiLInaoan();
await this.getJournalsForReviewerInEditor();
});
@@ -865,19 +894,19 @@ export default {
}
// this.addForm.maj_cn = [this.addForm.major, this.addForm.cmajor];
this.addForm.major = 1;
this.addForm.major_a = '';
this.addForm.major_b = '';
this.addForm.major_c = '';
this.addForm.majorList = [];
// this.addForm.major = 1;
// this.addForm.major_a = '';
// this.addForm.major_b = '';
// this.addForm.major_c = '';
// this.addForm.majorList = [];
if (this.addForm.majorshu != 0 && this.addForm.majorshu != null) {
if (typeof this.addForm.majorshu == 'number') {
this.addForm.majorList.push(this.addForm.majorshu);
} else {
this.addForm.majorList = this.addForm.majorshu.split(',');
}
}
// if (this.addForm.majorshu != 0 && this.addForm.majorshu != null) {
// if (typeof this.addForm.majorshu == 'number') {
// this.addForm.majorList.push(this.addForm.majorshu);
// } else {
// this.addForm.majorList = this.addForm.majorshu.split(',');
// }
// }
this.$nextTick(() => {
this.jiLInaoan();
@@ -937,7 +966,7 @@ export default {
reviewer_id: this.addForm.reviewer_id,
title: this.addForm.title,
country: this.addForm.country,
major: this.addForm.major,
// major: this.addForm.major,
// majorshu: this.addForm.majorshu,
cmajor: this.addForm.cmajor,
field: this.addForm.field,
@@ -949,10 +978,10 @@ export default {
cv: this.addForm.cv,
journal_id: this.addForm.journal_id
};
data.major = this.majorValueList.map((item) => item.selectedValue[item.selectedValue.length - 1]).toString(',');
console.log(data, this.addForm, 111111111111111111111);
if (this.email_num == 2) {
// 新的
path_add = this.urlList.addReviewer;
@@ -979,9 +1008,6 @@ export default {
}
}
this.$api
.post(path_add, data)
.then((res) => {

View File

@@ -128,8 +128,7 @@ export default {
const container = document.createElement('div');
container.innerHTML = content;
this.$commonJS.parseTableToArray(content, (table) => {
console.log('res at line 104:', table);
// return false
this.$emit('getContent', type, { html_data: content, table: table });
});
} else {

View File

@@ -23,11 +23,11 @@
left: 285px;
z-index: 10;
right: 330px;
height: 60px;
height: 46px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px;
padding:0 10px;
box-sizing: border-box;
overflow: hidden;
width: calc(100% - 285px - 330px);
@@ -70,20 +70,20 @@
</div>
</div>
<div style="border-left: 1px solid #d8d8d8; padding: 0 20px; float: right">
<div style="border-left: 1px solid #d8d8d8; padding: 0 0px; float: right">
<ul class="operateBox">
<li
v-if="isEditComment"
style="height: 40px; background-color: #fff !important; color: #f56c6c; border: 1px solid #f56c6c"
style=" background-color: #fff !important; color: #f56c6c; border: 1px solid #f56c6c"
@mousedown="cacheSelection"
@click="handleSelection"
>
<i class="el-icon-document-add" style="margin-top: 2px"></i>
<i class="el-icon-document-add" style="margin-top: 2px;float: left;"></i>
Comment
</li>
<li
style="height: 40px; background-color: #cbccd1 !important; color: #333; border: 1px solid #cbccd1"
style=" background-color: #cbccd1 !important; color: #333; border: 1px solid #cbccd1"
@click="onAddRow"
>
<i class="el-icon-document-add" style="margin-top: 2px"></i>
@@ -91,13 +91,13 @@
Row
</li>
<li style="height: 40px" @click="onEdit">
<li style="" @click="onEdit">
<i class="el-icon-edit" style="margin-top: 2px"></i>
Edit
</li>
<li style="height: 40px; background-color: red !important" @click="onDelete">
<li style=" background-color: #fc625d !important;" @click="onDelete">
<i class="el-icon-delete" style="margin-top: 2px"></i>
Delete
@@ -117,6 +117,10 @@
position: relative;
"
>
{{ selectedIds }}
<div v-if="selectedIds.length > 0" class="selected-to-here">
Selected to here: {{ selectedIds[selectedIds.length - 1] }}
</div>
<!-- <common-late-x></common-late-x> -->
<template v-for="(item, index) in wordList">
<el-checkbox
@@ -487,6 +491,12 @@ const tableStyle = `
}blue {
color: rgb(0, 130, 170) !important;
}
blue sup{
color: rgb(0, 130, 170) !important;
}
blue sub{
color: rgb(0, 130, 170) !important;
}
b span{
font-weight: bold !important;
}
@@ -725,7 +735,7 @@ export default {
formLabelWidth: '120px',
hasChange: false,
hasInit: false,
selectedIds:[],
tinymceId: this.id || 'vue-tinymce-' + +new Date()
};
},
@@ -904,6 +914,8 @@ export default {
updateUniqueIds() {
this.currentId = null;
this.currentData = {};
console.log('this.selectedIds at line 917:', this.selectedIds)
// this.uniqueIds = [...new Set(this.wordList.filter((item) => item.checked).map((item) => item.am_id))];
// console.log('this.uniqueIds at line 839:', this.selectedIds);
this.$forceUpdate();
@@ -918,7 +930,7 @@ export default {
},
onDelete() {
// console.log('this.uniqueIds.length at line 866:', this.selectedIds.length);
if (this.selectedIds.length > 0) {
if (this.selectedIds&&this.selectedIds.length > 0) {
this.$emit('onDeletes', this.selectedIds.toString());
this.$forceUpdate();
}
@@ -2352,23 +2364,37 @@ export default {
display: flex;
}
.operateBox li {
width: 55px;
min-width: 55px;
display: flex;
flex-direction: column;
justify-content: center;
/* flex-direction: column; */
justify-content: space-between;
align-items: center;
list-style: none;
padding: 2px 10px;
margin: 0 10px;
margin-left:10px;
color: #8a8a8b;
/* font-weight: bold; */
font-size: 16px;
background-color: rgb(43, 129, 239) !important;
color: #fff;
border-radius: 4px;
height: 26px;
}
::v-deep .el-checkbox__inner {
width: 18px;
height: 18px;
}
/* 悬浮提示的样式 */
.selected-to-here {
position: fixed;
top: 10px;
left: 50%;
transform: translateX(-50%);
background-color: rgba(0, 123, 255, 0.7);
color: white;
padding: 10px 20px;
border-radius: 5px;
font-size: 14px;
z-index: 999;
}
</style>

View File

@@ -51,7 +51,14 @@
<p>{{ v.title }}</p>
</li>
</ul> -->
<div style="width: 200px; float: right; padding: 10px; height: 100%; box-sizing: border-box; overflow-y: auto" class="arrlist">
<div class="go-mt" >
<el-radio-group v-model="isCollapse" style="float:right;" size="mini" @change="changeIsCollapse">
<el-radio-button :label="false">{{ $t('commonTable.singleRow') }}</el-radio-button>
<el-radio-button :label="true">{{ $t('commonTable.Multicolumn') }}</el-radio-button>
</el-radio-group>
</div>
<div style="width: 200px; float: right; padding: 10px; height: calc(100% - 28px); box-sizing: border-box; overflow-y: auto" class="arrlist">
<ul style="width: 100%; height: auto">
<!-- <li v-show="currentMenu == 1">
<div style="display: flex; flex-wrap: wrap; gap: 10px; justify-content: start">
@@ -101,9 +108,10 @@
</li>
</div>
</li> -->
<li v-show="currentMenu == 1">
<div style="" class="go-content-charts-item-box">
<div class="item_box" style="width: 100%; height: auto; position: relative">
<div style="" class="go-content-charts-item-box" :class="isCollapse?'double':'single'">
<!-- <div class="item_box" style="width: 100%; height: auto; position: relative" >
<el-collapse v-if="isShowEdit">
<el-collapse-item name="1" style="margin-top: 4px">
<template slot="title">
@@ -121,14 +129,8 @@
></el-input>
</el-collapse-item>
</el-collapse>
<!-- <p
style="color: #777; margin-top: 6px"
v-else
@click="img.has_selected == 1 ? goToListComment(img.article_image_id, 'img') : ''"
>
<el-link> Figures {{ index + 1 }} </el-link>
</p> -->
</div>
</div> -->
<div class="item_box" style="width: 100%; height: auto; position: relative">
<div class="list-center go-flex-center go-transition" style="width: 100%" @click="addImage">
<div class="title">
@@ -146,7 +148,7 @@
overflow: hidden;
position: relative;`"
>
<div style="width: 100%; height: 80px; display: flex; justify-content: center; align-items: center">
<div class="imgbox" style="width: 100%; height: 80px; display: flex; justify-content: center; align-items: center">
<!-- 图片内容 -->
<img src="@/assets/img/upload.png" style="width: 100px; height: 100%; object-fit: cover" />
</div>
@@ -189,13 +191,12 @@
<div class="title">
<span
>Figure {{ index + 1 }}
<span
<span class="previewbox"
@click="openPreview(index, 'img')"
v-if="['jpg', 'jpeg', 'png'].includes(img.image.split('.').pop().toLowerCase())"
>
<!-- <el-tooltip class="item" effect="dark" :content="$t('commonTable.preview')" placement="top"> -->
<i class="el-icon-view" style="font-size: 16px"></i>
<!-- </el-tooltip> -->
<i class="el-icon-view" style="font-size: 16px"></i>
</span>
<a :href="mediaUrl + img.image.url" style="color: #000" v-else>
<!-- <el-tooltip class="item" effect="dark" :content="$t('commonTable.preview')" placement="top"> -->
@@ -243,17 +244,17 @@
:draggable="img.has_selected == 0 ? true : false"
@dragstart="img.has_selected == 0 ? onDragStart($event, img, index, 'img') : ''"
>
<div style="width: 100%; height: 80px; display: flex; justify-content: center; align-items: center">
<div class="imgbox" style="width: 100%; height: 80px; display: flex; justify-content: center; align-items: center">
<!-- 图片内容 -->
<template v-if="['jpg', 'jpeg', 'png'].includes(img.image.split('.').pop().toLowerCase())">
<img
<img @click="img.has_selected == 1?goToListComment(img.article_image_id, 'img'):openPreview(index, 'img')"
:data-img-id="img.article_image_id"
:src="mediaUrl + img.image"
style="width: 140px; height: 100%; object-fit: cover"
/>
</template>
<template v-else-if="img.image.split('.').pop().toLowerCase() === 'tif'">
<img
<img @click="img.has_selected == 1?goToListComment(img.article_image_id, 'img'):openPreview(index, 'img')"
:data-img-id="img.article_image_id"
:src="img.dataUrl"
style="width: 140px; height: 100%; object-fit: cover"
@@ -309,13 +310,12 @@
</div>
</li>
<li v-show="currentMenu == 2">
<div style="" class="go-content-charts-item-box">
<div style="" class="go-content-charts-item-box" :class="isCollapse?'double':'single'">
<div class="item_box" @click="addTable" style="width: 100%; height: auto; position: relative">
<div class="list-center go-flex-center go-transition" style="width: 100%">
<div class="title">
<span>Add Table </span>
<!-- <span @click.stop="handlePaperclip"><i class="el-icon-paperclip"></i></span> -->
</div>
<div
@@ -329,7 +329,7 @@
overflow: hidden;
position: relative;`"
>
<div style="width: 100%; height: 80px; display: flex; justify-content: center; align-items: center">
<div class="imgbox" style="width: 100%; height: 80px; display: flex; justify-content: center; align-items: center">
<!-- 图片内容 -->
<img src="@/assets/img/uploadTable.png" style="width: 100px; height: 100%; object-fit: cover" />
</div>
@@ -371,7 +371,7 @@
<div class="title">
<span
>Table {{ index + 1 }}
<span @click="openPreview(index, 'table')">
<span class="previewbox" @click="openPreview(index, 'table')">
<el-tooltip class="item" effect="dark" :content="$t('commonTable.preview')" placement="top">
<i class="el-icon-view" style="font-size: 16px"></i>
</el-tooltip> </span
@@ -416,7 +416,7 @@
:draggable="table.has_selected == 0 ? true : false"
@dragstart="table.has_selected == 0 ? onDragStart($event, table, index, 'table') : ''"
>
<div style="width: 100%; height: 80px; display: flex; justify-content: center; align-items: center">
<div class="imgbox" @click="table.has_selected == 1?goToListComment(table.article_table_id, 'table'):openPreview(index, 'table')" style="width: 100%; height: 80px; display: flex; justify-content: center; align-items: center">
<!-- 图片内容 -->
<table
:data-table-id="table.article_table_id"
@@ -508,6 +508,7 @@ export default {
data() {
return {
isShowComment: false,
isCollapse: false,
isEditComment: false,
isEditing: null, // 用于跟踪当前正在编辑的批注索引
selectedComment: null, // 存储当前选择的批注内容
@@ -544,6 +545,11 @@ export default {
}
},
methods: {
changeIsCollapse(e){
localStorage.setItem('isCollapse', e)
},
isShowEditComment() {
if (localStorage.getItem('U_role')) {
var identity = localStorage.getItem('U_role');
@@ -633,7 +639,6 @@ export default {
})
.then((res) => {
this.comments = res.data.list;
});
},
addImage() {
@@ -668,7 +673,6 @@ export default {
this.filterData();
},
filterData(type) {
if (type) {
if (type == 'img') {
this.imagesList = [...this.images];
@@ -849,8 +853,8 @@ export default {
text-align: center;
table-layout: auto;"
>`;
if (table.table&&table.table.length > 0) {
if (table.table && table.table.length > 0) {
table.table.forEach((row) => {
modalContent += `<tr>`;
row.forEach((cell) => {
@@ -871,11 +875,12 @@ export default {
this.$commonJS.createImageModal(index, modalContent, 'table', '');
});
}
});
}
},
async created() {
this.isCollapse=localStorage.getItem('isCollapse')=='true'?true:false;
console.log('localStorage.getItem',typeof localStorage.getItem('isCollapse'))
this.isShowEditComment();
this.isFresh = false;
this.$nextTick(async () => {
@@ -887,6 +892,7 @@ export default {
});
},
async activated() {
this.isCollapse=localStorage.getItem('isCollapse')=='true'?true:false;
this.isFresh = false;
this.isShowEditComment();
this.$nextTick(async () => {
@@ -1058,5 +1064,34 @@ li {
}
::v-deep.pizhu.el-link--default:hover {
border-color: #fc625d !important;
}
.go-mt {
/* background-color: #f2f3f5;
height: 28px; */
width: 200px;
float: right;
}
.double .item_box{
width: 46% !important;
}
.double .item_box .previewbox{
display: none;
}
.double .item_box .imgbox {
height: 50px !important;
width: auto !important;
}
.double .item_box .imgbox img{
height: 60px !important;
width: auto !important;
}
.double .go-transition .title{
font-size: 12px !important;
padding:0 2px !important;
line-height: 20px !important;
}
.single{
}
</style>

View File

@@ -87,8 +87,13 @@
<p class="rm_huid">{{ userMessage.technical }}</p>
</div>
<div class="rol_mess">
<font>Major :</font>
<p class="rm_huid">{{ userMessage.majorStr }}</p>
<font>Research areas :</font>
<!-- <p class="rm_huid">{{ userMessage.majorStr }}</p> -->
<p class="rm_huid">
<span v-for="(field,fieldIndex) in userMessage.majors" style="display: block;">
<span>{{ fieldIndex+1}}.</span> {{ field.str.replace("Medicine >", "").trim() }}
</span>
</p>
</div>
<div class="rol_mess" v-if="userMessage.company != '' && userMessage.company != undefined">
<font>Company :</font>
@@ -409,9 +414,20 @@
line-height: 20px;
"
>
<a :href="this.userMessage.g_author?`https://scholar.google.com/citations?hl=en&user=${this.userMessage.g_author}`:''" target="_blank" style="color: rgb(0, 102, 153) !important">{{
this.userMessage.g_author?`https://scholar.google.com/citations?hl=en&user=${this.userMessage.g_author}`:''
}}</a>
<a
:href="
this.userMessage.g_author
? `https://scholar.google.com/citations?hl=en&user=${this.userMessage.g_author}`
: ''
"
target="_blank"
style="color: rgb(0, 102, 153) !important"
>{{
this.userMessage.g_author
? `https://scholar.google.com/citations?hl=en&user=${this.userMessage.g_author}`
: ''
}}</a
>
</span>
</div>
<!-- <div class="rol_mess">
@@ -747,7 +763,54 @@
<el-option v-for="item in df_technical" :key="item.label" :label="item.label" :value="item.label"></el-option>
</el-select>
</el-form-item>
<el-form-item label="Major :" prop="majors_a">
<el-form-item label="Research areas :" prop="major" label-width="160px">
<common-major-list :list="majorValueList" @load="(e) => (this.majorValueList = e)"></common-major-list>
<!-- <el-select
v-model="form.major_a"
placeholder="Please select major"
@change="majorChange(1)"
style="width: 240px"
>
<el-option
v-for="item in majors_a"
:key="item.major_id"
:label="item.major_title"
:value="item.major_id"
></el-option>
</el-select>
<el-select
v-model="form.major_b"
placeholder="Please select major"
v-if="majors_b != ''"
@change="majorChange(2)"
style="margin: 0 15px; width: 240px"
>
<el-option :key="0" label="None" :value="0"></el-option>
<el-option
v-for="item in majors_b"
:key="item.major_id"
:label="item.major_title"
:value="item.major_id"
></el-option>
</el-select>
<el-select
v-model="form.major_c"
placeholder="Please select major"
v-if="majors_c != ''"
style="width: 240px"
@change="majorChange(3)"
>
<el-option :key="0" label="None" :value="0"></el-option>
<el-option
v-for="item in majors_c"
:key="item.major_id"
:label="item.major_title"
:value="item.major_id"
></el-option>
</el-select> -->
</el-form-item>
<!-- <el-form-item label="Major :" prop="majors_a">
<el-select
v-model="MessForm.major_a"
placeholder="Please select"
@@ -791,7 +854,7 @@
:value="item.major_id"
></el-option>
</el-select>
</el-form-item>
</el-form-item> -->
<el-form-item label="Company :" prop="company">
<el-input v-model="MessForm.company" placeholder="Please enter"></el-input>
</el-form-item>
@@ -891,8 +954,8 @@
>Certified
</el-button>
<span style="margin: 0 0 0 5px; padding: 5px 12px; color: #999" v-if="googleSearchInfo != ''">
( {{ googleSearchInfo }} )</span
>
( {{ googleSearchInfo }} )</span
>
</el-form-item>
<p v-if="geogleList.length != 0 && bankVisible" style="margin: 20px 0 20px 0; font-weight: bold">
@@ -1110,13 +1173,16 @@
</template>
<script>
import PendingPayment from '@/components/page/components/pendingPayment/index.vue';
import PendingPayment from '@/components/page/components/pendingPayment/index.vue';
export default {
data() {
return {
orderList:[ { id: 1, title: '稿件1', author: '作者1', amount: 100, status: '未缴费',orderId:'6VT20279NK3463528' },
{ id: 2, title: '稿件2', author: '作者2', amount: 200, status: '未缴费',orderId:'6VT20279NK3463528' },
{ id: 3, title: '稿件3', author: '作者3', amount: 300, status: '未缴费' ,orderId:'6VT20279NK3463528' },],
majorValueList: [],
orderList: [
{ id: 1, title: '稿件1', author: '作者1', amount: 100, status: '未缴费', orderId: '6VT20279NK3463528' },
{ id: 2, title: '稿件2', author: '作者2', amount: 200, status: '未缴费', orderId: '6VT20279NK3463528' },
{ id: 3, title: '稿件3', author: '作者3', amount: 300, status: '未缴费', orderId: '6VT20279NK3463528' }
],
citeLoading: false,
wosLoading: false,
authorList: [],
@@ -1266,7 +1332,7 @@ export default {
}
],
role_author: 0,
googleSearchInfo:'',
googleSearchInfo: '',
role_editor: 0,
role_chief: 0,
role_reviewer: 0,
@@ -1346,11 +1412,27 @@ export default {
trigger: 'blur'
}
],
majors_a: [
// majors_a: [
// {
// required: true,
// message: 'Please select major',
// trigger: 'blur'
// }
// ],
major: [
{
required: true,
message: 'Please select major',
trigger: 'blur'
validator: (rule, value, callback) => {
console.log('value at line 1202:', this.form);
var major = this.majorValueList.map((item) => item.selectedValue[item.selectedValue.length - 1]).toString(',');
if (major == '') {
callback(new Error('Please select the Research areas'));
} else {
callback();
}
// 如果你需要在此处使用 this 访问 Vue 实例的数据,使用箭头函数保持上下文
// 其他逻辑
}
}
],
technical: [
@@ -1371,7 +1453,7 @@ export default {
};
},
components: {
PendingPayment
PendingPayment
},
mounted() {},
created() {
@@ -1532,7 +1614,17 @@ export default {
this.userMessage.majorStr = res.data.baseInfo.majorStr;
this.cvitaForm.user_id = res.data.baseInfo.user_id;
this.userMessage.website = res.data.baseInfo.website;
console.log('res.data.baseInfo.majors.map at line 16124:', res.data.baseInfo.majors)
this.userMessage.majors=res.data.baseInfo.majors
this.majorValueList = res.data.baseInfo.majors.map((item) => ({
selectedValue: Array.isArray(item.shu)
? item.shu
: typeof item.shu === 'string'
? item.shu.split(',').map(Number)
: [item.shu]
}));console.log('this.majorValueList at line 1612:', this.majorValueList)
this.$forceUpdate()
this.coreTable = res.data.baseInfo;
this.cvitaTable = res.data.cvs;
@@ -1633,22 +1725,23 @@ export default {
// query: {
// id: this.userMessage.user_id
// }
// });
// });console.log('this.userMessage at line 1700:', this.userMessage)
this.MessForm = JSON.parse(JSON.stringify(this.userMessage));
this.MessForm.major = 1;
this.MessForm.major_a = '';
this.MessForm.major_b = '';
this.MessForm.major_c = '';
this.MessForm.majorList = [];
if (this.MessForm.majorshu != 0) {
if (typeof this.MessForm.majorshu == 'number') {
this.MessForm.majorList.push(this.MessForm.majorshu);
} else {
this.MessForm.majorList = this.MessForm.majorshu.split(',');
}
}
// this.MessForm.major = 1;
// this.MessForm.major_a = '';
// this.MessForm.major_b = '';
// this.MessForm.major_c = '';
// this.MessForm.majorList = [];
// if (this.MessForm.majorshu != 0) {
// if (typeof this.MessForm.majorshu == 'number') {
// this.MessForm.majorList.push(this.MessForm.majorshu);
// } else {
// this.MessForm.majorList = this.MessForm.majorshu.split(',');
// }
// }
this.$nextTick(() => {
this.jiLInaoan();
@@ -1665,6 +1758,11 @@ export default {
this.$message.error(this.$t('info.realname'));
return false;
}
this.MessForm.major = this.majorValueList.map((item) => item.selectedValue[item.selectedValue.length - 1]).toString(',');
if (this.MessForm.major == '') {
this.$message.error('Please select the Research areas');
return false;
}
this.$api
.post('api/Ucenter/updateUserInfo', this.MessForm)
@@ -1732,7 +1830,7 @@ export default {
switch (data) {
case 'wos':
date = this.userMessage.wos_time;
console.log('date at line 1714:', date)
console.log('date at line 1714:', date);
break;
case 'scopus':
date = this.userMessage.scopus_time;

File diff suppressed because it is too large Load Diff