什么是商品规格参数
分析:
同一个商品类目下的商品的规格参数的格式(内容)一样,只是具体的数据不同。
不同的类目的商品规格参数的格式是不同的。
如何实现?
方案一:
针对每一个商品类目都创建一张表,来存储规格参数数据。就需要存储很多张表。
可行性: 不推荐。 维护的表太多了。
方案二:
使用模板的思想实现。
方案二具体实现:
1、 模板如何存储?
a) 存储到数据库
b) 字段不能固定
i. Map
ii. Json
2、 存储的json结构
a) 模板结构
b) 最终数据结构
数据库表结构
需要有2张表:
1、 模板表,需要和商品类目关联
2、 规格参数数据表,需要和商品关联
模板表
最终数据表
实现
导入pojo
package com.taotao.manage.pojo;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Table(name = "tb_item_param")
public class ItemParam extends BasePojo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "item_cat_id")
private Long itemCatId;
@Column(name = "param_data")
private String paramData;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getItemCatId() {
return itemCatId;
}
public void setItemCatId(Long itemCatId) {
this.itemCatId = itemCatId;
}
public String getParamData() {
return paramData;
}
public void setParamData(String paramData) {
this.paramData = paramData;
}
}
package com.taotao.manage.pojo;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Table(name = "tb_item_param_item")
public class ItemParamItem extends BasePojo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "item_id")
private Long itemId;
@Column(name = "param_data")
private String paramData;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getItemId() {
return itemId;
}
public void setItemId(Long itemId) {
this.itemId = itemId;
}
public String getParamData() {
return paramData;
}
public void setParamData(String paramData) {
this.paramData = paramData;
}
}
创建Mapper
package com.taotao.manage.mapper;
import com.github.abel533.mapper.Mapper;
import com.taotao.manage.pojo.ItemParam;
public interface ItemParamMapper extends Mapper<ItemParam>{
}
package com.taotao.manage.mapper;
import com.github.abel533.mapper.Mapper;
import com.taotao.manage.pojo.ItemParamItem;
public interface ItemParamItemMapper extends Mapper<ItemParamItem>{
}
创建Service
package com.taotao.manage.service;
import org.springframework.stereotype.Service;
import com.taotao.manage.pojo.ItemParam;
@Service
public class ItemParamService extends BaseService<ItemParam>{
}
package com.taotao.manage.service;
import org.springframework.stereotype.Service;
import com.taotao.manage.pojo.ItemParamItem;
@Service
public class ItemParamItemService extends BaseService<ItemParamItem> {
}
创建Controller
package com.taotao.manage.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.taotao.manage.service.ItemParamService;
@RequestMapping("item/param")
@Controller
public class ItemParamController {
@Autowired
private ItemParamService itemParamService;
}
package com.taotao.manage.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.taotao.manage.service.ItemParamItemService;
@RequestMapping("item/param/item")
@Controller
public class ItemParamItemController {
@Autowired
private ItemParamItemService itemParamItemService;
}
页面功能
选择类目
根据选择的类目进行判断,如果该类目所对应的模板存在,提醒用户已经存在,如果模板不存在,可以创建模板。
后台开发根据类目id查找模板的接口
package com.taotao.manage.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.taotao.manage.pojo.ItemParam;
import com.taotao.manage.service.ItemParamService;
@RequestMapping("item/param")
@Controller
public class ItemParamController {
@Autowired
private ItemParamService itemParamService;
/**
* 根据商品类目id查询规格参数模板
*
* @param itemCatId
* @return
*/
@RequestMapping(value = "{itemCatId}", method = RequestMethod.GET)
public ResponseEntity<ItemParam> queryByItemCatId(@PathVariable("itemCatId") Long itemCatId) {
try {
ItemParam record = new ItemParam();
record.setItemCatId(itemCatId);
ItemParam itemParam = this.itemParamService.queryOne(record);
if (null == itemParam) {
// 404
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
}
return ResponseEntity.ok(itemParam);
} catch (Exception e) {
e.printStackTrace();
}
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
}
}
JS实现
执行传入的函数:
点击提交事件
$("#itemParamAddTable .submit").click(function(){
var params = [];
var groups = $("#itemParamAddTable [name=group]");
groups.each(function(i,e){
var p = $(e).parentsUntil("ul").parent().find("[name=param]");
var _ps = [];
p.each(function(_i,_e){
var _val = $(_e).siblings("input").val();
if($.trim(_val).length>0){
_ps.push(_val);
}
});
var _val = $(e).siblings("input").val();
if($.trim(_val).length>0 && _ps.length > 0){
params.push({
"group":_val,
"params":_ps
});
}
});
var url = "/rest/item/param/"+$("#itemParamAddTable [name=cid]").val();
$.post(url,{"paramData":JSON.stringify(params)},function(data){
$.messager.alert('提示','新增商品规格成功!',undefined,function(){
$(".panel-tool-close").click();
$("#itemParamList").datagrid("reload");
});
});
});
查看提交数据:
提交的数据结构:
后端实现
package com.taotao.manage.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import com.taotao.manage.pojo.ItemParam;
import com.taotao.manage.service.ItemParamService;
@RequestMapping("item/param")
@Controller
public class ItemParamController {
@Autowired
private ItemParamService itemParamService;
/**
* 根据商品类目id查询规格参数模板
*
* @param itemCatId
* @return
*/
@RequestMapping(value = "{itemCatId}", method = RequestMethod.GET)
public ResponseEntity<ItemParam> queryByItemCatId(@PathVariable("itemCatId") Long itemCatId) {
try {
ItemParam record = new ItemParam();
record.setItemCatId(itemCatId);
ItemParam itemParam = this.itemParamService.queryOne(record);
if (null == itemParam) {
// 404
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
}
return ResponseEntity.ok(itemParam);
} catch (Exception e) {
e.printStackTrace();
}
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
}
/**
* 新增规格参数模板
*
* @param itemCatId
* @param paramData
* @return
*/
@RequestMapping(value = "{itemCatId}", method = RequestMethod.POST)
public ResponseEntity<Void> saveItemParam(@PathVariable("itemCatId") Long itemCatId,
@RequestParam("paramData") String paramData) {
try {
ItemParam itemParam = new ItemParam();
itemParam.setId(null);
itemParam.setItemCatId(itemCatId);
itemParam.setParamData(paramData);
this.itemParamService.save(itemParam);
return ResponseEntity.status(HttpStatus.CREATED).build();
} catch (Exception e) {
e.printStackTrace();
}
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
测试效果:
然后我们在重新选择手机类目:
点击确定会重新打开选择类目框:
新增商品时套用模板输入数据
选择类目时触发加载模板
动态生成form表单内容:
添加商品选择类目(选择手机)之后效果如下:
点击提交按钮,将用户的输入,生成json数据
后台实现
修改ItemController:
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<Void> saveItem(Item item, @RequestParam("desc") String desc,
@RequestParam("itemParams") String itemParams) {
try {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("新增商品, item = {}, desc = {}", item, desc);
}
if (StringUtils.isEmpty(item.getTitle())) { // TODO 未完成,待优化
// 参数有误, 400
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
}
// 保存商品
Boolean bool = this.itemService.saveItem(item, desc, itemParams);
if (!bool) {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("新增商品失败, item = {}", item);
}
// 保存失败
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
if (LOGGER.isInfoEnabled()) {
LOGGER.info("新增商品成功, itemId = {}", item.getId());
}
return ResponseEntity.status(HttpStatus.CREATED).build();
} catch (Exception e) {
LOGGER.error("新增商品出错! item = " + item, e);
}
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
修改Service:
package com.taotao.manage.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.github.abel533.entity.Example;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.taotao.common.bean.EasyUIResult;
import com.taotao.manage.mapper.ItemMapper;
import com.taotao.manage.pojo.Item;
import com.taotao.manage.pojo.ItemDesc;
import com.taotao.manage.pojo.ItemParamItem;
@Service
public class ItemService extends BaseService<Item> {
@Autowired
private ItemDescService itemDescService;
@Autowired
private ItemMapper itemMapper;
@Autowired
private ItemParamItemService itemParamItemService;
public Boolean saveItem(Item item, String desc, String itemParams) {
// 初始值
item.setStatus(1);
item.setId(null); // 出于安全考虑,强制设置id为null,通过数据库自增长得到
Integer count1 = super.save(item);
// 保存商品描述数据
ItemDesc itemDesc = new ItemDesc();
itemDesc.setItemId(item.getId());
itemDesc.setItemDesc(desc);
Integer count2 = this.itemDescService.save(itemDesc);
// 保存规格参数数据
ItemParamItem itemParamItem = new ItemParamItem();
itemParamItem.setItemId(item.getId());
itemParamItem.setParamData(itemParams);
Integer count3 = this.itemParamItemService.save(itemParamItem);
return count1.intValue() == 1 && count2.intValue() == 1 && count3.intValue() == 1;
}
public EasyUIResult queryItemList(Integer page, Integer rows) {
// 设置分页参数
PageHelper.startPage(page, rows);
Example example = new Example(Item.class);
// 安装创建时间排序
example.setOrderByClause("created DESC");
List<Item> items = this.itemMapper.selectByExample(example);
PageInfo<Item> pageInfo = new PageInfo<Item>(items);
return new EasyUIResult(pageInfo.getTotal(), pageInfo.getList());
}
public Boolean updateItem(Item item, String desc) {
// 强制设置状态不能被修改
item.setCreated(null);
item.setStatus(null);
Integer count1 = super.updateSelective(item);
ItemDesc itemDesc = new ItemDesc();
itemDesc.setItemId(item.getId());
itemDesc.setItemDesc(desc);
Integer count2 = this.itemDescService.updateSelective(itemDesc);
return count1.intValue() == 1 && count2.intValue() == 1;
}
}
测试效果:
编辑商品 – 规格参数回显
编辑商品时通过商品id查询规格参数数据:
后台实现:
package com.taotao.manage.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.taotao.manage.pojo.ItemParamItem;
import com.taotao.manage.service.ItemParamItemService;
@RequestMapping("item/param/item")
@Controller
public class ItemParamItemController {
@Autowired
private ItemParamItemService itemParamItemService;
/**
* 根据商品id查询规格参数数据
*
* @param itemId
* @return
*/
@RequestMapping(value = "{itemId}", method = RequestMethod.GET)
public ResponseEntity<ItemParamItem> queryByItemId(@PathVariable("itemId") Long itemId) {
try {
ItemParamItem record = new ItemParamItem();
record.setItemId(itemId);
ItemParamItem itemParamItem = this.itemParamItemService.queryOne(record);
if (null == itemParamItem) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
}
return ResponseEntity.ok(itemParamItem);
} catch (Exception e) {
e.printStackTrace();
}
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
}
}
前端JS:
效果:
更新规格参数数据
提交的数据格式:
后台处理:
修改ItemController:
/**
* 更新商品
*
* @param item
* @param desc
* @param itemParams
* @return
*/
@RequestMapping(method = RequestMethod.PUT)
public ResponseEntity<Void> updateItem(Item item, @RequestParam("desc") String desc,
@RequestParam("itemParams") String itemParams) {
try {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("编辑商品, item = {}, desc = {}", item, desc);
}
if (StringUtils.isEmpty(item.getTitle())) { // TODO 未完成,待优化
// 参数有误, 400
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
}
// 编辑商品
Boolean bool = this.itemService.updateItem(item, desc, itemParams);
if (!bool) {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("编辑商品失败, item = {}", item);
}
// 保存失败, 500
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
if (LOGGER.isInfoEnabled()) {
LOGGER.info("编辑商品成功, itemId = {}", item.getId());
}
// 204
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
} catch (Exception e) {
LOGGER.error("编辑商品出错! item = " + item, e);
}
// 500
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
Service:
public Boolean updateItem(Item item, String desc, String itemParams) {
item.setStatus(null);// 强制设置状态不能被修改
Integer count1 = super.updateSelective(item);
ItemDesc itemDesc = new ItemDesc();
itemDesc.setItemId(item.getId());
itemDesc.setItemDesc(desc);
Integer count2 = this.itemDescService.updateSelective(itemDesc);
// 更新规格参数数据
Integer count3 = this.itemParamItemService.updateItemParamItem(item.getId(), itemParams);
return count1.intValue() == 1 && count2.intValue() == 1 && count3.intValue() == 1;
}
ItemParamItemService:
package com.taotao.manage.service;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.github.abel533.entity.Example;
import com.taotao.manage.mapper.ItemParamItemMapper;
import com.taotao.manage.pojo.ItemParamItem;
@Service
public class ItemParamItemService extends BaseService<ItemParamItem> {
@Autowired
private ItemParamItemMapper itemParamItemMapper;
public Integer updateItemParamItem(Long itemId, String itemParams) {
// 更新数据
ItemParamItem itemParamItem = new ItemParamItem();
itemParamItem.setParamData(itemParams);
itemParamItem.setUpdated(new Date());
// 更新的条件
Example example = new Example(ItemParamItem.class);
example.createCriteria().andEqualTo("itemId", itemId);
return this.itemParamItemMapper.updateByExampleSelective(itemParamItem, example);
}
}
效果: