品优购电商系统 3 - 规格及模板管理

本文部分内容来自黑马49期项目实战-品优购电商系统开发

课程目标

  1. 理解和运用AngularJS的service
  2. 理解和运用控制器继承
  3. 掌握代码生成器的使用
  4. 实现规格管理
  5. 实现模板管理

前端分层开发

需求分析

  1. 为了方便维护,使用MVC的设计模式,将代码进行分层,提高程序的可维护性。

代码分离

前端基础层

  1. 在pinyougou-manager-web工程js下创建base.js和base_pagination.js

    1. base.js 用于不需要分页功能的页面

      // 定义模块;
      var app = angular.module("pinyougou", []);
    2. base_pagination.js用于需要分页功能的页面

      // 定义模块;
      var app = angular.module("pinyougou", ["pagination"]);

前端服务层

  1. 在pinyougou-manager-web工程js文件夹下创建service文件夹,创建brandService.js

    // 品牌服务层
    app.service('brandService', function ($http) {
    
        this.findById = function (id) {
            return $http.get("../brand/findOne.do?id="+id);
        }
    
        // 查询品牌列表
        this.findPage = function (page, rows) {
            return $http.get("../brand/findPage.do?page="+page+"&pageSize="+rows);
        };
    
        // 新增产品
        this.save = function (entity) {
            return $http.post("../brand/add.do", entity);
        };
    
        // 更新产品
        this.update = function (entity) {
            return $http.post("../brand/update.do", entity);
        };
    
        // 批量删除
        this.deleteBrands = function (ids) {
            return $http.get("../brand/delete.do?ids=" + ids);
        };
    
        // 条件查询
        this.searchBrand = function (page, rows, searchEntity) {
            return $http.post("../brand/search.do?page=" + page + "&pageSize=" + rows, searchEntity);
        };
    
    });

前端控制层

  1. 在pinyougou-manager-web工程js文件夹下创建controller文件夹,创建brandController.js

    // 定义控制器
    app.controller('brandController', function ($scope, $controller, brandService) {
    
        // 查询品牌列表
        $scope.findPage = function (page, rows) {
            brandService.findPage(page, rows).success(
                function (response) {
                    $scope.brandList = response.rows;
                    $scope.paginationConf.totalItems = response.total;
                }
            );
        };
    
        // 重新加载数据列表
        $scope.reloadBrandList = function() {
    
            // 切换页码
            $scope.search($scope.paginationConf.currentPage, $scope.paginationConf.itemsPerPage);
        };
    
    
        // 分页
        $scope.paginationConf = {
            // 当前页码
            currentPage: 1,
            // 总条数
            totalItems: 10,
            // 每页数量
            itemsPerPage: 10,
            // 页码选项
            perPageOptions: [10, 20, 30, 40, 50],
            // 更改页面时触发事件
            onChange: function () {
                // 重新加载
                $scope.reloadBrandList();
            }
        };
    
        // 新增产品
        $scope.save = function () {
            // 区分是保存还是修改
            var object;
    
            // 如果有实体id,则调用更新方法
            if ($scope.entity.id != null) {
                // 更新
                object = brandService.update($scope.entity);
            } else {
                // 保存
                object = brandService.save($scope.entity);
            }
    
            object.success(
                function (response) {
                    if (response.success) {
                        // 保存成功
                        alert(response.message);
                        // 重新加载数据
                        $scope.reloadBrandList();
                    } else {
                        alert(response.message);
                    }
                }
            );
        };
    
    
        // 查询品牌实体
        $scope.findOne = function (id) {
            brandService.findById(id).success(
                function (response) {
                    $scope.entity = response;
                }
            );
        };
    
        // 选中的Id集合
        $scope.selectIds = [];
    
        // 更新复选
        $scope.updateSelection = function ($event, id) {
    
            // 如果选中,添加到数组中
            if ($event.target.checked) {
                $scope.selectIds.push(id);
            } else {
                // splice方法,从数组的指定位置移除指定个数的元素,第一个参数为位置,第二个参数是移除的个数
                var index = $scope.selectIds.indexOf(id);
                $scope.selectIds.splice(index, 1);
            }
        };
    
        // 批量删除
        $scope.deleteBrands = function () {
    
            brandService.deleteBrands($scope.selectIds).success(
                function (response) {
                    if (response.success == true) {
                        // 重新加载数据
                        $scope.reloadBrandList();
                        $scope.selectIds = [];
                    } else {
                        // 保存失败
                        alert(response.message);
                    }
                }
            );
        };
    
        // 定义搜索对象
        $scope.searchEntity = {};
    
        // 条件查询
        $scope.search = function (page, rows) {
    
            brandService.searchBrand(page, rows, $scope.searchEntity).success(
                function (response) {
                    $scope.brandList = response.rows;
                    $scope.paginationConf.totalItems = response.total;
                }
            );
        }
    
    });

