1 课程计划
内容复习:
1、商品添加功能
a) 商品类目的选择。easyUI异步tree的使用。
b) 图片上传
i. 图片服务器。http服务、ftp服务。
ii. 使用kindEditor的图片上传插件实现上传。返回结果是一个json形式的字符串。
c) 富文本编辑器的使用
i. 引用富文本编辑器的js
ii. Jsp中添加一个textarea控件
iii. 基于textarea控件创建富文本编辑器。调用kindEditor的create方法。
iv. 表单提交前,需要把富文本编辑器的内容和textarea同步。Sync方法。
今天的内容:
1、商品描述的保存
2、商品规格的添加及使用
1、使用多个表实现商品规格
2、使用模板实现商品规格
2 商品描述的保存
后台要接收前台页面提交的商品信息,及商品描述。商品信息保存还要保存商品描述。
数据库中商品信息和商品描述是分开存储的。
2.1 Dao层
把商品描述信息保存到tb_item_desc表中。
可以使用逆向工程生成的代码
2.2 Service层
接收商品描述调用dao把商品描述插入到表中。
参数:String 商品描述
返回值:TaotaoResult
@Override public TaotaoResult createItem(TbItem item, String desc) throws Exception { //item补全 //生成商品ID Long itemId = IDUtils.genItemId(); item.setId(itemId); // '商品状态,1-正常,2-下架,3-删除', item.setStatus((byte) 1); item.setCreated(new Date()); item.setUpdated(new Date()); //插入到数据库 itemMapper.insert(item); //添加商品描述信息 TaotaoResult result = insertItemDesc(itemId, desc); if (result.getStatus() != 200) { throw new Exception(); } return TaotaoResult.ok(); } /** * 添加商品描述 * <p>Title: insertItemDesc</p> * <p>Description: </p> * @param desc */ private TaotaoResult insertItemDesc(Long itemId, String desc) { TbItemDesc itemDesc = new TbItemDesc(); itemDesc.setItemId(itemId); itemDesc.setItemDesc(desc); itemDesc.setCreated(new Date()); itemDesc.setUpdated(new Date()); itemDescMapper.insert(itemDesc); return TaotaoResult.ok(); } |
2.3 Controller
接收商品描述信息。
3 商品规格
3.1 什么是商品规格
规格参数:
规格组
|-规格项:规格值
规律:
1、同一类商品的规格项分组相同。
2、同一类商品的规格项目是相同的。规格项目是跟商品关联。
3、不同商品规格参数的值是不同的
3.2 实现方案
3.2.1 方案一:使用多个表来存储
1、每一类商品有多个分组
2、每个分组下有多个项
3、每个商品对应不同的规格参数
使用二维表来维护规格数据。
表一:规格组信息
列名 |
类型 |
长度 |
可以null |
键 |
说明 |
Id |
Int |
|
否 |
P |
主键(自增长) |
group_name |
varchar |
20 |
否 |
|
规格分组名称 |
item_cat_id |
Int |
|
否 |
F |
商品分类id(外键) |
表二:规格项信息
列名 |
类型 |
长度 |
可以null |
键 |
说明 |
Id |
Int |
|
否 |
P |
主键(自增长) |
param_name |
varchar |
20 |
否 |
|
规格项目名称 |
group_id |
Int |
|
否 |
F |
规格分组id(外键) |
表三:商品规格信息
列名 |
类型 |
长度 |
可以null |
键 |
说明 |
item_id |
Int |
|
否 |
P |
商品id(联合主键) |
param_id |
varchar |
|
否 |
P |
规格项id(联合主键) |
param_value |
varchar |
500 |
否 |
|
规格信息 |
3.2.2 Sql语句
SELECT pg.group_name,pk.param_name,pv.param_value FROM tb_item_param_value pv LEFT JOIN tb_item_param_key pk ON pv.param_id = pk.id LEFT JOIN tb_item_param_group pg ON pk.group_id = pg.id WHERE item_id = 855739 |
3.2.3 方案一存在的问题:
1、需要创建多张表来描述规格参数之间的关系。
2、查询时需要复杂的sql语句查询。
3、规格参数数据量是商品信息的几十倍,数据量十分庞大。查询时效率很低。
4、如果要求新添加的商品规格项发生改变,之前的商品不变是不能实现的。
3.3 方案二
3.3.1 方案分析
可以使用模板的思路来解决此问题。
1、每一个商品分类对一个规格参数模板。
[
{
"group": "主体", //组名称
"params": [ // 记录规格成员
"品牌",
"型号",
"颜色",
"上市年份",
"上市月份"
]
},
{
"group": "网络", //组名称
"params": [ // 记录规格成员
"4G",
"3G,
"2G"
]
}
]
2、使用模板
每个商品对应一唯一的规格参数。在添加商品时,可以根据规格参数的模板。生成一个表单。保存规格参数时。还可以生成规格参数的json数据。保存到数据库中。
[
{
"group": "主体",
"params": [
{
"k": "品牌",
"v": "苹果(Apple)"
},
{
"k": "型号",
"v": "iPhone 6A1589"
},
{
"k": "智能机",
"v": "是 "
}
]
}
]
3.3.2 实现流程
3.3.3 数据库存储
规格参数模板表:
商品的规格参数表:
优点:
1、不需要做多表管理。
2、如果要求新添加的商品规格项发生改变,之前的商品不变是很简单的。
缺点:
复杂的表单和json之间的转换。对js的编写要求很高。
4 创建规格参数模板
4.1 选择商品分类
选择商品分类后根据选择的商品分类到tb_item_param规格参数模板表中取规格模板,取到了说明此商品分类的规格模板已经添加提示不能添加。
如果没有取得正常添加。
|
4.1.1 功能分析
请求的url:
/item/param/query/itemcatid/{itemCatId}
参数:itemCatId,从url中获得
返回值:TaotaoResult
4.1.2 Dao层
从tb_item_param表中根据商品分类id查询内容。
单表操作。可以实现逆向工程的代码。
4.1.3 Service层
功能:接收商品分类id。调用mapper查询tb_item_param表,返回结果TaotaoResult。
@Service public class ItemParamServiceImpl implements ItemParamService {
@Autowired private TbItemParamMapper itemParamMapper;
@Override public TaotaoResult getItemParamByCid(long cid) { TbItemParamExample example = new TbItemParamExample(); Criteria criteria = example.createCriteria(); criteria.andItemCatIdEqualTo(cid); List<TbItemParam> list = itemParamMapper.selectByExample(example); //判断是否查询到结果 if (list != null && list.size() > 0) { return TaotaoResult.ok(list.get(0)); }
return TaotaoResult.ok(); }
} |
4.1.4 Controller
接收cid参数。调用Service查询规格参数模板。返回TaotaoResult。返回json数据。
@Controller @RequestMapping("/item/param") public class ItemParamController {
@Autowired private ItemParamService itemParamService;
@RequestMapping("/query/itemcatid/{itemCatId}") @ResponseBody public TaotaoResult getItemParamByCid(@PathVariable Long itemCatId) { TaotaoResult result = itemParamService.getItemParamByCid(itemCatId); returnresult; } } |
4.1.5 Jsp
4.2 提交规格参数模板
4.2.1 需求分析
首先把页面中所有文本框中的内容转换成json数据。把json字符串提交给后台。保存到规格参数表中。
请求的url:
/item/param/save/{cid}
参数:
String paramData
返回值:
TaotaoResult
4.2.2 Dao层
保存规格参数模板,向tb_item_param表添加一条记录。可以使用逆向工程生成的代码。
4.2.3 Service层
功能:接收TbItemParam对象。 把对象调用mapper插入到tb_item_param表中。返回TaotaoResult。
@Override public TaotaoResult insertItemParam(TbItemParam itemParam) { //补全pojo itemParam.setCreated(new Date()); itemParam.setUpdated(new Date()); //插入到规格参数模板表 itemParamMapper.insert(itemParam); return TaotaoResult.ok(); } |
4.2.4 Controller层
功能:接收cid、规格参数模板。创建一TbItemParam对象。调用Service返回TaotaoResult。返回json数据。
@RequestMapping("/save/{cid}") @ResponseBody public TaotaoResult insertItemParam(@PathVariable Long cid, String paramData) { //创建pojo对象 TbItemParam itemParam = new TbItemParam(); itemParam.setItemCatId(cid); itemParam.setParamData(paramData); TaotaoResult result = itemParamService.insertItemParam(itemParam); returnresult; } |
5 根据规格参数模板生成表单
在商品添加功能中,读取此商品对应的规格模板,生成表单。供使用者添加规格参数。
5.1 需求分析
Service修改:
6 保存商品的规格参数
6.1 需求分析
提交表单之前,先把规格参数表单中的内容转换成json数据然后跟商品基本信息、商品描述同时提交给后台。保存至数据库。
转换后把规格参数的信息放到表单的hidden域中:
随着表单的提交同时提交。
6.2 Dao层
需要向tb_item_param_item表中添加数据。
6.3 Service层
接收规格参数的内容,和商品id。拼装成pojo调用mapper 的方法tb_item_param_item表中添加数据返回TaotaoResult。
/** * 添加规格参数 * <p>Title: insertItemParamItem</p> * <p>Description: </p> * @param itemId * @param itemParam * @return */ private TaotaoResult insertItemParamItem(Long itemId, String itemParam) { //创建一个pojo TbItemParamItem itemParamItem = new TbItemParamItem(); itemParamItem.setItemId(itemId); itemParamItem.setParamData(itemParam); itemParamItem.setCreated(new Date()); itemParamItem.setUpdated(new Date()); //向表中插入数据 itemParamItemMapper.insert(itemParamItem);
return TaotaoResult.ok();
} |
6.4 表现层
接收规格参数信息,调用Service层保存商品信息及商品描述及商品规格参数。返回taotaoResult.
7 展示规格参数
当现实商品详情页面时,需要把商品的规格参数根据商品id取出来,生成html展示到页面。
7.1 Dao层
根据商品id查询规格参数,单表查询。
7.2 Service
接收商品id查询规格参数表。根据返回的规格参数生成html返回html。
@Service public class ItemParamItemServiceImpl implements ItemParamItemService {
@Autowired private TbItemParamItemMapper itemParamItemMapper;
@Override public String getItemParamByItemId(Long itemId) { //根据商品id查询规格参数 TbItemParamItemExample example = new TbItemParamItemExample(); Criteria criteria = example.createCriteria(); criteria.andItemIdEqualTo(itemId); //执行查询 List<TbItemParamItem> list = itemParamItemMapper.selectByExampleWithBLOBs(example); if (list == null || list.size() == 0) { return ""; } //取规格参数信息 TbItemParamItem itemParamItem = list.get(0); String paramData = itemParamItem.getParamData(); //生成html // 把规格参数json数据转换成java对象 List<Map> jsonList = JsonUtils.jsonToList(paramData, Map.class); StringBuffer sb = new StringBuffer(); sb.append("<table cellpadding=\"0\" cellspacing=\"1\" width=\"100%\" border=\"0\" class=\"Ptable\">\n"); sb.append(" <tbody>\n"); for(Map m1:jsonList) { sb.append(" <tr>\n"); sb.append(" <th class=\"tdTitle\" colspan=\"2\">"+m1.get("group")+"</th>\n"); sb.append(" </tr>\n"); List<Map> list2 = (List<Map>) m1.get("params"); for(Map m2:list2) { sb.append(" <tr>\n"); sb.append(" <td class=\"tdTitle\">"+m2.get("k")+"</td>\n"); sb.append(" <td>"+m2.get("v")+"</td>\n"); sb.append(" </tr>\n"); } } sb.append(" </tbody>\n"); sb.append("</table>"); return sb.toString(); }
} |
7.3 Controller
接收商品id调用Service查询规格参数信息,得到规格参数的html。返回一个逻辑视图。把html展示到页面。
@Controller public class ItemParamItemController {
@Autowired private ItemParamItemService itemParamItemService;
@RequestMapping("/item/{itemId}") public String showItemParam(@PathVariable Long itemId, Model model) { String string = itemParamItemService.getItemParamByItemId(itemId); model.addAttribute("itemParam", string); return"item"; } } |