1. 程式人生 > >品優購專案記錄:day06

品優購專案記錄:day06

今日目標:

        (1)完成選擇商品分類

        (2)完成品牌選擇功能

        (3)完成擴充套件屬性錄入

        (4)完成規格選擇功能

        (5)完成SKU商品資訊功能

        (6)完成是否啟用規格

目錄

1、商品錄入[2]

1.1 商品分類選擇

(1)複製 ItemCat相關控制層類,itemCatService.js 到 shop-web中

(2)在goodsController.js 中引入 itemCatService,並在頁面引入itemCatService.js檔案

(3)編寫goodsController.js,新增方法

    // 展示一級下拉列表
    $scope.selectItemCat1List = function () {
        itemCatService.findByParentId(0).success(
            function (rtn) {
                $scope.itemCat1List = rtn;
            }
        );
    }
    
    // 關聯展示二級下拉列表
    $scope.$watch('entity.goods.category1Id',function (newValue,oldValue) {
        // alert(newValue);
        itemCatService.findByParentId(newValue).success(
            function (rtn) {
                $scope.itemCat2List = rtn;
            }
        );
    });

    // 關聯展示三級下拉列表
    $scope.$watch('entity.goods.category2Id',function (newValue,oldValue) {
        // alert(newValue);
        itemCatService.findByParentId(newValue).success(
            function (rtn) {
                $scope.itemCat3List = rtn;
            }
        );
    });

    // 關聯展示模板id
    $scope.$watch('entity.goods.category3Id',function (newValue,oldValue) {
        // alert(newValue);
        itemCatService.findOne(newValue).success(
            function (rtn) {
                $scope.entity.goods.typeTemplateId = rtn.typeId;
            }
        );
    });

(4)為下拉框繫結變數,使用ng-options指令載入資料

(5)為模板ID繫結變數

(6)效果

1.2 品牌選擇

(1)將typeTemplate控制層,以及typeTemplateService.js複製到shop-web下

(2)在goodsController.js 中引入 typeTemplateService,並在頁面引入typeTemplateService.js檔案

(3)編寫goodsController.js,新增方法

    // 關聯載入品牌下拉列表
    $scope.$watch('entity.goods.typeTemplateId',function (newValue,oldValue) {
        // alert(newValue);
        typeTemplateService.findOne(newValue).success(
            function (rtn) {
                $scope.typeTemplate = rtn;
                // 將字串轉換為json物件
                $scope.typeTemplate.brandIds = JSON.parse($scope.typeTemplate.brandIds);
            }
        );
    });

(4)品牌下拉框繫結變數

(5)效果:

1.3 擴充套件屬性錄入

(1)改造goodsController.js的監控typeTemplateId的方法

(2)頁面繫結變數

1.4 規格選擇

(1)後端:服務層介面,TypeTemplateService(sellergoods-interface)

	/**
	 * 獲取規格列表
	 *
	 * @param id 模板id
	 * @return java.util.List<java.util.Map>
	 */
	List<Map> findSpecList(Long id);

(2)後端:服務層實現,TypeTemplateServiceImpl(sellergoods-service)

    @Override
    public List<Map> findSpecList(Long id) {
        // 根據模板id查詢模板
        TbTypeTemplate typeTemplate = typeTemplateMapper.selectByPrimaryKey(id);
        // 將SpecIds轉換為集合
        List<Map> list = JSON.parseArray(typeTemplate.getSpecIds(), Map.class);
        // 遍歷集合
        for (Map m : list) {
            // 查詢對應ID的規格選項列表
            TbSpecificationOptionExample example = new TbSpecificationOptionExample();
            example.createCriteria().andSpecIdEqualTo(new Long(String.valueOf(m.get("id"))));
            List<TbSpecificationOption> options = specificationOptionMapper.selectByExample(example);

            // 將options 放入map中
            m.put("options", options);
        }

        return list;
    }

(3)後端:控制層,TypeTemplateController(shop-web)

    @RequestMapping("/findSpecList")
    public List<Map> findSpecList(Long id) {
        return typeTemplateService.findSpecList(id);
    }

(4)前端:編寫typeTemplateService.js,新增方法

    this.findSpecList = function (id) {
        return $http.get('../typeTemplate/findSpecList.do?id=' + id);
    }

(5)前端:修改goodsController.js

(6)前端:編寫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;
    }

(7)前端:編寫goodsController.js

    // 更新specificationItems集合
    $scope.updateSpecAttribute = function ($event, name, value) {
        var object = $scope.searchObjectByKey($scope.entity.goodsDesc.specificationItems, 'attributeName', name);
        // 判斷是否存在該key的值
        if (object == null) {//不存在
            // 新增
            $scope.entity.goodsDesc.specificationItems.push({"attributeName": name, "attributeValue": [value]})
        } else {// 存在
            if ($event.target.checked) {//勾選
                // 追加
                object.attributeValue.push(value);
            } else {// 取消勾選
                if(object.attributeValue.length > 1) {
                    object.attributeValue.splice(object.attributeValue.indexOf(value),1);
                } else {
                    var index = $scope.entity.goodsDesc.specificationItems.indexOf(object);
                    $scope.entity.goodsDesc.specificationItems.splice(index,1);
                }
            }

        }
    }

注意初始化specificationItems:

(8)前端:頁面繫結變數,展示規格列表

1.5 SKU商品資訊(重點理解邏輯)

