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-04-24 16:10:51 +08:00
commit 741c723bab
6 changed files with 60 additions and 17 deletions

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1777014169186" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4736" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M1024 739.560727V1024H739.560727v-84.898909h199.540364v-199.540364H1024z m-939.101091 0v199.540364h199.540364V1024H0V739.560727h84.898909zM824.878545 199.121455v625.75709H199.121455V199.121455h625.75709z m-85.317818 85.317818H284.439273v455.121454h455.121454V284.439273zM1024 0v284.439273h-84.898909V84.898909h-199.540364V0H1024zM284.439273 0v84.898909H84.898909v199.540364H0V0h284.439273z" fill="#e6e6e6" p-id="4737"></path></svg>

After

Width:  |  Height:  |  Size: 764 B

View File

@ -40,10 +40,10 @@
<div v-if="series" class="right-bottom-text">
<div v-show="imageInfo.location">Location: {{
`${Number(imageInfo.location).toFixed(digitPlaces)} mm`
}}</div>
}}</div>
<div v-show="imageInfo.sliceThickness">Slice Thickness: {{
`${Number(imageInfo.sliceThickness).toFixed(digitPlaces)} mm`
}}</div>
}}</div>
<div v-show="imageInfo.wwwc">WW/WL: {{ imageInfo.wwwc }}</div>
</div>
<div class="orientation-top">
@ -512,7 +512,7 @@ export default {
const renderingEngine = getRenderingEngine(this.renderingEngineId)
const viewport = renderingEngine.getViewport(this.viewportId)
const currentImageIdIndex = viewport.getCurrentImageIdIndex()
const numImages = viewport.getImageIds().length
const numImages = this.imageInfo.total
let newImageIdIndex = null
if (type === 0) {
newImageIdIndex = 0
@ -628,6 +628,7 @@ export default {
let volume = cache.getVolume(this.volumeId)
// console.log(volume, 'volume')
if (this.series.orientation === 'AXIAL' && this.series.curIndex) return this.setFullScreen(this.series.curIndex)
console.log(this.series.orientation, this.series.curIndex)
let index = this.series.orientation === 'AXIAL' ? Math.ceil((volume._imageIds.length - 1) / 2) - 1 : Math.ceil((volume.dimensions[0]) / 2) - 1
this.setFullScreen(index)
} catch (e) {

View File

@ -162,9 +162,14 @@
</div>
<!-- MPR -->
<div class="tool-item" :title="`${$t('trials:reading:button:mpr')}`" @click.prevent="openMPRViewport()"
v-if="(criterionType === 0 && readingTool === 0) || this.readingTool === 3">
v-if="((criterionType === 0 && readingTool === 0) || this.readingTool === 3) && !isMPR">
<svg-icon icon-class="mpr" class="svg-icon" style="transform: rotate(180deg);" />
</div>
<!-- 退出MPR -->
<div class="tool-item" :title="`${$t('trials:reading:button:exit_mpr')}`" @click.prevent="openMPRViewport()"
v-if="((criterionType === 0 && readingTool === 0) || this.readingTool === 3) && isMPR">
<svg-icon icon-class="exit_mpr" class="svg-icon" style="transform: rotate(180deg);" />
</div>
<!-- 直方图 -->
<div class="tool-item" :title="`${$t('trials:reading:button:histogram')}`" @click.prevent="openHistogram"
v-if="this.readingTool === 3">
@ -477,7 +482,7 @@
</el-tab-pane>
<!-- 其他 -->
<el-tab-pane :label="$t('trials:reading:tab:others')" name="3">
<Others v-if="personalConfigDialog.activeName === '3'" :imageToolType="1"/>
<Others v-if="personalConfigDialog.activeName === '3'" :imageToolType="1" />
</el-tab-pane>
</el-tabs>
@ -1019,6 +1024,15 @@ export default {
// this.$refs.surfaceViewport.setSeriesInfo(obj)
},
async openHistogram() {
const renderingEngine = getRenderingEngine(this.renderingEngineId)
let viewportId = `${this.viewportKey}-${this.activeViewportIndex}`
const viewport = renderingEngine.getViewport(viewportId)
let imageIds = viewport.getImageIds(this.$refs[viewportId][0].volumeId)
let imageId = imageIds[0]
const imagePixelModule = metaData.get('imagePixelModule', imageId);
const photometricInterpretation = imagePixelModule?.photometricInterpretation;
console.log(photometricInterpretation, 'photometricInterpretation')
if (photometricInterpretation && photometricInterpretation !== 'MONOCHROME1' && photometricInterpretation !== 'MONOCHROME2') return this.$confirm(this.$t('trials:histogram:confirm:photometricInterpretationNotSupported'))
this.histogramVisible = true
this.setToolsPassive()
this.$refs.histogram.init()
@ -2304,7 +2318,7 @@ export default {
'#ffd10a',
'#b6d634',
]
if (viewportId === 'viewport-fusion-hidden-sag') {
return colors[colors.length - 1]
} else {
@ -4100,7 +4114,10 @@ export default {
},
async openMPRViewport(data = null) {
return new Promise(async (resolve, reject) => {
this.setToolsPassive()
if (this.isMPR) {
this.activeSeries(this.$refs[`viewport-MPR-0`][0].series)
resolve(false)
if (!data) return resolve(false)
let viewportSeries = this.$refs[`viewport-MPR-0`][0].series
if (data && viewportSeries.SeriesInstanceUid === data.SeriesInstanceUid) return resolve(true)
@ -4132,9 +4149,12 @@ export default {
await this.getVolume(series)
this.loading = false
this.loadingText = null
delete series.orientation
delete series.isLocation
this.$refs[`viewport-MPR-0`][0].setSeriesInfo(Object.assign({ orientation: 'AXIAL', isLocation: data && this.activeViewportIndex === 0 }, series))
this.$refs[`viewport-MPR-1`][0].setSeriesInfo(Object.assign({ orientation: 'SAGITTAL', isLocation: data && this.activeViewportIndex === 1 }, series))
this.$refs[`viewport-MPR-2`][0].setSeriesInfo(Object.assign({ orientation: 'CORONAL', isLocation: data && this.activeViewportIndex === 2 }, series))
this.setToolActive('Crosshairs')
resolve(false)
})

View File

@ -1,5 +1,9 @@
<template>
<div class="Segmentations" v-loading="loading">
<h3 style="color: #fff;margin: 0;padding: 15px 10px;">
<span>{{ series.TaskInfo.SubjectCode }} </span>
<span style="margin-left:5px;">{{ series.TaskInfo.TaskBlindName }}</span>
</h3>
<el-collapse v-model="activeNames">
<el-collapse-item name="tools">
<template slot="title">
@ -8,24 +12,24 @@
<div class="tool-frame">
<div :title="$t('trials:Segmentations:tools:contour')"
:class="['tool-item', activeTool === 'LabelMapEditWithContour' && segmentList.length > 0 ? 'tool-item-active' : '']"
:style="{ cursor: segmentList.length <= 0 || (curSegment && curSegment.lock) || ['viewport-MPR-1', 'viewport-MPR-2'].includes(`${viewportKey}-${activeViewportIndex}`) ? 'not-allowed' : 'pointer' }"
:style="{ cursor: isMPR || segmentList.length <= 0 || (curSegment && curSegment.lock) || ['viewport-MPR-1', 'viewport-MPR-2'].includes(`${viewportKey}-${activeViewportIndex}`) ? 'not-allowed' : 'pointer' }"
@click.prevent="setToolActive('LabelMapEditWithContour')">
<svg-icon icon-class="contour" class="svg-icon" />
</div>
<div :title="$t('trials:Segmentations:tools:thresholecircle')"
:class="['tool-item', ThresholdTools.includes(activeTool) && segmentList.length > 0 ? 'tool-item-active' : '']"
:style="{ cursor: segmentList.length <= 0 || (curSegment && curSegment.lock) || ['viewport-MPR-1', 'viewport-MPR-2'].includes(`${viewportKey}-${activeViewportIndex}`) ? 'not-allowed' : 'pointer' }"
:style="{ cursor: isMPR || segmentList.length <= 0 || (curSegment && curSegment.lock) || ['viewport-MPR-1', 'viewport-MPR-2'].includes(`${viewportKey}-${activeViewportIndex}`) ? 'not-allowed' : 'pointer' }"
@click.prevent="initThreshold">
<svg-icon icon-class="thresholecircle" class="svg-icon" />
</div>
<div :title="$t('trials:Segmentations:tools:circularbrush')"
:class="['tool-item', activeTool === 'CircularBrush' && segmentList.length > 0 ? 'tool-item-active' : '']"
:style="{ cursor: segmentList.length <= 0 || (curSegment && curSegment.lock) || ['viewport-MPR-1', 'viewport-MPR-2'].includes(`${viewportKey}-${activeViewportIndex}`) ? 'not-allowed' : 'pointer' }"
:style="{ cursor: isMPR || segmentList.length <= 0 || (curSegment && curSegment.lock) || ['viewport-MPR-1', 'viewport-MPR-2'].includes(`${viewportKey}-${activeViewportIndex}`) ? 'not-allowed' : 'pointer' }"
@click.prevent="setToolActive('CircularBrush')">
<svg-icon icon-class="circularbrush" class="svg-icon" />
</div>
<div :class="['tool-item', activeTool === 'CircularEraser' && segmentList.length > 0 ? 'tool-item-active' : '']"
:style="{ cursor: segmentList.length <= 0 || (curSegment && curSegment.lock) || ['viewport-MPR-1', 'viewport-MPR-2'].includes(`${viewportKey}-${activeViewportIndex}`) ? 'not-allowed' : 'pointer' }"
:style="{ cursor: isMPR || segmentList.length <= 0 || (curSegment && curSegment.lock) || ['viewport-MPR-1', 'viewport-MPR-2'].includes(`${viewportKey}-${activeViewportIndex}`) ? 'not-allowed' : 'pointer' }"
:title="$t('trials:Segmentations:tools:Eraser')"
@click.prevent="setToolActive('CircularEraser')">
<svg-icon icon-class="clear" class="svg-icon" />
@ -202,7 +206,8 @@
<template v-if="item.stats">
<div v-for="k in statsKey" :key="k" class="statsBox">
<span>{{ k }}</span>
<span v-if="item.stats[k]">{{ JSON.stringify(item.stats[k].value) !== 'null' ?
<span v-if="item.stats[k]">{{ JSON.stringify(item.stats[k].value) !== 'null'
?
Number(item.stats[k].value).toFixed(2) : null
}}<i>{{ item.stats[k].unit }}</i></span>
</div>
@ -494,11 +499,11 @@ export default {
this.popoverId = `popover-${item.segmentationId}_${item.segmentIndex}`
},
initThreshold() {
if (this.isMPR) return false
if (!this.ThresholdTools.includes(this.activeTool)) {
this.setToolActive(this.ThresholdTools[0])
this.thresholdType = this.ThresholdTools[0]
}
},
createSegmentConfiguration(segmentIndex, segmentationId, otherSegments) {
const containedSegmentIndices = otherSegments
@ -618,6 +623,7 @@ export default {
// if (!this.series.TaskInfo || this.series.TaskInfo.VisitTaskId !== this.visitInfo.VisitTaskId) return false
if (this.segmentList.length <= 0) return false
if (this.curSegment.lock) return false
if (this.isMPR) return false
if (this.histogramVisible && !this.ThresholdTools.includes(toolName)) return false
if (['viewport-MPR-1', 'viewport-MPR-2'].includes(`${this.viewportKey}-${this.activeViewportIndex}`)) return false
const toolGroupId = this.isMPR ? this.volumeToolGroupId : `${this.viewportKey}-${this.activeViewportIndex}`

View File

@ -59,10 +59,10 @@
<div v-if="series" class="right-bottom-text">
<div v-show="imageInfo.location">Location: {{
`${Number(imageInfo.location).toFixed(digitPlaces)} mm`
}}</div>
}}</div>
<div v-show="imageInfo.sliceThickness">Slice Thickness: {{
`${Number(imageInfo.sliceThickness).toFixed(digitPlaces)} mm`
}}</div>
}}</div>
<div v-show="imageInfo.wwwc">WW/WL: {{ imageInfo.wwwc }}</div>
</div>
<div class="orientation-top">
@ -386,6 +386,7 @@ export default {
const { detail } = e
delete this.series.segment
this.series.SliceIndex = detail.imageIndex
console.log(detail.imageIndex, 'idenx')
this.sliderInfo.height = detail.imageIndex * 100 / detail.numberOfSlices
const renderingEngine = getRenderingEngine(this.renderingEngineId)
const viewport = renderingEngine.getViewport(this.viewportId)
@ -441,7 +442,7 @@ export default {
)
csUtils.jumpToSlice(viewport.element, { imageIndex: index })
viewport.render()
})
}, 100)
},
voiModified(e) {
const renderingEngine = getRenderingEngine(this.renderingEngineId)

View File

@ -18,6 +18,14 @@
@click.prevent="setToolActive('histogram_PlanarFreehandROI')">
<svg-icon icon-class="polygon" class="svg-icon" />
</div>
<div :class="['tool-item']" :title="$t('trials:histogram:button:bgopen')"
@click.prevent="showDefaultData(false)" v-if="isNeedDefault">
<svg-icon icon-class="eye-open" class="svg-icon" />
</div>
<div :class="['tool-item']" :title="$t('trials:histogram:button:bgclose')"
@click.prevent="showDefaultData(true)" v-else>
<svg-icon icon-class="eye" class="svg-icon" />
</div>
</div>
<div class="title">{{ $t("trials:histogram:title:histogram") }}</div>
<i class="el-icon-circle-close closeBtn" @click.stop="close"></i>
@ -115,13 +123,18 @@ export default {
'#fb628b',
],
colors: [],
seriesData: {}
seriesData: {},
isNeedDefault: true
}
},
mounted() {
// this.initChart()
},
methods: {
async showDefaultData(f) {
this.isNeedDefault = f
this.initChart()
},
setToolActive(toolName) {
const toolGroupId = `${this.viewportKey}-${this.activeViewportIndex}`
const toolGroup = ToolGroupManager.getToolGroup(toolGroupId)
@ -206,8 +219,9 @@ export default {
}
let seriesData = []
Object.keys(this.seriesData).forEach(key => {
seriesData.push(this.seriesData[key])
if (key !== 'default' || this.isNeedDefault) seriesData.push(this.seriesData[key])
})
this.chart.clear();
const option = {
useUTC: true,
title: {