diff --git a/src/views/trials/trials-panel/reading/dicoms/customize/CustomizeQuestionTableFormItem.vue b/src/views/trials/trials-panel/reading/dicoms/customize/CustomizeQuestionTableFormItem.vue index 3163f2c9..251666fd 100644 --- a/src/views/trials/trials-panel/reading/dicoms/customize/CustomizeQuestionTableFormItem.vue +++ b/src/views/trials/trials-panel/reading/dicoms/customize/CustomizeQuestionTableFormItem.vue @@ -488,7 +488,8 @@ export default { return num.toFixed(this.digitPlaces) }, formItemNumberChange(v, question) { - this.$emit('formItemTableNumberChange', v, question) + this.$emit('formItemTableNumberChange') + this.$emit('setFormItemData', { key: question.Id, val: v, question: question }) // this.$emit('formItemTableNumberChange', v, question) }, resetChild(obj) { 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 6a2afe30..b48dc850 100644 --- a/src/views/trials/trials-panel/reading/dicoms3D/components/ReadPage.vue +++ b/src/views/trials/trials-panel/reading/dicoms3D/components/ReadPage.vue @@ -438,6 +438,8 @@ @resetAnnotations="resetAnnotations" @setReadingTaskState="setReadingTaskState" @viewCustomAnnotationSeries="viewCustomAnnotationSeries" + @setReadingToolActive="setReadingToolActive" + @setReadingToolPassive="setReadingToolPassive" /> @@ -719,7 +721,8 @@ export default { studyList: [], volumeData: {}, fusionSerieId: {}, - loadingText: null + loadingText: null, + toolNames: ['Length', 'Bidirectional', 'RectangleROI', 'ArrowAnnotate', 'CircleROI', 'Eraser'] // resetAnnotation: false , // 是否初始化标记 (融合时使用) } }, @@ -1160,7 +1163,7 @@ export default { }) toolGroup.addTool(RectangleROITool.toolName, { cachedStats: false, - getTextLines: this.getRectangleROIToolTextLines + getTextLines: this.criterionType === 0 ? this.getCustomRectangleROIToolTextLines : this.getRectangleROIToolTextLines }) toolGroup.addTool(PlanarFreehandROITool.toolName, { allowOpenContours: false, @@ -1685,7 +1688,7 @@ export default { } = cachedVolumeStats || {} const textLines = [] - + if (area) { const areaLine = isEmptyArea ? `Area: Oblique not supported` @@ -1728,11 +1731,23 @@ export default { if (data.label) { textLines.push(data.status ? `${data.label}(${data.status})` : data.label) } - // textLines.push(`Area: ${parseFloat(area).toFixed(this.digitPlaces)} ${areaUnit}`) - // textLines.push(`Mean: ${csUtils.roundNumber(mean)} ${modalityUnit}`) - // textLines.push(`Max: ${csUtils.roundNumber(max)} ${modalityUnit}`) - // textLines.push(`Std Dev: ${csUtils.roundNumber(stdDev)} ${modalityUnit}`) + return textLines + }, + getCustomRectangleROIToolTextLines(data, targetId) { + const cachedVolumeStats = data.cachedStats[targetId] + const { area, mean, max, stdDev, areaUnit, modalityUnit } = cachedVolumeStats + + if (mean === undefined) { + return + } + + const textLines = [] + textLines.push(`Area: ${this.reRound(area, this.digitPlaces)} ${areaUnit}`) + + textLines.push(`Mean: ${this.reRound(mean, this.digitPlaces)} ${modalityUnit}`) + textLines.push(`Max: ${this.reRound(max, this.digitPlaces)} ${modalityUnit}`) + textLines.push(`Std Dev: ${this.reRound(stdDev, this.digitPlaces)} ${modalityUnit}`) return textLines }, @@ -1751,12 +1766,10 @@ export default { if (length === undefined) { return textLines } - - // spaceBetweenSlices & pixelSpacing & - // magnitude in each direction? Otherwise, this is "px"? + textLines.push( - `L: ${csUtils.roundNumber(length)} ${unit || unit}`, - `S: ${csUtils.roundNumber(width)} ${unit}` + `L: ${parseFloat(length).toFixed(this.digitPlaces)} ${unit || unit}`, + `S: ${parseFloat(width).toFixed(this.digitPlaces)} ${unit}` ) return textLines @@ -1783,31 +1796,48 @@ export default { if (radius) { const radiusLine = isEmptyArea ? `Radius: Oblique not supported` - : `Radius: ${csUtils.roundNumber(radius)} ${radiusUnit}` + : `Radius: ${this.reRound(radius, this.digitPlaces)} ${radiusUnit}` textLines.push(radiusLine) } if (area) { const areaLine = isEmptyArea ? `Area: Oblique not supported` - : `Area: ${csUtils.roundNumber(area)} ${areaUnit}` + : `Area: ${parseFloat(area)} ${areaUnit}` textLines.push(areaLine) } if (mean) { - textLines.push(`Mean: ${csUtils.roundNumber(mean)} ${modalityUnit}`) + textLines.push(`Mean: ${this.reRound(mean, this.digitPlaces)} ${modalityUnit}`) } if (max) { - textLines.push(`Max: ${csUtils.roundNumber(max)} ${modalityUnit}`) + textLines.push(`Max: ${this.reRound(max, this.digitPlaces)} ${modalityUnit}`) } if (stdDev) { - textLines.push(`Std Dev: ${csUtils.roundNumber(stdDev)} ${modalityUnit}`) + textLines.push(`Std Dev: ${this.reRound(stdDev, this.digitPlaces)} ${modalityUnit}`) } return textLines }, + reRound(result, finalPrecision) { + if (result.includes(', ')) { + const numStrs = result.split(', ') + const processed = numStrs.map(str => this.processSingle(str, finalPrecision)) + return processed.join(', ') + } + return this.processSingle(result, finalPrecision) + }, + processSingle(str, precision) { + const num = parseFloat(str) + if (isNaN(num)) return 'NaN' + + // 保留原极小值处理逻辑 + if (Math.abs(num) < 0.0001) return str + const factor = 10 ** precision + return (Math.round(num * factor + 0.0000001) / factor).toFixed(precision) + }, // 激活工具 setToolActive(toolName) { const toolGroupId = `${this.viewportKey}-${this.activeViewportIndex}` @@ -1847,6 +1877,37 @@ export default { this.activeTool = toolName } } + if (this.criterionType === 0 && this.readingTaskState < 2) { + this.$refs[`ecrf_${this.taskInfo.VisitTaskId}`][0].resetOperateState() + } + }, + setReadingToolActive(toolName) { + if (this.readingTaskState === 2) return + if (this.activeTool === toolName) return + const series = this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].series + if (series && series.TaskInfo.VisitTaskId && series.TaskInfo.VisitTaskId === this.taskInfo.VisitTaskId) { + const toolGroupId = `${this.viewportKey}-${this.activeViewportIndex}` + const toolGroup = ToolGroupManager.getToolGroup(toolGroupId) + if (this.activeTool) { + toolGroup.setToolPassive(this.activeTool) + } + toolGroup.setToolActive(toolName, { + bindings: [{ mouseButton: MouseBindings.Primary }] + }) + this.activeTool = toolName + } + }, + setReadingToolPassive() { + if (this.readingTaskState === 2) return + if (this.activeTool && this.toolNames.includes(this.activeTool)) { + const series = this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].series + if (series && series.TaskInfo.VisitTaskId && series.TaskInfo.VisitTaskId === this.taskInfo.VisitTaskId) { + const toolGroupId = `${this.viewportKey}-${this.activeViewportIndex}` + const toolGroup = ToolGroupManager.getToolGroup(toolGroupId) + toolGroup.setToolPassive(this.activeTool) + this.activeTool = '' + } + } }, setMoreToolActive(toolName) { if (this.readingTaskState === 2) return 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 2e6fcbbb..586c878e 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 @@ -232,22 +232,32 @@ - + - 标记 + 测量 + + + + 绑定 i.MeasureData && i.MeasureData.annotationUID === annotation.annotationUID) return i > -1 @@ -354,9 +357,14 @@ export default { async operateImageMarker(obj) { this.operateStateEnum = obj.operateStateEnum this.operateQuestionId = obj.question.Id - if (obj.operateStateEnum === 1) { + this.imageTool = obj.question.ImageTool + this.imageToolAttribute = obj.question.ImageToolAttribute + if (obj.operateStateEnum === 0) { + // 绑定标记 + this.$emit('setReadingToolPassive') + } else if (obj.operateStateEnum === 1) { // 添加标记 - + this.$emit('setReadingToolActive', obj.question.ImageTool) } else if (obj.operateStateEnum === 2) { // 查看标记 const i = this.questionMarkInfoList.findIndex(i => i.QuestionId === obj.question.Id) @@ -366,8 +374,9 @@ export default { } } else if (obj.operateStateEnum === 3) { // 更改标记 - // this.$set(this.questionsMarkStatus, obj.question.Id, 1) + this.$emit('setReadingToolPassive') } else if (obj.operateStateEnum === 4) { + this.$emit('setReadingToolPassive') // 移除标记 this.$set(this.questionForm, obj.question.Id, '') const i = this.questionMarkInfoList.findIndex(i => i.QuestionId === obj.question.Id) @@ -405,14 +414,20 @@ export default { }, async bindAnnotationToQuestion(annotation) { try { - if (!(this.operateStateEnum === 1 || this.operateStateEnum === 3)) return + if (!(this.operateStateEnum === 0 || this.operateStateEnum === 1 || this.operateStateEnum === 3)) return + if (this.operateStateEnum === 1 && annotation.markTool !== this.imageTool) return if (!this.operateQuestionId) return - if (this.operateStateEnum === 3) { + if (this.operateStateEnum === 0 || this.operateStateEnum === 3) { if (!annotation.data.label) { this.$alert('该标记不能与问题绑定!') return } - const confirm = await this.$confirm('是否确认更改?', { + if (annotation.markTool !== this.imageTool) { + this.$alert('该标记不能与问题绑定!') + return + } + let msg = this.operateStateEnum === 0 ? '是否确认绑定?' : '是否确认更改?' + const confirm = await this.$confirm(msg, { type: 'warning', distinguishCancelAndClose: true }) @@ -449,7 +464,6 @@ export default { } }, updateAnnotationToQuestion(annotation) { - console.log('updateAnnotationToQuestion', annotation) const i = this.questionMarkInfoList.findIndex(i => i.MeasureData && i.MeasureData.annotationUID === annotation.annotationUID) if (i === -1) return this.questionMarkInfoList[i].measureData = annotation @@ -464,13 +478,25 @@ export default { length = length ? parseFloat(length).toFixed(this.digitPlaces) : length this.$set(this.questionForm, questionId, length) } else if (annotation.metadata.toolName === 'Bidirectional') { - // let length = annotation.data.cachedStats[`imageId:${referencedImageId}`].length - // length = length ? parseFloat(length).toFixed(this.digitPlaces) : length - let short = annotation.data.cachedStats[`imageId:${referencedImageId}`].width - short = short ? parseFloat(short).toFixed(this.digitPlaces) : short - this.$set(this.questionForm, questionId, short) + if (this.imageToolAttribute === 'length') { + let length = annotation.data.cachedStats[`imageId:${referencedImageId}`].length + length = length ? parseFloat(length).toFixed(this.digitPlaces) : length + this.$set(this.questionForm, questionId, length) + } else if (this.imageToolAttribute === 'width') { + let short = annotation.data.cachedStats[`imageId:${referencedImageId}`].width + short = short ? parseFloat(short).toFixed(this.digitPlaces) : short + this.$set(this.questionForm, questionId, short) + } } }, + resetOperateState() { + console.log('resetOperateState') + this.operateStateEnum = null + this.operateQuestionId = '' + this.operateRowId = '' + this.imageTool = '' + this.imageToolAttribute = '' + }, async resetForm() { const confirm = await this.$confirm( this.$t('trials:dicomReading:message:confirmReset1'), 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 547c1f0f..114c3d39 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 @@ -460,6 +460,7 @@ export default { }, formItemNumberChange(v, question) { this.$emit('formItemTableNumberChange', v, question) + this.$emit('setFormItemData', { key: question.Id, val: v, question: question }) // this.$emit('formItemTableNumberChange', v, question) }, resetChild(obj) { diff --git a/src/views/trials/trials-panel/setting/reading-unit/components/QuestionTableFormItem.vue b/src/views/trials/trials-panel/setting/reading-unit/components/QuestionTableFormItem.vue index 9fea8c37..3399d21f 100644 --- a/src/views/trials/trials-panel/setting/reading-unit/components/QuestionTableFormItem.vue +++ b/src/views/trials/trials-panel/setting/reading-unit/components/QuestionTableFormItem.vue @@ -353,7 +353,9 @@ export default { } }, formItemNumberChange(v, question) { - this.$emit('formItemTableNumberChange', v, question) + // this.$emit('formItemTableNumberChange', v, question) + this.$emit('formItemTableNumberChange') + this.$emit('setFormItemData', { key: question.Id, val: v, question: question }) }, resetChild(obj) { obj.forEach(i => { diff --git a/src/views/trials/trials-panel/setting/reading-unit/components/QuestionsForm.vue b/src/views/trials/trials-panel/setting/reading-unit/components/QuestionsForm.vue index a88e38b2..1caed299 100644 --- a/src/views/trials/trials-panel/setting/reading-unit/components/QuestionsForm.vue +++ b/src/views/trials/trials-panel/setting/reading-unit/components/QuestionsForm.vue @@ -28,7 +28,7 @@