Java大型电商项目——品优购(一)

  • 视频教程:【黑马程序员】Java大型电商项目—品优购【配套源码+笔记】_哔哩哔哩_bilibili
  • 源码下载:  
    • 链接:https://pan.baidu.com/s/1fECz5In_XCB-aW6ed6ZTbA 
    • 提取码:27xa 

技术选型:

后端框架:Spring+SpringMVC+mybatis+Dubbox

前端:angularJS+Bootstrap

  • 分布式:Dubbox框架
  • 注册中心:Zookeeper

前端出错,先清理一下浏览器的缓存,再刷新一下页面,,还是报错,再去看代码 

第一部分 

运行环境

1、linux虚拟机

  • 运行linux虚拟机
  • 打开linux的终端,不可关闭虚拟机
  • 打开SecureCRT代替linux的终端写命令,更清楚
  • 启动zookeeper
    • cd
    • cd zookeeper-3.4.6
    • cd bin
    • ./zkServer.sh start
    • ./zkServer.sh status 查看zookeeper运行状态,是否开启了
    • Java大型电商项目——品优购(一)_第1张图片
    • 每次重启虚拟机,ip地址会发生变化,所以把虚拟机挂起就行,不用关机
    • 查看ip地址的命令:ifconfigJava大型电商项目——品优购(一)_第2张图片
    • 如果ip地址变化,则相应地修改springmvc.xml文件里的zookeeper信息。2181是zookeeper的默认端口,如果配置文件里没有改动,就不变Java大型电商项目——品优购(一)_第3张图片
    • 后续写代码时,在浏览器访问html文件时,不报错,但就是不显示表格,除了表格什么都正常,很难排错。后来发现是zookeeper的端口发生了变化,但是代码里没有修改过来。

2、mysql数据库

  • mysql如何导入.sql文件:http://t.csdnimg.cn/mhP9M
  • 保持打开状态,才可运行其他代码

后端:在IDEA上搭建工程

1、先建父工程,后建子模块

  •                Java大型电商项目——品优购(一)_第4张图片

2、引入依赖

  • 主要问题:
    • 有些依赖maven的本地仓库里没有,需要手动导入
      • 解决教程:http://t.csdnimg.cn/m4fCs
    • 有些依赖的版本需要修改,比如dubbo的2.8.4版本已经不维护了,要改成2.5.3;还有mysql的版本也要和自己电脑里8.0版本的mysql相对应,不能用5.0版本的。
      • 解决办法:只需对着pom.xml文件里的依赖在maven的本地仓库里逐个寻找,把爆红的依赖版本改成仓库里现有的依赖版本
  • 父工程的pom.xml文件需要手动导入的jar包命令如下
    •         mvn install:install-file
              -Dfile=D:\各种jar包\fastdfs-client-java-1.29.jar
              -DgroupId=org.csource
              -DartifactId=fastdfs-client-java
              -Dversion=1.29 
              -Dpackaging=jar
    •         mvn install:install-file
              -Dfile=D:\各种jar包\spring-security-cas-4.1.0.RELEASE.jar
              -DgroupId=org.springframework.security
              -DartifactId=spring-security-cas
              -Dversion=4.1.0.RELEASE
              -Dpackaging=jar
    •          mvn install:install-file
              -Dfile=D:\各种jar包\cas-client-core-3.5.1.jar
              -DgroupId=org.jasig.cas.client
              -DartifactId=cas-client-core
              -Dversion=3.3.3
              -Dpackaging=jar
    •         mvn install:install-file
              -Dfile=D:\各种jar包\kaptcha-2.3.2.jar
              -DgroupId=com.github.penggle
              -DartifactId=kaptcha
              -Dversion=2.3.2 
              -Dpackaging=jar
    •         mvn install:install-file
              -Dfile=D:\各种jar包\solr-solrj-4.10.3.jar
              -DgroupId=org.apache.solr
              -DartifactId=solr-solrj
              -Dversion=4.10.3
              -Dpackaging=jar
    •         mvn install:install-file
              -Dfile=D:\各种jar包\activemq-all-5.11.2.jar
              -DgroupId=org.apache.activemq
              -DartifactId=activemq-all
              -Dversion=5.11.2 
              -Dpackaging=jar
    •         mvn install:install-file
              -Dfile=D:\各种jar包\ikanalyzer-2012_u6.jar
              -DgroupId=com.janeluo
              -DartifactId=ikanalyzer
              -Dversion=2012_u6
              -Dpackaging=jar
      
      

