Merge branch 'main' into uat_us

uat_us
wangxiaoshuang 2026-04-28 15:42:05 +08:00
commit 577bbcd182
13 changed files with 260 additions and 159 deletions

View File

@ -1 +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="1751350116150" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="20392" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M870.4 819.2a51.2 51.2 0 1 1 0 102.4 51.2 51.2 0 0 1 0-102.4zM512 179.2a332.8 332.8 0 1 1 0 665.6 332.8 332.8 0 0 1 0-665.6z m0 51.2a281.6 281.6 0 1 0 0 563.2 281.6 281.6 0 0 0 0-563.2zM153.6 102.4a51.2 51.2 0 1 1 0 102.4 51.2 51.2 0 0 1 0-102.4z" fill="#ADAEB8" p-id="20393"></path></svg>
<?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="1597744457882" class="icon" viewBox="0 0 1170 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10125" width="285.64453125" height="250" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M926.216214 404.588947l1.511115-151.84272H1079.570048c18.035893 0 33.098301-15.062408 33.098301-33.0983a33.390775 33.390775 0 0 0-33.098301-33.098301H927.727329V33.195792a33.390775 33.390775 0 0 0-33.049555-33.049555 33.390775 33.390775 0 0 0-33.0983 33.049555c0 3.022231 0 4.533346 1.511115 7.555577v144.287142H711.24787a33.390775 33.390775 0 0 0-33.098301 33.147046c0 18.035893 15.062408 33.049555 33.098301 33.049555H863.090589v139.802542c0 3.022231-1.46237 4.533346-1.46237 7.506831 0 18.035893 15.013662 33.098301 33.049555 33.098301 15.013662 1.46237 28.564955-10.529062 31.53844-27.053839zM1032.969201 790.995763a29.393631 29.393631 0 0 0-22.520493 10.480316 546.000095 546.000095 0 0 1-117.282049 88.717095 29.101157 29.101157 0 0 0-15.062408 25.591469c0 16.524777 13.551292 30.027324 30.07607 30.027324 4.533346 0 10.529062-1.46237 13.551292-2.973485 1.46237 0 1.46237-1.511115 1.46237-1.511115a523.235874 523.235874 0 0 0 127.811111-97.735041c6.044461-5.995716 10.529062-13.551292 10.529061-22.569238a28.028752 28.028752 0 0 0-28.564954-30.027325zM793.920503 935.282906c-2.973485 0-7.506831 0-10.529062 1.511115-46.600847 15.062408-96.223925 24.080354-145.798258 27.053839-15.062408 1.511115-25.59147 15.062408-25.591469 30.07607 0 16.573523 13.551292 30.07607 30.07607 30.07607 55.618794-4.4846 108.215357-13.502547 159.398295-30.07607a28.95492 28.95492 0 0 0 22.520494-28.564954 30.173561 30.173561 0 0 0-30.07607-30.07607zM535.324796 960.874375c-12.040177-1.511115-24.031609-1.511115-36.071785-3.02223a564.962155 564.962155 0 0 1-49.623078-7.506832c-230.030752-45.089732-389.380302-202.976912-389.380302-380.362355 0-139.851288 99.19741-269.124768 260.106822-339.805969 13.502547-5.995716 27.053839-12.040177 40.556386-16.573523 10.529062-4.4846 22.569239-7.506831 33.0983-10.480317 12.040177-4.533346 21.058123-15.062408 21.058124-28.564954a30.173561 30.173561 0 0 0-30.07607-30.07607 25.396487 25.396487 0 0 0-15.062408 4.4846c-10.529062 3.022231-19.498262 6.044461-28.564955 9.017947l-45.089732 18.035893C114.357309 254.257343 0.097491 406.148808 0.097491 568.471843c0 207.510258 180.407674 387.917932 439.00338 440.563241l54.107679 9.017946c12.040177 1.46237 25.59147 3.022231 37.631646 3.022231h1.46237c16.573523 0 30.07607-13.551292 30.07607-30.07607a30.758509 30.758509 0 0 0-27.05384-30.07607zM1169.798258 569.982958a30.173561 30.173561 0 0 0-30.07607-30.07607 30.173561 30.173561 0 0 0-30.07607 30.07607v1.46237c0 46.649593-10.529062 93.25044-33.049555 136.829057-1.511115 3.022231-1.511115 7.506831-1.511115 12.040177 0 16.573523 13.551292 30.07607 30.07607 30.07607 13.502547 0 24.031609-9.017946 28.564954-21.058124a361.985243 361.985243 0 0 0 36.071786-157.88718v-1.46237z" p-id="10126"></path><path d="M1052.516209 297.835959c-5.995716-4.533346-13.502547-9.017946-22.520493-9.017946a30.173561 30.173561 0 0 0-30.07607 30.07607c0 7.506831 2.973485 15.013662 9.017946 21.009378a375.14657 375.14657 0 0 1 79.699148 118.793164c4.4846 10.529062 15.013662 19.547008 27.053839 19.547008 16.524777 0 30.07607-13.551292 30.07607-30.07607 0-4.4846-1.511115-7.506831-3.02223-12.040177a422.039891 422.039891 0 0 0-90.179464-138.291427zM666.158138 182.065026h4.4846c16.573523 0 30.07607-13.551292 30.07607-30.07607 0-15.013662-12.040177-28.564955-27.053839-28.564954v-1.46237a761.602133 761.602133 0 0 0-154.86495-1.559861h-3.022231a30.173561 30.173561 0 0 0-30.07607 30.07607c0 16.573523 13.551292 30.07607 30.07607 30.07607h3.022231v1.462369c46.600847-5.94697 97.735041-4.4846 147.358119 0z" p-id="10127"></path></svg>

Before

Width:  |  Height:  |  Size: 623 B

After

Width:  |  Height:  |  Size: 3.8 KiB

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="1777352764855" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10736" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M587.808 383.392l-102.208 102.208A37.472 37.472 0 0 0 512 549.408a36.288 36.288 0 0 0 26.272-11.104l315.84-315.232a454.976 454.976 0 1 0 43.52 61.888l-54.688 54.752a372.704 372.704 0 1 1-94.816-116.928l-106.56 106.496-53.792 54.144z" p-id="10737"></path></svg>

After

Width:  |  Height:  |  Size: 594 B

View File

