普兆健康管家前端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

533 lines
18 KiB

<template>
<view class="page__view">
<navbar title="检测预约" leftClick @leftClick="$utils.navigateBack" color="#191919" bgColor="#F3F2F7" />
<view class="main">
<view class="card">
<view class="card-header">{{ typeDesc }}</view>
<view class="flex row">
<view class="row-label">联系电话</view>
<view class="row-content">{{ info.phone || '-' }}</view>
</view>
</view>
<view class="card">
<view class="card-header">预约信息</view>
<view class="form">
<uv-form
ref="form"
:model="form"
errorType="toast"
>
<!-- 自采 -->
<template v-if="type == 1">
<view class="form-item">
<uv-form-item prop="addressData" :customStyle="formItemStyle">
<view class="form-item-label">寄送地址</view>
<view class="form-item-content">
<view class="flex row" @click="jumpToSelectAddress">
<view v-if="form.addressData" class="text">{{ getAddressDesc(form.addressData) }}</view>
<view v-else class="text placeholder">请选择内容</view>
<uv-icon name="arrow-right" color="#C6C6C6" size="32rpx"></uv-icon>
</view>
</view>
</uv-form-item>
</view>
</template>
<!-- 上门 -->
<template v-else-if="type == 2">
<view class="form-item">
<uv-form-item prop="addressData" :customStyle="formItemStyle">
<view class="form-item-label">体检地址</view>
<view class="form-item-content">
<view class="flex row" @click="jumpToSelectAddress">
<view v-if="form.addressData" class="text">{{ getAddressDesc(form.addressData) }}</view>
<view v-else class="text placeholder">请选择内容</view>
<uv-icon name="arrow-right" color="#C6C6C6" size="32rpx"></uv-icon>
</view>
</view>
</uv-form-item>
</view>
<view class="form-item">
<uv-form-item prop="date" :customStyle="formItemStyle">
<view class="form-item-label">预约日期</view>
<view class="form-item-content">
<view class="flex row" @click="openDatePicker">
<view v-if="form.date" class="text">{{ $dayjs(form.date).format('YYYY-MM-DD') }}</view>
<view v-else class="text placeholder">请选择内容</view>
<uv-icon name="arrow-right" color="#C6C6C6" size="32rpx"></uv-icon>
</view>
<uv-datetime-picker
ref="datetimePicker"
v-model="form.date"
mode="date"
title="预约日期"
confirmColor="#7451DE"
cancelColor="#8B8B8B"
round="32rpx"
:minDate="minTime"
@confirm="onDateChange"
></uv-datetime-picker>
</view>
</uv-form-item>
</view>
<view class="form-item">
<uv-form-item prop="timeRange" :customStyle="formItemStyle">
<view class="form-item-label">预约时段</view>
<view class="form-item-content">
<view class="flex row" @click="openTimePicker">
<view v-if="form.timeRange" class="text">{{ form.timeRange.join('~') }}</view>
<view v-else class="text placeholder">请选择内容</view>
<uv-icon name="arrow-right" color="#C6C6C6" size="32rpx"></uv-icon>
</view>
<uv-picker
ref="timeRangePicker"
:columns="timeColumns"
:defaultIndex="[0, 0]"
title="预约时段"
confirmColor="#7451DE"
cancelColor="#8B8B8B"
round="32rpx"
@change="onTimeRangeColChange"
@confirm="onTimeRangeChange"
></uv-picker>
</view>
</uv-form-item>
</view>
</template>
<!-- 到店 -->
<template v-else-if="type == 3">
<view class="form-item">
<uv-form-item prop="addressData" :customStyle="formItemStyle">
<view class="form-item-label">预约日期</view>
<view class="form-item-content">
<view class="flex row" @click="openDatePicker">
<view v-if="form.date" class="text">{{ $dayjs(form.date).format('YYYY-MM-DD') }}</view>
<view v-else class="text placeholder">请选择内容</view>
<uv-icon name="arrow-right" color="#C6C6C6" size="32rpx"></uv-icon>
</view>
<uv-datetime-picker
ref="datetimePicker"
v-model="form.date"
mode="date"
title="预约日期"
confirmColor="#7451DE"
cancelColor="#8B8B8B"
round="32rpx"
:minDate="minTime"
@confirm="onDateChange"
></uv-datetime-picker>
</view>
</uv-form-item>
</view>
<view class="form-item">
<uv-form-item prop="timeRange" :customStyle="formItemStyle">
<view class="form-item-label">预约时段</view>
<view class="form-item-content">
<view class="flex row" @click="openTimePicker">
<view v-if="form.timeRange" class="text">{{ form.timeRange.join('~') }}</view>
<view v-else class="text placeholder">请选择内容</view>
<uv-icon name="arrow-right" color="#C6C6C6" size="32rpx"></uv-icon>
</view>
<uv-picker
ref="timeRangePicker"
:columns="timeColumns"
:defaultIndex="[0, 0]"
title="预约时段"
confirmColor="#7451DE"
cancelColor="#8B8B8B"
round="32rpx"
@change="onTimeRangeColChange"
@confirm="onTimeRangeChange"
></uv-picker>
</view>
</uv-form-item>
</view>
<view class="form-item">
<uv-form-item prop="hospital" :customStyle="formItemStyle">
<view class="form-item-label">预约医院</view>
<view class="form-item-content">
<view class="flex row" @click="openHospitalPicker">
<view v-if="form.hospital" class="text">{{ getHospitalDesc(form.hospital) }}</view>
<view v-else class="text placeholder">请选择内容</view>
<uv-icon name="arrow-right" color="#C6C6C6" size="32rpx"></uv-icon>
</view>
<uv-picker
ref="hospitalPicker"
:columns="[hospitalOptions]"
keyName="label"
title="预约医院"
confirmColor="#7451DE"
cancelColor="#8B8B8B"
round="32rpx"
@confirm="onHospitalChange"
></uv-picker>
</view>
</uv-form-item>
</view>
<view class="form-item">
<uv-form-item prop="name" :customStyle="formItemStyle">
<view class="form-item-label">姓名</view>
<view class="form-item-content input">
<formInput v-model="form.name" placeholder="请输入内容"></formInput>
</view>
</uv-form-item>
</view>
<view class="form-item">
<uv-form-item prop="phone" :customStyle="formItemStyle">
<view class="form-item-label">联系方式</view>
<view class="form-item-content input">
<formInput v-model="form.phone" placeholder="请输入内容"></formInput>
</view>
</uv-form-item>
</view>
</template>
</uv-form>
</view>
</view>
</view>
<view class="bottom">
<button class="btn" @click="onSubmit">提交预约</button>
</view>
</view>
</template>
<script>
import { mapState } from 'vuex'
import formInput from '@/pages_order/components/formInput.vue'
const TYPE_AND_DESC_MAPPING = {
1: '自采',
2: '上门',
3: '到店',
}
export default {
components: {
formInput,
},
data() {
return {
id: null,
type: null,
info: {},
form: {
addressData: null,
date: null,
timeRange: null,
hospital: null,
name: null,
phone: null,
},
formItemStyle: { padding: 0 },
minTime: new Date().getTime(),
hours: [],
timeColumns: [],
hospitalOptions: []
}
},
computed: {
...mapState(['configList', 'userInfo', 'payOrderProduct', 'addressInfo']),
typeDesc() {
const desc = TYPE_AND_DESC_MAPPING[this.type] || ''
return `${desc}检测`
},
},
onShow() {
console.log('onShow')
console.log('address', this.addressInfo)
this.form.addressData = this.addressInfo || null
},
onLoad(arg) {
const { id, type } = arg
this.id = id
this.type = parseInt(type)
// todo: fetch data
this.fetchCheckUpPackageInfo()
this.fetchCheckUpBookInfo()
},
onReady() {
this.setRules()
},
onUnload() {
this.$store.commit('setAddressInfo', null)
},
methods: {
setRules() {
let rules = {}
switch(this.type) {
case 1: // 自采
rules = {
'addressData': {
type: 'object',
required: true,
message: '请选择寄送地址',
},
}
break
case 2: // 上门
rules = {
'addressData': {
type: 'object',
required: true,
message: '请选择体检地址',
},
'date': {
type: 'string',
required: true,
message: '请选择预约日期',
},
'timeRange': {
type: 'array',
required: true,
message: '请选择预约时段',
},
}
this.setTimeColumns()
break
case 3: // 到店
rules = {
'date': {
type: 'string',
required: true,
message: '请选择预约日期',
},
'timeRange': {
type: 'array',
required: true,
message: '请选择预约时段',
},
'hospital': {
type: 'string',
required: true,
message: '请选择预约医院',
},
'name': {
type: 'string',
required: true,
message: '请输入姓名',
},
'phone': {
type: 'string',
required: true,
message: '请输入联系方式',
},
}
this.setTimeColumns()
this.hospitalOptions = [
{ id: '001', label: '湖南省长沙市湘雅第一医院' },
{ id: '002', label: '湖南省长沙市湘雅第二医院' },
{ id: '003', label: '湖南省长沙市湘雅第三医院' },
{ id: '004', label: '湖南省长沙市湘雅第四医院' },
]
break
default:
break
}
this.$refs.form.setRules(rules);
},
getAddressDesc(data) {
if (!data) {
return ''
}
const { area, address } = data
return `${area.join('')}${address}`
},
getHospitalDesc() {
},
fixedZero(num) {
return `${num < 10 ? '0' + num : num}`
},
setTimeColumns(date) {
let currentTime = this.$dayjs()
let startHour = 8
let endHour = 22
if (date && this.$dayjs(date).isSame(currentTime, 'day')) {
let currentHour = currentTime.hour()
console.log('currentHour', currentHour)
console.log('startHour', startHour)
console.log('endHour', endHour)
console.log('date', this.$dayjs(date))
console.log('currentTime', currentTime)
console.log('isToday', this.$dayjs(date).isSame(currentTime, 'day'))
if (currentHour > endHour) {
this.timeColumns = []
return
}
if (currentHour > startHour) {
// todo: check
startHour = currentHour
}
if (startHour == endHour) {
this.timeColumns = []
return
}
}
this.hours = new Array(endHour - startHour + 1).fill(startHour).map((val, idx) => val + idx)
let startCols = this.hours.slice(0, this.hours.length - 1).map(hour => `${this.fixedZero(hour)}:00`)
let endCols = this.hours.slice(1).map(hour => `${this.fixedZero(hour)}:00`)
this.timeColumns = [startCols, endCols]
this.$refs.timeRangePicker.setColumnValues(0, startCols)
this.$refs.timeRangePicker.setColumnValues(1, endCols)
},
openTimePicker() {
this.$refs.timeRangePicker.open();
},
onTimeRangeColChange(e) {
console.log('onTimeRangeColChange', e)
if (e.columnIndex == 0) {
let startIdx = e.indexs[0]
let endCols = startIdx == this.hours.length - 1 ? [] : this.hours.slice(startIdx + 1).map(hour => `${this.fixedZero(hour)}:00`)
console.log('endCols', endCols)
this.timeColumns[1] = endCols
this.$refs.timeRangePicker.setColumnValues(1, endCols)
}
},
onTimeRangeChange(e) {
console.log('onTimeRangeChange', e)
this.form.timeRange = e.value
const [startTime, endTime] = this.form.timeRange
let startIdx = startTime ? this.timeColumns[0].findIndex(item => item === startTime) : 0
let endIdx = endTime ? this.timeColumns[1].findIndex(item => item === endTime) : 0
console.log('setIndexs', [startIdx, endIdx])
this.$refs.timeRangePicker.setIndexs([startIdx, endIdx], true);
},
openDatePicker() {
this.$refs.datetimePicker.open();
},
onDateChange(e) {
const date = e.value
this.setTimeColumns(date)
const [startTime] = this.form.timeRange || []
let dateStr = this.$dayjs(date).format('YYYY-MM-DD')
if (startTime && this.$dayjs(`${dateStr} ${startTime}`).isBefore(this.$dayjs())) {
this.form.timeRange = null
this.$refs.datetimePicker.setIndexs([0, 0]);
}
},
openHospitalPicker() {
this.$refs.hospitalPicker.open();
},
onHospitalChange(e) {
console.log('onHospitalChange', e)
this.form.hospital = e.value[0].id
console.log('form.hospital', this.form.hospital)
},
getHospitalDesc(id) {
console.log('getHospitalDesc', id)
return this.hospitalOptions.find(item => item.id === id)?.label
},
fetchCheckUpPackageInfo() {
// todo: fetch
this.info = {
phone: '0745-5982433',
}
},
fetchCheckUpBookInfo() {
// todo: fetch
const detail = {
id: '003',
url: '',
title: '孕产妇体检套餐',
userName: '周小艺',
phone: '15558661691',
amount: 688,
area: ['海南省', '海口市', '秀英区'],
address: '秀英街道5单元183室',
hospital: '001',
createTime: '2025-04-28 08:14',
appointmentDate: '2025-04-28',
appointmentTime: ['08:00', '09:00'],
type: 2,
status: 2,
}
const {
userName,
phone,
area,
address,
appointmentDate,
appointmentTime,
hospital,
} = detail
this.form = {
addressData: {
id: '001',
name: userName,
phone,
area,
address,
},
date: appointmentDate,
timeRange: appointmentTime,
hospital,
name: userName,
phone,
}
},
jumpToSelectAddress() {
this.$utils.navigateTo('/pages_order/address/addressList')
},
async onSubmit() {
try {
const res = await this.$refs.form.validate()
console.log('onSubmit res', res)
// todo
setTimeout(() => {
// todo: check
// this.$utils.navigateBack()
let id = '001'
this.$utils.redirectTo(`/pages_order/checkup/checkupBook/detail?id=${id}`)
}, 800)
} catch (err) {
console.log('onSubmit err', err)
}
},
},
}
</script>
<style scoped lang="scss">
@import './style.scss';
</style>