29 Commits

Author SHA1 Message Date
wangxiaoshuang 2c0823f027 阅片表单数值问题可输入NE
continuous-integration/drone/push Build encountered an error
2025-06-25 09:15:09 +08:00
wangxiaoshuang 44b10255dd IVUS和OCT表单修改,新增靶段
continuous-integration/drone/push Build encountered an error
2025-06-19 17:47:10 +08:00
wangxiaoshuang a14aefca2c 上传影像文件统计问题
continuous-integration/drone/push Build encountered an error
2025-06-18 13:33:39 +08:00
wangxiaoshuang 334882cc68 阅片下载压缩包名称修改 2025-06-18 13:30:36 +08:00
wangxiaoshuang d8315fbfff 阅片上传下载按钮添加
continuous-integration/drone/push Build encountered an error
2025-06-18 09:55:16 +08:00
wangxiaoshuang 1022fa2888 阅片顺序添加admin角色权限
continuous-integration/drone/push Build encountered an error
2025-06-17 16:49:15 +08:00
wangxiaoshuang 48633a1ed4 阅片顺序手动修改添加限制条件
continuous-integration/drone/push Build encountered an error
2025-06-16 17:24:14 +08:00
wangxiaoshuang 108d01f81c 阅片顺序默认排序、阅片中禁用
continuous-integration/drone/push Build encountered an error
2025-06-16 16:05:49 +08:00
wangxiaoshuang 12e4128b7b 提交裁判阅片结果详情oldValue改为--
continuous-integration/drone/push Build encountered an error
2025-06-13 16:49:50 +08:00
wangxiaoshuang b512112d96 肿瘤学阅片查看屏蔽跳过按钮
continuous-integration/drone/push Build encountered an error
2025-06-13 14:33:55 +08:00
wangxiaoshuang a7251ce65c 阅片顺序
continuous-integration/drone/push Build encountered an error
2025-06-13 14:17:58 +08:00
wangxiaoshuang 7e2ff6de1b 稽查图片不存在展示问题
continuous-integration/drone/push Build encountered an error
2025-06-12 16:23:44 +08:00
caiyiling a66e15eb39 MRI-PDFF测量逻辑更改
continuous-integration/drone/push Build encountered an error
2025-06-04 16:25:48 +08:00
caiyiling 895e3a6bed MRI-PDFF更改
continuous-integration/drone/push Build encountered an error
2025-06-04 13:35:42 +08:00
caiyiling 9dddc0c012 MRI-PDFF测量逻辑更改
continuous-integration/drone/push Build encountered an error
2025-06-04 10:53:45 +08:00
caiyiling a965f08a1e MRI-PDFF标准更改
continuous-integration/drone/push Build encountered an error
2025-06-04 09:24:41 +08:00
caiyiling 9962b1a829 反色bug修复
continuous-integration/drone/push Build encountered an error
2025-05-28 18:46:53 +08:00
caiyiling 049128b90e 添加阅片完成支持添加临时标注(历史标注不允许更改)功能及阅片页面双击放大缺陷修复
continuous-integration/drone/push Build encountered an error
2025-05-28 15:44:38 +08:00
wangxiaoshuang 45e6a20988 Merge branch 'uat'
continuous-integration/drone/push Build encountered an error
# Conflicts:
#	src/utils/metaDataProvider.js
2025-05-26 12:30:44 +08:00
wangxiaoshuang 5141eb5cbd 发布配置修改
continuous-integration/drone/push Build is passing
2025-05-23 18:12:49 +08:00
wangxiaoshuang 073b06a76f 1
continuous-integration/drone/push Build is passing
2025-05-23 17:10:45 +08:00
wangxiaoshuang 20723e8d2c 1
continuous-integration/drone/push Build is passing
2025-05-23 16:25:30 +08:00
wangxiaoshuang fba00157a1 crc一致性核查回复弹窗添加取消按钮
continuous-integration/drone/push Build is passing
2025-05-23 16:06:12 +08:00
wangxiaoshuang f0e6708533 1
continuous-integration/drone/push Build is passing
2025-05-23 15:24:49 +08:00
wangxiaoshuang e770dc1078 1 2025-05-23 15:24:07 +08:00
wangxiaoshuang e0321bae72 影像预览问题解决
continuous-integration/drone/push Build encountered an error
2025-04-12 12:04:20 +08:00
wangxiaoshuang 1e720e399d 确认收入项,修改选项后,其他文件也改了
continuous-integration/drone/push Build encountered an error
2025-04-03 11:15:54 +08:00
wangxiaoshuang 1368397da9 项目总览—>上传记录:中心编号 查询条件,查询结果不对 2025-04-03 11:15:36 +08:00
wangxiaoshuang c8c049b5d0 DICOM影像中,存在Tag最大像素值、最小像素值等,但是和实际的数据统计结果不同 2025-04-03 11:15:22 +08:00
31 changed files with 1385 additions and 638 deletions
+8
View File
@@ -480,3 +480,11 @@ export function resetReadingRestTime() {
method: 'post'
})
}
// 设置随机排序
export function setRandomTaskOrder(data) {
return request({
url: `/VisitTask/setRandomTaskOrder`,
method: 'post',
data
})
}
@@ -1,39 +1,19 @@
<template>
<el-dialog
:visible.sync="visible"
:fullscreen="true"
:close-on-click-modal="false"
:before-close="beforeClose"
:append-to-body="true"
v-loading="btnLoading"
class="downloadDicomAndNonedicom"
>
<el-dialog :visible.sync="visible" :fullscreen="true" :close-on-click-modal="false" :before-close="beforeClose"
:append-to-body="true" v-loading="btnLoading" class="downloadDicomAndNonedicom">
<span slot="title">{{ title }}</span>
<div class="top">
<span>{{ $t('download:top:title') }}</span>
<div class="btnBox">
<el-button
type="primary"
size="mini"
v-if="hasDicom"
@click.stop="getIRReadingDownloadStudyInfo('dicom')"
>
<el-button type="primary" size="mini" v-if="hasDicom" @click.stop="getIRReadingDownloadStudyInfo('dicom')">
{{ $t('download:button:downloadDicom') }}
</el-button>
<el-button
type="primary"
size="mini"
v-if="hasNonedicom"
@click.stop="getIRReadingDownloadStudyInfo('noneDicom')"
>
<el-button type="primary" size="mini" v-if="hasNonedicom"
@click.stop="getIRReadingDownloadStudyInfo('noneDicom')">
{{ $t('download:button:downloadNonedicom') }}
</el-button>
<el-button
type="primary"
size="mini"
v-if="hasDicom || hasNonedicom"
@click.stop="getIRReadingDownloadStudyInfo('all')"
>
<el-button type="primary" size="mini" v-if="hasDicom || hasNonedicom"
@click.stop="getIRReadingDownloadStudyInfo('all')">
{{ $t('download:button:downloadAll') }}
</el-button>
</div>
@@ -43,16 +23,9 @@
<div v-html="$t('download:tip:message')"></div>
</div>
<!--上传列表@selection-change="handleSelectionChange"-->
<el-table
ref="dicomFilesTable"
v-adaptive="{ bottomOffset: 85 }"
height="100"
:data="list"
:loading="loading"
class="dicomFiles-table"
@sort-change="handleSortByColumn"
:default-sort="{ prop: 'TaskBlindName', order: 'descending' }"
>
<el-table ref="dicomFilesTable" v-adaptive="{ bottomOffset: 85 }" height="100" :data="list" :loading="loading"
class="dicomFiles-table" @sort-change="handleSortByColumn"
:default-sort="{ prop: 'TaskBlindName', order: 'descending' }">
<!-- <el-table-column
type="selection"
width="55"
@@ -60,50 +33,28 @@
/> -->
<el-table-column type="index" width="40" />
<!--受试者-->
<el-table-column
:label="$t('download:table:subjectCode')"
min-width="130"
prop="SubjectCode"
show-overflow-tooltip
/>
<el-table-column :label="$t('download:table:subjectCode')" min-width="130" prop="SubjectCode"
show-overflow-tooltip />
<!--任务名称-->
<el-table-column
:label="$t('download:table:taskName')"
min-width="130"
show-overflow-tooltip
prop="TaskBlindName"
sortable="custom"
/>
<el-table-column :label="$t('download:table:taskName')" min-width="130" show-overflow-tooltip prop="TaskBlindName"
sortable="custom" />
<!--检查类型-->
<el-table-column
:label="$t('download:table:studyType')"
min-width="130"
show-overflow-tooltip
prop="IsDicom"
sortable="custom"
>
<el-table-column :label="$t('download:table:studyType')" min-width="130" show-overflow-tooltip prop="IsDicom"
sortable="custom">
<template slot-scope="scope">
<span>{{ $fd('IsDicom', scope.row.IsDicom) }}</span>
</template>
</el-table-column>
<el-table-column
:label="$t('download:table:orginalStudyListNum')"
min-width="150"
show-overflow-tooltip
>
<el-table-column :label="$t('download:table:orginalStudyListNum')" min-width="150" show-overflow-tooltip>
<template slot-scope="scope">
<el-button
v-if="
(scope.row.IsDicom &&
scope.row.DicomStudyList &&
scope.row.DicomStudyList.length >= 1) ||
(!scope.row.IsDicom &&
scope.row.NoneDicomStudyList &&
scope.row.NoneDicomStudyList.length >= 1)
"
type="text"
@click="handleOpenDialog(scope.row)"
>
<el-button v-if="
(scope.row.IsDicom &&
scope.row.DicomStudyList &&
scope.row.DicomStudyList.length >= 1) ||
(!scope.row.IsDicom &&
scope.row.NoneDicomStudyList &&
scope.row.NoneDicomStudyList.length >= 1)
" type="text" @click="handleOpenDialog(scope.row)">
<span>{{
scope.row.IsDicom
? scope.row.DicomStudyList.length
@@ -113,37 +64,19 @@
<span v-else>0</span>
</template>
</el-table-column>
<el-table-column
:label="$t('common:action:action')"
fixed="right"
width="150"
>
<el-table-column :label="$t('common:action:action')" fixed="right" width="150">
<template slot-scope="scope">
<!--预览--->
<el-button
circle
icon="el-icon-view"
:title="$t('download:button:preview')"
@click.stop="preview(scope.row)"
/>
<el-button circle icon="el-icon-view" :title="$t('download:button:preview')"
@click.stop="preview(scope.row)" />
<!--下载--->
<el-button
circle
icon="el-icon-download"
:title="$t('download:button:download')"
@click.stop="getIRReadingDownloadStudyInfo('one', scope.row)"
/>
<el-button circle icon="el-icon-download" :title="$t('download:button:download')"
@click.stop="getIRReadingDownloadStudyInfo('one', scope.row)" />
</template>
</el-table-column>
</el-table>
<study-view
v-if="model_cfg.visible"
:model_cfg="model_cfg"
:modelList="modelList"
:bodyPart="bodyPart"
:IsDicom="IsDicom"
:visitTaskId="modelTaskId"
/>
<study-view v-if="model_cfg.visible" :model_cfg="model_cfg" :modelList="modelList" :bodyPart="bodyPart"
:IsDicom="IsDicom" :visitTaskId="modelTaskId" />
</el-dialog>
</template>
<script>
@@ -358,7 +291,8 @@ export default {
name = `${list[0].SubjectCode}_${list[0].TaskBlindName}.zip`
}
if (this.IsReadingTaskViewInOrder === 0) {
name = `${list[0].TaskBlindName}.zip`
// name = `${list[0].TaskBlindName}.zip`
name = `${list[0].SubjectCode}_${list[0].TaskBlindName}.zip`
}
list.forEach((data) => {
if (data.StudyList && data.StudyList.length > 0) {
@@ -370,11 +304,9 @@ export default {
series.InstancePathList.forEach((instance) => {
let fileName = instance.Path.split('/').pop()
let obj = {
name: `${data.SubjectCode}/${
data.TaskBlindName
}/${this.$fd('IsDicom', true)}/${
study.StudyCode
}/${fileName}`,
name: `${data.SubjectCode}/${data.TaskBlindName
}/${this.$fd('IsDicom', true)}/${study.StudyCode
}/${fileName}`,
url: this.OSSclientConfig.basePath + instance.Path,
}
if (this.IsReadingTaskViewInOrder === 0) {
@@ -500,10 +432,12 @@ export default {
justify-content: space-between;
margin: 10px 0;
}
.tip {
display: flex;
align-items: flex-start;
margin-top: 5px;
i {
margin: 3px 5px 0 0;
}
@@ -936,19 +936,19 @@ export default {
) {
++instanceIndex
}
if (instanceIndex >= fileList.length) {
fileList.push({
instanceUid: instanceUid,
file: file,
})
}
scope.uploadQueues[studyIndex].dicomInfo.fileCount = fileList.length
scope.uploadQueues[studyIndex].dicomInfo.fileSize = fileList.reduce(
(prev, next) => {
return prev + next.file.size
},
0
)
// if (instanceIndex >= fileList.length) {
// fileList.push({
// instanceUid: instanceUid,
// file: file,
// })
// }
// scope.uploadQueues[studyIndex].dicomInfo.fileCount = fileList.length
// scope.uploadQueues[studyIndex].dicomInfo.fileSize = fileList.reduce(
// (prev, next) => {
// return prev + next.file.size
// },
// 0
// )
var seriesUid = data.string('x0020000e')
var seriesList = scope.uploadQueues[studyIndex].seriesList
@@ -1046,6 +1046,19 @@ export default {
}
instanceList.push(instanceItem)
}
if (instanceIndex >= fileList.length) {
fileList.push({
instanceUid: instanceUid,
file: file,
})
}
scope.uploadQueues[studyIndex].dicomInfo.fileCount = fileList.length
scope.uploadQueues[studyIndex].dicomInfo.fileSize = fileList.reduce(
(prev, next) => {
return prev + next.file.size
},
0
)
resolve()
} catch (error) {
console.log(error)
+6
View File
@@ -61,6 +61,12 @@ export const constantRoutes = [
name: 'Resetpassword',
hidden: true
},
{
path: '/trials/trials-panel/reading/readingTracking/ReadOrder',
component: () => import('@/views/trials/trials-panel/reading/read-order/index'),
name: 'ReadOrder',
hidden: true
},
{
path: '/recompose',
component: () => import('@/views/recompose/index'),
+137 -10
View File
@@ -39,6 +39,108 @@ function getNumberValues(dataSet, tag, minimumLength) {
return values;
}
function getLutDescriptor(dataSet, tag) {
if (!dataSet.elements[tag] || dataSet.elements[tag].length !== 6) {
return;
}
return [
dataSet.uint16(tag, 0),
dataSet.uint16(tag, 1),
dataSet.uint16(tag, 2),
];
}
function getLutData(lutDataSet, tag, lutDescriptor) {
const lut = [];
const lutData = lutDataSet.elements[tag];
for (let i = 0; i < lutDescriptor[0]; i++) {
// Output range is always unsigned
if (lutDescriptor[2] === 16) {
lut[i] = lutDataSet.uint16(tag, i);
} else {
lut[i] = lutDataSet.byteArray[i + lutData.dataOffset];
}
}
return lut;
}
function populateSmallestLargestPixelValues(dataSet, imagePixelModule) {
const pixelRepresentation = dataSet.uint16('x00280103');
if (pixelRepresentation === 0) {
imagePixelModule.smallestPixelValue = dataSet.uint16('x00280106');
imagePixelModule.largestPixelValue = dataSet.uint16('x00280107');
} else {
imagePixelModule.smallestPixelValue = dataSet.int16('x00280106');
imagePixelModule.largestPixelValue = dataSet.int16('x00280107');
}
imagePixelModule.largestPixelValue = imagePixelModule.largestPixelValue === 0 ? undefined : imagePixelModule.largestPixelValue;
}
function populatePaletteColorLut(dataSet, imagePixelModule) {
imagePixelModule.redPaletteColorLookupTableDescriptor = getLutDescriptor(
dataSet,
'x00281101'
);
imagePixelModule.greenPaletteColorLookupTableDescriptor = getLutDescriptor(
dataSet,
'x00281102'
);
imagePixelModule.bluePaletteColorLookupTableDescriptor = getLutDescriptor(
dataSet,
'x00281103'
);
// The first Palette Color Lookup Table Descriptor value is the number of entries in the lookup table.
// When the number of table entries is equal to 2ˆ16 then this value shall be 0.
// See http://dicom.nema.org/MEDICAL/DICOM/current/output/chtml/part03/sect_C.7.6.3.html#sect_C.7.6.3.1.5
if (imagePixelModule.redPaletteColorLookupTableDescriptor[0] === 0) {
imagePixelModule.redPaletteColorLookupTableDescriptor[0] = 65536;
imagePixelModule.greenPaletteColorLookupTableDescriptor[0] = 65536;
imagePixelModule.bluePaletteColorLookupTableDescriptor[0] = 65536;
}
// The third Palette Color Lookup Table Descriptor value specifies the number of bits for each entry in the Lookup Table Data.
// It shall take the value of 8 or 16.
// The LUT Data shall be stored in a format equivalent to 8 bits allocated when the number of bits for each entry is 8, and 16 bits allocated when the number of bits for each entry is 16, where in both cases the high bit is equal to bits allocated-1.
// The third value shall be identical for each of the Red, Green and Blue Palette Color Lookup Table Descriptors.
//
// Note: Some implementations have encoded 8 bit entries with 16 bits allocated, padding the high bits;
// this can be detected by comparing the number of entries specified in the LUT Descriptor with the actual value length of the LUT Data entry.
// The value length in bytes should equal the number of entries if bits allocated is 8, and be twice as long if bits allocated is 16.
const numLutEntries =
imagePixelModule.redPaletteColorLookupTableDescriptor[0];
const lutData = dataSet.elements.x00281201;
const lutBitsAllocated = lutData.length === numLutEntries ? 8 : 16;
// If the descriptors do not appear to have the correct values, correct them
if (
imagePixelModule.redPaletteColorLookupTableDescriptor[2] !==
lutBitsAllocated
) {
imagePixelModule.redPaletteColorLookupTableDescriptor[2] = lutBitsAllocated;
imagePixelModule.greenPaletteColorLookupTableDescriptor[2] =
lutBitsAllocated;
imagePixelModule.bluePaletteColorLookupTableDescriptor[2] =
lutBitsAllocated;
}
imagePixelModule.redPaletteColorLookupTableData = getLutData(
dataSet,
'x00281201',
imagePixelModule.redPaletteColorLookupTableDescriptor
);
imagePixelModule.greenPaletteColorLookupTableData = getLutData(
dataSet,
'x00281202',
imagePixelModule.greenPaletteColorLookupTableDescriptor
);
imagePixelModule.bluePaletteColorLookupTableData = getLutData(
dataSet,
'x00281203',
imagePixelModule.bluePaletteColorLookupTableDescriptor
);
}
function metaDataProvider(type, imageId) {
const parsedImageId = parseImageId(imageId);
const dataSet = cornerstoneWADOImageLoader.wadouri.dataSetCacheManager.get(parsedImageId.url);
@@ -100,7 +202,7 @@ function metaDataProvider(type, imageId) {
};
}
if (type === 'imagePixelModule') {
return {
const imagePixelModule = {
samplesPerPixel: dataSet.uint16('x00280002'),
photometricInterpretation: dataSet.string('x00280004'),
rows: dataSet.uint16('x00280010'),
@@ -110,16 +212,41 @@ function metaDataProvider(type, imageId) {
highBit: dataSet.uint16('x00280102'),
pixelRepresentation: dataSet.uint16('x00280103'),
planarConfiguration: dataSet.uint16('x00280006'),
pixelAspectRatio: dataSet.uint16('x00280034'),
smallestPixelValue: null,
largestPixelValue: null,
redPaletteColorLookupTableDescriptor: dataSet.string('x00281101'),
greenPaletteColorLookupTableDescriptor: dataSet.string('x00281102'),
bluePaletteColorLookupTableDescriptor: dataSet.string('x00281103'),
redPaletteColorLookupTableData: dataSet.string('x00281201'),
greenPaletteColorLookupTableData: dataSet.string('x00281202'),
bluePaletteColorLookupTableData: dataSet.string('x00281203')
pixelAspectRatio: dataSet.string('x00280034'),
};
populateSmallestLargestPixelValues(dataSet, imagePixelModule);
if (
imagePixelModule.photometricInterpretation === 'PALETTE COLOR' &&
dataSet.elements.x00281101
) {
populatePaletteColorLut(dataSet, imagePixelModule);
}
return imagePixelModule;
}
// if (type === 'imagePixelModule') {
// return {
// samplesPerPixel: dataSet.uint16('x00280002'),
// photometricInterpretation: dataSet.string('x00280004'),
// rows: dataSet.uint16('x00280010'),
// columns: dataSet.uint16('x00280011'),
// bitsAllocated: dataSet.uint16('x00280100'),
// bitsStored: dataSet.uint16('x00280101'),
// highBit: dataSet.uint16('x00280102'),
// pixelRepresentation: dataSet.uint16('x00280103'),
// planarConfiguration: dataSet.uint16('x00280006'),
// pixelAspectRatio: dataSet.uint16('x00280034'),
// smallestPixelValue: null,
// largestPixelValue: null,
// // smallestPixelValue: dataSet.uint16('x00280106'),
// // largestPixelValue: dataSet.uint16('x00280107'),
// redPaletteColorLookupTableDescriptor: dataSet.string('x00281101'),
// greenPaletteColorLookupTableDescriptor: dataSet.string('x00281102'),
// bluePaletteColorLookupTableDescriptor: dataSet.string('x00281103'),
// redPaletteColorLookupTableData: dataSet.string('x00281201'),
// greenPaletteColorLookupTableData: dataSet.string('x00281202'),
// bluePaletteColorLookupTableData: dataSet.string('x00281203')
// }
// }
}
export default metaDataProvider;
@@ -124,7 +124,7 @@
<el-table-column prop="Name" :label="$t('trials:signRecords:table:fileName')" show-overflow-tooltip
sortable="custom" />
<el-table-column :label="$t('trials:signRecords:table:AttachmentCount')" prop="AttachmentCount"
show-overflow-tooltip sortable="custom">
show-overflow-tooltip>
<template slot-scope="scope">
<el-button type="text" @click.stop="openAttachment(scope.row, true)">{{ scope.row.AttachmentCount
}}</el-button>
@@ -263,7 +263,7 @@ export default {
series: '',
ToolStateManager: null,
renderedMeasured: [],
measuredTools: ['Length', 'Bidirectional', 'ArrowAnnotate', 'RectangleRoi'],
measuredTools: ['Length', 'Bidirectional', 'ArrowAnnotate', 'RectangleRoi', 'Probe'],
measureData: [],
selectedLesion: null,
activeTool: 0, // 0:enable 1:passive 2:active
@@ -303,8 +303,8 @@ export default {
],
scrollSyncInfo: { offset: 0 },
hideMeasureArr: []
hideMeasureArr: [],
isInitWwwc: true
}
},
computed: {
@@ -565,7 +565,6 @@ export default {
e.stopPropagation()
e.preventDefault()
} else if (this.activeToolName === 'Length' || this.activeToolName === 'Bidirectional' && this.readingTaskState < 2) {
console.log(e.detail.image)
if (!e.detail.image.columnPixelSpacing || !e.detail.image.rowPixelSpacing) {
// '该影像不具备测量长度所需的必要数据,不能进行长度测量。请选择其他工具进行标注。'
this.$confirm(this.$t('trials:reading:warnning:msg56'), '', {
@@ -578,6 +577,13 @@ export default {
e.stopPropagation()
e.preventDefault()
}
} else if (this.CriterionType === 21 && 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) {
@@ -607,7 +613,11 @@ export default {
if ((i.LesionType === 0 || i.LesionType === 1 || i.LesionType === 7) && i.IsFirstChangeTask) {
arr.push(i.OrderMarkName)
}
if (i.Id && this.readingTaskState >= 2) {
arr.push(i.OrderMarkName)
}
})
console.log(arr)
return arr
},
getMergeMarks(measureDatas) {
@@ -616,6 +626,9 @@ export default {
if ((i.LesionType === 0) && i.SplitOrMergeType === 1) {
arr.push(i.OrderMarkName)
}
if (i.Id && this.readingTaskState >= 2) {
arr.push(i.OrderMarkName)
}
})
return arr
},
@@ -661,7 +674,7 @@ export default {
},
sliderMousemove(e) {
if (!this.sliderInfo.isMove) return
console.log('sliderMousemove')
// console.log('sliderMousemove')
var PX = this.sliderInfo.oldB - (this.sliderInfo.oldM - e.clientY)
var boxHeight = this.$refs['sliderBox'].clientHeight
if (PX < 0) return
@@ -692,7 +705,7 @@ export default {
} else if (criterionType === 2) {
this.disabledMarks = this.getMergeMarks(this.visitTaskList[idx].MeasureData)
} else {
this.disabledMarks = []
this.disabledMarks = this.getDisabledMarks(this.visitTaskList[idx].MeasureData)
}
return true
},
@@ -785,6 +798,8 @@ export default {
} else if (toolType === 'Length') {
// toolState.data[i].length = this.calculateLenth(toolState.data[i])
}
measureData.largestPixelValue = image.imageFrame.largestPixelValue
measureData.imageId = imageId
measureData.studyId = this.stack.studyId
measureData.seriesId = this.stack.seriesId
measureData.instanceId = instanceId
@@ -901,6 +916,9 @@ export default {
}
} else if (this.activeTool === 1 && this.readingTaskState < 2) {
cornerstoneTools.setToolPassiveForElement(element, data.MeasureData.type, { mouseButtonMask: 1 })
} else if (this.readingTaskState >= 2 && this.isCurrentTask) {
// setToolPassiveForElement
cornerstoneTools.setToolEnabledForElement(element, data.MeasureData.type, { mouseButtonMask: 1 })
} else {
cornerstoneTools.setToolEnabledForElement(element, data.MeasureData.type, { mouseButtonMask: 1 })
}
@@ -919,6 +937,9 @@ export default {
}
}
})
if (this.readingTaskState >= 2 && this.activeToolName && this.isCurrentTask) {
cornerstoneTools.setToolActiveForElement(element, this.activeToolName, { mouseButtonMask: 1 })
}
},
setMeasureDataVisible() {
if (this.readingTaskState >= 2) return
@@ -986,6 +1007,7 @@ export default {
}
},
mouseClick(e) {
if (this.readingTaskState >= 2) return
const { element, currentPoints, image, viewport } = e.detail
var imageId = image.imageId
const imageInfo = this.getInstanceInfo(imageId)
@@ -1010,6 +1032,8 @@ export default {
var questionInfo = this.measureData[idx]
// const canvas = this.canvas.querySelector('canvas')
// measureData.pictureBaseStr = canvas.toDataURL('image/png', 1)
measureData.largestPixelValue = image.imageFrame.largestPixelValue
measureData.imageId = imageId
measureData.studyId = this.stack.studyId
measureData.seriesId = this.stack.seriesId
measureData.instanceId = instanceId
@@ -1035,6 +1059,7 @@ export default {
},
loadImageStack(dicomSeries) {
return new Promise(resolve => {
this.isInitWwwc = true
this.isCurrentTask = dicomSeries.isCurrentTask
this.isBaseline = dicomSeries.isBaseLineTask
this.readingTaskState = dicomSeries.readingTaskState
@@ -1073,7 +1098,8 @@ export default {
} else if (criterionType === 2) {
this.disabledMarks = this.getMergeMarks(this.visitTaskList[idx].MeasureData)
} else {
this.disabledMarks = []
// this.disabledMarks = []
this.disabledMarks = this.getDisabledMarks(this.visitTaskList[idx].MeasureData)
}
this.maxVistNum = this.visitTaskList[this.visitTaskList.length - 1].VisitTaskNum
@@ -1202,7 +1228,7 @@ export default {
this.stack.frame = this.stack.isExistMutiFrames ? parseInt(frame) : null
this.stack.instanceId = instanceId
this.height = (this.stack.currentImageIdIndex) * 100 / (this.stack.imageIds.length - 1)
// this.resetWwwc()
resolve()
})
},
@@ -1300,6 +1326,9 @@ export default {
this.scrollSyncInfo.offset = 0
}
this.renderMeasuredData(e)
if (this.isInitWwwc) {
this.resetWwwc()
}
},
getOrientationMarker(element) {
const enabledElement = cornerstone.getEnabledElement(element)
@@ -1336,6 +1365,8 @@ export default {
this.stack.frame = this.stack.isExistMutiFrames ? parseInt(frame) : null
if (e.detail.toolName === 'Length' || e.detail.toolName === 'ArrowAnnotate' || e.detail.toolName === 'RectangleRoi') {
const measureData = {}
measureData.largestPixelValue = element.image.imageFrame.largestPixelValue
measureData.imageId = imageId
measureData.studyId = this.stack.studyId
measureData.seriesId = this.stack.seriesId
measureData.instanceId = instanceId
@@ -1353,6 +1384,8 @@ export default {
cornerstoneTools.setToolPassiveForElement(this.canvas, e.detail.toolName)
} else if (e.detail.toolName === 'Bidirectional') {
const measureData = {}
measureData.largestPixelValue = element.image.imageFrame.largestPixelValue
measureData.imageId = imageId
measureData.studyId = this.stack.studyId
measureData.seriesId = this.stack.seriesId
measureData.instanceId = instanceId
@@ -1369,6 +1402,8 @@ export default {
cornerstoneTools.setToolPassiveForElement(this.canvas, e.detail.toolName)
} else if (e.detail.toolName === 'Probe') {
const measureData = {}
measureData.largestPixelValue = element.image.imageFrame.largestPixelValue
measureData.imageId = imageId
measureData.studyId = this.stack.studyId
measureData.seriesId = this.stack.seriesId
measureData.instanceId = instanceId
@@ -1478,6 +1513,8 @@ export default {
var questionInfo = this.measureData[idx]
// const canvas = this.canvas.querySelector('canvas')
// measureData.pictureBaseStr = canvas.toDataURL('image/png', 1)
measureData.largestPixelValue = element.image.imageFrame.largestPixelValue
measureData.imageId = imageId
measureData.studyId = this.stack.studyId
measureData.seriesId = this.stack.seriesId
measureData.instanceId = instanceId
@@ -1669,6 +1706,8 @@ export default {
},
resetWwwc() {
// console.log('resetWwwc')
this.isInitWwwc = true
this.toolState.viewportInvert = false
var viewport = cornerstone.getViewport(this.canvas)
// viewport.invert = false
@@ -1679,7 +1718,7 @@ export default {
},
setWwwc(ww, wc) {
// console.log('setWwwc', ww, wc)
this.isInitWwwc = false
var viewport = cornerstone.getViewport(this.canvas)
viewport.voi.windowWidth = ww
viewport.voi.windowCenter = wc
@@ -416,7 +416,7 @@
<dicom-canvas
v-if="canvasW"
:ref="`dicomCanvas${i-1}`"
:style="{width:canvasW,height: canvasH}"
:style="{width: fullScreenIndex === i-1 ? fullScreenWidth : canvasW,height: fullScreenIndex === i-1 ? fullScreenHeight : canvasH}"
:canvas-index="i-1"
:is-active="i-1===currentDicomCanvasIndex"
:is-scroll-sync="isScrollSync"
@@ -989,7 +989,10 @@ export default {
signVisible: false,
signCode: null,
currentUser: zzSessionStorage.getItem('userName'),
tmpData: null
tmpData: null,
fullScreenIndex: -1,
fullScreenWidth: window.innerWidth - 570 + 'px',
fullScreenHeight: window.innerHeight - 130 + 'px'
}
},
@@ -1379,22 +1382,25 @@ export default {
this.personalConfigDialog.visible = true
},
setCornerstoneStyle(i) {
if (this.layoutCol === 1 && this.layoutRow === 1) {
this.fullScreenIndex = -1
return
}
if (this.cornerstoneStyle.position) {
this.cornerstoneStyle = {}
this.setCanvasStyle()
this.fullScreenIndex = -1
} else {
this.cornerstoneStyle = {
position: 'absolute',
top: '72px',
top: '67px',
left: '0px',
right: '350px',
zIndex: 10
zIndex: 10,
}
this.canvasW = window.innerWidth - 570 + 'px'
this.canvasH = window.innerHeight - 130 + 'px'
this.fullScreenIndex = this.currentDicomCanvasIndex
}
this.$nextTick(() => {
// this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].reloadCanvas()
for (var i = 0; i < this.maxCanvas; i++) {
this.$refs[`dicomCanvas${i}`][0].reloadCanvas()
}
@@ -1941,6 +1947,7 @@ export default {
},
// 切换布局
changeLayout(name) {
this.fullScreenIndex = -1
if (this.activeTool) {
if (this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].isCurrentTask && this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].readingTaskState < 2) {
this.$nextTick(() => {
@@ -2043,14 +2050,17 @@ export default {
if (i === -1) return
var isCurrentTask = this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].isCurrentTask
var readingTaskState = this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].readingTaskState
if (!isCurrentTask || readingTaskState >= 2) {
if (!isCurrentTask) {
this.measuredTools[i].isDisabled = true
e.target.style.cursor = 'not-allowed'
if (this.activeTool) {
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].setToolEnabled(toolName)
this.activeTool = ''
}
} else {
} else if (isCurrentTask && readingTaskState >= 2) {
this.measuredTools[i].isDisabled = false
e.target.style.cursor = 'pointer'
} else if (isCurrentTask && readingTaskState < 2) {
// var obj = this.$refs['measurementList'].isCanActiveTool(toolName, true)
var obj = this.$refs['measurementList'].isCanActiveTool(toolName, true)
this.measuredTools[i].disabledReason = obj.reason
@@ -2087,7 +2097,7 @@ export default {
var toolObj = this.measuredTools.find(i => i.toolName === toolName)
if (!toolObj || toolObj.isDisabled) return
var dicomSeries = this.canvasObj[this.currentDicomCanvasIndex]
if (dicomSeries.isCurrentTask && isMeasuredTool && dicomSeries.readingTaskState < 2) {
if (dicomSeries.isCurrentTask && isMeasuredTool) {
if (this.activeTool) {
this.measuredTools.forEach(item => {
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].setToolPassive(item.toolName)
@@ -2248,13 +2258,14 @@ export default {
this.customWwc.visible = false
},
toggleInvert() {
if (this.activeTool === 'reversecolor') {
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].resetWwwc()
this.activeTool = ''
} else {
this.activeTool = 'reversecolor'
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].toggleInvert()
}
// if (this.activeTool === 'reversecolor') {
// this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].resetWwwc()
// this.activeTool = ''
// } else {
// this.activeTool = 'reversecolor'
// this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].toggleInvert()
// }
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].toggleInvert()
},
setImageIndexSync() {
this.isScrollSync = !this.isScrollSync
@@ -8,39 +8,27 @@
<span style="margin-left:5px;">{{ taskBlindName }}</span>
</h3>
<div v-if="readingTaskState < 2">
<el-tooltip class="item" effect="dark" :content="$t('trials:dicomReading:message:confirmReset')" placement="bottom">
<i
class="el-icon-refresh-left"
@click="resetMeasuredData"
/>
<el-tooltip class="item" effect="dark" :content="$t('trials:dicomReading:message:confirmReset')"
placement="bottom">
<i class="el-icon-refresh-left" @click="resetMeasuredData" />
</el-tooltip>
</div>
</div>
<!-- 影像质量问题 -->
<div class="lesions">
<Questions
ref="ecrf"
:question-form-change-state="true"
:question-form-change-num="0"
:is-qulity-issues="false"
:group-classify="1"
/>
<Questions ref="ecrf" :question-form-change-state="true" :question-form-change-num="0" :is-qulity-issues="false"
:group-classify="1" />
</div>
<!-- 测量问题 -->
<template v-if="questions.length > 0">
<div v-for="(qs,index) in questions" :key="index" v-loading="loading" class="lesions lesions_wrapper" style="margin-bottom: 10px">
<div v-for="(qs, index) in questions" :key="index" v-loading="loading" class="lesions lesions_wrapper"
style="margin-bottom: 10px">
<h4 v-if="qs.Type === 'group'" style="color: #ddd;padding: 5px 0px;margin: 0;">
{{ language==='en'?qs.GroupEnName:qs.GroupName }}
{{ language === 'en' ? qs.GroupEnName : qs.GroupName }}
</h4>
<div class="lesion_list">
<el-form
v-if="questions.length > 0"
:ref="`questions${index}`"
size="small"
:model="questionForm"
>
<el-form v-if="questions.length > 0" :ref="`questions${index}`" size="small" :model="questionForm">
<div class="table-wrapper">
<div v-for="item in qs.Childrens" :key="item.Id">
<div v-if="item.Type === 'basicTable'" class="flex-row" style="margin:3px 0;">
@@ -52,34 +40,25 @@
<div class="add-icon" style="margin: 0 5px;" @click.prevent="uploadTpl(item.LesionType)">
<i class="el-icon-upload2" />
</div>
<div class="add-icon" @click.prevent="handleAddOrEdit('add',item)">
<div class="add-icon" @click.prevent="handleAddOrEdit('add', item)">
<i class="el-icon-plus" />
</div>
</div>
</div>
<el-table
v-if="item.Type === 'basicTable' && item.TableQuestions"
:ref="item.Id"
:data="item.TableQuestions.Answers"
>
<el-table v-if="item.Type === 'basicTable' && item.TableQuestions" :ref="item.Id"
:data="item.TableQuestions.Answers">
<!-- <el-table-column :label="$t('CustomizeQuestionFormItem:label:OrderMark')" width="60px" show-overflow-tooltip>
<template slot-scope="scope">
{{ getLesionName(item.OrderMark,scope.row.RowIndex) }}
</template>
</el-table-column> -->
</el-table-column> -->
<!-- <el-table-column
type="index"
width="40px"
/> -->
<el-table-column
v-for="q of item.TableQuestions.Questions"
:key="q.Id"
:prop="q.Id"
:label="q.QuestionName"
show-overflow-tooltip
:render-header="renderHeader"
>
<el-table-column v-for="q of item.TableQuestions.Questions" :key="q.Id" :prop="q.Id"
:label="q.QuestionName" show-overflow-tooltip :render-header="renderHeader">
<template slot-scope="scope">
<span v-if="q.Unit > 0 && !isNaN(parseFloat(scope.row[q.Id]))">
{{ `${scope.row[q.Id]} ${$fd('ValueUnit', parseInt(q.Unit))}` }}
@@ -92,14 +71,10 @@
</span>
</template>
</el-table-column>
<el-table-column
v-if="readingTaskState < 2 && item.LesionType === 102"
:label="$t('common:action:action')"
width="90px"
fixed="right"
>
<el-table-column v-if="readingTaskState < 2 && item.LesionType === 102"
:label="$t('common:action:action')" width="90px" fixed="right">
<template slot-scope="scope">
<el-button type="text" size="mini" @click="handleAddOrEdit('edit',item, scope.$index)">
<el-button type="text" size="mini" @click="handleAddOrEdit('edit', item, scope.$index)">
{{ $t('common:button:edit') }}
</el-button>
<el-button type="text" size="mini" @click="handleDelete(item, scope.$index)">
@@ -111,41 +86,57 @@
<template v-else>
<!-- 数值 -->
<el-form-item
v-if="item.ShowQuestion!==2"
:key="item.Id"
:label="`${item.QuestionName}`"
:prop="item.Id"
:rules="[
{ required: (item.IsRequired === 0 || (item.IsRequired ===1 && item.RelevanceId && (item.RelevanceValue.includes(questionForm[item.RelevanceId])))) && item.Type!=='group' && item.Type!=='summary',
message:['radio', 'select', 'checkbox'].includes(item.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur','change']},
]"
>
<el-form-item v-if="item.ShowQuestion !== 2" :key="item.Id" :label="`${item.QuestionName}`"
:prop="item.Id" :rules="[
{
required: (item.IsRequired === 0 || (item.IsRequired === 1 && item.RelevanceId && (item.RelevanceValue.includes(questionForm[item.RelevanceId])))) && item.Type !== 'group' && item.Type !== 'summary',
message: ['radio', 'select', 'checkbox'].includes(item.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']
},
]">
<!-- 数值类型 -->
<template v-if="item.Type==='textarea'">
<el-input
v-model="questionForm[qs.Id]"
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
:disabled="!isCurrentTask || readingTaskState>=2"
@change="((val)=>{formItemChange(val, qs)})"
/>
<template v-if="item.Type === 'textarea'">
<el-input v-model="questionForm[item.Id]" type="textarea" :autosize="{ minRows: 2, maxRows: 4 }"
:disabled="!isCurrentTask || readingTaskState >= 2"
@change="((val) => { formItemChange(val, item) })" />
</template>
<template v-if="item.Type === 'number'">
<el-input-number v-model="questionForm[item.Id]"
:disabled="!isCurrentTask || readingTaskState >= 2" :precision="0"
@change="((val) => { formItemChange(val, item) })" />
</template>
<template v-if="item.Type === 'select'">
<el-select v-model="questionForm[item.Id]" :disabled="!isCurrentTask || readingTaskState >= 2"
@change="((val) => { formItemChange(val, item) })">
<el-option v-for="dict of $d[item.DictionaryCode]" :key="dict.id" :value="String(dict.value)"
:label="dict.label" />
</el-select>
</template>
</el-form-item>
<template v-if="item.Childrens && item.Childrens.length > 0">
<template v-for="child in item.Childrens">
<el-form-item :key="child.Id"
v-if="(child.ShowQuestion === 1 && child.ParentTriggerValueList.includes(String(questionForm[item.Id]))) || child.ShowQuestion === 0"
:label="`${child.QuestionName}`" :prop="child.Id" :rules="[
{
required: (child.IsRequired === 0 || (child.IsRequired === 1 && child.RelevanceId && (child.RelevanceValue.includes(questionForm[child.RelevanceId])))) && child.Type !== 'group' && child.Type !== 'summary',
message: ['radio', 'select', 'checkbox'].includes(child.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']
},
]">
<template v-if="child.Type === 'input'">
<el-input v-model="questionForm[child.Id]"
:disabled="!isCurrentTask || readingTaskState >= 2"
@change="((val) => { formItemChange(val, child) })" />
</template>
</el-form-item>
</template>
</template>
</template>
</div>
<div
v-if="isCurrentTask && readingTaskState<2 && qs.GroupClassify === 5"
class="base-dialog-footer"
style="text-align:right;margin-top:10px;"
>
<div v-if="isCurrentTask && readingTaskState < 2 && (qs.GroupClassify === 5 || qs.GroupClassify === 6)"
class="base-dialog-footer" style="text-align:right;margin-top:10px;">
<!-- 保存 -->
<el-button
type="primary"
size="mini"
:disabled="!formChanged"
@click="handleSave(index)"
>
<el-button type="primary" size="mini" :disabled="!formChanged" @click="handleSave(index)">
{{ $t('common:button:save') }}
</el-button>
</div>
@@ -156,51 +147,21 @@
</template>
<!-- 计算值 -->
<Questions
ref="ecrf2"
:question-form-change-state="true"
:question-form-change-num="0"
:is-qulity-issues="false"
:group-classify="4"
style="margin-top:20px"
/>
<Questions ref="ecrf2" :question-form-change-state="true" :question-form-change-num="0" :is-qulity-issues="false"
:group-classify="4" style="margin-top:20px" />
<!-- 评估结果 -->
<Questions
ref="ecrf3"
:question-form-change-state="true"
:question-form-change-num="0"
:is-qulity-issues="false"
:group-classify="5"
/>
<Questions ref="ecrf3" :question-form-change-state="true" :question-form-change-num="0" :is-qulity-issues="false"
:group-classify="5" />
<!-- 新增编辑弹窗 -->
<el-dialog
v-if="addOrEdit.visible"
:visible.sync="addOrEdit.visible"
:close-on-click-modal="false"
:title="addOrEdit.title"
width="500px"
>
<el-form
ref="tableQsForm"
v-loading="loading"
:model="qsForm"
size="small"
>
<QuestionTableFormItem
v-for="item in qsList"
:key="item.Id"
:question="item"
:question-form="qsForm"
:reading-task-state="readingTaskState"
@setFormItemData="setFormItemData"
@resetFormItemData="resetFormItemData"
/>
<el-dialog v-if="addOrEdit.visible" :visible.sync="addOrEdit.visible" :close-on-click-modal="false"
:title="addOrEdit.title" width="500px">
<el-form ref="tableQsForm" v-loading="loading" :model="qsForm" size="small">
<QuestionTableFormItem v-for="item in qsList" :key="item.Id" :question="item" :question-form="qsForm"
:reading-task-state="readingTaskState" @setFormItemData="setFormItemData"
@resetFormItemData="resetFormItemData" />
<el-form-item style="text-align: right">
<el-button
size="small"
@click="addOrEdit.visible = false"
>
<el-button size="small" @click="addOrEdit.visible = false">
{{ $t('common:button:cancel') }}
</el-button>
<!-- 保存 -->
@@ -211,17 +172,9 @@
</el-form>
</el-dialog>
<!-- 导入 -->
<el-dialog
v-if="upload.visible"
:visible.sync="upload.visible"
:close-on-click-modal="false"
:title="upload.title"
width="500px"
>
<UploadExcel
:visit-task-id="visitTaskId"
@close="uploadDlgClose"
/>
<el-dialog v-if="upload.visible" :visible.sync="upload.visible" :close-on-click-modal="false"
:title="upload.title" width="500px">
<UploadExcel :visit-task-id="visitTaskId" @close="uploadDlgClose" />
</el-dialog>
</div>
</div>
@@ -485,8 +438,22 @@ export default {
setMeasuredData(measureData) {
},
formItemChange() {
formItemChange(val, item) {
this.formChanged = true
if (item.Type === 'number') {
this.limitBlur(item.Id, item.ValueType)
}
if (question.Childrens.length > 0) {
this.resetChild(question.Childrens)
}
},
resetChild(obj) {
obj.forEach(i => {
this.resetData(i.Id)
if (i.Childrens && i.Childrens.length > 0) {
this.resetChild(i.Childrens)
}
})
},
limitBlur(qId, valueType) {
const value = this.questionForm[qId]
@@ -523,7 +490,7 @@ export default {
answers: answers
}
try {
await saveTaskQuestion(8, params)
await saveTaskQuestion(12, params)
this.$message.success(this.$t('common:message:savedSuccessfully'))
loading.close()
DicomEvent.$emit('getReportInfo', true)
@@ -578,6 +545,9 @@ export default {
},
receiveMsg(event) {
},
resetData(v) {
this.questionForm[v] = null
},
resetFormItemData(v) {
this.qsForm[v] = null
},
@@ -730,21 +700,25 @@ export default {
}
</script>
<style lang="scss" scoped>
.measurement-wrapper{
.measurement-wrapper {
height: 100%;
overflow-y: auto;
.container{
.container {
padding: 10px;
.basic-info{
.basic-info {
display: flex;
justify-content: space-between;
align-items: center;
h3{
h3 {
color: #ddd;
padding: 5px 0px;
margin: 0;
}
i{
i {
color: #fff;
font-size: 22px;
font-weight: bold;
@@ -752,14 +726,16 @@ export default {
}
}
}
.title{
.title {
padding: 5px;
font-weight: bold;
color: #ddd;
font-size: 15px;
}
.add-icon{
.add-icon {
display: inline-block;
padding: 5px;
font-weight: bold;
@@ -769,103 +745,123 @@ export default {
margin-bottom: 2px;
cursor: pointer;
}
.add-icon:hover{
.add-icon:hover {
background-color: #607d8b;
}
.flex-row{
.flex-row {
display: flex;
flex-direction: row;
justify-content: space-between;
background-color: #424242;
}
.lesion_list{
.lesion_list {
position: relative;
::v-deep .el-form-item__label{
::v-deep .el-form-item__label {
color: #c3c3c3;
text-align: left;
}
::v-deep .el-input .el-input__inner{
::v-deep .el-input .el-input__inner {
background-color: transparent;
color: #ddd;
border: 1px solid #5e5e5e;
}
::v-deep .el-textarea__inner{
::v-deep .el-textarea__inner {
background-color: transparent;
color: #ddd;
border: 1px solid #5e5e5e;
}
::v-deep .el-form-item{
::v-deep .el-form-item {
display: flex;
flex-direction: column;
justify-content: flex-start;
}
::v-deep .el-form-item__content{
::v-deep .el-form-item__content {
flex: 1;
}
::v-deep .el-input.is-disabled .el-input__inner{
background-color: #646464a1;
}
::v-deep .el-select.is-disabled .el-input__inner{
::v-deep .el-input.is-disabled .el-input__inner {
background-color: #646464a1;
}
.el-form-item__content
.el-select{
::v-deep .el-select.is-disabled .el-input__inner {
background-color: #646464a1;
}
.el-form-item__content .el-select {
width: 100%;
}
}
.table-wrapper {
::-webkit-scrollbar {
width: 5px;
height: 8px;
}
::-webkit-scrollbar-thumb {
border-radius: 10px;
background: #d0d0d0;
}
::v-deep .el-table,
.el-table__expanded-cell {
background-color: #000;
color: #fff;
border-color: #444444;
}
::v-deep .el-table th,
.el-table tr {
background-color: #000;
color: #fff;
border-color: #444444;
}
::v-deep .el-table__body tr > td {
::v-deep .el-table__body tr>td {
background-color: #000 !important;
color: #fff;
border-color: #444444;
}
::v-deep .el-table__body tr:hover > td {
::v-deep .el-table__body tr:hover>td {
background-color: #858282 !important;
color: #fff;
border-color: #444444;
}
::v-deep .el-table--border th.gutter:last-of-type {
border: none;
}
::v-deep .el-table__fixed-right {
height: 100% !important;
}
// ::v-deep .el-table .cell {
// line-height: 20px;
// }
::v-deep .el-table__cell {
padding: 5px 0;
}
::v-deep.el-table__fixed-right-patch {
background-color: #000 !important;
border-color: #444444;
}
::v-deep.el-table__fixed-body-wrapper tr:hover > td {
::v-deep.el-table__fixed-body-wrapper tr:hover>td {
background-color: #000 !important;
}
::v-deep.el-table--scrollable-x .el-table__body-wrapper {
z-index: 2;
}
@@ -205,6 +205,7 @@
import { saveTableQuestionMark, submitTaskRowInfo, deleteTableQuestionMark, deleteSingleTableQuestionMark } from '@/api/reading'
import DicomEvent from './../DicomEvent'
import store from '@/store'
import * as cornerstone from 'cornerstone-core'
export default {
name: 'MeasurementForm',
props: {
@@ -444,7 +445,12 @@ export default {
// 维护标记信息
measureData.data.remark = this.getLesionName(this.orderMark, this.activeQuestionMark)
}
const val = measureData.data.cachedStats.mean / 10
// const val = measureData.data.cachedStats.mean / 10
let val = parseFloat(measureData.data.cachedStats.mean)
// let imagePixelModule = cornerstone.metaData.get('imagePixelModule', measureData.imageId)
if (measureData.largestPixelValue >= 500) {
val = val / 10
}
this.$set(this.questionForm, measureData.tableQuestionId, val.toFixed(this.digitPlaces))
data = {
Id: '',
@@ -574,14 +580,26 @@ export default {
let params = {}
if (i > -1 && this.markList[i].measureData && this.markList[i].measureData.MeasureData) {
const measureData = this.markList[i].measureData.MeasureData
const tableQuestionId = this.markList[i].tableQuestionId
if (this.questionForm[tableQuestionId] > 100) {
const confirm = await this.$confirm(
this.$t('trials:MRIPDFF:message:message4'),
{
type: 'warning',
distinguishCancelAndClose: true
}
)
if (confirm !== 'confirm') return
}
// 上传截图
DicomEvent.$emit('getScreenshots', { questionId: this.parentQsId, rowIndex: this.questionForm.RowIndex, visitTaskId: this.visitTaskId, lesionName: measureData.OrderMarkName, lesionType: null, isMarked: !!measureData }, async val => {
params = Object.assign({}, this.markList[i].measureData)
if (val) {
const pictureObj = await this.uploadScreenshots(`${new Date().getTime()}`, val)
params.PicturePath = pictureObj.isSuccess ? this.$getObjectName(pictureObj.result.url) : ''
}
const tableQuestionId = this.markList[i].tableQuestionId
params.Answer = this.questionForm[tableQuestionId]
params.MeasureData = JSON.stringify(this.markList[i].measureData.MeasureData)
loading.close()
@@ -264,7 +264,6 @@ export default {
if (item.Type === 'table' && item.Id === obj.questionId) {
var idx = item.TableQuestions.Answers.findIndex(i => i.RowIndex === obj.rowIndex)
item.TableQuestions.Answers[idx].isMeasurable = obj.isMeasurable
console.log(obj.isMeasurable)
item.TableQuestions.Answers[idx].mean = obj.mean
item.TableQuestions.Answers[idx].saveTypeEnum = obj.saveTypeEnum
@@ -7,39 +7,28 @@
<span style="margin-left:5px;">{{ taskBlindName }}</span>
</h3>
<div v-if="readingTaskState < 2">
<el-tooltip class="item" effect="dark" :content="$t('trials:dicomReading:message:confirmReset')" placement="bottom">
<i
class="el-icon-refresh-left"
@click="resetMeasuredData"
/>
<el-tooltip class="item" effect="dark" :content="$t('trials:dicomReading:message:confirmReset')"
placement="bottom">
<i class="el-icon-refresh-left" @click="resetMeasuredData" />
</el-tooltip>
</div>
</div>
<!-- 影像质量问题 -->
<div class="lesions">
<Questions
ref="ecrf"
:question-form-change-state="true"
:question-form-change-num="0"
:is-qulity-issues="false"
:group-classify="1"
/>
<Questions ref="ecrf" :question-form-change-state="true" :question-form-change-num="0" :is-qulity-issues="false"
:group-classify="1" />
</div>
<!-- 测量问题 -->
<template v-if="questions.length > 0">
<div v-for="(qs,index) in questions" :key="index" v-loading="loading" class="lesions lesions_wrapper" style="margin-bottom: 10px">
<div v-for="(qs, index) in questions" :key="index" v-loading="loading" class="lesions lesions_wrapper"
style="margin-bottom: 10px">
<h4 v-if="qs.Type === 'group'" style="color: #ddd;padding: 5px 0px;margin: 0;">
{{ language==='en'?qs.GroupEnName:qs.GroupName }}
{{ language === 'en' ? qs.GroupEnName : qs.GroupName }}
</h4>
<div class="lesion_list">
<el-form
v-if="questions.length > 0"
:ref="`questions${index}`"
size="small"
:model="questionForm"
>
<el-form v-if="questions.length > 0" :ref="`questions${index}`" size="small" :model="questionForm">
<div class="table-wrapper">
<div v-for="item in qs.Childrens" :key="item.Id">
<div v-if="item.Type === 'basicTable'" class="flex-row" style="margin:3px 0;">
@@ -51,35 +40,25 @@
<div class="add-icon" style="margin: 0 5px;" @click.prevent="uploadTpl(item.LesionType)">
<i class="el-icon-upload2" />
</div>
<div class="add-icon" @click.prevent="handleAddOrEdit('add',item)">
<div class="add-icon" @click.prevent="handleAddOrEdit('add', item)">
<i class="el-icon-plus" />
</div>
</div>
</div>
<el-table
v-if="item.Type === 'basicTable' && item.TableQuestions"
:ref="item.Id"
:data="item.TableQuestions.Answers"
max-height="600"
>
<el-table v-if="item.Type === 'basicTable' && item.TableQuestions" :ref="item.Id"
:data="item.TableQuestions.Answers" max-height="600">
<!-- <el-table-column :label="$t('CustomizeQuestionFormItem:label:OrderMark')" width="60px" show-overflow-tooltip>
<template slot-scope="scope">
{{ getLesionName(item.OrderMark,scope.row.RowIndex) }}
</template>
</el-table-column> -->
</el-table-column> -->
<!-- <el-table-column
type="index"
width="40px"
/> -->
<el-table-column
v-for="q of item.TableQuestions.Questions"
:key="q.Id"
:prop="q.Id"
:label="q.QuestionName"
show-overflow-tooltip
:render-header="renderHeader"
>
<el-table-column v-for="q of item.TableQuestions.Questions" :key="q.Id" :prop="q.Id"
:label="q.QuestionName" show-overflow-tooltip :render-header="renderHeader">
<template slot-scope="scope">
<span v-if="q.Unit > 0 && !isNaN(parseFloat(scope.row[q.Id]))">
{{ `${scope.row[q.Id]} ${$fd('ValueUnit', parseInt(q.Unit))}` }}
@@ -92,17 +71,14 @@
</span>
</template>
</el-table-column>
<el-table-column
v-if="readingTaskState < 2"
:label="$t('common:action:action')"
width="90px"
fixed="right"
>
<el-table-column v-if="readingTaskState < 2" :label="$t('common:action:action')" width="90px"
fixed="right">
<template slot-scope="scope">
<el-button type="text" size="mini" @click="handleAddOrEdit('edit',item, scope.$index)">
<el-button type="text" size="mini" @click="handleAddOrEdit('edit', item, scope.$index)">
{{ $t('common:button:edit') }}
</el-button>
<el-button v-if="item.LesionType === 112 || item.LesionType === 111" type="text" size="mini" @click="handleDelete(item, scope.$index)">
<el-button v-if="item.LesionType === 112 || item.LesionType === 111" type="text" size="mini"
@click="handleDelete(item, scope.$index)">
{{ $t('common:button:delete') }}
</el-button>
</template>
@@ -111,41 +87,52 @@
<template v-else>
<!-- 数值 -->
<el-form-item
v-if="item.ShowQuestion!==2"
:key="item.Id"
:label="`${item.QuestionName}`"
:prop="item.Id"
:rules="[
{ required: (item.IsRequired === 0 || (item.IsRequired ===1 && item.RelevanceId && (item.RelevanceValue.includes(questionForm[item.RelevanceId])))) && item.Type!=='group' && item.Type!=='summary',
message:['radio', 'select', 'checkbox'].includes(item.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur','change']},
]"
>
<el-form-item v-if="item.ShowQuestion !== 2" :key="item.Id" :label="`${item.QuestionName}`"
:prop="item.Id" :rules="[
{
required: (item.IsRequired === 0 || (item.IsRequired === 1 && item.RelevanceId && (item.RelevanceValue.includes(questionForm[item.RelevanceId])))) && item.Type !== 'group' && item.Type !== 'summary',
message: ['radio', 'select', 'checkbox'].includes(item.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']
},
]">
<!-- 数值类型 -->
<template v-if="item.Type==='textarea'">
<el-input
v-model="questionForm[qs.Id]"
type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
:disabled="!isCurrentTask || readingTaskState>=2"
@change="((val)=>{formItemChange(val, qs)})"
/>
<template v-if="item.Type === 'textarea'">
<el-input v-model="questionForm[item.Id]" type="textarea" :autosize="{ minRows: 2, maxRows: 4 }"
:disabled="!isCurrentTask || readingTaskState >= 2"
@change="((val) => { formItemChange(val, item) })" />
</template>
<template v-if="item.Type === 'select'">
<el-select v-model="questionForm[item.Id]" :disabled="!isCurrentTask || readingTaskState >= 2"
@change="((val) => { formItemChange(val, item) })">
<el-option v-for="dict of $d[item.DictionaryCode]" :key="dict.id" :value="String(dict.value)"
:label="dict.label" />
</el-select>
</template>
</el-form-item>
<template v-if="item.Childrens && item.Childrens.length > 0">
<template v-for="child in item.Childrens">
<el-form-item :key="child.Id"
v-if="(child.ShowQuestion === 1 && child.ParentTriggerValueList.includes(String(questionForm[item.Id]))) || child.ShowQuestion === 0"
:label="`${child.QuestionName}`" :prop="child.Id" :rules="[
{
required: (child.IsRequired === 0 || (child.IsRequired === 1 && child.RelevanceId && (child.RelevanceValue.includes(questionForm[child.RelevanceId])))) && child.Type !== 'group' && child.Type !== 'summary',
message: ['radio', 'select', 'checkbox'].includes(child.Type) ? $t('common:ruleMessage:select') : $t('common:ruleMessage:specify'), trigger: ['blur', 'change']
},
]">
<template v-if="child.Type === 'input'">
<el-input v-model="questionForm[child.Id]"
:disabled="!isCurrentTask || readingTaskState >= 2"
@change="((val) => { formItemChange(val, child) })" />
</template>
</el-form-item>
</template>
</template>
</template>
</div>
<div
v-if="isCurrentTask && readingTaskState<2 && qs.GroupClassify === 5"
class="base-dialog-footer"
style="text-align:right;margin-top:10px;"
>
<div v-if="isCurrentTask && readingTaskState < 2 && (qs.GroupClassify === 5 || qs.GroupClassify === 6)"
class="base-dialog-footer" style="text-align:right;margin-top:10px;">
<!-- 保存 -->
<el-button
type="primary"
size="mini"
:disabled="!formChanged"
@click="handleSave(index)"
>
<el-button type="primary" size="mini" :disabled="!formChanged" @click="handleSave(index)">
{{ $t('common:button:save') }}
</el-button>
</div>
@@ -156,50 +143,20 @@
</template>
<!-- 计算值 -->
<Questions
ref="ecrf2"
:question-form-change-state="true"
:question-form-change-num="0"
:is-qulity-issues="false"
:group-classify="4"
style="margin-top:20px"
/>
<Questions ref="ecrf2" :question-form-change-state="true" :question-form-change-num="0" :is-qulity-issues="false"
:group-classify="4" style="margin-top:20px" />
<!-- 评估结果 -->
<Questions
ref="ecrf3"
:question-form-change-state="true"
:question-form-change-num="0"
:is-qulity-issues="false"
:group-classify="5"
/>
<el-dialog
v-if="addOrEdit.visible"
:visible.sync="addOrEdit.visible"
:close-on-click-modal="false"
:title="addOrEdit.title"
width="500px"
>
<el-form
ref="tableQsForm"
v-loading="loading"
:model="qsForm"
size="small"
>
<QuestionTableFormItem
v-for="item in qsList"
:key="item.Id"
:question="item"
:question-form="qsForm"
:reading-task-state="readingTaskState"
@setFormItemData="setFormItemData"
@resetFormItemData="resetFormItemData"
/>
<Questions ref="ecrf3" :question-form-change-state="true" :question-form-change-num="0" :is-qulity-issues="false"
:group-classify="5" />
<el-dialog v-if="addOrEdit.visible" :visible.sync="addOrEdit.visible" :close-on-click-modal="false"
:title="addOrEdit.title" width="500px">
<el-form ref="tableQsForm" v-loading="loading" :model="qsForm" size="small">
<QuestionTableFormItem v-for="item in qsList" :key="item.Id" :question="item" :question-form="qsForm"
:reading-task-state="readingTaskState" @setFormItemData="setFormItemData"
@resetFormItemData="resetFormItemData" />
<el-form-item style="text-align: right">
<el-button
size="small"
@click="addOrEdit.visible = false"
>
<el-button size="small" @click="addOrEdit.visible = false">
{{ $t('common:button:cancel') }}
</el-button>
<!-- 保存 -->
@@ -210,18 +167,9 @@
</el-form>
</el-dialog>
<!-- 导入 -->
<el-dialog
v-if="upload.visible"
:visible.sync="upload.visible"
:close-on-click-modal="false"
:title="upload.title"
width="500px"
>
<UploadExcel
:visit-task-id="visitTaskId"
:lesion-type="upload.lesionType"
@close="uploadDlgClose"
/>
<el-dialog v-if="upload.visible" :visible.sync="upload.visible" :close-on-click-modal="false"
:title="upload.title" width="500px">
<UploadExcel :visit-task-id="visitTaskId" :lesion-type="upload.lesionType" @close="uploadDlgClose" />
</el-dialog>
</div>
</div>
@@ -486,8 +434,22 @@ export default {
setMeasuredData(measureData) {
},
formItemChange() {
formItemChange(val, question) {
this.formChanged = true
if (item.Type === 'number') {
this.limitBlur(item.Id, item.ValueType)
}
if (question.Childrens.length > 0) {
this.resetChild(question.Childrens)
}
},
resetChild(obj) {
obj.forEach(i => {
this.resetData(i.Id)
if (i.Childrens && i.Childrens.length > 0) {
this.resetChild(i.Childrens)
}
})
},
limitBlur(qId, valueType) {
const value = this.questionForm[qId]
@@ -521,7 +483,7 @@ export default {
answers: answers
}
try {
await saveTaskQuestion(8, params)
await saveTaskQuestion(12, params)
this.$message.success(this.$t('common:message:savedSuccessfully'))
loading.close()
DicomEvent.$emit('getReportInfo', true)
@@ -576,6 +538,9 @@ export default {
},
receiveMsg(event) {
},
resetData(v) {
this.questionForm[v] = null
},
resetFormItemData(v) {
this.qsForm[v] = null
},
@@ -741,23 +706,26 @@ export default {
}
</script>
<style lang="scss" scoped>
.measurement-wrapper{
.measurement-wrapper {
height: 100%;
overflow-y: auto;
// overflow: hidden;
.container{
.container {
padding: 10px;
.basic-info{
.basic-info {
display: flex;
justify-content: space-between;
align-items: center;
h3{
h3 {
color: #ddd;
padding: 5px 0px;
margin: 0;
}
i{
i {
color: #fff;
font-size: 22px;
font-weight: bold;
@@ -765,14 +733,16 @@ export default {
}
}
}
.title{
.title {
padding: 5px;
font-weight: bold;
color: #ddd;
font-size: 15px;
}
.add-icon{
.add-icon {
display: inline-block;
padding: 5px;
font-weight: bold;
@@ -782,103 +752,123 @@ export default {
margin-bottom: 2px;
cursor: pointer;
}
.add-icon:hover{
.add-icon:hover {
background-color: #607d8b;
}
.flex-row{
.flex-row {
display: flex;
flex-direction: row;
justify-content: space-between;
background-color: #424242;
}
.lesion_list{
.lesion_list {
position: relative;
::v-deep .el-form-item__label{
::v-deep .el-form-item__label {
color: #c3c3c3;
text-align: left;
}
::v-deep .el-input .el-input__inner{
::v-deep .el-input .el-input__inner {
background-color: transparent;
color: #ddd;
border: 1px solid #5e5e5e;
}
::v-deep .el-textarea__inner{
::v-deep .el-textarea__inner {
background-color: transparent;
color: #ddd;
border: 1px solid #5e5e5e;
}
::v-deep .el-form-item{
::v-deep .el-form-item {
display: flex;
flex-direction: column;
justify-content: flex-start;
}
::v-deep .el-form-item__content{
::v-deep .el-form-item__content {
flex: 1;
}
::v-deep .el-input.is-disabled .el-input__inner{
background-color: #646464a1;
}
::v-deep .el-select.is-disabled .el-input__inner{
::v-deep .el-input.is-disabled .el-input__inner {
background-color: #646464a1;
}
.el-form-item__content
.el-select{
::v-deep .el-select.is-disabled .el-input__inner {
background-color: #646464a1;
}
.el-form-item__content .el-select {
width: 100%;
}
}
.table-wrapper {
::-webkit-scrollbar {
width: 5px;
height: 8px;
}
::-webkit-scrollbar-thumb {
border-radius: 10px;
background: #d0d0d0;
}
::v-deep .el-table,
.el-table__expanded-cell {
background-color: #000;
color: #fff;
border-color: #444444;
}
::v-deep .el-table th,
.el-table tr {
background-color: #000;
color: #fff;
border-color: #444444;
}
::v-deep .el-table__body tr > td {
::v-deep .el-table__body tr>td {
background-color: #000 !important;
color: #fff;
border-color: #444444;
}
::v-deep .el-table__body tr:hover > td {
::v-deep .el-table__body tr:hover>td {
background-color: #858282 !important;
color: #fff;
border-color: #444444;
}
::v-deep .el-table--border th.gutter:last-of-type {
border: none;
}
::v-deep .el-table__fixed-right {
height: 100% !important;
}
// ::v-deep .el-table .cell {
// line-height: 20px;
// }
::v-deep .el-table__cell {
padding: 5px 0;
}
::v-deep.el-table__fixed-right-patch {
background-color: #000 !important;
border-color: #444444;
}
::v-deep.el-table__fixed-body-wrapper tr:hover > td {
::v-deep.el-table__fixed-body-wrapper tr:hover>td {
background-color: #000 !important;
}
::v-deep.el-table--scrollable-x .el-table__body-wrapper {
z-index: 2;
}
@@ -556,7 +556,7 @@
<dicom-canvas
v-if="canvasW"
:ref="`dicomCanvas${i - 1}`"
:style="{ width: canvasW, height: canvasH }"
:style="{width: fullScreenIndex === i-1 ? fullScreenWidth : canvasW,height: fullScreenIndex === i-1 ? fullScreenHeight : canvasH}"
:canvas-index="i - 1"
:is-active="i - 1 === currentDicomCanvasIndex"
:is-scroll-sync="isScrollSync"
@@ -895,6 +895,9 @@ export default {
uploadTrialCriterion: {},
uploadStatus: 'upload',
taskId: '',
fullScreenIndex: -1,
fullScreenWidth: window.innerWidth - 570 + 'px',
fullScreenHeight: window.innerHeight - 128 + 'px'
}
},
@@ -1314,22 +1317,25 @@ export default {
this.personalConfigDialog.visible = true
},
setCornerstoneStyle(i) {
if (this.layoutCol === 1 && this.layoutRow === 1) {
this.fullScreenIndex = -1
return
}
if (this.cornerstoneStyle.position) {
this.cornerstoneStyle = {}
this.setCanvasStyle()
this.fullScreenIndex = -1
} else {
this.cornerstoneStyle = {
position: 'absolute',
top: '72px',
top: '70px',
left: '205px',
right: '350px',
zIndex: 10,
}
this.canvasW = window.innerWidth - 570 + 'px'
this.canvasH = window.innerHeight - 130 + 'px'
this.fullScreenIndex = this.currentDicomCanvasIndex
}
this.$nextTick(() => {
// this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].reloadCanvas()
for (var i = 0; i < this.maxCanvas; i++) {
this.$refs[`dicomCanvas${i}`][0].reloadCanvas()
}
@@ -1928,6 +1934,7 @@ export default {
},
//
changeLayout(name) {
this.fullScreenIndex = -1
if (this.activeTool) {
if (
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0]
@@ -2301,15 +2308,16 @@ export default {
this.customWwc.visible = false
},
toggleInvert() {
if (this.activeTool === 'reversecolor') {
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].resetWwwc()
this.activeTool = ''
} else {
this.activeTool = 'reversecolor'
this.$refs[
`dicomCanvas${this.currentDicomCanvasIndex}`
][0].toggleInvert()
}
// if (this.activeTool === 'reversecolor') {
// this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].resetWwwc()
// this.activeTool = ''
// } else {
// this.activeTool = 'reversecolor'
// this.$refs[
// `dicomCanvas${this.currentDicomCanvasIndex}`
// ][0].toggleInvert()
// }
this.$refs[`dicomCanvas${this.currentDicomCanvasIndex}`][0].toggleInvert()
},
setImageIndexSync() {
this.isScrollSync = !this.isScrollSync
@@ -69,6 +69,10 @@
:rules="[
{ required: (question.IsRequired === 0 || (question.IsRequired ===1 && question.RelevanceId && (question.RelevanceValueList.includes(isNaN(parseFloat(questionForm[question.RelevanceId])) ? questionForm[question.RelevanceId] : questionForm[question.RelevanceId].toString())))) && question.Type!=='group' && question.Type!=='summary',
message: $t('common:ruleMessage:specify'), trigger: ['blur', 'change']},
{
validator: question.Type === 'number' && !question.TypeValue ? validatorNumberInput :(rule,value,callback )=>{callback()},
trigger: ['blur', 'change']
}
]"
:class="[question.Type==='group'?'mb':question.Type==='upload'?'uploadWrapper':'']"
>
@@ -228,11 +232,12 @@
/>
</el-select>
<el-input
type="number"
type="text"
v-if="question.Type === 'number' && !question.TypeValue && question.DataSource !== 1"
@change="(val) => { formItemNumberChange(val, question) }"
@input="numberInput(question.Id)"
@blur="handleBlur(questionForm[question.Id], questionForm, question.Id)"
v-model="questionForm[question.Id]"
v-model.trim="questionForm[question.Id]"
:disabled="readingTaskState === 2"
>
<!-- <template slot="append">1</template> -->
@@ -240,11 +245,12 @@
<template slot="append" v-else-if="question.ValueType === 2">%</template>
</el-input>
<el-input
type="number"
type="text"
@input="numberInput(question.Id)"
v-if="question.Type === 'number' && !question.TypeValue && question.DataSource === 1"
@blur="handleBlur(questionForm[question.Id], questionForm, question.Id)"
:disabled="question.DataSource === 1 || readingTaskState === 2"
v-model="questionForm[question.Id]"
v-model.trim="questionForm[question.Id]"
>
<!-- <template slot="append">2</template> -->
<template slot="append" v-if="question.Unit !== 0">{{question.Unit !== 4 ? $fd('ValueUnit', question.Unit) : question.CustomUnit}}</template>
@@ -502,6 +508,21 @@ export default {
}
},
methods: {
numberInput(id) {
this.questionForm[id] = this.questionForm[id].toUpperCase();
},
validatorNumberInput(rule, value, callback) {
let reg = new RegExp(/^(?:-?(?:(?:0|[1-9]\d*)(?:\.\d+)?|\.\d+)|NE)$/, 'g')
if (value === '') {
callback(new Error(this.$t('common:ruleMessage:specify')));
} else {
if (!reg.test(value)) {
callback(new Error(this.$t('trials:reading:ruleMessage:validatorNumberInput')));
}else{
callback();
}
}
},
limitInput(value, a, b) {
if (value.indexOf('.') > -1) {
if (value.split('.')[1].length >= this.digitPlaces) {
@@ -510,7 +531,10 @@ export default {
}
},
handleBlur(value, a, b) {
this.$set(a, b, parseFloat(value).toFixed(this.digitPlaces))
if (!value) return false
if(!isNaN(parseFloat(value))) {
this.$set(a, b, parseFloat(value).toFixed(this.digitPlaces))
}
},
deleteTableCol(row, index) {
this.$confirm(this.$t('trials:uploadNonDicoms:message:msg1')).then(() => {
@@ -1085,8 +1109,6 @@ export default {
flex-direction: row;
align-items: flex-start;
}
::v-deep .el-form-item__content{
}
.el-input{
width:100%;
}
@@ -7,6 +7,10 @@
:rules="[
{ required: (question.IsRequired === 0 || (question.IsRequired ===1 && question.RelevanceId && !!~question.RelevanceValueList.indexOf(questionForm[question.RelevanceId]))) && question.Type!=='group' && question.Type!=='summary',
message: $t('common:ruleMessage:select'), trigger: ['blur', 'change']},
{
validator: question.Type === 'number' && !question.TypeValue ? validatorNumberInput :(rule,value,callback )=>{callback()},
trigger: ['blur', 'change']
}
]"
:class="[question.Type==='group'?'mb':question.Type==='upload'?'uploadWrapper':'']"
>
@@ -144,21 +148,23 @@
<!-- 数值 -->
<!-- :precision="2" :step="0.1" :max="10" -->
<el-input
type="number"
type="text"
v-if="question.Type === 'number' && question.DataSource !== 1"
:disabled="question.TableQuestionType === 2 || (question.IsCopy && type === 'edit' && !IsBaseline && questionForm.IsCurrentTaskAdd === 'False')"
@change="((val)=>{formItemNumberChange(val, question)})"
@input="numberInput(question.Id)"
@blur="handleBlur(questionForm[question.Id], questionForm, question.Id)"
v-model="questionForm[question.Id]"
v-model.trim="questionForm[question.Id]"
>
<template slot="append" v-if="question.Unit !== 0">{{question.Unit !== 4 ? $fd('ValueUnit', question.Unit) : question.CustomUnit}}</template>
</el-input>
<el-input
type="number"
type="text"
v-if="question.Type === 'number' && question.DataSource === 1"
:disabled="question.DataSource === 1"
@input="numberInput(question.Id, true )"
@blur="handleCalculationBlur(calculationValue)"
v-model="calculationValue"
v-model.trim="calculationValue"
>
<template slot="append" v-if="question.Unit !== 0">{{question.Unit !== 4 ? $fd('ValueUnit', question.Unit) : question.CustomUnit}}</template>
</el-input>
@@ -331,7 +337,6 @@ export default {
this.fileList.push({ name: '', url: `${url}` })
})
}
console.log('11')
}
if (this.type === 'edit') return
// if (this.question.Type === 'number') {
@@ -342,6 +347,25 @@ export default {
// }
},
methods: {
numberInput(id,notId = false) {
if(notId ) {
this.calculationValue = this.calculationValue.toUpperCase();
}else {
this.questionForm[id] = this.questionForm[id].toUpperCase();
}
},
validatorNumberInput(rule, value, callback) {
let reg = new RegExp(/^(?:-?(?:(?:0|[1-9]\d*)(?:\.\d+)?|\.\d+)|NE)$/, 'g')
if (value === '') {
callback(new Error(this.$t('common:ruleMessage:specify')));
} else {
if (!reg.test(value)) {
callback(new Error(this.$t('trials:reading:ruleMessage:validatorNumberInput')));
}else{
callback();
}
}
},
save() {
},
openAddTableCol(row) {
@@ -382,10 +406,17 @@ export default {
}
},
handleBlur(value, a, b) {
this.$set(a, b, parseFloat(value).toFixed(this.digitPlaces))
if (!value) return false
if(!isNaN(parseFloat(value))) {
this.$set(a, b, parseFloat(value).toFixed(this.digitPlaces))
}
// this.$set(a, b, parseFloat(value).toFixed(this.digitPlaces))
},
handleCalculationBlur(v) {
this.calculationValue = parseFloat(v).toFixed(this.digitPlaces)
if (!v) return false
if(!isNaN(parseFloat(v))) {
this.calculationValue = parseFloat(v).toFixed(this.digitPlaces)
}
},
limitInput(value, q) {
console.log(value)
@@ -137,7 +137,7 @@ export default {
this.classArr.push({triggerId: v.ClassifyQuestionId, classId: v.Id, classifyAlgorithms: v.ClassifyAlgorithms, classifyType: v.ClassifyType})
}
if (v.Type === 'number') {
this.$set(this.questionForm, v.Id, v.Answer === '' ? '' : parseFloat(v.Answer).toFixed(this.digitPlaces))
this.$set(this.questionForm, v.Id, isNaN(parseFloat(v.Answer)) ? v.Answer : parseFloat(v.Answer).toFixed(this.digitPlaces))
}
if (v.Childrens.length > 0) {
this.setChild(v.Childrens)
@@ -191,7 +191,7 @@ export default {
this.$set(this.questionForm, v.Id, v.TableQuestions.Answers)
}
if (v.Type === 'number') {
this.$set(this.questionForm, v.Id, v.Answer === '' ? '' : parseFloat(v.Answer).toFixed(this.digitPlaces))
this.$set(this.questionForm, v.Id, isNaN(parseFloat(v.Answer)) ? v.Answer : parseFloat(v.Answer).toFixed(this.digitPlaces))
}
if (v.Childrens.length > 0) {
this.setChild(v.Childrens)
@@ -212,7 +212,7 @@ export default {
i.TableQuestions.Questions.forEach(o => {
if (o.Type === 'number') {
i.TableQuestions.Answers.forEach((ite, index) => {
this.$set(i.TableQuestions.Answers[index], o.Id, i.TableQuestions.Answers[index][o.Id] ? parseFloat(i.TableQuestions.Answers[index][o.Id]).toFixed(this.digitPlaces) : null)
this.$set(i.TableQuestions.Answers[index], o.Id, isNaN(parseFloat(i.TableQuestions.Answers[index][o.Id])) ? i.TableQuestions.Answers[index][o.Id] : parseFloat(i.TableQuestions.Answers[index][o.Id]).toFixed(this.digitPlaces))
})
}
})
@@ -222,7 +222,7 @@ export default {
this.classArr.push({triggerId: i.ClassifyQuestionId, classId: i.Id, classifyAlgorithms: i.ClassifyAlgorithms, classifyType: i.ClassifyType})
}
if (i.Type === 'number') {
this.$set(this.questionForm, i.Id, i.Answer === '' ? '' : parseFloat(i.Answer).toFixed(this.digitPlaces))
this.$set(this.questionForm, i.Id, isNaN(parseFloat(i.Answer)) ? i.Answer : parseFloat(i.Answer).toFixed(this.digitPlaces))
}
if (i.Childrens && i.Childrens.length > 0) {
this.setChild(i.Childrens)
@@ -303,6 +303,38 @@
</div>
</div>
</div>
<div
class="tool-item"
:title="$t('trials:reading:button:upload')"
v-if="trialCriterion.ImageUploadEnum > 0 && readingTaskState < 2"
v-hasPermi="['role:ir']"
>
<div class="tool-wrapper">
<div class="icon" @click.prevent="openUploadImage('upload')">
<i class="el-icon-upload2 svg-icon" />
</div>
</div>
</div>
<div
v-if="trialCriterion.ImageDownloadEnum > 0"
v-hasPermi="[
'role:ir',
'role:mim',
'role:mc',
'role:pm',
'role:apm',
'role:ea',
'role:qa',
]"
class="tool-item"
:title="$t('trials:reading:button:download')"
>
<div class="tool-wrapper">
<div class="icon" @click.prevent="openUploadImage('download')">
<i class="el-icon-download svg-icon" />
</div>
</div>
</div>
<!-- 伪彩 -->
<template v-if="readingTool === 2">
<colorMap v-show="isFusion" ref="colorMap" @setColorMap="setColorMap" @voiChange="voiChange" />
@@ -526,10 +558,28 @@
width="850px" >
<FusionForm v-if="fusionVisible" :activeTaskIndex="activeTaskIndex" :taskList="visitTaskList" @close="closeFusion" @fusion="handleFusion" />
</el-dialog>
<upload-dicom-and-nonedicom
v-if="uploadImageVisible"
:subject-id="uploadSubjectId"
:subject-code="uploadSubjectCode"
:criterion="uploadTrialCriterion"
:visible.sync="uploadImageVisible"
:visit-task-id="taskId"
:is-reading-task-view-in-order="isReadingTaskViewInOrder"
/>
<download-dicom-and-nonedicom
v-if="downloadImageVisible"
:subject-id="uploadSubjectId"
:subject-code="uploadSubjectCode"
:criterion="uploadTrialCriterion"
:task-id="taskId"
:visible.sync="downloadImageVisible"
/>
</div>
</template>
<script>
import { getRelatedVisitTask, getReadingVisitStudyList, getTableAnswerRowInfoList, deleteCustomTag } from '@/api/trials'
import { getRelatedVisitTask, getReadingVisitStudyList, getTableAnswerRowInfoList, deleteCustomTag, getCriterionReadingInfo } from '@/api/trials'
import { getDoctorShortcutKey, getUserWLTemplateList } from '@/api/user'
import { getCustomTag, submitCustomTag } from '@/api/reading'
import {
@@ -565,6 +615,8 @@ import ClinicalData from '@/views/trials/trials-panel/reading/clinical-data'
import FusionForm from './FusionForm.vue'
import colorMap from './colorMap.vue'
import RectangleROITool from './tools/RectangleROITool'
import uploadDicomAndNonedicom from '@/components/uploadDicomAndNonedicom'
import downloadDicomAndNonedicom from '@/components/downloadDicomAndNonedicom'
const { visibility } = annotation
const { ViewportType, Events } = Enums
const renderingEngineId = 'myRenderingEngine'
@@ -638,7 +690,9 @@ export default {
Others,
ClinicalData,
FusionForm,
colorMap
colorMap,
downloadDicomAndNonedicom,
uploadDicomAndNonedicom,
},
data() {
return {
@@ -711,6 +765,17 @@ export default {
fusionSerieId: {},
loadingText: null,
// resetAnnotation: false , // 使
//
downloadImageVisible: false,
uploadImageVisible: false,
uploadSubjectId: null,
uploadSubjectCode: null,
uploadTrialCriterion: {},
uploadStatus: 'upload',
taskId: '',
isReadingTaskViewInOrder: null,
trialCriterion: {}
}
},
computed: {
@@ -739,6 +804,7 @@ export default {
}
},
watch: {
currentReadingTaskState(){console.log(this.currentReadingTaskState,'currentReadingTaskState')},
activeTaskId: {
immediate: true,
handler(id) {
@@ -788,6 +854,7 @@ export default {
},
mounted() {
this.taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
this.isReadingTaskViewInOrder = this.taskInfo.IsReadingTaskViewInOrder
this.criterionType = this.taskInfo.CriterionType
const digitPlaces = Number(localStorage.getItem('digitPlaces'))
this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
@@ -812,6 +879,7 @@ export default {
this.initLoader()
this.getWwcTpl()
this.getHotKeys()
this.getTrialCriterion()
})
},
methods: {
@@ -2851,6 +2919,27 @@ export default {
closeFusion() {
this.fusionVisible = false
},
getTrialCriterion() {
getCriterionReadingInfo({
TrialId: this.$route.query.trialId,
TrialReadingCriterionId: this.$route.query.TrialReadingCriterionId
})
.then((res) => {
this.trialCriterion = res.Result
})
.catch(() => {})
},
openUploadImage(status) {
const idx = this.visitTaskList.findIndex(i => i.IsCurrentTask)
if (idx > -1) {
this.taskId = this.visitTaskList[idx].VisitTaskId
}
this.uploadSubjectCode = localStorage.getItem("subjectCode")
this.uploadSubjectId = localStorage.getItem("subjectId")
this.uploadTrialCriterion = this.trialCriterion
this.uploadStatus = status
this[`${status}ImageVisible`] = true
},
}
}
</script>
@@ -402,7 +402,8 @@ export default {
this.series = { ...obj }
const renderingEngine = getRenderingEngine(this.renderingEngineId)
const viewport = renderingEngine.getViewport(this.viewportId)
const image = await cornerstoneDICOMImageLoader.wadouri.loadImage(obj.ImageIds[obj.SliceIndex]).promise
let imageId = obj.ImageIds[obj.SliceIndex] ? obj.ImageIds[obj.SliceIndex] : obj.ImageIds[0]
const image = await cornerstoneDICOMImageLoader.wadouri.loadImage(imageId).promise
if (obj.Modality === 'PT') {
this.cachePTMetadata([image])
}
@@ -112,7 +112,8 @@ export default {
calculationList: [],
taskInfo: null,
isBaseLineTask: false,
rerender: true
rerender: true,
digitPlaces: 2
}
},
mounted() {
@@ -121,6 +122,8 @@ export default {
this.taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
this.isBaseLineTask = this.taskInfo.IsBaseLine
this.criterionType = this.taskInfo.CriterionType
var digitPlaces = Number(localStorage.getItem('digitPlaces'))
this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
this.getQuestionCalculateRelation()
this.getQuestions()
},
@@ -146,7 +149,7 @@ export default {
this.classArr.push({ triggerId: v.ClassifyQuestionId, classId: v.Id, classifyAlgorithms: v.ClassifyAlgorithms, classifyType: v.ClassifyType })
}
if (v.Type === 'number') {
this.$set(this.questionForm, v.Id, v.Answer === '' ? '' : parseFloat(v.Answer).toFixed(this.digitPlaces))
this.$set(this.questionForm, v.Id, isNaN(parseFloat(v.Answer)) ? v.Answer : parseFloat(v.Answer).toFixed(this.digitPlaces))
}
if (v.Childrens.length > 0) {
this.setChild(v.Childrens)
@@ -169,7 +172,7 @@ export default {
i.TableQuestions.Questions.forEach(o => {
if (o.Type === 'number') {
i.TableQuestions.Answers.forEach((ite, index) => {
this.$set(i.TableQuestions.Answers[index], o.Id, i.TableQuestions.Answers[index][o.Id] ? parseFloat(i.TableQuestions.Answers[index][o.Id]).toFixed(this.digitPlaces) : null)
this.$set(i.TableQuestions.Answers[index], o.Id, isNaN(parseFloat(i.TableQuestions.Answers[index][o.Id])) ? i.TableQuestions.Answers[index][o.Id] : parseFloat(i.TableQuestions.Answers[index][o.Id]).toFixed(this.digitPlaces))
})
}
})
@@ -179,7 +182,7 @@ export default {
this.classArr.push({ triggerId: i.ClassifyQuestionId, classId: i.Id, classifyAlgorithms: i.ClassifyAlgorithms, classifyType: i.ClassifyType })
}
if (i.Type === 'number') {
this.$set(this.questionForm, i.Id, i.Answer === '' ? '' : parseFloat(i.Answer).toFixed(this.digitPlaces))
this.$set(this.questionForm, i.Id, isNaN(parseFloat(i.Answer)) ? i.Answer : parseFloat(i.Answer).toFixed(this.digitPlaces))
}
if (i.Childrens && i.Childrens.length > 0) {
this.setChild(i.Childrens)
@@ -396,7 +396,7 @@ export default {
if (v.Type === 'number') {
let val = null
if (v.ValueType === 0) {
val = parseInt(v.Answers[this.visitTaskId])
val = isNaN(parseFloat(v.Answers[this.visitTaskId])) ? v.Answers[this.visitTaskId] : parseInt(v.Answers[this.visitTaskId])
} else if (v.ValueType === 3) {
val = v.Answers[this.visitTaskId]
} else {
@@ -422,7 +422,7 @@ export default {
if (i.Type === 'number') {
let val = null
if (i.ValueType === 0) {
val = parseInt(i.Answers[this.visitTaskId])
val = isNaN(parseFloat(i.Answers[this.visitTaskId])) ? i.Answers[this.visitTaskId] : parseInt(i.Answers[this.visitTaskId])
} else if (i.ValueType === 3) {
val = i.Answers[this.visitTaskId]
} else {
@@ -561,7 +561,7 @@ export default {
if (item.Type === 'number') {
let val = null
if (item.ValueType === 0) {
val = parseInt(i.Answer)
val = isNaN(parseFloat(i.Answer)) ? i.Answer : parseInt(i.Answer)
} else if (item.ValueType === 3) {
val = i.Answer
} else {
@@ -30,6 +30,7 @@
type="primary"
size="small"
@click="skipTask"
v-if="!isView"
>
<!-- 跳过 -->
{{ $t('trials:readingReport:button:skip') }}
@@ -337,6 +338,11 @@ export default {
// }
// }
// },
computed:{
isView(){
return !this.hasPermi(['role:ir'])
}
},
mounted() {
this.getList()
if (this.isReadingShowPreviousResults) {
@@ -0,0 +1,433 @@
<template>
<BaseContainer style="padding: 20px;">
<template slot="title-container">
<div class="title">
{{ $t('trials:readOrder:title') }}
</div>
</template>
<template slot="search-container">
<el-form :inline="true">
<!-- 是否加急 -->
<el-form-item style="margin-bottom: 10px" :label="$t('trials:readOrder:table:isUrgent')">
<el-select v-model="searchData.IsUrgent" clearable style="width: 120px">
<el-option v-for="item of $d.YesOrNo" :key="'IsUrgent' + item.label" :value="item.value"
:label="item.label" />
</el-select>
</el-form-item>
<!-- 临床数据是否完备 -->
<el-form-item style="margin-bottom: 10px"
:label="$t('trials:readOrder:table:completeClinicalDataEnum')">
<el-select v-model="searchData.CompleteClinicalDataEnum" clearable style="width: 120px">
<el-option v-for="item of $d.CompleteClinicalDataEnum"
:key="'CompleteClinicalDataEnum' + item.label" :value="item.value" :label="item.label" />
</el-select>
</el-form-item>
<!-- 中心编号 -->
<el-form-item :label="$t('trials:readOrder:table:siteCode')">
<el-select v-model="searchData.TrialSiteId" clearable filterable style="width: 120px">
<el-option v-for="(item, index) of siteOptions" :key="index" :label="item.TrialSiteCode"
:value="item.TrialSiteId" />
</el-select>
</el-form-item>
<!-- 受试者编号 -->
<el-form-item :label="$t('trials:readOrder:table:subjectCode')">
<el-input v-model="searchData.SubjectCode" style="width: 100px" />
</el-form-item>
<!-- 任务名称 -->
<el-form-item style="margin-bottom: 10px" :label="$t('trials:readOrder:table:taskName')">
<el-input v-model="searchData.TaskName" style="width: 100px" clearable />
</el-form-item>
<!-- 阅片人 -->
<el-form-item style="margin-bottom: 10px" :label="$t('trials:readOrder:table:reader')">
<el-select v-model="searchData.DoctorUserId" style="width: 120px">
<el-option v-for="item of DoctorUserList" :key="'DoctorUserId' + item.DoctorUserId"
:value="item.DoctorUserId" :label="`${item.UserName}(${item.FullName})`" />
</el-select>
</el-form-item>
<!-- 阅片标准 -->
<el-form-item style="margin-bottom: 10px" :label="$t('trials:readOrder:table:criterionName')">
<el-select v-model="searchData.TrialReadingCriterionId" style="width: 120px">
<el-option v-for="item of trialCriterionList"
:key="'TrialReadingCriterionId' + item.TrialReadingCriterionId"
:value="item.TrialReadingCriterionId" :label="item.TrialReadingCriterionName" />
</el-select>
</el-form-item>
<!-- 分配时间 -->
<el-form-item style="margin-bottom: 10px" :label="$t('trials:readOrder:table:assignTime')">
<el-date-picker v-model="timeList" value-format="yyyy-MM-dd HH:mm:ss" type="datetimerange"
:default-time="['00:00:00', '23:59:59']" @change="changeTimeList" />
</el-form-item>
<el-form-item style="margin-bottom: 10px">
<el-button type="primary" icon="el-icon-search" @click="handleSearch">
{{ $t('common:button:search') }}
</el-button>
<el-button type="primary" icon="el-icon-refresh-left" @click="handleReset">
{{ $t('common:button:reset') }}
</el-button>
<!--导出-->
<el-button type="primary" icon="el-icon-download" @click="handleExport">
{{ $t('common:button:export') }}
</el-button>
<!-- 随机排序 -->
<el-button type="primary" @click="randomOrder"
:disabled="!searchData.TrialReadingCriterionId || !searchData.DoctorUserId" v-if="!isAdmin">
{{ $t('trials:readingTracking:button:order') }}
</el-button>
</el-form-item>
</el-form>
</template>
<template slot="main-container">
<el-table v-adaptive="{ bottomOffset: 60 }" v-loading="loading" :data="list" stripe height="100"
@sort-change="handleSortChange">
<!-- 是否加急 -->
<el-table-column prop="IsUrgent" :label="$t('trials:readOrder:table:isUrgent')" min-width="120"
sortable="custom" align="center" style="position: relative">
<template slot-scope="scope">
<el-tooltip placement="top">
<div slot="content">
<span>{{
`${$t('trials:readOrder:label:taskUrgentType')}${$fd(
'TaskUrgentType',
scope.row.TaskUrgentType
)}`
}}</span><br />
<span>{{
scope.row.TaskUrgentRemake
? `${$t('trials:readOrder:label:taskUrgentRemake')}${scope.row.TaskUrgentRemake
}`
: ''
}}</span>
</div>
<div>
<el-button :disabled="!(
!scope.row.TaskState &&
(scope.row.ReadingTaskState === 0 ||
scope.row.ReadingTaskState === 1)
) || !scope.row.IsCanEditUrgentState
" v-if="scope.row.IsUrgent" type="danger" size="mini">{{
$fd('YesOrNo', scope.row.IsUrgent) }}</el-button>
</div>
</el-tooltip>
<el-button :disabled="!(
!scope.row.TaskState &&
(scope.row.ReadingTaskState === 0 ||
scope.row.ReadingTaskState === 1)
) || !scope.row.IsCanEditUrgentState
" v-if="!scope.row.IsUrgent" type="primary" size="mini">{{
$fd('YesOrNo', scope.row.IsUrgent) }}</el-button>
</template>
</el-table-column>
<!-- 临床数据是否完备 -->
<el-table-column prop="CompleteClinicalDataEnum"
:label="$t('trials:readOrder:table:completeClinicalDataEnum')" min-width="160"
show-overflow-tooltip>
<template slot-scope="scope">
<span v-if="scope.row.CompleteClinicalDataEnum === -1">
{{
$fd(
'CompleteClinicalDataEnum',
scope.row.CompleteClinicalDataEnum
)
}}
</span>
<el-button type="text" v-else>
{{
$fd(
'CompleteClinicalDataEnum',
scope.row.CompleteClinicalDataEnum
)
}}
</el-button>
</template>
</el-table-column>
<!-- 中心编号 -->
<el-table-column prop="TrialSiteCode" :label="$t('trials:readOrder:table:siteCode')" min-width="100"
sortable="custom" show-overflow-tooltip />
<!-- 受试者编号 -->
<el-table-column prop="SubjectCode" :label="$t('trials:readOrder:table:subjectCode')" min-width="120"
sortable="custom" show-overflow-tooltip>
<template slot-scope="scope">
<span v-if="
scope.row.BlindSubjectCode &&
scope.row.BlindSubjectCode !== scope.row.SubjectCode
">
{{ `${scope.row.SubjectCode}/${scope.row.BlindSubjectCode}` }}
</span>
<span v-else>{{ scope.row.SubjectCode }}</span>
</template>
</el-table-column>
<!-- 任务名称 -->
<el-table-column prop="VisitTaskNum" :label="$t('trials:readOrder:table:taskName')" min-width="140"
sortable="custom" show-overflow-tooltip>
<template slot-scope="scope">
<span v-if="
scope.row.TaskBlindName &&
scope.row.TaskName !== scope.row.TaskBlindName
">
{{ `${scope.row.TaskName}/${scope.row.TaskBlindName}` }}
</span>
<span v-else>{{ scope.row.TaskName }}</span>
</template>
</el-table-column>
<!-- 阅片人 -->
<el-table-column prop="UserName" :label="$t('trials:readOrder:table:reader')" min-width="130"
sortable="custom" show-overflow-tooltip>
<template v-if="scope.row.UserName" slot-scope="scope">
<span>{{ scope.row.UserName }}({{ scope.row.FullName }})</span>
</template>
</el-table-column>
<!-- 阅片标准 -->
<el-table-column prop="TrialReadingCriterionName" :label="$t('trials:readOrder:table:criterionName')"
min-width="180" sortable="custom" show-overflow-tooltip />
<!-- 分配时间 -->
<el-table-column prop="AllocateTime" :label="$t('trials:readOrder:table:assignTime')" min-width="180"
sortable="custom" show-overflow-tooltip />
<!-- 阅片序号 -->
<el-table-column prop="RandomOrder" :label="$t('trials:readOrder:table:randomOrder')" min-width="180"
sortable="custom" show-overflow-tooltip>
<template slot-scope="scope">
<el-input-number v-model="scope.row.RandomOrder"
@change="(value, old) => handleChange(scope.row, value, old)" :min="0" style="width: 150px;"
v-if="scope.row.ReadingTaskState !== 1 && !isAdmin"></el-input-number>
<span v-else>{{ scope.row.RandomOrder }}</span>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize"
@pagination="getList" />
</template>
</BaseContainer>
</template>
<script>
import { getTrialSiteSelect } from '@/api/trials'
import {
getTrialCriterionList,
getReadingTaskList,
getDoctorUserSelectList,
setRandomTaskOrder
} from '@/api/trials/reading'
import { getReadingTaskList_Export } from '@/api/export'
import BaseContainer from '@/components/BaseContainer'
import Pagination from '@/components/Pagination'
const searchDataDefault = () => {
return {
PageIndex: 1,
PageSize: 20,
Asc: true,
SortField: 'RandomOrder',
TrialId: null,
TrialSiteId: null,
SubjectId: null,
SubjectCode: null,
IsUrgent: null,
TaskName: null,
TaskState: null,
DoctorUserId: null,
ReadingCategory: null,
TaskAllocationState: null,
BeginAllocateDate: null,
EndAllocateDate: null,
ReadingTaskState: null,
CompleteClinicalDataEnum: null,
BeginSignTime: null,
EndSignTime: null,
IsEffect: true,
TrialReadingCriterionId: null,
IsRandomOrderList: true
// ArmEnum: null
}
}
export default {
name: 'ReadOrder',
components: {
BaseContainer,
Pagination,
},
data() {
return {
searchData: searchDataDefault(),
exportVisible: false,
list: [],
siteOptions: [],
total: 0,
SubjectAssignListTotal: 0,
loading: false,
trialCriterionList: [],
DoctorUserList: [],
timeList: []
}
},
created() {
if (!this.hasPermi(['role:pm', 'role:apm', 'role:admin'])) return this.$router.replace("/login")
},
computed: {
isAdmin() {
return !!this.hasPermi(['role:admin'])
}
},
mounted() {
this.getSite()
Promise.all([this.getDoctorUserSelectList(), this.getTrialCriterionList()]).then(() => {
this.getList()
})
},
beforeDestroy() {
if (this.openWindow) {
this.openWindow.close()
}
},
methods: {
//
async handleChange(row, value, old) {
try {
if (!this.searchData.DoctorUserId || !this.searchData.TrialReadingCriterionId) return false
if (!value) throw this.$t('trials:readOrder:message:min1')
let data = {
TrialId: this.$route.query.trialId,
TrialReadingCriterionId: this.searchData.TrialReadingCriterionId,
DoctorUserId: this.searchData.DoctorUserId,
IsAutoSet: false,
SetList: [
{ Id: row.Id, RandomOrder: value }
]
}
this.loading = true;
let res = await setRandomTaskOrder(data)
this.loading = false
if (res.IsSuccess) {
this.getList()
} else {
row.RandomOrder = old
}
} catch (err) {
row.RandomOrder = old
console.log(err)
this.$message.warning(err)
this.getList()
this.loading = false
}
},
//
async randomOrder() {
try {
if (!this.searchData.DoctorUserId || !this.searchData.TrialReadingCriterionId) return false
let data = {
TrialId: this.$route.query.trialId,
TrialReadingCriterionId: this.searchData.TrialReadingCriterionId,
DoctorUserId: this.searchData.DoctorUserId,
IsAutoSet: true,
SetList: []
}
this.loading = true;
let res = await setRandomTaskOrder(data)
this.loading = false
if (res.IsSuccess) {
this.getList()
}
} catch (err) {
console.log(err)
this.loading = false
}
},
async handleExport() {
this.loading = true
try {
await getReadingTaskList_Export(this.searchData)
this.loading = false
} catch (e) {
this.loading = false
}
},
getTrialCriterionList() {
return new Promise((resolve, reject) => {
getTrialCriterionList(this.$route.query.trialId, true)
.then((res) => {
this.trialCriterionList = res.Result
if (this.trialCriterionList.length > 0) {
this.searchData.TrialReadingCriterionId = this.trialCriterionList[0].TrialReadingCriterionId
}
resolve()
})
.catch(() => { reject() })
})
},
getDoctorUserSelectList() {
return new Promise((resolve, reject) => {
getDoctorUserSelectList(this.$route.query.trialId).then((res) => {
this.DoctorUserList = res.Result
if (this.DoctorUserList.length > 0) {
this.searchData.DoctorUserId = this.DoctorUserList[0].DoctorUserId
}
resolve()
}).catch(() => { reject() })
})
},
getList() {
if (!this.searchData.DoctorUserId || !this.searchData.TrialReadingCriterionId) return false
this.searchData.TrialId = this.$route.query.trialId
this.loading = true
getReadingTaskList(this.searchData)
.then((res) => {
this.loading = false
this.list = []
this.$nextTick(() => {
this.list = res.Result.CurrentPageData
this.total = res.Result.TotalCount
})
})
.catch(() => {
this.loading = false
})
},
handleSearch() {
this.searchData.PageIndex = 1
this.getList()
},
handleReset() {
let TrialReadingCriterionId = this.searchData.TrialReadingCriterionId
let DoctorUserId = this.searchData.DoctorUserId
this.searchData = searchDataDefault()
this.searchData.DoctorUserId = DoctorUserId
this.searchData.TrialReadingCriterionId = TrialReadingCriterionId
this.timeList = []
this.getList()
},
getSite() {
getTrialSiteSelect(this.$route.query.trialId).then((res) => {
this.siteOptions = res.Result
})
},
changeTimeList() {
if (this.timeList) {
this.searchData.BeginAllocateDate = this.timeList[0]
this.searchData.EndAllocateDate = this.timeList[1]
} else {
this.searchData.BeginAllocateDate = null
this.searchData.EndAllocateDate = null
}
},
//
handleSortChange(column) {
if (column.order === 'ascending') {
this.searchData.Asc = true
} else {
this.searchData.Asc = false
}
this.searchData.SortField = column.prop
this.searchData.PageIndex = 1
this.getList()
},
},
}
</script>
<style lang="scss" scoped>
.title {
line-height: 40px;
font-weight: bold;
margin-bottom: 10px;
}
</style>
@@ -1018,28 +1018,34 @@ export default {
return
}
if (v.DataType === 'ImageList') {
if (obj[v.Code] && obj[v.Code].length > 0) {
// if (obj[v.Code] && obj[v.Code].length > 0) {
if (obj[v.Code]) {
obj[v.Code] = obj[v.Code].filter(s => s && s.trim())
// obj[v.Code].forEach((o,i) => {
// var uo = upObj && upObj.length > 0 ? upObj[v.Code][i] : 0
if (row.OptType === 'Add' || row.OptType === 'Init') {
item = {
key: v.Code,
Enum: this.$i18n.locale === 'zh' ? v.ValueCN : v.Value,
newValue: obj[v.Code] ? obj[v.Code] : '--',
// newValue: obj[v.Code] ? obj[v.Code] : '--',
newValue: obj[v.Code] && obj[v.Code].length > 0 ? obj[v.Code] : '--',
oldValue: ''
}
} else if (row.OptType === 'Delete') {
item = {
key: v.Code,
Enum: this.$i18n.locale === 'zh' ? v.ValueCN : v.Value,
oldValue: obj[v.Code] ? obj[v.Code] : '--',
// oldValue: obj[v.Code] ? obj[v.Code] : '--',
oldValue: obj[v.Code] && obj[v.Code].length > 0 ? obj[v.Code] : '--',
newValue: '--'
}
} else {
item = {
key: v.Code,
Enum: this.$i18n.locale === 'zh' ? v.ValueCN : v.Value,
newValue: obj[v.Code] ? obj[v.Code] : '--',
// newValue: obj[v.Code] ? obj[v.Code] : '--',
newValue: obj[v.Code] && obj[v.Code].length > 0 ? obj[v.Code] : '--',
oldValue: upObj[v.Code].length > 0 ? upObj[v.Code] : '--'
}
}
@@ -1082,14 +1088,17 @@ export default {
}
if (v.DataType === 'Router') {
item = {
oldValue: v.UrlConfig.IsHaveParameters ? v.UrlConfig.RoutePath + '?' +
v.UrlConfig.ParameterList.map((v) => {
let a = obj[v.UrlParameterValueName] ? obj[v.UrlParameterValueName] : parentRow[v.UrlParameterValueName]
if (v.UrlParameterValueName === 'token') {
a = getToken()
}
return v.UrlParameterName + '=' + a + '&'
}).toString().replaceAll(',', '')+'&'+'lang='+this.$i18n.locale +'&'+ 'zh='+this.$i18n.locale : v.UrlConfig.RoutePath,
// oldValue: v.UrlConfig.IsHaveParameters ? v.UrlConfig.RoutePath + '?' +
// v.UrlConfig.ParameterList.map((v) => {
// let a = obj[v.UrlParameterValueName] ? obj[v.UrlParameterValueName] : parentRow[v.UrlParameterValueName]
// if (v.UrlParameterValueName === 'token') {
// a = getToken()
// }
// return v.UrlParameterName + '=' + a + '&'
// }).toString().replaceAll(',', '')+'&'+'lang='+this.$i18n.locale +'&'+ 'zh='+this.$i18n.locale : v.UrlConfig.RoutePath,
// 25/06/13
oldValue: '--',
newValue: v.UrlConfig.IsHaveParameters ? v.UrlConfig.RoutePath + '?' +
v.UrlConfig.ParameterList.map((v) => {
let a = obj[v.UrlParameterValueName] ? obj[v.UrlParameterValueName] : parentRow[v.UrlParameterValueName]
@@ -359,7 +359,6 @@ export default {
status: 'add',
upload: null,
},
DATA: {},
doctorList: [],
}
},
@@ -632,12 +631,6 @@ export default {
},
immediate: true,
},
rowData: {
handler() {
this.DATA = Object.assign({}, this.rowData)
},
immediate: true,
},
},
created() {
let typeArr = ['', 'Report', 'Doc', 'Record', 'Reviewer', 'Template']
@@ -1,11 +1,11 @@
<template>
<div v-loading="loading" class="chat-wrapper">
<div v-if="recordContent.length>0" class="chat-content">
<div v-for="(record,index) in recordContent" :key="`${record.CreateTime}${index}`">
<div v-if="recordContent.length > 0" class="chat-content">
<div v-for="(record, index) in recordContent" :key="`${record.CreateTime}${index}`">
<div v-if="!record.IsCurrentUser" class="word">
<img v-if="record.UserTypeEnum*1 === 8" :src="adminAvatar" alt="Admin">
<img v-else-if="record.UserTypeEnum*1 === 1" :src="pmAvatar" alt="PM">
<img v-else-if="record.UserTypeEnum*1 === 2" :src="crcAvatar" alt="CRC">
<img v-if="record.UserTypeEnum * 1 === 8" :src="adminAvatar" alt="Admin">
<img v-else-if="record.UserTypeEnum * 1 === 1" :src="pmAvatar" alt="PM">
<img v-else-if="record.UserTypeEnum * 1 === 2" :src="crcAvatar" alt="CRC">
<div class="info">
<p class="user-info">
<span style="font-weight:700;">{{ record.CreateUserName }} </span>
@@ -24,9 +24,9 @@
<div class="info-content" v-html="record.TalkContent" />
</div>
<!-- <img :src="record.headUrl"> -->
<img v-if="record.UserTypeEnum*1 === 8" :src="adminAvatar" alt="Admin">
<img v-else-if="record.UserTypeEnum*1 === 1" :src="pmAvatar" alt="PM">
<img v-else-if="record.UserTypeEnum*1 === 2" :src="crcAvatar" alt="CRC">
<img v-if="record.UserTypeEnum * 1 === 8" :src="adminAvatar" alt="Admin">
<img v-else-if="record.UserTypeEnum * 1 === 1" :src="pmAvatar" alt="PM">
<img v-else-if="record.UserTypeEnum * 1 === 2" :src="crcAvatar" alt="CRC">
</div>
</div>
</div>
@@ -36,83 +36,50 @@
</div>
<div v-if="checkChallengeState !== 3 && checkState !== 11" class="chat-message">
<div class="message">
<el-input
v-model="newMessage"
v-hasPermi="['trials:trials-panel:visit:consistency-check:fallback']"
type="textarea"
:rows="2"
/>
<el-input v-model="newMessage" v-hasPermi="['trials:trials-panel:visit:consistency-check:fallback']"
type="textarea" :rows="2" />
</div>
<div class="function">
<!-- 申请回退 -->
<el-button
v-hasPermi="['trials:trials-panel:visit:consistency-check:apply-fallback']"
type="primary"
<el-button v-hasPermi="['trials:trials-panel:visit:consistency-check:apply-fallback']" type="primary"
:disabled="!(checkState === 10 && (requestBackState === 0 || requestBackState === 3))"
@click="handleApplyBack"
>
@click="handleApplyBack">
{{ $t('trials:consistencyCheck:action:applyFallback') }}
</el-button>
<!-- 拒绝回退 -->
<el-button
v-hasPermi="['trials:trials-panel:visit:consistency-check:fallback']"
type="primary"
:disabled="!(requestBackState === 1)"
@click="handleRejectBack"
>
<el-button v-hasPermi="['trials:trials-panel:visit:consistency-check:fallback']" type="primary"
:disabled="!(requestBackState === 1)" @click="handleRejectBack">
{{ $t('trials:consistencyCheck:button:rejectBack') }}
</el-button>
<!-- 回退 -->
<el-button
v-hasPermi="['trials:trials-panel:visit:consistency-check:fallback']"
type="primary"
:disabled="!(requestBackState === 1)"
@click="handleBack"
>
<el-button v-hasPermi="['trials:trials-panel:visit:consistency-check:fallback']" type="primary"
:disabled="!(requestBackState === 1)" @click="handleBack">
{{ $t('trials:consistencyCheck:action:fallback') }}
</el-button>
<!-- 发送 -->
<el-button
v-hasPermi="['role:pm']"
:disabled="!(checkState === 10 && checkChallengeState !== 3) || newMessage === ''"
type="primary"
:loading="btnLoading"
@click="handleReply()"
>
<el-button v-hasPermi="['role:pm']"
:disabled="!(checkState === 10 && checkChallengeState !== 3) || newMessage === ''" type="primary"
:loading="btnLoading" @click="handleReply()">
{{ $t('trials:consistencyCheck:button:sendMessage') }}
</el-button>
<!-- 回复 -->
<el-button
v-hasPermi="['role:crc']"
<el-button v-hasPermi="['role:crc']" type="primary"
:disabled="!(checkState === 10 && checkChallengeState !== 3) || (recordContent && recordContent.length > 0 ? recordContent[recordContent.length - 1].UserTypeEnum * 1 === 2 : false)"
type="primary"
:loading="btnLoading"
@click="handleCRCReply"
>
:loading="btnLoading" @click="handleCRCReply">
{{ $t('trials:consistencyCheck:title:reply') }}
</el-button>
<!-- 关闭 -->
<el-button
type="primary"
:loading="btnLoading"
@click="close"
>
<el-button type="primary" :loading="btnLoading" @click="close">
{{ $t('trials:consistencyCheck:title:close') }}
</el-button>
</div>
</div>
<!-- 回复一致性核查 -->
<el-dialog
v-if="sendMessageCRCVisible"
v-dialogDrag
:visible.sync="sendMessageCRCVisible"
:close-on-click-modal="false"
append-to-body
custom-class="base-dialog-wrapper"
:width="'600px'"
:title="$t('trials:consistencyCheck:title:replyConsistency')"
>
<crcSendMessage :crc-message-info="crcMessageInfo" @sendMessage="handleReply" />
<el-dialog v-if="sendMessageCRCVisible" v-dialogDrag :visible.sync="sendMessageCRCVisible"
:close-on-click-modal="false" append-to-body custom-class="base-dialog-wrapper" :width="'600px'"
:title="$t('trials:consistencyCheck:title:replyConsistency')">
<crcSendMessage :crc-message-info="crcMessageInfo" :visible.sync="sendMessageCRCVisible"
@sendMessage="handleReply" />
</el-dialog>
</div>
</template>
@@ -277,46 +244,54 @@ export default {
}
</script>
<style lang="scss">
.chat-wrapper{
::-webkit-scrollbar {
.chat-wrapper {
::-webkit-scrollbar {
width: 7px;
height: 7px;
}
::-webkit-scrollbar-thumb {
border-radius: 10px;
background: #d0d0d0;
}
.chat-content{
width:100%;
.chat-content {
width: 100%;
padding: 20px;
height: 500px;
overflow-y: auto;
.word{
.word {
display: flex;
margin-bottom: 20px;
img{
width:40px;
img {
width: 40px;
height: 40px;
border-radius: 50%;
}
.info{
.info {
margin-left: 10px;
.user-info{
.user-info {
font-size: 12px;
color:rgba(51,51,51,0.8);
margin:0;
color: rgba(51, 51, 51, 0.8);
margin: 0;
height: 20px;
line-height: 20px;
margin-top: -5px;
}
.info-content{
.info-content {
padding: 10px;
font-size: 14px;
background-color: #ebeef5;
position: relative;
margin-top: 8px;
}
.info-content::before{
.info-content::before {
position: absolute;
left: -8px;
top: 8px;
@@ -327,29 +302,34 @@ export default {
}
}
}
.word-my{
.word-my {
display: flex;
justify-content: flex-end;
margin-bottom: 20px;
img{
img {
width: 40px;
height: 40px;
border-radius: 50%;
}
.info{
.info {
width: 90%;
margin-left: 10px;
text-align: right;
.user-info{
.user-info {
font-size: 12px;
color: rgba(51,51,51,0.8);
color: rgba(51, 51, 51, 0.8);
margin: 0;
height: 20px;
line-height: 20px;
margin-top: -5px;
margin-right: 10px;
}
.info-content{
.info-content {
position: relative;
max-width: 70%;
padding: 10px;
@@ -361,7 +341,8 @@ export default {
color: #fff;
text-align: left;
}
.info-content::after{
.info-content::after {
position: absolute;
right: -8px;
top: 8px;
@@ -373,9 +354,11 @@ export default {
}
}
}
.chat-message{
.chat-message {
padding: 0 50px;
.function{
.function {
margin-top: 10px;
text-align: right;
}
@@ -51,8 +51,8 @@
</template>
</el-table-column>
</el-table>
<el-form ref="revenusForm" size="small" label-width="400px" :label-position="'top'" :rules="rules"
:model="form">
<el-form ref="revenusForm" size="small" label-width="400px" :label-position="'top'" :rules="rules" :model="form"
v-if="false">
<!-- IRC与实际情况影像检查不一致的原因为 -->
<el-form-item v-if="isLackOf" :label="$t('trials:consistencyCheck:title:title1')" prop="reason">
<el-checkbox-group v-model="form.reason" style="display: flex;flex-direction: column">
@@ -71,6 +71,10 @@
</div>
</div>
<div class="function">
<!-- 取消 -->
<el-button @click="close">
{{ $t('common:button:cancel') }}
</el-button>
<!-- 发送 -->
<el-button type="primary" @click="handleReply">
{{ $t('trials:consistencyCheck:button:sendMessage') }}
@@ -118,6 +122,10 @@ export default {
TalkContent: null
}
}
},
visible: {
type: Boolean,
default: false
}
},
data() {
@@ -149,6 +157,9 @@ export default {
this.compareStudy()
},
methods: {
close() {
this.$emit('update:visible', false)
},
compareStudy() {
var isLackOf = false
this.IRCList = []
@@ -204,8 +215,8 @@ export default {
this.$alert(this.$t('trials:consistencyCheck:title:title4'))
return
}
let valid = await this.$refs.revenusForm.validate()
if (!valid) return
// let valid = await this.$refs.revenusForm.validate()
// if (!valid) return
let confirm = true
if (this.msgList.every(item => !item.IsCheck)) {
confirm = await this.$confirm(this.$t('trials:consistencyCheck:title:confirm'), '', {
@@ -231,6 +242,7 @@ export default {
TalkContent += message
})
if (this.isLackOf) {
TalkContent += `<br>${this.$t('trials:consistencyCheck:title:title13')}`
// TalkContent += '<br>'
// // 'IRC<br>'
// TalkContent += `${this.$t('trials:consistencyCheck:title:title7')}<br>`
@@ -239,21 +251,23 @@ export default {
// msg = msg.replace('xxx', v.Modality)
// TalkContent += `${i + 1}.${msg}${v.IsJoin && !v.IsCheck ? this.$t('trials:consistencyCheck:title:title8') : this.$t('trials:consistencyCheck:title:title9')}<br>`
// })
if (this.form.reason.length > 0) {
TalkContent += '<br>'
// 'IRC<br>'
TalkContent += `${this.$t('trials:consistencyCheck:title:title10')}<br>`
this.form.reason.forEach((v, i) => {
TalkContent += `${i + 1}.${v}<br>`
})
}
// if (this.form.reason.length > 0) {
// TalkContent += '<br>'
// // 'IRC<br>'
// TalkContent += `${this.$t('trials:consistencyCheck:title:title10')}<br>`
// this.form.reason.forEach((v, i) => {
// TalkContent += `${i + 1}.${v}<br>`
// })
// }
} else {
// `<br>IRC`
TalkContent += `<br>${this.$t('trials:consistencyCheck:title:title11')}<br>`
TalkContent += '<br>'
TalkContent += `${this.$t('trials:consistencyCheck:title:title10')}<br>`
TalkContent += `1.${this.$t('trials:consistencyCheck:title:message10')}<br>`
TalkContent += `<br>${this.$t('trials:consistencyCheck:title:title11')}`
// TalkContent += '<br>'
// TalkContent += `${this.$t('trials:consistencyCheck:title:title10')}<br>`
// TalkContent += `1.${this.$t('trials:consistencyCheck:title:message10')}<br>`
}
console.log(TalkContent)
this.$emit('sendMessage', TalkContent, this.closeLoading)
@@ -952,19 +952,19 @@ export default {
) {
++instanceIndex
}
if (instanceIndex >= fileList.length) {
fileList.push({
instanceUid: instanceUid,
file: file,
})
}
scope.uploadQueues[studyIndex].dicomInfo.fileCount = fileList.length
scope.uploadQueues[studyIndex].dicomInfo.fileSize = fileList.reduce(
(prev, next) => {
return prev + next.file.size
},
0
)
// if (instanceIndex >= fileList.length) {
// fileList.push({
// instanceUid: instanceUid,
// file: file,
// })
// }
// scope.uploadQueues[studyIndex].dicomInfo.fileCount = fileList.length
// scope.uploadQueues[studyIndex].dicomInfo.fileSize = fileList.reduce(
// (prev, next) => {
// return prev + next.file.size
// },
// 0
// )
var seriesUid = data.string('x0020000e')
var seriesList = scope.uploadQueues[studyIndex].seriesList
@@ -1065,6 +1065,19 @@ export default {
}
instanceList.push(instanceItem)
}
if (instanceIndex >= fileList.length) {
fileList.push({
instanceUid: instanceUid,
file: file,
})
}
scope.uploadQueues[studyIndex].dicomInfo.fileCount = fileList.length
scope.uploadQueues[studyIndex].dicomInfo.fileSize = fileList.reduce(
(prev, next) => {
return prev + next.file.size
},
0
)
resolve()
} catch (error) {
console.log(error)
@@ -320,7 +320,7 @@
scope.row.IsLostVisit
" circle :title="$t('trials:crcUpload:action:submit')" @click="handleSubmit(scope.row)" />
<!-- 退回 -->
<el-button :disabled="scope.row.SubmitState * 1 < 2 || scope.row.IsImageBackApplying
<el-button :disabled="scope.row.SubmitState * 1 < 2 || scope.row.IsImageBackApplying || scope.row.ChallengeState * 1 === 2
" v-hasPermi="['trials:trials-panel:visit:crc-upload:back']" icon="el-icon-back" circle
:title="$t('trials:crcUpload:action:back')" @click="imageBack(scope.row)" />
<!-- 编辑 -->
@@ -393,7 +393,8 @@
scope.row.CurrentActionUserId !== userId
|| scope.row.IsImageBackApplying" @click="handleSecondaryQC(scope.row)" />
<!-- 退回 -->
<el-button :disabled="scope.row.SubmitState * 1 < 2 || scope.row.IsImageBackApplying"
<el-button
:disabled="scope.row.SubmitState * 1 < 2 || scope.row.IsImageBackApplying || scope.row.ChallengeState * 1 === 2"
v-hasPermi="['trials:trials-panel:visit:qc-check:back']" icon="el-icon-back" circle
:title="$t('trials:qcCheck:button:back')" @click="imageBack(scope.row)" />
</div>
@@ -194,10 +194,10 @@
<template slot="dialog-body">
<el-form ref="imageBackform" :model="form" class="demo-form-inline" :rules="rules"
:label-width="isEN ? '150px' : '100px'">
<el-form-item :label="$t('trials:reuploadAudit:table:Matters') + ': '" prop="Matters">
<el-form-item :label="$t('trials:reuploadAudit:table:Matters')" prop="Matters">
<span>{{ rowData.title }}</span>
</el-form-item>
<el-form-item :label="$t('trials:reuploadAudit:table:ApplyReason') + ': '" prop="ApplyReason">
<el-form-item :label="$t('trials:reuploadAudit:form:ApplyReason')" prop="ApplyReason">
<span>{{ rowData.ApplyReason }}</span>
</el-form-item>
<el-form-item :label="$t('trials:reuploadAudit:form:IsAgree')" prop="IsAgree">
@@ -206,7 +206,7 @@
<el-radio :label="false">{{ $t('trials:reuploadAudit:button:auditNo') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item :label="$t('trials:reuploadAudit:table:ResultRemark') + ': '" prop="ResultRemark">
<el-form-item :label="$t('trials:reuploadAudit:form:ResultRemark')" prop="ResultRemark">
<el-input type="textarea" :autosize="{ minRows: 2, maxRows: 4 }" placeholder=""
v-model="form.ResultRemark">
</el-input>
+1 -1
View File
@@ -97,7 +97,7 @@ module.exports = defineConfig({
]
}),
// new BundleAnalyzerPlugin(),
process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'prod' || process.env.NODE_ENV === 'production' || process.env.VUE_APP_OSS_CONFIG_BUCKET === 'zyypacs-usa' ? function () { }
process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'production' || process.env.VUE_APP_OSS_CONFIG_BUCKET === 'zyypacs-usa' ? function () { }
: new WebpackAliyunOss({
from: ['./dist/**'],
dist: process.env.VUE_APP_OSS_PATH + distDate,