@ -1 +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="1597744457882" class="icon" viewBox="0 0 1170 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10125" width="285.64453125" height="250" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M926.216214 404.588947l1.511115-151.84272H1079.570048c18.035893 0 33.098301-15.062408 33.098301-33.0983a33.390775 33.390775 0 0 0-33.098301-33.098301H927.727329V33.195792a33.390775 33.390775 0 0 0-33.049555-33.049555 33.390775 33.390775 0 0 0-33.0983 33.049555c0 3.022231 0 4.533346 1.511115 7.555577v144.287142H711.24787a33.390775 33.390775 0 0 0-33.098301 33.147046c0 18.035893 15.062408 33.049555 33.098301 33.049555H863.090589v139.802542c0 3.022231-1.46237 4.533346-1.46237 7.506831 0 18.035893 15.013662 33.098301 33.049555 33.098301 15.013662 1.46237 28.564955-10.529062 31.53844-27.053839zM1032.969201 790.995763a29.393631 29.393631 0 0 0-22.520493 10.480316 546.000095 546.000095 0 0 1-117.282049 88.717095 29.101157 29.101157 0 0 0-15.062408 25.591469c0 16.524777 13.551292 30.027324 30.07607 30.027324 4.533346 0 10.529062-1.46237 13.551292-2.973485 1.46237 0 1.46237-1.511115 1.46237-1.511115a523.235874 523.235874 0 0 0 127.811111-97.735041c6.044461-5.995716 10.529062-13.551292 10.529061-22.569238a28.028752 28.028752 0 0 0-28.564954-30.027325zM793.920503 935.282906c-2.973485 0-7.506831 0-10.529062 1.511115-46.600847 15.062408-96.223925 24.080354-145.798258 27.053839-15.062408 1.511115-25.59147 15.062408-25.591469 30.07607 0 16.573523 13.551292 30.07607 30.07607 30.07607 55.618794-4.4846 108.215357-13.502547 159.398295-30.07607a28.95492 28.95492 0 0 0 22.520494-28.564954 30.173561 30.173561 0 0 0-30.07607-30.07607zM535.324796 960.874375c-12.040177-1.511115-24.031609-1.511115-36.071785-3.02223a564.962155 564.962155 0 0 1-49.623078-7.506832c-230.030752-45.089732-389.380302-202.976912-389.380302-380.362355 0-139.851288 99.19741-269.124768 260.106822-339.805969 13.502547-5.995716 27.053839-12.040177 40.556386-16.573523 10.529062-4.4846 22.569239-7.506831 33.0983-10.480317 12.040177-4.533346 21.058123-15.062408 21.058124-28.564954a30.173561 30.173561 0 0 0-30.07607-30.07607 25.396487 25.396487 0 0 0-15.062408 4.4846c-10.529062 3.022231-19.498262 6.044461-28.564955 9.017947l-45.089732 18.035893C114.357309 254.257343 0.097491 406.148808 0.097491 568.471843c0 207.510258 180.407674 387.917932 439.00338 440.563241l54.107679 9.017946c12.040177 1.46237 25.59147 3.022231 37.631646 3.022231h1.46237c16.573523 0 30.07607-13.551292 30.07607-30.07607a30.758509 30.758509 0 0 0-27.05384-30.07607zM1169.798258 569.982958a30.173561 30.173561 0 0 0-30.07607-30.07607 30.173561 30.173561 0 0 0-30.07607 30.07607v1.46237c0 46.649593-10.529062 93.25044-33.049555 136.829057-1.511115 3.022231-1.511115 7.506831-1.511115 12.040177 0 16.573523 13.551292 30.07607 30.07607 30.07607 13.502547 0 24.031609-9.017946 28.564954-21.058124a361.985243 361.985243 0 0 0 36.071786-157.88718v-1.46237z" p-id="10126"></path><path d="M1052.516209 297.835959c-5.995716-4.533346-13.502547-9.017946-22.520493-9.017946a30.173561 30.173561 0 0 0-30.07607 30.07607c0 7.506831 2.973485 15.013662 9.017946 21.009378a375.14657 375.14657 0 0 1 79.699148 118.793164c4.4846 10.529062 15.013662 19.547008 27.053839 19.547008 16.524777 0 30.07607-13.551292 30.07607-30.07607 0-4.4846-1.511115-7.506831-3.02223-12.040177a422.039891 422.039891 0 0 0-90.179464-138.291427zM666.158138 182.065026h4.4846c16.573523 0 30.07607-13.551292 30.07607-30.07607 0-15.013662-12.040177-28.564955-27.053839-28.564954v-1.46237a761.602133 761.602133 0 0 0-154.86495-1.559861h-3.022231a30.173561 30.173561 0 0 0-30.07607 30.07607c0 16.573523 13.551292 30.07607 30.07607 30.07607h3.022231v1.462369c46.600847-5.94697 97.735041-4.4846 147.358119 0z" p-id="10127"></path></svg>
<?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="1777352032068" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5387" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M924.8 337.8c-22.6-53.4-54.9-101.3-96-142.4s-89-73.4-142.4-96C631.2 76.1 572.5 64.2 512 64.2S392.9 76.1 337.6 99.4c-53.4 22.6-101.3 54.9-142.4 96s-73.4 89-96 142.4C75.9 393.1 64 451.8 64 512.2c0 60.5 11.8 119.1 35.2 174.4 22.6 53.4 54.9 101.3 96 142.4 41.1 41.1 89 73.4 142.4 96 55.3 23.4 113.9 35.2 174.4 35.2s119.1-11.8 174.4-35.2c53.4-22.6 101.3-54.9 142.4-96 41.1-41.1 73.4-89 96-142.4 23.4-55.3 35.2-113.9 35.2-174.4 0-60.4-11.8-119.1-35.2-174.4zM780.3 780.5C708.6 852.2 613.4 891.6 512 891.6c-101.3 0-196.6-39.5-268.3-111.1S132.6 613.6 132.6 512.2c0-101.3 39.5-196.6 111.1-268.3s167-111.1 268.3-111.1c101.3 0 196.6 39.5 268.3 111.1s111.1 166.9 111.1 268.3S852 708.8 780.3 780.5z" p-id="5388"></path><path d="M512 512.2m-106.2 0a106.2 106.2 0 1 0 212.4 0 106.2 106.2 0 1 0-212.4 0Z" p-id="5389"></path></svg>

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -16,6 +16,7 @@
</div>
<div v-if="series" class="right-top-text">
<div>{{ series.Description }}</div>
<div class="colorBar" :style="`background-color:${getColor()}`"></div>
</div>
<div v-if="series" class="left-bottom-text">
<div v-show="mousePosition.index.length > 0">
@ -269,6 +270,21 @@ export default {
}
},
methods: {
getColor() {
let color = '#000'
switch (this.series.orientation) {
case 'AXIAL':
color = '#00f'
break;
case 'CORONAL':
color = '#f00'
break;
case 'SAGITTAL':
color = '#0f0'
break;
}
return color
},
initViewport() {
this.element = this.$refs['viewport-volume']
const resizeObserver = new ResizeObserver(() => {
@ -819,6 +835,13 @@ export default {
}
</script>
<style lang="scss" scoped>
.colorBar {
width: 10px;
height: 10px;
border-radius: 50%;
margin: auto;
}
.viewport-wrapper {
width: 100%;
height: 100%;

View File

@ -238,16 +238,16 @@
<svg-icon icon-class="refresh" class="svg-icon" />
</div>
<!-- 更多 :class="['tool-item', readingTaskState === 2 ? 'tool-disabled' : '']" -->
<div v-if="criterionType === 0" :title="$t('trials:reading:button:more')" :class="['tool-item']"
@click.stop="showPanel($event)" @mouseleave="toolMouseout">
<div v-if="criterionType === 0" :class="['tool-item']" @click.stop="showPanel($event)"
@mouseleave="toolMouseout">
<div class="dropdown">
<div class="icon" data-tool="more">
<div class="icon" data-tool="more" :title="$t('trials:reading:button:more')">
<svg-icon icon-class="more" class="svg-icon" />
<i class="el-icon-arrow-down" style="color:#fff;" />
</div>
<div class="dropdown-content">
<!--v-if="readingTaskState < 2"-->
<ul style="width:100px;">
<ul style="width:140px;">
<li v-for="i in customizeStandards" :key="i.toolName" style="text-align:left;">
<span @click.prevent="setMoreToolActive(i.toolName)">
<svg-icon :icon-class="i.icon" class="svg-icon" style="margin-right: 5px;" />
@ -1712,6 +1712,7 @@ export default {
enabled: true,
lineLengthInPx: this.fusionCrosshairStyle.lineLength,
},
mipViewportIds: ['viewport-fusion-3'],
})
toolGroup.setToolActive(VolumeRotateTool.toolName, {
@ -1925,6 +1926,7 @@ export default {
console.log('Completed')
const { annotation } = e.detail
if (!annotation) return
if (annotation.metadata.toolName === FusionJumpToPointTool.toolName) return
if (annotation.metadata.toolName.includes('histogram_')) return this.$refs.histogram.initToolValue(annotation)
if (this.readingTaskState === 2) return
if (annotation.metadata.toolName === 'PlanarFreehandROI' && !annotation.data.contour.closed) return
@ -1951,6 +1953,7 @@ export default {
console.log('Modified')
const { annotation } = e.detail
if (!annotation) return
if (annotation.metadata.toolName === FusionJumpToPointTool.toolName) return
if (annotation.metadata.toolName.includes('histogram_')) return this.$refs.histogram.initToolValue(annotation)
if (this.readingTaskState === 2) return
if (!annotation.highlighted) return
@ -1967,6 +1970,7 @@ export default {
const { annotation } = e.detail
try {
if (!annotation) return
if (annotation.metadata.toolName === FusionJumpToPointTool.toolName) return
if (annotation.metadata.toolName === CrosshairsTool.toolName) return
if (this.readingTaskState === 2 && !annotation.data.label) return false
if (this.readingTaskState === 2) {
@ -1996,6 +2000,7 @@ export default {
async customAnnotationCompletedListener(e) {
const { annotation } = e.detail
if (!annotation) return
if (annotation.metadata.toolName === FusionJumpToPointTool.toolName) return
if (annotation.metadata.toolName.includes('histogram_')) return this.$refs.histogram.initToolValue(annotation)
if (this.readingTaskState === 2) return
const i = this.tools.findIndex(i => i.toolName === annotation.metadata.toolName)
@ -2084,6 +2089,7 @@ export default {
customAnnotationModifiedListener(e) {
const { annotation } = e.detail
if (!annotation) return
if (annotation.metadata.toolName === FusionJumpToPointTool.toolName) return
if (annotation.metadata.toolName.includes('histogram_')) return this.$refs.histogram.initToolValue(annotation)
if (this.readingTaskState === 2) return
if (!annotation.highlighted) return
@ -2113,6 +2119,7 @@ export default {
try {
// if ( this.resetAnnotation && this.isFusion ) return false
if (!annotation) return false
if (annotation.metadata.toolName === FusionJumpToPointTool.toolName) return false
if (annotation.metadata.toolName === CrosshairsTool.toolName) return false
if (this.readingTaskState === 2 && !annotation.data.label) return false
if (this.readingTaskState === 2) {
@ -2217,7 +2224,11 @@ export default {
}
}
},
annotationSelectionChangeListener(e) { },
annotationSelectionChangeListener(e) {
const { annotation } = e.detail || {}
if (!annotation) return
if (annotation.metadata.toolName === FusionJumpToPointTool.toolName) return
},
async getAnnotations(visitTaskId) {
if (this.readingTaskState === 2) return
const taskIdx = this.visitTaskList.findIndex(i => i.VisitTaskId === visitTaskId)
@ -2307,20 +2318,20 @@ export default {
},
setCrosshairsToolLineColor(viewportId) {
let colors = [
'#ffd10a',
'#b6d634',
'#fb628b',
'#ff0000',
'#00ff00',
'#0000ff',
]
let index = viewportId.split("-").pop()
return colors[colors.length - 1 - Number(index)] || colors[0]
},
setFusionCrosshairsToolLineColor(viewportId) {
let colors = [
'#fb628b',
'#fb628b',
'#fb628b',
'#ffd10a',
'#b6d634',
'#0000ff',
'#0000ff',
'#0000ff',
'#ff0000',
'#00ff00',
]
if (viewportId === 'viewport-fusion-hidden-sag') {
@ -2615,7 +2626,7 @@ export default {
toolGroup.setToolDisabled(FusionJumpToPointTool.toolName)
}
},
dispatchFusionCenterPoint() {
dispatchFusionCenterPoint(retryCount = 0) {
const renderingEngine = getRenderingEngine(renderingEngineId)
if (!renderingEngine) return
const toolGroup = ToolGroupManager.getToolGroup(this.fusionToolGroupId)
@ -2641,6 +2652,11 @@ export default {
})
return
}
if (retryCount < 10) {
setTimeout(() => {
this.dispatchFusionCenterPoint(retryCount + 1)
}, 120)
}
},
setFusionMipRotateEnabled(enabled) {
if (!this.isFusion) return
@ -3002,7 +3018,15 @@ export default {
const voi = metaData.get('voiLutModule', volume._imageIds[Math.ceil((volume._imageIds.length - 1) / 2)])
const lower = voi.windowCenter[0] - voi.windowWidth[0] / 2
const upper = voi.windowCenter[0] + voi.windowWidth[0] / 2 - 1
viewport.setProperties({ voiRange: { upper: upper, lower: lower } })
let viewportIds = ['viewport-MPR-0', 'viewport-MPR-1', 'viewport-MPR-2']
viewportIds.forEach(viewportId => {
let viewport = renderingEngine.getViewport(viewportId)
viewport.resetProperties()
viewport.setProperties({ voiRange: { upper: upper, lower: lower } })
viewport.render()
})
return this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].setFullScreen(index)
}
if (this.readingTool === 3 && this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].series.Modality === 'PT') {
viewport.setProperties({ voiRange: { upper: 5, lower: 0 } })
@ -3109,6 +3133,8 @@ export default {
const renderingEngine = getRenderingEngine(renderingEngineId)
const viewportId = `${this.viewportKey}-${this.activeViewportIndex}`
const viewport = renderingEngine.getViewport(viewportId)
let index = this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].series.SliceIndex
if (this.readingTool === 3 || this.isMPR) this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].setFilp(true)
if (v.val === -1) {
//
viewport.resetProperties()
@ -3128,6 +3154,7 @@ export default {
viewport.setProperties({ voiRange: { upper: upper, lower: lower } })
viewport.render()
}
if (this.readingTool === 3 || this.isMPR) this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].setFullScreen(index)
},
setWindowLevelActive(e) {
this.setToolActive('WindowLevel')
@ -3676,6 +3703,8 @@ export default {
this.activeViewportIndex = 2
}
series = {
Id: series.Id,
Modality: series.Modality,
data: series,
StudyIndex: series.StudyIndex,
SeriesIndex: series.SeriesIndex,
@ -3683,7 +3712,7 @@ export default {
}
}
}
this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].setSeriesInfo(series, series.segment || curSeriesId !== series.Id ? false : true)
this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].setSeriesInfo(series, series.segment || curSeriesId !== series.Id ? false : true, { isFusion: this.isFusion && (series.Modality === 'PT' || series.Modality === 'NM') })
this.$refs[series.TaskInfo.VisitTaskId][0].setSeriesActive(series.StudyIndex, series.SeriesIndex)
}
},

View File

@ -1,6 +1,6 @@
<template>
<div class="Segmentations" v-loading="loading">
<h3 style="color: #fff;margin: 0;padding: 15px 10px;">
<h3 style="color: #fff;margin: 0;padding: 15px 10px 5px">
<span>{{ series.TaskInfo.SubjectCode }} </span>
<span style="margin-left:5px;">{{ series.TaskInfo.TaskBlindName }}</span>
</h3>
@ -133,7 +133,7 @@
<template v-if="segmentList.length > 0">
<div class="SegmentGroupBox">
<div style="display: flex;align-items: center;">
<el-popover placement="left" width="40" trigger="click" v-if="readingTaskState < 2"
<el-popover placement="left" width="200px" trigger="click" v-if="readingTaskState < 2"
v-model="popoverVisible" :teleported="true">
<div class="SegmentGroupBtnBox">
<div class="SegmentGroupBtn" @click.stop="addSegmentGroup">
@ -678,6 +678,7 @@ export default {
item.view = !item.view
item.segments.forEach(i => {
i.view = item.view
i.bidirectionalView = item.view
})
DicomEvent.$emit('viewSegmentation', item)
// this.viewBidirectional(item.segments, view)
@ -1932,7 +1933,7 @@ export default {
}
.Bidirectionalbox {
padding: 5px;
padding: 10px;
border-bottom: 1px solid #333;
width: 100%;
display: flex;
@ -1962,7 +1963,7 @@ export default {
}
.statsBox {
padding: 0 5px;
padding: 0 10px;
display: flex;
justify-content: space-between;
color: #333;
@ -1982,7 +1983,7 @@ export default {
cursor: pointer;
margin: 0 5px 10px;
border-radius: 3px;
padding: 5px;
padding: 5px 10px;
position: relative;
.messageBox {
@ -2060,7 +2061,7 @@ export default {
}
.SegmentGroupBox {
padding: 8px 5px;
padding: 8px 10px;
background-color: #333;
margin: 0 5px;
border-radius: 3px;
@ -2092,7 +2093,7 @@ export default {
line-height: 30px;
cursor: pointer;
border-radius: 3px;
padding: 0 5px;
padding: 0 10px;
&:hover {
background-color: rgba($color: #409EFF, $alpha: 0.2);
@ -2104,7 +2105,7 @@ export default {
color: #fff;
line-height: 30px;
margin: 5px;
padding: 0 5px;
padding: 0 10px;
border-radius: 3px;
}
@ -2135,7 +2136,7 @@ export default {
.EraserConfig,
.SegmentConfig {
width: calc(100% - 10px);
padding: 0 5px;
padding: 0 10px;
display: flex;
justify-content: space-between;
align-items: center;
@ -2166,13 +2167,13 @@ export default {
}
::v-deep .el-input-number.is-without-controls .el-input__inner {
padding: 0 5px;
padding: 0 10px;
width: 50px;
}
}
.SegmentConfig {
padding: 5px;
padding: 5px 10px;
}
.svg-icon {
@ -2202,12 +2203,12 @@ export default {
justify-content: flex-start;
align-items: center;
// margin-right: 20px;
padding: 5px;
padding: 5px 10px;
margin-bottom: 10px;
border-bottom: 1px solid #404040;
.icon {
padding: 5px;
padding: 5px 10px;
border-right: 1px solid #404040;
cursor: pointer;
text-align: center;
@ -2255,7 +2256,7 @@ export default {
background-color: #000 !important;
color: #ddd;
border-bottom-color: #5a5a5a;
padding-left: 5px;
padding-left: 10px;
// height: 50px;
line-height: 20px;
}

View File

@ -313,7 +313,7 @@ const config = {
},
{
'name': '定圆工具',
'icon': 'oval',
'icon': 'fixedRadiusCircle',
'toolName': 'FixedRadiusCircleROI',
'props': ['radius', 'area', 'mean', 'max', 'stdDev'],
'i18nKey': 'trials:reading:button:fixedCircle',

View File

@ -25,6 +25,7 @@ class FusionJumpToPointTool extends AnnotationDisplayTool {
enabled: true,
lineLengthInPx: 20,
},
mipViewportIds: [],
},
}) {
super(toolProps, defaultToolProps)
@ -39,17 +40,25 @@ class FusionJumpToPointTool extends AnnotationDisplayTool {
return
}
const { element, currentPoints } = evt.detail || {}
const worldPoint = currentPoints?.world
if (!element || !worldPoint || worldPoint.length < 3) return
if (!element || !currentPoints) return
const enabledElement = getEnabledElement(element)
const { viewport, renderingEngine } = enabledElement || {}
if (!viewport || !renderingEngine) return
const selectedPoint = this._resolveSelectedPoint(viewport, worldPoint)
const sourceIsMip = this._isMipViewportId(viewport.id)
// Non-MIP viewport click should not trigger point relocation.
if (!sourceIsMip) return
const interactionWorldPoint = this._getInteractionWorldPoint(viewport, currentPoints, !sourceIsMip)
if (!interactionWorldPoint || interactionWorldPoint.length < 3) return
const selectedPoint = sourceIsMip
? this._resolveSelectedPoint(viewport, interactionWorldPoint)
: interactionWorldPoint
if (!selectedPoint || selectedPoint.length < 3) return
this.setPoint(selectedPoint, viewport.id, renderingEngine.id)
this.setPoint(selectedPoint, viewport.id, renderingEngine.id, {
jumpToTargetViewports: sourceIsMip,
})
}
mouseDownCallback(evt) {
@ -69,15 +78,17 @@ class FusionJumpToPointTool extends AnnotationDisplayTool {
const { viewport, renderingEngine } = enabledElement || {}
if (!viewport || !renderingEngine) return
let worldPoint = currentPoints?.world
if ((!worldPoint || worldPoint.length < 3) && currentPoints?.canvas && viewport.canvasToWorld) {
worldPoint = viewport.canvasToWorld(currentPoints.canvas)
}
const sourceIsMip = this._isMipViewportId(viewport.id)
const worldPoint = this._getInteractionWorldPoint(viewport, currentPoints, !sourceIsMip)
if (!worldPoint || worldPoint.length < 3) return
const annotation = this._getViewportCrosshairAnnotation(viewport)
const sourceViewportId = this.dragSourceViewportId || annotation?.data?.sourceViewportId || viewport.id
this.setPoint(worldPoint, sourceViewportId, renderingEngine.id)
const sourceViewportId = sourceIsMip
? (this.dragSourceViewportId || annotation?.data?.sourceViewportId || viewport.id)
: viewport.id
this.setPoint(worldPoint, sourceViewportId, renderingEngine.id, {
jumpToTargetViewports: sourceIsMip,
})
evt.preventDefault?.()
}
@ -185,9 +196,7 @@ class FusionJumpToPointTool extends AnnotationDisplayTool {
if (!viewport?.element) return false
const annotations = getAnnotations(this.getToolName(), viewport.element) || []
const crosshairAnnotation = annotations.find((item) =>
item?.data?.type === 'fusion-jump-crosshair' && item?.data?.viewportId === viewport.id
)
const crosshairAnnotation = this._findViewportCrosshairAnnotationFromList(annotations, viewport.id)
if (!crosshairAnnotation) return false
const worldPoint = crosshairAnnotation.data?.handles?.points?.[0]
@ -314,9 +323,20 @@ class FusionJumpToPointTool extends AnnotationDisplayTool {
_getViewportCrosshairAnnotation(viewport) {
if (!viewport?.element) return null
const annotations = getAnnotations(this.getToolName(), viewport.element) || []
return annotations.find((item) =>
item?.data?.type === 'fusion-jump-crosshair' && item?.data?.viewportId === viewport.id
) || null
return this._findViewportCrosshairAnnotationFromList(annotations, viewport.id)
}
_findViewportCrosshairAnnotationFromList(annotations, viewportId) {
if (!Array.isArray(annotations) || !viewportId) return null
for (let i = 0; i < annotations.length; i++) {
const item = annotations[i]
const data = item && item.data
if (!data) continue
if (data.type === 'fusion-jump-crosshair' && data.viewportId === viewportId) {
return item
}
}
return null
}
_tryStartDrag(evt) {
@ -341,6 +361,27 @@ class FusionJumpToPointTool extends AnnotationDisplayTool {
return true
}
_getInteractionWorldPoint(viewport, currentPoints, preferCanvasToWorld = false) {
const worldPoint = currentPoints?.world
const canvasPoint = currentPoints?.canvas
if (preferCanvasToWorld && canvasPoint && viewport?.canvasToWorld) {
const worldFromCanvas = viewport.canvasToWorld(canvasPoint)
if (worldFromCanvas && worldFromCanvas.length >= 3) {
return worldFromCanvas
}
}
if (worldPoint && worldPoint.length >= 3) {
return worldPoint
}
if (canvasPoint && viewport?.canvasToWorld) {
const worldFromCanvas = viewport.canvasToWorld(canvasPoint)
if (worldFromCanvas && worldFromCanvas.length >= 3) {
return worldFromCanvas
}
}
return null
}
_dispatchPointEvent(worldPoint, sourceViewportId, crosshairAppearance) {
const { dispatchEventName } = this.configuration
if (!dispatchEventName || typeof window === 'undefined') return
@ -491,19 +532,33 @@ class FusionJumpToPointTool extends AnnotationDisplayTool {
_getReferenceLineColor(viewportId, fallbackColor) {
if (typeof this.configuration.getReferenceLineColor === 'function') {
const color = this.configuration.getReferenceLineColor(viewportId)
if (color) return color
try {
const safeViewportId = viewportId || ''
const color = this.configuration.getReferenceLineColor(safeViewportId)
if (color) return color
} catch (e) {
console.log(e)
}
}
return fallbackColor || '#6fb9ff'
}
_isMipViewportId(viewportId) {
const mipViewportIds = this.configuration?.mipViewportIds
return Array.isArray(mipViewportIds) && mipViewportIds.includes(viewportId)
}
_normalizeAppearance(appearance = {}, sourceViewportId) {
const lineWidth = Number.isFinite(appearance.lineWidth) ? appearance.lineWidth : 2
const lineLength = Number.isFinite(appearance.lineLength) ? appearance.lineLength : 9
const centerHoleSize = Number.isFinite(appearance.centerHoleSize) ? appearance.centerHoleSize : 8
let color = appearance.color
if (!color && typeof this.configuration.getReferenceLineColor === 'function') {
color = this.configuration.getReferenceLineColor(sourceViewportId)
try {
color = this.configuration.getReferenceLineColor(sourceViewportId || '')
} catch (e) {
console.log(e)
}
}
return {

View File

@ -521,7 +521,7 @@ export default {
IsImageFilter: false,
KeyFileListStr: '',
KeyFileList: [],
CircleRadius: null
CircleRadius: 10
},
rules: {
IsAutoCreate: [
@ -1063,7 +1063,7 @@ export default {
},
handleReadingToolListChange(v) {
if (!v.includes('FixedRadiusCircleROI')) {
this.form.CircleRadius = null
this.form.CircleRadius = 10
}
},
handleNumberInput(value, field) {

View File

@ -3,15 +3,15 @@
<template slot="search-container">
<el-form :inline="true">
<!-- 文件名称 -->
<el-form-item label="文件名称" prop="FileName">
<el-form-item :label="$t('trials:data-sync:fileList:fileName')" prop="FileName">
<el-input v-model="searchData.FileName" size="small" clearable style="width: 120px" />
</el-form-item>
<!-- 文件类型 -->
<el-form-item label="文件类型" prop="FileType">
<el-form-item :label="$t('trials:data-sync:fileList:fileType')" prop="FileType">
<el-input v-model="searchData.FileType" size="small" clearable style="width: 120px" />
</el-form-item>
<!-- 源区域 -->
<el-form-item label="源区域" prop="UploadRegion">
<el-form-item :label="$t('trials:data-sync:fileList:uploadRegion')" prop="UploadRegion">
<el-select v-model="searchData.UploadRegion" style="width: 120px">
<el-option
v-for="item in regionOptions"
@ -22,7 +22,7 @@
</el-select>
</el-form-item>
<!-- 源可用时间 -->
<el-form-item label="源可用时间">
<el-form-item :label="$t('trials:data-sync:fileList:uploadTimeRange')">
<el-date-picker
v-model="uploadTimeRange"
:default-time="['00:00:00', '23:59:59']"
@ -33,7 +33,7 @@
</el-date-picker>
</el-form-item>
<!-- 目标区域 -->
<el-form-item label="目标区域" prop="TargetRegion">
<el-form-item :label="$t('trials:data-sync:fileList:targetRegion')" prop="TargetRegion">
<el-select v-model="searchData.TargetRegion" style="width: 120px">
<el-option
v-for="item in regionOptions"
@ -44,7 +44,7 @@
</el-select>
</el-form-item>
<!-- 目标可用时间 -->
<el-form-item label="目标可用时间">
<el-form-item :label="$t('trials:data-sync:fileList:syncTimeRange')">
<el-date-picker
v-model="SyncTimeRange"
:default-time="['00:00:00', '23:59:59']"
@ -55,11 +55,11 @@
</el-date-picker>
</el-form-item>
<!-- 优先级 -->
<el-form-item label="优先级">
<el-form-item :label="$t('trials:data-sync:fileList:priority')">
<el-input v-model="searchData.Priority" clearable style="width: 120px"></el-input>
</el-form-item>
<!-- 是否同步完成 -->
<el-form-item label="是否同步完成" prop="IsSync">
<el-form-item :label="$t('trials:data-sync:fileList:isSync')" prop="IsSync">
<el-select v-model="searchData.IsSync" clearable style="width: 120px">
<el-option
v-for="item of $d.YesOrNo"
@ -79,7 +79,7 @@
</el-button>
<!-- 批量编辑 -->
<el-button type="primary" icon="el-icon-edit" :disabled="selectedRows.length === 0" @click="handleBatchEdit">
批量编辑
{{ $t('trials:data-sync:fileList:batchEdit') }}
</el-button>
</el-form-item>
</el-form>
@ -89,21 +89,21 @@
class="table" @sort-change="handleSortByColumn" :default-sort="{ prop: 'CreateTime', order: 'descending' }" @selection-change="handleSelectionChange">
<el-table-column type="index" width="50" />
<el-table-column type="selection" width="50" :selectable="selectableRow"/>
<el-table-column label="文件名称" prop="FileName" min-width="90" show-overflow-tooltip sortable="custom">
<el-table-column :label="$t('trials:data-sync:fileList:fileName')" prop="FileName" min-width="90" show-overflow-tooltip sortable="custom">
</el-table-column>
<el-table-column label="文件大小" prop="FileSize" min-width="90" show-overflow-tooltip>
<el-table-column :label="$t('trials:data-sync:fileList:fileSize')" prop="FileSize" min-width="90" show-overflow-tooltip>
<template slot-scope="scope">
{{ fileSizeFormatter(scope.row.FileSize) }}
</template>
</el-table-column>
<el-table-column label="文件类型" prop="FileType" min-width="90" show-overflow-tooltip sortable="custom">
<el-table-column :label="$t('trials:data-sync:fileList:fileType')" prop="FileType" min-width="90" show-overflow-tooltip sortable="custom">
</el-table-column>
<el-table-column label="源区域" prop="UploadRegion" min-width="90" show-overflow-tooltip sortable="custom" />
<el-table-column :label="$t('trials:data-sync:fileList:uploadRegion')" prop="UploadRegion" min-width="90" show-overflow-tooltip sortable="custom" />
<el-table-column label="源可用时间" prop="CreateTime" min-width="120" show-overflow-tooltip sortable="custom" />
<el-table-column label="路径" prop="Path" min-width="90" show-overflow-tooltip sortable="custom" />
<el-table-column label="是否需要同步" prop="IsNeedSync" min-width="120" show-overflow-tooltip sortable="custom">
<el-table-column :label="$t('trials:data-sync:fileList:createTime')" prop="CreateTime" min-width="120" show-overflow-tooltip sortable="custom" />
<el-table-column :label="$t('trials:data-sync:fileList:filePath')" prop="Path" min-width="90" show-overflow-tooltip sortable="custom" />
<el-table-column :label="$t('trials:data-sync:fileList:isNeedSync')" prop="IsNeedSync" min-width="120" show-overflow-tooltip sortable="custom">
<template slot-scope="scope">
<el-tag v-if="scope.row.IsNeedSync" type="success">
{{ $fd('YesOrNo', scope.row.IsNeedSync) }}
@ -113,10 +113,10 @@
</el-tag>
</template>
</el-table-column>
<el-table-column label="目标区域" prop="TargetRegion" min-width="100" show-overflow-tooltip sortable="custom" />
<el-table-column label="目标可用时间" prop="SyncFinishedTime" min-width="120" show-overflow-tooltip sortable="custom" />
<el-table-column label="优先级" prop="Priority" min-width="80" show-overflow-tooltip sortable="custom" />
<el-table-column label="是否同步完成" prop="IsSync" min-width="120" show-overflow-tooltip sortable="custom">
<el-table-column :label="$t('trials:data-sync:fileList:targetRegion')" prop="TargetRegion" min-width="100" show-overflow-tooltip sortable="custom" />
<el-table-column :label="$t('trials:data-sync:fileList:syncFinishedTime')" prop="SyncFinishedTime" min-width="120" show-overflow-tooltip sortable="custom" />
<el-table-column :label="$t('trials:data-sync:fileList:priority')" prop="Priority" min-width="80" show-overflow-tooltip sortable="custom" />
<el-table-column :label="$t('trials:data-sync:fileList:isSync')" prop="IsSync" min-width="120" show-overflow-tooltip sortable="custom">
<template slot-scope="scope">
<el-tag v-if="scope.row.IsSync" type="success">
{{ $fd('YesOrNo', scope.row.IsSync) }}
@ -126,17 +126,19 @@
</el-tag>
</template>
</el-table-column>
<el-table-column label="更新时间" prop="UpdateTime" min-width="120" show-overflow-tooltip sortable="custom" />
<el-table-column label="操作" width="240" show-overflow-tooltip fixed="right">
<el-table-column :label="$t('trials:data-sync:fileList:updateTime')" prop="UpdateTime" min-width="120" show-overflow-tooltip sortable="custom" />
<el-table-column :label="$t('common:action:action')" width="240" show-overflow-tooltip fixed="right">
<template slot-scope="scope">
<!-- 详情 -->
<el-button type="primary" size="mini" @click="handleOpenTaskTable(scope.row)">
详情
{{ $t('trials:data-sync:fileList:detail') }}
</el-button>
<!-- 重新同步 -->
<el-button type="primary" size="mini" :disabled="!scope.row.IsNeedSync || !scope.row.IsSync" @click="execute(scope.row)">
重新同步
{{ $t('trials:data-sync:fileList:reExecute') }}
</el-button>
<el-button type="primary" size="mini" :disabled="scope.row.IsSync" @click="handleEdit(scope.row)">
编辑
{{ $t('common:action:edit') }}
</el-button>
</template>
</el-table-column>
@ -145,24 +147,24 @@
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize"
@pagination="getList" />
</template>
<el-dialog v-if="editDialogVisible" title="编辑" :visible.sync="editDialogVisible" width="600px" :close-on-click-modal="false" append-to-body>
<el-dialog v-if="editDialogVisible" :title="$t('trials:data-sync:fileList:edit')" :visible.sync="editDialogVisible" width="600px" :close-on-click-modal="false" append-to-body>
<el-form ref="editFormRef" :model="editForm" :rules="editRules" label-width="110px" v-loading="formLoading">
<el-form-item label="文件名称">
<el-form-item :label="$t('trials:data-sync:fileList:fileName')">
<el-input v-model="editForm.FileName" disabled />
</el-form-item>
<el-form-item label="文件大小">
<el-form-item :label="$t('trials:data-sync:fileList:fileSize')">
<el-input :value="fileSizeFormatter(editForm.FileSize)" disabled />
</el-form-item>
<el-form-item label="文件类型">
<el-form-item :label="$t('trials:data-sync:fileList:fileType')">
<el-input v-model="editForm.FileType" disabled />
</el-form-item>
<el-form-item label="源区域">
<el-form-item :label="$t('trials:data-sync:fileList:uploadRegion')">
<el-input v-model="editForm.UploadRegion" disabled />
</el-form-item>
<el-form-item label="目标区域">
<el-form-item :label="$t('trials:data-sync:fileList:targetRegion')">
<el-input v-model="editForm.TargetRegion" disabled />
</el-form-item>
<el-form-item label="是否需要同步" prop="IsNeedSync">
<el-form-item :label="$t('trials:data-sync:fileList:isNeedSync')" prop="IsNeedSync">
<el-select v-model="editForm.IsNeedSync" style="width: 100%">
<el-option
v-for="item of $d.YesOrNo"
@ -173,16 +175,16 @@
</el-select>
</el-form-item>
<el-form-item label="更新时间">
<el-form-item :label="$t('trials:data-sync:fileList:updateTime')">
<el-input v-model="editForm.UpdateTime" disabled />
</el-form-item>
<el-form-item label="路径">
<el-form-item :label="$t('trials:data-sync:fileList:filePath')">
<el-input v-model="editForm.Path" type="textarea" :rows="2" disabled />
</el-form-item>
<el-form-item label="优先级" prop="Priority">
<el-form-item :label="$t('trials:data-sync:fileList:priority')" prop="Priority">
<el-input-number v-model="editForm.Priority" :min="0" :controls="true" style="width: 100%" />
</el-form-item>
<el-form-item label="是否同步完成" prop="IsSync">
<el-form-item :label="$t('trials:data-sync:fileList:isSync')" prop="IsSync">
<el-select v-model="editForm.IsSync" style="width: 100%" disabled>
<el-option
v-for="item of $d.YesOrNo"
@ -194,19 +196,19 @@
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="editDialogVisible = false">取消</el-button>
<el-button type="primary" @click="handleSaveEdit"></el-button>
<el-button @click="editDialogVisible = false">{{ $t('common:button:cancel') }}</el-button>
<el-button type="primary" @click="handleSaveEdit">{{ $t('common:button:save') }}</el-button>
</span>
</el-dialog>
<el-dialog v-if="batchEditDialogVisible" title="批量编辑" :visible.sync="batchEditDialogVisible" width="300px" :close-on-click-modal="false" append-to-body>
<el-dialog v-if="batchEditDialogVisible" :title="$t('trials:data-sync:fileList:batchEdit')" :visible.sync="batchEditDialogVisible" width="300px" :close-on-click-modal="false" append-to-body>
<el-form ref="batchEditFormRef" :model="batchEditForm" :rules="batchEditRules" label-width="80px" v-loading="formLoading">
<el-form-item label="优先级" prop="Priority">
<el-form-item :label="$t('trials:data-sync:fileList:priority')" prop="Priority">
<el-input-number v-model="batchEditForm.Priority" :min="0" :controls="true" style="width: 100%" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="batchEditDialogVisible = false">取消</el-button>
<el-button type="primary" @click="handleSaveBatchEdit"></el-button>
<el-button @click="batchEditDialogVisible = false">{{ $t('common:button:cancel') }}</el-button>
<el-button type="primary" @click="handleSaveBatchEdit">{{ $t('common:button:save') }}</el-button>
</span>
</el-dialog>
</BaseContainer>
@ -277,8 +279,8 @@ export default {
// IsSync: null,
},
editRules: {
Priority: [{ required: true, message: '请输入', trigger: 'change' }],
IsSync: [{ required: true, message: '请选择', trigger: 'change' }],
Priority: [{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'change' }],
IsSync: [{ required: true, message: this.$t('common:ruleMessage:select'), trigger: 'change' }],
},
formLoading: false,
selectedRows: [],
@ -287,7 +289,7 @@ export default {
Priority: null,
},
batchEditRules: {
Priority: [{ required: true, message: '请输入', trigger: 'change' }],
Priority: [{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'change' }],
},
}
},
@ -350,7 +352,7 @@ export default {
}
let res = await batchAddSyncFileTask(params)
if (res.IsSuccess) {
this.$message.success('执行成功!')
this.$message.success(this.$t('trials:data-sync:msg:executeSuccessfully'))
}
this.loading = false
this.getList()

View File

@ -3,11 +3,11 @@
<template slot="search-container">
<el-form :inline="true">
<!-- 受试者编号 -->
<el-form-item label="受试者编号" prop="SubjectCode">
<el-form-item :label="$t('trials:data-sync:studyList:subjectCode')" prop="SubjectCode">
<el-input v-model="searchData.SubjectCode" size="small" clearable style="width: 120px" />
</el-form-item>
<!-- 访视名称 -->
<el-form-item label="访视名称">
<el-form-item :label="$t('trials:data-sync:studyList:visitName')">
<el-select v-model="searchData.VisitName" style="width: 140px" clearable>
<el-option v-for="(item, index) of visitPlanOptions" :key="index" :label="item.VisitName"
:value="item.VisitNum">
@ -17,11 +17,11 @@
</el-select>
</el-form-item>
<!-- 检查编号 -->
<el-form-item label="检查编号" prop="StudyCode">
<el-form-item :label="$t('trials:data-sync:studyList:studyCode')" prop="StudyCode">
<el-input v-model="searchData.StudyCode" size="small" clearable style="width: 120px" />
</el-form-item>
<!-- 源区域 -->
<el-form-item label="源区域" prop="UploadRegion">
<el-form-item :label="$t('trials:data-sync:studyList:uploadRegion')" prop="UploadRegion">
<el-select v-model="searchData.UploadRegion" style="width: 120px">
<el-option
v-for="item in regionOptions"
@ -43,7 +43,7 @@
</el-date-picker>
</el-form-item> -->
<!-- 目标区域 -->
<el-form-item label="目标区域" prop="TargetRegion">
<el-form-item :label="$t('trials:data-sync:studyList:targetRegion')" prop="TargetRegion">
<el-select v-model="searchData.TargetRegion" style="width: 120px">
<el-option
v-for="item in regionOptions"
@ -65,7 +65,7 @@
</el-date-picker>
</el-form-item> -->
<!-- 是否同步完成 -->
<el-form-item label="是否同步完成" prop="IsSync">
<el-form-item :label="$t('trials:data-sync:studyList:visitName')" prop="IsSync">
<el-select v-model="searchData.IsSync" clearable style="width: 120px">
<el-option
v-for="item of $d.YesOrNo"
@ -90,15 +90,15 @@
<el-table v-loading="loading" v-adaptive="{ bottomOffset: 60 }" height="100" :data="list"
class="table" @sort-change="handleSortByColumn" :default-sort="{ prop: 'CreateTime', order: 'descending' }">
<el-table-column type="index" width="50" />
<el-table-column label="受试者编号" prop="SubjectCode" min-width="90" show-overflow-tooltip sortable="custom"/>
<el-table-column label="访视名称" prop="VisitName" min-width="90" show-overflow-tooltip sortable="custom"/>
<el-table-column label="检查编号" prop="StudyCode" min-width="90" show-overflow-tooltip sortable="custom"/>
<el-table-column label="文件数" prop="FileCount" min-width="90" show-overflow-tooltip/>
<el-table-column label="源区域" prop="UploadRegion" min-width="60" show-overflow-tooltip />
<el-table-column label="源可用时间" prop="CreateTime" min-width="90" show-overflow-tooltip />
<el-table-column label="目标区域" prop="TargetRegion" min-width="60" show-overflow-tooltip />
<el-table-column label="目标可用时间" prop="SyncFinishedTime" min-width="90" show-overflow-tooltip/>
<el-table-column label="是否同步完成" prop="IsSync" min-width="90" show-overflow-tooltip sortable="custom">
<el-table-column :label="$t('trials:data-sync:studyList:subjectCode')" prop="SubjectCode" min-width="90" show-overflow-tooltip sortable="custom"/>
<el-table-column :label="$t('trials:data-sync:studyList:visitName')" prop="VisitName" min-width="90" show-overflow-tooltip sortable="custom"/>
<el-table-column :label="$t('trials:data-sync:studyList:studyCode')" prop="StudyCode" min-width="90" show-overflow-tooltip sortable="custom"/>
<el-table-column :label="$t('trials:data-sync:studyList:fileCount')" prop="FileCount" min-width="90" show-overflow-tooltip/>
<el-table-column :label="$t('trials:data-sync:studyList:uploadRegion')" prop="UploadRegion" min-width="60" show-overflow-tooltip />
<el-table-column :label="$t('trials:data-sync:studyList:createTime')" prop="CreateTime" min-width="90" show-overflow-tooltip />
<el-table-column :label="$t('trials:data-sync:studyList:targetRegion')" prop="TargetRegion" min-width="60" show-overflow-tooltip />
<el-table-column :label="$t('trials:data-sync:studyList:syncFinishedTime')" prop="SyncFinishedTime" min-width="90" show-overflow-tooltip/>
<el-table-column :label="$t('trials:data-sync:studyList:isSync')" prop="IsSync" min-width="90" show-overflow-tooltip sortable="custom">
<template slot-scope="scope">
<el-tag v-if="scope.row.IsSync" type="success">
{{ $fd('YesOrNo', scope.row.IsSync) }}
@ -108,10 +108,11 @@
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" min-width="80" show-overflow-tooltip>
<el-table-column :label="$t('common:action:action')" min-width="80" show-overflow-tooltip>
<template slot-scope="scope">
<!-- 详情 -->
<el-button type="primary" size="small" @click="openDetailTable(scope.row)">
详情
{{ $t('trials:data-sync:studyList:detail') }}
</el-button>
</template>
</el-table-column>
@ -129,9 +130,11 @@
class="detail-dialog"
>
<span slot="title">{{ detailDialog.title }}</span>
<span v-if="detailDialog.currentRow">{{`${detailDialog.currentRow.SubjectCode} / ${detailDialog.currentRow.VisitName} ${detailDialog.currentRow.StudyCode ? ' / ' + detailDialog.currentRow.StudyCode : ''} ${detailDialog.currentRow.UploadRegion} -> 目标${detailDialog.currentRow.TargetRegion}`}}</span>
<!-- ${detailDialog.currentRow.UploadRegion} -> 目标${detailDialog.currentRow.TargetRegion} -->
<span v-if="detailDialog.currentRow">{{`${detailDialog.currentRow.SubjectCode} / ${detailDialog.currentRow.VisitName} ${detailDialog.currentRow.StudyCode ? ' / ' + detailDialog.currentRow.StudyCode : ''} ${$t('trials:data-sync:studyList:msg1').replace('xxx', detailDialog.currentRow.UploadRegion).replace('yyy', detailDialog.currentRow.TargetRegion)}`}}</span>
<el-tabs class="detail-tabs" v-model="detailDialog.activeTab" @tab-click="handleDetailTabClick">
<el-tab-pane label="文件级别" name="file">
<!-- 文件级别 -->
<el-tab-pane :label="$t('trials:data-sync:label:fileList')" name="file">
<FileList
v-if="detailDialog.activeTab === 'file'"
:dataFileType="1"
@ -139,7 +142,8 @@
@openTaskTable="openTaskTable"
/>
</el-tab-pane>
<el-tab-pane label="任务级别" name="task">
<!-- 任务级别 -->
<el-tab-pane :label="$t('trials:data-sync:label:taskList')" name="task">
<TaskList
v-if="detailDialog.activeTab === 'task'"
:rowInfo="detailDialog.currentRow"
@ -191,7 +195,7 @@ export default {
visitPlanOptions: [],
detailDialog: {
visible: false,
title: '详情',
title: this.$t('trials:data-sync:studyList:detail'),
activeTab: 'file',
currentRow: null
},

View File

@ -3,15 +3,15 @@
<template slot="search-container">
<el-form :inline="true">
<!-- 文件名称 -->
<el-form-item label="文件名称" prop="FileName">
<el-form-item :label="$t('trials:data-sync:table:fileName')" prop="FileName">
<el-input v-model="searchData.FileName" size="small" clearable style="width: 120px" />
</el-form-item>
<!-- 文件路径 -->
<el-form-item label="文件路径" prop="Path">
<el-form-item :label="$t('trials:data-sync:table:filePath')" prop="Path">
<el-input v-model="searchData.Path" size="small" clearable />
</el-form-item>
<!-- 任务状态 -->
<el-form-item label="任务状态" prop="JobState">
<el-form-item :label="$t('trials:data-sync:table:jobState')" prop="JobState">
<el-select v-model="searchData.JobState" clearable style="width: 120px">
<el-option
v-for="item of $d.JobState"
@ -22,7 +22,7 @@
</el-select>
</el-form-item>
<!-- 任务开始日期 -->
<el-form-item label="任务开始日期">
<el-form-item :label="$t('trials:data-sync:table:startTime')">
<el-date-picker
v-model="searchData.StartTime"
type="date"
@ -33,7 +33,7 @@
/>
</el-form-item>
<!-- 任务结束日期 -->
<el-form-item label="任务结束日期">
<el-form-item :label="$t('trials:data-sync:table:endTime')">
<el-date-picker
v-model="searchData.EndTime"
type="date"
@ -58,11 +58,11 @@
<el-table v-loading="loading" v-adaptive="{ bottomOffset: 70 }" height="100" :data="list"
class="table" @sort-change="handleSortByColumn" :default-sort="{ prop: 'CreateTime', order: 'descending' }">
<el-table-column type="index" width="50" />
<el-table-column label="Job编号" prop="Id" min-width="90" show-overflow-tooltip/>
<el-table-column label="文件名称" prop="FileName" min-width="90" show-overflow-tooltip sortable="custom">
<el-table-column :label="$t('trials:data-sync:table:jobCode')" prop="Id" min-width="90" show-overflow-tooltip/>
<el-table-column :label="$t('trials:data-sync:table:fileName')" prop="FileName" min-width="90" show-overflow-tooltip sortable="custom">
</el-table-column>
<el-table-column label="路径" prop="Path" min-width="90" show-overflow-tooltip/>
<el-table-column label="任务状态" prop="JobState" min-width="90" show-overflow-tooltip sortable="custom">
<el-table-column :label="$t('trials:data-sync:table:filePath')" prop="Path" min-width="90" show-overflow-tooltip/>
<el-table-column :label="$t('trials:data-sync:table:jobState')" prop="JobState" min-width="90" show-overflow-tooltip sortable="custom">
<template slot-scope="scope">
<el-tag v-if="scope.row.JobState === 1" type="infoinf0">
{{ $fd('JobState', scope.row.JobState) }}
@ -79,15 +79,16 @@
<el-tag v-else>{{ $fd('JobState', scope.row.JobState) }}</el-tag>
</template>
</el-table-column>
<el-table-column label="任务开始时间" prop="StartTime" min-width="90" show-overflow-tooltip sortable="custom" />
<el-table-column label="任务结束时间" prop="EndTime" min-width="90" show-overflow-tooltip sortable="custom" />
<el-table-column label="创建时间" prop="CreateTime" min-width="90" show-overflow-tooltip sortable="custom" />
<el-table-column :label="$t('trials:data-sync:table:startTime')" prop="StartTime" min-width="90" show-overflow-tooltip sortable="custom" />
<el-table-column :label="$t('trials:data-sync:table:endTime')" prop="EndTime" min-width="90" show-overflow-tooltip sortable="custom" />
<el-table-column :label="$t('trials:data-sync:table:createTime')" prop="CreateTime" min-width="90" show-overflow-tooltip sortable="custom" />
<el-table-column label="操作" min-width="80" show-overflow-tooltip>
<el-table-column :label="$t('common:action:action')" min-width="80" show-overflow-tooltip>
<template slot-scope="scope">
<!-- 再次执行 -->
<el-button type="primary" size="mini" :disabled="scope.row.JobState !== 3" @click="execute(scope.row)">
再次执行
{{ $t('trials:data-sync:button:execute') }}
</el-button>
</template>
</el-table-column>
@ -201,7 +202,7 @@ export default {
}
let res = await batchAddSyncFileTask(params)
if (res.IsSuccess) {
this.$message.success('执行成功!')
this.$message.success(this.$t('trials:data-sync:msg:executeSuccessfully')) //''
}
this.loading = false

View File

@ -1,20 +1,22 @@
<template>
<el-tabs class="data-sync-tabs" type="border-card" tab-position="left" v-model="activeTab" >
<el-tab-pane label="检查列表" name="study">
<!-- 检查列表 -->
<el-tab-pane :label="$t('trials:data-sync:label:studyList')" name="study">
<StudyList v-if="activeTab === 'study'"/>
</el-tab-pane>
<el-tab-pane label="其他" name="other">
<!-- <FileList v-if="activeTab === 'other'" :dataFileType="2" @openTaskTable="openTaskTable"/> -->
<!-- 其他 -->
<el-tab-pane :label="$t('trials:data-sync:label:otherList')" name="other">
<el-tabs v-if="activeTab === 'other'" class="detail-tabs" v-model="tabInfo.activeTab" @tab-click="handleDetailTabClick">
<el-tab-pane label="文件级别" name="file">
<!-- v-if="tabInfo.activeTab === 'file'" -->
<!-- 文件级别 -->
<el-tab-pane :label="$t('trials:data-sync:label:fileList')" name="file">
<FileList
v-if="tabInfo.activeTab === 'file'"
:dataFileType="2"
@openTaskTable="openTaskTable"
/>
</el-tab-pane>
<el-tab-pane label="任务级别" name="task">
<!-- 任务级别 -->
<el-tab-pane :label="$t('trials:data-sync:label:taskList')" name="task">
<TaskList
v-if="tabInfo.activeTab === 'task'"
:rowInfo="tabInfo.currentRow"
@ -24,22 +26,6 @@
</el-tab-pane>
</el-tabs>
</el-tab-pane>
<!-- <el-dialog
v-if="detailDialog.visible"
:visible.sync="detailDialog.visible"
fullscreen
append-to-body
:close-on-click-modal="false"
class="detail-dialog"
>
<span slot="title">{{ detailDialog.title }}</span>
<span v-if="detailDialog.currentRow">{{`${detailDialog.currentRow.SubjectCode} / ${detailDialog.currentRow.VisitName} ${detailDialog.currentRow.StudyCode ? ' / ' + detailDialog.currentRow.StudyCode : ''} ${detailDialog.currentRow.UploadRegion} -> 目标${detailDialog.currentRow.TargetRegion}`}}</span>
<TaskList
:rowInfo="detailDialog.currentRow"
:fileUploadRecordId="detailDialog.currentRow.Id"
:path="detailDialog.currentRow.Path"
/>
</el-dialog> -->
</el-tabs>
</template>
<script>
@ -57,7 +43,6 @@ export default {
return {
activeTab: 'study',
tabInfo: {
title: '详情',
activeTab: 'file',
currentRow: null
},