<template> <div class="screen-info"> <div class="flex items-end py-4 border-bottom"> <div class="px-4 font-semibold doc-title">筛查信息</div> <div class="text-12">请根据您身体实际情况填写以下内容</div> </div> <van-form label-width="10em" ref="form" class="screen-form" input-align="right" error-message-align="right"> <van-field v-model="form.currentAge" name="currentAge" label="年龄" type="digit" placeholder="请输入年龄" readonly maxlength="10" > <template #extra> <span class="ml-1">岁</span> </template> </van-field> <van-field required v-model="form.medicalHistoryName" is-link readonly name="medicalHistory" label="既往史" placeholder="请选择" :rules="rules.medicalHistory" @click="showMedical = true"/> <van-popup v-model:show="showMedical" position="bottom"> <div class="pt-4 popup-checkbox"> <div class="flex justify-between"> <button class="van-picker__cancel van-haptics-feedback" @click="showMedical = false">取消</button> <button class="van-picker__confirm van-haptics-feedback" @click="medicalConfirm">确认</button> </div> <van-checkbox-group v-model="form.medicalHistory" class="p-4"> <van-checkbox v-for="(item, index) in store.getDict('CP00118')" :key="index" @click="medicalChange" :name="item.value" class="mb-3">{{ item.name }}</van-checkbox> </van-checkbox-group> </div> </van-popup> <van-field required v-model="form.height" name="height" label="身高" type="number" placeholder="输入值10~300,1位小数" maxlength="10" :rules="rules.height" > <template #extra> <span class="ml-1">cm</span> </template> </van-field> <van-field required v-model="form.weight" name="weight" label="体重" type="number" placeholder="输入值20~500,2位小数" maxlength="10" :rules="rules.weight" > <template #extra> <span class="ml-1">kg</span> </template> </van-field> <van-field v-model="form.bmi" name="bmi" label="BMI" type="number" placeholder="请输入" maxlength="10" readonly > <template #extra> <span class="ml-1">kg/m²</span> </template> </van-field> <van-field v-model="form.waistline" name="waistline" label="腰围" type="number" placeholder="输入值10~150,1位小数" maxlength="10" :rules="rules.waistline" > <template #extra> <span class="ml-1">cm</span> </template> </van-field> <van-field v-model="form.isSmoking" name="isSmoking" label="是否吸烟" input-align="right" style="padding-top: .13rem;padding-bottom: .14rem;"> <template #input> <van-radio-group v-model="form.isSmoking" direction="horizontal" class="doc-radio-button"> <van-radio v-for="item in store.getDict('CP00120')" :key="item.value" :name="item.value"> <template #icon> <span :class="['radio-item', {'radio-item-active': form.isSmoking == item.value}]"> {{item.name}} </span> </template> </van-radio> </van-radio-group> </template> </van-field> <van-field required v-model="form.familyHistoryName" is-link readonly name="familyHistory" label="家族史" placeholder="请选择" :rules="rules.familyHistory" @click="showFamily = true"> <template #input> <div class="pb-3"> <!-- <span class="text-end" v-if="form.familyHistoryName">{{ form.familyHistoryName }}</span> <span class="text-end" style="color: #999999" v-else>请选择</span> --> <van-field v-model="form.familyHistoryName" placeholder="请选择" readonly style="padding: 0;background: transparent;" /> </div> <div class="tip">若一级家属(如父母)有家族病史,则请选择</div> </template> </van-field> <van-popup v-model:show="showFamily" position="bottom"> <div class="pt-4 popup-checkbox"> <div class="flex justify-between"> <button class="van-picker__cancel van-haptics-feedback" @click="showFamily = false">取消</button> <button class="van-picker__confirm van-haptics-feedback" @click="familyConfirm">确认</button> </div> <van-checkbox-group v-model="form.familyHistory" class="p-4"> <van-checkbox v-for="(item, index) in store.getDict('CP00167').filter(e => e.value != 7)" :key="index" @click="familyChange" :name="item.value" class="mb-3">{{ item.name }}</van-checkbox> </van-checkbox-group> </div> </van-popup> <div class="px-4 pt-3"> <table class="w-full"> <tr> <td style="width: 7.1em">血压值(mmHg)</td> <td>收缩压(高压)</td> <td>舒张压(低压)</td> </tr> <tr> <td> 第1次测量 </td> <td class="flex"> <van-field v-model="form.pressureOneSbp" name="pressureOneSbp" label="" type="number" placeholder="60~300,整数" maxlength="10" :rules="rules.pressureDbp" error-message-align="left" input-align="left" class="table-field" /> <span class="divide">/</span> </td> <td> <van-field v-model="form.pressureOneDbp" name="pressureOneDbp" label="" type="number" placeholder="30~300,整数" maxlength="10" :rules="rules.pressureSbp" error-message-align="left" input-align="left" class="table-field" /> </td> </tr> <tr> <td> 第2次测量 </td> <td class="flex"> <van-field v-model="form.pressureTwoSbp" name="pressureTwoSbp" label="" type="number" placeholder="60~300,整数" maxlength="10" :rules="rules.pressureDbp" error-message-align="left" input-align="left" class="table-field" /> <span class="divide">/</span> </td> <td> <div class="h-full flex"> <van-field v-model="form.pressureTwoDbp" name="pressureTwoDbp" label="" type="number" placeholder="30~300,整数" maxlength="10" :rules="rules.pressureSbp" error-message-align="left" input-align="left" class="table-field" /> </div> </td> </tr> </table> </div> <van-field v-model="form.fastingGlucose" name="fastingGlucose" label="空腹血糖" type="number" placeholder="输入值0~50,2位小数" maxlength="10" :rules="rules.fastingGlucose" > <template #extra> <span class="ml-1">mmol/L</span> </template> </van-field> <van-field v-model="form.ldlCholesterin" name="ldlCholesterin" label="低密度脂蛋白胆固醇" type="number" placeholder="输入值0~50,2位小数" maxlength="10" :rules="rules.ldlCholesterin" > <template #extra> <span class="ml-1">mmol/L</span> </template> </van-field> <van-field v-model="form.serumCholesterin" name="serumCholesterin" label="血清总胆固醇" type="number" placeholder="输入值0~50,1位小数" maxlength="10" :rules="rules.serumCholesterin" > <template #extra> <span class="ml-1">mmol/L</span> </template> </van-field> <van-field v-model="form.hdlCholesterin" name="hdlCholesterin" label="高密度脂蛋白胆固醇" type="number" placeholder="输入值0~50,1位小数" maxlength="10" :rules="rules.hdlCholesterin" > <template #extra> <span class="ml-1">mmol/L</span> </template> </van-field> <van-field v-model="form.exerciseIntensity" name="exerciseIntensity" label="运动" input-align="right" style="padding-top: .13rem;padding-bottom: .14rem;"> <template #input> <div> <van-radio-group v-model="form.exerciseIntensity" direction="horizontal" class="doc-radio-button"> <van-radio v-for="item in store.getDict('CP00120')" :key="item.value" :name="item.value"> <template #icon> <span :class="['radio-item', {'radio-item-active': form.exerciseIntensity == item.value}]"> {{item.name}} </span> </template> </van-radio> </van-radio-group> <div style="height: 14px"></div> <div class="tip">每周保持150分钟内中等或75分钟内的高强度身体活动</div> </div> </template> </van-field> <van-field required v-model="form.screenDate" is-link readonly name="screenDate" label="筛查日期" placeholder="请选择" @click="showScreenDate = true" /> <van-popup v-model:show="showScreenDate" position="bottom"> <van-date-picker v-model="form._screenDate" :min-date="screenDateRange.min" :max-date="screenDateRange.max" @confirm="screenDateConfirm" @cancel="showScreenDate = false" /> </van-popup> <div class="pt-4"></div> <div class="px-5 pb-4 mt-5 flex align-center justify-around"> <van-button type="primary" round plain style="width: 44%" @click="onPrev">上一步</van-button> <van-button type="primary" round style="width: 44%" @click="submit">下一步</van-button> </div> </van-form> </div> </template> <script> import { useStore } from '@/resident/store/index.js' import { checkboxReject, fetchDataHandle } from '@/utils/common.js' import { savefirstScreen } from '@/api/resident/screening.js' import dayjs from 'dayjs' const defaultForm = (info = {}) => { const form = { // 年龄 currentAge: undefined, // 既往史 medicalHistory: [], medicalHistoryName: undefined, // 身高 height: undefined, // 体重 weight: undefined, bmi: undefined, // 腰围 waistline: undefined, // 是否吸烟 isSmoking: undefined, // 家族史 familyHistory: [], familyHistoryName: undefined, // 空腹血糖 fastingGlucose: undefined, // 血清总胆固醇 serumCholesterin: undefined, // 低密度脂蛋白胆固醇 ldlCholesterin: undefined, // 高密度脂蛋白胆固醇 hdlCholesterin: undefined, // 运动 exerciseIntensity: undefined, // 筛查日期 screenDate: undefined, _screenDate: undefined, // 血压第一次 pressureOneDbp: undefined, pressureOneSbp: undefined, // 血压第二次 pressureTwoDbp: undefined, pressureTwoSbp: undefined, // 高危评估结果(1:一般人群(小于3个指标);2:高危人群(大于等于3个指标)) screenResult: undefined, // 高危项目 CP00113 highItem: undefined, gender: undefined } Reflect.ownKeys(form).forEach(key => { if (info[key] != undefined) { form[key] = info[key] } }) return form } export default { data() { return { form: defaultForm(), rules: { medicalHistory: [{ required: true, message: '请选择' }], familyHistory: [{ required: true, message: '请选择' }], height: [{ required: true, message: '请输入' }, { pattern: /^([1-9]\d{1}(?:\.\d{1})?|[1-2]\d{2}(?:\.\d{1})?|300)$/, message: '输入值在10~300内,1位小数' }], weight: [{ required: true, message: '请输入' }, { pattern: /^([2-9]\d{1}(?:\.\d{1,2})?|[1-4]\d{2}(?:\.\d{1,2})?|500)$/, message: '输入值在20~500内,2位小数' }], waistline: [{ pattern: /^([1-9]\d{1}(?:\.\d{1})?|[1][0-4]\d(?:\.\d{1})?|150)$/, message: '输入值在10~150内,1位小数', validateEmpty: false }], fastingGlucose: [{ pattern: /^(?:0(?:\.\d{1,2})?|[1-4]\d{0,1}(?:\.\d{1,2})?|[1-9]{0,1}(?:\.\d{1,2})?|50)$/, message: '输入值0~50,2位小数', validateEmpty: false }], serumCholesterin: [{ pattern: /^(?:0(?:\.\d{1})?|[1-4]\d{0,1}(?:\.\d{1})?|[1-9]{0,1}(?:\.\d{1})?|50)$$/, message: '输入值0~50,1位小数', validateEmpty: false }], ldlCholesterin: [{ pattern: /^(?:0(?:\.\d{1,2})?|[1-4]\d{0,1}(?:\.\d{1,2})?|[1-9]{0,1}(?:\.\d{1,2})?|50)$/, message: '输入值0~50,2位小数', validateEmpty: false }], hdlCholesterin: [{ pattern: /^(?:0(?:\.\d{1})?|[1-4]\d{0,1}(?:\.\d{1})?|[1-9]{0,1}(?:\.\d{1})?|50)$$/, message: '输入值0~50,1位小数', validateEmpty: false }], pressureDbp: [{ pattern: /^([6-9]\d{1}|[1-2]\d{2}|300)$/, message: '60~300,整数', validateEmpty: false }], pressureSbp: [{ pattern: /^([3-9]\d{1}|[1-2]\d{2}|300)$/, message: '30~300,整数', validateEmpty: false }], }, // 既往史 showMedical: false, // 家族史 showFamily: false, // 筛查日期 showScreenDate: false, // 筛查日期可选范围 screenDateRange: { min: undefined, max: undefined }, store: useStore() } }, computed: { // BMI bmi() { const { height, weight } = this.form return height && weight ? (weight / (height / 100 * height / 100)).toFixed(2) : undefined } }, inject: ['recordForm', 'checkInfo'], created() { this.init() }, methods: { init() { const date = dayjs() this.form.screenDate = date.format('YYYY-MM-DD') this.form._screenDate = [date.year(), date.month() + 1, date.date()] this.screenDateRange.max = new Date(date.year(), date.month(), date.date()) this.screenDateRange.min = new Date(date.year() - 20, date.month(), date.date()) if (this.recordForm.screen) { this.form = defaultForm(this.recordForm.screen) return } const baseInfo = this.recordForm.base this.form.currentAge = baseInfo.currentAge this.form.gender = baseInfo.gender }, submit() { this.$refs.form.validate().then(() => { this.resultHandle() this.recordForm.screen = {...this.form} console.log(this.form) const query = { ...this.form, screenDoctorId: this.recordForm.doctorId, residentsRecord: { ...this.recordForm.base, idCard: this.checkInfo.idCard }, source: 3 } // 提交表单 savefirstScreen(fetchDataHandle(query, { familyHistory: 'arrToStr', highItem: 'arrToStr', medicalHistory: 'arrToStr', })).then(() => { this.$parent.onNext() }) }).catch(err => { console.warn(err) const array = err || [] if (array.length) { this.$refs.form.scrollToField(array[0].name) } }) }, onPrev() { this.$parent.onBack() // this.$refs.form.validate().then(() => { // this.recordForm.screen = {...this.form} // this.$parent.onBack() // }).catch(err => console.warn(err)) }, // 既往史 medicalConfirm() { this.form.medicalHistoryName = this.store.getDict('CP00118').map(e => { return this.form.medicalHistory.includes(e.value) ? e.name : '' }).filter(e => e).join('、') this.showMedical = false }, medicalChange(e) { this.form.medicalHistory = checkboxReject(this.form.medicalHistory, [9]) }, // 家族史 familyConfirm() { this.form.familyHistoryName = this.store.getDict('CP00167').map(e => { return this.form.familyHistory.includes(e.value) ? e.name : '' }).filter(e => e).join('、') this.showFamily = false }, familyChange() { this.form.familyHistory = checkboxReject(this.form.familyHistory, [9]) }, // 筛查日期 screenDateConfirm({ selectedValues }) { this.form.screenDate = selectedValues.join('-') this.showScreenDate = false }, resultHandle() { const {currentAge, height = 0, weight = 0, waistline, familyHistory = [], isSmoking, gender, pressureOneSbp, pressureOneDbp, pressureTwoSbp, pressureTwoDbp, fastingGlucose, ldlCholesterin} = this.form let list = [] if (currentAge >= 50) { list.push(1) } let bmi = parseFloat(this.bmi) if ((bmi >= 24)|| (gender == 2 && waistline >=85) || (gender == 1 && waistline >=90) ){ list.push(2) } if (isSmoking == 1) { list.push(3) } if (familyHistory && familyHistory.length && (familyHistory.includes(1) || familyHistory.includes(2) || familyHistory.includes(3) || familyHistory.includes(4) || familyHistory.includes(5) || familyHistory.includes(6))) { list.push(4) } if ((pressureOneSbp >= 130 || pressureTwoSbp >= 130) || (pressureOneDbp >= 85 || pressureTwoDbp >= 85) ) { list.push(5) } if (fastingGlucose >= 6.1) { list.push(6) } if (ldlCholesterin >= 3.4) { list.push(7) } list = Array.from(new Set(list)) this.form.highItem = list if (list.length >= 3){ this.form.screenResult = 2 }else { this.form.screenResult = 1 } } }, watch: { bmi: { handler() { this.form.bmi = this.bmi }, immediate: true } } } </script> <style lang="less" scoped> @import '../../../utils/common.less'; .tip { color: #8C8C8C; font-size: 12px; position: absolute; bottom: -12px; // left: -100px; right: 0; width: 100vw; overflow: hidden; white-space: nowrap; } table { text-align: left; border-bottom: 1px solid var(--van-cell-border-color); >tr { >td { padding-left: 14px; padding-bottom: 20px; &:first-child { text-align: right; padding-left: 0; } } &:last-child { >td { padding-bottom: 12px; } } } .divide { transform: translateY(4px); } } </style>