品优购项目02——品牌管理

1. 品牌列表实现

1.1 数据库表

tb_brand  品牌表

字段

类型

长度

含义

Id

Bigint

 

主键

Name

Varchar

255

品牌名称

First_char

Varchar

1

品牌首字母

1.2 后端代码开发

1.2.1 服务层接口

在pinyougou-sellergoods-interface 工程创建BrandService接口

package com.pinyougou.sellergoods.service;

import java.util.List;

import com.pinyougou.pojo.TbBrand;

/**
 * 品牌接口
 * @author Administrator
 *	
 */
public interface BrandService {
	/**
	 * 返回品牌列表
	 * @return
	 */
	List<TbBrand> findAll();
}

1.2.2 服务实现类

在pinyougou-sellergoods-service 工程创建BrandServiceImpl类

package com.pinyougou.sellergoods.service.impl;

import java.util.List;

import javax.annotation.Resource;

import com.alibaba.dubbo.config.annotation.Service;
import com.pinyougou.mapper.TbBrandMapper;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.sellergoods.service.BrandService;

/**
 * 品牌服务实现类
 * @author Administrator
 *
 */
@Service
public class BrandServiceImpl implements BrandService{
	
	@Resource
	private TbBrandMapper brandMapper;

	@Override
	public List<TbBrand> findAll() {
		return brandMapper.selectByExample(null);
	}

}

注意:

1)类上的注解@Service是dubbox包下的(com.alibaba.dubbo.config.annotation.Service)

2)如果关联不上接口与mapper,引一下依赖

1.2.3 Controller层代码编写

品牌管理应该是运营商的权限,商家是没有权限管理的,所以应该在pinyougou-manager-web工程创建com.pinyougou.manager.controller包,包下创建BrandController类

1)添加interface依赖

<!-- 添加interface依赖 -->
  	<dependency>
		<groupId>com.pinyougou</groupId>
		<artifactId>pinyougou-sellergoods-interface</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</dependency>

2)BrandController.java

package com.pinyougou.manager.controller;

import java.util.List;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.dubbo.config.annotation.Reference;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.sellergoods.service.BrandService;

/**
 * @author Administrator
 *
 */
@RestController
@RequestMapping("/brand")
public class BrandController {
	
	@Reference
	private BrandService brandService;
	
    @RequestMapping("/findAll")
	public List<TbBrand> findAll(){
		return brandService.findAll();
	}
}

注意:这里注入用@Reference,远程注入

1.3 测试

1)启动zookeeper

2)启动pinyougou-sellergoods-service

3)启动pinyougou-manager-web

输入网址:http://localhost:9101/brand/findAll.do  浏览器返回json数据如图:

1.3 前端开发

1.3.1 静态原型准备

1.3.2 引入angular

<script type="text/javascript" src="../plugins/angularjs/angular.min.js"></script>

1.3.3 品牌列表数据获取

1)js代码

<script>
    	var app = angular.module("pinyougou",[]);
    	app.controller("brandController",function($scope,$http){
    		// 查询品牌列表
    		$scope.findAll = function(){
    			$http.get("../brand/findAll.do").success(function(response){
    				$scope.list = response;
    			});
    		}
    	});
    </script>

2)引入angular相关指令

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

3)循环list,展示品牌数据

<tbody>
	  <tr ng-repeat="brand in list">
		  <td><input  type="checkbox" ></td>			                              
		  <td>{{brand.id}}</td>
		  <td>{{brand.name}}</td>									     
		  <td>{{brand.firstChar}}</td>		                                 
		  <td class="text-center">                                           
			  <button type="button" class="btn bg-olive btn-xs" data-toggle="modal" data-target="#editModal"  >修改</button>                                           
		  </td>
	  </tr>
	</tbody>

1.3.4 访问测试

1.4 分页功能实现

1.4.1 后端

1)分页结果封装实体类

在pinyougou-pojo工程中创建entity包,用于存放通用实体类,创建类PageResult

package entity;

import java.io.Serializable;
import java.util.List;

/**
 * 分页结果类
 * @author Administrator
 * @param <T>
 */
public class PageResult<T> implements Serializable {
	private static final long serialVersionUID = -8744309372650296153L;
	
	private Long total;
	private List<T> rows;
	
	public PageResult() {
		super();
		// TODO Auto-generated constructor stub
	}
	public PageResult(Long total, List<T> rows) {
		super();
		this.total = total;
		this.rows = rows;
	}
	public Long getTotal() {
		return total;
	}
	public void setTotal(Long total) {
		this.total = total;
	}
	public List<T> getRows() {
		return rows;
	}
	public void setRows(List<T> rows) {
		this.rows = rows;
	}
	@Override
	public String toString() {
		return "PageResult [total=" + total + ", rows=" + rows + "]";
	}
	
}

