feat: 客服
This commit is contained in:
@@ -47,7 +47,8 @@
|
||||
}}</text>
|
||||
<text class="price_o">¥{{ orderInfo.adPrice }}</text>
|
||||
</view>
|
||||
<view class="text-24" style="color: #ff5a5a; height: 38rpx; display: flex; align-items: center; gap: 5rpx" v-if="orderInfo?.goodsTagList">
|
||||
<view class="text-24" style="color: #ff5a5a; height: 38rpx; display: flex; align-items: center; gap: 5rpx"
|
||||
v-if="orderInfo?.goodsTagList">
|
||||
<image v-for="val in orderInfo.goodsTagList" :src="val.icon" mode="heightFix" style="height: 38rpx">
|
||||
</image>
|
||||
</view>
|
||||
@@ -232,13 +233,13 @@
|
||||
<view v-for="(item, index) in specificationList" :key="item.id" class="list_warp">
|
||||
<view class="list_title_warp">{{ item.type }}</view>
|
||||
<view class="specification_item_warp">
|
||||
<view :class="oItem.inventory === 0
|
||||
<view :class="oItem.disabled || oItem.inventory === 0
|
||||
? 'item_Warp item_Warp_no_warp'
|
||||
: item.selectVal === oItem.n
|
||||
? 'item_Warp item_Warp_yes_warp'
|
||||
: 'item_Warp'
|
||||
" v-for="(oItem, oIndex) in item.items" :key="oItem.n"
|
||||
@click="clickSpecification(oIndex, item, oItem)">
|
||||
" v-for="(oItem, oIndex) in item.items" :key="oItem.id || oItem.n"
|
||||
@click="clickSpecification(index, item, oItem)">
|
||||
{{ oItem.n }}
|
||||
</view>
|
||||
</view>
|
||||
@@ -338,7 +339,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getGoodsDetail, addGoods, getGoodsSpecs } from "@/api/product.js";
|
||||
import { getGoodsDetail, addGoods, getGoodsSpecs, getGoodsSpecsInfo } from "@/api/product.js";
|
||||
import { getValue, PRODUCT_DELIVERY_TIME, ACTIVITY_TYPE } from "@/utils/enumUtils.js";
|
||||
import { copyData } from "@/utils/index.js";
|
||||
import Evaluation from "@/pages/other_package/productInfo/evaluation.vue";
|
||||
@@ -395,6 +396,8 @@ export default {
|
||||
selectSpecification: [], // 选择的规格
|
||||
specificationTempl: [], // 规格模版数据
|
||||
selectSpecificationTempl: {}, // 选择规格模版数据
|
||||
selectedSpecValueIds: [],
|
||||
skuBySpecKey: {},
|
||||
serviceShow: false, // 联系客服弹框
|
||||
openShow: false,
|
||||
source: null, // 来源:供应链,自营
|
||||
@@ -518,8 +521,17 @@ export default {
|
||||
if (this.isShareUrl) {
|
||||
return;
|
||||
}
|
||||
uni.setStorageSync("kefu-pending-context", {
|
||||
type: "product",
|
||||
data: {
|
||||
goodsId: this.id,
|
||||
goodsName: this.orderInfo.name,
|
||||
goodsMainGraph: this.orderInfo.mainGraph,
|
||||
currentPrice: this.orderInfo.adPrice,
|
||||
},
|
||||
});
|
||||
uni.navigateTo({
|
||||
url: "/pages/rwa_package/setting/kefu?type=5260",
|
||||
url: `/pages/rwa_package/setting/kefu?scene=product&goodsId=${this.id}`,
|
||||
});
|
||||
},
|
||||
getValue,
|
||||
@@ -858,7 +870,6 @@ export default {
|
||||
const resp = await getGoodsDetail(params);
|
||||
if (resp && resp.bizcode === 100) {
|
||||
const data = resp.data;
|
||||
|
||||
// 限时秒杀 和 积分兑换 不需要购物车
|
||||
this.isShowCart = this.activedType === 'seckill' || data.type == 3 ? 1 : 0;
|
||||
// 商品图
|
||||
@@ -939,9 +950,11 @@ export default {
|
||||
}
|
||||
// 需要查询一下最新的规格
|
||||
if (val) {
|
||||
await this.querySpecification();
|
||||
const data = this.orderInfo;
|
||||
this.getSpecification(data.specs);
|
||||
const hasStructuredSpecs = await this.querySpecification();
|
||||
if (!hasStructuredSpecs) {
|
||||
uni.showToast({ title: "SKU规格加载失败,请稍后重试", icon: "none" });
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
this.specificationList = []; //规格
|
||||
this.selectSpecification = []; // 选择的规格
|
||||
@@ -950,66 +963,138 @@ export default {
|
||||
this.specificationShow = val;
|
||||
this.specificationShowType = type;
|
||||
},
|
||||
// 拆解规格
|
||||
getSpecification(specs) {
|
||||
const optionArr = [];
|
||||
if (specs) {
|
||||
const arr = JSON.parse(specs);
|
||||
arr.map((item) => {
|
||||
optionArr.push({
|
||||
type: item.type,
|
||||
items: item.items,
|
||||
selectVal: null,
|
||||
});
|
||||
});
|
||||
}
|
||||
this.specificationList = optionArr;
|
||||
},
|
||||
// 获取规格模版数据
|
||||
async querySpecification() {
|
||||
const params = {
|
||||
id: this.id,
|
||||
};
|
||||
if (this.isCoupon) {
|
||||
params.type = -1;
|
||||
let infoResp = null;
|
||||
try {
|
||||
infoResp = await getGoodsSpecsInfo({ id: this.id });
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
if (this.activedType == "seckill") {
|
||||
params["activityType"] = this.activedType; // 活动类型
|
||||
params["activityId"] = this.activityId;// 秒杀活动ID
|
||||
if (!infoResp || infoResp.bizcode !== 100 || !infoResp.data) {
|
||||
return false;
|
||||
}
|
||||
const resp = await getGoodsSpecs(params);
|
||||
if (resp && resp.bizcode === 100) {
|
||||
const data = resp.data;
|
||||
let stock = 0;
|
||||
data.map((item) => {
|
||||
stock = stock + item.stock;
|
||||
const groups = infoResp.data.specGroups || [];
|
||||
const skus = infoResp.data.skus || [];
|
||||
if (!groups.length || !skus.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const skuBySpecKey = {};
|
||||
skus.forEach((sku) => {
|
||||
const valueIds = this.getSkuValueIds(sku, groups);
|
||||
if (valueIds.length !== groups.length) {
|
||||
return;
|
||||
}
|
||||
const normalizedSku = Object.assign({}, sku, {
|
||||
id: sku.id,
|
||||
valueIds,
|
||||
minBuyNum: sku.minBuyNum || 1,
|
||||
combTypes: this.formatSkuSelection(groups, valueIds),
|
||||
});
|
||||
this.specificationTempl = data;
|
||||
this.orderInfo.inventory = stock; // 库存
|
||||
skuBySpecKey[valueIds.join("_")] = normalizedSku;
|
||||
});
|
||||
if (!Object.keys(skuBySpecKey).length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.skuBySpecKey = skuBySpecKey;
|
||||
this.specificationTempl = Object.keys(skuBySpecKey).map((key) => skuBySpecKey[key]);
|
||||
this.orderInfo.inventory = this.specificationTempl.reduce(
|
||||
(total, sku) => total + Number(sku.stock || 0),
|
||||
0
|
||||
);
|
||||
this.selectedSpecValueIds = groups.map(() => null);
|
||||
this.selectSpecification = groups.map(() => null);
|
||||
this.selectSpecificationTempl = {};
|
||||
this.specificationList = groups.map((group) => ({
|
||||
id: group.id,
|
||||
type: group.name,
|
||||
selectVal: null,
|
||||
items: (group.values || []).map((value) => ({
|
||||
id: value.id,
|
||||
groupId: group.id,
|
||||
n: value.name,
|
||||
image: value.image,
|
||||
disabled: false,
|
||||
})),
|
||||
}));
|
||||
this.refreshSpecOptionState();
|
||||
return true;
|
||||
},
|
||||
|
||||
getSkuValueIds(sku, groups) {
|
||||
if (sku.specValueIds) {
|
||||
try {
|
||||
const ids = JSON.parse(sku.specValueIds);
|
||||
if (Array.isArray(ids)) {
|
||||
return ids.map((id) => Number(id));
|
||||
}
|
||||
} catch (e) { }
|
||||
}
|
||||
let path = {};
|
||||
try {
|
||||
path = JSON.parse(sku.specValuePath || "{}") || {};
|
||||
} catch (e) { }
|
||||
const legacyValues = String(path.legacyName || "")
|
||||
.split(/\s*(?:\/|♧)\s*/)
|
||||
.filter(Boolean);
|
||||
return groups.map((group, index) => {
|
||||
const selectedName = path[group.name] || legacyValues[index];
|
||||
const value = (group.values || []).find((item) => item.name === selectedName);
|
||||
return value ? Number(value.id) : null;
|
||||
}).filter((id) => id !== null);
|
||||
},
|
||||
|
||||
formatSkuSelection(groups, valueIds) {
|
||||
return groups.map((group, index) => {
|
||||
const value = (group.values || []).find((item) => Number(item.id) === Number(valueIds[index]));
|
||||
return value ? `${group.name}:${value.name}` : "";
|
||||
}).filter(Boolean).join(";");
|
||||
},
|
||||
|
||||
refreshSpecOptionState() {
|
||||
this.specificationList.forEach((group, groupIndex) => {
|
||||
group.items.forEach((value) => {
|
||||
const candidate = this.selectedSpecValueIds.slice();
|
||||
candidate[groupIndex] = Number(value.id);
|
||||
value.disabled = !Object.keys(this.skuBySpecKey).some((key) => {
|
||||
const sku = this.skuBySpecKey[key];
|
||||
const skuIds = sku.valueIds || [];
|
||||
return candidate.every((selectedId, index) =>
|
||||
selectedId == null || Number(skuIds[index]) === Number(selectedId)
|
||||
) && Number(sku.stock || 0) > 0;
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
//改变规格的样式
|
||||
clickSpecification(pIndex, item, oItem) {
|
||||
clickSpecification(groupIndex, item, oItem) {
|
||||
console.log(
|
||||
"改变规格的样式",
|
||||
pIndex,
|
||||
groupIndex,
|
||||
item,
|
||||
oItem,
|
||||
this.specificationTempl,
|
||||
this.specificationList
|
||||
);
|
||||
|
||||
const currentSelectSpecification = this.specificationTempl[pIndex];
|
||||
if (oItem.disabled) {
|
||||
return;
|
||||
}
|
||||
this.selectedSpecValueIds.splice(groupIndex, 1, Number(oItem.id));
|
||||
this.selectSpecification.splice(groupIndex, 1, oItem.n);
|
||||
this.specificationList[groupIndex].selectVal = oItem.n;
|
||||
this.refreshSpecOptionState();
|
||||
|
||||
console.log("当前规格", currentSelectSpecification);
|
||||
this.orderInfo.quantity = currentSelectSpecification?.minBuyNum || 1;
|
||||
|
||||
this.specificationList[0].selectVal = oItem.n;
|
||||
|
||||
this.selectSpecificationTempl = currentSelectSpecification;
|
||||
this.orderInfo.inventory = currentSelectSpecification.stock; // 库存
|
||||
// 计算规格的价格
|
||||
// this.selectSpecificationFun(pIndex, oItem);
|
||||
if (this.selectedSpecValueIds.every((id) => id != null)) {
|
||||
const currentSelectSpecification = this.skuBySpecKey[this.selectedSpecValueIds.join("_")] || {};
|
||||
this.selectSpecificationTempl = currentSelectSpecification;
|
||||
this.orderInfo.quantity = currentSelectSpecification.minBuyNum || 1;
|
||||
this.orderInfo.inventory = currentSelectSpecification.stock || 0;
|
||||
} else {
|
||||
this.selectSpecificationTempl = {};
|
||||
}
|
||||
},
|
||||
// 选择规格
|
||||
selectSpecificationFun(index, item) {
|
||||
|
||||
Reference in New Issue
Block a user