3、逆向工程

  • 目的:实现实体类与数据访问层代码的自动生成
  • 老师发的资料里没有逆向工程的最新代码,把旧的代码修改一下,即可用,具体代码已放资源里
  • 修改的地方主要有
    • 1、mapper映射文件的生成位置
              
      		
      			
      			
      		
    • 2、数据库的连接密码
  • 逆向代码运行教程:http://t.csdnimg.cn/Qt5ti

  • 没有逆向工程源码也行,直接从老师发的资料里其他源码里拿到pojo包,接口包和mapper映射文件包三个包即可

  • 容易出现的问题:逆向工程的代码生错了,要仔细辨别 

4、编写后端代码

  • 注意@Service和@Refrence(远程调用)注解引入要用dubbo的,否则会注入失败,报空指针异常
    • import com.alibaba.dubbo.config.annotation.Reference;
    • import com.alibaba.dubbo.config.annotation.Service;

5、测试

  • 地址:http://localhost:9101/brand/findAll.do
  • 错误一:
    • Java大型电商项目——品优购(一)_第5张图片
    • 解决办法:http://t.csdnimg.cn/ZnSSP
    • 修改了db.properties文件里的jdbc.url和jdbc.driver
      jdbc.driver=com.mysql.cj.jdbc.Driver
      jdbc.url=jdbc:mysql://localhost:3306/pinyougoudb?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&useSSL=false
      
    • 然后把pinyougou-dao该重新clean和install,真正修改完数据库文件后,再运行
    •  
  • 测试成功后Java大型电商项目——品优购(一)_第6张图片
  • 测试这里出了很多错,无奈之下,把项目又重新做了一遍,发现父工程的依赖无法爆红,无法正常导入;逆向工程代码出错了;zookeeper的ip地址也有变化;数据库的相关配置也没有修改完全,修改后又没有更新到数据库配置文件里……想过很多次放弃,但也没有更好的选择,所以还是坚持下来了,最大的收获还是可以静下心来好好分析报错信息了。

前端:框架AngularJS

  • 四大特性

    • 1、MVC模式
    • 2、双向绑定
    • 3、依赖注入
    • 4、模块化设计
  • 基本内容

    • 表达式
      
      
          angularJS demo 表达式
          
      
      
      {{100+100}}
      
      
    • 双向绑定
      
      
          angularJS demo 双向绑定
          
      
      
      请输入你的名称:
      {{myname}},你好
      
      
    • 初始化指令
      
      
          angularJS demo 初始化指令
          
      
      
      请输入你的名称:
      {{myname}},你好
      
      
    • 控制器
      
      
          angularJS demo 控制器
          
          
      
      
      
      x:
      
      y:
      
      {{add()}}
      
      
      • Java大型电商项目——品优购(一)_第7张图片
    • 事件指令
      
      
          angularJS demo 事件指令
          
          
      
      
      x:
      y:
      
      
      {{z}}
      
      
    • 循环数组
      
      
          angularJS demo 循环数组
          
          
      
      
      
          
      {{x}}
    • 循环对象数组
      
      
          angularJS demo 循环对象数组
          
          
      
      
          
      {{x.name}} {{x.chinese}} {{x.math}}
    • 内置服务
      
      
          angularJS demo 内置服务
          
          
          
      
      
      
          
      {{x.name}} {{x.chinese}} {{x.math}}
      //json数据
      [
      //  key用双引号括起,value若是字符串也要用双引号括起
        {"name":"张三","chinese":1,"math":1},
        {"name":"李四","chinese":2,"math":2},
        {"name":"王五","chinese":3,"math":3},
        {"name":"赵六","chinese":4,"math":4}
      ]
  • 常用指令

    • ng-app:定义AngularJS应用程序的根元素
    • ng-model:用于绑定变量(输入端和变量端,双向绑定)
    • ng-init:初始化变量
    • ng-controller:用于指定所用控制器
    • ng-click:单击事件指令,点击时触发控制器的某个方法
    • ng-repeat:用于循环数组变量

第二部分(实现功能)

品牌列表分页

1、后端

PageResult

pinyougou-pojo模块

package entity;

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

/**
 * 分布结果实体类
 * 模块:pinyougou-pojo
 * 路径:src/main/java/entity
 */
public class PageResult implements Serializable {

    private long total;//记录总条数
    private List rows;//当面页记录
    //getter,setter方法和构造器省略
}
BrandService

pinyougou-sellergoods-interface模块

package com.pinyougou.sellergoods.service;

import com.pinyougou.pojo.TbBrand;
import entity.PageResult;

import java.util.List;

/**
 * 品牌业务接口
 */
public interface BrandService {
    /**
     * 分布查询
     * @param pageNum
     * @param pageSize
     * @return
     */
    public PageResult findPage(int pageNum,int pageSize);
}
 BrandServiceImpl

pinyougou-sellergoods-service模块

package com.pinyougou.sellergoods.service.impl;


import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.pinyougou.mapper.TbBrandMapper;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.sellergoods.service.BrandService;
import entity.PageResult;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * 品牌服务层实现类
 */
@Service
public class BrandServiceImpl implements BrandService {

    /**
     * 分页的服务层代码
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public PageResult findPage(int pageNum, int pageSize) {
        PageHelper.startPage(pageNum,pageSize);//分页插件
        Page page=(Page)brandMapper.selectByExample(null);
        //使用分页可以简化前端工作量,不必返回全部内容
        return new PageResult(page.getTotal(),page.getResult());
    }
}
BrandController

pinyougou-manager-web模块

package com.pinyougou.manager.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.sellergoods.service.BrandService;
import entity.PageResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * 品牌的控制器层
 */
public class BrandController {
    @RequestMapping("/findPage")
    public PageResult findPage(int page,int rows){
        return brandService.findPage(page,rows);
    }
}

 父工程重新install后,运行结果:

Java大型电商项目——品优购(一)_第8张图片

2、前端 




	
	
    
	
	
	
	
	
	
    


  
                        
                        
{{entity.id}} {{entity.name}} {{entity.firstChar}}

运行结果:

Java大型电商项目——品优购(一)_第9张图片

增加品牌

1、后端 

BrandService

pinyougou-sellergoods-interface

package com.pinyougou.sellergoods.service;

import com.pinyougou.pojo.TbBrand;
import entity.PageResult;

import java.util.List;

/**
 * 品牌业务接口
 */
public interface BrandService {
    /**
     * 增加品牌
     * @param brand
     */
    public void add(TbBrand brand);
}
BrandServiceImpl

pinyougou-sellergoods-service

package com.pinyougou.sellergoods.service.impl;


import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.pinyougou.mapper.TbBrandMapper;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.sellergoods.service.BrandService;
import entity.PageResult;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * 品牌服务层实现类
 */
@Service
public class BrandServiceImpl implements BrandService {

    /**
     * 增加品牌
     * @param brand
     */
    @Override
    public void add(TbBrand brand) {
        brandMapper.insert(brand);
    }
}
 BrandController

pinyougou-manager-web

package com.pinyougou.manager.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.sellergoods.service.BrandService;
import entity.PageResult;
import entity.Result;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * 品牌的控制器层
 */
@RestController
@RequestMapping("/brand")
public class BrandController {

    //增加品牌
    @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,"添加失败");
        }

    }
}
Result

pinyougou-pojo

package entity;

import java.io.Serializable;

/**
 * 增加品牌的返回结果实体类
 */
public class Result implements Serializable {

    private boolean success;
    private String message;
    //getter,setter方法,构造器省略
}

2、前端




	
    


  
                    
品牌ID 品牌名称 品牌首字母 操作

运行结果:

Java大型电商项目——品优购(一)_第10张图片

修改品牌

1、后端 

BrandService

pinyougou-sellergoods-interface

package com.pinyougou.sellergoods.service;

import com.pinyougou.pojo.TbBrand;
import entity.PageResult;

import java.util.List;

/**
 * 品牌业务接口
 */
public interface BrandService {
    /**
     * 根据ID查询实体
     * @param id
     * @return
     */
    public TbBrand findOne(Long id);

    /**
     * 修改
     * @param brand
     */
    public void update(TbBrand brand);
}
BrandServiceImpl

pinyougou-sellergoods-service

package com.pinyougou.sellergoods.service.impl;


import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.pinyougou.mapper.TbBrandMapper;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.sellergoods.service.BrandService;
import entity.PageResult;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * 品牌服务层实现类
 */
@Service
public class BrandServiceImpl implements BrandService {

    //根据ID查询
    @Override
    public TbBrand findOne(Long id) {
        return brandMapper.selectByPrimaryKey(id);
    }

    //修改
    @Override
    public void update(TbBrand brand) {
        brandMapper.updateByPrimaryKey(brand);
    }
}
BrandController

