Instpect.vue 12.3 KB
<template>
    <van-form ref='form' class="doc-form instpect-common" >
        <div class='doc-form-label' required>检验项目</div>
        <van-field is-link
            :modelValue='inspectName'
            readonly
            placeholder='请选择'
            name="inspect"
            @click="showInspect = true"
            :rules="[{ required: true, message: '请选择' }]"
        />
        <van-popup v-model:show="showInspect" position="bottom" style="height: 60%">
            <div class="pt-4 h-full flex flex-col popup-checkbox">
                <div class="flex justify-between shrink-0 pb-2">
                    <button class="van-picker__cancel van-haptics-feedback" @click="showInspect = false" >取消</button>
                    <span class="text-16" >请选择(可多选)</span>
                    <button class="van-picker__confirm van-haptics-feedback" @click="inspectConfirm" >确认</button>
                </div>
                <div class="bottom-small-line"></div>
                <van-checkbox-group v-model="inspect" class="px-4 pb-4 pt-2 grow overflow-y-auto" >
                    <van-checkbox v-for="(item, index) in store.getDict('CP00100')" :key="index"
                        :name="item.value"
                        class="mb-3">
                        <span :class="{'text-primary': adviseInspect.includes(item.value)}">{{ item.name }}</span>
                    </van-checkbox>
                </van-checkbox-group>
            </div>
        </van-popup>
        <div class="flex flex-col mt-3 instpect-list">
            <div v-for="(row, index1) in viewData" :key="row.insType"
                class="pt-3 px-2 mb-2 instpect-list-item"
                :style="`order: ${row.insType}`">
                <div class="mb-3 flex items-center justify-between">
                    <span class="required-mark" >{{ row.insName }}</span>
                    <BloodPressurePanel :pressureObj="pressureObj" v-if="row.insType == 35"/>
                </div>
                <template v-for="(item, index2) in row.items">
                    <van-field :label="getItemName(item)"
                        v-model="item.itemValue"
                        placeholder="请输入"
                        :maxLength="100"
                        :rules="getRule(item)"
                        :name="['viewData', index1, 'items', index2, 'itemValue'].join('.')"
                        class="no-back mb-2"
                        maxlength="100"
                        v-destory:itemValue="item"
                        v-if="item.itemType === 1"
                    >
                        <template #extra v-if="item.unit">
                            <span class="ml-1">{{ item.unit }}</span>
                        </template>
                    </van-field>
                    <van-field :label="getItemName(item)"
                        is-link
                        :modelValue="item.itemValue"
                        readonly
                        placeholder='请选择'
                        :name="['viewData', index1, 'items', index2, 'itemValue'].join('.')"
                        :rules="getRule(item)"
                        @click="setSelectOption(item, item.itemType)"
                        label-align="top"
                        class="no-back mb-2"
                        v-destory:itemValue="item"
                        v-else-if="item.itemType === 3"
                    >
                        <template #extra v-if="item.unit">
                            <span class="ml-1">{{ item.unit }}</span>
                        </template>
                    </van-field>
                    <van-field :label="getItemName(item)"
                        is-link
                        :modelValue="item.itemValue"
                        readonly
                        placeholder='请选择或录入'
                        :name="['viewData', index1, 'items', index2, 'itemValue'].join('.')"
                        :rules="getRule(item)"
                        @click="setSelectOption(item, item.itemType)"
                        label-align="top"
                        class="no-back mb-2"
                        v-destory:itemValue="item"
                        v-else-if="item.itemType === 4"
                    >
                        <template #extra v-if="item.unit">
                            <span class="ml-1">{{ item.unit }}</span>
                        </template>
                    </van-field>
                </template>
                <BloodPressureBt :pressureObj="pressureObj" v-if="row.insType == 35"
                    @getValue="setPressure($event, row)" style="margin-bottom: .08rem" >测量</BloodPressureBt>
            </div>
            <van-popup v-model:show="selectOption.show3" position="bottom">
                <van-picker 
                    title="请选择"
                    :columns="selectOption.dict"
                    :columns-field-names="{text: 'name', value: 'value'}"
                    @confirm="onSelectConfirm"
                    @cancel="() => selectOption.show = false"
                >
                </van-picker>
            </van-popup>
            <InputSelect v-model:show="selectOption.show4"
                :dict="selectOption.dict"
                @change="onSelectInputConfirm"></InputSelect>
        </div>
        <van-field name="imageData"
            class="no-back"
            label="图片上传"
            label-align="top"
            style="padding: 0">
            <template #input>
                <DocImageUpload :imageData="imageData"
                    @change="(ids, option) => image = ids"
                    :maxLength="3"
                    description="请上传JPG、PNG格式图片,文件大小不超过10M"
                    class="w-full"/>
            </template>
        </van-field>
    </van-form>
</template>

<script>
import { inspectDefault } from './config.js'
import { getInspectCode } from '@/api/doctor/disease.js'
import { useStore } from '@/doctor/store/index.js'
import InputSelect from './InputSelect.vue'
import DocImageUpload from '@/doctor/components/docImageUpload/DocImageUpload.vue'
import { BloodPressurePanel, BloodPressureBt } from '@/doctor/components/bloodPressure/index.js'