(1)前端:編寫goodsController.js

    // 構建SKU商品列表
    $scope.createItemList = function () {
        // 初始化SKU商品列表
        $scope.entity.itemList = [{spec: {}, price: 0, num: 9999, status: '0', isDefault: '0'}];
        var specificationItems = $scope.entity.goodsDesc.specificationItems;

        for (var i = 0; i < specificationItems.length; i++) {
            // 用新生成的列表,覆蓋久的列表
            $scope.entity.itemList = addColumn($scope.entity.itemList,specificationItems[i].attributeName,specificationItems[i].attributeValue);
        }
    }

    /**
     * 生成SKU列表的方法
     *
     * @param list          原集合
     * @param columnName    新生成列的列名
     * @param columnValues  新生成列的值列表
     * @return SKU列表
     */
    addColumn = function (list, columnName, columnValues) {
        var SKUList = [];
        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));
                // 將值,追加到新增行
                newRow.spec[columnName] = columnValues[j];
                // 將新的行物件,新增到要SKU列表中
                SKUList.push(newRow);
            }
        }
        return SKUList;
    }

(2)前端:複選框繫結單擊事件

(3)前端:繫結變數

(4)效果:

(5)是否啟用規格

(6)後端:服務層實現,修改add方法

    /**
     * 增加
     */
    @Override
    public void add(Goods goods) {
        /***************************
         * 儲存商品基本資訊到goods表 *
         **************************/
        // 補全商品基本資訊
        TbGoods tbGoods = goods.getGoods();
        tbGoods.setAuditStatus(TbGoods.STATUS_CREATE);
        // 儲存商品基本資訊
        goodsMapper.insert(tbGoods);


        /*******************************
         * 儲存商品擴充套件資訊到goodsdesc表 *
         *******************************/
        // 補全商品擴充套件資訊資料
        TbGoodsDesc tbGoodsDesc = goods.getGoodsDesc();
        tbGoodsDesc.setGoodsId(tbGoods.getId());
        // 儲存商品擴充套件資訊
        goodsDescMapper.insert(tbGoodsDesc);


        /*******************************
         *   儲存SKU商品資訊到 item表    *
         *******************************/
        saveItemList(goods, tbGoods, tbGoodsDesc);


    }

    /**
     * 儲存SKU商品資訊
     *
     * @param goods       組合商品物件
     * @param tbGoods     商品基本資訊物件
     * @param tbGoodsDesc 商品擴充套件資訊物件
     */
    private void saveItemList(Goods goods, TbGoods tbGoods, TbGoodsDesc tbGoodsDesc) {
        // 判斷是否啟用規格
        if (tbGoods.getIsEnableSpec().equals(TbGoods.ISENABLESPEC_YES)) {// 啟用規格
            // 遍歷itemList,補全資料並儲存
            for (TbItem item : goods.getItemList()) {
                // 設定標題
                item.setTitle(builderTitle(tbGoods, item).toString());
                // 補全其他資料
                setValues(tbGoods, tbGoodsDesc, item);

                // 儲存SKU商品資訊
                itemMapper.insert(item);
            }
        } else {// 未啟用規格
            TbItem item = new TbItem();
            // 設定標題,直接為商品名稱
            item.setTitle(tbGoods.getGoodsName());
            // 補全其他資料
            setValues(tbGoods, tbGoodsDesc, item);

            // 儲存SKU商品資訊
            itemMapper.insert(item);
        }

    }

    /**
     * 補全item資料
     *
     * @param tbGoods     當前儲存的商品
     * @param tbGoodsDesc 商品的擴充套件資訊
     * @param item        SKU商品物件
     */
    private void setValues(TbGoods tbGoods, TbGoodsDesc tbGoodsDesc, TbItem item) {
        // 設定商品分類ID
        item.setCategoryid(tbGoods.getCategory3Id());
        // 設定建立日期和更新日期
        item.setCreateTime(new Date());
        item.setUpdateTime(new Date());
        // 設定商品ID
        item.setGoodsId(tbGoods.getId());
        // 設定商家ID
        item.setSeller(tbGoods.getSellerId());
        // 設定商品分類名稱
        TbItemCat itemCat = itemCatMapper.selectByPrimaryKey(tbGoods.getCategory3Id());
        item.setCategory(itemCat.getName());
        // 設定品牌名稱
        TbBrand brand = brandMapper.selectByPrimaryKey(tbGoods.getBrandId());
        item.setBrand(brand.getName());
        // 設定商家名稱(店鋪名)
        TbSeller seller = sellerMapper.selectByPrimaryKey(tbGoods.getSellerId());
        item.setSeller(seller.getNickName());
        // 設定圖片
        List<Map> mapList = JSON.parseArray(tbGoodsDesc.getItemImages(), Map.class);
        if (mapList.size() > 0) {
            item.setImage(String.valueOf(mapList.get(0).get("url")));
        }
    }


    /**
     * 構造SKU商品資訊的標題
     *
     * @param tbGoods 當前儲存的商品
     * @param item    SKU商品物件
     * @return java.lang.StringBuilder
     */
    private StringBuilder builderTitle(TbGoods tbGoods, TbItem item) {
        // 使用tbGoods和規格選項構造SKU名稱
        StringBuilder stringBuilder = new StringBuilder(tbGoods.getGoodsName());
        Map<String, Object> spec = JSON.parseObject(item.getSpec());
        for (String key : spec.keySet()) {
            stringBuilder.append(spec.get(key));
        }
        return stringBuilder;
    }

注意:其中儲存SKU商品資訊列表時,邏輯較多,所以我對程式碼進行了提取到單獨的方法,若是後期邏輯有變動,修改起來更加的方便。