淘淘商城第四天

  1. 课程计划

内容复习:

  1. 商品添加功能
    1. 商品类目的选择。easyUI异步tree的使用。
    2. 图片上传
      1. 图片服务器。http服务、ftp服务。使用的是系统自带的vsftp服务器
      2. 使用kindEditor的图片上传插件实现上传。返回结果是一个json形式的字符串。
    3. 富文本编辑器的使用
      1. 引用富文本编辑器的js
      2. Jsp中添加一个textarea控件
      3. 基于textarea控件创建富文本编辑器。调用kindEditor的create方法。
      4. 表单提交前,需要把富文本编辑器的内容和textarea同步。Sync方法。

今天的内容:

  1. 商品描述的保存
  2. 商品规格的添加及使用
  3. 使用多个表实现商品规格
  4. 使用模板实现商品规格
  5. 商品描述的保存

后台要接收前台页面提交的商品信息,及商品描述。商品信息保存还要保存商品描述。

数据库中商品信息和商品描述是分开存储的。

    1. Dao层

把商品描述信息保存到tb_item_desc表中。

可以使用逆向工程生成的代码

    1. 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();

}

    1. Controller

接收商品描述信息。

  1. 商品规格
    1. 什么是商品规格

这个是目前已经存在的技术,已经非常成熟的东西,但是会的人不太多

规格参数:

规格组

  |-规格项:规格值

规律:

1、同一类商品的规格项分组相同。

2、同一类商品的规格项目是相同的。规格项目是跟商品关联。

3、不同商品规格参数的值是不同的

    1. 实现方案
      1. 方案一:使用多个表来存储
  • 每一类商品有多个分组
  • 每个分组下有多个项
  • 每个商品对应不同的规格参数

 

使用二维表来维护规格数据。

表一:规格组信息

列名

类型

长度

可以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

 

规格信息

      1. 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

      1. 方案一存在的问题:
  1. 需要创建多张表来描述规格参数之间的关系。
  2. 查询时需要复杂的sql语句查询。
  3. 规格参数数据量是商品信息的几十倍,数据量十分庞大。查询时效率很低。
  4. 如果要求新添加的商品规格项发生改变,之前的商品不变是不能实现的。
    1. 方案二
      1. 方案分析

可以使用模板的思路来解决此问题。

  1. 每一个商品分类对一个规格参数模板。

[

    {

        "group": "主体",  //组名称

        "params": [ // 记录规格成员

            "品牌",

            "型号",

            "颜色",

            "上市年份",

            "上市月份"

        ]

}

{

        "group": "网络",  //组名称

        "params": [ // 记录规格成员

            "4G",

            "3G,

            "2G"

        ]

}

 

]

  1. 使用模板

每个商品对应一唯一的规格参数。在添加商品时,可以根据规格参数的模板。生成一个表单。保存规格参数时。还可以生成规格参数的json数据。保存到数据库中。

[

    {

        "group": "主体",

        "params": [

            {

                "k": "品牌",

                "v": "苹果(Apple"

            },

            {

                "k": "型号",

                "v": "iPhone 6 A1589"

            },

{

                "k": "智能机",

                "v": " "

            }

 

        ]

}

]

      1. 实现流程

      1. 数据库存储

规格参数模板表:

商品的规格参数表:

优点:

1、不需要做多表管理。

2、如果要求新添加的商品规格项发生改变,之前的商品不变是很简单的。

缺点:

复杂的表单和json之间的转换。对js的编写要求很高。

  1. 创建规格参数模板
    1. 选择商品分类

选择商品分类后根据选择的商品分类到tb_item_param规格参数模板表中取规格模板,取到了说明此商品分类的规格模板已经添加提示不能添加。

如果没有取得正常添加。

 

      1. 功能分析

请求的url:

/item/param/query/itemcatid/{itemCatId}

参数:itemCatId,从url中获得

返回值:TaotaoResult

      1. Dao层

从tb_item_param表中根据商品分类id查询内容。

单表操作。可以实现逆向工程的代码。

      1. 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();

}

 

}

      1. 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);

return result;

}

}

      1. Jsp

    1. 提交规格参数模板
      1. 需求分析

首先把页面中所有文本框中的内容转换成json数据。把json字符串提交给后台。保存到规格参数表中。

请求的url:

/item/param/save/{cid}

参数:

String paramData

返回值:

TaotaoResult

      1. Dao层

保存规格参数模板,向tb_item_param表添加一条记录。可以使用逆向工程生成的代码。

      1. 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();

}

      1. 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);

return result;

}

  1. 根据规格参数模板生成表单

在商品添加功能中,读取此商品对应的规格模板,生成表单。供使用者添加规格参数。

    1. 需求分析

 

Service修改:

  1. 保存商品的规格参数
    1. 需求分析

提交表单之前,先把规格参数表单中的内容转换成json数据然后跟商品基本信息、商品描述同时提交给后台。保存至数据库。

转换后把规格参数的信息放到表单的hidden域中:

随着表单的提交同时提交。

 

    1. Dao层

需要向tb_item_param_item表中添加数据。

 

    1. 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();

 

}

 

 

    1. 表现层

接收规格参数信息,调用Service层保存商品信息及商品描述及商品规格参数。返回taotaoResult.

  1. 展示规格参数

当现实商品详情页面时,需要把商品的规格参数根据商品id取出来,生成html展示到页面。

    1. Dao层

根据商品id查询规格参数,单表查询。

    1. 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();

}

 

}

    1. 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";

}

}