diff --git a/src/components/Dicom/DicomViewer.vue b/src/components/Dicom/DicomViewer.vue index 41c39b9c..583b303a 100644 --- a/src/components/Dicom/DicomViewer.vue +++ b/src/components/Dicom/DicomViewer.vue @@ -496,7 +496,7 @@ export default { this.colormapsList = cornerstone.colors.getColormapsList() this.currentDicomCanvas = this.$refs['dicomCanvas0'] this.type = this.$route.query.type - this.isEdit = parseInt(this.$route.query.showDelete) + this.isEdit = parseInt(this.$route.query.showDelete) || parseInt(this.$route.query.showEdit) }, beforeDestroy() { clearPTClinicalDataCache() diff --git a/src/views/trials/trials-panel/reading/dicoms/components/DicomCanvas.vue b/src/views/trials/trials-panel/reading/dicoms/components/DicomCanvas.vue index e4ac3899..1c2022a1 100644 --- a/src/views/trials/trials-panel/reading/dicoms/components/DicomCanvas.vue +++ b/src/views/trials/trials-panel/reading/dicoms/components/DicomCanvas.vue @@ -146,6 +146,7 @@ import BidirectionalTool from '@/views/trials/trials-panel/reading/dicoms/tools/ import ArrowAnnotateTool from '@/views/trials/trials-panel/reading/dicoms/tools/ArrowAnnotate/ArrowAnnotateTool' import RectangleRoiTool from '@/views/trials/trials-panel/reading/dicoms/tools/RectangleRoi/RectangleRoiTool' import ProbeTool from '@/views/trials/trials-panel/reading/dicoms/tools/Probe/ProbeTool' +import FixedCircleRoiTool from '@/views/trials/trials-panel/reading/dicoms/tools/FixedCircleRoi/FixedCircleRoiTool' // import OrientationMarkersTool from '@/views/trials/trials-panel/reading/dicoms/tools/OrientationMarkers/OrientationMarkersTool' import ScaleOverlayTool from '@/views/trials/trials-panel/reading/dicoms/tools/ScaleOverlay/ScaleOverlayTool' import getOrientationString from '@/views/trials/trials-panel/reading/dicoms/tools/OrientationMarkers/getOrientationString' @@ -260,7 +261,7 @@ export default { series: '', ToolStateManager: null, renderedMeasured: [], - measuredTools: ['Length', 'Bidirectional', 'ArrowAnnotate', 'RectangleRoi', 'Probe'], + measuredTools: ['Length', 'Bidirectional', 'ArrowAnnotate', 'RectangleRoi', 'Probe', 'FixedCircleRoi'], measureData: [], selectedLesion: null, activeTool: 0, // 0:enable 1:passive 2:active @@ -584,6 +585,13 @@ export default { e.stopPropagation() e.preventDefault() } + } else if (this.CriterionType === 22 && this.activeToolName === 'Probe' && this.readingTaskState < 2) { + if (!(e.detail.image.imageFrame.photometricInterpretation === 'MONOCHROME1' || e.detail.image.imageFrame.photometricInterpretation === 'MONOCHROME2')) { + this.$alert(this.$t('trials:MRIPDFF:message:message5')) + e.stopImmediatePropagation() + e.stopPropagation() + e.preventDefault() + } } }, pointNearTool(e) { @@ -593,7 +601,9 @@ export default { var toolType = this.measuredTools[m] const toolState = ToolStateManager.getImageIdToolState(image.imageId, toolType) if (toolState) { - var toolObj = new cornerstoneTools[`${toolType}Tool`]() + const toolClass = this.getToolClassByType(toolType) + if (!toolClass) continue + var toolObj = new toolClass() var i = toolState.data.findIndex(data => toolObj.pointNearTool(element, data, currentPoints.canvas, 'mouse')) if (i > -1 && this.disabledMarks.length > 0 && this.disabledMarks.indexOf(toolState.data[i].remark) > -1) { return true @@ -783,7 +793,9 @@ export default { var toolType = this.measuredTools[m] const toolState = ToolStateManager.getImageIdToolState(e.detail.image.imageId, toolType) if (toolState) { - var toolObj = new cornerstoneTools[`${toolType}Tool`]() + const toolClass = this.getToolClassByType(toolType) + if (!toolClass) continue + var toolObj = new toolClass() var i = toolState.data.findIndex(data => toolObj.pointNearTool(element, data, currentPoints.canvas, 'mouse')) if (i > -1) { @@ -1019,7 +1031,9 @@ export default { var toolType = this.measuredTools[t] const toolState = ToolStateManager.getImageIdToolState(e.detail.image.imageId, toolType) if (!toolState) continue - var toolObj = new cornerstoneTools[`${toolType}Tool`]() + const toolClass = this.getToolClassByType(toolType) + if (!toolClass) continue + var toolObj = new toolClass() var i = toolState.data.findIndex(data => toolObj.pointNearTool(element, data, currentPoints.canvas, 'mouse')) if (i > -1) { var idx = this.measureData.findIndex(item => item.MeasureData && item.MeasureData.data && item.MeasureData.data.uuid === toolState.data[i].uuid) @@ -1046,7 +1060,7 @@ export default { measureData.wc = Math.round(viewport.voi.windowCenter) measureData.data.active = false var criterionType = parseInt(localStorage.getItem('CriterionType')) - if (criterionType === 21) { + if (criterionType === 21 || criterionType === 22) { measureData.tableQuestionId = this.measureData[idx].TableQuestionId } this.$emit('modifyMeasureData', { measureData, questionInfo }) @@ -1057,6 +1071,15 @@ export default { } } }, + getToolClassByType(toolType) { + if (toolType === 'Length') return LengthTool + if (toolType === 'Bidirectional') return BidirectionalTool + if (toolType === 'ArrowAnnotate') return ArrowAnnotateTool + if (toolType === 'RectangleRoi') return RectangleRoiTool + if (toolType === 'Probe') return ProbeTool + if (toolType === 'FixedCircleRoi') return FixedCircleRoiTool + return cornerstoneTools[`${toolType}Tool`] + }, loadImageStack(dicomSeries) { return new Promise(resolve => { this.isInitWwwc = true @@ -1169,8 +1192,22 @@ export default { // Add the tool const toolName = toolBtn.getAttribute('data-tool') const apiTool = cornerstoneTools[`${toolName}Tool`] - if (apiTool) { - const toolAlreadyAddedToElement = cornerstoneTools.getToolForElement(element, apiTool) + let toolClass = apiTool + if (toolName === 'Length') { + toolClass = LengthTool + } else if (toolName === 'Bidirectional') { + toolClass = BidirectionalTool + } else if (toolName === 'ArrowAnnotate') { + toolClass = ArrowAnnotateTool + } else if (toolName === 'RectangleRoi') { + toolClass = RectangleRoiTool + } else if (toolName === 'Probe' && (parseInt(localStorage.getItem('CriterionType')) === 21)) { + toolClass = ProbeTool + } else if (toolName === 'Probe' && (parseInt(localStorage.getItem('CriterionType')) === 22)) { + toolClass = FixedCircleRoiTool + } + if (toolClass) { + const toolAlreadyAddedToElement = cornerstoneTools.getToolForElement(element, toolClass) if (!toolAlreadyAddedToElement) { if (toolName === 'Length') { @@ -1183,8 +1220,10 @@ export default { cornerstoneTools.addToolForElement(element, ArrowAnnotateTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true } }) } else if (toolName === 'RectangleRoi') { cornerstoneTools.addToolForElement(element, RectangleRoiTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true } }) - } else if (toolName === 'Probe' && parseInt(localStorage.getItem('CriterionType')) === 21) { + } else if (toolName === 'Probe' && (parseInt(localStorage.getItem('CriterionType')) === 21)) { cornerstoneTools.addToolForElement(element, ProbeTool, { configuration: { fixedRadius: 5, handleRadius: true, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces } }) + } else if (toolName === 'Probe' && parseInt(localStorage.getItem('CriterionType')) === 22) { + cornerstoneTools.addToolForElement(element, ProbeTool, { configuration: { fixedRadius: 5, unit: 'mm', handleRadius: true, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces } }) } else { cornerstoneTools.addToolForElement(element, apiTool) } @@ -1528,7 +1567,7 @@ export default { measureData.wc = Math.round(viewport.voi.windowCenter) measureData.data.active = false var criterionType = parseInt(localStorage.getItem('CriterionType')) - if (criterionType === 21) { + if (criterionType === 21 || criterionType === 22) { measureData.tableQuestionId = this.measureData[idx].TableQuestionId } this.$emit('modifyMeasureData', { measureData, questionInfo }) @@ -1982,7 +2021,8 @@ export default { 'CobbAngle', 'Angle', 'Bidirectional', - 'FreehandRoi' + 'FreehandRoi', + 'FixedCircleRoi' ] for (let i = 0; i < toolROITypes.length; i++) { const toolROIType = toolROITypes[i] diff --git a/src/views/trials/trials-panel/reading/dicoms/components/DicomViewer.vue b/src/views/trials/trials-panel/reading/dicoms/components/DicomViewer.vue index cbd3f60f..cce7ce21 100644 --- a/src/views/trials/trials-panel/reading/dicoms/components/DicomViewer.vue +++ b/src/views/trials/trials-panel/reading/dicoms/components/DicomViewer.vue @@ -492,6 +492,10 @@ :question-form-change-state="questionFormChangeState" :question-form-change-num="questionFormChangeNum" :is-show="isShow" :is-reading-show-subject-info="isReadingShowSubjectInfo" @handleReadingChart="handleReadingChart" /> +

Developing...

@@ -689,6 +693,7 @@ import LuganoWithoutPETQuestionList from './LuganoWithoutPET/QuestionList' import IVUSList from './IVUS/QuestionList' import OCTList from './OCT/QuestionList' import MRIPDFF from './MRIPDFF/QuestionList' +import MRIPDFFAdvance from './MRIPDFFAdvance/QuestionList' import CustomWwwcForm from './CustomWwwcForm' import Manuals from './Manuals' import Hotkeys from './Hotkeys' @@ -725,6 +730,7 @@ export default { IVUSList, OCTList, MRIPDFF, + MRIPDFFAdvance, 'download-dicom-and-nonedicom': downloadDicomAndNonedicom, 'upload-dicom-and-nonedicom': uploadDicomAndNonedicom, SignForm @@ -1012,6 +1018,10 @@ export default { this.measuredTools = [{ toolName: 'Probe', text: this.$t('trials:reading:button:circle'), icon: 'oval', isDisabled: false, disabledReason: '' }] + } else if (this.CriterionType === 22) { + this.measuredTools = [{ + toolName: 'Probe', text: this.$t('trials:reading:button:circle'), icon: 'oval', isDisabled: false, disabledReason: '' + }] } this.rotateList[0] = '1' this.colorList[0] = '' @@ -1126,7 +1136,12 @@ export default { DicomEvent.$on('addAnnotation', async obj => { this.tmpData = Object.assign({}, obj.question) // await this.imageLocation(obj.locateInfo) - this.setToolActive('Probe', true, null, 'tableQuestion') + if (this.CriterionType === 21) { + this.setToolActive('Probe', true, null, 'tableQuestion') + } else if (this.CriterionType === 22) { + this.setToolActive('Probe', true, null, 'tableQuestion') + } + }) window.addEventListener('beforeunload', () => { if (this.petctWindow) { @@ -2160,7 +2175,7 @@ export default { }, // 添加标记 setMeasureData(data) { - if (this.CriterionType === 21) { + if (this.CriterionType === 21 || this.CriterionType === 22) { if (this.tmpData) { data.tableQuestionId = this.tmpData.Id data.tableQuestionMark = this.tmpData.QuestionMark @@ -2174,7 +2189,7 @@ export default { }, // 修改标记 modifyMeasureData(data) { - if (this.CriterionType === 21 && data.measureData.tableQuestionId) { + if ((this.CriterionType === 21 || this.CriterionType === 22) && data.measureData.tableQuestionId) { this.$refs['measurementList'].modifyMeasuredData(data) } else { this.$refs['measurementList'].modifyMeasuredData(data) diff --git a/src/views/trials/trials-panel/reading/dicoms/components/MRIPDFFAdvance/QuestionForm.vue b/src/views/trials/trials-panel/reading/dicoms/components/MRIPDFFAdvance/QuestionForm.vue new file mode 100644 index 00000000..b6a654cd --- /dev/null +++ b/src/views/trials/trials-panel/reading/dicoms/components/MRIPDFFAdvance/QuestionForm.vue @@ -0,0 +1,862 @@ + + + diff --git a/src/views/trials/trials-panel/reading/dicoms/components/MRIPDFFAdvance/QuestionList.vue b/src/views/trials/trials-panel/reading/dicoms/components/MRIPDFFAdvance/QuestionList.vue new file mode 100644 index 00000000..a3a722bc --- /dev/null +++ b/src/views/trials/trials-panel/reading/dicoms/components/MRIPDFFAdvance/QuestionList.vue @@ -0,0 +1,622 @@ + + + diff --git a/src/views/trials/trials-panel/reading/dicoms/tools/FixedCircleRoi/FixedCircleRoiTool.js b/src/views/trials/trials-panel/reading/dicoms/tools/FixedCircleRoi/FixedCircleRoiTool.js new file mode 100644 index 00000000..b400be40 --- /dev/null +++ b/src/views/trials/trials-panel/reading/dicoms/tools/FixedCircleRoi/FixedCircleRoiTool.js @@ -0,0 +1,347 @@ +import * as cornerstoneTools from 'cornerstone-tools' +import * as cornerstone from 'cornerstone-core' +import getCircleCoords from '../CircleRoi/getCircleCoords' +const EVENTS = cornerstoneTools.EVENTS +const getPixelSpacing = cornerstoneTools.importInternal('util/getPixelSpacing') +const triggerEvent = cornerstoneTools.import('util/triggerEvent') +const external = cornerstoneTools.external +const getToolState = cornerstoneTools.getToolState +const toolStyle = cornerstoneTools.toolStyle +const toolColors = cornerstoneTools.toolColors +const getModule = cornerstoneTools.getModule +const getNewContext = cornerstoneTools.import('drawing/getNewContext') +const draw = cornerstoneTools.import('drawing/draw') +const setShadow = cornerstoneTools.import('drawing/setShadow') +const drawCircle = cornerstoneTools.import('drawing/drawCircle') +const drawHandles = cornerstoneTools.import('drawing/drawHandles') +const drawLinkedTextBox = cornerstoneTools.import('drawing/drawLinkedTextBox') +const getROITextBoxCoords = cornerstoneTools.import('util/getROITextBoxCoords') +const numbersWithCommas = cornerstoneTools.import('util/numbersWithCommas') + +/** + * @public + * @class FixedCircleRoiTool + * @memberof Tools.Annotation + * @classdesc Tool for drawing circular regions of interest with a fixed radius, and measuring + * the statistics of the enclosed pixels. + * @extends Tools.Annotation.CircleRoiTool + */ +export default class FixedCircleRoiTool extends cornerstoneTools.CircleRoiTool { + constructor(props = {}) { + const defaultProps = { + name: 'FixedCircleRoi', + configuration: { + radius: 10, // Default radius in units (mm by default) + unit: 'mm', // 'mm' or 'px' + centerPointRadius: 0, + renderDashed: false, + drawHandlesOnHover: false, + handleRadius: 0, + digits: 1, + }, + }; + super(props, defaultProps); + + // Explicitly set name to ensure it is defined + this.name = 'FixedCircleRoi'; + + // Manually merge configuration to ensure props override defaults + if (props && props.configuration) { + this.configuration = Object.assign( + {}, + this.configuration || defaultProps.configuration, + props.configuration + ); + } + } + + createNewMeasurement(eventData) { + const measurementData = super.createNewMeasurement(eventData); + + if (!measurementData) { + return; + } + + const { image } = eventData; + // Fallback if configuration is missing + if (!this.configuration) { + console.warn( + 'FixedCircleRoiTool: configuration missing, using defaults' + ); + this.configuration = { radius: 10, unit: 'mm' }; + } + + const config = this.configuration; + let radiusPixels = config.radius; + + if (config.unit === 'mm') { + const pixelSpacing = getPixelSpacing(image); + console.log( + 'FixedCircleRoiTool: PixelSpacing retrieved:', + pixelSpacing + ); + + const { colPixelSpacing } = pixelSpacing; + + if (colPixelSpacing && colPixelSpacing > 0) { + radiusPixels = config.radius / colPixelSpacing; + } else { + console.warn( + 'FixedCircleRoiTool: Invalid pixel spacing, treating radius as pixels' + ); + } + } + + // Ensure radiusPixels is a valid number + if (isNaN(radiusPixels)) { + console.warn( + 'FixedCircleRoiTool: radiusPixels is NaN, defaulting to 10px' + ); + radiusPixels = 10; + } + + // Set end handle position based on calculated radius pixels + measurementData.handles.end.x = + measurementData.handles.start.x + radiusPixels; + measurementData.handles.end.y = measurementData.handles.start.y; + + console.log( + 'FixedCircleRoiTool created measurement:', + JSON.parse(JSON.stringify(measurementData)) + ); + + // Invalidate to trigger stats calculation + measurementData.invalidated = true; + + return measurementData; + } + + /** + * Overwrite the addNewMeasurement method to prevent the default behavior + * of resizing the circle on mouse drag immediately after creation. + */ + addNewMeasurement(evt, interactionType) { + const eventData = evt.detail; + if ( + !eventData || + !eventData.currentPoints || + !eventData.currentPoints.image + ) { + console.warn( + 'FixedCircleRoiTool: Invalid eventData supplied to addNewMeasurement' + ); + return; + } + + const element = eventData.element; + + // 1. Create the measurement data (which already has the fixed radius) + const measurementData = this.createNewMeasurement(eventData); + + if (!measurementData) return; + + // 2. Add it to the tool state + cornerstoneTools.addToolState(element, this.name, measurementData); + + // 3. Ensure stats are available for completion listeners (e.g. mean value consumers). + if (!measurementData.cachedStats && eventData.image) { + this.updateCachedStats(eventData.image, element, measurementData) + } + + // 4. Update the image to show the new annotation + cornerstone.updateImage(element); + + // 5. Manually emit completion event since we bypass default drag-finish flow. + triggerEvent(element, EVENTS.MEASUREMENT_COMPLETED, { + toolName: this.name, + element, + measurementData, + }) + + // 6. Do NOT attach mouse/touch event listeners for resizing. + // The circle is created with fixed size and placed immediately. + } + + handleSelectedCallback(evt, measurementData, handle, interactionType = 'mouse') { + // Lock circle radius by preventing start/end handle drag. + if (measurementData && measurementData.handles) { + const { start, end } = measurementData.handles + if (handle === start || handle === end) { + evt.stopImmediatePropagation?.() + evt.preventDefault?.() + return + } + } + + super.handleSelectedCallback(evt, measurementData, handle, interactionType) + } + + pointNearTool(element, data, coords, interactionType = 'mouse') { + const isNearDefault = super.pointNearTool(element, data, coords, interactionType) + if (isNearDefault) { + return true + } + if (!data || !data.handles || !data.handles.start || !data.handles.end) { + return false + } + + const centerCanvas = external.cornerstone.pixelToCanvas(element, data.handles.start) + const edgeCanvas = external.cornerstone.pixelToCanvas(element, data.handles.end) + const radius = external.cornerstoneMath.point.distance(centerCanvas, edgeCanvas) + const distanceToCenter = external.cornerstoneMath.point.distance(centerCanvas, coords) + + return distanceToCenter <= radius + } + + renderToolData(evt) { + const toolData = getToolState(evt.currentTarget, this.name) + + if (!toolData) { + return + } + + const getDistance = external.cornerstoneMath.point.distance + const eventData = evt.detail + const { image, element, canvasContext } = eventData + const lineWidth = toolStyle.getToolWidth() + const { + handleRadius, + drawHandlesOnHover, + hideHandlesIfMoving, + renderDashed, + centerPointRadius, + } = this.configuration + const newContext = getNewContext(canvasContext.canvas) + const { rowPixelSpacing, colPixelSpacing } = getPixelSpacing(image) + const lineDash = getModule('globalConfiguration').configuration.lineDash + + const seriesModule = + external.cornerstone.metaData.get('generalSeriesModule', image.imageId) || + {} + const modality = seriesModule.modality + const hasPixelSpacing = rowPixelSpacing && colPixelSpacing + + draw(newContext, context => { + for (let i = 0; i < toolData.data.length; i++) { + const data = toolData.data[i] + + if (data.visible === false) { + continue + } + + const color = toolColors.getColorIfActive(data) + const handleOptions = { + color, + handleRadius, + drawHandlesIfActive: drawHandlesOnHover, + hideHandlesIfMoving, + } + + setShadow(context, this.configuration) + + const startCanvas = external.cornerstone.pixelToCanvas( + element, + data.handles.start + ) + const endCanvas = external.cornerstone.pixelToCanvas( + element, + data.handles.end + ) + const radius = getDistance(startCanvas, endCanvas) + + const circleOptions = { color } + if (renderDashed) { + circleOptions.lineDash = lineDash + } + + drawCircle( + context, + element, + data.handles.start, + radius, + circleOptions, + 'pixel' + ) + + if (centerPointRadius && radius > 3 * centerPointRadius) { + drawCircle( + context, + element, + data.handles.start, + centerPointRadius, + circleOptions, + 'pixel' + ) + } + + if (data.handles) { + data.handles.start.drawnIndependently = true + data.handles.end.drawnIndependently = true + } + drawHandles(context, eventData, data.handles, handleOptions) + + if (data.invalidated === true) { + if (data.cachedStats) { + this.throttledUpdateCachedStats(image, element, data) + } else { + this.updateCachedStats(image, element, data) + } + } + + if (!data.handles.textBox.hasMoved) { + const defaultCoords = getROITextBoxCoords( + eventData.viewport, + data.handles + ) + Object.assign(data.handles.textBox, defaultCoords) + } + + const textBoxContent = [] + console.log(data) + if (data.remark) { + textBoxContent.push(data.remark) + } + + const digits = this.configuration.digits || 1 + if (!image.color && data.cachedStats && Number.isFinite(data.cachedStats.mean)) { + const unit = modality === 'CT' && this.configuration.showHounsfieldUnits !== false ? 'HU' : '' + const meanText = numbersWithCommas(data.cachedStats.mean.toFixed(digits)) + textBoxContent.push(unit ? `Mean: ${meanText} ${unit}` : `Mean: ${meanText}`) + } + + if (!textBoxContent.length) { + continue + } + + const textBoxAnchorPoints = handles => + findTextBoxAnchorPoints(handles.start, handles.end) + + drawLinkedTextBox( + context, + element, + data.handles.textBox, + textBoxContent, + data.handles, + textBoxAnchorPoints, + color, + lineWidth, + 20, + true + ) + + data.unit = modality === 'CT' && this.configuration.showHounsfieldUnits !== false ? 'HU' : '' + } + }) + } +} + +function findTextBoxAnchorPoints(startHandle, endHandle) { + const { left, top, width, height } = getCircleCoords(startHandle, endHandle) + + return [ + { x: left + width / 2, y: top }, + { x: left, y: top + height / 2 }, + { x: left + width / 2, y: top + height }, + { x: left + width, y: top + height / 2 }, + ] +} diff --git a/src/views/trials/trials-panel/reading/dicoms/tools/Probe/ProbeTool.js b/src/views/trials/trials-panel/reading/dicoms/tools/Probe/ProbeTool.js index a8224bbc..65baf902 100644 --- a/src/views/trials/trials-panel/reading/dicoms/tools/Probe/ProbeTool.js +++ b/src/views/trials/trials-panel/reading/dicoms/tools/Probe/ProbeTool.js @@ -1,4 +1,6 @@ import * as cornerstoneTools from 'cornerstone-tools' +const EVENTS = cornerstoneTools.EVENTS +const triggerEvent = cornerstoneTools.import('util/triggerEvent') const external = cornerstoneTools.external // State const getToolState = cornerstoneTools.getToolState @@ -87,7 +89,7 @@ export default class ProbeTool extends cornerstoneTools.ProbeTool { return { visible: true, - active: true, + active: false, color: undefined, invalidated: true, handles: { @@ -100,8 +102,8 @@ export default class ProbeTool extends cornerstoneTools.ProbeTool { end: { x: eventData.currentPoints.image.x, y: eventData.currentPoints.image.y, - highlight: true, - active: true, + highlight: false, + active: false, radius: 0 }, // textBox: { @@ -125,6 +127,41 @@ export default class ProbeTool extends cornerstoneTools.ProbeTool { }; } + addNewMeasurement(evt, interactionType) { + const eventData = evt.detail + if (!eventData || !eventData.currentPoints || !eventData.currentPoints.image) { + return + } + + const { element, image } = eventData + const measurementData = this.createNewMeasurement(eventData) + + if (!measurementData) { + return + } + + // Click-to-place and finish immediately; avoid default drag listeners. + measurementData.active = false + if (measurementData.handles && measurementData.handles.end) { + measurementData.handles.end.active = false + measurementData.handles.end.highlight = false + } + + cornerstoneTools.addToolState(element, this.name, measurementData) + + if (!measurementData.cachedStats && image) { + this.updateCachedStats(image, element, measurementData) + } + + external.cornerstone.updateImage(element) + + triggerEvent(element, EVENTS.MEASUREMENT_COMPLETED, { + toolName: this.name, + element, + measurementData + }) + } + /** * * diff --git a/src/views/trials/trials-panel/visit/crc-upload/components/studyInfo.vue b/src/views/trials/trials-panel/visit/crc-upload/components/studyInfo.vue index 4886d9c3..2219867a 100644 --- a/src/views/trials/trials-panel/visit/crc-upload/components/studyInfo.vue +++ b/src/views/trials/trials-panel/visit/crc-upload/components/studyInfo.vue @@ -55,7 +55,7 @@ - + @@ -309,8 +309,14 @@ export default { // 预览影像 handleViewStudy(row) { var token = getToken() + let path = '' + if (this.hasPermi(['trials:trials-panel:visit:crc-upload:edit'])) { + path = `/showdicom?studyId=${row.StudyId}&isFromCRCUpload=1&TokenKey=${token}&type=Study&showEdit=${(this.data.SubmitState * 1 < 2 || (this.data.SubmitState === 2 && this.data.IsQCConfirmedReupload)) ? 1 : 0}` + } else { + path = `/showdicom?studyId=${row.StudyId}&isFromCRCUpload=1&TokenKey=${token}&type=Study` + } const routeData = this.$router.resolve({ - path: `/showdicom?studyId=${row.StudyId}&isFromCRCUpload=1&TokenKey=${token}&type=Study`, + path: path }) var newWindow = window.open(routeData.href, '_blank') this.$emit('setOpenWindow', newWindow) diff --git a/src/views/trials/trials-panel/visit/crc-upload/components/uploadDicomFiles2.vue b/src/views/trials/trials-panel/visit/crc-upload/components/uploadDicomFiles2.vue index 11cedab5..ea97a047 100644 --- a/src/views/trials/trials-panel/visit/crc-upload/components/uploadDicomFiles2.vue +++ b/src/views/trials/trials-panel/visit/crc-upload/components/uploadDicomFiles2.vue @@ -423,7 +423,7 @@ - + @@ -791,8 +791,14 @@ export default { // 预览单个检查影像 handleViewStudy(row) { var token = getToken() + let path = '' + if (this.hasPermi(['trials:trials-panel:visit:crc-upload:edit'])) { + path = `/showdicom?studyId=${row.StudyId}&TokenKey=${token}&type=Study&showEdit=${!(!this.isAfresh && this.data.SubmitState === 2 && this.data.SubmitTime) ? 1 : 0}` + } else { + path = `/showdicom?studyId=${row.StudyId}&TokenKey=${token}&type=Study` + } const routeData = this.$router.resolve({ - path: `/showdicom?studyId=${row.StudyId}&TokenKey=${token}&type=Study`, + path: path, }) window.open(routeData.href, '_blank') }, diff --git a/src/views/trials/trials-panel/visit/crc-upload/components/uploadPetClinicalData.vue b/src/views/trials/trials-panel/visit/crc-upload/components/uploadPetClinicalData.vue index 5ed6a82a..ed6a8c8d 100644 --- a/src/views/trials/trials-panel/visit/crc-upload/components/uploadPetClinicalData.vue +++ b/src/views/trials/trials-panel/visit/crc-upload/components/uploadPetClinicalData.vue @@ -512,7 +512,7 @@ export default { } }, mounted() { - this.isPatientFormCanEdit = this.allowAddOrEdit || this.isPatientFormAllowEdit + this.isPatientFormCanEdit = this.allowAddOrEdit || this.isPatientFormAllowEdit this.getClinicalData() }, methods: { diff --git a/src/views/trials/trials-panel/visit/qc-check/components/dicomFiles.vue b/src/views/trials/trials-panel/visit/qc-check/components/dicomFiles.vue index 087fca9e..44698a99 100644 --- a/src/views/trials/trials-panel/visit/qc-check/components/dicomFiles.vue +++ b/src/views/trials/trials-panel/visit/qc-check/components/dicomFiles.vue @@ -64,7 +64,7 @@ - +