Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/irc_web
continuous-integration/drone/push Build is passing Details

# Conflicts:
#	src/components/Dicom/DicomViewer.vue
#	src/views/dicom-show/dicom-study.vue
uat_us
wangxiaoshuang 2026-04-23 15:53:04 +08:00
commit 946203f124
22 changed files with 570 additions and 39 deletions

View File

@ -4430,4 +4430,22 @@ export function updateImageResizePath(data) {
method: 'post', method: 'post',
data data
}) })
}
// 获取PET图像上患者信息
export function getPatientInfo(data) {
return request({
url: `/Study/getPatientInfo`,
method: 'post',
data
})
}
//编辑患者基本信息
export function editPatientInfo(data) {
return request({
url: `/Study/editPatientInfo`,
method: 'post',
data
})
} }

View File

@ -282,6 +282,59 @@
</select> </select>
</div> </div>
</div> </div>
<!-- 患者信息 -->
<div class="measureTool-wrapper patient-form"
v-if="isHaveStudyClinicalData && type === 'Study' && modality && ['PT、CT', 'CT、PT', 'PET-CT'].includes(modality)">
<div class="sideTool-title">{{ $t('trials:tab:patientData') }}</div>
<div class="sideTool-wrapper">
<el-form ref="patientForm" :model="formData" :rules="rules" label-width="150" v-loading="formLoading">
<!-- 性别 -->
<el-form-item :label="$t('trials:ptData:label:patientSex')" prop="PatientSex">
<el-select v-model="formData.PatientSex" :placeholder="$t('common:ruleMessage:select')"
style="width: 100%" size="small" :disabled="!isEdit">
<el-option :label="$t('trials:patientSex:male')" value="M"></el-option>
<el-option :label="$t('trials:patientSex:female')" value="F"></el-option>
</el-select>
</el-form-item>
<!-- 体重kg 例如 70.5-->
<el-form-item :label="$t('trials:ptData:label:patientWeight')" prop="PatientWeight">
<el-input v-model.number="formData.PatientWeight" :placeholder="$t('trials:patientWeight:eg')"
style="width: 100%" size="small" :disabled="!isEdit"></el-input>
</el-form-item>
<!-- 总剂量Bq 例如 740000000-->
<el-form-item :label="$t('trials:ptData:label:totalDose')" prop="RadionuclideTotalDose">
<el-input v-model.number="formData.RadionuclideTotalDose" :placeholder="$t('trials:totalDose:eg')"
style="width: 100%" size="small" :disabled="!isEdit"></el-input>
</el-form-item>
<!-- 半衰期s 例如 21600-->
<el-form-item :label="$t('trials:ptData:label:halfLife')" prop="RadionuclideHalfLife">
<el-input v-model.number="formData.RadionuclideHalfLife" :placeholder="$t('trials:halfLife:eg')"
style="width: 100%" size="small" :disabled="!isEdit"></el-input>
</el-form-item>
<!-- 注射时间s Unix 相对秒-->
<el-form-item :label="$t('trials:ptData:label:injectTime')" prop="RadiopharmaceuticalStartTime">
<el-input v-model.number="formData.RadiopharmaceuticalStartTime" :placeholder="$t('trials:injectTime:eg')"
style="width: 100%" @input="computeTimeRelation" size="small" :disabled="!isEdit"></el-input>
</el-form-item>
<!-- 成像时间s Unix 相对秒-->
<el-form-item :label="$t('trials:ptData:label:acquisitionTime')" prop="AcquisitionTime">
<el-input v-model.number="formData.AcquisitionTime" :placeholder="$t('trials:injectTime:eg')"
style="width: 100%" @input="computeTimeRelation" size="small" :disabled="!isEdit"></el-input>
</el-form-item>
<!-- 时间一致性检查 -->
<el-form-item :label="$t('trials:ptData:label:timeCheck')">
<el-input v-model="formData.TimeCheck" disabled style="width: 100%" size="small"></el-input>
</el-form-item>
<!-- 提交 -->
<el-form-item style="margin-top: 20px;text-align: right;" v-if="isEdit">
<el-button type="primary" @click="submitForm" size="small">{{ $t('trials:ptData:button:submit')
}}</el-button>
</el-form-item>
</el-form>
</div>
</div>
</div> </div>
<el-dialog v-if="customWwc.visible" :visible.sync="customWwc.visible" :close-on-click-modal="false" <el-dialog v-if="customWwc.visible" :visible.sync="customWwc.visible" :close-on-click-modal="false"
:title="customWwc.title" width="400px" custom-class="base-dialog-wrapper" append-to-body> :title="customWwc.title" width="400px" custom-class="base-dialog-wrapper" append-to-body>
@ -306,6 +359,10 @@ console.log(cornerstoneTools, 'cornerstoneTools')
console.log(cornerstone, 'cornerstone') console.log(cornerstone, 'cornerstone')
import '@/utils/dialog' import '@/utils/dialog'
import { studyMaskImage, studyUndoMaskImage } from "@/api/reading" import { studyMaskImage, studyUndoMaskImage } from "@/api/reading"
import {
getPatientInfo,
editPatientInfo
} from '@/api/trials'
export default { export default {
name: 'DicomsViewer', name: 'DicomsViewer',
components: { components: {
@ -316,6 +373,10 @@ export default {
loading: { loading: {
type: Boolean, type: Boolean,
default: false default: false
},
modality: {
type: String,
default: ''
} }
}, },
data() { data() {
@ -345,6 +406,47 @@ export default {
series: {}, series: {},
customWwc: { visible: false, title: null }, customWwc: { visible: false, title: null },
fps: 15, fps: 15,
formData: {
Id: '',
PatientSex: '',
PatientWeight: null,
RadionuclideTotalDose: null,
RadionuclideHalfLife: null,
RadiopharmaceuticalStartTime: null,
AcquisitionTime: null,
TimeCheck: ''
},
rules: {
PatientSex: [
{ required: true, message: this.$t('common:ruleMessage:select'), trigger: 'change' }
],
PatientWeight: [
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' },
{ type: 'number', min: 0, message: this.$t('trials:ptData:ruleMessage:number1'), trigger: 'blur' }//0
],
RadionuclideTotalDose: [
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' },
{ type: 'number', min: 0, message: this.$t('trials:ptData:ruleMessage:number1'), trigger: 'blur' }//0
],
RadionuclideHalfLife: [
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' },
{ type: 'number', min: 0, message: this.$t('trials:ptData:ruleMessage:number1'), trigger: 'blur' }
],
RadiopharmaceuticalStartTime: [
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' },
{ type: 'number', message: this.$t('trials:ptData:ruleMessage:number2'), trigger: 'blur' }//
],
AcquisitionTime: [
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' },
{ type: 'number', message: this.$t('trials:ptData:ruleMessage:number2'), trigger: 'blur' },//
//
{ validator: this.validateTime, trigger: 'blur' }
]
},
formLoading: false,
isHaveStudyClinicalData: false,
type: '',
isEdit: 0
} }
}, },
mounted() { mounted() {
@ -357,6 +459,12 @@ export default {
this.wwwcList[0] = '-1' this.wwwcList[0] = '-1'
this.colormapsList = cornerstone.colors.getColormapsList() this.colormapsList = cornerstone.colors.getColormapsList()
this.currentDicomCanvas = this.$refs['dicomCanvas0'] this.currentDicomCanvas = this.$refs['dicomCanvas0']
this.isHaveStudyClinicalData = this.$route.query.isHaveStudyClinicalData === 'true'
this.type = this.$route.query.type
this.isEdit = parseInt(this.$route.query.showDelete)
if (this.isHaveStudyClinicalData && this.type === 'Study' && ['PT、CT', 'CT、PT', 'PET-CT'].includes(this.modality)) {
this.getPatientInfo()
}
}, },
methods: { methods: {
@ -684,13 +792,76 @@ export default {
} }
} }
}, },
}, //
validateTime(rule, value, callback) {
const { RadiopharmaceuticalStartTime } = this.formData
if (value && RadiopharmaceuticalStartTime !== null && value < RadiopharmaceuticalStartTime) {
callback(new Error(this.$t('trials:ptData:ruleMessage:number3')))//
} else {
callback()
}
},
computeTimeRelation() {
const startTime = this.formData.RadiopharmaceuticalStartTime
const acquireTime = this.formData.AcquisitionTime
if (!startTime || !acquireTime) {
this.formData.TimeCheck = ''
return
}
if (startTime <= acquireTime) {
this.formData.TimeCheck = this.$t('trials:ptData:timeCheck:val1') //
} else {
this.formData.TimeCheck = this.$t('trials:ptData:timeCheck:val2') // >
}
},
async getPatientInfo() {
try {
this.formLoading = true
let studyId = this.$route.query.studyId
let res = await getPatientInfo({ studyId: studyId })
this.formData = {
Id: res.Result.Id || '',
PatientSex: res.Result.PatientSex || '',
PatientWeight: parseFloat(res.Result.PatientWeight) || null,
RadionuclideTotalDose: parseFloat(res.Result.RadionuclideTotalDose) || null,
RadionuclideHalfLife: parseFloat(res.Result.RadionuclideHalfLife) || null,
RadiopharmaceuticalStartTime: parseFloat(res.Result.RadiopharmaceuticalStartTime) || '',
AcquisitionTime: parseFloat(res.Result.AcquisitionTime) || '',
TimeCheck: ''
}
this.computeTimeRelation()
this.formLoading = false
} catch (e) {
this.formLoading = false
console.log(e)
}
},
async submitForm() {
try {
let valid = await this.$refs.patientForm.validate()
if (!valid) return
this.formLoading = true
let res = await editPatientInfo(this.formData)
this.formLoading = false
if (res.IsSuccess) {
this.$message.success(this.$t('common:message:savedSuccessfully'))
}
} catch (e) {
this.formLoading = false
console.log(e)
}
}
}
} }
</script> </script>
<style> <style>
.dicom-wrapper { .dicom-wrapper {
display: flex; display: flex;
height: 100%;
} }
.dicom-wrapper .case-dialog-class { .dicom-wrapper .case-dialog-class {
@ -827,7 +998,7 @@ export default {
/* border: 1px solid blueviolet; */ /* border: 1px solid blueviolet; */
color: #d0d0d0; color: #d0d0d0;
font-size: 13px; font-size: 13px;
overflow: hidden; overflow-y: auto;
} }
.dicom-wrapper .measure-wrapper { .dicom-wrapper .measure-wrapper {
@ -1027,4 +1198,21 @@ export default {
.dicom-wrapper .dropdown-content div:hover { .dicom-wrapper .dropdown-content div:hover {
background-color: #16477b90; background-color: #16477b90;
} }
.patient-form .el-form-item {
margin-bottom: 15px;
}
.patient-form .el-form-item__label {
color: #d0d0d0;
}
.patient-form .el-input.is-disabled .el-input__inner {
background-color: #424244;
}
.patient-form .el-input .el-input__inner {
background-color: #323232;
color: #d0d0d0;
}
</style> </style>

View File

@ -123,12 +123,12 @@
</div> </div>
</div> </div>
<div class="viewerContent"> <div class="viewerContent">
<dicom-viewer id="dicomViewer" ref="dicomViewer" style="height:100%" :loading.sync="loading" /> <dicom-viewer id="dicomViewer" ref="dicomViewer" style="height:100%" :loading.sync="loading"
:modality="modality" />
</div> </div>
<!-- <div class="viewerRightSidePanel"> <!-- <div class="viewerRightSidePanel">
<dicom-tools /> <dicom-tools />
</div> --> </div> -->
</div> </div>
</div> </div>

View File

@ -2341,7 +2341,7 @@ export default {
this.readingTaskState = 2 this.readingTaskState = 2
await store.dispatch('reading/setVisitTaskReadingTaskState', { visitTaskId: this.visitTaskId, readingTaskState: 2 }) await store.dispatch('reading/setVisitTaskReadingTaskState', { visitTaskId: this.visitTaskId, readingTaskState: 2 })
await store.dispatch('reading/setCurrentReadingTaskState', 2) await store.dispatch('reading/setCurrentReadingTaskState', 2)
const res = await getAutoCutNextTask() const res = await getAutoCutNextTask({imageToolType: 1})
var isAutoTask = res.Result.AutoCutNextTask var isAutoTask = res.Result.AutoCutNextTask
if (isAutoTask) { if (isAutoTask) {
window.location.reload() window.location.reload()

View File

@ -31,6 +31,12 @@
import { setAutoCutNextTask, getAutoCutNextTask } from '@/api/user' import { setAutoCutNextTask, getAutoCutNextTask } from '@/api/user'
export default { export default {
name: 'Others', name: 'Others',
props: {
imageToolType: {
type: Number,
default: 1
}
},
data() { data() {
return { return {
form: { form: {
@ -47,7 +53,7 @@ export default {
async initForm() { async initForm() {
this.loading = true this.loading = true
try { try {
const res = await getAutoCutNextTask() const res = await getAutoCutNextTask({imageToolType: this.imageToolType})
if (res.IsSuccess) { if (res.IsSuccess) {
this.form.AutoCutNextTask = res.Result.AutoCutNextTask this.form.AutoCutNextTask = res.Result.AutoCutNextTask
this.form.IsDoubleScreen = res.Result.IsDoubleScreen this.form.IsDoubleScreen = res.Result.IsDoubleScreen
@ -62,7 +68,8 @@ export default {
if (!valid) return if (!valid) return
this.loading = true this.loading = true
try { try {
const res = await setAutoCutNextTask(this.form) let params = Object.assign(this.form, {imageToolType: this.imageToolType})
const res = await setAutoCutNextTask(params)
if (res.IsSuccess) { if (res.IsSuccess) {
this.$message.success(this.$t('common:message:savedSuccessfully')) this.$message.success(this.$t('common:message:savedSuccessfully'))
} }

View File

@ -733,7 +733,7 @@ export default {
await store.dispatch('reading/setVisitTaskReadingTaskState', { visitTaskId: this.visitTaskId, readingTaskState: 2 }) await store.dispatch('reading/setVisitTaskReadingTaskState', { visitTaskId: this.visitTaskId, readingTaskState: 2 })
// DicomEvent.$emit('setReadingState', 2) // DicomEvent.$emit('setReadingState', 2)
await store.dispatch('reading/setCurrentReadingTaskState', 2) await store.dispatch('reading/setCurrentReadingTaskState', 2)
const res = await getAutoCutNextTask() const res = await getAutoCutNextTask({imageToolType: 1})
var isAutoTask = res.Result.AutoCutNextTask var isAutoTask = res.Result.AutoCutNextTask
if (isAutoTask) { if (isAutoTask) {
// DicomEvent.$emit('reload') // DicomEvent.$emit('reload')
@ -780,7 +780,7 @@ export default {
var readingTool = this.$router.currentRoute.query.readingTool var readingTool = this.$router.currentRoute.query.readingTool
var path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${trialId}&subjectCode=${subjectCode}&subjectId=${subjectId}&visitTaskId=${task.VisitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}` var path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${trialId}&subjectCode=${subjectCode}&subjectId=${subjectId}&visitTaskId=${task.VisitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
const routeData = this.$router.resolve({ path }) const routeData = this.$router.resolve({ path })
const res = await getAutoCutNextTask() const res = await getAutoCutNextTask({imageToolType: 1})
let IsDoubleScreen = false let IsDoubleScreen = false
if (res.IsSuccess) { if (res.IsSuccess) {
IsDoubleScreen = res.Result.IsDoubleScreen IsDoubleScreen = res.Result.IsDoubleScreen

View File

@ -411,7 +411,7 @@
<WL v-if="activeName === '2'" @getWwcTpl="getWwcTpl" /> <WL v-if="activeName === '2'" @getWwcTpl="getWwcTpl" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="$t('trials:reading:tab:others')" name="3"> <el-tab-pane :label="$t('trials:reading:tab:others')" name="3">
<Others v-if="activeName === '3'" /> <Others v-if="activeName === '3'" :imageToolType="1"/>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</el-dialog> </el-dialog>

View File

@ -835,7 +835,7 @@ export default {
store.dispatch('reading/setVisitTaskReadingTaskState', { visitTaskId: this.visitTaskId, readingTaskState: 2 }) store.dispatch('reading/setVisitTaskReadingTaskState', { visitTaskId: this.visitTaskId, readingTaskState: 2 })
DicomEvent.$emit('setReadingState', 2) DicomEvent.$emit('setReadingState', 2)
window.opener.postMessage('refreshTaskList', window.location) window.opener.postMessage('refreshTaskList', window.location)
const res = await getAutoCutNextTask() const res = await getAutoCutNextTask({imageToolType: 1})
let isAutoTask = res.Result.AutoCutNextTask let isAutoTask = res.Result.AutoCutNextTask
if (isAutoTask) { if (isAutoTask) {
window.location.reload() window.location.reload()
@ -875,7 +875,7 @@ export default {
var trialReadingCriterionId = this.$router.currentRoute.query.TrialReadingCriterionId var trialReadingCriterionId = this.$router.currentRoute.query.TrialReadingCriterionId
var path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${trialId}&subjectCode=${subjectCode}&subjectId=${subjectId}&visitTaskId=${task.VisitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}` var path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${trialId}&subjectCode=${subjectCode}&subjectId=${subjectId}&visitTaskId=${task.VisitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
const routeData = this.$router.resolve({ path }) const routeData = this.$router.resolve({ path })
const res = await getAutoCutNextTask() const res = await getAutoCutNextTask({imageToolType: 1})
let IsDoubleScreen = false let IsDoubleScreen = false
if (res.IsSuccess) { if (res.IsSuccess) {
IsDoubleScreen = res.Result.IsDoubleScreen IsDoubleScreen = res.Result.IsDoubleScreen

View File

@ -23,6 +23,12 @@
import { setAutoCutNextTask, getAutoCutNextTask } from '@/api/user' import { setAutoCutNextTask, getAutoCutNextTask } from '@/api/user'
export default { export default {
name: 'Others', name: 'Others',
props: {
imageToolType: {
type: Number,
default: 1
}
},
data() { data() {
return { return {
form: { form: {
@ -38,7 +44,7 @@ export default {
async initForm() { async initForm() {
this.loading = true this.loading = true
try{ try{
await getAutoCutNextTask() await getAutoCutNextTask({imageToolType: this.imageToolType})
this.form.AutoCutNextTask = res.Result.AutoCutNextTask this.form.AutoCutNextTask = res.Result.AutoCutNextTask
this.loading = false this.loading = false
}catch(e){ }catch(e){
@ -50,7 +56,8 @@ export default {
if (!valid) return if (!valid) return
this.loading = true this.loading = true
try{ try{
await setAutoCutNextTask(this.form) let params = Object.assign(this.form, {imageToolType: this.imageToolType})
await setAutoCutNextTask(params)
this.loading = false this.loading = false
this.$message.success(this.$t('common:message:savedSuccessfully')) this.$message.success(this.$t('common:message:savedSuccessfully'))
}catch(e){ }catch(e){

View File

@ -53,20 +53,26 @@
:visit-task-id="visitTaskId" :reading-category="readingCategory" :subject-code="subjectCode" :visit-task-id="visitTaskId" :reading-category="readingCategory" :subject-code="subjectCode"
:task-blind-name="taskBlindName" :is-reading-show-subject-info="isReadingShowSubjectInfo" :task-blind-name="taskBlindName" :is-reading-show-subject-info="isReadingShowSubjectInfo"
:is-reading-show-previous-results="isReadingShowPreviousResults" :is-reading-show-previous-results="isReadingShowPreviousResults"
:is-exists-clinical-data="isExistsClinicalData" /> :is-exists-clinical-data="isExistsClinicalData"
:imageToolType="1"
/>
<!-- 裁判阅片 --> <!-- 裁判阅片 -->
<AdReview v-else-if="isShow && readingCategory === 4" :trial-id="trialId" :subject-id="subjectId" <AdReview v-else-if="isShow && readingCategory === 4" :trial-id="trialId" :subject-id="subjectId"
:visit-task-id="visitTaskId" :reading-category="readingCategory" :subject-code="subjectCode" :visit-task-id="visitTaskId" :reading-category="readingCategory" :subject-code="subjectCode"
:task-blind-name="taskBlindName" :is-reading-show-subject-info="isReadingShowSubjectInfo" :task-blind-name="taskBlindName" :is-reading-show-subject-info="isReadingShowSubjectInfo"
:is-reading-show-previous-results="isReadingShowPreviousResults" :is-reading-show-previous-results="isReadingShowPreviousResults"
:is-exists-clinical-data="isExistsClinicalData" /> :is-exists-clinical-data="isExistsClinicalData"
:imageToolType="1"
/>
<!-- 肿瘤学阅片 --> <!-- 肿瘤学阅片 -->
<OncologyReview v-else-if="isShow && readingCategory === 5" :trial-id="trialId" :subject-id="subjectId" <OncologyReview v-else-if="isShow && readingCategory === 5" :trial-id="trialId" :subject-id="subjectId"
:visit-task-id="visitTaskId" :reading-category="readingCategory" :subject-code="subjectCode" :visit-task-id="visitTaskId" :reading-category="readingCategory" :subject-code="subjectCode"
:task-blind-name="taskBlindName" :is-reading-show-subject-info="isReadingShowSubjectInfo" :task-blind-name="taskBlindName" :is-reading-show-subject-info="isReadingShowSubjectInfo"
:is-reading-show-previous-results="isReadingShowPreviousResults" :is-reading-show-previous-results="isReadingShowPreviousResults"
:is-exists-clinical-data="isExistsClinicalData" /> :is-exists-clinical-data="isExistsClinicalData"
:imageToolType="1"
/>
<el-dialog :visible.sync="dialogVisible" :custom-class="isFullscreen ? 'full-dialog-container' : 'dialog-container'" <el-dialog :visible.sync="dialogVisible" :custom-class="isFullscreen ? 'full-dialog-container' : 'dialog-container'"
:show-close="false" :close-on-click-modal="false" :fullscreen="isFullscreen"> :show-close="false" :close-on-click-modal="false" :fullscreen="isFullscreen">

View File

@ -477,7 +477,7 @@
</el-tab-pane> </el-tab-pane>
<!-- 其他 --> <!-- 其他 -->
<el-tab-pane :label="$t('trials:reading:tab:others')" name="3"> <el-tab-pane :label="$t('trials:reading:tab:others')" name="3">
<Others v-if="personalConfigDialog.activeName === '3'" /> <Others v-if="personalConfigDialog.activeName === '3'" :imageToolType="1"/>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>

View File

@ -918,7 +918,7 @@ export default {
// //
this.readingTaskState = 2 this.readingTaskState = 2
this.$emit('setReadingTaskState', 2) this.$emit('setReadingTaskState', 2)
const res = await getAutoCutNextTask() const res = await getAutoCutNextTask({imageToolType: 1})
var isAutoTask = res.Result.AutoCutNextTask var isAutoTask = res.Result.AutoCutNextTask
if (isAutoTask) { if (isAutoTask) {
window.location.reload() window.location.reload()
@ -963,7 +963,7 @@ export default {
var readingTool = this.$router.currentRoute.query.readingTool var readingTool = this.$router.currentRoute.query.readingTool
var path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${trialId}&subjectCode=${subjectCode}&subjectId=${subjectId}&visitTaskId=${task.VisitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}` var path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${trialId}&subjectCode=${subjectCode}&subjectId=${subjectId}&visitTaskId=${task.VisitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
const routeData = this.$router.resolve({ path }) const routeData = this.$router.resolve({ path })
const res = await getAutoCutNextTask() const res = await getAutoCutNextTask({imageToolType: 1})
let IsDoubleScreen = false let IsDoubleScreen = false
if (res.IsSuccess) { if (res.IsSuccess) {
IsDoubleScreen = res.Result.IsDoubleScreen IsDoubleScreen = res.Result.IsDoubleScreen

View File

@ -74,8 +74,39 @@
#{{ series.SeriesNumber }} #{{ series.SeriesNumber }}
</div> </div>
<div v-if="series.Description" class="text-desc" :title="series.Description"> <div v-if="series.Description" class="text-desc" :title="series.Description" style="position: relative;">
{{ series.Description }} {{ series.Description }}
<div class="patient-info" style="position: absolute;right: 0;top: 0;" v-if="taskInfo && taskInfo.IsExistsClinicalData && ['PT','PET'].includes(series.Modality)">
<el-popover placement="right" trigger="hover" popper-class="patient-info-popper">
<h4>{{ $t('trials:ptData:title') }}</h4>
<div class="patient-info-row">
<label>{{ $t('trials:ptData:label:patientSex') }}</label>
<span>{{ study.PatientSex }}</span>
</div>
<div class="patient-info-row">
<label>{{ $t('trials:ptData:label:patientWeight') }}</label>
<span>{{ study.PatientWeight }}</span>
</div>
<div class="patient-info-row">
<label>{{ $t('trials:ptData:label:totalDose') }}</label>
<span>{{ study.RadionuclideTotalDose }}</span>
</div>
<div class="patient-info-row">
<label>{{ $t('trials:ptData:label:halfLife') }}</label>
<span>{{ study.RadionuclideHalfLife }}</span>
</div>
<div class="patient-info-row">
<label>{{ $t('trials:ptData:label:injectTime') }}</label>
<span>{{ study.RadiopharmaceuticalStartTime }}</span>
</div>
<div class="patient-info-row">
<label>{{ $t('trials:ptData:label:acquisitionTime') }}</label>
<span>{{ study.AcquisitionTime }}</span>
</div>
<i slot="reference" class="el-icon-document"
style="font-size: 15px;cursor: pointer;color: #428bca;" />
</el-popover>
</div>
</div> </div>
<div v-if="series.SliceThickness && !study.IsCriticalSequence" class="text-desc"> <div v-if="series.SliceThickness && !study.IsCriticalSequence" class="text-desc">
T: {{ parseFloat(series.SliceThickness).toFixed(digitPlaces) }} T: {{ parseFloat(series.SliceThickness).toFixed(digitPlaces) }}
@ -223,10 +254,56 @@ export default {
const seriesIndex = seriseList[newIndex].SeriesIndex const seriesIndex = seriseList[newIndex].SeriesIndex
this.setSeriesActive(studyIndex, seriesIndex) this.setSeriesActive(studyIndex, seriesIndex)
this.activeSeries(seriseList[newIndex], seriesIndex, studyIndex) this.activeSeries(seriseList[newIndex], seriesIndex, studyIndex)
},
showPatientInfo(study) {
console.log(study)
} }
} }
} }
</script> </script>
<style lang="scss">
.patient-info-popper {
font-size: 12px;
color: #ddd;
background-color: #2f2f2f;
border-color: #5a5a5a;
padding: 8px 10px;
}
.patient-info-popper[x-placement^='right'] .popper__arrow {
border-right-color: #5a5a5a;
}
.patient-info-popper[x-placement^='right'] .popper__arrow::after {
border-right-color: #2f2f2f;
}
.patient-info-popper .patient-info-row {
display: grid;
grid-template-columns: 100px minmax(0, 1fr);
column-gap: 12px;
align-items: center;
line-height: 18px;
}
.patient-info-popper .patient-info-row + .patient-info-row {
margin-top: 4px;
}
.patient-info-popper label {
color: #bbb;
// font-weight: 600;
white-space: nowrap;
}
.patient-info-popper span {
text-align: left;
min-width: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
<style lang="scss" scoped> <style lang="scss" scoped>
.study-wrapper { .study-wrapper {
width: 100%; width: 100%;

View File

@ -987,7 +987,7 @@ export default {
this.readingTaskState = 2 this.readingTaskState = 2
this.$emit('setReadingTaskState', 2) this.$emit('setReadingTaskState', 2)
window.opener.postMessage('refreshTaskList', window.location) window.opener.postMessage('refreshTaskList', window.location)
const res = await getAutoCutNextTask() const res = await getAutoCutNextTask({imageToolType: 1})
const isAutoTask = res.Result.AutoCutNextTask const isAutoTask = res.Result.AutoCutNextTask
if (isAutoTask) { if (isAutoTask) {
window.location.reload() window.location.reload()
@ -1031,7 +1031,7 @@ export default {
var readingTool = this.$router.currentRoute.query.readingTool var readingTool = this.$router.currentRoute.query.readingTool
var path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${trialId}&subjectCode=${subjectCode}&subjectId=${subjectId}&visitTaskId=${task.VisitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}` var path = `/readingDicoms?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${trialId}&subjectCode=${subjectCode}&subjectId=${subjectId}&visitTaskId=${task.VisitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
const routeData = this.$router.resolve({ path }) const routeData = this.$router.resolve({ path })
const res = await getAutoCutNextTask() const res = await getAutoCutNextTask({imageToolType: 1})
let IsDoubleScreen = false let IsDoubleScreen = false
if (res.IsSuccess) { if (res.IsSuccess) {
IsDoubleScreen = res.Result.IsDoubleScreen IsDoubleScreen = res.Result.IsDoubleScreen

View File

@ -153,6 +153,10 @@ export default {
isExistsClinicalData: { isExistsClinicalData: {
type: Boolean, type: Boolean,
required: true required: true
},
imageToolType: {
type: Number,
required: true
} }
}, },
data() { data() {
@ -361,7 +365,7 @@ export default {
this.signVisible = false this.signVisible = false
// //
this.readingTaskState = 2 this.readingTaskState = 2
const res = await getAutoCutNextTask() const res = await getAutoCutNextTask({imageToolType: this.imageToolType})
var isAutoTask = res.Result.AutoCutNextTask var isAutoTask = res.Result.AutoCutNextTask
if (isAutoTask) { if (isAutoTask) {
// DicomEvent.$emit('getNextTask') // DicomEvent.$emit('getNextTask')

View File

@ -8,14 +8,18 @@
:reading-category="taskInfo.ReadingCategory" :subject-code="taskInfo.SubjectCode" :reading-category="taskInfo.ReadingCategory" :subject-code="taskInfo.SubjectCode"
:task-blind-name="taskInfo.TaskBlindName" :is-reading-show-subject-info="taskInfo.IsReadingShowSubjectInfo" :task-blind-name="taskInfo.TaskBlindName" :is-reading-show-subject-info="taskInfo.IsReadingShowSubjectInfo"
:is-reading-show-previous-results="taskInfo.IsReadingShowPreviousResults" :is-reading-show-previous-results="taskInfo.IsReadingShowPreviousResults"
:is-exists-clinical-data="taskInfo.IsExistsClinicalData" /> :is-exists-clinical-data="taskInfo.IsExistsClinicalData"
:imageToolType="2"
/>
<!-- 裁判阅片 --> <!-- 裁判阅片 -->
<ad-review v-else-if="taskInfo && taskInfo.ReadingCategory === 4" :trial-id="trialId" <ad-review v-else-if="taskInfo && taskInfo.ReadingCategory === 4" :trial-id="trialId"
:subject-id="taskInfo.SubjectId" :visit-task-id="taskInfo.VisitTaskId" :subject-id="taskInfo.SubjectId" :visit-task-id="taskInfo.VisitTaskId"
:reading-category="taskInfo.ReadingCategory" :subject-code="taskInfo.SubjectCode" :reading-category="taskInfo.ReadingCategory" :subject-code="taskInfo.SubjectCode"
:task-blind-name="taskInfo.TaskBlindName" :is-reading-show-subject-info="taskInfo.IsReadingShowSubjectInfo" :task-blind-name="taskInfo.TaskBlindName" :is-reading-show-subject-info="taskInfo.IsReadingShowSubjectInfo"
:is-reading-show-previous-results="taskInfo.IsReadingShowPreviousResults" :is-reading-show-previous-results="taskInfo.IsReadingShowPreviousResults"
:is-exists-clinical-data="taskInfo.IsExistsClinicalData" /> :is-exists-clinical-data="taskInfo.IsExistsClinicalData"
:imageToolType="2"
/>
<!-- 肿瘤学阅片 --> <!-- 肿瘤学阅片 -->
<!-- <oncology-review v-else-if="taskInfo && taskInfo.ReadingCategory=== 5" /> --> <!-- <oncology-review v-else-if="taskInfo && taskInfo.ReadingCategory=== 5" /> -->
<el-dialog :visible.sync="clinicalDataVisible" <el-dialog :visible.sync="clinicalDataVisible"

View File

@ -205,6 +205,10 @@ export default {
isExistsClinicalData: { isExistsClinicalData: {
type: Boolean, type: Boolean,
required: true required: true
},
imageToolType: {
type: Number,
required: true
} }
}, },
data() { data() {
@ -397,7 +401,7 @@ export default {
// //
this.oncologyInfo.ReadingTaskState = 2 this.oncologyInfo.ReadingTaskState = 2
const res = await getAutoCutNextTask() const res = await getAutoCutNextTask({imageToolType: this.imageToolType})
var isAutoTask = res.Result.AutoCutNextTask var isAutoTask = res.Result.AutoCutNextTask
if (isAutoTask) { if (isAutoTask) {
// store.dispatch('reading/resetVisitTasks') // store.dispatch('reading/resetVisitTasks')

View File

@ -442,7 +442,8 @@ export default {
path = `/noneDicomReading?TrialReadingCriterionId=${row.TrialReadingCriterionId}&trialId=${this.trialId}&subjectCode=${row.SubjectCode}&subjectId=${row.SubjectId}&visitTaskId=${row.Id}&isReadingTaskViewInOrder=${row.IsReadingTaskViewInOrder}&criterionType=${row.CriterionType}&readingTool=${row.ReadingTool}&TokenKey=${token}` path = `/noneDicomReading?TrialReadingCriterionId=${row.TrialReadingCriterionId}&trialId=${this.trialId}&subjectCode=${row.SubjectCode}&subjectId=${row.SubjectId}&visitTaskId=${row.Id}&isReadingTaskViewInOrder=${row.IsReadingTaskViewInOrder}&criterionType=${row.CriterionType}&readingTool=${row.ReadingTool}&TokenKey=${token}`
} }
var routeData = this.$router.resolve({ path }) var routeData = this.$router.resolve({ path })
const res = await getAutoCutNextTask() let imageToolType = row.ReadingTool === 1 ? 2 : 1
const res = await getAutoCutNextTask({imageToolType})
let IsDoubleScreen = false let IsDoubleScreen = false
if (res.IsSuccess) { if (res.IsSuccess) {
IsDoubleScreen = res.Result.IsDoubleScreen IsDoubleScreen = res.Result.IsDoubleScreen

View File

@ -329,7 +329,8 @@ export default {
path = `/noneDicomReading?TrialReadingCriterionId=${this.TrialReadingCriterionId}&trialId=${this.trialId}&subjectCode=${row.SubjectCode}&subjectId=${row.SubjectId}&isReadingTaskViewInOrder=${this.isReadingTaskViewInOrder}&criterionType=${this.criterionType}&readingTool=${this.readingTool}&TokenKey=${token}` path = `/noneDicomReading?TrialReadingCriterionId=${this.TrialReadingCriterionId}&trialId=${this.trialId}&subjectCode=${row.SubjectCode}&subjectId=${row.SubjectId}&isReadingTaskViewInOrder=${this.isReadingTaskViewInOrder}&criterionType=${this.criterionType}&readingTool=${this.readingTool}&TokenKey=${token}`
} }
var routeData = this.$router.resolve({ path }) var routeData = this.$router.resolve({ path })
const res = await getAutoCutNextTask() let imageToolType = this.readingTool === 1 ? 2 : 1
const res = await getAutoCutNextTask({imageToolType})
let IsDoubleScreen = false let IsDoubleScreen = false
if (res.IsSuccess) { if (res.IsSuccess) {
IsDoubleScreen = res.Result.IsDoubleScreen IsDoubleScreen = res.Result.IsDoubleScreen

View File

@ -775,7 +775,7 @@ export default {
localStorage.setItem('taskInfo', JSON.stringify(this.taskInfo)) localStorage.setItem('taskInfo', JSON.stringify(this.taskInfo))
store.dispatch('noneDicomReview/setCurrentTaskState', 2) store.dispatch('noneDicomReview/setCurrentTaskState', 2)
window.opener.postMessage('refreshTaskList', window.location) window.opener.postMessage('refreshTaskList', window.location)
const res = await getAutoCutNextTask() const res = await getAutoCutNextTask({ imageToolType: 2 })
const isAutoTask = res.Result.AutoCutNextTask const isAutoTask = res.Result.AutoCutNextTask
if (isAutoTask) { if (isAutoTask) {
window.location.reload() window.location.reload()
@ -814,7 +814,7 @@ export default {
var trialReadingCriterionId = this.$router.currentRoute.query.TrialReadingCriterionId var trialReadingCriterionId = this.$router.currentRoute.query.TrialReadingCriterionId
var path = `/noneDicomReading?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${trialId}&subjectCode=${subjectCode}&subjectId=${subjectId}&visitTaskId=${task.VisitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}` var path = `/noneDicomReading?TrialReadingCriterionId=${trialReadingCriterionId}&trialId=${trialId}&subjectCode=${subjectCode}&subjectId=${subjectId}&visitTaskId=${task.VisitTaskId}&isReadingTaskViewInOrder=${isReadingTaskViewInOrder}&criterionType=${criterionType}&readingTool=${readingTool}&TokenKey=${token}`
const routeData = this.$router.resolve({ path }) const routeData = this.$router.resolve({ path })
const res = await getAutoCutNextTask() const res = await getAutoCutNextTask({ imageToolType: 2 })
let IsDoubleScreen = false let IsDoubleScreen = false
if (res.IsSuccess) { if (res.IsSuccess) {
IsDoubleScreen = res.Result.IsDoubleScreen IsDoubleScreen = res.Result.IsDoubleScreen

View File

@ -1,10 +1,12 @@
<template> <template>
<div v-loading="loading" class="clinical-data-wrapper"> <div v-loading="loading" class="clinical-data-wrapper">
<el-tabs type="border-card"> <el-tabs type="border-card" v-model="activeName" @tab-click="tabClick">
<el-tab-pane v-for="cd in clinicalDatas" :key="cd.ClinicalDataTrialSetId" :label="$i18n.locale === 'zh' <el-tab-pane
? cd.ClinicalDataSetName v-for="cd in clinicalDatas"
: cd.ClinicalDataSetEnName :key="cd.ClinicalDataTrialSetId"
"> :label="$i18n.locale === 'zh' ? cd.ClinicalDataSetName: cd.ClinicalDataSetEnName"
:name="cd.ClinicalDataTrialSetId"
>
<!-- 格式化录入 --> <!-- 格式化录入 -->
<div v-if="cd.ClinicalUploadType === 0"> <div v-if="cd.ClinicalUploadType === 0">
<!-- 既往放疗史 --> <!-- 既往放疗史 -->
@ -222,6 +224,90 @@
:open-type="'add'" @close="getClinicalData" /> :open-type="'add'" @close="getClinicalData" />
</div> </div>
</el-tab-pane> </el-tab-pane>
<!-- 患者数据 -->
<el-tab-pane :label="$t('trials:tab:patientData')" name="patientForm">
<el-form
ref="patientForm"
:model="formData"
:rules="rules"
label-width="100"
v-loading="formLoading"
>
<div class="form-row">
<!-- 性别 -->
<el-form-item class="form-item-half" :label="$t('trials:ptData:label:patientSex')" prop="PatientSex">
<el-select
v-model="formData.PatientSex"
:placeholder="$t('common:ruleMessage:select')"
style="width: 100%"
>
<el-option :label="$t('trials:patientSex:male')" value="M"></el-option>
<el-option :label="$t('trials:patientSex:female')" value="F"></el-option>
</el-select>
</el-form-item>
<!-- 体重kg 例如 70.5-->
<el-form-item class="form-item-half" :label="$t('trials:ptData:label:patientWeight')" prop="PatientWeight">
<el-input
v-model.number="formData.PatientWeight"
:placeholder="$t('trials:patientWeight:eg')"
style="width: 100%"
></el-input>
</el-form-item>
</div>
<div class="form-row">
<!-- 总剂量Bq 例如 740000000-->
<el-form-item class="form-item-half" :label="$t('trials:ptData:label:totalDose')" prop="RadionuclideTotalDose">
<el-input
v-model.number="formData.RadionuclideTotalDose"
:placeholder="$t('trials:totalDose:eg')"
style="width: 100%"
></el-input>
</el-form-item>
<!-- 半衰期s 例如 21600-->
<el-form-item class="form-item-half" :label="$t('trials:ptData:label:halfLife')" prop="RadionuclideHalfLife">
<el-input
v-model.number="formData.RadionuclideHalfLife"
:placeholder="$t('trials:halfLife:eg')"
style="width: 100%"
></el-input>
</el-form-item>
</div>
<div class="form-row">
<!-- 注射时间s Unix 相对秒-->
<el-form-item class="form-item-half" :label="$t('trials:ptData:label:injectTime')" prop="RadiopharmaceuticalStartTime">
<el-input
v-model.number="formData.RadiopharmaceuticalStartTime"
:placeholder="$t('trials:injectTime:eg')"
style="width: 100%"
@input="computeTimeRelation"
></el-input>
</el-form-item>
<!-- 成像时间s Unix 相对秒-->
<el-form-item class="form-item-half" :label="$t('trials:ptData:label:acquisitionTime')" prop="AcquisitionTime">
<el-input
v-model.number="formData.AcquisitionTime"
:placeholder="$t('trials:injectTime:eg')"
style="width: 100%"
@input="computeTimeRelation"
></el-input>
</el-form-item>
</div>
<!-- 时间一致性检查 -->
<el-form-item :label="$t('trials:ptData:label:timeCheck')">
<el-input
v-model="formData.TimeCheck"
disabled
style="width: 100%"
></el-input>
</el-form-item>
<!-- 提交 -->
<el-form-item style="margin-top: 20px;text-align: right;">
<el-button type="primary" @click="submitForm">{{ $t('trials:ptData:button:submit') }}</el-button>
</el-form-item>
</el-form>
</el-tab-pane>
</el-tabs> </el-tabs>
<!-- 既往放疗史 --> <!-- 既往放疗史 -->
@ -269,6 +355,8 @@ import {
deletePreviousSurgery, deletePreviousSurgery,
getCRCClinicalData, getCRCClinicalData,
addOrUpdateReadingClinicalData, addOrUpdateReadingClinicalData,
getPatientInfo,
editPatientInfo
} from '@/api/trials' } from '@/api/trials'
import PreviousRadiotherapy from './previousRadiotherapy' import PreviousRadiotherapy from './previousRadiotherapy'
import PreviousSurgery from './previousSurgery' import PreviousSurgery from './previousSurgery'
@ -336,6 +424,45 @@ export default {
downloadLoading: false, downloadLoading: false,
clinicalDatas: [], clinicalDatas: [],
previewObj: { visible: false, filePath: '', fileType: '' }, previewObj: { visible: false, filePath: '', fileType: '' },
activeName: '',
formData: {
Id: '',
PatientSex: '',
PatientWeight: null,
RadionuclideTotalDose: null,
RadionuclideHalfLife: null,
RadiopharmaceuticalStartTime: null,
AcquisitionTime: null,
TimeCheck: ''
},
rules: {
PatientSex: [
{ required: true, message: this.$t('common:ruleMessage:select'), trigger: 'change' }
],
PatientWeight: [
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' },
{ type: 'number', min: 0, message: this.$t('trials:ptData:ruleMessage:number1'), trigger: 'blur' }//0
],
RadionuclideTotalDose: [
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' },
{ type: 'number', min: 0, message: this.$t('trials:ptData:ruleMessage:number1'), trigger: 'blur' }//0
],
RadionuclideHalfLife: [
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' },
{ type: 'number', min: 0, message: this.$t('trials:ptData:ruleMessage:number1'), trigger: 'blur' }
],
RadiopharmaceuticalStartTime: [
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' },
{ type: 'number', message: this.$t('trials:ptData:ruleMessage:number2'), trigger: 'blur' }//
],
AcquisitionTime: [
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' },
{ type: 'number', message: this.$t('trials:ptData:ruleMessage:number2'), trigger: 'blur' },//
//
{ validator: this.validateTime, trigger: 'blur' }
]
},
formLoading: false
} }
}, },
mounted() { mounted() {
@ -452,6 +579,7 @@ export default {
getCRCClinicalData(param) getCRCClinicalData(param)
.then((res) => { .then((res) => {
this.clinicalDatas = res.Result this.clinicalDatas = res.Result
this.activeName = res.Result.length > 0 ? res.Result[0].ClinicalDataTrialSetId : ''
this.loading = false this.loading = false
}) })
.catch(() => { .catch(() => {
@ -636,6 +764,70 @@ export default {
handleDownloadTpl(cd) { handleDownloadTpl(cd) {
window.open(this.OSSclientConfig.basePath + cd.Path) window.open(this.OSSclientConfig.basePath + cd.Path)
}, },
//
validateTime(rule, value, callback) {
const { RadiopharmaceuticalStartTime } = this.formData
if (value && RadiopharmaceuticalStartTime !== null && value < RadiopharmaceuticalStartTime) {
callback(new Error(this.$t('trials:ptData:ruleMessage:number3')))//
} else {
callback()
}
},
computeTimeRelation() {
const startTime = this.formData.RadiopharmaceuticalStartTime
const acquireTime = this.formData.AcquisitionTime
if (!startTime || !acquireTime) {
this.formData.TimeCheck = ''
return
}
if (startTime <= acquireTime) {
this.formData.TimeCheck = this.$t('trials:ptData:timeCheck:val1') //
} else {
this.formData.TimeCheck = this.$t('trials:ptData:timeCheck:val2') // >
}
},
async tabClick(tab) {
try {
const name = tab.name
if (name === 'patientForm' && !this.formData.Id) {
this.formLoading = true
let res = await getPatientInfo({studyId: this.studyData.StudyId})
this.formData = {
Id: res.Result.Id || '',
PatientSex: res.Result.PatientSex || '',
PatientWeight: parseFloat(res.Result.PatientWeight) || null,
RadionuclideTotalDose: parseFloat(res.Result.RadionuclideTotalDose) || null,
RadionuclideHalfLife: parseFloat(res.Result.RadionuclideHalfLife) || null,
RadiopharmaceuticalStartTime: parseFloat(res.Result.RadiopharmaceuticalStartTime) || '',
AcquisitionTime: parseFloat(res.Result.AcquisitionTime) || '',
TimeCheck: ''
}
this.computeTimeRelation()
this.formLoading = false
}
} catch(e) {
this.formLoading = false
console.log(e)
}
},
async submitForm() {
try {
let valid = await this.$refs.patientForm.validate()
if (!valid) return
this.formLoading = true
let res = await editPatientInfo(this.formData)
this.formLoading = false
if (res.IsSuccess) {
this.$message.success(this.$t('common:message:savedSuccessfully'))
}
} catch(e) {
this.formLoading = false
console.log(e)
}
}
}, },
} }
</script> </script>
@ -646,5 +838,16 @@ export default {
margin-bottom: 10px; margin-bottom: 10px;
background-color: #dcdfe6; background-color: #dcdfe6;
} }
.form-row {
display: flex;
gap: 20px;
margin-bottom: 0px;
.el-form-item {
margin-bottom: 15px;
}
}
.form-item-half {
flex: 1;
}
} }
</style> </style>

View File

@ -76,7 +76,18 @@
<el-table-column type="selection" width="55" v-if='$store.state.trials.config.IsSupportQCDownloadImage'> <el-table-column type="selection" width="55" v-if='$store.state.trials.config.IsSupportQCDownloadImage'>
</el-table-column> </el-table-column>
<!-- 检查编号 --> <!-- 检查编号 -->
<el-table-column prop="StudyCode" :label="$t('trials:audit:table:studyId')" sortable /> <el-table-column prop="StudyCode" :label="$t('trials:audit:table:studyId')" sortable>
<template slot-scope="scope">
<el-tooltip
placement="top"
v-if="['PT、CT', 'CT、PT', 'PET-CT'].includes(scope.row.Modalities) && IsHaveStudyClinicalData && scope.row.IsHasEmptyPatientInfo"
>
<div slot="content">{{ $t('trials:audit:message:ptDataValid') }}</div>
<span class="el-icon-warning" style="color: red; cursor: pointer"></span>
</el-tooltip>
{{ scope.row.StudyCode }}
</template>
</el-table-column>
<!-- 检查名称 --> <!-- 检查名称 -->
<el-table-column prop="StudyName" v-if="relationInfo.IsShowStudyName" <el-table-column prop="StudyName" v-if="relationInfo.IsShowStudyName"
:label="$t('trials:audit:table:StudyName')" sortable> :label="$t('trials:audit:table:StudyName')" sortable>
@ -149,7 +160,7 @@
<!-- 预览PET-CT数据 --> <!-- 预览PET-CT数据 -->
<el-button type="primary" icon="el-icon-document tip-i" :title="$t('trials:audit:tab:clinicalData')" <el-button type="primary" icon="el-icon-document tip-i" :title="$t('trials:audit:tab:clinicalData')"
v-if=" v-if="
['PT、CT', 'CT、PT', 'PET-CT'].includes( ['PT、CT', 'CT、PT', 'PET-CT'].includes(
scope.row.Modalities scope.row.Modalities
) && IsHaveStudyClinicalData ) && IsHaveStudyClinicalData
" circle :disabled="scope.row.IsDeleted" @click="handlePreviewClinicalData(scope.row)" /> " circle :disabled="scope.row.IsDeleted" @click="handlePreviewClinicalData(scope.row)" />
@ -2441,7 +2452,7 @@ export default {
const routeData = this.$router.resolve({ const routeData = this.$router.resolve({
path: `/showdicom?trialId=${this.trialId}&subjectVisitId=${this.data.Id path: `/showdicom?trialId=${this.trialId}&subjectVisitId=${this.data.Id
}&studyId=${row.StudyId}&showDelete=${this.isAudit ? 0 : 1 }&studyId=${row.StudyId}&showDelete=${this.isAudit ? 0 : 1
}&TokenKey=${token}&type=Study`, }&TokenKey=${token}&type=Study&isHaveStudyClinicalData=${this.IsHaveStudyClinicalData}`,
}) })
this.open = window.open(routeData.href, '_blank') this.open = window.open(routeData.href, '_blank')
}, },