第一章SKU核心思路

SKU购物车控件系列文章目录
第一章SKU核心思路


提示:这系列文章使用js实现,其他语言思路类似只是代码语法不同也能参考

 

 


前言

使用js写的购物车modle模型类,可供有需要的同学参考。大致的参数所有公司都差不多,只需要修改参数名即可使用。
这是一篇迟到的文章,之前用uiautomator2.0和robotium写过购物车的测试工具,等于说是反向写过购物车代码

闲来无事就想正着已一个程序员的角度,完成一个购物车控件。想看看自己能不能在技术上有所增长,所以特地使用了自己不擅长的js语言


 

一、业务模型分析

1.SKU介绍:

  •  在电商中一般分为spu和sku。spu是一组商品着一组商品中包含了几个不同的单个商品称为sku。
  • 例如:在淘宝上买一件短袖,在购买时你需要选择衣服的颜色、印的图案、尺码。在你点击进入详情页时服务端给的数据是spu,当你选择完颜色、图案、尺码后得到了唯一确定的一个商品sku。

2.需求分析:

客户端的需求可以参考淘宝京东这样的大型电商,这样用户在使用起来逻辑清晰也符合他的使用习惯。

  • 根据用户累计选择的选项,挑选有库存的后续可选择项提示给用户(可点击)
  • 用户已选择的选项可以被清除,所以用户每做一次选择都需要重新计算
  • 用户的选择是可以随机的,所以这些选择没有先后顺序
    • 如:用户可以先选衣服的颜色也可以先选尺码
  • 如果用户当前在有多个选项的情况下只选择了一个选项,那么这一行的选项都可点击。因为说不定用户就想换一个选择
    • 如:当你衣服只选择了红色并且没有选择其他行的属性,那么同一行的蓝色、白色、黑色都是可选择的
  •  每一项属性是唯一的不能重复选择。选了红色就不能选白色

 

二、数据模型分析

1.SKU格式

下面我们来看看服务端下发的sku是怎么样的格式,以及各自所代表的意思。

SKU一般是一串服务的下发的字符串(示例):101#11-5$4-3$21-5

  • 101是这个sku所对应的id
  • 11-5可以看作为颜色对应的11,5对应的黑色
  • 同理4-3可以看作对应爱心图案,21-5是L码
  • id和属性之间用#隔开,各个属性之间用$隔开

2.服务端数据

客户端的购物车肯定是按照服务的给的数据进行设计。而服务端的做法是将一组sku就是spu全部发下来。每一个sku里面还会带有拆分了的单个属性和他们的中文名称,让客户的可以显示。

一般服务端不会下发单个控件所对应的code码,只会下发一个sku的集合。

所以我们想要为这些控件添加文字或者图片时,需要对服务的都数据做出处理。既然给我们的是一组sku,控件上显示的是单个的code。恰好sku就是由一个个code码组合而成的,所以我们只需要遍历这一组sku然后将每个sku拆分得到单个的code码,再把这些得到的code去重就可以得到界面上需要显示的数据啦(一组sku中难免会有多个选择是重合的,比如红色的短袖可以选择L码的而白色的短袖也可选择L码的大小)。

那么问题来了有什么简单的方法去处理并得到一组符合分类规定的数据呢?

有!用矩阵转置。这里把之前的那张图片顺时针旋转90度,可以发现假如服务端给我们的一行数据是尺码和颜色。而界面上显示的数据是一行尺码一行颜色,那就可以发现服务端给的数据和界面要显示的数据只差了90度!

那么接下去只需要使用矩阵转置的算法进行处理就可以得到我们想要的数据啦。

虽然sku的思路大致相同,但各家公司的数据还是会有细节上的差别,所以各位在使用时需要注意。先把sku根据格式拆分成一个个的code码,再通过矩阵得到分组之后的数据。我这里就不贴代码了,因为我的数据不适合你们使用。各位可以百度矩阵算法然后处理你们的数据。