2)服务层编写

pinyougou-sellergoods-interfaceBrandService.java 增加方法定义

	/**分页查询品牌列表
	 * @param pageNum  当前页
	 * @param pagesize 每页记录数
	 * @return
	 */
	PageResult<TbBrand> findPage(int pageNum,int pagesize);

在pinyougou-sellergoods-service的BrandServiceImpl.java中实现该方法

@Override
	public PageResult<TbBrand> findPage(int pageNum, int pagesize) {
		PageHelper.startPage(pageNum, pagesize); // 分页
		Page<TbBrand> page = (Page<TbBrand>) brandMapper.selectByExample(null);
		return new PageResult<>(page.getTotal(), page.getResult());
	}

3)web层

在pinyougou-manager-web工程的BrandController.java新增方法

@RequestMapping("/findPage")
	public PageResult<TbBrand> findPage(int page,int size){
		return brandService.findPage(page, size);
	}

访问结果如图: 

1.4.2 前端

1)引入分页插件

在brand.html的head部分添加如下代码

<!-- 分页组件开始 -->
<script type="text/javascript" src="../plugins/angularjs/pagination.js"></script>
<link rel="stylesheet" href="../plugins/angularjs/pagination.css">
<!-- 分页组件结束 -->

2)构建app模块时引入pagination模块

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

3)在表格下放置分页组件

<tm-pagination conf="paginationConf"></tm-pagination>

如图:

4)设置分页paginationConf 属性

$scope.paginationConf = {
		 currentPage: 1,
		 totalItems: 10,
		 itemsPerPage: 10,
		 perPageOptions: [10, 20, 30, 40, 50],
		 onChange: function(){
		      
		 }
}; 

参数解释;

currentPage:当前页
 totalItems:总记录数
itemsPerPage:每页记录数
perPageOptions:分页选项

注意:这里的paginationConf与<tm-pagination conf="paginationConf"></tm-pagination>中的conf的属性值必须保持一致

5)编写前端分页逻辑

// 查询品牌分页列表
$scope.findPage = function(page,size){
	$http.get("../brand/findPage?page=" + page + "&size=" + size).success(function(response){
			$scope.list = response.rows;						// 显示当前页数据
			$scope.paginationConf.totalItems = response.total;  // 修改总记录数
	});    			
}

6)分页调用逻辑编写

// 刷新列表
$scope.reloadList = function(){
    		$scope.findPage($scope.paginationConf.currentPage,$scope.paginationConf.itemsPerPage);
}

在分页属性的onChange中加入分页调用

7)去掉body上的ng-init="findAll()",因为分页插件自动会触发分页方法 

测试结果:

2. 增加品牌

2.1 后端代码实现

2.1.1 结果类创建

为了系统的友好型,我们需要在操作成功或者失败的时候,给用户一个有好的 提示,所以定义一个Result类用于记录后端的返回信息给前端,当然也可以用map

package entity;

import java.io.Serializable;

/**
 * 后端返回给前端的结果
 * @author Administrator
 *
 */
public class Result implements Serializable{
	private Boolean success;    // 是否成功
	private String message;		// 返回的信息
	
	public Boolean getSuccess() {
		return success;
	}
	public void setSuccess(Boolean success) {
		this.success = success;
	}
	public String getMessage() {
		return message;
	}
	public void setMessage(String message) {
		this.message = message;
	}
	public Result(Boolean success, String message) {
		super();
		this.success = success;
		this.message = message;
	}
	public Result() {
		super();
	}
	
}

2.1.2 服务层添加方法

1)接口添加add方法

	/**
	 * 添加品牌
	 * @param brand
	 */
	void add(TbBrand brand);

2)实现类添加方法

	@Override
	public void add(TbBrand brand) {
		brandMapper.insert(brand);
	}

2.1.3 web层添加add方法

 

@RequestMapping("/add")
	public Result add(@RequestBody TbBrand brand){
		try {
			brandService.add(brand);
			return new Result(true, "添加成功!");
		} catch (Exception e) {
			e.printStackTrace();
			return new Result(false, "添加失败!");
		}
	}

2.2 前端代码实现

1)添加逻辑代码

// 新增
$scope.add = function(){
    $http.post("../brand/add",$scope.entity).success(function(response){
    	if(response.success){
    		$scope.reloadList();
    	} else {
    		alert(response.message);
    	}
    });
}

