<template> <view class="flex-col page" :style="{ backgroundImage: 'url(' + bkgUrl + ')' }"> <view class="flex-col group"> <view class="flex-row self-stretch group_2"> <image class="image_2" :src="publicPath + productObject.goodImg" /> <view class="flex-col flex-1 self-start ml-15"> <image class="self-end image" @click="close()" :src="workshopUrl + '/component/cha.png'" /> <view class="flex-col items-start self-stretch mt-58"> <text class="text">¥{{ productObject.price }}</text> <text class="font text_2 mt-14">请选择</text> </view> </view> </view> <text class="self-start font_2 text_3 mt-20">当前日期:{{appointmentDateVOList[appIdx].specificDate}}</text> <view class="flex-row justify-between items-center self-stretch mt-20"> <text class="font_2">剩余预约人数:{{ restNumber }}</text> <view class="flex-row items-center group_3" @click="openyyxzTip()"> <image class="shrink-0 image" :src="bookUrl + '/photoProductsOrder/yyxz.png'" /> <text class="font text_4 ml-3">预约须知</text> </view> </view> </view> <view class="flex-row equal-division group_4"> <view class="flex-col items-center section equal-division-item" :style="selectObj[index]" v-for="(item, index) in appointmentDateVOList" :key="index" @click="isSelected(index)"> <text class="font" :style="fontColor[index]">{{ getWeekday(item.specificDate) }}</text> <text class="font_3 mt-12" :style="fontColor[index]">{{item.specificDate.substring(5)}}</text> </view> </view> <view class="flex-col group_5"> <view class="flex-row list_2 my_grid"> <view class="flex-col justify-start items-center text-wrapper" v-for="(item, index) in appointmentDateVOList[appIdx].timePeriodVOList" :key="index" @click="itemIsSelected(index)" :style="itemSelectObj[appIdx][index]"> <text class="font_3 text_5" :style="itemFontColor[appIdx][index]">{{item.timeSlot}}</text> </view> </view> <view style="height: 1.88rpx; background-color: #d9d9d9; margin-top: 30rpx; margin-bottom: 20rpx;"></view> <view class="flex-row justify-between items-center group_7"> <text class="font_2 text_6">数量</text> <view class="flex-row"> <image @click="sub" class="image_3" :src="workshopUrl + '/component/sub.png'" /> <view class="flex-col justify-start items-center text-wrapper_2 ml-4"> <text class="font_3 text_7">{{cnt}}</text> </view> <image @click="add" class="image_4 ml-4" :src="workshopUrl + '/component/add.png'" /> </view> </view> </view> <view class="flex-col justify-start items-center text-wrapper_3" @click="selectStatus()"><text class="font text_8">{{ btnText }}</text></view> </view> <uni-popup ref="tip" :animation="false"> <view class="pop"> <tipVue></tipVue> </view> </uni-popup> </template> <script setup> import tipVue from './tip.vue'; import {nextTick, onMounted, onUnmounted, ref} from 'vue' import emitter from '../../../utils/emitter'; import { baseUrl } from '../../../api/request'; import { workshopUrl } from '../../../common/globalImagesUrl'; import { dealResult } from '../../../common/globalFunction'; import { onLoad } from "@dcloudio/uni-app"; import { getFonts } from '../../../common/globalFont'; import { bookUrl } from '../../../common/globalImagesUrl'; import { publicPath } from '../../../common/globalImagesUrl'; const bkgUrl = ref(bookUrl + '/component/bkg.png') let selectObj = ref([]) let fontColor = ref([]) let itemSelectObj = ref([]) let itemFontColor = ref([]) const cookie = wx.getStorageSync("cookie") //请求头 const appIdx = ref(0) const tIdx = ref(0) const cnt = ref(1) const productObject = ref() const appointmentDateVOList = ref([]) let appointmentDate = '' let timeSlot = '' const restNumber = ref('请选择时间段') let countMap = new Map() const getGoodDataHandler = (val) => { productObject.value = val appointmentDateVOList.value = val.appointmentDateVOList selectObj.value = new Array(appointmentDateVOList.value.length).fill(null).map(() => ({ backgroundColor: '#fff', borderColor: '#C35C5D' })); fontColor.value = new Array(appointmentDateVOList.value.length).fill(null).map(() => ({ color: '#323233' })) selectObj.value[0] = {backgroundColor: '#FBDEDF', borderColor: '#FBDEDF'} fontColor.value[0] = {color: '#C35C5D'} for (var i = 0; i < appointmentDateVOList.value.length; i ++ ) { var col = appointmentDateVOList.value[i].timePeriodVOList.length itemSelectObj.value[i] = new Array(col).fill(null).map(() => ({ backgroundColor: '#F3F3F3' })) itemFontColor.value[i] = new Array(col).fill(null).map(() => ({ color: '#323233' })) } } const getBookingNumberMapHandler = (val) => { countMap = val console.log("val==============>", val) appointmentDate = appointmentDateVOList.value[appIdx.value].specificDate; } const countHandler = (val) => { nowSelected.value = val console.log('现在选择的是---->',nowSelected.value); statusChange() //更改按钮文字 } const closeyyxzTipHandler = () => { nextTick(() => { if (tip.value) { tip.value.close() } }) } onLoad(() => { getFonts() }) onMounted(() => { emitter.on('closeyyxzTip', closeyyxzTipHandler) emitter.on('getGoodData', getGoodDataHandler) emitter.on('getBookingNumberMap', getBookingNumberMapHandler) emitter.on('count', countHandler) }) onUnmounted(() => { emitter.off('closeyyxzTip', closeyyxzTipHandler) emitter.off('getGoodData', getGoodDataHandler) emitter.off('getBookingNumberMap', getBookingNumberMapHandler) emitter.off('count', countHandler) }) const addCart = async () =>{ //加入购物车方法 console.log('日期--->',appointmentDate,'时间段--->',timeSlot,'数量--->',cnt.value,'商品id---->',productObject.value.id); if(appointmentDate === '' || timeSlot === '' ) { uni.showToast({ icon: 'error', title: "字段不能为空" }) return; } const res = await uni.request({ url: baseUrl + '/cartExperience/add', method: 'POST', header: { cookie }, data: { goodId : productObject.value.id, reservationDate : appointmentDate, timeSlot : timeSlot, quantity : cnt.value } }) if (!dealResult(res)) return console.log('加入购物车结果',res); if(res.data.code === 1) { uni.showToast({ icon: 'success', title: "加入购物车成功" }) close() //关闭弹窗 } else { uni.showToast({ icon: 'error', title: "服务错误" }) } } const tip = ref(null) const openyyxzTip = () => { tip.value.open() } const add = () => { //添加商品方法 if (restNumber.value === '请选择时间段') { uni.showToast({ title: '请选择时间段', icon: 'error' }) return ; } if (cnt.value < Number(restNumber.value)) { cnt.value ++ } } const sub = () => { //减少商品方法 if (cnt.value > 1) { cnt.value -- } } const close = () => { //关闭弹窗 emitter.emit('closeTimeDialog') } const isSelected = (index) => { //选择预约日期方法 if (appIdx.value === index) return appIdx.value = index restNumber.value = '请选择时间段' appointmentDate = appointmentDateVOList.value[appIdx.value].specificDate; timeSlot = '' console.log('appointmentDate===================================>', appointmentDate) for (var i = 0; i < appointmentDateVOList.value.length; i ++ ) { if (i == index) { selectObj.value[i].backgroundColor = '#FBDEDF' selectObj.value[i].borderColor = '#FBDEDF' fontColor.value[i].color = '#C35C5D' } else { selectObj.value[i].backgroundColor = '#fff' selectObj.value[i].borderColor = '#C35C5D' fontColor.value[i].color = '#323233' } } var col = appointmentDateVOList.value[appIdx.value].timePeriodVOList.length for (var i = 0; i < col; i ++ ) { itemSelectObj.value[appIdx.value][i].backgroundColor = '#F3F3F3' itemFontColor.value[appIdx.value][i].color = '#323233' } } const itemIsSelected = (index) => { //选择时间段方法 timeSlot = appointmentDateVOList.value[appIdx.value].timePeriodVOList[index].timeSlot restNumber.value = countMap[appointmentDate + '&' + timeSlot] console.log('timeSlot====================================>', timeSlot) var col = appointmentDateVOList.value[appIdx.value].timePeriodVOList.length for (var i = 0; i < col; i ++ ) { if (i == index) { itemSelectObj.value[appIdx.value][i].backgroundColor = '#FBDEDF' itemFontColor.value[appIdx.value][i].color = '#C35C5D' } else { itemSelectObj.value[appIdx.value][i].backgroundColor = '#F3F3F3' itemFontColor.value[appIdx.value][i].color = '#323233' } } } const nowSelected = ref(0) //区别于加入购物车弹窗和立即预约弹窗 const btnText = ref('加入购物车') const statusChange = () => { if(nowSelected.value === 2) { btnText.value = '立即预约' } else { btnText.value = '加入购物车' } } const selectStatus = () => { if(btnText.value === '加入购物车') { addCart() } else { goToBook() } } const goToBook = async () => { //去预约方法 console.log('日期--->',appointmentDate,'时间段--->',timeSlot,'数量--->',cnt.value,'商品id---->',productObject.value.id); if(appointmentDate === '' || timeSlot === '' ) { uni.showToast({ icon: 'error', title: "字段不能为空" }) return; } console.log('id---------------------------->',productObject.value.id); const res = await uni.request({ url: baseUrl + '/goods/checkServiceGood', method: 'POST', header: { cookie }, data: { goodId: productObject.value.id, reservationDate: appointmentDate, timeSlot: timeSlot, quantity: cnt.value } }) console.log(res) if (!dealResult(res)) return ; console.log('==============================>', productObject.value) uni.navigateTo({ //跳转到待支付页面 //商品信息+数量 url: '/pages/order/singleServiceWait/singleServiceWait?id=' + productObject.value.id + '&cnt=' + cnt.value + '&rest=' + restNumber.value + '&appointmentDate=' + appointmentDate + '&timeSlot=' + timeSlot }) } function getWeekday(dateStr) { const date = new Date(dateStr); const weekdays = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]; return weekdays[date.getDay()]; } </script> <style lang="scss" scoped> .ml-15 { margin-left: 28.13rpx; } .ml-3 { margin-left: 5.63rpx; } .mt-91 { margin-top: 170.63rpx; } .page { padding: 0 20.63rpx 48.75rpx; background-color: #ffffff; border-radius: 37.5rpx 37.5rpx 0rpx 0rpx; width: 100%; overflow-y: auto; overflow-x: hidden; height: 100%; } .group { padding: 30rpx 0 22.5rpx; border-bottom: solid 1.88rpx #d9d9d9; } .group_2 { padding-left: 18.75rpx; padding-right: 16.88rpx; } .image_2 { margin-top: 7.5rpx; border-radius: 5.63rpx; width: 221.25rpx; height: 232.5rpx; } .image { width: 37.5rpx; height: 37.5rpx; } .text { margin-left: 6.92rpx; color: #c35c5d; font-size: 37.5rpx; font-family: FangZhengFonts; line-height: 27.52rpx; } .font { font-size: 26.25rpx; font-family: FangZhengFonts; line-height: 23.94rpx; color: #323233; } .text_2 { line-height: 24.21rpx; } .font_2 { font-size: 30rpx; font-family: FangZhengFonts; line-height: 27.71rpx; color: #323233; } .text_3 { margin-left: 3.45rpx; line-height: 27.86rpx; } .group_3 { margin-right: 20.57rpx; } .text_4 { color: #000000; line-height: 24.23rpx; } .equal-division { margin-top: 43.13rpx; } .group_4 { border-bottom: solid 1.88rpx #d9d9d9; padding-bottom: 40rpx; -webkit-overflow-scrolling: touch; /* 使滚动更加平滑 */ margin: 30rpx auto; width: 100%; overflow-x: auto; } .group_4::-webkit-scrollbar { display: none; /* 隐藏滚动条 */ } .section { width: 150rpx; margin: 0 15rpx; } .equal-division-item { padding: 17.51rpx 0 20.49rpx; background-color: #ffffff; border-radius: 5.63rpx; height: 106.88rpx; border: solid 1.88rpx #c35c5d; } .font_3 { font-size: 26.25rpx; font-family: FangZhengFonts; line-height: 19.29rpx; color: #323233; } .group_5 { padding: 0 0 58.13rpx; } .list_2 { margin-right: 3.77rpx; // border-bottom: solid 1.88rpx #d9d9d9; } .list_2::-webkit-scrollbar { display: none; /* 隐藏滚动条 */ } .my_grid{ margin: 0 auto; display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr); row-gap: 20rpx; column-gap: 40rpx; overflow-y: auto; height: 350rpx; } .text-wrapper { padding: 39.09rpx 0 35.25rpx; background-color: #f3f3f3; border-radius: 5.63rpx; height: 93.75rpx; width: 200rpx; margin-bottom: 20rpx; } .text_5 { line-height: 19.41rpx; } .group_7 { padding: 28.13rpx 3.75rpx 0 11.32rpx; position: fixed; bottom: 180rpx; left: 30rpx; right: 30rpx; } .text_6 { color: #323232; } .image_3 { border-radius: 9.38rpx 0rpx 0rpx 9.38rpx; width: 46.88rpx; height: 46.88rpx; } .text-wrapper_2 { padding: 15.02rpx 0 13.13rpx; background-color: #f3f3f3; width: 46.88rpx; height: 46.88rpx; } .text_7 { color: #323232; line-height: 18.73rpx; } .image_4 { border-radius: 0rpx 9.38rpx 9.38rpx 0rpx; width: 46.88rpx; height: 46.88rpx; } .text-wrapper_3 { width: 600rpx; padding: 24.82rpx 0 27.84rpx; background-color: #fbdedf; border-radius: 37.5rpx; position: fixed; bottom: 50rpx; left: 0; right: 0; margin: 0 auto; } .text_8 { color: #c35c5d; line-height: 24.21rpx; } @import url(../../../common/css/global.css); </style>