前言

SKU百度百科为 库存保有单位 (Stock keeping Unit 或者SKU)是对每一个产品和服务的唯一标示符。 也就是说sku 为商品对应的很多种类规格情况下的 库存,价格 各有不同。需要通过sku 这样一种组合结构存储这些计量值。
在移动电商时代,网购已然成为潮流。更是全民参与。每一年都有购物节 : 京东618 , 淘宝天猫双11, 双12 。 一个淘宝店家月销售额30万背后 ,他的商品sku有上千种。 一个卖橱柜的,小到抽屉,拉篮,五金 ,把手,螺丝钉 都可以细分成很小的SKU。移动电商商品背后的SKU种类的复杂性。可正是因为商品SKU的多样化,才能商家带来巨量的销售额。

从详情页认识SKU

C端sku选择

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
这个商品包含的SKU信息:{
规格类型:[{
尺寸:[XS, S, M, L,XL, XXL]
},{
颜色: [白色,珊瑚粉,草木绿]
}],
规格明细组合描述: {
XS-白色:{
图片: 图片url,
价格: ¥328,
库存: 188件,
扩展..字段: 值
},
其他规格组合:{
图片: 图片url,
价格: 价格..,
库存: 库存数量..,
扩展..字段: 值
}
}
}

每个人的feed就是一个list,存储到redis;
用户前端产生的所有事件 发送到消息队列 RabbitMQ,
Server 根据 业务逻辑将新的item插入到下游用户的feed里面;

在线推,推给活跃在线用户,离线拉;

任务调度 :选用了Celery;

每个用户都有一个收件箱 和 发件箱;保存自己发过的动态以及Feed动态;

用户A关注了用户B , 用户B发布动态则将动态推进用户A的feed,这里使用redis的zset实现,sort为time(记得以毫秒为时间戳,秒级在数据量达到一定程度后,会有读取不到的问题,比如以时间戳为分页页码),value为具体的动态 ID(为什么是动态ID, 其实很简单, 就是因为动态的内容可以进行缓存,在redis里面全部走ID,修改动态内容也需要修改一处,动态内容可以保存在hash结构里), 每个用户维护一个zset保存我发布的动态,一个zset保存我的feed动态,过期时间3~7天看情况而定。

全局维护一个在线用户列表,怎么设计这个就自己琢磨了,为了防止用户挂后台导致与服务端为离线状态,所以最好是1~3小时未操作或者离线时间不大于3小时的,都当做在线处理,

那么,当用户发了一条动态后,后台会有以下这些操作:

在线推: 异步遍历在线的粉丝,将动态ID,添加到粉丝的Feed中。

离线拉: 离线用户打开APP后,我们是会请求一个公共的入口接口,主做统计以及其他初始化操作,在这里,我们也开了一个异步线程,对用户进行Feed更新操作,防止用户进入APP后等待拉取时间过长,毕竟关注成千上万的人肯定有(其实万单位以下遍历都很快)。拉取过程其实就是把自己最后一条Feed的时间戳取出,去遍历关注的人的feed,将大于该时间的ID全部拉取回来。用户进入APP后,刷新即可看到最新操作。

消息布局观察:周边头像,昵称,间距 ,气泡 及其他统一,内容视图挖空; 采取自定义注入视图配置;

从CellFor 方法说起;聊天消息页面,我们看到 有 聊天消息 还有时间戳;根据 ModelItem项 的 class类型 分别去创建 两种cell ; 只里只讲 聊天消息cell;

流程:当为聊天消息Model 时候,名 messageModel(messageModel 里面 大致有以下属性: 记录消息模型,消息布局,头像,昵称 显示控制,消息内容size; (不足 后补)); 取得消息布局; 相对应的content类字符串;根据 identify = content 去重用cell (不同消息类型重用标识不同 ); 创建MessageCell 根据 content 去创建 对应的内容视图 即可;再刷新视图数据 赋值;

布局来源:定义 一个 layoutconfigInterface;
layoutconfig 配置包含:{
1)message的内容大小;
2)需要创建显示的CellContent 类名
3)气泡的配置间距等
4)控制是否显示头像
5)控制是否 显示昵称
6)控制消息显示在左边还是在右边 (是否是自己发的)
}

Content来源
1、contentConfigInterface 接口:
考虑到message的内容大小 和 cellContent 类名 是 属于 CellContent 配置; 于是 考虑用一个 cellConentConfigFactory 的工厂来生产这些配置 ;

2、contentConfigInterface 实列
message的内容大小 和 cellContent 类名 抽出来 定义一个接口 ContentConfigInterface;
(考虑到有文本配置,图片配置,以及图文配置,后期 的扩展 声音配置,红包配置 , 好友分享配置) 准备一个超级父类
BaseContentConfig (具有message属性,方便计算message内容的大小); 后期配置只需继承 BaseContentConfig、实现ContentConfigInterface 接口 方法即可;

3、最终要把配置contentConfigInterface 这样的实列 反馈给 布局管理器; 为了不暴露太多的详细contentConfig 细节 以及 低耦合;用一个
ConentConfigFactory 工厂生产这些配置玩意 ,根据消息类型 返回 消息内容配置 contentConfig (工厂单列,实列化的时候 创建了一个Map或者字典, 记录了消息类型 对应的 消息contentConfig;)