272 lines
7.1 KiB
Vue
272 lines
7.1 KiB
Vue
<template>
|
|
<view class="goods-container">
|
|
<TopNavBar title="商品详情" />
|
|
|
|
<!-- 滚动区域 -->
|
|
<scroll-view class="content-wrapper" scroll-y>
|
|
<ImageSwiper
|
|
:border-radius="0"
|
|
:height="300"
|
|
:images="goodsData.commodityPhotoList"
|
|
thumbnailBottom="36px"
|
|
/>
|
|
|
|
<view class="goods-content">
|
|
<!-- 商品信息组件 -->
|
|
<GoodInfo :goodsData="goodsData" @showCalendar="showCalendar" />
|
|
|
|
<view v-if="goodsData.commodityPurchaseInstruction">
|
|
<ModuleTitle
|
|
:title="goodsData.commodityPurchaseInstruction.templateTitle"
|
|
/>
|
|
<view
|
|
class="use-notice"
|
|
v-for="(moduleItem, index) in goodsData.commodityPurchaseInstruction
|
|
.commodityPurchaseInstructionModuleEntityList"
|
|
:key="index"
|
|
>
|
|
<view class="module-item">
|
|
<view class="module-icon">
|
|
<image :src="moduleItem.moduleIcon" mode="aspectFit" />
|
|
<text class="module-title">{{ moduleItem.moduleTitle }}</text>
|
|
</view>
|
|
<text class="module-desc">{{ moduleItem.moduleContent }}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<zero-markdown-view
|
|
v-else
|
|
:markdown="goodsData.commodityTip"
|
|
:aiMode="true"
|
|
/>
|
|
</view>
|
|
</scroll-view>
|
|
|
|
<!-- 立即抢购 -->
|
|
<view class="footer">
|
|
<view class="left">
|
|
<text class="label">价格:</text>
|
|
<text class="price">{{ goodsData.specificationPrice || 399 }}</text>
|
|
</view>
|
|
<view class="buy-button" @click="showConfirmPopup">立即抢购</view>
|
|
</view>
|
|
|
|
<!-- 商品确认弹窗 -->
|
|
<GoodConfirm
|
|
ref="goodConfirmRef"
|
|
:goodsData="goodsData"
|
|
@confirm="handleConfirmOrder"
|
|
@close="handleCloseConfirm"
|
|
/>
|
|
|
|
<!-- 日历组件 -->
|
|
<Calender
|
|
:visible="calendarVisible"
|
|
:price-data="priceData"
|
|
mode="range"
|
|
@close="handleCalendarClose"
|
|
@range-select="handleDateSelect"
|
|
/>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref } from "vue";
|
|
import { onLoad } from "@dcloudio/uni-app";
|
|
import {
|
|
goodsDetail,
|
|
commodityDailyPriceList,
|
|
orderPay,
|
|
} from "@/request/api/GoodsApi";
|
|
import TopNavBar from "@/components/TopNavBar/index.vue";
|
|
import ImageSwiper from "@/components/ImageSwiper/index.vue";
|
|
import GoodInfo from "./components/GoodInfo/index.vue";
|
|
import ModuleTitle from "@/components/ModuleTitle/index.vue";
|
|
import GoodConfirm from "./components/GoodConfirm/index.vue";
|
|
import Calender from "@/components/Calender/index.vue";
|
|
|
|
const calendarVisible = ref(false);
|
|
const goodsData = ref({});
|
|
const goodConfirmRef = ref(null);
|
|
const selectedDate = ref();
|
|
const priceData = ref([]);
|
|
|
|
// 获取商品详情数据
|
|
const goodsInfo = async (params) => {
|
|
const res = await goodsDetail(params);
|
|
|
|
goodsData.value = res.data;
|
|
|
|
// 判断是酒店类型订单再获取获取商品日价格及库存
|
|
if (goodsData.value.commodityTypeCode === "0") {
|
|
getGoodsDailyPrice({
|
|
commodityId: goodsData.value.commodityId,
|
|
});
|
|
}
|
|
};
|
|
|
|
// 获取商品日价格及库存
|
|
const getGoodsDailyPrice = async (params) => {
|
|
const res = await commodityDailyPriceList(params);
|
|
|
|
priceData.value = res.data;
|
|
};
|
|
|
|
// 显示确认弹窗
|
|
const showConfirmPopup = () => {
|
|
// 当商品类型为"0"时,需要校验入住和离店日期
|
|
if (goodsData.value.commodityTypeCode === "0") {
|
|
// 检查是否已选择日期
|
|
if (
|
|
!selectedDate.value ||
|
|
!selectedDate.value.startDate ||
|
|
!selectedDate.value.endDate
|
|
) {
|
|
calendarVisible.value = true;
|
|
|
|
uni.showToast({
|
|
title: "请先选择入住和离店日期",
|
|
icon: "none",
|
|
duration: 2000,
|
|
});
|
|
return;
|
|
}
|
|
}
|
|
|
|
// 校验通过或非住宿类商品,显示确认弹窗
|
|
goodConfirmRef.value?.showPopup();
|
|
};
|
|
|
|
// 处理确认订单
|
|
const handleConfirmOrder = async (orderData) => {
|
|
console.log("确认订单---1:", orderData);
|
|
const { goodsData } = orderData;
|
|
// 购买的商品id
|
|
const commodityId = goodsData.commodityId;
|
|
// 消费者信息
|
|
const consumerInfoEntityList = orderData.userFormList;
|
|
// 购买数量
|
|
const purchaseAmount = orderData.userFormList.length;
|
|
// 支付方式 0-微信 1-支付宝 2-云闪付
|
|
const payWay = "0";
|
|
// 支付渠道 0-app 1-小程序 2-h5
|
|
const paySource = "1";
|
|
|
|
const params = {
|
|
commodityId,
|
|
purchaseAmount,
|
|
payWay,
|
|
paySource,
|
|
consumerInfoEntityList,
|
|
};
|
|
|
|
//酒店类型添加入住时间、离店时间
|
|
if (goodsData.commodityTypeCode === "0" && selectedDate.value) {
|
|
const { startDate, endDate } = selectedDate.value;
|
|
// 入住时间
|
|
params.checkInData = startDate;
|
|
// 离店时间
|
|
params.checkOutData = endDate;
|
|
}
|
|
|
|
// 购买数量
|
|
|
|
const res = await orderPay(params);
|
|
console.log("确认订单---2:", res);
|
|
|
|
// 检查接口返回数据
|
|
if (!res || !res.data) {
|
|
uni.showToast({
|
|
title: "订单创建失败,请重试",
|
|
icon: "none",
|
|
duration: 2000,
|
|
});
|
|
return;
|
|
}
|
|
|
|
const { data } = res;
|
|
const { nonceStr, packageVal, paySign, signType, timeStamp } = data;
|
|
|
|
// 验证支付参数是否完整
|
|
if (!nonceStr || !packageVal || !paySign || !signType || !timeStamp) {
|
|
console.error("支付参数不完整:", {
|
|
nonceStr: !!nonceStr,
|
|
packageVal: !!packageVal,
|
|
paySign: !!paySign,
|
|
signType: !!signType,
|
|
timeStamp: !!timeStamp,
|
|
});
|
|
uni.showToast({
|
|
title: "支付参数错误,请重试",
|
|
icon: "none",
|
|
duration: 2000,
|
|
});
|
|
return;
|
|
}
|
|
|
|
// 调用微信支付
|
|
uni.requestPayment({
|
|
provider: "wxpay",
|
|
timeStamp: String(timeStamp), // 确保为字符串类型
|
|
nonceStr: String(nonceStr),
|
|
package: String(packageVal), // 确保为字符串类型
|
|
signType: String(signType),
|
|
paySign: String(paySign),
|
|
success: (res) => {
|
|
console.log("支付成功:" + JSON.stringify(res));
|
|
uni.showToast({
|
|
title: "支付成功",
|
|
icon: "success",
|
|
duration: 2000,
|
|
success: () => {
|
|
uni.navigateTo({
|
|
url: "/pages/order/list",
|
|
});
|
|
},
|
|
});
|
|
},
|
|
fail: (err) => {
|
|
console.error("支付失败:" + JSON.stringify(err));
|
|
uni.showToast({
|
|
title: "支付失败,请重试",
|
|
icon: "none",
|
|
duration: 2000,
|
|
});
|
|
},
|
|
});
|
|
};
|
|
|
|
// 处理关闭弹窗
|
|
const handleCloseConfirm = () => {
|
|
console.log("关闭确认弹窗");
|
|
};
|
|
|
|
onLoad(({ commodityId = "1950766939442774018" }) => {
|
|
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,
|
|
};
|
|
|
|
// 日历组件会自动关闭,无需手动设置
|
|
calendarVisible.value = false;
|
|
};
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
@import "./styles/index.scss";
|
|
</style>
|