1. 前端分层
1)在web工程新建下的js目录下新建两个目录service和controller,如图:
2)将品牌管理中的js代码分别抽取到service与controller,如图;
brandService.js
app.service("brandService",function($http){
// 查询所有品牌列表
this.findAll = function(){
return $http.get("../brand/findAll.do");
}
// 查询品牌分页列表
this.findPage = function(page,size,entity){
return $http.post("../brand/findPage.do?page=" + page + "&size=" + size,entity);
}
// 添加
this.add = function(entity){
return $http.post("../brand/add.do",entity);
}
// 修改
this.update = function(entity){
return $http.post("../brand/update.do",entity);
}
// 查询单个品牌
this.findOne = function(id){
return $http.get("../brand/findOne.do?id="+id);
}
// 删除
this.dele = function(ids){
return $http.get("../brand/delete.do?ids="+ids);
}
});
brandController.js
app.controller("brandController",function($scope,$http,brandService){
// 查询所有品牌列表
$scope.findAll = function(){
brandService.findAll().success(function(response){
$scope.list = response;
});
}
//分页控件配置
$scope.paginationConf = {
currentPage: 1,
totalItems: 10,
itemsPerPage: 10,
perPageOptions: [10, 20, 30, 40, 50],
onChange: function(){
$scope.reloadList();
}
};
// 刷新列表
$scope.reloadList = function(){
$scope.findPage($scope.paginationConf.currentPage,$scope.paginationConf.itemsPerPage);
}
$scope.seachEntity = {};
// 查询品牌分页列表
$scope.findPage = function(page,size){
brandService.findPage(page,size,$scope.seachEntity).success(function(response){
$scope.list = response.rows; // 显示当前页数据
$scope.paginationConf.totalItems = response.total; // 修改总记录数
});
}
// 新增/修改
$scope.save = function(){
var object = null;
if($scope.entity.id){
object = brandService.update($scope.entity);
} else {
object = brandService.add($scope.entity);
}
object.success(function(response){
if(response.success){
$scope.reloadList();
} else {
alert(response.message);
}
});
}
// 根据id查询
$scope.findOne = function(id){
brandService.findOne(id).success(function(response){
$scope.entity = response;
});
}
// 定义一个变量用于记录用户选中的记录id
$scope.selectIds = [];
// 定义选中函数
$scope.updateSelection = function($event,id){
if($event.target.checked){ // 如果复选框被选中了
$scope.selectIds.push(id);
} else {
$scope.selectIds.splice($scope.selectIds.indexOf(id), 1);
}
}
// 删除
$scope.dele = function(){
brandService.dele($scope.selectIds).success(function(response){
if(response.success){
$scope.reloadList();
$scope.selectIds = [];
} else {
alert(response.message);
}
});
}
});
3)将模块的定义放在base.js文件中
base.js
// 定义模块
var app = angular.module("pinyougou",[]);
base_pagination.js
// 定义模块
var app = angular.module("pinyougou",['pagination']);
4)在brand.html页面中引入js文件
5)抽取公共的controller
baseController.js
app.controller("baseController",function($scope){
/*
* 分页控件
* */
// 1. 分页控件配置
$scope.paginationConf = {
currentPage: 1,
totalItems: 10,
itemsPerPage: 10,
perPageOptions: [10, 20, 30, 40, 50],
onChange: function(){
$scope.reloadList();
}
};
// 2. 刷新列表
$scope.reloadList = function(){
$scope.findPage($scope.paginationConf.currentPage,$scope.paginationConf.itemsPerPage);
}
/*
* 3. 搜索实体bean定义
*/
$scope.seachEntity = {};
/*
* 复选框勾选
*
* */
// 1. 定义一个变量用于记录用户选中的记录id
$scope.selectIds = [];
// 2. 定义选中函数
$scope.updateSelection = function($event,id){
if($event.target.checked){ // 如果复选框被选中了
$scope.selectIds.push(id);
} else {
$scope.selectIds.splice($scope.selectIds.indexOf(id), 1);
}
}
});
2. 规格管理
2.1 表结构
tb_specification 规格表
字段 | 类型 | 长度 | 含义 |
Id | Bigint |
| 主键 |
Spec_name | Varchar | 255 | 规格名称 |
tb_specification_option 规格选项表
字段 | 类型 | 长度 | 含义 |
Id | Bigint |
| 主键 |
Option_name | Varchar | 200 | 规格选项名称 |
Spec_id | Bigint | 30 | 规格ID |
Orders | Int | 11 | 排序 |
2.2 规格列表
2.2.1 引入js
<!-- 引入angularjs -->
<script type="text/javascript" src="../plugins/angularjs/angular.min.js"></script>
<!-- 分页组件开始 -->
<script type="text/javascript" src="../plugins/angularjs/pagination.js"></script>
<link rel="stylesheet" href="../plugins/angularjs/pagination.css">
<!-- 分页组件结束 -->
<!-- 引入js文件 -->
<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>
2.2.2 编写service与controller层的js
2.2.3 页面改造
1)添加分页插件
2)添加相关指令
2.2.4 后端代码
2.2.5 测试
2.3 新增规格
2.3.1 前端
A. 新增行的实现
1)html
<tr ng-repeat = "item in entity.specificationOptionalList">
<td>
<input class="form-control" placeholder="规格选项" ng-model="item.optionName">
</td>
<td>
<input class="form-control" placeholder="排序" ng-model="item.orders">
</td>
<td>
<button type="button" class="btn btn-default" title="删除" ng-click="deleTableRow($index)"><i class="fa fa-trash-o"></i> 删除</button>
</td>
</tr>
2)js代码
$scope.addTableRow = function(){
$scope.entity.specificationOptionalList.push({});
}
B. 删除行的实现
实现思路:在每一行将索引值传递给集合,在集合中删除
$scope.deleTableRow = function(index){
$scope.entity.specificationOptionalList.splice(index,1);
}
C. 后端代码
1)组合实体类
package com.pinyougou.povo;
import java.io.Serializable;
import java.util.List;
import com.pinyougou.pojo.TbSpecification;
import com.pinyougou.pojo.TbSpecificationOption;
/**
* 规格组合实体bean
* @author Administrator
*
*/
public class Specification implements Serializable{
private TbSpecification specification;
private List<TbSpecificationOption> specificationOptionalList;
public TbSpecification getSpecification() {
return specification;
}
public void setSpecification(TbSpecification specification) {
this.specification = specification;
}
public List<TbSpecificationOption> getSpecificationOptionalList() {
return specificationOptionalList;
}
public void setSpecificationOptionalList(List<TbSpecificationOption> specificationOptionalList) {
this.specificationOptionalList = specificationOptionalList;
}
}
2)Mapper文件添加主键返回
3)接口与实现
接口:
public void add(Specification specification);
实现;
public void add(Specification specification) {
if(null != specification){
TbSpecification tbSpecification = specification.getSpecification();
specificationMapper.insert(tbSpecification);
List<TbSpecificationOption> list = specification.getSpecificationOptionalList();
for(TbSpecificationOption o : list){
o.setSpecId(tbSpecification.getId());
specificationOptionMapper.insert(o);
}
}
}
4)web层
在com.pinyougou.manager.controller.SpecificationController中添加
@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, "增加失败");
}
}
2.4 修改规格
通过规格ID,到后端查询规格和规格选项列表,然后通过组合实体类返回结果
2.5 删除规格
删除规格的同时,还要记得将关联的规格选项删除掉
3. 模板管理
3.1 表结构
tb_type_template 模板表
字段 | 类型 | 长度 | 含义 |
Id | Bigint |
| 主键 |
name | Varchar | 80 | 模板名称 |
Spec_ids | Varchar | 1000 | 关联规格(json格式) |
brand_ids | Varchar | 1000 | 关联品牌(json格式) |
custom_attribute_items | Varchar | 2000 | 扩展属性 |
3.2 模板列表展示
1)引入js文件
2)修改HTML代码
3)修改js代码
4)测试结果
3.3 品牌下拉列表展示
3.3.1 后端新增查询品牌方法
1)dao
mapper
<!-- 查询品牌数据 -->
<select id="selectOptions" resultType="map">
select id , name text from tb_brand
</select>
接口:
/**
* 查询品牌数据
* @return
*/
List<Map<Long, String>> selectOptions();
2)服务接口与实现
接口:
/**
* 查询品牌数据
* @return
*/
List<Map<Long, String>> selectOptions();
实现类;
@Override
public List<Map<Long, String>> selectOptions() {
return brandMapper.selectOptions();
}
3)web层
@RequestMapping("/selectOptionList")
public List<Map<Long, String>> selectOptionList(){
return brandService.selectOptions();
}
3.3.2 前端
1)js代码
在brandService.js中添加方法
// 查询品牌信息
this.selectOptionList = function(){
return $http.get("../brand/selectOptionList.do");
}
在typeTemplateController.js中引入brandService
在typeTemplateController.js中添加方法
// 多选
$scope.brandList={data:[]};//定义品牌列表数据结构
$scope.findBrandList = function() {
brandService.selectOptionList().success(function(response) {
$scope.brandList = {data:response};
});
}
2)前台页面改造
在新建按钮添加点击事件
3.3.3 测试
3.3 规格下拉列表
实现方式同品牌下拉列表
3.4 新增扩展属性
1)新增1行与删除1行js
// 新增扩展属性
$scope.addtableRow = function() {
$scope.entity.customAttributeItems.push({});
}
// 删除扩展属性
$scope.dele = function(index){
$scope.entity.customAttributeItems.splice(index,1);
}
2)页面属性绑定
3)添加点击事件
4)测试
点击保存
3.5 修改模板
1)在修改button上添加点击事件findOne
2)修改findOne方法
//查询实体
$scope.findOne=function(id){
typeTemplateService.findOne(id).success(
function(response){
$scope.entity= response;
// 转换字符串为json
$scope.entity.specIds = JSON.parse($scope.entity.specIds);
$scope.entity.brandIds = JSON.parse($scope.entity.brandIds);
$scope.entity.customAttributeItems = JSON.parse($scope.entity.customAttributeItems);
}
);
}
3)测试:给电视添加重量扩展属性
注意:从数据库中查询出来的是字符串,我们必须将其转换为json对象才能实现信息的回显。
3.6 优化模板列表显示
模板列表品牌,规格和扩展属性,我们数据库中存储的是json格式的字符串,所以我们在页面不能直接使用,需要转换一下。
1)在baseController定义转换函数
/*
* Json字符串获取指定的key的字符串
* */
$scope.jsonToString = function(jsonstr,key) {
if(jsonstr){
var json=JSON.parse(jsonstr);//将json字符串转换为json对象
var value="";
for(var i=0;i<json.length;i++){
if(i>0){
value+=","
}
value+=json[i][key];
}
return value;
}
}
2)页面中调用该函数
3)测试