Files
tougao_web/src/components/page/GenerateCharts.vue

4427 lines
181 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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 }}&nbsp;<span v-html="formatTitle(scope.row.title)"></span>. &nbsp;<em>{{
scope.row.joura
}}</em
>.&nbsp;<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 }}&nbsp;<span v-html="formatTitle(scope.row.title)"></span>.&nbsp;{{
scope.row.dateno
}}.&nbsp;<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 为准。
* citeOptionsEdit 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连续全局序号合并为 13 */
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/batchUpdateReferp_article_id + listJSON 字符串,文献对象数组,顺序即保存序)
*/
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>