修改页面

  1. 去掉brand.html原来的JS代码,导入js文件

    <script type="text/javascript" src="../js/base_pagination.js"></script>
    <script type="text/javascript" src="../js/service/brandService.js"></script>
    <script type="text/javascript" src="../js/controller/brandController.js"></script>

控制器继承

需求分析

  1. 有些功能每个页面都有可能用到,比如分页,复选框等,为了重复编写,我们通过集成的方式来实现。

前端代码

建立父控制器

  1. 在pinyougou-manager-web工程js/controller下,创建baseController.js

    app.controller("baseController", function ($scope) {
    
        // 分页的配置信息
        $scope.paginationConf = {
            // 当前页码
            currentPage: 1,
            // 总条数
            totalItems: 10,
            // 每页数量
            itemsPerPage: 10,
            // 页码选项
            perPageOptions: [10, 20, 30, 40, 50],
            // 更改页面时触发事件
            onChange: function () {
                // 重新加载
                $scope.reloadList();
            }
        };
    
        // 重新加载数据列表
        $scope.reloadList = function() {
    
            // 切换页码
            $scope.search($scope.paginationConf.currentPage, $scope.paginationConf.itemsPerPage);
        };
    
        // 选中的Id集合
        $scope.selectIds = [];
    
        // 更新复选
        $scope.updateSelection = function ($event, id) {
    
            // 如果选中,添加到数组中
            if ($event.target.checked) {
                $scope.selectIds.push(id);
            } else {
                // splice方法,从数组的指定位置移除指定个数的元素,第一个参数为位置,第二个参数是移除的个数
                var index = $scope.selectIds.indexOf(id);
                $scope.selectIds.splice(index, 1);
            }
        };
    
    });

修改品牌控制器层

  1. 修改brandController.js

    // 定义控制器
    app.controller('brandController', function ($scope, $controller, brandService) {
    
        // AngularJS中的继承: 伪继承
        $controller('baseController', {$scope: $scope});
    
        // 查询品牌列表
        $scope.findPage = function (page, rows) {
            brandService.findPage(page, rows).success(
                function (response) {
                    $scope.brandList = response.rows;
                    $scope.paginationConf.totalItems = response.total;
                }
            );
        };
    
        // 重新加载数据列表
        $scope.reloadBrandList = function() {
    
            // 切换页码
            $scope.search($scope.paginationConf.currentPage, $scope.paginationConf.itemsPerPage);
        };
    
    
        // 新增产品
        $scope.save = function () {
            // 区分是保存还是修改
            var object;
    
            // 如果有实体id,则调用更新方法
            if ($scope.entity.id != null) {
                // 更新
                object = brandService.update($scope.entity);
            } else {
                // 保存
                object = brandService.save($scope.entity);
            }
    
            object.success(
                function (response) {
                    if (response.success) {
                        // 保存成功
                        alert(response.message);
                        // 重新加载数据
                        $scope.reloadBrandList();
                    } else {
                        alert(response.message);
                    }
                }
            );
        };
    
    
        // 查询品牌实体
        $scope.findOne = function (id) {
            brandService.findById(id).success(
                function (response) {
                    $scope.entity = response;
                }
            );
        };
    
    
        // 批量删除
        $scope.deleteBrands = function () {
    
            brandService.deleteBrands($scope.selectIds).success(
                function (response) {
                    if (response.success == true) {
                        // 重新加载数据
                        $scope.reloadBrandList();
                        $scope.selectIds = [];
                    } else {
                        // 保存失败
                        alert(response.message);
                    }
                }
            );
        };
    
        // 定义搜索对象
        $scope.searchEntity = {};
    
        // 条件查询
        $scope.search = function (page, rows) {
    
            brandService.searchBrand(page, rows, $scope.searchEntity).success(
                function (response) {
                    $scope.brandList = response.rows;
                    $scope.paginationConf.totalItems = response.total;
                }
            );
        }
    
    });
    1. $controller也是angular提供的服务,可以实现伪继承,实际上是与BaseController共享$scope
  2. 在brand.html中导入baseController.js

    <script type="text/javascript" src="../js/controller/baseController.js"></script>

