自动化
@@ -1071,3 +1071,108 @@ a {
|
||||
color: #fff !important;
|
||||
line-height: 24px;
|
||||
} */
|
||||
|
||||
.wordTableHtml b span {
|
||||
font-weight: bold !important;
|
||||
}
|
||||
.wordTableHtml i span {
|
||||
font-style: italic !important;
|
||||
}
|
||||
.wordTableHtml sub span {
|
||||
vertical-align: sub;
|
||||
}
|
||||
.wordTableHtml sup span {
|
||||
vertical-align: super;
|
||||
}
|
||||
.wordTableHtml sub {
|
||||
vertical-align: sub !important;
|
||||
}
|
||||
.wordTableHtml sup {
|
||||
vertical-align: super !important;
|
||||
}
|
||||
.wordTableHtml span[style*='vertical-align: super'] {
|
||||
vertical-align: super !important;
|
||||
}
|
||||
.wordTableHtml span[style*='vertical-align: sub'] {
|
||||
vertical-align: sub !important;
|
||||
}
|
||||
.wordTableHtml table {
|
||||
border: 0px !important;
|
||||
border-collapse: collapse; /* 去除单元格间隙 */
|
||||
width: auto;
|
||||
margin: 0 auto !important;
|
||||
table-layout: auto; /* 自动调整列宽 */
|
||||
text-align: left;
|
||||
font-family: 'Charis SIL' !important;
|
||||
font-size: 7.5pt !important;
|
||||
mso-font-kerning: 1pt !important;
|
||||
line-height: 10pt !important;
|
||||
mos-line-height: 10pt !important;
|
||||
}
|
||||
.wordTableHtml table td,
|
||||
.wordTableHtml table th{
|
||||
padding: 5px;
|
||||
text-align: left !important;
|
||||
|
||||
word-wrap: break-word; /* 长单词自动换行 */
|
||||
word-break: break-word;
|
||||
font-family: 'Charis SIL' !important;
|
||||
font-size: 7.5pt !important;
|
||||
mso-font-kerning: 1pt !important;
|
||||
line-height: 10pt !important;
|
||||
mos-line-height: 10pt !important;
|
||||
}
|
||||
.wordTableHtml table 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; */
|
||||
}
|
||||
.wordTableHtml table tr td p {
|
||||
display: flex;
|
||||
text-align: left !important;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
font-family: 'Charis SIL' !important;
|
||||
font-size: 7.5pt !important;
|
||||
mso-font-kerning: 1pt !important;
|
||||
line-height: 10pt !important;
|
||||
mos-line-height: 10pt !important;
|
||||
}
|
||||
.wordTableHtml table span {
|
||||
color: #000000;
|
||||
text-align: left !important;
|
||||
font-family: 'Charis SIL' !important;
|
||||
font-size: 7.5pt !important;
|
||||
mso-font-kerning: 1pt !important;
|
||||
line-height: 10pt !important;
|
||||
mos-line-height: 10pt !important;
|
||||
}
|
||||
.wordTableHtml table .color-highlight {
|
||||
color: rgb(0, 130, 170) !important;
|
||||
font-family: 'Charis SIL' !important;
|
||||
font-size: 7.5pt !important;
|
||||
mso-font-kerning: 1pt !important;
|
||||
line-height: 10pt !important;
|
||||
mos-line-height: 10pt !important;
|
||||
}
|
||||
.wordTableHtml table tr:first-child td {
|
||||
border-top: 1px solid #000 !important;
|
||||
|
||||
border-bottom: 1px solid #000 !important;
|
||||
|
||||
}
|
||||
.wordTableHtml table tr:last-of-type td {
|
||||
border-bottom: 1px solid #000 !important;
|
||||
|
||||
}
|
||||
BIN
src/assets/img/htmlLayout.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
src/assets/img/huifu.png
Normal file
|
After Width: | Height: | Size: 627 B |
BIN
src/assets/img/isRemark.png
Normal file
|
After Width: | Height: | Size: 583 B |
BIN
src/assets/img/pizhu.png
Normal file
|
After Width: | Height: | Size: 850 B |
BIN
src/assets/img/upload.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
src/assets/img/uploadTable.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
src/assets/img/wordImgBg.png
Normal file
|
After Width: | Height: | Size: 136 KiB |
205
src/common/dictionaries/en_US.aff
Normal file
@@ -0,0 +1,205 @@
|
||||
SET UTF-8
|
||||
TRY esianrtolcdugmphbyfvkwzESIANRTOLCDUGMPHBYFVKWZ'
|
||||
ICONV 1
|
||||
ICONV ’ '
|
||||
NOSUGGEST !
|
||||
|
||||
# ordinal numbers
|
||||
COMPOUNDMIN 1
|
||||
# only in compounds: 1th, 2th, 3th
|
||||
ONLYINCOMPOUND c
|
||||
# compound rules:
|
||||
# 1. [0-9]*1[0-9]th (10th, 11th, 12th, 56714th, etc.)
|
||||
# 2. [0-9]*[02-9](1st|2nd|3rd|[4-9]th) (21st, 22nd, 123rd, 1234th, etc.)
|
||||
COMPOUNDRULE 2
|
||||
COMPOUNDRULE n*1t
|
||||
COMPOUNDRULE n*mp
|
||||
WORDCHARS 0123456789’
|
||||
|
||||
PFX A Y 1
|
||||
PFX A 0 re .
|
||||
|
||||
PFX I Y 1
|
||||
PFX I 0 in .
|
||||
|
||||
PFX U Y 1
|
||||
PFX U 0 un .
|
||||
|
||||
PFX C Y 1
|
||||
PFX C 0 de .
|
||||
|
||||
PFX E Y 1
|
||||
PFX E 0 dis .
|
||||
|
||||
PFX F Y 1
|
||||
PFX F 0 con .
|
||||
|
||||
PFX K Y 1
|
||||
PFX K 0 pro .
|
||||
|
||||
SFX V N 2
|
||||
SFX V e ive e
|
||||
SFX V 0 ive [^e]
|
||||
|
||||
SFX N Y 3
|
||||
SFX N e ion e
|
||||
SFX N y ication y
|
||||
SFX N 0 en [^ey]
|
||||
|
||||
SFX X Y 3
|
||||
SFX X e ions e
|
||||
SFX X y ications y
|
||||
SFX X 0 ens [^ey]
|
||||
|
||||
SFX H N 2
|
||||
SFX H y ieth y
|
||||
SFX H 0 th [^y]
|
||||
|
||||
SFX Y Y 1
|
||||
SFX Y 0 ly .
|
||||
|
||||
SFX G Y 2
|
||||
SFX G e ing e
|
||||
SFX G 0 ing [^e]
|
||||
|
||||
SFX J Y 2
|
||||
SFX J e ings e
|
||||
SFX J 0 ings [^e]
|
||||
|
||||
SFX D Y 4
|
||||
SFX D 0 d e
|
||||
SFX D y ied [^aeiou]y
|
||||
SFX D 0 ed [^ey]
|
||||
SFX D 0 ed [aeiou]y
|
||||
|
||||
SFX T N 4
|
||||
SFX T 0 st e
|
||||
SFX T y iest [^aeiou]y
|
||||
SFX T 0 est [aeiou]y
|
||||
SFX T 0 est [^ey]
|
||||
|
||||
SFX R Y 4
|
||||
SFX R 0 r e
|
||||
SFX R y ier [^aeiou]y
|
||||
SFX R 0 er [aeiou]y
|
||||
SFX R 0 er [^ey]
|
||||
|
||||
SFX Z Y 4
|
||||
SFX Z 0 rs e
|
||||
SFX Z y iers [^aeiou]y
|
||||
SFX Z 0 ers [aeiou]y
|
||||
SFX Z 0 ers [^ey]
|
||||
|
||||
SFX S Y 4
|
||||
SFX S y ies [^aeiou]y
|
||||
SFX S 0 s [aeiou]y
|
||||
SFX S 0 es [sxzh]
|
||||
SFX S 0 s [^sxzhy]
|
||||
|
||||
SFX P Y 3
|
||||
SFX P y iness [^aeiou]y
|
||||
SFX P 0 ness [aeiou]y
|
||||
SFX P 0 ness [^y]
|
||||
|
||||
SFX M Y 1
|
||||
SFX M 0 's .
|
||||
|
||||
SFX B Y 3
|
||||
SFX B 0 able [^aeiou]
|
||||
SFX B 0 able ee
|
||||
SFX B e able [^aeiou]e
|
||||
|
||||
SFX L Y 1
|
||||
SFX L 0 ment .
|
||||
|
||||
REP 90
|
||||
REP a ei
|
||||
REP ei a
|
||||
REP a ey
|
||||
REP ey a
|
||||
REP ai ie
|
||||
REP ie ai
|
||||
REP alot a_lot
|
||||
REP are air
|
||||
REP are ear
|
||||
REP are eir
|
||||
REP air are
|
||||
REP air ere
|
||||
REP ere air
|
||||
REP ere ear
|
||||
REP ere eir
|
||||
REP ear are
|
||||
REP ear air
|
||||
REP ear ere
|
||||
REP eir are
|
||||
REP eir ere
|
||||
REP ch te
|
||||
REP te ch
|
||||
REP ch ti
|
||||
REP ti ch
|
||||
REP ch tu
|
||||
REP tu ch
|
||||
REP ch s
|
||||
REP s ch
|
||||
REP ch k
|
||||
REP k ch
|
||||
REP f ph
|
||||
REP ph f
|
||||
REP gh f
|
||||
REP f gh
|
||||
REP i igh
|
||||
REP igh i
|
||||
REP i uy
|
||||
REP uy i
|
||||
REP i ee
|
||||
REP ee i
|
||||
REP j di
|
||||
REP di j
|
||||
REP j gg
|
||||
REP gg j
|
||||
REP j ge
|
||||
REP ge j
|
||||
REP s ti
|
||||
REP ti s
|
||||
REP s ci
|
||||
REP ci s
|
||||
REP k cc
|
||||
REP cc k
|
||||
REP k qu
|
||||
REP qu k
|
||||
REP kw qu
|
||||
REP o eau
|
||||
REP eau o
|
||||
REP o ew
|
||||
REP ew o
|
||||
REP oo ew
|
||||
REP ew oo
|
||||
REP ew ui
|
||||
REP ui ew
|
||||
REP oo ui
|
||||
REP ui oo
|
||||
REP ew u
|
||||
REP u ew
|
||||
REP oo u
|
||||
REP u oo
|
||||
REP u oe
|
||||
REP oe u
|
||||
REP u ieu
|
||||
REP ieu u
|
||||
REP ue ew
|
||||
REP ew ue
|
||||
REP uff ough
|
||||
REP oo ieu
|
||||
REP ieu oo
|
||||
REP ier ear
|
||||
REP ear ier
|
||||
REP ear air
|
||||
REP air ear
|
||||
REP w qu
|
||||
REP qu w
|
||||
REP z ss
|
||||
REP ss z
|
||||
REP shun tion
|
||||
REP shun sion
|
||||
REP shun cion
|
||||
REP size cise
|
||||
49569
src/common/dictionaries/en_US.dic
Normal file
@@ -2,8 +2,12 @@
|
||||
//记得切换
|
||||
|
||||
//正式
|
||||
const mediaUrl = '/public/';
|
||||
const baseUrl = '/';
|
||||
// const mediaUrl = '/public/';
|
||||
// const baseUrl = '/api';
|
||||
|
||||
|
||||
const mediaUrl = 'https://submission.tmrjournals.com/public/';
|
||||
const baseUrl = '/api';
|
||||
|
||||
|
||||
//本地(正式环境 )
|
||||
|
||||
@@ -354,6 +354,9 @@ const en = {
|
||||
},
|
||||
commonTable: {
|
||||
add: 'Add',
|
||||
preview: 'Preview',
|
||||
link: 'Positioning',
|
||||
Typed: 'Typed',
|
||||
edit: 'Edit',
|
||||
rows: 'rows',
|
||||
columns: 'columns',
|
||||
@@ -361,9 +364,15 @@ const en = {
|
||||
headerPlaceholder: 'Fill in the header',
|
||||
typesettingType2: 'Horizontal A4',
|
||||
typesettingType1: 'Vertical A4',
|
||||
AnnotationList: 'Annotation List',
|
||||
Annotations: 'Annotations',
|
||||
exportWord: 'Export Word',
|
||||
exportImg: 'Export PNG',
|
||||
PaperRotation: 'Paper Rotation',
|
||||
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!'
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
@@ -347,16 +347,25 @@ const zh = {
|
||||
},
|
||||
commonTable: {
|
||||
add: '新增',
|
||||
preview: '预览',
|
||||
positioning: '定位',
|
||||
edit: '编辑',
|
||||
Typed: '已排版',
|
||||
rows: '行',
|
||||
columns: '列',
|
||||
table: '表格',
|
||||
headerPlaceholder: '填写表头',
|
||||
typesettingType2: '横向 A4',
|
||||
typesettingType1: '竖向 A4',
|
||||
AnnotationList: '批注列表',
|
||||
Annotations: '批注',
|
||||
exportWord: '导出 Word',
|
||||
exportImg: '导出 图片',
|
||||
PaperRotation: '纸张方向',
|
||||
removeAnnotations:'确定要删除这条批注吗?',
|
||||
removeContent:'确定要删除这条内容吗?',
|
||||
reContent:'确定要恢复这条内容吗?',
|
||||
uploadImageInfo:'Figures 只能上传 JPG、JPEG 和 PNG 格式的文件'
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<span v-else class="el-icon-pie-chart notPass status"> Pending</span>
|
||||
</h5>
|
||||
<div class="con">
|
||||
<h4>Generate charts </h4>
|
||||
<h4>HTML Proofread </h4>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,971 +0,0 @@
|
||||
<template>
|
||||
<div style="height: 98%">
|
||||
<div class="crumbs">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item> <i class="el-icon-document-copy"></i> Generate Charts </el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<div
|
||||
class="container"
|
||||
style="height: 97%; min-width: calc(1000px - 300px); width: calc(100% - 300px); background-color: #fafafa; padding: 10px 0 0 0"
|
||||
>
|
||||
<h3 class="man_Title">
|
||||
{{ detailTitle }}
|
||||
</h3>
|
||||
<div class="type_MTxt" style="box-sizing: border-box">
|
||||
<div
|
||||
v-for="(item, index) in Main_List"
|
||||
@dragover.prevent
|
||||
:class="item.p_main_img_id ? 'imgBox' : ''"
|
||||
@drop="onDrop($event, index)"
|
||||
>
|
||||
<p v-html="item.text" v-if="!item.p_main_img_id"></p>
|
||||
<p v-if="item.p_main_img_id" class="MaxPicture">
|
||||
<img :src="baseUrl + 'public/mainimg/' + item.content" :style="'width:' + item.width + 'px'" />
|
||||
<font :style="'width:' + item.width + 'px'">{{ item.note }} </font>
|
||||
</p>
|
||||
<font v-if="item.getnum != 0" class="chNumer">{{ item.getnum }}</font>
|
||||
<b
|
||||
class="MaxBtn"
|
||||
@click="MTxtEdit(item, index)"
|
||||
style="background-color: #006699; right: 40px"
|
||||
v-if="item.p_main_img_id"
|
||||
>
|
||||
<i class="el-icon-edit"></i>
|
||||
</b>
|
||||
<!-- <b class="MaxBtn" @click="MTxtPic(item, index)" style="background-color: #13bc20; right: 40px">
|
||||
<svg
|
||||
t="1684978324047"
|
||||
class="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="1967"
|
||||
width="15"
|
||||
height="15"
|
||||
>
|
||||
<path
|
||||
d="M512 46.208a42.666667 42.666667 0 0 1 4.992 85.077333L512 131.541333H174.208a42.666667 42.666667 0 0 0-42.368 37.717334l-0.298667 4.949333v487.850667L307.2 501.12a88.874667 88.874667 0 0 1 112.042667-6.570667l5.845333 4.608 150.442667 128.896 101.973333-101.888a88.874667 88.874667 0 0 1 110.122667-12.373333l6.058666 4.138667 104.832 78.592V512a42.666667 42.666667 0 0 1 85.077334-4.992l0.298666 4.992v342.698667a128 128 0 0 1-120.490666 127.786666l-7.509334 0.213334H174.208a128 128 0 0 1-127.786667-120.490667l-0.213333-7.509333V174.208a128 128 0 0 1 120.490667-127.786667l7.509333-0.213333H512zM366.378667 563.2l-1.536 0.853333-233.301334 213.76v76.885334a42.666667 42.666667 0 0 0 37.717334 42.368l4.949333 0.298666H855.893333a42.666667 42.666667 0 0 0 42.368-37.717333l0.298667-4.949333v-151.808l-3.285333-2.090667-152.789334-114.602667a3.541333 3.541333 0 0 0-3.2-0.554666l-1.450666 0.853333-97.28 97.28 76.970666 66.048a42.666667 42.666667 0 0 1-51.2 68.010667l-4.309333-3.2-292.437333-250.666667a3.541333 3.541333 0 0 0-3.2-0.768z m415.829333-516.992a42.666667 42.666667 0 0 1 42.410667 37.717333l0.256 4.949334v96h96a42.666667 42.666667 0 0 1 4.992 85.077333l-4.992 0.256h-96v96a42.666667 42.666667 0 0 1-85.034667 4.992l-0.298667-4.992v-96h-96a42.666667 42.666667 0 0 1-4.949333-85.034667l4.949333-0.298666h96v-96a42.666667 42.666667 0 0 1 42.666667-42.666667z"
|
||||
fill="#ffffff"
|
||||
p-id="1968"
|
||||
></path>
|
||||
</svg>
|
||||
</b> -->
|
||||
<!-- <b class="MaxBtn" @click="MTxtTable(item, index)" style="background-color: #e07404; right: 0px">
|
||||
<i class="el-icon-document-add"></i>
|
||||
</b> -->
|
||||
<b
|
||||
class="MaxBtn"
|
||||
@click="MTxtDelet(item, index)"
|
||||
style="background-color: #bc1a13; right: 0px"
|
||||
v-if="item.p_main_img_id"
|
||||
>
|
||||
<i class="el-icon-delete"></i>
|
||||
</b>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="height: 20px" v-if="Art_Doi == undefined"></div>
|
||||
<div style="margin: 20px 0 0 0; text-align: center; padding-bottom: 30px" v-if="Art_Doi != undefined">
|
||||
<el-button icon="el-icon-finished" type="primary" style="width: 350px" @click="pushOnline()"> Push Online </el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="right-side"
|
||||
style="
|
||||
width: 300px;
|
||||
position: fixed;
|
||||
right: 20px;
|
||||
top: 17vh;
|
||||
bottom: 10px;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 1px 3px rgb(16 17 19 / 6%);
|
||||
border-radius: 4px;
|
||||
"
|
||||
>
|
||||
<p style="padding: 10px 10px; box-sizing: border-box; font-weight: bold">
|
||||
Unfettered area
|
||||
<b class="MaxBtn" @click="MTxtPic()" style="background-color: #13bc20; right: 40px; top: 5px">
|
||||
<svg
|
||||
t="1684978324047"
|
||||
class="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="1967"
|
||||
width="15"
|
||||
height="15"
|
||||
>
|
||||
<path
|
||||
d="M512 46.208a42.666667 42.666667 0 0 1 4.992 85.077333L512 131.541333H174.208a42.666667 42.666667 0 0 0-42.368 37.717334l-0.298667 4.949333v487.850667L307.2 501.12a88.874667 88.874667 0 0 1 112.042667-6.570667l5.845333 4.608 150.442667 128.896 101.973333-101.888a88.874667 88.874667 0 0 1 110.122667-12.373333l6.058666 4.138667 104.832 78.592V512a42.666667 42.666667 0 0 1 85.077334-4.992l0.298666 4.992v342.698667a128 128 0 0 1-120.490666 127.786666l-7.509334 0.213334H174.208a128 128 0 0 1-127.786667-120.490667l-0.213333-7.509333V174.208a128 128 0 0 1 120.490667-127.786667l7.509333-0.213333H512zM366.378667 563.2l-1.536 0.853333-233.301334 213.76v76.885334a42.666667 42.666667 0 0 0 37.717334 42.368l4.949333 0.298666H855.893333a42.666667 42.666667 0 0 0 42.368-37.717333l0.298667-4.949333v-151.808l-3.285333-2.090667-152.789334-114.602667a3.541333 3.541333 0 0 0-3.2-0.554666l-1.450666 0.853333-97.28 97.28 76.970666 66.048a42.666667 42.666667 0 0 1-51.2 68.010667l-4.309333-3.2-292.437333-250.666667a3.541333 3.541333 0 0 0-3.2-0.768z m415.829333-516.992a42.666667 42.666667 0 0 1 42.410667 37.717333l0.256 4.949334v96h96a42.666667 42.666667 0 0 1 4.992 85.077333l-4.992 0.256h-96v96a42.666667 42.666667 0 0 1-85.034667 4.992l-0.298667-4.992v-96h-96a42.666667 42.666667 0 0 1-4.949333-85.034667l4.949333-0.298666h96v-96a42.666667 42.666667 0 0 1 42.666667-42.666667z"
|
||||
fill="#ffffff"
|
||||
p-id="1968"
|
||||
></path>
|
||||
</svg> </b
|
||||
><b class="MaxBtn" @click="MTxtTable()" style="background-color: #e07404; right: 0px; top: 5px">
|
||||
<i class="el-icon-document-add"></i>
|
||||
</b>
|
||||
</p>
|
||||
<div class="unfetteredBox">
|
||||
<div
|
||||
:style="item.isHidden ? 'opacity:0.2' : 'opacity:1'"
|
||||
v-for="(item, index) in images"
|
||||
:key="index"
|
||||
class="image"
|
||||
draggable="true"
|
||||
@dragstart="onDragStart($event, item, index)"
|
||||
>
|
||||
<img :src="baseUrl + 'public/mainimg/' + item.content" style="width: 100%; height: 100%; object-fit: cover" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--修改文本 -->
|
||||
<el-dialog title="Edit Text" :visible.sync="txtVisible" width="800px" :close-on-click-modal="false">
|
||||
<el-form ref="editMes" :model="txtStyle" label-width="1px">
|
||||
<p style="margin: 0 5px 15px 5px; line-height: 18px; font-size: 13px; color: #aaa">{{ exegesis }}</p>
|
||||
<el-form-item label="">
|
||||
<el-input type="textarea" placeholder="Please enter the table content..." v-model="txtStyle.text" autosize> </el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<p class="type_Gbtn" @click="trsanGtp">
|
||||
<i class="el-icon-document-copy" style="margin-right: 5px" v-if="btnDisble"></i>
|
||||
<i class="el-icon-loading" style="margin-right: 5px" v-if="!btnDisble"></i>
|
||||
TMRGTP Proofreading
|
||||
</p>
|
||||
<div class="type_CHar" v-if="txtStyle.ChGtpTxt != ''">
|
||||
<p v-html="txtStyle.ChGtpTxt"></p>
|
||||
<font class="chReple" @click="replceChGpr(item)">Replace</font>
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="txtVisible = false"> Cancel </el-button>
|
||||
<el-button type="primary" @click="saveTxt">
|
||||
<i class="el-icon-finished" style="margin-right: 5px"></i>
|
||||
Save
|
||||
</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<!--添加/修改图片 -->
|
||||
<el-dialog :title="picStyle.visiTitle" :visible.sync="pictVisible" width="800px" :close-on-click-modal="false">
|
||||
<el-form ref="editMes" :model="picStyle" label-width="150px">
|
||||
<el-form-item>
|
||||
<span slot="label">
|
||||
<font style="color: #f56c6c; margin-right: 5px">*</font>
|
||||
Picture :
|
||||
</span>
|
||||
<el-upload
|
||||
class="avatar-uploader"
|
||||
:action="'/api/api/Production/up_mainimg_file'"
|
||||
:show-file-list="false"
|
||||
name="mainimg"
|
||||
:on-success="handleAvatarSuccess"
|
||||
:on-error="handleAvatarError"
|
||||
:before-upload="beforeAvatarUpload"
|
||||
>
|
||||
<img v-if="picStyle.imageUrl" :src="picStyle.imageUrl" class="avatar" />
|
||||
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="Bottom Title :">
|
||||
<el-input placeholder="Please enter the table title..." v-model="picStyle.titleBot">
|
||||
</el-input>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="Picture Describe :">
|
||||
<el-input placeholder="Please enter the table describe..." v-model="picStyle.note" type="textarea" :rows="3">
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<p style="margin: 20px 0; text-align: right">
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
@click="
|
||||
picStyle.picUrl = '';
|
||||
picStyle.titleBot = '';
|
||||
picStyle.note = '';
|
||||
picStyle.imageUrl = '';
|
||||
"
|
||||
>
|
||||
<i class="el-icon-refresh" style="margin-right: 5px"></i>Empty
|
||||
</el-button>
|
||||
</p>
|
||||
<div class="lineStyle" v-if="picStyle.picUrl != ''">
|
||||
<div>
|
||||
<span class="title" style="margin-left: 25px">Picture Width :</span>
|
||||
<el-input v-model="picStyle.width" style="width: 120px">
|
||||
<template slot="append">px</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding: 0 20px" v-if="picStyle.picUrl != ''">
|
||||
<div style="text-align: center">
|
||||
<img :src="baseUrl + 'public/mainimg/' + picStyle.picUrl" :style="'width:' + picStyle.width + 'px'" />
|
||||
</div>
|
||||
<p style="text-align: center; margin: 10px 0 15px 0; font-size: 12px; color: #006699">
|
||||
<b>{{ picStyle.titleBot }}</b>
|
||||
</p>
|
||||
<p
|
||||
style="text-align: center; margin: 10px auto 0; font-size: 12px; line-height: 22px"
|
||||
:style="'width:' + picStyle.width + 'px'"
|
||||
v-html="picStyle.note"
|
||||
></p>
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer" v-if="picStyle.picUrl != ''">
|
||||
<el-button @click="pictVisible = false"> Cancel </el-button>
|
||||
<el-button type="primary" @click="savePic">
|
||||
<i class="el-icon-finished" style="margin-right: 5px"></i>
|
||||
Save Picture
|
||||
</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 添加表格 -->
|
||||
<el-dialog title="Insert Table" :visible.sync="threeVisible" width="1200px" :close-on-click-modal="false" >
|
||||
<el-form ref="editMes" :model="lineStyle" label-width="115px">
|
||||
<el-form-item label="Top Title :">
|
||||
<el-input placeholder="Please enter the table title..." v-model="lineStyle.titleTop"> </el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="Word">
|
||||
<span slot="label">
|
||||
<font style="color: #f56c6c; margin-right: 5px">*</font>
|
||||
Content :
|
||||
</span>
|
||||
|
||||
|
||||
|
||||
<common-table ref="commonTable" style="margin-left: -115px;" :lineStyle="lineStyle"></common-table>
|
||||
</el-form-item>
|
||||
<el-form-item label="Bottom Title :">
|
||||
<el-input placeholder="Please enter the table title..." v-model="lineStyle.titleBot"> </el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<p style="margin: 20px 0; text-align: right">
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
@click="
|
||||
lineStyle.textarea = '';
|
||||
lineStyle.titleTop = '';
|
||||
lineStyle.titleBot = '';
|
||||
lineTable = [];
|
||||
"
|
||||
>
|
||||
<i class="el-icon-refresh" style="margin-right: 5px"></i>Empty
|
||||
</el-button>
|
||||
<el-button type="primary" plain @click="CopyExcelToTable">
|
||||
<i class="el-icon-sort" style="margin-right: 5px"></i>Generate Table
|
||||
</el-button>
|
||||
</p>
|
||||
<div class="lineStyle" v-if="lineTable.length != 0">
|
||||
<div>
|
||||
<span class="title">Table All Width :</span>
|
||||
<el-input v-model="lineStyle.tabwith" style="width: 120px">
|
||||
<template slot="append">%</template>
|
||||
</el-input>
|
||||
</div>
|
||||
<div>
|
||||
<div v-for="(item, index) in lineStyle.arrwith" class="styArry">
|
||||
<span class="title"
|
||||
>Column <b style="color: #006699">{{ index + 1 }}</b> :</span
|
||||
>
|
||||
<el-input v-model="lineStyle.arrwith[index]" style="width: 100px">
|
||||
<template slot="append">%</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="saveLine" v-if="lineTable.length != 0">
|
||||
<i class="el-icon-finished" style="margin-right: 5px"></i>
|
||||
Save Table
|
||||
</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { del } from 'vue';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
images: [
|
||||
{
|
||||
p_main_img_id: 157,
|
||||
p_article_id: 2141,
|
||||
p_main_id: 101853,
|
||||
pre_id: 0,
|
||||
width: 500,
|
||||
content: '20240906/7c4cfd8f431cddf05f33634d4ee2cdca.jpg',
|
||||
note: 'Figure 1 Oracle bone inscriptions of YANG',
|
||||
ctime: 0,
|
||||
state: 0
|
||||
}
|
||||
],
|
||||
baseUrl: this.Common.baseUrl,
|
||||
baseUrl: 'https://submission.tmrjournals.com/',
|
||||
mediaUrl: this.Common.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: '',
|
||||
Main_List: [],
|
||||
txtStyle: {
|
||||
text: '',
|
||||
ChGtpTxt: ''
|
||||
},
|
||||
txtVisible: false,
|
||||
lineStyle: {
|
||||
titleTop: '',
|
||||
titleBot: '',
|
||||
textarea: '',
|
||||
tableData: [],
|
||||
tabwith: '100',
|
||||
arrwith: []
|
||||
},
|
||||
lineTable: [],
|
||||
threeVisible: false,
|
||||
picStyle: {
|
||||
titleBot: '',
|
||||
note: '',
|
||||
// picUrl: 'https://www.tmrjournals.cn/public/articleHTML/TMR/TMR20230213002/images/alternativeImage/TMR20230213002-F004.jpg',
|
||||
picUrl: '',
|
||||
imageUrl: '',
|
||||
width: '500'
|
||||
},
|
||||
pictVisible: false,
|
||||
typesettingType: 1,
|
||||
exegesis: "The following contents'<b></b>,<i></i>'are necessary for the generation phase, please do not delete them!!!"
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
this.getDate();
|
||||
},
|
||||
|
||||
methods: {
|
||||
onDragStart(event, image, index) {
|
||||
event.dataTransfer.setData('image', JSON.stringify({ ...image, isNewReformat: true }));
|
||||
event.dataTransfer.setData('imageIndex', index);
|
||||
},
|
||||
onDrop(event, index) {
|
||||
console.log('index at line 297:', index);
|
||||
const draggedImage = JSON.parse(event.dataTransfer.getData('image'));
|
||||
const draggedImageIndex = JSON.parse(event.dataTransfer.getData('imageIndex'));
|
||||
console.log('draggedImage at line 298:', draggedImage);
|
||||
this.Main_List.splice(index, 0, draggedImage);
|
||||
this.images[draggedImageIndex].isHidden = true;
|
||||
},
|
||||
// 获取数据
|
||||
getDate() {
|
||||
let urlLInk = '';
|
||||
let urlTask = {};
|
||||
if (this.Art_Id != undefined) {
|
||||
urlLInk = 'api/Production/getProductionMains';
|
||||
urlTask.p_article_id = this.Art_Id;
|
||||
}
|
||||
// if (this.Art_Doi != undefined) {
|
||||
// urlLInk = 'api/Production/getProductionMainsByDoi';
|
||||
// urlTask.doi = this.Art_Doi;
|
||||
// }
|
||||
const loading = this.$loading({
|
||||
lock: true,
|
||||
text: 'Loading...',
|
||||
spinner: 'el-icon-loading',
|
||||
background: 'rgba(0, 0, 0, 0.7)'
|
||||
});
|
||||
|
||||
// 获取文章信息
|
||||
this.$api
|
||||
.post(urlLInk, urlTask)
|
||||
.then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.detailTitle = res.data.production.title;
|
||||
this.Art_P_Id = res.data.production.p_article_id;
|
||||
this.Main_List = res.data.mains;
|
||||
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;
|
||||
}
|
||||
loading.close();
|
||||
} else {
|
||||
this.$message.error(res.msg);
|
||||
loading.close();
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
this.$message.error(err);
|
||||
loading.close();
|
||||
});
|
||||
},
|
||||
|
||||
// 修改段落/图片
|
||||
MTxtEdit(val, num) {
|
||||
this.picStyle = JSON.parse(JSON.stringify(val));
|
||||
this.picStyle.picUrl = this.picStyle.content;
|
||||
this.picStyle.imageUrl = this.baseUrl + 'public/mainimg/' + this.picStyle.content;
|
||||
this.picStyle.visiTitle = 'Edit Picture';
|
||||
this.pictVisible = true;
|
||||
},
|
||||
|
||||
// 转化为gpt标准格式
|
||||
trsanGtp() {
|
||||
if (this.btnDisble) {
|
||||
this.btnDisble = false;
|
||||
this.$api
|
||||
.post('api/Production/mainGptcheck', {
|
||||
p_main_id: this.txtStyle.p_main_id
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.txtStyle.ChGtpTxt = res.data.content;
|
||||
this.btnDisble = true;
|
||||
// this.$forceUpdate()
|
||||
this.$message.success('Converting success!');
|
||||
} else {
|
||||
this.btnDisble = true;
|
||||
this.$message.error('Converting fail!');
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
this.btnDisble = true;
|
||||
this.$message.error('Converting fail!');
|
||||
});
|
||||
} else {
|
||||
this.$message.warning('Converting, please wait!');
|
||||
}
|
||||
},
|
||||
|
||||
// 替换Gtp生成的内容
|
||||
replceChGpr(val) {
|
||||
this.txtStyle.text = JSON.parse(JSON.stringify(this.txtStyle.ChGtpTxt));
|
||||
},
|
||||
|
||||
// 确定保存段落修改
|
||||
saveTxt() {
|
||||
this.$api
|
||||
.post('api/Production/editProductionMain', {
|
||||
p_main_id: this.txtStyle.p_main_id,
|
||||
content: this.txtStyle.text
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('Successfully edit text!');
|
||||
this.txtVisible = false;
|
||||
this.getDate();
|
||||
// this.Main_List[this.txtStyle.index].text = JSON.parse(JSON.stringify(this.txtStyle.text))
|
||||
} else {
|
||||
this.$message.error(res.msg);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
this.$message.error(err);
|
||||
});
|
||||
},
|
||||
|
||||
// 图片段落
|
||||
MTxtPic(val, num) {
|
||||
this.picStyle.pre_type = 'img';
|
||||
// this.picStyle.body = val.p_main_img_id;
|
||||
|
||||
this.picStyle.p_article_id = this.Art_P_Id;
|
||||
this.picStyle.titleBot = '';
|
||||
this.picStyle.note = '';
|
||||
this.picStyle.width = '500';
|
||||
this.picStyle.picUrl = '';
|
||||
this.picStyle.imageUrl = '';
|
||||
this.picStyle.visiTitle = 'Insert Picture Backward';
|
||||
this.pictVisible = true;
|
||||
},
|
||||
|
||||
// 确定保存图片
|
||||
savePic() {
|
||||
this.picStyle.content = this.picStyle.picUrl;
|
||||
this.images.push(this.picStyle);
|
||||
this.pictVisible = false;
|
||||
return false;
|
||||
|
||||
//要走接口
|
||||
if (this.picStyle.note == '') {
|
||||
this.$message.error('Please fill in the picture describe!');
|
||||
return;
|
||||
}
|
||||
|
||||
this.picStyle.content = this.picStyle.picUrl;
|
||||
|
||||
if (this.picStyle.visiTitle == 'Edit Picture') {
|
||||
this.$api
|
||||
.post('api/Production/editProductionMainImg', this.picStyle)
|
||||
.then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('Successfully edit image!');
|
||||
this.pictVisible = false;
|
||||
this.getDate();
|
||||
} else {
|
||||
this.$message.error(res.msg);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
this.$message.error(err);
|
||||
});
|
||||
} else {
|
||||
this.$api
|
||||
.post('api/Production/addProductionMainImg', this.picStyle)
|
||||
.then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('Successfully added image!');
|
||||
this.pictVisible = false;
|
||||
this.getDate();
|
||||
} else {
|
||||
this.$message.error(res.msg);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
this.$message.error(err);
|
||||
});
|
||||
}
|
||||
},
|
||||
async removeEvent(row) {
|
||||
// const type = await VXETable.modal.confirm('您确定要删除该数据?')
|
||||
const $table = this.$refs.xTable;
|
||||
// if (type === 'confirm') {
|
||||
$table.remove(row);
|
||||
// }
|
||||
},
|
||||
async insertEvent(row) {
|
||||
const $table = this.$refs.xTable;
|
||||
const record = {};
|
||||
const { row: newRow } = await $table.insertAt(record, row);
|
||||
await $table.setEditCell(newRow, 'name');
|
||||
},
|
||||
// 表格段落
|
||||
MTxtTable(val, num) {
|
||||
// this.lineStyle.p_main_id = val.p_main_id;
|
||||
this.lineStyle.textarea = '';
|
||||
this.lineStyle.titleCon = '';
|
||||
this.lineTable = [];
|
||||
|
||||
this.threeVisible = true;
|
||||
this.typesettingType = '1';
|
||||
this.$forceUpdate();
|
||||
},
|
||||
|
||||
// 表格转化
|
||||
CopyExcelToTable() {
|
||||
if (this.lineStyle.textarea == '') {
|
||||
this.$message.error('Please fill in the table content!');
|
||||
return;
|
||||
}
|
||||
console.log(this.lineStyle.textarea);
|
||||
let txtRows = this.lineStyle.textarea.split('\n');
|
||||
let txtColum = [];
|
||||
for (let i = 0; i < txtRows.length; i++) {
|
||||
if (txtRows[i] != '') {
|
||||
let columns = txtRows[i].split('\t');
|
||||
let dataone = [];
|
||||
for (let j = 0; j < columns.length; j++) {
|
||||
dataone.push(columns[j]);
|
||||
}
|
||||
txtColum.push(dataone);
|
||||
}
|
||||
}
|
||||
let arrwithNumer = Math.floor(100 / txtColum[0].length) - 2;
|
||||
this.lineStyle.arrwith = [];
|
||||
for (let i = 0; i < txtColum[0].length; i++) {
|
||||
this.lineStyle.arrwith.push(arrwithNumer);
|
||||
}
|
||||
this.lineTable = txtColum;
|
||||
},
|
||||
|
||||
// 确定保存表格
|
||||
saveLine() {
|
||||
let dataTable = '';
|
||||
for (let i = 0; i < this.lineTable.length; i++) {
|
||||
let ArryDr = '';
|
||||
let listHNem = '';
|
||||
for (let j = 0; j < this.lineTable[i].length; j++) {
|
||||
let ArrHtml =
|
||||
'<div style="width:' +
|
||||
this.lineStyle.arrwith[j] +
|
||||
'%;line-height: 22px;vertical-align: middle;display: inline-block;padding: 0 1%;font-size: 14px;color: #606266;word-wrap: break-word;word-break: normal;">' +
|
||||
this.lineTable[i][j] +
|
||||
'</div>';
|
||||
ArryDr = ArryDr + ArrHtml;
|
||||
}
|
||||
if (i == 0) {
|
||||
listHNem =
|
||||
'<div style="display: flex;border-top: 2px solid #333333;border-bottom: 1px solid #333333;padding: 10px 0;font-weight: bold;margin-bottom: 20px;">' +
|
||||
ArryDr +
|
||||
'</div>';
|
||||
} else if (i == this.lineTable.length - 1) {
|
||||
listHNem = '<div style="display: flex;border-bottom: 2px solid #333333;padding:0 0 20px 0;">' + ArryDr + '</div>';
|
||||
ArryDr = ArryDr + listHNem;
|
||||
} else {
|
||||
listHNem = '<div style="display: flex;padding:20px 0;">' + ArryDr + '</div>';
|
||||
}
|
||||
dataTable = dataTable + listHNem;
|
||||
}
|
||||
dataTable = '<div style="width:' + this.lineStyle.tabwith + '%">' + dataTable + '</div>';
|
||||
if (this.lineStyle.titleTop != '') {
|
||||
dataTable =
|
||||
'<p style="text-align: center;margin: 0 0 10px 0;font-size: 12px;color: #006699;"><b>' +
|
||||
this.lineStyle.titleTop +
|
||||
'</b></p>' +
|
||||
dataTable;
|
||||
}
|
||||
if (this.lineStyle.titleBot != '') {
|
||||
dataTable =
|
||||
dataTable + '<p style="text-align: center;margin: 10px 0 0 0;font-size: 12px;">' + this.lineStyle.titleBot + '</p>';
|
||||
}
|
||||
console.log(dataTable);
|
||||
},
|
||||
|
||||
// 删除段落/图片
|
||||
MTxtDelet(val, index) {
|
||||
var imageIndex = this.images.findIndex((e) => e.p_main_img_id == val.p_main_img_id);
|
||||
if (imageIndex > -1) {
|
||||
delete this.images[imageIndex].isHidden;
|
||||
} else {
|
||||
this.images.push(val);
|
||||
}
|
||||
this.$forceUpdate();
|
||||
this.Main_List.splice(index, 1);
|
||||
console.log('this.images.push at line 654:', this.images);
|
||||
// this.$api
|
||||
// .post('api/Production/delProductionMainImg', {
|
||||
// p_main_img_id: val.p_main_img_id
|
||||
// })
|
||||
// .then((res) => {
|
||||
// if (res.code == 0) {
|
||||
// this.$message.success('Successfully deleted!');
|
||||
// this.getDate();
|
||||
// // this.Main_List.splice(num, 1);
|
||||
// } else {
|
||||
// this.$message.error(res.msg);
|
||||
// }
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// this.$message.error(err);
|
||||
// });
|
||||
},
|
||||
|
||||
// 推送
|
||||
pushOnline() {
|
||||
// 二次确认
|
||||
this.$confirm('Are you sure you want to push it to the official website?', 'Tips', {
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
this.$api
|
||||
.post('api/Production/pushMainToWeb', {
|
||||
article_id: this.Art_web_Id,
|
||||
p_article_id: this.Art_P_Id
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('Successfully push!');
|
||||
this.getDate();
|
||||
if (this.Art_Doi != undefined) {
|
||||
this.$router.push({
|
||||
path: 'comArtHtmlEdit',
|
||||
query: {
|
||||
artID: this.Art_web_Id
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.$message.error(res.msg);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
this.$message.error(err);
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
|
||||
// 上传图片
|
||||
handleAvatarSuccess(res, file) {
|
||||
if (res.code == 0) {
|
||||
this.picStyle.picUrl = res.upurl;
|
||||
this.$forceUpdate();
|
||||
} else {
|
||||
this.$message.error(res.msg);
|
||||
}
|
||||
this.picStyle.imageUrl = URL.createObjectURL(file.raw);
|
||||
},
|
||||
handleAvatarError(res, file) {},
|
||||
beforeAvatarUpload(file) {
|
||||
const isLt2M = file.size / 1024 / 1024 < 1;
|
||||
if (!isLt2M) {
|
||||
this.$message.error('Picture size cannot exceed 1M!');
|
||||
}
|
||||
return isLt2M;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.lineStyle {
|
||||
border-top: 1px solid #0066994d;
|
||||
padding: 20px 20px 40px 20px;
|
||||
}
|
||||
|
||||
.lineStyle > div {
|
||||
}
|
||||
|
||||
.lineStyle > div span.title {
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
margin: 0px 10px 0px 0px;
|
||||
}
|
||||
|
||||
.lineStyle > div font.mark {
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
margin: 0px 0px 0px 10px;
|
||||
}
|
||||
|
||||
.lineStyle .styArry {
|
||||
display: inline-block;
|
||||
margin: 15px 40px 0 0;
|
||||
}
|
||||
|
||||
.lineStyle .styArry:nth-last-child(1) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.lineAll {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.lineAll .lineTit {
|
||||
padding: 0 0 20px 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.lineAll .lineTit:nth-child(1) {
|
||||
border-top: 2px solid #333333;
|
||||
border-bottom: 1px solid #333333;
|
||||
padding: 10px 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.lineAll .lineTit:nth-child(2) {
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.lineAll .lineTit:nth-last-child(1) {
|
||||
border-bottom: 2px solid #333333;
|
||||
}
|
||||
|
||||
.lineAll .lineTit > div {
|
||||
line-height: 22px;
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
padding: 0 1%;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.type_MTxt {
|
||||
background-color: #fff;
|
||||
padding: 0 10px 10px 10px;
|
||||
box-shadow: 0 1px 3px rgb(16 17 19 / 6%);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.type_MTxt > div {
|
||||
position: relative;
|
||||
padding: 8px 15px;
|
||||
min-height: 22px;
|
||||
border: 2px dashed #fff;
|
||||
border-radius: 5px;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.type_MTxt > .imgBox:hover {
|
||||
background-color: rgb(0 102 153 / 10%);
|
||||
border: 2px dashed rgb(0 102 153 / 50%);
|
||||
}
|
||||
|
||||
.type_MTxt > div > p {
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.type_MTxt > .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;
|
||||
}
|
||||
|
||||
.type_MTxt > div .MaxPicture {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.type_MTxt > div .MaxPicture > img {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.type_MTxt > div .MaxPicture > font {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.MaxBtn {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: -1px;
|
||||
color: #fff;
|
||||
border-radius: 50px;
|
||||
font-size: 15.5px;
|
||||
padding: 6px 7px;
|
||||
display: none;
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
.MaxBtn {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.MaxBtn:hover {
|
||||
opacity: 1;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.type_Gbtn {
|
||||
color: #fff;
|
||||
border-color: #006699;
|
||||
background: #006699;
|
||||
width: 30%;
|
||||
text-align: center;
|
||||
padding: 8px 0;
|
||||
font-size: 14px;
|
||||
border-radius: 8px;
|
||||
font-weight: 500;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.type_Gbtn:hover {
|
||||
box-shadow: 0 4px 14px rgb(0 102 153 / 30%);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.type_CHar {
|
||||
position: relative;
|
||||
border-left: 4px solid rgba(0 102 153 / 20%);
|
||||
border-radius: 5px;
|
||||
padding: 20px 25px 15px 20px;
|
||||
background-color: #fff;
|
||||
margin: 20px 0 0 0;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
box-shadow: 0 1px 10px rgb(0 102 153 / 20%);
|
||||
}
|
||||
|
||||
.type_CHar .chReple {
|
||||
position: absolute;
|
||||
top: -1px;
|
||||
right: 1px;
|
||||
border-radius: 3px;
|
||||
font-size: 10px;
|
||||
background-color: rgb(223 109 11);
|
||||
opacity: 0.85;
|
||||
color: #fff;
|
||||
padding: 1px 10px;
|
||||
}
|
||||
|
||||
.type_CHar .chReple:hover {
|
||||
opacity: 1;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.avatar-uploader .el-upload {
|
||||
border: 1px dashed #d9d9d9;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.avatar-uploader_small {
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.avatar-uploader .el-upload:hover {
|
||||
border-color: #409eff;
|
||||
}
|
||||
|
||||
.avatar-uploader-icon {
|
||||
font-size: 28px;
|
||||
color: #8c939d;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
line-height: 120px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.avatar-uploader_small .el-upload {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
.avatar-uploader_small .avatar-uploader-icon {
|
||||
line-height: 80px;
|
||||
margin-left: -30px;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
display: block;
|
||||
}
|
||||
.unfetteredBox {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
padding: 0 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.unfetteredBox .image {
|
||||
margin-top: 10px;
|
||||
box-shadow: rgba(16, 17, 19, 0.5) 0px 1px 3px;
|
||||
margin-right: 10px;
|
||||
height: 60px;
|
||||
width: 60px;
|
||||
border-radius: 4px;
|
||||
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
@@ -82,7 +82,9 @@
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
|
||||
<common-word-html v-if="articleInfo.article_id" :articleId="articleInfo.article_id" style=" box-sizing: border-box"></common-word-html>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- end -->
|
||||
@@ -97,6 +99,7 @@
|
||||
<el-radio :label="3">Revison</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Comments to the authors" v-if="questionform.recommend == 3">
|
||||
<el-input type="textarea" placeholder="please input content" v-model="questionform.content"
|
||||
:rows="8"></el-input>
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
<el-breadcrumb-item> <i class="el-icon-uthorVisiblelx-cascades"></i> Submit manuscript </el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<div class="step_list" style="width: 960px; position: relative">
|
||||
<div style="display: flex;justify-content: space-between;">
|
||||
<div>
|
||||
<div class="step_list" style="width: 960px; position: relative">
|
||||
<div v-for="item in listStep" @click="StepCode(item.index)" :class="show_step == item.index ? 'C_style' : ''">
|
||||
<div>
|
||||
<i :class="item.icon"></i>
|
||||
@@ -15,39 +17,8 @@
|
||||
<p class="bor_der"></p>
|
||||
</div>
|
||||
<br clear="both" />
|
||||
<!-- <p
|
||||
style="position: absolute;line-height: 20px;color: #999;left:990px;top: 600px;width: 280px;font-size: 14px;">
|
||||
We encourage authors to upload a Cover Letter file and Highlights is also be encouraged. That will help
|
||||
authors let editors quickly obtain information and evaluate the
|
||||
scientific value of their research correctly.
|
||||
<br>Please remind our editor in the cover letter if you want your manuscript processed quickly.
|
||||
<br>Please note that manuscripts with at least one of the following characteristics will be included in
|
||||
the
|
||||
journal's manuscript fast track:
|
||||
<br>
|
||||
<font style="color: #006699;">1.Interest:</font> This manuscript has a novel perspective.
|
||||
<br>
|
||||
<font style="color: #006699;">2.Importance:</font> This manuscript belongs to the focus area.
|
||||
<br>
|
||||
<font style="color: #006699;">3.Value:</font> This manuscript belongs to the advanced topic and can
|
||||
attract wide
|
||||
attention.
|
||||
</p> -->
|
||||
<p style="position: absolute; line-height: 20px; color: #999; left: 990px; top: 120px; width: 280px; font-size: 14px">
|
||||
We highly encourage authors to upload a Cover Letter file and Highlights, as this will assist editors in quickly obtaining
|
||||
accurate information and evaluating the scientific value of their research. If you would like your manuscript to be
|
||||
processed quickly, please kindly remind our editor in the cover letter.
|
||||
<br />Additionally, please take note that manuscripts exhibiting at least one of the following characteristics will be
|
||||
considered for the journal's fast track process:
|
||||
<br />
|
||||
<font style="color: #006699">Interest:</font> The manuscript presents a unique perspective.
|
||||
<br />
|
||||
<font style="color: #006699">Importance:</font> The manuscript aligns with the journal's focus area.
|
||||
<br />
|
||||
<font style="color: #006699">Value:</font> The manuscript addresses an advanced topic that has the potential to garner
|
||||
widespread attention.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="manu_add" style="width: 960px" v-loading="loading">
|
||||
<el-form ref="articleform" :model="form" :rules="rules" label-width="160px">
|
||||
<div class="bag_color" v-if="show_step == 1">
|
||||
@@ -438,7 +409,7 @@
|
||||
</el-form-item> -->
|
||||
<el-form-item label="Manuscirpt :" prop="manuscirpt" label-width="200px">
|
||||
<el-upload
|
||||
ref="uploadFile"
|
||||
ref="uploadFileManuscirpt"
|
||||
class="upload-demo up_newstyle"
|
||||
:action="upload_manuscirpt"
|
||||
accept=".docx"
|
||||
@@ -452,7 +423,7 @@
|
||||
:file-list="fileL_manuscirpt"
|
||||
:on-preview="dowloadFile"
|
||||
>
|
||||
<div class="el-upload__text" @click="clearUploadedFile">
|
||||
<div class="el-upload__text" @click="removefilemanuscirpt">
|
||||
<em>Upload</em>
|
||||
</div>
|
||||
<div class="el-upload__tip" slot="tip">
|
||||
@@ -733,6 +704,55 @@
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
padding: 0;
|
||||
background: none;
|
||||
margin-top: 30px;
|
||||
line-height: 20px;
|
||||
color: #999;
|
||||
left: 990px;
|
||||
top: 120px;
|
||||
width: 400px;
|
||||
font-size: 14px;
|
||||
"
|
||||
>
|
||||
<p
|
||||
style="
|
||||
width: 400px;
|
||||
border: 1px solid #ebeef5;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
"
|
||||
>
|
||||
We encourage authors to upload a Cover Letter file and Highlights is also be encouraged. That will help authors let editors
|
||||
quickly obtain information and evaluate the scientific value of their research correctly.
|
||||
<br />Please remind our editor in the cover letter if you want your manuscript processed quickly. <br />Please note that
|
||||
manuscripts with at least one of the following characteristics will be included in the journal's manuscript fast track:
|
||||
<br />
|
||||
<font style="color: #006699">1.Interest:</font> This manuscript has a novel perspective.
|
||||
<br />
|
||||
<font style="color: #006699">2.Importance:</font> This manuscript belongs to the focus area.
|
||||
<br />
|
||||
<font style="color: #006699">3.Value:</font> This manuscript belongs to the advanced topic and can attract wide attention.
|
||||
</p>
|
||||
<common-word-html
|
||||
v-show="show_step == 3"
|
||||
:articleId="stagingID"
|
||||
imgHeight="120px"
|
||||
v-if="isShowCommonWord&&stagingID"
|
||||
style="margin-top: 10px; box-sizing: border-box; background-color: #fff"
|
||||
></common-word-html>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<el-dialog title="" :visible.sync="licensebox" width="500px">
|
||||
<span style="word-wrap: break-word; word-break: normal; line-height: 22px">
|
||||
Creative Commons Licensing<br /><br />
|
||||
@@ -879,6 +899,7 @@ export default {
|
||||
usercap: localStorage.getItem('U_role'),
|
||||
ms_alias: localStorage.getItem('ms_journal_alias'),
|
||||
stagingID: this.$route.query.id,
|
||||
isShowCommonWord: false,
|
||||
move_step: 1, //进行步骤
|
||||
show_step: 1, //显示内容
|
||||
items: [],
|
||||
@@ -1290,10 +1311,20 @@ export default {
|
||||
value: 'journal_topic_id', // 自定义要映射的键名
|
||||
label: 'title',
|
||||
children: 'children'
|
||||
}
|
||||
},
|
||||
tables: [],
|
||||
wordimgList: [],
|
||||
tablesHtml: [],
|
||||
imagesHtml: []
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
collapseValue: {
|
||||
handler(e) {
|
||||
console.log(e);
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
form: {
|
||||
handler(e) {
|
||||
// console.log(e)
|
||||
@@ -1313,6 +1344,9 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
collapseValue() {
|
||||
return localStorage.getItem('collapse');
|
||||
},
|
||||
upload_articleApproval: function () {
|
||||
return this.baseUrl + 'api/Article/up_approval_file';
|
||||
},
|
||||
@@ -1585,30 +1619,30 @@ export default {
|
||||
|
||||
// 邮箱用户模糊搜索
|
||||
chaMateFit(value, cb, num) {
|
||||
console.log('num at line 1587:', value)
|
||||
console.log('num at line 1587:', value);
|
||||
// var mailRegular = /^\w+([-+._']\w+)*@\w+(\.[a-zA-Z]{2,3}){1,2}$/
|
||||
var mailRegular = /^\w+([-+._']\w+)*@/;
|
||||
// if (mailRegular.test(value)) {
|
||||
this.form.authorList[num].load = true;
|
||||
// this.$forceUpdate();
|
||||
this.$api
|
||||
.post('api/Article/getRelationAuthorByEmail', {
|
||||
email: value,
|
||||
page: 1,
|
||||
limit: 10
|
||||
})
|
||||
.then((res) => {
|
||||
var restaurants = res.data.authors;
|
||||
for (let i in restaurants) {
|
||||
restaurants[i].value = restaurants[i].email + ' | ' + restaurants[i].firstname + restaurants[i].lastname;
|
||||
}
|
||||
var results = value ? restaurants.filter(this.createMata(value)) : restaurants;
|
||||
console.log('🚀 ~ .then ~ results177:', results);
|
||||
// 调用 callback 返回建议列表的数据
|
||||
cb(results);
|
||||
this.form.authorList[num].load = false;
|
||||
this.$forceUpdate();
|
||||
});
|
||||
this.form.authorList[num].load = true;
|
||||
// this.$forceUpdate();
|
||||
this.$api
|
||||
.post('api/Article/getRelationAuthorByEmail', {
|
||||
email: value,
|
||||
page: 1,
|
||||
limit: 10
|
||||
})
|
||||
.then((res) => {
|
||||
var restaurants = res.data.authors;
|
||||
for (let i in restaurants) {
|
||||
restaurants[i].value = restaurants[i].email + ' | ' + restaurants[i].firstname + restaurants[i].lastname;
|
||||
}
|
||||
var results = value ? restaurants.filter(this.createMata(value)) : restaurants;
|
||||
console.log('🚀 ~ .then ~ results177:', results);
|
||||
// 调用 callback 返回建议列表的数据
|
||||
cb(results);
|
||||
this.form.authorList[num].load = false;
|
||||
this.$forceUpdate();
|
||||
});
|
||||
// }
|
||||
},
|
||||
|
||||
@@ -2062,7 +2096,7 @@ export default {
|
||||
this.$message.error('Only ZIP files can be uploaded (file format: .zip).');
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// const iszip =
|
||||
// file.type === 'application/x-zip-compressed';
|
||||
// if (!iszip) {
|
||||
@@ -2073,12 +2107,14 @@ export default {
|
||||
},
|
||||
beforeupload_totalpage(file) {},
|
||||
beforeupload_manuscirpt(file) {
|
||||
console.log('file at line 2075:', file);
|
||||
let flieArr = file.name.split('.');
|
||||
let fileSuffix = flieArr[flieArr.length - 1];
|
||||
if (fileSuffix != 'docx') {
|
||||
this.$message.error('Only word and compressed files can be uploaded(.docx)');
|
||||
return false;
|
||||
}
|
||||
|
||||
// const ismau =
|
||||
// file.type === 'application/msword' ||
|
||||
// file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ||
|
||||
@@ -2147,12 +2183,48 @@ export default {
|
||||
this.$message.error('service error:' + res.msg);
|
||||
}
|
||||
},
|
||||
upSuccess_manuscirpt(res, file) {
|
||||
|
||||
addWordTablesList(tables) {
|
||||
console.log('tables at line 2187:', tables)
|
||||
console.log('this.fileMesForm at line 2189:', this.stagingID)
|
||||
var data = {
|
||||
article_id: this.stagingID,
|
||||
|
||||
list: tables.map(e=>( {
|
||||
table: JSON.stringify([...e]),
|
||||
type: 0,
|
||||
html_data: ''
|
||||
})),
|
||||
|
||||
|
||||
};
|
||||
|
||||
this.$api.post('api/Article/addArticleTable', data).then((res) => {
|
||||
this.isShowCommonWord=true
|
||||
});
|
||||
},
|
||||
upLoadWordTables() {},
|
||||
upSuccess_manuscirpt(res, File) {
|
||||
// console.log('file at line 2174:', file.raw)
|
||||
if (File) {
|
||||
var that = this;
|
||||
const reader = new FileReader();
|
||||
reader.onload = function (e) {
|
||||
that.$commonJS.extractWordTablesToArrays(File.raw, function (wordTables) {
|
||||
console.log('tablesHtml at line 61:', wordTables);
|
||||
|
||||
that.addWordTablesList(wordTables);
|
||||
});
|
||||
};
|
||||
reader.readAsArrayBuffer(File.raw);
|
||||
}
|
||||
if (res.code == 0) {
|
||||
this.form.manuscirpt = 'manuscirpt/' + res.upurl;
|
||||
this.fileL_manuscirpt = [{}];
|
||||
this.isShowCommonWord=false
|
||||
this.fileL_manuscirpt[0].name = 'Manuscirpt File';
|
||||
this.fileL_manuscirpt[0].url = 'manuscirpt/' + res.upurl;
|
||||
|
||||
this.onStaging(5);
|
||||
} else {
|
||||
this.$message.error('service error: ' + res.msg);
|
||||
@@ -2197,10 +2269,10 @@ export default {
|
||||
});
|
||||
},
|
||||
removefilepicturesAndTables(file, fileList) {
|
||||
console.log('file at line 2199:', file)
|
||||
if(!file){
|
||||
return false
|
||||
}
|
||||
console.log('file at line 2199:', file);
|
||||
if (!file) {
|
||||
return false;
|
||||
}
|
||||
this.form.picturesAndTables = '';
|
||||
this.fileL_picturesAndTables = [];
|
||||
this.$api
|
||||
@@ -2218,10 +2290,34 @@ return false
|
||||
removefiletotalpage(file, fileList) {
|
||||
this.form.totalpage = '';
|
||||
},
|
||||
clearFileManuscript() {
|
||||
this.wordimgList = [];
|
||||
this.imagesHtml = '';
|
||||
this.tables = [];
|
||||
this.tablesHtmlHtml = '';
|
||||
this.isShowCommonWord=false;
|
||||
this.$api
|
||||
.post('api/Article/reloadArticleImages', {
|
||||
article_id: this.stagingID
|
||||
})
|
||||
.then((res) => {});
|
||||
|
||||
this.$api
|
||||
.post('api/Article/reloadArticleTable', {
|
||||
article_id: this.stagingID
|
||||
})
|
||||
.then((res) => {});
|
||||
},
|
||||
removefilemanuscirpt(file, fileList) {
|
||||
console.log('fileList at line 2337:', file, fileList);
|
||||
if (this.form.manuscirpt != '') {
|
||||
}
|
||||
this.form.manuscirpt = '';
|
||||
this.fileL_manuscirpt = [];
|
||||
this.$api
|
||||
this.$refs['uploadFileManuscirpt'].clearFiles();
|
||||
this.clearFileManuscript();
|
||||
if(this.form.manuscirptId){
|
||||
this.$api
|
||||
.post('api/Article/delArticleFile', {
|
||||
file_id: this.form.manuscirptId
|
||||
})
|
||||
@@ -2232,6 +2328,8 @@ return false
|
||||
this.$message.error(res.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
removefilesupplementary() {
|
||||
this.form.supplementary = '';
|
||||
@@ -2492,6 +2590,7 @@ return false
|
||||
// this.$message.error('First author and corresponding author must be exist');
|
||||
// return;
|
||||
}
|
||||
|
||||
this.move_step = 3; //进行步骤
|
||||
this.show_step = 3; //显示内容
|
||||
}
|
||||
@@ -2517,6 +2616,8 @@ return false
|
||||
|
||||
// 暂存
|
||||
onStaging(e) {
|
||||
var that = this;
|
||||
console.log('e at line 2584:', e);
|
||||
if (e == 1) {
|
||||
var flist = this.keywordsList;
|
||||
var fstr = '';
|
||||
@@ -2538,6 +2639,12 @@ return false
|
||||
}
|
||||
});
|
||||
} else if (e == 2) {
|
||||
this.isShowCommonWord=false;
|
||||
setTimeout(() => {
|
||||
this.isShowCommonWord=true;
|
||||
// that.getWordTablesList();
|
||||
// that.getWordimgList();
|
||||
}, 200);
|
||||
// for (let i = 0; i < this.form.authorList.length; i++) {
|
||||
// if (this.form.authorList[i].art_aut_id == undefined) {
|
||||
// this.form.authorList[i].art_aut_id = 0
|
||||
@@ -2609,6 +2716,13 @@ return false
|
||||
.then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.form.manuscirptId = res.data.file_id;
|
||||
console.log('this.form.manuscirpt at line 2652:', this.form.manuscirpt);
|
||||
|
||||
console.log('1111111111111111111111111111');
|
||||
setTimeout(() => {
|
||||
// that.getWordTablesList();
|
||||
// that.getWordimgList();
|
||||
}, 500);
|
||||
} else {
|
||||
this.$message.error(res.msg);
|
||||
}
|
||||
@@ -3192,4 +3306,7 @@ return false
|
||||
.partyAry > div > p > font {
|
||||
color: #777;
|
||||
}
|
||||
</style>
|
||||
::v-deep .el-collapse-item__header {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<font>Title :</font>
|
||||
<b> {{ form.title }}</b>
|
||||
</p>
|
||||
|
||||
|
||||
<!-- <p v-show="form.type=='A'">
|
||||
<font>Ethical Approval :</font><b>{{form.approval?'Yes':'No'}}</b>
|
||||
</p> -->
|
||||
@@ -177,14 +177,23 @@
|
||||
<el-col :span="12">
|
||||
<h4>Manuscirpt :</h4>
|
||||
<p class="fi_new">
|
||||
<a v-for="item in manuscirptFileList" :href="mediaUrl + item.file_url">
|
||||
<img src="../../assets/img/icon_0.png" />
|
||||
<span>
|
||||
<font>Uploader : </font>{{ item.username }}
|
||||
<i><i class="el-icon-time"></i>{{ formatDate(item.ctime) }}</i>
|
||||
</span>
|
||||
<i class="el-icon-download download"></i>
|
||||
</a>
|
||||
<template v-for="item in manuscirptFileList">
|
||||
<a href="#">
|
||||
<img
|
||||
src="../../assets/img/icon_0.png"
|
||||
@click="openDrawer(item, mediaUrl + item.file_url)"
|
||||
/>
|
||||
|
||||
<span @click="openDrawer(item, mediaUrl + item.file_url)">
|
||||
<font>Uploader : </font>{{ item.username }}
|
||||
<i><i class="el-icon-time"></i>{{ formatDate(item.ctime) }}</i>
|
||||
<i class="el-icon-view" style="font-weight: bold; color: #888; margin: 0 0 0 10px"></i>
|
||||
</span>
|
||||
<a :href="mediaUrl + item.file_url">
|
||||
<i class="el-icon-download download"></i>
|
||||
</a>
|
||||
</a>
|
||||
</template>
|
||||
</p>
|
||||
<br clear="both" />
|
||||
</el-col>
|
||||
@@ -224,6 +233,12 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<common-word-html
|
||||
:articleId="$route.query.id"
|
||||
style=" box-sizing: border-box"
|
||||
|
||||
|
||||
></common-word-html>
|
||||
</div>
|
||||
<!-- 被拒稿件操作 --->
|
||||
<div class="art_caozuo_" v-if="opname == 'rejectArticles'">
|
||||
@@ -445,6 +460,46 @@
|
||||
<el-button type="primary" @click="saveResubmit">Save</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
<el-drawer
|
||||
append-to-body
|
||||
destroy-on-close
|
||||
:title="previewData.drawerTitle"
|
||||
:visible.sync="drawer"
|
||||
direction="rtl"
|
||||
:before-close="handleClose"
|
||||
size="1200px"
|
||||
>
|
||||
<template #title>
|
||||
<div style="display: inline-block; vertical-align: top">
|
||||
Manuscirpt :
|
||||
<img
|
||||
src="../../assets/img/icon_0.png"
|
||||
style="
|
||||
width: 15px;
|
||||
|
||||
margin: 0 5px 0 0;
|
||||
margin-left: 10px;
|
||||
"
|
||||
/>
|
||||
|
||||
<span>
|
||||
<font>Uploader : </font>{{ previewData.username }}
|
||||
<i style="color: #888; margin: 0 20px; font-style: normal"
|
||||
><i class="el-icon-time" style="margin-right: 10px"></i>{{ formatDate(previewData.ctime) }}</i
|
||||
>
|
||||
<a :href="mediaUrl + previewData.file_url">
|
||||
<i class="el-icon-download download" style="color: #75abf1; font-weight: bold"></i>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<iframe
|
||||
:src="`https://view.officeapps.live.com/op/embed.aspx?src=${previewData.previewUrl}`"
|
||||
width="100%"
|
||||
height="98%"
|
||||
frameborder="0"
|
||||
></iframe>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -456,10 +511,12 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
previewData: {},
|
||||
baseUrl: this.Common.baseUrl,
|
||||
mediaUrl: this.Common.mediaUrl,
|
||||
now_year: 0,
|
||||
items: '',
|
||||
drawer: false,
|
||||
loading: false,
|
||||
loading1: false,
|
||||
loading2: false,
|
||||
@@ -574,7 +631,10 @@ export default {
|
||||
},
|
||||
created: function () {
|
||||
this.initarticle();
|
||||
|
||||
this.initFileList();
|
||||
this.getWordimgList();
|
||||
this.getWordTablesList();
|
||||
},
|
||||
computed: {
|
||||
myType: function () {
|
||||
@@ -705,6 +765,48 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async getWordimgList() {
|
||||
var that = this;
|
||||
await this.$api
|
||||
.post('api/Article/getArticleImages', {
|
||||
article_id: this.$route.query.id
|
||||
})
|
||||
.then(async (res) => {
|
||||
this.wordimgList = res.data.list;
|
||||
if (this.wordimgList.length > 0) {
|
||||
await this.$commonJS.getWordImagesThumbnails(this.wordimgList, function (html) {
|
||||
that.imagesHtml = html;
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
getWordTablesList() {
|
||||
this.$api
|
||||
.post('api/Article/getArticleTable', {
|
||||
article_id: this.$route.query.id
|
||||
})
|
||||
.then((res) => {
|
||||
console.log('res at line 2210:', res);
|
||||
var that = this;
|
||||
that.tables = res.data.list && res.data.list.length > 0 ? JSON.parse(res.data.list[0].table) : [];
|
||||
if (that.tables.length > 0) {
|
||||
that.$commonJS.getWordTablesThumbnails(that.tables, function (html) {
|
||||
that.tablesHtml = html;
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
openDrawer(data, url) {
|
||||
this.previewData = {
|
||||
...data,
|
||||
previewUrl: url,
|
||||
drawerTitle: 'Uploader : ' + data.username + ' ' + this.formatDate(data.ctime)
|
||||
};
|
||||
this.drawer = true;
|
||||
},
|
||||
handleClose() {
|
||||
this.drawer = false;
|
||||
},
|
||||
talksave(val) {
|
||||
this.msgform.ad_content = '';
|
||||
this.getTalkList();
|
||||
@@ -1285,4 +1387,14 @@ export default {
|
||||
.art_state_message p {
|
||||
margin-left: 15px;
|
||||
}
|
||||
::v-deep .el-drawer__header {
|
||||
margin-bottom: 0;
|
||||
padding: 15px;
|
||||
}
|
||||
::v-deep #wacframe #AppHeaderPanel {
|
||||
width: 98% !important;
|
||||
}
|
||||
::v-deep .el-drawer__wrapper .WACContainer {
|
||||
z-index: 10000 !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -2028,7 +2028,7 @@
|
||||
background: 'rgba(0, 0, 0, 0.7)'
|
||||
});
|
||||
this.$api
|
||||
.post('api/Production/doTypeSetting', {
|
||||
.post('api/Production/doTypeSettingNew', {
|
||||
p_article_id: this.p_article_id
|
||||
})
|
||||
.then(res => {
|
||||
|
||||
@@ -1898,7 +1898,7 @@
|
||||
});
|
||||
|
||||
this.$api
|
||||
.post('api/Production/doTypeSetting', {
|
||||
.post('api/Production/doTypeSettingNew', {
|
||||
p_article_id: this.p_article_id
|
||||
})
|
||||
.then(res => {
|
||||
|
||||
@@ -275,7 +275,7 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<el-dialog title="Manuscript Basic Information" :visible.sync="Detailvisible" width="800px">
|
||||
<el-dialog destroy-on-close title="Manuscript Basic Information" :visible.sync="Detailvisible" width="800px">
|
||||
<div class="art_state_message">
|
||||
<p>
|
||||
<font>Title :</font><b>{{artMes.title}}</b>
|
||||
@@ -359,6 +359,7 @@
|
||||
</p>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="art_file">
|
||||
@@ -423,6 +424,8 @@
|
||||
</p>
|
||||
<br clear="both">
|
||||
</div>
|
||||
<common-word-html :articleId="articleId" style="box-sizing: border-box"
|
||||
></common-word-html>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="Detailvisible=false">OK</el-button>
|
||||
</span>
|
||||
@@ -468,7 +471,8 @@
|
||||
totalpageFileList: [],
|
||||
manuscirptFileList: [],
|
||||
supplementaryFileList:[],
|
||||
fileL_supplementary:[]
|
||||
fileL_supplementary:[],
|
||||
wordTables:[],
|
||||
};
|
||||
},
|
||||
created: function() {
|
||||
@@ -680,8 +684,41 @@
|
||||
},
|
||||
|
||||
// 上传文件
|
||||
onSubmit() {
|
||||
addWordTablesList(tables) {
|
||||
console.log('tables at line 687:', tables)
|
||||
var data = {
|
||||
article_id: this.fileMesForm.articleId,
|
||||
list: tables.map(e=>( {
|
||||
table: JSON.stringify([...e]),
|
||||
type: 0,
|
||||
html_data: ''
|
||||
})),
|
||||
|
||||
|
||||
};
|
||||
|
||||
this.$api.post('api/Article/addArticleTable', data).then((res) => {
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
async clearFileManuscript() {
|
||||
var that=this
|
||||
await this.$api
|
||||
.post('api/Article/reloadArticleImages', {
|
||||
article_id: this.fileMesForm.articleId
|
||||
})
|
||||
.then((res) => {});
|
||||
|
||||
await this.$api
|
||||
.post('api/Article/reloadArticleTable', {
|
||||
article_id: this.fileMesForm.articleId
|
||||
})
|
||||
.then((res) => {that. addWordTablesList(that.wordTables);});
|
||||
},
|
||||
async onSubmit() {
|
||||
console.log(this.fileMesForm)
|
||||
var that=this;
|
||||
//验证文件
|
||||
if (this.fileMesForm.manuscirpt == undefined || this.fileMesForm.manuscirpt == '') {
|
||||
this.$message.error(
|
||||
@@ -694,19 +731,28 @@
|
||||
return false;
|
||||
}
|
||||
this.loading = true;
|
||||
this.$api
|
||||
await this.$api
|
||||
.post('api/Article/RepairBack', this.fileMesForm)
|
||||
.then((res) => {
|
||||
this.loading = false;
|
||||
.then(async (res) => {
|
||||
|
||||
if (res.code == 0) {
|
||||
await that.clearFileManuscript()
|
||||
|
||||
this.$message.success('Upload successful!');
|
||||
this.loading = false;
|
||||
|
||||
|
||||
|
||||
|
||||
setTimeout(()=>{
|
||||
this.loading = false;
|
||||
this.$router.push({
|
||||
path: 'articleProcess',
|
||||
query: {
|
||||
id: this.articleId
|
||||
}
|
||||
});
|
||||
},500)
|
||||
|
||||
} else {
|
||||
this.$message.error('Failed to submit, please contact administrator!');
|
||||
console.log(res.msg);
|
||||
@@ -765,9 +811,21 @@
|
||||
// this.fileMesForm.picturesAndTables.push('picturesAndTables/' + url);
|
||||
// }
|
||||
},
|
||||
upSuccess_manuscirpt(res, file) {
|
||||
upSuccess_manuscirpt(res, File) {
|
||||
if (res.code == 0) {
|
||||
this.fileMesForm.manuscirpt = 'manuscirpt/' + res.upurl;
|
||||
if (File) {
|
||||
var that = this;
|
||||
const reader = new FileReader();
|
||||
reader.onload = function (e) {
|
||||
that.$commonJS.extractWordTablesToArrays(File.raw, function (wordTables) {
|
||||
console.log('tablesHtml at line 61:', wordTables);
|
||||
that.wordTables=wordTables
|
||||
|
||||
});
|
||||
};
|
||||
reader.readAsArrayBuffer(File.raw);
|
||||
}
|
||||
} else {
|
||||
this.$message.error('service error:' + res.msg);
|
||||
}
|
||||
|
||||
533
src/components/page/components/Tinymce/index copy 2.vue
Normal file
@@ -0,0 +1,533 @@
|
||||
<template>
|
||||
<div class="tinymce-container editor-container">
|
||||
<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 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 td {
|
||||
border-bottom:1.0000pt solid #000 !important;mso-border-bottom-alt:0.5000pt solid #000 !important;;
|
||||
}
|
||||
|
||||
|
||||
`;
|
||||
export default {
|
||||
name: 'tinymce',
|
||||
components: {},
|
||||
props: {
|
||||
id: {
|
||||
type: String
|
||||
},
|
||||
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
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
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()
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
value(val) {
|
||||
if (!this.hasChange && this.hasInit) {
|
||||
this.$nextTick(() => window.tinymce.get(this.tinymceId).setContent(val));
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.typesettingType = 1;
|
||||
this.initTinymce();
|
||||
},
|
||||
activated() {
|
||||
this.typesettingType = 1;
|
||||
this.initTinymce();
|
||||
},
|
||||
deactivated() {
|
||||
this.destroyTinymce();
|
||||
},
|
||||
methods: {
|
||||
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) => {
|
||||
const editor = window.tinymce.get(this.tinymceId);
|
||||
editor.dom.setStyles(table, {
|
||||
width: this.typesettingType == 1 ? '17.18cm' : '25.88cm'
|
||||
});
|
||||
});
|
||||
|
||||
this.$forceUpdate();
|
||||
},
|
||||
initTinymce() {
|
||||
const _this = this;
|
||||
window.tinymce.init({
|
||||
selector: `#${this.tinymceId}`,
|
||||
content_css: false, // 禁用默认样式
|
||||
table_resize_bars: true, // 启用拖动调整功能
|
||||
valid_elements: '*[*]', // 允许所有 HTML 标签
|
||||
|
||||
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}`,
|
||||
formats: {
|
||||
bold: { inline: 'b' },
|
||||
italic: { inline: 'i' }
|
||||
},
|
||||
body_class: 'panel-body ',
|
||||
object_resizing: false,
|
||||
toolbar: this.toolbar.length > 0 ? this.toolbar : toolbar,
|
||||
menubar: false, // 启用菜单栏并保持必要的项目
|
||||
statusbar: false, // 关闭底部状态栏
|
||||
custom_colors: false,
|
||||
color_map: ['000000', 'Black', '0082AA', 'TMR Blue'],
|
||||
plugins: 'forecolor code paste table image', // 启用 forecolor 和 code 插件
|
||||
end_container_on_empty_block: true,
|
||||
content_css: 'default', // 加载 TinyMCE 默认样式表
|
||||
//设置自定义按钮 myCustomToolbarButton
|
||||
|
||||
setup(ed) {
|
||||
ed.ui.registry.addButton('uploadWord', {
|
||||
text: 'Word',
|
||||
icon: 'import-word', // 使用自定义图标
|
||||
onAction: function () {
|
||||
const input = document.createElement('input');
|
||||
input.type = 'file';
|
||||
input.accept = '.docx'; // 限制为 Word 文件
|
||||
input.addEventListener('change', function () {
|
||||
const file = input.files[0];
|
||||
if (file) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = function (e) {
|
||||
const arrayBuffer = e.target.result;
|
||||
_this.$commonJS.extractTablesFromWord(arrayBuffer, function (tablesHtml) {
|
||||
console.log('tablesHtml at line 279:', tablesHtml);
|
||||
ed.setContent(tablesHtml);
|
||||
});
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
}
|
||||
});
|
||||
input.click();
|
||||
}
|
||||
});
|
||||
|
||||
ed.ui.registry.addMenuButton('customDropdown', {
|
||||
text: _this.$t('commonTable.PaperRotation'), // 下拉框标题
|
||||
fetch: function (callback) {
|
||||
// 定义下拉框的内容
|
||||
const items = [..._this.typesettingTypeOptions];
|
||||
const menuItems = items.map((item) => ({
|
||||
type: 'menuitem',
|
||||
text: item.label,
|
||||
onAction: function () {
|
||||
_this.typesettingType = item.value;
|
||||
_this.changeTable();
|
||||
// ed.execCommand(item.value); // 执行命令
|
||||
}
|
||||
}));
|
||||
callback(menuItems);
|
||||
}
|
||||
});
|
||||
|
||||
ed.on('init', function () {
|
||||
const editorBody = ed.getBody();
|
||||
// 创建 MutationObserver 监听内容变化
|
||||
const observer = new MutationObserver(() => {
|
||||
console.log('editorBody at line 313:', editorBody);
|
||||
// _this.updateTableStyles(editorBody, _this.typesettingType);
|
||||
// const hasHorizontalScrollbar = editorBody.scrollWidth > editorBody.clientWidth;
|
||||
// if (hasHorizontalScrollbar) {
|
||||
// console.log('TinyMCE 出现横向滚动条');
|
||||
// } else {
|
||||
// console.log('没有横向滚动条');
|
||||
// }
|
||||
});
|
||||
|
||||
// 监听子节点和内容的变化
|
||||
observer.observe(editorBody, { childList: true, subtree: true, characterData: true });
|
||||
});
|
||||
// 定义自定义按钮
|
||||
ed.ui.registry.addButton('clearButton', {
|
||||
text: 'Empty',
|
||||
|
||||
onAction: () => {
|
||||
// 插入自定义表格到编辑器中
|
||||
ed.setContent('');
|
||||
}
|
||||
});
|
||||
|
||||
// 定义自定义按钮
|
||||
ed.ui.registry.addButton('customButtonExportWord', {
|
||||
text: _this.$t('commonTable.exportWord'),
|
||||
onAction: () => {
|
||||
// 插入自定义表格到编辑器中
|
||||
let content = ed.getContent(); // 获取内容
|
||||
content = content.replace(/<strong>/g, '<b>').replace(/<\/strong>/g, '</b>');
|
||||
content = content.replace(/<em>/g, '<i>').replace(/<\/strong>/g, '</i>');
|
||||
const container = document.createElement('div');
|
||||
container.innerHTML = content;
|
||||
|
||||
_this.export('table', _this.$commonJS.updateTableStyles(container, _this.typesettingType, 1));
|
||||
}
|
||||
});
|
||||
// 定义自定义按钮
|
||||
ed.ui.registry.addButton('customButtonExportImg', {
|
||||
text: _this.$t('commonTable.exportImg'),
|
||||
onAction: () => {
|
||||
// 插入自定义表格到编辑器中
|
||||
_this.export('image', ed.getContent());
|
||||
}
|
||||
});
|
||||
ed.ui.registry.addContextToolbar('spacer', {
|
||||
predicate: () => false, // 保持静态
|
||||
items: '',
|
||||
scope: 'node'
|
||||
});
|
||||
ed.on('paste', (event) => {});
|
||||
ed.on('SetContent', function (e) {
|
||||
e.content = e.content.replace(/<strong>/g, '<b>').replace(/<\/strong>/g, '</b>');
|
||||
e.content = e.content.replace(/<em>/g, '<i>').replace(/<\/em>/g, '</i>');
|
||||
});
|
||||
ed.on('GetContent', function (e) {
|
||||
e.content = e.content.replace(/<b>/g, '<strong>').replace(/<\/b>/g, '</strong>');
|
||||
e.content = e.content.replace(/<i>/g, '<em>').replace(/<\/i>/g, '</em>');
|
||||
});
|
||||
},
|
||||
init_instance_callback: (editor) => {
|
||||
if (_this.value) {
|
||||
editor.setContent(_this.value);
|
||||
}
|
||||
_this.hasInit = true;
|
||||
editor.on('NodeChange Change KeyUp SetContent', () => {
|
||||
this.hasChange = true;
|
||||
this.$emit('input', editor.getContent());
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
// 提取 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());
|
||||
console.log('window.tinymce.get(this.tinymceId).getContent() at line 431:', 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;
|
||||
}
|
||||
</style>
|
||||
@@ -8,8 +8,7 @@ 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 =
|
||||
'uploadWord|undo redo | formatselect | bold italic | forecolor |subscript superscript|table tabledelete |customButtonExportWord |customButtonExportImg |customDropdown | clearButton';
|
||||
|
||||
const tableStyle = ` b span{
|
||||
font-weight: bold !important;
|
||||
}
|
||||
@@ -22,11 +21,23 @@ const tableStyle = ` b span{
|
||||
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;
|
||||
margin : 0 auto !important;
|
||||
table-layout: auto; /* 自动调整列宽 */
|
||||
text-align:left;
|
||||
font-family:'Charis SIL' !important;
|
||||
@@ -47,7 +58,8 @@ const tableStyle = ` b span{
|
||||
line-height: 10pt !important;
|
||||
mos-line-height: 10pt !important;
|
||||
}
|
||||
table tr td{
|
||||
table tbody tr td{
|
||||
|
||||
text-align:left !important;
|
||||
border-left:none !important;
|
||||
mso-border-left-alt:none !important;
|
||||
@@ -56,14 +68,18 @@ const tableStyle = ` b span{
|
||||
border-top:none;mso-border-top-alt:none !important;
|
||||
border-bottom:none !important;
|
||||
mso-border-bottom-alt:none !important;
|
||||
border:1px dashed #dcdfe6 !important;
|
||||
border-left:1px dashed #dcdfe6 !important;
|
||||
border-right:1px dashed #dcdfe6 !important;
|
||||
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{
|
||||
display:flex;text-align:left !important;
|
||||
align-items:center;
|
||||
|
||||
text-align:left !important;
|
||||
|
||||
margin:0;
|
||||
font-family:'Charis SIL' !important;
|
||||
font-size: 7.5000pt !important;
|
||||
@@ -72,6 +88,7 @@ const tableStyle = ` b span{
|
||||
mos-line-height: 10pt !important;
|
||||
}
|
||||
table span{
|
||||
|
||||
color:#000000;text-align:left !important;
|
||||
font-family:'Charis SIL' !important;
|
||||
font-size: 7.5000pt !important;
|
||||
@@ -93,15 +110,23 @@ const tableStyle = ` b span{
|
||||
table tr:last-of-type td {
|
||||
border-bottom:1.0000pt solid #000 !important;mso-border-bottom-alt:0.5000pt solid #000 !important;;
|
||||
}
|
||||
|
||||
|
||||
|
||||
`;
|
||||
export default {
|
||||
name: 'tinymce',
|
||||
components: {},
|
||||
props: {
|
||||
isAutomaticUpdate: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
id: {
|
||||
type: String
|
||||
},
|
||||
type: {
|
||||
type: String
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
@@ -188,6 +213,7 @@ export default {
|
||||
},
|
||||
watch: {
|
||||
value(val) {
|
||||
console.log('val at line 208:', val);
|
||||
if (!this.hasChange && this.hasInit) {
|
||||
this.$nextTick(() => window.tinymce.get(this.tinymceId).setContent(val));
|
||||
}
|
||||
@@ -244,13 +270,52 @@ export default {
|
||||
table_resize_bars: true, // 启用拖动调整功能
|
||||
valid_elements: '*[*]', // 允许所有 HTML 标签
|
||||
|
||||
height: this.height,
|
||||
paste_preprocess: function (plugin, args) {
|
||||
let content = args.content;
|
||||
const container = document.createElement('div');
|
||||
container.innerHTML = content;
|
||||
_this.updateTableStyles(container);
|
||||
args.content = container.innerHTML; // 更新内容
|
||||
// 阻止默认的粘贴行为
|
||||
if (args.event) {
|
||||
args.event.preventDefault(); // 阻止默认的粘贴处理
|
||||
args.event.stopPropagation(); // 阻止事件冒泡,确保自定义处理优先执行
|
||||
}
|
||||
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;">
|
||||
${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>
|
||||
`;
|
||||
|
||||
const container = document.createElement('div');
|
||||
container.innerHTML = contentHtml;
|
||||
|
||||
// _this.updateTableStyles(container); // 根据需要应用额外的样式
|
||||
args.content = container.innerHTML; // 更新处理后的内容
|
||||
});
|
||||
} else if (_this.isAutomaticUpdate) {
|
||||
args.content = _this.$commonJS.transformHtmlString(args.content); // 更新处理后的内容
|
||||
}
|
||||
},
|
||||
|
||||
content_style: `${tableStyle}`,
|
||||
formats: {
|
||||
bold: { inline: 'b' },
|
||||
@@ -316,14 +381,11 @@ export default {
|
||||
const editorBody = ed.getBody();
|
||||
// 创建 MutationObserver 监听内容变化
|
||||
const observer = new MutationObserver(() => {
|
||||
console.log('editorBody at line 313:', editorBody);
|
||||
// _this.updateTableStyles(editorBody, _this.typesettingType);
|
||||
// const hasHorizontalScrollbar = editorBody.scrollWidth > editorBody.clientWidth;
|
||||
// if (hasHorizontalScrollbar) {
|
||||
// console.log('TinyMCE 出现横向滚动条');
|
||||
// } else {
|
||||
// console.log('没有横向滚动条');
|
||||
// }
|
||||
const currentContent = ed.getContent();
|
||||
|
||||
if (_this.isAutomaticUpdate) {
|
||||
_this.$emit('updateChange', ed.getContent());
|
||||
}
|
||||
});
|
||||
|
||||
// 监听子节点和内容的变化
|
||||
@@ -366,7 +428,7 @@ export default {
|
||||
items: '',
|
||||
scope: 'node'
|
||||
});
|
||||
ed.on('paste', (event) => {});
|
||||
|
||||
ed.on('SetContent', function (e) {
|
||||
e.content = e.content.replace(/<strong>/g, '<b>').replace(/<\/strong>/g, '</b>');
|
||||
e.content = e.content.replace(/<em>/g, '<i>').replace(/<\/em>/g, '</i>');
|
||||
@@ -411,6 +473,7 @@ export default {
|
||||
//获取内容
|
||||
getContent(type) {
|
||||
this.$emit('getContent', type, window.tinymce.get(this.tinymceId).getContent());
|
||||
console.log('window.tinymce.get(this.tinymceId).getContent() at line 431:', window.tinymce.get(this.tinymceId).getContent());
|
||||
},
|
||||
|
||||
async export(type, data) {
|
||||
@@ -418,7 +481,7 @@ export default {
|
||||
var tableHtml = `<html xmlns:w="urn:schemas-microsoft-com:office:word">
|
||||
<head>
|
||||
<style>
|
||||
|
||||
|
||||
${tableStyle}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
200
src/components/page/components/table/annotations.vue
Normal file
@@ -0,0 +1,200 @@
|
||||
<template>
|
||||
<div style="height: 100%; position: relative">
|
||||
<div class="comments-section" style="width: calc(300px); height: 100%" v-if="isShowComment">
|
||||
<h5>{{ $t('commonTable.AnnotationList') }}</h5>
|
||||
<ul style="margin-top: 10px" v-if="comments.length > 0">
|
||||
<li v-for="(comment, index) in comments" :key="index" class="comment-item" style="padding: 6px 0">
|
||||
<div @click.prevent="goToComment(comment.mId)">
|
||||
<p style="display: flex; align-items: center; justify-content: space-between">
|
||||
<el-link>
|
||||
<span style="color: rgb(43, 129, 239)"
|
||||
><i class="el-icon-chat-dot-square" style="color: rgb(43, 129, 239)"></i> {{ index + 1 }}</span
|
||||
></el-link
|
||||
>
|
||||
|
||||
<span style="color: #b8b7b7">{{ getTime(comment.time) }}</span>
|
||||
</p>
|
||||
|
||||
<!-- 当 isEditing 为 true 时,显示可编辑的输入框 -->
|
||||
<div v-if="isEditing === index">
|
||||
<el-input
|
||||
v-focus
|
||||
type="textarea"
|
||||
v-model="comment.text"
|
||||
@blur="saveComment(index)"
|
||||
style="width: 100%; box-sizing: border-box; padding: 5px"
|
||||
></el-input>
|
||||
</div>
|
||||
|
||||
<!-- 当 isEditing 为 false 时,显示评论文本 -->
|
||||
<div v-else style="display: flex; align-items: center; justify-content: space-between">
|
||||
<p @click="editComment(index)" style="min-height: 20px; width: calc(100% - 20px)">
|
||||
{{ comment.text }}
|
||||
<!-- <span @click="editComment(index)" style="cursor: pointer; color: #007bff; margin-left: 10px;">修改</span> -->
|
||||
</p>
|
||||
|
||||
<i class="el-icon-delete" @click="deleteComment(comment, index)" style="color: #cd5454"></i>
|
||||
</div>
|
||||
|
||||
<!-- 删除按钮 -->
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<ul v-else style="color: #b0b0b0; text-align: center; margin-top: 60px">
|
||||
No Data
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ['articleId'],
|
||||
data() {
|
||||
return {
|
||||
isShowComment: false,
|
||||
isEditing: null, // 用于跟踪当前正在编辑的批注索引
|
||||
selectedComment: null, // 存储当前选择的批注内容
|
||||
comments: [] // 存储所有批注
|
||||
};
|
||||
},
|
||||
directives: {
|
||||
// 注册一个局部的自定义指令 v-focus
|
||||
focus: {
|
||||
// 指令的定义
|
||||
inserted: function (el) {
|
||||
console.log('el at line 263:', el);
|
||||
// 聚焦元素
|
||||
el.querySelector('textarea').focus();
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
|
||||
methods: {
|
||||
changeComment() {
|
||||
this.isShowComment = !this.isShowComment;
|
||||
},
|
||||
// 编辑评论,显示文本框
|
||||
editComment(index) {
|
||||
this.isEditing = index; // 设置当前正在编辑的评论索引
|
||||
|
||||
},
|
||||
|
||||
// 保存评论修改
|
||||
saveComment(index) {
|
||||
this.isEditing = null; // 退出编辑模式
|
||||
|
||||
},
|
||||
|
||||
// 删除评论
|
||||
deleteComment(comment, index) {
|
||||
this.$confirm(this.$t('commonTable.removeAnnotations'), 'Prompt', {
|
||||
confirmButtonText: 'Submit',
|
||||
cancelButtonText: 'Cancel',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
this.comments.splice(index, 1); // 删除评论
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
getTime(timestamp) {
|
||||
// 创建一个新的 Date 对象
|
||||
var date = new Date(timestamp);
|
||||
|
||||
// 获取年月日时分格式
|
||||
var year = date.getFullYear();
|
||||
var month = date.getMonth() + 1; // 月份从 0 开始,所以要加 1
|
||||
var day = date.getDate();
|
||||
var hours = date.getHours();
|
||||
var minutes = date.getMinutes();
|
||||
|
||||
// 格式化输出
|
||||
var formattedDate =
|
||||
year +
|
||||
'-' +
|
||||
(month < 10 ? '0' + month : month) +
|
||||
'-' +
|
||||
(day < 10 ? '0' + day : day) +
|
||||
' ' +
|
||||
(hours < 10 ? '0' + hours : hours) +
|
||||
':' +
|
||||
(minutes < 10 ? '0' + minutes : minutes);
|
||||
|
||||
return formattedDate;
|
||||
},
|
||||
goToComment(mainId) {
|
||||
this.$nextTick(() => {
|
||||
this.$emit('goToComment',mainId);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.comments-section {
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #cecfd3;
|
||||
border-left: 2px solid #cecfd3;
|
||||
/* border-radius: 5px; */
|
||||
background-color: #f9f9f9;
|
||||
box-shadow: rgba(16, 17, 19, 0.06) 0px 1px 3px;
|
||||
width: 300px;
|
||||
background-color: #fafafa;
|
||||
float: right;
|
||||
position: absolute;
|
||||
right: -302px;
|
||||
top: 0px;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.comment-item {
|
||||
padding: 5px 0;
|
||||
border-bottom: 1px solid #ddd;
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.comment-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.comment-details {
|
||||
margin-top: 20px;
|
||||
padding: 10px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 5px;
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.comment-details h3 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.comment-details p {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.comment-details button {
|
||||
padding: 5px 10px;
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.comment-details button:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
.comments-section ul,
|
||||
.comments-section li {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
148
src/components/page/components/table/content.vue
Normal file
@@ -0,0 +1,148 @@
|
||||
<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; /* 字体大小 */
|
||||
|
||||
margin-top: 0pt; /* 段前间距 */
|
||||
margin-bottom: 0pt; /* 段后间距 */
|
||||
"
|
||||
></tinymce>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import Tinymce from '@/components/page/components/Tinymce';
|
||||
export default {
|
||||
props: ['lineStyle'],
|
||||
components: {
|
||||
Tinymce
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showToolbar: false, // 是否显示工具栏
|
||||
toolbarStyle: {
|
||||
top: '0px',
|
||||
left: '0px'
|
||||
}, // 工具栏的样式
|
||||
selectionRange: null, // 保存选区范围
|
||||
updatedHtml: '',
|
||||
imgHtml: '',
|
||||
typesettingTypeOptions: [
|
||||
{ label: this.$t('commonTable.typesettingType1'), value: 1, pageWidth: 210 },
|
||||
{ label: this.$t('commonTable.typesettingType2'), value: 2, pageWidth: 297 }
|
||||
],
|
||||
transform: null,
|
||||
typesettingType: 1
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.typesettingType = 1;
|
||||
},
|
||||
methods: {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
border: 1px dashed #dcdfe6;
|
||||
padding: 8px;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
table {
|
||||
border-top: 2px solid #000;
|
||||
border-bottom: 1px solid #000;
|
||||
}
|
||||
th {
|
||||
border-bottom: 1px solid #000;
|
||||
}
|
||||
th input,
|
||||
td input {
|
||||
width: 100%;
|
||||
border: none;
|
||||
outline: none;
|
||||
text-align: center;
|
||||
}
|
||||
th input,
|
||||
td input ::placeholder {
|
||||
color: #aaa !important;
|
||||
}
|
||||
|
||||
.controls {
|
||||
margin: 0 0 20px;
|
||||
}
|
||||
|
||||
.drag-handle {
|
||||
cursor: move;
|
||||
}
|
||||
::v-deep .paste-area {
|
||||
height: auto; /* A4纸高度 */
|
||||
background: white; /* 纸张背景 */
|
||||
|
||||
/* padding: 25.4mm 19.1mm; //内边距 */
|
||||
box-sizing: border-box; /* 确保内边距不会影响整体尺寸 */
|
||||
transform-origin: top left;
|
||||
}
|
||||
::v-deep .paste-area table {
|
||||
/* border-top: 2px solid #000 !important; */
|
||||
/* border-bottom: 1px solid #000 !important; */
|
||||
margin-left: 0 !important;
|
||||
margin-right: 0 !important;
|
||||
margin: 0 auto !important;
|
||||
}
|
||||
::v-deep .paste-area table td {
|
||||
border-top: none !important;
|
||||
border-bottom: none !important;
|
||||
border: 1px dashed #dcdfe6 !important;
|
||||
/* display: flex;
|
||||
align-items: center; */
|
||||
}
|
||||
::v-deep .paste-area table td p {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
::v-deep .paste-area table .MsoNormal {
|
||||
max-width: 200px !important; /* 限制容器宽度 */
|
||||
|
||||
word-wrap: break-word !important;
|
||||
overflow-wrap: break-word !important;
|
||||
}
|
||||
.text-container {
|
||||
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
@@ -1,54 +1,38 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 拖拽区域 -->
|
||||
<div class="drag-drop-area" @dragover.prevent="onDragOver" @dragleave="onDragLeave" @drop.prevent="onDrop" @click="clickUpload">
|
||||
<p>将 Word 文件拖拽到此处</p>
|
||||
<div class="" @dragover.prevent="onDragOver" @dragleave="onDragLeave" @drop.prevent="onDrop" @click="clickUpload">
|
||||
<img src="@/assets/img/word.png" alt="" style="width: 30px; height: 30px" />
|
||||
</div>
|
||||
<el-dialog
|
||||
<div v-html="tablesHtml" class="wordTableHtml"></div>
|
||||
|
||||
<!-- <el-dialog
|
||||
append-to-body
|
||||
title="Add Academic Integrity Committee"
|
||||
:visible.sync="addVisible"
|
||||
width="660px"
|
||||
width="80%"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<div v-if="tables.length > 0" class="preview-area">
|
||||
<div v-for="(table, index) in tables" :key="index" class="table-wrapper">
|
||||
<h3>Table {{ index + 1 }}</h3>
|
||||
<div v-html="table.html" class="table-preview"></div>
|
||||
|
||||
<div class="table-options">
|
||||
<label>
|
||||
页面方向:
|
||||
<select v-model="table.orientation">
|
||||
<option value="portrait">纵向</option>
|
||||
<option value="landscape">横向</option>
|
||||
</select>
|
||||
</label>
|
||||
<button @click="confirmTable(index)">确认表格</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="addVisCancle">Cancel</el-button>
|
||||
<el-button type="primary" @click="saveAdd()" v-if="dis_able">OK</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
|
||||
</el-dialog> -->
|
||||
<!-- 表格预览区 -->
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import JSZip from 'jszip';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
tablesHtml: '',
|
||||
tables: [], // 保存解析后的表格数据
|
||||
addVisible: false
|
||||
};
|
||||
},
|
||||
components: {},
|
||||
methods: {
|
||||
addVisCancle(){
|
||||
this.addVisible = false;
|
||||
addVisCancle() {
|
||||
this.addVisible = false;
|
||||
},
|
||||
clickUpload() {
|
||||
this.tables = [];
|
||||
@@ -62,9 +46,16 @@ this.addVisible = false;
|
||||
const reader = new FileReader();
|
||||
reader.onload = function (e) {
|
||||
const arrayBuffer = e.target.result;
|
||||
that.extractTablesFromWord(arrayBuffer, function (tablesHtml) {
|
||||
console.log('tablesHtml at line 61:', that.tables);
|
||||
that.addVisible = true;
|
||||
|
||||
that.$commonJS.extractWordTablesToArrays(file, function (wordTables) {
|
||||
console.log('tablesHtml at line 61:', wordTables);
|
||||
that.tables = wordTables;
|
||||
that.$commonJS.getWordTablesThumbnails(wordTables, function (html) {
|
||||
console.log('html at line 78:', html);
|
||||
that.tablesHtml = html;
|
||||
that.addVisible = true;
|
||||
});
|
||||
that.$emit('tables', that.tables, html);
|
||||
});
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
@@ -80,44 +71,6 @@ this.addVisible = false;
|
||||
event.currentTarget.style.borderColor = '#ccc';
|
||||
},
|
||||
|
||||
// 提取 Word 文件中的表格
|
||||
extractTablesFromWord(arrayBuffer, callback) {
|
||||
const zip = new JSZip();
|
||||
var that = this;
|
||||
zip.loadAsync(arrayBuffer)
|
||||
.then(function (zip) {
|
||||
const docXmlPath = 'word/document.xml'; // Word 主文档的 XML 路径
|
||||
return zip.file(docXmlPath).async('string');
|
||||
})
|
||||
.then(function (docXml) {
|
||||
const parser = new DOMParser();
|
||||
const xmlDoc = parser.parseFromString(docXml, 'text/xml');
|
||||
const tables = xmlDoc.getElementsByTagName('w:tbl'); // 查找 Word 表格标签
|
||||
|
||||
let html = '';
|
||||
for (let table of tables) {
|
||||
var str = that.convertTableToHtml(table);
|
||||
const container = document.createElement('div');
|
||||
container.innerHTML = str;
|
||||
that.tables.push({
|
||||
html: that.updateTableStyles(container),
|
||||
orientation: 'portrait' // 默认纵向
|
||||
});
|
||||
|
||||
html += str;
|
||||
}
|
||||
|
||||
if (!html) {
|
||||
html = '<p>未检测到表格内容。</p>';
|
||||
}
|
||||
|
||||
callback(html);
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error('解析 Word 文件出错:', err);
|
||||
callback('<p>文件解析失败,请检查文件格式。</p>');
|
||||
});
|
||||
},
|
||||
async onDrop(event) {
|
||||
const file = event.dataTransfer.files[0];
|
||||
if (!file || !file.name.endsWith('.docx')) {
|
||||
@@ -176,195 +129,9 @@ this.addVisible = false;
|
||||
reader.readAsArrayBuffer(file);
|
||||
});
|
||||
},
|
||||
// 将 XML 表格转换为 HTML
|
||||
convertTableToHtml(tableNode) {
|
||||
const rows = tableNode.getElementsByTagName('w:tr');
|
||||
let html = '<table border="1" style="border-collapse: collapse;">';
|
||||
for (let row of rows) {
|
||||
html += '<tr>';
|
||||
const cells = row.getElementsByTagName('w:tc');
|
||||
for (let cell of cells) {
|
||||
let cellHtml = '';
|
||||
const paragraphs = cell.getElementsByTagName('w:p'); // 获取单元格内段落
|
||||
|
||||
for (let paragraph of paragraphs) {
|
||||
const texts = paragraph.getElementsByTagName('w:r'); // 获取段落内的文本和样式
|
||||
for (let run of texts) {
|
||||
const textNode = run.getElementsByTagName('w:t')[0];
|
||||
if (textNode) {
|
||||
const style = this.getStyleFromRun(run); // 提取样式
|
||||
cellHtml += `<span style="${style}">${textNode.textContent}</span>`;
|
||||
}
|
||||
}
|
||||
cellHtml += '<br>'; // 段落换行
|
||||
}
|
||||
|
||||
html += `<td>${cellHtml}</td>`;
|
||||
}
|
||||
html += '</tr>';
|
||||
}
|
||||
html += '</table>';
|
||||
|
||||
return html;
|
||||
},
|
||||
|
||||
// 提取 w:r 节点中的样式并转换为 CSS
|
||||
getStyleFromRun(run) {
|
||||
const styleNode = run.getElementsByTagName('w:rPr')[0];
|
||||
let style = '';
|
||||
|
||||
if (styleNode) {
|
||||
// 加粗
|
||||
if (styleNode.getElementsByTagName('w:b').length > 0) {
|
||||
style += 'font-weight: bold;';
|
||||
}
|
||||
// 斜体
|
||||
if (styleNode.getElementsByTagName('w:i').length > 0) {
|
||||
style += 'font-style: italic;';
|
||||
}
|
||||
// 上标或下标
|
||||
const vertAlign = styleNode.getElementsByTagName('w:vertAlign')[0];
|
||||
if (vertAlign) {
|
||||
const alignVal = vertAlign.getAttribute('w:val');
|
||||
if (alignVal === 'superscript') {
|
||||
style += 'vertical-align: super; font-size: smaller;';
|
||||
} else if (alignVal === 'subscript') {
|
||||
style += 'vertical-align: sub; font-size: smaller;';
|
||||
}
|
||||
}
|
||||
// 字体颜色
|
||||
const colorNode = styleNode.getElementsByTagName('w:color')[0];
|
||||
if (colorNode) {
|
||||
const colorVal = colorNode.getAttribute('w:val');
|
||||
style += `color: #${colorVal};`;
|
||||
}
|
||||
}
|
||||
|
||||
return style;
|
||||
},
|
||||
replaceNegativeSign(node) {
|
||||
if (node.nodeType === Node.TEXT_NODE) {
|
||||
// 如果是文本节点,替换负号
|
||||
node.nodeValue = node.nodeValue.replace(/^-(?=\d)/, '−');
|
||||
} else if (node.nodeType === Node.ELEMENT_NODE) {
|
||||
// 如果是元素节点,递归处理子节点
|
||||
node.childNodes.forEach(this.replaceNegativeSign);
|
||||
}
|
||||
},
|
||||
capitalizeFirstLetter(node) {
|
||||
if (node.nodeType === Node.TEXT_NODE) {
|
||||
// 如果是文本节点,只处理第一个非空字符
|
||||
node.nodeValue = node.nodeValue.replace(/^\s*([a-zA-Z])/, (match, firstLetter) => {
|
||||
return firstLetter.toUpperCase();
|
||||
});
|
||||
} else if (node.nodeType === Node.ELEMENT_NODE) {
|
||||
// 递归处理子节点
|
||||
node.childNodes.forEach(this.capitalizeFirstLetter);
|
||||
}
|
||||
},
|
||||
updateTableStyles(container) {
|
||||
var _this = this;
|
||||
// 更新表格样式
|
||||
const tables = container.querySelectorAll('table');
|
||||
tables.forEach((table) => {
|
||||
table.setAttribute(
|
||||
'style',
|
||||
`width: ${
|
||||
this.typesettingType == 1 ? '17.18cm' : '25.88cm'
|
||||
};border: none; margin: 0 auto !important;border-collapse: collapse; `
|
||||
);
|
||||
const cells = table.querySelectorAll('td');
|
||||
cells.forEach((td) => {
|
||||
if (/^-?\d+(\.\d+)?$/.test(td.textContent.trim())) {
|
||||
_this.replaceNegativeSign(td);
|
||||
}
|
||||
const hasSupOrSub = _this.containsSupOrSub(td); // 检查当前 td 是否包含上下标
|
||||
if (!hasSupOrSub) {
|
||||
// 递归处理单元格内的所有子节点
|
||||
td.childNodes.forEach(_this.capitalizeFirstLetter);
|
||||
// 替换 <a> 标签为其内部文本
|
||||
td.querySelectorAll('a').forEach((a) => {
|
||||
const textNode = document.createTextNode(a.textContent); // 创建文本节点
|
||||
a.replaceWith(textNode); // 用文本节点替换 <a> 标签
|
||||
});
|
||||
}
|
||||
|
||||
// 获取 td 元素中的所有子元素
|
||||
const childElements = td.querySelectorAll('*');
|
||||
|
||||
// 遍历每个子元素
|
||||
childElements.forEach((element) => {
|
||||
// 如果元素的文本内容匹配正则表达式
|
||||
if (/\[\d+(?:,\d+)*\]/g.test(element.textContent)) {
|
||||
console.log('匹配到带有数字的方括号内容');
|
||||
// 为匹配的元素添加样式类
|
||||
element.classList.add('color-highlight');
|
||||
element.style.color = 'rgb(0,130,170)';
|
||||
}
|
||||
});
|
||||
});
|
||||
const firstRowTdElements = container.querySelectorAll('tr:first-child td'); // 获取第一个 <tr> 中的所有 <td> 元素
|
||||
// 遍历所有 <td> 元素,添加上下边框样式
|
||||
firstRowTdElements.forEach((td) => {
|
||||
const currentStyle = td.getAttribute('style');
|
||||
if (currentStyle) {
|
||||
td.setAttribute(
|
||||
'style',
|
||||
currentStyle +
|
||||
';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;'
|
||||
);
|
||||
} else {
|
||||
td.setAttribute(
|
||||
'style',
|
||||
'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;'
|
||||
);
|
||||
}
|
||||
});
|
||||
const firstRowTdElementsLast = container.querySelectorAll('tr:last-of-type td');
|
||||
// 遍历所有 <td> 元素,添加上下边框样式
|
||||
firstRowTdElementsLast.forEach((td) => {
|
||||
// 获取当前的 style 属性(如果有)
|
||||
const currentStyle = td.getAttribute('style');
|
||||
// 如果已有 style 属性,则追加边框样式;如果没有 style 属性,则设置新的 style
|
||||
if (currentStyle) {
|
||||
td.setAttribute(
|
||||
'style',
|
||||
currentStyle +
|
||||
';border-bottom:1.0000pt solid #000 !important;mso-border-bottom-alt:0.5000pt solid #000 !important;'
|
||||
);
|
||||
} else {
|
||||
td.setAttribute(
|
||||
'style',
|
||||
'border-bottom:1.0000pt solid #000 !important;mso-border-bottom-alt:0.5000pt solid #000 !important;'
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
console.log('tables.forEach at line 270:', tables);
|
||||
// var editor = window.tinymce.activeEditor;
|
||||
var html = '';
|
||||
tables.forEach((e) => {
|
||||
html += e.outerHTML;
|
||||
console.log('html at line 582:', html);
|
||||
});
|
||||
this.$forceUpdate();
|
||||
return html
|
||||
|
||||
},
|
||||
|
||||
containsSupOrSub(element) {
|
||||
// 如果当前节点是元素节点
|
||||
if (element.nodeType === 1) {
|
||||
// 如果是 <sup> 或 <sub> 标签,返回 true
|
||||
if (element.tagName === 'SUP' || element.tagName === 'SUB') {
|
||||
return true;
|
||||
}
|
||||
// 否则,递归检查子节点
|
||||
return Array.from(element.childNodes).some((child) => this.containsSupOrSub(child));
|
||||
}
|
||||
// 如果不是元素节点(如文本节点),返回 false
|
||||
return false;
|
||||
},
|
||||
|
||||
// 确认表格
|
||||
confirmTable(index) {
|
||||
const table = this.tables[index];
|
||||
@@ -403,4 +170,33 @@ this.addVisible = false;
|
||||
.table-options {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.html-preview {
|
||||
transform: scale(0.5); /* 缩放比例为 50% */
|
||||
transform-origin: top left; /* 缩放基准点为左上角 */
|
||||
|
||||
|
||||
display: inline-block; /* 使内容大小随缩放变化 */
|
||||
}
|
||||
|
||||
|
||||
::v-deep.table-modal-content::-webkit-scrollbar {
|
||||
width: 12px; /* 垂直滚动条的宽度 */
|
||||
height: 12px; /* 水平滚动条的高度 */
|
||||
}
|
||||
|
||||
::v-deep.table-modal-content::-webkit-scrollbar-thumb {
|
||||
background-color: #888; /* 滑块的颜色 */
|
||||
border-radius: 10px; /* 滑块的圆角 */
|
||||
border: 3px solid #f1f1f1; /* 滑块的边框颜色 */
|
||||
}
|
||||
|
||||
::v-deep.table-modal-content::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #555; /* 悬停时的颜色 */
|
||||
}
|
||||
|
||||
::v-deep.table-modal-content::-webkit-scrollbar-track {
|
||||
background-color: #f1f1f1; /* 滚动条背景色 */
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -1,251 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
<div
|
||||
class="paste-area"
|
||||
:style="`width: ${210}mm !important;padding: 25.4mm 19.1mm;`"
|
||||
|
||||
|
||||
> <div
|
||||
class="paste-area"
|
||||
:style="`width: 100% !important;`"
|
||||
|
||||
contenteditable="true"
|
||||
id="content"
|
||||
ref="content"
|
||||
@paste="handlePaste"
|
||||
></div></div>
|
||||
<div class="controls" style="overflow: hidden;"> 请在此区域粘贴 Word 表格
|
||||
<div class="paste-area" contenteditable="true" @paste="handlePaste">
|
||||
|
||||
</div>
|
||||
<!-- <p style="float: left;">Add
|
||||
<el-input style="width: 50px;" v-model="rowsNumber"></el-input>
|
||||
<span> {{ $t('commonTable.rows') }} * </span>
|
||||
<el-input style="width: 50px;" v-model="columnsNumber"></el-input>
|
||||
<span> {{ $t('commonTable.columns') }} {{ $t('commonTable.table') }}</span>
|
||||
|
||||
<el-button style="margin-left: 20px;" @click="Generate">Generate</el-button>
|
||||
</p> -->
|
||||
<p style="float: right;">
|
||||
<el-button @click="addRow">增加行</el-button>
|
||||
<el-button @click="addColumn">增加列</el-button>
|
||||
<el-button @click="mergeCells">合并选中单元格</el-button>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
<table v-if="tableData.length > 0">
|
||||
<tbody>
|
||||
<tr v-for="(row, rowIndex) in tableData" :key="rowIndex">
|
||||
<td v-for="(cell, colIndex) in row" :key="colIndex" contenteditable="true">
|
||||
{{ cell }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!-- <table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th
|
||||
v-for="(header, index) in headers"
|
||||
:key="index"
|
||||
draggable="true"
|
||||
@dragstart="startDrag(index)"
|
||||
@dragover.prevent
|
||||
@drop="dropColumn(index)"
|
||||
>
|
||||
<input v-model="headers[index]" :placeholder="$t('commonTable.headerPlaceholder')" />
|
||||
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(row, rowIndex) in rows" :key="rowIndex">
|
||||
<td
|
||||
v-for="(cell, colIndex) in row"
|
||||
:key="colIndex"
|
||||
@click="selectCell(rowIndex, colIndex)"
|
||||
:colspan="cell.colspan"
|
||||
:rowspan="cell.rowspan"
|
||||
v-if="!cell.merged"
|
||||
>
|
||||
<input v-model="cell.value" placeholder="" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table> -->
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
tableData: [], // 表格数据
|
||||
rowsNumber:'',
|
||||
columnsNumber:'',
|
||||
headers: [], // 表头
|
||||
rows: [
|
||||
[
|
||||
{ value: '', rowspan: 1, colspan: 1, merged: false },
|
||||
{ value: '', rowspan: 1, colspan: 1, merged: false },
|
||||
{ value: '', rowspan: 1, colspan: 1, merged: false }
|
||||
]
|
||||
], // 表格数据
|
||||
selectedCells: [], // 存储选中的单元格
|
||||
draggedColumnIndex: null // 拖拽的列索引
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handlePaste(event) {
|
||||
// event.preventDefault(); // 阻止默认粘贴行为
|
||||
|
||||
// 获取剪贴板 HTML 内容
|
||||
// const clipboardData = event.clipboardData || window.clipboardData;
|
||||
// const htmlData = clipboardData.getData("text/html");
|
||||
|
||||
// if (!htmlData) {
|
||||
// alert("未检测到表格内容!");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// // 创建 DOM 元素解析 HTML
|
||||
// const parser = new DOMParser();
|
||||
// const doc = parser.parseFromString(htmlData, "text/html");
|
||||
// const table = doc.querySelector("table");
|
||||
|
||||
// if (!table) {
|
||||
// alert("粘贴内容中没有表格!");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// // 提取表格数据
|
||||
// const rows = Array.from(table.rows).map(row =>
|
||||
// Array.from(row.cells).map(cell => cell.innerText.trim()) // innerText 保留换行符
|
||||
// );
|
||||
|
||||
// this.tableData = rows; // 更新表格数据
|
||||
},
|
||||
|
||||
Generate(){
|
||||
for(let i=0;i<this.columnsNumber;i++){
|
||||
this.headers.push('')
|
||||
}
|
||||
|
||||
},
|
||||
addRow() {
|
||||
const newRow = this.headers.map(() => ({
|
||||
value: '',
|
||||
rowspan: 1,
|
||||
colspan: 1,
|
||||
merged: false
|
||||
}));
|
||||
this.rows.push(newRow);
|
||||
},
|
||||
addColumn() {
|
||||
this.headers.push(`列${this.headers.length + 1}`);
|
||||
this.rows.forEach((row) => {
|
||||
row.push({ value: '', rowspan: 1, colspan: 1, merged: false });
|
||||
});
|
||||
},
|
||||
startDrag(index) {
|
||||
this.draggedColumnIndex = index;
|
||||
},
|
||||
dropColumn(index) {
|
||||
if (this.draggedColumnIndex === null || this.draggedColumnIndex === index) return;
|
||||
const draggedHeader = this.headers.splice(this.draggedColumnIndex, 1)[0];
|
||||
this.headers.splice(index, 0, draggedHeader);
|
||||
this.rows.forEach((row) => {
|
||||
const draggedCell = row.splice(this.draggedColumnIndex, 1)[0];
|
||||
row.splice(index, 0, draggedCell);
|
||||
});
|
||||
this.draggedColumnIndex = null;
|
||||
},
|
||||
selectCell(rowIndex, colIndex) {
|
||||
this.selectedCells.push({ row: rowIndex, col: colIndex });
|
||||
},
|
||||
mergeCells() {
|
||||
if (this.selectedCells.length < 2) return;
|
||||
|
||||
const rows = this.selectedCells.map((cell) => cell.row);
|
||||
const cols = this.selectedCells.map((cell) => cell.col);
|
||||
|
||||
const minRow = Math.min(...rows);
|
||||
const maxRow = Math.max(...rows);
|
||||
const minCol = Math.min(...cols);
|
||||
const maxCol = Math.max(...cols);
|
||||
|
||||
for (let r = minRow; r <= maxRow; r++) {
|
||||
for (let c = minCol; c <= maxCol; c++) {
|
||||
if (r === minRow && c === minCol) {
|
||||
this.rows[r][c].rowspan = maxRow - minRow + 1;
|
||||
this.rows[r][c].colspan = maxCol - minCol + 1;
|
||||
} else {
|
||||
this.rows[r][c].merged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.selectedCells = [];
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
th, td {
|
||||
border: 1px dashed #DCDFE6;
|
||||
padding: 8px;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
table{
|
||||
border-top: 2px solid #000;
|
||||
border-bottom: 1px solid #000;
|
||||
}
|
||||
th{
|
||||
border-bottom: 1px solid #000;
|
||||
}
|
||||
th input, td input {
|
||||
width: 100%;
|
||||
border: none;
|
||||
outline: none;
|
||||
text-align: center;
|
||||
}
|
||||
th input, td input ::placeholder{
|
||||
color:#aaa !important;
|
||||
}
|
||||
|
||||
.controls {
|
||||
margin:0 0 20px;
|
||||
}
|
||||
|
||||
.drag-handle {
|
||||
cursor: move;
|
||||
}
|
||||
::v-deep .paste-area {
|
||||
width: 100%;
|
||||
|
||||
}
|
||||
::v-deep .paste-area .MsoNormalTable{
|
||||
border-top: 2px solid #000 !important;
|
||||
border-bottom: 1px solid #000 !important;
|
||||
margin-left: 0!important;
|
||||
margin-right: 0!important;
|
||||
margin: 0 auto !important;
|
||||
|
||||
}
|
||||
::v-deep .paste-area .MsoNormalTable td{
|
||||
border-top: none !important;
|
||||
border-bottom: none !important;
|
||||
border: 1px dashed #DCDFE6 !important;
|
||||
}
|
||||
</style>
|
||||
@@ -1,45 +1,49 @@
|
||||
<template>
|
||||
<div>
|
||||
<div>
|
||||
<!-- <el-select v-model="typesettingType">
|
||||
<el-option v-for="item in typesettingTypeOptions" :key="item.value" :label="item.label" :value="item.value"> </el-option>
|
||||
</el-select> -->
|
||||
<!-- <span style="margin-left:10px ;">请在下面区域粘贴 Word 表格</span> -->
|
||||
<!--uploadWord |customButtonExportWord |customButtonExportImg -->
|
||||
|
||||
<tinymce
|
||||
|
||||
ref="tinymceChild"
|
||||
:value="updatedHtml"
|
||||
:typesettingType="typesettingType"
|
||||
class="paste-area text-container"
|
||||
|
||||
|
||||
style="
|
||||
white-space: pre-line;
|
||||
line-height: 12px;
|
||||
max-height: 50vh;
|
||||
overflow: auto;
|
||||
font-size: 12px;
|
||||
font-size: 7.5pt; /* 字体大小 */
|
||||
type="table"
|
||||
ref="tinymceChild1"
|
||||
@getContent="getContent"
|
||||
:value="updatedHtml"
|
||||
:typesettingType="typesettingType"
|
||||
class="paste-area text-container"
|
||||
:toolbar="`undo redo | formatselect | bold italic ${
|
||||
identity ? '| forecolor' : ''
|
||||
} |subscript superscript|table tabledelete ${identity ? '| customDropdown' : ''} | 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>
|
||||
margin-top: 0pt; /* 段前间距 */
|
||||
margin-bottom: 0pt; /* 段后间距 */
|
||||
"
|
||||
></tinymce>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import Tinymce from '@/components/page/components/Tinymce';
|
||||
export default {
|
||||
props: ['lineStyle'],
|
||||
components: {
|
||||
Tinymce
|
||||
},
|
||||
watch: {
|
||||
lineStyle() {}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableData: [],
|
||||
identity: localStorage.getItem('U_role'),
|
||||
showToolbar: false, // 是否显示工具栏
|
||||
toolbarStyle: {
|
||||
top: '0px',
|
||||
@@ -58,15 +62,60 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
this.typesettingType = 1;
|
||||
if (this.lineStyle) {
|
||||
console.log('newVal at line 37:', this.lineStyle);
|
||||
if (this.lineStyle.table) {
|
||||
this.tableData = [...this.lineStyle.table];
|
||||
var modalContent = `
|
||||
<div class="wordTableHtml" >
|
||||
<table
|
||||
border="1"
|
||||
style="
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
table-layout: auto;"
|
||||
>`;
|
||||
this.tableData.forEach((row) => {
|
||||
modalContent += `<tr>`;
|
||||
row.forEach((cell) => {
|
||||
modalContent += `
|
||||
<td
|
||||
colspan="${cell.colspan || 1}"
|
||||
rowspan="${cell.rowspan || 1}"
|
||||
style=""
|
||||
>
|
||||
<span>${cell.text}</span>
|
||||
</td>`;
|
||||
});
|
||||
modalContent += `</tr>`;
|
||||
});
|
||||
modalContent += `</table></div>`;
|
||||
console.log('modalContent at line 91:', modalContent);
|
||||
this.updatedHtml = modalContent;
|
||||
}
|
||||
// this.updatedHtml = newVal.html_data;
|
||||
} else {
|
||||
this.updatedHtml = '';
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
getTableContent(type) {
|
||||
this.$refs.tinymceChild1.getContent(type);
|
||||
},
|
||||
getContent(type, content) {
|
||||
if (content) {
|
||||
const container = document.createElement("div");
|
||||
container.innerHTML = content;
|
||||
this.$commonJS.parseTableToArray(content, (table) => {
|
||||
console.log('res at line 104:', table);
|
||||
|
||||
this.$emit('getContent', type, { html_data: content, table: table });
|
||||
});
|
||||
} else {
|
||||
this.$emit('getContent', type, { html_data: '', table: [] });
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -114,7 +163,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;
|
||||
@@ -144,8 +193,5 @@ td input ::placeholder {
|
||||
overflow-wrap: break-word !important;
|
||||
}
|
||||
.text-container {
|
||||
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
39
src/components/page/components/table/tiff.vue
Normal file
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<div ref="tiffContainer" class="tiff-container"></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Tiff from 'tiff.js';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
imageSrc: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.loadTiffImage();
|
||||
},
|
||||
methods: {
|
||||
loadTiffImage() {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', this.imageSrc, true);
|
||||
xhr.responseType = 'arraybuffer';
|
||||
xhr.onload = () => {
|
||||
const tiff = new Tiff({ buffer: xhr.response });
|
||||
const canvas = tiff.toCanvas();
|
||||
this.$refs.tiffContainer.appendChild(canvas);
|
||||
};
|
||||
xhr.send();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.tiff-container {
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
|
||||
840
src/components/page/components/table/word.vue
Normal file
@@ -0,0 +1,840 @@
|
||||
<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 td {
|
||||
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
|
||||
},
|
||||
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;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
img{
|
||||
max-width:580px;
|
||||
}
|
||||
`,
|
||||
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.on('click', function (e) {
|
||||
// 判断点击的是否是目标元素
|
||||
const target = e.target;
|
||||
console.log('target at line 351:', target);
|
||||
|
||||
if (target.classList.contains('isRemarkIcon')) {
|
||||
_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);
|
||||
}
|
||||
|
||||
// 获取 TinyMCE iframe 内部的 document 对象
|
||||
|
||||
// 监听 TinyMCE iframe 内容区域的滚动事件
|
||||
|
||||
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>
|
||||
749
src/components/page/components/table/wordHtml.vue
Normal file
@@ -0,0 +1,749 @@
|
||||
<template>
|
||||
<div
|
||||
style="background-color: transparent !important; margin-top: 0px !important; height: 100%; padding: 0 !important; overflow: hidden"
|
||||
class="ManuscirptList"
|
||||
v-show="tables.length > 0 || images.length > 0"
|
||||
>
|
||||
<!-- 图片缩略图区域 -->
|
||||
|
||||
|
||||
<div style="width: 100%; padding: 10px; height: 100%; box-sizing: border-box; overflow-y: auto" class="arrlist">
|
||||
<ul style="width: 100%; height: auto">
|
||||
<el-collapse v-model="activeNames" @change="changeActiveNames"
|
||||
><el-collapse-item name="images" style="" v-if="images.length > 0">
|
||||
<template slot="title">
|
||||
<p style="font-weight: bold; color: #222 !important">Manuscirpt Figures ( {{ images.length }} )</p>
|
||||
|
||||
<!-- <p style="margin-left: 20px">
|
||||
<i class="header-icon el-icon-info"></i
|
||||
><span style="margin-left: 5px; color: rgb(153, 153, 153)">Click to open the Figures</span>
|
||||
</p> -->
|
||||
</template>
|
||||
<!-- <p style="margin-bottom: 15px;color: rgb(153, 153, 153);line-height: 16px;"> If you have any questions that need to be addressed to the author, you can leave valuable comments or suggestions below the Figures</p> -->
|
||||
|
||||
<li >
|
||||
<div class="go-content-charts-item-box" style="display: flex; flex-wrap: wrap; gap: 10px; justify-content: start">
|
||||
|
||||
<div
|
||||
class="item_box"
|
||||
v-for="(img, index) in images"
|
||||
style="width: 180px; height: auto; position: relative"
|
||||
:key="index"
|
||||
>
|
||||
<div class="list-center go-flex-center go-transition" style="width: 100%">
|
||||
<div class="title">
|
||||
<span
|
||||
>Figure {{ index + 1 }}
|
||||
<span
|
||||
@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> -->
|
||||
</span>
|
||||
<a :href="mediaUrl + img.image.url" style="color: #000" v-else>
|
||||
<!-- <el-tooltip class="item" effect="dark" :content="$t('commonTable.preview')" placement="top"> -->
|
||||
<i class="el-icon-download" style="font-size: 16px"></i>
|
||||
<!-- </el-tooltip> -->
|
||||
</a>
|
||||
</span>
|
||||
|
||||
</div>
|
||||
|
||||
<span
|
||||
v-if="img.has_selected == 1"
|
||||
@click="goToListComment(img.article_image_id, 'img')"
|
||||
style="
|
||||
text-align: center;
|
||||
height: 20px;
|
||||
padding: 2px 0;
|
||||
line-height: 20px;
|
||||
width: 60px;
|
||||
z-index: 10;
|
||||
border-radius: 4px;
|
||||
background-color: #006699d1;
|
||||
color: #ffff;
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
top: 45%;
|
||||
left: calc((100% - 60px) / 2);
|
||||
"
|
||||
>{{ $t('commonTable.Typed') }}</span
|
||||
>
|
||||
<div
|
||||
class="thumbnailBox image list-img"
|
||||
:style="`
|
||||
opacity:${img.has_selected == 1 ? '0.6' : '1'};
|
||||
border: 1px solid #ccccccb5;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
position: relative;`"
|
||||
|
||||
>
|
||||
<div 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
|
||||
: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
|
||||
:data-img-id="img.article_image_id"
|
||||
:src="img.dataUrl"
|
||||
style="width: 140px; height: 100%; object-fit: cover"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
|
||||
<div
|
||||
style="
|
||||
width: 140px;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
font-size: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
"
|
||||
>
|
||||
{{ img.image.split('.').pop().toUpperCase() }}
|
||||
<!-- <i class="el-icon-download" style="margin-left: 10px; color: #75abf1"></i> -->
|
||||
</div>
|
||||
<!-- </a> -->
|
||||
</template>
|
||||
</div>
|
||||
<!-- 输入框 -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-collapse v-if="isShowEdit">
|
||||
<el-collapse-item name="1" style="margin-top: 4px">
|
||||
<template slot="title">
|
||||
<div style="width: 100%; display: flex; align-items: center; justify-content: space-between">
|
||||
<span style="color: #777">Tables {{ index + 1 }}</span>
|
||||
<span v-if="isShowEdit"><i class="el-icon-edit" v-if="isEdit"></i>Comments/ Suggestions</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-input
|
||||
v-if="isShowEdit"
|
||||
type="textarea"
|
||||
placeholder="please input content"
|
||||
:readonly="!isEdit"
|
||||
:rows="4"
|
||||
></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>
|
||||
</li>
|
||||
|
||||
</el-collapse-item>
|
||||
<el-collapse-item name="tables" style="" v-if="tables.length > 0">
|
||||
<template slot="title">
|
||||
<p style="font-weight: bold; color: #222">Manuscirpt Tables ( {{ tables.length }} )</p>
|
||||
|
||||
<!-- <p style="margin-left: 20px">
|
||||
<i class="header-icon el-icon-info"></i
|
||||
><span style="margin-left: 5px; color: rgb(153, 153, 153)">Click to open the Tables</span>
|
||||
</p> -->
|
||||
</template>
|
||||
<!-- <p style="margin-bottom: 15px;color: rgb(153, 153, 153);line-height: 16px;"> If you have any questions that need to be addressed to the author, you can leave valuable comments or suggestions below the Table</p> -->
|
||||
<!-- 表格缩略图区域 -->
|
||||
|
||||
<li >
|
||||
<div class="go-content-charts-item-box" style="display: flex; flex-wrap: wrap; gap: 10px; justify-content: start; margin-top: 20px">
|
||||
|
||||
|
||||
<div
|
||||
class="item_box"
|
||||
v-for="(table, index) in tables"
|
||||
style="width: 180px; height: auto; position: relative"
|
||||
:key="index"
|
||||
>
|
||||
<div class="list-center go-flex-center go-transition" style="width: 100%">
|
||||
<div class="title">
|
||||
<span
|
||||
>Table {{ index + 1 }}
|
||||
<span @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
|
||||
></span>
|
||||
|
||||
</div>
|
||||
|
||||
<span
|
||||
v-if="table.has_selected == 1"
|
||||
@click="goToListComment(table.article_table_id, 'table')"
|
||||
style="
|
||||
text-align: center;
|
||||
height: 20px;
|
||||
padding: 2px 0;
|
||||
line-height: 20px;
|
||||
width: 60px;
|
||||
z-index: 10;
|
||||
border-radius: 4px;
|
||||
background-color: #006699d1;
|
||||
color: #ffff;
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
top: 45%;
|
||||
left: calc((100% - 60px) / 2);
|
||||
"
|
||||
>{{ $t('commonTable.Typed') }}</span
|
||||
>
|
||||
<div
|
||||
class="thumbnailBox image list-img"
|
||||
:style="`
|
||||
opacity:${table.has_selected == 1 ? '0.6' : '1'};
|
||||
border: 1px solid #ccccccb5;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
position: relative;`"
|
||||
>
|
||||
<div style="width: 100%; height: 80px; display: flex; justify-content: center; align-items: center">
|
||||
<!-- 图片内容 -->
|
||||
<table
|
||||
:data-table-id="table.article_table_id"
|
||||
border="1"
|
||||
style="
|
||||
transform: scale(0.5);
|
||||
width: 140px;
|
||||
height: auto;
|
||||
background-color: #fff;
|
||||
border-collapse: collapse;
|
||||
text-align: center;
|
||||
"
|
||||
>
|
||||
<tr v-for="(row, rowIndex) in table.table" :key="rowIndex">
|
||||
<td
|
||||
v-for="(cell, cellIndex) in row"
|
||||
:key="cellIndex"
|
||||
:colspan="cell.colspan || 1"
|
||||
:rowspan="cell.rowspan || 1"
|
||||
>
|
||||
<span v-html="cell.text"> </span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<!-- 输入框 -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-collapse v-if="isShowEdit">
|
||||
<el-collapse-item name="1" style="margin-top: 4px">
|
||||
<template slot="title">
|
||||
<div style="width: 100%; display: flex; align-items: center; justify-content: space-between">
|
||||
<span style="color: #777">Tables {{ index + 1 }}</span>
|
||||
<span v-if="isShowEdit"><i class="el-icon-edit" v-if="isEdit"></i>Comments/ Suggestions</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-input
|
||||
v-if="isShowEdit"
|
||||
type="textarea"
|
||||
placeholder="please input content"
|
||||
:readonly="!isEdit"
|
||||
:rows="4"
|
||||
></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>
|
||||
</li>
|
||||
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mediaUrl } from '@/common/js/commonJS.js'; // 引入通用逻辑
|
||||
export default {
|
||||
props: ['articleId', 'imgWidth', 'imgHeight', 'scale', 'isEdit', 'isShowEdit', 'urlList', 'content'],
|
||||
data() {
|
||||
return {
|
||||
identity: localStorage.getItem('U_role'),
|
||||
isShowComment: false,
|
||||
isEditing: null, // 用于跟踪当前正在编辑的批注索引
|
||||
selectedComment: null, // 存储当前选择的批注内容
|
||||
comments: [], // 存储所有批注
|
||||
isFresh: false,
|
||||
currentSelectType: '0',
|
||||
currentMenu: 1,
|
||||
|
||||
mediaUrl,
|
||||
|
||||
|
||||
statusList: [
|
||||
{ title: 'ALL', type: '0' },
|
||||
{ title: 'Typed', type: '1' },
|
||||
{ title: 'Unfettered', type: '2' }
|
||||
],
|
||||
images: [],
|
||||
tables: [],
|
||||
imagesList: [],
|
||||
tablesList: [],
|
||||
tablesHtml: [],
|
||||
imagesHtml: [],
|
||||
activeNames: []
|
||||
};
|
||||
},
|
||||
directives: {
|
||||
// 注册一个局部的自定义指令 v-focus
|
||||
focus: {
|
||||
// 指令的定义
|
||||
inserted: function (el) {
|
||||
console.log('el at line 263:', el);
|
||||
// 聚焦元素
|
||||
el.querySelector('textarea').focus();
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
|
||||
|
||||
add(type) {
|
||||
this.$emit('add', type);
|
||||
},
|
||||
edit(data, type) {
|
||||
this.$emit('edit', data, type);
|
||||
},
|
||||
huifu(id) {
|
||||
this.$emit('huifu', id);
|
||||
},
|
||||
handleSelectMenu(v) {
|
||||
this.currentMenu = v;
|
||||
this.currentSelectType = '0';
|
||||
if (v == 1) {
|
||||
this.getCommentList();
|
||||
} else {
|
||||
this.filterData();
|
||||
}
|
||||
},
|
||||
selectType(v) {
|
||||
this.currentSelectType = v.type;
|
||||
this.filterData();
|
||||
},
|
||||
filterData(type) {
|
||||
console.log('type at line 374:', type);
|
||||
if (type) {
|
||||
if (type == 'img') {
|
||||
this.imagesList = [...this.images];
|
||||
} else if (type == 'table') {
|
||||
this.tablesList = [...this.tables];
|
||||
}
|
||||
} else {
|
||||
if (this.currentMenu == 2) {
|
||||
switch (this.currentSelectType) {
|
||||
case '0':
|
||||
this.imagesList = [...this.images];
|
||||
break;
|
||||
case '1':
|
||||
this.imagesList = [...this.images].filter((e) => e.has_selected == 1);
|
||||
break;
|
||||
case '2':
|
||||
this.imagesList = [...this.images].filter((e) => e.has_selected == 0);
|
||||
break;
|
||||
}
|
||||
} else if (this.currentMenu == 3) {
|
||||
switch (this.currentSelectType) {
|
||||
case '0':
|
||||
this.tablesList = [...this.tables];
|
||||
console.log('this.tablesList at line 393:', this.tablesList);
|
||||
break;
|
||||
case '1':
|
||||
this.tablesList = [...this.tables].filter((e) => e.has_selected == 1);
|
||||
break;
|
||||
case '2':
|
||||
this.tablesList = [...this.tables].filter((e) => e.has_selected == 0);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
},
|
||||
goToListComment(id, type) {
|
||||
this.$emit('goToListComment', id, type);
|
||||
},
|
||||
async refresh(type) {
|
||||
this.isFresh = false;
|
||||
this.$nextTick(async () => {
|
||||
if (type == 'img') {
|
||||
await this.getWordimgList();
|
||||
await this.handleSelectMenu(2);
|
||||
} else if (type == 'table') {
|
||||
await this.getWordTablesList();
|
||||
}
|
||||
this.$forceUpdate();
|
||||
this.isFresh = true;
|
||||
});
|
||||
},
|
||||
changeDataIsHidden(val, status, type) {
|
||||
console.log('type at line 165:', type);
|
||||
var index;
|
||||
this.$nextTick(() => {
|
||||
if (type == 'img') {
|
||||
index = this.images.findIndex((element) => element.article_image_id === val.article_image_id);
|
||||
console.log('index at line 170:', index);
|
||||
this.images[index].isHidden = status;
|
||||
} else {
|
||||
index = this.tables.findIndex((element) => element.id === id);
|
||||
this.tables[index].isHidden = status;
|
||||
}
|
||||
this.$forceUpdate();
|
||||
});
|
||||
},
|
||||
changeIsHidden(index, status, type) {
|
||||
console.log('type at line 165:', type);
|
||||
this.$nextTick(() => {
|
||||
if (type == 'img') {
|
||||
this.images[index].isHidden = status;
|
||||
} else {
|
||||
this.tables[index].isHidden = status;
|
||||
console.log('this.tables at line 169:', this.tables);
|
||||
}
|
||||
this.$forceUpdate();
|
||||
});
|
||||
},
|
||||
onDragStart($event, item, index, type) {
|
||||
console.log('type at line 192:', index);
|
||||
this.$emit('onDragStart', $event, item, index, type);
|
||||
},
|
||||
changeActiveNames(e) {
|
||||
console.log('e at line 156:', e);
|
||||
|
||||
if (['tables'].includes(e)) {
|
||||
this.$nextTick(() => {
|
||||
this.getWordTablesList();
|
||||
});
|
||||
}
|
||||
if (['images'].includes(e)) {
|
||||
this.$nextTick(() => {
|
||||
this.getWordimgList();
|
||||
});
|
||||
}
|
||||
},
|
||||
openPreview(index, type) {
|
||||
this.$nextTick(() => {
|
||||
document.getElementById(type + '-modal-' + index).style.display = 'flex';
|
||||
});
|
||||
},
|
||||
async getWordimgList() {
|
||||
await this.$api
|
||||
.post(this.urlList ? this.urlList.img : 'api/Article/getArticleImages', {
|
||||
article_id: this.articleId
|
||||
})
|
||||
.then(async (res) => {
|
||||
var list = [...res.data.list];
|
||||
if (this.urlList) {
|
||||
list = list.map((e) => {
|
||||
return {
|
||||
...e,
|
||||
image: e.url,
|
||||
article_image_id: e.ami_id
|
||||
};
|
||||
});
|
||||
} else {
|
||||
list = res.data.list;
|
||||
}
|
||||
|
||||
if (list.length > 0) {
|
||||
list.forEach((img, index) => {
|
||||
var extension = img.image.split('.').pop().toLowerCase();
|
||||
if (extension === 'tif' || extension === 'jpg' || extension === 'jpeg' || extension === 'png') {
|
||||
const modalContent = ['jpg', 'jpeg', 'png'].includes(extension)
|
||||
? `<img src="${this.mediaUrl + img.image}" alt="Image ${index}" style="width:100%;background:#FFF;" >`
|
||||
: `<canvas id="tiff-canvas-modal-${index}" ></canvas>`;
|
||||
|
||||
this.$commonJS.createImageModal(index, modalContent, 'img');
|
||||
}
|
||||
|
||||
if (extension === 'tif') {
|
||||
this.$nextTick(() => {
|
||||
this.$commonJS.renderTiffImage(
|
||||
this.mediaUrl + img.image,
|
||||
`tiff-canvas-modal-${index}`,
|
||||
function (url) {
|
||||
list[index].dataUrl = url;
|
||||
},
|
||||
index,
|
||||
true
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
this.images = list;
|
||||
this.$emit('loaded');
|
||||
});
|
||||
},
|
||||
async getWordTablesList(callback) {
|
||||
this.$api
|
||||
.post(this.urlList ? this.urlList.table : 'api/Article/getArticleTable', {
|
||||
article_id: this.articleId
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (this.urlList) {
|
||||
this.tables =
|
||||
res.data.list && res.data.list.length > 0
|
||||
? res.data.list.map((e) => {
|
||||
return {
|
||||
...e,
|
||||
article_table_id: e.amt_id,
|
||||
table: JSON.parse(e.table_data)
|
||||
};
|
||||
})
|
||||
: [];
|
||||
} else {
|
||||
this.tables =
|
||||
res.data.list && res.data.list.length > 0
|
||||
? res.data.list.map((e) => {
|
||||
return {
|
||||
...e,
|
||||
|
||||
table: JSON.parse(e.table)
|
||||
};
|
||||
})
|
||||
: [];
|
||||
}
|
||||
await this.filterData('table');
|
||||
if (this.tables.length > 0) {
|
||||
this.tables.forEach((table, index) => {
|
||||
var modalContent = `
|
||||
<div class="wordTableHtml" style="background:#FFF;padding:20px">
|
||||
<table
|
||||
border="1"
|
||||
style="
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
table-layout: auto;"
|
||||
>`;
|
||||
table.table.forEach((row) => {
|
||||
modalContent += `<tr>`;
|
||||
row.forEach((cell) => {
|
||||
modalContent += `
|
||||
<td
|
||||
colspan="${cell.colspan || 1}"
|
||||
rowspan="${cell.rowspan || 1}"
|
||||
style=""
|
||||
>
|
||||
<span>${cell.text}</span>
|
||||
</td>`;
|
||||
});
|
||||
modalContent += `</tr>`;
|
||||
});
|
||||
modalContent += `</table></div>`;
|
||||
this.$commonJS.createImageModal(index, modalContent, 'table', '');
|
||||
});
|
||||
}
|
||||
console.log('this.tables at line 533:', this.tables);
|
||||
});
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
this.isFresh = false;
|
||||
this.$nextTick(async () => {
|
||||
|
||||
await this.getWordimgList();
|
||||
await this.getWordTablesList();
|
||||
await this.filterData();
|
||||
this.isFresh = true;
|
||||
});
|
||||
},
|
||||
async activated() {
|
||||
this.isFresh = false;
|
||||
this.$nextTick(async () => {
|
||||
await this.getWordimgList();
|
||||
await this.getWordTablesList();
|
||||
await this.filterData();
|
||||
this.isFresh = true;
|
||||
});
|
||||
},
|
||||
mounted() {}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ManuscirptList {
|
||||
background-color: none !important;
|
||||
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0);
|
||||
color: #333639;
|
||||
}
|
||||
.ManuscirptList div {
|
||||
cursor: pointer;
|
||||
background-color: none !important;
|
||||
}
|
||||
::v-deep .wordTableHtml table {
|
||||
cursor: pointer;
|
||||
background-color: #fff !important;
|
||||
}
|
||||
.el-menu-vertical-demo {
|
||||
width: 85px;
|
||||
}
|
||||
.el-menu-vertical-demo li {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 10px 6px !important;
|
||||
font-size: 14px !important;
|
||||
text-align: center;
|
||||
}
|
||||
::v-deep .el-menu-vertical-demo.el-menu-item:focus,
|
||||
.el-menu-item:hover {
|
||||
background-color: #f8f8f9 !important;
|
||||
}
|
||||
::v-deep .el-menu-item.is-active {
|
||||
background-color: #2196f32e !important;
|
||||
}
|
||||
.isSelectType {
|
||||
background-color: #2196f32e !important;
|
||||
color: #006699;
|
||||
}
|
||||
li {
|
||||
list-style: none;
|
||||
}
|
||||
.item_box {
|
||||
background-color: #f2f3f5;
|
||||
border: 1px solid rgba(0, 0, 0, 0);
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.go-transition .title {
|
||||
background-color: #e5e6eb;
|
||||
color: #767c82;
|
||||
font-size: 13px;
|
||||
padding: 2px 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.go-transition .list-img {
|
||||
padding: 6px 0;
|
||||
background-color: #f2f3f5;
|
||||
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.go-transition .list-img :hover {
|
||||
transition: all 0.4s;
|
||||
}
|
||||
.go-content-charts-item-box {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
gap: 9px;
|
||||
transition: all 0.7s linear;
|
||||
}
|
||||
|
||||
.arrlist::-webkit-scrollbar-thumb {
|
||||
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0);
|
||||
min-height: 12px;
|
||||
border: 4px solid transparent;
|
||||
background-clip: content-box;
|
||||
border-radius: 7px;
|
||||
background-color: #c8d5e1;
|
||||
}
|
||||
.badge {
|
||||
background-color: #f56c6c;
|
||||
border-radius: 10px;
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
padding: 0 6px;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
border: 1px solid #fff;
|
||||
position: absolute;
|
||||
}
|
||||
.comments-section {
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #cecfd3;
|
||||
border-left: 2px solid #cecfd3;
|
||||
/* border-radius: 5px; */
|
||||
background-color: #f9f9f9;
|
||||
box-shadow: rgba(16, 17, 19, 0.06) 0px 1px 3px;
|
||||
width: 300px;
|
||||
background-color: #fafafa;
|
||||
float: right;
|
||||
position: absolute;
|
||||
right: -302px;
|
||||
top: 0px;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.comment-item {
|
||||
padding: 5px 0;
|
||||
border-bottom: 1px solid #ddd;
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.comment-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.comment-details {
|
||||
margin-top: 20px;
|
||||
padding: 10px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 5px;
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.comment-details h3 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.comment-details p {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.comment-details button {
|
||||
padding: 5px 10px;
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.comment-details button:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
.comments-section ul,
|
||||
.comments-section li {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
955
src/components/page/components/table/wordHtmlTypesetting.vue
Normal file
@@ -0,0 +1,955 @@
|
||||
<template>
|
||||
<div
|
||||
style="background-color: transparent !important; margin-top: 0px !important; height: 100%; padding: 0 !important; overflow: hidden"
|
||||
class="ManuscirptList"
|
||||
v-show="tables.length > 0 || images.length > 0"
|
||||
>
|
||||
<!-- 图片缩略图区域 -->
|
||||
|
||||
<el-menu
|
||||
default-active="1"
|
||||
style="border: none; height: 100%; float: left"
|
||||
background-color="#f8f8f9"
|
||||
active-text-color="#006699"
|
||||
text-color="#333639"
|
||||
class="el-menu-vertical-demo"
|
||||
@select="handleSelectMenu"
|
||||
>
|
||||
<el-menu-item index="1">
|
||||
<i class="el-icon-message-solid" style="margin: 0 auto; color: #fc625d"></i>
|
||||
<span slot="title" style="line-height: 30px">Annotations</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="2">
|
||||
<i class="el-icon-picture" color="#333639" style="margin: 0 auto"></i>
|
||||
<span slot="title" style="line-height: 20px">Figures</span>
|
||||
</el-menu-item>
|
||||
|
||||
<el-menu-item index="3">
|
||||
<i class="el-icon-s-grid" color="#333639" style="margin: 0 auto"></i>
|
||||
<span slot="title" style="line-height: 30px">Tables</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item index="4">
|
||||
<i class="el-icon-delete-solid" color="#333639" style="margin: 0 auto"></i>
|
||||
<span slot="title" style="line-height: 30px">Recycle Bin</span>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
<!-- <ul style="width: 80px; height: 100%; float: left; padding: 6px; box-sizing: border-box" v-if="currentMenu != 3">
|
||||
<li
|
||||
@click="selectType(v)"
|
||||
:class="`${currentSelectType == v.type ? 'isSelectType' : ''}`"
|
||||
v-for="(v, i) in statusList"
|
||||
style="
|
||||
margin: 8px 0;
|
||||
cursor: pointer;
|
||||
padding: 0px 0px !important;
|
||||
font-size: 13px !important;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
border-radius: 4px;
|
||||
"
|
||||
>
|
||||
<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">
|
||||
<ul style="width: 100%; height: auto">
|
||||
<li v-show="currentMenu == 1">
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 10px; justify-content: start">
|
||||
<li v-for="(comment, index) in comments" :key="index" class="comment-item" style="width: 100%; padding: 6px 0">
|
||||
<div @click.prevent="goToComment(comment.am_id)">
|
||||
<p style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px">
|
||||
<el-link class="pizhu">
|
||||
<span style="color: #fc625d; display: flex; align-items: center">
|
||||
<img
|
||||
class="isRemark"
|
||||
src="@/assets/img/isRemark.png"
|
||||
alt=""
|
||||
style="width: 15px; height: 15px; margin-right: 6px"
|
||||
/>
|
||||
{{ comment.am_id }}</span
|
||||
></el-link
|
||||
>
|
||||
|
||||
<span style="color: #b8b7b7;font-size: 12px">{{ getTime(comment.ctime) }}</span>
|
||||
</p>
|
||||
|
||||
<!-- 当 isEditing 为 true 时,显示可编辑的输入框 -->
|
||||
<!-- <div v-if="isEditing === index">
|
||||
<el-input
|
||||
v-focus
|
||||
type="textarea"
|
||||
v-model="comment.remark"
|
||||
@blur.stop="saveComment(index,comment)"
|
||||
style="width: 100%; box-sizing: border-box; padding: 5px"
|
||||
></el-input>
|
||||
</div> -->
|
||||
|
||||
<!-- 当 isEditing 为 false 时,显示评论文本 -->
|
||||
<div style="display: flex; align-items: center; justify-content: space-between">
|
||||
<p style="min-height: 20px; width: calc(100%);white-space: normal;">
|
||||
{{ comment.remark }}
|
||||
<!-- <span @click="editComment(index)" style="cursor: pointer; color: #007bff; margin-left: 10px;">修改</span> -->
|
||||
</p>
|
||||
|
||||
<!-- <i
|
||||
class="el-icon-delete"
|
||||
v-if="isShowComment"
|
||||
@click="deleteComment(comment, index)"
|
||||
style="color: #cd5454"
|
||||
></i> -->
|
||||
</div>
|
||||
|
||||
<!-- 删除按钮 -->
|
||||
</div>
|
||||
</li>
|
||||
</div>
|
||||
</li>
|
||||
<li v-show="currentMenu == 2">
|
||||
<div style="" class="go-content-charts-item-box">
|
||||
<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">
|
||||
<div style="width: 100%; display: flex; align-items: center; justify-content: space-between">
|
||||
<span style="color: #777">Tables {{ index + 1 }}</span>
|
||||
<span v-if="isShowEdit"><i class="el-icon-edit" v-if="isEdit"></i>Comments/ Suggestions</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-input
|
||||
v-if="isShowEdit"
|
||||
type="textarea"
|
||||
placeholder="please input content"
|
||||
:readonly="!isEdit"
|
||||
:rows="4"
|
||||
></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
|
||||
class="item_box"
|
||||
v-for="(img, index) in imagesList"
|
||||
style="width: 100%; height: auto; position: relative"
|
||||
:key="index"
|
||||
>
|
||||
<div class="list-center go-flex-center go-transition" style="width: 100%">
|
||||
<div class="title">
|
||||
<span
|
||||
>Figure {{ index + 1 }}
|
||||
<span
|
||||
@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> -->
|
||||
</span>
|
||||
<a :href="mediaUrl + img.image.url" style="color: #000" v-else>
|
||||
<!-- <el-tooltip class="item" effect="dark" :content="$t('commonTable.preview')" placement="top"> -->
|
||||
<i class="el-icon-download" style="font-size: 16px"></i>
|
||||
<!-- </el-tooltip> -->
|
||||
</a>
|
||||
</span>
|
||||
<p>
|
||||
<span style="" @click="edit(img, 'img')">
|
||||
<i class="el-icon-edit" style="color: #409eff; font-size: 16px"></i>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<span
|
||||
v-if="img.has_selected == 1"
|
||||
@click="goToListComment(img.article_image_id, 'img')"
|
||||
style="
|
||||
text-align: center;
|
||||
height: 20px;
|
||||
padding: 2px 0;
|
||||
line-height: 20px;
|
||||
width: 60px;
|
||||
z-index: 10;
|
||||
border-radius: 4px;
|
||||
background-color: #006699d1;
|
||||
color: #ffff;
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
top: 45%;
|
||||
left: calc((100% - 60px) / 2);
|
||||
"
|
||||
>{{ $t('commonTable.Typed') }}</span
|
||||
>
|
||||
<div
|
||||
class="thumbnailBox image list-img"
|
||||
:style="`
|
||||
opacity:${img.has_selected == 1 ? '0.6' : '1'};
|
||||
border: 1px solid #ccccccb5;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
position: relative;`"
|
||||
: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">
|
||||
<!-- 图片内容 -->
|
||||
<template v-if="['jpg', 'jpeg', 'png'].includes(img.image.split('.').pop().toLowerCase())">
|
||||
<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
|
||||
:data-img-id="img.article_image_id"
|
||||
:src="img.dataUrl"
|
||||
style="width: 140px; height: 100%; object-fit: cover"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
|
||||
<div
|
||||
style="
|
||||
width: 140px;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
font-size: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
"
|
||||
>
|
||||
{{ img.image.split('.').pop().toUpperCase() }}
|
||||
<!-- <i class="el-icon-download" style="margin-left: 10px; color: #75abf1"></i> -->
|
||||
</div>
|
||||
<!-- </a> -->
|
||||
</template>
|
||||
</div>
|
||||
<!-- 输入框 -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-collapse v-if="isShowEdit">
|
||||
<el-collapse-item name="1" style="margin-top: 4px">
|
||||
<template slot="title">
|
||||
<div style="width: 100%; display: flex; align-items: center; justify-content: space-between">
|
||||
<span style="color: #777">Tables {{ index + 1 }}</span>
|
||||
<span v-if="isShowEdit"><i class="el-icon-edit" v-if="isEdit"></i>Comments/ Suggestions</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-input
|
||||
v-if="isShowEdit"
|
||||
type="textarea"
|
||||
placeholder="please input content"
|
||||
:readonly="!isEdit"
|
||||
:rows="4"
|
||||
></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>
|
||||
</li>
|
||||
<li v-show="currentMenu == 3">
|
||||
<div style="" class="go-content-charts-item-box">
|
||||
<div
|
||||
class="item_box"
|
||||
v-for="(table, index) in tablesList"
|
||||
style="width: 100%; height: auto; position: relative"
|
||||
:key="index"
|
||||
>
|
||||
<div class="list-center go-flex-center go-transition" style="width: 100%">
|
||||
<div class="title">
|
||||
<span
|
||||
>Table {{ index + 1 }}
|
||||
<span @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
|
||||
></span>
|
||||
<p>
|
||||
<span style="" @click="edit(table, 'table')">
|
||||
<i class="el-icon-edit" style="color: #409eff; font-size: 16px"></i>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<span
|
||||
v-if="table.has_selected == 1"
|
||||
@click="goToListComment(table.article_table_id, 'table')"
|
||||
style="
|
||||
text-align: center;
|
||||
height: 20px;
|
||||
padding: 2px 0;
|
||||
line-height: 20px;
|
||||
width: 60px;
|
||||
z-index: 10;
|
||||
border-radius: 4px;
|
||||
background-color: #006699d1;
|
||||
color: #ffff;
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
top: 45%;
|
||||
left: calc((100% - 60px) / 2);
|
||||
"
|
||||
>{{ $t('commonTable.Typed') }}</span
|
||||
>
|
||||
<div
|
||||
class="thumbnailBox image list-img"
|
||||
:style="`
|
||||
opacity:${table.has_selected == 1 ? '0.6' : '1'};
|
||||
border: 1px solid #ccccccb5;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
position: relative;`"
|
||||
: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">
|
||||
<!-- 图片内容 -->
|
||||
<table
|
||||
:data-table-id="table.article_table_id"
|
||||
border="1"
|
||||
style="
|
||||
transform: scale(0.5);
|
||||
width: 140px;
|
||||
height: auto;
|
||||
background-color: #fff;
|
||||
border-collapse: collapse;
|
||||
text-align: center;
|
||||
"
|
||||
>
|
||||
<tr v-for="(row, rowIndex) in table.table" :key="rowIndex">
|
||||
<td
|
||||
v-for="(cell, cellIndex) in row"
|
||||
:key="cellIndex"
|
||||
:colspan="cell.colspan || 1"
|
||||
:rowspan="cell.rowspan || 1"
|
||||
>
|
||||
<span v-html="cell.text"> </span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<!-- 输入框 -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-collapse v-if="isShowEdit">
|
||||
<el-collapse-item name="1" style="margin-top: 4px">
|
||||
<template slot="title">
|
||||
<div style="width: 100%; display: flex; align-items: center; justify-content: space-between">
|
||||
<span style="color: #777">Tables {{ index + 1 }}</span>
|
||||
<span v-if="isShowEdit"><i class="el-icon-edit" v-if="isEdit"></i>Comments/ Suggestions</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-input
|
||||
v-if="isShowEdit"
|
||||
type="textarea"
|
||||
placeholder="please input content"
|
||||
:readonly="!isEdit"
|
||||
:rows="4"
|
||||
></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>
|
||||
</li>
|
||||
<li v-show="currentMenu == 4">
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 10px; justify-content: start">
|
||||
<div
|
||||
v-for="(item, index) in content"
|
||||
style="width: calc(100%); display: flex; align-items: center; justify-content: space-between; color: #606266"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
width: calc(100% - 50px);
|
||||
white-space: nowrap; /* 防止文本换行 */
|
||||
overflow: hidden; /* 隐藏超出部分 */
|
||||
text-overflow: ellipsis;
|
||||
"
|
||||
>
|
||||
<p
|
||||
v-html="index + 1 + '. ' + item.content"
|
||||
style="font-size: 14px; width: 100%; overflow: hidden; line-height: 30px"
|
||||
></p>
|
||||
</div>
|
||||
<img src="@/assets/img/huifu.png" style="width: 20px; height: 20px" alt="" @click="huifu(item.am_id)" />
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mediaUrl } from '@/common/js/commonJS.js'; // 引入通用逻辑
|
||||
export default {
|
||||
props: ['articleId', 'imgWidth', 'imgHeight', 'scale', 'isEdit', 'isShowEdit', 'urlList', 'content'],
|
||||
data() {
|
||||
return {
|
||||
isShowComment: false,
|
||||
isEditComment: false,
|
||||
isEditing: null, // 用于跟踪当前正在编辑的批注索引
|
||||
selectedComment: null, // 存储当前选择的批注内容
|
||||
comments: [], // 存储所有批注
|
||||
isFresh: false,
|
||||
currentSelectType: '0',
|
||||
currentMenu: 1,
|
||||
|
||||
mediaUrl,
|
||||
|
||||
|
||||
statusList: [
|
||||
{ title: 'ALL', type: '0' },
|
||||
{ title: 'Typed', type: '1' },
|
||||
{ title: 'Unfettered', type: '2' }
|
||||
],
|
||||
images: [],
|
||||
tables: [],
|
||||
imagesList: [],
|
||||
tablesList: [],
|
||||
tablesHtml: [],
|
||||
imagesHtml: [],
|
||||
activeNames: ['images', 'tables']
|
||||
};
|
||||
},
|
||||
directives: {
|
||||
// 注册一个局部的自定义指令 v-focus
|
||||
focus: {
|
||||
// 指令的定义
|
||||
inserted: function (el) {
|
||||
console.log('el at line 263:', el);
|
||||
// 聚焦元素
|
||||
el.querySelector('textarea').focus();
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isShowEditComment() {
|
||||
if (localStorage.getItem('U_role')) {
|
||||
var identity = localStorage.getItem('U_role');
|
||||
if (identity.includes('editor')) {
|
||||
this.isEditComment = true;
|
||||
} else {
|
||||
this.isEditComment = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
changeComment() {
|
||||
this.isShowComment = !this.isShowComment;
|
||||
},
|
||||
// 编辑评论,显示文本框
|
||||
editComment(index) {
|
||||
if (this.isEditComment) {
|
||||
this.isEditing = index; // 设置当前正在编辑的评论索引
|
||||
}
|
||||
},
|
||||
|
||||
// 保存评论修改
|
||||
saveComment(index,comment) {
|
||||
if (this.isEditComment) {
|
||||
this.$emit('addComment',comment)
|
||||
this.isEditing = null; // 退出编辑模式
|
||||
}
|
||||
},
|
||||
|
||||
// 删除评论
|
||||
deleteComment(comment, index) {
|
||||
if (this.isShowComment) {
|
||||
this.$confirm(this.$t('commonTable.removeAnnotations'), 'Prompt', {
|
||||
confirmButtonText: 'Submit',
|
||||
cancelButtonText: 'Cancel',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
this.comments.splice(index, 1); // 删除评论
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
},
|
||||
getTime(timestamp) {
|
||||
// 创建一个新的 Date 对象
|
||||
|
||||
// 转换为 Date 对象(乘以 1000,因为 JavaScript 使用毫秒)
|
||||
const date = new Date(timestamp * 1000);
|
||||
|
||||
// 获取年、月、日、时、分、秒
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份是从 0 开始的,所以加 1
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
const hours = String(date.getHours()).padStart(2, '0');
|
||||
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||||
const seconds = String(date.getSeconds()).padStart(2, '0');
|
||||
|
||||
// 格式化为 年-月-日 时:分:秒
|
||||
const formattedDate = `${year}-${month}-${day} ${hours}:${minutes}`;
|
||||
|
||||
console.log(formattedDate); // 输出: 2025-10-20 15:30:03
|
||||
|
||||
return formattedDate;
|
||||
},
|
||||
goToComment(mainId) {
|
||||
this.$nextTick(() => {
|
||||
this.$emit('goToComment', mainId);
|
||||
});
|
||||
},
|
||||
getCommentList() {
|
||||
this.$api
|
||||
.post('api/Preaccept/getNotes', {
|
||||
article_id: this.articleId
|
||||
})
|
||||
.then((res) => {
|
||||
this.comments = res.data.list;
|
||||
console.log('this.comments at line 537:', this.comments);
|
||||
});
|
||||
},
|
||||
add(type) {
|
||||
this.$emit('add', type);
|
||||
},
|
||||
edit(data, type) {
|
||||
this.$emit('edit', data, type);
|
||||
},
|
||||
huifu(id) {
|
||||
this.$emit('huifu', id);
|
||||
},
|
||||
handleSelectMenu(v) {
|
||||
this.currentMenu = v;
|
||||
this.currentSelectType = '0';
|
||||
if (v == 1) {
|
||||
this.getCommentList();
|
||||
} else {
|
||||
this.filterData();
|
||||
}
|
||||
},
|
||||
selectType(v) {
|
||||
this.currentSelectType = v.type;
|
||||
this.filterData();
|
||||
},
|
||||
filterData(type) {
|
||||
console.log('type at line 374:', type);
|
||||
if (type) {
|
||||
if (type == 'img') {
|
||||
this.imagesList = [...this.images];
|
||||
} else if (type == 'table') {
|
||||
this.tablesList = [...this.tables];
|
||||
}
|
||||
} else {
|
||||
if (this.currentMenu == 2) {
|
||||
switch (this.currentSelectType) {
|
||||
case '0':
|
||||
this.imagesList = [...this.images];
|
||||
break;
|
||||
case '1':
|
||||
this.imagesList = [...this.images].filter((e) => e.has_selected == 1);
|
||||
break;
|
||||
case '2':
|
||||
this.imagesList = [...this.images].filter((e) => e.has_selected == 0);
|
||||
break;
|
||||
}
|
||||
} else if (this.currentMenu == 3) {
|
||||
switch (this.currentSelectType) {
|
||||
case '0':
|
||||
this.tablesList = [...this.tables];
|
||||
console.log('this.tablesList at line 393:', this.tablesList);
|
||||
break;
|
||||
case '1':
|
||||
this.tablesList = [...this.tables].filter((e) => e.has_selected == 1);
|
||||
break;
|
||||
case '2':
|
||||
this.tablesList = [...this.tables].filter((e) => e.has_selected == 0);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
},
|
||||
goToListComment(id, type) {
|
||||
this.$emit('goToListComment', id, type);
|
||||
},
|
||||
async refresh(type) {
|
||||
this.isFresh = false;
|
||||
this.$nextTick(async () => {
|
||||
if (type == 'img') {
|
||||
await this.getWordimgList();
|
||||
|
||||
await this.filterData();
|
||||
} else if (type == 'table') {
|
||||
await this.getWordTablesList();
|
||||
await this.filterData();
|
||||
}
|
||||
this.$forceUpdate();
|
||||
this.isFresh = true;
|
||||
this.$emit('loaded', this.images);
|
||||
});
|
||||
},
|
||||
changeDataIsHidden(val, status, type) {
|
||||
console.log('type at line 165:', type);
|
||||
var index;
|
||||
this.$nextTick(() => {
|
||||
if (type == 'img') {
|
||||
index = this.images.findIndex((element) => element.article_image_id === val.article_image_id);
|
||||
console.log('index at line 170:', index);
|
||||
this.images[index].isHidden = status;
|
||||
} else {
|
||||
index = this.tables.findIndex((element) => element.id === id);
|
||||
this.tables[index].isHidden = status;
|
||||
}
|
||||
this.$forceUpdate();
|
||||
});
|
||||
},
|
||||
changeIsHidden(index, status, type) {
|
||||
console.log('type at line 165:', type);
|
||||
this.$nextTick(() => {
|
||||
if (type == 'img') {
|
||||
this.images[index].isHidden = status;
|
||||
} else {
|
||||
this.tables[index].isHidden = status;
|
||||
console.log('this.tables at line 169:', this.tables);
|
||||
}
|
||||
this.$forceUpdate();
|
||||
});
|
||||
},
|
||||
onDragStart($event, item, index, type) {
|
||||
console.log('type at line 192:', index);
|
||||
this.$emit('onDragStart', $event, item, index, type);
|
||||
},
|
||||
changeActiveNames(e) {
|
||||
console.log('e at line 156:', e);
|
||||
|
||||
if (['tables'].includes(e)) {
|
||||
this.$nextTick(() => {
|
||||
this.getWordTablesList();
|
||||
});
|
||||
}
|
||||
if (['images'].includes(e)) {
|
||||
this.$nextTick(() => {
|
||||
this.getWordimgList();
|
||||
});
|
||||
}
|
||||
},
|
||||
openPreview(index, type) {
|
||||
this.$nextTick(() => {
|
||||
document.getElementById(type + '-modal-' + index).style.display = 'flex';
|
||||
});
|
||||
},
|
||||
async getWordimgList() {
|
||||
var that = this;
|
||||
await this.$api
|
||||
.post(this.urlList ? this.urlList.img : 'api/Article/getArticleImages', {
|
||||
article_id: this.articleId
|
||||
})
|
||||
.then(async (res) => {
|
||||
var list = [...res.data.list];
|
||||
if (this.urlList) {
|
||||
list = list.map((e) => {
|
||||
return {
|
||||
...e,
|
||||
image: e.url,
|
||||
article_image_id: e.ami_id
|
||||
};
|
||||
});
|
||||
} else {
|
||||
list = res.data.list;
|
||||
}
|
||||
|
||||
if (list.length > 0) {
|
||||
list.forEach((img, index) => {
|
||||
var extension = img.image.split('.').pop().toLowerCase();
|
||||
if (extension === 'tif' || extension === 'jpg' || extension === 'jpeg' || extension === 'png') {
|
||||
const modalContent = ['jpg', 'jpeg', 'png'].includes(extension)
|
||||
? `<img src="${this.mediaUrl + img.image}" alt="Image ${index}" style="width:100%;" >`
|
||||
: `<canvas id="tiff-canvas-modal-${index}" ></canvas>`;
|
||||
|
||||
this.$commonJS.createImageModal(index, modalContent, 'img');
|
||||
}
|
||||
|
||||
if (extension === 'tif') {
|
||||
this.$nextTick(() => {
|
||||
this.$commonJS.renderTiffImage(
|
||||
this.mediaUrl + img.image,
|
||||
`tiff-canvas-modal-${index}`,
|
||||
function (url) {
|
||||
list[index].dataUrl = url;
|
||||
},
|
||||
index,
|
||||
true
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
this.images = list;
|
||||
this.$emit('loaded', this.images);
|
||||
});
|
||||
},
|
||||
async getWordTablesList(callback) {
|
||||
this.$api
|
||||
.post(this.urlList ? this.urlList.table : 'api/Article/getArticleTable', {
|
||||
article_id: this.articleId
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (this.urlList) {
|
||||
this.tables =
|
||||
res.data.list && res.data.list.length > 0
|
||||
? res.data.list.map((e) => {
|
||||
return {
|
||||
...e,
|
||||
article_table_id: e.amt_id,
|
||||
table: JSON.parse(e.table_data)
|
||||
};
|
||||
})
|
||||
: [];
|
||||
} else {
|
||||
this.tables =
|
||||
res.data.list && res.data.list.length > 0
|
||||
? res.data.list.map((e) => {
|
||||
return {
|
||||
...e,
|
||||
|
||||
table: JSON.parse(e.table)
|
||||
};
|
||||
})
|
||||
: [];
|
||||
}
|
||||
await this.filterData('table');
|
||||
if (this.tables.length > 0) {
|
||||
this.tables.forEach((table, index) => {
|
||||
var modalContent = `
|
||||
<div class="wordTableHtml" style="background:#FFF;padding:20px">
|
||||
<table
|
||||
border="1"
|
||||
style="
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
table-layout: auto;"
|
||||
>`;
|
||||
table.table.forEach((row) => {
|
||||
modalContent += `<tr>`;
|
||||
row.forEach((cell) => {
|
||||
modalContent += `
|
||||
<td
|
||||
colspan="${cell.colspan || 1}"
|
||||
rowspan="${cell.rowspan || 1}"
|
||||
style=""
|
||||
>
|
||||
<span>${cell.text}</span>
|
||||
</td>`;
|
||||
});
|
||||
modalContent += `</tr>`;
|
||||
});
|
||||
modalContent += `</table></div>`;
|
||||
this.$commonJS.createImageModal(index, modalContent, 'table', '');
|
||||
});
|
||||
}
|
||||
console.log('this.tables at line 533:', this.tables);
|
||||
});
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
this.isShowEditComment();
|
||||
this.isFresh = false;
|
||||
this.$nextTick(async () => {
|
||||
await this.getCommentList();
|
||||
await this.getWordimgList();
|
||||
await this.getWordTablesList();
|
||||
await this.filterData();
|
||||
this.isFresh = true;
|
||||
});
|
||||
},
|
||||
async activated() {
|
||||
this.isFresh = false;
|
||||
this.isShowEditComment();
|
||||
this.$nextTick(async () => {
|
||||
await this.getWordimgList();
|
||||
await this.getWordTablesList();
|
||||
await this.filterData();
|
||||
this.isFresh = true;
|
||||
});
|
||||
},
|
||||
mounted() {}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ManuscirptList {
|
||||
background-color: none !important;
|
||||
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0);
|
||||
color: #333639;
|
||||
}
|
||||
.ManuscirptList div {
|
||||
cursor: pointer;
|
||||
background-color: none !important;
|
||||
}
|
||||
::v-deep .wordTableHtml table {
|
||||
cursor: pointer;
|
||||
background-color: #fff !important;
|
||||
}
|
||||
.el-menu-vertical-demo {
|
||||
width: 85px;
|
||||
}
|
||||
.el-menu-vertical-demo li {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 10px 6px !important;
|
||||
font-size: 14px !important;
|
||||
text-align: center;
|
||||
}
|
||||
::v-deep .el-menu-vertical-demo.el-menu-item:focus,
|
||||
.el-menu-item:hover {
|
||||
background-color: #f8f8f9 !important;
|
||||
}
|
||||
::v-deep .el-menu-item.is-active {
|
||||
background-color: #2196f32e !important;
|
||||
}
|
||||
.isSelectType {
|
||||
background-color: #2196f32e !important;
|
||||
color: #006699;
|
||||
}
|
||||
li {
|
||||
list-style: none;
|
||||
}
|
||||
.item_box {
|
||||
background-color: #f2f3f5;
|
||||
border: 1px solid rgba(0, 0, 0, 0);
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.go-transition .title {
|
||||
background-color: #e5e6eb;
|
||||
color: #767c82;
|
||||
font-size: 13px;
|
||||
padding: 2px 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.go-transition .list-img {
|
||||
padding: 6px 0;
|
||||
background-color: #f2f3f5;
|
||||
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.go-transition .list-img :hover {
|
||||
transition: all 0.4s;
|
||||
}
|
||||
.go-content-charts-item-box {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
gap: 9px;
|
||||
transition: all 0.7s linear;
|
||||
}
|
||||
|
||||
.arrlist::-webkit-scrollbar-thumb {
|
||||
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0);
|
||||
min-height: 12px;
|
||||
border: 4px solid transparent;
|
||||
background-clip: content-box;
|
||||
border-radius: 7px;
|
||||
background-color: #c8d5e1;
|
||||
}
|
||||
.badge {
|
||||
background-color: #f56c6c;
|
||||
border-radius: 10px;
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
padding: 0 6px;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
border: 1px solid #fff;
|
||||
position: absolute;
|
||||
}
|
||||
.comments-section {
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #cecfd3;
|
||||
border-left: 2px solid #cecfd3;
|
||||
/* border-radius: 5px; */
|
||||
background-color: #f9f9f9;
|
||||
box-shadow: rgba(16, 17, 19, 0.06) 0px 1px 3px;
|
||||
width: 300px;
|
||||
background-color: #fafafa;
|
||||
float: right;
|
||||
position: absolute;
|
||||
right: -302px;
|
||||
top: 0px;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.comment-item {
|
||||
padding: 5px 0;
|
||||
border-bottom: 1px solid #ddd;
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.comment-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.comment-details {
|
||||
margin-top: 20px;
|
||||
padding: 10px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 5px;
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.comment-details h3 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.comment-details p {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.comment-details button {
|
||||
padding: 5px 10px;
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.comment-details button:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
.comments-section ul,
|
||||
.comments-section li {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
::v-deep.pizhu.el-link--default:hover {
|
||||
border-color: #fc625d !important;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,317 @@
|
||||
<template>
|
||||
<div style="background-color: transparent !important" class="ManuscirptList" v-show="tables.length > 0 || images.length > 0">
|
||||
<!-- 图片缩略图区域 -->
|
||||
|
||||
<el-collapse v-model="activeNames" @change="changeActiveNames"
|
||||
><el-collapse-item name="images" style="" v-if="images.length > 0">
|
||||
<template slot="title">
|
||||
<p style="font-weight: bold; color: #222 !important">Manuscirpt Figures ( {{ images.length }} )</p>
|
||||
|
||||
<!-- <p style="margin-left: 20px">
|
||||
<i class="header-icon el-icon-info"></i
|
||||
><span style="margin-left: 5px; color: rgb(153, 153, 153)">Click to open the Figures</span>
|
||||
</p> -->
|
||||
</template>
|
||||
<!-- <p style="margin-bottom: 15px;color: rgb(153, 153, 153);line-height: 16px;"> If you have any questions that need to be addressed to the author, you can leave valuable comments or suggestions below the Figures</p> -->
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 10px; justify-content: start">
|
||||
<div v-for="(img, index) in images" style="width: 30%" :key="index">
|
||||
|
||||
<div
|
||||
class="thumbnailBox image"
|
||||
:style="`
|
||||
opacity:${img.isHidden ? '0.3' : '1'};
|
||||
border: 1px solid #ccccccb5;
|
||||
width: 100%;
|
||||
height: ${imgHeight ? imgHeight : '200px'};
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
position: relative;`"
|
||||
:draggable="!img.isHidden ? true : false"
|
||||
@dragstart="!img.isHidden ? onDragStart($event, img, index, 'img') : ''"
|
||||
>
|
||||
<div style="width: 100%; height: 100%; display: flex; justify-content: center; align-items: center">
|
||||
<!-- 图片内容 -->
|
||||
<template v-if="['jpg', 'jpeg', 'png'].includes(img.image.split('.').pop().toLowerCase())">
|
||||
<img :data-img-id="img.ami_id" @click="openPreview(index, 'img')" :src="mediaUrl + img.image" style="width: 100%; height: auto" />
|
||||
</template>
|
||||
<template v-else-if="img.image.split('.').pop().toLowerCase() === 'tif'">
|
||||
<canvas
|
||||
@click="openPreview(index, 'img')"
|
||||
:id="`tiff-canvas-${index}`"
|
||||
:data-img-id="img.article_image_id"
|
||||
style="width: 100%; height: auto"
|
||||
></canvas>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a :href="mediaUrl+ img.image" style="color: #75abf1">
|
||||
<div
|
||||
style="
|
||||
text-align: center;
|
||||
font-size: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
"
|
||||
>
|
||||
{{ img.image.split('.').pop().toUpperCase() }}
|
||||
<i class="el-icon-download" style="margin-left: 10px; color: #75abf1"></i>
|
||||
</div>
|
||||
</a>
|
||||
</template>
|
||||
</div>
|
||||
<!-- 输入框 -->
|
||||
</div>
|
||||
|
||||
<el-collapse v-if="isShowEdit">
|
||||
<el-collapse-item name="1" style="margin-top: 4px">
|
||||
<template slot="title">
|
||||
<div style="width: 100%; display: flex; align-items: center; justify-content: space-between">
|
||||
<span style="color: #777">Tables {{ index + 1 }}</span>
|
||||
<span v-if="isShowEdit"><i class="el-icon-edit" v-if="isEdit"></i>Comments/ Suggestions</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-input
|
||||
v-if="isShowEdit"
|
||||
type="textarea"
|
||||
placeholder="please input content"
|
||||
:readonly="!isEdit"
|
||||
:rows="4"
|
||||
></el-input>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
<p style="color: #777; margin-top: 6px" v-else>Figures {{ index + 1 }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item name="tables" style="" v-if="tables.length > 0">
|
||||
<template slot="title">
|
||||
<p style="font-weight: bold; color: #222">Manuscirpt Tables ( {{ tables.length }} )</p>
|
||||
|
||||
<!-- <p style="margin-left: 20px">
|
||||
<i class="header-icon el-icon-info"></i
|
||||
><span style="margin-left: 5px; color: rgb(153, 153, 153)">Click to open the Tables</span>
|
||||
</p> -->
|
||||
</template>
|
||||
<!-- <p style="margin-bottom: 15px;color: rgb(153, 153, 153);line-height: 16px;"> If you have any questions that need to be addressed to the author, you can leave valuable comments or suggestions below the Table</p> -->
|
||||
<!-- 表格缩略图区域 -->
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 10px; justify-content: start; margin-top: 20px">
|
||||
<div v-for="(table, index) in tables" style="width: 48%" :key="index">
|
||||
<div
|
||||
class="thumbnailTableBox wordTableHtml tables"
|
||||
:style="`
|
||||
opacity:${table.isHidden ? '0.3' : '1'};
|
||||
border: 1px solid #ccccccb5;
|
||||
width: 100%;
|
||||
height: ${imgHeight ? imgHeight : '200px'};
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
position: relative;`"
|
||||
@click="openPreview(index, 'table')"
|
||||
:draggable="!table.isHidden ? true : false"
|
||||
@dragstart="!table.isHidden ? onDragStart($event, table, index, 'table') : ''"
|
||||
>
|
||||
<table border="1" style="width: auto; border-collapse: collapse; text-align: center; ">
|
||||
<tr v-for="(row, rowIndex) in table" :key="rowIndex">
|
||||
<td
|
||||
v-for="(cell, cellIndex) in row"
|
||||
:key="cellIndex"
|
||||
:colspan="cell.colspan || 1"
|
||||
:rowspan="cell.rowspan || 1"
|
||||
>
|
||||
<span v-html="cell.text"> </span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<el-collapse v-if="isShowEdit">
|
||||
<el-collapse-item name="1" style="margin-top: 4px">
|
||||
<template slot="title">
|
||||
<div style="width: 100%; display: flex; align-items: center; justify-content: space-between">
|
||||
<span style="color: #777">Tables {{ index + 1 }}</span>
|
||||
<span v-if="isShowEdit"><i class="el-icon-edit" v-if="isEdit"></i>Comments/ Suggestions</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-input
|
||||
v-if="isShowEdit"
|
||||
type="textarea"
|
||||
placeholder="please input content"
|
||||
:readonly="!isEdit"
|
||||
:rows="4"
|
||||
></el-input>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
<p style="color: #777; margin-top: 6px" v-else>Table {{ index + 1 }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mediaUrl } from '@/common/js/commonJS.js'; // 引入通用逻辑
|
||||
export default {
|
||||
props: ['articleId', 'imgWidth', 'imgHeight', 'scale', 'isEdit', 'isShowEdit','urlList'],
|
||||
data() {
|
||||
return {
|
||||
mediaUrl,
|
||||
|
||||
tables: [],
|
||||
|
||||
|
||||
images: [],
|
||||
tablesHtml: [],
|
||||
imagesHtml: [],
|
||||
activeNames: ['images', 'tables']
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
changeDataIsHidden(val, status, type) {
|
||||
console.log('type at line 165:', type);
|
||||
var index;
|
||||
this.$nextTick(() => {
|
||||
if (type == 'img') {
|
||||
index= this.images.findIndex((element) => element.article_image_id === val.article_image_id)
|
||||
console.log('index at line 170:', index)
|
||||
this.images[index] .isHidden = status;
|
||||
} else {
|
||||
index= this.tables.findIndex((element) => element.id === id)
|
||||
this.tables[index] .isHidden = status;
|
||||
}
|
||||
this.$forceUpdate();
|
||||
});
|
||||
},
|
||||
changeIsHidden(index, status, type) {
|
||||
console.log('type at line 165:', type);
|
||||
this.$nextTick(() => {
|
||||
if (type == 'img') {
|
||||
this.images[index].isHidden = status;
|
||||
} else {
|
||||
this.tables[index].isHidden = status;
|
||||
console.log('this.tables at line 169:', this.tables);
|
||||
}
|
||||
this.$forceUpdate();
|
||||
});
|
||||
},
|
||||
onDragStart($event, item, index, type) {
|
||||
console.log('type at line 192:', index)
|
||||
this.$emit('onDragStart', $event, item, index, type);
|
||||
},
|
||||
changeActiveNames(e) {
|
||||
console.log('e at line 156:', e);
|
||||
|
||||
if (['tables'].includes(e)) {
|
||||
this.$nextTick(() => {
|
||||
this.getWordTablesList();
|
||||
});
|
||||
}
|
||||
if (['images'].includes(e)) {
|
||||
this.$nextTick(() => {
|
||||
this.getWordimgList();
|
||||
});
|
||||
}
|
||||
},
|
||||
openPreview(index, type) {
|
||||
this.$nextTick(() => {
|
||||
document.getElementById(type + '-modal-' + index).style.display = 'flex';
|
||||
});
|
||||
},
|
||||
async getWordimgList() {
|
||||
await this.$api
|
||||
.post(this.urlList?this.urlList.img:'api/Article/getArticleImages', {
|
||||
article_id: this.articleId
|
||||
})
|
||||
.then(async (res) => {
|
||||
this.images = res.data.list;
|
||||
if (this.images.length > 0) {
|
||||
this.images.forEach((img, index) => {
|
||||
var extension = img.image.split('.').pop().toLowerCase();
|
||||
if (extension === 'tif' || extension === 'jpg' || extension === 'jpeg' || extension === 'png') {
|
||||
const modalContent = ['jpg', 'jpeg', 'png'].includes(extension)
|
||||
? `<img src="${this.mediaUrl + img.image}" alt="Image ${index}" style="width:100%;" >`
|
||||
: `<canvas id="tiff-canvas-modal-${index}" ></canvas>`;
|
||||
|
||||
this.$commonJS.createImageModal(index, modalContent, 'img');
|
||||
}
|
||||
|
||||
if (extension === 'tif') {
|
||||
this.$nextTick(() => {
|
||||
this.$commonJS.renderTiffImage(mediaUrl + img.image, `tiff-canvas-modal-${index}`, index, true);
|
||||
const targetWidth = this.imgWidth || document.getElementsByClassName('thumbnailBox')[0].offsetWidth;
|
||||
const targetHeight = this.imgHeight || document.getElementsByClassName('thumbnailBox')[0].offsetHeight;
|
||||
this.$commonJS.renderTiffImage(
|
||||
mediaUrl + img.image,
|
||||
`tiff-canvas-${index}`,
|
||||
index,
|
||||
true,
|
||||
targetWidth,
|
||||
targetHeight
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
getWordTablesList() {
|
||||
this.$api
|
||||
.post(this.urlList?this.urlList.table:'api/Article/getArticleTable', {
|
||||
article_id: this.articleId
|
||||
})
|
||||
.then((res) => {
|
||||
this.tables = res.data.list && res.data.list.length > 0 ? JSON.parse(res.data.list[0].table) : [];
|
||||
if (this.tables.length > 0) {
|
||||
this.tables.forEach((table, index) => {
|
||||
var modalContent = `
|
||||
<div class="wordTableHtml" style="background:#FFF;padding:20px">
|
||||
<table
|
||||
border="1"
|
||||
style="
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
table-layout: auto;"
|
||||
>`;
|
||||
table.forEach((row) => {
|
||||
modalContent += `<tr>`;
|
||||
row.forEach((cell) => {
|
||||
modalContent += `
|
||||
<td
|
||||
colspan="${cell.colspan || 1}"
|
||||
rowspan="${cell.rowspan || 1}"
|
||||
style=""
|
||||
>
|
||||
<span>${cell.text}</span>
|
||||
</td>`;
|
||||
});
|
||||
modalContent += `</tr>`;
|
||||
});
|
||||
modalContent += `</table></div>`;
|
||||
this.$commonJS.createImageModal(index, modalContent, 'table', '');
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.getWordimgList();
|
||||
this.getWordTablesList();
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ManuscirptList {
|
||||
background-color: none !important;
|
||||
}
|
||||
.ManuscirptList div {
|
||||
cursor: pointer;
|
||||
background-color: none !important;
|
||||
}
|
||||
::v-deep .wordTableHtml table {
|
||||
cursor: pointer;
|
||||
background-color: #fff !important;
|
||||
}
|
||||
</style>
|
||||
49569
src/components/page/dictionaries/1.dic
Normal file
6907
src/components/page/dictionaries/en_US.aff
Normal file
49569
src/components/page/dictionaries/en_US.dic
Normal file
@@ -310,6 +310,9 @@
|
||||
v-model="questionform.comment"
|
||||
:rows="8"
|
||||
></el-input>
|
||||
</el-form-item> <el-form-item label="" v-if="articleId">
|
||||
<common-word-html :articleId="articleId" style="box-sizing: border-box"
|
||||
></common-word-html>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="Comments for the Authors"
|
||||
@@ -323,6 +326,7 @@
|
||||
:rows="8"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Confidential Comments to the Editor">
|
||||
<el-input
|
||||
type="textarea"
|
||||
@@ -331,6 +335,7 @@
|
||||
:rows="8"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Please choose disclose your name or remain anonymous">
|
||||
<el-radio-group v-model="questionform.is_anonymous" style="line-height: 30px">
|
||||
<el-radio :label="0">Disclose name</el-radio>
|
||||
@@ -363,6 +368,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
articleId: null,
|
||||
Direct_log: this.$route.query.act,
|
||||
Art_id: this.$route.query.Art_id,
|
||||
// morShow: false,
|
||||
@@ -488,6 +494,7 @@ export default {
|
||||
human: 'reviewer'
|
||||
})
|
||||
.then((res) => {
|
||||
this.articleId=res.article_id
|
||||
if (res.state != 0) {
|
||||
this.btn_submit = 1;
|
||||
}
|
||||
@@ -532,12 +539,12 @@ export default {
|
||||
|
||||
if (pdfOut.substring(pdfOut.lastIndexOf('.') + 1) == 'docx') {
|
||||
this.pdfUrl =
|
||||
'https://view.officeapps.live.com/op/view.aspx?src=https://submission.tmrjournals.com/public/' + pdfOut;
|
||||
'https://view.officeapps.live.com/op/view.aspx?src=https://submission.tmrjournals.com/public/' + pdfOut+`&ui=en-US`;
|
||||
// this.pdfUrl =
|
||||
// 'https://view.xdocin.com/view?src=https://submission.tmrjournals.com/public/' +
|
||||
// pdfOut
|
||||
} else {
|
||||
this.pdfUrl = 'https://submission.tmrjournals.com/public/' + pdfOut;
|
||||
this.pdfUrl = 'https://submission.tmrjournals.com/public/' + pdfOut+`&ui=en-US`;
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
|
||||
14
src/main.js
@@ -73,6 +73,20 @@ Vue.component("Editor", Editor);
|
||||
|
||||
import commonTable from '@/components/page/components/table/table.vue'
|
||||
Vue.component('common-table', commonTable);
|
||||
import commonTiff from '@/components/page/components/table/tiff.vue'
|
||||
Vue.component('common-tiff', commonTiff);
|
||||
import commonContent from '@/components/page/components/table/content.vue'
|
||||
Vue.component('common-content', commonContent);
|
||||
import commonWord from '@/components/page/components/table/word.vue'
|
||||
Vue.component('common-word', commonWord);
|
||||
import commonAnnotations from '@/components/page/components/table/annotations.vue'
|
||||
Vue.component('common-annotations', commonAnnotations);
|
||||
import commonWordHtml from '@/components/page/components/table/wordHtml.vue'
|
||||
Vue.component('common-word-html', commonWordHtml);
|
||||
import commonWordHtmlTypesetting from '@/components/page/components/table/wordHtmlTypesetting.vue'
|
||||
Vue.component('common-word-html-type-setting', commonWordHtmlTypesetting);
|
||||
|
||||
|
||||
import commonDragWord from '@/components/page/components/table/dragWord.vue'
|
||||
Vue.component('common-drag-word', commonDragWord);
|
||||
Vue.use(VueI18n);
|
||||
|
||||
@@ -946,7 +946,7 @@ export default new Router({
|
||||
path: '/GenerateCharts', //用户端预收录-引用编辑
|
||||
component: () => import('../components/page/GenerateCharts'),
|
||||
meta: {
|
||||
title: 'Generate Charts'
|
||||
title: 'HTML Proofread'
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||