品优购 第三天

品优购 第三天

规格及模板管理

1.前端分层开发

1.1 需求分析

我们在上次课学习了angularJS并完成的品牌管理的增删改查功能。但是我们看代码,JS和html都放在一起,并不利于我们后期的维护。我们可以在前端代码中也运用MVC的设计模式,将代码进行分离,提高程序的可维护性。

1.2 自定义服务

在 AngularJS 中,服务是一个函数或对象,可在你的 AngularJS 应用中使用。我们在上次课中使用了内置服务$http .其实我们也可以自己来定义服务,而服务会封装一些操作。我们在不同的控制器中可以调用同一个服务,这样服务的代码将会被重用。

我们现在就修改一下我们的品牌管理代码,使用自定义服务。

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

//品牌服务层

app.service('brandService',function($http){

//读取列表数据绑定到表单中

this.findAll=function(){

return $http.get('../brand/findAll.do');

}

//其它方法省略.......

});

//品牌控制层

app.controller('brandController' ,function($scope,brandService){

//读取列表数据绑定到表单中

$scope.findAll=function(){

brandService.findAll().success(

function(response){

$scope.list=response;

}

);

}

//其它方法省略........

});

1.3代码分离

我们刚才已经将与后端交互的部分放入自定义服务,目的是不同的控制层都可以重复调用服务层方法。所以我们还需要将代码分离出来,以便调用。

1.3.1 前端基础层

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

var app=angular.module('pinyougou',[]);

创建base_pagination.js

var app=angular.module('pinyougou',['pagination']);

一个用于不需要分页功能的页面,一个用于需要分页功能的页面.

1.3.2 前端服务层

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

//品牌服务层

app.service('brandService',function($http){

//读取列表数据绑定到表单中

this.findAll=function(){

return $http.get('../brand/findAll.do');

}

//其它方法省略........

});

1.3.3 前端控制层

在pinyougou-manager-web的js文件夹下创建brandController.js

//品牌控制层

app.controller('brandController' ,function($scope,brandService){

//读取列表数据绑定到表单中

$scope.findAll=function(){

brandService.findAll().success(

function(response){

$scope.list=response;

}

);

}

//其它方法省略........

});

1.3.4 修改页面

去掉brand.html原来的JS代码,引入刚才我们建立的JS

(3) 选择数据库类型为 MYSQL ,输入用户名和密码后点击“测试连接”按钮,提示连接成功后选择数据库,点击“下一步”。

品优购 第三天

(4)选择模板为SSM+dubbox+angularJS(服务层+WEB层)

品优购 第三天

这个模板不会生成数据访问层和实体类,因为我们之前已经用逆向工程完成了数据访问层与实体类的生成。

(5)点击生成代码按钮,提示成功后,到生成路径去找生成的代码,并拷贝到我们的工程中。

3.2代码拷贝

将商家商品相关代码拷贝到工程。

(1) 拷贝服务接口

品优购 第三天

(2) 拷贝服务实现类

品优购 第三天

(3) 拷贝控制器

品优购 第三天

(4) 拷贝JS

品优购 第三天

3.3安装到本地仓库

执行maven命令install ,将最新的品优购代码安装到本地仓库

4.规格管理

4.1需求及表结构分析

4.1.1 需求

实现规格管理功能

品优购 第三天

4.1.2 表结构

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

排序

4.2规格列表

4.2.1 引入JS

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

4.2.3 指令与表达式

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

ng-app="pinyougou" ng-controller="specificationController" >

循环表格行

{{entity.id}}

{{entity.specName}}

4.3新增规格

4.3.1 新增行的实现

修改specificationController.js 新增以下代码

//新增选项行

$scope.addTableRow=function(){

$scope.entity.specificationOptionList.push({});

}

specification.html “新建选项”按钮

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

4.3.2 删除行的实现

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

修改specificationController.js 新增以下代码

//批量选项删除

$scope.deleTableRow=function(index){

$scope.entity.specificationOptionList.splice(index,1);//删除

}

修改每行的删除按钮

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

4.3.3 提交保存

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

(1) 我们要增加规格选项,必须要知道新增规格的ID, 所以我们在修改pinyougou-dao 的TbSpecificationMapper.xml ,在insert节点后添加如下配置

SELECT LAST_INSERT_ID() AS id

insert into tb_specification (id, spec_name)

