diff --git a/.env.development b/.env.development index 1795b787..1cd11a20 100644 --- a/.env.development +++ b/.env.development @@ -14,6 +14,9 @@ VUE_CLI_BABEL_TRANSPILE_MODULES = false # 是否开启登陆限制 true:是 false:否 VUE_APP_LOGIN_FOR_PERMISSION = false +# 是否开启长时间无操作锁定弹框MFA验证 true:是 false:否 +VUE_APP_LOCK_FOR_PERMISSION_MFA = false + # 是否开启长时间无操作锁定弹框 true:是 false:否 VUE_APP_LOCK_FOR_PERMISSION = false diff --git a/.env.prod b/.env.prod index 49d97ae9..2f8d7ea6 100644 --- a/.env.prod +++ b/.env.prod @@ -8,6 +8,9 @@ VUE_APP_BASE_PATH = '/' # 是否开启登陆限制 true:是 false:否 VUE_APP_LOGIN_FOR_PERMISSION = true +# 是否开启长时间无操作锁定弹框MFA验证 true:是 false:否 +VUE_APP_LOCK_FOR_PERMISSION_MFA = false + # 是否开启长时间无操作锁定弹框 true:是 false:否 VUE_APP_LOCK_FOR_PERMISSION = true diff --git a/.env.production b/.env.production index 00537958..38fd6f0d 100644 --- a/.env.production +++ b/.env.production @@ -9,6 +9,9 @@ VUE_APP_IS_TEST = true # 是否开启登陆限制 true:是 false:否 VUE_APP_LOGIN_FOR_PERMISSION = false +# 是否开启长时间无操作锁定弹框MFA验证 true:是 false:否 +VUE_APP_LOCK_FOR_PERMISSION_MFA = false + # 是否开启长时间无操作锁定弹框 true:是 false:否 VUE_APP_LOCK_FOR_PERMISSION = false diff --git a/.env.prop b/.env.prop index 79660dba..20a7b9ee 100644 --- a/.env.prop +++ b/.env.prop @@ -5,6 +5,9 @@ NODE_ENV = 'prop' # 是否开启登陆限制 true:是 false:否 VUE_APP_LOGIN_FOR_PERMISSION = true +# 是否开启长时间无操作锁定弹框MFA验证 true:是 false:否 +VUE_APP_LOCK_FOR_PERMISSION_MFA = false + # 是否开启长时间无操作锁定弹框 true:是 false:否 VUE_APP_LOCK_FOR_PERMISSION = true diff --git a/.env.uat b/.env.uat index 1f04b231..b4586518 100644 --- a/.env.uat +++ b/.env.uat @@ -10,6 +10,9 @@ VUE_APP_BASE_PATH = '/' # 是否开启登陆限制 true:是 false:否 VUE_APP_LOGIN_FOR_PERMISSION = true +# 是否开启长时间无操作锁定弹框MFA验证 true:是 false:否 +VUE_APP_LOCK_FOR_PERMISSION_MFA = false + # 是否开启长时间无操作锁定弹框 true:是 false:否 VUE_APP_LOCK_FOR_PERMISSION = true diff --git a/.env.usa b/.env.usa index b621b83e..0098dc79 100644 --- a/.env.usa +++ b/.env.usa @@ -1,12 +1,15 @@ # just a flag -ENV = 'production' -NODE_ENV = 'production' +ENV = 'usa' +NODE_ENV = 'usa' # base public path VUE_APP_BASE_PATH = 'https://ei-code-prod.s3.amazonaws.com/2024-05-31/' # 是否开启登陆限制 true:是 false:否 VUE_APP_LOGIN_FOR_PERMISSION = false +# 是否开启长时间无操作锁定弹框MFA验证 true:是 false:否 +VUE_APP_LOCK_FOR_PERMISSION_MFA = true + # 是否开启长时间无操作锁定弹框 true:是 false:否 VUE_APP_LOCK_FOR_PERMISSION = false diff --git a/irc_vue_drone.yml b/irc_vue_drone.yml index 6dbcef8e..e62410c1 100644 --- a/irc_vue_drone.yml +++ b/irc_vue_drone.yml @@ -10,7 +10,7 @@ clone: disable: true #禁用默认克隆 server: - host: 192.168.3.68 + host: 106.14.89.110 user: root password: from_secret: local_pwd @@ -19,7 +19,7 @@ steps: - name: publish-test-irc-vue commands: - echo start publish test-irc-vue - - cd /opt/hang/vue/test-irc + - cd /opt/1panel/hang/vue/test-irc - sh test-irc.sh v${DRONE_BUILD_NUMBER} trigger: @@ -41,7 +41,7 @@ clone: disable: true #禁用默认克隆 server: - host: 123.56.94.154 + host: 106.14.89.110 user: root password: from_secret: local_pwd diff --git a/src/App.vue b/src/App.vue index 1d5e9db3..a7d5c2b7 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,169 +1,213 @@ diff --git a/src/api/dictionary.js b/src/api/dictionary.js index 25897aff..2ea54499 100644 --- a/src/api/dictionary.js +++ b/src/api/dictionary.js @@ -1006,3 +1006,11 @@ export function deleteCommonDocument(commonDocumentId) { method: 'delete' }) } +//getTrialSiteList +export function getTrialSiteList(params) { + return request({ + url: `/site/getTrialSiteList`, + method: 'post', + data: params + }) +} \ No newline at end of file diff --git a/src/api/dictionary/checkConfig.js b/src/api/dictionary/checkConfig.js index af74b938..771ca57e 100644 --- a/src/api/dictionary/checkConfig.js +++ b/src/api/dictionary/checkConfig.js @@ -76,3 +76,11 @@ export function fullyReplicated(param) { }) } +// 获取所有字典key +export function getDictionaryCodeList() { + return request({ + url: `/Dictionary/getAllDictionaryKey`, + method: 'post', + }) +} + diff --git a/src/api/global.js b/src/api/global.js index 6d0a4b58..a568bea3 100644 --- a/src/api/global.js +++ b/src/api/global.js @@ -14,17 +14,19 @@ export function getHospitalList() { }) } -export function getAllSponsorList() { +export function getAllSponsorList(params) { return request({ url: '/sponsor/getAllSponsorList', - method: 'get' + method: 'get', + params }) } -export function getAllCROList() { +export function getAllCROList(params) { return request({ url: '/cro/getAllCROList', - method: 'get' + method: 'get', + params }) } export function getAllSiteList() { diff --git a/src/api/load.js b/src/api/load.js new file mode 100644 index 00000000..cc23cc40 --- /dev/null +++ b/src/api/load.js @@ -0,0 +1,42 @@ +import request from '@/utils/request' +// 下载打包影像 +export function requestPackageAndAnonymizImage(params) { + return request({ + url: '/DownloadAndUpload/requestPackageAndAnonymizImage', + method: 'post', + params + }) +} +// 获取影像上传列表 +export function getSubjectImageUploadList(params) { + return request({ + url: '/DownloadAndUpload/getSubjectImageUploadList', + method: 'get', + params + }) +} +// 预上传 +export function preArchiveDicomStudy(data) { + return request({ + url: '/DownloadAndUpload/preArchiveDicomStudy', + method: 'post', + data + }) +} +// 归档 +export function addOrUpdateArchiveTaskStudy(data) { + return request({ + url: '/DownloadAndUpload/addOrUpdateArchiveTaskStudy', + method: 'post', + data + }) +} + +// 删除上传文件 +export function deleteTaskStudy(params) { + return request({ + url: '/DownloadAndUpload/deleteTaskStudy', + method: 'delete', + params + }) +} \ No newline at end of file diff --git a/src/api/trials.js b/src/api/trials.js index 1cdb1ff0..8d017e4a 100644 --- a/src/api/trials.js +++ b/src/api/trials.js @@ -1364,9 +1364,9 @@ export function getForwardList(param) { }) } -export function getNoneDicomStudyList(subjectVisitId, sudyId = '') { +export function getNoneDicomStudyList(subjectVisitId, sudyId = '', isFilterZip = false) { return request({ - url: `/NoneDicomStudy/getNoneDicomStudyList?subjectVisitId=${subjectVisitId}&nonedicomStudyId=${sudyId}`, + url: `/NoneDicomStudy/getNoneDicomStudyList?subjectVisitId=${subjectVisitId}&nonedicomStudyId=${sudyId}&isFilterZip=${isFilterZip}`, method: 'get' }) } @@ -3667,3 +3667,11 @@ export function getDicomSeriesInfo(param) { data: param }) } + +export function getTrialSiteSelectList(params) { + return request({ + url: `/trialMaintenance/getTrialSiteSelectList`, + method: 'get', + params + }) +} diff --git a/src/api/trials/reading.js b/src/api/trials/reading.js index 1d99fb1d..cebb8312 100644 --- a/src/api/trials/reading.js +++ b/src/api/trials/reading.js @@ -436,9 +436,9 @@ export function addSubjectCancelDoctorNote(params) { }) } -export function getSubjectCancelDoctorHistoryList(SubjectId) { +export function getSubjectCancelDoctorHistoryList(SubjectId, TrialReadingCriterionId) { return request({ - url: `/TaskAllocationRule/getSubjectCancelDoctorHistoryList?SubjectId=${SubjectId}`, + url: `/TaskAllocationRule/getSubjectCancelDoctorHistoryList?SubjectId=${SubjectId}&&TrialReadingCriterionId=${TrialReadingCriterionId}`, method: 'get' }) } diff --git a/src/api/trials/setting.js b/src/api/trials/setting.js index 1df89e8a..ad9bf3b9 100644 --- a/src/api/trials/setting.js +++ b/src/api/trials/setting.js @@ -94,4 +94,20 @@ export function getTrialJudgyInfo(params) { data: params }) } +// 获取检查部位列表 +export function getTrialBodyPartList(params) { + return request({ + url: `/TrialConfig/getTrialBodyPartList`, + method: 'get', + params + }) +} +// 新增检查部位 +export function addOrUpdateTrialBodyPart(data) { + return request({ + url: `/TrialConfig/addOrUpdateTrialBodyPart`, + method: 'post', + data + }) +} diff --git a/src/api/user.js b/src/api/user.js index aa9354c5..67027318 100644 --- a/src/api/user.js +++ b/src/api/user.js @@ -7,10 +7,11 @@ export function login(data) { data }) } -export function loginOut() { +export function loginOut(params) { return request({ url: `/User/loginOut`, - method: 'get' + method: 'get', + params }) } export function getAllDictionary() { @@ -157,3 +158,30 @@ export function getUserLogList(params) { data: params }) } + +// 获取登录用户 +export function getTrialUserList(params) { + return request({ + url: `/TrialMaintenance/getTrialUserList`, + method: 'get', + params + }) +} + +// 验证MFA邮件 +export function verifyMFACode(params) { + return request({ + url: `/User/verifyMFACode`, + method: 'post', + params + }) +} + +// 发送MFA邮件 +export function sendMFAEmail(params) { + return request({ + url: `/User/sendMFAEmail`, + method: 'post', + params + }) +} diff --git a/src/assets/icons/svg/resetSuccess.svg b/src/assets/icons/svg/resetSuccess.svg new file mode 100644 index 00000000..96c094b7 --- /dev/null +++ b/src/assets/icons/svg/resetSuccess.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/zip.png b/src/assets/zip.png new file mode 100644 index 00000000..bf027c11 Binary files /dev/null and b/src/assets/zip.png differ diff --git a/src/assets/zzlogo-usa.png b/src/assets/zzlogo-usa.png new file mode 100644 index 00000000..bb4be037 Binary files /dev/null and b/src/assets/zzlogo-usa.png differ diff --git a/src/components/BaseForm/search-form.vue b/src/components/BaseForm/search-form.vue index b05ef2b8..303307d6 100644 --- a/src/components/BaseForm/search-form.vue +++ b/src/components/BaseForm/search-form.vue @@ -2,18 +2,28 @@ diff --git a/src/views/none-dicom-show/components/image-viewer.vue b/src/views/none-dicom-show/components/image-viewer.vue index fd00a31c..a9718f07 100644 --- a/src/views/none-dicom-show/components/image-viewer.vue +++ b/src/views/none-dicom-show/components/image-viewer.vue @@ -50,7 +50,7 @@ :ref="`img${i}`" :key="item.Id" crossorigin="anonymous" - :src="`${OSSclientConfig.basePath}${item.Path}`" + :src="item.FileType&&item.FileType.indexOf('zip')>=0?zipImg:`${OSSclientConfig.basePath}${item.Path}`" :style="imgStyle" style="max-width:100%;max-height: 100%;" @load="handleImgLoad" @@ -68,7 +68,7 @@ + diff --git a/src/views/system/user/list/index.vue b/src/views/system/user/list/index.vue index f347279f..d32b1550 100644 --- a/src/views/system/user/list/index.vue +++ b/src/views/system/user/list/index.vue @@ -11,12 +11,6 @@ @reset="handleReset" @new="handleAddUser" /> - - - - - - { UserType: null, PageIndex: 1, PageSize: 20, - Asc: true, + Asc: false, RealName: '', - SortField: '' + BeginCreateTime: '', + EndCreateTime: '', + CreateTimeArr: [], + SortField: 'CreateTime' } } export default { @@ -163,6 +160,13 @@ export default { minWidth: 100, sortable: 'custom', showOverflowTooltip: true }, + { + prop: "CreateTime", + label: this.$t("system:userlist:table:createTime"), + minWidth: 200, + sortable: "custom", + showOverflowTooltip: true, + }, { type: 'operate', label: this.$t('common:action:action'), minWidth: 200, @@ -193,6 +197,13 @@ export default { width: '120px', placeholder: '' }, + { + type: "Input", + label: this.$t("system:userlist:label:EMail"), + prop: "EMail", + width: "120px", + placeholder: "", + }, { type: 'Input', label: this.$t('system:userlist:label:Organization'), @@ -247,7 +258,14 @@ export default { options: [], // 下拉选项 props: { label: 'UserType', value: 'Id' }, // 下拉选项配置信息,必填 placeholder: '' - } + }, + { + type: "Daterange", + label: this.$t("system:userlist:label:CreateTime"), + prop: "CreateTimeArr", + width: "400px", + placeholder: "", + }, ], searchHandle: [ { label: this.$t('common:button:reset'), type: 'primary', emitKey: 'reset' }, @@ -314,7 +332,14 @@ export default { handleReset() { this.searchData = searchDataDefault() this.getList() - } + }, + handleSearch() { + if (this.searchData.CreateTimeArr.length > 0) { + this.searchData.BeginCreateTime = this.searchData.CreateTimeArr[0] + this.searchData.EndCreateTime = this.searchData.CreateTimeArr[1] + } + this.getList() + }, } } diff --git a/src/views/trials/trials-layout/components/trialsNavbar.vue b/src/views/trials/trials-layout/components/trialsNavbar.vue index 082a8545..66754ce8 100644 --- a/src/views/trials/trials-layout/components/trialsNavbar.vue +++ b/src/views/trials/trials-layout/components/trialsNavbar.vue @@ -2,8 +2,13 @@
+ - + + + {{ $t('trials:trials:title:eics_title') }} + + {{ $t('trials:trials:title:eics') }} @@ -46,6 +51,12 @@ {{ $t('trials:trials-myinfo:title:accountInfo') }} + + {{ $t("trials:trials-myinfo:title:system") }} {{ $t('trials:trials-myinfo:button:loginout') }} @@ -68,7 +79,8 @@ export default { isReviewer: false, userTypeShortName: zzSessionStorage.getItem('userTypeShortName'), notice: '', - VUE_APP_OSS_CONFIG_REGION: process.env.VUE_APP_OSS_CONFIG_REGION + VUE_APP_OSS_CONFIG_REGION: process.env.VUE_APP_OSS_CONFIG_REGION, + NODE_ENV: process.env.NODE_ENV, } }, computed: { @@ -108,6 +120,9 @@ export default { case '4-3': this.logout() break + case "4-4": + this.go("/system"); + break; case '1': this.go('/trials/trials-workbench') break diff --git a/src/views/trials/trials-list/components/TrialForm.vue b/src/views/trials/trials-list/components/TrialForm.vue index b081bf3f..e3c252ed 100644 --- a/src/views/trials/trials-list/components/TrialForm.vue +++ b/src/views/trials/trials-list/components/TrialForm.vue @@ -12,29 +12,61 @@ > - - + + - - - {{ item.label }} + + + {{ item.label }} - - + + - + - + @@ -45,9 +77,18 @@ - + - + - + - + @@ -100,8 +156,14 @@ - - + + - + - + - + - + @@ -166,9 +242,12 @@ - + - @@ -193,14 +272,19 @@ - + - - - + - + - - + @@ -229,106 +319,95 @@ multiple clearable > - + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - + - {{ $t('trials:trials-list:form:cancel') }} + {{ $t("trials:trials-list:form:cancel") }} - {{ $t('trials:trials-list:form:save') }} + {{ $t("trials:trials-list:form:save") }} - diff --git a/src/views/trials/trials-myinfo/mine.vue b/src/views/trials/trials-myinfo/mine.vue new file mode 100644 index 00000000..455623f5 --- /dev/null +++ b/src/views/trials/trials-myinfo/mine.vue @@ -0,0 +1,199 @@ + + \ No newline at end of file diff --git a/src/views/trials/trials-myinfo/password.vue b/src/views/trials/trials-myinfo/password.vue new file mode 100644 index 00000000..28a4956c --- /dev/null +++ b/src/views/trials/trials-myinfo/password.vue @@ -0,0 +1,160 @@ + + \ No newline at end of file diff --git a/src/views/trials/trials-panel/attachments/attachment-management/index.vue b/src/views/trials/trials-panel/attachments/attachment-management/index.vue index 75272c38..6039250c 100644 --- a/src/views/trials/trials-panel/attachments/attachment-management/index.vue +++ b/src/views/trials/trials-panel/attachments/attachment-management/index.vue @@ -47,6 +47,7 @@ > - - - - + + + + + + + + + + + + + + + + {{ $fd('TaskState', scope.row.TaskState) }} - - - - - - - - - - - - {{ $fd('ReReadingApplyState', scope.row.ReReadingApplyState) }} {{ $fd('ReReadingApplyState', scope.row.ReReadingApplyState) }} - + --> - {{ $fd('YesOrNo', scope.row.IsReReadingOrBackInfluenceAnalysis) }} {{ $fd('YesOrNo', scope.row.IsReReadingOrBackInfluenceAnalysis) }} - + --> - {{$t('trials:consistencyAnalysis:title:impactInfluence')}} + : {{$t('trials:consistencyAnalysis:title:impactInfluence')}}
{ Asc: true, SortField: '', TrialId: null, - SiteId: null, + TrialSiteId: null, SubjectId: null, SubjectCode: null, TrialSiteCode: null, @@ -674,7 +701,9 @@ const searchDataDefault = () => { TaskAllocationState: null, BeginAllocateDate: null, EndAllocateDate: null, - TrialReadingCriterionId: null + TrialReadingCriterionId: null, + BeginSignTime: null, + EndSignTime: null } } export default { @@ -707,6 +736,7 @@ export default { ReaderRulesFormVisible: false, IsSelfAnalysis: true, timeList: [], + timeList2: [], ApplyforReasonVisible: false, ApplyforReasonForm: { Type: null, @@ -790,9 +820,18 @@ export default { this.searchData.EndAllocateDate = null } }, + changeTimeList2() { + if (this.timeList2) { + this.searchData.BeginSignTime = this.timeList2[0] + this.searchData.EndSignTime = this.timeList2[1] + } else { + this.searchData.BeginSignTime = null + this.searchData.EndSignTime = null + } + }, // 重阅历史 reReadingHistory(row) { - this.$router.push({ path: `/trials/trials-panel/reading/reReadingTracking?trialId=${this.$route.query.trialId}&trialCode=${this.$route.query.trialCode}&researchProgramNo=${this.$route.query.researchProgramNo}&SiteId=${row.SiteId}&SubjectCode=${row.SubjectCode}&TaskName=${row.TaskName}&DoctorUserId=${row.DoctorUserId}` }) + this.$router.push({ path: `/trials/trials-panel/reading/reReadingTracking?trialId=${this.$route.query.trialId}&trialCode=${this.$route.query.trialCode}&researchProgramNo=${this.$route.query.researchProgramNo}&TrialSiteId=${row.TrialSiteId}&SubjectCode=${row.SubjectCode}&TaskName=${row.TaskName}&DoctorUserId=${row.DoctorUserId}` }) }, // 申请重阅 applyReReading() { @@ -981,6 +1020,7 @@ export default { }, handleReset() { this.timeList = null + this.timeList2 = null this.searchData = searchDataDefault() this.getList() }, @@ -1004,12 +1044,17 @@ export default { } + diff --git a/src/views/trials/trials-panel/reading/dicoms/customize/CustomizeDicomCanvas.vue b/src/views/trials/trials-panel/reading/dicoms/customize/CustomizeDicomCanvas.vue index 8323b4d2..94ca0017 100644 --- a/src/views/trials/trials-panel/reading/dicoms/customize/CustomizeDicomCanvas.vue +++ b/src/views/trials/trials-panel/reading/dicoms/customize/CustomizeDicomCanvas.vue @@ -19,7 +19,7 @@
@@ -43,7 +43,7 @@
-
+

{{ subjectCode }} {{ stack.taskBlindName }}

Series: #{{ dicomInfo.series }}
Image: #{{ dicomInfo.frame }}
@@ -99,8 +99,8 @@
-
Location: {{ dicomInfo.location }}
-
Slice Thickness: {{ dicomInfo.thick }}mm
+
Location: {{ `${Number(dicomInfo.location).toFixed(digitPlaces)} mm` }}
+
Slice Thickness: {{ `${dicomInfo.thick} mm` }}
WW/WL: {{ dicomInfo.wwwc }}
@@ -180,7 +180,7 @@ export default { required: true }, isReadingTaskViewInOrder: { - type: Boolean, + type: Number, required: true }, customWwcTpl: { @@ -221,7 +221,7 @@ export default { taskBlindName: '', frame: null, imageRendered: false, - isExistsClinicalData:false + isExistsClinicalData: false // preventCache: true }, dicomInfo: { @@ -298,7 +298,7 @@ export default { ], scrollSyncInfo: { offset: 0 }, hideMeasureArr: [] - + } }, computed: { @@ -331,7 +331,9 @@ export default { }, mounted() { - this.subjectCode = this.$router.currentRoute.query.subjectCode + console.log(cornerstoneTools) + // this.subjectCode = this.$router.currentRoute.query.subjectCode + this.subjectCode = localStorage.getItem('subjectCode') document.addEventListener('mouseup', () => { this.sliderMouseup() }) @@ -374,10 +376,10 @@ export default { } ) - // this.canvas.addEventListener( - // 'cornerstonetoolsmeasurementremoved', - // this.onMeasurementremoved - // ) + this.canvas.addEventListener( + 'cornerstonetoolsmeasurementremoved', + this.onMeasurementremoved + ) // EVENTS.MOUSE_UP this.canvas.addEventListener('cornerstonetoolsmouseup', this.mouseUp) this.canvas.addEventListener('cornerstonetoolsmousedown', this.mouseDown) @@ -478,7 +480,6 @@ export default { }, methods: { goViewer(e) { - console.log('goViewer') console.log(this.$refs['sliderBox'].clientHeight) var height = e.offsetY * 100 / this.$refs['sliderBox'].clientHeight this.height = height @@ -567,6 +568,7 @@ export default { showCancelButton: false, type: 'warning' }).then(() => { + }).catch(() => {}) e.stopImmediatePropagation() e.stopPropagation() @@ -652,7 +654,7 @@ export default { if (PX < 0) return if (PX > boxHeight) return var height = PX * 100 / boxHeight - var index = Math.trunc(this.stack.imageIds.length * this.height / 100) + var index = Math.trunc(this.stack.imageIds.length * height / 100) index = index > this.stack.imageIds.length ? this.stack.imageIds.length : index < 0 ? 0 : index // if (!cornerstone.imageCache.getImageLoadObject(this.stack.imageIds[index])) return this.height = height @@ -664,6 +666,7 @@ export default { this.sliderInfo.isMove = false }, getMeasureData() { + console.log('getMeasureData') var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.stack.visitTaskId) this.measureData = this.visitTaskList[idx].MeasureData const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager @@ -737,14 +740,10 @@ export default { getToolStateInfo(e) { const { element, currentPoints, image, viewport } = e.detail var imageId = image.imageId - var instanceId = imageId.split('/')[imageId.split('/').length - 1] - var frame = null - if (instanceId.includes('?frame=')) { - frame = instanceId.split('?frame=')[1] - instanceId = instanceId.split('?frame=')[0] - } + const imageInfo = this.getInstanceInfo(imageId) + var instanceId = imageInfo.instanceId + var frame = imageInfo.frame this.stack.frame = !isNaN(parseInt(frame)) ? parseInt(frame) : 0 - instanceId = instanceId.split('.')[0] const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager for (var m = 0; m < this.measuredTools.length; m++) { var toolType = this.measuredTools[m] @@ -772,6 +771,7 @@ export default { measureData.data = toolState.data[i] measureData.type = toolType measureData.thick = this.dicomInfo.thick + measureData.location = this.dicomInfo.location var uuid = toolState.data[i].uuid var idx = this.measureData.findIndex(item => item.MeasureData && item.MeasureData.data && item.MeasureData.data.uuid === uuid) if (idx > -1) { @@ -800,7 +800,7 @@ export default { } }, stackScrollCallback(e) { - console.log('stackScrollCallback') + // console.log('stackScrollCallback') const { detail } = e if (this.isScrollSync && this.currentDicomCanvasIndex === this.canvasIndex) { this.scrollSyncInfo.canvasIndex = this.canvasIndex @@ -867,6 +867,7 @@ export default { renderMeasuredData(e) { this.stack.frame = !isNaN(parseInt(this.stack.frame)) ? parseInt(this.stack.frame) : 0 var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.stack.visitTaskId) + if (idx === -1) return this.measureData = this.visitTaskList[idx].MeasureData const { element } = e.detail const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager @@ -905,11 +906,8 @@ export default { if (this.readingTaskState >= 2) return var element = cornerstone.getEnabledElement(this.canvas) var { imageId } = element.image - var instanceId = imageId.split('/')[imageId.split('/').length - 1] - if (instanceId.includes('?frame=')) { - instanceId = instanceId.split('?frame=')[0] - } - instanceId = instanceId.split('.')[0] + const imageInfo = this.getInstanceInfo(imageId) + var instanceId = imageInfo.instanceId var idx = this.visitTaskList.findIndex(i => i.VisitTaskId === this.stack.visitTaskId && i.IsCurrentTask && i.ReadingTaskState < 2) if (idx === -1) return this.measureData = this.visitTaskList[idx].MeasureData @@ -969,18 +967,13 @@ export default { } } }, - async mouseClick(e) { + mouseClick(e) { const { element, currentPoints, image, viewport } = e.detail var imageId = image.imageId - var instanceId = imageId.split('/')[imageId.split('/').length - 1] - var frame = null - if (instanceId.includes('?frame=')) { - frame = instanceId.split('?frame=')[1] - instanceId = instanceId.split('?frame=')[0] - } + const imageInfo = this.getInstanceInfo(imageId) + var instanceId = imageInfo.instanceId + var frame = imageInfo.frame this.stack.frame = !isNaN(parseInt(frame)) ? parseInt(frame) : 0 - instanceId = instanceId.split('.')[0] - const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager for (let t = 0; t < this.measuredTools.length; t++) { var toolType = this.measuredTools[t] @@ -1011,6 +1004,7 @@ export default { measureData.data = toolState.data[i] measureData.type = toolType measureData.thick = this.dicomInfo.thick + measureData.location = this.dicomInfo.location measureData.ww = Math.round(viewport.voi.windowWidth) measureData.wc = Math.round(viewport.voi.windowCenter) measureData.data.active = false @@ -1060,22 +1054,19 @@ export default { } else { this.disabledMarks = [] } + this.maxVistNum = this.visitTaskList[this.visitTaskList.length - 1].VisitTaskNum this.minVistNum = this.visitTaskList[0].VisitTaskNum this.measureData = this.visitTaskList[idx].MeasureData const imageId = this.stack.imageIds[this.stack.currentImageIdIndex] - var instanceId = imageId.split('/')[imageId.split('/').length - 1] - var frame = null - if (instanceId.includes('?frame=')) { - frame = instanceId.split('?frame=')[1] - instanceId = instanceId.split('?frame=')[0] - } + const imageInfo = this.getInstanceInfo(imageId) + var instanceId = imageInfo.instanceId + var frame = imageInfo.frame this.stack.frame = !isNaN(parseInt(frame)) ? parseInt(frame) : 0 - instanceId = instanceId.split('.')[0] this.stack.instanceId = instanceId const ToolStateManager = cornerstoneTools.globalImageIdSpecificToolStateManager ToolStateManager.clearImageIdToolState(dicomSeries.imageIds) - if (this.toolState.clipPlaying) this.toggleClipPlay() + this.toggleClipPlay(false) this.toolState.viewportInvert = false this.toolState.dicomInfoVisible = false @@ -1095,102 +1086,105 @@ export default { // } // resolve() // }) + this.loading = true cornerstone.loadAndCacheImage(this.stack.imageIds[this.stack.currentImageIdIndex]) - .then(image => { - scope.onFirstImageLoaded(image) + .then(async image => { + if (this.stack.imageIds.indexOf(image.imageId) !== -1) { + await scope.onFirstImageLoaded(image) + } + scope.loading = false resolve() }) .catch((error) => { if (error.error && error.error.message) { this.$alert(error.error.message) } + scope.loading = false resolve() }) }) }, onFirstImageLoaded(image) { console.log('onFirstImageLoaded') + return new Promise(async resolve => { + const element = this.$refs.canvas + var viewport = cornerstone.getDefaultViewportForImage(this.canvas, image) + cornerstone.displayImage(this.canvas, image, viewport) - const element = this.$refs.canvas - var viewport = cornerstone.getDefaultViewportForImage(this.canvas, image) - cornerstone.displayImage(this.canvas, image, viewport) + if (!this.toolState.initialized) { + this.toolState.initialized = true + const toolButtons = document.querySelectorAll('[data-tool]') - if (!this.toolState.initialized) { - this.toolState.initialized = true - const toolButtons = document.querySelectorAll('[data-tool]') - - // const scope = this - Array.from(toolButtons).forEach((toolBtn) => { + // const scope = this + Array.from(toolButtons).forEach((toolBtn) => { // Add the tool - const toolName = toolBtn.getAttribute('data-tool') - const apiTool = cornerstoneTools[`${toolName}Tool`] - if (apiTool) { - const toolAlreadyAddedToElement = cornerstoneTools.getToolForElement(element, apiTool) + const toolName = toolBtn.getAttribute('data-tool') + const apiTool = cornerstoneTools[`${toolName}Tool`] + if (apiTool) { + const toolAlreadyAddedToElement = cornerstoneTools.getToolForElement(element, apiTool) - if (!toolAlreadyAddedToElement) { - if (toolName === 'Length') { - cornerstoneTools.addToolForElement(element, LengthTool, { configuration: { handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces, drawHandles: true }}) - } else if (toolName === 'Bidirectional') { + if (!toolAlreadyAddedToElement) { + if (toolName === 'Length') { + cornerstoneTools.addToolForElement(element, LengthTool, { configuration: { handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true, digits: this.digitPlaces, drawHandles: true }}) + } else if (toolName === 'Bidirectional') { // cornerstoneTools.addToolForElement(element, BidirectionalTool, { digits: this.digitPlaces }) // , handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true - cornerstoneTools.addToolForElement(element, BidirectionalTool, { configuration: { digits: this.digitPlaces, hideHandlesIfMoving: true }}) - } else if (toolName === 'ArrowAnnotate') { - cornerstoneTools.addToolForElement(element, ArrowAnnotateTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true }}) - } else if (toolName === 'RectangleRoi') { - cornerstoneTools.addToolForElement(element, RectangleRoiTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true }}) - } else { - cornerstoneTools.addToolForElement(element, apiTool) + cornerstoneTools.addToolForElement(element, BidirectionalTool, { configuration: { digits: this.digitPlaces, hideHandlesIfMoving: true }}) + } else if (toolName === 'ArrowAnnotate') { + cornerstoneTools.addToolForElement(element, ArrowAnnotateTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true }}) + } else if (toolName === 'RectangleRoi') { + cornerstoneTools.addToolForElement(element, RectangleRoiTool, { configuration: { allowEmptyLabel: true, handleRadius: false, drawHandlesOnHover: true, hideHandlesIfMoving: true }}) + } else { + cornerstoneTools.addToolForElement(element, apiTool) + } } } + }) + if (!cornerstoneTools.getToolForElement(element, cornerstoneTools.WwwcRegionTool)) { + cornerstoneTools.addToolForElement(element, cornerstoneTools.WwwcRegionTool) } - }) - if (!cornerstoneTools.getToolForElement(element, cornerstoneTools.WwwcRegionTool)) { - cornerstoneTools.addToolForElement(element, cornerstoneTools.WwwcRegionTool) - } - if (!cornerstoneTools.getToolForElement(element, cornerstoneTools.StackScrollMouseWheelTool)) { - cornerstoneTools.addToolForElement(element, cornerstoneTools.StackScrollMouseWheelTool) - } - cornerstoneTools.setToolActiveForElement(element, 'StackScrollMouseWheel', {}) + if (!cornerstoneTools.getToolForElement(element, cornerstoneTools.StackScrollMouseWheelTool)) { + cornerstoneTools.addToolForElement(element, cornerstoneTools.StackScrollMouseWheelTool) + } + cornerstoneTools.setToolActiveForElement(element, 'StackScrollMouseWheel', {}) - if (!cornerstoneTools.getToolForElement(element, ScaleOverlayTool)) { - cornerstoneTools.addToolForElement(element, ScaleOverlayTool) - } - cornerstoneTools.setToolActiveForElement(element, 'ScaleOverlay', {}) - cornerstoneTools.setToolActiveForElement(this.canvas, 'Zoom', { - mouseButtonMask: 2 - }) - cornerstoneTools.setToolActiveForElement(this.canvas, 'Pan', { - mouseButtonMask: 4 - }) + if (!cornerstoneTools.getToolForElement(element, ScaleOverlayTool)) { + cornerstoneTools.addToolForElement(element, ScaleOverlayTool) + } + cornerstoneTools.setToolActiveForElement(element, 'ScaleOverlay', {}) + cornerstoneTools.setToolActiveForElement(this.canvas, 'Zoom', { + mouseButtonMask: 2 + }) + cornerstoneTools.setToolActiveForElement(this.canvas, 'Pan', { + mouseButtonMask: 4 + }) // if (!cornerstoneTools.getToolForElement(element, OrientationMarkersTool)) { // cornerstoneTools.addToolForElement(element, OrientationMarkersTool) // } // cornerstoneTools.setToolActiveForElement(element, 'OrientationMarkers', { }) - } + } - // cornerstoneTools.addStackStateManager(this.canvas, ['stack', 'stackPrefetch', 'playClip']) - cornerstoneTools.addStackStateManager(this.canvas, ['stack', 'playClip']) - cornerstoneTools.addToolState(this.canvas, 'stack', this.stack) - // cornerstoneTools.stackPrefetch.enable(this.canvas) - cornerstone.updateImage(element, true) + // cornerstoneTools.addStackStateManager(this.canvas, ['stack', 'stackPrefetch', 'playClip']) + cornerstoneTools.addStackStateManager(this.canvas, ['stack', 'playClip']) + cornerstoneTools.addToolState(this.canvas, 'stack', this.stack) + // cornerstoneTools.stackPrefetch.enable(this.canvas) + cornerstone.updateImage(element, true) - this.stack.firstImageLoading = false - this.toolState.dicomInfoVisible = true - var instanceId = image.imageId.split('/')[image.imageId.split('/').length - 1] - var frame = null - if (instanceId.includes('?frame=')) { - frame = instanceId.split('?frame=')[1] - instanceId = instanceId.split('?frame=')[0] - } - this.stack.frame = !isNaN(parseInt(frame)) ? parseInt(frame) : 0 - instanceId = instanceId.split('.')[0] - this.stack.instanceId = instanceId - this.height = (this.stack.currentImageIdIndex) * 100 / (this.stack.imageIds.length - 1) - this.resetWwwc() + this.stack.firstImageLoading = false + this.toolState.dicomInfoVisible = true + const imageInfo = this.getInstanceInfo(image.imageId) + var instanceId = imageInfo.instanceId + var frame = imageInfo.frame + this.stack.frame = !isNaN(parseInt(frame)) ? parseInt(frame) : 0 + this.stack.instanceId = instanceId + this.height = (this.stack.currentImageIdIndex) * 100 / (this.stack.imageIds.length - 1) + this.resetWwwc() + resolve() + }) }, onNewImage(e) { - console.log('cornerstonenewimage') + // console.log('cornerstonenewimage') if (this.isCurrentTask && this.readingTaskState < 2) { this.resetHideMeasureArr() } @@ -1227,6 +1221,12 @@ export default { if (this.dicomInfo.thick) { this.dicomInfo.thick = this.dicomInfo.thick.toFixed(2) } + let newImageIdIndex = this.stack.imageIds.findIndex(i=>i===imageId) + if(newImageIdIndex === -1) return + this.stack.currentImageIdIndex = newImageIdIndex + this.stack.imageIdIndex = newImageIdIndex + this.series.imageIdIndex = newImageIdIndex + this.height = (this.stack.currentImageIdIndex) * 100 / (this.stack.imageIds.length - 1) }, getScreenshots() { const canvas = this.canvas.querySelector('canvas') @@ -1248,14 +1248,10 @@ export default { this.stack.imageRendered = true // const { element } = e.detail var imageId = e.detail.image.imageId - var instanceId = imageId.split('/')[imageId.split('/').length - 1] - var frame = null - if (instanceId.includes('?frame=')) { - frame = instanceId.split('?frame=')[1] - instanceId = instanceId.split('?frame=')[0] - } + const imageInfo = this.getInstanceInfo(imageId) + var instanceId = imageInfo.instanceId + var frame = imageInfo.frame this.stack.frame = !isNaN(parseInt(frame)) ? parseInt(frame) : 0 - instanceId = instanceId.split('.')[0] if (this.imageId !== instanceId) { this.getOrientationMarker(e.detail.element) // 初次加载时,如果该影像存在标记,则以标记的窗宽窗位为初始化默认值,否则以序列的窗宽窗位为初始化默认值 @@ -1292,20 +1288,11 @@ export default { if (!imagePlane || !imagePlane.rowCosines || !imagePlane.columnCosines) { return } - const row = getOrientationString(imagePlane.rowCosines) const column = getOrientationString(imagePlane.columnCosines) const oppositeRow = invertOrientationString(row) const oppositeColumn = invertOrientationString(column) - const markers = { - top: oppositeColumn, - bottom: column, - left: oppositeRow, - right: row - } - if (!markers) { - return - } + this.orientationMarkers = [oppositeColumn, row, column, oppositeRow] this.originalMarkers = [oppositeColumn, row, column, oppositeRow] this.setMarkers() @@ -1320,14 +1307,10 @@ export default { this.activeTool = 1 this.activeToolName = '' var { imageId } = element.image - var instanceId = imageId.split('/')[imageId.split('/').length - 1] - var frame = null - if (instanceId.includes('?frame=')) { - frame = instanceId.split('?frame=')[1] - instanceId = instanceId.split('?frame=')[0] - } + const imageInfo = this.getInstanceInfo(imageId) + var instanceId = imageInfo.instanceId + var frame = imageInfo.frame this.stack.frame = !isNaN(parseInt(frame)) ? parseInt(frame) : 0 - instanceId = instanceId.split('.')[0] if (e.detail.toolName === 'Length' || e.detail.toolName === 'ArrowAnnotate' || e.detail.toolName === 'RectangleRoi') { const measureData = {} measureData.studyId = this.stack.studyId @@ -1337,6 +1320,7 @@ export default { measureData.data = e.detail.measurementData measureData.type = e.detail.toolName measureData.thick = this.dicomInfo.thick + measureData.location = this.dicomInfo.location measureData.ww = Math.round(viewport.voi.windowWidth) measureData.wc = Math.round(viewport.voi.windowCenter) @@ -1353,6 +1337,7 @@ export default { measureData.data = e.detail.measurementData measureData.type = e.detail.toolName measureData.thick = this.dicomInfo.thick + measureData.location = this.dicomInfo.location measureData.ww = Math.round(viewport.voi.windowWidth) measureData.wc = Math.round(viewport.voi.windowCenter) const canvas = this.canvas.querySelector('canvas') @@ -1404,9 +1389,9 @@ export default { var element = cornerstone.getEnabledElement(this.canvas) const { rowPixelSpacing, colPixelSpacing } = this.getPixelSpacing(element.image) const dx = - (data.handles.end.x - data.handles.start.x) * (colPixelSpacing || 1) + (data.handles.end.x - data.handles.start.x) * (colPixelSpacing || 1) const dy = - (data.handles.end.y - data.handles.start.y) * (rowPixelSpacing || 1) + (data.handles.end.y - data.handles.start.y) * (rowPixelSpacing || 1) const length = Math.sqrt(dx * dx + dy * dy) return length.toFixed(this.digitPlaces) @@ -1420,9 +1405,9 @@ export default { if (imagePlane) { return { rowPixelSpacing: - imagePlane.rowPixelSpacing || imagePlane.rowImagePixelSpacing, + imagePlane.rowPixelSpacing || imagePlane.rowImagePixelSpacing, colPixelSpacing: - imagePlane.columnPixelSpacing || imagePlane.colImagePixelSpacing + imagePlane.columnPixelSpacing || imagePlane.colImagePixelSpacing } } @@ -1432,7 +1417,7 @@ export default { } }, onMeasurementremoved(e) { - + console.log('================移除病灶=================', e) }, onMeasurementmodified(e) { // 移动 @@ -1442,14 +1427,10 @@ export default { var element = cornerstone.getEnabledElement(this.canvas) var viewport = element.viewport var { imageId } = element.image - var instanceId = imageId.split('/')[imageId.split('/').length - 1] - var frame = null - if (instanceId.includes('?frame=')) { - frame = instanceId.split('?frame=')[1] - instanceId = instanceId.split('?frame=')[0] - } + const imageInfo = this.getInstanceInfo(imageId) + var instanceId = imageInfo.instanceId + var frame = imageInfo.frame this.stack.frame = !isNaN(parseInt(frame)) ? parseInt(frame) : 0 - instanceId = instanceId.split('.')[0] var uuid = measurementData.uuid var idx = this.measureData.findIndex(item => item.MeasureData && item.MeasureData.data && item.MeasureData.data.uuid === uuid) @@ -1467,6 +1448,7 @@ export default { measureData.data = measurementData measureData.type = toolType measureData.thick = this.dicomInfo.thick + measureData.location = this.dicomInfo.location measureData.ww = Math.round(viewport.voi.windowWidth) measureData.wc = Math.round(viewport.voi.windowCenter) measureData.data.active = false @@ -1506,11 +1488,8 @@ export default { // 判断有没有标记 获取第一个标记 var element = cornerstone.getEnabledElement(this.canvas) var { imageId } = element.image - var instanceId = imageId.split('/')[imageId.split('/').length - 1] - if (instanceId.includes('?frame=')) { - instanceId = instanceId.split('?frame=')[0] - } - instanceId = instanceId.split('.')[0] + const imageInfo = this.getInstanceInfo(imageId) + var instanceId = imageInfo.instanceId var idx = this.measureData.findIndex(item => item.InstanceId === instanceId) var measureData = null if (idx > -1) { @@ -1628,18 +1607,19 @@ export default { } }, - toggleClipPlay() { - if (this.toolState.clipPlaying) { + toggleClipPlay(isPlay) { + if (isPlay) { + this.toolState.clipPlaying = true + cornerstoneTools.playClip(this.canvas, this.dicomInfo.fps) + cornerstoneTools.getToolState( + this.canvas, + 'playClip' + ).data[0].loop = false + } else { cornerstoneTools.stopClip(this.canvas) this.toolState.clipPlaying = false return } - this.toolState.clipPlaying = true - cornerstoneTools.playClip(this.canvas, this.dicomInfo.fps) - cornerstoneTools.getToolState( - this.canvas, - 'playClip' - ).data[0].loop = false }, setFps(fps) { this.dicomInfo.fps = fps @@ -1925,6 +1905,14 @@ export default { } } }, + getInstanceInfo(imageId) { + const params = {} + const searchParams = new URLSearchParams(imageId.split('?')[1]) + for (const [key, value] of searchParams.entries()) { + params[key] = value + } + return params + }, preventDefault(e) { e.stopImmediatePropagation() e.stopPropagation() @@ -1942,87 +1930,87 @@ export default { diff --git a/src/views/trials/trials-panel/reading/dicoms/customize/CustomizeDicomViewer.vue b/src/views/trials/trials-panel/reading/dicoms/customize/CustomizeDicomViewer.vue index 1dccd8d7..9856780e 100644 --- a/src/views/trials/trials-panel/reading/dicoms/customize/CustomizeDicomViewer.vue +++ b/src/views/trials/trials-panel/reading/dicoms/customize/CustomizeDicomViewer.vue @@ -2,56 +2,50 @@
- -
+ +