This commit is contained in:
2025-01-23 10:32:14 +08:00
parent 1f169dc517
commit 85fbbd84f2
22 changed files with 3164 additions and 3263 deletions

View File

@@ -21,11 +21,11 @@
<div style="width: 100%;height: calc(100% - 62px);overflow: hidden;">
<div class="content" style="padding: 0;overflow: hidden;">
<transition name="move" mode="out-in">
<keep-alive :include="tagsList">
<!-- <transition name="move" mode="out-in"> -->
<!-- <keep-alive :include="tagsList"> -->
<router-view></router-view>
</keep-alive>
</transition>
<!-- </keep-alive> -->
<!-- </transition> -->
<el-backtop target=".content"></el-backtop>
</div>
</div>

View File

@@ -2,12 +2,12 @@
//记得切换
//正式
// const mediaUrl = '/public/';
// const baseUrl = '/';
const mediaUrl = '/public/';
const baseUrl = '/';
const mediaUrl = 'https://submission.tmrjournals.com/public/';
const baseUrl = '/api';
// const mediaUrl = 'https://submission.tmrjournals.com/public/';
// const baseUrl = '/api';

View File

@@ -358,6 +358,7 @@ const en = {
delete: 'Delete',
reply: 'Reply',
solve: 'Solve',
cancelsolve: 'Cancel resolved',
Resolved: 'Resolved',
preview: 'Preview',
link: 'Positioning',
@@ -377,7 +378,9 @@ const en = {
removeAnnotations:'Are you sure you want to delete this Annotation?',
removeContent:'Are you sure you want to delete this content?',
reContent:'Are you sure you want to restore this content?',
uploadImageInfo:'Figures can only upload files in JPG, JPEG, and PNG formats!'
uploadImageInfo:'Figures can only upload files in JPG, JPEG, and PNG formats!',
selectComment:'Please select the text to add annotations to!',
alreadyCommented:'There are already annotations in the text, please select again!'
},
pendingPayment:{
title:'Title',

View File

@@ -351,6 +351,7 @@ const zh = {
delete: '删除',
reply: '答复',
solve: '解决',
cancelsolve: '取消解决',
Resolved: '已解决',
preview: '预览',
positioning: '定位',
@@ -370,7 +371,9 @@ const zh = {
removeAnnotations: '确定要删除这条批注吗?',
removeContent: '确定要删除这条内容吗?',
reContent: '确定要恢复这条内容吗?',
uploadImageInfo: 'Figures 只能上传 JPG、JPEG 和 PNG 格式的文件'
uploadImageInfo: 'Figures 只能上传 JPG、JPEG 和 PNG 格式的文件',
selectComment: '请选择要添加批注的文本',
alreadyCommented:'文本中已有批注内容请重新选择',
},
pendingPayment: {
title: 'Title',

View File

@@ -270,12 +270,16 @@ export default {
},
// 跳转到图表编辑页面
goGenerateCharts(id) {
this.$router.push({
path: 'GenerateCharts',
window.open(this.$router.resolve({ path: '/GenerateCharts',
query: {
id: id
}
});
} }).href, '_blank');
// this.$router.push({
// path: 'GenerateCharts',
// query: {
// id: id
// }
// });
},
// 隐藏alert

View File

@@ -86,6 +86,7 @@
</div> -->
<common-word
:key="Main_List"
v-if="htmlContent"
ref="commonWord"
:value="htmlContent"
@@ -94,7 +95,6 @@
:wordStyle="wordStyle"
@onDrop="onDrop"
@saveContent="saveContent"
@deleteComment="deleteComment"
@editComment="editComment"
@loaded="loadedWord"
@onEdit="onEdit"
@@ -102,7 +102,12 @@
@refresh="onRefresh"
@onComment="onComment"
@onAddComment="onAddComment"
@solveComment="solveComment"
@cancelSolveComment="cancelSolveComment"
@replyComment="replyComment"
@deleteComment="deleteComment"
@onEditTitle="onEditTitle"
@onAddRow="onAddRow"
@changeComment="changeComment"
style="width: calc(100%); height: calc(100%)"
:style="`100%`"
@@ -139,16 +144,16 @@
</el-form-item>
<el-form-item label="Figure Describe :">
<tinymce
<common-content
:isAutomaticUpdate="true"
ref="tinymceChildImgNote"
@getContent="getContent"
@updateChange="(res) => updateChange(res, 'imgNote')"
:value="picStyle.note"
class="paste-area text-container"
toolbar="bold italic subscript superscript clearButton"
height="120"
></tinymce>
@getContent="getContent"
v-if="pictVisible"
@updateChange="(res) => updateChange(res, 'imgNote')"
:height="120"
ref="tinymceChildImgNote"
style="margin-left: -115px"
></common-content>
</el-form-item>
</el-form>
@@ -163,6 +168,7 @@
<!-- 添加表格 -->
<el-dialog
class="editTableDialog"
destroy-on-close
v-if="threeVisible"
:title="lineStyle.visiTitle"
@@ -172,16 +178,16 @@
>
<el-form ref="editMes" :model="lineStyle" label-width="115px">
<el-form-item label="Table Title :">
<tinymce
<common-content
:isAutomaticUpdate="true"
ref="tinymceChildTitle"
@getContent="getContent"
@updateChange="(res) => updateChange(res, 'title')"
:value="lineStyle.title"
class="paste-area text-container"
toolbar="bold italic subscript superscript clearButton"
height="120"
></tinymce>
@getContent="getContent"
v-if="threeVisible"
@updateChange="(res) => updateChange(res, 'title')"
:height="120"
ref="tinymceChildTitle"
style="margin-left: -115px"
></common-content>
</el-form-item>
<el-form-item label="Word">
<span slot="label">
@@ -198,16 +204,16 @@
></common-table>
</el-form-item>
<el-form-item label="Bottom Title :">
<bottom-tinymce
<common-content
:isAutomaticUpdate="true"
ref="tinymceChildNote"
@getContent="getContent"
@updateChange="(res) => updateChange(res, 'note')"
:value="lineStyle.note"
class="paste-area text-container"
toolbar="bold italic subscript superscript clearButton"
height="150"
></bottom-tinymce>
@getContent="getContent"
v-if="threeVisible"
@updateChange="(res) => updateChange(res, 'note')"
:height="120"
ref="tinymceChildNote"
style="margin-left: -115px"
></common-content>
</el-form-item>
</el-form>
<p style="margin: 20px 0; text-align: right">
@@ -224,9 +230,9 @@
:close-on-click-modal="false"
>
<el-form ref="editMes" :model="commentForm" label-width="115px">
<el-form-item label="Select Content:" v-if="commentForm.commentLabel">
<el-form-item label="Select Content:" v-if="commentForm.content">
<p style="background: #eef0f4; line-height: 20px; padding: 10px; box-sizing: border-box">
{{ commentForm.commentLabel }}
{{ commentForm.content }}
</p>
</el-form-item>
<el-form-item label="Word">
@@ -234,6 +240,7 @@
<font style="color: #f56c6c; margin-right: 5px">*</font>
Comment :
</span>
<tinymce
ref="tinymceChildComment"
@getContent="getContent"
@@ -267,14 +274,13 @@
<font style="color: #f56c6c; margin-right: 5px">*</font>
Content :
</span>
<tinymce
ref="tinymceChild"
@getContent="getContent"
<common-content
:value="currentContent.content"
class="paste-area text-container"
toolbar="bold italic customBlue removeBlue subscript superscript clearButton "
style=""
></tinymce>
@getContent="getContent"
v-if="editVisible"
ref="commonContent"
style="margin-left: -115px"
></common-content>
</el-form-item>
</el-form>
@@ -312,7 +318,13 @@ export default {
isShowComment: false,
urlList: {
delete: 'api/Preaccept/delArticleMains',
addComment: 'api/Preaccept/addMainsRemark',
addRow: 'api/Preaccept/addBlankRow',
addComment: 'api/Preaccept/createArticleMainCheckForEditor',
editComment: 'api/Preaccept/editArticleMainCheck',
solveComment: 'api/Preaccept/completeArticleMainCheckForAuthor',
cancelSolveComment: 'api/Preaccept/rejectArticleMainCheckForEditor',
deleteComment: 'api/Preaccept/delArticleMainCheckForEditor',
replyComment: 'api/Preaccept/rejectArticleMainCheckForAuthor',
content: 'api/Preaccept/getArticleMainsRecycle',
huifuContent: 'api/Preaccept/replyArticleRecycle',
editContent: 'api/Preaccept/editArticleMainsForAuthor',
@@ -432,12 +444,13 @@ export default {
}
},
created() {
localStorage.removeItem('scrollPosition');
this.isShowEditComment();
this.getDate();
this.getCommentList();
// this.loadDictionary().catch(console.error);
},
mounted() {},
activated() {
this.isShowEditComment();
this.getDate();
@@ -478,8 +491,9 @@ export default {
// }
// },
handleSaveContent() {
this.$refs.tinymceChild.getContent('content');
this.$refs.commonContent.getTinymceContent('content');
},
async getContent(type, content) {
if (type == 'content') {
// 使用正则表达式移除所有不允许的标签
@@ -523,7 +537,7 @@ export default {
// 6. 如果需要,还可以去除 <span> 标签内部的空格
// content = content.replace(/<span[^>]*>\s*([^<]+)\s*<\/span>/g, '<span>$1</span>'); // 清理 <span> 标签内部的空格
this.saveContent(content);
this.saveContent(content, this.currentContent.am_id);
} else if (type == 'table') {
this.saveTable(content);
} else if (type == 'comment') {
@@ -540,12 +554,16 @@ export default {
})
.then(() => {
this.$api
.post('api/Preaccept/clearMainsRemark', {
am_id: comment.am_id
.post(this.urlList.deleteComment, {
amc_id: comment.amc_id
})
.then((res) => {
this.getDate();
this.getCommentList();
if (res.code == 0) {
this.getDate();
this.getCommentList();
} else {
this.$message.error(res.msg);
}
});
// this.comments.splice(index, 1); // 删除评论
})
@@ -570,6 +588,7 @@ export default {
if (res.code == 0) {
this.editVisible = false;
this.getDate();
this.getCommentList();
}
});
},
@@ -605,7 +624,7 @@ export default {
.then(async (res) => {
if (res.code == 0) {
this.ManuscirptContent = res.data.list;
this.$refs.commonWordHtmlTypeSetting.getCommentList();
// this.$refs.commonWordHtmlTypeSetting.getCommentList();
}
});
},
@@ -733,26 +752,62 @@ export default {
type: 'warning',
message: 'Please enter the Comment!'
});
return;
}
if (this.commentForm.type == 'user') {
await this.$api
.post(this.urlList.replyComment, {
amc_id: this.commentForm.amc_id,
author_remark: str
})
.then(async (res) => {
if (res.code == 0) {
this.$forceUpdate();
this.commentVisible = false;
this.getDate();
this.getCommentList();
this.$nextTick(() => {});
} else {
this.$message.error(res.msg);
}
})
.catch((err) => {
this.$message.error(err.msg);
});
} else {
var data = {};
if (this.commentForm.amc_id) {
data = {
amc_id: this.commentForm.amc_id,
remark: str
};
} else {
data = {
article_id: this.articleId,
am_id: this.commentForm.am_id,
content: this.commentForm.content,
remark: str
};
}
await this.$api
.post(this.commentForm.amc_id ? this.urlList.editComment : this.urlList.addComment, { ...data })
.then(async (res) => {
if (res.code == 0) {
this.$forceUpdate();
this.commentVisible = false;
this.getDate();
this.getCommentList();
this.$nextTick(() => {});
} else {
this.$message.error(res.msg);
}
})
.catch((err) => {
this.$message.error(err.msg);
});
}
await this.$api
.post(this.urlList.addComment, {
am_id: this.commentForm.am_id,
remark: str
})
.then(async (res) => {
if (res.code == 0) {
this.$forceUpdate();
this.commentVisible = false;
this.getDate();
this.getCommentList();
this.$nextTick(() => {});
} else {
this.$message.error(res.msg);
}
})
.catch((err) => {
this.$message.error(err.msg);
});
},
async onComment(dataId) {
var data = this.Main_List.find((item) => item.am_id == dataId);
@@ -772,18 +827,32 @@ export default {
this.getDate();
this.getCommentList();
},
editComment(comment) {
editComment(comment, type) {
console.log('comment at line 813:', comment);
this.commentForm = {
...comment
...comment,
type: type,
remark: type == 'user' ? comment.author_remark : comment.remark
};
console.log('this.commentForm at line 815:', this.commentForm);
this.commentVisible = true;
},
async onAddComment(data) {
console.log('data at line 858:', data);
var form = this.Main_List.find((item) => item.am_id == data.mainId);
this.commentForm = {
commentLabel: data.label ? data.label : '',
...form
...form,
content: data.label ? data.label : '',
remark: '',
type: 'add',
role: 'editor'
};
this.commentVisible = true;
},
async replyComment(data) {
this.commentForm = {
...data,
remark: data.author_remark,
type: 'user'
};
this.commentVisible = true;
},
@@ -814,6 +883,56 @@ export default {
this.$message.error(err.msg);
});
},
async onAddRow(mainId) {
console.log('data at line 886:', mainId)
await this.$api
.post(this.urlList.addRow, {
am_id: mainId,
article_id: this.articleId
})
.then(async (res) => {
this.getDate();
this.getCommentList();
})
.catch((err) => {
this.$message.error(err.msg);
});
},
async solveComment(data) {
await this.$api
.post(this.urlList.solveComment, {
amc_id: data.amc_id
})
.then(async (res) => {
if (res.code == 0) {
this.getDate();
this.getCommentList();
} else {
this.$message.error(res.msg);
}
})
.catch((err) => {
this.$message.error(err.msg);
});
},
async cancelSolveComment(data) {
await this.$api
.post(this.urlList.cancelSolveComment, {
amc_id: data.amc_id
})
.then(async (res) => {
if (res.code == 0) {
this.getDate();
this.getCommentList();
} else {
this.$message.error(res.msg);
}
})
.catch((err) => {
this.$message.error(err.msg);
});
},
clearButton() {
var deleteButtons = document.querySelectorAll('.wordButtonContainer');
deleteButtons.forEach(function (button) {
@@ -834,10 +953,12 @@ export default {
console.log('data at line 600:', data);
if (type == 'img') {
var extension = data.url.split('.').pop().toLowerCase();
this.picStyle = {};
this.picStyle = { ...data, extension: extension, picUrl: data.url };
this.picStyle.visiTitle = 'Edit Figure';
this.pictVisible = true;
} else if (type == 'table') {
this.lineStyle = {};
this.lineStyle = {
...data,
table: JSON.parse(data.table_data),
@@ -858,6 +979,9 @@ export default {
}
},
onEdit(dataId) {
this.currentContent = {};
this.picStyle = {};
this.lineStyle = {};
this.currentId = null;
this.clearButton();
var data = this.Main_List.find((item) => item.am_id == dataId);
@@ -958,7 +1082,7 @@ export default {
},
getCommentList() {
this.$api
.post('api/Preaccept/getNotes', {
.post('api/Preaccept/getArticleMainCheckList', {
article_id: this.articleId
})
.then((res) => {
@@ -1098,6 +1222,16 @@ export default {
.post(urlLInk, urlTask)
.then(async (res) => {
if (res.code == 0) {
// res.data.list.forEach((data) => {
// if (data.amt_id) {
// try {
// const parsedData = JSON.parse(data.table.table_data);
// } catch (e) {
// console.error(e.message);
// }
// }
// });
this.Main_List = res.data.list;
this.getManuscirptContent();
for (let i = 0; i < this.Main_List.length; i++) {
@@ -1216,7 +1350,12 @@ export default {
if (res.code == 0) {
this.$message.success('Successfully edit Figure!');
this.pictVisible = false;
this.getDate();
this.$nextTick(() => {
this.getDate();
this.getCommentList();
this.$forceUpdate();
});
this.$refs.commonWordHtmlTypeSetting.refresh('img');
} else {
this.$message.error(res.msg);
@@ -1274,8 +1413,11 @@ export default {
if (res.code == 0) {
this.$message.success('Successfully edit Table!');
this.threeVisible = false;
this.getDate();
this.$refs.commonWordHtmlTypeSetting.refresh('table');
setTimeout(() => {
this.getDate();
this.getCommentList();
this.$refs.commonWordHtmlTypeSetting.refresh('table');
});
} else {
this.$message.error(res.msg);
}

View File

@@ -1671,12 +1671,11 @@ export default {
// 6----校对文章
htmlContet() {
this.$router.push({
path: '/GenerateCharts',
window.open(this.$router.resolve({ path: '/GenerateCharts',
query: {
id: this.$route.query.id
}
});
} }).href, '_blank');
},
// 6----修改时间为年月日

View File

@@ -1217,12 +1217,16 @@ export default {
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() {

View File

@@ -0,0 +1,299 @@
<template>
<div style="height: 98%;">
<div class="crumbs">
<el-breadcrumb separator="/">
<el-breadcrumb-item> <i class="el-icon-document-copy"></i> Artcile Html
<el-button size="mini" style="position: absolute;right: 40px;" @click="goEdit">Edit</el-button>
</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div class="container" style="height: 97%; min-width: 1000px; background-color: #fafafa; padding: 10px 0 0 0">
<common-word
:readonly="true"
v-if="htmlContent"
ref="commonWord"
:value="htmlContent"
:wordStyle="wordStyle"
style="width: calc(100%); height: calc(100%); "
:style="`100%`"
></common-word>
</div>
</div>
</template>
<script>
import { mediaUrl } from '@/common/js/commonJS.js'; // 引入通用逻辑
export default {
data() {
return {
wordStyle: `
p {
position: relative;
padding: 8px 15px;
min-height: 22px;
border: 2px dashed #fff;
border-radius: 5px;
color: #606266;
}
p {
font-size: 14px;
line-height: 22px;
}
.imgBox .chNumer {
position: absolute;
top: -2px;
right: -1px;
border-radius: 3px;
font-size: 10px;
background-color: rgb(0 102 153 / 85%);
color: #fff;
padding: 0 6px;
}
.MaxPicture {
text-align: center;
}
.MaxPicture > img {
margin-bottom: 10px;
}
.font {
display: block;
margin: 0 auto;
font-size: 13px;
}
.tableTitle{
text-align:center!important;
font-weight: bold;
}
`,
detailMes: {},
baseUrl: this.Common.baseUrl,
mediaUrl: mediaUrl, //
Art_Id: this.$route.query.id,
Art_Doi: this.$route.query.doi,
Art_web_Id: this.$route.query.artID,
Art_P_Id: '',
btnDisble: true,
detailTitle: '',
htmlContent: '',
Main_List: [],
exegesis: "The following contents'<b></b>,<i></i>'are necessary for the generation phase, please do not delete them!!!"
};
},
created() {
this.getInfo();
},
activated() {
this.getInfo();
},
methods: {
goEdit(){
this.$router.push({
path: '/GenerateCharts',
query: {
id: this.Art_Id
}
});
},
async getInfo() {
const loading = this.$loading({
lock: true,
text: 'Loading...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
// 获取文章信息
await this.$api
.post('api/Production/getProductionDetail', { p_article_id: this.Art_Id })
.then(async (res) => {
if (res.code == 0) {
this.detailTitle = res.data.production.title
this.detailMes = res.data.production;
await this.getDate(loading);
loading.close();
} else {
this.$message.error(res.msg);
loading.close();
}
})
.catch((err) => {
this.$message.error(err);
loading.close();
});
},
getWord() {
var htmlContent = `<h3 class="man_Title" contenteditable="false">${this.detailTitle} </h3>`;
htmlContent += this.Main_List.map((item) => {
//批注
let contentHtml = '';
var isRemark = ``;
// if (item.state == 2 && item.remark && item.remark != '') {
// // isRemark = `<img class="isRemark" main-id="${item.am_id}" src="${this.remarkImageUrl}" alt="" style="width:20px;height:20px;"/>`;
// isRemark = `<span class="isRemark" main-id="${item.am_id}"><img class="isRemarkIcon" main-id="${item.am_id}" src="${this.remarkImageUrl}" alt="" style="width: 20px; height: 20px" />
// <span class="isRemarkIcon" main-id="${item.am_id}" > (${item.am_id})</span>
// </span>
// `;
// }
// 判断是否是图片
if (item.type == 1) {
var extension = item.image.url.split('.').pop().toLowerCase();
if (extension == 'tif') {
contentHtml = `
<p contenteditable="false" main-state="${item.state}" class="MaxPicture pMain" data-id="${item.ami_id}" main-id="${
item.am_id
}">
<img src="" data-img-id="${item.ami_id}" style="width: ${item.width ? `${item.width}px` : '100%'}" />
<font class="font" style="width: ${item.width ? `${item.width}px` : '100%'}">${item.image.note ? item.image.note : ''}</font>
</p>
`;
} else if (['jpg', 'jpeg', 'png'].includes(extension)) {
contentHtml = `
<p contenteditable="false" main-state="${item.state}" class="MaxPicture pMain" data-id="${
item.ami_id
}" main-id="${item.am_id}">
${isRemark}
<img src="${this.mediaUrl + item.image.url}" style="width: ${
item.width ? `${item.width}px` : '100%'
}" />
<font class="font" style="width: ${item.width ? `${item.width}px` : '100%'}" >${
item.image.note ? item.image.note : ''
}</font>
</p>
`;
} else {
contentHtml = `
<p contenteditable="false" main-state="${item.state}" class="MaxPicture pMain" data-id="${
item.ami_id
}" main-id="${item.am_id}">
${isRemark}
<span
style="
text-align: center;
font-size: 30px;
display: flex;
align-items: center;
justify-content: center;
"
>
Figures ( .${item.image.url.split('.').pop().toUpperCase()})
</span>
<font class="font" style="width: ${item.width ? `${item.width}px` : '100%'}" >${
item.image.note ? item.image.note : ''
}</font>
</p>
`;
}
} else if (item.type == 2) {
var tableList = JSON.parse(item.table.table_data);
contentHtml = `
<div contenteditable="false" data-id="${item.amt_id}" main-state="${item.state}" main-id="${
item.am_id
}" class="thumbnailTableBox wordTableHtml table_Box pMain" style="width: 100%; padding: 8px 15px; box-sizing: border-box; border-radius: 4px; position: relative;">
${isRemark}
<font class="font tableTitle" style="width:100%" >${item.table.title ? item.table.title : ''}</font>
<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('')} <!-- join the cells in the row -->
</tr>
`;
})
.join('')} <!-- join the rows -->
</table>
<font class="font" style="width:100%" >${item.table.note ? item.table.note : ''}</font>
</div>
`;
} else {
contentHtml = `<p class="pMain" main-state="${item.state}" contenteditable="false" data-id="${item.am_id}" main-id="${item.am_id}">${isRemark}${item.content}</p>`;
}
// 判断是否是表格类型
return contentHtml;
}).join('');
this.htmlContent = htmlContent;
},
async getDate(loading) {
let urlLInk = '';
let urlTask = {};
if (this.Art_Id != undefined) {
urlLInk = 'api/Preaccept/getArticleMains';
urlTask.article_id = this.detailMes.article_id;
}
// 获取文章信息
await this.$api
.post(urlLInk, urlTask)
.then(async (res) => {
if (res.code == 0) {
this.Main_List = res.data.list;
// this.detailTitle = res.data.production.title
for (let i = 0; i < this.Main_List.length; i++) {
this.Main_List[i].text = this.Main_List[i].content;
this.Main_List[i].getnum = 0;
}
// setTimeout(async () => {
this.$nextTick(async () => {
await this.getWord();
loading.close();
});
loading.close();
} else {
this.$message.error(res.msg);
loading.close();
}
})
.catch((err) => {
this.$message.error(err);
loading.close();
});
}
}
};
</script>
<style scoped>
.man_Title {
background-color: #fff;
margin: 0 0 10px 0;
border-bottom: 1px solid #dde1eb;
box-shadow: 0 5px 5px -2px rgb(134 134 134);
padding: 12px 25px 8px 25px;
font-size: 16px;
line-height: 24px;
color: #333;
position: relative;
}
.man_Title button {
position: absolute;
top: 10px;
right: 10px;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,6 @@
<template>
<div class="tinymce-container editor-container">
<textarea class="tinymce-textarea" :id="tinymceId"></textarea>
</div>
</template>
@@ -110,7 +111,11 @@ const tableStyle = ` b span{
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;
}
`;
export default {
@@ -133,11 +138,9 @@ export default {
},
isEdit: {},
toolbar: {
type: Array,
required: false,
default() {
return [];
}
},
menubar: {
default: 'file edit insert view format table '
@@ -154,6 +157,10 @@ export default {
},
isShowArtWorkButton: {
default: false
},
wordStyle: {
type: String,
default: ''
}
},
data() {
@@ -263,8 +270,9 @@ 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,24 +337,14 @@ export default {
}
},
content_style: `${tableStyle}
.tox-editor-header{
background-color: #f8f9fa!important;
}
.tox-toolbar:nth-child(1) .tox-toolbar__group:nth-child(2) button.tox-tbtn:nth-child(1){
font-weight:bold !important;
color: #007bff; /* 设置字体颜色 */
}
.tox-toolbar:nth-child(1) .tox-toolbar__group:nth-child(2) button.tox-tbtn:nth-child(2){
font-weight:bold !important;
color: #007bff; /* 设置字体颜色 */
text-decoration: line-through;
}
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' },
@@ -359,9 +357,14 @@ export default {
statusbar: false, // 关闭底部状态栏
custom_colors: false,
color_map: ['0082AA', 'TMR Blue'],
plugins: 'forecolor code paste table image', // 启用 forecolor 和 code 插件
plugins: 'forecolor code paste table image mathType', // 启用 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) {
_this.$commonJS.initEditorButton(_this, ed);
@@ -408,30 +411,33 @@ export default {
// 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());
}
});
// 监听子节点和内容的变化
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', {

View File

@@ -948,12 +948,16 @@ export default {
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() {

View File

@@ -1,42 +1,50 @@
<template>
<div>
<div>
<tinymce
ref="tinymceChild"
:value="updatedHtml"
:typesettingType="typesettingType"
class="paste-area text-container"
toolbar=" bold italic | forecolor |subscript superscript|table tabledelete |customButtonExportWord |customButtonExportImg |customDropdown | clearButton"
style="
white-space: pre-line;
line-height: 12px;
max-height: 50vh;
overflow: auto;
font-size: 12px;
font-size: 7.5pt; /* 字体大小 */
<!--uploadWord |customButtonExportWord |customButtonExportImg -->
margin-top: 0pt; /* 段前间距 */
margin-bottom: 0pt; /* 段后间距 */
"
></tinymce>
<tinymce
type="table"
:height="height"
ref="tinymceChild1"
:wordStyle="wordStyle"
:isAutomaticUpdate="isAutomaticUpdate"
@getContent="getContent"
@updateChange="updateChange"
:value="value"
:typesettingType="typesettingType"
class="paste-area text-container"
:toolbar="['bold italic|customBlue removeBlue|subscript superscript|clearButton']"
style="
/* white-space: pre-line; */
line-height: 12px;
max-height: 60vh;
overflow: auto;
font-size: 12px;
font-size: 7.5pt; /* 字体大小 */
margin-top: 0pt; /* 段前间距 */
margin-bottom: 0pt; /* 段后间距 */
"
></tinymce>
</div>
</div>
</template>
<script>
import Tinymce from '@/components/page/components/Tinymce';
export default {
props: ['lineStyle'],
props: ['value','isAutomaticUpdate','height'],
components: {
Tinymce
},
watch: {
lineStyle() {}
},
data() {
return {
tableData: [],
identity: localStorage.getItem('U_role'),
showToolbar: false, // 是否显示工具栏
toolbarStyle: {
top: '0px',
@@ -50,20 +58,30 @@ export default {
{ label: this.$t('commonTable.typesettingType2'), value: 2, pageWidth: 297 }
],
transform: null,
typesettingType: 1
typesettingType: 1,
wordStyle: ``
};
},
mounted() {
this.typesettingType = 1;
if (this.lineStyle) {
console.log('newVal at line 37:', this.lineStyle);
} else {
this.updatedHtml = '';
}
},
methods: {
updateChange(content){
this.$emit('updateChange',content)
},
getTinymceContent(type) {
this.$refs.tinymceChild1.getContent(type);
},
getContent(type, content) {
console.log('content at line 75:', content)
this.$emit('getContent', type, content);
}
}
};
</script>
@@ -111,7 +129,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 +159,5 @@ td input ::placeholder {
overflow-wrap: break-word !important;
}
.text-container {
}
</style>

View File

@@ -6,11 +6,12 @@
<tinymce
type="table"
ref="tinymceChild1"
:wordStyle="wordStyle"
@getContent="getContent"
:value="updatedHtml"
:typesettingType="typesettingType"
class="paste-area text-container"
:toolbar="['bold italic|customBlue removeBlue|subscript superscript|table tabledelete|clearButton']"
:toolbar="['bold italic|customBlue removeBlue|subscript superscript|table tabledelete| mathType |clearButton']"
style="
/* white-space: pre-line; */
line-height: 12px;
@@ -54,7 +55,9 @@ export default {
{ label: this.$t('commonTable.typesettingType2'), value: 2, pageWidth: 297 }
],
transform: null,
typesettingType: 1
typesettingType: 1,
wordStyle: `
`
};
},
mounted() {

File diff suppressed because it is too large Load Diff

View File

@@ -1,875 +0,0 @@
<template>
<div class="tinymce-container editor-container" style="width: 100%; height: 100%; position: relative">
<textarea class="tinymce-textarea" :id="tinymceId"></textarea>
</div>
</template>
<script>
import { string } from 'html-docx-js/dist/html-docx';
import htmlDocx from 'html-docx-js/dist/html-docx.js';
import { Document, Packer, PageOrientation, Paragraph, TextRun } from 'docx'; // 引入 docx.js
import html2canvas from 'html2canvas';
const toolbar = 'addImageButton ';
const tableStyle = `b span{
font-weight: bold !important;
}
i span{
font-style: italic !important; ;
}
sub span{
vertical-align: sub;
}
sup span{
vertical-align: sup;
}
sub {
vertical-align: sub!important;
}
sup {
vertical-align: sup !important;
}
span[style*="vertical-align: super"] {
vertical-align: super !important;
}
span[style*="vertical-align: sub"] {
vertical-align: sub !important;
}
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.5000pt !important;
mso-font-kerning: 1.0000pt !important;
line-height: 10pt !important;
mos-line-height: 10pt !important;
}
table td, table th {
padding: 5px;
text-align:left !important;
white-space: pre-wrap; /* 保留换行符并换行 */
word-wrap: break-word; /* 长单词自动换行 */
word-break: break-word;
font-family:'Charis SIL' !important;
font-size: 7.5000pt !important;
mso-font-kerning: 1.0000pt !important;
line-height: 10pt !important;
mos-line-height: 10pt !important;
}
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; // 设置两端对齐
}
table tr td p{
text-align:left !important;
margin:0;
font-family:'Charis SIL' !important;
font-size: 7.5000pt !important;
mso-font-kerning: 1.0000pt !important;
line-height: 10pt !important;
mos-line-height: 10pt !important;
}
table span{
color:#000000;text-align:left !important;
font-family:'Charis SIL' !important;
font-size: 7.5000pt !important;
mso-font-kerning: 1.0000pt !important;
line-height: 10pt !important;
mos-line-height: 10pt !important;
}
table .color-highlight{
color:rgb(0,130,170) !important;
font-family:'Charis SIL' !important;
font-size: 7.5000pt !important;
mso-font-kerning: 1.0000pt !important;
line-height: 10pt !important;
mos-line-height: 10pt !important;
}
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 {
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;
}
`;
export default {
name: 'tinymce',
components: {},
props: {
id: {
type: String
},
readonly: {
type: Boolean,
default() {
return false;
}
},
value: {
type: String,
default: ''
},
isEdit: {},
toolbar: {
type: Array,
required: false,
default() {
return [];
}
},
menubar: {
default: 'file edit insert view format table '
},
height: {
type: Number,
required: false,
default: 360
},
width: {
type: String,
required: false,
default: '100%'
},
isShowArtWorkButton: {
default: false
},
wordStyle: {
type: String,
default: ''
}
},
data() {
return {
lastTag: null,
isEditComment: false,
typesettingType: 1,
typesettingTypeOptions: [
{
label: this.$t('commonTable.typesettingType1'),
value: 1,
orientation: 'portrait',
pageSize: {
width: 11906,
height: 16976
},
pageMargins: {
top: 1440,
bottom: 1440,
left: 1084,
right: 1084
}
},
// 1 cm = 144 Twip 上边距2.54 cm = 2.54 × 144 = 365.76 Twip
{
label: this.$t('commonTable.typesettingType2'),
value: 2,
orientation: 'landscape',
pageSize: {
width: 16976,
height: 11906
},
pageMargins: {
top: 1440,
bottom: 1440,
left: 1084,
right: 1084
}
}
],
uploadReset: false,
dialogVisible: false,
form: {
name: '',
region: '',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: ''
},
formLabelWidth: '120px',
hasChange: false,
hasInit: false,
tinymceId: this.id || 'vue-tinymce-' + +new Date()
};
},
// this.$nextTick(() => window.tinymce.get(this.tinymceId).setContent(newVal));
watch: {
value(newVal) {
this.$nextTick(() => {
window.tinymce.get(this.tinymceId).setContent(newVal);
this.$emit('loaded');
});
// this.destroyTinymce();
// this.$nextTick(() => {
// this.initTinymce();
// });
}
},
mounted() {
this.isShowEditComment();
this.typesettingType = 1;
this.initTinymce();
},
activated() {
this.isShowEditComment();
this.typesettingType = 1;
this.initTinymce();
},
deactivated() {
this.destroyTinymce();
},
methods: {
isShowEditComment() {
if (localStorage.getItem('U_role')) {
var identity = localStorage.getItem('U_role');
if (identity.includes('editor')) {
this.isEditComment = true;
} else {
this.isEditComment = false;
}
}
},
// 查看评论详情
handleSubmit() {
this.$refs.uploadImage.handleSubmit();
},
getDetail(val) {
if (this.hasInit == true) {
this.$nextTick(() => window.tinymce.get(this.tinymceId).setContent(val));
}
},
//将字符串添加到富文本编辑器中
addArtWork(str) {
window.tinymce.get(this.tinymceId).insertContent(str);
},
onClick(e) {
this.$emit('onClick', e, tinymce);
},
changeTable() {
// 获取所有表格
const tables = window.tinymce.get(this.tinymceId).getBody().querySelectorAll('table');
console.log('tables at line 110:', tables);
// 遍历并设置样式
tables.forEach((table) => {
console.log('table at line 360:', table);
const editor = window.tinymce.get(this.tinymceId);
editor.dom.setStyles(table, {
width: this.typesettingType == 1 ? '17.18cm' : '25.88cm'
});
});
this.$forceUpdate();
},
goToComment(mainId) {
var ed = window.tinymce.get(this.tinymceId);
const editorDoc = ed.getDoc(); // 获取 TinyMCE 内部的 document
console.log('Looking for element with main-id:', mainId); // 调试输出
// 在 iframe 内部的 document 中查找带有 main-id 的元素
const commentElement = editorDoc.querySelector(`[main-id="${mainId}"]`);
if (commentElement) {
commentElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
} else {
console.log('没有找到对应的批注元素', mainId); // 调试输出
}
},
initTinymce() {
var deleteButtons = document.querySelectorAll('.wordButtonContainer');
if (deleteButtons) {
deleteButtons.forEach(function (button) {
button.remove(); // 移除每个 wordButtonContainer 按钮
});
}
let isDeleting = false;
let currentParagraph = null; // 用来存储当前选中的 <p> 元素
let wordButtonContainer = null; // 用来存储删除按钮
const _this = this;
window.tinymce.init({
height: '100%',
resize: true,
readonly: true, // 设置为只读模式
selector: `#${this.tinymceId}`,
content_css: false,
table_resize_bars: true,
valid_elements: '*[*]',
paste_preprocess: function (plugin, args) {
let content = args.content;
const container = document.createElement('div');
container.innerHTML = content;
_this.updateTableStyles(container);
args.content = container.innerHTML;
},
content_style: `${tableStyle + this.wordStyle}.tox .tox-edit-area::before{
border:none;
}
.isRemark {
display:flex;
align-items:center;
position:absolute;
top:-12px;
left:-12px;
z-index:2;
cursor: pointer;
}
.isRemark img{
width:15px;
height:15px;
margin-right:4px;
}
.isRemark span{
background-color: #fef0f0;
border-color: #fde2e2;
padding: 0 5px;
line-height: 19px;
color: #f56c6c;
font-size: 12px;display:inline-block;
}
.isRemark .Resolved{
background-color: #f0f9eb;
margin-left:10px;
border-color: #67c23a;
color:#67c23a;
font-weight:bold;
border-radius:2px;
}
img{
max-width:580px;
}blue {
color: rgb(0, 130, 170) !important;
}
`,
formats: {
bold: { inline: 'b' },
italic: { inline: 'i' }
},
body_class: 'panel-body ',
object_resizing: false,
toolbar: [],
menubar: false,
statusbar: false,
custom_colors: false,
color_map: ['000000', 'Black', '0082AA', 'TMR Blue'],
plugins: 'forecolor code paste table image resize',
end_container_on_empty_block: true,
content_css: 'default ',
setup(ed) {
ed.ui.registry.addButton('customBlue', {
text: 'Blue', // 按钮文本
onAction: function () {
// 在选中的文本周围包裹 <blue> 标签
var selectedText = ed.selection.getContent();
var wrappedText = `<blue>${selectedText}</blue>`;
ed.selection.setContent(wrappedText);
}
});
ed.ui.registry.addButton('removeBlue', {
text: 'Remove Blue', // 按钮文本
onAction: function () {
var content = ed.selection.getContent(); // 获取选中的文本内容
// 如果选中内容中有 <blue> 标签,去掉它们
var cleanedContent = content.replace(/<\/?blue>/g, ''); // 删除所有 <blue> 和 </blue> 标签
// 更新编辑器中的内容
ed.selection.setContent(cleanedContent);
}
});
if (!_this.readonly) {
ed.on('click', function (e) {
// 判断点击的是否是目标元素
const target = e.target;
console.log('target at line 351:', target);
if (target.classList.contains('isRemarkIcon')||target.classList.contains('Resolved')) {
_this.$emit('onComment', target.getAttribute('main-id'));
}
});
// // 添加批注按钮
ed.ui.registry.addButton('addImageButton', {
text: 'Add Figure',
icon: 'comment',
onAction: function () {
_this.$emit('add', img);
// const selection = ed.selection;
// const selectedNode = selection.getNode(); // 获取选中的节点
// console.log('selectedNode at line 333:', selectedNode);
// if (selectedNode) {
// const comment = prompt('Enter your comment:');
// if (comment) {
// const dataId = selectedNode.getAttribute('main-id');
// _this.comments.push({ text: comment, time: new Date().getTime(), mId: dataId });
// }
// } else {
// alert('Please select some text to comment on.');
// }
}
});
ed.on('dragstart', (e) => {
// 阻止拖动事件
e.preventDefault();
});
// 监听焦点变化并高亮当前选中的元素
ed.on('focus', function () {
if (!isDeleting) {
// 处理正常的焦点逻辑
ed.getBody().style.outline = 'none'; // 当编辑器获取焦点时,移除焦点框
_this.updateCurrentTag(ed);
}
});
// 监听焦点变化并高亮当前选中的元素
ed.on('selectionChange', function () {
_this.updateCurrentTag(ed);
});
ed.on('mouseup', function () {
_this.updateCurrentTag(ed);
});
ed.on('blur', function () {
console.log('_this.lastPTag at line 367:', _this.lastTag);
if (_this.lastTag) {
_this.lastTag.style.backgroundColor = ''; // 清除之前的高亮
_this.lastTag.style.border = '';
_this.lastTag = null;
}
if (wordButtonContainer) {
wordButtonContainer.remove();
wordButtonContainer = null;
}
});
ed.on('drop', (event, index) => {
console.log('event at line 375:', event);
const selection = ed.selection;
const selectedNode = selection.getNode(); // 获取选中的节点
console.log('1899', selectedNode); // 查看光标位置的节点类型
// 向上遍历直到找到带有 main-id 属性的节点
const findParentWithMainId = (node) => {
while (node) {
if (node.hasAttribute && node.classList.contains('pMain')) {
return node; // 找到并返回该节点
}
node = node.parentNode; // 向上遍历父节点
}
return null; // 如果没有找到,返回 null
};
// 查找选中节点的父节点,直到找到带有 main-id 属性的节点
const nodeWithMainId = findParentWithMainId(selectedNode);
console.log('at line 395:', nodeWithMainId);
const dataId = nodeWithMainId.getAttribute('main-id');
event.preventDefault();
hideDeleteButton();
// 获取拖动的数据
_this.$emit('onDrop', event, dataId); // 阻止默认的行为
// 在编辑器中插入数据
// const content = <div class="dropped-item">${itemData}</div>;
// ed.insertContent(content); // 插入文本或HTML
});
// 方法:更新当前选中的 p 标签的样式
_this.updateCurrentTag = function (ed) {
var selection = ed.selection;
var node = selection.getNode();
// 向上查找包含的节点直到找到合适的标签
if (node && !node.classList.contains('pMain')) {
node = node.closest('.pMain'); // 向上找到最近的包含 'aa' 类的标签
}
if (node && node.classList.contains('pMain')) {
// 清除上一个高亮的节点样式
if (_this.lastTag && _this.lastTag !== node) {
_this.lastTag.style.backgroundColor = ''; // 清除上一个高亮的标签样式
_this.lastTag.style.border = '';
}
// 设置当前节点的背景色和边框
node.style.backgroundColor = 'rgb(0 102 153 / 10%)';
node.style.border = '2px dashed rgb(0 102 153 / 50%)';
// 更新选中的节点
var currentNode = node;
// 显示删除按钮
showDeleteButton(currentNode);
// 更新 lastTag
_this.lastTag = node;
} else {
// 如果没有找到包含 'aa' 类的节点,隐藏删除按钮
hideDeleteButton();
}
};
function hideDeleteButton() {
if (wordButtonContainer) {
wordButtonContainer.remove(); // 移除删除按钮
wordButtonContainer = null; // 清空按钮引用
}
}
function showDeleteButton(paragraph) {
if (wordButtonContainer) {
wordButtonContainer.remove(); // 如果已有按钮容器,移除
}
// 获取 <p> 标签的位置信息
const paragraphRect = paragraph.getBoundingClientRect();
const iframe = ed.getDoc().defaultView.frameElement;
const iframeRect = iframe.getBoundingClientRect();
var left = 0;
if (_this.isEditComment) {
left = 100;
} else {
left = 80;
}
// 创建按钮容器 div
wordButtonContainer = document.createElement('div');
wordButtonContainer.style.position = 'absolute';
wordButtonContainer.style.top = `${iframeRect.top + paragraphRect.top + window.scrollY - 20}px`; // 确保按钮容器位于 <p> 标签旁边
wordButtonContainer.style.left = `${iframeRect.left + paragraphRect.left + paragraphRect.width - left}px`;
wordButtonContainer.style.zIndex = '9999'; // 设置更高的值
wordButtonContainer.style.display = 'flex'; // 使用 flex 布局将按钮水平排列
wordButtonContainer.style.alignItems = 'center'; // 垂直居中
// 创建删除按钮
const deleteButton = document.createElement('button');
deleteButton.style.backgroundColor = 'red';
deleteButton.style.color = 'white';
deleteButton.style.border = 'none';
deleteButton.style.borderRadius = '50%';
deleteButton.style.padding = '5px';
deleteButton.style.cursor = 'pointer';
deleteButton.style.marginLeft = '10px'; // 给批注按钮添加间距
const deleteIcon = document.createElement('i');
deleteIcon.classList.add('el-icon-delete'); // 使用 Element UI 删除图标
deleteIcon.style.fontSize = '20px';
deleteIcon.style.color = '#fff'; // 设置图标颜色
deleteButton.appendChild(deleteIcon);
deleteButton.addEventListener('mousedown', function (e) {
e.stopImmediatePropagation();
e.preventDefault();
_this.$emit('onDelete', paragraph.getAttribute('main-id'));
});
// 创建批注按钮
const editButton = document.createElement('button');
editButton.style.backgroundColor = 'rgb(19, 188, 32)';
editButton.style.color = 'white';
editButton.style.border = 'none';
editButton.style.borderRadius = '50%';
editButton.style.padding = '5px';
editButton.style.marginLeft = '10px'; // 给批注按钮添加间距
editButton.style.cursor = 'pointer';
const editIcon = document.createElement('i');
editIcon.classList.add('el-icon-edit'); // 使用 Element UI 批注图标
editIcon.style.fontSize = '20px';
editIcon.style.color = '#fff'; // 设置图标颜色
editButton.appendChild(editIcon);
editButton.addEventListener('mousedown', function (e) {
e.stopImmediatePropagation();
e.preventDefault();
// 触发批注事件
_this.$emit('onEdit', paragraph.getAttribute('main-id'));
});
// 将按钮添加到容器中
wordButtonContainer.appendChild(editButton);
wordButtonContainer.appendChild(deleteButton);
if (_this.isEditComment) {
// 创建批注按钮
const commentButton = document.createElement('button');
commentButton.style.backgroundColor = '#2b81ef';
commentButton.style.color = 'white';
commentButton.style.border = 'none';
commentButton.style.borderRadius = '50%';
commentButton.style.padding = '5px';
commentButton.style.marginLeft = '10px'; // 给批注按钮添加间距
commentButton.style.cursor = 'pointer';
const commentIcon = document.createElement('i');
commentIcon.classList.add('el-icon-chat-dot-square'); // 使用 Element UI 批注图标
commentIcon.style.fontSize = '20px';
commentIcon.style.color = '#fff'; // 设置图标颜色
commentButton.appendChild(commentIcon);
commentButton.addEventListener('mousedown', function (e) {
e.stopImmediatePropagation();
e.preventDefault();
// 触发批注事件
_this.$emit('onAddComment', paragraph.getAttribute('main-id'));
if (wordButtonContainer) {
wordButtonContainer.remove(); // 移除删除按钮
wordButtonContainer = null; // 清空按钮引用
}
});
wordButtonContainer.appendChild(commentButton);
}
wordButtonContainer.classList.add('wordButtonContainer'); // 给按钮
// 将容器添加到页面中
document.body.appendChild(wordButtonContainer);
}
ed.on('mousedown', function (e) {
// 检查点击的位置是否是删除按钮或选中的 <p> 标签
if (!currentParagraph || (e.target !== wordButtonContainer && !currentParagraph.contains(e.target))) {
if (wordButtonContainer) {
wordButtonContainer.remove(); // 移除删除按钮
wordButtonContainer = null; // 清空按钮引用
}
}
});
}
},
init_instance_callback: (editor) => {
if (_this.value) {
editor.setContent(_this.value);
_this.$emit('loaded');
}
_this.hasInit = true;
editor.on('NodeChange Change KeyUp SetContent', () => {
this.hasChange = true;
this.$emit('input', editor.getContent());
});
const iframeDocument = editor.getDoc(); // 使用 ed.getDoc() 获取编辑器的 document
if (iframeDocument) {
iframeDocument.addEventListener('scroll', function () {
if (wordButtonContainer) {
wordButtonContainer.remove();
wordButtonContainer = null;
}
if (_this.lastTag) {
_this.lastTag.style.backgroundColor = ''; // 清除上一个高亮的标签样式
_this.lastTag.style.border = '';
}
});
}
}
});
},
// 显示选中的批注内容
viewCommentDetail(comment) {
this.selectedComment = comment.text;
},
// 关闭批注详情
closeCommentDetails() {
this.selectedComment = null;
},
replacePlaceholderImage(ami_id, realImgSrc) {
console.log('realImgSrc at line 638:', ami_id, realImgSrc);
const iframeDocument = window.tinymce.get(this.tinymceId).getDoc();
console.log('iframeDocument at line 639:', iframeDocument);
const placeholderImg = iframeDocument.querySelector(`img[data-img-id="${ami_id}"]`);
console.log('placeholderImg at line 640:', placeholderImg);
if (placeholderImg) {
placeholderImg.src = realImgSrc; // 替换图片 URL
placeholderImg.removeAttribute('data-img-id'); // 删除标识属性
}
},
// 提取 Word 文件中的表格
updateTableStyles(container) {
var html = this.$commonJS.updateTableStyles(container, this.typesettingType);
var editor = window.tinymce.activeEditor; // 将外部 DOM 内容更新到编辑器
const container1 = document.createElement('div');
container1.innerHTML = html; // html 是更新后的 HTML 内容
editor.setContent(container1.innerHTML); // 更新编辑器内容
editor.focus(); // 聚焦到编辑器// 触发编辑器内容变化后,如果需要,可能还要设置编辑器的样式
},
//销毁富文本
destroyTinymce() {
if (window.tinymce.get(this.tinymceId)) {
window.tinymce.get(this.tinymceId).destroy();
}
},
//设置内容
setContent(value) {
window.tinymce.get(this.tinymceId).setContent(value);
},
//获取内容
getContent(type) {
this.$emit('getContent', type, window.tinymce.get(this.tinymceId).getContent());
},
async export(type, data) {
if (type == 'table') {
var tableHtml = `<html xmlns:w="urn:schemas-microsoft-com:office:word">
<head>
<style>
${tableStyle}
</style>
</head>
<body>
${data}
</body>
</html>`;
const converted = htmlDocx.asBlob(tableHtml, {
orientation: this.typesettingTypeOptions[this.typesettingType - 1].orientation,
pageSize: {
...this.typesettingTypeOptions[this.typesettingType - 1].pageSize
},
pageMargins: {
...this.typesettingTypeOptions[this.typesettingType - 1].pageMargins
}
});
// const converted = htmlDocx.asBlob(tableHtml); // 将 HTML 转换为 Word Blob
// 触发文件下载
const link = document.createElement('a');
link.href = URL.createObjectURL(converted);
link.download = 'table.docx';
link.click();
} else if (type == 'image') {
const hiddenContainer = document.createElement('div');
hiddenContainer.style.position = 'absolute';
hiddenContainer.style.left = '-9999ppx';
hiddenContainer.style.top = '0';
hiddenContainer.innerHTML = data;
const style = document.createElement('style');
style.innerHTML = `${tableStyle}`;
document.head.appendChild(style);
document.body.appendChild(hiddenContainer);
// 使用 html2canvas 捕获表格内容
const table = hiddenContainer.querySelector('table'); // 找到表格
table.style.border = 'none';
// 使用 html2canvas 将内容转为图片
html2canvas(hiddenContainer, {
scale: 2, // 提高图片的分辨率默认为1设置为2可以使图片更清晰
logging: false, // 禁用日志输出
useCORS: true, // 允许跨域图像
allowTaint: true // 允许污染 canvas解决图片链接不可用问题
})
// 清空现有内容,显示图片
.then((canvas) => {
const imgData = canvas.toDataURL('image/png'); // 创建一个图片对象
const link = document.createElement('a'); // 创建一个链接并下载图片
link.href = imgData;
link.download = 'image.png';
link.click();
});
}
},
inlineStyles(element) {
const styles = window.getComputedStyle(element);
for (let style in styles) {
if (styles.hasOwnProperty(style)) {
element.style[style] = styles[style];
}
}
},
//获取上传图片后的地址,并设置图片样式
tableSuccessCBK(arr) {
console.log(arr, '222');
const _this = this;
window.tinymce.get(_this.tinymceId).insertContent(arr);
}
},
destroyed() {
this.destroyTinymce();
}
};
</script>
<style scoped>
::v-deep .tox-tinymce-aux {
z-index: 9999 !important;
}
::v-deep .tox .tox-menu {
z-index: 9999 !important;
}
/* 自定义按钮样式 */
.custom-btn {
background-color: #28a745 !important;
color: #fff !important;
border-radius: 4px;
padding: 5px 10px;
font-weight: bold;
}
.custom-btn:hover {
background-color: #218838 !important;
}
/* 批注的样式 */
.comment {
position: relative;
background-color: #ffeb3b;
color: black;
padding: 2px 5px;
border-radius: 5px;
cursor: pointer;
display: inline-block;
}
.comment::after {
content: attr(title);
position: absolute;
top: -20px;
left: 0;
background-color: #f1f1f1;
padding: 5px;
border-radius: 5px;
font-size: 12px;
display: none;
white-space: nowrap;
max-width: 150px;
word-wrap: break-word;
}
.comment:hover::after {
display: block;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -310,21 +310,12 @@
</li>
<li v-show="currentMenu == 2">
<div style="" class="go-content-charts-item-box">
<div
class="item_box"
@click="addTable"
style="width: 100%; height: auto; position: relative"
>
<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>Add Table </span>
</div>
<div
class="thumbnailBox image list-img"
:style="`
@@ -335,8 +326,8 @@
border-radius: 4px;
overflow: hidden;
position: relative;`"
>
<div style="width: 100%; height: 80px; display: flex; justify-content: center; align-items: center">
>
<div 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>
@@ -661,11 +652,11 @@ export default {
handleSelectMenu(v) {
this.currentMenu = v;
this.currentSelectType = '0';
if (v == 1) {
this.getCommentList();
} else {
this.filterData();
}
// if (v == 1) {
// this.getCommentList();
// } else {
this.filterData();
// }
},
selectType(v) {
this.currentSelectType = v.type;
@@ -756,7 +747,6 @@ export default {
});
},
onDragStart($event, item, index, type) {
this.$emit('onDragStart', $event, item, index, type);
},
changeActiveNames(e) {
@@ -854,10 +844,12 @@ export default {
text-align: center;
table-layout: auto;"
>`;
table.table.forEach((row) => {
modalContent += `<tr>`;
row.forEach((cell) => {
modalContent += `
if (table.table&&table.table.length > 0) {
table.table.forEach((row) => {
modalContent += `<tr>`;
row.forEach((cell) => {
modalContent += `
<td
colspan="${cell.colspan || 1}"
rowspan="${cell.rowspan || 1}"
@@ -865,9 +857,11 @@ export default {
>
<span>${cell.text}</span>
</td>`;
});
modalContent += `</tr>`;
});
modalContent += `</tr>`;
});
}
modalContent += `</table></div>`;
this.$commonJS.createImageModal(index, modalContent, 'table', '');
});