Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web into main
continuous-integration/drone/push Build is passing Details

uat_us
caiyiling 2026-03-25 16:51:31 +08:00
commit 4794429a57
5 changed files with 90 additions and 44 deletions

View File

@ -712,12 +712,12 @@ export default {
var studyUid = data.string('x0020000d') var studyUid = data.string('x0020000d')
if (!studyUid) return resolve() if (!studyUid) return resolve()
var pixelDataElement = data.elements.x7fe00010 var pixelDataElement = data.elements.x7fe00010
if (!pixelDataElement && modality !== 'SR') return resolve() if (!pixelDataElement && modality !== 'SR' && modality !== 'ECG') return resolve()
var studyIndex = 0 var studyIndex = 0
while ( while (
studyIndex < scope.uploadQueues.length && studyIndex < scope.uploadQueues.length &&
scope.uploadQueues[studyIndex].dicomInfo.studyUid !== studyUid && scope.uploadQueues[studyIndex].dicomInfo.studyUid !== studyUid &&
(pixelDataElement || modality === 'SR') && (pixelDataElement || modality === 'SR' || modality === 'ECG') &&
modality != '' modality != ''
) { ) {
++studyIndex ++studyIndex

View File

@ -1589,7 +1589,7 @@ export default {
// }) // })
}, },
renderAnnotations(series) { renderAnnotations(series) {
const taskId = series.TaskInfo.VisitTaskId const taskId = series.TaskInfo ? series.TaskInfo.VisitTaskId : null
if (!taskId || this.renderedTaskIds.includes(taskId)) return if (!taskId || this.renderedTaskIds.includes(taskId)) return
this.renderedTaskIds.push(taskId) this.renderedTaskIds.push(taskId)
const taskIdx = this.visitTaskList.findIndex(i => i.VisitTaskId === taskId) const taskIdx = this.visitTaskList.findIndex(i => i.VisitTaskId === taskId)
@ -1726,7 +1726,7 @@ export default {
if (annotation.metadata.toolName !== LabelMapEditWithContourTool.toolName) this.setToolsPassive() if (annotation.metadata.toolName !== LabelMapEditWithContourTool.toolName) this.setToolsPassive()
return return
} }
if (annotation.data.segmentation || annotation.data.segment) return if (annotation.metadata.segmentationId) return
if (annotation.metadata.toolName === 'PlanarFreehandROI' && !annotation.data.contour.closed) return if (annotation.metadata.toolName === 'PlanarFreehandROI' && !annotation.data.contour.closed) return
const series = this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].series const series = this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].series
if (series && series.TaskInfo.VisitTaskId && series.TaskInfo.VisitTaskId === this.taskInfo.VisitTaskId) { if (series && series.TaskInfo.VisitTaskId && series.TaskInfo.VisitTaskId === this.taskInfo.VisitTaskId) {
@ -1814,7 +1814,7 @@ export default {
if (annotation.metadata.toolName !== LabelMapEditWithContourTool.toolName) this.setToolsPassive() if (annotation.metadata.toolName !== LabelMapEditWithContourTool.toolName) this.setToolsPassive()
return return
} }
if (annotation.data.segmentation || annotation.data.segment) return if (annotation.metadata.segmentationId) return
if (!annotation.data.label) return if (!annotation.data.label) return
if (annotation.metadata.toolName === 'PlanarFreehandROI' && !annotation.data.contour.closed) return if (annotation.metadata.toolName === 'PlanarFreehandROI' && !annotation.data.contour.closed) return
const series = this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].series const series = this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].series
@ -1845,7 +1845,7 @@ export default {
// //
return return
} }
if (annotation.data.segmentation || annotation.data.segment) return if (annotation.metadata.segmentationId) return
if (annotation.visitTaskId === this.taskInfo.VisitTaskId) { if (annotation.visitTaskId === this.taskInfo.VisitTaskId) {
const isBound = this.$refs[`ecrf_${annotation.visitTaskId}`][0].verifyAnnotationIsBound(annotation) const isBound = this.$refs[`ecrf_${annotation.visitTaskId}`][0].verifyAnnotationIsBound(annotation)
if (isBound && this.activeTool === 'Eraser') { if (isBound && this.activeTool === 'Eraser') {

View File

@ -397,7 +397,6 @@ export default {
segmentationId: item.segmentationId, segmentationId: item.segmentationId,
segmentIndices: [item.segmentIndex], segmentIndices: [item.segmentIndex],
}); });
// console.log(bidirectionalData, 'bidirectionalData')
if (bidirectionalData.length <= 0) { if (bidirectionalData.length <= 0) {
let annotations = annotation.state.getAllAnnotations().filter(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === item.segmentIndex); let annotations = annotation.state.getAllAnnotations().filter(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === item.segmentIndex);
annotations.forEach(i => { annotations.forEach(i => {
@ -421,11 +420,12 @@ export default {
segmentIndex, segmentIndex,
segmentationId: item.segmentationId, segmentationId: item.segmentationId,
}); });
item.bidirectional = bidirectional
let an = annotation.state.getAllAnnotations().find(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === bidirectional.segmentIndex && i.metadata.toolName === "SegmentBidirectional"); let an = annotation.state.getAllAnnotations().find(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === bidirectional.segmentIndex && i.metadata.toolName === "SegmentBidirectional");
if (an) { if (an) {
annotation.locking.setAnnotationLocked(an.annotationUID, true) annotation.locking.setAnnotationLocked(an.annotationUID, true)
annotation.visibility.setAnnotationVisibility(an.annotationUID, item.bidirectionalView)
} }
item.bidirectional = bidirectional
if (DATA) { if (DATA) {
this.segmentationId = DATA.SegmentationId; this.segmentationId = DATA.SegmentationId;
this.segmentIndex = DATA.SegmentMumber; this.segmentIndex = DATA.SegmentMumber;
@ -481,16 +481,30 @@ export default {
} }
this.resetViewport() this.resetViewport()
}, },
jumpBidirectional(item) { async jumpBidirectional(item) {
if (item.bidirectional) { if (item.bidirectional) {
let an = annotation.state.getAllAnnotations().find(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === item.segmentIndex && i.metadata.toolName === "SegmentBidirectional"); let an = annotation.state.getAllAnnotations().find(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === item.segmentIndex && i.metadata.toolName === "SegmentBidirectional");
// console.log(an, 'an')
if (!an) return false if (!an) return false
let referencedImageId = an.metadata.referencedImageId;
let sliceIndex = metaData.get('generalImageModule', referencedImageId).instanceNumber
const renderingEngine = getRenderingEngine(this.renderingEngineId) const renderingEngine = getRenderingEngine(this.renderingEngineId)
const viewportId = `${this.viewportKey}-${this.activeViewportIndex}` const viewportId = `${this.viewportKey}-${this.activeViewportIndex}`
const viewport = renderingEngine.getViewport(viewportId) const viewport = renderingEngine.getViewport(viewportId)
csUtils.jumpToSlice(viewport.element, { imageIndex: sliceIndex - 1 }); let key = Object.keys(an.data.cachedStats)[0]; // referencedImageId
if (key) {
let sliceIndex = key.split("?")[1].split("&")[0].split("=")[1]
csUtils.jumpToSlice(viewport.element, { imageIndex: sliceIndex });
} else {
const points = an.data.handles.points;
const worldPoint = points[0]; //
let imageData = cache.getVolume(this.series.SeriesInstanceUid).imageData
const ijk = imageData.worldToIndex(worldPoint);
const sliceIndex = Math.abs(Math.round(ijk[2]));
let imageIds = viewport.getImageIds(this.series.SeriesInstanceUid)
// console.log(sliceIndex, 'sliceIndex')
csUtils.jumpToSlice(viewport.element, { imageIndex: imageIds.length - sliceIndex - 1 });
}
} }
}, },
viewSegmentGroup(item) { viewSegmentGroup(item) {
@ -542,7 +556,8 @@ export default {
this.viewprotIds.forEach(id => { this.viewprotIds.forEach(id => {
segmentation.activeSegmentation.setActiveSegmentation(id, this.segmentationId) segmentation.activeSegmentation.setActiveSegmentation(id, this.segmentationId)
}) })
this.selectSegment({ segmentationId: this.segmentationId, segmentIndex: 1 }) let segment = this.segmentList.find(item => item.segmentationId === this.segmentationId).segments[0]
this.selectSegment(segment)
this.readingSegmentByConfig() this.readingSegmentByConfig()
}, },
async addSegmentGroup() { async addSegmentGroup() {
@ -661,6 +676,8 @@ export default {
}, },
// //
async delSegmentGroup() { async delSegmentGroup() {
let confirm = await this.$confirm(this.$t('trials:reading:Segmentations:confirm:delSegmentions'))
if (!confirm) return false
let res = await this.deleteSegmentation(this.segmentationId) let res = await this.deleteSegmentation(this.segmentationId)
if (!res) return false if (!res) return false
segmentation.removeSegmentation(this.segmentationId) segmentation.removeSegmentation(this.segmentationId)
@ -682,12 +699,15 @@ export default {
}, },
// //
async delSegment(segmentIndex) { async delSegment(segmentIndex) {
let confirm = await this.$confirm(this.$t('trials:reading:Segmentations:confirm:delSegment'))
if (!confirm) return false
let groupIndex = this.segmentList.findIndex(item => item.segmentationId === this.segmentationId) let groupIndex = this.segmentList.findIndex(item => item.segmentationId === this.segmentationId)
if (this.segmentList[groupIndex].segments.length <= 1) return this.$confirm(this.$t('trials:reading:Segmentations:confirm:hasOneSegment')) if (this.segmentList[groupIndex].segments.length <= 1) return this.$confirm(this.$t('trials:reading:Segmentations:confirm:hasOneSegment'))
let s = this.segmentList[groupIndex].segments.find(item => item.segmentIndex === segmentIndex) let s = this.segmentList[groupIndex].segments.find(item => item.segmentIndex === segmentIndex)
let res = await this.deleteSegment(s.id) let res = await this.deleteSegment(s.id)
if (!res) return false if (!res) return false
segmentation.removeSegment(this.segmentationId, Number(segmentIndex), { setNextSegmentAsActive: false }) segmentation.removeSegment(this.segmentationId, Number(segmentIndex), { setNextSegmentAsActive: false, recordHistory: false })
segmentation.helpers.clearSegmentValue(this.segmentationId, Number(segmentIndex), { recordHistory: false })
// segmentation.updateSegmentations({ segmentationId: this.segmentationId }) // segmentation.updateSegmentations({ segmentationId: this.segmentationId })
let index = this.segmentList[groupIndex].segments.findIndex(item => item.segmentIndex === segmentIndex) let index = this.segmentList[groupIndex].segments.findIndex(item => item.segmentIndex === segmentIndex)
this.segmentList[groupIndex].segments.splice(index, 1) this.segmentList[groupIndex].segments.splice(index, 1)
@ -711,6 +731,7 @@ export default {
}, },
async rename(key, item) { async rename(key, item) {
let name = await this.customPrompt() let name = await this.customPrompt()
if (!name) return false
if (key === 'segmentGroup') { if (key === 'segmentGroup') {
let group = this.segmentList.find(i => i.segmentationId === this.segmentationId) let group = this.segmentList.find(i => i.segmentationId === this.segmentationId)
group.name = name group.name = name
@ -775,9 +796,11 @@ export default {
segmentList.forEach(segment => { segmentList.forEach(segment => {
this.viewBidirectional(segment.segments, this.SegmentConfig.InactiveSegmentations.show) this.viewBidirectional(segment.segments, this.SegmentConfig.InactiveSegmentations.show)
}) })
let segments = this.segmentList.find(item => item.segmentationId === this.segmentationId).segments let segmentGroup = this.segmentList.find(item => item.segmentationId === this.segmentationId)
this.viewBidirectional(segments, true) if (segmentGroup) {
let segments = segmentGroup.segments
this.viewBidirectional(segments, true)
}
}, },
// //
changeSegmentConfig(renderOutline, renderFill) { changeSegmentConfig(renderOutline, renderFill) {
@ -850,25 +873,28 @@ export default {
color.slice(0, 3).map(value => value / 255) color.slice(0, 3).map(value => value / 255)
).map(value => Math.round(value)); ).map(value => Math.round(value));
let segment = group.segments.find(item => item.segmentIndex === segmentIndex) let segment = group.segments.find(item => item.segmentIndex === segmentIndex)
let SegmentLabel = segment.SegmentLabel if (segment) {
const segmentMetadata = { let SegmentLabel = segment.SegmentLabel
SegmentNumber: segmentIndex.toString(), const segmentMetadata = {
SegmentLabel: SegmentLabel, SegmentNumber: segmentIndex.toString(),
SegmentAlgorithmType: "MANUAL", SegmentLabel: SegmentLabel,
SegmentAlgorithmName: "OHIF Brush", SegmentAlgorithmType: "MANUAL",
RecommendedDisplayCIELabValue, SegmentAlgorithmName: "OHIF Brush",
SegmentedPropertyCategoryCodeSequence: { RecommendedDisplayCIELabValue,
CodeValue: "T-D0050", SegmentedPropertyCategoryCodeSequence: {
CodingSchemeDesignator: "SRT", CodeValue: "T-D0050",
CodeMeaning: "Tissue" CodingSchemeDesignator: "SRT",
}, CodeMeaning: "Tissue"
SegmentedPropertyTypeCodeSequence: { },
CodeValue: "T-D0050", SegmentedPropertyTypeCodeSequence: {
CodingSchemeDesignator: "SRT", CodeValue: "T-D0050",
CodeMeaning: "Tissue" CodingSchemeDesignator: "SRT",
} CodeMeaning: "Tissue"
}; }
if (segment.bidirectional && segment.stats) labelmap3D.metadata[segmentIndex] = segmentMetadata; };
if (segment.bidirectional && segment.stats) labelmap3D.metadata[segmentIndex] = segmentMetadata;
}
}); });
if (labelmap3D.metadata.length <= 0) { if (labelmap3D.metadata.length <= 0) {
return false return false
@ -879,6 +905,9 @@ export default {
labelmap3D, labelmap3D,
metaData metaData
); );
group.segments.forEach((item, index) => {
generatedSegmentation.dataset.SegmentSequence[index].SegmentNumber = item.segmentIndex.toString()
})
if (!isFile) { if (!isFile) {
const buffer = Buffer.from(dcmjs.data.datasetToDict(generatedSegmentation.dataset).write()); const buffer = Buffer.from(dcmjs.data.datasetToDict(generatedSegmentation.dataset).write());
let blob = new Blob([buffer], { type: "application/dicom" }); let blob = new Blob([buffer], { type: "application/dicom" });
@ -944,7 +973,6 @@ export default {
arrayBuffer, arrayBuffer,
metaData, metaData,
); );
if (generateToolState.labelmapBufferArray.length !== 1) { if (generateToolState.labelmapBufferArray.length !== 1) {
alert( alert(
"Overlapping segments in your segmentation are not supported yet. You can turn on the skipOverlapping option but it will override the overlapping segments." "Overlapping segments in your segmentation are not supported yet. You can turn on the skipOverlapping option but it will override the overlapping segments."
@ -964,12 +992,28 @@ export default {
const volumeScalarData = new Uint8Array( const volumeScalarData = new Uint8Array(
generateToolState.labelmapBufferArray[0] generateToolState.labelmapBufferArray[0]
); );
const remappedData = new Uint8Array(volumeScalarData.length);
let mapping = {}
let segments = await this.getSegmentList(segmentationId)
if (segments.length > 0) {
segments.forEach(item => {
let SegmentJson = item.SegmentJson ? JSON.parse(item.SegmentJson) : {};
if (SegmentJson.bidirectional && SegmentJson.stats) {
let keys = Object.keys(mapping)
mapping[keys.length + 1] = Number(item.SegmentMumber)
}
})
}
for (let i = 0; i < volumeScalarData.length; i++) {
const value = volumeScalarData[i];
remappedData[i] = value === 0 ? 0 : (mapping[value] ? mapping[value] : 0);
}
for (let i = 0; i < derivedSegmentationImages.length; i++) { for (let i = 0; i < derivedSegmentationImages.length; i++) {
const voxelManager = derivedSegmentationImages[i].voxelManager; const voxelManager = derivedSegmentationImages[i].voxelManager;
const scalarData = voxelManager.getScalarData(); const scalarData = voxelManager.getScalarData();
scalarData.set( scalarData.set(
volumeScalarData.slice( remappedData.slice(
i * scalarData.length, i * scalarData.length,
(i + 1) * scalarData.length (i + 1) * scalarData.length
) )
@ -1200,6 +1244,7 @@ export default {
}) })
// //
let blob = this.exportSegmentation(segmentGroup.segmentationId, segmentGroup) let blob = this.exportSegmentation(segmentGroup.segmentationId, segmentGroup)
// if (!blob) return false
if (blob) { if (blob) {
let path = `/${this.$route.query.trialId}/Segment/${this.visitInfo.SubjectId let path = `/${this.$route.query.trialId}/Segment/${this.visitInfo.SubjectId
}/${this.visitInfo.VisistId}/${this.series.StudyId }/${this.visitInfo.VisistId}/${this.series.StudyId
@ -1301,13 +1346,14 @@ export default {
// this.getBidirectional(o) // this.getBidirectional(o)
// }) // })
if (SEGMENT && index === segments.length - 1) { if (SEGMENT && index === segments.length - 1) {
console.log(SEGMENT, 'SEGMENT') // console.log(SEGMENT, 'SEGMENT')
return this.getBidirectional(o, SEGMENT) return this.getBidirectional(o, SEGMENT)
} }
this.getBidirectional(o) this.getBidirectional(o)
}) })
} }
} }
// console.log(segmentation.state.getSegmentations(), 'segmentation.state.getSegmentations()')
} catch (err) { } catch (err) {
this.loading = false this.loading = false
console.log(err) console.log(err)

View File

@ -40,10 +40,10 @@
<div v-if="series" class="right-bottom-text"> <div v-if="series" class="right-bottom-text">
<div v-show="imageInfo.location">Location: {{ <div v-show="imageInfo.location">Location: {{
`${Number(imageInfo.location).toFixed(digitPlaces)} mm` `${Number(imageInfo.location).toFixed(digitPlaces)} mm`
}}</div> }}</div>
<div v-show="imageInfo.sliceThickness">Slice Thickness: {{ <div v-show="imageInfo.sliceThickness">Slice Thickness: {{
`${Number(imageInfo.sliceThickness).toFixed(digitPlaces)} mm` `${Number(imageInfo.sliceThickness).toFixed(digitPlaces)} mm`
}}</div> }}</div>
<div v-show="imageInfo.wwwc">WW/WL: {{ imageInfo.wwwc }}</div> <div v-show="imageInfo.wwwc">WW/WL: {{ imageInfo.wwwc }}</div>
</div> </div>
<div class="orientation-top"> <div class="orientation-top">
@ -279,7 +279,7 @@ export default {
this.imageInfo.location = imagePlaneModule.sliceLocation this.imageInfo.location = imagePlaneModule.sliceLocation
this.imageInfo.total = detail.numberOfSlices this.imageInfo.total = detail.numberOfSlices
this.getOrientationMarker() this.getOrientationMarker()
// this.$emit('renderAnnotations', this.series) this.$emit('renderAnnotations', this.series)
let properties = viewport.getProperties() let properties = viewport.getProperties()
if (this.isFusion) { if (this.isFusion) {
properties = viewport.getProperties(this.ptVolumeId) properties = viewport.getProperties(this.ptVolumeId)

View File

@ -891,12 +891,12 @@ export default {
var studyUid = data.string('x0020000d') var studyUid = data.string('x0020000d')
if (!studyUid) return resolve() if (!studyUid) return resolve()
var pixelDataElement = data.elements.x7fe00010 var pixelDataElement = data.elements.x7fe00010
if (!pixelDataElement && modality !== 'SR') return resolve() if (!pixelDataElement && modality !== 'SR' && modality !== 'ECG') return resolve()
var studyIndex = 0 var studyIndex = 0
while ( while (
studyIndex < scope.uploadQueues.length && studyIndex < scope.uploadQueues.length &&
scope.uploadQueues[studyIndex].dicomInfo.studyUid !== studyUid && scope.uploadQueues[studyIndex].dicomInfo.studyUid !== studyUid &&
(pixelDataElement || modality === 'SR') && (pixelDataElement || modality === 'SR' || modality === 'ECG') &&
modality != '' modality != ''
) { ) {
++studyIndex ++studyIndex