486 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Plaintext
		
	
	
			
		
		
	
	
			486 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Plaintext
		
	
	
| <template>
 | ||
|   <div class="glReview_wrapper">
 | ||
|     <!--    <el-card v-if="isReadingShowSubjectInfo" shadow="never" :body-style="{ padding: '10px' }" style="margin-bottom:10px">-->
 | ||
|     <!--      <h4>-->
 | ||
|     <!--        <!– 受试者: –>-->
 | ||
|     <!--        {{ $t('trials:globalReview:title:subject') }}-->
 | ||
|     <!--        <span style="font-weight:normal">{{ subjectCode }} </span>-->
 | ||
|     <!--        <span style="font-weight:normal">({{ taskBlindName }})</span>-->
 | ||
|     <!--      </h4>-->
 | ||
|     <!--    </el-card>-->
 | ||
| 
 | ||
|     <el-card v-loading="loading" :body-style="{ padding: '10px' }" shadow="never">
 | ||
|       <div slot="header" style="display: flex;flex-direction: row;justify-content: space-between;">
 | ||
|         <!-- 访视评估结果 -->
 | ||
|         <div style="font-weight: bold;">
 | ||
|           {{ $t('trials:globalReview:title:result') }}
 | ||
|           <span v-if="isReadingShowSubjectInfo">
 | ||
|             ({{ subjectCode }} | {{ taskBlindName }})
 | ||
|           </span>
 | ||
|         </div>
 | ||
|         <div v-if="isExistsClinicalData">
 | ||
|           <!-- 临床数据 -->
 | ||
|           <el-button type="text" @click="previewCD">{{ $t('trials:globalReview:title:clinicalData') }}</el-button>
 | ||
|         </div>
 | ||
|       </div>
 | ||
| 
 | ||
|       <div v-if=" readingTaskState < 2" style="text-align:right;margin:5px 0;">
 | ||
| 
 | ||
|         <el-button size="small" type="primary" @click="handleSave">
 | ||
|           {{ $t('common:button:save') }}
 | ||
|         </el-button>
 | ||
|         <!-- 提交 -->
 | ||
|         <el-button size="small" type="primary" @click="handleConfirm">
 | ||
|           {{ $t('trials:globalReview:button:submit') }}
 | ||
|         </el-button>
 | ||
|       </div>
 | ||
|       <RecistTable
 | ||
|         v-if="(CriterionType === 1 || CriterionType === 0) && Object.keys(globalInfo).length !== 0"
 | ||
|         ref="globalTbl"
 | ||
|         :global-info="globalInfo"
 | ||
|         :global-form="globalInfo.globalForm"
 | ||
|         :reading-task-state="readingTaskState"
 | ||
|         @getGlInfo="getGlInfo"
 | ||
|         @setOpenWindow="setOpenWindow"
 | ||
|       />
 | ||
|       <PCWG3Table
 | ||
|         v-if="CriterionType === 10 && Object.keys(globalInfo).length !== 0"
 | ||
|         ref="globalTbl"
 | ||
|         :global-info="globalInfo"
 | ||
|         :global-form="globalInfo.globalForm"
 | ||
|         :reading-task-state="readingTaskState"
 | ||
|         @getGlInfo="getGlInfo"
 | ||
|         @handleView="handleView"
 | ||
|         @setOpenWindow="setOpenWindow"
 | ||
|       />
 | ||
|       <IRecistTable
 | ||
|         v-if="CriterionType === 3 && Object.keys(globalInfo).length !== 0"
 | ||
|         ref="globalTbl"
 | ||
|         :global-info="globalInfo"
 | ||
|         :global-form="globalInfo.globalForm"
 | ||
|         :reading-task-state="readingTaskState"
 | ||
|         @getGlInfo="getGlInfo"
 | ||
|         @setOpenWindow="setOpenWindow"
 | ||
|       />
 | ||
|       <RecistBMTable
 | ||
|         v-if="CriterionType === 17 && Object.keys(globalInfo).length !== 0"
 | ||
|         ref="globalTbl"
 | ||