pinyougou-manager-web

package com.pinyougou.manager.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.sellergoods.service.BrandService;
import entity.PageResult;
import entity.Result;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * 品牌的控制器层
 */
public class BrandController {

    //根据ID查询
    @RequestMapping("/findOne")
    public TbBrand findOne(Long id){
        return brandService.findOne(id);
    }

    //修改
    @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,"修改失败");
        }
    }
}

运行结果:

2、前端




	
    


  
                    
{{entity.id}} {{entity.name}} {{entity.firstChar}}

运行结果:

Java大型电商项目——品优购(一)_第11张图片

删除品牌

1、后端 

BrandService

pinyougou-sellergoods-interface

package com.pinyougou.sellergoods.service;

import com.pinyougou.pojo.TbBrand;
import entity.PageResult;

import java.util.List;

/**
 * 品牌业务接口
 */
public interface BrandService {
    /**
     * 删除
     * @param ids
     */
    public void delete(Long []ids);
}
BrandServiceImpl

pinyougou-sellergoods-service

package com.pinyougou.sellergoods.service.impl;


import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.pinyougou.mapper.TbBrandMapper;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.sellergoods.service.BrandService;
import entity.PageResult;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * 品牌服务层实现类
 */
@Service
public class BrandServiceImpl implements BrandService {

    //删除
    @Override
    public void delete(Long[] ids) {
        for(Long id:ids){
            brandMapper.deleteByPrimaryKey(id);
        }
    }
}
BrandController

pinyougou-manager-web

package com.pinyougou.manager.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.sellergoods.service.BrandService;
import entity.PageResult;
import entity.Result;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * 品牌的控制器层
 */
@RestController
@RequestMapping("/brand")
public class BrandController {
    //删除
    @RequestMapping("/delete")
    public Result delete(Long []ids){
        try {
            brandService.delete(ids);
            return new Result(true,"删除成功☺");
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false,"删除失败");
        }
    }
}

运行结果:

Java大型电商项目——品优购(一)_第12张图片

2、前端




	    


  
                    
{{selectIds}}

条件查询

1、后端 

BrandService

pinyougou-sellergoods-interface

package com.pinyougou.sellergoods.service;

import com.pinyougou.pojo.TbBrand;
import entity.PageResult;

import java.util.List;

/**
 * 品牌业务接口
 */
public interface BrandService {
    /**
     * 条件查询
     * @param pageNum
     * @param pageSize
     * @return
     */
    //直接传递一个实体类TbBrand比逐个传递它的属性要更灵活
    public PageResult findPage(TbBrand brand,int pageNum,int pageSize);
}
BrandServiceImpl

pinyougou-sellergoods-service

package com.pinyougou.sellergoods.service.impl;


import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.pinyougou.mapper.TbBrandMapper;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.pojo.TbBrandExample;
import com.pinyougou.sellergoods.service.BrandService;
import entity.PageResult;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * 品牌服务层实现类
 */
@Service
public class BrandServiceImpl implements BrandService {
    //条件查询
    @Override
    public PageResult findPage(TbBrand brand, int pageNum, int pageSize) {
        //分页插件
        PageHelper.startPage(pageNum,pageSize);
        //封装查询条件
        TbBrandExample example = new TbBrandExample();
        //构建查询条件的类
        TbBrandExample.Criteria criteria = example.createCriteria();

        if(brand!=null){
            //如果有名称的条件
            if(brand.getName()!=null && brand.getName().length() > 0){
                //where name like %s%
                criteria.andNameLike("%"+brand.getName()+"%");
            }
            //如果有首字母的条件
            if(brand.getFirstChar()!=null && brand.getFirstChar().length() > 0){
                criteria.andFirstCharEqualTo(brand.getFirstChar());
            }
        }

        Page page=(Page)brandMapper.selectByExample(null);
        return new PageResult(page.getTotal(),page.getResult());
    }
}
BrandController

pinyougou-manager-web

package com.pinyougou.manager.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.sellergoods.service.BrandService;
import entity.PageResult;
import entity.Result;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * 品牌的控制器层
 */
@RestController
@RequestMapping("/brand")
public class BrandController {
    //条件查询
    @RequestMapping("/search")
    public PageResult search(@RequestBody TbBrand brand, int page,int rows){
        return brandService.findPage(brand,page,rows);
    }
}

2、前端




	
    


  
                    
名称: 首字母:

运行结果:

Java大型电商项目——品优购(一)_第13张图片Java大型电商项目——品优购(一)_第14张图片


第三部分(简化开发)

前端分层开发(后端MVC的分层思想)

Java大型电商项目——品优购(一)_第15张图片

brand.html




	
	
	

base_pagination.js

//使用分页插件时,引入该资源
var app=angular.module("pinyougou",["pagination"]);

base.js

//不使用分页插件时,引入该资源
var app=angular.module("pinyougou",[]);

brandService.js

//构建前端服务层
//和后端打交道的代码写在服务层
app.service("brandService",function($http){
    //$get:传递属性,变量; $post:传递对象
    this.findAll=function () {
        return $http.get('../brand/findAll.do');
    }
    this.findPage=function (page,rows) {
        return $http.get("../brand/findPage.do?page="+page+"&rows="+rows);
    }
    this.search=function (page,rows,searchEntity) {
        return $http.post("../brand/search.do?page="+page+"&rows="+rows,searchEntity);
    }
    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,brandService) {
    //读取列表数据绑定到表单中
    $scope.findAll=function () {
        brandService.findAll().success(function(response){
            $scope.list=response;
        })
    }
    //定义搜索对象
    $scope.searchEntity={};
    //条件查询+分页
    $scope.search=function(page,rows){
        brandService.search(page,rows,$scope.searchEntity).success(function (response) {
            $scope.list=response.rows;//给列表变量赋值
            $scope.paginationConf.totalItems=response.total;//定义总记录数
        })
    }
    //分页
    $scope.findPage=function(page,rows) {
        brandService.findPage(page,rows).success(function(response){
            $scope.list=response.rows;
            $scope.paginationConf.totalItems=response.total;//定义总记录数
        })

    }
    //定义对象paginationConf,分布的配置
    $scope.paginationConf={
        currentPage: 1,//当前页
        totalItems: 10,//总记录条数
        itemsPerPage: 10,//每页的记录条数
        perPageOptions: [10,20,30,40,50],//页码选项,每页10条还是20还是...
        onChange: function () {//当页码发生变化时自动触发的方法
            $scope.reloadList();
        }
    }
    //重新加载记录
    $scope.reloadList=function () {
        $scope.search($scope.paginationConf.currentPage,$scope.paginationConf.itemsPerPage);
    }
    //保存(新增和修改)
    $scope.save=function () {
        var object=null;
        //新增时,id为空;但修改时,id不为空
        if($scope.entity.id!=null){
            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;
        })
    }
    //批量选中
    $scope.selectIds=[];//选中的ID数组,准备批量删除的数据
    $scope.updateSelection=function($event,id){
        if($event.target.checked){//判断是否选中
            $scope.selectIds.push(id);//向数组中添加数据
        }else{
            var idx=$scope.selectIds.indexOf(id);//id在选中数据的数组中的位置
            $scope.selectIds.splice(idx,1);//从数组中删除数据,重复点复选框,选择和取消选择反复横跳
        }
    }
    //删除
    $scope.dele=function () {
        brandService.dele($scope.selectIds).success(function (response) {
            if(response.success){
                $scope.reloadList();//刷新列表
                $scope.selectIds=[];
            }else{
                alert(response.message);//打印信息
            }
        })
    }
})

 控制器继承(提高代码复用率)

Java大型电商项目——品优购(一)_第16张图片

brand.html




	
	 

baseController.js

//父控制器
app.controller("baseController",function ($scope) {

    //定义搜索对象
    $scope.searchEntity={};
    //定义对象paginationConf,分布的配置
    $scope.paginationConf={
        currentPage: 1,//当前页
        totalItems: 10,//总记录条数
        itemsPerPage: 10,//每页的记录条数
        perPageOptions: [10,20,30,40,50],//页码选项,每页10条还是20还是...
        onChange: function () {//当页码发生变化时自动触发的方法
            $scope.reloadList();
        }
    }
    //重新加载记录
    $scope.reloadList=function () {
        $scope.search($scope.paginationConf.currentPage,$scope.paginationConf.itemsPerPage);
    }
    //批量选中
    $scope.selectIds=[];//选中的ID数组,准备批量删除的数据
    $scope.updateSelection=function($event,id){
        if($event.target.checked){//判断是否选中
            $scope.selectIds.push(id);//向数组中添加数据
        }else{
            var idx=$scope.selectIds.indexOf(id);//id在选中数据的数组中的位置
            $scope.selectIds.splice(idx,1);//从数组中删除数据,重复点复选框,选择和取消选择反复横跳
        }
    }

})

