544 lines
14 KiB
Vue
544 lines
14 KiB
Vue
<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: res.data.message
|
||
})
|
||
}
|
||
}
|
||
|
||
|
||
|
||
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 = () => { //关闭弹窗
|
||
timeSlot = ''
|
||
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: #323232;
|
||
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> |