340 lines
8.7 KiB
JavaScript
340 lines
8.7 KiB
JavaScript
|
/* eslint-disable no-param-reassign */
|
||
|
/* eslint-disable no-nested-ternary */
|
||
|
import Toast from 'tdesign-miniprogram/toast/index';
|
||
|
|
||
|
Component({
|
||
|
options: {
|
||
|
multipleSlots: true,
|
||
|
addGlobalClass: true,
|
||
|
},
|
||
|
|
||
|
properties: {
|
||
|
src: {
|
||
|
type: String,
|
||
|
},
|
||
|
title: String,
|
||
|
show: {
|
||
|
type: Boolean,
|
||
|
value: false,
|
||
|
},
|
||
|
limitBuyInfo: {
|
||
|
type: String,
|
||
|
value: '',
|
||
|
},
|
||
|
isStock: {
|
||
|
type: Boolean,
|
||
|
value: true,
|
||
|
},
|
||
|
limitMaxCount: {
|
||
|
type: Number,
|
||
|
value: 999,
|
||
|
},
|
||
|
limitMinCount: {
|
||
|
type: Number,
|
||
|
value: 1,
|
||
|
},
|
||
|
skuList: {
|
||
|
type: Array,
|
||
|
value: [],
|
||
|
observer(skuList) {
|
||
|
if (skuList && skuList.length > 0) {
|
||
|
if (this.initStatus) {
|
||
|
this.initData();
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
},
|
||
|
specList: {
|
||
|
type: Array,
|
||
|
value: [],
|
||
|
observer(specList) {
|
||
|
if (specList && specList.length > 0) {
|
||
|
this.initData();
|
||
|
}
|
||
|
},
|
||
|
},
|
||
|
outOperateStatus: {
|
||
|
type: Boolean,
|
||
|
value: false,
|
||
|
},
|
||
|
hasAuth: {
|
||
|
type: Boolean,
|
||
|
value: false,
|
||
|
},
|
||
|
count: {
|
||
|
type: Number,
|
||
|
value: 1,
|
||
|
observer(count) {
|
||
|
this.setData({
|
||
|
buyNum: count,
|
||
|
});
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
|
||
|
initStatus: false,
|
||
|
selectedSku: {},
|
||
|
selectSpecObj: {},
|
||
|
|
||
|
data: {
|
||
|
buyNum: 1,
|
||
|
isAllSelectedSku: false,
|
||
|
},
|
||
|
|
||
|
methods: {
|
||
|
initData() {
|
||
|
const { skuList } = this.properties;
|
||
|
const { specList } = this.properties;
|
||
|
specList.forEach((item) => {
|
||
|
if (item.specValueList.length > 0) {
|
||
|
item.specValueList.forEach((subItem) => {
|
||
|
const obj = this.checkSkuStockQuantity(subItem.specValueId, skuList);
|
||
|
subItem.hasStockObj = obj;
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
const selectedSku = {};
|
||
|
specList.forEach((item) => {
|
||
|
selectedSku[item.specId] = '';
|
||
|
});
|
||
|
this.setData({
|
||
|
specList,
|
||
|
});
|
||
|
this.selectSpecObj = {};
|
||
|
this.selectedSku = {};
|
||
|
this.initStatus = true;
|
||
|
},
|
||
|
|
||
|
checkSkuStockQuantity(specValueId, skuList) {
|
||
|
let hasStock = false;
|
||
|
const array = [];
|
||
|
skuList.forEach((item) => {
|
||
|
(item.specInfo || []).forEach((subItem) => {
|
||
|
if (subItem.specValueId === specValueId && item.quantity > 0) {
|
||
|
const subArray = [];
|
||
|
(item.specInfo || []).forEach((specItem) => {
|
||
|
subArray.push(specItem.specValueId);
|
||
|
});
|
||
|
array.push(subArray);
|
||
|
hasStock = true;
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
return {
|
||
|
hasStock,
|
||
|
specsArray: array,
|
||
|
};
|
||
|
},
|
||
|
|
||
|
chooseSpecValueId(specValueId, specId) {
|
||
|
const { selectSpecObj } = this;
|
||
|
const { skuList, specList } = this.properties;
|
||
|
if (selectSpecObj[specId]) {
|
||
|
selectSpecObj[specId] = [];
|
||
|
this.selectSpecObj = selectSpecObj;
|
||
|
} else {
|
||
|
selectSpecObj[specId] = [];
|
||
|
}
|
||
|
|
||
|
const itemAllSpecArray = [];
|
||
|
const itemUnSelectArray = [];
|
||
|
const itemSelectArray = [];
|
||
|
specList.forEach((item) => {
|
||
|
if (item.specId === specId) {
|
||
|
const subSpecValueItem = item.specValueList.find((subItem) => subItem.specValueId === specValueId);
|
||
|
let specSelectStatus = false;
|
||
|
item.specValueList.forEach((n) => {
|
||
|
itemAllSpecArray.push(n.hasStockObj.specsArray);
|
||
|
if (n.isSelected) {
|
||
|
specSelectStatus = true;
|
||
|
}
|
||
|
if (n.hasStockObj.hasStock) {
|
||
|
itemSelectArray.push(n.specValueId);
|
||
|
} else {
|
||
|
itemUnSelectArray.push(n.specValueId);
|
||
|
}
|
||
|
});
|
||
|
if (specSelectStatus) {
|
||
|
selectSpecObj[specId] = this.flatten(subSpecValueItem?.hasStockObj.specsArray.concat(itemSelectArray));
|
||
|
} else {
|
||
|
const subSet = function (arr1, arr2) {
|
||
|
const set2 = new Set(arr2);
|
||
|
const subset = [];
|
||
|
arr1.forEach((val) => {
|
||
|
if (!set2.has(val)) {
|
||
|
subset.push(val);
|
||
|
}
|
||
|
});
|
||
|
return subset;
|
||
|
};
|
||
|
selectSpecObj[specId] = subSet(this.flatten(itemAllSpecArray), this.flatten(itemUnSelectArray));
|
||
|
}
|
||
|
} else {
|
||
|
// 未点击规格的逻辑
|
||
|
const itemSelectArray = [];
|
||
|
let specSelectStatus = false;
|
||
|
item.specValueList.map(
|
||
|
// 找到有库存的规格数组
|
||
|
(n) => {
|
||
|
itemSelectArray.push(n.hasStockObj.specsArray);
|
||
|
if (n.isSelected) {
|
||
|
specSelectStatus = true;
|
||
|
}
|
||
|
n.hasStockObj.hasStock = true;
|
||
|
return n;
|
||
|
},
|
||
|
);
|
||
|
if (specSelectStatus) {
|
||
|
selectSpecObj[item.specId] = this.flatten(itemSelectArray);
|
||
|
} else {
|
||
|
delete selectSpecObj[item.specId];
|
||
|
}
|
||
|
}
|
||
|
this.selectSpecObj = selectSpecObj;
|
||
|
});
|
||
|
const combatArray = Object.values(selectSpecObj);
|
||
|
if (combatArray.length > 0) {
|
||
|
const showArray = combatArray.reduce((x, y) => this.getIntersection(x, y));
|
||
|
const lastResult = Array.from(new Set(showArray));
|
||
|
specList.forEach((item) => {
|
||
|
item.specValueList.forEach((subItem) => {
|
||
|
if (lastResult.includes(subItem.specValueId)) {
|
||
|
subItem.hasStockObj.hasStock = true;
|
||
|
} else {
|
||
|
subItem.hasStockObj.hasStock = false;
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
} else {
|
||
|
specList.forEach((item) => {
|
||
|
if (item.specValueList.length > 0) {
|
||
|
item.specValueList.forEach((subItem) => {
|
||
|
const obj = this.checkSkuStockQuantity(subItem.specValueId, skuList);
|
||
|
subItem.hasStockObj = obj;
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
this.setData({
|
||
|
specList,
|
||
|
});
|
||
|
},
|
||
|
|
||
|
flatten(input) {
|
||
|
const stack = [...input];
|
||
|
const res = [];
|
||
|
while (stack.length) {
|
||
|
const next = stack.pop();
|
||
|
if (Array.isArray(next)) {
|
||
|
stack.push(...next);
|
||
|
} else {
|
||
|
res.push(next);
|
||
|
}
|
||
|
}
|
||
|
return res.reverse();
|
||
|
},
|
||
|
|
||
|
getIntersection(array, nextArray) {
|
||
|
return array.filter((item) => nextArray.includes(item));
|
||
|
},
|
||
|
|
||
|
toChooseItem(e) {
|
||
|
const { isStock } = this.properties;
|
||
|
if (!isStock) return;
|
||
|
const { id } = e.currentTarget.dataset;
|
||
|
const specId = e.currentTarget.dataset.specid;
|
||
|
const hasStock = e.currentTarget.dataset.hasstock;
|
||
|
if (!hasStock) {
|
||
|
Toast({
|
||
|
context: this,
|
||
|
selector: '#t-toast',
|
||
|
message: '该规格已售罄',
|
||
|
icon: '',
|
||
|
duration: 1000,
|
||
|
});
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
let { selectedSku } = this;
|
||
|
const { specList } = this.properties;
|
||
|
selectedSku =
|
||
|
selectedSku[specId] === id ? { ...this.selectedSku, [specId]: '' } : { ...this.selectedSku, [specId]: id };
|
||
|
specList.forEach((item) => {
|
||
|
item.specValueList.forEach((valuesItem) => {
|
||
|
if (item.specId === specId) {
|
||
|
valuesItem.isSelected = valuesItem.specValueId === selectedSku[specId];
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
this.chooseSpecValueId(id, specId);
|
||
|
const isAllSelectedSku = this.isAllSelected(specList, selectedSku);
|
||
|
if (!isAllSelectedSku) {
|
||
|
this.setData({
|
||
|
selectSkuSellsPrice: 0,
|
||
|
selectSkuImg: '',
|
||
|
});
|
||
|
}
|
||
|
this.setData({
|
||
|
specList,
|
||
|
isAllSelectedSku,
|
||
|
});
|
||
|
this.selectedSku = selectedSku;
|
||
|
this.triggerEvent('change', {
|
||
|
specList,
|
||
|
selectedSku,
|
||
|
isAllSelectedSku,
|
||
|
});
|
||
|
},
|
||
|
|
||
|
// 判断是否所有的sku都已经选中
|
||
|
isAllSelected(skuTree, selectedSku) {
|
||
|
const selected = Object.keys(selectedSku).filter((skuKeyStr) => selectedSku[skuKeyStr] !== '');
|
||
|
return skuTree.length === selected.length;
|
||
|
},
|
||
|
|
||
|
handlePopupHide() {
|
||
|
this.triggerEvent('closeSpecsPopup', {
|
||
|
show: false,
|
||
|
});
|
||
|
},
|
||
|
|
||
|
specsConfirm() {
|
||
|
const { isStock } = this.properties;
|
||
|
if (!isStock) return;
|
||
|
this.triggerEvent('specsConfirm');
|
||
|
},
|
||
|
|
||
|
addCart() {
|
||
|
const { isStock } = this.properties;
|
||
|
if (!isStock) return;
|
||
|
this.triggerEvent('addCart');
|
||
|
},
|
||
|
|
||
|
buyNow() {
|
||
|
const { isAllSelectedSku } = this.data;
|
||
|
const { isStock } = this.properties;
|
||
|
if (!isStock) return;
|
||
|
this.triggerEvent('buyNow', {
|
||
|
isAllSelectedSku,
|
||
|
});
|
||
|
},
|
||
|
|
||
|
// 总处理
|
||
|
setBuyNum(buyNum) {
|
||
|
this.setData({
|
||
|
buyNum,
|
||
|
});
|
||
|
this.triggerEvent('changeNum', {
|
||
|
buyNum,
|
||
|
});
|
||
|
},
|
||
|
|
||
|
handleBuyNumChange(e) {
|
||
|
const { value } = e.detail;
|
||
|
this.setData({
|
||
|
buyNum: value,
|
||
|
});
|
||
|
},
|
||
|
},
|
||
|
});
|