测试

  1. 刷新品牌管理列表,数据正常显示

    这里写图片描述

  2. 点击修改,保存成功

    这里写图片描述

导入生成的代码

  1. 导入生成的代码

规格管理

需求及表结构分析

需求

  1. 实现规格管理功能

    这里写图片描述

表结构

  1. tb_specification 规格表

    字段 类型 长度 含义
    Id Bigint 主键
    Spec_name Varchar 255 规格名称
  2. tb_specification_option 规格选项表

    字段 类型 长度 含义
    Id Bigint 主键
    Option_name Varchar 200 规格选项名称
    Spec_id Bigint 30 规格ID
    Orders Int 11 排序

规格列表

引入JS

  1. 修改pinyougou-manager-web工程的specification.html

    <script type="text/javascript" src="../plugins/angularjs/angular.min.js"></script>
    <script src="../plugins/angularjs/pagination.js"></script>
    <link rel="stylesheet" href="../plugins/angularjs/pagination.css">
    
    <script type="text/javascript" src="../js/base_pagination.js"></script>
    <script type="text/javascript" src="../js/service/specificationService.js"></script>
    <script type="text/javascript" src="../js/controller/baseController.js"></script>
    <script type="text/javascript" src="../js/controller/specificationController.js"></script>

加载列表数据

  1. 在body元素指定模块名和控制器名

    <body class="hold-transition skin-red sidebar-mini" ng-app="pinyougou" ng-controller="specificationController">
  2. 加载数据,添加分页

    <!--数据列表-->
    <table id="dataList" class="table table-bordered table-striped table-hover dataTable">
      <thead>
          <tr>
              <th class="" style="padding-right:0px">
                  <input id="selall" type="checkbox" class="icheckbox_square-blue">
              </th> 
              <th class="sorting_asc">规格ID</th>
              <th class="sorting">规格名称</th>                                                                                     
              <th class="text-center">操作</th>
          </tr>
      </thead>
      <tbody>
          <tr ng-repeat="entity in list">
              <td><input type="checkbox" ng-click="updateSelection($event, entity.id)"></td>
              <td>{{ entity.id }}</td>
              <td>{{ entity.specName }}</td>
              <td class="text-center">                                           
                  <button type="button" class="btn bg-olive btn-xs" data-toggle="modal" data-target="#editModal">修改</button>                                           
              </td>
          </tr>
      </tbody>
    </table>
    <!--数据列表/-->
    
    <!-- 分页 -->
    <tm-pagination conf="paginationConf"></tm-pagination>

新增规格

新增行的实现

  1. 修改specificationController.js新增以下代码

    // 增加规格选项行
    $scope.addTableRow=function(){
        $scope.entity.specificationOptionList.push({});            
    }
  2. 修改specification.html的“新建选项”按钮和加载表格编辑框列表

    <!-- 规格选项 -->
    <div class="btn-group">
        <button type="button" class="btn btn-default" title="新建" ng-click="addTableRow()"><i class="fa fa-file-o"></i> 新增规格选项
        </button>
    
    </div>
    
    <table class="table table-bordered table-striped table-hover dataTable">
        <thead>
        <tr>
            <th class="sorting">规格选项</th>
            <th class="sorting">排序</th>
            <th class="sorting">操作</th>
        </thead>
        <tbody>
        <tr ng-repeat="pojo in entity.specificationOptionList">
            <td>
                <input ng-model="pojo.optionName" class="form-control" placeholder="规格选项">
            </td>
            <td>
                <input ng-model="pojo.orders" class="form-control" placeholder="排序">
            </td>
            <td>
                <button type="button" class="btn btn-default" title="删除"><i class="fa fa-trash-o"></i> 删除
                </button>
            </td>
        </tr>
        </tbody>
    </table>
  3. 修改“新建”按钮,弹出窗口时对entity进行初始化,否则添加规格选项会报错

    <button type="button" class="btn btn-default" title="新建" data-toggle="modal" data-target="#editModal" ng-click="entity={'specificationOptionList':[]}"><i class="fa fa-file-o"></i> 新建 </button>

