jiuyiUniapp/shop/components/rf-attr-content/index.vue

321 lines
7.7 KiB
Vue
Raw Normal View History

2024-12-18 15:46:27 +08:00
<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>