274 lines
7.0 KiB
JavaScript
274 lines
7.0 KiB
JavaScript
|
|
import { fetchGood } from '../../../../services/good/fetchGood';
|
|||
|
|
import Toast from 'tdesign-miniprogram/toast/index';
|
|||
|
|
|
|||
|
|
Component({
|
|||
|
|
options: {
|
|||
|
|
addGlobalClass: true,
|
|||
|
|
multipleSlots: true, // 在组件定义时的选项中启用多slot支持
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
properties: {
|
|||
|
|
show: {
|
|||
|
|
type: Boolean,
|
|||
|
|
value: false,
|
|||
|
|
observer(newVal) {
|
|||
|
|
if (newVal && this.data.spuId) {
|
|||
|
|
this.loadProductDetail();
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
spuId: {
|
|||
|
|
type: String,
|
|||
|
|
value: '',
|
|||
|
|
},
|
|||
|
|
skuId: {
|
|||
|
|
type: String,
|
|||
|
|
value: '',
|
|||
|
|
},
|
|||
|
|
value: {
|
|||
|
|
type: String,
|
|||
|
|
value: '',
|
|||
|
|
},
|
|||
|
|
title: {
|
|||
|
|
type: String,
|
|||
|
|
observer(newVal) {
|
|||
|
|
this.setData({ 'goods.title': newVal });
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
price: {
|
|||
|
|
type: String,
|
|||
|
|
value: '',
|
|||
|
|
observer(newVal) {
|
|||
|
|
this.setData({ 'goods.price': newVal });
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
thumb: {
|
|||
|
|
type: String,
|
|||
|
|
value: '',
|
|||
|
|
observer(newVal) {
|
|||
|
|
this.setData({ 'goods.thumb': newVal });
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
thumbMode: {
|
|||
|
|
type: String,
|
|||
|
|
value: 'aspectFit',
|
|||
|
|
},
|
|||
|
|
zIndex: {
|
|||
|
|
type: Number,
|
|||
|
|
value: 99,
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
data: {
|
|||
|
|
goods: {
|
|||
|
|
title: '',
|
|||
|
|
thumb: '',
|
|||
|
|
price: '',
|
|||
|
|
hideKey: {
|
|||
|
|
originPrice: true,
|
|||
|
|
tags: true,
|
|||
|
|
specs: true,
|
|||
|
|
num: true,
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
specList: [],
|
|||
|
|
skuList: [],
|
|||
|
|
selectedSku: {},
|
|||
|
|
isAllSelectedSku: false,
|
|||
|
|
selectSkuSellsPrice: 0,
|
|||
|
|
currentPrice: '',
|
|||
|
|
buyNum: 1,
|
|||
|
|
loading: false,
|
|||
|
|
},
|
|||
|
|
methods: {
|
|||
|
|
async loadProductDetail() {
|
|||
|
|
const { spuId, skuId } = this.data;
|
|||
|
|
if (!spuId) return;
|
|||
|
|
|
|||
|
|
this.setData({ loading: true });
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
const detail = await fetchGood(spuId);
|
|||
|
|
const { specList = [], skuList = [], minSalePrice } = detail;
|
|||
|
|
|
|||
|
|
// 处理SKU数据
|
|||
|
|
const skuArray = skuList.map((sku) => ({
|
|||
|
|
...sku,
|
|||
|
|
specInfo: sku.specInfo || [],
|
|||
|
|
quantity: Number(
|
|||
|
|
(sku.stockInfo && sku.stockInfo.stockQuantity) || sku.stock || sku.quantity || 0
|
|||
|
|
),
|
|||
|
|
price: Number((sku.priceInfo && sku.priceInfo[0] && sku.priceInfo[0].price) || sku.price || 0),
|
|||
|
|
skuId: sku.skuId || sku.id,
|
|||
|
|
}));
|
|||
|
|
|
|||
|
|
// 初始化规格选择,默认选中当前SKU
|
|||
|
|
this.initSpecSelection(specList, skuArray, skuId);
|
|||
|
|
|
|||
|
|
this.setData({
|
|||
|
|
specList,
|
|||
|
|
skuList: skuArray,
|
|||
|
|
selectSkuSellsPrice: minSalePrice,
|
|||
|
|
currentPrice: minSalePrice,
|
|||
|
|
loading: false,
|
|||
|
|
});
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('加载商品详情失败:', error);
|
|||
|
|
Toast({
|
|||
|
|
context: this,
|
|||
|
|
selector: '#t-toast',
|
|||
|
|
message: '加载失败,请重试',
|
|||
|
|
theme: 'error',
|
|||
|
|
});
|
|||
|
|
this.setData({ loading: false });
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
initSpecSelection(specList, skuArray, currentSkuId) {
|
|||
|
|
const selectedSku = {};
|
|||
|
|
|
|||
|
|
// 查找当前SKU
|
|||
|
|
const currentSku = skuArray.find(sku => String(sku.skuId) === String(currentSkuId));
|
|||
|
|
|
|||
|
|
console.log('[初始化规格] 当前SKU ID:', currentSkuId);
|
|||
|
|
console.log('[初始化规格] 匹配的SKU:', currentSku);
|
|||
|
|
|
|||
|
|
if (currentSku && Array.isArray(currentSku.specInfo)) {
|
|||
|
|
// 标记当前SKU的规格为选中
|
|||
|
|
currentSku.specInfo.forEach((spec) => {
|
|||
|
|
const specId = spec.specId;
|
|||
|
|
const specValueId = spec.specValueId;
|
|||
|
|
|
|||
|
|
specList.forEach((group) => {
|
|||
|
|
if (String(group.specId) === String(specId)) {
|
|||
|
|
group.specValueList.forEach((sv) => {
|
|||
|
|
sv.isSelected = String(sv.specValueId) === String(specValueId);
|
|||
|
|
});
|
|||
|
|
selectedSku[group.specId] = specValueId;
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const isAllSelectedSku = specList.every((spec) => !!selectedSku[spec.specId]);
|
|||
|
|
|
|||
|
|
// 更新价格
|
|||
|
|
const initPrice = currentSku ? currentSku.price : (skuArray[0] ? skuArray[0].price : 0);
|
|||
|
|
console.log('[初始化规格] 初始价格:', initPrice);
|
|||
|
|
|
|||
|
|
this.setData({
|
|||
|
|
selectedSku,
|
|||
|
|
isAllSelectedSku,
|
|||
|
|
selectSkuSellsPrice: initPrice,
|
|||
|
|
currentPrice: initPrice,
|
|||
|
|
'goods.price': initPrice,
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
toChooseItem(e) {
|
|||
|
|
const { specid, id } = e.currentTarget.dataset;
|
|||
|
|
const { specList, skuList } = this.data;
|
|||
|
|
|
|||
|
|
// 更新选中状态
|
|||
|
|
specList.forEach((spec) => {
|
|||
|
|
if (String(spec.specId) === String(specid)) {
|
|||
|
|
spec.specValueList.forEach((specValue) => {
|
|||
|
|
specValue.isSelected = String(specValue.specValueId) === String(id);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 更新selectedSku
|
|||
|
|
const selectedSku = { ...this.data.selectedSku };
|
|||
|
|
selectedSku[specid] = id;
|
|||
|
|
|
|||
|
|
const isAllSelectedSku = specList.every((spec) => !!selectedSku[spec.specId]);
|
|||
|
|
|
|||
|
|
this.setData({
|
|||
|
|
specList,
|
|||
|
|
selectedSku,
|
|||
|
|
isAllSelectedSku,
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 查找SKU并更新价格
|
|||
|
|
if (isAllSelectedSku) {
|
|||
|
|
const matchedSku = this.findMatchedSku(selectedSku, skuList);
|
|||
|
|
if (matchedSku) {
|
|||
|
|
console.log('[SKU选择] 匹配SKU:', matchedSku);
|
|||
|
|
console.log('[SKU选择] SKU价格:', matchedSku.price);
|
|||
|
|
this.setData({
|
|||
|
|
selectSkuSellsPrice: matchedSku.price,
|
|||
|
|
currentPrice: matchedSku.price,
|
|||
|
|
'goods.price': matchedSku.price,
|
|||
|
|
});
|
|||
|
|
} else {
|
|||
|
|
console.warn('[SKU选择] 未找到匹配SKU');
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
findMatchedSku(selectedSku, skuList) {
|
|||
|
|
return skuList.find((sku) => {
|
|||
|
|
if (!sku.specInfo || sku.specInfo.length === 0) return false;
|
|||
|
|
|
|||
|
|
return sku.specInfo.every((spec) => {
|
|||
|
|
const specId = String(spec.specId);
|
|||
|
|
const specValueId = String(spec.specValueId);
|
|||
|
|
const selectedSpecValueId = String(selectedSku[specId] || '');
|
|||
|
|
return selectedSpecValueId === specValueId;
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onClose() {
|
|||
|
|
this.triggerEvent('close');
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onConfirm() {
|
|||
|
|
const { isAllSelectedSku, selectedSku, skuList, spuId, buyNum } = this.data;
|
|||
|
|
|
|||
|
|
if (!isAllSelectedSku) {
|
|||
|
|
Toast({
|
|||
|
|
context: this,
|
|||
|
|
selector: '#t-toast',
|
|||
|
|
message: '请选择完整的商品规格',
|
|||
|
|
theme: 'warning',
|
|||
|
|
});
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 查找匹配SKU
|
|||
|
|
const matchedSku = this.findMatchedSku(selectedSku, skuList);
|
|||
|
|
|
|||
|
|
if (!matchedSku) {
|
|||
|
|
Toast({
|
|||
|
|
context: this,
|
|||
|
|
selector: '#t-toast',
|
|||
|
|
message: '该规格不存在',
|
|||
|
|
theme: 'error',
|
|||
|
|
});
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 触发confirm事件,传递数量
|
|||
|
|
this.triggerEvent('confirm', {
|
|||
|
|
spuId,
|
|||
|
|
skuId: matchedSku.skuId,
|
|||
|
|
price: matchedSku.price,
|
|||
|
|
quantity: buyNum,
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
handleBuyNumChange(e) {
|
|||
|
|
const { value } = e.detail;
|
|||
|
|
this.setData({
|
|||
|
|
buyNum: value,
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onCloseOver() {
|
|||
|
|
this.triggerEvent('closeover');
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
});
|