321 lines
7.7 KiB
Vue
321 lines
7.7 KiB
Vue
|
<template>
|
|||
|
<view class="attr-content">
|
|||
|
<view class="a-t">
|
|||
|
<image class="image" mode="widthFix" :src="picture || product.sku.url"></image>
|
|||
|
<view class="right">
|
|||
|
<text class="title in2line">{{ skuName }}</text>
|
|||
|
<view class="sku-info-wrapper">
|
|||
|
<view class="price-wrapper">
|
|||
|
<text :class="'text-' + themeColor.name" v-if="currentProductPrice">{{ moneySymbol }}{{ currentProductPrice }}</text>
|
|||
|
</view>
|
|||
|
<text class="stock" v-if="stock">库存:{{ stock }}{{ product.unit || '件' }}</text>
|
|||
|
<view class="selected in2line" v-if="specSelected.length > 0">
|
|||
|
已选:
|
|||
|
<text
|
|||
|
class="selected-text"
|
|||
|
v-for="(sItem, sIndex) in specSelected"
|
|||
|
:key="sIndex"
|
|||
|
>
|
|||
|
{{ sItem.name }}
|
|||
|
</text>
|
|||
|
<text v-if="specSelected.length > 0"> * {{ cartCount }} </text>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<scroll-view class="attr-content-scroll-view" scroll-y>
|
|||
|
<view v-for="(item, index) in specList" :key="index" class="attr-list">
|
|||
|
<text>{{ item.name }}</text>
|
|||
|
<view class="item-list">
|
|||
|
<view
|
|||
|
v-for="(childItem, childIndex) in specChildList"
|
|||
|
:key="childIndex"
|
|||
|
@tap="
|
|||
|
selectSpec(childIndex, childItem.specId, item.show_type)
|
|||
|
"
|
|||
|
>
|
|||
|
<view
|
|||
|
v-if="childItem.specId === item.id"
|
|||
|
:class="[childItem.selected ? 'bg-' + themeColor.name : 'tit-normal', childItem.disabled ? 'disabled' : '']"
|
|||
|
:style="
|
|||
|
childItem.selected && parseInt(item.show_type) === 2
|
|||
|
? styleObject
|
|||
|
: ''
|
|||
|
"
|
|||
|
class="tit"
|
|||
|
>
|
|||
|
<text >
|
|||
|
{{ childItem.name }}
|
|||
|
</text>
|
|||
|
<text v-if="parseInt(item.show_type) === 2">
|
|||
|
{{ childItem.name }}
|
|||
|
</text>
|
|||
|
<view v-if="parseInt(item.show_type) === 3">
|
|||
|
<image
|
|||
|
class="img"
|
|||
|
:src="childItem.data || product.picture"
|
|||
|
mode="aspectFill"
|
|||
|
></image>
|
|||
|
{{ childItem.title }}
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
<view class="select-count" v-if="isSelectedNum">
|
|||
|
<text>购买数量</text>
|
|||
|
<rf-number-box
|
|||
|
class="step"
|
|||
|
:min="parseInt(product.min_buy, 1) || minNum"
|
|||
|
:max="parseInt(product.max_buy, 10) || (maxNum === 0 ? parseInt(stock, 10) : maxNum)"
|
|||
|
:value="cartCount"
|
|||
|
@eventChange="numberChange"
|
|||
|
></rf-number-box>
|
|||
|
|
|||
|
</view>
|
|||
|
</scroll-view>
|
|||
|
<button v-if="!showBuyBtn" class="btn" :class="'bg-' + themeColor.name" @tap="toggleSpec">完成</button>
|
|||
|
<view class="btn-group" v-else>
|
|||
|
<button class="btn" :class="'bg-' + themeColor.name" @tap="toggleSpec(1)" >加入购物车</button>
|
|||
|
<button class="btn" :class="'bg-' + themeColor.name" @tap="toggleSpec(2)" >立即购买</button>
|
|||
|
</view>
|
|||
|
</view>
|
|||
|
</template>
|
|||
|
<script>
|
|||
|
/**
|
|||
|
*@des 商品规范组件
|
|||
|
*@author 237524947@qq.com
|
|||
|
*@blog https://gitee.com/zscat/mallplus/wikis/pages/preview?sort_id=1703736&doc_id=326093
|
|||
|
*@date 2020/05/03 19:17:15
|
|||
|
*/
|
|||
|
import rfNumberBox from '@/components/rf-number-box';
|
|||
|
export default {
|
|||
|
name: 'rfAttrContent',
|
|||
|
components: { rfNumberBox },
|
|||
|
props: {
|
|||
|
showBuyBtn: {
|
|||
|
type: Boolean,
|
|||
|
default: false
|
|||
|
},
|
|||
|
isSelectedNum: {
|
|||
|
type: Boolean,
|
|||
|
default: true
|
|||
|
},
|
|||
|
type: {
|
|||
|
type: String,
|
|||
|
default: 'buy_now'
|
|||
|
},
|
|||
|
product: {
|
|||
|
type: Object,
|
|||
|
default() {
|
|||
|
return {};
|
|||
|
}
|
|||
|
},
|
|||
|
minNum: {
|
|||
|
type: Number,
|
|||
|
default: 1
|
|||
|
},
|
|||
|
maxNum: {
|
|||
|
type: Number,
|
|||
|
default: 100
|
|||
|
}
|
|||
|
},
|
|||
|
data() {
|
|||
|
return {
|
|||
|
styleObject: null,
|
|||
|
specList: [],
|
|||
|
specChildList: [],
|
|||
|
skuId: this.product && this.product.sku.id,
|
|||
|
price: null,
|
|||
|
stock: null,
|
|||
|
cartCount: parseInt(this.product.min_buy, 10) || this.minNum || 1,
|
|||
|
picture: null,
|
|||
|
specSelected: [],
|
|||
|
vipPrice: this.$mAssetsPath.vipPrice,
|
|||
|
moneySymbol: this.moneySymbol,
|
|||
|
skuName: null
|
|||
|
};
|
|||
|
},
|
|||
|
computed: {
|
|||
|
currentDiscountPrice() {
|
|||
|
const decimal = 1;
|
|||
|
const discount = 2;
|
|||
|
const price = this.price;
|
|||
|
switch (parseInt(decimal, 10)) {
|
|||
|
case -1:
|
|||
|
return (price * discount / 100).toFixed(2);
|
|||
|
case 0:
|
|||
|
return (price * discount / 100).toFixed(0);
|
|||
|
case 1:
|
|||
|
return (price * discount / 100).toFixed(1);
|
|||
|
default:
|
|||
|
return (price * discount / 100).toFixed(2);
|
|||
|
}
|
|||
|
},
|
|||
|
currentProductPrice () {
|
|||
|
let price = this.price;
|
|||
|
if (this.type === 'discount') {
|
|||
|
price = this.currentSkuPrice || this.currentDiscountPrice;
|
|||
|
}
|
|||
|
if (this.type === 'group_buy') {
|
|||
|
price = this.currentSkuPrice || this.product.marketing.ladder.price;
|
|||
|
}
|
|||
|
if (this.product.memberDiscount && this.product.memberDiscount.length !== 0) {
|
|||
|
price = price * (1 - this.product.memberDiscount.discount / 100);
|
|||
|
}
|
|||
|
return parseFloat(price || '0').toFixed(2);
|
|||
|
}
|
|||
|
},
|
|||
|
async mounted() {
|
|||
|
await this.initData();
|
|||
|
},
|
|||
|
methods: {
|
|||
|
initData() {
|
|||
|
|
|||
|
this.product.skuSpecValues.forEach(item => {
|
|||
|
this.specList.push(item.spec)
|
|||
|
});
|
|||
|
|
|||
|
this.specList.forEach(item => {
|
|||
|
this.specChildList = [...this.specChildList, ...item.goodsSpecValues];
|
|||
|
|
|||
|
});
|
|||
|
|
|||
|
this.specChildList.forEach(item => {
|
|||
|
|
|||
|
if (this.product.sku.subtitle.indexOf(item.name) !== -1) {
|
|||
|
item.selected = true;
|
|||
|
|
|||
|
this.specSelected.push(item);
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
let skuStrArr = [];
|
|||
|
this.specSelected.forEach(item => {
|
|||
|
skuStrArr.push(item.name);
|
|||
|
});
|
|||
|
|
|||
|
this.product.skuList.forEach(item => {
|
|||
|
|
|||
|
if (item.subtitle === skuStrArr.join('-')) {
|
|||
|
|
|||
|
this.stock = item.stock;
|
|||
|
if (this.type === 'buy_now') {
|
|||
|
this.price = item.price;
|
|||
|
} else {
|
|||
|
// this.price = this.product.marketing_type === 'wholesale' ? item.wholesale_price : item.price;
|
|||
|
}
|
|||
|
this.skuName = item.name;
|
|||
|
this.skuId = item.id;
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
},
|
|||
|
numberChange(data) {
|
|||
|
|
|||
|
if(data==1){
|
|||
|
this.cartCount =1
|
|||
|
}else{
|
|||
|
this.cartCount = parseInt(data.number, 10);
|
|||
|
}
|
|||
|
|
|||
|
},
|
|||
|
// 选择规格
|
|||
|
selectSpec(index, pid, type) {
|
|||
|
let list = this.specChildList;
|
|||
|
|
|||
|
|
|||
|
list.forEach(item => {
|
|||
|
if (item.specId === pid) {
|
|||
|
this.$set(item, 'selected', false);
|
|||
|
}
|
|||
|
});
|
|||
|
if (parseInt(type, 10) === 3) {
|
|||
|
this.picture = list[index].data;
|
|||
|
}
|
|||
|
if (parseInt(type, 10) === 2) {
|
|||
|
this.styleObject = {
|
|||
|
color: list[index].data,
|
|||
|
border: `1px solid ${list[index].data}`
|
|||
|
};
|
|||
|
}
|
|||
|
this.$set(list[index], 'selected', true);
|
|||
|
// 存储已选择
|
|||
|
/**
|
|||
|
* 修复选择规格存储错误
|
|||
|
* 将这几行代码替换即可
|
|||
|
* 选择的规格存放在specSelected中
|
|||
|
*/
|
|||
|
this.specSelected = [];
|
|||
|
list.forEach(item => {
|
|||
|
if (item.selected === true) {
|
|||
|
this.specSelected.push(item);
|
|||
|
}
|
|||
|
});
|
|||
|
let skuStr = [];
|
|||
|
this.specSelected.forEach(item => {
|
|||
|
skuStr.push(item.name);
|
|||
|
});
|
|||
|
// console.log(this.specSelected)
|
|||
|
this.product.skuList.forEach(item => {
|
|||
|
|
|||
|
if (item.subtitle === skuStr.join('-')) {
|
|||
|
|
|||
|
this.picture = item.picture;
|
|||
|
this.stock = item.stock;
|
|||
|
this.price = this.product.marketing_type === 'wholesale' ? item.wholesale_price : item.price;
|
|||
|
this.skuId = item.id;
|
|||
|
this.skuName = item.name;
|
|||
|
}
|
|||
|
|
|||
|
});
|
|||
|
},
|
|||
|
toggleSpec(type) {
|
|||
|
if (!this.skuId) {
|
|||
|
this.$mHelper.toast('请选择规格');
|
|||
|
return;
|
|||
|
}
|
|||
|
if (this.stock < 1) {
|
|||
|
this.$mHelper.toast('库存不足');
|
|||
|
return;
|
|||
|
}
|
|||
|
this.$emit('toggle', {
|
|||
|
stock: this.stock,
|
|||
|
skuInfo:this.skuId + ',' + this.cartCount,
|
|||
|
skuId: this.skuId,
|
|||
|
cartCount: this.cartCount,
|
|||
|
skuName: this.skuName || this.singleSkuText,
|
|||
|
price: this.price,
|
|||
|
type: type
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
</script>
|
|||
|
<style scoped lang="scss">
|
|||
|
.sku-info-wrapper {
|
|||
|
width: 100%;
|
|||
|
padding-bottom: $spacing-sm;
|
|||
|
}
|
|||
|
.price-wrapper {
|
|||
|
height: 38upx;
|
|||
|
display: flex;
|
|||
|
align-items: center;
|
|||
|
margin: $spacing-sm 0;
|
|||
|
.image {
|
|||
|
width: 120upx;
|
|||
|
height: 38upx;
|
|||
|
}
|
|||
|
.base-color {
|
|||
|
margin-top: 2upx;
|
|||
|
}
|
|||
|
}
|
|||
|
.btn-group {
|
|||
|
display: flex;
|
|||
|
justify-content: space-between;
|
|||
|
.btn {
|
|||
|
width: 40vw;
|
|||
|
}
|
|||
|
}
|
|||
|
</style>
|