<template> <div> <van-form ref='form'> <div class='title'>随访信息</div> <div v-if='showOne'> <div class='label-title'>随访内容</div> <van-field v-model='form.visitContent' name='visitContent' placeholder='随访内容' class='input-back mt-2 form-input' rows='2' autosize type='textarea' :rules='rules.visitContent' /> </div> <div v-if='showOne'> <div class='no-req-label mt-5'>处置意见</div> <van-field v-model='form.disposalOpinion' rows='2' autosize type='textarea' placeholder='处置意见' class='input-back mt-2 form-input' /> </div> <!-- 健康指导--> <div v-if='showTwo'> <div class='flex justify-between items-center mt-5'> <div class='label-title '>健康指导</div> <!-- <van-button class='doc-btn-p' @click='toShowTem(1)'>选择内容</van-button>--> </div> <div class='health mt-2'> <GuideTextVideo :file-type='[1]' :info='form.guide' :content-title="'指导内容'" :classify='1' @changeSelect='toShowTem' ref='guideRef' ></GuideTextVideo> </div> </div> <!-- 宣教内容--> <div v-if='showThree'> <div class='flex justify-between items-center mt-5'> <div class='label-title '>宣教内容</div> <!-- <van-button class='doc-btn-p' @click='toShowTem(2)'>选择内容</van-button>--> </div> <div class='health mt-2'> <div class='health-cell mt-2'> <div class='no-req-label'>健康宣教</div> <van-field v-model='form.publicizeTypeName' readonly is-link placeholder='请选择' class='input-back mt-2 form-input' @click='showPublicizeType= true' > <template #input> <span class='text-end' v-if='form.publicizeTypeName'>{{ form.publicizeTypeName }}</span> <span class='text-end' v-if='!form.publicizeTypeName' style='color: #dfdfe1'>请选择</span> </template> </van-field> <van-popup v-model:show='showPublicizeType' position='bottom'> <div class='p-4'> <div class='flex justify-between mb-4 items-center pop-title'> <div class='greyColor' @click='showPublicizeType = false' style='font-weight: 400'> 取消 </div> <div>健康宣教(可多选)</div> <div class='blueColor' @click='publicizeTypeConfirm'>确定</div> </div> <CheckBtn multiple column-3 :options="store.getDict('DC00091')" v-model:value='checkPublicizeType' :fieldNames="{text: 'name', value: 'value'}" /> </div> </van-popup> </div> <div class='mt-2' v-if='form.publicizeTypeName &&!form?.publicizeType?.includes(1)'> <van-button type='primary' plain class='w-full' @click='toShowTem(2)' size='small'>选择内容</van-button> </div> <div v-if='form?.publicizeType?.includes(1)'> <GuideTextVideo :file-type='[1]' :info='form.publicize' :content-title="'文本内容'" :classify='2' @changeSelect='toShowTem' ref='contentOne'></GuideTextVideo> </div> <div v-if='form?.publicizeType?.includes(2)'> <GuideTextVideo :file-type='[2]' :info='form.publicize' :classify='2' ref='contentTwo'></GuideTextVideo> </div> <div v-if='form?.publicizeType?.includes(3)'> <GuideTextVideo :file-type='[3]' :info='form.publicize' :classify='2' ref='contentThree'></GuideTextVideo> </div> </div> </div> <!-- 催检--> <div v-if='showFour'> <div class='no-req-label mt-5'>催检内容</div> <div class='tel-back mt-2'> <div class='tel'> <div style='text-indent: 2em;line-height: .2rem'> <span v-if='modeEnumList.urgeResidentShow'>{{ firstForm.residentsRecord.residentName }}先生/女士,</span> <span v-else>您好,</span> <span>请您于{{ form.screenTime }}</span> <span>到{{ authInfo.unitName }}</span> <span>进行专病高危筛查/慢病复查,</span> <span>祝早日康复!</span> </div> <div class='mt-2' style='text-align: center' @click='showTime1 = true'> <span style='color: #607FF0'>修改日期</span> </div> </div> </div> <DataTime :values='startTime' :showType="['year', 'month', 'day', 'hour']" @changeValue='showTime1 = false' :showPicker='showTime1' @confirm='timeConfirm1' :min-date='startDateRange.min' :max-date='startDateRange.max' /> </div> <!-- 上传随访照片--> <div v-if='showOne'> <div class='no-req-label mt-5'>上传随访记录</div> <DocImageUpload description='支持上传jpg、png、jpeg文件,大小请在10M以内' lengthMessage='抱歉,最多可上传6个文件。' @change='(ids, option) => form.uploadVisitRecord = ids' :maxLength='6' class='mt-2' /> </div> <!-- 现场随访照片--> <div> <div class='no-req-label mt-5'>现场随访照片</div> <DocImageUpload description='支持上传jpg、png、jpeg文件,大小请在10M以内' lengthMessage='抱歉,最多可上传6个文件。' @change='(ids, option) => form.sceneVisitImage = ids' :maxLength='6' class='mt-2' /> </div> <div> <div class='label-title mt-5'>下次随访日期</div> <van-field v-model='form.nextVisitDate' is-link readonly name='nextVisitDate' placeholder='下次随访日期' class='input-back mt-2 form-input' :rules='rules.nextVisitDate' @click='showDate = true' /> <van-popup v-model:show='showDate' position='bottom'> <van-date-picker v-model='form._nextVisitDate' :min-date='nextVisitDateRange.min' :max-date='nextVisitDateRange.max' @confirm='dataConfirm' @cancel='showDate = false' /> </van-popup> </div> </van-form> <div v-if='showTem'> <temList :show='showTem' @closed='closedTem' @selectRecord='getSelectTem' :templateClassify='citeInfo'></temList> </div> </div> </template> <script> import { useStore } from '@/resident/store' import dayjs from 'dayjs' import DocIcon from '@/components/docIcon/DocIcon' import { showFailToast } from 'vant' import { fetchDataHandle, uniqueArr } from '@/utils/common' import DocImageUpload from '@/doctor/components/docImageUpload/DocImageUpload' import TemList from '@/doctor/components/template/temList' import { getTemplateDetail } from '@/api/doctor/workbench' import GuideTextVideo from '@/doctor/followUp/generalFU/form/GuideTextVideo' import CheckBtn from '@/doctor/components/checkBtn/CheckBtn' import DataTime from '@/doctor/components/dataTime/dataTime' export default { name: 'GeneralFUForm', components: { DataTime, CheckBtn, GuideTextVideo, TemList, DocImageUpload, DocIcon }, props: { info: { default: () => { return {} } }, firstForm: { default: () => { return {} } }, modeEnumList: { default: () => { return {} } } }, data() { return { store: useStore(), form: {}, showDate: false, showTime1: false, showTem: false, showPublicizeType: false, checkPublicizeType: [], currentTime1: null, citeInfo: 1, rules: { visitContent: [{ required: true, message: '请输入' }], nextVisitDate: [{ required: true, message: '请选择' }] }, // 筛查日期可选范围 nextVisitDateRange: { min: undefined, max: undefined }, startTime: '', // 催检时间范围 startDateRange: { min: undefined, max: undefined }, } }, watch: { 'info': { handler() { this.form = this.setForm(this.info) }, immediate: true } }, computed: { authInfo() { return this.store.$state.authInfo }, //复检 showOne() { const { visitWayRules } = this.firstForm let res = false let list = visitWayRules && visitWayRules.split(',').map(item => Number(item)) if (list && list.includes(1)) { res = true } return res }, //指导 showTwo() { const { visitWayRules } = this.firstForm let res = false let list = visitWayRules && visitWayRules.split(',').map(item => Number(item)) if (list && list.includes(2)) { res = true } return res }, //宣教 showThree() { const { visitWayRules } = this.firstForm let res = false let list = visitWayRules && visitWayRules.split(',').map(item => Number(item)) if (list && list.includes(3)) { res = true } return res }, //催检 showFour() { const { visitWayRules } = this.firstForm let res = false let list = visitWayRules && visitWayRules.split(',').map(item => Number(item)) if (list && list.includes(4)) { res = true } return res } }, created() { const date = dayjs() this.nextVisitDateRange.max = new Date(date.year() + 10, date.month(), date.date()) this.nextVisitDateRange.min = new Date(date.year(), date.month(), date.date() + 1) this.form._nextVisitDate = [date.year(), date.month(), date.date() + 1] let time = new dayjs().add(1, 'day').format('YYYY-MM-DD') this.currentTime1 = time.split('-') this.startTime = new dayjs().add(1, 'day').format('YYYY-MM-DD HH:mm:ss') this.startDateRange.max = new Date(date.year() + 10, date.month(), date.date()) this.startDateRange.min = new Date(date.year(), date.month(), date.date() + 1) }, methods: { setForm(data = {}) { let info = fetchDataHandle(data, { visitWayRules: 'strToArrNum', groupsArrays: 'strToArrNum', publicizeType: 'strToArrNum' }) let isSmsIsWx = [] if (info.id) { const { isSms, isWx } = info if (isSms == 1) { isSmsIsWx = [1] } if (isWx == 1) { isSmsIsWx = [2] } if (isSms == 1 && isWx == 1) { isSmsIsWx = [1, 2] } } else { isSmsIsWx = [1] } const form = { id: info.id, groupsArrays: info.groupsArrays, visitDate: info.visitDate || new dayjs(), nextVisitDate: info.nextVisitDate, visitWay: info.visitWay || 1, isSms: info.isSms, isWx: info.isWx, isSmsIsWx: isSmsIsWx, visitContent: info.visitContent, disposalOpinion: info.disposalOpinion, uploadVisitRecord: info.uploadVisitRecord, sceneVisitImage: info.sceneVisitImage, screenTime: info.screenTime || new dayjs().add(1, 'day').format('YYYY-MM-DD HH:00:00'), sendInfo: info.sendInfo, publicizeType: info.publicizeType, guide: info.guide || {}, publicize: info.publicize || {} } return form }, dataConfirm({ selectedValues }) { this.form.nextVisitDate = selectedValues.join('-') this.showDate = false }, //催检日期选择 timeConfirm1(selectedValues) { this.form.screenTime = dayjs(selectedValues).format('YYYY-MM-DD HH:00:00') this.startTime = dayjs(selectedValues).format('YYYY-MM-DD HH:00:00') this.showTime1 = false console.log(this.form) }, toShowTem(val) { this.citeInfo = val this.showTem = true }, closedTem(val) { this.showTem = val }, //获取选中的模板 async getSelectTem(val, selectType = []) { if (val && selectType && selectType.length) { let par = { id: val } let result = await getTemplateDetail(par) const { data } = result let obj = { annexList: [], contentList: [], drugsList: [] } let mp3List = data.annexList && data.annexList.filter(item => item.type == 2) let mp4List = data.annexList && data.annexList.filter(item => item.type == 3) if (selectType.includes(1)) { //是否返回文本选中 obj.contentList = data.contentList obj.drugsList = data.drugsList } if (selectType.includes(2)) {//是否返回音频选中 obj.annexList = [...obj.annexList, ...mp3List] } if (selectType.includes(3)) {//是否返回视频选中 obj.annexList = [...obj.annexList, ...mp4List] } //健康指导 if (this.showTwo && this.citeInfo == 1) { this.setGuide(obj) } //宣教内容 if (this.showThree && this.citeInfo == 2) { this.setPublicize(obj) } } }, publicizeTypeConfirm() { let res = [] this.store.getDict('DC00091').forEach(item => { let selected = this.checkPublicizeType.filter(i => i == item.value) if (selected && selected.length) { res.push(item.name) } }) if (this.checkPublicizeType && this.checkPublicizeType.length) { this.form.publicizeType = this.checkPublicizeType.join() this.form.publicizeTypeName = res.join() } else { this.form.publicizeType = '' this.form.publicizeTypeName = '' } this.showPublicizeType = false }, //健康指导模板赋值 async setGuide(val = {}) { //获取上一次的值 let lastObj = { contentList: [], drugsList: [] } let obj = await this.$refs.guideRef.getForm() lastObj = { contentList: obj.contentList, drugsList: obj.drugsList } //重新赋值 let resObj = { contentList: [], drugsList: [] } if (lastObj.contentList && lastObj.contentList.length) { resObj.contentList = [...lastObj.contentList] } if (lastObj.drugsList && lastObj.drugsList.length) { resObj.drugsList = [...lastObj.drugsList] } //判断模板文本是否选中 并赋值 if (val.contentList) { //文本内容区域存在 初始值 后面选中的模板内容需要拼接在初始值后面 if (lastObj.contentList && lastObj.contentList.length) { //合并相同的文本选项内容 resObj.contentList.forEach(item => { val.contentList.forEach(vitem => { if (item.templateMode != 5 && item.templateMode == vitem.templateMode) { item.templateContent = item.templateContent ? item.templateContent + `\n` + vitem.templateContent : vitem.templateContent } }) }) //去掉 返回的val中与合并后相同的文本 resObj.contentList.forEach(item => { let reIndex = val.contentList.findIndex(vitem => vitem.templateMode == item.templateMode) if (reIndex != -1) { val.contentList.splice(reIndex, 1) } }) //合并剩余的val.contentList到 resObj.contentList中 resObj.contentList = [...resObj.contentList, ...val.contentList] //合并药物指导 //判断之前是否存在药物指导 if (lastObj.drugsList && lastObj.drugsList.length) { //获取之前药物指导的最大_id的值 let rowId = 0 rowId = Math.max.apply(null, lastObj.drugsList.map(item => Number(item._id))) val.drugsList.forEach((item, index) => { item.id = '' item._id = rowId + index + 1 }) //合并 resObj.drugsList = [...resObj.drugsList, ...val.drugsList] } else { resObj.drugsList = [...val.drugsList] } } else { if (val.contentList) { resObj.contentList = [...val.contentList] resObj.drugsList = [...val.drugsList] } } } else { //模板未选中文本 赋初始值 if (lastObj.contentList && lastObj.contentList.length) { resObj.contentList = [...lastObj.contentList] } } console.log('resObj', resObj) this.form.guide = resObj }, //宣教内容模板赋值 async setPublicize(val = {}) { //获取上一次的值 let lastObj = { annexList: [], contentList: [], drugsList: [] } //文本 if (this.form?.publicizeType?.includes(1)) { let obj1 = await this.$refs.contentOne.getForm() lastObj = { annexList: [], contentList: obj1.contentList, drugsList: obj1.drugsList } } //音频 if (this.form?.publicizeType?.includes(2)) { let obj2 = await this.$refs.contentTwo.getForm() let list = obj2.annexList.filter(item => item.type == 2) lastObj = { ...lastObj, annexList: list } } //视频 if (this.form?.publicizeType?.includes(3)) { let obj3 = await this.$refs.contentThree.getForm() let list = obj3.annexList.filter(item => item.type == 3) lastObj = { ...lastObj, annexList: [...lastObj.annexList, ...list] } } //重新赋值 console.log('json', val) let resObj = { annexList: [], contentList: [], drugsList: [] } const { publicizeType = [], publicize = {} } = this.form if (lastObj.annexList && lastObj.annexList.length) { resObj.annexList = [...lastObj.annexList] } if (lastObj.contentList && lastObj.contentList.length) { resObj.contentList = [...lastObj.contentList] } if (lastObj.drugsList && lastObj.drugsList.length) { resObj.drugsList = [...lastObj.drugsList] } //文本 if (publicizeType.includes(1)) { //判断模板文本是否选中 并赋值 if (val.contentList) { //文本内容区域存在 初始值 后面选中的模板内容需要拼接在初始值后面 if (lastObj.contentList && lastObj.contentList.length) { //合并相同的文本选项内容 resObj.contentList.forEach(item => { val.contentList.forEach(vitem => { if (item.templateMode != 5 && item.templateMode == vitem.templateMode) { item.templateContent = item.templateContent ? item.templateContent + `\n` + vitem.templateContent : vitem.templateContent } }) }) //去掉 返回的val中与合并后相同的文本 resObj.contentList.forEach(item => { let reIndex = val.contentList.findIndex(vitem => vitem.templateMode == item.templateMode) if (reIndex != -1) { val.contentList.splice(reIndex, 1) } }) //合并剩余的val.contentList到 resObj.contentList中 resObj.contentList = [...resObj.contentList, ...val.contentList] //合并药物指导 //判断之前是否存在药物指导 if (lastObj.drugsList && lastObj.drugsList.length) { //获取之前药物指导的最大_id的值 let rowId = 0 rowId = Math.max.apply(null, lastObj.drugsList.map(item => Number(item._id))) val.drugsList.forEach((item, index) => { item.id = '' item._id = rowId + index + 1 }) //合并 resObj.drugsList = [...resObj.drugsList, ...val.drugsList] } else { resObj.drugsList = [...val.drugsList] } } else { if (val.contentList) { resObj.contentList = [...val.contentList] resObj.drugsList = [...val.drugsList] } } } else { //模板未选中文本 赋初始值 if (lastObj.contentList && lastObj.contentList.length) { resObj.contentList = [...lastObj.contentList] } } } //音频 if (publicizeType.includes(2)) { //判断模板音频是否选中 并赋值 let mp3List = val.annexList.filter(item => item.type == 2) || [] if (mp3List && mp3List.length) { if (resObj.annexList && resObj.annexList.length) { let rowId = 0 rowId = Math.max.apply(null, resObj.annexList.map(item => Number(item.annexId))) mp3List.forEach((item, index) => { item['annexId'] = rowId + index + 1 resObj.annexList.push(item) }) } else { resObj.annexList = [...mp3List] } } } //视频 if (publicizeType.includes(3)) { //判断模板视频是否选中 并赋值 let mp4List = val.annexList.filter(item => item.type == 3) || [] if (mp4List && mp4List.length) { if (resObj.annexList && resObj.annexList.length) { let rowId = 0 rowId = Math.max.apply(null, resObj.annexList.map(item => Number(item.annexId))) mp4List.forEach((item, index) => { item['annexId'] = rowId + index + 1 resObj.annexList.push(item) }) } else { resObj.annexList = [...mp4List] } } } //对视频音频去重 resObj.annexList = uniqueArr(resObj.annexList, 'relativeUrl') this.form.publicize = resObj }, async onSubmit() { try { if (this.showTwo) { await this.$refs.guideRef.submit() } if (this.showThree) { //文本 if (this.form?.publicizeType?.includes(1)) { await this.$refs.contentOne.submit() } //音频 if (this.form?.publicizeType?.includes(2)) { await this.$refs.contentTwo.submit() } //视频 if (this.form?.publicizeType?.includes(3)) { await this.$refs.contentThree.submit() } } }catch (e) {} return new Promise((resolve, reject) => { this.$refs.form.validate().then(async () => { let time = dayjs(this.form.screenTime).format('YYYY-MM-DD HH:00:00') let content = `${this.modeEnumList?.urgeResidentShow ? `${this.firstForm?.residentsRecord?.residentName}先生/女士,` : `您好,`}请您于${time}到${this.authInfo.unitName}进行专病高危筛查/慢病复查,祝早日恢复健康!` const { publicizeType, ...others } = this.form let publicizeTypeInfo = '' if (publicizeType && publicizeType instanceof Array) { publicizeTypeInfo = publicizeType.join() } if (publicizeType && typeof publicizeType === 'string') { publicizeTypeInfo = publicizeType } let res = { ...others, publicizeType: publicizeTypeInfo, urgentInsContent: content } //健康指导 if (this.showTwo) { let obj = await this.$refs.guideRef.submit() res.guide = { contentList: obj.contentList, drugsList: obj.drugsList } } //宣教内容 if (this.showThree) { let resObj = { annexList: [], contentList: [], drugsList: [] } //文本 if (this.form?.publicizeType?.includes(1)) { let obj1 = await this.$refs.contentOne.submit() resObj = { annexList: [], contentList: obj1.contentList, drugsList: obj1.drugsList } } //音频 if (this.form?.publicizeType?.includes(2)) { let obj2 = await this.$refs.contentTwo.submit() let list = obj2.annexList.filter(item => item.type == 2) if (!list.length) { showFailToast('请上传音频') return } resObj = { ...resObj, annexList: list } } //视频 if (this.form?.publicizeType?.includes(3)) { let obj3 = await this.$refs.contentThree.submit() let list = obj3.annexList.filter(item => item.type == 3) if (!list.length) { showFailToast('请上传视频') return } resObj = { ...resObj, annexList: [...resObj.annexList, ...list] } } res.publicize = { ...resObj } } resolve(res) }).catch((e) => { console.warn('generaFu error', e) // reject(e) }) }) } } } </script> <style scoped lang='less'> // 按钮样式 .doc-btn { border: 0; padding: 4px 8px; height: 26px; border-radius: 38px; } .doc-btn-p { .doc-btn(); color: var(--van-primary-color); background: #F0F3FF; font-size: 13px; } .title { font-weight: bold; margin-bottom: 20px; } .label-title { font-size: 13px; color: #595959; font-weight: 500; &::after { content: "*"; color: red; font-weight: bold; margin-left: 4px; } } .no-req-label { font-size: 13px; color: #595959; font-weight: 500; } .form-input { padding: 8px 12px; border-radius: 8px; } .input-back { background: #FAFAFA; } .tel-back { background: #F5F5F5; padding: 8px; border-radius: 0px 0px 8px 8px; } .tel { background: #FFFFFF; padding: 8px; border-radius: 8px; } .tel-label { color: #607FF0; font-weight: bold; } .p-12-0 { padding: 12px 0px; } .health { padding: 1px 8px 8px 8px; background: #FAFAFA; border-radius: 8px; .health-cell { padding: 8px; background: #FFFFFF; border-radius: 8px; } } .tips { color: #A5AEBE; font-size: 12px; margin-top: 8px; } .img-btn { border: 1px solid #EEEEEE; background: #FAFAFA; border-radius: 8px; padding: 14px 46px; text-align: center; color: #607FF0; } .doc-up { font-size: 20px; } .pdf { border: 1px solid #EEEEEE; border-radius: 8px; padding: 8px; } .remove { font-size: 24px; position: absolute; right: -8px; top: -9px; z-index: 1; } .wrapper { display: flex; align-items: center; justify-content: center; height: 100%; .block { width: 100%; height: 300px; } } :deep(.van-cell-group--inset) { overflow: visible; } :deep(.van-cell) { overflow: visible; } //:deep(.van-field__error-message) { // position: absolute; // margin-top: 3px; //} :deep(.van-cell:after) { border-bottom: 0px; } .warn { color: #ee0a24; text-align: left; } //灰色 .greyColor { color: var(--van-text-color-2); } //确定按钮颜色 .blueColor { color: var(--van-primary-color) } .pop-title { color: #262626; font-size: 16px; line-height: 24px; font-weight: bold; } :deep(.van-popup) { min-height: 30% !important; } </style> <style lang='less'> .custom-image-preview .van-image-preview__container .van-image-preview__item:not(:first-child):not(last-child) { display: block !important; } .van-image__img { width: 100%; } .van-swipe__track { width: 100% !important; } .van-swipe-item { width: 100% !important; } </style>