一、业务介绍
1.SPU和SKU
SPU:标准化产品单位。它是商品信息集合的最小单位,是一组可重用且易于检索的标准化信息,描述了一个产品的特征。
库存股.即库存进出计量的基本单位,可以是件、箱、盘等。SKU是大型连锁超市DC物流管理的必要方法。现在已经扩展为产品统一编号的缩写,每个产品都有唯一的SKU号。
比如说我们买一个iPhone,它是一个SPU,但是你买的时候不能用iPhone买,商家也不可能用iPhone记录库存。必须基于iPhoneX是什么颜色,什么版本。比如你买了一个128G内存的银色iPhoneX,支持联通网络,商家也会以此单位记录库存。这个更详细的单位被称为库存单位。
销售属性和平台属性
“销售”属性位于产品详细信息页面的右侧。您可以通过销售属性找到一组spu下的sku。可以让当前产品详情页跳转到自己的“兄弟”产品。
一般每个商品的销售属性不会太多,大概1-4种。整个电商的销售属性不会有太多种,10种左右。比如:颜色、尺码、版型、西装等。不同销售属性的组合构成了一个spu下多个SKU的结构。
平台属性,即与之前分类下的条件相似的属性,辅助搜索。
销售属性独立于平台属性。SPU将决定产品的销售属性。比如iPhonx会有颜色、版型、内存的销售属性,一件t恤只有尺码的销售属性。
而一个商品具有什么平台属性,是由其三级分类决定的。比如笔记本包括:运行内存、cpu、显卡、硬盘、屏幕尺寸等。
2.SKU和SPU的图片资源
同一个SPU下的另一个SKU可以共享一些资源,比如产品图片,海报等等。毕竟大部分同款产品的图片分享只是因为颜色和大小,差别不大。一般来说,产品的图片是在添加SPU的时候上传的,添加SKU的时候选择这个SPU上传的图片。
而且海报对于SPU下的所有SKU几乎都是一样的。
3.数据结构图
根据上述要求,SPU关联的数据库表结构设计如下:
4.数据示例:
二、列表查询功能开发
1.主页菜单index.html
别忘了加上控制器的跳转。
2、SpuManageController
@ controller public class SpuManageController { @ requestmapping public String getSpuListPage { return " spuListPage ";}}
3.SPU列表页面
并且属性列表基本相同,通过三级分类得到spu信息列表。
spuListPage.html
注意:我们现在使用的是easyui的单页模式,也就是说所有的页面最后都会加载到一个页面上。所以,我们要注意的是,中所有打开的页签的元素id不能重复,否则会有冲突。
4.背景代码
4.1控制器
@ request mapping @ ResponseBodypublic List getSpuInfoList { String catalog 3 id = map . get;SpuInfo spuInfo = new SpuInfospu info . setcatalog 3 id;list spuInfoList = manage service . getspuinfolist;返回spuInfoList}
4.2豆
公共类SpuInfo实现可序列化的{私有字符串id;私弦spuName私有字符串描述;私有字符串catalog3Id}
在gmall-管理-服务项目中添加
4.3映射器
公共接口SpuInfoMapper扩展映射器{}
实现manageServiceImpl类的添加方法。
public List getSpuInfoList { List spuInfoList = spuinfomapper . select;返回spuInfoList}
第三,spu的保存功能
1.点击添加,弹出输入框。
首先在列表页面点击【添加】,会出现一个弹出框。
函数addSpuInfo { initSpuInfoDlg//在spuInfoPage.html中}
因为这个弹出框是一个新的表单,虽然整个后台系统是单个页面,但是如果所有的代码都集中在一个html里,维护起来非常不方便,可读性也很差。因此,让我们通过使用页面呈现工具themeleaf的标签将一段代码提取到另一个html文件中。
这个标签有点类似于Jsp。
这样,我们用这个新的弹出窗口所做的一切都可以放在spuInfoPage.html的这个文件中。
1.1创建spuInfoPage.html
参见代码思维导图。
2.困难分析
两个困难:
涉及到上传图片附件,需要上传多个图片附件。每个图像应该以可管理的方式分配,因为每个图像最终将被分配到不同的sku。同时,用户上传成功后可以预览。
一个spu对应于多个销售属性,但是每个销售属性对应于多个属性值。
3.图片上传预览解决方案:
上传组件
分布式存储
控件
3.1先说WebUploader。
官方网站:'
WebUploader是百度WebFE团队开发的一个简单的现代文件上传组件,以HTML5为主,FLASH为辅。
如何使用,可以参考官网给出的例子。
简单归纳:安装常规完工控制所需的几个动作。
3.2网络上传器的实现步骤
背景代码
实际业务代码见脑图。
3.3解决上传后预览,通过伸缩线实现。
使用datagridview。这是easyui 空的扩展。
若要使用它,请将datagridview.js复制到,并在表中添加以下红色部分
${$.数据网格{return '' +'' +'
状态:“+ rowData.status +”
' +'4.文件服务器
现在我们已经实现了从客户端提交和显示文件的功能。服务器需要做的就是接收文件流,保存,并返回到客户端文件的访问地址。
传统的用io流保存到web服务器的方式,可以通过当前web服务的路径+镜像名直接访问。
而像商品图片这样的海量文件,单靠web服务器的硬盘是无法满足的。
另外,如果web服务器是集群的,那么服务器A不能访问服务器b的本地文件。
所以需要单独管理文件服务,成为文件服务器。
实现是nginx+FastDFS
4.1快速DFS简介
FastDFS一个用C语言实现的开源轻量级分布式文件系统。作者余庆支持Linux、FreeBSD、AID等Unix系统,解决了大数据存储、读写负载均衡等问题。适合存储4 KB到500 MB之间的小文件,如图片网站、短视频网站、文档、app下载站等。UC、JD.COM、支付宝、迅雷、酷狗等都是二手的。
该软件的作者是由阿里丹尼尔和中国Unix的版主余庆独立开发的。
4.2上传和下载fastdfs的流程
4.3安装步骤参见FastDFS的安装说明。
4.4通过Java客户端调用FastDFS
安装好服务器后,我们通过Java调用fastdfs。
加载Maven依赖项
DFS没有提供在中央仓库中获得的从属坐标。
只能通过源代码编译,做一个jar包,安装在本地仓库。
正式仓库地址:
https://github.com/happyfish100/fastdfs-client-java
使用idea直接将这个源代码作为一个模块导入到项目中。
别的不要改,把pom.xml里的版本改成1.27就行了。
然后在右边执行install。
安装后,其他模块可以直接使用这个坐标。
org . csourcefastdfs-client-Java 1.27
而这个fastdfs-client-java模块可以从idea中删除。
然后就可以做上传测试了。
@Testpublic void textFileUpload抛出IOException,my exception { String file = this . getclass . get resource . getfile;ClientGlobal.inittracker client tracker client = new tracker client;tracker server tracker server = tracker client . get connection;StorageClient storageClient =新存储客户端;string orginal filename = " e://victor . jpg ";string[]upload _ file = storage client . upload _ file;for { String s = upload _ file[I];system . out . println;}}
添加tracker.conf文件
tracker _ server = file . server . com:22122 #连接超时。对于socket函数connect,默认值为30秒connect_timeout=30000#网络通信超时,默认值为60秒network_timeout=60000。
打印结果
这个打印结果实际上是我们访问过的路径,我们可以把它和服务器的地址拼接成一个字符串。
直接去浏览器。
上传成功!
停靠在业务模块中。
修改FileUploadController的方法
@Value标记可以引用application.properties中的值。
测试结果:
至此,我们已经解决了文件上传的功能。
5.销售属性——两层多对多关系。
一个spu对应于多个销售属性,但是每个销售属性对应于多个属性值。
在spu的details页面上,sales属性以表格形式显示了一对多关系,但是每一行代表多个属性值。
每行只能再弹出一个表来添加多个属性。
但是和之前的弹出框保存不同。弹出框打开后,输入数值。当你点击右下角的“确定”时,你不能直接将数据保存到数据库中,但你必须将这个项目符号框中的数据保存到销售属性表控件中。只有在输入了整个spu后,点击Save才能真正写入数据库。
输入属性值信息,确认后保存。
Datagrid将整个datagrid的数据提取到一个Json中。
该Json的格式如下
但这是Json对象,不是Json字符串。
如果保存到控件的临时列中。
然后,当您将来想要编辑该属性时,可以使用loadData将原始数据加载回来。


