464 lines
9.8 KiB
Vue
464 lines
9.8 KiB
Vue
<template>
|
|
<view class="app">
|
|
<view class="head-wrapper" :style="{ top: BarHeight + 'px' }">
|
|
<view class="head-menu">
|
|
<Left class="iconfont" @click="returns" />
|
|
<Home class="iconfont" @click="goHome" />
|
|
</view>
|
|
</view>
|
|
<!-- 幻灯片 -->
|
|
<nut-swiper
|
|
:init-page="0"
|
|
:pagination-visible="true"
|
|
pagination-color="#426543"
|
|
auto-play="3000"
|
|
>
|
|
<nut-swiper-item v-for="(itm, idx) in swiperList" :key="idx">
|
|
<img :alt="idx.toString()" :src="itm" />
|
|
</nut-swiper-item>
|
|
</nut-swiper>
|
|
<!-- 标题价格 -->
|
|
<view class="card">
|
|
<view class="header">
|
|
<nut-price
|
|
size="large"
|
|
:price="goodInfo.number as number"
|
|
position="after"
|
|
:symbol="payType === 'jf' ? '积分' : '元'"
|
|
/>
|
|
<view class="stock"> 库存剩余:{{ goodInfo.stock }} </view>
|
|
</view>
|
|
<view class="title">{{ goodInfo.name }}</view>
|
|
<view class="sub">{{ goodInfo.profile }}</view>
|
|
</view>
|
|
<nut-cell title="请选择规格: " is-link @click="openSku"></nut-cell>
|
|
<!-- 产品介绍 -->
|
|
<view class="rich-box">
|
|
<view class="title">产品介绍</view>
|
|
<rich-text
|
|
v-if="goodInfo.details"
|
|
class="rich"
|
|
:nodes="goodInfo.details"
|
|
></rich-text>
|
|
<nut-empty v-else description="暂无产品介绍"></nut-empty>
|
|
</view>
|
|
<view style="height: 9vh"></view>
|
|
<!-- 底部 -->
|
|
<view class="bottom-box">
|
|
<view class="left">
|
|
<view class="icon" @click="toPage('/pages/index/index')">
|
|
<Home />
|
|
<view>首页</view>
|
|
</view>
|
|
<!-- <view-->
|
|
<!-- class="icon"-->
|
|
<!-- v-if="payType === 'jf'"-->
|
|
<!-- @click="toPage('/pages/cart/index')"-->
|
|
<!-- >-->
|
|
<!-- <Cart/>-->
|
|
<!-- <view>购物车</view>-->
|
|
<!-- </view>-->
|
|
<view class="icon" @click="toPage('/pages/kefu/index', 2)">
|
|
<My />
|
|
<view>客服</view>
|
|
</view>
|
|
</view>
|
|
<!-- 占位 -->
|
|
|
|
<view style="width: 80%">
|
|
<!-- <nut-button-->
|
|
<!-- v-if="payType === 'jf'"-->
|
|
<!-- style="margin-right: 10px"-->
|
|
<!-- type="warning"-->
|
|
<!-- @click="add_cart()"-->
|
|
<!-- >加入购物车-->
|
|
<!-- </nut-button>-->
|
|
<nut-button type="primary" block @click="toOrderDetail()"
|
|
>{{ payType === "jf" ? "立即兑换" : "立即购买" }}
|
|
</nut-button>
|
|
</view>
|
|
</view>
|
|
<!-- 规格选择 -->
|
|
<nut-popup
|
|
position="bottom"
|
|
overlay-class="overlay"
|
|
safe-area-inset-bottom
|
|
closeable
|
|
round
|
|
:style="{ zIndex: 1 }"
|
|
v-model:visible="isSkuShow"
|
|
>
|
|
<view class="sku-box">
|
|
<view>商品规格</view>
|
|
<nut-cell-group>
|
|
<nut-cell title="数量:">
|
|
<template v-slot:link>
|
|
<nut-input-number
|
|
v-model="count"
|
|
@change="addCount"
|
|
button-size="30"
|
|
/>
|
|
</template>
|
|
</nut-cell>
|
|
</nut-cell-group>
|
|
</view>
|
|
</nut-popup>
|
|
<!-- <nut-sku
|
|
v-model:visible="isSkuShow"
|
|
:sku="sku"
|
|
:goods="goods"
|
|
@selectSku="selectSku"
|
|
@clickBtnOperate="clickBtnOperate"
|
|
@close="close"
|
|
></nut-sku> -->
|
|
<Pay
|
|
:is-show-pay="isShowPay"
|
|
:pay-type="payType"
|
|
v-model:jfInfo="orderData"
|
|
@closePay="closePay"
|
|
/>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
const statusBarHeight = Taro.getSystemInfoSync()?.statusBarHeight;
|
|
import { ref } from "vue";
|
|
import Taro from "@tarojs/taro";
|
|
import { Home, Left, My } from "@nutui/icons-vue-taro";
|
|
import {
|
|
createActiveOrder,
|
|
createOrder,
|
|
getActiveGoodsDetail,
|
|
getGoodsDetail,
|
|
} from "@/api/goods";
|
|
import Pay from "@/components/Pay.vue";
|
|
|
|
const BarHeight = ref((statusBarHeight as number) + 7);
|
|
|
|
const swiperList = ref([]);
|
|
|
|
const isSkuShow = ref(false);
|
|
|
|
const isShowPay = ref(false);
|
|
|
|
// const sku = ref([]);
|
|
|
|
const payType = ref("");
|
|
|
|
const orderData = ref([]);
|
|
|
|
const count = ref(1);
|
|
|
|
interface GoodInfo {
|
|
gid?: number;
|
|
name?: string;
|
|
number?: number;
|
|
cover?: string;
|
|
details?: string;
|
|
sku?: any[];
|
|
stock?: number;
|
|
profile?: string;
|
|
}
|
|
|
|
const goodInfo = ref<GoodInfo>({});
|
|
|
|
Taro.useLoad((options) => {
|
|
payType.value = options.type === "1" ? "wx" : "jf";
|
|
get_good_detail(options.gid);
|
|
});
|
|
|
|
const get_good_detail = async (gid: string) => {
|
|
try {
|
|
let res: any;
|
|
if (payType.value === "jf") {
|
|
res = await getGoodsDetail({ gid: gid });
|
|
} else {
|
|
res = await getActiveGoodsDetail({ gid: gid });
|
|
}
|
|
goodInfo.value = {
|
|
...res.data.data,
|
|
// details: res.data.data.details.,
|
|
};
|
|
|
|
swiperList.value = res.data.data.rotation.split(",");
|
|
} catch (e) {
|
|
Taro.showToast({
|
|
title: e.msg,
|
|
icon: "none",
|
|
});
|
|
}
|
|
};
|
|
|
|
const addCount = () => {
|
|
if (count.value >= (goodInfo.value.stock as number)) {
|
|
count.value = goodInfo.value.stock as number;
|
|
Taro.showToast({
|
|
title: "库存不足",
|
|
icon: "none",
|
|
});
|
|
return;
|
|
}
|
|
};
|
|
|
|
const returns = () => {
|
|
Taro.navigateBack({
|
|
delta: 1,
|
|
});
|
|
};
|
|
|
|
const goHome = () => {
|
|
Taro.switchTab({
|
|
url: "/pages/index/index",
|
|
});
|
|
};
|
|
|
|
const openSku = () => {
|
|
isSkuShow.value = true;
|
|
};
|
|
|
|
// const selectSku = () => {};
|
|
// const clickBtnOperate = () => {};
|
|
// const close = () => {};
|
|
// const add_cart = async () => {
|
|
// if (isSkuShow.value === false) return openSku();
|
|
// try {
|
|
// await addCart({ gid: goodInfo.value.gid });
|
|
// Taro.showToast({
|
|
// title: "加入购物车成功",
|
|
// icon: "success",
|
|
// duration: 2000,
|
|
// });
|
|
// } catch (e) {
|
|
// Taro.showToast({
|
|
// title: e.msg,
|
|
// icon: "none",
|
|
// });
|
|
// }
|
|
// isSkuShow.value = false;
|
|
// };
|
|
|
|
const toOrderDetail = async () => {
|
|
if (!Taro.getStorageSync("token")) {
|
|
return Taro.showModal({
|
|
title: "提示",
|
|
content: "你还没登录,请先登录",
|
|
cancelText: "先逛逛",
|
|
confirmText: "去登录",
|
|
success: (res) => {
|
|
if (res.confirm) {
|
|
Taro.reLaunch({
|
|
url: "/pages/users/login/index",
|
|
});
|
|
}
|
|
},
|
|
});
|
|
}
|
|
if (isSkuShow.value === false) return openSku();
|
|
// Taro.navigateTo({
|
|
// url: '/pages/goods/order_create/index'
|
|
// })
|
|
try {
|
|
let res: any;
|
|
if (payType.value === "jf") {
|
|
res = await createOrder([
|
|
{
|
|
gid: goodInfo.value.gid,
|
|
count: Number(count.value),
|
|
},
|
|
]);
|
|
} else {
|
|
res = await createActiveOrder({
|
|
gid: goodInfo.value.gid,
|
|
stock: Number(count.value),
|
|
});
|
|
}
|
|
|
|
orderData.value = res?.data?.data;
|
|
|
|
isShowPay.value = true;
|
|
|
|
count.value = 1;
|
|
} catch (e) {
|
|
Taro.showToast({
|
|
title: e.msg,
|
|
icon: "none",
|
|
});
|
|
}
|
|
|
|
isSkuShow.value = false;
|
|
};
|
|
|
|
const closePay = (val: boolean) => {
|
|
isShowPay.value = val;
|
|
orderData.value = [];
|
|
};
|
|
|
|
const toPage = (url: string, type: number = 1) => {
|
|
if (type === 1) {
|
|
Taro.switchTab({
|
|
url: url,
|
|
});
|
|
} else {
|
|
// Taro.navigateTo({
|
|
// url: url,
|
|
// });
|
|
Taro.showToast({
|
|
title: "暂未开放",
|
|
icon: "none",
|
|
});
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
page {
|
|
--nut-cell-box-shadow: none;
|
|
// --nut-cell-padding: 0;
|
|
--nut-cell-title-font: 30px;
|
|
}
|
|
|
|
// sku遮罩
|
|
.overlay {
|
|
background-color: rgba(0, 0, 0, 0.5);
|
|
z-index: 1 !important;
|
|
}
|
|
|
|
.head-wrapper {
|
|
z-index: 999;
|
|
display: flex;
|
|
align-items: center;
|
|
position: fixed;
|
|
left: 30px;
|
|
top: 0;
|
|
height: 114px;
|
|
}
|
|
|
|
.head-menu {
|
|
display: flex;
|
|
align-items: center;
|
|
height: 54px;
|
|
width: 140px;
|
|
background: rgba(0, 0, 0, 0.25);
|
|
border-radius: 27px;
|
|
|
|
.iconfont {
|
|
flex: 1;
|
|
text-align: center;
|
|
color: #fff;
|
|
box-sizing: border-box;
|
|
}
|
|
}
|
|
|
|
.nut-swiper-item img {
|
|
width: 100%;
|
|
height: 730px;
|
|
}
|
|
|
|
.card {
|
|
padding: 30px;
|
|
background-color: #fff;
|
|
|
|
.header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
|
|
.title {
|
|
font-size: 30px;
|
|
font-weight: bold;
|
|
color: #333;
|
|
}
|
|
|
|
.stock {
|
|
color: #8f8f8f;
|
|
}
|
|
}
|
|
|
|
.sub {
|
|
font-size: 24px;
|
|
color: #999;
|
|
}
|
|
}
|
|
|
|
.rich-box {
|
|
background-color: #fff;
|
|
margin-top: 20px;
|
|
width: 100vw;
|
|
box-sizing: border-box;
|
|
text-align: center;
|
|
padding: 15px 0;
|
|
|
|
.title {
|
|
font-size: 30px;
|
|
font-weight: bold;
|
|
color: #333;
|
|
}
|
|
|
|
.rich {
|
|
width: 100%;
|
|
|
|
// img {
|
|
// width: 100%;
|
|
// height: auto;
|
|
// display: block;
|
|
// }
|
|
}
|
|
}
|
|
|
|
.nut-sku {
|
|
// 适配ios底部安全区域
|
|
padding-bottom: constant(safe-area-inset-bottom);
|
|
padding-bottom: env(safe-area-inset-bottom);
|
|
}
|
|
|
|
.sku-box {
|
|
padding: 100px 50px;
|
|
}
|
|
|
|
.bottom-box {
|
|
border-top: 1px solid #e5e5e585;
|
|
position: fixed;
|
|
box-sizing: border-box;
|
|
bottom: 0;
|
|
height: 150rpx;
|
|
background: #fff;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
// 适配ios底部安全区域
|
|
padding-bottom: constant(safe-area-inset-bottom);
|
|
padding-bottom: env(safe-area-inset-bottom);
|
|
z-index: 999;
|
|
width: 100%;
|
|
|
|
.left {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: flex-start;
|
|
width: 300px;
|
|
padding: 0 20px;
|
|
box-sizing: border-box;
|
|
|
|
.icon {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: #333;
|
|
font-size: 25px;
|
|
width: 100px;
|
|
// margin-right: 100px;
|
|
}
|
|
}
|
|
|
|
.icon {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: #333;
|
|
font-size: 25px;
|
|
}
|
|
}
|
|
</style>
|