|         :global-info="globalInfo"
 | ||
|         :global-form="globalInfo.globalForm"
 | ||
|         :reading-task-state="readingTaskState"
 | ||
|         @getGlInfo="getGlInfo"
 | ||
|         @setOpenWindow="setOpenWindow"
 | ||
|       />
 | ||
| 
 | ||
|     </el-card>
 | ||
| 
 | ||
|     <el-card v-if="isReadingShowPreviousResults" :body-style="{ padding: '10px' }" shadow="never">
 | ||
|       <div slot="header" class="clearfix">
 | ||
|         <!-- 既往全局阅片结果 -->
 | ||
|         <span style="font-weight: bold;">{{ $t('trials:globalReview:title:previousRes') }}</span>
 | ||
|       </div>
 | ||
|       <el-table
 | ||
|         v-loading="historyLoading"
 | ||
|         :data="historyTaskList"
 | ||
|       >
 | ||
|         <!-- 全局 -->
 | ||
|         <el-table-column
 | ||
|           prop="TaskBlindName"
 | ||
|           :label="$t('trials:globalReview:table:globalReading')"
 | ||
|           show-overflow-tooltip
 | ||
|           width="200"
 | ||
|         />
 | ||
|         <el-table-column
 | ||
|           :label="$t('common:action:action')"
 | ||
|           width="200"
 | ||
|         >
 | ||
|           <template slot-scope="scope">
 | ||
|             <!-- 查看详情 -->
 | ||
|             <el-button
 | ||
|               circle
 | ||
|               :title="$t('trials:globalReview:table:view')"
 | ||
|               icon="el-icon-view"
 | ||
|               @click="handleView(scope.row)"
 | ||
|             />
 | ||
|           </template>
 | ||
|         </el-table-column>
 | ||
|       </el-table>
 | ||
|     </el-card>
 | ||
| 
 | ||
|     <!-- 签名框 -->
 | ||
|     <el-dialog
 | ||
|       v-if="signVisible"
 | ||
|       :visible.sync="signVisible"
 | ||
|       :close-on-click-modal="false"
 | ||
|       width="600px"
 | ||
|       custom-class="base-dialog-wrapper"
 | ||
|     >
 | ||
|       <div slot="title">
 | ||
|         <span style="font-size:18px;">{{ $t('common:dialogTitle:sign') }}</span>
 | ||
|         <span style="font-size:12px;margin-left:5px">{{ `(${$t('common:label:sign')}${ currentUser })` }}</span>
 | ||
|       </div>
 | ||
|       <SignForm ref="signForm" :sign-code-enum="signCode" @closeDialog="closeSignDialog" />
 | ||
|     </el-dialog>
 | ||
|   </div>
 | ||
| </template>
 | ||
| <script>
 | ||
| import { getGlobalReadingInfo, getReadingPastResultList, submitGlobalReadingInfo, saveGlobalReadingInfo } from '@/api/trials'
 | ||
| import { getAutoCutNextTask } from '@/api/user'
 | ||
| import { getToken } from '@/utils/auth'
 | ||
| import const_ from '@/const/sign-code'
 | ||
| import DicomEvent from '@/views/trials/trials-panel/reading/dicoms/components/DicomEvent'
 | ||
| import RecistTable from './components/RecistTable'
 | ||
| import PCWG3Table from './components/PCWG3Table'
 | ||
| import IRecistTable from './components/IRecistTable'
 | ||
| import RecistBMTable from './components/RecistBMTable'
 | ||
| import SignForm from '@/views/trials/components/newSignForm'
 | ||
| import { changeURLStatic } from '@/utils/history.js'
 | ||
| import store from '@/store'
 | ||
