feat(商品属性): 多 sku

This commit is contained in:
unknown 2024-06-12 00:32:45 +08:00
parent 3f51efcebe
commit 1c71006dc5
1 changed files with 214 additions and 191 deletions

View File

@ -1,97 +1,108 @@
import { ref, computed } from 'vue' import { ref, computed } from "vue";
import { onLoad } from '@dcloudio/uni-app' import { onLoad } from "@dcloudio/uni-app";
import peach from '@/peach' import peach from "@/peach";
import GoodsApi from '@/peach/api/trade/goods' import GoodsApi from "@/peach/api/trade/goods";
import { SPEC_TYPE, SKU_RULE_CONFIG } from './config' import { SPEC_TYPE, SKU_RULE_CONFIG } from "./config";
const pickerRef = ref(null) const pickerRef = ref(null);
// 多属性商品 sku 列表 // 多属性商品 sku 列表
const skus = ref([]) const skus = ref([]);
const propertyList = ref([]) const propertyList = ref([]);
const goodsPropertyList = ref([]) const goodsPropertyList = ref([]);
const propertyListRef = ref(null) const propertyListRef = ref(null);
const canEdit = computed(() => peach.$store('trade').canEdit) const canEdit = computed(() => peach.$store("trade").canEdit);
const formData = ref({ const formData = ref({
specType: true, specType: true,
specText: SPEC_TYPE[0].label, specText: SPEC_TYPE[0].label,
}) });
async function showPropertyList() { async function showPropertyList() {
await getGoodsProperty() await getGoodsProperty();
propertyListRef.value.onOpen() propertyListRef.value.onOpen();
} }
function onRDPickerConfirm(e) { function onRDPickerConfirm(e) {
formData.value.specType = SPEC_TYPE[e.value[0]].value formData.value.specType = SPEC_TYPE[e.value[0]].value;
formData.value.specText = SPEC_TYPE[e.value[0]].label formData.value.specText = SPEC_TYPE[e.value[0]].label;
// 如果商品规格不一致,则需要重新初始化 sku 列表 // 如果商品规格不一致,则需要重新初始化 sku 列表
initSku() initSku();
peach.$store('trade').specType = SPEC_TYPE[e.value[0]].value peach.$store("trade").specType = SPEC_TYPE[e.value[0]].value;
} }
function pickerProperty() { function pickerProperty() {
if (canEdit.value) { if (canEdit.value) {
let index = formData.value.specType ? 1 : 0 let index = formData.value.specType ? 1 : 0;
console.log(index) console.log(index);
pickerRef.value.onOpen([index]) pickerRef.value.onOpen([index]);
} }
} }
async function onPropertyConfirm(e) { async function onPropertyConfirm(e) {
await getGoodsProperty() await getGoodsProperty();
console.log(e) console.log(e);
} }
function onConfirm() { function onConfirm() {
console.log(skus.value) console.log(skus.value);
} }
async function getGoodsProperty() { async function getGoodsProperty() {
let { data } = await GoodsApi.getHistoryProperty() let { data } = await GoodsApi.getHistoryProperty();
// 把 propertyList 中 id 相同的属性合并,并去重 // 把 propertyList 中 id 相同的属性合并,并去重
propertyList.value = peach.$store('trade').selectedProperty propertyList.value = peach.$store("trade").selectedProperty;
console.log(propertyList.value) console.log(propertyList.value);
if (propertyList.value) {
// 根据已经选择数据,设置默认选中 // 根据已经选择数据,设置默认选中
data.forEach((item) => { data.forEach((item) => {
// 判断属性是否已经选中 // 判断属性是否已经选中
let propertyParent = propertyList.value.find((sitem) => sitem?.id === item.id) let propertyParent = propertyList.value.find(
(sitem) => sitem?.id === item.id
);
item.checked = propertyParent ? true : false item.checked = propertyParent ? true : false;
// 如果属性已经选中,查询子类中是否有选中 // 如果属性已经选中,查询子类中是否有选中
if (item.checked) { if (item.checked) {
item.propertyValues.forEach((child) => { item.propertyValues.forEach((child) => {
let childResult = propertyParent?.children.some((schild) => schild === child.id) let childResult = propertyParent?.children.some(
child.checked = childResult ? true : false (schild) => schild === child.id
}) );
child.checked = childResult ? true : false;
});
} }
}) });
goodsPropertyList.value = data goodsPropertyList.value = data;
console.log(goodsPropertyList.value) } else {
goodsPropertyList.value = [];
}
console.log(goodsPropertyList.value);
} }
function changeSubProperty() { function changeSubProperty() {
// 修改子属性状态,需要同步更新 skus 的显示 // 修改子属性状态,需要同步更新 skus 的显示
console.log(goodsPropertyList.value) console.log(goodsPropertyList.value);
// 过滤父属性 checked 选项,深拷贝避免后面循环改变元数据内容 // 过滤父属性 checked 选项,深拷贝避免后面循环改变元数据内容
let temp = JSON.parse(JSON.stringify(goodsPropertyList.value.filter((item) => item.checked))) let temp = JSON.parse(
JSON.stringify(goodsPropertyList.value.filter((item) => item.checked))
);
temp.forEach((item) => { temp.forEach((item) => {
item.propertyValues = item.propertyValues.filter((child) => child.checked) item.propertyValues = item.propertyValues.filter((child) => child.checked);
}) });
let result = temp.map((item) => { let result = temp.map((item) => {
return item.propertyValues.map((child) => ({ return item.propertyValues.map((child) => ({
@ -99,15 +110,15 @@ function changeSubProperty() {
propertyName: item.name, propertyName: item.name,
valueId: child.id, valueId: child.id,
valueName: child.name, valueName: child.name,
})) }));
}) });
let tempSkus = [] let tempSkus = [];
for (let item of reduceArr(result)) { for (let item of reduceArr(result)) {
let obj = { let obj = {
picUrl: '', picUrl: "",
barCode: '', barCode: "",
price: 0, price: 0,
marketPrice: 0, marketPrice: 0,
costPrice: 0, costPrice: 0,
@ -115,11 +126,11 @@ function changeSubProperty() {
weight: 0, weight: 0,
volume: 0, volume: 0,
properties: item, properties: item,
} };
tempSkus.push(obj) tempSkus.push(obj);
} }
skus.value = tempSkus skus.value = tempSkus;
} }
/** /**
@ -132,8 +143,8 @@ function initSku() {
// 单规格 // 单规格
if (!formData.value.specType) { if (!formData.value.specType) {
let obj = { let obj = {
picUrl: '', picUrl: "",
barCode: '', barCode: "",
price: 0, price: 0,
marketPrice: 0, marketPrice: 0,
costPrice: 0, costPrice: 0,
@ -143,17 +154,17 @@ function initSku() {
properties: [ properties: [
{ {
propertyId: 0, propertyId: 0,
propertyName: '默认', propertyName: "默认",
valueId: 0, valueId: 0,
valueName: '默认', valueName: "默认",
}, },
], ],
} };
skus.value = [obj] skus.value = [obj];
} else { } else {
// 多规格 // 多规格
skus.value = [] skus.value = [];
} }
} }
@ -165,96 +176,108 @@ function initSku() {
*/ */
function submitProperty() { function submitProperty() {
try { try {
validateSku(skus.value) validateSku(skus.value);
peach.$store('trade').skus = skus.value peach.$store("trade").skus = skus.value;
peach.$router.back() peach.$router.back();
} catch (e) { } catch (e) {
console.log(skus.value) console.log(skus.value);
console.log(e, '校验失败') console.log(e, "校验失败");
} }
} }
function validateSku(skus) { function validateSku(skus) {
let warningInfo = '请检查商品各行相关属性配置,' let warningInfo = "请检查商品各行相关属性配置,";
let validateStatue = true let validateStatue = true;
let skusValue = skus ?? peach.$store('trade').skus let skusValue = skus ?? peach.$store("trade").skus;
// 判断如果是多规格,并且 skusValue 为空 [],则提示
if (formData.value.specType && skusValue.length < 1) {
uni.showToast({
title: "请选择商品规格",
icon: "none",
duration: 4000,
});
throw new Error("请选择商品规格");
}
for (const sku of skusValue) { for (const sku of skusValue) {
for (const rule of SKU_RULE_CONFIG) { for (const rule of SKU_RULE_CONFIG) {
const arg = getValue(sku, rule.name) const arg = getValue(sku, rule.name);
if (!rule.rule(arg)) { if (!rule.rule(arg)) {
validateStatue = false validateStatue = false;
warningInfo += rule.message warningInfo += rule.message;
break break;
} }
} }
if (!validateStatue) { if (!validateStatue) {
uni.showToast({ uni.showToast({
title: warningInfo, title: warningInfo,
icon: 'none', icon: "none",
duration: 4000, duration: 4000,
}) });
throw new Error(warningInfo) throw new Error(warningInfo);
} }
} }
} }
function getValue(obj, arg) { function getValue(obj, arg) {
const keys = arg.split('.') const keys = arg.split(".");
let value = obj let value = obj;
for (const key of keys) { for (const key of keys) {
if (value && typeof value === 'object' && key in value) { if (value && typeof value === "object" && key in value) {
value = value[key] value = value[key];
} else { } else {
value = undefined value = undefined;
break break;
} }
} }
return value return value;
} }
function reduceArr(arr) { function reduceArr(arr) {
return arr.reduce((acc, cur) => { return arr.reduce((acc, cur) => {
let tempAcc = [] let tempAcc = [];
if (acc.length < 1) { if (acc.length < 1) {
cur.forEach((item, index) => { cur.forEach((item, index) => {
if (tempAcc[index]) { if (tempAcc[index]) {
tempAcc[index].push(item) tempAcc[index].push(item);
} else { } else {
tempAcc[index] = [item] tempAcc[index] = [item];
} }
}) });
} else { } else {
acc.forEach((item, index) => { acc.forEach((item, index) => {
cur.forEach((sitem, sindex) => { cur.forEach((sitem, sindex) => {
tempAcc.push([...item, sitem]) tempAcc.push([...item, sitem]);
}) });
}) });
if (cur.length < 1) { if (cur.length < 1) {
tempAcc = acc tempAcc = acc;
} }
} }
return tempAcc return tempAcc;
}, []) }, []);
} }
const specType = computed(() => peach.$store('trade').goodsInfo?.specType || false) const specType = computed(
() => peach.$store("trade").goodsInfo?.specType || false
);
function initial() { function initial() {
onLoad(() => { onLoad(() => {
formData.value.specType = specType.value ? true : false formData.value.specType = specType.value ? true : false;
formData.value.specText = SPEC_TYPE[specType.value ? 1 : 0].label formData.value.specText = SPEC_TYPE[specType.value ? 1 : 0].label;
skus.value = JSON.parse(JSON.stringify(peach.$store('trade').skus)) skus.value = JSON.parse(JSON.stringify(peach.$store("trade").skus));
// 如果新增商品 sku并且是单规格初始化 sku // 如果新增商品 sku并且是单规格初始化 sku
if (!skus.value) { if (!skus.value) {
initSku() initSku();
} }
if (specType.value) { if (specType.value) {
getGoodsProperty() getGoodsProperty();
} }
}) });
} }
export { export {
@ -274,4 +297,4 @@ export {
showPropertyList, showPropertyList,
goodsPropertyList, goodsPropertyList,
changeSubProperty, changeSubProperty,
} };