SPU&SKU
1. Introduction to SPU
SPU = Standard Product Unit (standard product unit)
In this way, it may still be difficult to understand what a standard product unit is. So if you take the Apple mobile phone as an example, is iPhone 11 an SPU or SKU?
The answer is SPU in the end what is it SPU? My understanding is: SPU is a standardized collection of commodities that can relatively contain some distinctive features of commodities. For example: SPU = brand + model "Apple" + "iPhone 11" constitutes an SPU, which can be called "commodity" here. It should be noted that the SPU=brand+model mentioned above is also in a relative sense and is restricted by the scene and demand.
2. Introduction to SKU
stock keeping unit
The understanding of this can be further understood in the above equation as: SKU = SPU + specification . The specifications here are a collective term. For example, for mobile phones, memory, screen size, color, etc. are specifications; such as clothes, colors, patterns, and sizes.
3. The embodiment of SPU&SKU in the project
3.1 Analysis of back-end data structure
The specs array in the sku_list in the figure below is the specifications of the current spu
"spu_detail": {
"id":2,
"title":"林间有风自营针织衫",
"subtitle":"秋日冬款,浪漫满屋",
"category_id":12,
"root_category_id":2,
"price":"77.00",
"img":"http://i1.sleeve.7yue.pro/assets/ecf8d824-19d4-4db2-a5da-872ab014fecd.png",
"for_theme_img":"https://gitee.com/lrelia7/sleeve-static/raw/master/theme/spu1.png",
"description":null,
"discount_price":"62.00",
"tags":"秋日冬款$浪漫满屋",
"is_test":true,
"online":true,
"sku_list":[
{
"id":2,
"price":77.76,
"discount_price":null,
"online":true,
"img":"http://i1.sleeve.7yue.pro/assets/2d22ffec-b1c1-43e0-ad21-25aa5c26ab34.png",
"title":"金属灰·七龙珠",
"spu_id":2,
"category_id":17,
"root_category_id":3,
"specs":[
{
"key_id":1,
"key":"颜色",
"value_id":45,
"value":"金属灰"
},
{
"key_id":3,
"key":"图案",
"value_id":9,
"value":"七龙珠"
},
{
"key_id":4,
"key":"尺码",
"value_id":14,
"value":"小号 S"
}
],
"code":"2$1-45#3-9#4-14",
"stock":5
},
{
"id":3,
"price":66,
"discount_price":59,
"online":true,
"img":"http://i1.sleeve.7yue.pro/assets/c6b52c90-5b10-4823-baef-6c37d3d3532f.png",
"title":"青芒色·灌篮高手",
"spu_id":2,
"category_id":17,
"root_category_id":3,
"specs":[
{
"key_id":1,
"key":"颜色",
"value_id":42,
"value":"青芒色"
},
{
"key_id":3,
"key":"图案",
"value_id":10,
"value":"灌篮高手"
},
{
"key_id":4,
"key":"尺码",
"value_id":15,
"value":"中号 M"
}
],
"code":"2$1-42#3-10#4-15",
"stock":999
},
{
"id":4,
"price":88,
"discount_price":null,
"online":true,
"img":"http://i1.sleeve.7yue.pro/assets/c6b52c90-5b10-4823-baef-6c37d3d3532f.png",
"title":"青芒色·圣斗士",
"spu_id":2,
"category_id":17,
"root_category_id":3,
"specs":[
{
"key_id":1,
"key":"颜色",
"value_id":42,
"value":"青芒色"
},
{
"key_id":3,
"key":"图案",
"value_id":11,
"value":"圣斗士"
},
{
"key_id":4,
"key":"尺码",
"value_id":16,
"value":"大号 L"
}
],
"code":"2$1-42#3-11#4-16",
"stock":8
},
{
"id":5,
"price":77,
"discount_price":59,
"online":true,
"img":"http://i1.sleeve.7yue.pro/assets/09f32ac8-1af4-4424-b221-44b10bd0986e.png",
"title":"橘黄色·七龙珠",
"spu_id":2,
"category_id":17,
"root_category_id":3,
"specs":[
{
"key_id":1,
"key":"颜色",
"value_id":44,
"value":"橘黄色"
},
{
"key_id":3,
"key":"图案",
"value_id":9,
"value":"七龙珠"
},
{
"key_id":4,
"key":"尺码",
"value_id":14,
"value":"小号 S"
}
],
"code":"2$1-44#3-9#4-14",
"stock":7
}
],
"spu_img_list":[
{
"id":165,
"img":"http://i1.sleeve.7yue.pro/assets/5605cd6c-f869-46db-afe6-755b61a0122a.png",
"spu_id":2
},
{
"id":166,
"img":"http://i1.sleeve.7yue.pro/assets/ecf8d824-19d4-4db2-a5da-872ab014fecd.png",
"spu_id":2
},
{
"id":167,
"img":"http://i1.sleeve.7yue.pro/assets/8451cebd-5a8d-4758-bb2a-652e026a7c00.png",
"spu_id":2
}
],
"spu_detail_img_list":[
{
"id":24,
"img":"http://i2.sleeve.7yue.pro/n4.png",
"spu_id":2,
"index":1
},
{
"id":27,
"img":"http://i2.sleeve.7yue.pro/n7.png",
"spu_id":2,
"index":2
},
{
"id":25,
"img":"http://i2.sleeve.7yue.pro/n5.png",
"spu_id":2,
"index":3
},
{
"id":26,
"img":"http://i2.sleeve.7yue.pro/n6.png",
"spu_id":2,
"index":4
}
],
"sketch_spec_id":1,
"default_sku_id":2
}
Extract the above specifications as follows, there are four different specifications of single products.
SKU name | colour | pattern | size |
---|---|---|---|
sku1 | metal gray | Dragon Ball | Small S |
sku2 | Blue awn color | Slam Dunk | Medium M |
sku3 | Blue awn color | Saint Seiya | Large L |
sku4 | Orange | Dragon Ball | Small S |
What may be strange here is that the returned data format does not return the specifications of the SPU, but directly returns the details of the single product in stock. This means that we need to filter out the specifications of the single products that can be selected .
3.2. How to extract single product data into product specification data
As shown in the figure above, the specification data we need is arranged horizontally. That is, the vertical specifications of the red box in the figure below need to be arranged horizontally.
Applied to the code is to use the form of a two-dimensional array: [[], [], []]
Four, matrix
4.1, the definition of matrix
4.2, matrix transpose
Five, code implementation
4.1, the way of traversal
First, loop out a specification array of sku and put it into the array m. Throw the array to the Matrix object for processing
_createMatrix(skuList) {
const m = []
skuList.forEach(sku => {
m.push(sku.specs)
})
return new Matrix(m)
}
After throwing the m array to the matrix class, use the internal rowNum() and colNum() methods
Matrix
class Matrix {
m
constructor(matrix) {
this.m = matrix
}
// m = [[1,2,3],[4,5,6],[7,8,9]]
// 显示如下矩阵
// 1,2,3
// 4,5,6
// 7,8,9
/**
* 获取行数
* @returns {*}
*/
get rowNum() {
return this.m.length
}
/**
* 获取列数
* @returns {*}
*/
get colNum() {
return this.m[0].length
}
each(cb) {
for (let j = 0; j < this.colNum; j++) {
for (let i = 0; i < this.rowNum; i++) {
const element = this.m[i][j]
cb(element, i, j)
}
}
}
transpose() {
const desArr = []
for (let j = 0; j<this.colNum; j++) {
desArr[j] = []
for (let i = 0; i < this.rowNum; i++) {
// 矩阵转置就是需要把x,y对调
desArr[j][i] = this.m[i][j]
}
}
return desArr
}
}
export {
Matrix
}
The each method in the code above is looping through the m array, extracting the elements in the array, and then calling the cb method to return
/**
* 遍历方式-转置矩阵
*/
initFence1() {
const matrix = this._createMatrix(this.skuList)
const fences = []
let currentJ = -1
matrix.each((element, i, j) => {
if (currentJ !== j) {
// 列号不同,创建一个新的fence
currentJ = j
fences[currentJ] = this._createFence(element)
}
// 列号相同则将当前element的信息设置到当前的fence中
fences[currentJ].pushValueTitle(element.value)
})
}
_createFence(element) {
const fence = new Fence()
return fence
}
In the code above, it should be noted that i represents the row number and j represents the column number. How to determine that the current column of the array has been looped is completed in the process of looping out the array. It is judged by the value of j. If the value of j changes , It means that the current element is the first element in a new column. Then we must create a new fence to store the elements of this column.
4.2 The way of matrix transposition
The result of matrix transposition is to reverse x and y. The transpose method in the Matrix class above is to convert the incoming specs array according to the two-dimensional array subscript, x-axis, and y-axis. It should be noted here that the outer layer of the for loop in the transpose method must be y, and the inner layer must be x. This is because one column is one specification. Rather than a single specification.
/**
* 矩阵转置-转置矩阵
*/
initFence() {
const matrix = this._createMatrix(this.skuList)
const fences = []
const AT = matrix.transpose()
AT.forEach(specs => {
const fence = new Fence(specs)
fence.init()
fences.push(fence)
})
}