brandController.js

//构建前端的控制层
//和页面打交道的代码写在控制层
app.controller("brandController",function ($scope,$controller,brandService) {

    //把baseController的$scope传递给brandController的$scope,伪继承
    $controller("baseController",{$scope:$scope});
    //读取列表数据绑定到表单中
    $scope.findAll=function () {
        brandService.findAll().success(function(response){
            $scope.list=response;
        })
    }
    //条件查询+分页
    $scope.search=function(page,rows){
        brandService.search(page,rows,$scope.searchEntity).success(function (response) {
            $scope.list=response.rows;//给列表变量赋值
            $scope.paginationConf.totalItems=response.total;//定义总记录数
        })
    }
    //分页
    $scope.findPage=function(page,rows) {
        brandService.findPage(page,rows).success(function(response){
            $scope.list=response.rows;
            $scope.paginationConf.totalItems=response.total;//定义总记录数
        })

    }
    //保存(新增和修改)
    $scope.save=function () {
        var object=null;
        //新增时,id为空;但修改时,id不为空
        if($scope.entity.id!=null){
            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;
        })
    }
    //删除
    $scope.dele=function () {
        brandService.dele($scope.selectIds).success(function (response) {
            if(response.success){
                $scope.reloadList();//刷新列表
                $scope.selectIds=[];
            }else{
                alert(response.message);//打印信息
            }
        })
    }
})

规格管理(深入理解和使用双向绑定)

代码较散,前后端不断切换写代码,调试
Java大型电商项目——品优购(一)_第17张图片


第四部分

模板管理

Java大型电商项目——品优购(一)_第18张图片

一、品牌下拉列表(使用select2实现下拉列表功能

写代码的思路、逻辑、顺序基本如下

Java大型电商项目——品优购(一)_第19张图片

后端

TbBrandMapper.xml
  
TbBrandMapper
    /**
     * 下拉列表数据
     * @return
     */
    List selectOptionList();
 BrandService
    public List selectOptionList();
BrandServiceImpl
    @Override
    public List selectOptionList() {
        return brandMapper.selectOptionList();
    }
 BrandController
    @RequestMapping("/selectOptionList")
    public List selectOptionList(){
        return brandService.selectOptionList();
    }

运行结果:

 前端

 brandService.js
    this.selectOptionList=function () {
        return $http.get("../brand/selectOptionList.do")
    }
typeTemplateController.js 
 //控制层 
app.controller('typeTemplateController' ,function($scope,$controller,typeTemplateService,brandService,specificationService){
	$controller('baseController',{$scope:$scope});//继承
	//搜索
	$scope.search=function(page,rows){			
		typeTemplateService.search(page,rows,$scope.searchEntity).success(
			function(response){
				$scope.list=response.rows;	
				$scope.paginationConf.totalItems=response.total;//更新总记录数
			}			
		);
	}

	$scope.brandList={data:[]};//品牌列表
    
	//查询品牌列表
	$scope.findBrandList=function(){
		brandService.selectOptionList().success(
			function(response){
				$scope.brandList={data:response};
			}
		);		
	}	
});	
typeTemplate.html




	
	
	
	
	
	
	

	
	
	

	
	



  
                    
{{entity.id}} {{entity.name}} {{entity.brandIds}} {{entity.specIds}} {{entity.customAttributeItems}}

运行结果:

Java大型电商项目——品优购(一)_第20张图片

规格下拉列表(同上)

注意事项:

typeTemplate.html文件里的ng-init必须带上findAll()方法,用浏览器访问时才会正常显示表格


Java大型电商项目——品优购(一)_第21张图片

Java大型电商项目——品优购(一)_第22张图片

二、扩展属性(增加、删除行)

typeTemplateController.js

	//增加扩展属性行
	$scope.addTableRow=function(){
		$scope.entity.customAttributeItems.push({});
	}
	//删除扩展属性行
	$scope.deleTableRow=function(index){
		$scope.entity.customAttributeItems.splice(index,1);
	}

typeTemplate.html




  
                    

 运行结果:

Java大型电商项目——品优购(一)_第23张图片

三、新增模板

typeTemplate.html

1、绑定文本框

							
								
									
									
									
								
							

2、保存按钮

		

 运行结果:

Java大型电商项目——品优购(一)_第24张图片

四、修改模板

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);//自定义属性
				// JSON.parse(string): 将字符串转成对象
				// JSON.stringify(object): 将对象转成字符串
			}
		);				
	}