2)页面编写

<!-- 编辑窗口 -->
<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" placeholder="品牌名称" ng-model="entity.name">  </td>
		      	</tr>		      	
		      	<tr>
		      		<td>首字母</td>
		      		<td><input  class="form-control" placeholder="首字母" ng-model="entity.firstChar">  </td>
		      	</tr>		      	
			 </table>				
		</div>
		<div class="modal-footer">						
			<button class="btn btn-success" data-dismiss="modal" aria-hidden="true" ng-click="add()">保存</button>
			<button class="btn btn-default" data-dismiss="modal" aria-hidden="true">关闭</button>
		</div>
	  </div>
	</div>
</div>

测试:

3. 品牌修改

3.1 后端代码

1)接口代码编写

	/**
	 * 根据ID查询品牌信息
	 * @param id
	 * @return
	 */
	TbBrand findOne(Long id);
	
	/**修改品牌信息
	 * @param brand
	 * @return
	 */
	void update(TbBrand brand);

2)服务层代码代码编写

	@Override
	public TbBrand findOne(Long id) {
		return brandMapper.selectByPrimaryKey(id);
	}

	@Override
	public void update(TbBrand brand) {
		brandMapper.updateByPrimaryKey(brand);
	}

3)web层代码编码

	/** 根据ID查询
	 * @param id
	 * @return
	 */
	@RequestMapping("findOne")
	public TbBrand findOne(Long id){
		return brandService.findOne(id);
	}
	
	/**
	 * 添加品牌
	 * @param brand
	 * @return
	 */
	@RequestMapping("/update")
	public Result update(@RequestBody TbBrand brand){
		try {
			brandService.update(brand);
			return new Result(true, "修改成功!");
		} catch (Exception e) {
			e.printStackTrace();
			return new Result(false, "修改失败!");
		}
	}

3.2 前端代码编写

1)添加根据id查询的方法

// 根据id查询
$scope.findOne = function(id){
    $http.get("../brand/findOne.do?id="+id).success(function(response){
    	$scope.entity = response;
    });
}

2)添加修改事件

3)修改保存方法

测试:

4. 品牌删除

4.1 后端代码

1)dao层代码

接口

	/**根据id批量删除
	 * @param ids
	 */
	void delByIds(@Param("ids") Long[] ids);

 xml

  <!-- 根据ID批量删除 -->
  <delete id="delByIds" parameterType="long">
  		delete from tb_brand
  		where id in (
  			<foreach collection="ids" separator="," item="id">
  				#{id}
  			</foreach>
  		);
  </delete>

2)接口代码

	/** 根据id批量删除
	 * @param ids
	 */
	void delete(Long[] ids);

3)服务层业务逻辑

	@Override
	public void delete(Long[] ids) {
		brandMapper.delByIds(ids);
	}

4)web层

	/**
	 * 批量删除品牌
	 * @param brand
	 * @return
	 */
	@RequestMapping("/delete")
	public Result delete(Long[] ids){
		try {
			brandService.delete(ids);
			return new Result(true, "删除成功!");
		} catch (Exception e) {
			e.printStackTrace();
			return new Result(false, "删除失败!");
		}
	}

4.2 前端代码

1)业务代码

// 定义一个变量用于记录用户选中的记录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(){
	$http.get("../brand/delete.do?ids="+$scope.selectIds).success(function(response){
		if(response.success){
			$scope.reloadList();
			$scope.selectIds = [];
		} else {
			alert(response.message);
		}
	});
}

2)页面改造

删除按钮

复选框 

 

注意:这里的$event表示input的源,$event.target表示input

4.3 测试

 

5. 条件查询

5.1 后端代码

条件查询只需要在之前的分页上加上条件就可以了,所以我们改造一下之前的findPage方法

1)接口

	/**分页查询品牌列表
	 * @param pageNum  当前页
	 * @param pagesize 每页记录数
	 * @return
	 */
	PageResult<TbBrand> findPage(TbBrand brand,int pageNum,int pagesize);

2)服务层

@Override
	public PageResult<TbBrand> findPage(TbBrand brand,int pageNum, int pagesize) {
		PageHelper.startPage(pageNum, pagesize); // 分页
		TbBrandExample example = null;
		if(null != brand){
			example = new TbBrandExample();
			Criteria createCriteria = example.createCriteria();
			if(!StringUtils.isEmpty(brand.getName())){
				createCriteria.andNameLike("%" + brand.getName() + "%");
			}
			if(!StringUtils.isEmpty(brand.getFirstChar())){
				createCriteria.andFirstCharEqualTo(brand.getFirstChar());
			}
		}
		Page<TbBrand> page = (Page<TbBrand>) brandMapper.selectByExample(example);
		return new PageResult<>(page.getTotal(), page.getResult());
	}

