Files
YGChatCS/src/pages-booking/index.vue
2025-10-27 21:19:09 +08:00

210 lines
6.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="booking h-screen flex flex-col">
<TopNavBar
titleAlign="center"
backgroundColor="#D9EEFF"
backIconColor="#000"
:shadow="false"
>
<template #title>
{{ GOODS_TYPE[orderData.commodityTypeCode] }}
</template>
</TopNavBar>
<view class="booking-content flex-full border-box p-12">
<!-- 预约内容 -->
<view class="border-box bg-white p-12 rounded-12 mb-12">
<!-- 酒店类型入住离店日期部分 -->
<DateRangeSection
v-if="orderData.commodityTypeCode === '0'"
:selectedDate="selectedDate"
:showBtn="true"
@click="navigateToDetail(orderData)"
/>
<view class="font-size-16 font-500 color-000 line-height-24 ellipsis-1">
{{ orderData.commodityName }}
</view>
<view class="border-box border-bottom">
<view class="font-size-12 color-99A0AE line-height-16 pb-12">
{{ orderData.commodityDescription }}
</view>
<!-- 权益部分 -->
<view class="flex flex-items-center mb-8">
<text
class="bg-F7F7F7 border-box rounded-4 font-size-11 color-525866 mr-4 pt-4 pb-4 pl-6 pr-6"
v-for="(item, index) in orderData.commodityFacilityList"
:key="index"
>
{{ item }}
</text>
</view>
</view>
<view
class="border-box flex flex-items-center flex-justify-between pt-12"
>
<text class="font-size-12 color-525866 line-height-18"
>取消政策及说明</text
>
<view class="flex flex-items-center">
<text
class="font-size-12 color-2D91FF line-height-16"
@click="refundVisible = true"
>取消政策</text
>
<uni-icons type="right" size="15" color="#99A0AE" />
</view>
</view>
</view>
<!-- 非酒店类型 -->
<ContactSection
v-if="orderData.commodityTypeCode !== '0'"
v-model="quantity"
:userFormList="userFormList"
/>
<!-- 酒店类型 -->
<UserSection
v-if="orderData.commodityTypeCode === '0'"
v-model="quantity"
:userFormList="userFormList"
/>
</view>
<!-- 底部 -->
<FooterSection
v-model="quantity"
:selectedDate="selectedDate"
:orderData="orderData"
@detailClick="detailVisible = true"
@payClick="handlePayClick"
/>
<!-- 取消政策弹窗 -->
<RefundPopup v-model="refundVisible" :orderData="orderData" />
<!-- 明细弹窗 -->
<DetailPopup v-model="detailVisible" :orderData="orderData" />
</view>
</template>
<script setup>
import { ref, watch, nextTick } from "vue";
import { onLoad, onShow } from "@dcloudio/uni-app";
import TopNavBar from "@/components/TopNavBar/index.vue";
import DateRangeSection from "@/components/DateRangeSection/index.vue";
import ContactSection from "./components/ConactSection/index.vue";
import UserSection from "./components/UserSection/index.vue";
import RefundPopup from "@/components/RefundPopup/index.vue";
import DetailPopup from "@/components/DetailPopup/index.vue";
import FooterSection from "./components/FooterSection/index.vue";
import { goodsDetail } from "@/request/api/GoodsApi";
import { useSelectedDateStore } from "@/store";
import { GOODS_TYPE } from "@/constant/type";
import { PhoneUtils } from "@/utils";
const refundVisible = ref(false);
const detailVisible = ref(false);
const orderData = ref({});
const selectedDate = ref({
startDate: "",
endDate: "",
totalDays: 1,
});
const quantity = ref(1);
// 工具函数
const createEmptyUserForm = () => ({ visitorName: "", contactPhone: "" });
const userFormList = ref([createEmptyUserForm()]);
const isDeleting = ref(false); // 标志位防止删除时watch冲突
// 监听 quantity 变化,动态调整 userFormList
watch(
quantity,
async (newQuantity) => {
// 非酒店类型,不处理
if (orderData.value.commodityTypeCode !== "0") {
return;
}
// 如果正在执行删除操作跳过watch逻辑
if (isDeleting.value) {
isDeleting.value = false;
return;
}
const currentLength = userFormList.value.length;
if (newQuantity > currentLength) {
// 数量增加,添加新的表单项
const newForms = Array.from({ length: newQuantity - currentLength }, () =>
createEmptyUserForm()
);
userFormList.value.push(...newForms);
} else if (newQuantity < currentLength) {
// 数量减少,删除多余的表单项
userFormList.value.splice(newQuantity);
}
// 等待DOM更新完成
await nextTick();
},
{ immediate: false }
);
onLoad((options) => {
const { commodityId } = options;
getGoodsDetail(commodityId);
});
onShow(() => {
const selectedDateStore = useSelectedDateStore();
selectedDate.value.startDate = selectedDateStore.selectedDate.startDate;
selectedDate.value.endDate = selectedDateStore.selectedDate.endDate;
selectedDate.value.totalDays = selectedDateStore.selectedDate.totalDays;
});
const getGoodsDetail = async (commodityId) => {
const res = await goodsDetail({ commodityId });
console.log("获取商品详情", res);
orderData.value = res.data;
// 取commodityFacilityList前3个
orderData.value.commodityFacilityList = res.data.commodityFacilityList.slice(
0,
3
);
};
// 跳转商品详情
const navigateToDetail = ({ commodityId }) => {
uni.navigateTo({
url: `/pages/goods/index?commodityId=${commodityId}`,
});
};
// 处理支付点击事件
const handlePayClick = (orderData) => {
console.log("处理支付点击事件", userFormList.value);
// 校验手机号
if (!PhoneUtils.validatePhone(userFormList.value[0].contactPhone)) {
uni.showToast({
title: "请输入正确的手机号",
icon: "none",
});
return;
}
};
</script>
<style scoped lang="scss">
@import "./styles/index.scss";
</style>