typeTemplate.html

修改按钮

		                                  
		                                 	  
		                                  

运行结果:Java大型电商项目——品优购(一)_第25张图片 

 五、删除模板

typeTemplate.html

1、复选框勾选

		                          
			                              
				                          {{entity.id}}
									      {{entity.name}}
									      {{entity.brandIds}}
									      {{entity.specIds}}
									      {{entity.customAttributeItems}}
		                                  
		                                 	  
		                                  
			                          

2、删除按钮

                                    

 运行结果:

Java大型电商项目——品优购(一)_第26张图片

六、优化页面

baseController.js

    //提取json字符串数据中某个属性,返回拼接字符串,逗号分隔
    // 让浏览器访问的html文件上的数据更通俗易懂
    $scope.jsonToString=function (jsonString,key) {

        var json=JSON.parse(jsonString);
        var value="";
        for(var i=0;i0){//第一个值前面不用加逗号分隔
                value+=",";//使用逗号分隔
            }
            value+=json[i][key];//key是json[i]的某个属性
        }
        return value;
    }

typeTemplate.html

			                      
			                          
			                              
				                          {{entity.id}}
									      {{entity.name}}
									      {{ jsonToString(entity.brandIds,"text") }}
									      {{ jsonToString(entity.specIds,"text") }}
									      {{ jsonToString(entity.customAttributeItems,"text") }}
		                                  
		                                 	  
		                                  
			                          
			                      

优化前:

Java大型电商项目——品优购(一)_第27张图片

 优化后:

Java大型电商项目——品优购(一)_第28张图片

经常出现的问题:

        如果出现更改了前端代码,前端代码没有问题,但前端页面显示不正常(一般是规定的数据不显示),就清除一下浏览器的数据(另外去百度),再刷新一下页面

 商品分类

一、商品列表

后端

ItemCatService
	public List findByParentId(Long parentId);
ItemCatServiceImpl
	@Override
	public List findByParentId(Long parentId) {
		TbItemCatExample example = new TbItemCatExample();
		TbItemCatExample.Criteria criteria = example.createCriteria();
		criteria.andParentIdEqualTo(parentId);
		return tbItemCatMapper.selectByExample(example);
	}
ItemCatController
	/**
	 * 根据上级ID查询商品分类
	 * @param parentId
	 * @return
	 */
	@RequestMapping("/findByParentId")
	public List findByParentId(Long parentId){
		return itemCatService.findByParentId(parentId);
	}

运行结果:

Java大型电商项目——品优购(一)_第29张图片

前端

itemCatService.js
	//根据上级ID查询列表
	this.findByParentId=function (parentId) {
		return $http.get('../itemCat/findByParentId.do?parentId='+parentId);
	}
itemCatController.js
	//根据上级ID查询列表
	$scope.findByParentId=function (parentId) {
		itemCatService.findByParentId(parentId).success(
			function (response) {
				$scope.list=response;
			}
		);
	}
item_cat.html




	
	
	
	
	



                                    
			                          
			                              			                              
				                          {{entity.id}}
									      {{entity.name}}
									      {{entity.typeId}}
		                                  		                                     
		                                      
		                                 	                                             
		                                  
			                          
			                      

 运行结果:

Java大型电商项目——品优购(一)_第30张图片

二、面包屑导航(Breadcrumb Navigation)

面包屑导航(Breadcrumb Navigation)这个概念来自童话故事“汉赛尔和格莱特”,当汉赛尔和格莱特穿过森林时,不小心迷路了,但是他们发现沿途走过的地方都撒下了面包屑,让这些面包屑来帮助他们找到回家的路。 

itemCatController.js

	//定义面包屑
	$scope.breadcrumb=[{id:0,name:"顶级分类列表"}];
	$scope.search=function (id,name) {
		//添加面包屑
		$scope.breadcrumb.push({id:id,name:name});
		$scope.findByParentId(id);
	}
	$scope.showList=function (index,id) {
		//截断面包屑
		//index+1: 表示从当前索引的后一个索引开始截断(从面包屑中去除)
		//2: 表示截断的个数,在此最大是3级,所以写2,写100也没关系
		$scope.breadcrumb.splice(index+1,2);
		$scope.findByParentId(id);
	}

item_cat.html

1、查询下级按钮


2、绑定面包屑

                      	    

 运行结果:

