商品錄入【規格選擇】
4.1需求分析
顯示規格及選項列表(複選框)如下圖,並保存用戶選擇的結果
4.2代碼實現
4.2.1 顯示規格選項列表
由於我們的模板中只記錄了規格名稱,而我們除了顯示規格名稱還是顯示規格下的規格選項,所以我們需要在後端擴充方法。
(1)在pinyougou-sellergoods-interface的TypeTemplateService.java新增方法定義
/**
* 返回規格列表
* @return
*/
public List<Map> findSpecList(Long id);
在pinyougou-sellergoods-service的TypeTemplateServiceImpl.java新增方法
@Override
public List<Map> findSpecList(Long id) {
//查詢模板
TbTypeTemplate typeTemplate = typeTemplateMapper.selectByPrimaryKey (id);
//獲取到規格字段中的json數據並轉換成map的list集合
List<Map> mapList = JSON.parseArray (typeTemplate.getSpecIds (), Map.class);
for (Map map :
mapList) {
TbSpecificationOptionExample example=new TbSpecificationOptionExample ();
TbSpecificationOptionExample.Criteria criteria = example.createCriteria ();
//獲取到map中的id值並轉換成long型作爲條件
criteria.andSpecIdEqualTo(new Long ((Integer)map.get ("id")));
List<TbSpecificationOption> tbSpecificationOptions = specificationOptionMapper.selectByExample (example);
map.put ("options",tbSpecificationOptions);
}
return mapList;
}
在pinyougou-shop-web的TypeTemplateController.java新增方法
@RequestMapping("/findSpecList") public List<Map> findSpecList(Long id){ return typeTemplateService.findSpecList(id); } |
測試後端代碼:
- 前端代碼:修改pinyougou-shop-web的typeTemplateService.js
//查詢規格列表
this.findSpecList=function (id) {
return $http.get('../typeTemplate/findSpecList.do?id='+id)
}
修改pinyougou-shop-web的goodsController.js
在紅框中添加
//查詢規格列表
typeTemplateService.findSpecList(newValue).success(
function(response){
$scope.specList=response;
}
);
- 修改goods_edit.html頁面
<div ng-repeat="pojo in specList"> <div class="col-md-2 title">{{pojo.text}}</div> <div class="col-md-10 data"> <span ng-repeat="option in pojo.options"> <input type="checkbox" >{{option.optionName}} </span> </div> </div> |
保存選中規格選項
我們需要將用戶選中的選項保存在tb_goods_desc表的specification_items字段中,定義json格式如下:
[{“attributeName”:”規格名稱”,”attributeValue”:[“規格選項1”,“規格選項2”.... ] } , .... ] |
在baseController.js增加代碼
//在list集合中根據某key的值查詢對象
$scope.searchObjectByKey=function (list, key, keyValue) {
for (var i=0;i<list.length;i++){
if (list[i][key]==keyValue){
return list[i];
}
}
return null;
}
在goodsController.js增加代碼
在goodsController.js增加代碼
$scope.entity={ goodsDesc:{itemImages:[],specificationItems:[]} }; |
//勾選時生成的規格詳細
$scope.updateSpecAttribute=function ($event,name,value) {
var object=$scope.searchObjectByKey($scope.entity.tbGoodsDesc.specificationItems,'attributeName',name);
if(object!=null){
if ($event.target.checked){
object.attributeValue.push(value);
}else {
object.attributeValue.splice(object.attributeValue.indexOf(value),1);//移除選項
//如果勾選的都取消了就刪除這個集合
if (object.attributeValue.length==0){
$scope.entity.tbGoodsDesc.specificationItems.splice( $scope.entity.tbGoodsDesc.specificationItems.indexOf(object),1);
}
}
}else {
$scope.entity.tbGoodsDesc.specificationItems.push({"attributeName":name,"attributeValue":[value]});
}
}
(3)在goods_edit.html調用方法
<div ng-repeat="pojo in specList"> <div class="col-md-2 title">{{pojo.text}}</div> <div class="col-md-10 data"> <span ng-repeat="option in pojo.options"> <input type="checkbox" ng-click="updateSpecAttribute($event,pojo.text,option.optionName)">{{option.optionName}} </span> </div> </div> |
爲了方便測試,我們可以在頁面上某個區域臨時添加表達式,以便觀測測試結果
{{entity.goodsDesc.specificationItems}} |
5.商品錄入【SKU商品信息】
5.1需求分析
基於上一步我們完成的規格選擇,根據選擇的規格錄入商品的SKU信息,當用戶選擇相應的規格,下面的SKU列表就會自動生成,如下圖:
實現思路:實現思路:
- 我們先定義一個初始的不帶規格名稱的集合,只有一條記錄。
- 循環用戶選擇的規格,根據規格名稱和已選擇的規格選項對原集合進行擴充,添加規格名稱和值,新增的記錄數與選擇的規格選項個數相同
生成的順序如下圖:
5.2前端代碼
5.2.1 生成SKU列表(深克隆)
(1)在goodsController.js實現創建sku列表的方法
//創建SKU列表
$scope.createItemList=function () {
//用於深克隆初始化
$scope.entity.itemList=[{spec:{},price:0,num:99999,status:'0',isDefault:'0'}];//初始列表對象
var items= $scope.entity.tbGoodsDesc.specificationItems;
for (var i=0;i<items.length;i++){
$scope.entity.itemList=addColumn( $scope.entity.itemList,items[i].attributeName,items[i].attributeValue);
}
}
//添加列值深克隆
addColumn=function (list,columnName,columnValues) {
var newList=[];
for (var i=0;i<list.length;i++){
var oldRow=list[i];
for (var j=0;j<columnValues.length;j++){
var newRow= JSON.parse(JSON.stringify(oldRow));//stringify複製
newRow.spec[columnName]=columnValues[j];
newList.push(newRow);
}
}
return newList;
}
(2)在更新規格屬性後調用生成SKU列表的方法
<input type="checkbox" ng-click="updateSpecAttribute($event,pojo.text,option.optionName);createItemList()">{{option.optionName}} |
(3)在頁面上添加表達式,進行測試
{{entity.itemList}} |
顯示效果如下:
5.2.2 顯示SKU列表
goods_edit.html頁面上綁定SKU列表
<table class="table table-bordered table-striped table-hover dataTable"> <thead> <tr> <th class="sorting" ng-repeat="item in entity.goodsDesc.specificationItems">{{item.attributeName}}</th> <th class="sorting">價格</th> <th class="sorting">庫存</th> <th class="sorting">是否啓用</th> <th class="sorting">是否默認</th> </tr> </thead> <tbody> <tr ng-repeat="pojo in entity.itemList"> <td ng-repeat="item in entity.goodsDesc.specificationItems"> {{pojo.spec[item.attributeName]}} </td> <td> <input class="form-control" ng-model="pojo.price" placeholder="價格"> </td> <td> <input class="form-control" ng-model="pojo.num" placeholder="庫存數量"> </td> <td> <input type="checkbox" ng-model="pojo.status" ng-true-value="1" ng-false-value="0" > </td> <td> <input type="checkbox" ng-model="pojo.isDefault" ng-true-value="1" ng-false-value="0"> </td> </tr> </tbody> </table> |
刪除掉原來的測試用的表達式
5.3後端代碼
(1)在GoodsServiceImpl添加屬性
@Autowired private TbItemMapper itemMapper;
@Autowired private TbBrandMapper brandMapper;
@Autowired private TbItemCatMapper itemCatMapper;
@Autowired private TbSellerMapper sellerMapper; |
(2)修改GoodsServiceImpl的add方法,增加代碼,實現對SKU商品信息的保存
/**
* 增加
*/
@Override
public void add(Goods goods) {
goods.getTbGoods ().setAuditStatus ("0");//狀態:未審覈
goodsMapper.insert(goods.getTbGoods ());//插入商品的基本信息
goods.getTbGoodsDesc ().setGoodsId (goods.getTbGoods ().getId ());//將商品的基本表id給商品擴展表的設置goodsId
goodsDescMapper.insert (goods.getTbGoodsDesc ());//插入商品的擴展表信息
for (TbItem item :
goods.getItemList ()) {
//構建標題SPU名稱+規格選項值
String title= goods.getTbGoods ().getGoodsName ();//SPU名稱
Map<String,Object> map = JSON.parseObject (item.getSpec ());
for (String key :
map.keySet ()) {
title += " " + map.get (key);
}
item.setTitle (title);
//商品分類
item.setCategoryid(goods.getTbGoods ().getCategory3Id ());//三級分類id
item.setCreateTime (new Date ());
item.setUpdateTime (new Date ());
item.setGoodsId (goods.getTbGoods ().getId ());//商品id
item.setSellerId (goods.getTbGoods ().getSellerId ());//商家id
//分類名稱
TbItemCat itemCat = itemCatMapper.selectByPrimaryKey (goods.getTbGoods ().getCategory3Id ());
item.setCategory (itemCat.getName ());
//品牌名稱
TbBrand brand = brandMapper.selectByPrimaryKey (goods.getTbGoods ().getBrandId ());
item.setBrand (brand.getName ());
//商家名稱 店鋪名稱
TbSeller seller = sellerMapper.selectByPrimaryKey (goods.getTbGoods ().getSellerId ());
item.setSeller (seller.getNickName ());
//圖片
List<Map> imageList = JSON.parseArray (goods.getTbGoodsDesc ().getItemImages (), Map.class);
if (imageList.size ()>0 ){
item.setImage (imageList.get (0).get("url").toString ());//存入地址圖片
}
itemMapper.insert(item);
}
}
6.商品錄入【是否啓用規格】
6.1需求分析
在規格面板添加是否啓用規格,當用戶沒有選擇該項,將原來的規格面板和SKU列表隱藏,用戶保存商品後只生成一個SKU.
6.2前端代碼
goods_add.html添加複選框
<div class="row data-type"> <div class="col-md-2 title">是否啓用規格</div> <div class="col-md-10 data"> <input type="checkbox" ng-model="entity.goods.isEnableSpec" ng-true-value="1" ng-false-value="0"> </div> </div> |
用if指令控制規格面板與SKU列表的顯示與隱藏
<div ng-if="entity.goods.isEnableSpec==1"> ......SKU表格部分 </div> |
6.3後端代碼
修改GoodsServiceImpl的add方法
|
/**
* 增加
*/
@Override
public void add(Goods goods) {
goods.getTbGoods ().setAuditStatus ("0");//狀態:未審覈
goodsMapper.insert(goods.getTbGoods ());//插入商品的基本信息
goods.getTbGoodsDesc ().setGoodsId (goods.getTbGoods ().getId ());//將商品的基本表id給商品擴展表的設置goodsId
goodsDescMapper.insert (goods.getTbGoodsDesc ());//插入商品的擴展表信息
if ("1".equals (goods.getTbGoods ().getIsEnableSpec ())){//啓用規格
for (TbItem item :
goods.getItemList ()) {
//構建標題SPU名稱+規格選項值
String title= goods.getTbGoods ().getGoodsName ();//SPU名稱
Map<String,Object> map = JSON.parseObject (item.getSpec ());
for (String key :
map.keySet ()) {
title += " " + map.get (key);
}
item.setTitle (title);
setItemValue (item,goods);
itemMapper.insert(item);
}
}else{//沒有啓用規格
TbItem item=new TbItem ();//創建一個item
item.setTitle (goods.getTbGoods ().getGoodsName ());//設置標題爲商品的名稱
item.setPrice (goods.getTbGoods ().getPrice ());//設置價格
item.setNum (999999);//庫存數量
item.setStatus ("1");//狀態
item.setIsDefault ("1");//默認
item.setSpec ("{}");//規格
setItemValue (item,goods);
itemMapper.insert (item);
}
}
/**
* 通過方法設置item中的屬性值
* @auther: jun
* @date: 2018/9/7 0007 11:12
* @param item 商品信息
* @param goods 商品信息組合信息
* @return: void
*/
private void setItemValue(TbItem item,Goods goods){
//商品分類
item.setCategoryid(goods.getTbGoods ().getCategory3Id ());//三級分類id
item.setCreateTime (new Date ());
item.setUpdateTime (new Date ());
item.setGoodsId (goods.getTbGoods ().getId ());//商品id
item.setSellerId (goods.getTbGoods ().getSellerId ());//商家id
//分類名稱
TbItemCat itemCat = itemCatMapper.selectByPrimaryKey (goods.getTbGoods ().getCategory3Id ());
item.setCategory (itemCat.getName ());
//品牌名稱
TbBrand brand = brandMapper.selectByPrimaryKey (goods.getTbGoods ().getBrandId ());
item.setBrand (brand.getName ());
//商家名稱 店鋪名稱
TbSeller seller = sellerMapper.selectByPrimaryKey (goods.getTbGoods ().getSellerId ());
item.setSeller (seller.getNickName ());
//圖片
List<Map> imageList = JSON.parseArray (goods.getTbGoodsDesc ().getItemImages (), Map.class);
if (imageList.size ()>0 ){
item.setImage (imageList.get (0).get("url").toString ());//存入地址圖片
}
}