4427 lines
181 KiB
Vue
4427 lines
181 KiB
Vue
<template>
|
||
<div style="height: 100%">
|
||
<div
|
||
class="container"
|
||
style="
|
||
height: 100%;
|
||
min-width: calc(1000px);
|
||
width: calc(100%);
|
||
background-color: #fafafa;
|
||
padding: 0px 0 0 0;
|
||
box-sizing: border-box;
|
||
position: relative;
|
||
box-sizing: border-box;
|
||
"
|
||
>
|
||
<div
|
||
class="right-side"
|
||
style="
|
||
width: 260px;
|
||
float: left;
|
||
height: 100%;
|
||
background-color: #fff;
|
||
box-shadow: 0 1px 3px rgb(16 17 19 / 6%);
|
||
border-radius: 4px;
|
||
overflow-y: auto;
|
||
"
|
||
>
|
||
<!-- <p style="padding: 10px 10px; box-sizing: border-box; font-weight: bold"> -->
|
||
|
||
<!-- <b class="MaxBtn" style="right: 80px; top: 5px; padding: 0"><common-drag-word @tables="getTables"></common-drag-word></b> -->
|
||
<!-- <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" style="height: 100%">
|
||
<common-word-html-type-setting
|
||
:urlList="{
|
||
img: 'api/Preaccept/getMainImages',
|
||
table: 'api/Preaccept/getMainTables'
|
||
}"
|
||
:articleId="articleId"
|
||
:bodyCiteIdOrder="articleCiteIdOrder"
|
||
:chanFerForm="chanFerForm"
|
||
:content="ManuscirptContent"
|
||
ref="commonWordHtmlTypeSetting"
|
||
@onDragStart="onDragStart"
|
||
@huifu="huifu"
|
||
@onAddComment="onAddComment"
|
||
@addImage="handleImageAdd"
|
||
@addTable="handleTableAdd"
|
||
@handlePaperclip="handlePaperclip"
|
||
@addComment="addCommentSetting"
|
||
@goToComment="goToComment"
|
||
@edit="handleFigureAndTableEdit"
|
||
@delete="handleFigureAndTableDelete"
|
||
@goToListComment="goToListComment"
|
||
style="width: 100%; height: 100%; padding: 0 0px; box-sizing: border-box; background-color: #fff"
|
||
>
|
||
<template slot="catalogue1">
|
||
<catalogue
|
||
v-if="Main_List.length > 0"
|
||
:content="catalogueContent"
|
||
:articleId="articleId"
|
||
ref="catalogue"
|
||
@goToListComment="goToListComment"
|
||
style="width: 100%; height: 100%; padding: 0 0px; box-sizing: border-box; background-color: #fff"
|
||
>
|
||
</catalogue>
|
||
</template>
|
||
</common-word-html-type-setting>
|
||
<input type="file" ref="fileInput" style="display: none" @change="handleFileChange" />
|
||
</div>
|
||
</div>
|
||
<div style="width: 100%; width: calc(100% - 260px); float: right; height: calc(100% - 0px); background-color: #e4e9ed">
|
||
<common-word
|
||
:articleId="articleId"
|
||
v-if="htmlContent"
|
||
ref="commonWord"
|
||
:value="htmlContent"
|
||
:contentList="Main_List"
|
||
:chanFerForm="chanFerForm"
|
||
:comments="comments"
|
||
:wordStyle="wordStyle"
|
||
@onDrop="onDrop"
|
||
@onLinkUnbind="handleUnbindLink"
|
||
@onLinkConfirm="handleConfirmLink"
|
||
@saveContent="saveContent"
|
||
@editComment="editComment"
|
||
@loaded="loadedWord"
|
||
@onEdit="onEdit"
|
||
@addContent="onAddContent"
|
||
@changeSort="changeSort"
|
||
@onDelete="onDelete"
|
||
@onDeletes="onDeletes"
|
||
@refresh="onRefresh"
|
||
@onComment="onComment"
|
||
@onAddComment="onAddComment"
|
||
@solveComment="solveComment"
|
||
@cancelSolveComment="cancelSolveComment"
|
||
@replyComment="replyComment"
|
||
@deleteComment="deleteComment"
|
||
@editProofreading="editProofreading"
|
||
@revokeProofreading="revokeProofreading"
|
||
@executeProofreading="executeProofreading"
|
||
@deleteProofreading="deleteProofreading"
|
||
@onEditTitle="onEditTitle"
|
||
@onAddRow="onAddRow"
|
||
@changeComment="changeComment"
|
||
@openRefSelector="handleOpenRefSelectorFromManuscript"
|
||
@reorderReferencesByBody="handleReorderReferencesByBody"
|
||
@saveTableManuscript="saveTableManuscript"
|
||
@saveImageManuscript="saveImageManuscript"
|
||
style="width: calc(100%); height: calc(100%)"
|
||
:style="`100%`"
|
||
>
|
||
<template slot="comment">
|
||
<div style="" class="commentList annotations"></div>
|
||
</template>
|
||
<template slot="refrences">
|
||
<edit-public-ref-table-only
|
||
v-if="p_article_id != null && p_article_id !== ''"
|
||
ref="editPublicRefTableOnly"
|
||
:chanFerForm="chanFerForm"
|
||
:chanFerFormRepeatList="chanFerFormRepeatList"
|
||
:citeOrderFromParent="articleCiteIdOrder"
|
||
:ref-order-follows-body="true"
|
||
:p_article_id="p_article_id"
|
||
@ChanFerMashUp="ChanFerMashUp"
|
||
@refrashComp="fetchReferList"
|
||
@changeRefer="fetchReferList"
|
||
/>
|
||
</template>
|
||
</common-word>
|
||
</div>
|
||
</div>
|
||
|
||
<!--添加/修改图片 -->
|
||
<el-dialog :title="picStyle.visiTitle" :visible.sync="pictVisible" width="1200px" :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>
|
||
Figure :
|
||
</span>
|
||
<el-upload
|
||
:data="{ article_id: articleId }"
|
||
class="avatar-uploader"
|
||
:action="baseUrl + 'api/Preaccept/up_img_mainImage'"
|
||
:show-file-list="false"
|
||
name="mainImage"
|
||
accept=".jpg,.jpeg,.png,.tif"
|
||
:on-success="handleAvatarSuccess"
|
||
:on-error="handleAvatarError"
|
||
:before-upload="beforeAvatarUpload"
|
||
>
|
||
<img v-if="picStyle && picStyle.picUrl" :src="mediaUrl + picStyle.picUrl" class="avatar" />
|
||
<i class="el-icon-plus avatar-uploader-icon" v-else></i>
|
||
</el-upload>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="Figure Title :">
|
||
<span slot="label">
|
||
<font style="color: #f56c6c; margin-right: 5px">*</font>
|
||
Figure Title :
|
||
</span>
|
||
<common-content
|
||
type="content"
|
||
:isAutomaticUpdate="true"
|
||
:value="picStyle.title"
|
||
:show-ref-button="false"
|
||
@getContent="getContent"
|
||
@openLatexEditor="openLatexEditor"
|
||
v-if="pictVisible"
|
||
@updateChange="(res) => updateChange(res, 'imgTitle')"
|
||
:height="200"
|
||
ref="tinymceChildImgTitle"
|
||
style="margin-left: -115px"
|
||
></common-content>
|
||
</el-form-item>
|
||
<el-form-item label="Figure Describe :">
|
||
<common-content
|
||
type="content"
|
||
:isAutomaticUpdate="true"
|
||
:value="picStyle.note"
|
||
:show-ref-button="false"
|
||
:chanFerForm="chanFerForm"
|
||
:body-cite-id-order="articleCiteIdOrder"
|
||
@getContent="getContent"
|
||
@openLatexEditor="openLatexEditor"
|
||
@openRefSelector="(d) => handleOpenRefSelector(d, 'tinymceChildImgNote')"
|
||
v-if="pictVisible"
|
||
@updateChange="(res) => updateChange(res, 'imgNote')"
|
||
:height="400"
|
||
ref="tinymceChildImgNote"
|
||
style="margin-left: -115px"
|
||
></common-content>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<span slot="footer" class="dialog-footer">
|
||
<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 Figure
|
||
</el-button>
|
||
</span>
|
||
</el-dialog>
|
||
|
||
<!-- 添加表格 -->
|
||
<el-drawer
|
||
title="我嵌套了表格!"
|
||
class="editTableDialog"
|
||
destroy-on-close
|
||
v-if="threeVisible"
|
||
:title="lineStyle.visiTitle"
|
||
:visible.sync="threeVisible"
|
||
:wrapperClosable="false"
|
||
:close-on-click-modal="false"
|
||
direction="rtl"
|
||
size="80vw"
|
||
>
|
||
<el-form ref="editMes" :model="lineStyle" label-width="80px">
|
||
<!-- <common-late-x></common-late-x> -->
|
||
<!-- :id="`editor-${new Date().getTime()}-${lineStyle.am_id}-${lineStyle.amt_id}-title`" -->
|
||
<el-form-item label="Title:">
|
||
<span slot="label">
|
||
<font style="color: #f56c6c; margin-right: 5px">*</font>
|
||
Title:
|
||
</span>
|
||
<common-content
|
||
type="content"
|
||
:id="`editor-${new Date().getTime()}-${lineStyle.am_id}-${lineStyle.amt_id}-title`"
|
||
:isAutomaticUpdate="true"
|
||
:value="lineStyle.title"
|
||
:show-ref-button="false"
|
||
@getContent="getContent"
|
||
@openLatexEditor="openLatexEditor"
|
||
v-if="threeVisible"
|
||
@updateChange="(res) => updateChange(res, 'title')"
|
||
@editorInput="onTableModalEditorInput"
|
||
:height="120"
|
||
ref="tinymceChildTitle"
|
||
style="margin-left: -115px"
|
||
></common-content>
|
||
</el-form-item>
|
||
<el-form-item label="Word">
|
||
<span slot="label">
|
||
<font style="color: #f56c6c; margin-right: 5px">*</font>
|
||
Table:
|
||
</span>
|
||
|
||
<common-table
|
||
:articleId="articleId"
|
||
:chanFerForm="chanFerForm"
|
||
:body-cite-id-order="tableModalBodyCiteOrder"
|
||
@getContent="getContent"
|
||
v-if="threeVisible"
|
||
ref="commonTable"
|
||
@openLatexEditor="openLatexEditor"
|
||
@openRefSelector="handleOpenRefSelector"
|
||
@editorInput="onTableModalEditorInput"
|
||
:lineStyle="lineStyle"
|
||
></common-table>
|
||
</el-form-item>
|
||
<el-form-item label="Note:">
|
||
<!-- :id="`editor-${new Date().getTime()}-${lineStyle.am_id}-${lineStyle.amt_id}-note`" -->
|
||
<common-content
|
||
type="content"
|
||
:id="`editor-${new Date().getTime()}-${lineStyle.am_id}-${lineStyle.amt_id}-note`"
|
||
:isAutomaticUpdate="true"
|
||
:value="lineStyle.note"
|
||
:show-ref-button="false"
|
||
:chanFerForm="chanFerForm"
|
||
:body-cite-id-order="tableModalBodyCiteOrder"
|
||
@getContent="getContent"
|
||
@openLatexEditor="openLatexEditor"
|
||
@openRefSelector="(d) => handleOpenRefSelector(d, 'tinymceChildNote')"
|
||
v-if="threeVisible"
|
||
@updateChange="(res) => updateChange(res, 'note')"
|
||
@editorInput="onTableModalEditorInput"
|
||
:height="120"
|
||
ref="tinymceChildNote"
|
||
></common-content>
|
||
</el-form-item>
|
||
</el-form>
|
||
<p style="margin-top: 20px; text-align: right">
|
||
<el-button @click="threeVisible = false"> Cancel </el-button>
|
||
<el-button
|
||
type="primary"
|
||
plain
|
||
@click="handleSaveTable"
|
||
style="background-color: #006699 !important; background: #006699 !important; margin-right: 20px; color: #fff !important"
|
||
>
|
||
save Table
|
||
</el-button>
|
||
</p>
|
||
</el-drawer>
|
||
<el-drawer
|
||
title="我嵌套了表格!"
|
||
class="editTableDialog"
|
||
destroy-on-close
|
||
v-if="tablesHtmlVisible"
|
||
:title="lineStyle.visiTitle"
|
||
:visible.sync="tablesHtmlVisible"
|
||
:wrapperClosable="false"
|
||
:close-on-click-modal="false"
|
||
direction="rtl"
|
||
size="80vw"
|
||
>
|
||
<div style="display: flex; flex-wrap: wrap; gap: 10px; justify-content: start">
|
||
<div v-for="(item, i) in uploadWordTables" class="uploadWordTableBox">
|
||
<el-button @click="addUploadWordTable(item)" size="mini" class="insertTable"> 插入 </el-button>
|
||
<div class="thumbnailTableBox wordTableHtml table_Box pMain myeditabledivTable drop-target">
|
||
<p style="font-size: 12px; padding: 10px; box-sizing: border-box">Table {{ i + 1 }}</p>
|
||
<table border="1" :style="`width: 800px;zoom:${zoomNum};border-collapse: collapse; text-align: center`">
|
||
<tr
|
||
v-for="(row, i) in item.table_data"
|
||
:key="i"
|
||
:class="{ 'table-header-row': isHeaderRow(i, item.table_data) }"
|
||
>
|
||
<td
|
||
style="font-size: 20px"
|
||
v-for="(cell, i1) in row"
|
||
:key="i1"
|
||
:colspan="`${cell.colspan || 1}`"
|
||
:rowspan="`${cell.rowspan || 1}`"
|
||
>
|
||
<span v-html="cell.text"></span>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</el-drawer>
|
||
<el-dialog
|
||
destroy-on-close
|
||
v-if="commentVisible"
|
||
title="Comment"
|
||
:visible.sync="commentVisible"
|
||
width="600px"
|
||
:close-on-click-modal="false"
|
||
>
|
||
<el-form ref="editMes" :model="commentForm" label-width="115px">
|
||
<el-form-item label="Select Content:" v-if="commentForm.content">
|
||
<p
|
||
style="background: #eef0f4; line-height: 20px; padding: 10px; box-sizing: border-box"
|
||
v-html="commentForm.content"
|
||
></p>
|
||
</el-form-item>
|
||
<el-form-item label="Word">
|
||
<span slot="label">
|
||
<font style="color: #f56c6c; margin-right: 5px">*</font>
|
||
Comment :
|
||
</span>
|
||
|
||
<tinymce
|
||
ref="tinymceChildComment"
|
||
@getContent="getContent"
|
||
:value="commentForm.remark"
|
||
class="paste-area text-container"
|
||
toolbar="bold italic subscript superscript clearButton "
|
||
style=""
|
||
></tinymce>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<span slot="footer" class="dialog-footer">
|
||
<el-button @click="commentVisible = false"> Cancel </el-button>
|
||
<el-button type="primary" @click="handleSaveComment">
|
||
<!-- <i class="el-icon-finished" style="margin-right: 5px"></i> -->
|
||
Save Comment
|
||
</el-button>
|
||
</span>
|
||
</el-dialog>
|
||
<el-dialog
|
||
destroy-on-close
|
||
v-if="editVisible"
|
||
title="Edit Content"
|
||
:visible.sync="editVisible"
|
||
width="1200px"
|
||
:close-on-click-modal="false"
|
||
>
|
||
<el-form ref="editMes" :model="contentStyle" label-width="115px">
|
||
<el-form-item label="Word">
|
||
<span slot="label">
|
||
<font style="color: #f56c6c; margin-right: 5px">*</font>
|
||
Content :
|
||
</span>
|
||
|
||
<common-content
|
||
type="content"
|
||
@openAddTable="openAddTable"
|
||
:value="currentContent.content"
|
||
@getContent="getContent"
|
||
@openLatexEditor="openLatexEditor"
|
||
@openRefSelector="handleOpenRefSelector"
|
||
:chanFerForm="chanFerForm"
|
||
:body-cite-id-order="editModalBodyCiteOrder"
|
||
:table-link-cite-max-map="tableLinkCiteMaxMap"
|
||
@editorInput="onEditModalEditorInput"
|
||
v-if="editVisible"
|
||
ref="commonContent"
|
||
style="margin-left: -115px"
|
||
></common-content>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<span slot="footer" class="dialog-footer">
|
||
<el-button @click="editVisible = false"> Cancel </el-button>
|
||
<el-button type="primary" @click="handleSaveContent">
|
||
<!-- <i class="el-icon-finished" style="margin-right: 5px"></i> -->
|
||
Save
|
||
</el-button>
|
||
</span>
|
||
</el-dialog>
|
||
<el-dialog
|
||
destroy-on-close
|
||
v-if="addContentVisible"
|
||
title="Add Content"
|
||
:visible.sync="addContentVisible"
|
||
width="1200px"
|
||
:close-on-click-modal="false"
|
||
>
|
||
<el-form ref="editMes" :model="addContent" label-width="115px">
|
||
<el-form-item label="Word">
|
||
<span slot="label">
|
||
<font style="color: #f56c6c; margin-right: 5px">*</font>
|
||
Content :
|
||
</span>
|
||
<common-content
|
||
:value="addContent.content"
|
||
@getContent="getContent"
|
||
type="content"
|
||
@openLatexEditor="openLatexEditor"
|
||
@openRefSelector="handleOpenRefSelector"
|
||
:chanFerForm="chanFerForm"
|
||
:body-cite-id-order="articleCiteIdOrder"
|
||
v-if="addContentVisible"
|
||
ref="addContent"
|
||
style="margin-left: -115px"
|
||
></common-content>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<span slot="footer" class="dialog-footer">
|
||
<el-button @click="addContentVisible = false"> Cancel </el-button>
|
||
<el-button type="primary" @click="handleSaveAddContent">
|
||
<!-- <i class="el-icon-finished" style="margin-right: 5px"></i> -->
|
||
Save
|
||
</el-button>
|
||
</span>
|
||
</el-dialog>
|
||
|
||
<common-late-x v-if="showLateX" @close="showLateX = false" @save="saveLateX" :LateXInfo="LateXInfo"></common-late-x>
|
||
|
||
<el-dialog
|
||
:title="$t('wordCite.selectRef')"
|
||
:visible.sync="refSelectorVisible"
|
||
width="1200px"
|
||
append-to-body
|
||
:close-on-click-modal="false"
|
||
@closed="onRefSelectorDialogClosed"
|
||
>
|
||
|
||
|
||
<div class="duplicateRefBox" v-if="chanFerFormRepeatList.length > 0">
|
||
<el-tooltip class="item" effect="dark" content="Duplicate references" placement="top">
|
||
<img src="../../assets/img/repeat.png" alt="" style="width: 22px; height: 22px" />
|
||
</el-tooltip>
|
||
|
||
<span @click="handleContainerClick" style="margin-left: 5px" v-html="getRepeatRefHtml()"> </span>
|
||
</div>
|
||
<div>
|
||
<el-input
|
||
v-model="refSelectorQuickPick"
|
||
size="small"
|
||
clearable
|
||
:placeholder="$t('wordCite.quickPickPlaceholder')"
|
||
style="width: calc(100% - 340px);"
|
||
/>
|
||
<el-button size="small" type="primary" plain @click="applyRefSelectorQuickPick" style="margin-left: 20px;">
|
||
{{ $t('wordCite.quickPickApply') }}
|
||
</el-button>
|
||
<el-button
|
||
style="float: right; margin-bottom: 30px"
|
||
icon="el-icon-plus"
|
||
@mousedown.stop
|
||
@click.stop="addLine('Add')"
|
||
type="success"
|
||
size="small"
|
||
plain
|
||
>Cite new reference</el-button
|
||
>
|
||
</div>
|
||
|
||
|
||
<el-table
|
||
:row-style="tableRowStyle"
|
||
ref="refSelectorTable"
|
||
:data="refSelectorTableData"
|
||
@selection-change="handleRefSelectionChange"
|
||
@row-click="handleRefSelectorRowClick"
|
||
style="width: 100%"
|
||
max-height="500"
|
||
size="small"
|
||
row-key="p_refer_id"
|
||
>
|
||
<el-table-column type="selection" width="45" :reserve-selection="true"></el-table-column>
|
||
<el-table-column type="index" label="No." width="60" align="center">
|
||
<template slot-scope="scope">
|
||
<i v-if="scope.row.is_change == 1" class="itemChanged"></i>
|
||
<!-- <el-tooltip
|
||
class="Duplicate-item"
|
||
effect="dark"
|
||
:content="getParsingInfo(scope.row, scope.$index)"
|
||
placement="top"
|
||
|
||
> -->
|
||
<img v-if="scope.row.is_repeat == 1" src="../../assets/img/repeat.png" alt="" style="width: 22px; height: 22px" />
|
||
<!-- </el-tooltip> -->
|
||
|
||
<span>{{ scope.$index + 1 }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="State" width="55" align="center">
|
||
<template slot-scope="scope">
|
||
<span
|
||
class="status ok"
|
||
:class="scope.row.refer_type == 'journal' ? getJournalDateno(scope.row.dateno, 'status') : ''"
|
||
v-if="
|
||
((scope.row.refer_type == 'journal' && scope.row.doilink != '' && scope.row.cs == 1) ||
|
||
(scope.row.refer_type == 'book' && scope.row.isbn != '' && scope.row.cs == 1)) &&
|
||
scope.row.retract == 0
|
||
"
|
||
>
|
||
<i class="el-icon-circle-check"></i>
|
||
</span>
|
||
<span class="status warn" v-else>
|
||
<i class="el-icon-warning-outline"></i>
|
||
</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column :label="$t('wordCite.reference')">
|
||
<template slot-scope="scope">
|
||
<el-tag
|
||
v-if="isUncitedReference(scope.row)"
|
||
class="uncited-tag"
|
||
size="mini"
|
||
type="info"
|
||
effect="plain"
|
||
style="margin: 0 8px 6px 0"
|
||
>
|
||
{{ $t('wordCite.uncited') }}
|
||
</el-tag>
|
||
<!-- journal 形式 -->
|
||
<div style="text-align: left" v-if="scope.row.refer_type == 'journal'" class="reference-item">
|
||
<p>
|
||
{{ scope.row.author }} <span v-html="formatTitle(scope.row.title)"></span>. <em>{{
|
||
scope.row.joura
|
||
}}</em
|
||
>. <span :class="getJournalDateno(scope.row.dateno, 'title')">{{ scope.row.dateno }}</span
|
||
>.<br />
|
||
</p>
|
||
<a class="doiLink" :href="scope.row.doilink" target="_blank">{{ scope.row.doilink }}</a>
|
||
</div>
|
||
<!-- book 形式 -->
|
||
<div style="text-align: left" v-if="scope.row.refer_type == 'book'" class="reference-item">
|
||
<p>
|
||
{{ scope.row.author }} <span v-html="formatTitle(scope.row.title)"></span>. {{
|
||
scope.row.dateno
|
||
}}. <br />
|
||
</p>
|
||
<a class="doiLink" :href="scope.row.isbn" target="_blank">{{ scope.row.isbn }}</a>
|
||
</div>
|
||
<!-- other 形式 -->
|
||
<p class="wrongLine reference-item" style="text-align: left" v-if="scope.row.refer_type == 'other'">
|
||
<span v-html="formatTitle(scope.row.refer_frag)"></span>
|
||
</p>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column :label="$t('wordCite.originalOrder')" width="120" align="center">
|
||
<template slot-scope="scope">
|
||
<span>{{ refSelectorOrderIndexDisplay(scope.row) }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column align="center" :width="'200'">
|
||
<div slot-scope="scope">
|
||
<div class="operation" style="">
|
||
<el-button
|
||
style="margin-left: 10px"
|
||
@mousedown.stop
|
||
@click.stop="change(scope.row, 'Edit')"
|
||
plain
|
||
type="primary"
|
||
size="mini"
|
||
icon="el-icon-edit"
|
||
>edit</el-button
|
||
>
|
||
|
||
<el-button
|
||
type="danger"
|
||
icon="el-icon-delete"
|
||
size="mini"
|
||
style=""
|
||
plain
|
||
@mousedown.stop
|
||
@click.stop="deleteLine(scope.row)"
|
||
>delete</el-button
|
||
>
|
||
</div>
|
||
</div>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<div style="display: flex; gap: 10px; align-items: center; margin: 10px 0;">
|
||
|
||
<div v-if="refSelectedRows.length > 0" style="margin-bottom: 10px; font-size: 13px; color: #606266">
|
||
{{ $t('wordCite.selected') }}:
|
||
<b v-if="refPreviewLabel" style="color: #0082aa">[{{ refPreviewLabel }}]</b>
|
||
</div>
|
||
<div style="flex: 1;"></div>
|
||
|
||
<el-button size="small" @click="refSelectorVisible = false">
|
||
{{ $t('wordCite.cancel') }}
|
||
</el-button>
|
||
<el-button
|
||
size="small"
|
||
type="primary"
|
||
:disabled="refSelectedRows.length === 0"
|
||
@click="handleConfirmRefCite"
|
||
>
|
||
{{ $t('wordCite.confirm') }}
|
||
</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
|
||
<!-- 引用:编辑 / 新增 / 删除(复用 editPublicRefRdit.vue 逻辑) -->
|
||
<el-dialog
|
||
:close-on-click-modal="false"
|
||
destroy-on-close
|
||
:append-to-body="true"
|
||
v-loading="addLoading"
|
||
:title="dialogTitle + ' References'"
|
||
:visible.sync="editboxVisible"
|
||
width="1200px"
|
||
@close="cancelSave"
|
||
>
|
||
<p class="yinyongPre c888" style="margin-bottom: 20px; color: #888; line-height: 24px">
|
||
You may add or modify the references. The system will automatically identify and retrieve the reference information. Please
|
||
note that if the reference type is set to “Other”, the “Parse” button will not be available.
|
||
</p>
|
||
|
||
<el-form :model="refenceForm" :rules="refenceFormrules" ref="refenceForm" label-width="150px" class="editForm mt10">
|
||
<el-form-item label="Source:">
|
||
<el-select v-model="SourceType" placeholder="please pick">
|
||
<el-option v-for="item in sourceOptions" :key="item.value" :label="item.label" :value="item.value"> </el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="Content:" required prop="content">
|
||
<div class="automatic-parsing-box">
|
||
<el-input
|
||
style="border: none"
|
||
class="automaticParsing"
|
||
type="textarea"
|
||
rows="5"
|
||
v-model="refenceForm.content"
|
||
placeholder=""
|
||
></el-input>
|
||
<span v-if="isShowParsing" style="color: #409eff"
|
||
>We have detected updates to the reference content. You need to click the "Automatic parsing" button to
|
||
recognize them.</span
|
||
>
|
||
</div>
|
||
</el-form-item>
|
||
|
||
<div v-if="!isShowParsing && isShowParsingData && SourceType != 'other'">
|
||
<el-form-item style="margin: 0 0 30px">
|
||
<div class="line" style="border: 1px dashed #dcdfe6"></div>
|
||
</el-form-item>
|
||
|
||
<div v-show="SourceType == 'journal'">
|
||
<el-form-item label="Doi:" prop="doi">
|
||
<el-input v-model="refenceForm.doi"></el-input>
|
||
</el-form-item>
|
||
</div>
|
||
|
||
<div v-show="SourceType != 'other'">
|
||
<el-form-item label="Author(s):" required prop="author">
|
||
<el-input v-model="refenceForm.author"></el-input>
|
||
</el-form-item>
|
||
<el-form-item :label="SourceType == 'journal' ? 'Title:' : 'Book'" required prop="title">
|
||
<el-input v-model="refenceForm.title"></el-input>
|
||
</el-form-item>
|
||
<el-form-item label="Publication Details:" required prop="dateno">
|
||
<el-input v-model="refenceForm.dateno"></el-input>
|
||
</el-form-item>
|
||
</div>
|
||
<div v-show="SourceType == 'journal'">
|
||
<el-form-item label="Journal:" required prop="joura">
|
||
<el-input v-model="refenceForm.joura"></el-input>
|
||
</el-form-item>
|
||
<el-form-item label="DOI/URL:" required prop="doilink">
|
||
<el-input v-model="refenceForm.doilink"></el-input>
|
||
</el-form-item>
|
||
</div>
|
||
<div v-show="SourceType == 'book'">
|
||
<el-form-item label="ISBN:" required prop="isbn">
|
||
<el-input v-model="refenceForm.isbn"></el-input>
|
||
</el-form-item>
|
||
</div>
|
||
</div>
|
||
</el-form>
|
||
|
||
<span slot="footer" class="dialog-footer">
|
||
<el-button @click="cancelSave">Cancel</el-button>
|
||
<el-button
|
||
v-if="isShowParsing"
|
||
type="primary"
|
||
style="background-color: #409eff !important; border-color: #409eff !important"
|
||
@click="getParsingData()"
|
||
>Automatic parsing</el-button
|
||
>
|
||
<el-button v-else type="primary" @click="dialogTitle == 'Edit' ? saveChange() : saveAdd()">Save</el-button>
|
||
</span>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import bus from '@/components/common/bus';
|
||
import { del, isShallow } from 'vue';
|
||
import Tiff from 'tiff.js';
|
||
import { mediaUrl } from '@/common/js/commonJS.js'; // 引入通用逻辑
|
||
import Tinymce from '@/components/page/components/Tinymce';
|
||
import bottomTinymce from '@/components/page/components/Tinymce';
|
||
import catalogue from '@/components/page/components/table/catalogue.vue';
|
||
import editPublicRefTableOnly from './editPublicRefTableOnly.vue';
|
||
import { extractAutociteIdsFromHtmlString } from '@/utils/autociteHtml.js';
|
||
import {
|
||
collectCiteHtmlSourcesForMainListItem,
|
||
extractAutociteOrderFromMainList
|
||
} from '@/utils/autociteMainListOrder.js';
|
||
export default {
|
||
data() {
|
||
return {
|
||
zoomNum: (window.innerWidth * 0.38) / 850,
|
||
uploadWordTables: [],
|
||
tablesHtmlVisible: false,
|
||
tablesHtml: '',
|
||
LateXInfo: {},
|
||
isEditComment: false,
|
||
showLateX: false,
|
||
comments: [],
|
||
remarkImageUrl: 'https://submission.tmrjournals.com/public/usericon/20241222/4e77ba3f29ce3cf798b36f24dc411b76.png',
|
||
isFirstComponentLoaded: false,
|
||
isWordComponentLoaded: false,
|
||
currentContent: null,
|
||
editVisible: false,
|
||
currentId: null,
|
||
ManuscirptContent: [],
|
||
articleId: this.$route.query.id,
|
||
isShowComment: false,
|
||
urlList: {
|
||
executeProofreading: 'api/Proofread/change',
|
||
delete: 'api/Preaccept/delArticleMains',
|
||
addRow: 'api/Preaccept/addBlankRow',
|
||
addComment: 'api/Preaccept/createArticleMainCheckForEditor',
|
||
editComment: 'api/Preaccept/editArticleMainCheck',
|
||
solveComment: 'api/Preaccept/completeArticleMainCheckForAuthor',
|
||
cancelSolveComment: 'api/Preaccept/rejectArticleMainCheckForEditor',
|
||
deleteComment: 'api/Preaccept/delArticleMainCheckForEditor',
|
||
replyComment: 'api/Preaccept/rejectArticleMainCheckForAuthor',
|
||
content: 'api/Preaccept/getArticleMainsRecycle',
|
||
huifuContent: 'api/Preaccept/replyArticleRecycle',
|
||
editContent: 'api/Preaccept/editArticleMainsForAuthor',
|
||
setPositioningTable: 'api/Preaccept/positioningTable',
|
||
removePositioningTable: 'api/Preaccept/removeTable',
|
||
setPositioningImage: 'api/Preaccept/positioningImage',
|
||
removePositioningImage: 'api/Preaccept/removeImage',
|
||
addImage: 'api/Preaccept/addMainImage',
|
||
addTable: 'api/Preaccept/addMainTable',
|
||
editImage: 'api/Preaccept/editMainImage',
|
||
editTable: 'api/Preaccept/editMainTable',
|
||
deleteImage: 'api/Articlemain/removeMainImage',
|
||
deleteTable: 'api/Articlemain/removeMainTable'
|
||
},
|
||
wordStyle: `
|
||
// p {
|
||
// position: relative;
|
||
// padding: 8px 15px;
|
||
// min-height: 22px;
|
||
// border: 2px dashed #fff;
|
||
// border-radius: 5px;
|
||
// color: #606266;
|
||
// }
|
||
// p {
|
||
// font-size: 14px;
|
||
// line-height: 22px;
|
||
// }
|
||
|
||
.imgBox .chNumer {
|
||
position: absolute;
|
||
top: -2px;
|
||
right: -1px;
|
||
border-radius: 3px;
|
||
font-size: 10px;
|
||
background-color: rgb(0 102 153 / 85%);
|
||
color: #fff;
|
||
padding: 0 6px;
|
||
}
|
||
|
||
.MaxPicture {
|
||
text-align: center;
|
||
}
|
||
|
||
.MaxPicture > img {
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.font {
|
||
display: block;
|
||
margin: 0 auto;
|
||
font-size: 13px;
|
||
}
|
||
.tableTitle{
|
||
text-align:center!important;
|
||
font-weight: bold;
|
||
}
|
||
`,
|
||
tables: [],
|
||
htmlContent: '',
|
||
|
||
baseUrl: this.Common.baseUrl,
|
||
// baseUrl: 'https://submission.tmrjournals.com/',
|
||
// mediaUrl: this.Common.mediaUrl,//暂时注释2024121601
|
||
mediaUrl: mediaUrl, //
|
||
Art_Id: this.$route.query.id,
|
||
Art_Doi: this.$route.query.doi,
|
||
Art_web_Id: this.$route.query.artID,
|
||
Art_P_Id: '',
|
||
btnDisble: true,
|
||
detailTitle: '',
|
||
Main_List: [],
|
||
txtStyle: {
|
||
text: '',
|
||
ChGtpTxt: ''
|
||
},
|
||
txtVisible: false,
|
||
addContentVisible: false,
|
||
editProofreadingContentVisible: false,
|
||
proofreadingContent: {},
|
||
addContent: {},
|
||
lineStyle: {},
|
||
lineStyle1: {},
|
||
contentStyle: {},
|
||
lineTable: [],
|
||
threeVisible: false,
|
||
picStyle: {},
|
||
picStyle1: {},
|
||
commentForm: {},
|
||
commentVisible: false,
|
||
pictVisible: false,
|
||
typesettingType: 1,
|
||
imagesList: [],
|
||
exegesis: "The following contents'<b></b>,<i></i>'are necessary for the generation phase, please do not delete them!!!",
|
||
p_article_id: null,
|
||
chanFerForm: [],
|
||
chanFerFormRepeatList: [],
|
||
/** 全文 mycite 首次出现顺序(与稿面 common-word 一致),供 Edit Content 弹窗内 TinyMCE 显示 [1][2] 与重排列表 */
|
||
articleCiteIdOrder: [],
|
||
/** Edit Content 弹窗内当前 HTML(与保存合并逻辑一致),用于实时算出与稿面相同的 [n],避免仅依赖防抖后的 articleCiteIdOrder */
|
||
editModalDraftHtml: '',
|
||
/** 编辑器 getContent(raw) 快照;draft 为空时 editModalBodyCiteOrder 用其与 extract 对齐稿面 */
|
||
editModalSyncedHtml: '',
|
||
/** 表格抽屉:Title+Table+Note 合并稿,驱动 tableModalBodyCiteOrder(与 editModalDraftHtml 对 Edit Content 一致) */
|
||
tableModalDraftHtml: '',
|
||
refSelectorVisible: false,
|
||
refSelectorIsEdit: false,
|
||
refSelectedRows: [],
|
||
refSelectorSource: 'commonContent',
|
||
/** 表格抽屉内合并稿防抖:按全文首次出现顺序更新 articleCiteIdOrder,避免角标停留在列表序号 [38] */
|
||
_tableReorderTimer: null,
|
||
/** 最近一次 getReferList 返回的 p_refer_id 顺序;与当前 chanFerForm 不一致时回写 batchUpdateRefer */
|
||
_lastReferListApiOrder: null,
|
||
/** 打开选择器时若带 currentRefIds(编辑已有引用),排序用「传值计算的顺序」;关闭后清空 */
|
||
refSelectorContextIds: [],
|
||
/** 选择参考文献弹窗:按 # 序号快速勾选,如 [5, 6, 10-15] */
|
||
refSelectorQuickPick: '',
|
||
|
||
/** 引用编辑弹窗(复用 editPublicRefRdit.vue 的新增/编辑/删除逻辑) */
|
||
editboxVisible: false,
|
||
dialogTitle: 'Edit',
|
||
SourceType: 'journal',
|
||
sourceOptions: [
|
||
{ label: 'Journal', value: 'journal' },
|
||
{ label: 'Book', value: 'book' },
|
||
{ label: 'Other', value: 'other' }
|
||
],
|
||
refenceForm: {
|
||
doi: '',
|
||
p_article_id: null,
|
||
p_refer_id: null,
|
||
pre_p_refer_id: null,
|
||
refer_type: '',
|
||
author: '',
|
||
title: '',
|
||
joura: '',
|
||
dateno: '',
|
||
doilink: '',
|
||
isbn: '',
|
||
content: ''
|
||
},
|
||
old_refence_content: '',
|
||
old_refence_type: '',
|
||
isShowParsing: false,
|
||
isShowParsingData: false,
|
||
addLoading: false,
|
||
refenceFormrules: {
|
||
doi: [{ required: true, message: 'The Doi cannot be empty', trigger: 'blur' }],
|
||
author: [{ required: true, message: 'The Author(s) cannot be empty', trigger: 'blur' }],
|
||
title: [{ required: true, message: 'The Title cannot be empty', trigger: 'blur' }],
|
||
joura: [{ required: true, message: 'The Journal cannot be empty', trigger: 'blur' }],
|
||
doilink: [{ required: true, message: 'The DOI/URL cannot be empty', trigger: 'blur' }],
|
||
dateno: [{ required: true, message: 'The Publication Details cannot be empty', trigger: 'blur' }],
|
||
isbn: [{ required: true, message: 'The ISBN cannot be empty', trigger: 'blur' }],
|
||
content: [{ required: true, message: 'The Content cannot be empty', trigger: 'blur' }]
|
||
}
|
||
};
|
||
},
|
||
components: {
|
||
Tinymce,
|
||
bottomTinymce,
|
||
catalogue,
|
||
editPublicRefTableOnly
|
||
},
|
||
computed: {
|
||
/** 选择器打开时:无传值用 articleCiteIdOrder;有传值且 Edit Content 打开时用合并稿 editModalBodyCiteOrder,与 # 列、正文 [n] 一致 */
|
||
refSelectorOrderForPreview() {
|
||
if (!this.refSelectorVisible) {
|
||
return Array.isArray(this.articleCiteIdOrder) ? this.articleCiteIdOrder : [];
|
||
}
|
||
const hasCtx = Array.isArray(this.refSelectorContextIds) && this.refSelectorContextIds.length > 0;
|
||
if (hasCtx && this.editVisible) {
|
||
const o = this.editModalBodyCiteOrder;
|
||
return Array.isArray(o) && o.length > 0 ? o : this.articleCiteIdOrder || [];
|
||
}
|
||
if (hasCtx && this.threeVisible && this.lineStyle && this.lineStyle.am_id != null) {
|
||
const o = this.tableModalBodyCiteOrder;
|
||
return Array.isArray(o) && o.length > 0 ? o : this.articleCiteIdOrder || [];
|
||
}
|
||
return Array.isArray(this.articleCiteIdOrder) ? this.articleCiteIdOrder : [];
|
||
},
|
||
/** 选择器内表格行顺序:默认按正文 articleCiteIdOrder;有传值且处于编辑弹窗时按合并稿计算顺序 */
|
||
refSelectorTableData() {
|
||
const refs = Array.isArray(this.chanFerForm) ? [...this.chanFerForm] : [];
|
||
if (!refs.length) return [];
|
||
let order;
|
||
const hasCtx = Array.isArray(this.refSelectorContextIds) && this.refSelectorContextIds.length > 0;
|
||
if (hasCtx && this.editVisible) {
|
||
order = this.editModalBodyCiteOrder;
|
||
} else if (hasCtx && this.threeVisible && this.lineStyle && this.lineStyle.am_id != null) {
|
||
order = this.tableModalBodyCiteOrder;
|
||
} else {
|
||
order = this.articleCiteIdOrder;
|
||
}
|
||
if (!Array.isArray(order) || order.length === 0) return refs;
|
||
return this.sortChanFerRowsByOrder(refs, order);
|
||
},
|
||
/** 与正文 mycite 一致:只展示已在列表中且有序号的文献,不显示「?」 */
|
||
refPreviewLabel() {
|
||
const refList = Array.isArray(this.chanFerForm) ? this.chanFerForm : [];
|
||
const refMap = refList.reduce((acc, item) => {
|
||
const key = item && item.p_refer_id != null ? String(item.p_refer_id) : '';
|
||
if (key) acc[key] = item;
|
||
return acc;
|
||
}, {});
|
||
|
||
const order = (this.refSelectorVisible ? this.refSelectorOrderForPreview : this.articleCiteIdOrder) || [];
|
||
const citeMap = this.buildDisplayCiteMap(order);
|
||
|
||
const ctx = Array.isArray(this.refSelectorContextIds) ? this.refSelectorContextIds.map(String) : [];
|
||
const selectedIds = (this.refSelectedRows || [])
|
||
.map((r) => (r && r.p_refer_id != null ? String(r.p_refer_id) : ''))
|
||
.filter(Boolean);
|
||
|
||
let idsForPreview = [];
|
||
if (this.refSelectorVisible && ctx.length > 0) {
|
||
const hasMissingInCtx = ctx.some((id) => !refMap[id]);
|
||
if (hasMissingInCtx) {
|
||
idsForPreview = ctx;
|
||
} else if (selectedIds.length > 0) {
|
||
idsForPreview = selectedIds;
|
||
} else {
|
||
idsForPreview = ctx;
|
||
}
|
||
} else if (selectedIds.length > 0) {
|
||
idsForPreview = selectedIds;
|
||
}
|
||
|
||
if (!idsForPreview.length) return '';
|
||
|
||
const sortedIds = this.sortAutociteIdsByCiteNumber(idsForPreview, order);
|
||
const parts = sortedIds.map((id) => {
|
||
const ref = refMap[id];
|
||
const no = ref ? citeMap[id] : null;
|
||
const num = no != null && no !== '' ? String(no) : null;
|
||
return { id, ref, num };
|
||
});
|
||
|
||
const numsForLabel = parts
|
||
.map((p) => p.num)
|
||
.filter((n) => n != null && n !== '')
|
||
.map(Number);
|
||
|
||
if (numsForLabel.length === 0) return '';
|
||
return this.formatCiteNumbers(numsForLabel);
|
||
},
|
||
catalogueContent() {
|
||
const base = Array.isArray(this.Main_List) ? this.Main_List : [];
|
||
if (!Array.isArray(this.chanFerForm) || this.chanFerForm.length === 0) return base;
|
||
return [
|
||
...base,
|
||
{
|
||
am_id: 'References',
|
||
content: 'References',
|
||
is_h1: 1,
|
||
is_h2: 0
|
||
}
|
||
];
|
||
},
|
||
/** 弹窗内引用角标:与稿面同源 —— 始终用 extractAutociteOrderFromMainList(Main_List, am_id, 当前用于合并的 HTML) */
|
||
editModalBodyCiteOrder() {
|
||
if (!this.editVisible || !this.currentContent || this.currentContent.am_id == null) {
|
||
return this.articleCiteIdOrder;
|
||
}
|
||
const d = this.editModalDraftHtml;
|
||
const draftTrim = d != null && String(d).trim() !== '' ? d : '';
|
||
const s = this.editModalSyncedHtml;
|
||
const syncedTrim = s != null && String(s).trim() !== '' ? s : '';
|
||
const saved = this.currentContent.content;
|
||
const savedTrim = saved != null && String(saved).trim() !== '' ? saved : '';
|
||
const htmlForExtract = draftTrim || syncedTrim || savedTrim;
|
||
if (!htmlForExtract) {
|
||
return this.articleCiteIdOrder;
|
||
}
|
||
const order = extractAutociteOrderFromMainList(this.Main_List, this.currentContent.am_id, htmlForExtract);
|
||
return order.length > 0 ? order : this.articleCiteIdOrder;
|
||
},
|
||
/**
|
||
* mytable(data-id) -> 该表格中已出现引用的最大全局序号
|
||
* 用于正文链接表格后,后续 [2,3] 按“表内最大序号之后”继续映射(如 33,34)
|
||
*/
|
||
tableLinkCiteMaxMap() {
|
||
const out = {};
|
||
const list = Array.isArray(this.Main_List) ? this.Main_List : [];
|
||
if (!list.length) return out;
|
||
const order = Array.isArray(this.editModalBodyCiteOrder) ? this.editModalBodyCiteOrder : this.articleCiteIdOrder;
|
||
const citeMap = this.buildDisplayCiteMap(order || []);
|
||
list.forEach((p) => {
|
||
if (!p || Number(p.type) !== 2) return;
|
||
const candidates = collectCiteHtmlSourcesForMainListItem(p);
|
||
const ids = [];
|
||
candidates.forEach((raw) => {
|
||
extractAutociteIdsFromHtmlString(raw).forEach((id) => {
|
||
if (!ids.includes(id)) ids.push(id);
|
||
});
|
||
});
|
||
const numsFromIds = ids
|
||
.map((id) => Number(citeMap[String(id)]))
|
||
.filter((n) => !Number.isNaN(n) && n > 0);
|
||
// 兜底:有些表格仍是纯文本 [34](未转 mycite),这里直接取括号数字最大值参与 max
|
||
const numsFromPlain = [];
|
||
candidates.forEach((raw) => {
|
||
this.extractBracketCiteNumbersFromText(raw).forEach((n) => numsFromPlain.push(n));
|
||
});
|
||
const nums = [...numsFromIds, ...numsFromPlain];
|
||
const max = nums.length ? Math.max(...nums) : 0;
|
||
if (max <= 0) return;
|
||
if (p.am_id != null) out[String(p.am_id)] = max;
|
||
if (p.amt_id != null) out[String(p.amt_id)] = max;
|
||
if (p.p_main_table_id != null) out[String(p.p_main_table_id)] = max;
|
||
if (p.table) {
|
||
if (p.table.amt_id != null) out[String(p.table.amt_id)] = max;
|
||
if (p.table.am_id != null) out[String(p.table.am_id)] = max;
|
||
if (p.table.p_main_table_id != null) out[String(p.table.p_main_table_id)] = max;
|
||
if (p.table.table_id != null) out[String(p.table.table_id)] = max;
|
||
}
|
||
});
|
||
return out;
|
||
},
|
||
/** 表格抽屉内角标:与 Edit Content 同源,按 Main_List + Title/表/Note 合并稿做全文首次出现排序,避免仍用 articleCiteIdOrder 列表下标 [38] */
|
||
tableModalBodyCiteOrder() {
|
||
if (!this.threeVisible || !this.lineStyle || this.lineStyle.am_id == null) {
|
||
return this.articleCiteIdOrder;
|
||
}
|
||
const draft = this.tableModalDraftHtml;
|
||
if (draft == null || draft === '') {
|
||
return this.articleCiteIdOrder;
|
||
}
|
||
/** 正文里 <mytable> 指向本表时,展开用当前抽屉合并稿,角标与「全文该 mytable 之前」顺序一致 */
|
||
const citeOpts = {
|
||
tableDraftAmId: this.lineStyle.am_id,
|
||
tableDraftHtml: draft
|
||
};
|
||
const order = extractAutociteOrderFromMainList(this.Main_List, this.lineStyle.am_id, draft, citeOpts);
|
||
return order.length > 0 ? order : this.articleCiteIdOrder;
|
||
}
|
||
},
|
||
watch: {
|
||
editVisible(val) {
|
||
if (!val) {
|
||
this.editModalDraftHtml = '';
|
||
this.editModalSyncedHtml = '';
|
||
}
|
||
},
|
||
/** 计算属性 editModalBodyCiteOrder 变化后重绘 TinyMCE 角标,与 body-cite-id-order 一致 */
|
||
editModalBodyCiteOrder: {
|
||
handler() {
|
||
if (!this.editVisible) return;
|
||
this.$nextTick(() => {
|
||
this.refreshEditModalAutociteDisplay();
|
||
});
|
||
}
|
||
},
|
||
threeVisible(val) {
|
||
if (!val) this.tableModalDraftHtml = '';
|
||
},
|
||
// 监听计算属性
|
||
// combinedValue(newVal, oldVal) {
|
||
// console.log('value1 或 value2 发生变化');
|
||
// console.log('新值:', newVal);
|
||
// console.log('旧值:', oldVal);
|
||
// // 处理任意一个值变化的逻辑
|
||
// this.updateWordTiffImage(newVal);
|
||
// }
|
||
},
|
||
|
||
directives: {
|
||
// 注册一个局部的自定义指令 v-focus
|
||
focus: {
|
||
// 指令的定义
|
||
inserted: function (el) {
|
||
// 聚焦元素
|
||
el.querySelector('textarea').focus();
|
||
}
|
||
}
|
||
},
|
||
async created() {
|
||
localStorage.removeItem('scrollPosition');
|
||
this.isShowEditComment();
|
||
/** 先拿 p_article_id 并拉参考文献,再拉正文段落,避免稿面/角标早于 chanFerForm 就绪 */
|
||
await this.loadPreacceptArticleDetail();
|
||
await this.getDate();
|
||
this.getCommentList();
|
||
},
|
||
mounted() {
|
||
document.addEventListener('copy', (event) => {
|
||
// 获取用户选中的文本
|
||
const selection = document.getSelection().toString();
|
||
|
||
// 你可以修改剪贴板内容
|
||
// event.clipboardData.setData('text/plain', selection + '\n---来自我的系统---');
|
||
|
||
console.log('用户复制了内容:', selection);
|
||
// 阻止默认行为(如果需要自定义复制逻辑的话)
|
||
// event.preventDefault();
|
||
});
|
||
},
|
||
async activated() {
|
||
this.isShowEditComment();
|
||
await this.loadPreacceptArticleDetail();
|
||
await this.getDate();
|
||
this.getCommentList();
|
||
},
|
||
beforeDestroy() {
|
||
if (this._editModalCiteTimer) {
|
||
clearTimeout(this._editModalCiteTimer);
|
||
this._editModalCiteTimer = null;
|
||
}
|
||
if (this._tableReorderTimer) {
|
||
clearTimeout(this._tableReorderTimer);
|
||
this._tableReorderTimer = null;
|
||
}
|
||
},
|
||
|
||
methods: {
|
||
isUncitedReference(row) {
|
||
const id = row && row.p_refer_id != null ? String(row.p_refer_id) : '';
|
||
if (!id) return false;
|
||
const order = Array.isArray(this.articleCiteIdOrder) ? this.articleCiteIdOrder.map(String) : [];
|
||
if (!order.length) return false;
|
||
return !order.includes(id);
|
||
},
|
||
/** 参考文献:刷新(供编辑/新增/删除后更新选择器列表) */
|
||
changeRefer() {
|
||
return this.fetchReferList();
|
||
},
|
||
cancelSave() {
|
||
this.editboxVisible = false;
|
||
this.isShowParsing = false;
|
||
this.isShowParsingData = false;
|
||
this.old_refence_content = '';
|
||
this.old_refence_type = '';
|
||
this.$nextTick(() => {
|
||
if (this.$refs.refenceForm) {
|
||
try {
|
||
this.$refs.refenceForm.clearValidate();
|
||
} catch (e) {
|
||
/* ignore */
|
||
}
|
||
}
|
||
});
|
||
},
|
||
getParsingData() {
|
||
if (!this.refenceForm || !this.refenceForm.content) {
|
||
this.$message.error('The Content cannot be empty');
|
||
return;
|
||
}
|
||
const loading = this.$loading({
|
||
lock: true,
|
||
text: 'Loading...',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(0, 0, 0, 0.7)'
|
||
});
|
||
this.$api
|
||
.post('api/References/dealContent', {
|
||
content: this.refenceForm.content
|
||
})
|
||
.then((res) => {
|
||
loading.close();
|
||
this.isShowParsing = false;
|
||
this.isShowParsingData = true;
|
||
this.refenceForm.joura = res.data.joura;
|
||
this.refenceForm.author = res.data.author;
|
||
this.refenceForm.dateno = res.data.dateno;
|
||
this.refenceForm.doilink = res.data.doilink;
|
||
this.refenceForm.doi = res.data.doi;
|
||
this.refenceForm.title = res.data.title;
|
||
this.refenceForm.isbn = this.refenceForm.refer_type == 'book' ? res.data.doilink : res.data.isbn;
|
||
})
|
||
.catch((err) => {
|
||
loading.close();
|
||
this.$message.error(err);
|
||
});
|
||
},
|
||
getRefData(id) {
|
||
return this.$api
|
||
.post('api/References/get', {
|
||
account: localStorage.getItem('U_name'),
|
||
p_refer_id: id
|
||
})
|
||
.then((res) => {
|
||
if (res && res.status == 1) return res.data;
|
||
throw (res && res.msg) || 'get ref failed';
|
||
});
|
||
},
|
||
/** 引用:编辑 */
|
||
async change(row, optitle) {
|
||
this.dialogTitle = optitle;
|
||
this.isShowParsing = false;
|
||
this.isShowParsingData = false;
|
||
const loading = this.$loading({
|
||
lock: true,
|
||
text: 'Loading...',
|
||
background: 'rgba(0, 0, 0, 0.7)'
|
||
});
|
||
try {
|
||
const data = await this.getRefData(row.p_refer_id);
|
||
this.SourceType = data.refer_type ? data.refer_type : '';
|
||
this.refenceForm = {
|
||
doi: '',
|
||
p_article_id: this.p_article_id,
|
||
p_refer_id: row.p_refer_id,
|
||
pre_p_refer_id: null,
|
||
refer_type: data.refer_type ? data.refer_type : '',
|
||
author: data.author ? data.author : '',
|
||
doilink: data.doilink ? data.doilink : '',
|
||
dateno: data.dateno ? data.dateno : '',
|
||
isbn: data.isbn ? data.isbn : '',
|
||
joura: data.joura ? data.joura : '',
|
||
content: data.deal_content ? data.deal_content : '',
|
||
title: data.title ? data.title : ''
|
||
};
|
||
this.old_refence_content = JSON.parse(JSON.stringify(data.deal_content));
|
||
this.old_refence_type = JSON.parse(JSON.stringify(data.refer_type));
|
||
if (this.SourceType === 'book') {
|
||
this.refenceForm.isbn = data.doilink ? data.doilink : '';
|
||
}
|
||
this.editboxVisible = true;
|
||
} catch (e) {
|
||
this.$message.error(e);
|
||
} finally {
|
||
loading.close();
|
||
}
|
||
},
|
||
/** 引用:新增(在当前行下方插入) */
|
||
addLine(optitle) {
|
||
this.dialogTitle = optitle;
|
||
this.old_refence_type = '';
|
||
this.old_refence_content = '';
|
||
this.SourceType = 'journal';
|
||
this.refenceForm = {
|
||
doi: '',
|
||
p_article_id: this.p_article_id,
|
||
p_refer_id: null,
|
||
pre_p_refer_id: this.chanFerForm.length > 0 ? this.chanFerForm[this.chanFerForm.length - 1].p_refer_id : null,
|
||
refer_type: '',
|
||
joura: '',
|
||
author: '',
|
||
doilink: '',
|
||
dateno: '',
|
||
isbn: '',
|
||
content: '',
|
||
title: ''
|
||
};
|
||
this.isShowParsing = true;
|
||
this.isShowParsingData = false;
|
||
this.editboxVisible = true;
|
||
this.$nextTick(() => {
|
||
if (this.$refs.refenceForm) {
|
||
this.$refs.refenceForm.clearValidate(['content']);
|
||
this.$refs.refenceForm.clearValidate(['doi']);
|
||
}
|
||
});
|
||
},
|
||
/** 引用:删除 */
|
||
deleteLine(row) {
|
||
this.$confirm('Are you sure you want to remove this reference?', 'Tips', {
|
||
confirmButtonText: 'Sure',
|
||
cancelButtonText: 'Cancel',
|
||
type: 'warning'
|
||
})
|
||
.then(() => {
|
||
const loading = this.$loading({
|
||
lock: true,
|
||
text: 'Loading...',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(0, 0, 0, 0.7)'
|
||
});
|
||
this.$api
|
||
.post('api/Preaccept/delRefer', {
|
||
p_refer_id: row.p_refer_id
|
||
})
|
||
.then((res) => {
|
||
loading.close();
|
||
if (res.code == 0) {
|
||
this.$message.success('remove successed!');
|
||
this.changeRefer();
|
||
} else {
|
||
this.$message.error(res.msg);
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
loading.close();
|
||
this.$message.error(err);
|
||
});
|
||
})
|
||
.catch(() => {});
|
||
},
|
||
saveChange() {
|
||
this.editRefSave();
|
||
},
|
||
editRefSave() {
|
||
this.refenceForm.refer_type = this.SourceType;
|
||
const loading = this.$loading({
|
||
lock: true,
|
||
text: 'Loading...',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(0, 0, 0, 0.7)'
|
||
});
|
||
const form = { ...this.refenceForm };
|
||
this.$api
|
||
.post('api/Preaccept/editRefer', form)
|
||
.then((res) => {
|
||
loading.close();
|
||
if (res.code == 0) {
|
||
this.$message.success('successed!');
|
||
this.changeRefer();
|
||
this.cancelSave();
|
||
} else {
|
||
this.$message.error(res.msg);
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
loading.close();
|
||
this.$message.error(err);
|
||
});
|
||
},
|
||
saveAdd() {
|
||
this.refenceForm.refer_type = this.SourceType;
|
||
const loading = this.$loading({
|
||
lock: true,
|
||
text: 'Loading...',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(0, 0, 0, 0.7)'
|
||
});
|
||
const form = { ...this.refenceForm };
|
||
this.$api
|
||
.post('api/Preaccept/addReferByParticleid', form)
|
||
.then((res) => {
|
||
loading.close();
|
||
if (res.code == 0) {
|
||
this.$message.success('successed!');
|
||
this.changeRefer();
|
||
this.cancelSave();
|
||
} else {
|
||
this.$message.error(res.msg);
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
loading.close();
|
||
this.$message.error(err);
|
||
});
|
||
},
|
||
formatTitle(title) {
|
||
if (!title) return '';
|
||
// 使用正则匹配,'gi' 表示全局匹配且不区分大小写
|
||
// \b 确保是完整单词匹配,防止误伤含有这些字母的其他单词
|
||
const reg = /\b(Retracted|Retraction)\b/gi;
|
||
|
||
return title.replace(reg, (match) => {
|
||
return `<span style="color: red; font-weight: bold;">${match}</span>`;
|
||
});
|
||
},
|
||
getJournalDateno(dateno, type) {
|
||
if (dateno && typeof dateno === 'string') {
|
||
const hasInvalidColon = !dateno.includes(':') || (dateno.includes(':') && dateno.split(':').pop().trim() === '');
|
||
|
||
if (hasInvalidColon) {
|
||
return type === 'title' ? 'text-highlight' : 'warn';
|
||
}
|
||
}
|
||
return '';
|
||
},
|
||
tableRowStyle({ row }) {
|
||
if (row.is_repeat === 1) {
|
||
return { backgroundColor: '#ffececa1' }; // 浅红色
|
||
}
|
||
return {};
|
||
},
|
||
handleContainerClick(e) {
|
||
if (e.target.tagName === 'SPAN' && e.target.hasAttribute('data-ref')) {
|
||
const ref = Number(e.target.getAttribute('data-ref')); // 获取存储的 ref 值
|
||
this.handleClickRef(ref); // 触发实际逻辑
|
||
}
|
||
},
|
||
|
||
handleClickRef(ref) {},
|
||
getRepeatRefHtml() {
|
||
let warningText = 'Please note that ';
|
||
this.chanFerFormRepeatList.forEach((pair, index) => {
|
||
let singlePairText = '';
|
||
pair.forEach((ref, refIndex) => {
|
||
singlePairText += `<span style="font-weight: bold;color: #F56C6C;cursor: pointer;" data-ref="${ref}" >${
|
||
ref + 1
|
||
}</span>`;
|
||
if (refIndex !== pair.length - 1) {
|
||
singlePairText += ' and ';
|
||
}
|
||
});
|
||
warningText += `ref. ${singlePairText}`;
|
||
if (index === this.chanFerFormRepeatList.length - 1) {
|
||
warningText += ' are duplicates.';
|
||
} else {
|
||
warningText += ', and ';
|
||
}
|
||
});
|
||
return warningText;
|
||
},
|
||
getParsingInfo(data, index) {
|
||
const targetSubArr = this.chanFerFormRepeatList.find((subArr) => subArr.includes(index));
|
||
if (targetSubArr) {
|
||
let warningText = 'Please note that ';
|
||
const refElements = targetSubArr.map((ref, refIndex) => {
|
||
return `${ref + 1}`;
|
||
});
|
||
if (refElements.length > 0) {
|
||
if (refElements.length === 1) {
|
||
warningText += `ref. ${refElements[0]} is a duplicate.`;
|
||
} else {
|
||
const lastRef = refElements.pop(); // 取出最后一个 ref
|
||
warningText += `ref. ${refElements.join(', ')} and ${lastRef} are duplicates.`;
|
||
}
|
||
}
|
||
return warningText;
|
||
}
|
||
},
|
||
loadPreacceptArticleDetail() {
|
||
if (!this.articleId) return Promise.resolve();
|
||
return this.$api
|
||
.post('api/Article/getPreacceptArticleDetail', { article_id: this.articleId })
|
||
.then((res) => {
|
||
const pid = res.data && res.data.production && res.data.production.p_article_id;
|
||
this.p_article_id = pid;
|
||
if (pid != null && pid !== '') {
|
||
if (!this.Art_P_Id) this.Art_P_Id = pid;
|
||
return this.fetchReferList();
|
||
}
|
||
})
|
||
.catch(() => {});
|
||
},
|
||
fetchReferList() {
|
||
if (!this.p_article_id) return Promise.resolve();
|
||
return this.$api
|
||
.post('api/Production/getReferList', {
|
||
p_article_id: this.p_article_id
|
||
})
|
||
.then((res) => {
|
||
this._lastReferListApiOrder = this.referIdOrderSnapshot(res.data && res.data.refers).slice();
|
||
this.chanFerForm = res.data.refers;
|
||
this.chanFerFormRepeatList = Object.values(res.data.repeat || {});
|
||
for (let i = 0; i < this.chanFerForm.length; i++) {
|
||
this.chanFerForm[i].edit_mark = 1;
|
||
}
|
||
this.$nextTick(() => {
|
||
if (this.$refs.editPublicRefTableOnly) {
|
||
this.$refs.editPublicRefTableOnly.init();
|
||
}
|
||
if (this.editVisible && this.$refs.commonContent) {
|
||
this.refreshEditModalAutociteDisplay();
|
||
}
|
||
if (this.addContentVisible && this.$refs.addContent && this.$refs.addContent.refreshAutociteDisplay) {
|
||
this.$refs.addContent.refreshAutociteDisplay();
|
||
}
|
||
if (this.threeVisible && this.$refs.commonTable && this.$refs.commonTable.refreshAutociteDisplay) {
|
||
this.$refs.commonTable.refreshAutociteDisplay();
|
||
}
|
||
if (this.threeVisible && this.$refs.tinymceChildNote && this.$refs.tinymceChildNote.refreshAutociteDisplay) {
|
||
this.$refs.tinymceChildNote.refreshAutociteDisplay();
|
||
}
|
||
if (this.pictVisible && this.$refs.tinymceChildImgNote && this.$refs.tinymceChildImgNote.refreshAutociteDisplay) {
|
||
this.$refs.tinymceChildImgNote.refreshAutociteDisplay();
|
||
}
|
||
/** getReferList 会整表覆盖 chanFerForm,需再按正文首次出现顺序对齐,否则下方列表与 [n] 脱节 */
|
||
this.applyRefOrderAfterFetchReferList();
|
||
/** 正文序与接口序不一致时回写(Main_List 未就绪时可能无变化,getDate 后会再比一次) */
|
||
this.scheduleTryBatchSyncReferOrderIfOutOfSync();
|
||
});
|
||
})
|
||
.catch((err) => {
|
||
console.log(err);
|
||
});
|
||
},
|
||
/** 参考文献列表接口返回后:弹窗内按合并稿重排;稿面由 word 同步正文顺序 */
|
||
applyRefOrderAfterFetchReferList() {
|
||
if (this.editVisible && this.currentContent && this.currentContent.am_id != null) {
|
||
let html = this.editModalDraftHtml;
|
||
if (html === '' || html == null || !String(html).trim()) {
|
||
html = this.syncEditModalHtmlFromEditor();
|
||
if (html) this.editModalDraftHtml = html;
|
||
}
|
||
if (html === '' || html == null || !String(html).trim()) {
|
||
html = (this.currentContent && this.currentContent.content) || '';
|
||
}
|
||
this.flushReorderFromEditModal(html);
|
||
return;
|
||
}
|
||
if (this.threeVisible && this.lineStyle && this.lineStyle.am_id != null) {
|
||
this.$nextTick(() => {
|
||
this.flushReorderFromTableModal();
|
||
this.refreshTableDrawerAutociteDisplays();
|
||
});
|
||
return;
|
||
}
|
||
const w = this.$refs.commonWord;
|
||
if (w && typeof w.syncRefOrder === 'function') {
|
||
w.syncRefOrder();
|
||
}
|
||
/** 与稿面内部顺序对齐:父级 articleCiteIdOrder 供表格/图注等弹窗 TinyMCE 用,避免仍按列表下标显示 [38] */
|
||
this.reorderReferencesFromMainListBody(null, null);
|
||
},
|
||
/**
|
||
* 按 Main_List 各段正文中 mycite 首次出现顺序重排参考文献。
|
||
* draftAmId + draftHtml:合并「当前将保存的这一段」后再扫全文(点 Save 时与保存后一致);
|
||
* 传 (null, null) 表示完全以 Main_List 已存 content 为准。
|
||
* citeOptions:Edit Table 时传入 { tableDraftAmId, tableDraftHtml },使正文 mytable 展开与抽屉稿一致。
|
||
*/
|
||
reorderReferencesFromMainListBody(draftAmId, draftHtml, citeOptions) {
|
||
const order = extractAutociteOrderFromMainList(this.Main_List, draftAmId, draftHtml, citeOptions || {});
|
||
if (order.length > 0) {
|
||
this.handleReorderReferencesByBody(order);
|
||
}
|
||
},
|
||
/** Edit Table 抽屉:Title + 表格区 + Note 合并为一段,与 extractAutociteOrderFromMainList 的 draft 语义一致 */
|
||
getTableDrawerMergedDraftHtml() {
|
||
const parts = [];
|
||
const titleInst =
|
||
this.$refs.tinymceChildTitle && this.$refs.tinymceChildTitle.$refs && this.$refs.tinymceChildTitle.$refs.tinymceChild1;
|
||
if (titleInst && titleInst.editorInstance) {
|
||
parts.push(titleInst.editorInstance.getContent({ format: 'raw' }) || '');
|
||
} else if (this.lineStyle && typeof this.lineStyle.title === 'string') {
|
||
parts.push(this.lineStyle.title);
|
||
}
|
||
const tableInst = this.$refs.commonTable && this.$refs.commonTable.$refs && this.$refs.commonTable.$refs.tinymceChild1;
|
||
if (tableInst && tableInst.editorInstance) {
|
||
parts.push(tableInst.editorInstance.getContent({ format: 'raw' }) || '');
|
||
} else if (this.lineStyle && typeof this.lineStyle.html_data === 'string') {
|
||
parts.push(this.lineStyle.html_data);
|
||
}
|
||
const noteInst =
|
||
this.$refs.tinymceChildNote && this.$refs.tinymceChildNote.$refs && this.$refs.tinymceChildNote.$refs.tinymceChild1;
|
||
if (noteInst && noteInst.editorInstance) {
|
||
parts.push(noteInst.editorInstance.getContent({ format: 'raw' }) || '');
|
||
} else if (this.lineStyle && typeof this.lineStyle.note === 'string') {
|
||
parts.push(this.lineStyle.note);
|
||
}
|
||
return parts
|
||
.map((p) => (p == null ? '' : String(p)))
|
||
.filter((s) => s.trim() !== '')
|
||
.join('\n');
|
||
},
|
||
refreshTableDrawerAutociteDisplays() {
|
||
if (this.$refs.commonTable && typeof this.$refs.commonTable.refreshAutociteDisplay === 'function') {
|
||
this.$refs.commonTable.refreshAutociteDisplay();
|
||
}
|
||
if (this.$refs.tinymceChildNote && typeof this.$refs.tinymceChildNote.refreshAutociteDisplay === 'function') {
|
||
this.$refs.tinymceChildNote.refreshAutociteDisplay();
|
||
}
|
||
},
|
||
/** 按全文合并稿更新 articleCiteIdOrder,再刷新表格/表注内角标(与保存后稿面一致) */
|
||
flushReorderFromTableModal() {
|
||
if (!this.threeVisible || !this.lineStyle || this.lineStyle.am_id == null) return;
|
||
const html = this.getTableDrawerMergedDraftHtml();
|
||
this.tableModalDraftHtml = html || '';
|
||
if (!html || !String(html).trim()) {
|
||
this.reorderReferencesFromMainListBody(null, null);
|
||
return;
|
||
}
|
||
const citeOpts = {
|
||
tableDraftAmId: this.lineStyle.am_id,
|
||
tableDraftHtml: html
|
||
};
|
||
this.reorderReferencesFromMainListBody(this.lineStyle.am_id, html, citeOpts);
|
||
},
|
||
scheduleFlushReorderFromTableModal() {
|
||
if (!this.threeVisible || !this.lineStyle || this.lineStyle.am_id == null) return;
|
||
if (this._tableReorderTimer) clearTimeout(this._tableReorderTimer);
|
||
this._tableReorderTimer = setTimeout(() => {
|
||
this._tableReorderTimer = null;
|
||
this.flushReorderFromTableModal();
|
||
this.$nextTick(() => {
|
||
this.refreshTableDrawerAutociteDisplays();
|
||
});
|
||
}, 180);
|
||
},
|
||
/** 打开表格抽屉后待 TinyMCE 就绪再扫全文顺序,避免草稿态仍用列表下标 [38] */
|
||
afterOpenTableDrawerSyncCiteOrder() {
|
||
const run = () => {
|
||
this.flushReorderFromTableModal();
|
||
this.refreshTableDrawerAutociteDisplays();
|
||
};
|
||
this.$nextTick(() => {
|
||
this.$nextTick(() => {
|
||
run();
|
||
setTimeout(run, 400);
|
||
});
|
||
});
|
||
},
|
||
handleOpenRefSelectorFromManuscript(data) {
|
||
this.handleOpenRefSelector(data, 'manuscriptAutocite');
|
||
},
|
||
onRefSelectorDialogClosed() {
|
||
this.refSelectorContextIds = [];
|
||
this.refSelectorQuickPick = '';
|
||
},
|
||
/** 仅排序展示用,不修改 chanFerForm(逻辑与 handleReorderReferencesByBody 一致) */
|
||
sortChanFerRowsByOrder(refs, orderedIds) {
|
||
if (!Array.isArray(orderedIds) || orderedIds.length === 0) return refs;
|
||
const ids = orderedIds.map(String);
|
||
const idSet = new Set(ids);
|
||
const byId = {};
|
||
refs.forEach((r) => {
|
||
if (r && r.p_refer_id != null) byId[String(r.p_refer_id)] = r;
|
||
});
|
||
const next = [];
|
||
ids.forEach((id) => {
|
||
const row = byId[id];
|
||
if (row) next.push(row);
|
||
});
|
||
refs.forEach((r) => {
|
||
if (!r || r.p_refer_id == null) return;
|
||
const id = String(r.p_refer_id);
|
||
if (!idSet.has(id)) next.push(r);
|
||
});
|
||
if (refs.length > 0 && next.length === 0) return refs;
|
||
return next;
|
||
},
|
||
/**
|
||
* 与 word.vue citeMap:正文顺序中仅「当前参考文献列表里存在」的 id 依次占号,已删除/不存在的 id 不占位
|
||
*/
|
||
buildDisplayCiteMap(orderArray) {
|
||
const refs = Array.isArray(this.chanFerForm) ? this.chanFerForm : [];
|
||
const refIdSet = new Set(refs.map((r) => (r && r.p_refer_id != null ? String(r.p_refer_id) : '')).filter(Boolean));
|
||
const map = {};
|
||
if (!Array.isArray(orderArray) || orderArray.length === 0) {
|
||
refs.forEach((row, idx) => {
|
||
const key = row && row.p_refer_id != null ? String(row.p_refer_id) : '';
|
||
if (key) map[key] = idx + 1;
|
||
});
|
||
return map;
|
||
}
|
||
const filtered = [];
|
||
orderArray.forEach((id) => {
|
||
const k = String(id);
|
||
if (!k || !refIdSet.has(k)) return;
|
||
if (filtered.includes(k)) return;
|
||
filtered.push(k);
|
||
});
|
||
filtered.forEach((id, idx) => {
|
||
map[id] = idx + 1;
|
||
});
|
||
let next = filtered.length + 1;
|
||
refs.forEach((r) => {
|
||
const key = r && r.p_refer_id != null ? String(r.p_refer_id) : '';
|
||
if (!key || map[key] != null) return;
|
||
map[key] = next++;
|
||
});
|
||
return map;
|
||
},
|
||
/** 与 word.vue sortAutociteIdsByCiteNumber:排序键使用 buildDisplayCiteMap */
|
||
sortAutociteIdsByCiteNumber(ids, orderArray) {
|
||
const uniq = [...new Set((ids || []).map(String))];
|
||
const map = this.buildDisplayCiteMap(orderArray);
|
||
return uniq.sort((a, b) => {
|
||
const na = map[a];
|
||
const nb = map[b];
|
||
const ha = na != null && na !== '';
|
||
const hb = nb != null && nb !== '';
|
||
if (ha && hb) return Number(na) - Number(nb);
|
||
if (ha) return -1;
|
||
if (hb) return 1;
|
||
return String(a).localeCompare(String(b));
|
||
});
|
||
},
|
||
/** 与 word.vue:连续全局序号合并为 1–3 */
|
||
formatCiteNumbers(nums) {
|
||
if (!nums || !nums.length) return '';
|
||
const sorted = [...new Set(nums)].sort((a, b) => a - b);
|
||
const result = [];
|
||
let i = 0;
|
||
while (i < sorted.length) {
|
||
let j = i;
|
||
while (j < sorted.length - 1 && sorted[j + 1] === sorted[j] + 1) j++;
|
||
if (j - i >= 2) {
|
||
result.push(`${sorted[i]}–${sorted[j]}`);
|
||
} else {
|
||
for (let k = i; k <= j; k++) result.push(sorted[k]);
|
||
}
|
||
i = j + 1;
|
||
}
|
||
return result.join(', ');
|
||
},
|
||
/** 正文 mycite 顺序为唯一依据:按首次出现顺序重排 chanFerForm,未在正文出现的条目排在末尾 */
|
||
handleReorderReferencesByBody(orderedIds) {
|
||
if (!Array.isArray(orderedIds) || orderedIds.length === 0) return;
|
||
const ids = orderedIds.map(String);
|
||
const prevOrder = this.articleCiteIdOrder || [];
|
||
const sameOrder = ids.length === prevOrder.length && ids.every((id, i) => String(id) === String(prevOrder[i]));
|
||
if (!sameOrder) {
|
||
this.articleCiteIdOrder = ids.slice();
|
||
}
|
||
const idSet = new Set(ids);
|
||
const refs = Array.isArray(this.chanFerForm) ? [...this.chanFerForm] : [];
|
||
const byId = {};
|
||
refs.forEach((r) => {
|
||
if (r && r.p_refer_id != null) byId[String(r.p_refer_id)] = r;
|
||
});
|
||
const next = [];
|
||
ids.forEach((id) => {
|
||
const row = byId[id];
|
||
if (row) next.push(row);
|
||
});
|
||
refs.forEach((r) => {
|
||
if (!r || r.p_refer_id == null) return;
|
||
const id = String(r.p_refer_id);
|
||
if (!idSet.has(id)) next.push(r);
|
||
});
|
||
/**
|
||
* 若正文已出现引用 id,但列表尚未加载或 id 与 byId 对不上,会出现 next 为空而 refs 非空
|
||
* (正文 id 全在 idSet 内,第二轮被跳过),此时切勿 chanFerForm=[],否则参考文献整块消失。
|
||
*/
|
||
if (refs.length > 0 && next.length === 0) {
|
||
return;
|
||
}
|
||
const sig = (arr) => arr.map((r) => String(r.p_refer_id)).join('\0');
|
||
if (sig(next) === sig(refs)) return;
|
||
this.chanFerForm = next;
|
||
},
|
||
/**
|
||
* 将当前 chanFerForm 全文同步到后端(顺序 + 各字段内容与 getReferList 行结构一致)。
|
||
* 接口:api/References/batchUpdateRefer:p_article_id + list(JSON 字符串,文献对象数组,顺序即保存序)
|
||
*/
|
||
syncBatchReferenceOrderToServer() {
|
||
const pid = this.p_article_id;
|
||
if (pid == null || pid === '') return Promise.resolve();
|
||
const refs = Array.isArray(this.chanFerForm) ? this.chanFerForm : [];
|
||
if (refs.length === 0) return Promise.resolve();
|
||
let listJson;
|
||
try {
|
||
listJson = JSON.stringify(JSON.parse(JSON.stringify(refs)));
|
||
} catch (e) {
|
||
return Promise.resolve();
|
||
}
|
||
return this.$api
|
||
.post('api/References/batchUpdateRefer', {
|
||
p_article_id: String(pid),
|
||
list: listJson
|
||
})
|
||
.then((res) => {
|
||
const ok = res && (res.code === 0 || res.code === 1 || res.status === 1);
|
||
if (ok) {
|
||
this._lastReferListApiOrder = this.referIdOrderSnapshot(this.chanFerForm).slice();
|
||
}
|
||
if (!ok && res && (res.msg || res.message)) {
|
||
console.warn('[batchUpdateRefer]', res.msg || res.message);
|
||
}
|
||
return res;
|
||
})
|
||
.catch((err) => {
|
||
console.warn('[batchUpdateRefer] request failed', err);
|
||
});
|
||
},
|
||
/** 从 getReferList 原始 refers 提取 p_refer_id 顺序(字符串,便于比较) */
|
||
referIdOrderSnapshot(refs) {
|
||
return (Array.isArray(refs) ? refs : [])
|
||
.map((r) => (r && r.p_refer_id != null ? String(r.p_refer_id) : ''))
|
||
.filter(Boolean);
|
||
},
|
||
/** 当前 chanFerForm 顺序与 _lastReferListApiOrder 不一致则调用 batchUpdateRefer */
|
||
tryBatchSyncReferOrderIfOutOfSync() {
|
||
if (this._lastReferListApiOrder == null) return;
|
||
const track = this._lastReferListApiOrder.map(String);
|
||
const cur = this.referIdOrderSnapshot(this.chanFerForm);
|
||
if (cur.length === 0) return;
|
||
const same = track.length === cur.length && track.every((id, i) => id === cur[i]);
|
||
if (!same) {
|
||
this.syncBatchReferenceOrderToServer();
|
||
}
|
||
},
|
||
/**
|
||
* 等 applyRefOrder / syncRefOrder / 表格抽屉内 nextTick 跑完后再比对顺序。
|
||
*/
|
||
scheduleTryBatchSyncReferOrderIfOutOfSync() {
|
||
this.$nextTick(() => {
|
||
this.$nextTick(() => {
|
||
this.$nextTick(() => {
|
||
this.tryBatchSyncReferOrderIfOutOfSync();
|
||
});
|
||
});
|
||
});
|
||
},
|
||
extractBracketCiteNumbersFromText(raw) {
|
||
const out = [];
|
||
if (!raw || typeof raw !== 'string') return out;
|
||
const text = raw.replace(/<[^>]+>/g, ' ');
|
||
const re = /\[([\d\s,,\-–—]+)\]/g;
|
||
let m;
|
||
while ((m = re.exec(text)) !== null) {
|
||
const inner = String(m[1] || '').trim().replace(/,/g, ',');
|
||
if (!inner) continue;
|
||
const range = inner.match(/^(\d+)\s*[-–—]\s*(\d+)$/);
|
||
if (range) {
|
||
const a = Number(range[1]);
|
||
const b = Number(range[2]);
|
||
if (!Number.isNaN(a) && !Number.isNaN(b)) {
|
||
const lo = Math.min(a, b);
|
||
const hi = Math.max(a, b);
|
||
for (let i = lo; i <= hi; i++) out.push(i);
|
||
}
|
||
continue;
|
||
}
|
||
inner
|
||
.split(',')
|
||
.map((x) => parseInt(String(x).trim(), 10))
|
||
.filter((n) => !Number.isNaN(n) && n > 0)
|
||
.forEach((n) => out.push(n));
|
||
}
|
||
return out;
|
||
},
|
||
/** 编辑弹窗内正文一变立即按全文合并稿重排参考文献(不再防抖,选中/输入后列表马上跟正文一致) */
|
||
scheduleReorderFromEditModal(html) {
|
||
if (!this.editVisible || !this.currentContent || this.currentContent.am_id == null) return;
|
||
this.$nextTick(() => {
|
||
this.flushReorderFromEditModal(html);
|
||
});
|
||
},
|
||
/** 立即按全文合并稿重排参考文献顺序(插入引用后调用,避免编号长期停留在列表序号 [8]) */
|
||
flushReorderFromEditModal(html) {
|
||
if (!this.editVisible || !this.currentContent || this.currentContent.am_id == null) return;
|
||
let order = extractAutociteOrderFromMainList(this.Main_List, this.currentContent.am_id, html);
|
||
if (order.length === 0 && html && /(autocite|mycite)/i.test(html)) {
|
||
order = extractAutociteIdsFromHtmlString(html);
|
||
}
|
||
if (order.length > 0) {
|
||
this.handleReorderReferencesByBody(order);
|
||
}
|
||
},
|
||
/**
|
||
* 插入引用前先把新 p_refer_id 并入 articleCiteIdOrder,避免子组件 citeMap 缺键显示 [?];
|
||
* 随后 flush 会按全文首次出现顺序覆盖为准确值。
|
||
*/
|
||
ensureArticleCiteOrderIncludesIds(newIds) {
|
||
const add = (newIds || []).map(String).filter(Boolean);
|
||
if (!add.length) return;
|
||
let order = Array.isArray(this.articleCiteIdOrder) ? [...this.articleCiteIdOrder.map(String)] : [];
|
||
add.forEach((id) => {
|
||
if (!order.includes(id)) order.push(id);
|
||
});
|
||
this.articleCiteIdOrder = order;
|
||
},
|
||
onEditModalEditorInput(html) {
|
||
const h = html || '';
|
||
this.editModalDraftHtml = h;
|
||
this.editModalSyncedHtml = h;
|
||
this.flushReorderFromEditModal(h);
|
||
},
|
||
/** 从 Edit Content 内 TinyMCE 取 raw HTML 写入 editModalSyncedHtml,供 extract 与 applyRefOrder 与稿面对齐 */
|
||
syncEditModalHtmlFromEditor() {
|
||
if (!this.editVisible || !this.currentContent || this.currentContent.am_id == null) return '';
|
||
const cc = this.$refs.commonContent;
|
||
const inst = cc && cc.$refs && cc.$refs.tinymceChild1;
|
||
const ed = inst && inst.editorInstance;
|
||
if (!ed || typeof ed.getContent !== 'function') return '';
|
||
const raw = ed.getContent({ format: 'raw' }) || '';
|
||
this.editModalSyncedHtml = raw;
|
||
return raw;
|
||
},
|
||
refreshEditModalAutociteDisplay() {
|
||
if (!this.editVisible) return;
|
||
const cc = this.$refs.commonContent;
|
||
if (cc && typeof cc.refreshAutociteDisplay === 'function') {
|
||
cc.refreshAutociteDisplay();
|
||
}
|
||
},
|
||
/** 打开表格抽屉时用已有 lineStyle 字段拼合并稿,先写入 tableModalDraftHtml,角标与 Edit Content 一样按全文算 */
|
||
seedTableModalDraftFromLineStyle() {
|
||
if (!this.lineStyle || this.lineStyle.am_id == null) return;
|
||
const ls = this.lineStyle;
|
||
const parts = [];
|
||
if (typeof ls.title === 'string' && ls.title.trim()) parts.push(ls.title);
|
||
if (typeof ls.html_data === 'string' && ls.html_data.trim()) parts.push(ls.html_data);
|
||
if (typeof ls.note === 'string' && ls.note.trim()) parts.push(ls.note);
|
||
this.tableModalDraftHtml = parts.join('\n');
|
||
},
|
||
/** Title / 表格 / Note 任一输入,同步合并稿并防抖重排文献列表 */
|
||
onTableModalEditorInput() {
|
||
this.$nextTick(() => {
|
||
if (!this.threeVisible || !this.lineStyle || this.lineStyle.am_id == null) return;
|
||
const html = this.getTableDrawerMergedDraftHtml();
|
||
this.tableModalDraftHtml = html || '';
|
||
});
|
||
this.scheduleFlushReorderFromTableModal();
|
||
},
|
||
handleOpenRefSelector(data, sourceOverride) {
|
||
const currentIds = data && Array.isArray(data.currentRefIds) ? data.currentRefIds : [];
|
||
this.refSelectorContextIds = currentIds.map(String);
|
||
this.refSelectorIsEdit = currentIds.length > 0;
|
||
this.refSelectedRows = [];
|
||
if (sourceOverride === 'manuscriptAutocite' || (data && data.source === 'manuscript')) {
|
||
this.refSelectorSource = 'manuscriptAutocite';
|
||
} else if (
|
||
typeof sourceOverride === 'string' &&
|
||
sourceOverride &&
|
||
(sourceOverride === 'tinymceChildNote' || sourceOverride === 'tinymceChildImgNote') &&
|
||
this.$refs[sourceOverride]
|
||
) {
|
||
/** 表格 Note / 图片说明 独立编辑器,勿与 commonTable 混淆 */
|
||
this.refSelectorSource = sourceOverride;
|
||
} else if (this.threeVisible) {
|
||
/** Edit Table 主表格区 */
|
||
this.refSelectorSource = 'commonTable';
|
||
} else if (this.editVisible) {
|
||
this.refSelectorSource = 'commonContent';
|
||
} else if (this.addContentVisible) {
|
||
this.refSelectorSource = 'addContent';
|
||
}
|
||
this.refSelectorVisible = true;
|
||
this.$nextTick(() => {
|
||
const table = this.$refs.refSelectorTable;
|
||
if (table) {
|
||
table.clearSelection();
|
||
if (currentIds.length > 0) {
|
||
const idSet = new Set(currentIds.map(String));
|
||
this.chanFerForm.forEach((row) => {
|
||
if (idSet.has(String(row.p_refer_id))) {
|
||
table.toggleRowSelection(row, true);
|
||
}
|
||
});
|
||
}
|
||
}
|
||
});
|
||
},
|
||
handleRefSelectionChange(rows) {
|
||
this.refSelectedRows = rows;
|
||
},
|
||
/**
|
||
* 选择文献弹窗「原排序」列:与表格 [n] 一致 —— 有 old_index 时显示 old_index+1,否则显示 order_index(已为 n)
|
||
*/
|
||
refSelectorOrderIndexDisplay(row) {
|
||
if (!row) return '—';
|
||
const pick = (v) => {
|
||
if (v == null || v === '') return null;
|
||
const x = Number(v);
|
||
return Number.isNaN(x) ? null : x;
|
||
};
|
||
const oi =
|
||
row.old_index != null && row.old_index !== ''
|
||
? pick(row.old_index)
|
||
: pick(row.oldIndex);
|
||
if (oi != null) return oi + 1;
|
||
const ord =
|
||
row.order_index != null && row.order_index !== ''
|
||
? pick(row.order_index)
|
||
: pick(row.orderIndex);
|
||
if (ord != null) return ord;
|
||
return '—';
|
||
},
|
||
parseQuickPickNumbers(input) {
|
||
const s = String(input || '').trim();
|
||
if (!s) return [];
|
||
let t = s.replace(/^\s*\[/, '').replace(/\]\s*$/, '');
|
||
t = t.replace(/[,]/g, ',');
|
||
const parts = t
|
||
.split(',')
|
||
.map((x) => x.trim())
|
||
.filter(Boolean);
|
||
const out = new Set();
|
||
parts.forEach((p) => {
|
||
const m = p.match(/^(\d+)\s*[-–—]\s*(\d+)$/);
|
||
if (m) {
|
||
const a = Number(m[1]);
|
||
const b = Number(m[2]);
|
||
if (!Number.isNaN(a) && !Number.isNaN(b)) {
|
||
const lo = Math.min(a, b);
|
||
const hi = Math.max(a, b);
|
||
for (let i = lo; i <= hi; i++) out.add(i);
|
||
}
|
||
return;
|
||
}
|
||
const n = parseInt(p, 10);
|
||
if (!Number.isNaN(n)) out.add(n);
|
||
});
|
||
return Array.from(out).sort((a, b) => a - b);
|
||
},
|
||
clearRefSelectorSelection() {
|
||
const table = this.$refs.refSelectorTable;
|
||
if (table && typeof table.clearSelection === 'function') {
|
||
table.clearSelection();
|
||
}
|
||
this.refSelectedRows = [];
|
||
},
|
||
applyRefSelectorQuickPick() {
|
||
const table = this.$refs.refSelectorTable;
|
||
if (!table) return;
|
||
const nums = this.parseQuickPickNumbers(this.refSelectorQuickPick);
|
||
if (!nums.length) {
|
||
this.clearRefSelectorSelection();
|
||
return;
|
||
}
|
||
table.clearSelection();
|
||
const data = Array.isArray(this.refSelectorTableData) ? this.refSelectorTableData : [];
|
||
nums.forEach((n) => {
|
||
const idx = n - 1;
|
||
if (idx < 0 || idx >= data.length) return;
|
||
table.toggleRowSelection(data[idx], true);
|
||
});
|
||
},
|
||
/** 点击整行切换勾选(与点复选框一致);点链接或点复选框本身时不处理,避免重复或误触 */
|
||
handleRefSelectorRowClick(row, column, event) {
|
||
if (column && column.type === 'selection') return;
|
||
if (event && event.target && typeof event.target.closest === 'function') {
|
||
if (
|
||
event.target.closest('.el-checkbox') ||
|
||
event.target.closest('a[href]') ||
|
||
event.target.closest('.operation') ||
|
||
event.target.closest('.el-button')
|
||
)
|
||
return;
|
||
}
|
||
const table = this.$refs.refSelectorTable;
|
||
if (!table || !row) return;
|
||
const isSelected = (this.refSelectedRows || []).some((r) => r && String(r.p_refer_id) === String(row.p_refer_id));
|
||
table.toggleRowSelection(row, !isSelected);
|
||
},
|
||
handleConfirmRefCite() {
|
||
if (this.refSelectedRows.length === 0) return;
|
||
const ids = this.refSelectedRows.map((r) => r.p_refer_id);
|
||
if (this.refSelectorSource === 'manuscriptAutocite') {
|
||
const w = this.$refs.commonWord;
|
||
if (w && typeof w.applyManuscriptAutocite === 'function') {
|
||
w.applyManuscriptAutocite(ids);
|
||
}
|
||
this.refSelectorVisible = false;
|
||
this.refSelectedRows = [];
|
||
this.$nextTick(() => {
|
||
if (w && typeof w.syncRefOrder === 'function') {
|
||
w.syncRefOrder();
|
||
}
|
||
});
|
||
return;
|
||
}
|
||
this.ensureArticleCiteOrderIncludesIds(ids);
|
||
this.$nextTick(() => {
|
||
const ref = this.$refs[this.refSelectorSource];
|
||
if (ref) {
|
||
ref.insertAutocite(ids);
|
||
}
|
||
this.refSelectorVisible = false;
|
||
this.refSelectedRows = [];
|
||
this.$nextTick(() => {
|
||
if (this.threeVisible && this.lineStyle && this.lineStyle.am_id != null) {
|
||
this.flushReorderFromTableModal();
|
||
}
|
||
if (this.editVisible && this.$refs.commonContent) {
|
||
const html = this.syncEditModalHtmlFromEditor();
|
||
if (html) {
|
||
this.editModalDraftHtml = html;
|
||
this.editModalSyncedHtml = html;
|
||
this.flushReorderFromEditModal(html);
|
||
}
|
||
this.refreshEditModalAutociteDisplay();
|
||
}
|
||
if (
|
||
this.addContentVisible &&
|
||
this.$refs.addContent &&
|
||
typeof this.$refs.addContent.refreshAutociteDisplay === 'function'
|
||
) {
|
||
this.$refs.addContent.refreshAutociteDisplay();
|
||
}
|
||
if (
|
||
this.threeVisible &&
|
||
this.$refs.commonTable &&
|
||
typeof this.$refs.commonTable.refreshAutociteDisplay === 'function'
|
||
) {
|
||
this.$refs.commonTable.refreshAutociteDisplay();
|
||
}
|
||
if (
|
||
this.threeVisible &&
|
||
this.$refs.tinymceChildNote &&
|
||
typeof this.$refs.tinymceChildNote.refreshAutociteDisplay === 'function'
|
||
) {
|
||
this.$refs.tinymceChildNote.refreshAutociteDisplay();
|
||
}
|
||
if (
|
||
this.pictVisible &&
|
||
this.$refs.tinymceChildImgNote &&
|
||
typeof this.$refs.tinymceChildImgNote.refreshAutociteDisplay === 'function'
|
||
) {
|
||
this.$refs.tinymceChildImgNote.refreshAutociteDisplay();
|
||
}
|
||
});
|
||
});
|
||
},
|
||
handleRemoveRefCite() {
|
||
const idsToStrip = (this.refSelectedRows || []).map((r) => r.p_refer_id);
|
||
if (this.refSelectorSource === 'manuscriptAutocite') {
|
||
const w = this.$refs.commonWord;
|
||
if (w && typeof w.stripManuscriptAutociteIds === 'function') {
|
||
w.stripManuscriptAutociteIds(idsToStrip);
|
||
}
|
||
this.refSelectorVisible = false;
|
||
this.refSelectedRows = [];
|
||
return;
|
||
}
|
||
const ref = this.$refs[this.refSelectorSource];
|
||
if (ref && typeof ref.stripAutociteIds === 'function') {
|
||
ref.stripAutociteIds(idsToStrip);
|
||
} else if (ref) {
|
||
ref.removeAutocite();
|
||
}
|
||
this.refSelectorVisible = false;
|
||
this.refSelectedRows = [];
|
||
this.$nextTick(() => {
|
||
if (this.threeVisible && this.lineStyle && this.lineStyle.am_id != null) {
|
||
this.flushReorderFromTableModal();
|
||
this.refreshTableDrawerAutociteDisplays();
|
||
}
|
||
});
|
||
},
|
||
ChanFerMashUp(e) {
|
||
this.$api
|
||
.post('api/Production/referHB', e)
|
||
.then((res) => {
|
||
if (res.code == 0) {
|
||
this.fetchReferList();
|
||
} else {
|
||
this.$message.error(res.msg);
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
this.$message.error(err);
|
||
});
|
||
},
|
||
openAddTable(content) {
|
||
this.editVisible = false;
|
||
this.threeVisible = true;
|
||
this.$forceUpdate();
|
||
},
|
||
async copyArray(data) {
|
||
try {
|
||
// 将数组内容转换为字符串,使用换行符分隔
|
||
const textToCopy = JSON.stringify(data);
|
||
|
||
// 使用 Clipboard API 复制文本
|
||
await navigator.clipboard.writeText(textToCopy);
|
||
alert('数组内容已复制到剪贴板!');
|
||
} catch (err) {
|
||
console.error('复制失败:', err);
|
||
alert('复制失败,请重试!');
|
||
}
|
||
},
|
||
openLatexEditor(data) {
|
||
this.showLateX = true;
|
||
this.LateXInfo = data;
|
||
},
|
||
isShowEditComment() {
|
||
if (localStorage.getItem('U_role')) {
|
||
var identity = localStorage.getItem('U_role');
|
||
if (identity.includes('editor')) {
|
||
this.isEditComment = true;
|
||
} else {
|
||
this.isEditComment = false;
|
||
}
|
||
}
|
||
},
|
||
|
||
loadedWord() {
|
||
this.isWordComponentLoaded = true;
|
||
this.$nextTick(() => {
|
||
if (this.$refs.editPublicRefTableOnly) {
|
||
this.$refs.editPublicRefTableOnly.init();
|
||
}
|
||
});
|
||
},
|
||
// 监听第一个兄弟组件加载完毕
|
||
// onFirstComponentLoaded(imagesList) {
|
||
// this.imagesList = [...imagesList];
|
||
// this.isFirstComponentLoaded = true;
|
||
// },
|
||
// updateWordTiffImage(data) {
|
||
// console.log('updateWordTiffImage at line 423:', data);
|
||
|
||
// if (this.isFirstComponentLoaded && this.isWordComponentLoaded) {
|
||
// this.imagesList.forEach((e) => {
|
||
// if (e.dataUrl) {
|
||
// this.$nextTick(() => {
|
||
// this.$refs.commonWord.replacePlaceholderImage(e.ami_id, e.dataUrl);
|
||
// });
|
||
// }
|
||
// });
|
||
// }
|
||
// },
|
||
handleSaveContent() {
|
||
this.$refs.commonContent.getTinymceContent('content');
|
||
},
|
||
handleMatchBracketRefsInAddContent() {
|
||
const ref = this.$refs.addContent;
|
||
if (!ref || typeof ref.convertBracketRefsToAutocite !== 'function') return;
|
||
const { replaced } = ref.convertBracketRefsToAutocite();
|
||
if (replaced > 0) {
|
||
this.$message.success(this.$t('wordCite.matchBracketRefsDone', { n: replaced }));
|
||
} else {
|
||
this.$message.info(this.$t('wordCite.matchBracketRefsNone'));
|
||
}
|
||
},
|
||
handleSaveAddContent() {
|
||
this.$refs.addContent.getTinymceContent('addcontent');
|
||
},
|
||
handleSaveEditProofreadingContent() {
|
||
this.$refs.addContent.getTinymceContent('addcontent');
|
||
},
|
||
|
||
async getContent(type, content) {
|
||
if (type == 'content') {
|
||
content = this.$commonJS.transformHtmlString(content);
|
||
|
||
var div = document.createElement('div');
|
||
div.innerHTML = content; // 将 HTML 字符串加载到 div 中
|
||
// 替换所有 <strong> 为 <b>
|
||
var strongTags = div.getElementsByTagName('strong');
|
||
for (var i = 0; i < strongTags.length; i++) {
|
||
var bTag = document.createElement('b');
|
||
bTag.innerHTML = strongTags[i].innerHTML; // 保留内容
|
||
strongTags[i].parentNode.replaceChild(bTag, strongTags[i]);
|
||
}
|
||
// 替换所有 <em> 为 <i>
|
||
var emTags = div.getElementsByTagName('em');
|
||
for (var i = 0; i < emTags.length; i++) {
|
||
var iTag = document.createElement('i');
|
||
iTag.innerHTML = emTags[i].innerHTML; // 保留内容
|
||
emTags[i].parentNode.replaceChild(iTag, emTags[i]);
|
||
}
|
||
|
||
// 获取最终修改后的 HTML
|
||
content = div.innerHTML;
|
||
|
||
this.saveContent(content, this.currentContent.am_id);
|
||
} else if (type == 'addcontent') {
|
||
var hasTable = /<table[\s\S]*?>[\s\S]*?<\/table>/i.test(content);
|
||
|
||
if (hasTable) {
|
||
this.$message({
|
||
type: 'warning',
|
||
message: 'Table content is not supported!'
|
||
});
|
||
return false;
|
||
}
|
||
var list = this.$commonJS.cleanAndParseWordContent(content);
|
||
|
||
this.saveContentList(list, this.currentId);
|
||
} else if (type == 'table') {
|
||
this.saveTable(content);
|
||
} else if (type == 'comment') {
|
||
this.addComment(content);
|
||
}
|
||
},
|
||
handleUnbindLink(data) {
|
||
const { label, mainId, index, content } = data;
|
||
|
||
const unwrapTag = (str) => {
|
||
return str.replace(/<(myfigure|mytable)[^>]*>([\s\S]*?)<\/\1>/gi, '$2');
|
||
};
|
||
|
||
// 2. 执行替换
|
||
// 我们只针对传入的这个特定的 label 进行剥壳
|
||
const strippedLabel = unwrapTag(label);
|
||
|
||
// 3. 将 content 中的原标签替换为剥壳后的文字
|
||
// 使用 split/join 或者是精准 replace,确保只替换这一处
|
||
const newContent = content.replace(label, strippedLabel);
|
||
this.saveContent(newContent, mainId);
|
||
},
|
||
handleConfirmLink(selectedMedia) {
|
||
const select = (selectedMedia && selectedMedia.select) || {};
|
||
// 不同列表来源字段不一致:表可能是 amt_id / am_id,图可能是 ami_id / am_id
|
||
const targetId =
|
||
select.amt_id ||
|
||
select.ami_id ||
|
||
select.am_id ||
|
||
select.p_main_table_id ||
|
||
select.table_id ||
|
||
(select.table &&
|
||
(select.table.amt_id || select.table.am_id || select.table.p_main_table_id || select.table.table_id));
|
||
const type = selectedMedia.type;
|
||
const tagName = `my${type}`;
|
||
let originalContent = selectedMedia.linkData.content;
|
||
const label = selectedMedia.linkData.label;
|
||
if (!label || !originalContent || targetId == null || targetId === '') return;
|
||
const isAlreadyTagged = label.startsWith('<my') && label.endsWith('>');
|
||
let newContent = '';
|
||
if (isAlreadyTagged) {
|
||
const updatedTag = label
|
||
.replace(/<my(figure|table)/, `<${tagName}`)
|
||
.replace(/data-id=".*?"/, `data-id="${targetId}"`)
|
||
.replace(/<\/my(figure|table)>$/, `</${tagName}>`);
|
||
|
||
newContent = originalContent.replace(label, updatedTag);
|
||
} else {
|
||
const replacement = `<${tagName} data-id="${targetId}">${label}</${tagName}>`;
|
||
newContent = originalContent.replace(label, replacement);
|
||
}
|
||
this.saveContent(newContent, selectedMedia.linkData.mainId);
|
||
},
|
||
|
||
async saveContent(content, am_id) {
|
||
const loading = this.$loading({
|
||
lock: true,
|
||
text: 'Loading...',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(0, 0, 0, 0.7)'
|
||
});
|
||
var that = this;
|
||
var str = content.replace(/^<p>\s*(.*?)\s*<\/p>$/, '$1').trim();
|
||
|
||
str = str.replace(/<br\s*\/?>/gi, '');
|
||
|
||
str = await that.$commonJS.decodeHtml(str);
|
||
|
||
/** 点 Save 立即按将写入的正文重排下方列表(不等待接口),与弹窗内 [n] 一致 */
|
||
this.reorderReferencesFromMainListBody(am_id, str);
|
||
|
||
await that.$api
|
||
.post(that.urlList.editContent, {
|
||
am_id: am_id,
|
||
content: str
|
||
})
|
||
.then(async (res) => {
|
||
if (res.code == 0) {
|
||
loading.close();
|
||
this.editVisible = false;
|
||
this.refreshCurrentContent('content', am_id, res.data);
|
||
this.getCommentList();
|
||
/** 以接口回写后的 Main_List 再对齐一次;稿面 word 会由 contentList 监听触发 syncRefOrder */
|
||
this.$nextTick(() => {
|
||
this.reorderReferencesFromMainListBody(null, null);
|
||
this.$nextTick(() => {
|
||
this.syncBatchReferenceOrderToServer();
|
||
});
|
||
});
|
||
} else {
|
||
loading.close();
|
||
this.$message.error(res.msg);
|
||
this.reorderReferencesFromMainListBody(null, null);
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
loading.close();
|
||
this.$message.error(err);
|
||
this.reorderReferencesFromMainListBody(null, null);
|
||
});
|
||
},
|
||
async saveContentList(content, am_id) {
|
||
if (content.length == 0) {
|
||
this.$message({
|
||
type: 'warning',
|
||
message: 'Please enter the content!'
|
||
});
|
||
}
|
||
const loading = this.$loading({
|
||
lock: true,
|
||
text: 'Loading...',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(0, 0, 0, 0.7)'
|
||
});
|
||
|
||
content = content.map((str) => {
|
||
// 逻辑:去掉所有换行符后,如果剩下的内容是空的
|
||
if (str.replace(/<br\s*\/?>/gi, '').trim() === '') {
|
||
return ''; // 变成真正的空字符串
|
||
}
|
||
return str; // 如果有文字,保留原样
|
||
});
|
||
await this.$api
|
||
.post('api/Preaccept/addMoreRow', {
|
||
article_id: this.articleId,
|
||
am_id: am_id,
|
||
rows: content
|
||
})
|
||
.then(async (res) => {
|
||
if (res.code == 0) {
|
||
loading.close();
|
||
this.addContentVisible = false;
|
||
this.refreshCurrentContent('addMoreRow', am_id, res.data);
|
||
this.getCommentList();
|
||
} else {
|
||
loading.close();
|
||
this.$message.error(res.msg);
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
loading.close();
|
||
this.$message.error(err);
|
||
});
|
||
},
|
||
isHeaderRow(rowIndex, table) {
|
||
var table = table;
|
||
|
||
var head = table[0];
|
||
|
||
return rowIndex < head[0].rowspan; // 假设前两行是表头
|
||
},
|
||
deleteComment(comment, index) {
|
||
if (this.isEditComment) {
|
||
this.$confirm(this.$t('commonTable.removeAnnotations'), 'Prompt', {
|
||
confirmButtonText: 'Submit',
|
||
cancelButtonText: 'Cancel',
|
||
type: 'warning'
|
||
})
|
||
.then(() => {
|
||
this.$api
|
||
.post(this.urlList.deleteComment, {
|
||
amc_id: comment.amc_id
|
||
})
|
||
.then((res) => {
|
||
if (res.code == 0) {
|
||
this.getDate();
|
||
this.getCommentList();
|
||
} else {
|
||
this.$message.error(res.msg);
|
||
}
|
||
});
|
||
// this.comments.splice(index, 1); // 删除评论
|
||
})
|
||
.catch(() => {});
|
||
}
|
||
},
|
||
saveLateX(data) {
|
||
// 1. 从 data 中解构出 wrap (或者你命名的模式变量)
|
||
const { editorId, wmathId, latex, wrap } = data;
|
||
const newLatex = latex ? latex.trim() : '';
|
||
|
||
if (!editorId || !wmathId) return;
|
||
|
||
const targetEditor = tinymce.get(editorId);
|
||
if (!targetEditor) return;
|
||
|
||
// 2. 找到编辑器中现有的 wmath 标签
|
||
const targetWmath = targetEditor.dom.select(`wmath[data-id="${wmathId}"]`, targetEditor.getBody())[0];
|
||
|
||
if (targetWmath) {
|
||
if (!newLatex) {
|
||
// ❌ 删除公式
|
||
targetEditor.dom.remove(targetWmath);
|
||
} else {
|
||
// ✅ 更新公式
|
||
// 保持属性纯净:同时更新 latex 内容和 wrap 属性
|
||
targetWmath.setAttribute('data-latex', newLatex);
|
||
|
||
// 如果 data 中传了 wrap 模式就更新它,否则可以保留原样或设为默认
|
||
if (wrap) {
|
||
targetWmath.setAttribute('data-wrap', wrap);
|
||
}
|
||
|
||
// 内部只放纯 latex 文本,不包裹 $ 符号
|
||
targetWmath.innerHTML = newLatex;
|
||
|
||
setTimeout(() => {
|
||
if (typeof renderMathJax === 'function') {
|
||
// 重新渲染该编辑器内的数学公式
|
||
renderMathJax(editorId);
|
||
}
|
||
}, 10);
|
||
}
|
||
}
|
||
},
|
||
async huifu(id) {
|
||
var that = this;
|
||
await this.$confirm(this.$t('commonTable.reContent'), 'Prompt', {
|
||
confirmButtonText: 'Submit',
|
||
cancelButtonText: 'Cancel',
|
||
type: 'warning'
|
||
})
|
||
.then(async () => {
|
||
var that = this;
|
||
await that.$api
|
||
.post(that.urlList.huifuContent, {
|
||
am_id: id
|
||
})
|
||
.then(async (res) => {
|
||
if (res.code == 0) {
|
||
this.getDate();
|
||
}
|
||
});
|
||
})
|
||
.catch((err) => {
|
||
console.log('err at line 466:', err);
|
||
});
|
||
},
|
||
async getManuscirptContent() {
|
||
var that = this;
|
||
await that.$api
|
||
.post(that.urlList.content, {
|
||
article_id: this.articleId
|
||
})
|
||
.then(async (res) => {
|
||
if (res.code == 0) {
|
||
this.ManuscirptContent = res.data.list;
|
||
// this.$refs.commonWordHtmlTypeSetting.getCommentList();
|
||
}
|
||
});
|
||
},
|
||
changeComment() {
|
||
this.isShowComment = !this.isShowComment;
|
||
},
|
||
|
||
// 编辑评论,显示文本框
|
||
goToListComment(id, type) {
|
||
var am_id;
|
||
if (type == 'img') {
|
||
am_id = this.Main_List.find((item) => item.ami_id == id).am_id;
|
||
} else if (type == 'table') {
|
||
am_id = this.Main_List.find((item) => item.amt_id == id).am_id;
|
||
} else {
|
||
am_id = id;
|
||
}
|
||
if (am_id) {
|
||
this.goToComment(am_id);
|
||
}
|
||
},
|
||
goToComment(mainId) {
|
||
this.$nextTick(() => {
|
||
this.$refs.commonWord.goToComment(mainId);
|
||
});
|
||
},
|
||
getTables(tables, html) {
|
||
this.tables = data.map((e, i) => ({ ...e, p_main_table_id: 2141 + i, p_article_id: 2141 }));
|
||
this.tablesHtml = html;
|
||
},
|
||
onDragStart(event, image, index, type) {
|
||
if (type == 'img') {
|
||
event.dataTransfer.setData('image', JSON.stringify({ ...image }));
|
||
event.dataTransfer.setData('imageIndex', index);
|
||
} else {
|
||
event.dataTransfer.setData('table', JSON.stringify({ table: image.table, amt_id: image.amt_id, title: image.title }));
|
||
event.dataTransfer.setData('tableIndex', index);
|
||
}
|
||
},
|
||
async onDelete(dataId) {
|
||
var that = this;
|
||
var dataInfo = this.Main_List.find((item) => item.am_id == dataId);
|
||
var dataIndex = this.Main_List.indexOf(dataInfo);
|
||
|
||
var type = '';
|
||
if (dataInfo.type == 1) {
|
||
type = 'img';
|
||
} else if (dataInfo.type == 2) {
|
||
type = 'table';
|
||
} else if (dataInfo.type == 0) {
|
||
type = 'content';
|
||
}
|
||
var url = '';
|
||
switch (type) {
|
||
case 'table':
|
||
url = that.urlList.removePositioningTable;
|
||
break;
|
||
case 'img':
|
||
url = that.urlList.removePositioningImage;
|
||
break;
|
||
case 'content':
|
||
url = that.urlList.delete;
|
||
break;
|
||
}
|
||
if (dataInfo.type == 0 && dataInfo.content == '') {
|
||
await that.$api
|
||
.post(url, {
|
||
am_id: dataId
|
||
})
|
||
.then(async (res) => {
|
||
if (res.code == 0) {
|
||
setTimeout(() => {
|
||
that.Main_List.splice(dataIndex, 1);
|
||
|
||
that.getCommentList();
|
||
that.$forceUpdate();
|
||
});
|
||
} else {
|
||
this.$message.error(res.msg);
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
this.$message.error(err);
|
||
});
|
||
} else {
|
||
await this.$confirm(this.$t('commonTable.removeContent'), 'Prompt', {
|
||
confirmButtonText: 'Submit',
|
||
cancelButtonText: 'Cancel',
|
||
type: 'warning'
|
||
})
|
||
.then(async () => {
|
||
await that.$api
|
||
.post(url, {
|
||
am_id: dataId
|
||
})
|
||
.then(async (res) => {
|
||
if (res.code == 0) {
|
||
setTimeout(() => {
|
||
that.Main_List.splice(dataIndex, 1);
|
||
that.$forceUpdate();
|
||
if (type == 'img') {
|
||
that.$refs.commonWordHtmlTypeSetting.refresh('removeImg', { ami_id: dataInfo.ami_id });
|
||
} else if (type == 'table') {
|
||
that.$refs.commonWordHtmlTypeSetting.refresh('removeTable', { amt_id: dataInfo.amt_id });
|
||
}
|
||
that.getCommentList();
|
||
|
||
that.$forceUpdate();
|
||
});
|
||
}
|
||
});
|
||
})
|
||
.catch((err) => {
|
||
console.log('err at line 466:', err);
|
||
});
|
||
}
|
||
},
|
||
async onDeletes(dataId) {
|
||
await this.$confirm(this.$t('commonTable.removeContent'), 'Prompt', {
|
||
confirmButtonText: 'Submit',
|
||
cancelButtonText: 'Cancel',
|
||
type: 'warning'
|
||
})
|
||
.then(async () => {
|
||
var that = this;
|
||
await that.$api
|
||
.post('/api/Preaccept/delMoreArticleMains', {
|
||
ids: dataId
|
||
})
|
||
.then(async (res) => {
|
||
if (res.code == 0) {
|
||
setTimeout(() => {
|
||
that.getDate();
|
||
that.getCommentList();
|
||
that.$refs.commonWordHtmlTypeSetting.reload();
|
||
|
||
that.$forceUpdate();
|
||
});
|
||
}
|
||
});
|
||
// this.Main_List.splice(
|
||
// this.Main_List.findIndex((item) => item.p_main_id == dataId),
|
||
// 1
|
||
// );
|
||
})
|
||
.catch((err) => {
|
||
console.log('err at line 466:', err);
|
||
});
|
||
},
|
||
async changeSort(type, id) {
|
||
var that = this;
|
||
const index = this.Main_List.findIndex((item) => item.am_id == id);
|
||
if (type == 'up' && index == 0) {
|
||
return;
|
||
}
|
||
if (type == 'down' && index == this.Main_List.length - 1) {
|
||
return;
|
||
}
|
||
const load = this.$loading({
|
||
lock: true,
|
||
text: 'Loading...',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(0, 0, 0, 0.7)'
|
||
});
|
||
await that.$api
|
||
.post(type == 'up' ? '/api/Preaccept/upArticleMain' : '/api/Preaccept/downArticleMain', {
|
||
am_id: id
|
||
})
|
||
.then(async (res) => {
|
||
if (res.code == 0) {
|
||
load.close();
|
||
await this.refreshCurrentContent(`${type}ArticleMain`, id);
|
||
that.$forceUpdate();
|
||
} else {
|
||
load.close();
|
||
this.$message.error(res.msg);
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
load.close();
|
||
this.$message.error(err);
|
||
});
|
||
},
|
||
async addCommentSetting(content) {
|
||
await this.$api
|
||
.post(this.urlList.addComment, {
|
||
am_id: content.am_id,
|
||
remark: content.remark
|
||
})
|
||
.then(async (res) => {
|
||
if (res.code == 0) {
|
||
this.$forceUpdate();
|
||
// this.commentVisible = false;
|
||
// this.getDate()
|
||
this.$nextTick(() => {
|
||
this.$refs.commonWordHtmlTypeSetting.getCommentList();
|
||
});
|
||
} else {
|
||
this.$message.error(res.msg);
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
this.$message.error(err.msg);
|
||
});
|
||
},
|
||
async addComment(content) {
|
||
var str = this.$commonJS.transformHtmlString(content);
|
||
str = str.replace(/<br\s*\/?>/gi, '');
|
||
console.log('🚀 ~ addComment ~ content:', str);
|
||
if (str == '') {
|
||
this.$message({
|
||
type: 'warning',
|
||
message: 'Please enter the Comment!'
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (this.commentForm.type == 'user') {
|
||
await this.$api
|
||
.post(this.urlList.replyComment, {
|
||
amc_id: this.commentForm.amc_id,
|
||
author_remark: str
|
||
})
|
||
.then(async (res) => {
|
||
if (res.code == 0) {
|
||
this.$forceUpdate();
|
||
this.commentVisible = false;
|
||
this.getDate();
|
||
this.getCommentList();
|
||
this.$nextTick(() => {});
|
||
} else {
|
||
this.$message.error(res.msg);
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
this.$message.error(err.msg);
|
||
});
|
||
} else {
|
||
var data = {};
|
||
if (this.commentForm.amc_id) {
|
||
data = {
|
||
amc_id: this.commentForm.amc_id,
|
||
|
||
remark: str
|
||
};
|
||
} else {
|
||
data = {
|
||
article_id: this.articleId,
|
||
am_id: this.commentForm.am_id,
|
||
content: this.commentForm.content,
|
||
remark: str
|
||
};
|
||
}
|
||
await this.$api
|
||
.post(this.commentForm.amc_id ? this.urlList.editComment : this.urlList.addComment, { ...data })
|
||
.then(async (res) => {
|
||
if (res.code == 0) {
|
||
this.$forceUpdate();
|
||
this.commentVisible = false;
|
||
this.getDate();
|
||
this.getCommentList();
|
||
this.$nextTick(() => {});
|
||
} else {
|
||
this.$message.error(res.msg);
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
this.$message.error(err.msg);
|
||
});
|
||
}
|
||
},
|
||
async onComment(dataId) {
|
||
var data = this.Main_List.find((item) => item.am_id == dataId);
|
||
if (data && data.remark) {
|
||
this.$alert(
|
||
`<p style="display:flex;"><img src="${this.remarkImageUrl}" alt="" style="width:20px;height:20px;margin-right:10px;"/><span style=" overflow-wrap: break-word;width:calc(100% - 50px)"> ${data.remark}</span></p>`,
|
||
'Comments',
|
||
{
|
||
confirmButtonText: 'OK',
|
||
dangerouslyUseHTMLString: true, // 启用 HTML 渲染
|
||
callback: (action) => {}
|
||
}
|
||
);
|
||
}
|
||
},
|
||
onRefresh() {
|
||
this.getDate();
|
||
this.getCommentList();
|
||
},
|
||
editComment(comment, type) {
|
||
this.commentForm = {
|
||
...comment,
|
||
type: type,
|
||
remark: type == 'user' ? comment.author_remark : comment.remark
|
||
};
|
||
|
||
this.commentVisible = true;
|
||
},
|
||
async onAddComment(data) {
|
||
var form = this.Main_List.find((item) => item.am_id == data.mainId);
|
||
this.commentForm = {
|
||
...form,
|
||
content: data.label ? data.label : '',
|
||
remark: '',
|
||
type: 'add',
|
||
role: 'editor'
|
||
};
|
||
this.commentVisible = true;
|
||
},
|
||
async replyComment(data) {
|
||
this.commentForm = {
|
||
...data,
|
||
remark: data.author_remark,
|
||
type: 'user'
|
||
};
|
||
this.commentVisible = true;
|
||
},
|
||
async onEditTitle(data) {
|
||
const loading = this.$loading({
|
||
lock: true,
|
||
text: 'Loading...',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(0, 0, 0, 0.7)'
|
||
});
|
||
var url;
|
||
switch (data.value) {
|
||
case 0:
|
||
url = 'api/Preaccept/changeNormal';
|
||
break;
|
||
case 1:
|
||
url = 'api/Preaccept/changeH1';
|
||
break;
|
||
case 2:
|
||
url = 'api/Preaccept/changeH2';
|
||
break;
|
||
case 3:
|
||
url = 'api/Preaccept/changeH3';
|
||
break;
|
||
}
|
||
|
||
await this.$api
|
||
.post(url, {
|
||
am_id: data.mainId
|
||
})
|
||
.then(async (res) => {
|
||
if (res.code == 0) {
|
||
await this.refreshCurrentContent('content', data.mainId, res.data);
|
||
loading.close();
|
||
this.getCommentList();
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
loading.close();
|
||
this.$message.error(err.msg);
|
||
});
|
||
},
|
||
async refreshCurrentContent(type, mainId, resData) {
|
||
const index = this.Main_List.findIndex((item) => item.am_id == mainId);
|
||
if (type == 'upArticleMain') {
|
||
if (index == 0) {
|
||
return;
|
||
}
|
||
const item = this.Main_List[index];
|
||
// 2. 从原位置删除
|
||
this.Main_List.splice(index, 1);
|
||
// 3. 插入到前一个位置
|
||
this.Main_List.splice(index - 1, 0, item);
|
||
return;
|
||
}
|
||
if (type == 'downArticleMain') {
|
||
if (index == this.Main_List.length - 1) {
|
||
return;
|
||
}
|
||
const item = this.Main_List[index];
|
||
// 2. 从原位置删除
|
||
this.Main_List.splice(index, 1);
|
||
// 3. 插入到前一个位置
|
||
this.Main_List.splice(index + 1, 0, item);
|
||
return;
|
||
}
|
||
if (index !== -1 && resData) {
|
||
var newData = Array.isArray(resData) ? resData : resData ? [resData] : [];
|
||
const updatedItems = newData.map((item) => ({
|
||
...item,
|
||
checked: false,
|
||
getnum: 0
|
||
}));
|
||
if (type == 'addRow') {
|
||
this.Main_List.splice(index + 1, 0, updatedItems[0]);
|
||
} else if (type == 'addMoreRow') {
|
||
this.Main_List.splice(index + 1, 0, ...updatedItems);
|
||
} else if (type == 'positioningImg' || type == 'positioningTable') {
|
||
this.Main_List.splice(index + 1, 0, ...updatedItems);
|
||
} else {
|
||
this.$set(this.Main_List, index, updatedItems[0]);
|
||
}
|
||
} else {
|
||
console.warn(`Item with am_id ${mainId} not found.`);
|
||
}
|
||
this.$forceUpdate();
|
||
},
|
||
handlePaperclip() {
|
||
this.uploadWordTables = [];
|
||
this.$refs.fileInput.click();
|
||
},
|
||
handleFileChange(event) {
|
||
var that = this;
|
||
const loading = this.$loading({
|
||
lock: true,
|
||
text: 'Loading...',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(0, 0, 0, 0.7)'
|
||
});
|
||
// 处理文件上传并传递回调函数
|
||
this.$commonJS.handleFileUpload(event, function (tables) {
|
||
if (tables.length == 0) {
|
||
loading.close();
|
||
that.$message({
|
||
type: 'warning',
|
||
message: 'No table found!'
|
||
});
|
||
return false;
|
||
}
|
||
|
||
// 使用 Promise.all 等待所有表格解析完成
|
||
Promise.all(
|
||
tables.map((table) => {
|
||
return new Promise((resolve, reject) => {
|
||
// 解析每个表格
|
||
that.$commonJS.parseTableToArray(table, (tableList) => {
|
||
resolve({ table_data: tableList, html_data: '' });
|
||
});
|
||
});
|
||
})
|
||
)
|
||
.then((result) => {
|
||
// 所有表格的解析完成后,处理结果
|
||
that.uploadWordTables = result;
|
||
loading.close();
|
||
that.tablesHtmlVisible = true;
|
||
})
|
||
.catch((error) => {
|
||
loading.close();
|
||
console.error('Error processing tables:', error);
|
||
});
|
||
});
|
||
const file = event.target.files[0];
|
||
if (file) {
|
||
// 处理文件逻辑
|
||
}
|
||
|
||
// 关键:重置 input 的值
|
||
event.target.value = '';
|
||
},
|
||
|
||
async onAddRow(mainId) {
|
||
await this.$api
|
||
.post(this.urlList.addRow, {
|
||
am_id: mainId,
|
||
article_id: this.articleId
|
||
})
|
||
.then(async (res) => {
|
||
if (res.code == 0) {
|
||
this.refreshCurrentContent('addRow', mainId, res.data);
|
||
this.getCommentList();
|
||
} else {
|
||
this.$message.error(res.msg);
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
this.$message.error(err.msg);
|
||
});
|
||
},
|
||
async solveComment(data) {
|
||
await this.$api
|
||
.post(this.urlList.solveComment, {
|
||
amc_id: data.amc_id
|
||
})
|
||
.then(async (res) => {
|
||
if (res.code == 0) {
|
||
this.getDate();
|
||
this.getCommentList();
|
||
} else {
|
||
this.$message.error(res.msg);
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
this.$message.error(err.msg);
|
||
});
|
||
},
|
||
|
||
async executeProofreading(data) {
|
||
await this.$api
|
||
.post(this.urlList.executeProofreading, {
|
||
am_id: data.am_id,
|
||
record_id: data.id,
|
||
state: 1,
|
||
article_id: this.$route.query.id
|
||
})
|
||
.then(async (res) => {
|
||
if (res.status == 1) {
|
||
this.getDate();
|
||
this.getCommentList();
|
||
} else {
|
||
this.$message.error(res.msg);
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
this.$message.error(err.msg);
|
||
});
|
||
},
|
||
async revokeProofreading(data) {
|
||
await this.$api
|
||
.post(this.urlList.executeProofreading, {
|
||
am_id: data.am_id,
|
||
record_id: data.id,
|
||
state: 2,
|
||
article_id: this.$route.query.id
|
||
})
|
||
.then(async (res) => {
|
||
if (res.status == 1) {
|
||
this.getDate();
|
||
this.getCommentList();
|
||
} else {
|
||
this.$message.error(res.msg);
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
this.$message.error(err.msg);
|
||
});
|
||
},
|
||
async editProofreading(data) {},
|
||
deleteProofreading(data, index) {},
|
||
|
||
async cancelSolveComment(data) {
|
||
await this.$api
|
||
.post(this.urlList.cancelSolveComment, {
|
||
amc_id: data.amc_id
|
||
})
|
||
.then(async (res) => {
|
||
if (res.code == 0) {
|
||
this.getDate();
|
||
this.getCommentList();
|
||
} else {
|
||
this.$message.error(res.msg);
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
this.$message.error(err.msg);
|
||
});
|
||
},
|
||
clearButton() {
|
||
var deleteButtons = document.querySelectorAll('.wordButtonContainer');
|
||
deleteButtons.forEach(function (button) {
|
||
button.remove(); // 移除每个 wordButtonContainer 按钮
|
||
});
|
||
},
|
||
handleImageAdd(type) {
|
||
this.picStyle = { note: '', picUrl: '', title: '' };
|
||
this.picStyle1 = { note: '', picUrl: '', title: '' };
|
||
this.picStyle.visiTitle = 'Add Figure';
|
||
this.pictVisible = true;
|
||
},
|
||
handleTableAdd(type) {
|
||
this.lineStyle = { note: '', table_data: '', html_data: '' };
|
||
this.lineStyle1 = { note: '', table_data: '', html_data: '' };
|
||
this.lineStyle.visiTitle = 'Add Table';
|
||
this.threeVisible = true;
|
||
},
|
||
addUploadWordTable(data) {
|
||
this.lineStyle = { note: '', table: data.table_data, html_data: data.html_data };
|
||
this.lineStyle1 = { note: '', table: data.table_data, html_data: data.html_data };
|
||
|
||
this.lineStyle.visiTitle = 'Add Table';
|
||
this.threeVisible = true;
|
||
},
|
||
|
||
async handleFigureAndTableDelete(data, type) {
|
||
await this.$confirm(this.$t('commonTable.remove' + type), 'Prompt', {
|
||
confirmButtonText: 'Submit',
|
||
cancelButtonText: 'Cancel',
|
||
type: 'warning'
|
||
})
|
||
.then(async (res) => {
|
||
const loading = this.$loading({
|
||
lock: true,
|
||
text: 'Loading...',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(0, 0, 0, 0.7)'
|
||
});
|
||
if (type == 'img') {
|
||
this.$api
|
||
.post(this.urlList.deleteImage, {
|
||
ami_id: data.ami_id,
|
||
|
||
article_id: this.articleId
|
||
})
|
||
.then(async (res) => {
|
||
if (res.status == 1) {
|
||
loading.close();
|
||
this.$message.success(res.msg);
|
||
this.$refs.commonWordHtmlTypeSetting.replacement('img', data.ami_id);
|
||
} else {
|
||
loading.close();
|
||
this.$message.error(res.msg);
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
loading.close();
|
||
this.$message.error(err.msg);
|
||
});
|
||
}
|
||
if (type == 'table') {
|
||
this.$api
|
||
.post(this.urlList.deleteTable, {
|
||
amt_id: data.amt_id,
|
||
|
||
article_id: this.articleId
|
||
})
|
||
.then(async (res) => {
|
||
if (res.status == 1) {
|
||
loading.close();
|
||
this.$refs.commonWordHtmlTypeSetting.replacement('table', data.amt_id);
|
||
} else {
|
||
loading.close();
|
||
this.$message.error(res.msg);
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
loading.close();
|
||
this.$message.error(err.msg);
|
||
});
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
// this.$message.error(err.msg);
|
||
});
|
||
},
|
||
handleFigureAndTableEdit(data, type) {
|
||
if (type == 'img') {
|
||
var extension = data.url.split('.').pop().toLowerCase();
|
||
this.picStyle = {};
|
||
this.picStyle = { ...data, extension: extension, picUrl: data.url };
|
||
this.picStyle.visiTitle = 'Edit Figure';
|
||
this.pictVisible = true;
|
||
} else if (type == 'table') {
|
||
this.lineStyle = {};
|
||
this.lineStyle1 = {};
|
||
// 1. 提取处理逻辑
|
||
const formattedData = {
|
||
...data,
|
||
table: JSON.parse(data.table_data)
|
||
};
|
||
|
||
// 2. 统一赋值
|
||
this.lineStyle = formattedData;
|
||
this.lineStyle1 = { ...formattedData }; // 使用浅拷贝确保两个变量指向不同引用(如果需要独立修改)
|
||
this.lineStyle.visiTitle = 'Edit Table';
|
||
this.threeVisible = true;
|
||
this.seedTableModalDraftFromLineStyle();
|
||
this.afterOpenTableDrawerSyncCiteOrder();
|
||
}
|
||
},
|
||
updateChange(content, type) {
|
||
var str = this.$commonJS.transformHtmlString(content);
|
||
if (type == 'imgNote') {
|
||
this.picStyle1.note = str;
|
||
} else if (type == 'imgTitle') {
|
||
this.picStyle1.title = str;
|
||
} else {
|
||
this.lineStyle1[type] = str;
|
||
}
|
||
if (this.threeVisible && this.lineStyle && this.lineStyle.am_id != null) {
|
||
this.onTableModalEditorInput();
|
||
}
|
||
},
|
||
onEdit(dataId) {
|
||
this.currentContent = {};
|
||
this.picStyle = {};
|
||
this.lineStyle = {};
|
||
this.currentId = null;
|
||
this.clearButton();
|
||
var data = this.Main_List.find((item) => item.am_id == dataId);
|
||
// console.log('data at line 667:', data);
|
||
if (data.type == 1) {
|
||
var extension = data.image.url.split('.').pop().toLowerCase();
|
||
if (extension == 'tif') {
|
||
const imgElement = document.querySelector(`[data-img-id="${data.ami_id}"]`);
|
||
if (imgElement) {
|
||
// 获取图片的 src
|
||
data.dataUrl = imgElement.src;
|
||
}
|
||
} else if (['jpg', 'jpeg', 'png'].includes(extension)) {
|
||
} else {
|
||
}
|
||
this.currentContent = { ...data, extension: extension };
|
||
this.picStyle = { ...data, extension: extension, picUrl: data.image.url, note: data.image.note, title: data.image.title };
|
||
this.picStyle.visiTitle = 'Edit Figure';
|
||
this.pictVisible = true;
|
||
} else if (data.type == 2) {
|
||
this.currentContent = { ...data };
|
||
this.lineStyle = {
|
||
...data,
|
||
table: JSON.parse(data.table.table_data),
|
||
html_data: data.table.html_data,
|
||
note: data.table.note,
|
||
title: data.table.title
|
||
};
|
||
this.lineStyle.visiTitle = 'Edit Table';
|
||
this.threeVisible = true;
|
||
this.seedTableModalDraftFromLineStyle();
|
||
this.afterOpenTableDrawerSyncCiteOrder();
|
||
} else {
|
||
data.content = data.content.replace(/<span[^>]*>/g, '').replace(/<\/span>/g, ''); // 去除span标签
|
||
this.editModalDraftHtml = data.content || '';
|
||
this.currentContent = data;
|
||
|
||
this.editVisible = true;
|
||
this.currentId = dataId;
|
||
if (this.p_article_id) {
|
||
this.fetchReferList();
|
||
}
|
||
this.$nextTick(() => {
|
||
this.$nextTick(() => {
|
||
const raw = this.syncEditModalHtmlFromEditor();
|
||
if (raw) {
|
||
this.editModalDraftHtml = raw;
|
||
}
|
||
const html = raw || (this.currentContent && this.currentContent.content) || '';
|
||
if (html) {
|
||
this.flushReorderFromEditModal(html);
|
||
}
|
||
this.refreshEditModalAutociteDisplay();
|
||
});
|
||
});
|
||
}
|
||
},
|
||
onAddContent(dataId) {
|
||
this.addContentVisible = true;
|
||
this.addContent = {};
|
||
|
||
this.currentId = dataId;
|
||
},
|
||
|
||
async onDrop(event, dataId) {
|
||
if (event.dataTransfer.getData('image')) {
|
||
const loading = this.$loading({
|
||
lock: true,
|
||
text: 'Loading...',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(0, 0, 0, 0.7)'
|
||
});
|
||
const draggedImage = JSON.parse(event.dataTransfer.getData('image'));
|
||
const draggedImageIndex = JSON.parse(event.dataTransfer.getData('imageIndex'));
|
||
this.$nextTick(async () => {
|
||
await this.$api
|
||
.post(this.urlList.setPositioningImage, {
|
||
am_id: dataId,
|
||
ami_id: draggedImage.ami_id
|
||
})
|
||
.then(async (res) => {
|
||
if (res.code == 0) {
|
||
loading.close();
|
||
this.refreshCurrentContent('positioningImg', dataId, res.data);
|
||
this.$nextTick(() => {
|
||
this.$refs.commonWordHtmlTypeSetting.refresh('positioningImg', res.data);
|
||
});
|
||
this.$forceUpdate();
|
||
} else {
|
||
loading.close();
|
||
this.$message.error(res.msg);
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
loading.close();
|
||
this.$message.error(err.msg);
|
||
});
|
||
});
|
||
} else if(event.dataTransfer.getData('table')) {
|
||
const loading = this.$loading({
|
||
lock: true,
|
||
text: 'Loading...',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(0, 0, 0, 0.7)'
|
||
});
|
||
const draggedtable = JSON.parse(event.dataTransfer.getData('table'));
|
||
|
||
this.$nextTick(async () => {
|
||
await this.$api
|
||
.post(this.urlList.setPositioningTable, {
|
||
am_id: dataId,
|
||
amt_id: draggedtable.amt_id
|
||
})
|
||
.then(async (res) => {
|
||
if (res.code == 0) {
|
||
loading.close();
|
||
this.refreshCurrentContent('positioningTable', dataId, res.data);
|
||
this.$nextTick(() => {
|
||
this.$refs.commonWordHtmlTypeSetting.refresh('positioningTable', res.data);
|
||
});
|
||
this.$forceUpdate();
|
||
} else {
|
||
loading.close();
|
||
this.$message.error(res.msg);
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
loading.close();
|
||
this.$message.error(err.msg);
|
||
});
|
||
});
|
||
}else{
|
||
|
||
}
|
||
},
|
||
getCommentList() {
|
||
this.$api
|
||
.post('api/Preaccept/getArticleMainCheckList', {
|
||
article_id: this.articleId
|
||
})
|
||
.then((res) => {
|
||
this.comments = res.data.list;
|
||
// this.positionAnnotations();
|
||
});
|
||
},
|
||
getWord() {
|
||
this.htmlContent = 'true';
|
||
},
|
||
// 获取数据
|
||
async getDate() {
|
||
this.imagesList = [];
|
||
let urlLInk = '';
|
||
let urlTask = {};
|
||
if (this.Art_Id != undefined) {
|
||
urlLInk = 'api/Preaccept/getArticleMainsNew';
|
||
urlTask.article_id = this.Art_Id;
|
||
}
|
||
const loading = this.$loading({
|
||
lock: true,
|
||
text: 'Loading...',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(0, 0, 0, 0.7)'
|
||
});
|
||
|
||
// 获取文章信息
|
||
await this.$api
|
||
.post(urlLInk, urlTask)
|
||
.then(async (res) => {
|
||
if (res.code == 0) {
|
||
this.Main_List = res.data.list.map((e) => {
|
||
e.checked = false;
|
||
return e;
|
||
});
|
||
this.getManuscirptContent();
|
||
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;
|
||
}
|
||
this.$nextTick(async () => {
|
||
await this.getWord();
|
||
if (this.$refs.catalogue) {
|
||
await this.$refs.catalogue.getCatalogueList();
|
||
}
|
||
/** 正文加载后按 Main_List 扫出全文首次出现顺序,写入 articleCiteIdOrder,弹窗角标与稿面一致 */
|
||
this.$nextTick(() => {
|
||
this.reorderReferencesFromMainListBody(null, null);
|
||
/** getReferList 早于 Main_List 时在此才完成正文序重排,与接口序不一致则回写 */
|
||
this.scheduleTryBatchSyncReferOrderIfOutOfSync();
|
||
});
|
||
loading.close();
|
||
});
|
||
// }, 1000);
|
||
} 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 Figure';
|
||
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;
|
||
},
|
||
|
||
// 确定保存图片
|
||
async savePic() {
|
||
var str = this.picStyle1.note ? await this.$commonJS.decodeHtml(this.picStyle1.note) : '';
|
||
|
||
var titleStr = this.picStyle1.title ? await this.$commonJS.decodeHtml(this.picStyle1.title) : '';
|
||
|
||
if (!this.picStyle.picUrl) {
|
||
this.$message.error('Please upload a picture');
|
||
return;
|
||
}
|
||
if (!titleStr) {
|
||
this.$message.error('Please enter a title');
|
||
return;
|
||
}
|
||
str = str.replace(/<br\s*\/?>/gi, '');
|
||
titleStr = titleStr.replace(/<br\s*\/?>/gi, '');
|
||
const loading = this.$loading({
|
||
lock: true,
|
||
text: 'Loading...',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(0, 0, 0, 0.7)'
|
||
});
|
||
if (this.picStyle.visiTitle == 'Edit Figure') {
|
||
this.$api
|
||
.post(this.urlList.editImage, {
|
||
ami_id: this.picStyle.ami_id,
|
||
url: this.picStyle.picUrl,
|
||
note: str,
|
||
title: titleStr
|
||
})
|
||
.then((res) => {
|
||
if (res.code == 0) {
|
||
loading.close();
|
||
this.$message.success('Successfully edit Figure!');
|
||
this.pictVisible = false;
|
||
this.$refs.commonWordHtmlTypeSetting.refresh(
|
||
'editImg',
|
||
res.data.image ? { ...res.data.image, has_selected: 1 } : res.data
|
||
);
|
||
this.refreshCurrentContent('editImg', res.data.am_id, res.data);
|
||
this.$nextTick(() => {
|
||
this.getCommentList();
|
||
this.$forceUpdate();
|
||
});
|
||
} else {
|
||
loading.close();
|
||
this.$message.error(res.msg);
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
loading.close();
|
||
this.$message.error(err);
|
||
});
|
||
} else {
|
||
this.$api
|
||
.post(this.urlList.addImage, {
|
||
article_id: this.articleId,
|
||
url: this.picStyle.picUrl,
|
||
note: str,
|
||
title: titleStr
|
||
})
|
||
.then((res) => {
|
||
if (res.code == 0) {
|
||
loading.close();
|
||
this.$message.success('Successfully Add Figure!');
|
||
this.pictVisible = false;
|
||
|
||
this.$refs.commonWordHtmlTypeSetting.refresh('addImg', res.data);
|
||
} else {
|
||
loading.close();
|
||
this.$message.error(res.msg);
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
loading.close();
|
||
this.$message.error(err);
|
||
});
|
||
}
|
||
},
|
||
handleSaveTable() {
|
||
this.$nextTick(() => {
|
||
this.$refs.commonTable.getTableContent('table');
|
||
});
|
||
},
|
||
handleSaveComment() {
|
||
this.$nextTick(() => {
|
||
this.$refs.tinymceChildComment.getContent('comment');
|
||
});
|
||
},
|
||
/** 稿面图片说明/标题内修改/移除 mycite 后,走 editImage 写回 */
|
||
async saveImageManuscript(payload) {
|
||
if (!payload || payload.ami_id == null) return;
|
||
const loading = this.$loading({
|
||
lock: true,
|
||
text: 'Loading...',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(0, 0, 0, 0.7)'
|
||
});
|
||
let strNote = payload.note || '';
|
||
let strTitle = payload.title || '';
|
||
if (strNote !== '') {
|
||
strNote = await this.$commonJS.decodeHtml(strNote);
|
||
}
|
||
if (strTitle !== '') {
|
||
strTitle = await this.$commonJS.decodeHtml(strTitle);
|
||
}
|
||
strNote = strNote.replace(/<br\s*\/?>/gi, '');
|
||
strTitle = strTitle.replace(/<br\s*\/?>/gi, '');
|
||
try {
|
||
const res = await this.$api.post(this.urlList.editImage, {
|
||
ami_id: payload.ami_id,
|
||
url: payload.url || '',
|
||
note: strNote,
|
||
title: strTitle
|
||
});
|
||
loading.close();
|
||
if (res.code == 0) {
|
||
this.$message.success('Successfully updated.');
|
||
if (this.$refs.commonWordHtmlTypeSetting && this.$refs.commonWordHtmlTypeSetting.refresh) {
|
||
this.$refs.commonWordHtmlTypeSetting.refresh(
|
||
'editImg',
|
||
res.data.image ? { ...res.data.image, has_selected: 1 } : res.data
|
||
);
|
||
}
|
||
this.refreshCurrentContent('editImg', res.data.am_id, res.data);
|
||
this.getCommentList();
|
||
this.$nextTick(() => {
|
||
const w = this.$refs.commonWord;
|
||
if (w && typeof w.syncRefOrder === 'function') {
|
||
w.syncRefOrder();
|
||
}
|
||
this.$nextTick(() => {
|
||
this.syncBatchReferenceOrderToServer();
|
||
});
|
||
});
|
||
} else {
|
||
this.$message.error(res.msg);
|
||
}
|
||
} catch (err) {
|
||
loading.close();
|
||
this.$message.error(err && err.message ? err.message : String(err));
|
||
}
|
||
},
|
||
/** 稿面表格单元格内修改/移除 mycite 后,走 editMainTable 写回 */
|
||
async saveTableManuscript(payload) {
|
||
if (!payload || payload.amt_id == null) return;
|
||
const loading = this.$loading({
|
||
lock: true,
|
||
text: 'Loading...',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(0, 0, 0, 0.7)'
|
||
});
|
||
let strTitle = payload.title || '';
|
||
let strNote = payload.note || '';
|
||
if (strNote !== '') {
|
||
strNote = await this.$commonJS.decodeHtml(strNote);
|
||
}
|
||
if (strTitle !== '') {
|
||
strTitle = await this.$commonJS.decodeHtml(strTitle);
|
||
}
|
||
strNote = strNote.replace(/<br\s*\/?>/gi, '');
|
||
strTitle = strTitle.replace(/<br\s*\/?>/gi, '');
|
||
try {
|
||
const res = await this.$api.post(this.urlList.editTable, {
|
||
amt_id: payload.amt_id,
|
||
table_data: payload.table_data,
|
||
html_data: payload.html_data || '',
|
||
note: strNote,
|
||
title: strTitle
|
||
});
|
||
loading.close();
|
||
if (res.code == 0) {
|
||
this.$message.success('Successfully updated.');
|
||
if (this.$refs.commonWordHtmlTypeSetting && this.$refs.commonWordHtmlTypeSetting.refresh) {
|
||
this.$refs.commonWordHtmlTypeSetting.refresh(
|
||
'editTable',
|
||
res.data.table ? { ...res.data.table, has_selected: 1 } : res.data
|
||
);
|
||
}
|
||
this.refreshCurrentContent('editTable', res.data.am_id, res.data);
|
||
this.getCommentList();
|
||
this.$nextTick(() => {
|
||
const w = this.$refs.commonWord;
|
||
if (w && typeof w.syncRefOrder === 'function') {
|
||
w.syncRefOrder();
|
||
}
|
||
this.$nextTick(() => {
|
||
this.syncBatchReferenceOrderToServer();
|
||
});
|
||
});
|
||
} else {
|
||
this.$message.error(res.msg);
|
||
}
|
||
} catch (err) {
|
||
loading.close();
|
||
this.$message.error(err && err.message ? err.message : String(err));
|
||
}
|
||
},
|
||
async saveTable(content) {
|
||
const cleanTableData = (tableList) => {
|
||
if (tableList.length == 0) {
|
||
return [];
|
||
} else {
|
||
// 定义清理函数:去掉所有 br 标签和 TinyMCE 占位符
|
||
const cleanText = (text) => {
|
||
if (!text) return '';
|
||
// return text.replace(/<br\s*\/?>/gi, '').trim();
|
||
return text;
|
||
};
|
||
|
||
// 1. 获取处理后的干净表头
|
||
const header = tableList[0].map((cell) => ({
|
||
...cell,
|
||
text: cleanText(cell.text)
|
||
}));
|
||
|
||
// 2. 过滤逻辑
|
||
const cleanedTable = tableList
|
||
.map((row) => {
|
||
// 首先:把每一行里的每个 cell.text 里的 <br> 都去掉
|
||
return row.map((cell) => ({
|
||
...cell,
|
||
text: cleanText(cell.text)
|
||
}));
|
||
})
|
||
.filter((row, index) => {
|
||
if (index === 0) return true;
|
||
|
||
// 3. 此时比较的就是没有 <br> 的文本了
|
||
const isHeaderRow = row.every((cell, cellIndex) => {
|
||
return cell.text === header[cellIndex].text;
|
||
});
|
||
|
||
return !isHeaderRow;
|
||
});
|
||
|
||
return cleanedTable;
|
||
}
|
||
};
|
||
var cleanedTableList = content.table ? content.table : [];
|
||
|
||
cleanedTableList = cleanTableData(content.table);
|
||
var strTitle = this.lineStyle1.title ? this.lineStyle1.title : '';
|
||
|
||
var strNote = this.lineStyle1.note ? this.lineStyle1.note : '';
|
||
if (strNote != '') {
|
||
strNote = await this.$commonJS.decodeHtml(strNote);
|
||
}
|
||
if (strTitle != '') {
|
||
strTitle = await this.$commonJS.decodeHtml(strTitle);
|
||
} else {
|
||
this.$message.error('Please enter a title');
|
||
return;
|
||
}
|
||
|
||
if (content && cleanedTableList && cleanedTableList.length > 0) {
|
||
const loading = this.$loading({
|
||
lock: true,
|
||
text: 'Loading...',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(0, 0, 0, 0.7)'
|
||
});
|
||
strNote = strNote.replace(/<br\s*\/?>/gi, '');
|
||
strTitle = strTitle.replace(/<br\s*\/?>/gi, '');
|
||
var tableStr = JSON.stringify(cleanedTableList);
|
||
|
||
if (this.lineStyle.visiTitle == 'Edit Table') {
|
||
this.$api
|
||
.post(this.urlList.editTable, {
|
||
amt_id: this.lineStyle.amt_id,
|
||
table_data: tableStr,
|
||
html_data: content.html_data,
|
||
note: strNote,
|
||
title: strTitle
|
||
})
|
||
.then((res) => {
|
||
if (res.code == 0) {
|
||
loading.close();
|
||
this.$message.success('Successfully edit Table!');
|
||
this.threeVisible = false;
|
||
setTimeout(() => {
|
||
this.$refs.commonWordHtmlTypeSetting.refresh(
|
||
'editTable',
|
||
res.data.table ? { ...res.data.table, has_selected: 1 } : res.data
|
||
);
|
||
this.refreshCurrentContent('editTable', res.data.am_id, res.data);
|
||
this.getCommentList();
|
||
});
|
||
} else {
|
||
loading.close();
|
||
this.$message.error(res.msg);
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
loading.close();
|
||
this.$message.error(err);
|
||
});
|
||
} else {
|
||
this.$api
|
||
.post(this.urlList.addTable, {
|
||
article_id: this.articleId,
|
||
table_data: JSON.stringify(cleanedTableList),
|
||
html_data: content.html_data,
|
||
note: strNote,
|
||
title: strTitle
|
||
})
|
||
.then((res) => {
|
||
if (res.code == 0) {
|
||
loading.close();
|
||
this.$message.success('Successfully Add Table!');
|
||
this.threeVisible = false;
|
||
|
||
this.$refs.commonWordHtmlTypeSetting.refresh('addTable', res.data);
|
||
} else {
|
||
loading.close();
|
||
this.$message.error(res.msg);
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
this.$message.error(err);
|
||
loading.close();
|
||
});
|
||
}
|
||
} else {
|
||
this.$message.error('Please fill in the table content!');
|
||
loading.close();
|
||
}
|
||
},
|
||
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.textarea = '';
|
||
this.lineStyle.titleCon = '';
|
||
this.lineTable = [];
|
||
this.lineStyle = {};
|
||
this.threeVisible = true;
|
||
|
||
this.$forceUpdate();
|
||
},
|
||
|
||
// 表格转化
|
||
CopyExcelToTable() {
|
||
if (this.lineStyle.textarea == '') {
|
||
this.$message.error('Please fill in the table content!');
|
||
return;
|
||
}
|
||
|
||
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;
|
||
},
|
||
|
||
// 推送
|
||
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.data.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 < 20;
|
||
if (!isLt2M) {
|
||
this.$message.error('Picture size cannot exceed 20M!');
|
||
return false;
|
||
}
|
||
|
||
const isValidFormat = ['image/jpeg', 'image/png', 'image/tiff'].includes(file.type);
|
||
if (!isValidFormat) {
|
||
this.$message.error(this.$t('commonTable.uploadImageInfo'));
|
||
}
|
||
return isValidFormat; // 返回false将阻止文件上传
|
||
},
|
||
positionAnnotations() {
|
||
this.$nextTick(() => {
|
||
this.comments.forEach((item) => {
|
||
const contentElement = document.querySelector('[remark-main-id="' + item.am_id + '"]');
|
||
const annotationElement = document.querySelector('[data-target="main-' + item.am_id + '"]');
|
||
if (contentElement && annotationElement) {
|
||
const rect = contentElement.getBoundingClientRect();
|
||
annotationElement.style.position = 'absolute';
|
||
annotationElement.style.top = `${rect.top}px`;
|
||
}
|
||
});
|
||
});
|
||
}
|
||
}
|
||
};
|
||
</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 red;
|
||
border-radius: 5px;
|
||
color: #606266;
|
||
}
|
||
.type_MTxt > div:hover {
|
||
background-color: rgb(0 102 153 / 10%);
|
||
border: 2px dashed rgb(0 102 153 / 50%);
|
||
}
|
||
/* .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;
|
||
}
|
||
|
||
::v-deep .uncited-tag.el-tag {
|
||
background-color: #f56c6c !important;
|
||
border-color: #f56c6c !important;
|
||
color: #fff !important;
|
||
}
|
||
|
||
.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;
|
||
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;
|
||
}
|
||
|
||
::v-deep .wordTableHtml table span blue {
|
||
color: rgb(0, 130, 170) !important;
|
||
}
|
||
::v-deep .wordTableHtml table span blue sup {
|
||
color: rgb(0, 130, 170) !important;
|
||
}
|
||
::v-deep .wordTableHtml table span blue sub {
|
||
color: rgb(0, 130, 170) !important;
|
||
}
|
||
.toolbar {
|
||
display: flex;
|
||
align-items: center;
|
||
width: 100%;
|
||
background-color: #fff;
|
||
border-bottom: none;
|
||
box-shadow: 0 2px 2px -2px rgba(34, 47, 62, 0.1), 0 8px 8px -4px rgba(34, 47, 62, 0.07);
|
||
padding: 4px 0;
|
||
height: 50px;
|
||
box-sizing: border-box;
|
||
transition: box-shadow 0.5s;
|
||
|
||
border-top-left-radius: 10px;
|
||
border-top-right-radius: 10px;
|
||
z-index: 2;
|
||
}
|
||
.toolbar .toolbar_item {
|
||
width: auto;
|
||
color: #767c82;
|
||
font-size: 14px;
|
||
padding: 0 11px 0 12px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
cursor: pointer;
|
||
line-height: 24px;
|
||
background-color: #fff;
|
||
}
|
||
|
||
.toolbar .toolbar_item img {
|
||
width: 24px;
|
||
height: 24px;
|
||
margin-right: 6px;
|
||
margin-top: -2px;
|
||
}
|
||
::v-deep .el-dialog__body {
|
||
padding: 10px 20px !important;
|
||
}
|
||
.editFormPizhu {
|
||
display: flex;
|
||
margin-bottom: 20px;
|
||
}
|
||
.editFormPizhu img {
|
||
margin-right: 10px;
|
||
}
|
||
.go-content-box {
|
||
background-color: #f2f3f5;
|
||
}
|
||
.commentList {
|
||
width: 350px !important;
|
||
|
||
padding: 15px;
|
||
position: relative;
|
||
box-sizing: border-box;
|
||
/* background-color: #fafafa; */
|
||
background-color: #fafafa;
|
||
box-shadow: 0 1px 3px rgb(16 17 19 / 6%);
|
||
}
|
||
|
||
/* 为整个页面的滚动条设置样式 */
|
||
::-webkit-scrollbar {
|
||
width: 8px; /* 垂直滚动条的宽度 */
|
||
height: 8px; /* 水平滚动条的高度 */
|
||
}
|
||
|
||
/* 滚动条轨道样式 */
|
||
::-webkit-scrollbar-track {
|
||
background: #f1f1f1; /* 滚动条轨道颜色 */
|
||
border-radius: 10px; /* 轨道圆角 */
|
||
}
|
||
|
||
/* 滚动条滑块样式 */
|
||
::-webkit-scrollbar-thumb {
|
||
background: #888; /* 滚动条滑块颜色 */
|
||
border-radius: 10px; /* 滑块圆角 */
|
||
}
|
||
|
||
/* 滑块在悬停时的样式 */
|
||
::-webkit-scrollbar-thumb:hover {
|
||
background: #555; /* 滑块悬停时的颜色 */
|
||
}
|
||
.uploadWordTableBox {
|
||
width: 38vw;
|
||
position: relative;
|
||
height: auto;
|
||
overflow: hidden;
|
||
padding: 10px;
|
||
box-sizing: border-box;
|
||
box-shadow: rgba(0, 0, 0, 0.1) 0px 2px 12px 0px;
|
||
}
|
||
::v-deep .el-drawer__header {
|
||
margin-bottom: 0;
|
||
padding: 15px;
|
||
}
|
||
.uploadWordTableBox .insertTable {
|
||
/* display: none; */
|
||
position: absolute;
|
||
right: 10px;
|
||
}
|
||
.uploadWordTableBox:hover {
|
||
background-color: #0066990d;
|
||
/* display: block !important; */
|
||
}
|
||
wmath[data-wrap='inline'] {
|
||
display: inline-block !important;
|
||
width: auto !important;
|
||
}
|
||
.duplicateRefBox {
|
||
color: #606266;
|
||
margin-top: 0px;
|
||
margin-bottom: 20px;
|
||
|
||
background: #fef0f0;
|
||
border: 1px solid #fbc4c4;
|
||
padding: 4px 10px;
|
||
font-size: 12px;
|
||
border-radius: 3px;
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.text-highlight {
|
||
background-color: rgb(252, 98, 93);
|
||
background-color: rgb(252 98 93 / 68%);
|
||
color: #333;
|
||
}
|
||
.status {
|
||
display: block;
|
||
width: 36px;
|
||
height: 36px;
|
||
border-radius: 36px;
|
||
font-size: 22px;
|
||
line-height: 36px;
|
||
color: #fff;
|
||
text-align: center;
|
||
}
|
||
|
||
.status.ok {
|
||
background: #a7e389;
|
||
}
|
||
|
||
.status.warn {
|
||
background: #ffd192;
|
||
}
|
||
|
||
.status.float {
|
||
display: inline-block;
|
||
}
|
||
.doiLink {
|
||
color: #409eff;
|
||
}
|
||
.reference-item{
|
||
line-height: 16px;
|
||
}
|
||
</style>
|