Java大型电商项目——品优购(一)_第31张图片

三、新增商品分类

在哪一级新增商品分类,那新增数据就应该显示在哪一级,而不是全部显示在顶级。

关键在于查询时记录下当前级parentId

itemCatController.js

	
	//保存 
	$scope.save=function(){				
		var serviceObject;//服务层对象  				
		if($scope.entity.id!=null){//如果有ID
			serviceObject=itemCatService.update( $scope.entity ); //修改  
		}else{
			serviceObject=itemCatService.add( $scope.entity  );//增加 
		}				
		serviceObject.success(
			function(response){
				if(response.success){
					//重新查询
		        	$scope.findByParentId($scope.entity.parentId);
				}else{
					alert(response.message);
				}
			}		
		);				
	}
	
	$scope.searchEntity={};//定义搜索对象
	//定义变量parentId,记录本级的ID
	//entity是表单所绑定的实体
	// $socpe.entity={parentId:0};

	//根据上级ID查询列表
	$scope.findByParentId=function (parentId) {
		//查询时记录上级ID
		$scope.entity={parentId:parentId};
		itemCatService.findByParentId(parentId).success(
			function (response) {
				$scope.list=response;
			}
		);
	}

item_cat.html


		

注意:

itemCatController.js文件去除了  $socpe.entity={parentId:0}; 这句给parentId赋初值的语句,因为parentId后续在function函数中再次被修改,这两个操作会发生冲突,导致前端引用$scope.entity对象时出错,如果要修改,最好使用深拷贝,而非直接赋值

 运行结果:

Java大型电商项目——品优购(一)_第32张图片

四、模板下拉列表

itemCatController.js

	//查询模板列表 (下拉框显示模板)
	$scope.findTypeTemplateList=function () {
		typeTemplateService.findAll().success(function (response) {
			$scope.typeTemplateList=response;//模板列表
		})
	}

item_cat.html

      	        
		      		类型模板
		      		
						
		      		
		      		

运行结果:

Java大型电商项目——品优购(一)_第33张图片

五、修改商品分类

item_cat.html

 

六、删除商品分类

itemCatServiceImpl

	/**
	 * 批量删除
	 */
	@Override
	public void delete(Long[] ids) {
		for(Long id:ids){
			List list=findByParentId(id);
			if(list.size()>0){//要删除的商品有下级商品分类,抛出运行时异常
				throw new RuntimeException("不能删除有下级分类的商品分类!");
			}else{
				//删除
				tbItemCatMapper.deleteByPrimaryKey(id);
			}

		}
	}

itemCatController

	@RequestMapping("/delete")
	public Result delete(Long [] ids){
		try {
			itemCatService.delete(ids);
			return new Result(true, "删除成功"); 
		} catch(RuntimeException e){//把抛出的运行时异常信息打印出来
			e.printStackTrace();
			return new Result(false,e.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
			return new Result(false, "删除失败");
		}
	}

itemCatController.js

	//批量删除 
	$scope.dele=function(){			
		//获取选中的复选框			
		itemCatService.dele( $scope.selectIds ).success(
			function(response){
				if(response.success) {
					$scope.findByParentId($scope.entity.parentId);
					$scope.selectIds = [];
				}else{
					alert(response.message);//把异常信息显示在前端页面
				}
			}		
		);				
	}

item_cat.html

1、复选框,实现多选


2、删除按钮


Java大型电商项目——品优购(一)_第34张图片

 七、显示模板名称

itemCatController.js

//定义一个变量
	$scope.typeTemplateMap=[];
	//查询模板列表 (下拉框显示模板)
	$scope.findTypeTemplateList=function () {
		typeTemplateService.findAll().success(function (response) {
			$scope.typeTemplateList=response;//模板列表

			//构建模板数据,用于列表显示名称
			for(var i=0;i<$scope.typeTemplateList.length;i++){
				//得到一个对象
				var typeTemplate=$scope.typeTemplateList[i];
				//把对象的id值修改成name
				$scope.typeTemplateMap[typeTemplate.id]=typeTemplate.name;
			}
		})
	}

item_cat.html

                                    
										  
			                              
				                          {{entity.id}}
									      {{entity.name}}
									      {{typeTemplateMap[entity.typeId]}}
		                                  		                                     
		                                      
		                                 	  
		                                  
			                          

 运行结果:

Java大型电商项目——品优购(一)_第35张图片

你可能感兴趣的:(java项目,java,开发语言)