export default {
    name: 'InstpectCommon',
    components: {
        InputSelect,
        DocImageUpload,
        BloodPressurePanel,
        BloodPressureBt
    },
    inject: ['pressureObj'],
    props: {
        // 初始化数据
        info: { default: () => { return {} } },
        // 慢病
        disease: {
            type: [String, Number],
            required: true
        },
        // 是否显示图片上传表单
        imageVisible: {
            type: Boolean,
            default: false
        }
    },
    data() {
        return {
            store: useStore(),
            inspect: [],
            inspectName: '',
            viewData: [],
            image: '',
            // 可显示的检验项
            codeTable: [],
            // 图片上传回显
            imageData: [],
            showInspect: false,
            selectOption: {
                show3: false,
                show4: false,
                dict: [],
                item: {}
            }
        }
    },
    computed: {
        // 推荐选中的项目
        adviseInspect() {
            return inspectDefault(this.disease)
        }
    },
    created() {
        this.init()
    },
    methods: {
        init() {
            if (this.info.inspect) {
                let inspect = this.info.inspect
                this.inspect = typeof inspect === 'string' ? inspect.split(',') : inspect
                this.inspectName = this.store.getDictValue('CP00100', this.inspect)
            }
            this.image = this.info.image
            this.imageData = this.info.imageData || []
            getInspectCode(1).then(res => {
                console.log(res)
                const inspect = this.inspect
                const data = this.info.items || []
                this.codeTable = res.data || []
                this.codeTable.forEach(e => {
                    const item = data.find(i => e.itemCode === i.itemCode) || {}
                    e.itemValue = item.itemValue
                })
                this.viewData = inspect.map(val => {
                    const items = this.codeTable.filter(e => e.insType === val)
                    if (!items.length) return {}
                    return {
                        insName: items[0].insName,
                        insType: val,
                        items: [...items]
                    }
                })
                console.log(this.viewData)
            })
        },
        submit() {
            return new Promise((resolve, reject) => {
                this.$refs.form.validate().then(() => {
                    const inspect = this.inspect.join(',')
                    const image = this.image
                    let data = []
                    this.viewData.forEach(e => {
                        data = data.concat(e.items)
                    })
                    console.log(data, inspect, image)
                    resolve({ inspect, data, image })
                }).catch((e) => {
                    reject('检验表单校验失败')
                    console.warn('检验表单校验失败', e)
                    const array = e || []
                    if (array.length) {
                        this.$refs.form.scrollToField(array[0].name)
                    }
                })
            })
        },
        inspectConfirm() {
            this.inspectName = this.store.getDict('CP00100').map(e => {
                return this.inspect.includes(e.value) ? e.name : ''
            }).filter(e => e).join('、')
            this.showInspect = false
            this.inspectChange(this.inspect)
        },
        inspectChange(val) {
            const viewData = this.viewData
            const addValue = val.filter(e => !viewData.find(i => i.insType === e))
            const delValue = viewData.filter(i => !val.includes(i.insType)).map(e => e.insType)
            if (delValue.length) {
                this.viewData = this.viewData.filter(e => !delValue.includes(e.insType))
            }
            if (addValue.length) {
                addValue.forEach(val => {
                    const items = this.codeTable.filter(e => e.insType === val)
                    if (!items.length) return {}
                    this.viewData.push({
                        insName: items[0].insName,
                        insType: val,
                        items: [...items]
                    })
                })
            }
            setTimeout(() => {
                this.$refs.form.resetValidation()
            }, 0)
            console.log('inspectChange', this.viewData)
        },
        getItemName(item) {
            if (item.itemCode) {
                return `${item.itemName}(${item.itemCode}) : `
            }
            return item.itemName + ' : '
        },
        getRule(item) {
            if (!item.pattern) {
                return [{ required: true, message: '请录入' }]
            }
            return [
                { required: true, message: '请录入' },
                { pattern: new RegExp(item.pattern), message: item.message }
            ]
        },
        setSelectOption(item, itemType) {
            this.selectOption.dict = item.dictItemList
            this.selectOption.item = item
            this.selectOption['show'+itemType] = true
        },
        onSelectConfirm({ selectedValues } = {}) {
            // console.log(selectedValues)
            this.selectOption.item.itemValue = selectedValues[0]
            this.selectOption.show3 = false
        },
        onSelectInputConfirm(option) {
            this.selectOption.item.itemValue = option.value
            this.selectOption.show4 = false
        },
        setPressure(val, row = {}) {
            const items = row.items || []
            items[0] && (items[0].itemValue = val.systolicPressure)
            items[1] && (items[1].itemValue = val.diastolicPressure)
        }
    }
}
</script>

<style lang="less" scoped>
.instpect-list {
    .instpect-list-item {
        background-color: #F5F5F5;
        border-radius: 8px;
    }
    :deep(.van-field) {
        border-radius: .08rem;
        .van-field__label {
            width: auto;
        }
    }
}
</style>