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.

518 lines
12 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 class="popup">
<view class="mask" @touchmove.stop.prevent="moveHandle" v-if="showModal" @tap="onhide"></view>
<view @touchmove.stop.prevent="moveHandle" :class="'sku ' + (showModal==true ? 'shows':'')" :style="{bottom: showModal == true ? bottoms+'upx': ''}">
<view class="sku_top">
<image :src="goods.url" class="top_img"></image>
<view class="sku_title">
{{goods.goodsName}}
</view>
<view class="moneys">
<!-- 这里的价格是选择完规格后计算的价格 -->
¥{{(Number(goods.price) * number).toFixed(2)}}
</view>
<view class="kucun">
<!-- 这里的价格是选择完规格后计算的库存 -->
库存: {{goods.stock || stock }}
</view>
</view>
<block v-if="goods._skus.length > 0">
<view v-for="(item, index) in goods._skus"
:key="index"
class="sku_list">
<view class="sku_name">
{{item.skuname}}
</view>
<view class="sku_tag">
<view v-for="(row, sIndex) in item.child"
:key="row.id"
class="tag_s"
:class="[currentArr['' + index] == row.id ? ' active' : '']"
@tap="setTag(item, index, sIndex, row)"
>
{{row.tagname}}
</view>
</view>
</view>
</block>
<view class="number">
<view class="n_left">购买数量</view>
<view class="n_right">
<text class="jian" @tap="onChangeNum('reduce')"></text>
<input :value="number" disabled type="number" maxlength="2" class="inputs"></input>
<text class="jia" @tap="onChangeNum('add')"></text>
</view>
</view>
<view class="btn_box">
<view class="addcart_btn" :style="'background-color:' + colors" @tap="onsubmit('add')">加入购物车</view>
<view class="submit" :style="'background-color:' + colors" @tap="onsubmit('pay')">立即购买</view>
</view>
</view>
</view>
</template>
<script>
import { setTabBarBadge } from'@/utils/util.js'
import {getCart, setCart ,resetCart, setGoodsData,getCartNumber, getToken} from '@/utils/auth.js'
import { addCart } from '@/api';
export default {
data() {
return {
number: 1,
current: "",
currentArr: {}, //当前选中的规格数组
currentSku:{}, //选择后的规格详情
skulength: 0, //选择商品规格的长度
issku: false ,//判断当前商品是否存在规格
update: true,
nowList:{},
stock: 500
};
},
components: {},
props: {
colors: {
type: String
},
showModal: {
type: Boolean,
default: false
},
goods: {
type: Object
},
bottoms:{
type: String,
default: 0
}
},
computed:{
skuArr() {
return this.goods.skuArr;
}
},
watch:{
goods(newVal){//监听商品规格变化 来清空之前所选的规格
newVal._skus.forEach((v, index) => {
this.$set(this.currentArr, index, v.child[0].id)
})
this.number = 1 //初始数量
}
},
methods: {
moveHandle(){
return
},
setTag(items, current, indexs,row) {
console.log(items, current, indexs,row)
//选择规格
let that = this
let item = items
let pid = items.sku_id
let isChecked = true; // 选中 or 取消选中
// const findIndex = this.currentArr.findIndex(v => v === row.id)
// if (findIndex > -1) {
// this.currentArr.splice(findIndex, 1, '');
// isChecked = false
// } else {
// this.$set(this.currentArr, current, row.id)
// }
// this.currentArr[current + ''] = row.id
this.$set(this.currentArr, current, row.id)
const chooseSkuId = Object.values(this.currentArr).filter(v => !!v);
let newSku = this.getAllSku() //获取符合条件的规格数据
that.skulength = chooseSkuId.length
if(chooseSkuId.length == that.nowList.sku.length && newSku.length){
//如果所有的规格类都被选中了 设置当前选中项商品的信息
that.currentSku = newSku[0]
that.issku = true //设定当前商品为规格商品 用于加入购物车时判断
}else{
that.currentSku = that.nowList;
}
// 每次点击选择或者取消之后都要刷新下选择状态 判断其他规格不符合条件的是否被选中
that.changeDisabled(isChecked,row.id, pid)
},
changeDisabled(isChecked=false,skuId=0, pid=0){ //改变禁用状态
let newSku = []
if (isChecked) {
for(let key of this.skuArr){ //遍历可用规格数组
if(key.stock <= 0){ //如果规格现有的库存小于等于0
continue
}
if(key.goods_sku_arr.indexOf(skuId.toString()) >= 0){ //如果当前选中的类中存在对应的规格
newSku.push(key)
}
}
}else{
newSku = this.getAllSku()
}
// 所有存在并且有库存未选择的规格项 的 子项 id
let noChooseSkuIds = [];
for (let price of newSku) {
noChooseSkuIds = noChooseSkuIds.concat(price.goods_sku_arr);
}
// 去重
noChooseSkuIds = Array.from(new Set(noChooseSkuIds));
if (isChecked) {
// 去除当前选中的规格项
let index = noChooseSkuIds.indexOf(skuId.toString());
noChooseSkuIds.splice(index, 1);
} else {
// 循环去除当前已选择的规格项
// this.currentArr.forEach(sku => {
// if (sku.toString() != '') {
// // sku 为空是反选 填充的
// let index = noChooseSkuIds.indexOf(sku.toString());
// if (index >= 0) {
// // sku 存在于 noChooseSkuIds
// noChooseSkuIds.splice(index, 1);
// }
// }
// });
}
// 当前已选择的规格大类
let chooseSkuKey = [];
if (!isChecked) {
// 当前已选择的规格大类
// this.currentArr.forEach((sku, key) => {
// if (sku != '') {
// // sku 为空是反选 填充的
// chooseSkuKey.push(key);
// }
// });
} else {
// 当前点击选择的规格大类
chooseSkuKey = [pid];
}
let skuid = this.currentArr[pid]
for(let i in this.nowList.sku){
// 当前点击的规格,或者取消选择时候 已选中的规格 不进行处理
for (var x in this.nowList.sku[i]['child']) {
// 如果当前规格项 id 不存在于有库存的规格项中,则禁用
if (chooseSkuKey.indexOf(this.nowList.sku[i]['sku_id']) >= 0) {
if(this.nowList.sku[i]['child'][x]['id'] == skuid){
continue
}else{
if(!isChecked){
this.nowList.sku[i]['child'][x]['disabled'] = false;
}
}
}else{
if (noChooseSkuIds.indexOf(this.nowList.sku[i]['child'][x]['id'].toString()) >= 0) {
this.nowList.sku[i]['child'][x]['disabled'] = false;
} else {
this.nowList.sku[i]['child'][x]['disabled'] = true;
}
}
}
}
},
onhide() {
//隐藏规格对话框
this.$emit('onhide')
},
onChangeNum(type = 'reduce') {
if (type === 'add') {
if (this.number >= this.stock) {
return
}
this.number += 1
} else {
if (this.number <= 1) {
return;
}
this.number -= 1
}
},
onsubmit(value) {
// 此处应该判断是否登录 如果没登录 跳转到登录页
if(!getToken()){
uni.navigateTo({ //登录
url:'/pages/login/index1'
})
return
}
//提交购物车
if(Object.keys(this.currentArr).length != this.goods._skus.length){ //如果规格长度和所选规格长度不相等 提示
uni.showToast({
title: '请选择规格',
icon: 'none'
});
return
}
// addCart
const cartParams = {
"goodsId": 0,
"goodsName": "",
"goodsNo": 0,
"url": "",
"userId": "",
specs: ''
}
const data = this.goods
const selectedSku = []
Object.keys(this.currentArr).forEach(key => {
const item = this.currentArr[key]
if (item) {
const sku = this.goods._skus[key].child[item -1 ]
sku.number = sku.number ? sku.number + this.number : this.number
selectedSku.push(sku)
}
})
data._selectedSku = selectedSku
data.number = this.number
if(value == 'add'){ //如果是添加购物车
let colCart = getCart();
if(colCart.length){
const hasItem = colCart.some(v => v.id === data.id)
if (!hasItem) {
colCart.push(data)
} else {
for(let y = 0;y < colCart.length; y++){
const item = colCart[y]
if (data.id === item.id) {
item.number += this.number
item._selectedSku = selectedSku
break
}
}
}
} else {
colCart = [data]
}
resetCart(colCart)
// 存储商品数据
uni.showToast({
title: '加入购物车成功 !',
icon: 'none'
});
/**
* 模拟获取购物车的数量 getCart
*/
let cartNum = getCartNumber()
setTabBarBadge(cartNum)
}else{ //如果是购买商品
let goods = []
goods.push(data)
setGoodsData(goods) //存储商品信息和商品规格
uni.navigateTo({ //提交订单
url:'/pages/views/order/confirmOrder'
})
}
setTimeout(() => {
this.$emit('onhide')
}, 800);
},
// 处理规格多选情况下 符合条件的规格 并把不符合条件的规格禁用
getAllSku(){
let newSku = []
for(let key of this.skuArr){ //遍历可用规格数组
if(key.stock <= 0){ //如果规格现有的库存小于等于0
continue
}
var isOk = true
// this.currentArr.forEach((sku)=>{
// // sku 不为空,并且,这个 条 skuPrice 没有被选中,则排除
// if(sku.toString() !== '' && key.goods_sku_arr.indexOf(sku.toString()) < 0){
// isOk = false
// }
// })
if(isOk == true){
newSku.push(key)
}
}
return newSku
}
}
};
</script>
<style scoped lang="scss">
.mask{
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background: #000;
z-index: 900;
opacity: 0.7;
}
.sku{
width: 100vw;
min-height: 30vh;
position: fixed;
bottom: -100%;
z-index: 910;
left: 0;
background-color: #ffffff;
padding: 20upx 4%;
border-top-left-radius: 10upx;
border-top-right-radius: 10upx;
border-bottom: 1upx solid #eee;
transition: all 0.3s;
}
.shows{
bottom: 0;
transition: all 0.3s;
}
.sku_top{
overflow: hidden;
margin-top: 20upx;
}
.sku_top .top_img{
height: 170upx;
width: 170upx;
float: left;
margin-right: 15upx;
border-radius: 8upx;
}
.sku_top .sku_title{
font-size: 30upx;
line-height: 35upx;
font-weight: bold;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.sku_top .moneys{
font-size: 30upx;
line-height: 40upx;
overflow: hidden;
margin-top: 20upx;
font-weight: bold;
color: $mycolor;
}
.sku_top .kucun{
font-size: 24upx;
color: #999;
overflow: hidden;
}
.sku_list{
margin-top: 20upx;
overflow: hidden;
margin-bottom: 40upx;
}
.sku_name{
font-size: 24upx;
color: #666;
overflow: hidden;
}
.sku_tag{
overflow: hidden;
margin-top: 20upx;
}
.sku_tag .tag_s{
height: 60upx;
line-height: 60upx;
align-items: center;
padding: 0 20upx;
text-align: center;
font-size: 26upx;
color: #202020;
background-color: #F5F5F5;
border: 1upx solid #F5F5F5;
float: left;
border-radius: 40upx;
margin-right: 20upx;
transition: all 0.2s;
margin-bottom: 20upx;
font-weight: 500;
&::after{
border: none;
}
}
.sku_tag .tag_s.active {
color: rgb(57, 181, 74);
background: rgb(255, 255, 255);
border-color: rgb(57, 181, 74);
}
.number{
margin-top: 10upx;
border-top: 1upx solid #ccc;
width: 100%;
height: 80upx;
line-height: 80upx;
padding-top: 10upx;
}
.number .n_left{
float: left;
font-size: 28upx;
color: #333;
}
.number .n_right{
float: right;
height: 60upx;
width: 200upx;
background-color: #F5F5F5;
margin-top: 10upx;
border-radius: 5upx;
}
.n_right .jian,.jia{
width: 60upx;
height: 60upx;
text-align: center;
line-height: 60upx;
font-size: 42upx;
}
.jian{
float: left;
}
.jia{
float: right;
}
.jian:active{
background-color: #eee;
}
.jia:active{
background-color: #eee;
}
.n_right .inputs{
width: 76upx;
float: left;
text-align: center;
margin-top: 6upx;
}
.btn_box{
margin-top: 40upx;
}
.btn_box .addcart_btn, .submit{
width: 40vw;
height: 60upx;
line-height: 60upx;
border-radius: 42upx;
font-size: 26upx;
text-align: center;
color: #ffffff;
float: left;
margin-left: 30upx;
margin-bottom: 30upx;
}
.btn_box .addcart_btn:active{
opacity: 0.8;
}
.btn_box .submit:active{
opacity: 0.8;
}
.ondisabled{
background-color: #F9F9F9;
opacity: 0.5;
}
</style>