3)web层

/**
	 * 分页查询
	 * @param page
	 * @param size
	 * @return
	 */
	@RequestMapping("/findPage")
	public PageResult<TbBrand> findPage(@RequestBody TbBrand brand,int page,int size){
		return brandService.findPage(brand,page, size);
	}

5.2 前端代码

1)添加查询界面代码

<div class="box-tools pull-right">
	<div class="has-feedback">
		品牌名称:<input ng-model="seachEntity.name" />
		品牌首字母:<input ng-model="seachEntity.firstChar" />
		<button class="btn btn-default" ng-click="reloadList()">查询</button>
	</div>
</div>

2)改造findPage

$scope.seachEntity = {};
// 查询品牌分页列表
$scope.findPage = function(page,size){
		$http.post("../brand/findPage.do?page=" + page + "&size=" + size,$scope.seachEntity).success(function(response){
			$scope.list = response.rows;						// 显示当前页数据
			$scope.paginationConf.totalItems = response.total;  // 修改总记录数
		});    			
}

5.3 测试

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.2. 结构化一下 1.3. 图形化一下 1.3.1. 运营商后台 1.3.2. 商家后台 1.3.3. 网页前台 参考京东 2. 技术选型 前端:angularJS + Bootstrap 后台:SSM( springmvc+spring+mybatis) 数据库:mysql,使用mycat读写分离 开发模式:SOA 服务中间件:dubbox,需要和zookeeper配合使用 注册中心:zookeeper 消息中间件:Activemq,使用spring-jms 负载均衡:nginx 搜索:solr集群(solrCloud),配合zookeeper搭建, 使用spring-data-solor 缓存:redis集群,使用spring-data-redis 图片存储:fastDFS集群 网页静态化:freemarker 单点登录:cas 权限管理:SpringSecurity, 跨域:cros 支付:微信扫描 短信验证:阿里大于 密码加密:BCrypt 富文本:KindEditor 事务:声明式事务 任务调度:spring task 所有的技术,都可能涉及到为什么用?怎么用?用的过程中有什么问题? 3. 框架搭建 3.1. 前端 理解baseControler.js、base.js、base_pagination.js,以及每一个xxxController.js里面都公共的做了些什么。 baseControler.js 分页配置 列表刷新 处理checkBox勾选 xxxControler.js 自动生成增删改查 base_pagination.js 带分页 base.js 不带分页 3.2. dao 使用了mybatis逆向工程 4. 模块开发 逐个模块开发就好 4.1. 学会评估模块难不难 一个模块难不难从几方面考虑。 涉及几张表? 1,2张表的操作还是没有什么难度的。 涉及哪些功能? 增删改查,批量删除。 前端展示? 分页列表、树形、面包屑、三级联动、内容格式化。 4.2. 举几个简单模块的例子 4.2.1. 品牌管理 单表 分页、新增、删除、修改 4.2.2. 规格管理 2张表 分页、新增、删除、修改、显示优化(显示列表内容的一部分) 4.2.3. 模板管理 2张表 分页、新增、删除、修改、显示优化(显示列表内容的一部分) 4.2.4. 分类管理 单表 4.2.5. 商家审核 单表 4.3. 举一个复杂模块 4.3.1. 商品新增 需要插入3张表,tb_goods、tb_goods_desc、tb_item 前端:三级联动、富文本、图片上传、动态生成内容 4.3.2. 商品修改 需要从3张表获取数据,然后进行回显。 4.4. 典型模块设计 4.4.1. 管理后台 商品新增、商品修改 4.4.2. 前台页面 搜索模块实现 购物车模块实现 支付模块实现 秒杀模块实现 5. 开发过程中问题&优化 1.1. 登录 单点登录怎么实现 session怎么共享 1.2. 缓存 哪些场景需要用到redis redis存储格式的选择 怎么提高redis缓存利用率 缓存如何同步 1.3. 图片上传 图片怎么存储 图片怎么上传 1.4. 搜索 ​ 怎么实现 数据量大、 并发量高的搜索 怎么分词 1.5. 消息通知 ​ 哪些情况用到activeMq 1.6. 优化 seo怎么优化 怎么加快访问速度 1.7. 秒杀 ​ 怎么处理高并发 ​ 秒杀过程中怎么控制库存

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值