From f60d845725d707a79f64d654626ba20992e77342 Mon Sep 17 00:00:00 2001 From: caiyiling <1321909229@qq.com> Date: Fri, 13 Jun 2025 16:06:54 +0800 Subject: [PATCH] =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E9=98=85=E7=89=87?= =?UTF-8?q?=E6=9B=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/modules/dicom3d.js | 8 +- .../components/customize/QuestionFormItem.vue | 78 +- .../components/customize/QuestionList.vue | 746 ++++++++++++------ .../customize/QuestionTableFormItem.vue | 2 +- 4 files changed, 541 insertions(+), 293 deletions(-) diff --git a/src/store/modules/dicom3d.js b/src/store/modules/dicom3d.js index 486a5c08..aafc27a1 100644 --- a/src/store/modules/dicom3d.js +++ b/src/store/modules/dicom3d.js @@ -1,6 +1,6 @@ const getDefaultState = () => { return { - operateInfo: {}, + operateInfo: [], deleteAnnotationIds: [] } } @@ -11,11 +11,11 @@ const mutations = { } const actions = { - setOperateInfo({ state }, obj) { - state.operateInfo = Object.assign({}, obj) + setOperateInfo({ state }, arr) { + state.operateInfo = arr }, setDeleteAnnotationIds({ state }, arr) { - state.deleteAnnotationIds = Object.assign({}, obj) + state.deleteAnnotationIds = arr }, } diff --git a/src/views/trials/trials-panel/reading/dicoms3D/components/customize/QuestionFormItem.vue b/src/views/trials/trials-panel/reading/dicoms3D/components/customize/QuestionFormItem.vue index 5edd289e..7007ff78 100644 --- a/src/views/trials/trials-panel/reading/dicoms3D/components/customize/QuestionFormItem.vue +++ b/src/views/trials/trials-panel/reading/dicoms3D/components/customize/QuestionFormItem.vue @@ -580,22 +580,26 @@ export default { immediate: true, handler(v) { + let i = v.findIndex(i=>i.QuestionId === this.question.Id) - const { parentQsId, rowId } = v - if (this.question.Id !== parentQsId) return + if (i === -1) return + // const { parentQsId, rowId } = v + // if (this.question.Id !== parentQsId) return if (this.addOrEdit.visible) { // 如果不是当前窗口绑定的标记如何处理? this.setAnswerToQuestion(v) } else { - // 激活弹窗 - // const { parentQsId, rowId } = v - if (!parentQsId && !rowId) return - let arr = this.questionForm[parentQsId] - if (!arr || !Array.isArray(arr)) return - let i = arr.findIndex(i=>i.RowId === rowId) - if (i === -1) return - this.openAddTableCol(this.question, i) + if (v.length === 1) { + const { parentQsId, rowId } = v[0] + if (!parentQsId && !rowId) return + let arr = this.questionForm[parentQsId] + if (!arr || !Array.isArray(arr)) return + let i = arr.findIndex(i=>i.RowId === rowId) + if (i === -1) return + this.openAddTableCol(this.question, i) + } + } } } @@ -1096,7 +1100,9 @@ export default { this.AnswersList = row.TableQuestions.Answers if (!index && index !== 0) { this.addOrEdit.type = 'add' - this.QuestionsForm = {RowIndex: this.questionForm[this.question.Id].length + 1} + this.QuestionsForm = {} + this.$set(this.QuestionsForm, 'RowIndex', this.questionForm[this.question.Id].length + 1) + this.$set(this.QuestionsForm, 'RowId', '') } else { this.addOrEdit.type = 'edit' this.QuestionsForm = Object.assign({}, this.questionForm[row.Id][index]) @@ -1204,31 +1210,35 @@ export default { unBindAnnotationToQuestion(obj) { this.$emit('unBindAnnotationToQuestion', obj) }, - setAnswerToQuestion(obj) { - console.log('setAnswerToQuestion') - let val = null - const {questionId, annotation} = obj - if (!questionId || !annotation) return - const referencedImageId = annotation.metadata.referencedImageId - if (annotation.metadata.toolName === 'Length') { - let length = annotation.data.cachedStats[`imageId:${referencedImageId}`].length - val = length ? parseFloat(length).toFixed(this.digitPlaces) : length + setAnswerToQuestion(arr) { + if (!Array.isArray(arr)) return + const tableQuestions = this.question.TableQuestions.Questions || [] - } else if (annotation.metadata.toolName === 'Bidirectional') { - if (obj.imageToolAttribute === 'length') { - let length = annotation.data.cachedStats[`imageId:${referencedImageId}`].length - val = length ? parseFloat(length).toFixed(this.digitPlaces) : length - this.$set(this.QuestionsForm, questionId, length) - } else if (obj.imageToolAttribute === 'width') { - let short = annotation.data.cachedStats[`imageId:${referencedImageId}`].width - val = short ? parseFloat(short).toFixed(this.digitPlaces) : short + arr.forEach(item => { + if (!item.TableQuestionId || !item.MeasureData) return + if (!item.ImageToolAttribute) { + const targetQuestion = tableQuestions.find(q => q.Id === item.TableQuestionId) + if (targetQuestion) { + item.ImageToolAttribute = targetQuestion.ImageToolAttribute + } } - } - this.$set(this.QuestionsForm, questionId, val) - - // this.AnswersList.push(this.QuestionsForm) - // this.$emit('setFormItemData', {key: this.question.Id, val: this.AnswersList, question: this.question}) - // this.formItemNumberChange(this.question.Id, true) + const val = this.getAnnotationProp(item.MeasureData, item.ImageToolAttribute) + this.$set(this.QuestionsForm, item.TableQuestionId, val) + }) + }, + getAnnotationProp(annotation, prop) { + if (!annotation) return + const referencedImageId = annotation?.metadata?.referencedImageId + if (!referencedImageId) return null + const cacheKey = `imageId:${referencedImageId}` + const cachedStats = annotation.data?.cachedStats?.[cacheKey] + const hasProp = cachedStats + && Object.prototype.hasOwnProperty.call(cachedStats, prop) + if (!hasProp) return null + const value = cachedStats[prop] + return value !== null + ? parseFloat(value).toFixed(this.digitPlaces) + : value }, async beforeClose(done) { try { diff --git a/src/views/trials/trials-panel/reading/dicoms3D/components/customize/QuestionList.vue b/src/views/trials/trials-panel/reading/dicoms3D/components/customize/QuestionList.vue index 50c191d6..4fac4075 100644 --- a/src/views/trials/trials-panel/reading/dicoms3D/components/customize/QuestionList.vue +++ b/src/views/trials/trials-panel/reading/dicoms3D/components/customize/QuestionList.vue @@ -363,213 +363,385 @@ export default { const i = this.questionMarkInfoList.findIndex(i => i.MeasureData && i.MeasureData.annotationUID === annotation.annotationUID) return i > -1 }, - async operateImageMarker(obj) { - this.operateStateEnum = obj.operateStateEnum - this.isTableQuestion = obj.question.IsTableQuestion ? true : false - this.imageTool = obj.question.ImageTool - this.imageToolAttribute = obj.question.ImageToolAttribute - this.operateQuestionId = obj.question.Id - this.operateRowId = obj.question.RowId - this.operateParentQsId = obj.question.ParentQsId - if (obj.operateStateEnum === 0) { - // 绑定标记 - this.$emit('setReadingToolPassive') - } else if (obj.operateStateEnum === 1) { - // 添加标记 - this.$emit('setReadingToolActive', obj.question.ImageTool) - } else if (obj.operateStateEnum === 2) { - // 查看标记 - let i = -1 - if (this.isTableQuestion) { - if (this.operateRowId) { - i = this.questionMarkInfoList.findIndex(i => i.TableQuestionId === obj.question.Id && i.RowId === this.operateRowId) - } else { - i = this.questionMarkInfoList.findIndex(i => i.TableQuestionId === obj.question.Id && !i.RowId) - } - } else { - i = this.questionMarkInfoList.findIndex(i => i.QuestionId === obj.question.Id) - } - if (i > -1) { - const annotation = this.questionMarkInfoList[i].MeasureData - this.$emit('viewCustomAnnotationSeries', { visitTaskId: this.visitTaskId, annotation }) - } - } else if (obj.operateStateEnum === 3) { - // 更改标记 - this.$emit('setReadingToolPassive') - } else if (obj.operateStateEnum === 4) { - this.$emit('setReadingToolPassive') - // 移除标记 - let i = -1 - let questionMarkInfo = {} - if (this.isTableQuestion) { - if (this.operateRowId) { - i = this.questionMarkInfoList.findIndex(i => i.TableQuestionId === obj.question.Id && i.RowId === this.operateRowId) - } else { - i = this.questionMarkInfoList.findIndex(i => i.TableQuestionId === obj.question.Id && !i.RowId) - } - } else { - this.$set(this.questionForm, obj.question.Id, '') - i = this.questionMarkInfoList.findIndex(i => i.QuestionId === obj.question.Id) - } - if (i === -1) return - this.questionMarkInfoList[i].MeasureData = '' - this.questionMarkInfoList[i].StudyId = '' - this.questionMarkInfoList[i].SeriesId = '' - this.questionMarkInfoList[i].InstanceId = '' - questionMarkInfo = this.questionMarkInfoList[i] - questionMarkInfo.isMarked = false - questionMarkInfo.isSaved = false - this.$set(this.questionsMarkStatus, this.operateRowId ? `${this.operateRowId}_${obj.question.Id}` : obj.question.Id, questionMarkInfo) - } else if (obj.operateStateEnum === 5) { - // 保存外层标记 - this.loading = true - try { - const answers = [] - answers.push({ id: obj.question.Id, answer: this.questionForm[obj.question.Id] }) - const markInfo = [] - const i = this.questionMarkInfoList.findIndex(i => i.QuestionId === this.operateQuestionId) - if (i > -1) { - const obj = Object.assign({}, this.questionMarkInfoList[i]) - obj.MeasureData = obj.MeasureData ? JSON.stringify(obj.MeasureData) : '' - markInfo.push(obj) - } - // 上传截图 - const params = { - visitTaskId: this.visitTaskId, - answers: answers, - questionMarkInfoList: markInfo - } - await saveTaskQuestion(-10, params) + // async operateImageMarker(obj) { + // this.operateStateEnum = obj.operateStateEnum + // this.isTableQuestion = obj.question.IsTableQuestion ? true : false + // this.imageTool = obj.question.ImageTool + // this.imageToolAttribute = obj.question.ImageToolAttribute + // this.operateQuestionId = obj.question.Id + // this.operateRowId = obj.question.RowId + // this.operateParentQsId = obj.question.ParentQsId + // if (obj.operateStateEnum === 0) { + // // 绑定标记 + // this.$emit('setReadingToolPassive') + // } else if (obj.operateStateEnum === 1) { + // // 添加标记 + // this.$emit('setReadingToolActive', obj.question.ImageTool) + // } else if (obj.operateStateEnum === 2) { + // // 查看标记 + // let i = -1 + // if (this.isTableQuestion) { + // if (this.operateRowId) { + // i = this.questionMarkInfoList.findIndex(i => i.TableQuestionId === obj.question.Id && i.RowId === this.operateRowId) + // } else { + // i = this.questionMarkInfoList.findIndex(i => i.TableQuestionId === obj.question.Id && !i.RowId) + // } + // } else { + // i = this.questionMarkInfoList.findIndex(i => i.QuestionId === obj.question.Id) + // } + // if (i > -1) { + // const annotation = this.questionMarkInfoList[i].MeasureData + // this.$emit('viewCustomAnnotationSeries', { visitTaskId: this.visitTaskId, annotation }) + // } + // } else if (obj.operateStateEnum === 3) { + // // 更改标记 + // this.$emit('setReadingToolPassive') + // } else if (obj.operateStateEnum === 4) { + // this.$emit('setReadingToolPassive') + // // 移除标记 + // let i = -1 + // let questionMarkInfo = {} + // if (this.isTableQuestion) { + // if (this.operateRowId) { + // i = this.questionMarkInfoList.findIndex(i => i.TableQuestionId === obj.question.Id && i.RowId === this.operateRowId) + // } else { + // i = this.questionMarkInfoList.findIndex(i => i.TableQuestionId === obj.question.Id && !i.RowId) + // } + // } else { + // this.$set(this.questionForm, obj.question.Id, '') + // i = this.questionMarkInfoList.findIndex(i => i.QuestionId === obj.question.Id) + // } + // if (i === -1) return + // this.questionMarkInfoList[i].MeasureData = '' + // this.questionMarkInfoList[i].StudyId = '' + // this.questionMarkInfoList[i].SeriesId = '' + // this.questionMarkInfoList[i].InstanceId = '' + // questionMarkInfo = this.questionMarkInfoList[i] + // questionMarkInfo.isMarked = false + // questionMarkInfo.isSaved = false + // this.$set(this.questionsMarkStatus, this.operateRowId ? `${this.operateRowId}_${obj.question.Id}` : obj.question.Id, questionMarkInfo) + // } else if (obj.operateStateEnum === 5) { + // // 保存外层标记 + // this.loading = true + // try { + // const answers = [] + // answers.push({ id: obj.question.Id, answer: this.questionForm[obj.question.Id] }) + // const markInfo = [] + // const i = this.questionMarkInfoList.findIndex(i => i.QuestionId === this.operateQuestionId) + // if (i > -1) { + // const obj = Object.assign({}, this.questionMarkInfoList[i]) + // obj.MeasureData = obj.MeasureData ? JSON.stringify(obj.MeasureData) : '' + // markInfo.push(obj) + // } + // // 上传截图 + // const params = { + // visitTaskId: this.visitTaskId, + // answers: answers, + // questionMarkInfoList: markInfo + // } + // await saveTaskQuestion(-10, params) - this.$set(this.questionsMarkStatus, obj.question.Id, {isMarked: this.questionMarkInfoList[i].MeasureData ? true : false, isSaved: true}) - this.loading = false - } catch (e) { - console.log(e) - this.loading = false - } - } else if (obj.operateStateEnum === 6) { - // 更改数值内容 - let questionMarkInfo = {} - if (this.isTableQuestion) { - questionMarkInfo.isMarked = false - questionMarkInfo.isSaved = false - } else { - questionMarkInfo.isMarked = false - questionMarkInfo.isSaved = false - } - this.$set(this.questionsMarkStatus, this.operateRowId ? `${this.operateRowId}_obj.question.Id` : obj.question.Id, questionMarkInfo) - } else if (obj.operateStateEnum === 7) { - // 保存表格问题标记 - const loading = this.$loading({ fullscreen: true }) - try { - let annotation = null - if (!this.operateRowId && this.operateQuestionId && obj.rowId) { - const i = this.questionMarkInfoList.findIndex(i => i.TableQuestionId === this.operateQuestionId && !i.RowId) - if (i === -1) return - this.questionMarkInfoList[i].RowId = obj.rowId - this.operateRowId = obj.rowId - annotation = this.questionMarkInfoList[i].MeasureData - let questionMarkStatus = Object.assign({}, this.questionsMarkStatus[this.operateQuestionId]) - delete this.questionsMarkStatus[this.operateQuestionId] - this.$set(this.questionsMarkStatus, `${obj.rowId}_${this.operateQuestionId}`, questionMarkStatus) - } else if (this.operateRowId && this.operateQuestionId) { - const i = this.questionMarkInfoList.findIndex(i => i.RowId === this.operateRowId && i.TableQuestionId === this.operateQuestionId) - if (i === -1) return - annotation = this.questionMarkInfoList[i].MeasureData - } - let picturePath = '' - if (annotation) { - // 上传截图 - const base64Str = await this.getScreenshots({ visitTaskId: this.visitTaskId, annotation }) - const pictureObj = await this.uploadScreenshots(`${new Date().getTime()}`, base64Str) - picturePath = pictureObj.isSuccess ? this.$getObjectName(pictureObj.result.url) : '' - } - let params = { - Answer: obj.answer, - VisitTaskId: this.visitTaskId, - QuestionId: obj.question.ParentQsId, - InstanceId: annotation ? annotation.instanceId : '', - SeriesId: annotation ? annotation.seriesId : '', - StudyId: annotation ? annotation.studyId : '', - MarkTool: annotation ? annotation.markTool : '', - PicturePath: picturePath, - NumberOfFrames: annotation ? annotation.numberOfFrames : null, - MeasureData: annotation ? JSON.stringify(annotation) : '', - QuestionType: 0, - OrderMarkName: annotation ? annotation.data.label : '', - RowId: this.operateRowId, - TableQuestionId: this.operateQuestionId, - RowIndex: obj.rowIndex - } - // 保存标记 - await saveTableQuestionMark(params, -10) - this.$set(this.questionsMarkStatus, `${this.operateRowId}_${this.operateQuestionId}`, {isMarked: annotation ? true : false, isSaved: true}) - this.resetOperateState() - loading.close() - } catch(e) { - console.log(e) - loading.close() + // this.$set(this.questionsMarkStatus, obj.question.Id, {isMarked: this.questionMarkInfoList[i].MeasureData ? true : false, isSaved: true}) + // this.loading = false + // } catch (e) { + // console.log(e) + // this.loading = false + // } + // } else if (obj.operateStateEnum === 6) { + // // 更改数值内容 + // let questionMarkInfo = {} + // if (this.isTableQuestion) { + // questionMarkInfo.isMarked = false + // questionMarkInfo.isSaved = false + // } else { + // questionMarkInfo.isMarked = false + // questionMarkInfo.isSaved = false + // } + // this.$set(this.questionsMarkStatus, this.operateRowId ? `${this.operateRowId}_obj.question.Id` : obj.question.Id, questionMarkInfo) + // } else if (obj.operateStateEnum === 7) { + // // 保存表格问题标记 + // const loading = this.$loading({ fullscreen: true }) + // try { + // let annotation = null + // if (!this.operateRowId && obj.rowId && obj.question.ParentQsId) { + // this.operateRowId = obj.rowId + // this.questionMarkInfoList.forEach(item => { + // if (item.QuestionId === obj.question.ParentQsId && !item.RowId) { + // item.RowId = obj.rowId + // let questionMarkStatus = Object.assign({}, this.questionsMarkStatus[item.TableQuestionId]) + // delete this.questionsMarkStatus[item.TableQuestionId] + // if (item.TableQuestionId === this.operateQuestionId) { + // annotation = item.MeasureData + // this.$set(this.questionsMarkStatus, `${obj.rowId}_${item.TableQuestionId}`, questionMarkStatus) + // } else { + // this.$set(this.questionsMarkStatus, `${obj.rowId}_${item.TableQuestionId}`, {isMarked: item.MeasureData ? true : false, isSaved: false}) + // } + + // } + // }) + // } else if (this.operateRowId && this.operateQuestionId) { + // const i = this.questionMarkInfoList.findIndex(i => i.RowId === this.operateRowId && i.TableQuestionId === this.operateQuestionId) + // if (i === -1) return + // annotation = this.questionMarkInfoList[i].MeasureData + // } + // let picturePath = '' + // if (annotation) { + // // 上传截图 + // const base64Str = await this.getScreenshots({ visitTaskId: this.visitTaskId, annotation }) + // const pictureObj = await this.uploadScreenshots(`${new Date().getTime()}`, base64Str) + // picturePath = pictureObj.isSuccess ? this.$getObjectName(pictureObj.result.url) : '' + // } + // let params = { + // Answer: obj.answer, + // VisitTaskId: this.visitTaskId, + // QuestionId: obj.question.ParentQsId, + // InstanceId: annotation ? annotation.instanceId : '', + // SeriesId: annotation ? annotation.seriesId : '', + // StudyId: annotation ? annotation.studyId : '', + // MarkTool: annotation ? annotation.markTool : '', + // PicturePath: picturePath, + // NumberOfFrames: annotation ? annotation.numberOfFrames : null, + // MeasureData: annotation ? JSON.stringify(annotation) : '', + // QuestionType: 0, + // OrderMarkName: annotation ? annotation.data.label : '', + // RowId: this.operateRowId, + // TableQuestionId: this.operateQuestionId, + // RowIndex: obj.rowIndex + // } + // // 保存标记 + // await saveTableQuestionMark(params, -10) + // this.$set(this.questionsMarkStatus, `${this.operateRowId}_${this.operateQuestionId}`, {isMarked: annotation ? true : false, isSaved: true}) + // this.resetOperateState() + // loading.close() + // } catch(e) { + // console.log(e) + // loading.close() + // } + // } + // }, + async operateImageMarker(obj) { + const STATE = { + BIND: 0, // 绑定标记 + ADD: 1, // 添加标记 + VIEW: 2, // 查看标记 + CHANGE: 3, // 更改标记 + REMOVE: 4, // 移除标记 + SAVE_OUTER: 5, // 保存外层标记 + UPDATE: 6, // 更改数值内容 + SAVE_TABLE: 7 // 保存表格标记 + } + const { question, operateStateEnum, rowId, answer } = obj + const { Id, IsTableQuestion, ImageTool, ImageToolAttribute, ParentQsId, RowId } = question + + Object.assign(this, { + operateStateEnum, + isTableQuestion: !!IsTableQuestion, + imageTool: ImageTool, + imageToolAttribute: ImageToolAttribute, + operateQuestionId: Id, + operateRowId: RowId, + operateParentQsId: ParentQsId + }) + const stateHandlers = { + [STATE.BIND]: () => this.$emit('setReadingToolPassive'), + [STATE.ADD]: () => this.$emit('setReadingToolActive', ImageTool), + [STATE.VIEW]: this.handleViewState, + [STATE.CHANGE]: () => this.$emit('setReadingToolPassive'), + [STATE.REMOVE]: this.handleRemoveState, + [STATE.SAVE_OUTER]: this.handleSaveOuterState, + [STATE.UPDATE]: this.handleUpdateState, + [STATE.SAVE_TABLE]: this.handleSaveTableState + } + + const handler = stateHandlers[operateStateEnum] + handler && await handler.call(this, obj) + }, + async handleViewState(obj) { + const index = this.findMarkIndex(obj.question) + if (index === -1) return + const annotation = this.questionMarkInfoList[index].MeasureData + this.$emit('viewCustomAnnotationSeries', { + visitTaskId: this.visitTaskId, + annotation + }) + }, + handleRemoveState(obj) { + const index = this.findMarkIndex(obj.question) + if (index === -1) return + Object.assign(this.questionMarkInfoList[index], { + MeasureData: '', + StudyId: '', + SeriesId: '', + InstanceId: '' + }) + const key = this.operateRowId + ? `${this.operateRowId}_${obj.question.Id}` + : obj.question.Id + this.$set(this.questionsMarkStatus, key, { + isMarked: false, + isSaved: false + }) + }, + async handleSaveOuterState(obj) { + this.loading = true; + try { + const answers = [{ id: obj.question.Id, answer: this.questionForm[obj.question.Id] }] + const markInfo = [] + + const index = this.questionMarkInfoList.findIndex( + item => item.QuestionId === this.operateQuestionId + ) + + if (index > -1) { + const item = { ...this.questionMarkInfoList[index] } + item.MeasureData = item.MeasureData ? JSON.stringify(item.MeasureData) : '' + markInfo.push(item) } + + await saveTaskQuestion(-10, { + visitTaskId: this.visitTaskId, + answers, + questionMarkInfoList: markInfo + }) + this.$set(this.questionsMarkStatus, obj.question.Id, { + isMarked: !!this.questionMarkInfoList[index]?.MeasureData, + isSaved: true + }) + } catch (e) { + console.error('保存失败:', e) + } finally { + this.loading = false } }, - - async bindAnnotationToQuestion(annotation) { - console.log('bindAnnotationToQuestion') + handleUpdateState(obj) { + const key = this.operateRowId + ? `${this.operateRowId}_${obj.question.Id}` + : obj.question.Id + this.$set(this.questionsMarkStatus, key, { + isMarked: false, + isSaved: false + }) + }, + async handleSaveTableState(obj) { + const loading = this.$loading({ fullscreen: true }) try { - if (!(this.operateStateEnum === null || this.operateStateEnum === 0 || this.operateStateEnum === 1 || this.operateStateEnum === 3)) return - if (this.operateStateEnum === 1 && annotation.markTool !== this.imageTool) return - if (this.operateStateEnum === null) { - for(let i = 0; i < this.questionMarkInfoList.length; i++) { - if (this.questionMarkInfoList[i].MeasureData.annotationUID === annotation.annotationUID) { - this.questionMarkInfoList[i].MeasureData = annotation - if (this.questionMarkInfoList[i].TableQuestionId) { - store.dispatch('dicom3d/setOperateInfo', {annotation, parentQsId: this.questionMarkInfoList[i].QuestionId, questionId: this.questionMarkInfoList[i].TableQuestionId, rowId: this.questionMarkInfoList[i].RowId, imageToolAttribute: this.questionMarkInfoList[i].MarkTool}) - - let keyId = i > -1 && this.questionMarkInfoList[i].RowId ? `${this.questionMarkInfoList[i].RowId}_${this.questionMarkInfoList[i].TableQuestionId}` : this.questionMarkInfoList[i].TableQuestionId - this.$set(this.questionsMarkStatus, keyId, {isMarked: true, isSaved: false}) - } else { - this.setAnswerToQuestion(annotation, this.questionMarkInfoList[i].QuestionId) - this.$set(this.questionsMarkStatus, this.questionMarkInfoList[i].QuestionId, {isMarked: true, isSaved: false}) - } - } + let annotation = null + if (!this.operateRowId && obj.rowId && obj.question.ParentQsId) { + this.updateQuestionsMarkStatus(obj) + annotation = this.getAnnotationByRow(obj.rowId) + } else if (this.operateRowId && this.operateQuestionId) { + annotation = this.getAnnotationByRow(this.operateRowId) + } + // 截图上传 + let picturePath = '' + if (annotation) { + const base64Str = await this.getScreenshots({ + visitTaskId: this.visitTaskId, + annotation + }) + const pictureObj = await this.uploadScreenshots(`${Date.now()}`, base64Str) + picturePath = pictureObj.isSuccess ? this.$getObjectName(pictureObj.result.url) : '' + } + await saveTableQuestionMark({ + Answer: obj.answer, + VisitTaskId: this.visitTaskId, + QuestionId: obj.question.ParentQsId, + ...(annotation ? { + InstanceId: annotation.instanceId, + SeriesId: annotation.seriesId, + StudyId: annotation.studyId, + MarkTool: annotation.markTool, + NumberOfFrames: annotation.numberOfFrames, + MeasureData: JSON.stringify(annotation), + OrderMarkName: annotation.data.label + } : {}), + PicturePath: picturePath, + QuestionType: 0, + RowId: this.operateRowId, + TableQuestionId: this.operateQuestionId, + RowIndex: obj.rowIndex + }, -10) + this.$set(this.questionsMarkStatus, + `${this.operateRowId}_${this.operateQuestionId}`, + { isMarked: !!annotation, isSaved: true } + ) + this.resetOperateState() + } catch(e) { + console.error('表格保存失败:', e) + } finally { + loading.close() + } + }, + findMarkIndex(question) { + const { Id, RowId } = question + if (this.isTableQuestion) { + return RowId + ? this.questionMarkInfoList.findIndex(i => + i.TableQuestionId === Id && i.RowId === RowId) + : this.questionMarkInfoList.findIndex(i => + i.TableQuestionId === Id && !i.RowId) + } + return this.questionMarkInfoList.findIndex(i => i.QuestionId === Id) + }, + updateQuestionsMarkStatus(obj) { + this.operateRowId = obj.rowId + this.questionMarkInfoList.forEach(item => { + if (item.QuestionId === obj.question.ParentQsId && !item.RowId) { + item.RowId = obj.rowId + const oldKey = item.TableQuestionId + const newKey = `${obj.rowId}_${item.TableQuestionId}` + + if (this.questionsMarkStatus[oldKey]) { + const status = { ...this.questionsMarkStatus[oldKey] } + delete this.questionsMarkStatus[oldKey] + this.$set(this.questionsMarkStatus, newKey, status) } - return + } + }) + }, + getAnnotationByRow(rowId) { + const index = this.questionMarkInfoList.findIndex( + i => i.RowId === rowId && i.TableQuestionId === this.operateQuestionId + ) + return index > -1 ? this.questionMarkInfoList[index].MeasureData : null + }, + async bindAnnotationToQuestion(annotation) { + try { + const VALID_STATES = [null, 0, 1, 3] + const currentState = this.operateStateEnum + if (!VALID_STATES.includes(currentState)) return + const isInvalidAnnotation = currentState === 1 && annotation.markTool !== this.imageTool + if (isInvalidAnnotation) return + if (currentState === null) { + return this.handleNullState(annotation) } if (!this.operateQuestionId) return - if (this.operateStateEnum === 0 || this.operateStateEnum === 3) { - if (!annotation.data.label) { + if ([0, 3].includes(currentState)) { + if (!annotation.data.label || annotation.markTool !== this.imageTool) { this.$alert('该标记不能与问题绑定!') return } - if (annotation.markTool !== this.imageTool) { - this.$alert('该标记不能与问题绑定!') - return - } - // 判断标记是否跟其他rowId绑定 - if (this.operateStateEnum === 3) { - const i = this.questionMarkInfoList.findIndex(i=>i.MeasureData.annotationUID === annotation.annotationUID && i.RowId !== this.operateRowId) - if (i > -1) { + if (currentState === 3) { + const conflictIndex = this.questionMarkInfoList.findIndex( + item => item.MeasureData.annotationUID === annotation.annotationUID + && item.RowId !== this.operateRowId + ) + if (conflictIndex > -1) { this.$alert('该标记已绑定到其他行,不能更改绑定!') return } } - let msg = this.operateStateEnum === 0 ? '是否确认绑定?' : '是否确认更改?' - const confirm = await this.$confirm(msg, { - type: 'warning', - distinguishCancelAndClose: true + const message = currentState === 0 ? '是否确认绑定?' : '是否确认更改?' + const result = await this.$confirm(message, { + type: 'warning', + distinguishCancelAndClose: true }) - if (confirm !== 'confirm') return + const isConfirmed = result === 'confirm' + if (!isConfirmed) return } - let i = -1 - if (this.isTableQuestion && this.operateRowId) { - i = this.questionMarkInfoList.findIndex(i => i.TableQuestionId === this.operateQuestionId && i.RowId === this.operateRowId) - } else if (this.isTableQuestion) { - i = this.questionMarkInfoList.findIndex(i => i.TableQuestionId === this.operateQuestionId && !i.RowId) - } else { - i = this.questionMarkInfoList.findIndex(i => i.QuestionId === this.operateQuestionId) - } - if (i === -1) { - const markInfo = { + const targetIndex = this.findTargetIndex() + if (targetIndex === -1) { + this.questionMarkInfoList.push({ InstanceId: annotation.instanceId, SeriesId: annotation.seriesId, StudyId: annotation.studyId, @@ -577,79 +749,145 @@ export default { PicturePath: '', NumberOfFrames: annotation.numberOfFrames, MeasureData: annotation, - RowId: this.operateRowId ? this.operateRowId : '', - QuestionId: this.isTableQuestion ? this.operateParentQsId : this.operateQuestionId, - TableQuestionId: this.isTableQuestion ? this.operateQuestionId : '', - } - this.questionMarkInfoList.push(markInfo) + RowId: this.operateRowId || '', + QuestionId: this.isTableQuestion + ? this.operateParentQsId + : this.operateQuestionId, + TableQuestionId: this.isTableQuestion + ? this.operateQuestionId + : '' + }) } else { - this.questionMarkInfoList[i].InstanceId = annotation.instanceId - this.questionMarkInfoList[i].SeriesId = annotation.seriesId - this.questionMarkInfoList[i].StudyId = annotation.studyId - this.questionMarkInfoList[i].MarkTool = annotation.metadata.toolName - this.questionMarkInfoList[i].PicturePath = '' - this.questionMarkInfoList[i].NumberOfFrames = annotation.numberOfFrames - this.questionMarkInfoList[i].MeasureData = annotation + const target = this.questionMarkInfoList[targetIndex] + Object.assign(target, { + InstanceId: annotation.instanceId, + SeriesId: annotation.seriesId, + StudyId: annotation.studyId, + MarkTool: annotation.metadata.toolName, + PicturePath: '', + NumberOfFrames: annotation.numberOfFrames, + MeasureData: annotation + }) } - let obj = null - if (this.isTableQuestion) { - obj = {isMarked: true, isSaved: false} - store.dispatch('dicom3d/setOperateInfo', {annotation, parentQsId: this.operateParentQsId, questionId: this.operateQuestionId, rowId: this.operateRowId, imageToolAttribute: this.imageToolAttribute}) - - let keyId = i > -1 && this.questionMarkInfoList[i].RowId ? `${this.questionMarkInfoList[i].RowId}_${this.questionMarkInfoList[i].TableQuestionId}` : this.operateRowId ? `${this.operateRowId}_${this.operateQuestionId}` : this.operateQuestionId - this.$set(this.questionsMarkStatus, keyId, obj) - } else { - obj = {isMarked: true, isSaved: false} - this.setAnswerToQuestion(annotation, this.operateQuestionId) - this.$set(this.questionsMarkStatus, this.operateQuestionId, obj) - } - this.operateStateEnum === null - + this.updateMarkStatus(targetIndex, annotation) + this.operateStateEnum = null } catch (e) { - console.log(e) + console.error('绑定失败:', e); // 增强错误信息 } }, - updateAnnotationToQuestion(annotation) { - const i = this.questionMarkInfoList.findIndex(i => i.MeasureData && i.MeasureData.annotationUID === annotation.annotationUID) - if (i === -1) return - this.questionMarkInfoList[i].MeasureData = annotation - let obj = null - if (this.isTableQuestion || this.questionMarkInfoList[i].TableQuestionId) { - this.operateParentQsId = this.operateParentQsId ? this.operateParentQsId : this.questionMarkInfoList[i].QuestionId - this.operateQuestionId = this.operateQuestionId ? this.operateQuestionId : this.questionMarkInfoList[i].TableQuestionId - this.operateRowId = this.operateRowId ? this.operateRowId : this.questionMarkInfoList[i].RowId - this.imageToolAttribute = this.imageToolAttribute ? this.imageToolAttribute : annotation.metadata.toolName - obj = {isMarked: true, isSaved: false} - store.dispatch('dicom3d/setOperateInfo', {annotation, parentQsId: this.operateParentQsId, questionId: this.operateQuestionId, rowId: this.operateRowId, imageToolAttribute: this.imageToolAttribute}) - let keyId = this.questionMarkInfoList[i].RowId ? `${this.questionMarkInfoList[i].RowId}_${this.questionMarkInfoList[i].TableQuestionId}` : this.questionMarkInfoList[i].TableQuestionId - this.$set(this.questionsMarkStatus, keyId, obj) - - } else { - obj = {isMarked: true, isSaved: false} - this.setAnswerToQuestion(annotation, this.questionMarkInfoList[i].QuestionId) - this.$set(this.questionsMarkStatus, this.questionMarkInfoList[i].QuestionId, obj) + handleNullState(annotation) { + const qsArr = [] + const markList = this.questionMarkInfoList + for (let i = 0; i < markList.length; i++) { + const item = markList[i]; + if (item.MeasureData?.annotationUID !== annotation.annotationUID) continue + item.MeasureData = annotation + + if (item.TableQuestionId) { + qsArr.push({ ...item, ImageToolAttribute: this.imageToolAttribute }) + + const keyId = item.RowId + ? `${item.RowId}_${item.TableQuestionId}` + : item.TableQuestionId + + this.$set(this.questionsMarkStatus, keyId, { + isMarked: true, + isSaved: false + }) + } else { + this.setAnswerToQuestion(annotation, item.QuestionId) + this.$set(this.questionsMarkStatus, item.QuestionId, { + isMarked: true, + isSaved: false + }) + } + } + if (qsArr.length) { + store.dispatch('dicom3d/setOperateInfo', qsArr) + } + }, + findTargetIndex() { + if (this.isTableQuestion && this.operateRowId) { + return this.questionMarkInfoList.findIndex( + item => item.TableQuestionId === this.operateQuestionId + && item.RowId === this.operateRowId + ) + } else if (this.isTableQuestion) { + return this.questionMarkInfoList.findIndex( + item => item.TableQuestionId === this.operateQuestionId + && !item.RowId + ) + } + return this.questionMarkInfoList.findIndex( + item => item.QuestionId === this.operateQuestionId + ) + }, + + updateMarkStatus(index, annotation) { + const status = { isMarked: true, isSaved: false } + if (this.isTableQuestion) { + const keyId = index > -1 && this.questionMarkInfoList[index].RowId + ? `${this.questionMarkInfoList[index].RowId}_${this.questionMarkInfoList[index].TableQuestionId}` + : this.operateRowId + ? `${this.operateRowId}_${this.operateQuestionId}` + : this.operateQuestionId + + this.$set(this.questionsMarkStatus, keyId, status) + store.dispatch('dicom3d/setOperateInfo', [{ + MeasureData: annotation, + QuestionId: this.operateParentQsId, + TableQuestionId: this.operateQuestionId, + RowId: this.operateRowId, + ImageToolAttribute: this.imageToolAttribute + }]) + } else { + this.setAnswerToQuestion(annotation, this.operateQuestionId) + this.$set(this.questionsMarkStatus, this.operateQuestionId, status) + } + }, + + updateAnnotationToQuestion(annotation) { + const questionMarkInfo = { isMarked: true, isSaved: false } + const qsArr = [] + for (let i = 0; i < this.questionMarkInfoList.length; i++) { + const item = this.questionMarkInfoList[i] + if (!item.MeasureData || item.MeasureData.annotationUID !== annotation.annotationUID) continue + item.MeasureData = annotation + const isTableMode = this.isTableQuestion || item.TableQuestionId + if (!isTableMode) { + this.setAnswerToQuestion(annotation, item.QuestionId) + this.$set(this.questionsMarkStatus, item.QuestionId, questionMarkInfo) + continue + } + this.operateParentQsId = item.QuestionId + this.operateQuestionId = item.TableQuestionId + this.operateRowId ||= item.RowId + qsArr.push({ ...item }) + const keyId = item.RowId ? `${item.RowId}_${item.TableQuestionId}` : item.TableQuestionId; + this.$set(this.questionsMarkStatus, keyId, questionMarkInfo); + } + if (qsArr.length > 0) { + store.dispatch('dicom3d/setOperateInfo', qsArr); } - - }, setAnswerToQuestion(annotation, questionId) { if (!questionId || !annotation) return - const referencedImageId = annotation.metadata.referencedImageId - if (annotation.metadata.toolName === 'Length') { - let length = annotation.data.cachedStats[`imageId:${referencedImageId}`].length - length = length ? parseFloat(length).toFixed(this.digitPlaces) : length - this.$set(this.questionForm, questionId, length) - } else if (annotation.metadata.toolName === 'Bidirectional') { - if (this.imageToolAttribute === 'length') { - let length = annotation.data.cachedStats[`imageId:${referencedImageId}`].length - length = length ? parseFloat(length).toFixed(this.digitPlaces) : length - this.$set(this.questionForm, questionId, length) - } else if (this.imageToolAttribute === 'width') { - let short = annotation.data.cachedStats[`imageId:${referencedImageId}`].width - short = short ? parseFloat(short).toFixed(this.digitPlaces) : short - this.$set(this.questionForm, questionId, short) - } - } + let val = this.getAnnotationProp(annotation, this.imageToolAttribute) + this.$set(this.questionForm, questionId, val) + }, + getAnnotationProp(annotation, prop) { + if (!annotation) return + const referencedImageId = annotation?.metadata?.referencedImageId + if (!referencedImageId) return null + const cacheKey = `imageId:${referencedImageId}` + const cachedStats = annotation.data?.cachedStats?.[cacheKey] + const hasProp = cachedStats + && Object.prototype.hasOwnProperty.call(cachedStats, prop) + if (!hasProp) return null + const value = cachedStats[prop] + return value !== null + ? parseFloat(value).toFixed(this.digitPlaces) + : value }, unBindAnnotationToQuestion(obj) { const { markTableQuestions = [], questionId } = obj || {} diff --git a/src/views/trials/trials-panel/reading/dicoms3D/components/customize/QuestionTableFormItem.vue b/src/views/trials/trials-panel/reading/dicoms3D/components/customize/QuestionTableFormItem.vue index 92700433..12add325 100644 --- a/src/views/trials/trials-panel/reading/dicoms3D/components/customize/QuestionTableFormItem.vue +++ b/src/views/trials/trials-panel/reading/dicoms3D/components/customize/QuestionTableFormItem.vue @@ -400,7 +400,7 @@ export default { deep: true, immediate: true, handler(v) { - // console.log(v, this.rowId) + this.$forceUpdate() } } },