通常电子商城项目中会涉及到SKU ,SPU 概念 , 前者是原子级 , 后者是一种类别 。
SKU:Stock Keeping Unit : 库存单位 , 以库存进出为单位 ,
SPU:Standard Product Unit : 标准产品单位 ,从产品视角 ,是产品信息聚合的最小单位 ,一个SPU 可以包含多个 SKU
SPU 就是一个商品 ,例如华为P30 , 小米9 , 而每个 SPU下或有不同的商品 ,SKU 即为销售单元 ,也是库存的基础单位,例如小米8 白色 64G , 这就是一个SKU , 当库存出库的同时 , 去获取的也是该SKU的值
此结构设计参考自芋道源码及有赞 。
芋道源码
CREATE TABLE `item_sku_property_key` (
`id` int(5) NOT NULL COMMENT '属性编号',
`add_time` datetime DEFAULT NULL COMMENT '添加时间',
`ismultiple` bit(1) DEFAULT NULL COMMENT '是否多选',
`mustneed` bit(1) DEFAULT NULL COMMENT '是否必须',
`name` varchar(128) NOT NULL COMMENT '属性文本',
`status` int(5) NOT NULL COMMENT '状态',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `item_sku_property_reference` (
`id` int(11) NOT NULL,
`add_time` datetime DEFAULT NULL,
`goodsid` int(15) NOT NULL COMMENT '对应商品ID',
`issku` tinyint(1) NOT NULL COMMENT '是否为SKU',
`shopid` int(5) NOT NULL COMMENT '对应店铺ID',
`skuid` int(5) NOT NULL COMMENT 'skuid',
`skukeyid` int(5) NOT NULL COMMENT '对应属性KEY',
`skuvalueid` int(5) NOT NULL COMMENT '对应属Value',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `item_sku_property_value` (
`id` int(11) NOT NULL,
`add_time` datetime DEFAULT NULL COMMENT '添加时间',
`datatype` int(5) DEFAULT '0' COMMENT '数据类型',
`keyid` int(5) NOT NULL COMMENT '对应属性KEY',
`value` varchar(128) NOT NULL COMMENT '属性文本',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `shop_goods_sku` (
`unique_code` varchar(128) NOT NULL DEFAULT '0' COMMENT '唯一编号',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`gid` int(5) DEFAULT '0' COMMENT '商品编号,对应goods',
`goods_no` varchar(128) DEFAULT '' COMMENT '商品货号',
`imageurl` varchar(256) DEFAULT '' COMMENT '图片地址',
`price` int(6) DEFAULT '0' COMMENT '价格',
`properties` varchar(256) DEFAULT '' COMMENT '商品规格,字符串 ,通常用于预览',
`quantity` int(6) DEFAULT '0' COMMENT '库存',
`sale_num` int(6) DEFAULT '0' COMMENT '销量',
`shop_id` int(5) DEFAULT '0' COMMENT '店铺编号',
`sku_id` int(5) DEFAULT '0' COMMENT 'sku 编号',
`status` int(3) DEFAULT '0' COMMENT '状态 1 正常 2 删除',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`with_hold_quantity` int(6) DEFAULT '9999' COMMENT '未付款订单数',
PRIMARY KEY (`unique_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `shop_goods` (
`id` int(11) NOT NULL,
`alias` varchar(100) DEFAULT '' COMMENT '系统生成唯一ID',
`create_date` datetime DEFAULT NULL,
`goodscate` varchar(100) DEFAULT '' COMMENT '商品类别',
`goodscode` varchar(100) DEFAULT '' COMMENT '商家自定义货号',
`goodsdesc` varchar(255) DEFAULT '' COMMENT '货品描述',
`goodsprice` varchar(255) DEFAULT NULL,
`goodsstyle` varchar(100) DEFAULT '' COMMENT '商品风格',
`goodstitle` varchar(100) DEFAULT '' COMMENT '货品标题',
`goodstype` varchar(100) DEFAULT '' COMMENT '商品类型',
`message` varchar(255) DEFAULT NULL,
`sale_staus` varchar(255) DEFAULT NULL,
`sale_type` varchar(255) DEFAULT NULL,
`shopid` varchar(100) DEFAULT '' COMMENT '店铺ID',
`size` varchar(255) DEFAULT NULL,
`status` int(11) DEFAULT NULL,
`summary` varchar(255) DEFAULT '' COMMENT '货品副标题',
`update_date` datetime DEFAULT NULL,
`volume` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
var obj = console.log(JSON.stringify(data));
let pageObject = {};
// 算法目的 :
// 原数据 : {
// "1":{"颜色":"白色","尺寸":"10*10","skuid":1},
// "2":{"颜色":"玫瑰色","尺寸":"10*20","skuid":2}
// }
// showobj = {
// 颜色 : { 白色 :[0,1] ,黑色 :[1 ,2] },
// 尺码 : { 大号 :[0,2] }
// }
this.selectgood = data;
findGoodsOne(data.id, "100001").then(re => {
console.log("find success:{}--goolist:{}", JSON.stringify(re), this.goodlist);
Object.keys(re).forEach(function (key) {
// 对每一条记录进行循环 -》 {"颜色":"白色","尺寸":"10*10","skuid":1}
let itemObject = re[key];
let itemSKUID = itemObject.skuid;
Object.keys(itemObject).forEach(function (itemKey) {
// 获得每一种种类 -》 "颜色":"白色" 、 "尺寸":"10*10"
// 种类 -> itemKey : 颜色 、尺寸
// 值 -> itemValue : 白色 、红色 、大 、小
let itemValue = itemObject[itemKey];
// 当前页面渲染对象包含 种类 itemKey
if (pageObject.hasOwnProperty(itemKey)) {
// 最终的存储单元 --{白色 ,[ 1 , 2 ]}
let atomobj = pageObject[itemKey];
// 当前 种类对象 中 是否包含 该 值 , 例如颜色 种类之中只包含了白色 ,而没有黑色
if (atomobj.hasOwnProperty(itemValue)) {
atomobj[itemValue].push(itemSKUID);
} else {
// 生成 该 值 , 并且为 其配置 skuid
atomobj[itemValue] = [itemSKUID];
}
} else {
// 创建种类对象 -》 尺码 : { 大号 :[0,2] }
let valueSKUid = [itemSKUID];
pageObject[itemKey] = {};
pageObject[itemKey][itemValue] = valueSKUid;
}
});
});
console.log("=================");
console.log(pageObject);
this.pageObject = pageObject;
this.showpop = true;
}).catch(err => {
console.log("press cancel");
});
参照上面的注解就很同意理解了
ensuregoodfun: function () {
console.log("确定选购商品:{}", this.selectgood);
console.log("确定选购商品 规格:{}", this.selectSKU);
let itemSKU = this.selectSKU;
let skuArray = new Array();
//很明朗 , 依次循环 ,若下一个集合中有当前的skuid , 则保存到新的数组总 , 到最后 ,一定只有一个skuid 存在
Object.keys(itemSKU).forEach(function (itemKey) {
//获得第一个sku array
if (skuArray.length == 0) {
skuArray = itemSKU[itemKey].skid
} else {
let newArray = new Array();
let next = itemSKU[itemKey];
for (let x in next) {
if (skuArray.indexOf(next[x])) {
newArray.push(next[x]);
}
}
}
});
console.log("最终sku:{}", skuArray[0]);
var cartObject = {
cartdesc: 'app',
carttype: 0,
goodsid: this.selectgood.id,
skuid: skuArray[0],
shopId: 100001,
buyerId: 10001,
nobodyKey: 'A0001',
num: this.buynum,
price: this.selectgood.goodsprice
}
addGoodsToCart(cartObject).then(re => {
console.log("add success:{}--goolist:{}", JSON.stringify(re), this.goodlist);
this.showpop = false;
util.showmsg("货品已添加到购物车");
}).catch(err => {
});
},
此SKU 表的设计还有很多可扩展的空间 , 对于 前端算法 ,SKU不会太多 ,基本满足复杂需求 ,可以尝试优化后使用