<template> <view class="flex-col justify-start relative page"> <view class="section"></view> <text class="font text pos_2">选择联系人</text> <image class="image pos" :src="bookUrl + '/photoProductsOrder/yyxz.png'" @click="openTipsPopup" /> <text class="font_2 text_2 pos_3" @click="openTipsPopup">预约须知</text> <view class="flex-row justify-between items-center section_2 pos_4" @click="openContactsPopup"> <view class="flex-row items-center"> <image class="shrink-0 image_2" :src="bookUrl + '/photoProductsOrder/lxr.png'" /> <text class="font text_3 ml-10">{{ contactTemplateString }}</text> </view> <view class="flex-row items-center group"> <image class="image_3" :src="bookUrl + '/photoProductsOrder/yjt.png'" /> <text class="font_3 text_4">更换联系人</text> </view> </view> <text class="font text_5 pos_5">请选择拍摄时间</text> <view class="flex-col section_3 pos_6"> <text class="self-start font_2 text_6">预约日期:{{ bookingDate }}</text> <text class="self-start font_2 text_7">预约时间:{{ bookingTime }}</text> <view class="self-stretch divider"></view> <view class="flex-row equal-division my-box"> <view class="flex-col items-center section_4 equal-division-item" @click="selectTime(index)" :style="timeSelectedStyle[index]" v-for="(item, index) in bookingDateVOList" :key="index"> <text class="font_3" :style="timeFontStyle[index]">{{ getWeekday(item.specificDate) }}</text> <text class="font_4 mt-11" :style="timeFontStyle[index]">{{ item.specificDate.substr(5) }}</text> </view> </view> <view class="flex-col justify-start self-stretch group_2"> <view class="flex-row relative group_1 my_grid"> <view class="flex-col justify-start items-center text-wrapper_1 pos_1" :style="tpSelectedStyle[bid][index]" v-for="(item, index) in bookingDateVOList[bid].bookingTimeVOList" :key="index" @click="selectTpTime(index)" > <text class="font_5" :style="tpFontStyle[bid][index]"> {{ item.timePoint }}</text> </view> </view> </view> </view> <text class="font pos_7">预约信息</text> <view class="flex-row justify-between items-center section_5 pos_8"> <view class="flex-row items-center"> <image class="image_4" :src="photoProduct.introImg" /> <view class="flex-col items-start ml-11"> <text class="font_2 text_8">{{ photoProduct.name }}</text> <text class="font_6 text_9 mt-10">拍摄人数:{{ number }}人</text> <text class="font_6 text_10 mt-10">拍摄场地:{{ field }}</text> <text class="font_6 text_12 mt-10">预约门店:哈尔滨师范大学</text> </view> </view> <view class="flex-col items-center group_3" @click="nav"> <image class="image" :src="bookUrl + '/photoProductsOrder/nav.png'" /> <text class="text_11 mt-3">导航</text> </view> </view> <view class="flex-row justify-between items-center section_6 pos_9"> <view class="flex-row items-baseline"> <text class="font text_13">定金:</text> <text class="font text_14">¥{{ totalPrice.toFixed(2) }}</text> </view> <view class="flex-col justify-start items-center text-wrapper_2" @click="confirm"><text class="font_2 text_15">确定</text></view> </view> </view> <uni-popup ref="bookingTips" :maskClick="false" :animation="false"> <view class="booking-tips"> <bookingTipsVue></bookingTipsVue> </view> </uni-popup> <uni-popup ref="contactsPopup" > <view class="contacts-popup"> <contactsComponentVue></contactsComponentVue> </view> </uni-popup> <uni-popup ref="confirmBookingInfo" :maskClick="true" :animation="false"> <view class="confirm-book-info"> <confirmBookingInfoVue></confirmBookingInfoVue> </view> </uni-popup> <!-- 遮罩层 --> <view v-if="isShow" class="overlay"></view> </template> <script setup lang="ts"> import {nextTick, onMounted, onUnmounted, ref} from 'vue' import emitter from '../../../utils/emitter'; import bookingTipsVue from '../component/bookingTips.vue'; import { baseUrl } from '../../../api/request'; import contactsComponentVue from '../../order/component/contactsComponent.vue'; import confirmBookingInfoVue from '../component/confirmBookingInfo.vue'; import { onLoad } from "@dcloudio/uni-app"; import { bookUrl } from '../../../common/globalImagesUrl'; import { getFonts } from '../../../common/globalFont'; const cookie = wx.getStorageSync("cookie") //请求头 const photoProduct = ref({}) const bookingDateVOList = ref([]) const timeSelectedStyle = ref([]) const timeFontStyle = ref([]) const tpSelectedStyle = ref([]) const tpFontStyle = ref([]) const bid = ref(0) const bookingDate = ref('请选择') const bookingTime = ref('请选择') const bookingDateId = ref(0) const bookingTimeId = ref(0) const bookingTips = ref(null) const contactsPopup = ref(null) const confirmBookingInfo = ref(null) const contactInfo = ref({}) const field = ref('') const number = ref(0) const id = ref(0) const totalPrice = ref(0) const isShow = ref(false) let loading = false; const type = ref('') const contactTemplateString = ref('请选择') function showLoading() { if (!loading) { wx.showLoading({ title: '加载中...', }); loading = true; } } function hideLoading() { if (loading) { wx.hideLoading(); loading = false; } } const openTipsPopup = () => { bookingTips.value.open('center') } const openContactsPopup = () => { contactsPopup.value.open('bottom') } const confirm = () => { if (contactTemplateString.value === null || contactTemplateString.value === undefined || contactTemplateString.value === '请选择') { uni.showToast({ title: '请选择联系人', icon: 'error' }) return ; } if (bookingTime.value === null || bookingTime.value == undefined || bookingTime.value === '请选择') { uni.showToast({ title: '请填写预约时间', icon: 'error' }) return ; } emitter.emit('getBookingOrderData', { field: field.value, number: number.value, id: id.value, contactId: contactInfo.value.id, name: photoProduct.value.name, bookingDateId: bookingDateId.value, bookingTimeId: bookingTimeId.value, bookingDate: bookingDate.value, bookingTime: bookingTime.value, type: type.value }) confirmBookingInfo.value.open('center') } onLoad((options) => { getFonts() console.log(options) field.value = options.field number.value = options.number id.value = options.id type.value = options.type }) const closeBookingTipsHandler = () => { nextTick(() => { if (bookingTips.value) { bookingTips.value.close() } }) } const closeHandler = () => { nextTick(() => { if (contactsPopup.value) { contactsPopup.value.close() } }) } const contactsNowInfoHandler = (val) => { contactInfo.value = val contactTemplateString.value = val.name + ' ' + val.phone console.log(val) } const closeConfirmBookingInfoHandler = () => { nextTick(() => { if (confirmBookingInfo.value) { confirmBookingInfo.value.close() } }) } const openMaskHandler = () => { showLoading() isShow.value = true } const closeMaskHandler = () => { hideLoading() isShow.value = false } onMounted(() => { getFonts() getDefaultAddress() getPhotoProductsById() emitter.on('closeBookingTips', closeBookingTipsHandler) emitter.on('close', closeHandler) emitter.on('contactsNowInfo', contactsNowInfoHandler) emitter.on('closeConfirmBookingInfo', closeConfirmBookingInfoHandler) emitter.on('openMask', openMaskHandler) emitter.on('closeMask', closeMaskHandler) }) onUnmounted(() => { emitter.off('closeBookingTips', closeBookingTipsHandler) emitter.off('close', closeHandler) emitter.off('contactsNowInfo', contactsNowInfoHandler) emitter.off('closeConfirmBookingInfo', closeConfirmBookingInfoHandler) emitter.off('openMask', openMaskHandler) emitter.off('closeMask', closeMaskHandler) }) const getPhotoProductsById = async () => { const res = await uni.request({ url: baseUrl + '/photoProducts/list/detail', method: 'POST', header: { cookie }, data: { id: id.value } }) console.log(res.data.data) photoProduct.value = res.data.data totalPrice.value = photoProduct.value.price * number.value bookingDateVOList.value = res.data.data.bookingDateVOList timeSelectedStyle.value = new Array(bookingDateVOList.value.length).fill(null).map(() => ({ backgroundColor: '#F3F3F3', })) timeFontStyle.value = new Array(bookingDateVOList.value.length).fill(null).map(() => ({ color: '#8B8B8B', })) timeSelectedStyle.value[0].backgroundColor = '#FFB6B9' timeFontStyle.value[0].color = '#C35C5D' bookingDate.value = bookingDateVOList.value[0].specificDate bookingDateId.value = bookingDateVOList.value[0].id for (var i = 0; i < bookingDateVOList.value.length; i ++ ) { let len = bookingDateVOList.value[i].bookingTimeVOList.length tpSelectedStyle.value[i] = new Array(len).fill(null).map(() => ({ borderColor: '#8B8B8B' })) } for (var i = 0; i < bookingDateVOList.value.length; i ++ ) { let len = bookingDateVOList.value[i].bookingTimeVOList.length tpFontStyle.value[i] = new Array(len).fill(null).map(() => ({ color: '#323232', })) } } const selectTime = (index:any) => { if (bid.value === index) return ; bookingTime.value = '请选择' bookingTimeId.value = 0 bid.value = index bookingDate.value = bookingDateVOList.value[index].specificDate bookingDateId.value = bookingDateVOList.value[index].id for (var i = 0; i < bookingDateVOList.value.length; i ++ ) { if (i == index) { timeSelectedStyle.value[i].backgroundColor = '#FFB6B9' timeFontStyle.value[i].color = '#C35C5D' } else { timeSelectedStyle.value[i].backgroundColor = '#F3F3F3' timeFontStyle.value[i].color = '#8B8B8B' } } let col = bookingDateVOList.value[index].bookingTimeVOList.length for (var i = 0; i < col ; i ++ ) { tpSelectedStyle.value[bid.value][i].borderColor = '#8B8B8B' tpFontStyle.value[bid.value][i].color = '#323232' } } const selectTpTime = (index:any) => { bookingTime.value = bookingDateVOList.value[bid.value].bookingTimeVOList[index].timePoint bookingTimeId.value = bookingDateVOList.value[bid.value].bookingTimeVOList[index].id let len = bookingDateVOList.value[bid.value].bookingTimeVOList.length for (var i = 0; i < len; i ++ ) { if (i == index) { tpSelectedStyle.value[bid.value][i].borderColor = '#C35C5D' tpFontStyle.value[bid.value][i].color = '#C35C5D' } else { tpSelectedStyle.value[bid.value][i].borderColor = '#8B8B8B' tpFontStyle.value[bid.value][i].color = '#323232' } } } const nav = () => { wx.openLocation({ latitude: 45.867741, longitude: 126.560037, name: '哈尔滨师范大学(松北校区)', address: '黑龙江省哈尔滨市呼兰区利民经济开发区师大路1号', success: (res) => { console.log(res) } }) } function getWeekday(dateStr:any) { const date = new Date(dateStr); const weekdays = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]; return weekdays[date.getDay()]; } //获取用户默认联系人 const getDefaultAddress = async () =>{ const res = await uni.request({ url: baseUrl + '/contacts/list', method: 'POST', header: { cookie: wx.getStorageSync('cookie') } }) if(res.data.code === 1) { console.log('联系人数组---->',res.data.data); } //根据for循环遍历默认地址 for(let key in res.data.data) { if(res.data.data[key].isDefault === 1) { contactInfo.value = res.data.data[key] contactTemplateString.value = contactInfo.value.name + ' ' + contactInfo.value.phone } } } </script> <style scoped lang="scss"> .overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.4); /* 半透明黑色背景 */ z-index: 999; } .confirm-book-info { justify-content: center; background-color: #fff; border-radius: 41.1rpx; margin-top: -150rpx; width: 600rpx; } .contacts-popup { height: 800rpx; } .booking-tips { justify-content: center; background-color: #fff; border-radius: 41.1rpx; margin-top: -100rpx; width: 650rpx; } .my-box { width: 100%; overflow-x: auto; } /* 隐藏滚动条 */ ::-webkit-scrollbar { display: none; } .mt-11 { margin-top: 20.63rpx; } .ml-11 { margin-left: 20.63rpx; } .mt-3 { margin-top: 5.63rpx; } .page { background-color: #ffffff; background-image: url(https://carbon2.obs.cn-north-4.myhuaweicloud.com/feiyi/miniProgram/book/photoProductsOrder/bkg.png); background-size: 100% 100%; background-repeat: no-repeat; width: 100%; overflow-y: auto; overflow-x: hidden; height: 100%; } .section { background-image: url(https://carbon2.obs.cn-north-4.myhuaweicloud.com/feiyi/miniProgram/book/photoProductsOrder/bkg.png); background-size: 100% 100%; background-repeat: no-repeat; width: 750rpx; height: 100vh; } .font { font-size: 37.5rpx; font-family: FZSongKeBenXiuKaiS-R-GB; line-height: 35.01rpx; color: #000000; } .text { line-height: 36.47rpx; } .pos_2 { position: absolute; left: 16.46rpx; top: 45.38rpx; } .image { width: 45rpx; height: 45rpx; } .pos { position: absolute; right: 138.13rpx; top: 40.25rpx; } .font_2 { font-size: 30rpx; font-family: FZSongKeBenXiuKaiS-R-GB; line-height: 28.01rpx; color: #000000; } .text_2 { line-height: 27.54rpx; } .pos_3 { position: absolute; right: 19.33rpx; top: 48.51rpx; } .section_2 { padding: 20.63rpx 30.58rpx 24.98rpx 35.04rpx; background-color: #ffffff; border-radius: 18.75rpx; } .pos_4 { position: absolute; left: 15rpx; right: 16.88rpx; top: 110.63rpx; } .image_2 { width: 65.63rpx; height: 67.5rpx; } .text_3 { color: #818181; line-height: 32.38rpx; font-size: 30rpx; } .group { width: 167.03rpx; } .image_3 { margin-left: 129.53rpx; width: 37.5rpx; height: 37.5rpx; } .font_3 { font-size: 26.25rpx; font-family: FZSongKeBenXiuKaiS-R-GB; line-height: 24.3rpx; color: #8b8b8b; } .text_4 { margin-left: -167.03rpx; color: #ffaaa5; line-height: 25.54rpx; } .text_5 { line-height: 36.34rpx; } .pos_5 { position: absolute; left: 16.18rpx; top: 255.53rpx; } .section_3 { padding: 41.36rpx 26.25rpx 32.81rpx 28.13rpx; background-color: #ffffff; border-radius: 18.75rpx; box-shadow: 0rpx 7.5rpx 7.5rpx #00000040; } .pos_6 { position: absolute; left: 15rpx; right: 16.88rpx; top: 316.88rpx; } .text_6 { margin-left: 3.17rpx; line-height: 27.77rpx; } .text_7 { margin-left: 3.17rpx; margin-top: 33.88rpx; } .divider { margin-top: 38.66rpx; background-color: #a5a5a5; height: 1.88rpx; } .equal-division { align-self: stretch; margin-top: 27.19rpx; } .section_4 { width: 150rpx; margin: 0 15rpx; } .equal-division-item { padding: 14.4rpx 0 19.22rpx; background-color: #f3f3f3; border-radius: 9.38rpx; height: 99.38rpx; } .font_4 { font-size: 30rpx; font-family: FZSongKeBenXiuKaiS-R-GB; line-height: 20.04rpx; color: #8b8b8b; } .group_2 { margin-top: 29.06rpx; padding: 34.69rpx 0 30.94rpx; border-top: solid 1.88rpx #a5a5a5; } .group_1 { margin-right: 3.77rpx; // height: 373.13rpx; } .my_grid { margin: 0 auto; display: grid; grid-template-columns: repeat(5, 1fr); grid-template-rows: repeat(2, 1fr); row-gap: 36rpx; column-gap: 36rpx; overflow-y: auto; height: 250rpx; } .text-wrapper_1 { padding: 39.38rpx 0 39.96rpx; background-color: #ffffff; border-radius: 9.38rpx; width: 105rpx; border: solid 1.88rpx #c35c5d; } .pos_1 { // position: absolute; // left: 0; // top: 0; } .font_5 { font-size: 30rpx; font-family: FZSongKeBenXiuKaiS-R-GB; line-height: 20.04rpx; color: #323232; } .pos_7 { position: absolute; left: 24.11rpx; top: 1020rpx; } .section_5 { padding: 25.43rpx 35.63rpx 34.01rpx; background-color: #ffffff; border-radius: 37.5rpx; box-shadow: 0rpx 7.5rpx 7.5rpx #00000040; } .pos_8 { position: absolute; left: 22.5rpx; right: 22.5rpx; top: 1080.75rpx; } .image_4 { width: 120rpx; height: 133.13rpx; } .text_8 { line-height: 29.18rpx; } .font_6 { font-size: 26.25rpx; font-family: FZSongKeBenXiuKaiS-R-GB; line-height: 24.3rpx; color: #000000; } .text_9 { line-height: 23.79rpx; } .text_10 { line-height: 24.21rpx; } .text_12 { line-height: 25.33rpx; } .group_3 { margin-right: 3.02rpx; } .text_11 { color: #000000; font-size: 22.5rpx; font-family: FZSongKeBenXiuKaiS-R-GB; line-height: 21.09rpx; } .section_6 { padding: 26.25rpx 27.15rpx; background-color: #ffffff; } .pos_9 { position: fixed; bottom: 0; left: 0; right: 0; margin: 0 auto; } .text_13 { line-height: 34.42rpx; } .text_14 { margin-left: -10.14rpx; line-height: 25.05rpx; } .text-wrapper_2 { margin-right: 4.72rpx; padding: 24.38rpx 0 24.49rpx; background-color: #ffb6b9; border-radius: 187.5rpx; width: 241.88rpx; height: 76.88rpx; } .text_15 { color: #ffffff; } @import url(../../../common/css/global.css); </style>