Files
tougao_web/src/components/page/components/articleDetail/reviewerdetail.vue

580 lines
21 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>
<el-dialog title="" :visible.sync="reviewerVisible" width="1200px" :close-on-click-modal="false">
<template slot="title" >
<div class="dialog-title">
<p v-if="type=='detail'">Manuscript reviewer detail</p>
<p v-else>Feedback questionnaire
<span style="margin-top: -3px;"> <span v-if="time" class="time">Time{{ formatDate(time) }}</span>
<span v-if="stime" class="time">Response time {{ formatDate(stime) }}</span></span>
</p>
</div>
</template>
<div>
<div class="" v-if="type=='detail'">
<el-row :gutter="10">
<el-col :span="24">
<div class="form-box" style="width: 100%">
<el-form ref="articleform" :model="detailDate" label-width="140px">
<el-form-item label="Title">
<span style="font-weight: bold;color: #333;">{{ 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="detailDate.is_anonymous == 0">Disclose name</span>
<span v-if="detailDate.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-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-form :model="ReReviewQuestion" ref="question" label-width="300px" label-position="top" v-if="type=='re-review'">
<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: {},
repeatItem: {},
time:"",//审稿时间
stime:"",//复审回复时间
};
},
created: function () {
console.log('this.reviewerDetail at line 971:', this.reviewerDetail.art_rev_id);
},
computed: {},
methods: {
init(art_rev_id,type,repeatItem) {
this.time="";
this.stime="";
this.type=type;
this.repeatItem=repeatItem
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();
}
if(type=='re-review'){
this. ReReviewQuestion={}
this.initReReviewQuestion();
}
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/Workbench/getArticleReviewDetail', {
article_id:this.$route.query.id,
art_rev_id:this.dateId ,
account: localStorage.getItem('U_name')
})
.then((res) => {
if(res.status == 1){
this.detailDate.artrevid = res.data.article_reviewer.art_rev_id;
this.detailDate.article = res.data.article.title;
this.detailDate.reviewer = res.data.article_reviewer.realname;
this.detailDate.reviewer_email = res.data.article_reviewer.email;
this.detailDate.ctime = res.data.article_reviewer.ctime;
this.detailDate.is_anonymous = res.data.article_reviewer.is_anonymous;
this.articleId = res.data.article.article_id;
loading.close();
this.reviewerVisible = true;
}else{
loading.close();
this.$message.error(res.msg);
return false;
}
})
.catch((err) => {
loading.close();
console.log(err);
});
},
initReReviewQuestion() {
console.log('this.repeatItem at line 335:', this.repeatItem)
const loading = this.$loading({
lock: true,
text: 'Loading...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
this.$api.post('api/Workbench/getArticleReviewDetail', {
article_id:this.$route.query.id,
art_rev_id:this.dateId,
art_rev_rep_id:this.repeatItem.art_rev_rep_id,
account: localStorage.getItem('U_name')
})
.then((res) => {
if(res.status==1){
this.time=res.data.article_reviewer_repeat.ctime;
this.stime=res.data.article_reviewer_repeat.stime;
this.ReReviewQuestion = res.data.article_reviewer_repeat;
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.time=res.data.ctime;
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;
}
.dialog-title {
width: 100%;
line-height: 24px;
font-size: 18px;
color: #303133;
}
.dialog-title p{
width:calc(100% - 30px);
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.time{
color: #888;line-height: 20px;
font-size: 14px;
margin-left: 20px;
display: inline-block
}
</style>