自定义阅片表单更改

main
caiyiling 2025-06-12 15:43:59 +08:00
parent dbffc2787d
commit 19bb1eccd8
7 changed files with 844 additions and 187 deletions

View File

@ -50,6 +50,8 @@ const getters = {
IsFirstSysDocNeedSign: state => state.user.IsFirstSysDocNeedSign,
TrialStatusStr: state => state.user.TrialStatusStr,
lastViewportTaskId: state => state.noneDicomReview.lastViewportTaskId,
currentTaskState: state => state.noneDicomReview.currentTaskState
currentTaskState: state => state.noneDicomReview.currentTaskState,
operateInfo: state => state.dicom3d.operateInfo,
deleteAnnotationIds: state => state.dicom3d.deleteAnnotationIds
}
export default getters

View File

@ -13,6 +13,7 @@ import financials from './modules/financials'
import reading from './modules/reading'
import lang from './modules/lang'
import noneDicomReview from './modules/noneDicomReview'
import dicom3d from './modules/dicom3d'
Vue.use(Vuex)
const store = new Vuex.Store({
@ -28,7 +29,8 @@ const store = new Vuex.Store({
financials,
reading,
lang,
noneDicomReview
noneDicomReview,
dicom3d
},
getters
})

View File

@ -0,0 +1,28 @@
const getDefaultState = () => {
return {
operateInfo: {},
deleteAnnotationIds: []
}
}
const state = getDefaultState
const mutations = {
}
const actions = {
setOperateInfo({ state }, obj) {
state.operateInfo = Object.assign({}, obj)
},
setDeleteAnnotationIds({ state }, arr) {
state.deleteAnnotationIds = Object.assign({}, obj)
},
}
export default {
namespaced: true,
state,
mutations,
actions
}

View File

@ -438,6 +438,7 @@
@resetAnnotations="resetAnnotations"
@setReadingTaskState="setReadingTaskState"
@viewCustomAnnotationSeries="viewCustomAnnotationSeries"
@getCustomScreenshots="getCustomScreenshots"
@setReadingToolActive="setReadingToolActive"
@setReadingToolPassive="setReadingToolPassive"
/>
@ -562,6 +563,8 @@ import * as cornerstoneTools from '@cornerstonejs/tools'
import initLibraries from '@/views/trials/trials-panel/reading/dicoms/components/Fusion/js/initLibraries'
import html2canvas from 'html2canvas'
import { getTools, getCustomizeStandardsTools, config } from './toolConfig'
import { mapGetters } from 'vuex'
import store from '@/store'
import StudyList from './StudyList'
import Viewport from './Viewport'
import PetCtViewport from './PetCtViewport'
@ -751,7 +754,7 @@ export default {
},
viewportKey() {
return this.isFusion ? 'viewport-fusion' : 'viewport'
}
},
},
watch: {
activeTaskId: {
@ -1450,15 +1453,19 @@ export default {
annotation.numberOfFrames = isNaN(parseInt(params.frame)) ? null : parseInt(params.frame)
annotation.markTool = annotation.metadata.toolName
this.markedSeriesIds.push(series.Id)
const markName = await this.customPrompt()
const operateStateEnum = this.$refs[`ecrf_${this.taskInfo.VisitTaskId}`][0].operateStateEnum
const markName = await this.customPrompt(!this.isNumber(operateStateEnum))
if (markName) {
annotation.data.label = markName
if (annotation.metadata.toolName === 'ArrowAnnotate') {
annotation.data.text = markName
}
this.saveCustomAnnotation(annotation)
this.$refs[`ecrf_${series.TaskInfo.VisitTaskId}`][0].bindAnnotationToQuestion(annotation)
if (this.isNumber(operateStateEnum)) {
this.$refs[`ecrf_${series.TaskInfo.VisitTaskId}`][0].bindAnnotationToQuestion(annotation)
} else {
this.saveCustomAnnotation(annotation)
}
}
}
@ -1500,8 +1507,13 @@ export default {
if (annotation.metadata.toolName === 'PlanarFreehandROI' && !annotation.data.contour.closed) return
const series = this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].series
if (series && series.TaskInfo.VisitTaskId && series.TaskInfo.VisitTaskId === this.taskInfo.VisitTaskId) {
this.saveCustomAnnotation(annotation)
this.$refs[`ecrf_${series.TaskInfo.VisitTaskId}`][0].updateAnnotationToQuestion(annotation)
const operateStateEnum = this.$refs[`ecrf_${this.taskInfo.VisitTaskId}`][0].operateStateEnum
const isBound = this.$refs[`ecrf_${annotation.visitTaskId}`][0].verifyAnnotationIsBound(annotation)
if (isBound || this.isNumber(operateStateEnum)) {
this.$refs[`ecrf_${series.TaskInfo.VisitTaskId}`][0].updateAnnotationToQuestion(annotation)
} else {
this.saveCustomAnnotation(annotation)
}
}
this.setToolsPassive()
},
@ -1521,7 +1533,7 @@ export default {
}
if (annotation.visitTaskId === this.taskInfo.VisitTaskId) {
const isBound = this.$refs[`ecrf_${annotation.visitTaskId}`][0].verifyAnnotationIsBound(annotation)
if (isBound) {
if (isBound && this.activeTool === 'Eraser') {
this.$alert('该标记已与问题进行绑定,不允许删除!')
const errorMsg = { message: 'annotation Not allowed to operate' }
throw errorMsg
@ -2589,6 +2601,23 @@ export default {
this.$refs[series.TaskInfo.VisitTaskId][0].setSeriesActive(series.StudyIndex, series.SeriesIndex)
}
},
async getCustomScreenshots(obj, callback) {
const i = this.visitTaskList.findIndex(i => i.VisitTaskId === obj.visitTaskId)
if (i === -1) return
const studyList = this.visitTaskList[i].StudyList
const series = this.getMarkedSeries(studyList, obj.annotation)
if (series) {
this.$refs[`${this.viewportKey}-${this.cells.length - 1}`][0].setSeriesInfo(series, true)
this.activeViewportIndex = i
this.$refs[series.TaskInfo.VisitTaskId][0].setSeriesActive(series.StudyIndex, series.SeriesIndex)
const divForDownloadViewport = document.querySelector(
`div[data-viewport-uid="${this.viewportKey}-${this.activeViewportIndex}"]`
)
const canvas = await html2canvas(divForDownloadViewport)
const base64Str = canvas.toDataURL('image/png', 1)
callback(base64Str)
}
},
async getScreenshots(measureData, callback) {
if (measureData) {
await this.imageLocation(measureData)
@ -2787,12 +2816,13 @@ export default {
return params
},
//
async customPrompt() {
async customPrompt(isShowCancelButton = true) {
try {
const that = this
//
const { value } = await this.$prompt(this.$t('trials:noneDicom:message:msg1'), '', {
showClose: false,
showCancelButton: isShowCancelButton,
beforeClose: (action, instance, done) => {
if (action === 'confirm') {
const value = instance.inputValue
@ -2813,6 +2843,9 @@ export default {
return null
}
},
isNumber(value) {
return typeof value === 'number' && value !== null && !isNaN(value)
},
showPanel(e, toolName) {
if (toolName === 'layout' && this.isFusion) return false
e.currentTarget.firstChild.lastChild.style.display = 'block'

View File

@ -54,12 +54,64 @@
<el-button type="text" size="mini" @click="openAddTableCol(question, scope.$index)">
{{$t('common:button:edit')}}
</el-button>
<el-button type="text" size="mini" v-if="scope.row.IsCurrentTaskAdd === 'True' || !question.IsCopyLesions || isBaseline" @click="deleteTableCol(question, scope.$index)">
<el-button type="text" size="mini" :disabled="addOrEdit.visible" v-if="scope.row.IsCurrentTaskAdd === 'True' || !question.IsCopyLesions || isBaseline" @click="deleteTableCol(question, scope.$index)">
{{$t('common:button:delete')}}
</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog
v-if="addOrEdit.visible"
v-dialogDrag
:title="addOrEdit.title"
:visible.sync="addOrEdit.visible"
:close-on-click-modal="false"
:close-on-press-escape="false"
width="400px"
:modal="false"
:before-close="beforeClose"
>
<div>
<el-form
ref="tableQsForm"
:model="QuestionsForm"
v-loading="loading"
size="small"
>
<QuestionTableFormItem
v-for="(item) in QuestionsList"
:key="item.Id"
:question="item"
:parentQsId="parentQsId"
:isBaseline="isBaseline"
:reading-task-state="readingTaskState"
:question-form="QuestionsForm"
:visit-task-id="visitTaskId"
:criterion-id="criterionId"
:type="addOrEdit.type"
:calculationList="calculationList"
:questionsMarkStatus="questionsMarkStatus"
@formItemTableNumberChange="formItemTableNumberChange"
@resetFormItemData="resetTableFormItemData"
@setFormItemData="setFormTableItemData"
@operateImageMarker="operateImageMarker"
@save="save"
/>
</el-form>
</div>
<div slot="footer" >
<el-button
size="small"
@click="handleCancel"
>
{{ $t('common:button:cancel') }}
</el-button>
<!-- 保存 -->
<el-button size="small" class="my_upload_btn" @click="handleSave">
{{ $t('common:button:save') }}
</el-button>
</div>
</el-dialog>
</div>
<template v-else>
<el-form-item
@ -234,7 +286,7 @@
@change="(val) => { formItemNumberChange(val, question) }"
@blur="questionsMarkStatus[question.Id] && questionsMarkStatus[question.Id].isMarked ? ()=>{} : handleMarkedQsBlur(questionForm[question.Id], questionForm, question.Id, question) "
v-model="questionForm[question.Id]"
:disabled="(questionsMarkStatus[question.Id].isMarked && question.ImageMarkEnum === 2) || question.ImageMarkEnum === 1"
:disabled="(questionsMarkStatus[question.Id] && questionsMarkStatus[question.Id].isMarked && question.ImageMarkEnum === 2) || question.ImageMarkEnum === 1"
style="width: 150px;"
>
<template v-if="question.Unit !== 0" slot="append">
@ -243,7 +295,7 @@
</el-input>
<!-- 测量 -->
<el-button
v-if="readingTaskState < 2 && (!questionsMarkStatus[question.Id].isMarked)"
v-if="readingTaskState < 2 && (!questionsMarkStatus[question.Id] || (questionsMarkStatus[question.Id] && !questionsMarkStatus[question.Id].isMarked))"
size="mini"
type="text"
@click="operateImageMarker({operateStateEnum: 1, question})"
@ -252,7 +304,7 @@
</el-button>
<!-- 绑定 -->
<el-button
v-if="readingTaskState < 2 && (!questionsMarkStatus[question.Id].isMarked)"
v-if="readingTaskState < 2 && (!questionsMarkStatus[question.Id] || (questionsMarkStatus[question.Id] && !questionsMarkStatus[question.Id].isMarked))"
size="mini"
type="text"
@click="operateImageMarker({operateStateEnum: 0, question})"
@ -261,7 +313,7 @@
</el-button>
<!-- 查看 -->
<el-button
v-if="questionsMarkStatus[question.Id].isMarked"
v-if="questionsMarkStatus[question.Id] && questionsMarkStatus[question.Id].isMarked"
size="mini"
type="text"
@click="operateImageMarker({operateStateEnum: 2, question})"
@ -270,7 +322,7 @@
</el-button>
<!-- 更改 -->
<el-button
v-if="readingTaskState < 2 && (questionsMarkStatus[question.Id].isMarked)"
v-if="readingTaskState < 2 && (questionsMarkStatus[question.Id] && questionsMarkStatus[question.Id].isMarked)"
size="mini"
type="text"
@click="operateImageMarker({operateStateEnum: 3, question})"
@ -279,7 +331,7 @@
</el-button>
<!-- 移除 -->
<el-button
v-if="readingTaskState < 2 && (questionsMarkStatus[question.Id].isMarked)"
v-if="readingTaskState < 2 && (questionsMarkStatus[question.Id] && questionsMarkStatus[question.Id].isMarked)"
size="mini"
type="text"
@click="operateImageMarker({operateStateEnum: 4, question})"
@ -288,12 +340,12 @@
</el-button>
<!-- 保存 -->
<el-button
v-if="readingTaskState < 2 && !questionsMarkStatus[question.Id].isSaved"
v-if="readingTaskState < 2 && (questionsMarkStatus[question.Id] && !questionsMarkStatus[question.Id].isSaved)"
size="mini"
type="text"
@click="operateImageMarker({operateStateEnum: 5, question})"
>
<el-tooltip v-if="!questionsMarkStatus[question.Id].isSaved" class="item" effect="dark" :content="$t('trials:reading:button:unsaved')" placement="bottom">
<el-tooltip v-if="questionsMarkStatus[question.Id] && !questionsMarkStatus[question.Id].isSaved" class="item" effect="dark" :content="$t('trials:reading:button:unsaved')" placement="bottom">
<i class="el-icon-warning" style="color:red" />
</el-tooltip>
保存
@ -378,51 +430,20 @@
@resetFormItemData="resetFormItemData"
@getQuestions="getQuestions"
@operateImageMarker="operateImageMarker"
@unBindAnnotationToQuestion="unBindAnnotationToQuestion"
/>
</template>
<base-model :config="addOrEdit"
<!-- <base-model :config="addOrEdit"
class="my_dialog"
:close-on-click-modal="false"
:close-on-press-escape="false"
width="400px"
append-to-body
:modal="false"
v-dialogDrag
>
<template slot="dialog-body">
<el-form
ref="tableQsForm"
:model="QuestionsForm"
v-loading="loading"
size="small"
>
<QuestionTableFormItem
v-for="(item) in QuestionsList"
:key="item.Id"
:question="item"
:isBaseline="isBaseline"
:reading-task-state="readingTaskState"
:question-form="QuestionsForm"
:visit-task-id="visitTaskId"
:criterion-id="criterionId"
:type="addOrEdit.type"
:calculationList="calculationList"
@formItemTableNumberChange="formItemTableNumberChange"
@resetFormItemData="resetTableFormItemData"
@setFormItemData="setFormTableItemData"
/>
</el-form>
</template>
<template slot="dialog-footer">
<el-button
size="small"
@click="addOrEdit.visible = false"
>
{{ $t('common:button:cancel') }}
</el-button>
<!-- 保存 -->
<el-button size="small" class="my_upload_btn" @click="handleSave">
{{ $t('common:button:save') }}
</el-button>
</template>
</base-model>
</base-model> -->
<!-- 预览文件 -->
<el-dialog
v-if="previewVisible"
@ -446,10 +467,12 @@
</div>
</template>
<script>
import { deleteReadingRowAnswer, getQuestionCalculateRelation, submitTableQuestion } from '@/api/trials'
import { deleteReadingRowAnswer, getQuestionCalculateRelation, submitTableQuestion, deleteCustomTag } from '@/api/trials'
import QuestionTableFormItem from './QuestionTableFormItem'
import BaseModel from '@/components/BaseModel'
import PreviewFile from '@/components/PreviewFile/index'
import { mapGetters } from 'vuex'
import store from '@/store'
export default {
name: 'QuestionFormItem',
components: { QuestionTableFormItem, BaseModel, PreviewFile },
@ -517,9 +540,14 @@ export default {
classArr: [],
previewVisible: false,
currentPath: '',
currentType: ''
currentType: '',
markTableQuestions: [],
parentQsId: ''
}
},
computed: {
...mapGetters(['operateInfo'])
},
watch: {
questionForm: {
deep: true,
@ -547,8 +575,32 @@ export default {
handler(v, oldv) {
// console.log(v)
}
},
operateInfo: {
immediate: true,
handler(v) {
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)
}
}
}
},
mounted() {
var digitPlaces = Number(localStorage.getItem('digitPlaces'))
this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
@ -605,25 +657,39 @@ export default {
this.$set(a, b, parseFloat(value).toFixed(this.digitPlaces))
this.$emit('operateImageMarker', {operateStateEnum: 6, question})
},
deleteTableCol(row, index) {
this.$confirm(this.$t('trials:uploadNonDicoms:message:msg1')).then(() => {
const loading = this.$loading({ fullscreen: true })
var param = {
async deleteTableCol(row, index) {
let loading = null
try {
let confirm = await this.$confirm(this.$t('trials:uploadNonDicoms:message:msg1'))
if (confirm !== 'confirm') return
loading = this.$loading({ fullscreen: true })
let param = {
visitTaskId: this.visitTaskId,
questionId: row.Id,
rowId: this.questionForm[row.Id][index].RowId
}
deleteReadingRowAnswer(param)
.then(async res => {
if (res.IsSuccess) {
this.$message.success(this.$t('common:message:deletedSuccessfully'))
this.$emit('getQuestions')
}
loading.close()
}).catch(() => {
loading.close()
})
})
let res = await deleteReadingRowAnswer(param)
if (res.IsSuccess) {
//
// let deleteAnnotationIds = []
// let arr = this.questionMarkInfoList.filter(i=>i.RowId === this.questionForm[row.Id][index].RowId)
// for(let i = 0; i < arr.length; i++) {
// if (arr[i].Id && arr[i].MeasureData) {
// let measureData = arr[i].MeasureData
// deleteAnnotationIds.push(measureData.annotationUID)
// await deleteCustomTag(arr[i].Id)
// }
// }
// store.dispatch('dicom3d/setDeleteAnnotationIds', deleteAnnotationIds)
//
this.$message.success(this.$t('common:message:deletedSuccessfully'))
this.$emit('getQuestions')
}
loading.close()
} catch(e) {
loading ? loading.close() : ''
console.log(e)
}
},
setFormTableItemData(obj) {
@ -679,12 +745,27 @@ export default {
getQuestions() {
this.$emit('getQuestions')
},
handleSave() {
this.$refs.tableQsForm.validate(valid => {
async handleSave() {
let loading = null
try {
let valid = await this.$refs.tableQsForm.validate()
if (!valid) return
const loading = this.$loading({ fullscreen: true })
var answers = []
var reg = new RegExp(/^[0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}$/)
//
let isExistUnSaved = false
for(let i = 0; i < this.markTableQuestions.length; i++) {
let keyId = this.QuestionsForm.RowId ? `${this.QuestionsForm.RowId}_${this.markTableQuestions[i]}` : this.markTableQuestions[i]
if (this.questionsMarkStatus[keyId] && !this.questionsMarkStatus[keyId].isSaved) {
isExistUnSaved = true
break
}
}
if (isExistUnSaved) {
this.$alert('存在标记信息未保存!')
return
}
loading = this.$loading({ fullscreen: true })
let answers = []
let reg = new RegExp(/^[0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}$/)
for (const k in this.QuestionsForm) {
if (reg.test(k)) {
if (answers.findIndex(i => i.tableQuestionId === k) === -1) {
@ -692,8 +773,9 @@ export default {
}
}
}
let params = null
if (this.addOrEdit.type === 'edit') {
var params = {
params = {
questionId: this.question.Id,
RowIndex: parseInt(this.QuestionsForm.RowIndex),
RowId: this.QuestionsForm.RowId,
@ -702,22 +784,31 @@ export default {
answerList: answers,
}
} else {
var params = {
params = {
questionId: this.question.Id,
RowIndex: this.questionForm[this.question.Id].length + 1,
RowId: this.QuestionsForm.RowId ? this.QuestionsForm.RowId : '',
visitTaskId: this.visitTaskId,
trialId: this.$route.query.trialId,
answerList: answers,
answerList: answers
}
this.QuestionsForm.RowIndex = this.questionForm[this.question.Id].length + 1
}
submitTableQuestion(params).then(async res => {
let res = await submitTableQuestion(params)
if (res.IsSuccess) {
this.$message.success(this.$t('common:message:savedSuccessfully'))
this.QuestionsForm.RowId = res.Result.RowId
// this.$emit('getQuestions')
this.save()
loading.close()
}).catch(() => { loading.close() })
})
}
loading.close()
} catch (e) {
loading ? loading.close() : ''
console.log(e)
}
},
saveRowInfo() {
},
renderHeader(h, obj) {
let span = document.createElement('span')
@ -749,6 +840,36 @@ export default {
this.addOrEdit.visible = false
})
},
async handleCancel() {
//
let isExistUnSaved = false
for(let i = 0; i < this.markTableQuestions.length; i++) {
let keyId = this.QuestionsForm.RowId ? `${this.QuestionsForm.RowId}_${this.markTableQuestions[i]}` : this.markTableQuestions[i]
if (this.questionsMarkStatus[keyId] && !this.questionsMarkStatus[keyId].isSaved) {
isExistUnSaved = true
break
}
}
if (isExistUnSaved) {
// this.$alert('')
const confirm = await this.$confirm('标记未保存是否确认关闭?', {
type: 'warning',
distinguishCancelAndClose: true
})
if (confirm !== 'confirm') return
//
let obj = {}
if (!this.QuestionsForm.RowId) {
obj.markTableQuestions = this.markTableQuestions
obj.questionId = this.question.Id
this.$emit('unBindAnnotationToQuestion', obj)
}
this.addOrEdit.visible = false
} else {
this.addOrEdit.visible = false
}
},
logic(rules, num = 0) {
try {
if (rules.CalculateQuestionList.length === 0) {
@ -958,18 +1079,24 @@ export default {
});
},
openAddTableCol(row, index) {
if (this.addOrEdit.visible) return
this.parentQsId = row.Id
this.addOrEdit.visible = true
this.addOrEdit.title = row.QuestionName + this.$t('trials:readingUnit:qsList:title:tableQs')
this.QuestionsList = row.TableQuestions.Questions
this.markTableQuestions = []
row.TableQuestions.Questions.map(v=>{
if (v.Type === 'class') {
this.classArr.push({triggerId: v.ClassifyTableQuestionId, classId: v.Id, classifyAlgorithms: v.ClassifyAlgorithms, classifyType: v.ClassifyType})
}
if (v.ImageMarkEnum === 1 || v.ImageMarkEnum == 2) {
this.markTableQuestions.push(v.Id)
}
})
this.AnswersList = row.TableQuestions.Answers
if (!index && index !== 0) {
this.addOrEdit.type = 'add'
this.QuestionsForm = {}
this.QuestionsForm = {RowIndex: this.questionForm[this.question.Id].length + 1}
} else {
this.addOrEdit.type = 'edit'
this.QuestionsForm = Object.assign({}, this.questionForm[row.Id][index])
@ -1011,9 +1138,132 @@ export default {
setFormItemData(obj) {
this.$emit('setFormItemData', obj)
},
operateImageMarker(obj) {
// async operateImageMarker(obj) {
// if (obj.question.IsTableQuestion && obj.operateStateEnum === 4) {
// //
// this.$set(this.QuestionsForm, obj.question.Id, null)
// } else if (obj.question.IsTableQuestion && obj.operateStateEnum === 7 && obj.rowId) {
// this.$set(this.QuestionsForm, 'RowId', obj.rowId)
// }
// this.$emit('operateImageMarker', obj)
// },
async operateImageMarker(obj) {
// if (obj.question.IsTableQuestion && this.question.Id !== obj.question.ParentQsId) return
if (obj.question.IsTableQuestion && obj.operateStateEnum === 4) {
//
this.$set(this.QuestionsForm, obj.question.Id, null)
} else if (obj.question.IsTableQuestion && obj.operateStateEnum === 7 && this.question.Id === obj.question.ParentQsId) {
if (!this.QuestionsForm.RowId) {
//
let loading = null
try {
loading = this.$loading({ fullscreen: true })
let answers = []
let reg = new RegExp(/^[0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}$/)
for (const k in this.QuestionsForm) {
if (reg.test(k)) {
if (answers.findIndex(i => i.tableQuestionId === k) === -1) {
answers.push({ tableQuestionId: k, answer: this.QuestionsForm[k] })
}
}
}
let params = {
questionId: this.question.Id,
RowIndex: this.questionForm[this.question.Id].length + 1,
RowId: this.QuestionsForm.RowId ? this.QuestionsForm.RowId : '',
visitTaskId: this.visitTaskId,
trialId: this.$route.query.trialId,
answerList: answers
}
let res = await submitTableQuestion(params)
if (res.IsSuccess) {
this.QuestionsForm.RowId = res.Result.RowId
obj.rowId = res.Result.RowId
this.AnswersList.push(this.QuestionsForm)
this.$emit('setFormItemData', {key: this.question.Id, val: this.AnswersList, question: this.question})
this.formItemNumberChange(this.question.Id, true)
}
loading.close()
} catch(e) {
console.log(e)
loading.close()
}
} else {
let i = this.AnswersList.findIndex(i=>i.RowId === this.QuestionsForm.RowId)
this.AnswersList[i][obj.question.Id] = this.QuestionsForm[obj.question.Id]
this.$emit('setFormItemData', {key: this.question.Id, val: this.AnswersList, question: this.question})
this.formItemNumberChange(this.question.Id, true)
}
}
this.$emit('operateImageMarker', obj)
},
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
} 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
}
}
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)
},
async beforeClose(done) {
try {
//
let isExistUnSaved = false
for(let i = 0; i < this.markTableQuestions.length; i++) {
let keyId = this.QuestionsForm.RowId ? `${this.QuestionsForm.RowId}_${this.markTableQuestions[i]}` : this.markTableQuestions[i]
if (this.questionsMarkStatus[keyId] && !this.questionsMarkStatus[keyId].isSaved) {
isExistUnSaved = true
break
}
}
if (isExistUnSaved) {
const confirm = await this.$confirm('标记未保存是否确认关闭?', {
type: 'warning',
distinguishCancelAndClose: true
})
if (confirm !== 'confirm') return
//
let obj = {}
if (!this.QuestionsForm.RowId) {
obj.markTableQuestions = this.markTableQuestions
obj.questionId = this.question.Id
this.$emit('unBindAnnotationToQuestion', obj)
}
done()
// this.$alert('')
} else {
done()
}
} catch (e) {
}
},
async uploadScreenshot(param) {
if (!this.visitTaskId) return
const loading = this.$loading({
@ -1095,19 +1345,20 @@ export default {
}
</script>
<style lang="scss" scoped>
.my_dialog{
.criterion-form-item{
width: 100%;
::v-deep .el-form-item__content{
width: auto;
}
//::v-deep .el-input-goup__append{
// background-color: transparent;
// color: #ddd;
// border: 1px solid #5e5e5e;
//}
}
.criterion-form-item {
// 穿
::v-deep .el-dialog{
pointer-events:auto;
margin-right: 15px !important;
margin-top: 30vh !important;
}
::v-deep .el-dialog__wrapper{
pointer-events:none;
}
// .custom-dialog .el-dialog__wrapper {
// pointer-events:none;
// }
::v-deep .el-form-item__label{
color: #c3c3c3;
}
@ -1124,6 +1375,7 @@ export default {
color: #ddd;
border: 1px solid #5e5e5e;
}
}
.criterion-form-item{
::v-deep .criterion-form-item .el-form-item{
display: block;
@ -1142,30 +1394,31 @@ export default {
.el-input{
width:100%;
}
.mb{
margin-bottom: 0px;
}
.disabled{
::v-deep .el-upload--picture-card {
.mb{
margin-bottom: 0px;
}
.disabled{
::v-deep .el-upload--picture-card {
display: none;
}
}
.uploadWrapper{
display: flex;
flex-direction: column;
align-items: flex-start;
}
::v-deep .el-table__body-wrapper::-webkit-scrollbar{
height: 10px!important;
}
::v-deep .el-table__fixed-right::before{
display: none;
}
}
.uploadWrapper{
display: flex;
flex-direction: column;
align-items: flex-start;
}
}
::v-deep .el-table__body-wrapper::-webkit-scrollbar{
height: 10px!important;
}
::v-deep .el-table__fixed-right::before{
display: none;
}
::v-deep .el-upload-list__item-name{
color: #0a84ff;
.el-icon-document{
::v-deep .el-upload-list__item-name{
color: #0a84ff;
.el-icon-document{
color: #0a84ff;
}
}
}
</style>

View File

@ -39,6 +39,7 @@
@setFormItemData="setFormItemData"
@getQuestions="getQuestions"
@operateImageMarker="operateImageMarker"
@unBindAnnotationToQuestion="unBindAnnotationToQuestion"
/>
</template>
@ -79,10 +80,11 @@
<script>
import { getCustomTableQuestionAnswer, changeDicomReadingQuestionAnswer, submitVisitTaskQuestionsInDto, getQuestionCalculateRelation, saveTaskQuestion } from '@/api/trials'
import { setSkipReadingCache, resetReadingTask } from '@/api/reading'
import { setSkipReadingCache, resetReadingTask, saveTableQuestionMark } from '@/api/reading'
import const_ from '@/const/sign-code'
import QuestionFormItem from './QuestionFormItem'
import SignForm from '@/views/trials/components/newSignForm'
import store from '@/store'
export default {
name: 'EcrfList',
components: {
@ -118,13 +120,15 @@ export default {
isBaseLineTask: false,
rerender: true,
questionMarkInfoList: [],
operateStateEnum: null, // 012345
operateStateEnum: null, // 0123456
operateQuestionId: '',
operateRowId: '',
operateParentQsId: '',
isTableQuestion: false,
imageTool: '',
imageToolAttribute: '',
questionsMarkStatus: {},
digitPlaces: 2
digitPlaces: 2,
}
},
mounted() {
@ -136,10 +140,10 @@ export default {
const digitPlaces = Number(localStorage.getItem('digitPlaces'))
this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
this.getQuestionCalculateRelation()
this.getQuestions()
this.getQuestions(true)
},
methods: {
async getQuestions() {
async getQuestions(isInit) {
this.loading = true
try {
const param = {
@ -169,7 +173,9 @@ export default {
this.questions = res.Result.SinglePage
this.questionsMarkStatus = {}
this.questionMarkInfoList = res.OtherInfo.QuestionMarkInfoList.map(i => {
if (i.QuestionId) {
if (i.RowId) {
this.$set(this.questionsMarkStatus, `${i.RowId}_${i.TableQuestionId}`, {isMarked: i.MeasureData !== '', isSaved: true})
} else if (i.QuestionId) {
this.$set(this.questionsMarkStatus, i.QuestionId, {isMarked: i.MeasureData !== '', isSaved: true})
}
if (typeof i.MeasureData === 'string' && i.MeasureData) {
@ -177,6 +183,9 @@ export default {
}
return i
})
if (!isInit) {
this.$emit('resetAnnotations', this.visitTaskId)
}
this.loading = false
}
} catch (e) {
@ -356,9 +365,12 @@ export default {
},
async operateImageMarker(obj) {
this.operateStateEnum = obj.operateStateEnum
this.operateQuestionId = obj.question.Id
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')
@ -367,7 +379,16 @@ export default {
this.$emit('setReadingToolActive', obj.question.ImageTool)
} else if (obj.operateStateEnum === 2) {
//
const i = this.questionMarkInfoList.findIndex(i => i.QuestionId === obj.question.Id)
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 })
@ -378,17 +399,29 @@ export default {
} else if (obj.operateStateEnum === 4) {
this.$emit('setReadingToolPassive')
//
this.$set(this.questionForm, obj.question.Id, '')
const i = this.questionMarkInfoList.findIndex(i => i.QuestionId === obj.question.Id)
if (i > -1) {
this.questionMarkInfoList[i].MeasureData = ''
this.questionMarkInfoList[i].StudyId = ''
this.questionMarkInfoList[i].SeriesId = ''
this.questionMarkInfoList[i].InstanceId = ''
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)
}
this.$set(this.questionsMarkStatus, obj.question.Id, {isMarked: false, isSaved: false})
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 = []
@ -400,6 +433,7 @@ export default {
obj.MeasureData = obj.MeasureData ? JSON.stringify(obj.MeasureData) : ''
markInfo.push(obj)
}
//
const params = {
visitTaskId: this.visitTaskId,
answers: answers,
@ -414,14 +448,93 @@ export default {
this.loading = false
}
} else if (obj.operateStateEnum === 6) {
//
this.$set(this.questionsMarkStatus, obj.question.Id, {isMarked: false, isSaved: false})
//
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()
}
}
},
async bindAnnotationToQuestion(annotation) {
console.log('bindAnnotationToQuestion')
try {
if (!(this.operateStateEnum === 0 || this.operateStateEnum === 1 || this.operateStateEnum === 3)) return
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})
}
}
}
return
}
if (!this.operateQuestionId) return
if (this.operateStateEnum === 0 || this.operateStateEnum === 3) {
if (!annotation.data.label) {
@ -432,6 +545,14 @@ export default {
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) {
this.$alert('该标记已绑定到其他行,不能更改绑定!')
return
}
}
let msg = this.operateStateEnum === 0 ? '是否确认绑定?' : '是否确认更改?'
const confirm = await this.$confirm(msg, {
type: 'warning',
@ -439,19 +560,26 @@ export default {
})
if (confirm !== 'confirm') return
}
console.log('bindAnnotationToQuestion', annotation)
const i = this.questionMarkInfoList.findIndex(i => i.QuestionId === this.operateQuestionId)
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 = {
QuestionId: this.operateQuestionId,
InstanceId: annotation.instanceId,
SeriesId: annotation.seriesId,
StudyId: annotation.studyId,
MarkTool: annotation.metadata.toolName,
PicturePath: '',
NumberOfFrames: annotation.numberOfFrames,
MeasureData: annotation
MeasureData: annotation,
RowId: this.operateRowId ? this.operateRowId : '',
QuestionId: this.isTableQuestion ? this.operateParentQsId : this.operateQuestionId,
TableQuestionId: this.isTableQuestion ? this.operateQuestionId : '',
}
this.questionMarkInfoList.push(markInfo)
} else {
@ -463,8 +591,20 @@ export default {
this.questionMarkInfoList[i].NumberOfFrames = annotation.numberOfFrames
this.questionMarkInfoList[i].MeasureData = annotation
}
this.setAnswerToQuestion(annotation, this.operateQuestionId)
this.$set(this.questionsMarkStatus, this.operateQuestionId, {isMarked: true, isSaved: false})
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
} catch (e) {
console.log(e)
}
@ -472,9 +612,25 @@ export default {
updateAnnotationToQuestion(annotation) {
const i = this.questionMarkInfoList.findIndex(i => i.MeasureData && i.MeasureData.annotationUID === annotation.annotationUID)
if (i === -1) return
this.questionMarkInfoList[i].measureData = annotation
this.setAnswerToQuestion(annotation, this.questionMarkInfoList[i].QuestionId)
this.$set(this.questionsMarkStatus, this.questionMarkInfoList[i].QuestionId, {isMarked: true, isSaved: false})
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)
}
},
setAnswerToQuestion(annotation, questionId) {
if (!questionId || !annotation) return
@ -495,6 +651,61 @@ export default {
}
}
},
unBindAnnotationToQuestion(obj) {
const { markTableQuestions = [], questionId } = obj || {}
const { questionMarkInfoList, questionsMarkStatus } = this
if (!Array.isArray(markTableQuestions) || !questionId || !Array.isArray(questionMarkInfoList)) {
return
}
this.questionMarkInfoList = questionMarkInfoList.filter(item => {
const { TableQuestionId, QuestionId } = item || {}
if ((TableQuestionId && QuestionId === questionId && markTableQuestions.includes(TableQuestionId))) {
if (questionsMarkStatus && questionsMarkStatus[TableQuestionId]) {
delete questionsMarkStatus[TableQuestionId]
}
} else {
return
}
})
},
//
getScreenshots(obj) {
return new Promise((resolve, reject) => {
this.$emit('getCustomScreenshots', obj, resolve) // resolve
})
},
async uploadScreenshots(fileName, file) {
try {
file = this.convertBase64ToBlob(file)
const trialId = this.$route.query.trialId
const taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
const subjectId = taskInfo.SubjectId
const result = await this.OSSclient.put(`/${trialId}/Read/${subjectId}/Visit/${fileName}.png`, file)
return { isSuccess: true, result: result }
} catch (e) {
console.log(e)
return { isSuccess: false, result: e }
}
},
convertBase64ToBlob(imageEditorBase64) {
const base64Arr = imageEditorBase64.split(',')
let imgtype = ''
let base64String = ''
if (base64Arr.length > 1) {
base64String = base64Arr[1]
imgtype = base64Arr[0].substring(
base64Arr[0].indexOf(':') + 1,
base64Arr[0].indexOf(';')
)
}
const bytes = atob(base64String)
const bytesCode = new ArrayBuffer(bytes.length)
const byteArray = new Uint8Array(bytesCode)
for (let i = 0; i < bytes.length; i++) {
byteArray[i] = bytes.charCodeAt(i)
}
return new Blob([bytesCode], { type: imgtype })
},
resetOperateState() {
console.log('resetOperateState')
this.operateStateEnum = null
@ -513,13 +724,14 @@ export default {
}
)
if (confirm !== 'confirm') return
this.$emit('setReadingToolPassive')
const loading = this.$loading({ fullscreen: true })
try {
const res = await resetReadingTask({ visitTaskId: this.visitTaskId })
if (res.IsSuccess) {
this.rerender = false
await this.getQuestionCalculateRelation()
await this.getQuestions()
await this.getQuestions(true)
this.$emit('resetAnnotations', this.visitTaskId)
this.$nextTick(() => {
this.rerender = true

View File

@ -1,5 +1,5 @@
<template>
<div class="criterion-form-item">
<div class="criterion-table-form-item">
<el-form-item
v-if="(question.ShowQuestion===1 && !!~question.ParentTriggerValueList.indexOf(questionForm[question.ParentId])) || question.ShowQuestion===0"
:label="`${question.QuestionName}`"
@ -142,26 +142,100 @@
disabled
/>
<!-- 数值 -->
<!-- :precision="2" :step="0.1" :max="10" -->
<el-input
type="number"
v-if="question.Type === 'number' && question.DataSource !== 1"
:disabled="question.TableQuestionType === 2 || (question.IsCopy && type === 'edit' && !isBaseline && questionForm.IsCurrentTaskAdd === 'False')"
@change="((val)=>{formItemNumberChange(val, question)})"
@blur="handleBlur(questionForm[question.Id], questionForm, question.Id)"
v-model="questionForm[question.Id]"
>
<template slot="append" v-if="question.Unit !== 0">{{question.Unit !== 4 ? $fd('ValueUnit', question.Unit) : question.CustomUnit}}</template>
</el-input>
<el-input
type="number"
v-if="question.Type === 'number' && question.DataSource === 1"
:disabled="question.DataSource === 1"
@blur="handleCalculationBlur(calculationValue)"
v-model="calculationValue"
>
<template slot="append" v-if="question.Unit !== 0">{{question.Unit !== 4 ? $fd('ValueUnit', question.Unit) : question.CustomUnit}}</template>
</el-input>
<template v-if="question.Type === 'number' && (question.ImageMarkEnum === 1 || question.ImageMarkEnum === 2)">
<div style="display: flex;flex-direction: row;justify-content: flex-start;align-items: center;">
<el-input
type="number"
@change="(val) => { formItemNumberChange(val, question) }"
@blur="questionsMarkStatus[question.Id] && questionsMarkStatus[question.Id].isMarked ? ()=>{} : handleMarkedQsBlur(questionForm[question.Id], questionForm, question.Id, question) "
v-model="questionForm[question.Id]"
:disabled="(questionsMarkStatus[question.Id] && questionsMarkStatus[question.Id].isMarked && question.ImageMarkEnum === 2) || question.ImageMarkEnum === 1"
style="width: 150px;"
>
<template v-if="question.Unit !== 0" slot="append">
{{ question.Unit !== 4 ? $fd('ValueUnit', question.Unit) : question.CustomUnit }}
</template>
</el-input>
<!-- 测量 -->
<el-button
v-if="readingTaskState < 2 && (!questionsMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id] || (questionsMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id] && !questionsMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id].isMarked))"
size="mini"
type="text"
@click="operateImageMarker({operateStateEnum: 1, question})"
>
测量
</el-button>
<!-- 绑定 -->
<el-button
v-if="readingTaskState < 2 && (!questionsMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id] || (questionsMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id] && !questionsMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id].isMarked))"
size="mini"
type="text"
@click="operateImageMarker({operateStateEnum: 0, question})"
>
绑定
</el-button>
<!-- 查看 -->
<el-button
v-if="questionsMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id] && questionsMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id].isMarked"
size="mini"
type="text"
@click="operateImageMarker({operateStateEnum: 2, question})"
>
查看
</el-button>
<!-- 更改 -->
<el-button
v-if="readingTaskState < 2 && (questionsMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id] && questionsMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id].isMarked)"
size="mini"
type="text"
@click="operateImageMarker({operateStateEnum: 3, question})"
>
更改
</el-button>
<!-- 移除 -->
<el-button
v-if="readingTaskState < 2 && (questionsMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id] && questionsMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id].isMarked)"
size="mini"
type="text"
@click="operateImageMarker({operateStateEnum: 4, question})"
>
移除
</el-button>
<!-- 保存 -->
<el-button
v-if="readingTaskState < 2 && (questionsMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id] && !questionsMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id].isSaved)"
size="mini"
type="text"
@click="operateImageMarker({operateStateEnum: 7, question})"
>
<el-tooltip v-if="questionsMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id] && !questionsMarkStatus[rowId ? `${rowId}_${question.Id}` : question.Id].isSaved" class="item" effect="dark" :content="$t('trials:reading:button:unsaved')" placement="bottom">
<i class="el-icon-warning" style="color:red" />
</el-tooltip>
保存
</el-button>
</div>
</template>
<template v-else-if="question.Type === 'number'">
<el-input
type="number"
v-if="question.Type === 'number' && question.DataSource !== 1"
:disabled="question.TableQuestionType === 2 || (question.IsCopy && type === 'edit' && !isBaseline && questionForm.IsCurrentTaskAdd === 'False')"
@change="((val)=>{formItemNumberChange(val, question)})"
@blur="handleBlur(questionForm[question.Id], questionForm, question.Id)"
v-model="questionForm[question.Id]"
>
<template slot="append" v-if="question.Unit !== 0">{{question.Unit !== 4 ? $fd('ValueUnit', question.Unit) : question.CustomUnit}}</template>
</el-input>
<el-input
type="number"
v-if="question.Type === 'number' && question.DataSource === 1"
:disabled="question.DataSource === 1"
@blur="handleCalculationBlur(calculationValue)"
v-model="calculationValue"
>
<template slot="append" v-if="question.Unit !== 0">{{question.Unit !== 4 ? $fd('ValueUnit', question.Unit) : question.CustomUnit}}</template>
</el-input>
</template>
<!-- 上传图像 -->
<el-upload
v-if="question.Type==='upload'"
@ -231,6 +305,7 @@
</div>
</template>
<script>
import { submitTableQuestion } from '@/api/trials'
export default {
name: 'QuestionTableFormItem',
props: {
@ -271,7 +346,17 @@ export default {
type: {
type: String,
default: 'add'
}
},
questionsMarkStatus: {
type: Object,
default() {
return {}
}
},
parentQsId: {
type: String,
default: ''
},
},
computed: {
calculationValue: {
@ -294,7 +379,8 @@ export default {
organList: [],
QuestionsList: [],
QuestionsForm: {},
digitPlaces: 2
digitPlaces: 2,
rowId: ''
}
},
watch: {
@ -307,10 +393,19 @@ export default {
// } catch (e) {
// }
// this.formItemNumberChange(this.question.Id, false)
this.rowId = this.questionForm.RowId
}
},
questionsMarkStatus: {
deep: true,
immediate: true,
handler(v) {
// console.log(v, this.rowId)
}
}
},
mounted() {
var digitPlaces = Number(localStorage.getItem('digitPlaces'))
this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
if (this.question.Type === 'upload') {
@ -356,6 +451,11 @@ export default {
handleBlur(value, a, b) {
this.$set(a, b, parseFloat(value).toFixed(this.digitPlaces))
},
handleMarkedQsBlur(value, a, b, question) {
this.$set(a, b, parseFloat(value).toFixed(this.digitPlaces))
question.IsTableQuestion = true
// this.$emit('operateImageMarker', {operateStateEnum: 6, question})
},
handleCalculationBlur(v) {
this.calculationValue = parseFloat(v).toFixed(this.digitPlaces)
},
@ -477,6 +577,39 @@ export default {
setFormItemData(obj) {
this.$emit('setFormItemData', obj)
},
async operateImageMarker(obj) {
obj.question.IsTableQuestion = true
obj.question.RowId = this.rowId
obj.question.ParentQsId = this.parentQsId
if (obj.operateStateEnum === 7) {
//
// if (!obj.question.RowId) {
// // rowId
// const loading = this.$loading({ fullscreen: true })
// try {
// let params = {
// questionId: this.parentQsId,
// RowIndex: this.questionForm.RowIndex,
// visitTaskId: this.visitTaskId,
// trialId: this.$route.query.trialId,
// answerList: [],
// }
// let res = await submitTableQuestion(params)
// // this.$emit('save',rowId)
// this.QuestionsForm.RowId = res.Result.RowId
// obj.rowId = res.Result.RowId
// this.rowId = res.Result.RowId
// loading.close()
// } catch(e) {
// loading.close()
// }
// }
obj.rowIndex = this.questionForm.RowIndex
// obj.parentQsId = this.parentQsId
obj.answer = this.questionForm[obj.question.Id]
}
this.$emit('operateImageMarker', obj)
},
async uploadScreenshot(param) {
if (!this.visitTaskId) return
const loading = this.$loading({
@ -541,25 +674,19 @@ export default {
}
</script>
<style lang="scss" scoped>
.my_dialog{
.criterion-form-item{
::v-deep .el-form-item__content{
width: auto;
}
}
}
.criterion-form-item{
.criterion-table-form-item{
.el-form-item{
display: flex;
flex-direction: row;
align-items: flex-start;
}
::v-deep .el-form-item__content{
width: 500px;
}
.el-input{
width:100%;
}
.el-select {
width:100%;
}
.mb{
margin-bottom: 0px;
}