You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
high-mini/pages/goods/goods.vue

1151 lines
22 KiB

<template>
<view>
<!-- 底部菜单 -->
<view class="footer">
<button v-if="user.phone == null" class="width100 fotct btnfot" open-type="getPhoneNumber"
@getphonenumber="getPhoneNumber">
立即购买
</button>
<button v-else class="width100 fotct btnfot" @click="buy">
立即购买
</button>
</view>
<!-- 商品主图轮播 -->
<view class="swiper-box">
<swiper circular="true" autoplay="true" @change="swiperChange">
<swiper-item v-for="swiper in swiperList" :key="swiper.id">
<image :src="imageUrl+swiper"></image>
</swiper-item>
</swiper>
<view class="indicator">{{currentSwiper+1}}/{{swiperList.length}}</view>
</view>
<!-- 标题 价格 -->
<view class="info-box goods-info">
<view class="price">{{goodsData[0].discountPrice}} <text class="zprice font14 fcor666"
v-if="goodsData[0].discountPrice !=goodsData[0].salesPrice">{{goodsData[0].salesPrice}}</text>
</view>
<view class="title">
{{goodsData[0].couponName}}
</view>
<view class="mart10 width100">
<view class="font14 fcor666">库存 : {{goodsData[0].stockCount}}</view>
</view>
</view>
<!-- 服务-规则选择 -->
<view class="info-box spec" @click="jumpstore">
<view class="row">
<view class="text">门店列表</view>
<!-- <view class="content"><view class="serviceitem" v-for="(item,index) in goodsData.service" :key="index">{{item.name}}</view></view> -->
<view class="arrow">
<view class="icon xiangyou"></view>
</view>
</view>
</view>
<!-- 赠送 -->
<view class="description" v-if="goodsData[0].handselCouponList != '' ">
<view class="title"> 赠送卡券 </view>
<view class="product-list mart15">
<view class="product" v-for="product in goodsData[0].handselCouponList" :key="product.id"
@tap="toGoods(product.id)">
<image mode="widthFix" :src="imageUrl+product.highCouponModel.couponImg"></image>
<view class="name">{{ product.highCouponModel.couponName }}</view>
<view class="info">
<view class="price">{{ product.highCouponModel.discountPrice}}</view>
<view class="slogan" v-if="product.highCouponModel.discountPrice !== product.highCouponModel.salesPrice">
{{ product.highCouponModel.salesPrice}}</view>
</view>
</view>
</view>
</view>
<!-- 详情 -->
<view class="description">
<view class="title"> 商品详情 </view>
<view class="content marb65">
<image class="width100" :src="imageUrl+goodsData[0].couponDesc">
</image>
</view>
</view>
<authorize></authorize>
</view>
</template>
<script>
import {
getCouponById,
GetPhoneNumber,
addOrder
} from "../../Utils/Api.js";
import authorize from '../../components/Authorize.vue'
let app = getApp()
export default {
components: {
authorize
},
data() {
return {
//控制渐变标题栏的参数
beforeHeaderzIndex: 11, //层级
afterHeaderzIndex: 10, //层级
beforeHeaderOpacity: 1, //不透明度
afterHeaderOpacity: 0, //不透明度
//是否显示返回按钮
// #ifndef MP
showBack: true,
// #endif
//轮播主图数据
swiperList: [],
//轮播图下标
currentSwiper: 0,
anchorlist: [], //导航条锚点
selectAnchor: 0, //选中锚点
serviceClass: '', //服务弹窗css类,控制开关动画
specClass: '', //规格弹窗css类,控制开关动画
shareClass: '', //分享弹窗css类,控制开关动画
// 商品信息
goodsData: "",
selectSpec: null, //选中规格
isKeep: false, //收藏
//商品描述html
desid: '',
imageUrl: app.globalData.imgUrl,
user: ''
};
},
onLoad(option) {
this.desid = option.id;
this.user = app.globalData.userInfo;
this.getCouponById();
// #ifdef MP
//小程序隐藏返回按钮
this.showBack = false;
// #endif
//option为object类型,会序列化上个页面传递的参数
},
onReady() {
this.calcAnchor(); //计算锚点高度,页面数据是ajax加载时,请把此行放在数据渲染完成事件中执行以保证高度计算正确
},
onPageScroll(e) {
//锚点切换
this.selectAnchor = e.scrollTop >= this.anchorlist[2].top ? 2 : e.scrollTop >= this.anchorlist[1].top ? 1 : 0;
//导航栏渐变
let tmpY = 375;
e.scrollTop = e.scrollTop > tmpY ? 375 : e.scrollTop;
this.afterHeaderOpacity = e.scrollTop * (1 / tmpY);
this.beforeHeaderOpacity = 1 - this.afterHeaderOpacity;
//切换层级
this.beforeHeaderzIndex = e.scrollTop > 0 ? 10 : 11;
this.afterHeaderzIndex = e.scrollTop > 0 ? 11 : 10;
},
//上拉加载,需要自己在page.json文件中配置"onReachBottomDistance"
onReachBottom() {
// uni.showToast({ title: '触发上拉加载' });
},
mounted() {
},
methods: {
//卡券详情
getCouponById() {
uni.showLoading({
title:'加载中...'
})
uni.showLoading({})
let params = {
couponId: this.desid
}
getCouponById(params).then(res => {
if (res.return_code == '000000') {
this.goodsData = [res.return_data];
this.swiperList = res.return_data.couponCarouselImg.split(',')
uni.hideLoading()
} else {
uni.hideLoading()
}
})
},
/**
* 跳转门店详情
*/
jumpstore() {
uni.navigateTo({
url: './store-list/store-list?id=' + this.desid
})
},
//轮播图指示器
swiperChange(event) {
this.currentSwiper = event.detail.current;
},
//消息列表
toMsg() {
uni.navigateTo({
url: '../msg/msg'
})
},
// 客服
toChat() {
// uni.navigateTo({
// url:"../msg/chat/chat?name=客服008"
// })
},
// 分享
share() {
this.shareClass = 'show';
},
hideShare() {
this.shareClass = 'hide';
setTimeout(() => {
this.shareClass = 'none';
}, 150);
},
//收藏
keep() {
this.isKeep = this.isKeep ? false : true;
},
// 加入购物车
joinCart() {
if (this.selectSpec == null) {
return this.showSpec(() => {
uni.showToast({
title: "已加入购物车"
});
});
}
uni.showToast({
title: "已加入购物车"
});
},
//立即购买
getPhoneNumber(PhoneNumber) {
let params = {
openId: app.globalData.openId,
iv: PhoneNumber.detail.iv,
encryptedData: PhoneNumber.detail.encryptedData
}
GetPhoneNumber(params).then(res => {
if (res.return_code == '000000') {
app.globalData.userInfo = res.return_data
.object
.highUser;
uni.setStorage({
key: "user",
data: res.return_data
.object
.highUser
})
this.buy();
}
});
},
buy() {
uni.showLoading({
title: '正在提交订单...'
})
let goods = {
"highChildOrderList": [{
"goodsType": 1,
"goodsId": this.goodsData[0].id,
"saleCount": 1
}]
}
addOrder(goods).then(res => {
if (res.return_code == '000000') {
uni.hideLoading();
uni.redirectTo({
url: "../pay/payment/payment?amount=" + this.goodsData[0].discountPrice +
'&paytype=' + this.goodsData[0].payType + '&orderId=' + res.return_data.id
})
} else {
uni.showToast({
title: res.return_msg,
icon: 'none'
});
}
})
},
//商品评论
toRatings() {
uni.navigateTo({
url: 'ratings/ratings'
})
},
//跳转评论列表
showComments(goodsid) {
},
//选择规格
setSelectSpec(index) {
this.selectSpec = index;
},
//减少数量
sub() {
if (this.goodsData.number <= 1) {
return;
}
this.goodsData.number--;
},
//增加数量
add() {
this.goodsData.number++;
},
//跳转锚点
toAnchor(index) {
this.selectAnchor = index;
uni.pageScrollTo({
scrollTop: this.anchorlist[index].top,
duration: 200
});
},
//计算锚点高度
calcAnchor() {
this.anchorlist = [{
name: '主图',
top: 0
},
{
name: '评价',
top: 0
},
{
name: '详情',
top: 0
}
]
let commentsView = uni.createSelectorQuery().select("#comments");
commentsView.boundingClientRect((data) => {
let statusbarHeight = 0;
//APP内还要计算状态栏高度
// #ifdef APP-PLUS
statusbarHeight = plus.navigator.getStatusbarHeight()
// #endif
let headerHeight = uni.upx2px(100);
this.anchorlist[1].top = data.top - headerHeight - statusbarHeight;
this.anchorlist[2].top = data.bottom - headerHeight - statusbarHeight;
}).exec();
},
//返回上一页
back() {
uni.navigateBack();
},
//服务弹窗
showService() {
console.log('show');
this.serviceClass = 'show';
},
//关闭服务弹窗
hideService() {
this.serviceClass = 'hide';
setTimeout(() => {
this.serviceClass = 'none';
}, 200);
},
//规格弹窗
showSpec(fun) {
console.log('show');
this.specClass = 'show';
this.specCallback = fun;
},
specCallback() {
return;
},
//关闭规格弹窗
hideSpec() {
this.specClass = 'hide';
//回调
this.selectSpec && this.specCallback && this.specCallback();
this.specCallback = false;
setTimeout(() => {
this.specClass = 'none';
}, 200);
},
discard() {
//丢弃
}
}
};
</script>
<style lang="scss">
page {
background-color: #f8f8f8;
}
.product-list {
width: 92%;
padding: 0 4% 3vw 4%;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.product {
width: 48%;
border-radius: 20upx;
background-color: #fff;
margin: 0 0 15upx 0;
box-shadow: 0upx 5upx 25upx rgba(0, 0, 0, 0.1);
image {
width: 100%;
border-radius: 20upx 20upx 0 0;
}
.name {
width: 92%;
padding: 10upx 4%;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
text-align: justify;
overflow: hidden;
font-size: 30upx;
}
.info {
display: flex;
justify-content: space-between;
align-items: flex-end;
width: 92%;
padding: 10upx 4% 10upx 4%;
.price {
color: #e65339;
font-size: 30upx;
font-weight: 600;
}
.slogan {
color: #807c87;
font-size: 24upx;
text-decoration: line-through;
margin-right: 50px;
}
}
}
}
@keyframes showPopup {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes hidePopup {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@keyframes showLayer {
0% {
transform: translateY(0);
}
100% {
transform: translateY(-100%);
}
}
@keyframes hideLayer {
0% {
transform: translateY(-100%);
}
100% {
transform: translateY(0);
}
}
.icon {
font-size: 26upx;
}
.status {
width: 100%;
height: 0;
position: fixed;
z-index: 10;
top: 0;
/* #ifdef APP-PLUS */
height: var(--status-bar-height); //覆盖样式
/* #endif */
background-color: #f1f1f1;
transition: opacity 0.05s linear;
}
.header {
width: 100%;
height: 100upx;
display: flex;
align-items: center;
position: fixed;
top: 0;
z-index: 10;
/* #ifdef APP-PLUS */
top: var(--status-bar-height);
/* #endif */
.before,
.after {
width: 92%;
padding: 0 4%;
height: 100upx;
display: flex;
align-items: center;
position: fixed;
top: 0;
/* #ifdef APP-PLUS */
top: var(--status-bar-height);
/* #endif */
transition: opacity 0.05s linear;
.back {
width: 125upx;
height: 60upx;
flex-shrink: 0;
.icon {
margin-left: -10%;
width: 60upx;
height: 60upx;
display: flex;
align-items: center;
justify-content: center;
font-size: 42upx;
}
}
.middle {
width: 100%;
}
.icon-btn {
width: 125upx;
height: 60upx;
flex-shrink: 0;
display: flex;
.icon {
&:first-child {
margin-right: 5upx;
}
width: 60upx;
height: 60upx;
display: flex;
justify-content: center;
align-items: center;
font-size: 42upx;
}
}
}
.before {
.back {
.icon {
color: #fff;
background-color: rgba(0, 0, 0, 0.2);
border-radius: 100%;
}
}
.icon-btn {
.icon {
color: #fff;
background-color: rgba(0, 0, 0, 0.2);
border-radius: 100%;
}
}
}
.after {
background-color: #f1f1f1;
.back {
.icon {
color: #666;
}
}
.icon-btn {
.icon {
color: #666;
}
}
.middle {
font-size: 32upx;
height: 90upx;
display: flex;
justify-content: center;
align-items: center;
padding: 0 7%;
view {
width: (100%/3);
padding: 0 3%;
margin: 0 3%;
display: flex;
justify-content: center;
align-items: center;
&.on {
margin-bottom: -4upx;
color: #f47952;
border-bottom: solid 4upx #f47952;
}
}
}
}
}
.swiper-box {
position: relative;
width: 100%;
height: 100vw;
swiper {
width: 100%;
height: 100vw;
swiper-item {
image {
width: 100%;
height: 100vw;
}
}
}
.indicator {
display: flex;
justify-content: center;
align-items: center;
padding: 0 25upx;
height: 40upx;
border-radius: 40upx;
font-size: 22upx;
position: absolute;
bottom: 20upx;
right: 20upx;
color: #fff;
background-color: rgba(0, 0, 0, 0.2);
}
}
.info-box {
width: 92%;
padding: 20upx 4%;
background-color: #fff;
margin-bottom: 20upx;
}
.goods-info {
.price {
font-size: 46upx;
font-weight: 600;
color: #f47925;
.zprice {
padding-left: 10px;
text-decoration: line-through;
}
}
.title {
font-size: 30upx;
}
}
.spec {
.row {
width: 100%;
display: flex;
align-items: center;
margin: 5px 0 5px 0;
.text {
font-size: 24upx;
color: #a2a2a2;
margin-right: 20upx;
}
.content {
font-size: 28upx;
display: flex;
flex-wrap: wrap;
.serviceitem {
margin-right: 10upx;
}
.sp {
width: 100%;
display: flex;
view {
background-color: #f6f6f6;
padding: 5upx 10upx;
color: #999;
margin-right: 10upx;
font-size: 20upx;
border-radius: 5upx;
&.on {
border: solid 1upx #f47952;
padding: 4upx 8upx;
}
}
}
}
.arrow {
position: absolute;
right: 4%;
.icon {
color: #ccc;
}
}
}
}
.comments {
.row {
width: 100%;
height: 40upx;
display: flex;
align-items: center;
margin: 0 0 30upx 0;
.text {
font-size: 30upx;
}
.arrow {
font-size: 28upx;
position: absolute;
right: 4%;
color: #17e6a1;
.show {
display: flex;
align-items: center;
.icon {
color: #17e6a1;
}
}
}
}
.comment {
width: 100%;
.user-info {
width: 100%;
height: 40upx;
display: flex;
align-items: center;
.face {
width: 40upx;
height: 40upx;
margin-right: 8upx;
image {
width: 40upx;
height: 40upx;
border-radius: 100%;
}
}
.username {
font-size: 24upx;
color: #999;
}
}
.content {
margin-top: 10upx;
font-size: 26upx;
}
}
}
.description {
.title {
width: 100%;
height: 80upx;
display: flex;
justify-content: center;
align-items: center;
font-size: 26upx;
color: #999;
}
}
.footer {
position: fixed;
bottom: 0upx;
width: 100%;
height: 99upx;
color: #FFFFFF;
border-top: solid 1upx #eee;
background-color: red;
z-index: 2;
display: flex;
justify-content: space-between;
align-items: center;
.btnfot {
text-align: center;
padding: 0;
border-radius: 0;
height: 48px;
background-color: red;
color: #ffffff;
}
.icons {
display: flex;
height: 80upx;
margin-left: -4%;
.box {
width: 80upx;
height: 80upx;
display: flex;
justify-content: center;
flex-wrap: wrap;
.icon {
font-size: 40upx;
color: #828282;
}
.text {
display: flex;
justify-content: center;
width: 100%;
font-size: 22upx;
color: #666;
}
}
}
.btn {
height: 80upx;
border-radius: 40upx;
overflow: hidden;
display: flex;
margin-right: -2%;
.joinCart,
.buy {
height: 80upx;
padding: 0 40upx;
color: #fff;
display: flex;
align-items: center;
font-size: 28upx;
}
.joinCart {
background-color: #f0b46c;
}
.buy {
background-color: #f06c7a;
}
}
}
.popup {
position: fixed;
top: 0;
width: 100%;
height: 100%;
z-index: 20;
display: none;
.mask {
position: fixed;
top: 0;
width: 100%;
height: 100%;
z-index: 21;
background-color: rgba(0, 0, 0, 0.6);
}
.layer {
position: fixed;
z-index: 22;
bottom: -70%;
width: 92%;
padding: 0 4%;
height: 70%;
border-radius: 20upx 20upx 0 0;
background-color: #fff;
display: flex;
flex-wrap: wrap;
align-content: space-between;
.content {
width: 100%;
padding: 20upx 0;
}
.btn {
width: 100%;
height: 100upx;
.button {
width: 100%;
height: 80upx;
border-radius: 40upx;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
background-color: #f47952;
font-size: 28upx;
}
}
}
&.show {
display: block;
.mask {
animation: showPopup 0.2s linear both;
}
.layer {
animation: showLayer 0.2s linear both;
}
}
&.hide {
display: block;
.mask {
animation: hidePopup 0.2s linear both;
}
.layer {
animation: hideLayer 0.2s linear both;
}
}
&.none {
display: none;
}
&.service {
.row {
margin: 30upx 0;
.title {
font-size: 30upx;
margin: 10upx 0;
}
.description {
font-size: 28upx;
color: #999;
}
}
}
&.spec {
.title {
font-size: 30upx;
margin: 30upx 0;
}
.sp {
display: flex;
view {
font-size: 28upx;
padding: 5upx 20upx;
border-radius: 8upx;
margin: 0 30upx 20upx 0;
background-color: #f6f6f6;
&.on {
padding: 3upx 18upx;
border: solid 1upx #f47925;
}
}
}
.length {
margin-top: 30upx;
border-top: solid 1upx #aaa;
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 20upx;
.text {
font-size: 30upx;
}
.number {
display: flex;
justify-content: center;
align-items: center;
.input {
width: 80upx;
height: 60upx;
margin: 0 10upx;
background-color: #f3f3f3;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
input {
width: 80upx;
height: 60upx;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
font-size: 26upx;
}
}
.sub,
.add {
width: 60upx;
height: 60upx;
background-color: #f3f3f3;
border-radius: 5upx;
.icon {
font-size: 30upx;
width: 60upx;
height: 60upx;
display: flex;
justify-content: center;
align-items: center;
}
}
}
}
}
}
.share {
display: none;
&.show {
display: block;
.mask {
animation: showPopup 0.15s linear both;
}
.layer {
animation: showLayer 0.15s linear both;
}
}
&.hide {
display: block;
.mask {
animation: hidePopup 0.15s linear both;
}
.layer {
animation: hideLayer 0.15s linear both;
}
}
&.none {
display: none;
}
.mask {
background-color: rgba(0, 0, 0, .5);
position: fixed;
width: 100%;
height: 100%;
top: 0;
z-index: 11;
}
.layer {
width: 92%;
position: fixed;
z-index: 12;
padding: 0 4%;
top: 100%;
background-color: rgba(255, 255, 255, 0.9);
.list {
width: 100%;
display: flex;
padding: 10upx 0 30upx 0;
.box {
width: 25%;
display: flex;
justify-content: center;
flex-wrap: wrap;
image {
width: 13.8vw;
height: 13.8vw;
}
.title {
margin-top: 10upx;
display: flex;
justify-content: center;
width: 100%;
font-size: 26upx;
}
}
}
.btn {
width: 100%;
height: 100upx;
display: flex;
justify-content: center;
align-items: center;
font-size: 28upx;
border-top: solid 1upx #666666;
}
.h1 {
width: 100%;
height: 80upx;
display: flex;
justify-content: center;
align-items: center;
font-size: 34upx;
}
}
}
</style>