提交 编辑工作台
This commit is contained in:
@@ -19,8 +19,8 @@ const service = axios.create({
|
||||
// baseURL: 'https://submission.tmrjournals.com/', //正式 记得切换
|
||||
// baseURL: 'http://www.tougao.com/', //测试本地 记得切换
|
||||
// baseURL: 'http://192.168.110.110/tougao/public/index.php/',
|
||||
// baseURL: '/api', //本地
|
||||
baseURL: '/', //正式
|
||||
baseURL: '/api', //本地
|
||||
// baseURL: '/', //正式
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ a {
|
||||
position: absolute;
|
||||
left: 260px;
|
||||
right: 0;
|
||||
top: 60px;
|
||||
top: 40px;
|
||||
bottom: 0;
|
||||
padding-bottom: 30px;
|
||||
-webkit-transition: left .3s ease-in-out;
|
||||
|
||||
BIN
src/assets/img/Online Proofreading.png
Normal file
BIN
src/assets/img/Online Proofreading.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.8 KiB |
@@ -1,9 +1,10 @@
|
||||
<template>
|
||||
<div class="header">
|
||||
<!-- 折叠按钮 -->
|
||||
|
||||
<div class="" @click="goHome" >
|
||||
<i class="el-icon-s-home" style="font-size: 24px;line-height: 60px;color: #006699d1;"></i>
|
||||
|
||||
<div class="" style="display: flex;align-items: center">
|
||||
<i class="el-icon-s-home" style="font-size: 24px;line-height: 40px;color: #006699d1;"@click="goHome"></i>
|
||||
<img v-if="isProofreading" src="../../assets/img/Online Proofreading.png" alt="" height="24px" style="margin-left: 10px;margin-top: 4px;"/>
|
||||
</div>
|
||||
|
||||
<div class="header-right">
|
||||
@@ -85,6 +86,7 @@ export default {
|
||||
props: ['home'],
|
||||
data() {
|
||||
return {
|
||||
isProofreading: false,
|
||||
collapse: false,
|
||||
fullscreen: false,
|
||||
name: 'unknown user',
|
||||
@@ -277,6 +279,13 @@ export default {
|
||||
$route: {
|
||||
handler: function (route) {
|
||||
this.link_path = route.path;
|
||||
if(this.link_path.includes('OnlineProofreading')){
|
||||
this.isProofreading=true;
|
||||
|
||||
}else{
|
||||
this.isProofreading=false;
|
||||
}
|
||||
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
@@ -291,7 +300,7 @@ export default {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 60px;
|
||||
height: 40px;
|
||||
padding: 0 20px;
|
||||
color: #333639;
|
||||
box-shadow: 0 2px 2px -2px rgba(34, 47, 62, 0.1), 0 8px 8px -4px rgba(34, 47, 62, 0.07);
|
||||
@@ -302,7 +311,7 @@ export default {
|
||||
float: left;
|
||||
padding: 0 15px 0 21px;
|
||||
cursor: pointer;
|
||||
line-height: 60px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.header .logo {
|
||||
@@ -337,7 +346,7 @@ export default {
|
||||
|
||||
.header-user-con {
|
||||
display: flex;
|
||||
height: 60px;
|
||||
height: 40px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@@ -350,7 +359,7 @@ export default {
|
||||
.changelang {
|
||||
position: relative;
|
||||
width: 90px;
|
||||
height: 30px;
|
||||
/* height: 30px; */
|
||||
}
|
||||
|
||||
.btn-fullscreen {
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
</template>
|
||||
<template v-else>
|
||||
<v-head2 :home="true"></v-head2>
|
||||
<div style="width: 100%; height: calc(100% - 62px); overflow: hidden">
|
||||
<div style="width: 100%; height: calc(100% - 42px); overflow: hidden">
|
||||
<div class="content" style="padding: 0; overflow: hidden">
|
||||
<!-- <transition name="move" mode="out-in"> -->
|
||||
<!-- <keep-alive :include="tagsList"> -->
|
||||
|
||||
@@ -2,56 +2,14 @@
|
||||
<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: 285px;
|
||||
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
|
||||
<commonCatalogue
|
||||
:urlList="{
|
||||
img: 'api/Preaccept/getMainImages',
|
||||
table: 'api/Preaccept/getMainTables'
|
||||
@@ -61,6 +19,7 @@
|
||||
ref="commonWordHtmlTypeSetting"
|
||||
@onDragStart="onDragStart"
|
||||
@huifu="huifu"
|
||||
:catalogueList="catalogueList"
|
||||
@onAddComment="onAddComment"
|
||||
@addImage="handleImageAdd"
|
||||
@addTable="handleTableAdd"
|
||||
@@ -71,24 +30,17 @@
|
||||
@goToListComment="goToListComment"
|
||||
style="width: 100%; height: 100%; padding: 0 0px; box-sizing: border-box; background-color: #fff"
|
||||
>
|
||||
</common-word-html-type-setting>
|
||||
</commonCatalogue>
|
||||
<input type="file" ref="fileInput" style="display: none" @change="handleFileChange" />
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 100%; width: calc(100% - 285px); float: right; height: calc(100% - 0px); background-color: #e4e9ed">
|
||||
<!-- <div class="toolbar">
|
||||
<div class="toolbar_item" @click="handleImageAdd('img')">
|
||||
<img src="@/assets/img/upload.png" style="object-fit: contain" />
|
||||
<span>Add Figure </span>
|
||||
</div>
|
||||
<div class="toolbar_item" @click="handleTableAdd('table')">
|
||||
<img src="@/assets/img/uploadTable.png" style="object-fit: contain" />
|
||||
<span>Add Table </span>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<common-word
|
||||
|
||||
<div style="" class="right-content-box">
|
||||
<!-- title -->
|
||||
<div v-for="(item, index) in catalogueList" :key="index">
|
||||
<h1 :class="`title${item.key}`">{{ item.title }}</h1>
|
||||
|
||||
</div>
|
||||
<!-- <common-word
|
||||
v-if="htmlContent"
|
||||
ref="commonWord"
|
||||
:value="htmlContent"
|
||||
@@ -101,7 +53,6 @@
|
||||
@loaded="loadedWord"
|
||||
@onEdit="onEdit"
|
||||
@addContent="onAddContent"
|
||||
|
||||
@changeSort="changeSort"
|
||||
@onDelete="onDelete"
|
||||
@onDeletes="onDeletes"
|
||||
@@ -125,7 +76,7 @@
|
||||
<template slot="comment">
|
||||
<div style="" class="commentList annotations"></div>
|
||||
</template>
|
||||
</common-word>
|
||||
</common-word> -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -204,8 +155,7 @@
|
||||
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:">
|
||||
<common-content
|
||||
:id="`editor-${new Date().getTime()}-${lineStyle.am_id}-${lineStyle.amt_id}-title`"
|
||||
@@ -234,7 +184,7 @@
|
||||
></common-table>
|
||||
</el-form-item>
|
||||
<el-form-item label="Note:">
|
||||
<!-- :id="`editor-${new Date().getTime()}-${lineStyle.am_id}-${lineStyle.amt_id}-note`" -->
|
||||
|
||||
<common-content
|
||||
:id="`editor-${new Date().getTime()}-${lineStyle.am_id}-${lineStyle.amt_id}-note`"
|
||||
:isAutomaticUpdate="true"
|
||||
@@ -404,12 +354,14 @@
|
||||
</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
|
||||
<common-late-x v-if="showLateX" @close="showLateX = false" @save="saveLateX" :LateXInfo="LateXInfo"></common-late-x>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import commonCatalogue from '@/components/page/components/OnlineProofreading/catalogue.vue';
|
||||
|
||||
import bus from '@/components/common/bus';
|
||||
import { del, isShallow } from 'vue';
|
||||
import Tiff from 'tiff.js';
|
||||
@@ -419,6 +371,16 @@ import bottomTinymce from '@/components/page/components/Tinymce';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
catalogueList: [
|
||||
{ title: 'Title ', key: '1' },
|
||||
{ title: 'Author name', key: '2' },
|
||||
{ title: 'Affialition', key: '3' },
|
||||
{ title: 'Abstract & Keywords', key: '4' },
|
||||
{ title: 'Main text', key: '5' },
|
||||
{ title: 'Back Matter', key: '6' },
|
||||
{ title: 'Editorial inforation', key: '7' },
|
||||
{ title: 'Reference ', key: '8' },
|
||||
],
|
||||
zoomNum: (window.innerWidth * 0.38) / 850,
|
||||
uploadWordTables: [],
|
||||
tablesHtmlVisible: false,
|
||||
@@ -541,12 +503,12 @@ export default {
|
||||
},
|
||||
components: {
|
||||
Tinymce,
|
||||
bottomTinymce
|
||||
bottomTinymce,
|
||||
commonCatalogue
|
||||
},
|
||||
computed: {
|
||||
combinedValue() {
|
||||
// 将两个值组合成一个新的值,可以是字符串、数组、对象等
|
||||
// return `${this.isFirstComponentLoaded}-${this.isWordComponentLoaded}`;
|
||||
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -571,9 +533,7 @@ export default {
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
// await this.$api.post('api/Proofread/proofRead', {
|
||||
// article_id: this.$route.query.id
|
||||
// });
|
||||
|
||||
localStorage.removeItem('scrollPosition');
|
||||
this.isShowEditComment();
|
||||
this.getDate();
|
||||
@@ -582,9 +542,7 @@ export default {
|
||||
},
|
||||
mounted() {},
|
||||
async activated() {
|
||||
// await this.$api.post('api/Proofread/proofRead', {
|
||||
// article_id: this.$route.query.id
|
||||
// });
|
||||
|
||||
this.isShowEditComment();
|
||||
this.getDate();
|
||||
this.getCommentList();
|
||||
@@ -593,10 +551,10 @@ export default {
|
||||
methods: {
|
||||
async copyArray(data) {
|
||||
try {
|
||||
// 将数组内容转换为字符串,使用换行符分隔
|
||||
|
||||
const textToCopy = JSON.stringify(data);
|
||||
|
||||
// 使用 Clipboard API 复制文本
|
||||
|
||||
await navigator.clipboard.writeText(textToCopy);
|
||||
alert('数组内容已复制到剪贴板!');
|
||||
} catch (err) {
|
||||
@@ -697,7 +655,7 @@ export default {
|
||||
async saveContent(content, am_id) {
|
||||
var that = this;
|
||||
var str = content.replace(/^<p>\s*(.*?)\s*<\/p>$/, '$1').trim();
|
||||
|
||||
|
||||
str = await that.$commonJS.decodeHtml(str);
|
||||
|
||||
await that.$api
|
||||
@@ -1192,21 +1150,19 @@ export default {
|
||||
},
|
||||
|
||||
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.getDate();
|
||||
|
||||
this.getCommentList();
|
||||
}else{
|
||||
if (res.code == 0) {
|
||||
this.getDate();
|
||||
|
||||
this.getCommentList();
|
||||
} else {
|
||||
this.$message.error(res.msg);
|
||||
}
|
||||
|
||||
})
|
||||
.catch((err) => {
|
||||
this.$message.error(err.msg);
|
||||
@@ -1279,7 +1235,6 @@ export default {
|
||||
},
|
||||
deleteProofreading(data, index) {
|
||||
console.log('comment at line 480:', data);
|
||||
|
||||
},
|
||||
|
||||
async cancelSolveComment(data) {
|
||||
@@ -1401,7 +1356,7 @@ export default {
|
||||
|
||||
this.currentId = dataId;
|
||||
},
|
||||
|
||||
|
||||
async onDrop(event, dataId) {
|
||||
if (event.dataTransfer.getData('image')) {
|
||||
const draggedImage = JSON.parse(event.dataTransfer.getData('image'));
|
||||
@@ -1475,13 +1430,10 @@ export default {
|
||||
});
|
||||
},
|
||||
getWord() {
|
||||
|
||||
this.htmlContent = 'true';
|
||||
|
||||
},
|
||||
// 获取数据
|
||||
async getDate() {
|
||||
|
||||
this.imagesList = [];
|
||||
let urlLInk = '';
|
||||
let urlTask = {};
|
||||
@@ -1501,7 +1453,7 @@ export default {
|
||||
.post(urlLInk, urlTask)
|
||||
.then(async (res) => {
|
||||
if (res.code == 0) {
|
||||
this.Main_List = res.data.list.map(e=>{
|
||||
this.Main_List = res.data.list.map((e) => {
|
||||
e.checked = false;
|
||||
return e;
|
||||
});
|
||||
@@ -1515,8 +1467,7 @@ export default {
|
||||
// setTimeout(async () => {
|
||||
this.$nextTick(async () => {
|
||||
await this.getWord();
|
||||
|
||||
|
||||
|
||||
loading.close();
|
||||
});
|
||||
// }, 1000);
|
||||
@@ -1904,6 +1855,28 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.container{
|
||||
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;
|
||||
}
|
||||
.right-side{
|
||||
width: 240px;
|
||||
float: left;
|
||||
height: 100%;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 1px 3px rgb(16 17 19 / 6%);
|
||||
border-radius: 4px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.right-content-box{
|
||||
width: 100%; width: calc(100% - 245px); float: right; height: calc(100% - 0px); background-color: #e4e9ed
|
||||
}
|
||||
.lineStyle {
|
||||
border-top: 1px solid #0066994d;
|
||||
padding: 20px 20px 40px 20px;
|
||||
|
||||
@@ -673,12 +673,12 @@
|
||||
>
|
||||
<span v-if="iken.state != 0"
|
||||
style="color: #006699;float: right;"
|
||||
@click="handleClick(iken)"
|
||||
@click="handleClick(iken,'detail')"
|
||||
>Detail</span
|
||||
>
|
||||
</td>
|
||||
<!-- 1st review:原逻辑不变 -->
|
||||
<td @click="handleClick(iken)" style="cursor: pointer">
|
||||
<td @click="handleClick(iken,'question')" style="cursor: pointer">
|
||||
<span style="display: inline-block; margin-left: 4px; margin-right: 8px">
|
||||
<font
|
||||
v-if="iken.recommend == 1 || iken.recommend == 2"
|
||||
@@ -726,7 +726,7 @@
|
||||
<span
|
||||
v-if="Array.isArray(iken.repeat) && iken.repeat[index1]"
|
||||
style="cursor: pointer"
|
||||
@click="handleClick(iken)"
|
||||
|
||||
>
|
||||
<span style="display: inline-block; margin-left: 4px; margin-right: 8px">
|
||||
<font
|
||||
@@ -1007,6 +1007,9 @@
|
||||
<el-button type="" @click="FinalDecisionVisible=false">Cancal</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<reviewerDetail ref="reviewerDetail" v-if="reviewerVisible" :reviewerDetail="reviewerDetail" destroy-on-close></reviewerDetail>
|
||||
|
||||
<el-dialog title="Edit H Index" :visible.sync="HEditVisible" width="400px" :close-on-click-modal="false">
|
||||
<div style="margin: 0 0 20px 10px; font-weight: bold">{{ HIxForm.realname }}</div>
|
||||
<div style="margin: 0 0 20px 10px">Email :{{ HIxForm.email }}</div>
|
||||
@@ -1339,15 +1342,18 @@
|
||||
|
||||
<script>
|
||||
import timetalk from './time_talk';
|
||||
import reviewerDetail from '../../components/page/components/articleDetail/reviewerdetail.vue';
|
||||
export default {
|
||||
components: {
|
||||
timetalk
|
||||
timetalk,reviewerDetail
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
reviewerDetail: {},
|
||||
corresList: [],
|
||||
finalDecisionData: {},
|
||||
FinalDecisionVisible: false,
|
||||
reviewerVisible: false,
|
||||
expanded: false,
|
||||
corresVisible: false,
|
||||
isShowAuthorInfo: false,
|
||||
@@ -1731,6 +1737,7 @@ this.FinalDecisionVisible=true
|
||||
this.$forceUpdate();
|
||||
},
|
||||
articleReviewer(row) {
|
||||
|
||||
this.$router.push({
|
||||
path: 'articleReviewer',
|
||||
query: {
|
||||
@@ -1893,14 +1900,15 @@ this.FinalDecisionVisible=true
|
||||
// console.log('maxItem at line 2142:', maxItem.repeat.length)
|
||||
return maxItem && maxItem.repeat ? maxItem.repeat.length : 0;
|
||||
},
|
||||
handleClick(item) {
|
||||
console.log('item at line 1228:', item);
|
||||
this.$router.push({
|
||||
path: 'articleReviewerDetail',
|
||||
query: {
|
||||
id: item.art_rev_id
|
||||
}
|
||||
});
|
||||
handleClick(item,type) {
|
||||
|
||||
this.reviewerDetail=item
|
||||
this.reviewerVisible=true
|
||||
this.$nextTick(()=>{
|
||||
this.$refs.reviewerDetail.init(item.art_rev_id,type)
|
||||
})
|
||||
|
||||
|
||||
},
|
||||
|
||||
goReviewerDetail(id) {
|
||||
|
||||
@@ -760,6 +760,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
props: {
|
||||
dateId: {
|
||||
@@ -767,7 +768,9 @@ export default {
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
|
||||
components: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
editVisible1: false,
|
||||
|
||||
@@ -1052,11 +1052,13 @@ import { Loading } from 'element-ui';
|
||||
import timetalk from './time_talk';
|
||||
import commonRemarkList from './articleListEditor_A_list.vue';
|
||||
import articleEditorDetail from './articleEditorDetail.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
timetalk,
|
||||
commonRemarkList,
|
||||
articleEditorDetail
|
||||
articleEditorDetail,
|
||||
|
||||
},
|
||||
props: ['journals'],
|
||||
data() {
|
||||
|
||||
661
src/components/page/components/OnlineProofreading/catalogue.vue
Normal file
661
src/components/page/components/OnlineProofreading/catalogue.vue
Normal file
@@ -0,0 +1,661 @@
|
||||
<template>
|
||||
<!-- v-show="tables.length > 0 || images.length > 0" -->
|
||||
<div
|
||||
style="background-color: transparent !important; margin-top: 0px !important; height: 100%; padding: 0 !important; overflow: hidden"
|
||||
class="ManuscirptList"
|
||||
>
|
||||
<!-- 图片缩略图区域 -->
|
||||
|
||||
|
||||
<div class="title">
|
||||
Contents
|
||||
</div>
|
||||
<div
|
||||
style=""
|
||||
class="arrlist"
|
||||
>
|
||||
<ul style="width: 100%; height: auto">
|
||||
|
||||
|
||||
<li >
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 10px; justify-content: start">
|
||||
<div @click="goToListComment(item.key)"
|
||||
v-for="(item, index) in catalogueList"
|
||||
style="width: calc(100%); display: flex; align-items: center; justify-content: space-between; color: #606266"
|
||||
>
|
||||
<span><span style="color: #888;margin-right: 5px;">{{ index+1 }}.</span> {{ item.title }}</span>
|
||||
|
||||
<!-- <div
|
||||
style="
|
||||
width: calc(100% - 50px);
|
||||
white-space: nowrap; /* 防止文本换行 */
|
||||
overflow: hidden; /* 隐藏超出部分 */
|
||||
text-overflow: ellipsis;
|
||||
"
|
||||
>
|
||||
<p
|
||||
v-html="index + 1 + '. ' + item.content"
|
||||
style="font-size: 14px; width: 100%; overflow: hidden; line-height: 30px"
|
||||
></p>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mediaUrl } from '@/common/js/commonJS.js'; // 引入通用逻辑
|
||||
export default {
|
||||
props: ['articleId', 'imgWidth', 'imgHeight', 'scale', 'isEdit', 'isShowEdit', 'urlList', 'content','catalogueList'],
|
||||
data() {
|
||||
return {
|
||||
isShowComment: false,
|
||||
isCollapse: false,
|
||||
isEditComment: false,
|
||||
isEditing: null, // 用于跟踪当前正在编辑的批注索引
|
||||
selectedComment: null, // 存储当前选择的批注内容
|
||||
comments: [], // 存储所有批注
|
||||
isFresh: false,
|
||||
currentSelectType: '0',
|
||||
currentMenu: 1,
|
||||
|
||||
mediaUrl,
|
||||
|
||||
statusList: [
|
||||
{ title: 'ALL', type: '0' },
|
||||
{ title: 'Typed', type: '1' },
|
||||
{ title: 'Unfettered', type: '2' }
|
||||
],
|
||||
|
||||
images: [],
|
||||
tables: [],
|
||||
imagesList: [],
|
||||
tablesList: [],
|
||||
tablesHtml: [],
|
||||
imagesHtml: [],
|
||||
activeNames: ['images', 'tables']
|
||||
};
|
||||
},
|
||||
directives: {
|
||||
// 注册一个局部的自定义指令 v-focus
|
||||
focus: {
|
||||
// 指令的定义
|
||||
inserted: function (el) {
|
||||
console.log('el at line 263:', el);
|
||||
// 聚焦元素
|
||||
el.querySelector('textarea').focus();
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
changeIsCollapse(e) {
|
||||
localStorage.setItem('isCollapse', e);
|
||||
},
|
||||
isShowEditComment() {
|
||||
if (localStorage.getItem('U_role')) {
|
||||
var identity = localStorage.getItem('U_role');
|
||||
if (identity.includes('editor')) {
|
||||
this.isEditComment = true;
|
||||
} else {
|
||||
this.isEditComment = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
changeComment() {
|
||||
this.isShowComment = !this.isShowComment;
|
||||
},
|
||||
// 编辑评论,显示文本框
|
||||
editComment(index) {
|
||||
if (this.isEditComment) {
|
||||
this.isEditing = index; // 设置当前正在编辑的评论索引
|
||||
}
|
||||
},
|
||||
|
||||
// 保存评论修改
|
||||
saveComment(index, comment) {
|
||||
if (this.isEditComment) {
|
||||
this.$emit('addComment', comment);
|
||||
this.isEditing = null; // 退出编辑模式
|
||||
}
|
||||
},
|
||||
onAddComment(comment) {
|
||||
if (this.isEditComment) {
|
||||
this.$emit('onAddComment', comment.am_id);
|
||||
// this.isEditing = null; // 退出编辑模式
|
||||
}
|
||||
},
|
||||
|
||||
// 删除评论
|
||||
deleteComment(comment, index) {
|
||||
console.log('comment at line 480:', comment);
|
||||
if (this.isEditComment) {
|
||||
this.$confirm(this.$t('commonTable.removeAnnotations'), 'Prompt', {
|
||||
confirmButtonText: 'Submit',
|
||||
cancelButtonText: 'Cancel',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
this.$api
|
||||
.post('api/Preaccept/clearMainsRemark', {
|
||||
am_id: comment.am_id
|
||||
})
|
||||
.then((res) => {
|
||||
this.getCommentList();
|
||||
});
|
||||
// this.comments.splice(index, 1); // 删除评论
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
},
|
||||
getTime(timestamp) {
|
||||
// 创建一个新的 Date 对象
|
||||
|
||||
// 转换为 Date 对象(乘以 1000,因为 JavaScript 使用毫秒)
|
||||
const date = new Date(timestamp * 1000);
|
||||
|
||||
// 获取年、月、日、时、分、秒
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份是从 0 开始的,所以加 1
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
const hours = String(date.getHours()).padStart(2, '0');
|
||||
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||||
const seconds = String(date.getSeconds()).padStart(2, '0');
|
||||
|
||||
// 格式化为 年-月-日 时:分:秒
|
||||
const formattedDate = `${year}-${month}-${day} ${hours}:${minutes}`;
|
||||
|
||||
console.log(formattedDate); // 输出: 2025-10-20 15:30:03
|
||||
|
||||
return formattedDate;
|
||||
},
|
||||
goToComment(mainId) {
|
||||
this.$nextTick(() => {
|
||||
this.$emit('goToComment', mainId);
|
||||
});
|
||||
},
|
||||
getCommentList() {
|
||||
this.$api
|
||||
.post('api/Preaccept/getNotes', {
|
||||
article_id: this.articleId
|
||||
})
|
||||
.then((res) => {
|
||||
this.comments = res.data.list;
|
||||
});
|
||||
},
|
||||
addImage() {
|
||||
this.$emit('addImage');
|
||||
},
|
||||
addTable() {
|
||||
this.$emit('addTable');
|
||||
},
|
||||
handlePaperclip() {
|
||||
this.$emit('handlePaperclip');
|
||||
},
|
||||
add(type) {
|
||||
this.$emit('add', type);
|
||||
},
|
||||
edit(data, type) {
|
||||
this.$emit('edit', data, type);
|
||||
},
|
||||
huifu(id) {
|
||||
this.$emit('huifu', id);
|
||||
},
|
||||
handleSelectMenu(v) {
|
||||
this.currentMenu = v;
|
||||
this.currentSelectType = '0';
|
||||
// if (v == 1) {
|
||||
// this.getCommentList();
|
||||
// } else {
|
||||
this.filterData();
|
||||
// }
|
||||
},
|
||||
selectType(v) {
|
||||
this.currentSelectType = v.type;
|
||||
this.filterData();
|
||||
},
|
||||
filterData(type) {
|
||||
if (type) {
|
||||
if (type == 'img') {
|
||||
this.imagesList = [...this.images];
|
||||
} else if (type == 'table') {
|
||||
this.tablesList = [...this.tables];
|
||||
}
|
||||
} else {
|
||||
if (this.currentMenu == 1) {
|
||||
switch (this.currentSelectType) {
|
||||
case '0':
|
||||
this.imagesList = [...this.images];
|
||||
break;
|
||||
case '1':
|
||||
this.imagesList = [...this.images].filter((e) => e.has_selected == 1);
|
||||
break;
|
||||
case '2':
|
||||
this.imagesList = [...this.images].filter((e) => e.has_selected == 0);
|
||||
break;
|
||||
}
|
||||
} else if (this.currentMenu == 2) {
|
||||
switch (this.currentSelectType) {
|
||||
case '0':
|
||||
this.tablesList = [...this.tables];
|
||||
// console.log('this.tablesList at line 393:', this.tablesList);
|
||||
break;
|
||||
case '1':
|
||||
this.tablesList = [...this.tables].filter((e) => e.has_selected == 1);
|
||||
break;
|
||||
case '2':
|
||||
this.tablesList = [...this.tables].filter((e) => e.has_selected == 0);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
},
|
||||
goToListComment(id, type) {
|
||||
this.$emit('goToListComment', id, type);
|
||||
},
|
||||
async refresh(type) {
|
||||
this.isFresh = false;
|
||||
this.$nextTick(async () => {
|
||||
if (type == 'img') {
|
||||
await this.getWordimgList();
|
||||
|
||||
await this.filterData();
|
||||
} else if (type == 'table') {
|
||||
await this.getWordTablesList();
|
||||
await this.filterData();
|
||||
}
|
||||
this.$forceUpdate();
|
||||
this.isFresh = true;
|
||||
// this.$emit('loaded', loadedthis.images);
|
||||
});
|
||||
},
|
||||
changeDataIsHidden(val, status, type) {
|
||||
console.log('type at line 165:', type);
|
||||
var index;
|
||||
this.$nextTick(() => {
|
||||
if (type == 'img') {
|
||||
index = this.images.findIndex((element) => element.article_image_id === val.article_image_id);
|
||||
console.log('index at line 170:', index);
|
||||
this.images[index].isHidden = status;
|
||||
} else {
|
||||
index = this.tables.findIndex((element) => element.id === id);
|
||||
this.tables[index].isHidden = status;
|
||||
}
|
||||
this.$forceUpdate();
|
||||
});
|
||||
},
|
||||
changeIsHidden(index, status, type) {
|
||||
console.log('type at line 165:', type);
|
||||
this.$nextTick(() => {
|
||||
if (type == 'img') {
|
||||
this.images[index].isHidden = status;
|
||||
} else {
|
||||
this.tables[index].isHidden = status;
|
||||
console.log('this.tables at line 169:', this.tables);
|
||||
}
|
||||
this.$forceUpdate();
|
||||
});
|
||||
},
|
||||
onDragStart($event, item, index, type) {
|
||||
this.$emit('onDragStart', $event, item, index, type);
|
||||
},
|
||||
changeActiveNames(e) {
|
||||
console.log('e at line 156:', e);
|
||||
|
||||
if (['tables'].includes(e)) {
|
||||
this.$nextTick(() => {
|
||||
this.getWordTablesList();
|
||||
});
|
||||
}
|
||||
if (['images'].includes(e)) {
|
||||
this.$nextTick(() => {
|
||||
this.getWordimgList();
|
||||
});
|
||||
}
|
||||
},
|
||||
openPreview(index, type) {
|
||||
this.$nextTick(() => {
|
||||
document.getElementById(type + '-modal-' + index).style.display = 'flex';
|
||||
});
|
||||
},
|
||||
async getWordimgList() {
|
||||
var that = this;
|
||||
await this.$api
|
||||
.post(this.urlList ? this.urlList.img : 'api/Article/getArticleImages', {
|
||||
article_id: this.articleId
|
||||
})
|
||||
.then(async (res) => {
|
||||
var list = [...res.data.list];
|
||||
if (this.urlList) {
|
||||
list = list.map((e) => {
|
||||
return {
|
||||
...e,
|
||||
image: e.url,
|
||||
article_image_id: e.ami_id
|
||||
};
|
||||
});
|
||||
} else {
|
||||
list = res.data.list;
|
||||
}
|
||||
|
||||
if (list.length > 0) {
|
||||
list.forEach((img, index) => {
|
||||
var extension = img.image.split('.').pop().toLowerCase();
|
||||
// if (extension === 'tif' || extension === 'jpg' || extension === 'jpeg' || extension === 'png') {
|
||||
const modalContent = `<img src="${this.mediaUrl + img.image}" alt="Image ${index}" style="width:100%;" >`;
|
||||
|
||||
this.$commonJS.createImageModal(index, modalContent, 'img');
|
||||
// }
|
||||
});
|
||||
}
|
||||
this.images = list;
|
||||
this.$emit('loaded', this.images);
|
||||
});
|
||||
},
|
||||
isHeaderRow(rowIndex, table) {
|
||||
var table =table;
|
||||
|
||||
var head = table[0];
|
||||
|
||||
return rowIndex < head[0].rowspan; // 假设前两行是表头
|
||||
},
|
||||
async getWordTablesList(callback) {
|
||||
this.$api
|
||||
.post(this.urlList ? this.urlList.table : 'api/Article/getArticleTable', {
|
||||
article_id: this.articleId
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (this.urlList) {
|
||||
this.tables =
|
||||
res.data.list && res.data.list.length > 0
|
||||
? res.data.list.map((e) => {
|
||||
return {
|
||||
...e,
|
||||
article_table_id: e.amt_id,
|
||||
table: JSON.parse(e.table_data)
|
||||
};
|
||||
})
|
||||
: [];
|
||||
} else {
|
||||
this.tables =
|
||||
res.data.list && res.data.list.length > 0
|
||||
? res.data.list.map((e) => {
|
||||
return {
|
||||
...e,
|
||||
|
||||
table: JSON.parse(e.table)
|
||||
};
|
||||
})
|
||||
: [];
|
||||
}
|
||||
await this.filterData('table');
|
||||
if (this.tables.length > 0) {
|
||||
this.tables.forEach((table, index) => {
|
||||
var modalContent = `
|
||||
<div class="wordTableHtml" style="background:#FFF;padding:20px">
|
||||
<table
|
||||
border="1"
|
||||
style="
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
table-layout: auto;"
|
||||
>`;
|
||||
|
||||
if (table.table && table.table.length > 0) {
|
||||
table.table.forEach((row,i) => {
|
||||
modalContent += `<tr class="${this.isHeaderRow(i, table.table)? 'table-header-row':'' }">`;
|
||||
row.forEach((cell) => {
|
||||
modalContent += `
|
||||
<td
|
||||
colspan="${cell.colspan || 1}"
|
||||
rowspan="${cell.rowspan || 1}"
|
||||
style=""
|
||||
>
|
||||
<span>${cell.text}</span>
|
||||
</td>`;
|
||||
});
|
||||
modalContent += `</tr>`;
|
||||
});
|
||||
}
|
||||
|
||||
modalContent += `</table></div>`;
|
||||
this.$commonJS.createImageModal(index, modalContent, 'table', '');
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
this.isCollapse = localStorage.getItem('isCollapse') == 'true' ? true : false;
|
||||
console.log('localStorage.getItem', typeof localStorage.getItem('isCollapse'));
|
||||
this.isShowEditComment();
|
||||
this.isFresh = false;
|
||||
this.$nextTick(async () => {
|
||||
await this.getCommentList();
|
||||
await this.getWordimgList();
|
||||
await this.getWordTablesList();
|
||||
await this.filterData();
|
||||
this.isFresh = true;
|
||||
});
|
||||
},
|
||||
async activated() {
|
||||
this.isCollapse = localStorage.getItem('isCollapse') == 'true' ? true : false;
|
||||
this.isFresh = false;
|
||||
this.isShowEditComment();
|
||||
this.$nextTick(async () => {
|
||||
await this.getWordimgList();
|
||||
await this.getWordTablesList();
|
||||
await this.filterData();
|
||||
this.isFresh = true;
|
||||
});
|
||||
},
|
||||
mounted() {}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ManuscirptList {
|
||||
background-color: none !important;
|
||||
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0);
|
||||
color: #333639;
|
||||
}
|
||||
.ManuscirptList div {
|
||||
cursor: pointer;
|
||||
background-color: none !important;
|
||||
}
|
||||
::v-deep .wordTableHtml table {
|
||||
cursor: pointer;
|
||||
background-color: #fff !important;
|
||||
border-bottom: 1px solid #000 !important;
|
||||
}
|
||||
.el-menu-vertical-demo {
|
||||
width: 85px;
|
||||
}
|
||||
.el-menu-vertical-demo li {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 10px 6px !important;
|
||||
font-size: 14px !important;
|
||||
text-align: center;
|
||||
}
|
||||
::v-deep .el-menu-vertical-demo.el-menu-item:focus,
|
||||
.el-menu-item:hover {
|
||||
background-color: #f8f8f9 !important;
|
||||
}
|
||||
::v-deep .el-menu-item.is-active {
|
||||
background-color: #2196f32e !important;
|
||||
}
|
||||
.isSelectType {
|
||||
background-color: #2196f32e !important;
|
||||
color: #006699;
|
||||
}
|
||||
li {
|
||||
list-style: none;
|
||||
}
|
||||
.item_box {
|
||||
background-color: #f2f3f5;
|
||||
border: 1px solid rgba(0, 0, 0, 0);
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.go-transition .title {
|
||||
background-color: #e5e6eb;
|
||||
color: #767c82;
|
||||
font-size: 13px;
|
||||
padding: 2px 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.go-transition .list-img {
|
||||
padding: 6px 0;
|
||||
background-color: #f2f3f5;
|
||||
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.go-transition .list-img :hover {
|
||||
transition: all 0.4s;
|
||||
}
|
||||
.go-content-charts-item-box {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
gap: 9px;
|
||||
transition: all 0.7s linear;
|
||||
}
|
||||
.arraylist {
|
||||
background-color: #f8f8f9;
|
||||
}
|
||||
.arrlist {
|
||||
width: 240px; padding: 20px; height: calc(100% - 30px); box-sizing: border-box; overflow-y: auto;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
.arrlist li{
|
||||
line-height: 30px
|
||||
}
|
||||
.arrlist::-webkit-scrollbar-thumb {
|
||||
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0);
|
||||
min-height: 12px;
|
||||
border: 4px solid transparent;
|
||||
background-clip: content-box;
|
||||
border-radius: 7px;
|
||||
background-color: #c8d5e1;
|
||||
}
|
||||
.badge {
|
||||
background-color: #f56c6c;
|
||||
border-radius: 10px;
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
padding: 0 6px;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
border: 1px solid #fff;
|
||||
position: absolute;
|
||||
}
|
||||
.comments-section {
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #cecfd3;
|
||||
border-left: 2px solid #cecfd3;
|
||||
/* border-radius: 5px; */
|
||||
background-color: #f9f9f9;
|
||||
box-shadow: rgba(16, 17, 19, 0.06) 0px 1px 3px;
|
||||
width: 300px;
|
||||
background-color: #fafafa;
|
||||
float: right;
|
||||
position: absolute;
|
||||
right: -302px;
|
||||
top: 0px;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.comment-item {
|
||||
padding: 5px 0;
|
||||
border-bottom: 1px solid #ddd;
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.comment-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.comment-details {
|
||||
margin-top: 20px;
|
||||
padding: 10px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 5px;
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.comment-details h3 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.comment-details p {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.comment-details button {
|
||||
padding: 5px 10px;
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.comment-details button:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
.comments-section ul,
|
||||
.comments-section li {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
::v-deep.pizhu.el-link--default:hover {
|
||||
border-color: #fc625d !important;
|
||||
}
|
||||
.go-mt {
|
||||
/* background-color: #f2f3f5;
|
||||
height: 28px; */
|
||||
width: 200px;
|
||||
float: right;
|
||||
}
|
||||
.double .item_box {
|
||||
width: 46% !important;
|
||||
}
|
||||
.double .item_box .previewbox {
|
||||
display: none;
|
||||
}
|
||||
.double .item_box .imgbox {
|
||||
height: 50px !important;
|
||||
width: auto !important;
|
||||
}
|
||||
.double .item_box .imgbox img {
|
||||
height: 60px !important;
|
||||
width: auto !important;
|
||||
}
|
||||
.double .go-transition .title {
|
||||
font-size: 12px !important;
|
||||
padding: 0 2px !important;
|
||||
line-height: 20px !important;
|
||||
}
|
||||
.single {
|
||||
}
|
||||
.title{
|
||||
line-height: 28px;
|
||||
padding: 10px 10px;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
551
src/components/page/components/articleDetail/reviewerdetail.vue
Normal file
551
src/components/page/components/articleDetail/reviewerdetail.vue
Normal file
@@ -0,0 +1,551 @@
|
||||
<template>
|
||||
<el-dialog :title="type=='detail'?'Manuscript reviewer detail':'Feedback questionnaire'" :visible.sync="reviewerVisible" width="1200px" :close-on-click-modal="false">
|
||||
<div>
|
||||
|
||||
<div class="container" v-if="type=='detail'">
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="20">
|
||||
<div class="form-box" style="width: 100%">
|
||||
<el-form ref="articleform" :model="detailDate" label-width="130px">
|
||||
<el-form-item label="Article">
|
||||
<span>{{ detailDate.article }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="Reviewer">
|
||||
<span>{{ detailDate.reviewer }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="Reviewer email">
|
||||
<span>{{ detailDate.reviewer_email }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="CreateTime">
|
||||
<span>{{ formatDate(detailDate.ctime) }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="Disclose name or anonymous" label-width="200px">
|
||||
<span v-if="reviewList.length > 0 && reviewList[0].is_anonymous == 0">Disclose name</span>
|
||||
<span v-if="reviewList.length > 0 && reviewList[0].is_anonymous == 1">Remain anonymous</span>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="canRepeat == 1">
|
||||
<el-button type="primary" @click="createRevision">Re-review</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8" v-if="recordList && recordList.length > 0">
|
||||
<div class="clearfix fsheader">
|
||||
<h4>Peer-review Archive</h4>
|
||||
</div>
|
||||
<div class="time">
|
||||
<el-timeline>
|
||||
<el-timeline-item
|
||||
reverse="true"
|
||||
:timestamp="item.ctime | formatDatehms"
|
||||
placement="top"
|
||||
v-for="(item, index) in recordList"
|
||||
:key="index"
|
||||
>
|
||||
<el-card>
|
||||
<h4></h4>
|
||||
<div>
|
||||
<div v-if="index == recordList.length - 1">
|
||||
<!-- 初审 -->
|
||||
<el-tag>Under review</el-tag>
|
||||
<p style="margin-top: 10px">
|
||||
Comments:
|
||||
<el-button
|
||||
style="margin-left: 10px"
|
||||
type="text"
|
||||
@click="showUnderReview(item)"
|
||||
icon="el-icon-view"
|
||||
>Details</el-button
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
<div v-else>
|
||||
<!-- 复审 -->
|
||||
<el-tag type="success">Second review</el-tag>
|
||||
<p style="margin-top: 10px">
|
||||
Comments:
|
||||
<el-button
|
||||
style="margin-left: 10px"
|
||||
type="text"
|
||||
@click="showSecondReview(item)"
|
||||
icon="el-icon-view"
|
||||
>Details</el-button
|
||||
>
|
||||
</p>
|
||||
<p v-if="item.stime > 0" style="" class="stime">
|
||||
Response time: {{ item.stime | formatDatehms }}
|
||||
</p>
|
||||
<p v-else style="" class="stime">Response time: Re-reviewing...</p>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<common-review-article v-if="type=='question'"
|
||||
type="undeQuestion"
|
||||
pagetype="Editor"
|
||||
:form="undeQuestion"
|
||||
:txt_mess="txt_mess"
|
||||
:btn_submit="1"
|
||||
:articleId="articleId"
|
||||
:journal_id="journal_id"
|
||||
></common-review-article>
|
||||
|
||||
<!-- <el-dialog title="Second review questionnaire" :visible.sync="FdialogFormVisible" width="900px" @close="closeSecDia" :close-on-click-modal="false"> -->
|
||||
<el-form :model="ReReviewQuestion" ref="question" label-width="300px" label-position="top">
|
||||
<el-divider content-position="center">REFEREE'S RECOMMENDATIONS</el-divider>
|
||||
<el-form-item label="REFEREE'S RECOMMENDATIONS" prop="recommend">
|
||||
<el-radio-group v-model="ReReviewQuestion.recommend" style="line-height: 30px">
|
||||
<el-radio :label="1" :disabled="ReReviewQuestion.recommend != 1">Accept</el-radio>
|
||||
<el-radio :label="2" :disabled="ReReviewQuestion.recommend != 2">Reject</el-radio>
|
||||
<!-- 退修改20251119 -->
|
||||
<el-radio :label="3" :disabled="ReReviewQuestion.recommend != 3">Revison</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="Confidential Comments to the Editor" v-if="ReReviewQuestion.recommend == 3">
|
||||
<el-input
|
||||
readonly
|
||||
type="textarea"
|
||||
placeholder="please input content"
|
||||
v-model="ReReviewQuestion.content"
|
||||
:rows="8"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!-- </el-dialog> -->
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="" @click="reviewerVisible = false">Cancal</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
reviewerDetail: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
type:'',
|
||||
|
||||
reviewerVisible: false,
|
||||
FdialogFormVisible: false,
|
||||
dialogFormVisible1: false,
|
||||
recordList: [],
|
||||
reviewList: [],
|
||||
journal_id: null,
|
||||
baseUrl: this.Common.baseUrl,
|
||||
mediaUrl: this.Common.mediaUrl,
|
||||
articleId: this.$route.query.id,
|
||||
dateId: '',
|
||||
username: localStorage.getItem('U_name'),
|
||||
articlefileList: [],
|
||||
articlezipList: [],
|
||||
dialogFormVisible: false,
|
||||
activeNames: ['1', '2', '3', '4', '5', '6', '7'],
|
||||
detailDate: {},
|
||||
txt_mess: {},
|
||||
questionform: { },
|
||||
canRepeat: null,
|
||||
undeQuestion: {},
|
||||
ReReviewQuestion: {}
|
||||
};
|
||||
},
|
||||
created: function () {
|
||||
console.log('this.reviewerDetail at line 971:', this.reviewerDetail.art_rev_id);
|
||||
},
|
||||
|
||||
computed: {},
|
||||
methods: {
|
||||
init(art_rev_id,type) {
|
||||
this.type=type;
|
||||
if (art_rev_id) {
|
||||
this.dateId = art_rev_id;
|
||||
this.detailDate = {
|
||||
editor: localStorage.getItem('U_name'),
|
||||
artrevid: art_rev_id,
|
||||
article: '',
|
||||
reviewer: '',
|
||||
reviewer_email: '',
|
||||
articlefile: '',
|
||||
articlezip: '',
|
||||
ctime: '',
|
||||
state: ''
|
||||
};
|
||||
if(type=='detail'){
|
||||
this.getDate();
|
||||
}
|
||||
if(type=='question'){
|
||||
this. questionform={}
|
||||
|
||||
this.initquesion();
|
||||
}
|
||||
this.$api
|
||||
.post('api/Workbench/updateArticleState', {
|
||||
article_id: this.articleId,
|
||||
act_p_id: art_rev_id,
|
||||
type: '1,2',
|
||||
account: localStorage.getItem('U_name')
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
},
|
||||
maxRepeatReviewCount() {
|
||||
if (!this.reviewList || !Array.isArray(this.reviewList)) return null; // 边界处理:无数据返回null
|
||||
|
||||
// 遍历所有评审者,找到repeat数组长度最大的那条数据
|
||||
const maxItem = this.reviewList.reduce((maxItem, currentItem) => {
|
||||
// 计算当前项的repeat长度,非数组则视为0
|
||||
const currentLen = Array.isArray(currentItem.repeat) ? currentItem.repeat.length : 0;
|
||||
// 计算当前最大项的repeat长度,非数组则视为0
|
||||
const maxLen = Array.isArray(maxItem.repeat) ? maxItem.repeat.length : 0;
|
||||
|
||||
// 如果当前项长度更大,则更新最大项
|
||||
return currentLen > maxLen ? currentItem : maxItem;
|
||||
}, {}); // 初始值设为一个空对象
|
||||
// console.log('maxItem at line 2142:', maxItem.repeat.length)
|
||||
return maxItem && maxItem.repeat ? maxItem.repeat.length : 0;
|
||||
},
|
||||
|
||||
// 显示复审对话框
|
||||
showSecondReview(item) {
|
||||
this.FdialogFormVisible = true;
|
||||
this.ReReviewQuestion = item;
|
||||
},
|
||||
// 显示初审对话框
|
||||
showUnderReview(item) {
|
||||
// this.dialogFormVisible1 = true;
|
||||
this.undeQuestion = { ...item };
|
||||
this.undeQuestion.qu9 = item.qu9 == 0 ? false : true;
|
||||
this.undeQuestion.qu9contents = item.qu9_contents;
|
||||
this.undeQuestion.qu10 = item.qu10 == 0 ? false : true;
|
||||
this.undeQuestion.qu10contents = item.qu10_contents;
|
||||
this.undeQuestion.qu11 = item.qu11 == 0 ? false : true;
|
||||
this.undeQuestion.qu11contents = item.qu11_contents;
|
||||
this.undeQuestion.qu12 = item.qu12 == 0 ? false : true;
|
||||
this.undeQuestion.qu12contents = item.qu12_contents;
|
||||
this.undeQuestion.qu13 = item.qu13 == 0 ? false : true;
|
||||
this.undeQuestion.qu13contents = item.qu13_contents;
|
||||
this.undeQuestion.qu14 = item.qu14 == 0 ? false : true;
|
||||
this.undeQuestion.qu14contents = item.qu14_contents;
|
||||
this.undeQuestion.qu15 = item.qu15 == 0 ? false : true;
|
||||
this.undeQuestion.qu15contents = item.qu15_contents;
|
||||
this.undeQuestion.confident = item.confidential;
|
||||
this.undeQuestion.comment = item.comments;
|
||||
},
|
||||
// 关闭初审对话框
|
||||
closeUnderDia() {
|
||||
this.dialogFormVisible1 = false;
|
||||
this.undeQuestion = {};
|
||||
},
|
||||
closeSecDia() {
|
||||
this.FdialogFormVisible = false;
|
||||
this.ReReviewQuestion = {};
|
||||
},
|
||||
// 2. 定义所有必需字段(确保所有数据结构统一)
|
||||
|
||||
// 3. 核心函数:提取第一个元素,剩余放入 repeat
|
||||
splitQuestion(questionArr = []) {
|
||||
const requiredFields = [
|
||||
'rev_qu_id',
|
||||
'art_rev_id',
|
||||
'type',
|
||||
'art_rev_rep_id',
|
||||
'recommend',
|
||||
'score',
|
||||
'state',
|
||||
'reviewer_id',
|
||||
'realname',
|
||||
'ctime',
|
||||
'stime',
|
||||
'is_anonymous'
|
||||
];
|
||||
// 解构数组:firstItem 取第一个元素,restItems 取剩余所有元素
|
||||
const [firstItem = {}, ...restItems] = questionArr;
|
||||
|
||||
// 工具函数:补全单个对象的必需字段(空值用 null 填充)
|
||||
const completeFields = (item) => {
|
||||
console.log('item at line 1056:', item);
|
||||
const result = { question: item };
|
||||
requiredFields.forEach((field) => {
|
||||
result[field] = item[field] ? item[field] : '';
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
// 补全第一个元素的字段
|
||||
const firstCompleted = completeFields(firstItem);
|
||||
|
||||
// 补全剩余元素的字段,存入 repeat 数组
|
||||
const repeat = restItems.map((item) => completeFields(item));
|
||||
|
||||
// 返回结果:按需选择格式(二选一)
|
||||
return { ...firstCompleted, repeat: repeat };
|
||||
},
|
||||
|
||||
// 创建复审实例
|
||||
createRevision() {
|
||||
this.$api
|
||||
.post('api/Reviewer/startRepeatReviewer', {
|
||||
art_rev_id: this.detailDate.artrevid
|
||||
})
|
||||
.then((res) => {
|
||||
//console.log(res)
|
||||
if (res.code == 0) {
|
||||
this.$message.success('A review invitation was successfully sent!');
|
||||
this.getdate();
|
||||
} else {
|
||||
this.$message.error(res.msg);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
},
|
||||
upload_file(type) {
|
||||
return this.baseUrl + 'api/reviewer/up_file/type/' + type;
|
||||
},
|
||||
onSubmit() {
|
||||
if (this.detailDate.articlefile == '') {
|
||||
this.$message.error('you must upload article file');
|
||||
console.log('file up error');
|
||||
return false;
|
||||
}
|
||||
this.$api
|
||||
.post('api/Reviewer/articleReviewerUpSubmit/type/editor', this.detailDate)
|
||||
.then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('success');
|
||||
this.$router.go(0);
|
||||
} else {
|
||||
this.$message.error('Failed to submit, please contact administrator!');
|
||||
console.log(res.msg);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
},
|
||||
//初始化详情信息
|
||||
getDate() {
|
||||
const loading = this.$loading({
|
||||
lock: true,
|
||||
text: 'Loading...',
|
||||
spinner: 'el-icon-loading',
|
||||
background: 'rgba(0, 0, 0, 0.7)'
|
||||
});
|
||||
this.$api
|
||||
.post('api/Reviewer/getartrevdate', {
|
||||
revid: this.dateId,
|
||||
human: 'editor'
|
||||
})
|
||||
.then((res) => {
|
||||
this.detailDate.artrevid = res.art_rev_id;
|
||||
this.detailDate.article = res.article_title;
|
||||
this.detailDate.reviewer = res.account;
|
||||
this.detailDate.reviewer_email = res.user_email;
|
||||
this.detailDate.ctime = res.ctime;
|
||||
this.detailDate.state = res.state;
|
||||
|
||||
this.txt_mess = res;
|
||||
this.canRepeat = res.can_repeat;
|
||||
this.journal_id = res.journal_id;
|
||||
this.articleId = res.article_id;
|
||||
loading.close();
|
||||
this.reviewerVisible = true;
|
||||
})
|
||||
.catch((err) => {
|
||||
loading.close();
|
||||
console.log(err);
|
||||
});
|
||||
},
|
||||
|
||||
//初始化问卷
|
||||
initquesion() {
|
||||
const loading = this.$loading({
|
||||
lock: true,
|
||||
text: 'Loading...',
|
||||
spinner: 'el-icon-loading',
|
||||
background: 'rgba(0, 0, 0, 0.7)'
|
||||
});
|
||||
this.$api
|
||||
.post('api/Reviewer/getQuestion', {
|
||||
artrevid: this.dateId
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.showUnderReview(res.data)
|
||||
this.reviewerVisible = true;
|
||||
loading.close();
|
||||
}
|
||||
}).catch((err) => {
|
||||
loading.close();
|
||||
console.log(err);
|
||||
});
|
||||
},
|
||||
//检验上传文件的格式
|
||||
beforeupload_file(file) {
|
||||
// const isWORd =
|
||||
// file.type === 'application/msword' ||
|
||||
// file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
|
||||
// if (!isWORd) {
|
||||
// this.$message.error('Only word files can be uploaded(.doc,.docx)');
|
||||
// }
|
||||
// return isWORd;
|
||||
},
|
||||
beforeupload_articlezip(file) {
|
||||
// const iszip = file.type === 'application/x-zip-compressed' || file.name.split('.')[1] === 'rar';
|
||||
// if (!iszip) {
|
||||
// this.$message.error('Only compressed files can be uploaded(.rar,.zip)');
|
||||
// }
|
||||
// return iszip;
|
||||
},
|
||||
getlinkurl(row) {
|
||||
return this.mediaUrl + row.file_url;
|
||||
},
|
||||
filedateformate(row, column, cellValue, index) {
|
||||
return this.formatDate(cellValue);
|
||||
},
|
||||
uperr_file(err) {
|
||||
this.$message.error('上传失败');
|
||||
},
|
||||
beforeupload() {},
|
||||
upSuccess_file(res, file) {
|
||||
if (res.code == 0) {
|
||||
this.detailDate.articlefile = 'articlefile/' + res.upurl;
|
||||
} else {
|
||||
this.$message.error('服务器上传错误:' + res.msg);
|
||||
}
|
||||
},
|
||||
upSuccess_articlezip(res, file) {
|
||||
if (res.code == 0) {
|
||||
this.detailDate.articlezip = 'articlezip/' + res.upurl;
|
||||
} else {
|
||||
this.$message.error('服务器上传错误:' + res.msg);
|
||||
}
|
||||
},
|
||||
handleClick(item) {
|
||||
console.log('item at line 1228:', item);
|
||||
this.$router.push({
|
||||
path: 'articleReviewerDetail',
|
||||
query: {
|
||||
id: item.art_rev_id
|
||||
}
|
||||
});
|
||||
},
|
||||
formatDate(timestamp) {
|
||||
var date = new Date(timestamp * 1000); //时间戳为10位需*1000,时间戳为13位的话不需乘1000
|
||||
var Y = date.getFullYear() + '-';
|
||||
var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
|
||||
var D = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
|
||||
var h = date.getHours() < 10 ? '0' + date.getHours() : date.getHours();
|
||||
var m = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes();
|
||||
var s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();
|
||||
return Y + M + D + ' ' + h + ':' + m + ':' + s;
|
||||
},
|
||||
//超出传送文件个数限制
|
||||
alertlimit() {
|
||||
this.$message.error('超过最大上传文件个数');
|
||||
},
|
||||
//清除文件时的事件
|
||||
removefilearticlefile(file, fileList) {
|
||||
this.detailDate.articlefile = '';
|
||||
},
|
||||
removefilearticlezip(file, fileList) {
|
||||
this.detailDate.articlezip = '';
|
||||
},
|
||||
mystate(mystate) {
|
||||
let str = '';
|
||||
switch (mystate) {
|
||||
case 0:
|
||||
str = 'With reviewer';
|
||||
break;
|
||||
case 1:
|
||||
str = 'Major';
|
||||
break;
|
||||
case 2:
|
||||
str = 'Reject';
|
||||
break;
|
||||
case 3:
|
||||
// str = 'Accept';
|
||||
str = 'Minor';
|
||||
break;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.fsheader {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.dwnbtn {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.container {
|
||||
min-width: 1000px;
|
||||
}
|
||||
|
||||
.tree_box {
|
||||
padding: 15px 10px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
::v-deep .el-dialog__body {
|
||||
padding: 10px 20px 20px !important;
|
||||
}
|
||||
.review_table {
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
/* margin-top: 10px; */
|
||||
border-collapse: collapse; /* 合并表格边框 */
|
||||
}
|
||||
|
||||
.review_table th,
|
||||
td {
|
||||
padding: 6px;
|
||||
min-width: 70px;
|
||||
border: 1px solid #ddd;
|
||||
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.review_table th {
|
||||
font-size: 14px;
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
.review_table td {
|
||||
font-size: 14px;
|
||||
/* background-color: #f0f0f0; */
|
||||
}
|
||||
.review_table th:first-child,
|
||||
.review_table td:first-child {
|
||||
width: 100px;
|
||||
/* 内容过长时自动换行 */
|
||||
word-wrap: break-word;
|
||||
/* 强制在单词内换行(针对长单词) */
|
||||
word-break: break-all;
|
||||
}
|
||||
.review_table tr:hover {
|
||||
/* background-color: #fff; */
|
||||
}
|
||||
.overflow-x-auto {
|
||||
overflow-x: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -25,7 +25,7 @@
|
||||
border-bottom: 2px solid #c7cdcf;
|
||||
background-color: #fff;
|
||||
position: fixed;
|
||||
top: 60px;
|
||||
top: 40px;
|
||||
left: 285px;
|
||||
z-index: 10;
|
||||
right: 330px;
|
||||
|
||||
Reference in New Issue
Block a user