From ca35fe6df45654a4f7ceee8d90c4a580857fae16 Mon Sep 17 00:00:00 2001 From: wangxiaoshuang <825034831@qq.com> Date: Tue, 31 Mar 2026 15:17:13 +0800 Subject: [PATCH] =?UTF-8?q?=E9=83=A8=E5=88=86=E9=97=AE=E9=A2=98=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dicoms3D/components/MPRViewport.vue | 2 +- .../reading/dicoms3D/components/ReadPage.vue | 18 +- .../dicoms3D/components/Segmentations.vue | 166 +++++++++++------- .../dicoms3D/components/VolumeViewport.vue | 4 +- .../components/customize/QuestionFormItem.vue | 2 +- .../customize/QuestionTableFormItem.vue | 2 +- 6 files changed, 117 insertions(+), 77 deletions(-) diff --git a/src/views/trials/trials-panel/reading/dicoms3D/components/MPRViewport.vue b/src/views/trials/trials-panel/reading/dicoms3D/components/MPRViewport.vue index e8f915cb..c4ea3bcb 100644 --- a/src/views/trials/trials-panel/reading/dicoms3D/components/MPRViewport.vue +++ b/src/views/trials/trials-panel/reading/dicoms3D/components/MPRViewport.vue @@ -497,7 +497,7 @@ export default { setCtTransferFunctionForVolumeActor(r) } console.log("渲染成功") - DicomEvent.$emit("isloaded", {}) + DicomEvent.$emit("isloaded", { isChange: false }) } }]).then(r => { if (data.isLocation || !this.imageInfo.zoom) { diff --git a/src/views/trials/trials-panel/reading/dicoms3D/components/ReadPage.vue b/src/views/trials/trials-panel/reading/dicoms3D/components/ReadPage.vue index 10746aa9..86cad5d7 100644 --- a/src/views/trials/trials-panel/reading/dicoms3D/components/ReadPage.vue +++ b/src/views/trials/trials-panel/reading/dicoms3D/components/ReadPage.vue @@ -2539,7 +2539,7 @@ export default { viewport.render() renderingEngine.render() if (this.readingTool === 3) { - DicomEvent.$emit('isloaded', {}) + DicomEvent.$emit('isloaded', { isChange: false }) } }, // 更改视图布局 @@ -2826,13 +2826,20 @@ export default { renderingEngine.resize(true, false) renderingEngine.render() if (this.readingTool === 3) { - DicomEvent.$emit('isloaded', {}) + DicomEvent.$emit('isloaded', { isChange: false }) } }) } - if (this.isFusion) { - const viewportIds = [`${this.viewportKey}-0`, `${this.viewportKey}-1`, `${this.viewportKey}-2`] + if (this.isFusion || this.isMPR || this.readingTool === 3) { + let viewportIds = [`${this.viewportKey}-0`, `${this.viewportKey}-1`, `${this.viewportKey}-2`] + if (!this.isFusion && !this.isMPR) { + viewportIds = [] + for (let i = 0; i < this.cells.length; i++) { + const viewportId = `${this.viewportKey}-${i}` + viewportIds.push(viewportId) + } + } viewportIds.forEach(id => { const index = this.$refs[id][0].series.SliceIndex this.$refs[id][0].setFullScreen(index) @@ -2933,13 +2940,14 @@ export default { this.activeViewportIndex = 0 this.fullScreenIndex = null this.isMPR = false + obj.isChange = false this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].setSeriesInfo(obj) return this.$nextTick(() => { const renderingEngine = getRenderingEngine(renderingEngineId) renderingEngine.resize(true, false) renderingEngine.render() if (this.readingTool === 3) { - DicomEvent.$emit('isloaded', {}) + DicomEvent.$emit('isloaded', { isChange: false }) } }) diff --git a/src/views/trials/trials-panel/reading/dicoms3D/components/Segmentations.vue b/src/views/trials/trials-panel/reading/dicoms3D/components/Segmentations.vue index 43942dae..869728fd 100644 --- a/src/views/trials/trials-panel/reading/dicoms3D/components/Segmentations.vue +++ b/src/views/trials/trials-panel/reading/dicoms3D/components/Segmentations.vue @@ -148,7 +148,7 @@ - + @@ -159,7 +159,7 @@ :title="$t('trials:reading:Segmentations:tip:segmentationIsNotSave')" v-if="!curSegmentGroup.isSaved"> - {{ $t("common:button:save") }} + {{ $t("trials:reading:Segmentations:button:save") }} @@ -186,7 +186,7 @@ L:{{ Number(item.bidirectional.maxMajor).toFixed(2) }} mm - s:{{ Number(item.bidirectional.maxMinor).toFixed(2) }} mm + W:{{ Number(item.bidirectional.maxMinor).toFixed(2) }} mm - {{ $t("common:button:save") - }} + + {{ $t("trials:reading:Segmentations:button:saveAll") }} + @@ -331,6 +332,7 @@ export default { isDynamic: false, range: [200, 1000] }, + tools: ['LabelMapEditWithContour', 'CircularBrush', 'CircularEraser'], ThresholdTools: ['ThresholdCircle', 'ThresholdSphere'], thresholdType: null, showSegmentConfig: false, @@ -383,8 +385,8 @@ export default { DicomEvent.$on('isloaded', (data) => { if (this.isloaded) return false this.isloaded = true - let { segment } = data - this.delAllSegment() + let { segment, isChange = true } = data + this.delAllSegment(isChange) this.getSegmentationList(segment) }) const digitPlaces = Number(localStorage.getItem('digitPlaces')) @@ -473,13 +475,13 @@ export default { this.actionConfiguration.contourBidirectional.data.segmentIndex = segmentIndex }, async addTip(item) { - let segmentGroup = this.segmentList.filter(item => i.segmentationId === i.segmentationId) + let segmentGroup = this.segmentList.filter(i => item.segmentationId === i.segmentationId) await this.saveSegmentGroup(segmentGroup, false) this.calculateStatistics([item.segmentIndex], item.segmentationId, 'individual'); this.getBidirectional([item]) }, - getBidirectional(list, DATA = null) { + getBidirectional(list, DATA = null, isCompute = true) { list.forEach(item => { this.createSegmentConfiguration(item.segmentIndex, item.segmentationId); }) @@ -487,57 +489,70 @@ export default { const renderingEngine = getRenderingEngine(this.renderingEngineId) const viewportId = `${this.viewportKey}-${this.activeViewportIndex}` const viewport = renderingEngine.getViewport(viewportId); - [viewport.element].forEach(async (element) => { - const bidirectionalData = - await CStUtils.segmentation.getSegmentLargestBidirectional({ - segmentationId: list[0].segmentationId, - segmentIndices: list.map(item => item.segmentIndex), - }); - console.log(bidirectionalData, 'bidirectionalData') - if (bidirectionalData.length <= 0) { - list.forEach(item => { - let annotations = annotation.state.getAllAnnotations().filter(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === item.segmentIndex); - annotations.forEach(i => { - annotation.state.removeAnnotation(i.annotationUID) + if (isCompute) { + [viewport.element].forEach(async (element) => { + const bidirectionalData = + await CStUtils.segmentation.getSegmentLargestBidirectional({ + segmentationId: list[0].segmentationId, + segmentIndices: list.map(item => item.segmentIndex), + }); + console.log(bidirectionalData, list[0].segmentationId, 'bidirectionalData') + if (bidirectionalData.length <= 0) { + list.forEach(item => { + let annotations = annotation.state.getAllAnnotations().filter(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === item.segmentIndex); + annotations.forEach(i => { + annotation.state.removeAnnotation(i.annotationUID) + }) + item.bidirectional = null }) - item.bidirectional = null - }) - this.resetViewport(false) + this.resetViewport(false) - if (DATA) { - this.segmentationId = DATA.SegmentationId; - this.segmentIndex = DATA.SegmentMumber; - setTimeout(() => { - this.selectSegment(DATA) - }) + if (DATA) { + this.segmentationId = DATA.SegmentationId; + this.segmentIndex = DATA.SegmentMumber; + setTimeout(() => { + this.selectSegment(DATA) + }) + } } - } - bidirectionalData.forEach((bidirectional) => { - const { segmentIndex } = bidirectional; - const { majorAxis, minorAxis, maxMajor, maxMinor } = bidirectional; - let item = list.find(i => i.segmentIndex === segmentIndex) - SegmentBidirectionalTool.hydrate(viewportId, [majorAxis, minorAxis], { - segmentIndex, - segmentationId: item.segmentationId, + bidirectionalData.forEach((bidirectional) => { + const { segmentIndex } = bidirectional; + const { majorAxis, minorAxis, maxMajor, maxMinor } = bidirectional; + let item = list.find(i => i.segmentIndex === segmentIndex) + SegmentBidirectionalTool.hydrate(viewportId, [majorAxis, minorAxis], { + segmentIndex, + segmentationId: item.segmentationId, + }) + let an = annotation.state.getAllAnnotations().find(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === bidirectional.segmentIndex && i.metadata.toolName === "SegmentBidirectional"); + if (an) { + annotation.locking.setAnnotationLocked(an.annotationUID, true) + annotation.visibility.setAnnotationVisibility(an.annotationUID, item.bidirectionalView) + } + item.bidirectional = bidirectional + if (DATA) { + this.segmentationId = DATA.SegmentationId; + this.segmentIndex = DATA.SegmentMumber; + setTimeout(() => { + this.selectSegment(DATA) + }) + } + // render the bidirectional tool data }); - let an = annotation.state.getAllAnnotations().find(i => i.metadata.segmentationId === item.segmentationId && i.metadata.segmentIndex === bidirectional.segmentIndex && i.metadata.toolName === "SegmentBidirectional"); - if (an) { - annotation.locking.setAnnotationLocked(an.annotationUID, true) - annotation.visibility.setAnnotationVisibility(an.annotationUID, item.bidirectionalView) - } - item.bidirectional = bidirectional - if (DATA) { - this.segmentationId = DATA.SegmentationId; - this.segmentIndex = DATA.SegmentMumber; - setTimeout(() => { - this.selectSegment(DATA) - }) - } - // render the bidirectional tool data + }); + } else { + list.forEach(item => { + if (item.bidirectional) { + let { majorAxis, minorAxis } = item.bidirectional + SegmentBidirectionalTool.hydrate(viewportId, [majorAxis, minorAxis], { + segmentIndex: item.segmentIndex, + segmentationId: item.segmentationId, + }) + } + }) + } - }); }, setToolActive(toolName) { if (this.segmentList.length <= 0) return false @@ -647,9 +662,11 @@ export default { item.lock = lock if (!lock) this.changeSegmentationSavedStatus(item.segmentationId, lock) }, - selectSegment(item) { - this.segmentationId = item.segmentationId; - this.segmentIndex = item.segmentIndex; + selectSegment(item, isChange = true) { + if (isChange) { + this.segmentationId = item.segmentationId; + this.segmentIndex = item.segmentIndex; + } segmentation.segmentIndex.setActiveSegmentIndex(item.segmentationId, item.segmentIndex); this.jumpBidirectional(item) if (item.lock) { @@ -657,11 +674,11 @@ export default { } // this.resetViewport() }, - selectSegmentGroup() { + selectSegmentGroup(s) { this.viewprotIds.forEach(id => { segmentation.activeSegmentation.setActiveSegmentation(id, this.segmentationId) }) - let segment = this.segmentList.find(item => item.segmentationId === this.segmentationId).segments[0] + let segment = s ? s : this.segmentList.find(item => item.segmentationId === this.segmentationId).segments[0] this.selectSegment(segment) this.readingSegmentByConfig() }, @@ -775,15 +792,17 @@ export default { }) }, // 清空所有分割 - delAllSegment() { + delAllSegment(isChange) { segmentation.removeAllSegmentations() segmentation.state.removeAllSegmentations() let annotations = annotation.state.getAllAnnotations().filter(item => item.metadata.segmentationId && item.metadata.segmentIndex && item.metadata.toolName === "SegmentBidirectional"); annotations.forEach(item => { annotation.state.removeAnnotation(item.annotationUID) }) - this.segmentationId = '' - this.segmentIndex = null + if (isChange) { + this.segmentationId = '' + this.segmentIndex = null + } this.segmentList = [] this.resetViewport() }, @@ -1222,7 +1241,8 @@ export default { }, segmentationModifiedCallback(evt) { const { detail } = evt; - if (!detail || detail.segmentIndex === 255) { + let tools = [...this.ThresholdTools, ...this.tools] + if (!detail || detail.segmentIndex === 255 || !this.activeTool || !tools.includes(this.activeTool)) { return; } this.drawing = true @@ -1379,8 +1399,8 @@ export default { this.addOrUpdateSegmentation({ name: segmentGroup.name, id: segmentGroup.segmentationId, url: segmentGroup.segUrl }) this.changeSegmentationSavedStatus(segmentGroup.segmentationId, saveSegment) if (saveSegment) { - await this.getBidirectionalSaveSegment(list) - this.syncBindingAnswer(list) + await this.getBidirectionalSaveSegment(segmentList) + this.syncBindingAnswer(segmentList) } } this.$emit("update:globalLoading", false) @@ -1467,7 +1487,7 @@ export default { SegmentationId: segmentGroup.segmentationId } let res = await this.getSegmentBindingList(data) - if (res && res.length > 0) questionNeedChange = true + // if (res && res.length > 0) questionNeedChange = true for (let j = 0; j < res.length; j++) { let item = res[j] let segment = segmentGroup.segments.find(d => d.id === item.SegmentId) @@ -1558,6 +1578,9 @@ export default { this.createSegmentationRepresentation(obj.segmentationId) } } + if (!this.segmentationId) { + this.segmentationId = obj.segmentationId + } let segments = await this.getSegmentList(item.Id) segments.forEach((s, index) => { let SegmentJson = s.SegmentJson ? JSON.parse(s.SegmentJson) : {}; @@ -1576,19 +1599,28 @@ export default { id: s.Id } obj.segments.push(o) - this.selectSegment(o) + this.selectSegment(o, false) this.changeColor(s.ColorRgb, o) this.lockSegment(o, true) } + if (!this.segmentIndex) { + this.segmentIndex = s.SegmentMumber + } }) this.$nextTick(() => { if (SEGMENT) { // console.log(SEGMENT, 'SEGMENT') return this.getBidirectional(obj.segments, SEGMENT) } - this.getBidirectional(obj.segments) + this.getBidirectional(obj.segments, null, false) }) } + if (this.segmentationId && this.segmentIndex) { + let segment = this.segmentList.find(item => item.segmentationId === this.segmentationId).segments.find(item => item.segmentIndex === this.segmentIndex) + console.log(segment, 'segment') + this.selectSegmentGroup(segment) + // this.selectSegment(segment) + } this.isloaded = false this.readingSegmentByConfig() } diff --git a/src/views/trials/trials-panel/reading/dicoms3D/components/VolumeViewport.vue b/src/views/trials/trials-panel/reading/dicoms3D/components/VolumeViewport.vue index c6ba91af..42ca880c 100644 --- a/src/views/trials/trials-panel/reading/dicoms3D/components/VolumeViewport.vue +++ b/src/views/trials/trials-panel/reading/dicoms3D/components/VolumeViewport.vue @@ -541,12 +541,12 @@ export default { } }]).then(r => { if (data.segment) { - return DicomEvent.$emit("isloaded", { segment: data.segment }) + return DicomEvent.$emit("isloaded", { segment: data.segment, isChange: data.isChange }) } if (data.isLocation) { setTimeout(() => { csUtils.jumpToSlice(viewport.element, { imageIndex: data.SliceIndex }); }) } - DicomEvent.$emit("isloaded", {}) + DicomEvent.$emit("isloaded", { isChange: data.isChange }) }) viewport.render() } catch (e) { diff --git a/src/views/trials/trials-panel/reading/dicoms3D/components/customize/QuestionFormItem.vue b/src/views/trials/trials-panel/reading/dicoms3D/components/customize/QuestionFormItem.vue index bf7fa69b..30039696 100644 --- a/src/views/trials/trials-panel/reading/dicoms3D/components/customize/QuestionFormItem.vue +++ b/src/views/trials/trials-panel/reading/dicoms3D/components/customize/QuestionFormItem.vue @@ -190,7 +190,7 @@ @input="numberInput(question.Id)" @blur="questionsSegmentMarkStatus[question.Id] ? () => { } : handleMarkedQsBlur(questionForm[question.Id], questionForm, question.Id, question)" v-model="questionForm[question.Id]" - :title="questionsSegmentMarkStatus[question.Id] ? `${questionsSegmentMarkStatus[question.Id].SegmentationName}_${questionsSegmentMarkStatus[question.Id].SegmentName}` : question.Remark" + :title="questionsSegmentMarkStatus[question.Id] ? `${questionsSegmentMarkStatus[question.Id].SegmentationName}\n${questionsSegmentMarkStatus[question.Id].SegmentName}\n${questionForm[question.Id]}` : question.Remark" :disabled="(questionsSegmentMarkStatus[question.Id] && question.ImageMarkEnum === 2) || question.ImageMarkEnum === 1 || readingTaskState === 2" style="width: 150px;margin-right: 5px;"> diff --git a/src/views/trials/trials-panel/reading/dicoms3D/components/customize/QuestionTableFormItem.vue b/src/views/trials/trials-panel/reading/dicoms3D/components/customize/QuestionTableFormItem.vue index c80fd867..4ac87da8 100644 --- a/src/views/trials/trials-panel/reading/dicoms3D/components/customize/QuestionTableFormItem.vue +++ b/src/views/trials/trials-panel/reading/dicoms3D/components/customize/QuestionTableFormItem.vue @@ -113,7 +113,7 @@ @input="numberInput(question.Id)" @blur="questionsSegmentMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id] ? () => { } : handleMarkedQsBlur(questionForm[question.Id], questionForm, question.Id, question)" v-model="questionForm[question.Id]" - :title="questionsSegmentMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id] ? `${questionsSegmentMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id].SegmentationName}_${questionsSegmentMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id].SegmentName}` : question.Remark" + :title="questionsSegmentMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id] ? `${questionsSegmentMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id].SegmentationName}\n${questionsSegmentMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id].SegmentName}\n${questionForm[question.Id]}` : question.Remark" :disabled="(questionsSegmentMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id] && question.ImageMarkEnum === 2) || question.ImageMarkEnum === 1 || question.IsPreinstall" style="width: 150px;margin-right: 5px;">