阅片前对影像进行靶段标注
continuous-integration/drone/push Build encountered an error Details

uat
wangxiaoshuang 2025-11-19 15:51:10 +08:00
parent 64cec20d7d
commit 20c257be4f
7 changed files with 424 additions and 276 deletions

View File

@ -4282,3 +4282,12 @@ export function deleteAuditRecord(auditRecordId) {
method: 'delete'
})
}
// 靶段标注列表
export function getTrialSubjectVisitMarkList(data) {
return request({
url: `/DownloadAndUpload/getTrialSubjectVisitMarkList`,
method: 'post',
data
})
}

View File

@ -34,9 +34,12 @@
<!--受试者-->
<el-table-column :label="$t('download:table:subjectCode')" min-width="130" prop="SubjectCode"
show-overflow-tooltip />
<!--访视名称-->
<el-table-column prop="VisitName" :label="$t('download:table:VisitName')" sortable="custom"
v-if="IsImageSegment" />
<!--任务名称-->
<el-table-column :label="$t('download:table:taskName')" min-width="130" show-overflow-tooltip prop="TaskBlindName"
sortable />
sortable v-else />
<!--检查类型-->
<el-table-column :label="$t('download:table:studyType')" min-width="130" show-overflow-tooltip prop="IsDicom"
sortable>
@ -126,6 +129,10 @@ export default {
return {}
},
},
IsImageSegment: {
type: Boolean,
default: false,
}
},
data() {
return {
@ -157,6 +164,7 @@ export default {
this.bodyPart.Bodypart = await this.$getBodyPart(this.$route.query.trialId)
this.getList()
this.title = `Download Images${this.SubjectCode}${this.Criterion.TrialReadingCriterionName}`
if (this.IsImageSegment) this.title = `Download Images${this.SubjectCode}`
},
beforeDestroy() {
store.dispatch('trials/setUnLock', false)
@ -175,6 +183,12 @@ export default {
if (this.TaskId) {
this.searchData.VisitTaskId = this.TaskId
}
if (this.IsImageSegment) {
this.searchData.IsImageSegmentLabel = true
}
else if (this.Criterion.CriterionType == 19 || this.Criterion.CriterionType == 20) {
this.searchData.IsImageSegmentLabel = false
}
this.loading = true
let res = await getSubjectImageDownloadSelectList(this.searchData)
this.loading = false
@ -257,6 +271,12 @@ export default {
data.NoneDicomStudyIdList = [...data.NoneDicomStudyIdList, ...arr]
}
}
if (this.IsImageSegment) {
data.IsImageSegmentLabel = true
}
else if (this.Criterion.CriterionType == 19 || this.Criterion.CriterionType == 20) {
data.IsImageSegmentLabel = false
}
this.btnLoading = true
let res = await getIRReadingDownloadStudyInfo(data)
this.btnLoading = false
@ -286,6 +306,9 @@ export default {
formatDownloadFile(list) {
let files = [],
name = `${list[0].SubjectCode}_${new Date().getTime()}.zip`
if (this.IsImageSegment) {
name = `${list[0].SubjectCode}_${list[0].VisitName}.zip`
} else {
if (this.IsReadingTaskViewInOrder === 1) {
name = `${list[0].SubjectCode}_${list[0].TaskBlindName}.zip`
}
@ -293,6 +316,8 @@ export default {
// name = `${list[0].TaskBlindName}.zip`
name = `${list[0].SubjectCode}_${list[0].TaskBlindName}.zip`
}
}
list.forEach((data) => {
if (data.StudyList && data.StudyList.length > 0) {
let StudyList = data.StudyList
@ -304,7 +329,14 @@ export default {
}/DICOMDIR`,
url: this.OSSclientConfig.basePath + study.StudyDIRPath,
}
if (this.IsReadingTaskViewInOrder === 0) {
if (this.IsImageSegment) {
obj = {
name: `${data.SubjectCode}/${data.VisitName
}/${this.$fd('IsDicom', true)}/${study.StudyCode
}/DICOMDIR`,
url: this.OSSclientConfig.basePath + study.StudyDIRPath,
}
} else if (this.IsReadingTaskViewInOrder === 0) {
obj = {
name: `${data.TaskBlindName}/${this.$fd(
'IsDicom',
@ -330,7 +362,15 @@ export default {
url: this.OSSclientConfig.basePath + instance.Path,
IsEncapsulated: instance.IsEncapsulated
}
if (this.IsReadingTaskViewInOrder === 0) {
if (this.IsImageSegment) {
obj = {
name: `${data.SubjectCode}/${data.VisitName
}/${this.$fd('IsDicom', true)}/${study.StudyCode
}/IMAGE/${fileName}`,
url: this.OSSclientConfig.basePath + instance.Path,
IsEncapsulated: instance.IsEncapsulated
}
} else if (this.IsReadingTaskViewInOrder === 0) {
obj = {
name: `${data.TaskBlindName}/${this.$fd(
'IsDicom',
@ -360,7 +400,16 @@ export default {
)}/${study.StudyCode}/${item.FileName}`,
url: this.OSSclientConfig.basePath + item.Path,
}
if (this.IsReadingTaskViewInOrder === 0) {
if (this.IsImageSegment) {
obj = {
name: `${data.SubjectCode}/${data.VisitName}/${this.$fd(
'IsDicom',
false
)}/${study.StudyCode}/${item.FileName}`,
url: this.OSSclientConfig.basePath + item.Path,
}
}
else if (this.IsReadingTaskViewInOrder === 0) {
obj = {
name: `${data.TaskBlindName}/${this.$fd(
'IsDicom',
@ -390,6 +439,9 @@ export default {
},
handleOpenDialog(item) {
this.model_cfg.title = `${item.SubjectCode || ''} > ${item.TaskBlindName}`
if (this.IsImageSegment) {
this.model_cfg.title = `${item.SubjectCode || ''} > ${item.VisitName}`
}
if (item.IsDicom) {
this.modelList = item.DicomStudyList
} else {

View File

@ -363,12 +363,17 @@ export default {
type: Number,
default: 0,
},
IsImageSegment: {
type: Boolean,
default: false,
}
},
components: {
'study-view': studyView,
},
data() {
return {
loading: false,
list: [],
StudyInstanceUidList: [],
SopInstanceUidList: [],
@ -439,6 +444,12 @@ export default {
if (this.TaskId) {
params.VisitTaskId = this.TaskId
}
if (this.IsImageSegment) {
this.searchData.IsImageSegmentLabel = true
}
else if (this.Criterion.CriterionType == 19 || this.Criterion.CriterionType == 20) {
this.searchData.IsImageSegmentLabel = false
}
this.loading = true
let res = await getSubjectImageUploadList(params)
this.loading = false
@ -536,6 +547,9 @@ export default {
if (this.VisitTaskId) {
data.VisitTaskId = this.VisitTaskId
}
if (this.IsImageSegment) {
data.IsImageSegmentLabel = true
}
let res = await verifyIRStudyAllowUpload(data)
if (res.IsSuccess) {
return res.Result
@ -562,8 +576,9 @@ export default {
confirmMessage = null
for (let i = 0; i < checkFiles.length; i++) {
let item = checkFiles[i]
var dicom = await parseDicom(item, 'StudyInstanceUid')
var dicom = await parseDicom(item, ['StudyInstanceUid', 'Modality'])
if (!dicom.StudyInstanceUid) continue
if (this.IsImageSegment && dicom.Modality !== 'US') continue
let has = true,
has2 = false,
has3 = false
@ -1153,6 +1168,16 @@ export default {
o.instanceUid +
params.trialId
)}`
if (this.IsImageSegment) {
path = `/${params.trialId}/Image/${params.subjectId
}/${params.subjectVisitId}/AnnotationImage/${dicomInfo.visitTaskId
}/${scope.getGuid(
dicomInfo.studyUid +
v.seriesUid +
o.instanceUid +
params.trialId
)}`
}
if (scope.isClose) return
let res = await dcmUpload(
{
@ -1186,6 +1211,9 @@ export default {
o.imageRows
)
let thumbnailPath = `/${params.trialId}/Image/${params.subjectId}/${params.subjectVisitId}/${dicomInfo.visitTaskId}/${dicomInfo.studyUid}/${v.seriesUid}.jpg`
if (this.IsImageSegment) {
thumbnailPath = `/${params.trialId}/Image/${params.subjectId}/${params.subjectVisitId}/AnnotationImage/${dicomInfo.visitTaskId}/${dicomInfo.studyUid}/${v.seriesUid}.jpg`
}
let OSSclient = scope.OSSclient
let seriesRes = await OSSclient.put(
thumbnailPath,
@ -1277,6 +1305,9 @@ export default {
let text = JSON.stringify(Record)
let logJsonBlob = scope.generateTxtFile(text)
let logJsonObjectName = `/${params.trialId}/Image/${params.subjectId}/${params.subjectVisitId}/${dicomInfo.visitTaskId}/${dicomInfo.studyUid}/${params.studyMonitorId}.txt`
if (this.IsImageSegment) {
logJsonObjectName = `/${params.trialId}/Image/${params.subjectId}/${params.subjectVisitId}/AnnotationImage/${dicomInfo.visitTaskId}/${dicomInfo.studyUid}/${params.studyMonitorId}.txt`
}
let logRes
try {
logRes = await scope.OSSclient.put(
@ -1305,6 +1336,9 @@ export default {
v.instanceList[0].imageRows
)
let thumbnailPath = `/${params.trialId}/Image/${params.subjectId}/${params.subjectVisitId}/${dicomInfo.studyUid}/${v.seriesUid}.jpg`
if (this.IsImageSegment) {
thumbnailPath = `/${params.trialId}/Image/${params.subjectId}/${params.subjectVisitId}/AnnotationImage/${dicomInfo.studyUid}/${v.seriesUid}.jpg`
}
let OSSclient = scope.OSSclient
try {
let seriesRes = await OSSclient.put(thumbnailPath, blob)
@ -1322,6 +1356,9 @@ export default {
if (scope.isClose) return false
console.log(params)
params.VisitTaskId = dicomInfo.visitTaskId
if (this.IsImageSegment) {
params.IsImageSegmentLabel = true
}
addOrUpdateArchiveTaskStudy(params)
.then((res) => {
if (dicomInfo.failedFileCount === dicomInfo.fileCount) {

View File

@ -1,40 +1,17 @@
<template>
<el-dialog
:visible.sync="visible"
:fullscreen="true"
:close-on-click-modal="false"
:before-close="beforeClose"
:append-to-body="true"
class="uploadDicomAndNonedicom"
>
<el-dialog :visible.sync="visible" :fullscreen="true" :close-on-click-modal="false" :before-close="beforeClose"
:append-to-body="true" class="uploadDicomAndNonedicom">
<span slot="title">{{ title }}</span>
<el-tabs type="border-card" v-model="activeName">
<el-tab-pane
:label="$t('uploadDicomAndNonedicom:label:dicom')"
name="dicom"
>
<dicomFile
v-if="activeName === 'dicom'"
:SubjectId="SubjectId"
:SubjectCode="SubjectCode"
:Criterion="Criterion"
:TaskId="VisitTaskId"
:isUpload.sync="isUpload"
:isReadingTaskViewInOrder="isReadingTaskViewInOrder"
/>
<el-tab-pane :label="$t('uploadDicomAndNonedicom:label:dicom')" name="dicom">
<dicomFile v-if="activeName === 'dicom'" :SubjectId="SubjectId" :SubjectCode="SubjectCode"
:Criterion="Criterion" :TaskId="VisitTaskId" :isUpload.sync="isUpload"
:isReadingTaskViewInOrder="isReadingTaskViewInOrder" :IsImageSegment="IsImageSegment" />
</el-tab-pane>
<el-tab-pane
:label="$t('uploadDicomAndNonedicom:label:nonedicom')"
name="nonedicom"
>
<nonedicomFile
v-if="activeName === 'nonedicom'"
:SubjectId="SubjectId"
:SubjectCode="SubjectCode"
:Criterion="Criterion"
:VisitTaskId="VisitTaskId"
:isUpload.sync="isUpload"
/>
<el-tab-pane :label="$t('uploadDicomAndNonedicom:label:nonedicom')" name="nonedicom">
<nonedicomFile v-if="activeName === 'nonedicom'" :SubjectId="SubjectId" :SubjectCode="SubjectCode"
:Criterion="Criterion" :VisitTaskId="VisitTaskId" :isUpload.sync="isUpload"
:IsImageSegment="IsImageSegment" />
</el-tab-pane>
</el-tabs>
</el-dialog>
@ -74,6 +51,10 @@ export default {
type: Number,
default: 0,
},
IsImageSegment: {
type: Boolean,
default: false,
}
},
data() {
return {
@ -84,6 +65,7 @@ export default {
},
mounted() {
this.title = `Upload Images${this.SubjectCode}${this.Criterion.TrialReadingCriterionName}`
if (this.IsImageSegment) this.title = `Upload Images${this.SubjectCode}`
store.dispatch('trials/setUnLock', true)
},
methods: {
@ -103,11 +85,13 @@ export default {
::v-deep.el-tabs--left .el-tabs__header.is-left {
margin-right: 0;
}
.uploadDicomAndNonedicom {
::v-deep.el-tabs--border-card > .el-tabs__header .el-tabs__item {
::v-deep.el-tabs--border-card>.el-tabs__header .el-tabs__item {
color: #909399;
}
::v-deep.el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active {
::v-deep.el-tabs--border-card>.el-tabs__header .el-tabs__item.is-active {
color: #428bca;
background-color: #fff;
border-right-color: #dcdfe6;

View File

@ -12,8 +12,11 @@
@sort-change="handleSortByColumn" :default-sort="{ prop: 'TaskBlindName', order: 'descending' }">
<!--受试者-->
<el-table-column prop="SubjectCode" :label="$t('upload:nonedicom:table:subject')" />
<!--访视名称-->
<el-table-column prop="VisitName" :label="$t('upload:nonedicom:table:VisitName')" sortable="custom"
v-if="IsImageSegment" />
<!--任务名称-->
<el-table-column prop="TaskBlindName" :label="$t('upload:nonedicom:table:taskName')" sortable="custom" />
<el-table-column prop="TaskBlindName" :label="$t('upload:nonedicom:table:taskName')" sortable="custom" v-else />
<!--检查类型-->
<el-table-column prop="Modality" :label="$t('upload:nonedicom:table:molityType')" sortable="custom">
</el-table-column>
@ -104,7 +107,7 @@
:title="$t('upload:nonedicom:button:preview')" @click.stop="handlePreviewNoneDicomFiles(scope.row)" />
<!--上传--->
<el-button circle icon="el-icon-upload2" :title="$t('upload:nonedicom:button:upload')"
@click.native.prevent="handleUpload(scope.row)" />
@click.native.prevent="handleUpload(scope.row)" v-if="scope.row.Modality !== 'IVUS'" />
<!--删除--->
<el-button :disabled="scope.row.UploadedFileCount <= 0 ||
scope.row.ReadingTaskState === 2
@ -248,6 +251,10 @@ export default {
type: Boolean,
default: false,
},
IsImageSegment: {
type: Boolean,
default: false,
},
},
data() {
return {
@ -311,6 +318,12 @@ export default {
if (this.VisitTaskId) {
this.searchData.VisitTaskId = this.VisitTaskId
}
if (this.IsImageSegment) {
this.searchData.IsImageSegmentLabel = true
}
else if (this.Criterion.CriterionType == 19 || this.Criterion.CriterionType == 20) {
this.searchData.IsImageSegmentLabel = false
}
this.loading = true
let res = await getIRUploadTaskNoneDicomStudyList(this.searchData)
this.loading = false
@ -534,9 +547,15 @@ export default {
let file = this.fileList.filter((item) => item.id === arr[index].id)[0]
file.status = 1
let path = `/${this.$route.query.trialId}/TaskImage/${this.currentRow.SubjectId
}/${this.currentRow.VisitTaskId}/${this.$guid()}${file.name
}/${this.currentRow.SourceSubjectVisitId}/${this.currentRow.VisitTaskId}/${this.$guid()}${file.name
.substring(file.name.lastIndexOf('.'))
.toLocaleLowerCase()}`
if (this.IsImageSegment) {
path = `/${this.$route.query.trialId}/TaskImage/${this.currentRow.SubjectId
}/${this.currentRow.SourceSubjectVisitId}/AnnotationImage/${this.currentRow.VisitTaskId}/${this.$guid()}${file.name
.substring(file.name.lastIndexOf('.'))
.toLocaleLowerCase()}`
}
file.curPath = path
const fileData = await this.fileToBlob(file.file)
let res = await this.fileToOss(path, fileData, file)
@ -620,6 +639,9 @@ export default {
params.RecordPath = RecordPath.path
params.FailedFileCount = RecordPath.Record.Failed.length
}
if (this.IsImageSegment) {
params.IsImageSegmentLabel = true
}
uploadNoneDicomFile(params)
.then((res) => {
if (!isReLoad) {
@ -658,7 +680,10 @@ export default {
})
let text = JSON.stringify(Record)
let logJsonBlob = this.generateTxtFile(text)
let logJsonObjectName = `/${this.$route.query.trialId}/TaskImage/${this.currentRow.SubjectId}/${this.currentRow.VisitTaskId}/${this.studyMonitorId}.txt`
let logJsonObjectName = `/${this.$route.query.trialId}/TaskImage/${this.currentRow.SubjectId}/${this.currentRow.SourceSubjectVisitId}/${this.currentRow.VisitTaskId}/${this.studyMonitorId}.txt`
if (this.IsImageSegment) {
logJsonObjectName = `/${this.$route.query.trialId}/TaskImage/${this.currentRow.SubjectId}/${this.currentRow.SourceSubjectVisitId}/AnnotationImage/${this.currentRow.VisitTaskId}/${this.studyMonitorId}.txt`
}
let logRes
try {
logRes = await this.OSSclient.put(logJsonObjectName, logJsonBlob)

View File

@ -0,0 +1,160 @@
<template>
<BaseContainer>
<div slot="main-container">
<el-table v-adaptive="{ bottomOffset: 75 }" :data="list" stripe height="100" @sort-change="handleSortChange"
v-loading="loading">
<el-table-column type="index" width="40" align="left" />
<el-table-column prop="IsUrgent" :label="$t('trials:consistencyCheck:table:isUrgent')"
show-overflow-tooltip min-width="100">
<template slot-scope="scope">
<el-tag :type="scope.row.IsUrgent
? 'danger' : 'primary'
">{{ $fd('YesOrNo', scope.row.IsUrgent) }}</el-tag>
</template>
</el-table-column>
<!-- 受试者编号 -->
<el-table-column prop="SubjectCode" min-width="100"
:label="$t('trials:pendingReadingTasks:table:subjectCode')" show-overflow-tooltip
sortable="custom" />
<!-- 访视数量 -->
<el-table-column prop="VisitCount" :label="$t('trials:pendingReadingTasks:table:VisitCount')"
show-overflow-tooltip />
<!-- dicom检查数量 -->
<el-table-column prop="DicomStudyCount" :label="$t('trials:pendingReadingTasks:table:DicomStudyCount')"
show-overflow-tooltip />
<!-- 非dicom检查数量 -->
<el-table-column prop="NoneDicomStudyCount"
:label="$t('trials:pendingReadingTasks:table:NoneDicomStudyCount')" show-overflow-tooltip />
<!-- 标记访视数量 -->
<el-table-column prop="MarkVisitCount" :label="$t('trials:pendingReadingTasks:table:MarkVisitCount')"
show-overflow-tooltip />
<!-- 标记dicom检查数量 -->
<el-table-column prop="MarkDicomStudyCount"
:label="$t('trials:pendingReadingTasks:table:MarkDicomStudyCount')" show-overflow-tooltip />
<!-- 标记非dicom检查数量 -->
<el-table-column prop="MarkNoneDicomStudyCount"
:label="$t('trials:pendingReadingTasks:table:MarkNoneDicomStudyCount')" show-overflow-tooltip />
<el-table-column :label="$t('common:action:action')" width="250" fixed="right">
<template slot-scope="scope">
<!-- 阅片 -->
<!-- <el-button :disabled="scope.row.ExistReadingApply" circle :title="scope.row.ExistReadingApply
? $t(
'trials:pendingReadingTasks:button:ExistReadingApply'
)
: $t('trials:pendingReadingTasks:button:review')
" icon="el-icon-edit-outline" @click="handleReadImage(scope.row)" /> -->
<!-- 上传 -->
<el-button v-hasPermi="['role:ir']" circle icon="el-icon-upload2"
:title="$t('trials:pendingReadingTasks:button:upload')"
@click="openUploadImage(scope.row, 'upload')" />
<!-- 下载 -->
<el-button v-hasPermi="['role:ir']" circle icon="el-icon-download"
:title="$t('trials:pendingReadingTasks:button:download')"
@click="openUploadImage(scope.row, 'download')" />
</template>
</el-table-column>
</el-table>
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize"
@pagination="getList" />
</div>
<upload-dicom-and-nonedicom v-if="uploadImageVisible" :SubjectId="uploadSubjectId"
:SubjectCode="uploadSubjectCode" :Criterion="uploadTrialCriterion" :visible.sync="uploadImageVisible"
:IsImageSegment="true" />
<download-dicom-and-nonedicom v-if="downloadImageVisible" :SubjectId="uploadSubjectId"
:SubjectCode="uploadSubjectCode" :Criterion="uploadTrialCriterion" :visible.sync="downloadImageVisible"
:IsImageSegment="true" />
</BaseContainer>
</template>
<script>
import BaseContainer from '@/components/BaseContainer'
import uploadDicomAndNonedicom from '@/components/uploadDicomAndNonedicom'
import downloadDicomAndNonedicom from '@/components/downloadDicomAndNonedicom'
import Pagination from '@/components/Pagination'
import { getTrialSubjectVisitMarkList } from "@/api/trials"
const searchDataDefault = () => {
return {
SubjectCode: '',
PageIndex: 1,
PageSize: 20,
}
}
export default {
name: "TargetSection",
components: {
BaseContainer,
Pagination,
'upload-dicom-and-nonedicom': uploadDicomAndNonedicom,
'download-dicom-and-nonedicom': downloadDicomAndNonedicom,
},
props: {
TrialReadingCriterionId: {
type: String,
default: ''
},
trialCriterionList: {
type: Array,
default: () => {
return []
}
}
},
data() {
return {
searchData: searchDataDefault(),
loading: false,
list: [],
total: 0,
//
downloadImageVisible: false,
uploadImageVisible: false,
uploadSubjectId: null,
uploadSubjectCode: null,
uploadTrialCriterion: {},
uploadStatus: 'upload',
}
},
mounted() {
this.getList()
},
methods: {
async getList() {
try {
this.searchData.TrialId = this.$route.query.trialId
this.searchData.TrialReadingCriterionId = this.TrialReadingCriterionId
this.loading = true
let res = await getTrialSubjectVisitMarkList(this.searchData)
this.loading = false
if (res.IsSuccess) {
this.list = res.Result.CurrentPageData
this.total = res.Result.TotalCount
}
} catch (err) {
this.loading = false
console.log(err)
}
},
//
handleSortChange(column) {
if (column.order === 'ascending') {
this.searchData.Asc = true
} else {
this.searchData.Asc = false
}
this.searchData.SortField = column.prop
this.searchData.PageIndex = 1
this.getList()
},
//
openUploadImage(item, status) {
this.uploadSubjectCode = item.SubjectCode
this.uploadSubjectId = item.SubjectId
let trialCriterion = this.trialCriterionList.find(item => item.TrialReadingCriterionId === this.TrialReadingCriterionId)
this.uploadTrialCriterion = trialCriterion
this.uploadStatus = status
this[`${status}ImageVisible`] = true
},
}
}
</script>
<style lang="scss" scoped></style>

View File

@ -1,272 +1,152 @@
<template>
<BaseContainer
v-loading="loading"
class="reading-task"
>
<el-tabs
v-if="TrialReadingCriterionId"
v-model="TrialReadingCriterionId"
type="border-card"
>
<el-tab-pane
v-for="item of trialCriterionList"
:key="item.TrialReadingCriterionId"
:label="item.TrialReadingCriterionName"
:name="item.TrialReadingCriterionId"
>
<div
v-if="
<BaseContainer v-loading="loading" class="reading-task">
<el-tabs v-if="TrialReadingCriterionId" v-model="TrialReadingCriterionId" type="border-card">
<el-tab-pane v-for="item of trialCriterionList" :key="item.TrialReadingCriterionId"
:label="item.TrialReadingCriterionName" :name="item.TrialReadingCriterionId">
<div v-if="
(isReadingTaskViewInOrder === 1 ||
isReadingTaskViewInOrder === 2) &&
TrialReadingCriterionId === item.TrialReadingCriterionId
"
>
">
<div slot="search-container">
<el-form :inline="true">
<!-- 受试者编号 -->
<el-form-item
:label="$t('trials:pendingReadingTasks:table:subjectCode')"
>
<el-input
v-model="searchData.SubjectCode"
style="width: 130px"
clearable
/>
<el-form-item :label="$t('trials:pendingReadingTasks:table:subjectCode')">
<el-input v-model="searchData.SubjectCode" style="width: 130px" clearable />
</el-form-item>
<el-form-item>
<!-- 查询 -->
<el-button
type="primary"
icon="el-icon-search"
@click="handleSearch"
>
<el-button type="primary" icon="el-icon-search" @click="handleSearch">
{{ $t('common:button:search') }}
</el-button>
<!-- 重置 -->
<el-button
type="primary"
icon="el-icon-refresh-left"
@click="handleReset"
>
<el-button type="primary" icon="el-icon-refresh-left" @click="handleReset">
{{ $t('common:button:reset') }}
</el-button>
<!-- 靶段标注 -->
<el-button type="primary" @click="() => TargetSection_visible = true"
v-if="item.CriterionType === 19 || item.CriterionType === 20">
{{ $t('trials:pendingReadingTasks:button:TargetSection') }}
</el-button>
</el-form-item>
</el-form>
</div>
<div slot="main-container">
<el-table
v-adaptive="{ bottomOffset: 75 }"
:data="list"
stripe
height="100"
@sort-change="handleSortChange"
>
<el-table v-adaptive="{ bottomOffset: 75 }" :data="list" stripe height="100"
@sort-change="handleSortChange">
<el-table-column type="index" width="40" align="left" />
<el-table-column
prop="IsUrgent"
:label="$t('trials:consistencyCheck:table:isUrgent')"
show-overflow-tooltip
min-width="100"
>
<el-table-column prop="IsUrgent" :label="$t('trials:consistencyCheck:table:isUrgent')"
show-overflow-tooltip min-width="100">
<template slot-scope="scope">
<el-tooltip
class="item"
effect="dark"
:content="$t('trials:pendingReadingTasks:table:feedbackmsg')"
placement="bottom"
v-if="scope.row.IsExistUnprocessedFeedback"
>
<i
v-if="scope.row.IsExistUnprocessedFeedback"
class="el-icon-warning"
style="color: #f44336; font-size: 16px"
/>
<el-tooltip class="item" effect="dark" :content="$t('trials:pendingReadingTasks:table:feedbackmsg')"
placement="bottom" v-if="scope.row.IsExistUnprocessedFeedback">
<i v-if="scope.row.IsExistUnprocessedFeedback" class="el-icon-warning"
style="color: #f44336; font-size: 16px" />
</el-tooltip>
<el-tag
:type="
scope.row.UrgentColor === 1
<el-tag :type="scope.row.UrgentColor === 1
? 'danger'
: scope.row.UrgentColor === 2
? 'warning'
: 'primary'
"
>{{ $fd('YesOrNo', scope.row.IsUrgent) }}</el-tag
>
">{{ $fd('YesOrNo', scope.row.IsUrgent) }}</el-tag>
</template>
</el-table-column>
<!-- 受试者编号 -->
<el-table-column
prop="SubjectCode"
min-width="100"
:label="$t('trials:pendingReadingTasks:table:subjectCode')"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column prop="SubjectCode" min-width="100"
:label="$t('trials:pendingReadingTasks:table:subjectCode')" show-overflow-tooltip sortable="custom" />
<!-- 剩余阅片量 -->
<el-table-column
prop="UnReadCanReadTaskCount"
min-width="100"
:label="
$t('trials:pendingReadingTasks:table:remainingReadingVolume')
"
show-overflow-tooltip
sortable="custom"
/>
<el-table-column
prop="UrgentCount"
:label="$t('trials:sysDocBeSigned:table:UrgentCount')"
show-overflow-tooltip
min-width="100"
sortable="custom"
>
<el-table-column prop="UnReadCanReadTaskCount" min-width="100" :label="$t('trials:pendingReadingTasks:table:remainingReadingVolume')
" show-overflow-tooltip sortable="custom" />
<el-table-column prop="UrgentCount" :label="$t('trials:sysDocBeSigned:table:UrgentCount')"
show-overflow-tooltip min-width="100" sortable="custom">
<template slot-scope="scope">
<span
:style="{
<span :style="{
color:
scope.row.UrgentColor === 1
? '#F56C6C'
: scope.row.UrgentColor === 2
? '#E6A23C'
: '#409EFF',
}"
>{{ scope.row.UrgentCount }}</span
>
}">{{ scope.row.UrgentCount }}</span>
</template>
</el-table-column>
<!-- 建议完成时间 -->
<el-table-column
prop="SuggesteFinishedTime"
min-width="100"
:label="
$t('trials:pendingReadingTasks:table:suggestedCompletionTime')
"
show-overflow-tooltip
sortable="custom"
>
<el-table-column prop="SuggesteFinishedTime" min-width="100" :label="$t('trials:pendingReadingTasks:table:suggestedCompletionTime')
" show-overflow-tooltip sortable="custom">
<template slot-scope="scope">
{{ scope.row.SuggesteFinishedTime.split(':')[0] + ':00:00' }}
</template>
</el-table-column>
<el-table-column
:label="$t('common:action:action')"
width="250"
fixed="right"
>
<el-table-column :label="$t('common:action:action')" width="250" fixed="right">
<template slot-scope="scope">
<!-- 阅片 -->
<el-button
:disabled="scope.row.ExistReadingApply"
circle
:title="
scope.row.ExistReadingApply
<el-button :disabled="scope.row.ExistReadingApply" circle :title="scope.row.ExistReadingApply
? $t(
'trials:pendingReadingTasks:button:ExistReadingApply'
)
: $t('trials:pendingReadingTasks:button:review')
"
icon="el-icon-edit-outline"
@click="handleReadImage(scope.row)"
/>
" icon="el-icon-edit-outline" @click="handleReadImage(scope.row)" />
<!-- 上传 -->
<el-button
v-if="
<el-button v-if="
item.ImageUploadEnum > 0 &&
item.IsReadingTaskViewInOrder > 1 &&
!scope.row.IsSubjectJudge
"
v-hasPermi="['role:ir']"
circle
icon="el-icon-upload2"
" v-hasPermi="['role:ir']" circle icon="el-icon-upload2"
:title="$t('trials:pendingReadingTasks:button:upload')"
@click="openUploadImage(scope.row, item, 'upload')"
/>
@click="openUploadImage(scope.row, item, 'upload')" />
<!-- 下载 -->
<el-button
v-if="
<el-button v-if="
item.ImageDownloadEnum > 0 &&
item.IsReadingTaskViewInOrder > 1 &&
!scope.row.IsSubjectJudge
"
v-hasPermi="['role:ir']"
circle
icon="el-icon-download"
" v-hasPermi="['role:ir']" circle icon="el-icon-download"
:title="$t('trials:pendingReadingTasks:button:download')"
@click="openUploadImage(scope.row, item, 'download')"
/>
@click="openUploadImage(scope.row, item, 'download')" />
</template>
</el-table-column>
</el-table>
<pagination
class="page"
:total="total"
:page.sync="searchData.PageIndex"
:limit.sync="searchData.PageSize"
@pagination="getList"
/>
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize"
@pagination="getList" />
</div>
</div>
<div
v-else-if="
<div v-else-if="
isReadingTaskViewInOrder === 0 &&
TrialReadingCriterionId === item.TrialReadingCriterionId
"
>
">
<el-descriptions :column="2" border style="width: 800px">
<!-- 剩余任务量 -->
<el-descriptions-item
:label="
$t('trials:pendingReadingTasks:table:remainingTaskVolume')
"
:label-style="{ width: '200px' }"
>
<el-descriptions-item :label="$t('trials:pendingReadingTasks:table:remainingTaskVolume')
" :label-style="{ width: '200px' }">
<el-tag size="small" type="danger">{{
randomReadInfo.UnReadTaskCount
}}</el-tag>
</el-descriptions-item>
<!-- 剩余裁判量 -->
<el-descriptions-item
:label="
$t('trials:pendingReadingTasks:table:amountOfJudgesRemaining')
"
:label-style="{ width: '200px' }"
>
<el-descriptions-item :label="$t('trials:pendingReadingTasks:table:amountOfJudgesRemaining')
" :label-style="{ width: '200px' }">
<el-tag size="small" type="danger">{{
randomReadInfo.UnReadJudgeTaskCount
}}</el-tag>
</el-descriptions-item>
<!-- 已完成任务量 -->
<el-descriptions-item
:label="
$t('trials:pendingReadingTasks:table:amountOfCompletedTasks')
"
:label-style="{ width: '200px' }"
>
<el-descriptions-item :label="$t('trials:pendingReadingTasks:table:amountOfCompletedTasks')
" :label-style="{ width: '200px' }">
<el-tag size="small">{{ randomReadInfo.FinishTaskCount }}</el-tag>
</el-descriptions-item>
<!-- 已完成裁判量 -->
<el-descriptions-item
:label="
$t('trials:pendingReadingTasks:table:numberOfJudgesCompleted')
"
:label-style="{ width: '200px' }"
>
<el-descriptions-item :label="$t('trials:pendingReadingTasks:table:numberOfJudgesCompleted')
" :label-style="{ width: '200px' }">
<el-tag size="small">{{
randomReadInfo.FinishJudgeTaskCount
}}</el-tag>
</el-descriptions-item>
<el-descriptions-item>
<!-- 开始随机阅片 -->
<el-button
type="primary"
size="small"
:disabled="
randomReadInfo.UnReadTaskCount +
<el-button type="primary" size="small" :disabled="randomReadInfo.UnReadTaskCount +
randomReadInfo.UnReadJudgeTaskCount ===
0
"
@click="handleOutOfOrderReading"
>
" @click="handleOutOfOrderReading">
{{ $t('trials:pendingReadingTasks:button:beginRandomReview') }}
</el-button>
</el-descriptions-item>
@ -282,21 +162,17 @@
:status="uploadStatus"
@getList="getList"
/> -->
<upload-dicom-and-nonedicom
v-if="uploadImageVisible"
:SubjectId="uploadSubjectId"
:SubjectCode="uploadSubjectCode"
:Criterion="uploadTrialCriterion"
:isReadingTaskViewInOrder="isReadingTaskViewInOrder"
:visible.sync="uploadImageVisible"
/>
<download-dicom-and-nonedicom
v-if="downloadImageVisible"
:SubjectId="uploadSubjectId"
:SubjectCode="uploadSubjectCode"
:Criterion="uploadTrialCriterion"
:visible.sync="downloadImageVisible"
/>
<upload-dicom-and-nonedicom v-if="uploadImageVisible" :SubjectId="uploadSubjectId" :SubjectCode="uploadSubjectCode"
:Criterion="uploadTrialCriterion" :isReadingTaskViewInOrder="isReadingTaskViewInOrder"
:visible.sync="uploadImageVisible" />
<download-dicom-and-nonedicom v-if="downloadImageVisible" :SubjectId="uploadSubjectId"
:SubjectCode="uploadSubjectCode" :Criterion="uploadTrialCriterion" :visible.sync="downloadImageVisible" />
<el-dialog :title="$t('trials:pendingReadingTasks:button:TargetSection')" :visible.sync="TargetSection_visible"
:fullscreen="true">
<TargetSection v-if="TargetSection_visible" :TrialReadingCriterionId="TrialReadingCriterionId"
:trialCriterionList="trialCriterionList" />
</el-dialog>
</BaseContainer>
</template>
<script>
@ -308,6 +184,7 @@ import uploadDicomAndNonedicom from '@/components/uploadDicomAndNonedicom'
import downloadDicomAndNonedicom from '@/components/downloadDicomAndNonedicom'
import Pagination from '@/components/Pagination'
import { getToken } from '@/utils/auth'
import TargetSection from "./components/TargetSection"
const searchDataDefault = () => {
return {
SubjectCode: '',
@ -322,6 +199,7 @@ export default {
Pagination,
'upload-dicom-and-nonedicom': uploadDicomAndNonedicom,
'download-dicom-and-nonedicom': downloadDicomAndNonedicom,
TargetSection
},
data() {
return {
@ -347,6 +225,8 @@ export default {
uploadSubjectCode: null,
uploadTrialCriterion: {},
uploadStatus: 'upload',
TargetSection_visible: false
}
},
watch: {
@ -468,7 +348,7 @@ export default {
)
var token = getToken()
var path = ''
if (this.readingTool === 0 || this.readingTool === 2 ) {
if (this.readingTool === 0 || this.readingTool === 2) {
path = `/readingDicoms?TrialReadingCriterionId=${this.TrialReadingCriterionId}&trialId=${this.trialId}&isReadingTaskViewInOrder=${this.isReadingTaskViewInOrder}&criterionType=${this.criterionType}&readingTool=${this.readingTool}&TokenKey=${token}`
} else {
path = `/noneDicomReading?TrialReadingCriterionId=${this.TrialReadingCriterionId}&trialId=${this.trialId}&isReadingTaskViewInOrder=${this.isReadingTaskViewInOrder}&criterionType=${this.criterionType}&readingTool=${this.readingTool}&TokenKey=${token}`
@ -500,11 +380,12 @@ export default {
}
</script>
<style lang="scss" scoped>
.reading-task{
.reading-task {
height: 100%;
background-color: #fff;
::v-deep.search {
padding: 0px !important;
}
}
}
</style>