提交 b0955347 编写于 作者: guofeng.chen's avatar guofeng.chen

商品详情页

上级 80075b47
...@@ -8,19 +8,19 @@ export const envConfig = { ...@@ -8,19 +8,19 @@ export const envConfig = {
// baseUrl: 'http://10.177.15.180:10202/', // baseUrl: 'http://10.177.15.180:10202/',
// baseUrl: 'http://192.168.140.14:10201/', // baseUrl: 'http://192.168.140.14:10201/',
// apiUrl: 'https://dev-api.yunqueyi.com/', apiUrl: 'https://dev-api.yunqueyi.com/',
// webPageUrl: 'https://dev-phome.yunqueyi.com/', webPageUrl: 'https://dev-phome.yunqueyi.com/',
// baseUrl: 'https://dev-sc.yunqueyi.com/', baseUrl: 'https://dev-sc.yunqueyi.com/',
// hactiveUrl: 'https://dev-hactive.yunqueyi.com',
// fileUrl: 'https://dev-www.yunqueyi.com',
// appId: 'wxf4e66242d31c81c2', // 用于微信授权登录
baseUrl: 'https://test1-sc.yunqueyi.com/',
apiUrl: 'https://test1-api.yunqueyi.com/',
webPageUrl: 'https://test1-phome.yunqueyi.com/',
hactiveUrl: 'https://dev-hactive.yunqueyi.com', hactiveUrl: 'https://dev-hactive.yunqueyi.com',
fileUrl: 'https://test1-www.yunqueyi.com', fileUrl: 'https://dev-www.yunqueyi.com',
appId: 'wxcaad75b7fff5659c', // 用于微信授权登录 appId: 'wxf4e66242d31c81c2', // 用于微信授权登录
// baseUrl: 'https://test1-sc.yunqueyi.com/',
// apiUrl: 'https://test1-api.yunqueyi.com/',
// webPageUrl: 'https://test1-phome.yunqueyi.com/',
// hactiveUrl: 'https://dev-hactive.yunqueyi.com',
// fileUrl: 'https://test1-www.yunqueyi.com',
// appId: 'wxcaad75b7fff5659c', // 用于微信授权登录
// baseUrl: 'https://uat-sc.yunqueyi.com/', // baseUrl: 'https://uat-sc.yunqueyi.com/',
// apiUrl: 'https://uat-api.yunqueyi.com/', // apiUrl: 'https://uat-api.yunqueyi.com/',
......
...@@ -237,4 +237,15 @@ export const getCookie = key => { ...@@ -237,4 +237,15 @@ export const getCookie = key => {
} }
} }
return ''; return '';
}; };
\ No newline at end of file
export function debounce(fn, wait = 50) {
let timer;
return function() {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this, arguments);
timer = null;
}, wait)
}
}
<template> <template>
<div class="goods-details-wrapper"> <div class="goods-details-wrapper">
商品详情页面 <!-- 轮播 -->
<div class="swiper-box">
<van-swipe :show-indicators="false" @change="onSwiperChange">
<van-swipe-item
v-for="(item, index) in swiperList"
:key="index">
<img class="img" :src="item.goodsImgUrl" alt="" />
</van-swipe-item>
</van-swipe>
<div class="indicator">
{{ swiperCurtIndex + 1 }}/{{ swiperList.length }}
</div>
</div>
<!-- 商品信息 -->
<div class="info-box border-line">
<p class="title">{{ goods.goodsName }}</p>
<div class="price">
<div class="money">
<span class="yuan">{{ goods.salePrice.yuan }}</span><span class="fen">.{{ goods.salePrice.fen }}</span><span v-if="goods.hasDiscount" class="del">原价: ¥{{ goods.costPriceText }}</span>
</div>
<div class="bought">{{ goods.saledNum }}购买</div>
</div>
</div>
<!-- 购买数量、支付方式 -->
<div class="buy-box border-line">
<div class="flex">
<div class="name">购买数量</div>
<div class="buy-num">
<div class="reduce" @click="onReduce"></div>
<div class="num">{{ goodsNum }}</div>
<div class="plus" @click="onPlus"></div>
</div>
</div>
<div class="flex buy-way">
<div class="name">
支付方式
<span>目前只支持微信支付</span>
</div>
<div class="way">微信支付</div>
</div>
</div>
<!-- tab切换 -->
<div class="tab-box">
<div
class="tab-item"
:class="{'tab-active': curtTabIdx === index}"
v-for="(tab, index) in tabs"
:key="index"
@click="curtTabIdx=index">
{{ tab.name }}
</div>
<div class="tab-line" :style="{left: `${tabLeft}px`}"></div>
</div>
<!-- 详情 -->
<div class="detail-box" v-html="tabs[curtTabIdx] && tabs[curtTabIdx]['detail']"></div>
<!-- 底部购买 -->
<div class="btn-box">
<div class="money">
<p>合计:<span class="yuan">{{ totalPrice.yuan }}</span><span class="fen">.{{ totalPrice.fen }}</span><span v-if="goods.hasDiscount" class="del">原价: ¥{{ totalPrice.costPriceText }}</span></p>
<p v-if="goods.couponAmountText" class="coupon">已使用优惠券,为您再优惠{{ goods.couponAmountText }}</p>
</div>
<div
class="btn"
:class="[goods.isSale === 2 ? 'cannot-buy' : 'can-but']"
@click="createOrder">
{{ goods.isSale === 2 ? '商品已下架' : '确认支付' }}
</div>
</div>
</div> </div>
</template> </template>
<script> <script>
import { Swipe, SwipeItem } from 'vant';
import { debounce } from '@/utils';
export default { export default {
components: {
Swipe,
SwipeItem,
},
data() {
return {
goods: {
salePrice: {},
}, // 商品信息
totalPrice: {}, // 底部价格
swiperList: [], // 轮播图
swiperCurtIndex: 0, // 轮播当前下标
goodsNum: 1, // 数量
tabs: [],
curtTabIdx: 0,
tabW: 0, // tab的宽度
}
},
computed: {
logged() {
return this.$store.getters.logged;
},
tabLeft() {
const num = this.curtTabIdx + 0.25 + 15 / 115;
return this.tabW * num;
},
},
mounted() {
this.projectId = this.$route.query.projectId;
this.goodsId = this.$route.query.goodsId || 10077;
this.returnUrl = this.$route.query.returnUrl;
this.getGoodsInfo();
this.getTabW();
// 数量加减
this.curtGoodsNum = this.goodsNum;
this.countTotalPrice = debounce(this.getTotalPrice, 500);
},
beforeDestroy() {
this.countTotalPrice = null;
},
methods: {
getGoodsInfo() {
this.GET(`trade/goods/goodInfo/${this.goodsId}`, {}).then(res => {
if (res.code == "000000") {
const goods = res.data;
const tabs = [];
let price = goods.couponPrice || goods.preferentialPrice || goods.costPrice;
goods.salePrice = this.formatPrice(price);
goods.costPriceText = (goods.costPrice / 100).toFixed(2);
goods.hasDiscount = !!(goods.couponPrice || goods.preferentialPrice);
if (goods.couponDTO) {
goods.couponAmountText = (goods.couponDTO.discountAmount / 100).toFixed(2);
}
if (goods.goodsDescWhere) {
tabs.push({ name: '使用范围', detail: goods.goodsDescWhere })
}
if (goods.goodsDescHow) {
tabs.push({ name: '如何使用', detail: goods.goodsDescHow })
}
if (goods.goodsDescQaq) {
tabs.push({ name: '常见问题', detail: goods.goodsDescQaq })
}
this.totalPrice = {
...goods.salePrice,
preferentialPrice: goods.preferentialPrice,
costPrice: goods.costPrice,
costPriceText: goods.costPriceText
}
this.goods = goods;
this.swiperList = res.data && res.data.imgList || [];
this.tabs = tabs;
this.getTabW();
} else {
this.$toast(res.message);
}
})
},
// 多件商品的价格
getTotalPrice() {
const num = this.curtGoodsNum;
this.GET(`trade/goods/getPrice/${this.goodsId}/${num}`, {}).then(res => {
if (res.code == "000000") {
const { preferentialPrice, totalPrice } = res.data;
this.totalPrice = {
...this.formatPrice(preferentialPrice),
preferentialPrice,
costPrice: totalPrice,
costPriceText: (totalPrice / 100).toFixed(2),
}
this.goodsNum = num;
}
})
},
// 价格转成元、分
formatPrice(price) {
let yuan = (price / 100).toFixed(0);
let fen = price % 100;
fen = fen < 10 ? `0${fen}` : fen;
return {
yuan,
fen
}
},
// 获取切换标签宽度
getTabW() {
if (this.tabs.length === 0) {
return;
}
this.$nextTick(() => {
const { width } = this.$el.querySelector('.tab-item').getBoundingClientRect();
this.tabW = width;
})
},
// 轮播切换
onSwiperChange(index) {
this.swiperCurtIndex = index;
},
// 数量增
onPlus() {
if (!this.logged) {
this.goLogin();
return;
}
let num = this.curtGoodsNum;
if (this.goods.limitPurchase && this.goods.limitPurchaseNum && num >= this.goods.limitPurchaseNum) {
this.$toast('已达最大限购数量')
return;
}
this.curtGoodsNum = num + 1;
this.countTotalPrice();
},
// 数量减
onReduce() {
if (!this.logged) {
this.goLogin();
return;
}
let num = this.curtGoodsNum;
if (num <= 1) {
this.$toast('最少购买一张哦')
return;
}
this.curtGoodsNum = num - 1;
this.countTotalPrice();
},
goLogin() {
this.$store.dispatch('goLogin');
},
// 创建订单
createOrder() {
if (!this.logged) {
this.goLogin();
return;
}
const { id, couponDTO, isSale } = this.goods;
const { preferentialPrice, costPrice } = this.totalPrice;
// if (!id || isSale !== 1) {
// return;
// }
const orderData = {
couponId: couponDTO ? couponDTO.couponId : 0,
goodsId: id,
goodsQuantity: this.goodsNum,
orderSource: 3,
preferentialPrice: preferentialPrice,
price: costPrice,
}
this.POST('trade/center/order/createV2', orderData).then(res => {
if (res.code == "000000") {
const orderId = res.data.orderId;
if (this.projectId) {
this.createRelation(this.projectId, orderId);
}
} else {
this.$toast(res.message);
}
})
},
// 支付
goPay(orderId) {
//
},
// 绑定项目和订单的关系
createRelation(projectId, orderId) {
this.POST(`cme/projectCard/correlation/${projectId}/${orderId}`, {channel: 3}).then(res => {
if (res.code == "000000") {
//
} else {
this.$toast(res.message);
}
})
}
},
} }
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.goods-details-wrapper { .goods-details-wrapper {
font-size: 14px; .swiper-box{
position: relative;
.indicator{
position: absolute;
right: 10px;
bottom: 10px;
width: 40px;
height: 22px;
line-height: 22px;
color: #fff;
font-size: 12px;
text-align: center;
padding: 0 8px;
border-radius: 11px;
background: rgba(0, 0, 0, 0.2);
}
.img{
display: block;
width: 100%;
}
}
.border-line{
padding: 20px 15px;
border-bottom: 6px solid #F8F9FA;
}
.info-box{
.title{
font-size: 18px;
font-weight: bold;
padding-bottom: 12px;
}
.price{
display: flex;
align-items: baseline;
font-size: 12px;
}
.money{
flex: 1;
width: 100px;
}
.yuan{
color: #FB5B52;
font-size: 18px;
font-weight: bold;
}
.fen{
color: #FB5B52;
font-weight: bold;
}
.del{
color: #979899;
text-decoration: line-through;
margin-left: 6px;
}
.bought{
color: #979899;
}
}
.buy-box{
font-size: 14px;
.flex{
display: flex;
align-items: center;
}
.name{
flex: 1;
width: 100px;
font-weight: bold;
}
.buy-num{
display: flex;
}
.reduce{
position: relative;
width: 22px;
height: 22px;
line-height: 22px;
text-align: center;
&::before{
position: absolute;
content: "";
left: 6px;
top: 10px;
width: 10px;
height: 1px;
background-color: #449284;
pointer-events: none;
}
&::after{
position: absolute;
content: "";
left: 0;
top: 0;
width: 200%;
height: 200%;
border: 1PX solid #449284;
transform: scale(0.5);
transform-origin: left top;
pointer-events: none;
border-radius: 4px;
}
}
.num{
width: 30px;
text-align: center;
}
.plus{
position: relative;
width: 22px;
height: 22px;
line-height: 22px;
text-align: center;
background-color: #449284;
border-radius: 2px;
&::before{
position: absolute;
content: "";
left: 6px;
top: 10px;
width: 10px;
height: 1px;
background-color: #fff;
pointer-events: none;
}
&::after{
position: absolute;
content: "";
left: 10px;
top: 6px;
width: 1px;
height: 10px;
background-color: #fff;
pointer-events: none;
}
}
.buy-way{
margin-top: 25px;
span{
color: #979899;
font-size: 12px;
margin-left: 6px;
}
}
.way{
padding-left: 28px;
background: url('~@/images/wxpay.png') no-repeat left center;
background-size: 18px auto;
}
}
.tab-box{
display: flex;
position: relative;
height: 50px;
padding: 0 15px;
background-color: #fff;
&::after{
position: absolute;
content: "";
left: 0;
bottom: 0;
width: 200%;
height: 0;
border-bottom: 1px solid #F0F1F2;
transform: scale(0.5);
transform-origin: left center;
}
}
.tab-item{
color: #979899;
font-size: 15px;
width: 115px;
height: 50px;
line-height: 50px;
}
.tab-active{
color: #373839;
font-weight: bold;
}
.tab-line{
position: absolute;
left: 30px;
bottom: 3px;
width: 10px;
height: 3px;
background-color: #449284;
border-radius: 1.5px;
transform: translate3d(-5px, 0, 0);
transition: left 0.3s;
}
.detail-box{
font-size: 14px;
text-align: justify;
padding: 15px 15px 75px;
img{
display: block;
width: 100%;
}
}
.btn-box{
display: flex;
align-items: center;
position: fixed;
left: 0;
bottom: 0;
width: 100%;
height: 60px;
padding: 10px 15px;
box-shadow: 0 -4px 4px rgba(240, 240, 240, 0.5);
.money{
flex: 1;
width: 100px;
font-size: 14px;
}
.yuan{
color: #FB5B52;
font-size: 18px;
font-weight: bold;
}
.fen{
font-size: 12px;
color: #FB5B52;
font-weight: bold;
}
.del{
color: #979899;
font-size: 12px;
text-decoration: line-through;
margin-left: 6px;
}
.coupon{
color: #979899;
font-size: 12px;
}
.btn{
width: 125px;
height: 40px;
line-height: 40px;
text-align: center;
color: #fff;
font-size: 16px;
font-weight: bold;
border-radius: 20px;
}
.can-but{
background-image: linear-gradient(90deg, #FFA65F, #FF7A4B);
}
.cannot-buy{
background-color: #C7C8C9;
}
}
} }
</style> </style>
\ No newline at end of file
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册