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.

414 lines
9.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view>
<!-- 规格选择 -->
<uni-popup ref="cartpup" type="share">
<view class="allcon">
<view class="gcon" v-if="product">
<image :src="product.img1"></image>
<view class="tit-box">
<view class="price">
<text class="txt">¥</text>
<text class="tint">{{product.price}}</text>
<text class="txt" v-if="product.unit">/{{product.unit}}</text>
</view>
<text class="tit2">
已选: {{product.sels}}
</text>
<text class="tit2">
商品: {{product.name}} {{product.tip}}{{product.sels}}
</text>
</view>
</view>
<view class="selcon" v-if="product.specs&&product.specs.length>0" >
<view class="spcitem" v-for="(item, index) in product.specs" :key="index" v-if="item.list.length>0">
<view class="spcname">
{{item.name}}
</view>
<view class="spcul" v-if="item.list&&item.list.length>0">
<view class="spcli" v-for="(cell, ii) in item.list" :key="ii" :class="item.sels==ii?'cur':''" @tap="seldo(index,ii)">
{{cell.name}}
</view>
</view>
</view>
</view>
<view class="numcon">
<view class="ntip">购买数量</view>
<view class="nadc">
<uni-number-box v-model="product.quantity" :value="product.quantity" :min="1" :max="product.stock" />
</view>
</view>
<button v-if="buyType==1" type="primary" class="sbtn" data-img="/static/image/cart.png" @tap="addcarDo">加入购物车</button>
<button v-if="buyType==2" type="primary" class="sbtn1" @tap="gotoBuy()">立即购买</button>
</view>
</uni-popup>
<!-- 加入购物车动画 cartx 和 carty 是购物车位置在屏幕位置的比例 例如左上角x0.1 y0.1 右下角 x0.9 y0.9-->
<shopCarAnimation ref="carAnmation" :cartx="x" :carty="y"></shopCarAnimation>
</view>
</template>
<script>
import { myCache,getRemoteFile } from '../../utils/utils.js';
// 加入购物车动画组件
import shopCarAnimation from '@/components/fly-in-cart/fly-in-cart.vue'
export default {
components: {
shopCarAnimation
},
props: {
pdata: {
type: Object,
default: function () {
return null
},
},// 商品信息
ptype: {
type: Number,
default: 1,
},// 1加入购物车2 购买
x: {
type: String,
default: function () {
return "0.1"
},
},// 坐标点
y: {
type: String,
default: function () {
return "0.1"
},
},// 坐标点
},
data() {
return {
product:{
specs:[]
},
buyType:1
};
},
watch: {
pdata(value) {
this.init(value);
},
ptype(value) {
this.initbt(value);
},
},
methods: {
init(value){
this.product=value;
this.$forceUpdate();
if(this.product&&this.product.specs){
this.selinit();
}
},
initbt(value){
this.buyType=value;
},
seldo(ii,kk){
console.log(ii,kk)
this.product.specs[ii].sels=kk;
this.$forceUpdate();
this.selinit();
},
selinit(){
// 初始化
if(this.product.specs&&this.product.specs.length>0){
var sels='',spData={};
this.product.specs.forEach((cell,idx)=>{
if(cell.list&&cell.list[cell.sels]){
sels=sels+cell.list[cell.sels].name+' ',
spData[cell.name]=cell.list[cell.sels].name;
}
});
this.product.sels=sels;
this.product.spData=spData; // 规格的json形式非字符串
this.product.skus.forEach(cell=>{
if(cell.spData==JSON.stringify(spData)){
this.product.skuId=cell.id;
this.product.price=cell.price;
this.product.img=cell.pic?getRemoteFile(cell.pic):this.product.img1;
this.product.img1=cell.pic?getRemoteFile(cell.pic):this.product.img1;
this.product.stock=cell.stock;//库存
if(this.product.quantity>this.product.stock){
this.product.quantity=this.product.stock
}
else if(this.product.quantity==0&&this.product.stock>0){
this.product.quantity=1
}
}
});
this.$forceUpdate();
}
else{
this.product.sels='';
this.product.spData==null;
this.product.skuId=null;
this.$forceUpdate();
}
},
retSku(spData){
var rets=[];
if(spData){
var suk= spData;
var keys=Object.keys(suk);
keys.forEach(dd=>{
rets.push(dd+":"+suk[dd])
});
}
return rets.join(',');
},
gotoBuy(){
// 购物车数量要大于0
if(this.product.quantity<=0){
uni.showModal({
title: '提示',
content: '数量要大于0',
cancelText: '取消',
confirmText: '确定',
});
return false;
}
// 更改字符方式传输
this.product.spData=JSON.stringify(this.product.spData);
// 缓存购买商品
var setcart= JSON.parse(JSON.stringify(this.product));
myCache('buycartList',setcart);
// 跳转订单结算
uni.navigateTo({
url: `/pages/product/order?type=buy`
});
},
async addcarDo(e){
try{
// 购物车数量要大于0
if(this.product.quantity<=0){
uni.showModal({
title: '提示',
content: '数量要大于0',
cancelText: '取消',
confirmText: '确定',
});
return false;
}
var param={
productId:this.product.id,
productName:this.product.name,
pic:this.product.img,
spData:JSON.stringify(this.product.spData),// this.retSku(this.product.spData) 展示时候再解析,保持数据一致, // 保存字符串 this.product.spData,
skuId:this.product.skuId,
quantity:this.product.quantity,
storeId:myCache('myshopid')?myCache('myshopid'):'',
isCourse:this.product.isCourse,
};
const {data: res1} = await uni.$http.post('/api/cart/add',param);
if (res1) {
// 购物车缓存
this.updatecart(e);
this.close();
}
else{
uni.showModal({
title: '提示',
content: res1.message? res1.message:'加入购物车失败!请稍候再试',
cancelText: '取消',
confirmText: '确定',
});
}
}
catch(e){
console.log(e)
}
},
async updatecart(e){
try{
const {data: res } = await uni.$http.get('/api/cart/list');
if (res&&res.length>0) {
// 购物车缓存
myCache("carts",res);
// 加入购物车动画
this.$refs.carAnmation.touchOnGoods(e);
this.$emit("addShopCar", this.product.sels,this.product.quantity,this.buyType);
}
}
catch(e){
console.log(e)
}
},
close(){
this.$refs.cartpup.close();
},
show() {
this.$refs.cartpup.open();
this.product=this.pdata;
this.buyType=this.ptype;
console.log(this.product,this.buyType)
this.$forceUpdate();
if(this.product&&this.product.specs){
this.selinit();
}
},
}
}
</script>
<style lang="scss" scoped>
/* 弹框 */
.allcon{
width: 100%;
background-color: #FFFFFF;
padding-bottom: calc(var(--window-bottom) + 30rpx);
border-radius: 20rpx 20rpx 0 0;
position: relative;
.gcon{
display:flex;
align-items:center;
padding: 20rpx;
border-bottom: 1rpx solid #eee;
image{
flex-shrink: 0;
width: 150rpx;
height: 150rpx;
border-radius: 6rpx;
border: 1rpx solid #eee;
margin-right: 20rpx;
}
.tit-box{
flex: 1;
display: flex;
flex-direction: column;
}
.price{
line-height: 1;
color: #89965f;
.txt{
font-size: 30rpx;
}
.tint{
font-size: 42rpx;
font-weight: 600;
}
}
.tit{
font-size: 36rpx;
color: rgba(0, 0, 0, 0.9);
line-height: 1.3;
}
.tit2{
font-size: 24rpx;
color: #909399;
margin-top: 10rpx;
}
}
.selcon{
position: relative;
padding: 20rpx 0;
.spcitem{
padding: 0 20rpx 0 20rpx;
display: flex;
flex-direction: column;
.spcname{
line-height: 70rpx;
color: #000;
font-size: 28rpx;
}
.spcul{
display: flex;
flex-direction: row;
flex-flow: wrap;
.spcli{
height: 60rpx;
line-height: 60rpx;
padding: 0 20rpx;
border: 1rpx solid #eee;
font-size: 26rpx;
color: #000;
background: #FFF;
margin-right: 20rpx;
border-radius: 6rpx;
margin-bottom: 20rpx;
}
.spcli.cur{
background: #f3f4ee;
border: 1rpx solid #89965f;
font-weight: 600;
}
.spclilong{
height: 66rpx;
line-height: 66rpx;
padding: 0 20rpx;
border: 1rpx solid #eee;
font-size: 26rox;
color: #000;
background: #FFF;
margin-right: 20rpx;
border-radius: 6rpx;
margin-bottom: 30rpx;
display: flex;
flex:1;
justify-content: space-between;
}
.spclilong.cur{
background: #f3f4ee;
border: 1rpx solid #89965f;
font-weight: 600;
}
}
}
}
.numcon{
padding: 10rpx 20rpx 40rpx 20rpx;
display: flex;
justify-content: space-between;
.ntip{
font-size: 28rpx;
color: #000;
}
.nadc{
margin-right: 20rpx;
}
}
.sbtn{
margin: 20rpx 30rpx 54rpx;
font-size: 30rpx;
font-family: PingFang SC-Medium, PingFang SC;
font-weight: 500;
color: #FCFCFD;
width: 690rpx;
height: 76rpx;
line-height: 76rpx;
background: #89965f;
box-shadow: 0rpx 12rpx 64rpx 2rpx rgba(137,150,95,0.4);
margin: 0 30rpx 30rpx;
border-radius: 10rpx;
opacity: 1;
&::after{
border:none;
}
}
.sbtn1{
margin: 20rpx 30rpx 54rpx;
font-size: 30rpx;
font-family: PingFang SC-Medium, PingFang SC;
font-weight: 500;
color: #FCFCFD;
width: 690rpx;
height: 76rpx;
line-height: 76rpx;
background: #55690e;
box-shadow: 0rpx 12rpx 64rpx 2rpx rgba(137,150,95,0.4);
margin: 0 30rpx 30rpx;
border-radius: 10rpx;
opacity: 1;
&::after{
border:none;
}
}
}
</style>