一、查看商品类型属性
不同的商品类型其属性也是不一样的。
- 在admin-view-type-index.html修改链接地址

- 在admin-typeController-getAttr方法中,取出当前分类所有的属性展示在模板中

- 模板中遍历数据

二、去除编辑属性时属性值的多个空格
修改admin/view/attribute/upd.html模板

效果:

三、完成商品的添加
商品的认识
商品=产品+商品属性,即同一个产品,但是商品属性不同,就不是同一个商品,且价格也不同。
如:iphone6s黑色 和iphone6s银色
商品添加所需的数据表
当在后台添加一个商品的时候,商品相关数据需要入库到以下两个表:
商品表sh_goods和商品属性表sh_goods_attr
![]()
商品的基本信息数据存储在sh_goods表中,商品属性数据存储在sh_goods_attr中
商品表sh_goods表结构:

注:给我们的商品表添加一个goods_middle字段,存储图片的生成的中图的路径

商品属性表sh_goods_attr表结构:

完成商品基本信息的入库
基本信息:商品名称、商品价格、库存、详情、是否热卖…..
展示添加商品模板
- 在admin-GoodsController-add方法中,输出添加商品的模板

- 把后台的添加商品的模板复制到admin/view/goods/目录下面,并且修改静态资源路径

模板是四个选项卡构成:

先修改第一个和第四选项卡的name名称:
第一个选项卡:

效果:

第四个选项卡内容:

基本信息入库操作
- 定义添加商品的验证器Goods

- 在admin-GoodsController-add 方法中完成商品的入库操作

- 使用ueditor 完成商品的详情
引入三个核心js文件:

设置textarea的id,初始化编辑器:

添加商品的多图片上传

建议原图上传800*800 ,生成两种缩略图
中图缩略图:350*350 比例为2
小图:50*50 生成缩略图的类型为2位等比例补白
- 上传文件的form两个要求:post提交 和enctype = multipart/form-data

- 设置文件上传的name属性,因为是多图上传,所以呢name后需要加[]。

(1)思路分析
实现思路:可以参考ecshop开源商城:

①构建布局:
每个文件上传域名其实可以看做是一个li标签,其中包含a标签和input上传文件域
如下结构:
<li> <a href=’javascript:;’ >[+]</a><input type=’file’/> </li>
<li> <a href=’javascript:;’ >[-]</a><input type=’file’/> </li>
②怎么实现图片前的[+][-]加减功能?
思路:
- 给li中的a标签绑定单击事件,获取当前单击元素的内容
- 判断内容,含两种情况[+]、[-]
若是[+]: 则获取当前元素的父元素(即li),克隆一份,在把内部的a标签的[+]变成[-]。
若是[-]: 则获取当前元素的父元素(即li),并移除。
多图片上传加减特效
1、修改第三个选项卡的内容,设置标签。以及绑定单击事件

- 实现上面的单击事件克隆图片
通过看思路实现代码:
思路:
a、给li中的a标签绑定单击事件,获取当前单击元素的内容
b、判断内容,含两种情况[+]、[-]
若是[+]: 则获取当前元素的父元素(即li),克隆一份,在把内部的a标签的[+]变成[-]。
若是[-]: 则获取当前元素的父元素(即li),并移除。

效果:

实现多图片的上传
- 在Goods模型中定义一个方法,判断进行图片的原图上传,并返回上传成功的文件路径

- add方法中进行调用上面的方法,把图片的路径转化为json格式存储到表对应字段中

(4)生成多图片的缩略图
生成缩略图的步骤:
- Image打开源图片 $image = \Think\Image::open(源图片);
- 进行缩放处理 $image -> thumb(宽度,高度,类型)
- 把缩放好的图片保存到服务器上 $image -> save(小图路径名);
- 在goods模型中定义处理原图缩放的方法

- add方法中若原图上传成功,则调用上面的方法进行缩略图处理

最终生成的各图片名:

三、[难点-重点]完成商品的属性添加
1、分析商品动态属性的生成
添加一个商品,其商品属性可能有多个。
即商品表sh_goods的一条记录对应商品属性表sh_goods_attr的多条记录,属于一对多关系。
问题:怎么给商品设置商品属性?
这里可以参考ecshop的方案,当添加商品的,必须先选择一个商品类型,在通过ajax动态获取商品类型的属性,再给商品设置这些属性值。
如在ecshop后台添加商品的时候,选择手机类型,动态生成的属性框如下:

从上面添加商品属性可以看出,动态生成商品属性的时候,共有4种组合情况。
其实就是属性类型和属性值录入方式的互相组合:
①唯一属性+手工输入
②唯一属性+列表选择
③单选属性+手工输入
④单选属性+列表选择
其实可以把上面每个动态生成的属性信息看作是被包含在一个li标签中。
分析四种组合情况生成动态属性的特点如下:元素从左到右分析:

- 单选属性属性名称前有个[+]或[-]号,可以进行加减,而唯一属性则没有
- 属性名称
- 属性值录入方式为手工输入,则对应属性值的输入方式的是一个输入框(<input type=’text’/>),而属性值录入方式为列表选择的时候则对应属性值的输入方式的是一个select下拉框。
- 单选属性可以输入价格,而唯一属性则没有
完成商品的动态属性生成
- 在商品添加的add方法中取出所有的商品类型

- 模板中遍历数据在第二个选项卡

3、设置一个存储动态生成属性的容器

- 绑定onchange事件给select框

- 在admin-GoodsController-ajaxGetTypeAttr方法,获取对应类型的属性,并以json格式输出

- 根据ajax返回的属性数据,动态构建属性框

注:上面代码173行有错误:把判断attr_input_type改为attr_type
效果:

- 完成单选属性的[+]功能

说明,逻辑和之前相册的是完全一致

效果:

完成商品动态属性的入库
分析:
在表单中把单选属性值和单选属性价格通过属性attr_id归为同一组,方便后续获取对应属性的值和价格。
单选属性值: name=goodsAttrValue[attr_id][]
单选属性值价格: name=goodsAttrValue[attr_id][]
因为单选属性用户可以点击[+]号会生成多个,所以多个单选属性值和价格name的值后面都必须加上中括号[]。
由于唯一属性只能选择一个值,所以name后不需要加[]
我们最终需要构造类似于下面的数组,存储商品属性值和商品属性价格:

在动态生成的属性框元素中设置name属性:

在admin-GoodsController-add方法中打印提交过来的$postData数据如下:

由于商品属性表(sh_goods_attr)数据需要得到入库成功的商品主键goods_id,所以我们可以在商品模型Goods的入库后钩子after_insert中完成完成商品属性表数据的入库。

商品列表展示
- 在admin-GoodsController-index方法中取出商品数据进行分配到模板

- 模板中遍历数据

使用ajax+layer弹出层查看商品详情
- 给admin-view-goods-index.html模板内容设置查看商品详情的标签属性

- 给上面的class=showContent绑定单击事件,发送ajax请求

同时引入layer弹出层插件的核心js文件layer.js:

3、在admin-GoodsController-ajaxGetContent获取商品的数据,返回json数据

效果:

作业:使用ajax修改商品的是否热卖等状态,类似于ecshop如下:

