Compare commits
20 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
0b9f33b36f | |
|
|
8bdac9bd6e | |
|
|
97a406d32a | |
|
|
f47db19702 | |
|
|
f3610b685a | |
|
|
3cf1cf5f91 | |
|
|
8315bcf59f | |
|
|
653faaf4ba | |
|
|
aa92776b31 | |
|
|
5bbbd9334e | |
|
|
fcd6efaa39 | |
|
|
b7de254b5f | |
|
|
9256970662 | |
|
|
c53890add7 | |
|
|
23fb7be52b | |
|
|
4e5c9aaf38 | |
|
|
52bb39d6c2 | |
|
|
cbd860a35e | |
|
|
7e9eb1f3a5 | |
|
|
254e43ac3d |
|
|
@ -80,7 +80,7 @@
|
||||||
import * as cornerstone from 'cornerstone-core'
|
import * as cornerstone from 'cornerstone-core'
|
||||||
import * as cornerstoneMath from 'cornerstone-math'
|
import * as cornerstoneMath from 'cornerstone-math'
|
||||||
import * as cornerstoneTools from 'cornerstone-tools'
|
import * as cornerstoneTools from 'cornerstone-tools'
|
||||||
import metaDataProvider from '@/utils/metaDataProvider'
|
import metaDataProvider, { registerImageSharedCacheKey, unregisterImageSharedCacheKeys } from '@/utils/metaDataProvider'
|
||||||
|
|
||||||
const scroll = cornerstoneTools.import('util/scrollToIndex')
|
const scroll = cornerstoneTools.import('util/scrollToIndex')
|
||||||
import Hammer from 'hammerjs'
|
import Hammer from 'hammerjs'
|
||||||
|
|
@ -211,6 +211,9 @@ export default {
|
||||||
this.stackScrollCallback
|
this.stackScrollCallback
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
unregisterImageSharedCacheKeys(this.stack?.imageIds)
|
||||||
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
loadImageStack(dicomSeries, text = '') {
|
loadImageStack(dicomSeries, text = '') {
|
||||||
|
|
@ -400,6 +403,10 @@ export default {
|
||||||
},
|
},
|
||||||
onNewImage(e) {
|
onNewImage(e) {
|
||||||
e.detail.enabledElement.options = {}
|
e.detail.enabledElement.options = {}
|
||||||
|
registerImageSharedCacheKey(
|
||||||
|
e.detail.image?.imageId,
|
||||||
|
e.detail.image?.sharedCacheKey
|
||||||
|
)
|
||||||
var data = e.detail.image.data
|
var data = e.detail.image.data
|
||||||
this.dicomInfo.hospital = data.string('x00080080')
|
this.dicomInfo.hospital = data.string('x00080080')
|
||||||
// let instanceInfo = this.series.instanceInfoList.find(item => item.ImageId === e.detail.image.imageId)
|
// let instanceInfo = this.series.instanceInfoList.find(item => item.ImageId === e.detail.image.imageId)
|
||||||
|
|
|
||||||
|
|
@ -477,7 +477,10 @@ export default {
|
||||||
let res = await getSubjectImageUploadList(params)
|
let res = await getSubjectImageUploadList(params)
|
||||||
this.loading = false
|
this.loading = false
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
this.isDownloaded = res.OtherInfo.IsIRImageDownloaded
|
this.isDownloaded = this.Criterion && this.Criterion.CriterionType && (
|
||||||
|
this.Criterion.CriterionType == 19 ||
|
||||||
|
this.Criterion.CriterionType == 20
|
||||||
|
) ? res.OtherInfo.IsIRImageDownloaded : true
|
||||||
this.TrialModality = res.OtherInfo.TrialModality.split('|')
|
this.TrialModality = res.OtherInfo.TrialModality.split('|')
|
||||||
this.IsReadingTaskViewInOrder = res.OtherInfo.IsReadingTaskViewInOrder || res.OtherInfo.IsReadingTaskViewInOrder === 0 ? res.OtherInfo.IsReadingTaskViewInOrder : 2
|
this.IsReadingTaskViewInOrder = res.OtherInfo.IsReadingTaskViewInOrder || res.OtherInfo.IsReadingTaskViewInOrder === 0 ? res.OtherInfo.IsReadingTaskViewInOrder : 2
|
||||||
this.StudyInstanceUidList = []
|
this.StudyInstanceUidList = []
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@
|
||||||
<span v-else>{{ scope.row.UploadedFileCount }}</span>
|
<span v-else>{{ scope.row.UploadedFileCount }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column :label="$t('common:action:action')" fixed="right" width="180">
|
<el-table-column :label="$t('common:action:action')" width="180">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<!--预览--->
|
<!--预览--->
|
||||||
<el-button circle :disabled="scope.row.UploadedFileCount <= 0" icon="el-icon-view"
|
<el-button circle :disabled="scope.row.UploadedFileCount <= 0" icon="el-icon-view"
|
||||||
|
|
@ -353,7 +353,10 @@ export default {
|
||||||
if (res.IsSuccess) {
|
if (res.IsSuccess) {
|
||||||
this.list = res.Result
|
this.list = res.Result
|
||||||
this.relationInfo = res.OtherInfo
|
this.relationInfo = res.OtherInfo
|
||||||
this.isDownloaded = res.OtherInfo.IsIRImageDownloaded
|
this.isDownloaded = this.Criterion && this.Criterion.CriterionType && (
|
||||||
|
this.Criterion.CriterionType == 19 ||
|
||||||
|
this.Criterion.CriterionType == 20
|
||||||
|
) ? res.OtherInfo.IsIRImageDownloaded : true
|
||||||
this.faccept = []
|
this.faccept = []
|
||||||
this.relationInfo.ImageFormatList.forEach((item) => {
|
this.relationInfo.ImageFormatList.forEach((item) => {
|
||||||
this.faccept.push(`.${item}`)
|
this.faccept.push(`.${item}`)
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,25 @@ function parseImageId(imageId) {
|
||||||
|
|
||||||
return { scheme, url, frame };
|
return { scheme, url, frame };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const imageIdToSharedCacheKey = new Map();
|
||||||
|
|
||||||
|
export function registerImageSharedCacheKey(imageId, sharedCacheKey) {
|
||||||
|
if (!imageId || !sharedCacheKey) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
imageIdToSharedCacheKey.set(imageId, sharedCacheKey);
|
||||||
|
}
|
||||||
|
export function unregisterImageSharedCacheKeys(imageIds) {
|
||||||
|
if (!Array.isArray(imageIds) || imageIds.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
imageIds.forEach((imageId) => {
|
||||||
|
if (imageId) {
|
||||||
|
imageIdToSharedCacheKey.delete(imageId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
function getNumberValues(dataSet, tag, minimumLength) {
|
function getNumberValues(dataSet, tag, minimumLength) {
|
||||||
const values = [];
|
const values = [];
|
||||||
const valueAsString = dataSet.string(tag);
|
const valueAsString = dataSet.string(tag);
|
||||||
|
|
@ -257,10 +276,20 @@ function getSpacingBetweenSlices(dataSet) {
|
||||||
}
|
}
|
||||||
function metaDataProvider(type, imageId) {
|
function metaDataProvider(type, imageId) {
|
||||||
const parsedImageId = parseImageId(imageId);
|
const parsedImageId = parseImageId(imageId);
|
||||||
const dataSet = cornerstoneWADOImageLoader.wadouri.dataSetCacheManager.get(
|
let dataSet = cornerstoneWADOImageLoader.wadouri.dataSetCacheManager.get(
|
||||||
parsedImageId.url
|
parsedImageId.url
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (!dataSet) {
|
||||||
|
const sharedCacheKey = imageIdToSharedCacheKey.get(imageId);
|
||||||
|
|
||||||
|
if (sharedCacheKey) {
|
||||||
|
dataSet = cornerstoneWADOImageLoader.wadouri.dataSetCacheManager.get(
|
||||||
|
sharedCacheKey
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!dataSet) {
|
if (!dataSet) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -421,7 +450,6 @@ function metaDataProvider(type, imageId) {
|
||||||
let columnPixelSpacing = null;
|
let columnPixelSpacing = null;
|
||||||
|
|
||||||
let rowPixelSpacing = null;
|
let rowPixelSpacing = null;
|
||||||
|
|
||||||
if (pixelSpacing) {
|
if (pixelSpacing) {
|
||||||
rowPixelSpacing = pixelSpacing[0];
|
rowPixelSpacing = pixelSpacing[0];
|
||||||
columnPixelSpacing = pixelSpacing[1];
|
columnPixelSpacing = pixelSpacing[1];
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,11 @@ function zipFiles(zipName, files) {
|
||||||
store.dispatch('trials/setUnLock', true)
|
store.dispatch('trials/setUnLock', true)
|
||||||
files = formatFiles(files)
|
files = formatFiles(files)
|
||||||
// 创建压缩文件输出流
|
// 创建压缩文件输出流
|
||||||
const zipFileOutputStream = streamSaver.createWriteStream(zipName);
|
let zipFileOutputStream = streamSaver.createWriteStream(zipName);
|
||||||
// 创建下载文件流
|
// 创建下载文件流
|
||||||
const fileIterator = files.values();
|
const fileIterator = files.values();
|
||||||
const readableZipStream = new ZIP({
|
let Url = [];
|
||||||
|
let readableZipStream = new ZIP({
|
||||||
async pull(ctrl) {
|
async pull(ctrl) {
|
||||||
const fileInfo = fileIterator.next();
|
const fileInfo = fileIterator.next();
|
||||||
if (fileInfo.done) {//迭代终止
|
if (fileInfo.done) {//迭代终止
|
||||||
|
|
@ -23,6 +24,7 @@ function zipFiles(zipName, files) {
|
||||||
let { name, url, IsEncapsulated = false } = fileInfo.value;
|
let { name, url, IsEncapsulated = false } = fileInfo.value;
|
||||||
if (IsEncapsulated) {
|
if (IsEncapsulated) {
|
||||||
url = await downloadFileToUrl(url)
|
url = await downloadFileToUrl(url)
|
||||||
|
Url.push(url)
|
||||||
}
|
}
|
||||||
// url = decodeUtf8(url); // 待定,可能做过特殊处理
|
// url = decodeUtf8(url); // 待定,可能做过特殊处理
|
||||||
return fetch(url).then(res => {
|
return fetch(url).then(res => {
|
||||||
|
|
@ -40,13 +42,31 @@ function zipFiles(zipName, files) {
|
||||||
.pipeTo(zipFileOutputStream)
|
.pipeTo(zipFileOutputStream)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
console.log("同步下载打包结束时间:" + new Date());
|
console.log("同步下载打包结束时间:" + new Date());
|
||||||
store.dispatch('trials/setUnLock', false)
|
|
||||||
resolve(true)
|
resolve(true)
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
resolve(false)
|
resolve(false)
|
||||||
|
}).finally(() => {
|
||||||
|
store.dispatch('trials/setUnLock', false)
|
||||||
|
readableZipStream = null;
|
||||||
|
zipFileOutputStream = null;
|
||||||
|
if (Url && Url.length > 0) {
|
||||||
|
Url.forEach(url => {
|
||||||
|
URL.revokeObjectURL(url)
|
||||||
|
})
|
||||||
|
Url = null
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
store.dispatch('trials/setUnLock', false)
|
||||||
|
readableZipStream = null;
|
||||||
|
zipFileOutputStream = null;
|
||||||
|
if (Url && Url.length > 0) {
|
||||||
|
Url.forEach(url => {
|
||||||
|
URL.revokeObjectURL(url)
|
||||||
|
})
|
||||||
|
Url = null
|
||||||
|
}
|
||||||
resolve(false)
|
resolve(false)
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
@ -61,15 +81,17 @@ async function updateFile(file, name) {
|
||||||
return new Promise(async resolve => {
|
return new Promise(async resolve => {
|
||||||
try {
|
try {
|
||||||
store.dispatch('trials/setUnLock', true)
|
store.dispatch('trials/setUnLock', true)
|
||||||
const fileOutputStream = streamSaver.createWriteStream(name);
|
let fileOutputStream = streamSaver.createWriteStream(name);
|
||||||
// file = decodeUtf8(file);
|
// file = decodeUtf8(file);
|
||||||
let res = await fetch(file);
|
let res = await fetch(file);
|
||||||
res.body.pipeTo(fileOutputStream).then(() => {
|
res.body.pipeTo(fileOutputStream).then(() => {
|
||||||
store.dispatch('trials/setUnLock', true)
|
|
||||||
resolve(true)
|
resolve(true)
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.log(err)
|
console.log(err)
|
||||||
resolve(false)
|
resolve(false)
|
||||||
|
}).finally(() => {
|
||||||
|
store.dispatch('trials/setUnLock', false)
|
||||||
|
fileOutputStream = null;
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err)
|
console.log(err)
|
||||||
|
|
@ -110,6 +132,7 @@ function downloadFileToUrl(url) {
|
||||||
xhr.open('GET', url);
|
xhr.open('GET', url);
|
||||||
xhr.responseType = 'arraybuffer';
|
xhr.responseType = 'arraybuffer';
|
||||||
xhr.onload = function () {
|
xhr.onload = function () {
|
||||||
|
try {
|
||||||
const arraybuffer = xhr.response;
|
const arraybuffer = xhr.response;
|
||||||
let dataset = dcmjs.data.DicomMessage.readFile(arraybuffer)
|
let dataset = dcmjs.data.DicomMessage.readFile(arraybuffer)
|
||||||
let newDicomFile = dataset.write({ fragmentMultiframe: false, startOffset: false }) // fragmentMultiframe 原始数据是否进行分割
|
let newDicomFile = dataset.write({ fragmentMultiframe: false, startOffset: false }) // fragmentMultiframe 原始数据是否进行分割
|
||||||
|
|
@ -117,6 +140,9 @@ function downloadFileToUrl(url) {
|
||||||
const blob = new Blob([bufferArray], { type: 'application/octet-stream' })
|
const blob = new Blob([bufferArray], { type: 'application/octet-stream' })
|
||||||
const href = URL.createObjectURL(blob)
|
const href = URL.createObjectURL(blob)
|
||||||
resolve(href)
|
resolve(href)
|
||||||
|
} catch (err) {
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
xhr.send();
|
xhr.send();
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ import { mapGetters } from 'vuex'
|
||||||
import Contextmenu from 'vue-contextmenujs'
|
import Contextmenu from 'vue-contextmenujs'
|
||||||
Vue.use(Contextmenu)
|
Vue.use(Contextmenu)
|
||||||
import * as cornerstone from 'cornerstone-core'
|
import * as cornerstone from 'cornerstone-core'
|
||||||
import metaDataProvider from '@/utils/metaDataProvider'
|
import metaDataProvider, { registerImageSharedCacheKey, unregisterImageSharedCacheKeys } from '@/utils/metaDataProvider'
|
||||||
|
|
||||||
import * as cornerstoneMath from 'cornerstone-math'
|
import * as cornerstoneMath from 'cornerstone-math'
|
||||||
import * as cornerstoneTools from 'cornerstone-tools'
|
import * as cornerstoneTools from 'cornerstone-tools'
|
||||||
|
|
@ -480,6 +480,7 @@ export default {
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
// Store.$off('getMeasureData')
|
// Store.$off('getMeasureData')
|
||||||
|
unregisterImageSharedCacheKeys(this.stack?.imageIds)
|
||||||
DicomEvent.$off('setReadingState')
|
DicomEvent.$off('setReadingState')
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -1279,6 +1280,7 @@ export default {
|
||||||
this.resetHideMeasureArr()
|
this.resetHideMeasureArr()
|
||||||
}
|
}
|
||||||
const { image } = e.detail
|
const { image } = e.detail
|
||||||
|
registerImageSharedCacheKey(image?.imageId, image?.sharedCacheKey)
|
||||||
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
||||||
const imageId = image.imageId
|
const imageId = image.imageId
|
||||||
ToolStateManager.clearImageIdToolState(imageId)
|
ToolStateManager.clearImageIdToolState(imageId)
|
||||||
|
|
|
||||||
|
|
@ -189,11 +189,22 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 计算值 -->
|
<!-- 计算值 -->
|
||||||
<Questions ref="ecrf2" :question-form-change-state="true" :question-form-change-num="0" :is-qulity-issues="false"
|
<Questions
|
||||||
:group-classify="4" style="margin-top:20px" />
|
ref="ecrf2"
|
||||||
|
:question-form-change-state="true"
|
||||||
|
:question-form-change-num="0"
|
||||||
|
:is-qulity-issues="false"
|
||||||
|
:group-classify="4"
|
||||||
|
:question-type="12"
|
||||||
|
style="margin-top:20px" />
|
||||||
|
|
||||||
<!-- 评估结果 -->
|
<!-- 评估结果 -->
|
||||||
<Questions ref="ecrf3" :question-form-change-state="true" :question-form-change-num="0" :is-qulity-issues="false"
|
<Questions
|
||||||
|
ref="ecrf3"
|
||||||
|
:question-form-change-state="true"
|
||||||
|
:question-form-change-num="0"
|
||||||
|
:is-qulity-issues="false"
|
||||||
|
:question-type="12"
|
||||||
:group-classify="5" />
|
:group-classify="5" />
|
||||||
<!-- 新增、编辑弹窗 -->
|
<!-- 新增、编辑弹窗 -->
|
||||||
<el-dialog v-if="addOrEdit.visible" :visible.sync="addOrEdit.visible" :close-on-click-modal="false"
|
<el-dialog v-if="addOrEdit.visible" :visible.sync="addOrEdit.visible" :close-on-click-modal="false"
|
||||||
|
|
@ -622,7 +633,7 @@ export default {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async handleSave(index) {
|
async handleSave(index, options = {}) {
|
||||||
if (this.rowSaveLoadingMap[index]) return
|
if (this.rowSaveLoadingMap[index]) return
|
||||||
const refName = `questions${index}`
|
const refName = `questions${index}`
|
||||||
this.$set(this.rowSaveLoadingMap, index, true)
|
this.$set(this.rowSaveLoadingMap, index, true)
|
||||||
|
|
@ -640,9 +651,13 @@ export default {
|
||||||
answers: answers
|
answers: answers
|
||||||
}
|
}
|
||||||
await saveTaskQuestion(12, params)
|
await saveTaskQuestion(12, params)
|
||||||
|
if (!options.silentSuccess) {
|
||||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||||
|
}
|
||||||
DicomEvent.$emit('getReportInfo', true)
|
DicomEvent.$emit('getReportInfo', true)
|
||||||
this.refreshQuestions()
|
if (!options.skipRefresh) {
|
||||||
|
await this.refreshQuestions()
|
||||||
|
}
|
||||||
this.formChanged = false
|
this.formChanged = false
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e)
|
console.log(e)
|
||||||
|
|
@ -858,9 +873,29 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async uploadDlgClose() {
|
async uploadDlgClose() {
|
||||||
this.refreshQuestions()
|
try {
|
||||||
DicomEvent.$emit('getReportInfo', true)
|
await this.refreshQuestions()
|
||||||
|
const saveTasks = []
|
||||||
|
for (let index = 0; index < this.questions.length; index++) {
|
||||||
|
const qs = this.questions[index]
|
||||||
|
if (qs.GroupClassify === 6) {
|
||||||
|
saveTasks.push(() => this.handleSave(index, { silentSuccess: true, skipRefresh: true }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
saveTasks.push(() => this.$refs['ecrf2'] && this.$refs['ecrf2'].handleSave({ silentSuccess: true, skipRefresh: true }))
|
||||||
|
saveTasks.push(() => this.$refs['ecrf3'] && this.$refs['ecrf3'].handleSave({ silentSuccess: true, skipRefresh: true }))
|
||||||
|
for (const saveTask of saveTasks) {
|
||||||
|
try {
|
||||||
|
await saveTask()
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
} finally {
|
||||||
this.upload.visible = false
|
this.upload.visible = false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
renderHeader(h, { column, $index }) {
|
renderHeader(h, { column, $index }) {
|
||||||
const span = document.createElement('span')
|
const span = document.createElement('span')
|
||||||
|
|
|
||||||
|
|
@ -189,11 +189,22 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 计算值 -->
|
<!-- 计算值 -->
|
||||||
<Questions ref="ecrf2" :question-form-change-state="true" :question-form-change-num="0" :is-qulity-issues="false"
|
<Questions
|
||||||
:group-classify="4" style="margin-top:20px" />
|
ref="ecrf2"
|
||||||
|
:question-form-change-state="true"
|
||||||
|
:question-form-change-num="0"
|
||||||
|
:is-qulity-issues="false"
|
||||||
|
:group-classify="4"
|
||||||
|
:question-type="12"
|
||||||
|
style="margin-top:20px" />
|
||||||
|
|
||||||
<!-- 评估结果 -->
|
<!-- 评估结果 -->
|
||||||
<Questions ref="ecrf3" :question-form-change-state="true" :question-form-change-num="0" :is-qulity-issues="false"
|
<Questions
|
||||||
|
ref="ecrf3"
|
||||||
|
:question-form-change-state="true"
|
||||||
|
:question-form-change-num="0"
|
||||||
|
:is-qulity-issues="false"
|
||||||
|
:question-type="12"
|
||||||
:group-classify="5" />
|
:group-classify="5" />
|
||||||
<el-dialog v-if="addOrEdit.visible" :visible.sync="addOrEdit.visible" :close-on-click-modal="false"
|
<el-dialog v-if="addOrEdit.visible" :visible.sync="addOrEdit.visible" :close-on-click-modal="false"
|
||||||
:title="addOrEdit.title" width="500px">
|
:title="addOrEdit.title" width="500px">
|
||||||
|
|
@ -617,7 +628,7 @@ export default {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async handleSave(index) {
|
async handleSave(index, options = {}) {
|
||||||
if (this.rowSaveLoadingMap[index]) return
|
if (this.rowSaveLoadingMap[index]) return
|
||||||
const refName = `questions${index}`
|
const refName = `questions${index}`
|
||||||
this.$set(this.rowSaveLoadingMap, index, true)
|
this.$set(this.rowSaveLoadingMap, index, true)
|
||||||
|
|
@ -635,9 +646,13 @@ export default {
|
||||||
answers: answers
|
answers: answers
|
||||||
}
|
}
|
||||||
await saveTaskQuestion(12, params)
|
await saveTaskQuestion(12, params)
|
||||||
|
if (!options.silentSuccess) {
|
||||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||||
|
}
|
||||||
DicomEvent.$emit('getReportInfo', true)
|
DicomEvent.$emit('getReportInfo', true)
|
||||||
this.refreshQuestions()
|
if (!options.skipRefresh) {
|
||||||
|
await this.refreshQuestions()
|
||||||
|
}
|
||||||
this.formChanged = false
|
this.formChanged = false
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e)
|
console.log(e)
|
||||||
|
|
@ -884,9 +899,29 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async uploadDlgClose() {
|
async uploadDlgClose() {
|
||||||
this.refreshQuestions()
|
try {
|
||||||
DicomEvent.$emit('getReportInfo', true)
|
await this.refreshQuestions()
|
||||||
|
const saveTasks = []
|
||||||
|
for (let index = 0; index < this.questions.length; index++) {
|
||||||
|
const qs = this.questions[index]
|
||||||
|
if (qs.GroupClassify === 6) {
|
||||||
|
saveTasks.push(() => this.handleSave(index, { silentSuccess: true, skipRefresh: true }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
saveTasks.push(() => this.$refs['ecrf2'] && this.$refs['ecrf2'].handleSave({ silentSuccess: true, skipRefresh: true }))
|
||||||
|
saveTasks.push(() => this.$refs['ecrf3'] && this.$refs['ecrf3'].handleSave({ silentSuccess: true, skipRefresh: true }))
|
||||||
|
for (const saveTask of saveTasks) {
|
||||||
|
try {
|
||||||
|
await saveTask()
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
} finally {
|
||||||
this.upload.visible = false
|
this.upload.visible = false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
renderHeader(h, { column, $index }) {
|
renderHeader(h, { column, $index }) {
|
||||||
const span = document.createElement('span')
|
const span = document.createElement('span')
|
||||||
|
|
|
||||||
|
|
@ -279,22 +279,24 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
handleSave() {
|
async handleSave(options = {}) {
|
||||||
if (this.saveLoading) return
|
if (this.saveLoading) return false
|
||||||
this.saveLoading = true
|
this.saveLoading = true
|
||||||
this.$refs['questions'].validate(async (valid) => {
|
const valid = await new Promise(resolve => {
|
||||||
|
this.$refs['questions'].validate(v => resolve(v))
|
||||||
|
})
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
this.saveLoading = false
|
this.saveLoading = false
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
// lugano标准校验脾脏状态是否符合要求
|
// lugano标准校验脾脏状态是否符合要求
|
||||||
if ((this.criterionType === 2 || this.criterionType === 18) && this.groupClassify === 3) {
|
if ((this.criterionType === 2 || this.criterionType === 18) && this.groupClassify === 3) {
|
||||||
// 是否有标记未保存
|
// 是否有标记未保存
|
||||||
var existUnSave = this.checkAnnotationStatus(this.questions)
|
var existUnSave = this.checkAnnotationStatus(this.questions)
|
||||||
if (existUnSave) {
|
if (existUnSave) {
|
||||||
this.$alert(this.$t('trials:lugano:message:saveWarning'), this.$t('trials:lugano:fusionDialog:warning'))
|
await this.$alert(this.$t('trials:lugano:message:saveWarning'), this.$t('trials:lugano:fusionDialog:warning'))
|
||||||
this.saveLoading = false
|
this.saveLoading = false
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentSpleenStatus = this.questionForm[this.spleenStatusId]
|
var currentSpleenStatus = this.questionForm[this.spleenStatusId]
|
||||||
|
|
@ -305,24 +307,26 @@ export default {
|
||||||
|
|
||||||
if (currentSpleenLength && currentSpleenStatus === 5) {
|
if (currentSpleenLength && currentSpleenStatus === 5) {
|
||||||
// '脾脏状态为不可评估,不需要添加标记!'
|
// '脾脏状态为不可评估,不需要添加标记!'
|
||||||
this.$alert(this.$t('trials:lugano:message:validSpleen1'), this.$t('trials:lugano:fusionDialog:warning'), {
|
await this.$alert(this.$t('trials:lugano:message:validSpleen1'), this.$t('trials:lugano:fusionDialog:warning'), {
|
||||||
callback: _ => { }
|
callback: _ => { }
|
||||||
})
|
})
|
||||||
this.saveLoading = false
|
this.saveLoading = false
|
||||||
|
return false
|
||||||
} else if (currentSpleenStatus === 5 && ((stIdx > -1 && this.measurements[stIdx].MeasureData) || (slIdx > -1 && this.measurements[slIdx].MeasureData))) {
|
} else if (currentSpleenStatus === 5 && ((stIdx > -1 && this.measurements[stIdx].MeasureData) || (slIdx > -1 && this.measurements[slIdx].MeasureData))) {
|
||||||
// 若有标记,状态不可为“无法评估”
|
// 若有标记,状态不可为“无法评估”
|
||||||
this.$alert(this.$t('trials:lugano:message:validSpleen1'), this.$t('trials:lugano:fusionDialog:warning'), {
|
await this.$alert(this.$t('trials:lugano:message:validSpleen1'), this.$t('trials:lugano:fusionDialog:warning'), {
|
||||||
callback: _ => { }
|
callback: _ => { }
|
||||||
})
|
})
|
||||||
this.saveLoading = false
|
this.saveLoading = false
|
||||||
|
return false
|
||||||
} else if (((stIdx > -1 && this.measurements[stIdx].MeasureData) || (slIdx > -1 && this.measurements[slIdx].MeasureData)) && !currentSpleenLength) {
|
} else if (((stIdx > -1 && this.measurements[stIdx].MeasureData) || (slIdx > -1 && this.measurements[slIdx].MeasureData)) && !currentSpleenLength) {
|
||||||
this.$alert(this.$t('trials:lugano:message:validSpleen2'), this.$t('trials:lugano:fusionDialog:warning'), {
|
await this.$alert(this.$t('trials:lugano:message:validSpleen2'), this.$t('trials:lugano:fusionDialog:warning'), {
|
||||||
callback: _ => { }
|
callback: _ => { }
|
||||||
})
|
})
|
||||||
this.saveLoading = false
|
this.saveLoading = false
|
||||||
} else {
|
return false
|
||||||
this.saveQuestionsList()
|
|
||||||
}
|
}
|
||||||
|
return await this.saveQuestionsList(options)
|
||||||
} else if ((this.criterionType === 2 || this.criterionType === 18) && this.groupClassify === 1 && this.questionForm[this.imageQualityIssuesId] && parseInt(this.questionForm[this.imageQualityIssuesId]) === 6) {
|
} else if ((this.criterionType === 2 || this.criterionType === 18) && this.groupClassify === 1 && this.questionForm[this.imageQualityIssuesId] && parseInt(this.questionForm[this.imageQualityIssuesId]) === 6) {
|
||||||
// 保存影响质量问题分组,如果质量问题为PET-CT影像无法融合则验证是否可以保存
|
// 保存影响质量问题分组,如果质量问题为PET-CT影像无法融合则验证是否可以保存
|
||||||
let res = null
|
let res = null
|
||||||
|
|
@ -333,30 +337,28 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.IsSuccess && !res.Result.IsCanChooseNotMerge) {
|
if (res.IsSuccess && !res.Result.IsCanChooseNotMerge) {
|
||||||
// this.$alert(this.$t('trials:lugano:saveQuestions:warning1'), this.$t('trials:lugano:fusionDialog:warning'), {showCancelButton: false})
|
await this.$alert(this.$t('trials:lugano:saveQuestions:warning1'), this.$t('trials:lugano:fusionDialog:warning'), {
|
||||||
this.$alert(this.$t('trials:lugano:saveQuestions:warning1'), this.$t('trials:lugano:fusionDialog:warning'), {
|
|
||||||
showCancelButton: false,
|
showCancelButton: false,
|
||||||
callback: action => { }
|
callback: action => { }
|
||||||
})
|
})
|
||||||
this.saveLoading = false
|
this.saveLoading = false
|
||||||
return
|
return false
|
||||||
} else {
|
}
|
||||||
// 如果设置为PET-CT影像无法融合,则FDG-PET评估会被设置为NE。
|
// 如果设置为PET-CT影像无法融合,则FDG-PET评估会被设置为NE。
|
||||||
this.$confirm(this.$t('trials:lugano:saveQuestions:warning2'), {
|
const confirm = await this.$confirm(this.$t('trials:lugano:saveQuestions:warning2'), {
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
distinguishCancelAndClose: true
|
distinguishCancelAndClose: true
|
||||||
})
|
}).then(() => true).catch(() => false)
|
||||||
.then(() => {
|
if (!confirm) {
|
||||||
this.saveQuestionsList()
|
this.saveLoading = false
|
||||||
})
|
return false
|
||||||
}
|
}
|
||||||
|
return await this.saveQuestionsList(options)
|
||||||
} else {
|
} else {
|
||||||
this.saveQuestionsList()
|
return await this.saveQuestionsList(options)
|
||||||
}
|
}
|
||||||
// this.saveQuestionsList()
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
async saveQuestionsList() {
|
async saveQuestionsList(options = {}) {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
var answers = []
|
var answers = []
|
||||||
var imageQuality = null
|
var imageQuality = null
|
||||||
|
|
@ -382,18 +384,22 @@ export default {
|
||||||
// })
|
// })
|
||||||
// params.questionMarkInfoList = questionMarkInfoList
|
// params.questionMarkInfoList = questionMarkInfoList
|
||||||
// }
|
// }
|
||||||
|
try {
|
||||||
saveTaskQuestion(this.questionType, params).then(async res => {
|
const res = await saveTaskQuestion(this.questionType, params)
|
||||||
if (this.imageQualityIssuesId) {
|
if (this.imageQualityIssuesId) {
|
||||||
store.dispatch('reading/setImageQualityIssues', this.questionForm[this.imageQualityIssuesId])
|
store.dispatch('reading/setImageQualityIssues', this.questionForm[this.imageQualityIssuesId])
|
||||||
if (this.questionForm[this.imageQualityIssuesId] && parseInt(this.questionForm[this.imageQualityIssuesId]) === 6) {
|
if (this.questionForm[this.imageQualityIssuesId] && parseInt(this.questionForm[this.imageQualityIssuesId]) === 6) {
|
||||||
DicomEvent.$emit('closePetct')
|
DicomEvent.$emit('closePetct')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!options.silentSuccess) {
|
||||||
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
this.$message.success(this.$t('common:message:savedSuccessfully'))
|
||||||
|
}
|
||||||
|
if (!options.skipRefresh) {
|
||||||
var trialId = this.$route.query.trialId
|
var trialId = this.$route.query.trialId
|
||||||
await store.dispatch('reading/refreshDicomReadingQuestionAnswer', { trialId: trialId, visitTaskId: this.visitTaskId })
|
await store.dispatch('reading/refreshDicomReadingQuestionAnswer', { trialId: trialId, visitTaskId: this.visitTaskId })
|
||||||
this.getQuestions(this.visitTaskId, true)
|
this.getQuestions(this.visitTaskId, true)
|
||||||
|
}
|
||||||
this.loading = false
|
this.loading = false
|
||||||
if (this.isQulityIssues) {
|
if (this.isQulityIssues) {
|
||||||
DicomEvent.$emit('questionFormChange', false)
|
DicomEvent.$emit('questionFormChange', false)
|
||||||
|
|
@ -417,10 +423,12 @@ export default {
|
||||||
}
|
}
|
||||||
this.formChanged = false
|
this.formChanged = false
|
||||||
this.saveLoading = false
|
this.saveLoading = false
|
||||||
}).catch(() => {
|
return res
|
||||||
|
} catch (e) {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
this.saveLoading = false
|
this.saveLoading = false
|
||||||
})
|
throw e
|
||||||
|
}
|
||||||
},
|
},
|
||||||
checkAnnotationStatus(obj) {
|
checkAnnotationStatus(obj) {
|
||||||
for (let i = 0; i < obj.length; i++) {
|
for (let i = 0; i < obj.length; i++) {
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ import { mapGetters } from 'vuex'
|
||||||
import Contextmenu from 'vue-contextmenujs'
|
import Contextmenu from 'vue-contextmenujs'
|
||||||
Vue.use(Contextmenu)
|
Vue.use(Contextmenu)
|
||||||
import * as cornerstone from 'cornerstone-core'
|
import * as cornerstone from 'cornerstone-core'
|
||||||
import metaDataProvider from '@/utils/metaDataProvider'
|
import metaDataProvider, { registerImageSharedCacheKey, unregisterImageSharedCacheKeys } from '@/utils/metaDataProvider'
|
||||||
|
|
||||||
import * as cornerstoneMath from 'cornerstone-math'
|
import * as cornerstoneMath from 'cornerstone-math'
|
||||||
import * as cornerstoneTools from 'cornerstone-tools'
|
import * as cornerstoneTools from 'cornerstone-tools'
|
||||||
|
|
@ -473,6 +473,7 @@ export default {
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
// Store.$off('getMeasureData')
|
// Store.$off('getMeasureData')
|
||||||
|
unregisterImageSharedCacheKeys(this.stack?.imageIds)
|
||||||
DicomEvent.$off('setReadingState')
|
DicomEvent.$off('setReadingState')
|
||||||
DicomEvent.$off('updateImage')
|
DicomEvent.$off('updateImage')
|
||||||
},
|
},
|
||||||
|
|
@ -1186,6 +1187,7 @@ export default {
|
||||||
this.resetHideMeasureArr()
|
this.resetHideMeasureArr()
|
||||||
}
|
}
|
||||||
const { image } = e.detail
|
const { image } = e.detail
|
||||||
|
registerImageSharedCacheKey(image?.imageId, image?.sharedCacheKey)
|
||||||
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager
|
||||||
const imageId = image.imageId
|
const imageId = image.imageId
|
||||||
ToolStateManager.clearImageIdToolState(imageId)
|
ToolStateManager.clearImageIdToolState(imageId)
|
||||||
|
|
|
||||||
|
|
@ -411,7 +411,7 @@
|
||||||
<WL v-if="activeName === '2'" @getWwcTpl="getWwcTpl" />
|
<WL v-if="activeName === '2'" @getWwcTpl="getWwcTpl" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane :label="$t('trials:reading:tab:others')" name="3">
|
<el-tab-pane :label="$t('trials:reading:tab:others')" name="3">
|
||||||
<Others v-if="activeName === '3'" :imageToolType="1"/>
|
<Others v-if="activeName === '3'" :imageToolType="1" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
@ -448,10 +448,10 @@
|
||||||
/> -->
|
/> -->
|
||||||
<upload-dicom-and-nonedicom v-if="uploadImageVisible" :SubjectId="uploadSubjectId" :SubjectCode="uploadSubjectCode"
|
<upload-dicom-and-nonedicom v-if="uploadImageVisible" :SubjectId="uploadSubjectId" :SubjectCode="uploadSubjectCode"
|
||||||
:Criterion="uploadTrialCriterion" :visible.sync="uploadImageVisible" :VisitTaskId="taskId"
|
:Criterion="uploadTrialCriterion" :visible.sync="uploadImageVisible" :VisitTaskId="taskId"
|
||||||
:isReadingTaskViewInOrder="isReadingTaskViewInOrder" />
|
:isReadingTaskViewInOrder="isReadingTaskViewInOrder" :isReading="true" />
|
||||||
<download-dicom-and-nonedicom v-if="downloadImageVisible" :SubjectId="uploadSubjectId"
|
<download-dicom-and-nonedicom v-if="downloadImageVisible" :SubjectId="uploadSubjectId"
|
||||||
:SubjectCode="uploadSubjectCode" :Criterion="uploadTrialCriterion" :TaskId="taskId"
|
:SubjectCode="uploadSubjectCode" :Criterion="uploadTrialCriterion" :TaskId="taskId"
|
||||||
:visible.sync="downloadImageVisible" />
|
:visible.sync="downloadImageVisible" :isReading="true"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,7 @@
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<div style="text-align:right;margin-top: 10px;">
|
<div style="text-align:right;margin-top: 10px;" v-if="!IsViewStudyPart">
|
||||||
<!-- 确认 -->
|
<!-- 确认 -->
|
||||||
<el-button type="primary" @click="handleConfirmBP">{{ $t('trials:reading:button:confirm')
|
<el-button type="primary" @click="handleConfirmBP">{{ $t('trials:reading:button:confirm')
|
||||||
}}</el-button>
|
}}</el-button>
|
||||||
|
|
@ -223,7 +223,8 @@ export default {
|
||||||
readingVersionEnum: null,
|
readingVersionEnum: null,
|
||||||
dialogBodyPartVisible: false,
|
dialogBodyPartVisible: false,
|
||||||
isReadKeyFile: true,
|
isReadKeyFile: true,
|
||||||
isHaveKeyFile: false
|
isHaveKeyFile: false,
|
||||||
|
IsViewStudyPart: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,17 @@
|
||||||
<svg-icon v-if="forceFitToWindow" icon-class="fitToWindow" class="svg-icon" />
|
<svg-icon v-if="forceFitToWindow" icon-class="fitToWindow" class="svg-icon" />
|
||||||
<svg-icon v-else icon-class="fitToImage" class="svg-icon" />
|
<svg-icon v-else icon-class="fitToImage" class="svg-icon" />
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 同步切图 -->
|
||||||
|
<div v-if="!isFusion && !isMPR && cells.length > 1"
|
||||||
|
:class="['tool-item', isScrollSync ? 'tool-item-active' : '']"
|
||||||
|
:title="$t('trials:reading:button:imageIndexSync')" @click.prevent="setImageIndexSync">
|
||||||
|
<i v-if="isScrollSync" class="el-icon-lock svg-icon" />
|
||||||
|
<i v-else class="el-icon-unlock svg-icon" />
|
||||||
|
</div>
|
||||||
|
<!-- 截图 -->
|
||||||
|
<div class="tool-item" :title="$t('trials:reading:button:screenShot')" @click.prevent="saveImage">
|
||||||
|
<svg-icon icon-class="image" class="svg-icon" />
|
||||||
|
</div>
|
||||||
<!-- MPR -->
|
<!-- MPR -->
|
||||||
<div class="tool-item" :title="`${$t('trials:reading:button:mpr')}`" @click.prevent="openMPRViewport()"
|
<div class="tool-item" :title="`${$t('trials:reading:button:mpr')}`" @click.prevent="openMPRViewport()"
|
||||||
v-if="((criterionType === 0 && readingTool === 0) || this.readingTool === 3) && !isMPR">
|
v-if="((criterionType === 0 && readingTool === 0) || this.readingTool === 3) && !isMPR">
|
||||||
|
|
@ -381,13 +392,16 @@
|
||||||
:rendering-engine-id="renderingEngineId" :viewport-id="`viewport-${index}`" :viewport-index="index"
|
:rendering-engine-id="renderingEngineId" :viewport-id="`viewport-${index}`" :viewport-index="index"
|
||||||
:histogramVisible="histogramVisible" :actionConfiguration="actionConfiguration"
|
:histogramVisible="histogramVisible" :actionConfiguration="actionConfiguration"
|
||||||
:SegmentConfig="SegmentConfig" :segmentationId.sync="segId" :segmentIndex.sync="segIndex"
|
:SegmentConfig="SegmentConfig" :segmentationId.sync="segId" :segmentIndex.sync="segIndex"
|
||||||
:curSegSeries.sync="curSegSeries" @activeViewport="activeViewport"
|
:curSegSeries.sync="curSegSeries" :is-scroll-sync="isScrollSync"
|
||||||
|
@activeViewport="activeViewport"
|
||||||
@toggleTaskByViewport="toggleTaskByViewport" @previewCD="previewCD"
|
@toggleTaskByViewport="toggleTaskByViewport" @previewCD="previewCD"
|
||||||
@renderAnnotations="renderAnnotations" @contentMouseup="contentMouseup"
|
@renderAnnotations="renderAnnotations" @contentMouseup="contentMouseup"
|
||||||
@resetViewport="resetViewport" @resetHistogram="resetHistogram" v-if="readingTool === 3"
|
@resetViewport="resetViewport" @resetHistogram="resetHistogram"
|
||||||
|
@scrollSync="handleViewportScrollSync" v-if="readingTool === 3"
|
||||||
v-resize="(e) => handleSizeChange(e, `viewport-${index}`)" />
|
v-resize="(e) => handleSizeChange(e, `viewport-${index}`)" />
|
||||||
<Viewport :ref="`viewport-${index}`" :data-viewport-uid="`viewport-${index}`"
|
<Viewport :ref="`viewport-${index}`" :data-viewport-uid="`viewport-${index}`"
|
||||||
:rendering-engine-id="renderingEngineId" :viewport-id="`viewport-${index}`" :viewport-index="index"
|
:rendering-engine-id="renderingEngineId" :viewport-id="`viewport-${index}`" :viewport-index="index"
|
||||||
|
:is-scroll-sync="isScrollSync" @scrollSync="handleViewportScrollSync"
|
||||||
@activeViewport="activeViewport" @toggleTaskByViewport="toggleTaskByViewport" @previewCD="previewCD"
|
@activeViewport="activeViewport" @toggleTaskByViewport="toggleTaskByViewport" @previewCD="previewCD"
|
||||||
@renderAnnotations="renderAnnotations" @contentMouseup="contentMouseup" v-else />
|
@renderAnnotations="renderAnnotations" @contentMouseup="contentMouseup" v-else />
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -799,6 +813,7 @@ export default {
|
||||||
activeViewportWC: null,
|
activeViewportWC: null,
|
||||||
clipPlaying: false,
|
clipPlaying: false,
|
||||||
fps: 15,
|
fps: 15,
|
||||||
|
isScrollSync: false,
|
||||||
manualsDialog: { visible: false, isFullscreen: false, justKeyDoc: false },
|
manualsDialog: { visible: false, isFullscreen: false, justKeyDoc: false },
|
||||||
hotKeyList: [],
|
hotKeyList: [],
|
||||||
forceFitToWindow: false,
|
forceFitToWindow: false,
|
||||||
|
|
@ -3415,8 +3430,34 @@ export default {
|
||||||
scrollPage(type) {
|
scrollPage(type) {
|
||||||
// if (this.histogramVisible) return false
|
// if (this.histogramVisible) return false
|
||||||
this.clipPlaying = false
|
this.clipPlaying = false
|
||||||
|
if (this.isScrollSync && !this.isFusion && !this.isMPR && this.cells.length > 1) {
|
||||||
|
for (let i = 0; i < this.cells.length; i++) {
|
||||||
|
const viewportRef = this.$refs[`${this.viewportKey}-${i}`]
|
||||||
|
if (viewportRef && viewportRef[0] && typeof viewportRef[0].scrollPage === 'function') {
|
||||||
|
viewportRef[0].scrollPage(type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].scrollPage(type)
|
this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].scrollPage(type)
|
||||||
},
|
},
|
||||||
|
setImageIndexSync() {
|
||||||
|
this.isScrollSync = !this.isScrollSync
|
||||||
|
},
|
||||||
|
handleViewportScrollSync({ viewportIndex, type, direction }) {
|
||||||
|
if (!this.isScrollSync || this.isFusion || this.isMPR || this.cells.length <= 1) return
|
||||||
|
const syncType = type ?? direction
|
||||||
|
if (viewportIndex !== this.activeViewportIndex || ![-1, 1, 0, 99999].includes(syncType)) return
|
||||||
|
|
||||||
|
this.clipPlaying = false
|
||||||
|
for (let i = 0; i < this.cells.length; i++) {
|
||||||
|
if (i === viewportIndex) continue
|
||||||
|
const viewportRef = this.$refs[`${this.viewportKey}-${i}`]
|
||||||
|
if (viewportRef && viewportRef[0] && typeof viewportRef[0].scrollPage === 'function') {
|
||||||
|
viewportRef[0].scrollPage(syncType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
// 播放
|
// 播放
|
||||||
toggleClipPlay(isPlay) {
|
toggleClipPlay(isPlay) {
|
||||||
// if (this.histogramVisible) return false
|
// if (this.histogramVisible) return false
|
||||||
|
|
@ -3723,7 +3764,7 @@ export default {
|
||||||
})
|
})
|
||||||
this.setToolsPassive()
|
this.setToolsPassive()
|
||||||
},
|
},
|
||||||
async activeSeries(obj) {
|
async activeSeries(obj, isSave = false) {
|
||||||
if (this.readingTool === 3) {
|
if (this.readingTool === 3) {
|
||||||
let res = await this.changeScreenSave()
|
let res = await this.changeScreenSave()
|
||||||
if (!res) return false
|
if (!res) return false
|
||||||
|
|
@ -3735,6 +3776,7 @@ export default {
|
||||||
if (!confirm) return false
|
if (!confirm) return false
|
||||||
this.$refs[`ecrf_${this.taskInfo.VisitTaskId}`][0].removeAllNoSaveAnnotation()
|
this.$refs[`ecrf_${this.taskInfo.VisitTaskId}`][0].removeAllNoSaveAnnotation()
|
||||||
} else {
|
} else {
|
||||||
|
if (isSave) return false
|
||||||
const confirm = await this.$confirm(this.$t('trials:reading:confirm:changeStack'))
|
const confirm = await this.$confirm(this.$t('trials:reading:confirm:changeStack'))
|
||||||
if (!confirm) return false
|
if (!confirm) return false
|
||||||
}
|
}
|
||||||
|
|
@ -4022,7 +4064,7 @@ export default {
|
||||||
}
|
}
|
||||||
let res = await this.openMPRViewport(series)
|
let res = await this.openMPRViewport(series)
|
||||||
if (!res) {
|
if (!res) {
|
||||||
this.$refs[series.TaskInfo.VisitTaskId][0].setSeriesActive(series.StudyIndex, series.SeriesIndex)
|
this.$refs[series.TaskInfo.VisitTaskId][0].setSeriesActive(series.StudyIndex, series.SeriesIndex, true)
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
const divForDownloadViewport = document.querySelector(
|
const divForDownloadViewport = document.querySelector(
|
||||||
`div[data-viewport-uid="${this.viewportKey}-${this.activeViewportIndex}"]`
|
`div[data-viewport-uid="${this.viewportKey}-${this.activeViewportIndex}"]`
|
||||||
|
|
@ -4534,7 +4576,7 @@ export default {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
this.setToolsPassive()
|
this.setToolsPassive()
|
||||||
if (this.isMPR) {
|
if (this.isMPR) {
|
||||||
this.activeSeries(this.$refs[`viewport-MPR-0`][0].series)
|
this.activeSeries(this.$refs[`viewport-MPR-0`][0].series, true)
|
||||||
resolve(false)
|
resolve(false)
|
||||||
if (!data) return resolve(false)
|
if (!data) return resolve(false)
|
||||||
let viewportSeries = this.$refs[`viewport-MPR-0`][0].series
|
let viewportSeries = this.$refs[`viewport-MPR-0`][0].series
|
||||||
|
|
|
||||||
|
|
@ -804,12 +804,16 @@ export default {
|
||||||
toolGroup.setToolPassive(this.activeTool)
|
toolGroup.setToolPassive(this.activeTool)
|
||||||
}
|
}
|
||||||
this.$emit('update:activeTool', '')
|
this.$emit('update:activeTool', '')
|
||||||
|
} else if (this.activeTool === name) {
|
||||||
|
toolGroup.setToolPassive(this.ThresholdTools[1])
|
||||||
|
this.$emit('update:activeTool', '')
|
||||||
} else {
|
} else {
|
||||||
if (this.activeTool) {
|
if (this.activeTool) {
|
||||||
if (toolName === CrosshairsTool.toolName) {
|
if (toolName === CrosshairsTool.toolName) {
|
||||||
toolGroup.setToolDisabled(this.activeTool)
|
toolGroup.setToolDisabled(this.activeTool)
|
||||||
} else {
|
} else {
|
||||||
toolGroup.setToolPassive(this.activeTool)
|
toolGroup.setToolPassive(this.activeTool)
|
||||||
|
toolGroup.setToolPassive(this.ThresholdTools[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
toolGroup.setToolActive(toolName, {
|
toolGroup.setToolActive(toolName, {
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span class="study-meta-line" :title="study.Modalities">
|
<span class="study-meta-line" :title="study.Modalities">
|
||||||
<span v-if="taskInfo && taskInfo.IsReadingTaskViewInOrder !== 0" class="study-code" :title="study.StudyCode">{{ study.StudyCode }}</span>
|
<span v-if="taskInfo && taskInfo.IsReadingTaskViewInOrder !== 0" class="study-code"
|
||||||
|
:title="study.StudyCode">{{ study.StudyCode }}</span>
|
||||||
<span class="study-modality">{{ `${study.Modalities}(${study.SeriesCount})` }}</span>
|
<span class="study-modality">{{ `${study.Modalities}(${study.SeriesCount})` }}</span>
|
||||||
<span class="patient-info" v-if="['PT、CT', 'CT、PT', 'PET-CT'].includes(study.Modalities)">
|
<span class="patient-info" v-if="['PT、CT', 'CT、PT', 'PET-CT'].includes(study.Modalities)">
|
||||||
<el-popover placement="right-start" trigger="hover" popper-class="patient-info-popper">
|
<el-popover placement="right-start" trigger="hover" popper-class="patient-info-popper">
|
||||||
|
|
@ -81,8 +82,7 @@
|
||||||
style="position: absolute;right: 0;top: 0;">
|
style="position: absolute;right: 0;top: 0;">
|
||||||
<el-popover placement="right" trigger="hover" popper-class="instance_frame_wrapper">
|
<el-popover placement="right" trigger="hover" popper-class="instance_frame_wrapper">
|
||||||
<div class="frame_list">
|
<div class="frame_list">
|
||||||
<div v-for="(instance, idx) in series.InstanceInfoList" :key="instance.Id"
|
<div v-for="(instance, idx) in series.InstanceInfoList" :key="instance.Id" class="frame_content"
|
||||||
class="frame_content"
|
|
||||||
:class="{ 'frame_content_active': activeInstanceId === instance.Id }"
|
:class="{ 'frame_content_active': activeInstanceId === instance.Id }"
|
||||||
:style="{ 'margin-bottom': idx < series.InstanceInfoList.length - 1 ? '5px' : '0px' }"
|
:style="{ 'margin-bottom': idx < series.InstanceInfoList.length - 1 ? '5px' : '0px' }"
|
||||||
@click.stop="showMultiFrames(index, series, i, instance)">
|
@click.stop="showMultiFrames(index, series, i, instance)">
|
||||||
|
|
@ -211,12 +211,13 @@ export default {
|
||||||
if (this.activeNames.indexOf(id) > -1) return
|
if (this.activeNames.indexOf(id) > -1) return
|
||||||
this.activeNames.push(id)
|
this.activeNames.push(id)
|
||||||
},
|
},
|
||||||
setSeriesActive(studyIndex, seriesIndex) {
|
setSeriesActive(studyIndex, seriesIndex, isSave = false) {
|
||||||
this.activeStudyIndex = studyIndex
|
this.activeStudyIndex = studyIndex
|
||||||
this.activeSeriesIndex = seriesIndex
|
this.activeSeriesIndex = seriesIndex
|
||||||
const studyId = this.studyList[studyIndex].StudyId
|
const studyId = this.studyList[studyIndex].StudyId
|
||||||
if (!studyId) return
|
if (!studyId) return
|
||||||
this.activeStudy(studyId)
|
this.activeStudy(studyId)
|
||||||
|
if (isSave) return false
|
||||||
DicomEvent.$emit('activeSeries', this.studyList[studyIndex].SeriesList[this.activeSeriesIndex])
|
DicomEvent.$emit('activeSeries', this.studyList[studyIndex].SeriesList[this.activeSeriesIndex])
|
||||||
},
|
},
|
||||||
showMultiFrames(studyIndex, series, seriesIndex, instance) {
|
showMultiFrames(studyIndex, series, seriesIndex, instance) {
|
||||||
|
|
@ -482,25 +483,29 @@ export default {
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.study-wrapper {
|
.study-wrapper {
|
||||||
.instance_frame_wrapper{
|
.instance_frame_wrapper {
|
||||||
min-width: 120px;
|
min-width: 120px;
|
||||||
background-color: #2c2c2c;
|
background-color: #2c2c2c;
|
||||||
border: 1px solid #2c2c2c;
|
border: 1px solid #2c2c2c;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
.frame_list{
|
|
||||||
|
.frame_list {
|
||||||
max-height: 500px;
|
max-height: 500px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.instance_frame_wrapper ::-webkit-scrollbar {
|
.instance_frame_wrapper ::-webkit-scrollbar {
|
||||||
width: 7px;
|
width: 7px;
|
||||||
height: 7px;
|
height: 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.instance_frame_wrapper ::-webkit-scrollbar-thumb {
|
.instance_frame_wrapper ::-webkit-scrollbar-thumb {
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background: #d0d0d0;
|
background: #d0d0d0;
|
||||||
}
|
}
|
||||||
.frame_content{
|
|
||||||
|
.frame_content {
|
||||||
height: 50px;
|
height: 50px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -509,6 +514,7 @@ export default {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
border: 1px solid #404040;
|
border: 1px solid #404040;
|
||||||
}
|
}
|
||||||
|
|
||||||
.frame_content:hover {
|
.frame_content:hover {
|
||||||
/* font-weight: bold; */
|
/* font-weight: bold; */
|
||||||
/* box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); */
|
/* box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); */
|
||||||
|
|
@ -517,10 +523,10 @@ export default {
|
||||||
border-color: #213a54 !important;
|
border-color: #213a54 !important;
|
||||||
background-color: #213a54;
|
background-color: #213a54;
|
||||||
}
|
}
|
||||||
|
|
||||||
.frame_content_active {
|
.frame_content_active {
|
||||||
border-color: #213a54 !important;
|
border-color: #213a54 !important;
|
||||||
background-color: #213a54;
|
background-color: #213a54;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,10 @@ export default {
|
||||||
viewportIndex: {
|
viewportIndex: {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true
|
required: true
|
||||||
|
},
|
||||||
|
isScrollSync: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|
@ -191,6 +195,7 @@ export default {
|
||||||
this.element.oncontextmenu = (e) => e.preventDefault()
|
this.element.oncontextmenu = (e) => e.preventDefault()
|
||||||
this.resizeObserver.observe(this.element)
|
this.resizeObserver.observe(this.element)
|
||||||
this.element.addEventListener('CORNERSTONE_STACK_NEW_IMAGE', this.stackNewImage)
|
this.element.addEventListener('CORNERSTONE_STACK_NEW_IMAGE', this.stackNewImage)
|
||||||
|
this.element.addEventListener('wheel', this.handleWheelSync)
|
||||||
// this.element.addEventListener('CORNERSTONE_VOI_MODIFIED', this.voiModified)
|
// this.element.addEventListener('CORNERSTONE_VOI_MODIFIED', this.voiModified)
|
||||||
// this.element.addEventListener('CORNERSTONE_CAMERA_MODIFIED', this.cameraModified)
|
// this.element.addEventListener('CORNERSTONE_CAMERA_MODIFIED', this.cameraModified)
|
||||||
|
|
||||||
|
|
@ -374,6 +379,32 @@ export default {
|
||||||
toolGroup.setToolEnabled('ScaleOverlay')
|
toolGroup.setToolEnabled('ScaleOverlay')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
handleWheelSync(e) {
|
||||||
|
if (!this.isScrollSync) return
|
||||||
|
|
||||||
|
const deltaY = typeof e.deltaY === 'number' ? e.deltaY : -e.wheelDeltaY
|
||||||
|
if (!deltaY) return
|
||||||
|
|
||||||
|
const renderingEngine = getRenderingEngine(this.renderingEngineId)
|
||||||
|
const viewport = renderingEngine && renderingEngine.getViewport(this.viewportId)
|
||||||
|
if (!viewport) return
|
||||||
|
|
||||||
|
const currentImageIdIndex = viewport.getCurrentImageIdIndex()
|
||||||
|
const numImages = viewport.getImageIds().length
|
||||||
|
if (numImages <= 1) return
|
||||||
|
const direction = deltaY > 0 ? 1 : -1
|
||||||
|
let type = direction
|
||||||
|
|
||||||
|
if (direction === 1 && currentImageIdIndex >= numImages - 1) {
|
||||||
|
type = 0
|
||||||
|
csUtils.jumpToSlice(viewport.element, { imageIndex: 0 })
|
||||||
|
} else if (direction === -1 && currentImageIdIndex <= 0) {
|
||||||
|
type = 99999
|
||||||
|
csUtils.jumpToSlice(viewport.element, { imageIndex: numImages - 1 })
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$emit('scrollSync', { viewportIndex: this.viewportIndex, type })
|
||||||
|
},
|
||||||
scrollPage(type) {
|
scrollPage(type) {
|
||||||
const renderingEngine = getRenderingEngine(this.renderingEngineId)
|
const renderingEngine = getRenderingEngine(this.renderingEngineId)
|
||||||
const viewport = renderingEngine.getViewport(this.viewportId)
|
const viewport = renderingEngine.getViewport(this.viewportId)
|
||||||
|
|
@ -383,9 +414,9 @@ export default {
|
||||||
if (type === 0) {
|
if (type === 0) {
|
||||||
newImageIdIndex = 0
|
newImageIdIndex = 0
|
||||||
} else if (type === -1) {
|
} else if (type === -1) {
|
||||||
newImageIdIndex = currentImageIdIndex === 0 ? currentImageIdIndex : currentImageIdIndex - 1
|
newImageIdIndex = currentImageIdIndex === 0 ? numImages - 1 : currentImageIdIndex - 1
|
||||||
} else if (type === 1) {
|
} else if (type === 1) {
|
||||||
newImageIdIndex = currentImageIdIndex === numImages - 1 ? currentImageIdIndex : currentImageIdIndex + 1
|
newImageIdIndex = currentImageIdIndex === numImages - 1 ? 0 : currentImageIdIndex + 1
|
||||||
} else if (type === 99999) {
|
} else if (type === 99999) {
|
||||||
newImageIdIndex = numImages - 1
|
newImageIdIndex = numImages - 1
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,10 @@ export default {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
isScrollSync: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
histogramVisible: {
|
histogramVisible: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
|
@ -304,23 +308,7 @@ export default {
|
||||||
this.element.addEventListener("CORNERSTONE_VOLUME_NEW_IMAGE", this.stackNewImage)
|
this.element.addEventListener("CORNERSTONE_VOLUME_NEW_IMAGE", this.stackNewImage)
|
||||||
this.element.addEventListener('CORNERSTONE_VOI_MODIFIED', this.voiModified)
|
this.element.addEventListener('CORNERSTONE_VOI_MODIFIED', this.voiModified)
|
||||||
this.element.addEventListener('CORNERSTONE_IMAGE_RENDERED', this.imageRendered)
|
this.element.addEventListener('CORNERSTONE_IMAGE_RENDERED', this.imageRendered)
|
||||||
this.element.addEventListener('wheel', (e) => {
|
this.element.addEventListener('wheel', this.handleWheelSync)
|
||||||
// if (this.histogramVisible) return false
|
|
||||||
console.log('CORNERSTONE_STACK_VIEWPORT_SCROLL')
|
|
||||||
const renderingEngine = getRenderingEngine(this.renderingEngineId)
|
|
||||||
const viewport = renderingEngine.getViewport(this.viewportId)
|
|
||||||
const currentImageIdIndex = viewport.getCurrentImageIdIndex()
|
|
||||||
const totalImages = this.imageInfo.total;
|
|
||||||
|
|
||||||
// 手动实现循环逻辑
|
|
||||||
if (currentImageIdIndex >= totalImages - 1 && e.wheelDeltaY < 0) {
|
|
||||||
// 滚动到最后一张时跳回第一张
|
|
||||||
csUtils.jumpToSlice(viewport.element, { imageIndex: 0 });
|
|
||||||
} else if (currentImageIdIndex <= 0 && e.wheelDeltaY > 0) {
|
|
||||||
// 滚动到第一张时跳回最后一张
|
|
||||||
csUtils.jumpToSlice(viewport.element, { imageIndex: totalImages - 1 });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.element.addEventListener('CORNERSTONE_TOOLS_MOUSE_MOVE', this.cornerstoneToolsMouseMove)
|
this.element.addEventListener('CORNERSTONE_TOOLS_MOUSE_MOVE', this.cornerstoneToolsMouseMove)
|
||||||
// this.element.addEventListener(cornerstoneTools.Enums.Events.MOUSE_WHEEL, this.handletoolsMouseWheel)
|
// this.element.addEventListener(cornerstoneTools.Enums.Events.MOUSE_WHEEL, this.handletoolsMouseWheel)
|
||||||
this.element.addEventListener('mouseleave', () => {
|
this.element.addEventListener('mouseleave', () => {
|
||||||
|
|
@ -390,6 +378,30 @@ export default {
|
||||||
setFilp(f = false) {
|
setFilp(f = false) {
|
||||||
this.isFlip = f
|
this.isFlip = f
|
||||||
},
|
},
|
||||||
|
handleWheelSync(e) {
|
||||||
|
const deltaY = typeof e.deltaY === 'number' ? e.deltaY : -e.wheelDeltaY
|
||||||
|
if (!deltaY) return
|
||||||
|
|
||||||
|
const renderingEngine = getRenderingEngine(this.renderingEngineId)
|
||||||
|
const viewport = renderingEngine.getViewport(this.viewportId)
|
||||||
|
const currentImageIdIndex = viewport.getCurrentImageIdIndex()
|
||||||
|
const totalImages = this.imageInfo.total
|
||||||
|
if (totalImages <= 1) return
|
||||||
|
const direction = deltaY > 0 ? 1 : -1
|
||||||
|
let type = direction
|
||||||
|
|
||||||
|
if (currentImageIdIndex >= totalImages - 1 && direction === 1) {
|
||||||
|
type = 0
|
||||||
|
csUtils.jumpToSlice(viewport.element, { imageIndex: 0 })
|
||||||
|
} else if (currentImageIdIndex <= 0 && direction === -1) {
|
||||||
|
type = 99999
|
||||||
|
csUtils.jumpToSlice(viewport.element, { imageIndex: totalImages - 1 })
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isScrollSync) {
|
||||||
|
this.$emit('scrollSync', { viewportIndex: this.viewportIndex, type })
|
||||||
|
}
|
||||||
|
},
|
||||||
stackNewImage(e) {
|
stackNewImage(e) {
|
||||||
if (this.isFlip) return this.isFlip = false
|
if (this.isFlip) return this.isFlip = false
|
||||||
const { detail } = e
|
const { detail } = e
|
||||||
|
|
@ -573,9 +585,9 @@ export default {
|
||||||
if (type === 0) {
|
if (type === 0) {
|
||||||
newImageIdIndex = 0
|
newImageIdIndex = 0
|
||||||
} else if (type === -1) {
|
} else if (type === -1) {
|
||||||
newImageIdIndex = currentImageIdIndex === 0 ? currentImageIdIndex : currentImageIdIndex - 1
|
newImageIdIndex = currentImageIdIndex === 0 ? numImages - 1 : currentImageIdIndex - 1
|
||||||
} else if (type === 1) {
|
} else if (type === 1) {
|
||||||
newImageIdIndex = currentImageIdIndex === numImages - 1 ? currentImageIdIndex : currentImageIdIndex + 1
|
newImageIdIndex = currentImageIdIndex === numImages - 1 ? 0 : currentImageIdIndex + 1
|
||||||
} else if (type === 99999) {
|
} else if (type === 99999) {
|
||||||
newImageIdIndex = numImages - 1
|
newImageIdIndex = numImages - 1
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,21 +88,21 @@
|
||||||
: $t('trials:pendingReadingTasks:button:review')
|
: $t('trials:pendingReadingTasks:button:review')
|
||||||
" icon="el-icon-edit-outline" @click="handleReadImage(scope.row)" />
|
" icon="el-icon-edit-outline" @click="handleReadImage(scope.row)" />
|
||||||
<!-- 上传 -->
|
<!-- 上传 -->
|
||||||
<el-button v-if="
|
<!-- <el-button v-if="
|
||||||
item.ImageUploadEnum > 0 &&
|
item.ImageUploadEnum > 0 &&
|
||||||
item.IsReadingTaskViewInOrder > 1 &&
|
item.IsReadingTaskViewInOrder > 1 &&
|
||||||
!scope.row.IsSubjectJudge
|
!scope.row.IsSubjectJudge
|
||||||
" v-hasPermi="['role:ir']" circle icon="el-icon-upload2"
|
" v-hasPermi="['role:ir']" circle icon="el-icon-upload2"
|
||||||
:title="$t('trials:pendingReadingTasks:button:upload')"
|
:title="$t('trials:pendingReadingTasks:button:upload')"
|
||||||
@click="openUploadImage(scope.row, item, 'upload')" />
|
@click="openUploadImage(scope.row, item, 'upload')" /> -->
|
||||||
<!-- 下载 -->
|
<!-- 下载 -->
|
||||||
<el-button v-if="
|
<!-- <el-button v-if="
|
||||||
item.ImageDownloadEnum > 0 &&
|
item.ImageDownloadEnum > 0 &&
|
||||||
item.IsReadingTaskViewInOrder > 1 &&
|
item.IsReadingTaskViewInOrder > 1 &&
|
||||||
!scope.row.IsSubjectJudge
|
!scope.row.IsSubjectJudge
|
||||||
" v-hasPermi="['role:ir']" circle icon="el-icon-download"
|
" v-hasPermi="['role:ir']" circle icon="el-icon-download"
|
||||||
:title="$t('trials:pendingReadingTasks:button:download')"
|
:title="$t('trials:pendingReadingTasks:button:download')"
|
||||||
@click="openUploadImage(scope.row, item, 'download')" />
|
@click="openUploadImage(scope.row, item, 'download')" /> -->
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
|
||||||
|
|
@ -1,58 +1,35 @@
|
||||||
<template>
|
<template>
|
||||||
<el-form
|
<el-form ref="subjectForm" v-loading="loading" :model="form" :rules="rules" size="small" label-width="200px">
|
||||||
ref="subjectForm"
|
|
||||||
v-loading="loading"
|
|
||||||
:model="form"
|
|
||||||
:rules="rules"
|
|
||||||
size="small"
|
|
||||||
label-width="200px"
|
|
||||||
>
|
|
||||||
<div class="base-dialog-body">
|
<div class="base-dialog-body">
|
||||||
<!-- Site -->
|
<!-- Site -->
|
||||||
<el-form-item :label="$t('trials:subject:table:site')" prop="TrialSiteId">
|
<el-form-item :label="$t('trials:subject:table:site')" prop="TrialSiteId">
|
||||||
<el-select
|
<el-select v-model="form.TrialSiteId" clearable filterable style="width:100%"
|
||||||
v-model="form.TrialSiteId"
|
:disabled="form.StudyCount > 0 || isEdit">
|
||||||
clearable
|
<el-option v-for="item of siteOptions" :key="item.Id" :label="item.TrialSiteCode" :value="item.TrialSiteId" />
|
||||||
filterable
|
|
||||||
style="width:100%"
|
|
||||||
:disabled="form.StudyCount>0 || isEdit"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item of siteOptions"
|
|
||||||
:key="item.Id"
|
|
||||||
:label="item.TrialSiteCode"
|
|
||||||
:value="item.TrialSiteId"
|
|
||||||
/>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 受试者编号 -->
|
<!-- 受试者编号 -->
|
||||||
<el-form-item :label="$t('trials:subject:table:subjectId')" prop="Code">
|
<el-form-item :label="$t('trials:subject:table:subjectId')" prop="Code">
|
||||||
<el-input v-model="form.Code" :disabled="form.StudyCount > 0 || isEdit" />
|
<el-input v-model="form.Code" :disabled="form.StudyCount > 0 || isEdit" @input="
|
||||||
<span v-show="otherInfo.IsNoticeSubjectCodeRule" style="color:#F56C6C;font-size:12px;">{{ otherInfo.SubjectCodeRule }}</span>
|
form.Code =
|
||||||
|
form.Code.replace(/[^0-9a-zA-Z\_\-]/g, '')
|
||||||
|
" />
|
||||||
|
<span v-show="otherInfo.IsNoticeSubjectCodeRule" style="color:#F56C6C;font-size:12px;">{{
|
||||||
|
otherInfo.SubjectCodeRule }}</span>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 受试者第二编号 -->
|
<!-- 受试者第二编号 -->
|
||||||
<el-form-item v-if="otherInfo.IsSubjectSecondCodeView" :label="$t('trials:subject:table:medicalNo')" prop="MedicalNo">
|
<el-form-item v-if="otherInfo.IsSubjectSecondCodeView" :label="$t('trials:subject:table:medicalNo')"
|
||||||
|
prop="MedicalNo">
|
||||||
<el-input v-model="form.MedicalNo" :disabled="form.StudyCount > 0 || isEdit" />
|
<el-input v-model="form.MedicalNo" :disabled="form.StudyCount > 0 || isEdit" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 访视基准日期 -->
|
<!-- 访视基准日期 -->
|
||||||
<el-form-item
|
<el-form-item v-show="otherInfo.IsHaveFirstGiveMedicineDate"
|
||||||
v-show="otherInfo.IsHaveFirstGiveMedicineDate"
|
:label="$t('trials:subject:table:firstGiveMedicineTime')">
|
||||||
:label="$t('trials:subject:table:firstGiveMedicineTime')"
|
<el-date-picker v-model="form.FirstGiveMedicineTime" type="date" :picker-options="pickerOption"
|
||||||
>
|
value-format="yyyy-MM-dd" format="yyyy-MM-dd" />
|
||||||
<el-date-picker
|
|
||||||
v-model="form.FirstGiveMedicineTime"
|
|
||||||
type="date"
|
|
||||||
:picker-options="pickerOption"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
format="yyyy-MM-dd"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- Age -->
|
<!-- Age -->
|
||||||
<el-form-item
|
<el-form-item v-if="otherInfo.IsHaveSubjectAge" :label="$t('trials:subject:table:age')" prop="Age">
|
||||||
v-if="otherInfo.IsHaveSubjectAge"
|
|
||||||
:label="$t('trials:subject:table:age')"
|
|
||||||
prop="Age"
|
|
||||||
>
|
|
||||||
<el-input-number v-model="form.Age" controls-position="right" :min="0" />
|
<el-input-number v-model="form.Age" controls-position="right" :min="0" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- Gender -->
|
<!-- Gender -->
|
||||||
|
|
@ -73,12 +50,7 @@
|
||||||
<div class="base-dialog-footer" style="text-align:right;margin-top:10px;">
|
<div class="base-dialog-footer" style="text-align:right;margin-top:10px;">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<!-- 取消 -->
|
<!-- 取消 -->
|
||||||
<el-button
|
<el-button :disabled="btnLoading" size="small" type="primary" @click="handleCancel">
|
||||||
:disabled="btnLoading"
|
|
||||||
size="small"
|
|
||||||
type="primary"
|
|
||||||
@click="handleCancel"
|
|
||||||
>
|
|
||||||
{{ $t('common:button:cancel') }}
|
{{ $t('common:button:cancel') }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- 保存 -->
|
<!-- 保存 -->
|
||||||
|
|
|
||||||
|
|
@ -644,7 +644,7 @@
|
||||||
<el-input v-model="studyForm.Modalities" disabled />
|
<el-input v-model="studyForm.Modalities" disabled />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 检查类型 -->
|
<!-- 检查类型 -->
|
||||||
<el-form-item v-else :label="$t('trials:audit:table:modality')" prop="Modalities" :rules="[
|
<el-form-item v-else :label="$t('trials:audit:table:modality')" prop="Modality" :rules="[
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: $t('common:ruleMessage:specify'),
|
message: $t('common:ruleMessage:specify'),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue