影像替换与补充
parent
cb2fed1ad2
commit
1ca4fb7dd4
|
|
@ -488,3 +488,24 @@ export function getFilterTableQuestion(data) {
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
export function deleteImageCache(params) {
|
||||||
|
return request({
|
||||||
|
url: `/Study/deleteImageCache`,
|
||||||
|
method: 'delete',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
export function getAnonymizeInfo(params) {
|
||||||
|
return request({
|
||||||
|
url: `/Study/getAnonymizeInfo`,
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
export function updateModality(params) {
|
||||||
|
return request({
|
||||||
|
url: `/Study/updateModality`,
|
||||||
|
method: 'put',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -213,6 +213,10 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
getInfo() {
|
||||||
|
var image = cornerstone.getImage(this.canvas)
|
||||||
|
return image
|
||||||
|
},
|
||||||
loadImageStack(dicomSeries, text = '') {
|
loadImageStack(dicomSeries, text = '') {
|
||||||
this.tip = text
|
this.tip = text
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
|
|
|
||||||
|
|
@ -296,6 +296,13 @@
|
||||||
<option v-for="(item, index) in colormapsList" :key="index" :value="item.id">{{ item.name }}</option>
|
<option v-for="(item, index) in colormapsList" :key="index" :value="item.id">{{ item.name }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="sideTool-wrapper">
|
||||||
|
<label for="Replacement" style="display: inline-block;color: #fff;line-height: 20px;cursor: pointer;">
|
||||||
|
替换
|
||||||
|
</label>
|
||||||
|
<input type="file" id="Replacement" @change="beginScanFiles($event, 'replace')" style="display: none;">
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 患者信息 -->
|
<!-- 患者信息 -->
|
||||||
|
|
@ -382,6 +389,7 @@ import {
|
||||||
editPatientInfo
|
editPatientInfo
|
||||||
} from '@/api/trials'
|
} from '@/api/trials'
|
||||||
import { setPTClinicalDataForInstance, clearPTClinicalDataCache } from '@/utils/ptClinicalDataCache'
|
import { setPTClinicalDataForInstance, clearPTClinicalDataCache } from '@/utils/ptClinicalDataCache'
|
||||||
|
import { changeFile } from "@/views/trials/trials-panel/reading/dicoms/components/upload.js"
|
||||||
export default {
|
export default {
|
||||||
name: 'DicomsViewer',
|
name: 'DicomsViewer',
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -400,6 +408,14 @@ export default {
|
||||||
modality: {
|
modality: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
|
},
|
||||||
|
SeriesList: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
currentSeriesIndex: {
|
||||||
|
type: Number,
|
||||||
|
default: -1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
|
@ -483,7 +499,9 @@ export default {
|
||||||
},
|
},
|
||||||
formLoading: false,
|
formLoading: false,
|
||||||
type: '',
|
type: '',
|
||||||
isEdit: 0
|
isEdit: 0,
|
||||||
|
fileKey: null,
|
||||||
|
file: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -511,6 +529,19 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
beginScanFiles(e, key) {
|
||||||
|
this.fileKey = key
|
||||||
|
this.file = e.target.files[0]
|
||||||
|
let image = this.$refs[this.activeItem].getInfo()
|
||||||
|
let study = {
|
||||||
|
seriesList: this.SeriesList,
|
||||||
|
currentSeriesIndex: this.currentSeriesIndex
|
||||||
|
}
|
||||||
|
this.$emit("update:loading", true)
|
||||||
|
changeFile('CRC', this.file, study, image)
|
||||||
|
|
||||||
|
// DicomEvent.$emit('getStudyFile')
|
||||||
|
},
|
||||||
setToolsPassive() {
|
setToolsPassive() {
|
||||||
const elements = document.querySelectorAll('.dicom-item')
|
const elements = document.querySelectorAll('.dicom-item')
|
||||||
const scope = this
|
const scope = this
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,8 @@
|
||||||
scope.row.UploadStudyList.length <= 0
|
scope.row.UploadStudyList.length <= 0
|
||||||
" @click.stop="handleViewReadingImages(scope.row)" :title="$t('upload:dicom:button:preview')" />
|
" @click.stop="handleViewReadingImages(scope.row)" :title="$t('upload:dicom:button:preview')" />
|
||||||
<!--删除--->
|
<!--删除--->
|
||||||
<el-button circle icon="el-icon-delete" :title="$t('upload:dicom:button:delete')" @click.stop="remove(scope.row)" />
|
<el-button circle icon="el-icon-delete" :title="$t('upload:dicom:button:delete')"
|
||||||
|
@click.stop="remove(scope.row)" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
@ -380,6 +381,10 @@ export default {
|
||||||
isReading: {
|
isReading: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
|
},
|
||||||
|
StudyInstanceUID: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -1081,11 +1086,12 @@ export default {
|
||||||
async verifyStudy() {
|
async verifyStudy() {
|
||||||
this.btnLoading = true
|
this.btnLoading = true
|
||||||
var studyList = []
|
var studyList = []
|
||||||
|
let scope = this
|
||||||
this.selectArr.forEach((item) => {
|
this.selectArr.forEach((item) => {
|
||||||
item.dicomInfo.uploadFileSize = 0
|
item.dicomInfo.uploadFileSize = 0
|
||||||
if (!item.uploadState.selected) {
|
if (!item.uploadState.selected) {
|
||||||
studyList.push({
|
studyList.push({
|
||||||
studyInstanceUid: item.dicomInfo.studyUid,
|
studyInstanceUid: scope.isReading && scope.StudyInstanceUID ? scope.StudyInstanceUID : item.dicomInfo.studyUid,
|
||||||
studyDate: item.dicomInfo.studyTime,
|
studyDate: item.dicomInfo.studyTime,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -1180,7 +1186,7 @@ export default {
|
||||||
let t = setInterval(() => {
|
let t = setInterval(() => {
|
||||||
dicomUploadInProgress({
|
dicomUploadInProgress({
|
||||||
trialId: scope.trialId,
|
trialId: scope.trialId,
|
||||||
studyInstanceUid: dicomInfo.studyUid,
|
studyInstanceUid: scope.isReading && scope.StudyInstanceUID ? scope.StudyInstanceUID : dicomInfo.studyUid,
|
||||||
VisitTaskId: dicomInfo.visitTaskId,
|
VisitTaskId: dicomInfo.visitTaskId,
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
console.log(dicomInfo.visitTaskId)
|
console.log(dicomInfo.visitTaskId)
|
||||||
|
|
@ -1207,7 +1213,7 @@ export default {
|
||||||
dicomInfo.RadiopharmaceuticalStartTime,
|
dicomInfo.RadiopharmaceuticalStartTime,
|
||||||
|
|
||||||
studyId: dicomInfo.studyId,
|
studyId: dicomInfo.studyId,
|
||||||
studyInstanceUid: dicomInfo.studyUid,
|
studyInstanceUid: scope.isReading && scope.StudyInstanceUID ? scope.StudyInstanceUID : dicomInfo.studyUid,
|
||||||
studyTime: dicomInfo.studyTime,
|
studyTime: dicomInfo.studyTime,
|
||||||
description: dicomInfo.description,
|
description: dicomInfo.description,
|
||||||
seriesCount: dicomInfo.seriesNum,
|
seriesCount: dicomInfo.seriesNum,
|
||||||
|
|
@ -1327,7 +1333,18 @@ export default {
|
||||||
file: o.file,
|
file: o.file,
|
||||||
speed: true,
|
speed: true,
|
||||||
},
|
},
|
||||||
null,
|
scope.isReading && scope.StudyInstanceUID ? {
|
||||||
|
AnonymizeFixedList: [
|
||||||
|
{
|
||||||
|
Element: '000D',
|
||||||
|
Group: '0020',
|
||||||
|
ReplaceValue: scope.StudyInstanceUID,
|
||||||
|
Id: 'StudyInstanceUID'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
AnonymizeNotFixedList: [],
|
||||||
|
DicomStoreInfo: {}
|
||||||
|
} : null,
|
||||||
(percentage, checkpoint, lastPer) => {
|
(percentage, checkpoint, lastPer) => {
|
||||||
dicomInfo.uploadFileSize +=
|
dicomInfo.uploadFileSize +=
|
||||||
checkpoint.size * (percentage - lastPer)
|
checkpoint.size * (percentage - lastPer)
|
||||||
|
|
@ -1393,7 +1410,7 @@ export default {
|
||||||
}
|
}
|
||||||
if (res && res.url) {
|
if (res && res.url) {
|
||||||
instanceList.push({
|
instanceList.push({
|
||||||
studyInstanceUid: dicomInfo.studyUid,
|
studyInstanceUid: scope.isReading && scope.StudyInstanceUID ? scope.StudyInstanceUID : dicomInfo.studyUid,
|
||||||
seriesInstanceUid: v.seriesUid,
|
seriesInstanceUid: v.seriesUid,
|
||||||
sopInstanceUid: o.instanceUid,
|
sopInstanceUid: o.instanceUid,
|
||||||
SOPClassUID: o.SOPClassUID,
|
SOPClassUID: o.SOPClassUID,
|
||||||
|
|
@ -1460,7 +1477,7 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
params.study.seriesList.push({
|
params.study.seriesList.push({
|
||||||
studyInstanceUid: dicomInfo.studyUid,
|
studyInstanceUid: scope.isReading && scope.StudyInstanceUID ? scope.StudyInstanceUID : dicomInfo.studyUid,
|
||||||
seriesInstanceUid: v.seriesUid,
|
seriesInstanceUid: v.seriesUid,
|
||||||
seriesNumber: v.seriesNumber,
|
seriesNumber: v.seriesNumber,
|
||||||
seriesTime: v.seriesTime,
|
seriesTime: v.seriesTime,
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
<dicomFile v-if="activeName === 'dicom'" :SubjectId="SubjectId" :SubjectCode="SubjectCode"
|
<dicomFile v-if="activeName === 'dicom'" :SubjectId="SubjectId" :SubjectCode="SubjectCode"
|
||||||
:Criterion="Criterion" :TaskId="VisitTaskId" :isUpload.sync="isUpload"
|
:Criterion="Criterion" :TaskId="VisitTaskId" :isUpload.sync="isUpload"
|
||||||
:isReadingTaskViewInOrder="isReadingTaskViewInOrder" :IsImageSegment="IsImageSegment" :forbid="forbid"
|
:isReadingTaskViewInOrder="isReadingTaskViewInOrder" :IsImageSegment="IsImageSegment" :forbid="forbid"
|
||||||
:isReading="isReading" />
|
:isReading="isReading" :StudyInstanceUID="StudyInstanceUID" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane :label="$t('uploadDicomAndNonedicom:label:nonedicom')" name="nonedicom">
|
<el-tab-pane :label="$t('uploadDicomAndNonedicom:label:nonedicom')" name="nonedicom">
|
||||||
<nonedicomFile v-if="activeName === 'nonedicom'" :SubjectId="SubjectId" :SubjectCode="SubjectCode"
|
<nonedicomFile v-if="activeName === 'nonedicom'" :SubjectId="SubjectId" :SubjectCode="SubjectCode"
|
||||||
|
|
@ -63,6 +63,10 @@ export default {
|
||||||
isReading: {
|
isReading: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
|
},
|
||||||
|
StudyInstanceUID: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ export const anonymization = function (file, config) {
|
||||||
try {
|
try {
|
||||||
const reader = new FileReader()
|
const reader = new FileReader()
|
||||||
let AnonymizeFixedList = config.AnonymizeFixedList
|
let AnonymizeFixedList = config.AnonymizeFixedList
|
||||||
|
console.log(AnonymizeFixedList, 'AnonymizeFixedList')
|
||||||
let AnonymizeNotFixedList = config.AnonymizeNotFixedList
|
let AnonymizeNotFixedList = config.AnonymizeNotFixedList
|
||||||
let DicomStoreInfo = config.DicomStoreInfo
|
let DicomStoreInfo = config.DicomStoreInfo
|
||||||
reader.onload = async (event) => {
|
reader.onload = async (event) => {
|
||||||
|
|
@ -15,9 +16,11 @@ export const anonymization = function (file, config) {
|
||||||
let dataset = dcmjs.data.DicomMessage.readFile(buffer)
|
let dataset = dcmjs.data.DicomMessage.readFile(buffer)
|
||||||
for (var i = 0; i < AnonymizeFixedList.length; i++) {
|
for (var i = 0; i < AnonymizeFixedList.length; i++) {
|
||||||
let AnonymizeFixed = AnonymizeFixedList[i]
|
let AnonymizeFixed = AnonymizeFixedList[i]
|
||||||
if (!dataset.dict.hasOwnProperty(`${AnonymizeFixed.Group + AnonymizeFixed.Element}`)) continue
|
if (!dataset.dict.hasOwnProperty(`${AnonymizeFixed.Group + AnonymizeFixed.Element}`) && !dataset.meta.hasOwnProperty(`${AnonymizeFixed.Group + AnonymizeFixed.Element}`)) continue
|
||||||
if (dataset.dict[AnonymizeFixed.Group + AnonymizeFixed.Element]) {
|
if (dataset.dict[AnonymizeFixed.Group + AnonymizeFixed.Element]) {
|
||||||
dataset.dict[AnonymizeFixed.Group + AnonymizeFixed.Element].Value[0] = AnonymizeFixed.ReplaceValue
|
dataset.dict[AnonymizeFixed.Group + AnonymizeFixed.Element].Value[0] = AnonymizeFixed.ReplaceValue
|
||||||
|
} else if (dataset.meta[AnonymizeFixed.Group + AnonymizeFixed.Element]) {
|
||||||
|
dataset.meta[AnonymizeFixed.Group + AnonymizeFixed.Element].Value[0] = AnonymizeFixed.ReplaceValue
|
||||||
} else {
|
} else {
|
||||||
dataset.dict[AnonymizeFixed.Group + AnonymizeFixed.Element] = {
|
dataset.dict[AnonymizeFixed.Group + AnonymizeFixed.Element] = {
|
||||||
vr: AnonymizeFixed.ValueRepresentation,
|
vr: AnonymizeFixed.ValueRepresentation,
|
||||||
|
|
@ -60,7 +63,7 @@ export const anonymization = function (file, config) {
|
||||||
let newDicomFile = dataset.write() // fragmentMultiframe 原始数据是否进行分割
|
let newDicomFile = dataset.write() // fragmentMultiframe 原始数据是否进行分割
|
||||||
const bufferArray = new Uint8Array(newDicomFile)
|
const bufferArray = new Uint8Array(newDicomFile)
|
||||||
const blob = new Blob([bufferArray], { type: 'application/octet-stream' })
|
const blob = new Blob([bufferArray], { type: 'application/octet-stream' })
|
||||||
resolve({ blob, pixelDataElement })
|
resolve({ blob, pixelDataElement, Modality: dataset.dict['00080060'].Value[0] })
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(file, 'warning')
|
console.log(file, 'warning')
|
||||||
console.log(err)
|
console.log(err)
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,8 @@ export const dcmUpload = async function (data, config, progressFn, fileInfo) {
|
||||||
let res = await Vue.prototype.OSSclient.multipartUpload(Object.assign(data, { file: blob.blob }), progressFn, fileInfo)
|
let res = await Vue.prototype.OSSclient.multipartUpload(Object.assign(data, { file: blob.blob }), progressFn, fileInfo)
|
||||||
resolve({
|
resolve({
|
||||||
...res,
|
...res,
|
||||||
image: blob.pixelDataElement
|
image: blob.pixelDataElement,
|
||||||
|
Modality: blob.Modality
|
||||||
})
|
})
|
||||||
// let OSSclientA = await OSSclient
|
// let OSSclientA = await OSSclient
|
||||||
// let blob = await encoder(file)
|
// let blob = await encoder(file)
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ async function ossGenerateSTS() {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
let _vm = router.default.app
|
let _vm = router.default.app
|
||||||
if (_vm._route.path !== '/trials/trials-panel/visit/crc-upload') {
|
if (_vm._route.path !== '/trials/trials-panel/visit/crc-upload' && _vm._route.path !== '/readingDicoms' && _vm._route.path !== '/showdicom') {
|
||||||
var objectItem = objectName.split('/')
|
var objectItem = objectName.split('/')
|
||||||
// objectItem[objectItem.length - 1] = new Date().getTime() + '_' + objectItem[objectItem.length - 1]
|
// objectItem[objectItem.length - 1] = new Date().getTime() + '_' + objectItem[objectItem.length - 1]
|
||||||
objectItem[objectItem.length - 1] = `${objectItem[objectItem.length - 1].substring(
|
objectItem[objectItem.length - 1] = `${objectItem[objectItem.length - 1].substring(
|
||||||
|
|
@ -57,7 +57,7 @@ async function ossGenerateSTS() {
|
||||||
const trialId = urlParams.get('trialId')
|
const trialId = urlParams.get('trialId')
|
||||||
if (Object.keys(fileInfo).length !== 0) {
|
if (Object.keys(fileInfo).length !== 0) {
|
||||||
fileInfo.fileType = mimeTypeToExt(fileInfo.fileType)
|
fileInfo.fileType = mimeTypeToExt(fileInfo.fileType)
|
||||||
let params = Object.assign({path: objectName}, fileInfo)
|
let params = Object.assign({ path: objectName }, fileInfo)
|
||||||
addOrUpdateFileUploadRecord(params)
|
addOrUpdateFileUploadRecord(params)
|
||||||
} else if (trialId) {
|
} else if (trialId) {
|
||||||
const fileName = objectName.split('/').pop()
|
const fileName = objectName.split('/').pop()
|
||||||
|
|
@ -97,7 +97,7 @@ async function ossGenerateSTS() {
|
||||||
OSSclient = new OSS(Vue.prototype.OSSclientConfig);
|
OSSclient = new OSS(Vue.prototype.OSSclientConfig);
|
||||||
}
|
}
|
||||||
let _vm = router.default.app
|
let _vm = router.default.app
|
||||||
if (_vm._route.path !== '/trials/trials-panel/visit/crc-upload') {
|
if (_vm._route.path !== '/trials/trials-panel/visit/crc-upload' && _vm._route.path !== '/readingDicoms' && _vm._route.path !== '/showdicom') {
|
||||||
var objectItem = data.path.split('/')
|
var objectItem = data.path.split('/')
|
||||||
// objectItem[objectItem.length - 1] = new Date().getTime() + '_' + objectItem[objectItem.length - 1]
|
// objectItem[objectItem.length - 1] = new Date().getTime() + '_' + objectItem[objectItem.length - 1]
|
||||||
objectItem[objectItem.length - 1] = `${objectItem[objectItem.length - 1].substring(
|
objectItem[objectItem.length - 1] = `${objectItem[objectItem.length - 1].substring(
|
||||||
|
|
@ -114,7 +114,7 @@ async function ossGenerateSTS() {
|
||||||
const trialId = urlParams.get('trialId')
|
const trialId = urlParams.get('trialId')
|
||||||
if (Object.keys(fileInfo).length !== 0) {
|
if (Object.keys(fileInfo).length !== 0) {
|
||||||
fileInfo.fileType = mimeTypeToExt(fileInfo.fileType)
|
fileInfo.fileType = mimeTypeToExt(fileInfo.fileType)
|
||||||
let params = Object.assign({path: data.path}, fileInfo)
|
let params = Object.assign({ path: data.path }, fileInfo)
|
||||||
addOrUpdateFileUploadRecord(params)
|
addOrUpdateFileUploadRecord(params)
|
||||||
} else if (trialId) {
|
} else if (trialId) {
|
||||||
const fileName = data.path.split('/').pop()
|
const fileName = data.path.split('/').pop()
|
||||||
|
|
@ -151,7 +151,7 @@ async function ossGenerateSTS() {
|
||||||
try {
|
try {
|
||||||
var name = objectName.split('/')[objectName.split('/').length - 1]
|
var name = objectName.split('/')[objectName.split('/').length - 1]
|
||||||
let _vm = router.default.app
|
let _vm = router.default.app
|
||||||
if (_vm._route.path !== '/trials/trials-panel/visit/crc-upload') {
|
if (_vm._route.path !== '/trials/trials-panel/visit/crc-upload' && _vm._route.path !== '/readingDicoms' && _vm._route.path !== '/showdicom') {
|
||||||
var objectItem = objectName.split('/')
|
var objectItem = objectName.split('/')
|
||||||
objectItem[objectItem.length - 1] = new Date().getTime() + '_' + objectItem[objectItem.length - 1]
|
objectItem[objectItem.length - 1] = new Date().getTime() + '_' + objectItem[objectItem.length - 1]
|
||||||
objectName = objectItem.join('/')
|
objectName = objectItem.join('/')
|
||||||
|
|
@ -225,7 +225,7 @@ function uploadAWS(aws, data, progress, fileInfo) {
|
||||||
const { file, path } = data;
|
const { file, path } = data;
|
||||||
if (!file || !path) return reject('file and path be required');
|
if (!file || !path) return reject('file and path be required');
|
||||||
let _vm = router.default.app
|
let _vm = router.default.app
|
||||||
if (_vm._route.path !== '/trials/trials-panel/visit/crc-upload') {
|
if (_vm._route.path !== '/trials/trials-panel/visit/crc-upload' && _vm._route.path !== '/readingDicoms' && _vm._route.path !== '/showdicom') {
|
||||||
var objectItem = data.path.split('/')
|
var objectItem = data.path.split('/')
|
||||||
// objectItem[objectItem.length - 1] = new Date().getTime() + '_' + objectItem[objectItem.length - 1]
|
// objectItem[objectItem.length - 1] = new Date().getTime() + '_' + objectItem[objectItem.length - 1]
|
||||||
objectItem[objectItem.length - 1] = `${objectItem[objectItem.length - 1].substring(
|
objectItem[objectItem.length - 1] = `${objectItem[objectItem.length - 1].substring(
|
||||||
|
|
@ -246,7 +246,7 @@ function uploadAWS(aws, data, progress, fileInfo) {
|
||||||
const trialId = urlParams.get('trialId')
|
const trialId = urlParams.get('trialId')
|
||||||
if (Object.keys(fileInfo).length !== 0) {
|
if (Object.keys(fileInfo).length !== 0) {
|
||||||
fileInfo.fileType = mimeTypeToExt(fileInfo.fileType)
|
fileInfo.fileType = mimeTypeToExt(fileInfo.fileType)
|
||||||
let params = Object.assign({path: decodeUtf8(curPath)}, fileInfo)
|
let params = Object.assign({ path: decodeUtf8(curPath) }, fileInfo)
|
||||||
addOrUpdateFileUploadRecord(params)
|
addOrUpdateFileUploadRecord(params)
|
||||||
} else if (trialId) {
|
} else if (trialId) {
|
||||||
const fileName = decodeUtf8(curPath).split('/').pop()
|
const fileName = decodeUtf8(curPath).split('/').pop()
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="viewerContent">
|
<div class="viewerContent">
|
||||||
<dicom-viewer id="dicomViewer" ref="dicomViewer" style="height:100%" :loading.sync="loading"
|
<dicom-viewer id="dicomViewer" ref="dicomViewer" style="height:100%" :loading.sync="loading"
|
||||||
:modality="modality" :Comparison.sync="isComparison" @loadStudy="loadStudy" />
|
:modality="modality" :Comparison.sync="isComparison" :SeriesList="seriesList"
|
||||||
|
:currentSeriesIndex="currentSeriesIndex" @loadStudy="loadStudy" />
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="viewerRightSidePanel">
|
<!-- <div class="viewerRightSidePanel">
|
||||||
<dicom-tools />
|
<dicom-tools />
|
||||||
|
|
@ -179,7 +180,7 @@ export default {
|
||||||
description: '',
|
description: '',
|
||||||
seriesCount: 0,
|
seriesCount: 0,
|
||||||
seriesList: [],
|
seriesList: [],
|
||||||
currentSeriesIndex: -1,
|
currentSeriesIndex: 0,
|
||||||
arr: [],
|
arr: [],
|
||||||
activeName: 'first',
|
activeName: 'first',
|
||||||
tpList: [],
|
tpList: [],
|
||||||
|
|
@ -253,6 +254,11 @@ export default {
|
||||||
})
|
})
|
||||||
workSpeedclose(true)
|
workSpeedclose(true)
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
currentSeriesIndex() {
|
||||||
|
console.log(this.currentSeriesIndex, 'currentSeriesIndex')
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async updateImageResizePath(data) {
|
async updateImageResizePath(data) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -353,13 +359,14 @@ export default {
|
||||||
i.ImageId = imageId
|
i.ImageId = imageId
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
var subjectVisitId = this.$router.currentRoute.query.subjectVisitId
|
var subjectVisitId = this.$router.currentRoute.query.subjectVisitId ? this.$router.currentRoute.query.subjectVisitId : item.SubjectVisitId
|
||||||
var studyId = this.$router.currentRoute.query.studyId
|
var studyId = this.$router.currentRoute.query.studyId
|
||||||
var trialId = this.$router.currentRoute.query.trialId
|
var trialId = this.$router.currentRoute.query.trialId
|
||||||
seriesList.push({
|
seriesList.push({
|
||||||
trialId,
|
trialId,
|
||||||
subjectVisitId,
|
subjectVisitId,
|
||||||
studyId,
|
studyId,
|
||||||
|
subjectId: item.SubjectId,
|
||||||
imageIds: imageIds,
|
imageIds: imageIds,
|
||||||
instanceInfoList: item.InstanceInfoList,
|
instanceInfoList: item.InstanceInfoList,
|
||||||
seriesId: item.Id,
|
seriesId: item.Id,
|
||||||
|
|
@ -415,12 +422,13 @@ export default {
|
||||||
i.ImageId = imageId
|
i.ImageId = imageId
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
var subjectVisitId = this.$router.currentRoute.query.subjectVisitId
|
var subjectVisitId = this.$router.currentRoute.query.subjectVisitId ? this.$router.currentRoute.query.subjectVisitId : item.SubjectVisitId
|
||||||
var studyId = this.$router.currentRoute.query.studyId
|
var studyId = this.$router.currentRoute.query.studyId
|
||||||
var trialId = this.$router.currentRoute.query.trialId
|
var trialId = this.$router.currentRoute.query.trialId
|
||||||
seriesList.push({
|
seriesList.push({
|
||||||
trialId,
|
trialId,
|
||||||
subjectVisitId,
|
subjectVisitId,
|
||||||
|
subjectId: item.SubjectId,
|
||||||
studyId,
|
studyId,
|
||||||
imageIds: imageIds,
|
imageIds: imageIds,
|
||||||
instanceInfoList: item.InstanceInfoList,
|
instanceInfoList: item.InstanceInfoList,
|
||||||
|
|
@ -1197,6 +1205,7 @@ export default {
|
||||||
border-color: #213a54 !important;
|
border-color: #213a54 !important;
|
||||||
background-color: #213a54;
|
background-color: #213a54;
|
||||||
}
|
}
|
||||||
|
|
||||||
.frame_content_active {
|
.frame_content_active {
|
||||||
border-color: #213a54 !important;
|
border-color: #213a54 !important;
|
||||||
background-color: #213a54;
|
background-color: #213a54;
|
||||||
|
|
|
||||||
|
|
@ -1675,7 +1675,10 @@ export default {
|
||||||
cornerstone.getDefaultViewportForImage(this.canvas, image)
|
cornerstone.getDefaultViewportForImage(this.canvas, image)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
getInfo() {
|
||||||
|
var image = cornerstone.getImage(this.canvas)
|
||||||
|
return image
|
||||||
|
},
|
||||||
toggleDicomInfo() {
|
toggleDicomInfo() {
|
||||||
this.toolState.dicomInfoVisible = !this.toolState.dicomInfoVisible
|
this.toolState.dicomInfoVisible = !this.toolState.dicomInfoVisible
|
||||||
if (this.toolState.dicomInfoVisible) {
|
if (this.toolState.dicomInfoVisible) {
|
||||||
|
|
|
||||||
|
|
@ -447,6 +447,10 @@
|
||||||
<div class="text">{{ $t('trials:reading:button:download') }}</div>
|
<div class="text">{{ $t('trials:reading:button:download') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
<label for="Replacement" style="color: #fff;cursor: pointer;">
|
||||||
|
替换
|
||||||
|
</label>
|
||||||
|
<input type="file" id="Replacement" @change="beginScanFiles($event, 'replace')" style="display: none;">
|
||||||
<div style="margin-left:auto;">
|
<div style="margin-left:auto;">
|
||||||
<div style="padding:5px;display: flex;">
|
<div style="padding:5px;display: flex;">
|
||||||
<!-- 手册 -->
|
<!-- 手册 -->
|
||||||
|
|
@ -708,7 +712,8 @@
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<upload-dicom-and-nonedicom v-if="uploadImageVisible" :subject-id="uploadSubjectId"
|
<upload-dicom-and-nonedicom v-if="uploadImageVisible" :subject-id="uploadSubjectId"
|
||||||
:subject-code="uploadSubjectCode" :criterion="uploadTrialCriterion" :visible.sync="uploadImageVisible"
|
:subject-code="uploadSubjectCode" :criterion="uploadTrialCriterion" :visible.sync="uploadImageVisible"
|
||||||
:visit-task-id="taskId" :is-reading-task-view-in-order="isReadingTaskViewInOrder" :isReading="true" />
|
:visit-task-id="taskId" :is-reading-task-view-in-order="isReadingTaskViewInOrder" :isReading="true"
|
||||||
|
:StudyInstanceUID="StudyInstanceUID" />
|
||||||
<download-dicom-and-nonedicom v-if="downloadImageVisible" :subject-id="uploadSubjectId"
|
<download-dicom-and-nonedicom v-if="downloadImageVisible" :subject-id="uploadSubjectId"
|
||||||
:subject-code="uploadSubjectCode" :criterion="uploadTrialCriterion" :task-id="taskId"
|
:subject-code="uploadSubjectCode" :criterion="uploadTrialCriterion" :task-id="taskId"
|
||||||
:visible.sync="downloadImageVisible" :isReading="true" />
|
:visible.sync="downloadImageVisible" :isReading="true" />
|
||||||
|
|
@ -767,6 +772,8 @@ import const_ from '@/const/sign-code'
|
||||||
import { changeURLStatic } from '@/utils/history.js'
|
import { changeURLStatic } from '@/utils/history.js'
|
||||||
import SystemInfo from "@/utils/systemInfo";
|
import SystemInfo from "@/utils/systemInfo";
|
||||||
import md5 from 'js-md5'
|
import md5 from 'js-md5'
|
||||||
|
import { changeFile } from "./upload.js"
|
||||||
|
import dcmjs from '@/utils/dcmUpload/dcmjs'
|
||||||
export default {
|
export default {
|
||||||
name: 'DicomViewer',
|
name: 'DicomViewer',
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -845,6 +852,10 @@ export default {
|
||||||
default() {
|
default() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
Loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|
@ -978,7 +989,10 @@ export default {
|
||||||
fullScreenWidth: window.innerWidth - 570 + 'px',
|
fullScreenWidth: window.innerWidth - 570 + 'px',
|
||||||
fullScreenHeight: window.innerHeight - 130 + 'px',
|
fullScreenHeight: window.innerHeight - 130 + 'px',
|
||||||
|
|
||||||
ManualsClose: false
|
ManualsClose: false,
|
||||||
|
fileKey: null,
|
||||||
|
file: null,
|
||||||
|
StudyInstanceUID: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -1213,6 +1227,12 @@ export default {
|
||||||
this.AspectRatio = windowWidth / windowHeight
|
this.AspectRatio = windowWidth / windowHeight
|
||||||
};
|
};
|
||||||
this.getSystemInfoReading()
|
this.getSystemInfoReading()
|
||||||
|
DicomEvent.$on('sendStudyFile', (study) => {
|
||||||
|
let image = this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].getInfo()
|
||||||
|
study.visitTaskList = this.visitTaskList
|
||||||
|
this.$emit("update:Loading", true)
|
||||||
|
changeFile('IR', this.file, study, image)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
DicomEvent.$off('updateImage')
|
DicomEvent.$off('updateImage')
|
||||||
|
|
@ -1236,6 +1256,11 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
beginScanFiles(e, key) {
|
||||||
|
this.fileKey = key
|
||||||
|
this.file = e.target.files[0]
|
||||||
|
DicomEvent.$emit('getStudyFile')
|
||||||
|
},
|
||||||
handleReadingChart(e) {
|
handleReadingChart(e) {
|
||||||
this.$emit('handleReadingChart', e)
|
this.$emit('handleReadingChart', e)
|
||||||
},
|
},
|
||||||
|
|
@ -1283,6 +1308,10 @@ export default {
|
||||||
if (idx > -1) {
|
if (idx > -1) {
|
||||||
this.taskId = this.visitTaskList[idx].VisitTaskId
|
this.taskId = this.visitTaskList[idx].VisitTaskId
|
||||||
}
|
}
|
||||||
|
let image = this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].getInfo()
|
||||||
|
let dataset = dcmjs.data.DicomMessage.readFile(image.data.byteArray.buffer)
|
||||||
|
this.StudyInstanceUID = dataset.dict['0020000D'].Value[0]
|
||||||
|
dataset = null
|
||||||
this.uploadSubjectCode = localStorage.getItem("subjectCode")
|
this.uploadSubjectCode = localStorage.getItem("subjectCode")
|
||||||
this.uploadSubjectId = localStorage.getItem("subjectId")
|
this.uploadSubjectId = localStorage.getItem("subjectId")
|
||||||
this.uploadTrialCriterion = this.trialCriterion
|
this.uploadTrialCriterion = this.trialCriterion
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="dicom-container">
|
<div class="dicom-container" v-loading="loading">
|
||||||
<div :class="{ 'dicom-list': true, studyHide: !studyShow }">
|
<div :class="{ 'dicom-list': true, studyHide: !studyShow }">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="related-study-wrapper">
|
<div class="related-study-wrapper">
|
||||||
|
|
@ -27,7 +27,8 @@
|
||||||
class="study-wrapper">
|
class="study-wrapper">
|
||||||
<StudyList v-if="selectArr.includes(s.VisitTaskId)" :ref="s.VisitTaskId" :visit-task-id="s.VisitTaskId"
|
<StudyList v-if="selectArr.includes(s.VisitTaskId)" :ref="s.VisitTaskId" :visit-task-id="s.VisitTaskId"
|
||||||
:trial-id="trialId" :subject-visit-id="s.VisitId" :task-blind-name="s.TaskBlindName"
|
:trial-id="trialId" :subject-visit-id="s.VisitId" :task-blind-name="s.TaskBlindName"
|
||||||
:is-reading-show-subject-info="isReadingShowSubjectInfo" :is-reading-task-view-in-order="isReadingTaskViewInOrder" @loadImageStack="loadImageStack"
|
:is-reading-show-subject-info="isReadingShowSubjectInfo"
|
||||||
|
:is-reading-task-view-in-order="isReadingTaskViewInOrder" @loadImageStack="loadImageStack"
|
||||||
@previewNoneDicoms="previewNoneDicoms" />
|
@previewNoneDicoms="previewNoneDicoms" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -38,7 +39,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="dicom-viewer">
|
<div class="dicom-viewer">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<DicomViewer v-if="activeTaskVisitId" ref="dicomViewer" :is-show="isShow"
|
<DicomViewer v-if="activeTaskVisitId" ref="dicomViewer" :is-show="isShow" :Loading.sync="loading"
|
||||||
:question-form-change-state="questionFormChangeState" :question-form-change-num="questionFormChangeNum"
|
:question-form-change-state="questionFormChangeState" :question-form-change-num="questionFormChangeNum"
|
||||||
:is-exists-clinical-data="isExistsClinicalData" :is-exists-no-dicom-file="isExistsNoDicomFile"
|
:is-exists-clinical-data="isExistsClinicalData" :is-exists-no-dicom-file="isExistsNoDicomFile"
|
||||||
:is-reading-show-subject-info="isReadingShowSubjectInfo" :studyShow="studyShow"
|
:is-reading-show-subject-info="isReadingShowSubjectInfo" :studyShow="studyShow"
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-loading="loading" class="study-wrapper">
|
<div v-loading="loading" class="study-wrapper">
|
||||||
<h4 v-if="isReadingShowSubjectInfo" style="color: #ddd;padding: 5px 0px;margin: 0;text-align: center;background-color: #4c4c4c;">
|
<h4 v-if="isReadingShowSubjectInfo"
|
||||||
|
style="color: #ddd;padding: 5px 0px;margin: 0;text-align: center;background-color: #4c4c4c;">
|
||||||
{{ subjectCode }}
|
{{ subjectCode }}
|
||||||
</h4>
|
</h4>
|
||||||
<h4 v-if="isReadingShowSubjectInfo" style="color: #ddd;padding: 5px 0px;margin: 0;text-align: center;background-color: #4c4c4c;margin-bottom: 5px;">
|
<h4 v-if="isReadingShowSubjectInfo"
|
||||||
|
style="color: #ddd;padding: 5px 0px;margin: 0;text-align: center;background-color: #4c4c4c;margin-bottom: 5px;">
|
||||||
{{ taskBlindName }}
|
{{ taskBlindName }}
|
||||||
</h4>
|
</h4>
|
||||||
<div class="ps">
|
<div class="ps">
|
||||||
|
|
@ -14,21 +16,18 @@
|
||||||
<!-- 关键序列 -->
|
<!-- 关键序列 -->
|
||||||
{{ $t('trials:reading:title:keySeries') }}
|
{{ $t('trials:reading:title:keySeries') }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div v-else class="dicom-desc" style="white-space: normal;">
|
||||||
v-else
|
|
||||||
class="dicom-desc"
|
|
||||||
style="white-space: normal;"
|
|
||||||
>
|
|
||||||
<div>
|
<div>
|
||||||
<div style="text-overflow: ellipsis;overflow: hidden;">
|
<div style="text-overflow: ellipsis;overflow: hidden;">
|
||||||
|
|
||||||
<span v-if="taskInfo && taskInfo.IsShowStudyName && study.StudyName" :title="study.StudyName">
|
<span v-if="taskInfo && taskInfo.IsShowStudyName && study.StudyName" :title="study.StudyName">
|
||||||
{{study.StudyName}}
|
{{ study.StudyName }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span class="study-meta-line" :title="study.Modalities">
|
<span class="study-meta-line" :title="study.Modalities">
|
||||||
<span v-if="isReadingTaskViewInOrder !== 0" class="study-code" :title="study.StudyCode">{{ study.StudyCode }}</span>
|
<span v-if="isReadingTaskViewInOrder !== 0" class="study-code" :title="study.StudyCode">{{
|
||||||
|
study.StudyCode }}</span>
|
||||||
<span class="study-modality">{{ study.Modalities }}({{ study.SeriesCount }})</span>
|
<span class="study-modality">{{ study.Modalities }}({{ study.SeriesCount }})</span>
|
||||||
<span class="patient-info" v-if="['PT、CT', 'CT、PT', 'PET-CT'].includes(study.Modalities)">
|
<span class="patient-info" v-if="['PT、CT', 'CT、PT', 'PET-CT'].includes(study.Modalities)">
|
||||||
<el-popover placement="right-start" trigger="hover" popper-class="patient-info-popper">
|
<el-popover placement="right-start" trigger="hover" popper-class="patient-info-popper">
|
||||||
|
|
@ -63,67 +62,57 @@
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="study.Description" class="study-desc-text" :title="study.Description">{{ study.Description }}</div>
|
<div v-if="study.Description" class="study-desc-text" :title="study.Description">{{ study.Description }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div class="series">
|
<div class="series">
|
||||||
<div
|
<div v-for="(series, i) in study.SeriesList" :key="i" style="position:relative;margin-top:5px;"
|
||||||
v-for="(series, i) in study.SeriesList"
|
series-type="current" @click="showSeriesImage(index, i, series)">
|
||||||
:key="i"
|
|
||||||
style="position:relative;margin-top:5px;"
|
|
||||||
series-type="current"
|
|
||||||
@click="showSeriesImage(index,i,series)"
|
|
||||||
>
|
|
||||||
|
|
||||||
<div
|
<div :class="{ 'series-active': i == seriesIndex && index === studyIndex }" class="series-wrapper">
|
||||||
:class="{'series-active': i==seriesIndex && index === studyIndex}"
|
<el-image class="image-preview" :src="series.previewImageUrl" fit="fill" crossorigin="anonymous" />
|
||||||
class="series-wrapper"
|
|
||||||
>
|
|
||||||
<el-image
|
|
||||||
class="image-preview"
|
|
||||||
:src="series.previewImageUrl"
|
|
||||||
fit="fill"
|
|
||||||
crossorigin="anonymous"
|
|
||||||
/>
|
|
||||||
<div class="image-desc">
|
<div class="image-desc">
|
||||||
<div class="flex-div">
|
<div class="flex-div">
|
||||||
<div style="width: 40px;display: flex;flex-direction: row;justify-content: space-between;">
|
<div style="width: 40px;display: flex;flex-direction: row;justify-content: space-between;">
|
||||||
<div v-if="!study.IsCriticalSequence">#{{ series.seriesNumber }}</div>
|
<div v-if="!study.IsCriticalSequence">#{{ series.seriesNumber }}</div>
|
||||||
<div v-if="series.isDicom && series.prefetchInstanceCount<series.instanceCount * 100 && series.modality!== 'SR'">
|
<div
|
||||||
|
v-if="series.isDicom && series.prefetchInstanceCount < series.instanceCount * 100 && series.modality !== 'SR'">
|
||||||
<!-- 下载 -->
|
<!-- 下载 -->
|
||||||
<el-tooltip v-if="!series.isLoading" class="item" effect="dark" :content="$t('trials:reading:button:download')" placement="bottom">
|
<el-tooltip v-if="!series.isLoading" class="item" effect="dark"
|
||||||
<i class="el-icon-video-play" style="font-size: 18px;margin-right: 5px;color: #ffeb3b;cursor: pointer;" @click.stop="loadSeries(series,index,i)" />
|
:content="$t('trials:reading:button:download')" placement="bottom">
|
||||||
|
<i class="el-icon-video-play"
|
||||||
|
style="font-size: 18px;margin-right: 5px;color: #ffeb3b;cursor: pointer;"
|
||||||
|
@click.stop="loadSeries(series, index, i)" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<el-tooltip v-else-if="series.isDicom && series.prefetchInstanceCount === 0 &&series.modality!== 'SR'" class="item" effect="dark" :content="$t('trials:reading:button:download')" placement="bottom">
|
<el-tooltip
|
||||||
<i class="el-icon-video-play" style="font-size: 18px;margin-right: 5px;color: #ffeb3b;cursor: pointer;" @click.stop="loadSeries(series,index,i)" />
|
v-else-if="series.isDicom && series.prefetchInstanceCount === 0 && series.modality !== 'SR'"
|
||||||
|
class="item" effect="dark" :content="$t('trials:reading:button:download')" placement="bottom">
|
||||||
|
<i class="el-icon-video-play"
|
||||||
|
style="font-size: 18px;margin-right: 5px;color: #ffeb3b;cursor: pointer;"
|
||||||
|
@click.stop="loadSeries(series, index, i)" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="series.isExistMutiFrames && series.instanceCount > 1">
|
<div v-if="series.isExistMutiFrames && series.instanceCount > 1">
|
||||||
<el-popover
|
<el-popover placement="right" trigger="hover" popper-class="instance_frame_wrapper">
|
||||||
placement="right"
|
|
||||||
trigger="hover"
|
|
||||||
popper-class="instance_frame_wrapper"
|
|
||||||
>
|
|
||||||
<div class="frame_list">
|
<div class="frame_list">
|
||||||
<div
|
<div v-for="(instance, idx) in series.instanceInfoList" :key="instance.Id"
|
||||||
v-for="(instance, idx) in series.instanceInfoList"
|
class="frame_content" :class="{ 'frame_content_active': activeInstanceId === instance.Id }"
|
||||||
:key="instance.Id"
|
:style="{ 'margin-bottom': idx < series.instanceInfoList.length - 1 ? '5px' : '0px' }"
|
||||||
class="frame_content"
|
@click.stop="showMultiFrames(index, series, i, instance)">
|
||||||
:class="{ 'frame_content_active': activeInstanceId === instance.Id }"
|
|
||||||
:style="{'margin-bottom':idx<series.instanceInfoList.length-1? '5px':'0px'}"
|
|
||||||
@click.stop="showMultiFrames(index,series, i, instance)"
|
|
||||||
>
|
|
||||||
<div>
|
<div>
|
||||||
<div>{{ instance.InstanceNumber }}</div>
|
<div>{{ instance.InstanceNumber }}</div>
|
||||||
<div>{{ `${instance.NumberOfFrames > 0 ? instance.KeyFramesList.length > 0 ? instance.KeyFramesList.length : instance.NumberOfFrames : 1} frame` }}</div>
|
<div>{{ `${instance.NumberOfFrames > 0 ? instance.KeyFramesList.length > 0 ?
|
||||||
|
instance.KeyFramesList.length : instance.NumberOfFrames : 1} frame` }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<i slot="reference" class="el-icon-connection" style="font-size: 15px;cursor: pointer;color: #ffeb3b;" />
|
<i slot="reference" class="el-icon-connection"
|
||||||
|
style="font-size: 15px;cursor: pointer;color: #ffeb3b;" />
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -145,9 +134,11 @@
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="flex-div">
|
<div class="flex-div">
|
||||||
<div v-if="measureData && measureData.findIndex(v=>v.SeriesId === series.seriesId && v.MeasureData) > -1">
|
<div
|
||||||
|
v-if="measureData && measureData.findIndex(v => v.SeriesId === series.seriesId && v.MeasureData) > -1">
|
||||||
<!-- 有标注 -->
|
<!-- 有标注 -->
|
||||||
<el-tooltip class="item" effect="dark" :content="$t('trials:reading:button:marked')" placement="right">
|
<el-tooltip class="item" effect="dark" :content="$t('trials:reading:button:marked')"
|
||||||
|
placement="right">
|
||||||
<i class="el-icon-star-on" style="font-size: 16px;color: #ff5722;" />
|
<i class="el-icon-star-on" style="font-size: 16px;color: #ff5722;" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
|
|
@ -155,10 +146,10 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="series.isDicom && series.prefetchInstanceCount>0 && series.prefetchInstanceCount<series.instanceCount * 100" style="width: 100%;">
|
<div
|
||||||
<el-progress
|
v-if="series.isDicom && series.prefetchInstanceCount > 0 && series.prefetchInstanceCount < series.instanceCount * 100"
|
||||||
:percentage="parseInt((series.prefetchInstanceCount / series.instanceCount).toFixed(2))"
|
style="width: 100%;">
|
||||||
/>
|
<el-progress :percentage="parseInt((series.prefetchInstanceCount / series.instanceCount).toFixed(2))" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -168,24 +159,19 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="sr-wrapper">
|
<div class="sr-wrapper">
|
||||||
<el-dialog
|
<el-dialog :visible.sync="srDialogVisible"
|
||||||
:visible.sync="srDialogVisible"
|
:custom-class="isSrFullscreen ? 'sr-full-dialog-container' : 'sr-dialog-container'" :show-close="false"
|
||||||
:custom-class="isSrFullscreen?'sr-full-dialog-container':'sr-dialog-container'"
|
:close-on-click-modal="false" :fullscreen="isSrFullscreen">
|
||||||
:show-close="false"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
:fullscreen="isSrFullscreen"
|
|
||||||
>
|
|
||||||
<span slot="title" class="dialog-footer">
|
<span slot="title" class="dialog-footer">
|
||||||
<div style="position: absolute;right: 20px;top: 10px;">
|
<div style="position: absolute;right: 20px;top: 10px;">
|
||||||
<svg-icon :icon-class="isSrFullscreen?'exit-fullscreen':'fullscreen'" style="cursor: pointer;font-size: 20px;color:#000;" @click="isSrFullscreen=!isSrFullscreen" />
|
<svg-icon :icon-class="isSrFullscreen ? 'exit-fullscreen' : 'fullscreen'"
|
||||||
<svg-icon icon-class="dClose" style="cursor: pointer;font-size: 25px;margin-left: 10px;" @click="srDialogVisible = false" />
|
style="cursor: pointer;font-size: 20px;color:#000;" @click="isSrFullscreen = !isSrFullscreen" />
|
||||||
|
<svg-icon icon-class="dClose" style="cursor: pointer;font-size: 25px;margin-left: 10px;"
|
||||||
|
@click="srDialogVisible = false" />
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
<div style="height: 100%;margin:0;">
|
<div style="height: 100%;margin:0;">
|
||||||
<SrList
|
<SrList v-if="srDialogVisible" :sr-info="srInfo" />
|
||||||
v-if="srDialogVisible"
|
|
||||||
:sr-info="srInfo"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -296,6 +282,9 @@ export default {
|
||||||
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||||
this.measureData = this.visitTaskList[idx].MeasureData
|
this.measureData = this.visitTaskList[idx].MeasureData
|
||||||
})
|
})
|
||||||
|
DicomEvent.$on("getStudyFile", () => {
|
||||||
|
DicomEvent.$emit('sendStudyFile', { studyList: this.studyList, studyIndex: this.studyIndex, seriesIndex: this.seriesIndex, visitTaskId: this.visitTaskId })
|
||||||
|
})
|
||||||
|
|
||||||
// DicomEvent.$on('setReadingState', readingTaskState => {
|
// DicomEvent.$on('setReadingState', readingTaskState => {
|
||||||
// var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
// var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.visitTaskId)
|
||||||
|
|
@ -320,7 +309,7 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
debounce(fn, delay) {
|
debounce(fn, delay) {
|
||||||
let timer = null
|
let timer = null
|
||||||
return function() {
|
return function () {
|
||||||
const context = this
|
const context = this
|
||||||
const args = arguments
|
const args = arguments
|
||||||
clearTimeout(timer)
|
clearTimeout(timer)
|
||||||
|
|
@ -334,7 +323,7 @@ export default {
|
||||||
// 初始化待渲染序列
|
// 初始化待渲染序列
|
||||||
this.getInitSeries().then((res) => {
|
this.getInitSeries().then((res) => {
|
||||||
requestPoolManager.startTaskTimer()
|
requestPoolManager.startTaskTimer()
|
||||||
res.map(async(item) => {
|
res.map(async (item) => {
|
||||||
// this.loadInitialImage(item)
|
// this.loadInitialImage(item)
|
||||||
const imageId = item.imageIds[item.imageIdIndex]
|
const imageId = item.imageIds[item.imageIdIndex]
|
||||||
const p = parseInt(new Date().getTime())
|
const p = parseInt(new Date().getTime())
|
||||||
|
|
@ -456,8 +445,8 @@ export default {
|
||||||
this.studyIndex = obj.studyIndex
|
this.studyIndex = obj.studyIndex
|
||||||
this.seriesIndex = obj.seriesIndex
|
this.seriesIndex = obj.seriesIndex
|
||||||
seriesList.push(obj.series)
|
seriesList.push(obj.series)
|
||||||
this.activeNames = [`${this.studyList[ this.studyIndex].StudyId}`]
|
this.activeNames = [`${this.studyList[this.studyIndex].StudyId}`]
|
||||||
this.studyList[ obj.studyIndex].SeriesList[obj.seriesIndex].isFirstRender = true
|
this.studyList[obj.studyIndex].SeriesList[obj.seriesIndex].isFirstRender = true
|
||||||
} else {
|
} else {
|
||||||
if (this.studyList.length > 0) {
|
if (this.studyList.length > 0) {
|
||||||
// 初始化问题表单
|
// 初始化问题表单
|
||||||
|
|
@ -494,7 +483,7 @@ export default {
|
||||||
this.studyIndex = secondObj.studyIndex
|
this.studyIndex = secondObj.studyIndex
|
||||||
this.seriesIndex = secondObj.seriesIndex
|
this.seriesIndex = secondObj.seriesIndex
|
||||||
seriesList.push(secondObj.series)
|
seriesList.push(secondObj.series)
|
||||||
this.studyList[ secondObj.studyIndex].SeriesList[secondObj.seriesIndex].isFirstRender = true
|
this.studyList[secondObj.studyIndex].SeriesList[secondObj.seriesIndex].isFirstRender = true
|
||||||
this.studyIndex = secondObj.studyIndex
|
this.studyIndex = secondObj.studyIndex
|
||||||
this.seriesIndex = secondObj.seriesIndex
|
this.seriesIndex = secondObj.seriesIndex
|
||||||
|
|
||||||
|
|
@ -527,7 +516,7 @@ export default {
|
||||||
// const instanceList = seriesList[srIdx].instanceList
|
// const instanceList = seriesList[srIdx].instanceList
|
||||||
const imageIds = seriesList[srIdx].imageIds
|
const imageIds = seriesList[srIdx].imageIds
|
||||||
// const filterStr = seriesList[srIdx].isExistMutiFrames ? `frame=${measureDatas[i].MeasureData.frame}&instanceId=${measureDatas[i].InstanceId}` : `instanceId=${measureDatas[i].InstanceId}`
|
// const filterStr = seriesList[srIdx].isExistMutiFrames ? `frame=${measureDatas[i].MeasureData.frame}&instanceId=${measureDatas[i].InstanceId}` : `instanceId=${measureDatas[i].InstanceId}`
|
||||||
let instanceIndex = seriesList[srIdx].instanceInfoList.findIndex(k=>k.Id === measureDatas[i].InstanceId)
|
let instanceIndex = seriesList[srIdx].instanceInfoList.findIndex(k => k.Id === measureDatas[i].InstanceId)
|
||||||
let filterStr = ''
|
let filterStr = ''
|
||||||
if (instanceIndex > -1 && seriesList[srIdx].isExistMutiFrames) {
|
if (instanceIndex > -1 && seriesList[srIdx].isExistMutiFrames) {
|
||||||
if (seriesList[srIdx].instanceInfoList[instanceIndex].NumberOfFrames > 0) {
|
if (seriesList[srIdx].instanceInfoList[instanceIndex].NumberOfFrames > 0) {
|
||||||
|
|
@ -611,7 +600,7 @@ export default {
|
||||||
// const instanceList = seriesList[srIdx].imageIds
|
// const instanceList = seriesList[srIdx].imageIds
|
||||||
const imageIds = seriesList[srIdx].imageIds
|
const imageIds = seriesList[srIdx].imageIds
|
||||||
// const filterStr = seriesList[srIdx].isExistMutiFrames ? `frame=${measureDatas[mIdx].MeasureData.frame}&instanceId=${measureDatas[mIdx].InstanceId}` : `instanceId=${measureDatas[mIdx].InstanceId}`
|
// const filterStr = seriesList[srIdx].isExistMutiFrames ? `frame=${measureDatas[mIdx].MeasureData.frame}&instanceId=${measureDatas[mIdx].InstanceId}` : `instanceId=${measureDatas[mIdx].InstanceId}`
|
||||||
let instanceIndex = seriesList[srIdx].instanceInfoList.findIndex(i=>i.Id === measureDatas[mIdx].InstanceId)
|
let instanceIndex = seriesList[srIdx].instanceInfoList.findIndex(i => i.Id === measureDatas[mIdx].InstanceId)
|
||||||
let filterStr = ''
|
let filterStr = ''
|
||||||
if (instanceIndex > -1 && seriesList[srIdx].isExistMutiFrames) {
|
if (instanceIndex > -1 && seriesList[srIdx].isExistMutiFrames) {
|
||||||
if (seriesList[srIdx].instanceInfoList[instanceIndex].NumberOfFrames > 0) {
|
if (seriesList[srIdx].instanceInfoList[instanceIndex].NumberOfFrames > 0) {
|
||||||
|
|
@ -968,15 +957,17 @@ export default {
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.study-wrapper{
|
.study-wrapper {
|
||||||
::v-deep .el-progress-bar__inner{
|
::v-deep .el-progress-bar__inner {
|
||||||
transition: width 0s ease;
|
transition: width 0s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
width:100%;
|
width:100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
.dicom-desc{
|
|
||||||
|
.dicom-desc {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
|
@ -985,6 +976,7 @@ export default {
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
.study-meta-line {
|
.study-meta-line {
|
||||||
// display: grid;
|
// display: grid;
|
||||||
// grid-template-columns: minmax(0, 1fr) auto;
|
// grid-template-columns: minmax(0, 1fr) auto;
|
||||||
|
|
@ -994,6 +986,7 @@ export default {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.study-meta-main {
|
.study-meta-main {
|
||||||
display: block;
|
display: block;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
|
@ -1001,11 +994,13 @@ export default {
|
||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.study-code,
|
.study-code,
|
||||||
.study-modality {
|
.study-modality {
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
margin: 0 2px;
|
margin: 0 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.study-desc-text {
|
.study-desc-text {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
@ -1017,19 +1012,23 @@ export default {
|
||||||
overflow-anchor: none;
|
overflow-anchor: none;
|
||||||
touch-action: auto;
|
touch-action: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.series-active {
|
.series-active {
|
||||||
background-color: #607d8b!important;
|
background-color: #607d8b !important;
|
||||||
border: 1px solid #607d8b!important;
|
border: 1px solid #607d8b !important;
|
||||||
}
|
}
|
||||||
::v-deep .el-progress__text{
|
|
||||||
|
::v-deep .el-progress__text {
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
.series{
|
|
||||||
|
.series {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
|
|
||||||
.series-wrapper {
|
.series-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
@ -1042,11 +1041,13 @@ export default {
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
border: 1px solid #404040;
|
border: 1px solid #404040;
|
||||||
background-color: #3a3a3a;
|
background-color: #3a3a3a;
|
||||||
.el-progress__text{
|
|
||||||
|
.el-progress__text {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.el-progress-bar{
|
|
||||||
padding-right:0px;
|
.el-progress-bar {
|
||||||
|
padding-right: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.image-preview {
|
.image-preview {
|
||||||
|
|
@ -1055,9 +1056,11 @@ export default {
|
||||||
border: 2px solid #252525;
|
border: 2px solid #252525;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.image-desc {
|
.image-desc {
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
p{
|
|
||||||
|
p {
|
||||||
width: 95px;
|
width: 95px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
@ -1066,7 +1069,8 @@ export default {
|
||||||
color: #ddd;
|
color: #ddd;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
div{
|
|
||||||
|
div {
|
||||||
width: 95px;
|
width: 95px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
@ -1074,7 +1078,8 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.flex-div{
|
|
||||||
|
.flex-div {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
@ -1091,21 +1096,25 @@ export default {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
::v-deep .el-collapse{
|
|
||||||
|
::v-deep .el-collapse {
|
||||||
border: none;
|
border: none;
|
||||||
.el-collapse-item{
|
|
||||||
background-color: #000!important;
|
.el-collapse-item {
|
||||||
|
background-color: #000 !important;
|
||||||
color: #ddd;
|
color: #ddd;
|
||||||
|
|
||||||
}
|
}
|
||||||
.el-collapse-item__content{
|
|
||||||
padding-bottom:5px;
|
.el-collapse-item__content {
|
||||||
background-color: #000!important;
|
padding-bottom: 5px;
|
||||||
|
background-color: #000 !important;
|
||||||
}
|
}
|
||||||
.el-collapse-item__header{
|
|
||||||
background-color: #000!important;
|
.el-collapse-item__header {
|
||||||
|
background-color: #000 !important;
|
||||||
color: #ddd;
|
color: #ddd;
|
||||||
border-bottom-color:#5a5a5a;
|
border-bottom-color: #5a5a5a;
|
||||||
padding-left: 1px;
|
padding-left: 1px;
|
||||||
min-height: 40px;
|
min-height: 40px;
|
||||||
height: auto;
|
height: auto;
|
||||||
|
|
@ -1114,35 +1123,42 @@ export default {
|
||||||
padding-top: 6px;
|
padding-top: 6px;
|
||||||
padding-bottom: 6px;
|
padding-bottom: 6px;
|
||||||
}
|
}
|
||||||
.el-collapse-item__arrow{
|
|
||||||
|
.el-collapse-item__arrow {
|
||||||
align-self: flex-start;
|
align-self: flex-start;
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.sr-wrapper{
|
|
||||||
::v-deep .el-dialog{
|
.sr-wrapper {
|
||||||
|
::v-deep .el-dialog {
|
||||||
background: #fff !important;
|
background: #fff !important;
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
|
|
||||||
// color: #ddd;
|
// color: #ddd;
|
||||||
.el-dialog__title{
|
.el-dialog__title {
|
||||||
color:#fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
::v-deep .sr-dialog-container{
|
|
||||||
|
::v-deep .sr-dialog-container {
|
||||||
margin-top: 50px !important;
|
margin-top: 50px !important;
|
||||||
width:75%;
|
width: 75%;
|
||||||
height:80%;
|
height: 80%;
|
||||||
}
|
}
|
||||||
::v-deep .el-dialog__body{
|
|
||||||
|
::v-deep .el-dialog__body {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
height: calc(100% - 50px);
|
height: calc(100% - 50px);
|
||||||
}
|
}
|
||||||
.el-dialog__header{
|
|
||||||
|
.el-dialog__header {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
.sr-full-dialog-container{
|
|
||||||
::v-deep .is-fullscreen .el-dialog__body{
|
.sr-full-dialog-container {
|
||||||
|
::v-deep .is-fullscreen .el-dialog__body {
|
||||||
height: calc(100% - 50px);
|
height: calc(100% - 50px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1150,25 +1166,29 @@ export default {
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<style>
|
<style>
|
||||||
.instance_frame_wrapper{
|
.instance_frame_wrapper {
|
||||||
min-width: 120px;
|
min-width: 120px;
|
||||||
background-color: #2c2c2c;
|
background-color: #2c2c2c;
|
||||||
border: 1px solid #2c2c2c;
|
border: 1px solid #2c2c2c;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
.frame_list{
|
|
||||||
|
.frame_list {
|
||||||
max-height: 500px;
|
max-height: 500px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.instance_frame_wrapper ::-webkit-scrollbar {
|
.instance_frame_wrapper ::-webkit-scrollbar {
|
||||||
width: 7px;
|
width: 7px;
|
||||||
height: 7px;
|
height: 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.instance_frame_wrapper ::-webkit-scrollbar-thumb {
|
.instance_frame_wrapper ::-webkit-scrollbar-thumb {
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background: #d0d0d0;
|
background: #d0d0d0;
|
||||||
}
|
}
|
||||||
.frame_content{
|
|
||||||
|
.frame_content {
|
||||||
height: 50px;
|
height: 50px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -1177,6 +1197,7 @@ export default {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
border: 1px solid #404040;
|
border: 1px solid #404040;
|
||||||
}
|
}
|
||||||
|
|
||||||
.frame_content:hover {
|
.frame_content:hover {
|
||||||
/* font-weight: bold; */
|
/* font-weight: bold; */
|
||||||
/* box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); */
|
/* box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); */
|
||||||
|
|
@ -1185,6 +1206,7 @@ export default {
|
||||||
border-color: #213a54 !important;
|
border-color: #213a54 !important;
|
||||||
background-color: #213a54;
|
background-color: #213a54;
|
||||||
}
|
}
|
||||||
|
|
||||||
.frame_content_active {
|
.frame_content_active {
|
||||||
border-color: #213a54 !important;
|
border-color: #213a54 !important;
|
||||||
background-color: #213a54;
|
background-color: #213a54;
|
||||||
|
|
@ -1197,6 +1219,7 @@ export default {
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.patient-info-popper {
|
.patient-info-popper {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #ddd;
|
color: #ddd;
|
||||||
|
|
@ -1221,7 +1244,7 @@ export default {
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.patient-info-popper .patient-info-row + .patient-info-row {
|
.patient-info-popper .patient-info-row+.patient-info-row {
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,204 @@
|
||||||
|
import { dcmUpload } from '@/utils/dcmUpload/dcmUpload'
|
||||||
|
import dcmjs from '@/utils/dcmUpload/dcmjs'
|
||||||
|
import { deleteImageCache, getAnonymizeInfo, updateModality } from '@/api/reading'
|
||||||
|
import * as dicomParser from 'dicom-parser'
|
||||||
|
import * as cornerstone from 'cornerstone-core'
|
||||||
|
import * as cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader'
|
||||||
|
var config = {
|
||||||
|
maxWebWorkers: 4,
|
||||||
|
startWebWorkersOnDemand: true,
|
||||||
|
taskConfiguration: {
|
||||||
|
decodeTask: {
|
||||||
|
initializeCodecsOnStartup: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cornerstoneWADOImageLoader.webWorkerManager.initialize(config)
|
||||||
|
cornerstoneWADOImageLoader.external.dicomParser = dicomParser
|
||||||
|
cornerstoneWADOImageLoader.external.cornerstone = cornerstone
|
||||||
|
import Vue from 'vue'
|
||||||
|
function dicomToPng(imageId, width, height) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
cornerstone.loadImage(imageId).then(async (image) => {
|
||||||
|
let canvas = document.createElement('canvas')
|
||||||
|
canvas.width = (width * 60) / height
|
||||||
|
canvas.height = 60
|
||||||
|
if (image) {
|
||||||
|
cornerstone.renderToCanvas(canvas, image)
|
||||||
|
// 将 Canvas 图像对象转换为 PNG 格式
|
||||||
|
let blob = await canvasToBlob(canvas)
|
||||||
|
resolve(blob)
|
||||||
|
} else {
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}).catch((reason) => {
|
||||||
|
reason()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function canvasToBlob(canvas) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
canvas.toBlob((blob) => {
|
||||||
|
resolve(blob)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async function UpdateModality(params) {
|
||||||
|
try {
|
||||||
|
let res = await updateModality(params)
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function getAnonymize(VisitTaskId, SubjectVisitId) {
|
||||||
|
try {
|
||||||
|
let params = {}
|
||||||
|
if (VisitTaskId) {
|
||||||
|
params.VisitTaskId = VisitTaskId
|
||||||
|
} else {
|
||||||
|
params.SubjectVisitId = SubjectVisitId
|
||||||
|
}
|
||||||
|
let res = await getAnonymizeInfo(params)
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
return res.Result
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function deleteCache(path) {
|
||||||
|
try {
|
||||||
|
let params = {
|
||||||
|
path
|
||||||
|
}
|
||||||
|
let res = await deleteImageCache(params)
|
||||||
|
if (res.IsSuccess) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 0002,0003 MediaStorageSOPInstanceUID
|
||||||
|
* 0008,0018 SOPInstanceUID
|
||||||
|
* 0020,000D StudyInstanceUID
|
||||||
|
* 0020,000E SeriesInstanceUID
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export async function changeFile(key, file, study, image) {
|
||||||
|
// return console.log(study, 'study')
|
||||||
|
let dataset = dcmjs.data.DicomMessage.readFile(image.data.byteArray.buffer)
|
||||||
|
// console.log(dataset, 'dataset')
|
||||||
|
let MediaStorageSOPInstanceUID = dataset.meta['00020003'].Value[0]
|
||||||
|
let SOPInstanceUID = dataset.dict['00080018'].Value[0]
|
||||||
|
let StudyInstanceUID = dataset.dict['0020000D'].Value[0]
|
||||||
|
let SeriesInstanceUID = dataset.dict['0020000E'].Value[0]
|
||||||
|
// let Modality = dataset.dict['00080060'].Value[0]
|
||||||
|
let { visitTaskId, visitTaskList = [], studyList, studyIndex, seriesIndex, seriesList, currentSeriesIndex } = study
|
||||||
|
let series = key === 'IR' ? studyList[studyIndex].SeriesList[seriesIndex] : seriesList[currentSeriesIndex]
|
||||||
|
console.log(series, 'seriesId')
|
||||||
|
let index = visitTaskList.findIndex(i => i.VisitTaskId === visitTaskId)
|
||||||
|
let config = null
|
||||||
|
if (key === 'IR') {
|
||||||
|
config = await getAnonymize(visitTaskId)
|
||||||
|
} else {
|
||||||
|
config = await getAnonymize(null, series.subjectVisitId)
|
||||||
|
}
|
||||||
|
if (!config) return false
|
||||||
|
config.AnonymizeFixedList.push({
|
||||||
|
Element: '0003',
|
||||||
|
Group: '0002',
|
||||||
|
ReplaceValue: MediaStorageSOPInstanceUID,
|
||||||
|
Id: 'MediaStorageSOPInstanceUID'
|
||||||
|
})
|
||||||
|
config.AnonymizeFixedList.push({
|
||||||
|
Element: '0018',
|
||||||
|
Group: '0008',
|
||||||
|
ReplaceValue: SOPInstanceUID,
|
||||||
|
Id: 'SOPInstanceUID'
|
||||||
|
})
|
||||||
|
config.AnonymizeFixedList.push({
|
||||||
|
Element: '000D',
|
||||||
|
Group: '0020',
|
||||||
|
ReplaceValue: StudyInstanceUID,
|
||||||
|
Id: 'StudyInstanceUID'
|
||||||
|
})
|
||||||
|
config.AnonymizeFixedList.push({
|
||||||
|
Element: '000E',
|
||||||
|
Group: '0020',
|
||||||
|
ReplaceValue: SeriesInstanceUID,
|
||||||
|
Id: 'SeriesInstanceUID'
|
||||||
|
})
|
||||||
|
let uploadBatchId = Vue.prototype.$guid()
|
||||||
|
let path = image.imageId.split(`wadouri:${Vue.prototype.OSSclientConfig.basePath}`)[1].split("?")[0]
|
||||||
|
let res = await dcmUpload(
|
||||||
|
{
|
||||||
|
path: path,
|
||||||
|
file: file,
|
||||||
|
speed: true,
|
||||||
|
},
|
||||||
|
config,
|
||||||
|
(percentage, checkpoint, lastPer) => {
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fileName: file.name,
|
||||||
|
fileSize: file.size,
|
||||||
|
fileType: 'application/dicom',
|
||||||
|
uploadBatchId: uploadBatchId,
|
||||||
|
batchDataType: 1,
|
||||||
|
// trialId: params.trialId,
|
||||||
|
subjectId: key === 'IR' ? localStorage.getItem("subjectId") : series.subjectId,
|
||||||
|
subjectVisitId: key === 'IR' ? visitTaskList[index].VisitId : series.subjectVisitId,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if (!res || !res.url) return false
|
||||||
|
let Modality = res.Modality
|
||||||
|
let fileId =
|
||||||
|
cornerstoneWADOImageLoader.wadouri.fileManager.add(
|
||||||
|
file
|
||||||
|
)
|
||||||
|
let blob = await dicomToPng(
|
||||||
|
fileId,
|
||||||
|
image.columns,
|
||||||
|
image.rows
|
||||||
|
)
|
||||||
|
let thumbnailPath = series.previewImageUrl.split(Vue.prototype.OSSclientConfig.basePath)[1]
|
||||||
|
let OSSclient = Vue.prototype.OSSclient
|
||||||
|
try {
|
||||||
|
let seriesRes = await OSSclient.put(thumbnailPath, blob, {
|
||||||
|
fileName: thumbnailPath.split('/')[thumbnailPath.split('/').length - 1],
|
||||||
|
fileSize: blob.size,
|
||||||
|
fileType: 'image/jpeg',
|
||||||
|
uploadBatchId: uploadBatchId,
|
||||||
|
batchDataType: 2,
|
||||||
|
// trialId: params.trialId,
|
||||||
|
subjectId: key === 'IR' ? localStorage.getItem("subjectId") : series.subjectId,
|
||||||
|
subjectVisitId: key === 'IR' ? visitTaskList[index].VisitId : series.subjectVisitId,
|
||||||
|
})
|
||||||
|
console.log(seriesRes, 'seriesRes')
|
||||||
|
if (!seriesRes || !seriesRes.url) return false
|
||||||
|
res = await Promise.all([deleteCache(path), deleteCache(thumbnailPath)])
|
||||||
|
if (!res) return false
|
||||||
|
let params = {
|
||||||
|
Modality,
|
||||||
|
SeriesId: series.seriesId,
|
||||||
|
IsCRCReplace: key === 'IR' ? false : true
|
||||||
|
}
|
||||||
|
res = await UpdateModality(params)
|
||||||
|
if (!res) return false
|
||||||
|
window.location.reload(true)
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -105,6 +105,7 @@
|
||||||
<el-button icon="el-icon-delete" :title="$t('trials:uploadedDicoms:action:delete')" circle
|
<el-button icon="el-icon-delete" :title="$t('trials:uploadedDicoms:action:delete')" circle
|
||||||
:disabled="!isAfresh && data.SubmitState === 2 && data.SubmitTime && moment(data.SubmitTime).isAfter(moment(scope.row.UploadedTime))"
|
:disabled="!isAfresh && data.SubmitState === 2 && data.SubmitTime && moment(data.SubmitTime).isAfter(moment(scope.row.UploadedTime))"
|
||||||
@click="handleDeleteStudy(scope.row)" />
|
@click="handleDeleteStudy(scope.row)" />
|
||||||
|
<el-button icon="el-icon-upload2" title="上传" circle @click="upload(scope.row)" />
|
||||||
<!-- <el-button-->
|
<!-- <el-button-->
|
||||||
<!-- icon="el-icon-toilet-paper"-->
|
<!-- icon="el-icon-toilet-paper"-->
|
||||||
<!-- circle-->
|
<!-- circle-->
|
||||||
|
|
@ -423,7 +424,8 @@
|
||||||
<DicomPreview :uid="uid" :studyList="uploadQueues" />
|
<DicomPreview :uid="uid" :studyList="uploadQueues" />
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<!--pet-ct临床数据上传-->
|
<!--pet-ct临床数据上传-->
|
||||||
<el-dialog v-if="petVisible" :show-close="true" :close-on-click-modal="false" :visible.sync="petVisible" append-to-body>
|
<el-dialog v-if="petVisible" :show-close="true" :close-on-click-modal="false" :visible.sync="petVisible"
|
||||||
|
append-to-body>
|
||||||
<uploadPetClinicalData :subject-visit-id="data.Id" :data="data" :studyData="studyData" :allow-add-or-edit="true"
|
<uploadPetClinicalData :subject-visit-id="data.Id" :data="data" :studyData="studyData" :allow-add-or-edit="true"
|
||||||
@getStudyInfo="getStudyInfo" />
|
@getStudyInfo="getStudyInfo" />
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
@ -650,6 +652,7 @@ export default {
|
||||||
BodyPart: {},
|
BodyPart: {},
|
||||||
|
|
||||||
isClose: false,
|
isClose: false,
|
||||||
|
StudyInstanceUID: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -682,6 +685,10 @@ export default {
|
||||||
this.OSSclient.close()
|
this.OSSclient.close()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
upload(row) {
|
||||||
|
this.StudyInstanceUID = row.StudyInstanceUid
|
||||||
|
this.$refs.pathClear.click()
|
||||||
|
},
|
||||||
handleDragover(e) {
|
handleDragover(e) {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
@ -1274,11 +1281,12 @@ export default {
|
||||||
verifyStudy() {
|
verifyStudy() {
|
||||||
this.btnLoading = true
|
this.btnLoading = true
|
||||||
var studyList = []
|
var studyList = []
|
||||||
|
let scope = this
|
||||||
this.selectArr.forEach((item) => {
|
this.selectArr.forEach((item) => {
|
||||||
item.dicomInfo.uploadFileSize = 0
|
item.dicomInfo.uploadFileSize = 0
|
||||||
if (!item.uploadState.selected) {
|
if (!item.uploadState.selected) {
|
||||||
studyList.push({
|
studyList.push({
|
||||||
studyInstanceUid: item.dicomInfo.studyUid,
|
studyInstanceUid: scope.StudyInstanceUID ? scope.StudyInstanceUID : item.dicomInfo.studyUid,
|
||||||
studyDate: item.dicomInfo.studyTime,
|
studyDate: item.dicomInfo.studyTime,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -1293,6 +1301,8 @@ export default {
|
||||||
batchVerifyStudyAllowUpload(param)
|
batchVerifyStudyAllowUpload(param)
|
||||||
.then(async (res) => {
|
.then(async (res) => {
|
||||||
var messageArr = []
|
var messageArr = []
|
||||||
|
res.Result = []
|
||||||
|
console.log(res)
|
||||||
res.Result.forEach((item) => {
|
res.Result.forEach((item) => {
|
||||||
const i = this.uploadQueues.findIndex(
|
const i = this.uploadQueues.findIndex(
|
||||||
(value) => value.dicomInfo.studyUid === item.StudyInstanceUid
|
(value) => value.dicomInfo.studyUid === item.StudyInstanceUid
|
||||||
|
|
@ -1475,8 +1485,21 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 上传影像并归档
|
// 上传影像并归档
|
||||||
archiveStudy(index, config) {
|
archiveStudy(index, config = {}) {
|
||||||
var scope = this
|
var scope = this
|
||||||
|
try {
|
||||||
|
if (!config.AnonymizeFixedList) config.AnonymizeFixedList = []
|
||||||
|
config.AnonymizeFixedList.push(
|
||||||
|
{
|
||||||
|
Element: '000D',
|
||||||
|
Group: '0020',
|
||||||
|
ReplaceValue: scope.StudyInstanceUID,
|
||||||
|
Id: 'StudyInstanceUID'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
try {
|
try {
|
||||||
preArchiveDicomStudy({
|
preArchiveDicomStudy({
|
||||||
|
|
@ -1506,7 +1529,7 @@ export default {
|
||||||
let t = setInterval(() => {
|
let t = setInterval(() => {
|
||||||
dicomUploadInProgress({
|
dicomUploadInProgress({
|
||||||
trialId: scope.trialId,
|
trialId: scope.trialId,
|
||||||
studyInstanceUid: dicomInfo.studyUid,
|
studyInstanceUid: scope.StudyInstanceUID ? scope.StudyInstanceUID : dicomInfo.studyUid,
|
||||||
}).then((res) => { })
|
}).then((res) => { })
|
||||||
}, 5000)
|
}, 5000)
|
||||||
scope.myInterval.push(t)
|
scope.myInterval.push(t)
|
||||||
|
|
@ -1531,7 +1554,7 @@ export default {
|
||||||
dicomInfo.RadiopharmaceuticalStartTime,
|
dicomInfo.RadiopharmaceuticalStartTime,
|
||||||
|
|
||||||
studyId: dicomInfo.studyId,
|
studyId: dicomInfo.studyId,
|
||||||
studyInstanceUid: dicomInfo.studyUid,
|
studyInstanceUid: scope.StudyInstanceUID ? scope.StudyInstanceUID : dicomInfo.studyUid,
|
||||||
studyTime: dicomInfo.studyTime,
|
studyTime: dicomInfo.studyTime,
|
||||||
description: dicomInfo.description,
|
description: dicomInfo.description,
|
||||||
seriesCount: dicomInfo.seriesNum,
|
seriesCount: dicomInfo.seriesNum,
|
||||||
|
|
@ -1714,7 +1737,7 @@ export default {
|
||||||
}
|
}
|
||||||
if (res && res.url) {
|
if (res && res.url) {
|
||||||
instanceList.push({
|
instanceList.push({
|
||||||
studyInstanceUid: dicomInfo.studyUid,
|
studyInstanceUid: scope.StudyInstanceUID ? scope.StudyInstanceUID : dicomInfo.studyUid,
|
||||||
seriesInstanceUid: v.seriesUid,
|
seriesInstanceUid: v.seriesUid,
|
||||||
SOPClassUID: o.SOPClassUID,
|
SOPClassUID: o.SOPClassUID,
|
||||||
TransferSytaxUID: o.TransferSytaxUID,
|
TransferSytaxUID: o.TransferSytaxUID,
|
||||||
|
|
@ -1781,7 +1804,7 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
params.study.seriesList.push({
|
params.study.seriesList.push({
|
||||||
studyInstanceUid: dicomInfo.studyUid,
|
studyInstanceUid: scope.StudyInstanceUID ? scope.StudyInstanceUID : dicomInfo.studyUid,
|
||||||
seriesInstanceUid: v.seriesUid,
|
seriesInstanceUid: v.seriesUid,
|
||||||
seriesNumber: v.seriesNumber,
|
seriesNumber: v.seriesNumber,
|
||||||
seriesTime: v.seriesTime,
|
seriesTime: v.seriesTime,
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ module.exports = defineConfig({
|
||||||
},
|
},
|
||||||
|
|
||||||
'/api': {
|
'/api': {
|
||||||
target: 'http://106.14.89.110:30000',
|
target: 'http://192.168.3.99:6100',
|
||||||
// target: 'http://101.132.253.119:7010', // uat
|
// target: 'http://101.132.253.119:7010', // uat
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
secure: false,
|
secure: false,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue