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

main
wangxiaoshuang 2026-05-07 17:43:35 +08:00
commit fd0412004e
6 changed files with 185 additions and 32 deletions

View File

@ -327,14 +327,22 @@
<el-input v-model.number="formData.RadionuclideHalfLife" :placeholder="$t('trials:halfLife:eg')"
style="width: 100%" :disabled="!isEdit"></el-input>
</el-form-item>
<!-- 注射时间s Unix 相对秒-->
<!-- 注射时间 HHMMSS-->
<el-form-item :label="$t('trials:ptData:label:injectTime')" prop="RadiopharmaceuticalStartTime">
<el-input v-model.number="formData.RadiopharmaceuticalStartTime" :placeholder="$t('trials:injectTime:eg')"
<el-input
v-model.trim="formData.RadiopharmaceuticalStartTime"
:placeholder="$t('trials:injectTime:eg')"
@blur="handleTimeBlur('RadiopharmaceuticalStartTime')"
maxlength="6"
style="width: 100%" @input="computeTimeRelation" :disabled="!isEdit"></el-input>
</el-form-item>
<!-- 成像时间s Unix 相对秒-->
<!-- 成像时间 HHMMSS-->
<el-form-item :label="$t('trials:ptData:label:acquisitionTime')" prop="AcquisitionTime">
<el-input v-model.number="formData.AcquisitionTime" :placeholder="$t('trials:injectTime:eg')"
<el-input
v-model.trim="formData.AcquisitionTime"
@blur="handleTimeBlur('AcquisitionTime')"
maxlength="6"
:placeholder="$t('trials:injectTime:eg')"
style="width: 100%" @input="computeTimeRelation" :disabled="!isEdit"></el-input>
</el-form-item>
<!-- 时间一致性检查 -->
@ -447,8 +455,8 @@ export default {
PatientWeight: null,
RadionuclideTotalDose: null,
RadionuclideHalfLife: null,
RadiopharmaceuticalStartTime: null,
AcquisitionTime: null,
RadiopharmaceuticalStartTime: '',
AcquisitionTime: '',
TimeCheck: ''
},
rules: {
@ -469,11 +477,11 @@ export default {
],
RadiopharmaceuticalStartTime: [
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' },
{ type: 'number', message: this.$t('trials:ptData:ruleMessage:number2'), trigger: 'blur' }//
{ validator: this.validateDicomTime, 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.validateDicomTime, trigger: 'blur' },
//
{ validator: this.validateTime, trigger: 'blur' }
]
@ -1055,12 +1063,68 @@ export default {
//
validateTime(rule, value, callback) {
const { RadiopharmaceuticalStartTime } = this.formData
if (value && RadiopharmaceuticalStartTime !== null && value < RadiopharmaceuticalStartTime) {
const acquireSeconds = this.timeToSeconds(value)
const startSeconds = this.timeToSeconds(RadiopharmaceuticalStartTime)
if (acquireSeconds !== null && startSeconds !== null && acquireSeconds < startSeconds) {
callback(new Error(this.$t('trials:ptData:ruleMessage:number3')))//
} else {
callback()
}
},
validateDicomTime(rule, value, callback) {
if (value === undefined || value === null || value === '') {
callback()
return
}
const raw = String(value).trim()
if (!/^\d{1,6}$/.test(raw)) {
callback(new Error(this.$t('trials:ptData:ruleMessage:number2')))
return
}
const normalized = this.normalizeClinicalTime(raw)
if (!this.isValidDicomTime(normalized)) {
callback(new Error(this.$t('trials:ptData:ruleMessage:number4')))//HHMMSS
return
}
callback()
},
normalizeClinicalTime(value) {
if (value === undefined || value === null || value === '') return ''
const digits = String(value).trim().replace(/[^\d]/g, '')
if (!digits) return ''
return digits.slice(0, 6).padStart(6, '0')
},
isValidDicomTime(value) {
if (!/^\d{6}$/.test(String(value || ''))) return false
const normalized = String(value)
const hh = Number(normalized.slice(0, 2))
const mm = Number(normalized.slice(2, 4))
const ss = Number(normalized.slice(4, 6))
return hh >= 0 && hh <= 23 && mm >= 0 && mm <= 59 && ss >= 0 && ss <= 59
},
timeToSeconds(value) {
const normalized = this.normalizeClinicalTime(value)
if (!this.isValidDicomTime(normalized)) return null
const hh = Number(normalized.slice(0, 2))
const mm = Number(normalized.slice(2, 4))
const ss = Number(normalized.slice(4, 6))
return hh * 3600 + mm * 60 + ss
},
handleTimeBlur(field) {
const value = this.formData[field]
if (value === undefined || value === null || value === '') return
this.formData[field] = this.normalizeClinicalTime(value)
this.computeTimeRelation()
},
normalizeTimeFields() {
this.formData.RadiopharmaceuticalStartTime = this.normalizeClinicalTime(
this.formData.RadiopharmaceuticalStartTime
)
this.formData.AcquisitionTime = this.normalizeClinicalTime(
this.formData.AcquisitionTime
)
this.computeTimeRelation()
},
computeTimeRelation() {
const startTime = this.formData.RadiopharmaceuticalStartTime
const acquireTime = this.formData.AcquisitionTime
@ -1070,7 +1134,14 @@ export default {
return
}
if (startTime <= acquireTime) {
const startSeconds = this.timeToSeconds(startTime)
const acquireSeconds = this.timeToSeconds(acquireTime)
if (startSeconds === null || acquireSeconds === null) {
this.formData.TimeCheck = ''
return
}
if (startSeconds <= acquireSeconds) {
this.formData.TimeCheck = this.$t('trials:ptData:timeCheck:val1') //
} else {
this.formData.TimeCheck = this.$t('trials:ptData:timeCheck:val2') // >
@ -1087,8 +1158,8 @@ export default {
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) || '',
RadiopharmaceuticalStartTime: this.normalizeClinicalTime(res.Result.RadiopharmaceuticalStartTime),
AcquisitionTime: this.normalizeClinicalTime(res.Result.AcquisitionTime),
TimeCheck: ''
}
this.computeTimeRelation()
@ -1178,6 +1249,7 @@ export default {
try {
let valid = await this.$refs.patientForm.validate()
if (!valid) return
this.normalizeTimeFields()
this.formLoading = true
let res = await editPatientInfo(this.formData)
this.formLoading = false

View File

@ -79,7 +79,7 @@ function getQuestions(questions) {
answerObj.angle = angle
answerObj.saveTypeEnum = isNaN(parseFloat(angle)) ? 1 : 2
}
} else if (criterionType === 21) {
} else if (criterionType === 21 || criterionType === 22) {
// MRI-PDFF
let isMeasurable = getQuestionAnswer(item.TableQuestions.Questions, 1105, answerObj)
answerObj.isMeasurable = isMeasurable
@ -699,7 +699,7 @@ const actions = {
var measureData = state.visitTaskList[index].MeasureData
// var idx = measureData.findIndex(item => item.MeasureData.uuid === obj.data.MeasureData.data.uuid)
if (criterionType === 21) {
if (criterionType === 21 || criterionType === 22) {
let i = measureData.findIndex(i => i.TableQuestionId === obj.data.TableQuestionId)
if (i > -1) {
for (const k in state.visitTaskList[index].MeasureData[i]) {
@ -821,7 +821,7 @@ const actions = {
var index = state.visitTaskList.findIndex(i => i.VisitTaskId === obj.visitTaskId)
var measureData = state.visitTaskList[index].MeasureData
const criterionType = parseInt(localStorage.getItem('CriterionType'))
if (criterionType === 21) {
if (criterionType === 21 || criterionType === 22) {
const i = measureData.findIndex(item => item.QuestionId === obj.questionId && item.OrderMarkName === obj.orderMarkName)
if (i > -1) {
if (measureData[i].FristAddTaskId) {

View File

@ -784,7 +784,7 @@
<el-dialog v-if="clinicalDataVisible" :title="`${$t('trials:readingPeriod:dialogTitle:clinicalData')}(${rowData.SubjectCode
}|${rowData.TaskName}|${rowData.TrialReadingCriterionName})`" :visible.sync="clinicalDataVisible"
:close-on-click-modal="false" append-to-body>
<ClinicalData :trial-reading-criterion-id="TrialReadingCriterionId" :data="currentData" />
<ClinicalData :trial-reading-criterion-id="TrialReadingCriterionId" :data="currentData" :showUpdateStatusBtn="currentData.ReadingCategory === 2"/>
</el-dialog>
<el-dialog v-if="exportVisible" v-dialogDrag :title="$t('trials:reviewTrack:button:export')"
:visible.sync="exportVisible" :close-on-click-modal="false" width="60%" append-to-body>
@ -894,7 +894,7 @@ import BaseContainer from '@/components/BaseContainer'
import Pagination from '@/components/Pagination'
import RefereeRules from './components/RefereeRules.vue'
import ReviewResults from './components/ReviewResults'
import ClinicalData from '../../subject/reading-period/components/ClinicalData'
import ClinicalData from '../../subject/reading-period/components/ClinicalData'
import RecordList from './components/RecordList.vue'
import TargetSection from "@/views/trials/trials-panel/reading/reading-task/components/TargetSection"
const searchDataDefault = () => {

View File

@ -145,7 +145,7 @@
" @click="handleDelete(scope.row)" />
<!-- 更新 临床数据已签名阅片状态待阅片 -->
<el-button
v-hasPermi="['trials:trials-panel:subject:readingPeriod:edit']"
v-if="showUpdateStatusBtn && hasPermi(['trials:trials-panel:subject:readingPeriod:edit'])"
circle
:title="$t('trials:readingPeriod:cd:action:update')" icon="el-icon-refresh"
:disabled="
@ -296,7 +296,7 @@
" @click="handleDelete(scope.row)" />
<!-- 更新 临床数据已签名阅片状态待阅片 -->
<el-button
v-hasPermi="['trials:trials-panel:subject:readingPeriod:edit']"
v-if="showUpdateStatusBtn && hasPermi(['trials:trials-panel:subject:readingPeriod:edit'])"
circle
:title="$t('trials:readingPeriod:cd:action:update')" icon="el-icon-refresh"
:disabled="
@ -354,6 +354,7 @@ import SignForm from '@/views/trials/components/newSignForm'
import const_ from '@/const/sign-code'
import { getToken } from '@/utils/auth'
import { downLoadFile } from '@/utils/stream.js'
import hasPermi from '../../../../../../directive/permission/hasPermi'
export default {
name: 'ClinicalData',
components: { AddOrEditCD, SignForm, Verification },
@ -373,11 +374,21 @@ export default {
type: {
default: 'readingPeriod',
},
showUpdateStatusBtn: {
type: Boolean,
default: false
},
},
watch: {
clinicalType() {
this.getList()
},
showUpdateStatusBtn: {
immediate: true,
handler(v) {
console.log(v)
}
}
},
data() {
return {
@ -402,6 +413,7 @@ export default {
}
},
mounted() {
console.log(this.showUpdateStatusBtn)
if (!(this.data.IsVisit || this.data.IsBaseLine)) {
// this.clinicalType = this.$d.GetClinicalType[0].value.toString();
this.clinicalType = '1'

View File

@ -376,7 +376,7 @@
)}${currentData.SubjectCode}|${currentData.Name}|${currentData.CriterionName
}`" :visible.sync="clinicalDataVisible" :close-on-click-modal="false" append-to-body width="70%">
<ClinicalData :trial-reading-criterion-id="TrialReadingCriterionId" :trial-id="trialId"
:data="currentData" @getList="getList" />
:data="currentData" :showUpdateStatusBtn="currentData.ModuleType === 3" @getList="getList" />
</el-dialog>
<!-- 添加受试者阅片期 -->
<el-dialog v-if="subjectPeriod.visible" :title="subjectPeriod.title" :visible.sync="subjectPeriod.visible"

View File

@ -277,23 +277,27 @@
</el-form-item>
</div>
<div class="form-row">
<!-- 注射时间s Unix 相对秒-->
<!-- 注射时间 HHMMSS-->
<el-form-item class="form-item-half" :label="$t('trials:ptData:label:injectTime')" prop="RadiopharmaceuticalStartTime">
<el-input
v-model.number="formData.RadiopharmaceuticalStartTime"
v-model.trim="formData.RadiopharmaceuticalStartTime"
:placeholder="$t('trials:injectTime:eg')"
style="width: 100%"
@input="computeTimeRelation"
@blur="handleTimeBlur('RadiopharmaceuticalStartTime')"
maxlength="6"
:disabled="!isPatientFormCanEdit"
></el-input>
</el-form-item>
<!-- 成像时间s Unix 相对秒-->
<!-- 成像时间 HHMMSS-->
<el-form-item class="form-item-half" :label="$t('trials:ptData:label:acquisitionTime')" prop="AcquisitionTime">
<el-input
v-model.number="formData.AcquisitionTime"
v-model.trim="formData.AcquisitionTime"
:placeholder="$t('trials:injectTime:eg')"
style="width: 100%"
@input="computeTimeRelation"
@blur="handleTimeBlur('AcquisitionTime')"
maxlength="6"
:disabled="!isPatientFormCanEdit"
></el-input>
</el-form-item>
@ -469,8 +473,8 @@ export default {
PatientWeight: null,
RadionuclideTotalDose: null,
RadionuclideHalfLife: null,
RadiopharmaceuticalStartTime: null,
AcquisitionTime: null,
RadiopharmaceuticalStartTime: '',
AcquisitionTime: '',
TimeCheck: '',
Reason: ''
},
@ -492,11 +496,11 @@ export default {
],
RadiopharmaceuticalStartTime: [
{ required: true, message: this.$t('common:ruleMessage:specify'), trigger: 'blur' },
{ type: 'number', message: this.$t('trials:ptData:ruleMessage:number2'), trigger: 'blur' }//
{ validator: this.validateDicomTime, 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.validateDicomTime, trigger: 'blur' },
//
{ validator: this.validateTime, trigger: 'blur' }
],
@ -814,12 +818,68 @@ export default {
//
validateTime(rule, value, callback) {
const { RadiopharmaceuticalStartTime } = this.formData
if (value && RadiopharmaceuticalStartTime !== null && value < RadiopharmaceuticalStartTime) {
const acquireSeconds = this.timeToSeconds(value)
const startSeconds = this.timeToSeconds(RadiopharmaceuticalStartTime)
if (acquireSeconds !== null && startSeconds !== null && acquireSeconds < startSeconds) {
callback(new Error(this.$t('trials:ptData:ruleMessage:number3')))//
} else {
callback()
}
},
validateDicomTime(rule, value, callback) {
if (value === undefined || value === null || value === '') {
callback()
return
}
const raw = String(value).trim()
if (!/^\d{1,6}$/.test(raw)) {
callback(new Error(this.$t('trials:ptData:ruleMessage:number2')))
return
}
const normalized = this.normalizeClinicalTime(raw)
if (!this.isValidDicomTime(normalized)) {
callback(new Error(this.$t('trials:ptData:ruleMessage:number4')))//HHMMSS
return
}
callback()
},
normalizeClinicalTime(value) {
if (value === undefined || value === null || value === '') return ''
const digits = String(value).trim().replace(/[^\d]/g, '')
if (!digits) return ''
return digits.slice(0, 6).padStart(6, '0')
},
isValidDicomTime(value) {
if (!/^\d{6}$/.test(String(value || ''))) return false
const normalized = String(value)
const hh = Number(normalized.slice(0, 2))
const mm = Number(normalized.slice(2, 4))
const ss = Number(normalized.slice(4, 6))
return hh >= 0 && hh <= 23 && mm >= 0 && mm <= 59 && ss >= 0 && ss <= 59
},
timeToSeconds(value) {
const normalized = this.normalizeClinicalTime(value)
if (!this.isValidDicomTime(normalized)) return null
const hh = Number(normalized.slice(0, 2))
const mm = Number(normalized.slice(2, 4))
const ss = Number(normalized.slice(4, 6))
return hh * 3600 + mm * 60 + ss
},
handleTimeBlur(field) {
const value = this.formData[field]
if (value === undefined || value === null || value === '') return
this.formData[field] = this.normalizeClinicalTime(value)
this.computeTimeRelation()
},
normalizeTimeFields() {
this.formData.RadiopharmaceuticalStartTime = this.normalizeClinicalTime(
this.formData.RadiopharmaceuticalStartTime
)
this.formData.AcquisitionTime = this.normalizeClinicalTime(
this.formData.AcquisitionTime
)
this.computeTimeRelation()
},
computeTimeRelation() {
const startTime = this.formData.RadiopharmaceuticalStartTime
const acquireTime = this.formData.AcquisitionTime
@ -829,7 +889,14 @@ export default {
return
}
if (startTime <= acquireTime) {
const startSeconds = this.timeToSeconds(startTime)
const acquireSeconds = this.timeToSeconds(acquireTime)
if (startSeconds === null || acquireSeconds === null) {
this.formData.TimeCheck = ''
return
}
if (startSeconds <= acquireSeconds) {
this.formData.TimeCheck = this.$t('trials:ptData:timeCheck:val1') //
} else {
this.formData.TimeCheck = this.$t('trials:ptData:timeCheck:val2') // >
@ -847,8 +914,8 @@ export default {
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) || '',
RadiopharmaceuticalStartTime: this.normalizeClinicalTime(res.Result.RadiopharmaceuticalStartTime),
AcquisitionTime: this.normalizeClinicalTime(res.Result.AcquisitionTime),
TimeCheck: '',
Reason: res.Result.Reason
}
@ -865,10 +932,12 @@ export default {
let valid = await this.$refs.patientForm.validate()
if (!valid) return
if (this.isAudit) {
this.normalizeTimeFields()
const { CorrectImageExaminationInformation } = const_.processSignature
this.signCode = CorrectImageExaminationInformation
this.signVisible = true
} else {
this.normalizeTimeFields()
this.formLoading = true
let res = await editPatientInfo(this.formData)
this.formLoading = false