| export default {
 | ||
|   name: 'GlobalReview',
 | ||
|   components: { RecistTable, PCWG3Table, IRecistTable, RecistBMTable, SignForm },
 | ||
|   props: {
 | ||
|     trialId: {
 | ||
|       type: String,
 | ||
|       required: true
 | ||
|     },
 | ||
|     subjectId: {
 | ||
|       type: String,
 | ||
|       required: true
 | ||
|     },
 | ||
|     visitTaskId: {
 | ||
|       type: String,
 | ||
|       required: true
 | ||
|     },
 | ||
|     readingCategory: {
 | ||
|       type: Number,
 | ||
|       required: true
 | ||
|     },
 | ||
|     subjectCode: {
 | ||
|       type: String,
 | ||
|       required: true
 | ||
|     },
 | ||
|     taskBlindName: {
 | ||
|       type: String,
 | ||
|       required: true
 | ||
|     },
 | ||
|     isReadingShowSubjectInfo: {
 | ||
|       type: Boolean,
 | ||
|       required: true
 | ||
|     },
 | ||
|     isReadingShowPreviousResults: {
 | ||
|       type: Boolean,
 | ||
|       required: true
 | ||
|     },
 | ||
|     isExistsClinicalData: {
 | ||
|       type: Boolean,
 | ||
|       required: true
 | ||
|     }
 | ||
|   },
 | ||
|   data() {
 | ||
|     return {
 | ||
|       loading: false,
 | ||
|       maxLength: 2,
 | ||
|       evaluationQsList: [],
 | ||
|       adjustedQsList: [],
 | ||
|       agreeOrNotList: [],
 | ||
|       taskList: [],
 | ||
|       historyLoading: false,
 | ||
|       historyTaskList: [],
 | ||
|       currentUser: zzSessionStorage.getItem('userName'),
 | ||
|       signVisible: false,
 | ||
|       signCode: null,
 | ||
|       rowData: {},
 | ||
|       readingTaskState: 0,
 | ||
|       globalUpdateType: [],
 | ||
|       assessTypeList: [],
 | ||
|       CriterionType: 0,
 | ||
|       globalInfo: {},
 | ||
|       openWindow: null
 | ||
|     }
 | ||
|   },
 | ||
|   // watch: {
 | ||
|   //   visitTaskId: {
 | ||
|   //     immediate: true,
 | ||
|   //     handler(val) {
 | ||
|   //       this.$nextTick(() => {
 | ||
|   //         this.getGlInfo()
 | ||
|   //         if (this.isReadingShowPreviousResults) {
 | ||
|   //           this.getHistoryGlobalInfo()
 | ||
|   //         }
 | ||
|   //       })
 | ||
|   //     }
 | ||
|   //   }
 | ||
|   // },
 | ||
|   mounted() {
 | ||
|     this.CriterionType = parseInt(this.$route.query.criterionType)
 | ||
|     this.getGlInfo()
 | ||
|     if (this.isReadingShowPreviousResults) {
 | ||
|       this.getHistoryGlobalInfo()
 | ||
|     }
 | ||
|     DicomEvent.$on('resetOpenWindow', () => {
 | ||
|       if (this.openWindow) {
 | ||
|         this.openWindow.close()
 | ||
|       }
 | ||
|     })
 | ||
|   },
 | ||
|   beforeDestroy() {
 | ||
|     DicomEvent.$off('resetOpenWindow')
 | ||
|     if (this.openWindow) {
 | ||
|       this.openWindow.close()
 | ||
|     }
 | ||
|   },
 | ||
|   methods: {
 | ||
|     getGlInfo() {
 | ||
|       this.loading = true
 | ||
|       getGlobalReadingInfo({ visitTaskId: this.visitTaskId }).then(res => {
 | ||
|         var evaluationQsList = []
 | ||
|         var adjustedQsList = []
 | ||
|         var agreeOrNotList = []
 | ||
|         var globalForm = {}
 | ||
|         if (res.Result.TaskList.length > 0) {
 | ||
|           res.Result.TaskList.map((qs, index) => {
 | ||
|             if (index === 0) {
 | ||
|               qs.BeforeQuestionList.map(qs => {
 | ||
|                 evaluationQsList.push(qs.QuestionName)
 | ||
|               })
 | ||
|               qs.AfterQuestionList.map(qs => {
 | ||
|                 if (qs.GlobalAnswerType === 1 && (this.CriterionType === 10)) {
 | ||
|                   // 访视阅片备注
 | ||
|                   adjustedQsList.push(this.$t('trials:globalReview:table:visitRemark'))
 | ||
|                 } else if (qs.GlobalAnswerType === 1 && (this.CriterionType === 1 || this.CriterionType === 3 || this.CriterionType === 17 || this.CriterionType === 0)) {
 | ||
|                   // 全局阅片备注
 | ||
|                   adjustedQsList.push(this.$t('trials:globalReview:table:globalRemark'))
 | ||
|                 } else if (qs.GlobalAnswerType === 3 && (this.CriterionType === 1 || this.CriterionType === 3 || this.CriterionType === 17 || this.CriterionType === 0)) {
 | ||
|                   // 评估更新类型
 | ||
|                   adjustedQsList.push(this.$t('trials:globalReview:table:updateType'))
 | ||
|                 } else {
 | ||
|                   adjustedQsList.push(qs.QuestionName)
 | ||
|                 }
 | ||
|               })
 | ||
|               qs.AgreeOrNot.map(qs => {
 | ||
|                 agreeOrNotList.push(qs.QuestionName)
 | ||
|               })
 | ||
|             }
 | ||
|             qs.AfterQuestionList.map(q => {
 | ||
|               if (q.Answer !== q.VisitAnswer) {
 | ||
|                 this.$set(q, 'isChange', true)
 | ||
|               }
 | ||
|               var answer = ''
 | ||
|               if (q.DictionaryCode) {
 | ||
|                 answer = q.Answer
 | ||
|               } else {
 | ||
|                 answer = q.Answer
 | ||
|               }
 | ||
|               if (!q.QuestionId) {
 | ||
|                 this.$set(globalForm, `${index}${q.GlobalAnswerType}`, answer)
 | ||
|               } else {
 | ||
|                 this.$set(globalForm, `${index}${q.QuestionId}`, answer)
 | ||
|               }
 | ||
|             })
 | ||
|             if (this.CriterionType === 1 || this.CriterionType === 3 || this.CriterionType === 17 || this.CriterionType === 0) {
 | ||
|               this.$set(globalForm, `${index}${qs.AgreeOrNot[0].GlobalAnswerType}`, qs.AgreeOrNot[0].Answer)
 | ||
|             }
 | ||
|           })
 | ||
|         }
 | ||
|         var globalUpdateType = res.Result.GlobalUpdateType ? res.Result.GlobalUpdateType.split('|') : []
 | ||
| 
 | ||
|         this.readingTaskState = res.Result.ReadingTaskState
 | ||
|         globalForm.taskList = res.Result.TaskList
 | ||
|         this.globalInfo = {
 | ||
|           trialId: this.trialId, subjectId: this.subjectId, subjectCode: this.subjectCode, visitTaskId: res.Result.GlobalTaskId, globalForm, globalUpdateType, evaluationQsList, adjustedQsList, agreeOrNotList, readingTaskState: this.readingTaskState, assessTypeList: res.Result.AssessTypeList
 | ||
|         }
 | ||
|         this.loading = false
 | ||
|       }).catch(() => { this.loading = false })
 | ||
|     },
 | ||
|     getHistoryGlobalInfo() {
 | ||
|       this.historyLoading = true
 | ||
|       getReadingPastResultList({ visitTaskId: this.visitTaskId }).then(res => {
 | ||
|         this.historyTaskList = res.Result
 | ||
|         this.historyLoading = false
 | ||
|       }).catch(() => { this.historyLoading = false })
 | ||
|     },
 | ||
|     changeAgreeOrNotList(callback, row, visitTaskId) {
 | ||
|       var message = ''
 | ||
|       if (parseInt(callback) === 1) {
 | ||
|         message = '是否确认更改?'
 | ||
|         row.Answer = '0'
 | ||
|       } else {
 | ||
|         message = '是否确认更改?'
 | ||
|         row.Answer = '1'
 | ||
|       }
 | ||
|       this.$confirm(message, {
 | ||
|         distinguishCancelAndClose: true,
 | ||
|         type: 'warning'
 | ||
|       }).then(() => {
 | ||
|         this.loading = true
 | ||
|         var params = {
 | ||
|           globalTaskId: this.visitTaskId,
 | ||
|           subjectId: this.subjectId,
 | ||
|           trialId: this.trialId,
 | ||
|           questionList: [
 | ||
|             {
 | ||
|               questionId: row.QuestionId ? row.QuestionId : '',
 | ||
|               visitTaskId: visitTaskId,
 | ||
|               globalAnswerType: row.GlobalAnswerType,
 | ||
|               answer: row.Answer === '1' ? '0' : '1'
 | ||
|             }
 | ||
|           ]
 | ||
|         }
 | ||
|         saveGlobalReadingInfo(params).then(res => {
 | ||
|           this.loading = false
 | ||
|           if (res.IsSuccess) {
 | ||
|             this.$message.success('保存成功!')
 | ||
|             this.getGlInfo()
 | ||
|           }
 | ||
|         }).catch(() => { this.loading = false })
 | ||
|       }).catch(() => {})
 | ||
|     },
 | ||
|     // handleEdit(row) {
 | ||
|     //   this.rowData = { ...row }
 | ||
|     //   if (this.CriterionType === 1) {
 | ||
|     //     this.rowData.AfterQuestionList.forEach(item => {
 | ||
|     //       if (item.GlobalAnswerType === 1) {
 | ||
|     //         // 全局阅片备注
 | ||
|     //         item.QuestionName = this.$t('trials:globalReview:table:globalRemark')
 | ||
|     //       } else if (item.GlobalAnswerType === 3) {
 | ||
|     //         // 评估更新类型
 | ||
|     //         item.QuestionName = this.$t('trials:globalReview:table:updateType')
 | ||
|     //       }
 | ||
|     //     })
 | ||
|     //   }
 | ||
|     //   // this.editVisible = true
 | ||
|     // },
 | ||
|     handleSave() {
 | ||
|       this.$refs['globalTbl'].handleSave(true)
 | ||
|     },
 | ||
|     async handleConfirm() {
 | ||
|       // 判断是否存在访视评估结果未确认
 | ||
|       var idx = this.taskList.findIndex(i => !i.AgreeOrNotAnswer)
 | ||
|       if (idx > -1) {
 | ||
|         // 存在访视评估结果未确认!
 | ||
|         this.$confirm(this.$t('trials:globalReview:message:msg1'), {
 | ||
|           type: 'warning',
 | ||
|           distinguishCancelAndClose: true
 | ||
|         })
 | ||
|           .then(() => {})
 | ||
|           .catch(() => {})
 | ||
|       } else {
 | ||
|         // 自动保存
 | ||
|         await this.$refs['globalTbl'].handleSave(false)
 | ||
|         const { ImageAssessmentReportConfirmation } = const_.processSignature
 | ||
|         this.signCode = ImageAssessmentReportConfirmation
 | ||
|         this.signVisible = true
 | ||
|       }
 | ||
|     },
 | ||
|     // 关闭签名框
 | ||
|     closeSignDialog(isSign, signInfo) {
 | ||
|       if (isSign) {
 | ||
|         this.signConfirm(signInfo)
 | ||
|       } else {
 | ||
|         this.signVisible = false
 | ||
|       }
 | ||
|     },
 | ||
|     // 签名并确认
 | ||
|     signConfirm(signInfo) {
 | ||
|       this.loading = true
 | ||
| 
 | ||
|       var params = {
 | ||
|         data: {
 | ||
|           globalTaskId: this.visitTaskId
 | ||
|         },
 | ||
|         signInfo: signInfo
 | ||
|       }
 | ||
|       submitGlobalReadingInfo(params).then(async res => {
 | ||
|         if (res.IsSuccess) {
 | ||
|           this.$message.success(this.$t('common:message:savedSuccessfully'))
 | ||
|           this.$refs['signForm'].btnLoading = false
 | ||
|           this.signVisible = false
 | ||
|           // 设置当前任务阅片状态为已读
 | ||
|           this.readingTaskState = 2
 | ||
|           var isAutoTask = await this.getAutoTaskVal()
 | ||
|           if (isAutoTask) {
 | ||
|             DicomEvent.$emit('getNextTask')
 | ||
|           } else {
 | ||
|           // 当前阅片任务已完成,是否进入下一个阅片任务
 | ||
|             this.$confirm(this.$t('trials:globalReview:message:msg2'), {
 | ||
|               type: 'warning',
 | ||
|               distinguishCancelAndClose: true
 | ||
|             })
 | ||
|               .then(() => {
 | ||
|                 store.dispatch('reading/resetVisitTasks')
 | ||
|                 DicomEvent.$emit('getNextTask')
 | ||
|               })
 | ||
|               .catch(action => {
 | ||
|                 changeURLStatic('visitTaskId', this.visitTaskId)
 | ||
|               })
 | ||
|           }
 | ||
|           window.opener.postMessage('refreshTaskList', window.location)
 | ||
|         }
 | ||
|         this.loading = false
 | ||
|       }).catch(_ => {
 | ||
|         this.loading = false
 | ||
|         this.$refs['signForm'].btnLoading = false
 | ||
|       })
 | ||
|     },
 | ||
|     getAutoTaskVal() {
 | ||
|       return new Promise((resolve, reject) => {
 | ||
|         getAutoCutNextTask().then(res => {
 | ||
|           resolve(res.Result.AutoCutNextTask)
 | ||
|         }).catch(() => { reject() })
 | ||
|       })
 | ||
|     },
 | ||
|     handleView(row) {
 | ||
|       if (this.openWindow) {
 | ||
|         this.openWindow.close()
 | ||
|       }
 | ||
|       try {
 | ||
|         var token = getToken()
 | ||
|         var visitTaskId = row.VisitTaskId
 | ||
|         var criterionType = this.$router.currentRoute.query.criterionType
 | ||
|         var readingTool = this.$router.currentRoute.query.readingTool
 | ||
|         readingTool = isNaN(parseInt(readingTool)) ? null : parseInt(readingTool)
 | ||
|         var isReadingTaskViewInOrder = this.$router.currentRoute.query.isReadingTaskViewInOrder
 | ||
|         var path = ''
 | ||
|         if (readingTool === 0) {
 | ||
|           path = `/readingDicoms?trialId=${this.trialId}&subjectCode=${this.subjectCode}&subjectId=${this.subjectId}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
 | ||
|         } else {
 | ||
|           path = `/noneDicomReading?trialId=${this.trialId}&subjectCode=${this.subjectCode}&subjectId=${this.subjectId}&visitTaskId=${visitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
 | ||
|         }
 | ||
|         const routeData = this.$router.resolve({ path })
 | ||
|         this.openWindow = window.open(routeData.href, '_blank')
 | ||
|       } catch (e) {
 | ||
|         console.log(e)
 | ||
|       }
 | ||
|     },
 | ||
| 
 | ||
|     previewCD() {
 | ||
|       var token = getToken()
 | ||
|       const routeData = this.$router.resolve({
 | ||
|         path: `/clinicalData?subjectId=${this.subjectId}&trialId=${this.trialId}&visitTaskId=${this.visitTaskId}&TokenKey=${token}`
 | ||
|       })
 | ||
| 
 | ||
|       window.open(routeData.href, '_blank')
 | ||
|     },
 | ||
|     setOpenWindow(window) {
 | ||
|       if (this.openWindow) {
 | ||
|         this.openWindow.close()
 | ||
|       }
 | ||
|       this.openWindow = window
 | ||
|     }
 | ||
|   }
 | ||
| }
 | ||
| </script>
 | ||
| <style lang="scss" scoped>
 | ||
| .glReview_wrapper{
 | ||
|   flex: 1;
 | ||
|   padding: 10px;
 | ||
|   width: 100%;
 | ||
|   height: 100%;
 | ||
|   overflow-y: auto;
 | ||
|   .box-mr{
 | ||
|     margin:10px 0;
 | ||
|   }
 | ||
| }
 | ||
| </style>
 |