删除行的实现

  1. 修改specificationController.js新增以下代码

    //删除规格选项行
    $scope.deleTableRow=function(index){
        $scope.entity.specificationOptionList.splice(index,1);
    }
  2. 修改每行的删除按钮,使用$index 用于获取ng-repeat指令循环中的索引

    <button type="button" class="btn btn-default" title="删除" ng-click="deleTableRow($index)"><i class="fa fa-trash-o"></i> 删除 </button>

提交保存

  1. 思路: 将规格和规格选项数据合并成一个对象来传递,需要用一个对象将两个对象组合起来。在业务逻辑中,得到组合对象中的规格和规格选项列表,插入规格返回规格ID,然后循环插入规格选项。

  2. 增加规格选项,必须知道新增规格的ID,需要修改pinyougou-dao的TbSpecificationMapper.xml,在insert节点后添加

    <insert id="insert" parameterType="com.huangwangxin.pojo.TbSpecification" >
        <selectKey resultType="java.lang.Long" order="AFTER" keyProperty="id">
            SELECT LAST_INSERT_ID() AS id
        </selectKey>
        insert into tb_specification (id, spec_name)
        values (#{id,jdbcType=BIGINT}, #{specName,jdbcType=VARCHAR})
    </insert>
  3. 在pinyougou-pojo新增group包,创建Specificatio类

    package com.huangwangxin.group;
    
    import com.huangwangxin.pojo.TbSpecification;
    import com.huangwangxin.pojo.TbSpecificationOption;
    
    import java.io.Serializable;
    import java.util.List;
    
    
    /**
     * 规格组合实体类
     * @author Administrator
     *
     */
    public class Specification implements Serializable{
    
        private TbSpecification specification;
    
        private List<TbSpecificationOption> specificationOptionList;
    
        public TbSpecification getSpecification() {
            return specification;
        }
    
        public void setSpecification(TbSpecification specification) {
            this.specification = specification;
        }
    
        public List<TbSpecificationOption> getSpecificationOptionList() {
            return specificationOptionList;
        }
    
        public void setSpecificationOptionList(List<TbSpecificationOption> specificationOptionList) {
            this.specificationOptionList = specificationOptionList;
        }
    
    }
  4. 修改pinyougou-sellergoods-interface的SpecificationService.java

    /**
     * 增加
     */
    public void add(Specification specification);
  5. 修改pinyougou-sellergoods-service的SpecificationServiceImpl.java

    /**
     * 增加
     */
    @Override
    public void add(Specification specification) {
        //获取规格实体
        TbSpecification tbspecification = specification.getSpecification();             
        specificationMapper.insert(tbspecification);    
    
        //获取规格选项集合
        List<TbSpecificationOption> specificationOptionList = specification.getSpecificationOptionList();
        for( TbSpecificationOption option:specificationOptionList){
            option.setSpecId(tbspecification.getId());//设置规格ID
            specificationOptionMapper.insert(option);//新增规格
        }
    }
  6. 修改pinyougou-manager-web的SpecificationController.java

    /**
     * 增加
     *
     * @param specification the specification
     * @return result
     */
    @RequestMapping("/add")
    public Result add(@RequestBody Specification specification){
        try {
            specificationService.add(specification);
            return new Result(true, "增加成功");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new Result(false, "增加失败");
    }
  7. 修改页面specification.html

    1. 绑定规格名称

      <table class="table table-bordered table-striped" width="800px">
          <tr>
              <td>规格名称</td>
              <td><input class="form-control" placeholder="规格名称" ng-model="entity.specification.specName"></td>
          </tr>
      </table>
    2. 绑定保存按钮事件

      <button class="btn btn-success" data-dismiss="modal" aria-hidden="true" ng-click="save()">保存</button>

修改规格

获取规格数据

  1. 实现思路:通过规格ID,到后端查询规格和规格选项列表,然后通过组合实体类返回结果
  2. 修改pinyougou-sellergoods-interface的SpecificationService.java

    /**
     * 根据ID获取实体
     * @param id
     * @return
     */
    public Specification findOne(Long id);
  3. 修改pinyougou-sellergoods-service的SpecificationServiceImpl.java

    /**
     * 根据ID获取实体
     * @param id
     * @return
     */
    @Override
    public Specification findOne(Long id){
    
        Specification specification=new Specification();
        //获取规格实体
        TbSpecification tbSpecification = specificationMapper.selectByPrimaryKey(id);
        specification.setSpecification(tbSpecification);
    
        //获取规格选项列表  
        TbSpecificationOptionExample example=new TbSpecificationOptionExample();
        TbSpecificationOptionExample.Criteria criteria = example.createCriteria();
        criteria.andSpecIdEqualTo(id);
        List<TbSpecificationOption> specificationOptionList = specificationOptionMapper.selectByExample(example);
    
        specification.setSpecificationOptionList(specificationOptionList);
    
        return specification;//组合实体类
    }
  4. 修改pinyougou-manager-web的SpecificationController.java

    /**
     * 获取实体
     * @param id
     * @return
     */
    @RequestMapping("/findOne")
    public Specification findOne(Long id){
        return specificationService.findOne(id);
    }
  5. 修改页面specification.html的修改按钮

    <button type="button" class="btn bg-olive btn-xs" data-toggle="modal" data-target="#editModal" ng-click="findOne(entity.id)">修改</button>

保存修改结果

  1. 修改pinyougou-sellergoods-interface的SpecificationService.java

    /**
     * 修改
     */
    public void update(Specification specification);
  2. 修改pinyougou-sellergoods-service的SpecificationServiceImpl.java

    /**
     * 修改
     */
    @Override
    public void update(Specification specification){
    
        //获取规格实体
        TbSpecification tbspecification = specification.getSpecification();             
        specificationMapper.updateByPrimaryKey(tbspecification);    
    
        //删除原来规格对应的规格选项
        TbSpecificationOptionExample example=new TbSpecificationOptionExample();
        TbSpecificationOptionExample.Criteria criteria = example.createCriteria();
        criteria.andSpecIdEqualTo(tbspecification.getId());
        specificationOptionMapper.deleteByExample(example);
    
        //获取规格选项集合
        List<TbSpecificationOption> specificationOptionList = specification.getSpecificationOptionList();
        for( TbSpecificationOption option:specificationOptionList){
            option.setSpecId(tbspecification.getId());//设置规格ID
            specificationOptionMapper.insert(option);//新增规格
        }
    
    }   
  3. 修改pinyougou-manager-web的SpecificationController.java

    /**
     * 修改
     * @param specification
     * @return
     */
    @RequestMapping("/update")
    public Result update(@RequestBody Specification specification){
        try {
            specificationService.update(specification);
            return new Result(true, "修改成功");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new Result(false, "修改失败");
    }
  4. 修改specificationController.js的save方法

    //保存 
    $scope.save=function(){                
        var serviceObject;//服务层对象               
        if($scope.entity.specification.id!=null){//如果有ID
            serviceObject=specificationService.update( $scope.entity ); //修改  
        }else{
            serviceObject=specificationService.add( $scope.entity  );//增加 
        }               
        serviceObject.success(
            function(response){
                if(response.success){
                    //重新查询 
                    $scope.reloadList();//重新加载
                }else{
                    alert(response.message);
                }
            }       
        );              
    };

删除规格

  1. 思路: 要删除规格的同时,还要记得将关联的规格选项删除掉
  2. 修改pinyougou-sellergoods-service的SpecificationServiceImpl.java

    /**
     * 批量删除
     */
    @Override
    public void delete(Long[] ids) {
        for(Long id:ids){
            //删除规格表数据
            specificationMapper.deleteByPrimaryKey(id);
    
            //删除规格选项表数据     
            TbSpecificationOptionExample example=new TbSpecificationOptionExample();
            TbSpecificationOptionExample.Criteria criteria = example.createCriteria();
            criteria.andSpecIdEqualTo(id);
            specificationOptionMapper.deleteByExample(example);
        }       
    }
  3. 修改页面specification.html

    1. 列表复选框

      <td><input type="checkbox" ng-click="updateSelection($event, entity.id)"></td>
    2. 删除按钮

      <button type="button" class="btn btn-default" title="删除" ng-click="dele()"><i class="fa fa-trash-o"></i> 删除</button>

测试

  1. 查看规格管理列表

    这里写图片描述

  2. 新建规格,保存成功

    这里写图片描述

    这里写图片描述

  3. 修改规格,保存

    这里写图片描述

  4. 删除规格

    这里写图片描述

模板管理

需求及表结构分析

需求分析

  1. 模板的作用:
    1. 用于关联品牌与规格
    2. 定义扩充属性

表结构分析

  1. tb_type_template 模板表

    字段 类型 长度 含义
    Id Bigint 主键
    name Varchar 80 模板名称
    Spec_ids Varchar 1000 关联规格(json格式)
    brand_ids Varchar 1000 关联品牌(json格式)
    custom_attribute_items Varchar 2000 扩展属性

模板列表

引入JS

  1. 修改type_template.html

    <script type="text/javascript" src="../plugins/angularjs/angular.min.js"></script>
    <script src="../plugins/angularjs/pagination.js"></script>
    <link rel="stylesheet" href="../plugins/angularjs/pagination.css">
    <script type="text/javascript" src="../js/base_pagination.js"></script>
    <script type="text/javascript" src="../js/controller/baseController.js"></script>
    
    <script type="text/javascript" src="../js/service/typeTemplateService.js"></script>
    <script type="text/javascript" src="../js/controller/typeTemplateController.js"></script>

加载列表数据

  1. 在body元素指定模块名和控制器名

    <body class="hold-transition skin-red sidebar-mini" ng-app="pinyougou" ng-controller="typeTemplateController">
  2. 加载数据,添加分页

    <!--数据列表-->
    <table id="dataList" class="table table-bordered table-striped table-hover dataTable">
        <thead>
        <tr>
            <th class="" style="padding-right:0px">
                <input id="selall" type="checkbox" class="icheckbox_square-blue">
            </th>
            <th class="sorting_asc">模板ID</th>
            <th class="sorting">分类模板名称</th>
            <th class="sorting">关联品牌</th>
            <th class="sorting">关联规格</th>
            <th class="sorting">扩展属性</th>
            <th class="text-center">操作</th>
        </tr>
        </thead>
        <tbody>
        <tr ng-repeat="entity in list">
            <td><input type="checkbox"></td>
            <td>{{entity.id}}</td>
            <td>{{entity.name}}</td>
            <td>{{entity.brandIds}}</td>
            <td>{{entity.specIds}}</td>
            <td>{{entity.customAttributeItems}}</td>
            <td class="text-center">
                <button type="button" class="btn bg-olive btn-xs" data-toggle="modal" data-target="#editModal">修改
                </button>
            </td>
        </tr>
        </tbody>
    </table>
    <!--数据列表/-->
    
    <!-- 分页 -->
    <tm-pagination conf="paginationConf"></tm-pagination>

品牌下拉列表

  1. 在新增或修改的弹出窗口中有个品牌下拉列表,要求品牌是可以选择多个。要实现这个功能,需要使用select2组件。

    这里写图片描述

显示品牌下拉列表

  1. 修改type_template.html,引入select JS

    <!-- 引入select2相关的css和js -->
    <link rel="stylesheet" href="../plugins/select2/select2.css">
    <link rel="stylesheet" href="../plugins/select2/select2-bootstrap.css">
    <script type="text/javascript" src="../plugins/select2/select2.min.js"></script>
    <script type="text/javascript" src="../js/angular-select2.js"></script>
  2. 修改typeTemplateController.js,定义品牌列表数据

    $scope.brandList={data:[]};//品牌列表 
  3. 修改type_template.html,实现select2组件多选下拉框

    <tr>
        <td>关联品牌</td>
        <td>
            <input select2 select2-model="entity.brandIds" config="brandList" multiple placeholder="选择品牌(可多选)" class="form-control" type="text">
        </td>
    </tr>
    1. multiple 表示可多选
    2. config 用户配置数据来源
    3. select2-model用于指定用户选择后提交的变量

后端数据支撑

  1. 在pinyougou-dao工程,TbBrandMapper.xml中添加SQL语句

    <select id="selectOptionList" resultType="java.util.Map">
    select id,name as text from tb_brand
    </select>
  2. 在pinyougou-dao工程,TbBrandMapper中添加方法定义

    List<Map> selectOptionList();
  3. 修改pinyougou-sellergoods-interface的BrandService.java

    /**
     * 品牌下拉框数据
     *
     * @return the list
     */
    List<Map> selectOptionList();
  4. 修改pinyougou-sellergoods-service的BrandServiceImpl.java

    @Override
    public List<Map> selectOptionList() {
        return brandMapper.selectOptionList();
    }
  5. 修改pinyougou-manager-web的BrandController.java

    /**
     * 下拉列表数据.
     *
     * @return the list
     */
    @RequestMapping("/selectOptionList")
    public List<Map> selectOptionList() {
        return brandService.selectOptionList();
    }
  6. 修改webapp下的brandService.js

    // 下拉列表数据
    this.selectOptionList = function () {
        return $http.get("../brand/selectOptionList.do");
    }
  7. 修改pinyougou-manager-web的typeTemplateController.js

    1. 依赖注入brandService

      app.controller('typeTemplateController' ,function($scope,$controller, typeTemplateService, brandService, specificationService)
    2. 修改品牌服务方法实现查询,结果赋值给变量

      $scope.brandList={data:[]};//品牌列表
      
      //读取品牌列表
      $scope.findBrandList=function(){
          brandService.selectOptionList().success(
              function(response){
                  $scope.brandList={data:response};
              }
          );      
      }
    3. 修改type_template.html,导入js

      <script type="text/javascript" src="../js/service/brandService.js"></script>
      <script type="text/javascript" src="../js/service/specificationService.js"></script>
      <script type="text/javascript" src="../js/service/typeTemplateService.js"></script>
      <script type="text/javascript" src="../js/controller/typeTemplateController.js"></script>
    4. 修改type_template.html,添加初始化

      <body class="hold-transition skin-red sidebar-mini" ng-app="pinyougou" ng-controller="typeTemplateController" ng-init="findBrandList()">

规格下拉列表

  1. 在新增或修改的弹出窗口中规格下拉列表,要求品牌是可以选择多个。

    这里写图片描述

显示规格下拉列表

  1. 修改typeTemplateController.js,定义规格列表数据

    $scope.specList={data:[]};//规格列表
  2. 修改type_template.html,实现select2组件多选下拉框

    <tr>
        <td>关联规格</td>
        <td>
            <input select2 select2-model="entity.specIds" config="specList" multiple placeholder="选择规格(可多选)" class="form-control" type="text">
        </td>
    </tr>
    1. multiple 表示可多选
    2. config 用户配置数据来源
    3. select2-model用于指定用户选择后提交的变量

后端数据支撑

  1. 在pinyougou-dao工程,TbSpecificationMapper.xml中添加SQL语句

    <select id="selectOptionList" resultType="java.util.Map">
        select id,spec_name as text from tb_specification
    </select>
  2. 在pinyougou-dao工程,TbSpecificationMapper中添加方法定义

    List<Map> selectOptionList();
  3. 修改pinyougou-sellergoods-interface的SpecificationService.java

    /**
     * 规格下拉列表
     *
     * @return the list
     */
    public List<Map> selectOptionList();
  4. 修改pinyougou-sellergoods-service的SpecificationServiceImpl.java

    @Override
    public List<Map> selectOptionList() {
    
        return specificationMapper.selectOptionList();
    }
  5. 修改pinyougou-manager-web的SpecificationController.java

    /**
     * 规格下拉列表.
     *
     * @return the list
     */
    @RequestMapping("/selectOptionList")
    public List<Map> selectOptionList(){
        return specificationService.selectOptionList();
    }
  6. 修改webapp下的specificationService.js

    //下拉列表
    this.selectOptionList=function(){
        return $http.get('../specification/selectOptionList.do');
    }
  7. 修改pinyougou-manager-web的typeTemplateController.js

    1. 依赖注入specificationService

      app.controller('typeTemplateController' ,function($scope,$controller, typeTemplateService, brandService, specificationService)
    2. 修改规格服务方法实现查询,结果赋值给变量

      $scope.specList={data:[]};//规格列表
      
      //读取规格列表
      $scope.findSpecList=function(){
          specificationService.selectOptionList().success(
                  function(response){
                      $scope.specList={data:response};
                  }
          );      
      }
    3. 修改type_template.html,添加初始化

      <body class="hold-transition skin-red sidebar-mini" ng-app="pinyougou" ng-controller="typeTemplateController" ng-init="findBrandList();findSpecList()">

扩展属性

增加行

  1. 在typeTemplateController.js中新增代码

    //增加扩展属性行
    $scope.addTableRow=function(){
        $scope.entity.customAttributeItems.push({});
    };
  2. 修改type_template.html的“新建”按钮

    <button type="button" class="btn btn-default" title="新建" data-toggle="modal"
            data-target="#editModal" ng-click="entity={customAttributeItems:[]}"><i class="fa fa-file-o"></i> 新建
    </button>
  3. 加载数据

    <tr ng-repeat="pojo in entity.customAttributeItems">
        <td><input type="checkbox" class="icheckbox_square-blue"></td>
        <td><input class="form-control" placeholder="属性名称" ng-model="pojo.text"></td>
        <td>
            <button type="button" class="btn btn-default" title="删除"><i
                    class="fa fa-trash-o"></i> 删除
            </button>
        </td>
    </tr>

删除行

  1. 思路:在每一行将索引值传递给集合,在集合中删除。
  2. 修改typeTemplateController.js新增以下代码

    //删除扩展属性行
    $scope.deleTableRow=function(index){
        $scope.entity.customAttributeItems.splice( index,1);
    }
  3. 修改每行的删除按钮

    <td>
        <button type="button" class="btn btn-default" title="删除" ng-click="deleTableRow($index)"><i
                class="fa fa-trash-o"></i> 删除
        </button>
    </td>

新增模板

  1. 修改type_template.html, 绑定名称

    <tr>
        <td>商品类型</td>
        <td><input class="form-control" placeholder="商品类型" ng-model="entity.name"></td>
    </tr>
  2. 保存事件

    <button class="btn btn-success" data-dismiss="modal" aria-hidden="true" ng-click="save()">保存</button>

修改模板

  1. 修改typeTemplateController.js

    // 查询实体 
    $scope.findOne=function(id){               
        typeTemplateService.findOne(id).success(
            function(response){
                $scope.entity= response;       
    
                //转换字符串为json对象(集合)
                $scope.entity.brandIds=  JSON.parse( $scope.entity.brandIds);
                $scope.entity.specIds= JSON.parse($scope.entity.specIds);
                $scope.entity.customAttributeItems = JSON.parse($scope.entity.customAttributeItems);
    
            }
        );              
    };
  2. 修改按钮

    <td class="text-center">
        <button type="button" class="btn bg-olive btn-xs" data-toggle="modal" data-target="#editModal" ng-click="findOne(entity.id)">修改
        </button>
    </td>

删除模板

  1. 修改type_template.html的复选框

    <tr ng-repeat="entity in list">
        <td><input type="checkbox" ng-click="updateSelection($event, entity.id)"></td>
        <td>{{entity.id}}</td>
        <td>{{entity.name}}</td>
        <td>{{entity.brandIds}}</td>
        <td>{{entity.specIds}}</td>
        <td>{{entity.customAttributeItems}}</td>
        <td class="text-center">
            <button type="button" class="btn bg-olive btn-xs" data-toggle="modal" data-target="#editModal" ng-click="findOne(entity.id)">修改
            </button>
        </td>
    </tr>
  2. 保存事件

    <button type="button" class="btn btn-default" title="删除" ng-click="dele()"><i class="fa fa-trash-o"></i> 删除</button>

优化模板列表的显示

  1. 修改baseController.js

    // 定义方法:获取JSON字符串中的某个key对应值的集合
    $scope.jsonToString = function(jsonStr,key){
        // 将字符串转成JSOn:
        var jsonObj = JSON.parse(jsonStr);
    
        var value = "";
        for(var i=0;i<jsonObj.length;i++){
    
            if(i>0){
                value += ",";
            }
    
            value += jsonObj[i][key];
        }
        return value;
    };
  2. 修改type_template.html

    <tr ng-repeat="entity in list">
        <td><input type="checkbox" ng-click="updateSelection($event, entity.id)"></td>
        <td>{{entity.id}}</td>
        <td>{{entity.name}}</td>
        <td>{{jsonToString(entity.brandIds, 'text')}}</td>
        <td>{{jsonToString(entity.specIds, 'text')}}</td>
        <td>{{jsonToString(entity.customAttributeItems, 'text')}}</td>
        <td class="text-center">
            <button type="button" class="btn bg-olive btn-xs" data-toggle="modal" data-target="#editModal" ng-click="findOne(entity.id)">修改
            </button>
        </td>
    </tr>

测试

  1. 刷新页面,查看页面显示不为json

    这里写图片描述

  2. 新增模板,能够保存成功

    这里写图片描述

    这里写图片描述

  3. 修改

    这里写图片描述

    这里写图片描述

  4. 删除

    这里写图片描述

    这里写图片描述

猜你喜欢

转载自blog.csdn.net/h1101723183/article/details/80929362