1595 lines
61 KiB
Plaintext
1595 lines
61 KiB
Plaintext
<template>
|
||
<div v-loading="loading" class="qa-wrapper">
|
||
|
||
<div class="qa-content">
|
||
<!-- 所有检查信息 -->
|
||
<el-card shadow="hover" style="min-height:600px;">
|
||
<el-tabs v-model="activeName" type="card">
|
||
<!-- DICOM影像 -->
|
||
<el-tab-pane v-if="data.DicomStudyCount > 0" :label="$t('trials:audit:tab:dicoms')" name="dicom">
|
||
<el-row>
|
||
<el-col :span="12">
|
||
<!-- 检查信息 -->
|
||
<h3>{{ $t('trials:audit:title:dicoms') }}</h3>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
|
||
<div v-show="isHaveFirstGiveMedicineDate" style="text-align:right;">
|
||
<!-- 访视窗口期 -->
|
||
<h4>
|
||
{{ $t('trials:audit:tip:visitWindow') }}:
|
||
<span v-if="!!baseDate" style="font-weight:normal;">
|
||
{{ `${upperLimit}~${lowerLimit}` }}
|
||
</span>
|
||
<!-- 访视基准日期或窗口未设置 -->
|
||
<span v-else>{{ $t('trials:audit:tip:visitWindowNotSet') }}</span>
|
||
</h4>
|
||
|
||
</div>
|
||
</el-col>
|
||
</el-row>
|
||
<div style="text-align:right;">
|
||
<!-- 预览所有影像 -->
|
||
<el-button size="small" type="primary" style="margin-left:10px;" @click="handleViewImages">
|
||
{{ $t('trials:audit:button:previewAllDiocms') }}
|
||
</el-button>
|
||
<!-- 预览阅片影像 -->
|
||
<el-button size="small" type="primary" style="margin-left:10px;" @click="handleViewReadingImages">
|
||
{{ $t('trials:audit:button:previewReadingDiocms') }}
|
||
</el-button>
|
||
</div>
|
||
<el-table
|
||
:data="studyList"
|
||
:row-class-name="tableRowClassName"
|
||
>
|
||
<!-- 检查编号 -->
|
||
<el-table-column
|
||
prop="StudyCode"
|
||
:label="$t('trials:audit:table:studyId')"
|
||
/>
|
||
<!-- 检查类型 -->
|
||
<el-table-column
|
||
prop="ModalityForEdit"
|
||
:label="$t('trials:audit:table:modality')"
|
||
/>
|
||
<!-- 检查类型 -->
|
||
<el-table-column
|
||
prop="Modalities"
|
||
label="检查设备"
|
||
/>
|
||
<!-- 检查部位 -->
|
||
<el-table-column
|
||
prop="BodyPartForEdit"
|
||
:label="$t('trials:audit:table:bodyPart')"
|
||
/>
|
||
<!-- 序列数量 -->
|
||
<el-table-column
|
||
prop="SeriesCount"
|
||
:label="$t('trials:audit:table:seriesCount')"
|
||
/>
|
||
<!-- 图像数量 -->
|
||
<el-table-column
|
||
prop="InstanceCount"
|
||
:label="$t('trials:audit:table:instanceCount')"
|
||
/>
|
||
<!-- 检查日期 -->
|
||
<el-table-column
|
||
prop="StudyTime"
|
||
:label="$t('trials:audit:table:studyDate')"
|
||
>
|
||
<template slot-scope="scope">
|
||
<el-tooltip class="item" effect="dark" :content="$t('trials:audit:message:qsOverWindow')" placement="bottom">
|
||
<i
|
||
v-if="isHaveFirstGiveMedicineDate && !!baseDate && scope.row.StudyTime && (moment(scope.row.StudyTime).format('YYYY-MM-DD')>lowerLimit || moment(scope.row.StudyTime).format('YYYY-MM-DD')<upperLimit) "
|
||
class="el-icon-warning"
|
||
style="color: #f44336;font-size: 16px;"
|
||
/>
|
||
</el-tooltip>
|
||
|
||
<span>{{ scope.row.StudyTime ? moment(scope.row.StudyTime).format('YYYY-MM-DD') : '' }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
:label="$t('common:action:action')"
|
||
>
|
||
<template slot-scope="scope">
|
||
<!-- 预览 -->
|
||
<el-button
|
||
icon="el-icon-view"
|
||
:title="$t('trials:audit:action:preview')"
|
||
circle
|
||
:disabled="scope.row.IsDeleted"
|
||
@click="handlePreviewStudy(scope.row)"
|
||
/>
|
||
<!-- 编辑 -->
|
||
<el-button
|
||
icon="el-icon-edit-outline"
|
||
:title="$t('trials:audit:action:edit')"
|
||
circle
|
||
:disabled="isAudit || scope.row.IsDeleted"
|
||
@click="handleEditStudy(scope.row)"
|
||
/>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
<!-- 序列信息 -->
|
||
<h3>{{ $t('trials:audit:title:series') }}</h3>
|
||
<el-table
|
||
:data="seriesList"
|
||
:row-class-name="tableRowClassName"
|
||
>
|
||
<!-- 序列号 -->
|
||
<el-table-column
|
||
prop="SeriesNumber"
|
||
:label="$t('trials:audit:table:seriesId')"
|
||
/>
|
||
<!-- 检查编号 -->
|
||
<el-table-column
|
||
prop="StudyCode"
|
||
:label="$t('trials:audit:table:seriesOfStudyId')"
|
||
/>
|
||
<!-- 检查类型 -->
|
||
<el-table-column
|
||
prop="Modality"
|
||
:label="$t('trials:audit:table:seriesModality')"
|
||
|
||
show-overflow-tooltip
|
||
/>
|
||
<!-- 图像数量 -->
|
||
<el-table-column
|
||
prop="InstanceCount"
|
||
:label="$t('trials:audit:table:seriesOfInstanceCount')"
|
||
/>
|
||
<!-- 检查日期 -->
|
||
<el-table-column
|
||
prop="SeriesTime"
|
||
:label="$t('trials:audit:table:seriesOfStudyDate')"
|
||
|
||
show-overflow-tooltip
|
||
>
|
||
<template slot-scope="scope">
|
||
{{ scope.row.StudyTime ? moment(scope.row.StudyTime).format('YYYY-MM-DD') : '' }}
|
||
</template>
|
||
</el-table-column>
|
||
<!-- 上传时间 -->
|
||
<el-table-column
|
||
prop="CreateTime"
|
||
:label="$t('trials:audit:table:seriesOfUploadedDate')"
|
||
|
||
show-overflow-tooltip
|
||
/>
|
||
<!-- 是否阅片 -->
|
||
<el-table-column
|
||
prop="IsReading"
|
||
:label="$t('trials:audit:table:isReading')"
|
||
>
|
||
<template slot-scope="scope">
|
||
<el-switch
|
||
v-model="scope.row.IsReading"
|
||
:disabled="scope.row.IsDeleted || isAudit"
|
||
@change="changeReadingStatus($event, scope.row)"
|
||
/>
|
||
</template>
|
||
</el-table-column>
|
||
<!-- 是否删除 复审时删除的序列不可再次编辑 -->
|
||
<el-table-column
|
||
prop="IsDeleted"
|
||
:label="$t('trials:audit:table:isDelete')"
|
||
>
|
||
<template slot-scope="scope">
|
||
<el-switch
|
||
v-model="scope.row.IsDeleted"
|
||
:disabled="isAudit"
|
||
@change="changeDeleteStatus($event, scope.row)"
|
||
/>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
:label="$t('common:action:action')"
|
||
>
|
||
<template slot-scope="scope">
|
||
<!-- 预览 -->
|
||
<el-button
|
||
icon="el-icon-view"
|
||
:title="$t('trials:audit:action:seriesPreview')"
|
||
circle
|
||
:disabled="scope.row.IsDeleted"
|
||
@click="handlePreviewInstance(scope.row)"
|
||
/>
|
||
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</el-tab-pane>
|
||
<!-- 非DICOM影像 -->
|
||
<el-tab-pane v-if="data.NoneDicomStudyCount > 0" :label="$t('trials:audit:tab:nonDicoms')" name="none-dicom">
|
||
<el-row>
|
||
<!-- 检查信息 -->
|
||
<el-col :span="12"><h3>{{ $t('trials:audit:title:nonDicomsTitle') }}</h3></el-col>
|
||
<el-col :span="12">
|
||
<div v-show="isHaveFirstGiveMedicineDate" style="text-align:right;">
|
||
<!-- 访视窗口期 -->
|
||
<h4>{{ $t('trials:audit:tip:nonDicomsVisitWindow') }}:
|
||
<span v-if="!!baseDate" style="font-weight:normal;">
|
||
{{ `${upperLimit}~${lowerLimit}` }}
|
||
</span>
|
||
<!-- 访视基准日期或窗口未设置 -->
|
||
<span v-else>{{ $t('trials:audit:tip:visitWindowNotSet') }}</span>
|
||
</h4>
|
||
</div>
|
||
</el-col>
|
||
</el-row>
|
||
<div style="text-align:right;">
|
||
<!-- 预览 -->
|
||
<el-button size="small" :disabled="noneDicomStudyList.length === 0" type="primary" style="margin-left:10px;" @click="handleViewAllNoneDicoms">
|
||
{{ $t('trials:audit:tip:nonDicomsPreviewAll') }}
|
||
</el-button>
|
||
</div>
|
||
<el-table :data="noneDicomStudyList">
|
||
<!-- 检查编号 -->
|
||
<el-table-column
|
||
prop="CodeView"
|
||
:label="$t('trials:audit:table:nonDicomsStudyId')"
|
||
/>
|
||
<!-- 检查类型 -->
|
||
<el-table-column
|
||
prop="Modality"
|
||
:label="$t('trials:audit:table:nonDicomsModality')"
|
||
/>
|
||
<!-- 检查部位 -->
|
||
<el-table-column
|
||
prop="BodyPart"
|
||
:label="$t('trials:audit:table:nonDicomsBodypart')"
|
||
/>
|
||
<!-- 文件 -->
|
||
<el-table-column
|
||
prop="FileCount"
|
||
:label="$t('trials:audit:table:nonDicomsFileCount')"
|
||
>
|
||
<template slot-scope="scope">
|
||
<el-popover v-if="scope.row.FileCount" trigger="click" placement="bottom">
|
||
<el-table :data="scope.row.NoneDicomStudyFileList" height="300" size="small">
|
||
<!-- 文件名称 -->
|
||
<el-table-column
|
||
prop="FileName"
|
||
:label="$t('trials:audit:table:nonDicomsFileName')"
|
||
width="200"
|
||
/>
|
||
<el-table-column :label="$t('common:action:action')" width="120">
|
||
<template slot-scope="files">
|
||
<!-- 预览 -->
|
||
<el-button
|
||
type="text"
|
||
@click.native.prevent="previewFile(files.row)"
|
||
>
|
||
{{ $t('trials:audit:button:nonDicomsPreview') }}
|
||
</el-button>
|
||
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
<div slot="reference" class="name-wrapper">
|
||
<el-button
|
||
type="text"
|
||
>
|
||
{{ scope.row.FileCount }}
|
||
</el-button>
|
||
</div>
|
||
</el-popover>
|
||
<span v-else>{{ scope.row.FileCount }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<!-- 检查日期 -->
|
||
<el-table-column
|
||
prop="ImageDate"
|
||
:label="$t('trials:audit:table:nonDicomsStudyDate')"
|
||
>
|
||
<template slot-scope="scope">
|
||
<i
|
||
v-if="isHaveFirstGiveMedicineDate && !!baseDate && scope.row.ImageDate && (moment(scope.row.ImageDate).format('YYYY-MM-DD')>lowerLimit || moment(scope.row.ImageDate).format('YYYY-MM-DD')<upperLimit)"
|
||
class="el-icon-warning"
|
||
style="color: #f44336;font-size: 16px;"
|
||
/>
|
||
<span>{{ moment(scope.row.ImageDate).format('YYYY-MM-DD') }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<!-- 更新时间 -->
|
||
<el-table-column
|
||
prop="UpdateTime"
|
||
:label="$t('trials:audit:table:nonDicomsUpdateTime')"
|
||
/>
|
||
<el-table-column
|
||
:label="$t('common:action:action')"
|
||
>
|
||
<template slot-scope="scope">
|
||
<!-- 预览 -->
|
||
<el-button
|
||
type="text"
|
||
:disabled="scope.row.FileCount===0"
|
||
@click.native.prevent="handlePreviewNoneDicomFiles(scope.row)"
|
||
>
|
||
{{ $t('trials:audit:button:nonDicomsPreview') }}
|
||
</el-button>
|
||
<!-- 编辑 -->
|
||
<el-button
|
||
type="text"
|
||
:disabled="isAudit"
|
||
@click.native.prevent="handleEditNoneDicomInfo(scope.row)"
|
||
>
|
||
{{ $t('trials:audit:button:nonDicomsEdit') }}
|
||
</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</el-tab-pane>
|
||
<!-- 临床数据 -->
|
||
<!-- data.IsBaseLine && relationInfo.TrialClinicalInformationTransmissionEnum*1>0 && data.IsHaveClinicalData -->
|
||
<el-tab-pane v-if="data.IsHaveClinicalData" :label="$t('trials:audit:tab:clinicalData')" name="clinical-data">
|
||
<ClinicalData v-if="Object.keys(subjectClinicalData).length>0" :data="data" style="margin-top:5px;" :subject-clinical-data="subjectClinicalData" :enum-type="relationInfo.TrialClinicalInformationTransmissionEnum*1" :subject-visit-id="data.Id" :is-audit="isAudit" :subject-id="data.SubjectId" />
|
||
</el-tab-pane>
|
||
</el-tabs>
|
||
</el-card>
|
||
|
||
<!-- 审核问题 -->
|
||
<!-- select/input/textarea/radio -->
|
||
<el-card shadow="hover" style="margin-top:10px;">
|
||
<!-- 审核问题 -->
|
||
<h3>{{ $t('trials:audit:title:questions') }}</h3>
|
||
<div v-if="qCQuestionAnswerList.length > 0" style="overflow-y: auto;">
|
||
<QuestionForm
|
||
ref="questions"
|
||
:trial-id="trialId"
|
||
:subject-visit-id="data.Id"
|
||
:qc-process-enum="data.QCProcessEnum"
|
||
:current-q-c-enum="currentQCType"
|
||
:answers="qCQuestionAnswerList"
|
||
:is-audit="isAudit"
|
||
/>
|
||
</div>
|
||
<!-- 暂无数据 -->
|
||
<h3 v-else>{{ $t('trials:audit:message:noData') }}</h3>
|
||
</el-card>
|
||
|
||
<!-- 发起质疑 -->
|
||
<el-dialog
|
||
v-if="qcVisible"
|
||
:title="$t('trials:audit:dialogTitle:question')"
|
||
:visible.sync="qcVisible"
|
||
:close-on-click-modal="false"
|
||
append-to-body
|
||
custom-class="base-dialog-wrapper"
|
||
width="1000px"
|
||
>
|
||
<div style="padding:10px;border: 1px solid #e0e0e0;max-height:650px;overflow-y: auto;">
|
||
<el-form v-if="qcVisible" ref="qcForm" :model="qcForm" label-width="120px" size="small">
|
||
<el-form-item :label="$t('trials:audit:form:questionContent')">
|
||
<!-- :header-row-style="{display:'none'}" -->
|
||
<el-table
|
||
:data="qcForm.qcContent"
|
||
style="width: 100%"
|
||
>
|
||
<el-table-column
|
||
prop="isSelect"
|
||
label=""
|
||
width="40"
|
||
>
|
||
<template slot-scope="scope">
|
||
<el-checkbox v-model="scope.row.isSelect" />
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
prop="keyName"
|
||
label=""
|
||
width="180"
|
||
/>
|
||
<!-- 问题总结 -->
|
||
<el-table-column
|
||
prop="keyValue"
|
||
:label="$t('trials:audit:form:questionSummary')"
|
||
>
|
||
<template slot-scope="scope">
|
||
<el-input
|
||
v-show="scope.row.keyValue || scope.row.isSelect"
|
||
v-model="scope.row.keyValue"
|
||
type="textarea"
|
||
:rows="4"
|
||
size="mini"
|
||
/>
|
||
</template>
|
||
</el-table-column>
|
||
<!-- 行动事项 -->
|
||
<el-table-column
|
||
prop="ActionContent"
|
||
:label="$t('trials:audit:form:actionMatters')"
|
||
>
|
||
<template slot-scope="scope">
|
||
<el-input
|
||
v-show="scope.row.actionContent || scope.row.isSelect"
|
||
v-model="scope.row.actionContent"
|
||
type="textarea"
|
||
:rows="4"
|
||
size="mini"
|
||
/>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</el-form-item>
|
||
<el-form-item :label="$t('trials:audit:form:questionDeadline')">
|
||
<el-date-picker
|
||
v-model="qcForm.deadlineTime"
|
||
value-format="yyyy-MM-dd HH:mm:ss"
|
||
type="datetime"
|
||
size="small"
|
||
clearable
|
||
default-time="23:59:59"
|
||
style="width:100%"
|
||
/>
|
||
</el-form-item>
|
||
|
||
</el-form>
|
||
</div>
|
||
<div slot="footer" class="dialog-footer">
|
||
<!-- 取消 -->
|
||
<el-button :disabled="btnLoading" size="small" type="primary" @click="qcVisible = false">
|
||
{{ $t('common:button:cancel') }}
|
||
</el-button>
|
||
<!-- 保存 -->
|
||
<el-button size="small" type="primary" :loading="btnLoading" @click="handleSaveQC">
|
||
{{ $t('common:button:save') }}
|
||
</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
|
||
<!-- 历史质疑 -->
|
||
<el-dialog
|
||
v-if="historyVisible"
|
||
:visible.sync="historyVisible"
|
||
:close-on-click-modal="false"
|
||
custom-class="base-dialog-wrapper"
|
||
append-to-body
|
||
width="80%"
|
||
:title="$t('trials:audit:dialogTitle:historicalQuestions')"
|
||
>
|
||
<div style="text-align:right;">
|
||
<el-button icon="el-icon-refresh-left" circle :title="$t('trials:audit:button:refreshHistoryQs')" @click="getHistoryInfo" />
|
||
</div>
|
||
<el-table
|
||
v-loading="historyLoading"
|
||
:data="historyList"
|
||
style="width: 100%"
|
||
height="500"
|
||
>
|
||
<!-- 质疑编号 -->
|
||
<el-table-column
|
||
prop="ChallengeCode"
|
||
:label="$t('trials:qcQuality:table:challengeCode')"
|
||
min-width="80"
|
||
show-overflow-tooltip
|
||
>
|
||
<template slot-scope="scope">
|
||
<el-button :style="{color:scope.row.IsClosed?'':'red'}" type="text" @click="handleReply(scope.row)">{{ scope.row.ChallengeCode }}</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
<!-- 质疑状态 -->
|
||
<el-table-column
|
||
prop="IsClosed"
|
||
:label="$t('trials:qcQuality:table:isClosed')"
|
||
min-width="80"
|
||
show-overflow-tooltip
|
||
>
|
||
<template slot-scope="scope">
|
||
{{ scope.row.IsClosed?'已关闭':'未关闭' }}
|
||
</template>
|
||
</el-table-column>
|
||
<!-- 创建时间 -->
|
||
<el-table-column
|
||
prop="CreateTime"
|
||
:label="$t('trials:qcQuality:table:createTime')"
|
||
min-width="150"
|
||
show-overflow-tooltip
|
||
/>
|
||
<!-- 创建人 -->
|
||
<el-table-column
|
||
prop="CreateUserName"
|
||
:label="$t('trials:qcQuality:table:organizer')"
|
||
min-width="80"
|
||
show-overflow-tooltip
|
||
/>
|
||
<!-- 领取人 -->
|
||
<el-table-column
|
||
prop="CurrentActionUserName"
|
||
:label="$t('trials:qcCheck:table:crrentUser')"
|
||
min-width="80"
|
||
show-overflow-tooltip
|
||
/>
|
||
<!-- 最新消息时间 -->
|
||
<el-table-column
|
||
prop="LatestMsgTime"
|
||
:label="$t('trials:qcQuality:table:latestMsgTime')"
|
||
min-width="150"
|
||
show-overflow-tooltip
|
||
/>
|
||
<!-- 重传状态 -->
|
||
<el-table-column
|
||
prop="ReuploadEnum"
|
||
:label="$t('trials:qcQuality:table:reUploadStatus')"
|
||
show-overflow-tooltip
|
||
min-width="110"
|
||
sortable="custom"
|
||
>
|
||
<template slot-scope="scope">
|
||
<span v-if="scope.row.ReuploadEnum === 0">--</span>
|
||
<el-tag v-else-if="scope.row.ReuploadEnum === 1" type="danger">{{ $fd('ReuploadEnum', scope.row.ReuploadEnum) }}</el-tag>
|
||
<el-tag v-else-if="scope.row.ReuploadEnum === 2" type="warning">{{ $fd('ReuploadEnum', scope.row.ReuploadEnum) }}</el-tag>
|
||
<el-tag v-else-if="scope.row.ReuploadEnum === 3" type="primary">{{ $fd('ReuploadEnum', scope.row.ReuploadEnum) }}</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<!-- 重传完成时间 -->
|
||
<el-table-column
|
||
prop="ReUploadedTime"
|
||
:label="$t('trials:qcQuality:table:reUploadTime')"
|
||
show-overflow-tooltip
|
||
min-width="150"
|
||
sortable="custom"
|
||
/>
|
||
<!-- 处理截止日期 -->
|
||
<el-table-column
|
||
prop="DeadlineTime"
|
||
:label="$t('trials:qcQuality:table:deadline')"
|
||
min-width="120"
|
||
show-overflow-tooltip
|
||
/>
|
||
<!-- 是否超限 -->
|
||
<el-table-column
|
||
prop="IsOverTime"
|
||
:label="$t('trials:qcQuality:table:isOverTime')"
|
||
min-width="100"
|
||
show-overflow-tooltip
|
||
>
|
||
<template slot-scope="scope">
|
||
{{ $fd('YesOrNo', scope.row.IsOverTime) }}
|
||
</template>
|
||
</el-table-column>
|
||
<!-- 关闭时间 -->
|
||
<el-table-column
|
||
prop="ClosedTime"
|
||
:label="$t('trials:qcQuality:table:closingTime')"
|
||
min-width="150"
|
||
show-overflow-tooltip
|
||
/>
|
||
<el-table-column :label="$t('common:action:action')" min-width="100">
|
||
<template slot-scope="scope">
|
||
<!-- 回复 -->
|
||
<el-button
|
||
type="text"
|
||
:disabled="scope.row.IsClosed || isAudit"
|
||
@click="handleReply(scope.row)"
|
||
>
|
||
{{ $t('trials:qcQuality:action:reply') }}
|
||
</el-button>
|
||
<!-- 关闭 -->
|
||
<el-button
|
||
type="text"
|
||
:disabled="scope.row.IsClosed || isAudit"
|
||
@click="handleCloseQC(scope.row)"
|
||
>
|
||
{{ $t('trials:qcQuality:action:close') }}
|
||
</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</el-dialog>
|
||
|
||
<!-- 质疑记录 -->
|
||
<el-dialog
|
||
v-if="chatVisible"
|
||
:visible.sync="chatVisible"
|
||
:close-on-click-modal="false"
|
||
custom-class="base-dialog-wrapper"
|
||
append-to-body
|
||
width="800px"
|
||
:title="$t('trials:qcQuality:dialogTitle:reply') + `(${currentQCRow.SubjectCode} ${currentQCRow.VisitName})`"
|
||
>
|
||
<chat-form :data="currentQCRow" :sign-text="relationInfo.TrialImageQCSignText" :clinical-enum="relationInfo.ClinicalInformationTransmissionEnum" @close="chatVisible = false" @getDialogList="getDialogList" />
|
||
</el-dialog>
|
||
|
||
<!-- 更新检查拍片部位信息 -->
|
||
<el-dialog
|
||
v-if="editStudyInfoVisible"
|
||
:title="$t('trials:audit:action:edit')"
|
||
:visible.sync="editStudyInfoVisible"
|
||
:close-on-click-modal="false"
|
||
append-to-body
|
||
custom-class="base-dialog-wrapper"
|
||
width="600px"
|
||
>
|
||
<div style="padding:10px;border: 1px solid #e0e0e0;max-height:650px;overflow-y: auto;">
|
||
<el-form ref="studyForm" :model="studyForm" label-width="100px">
|
||
<!-- 检查编号 -->
|
||
<el-form-item :label="$t('trials:audit:table:studyId')">
|
||
<el-input v-model="studyForm.StudyCode" disabled />
|
||
</el-form-item>
|
||
<!-- 检查类型 -->
|
||
<el-form-item v-if="studyForm.IsDicomData" :label="$t('trials:audit:table:modality')">
|
||
<el-input v-model="studyForm.Modalities" disabled />
|
||
</el-form-item>
|
||
<!-- 检查类型 -->
|
||
<el-form-item
|
||
v-else
|
||
:label="$t('trials:audit:table:modality')"
|
||
prop="Modalities"
|
||
:rules="[
|
||
{ required: true, message: $t('common:ruleMessage:specify'), trigger: 'blur' }
|
||
]"
|
||
>
|
||
<el-radio-group v-model="studyForm.Modality">
|
||
<el-radio v-for="m in trialModalitys" v-show="m !== ''" :key="m" :label="m" style="margin-bottom: 15px;" />
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
<!-- 检查部位 -->
|
||
<el-form-item
|
||
:label="$t('trials:audit:table:bodyPart')"
|
||
prop="BodyPartForEdit"
|
||
:rules="[
|
||
{ required: true, message: $t('common:ruleMessage:specify'), trigger: 'blur' }
|
||
]"
|
||
>
|
||
<el-checkbox-group v-model="studyForm.BodyPartForEdit">
|
||
<el-checkbox v-for="bodyPart in trialBodyPartTypes" :key="bodyPart" :label="bodyPart" />
|
||
</el-checkbox-group>
|
||
</el-form-item>
|
||
<!-- 序列数量 -->
|
||
<el-form-item :label="$t('trials:audit:table:seriesCount')">
|
||
<el-input v-model="studyForm.SeriesCount" disabled />
|
||
</el-form-item>
|
||
<!-- 图像数量 -->
|
||
<el-form-item v-if="studyForm.InstanceCount" :label="$t('trials:audit:table:instanceCount')">
|
||
<el-input v-model="studyForm.InstanceCount" disabled />
|
||
</el-form-item>
|
||
<!-- 检查日期 -->
|
||
<el-form-item :label="$t('trials:audit:table:studyDate')">
|
||
<el-date-picker
|
||
v-model="studyForm.StudyTime"
|
||
disabled
|
||
type="date"
|
||
value-format="yyyy-MM-dd"
|
||
format="yyyy-MM-dd"
|
||
style="width:100%;"
|
||
/>
|
||
</el-form-item>
|
||
</el-form>
|
||
</div>
|
||
<div slot="footer" class="dialog-footer">
|
||
<el-button :disabled="btnLoading" size="small" type="primary" @click="editStudyInfoVisible = false">
|
||
{{ $t('common:button:cancel') }}
|
||
</el-button>
|
||
<el-button :loading="btnLoading" size="small" type="primary" @click="handleUpdateStudyInfo">
|
||
{{ $t('common:button:save') }}
|
||
</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
|
||
<!-- 审核签名 -->
|
||
<el-dialog
|
||
v-if="signVisible"
|
||
:visible.sync="signVisible"
|
||
:close-on-click-modal="false"
|
||
width="600px"
|
||
append-to-body
|
||
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" :subject-visit-id="data.Id" @closeDialog="closeSignDialog" />
|
||
</el-dialog>
|
||
<!-- 编辑非Dicom文件 -->
|
||
<el-dialog
|
||
v-if="editNoneDicomVisible"
|
||
:title="$t('trials:audit:button:nonDicomsEdit')"
|
||
:visible.sync="editNoneDicomVisible"
|
||
:close-on-click-modal="false"
|
||
append-to-body
|
||
custom-class="base-dialog-wrapper"
|
||
width="600px"
|
||
>
|
||
<div style="padding:10px;border: 1px solid #e0e0e0;max-height:650px;overflow-y: auto;">
|
||
<el-form ref="noneDicomForm" :model="noneDicomForm" label-width="100px">
|
||
<!-- 检查编号 -->
|
||
<el-form-item :label="$t('trials:audit:table:nonDicomsStudyId')">
|
||
<el-input v-model="noneDicomForm.CodeView" disabled />
|
||
</el-form-item>
|
||
<!-- 检查类型 -->
|
||
<el-form-item
|
||
:label="$t('trials:audit:table:nonDicomsModality')"
|
||
prop="Modality"
|
||
:rules="[
|
||
{ required: true, message: $t('common:ruleMessage:specify'), trigger: 'blur' }
|
||
]"
|
||
>
|
||
<el-radio-group v-model="noneDicomForm.Modality">
|
||
<el-radio v-for="m in trialModalitys" v-show="m !== ''" :key="m" :label="m" style="margin-bottom: 15px;" />
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
<!-- 检查部位 -->
|
||
<el-form-item
|
||
:label="$t('trials:audit:table:nonDicomsBodypart')"
|
||
prop="BodyParts"
|
||
:rules="[
|
||
{ required: true, message: $t('common:ruleMessage:specify'), trigger: 'blur' }
|
||
]"
|
||
>
|
||
<el-checkbox-group v-model="noneDicomForm.BodyParts">
|
||
<el-checkbox v-for="bodyPart in trialBodyPartTypes" :key="bodyPart" :label="bodyPart" />
|
||
</el-checkbox-group>
|
||
</el-form-item>
|
||
<!-- 检查日期 -->
|
||
<el-form-item
|
||
:label="$t('trials:audit:table:nonDicomsStudyDate')"
|
||
prop="ImageDate"
|
||
>
|
||
<el-date-picker
|
||
v-model="noneDicomForm.ImageDate"
|
||
disabled
|
||
type="date"
|
||
:picker-options="pickerOption"
|
||
value-format="yyyy-MM-dd"
|
||
format="yyyy-MM-dd"
|
||
style="width:100%;"
|
||
/>
|
||
</el-form-item>
|
||
</el-form>
|
||
</div>
|
||
<div slot="footer" class="dialog-footer">
|
||
<el-button :disabled="btnLoading" size="small" type="primary" @click="editNoneDicomVisible = false">
|
||
{{ $t('common:button:cancel') }}
|
||
</el-button>
|
||
<el-button :loading="btnLoading" size="small" type="primary" @click="handleUpdateNoneDicomInfo">
|
||
{{ $t('common:button:save') }}
|
||
</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
|
||
<!-- 关闭质疑 -->
|
||
<el-dialog
|
||
v-if="closeQuestionVisible"
|
||
:visible.sync="closeQuestionVisible"
|
||
:close-on-click-modal="false"
|
||
append-to-body
|
||
custom-class="base-dialog-wrapper"
|
||
width="600px"
|
||
:title="$t('trials:qcQuality:dialogTitle:closeQuestion')"
|
||
>
|
||
<div style="padding:10px;border: 1px solid #e0e0e0;max-height:650px;overflow-y: auto;">
|
||
<el-form
|
||
ref="closeQuestionForm"
|
||
:model="closeQuestionForm"
|
||
size="small"
|
||
label-width="120px"
|
||
>
|
||
<el-form-item
|
||
:label="$t('trials:qcQuality:label:closeReason')"
|
||
prop="Type"
|
||
:rules="[
|
||
{ required: true, message: $t('common:ruleMessage:select')},
|
||
]"
|
||
>
|
||
<el-radio-group v-model="closeQuestionForm.Type">
|
||
<!-- 问题已解决 -->
|
||
<el-radio :label="1">{{ $t('trials:qcQuality:radio:reason1') }}</el-radio>
|
||
<!-- 问题无法解决强制关闭质疑 -->
|
||
<el-radio :label="2">{{ $t('trials:qcQuality:radio:reason2') }}</el-radio>
|
||
<!-- <!– 其他 –>-->
|
||
<!-- <el-radio :label="3">{{ $t('trials:qcQuality:radio:reason3') }}</el-radio>-->
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
<el-form-item
|
||
v-if="closeQuestionForm.Type === 2"
|
||
:label="$t('trials:consistencyCheck:label:closereason')"
|
||
prop="Remake"
|
||
:rules="[
|
||
{ required: true, message: $t('common:ruleMessage:specify')},
|
||
]"
|
||
>
|
||
<el-input
|
||
v-model="closeQuestionForm.Remake"
|
||
type="textarea"
|
||
:autosize="{ minRows: 2, maxRows: 4}"
|
||
/>
|
||
</el-form-item>
|
||
</el-form>
|
||
</div>
|
||
<div slot="footer" class="dialog-footer">
|
||
<el-button :disabled="closeBtnLoading" size="small" type="primary" @click="closeQuestionVisible = false">
|
||
{{ $t('common:button:cancel') }}
|
||
</el-button>
|
||
<el-button :loading="closeBtnLoading" size="small" type="primary" @click="handleCloseQuestion">
|
||
{{ $t('common:button:save') }}
|
||
</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
<!-- 预览单个图像 -->
|
||
<el-dialog
|
||
v-if="imgObj.visible"
|
||
:visible.sync="imgObj.visible"
|
||
:title="$t('trials:uploadNonDicoms:dialogTitle:preview')"
|
||
append-to-body
|
||
width="565px"
|
||
>
|
||
<div v-loading="imgObj.loading" class="base-modal-body" style="border:2px solid #ccc;padding: 10px;">
|
||
<el-image
|
||
:src="`/api${imgObj.url}`"
|
||
fit="fit"
|
||
style="height:500px;width:500px"
|
||
@error="imgObj.loading = false"
|
||
@load="imgObj.loading = false"
|
||
/>
|
||
</div>
|
||
|
||
</el-dialog>
|
||
</div>
|
||
<div class="function-wrapper">
|
||
<!-- 保存 -->
|
||
<el-button :disabled="isAudit" size="small" type="primary" round @click="handleSave">
|
||
{{ $t('trials:audit:button:save') }}
|
||
</el-button>
|
||
<!-- 发质疑 -->
|
||
<el-button :disabled="isAudit" size="small" type="primary" round @click="handleQC">
|
||
{{ $t('trials:audit:button:question') }}
|
||
</el-button>
|
||
<!-- 历史质疑 -->
|
||
<el-button size="small" type="primary" round @click="handleHistoryQC">
|
||
{{ `${$t('trials:audit:button:historicalQuestions')}(${relationInfo.TotalChallengeCount !== undefined ?relationInfo.TotalChallengeCount:0}, ${relationInfo.NotClosedChallengeCount !== undefined?relationInfo.NotClosedChallengeCount:0})` }}
|
||
</el-button>
|
||
|
||
<!-- 审核通过 -->
|
||
<el-button :disabled="isAudit" size="small" type="primary" round @click="handleQCState(8)">
|
||
{{ $t('trials:audit:button:auditPassed') }}
|
||
</el-button>
|
||
<!-- 审核终止 -->
|
||
<!-- <el-button :disabled="isAudit" size="small" type="primary" round @click="handleQCState(7)">-->
|
||
<!-- {{ $t('trials:audit:button:auditFailed') }}-->
|
||
<!-- </el-button>-->
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<script>
|
||
import { getVisitQCInfo, getQCQuestionAnswerList, getHistoryChallengeList, getVisitQCStudyAndSeriesList, getNoneDicomStudyList, verifyCanQCPassedOrFailed, verifyQCCanAddChallenge, setSeriesStatus, addOrUpdateNoneDicomStudy, addOrUpdateQCQuestionAnswerList, addOrUpdateQCChallenge, closeQCChallenge, updateModality, getQCChallengeDialogList } from '@/api/trials'
|
||
import { qCPassedOrFailed } from '@/api/trials/visit'
|
||
import { getBasicDataSelects } from '@/api/dictionary/dictionary'
|
||
import ChatForm from './chatForm'
|
||
import QuestionForm from './questions'
|
||
import moment from 'moment'
|
||
import ClinicalData from './clinicalData'
|
||
import SignForm from '@/views/trials/components/newSignForm'
|
||
import { getToken } from '@/utils/auth'
|
||
import const_ from '@/const/sign-code'
|
||
export default {
|
||
name: 'QualityAssurance',
|
||
components: { ChatForm, ClinicalData, QuestionForm, SignForm },
|
||
props: {
|
||
data: {
|
||
type: Object,
|
||
default() {
|
||
return {}
|
||
}
|
||
},
|
||
disabled: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
qType: {
|
||
type: Number,
|
||
default: 1
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
activeName: this.data.DicomStudyCount > 0 ? 'dicom' : 'none-dicom',
|
||
questionForm: {},
|
||
qCQuestionAnswerList: [],
|
||
studyList: [],
|
||
seriesList: [],
|
||
relationInfo: {},
|
||
noneDicomStudyList: [],
|
||
qcForm: { subjectVisitId: '', challengeType: '', content: '', actionContent: '', deadlineTime: '', qcContent: '' },
|
||
qcVisible: false,
|
||
chatVisible: false,
|
||
loading: false,
|
||
btnLoading: false,
|
||
historyVisible: false,
|
||
historyList: [],
|
||
historyLoading: false,
|
||
editStudyInfoVisible: false,
|
||
studyForm: { StudyCode: '', IsDicomData: true, Modalities: '', BodyPartForEdit: [], SeriesCount: null, StudyTime: '' },
|
||
currentQCRow: {},
|
||
isAudit: false, // 审核过之后功能按钮禁用标识
|
||
qcType: '',
|
||
trialBodyPartTypes: [],
|
||
trialModalitys: [],
|
||
signVisible: false,
|
||
signCode: '',
|
||
auditState: null,
|
||
currentNoneDicomId: '',
|
||
editNoneDicomVisible: false,
|
||
noneDicomForm: { Id: '', CodeView: '', BodyParts: [], Modality: '', ImageDate: '' },
|
||
subjectClinicalData: {},
|
||
moment,
|
||
currentQCType: null,
|
||
currentUser: zzSessionStorage.getItem('userName'),
|
||
pickerOption: {
|
||
disabledDate: time => {
|
||
return time.getTime() > Date.now()
|
||
}
|
||
},
|
||
isHaveFirstGiveMedicineDate: false,
|
||
baseDate: '',
|
||
upperLimit: '', // 超期上限
|
||
lowerLimit: '', // 超期下限
|
||
closeQuestionForm: { Id: '', SubjectVisitId: '', Type: null, Reason: '', Remake: '' },
|
||
closeBtnLoading: false,
|
||
closeQuestionVisible: false,
|
||
trialId: '',
|
||
dictionaryList: {},
|
||
currentSeriesIsReading: false,
|
||
currentSeriesIsDeleted: false,
|
||
imgObj: { url: '', visible: false, loading: false },
|
||
open: null
|
||
}
|
||
},
|
||
mounted() {
|
||
if (this.disabled) {
|
||
this.isAudit = true
|
||
this.currentQCType = this.qType
|
||
} else {
|
||
this.currentQCType = this.data.AuditState < 6 ? 1 : 2
|
||
}
|
||
window.addEventListener('message', this.receiveMsg)
|
||
|
||
this.trialId = this.$route.query.trialId
|
||
this.getQCInfo()
|
||
this.getDicData()
|
||
// this.handleViewImages()
|
||
// this.handleViewAllNoneDicoms()
|
||
},
|
||
methods: {
|
||
// 获取QC界面基本信息
|
||
getQCInfo() {
|
||
this.loading = true
|
||
getVisitQCInfo(this.data.Id, this.data.QCProcessEnum, this.currentQCType).then(res => {
|
||
this.qCQuestionAnswerList = res.Result.QCQuestionAnswerList
|
||
this.studyList = res.Result.StudyList
|
||
this.seriesList = res.Result.SeriesList
|
||
this.noneDicomStudyList = res.Result.NoneDicomStudyList
|
||
this.relationInfo = res.Result.RelationInfo
|
||
this.trialBodyPartTypes =
|
||
this.relationInfo.TrialBodyPartTypes ? this.relationInfo.TrialBodyPartTypes.trim().split('|') : []
|
||
this.trialModalitys =
|
||
this.relationInfo.TrialModalitys ? this.relationInfo.TrialModalitys.trim().split('|') : []
|
||
this.subjectClinicalData = res.Result.SubjectClinicalData
|
||
this.baseDate = res.Result.RelationInfo.SubjectFirstGiveMedicineTime
|
||
if (this.baseDate) {
|
||
const uDay = res.Result.RelationInfo.VisitDay * 1 + res.Result.RelationInfo.VisitWindowLeft * 1
|
||
this.upperLimit = moment(this.baseDate, 'YYYY-MM-DD').add(uDay, 'days').format('YYYY-MM-DD')
|
||
const lDay = res.Result.RelationInfo.VisitDay * 1 + res.Result.RelationInfo.VisitWindowRight * 1
|
||
this.lowerLimit = moment(this.baseDate, 'YYYY-MM-DD').add(lDay, 'days').format('YYYY-MM-DD')
|
||
}
|
||
this.isHaveFirstGiveMedicineDate = res.Result.RelationInfo.IsHaveFirstGiveMedicineDate
|
||
this.loading = false
|
||
}).catch(() => {
|
||
this.loading = false
|
||
})
|
||
},
|
||
// 刷新审核问题列表
|
||
getCheckList() {
|
||
this.loading = true
|
||
getQCQuestionAnswerList(this.trialId, this.data.Id, this.data.QCProcessEnum, this.currentQCType).then(res => {
|
||
this.loading = false
|
||
res.Result.forEach((element, index) => {
|
||
// this.qCQuestionAnswerList
|
||
this.$set(this.qCQuestionAnswerList[index], 'Id', element.Id)
|
||
})
|
||
}).catch(() => {
|
||
this.loading = false
|
||
})
|
||
},
|
||
// 保存审核问题
|
||
handleSave(isMessage) {
|
||
return new Promise(resolve => {
|
||
this.$refs['questions'].submit().then(res => {
|
||
var answerList = []
|
||
res.forEach(item => {
|
||
var index = this.qCQuestionAnswerList.findIndex(v => v.TrialQCQuestionConfigureId === item.Id)
|
||
if (index > -1) {
|
||
answerList.push({ id: this.qCQuestionAnswerList[index].Id, answer: item.answer, trialQCQuestionConfigureId: item.Id })
|
||
}
|
||
})
|
||
this.loading = true
|
||
addOrUpdateQCQuestionAnswerList(this.trialId, this.data.Id, this.data.QCProcessEnum, this.currentQCType, answerList).then(res => {
|
||
this.loading = false
|
||
if (res.IsSuccess) {
|
||
if (isMessage !== true) {
|
||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||
}
|
||
this.getCheckList()
|
||
resolve(true)
|
||
}
|
||
}).catch(() => {
|
||
this.loading = false
|
||
resolve(false)
|
||
})
|
||
}).catch(() => {
|
||
this.loading = false
|
||
resolve(false)
|
||
})
|
||
})
|
||
},
|
||
// 保存质疑
|
||
handleSaveQC() {
|
||
this.$refs['qcForm'].validate((valid) => {
|
||
if (!valid) return
|
||
this.btnLoading = true
|
||
this.qcForm.subjectVisitId = this.data.Id
|
||
var contents = []
|
||
var types = []
|
||
var actions = []
|
||
this.qcForm.qcContent.forEach(item => {
|
||
if (item.isSelect) {
|
||
types.push(`${item.keyName}`)
|
||
var str = `${item.keyName} <br>`
|
||
if (item.keyValue) {
|
||
// 问题总结
|
||
str = `${str}${this.$t('trials:audit:form:questionSummary')}:${item.keyValue}<br>`
|
||
}
|
||
if (item.actionContent) {
|
||
// 行动事项
|
||
actions.push(`${item.actionContent}`)
|
||
str = `${str}${this.$t('trials:audit:form:actionMatters')}:${item.actionContent}<br>`
|
||
}
|
||
contents.push(str)
|
||
}
|
||
})
|
||
if (contents.length === 0) {
|
||
// 质疑内容不能为空!
|
||
this.$message.error(this.$t('trials:audit:message:qsContentIsNull'))
|
||
this.btnLoading = false
|
||
return
|
||
} else {
|
||
this.qcForm.content = contents.join('|')
|
||
this.qcForm.challengeType = types.join('|')
|
||
this.qcForm.actionContent = actions.join('|')
|
||
}
|
||
var params = {
|
||
challengeType: this.qcForm.challengeType,
|
||
subjectVisitId: this.qcForm.subjectVisitId,
|
||
content: this.qcForm.content,
|
||
actionContent: this.qcForm.actionContent,
|
||
reuploadEnum: 0,
|
||
deadlineTime: this.qcForm.deadlineTime
|
||
}
|
||
addOrUpdateQCChallenge(this.trialId, this.data.QCProcessEnum, this.currentQCType, params).then(res => {
|
||
this.btnLoading = false
|
||
if (res.IsSuccess) {
|
||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||
this.qcVisible = false
|
||
this.relationInfo.TotalChallengeCount++
|
||
this.relationInfo.NotClosedChallengeCount++
|
||
}
|
||
}).catch(() => { this.btnLoading = false })
|
||
})
|
||
},
|
||
// 打开发起质疑弹窗
|
||
handleQC() {
|
||
this.loading = true
|
||
// 检验qc审核问题是否保存,否则不允许发质疑
|
||
verifyQCCanAddChallenge(this.trialId, this.data.Id, this.currentQCType).then(res => {
|
||
this.loading = false
|
||
if (res.IsSuccess) {
|
||
this.renderQCForm()
|
||
}
|
||
}).catch(() => { this.loading = false })
|
||
},
|
||
handleQCVerify() {
|
||
this.loading = true
|
||
return new Promise(resolve => {
|
||
verifyQCCanAddChallenge(this.trialId, this.data.Id, this.currentQCType).then(res => {
|
||
this.loading = false
|
||
if (res.IsSuccess) {
|
||
resolve(true)
|
||
} else {
|
||
resolve(false)
|
||
}
|
||
}).catch(() => {
|
||
this.loading = false
|
||
resolve(false)
|
||
})
|
||
})
|
||
},
|
||
// 渲染发质疑窗口
|
||
renderQCForm() {
|
||
var contents = []
|
||
const challengeType = this.dictionaryList['ChallengeType']
|
||
challengeType.forEach(i => {
|
||
contents.push({ keyName: i.Value, keyValue: '', isSelect: false })
|
||
})
|
||
var isHyperwindow = false
|
||
if (this.isHaveFirstGiveMedicineDate && !!this.baseDate) {
|
||
isHyperwindow = this.isHyperwindow()
|
||
}
|
||
if (isHyperwindow) {
|
||
contents.push({ keyName: this.$t('trials:audit:message:qsOverWindow'), keyValue: `${this.$t('trials:audit:message:qsOverWindow1')}:${this.upperLimit}~${this.lowerLimit},${this.$t('trials:audit:message:qsOverWindow2')}:${moment(this.relationInfo.EarliestScanDate).format('YYYY-MM-DD')}~${moment(this.relationInfo.LatestScanDate).format('YYYY-MM-DD')},${this.$t('trials:audit:message:qsOverWindow3')}`, isSelect: false, actionContent: this.$t('trials:audit:message:qsOverWindow4') })
|
||
}
|
||
this.qcForm.qcContent = contents
|
||
const day = this.relationInfo.TrialChangeDefalutDays
|
||
this.qcForm.deadlineTime = moment().add(day * 1, 'days').format('YYYY-MM-DD HH:mm:ss')
|
||
this.qcVisible = true
|
||
},
|
||
isHyperwindow() {
|
||
var isHyperwindow = false
|
||
if (this.relationInfo.EarliestScanDate < this.upperLimit || this.relationInfo.LatestScanDate > this.lowerLimit) {
|
||
isHyperwindow = true
|
||
}
|
||
return isHyperwindow
|
||
},
|
||
// 获取字典数据
|
||
getDicData() {
|
||
getBasicDataSelects(['ChallengeType']).then(res => {
|
||
this.dictionaryList = { ...res.Result }
|
||
})
|
||
},
|
||
// 打开历史质疑弹窗
|
||
handleHistoryQC() {
|
||
this.historyVisible = true
|
||
this.getHistoryInfo()
|
||
},
|
||
// 获取历史质疑记录
|
||
getHistoryInfo() {
|
||
this.historyLoading = true
|
||
getHistoryChallengeList(this.data.Id, this.data.QCProcessEnum, this.currentQCType).then(res => {
|
||
this.historyList = res.Result
|
||
this.historyLoading = false
|
||
}).catch(() => { this.historyLoading = false })
|
||
},
|
||
|
||
// 回复质疑
|
||
handleReply(row) {
|
||
this.historyLoading = true
|
||
getQCChallengeDialogList(row.Id).then(res => {
|
||
this.historyLoading = false
|
||
if (res.IsSuccess) {
|
||
if (res.Result.length > 0) { Object.assign(row, res.Result[0]) }
|
||
this.currentQCRow = { ...row }
|
||
this.chatVisible = true
|
||
}
|
||
}).catch(() => { this.historyLoading = false })
|
||
},
|
||
getDialogList() {
|
||
this.historyLoading = true
|
||
getQCChallengeDialogList(this.currentQCRow.Id).then(res => {
|
||
this.historyLoading = false
|
||
if (res.IsSuccess && res.Result.length > 0) {
|
||
var i = this.historyList.findIndex(item => item.Id === this.currentQCRow.Id)
|
||
if (i > -1) {
|
||
this.currentQCRow = Object.assign(this.historyList[i], res.Result[0])
|
||
}
|
||
}
|
||
}).catch(() => { this.historyLoading = false })
|
||
},
|
||
// 关闭质疑
|
||
handleCloseQuestion() {
|
||
this.$refs['closeQuestionForm'].validate((valid) => {
|
||
if (!valid) return
|
||
this.closeBtnLoading = true
|
||
if (this.closeQuestionForm.Type === 1) {
|
||
// 问题已解决
|
||
this.closeQuestionForm.Reason = this.$t('trials:qcQuality:message:problemSolved')
|
||
} else if (this.closeQuestionForm.Type === 2) {
|
||
// 问题无法解决强制关闭质疑,已提醒中心下次注意
|
||
this.closeQuestionForm.Reason = `${this.$t('trials:qcQuality:message:problemNotSolved')}<br/><br/>${this.$t('trials:consistencyCheck:label:closereason')}:${this.closeQuestionForm.Remake}`
|
||
}
|
||
var params = {
|
||
TrialId: this.data.TrialId,
|
||
QcChallengeId: this.closeQuestionForm.Id,
|
||
SubjectVisitId: this.data.Id,
|
||
CloseEnum: this.closeQuestionForm.Type,
|
||
CloseReason: this.closeQuestionForm.Reason
|
||
}
|
||
closeQCChallenge(params)
|
||
.then(res => {
|
||
this.closeBtnLoading = false
|
||
if (res.IsSuccess) {
|
||
this.getHistoryInfo()
|
||
this.$message.success(this.$t('trials:qcQuality:message:closedSuccessfully'))
|
||
this.closeQuestionVisible = false
|
||
this.relationInfo.NotClosedChallengeCount--
|
||
}
|
||
}).catch(() => {
|
||
this.closeBtnLoading = false
|
||
})
|
||
})
|
||
},
|
||
// 打开关闭质疑框并初始化
|
||
handleCloseQC(row) {
|
||
this.closeQuestionForm = Object.assign(this.closeQuestionForm, row)
|
||
this.closeQuestionForm.CurrentQCType = this.currentQCType
|
||
this.closeQuestionForm.AuditState = this.data.AuditState
|
||
this.closeQuestionForm.TrialQCProcess = this.data.QCProcessEnum
|
||
this.closeQuestionForm.Type = null
|
||
this.closeQuestionForm.Reason = ''
|
||
this.closeQuestionForm.Remake = ''
|
||
this.closeQuestionVisible = true
|
||
},
|
||
// 打开质疑记录弹窗
|
||
handleQCInfo(row) {
|
||
this.currentQCRow = { ...row }
|
||
this.chatVisible = true
|
||
},
|
||
changeReadingStatus(callback, row) {
|
||
let statusStr = ''
|
||
if (callback) {
|
||
statusStr = this.$t('trials:audit:label:setSeriesReading')
|
||
row.IsReading = false
|
||
} else {
|
||
statusStr = this.$t('trials:audit:label:setSeriesNotReading')
|
||
row.IsReading = true
|
||
}
|
||
var message = this.$t('trials:audit:message:changeSeriesStatus').replace('xxx', statusStr)
|
||
this.$confirm(message, {
|
||
distinguishCancelAndClose: true,
|
||
type: 'warning'
|
||
}).then(() => {
|
||
const state = row.IsReading ? 1 : 2
|
||
this.loading = true
|
||
setSeriesStatus(this.trialId, this.data.Id, row.StudyId, row.Id, state).then(res => {
|
||
this.loading = false
|
||
if (res.IsSuccess) {
|
||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||
this.getStudyInfo()
|
||
}
|
||
}).catch(() => { this.loading = false })
|
||
}).catch(() => {})
|
||
},
|
||
changeDeleteStatus(callback, row) {
|
||
let statusStr = ''
|
||
if (callback) {
|
||
statusStr = this.$t('trials:audit:label:setSeriesDeleted')
|
||
row.IsDeleted = false
|
||
} else {
|
||
statusStr = this.$t('trials:audit:label:setSeriesNotDelete')
|
||
row.IsDeleted = true
|
||
}
|
||
var message = this.$t('trials:audit:message:changeSeriesStatus').replace('xxx', statusStr)
|
||
this.$confirm(message, {
|
||
distinguishCancelAndClose: true,
|
||
type: 'warning'
|
||
}).then(() => {
|
||
const state = row.IsDeleted ? 5 : 4
|
||
this.loading = true
|
||
setSeriesStatus(this.trialId, this.data.Id, row.StudyId, row.Id, state).then(res => {
|
||
this.loading = false
|
||
if (res.IsSuccess) {
|
||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||
this.getStudyInfo()
|
||
}
|
||
}).catch(() => { this.loading = false })
|
||
}).catch(() => {})
|
||
},
|
||
receiveMsg(event) {
|
||
if (event.data.type === 'refreshSeriesList') {
|
||
this.getStudyInfo()
|
||
}
|
||
},
|
||
// 刷新检查新
|
||
getStudyInfo() {
|
||
this.loading = true
|
||
getVisitQCStudyAndSeriesList(this.data.Id).then(res => {
|
||
this.loading = false
|
||
this.studyList = res.Result.StudyList
|
||
this.seriesList = res.Result.SeriesList
|
||
}).catch(() => { this.loading = false })
|
||
},
|
||
// 设置qc通过/不通过
|
||
async handleQCState(auditState) {
|
||
if (auditState === 7) {
|
||
this.signCode = this.getSignCode(auditState)
|
||
this.signVisible = true
|
||
this.auditState = auditState
|
||
return
|
||
}
|
||
if (auditState === 8) {
|
||
var isgo = true
|
||
var isgoList = []
|
||
this.studyList.forEach(v => {
|
||
if (!v.BodyPartForEdit) {
|
||
isgo = false
|
||
isgoList.push(v.StudyCode)
|
||
}
|
||
})
|
||
if (!isgo) {
|
||
this.$message.error(`请补充检查${isgoList.toString()}的检查部位!`)
|
||
return
|
||
}
|
||
}
|
||
this.loading = true
|
||
var isVerify = await this.handleSave(true)
|
||
if (!isVerify) {
|
||
return
|
||
}
|
||
// 验证是否关闭所有质疑
|
||
verifyCanQCPassedOrFailed(this.trialId, this.data.Id).then(res => {
|
||
this.loading = false
|
||
if (res.IsSuccess) {
|
||
this.signCode = this.getSignCode(auditState)
|
||
this.signVisible = true
|
||
this.auditState = auditState
|
||
}
|
||
}).catch(() => { this.loading = false })
|
||
},
|
||
getSignCode(auditState) {
|
||
if (this.relationInfo.TrialQCProcessEnum === 1 && auditState === 8) {
|
||
// 单审通过
|
||
const { QCSingleReviewPassed } = const_.processSignature
|
||
return QCSingleReviewPassed
|
||
} else if (this.relationInfo.TrialQCProcessEnum === 1 && auditState === 7) {
|
||
// 单审不通过
|
||
const { QCSingleReviewFailed } = const_.processSignature
|
||
return QCSingleReviewFailed
|
||
} else if (this.relationInfo.TrialQCProcessEnum === 2 && auditState === 8 && this.currentQCType === 1) {
|
||
// 初审通过
|
||
const { PreliminaryReviewOfQCPassed } = const_.processSignature
|
||
return PreliminaryReviewOfQCPassed
|
||
} else if (this.relationInfo.TrialQCProcessEnum === 2 && auditState === 7 && this.currentQCType === 1) {
|
||
// 初审不通过
|
||
const { PreliminaryReviewOfQCFailed } = const_.processSignature
|
||
return PreliminaryReviewOfQCFailed
|
||
} else if (this.relationInfo.TrialQCProcessEnum === 2 && auditState === 8 && this.currentQCType === 2) {
|
||
// 复审通过
|
||
const { SecondaryReviewOfQCPassed } = const_.processSignature
|
||
return SecondaryReviewOfQCPassed
|
||
} else if (this.relationInfo.TrialQCProcessEnum === 2 && auditState === 7 && this.currentQCType === 2) {
|
||
// 复审不通过
|
||
const { SecondaryReviewOfQCFailed } = const_.processSignature
|
||
return SecondaryReviewOfQCFailed
|
||
}
|
||
},
|
||
// 关闭签名框
|
||
closeSignDialog(isSign, signInfo) {
|
||
if (isSign) {
|
||
this.setQCStatus(signInfo)
|
||
} else {
|
||
this.signVisible = false
|
||
}
|
||
},
|
||
// 设置qc审核状态
|
||
async setQCStatus(signInfo) {
|
||
this.loading = true
|
||
var params = {
|
||
data: {
|
||
TrialId: this.trialId,
|
||
SubjectVisitId: this.data.Id,
|
||
AuditState: this.auditState
|
||
},
|
||
signInfo: signInfo
|
||
}
|
||
qCPassedOrFailed(params).then(res => {
|
||
this.loading = false
|
||
if (res.IsSuccess) {
|
||
this.$refs['signForm'].btnLoading = false
|
||
this.signVisible = false
|
||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||
// this.getQCInfo()
|
||
this.isAudit = true
|
||
this.$forceUpdate()
|
||
// 更新QC审核列表
|
||
this.$emit('getList')
|
||
|
||
this.getNextQCInfo()
|
||
}
|
||
}).catch(() => {
|
||
this.loading = false
|
||
this.$refs['signForm'].btnLoading = false
|
||
})
|
||
},
|
||
getNextQCInfo() {
|
||
// '是否确认进入下一个医学审核任务?' : '当前医学审核任务未完成,是否确认进入下一个医学审核任务?'
|
||
var message = '是否确认进入下一个指控任务?'
|
||
|
||
this.$confirm(message, {
|
||
type: 'warning',
|
||
distinguishCancelAndClose: true
|
||
})
|
||
.then(() => {
|
||
this.loading = true
|
||
this.$emit('nextTask')
|
||
})
|
||
.catch(action => {
|
||
this.loading = false
|
||
})
|
||
},
|
||
// 设置已删除序列行样式
|
||
tableRowClassName({ row, rowIndex }) {
|
||
if (row.IsDeleted) {
|
||
return 'delete-row'
|
||
} else {
|
||
return ''
|
||
}
|
||
},
|
||
// 打开检查信息编辑框
|
||
handleEditStudy(row) {
|
||
this.editStudyInfoVisible = true
|
||
this.studyForm = { ...row }
|
||
var bodyPart = []
|
||
if (this.studyForm.BodyPartForEdit.indexOf('|') !== -1) {
|
||
bodyPart = this.studyForm.BodyPartForEdit.split('|')
|
||
} else if (this.studyForm.BodyPartForEdit !== '') {
|
||
bodyPart.push(this.studyForm.BodyPartForEdit)
|
||
}
|
||
this.$set(this.studyForm, 'Modality', row.ModalityForEdit)
|
||
// this.studyForm.Modality = row.ModalityForEdit
|
||
this.studyForm.BodyPartForEdit = bodyPart
|
||
},
|
||
// 更新拍片部位/拍片类型信息
|
||
handleUpdateStudyInfo() {
|
||
this.$refs['studyForm'].validate((valid) => {
|
||
if (!valid) return
|
||
this.btnLoading = true
|
||
this.studyForm.BodyPart = this.studyForm.BodyPartForEdit.join('|')
|
||
// this.studyForm.Modality = this.studyForm.Modalities
|
||
var params = {
|
||
id: this.studyForm.StudyId,
|
||
subjectVisitId: this.data.Id,
|
||
type: 1,
|
||
modality: this.studyForm.Modality,
|
||
bodyPart: this.studyForm.BodyPart
|
||
}
|
||
updateModality(this.data.TrialId, params).then(res => {
|
||
this.btnLoading = false
|
||
if (res.IsSuccess) {
|
||
this.getStudyInfo()
|
||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||
this.editStudyInfoVisible = false
|
||
}
|
||
}).catch(() => { this.btnLoading = false })
|
||
})
|
||
},
|
||
// 设置重传时刷新历史质疑列表及影响指控列表
|
||
refreshList() {
|
||
// 如果是复审时候设置重传,需要将当前审核状态设置为初审,且刷新页面数据并关闭历史质疑和质疑记录窗口
|
||
if (this.currentQCType === 2) {
|
||
this.currentQCType = 1
|
||
// this.getQCInfo()
|
||
this.getHistoryInfo()
|
||
} else {
|
||
// 如果是初审时候设置重传,不影响
|
||
this.getHistoryInfo()
|
||
}
|
||
this.$emit('getList')
|
||
},
|
||
|
||
// 打开非Dicom信息编辑框
|
||
handleEditNoneDicomInfo(row) {
|
||
const { CodeView, Id, BodyPart, Modality, ImageDate } = { ...row }
|
||
this.noneDicomForm.CodeView = CodeView
|
||
this.noneDicomForm.Id = Id
|
||
this.noneDicomForm.BodyPart = BodyPart
|
||
this.noneDicomForm.Modality = Modality
|
||
this.noneDicomForm.ImageDate = ImageDate
|
||
this.noneDicomForm.BodyParts = BodyPart.split(', ')
|
||
this.editNoneDicomVisible = true
|
||
},
|
||
// 更新非Dicom部位/拍片类型信息
|
||
handleUpdateNoneDicomInfo() {
|
||
this.$refs.noneDicomForm.validate(valid => {
|
||
if (!valid) return
|
||
this.btnLoading = true
|
||
this.noneDicomForm.BodyPart = this.noneDicomForm.BodyParts.join(', ')
|
||
this.noneDicomForm.TrialId = this.trialId
|
||
this.noneDicomForm.SiteId = this.data.SiteId
|
||
this.noneDicomForm.SubjectId = this.data.SubjectId
|
||
this.noneDicomForm.SubjectVisitId = this.data.Id
|
||
addOrUpdateNoneDicomStudy(this.noneDicomForm).then(res => {
|
||
this.btnLoading = false
|
||
if (res.IsSuccess) {
|
||
this.getNoneDicomList()
|
||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||
this.editNoneDicomVisible = false
|
||
}
|
||
}).catch(() => {
|
||
this.btnLoading = false
|
||
})
|
||
})
|
||
},
|
||
// 获取非Dicom检查信息
|
||
getNoneDicomList() {
|
||
this.loading = true
|
||
getNoneDicomStudyList(this.data.Id).then(res => {
|
||
this.noneDicomStudyList = res.Result
|
||
this.loading = false
|
||
}).catch(() => { this.loading = false })
|
||
},
|
||
// 预览文件
|
||
previewFile(row) {
|
||
// window.open(row.FullFilePath, '_blank')
|
||
this.imgObj.url = row.FullFilePath
|
||
this.imgObj.loading = true
|
||
this.imgObj.visible = true
|
||
},
|
||
// 预览所有影像
|
||
handleViewImages() {
|
||
var token = getToken()
|
||
const routeData = this.$router.resolve({
|
||
path: `/showvisitdicoms?trialId=${this.data.TrialId}&visitInfo=${this.data.VisitName}(${this.data.VisitNum})&subjectVisitId=${this.data.Id}&showDelete=${this.isAudit ? 0 : 1}&TokenKey=${token}`
|
||
})
|
||
window.open(routeData.href, '_blank')
|
||
},
|
||
// 预览阅片影像
|
||
handleViewReadingImages() {
|
||
var token = getToken()
|
||
const routeData = this.$router.resolve({
|
||
path: `/showvisitdicoms?trialId=${this.data.TrialId}&visitInfo=${this.data.VisitName}(${this.data.VisitNum})&subjectVisitId=${this.data.Id}&isReading=1&TokenKey=${token}`
|
||
})
|
||
window.open(routeData.href, '_blank')
|
||
},
|
||
// 预览某个检查
|
||
handlePreviewStudy(row) {
|
||
var token = getToken()
|
||
const routeData = this.$router.resolve({
|
||
path: `/showdicom?trialId=${this.trialId}&subjectVisitId=${this.data.Id}&studyId=${row.StudyId}&showDelete=${this.isAudit ? 0 : 1}&TokenKey=${token}&type=Study`
|
||
})
|
||
window.open(routeData.href, '_blank')
|
||
},
|
||
// 预览某个序列
|
||
handlePreviewInstance(row) {
|
||
var token = getToken()
|
||
const routeData = this.$router.resolve({
|
||
path: `/showdicom?trialId=${this.trialId}&studyId=${row.StudyId}&studyCode=${row.StudyCode}&modality=${row.Modality}&description=${row.Description}&seriesId=${row.Id}&seriesNumber=${row.SeriesNumber}&showDelete=${this.isAudit ? 0 : 1}&subjectVisitId=${this.data.Id}&TokenKey=${token}&type=Series`
|
||
})
|
||
this.open = window.open(routeData.href, '_blank')
|
||
},
|
||
// 预览所有检查下非Dicom文件
|
||
handleViewAllNoneDicoms() {
|
||
// this.previewAllNoneDicomVisible = true
|
||
var token = getToken()
|
||
const routeData = this.$router.resolve({
|
||
path: `/showNoneDicoms?subjectVisitId=${this.data.Id}&TokenKey=${token}`
|
||
})
|
||
window.open(routeData.href, '_blank')
|
||
},
|
||
// 预览单个检查下非Dicom文件
|
||
handlePreviewNoneDicomFiles(row) {
|
||
var token = getToken()
|
||
const routeData = this.$router.resolve({
|
||
path: `/showNoneDicoms?subjectVisitId=${this.data.Id}&studyId=${row.Id}&TokenKey=${token}`
|
||
})
|
||
window.open(routeData.href, '_blank')
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
<style lang="scss" scoped>
|
||
.qa-wrapper{
|
||
display: flex;
|
||
flex-flow: column;
|
||
height: 100%;
|
||
border: 1px solid #fff;
|
||
padding: 10px;
|
||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||
.function-wrapper{
|
||
text-align: right;
|
||
}
|
||
.qa-content{
|
||
flex: 1;
|
||
margin-top: 10px;
|
||
overflow-y: auto;
|
||
}
|
||
>>>.delete-row{
|
||
text-decoration-line: line-through;
|
||
color: #c0c4cc;
|
||
}
|
||
>>>.el-card{
|
||
padding: 10px;
|
||
}
|
||
}
|
||
</style>
|