• 十八、商城 - 规格管理-模板管理(6)


    一、规格管理

    1.1 需求及表结构分析

    1.1.1 需求

    实现规格管理功能

    在这里插入图片描述

    1.1.2 表结构

    tb_specification 规格表

    字段类型长度含义
    idBigint主键
    spec_nameVarchar255规格名称

    tb_specification_option 规格选项表

    字段类型长度含义
    idBigint主键
    option_nameVarchar200规格选项名称
    spec_idBigint30规格ID
    ordersInt11排序

    1.2 完善规格弹出编辑页面

    在这里插入图片描述

    copy 相应代码 👇🏾👇🏾 到 工程中 youlexuan_manager_web/webapp/admin/specification.html对应位置,显示如下所示 :

    在这里插入图片描述

    
    <div class="btn-group">
        <button type="button" class="btn btn-default" title="新建" ><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>
            <td>
                <input  class="form-control" placeholder="规格选项">
            td>
            <td>
                <input  class="form-control" placeholder="排序">
            td>
            <td>
                <button type="button" class="btn btn-default" title="删除" ><i class="fa fa-trash-o">i> 删除button>
            td>
        tr>
        <tr>
            <td>
                <input  class="form-control" placeholder="规格选项">
            td>
            <td>
                <input  class="form-control" placeholder="排序">
            td>
            <td>
                <button type="button" class="btn btn-default" title="删除" ><i class="fa fa-trash-o">i> 删除button>
            td>
        tr>
        <tr>
            <td>
                <input  class="form-control" placeholder="规格选项">
            td>
            <td>
                <input  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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    添加代码后显示 :👇🏾👇🏾

    在这里插入图片描述

    1.3 新增规格

    1.3.1 新增行的实现

    修改 youlexuan_manager_web / webapp / js / controller / specificationController.js 新增以下代码

    在这里插入图片描述

    //定义一个变量存放规格选项行
    $scope.entity={specificationOptionList:[]};
      //新增规格选项
    $scope.addTableRow = function () {
    
    	$scope.entity.specificationOptionList.push({});
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    (1) 修改 youlexuan_manager_web / webapp / admin / specification.html “新增规格选项”按钮

    (2) 循环列表行,绑定表格内的编辑框 ⑤ 为下面 1.3.2 删除操作

    在这里插入图片描述

    
    <div class="btn-group">
        <button type="button" class="btn btn-default" title="新建" ng-click="addTableRow()"><i class="fa fa-file-o">i> 新增规格选项button>
    div>
    
    {{entity.specificationOptionList}} //前台查看测试
    
    <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  class="form-control"  ng-model="pojo.optionName"   placeholder="规格选项">
            td>
            <td>
                <input  class="form-control"  ng-model="pojo.orders" placeholder="排序">
            td>
            <td>
                <button type="button" class="btn btn-default" title="删除" ng-click="deleTableRow($index)"><i class="fa fa-trash-o">i> 删除button>
            td>
        tr>
        <tr>
        tbody>
    table>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    注意:要修改specification.html “新建”按钮,弹出窗口时对entity进行初始化,否则向集合添加数据时会报错!

    在这里插入图片描述

    ng-click="entity={'specificationOptionList':[]}"
    
    • 1

    1.3.2 删除行的实现

    实现思路:在每一行将索引值传递给集合,在集合中删除。

    修改 youlexuan_manager_web / webapp / js / controller / specificationController.js 新增以下代码

    在这里插入图片描述

    //删除规格选项行
    $scope.deleTableRow = function (index) {
    
       $scope.entity.specificationOptionList.splice(index,1);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    截图看上面 1.3.1 (2)截图 🤔🤔

    修改每行的删除按钮 $index 用于获取ng-repeat指令循环中的索引。

    最终显示 👇🏾👇🏾

    在这里插入图片描述

    1.3.3 提交保存

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

    (1)我们要增加规格选项,必须要知道新增规格的ID, 所以我们在修改youlexuan_dao 的

    TbSpecificationMapper.xml ,在insert节点后添加如下配置

    在这里插入图片描述

    <selectKey keyColumn="id" keyProperty="id" resultType="java.lang.Long" order="AFTER">
    	SELECT LAST_INSERT_ID() AS id
    selectKey>
    
    • 1
    • 2
    • 3

    (2)在youlexuan_pojo 建立com.zql.group包,包下建立 Specification 类

    package com.zql.group;
    
    import com.zql.pojo.TbSpecification;
    import com.zql.pojo.TbSpecificationOption;
    
    import java.io.Serializable;
    import java.util.List;
    
    /**
     * @Author:Daniel
     * 规格组合实体类
     * @Version 1.0
     */
    public class Specification  implements Serializable {
    
        private TbSpecification specification;
        private List<TbSpecificationOption> specificationOptionList;
    
        public Specification(TbSpecification specification, List<TbSpecificationOption> specificationOptionList) {
            this.specification = specification;
            this.specificationOptionList = 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;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    (3)在youlexuan_manager_web / webapp / admin / specification.html 中添加 下面添加

    specification

    在这里插入图片描述

    (4)修改youlexuan_sellergoods-interface 的 SpecificationService.java

    在这里插入图片描述

    /**
    * 增加
    */
    public void add(Specification specification);
    
    • 1
    • 2
    • 3
    • 4

    (5)修改youlexuan-sellergoods-service的SpecificationServiceImpl.java

    @Autowired
    private TbSpecificationOptionMapper specificationOptionMapper;
    
    
    /**
     * 增加
     */
    @Override
    public void add(Specification specification) {
    
    	specificationMapper.insert(specification.getSpecification());//保存规格
    
    	//保存规格选项
    	for(TbSpecificationOption specificationOption : specification.getSpecificationOptionList()){
    
    		specificationOption.setSpecId(specification.getSpecification().getId()); //设置规格ID
    
    		specificationOptionMapper.insert(specificationOption);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    其余的都生成器生好了!!

    1.4 修改规格

    1.4.1 获取规格数据

    实现思路:通过规格ID,到后端查询规格和规格选项列表,然后通过组合实体类返回结果

    (1)修改youlexuan_sellergoods-interface的SpecificationService.java

    /**
    * 根据ID获取实体
    * @param id
    * @return
    */
    public Specification findOne(Long id);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    (2)修改youlexuan_sellergoods_service的SpecificationServiceImpl.java

    /**
     * 根据ID获取实体
     * @param id
     * @return
     */
    @Override
    public Specification findOne(Long id){
    	//查询规格
    	TbSpecification specification = specificationMapper.selectByPrimaryKey(id);
    	//查询规格选项列表
    	TbSpecificationOptionExample example = new TbSpecificationOptionExample();
    
    	TbSpecificationOptionExample.Criteria criteria = example.createCriteria();
    
    	criteria.andSpecIdEqualTo(id);//根据规格ID查询
    
    	List<TbSpecificationOption> specificationOptions = specificationOptionMapper.selectByExample(example);
    	//构建组合实体类返回结果
    	Specification spec = new Specification();
    
    	spec.setSpecification(specification);
    
    	spec.setSpecificationOptionList(specificationOptions);
    
    	return spec;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    (3)修改youlexuan_manager_web的 SpecificationController.java

    在这里插入图片描述

    /**
     * 获取实体
     * @param id
     * @return
     */
    @RequestMapping("/findOne")
    public Specification findOne(Long id){
    
    	return specificationService.findOne(id);		
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    点击【修改】回显如下

    在这里插入图片描述

    1.4.2 保存修改结果

    (1)修改youlexuan_sellergoods_interface 的 SpecificationService.java

    在这里插入图片描述

    (2)修改youlexuan_sellergoods_service 的 SpecificationServiceImpl.java

    /**
     * 修改
     */
    @Override
    public void update(Specification specification){
    
    	//保存修改的规格
    	specificationMapper.updateByPrimaryKey(specification.getSpecification());//保存规格
    
    	//删除原有的规格选项
    	TbSpecificationOptionExample example = new TbSpecificationOptionExample();
    
    	TbSpecificationOptionExample.Criteria criteria = example.createCriteria();
    
    	criteria.andSpecIdEqualTo(specification.getSpecification().getId());//指定规格ID为选项
    
    	specificationOptionMapper.deleteByExample(example);//删除
    
    	//循环插入规格选项
    
    	for (TbSpecificationOption specificationOption :specification.getSpecificationOptionList()){
    
    		specificationOption.setSpecId(specification.getSpecification().getId());
    
    		specificationOptionMapper.insert(specificationOption);
    
    	}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    (3)修改youlexuan_manager_web 的 SpecificationController.java

    在这里插入图片描述

    1.5 删除规格

    实现思路:我们要删除规格的同时,还要记得将关联的规格选项删除掉。

    1.5.1 后端代码

    修改youlexuan_sellergoods_service 的 SpecificationServiceImpl.java

    /**
     * 批量删除
     */
    @Override
    public void delete(Long[] ids) {
    
    	for(Long id:ids){
    		//删除 规格选项
    		TbSpecificationOptionExample example = new TbSpecificationOptionExample();
    
    		TbSpecificationOptionExample.Criteria criteria = example.createCriteria();
    
    		criteria.andSpecIdEqualTo(id);
    
    		specificationOptionMapper.deleteByExample(example);
    		//删除规格
    		specificationMapper.deleteByPrimaryKey(id);
    	}		
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    1.6 查询

    1.6.1 后端代码

    代码生成器已经生成好了!

    1.6.2 前端代码

    <div class="has-feedback">
    	规格名称:<input ng-model="searchEntity.specName" >
    	<button class="btn btn-default" ng-click="reloadList()">查询button>
    div>
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    完整代码:specification.html

    DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>管理title>
        <meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport">
        <link rel="stylesheet" href="../plugins/bootstrap/css/bootstrap.min.css">
        <link rel="stylesheet" href="../plugins/adminLTE/css/AdminLTE.css">
        <link rel="stylesheet" href="../plugins/adminLTE/css/skins/_all-skins.min.css">
        <link rel="stylesheet" href="../css/style.css">
        <script src="../plugins/jQuery/jquery-2.2.3.min.js">script>
        <script src="../plugins/bootstrap/js/bootstrap.min.js">script>
    
        <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>
    
    head>
    <body class="hold-transition skin-red sidebar-mini" ng-app="youlexuan" ng-controller="specificationController">
    
    <div class="box-header with-border">
        <h3 class="box-title">管理h3>
    div>
    
    <div class="box-body">
    
        
        <div class="table-box">
    
            
            <div class="pull-left">
                <div class="form-group form-inline">
                    <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>
                    <button type="button" class="btn btn-default" title="删除" ng-click="dele()"><i class="fa fa-trash-o">i>
                        删除
                    button>
                    <button type="button" class="btn btn-default" title="刷新" onclick="window.location.reload();"><i
                            class="fa fa-refresh">i> 刷新
                    button>
                div>
                <div class="btn-group">
    
                div>
            div>
            <div class="box-tools pull-right">
                <div class="has-feedback">
                div>
    
                <div class="has-feedback">
                    规格名称:<input ng-model="searchEntity.specName">
                    <button class="btn btn-default" ng-click="reloadList()">查询button>
                div>
    
            div>
            
    
            
            <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="text-left">规格名称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.specName}}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>
                tbody>
            table>
            
        div>
        
        
        <tm-pagination conf="paginationConf">tm-pagination>
    div>
    
    
    <div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×button>
                    <h3 id="myModalLabel">编辑h3>
                div>
                <div class="modal-body">
                    <table class="table table-bordered table-striped" width="800px">
                        <tr>
                            <td>规格名称td>
                            <td><input class="form-control" ng-model="entity.specification.specName" placeholder="规格名称">
                            td>
                        tr>
                    table>
    
                    
                    <div class="btn-group">
                        <button type="button" class="btn btn-default" title="新建" ng-click="addTableRow()"><i
                                class="fa fa-file-o">i> 新增规格选项
                        button>
                    div>
    
                    {{entity.specificationOptionList}} 
    
                    <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 class="form-control" ng-model="pojo.optionName" placeholder="规格选项">
                            td>
                            <td>
                                <input class="form-control" ng-model="pojo.orders" placeholder="排序">
                            td>
                            <td>
                                <button type="button" class="btn btn-default" title="删除" ng-click="deleTableRow($index)"><i
                                        class="fa fa-trash-o">i> 删除
                                button>
                            td>
                        tr>
                        <tr>
                        tbody>
                    table>
                div>
                <div class="modal-footer">
                    <button class="btn btn-success" data-dismiss="modal" aria-hidden="true" ng-click="save()">保存button>
                    <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">关闭button>
                div>
            div>
        div>
    div>
    
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157

    二、模板管理

    2.1 需求及表结构分析

    2.1.1 需求分析

    在这里插入图片描述

    首选我们需要理解模板的作用。模板主要有两个:

    1. 是用于关联品牌与规格
    2. 定义扩充属性

    2.1.2 表结构分析

    tb_type_template 模板表

    字段类型长度含义
    idBigint主键
    nameVarchar80模板名称
    spec_idsVarchar1000关联规格(json格式)
    brand_idsVarchar1000关联品牌(json格式)
    custom_attribute_itemsVarchar2000扩展属性(Json格式)

    2.2 品牌下拉列表

    在弹出窗口中有个品牌下拉列表,要求品牌是可以选择多个,这与我们之前的单选的下拉列表是不同的。我们要想实现这个功能,需要使用select2 组件来完成。

    2.2.1 引入JS

    (1) 下载 angular-select2.js

    导入 youlexuan_manager_web / webapp / js / angular-select2.js

    在这里插入图片描述

    (2) 修改 typeTemplate.html ,分别引入JS 到 typeTemplate.html

    在这里插入图片描述

    <!-- slect2插件  angularjs上面 -->
    <link rel="stylesheet" href="../plugins/select2/select2.css" />
    <link rel="stylesheet" href="../plugins/select2/select2-bootstrap.css" />
    <script src="../plugins/select2/select2.min.js" type="text/javascript"></script>
    
    <!-- 导入select2-angula  base_pagination.js下面-->
    <script src="../js/angular-select2.js"></script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    注意:base_pagination.js一定要在angular-select2.js之前导入,不然报app not define!

    (3)修改typeTemplateController.js ,定义品牌列表数据

    在这里插入图片描述

        $scope.brandList={data:[{id:1,text:'联想'},{id:2,text:'华为'},{id:3,text:'小米'}]};//品牌列表
    
    • 1

    (4)在typeTemplate.html 用select2组件实现多选下拉框

    在这里插入图片描述

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

    2.2.2 效果显示

    最终实现效果如下:http://localhost:9101/admin/typeTemplate.html

    在这里插入图片描述
    在这里插入图片描述

    2.2.3 后端数据支撑

    我们现在让这个下拉列表的数据从数据库中提取,修改后端代码

    (1)在youlexuan_dao 的 TbBrandMapper 中添加方法定义

    //关联品牌
    List<Map> selectOptionList();
    
    • 1
    • 2

    (2)youlexuan_dao 工程 ,在TbBrandMapper.xml中添加SQL语句配置

    <!--关联品牌-->
    <select id="selectOptionList" resultType="java.util.Map" >
      SELECT id,name AS text FROM tb_brand;
    </select>
    
    • 1
    • 2
    • 3
    • 4

    (3)修改 youlexuan_sellergoods_interface 的 BrandService.java,增加接口方法定义

    //关联品牌
    List<Map> selectOptionList();
    
    • 1
    • 2

    (4)修改youlexuan_sellergoods-service 的 BrandServiceImpl.java,增加方法

    /*关联品牌*/
    @Override
    public List<Map> selectOptionList() {
    
    	return brandMapper.selectOptionList();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    (5)修改youlexuan_manager_web 的 BrandController.java

    /*关联品牌*/
    @RequestMapping("/selectOptionList")
    public List<Map> selectOptionList(){
    	return  brandService.selectOptionList();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    测试是否输出为 json 格式的数据 http://localhost:9101/brand/selectOptionList.do 👇🏾👇🏾

    在这里插入图片描述

    (6)修改youlexuan_manager_web 的 brandService.js

    //下拉列表数据
    this.selectOptionList=function(){
        return $http.get('../brand/selectOptionList.do');
    }
    
    • 1
    • 2
    • 3
    • 4

    (7)修改youlexuan_manager_web 的 typeTemplateController.js

    因为我们在模板控制层中需要使用品牌服务层的方法,所以需要添加依赖注入 brandService

    在这里插入图片描述
    使用品牌服务方法实现查询,结果赋给变量 typeTemplateController.js

    /*关联品牌*/
    $scope.findBrandList = function () {
    
        brandService.selectOptionList().success(function (response) {
    
           // $scope.brandList.data = response; //方式一
            $scope.brandList={data:response};//方式二
        });
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    (8)修改typeTemplate.html ,添加JS引入

    在这里插入图片描述

    特别注意一下,JS引入的位置,要在typeTemplateController.js之前,因为该控制器要使用到它

    <script type="text/javascript" src="../js/service/brandService.js">  </script>
    
    • 1

    (9)修改typeTemplate.html ,添加初始化 ng-init="findBrandList()"

    在这里插入图片描述

    2.4 规格下拉列表

    2.4.1 前端js修改

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

    在这里插入图片描述

     $scope.specList={data:[{id:1,text:'屏幕尺寸'},{id:2,text:'网络制式'},{id:3,text:'尺码'}]};//规格列表 静态测试
    
    • 1

    (2)在 typeTemplate.html 用 select2 组件实现多选下拉框

    在这里插入图片描述

    <tr>
    	<td>关联规格td>
    	<td><input select2  config="specList" select2-model="entity.specList"  multiple placeholder="选择规格(可多选)" class="form-control" type="text"/>td>
    tr>
    
    • 1
    • 2
    • 3
    • 4

    访问 :http://localhost:9101/admin/typeTemplate.html

    在这里插入图片描述

    • multiple 表示可多选
    • Config 用于配置数据来源
    • select2-model用于指定用户选择后提交的变量

    2.4.2 后端数据支撑

    现在让这个下拉列表的数据从数据库中提取,修改后端代码

    (1)在youlexuan_dao 的TbSpecificationMapper中添加方法定义

    /*关联规格*/
    List<Map> selectOptionList();
    
    • 1
    • 2

    (2)youlexuan_dao 工程 ,在 TbSpecificationMapper.xml 中添加SQL语句配置

    <!--关联规格-->
    <select id="selectOptionList" resultType="java.util.Map">
    SELECT id,spec_name AS text FROM tb_specification
    </select>
    
    • 1
    • 2
    • 3
    • 4

    (3)修改youlexuan_sellergoods-interface 的SpecificationService.java,增加方法定义

    /*关联规格*/
    List<Map> selectOptionList();
    
    • 1
    • 2

    (4)修改 youlexuan_sellergoods-service 的 SpecificationServiceImpl.java,增加方法

    /*关联规格*/
    @Override
    public List<Map> selectOptionList() {
    
    	return specificationMapper.selectOptionList();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    (5)修改youlexuan_manager-web的SpecificationController.java

    /*关联规格*/
    @RequestMapping("/selectOptionList")
    public List<Map> selectOptionList(){
    
    	return specificationService.selectOptionList();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    测试 : http://localhost:9101/specification/selectOptionList.do

    在这里插入图片描述

    (8)修改 youlexuan_manager_web 的 specificationService.js

    /*关联规格*/
    this.selectOptionList = function () {
    	return $http.get('../specification/selectOptionList.do');
    }
    
    • 1
    • 2
    • 3
    • 4

    (9)修改 youlexuan_manager_web 的 typeTemplateController.js

    因为我们在模板控制层中需要使用品牌服务层的方法,所以需要添加依赖注入 specificationService

    在这里插入图片描述

    使用规格服务方法实现查询,结果赋给变量

    $scope.specList={data:[{id:1,text:'屏幕尺寸'},{id:2,text:'网络制式'},{id:3,text:'尺码'}]};//规格列表 静态测试
    
    $scope.specList={data:[]};//规格列表
    	/*关联规格*/
    	$scope.findSpecList = function () {
    	//读取规格列表
    	specificationService.selectOptionList().success(function (response) {
    
    	$scope.specList= {data:response};
        });
    
    }
    
    //定义同时初始化品牌、规格列表数据
    $scope.initSelect=function(){
    
        $scope.findSpecList();
        $scope.findBrandList();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    (8)修改typeTemplate.html ,添加JS引入

    在这里插入图片描述

    <script type="text/javascript" src="../js/service/specificationService.js"></script>
    
    • 1

    特别注意一下,JS引入的位置,要在typeTemplateController.js之前,因为该控制器要使用到它

    (9)修改typeTemplate.html ,添加初始化,同时初始化品牌、规格下拉菜单数据 ng-init="initSelect()"

    在这里插入图片描述

    2.4.3 效果显示

    最终实现效果如下:http://localhost:9101/admin/typeTemplate.html

    在这里插入图片描述

    2.5 扩展属性

    2.5.1 增加行

    (1) copy 代替自定义属性
    在这里插入图片描述

    优化删掉框框
    在这里插入图片描述

    在typeTemplateController.js中新增代码

    //模板扩展属性新增
    $scope.entity = {customAttributeItems:[]};
    
    $scope.addTableRow = function () {
    
    	$scope.entity.customAttributeItems.push({});
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在typeTemplate.html中的“新建”按钮,执行实体的初始化操作 ng-click="entity={customAttributeItems:[]}"
    在这里插入图片描述
    修改“新增扩展属性按钮” ng-click="addTableRow()"

    在这里插入图片描述
    循环表格、绑定属性名称

    在这里插入图片描述

    <tbody>
    	<tr ng-repeat="pojo in entity.customAttributeItems">
    	
    		<td><input class="form-control" ng-model="pojo.text" placeholder="属性名称">td>
    		<td>
    			<button type="button" class="btn btn-default" title="删除"><i
    	class="fa fa-trash-o">i> 删除
    			button>
    		td>
    	tr>
    tbody>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    (2) 最终显示:http://localhost:9101/admin/typeTemplate.html

    在这里插入图片描述

    2.5.2 删除行

    实现思路:在每一行将索引值传递给集合,在集合中删除。

    修改typeTemplateController.js新增以下代码

    //模板扩展属性删除
    
    $scope.deleTableRow = function (index) {
    
       	$scope.entity.customAttributeItems.splice(index,1);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    修改每行的删除按钮 ng-click="deleTableRow($index)"

    在这里插入图片描述

    $index 用于获取 ng-repeat 指令循环中的索引。

    (2) 最终显示:http://localhost:9101/admin/typeTemplate.html
    在这里插入图片描述

    2.5.3 保存(代码生成器处理了)

    在这里插入图片描述

    2.6 新增模板

    代码生成器已完成

    2.7 修改模板

    分析 👇🏾👇🏾 将 json字符串转换为json对象
    在这里插入图片描述

    修改typeTemplateController.js的 findOne 方法

    在这里插入图片描述

    $scope.entity.brandIds=  JSON.parse($scope.entity.brandIds);//转换品牌列表
    $scope.entity.specIds=  JSON.parse($scope.entity.specIds);//转换规格列表
    $scope.entity.customAttributeItems= JSON.parse($scope.entity.customAttributeItems);//转换扩展属性
    
    • 1
    • 2
    • 3

    从数据库中查询出来的是字符串,我们必须将其转换为json对象才能实现信息的回显。

    2.9 优化模板列表的显示

    现在完成的列表中都是以JSON格式显示的,不利于用户的查询。

    在这里插入图片描述
    我们需要将信息以更友好的方式展现出来,如下图形式

    我们需要将一个json字符串中某个属性的值提取出来,用逗号拼接成一个新的字符串。这样的功能比较常用,所以我们将方法写到baseController.js
    在这里插入图片描述

    //提取json字符串数据中某个属性,返回拼接字符串 逗号分隔
    $scope.jsonToString=function(jsonString,key){
        var json=JSON.parse(jsonString);//将json字符串转换为json对象
        var value="";
        for(var i=0;i<json.length;i++){
            if(i>0){
                value+=","
            }
            value+=json[i][key];
        }
        return value;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    注意:转换json字符串有可能为空,可以利用if(jsonString) 判断是否为空
    页面上使用该函数进行转换

    在这里插入图片描述

    <tbody>
    	<tr ng-repeat="entity in list">
    		  <td><input type="checkbox" ng-click="updateSelection($event,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>
    tbody>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    最终显示 : http://localhost:9101/admin/typeTemplate.html

    在这里插入图片描述

    2.10 查询

    2.10.1 后端代码

    代码生成器已经生成好了!

    2.10.2 前端代码

    <div class="box-tools pull-right">
       <div class="has-feedback">
           分类模板名称:<input ng-model="searchEntity.name">
           <button class="btn btn-default" ng-click="reloadList()">查询button>
       div>
    div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    typeTemplate.html 完整代码 👇🏾👇🏾

    DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>管理title>
        <meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport">
        <link rel="stylesheet" href="../plugins/bootstrap/css/bootstrap.min.css">
        <link rel="stylesheet" href="../plugins/adminLTE/css/AdminLTE.css">
        <link rel="stylesheet" href="../plugins/adminLTE/css/skins/_all-skins.min.css">
        <link rel="stylesheet" href="../css/style.css">
        <script src="../plugins/jQuery/jquery-2.2.3.min.js">script>
        <script src="../plugins/bootstrap/js/bootstrap.min.js">script>
    
        
        <link rel="stylesheet" href="../plugins/select2/select2.css"/>
        <link rel="stylesheet" href="../plugins/select2/select2-bootstrap.css"/>
        <script src="../plugins/select2/select2.min.js" type="text/javascript">script>
    
        <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 src="../js/angular-select2.js">script>
        <script type="text/javascript" src="../js/service/typeTemplateService.js">script>
    
        <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/controller/baseController.js">script>
        <script type="text/javascript" src="../js/controller/typeTemplateController.js">script>
    
    head>
    <body class="hold-transition skin-red sidebar-mini" ng-app="youlexuan" ng-controller="typeTemplateController"
          ng-init="initSelect()">
    
    <div class="box-header with-border">
        <h3 class="box-title">管理h3>
    div>
    
    <div class="box-body">
    
        
        <div class="table-box">
    
            
            <div class="pull-left">
                <div class="form-group form-inline">
                    <div class="btn-group">
                        <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>
                        <button type="button" class="btn btn-default" title="删除" ng-click="dele()"><i
                                class="fa fa-trash-o">i> 删除
                        button>
                        <button type="button" class="btn btn-default" title="刷新" onclick="window.location.reload();"><i
                                class="fa fa-refresh">i> 刷新
                        button>
                    div>
                div>
            div>
            
            <div class="box-tools pull-right">
                <div class="has-feedback">
                    分类模板名称:<input ng-model="searchEntity.name">
                    <button class="btn btn-default" ng-click="reloadList()">查询button>
                div>
            div>
    
            <div class="box-tools pull-right">
                <div class="has-feedback">
                div>
            div>
            
    
            
            <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="text-center">模板名称th>
                    <th class="text-center">关联规格th>
                    <th class="text-center">关联品牌th>
                    <th class="text-center">扩展属性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.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>
                tbody>
            table>
            
        div>
        
        
        <tm-pagination conf="paginationConf">tm-pagination>
    div>
    
    
    
    <div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×button>
                    <h3 id="myModalLabel">编辑h3>
                div>
                <div class="modal-body">
                    <table class="table table-bordered table-striped" width="800px">
                        <tr>
                            <td>模板名称td>
                            <td><input class="form-control" ng-model="entity.name" placeholder="模板名称">td>
                        tr>
    
                        <tr>
                            <td>关联品牌td>
                            <td><input select2 config="brandList" select2-model="entity.brandIds" multiple
                                       placeholder="选择品牌(可多选)" class="form-control" type="text"/>td>
                        tr>
    
                        <tr>
                            <td>关联规格td>
                            <td><input select2 config="specList" select2-model="entity.specIds" multiple
                                       placeholder="选择规格(可多选)" class="form-control" type="text"/>td>
                        tr>
                        <tr>
                            <td>扩展属性td>
                            <td>
                                <div class="btn-group">
                                    <button type="button" class="btn btn-default" ng-click="addTableRow()" title="新增扩展属性"><i
                                            class="fa fa-file-o">i> 新增扩展属性
                                    button>
                                    {{entity.customAttributeItems}}
                                div>
                                <table class="table table-bordered table-striped" width="800px">
                                    <thead>
                                    <tr>
    
                                        <td>属性名称td>
                                        <td>操作td>
                                    tr>
                                    thead>
                                    <tbody>
                                    <tr ng-repeat="pojo in entity.customAttributeItems">
    
                                        <td><input class="form-control" ng-model="pojo.text" placeholder="属性名称">td>
                                        <td>
                                            <button type="button" class="btn btn-default" ng-click="deleTableRow($index)"
                                                    title="删除"><i
                                                    class="fa fa-trash-o">i> 删除
                                            button>
                                        td>
                                    tr>
                                    tbody>
                                table>
                            td>
                        tr>
    
                    table>
                div>
                <div class="modal-footer">
                    <button class="btn btn-success" data-dismiss="modal" aria-hidden="true" ng-click="save()">保存button>
                    <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">关闭button>
                div>
            div>
        div>
    div>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
  • 相关阅读:
    MyCat-web安装文档:安装Zookeeper、安装Mycat-web
    为什么要注册软件著作权
    Analyzing User-Level Privacy Attack Against Federated Learning
    解决docker使用pandarallel报错OSError: [Errno 28] No space left on device
    iPhone手机记笔记工具选择用哪个
    tiup dm scale-out
    Springboot+JWT+Redis实现登陆登出功能
    记录--用JS轻松实现一个录音、录像、录屏的工具库
    Maven
    云原生安全应用场景有哪些?
  • 原文地址:https://blog.csdn.net/weixin_42171159/article/details/126218834