在影像质控完成后,可以更正影像检查的基本信息,并且需要签名
continuous-integration/drone/push Build is passing Details

main
wangxiaoshuang 2025-07-31 16:09:44 +08:00
parent d911d55129
commit 5a8ec13c2f
4 changed files with 194 additions and 35 deletions

View File

@ -4205,3 +4205,19 @@ export function getExportSubjectVisitImageList(data) {
data data
}) })
} }
// 影像质控-更正dicom
export function updateDicomStudyInfo(data) {
return request({
url: `/Inspection/QCOperation/UpdateDicomStudyInfo`,
method: 'post',
data
})
}
// 影像质控-更正非dicom
export function updateNoneDicomStudy(data) {
return request({
url: `/Inspection/NoneDicomStudy/UpdateNoneDicomStudy`,
method: 'post',
data
})
}

View File

@ -32,7 +32,7 @@ export default {
ResetImageQualityControlQuestion: 112, // ResetImageQualityControlQuestion: 112, //
CreateReviewTask: 113, // CreateReviewTask: 113, //
ReviewImageQualityControlQuestion: 219, // ReviewImageQualityControlQuestion: 219, //
CorrectImageExaminationInformation: 220, //
}, },
}; };
</script> </script>

View File

@ -129,7 +129,7 @@
<!-- 上传时间 --> <!-- 上传时间 -->
<el-table-column prop="UploadedTime" :label="$t('trials:audit:table:seriesOfUploadedDate')" <el-table-column prop="UploadedTime" :label="$t('trials:audit:table:seriesOfUploadedDate')"
min-width="120" sortable show-overflow-tooltip /> min-width="120" sortable show-overflow-tooltip />
<el-table-column :label="$t('common:action:action')"> <el-table-column :label="$t('common:action:action')" min-width="160">
<template slot-scope="scope"> <template slot-scope="scope">
<!-- 预览 --> <!-- 预览 -->
<el-button icon="el-icon-view" :title="$t('trials:audit:action:preview')" circle <el-button icon="el-icon-view" :title="$t('trials:audit:action:preview')" circle
@ -145,6 +145,9 @@
scope.row.Modalities scope.row.Modalities
) && IsHaveStudyClinicalData ) && IsHaveStudyClinicalData
" circle :disabled="scope.row.IsDeleted" @click="handlePreviewClinicalData(scope.row)" /> " circle :disabled="scope.row.IsDeleted" @click="handlePreviewClinicalData(scope.row)" />
<!-- 质控后编辑 -->
<el-button icon="el-icon-edit" :title="$t('trials:audit:action:Correction')" circle
v-if="isAuditToEdit" @click="handleEditStudy(scope.row)" />
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -354,7 +357,7 @@
:inactive-text="$fd('YesOrNo', false)" /> :inactive-text="$fd('YesOrNo', false)" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column :label="$t('common:action:action')"> <el-table-column :label="$t('common:action:action')" min-width="160">
<template slot-scope="scope"> <template slot-scope="scope">
<!-- 预览 --> <!-- 预览 -->
<el-button icon="el-icon-view" :title="$t('trials:audit:button:nonDicomsPreview')" circle <el-button icon="el-icon-view" :title="$t('trials:audit:button:nonDicomsPreview')" circle
@ -365,6 +368,9 @@
<el-button icon="el-icon-edit-outline" :title="$t('trials:audit:button:nonDicomsEdit')" circle <el-button icon="el-icon-edit-outline" :title="$t('trials:audit:button:nonDicomsEdit')" circle
:disabled="isAudit || SecondReviewState > 0" :disabled="isAudit || SecondReviewState > 0"
@click.native.prevent="handleEditNoneDicomInfo(scope.row)" /> @click.native.prevent="handleEditNoneDicomInfo(scope.row)" />
<!-- 质控后编辑 -->
<el-button icon="el-icon-edit" :title="$t('trials:audit:action:Correction')" circle
v-if="isAuditToEdit" @click="handleEditNoneDicomInfo(scope.row)" />
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -633,18 +639,28 @@
</el-checkbox-group> </el-checkbox-group>
</el-form-item> </el-form-item>
<!-- 序列数量 --> <!-- 序列数量 -->
<el-form-item :label="$t('trials:audit:table:seriesCount')"> <el-form-item :label="$t('trials:audit:table:seriesCount')" v-if="!isAuditToEdit">
<el-input v-model="studyForm.SeriesCount" disabled /> <el-input v-model="studyForm.SeriesCount" disabled />
</el-form-item> </el-form-item>
<!-- 图像数量 --> <!-- 图像数量 -->
<el-form-item v-if="studyForm.InstanceCount" :label="$t('trials:audit:table:instanceCount')"> <el-form-item v-if="studyForm.InstanceCount && !isAuditToEdit"
:label="$t('trials:audit:table:instanceCount')">
<el-input v-model="studyForm.InstanceCount" disabled /> <el-input v-model="studyForm.InstanceCount" disabled />
</el-form-item> </el-form-item>
<!-- 检查日期 --> <!-- 检查日期 -->
<el-form-item :label="$t('trials:audit:table:studyDate')"> <el-form-item :label="$t('trials:audit:table:studyDate')" v-if="!isAuditToEdit">
<el-date-picker v-model="studyForm.StudyTime" disabled type="date" value-format="yyyy-MM-dd" <el-date-picker v-model="studyForm.StudyTime" disabled type="date" value-format="yyyy-MM-dd"
format="yyyy-MM-dd" style="width: 100%" /> format="yyyy-MM-dd" style="width: 100%" />
</el-form-item> </el-form-item>
<!-- 修改原因 -->
<el-form-item v-if="isAuditToEdit" :label="$t('trials:audit:table:Reason')" prop="ModifyReason" :rules="[
{
required: true,
message: $t('common:ruleMessage:specify'),
trigger: 'blur',
}]">
<el-input v-model="studyForm.ModifyReason" type="textarea" />
</el-form-item>
</el-form> </el-form>
</div> </div>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
@ -730,10 +746,29 @@
</el-checkbox-group> </el-checkbox-group>
</el-form-item> </el-form-item>
<!-- 检查日期 --> <!-- 检查日期 -->
<el-form-item :label="$t('trials:audit:table:nonDicomsStudyDate')" prop="ImageDate"> <el-form-item :label="$t('trials:audit:table:nonDicomsStudyDate')" prop="ImageDate" :rules="[
{
required: true,
message: $t('common:ruleMessage:specify'),
trigger: 'blur',
}]" v-if="isAuditToEdit">
<el-date-picker v-model="noneDicomForm.ImageDate" type="date" :picker-options="pickerOption"
value-format="yyyy-MM-dd" format="yyyy-MM-dd" style="width: 100%" />
</el-form-item>
<!-- 检查日期 -->
<el-form-item :label="$t('trials:audit:table:nonDicomsStudyDate')" prop="ImageDate" v-else>
<el-date-picker v-model="noneDicomForm.ImageDate" disabled type="date" :picker-options="pickerOption" <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%" /> value-format="yyyy-MM-dd" format="yyyy-MM-dd" style="width: 100%" />
</el-form-item> </el-form-item>
<!-- 修改原因 -->
<el-form-item v-if="isAuditToEdit" :label="$t('trials:audit:table:Reason')" prop="ModifyReason" :rules="[
{
required: true,
message: $t('common:ruleMessage:specify'),
trigger: 'blur',
}]">
<el-input v-model="noneDicomForm.ModifyReason" type="textarea" />
</el-form-item>
</el-form> </el-form>
</div> </div>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
@ -882,7 +917,9 @@ import {
updateModality, updateModality,
getQCChallengeDialogList, getQCChallengeDialogList,
replaceQCTaskActionUser, replaceQCTaskActionUser,
getTrialUserRoleList getTrialUserRoleList,
updateNoneDicomStudy,
updateDicomStudyInfo
} from '@/api/trials' } from '@/api/trials'
import { qCPassedOrFailed } from '@/api/trials/visit' import { qCPassedOrFailed } from '@/api/trials/visit'
import { getBasicDataSelects } from '@/api/dictionary/dictionary' import { getBasicDataSelects } from '@/api/dictionary/dictionary'
@ -924,12 +961,19 @@ export default {
SecondReviewState: { SecondReviewState: {
type: Number, type: Number,
default: 0, default: 0,
},
auditorId: {
type: String,
default: ''
} }
}, },
computed: { computed: {
isEN() { isEN() {
return this.$i18n.locale !== 'zh' return this.$i18n.locale !== 'zh'
}, },
isAuditToEdit() {
return this.isAudit && this.auditorId === this.userId
}
}, },
data() { data() {
return { return {
@ -963,6 +1007,7 @@ export default {
BodyPartForEdit: [], BodyPartForEdit: [],
SeriesCount: null, SeriesCount: null,
StudyTime: '', StudyTime: '',
ModifyReason: ''
}, },
currentQCRow: {}, currentQCRow: {},
isAudit: false, // isAudit: false, //
@ -981,6 +1026,7 @@ export default {
Modality: '', Modality: '',
ImageDate: '', ImageDate: '',
StudyName: '', StudyName: '',
ModifyReason: ''
}, },
subjectClinicalData: {}, subjectClinicalData: {},
moment, moment,
@ -1035,7 +1081,8 @@ export default {
secondReviewList: [], secondReviewList: [],
secondReviewActiveName: null, secondReviewActiveName: null,
SecondReviewTime: '', SecondReviewTime: '',
IsSecondPass: false IsSecondPass: false,
userId: zzSessionStorage.getItem('userId'),
} }
}, },
async mounted() { async mounted() {
@ -1935,7 +1982,17 @@ export default {
// //
closeSignDialog(isSign, signInfo) { closeSignDialog(isSign, signInfo) {
if (isSign) { if (isSign) {
this.setQCStatus(signInfo) if (this.isAuditToEdit) {
if (this.editStudyInfoVisible) {
// dicom
this.updateDicomStudyInfo(signInfo)
} else if (this.editNoneDicomVisible) {
// dicom
this.updateNoneDicomStudy(signInfo)
}
} else {
this.setQCStatus(signInfo)
}
} else { } else {
this.signVisible = false this.signVisible = false
} }
@ -2045,6 +2102,7 @@ export default {
this.$set(this.studyForm, 'Modality', row.ModalityForEdit) this.$set(this.studyForm, 'Modality', row.ModalityForEdit)
// this.studyForm.Modality = row.ModalityForEdit // this.studyForm.Modality = row.ModalityForEdit
this.studyForm.BodyPartForEdit = bodyPart this.studyForm.BodyPartForEdit = bodyPart
this.$set(this.studyForm, 'ModifyReason', '')
}, },
// / // /
handleUpdateStudyInfo() { handleUpdateStudyInfo() {
@ -2061,20 +2119,58 @@ export default {
bodyPart: this.studyForm.BodyPart, bodyPart: this.studyForm.BodyPart,
StudyName: this.studyForm.StudyName, StudyName: this.studyForm.StudyName,
} }
updateModality(this.data.TrialId, params) if (this.isAuditToEdit) {
.then((res) => { const { CorrectImageExaminationInformation } = const_.processSignature
this.btnLoading = false this.signCode = CorrectImageExaminationInformation
if (res.IsSuccess) { this.signVisible = true
this.getStudyInfo() } else {
this.$message.success(this.$t('common:message:savedSuccessfully')) updateModality(this.data.TrialId, params)
this.editStudyInfoVisible = false .then((res) => {
} this.btnLoading = false
}) if (res.IsSuccess) {
.catch(() => { this.getStudyInfo()
this.btnLoading = false this.$message.success(this.$t('common:message:savedSuccessfully'))
}) this.editStudyInfoVisible = false
}
})
.catch(() => {
this.btnLoading = false
})
}
}) })
}, },
// dicom
async updateDicomStudyInfo(signInfo) {
try {
this.loading = true
let data = {
data: {
Id: this.studyForm.StudyId,
SubjectVisitId: this.data.Id,
StudyName: this.studyForm.StudyName,
ModifyReason: this.studyForm.ModifyReason,
Modality: this.studyForm.Modality,
BodyPart: this.studyForm.BodyPart,
},
signInfo
}
let res = await updateDicomStudyInfo(data)
this.loading = false
this.btnLoading = false
this.signVisible = false
if (res.IsSuccess) {
this.getStudyInfo()
this.$message.success(this.$t('common:message:savedSuccessfully'))
this.editStudyInfoVisible = false
}
} catch (err) {
console.log(err)
this.btnLoading = false
this.loading = false
this.signVisible = false
}
},
// //
refreshList() { refreshList() {
// //
@ -2101,6 +2197,7 @@ export default {
this.noneDicomForm.Modality = Modality this.noneDicomForm.Modality = Modality
this.noneDicomForm.ImageDate = ImageDate this.noneDicomForm.ImageDate = ImageDate
this.noneDicomForm.BodyParts = BodyPart.split(', ') this.noneDicomForm.BodyParts = BodyPart.split(', ')
this.noneDicomForm.ModifyReason = null
this.editNoneDicomVisible = true this.editNoneDicomVisible = true
}, },
// Dicom/ // Dicom/
@ -2113,20 +2210,57 @@ export default {
this.noneDicomForm.TrialSiteId = this.data.TrialSiteId this.noneDicomForm.TrialSiteId = this.data.TrialSiteId
this.noneDicomForm.SubjectId = this.data.SubjectId this.noneDicomForm.SubjectId = this.data.SubjectId
this.noneDicomForm.SubjectVisitId = this.data.Id this.noneDicomForm.SubjectVisitId = this.data.Id
addOrUpdateNoneDicomStudy(this.noneDicomForm) if (this.isAuditToEdit) {
.then((res) => { const { CorrectImageExaminationInformation } = const_.processSignature
this.btnLoading = false this.signCode = CorrectImageExaminationInformation
if (res.IsSuccess) { this.signVisible = true
this.getNoneDicomList() } else {
this.$message.success(this.$t('common:message:savedSuccessfully')) addOrUpdateNoneDicomStudy(this.noneDicomForm)
this.editNoneDicomVisible = false .then((res) => {
} this.btnLoading = false
}) if (res.IsSuccess) {
.catch(() => { this.getNoneDicomList()
this.btnLoading = false this.$message.success(this.$t('common:message:savedSuccessfully'))
}) this.editNoneDicomVisible = false
}
})
.catch(() => {
this.btnLoading = false
})
}
}) })
}, },
// dicom
async updateNoneDicomStudy(signInfo) {
try {
this.loading = true
let data = {
data: {
Id: this.noneDicomForm.Id,
SubjectVisitId: this.data.Id,
StudyName: this.noneDicomForm.StudyName,
ModifyReason: this.noneDicomForm.ModifyReason,
Modality: this.noneDicomForm.Modality,
BodyPart: this.noneDicomForm.BodyParts.join(', '),
},
signInfo
}
let res = await updateNoneDicomStudy(data)
this.loading = false
this.btnLoading = false
this.signVisible = false
if (res.IsSuccess) {
this.getNoneDicomList()
this.$message.success(this.$t('common:message:savedSuccessfully'))
this.editNoneDicomVisible = false
}
} catch (err) {
console.log(err)
this.btnLoading = false
this.loading = false
this.signVisible = false
}
},
// Dicom // Dicom
getNoneDicomList() { getNoneDicomList() {
this.loading = true this.loading = true

View File

@ -478,7 +478,8 @@
<div class="qc-dialog-body"> <div class="qc-dialog-body">
<quality-assurance v-if="qcVisible" :data="rowData" :disabled="rowData.disabled ? rowData.disabled : false" <quality-assurance v-if="qcVisible" :data="rowData" :disabled="rowData.disabled ? rowData.disabled : false"
:SecondReviewState="rowData.SecondReviewState" :q-type="rowData.qcType ? rowData.qcType : 1" :SecondReviewState="rowData.SecondReviewState" :q-type="rowData.qcType ? rowData.qcType : 1"
@getList="getList" @nextTask="nextTask" @openManuals="openManuals" @close="qcVisible = false" /> :auditorId="auditorId" @getList="getList" @nextTask="nextTask" @openManuals="openManuals"
@close="qcVisible = false" />
</div> </div>
</el-dialog> </el-dialog>
<!-- 手册 --> <!-- 手册 -->
@ -692,12 +693,18 @@ export default {
isFullscreen: false, isFullscreen: false,
timeList: [], timeList: [],
exportLoading: false, exportLoading: false,
auditorId: null
} }
}, },
watch: { watch: {
list(val) { list(val) {
this.doLayout() this.doLayout()
}, },
qcVisible() {
if (!this.qcVisible) {
this.auditorId = null
}
}
}, },
mounted() { mounted() {
this.query = this.$route.query this.query = this.$route.query
@ -889,12 +896,14 @@ export default {
this.rowData.disabled = true this.rowData.disabled = true
this.rowData.qcType = 1 this.rowData.qcType = 1
this.qcVisible = true this.qcVisible = true
this.auditorId = row.PreliminaryAuditUserId
}, },
handleViewReviewQC(row) { handleViewReviewQC(row) {
this.rowData = { ...row } this.rowData = { ...row }
this.rowData.disabled = true this.rowData.disabled = true
this.rowData.qcType = 2 this.rowData.qcType = 2
this.qcVisible = true this.qcVisible = true
this.auditorId = row.ReviewAuditUserId
}, },
// //
handleViewImages() { handleViewImages() {