提交
This commit is contained in:
@@ -42,7 +42,7 @@ export default {
|
||||
str = capitalizeFirstLetter(str);
|
||||
|
||||
// 添加蓝色标签
|
||||
const regex = /\[\d+(?:,\d+)*\]/g;
|
||||
const regex = /\[(\d+(?:–\d+)?(?:,\d+(?:–\d+)?)*)\]/g;;
|
||||
if (regex.test(str)) {
|
||||
str = `<blue>${str}</blue>`;
|
||||
}
|
||||
|
||||
@@ -123,6 +123,10 @@
|
||||
};
|
||||
},
|
||||
created() {
|
||||
if(this.$route.meta.hideSidebar){
|
||||
this.collapse=false
|
||||
|
||||
}
|
||||
this.initORCID();
|
||||
if (this.user_id == 24) {
|
||||
this.daojishi = '2021.9.3 - 2021.9.30'
|
||||
@@ -272,6 +276,7 @@
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
|
||||
if (document.body.clientWidth < 1000) {
|
||||
this.collapseChage();
|
||||
}
|
||||
|
||||
@@ -34,6 +34,10 @@ export default {
|
||||
vTags
|
||||
},
|
||||
created() {
|
||||
if(this.$route.meta.hideSidebar){
|
||||
this.collapse=false
|
||||
|
||||
}
|
||||
bus.$on('collapse-content', (msg) => {
|
||||
this.collapse = msg;
|
||||
localStorage.setItem('collapse', this.collapse);
|
||||
|
||||
@@ -636,6 +636,10 @@ export default {
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if(this.$route.meta.hideSidebar){
|
||||
this.collapse=false
|
||||
|
||||
}
|
||||
localStorage.setItem('collapse', this.collapse);
|
||||
if (this.userrole == 2) {
|
||||
//其余的身份(显示作者)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div style="height: 98%">
|
||||
<div class="crumbs">
|
||||
<!-- <div class="crumbs">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item> <i class="el-icon-document-copy"></i> HTML Proofread </el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<div
|
||||
class="container"
|
||||
@@ -99,6 +99,7 @@
|
||||
v-if="htmlContent"
|
||||
ref="commonWord"
|
||||
:value="htmlContent"
|
||||
:contentList="Main_List"
|
||||
:wordStyle="wordStyle"
|
||||
@onDrop="onDrop"
|
||||
@loaded="loadedWord"
|
||||
@@ -281,6 +282,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import bus from '@/components/common/bus';
|
||||
import { del, isShallow } from 'vue';
|
||||
import Tiff from 'tiff.js';
|
||||
import { mediaUrl } from '@/common/js/commonJS.js'; // 引入通用逻辑
|
||||
@@ -314,18 +316,18 @@ export default {
|
||||
editTable: 'api/Preaccept/editMainTable'
|
||||
},
|
||||
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;
|
||||
}
|
||||
// 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;
|
||||
@@ -420,6 +422,11 @@ export default {
|
||||
}
|
||||
},
|
||||
created() {
|
||||
bus.$on('collapse', (msg) => {
|
||||
this.collapse = msg;
|
||||
localStorage.setItem('collapse', this.collapse);
|
||||
bus.$emit('collapse-content', msg);
|
||||
});
|
||||
this.getDate();
|
||||
// this.loadDictionary().catch(console.error);
|
||||
},
|
||||
@@ -1421,7 +1428,7 @@ export default {
|
||||
position: relative;
|
||||
padding: 8px 15px;
|
||||
min-height: 22px;
|
||||
border: 2px dashed #fff;
|
||||
border: 2px dashed red;
|
||||
border-radius: 5px;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ const tableStyle = ` b span{
|
||||
table tr:first-child td {
|
||||
border-top:1.0000pt solid #000 !important;mso-border-top-alt:0.5000pt solid #000 !important;border-bottom:1.0000pt solid #000 !important;mso-border-bottom-alt:0.5000pt solid #000 !important;
|
||||
}
|
||||
table tr:last-of-type td {
|
||||
table tr:last-of-type {
|
||||
border-bottom:1.0000pt solid #000 !important;mso-border-bottom-alt:0.5000pt solid #000 !important;;
|
||||
}
|
||||
|
||||
|
||||
875
src/components/page/components/table/word copy.vue
Normal file
875
src/components/page/components/table/word copy.vue
Normal file
@@ -0,0 +1,875 @@
|
||||
<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
@@ -988,7 +988,8 @@ export default new Router({
|
||||
path: '/GenerateCharts', //用户端预收录-引用编辑
|
||||
component: () => import('../components/page/GenerateCharts'),
|
||||
meta: {
|
||||
title: 'HTML Proofread'
|
||||
title: 'HTML Proofread',
|
||||
hideSidebar: true
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user