当然也可以用自己的方法,只要能把下发的数据分类处理得到自己想要的就行。

 

三、代码模型分析

在数据处理完成之后,现在我们就可以来看看实现购物车这个功能需要在代码层面做那些东西。

首先界面上的模型。购物车一般是由最上层的图片和价格,中间层的可供用户选择的核心板块,以及最下面的数量这三个部分组成的。

单讲核心板块:

  • 我们在把sku拆分之后得到单个的code码,这个code码所对应的控件在这里把它称为cell。
    • 它是购物车中最小的节点,也是用户唯一可点击的控件
    • 前面举例体恤的颜色,红色黑色蓝色就是一个个的cell
  • 同一种属性的一个个的cell组成了一组这里称为group
    • 颜色,图案,尺码就是三个group
  • 颜色,图案,尺码这三个group组成了groups就形成了购物车的核心板块

现在项目开发都是提倡界面和业务模型分离,所以在逻辑处理上还需要一个模型这里称它为judger。这样界面上只需要提供给我们一个groups(groups里面必然包含了全部的cell),并告诉我们用户点击哪个控件就可以啦。剩下的事情交给我们的逻辑模型来处理。

这个逻辑模型而言里面的代码有不少我会放到下一篇去讲,这样我们sku购物车控件大致的框架草稿就打完了。


总结

在做购物车的时粗看要做的东西很多比较复杂,那么我们就把他拆分尘归尘土归土。界面的归界面逻辑的归逻辑,界面的上控件展示交给逻辑来控制这样就可以减轻我们的思维负担。
要牢记购物车是根据用户的选择实时在变化的,所以用户的每次点击都需要重新处理逻辑更新界面。

