pt临床数据更改
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
946203f124
commit
f7dd68f7f3
|
|
@ -285,14 +285,14 @@
|
||||||
|
|
||||||
<!-- 患者信息 -->
|
<!-- 患者信息 -->
|
||||||
<div class="measureTool-wrapper patient-form"
|
<div class="measureTool-wrapper patient-form"
|
||||||
v-if="isHaveStudyClinicalData && type === 'Study' && modality && ['PT、CT', 'CT、PT', 'PET-CT'].includes(modality)">
|
v-if="type === 'Study' && modality && ['PT、CT', 'CT、PT', 'PET-CT'].includes(modality)">
|
||||||
<div class="sideTool-title">{{ $t('trials:tab:patientData') }}</div>
|
<div class="sideTool-title">{{ $t('trials:tab:patientData') }}</div>
|
||||||
<div class="sideTool-wrapper">
|
<div class="sideTool-wrapper">
|
||||||
<el-form ref="patientForm" :model="formData" :rules="rules" label-width="150" v-loading="formLoading">
|
<el-form ref="patientForm" size="mini" :model="formData" :rules="rules" label-width="150" v-loading="formLoading">
|
||||||
<!-- 性别 -->
|
<!-- 性别 -->
|
||||||
<el-form-item :label="$t('trials:ptData:label:patientSex')" prop="PatientSex">
|
<el-form-item :label="$t('trials:ptData:label:patientSex')" prop="PatientSex">
|
||||||
<el-select v-model="formData.PatientSex" :placeholder="$t('common:ruleMessage:select')"
|
<el-select v-model="formData.PatientSex" :placeholder="$t('common:ruleMessage:select')"
|
||||||
style="width: 100%" size="small" :disabled="!isEdit">
|
style="width: 100%" :disabled="!isEdit">
|
||||||
<el-option :label="$t('trials:patientSex:male')" value="M"></el-option>
|
<el-option :label="$t('trials:patientSex:male')" value="M"></el-option>
|
||||||
<el-option :label="$t('trials:patientSex:female')" value="F"></el-option>
|
<el-option :label="$t('trials:patientSex:female')" value="F"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
|
|
@ -300,32 +300,32 @@
|
||||||
<!-- 体重(kg) 例如 70.5-->
|
<!-- 体重(kg) 例如 70.5-->
|
||||||
<el-form-item :label="$t('trials:ptData:label:patientWeight')" prop="PatientWeight">
|
<el-form-item :label="$t('trials:ptData:label:patientWeight')" prop="PatientWeight">
|
||||||
<el-input v-model.number="formData.PatientWeight" :placeholder="$t('trials:patientWeight:eg')"
|
<el-input v-model.number="formData.PatientWeight" :placeholder="$t('trials:patientWeight:eg')"
|
||||||
style="width: 100%" size="small" :disabled="!isEdit"></el-input>
|
style="width: 100%" :disabled="!isEdit"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 总剂量(Bq) 例如 740000000-->
|
<!-- 总剂量(Bq) 例如 740000000-->
|
||||||
<el-form-item :label="$t('trials:ptData:label:totalDose')" prop="RadionuclideTotalDose">
|
<el-form-item :label="$t('trials:ptData:label:totalDose')" prop="RadionuclideTotalDose">
|
||||||
<el-input v-model.number="formData.RadionuclideTotalDose" :placeholder="$t('trials:totalDose:eg')"
|
<el-input v-model.number="formData.RadionuclideTotalDose" :placeholder="$t('trials:totalDose:eg')"
|
||||||
style="width: 100%" size="small" :disabled="!isEdit"></el-input>
|
style="width: 100%" :disabled="!isEdit"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 半衰期(s) 例如 21600-->
|
<!-- 半衰期(s) 例如 21600-->
|
||||||
<el-form-item :label="$t('trials:ptData:label:halfLife')" prop="RadionuclideHalfLife">
|
<el-form-item :label="$t('trials:ptData:label:halfLife')" prop="RadionuclideHalfLife">
|
||||||
<el-input v-model.number="formData.RadionuclideHalfLife" :placeholder="$t('trials:halfLife:eg')"
|
<el-input v-model.number="formData.RadionuclideHalfLife" :placeholder="$t('trials:halfLife:eg')"
|
||||||
style="width: 100%" size="small" :disabled="!isEdit"></el-input>
|
style="width: 100%" :disabled="!isEdit"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 注射时间(s) Unix 秒 或 相对秒-->
|
<!-- 注射时间(s) Unix 秒 或 相对秒-->
|
||||||
<el-form-item :label="$t('trials:ptData:label:injectTime')" prop="RadiopharmaceuticalStartTime">
|
<el-form-item :label="$t('trials:ptData:label:injectTime')" prop="RadiopharmaceuticalStartTime">
|
||||||
<el-input v-model.number="formData.RadiopharmaceuticalStartTime" :placeholder="$t('trials:injectTime:eg')"
|
<el-input v-model.number="formData.RadiopharmaceuticalStartTime" :placeholder="$t('trials:injectTime:eg')"
|
||||||
style="width: 100%" @input="computeTimeRelation" size="small" :disabled="!isEdit"></el-input>
|
style="width: 100%" @input="computeTimeRelation" :disabled="!isEdit"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 成像时间(s) Unix 秒 或 相对秒-->
|
<!-- 成像时间(s) Unix 秒 或 相对秒-->
|
||||||
<el-form-item :label="$t('trials:ptData:label:acquisitionTime')" prop="AcquisitionTime">
|
<el-form-item :label="$t('trials:ptData:label:acquisitionTime')" prop="AcquisitionTime">
|
||||||
<el-input v-model.number="formData.AcquisitionTime" :placeholder="$t('trials:injectTime:eg')"
|
<el-input v-model.number="formData.AcquisitionTime" :placeholder="$t('trials:injectTime:eg')"
|
||||||
style="width: 100%" @input="computeTimeRelation" size="small" :disabled="!isEdit"></el-input>
|
style="width: 100%" @input="computeTimeRelation" :disabled="!isEdit"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 时间一致性检查 -->
|
<!-- 时间一致性检查 -->
|
||||||
<el-form-item :label="$t('trials:ptData:label:timeCheck')">
|
<!-- <el-form-item :label="$t('trials:ptData:label:timeCheck')">
|
||||||
<el-input v-model="formData.TimeCheck" disabled style="width: 100%" size="small"></el-input>
|
<el-input v-model="formData.TimeCheck" disabled style="width: 100%"></el-input>
|
||||||
</el-form-item>
|
</el-form-item> -->
|
||||||
|
|
||||||
<!-- 提交 -->
|
<!-- 提交 -->
|
||||||
<el-form-item style="margin-top: 20px;text-align: right;" v-if="isEdit">
|
<el-form-item style="margin-top: 20px;text-align: right;" v-if="isEdit">
|
||||||
|
|
@ -363,6 +363,7 @@ import {
|
||||||
getPatientInfo,
|
getPatientInfo,
|
||||||
editPatientInfo
|
editPatientInfo
|
||||||
} from '@/api/trials'
|
} from '@/api/trials'
|
||||||
|
import { setPTClinicalDataForInstance } from '@/utils/ptClinicalDataCache'
|
||||||
export default {
|
export default {
|
||||||
name: 'DicomsViewer',
|
name: 'DicomsViewer',
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -379,6 +380,20 @@ export default {
|
||||||
default: ''
|
default: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
modality: {
|
||||||
|
immediate: true,
|
||||||
|
handler(v) {
|
||||||
|
if (v) {
|
||||||
|
if (this.type === 'Study' && ['PT、CT', 'CT、PT', 'PET-CT'].includes(v)) {
|
||||||
|
this.$nextTick(()=>{
|
||||||
|
this.getPatientInfo()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isAnonymous: false,
|
isAnonymous: false,
|
||||||
|
|
@ -444,7 +459,6 @@ export default {
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
formLoading: false,
|
formLoading: false,
|
||||||
isHaveStudyClinicalData: false,
|
|
||||||
type: '',
|
type: '',
|
||||||
isEdit: 0
|
isEdit: 0
|
||||||
}
|
}
|
||||||
|
|
@ -459,12 +473,8 @@ export default {
|
||||||
this.wwwcList[0] = '-1'
|
this.wwwcList[0] = '-1'
|
||||||
this.colormapsList = cornerstone.colors.getColormapsList()
|
this.colormapsList = cornerstone.colors.getColormapsList()
|
||||||
this.currentDicomCanvas = this.$refs['dicomCanvas0']
|
this.currentDicomCanvas = this.$refs['dicomCanvas0']
|
||||||
this.isHaveStudyClinicalData = this.$route.query.isHaveStudyClinicalData === 'true'
|
|
||||||
this.type = this.$route.query.type
|
this.type = this.$route.query.type
|
||||||
this.isEdit = parseInt(this.$route.query.showDelete)
|
this.isEdit = parseInt(this.$route.query.showDelete)
|
||||||
if (this.isHaveStudyClinicalData && this.type === 'Study' && ['PT、CT', 'CT、PT', 'PET-CT'].includes(this.modality)) {
|
|
||||||
this.getPatientInfo()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -820,7 +830,7 @@ export default {
|
||||||
try {
|
try {
|
||||||
this.formLoading = true
|
this.formLoading = true
|
||||||
let studyId = this.$route.query.studyId
|
let studyId = this.$route.query.studyId
|
||||||
let res = await getPatientInfo({ studyId: studyId })
|
let res = await getPatientInfo({studyId: studyId})
|
||||||
this.formData = {
|
this.formData = {
|
||||||
Id: res.Result.Id || '',
|
Id: res.Result.Id || '',
|
||||||
PatientSex: res.Result.PatientSex || '',
|
PatientSex: res.Result.PatientSex || '',
|
||||||
|
|
@ -832,12 +842,88 @@ export default {
|
||||||
TimeCheck: ''
|
TimeCheck: ''
|
||||||
}
|
}
|
||||||
this.computeTimeRelation()
|
this.computeTimeRelation()
|
||||||
|
// 缓存 PT 临床数据:用于 2D SUV 计算时优先使用接口/人工录入值
|
||||||
|
this.cachePtClinicalDataToInstances()
|
||||||
this.formLoading = false
|
this.formLoading = false
|
||||||
} catch (e) {
|
} catch(e) {
|
||||||
this.formLoading = false
|
this.formLoading = false
|
||||||
console.log(e)
|
console.log(e)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
cachePtClinicalDataToInstances() {
|
||||||
|
const clinicalData = {
|
||||||
|
PatientSex: this.formData.PatientSex,
|
||||||
|
PatientWeight: this.formData.PatientWeight,
|
||||||
|
RadionuclideTotalDose: this.formData.RadionuclideTotalDose,
|
||||||
|
RadionuclideHalfLife: this.formData.RadionuclideHalfLife,
|
||||||
|
RadiopharmaceuticalStartTime: this.formData.RadiopharmaceuticalStartTime,
|
||||||
|
AcquisitionTime: this.formData.AcquisitionTime
|
||||||
|
}
|
||||||
|
const seriesList = Array.isArray(this.seriesList) ? this.seriesList : []
|
||||||
|
seriesList.forEach(series => {
|
||||||
|
const instanceInfoList = series?.instanceInfoList
|
||||||
|
if (Array.isArray(instanceInfoList) && instanceInfoList.length > 0) {
|
||||||
|
instanceInfoList.forEach(instance => {
|
||||||
|
if (instance && instance.Id != null) {
|
||||||
|
setPTClinicalDataForInstance(instance.Id, clinicalData)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const imageIds = series?.imageIds
|
||||||
|
if (Array.isArray(imageIds) && imageIds.length > 0) {
|
||||||
|
imageIds.forEach(imageId => {
|
||||||
|
const instanceId = this.getInstanceIdFromImageId(imageId)
|
||||||
|
if (instanceId) {
|
||||||
|
setPTClinicalDataForInstance(instanceId, clinicalData)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getInstanceIdFromImageId(imageId) {
|
||||||
|
try {
|
||||||
|
const qIndex = String(imageId).indexOf('?')
|
||||||
|
if (qIndex === -1) return null
|
||||||
|
const params = new URLSearchParams(String(imageId).slice(qIndex + 1))
|
||||||
|
const instanceId = params.get('instanceId')
|
||||||
|
return instanceId ? String(instanceId).trim() : null
|
||||||
|
} catch (e) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
refreshDicomAfterClinicalDataChanged() {
|
||||||
|
// 患者信息保存后,强制刷新画布与标注统计,确保 SUV 等数据显示使用最新的 PT 临床数据口径
|
||||||
|
const toolTypes = [
|
||||||
|
'Probe',
|
||||||
|
'RectangleRoi',
|
||||||
|
'EllipticalRoi',
|
||||||
|
'FreehandRoi',
|
||||||
|
'Bidirectional',
|
||||||
|
'Length',
|
||||||
|
'ArrowAnnotate',
|
||||||
|
'Angle',
|
||||||
|
'CobbAngle'
|
||||||
|
]
|
||||||
|
const elements = document.querySelectorAll('.dicom-item')
|
||||||
|
Array.from(elements).forEach((wrapper) => {
|
||||||
|
const index = wrapper.getAttribute('data-index')
|
||||||
|
const canvasComp = index !== null ? this.$refs[`dicomCanvas${index}`] : null
|
||||||
|
const element = canvasComp?.$refs?.canvas
|
||||||
|
if (!element) return
|
||||||
|
toolTypes.forEach((toolType) => {
|
||||||
|
const toolState = cornerstoneTools.getToolState(element, toolType)
|
||||||
|
if (toolState && Array.isArray(toolState.data)) {
|
||||||
|
toolState.data.forEach((d) => {
|
||||||
|
if (d && typeof d === 'object') {
|
||||||
|
d.invalidated = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
cornerstone.updateImage(element, true)
|
||||||
|
})
|
||||||
|
},
|
||||||
async submitForm() {
|
async submitForm() {
|
||||||
try {
|
try {
|
||||||
let valid = await this.$refs.patientForm.validate()
|
let valid = await this.$refs.patientForm.validate()
|
||||||
|
|
@ -847,6 +933,8 @@ export default {
|
||||||
this.formLoading = false
|
this.formLoading = false
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||||
|
this.cachePtClinicalDataToInstances()
|
||||||
|
this.refreshDicomAfterClinicalDataChanged()
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.formLoading = false
|
this.formLoading = false
|
||||||
|
|
@ -910,28 +998,28 @@ export default {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
|
|
||||||
.btn {
|
|
||||||
width: 15%;
|
|
||||||
text-align: center;
|
|
||||||
height: 40px;
|
|
||||||
line-height: 30px;
|
|
||||||
border-radius: 15px;
|
|
||||||
background-color: rgba(255, 255, 255, .3);
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 5px 10px;
|
|
||||||
border: 1px solid rgba(255, 255, 255, .7);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: rgba(255, 255, 255, .5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.activeBtn {
|
|
||||||
background-color: rgba(255, 255, 255, .5);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.Anonymous .btn {
|
||||||
|
width: 15%;
|
||||||
|
text-align: center;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 30px;
|
||||||
|
border-radius: 15px;
|
||||||
|
background-color: rgba(255, 255, 255, .3);
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border: 1px solid rgba(255, 255, 255, .7);
|
||||||
|
}
|
||||||
|
.Anonymous .btn:hover {
|
||||||
|
background-color: rgba(255, 255, 255, .5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.Anonymous .activeBtn {
|
||||||
|
background-color: rgba(255, 255, 255, .5);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.btnBox {
|
.btnBox {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 80px;
|
width: 80px;
|
||||||
|
|
@ -1200,11 +1288,20 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.patient-form .el-form-item {
|
.patient-form .el-form-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.patient-form .el-form-item__label {
|
.patient-form .el-form-item__label {
|
||||||
color: #d0d0d0;
|
color: #d0d0d0;
|
||||||
|
flex: 0 0 150px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.patient-form .el-form-item__content {
|
||||||
|
flex: 1;
|
||||||
|
margin-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.patient-form .el-input.is-disabled .el-input__inner {
|
.patient-form .el-input.is-disabled .el-input__inner {
|
||||||
|
|
|
||||||
|
|
@ -932,6 +932,12 @@ const actions = {
|
||||||
data.IsDicom = study.IsDicom
|
data.IsDicom = study.IsDicom
|
||||||
data.PreviewImageCount = 0
|
data.PreviewImageCount = 0
|
||||||
data.IsCriticalSequence = study.IsCriticalSequence
|
data.IsCriticalSequence = study.IsCriticalSequence
|
||||||
|
data.PatientSex = study.PatientSex
|
||||||
|
data.PatientWeight = study.PatientWeight
|
||||||
|
data.RadionuclideHalfLife = study.RadionuclideHalfLife
|
||||||
|
data.RadionuclideTotalDose = study.RadionuclideTotalDose
|
||||||
|
data.RadiopharmaceuticalStartTime = study.RadiopharmaceuticalStartTime
|
||||||
|
data.AcquisitionTime = study.AcquisitionTime
|
||||||
var seriesList = []
|
var seriesList = []
|
||||||
study.SeriesList.forEach((series, seriesIndex) => {
|
study.SeriesList.forEach((series, seriesIndex) => {
|
||||||
const imageIds = []
|
const imageIds = []
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
import * as cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader'
|
import * as cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader'
|
||||||
|
import store from '@/store'
|
||||||
|
import { getPTClinicalDataForInstance } from '@/utils/ptClinicalDataCache'
|
||||||
import {
|
import {
|
||||||
getImageTypeSubItemFromDataset,
|
getImageTypeSubItemFromDataset,
|
||||||
extractOrientationFromDataset,
|
extractOrientationFromDataset,
|
||||||
|
|
@ -6,6 +8,87 @@ import {
|
||||||
extractSpacingFromDataset,
|
extractSpacingFromDataset,
|
||||||
extractSliceThicknessFromDataset,
|
extractSliceThicknessFromDataset,
|
||||||
} from './extractPositioningFromDataset';
|
} from './extractPositioningFromDataset';
|
||||||
|
|
||||||
|
function toNumber(val) {
|
||||||
|
if (val === undefined || val === null || val === '') return null;
|
||||||
|
const n = typeof val === 'number' ? val : parseFloat(val);
|
||||||
|
return Number.isFinite(n) ? n : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseDicomTimeToObject(value) {
|
||||||
|
if (value === undefined || value === null || value === '') return null;
|
||||||
|
const raw = String(value).trim();
|
||||||
|
if (!raw) return null;
|
||||||
|
const cleaned = raw.replace(/[^\d.]/g, '');
|
||||||
|
if (!cleaned) return null;
|
||||||
|
const [baseRaw, fracRaw] = cleaned.split('.');
|
||||||
|
const base = `${baseRaw || ''}`.padStart(6, '0').slice(-6);
|
||||||
|
const hours = toNumber(base.slice(0, 2)) ?? 0;
|
||||||
|
const minutes = toNumber(base.slice(2, 4)) ?? 0;
|
||||||
|
const seconds = toNumber(base.slice(4, 6)) ?? 0;
|
||||||
|
const fractionalSeconds = `${fracRaw || ''}`.padEnd(6, '0').slice(0, 6);
|
||||||
|
if (!Number.isFinite(hours) || !Number.isFinite(minutes) || !Number.isFinite(seconds)) return null;
|
||||||
|
return { hours, minutes, seconds, fractionalSeconds };
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFirstSequenceItemDataSet(dataSet, tag) {
|
||||||
|
const el = dataSet?.elements?.[tag];
|
||||||
|
const item = el?.items?.[0];
|
||||||
|
return item?.dataSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getIntString(dataSet, tag) {
|
||||||
|
if (!dataSet) return undefined;
|
||||||
|
if (typeof dataSet.intString === 'function') {
|
||||||
|
return dataSet.intString(tag);
|
||||||
|
}
|
||||||
|
const raw = dataSet.string(tag);
|
||||||
|
const n = raw != null ? parseInt(raw, 10) : NaN;
|
||||||
|
return Number.isFinite(n) ? n : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPTClinicalOverrideFromImageId(imageId) {
|
||||||
|
try {
|
||||||
|
const qIndex0 = imageId.indexOf('?');
|
||||||
|
if (qIndex0 !== -1) {
|
||||||
|
const params0 = new URLSearchParams(imageId.slice(qIndex0 + 1));
|
||||||
|
const instanceId0 = params0.get('instanceId');
|
||||||
|
if (instanceId0) {
|
||||||
|
const cached = getPTClinicalDataForInstance(instanceId0);
|
||||||
|
if (cached) return cached;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const qIndex = imageId.indexOf('?');
|
||||||
|
if (qIndex === -1) return null;
|
||||||
|
const params = new URLSearchParams(imageId.slice(qIndex + 1));
|
||||||
|
const visitTaskId = params.get('visitTaskId');
|
||||||
|
const idx = params.get('idx');
|
||||||
|
if (!visitTaskId || !idx) return null;
|
||||||
|
const parts = idx.split('|');
|
||||||
|
const studyIndex = toNumber(parts[0]);
|
||||||
|
if (!Number.isInteger(studyIndex) || studyIndex < 0) return null;
|
||||||
|
|
||||||
|
const visitTaskList = store?.state?.reading?.visitTaskList;
|
||||||
|
if (!Array.isArray(visitTaskList)) return null;
|
||||||
|
const visitTaskInfo = visitTaskList.find(v => v && v.VisitTaskId === visitTaskId);
|
||||||
|
const study = visitTaskInfo?.StudyList?.[studyIndex];
|
||||||
|
if (!study) return null;
|
||||||
|
|
||||||
|
if (
|
||||||
|
study.PatientWeight == null &&
|
||||||
|
study.RadionuclideTotalDose == null &&
|
||||||
|
study.RadionuclideHalfLife == null &&
|
||||||
|
study.RadiopharmaceuticalStartTime == null &&
|
||||||
|
study.AcquisitionTime == null &&
|
||||||
|
study.PatientSex == null
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return study;
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
function parseImageId(imageId) {
|
function parseImageId(imageId) {
|
||||||
// build a url by parsing out the url scheme and frame index from the imageId
|
// build a url by parsing out the url scheme and frame index from the imageId
|
||||||
const firstColonIndex = imageId.indexOf(':');
|
const firstColonIndex = imageId.indexOf(':');
|
||||||
|
|
@ -168,6 +251,65 @@ function metaDataProvider(type, imageId) {
|
||||||
if (!dataSet) {
|
if (!dataSet) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const ptOverride = getPTClinicalOverrideFromImageId(imageId);
|
||||||
|
if (type === 'generalSeriesModule') {
|
||||||
|
// 参照 cornerstoneWADOImageLoader 的 module 结构返回,避免调用方拿不到预期字段
|
||||||
|
const dicomParser = cornerstoneWADOImageLoader?.external?.dicomParser;
|
||||||
|
const modality = dataSet.string('x00080060');
|
||||||
|
const seriesDateRaw = dataSet.string('x00080021') || '';
|
||||||
|
const seriesTimeRaw = dataSet.string('x00080031') || '';
|
||||||
|
const acquisitionDateRaw = dataSet.string('x00080022') || '';
|
||||||
|
const acquisitionTimeRaw = dataSet.string('x00080032') || '';
|
||||||
|
const seriesTimeValue = ptOverride?.AcquisitionTime ?? seriesTimeRaw;
|
||||||
|
return {
|
||||||
|
modality,
|
||||||
|
seriesInstanceUID: dataSet.string('x0020000e'),
|
||||||
|
seriesNumber: getIntString(dataSet, 'x00200011'),
|
||||||
|
studyInstanceUID: dataSet.string('x0020000d'),
|
||||||
|
seriesDate: dicomParser?.parseDA ? dicomParser.parseDA(seriesDateRaw) : seriesDateRaw,
|
||||||
|
seriesTime: dicomParser?.parseTM ? dicomParser.parseTM(seriesTimeValue || '') : parseDicomTimeToObject(seriesTimeValue),
|
||||||
|
acquisitionDate: dicomParser?.parseDA ? dicomParser.parseDA(acquisitionDateRaw) : acquisitionDateRaw,
|
||||||
|
acquisitionTime: dicomParser?.parseTM ? dicomParser.parseTM(acquisitionTimeRaw || '') : parseDicomTimeToObject(acquisitionTimeRaw)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (type === 'patientStudyModule') {
|
||||||
|
// 参照 cornerstoneWADOImageLoader 的 module 结构返回
|
||||||
|
const patientWeightRaw = dataSet.floatString('x00101030') || dataSet.string('x00101030');
|
||||||
|
// const patientSexRaw = dataSet.string('x00100040');
|
||||||
|
const patientSizeRaw = dataSet.floatString('x00101020') || dataSet.string('x00101020');
|
||||||
|
const patientAge = getIntString(dataSet, 'x00101010');
|
||||||
|
const patientWeight = toNumber(ptOverride?.PatientWeight ?? patientWeightRaw);
|
||||||
|
// const patientSex = ptOverride?.PatientSex ?? patientSexRaw;
|
||||||
|
const patientSize = toNumber(patientSizeRaw);
|
||||||
|
return {
|
||||||
|
patientAge,
|
||||||
|
patientWeight,
|
||||||
|
// patientSex,
|
||||||
|
patientSize
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (type === 'petIsotopeModule') {
|
||||||
|
// 统一 SUV 口径:优先使用接口/人工录入的 PT 临床数据,缺失时回退读取 DICOM Tag
|
||||||
|
// 同时保持与 cornerstoneWADOImageLoader 返回结构一致(radiopharmaceuticalInfo.*)
|
||||||
|
const dicomParser = cornerstoneWADOImageLoader?.external?.dicomParser;
|
||||||
|
const radioPharmItem = getFirstSequenceItemDataSet(dataSet, 'x00540016');
|
||||||
|
const startTimeRaw = radioPharmItem?.string?.('x00181072') || dataSet.string('x00181072');
|
||||||
|
const totalDoseRaw = radioPharmItem?.floatString?.('x00181074') || radioPharmItem?.string?.('x00181074') || dataSet.floatString('x00181074') || dataSet.string('x00181074');
|
||||||
|
const halfLifeRaw = radioPharmItem?.floatString?.('x00181075') || radioPharmItem?.string?.('x00181075') || dataSet.floatString('x00181075') || dataSet.string('x00181075');
|
||||||
|
const startTimeValue = ptOverride?.RadiopharmaceuticalStartTime ?? startTimeRaw;
|
||||||
|
const radiopharmaceuticalStartTime = dicomParser?.parseTM
|
||||||
|
? dicomParser.parseTM(startTimeValue || '')
|
||||||
|
: parseDicomTimeToObject(startTimeValue);
|
||||||
|
const radionuclideTotalDose = toNumber(ptOverride?.RadionuclideTotalDose ?? totalDoseRaw);
|
||||||
|
const radionuclideHalfLife = toNumber(ptOverride?.RadionuclideHalfLife ?? halfLifeRaw);
|
||||||
|
return {
|
||||||
|
radiopharmaceuticalInfo: {
|
||||||
|
radiopharmaceuticalStartTime,
|
||||||
|
radionuclideTotalDose,
|
||||||
|
radionuclideHalfLife
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
if (type === 'imagePlaneModule') {
|
if (type === 'imagePlaneModule') {
|
||||||
// const imageOrientationPatient = getNumberValues(dataSet, 'x00200037', 6);
|
// const imageOrientationPatient = getNumberValues(dataSet, 'x00200037', 6);
|
||||||
// const imagePositionPatient = getNumberValues(dataSet, 'x00200032', 3);
|
// const imagePositionPatient = getNumberValues(dataSet, 'x00200032', 3);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
// PT 临床数据缓存:用于统一 SUV 口径(优先接口,缺失则回退 DICOM 元数据)
|
||||||
|
const instanceIdToClinicalData = new Map()
|
||||||
|
|
||||||
|
function normalizeId(id) {
|
||||||
|
if (id === undefined || id === null) return null
|
||||||
|
const s = String(id).trim()
|
||||||
|
return s ? s : null
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setPTClinicalDataForInstance(instanceId, clinicalData) {
|
||||||
|
const key = normalizeId(instanceId)
|
||||||
|
if (!key) return
|
||||||
|
if (!clinicalData || typeof clinicalData !== 'object') return
|
||||||
|
instanceIdToClinicalData.set(key, clinicalData)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPTClinicalDataForInstance(instanceId) {
|
||||||
|
const key = normalizeId(instanceId)
|
||||||
|
if (!key) return null
|
||||||
|
return instanceIdToClinicalData.get(key) || null
|
||||||
|
}
|
||||||
|
|
||||||
|
export function clearPTClinicalDataCache() {
|
||||||
|
instanceIdToClinicalData.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -539,7 +539,7 @@
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<!-- 其他 -->
|
<!-- 其他 -->
|
||||||
<el-tab-pane :label="$t('trials:reading:tab:others')" name="3">
|
<el-tab-pane :label="$t('trials:reading:tab:others')" name="3">
|
||||||
<Others v-if="activeName === '3'" />
|
<Others v-if="activeName === '3'" :imageToolType="1"/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { metaData } from '@cornerstonejs/core'
|
import { metaData } from '@cornerstonejs/core'
|
||||||
// import { InstanceMetadata } from '@cornerstonejs/calculate-suv'
|
// import { InstanceMetadata } from '@cornerstonejs/calculate-suv'
|
||||||
import cornerstoneDICOMImageLoader from '@cornerstonejs/dicom-image-loader'
|
import cornerstoneDICOMImageLoader from '@cornerstonejs/dicom-image-loader'
|
||||||
|
import { getPTClinicalDataForInstance } from '@/utils/ptClinicalDataCache'
|
||||||
function parseImageId(imageId) {
|
function parseImageId(imageId) {
|
||||||
// build a url by parsing out the url scheme and frame index from the imageId
|
// build a url by parsing out the url scheme and frame index from the imageId
|
||||||
const firstColonIndex = imageId.indexOf(':')
|
const firstColonIndex = imageId.indexOf(':')
|
||||||
|
|
@ -42,6 +43,9 @@ function getMetaData(type, imageId) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export default function getPTImageIdInstanceMetadata(imageId) {
|
export default function getPTImageIdInstanceMetadata(imageId) {
|
||||||
|
const instanceId = getInstanceIdFromImageId(imageId)
|
||||||
|
// 统一 SUV 口径:若接口存在 PT 临床数据,则优先覆盖 DICOM 元数据
|
||||||
|
const ptClinicalData = instanceId ? getPTClinicalDataForInstance(instanceId) : null
|
||||||
const petSequenceModule = metaData.get('petIsotopeModule', imageId)
|
const petSequenceModule = metaData.get('petIsotopeModule', imageId)
|
||||||
|
|
||||||
const generalSeriesModule = metaData.get('generalSeriesModule', imageId)
|
const generalSeriesModule = metaData.get('generalSeriesModule', imageId)
|
||||||
|
|
@ -60,25 +64,36 @@ export default function getPTImageIdInstanceMetadata(imageId) {
|
||||||
const { seriesDate, seriesTime, acquisitionDate, acquisitionTime } =
|
const { seriesDate, seriesTime, acquisitionDate, acquisitionTime } =
|
||||||
generalSeriesModule
|
generalSeriesModule
|
||||||
var { patientWeight } = patientStudyModule
|
var { patientWeight } = patientStudyModule
|
||||||
|
if (ptClinicalData && ptClinicalData.PatientWeight != null && ptClinicalData.PatientWeight !== '') {
|
||||||
|
patientWeight = parseFloat(ptClinicalData.PatientWeight)
|
||||||
|
}
|
||||||
// console.log('更改前:', patientWeight)
|
// console.log('更改前:', patientWeight)
|
||||||
// patientWeight = patientWeight * 10
|
// patientWeight = patientWeight * 10
|
||||||
// console.log('更改后:', patientWeight)
|
// console.log('更改后:', patientWeight)
|
||||||
const { correctedImage, units, decayCorrection } = ptSeriesModule
|
const { correctedImage, units, decayCorrection } = ptSeriesModule
|
||||||
|
const totalDose = ptClinicalData && ptClinicalData.RadionuclideTotalDose != null && ptClinicalData.RadionuclideTotalDose !== ''
|
||||||
|
? parseFloat(ptClinicalData.RadionuclideTotalDose)
|
||||||
|
: radiopharmaceuticalInfo.radionuclideTotalDose
|
||||||
|
const halfLife = ptClinicalData && ptClinicalData.RadionuclideHalfLife != null && ptClinicalData.RadionuclideHalfLife !== ''
|
||||||
|
? parseFloat(ptClinicalData.RadionuclideHalfLife)
|
||||||
|
: radiopharmaceuticalInfo.radionuclideHalfLife
|
||||||
|
const startTimeOverride = ptClinicalData ? normalizeDicomTime(ptClinicalData.RadiopharmaceuticalStartTime) : null
|
||||||
|
const acquisitionTimeOverride = ptClinicalData ? normalizeDicomTime(ptClinicalData.AcquisitionTime) : null
|
||||||
|
|
||||||
if (
|
if (
|
||||||
seriesDate === undefined ||
|
seriesDate === undefined ||
|
||||||
seriesTime === undefined ||
|
seriesTime === undefined ||
|
||||||
patientWeight === undefined ||
|
patientWeight === undefined ||
|
||||||
acquisitionDate === undefined ||
|
acquisitionDate === undefined ||
|
||||||
acquisitionTime === undefined ||
|
(acquisitionTimeOverride || acquisitionTime) === undefined ||
|
||||||
correctedImage === undefined ||
|
correctedImage === undefined ||
|
||||||
units === undefined ||
|
units === undefined ||
|
||||||
decayCorrection === undefined ||
|
decayCorrection === undefined ||
|
||||||
radiopharmaceuticalInfo.radionuclideTotalDose === undefined ||
|
totalDose === undefined ||
|
||||||
radiopharmaceuticalInfo.radionuclideHalfLife === undefined ||
|
halfLife === undefined ||
|
||||||
(radiopharmaceuticalInfo.radiopharmaceuticalStartDateTime === undefined &&
|
(radiopharmaceuticalInfo.radiopharmaceuticalStartDateTime === undefined &&
|
||||||
seriesDate === undefined &&
|
seriesDate === undefined &&
|
||||||
radiopharmaceuticalInfo.radiopharmaceuticalStartTime === undefined)
|
(startTimeOverride || radiopharmaceuticalInfo.radiopharmaceuticalStartTime) === undefined)
|
||||||
//
|
//
|
||||||
) {
|
) {
|
||||||
throw new Error('required metadata are missing')
|
throw new Error('required metadata are missing')
|
||||||
|
|
@ -87,14 +102,14 @@ export default function getPTImageIdInstanceMetadata(imageId) {
|
||||||
const instanceMetadata = {
|
const instanceMetadata = {
|
||||||
CorrectedImage: correctedImage,
|
CorrectedImage: correctedImage,
|
||||||
Units: units,
|
Units: units,
|
||||||
RadionuclideHalfLife: radiopharmaceuticalInfo.radionuclideHalfLife,
|
RadionuclideHalfLife: halfLife,
|
||||||
RadionuclideTotalDose: radiopharmaceuticalInfo.radionuclideTotalDose,
|
RadionuclideTotalDose: totalDose,
|
||||||
DecayCorrection: decayCorrection,
|
DecayCorrection: decayCorrection,
|
||||||
PatientWeight: patientWeight,
|
PatientWeight: patientWeight,
|
||||||
SeriesDate: seriesDate,
|
SeriesDate: seriesDate,
|
||||||
SeriesTime: seriesTime,
|
SeriesTime: seriesTime,
|
||||||
AcquisitionDate: acquisitionDate,
|
AcquisitionDate: acquisitionDate,
|
||||||
AcquisitionTime: acquisitionTime
|
AcquisitionTime: acquisitionTimeOverride || acquisitionTime
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|
@ -159,6 +174,10 @@ export default function getPTImageIdInstanceMetadata(imageId) {
|
||||||
instanceMetadata.RadiopharmaceuticalStartTime = timeString
|
instanceMetadata.RadiopharmaceuticalStartTime = timeString
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (startTimeOverride) {
|
||||||
|
instanceMetadata.RadiopharmaceuticalStartTime = startTimeOverride
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
instanceMetadata.AcquisitionTime &&
|
instanceMetadata.AcquisitionTime &&
|
||||||
instanceMetadata.AcquisitionTime !== undefined &&
|
instanceMetadata.AcquisitionTime !== undefined &&
|
||||||
|
|
@ -201,6 +220,9 @@ export default function getPTImageIdInstanceMetadata(imageId) {
|
||||||
) {
|
) {
|
||||||
instanceMetadata.PatientSex = patientStudyModule.patientSex
|
instanceMetadata.PatientSex = patientStudyModule.patientSex
|
||||||
}
|
}
|
||||||
|
if (ptClinicalData && ptClinicalData.PatientSex != null && ptClinicalData.PatientSex !== '') {
|
||||||
|
instanceMetadata.PatientSex = ptClinicalData.PatientSex
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
patientStudyModule.patientSize &&
|
patientStudyModule.patientSize &&
|
||||||
|
|
@ -234,3 +256,40 @@ function convertInterfaceDateToString(date) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export { getPTImageIdInstanceMetadata }
|
export { getPTImageIdInstanceMetadata }
|
||||||
|
|
||||||
|
function getInstanceIdFromImageId(imageId) {
|
||||||
|
try {
|
||||||
|
const qIndex = imageId.indexOf('?')
|
||||||
|
if (qIndex === -1) return null
|
||||||
|
const params = new URLSearchParams(imageId.slice(qIndex + 1))
|
||||||
|
const instanceId = params.get('instanceId')
|
||||||
|
if (!instanceId) return null
|
||||||
|
return String(instanceId).trim() || null
|
||||||
|
} catch (e) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeDicomTime(value) {
|
||||||
|
if (value === undefined || value === null || value === '') return null
|
||||||
|
if (typeof value === 'object') {
|
||||||
|
return convertInterfaceTimeToString(value)
|
||||||
|
}
|
||||||
|
const raw = String(value).trim()
|
||||||
|
if (!raw) return null
|
||||||
|
|
||||||
|
if (raw.includes(':')) {
|
||||||
|
const parts = raw.split(':')
|
||||||
|
const hh = `${parts[0] || '00'}`.padStart(2, '0')
|
||||||
|
const mm = `${parts[1] || '00'}`.padStart(2, '0')
|
||||||
|
const ss = `${parts[2] || '00'}`.padStart(2, '0')
|
||||||
|
return `${hh}${mm}${ss}.000000`
|
||||||
|
}
|
||||||
|
|
||||||
|
const cleaned = raw.replace(/[^\d.]/g, '')
|
||||||
|
if (!cleaned) return null
|
||||||
|
const [baseRaw, fracRaw] = cleaned.split('.')
|
||||||
|
const base = `${baseRaw || ''}`.padStart(6, '0').slice(-6)
|
||||||
|
const frac = `${fracRaw || ''}`.padEnd(6, '0').slice(0, 6)
|
||||||
|
return `${base}.${frac}`
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -577,6 +577,7 @@ import colorMap from './colorMap.vue'
|
||||||
import RectangleROITool from './tools/RectangleROITool'
|
import RectangleROITool from './tools/RectangleROITool'
|
||||||
import ScaleOverlayTool from './tools/ScaleOverlayTool'
|
import ScaleOverlayTool from './tools/ScaleOverlayTool'
|
||||||
import SegmentBidirectionalTool from './tools/SegmentBidirectionalTool'
|
import SegmentBidirectionalTool from './tools/SegmentBidirectionalTool'
|
||||||
|
import { setPTClinicalDataForInstance } from '@/utils/ptClinicalDataCache'
|
||||||
import FixedRadiusCircleROITool from './tools/FixedRadiusCircleROITool'
|
import FixedRadiusCircleROITool from './tools/FixedRadiusCircleROITool'
|
||||||
import uploadDicomAndNonedicom from '@/components/uploadDicomAndNonedicom'
|
import uploadDicomAndNonedicom from '@/components/uploadDicomAndNonedicom'
|
||||||
import downloadDicomAndNonedicom from '@/components/downloadDicomAndNonedicom'
|
import downloadDicomAndNonedicom from '@/components/downloadDicomAndNonedicom'
|
||||||
|
|
@ -1155,10 +1156,28 @@ export default {
|
||||||
let keySeriesIndex = -1
|
let keySeriesIndex = -1
|
||||||
const arr = res1.Result
|
const arr = res1.Result
|
||||||
arr.forEach((study, studyIndex) => {
|
arr.forEach((study, studyIndex) => {
|
||||||
|
// 缓存接口返回的 PT 临床数据:用于后续统一 SUV 计算(3D suvFactor 计算优先用接口值)
|
||||||
|
const ptClinicalData = {
|
||||||
|
PatientSex: study.PatientSex,
|
||||||
|
PatientWeight: study.PatientWeight,
|
||||||
|
RadionuclideTotalDose: study.RadionuclideTotalDose,
|
||||||
|
RadionuclideHalfLife: study.RadionuclideHalfLife,
|
||||||
|
RadiopharmaceuticalStartTime: study.RadiopharmaceuticalStartTime,
|
||||||
|
AcquisitionTime: study.AcquisitionTime
|
||||||
|
}
|
||||||
|
const hasPtClinicalData =
|
||||||
|
ptClinicalData.PatientWeight != null ||
|
||||||
|
ptClinicalData.RadionuclideTotalDose != null ||
|
||||||
|
ptClinicalData.RadionuclideHalfLife != null ||
|
||||||
|
ptClinicalData.RadiopharmaceuticalStartTime != null ||
|
||||||
|
ptClinicalData.AcquisitionTime != null
|
||||||
study.SeriesList.forEach((series, seriesIndex) => {
|
study.SeriesList.forEach((series, seriesIndex) => {
|
||||||
const imageIds = []
|
const imageIds = []
|
||||||
const stack = []
|
const stack = []
|
||||||
series.InstanceInfoList.forEach((instance, instanceIndex) => {
|
series.InstanceInfoList.forEach((instance, instanceIndex) => {
|
||||||
|
if (hasPtClinicalData) {
|
||||||
|
setPTClinicalDataForInstance(instance.Id, ptClinicalData)
|
||||||
|
}
|
||||||
if (study.IsCriticalSequence) {
|
if (study.IsCriticalSequence) {
|
||||||
keyStudyIndex = studyIndex
|
keyStudyIndex = studyIndex
|
||||||
keySeriesIndex = seriesIndex
|
keySeriesIndex = seriesIndex
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@
|
||||||
<span>{{ study.AcquisitionTime }}</span>
|
<span>{{ study.AcquisitionTime }}</span>
|
||||||
</div>
|
</div>
|
||||||
<i slot="reference" class="el-icon-document"
|
<i slot="reference" class="el-icon-document"
|
||||||
style="font-size: 15px;cursor: pointer;color: #428bca;" />
|
style="font-size: 15px;cursor: pointer;color: #f5f7fa;" />
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -245,7 +245,7 @@
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<!-- 其他 -->
|
<!-- 其他 -->
|
||||||
<el-tab-pane :label="$t('trials:reading:tab:others')" name="2">
|
<el-tab-pane :label="$t('trials:reading:tab:others')" name="2">
|
||||||
<Others v-if="activeName === '2'" />
|
<Others v-if="activeName === '2'" :imageToolType="2"/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
|
||||||
|
|
@ -2452,7 +2452,7 @@ export default {
|
||||||
const routeData = this.$router.resolve({
|
const routeData = this.$router.resolve({
|
||||||
path: `/showdicom?trialId=${this.trialId}&subjectVisitId=${this.data.Id
|
path: `/showdicom?trialId=${this.trialId}&subjectVisitId=${this.data.Id
|
||||||
}&studyId=${row.StudyId}&showDelete=${this.isAudit ? 0 : 1
|
}&studyId=${row.StudyId}&showDelete=${this.isAudit ? 0 : 1
|
||||||
}&TokenKey=${token}&type=Study&isHaveStudyClinicalData=${this.IsHaveStudyClinicalData}`,
|
}&TokenKey=${token}&type=Study`,
|
||||||
})
|
})
|
||||||
this.open = window.open(routeData.href, '_blank')
|
this.open = window.open(routeData.href, '_blank')
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue