update scroll-view component syntax in goods, ChatLongAnswer and Discovery pages
237 lines
7.7 KiB
Vue
237 lines
7.7 KiB
Vue
<template>
|
|
<view class="goods-container bg-[#f5f5f5]">
|
|
<TopNavBar :title="navOpacity < 0.5 ? '' : '商品详情'" :background="`rgba(217, 238, 255, ${navOpacity})`"
|
|
:titleColor="navOpacity < 0.5 ? '#ffffff' : '#000000'"
|
|
:backIconColor="navOpacity < 0.5 ? '#ffffff' : '#000000'" />
|
|
|
|
<!-- 滚动区域 -->
|
|
<scroll-view class="content-wrapper" scroll-y @scroll="handleScroll">
|
|
<ImageSwiper :border-radius="0" :height="300" :images="goodsData.commodityPhotoList" thumbnailBottom="42px" />
|
|
|
|
<view class="goods-content">
|
|
<!-- 商品信息组件 -->
|
|
<GoodInfo :goodsData="goodsData" />
|
|
|
|
<!-- 地址区域 -->
|
|
<LocationCard :orderData="goodsData" />
|
|
|
|
<!-- 日期选择区域 -->
|
|
<DateSelector v-if="goodsData.orderType == 0" @showCalendar="showCalendar" :checkInDate="selectedDate.startDate"
|
|
:checkOutDate="selectedDate.endDate" :checkInDay="''" :checkOutDay="''" :nights="selectedDate.totalDays" />
|
|
|
|
<!-- 商品套餐组件 -->
|
|
<GoodPackage
|
|
v-if="goodsData.orderType != 0 && goodsData.commodityPackageConfig && goodsData.commodityPackageConfig.length > 0"
|
|
:goodsData="goodsData" />
|
|
|
|
<!-- 商品设施组件 -->
|
|
<GoodFacility v-if="goodsData.commodityEquipment && goodsData.commodityEquipment.length > 0"
|
|
:goodsData="goodsData" />
|
|
|
|
<!-- 商品详情组件 -->
|
|
<GoodDetail :goodsData="goodsData" />
|
|
</view>
|
|
</scroll-view>
|
|
|
|
<!-- 立即抢购 -->
|
|
<view class="footer border-top">
|
|
<view class="amt text-[20px] font-bold text-[#ff3d60] line-height-28 flex items-center mr-[8px]">
|
|
{{ calculatedTotalPrice }}
|
|
</view>
|
|
|
|
<view class="btn rounded-[10px] flex items-center ml-auto pl-[8px]" @click="navigateToPay(goodsData)">
|
|
<image class="icon" src="https://oss.nianxx.cn/mp/static/version_101/common/btn.png" />
|
|
<text class="text-[16px] font-[500] text-white">立即预定</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 日历组件 -->
|
|
<Calender :visible="calendarVisible" mode="range" :range-require-price="true" :price-data="priceData"
|
|
@close="handleCalendarClose" @range-select="handleDateSelect" />
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref } from "vue";
|
|
import { onLoad } from "@dcloudio/uni-app";
|
|
import { goodsDetail, commodityDailyPriceList } from "@/request/api/GoodsApi";
|
|
import { DateUtils } from "@/utils";
|
|
import TopNavBar from "@/components/TopNavBar/index.vue";
|
|
import ImageSwiper from "@/components/ImageSwiper/index.vue";
|
|
import GoodInfo from "./components/GoodInfo/index.vue";
|
|
import Calender from "@/components/Calender/index.vue";
|
|
import LocationCard from "@/components/LocationCard/index.vue";
|
|
import DateSelector from "./components/DateSelector/index.vue";
|
|
import GoodDetail from "@/components/GoodDetail/index.vue";
|
|
import GoodFacility from "./components/GoodFacility/index.vue";
|
|
import GoodPackage from "./components/GoodPackage/index.vue";
|
|
import { useSelectedDateStore } from "@/store";
|
|
|
|
// 导航栏透明度 - 默认透明,随滚动变为不透明
|
|
const navOpacity = ref(0);
|
|
const calendarVisible = ref(false);
|
|
const goodsData = ref({});
|
|
|
|
// 处理滚动事件
|
|
const handleScroll = (e) => {
|
|
const scrollTop = e.detail.scrollTop;
|
|
// 设置一个阈值,当滚动超过200px时,导航栏完全不透明
|
|
const threshold = 200;
|
|
// 计算透明度,范围从0到1
|
|
navOpacity.value = Math.min(scrollTop / threshold, 1);
|
|
};
|
|
|
|
const selectedDate = ref({
|
|
startDate: DateUtils.formatDate(), // 当天日期
|
|
endDate: DateUtils.formatDate(new Date(Date.now() + 24 * 60 * 60 * 1000)), // 第二天日期
|
|
totalDays: 1,
|
|
});
|
|
|
|
const priceData = ref([])
|
|
|
|
// 计算的总价格
|
|
const calculatedTotalPrice = ref(0);
|
|
|
|
// 获取商品详情数据
|
|
const goodsInfo = async (params) => {
|
|
const res = await goodsDetail(params);
|
|
|
|
goodsData.value = res.data;
|
|
|
|
// 初始化计算价格
|
|
calculatedTotalPrice.value = goodsData.value.specificationPrice || 0;
|
|
|
|
// 判断是酒店类型订单再获取获取商品日价格及库存
|
|
if (goodsData.value.orderType == 0) {
|
|
configGoodsData();
|
|
getGoodsDailyPrice({
|
|
commodityId: goodsData.value.commodityId,
|
|
});
|
|
}
|
|
|
|
if (goodsData.value.commodityStatus !== "1") {
|
|
uni.showModal({
|
|
title: "温馨提示",
|
|
content: "您选的商品暂不可预订,请重新选择。",
|
|
success: (res) => {
|
|
if (res.confirm) {
|
|
uni.navigateBack({ delta: 1 });
|
|
}
|
|
},
|
|
});
|
|
return;
|
|
}
|
|
};
|
|
|
|
const configGoodsData = () => {
|
|
goodsData.value.startDate = selectedDate.value.startDate;
|
|
goodsData.value.endDate = selectedDate.value.endDate;
|
|
goodsData.value.totalDays = selectedDate.value.totalDays;
|
|
goodsData.value.calculatedTotalPrice = calculatedTotalPrice.value;
|
|
};
|
|
|
|
// 获取商品日价格及库存
|
|
const getGoodsDailyPrice = async (params) => {
|
|
const res = await commodityDailyPriceList(params);
|
|
|
|
priceData.value = res.data;
|
|
};
|
|
|
|
const selectedDateStore = useSelectedDateStore();
|
|
onLoad(({ commodityId = "1950766939442774018" }) => {
|
|
// 从store中获取选中的日期
|
|
selectedDate.value = selectedDateStore.selectedDate;
|
|
|
|
goodsInfo({ commodityId });
|
|
});
|
|
|
|
// 显示日历弹窗
|
|
const showCalendar = () => (calendarVisible.value = true);
|
|
|
|
const handleCalendarClose = () => (calendarVisible.value = false);
|
|
|
|
const handleDateSelect = (data) => {
|
|
console.log("选择的日期:", data);
|
|
|
|
// 保存选择的日期范围
|
|
selectedDate.value = {
|
|
startDate: data.startDate,
|
|
endDate: data.endDate,
|
|
totalDays: data.totalDays,
|
|
};
|
|
|
|
selectedDateStore.setData(selectedDate.value);
|
|
|
|
// 根据商品类型计算价格
|
|
if (goodsData.value.orderType == 0) {
|
|
// 酒店类型:计算dateRange总价格,排除最后一天(同一天除外)
|
|
if (data.dateRange && Array.isArray(data.dateRange)) {
|
|
// 获取默认价格作为回退值
|
|
const defaultPrice = Number(goodsData.value.specificationPrice) || 0;
|
|
|
|
// 检查价格是否有效的函数
|
|
const isValidPrice = (price) => {
|
|
return (
|
|
price !== null &&
|
|
price !== undefined &&
|
|
price !== "" &&
|
|
price !== "-" &&
|
|
!isNaN(Number(price)) &&
|
|
Number(price) > 0
|
|
);
|
|
};
|
|
|
|
// 如果是同一天(数组长度为1),使用该天的价格
|
|
if (data.dateRange.length === 1) {
|
|
const dayPrice = data.dateRange[0].price;
|
|
calculatedTotalPrice.value = isValidPrice(dayPrice)
|
|
? Number(dayPrice)
|
|
: defaultPrice;
|
|
console.log(
|
|
"同一天选择,价格:",
|
|
calculatedTotalPrice.value,
|
|
"(原价格:",
|
|
dayPrice,
|
|
")"
|
|
);
|
|
} else {
|
|
// 多天选择,排除最后一天
|
|
const dateRangeExcludingLast = data.dateRange.slice(0, -1);
|
|
calculatedTotalPrice.value = dateRangeExcludingLast.reduce(
|
|
(total, dateItem) => {
|
|
const dayPrice = dateItem.price;
|
|
const priceToAdd = isValidPrice(dayPrice)
|
|
? Number(dayPrice)
|
|
: defaultPrice;
|
|
return total + priceToAdd;
|
|
},
|
|
0
|
|
);
|
|
console.log(
|
|
"酒店类型计算总价格(排除最后一天):",
|
|
calculatedTotalPrice.value
|
|
);
|
|
}
|
|
configGoodsData();
|
|
}
|
|
} else {
|
|
// 非酒店类型:如果没有dateRange,使用默认价格
|
|
calculatedTotalPrice.value = goodsData.value.specificationPrice || 0;
|
|
}
|
|
|
|
// 日历组件会自动关闭,无需手动设置
|
|
calendarVisible.value = false;
|
|
};
|
|
|
|
// 跳转订购
|
|
const navigateToPay = ({ commodityId }) => {
|
|
uni.navigateTo({
|
|
url: `/pages-booking/index?commodityId=${commodityId}`,
|
|
});
|
|
};
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
@import "./styles/index.scss";
|
|
</style>
|