首先,需要引入layui库和jQuery库: ```html <link rel="stylesheet" href="https://cdn.staticfile.org/layui/2.5.6/css/layui.css"> <script src="https://cdn.staticfile.org/jquery/3.5.1/jquery.min.js"></script> <script src="https://cdn.staticfile.org/layui/2.5.6/layui.all.js"></script> ``` 然后,我们可以通过以下方式来实现一个SKU选择器: 1. 定义属性和SKU列表 ```javascript var attrs = [ {name: '尺码', values: ['S', 'M', 'L', 'XL']}, {name: '颜色', values: ['红色', '黄色', '蓝色']} ]; var skus = [ {attrs: ['S', '红色'], price: 100, stock: 10}, {attrs: ['S', '黄色'], price: 110, stock: 5}, {attrs: ['S', '蓝色'], price: 120, stock: 2}, {attrs: ['M', '红色'], price: 130, stock: 7}, {attrs: ['M', '黄色'], price: 140, stock: 8}, {attrs: ['M', '蓝色'], price: 150, stock: 3}, {attrs: ['L', '红色'], price: 160, stock: 6}, {attrs: ['L', '黄色'], price: 170, stock: 4}, {attrs: ['L', '蓝色'], price: 180, stock: 1}, {attrs: ['XL', '红色'], price: 190, stock: 0}, {attrs: ['XL', '黄色'], price: 200, stock: 0}, {attrs: ['XL', '蓝色'], price: 210, stock: 0} ]; ``` 2. 渲染属性选择器 ```javascript var $attrs = $('#attrs'); $.each(attrs, function(i, attr) { var $attr = $('<div class="layui-form-item"></div>'); $attr.append('<label class="layui-form-label">'+attr.name+'</label>'); var $values = $('<div class="layui-input-block"></div>'); $.each(attr.values, function(j, value) { $values.append('<input type="checkbox" name="'+attr.name+'" title="'+value+'">'); }); $attr.append($values); $attrs.append($attr); }); ``` 3. 监听属性变化,更新SKU信息 ```javascript $('#attrs input').on('change', function() { var selectedAttrs = []; $('#attrs input:checked').each(function() { selectedAttrs.push($(this).attr('title')); }); var sku = getSKU(selectedAttrs); $('#price').text(sku ? sku.price : '未知'); $('#stock').text(sku ? sku.stock : '0'); }); function getSKU(selectedAttrs) { var sku = null; $.each(skus, function(i, _sku) { if (matchAttrs(_sku.attrs, selectedAttrs)) { sku = _sku; return false; } }); return sku; } function matchAttrs(attrs1, attrs2) { if (attrs1.length != attrs2.length) { return false; } for (var i = 0; i < attrs1.length; i++) { if (attrs1[i] != attrs2[i]) { return false; } } return true; } ``` 4. 渲染价格和库存信息 ```html <div class="layui-form-item"> <label class="layui-form-label">价格</label> <div class="layui-input-block"> <span id="price">未知</span>元 </div> </div> <div class="layui-form-item"> <label class="layui-form-label">库存</label> <div class="layui-input-block"> <span id="stock">0</span>件 </div> </div> ``` 完整的代码如下: ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>SKU选择器</title> <link rel="stylesheet" href="https://cdn.staticfile.org/layui/2.5.6/css/layui.css"> <script src="https://cdn.staticfile.org/jquery/3.5.1/jquery.min.js"></script> <script src="https://cdn.staticfile.org/layui/2.5.6/layui.all.js"></script> </head> <body> <form class="layui-form layui-form-pane" style="margin: 20px;"> <div id="attrs"></div> <div class="layui-form-item"> <label class="layui-form-label">价格</label> <div class="layui-input-block"> <span id="price">未知</span>元 </div> </div> <div class="layui-form-item"> <label class="layui-form-label">库存</label> <div class="layui-input-block"> <span id="stock">0</span>件 </div> </div> </form> <script> var attrs = [ {name: '尺码', values: ['S', 'M', 'L', 'XL']}, {name: '颜色', values: ['红色', '黄色', '蓝色']} ]; var skus = [ {attrs: ['S', '红色'], price: 100, stock: 10}, {attrs: ['S', '黄色'], price: 110, stock: 5}, {attrs: ['S', '蓝色'], price: 120, stock: 2}, {attrs: ['M', '红色'], price: 130, stock: 7}, {attrs: ['M', '黄色'], price: 140, stock: 8}, {attrs: ['M', '蓝色'], price: 150, stock: 3}, {attrs: ['L', '红色'], price: 160, stock: 6}, {attrs: ['L', '黄色'], price: 170, stock: 4}, {attrs: ['L', '蓝色'], price: 180, stock: 1}, {attrs: ['XL', '红色'], price: 190, stock: 0}, {attrs: ['XL', '黄色'], price: 200, stock: 0}, {attrs: ['XL', '蓝色'], price: 210, stock: 0} ]; var $attrs = $('#attrs'); $.each(attrs, function(i, attr) { var $attr = $('<div class="layui-form-item"></div>'); $attr.append('<label class="layui-form-label">'+attr.name+'</label>'); var $values = $('<div class="layui-input-block"></div>'); $.each(attr.values, function(j, value) { $values.append('<input type="checkbox" name="'+attr.name+'" title="'+value+'">'); }); $attr.append($values); $attrs.append($attr); }); $('#attrs input').on('change', function() { var selectedAttrs = []; $('#attrs input:checked').each(function() { selectedAttrs.push($(this).attr('title')); }); var sku = getSKU(selectedAttrs); $('#price').text(sku ? sku.price : '未知'); $('#stock').text(sku ? sku.stock : '0'); }); function getSKU(selectedAttrs) { var sku = null; $.each(skus, function(i, _sku) { if (matchAttrs(_sku.attrs, selectedAttrs)) { sku = _sku; return false; } }); return sku; } function matchAttrs(attrs1, attrs2) { if (attrs1.length != attrs2.length) { return false; } for (var i = 0; i < attrs1.length; i++) { if (attrs1[i] != attrs2[i]) { return false; } } return true; } </script> </body> </html> ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值