values (#{id,jdbcType=BIGINT}, #{specName,jdbcType=VARCHAR})

(2)在pinyougou-pojo 建立com.pinyougou.pojogroup包,包下建立Specification类

package com.pinyougou.pojogroup;

import java.io.Serializable;

import java.util.List;

import com.pinyougou.pojo.TbSpecification;

import com.pinyougou.pojo.TbSpecificationOption;

/**

* 规格组合实体类

* @author Administrator

*

*/

public class Specification implements Serializable {

private TbSpecification specification;

private List specificationOptionList;

public TbSpecification getSpecification() {

return specification;

}

public void setSpecification(TbSpecification specification) {

this.specification = specification;

}

public List getSpecificationOptionList() {

return specificationOptionList;

}

public void setSpecificationOptionList(List specificationOptionList) {

this.specificationOptionList = specificationOptionList;

}

}

(%1) 修改pinyougou-sellergoods-interface的SpecificationService.java

/**

* 增加

*/

public void add(Specification specification);

(%1) 修改pinyougou-sellergoods-service的SpecificationServiceImpl.java

/**

* 增加

*/

@Override

public void add(Specification specification) {

specificationMapper.insert(specification.getSpecification());//插入规格

//循环插入规格选项

for(TbSpecificationOption specificationOption:specification.getSpecificationOptionList()){ specificationOption.setSpecId(specification.getSpecification().getId());//设置规格ID specificationOptionMapper.insert(specificationOption);

}

}

(5)修改pinyougou-manager-web的SpecificationController.java

/**

* 增加

* @param specification

* @return

*/

@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, "增加失败");

}

}

(%1) 修改页面specification.html

绑定规格名称

规格名称

绑定保存按钮事件

4.4修改规格

4.4.1 获取规格数据

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

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

/**

* 根据ID获取实体

* @param id

* @return

*/

public Specification findOne(Long id);

(2)修改pinyougou-sellergoods-service的SpecificationServiceImpl.java

/**

* 根据ID获取实体

* @param id

* @return

*/

@Override

public Specification findOne(Long id){

//查询规格

TbSpecification tbSpecification = specificationMapper.selectByPrimaryKey(id);

//查询规格选项列表

TbSpecificationOptionExample example=new TbSpecificationOptionExample();

Criteria criteria = example.createCriteria();

criteria.andSpecIdEqualTo(id);//根据规格ID查询

List optionList = specificationOptionMapper.selectByExample(example);

//构建组合实体类返回结果

Specification spec=new Specification();

spec.setSpecification(tbSpecification);

spec.setSpecificationOptionList(optionList);

return spec;

}

(3)修改pinyougou-manager-web的SpecificationController.java

@RequestMapping("/findOne")

public Specification findOne(Long id){

return specificationService.findOne(id);

}

(%1) 修改页面specification.html 中列表的修改按钮

4.4.2 保存修改结果

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

/**

* 修改

*/

public void update(Specification specification);

(2)修改pinyougou-sellergoods-service的SpecificationServiceImpl.java

/**

* 修改

*/

@Override

public void update(Specification specification){

//保存修改的规格

specificationMapper.updateByPrimaryKey(specification.getSpecification());//保存规格

//删除原有的规格选项

TbSpecificationOptionExample example=new TbSpecificationOptionExample();

com.pinyougou.pojo.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);

}

}

(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)修改specification.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);

}

}

);

}

4.5删除规格

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

4.5.1 后端代码

修改pinyougou-sellergoods-service的SpecificationServiceImpl.java

/**

* 批量删除

*/

@Override

public void delete(Long[] ids) {

for(Long id:ids){

specificationMapper.deleteByPrimaryKey(id);

//删除原有的规格选项

TbSpecificationOptionExample example=new TbSpecificationOptionExample();

com.pinyougou.pojo.TbSpecificationOptionExample.Criteria criteria = example.createCriteria();

criteria.andSpecIdEqualTo(id);//指定规格ID为条件

specificationOptionMapper.deleteByExample(example);//删除

}

}

4.5.2 前端代码

修改pinyougou-manager-web的specification.html

列表的复选框

删除按钮

5.模板管理

5.1 需求及表结构分析

5.1.1 需求分析

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

1是用于关联品牌与规格

2定义扩充属性

5.1.2 表结构分析

tb_type_template 模板表

字段

类型

长度

含义

Id

Bigint

主键

name

Varchar

80

模板名称

Spec_ids

Varchar

1000

关联规格(json格式)

brand_ids

Varchar

1000

关联品牌(json格式)

custom_attribute_items

Varchar

2000

扩展属性

5.2 模板列表

5.2.1 引入JS

修改type_template.html ,引入JS

5.2.3 指令与表达式

{{entity.id}}

{{entity.name}}

{{entity.brandIds}}

{{entity.specIds}}

{{entity.customAttributeItems}}

5.3 品牌下拉列表

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

品优购 第三天

5.2.1 认识select2

我们来看例子:我们需要的就是这样可以多选的下拉框

品优购 第三天

5.2.2 显示品牌下拉列表(静态)

(1)修改 type_template.html 引入JS

multiple 表示可多选

Config用于配置数据来源

select2-model用于指定用户选择后提交的变量

最终实现效果如下:

品优购 第三天

5.2.3 后端数据支撑

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

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