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運行狀態,是否開啟了
    • 每次重啟虛擬機,ip地址會發生變化,所以把虛擬機掛起就行,不用關機
    • 查看ip地址的命令:ifconfig
    • 如果ip地址變化,則相應地修改springmvc.xml文件里的zookeeper信息。2181是zookeeper的默認端口,如果配置文件里沒有改動,就不變
    • 后續寫代碼時,在瀏覽器訪問html文件時,不報錯,但就是不顯示表格,除了表格什么都正常,很難排錯。后來發現是zookeeper的端口發生了變化,但是代碼里沒有修改過來。

2、mysql數據庫

  • mysql如何導入.sql文件:http://t.csdnimg.cn/mhP9M
  • 保持打開狀態,才可運行其他代碼

后端:在IDEA上搭建工程

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

  • ? ? ? ? ? ? ? ?

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映射文件的生成位置
              <!-- targetProject:mapper映射文件生成的位置 --><sqlMapGenerator targetPackage="com.pinyougou.mapper" targetProject=".\src\main\resources"><!-- enableSubPackages:是否讓schema作為包的后綴 --><property name="enableSubPackages" value="false" /></sqlMapGenerator>
    • 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
  • 錯誤一:
    • 解決辦法: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,真正修改完數據庫文件后,再運行
    •  
  • 測試成功后
  • 測試這里出了很多錯,無奈之下,把項目又重新做了一遍,發現父工程的依賴無法爆紅,無法正常導入;逆向工程代碼出錯了;zookeeper的ip地址也有變化;數據庫的相關配置也沒有修改完全,修改后又沒有更新到數據庫配置文件里……想過很多次放棄,但也沒有更好的選擇,所以還是堅持下來了,最大的收獲還是可以靜下心來好好分析報錯信息了。

前端:框架AngularJS

  • 四大特性

    • 1、MVC模式
    • 2、雙向綁定
    • 3、依賴注入
    • 4、模塊化設計
  • 基本內容

    • 表達式
      <html>
      <head><title>angularJS demo 表達式</title><script src="angular.min.js"></script>
      </head>
      <body ng-app>
      {{100+100}}
      </body>
      </html>
    • 雙向綁定
      <html>
      <head><title>angularJS demo 雙向綁定</title><script src="angular.min.js"></script>
      </head>
      <body ng-app>
      請輸入你的名稱:<input ng-model="myname">
      {{myname}},你好
      </body>
      </html>
    • 初始化指令
      <html>
      <head><title>angularJS demo 初始化指令</title><script src="angular.min.js"></script>
      </head>
      <body ng-app ng-init="myname='abc'">
      請輸入你的名稱:<input ng-model="myname">
      {{myname}},你好
      </body>
      </html>
    • 控制器
      <html>
      <head><title>angularJS demo 控制器</title><script src="angular.min.js"></script><script>// 定義一個名為myApp的模塊,下面的<body>塊內的代碼都屬于該模塊var app=angular.module("myApp",[]);// 定義控制器,可以控制頁面的某個功能// $scope在視圖和控制器之間建立了一個通道,雙向更新app.controller("myController",function($scope){$scope.add=function(){//parseInt把字符串類型轉換成數值類型return parseInt($scope.x)+parseInt($scope.y);}});</script>
      </head>
      <body ng-app="myApp" ng-controller="myController">
      <!--輸入綁定變量x-->
      x:<input ng-model="x">
      <!--輸入綁定變量y-->
      y:<input ng-model="y">
      <!--在頁面顯示x+y的結果add-->
      {{add()}}
      </body>
      </html>
    • 事件指令
      <html>
      <head><title>angularJS demo 事件指令</title><script src="angular.min.js"></script><script>var app=angular.module("myApp",[]);app.controller("myController",function($scope){$scope.add=function(){$scope.z=parseInt($scope.x)+parseInt($scope.y);}});</script>
      </head>
      <body ng-app="myApp" ng-controller="myController">
      x:<input ng-model="x">
      y:<input ng-model="y">
      <!--點擊“運算”按鈕后,觸發add()方法,輸出x+y的結果-->
      <button ng-click="add()">運算</button>
      {{z}}
      </body>
      </html>
    • 循環數組
      <html>
      <head><title>angularJS demo 循環數組</title><script src="angular.min.js"></script><script>var app=angular.module("myApp",[]);app.controller("myController",function($scope){$scope.list=[100,200,300,400];});</script>
      </head>
      <body ng-app="myApp" ng-controller="myController">
      <!--    利用循環把list里的元素打印到表格中--><table><tr ng-repeat="x in list"><td>{{x}}</td></tr></table>
      </body>
      </html>
    • 循環對象數組
      <html>
      <head><title>angularJS demo 循環對象數組</title><script src="angular.min.js"></script><script>var app=angular.module("myApp",[]);app.controller("myController",function($scope){$scope.list=[{name:"張三",chinese:1,math:1},{name:"李四",chinese:2,math:2},{name:"王五",chinese:3,math:3},{name:"趙六",chinese:4,math:4}];});</script>
      </head>
      <body ng-app="myApp" ng-controller="myController"><table><tr ng-repeat="x in list"><td>{{x.name}}</td><td>{{x.chinese}}</td><td>{{x.math}}</td></tr></table>
      </body>
      </html>
    • 內置服務
      <html>
      <head><title>angularJS demo 內置服務</title><meta charset="utf-8"><script src="angular.min.js"></script><script>var app=angular.module("myApp",[]);// $http從后端獲取數據,數據修改更靈活app.controller("myController",function($scope,$http){$scope.findList=function(){$http.get("data.json").success(function(response){$scope.list=response;});}});</script>
      </head>
      <!--初始化時,順便觸發findList()方法-->
      <body ng-app="myApp" ng-controller="myController" ng-init="findList()"><table><tr ng-repeat="x in list"><td>{{x.name}}</td><td>{{x.chinese}}</td><td>{{x.math}}</td></tr></table>
      </body>
      </html>
      //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*/@Overridepublic PageResult findPage(int pageNum, int pageSize) {PageHelper.startPage(pageNum,pageSize);//分頁插件Page<TbBrand> page=(Page<TbBrand>)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后,運行結果:

2、前端?

<!DOCTYPE html>
<html>
<head><!--導入資源--><script src="../plugins/jQuery/jquery-2.2.3.min.js"></script><script src="../plugins/bootstrap/js/bootstrap.min.js"></script><script src="../plugins/angularjs/angular.min.js"></script><!--分頁組件開始--><script src="../plugins/angularjs/pagination.js"></script><link rel="stylesheet" href="../plugins/angularjs/pagination.css"><!--分頁組件結束--><script>//定義名為app的模塊var app=angular.module("pinyougou",["pagination"]);app.controller("brandController",function ($scope,$http) {//讀取列表數據綁定到表單中// $scope.findAll=function () {// 	$http.get("../brand/findAll.do").success(function(response){// 		$scope.list=response;// 	})//// }//分頁$scope.findPage=function(page,rows) {$http.get("../brand/findPage.do?page="+page+"&rows="+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.findPage($scope.paginationConf.currentPage,$scope.paginationConf.itemsPerPage);}})</script></head>
<body class="hold-transition skin-red sidebar-mini" ng-app="pinyougou" ng-controller="brandController" ng-init="findAll()"><!-- .box-body --><!-- 數據表格 --><div class="table-box"><!--數據列表--><table id="dataList" class="table table-bordered table-striped table-hover dataTable"><!--表體--><tbody><!--使用循環填寫表格--><tr ng-repeat="entity in list"><td><input  type="checkbox" ></td>			                              <td>{{entity.id}}</td><td>{{entity.name}}</td><td>{{entity.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></table><!--數據列表/--><!--在數據表格下放置分頁組件,那個分頁的小欄--><tm-pagination conf="paginationConf"></tm-pagination>	 </div><!-- 數據表格 /-->                                    </div>
</body>
</html>

運行結果:

增加品牌

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*/@Overridepublic 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、前端

<!DOCTYPE html>
<html>
<head><script>//定義名為app的模塊var app=angular.module("pinyougou",["pagination"]);app.controller("brandController",function ($scope,$http) {//增加品牌$scope.add=function () {$http.post("../brand/add.do",$scope.entity).success(function(response){if(response.success){$scope.reloadList();//刷新數據}else{alert(response.message);//打印信息}})}})</script></head>
<body class="hold-transition skin-red sidebar-mini" ng-app="pinyougou" ng-controller="brandController" ng-init="findAll()"><!-- .box-body --><div class="box-body"><!-- 數據表格 --><div class="table-box"><!--工具欄--><div class="pull-left"><div class="form-group form-inline"><div class="btn-group"><!--添加的ng-click可以讓每次打開新建的窗口里,都保持空白頁面--><button type="button" class="btn btn-default" title="新建" ng-click="entity={}" data-toggle="modal" data-target="#editModal" ><i class="fa fa-file-o"></i> 新建</button></div></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="sorting_asc">品牌ID</th><th class="sorting">品牌名稱</th>									      <th class="sorting">品牌首字母</th>									     				<th class="text-center">操作</th></tr></thead></table>					 </div><!-- 數據表格 /--> </div><!-- /.box-body --><!-- 編輯窗口 -->
<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-body">		<table class="table table-bordered table-striped"  width="800px"><tr><td>品牌名稱</td><!--此處的ng-model是將屬性name和品牌名稱綁定,獲取到品牌名稱后,綁定后name屬性中--><td><input  class="form-control" ng-model="entity.name" placeholder="品牌名稱" >  </td></tr>		      	<tr><td>首字母</td><td><input  class="form-control" ng-model="entity.firstChar" placeholder="首字母">  </td></tr>		      	</table>				</div><div class="modal-footer">	<!--此處的ng-click是為了在點擊保存時,觸發add()方法-->					<button class="btn btn-success" data-dismiss="modal" ng-click="add()" aria-hidden="true">保存</button></div></div></div>
</div></body>
</html>

運行結果:

修改品牌

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查詢@Overridepublic TbBrand findOne(Long id) {return brandMapper.selectByPrimaryKey(id);}//修改@Overridepublic 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、前端

<!DOCTYPE html>
<html>
<head><script>//定義名為app的模塊var app=angular.module("pinyougou",["pagination"]);app.controller("brandController",function ($scope,$http) {//保存(新增和修改)$scope.save=function () {var methodName="add";//新增時,id為空;但修改時,id不為空if($scope.entity.id!=null){methodName="update";}$http.post("../brand/"+methodName+".do",$scope.entity).success(function(response){if(response.success){$scope.reloadList();//刷新數據}else{alert(response.message);//打印信息}})}//根據ID查詢$scope.findOne=function(id){$http.get("../brand/findOne.do?id="+id).success(function (response) {$scope.entity=response;})}})</script></head>
<body class="hold-transition skin-red sidebar-mini" ng-app="pinyougou" ng-controller="brandController" ng-init="findAll()"><!-- .box-body --><div class="box-body"><!-- 數據表格 --><div class="table-box"><!--數據列表--><table id="dataList" class="table table-bordered table-striped table-hover dataTable"><!--表體--><tbody><!--使用循環填寫表格--><tr ng-repeat="entity in list"><td><input  type="checkbox" ></td><!--此處要加雙花括號,是因為entity.id是表達式--><td>{{entity.id}}</td><td>{{entity.name}}</td><td>{{entity.firstChar}}</td><td class="text-center"><!--此處的findOne()里entity.id不用雙括號是因為在這里它是變量--><button type="button" class="btn bg-olive btn-xs" data-toggle="modal" ng-click="findOne(entity.id)" data-target="#editModal"  >修改</button></td></tr></tbody></table>			 </div><!-- 數據表格 /--></div><!-- /.box-body --><!-- 編輯窗口 -->
<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-footer">						<button class="btn btn-success" data-dismiss="modal" ng-click="save()" aria-hidden="true">保存</button></div></div></div>
</div> 
</body>
</html>

運行結果:

刪除品牌

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 {//刪除@Overridepublic 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,"刪除失敗🙃");}}
}

運行結果:

2、前端

<!DOCTYPE html>
<html>
<head><script>//定義名為app的模塊var app=angular.module("pinyougou",["pagination"]);app.controller("brandController",function ($scope,$http) {//批量選中$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 () {$http.get("../brand/delete.do?ids="+$scope.selectIds).success(function (response) {if(response.success){$scope.reloadList();//刷新列表$scope.selectIds=[];}else{alert(response.message);//打印信息}})}})</script>    
</head>
<body class="hold-transition skin-red sidebar-mini" ng-app="pinyougou" ng-controller="brandController" ng-init="findAll()"><!-- .box-body --><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="刪除" ng-click="dele()"><i class="fa fa-trash-o"></i> 刪除</button>                                    </div></div></div><!--工具欄/--><!--在數據表格下放置分頁組件,那個分頁的小欄--><tm-pagination conf="paginationConf"></tm-pagination>{{selectIds}}							 </div><!-- 數據表格 /-->             </div><!-- /.box-body -->
</body>
</html>

條件查詢

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 {//條件查詢@Overridepublic 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<TbBrand> page=(Page<TbBrand>)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、前端

<!DOCTYPE html>
<html>
<head><script>//定義名為app的模塊var app=angular.module("pinyougou",["pagination"]);app.controller("brandController",function ($scope,$http) {//定義搜索對象$scope.searchEntity={};//條件查詢+分頁$scope.search=function(page,rows){$http.post("../brand/search.do?page="+page+"&rows="+rows,$scope.searchEntity).success(function (response) {$scope.list=response.rows;//給列表變量賦值$scope.paginationConf.totalItems=response.total;//定義總記錄數})}//重新加載記錄$scope.reloadList=function () {$scope.search($scope.paginationConf.currentPage,$scope.paginationConf.itemsPerPage);}})</script></head>
<body class="hold-transition skin-red sidebar-mini" ng-app="pinyougou" ng-controller="brandController" ng-init="findAll()"><!-- .box-body --><div class="box-body"><!-- 數據表格 --><div class="table-box"><!--工具欄--><div class="box-tools pull-right"><div class="has-feedback">名稱: <input ng-model="searchEntity.name">首字母: <input ng-model="searchEntity.firstChar"><button ng-click="reloadList()">查詢</button></div></div><!--工具欄/-->						 </div><!-- 數據表格 /-->     </div><!-- /.box-body -->
</body>
</html>

運行結果:


第三部分(簡化開發)

前端分層開發(后端MVC的分層思想)

brand.html

<!DOCTYPE html>
<html>
<head><script src="../js/base_pagination.js"></script><script src="../js/service/brandService.js"></script><script src="../js/controller/brandController.js"></script>
</body>
</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);//打印信息}})}
})

?控制器繼承(提高代碼復用率)

brand.html

<!DOCTYPE html>
<html>
<head><script src="../js/controller/baseController.js"></script><script src="../js/controller/brandController.js"></script> 
</body>
</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);//打印信息}})}
})

規格管理(深入理解和使用雙向綁定)

代碼較散,前后端不斷切換寫代碼,調試


第四部分

模板管理

一、品牌下拉列表(使用select2實現下拉列表功能

寫代碼的思路、邏輯、順序基本如下

后端

TbBrandMapper.xml
  <select id="selectOptionList" resultType="java.util.Map">select id,name as text from tb_brand</select>
TbBrandMapper
    /*** 下拉列表數據* @return*/List<Map> selectOptionList();
?BrandService
    public List<Map> selectOptionList();
BrandServiceImpl
    @Overridepublic List<Map> selectOptionList() {return brandMapper.selectOptionList();}
?BrandController
    @RequestMapping("/selectOptionList")public List<Map> 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
<!DOCTYPE html>
<html><head><script src="../plugins/angularjs/angular.min.js"></script><!--分頁組件開始--><script src="../plugins/angularjs/pagination.js"></script><link rel="stylesheet" href="../plugins/angularjs/pagination.css"><!--分頁組件結束--><script src="../js/base_pagination.js"></script><script src="../js/angular-select2.js"></script><script src="../js/service/typeTemplateService.js"></script><script src="../js/service/brandService.js"></script><script src="../js/service/specificationService.js"></script><script src="../js/controller/baseController.js"></script><script src="../js/controller/typeTemplateController.js"></script>
</head><body class="hold-transition skin-red sidebar-mini" ng-app="pinyougou" ng-controller="typeTemplateController" ng-init="findAll();findBrandList()"><!-- .box-body --><div class="box-body"><!--工具欄/--><!--數據列表--><table id="dataList" class="table table-bordered table-striped table-hover dataTable"><tbody><tr ng-repeat="entity in list"><td><input  type="checkbox"></td><td>{{entity.id}}</td><td>{{entity.name}}</td><td>{{entity.brandIds}}</td><td>{{entity.specIds}}</td><td>{{entity.customAttributeItems}}</td><td class="text-center"><button type="button" class="btn bg-olive btn-xs" data-toggle="modal" data-target="#editModal">修改</button></td></tr></tbody></table><!--數據列表/--><tm-pagination conf="paginationConf"></tm-pagination></div><!-- 數據表格 /-->                        </div><!-- /.box-body --><!-- 編輯窗口 -->
<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><!--multiple表示可多選config用于配置數據來源select2-model用于指定用戶選擇后提交的變量--><input select2 select2-model="entity.brandIds" config="brandList" multiple placeholder="支持多選" class="form-control" type="text"/></td></tr><tr></tr>	<tr><td>擴展屬性</td><td><div class="btn-group">                                                                    </div>         </td></tr>	</table>				</div></div></div>
</div></body></html>

運行結果:

規格下拉列表(同上)

注意事項:

typeTemplate.html文件里的ng-init必須帶上findAll()方法,用瀏覽器訪問時才會正常顯示表格

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

二、擴展屬性(增加、刪除行)

typeTemplateController.js

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

typeTemplate.html

<!DOCTYPE html>
<html>
<body class="hold-transition skin-red sidebar-mini" ng-app="pinyougou" ng-controller="typeTemplateController" ng-init="findAll();findBrandList();findSpecList()"><!-- .box-body --><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></div></div></div><!--工具欄/--></div><!-- 數據表格 /--></div><!-- /.box-body -->     
<!-- 編輯窗口 -->
<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><tr><td>關聯規格</td><td><input select2 select2-model="entity.specIds" config="specList" multiple placeholder="支持多選" class="form-control" type="text"/></td></tr>	<tr><td>擴展屬性</td><td><div class="btn-group"><button type="button" class="btn btn-default" title="新增擴展屬性" ng-click="addTableRow()"><i class="fa fa-file-o"></i> 新增擴展屬性</button></div><table class="table table-bordered table-striped"  width="800px"><tbody><tr ng-repeat="pojo in entity.customAttributeItems"><td><input type="checkbox" class="icheckbox_square-blue" ></td><td><input class="form-control" ng-model="pojo.text" 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></tbody></table>	</td></tr>	</table>				</div></div></div>
</div></body></html>

?運行結果:

三、新增模板

typeTemplate.html

1、綁定文本框

							<tbody><tr ng-repeat="pojo in entity.customAttributeItems"><td><input type="checkbox" class="icheckbox_square-blue" ></td><td><input class="form-control" ng-model="pojo.text" 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></tbody>

2、保存按鈕

		<div class="modal-footer">						<button class="btn btn-success" data-dismiss="modal" aria-hidden="true" ng-click="save()">保存</button></div>

?運行結果:

四、修改模板

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

修改按鈕

		                                  <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>

運行結果:?

?五、刪除模板

typeTemplate.html

1、復選框勾選

		                          <tr ng-repeat="entity in list"><td><input  type="checkbox" ng-click="updateSelection($event,entity.id)"></td><td>{{entity.id}}</td><td>{{entity.name}}</td><td>{{entity.brandIds}}</td><td>{{entity.specIds}}</td><td>{{entity.customAttributeItems}}</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>

2、刪除按鈕

                                    <div class="btn-group"><button type="button" class="btn btn-default" title="刪除" ng-click="dele()"><i class="fa fa-trash-o"></i> 刪除</button>                                  </div>

?運行結果:

六、優化頁面

baseController.js

    //提取json字符串數據中某個屬性,返回拼接字符串,逗號分隔// 讓瀏覽器訪問的html文件上的數據更通俗易懂$scope.jsonToString=function (jsonString,key) {var json=JSON.parse(jsonString);var value="";for(var i=0;i<json.length;i++){if(i>0){//第一個值前面不用加逗號分隔value+=",";//使用逗號分隔}value+=json[i][key];//key是json[i]的某個屬性}return value;}

typeTemplate.html

			                      <tbody><tr ng-repeat="entity in list"><td><input  type="checkbox" ng-click="updateSelection($event,entity.id)"></td><td>{{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>

優化前:

?優化后:

經常出現的問題:

????????如果出現更改了前端代碼,前端代碼沒有問題,但前端頁面顯示不正常(一般是規定的數據不顯示),就清除一下瀏覽器的數據(另外去百度),再刷新一下頁面

?商品分類

一、商品列表

后端

ItemCatService
	public List<TbItemCat> findByParentId(Long parentId);
ItemCatServiceImpl
	@Overridepublic List<TbItemCat> 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<TbItemCat> findByParentId(Long parentId){return itemCatService.findByParentId(parentId);}

運行結果:

前端

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
<!DOCTYPE html>
<html>
<head><script src="../plugins/angularjs/angular.min.js"></script><script src="../js/base.js"></script><script src="../js/service/itemCatService.js"></script><script src="../js/controller/baseController.js"></script><script src="../js/controller/itemCatController.js"></script>
</head>
<body class="hold-transition skin-red sidebar-mini" ng-app="pinyougou" ng-controller="itemCatController" ng-init="findAll();findByParentId()"><tbody><tr ng-repeat="entity in list"><td><input  type="checkbox" ></td>			                              <td>{{entity.id}}</td><td>{{entity.name}}</td><td>{{entity.typeId}}</td><td class="text-center">		                                     <button type="button" class="btn bg-olive btn-xs" ng-click="findByParentId(entity.id)">查詢下級</button><button type="button" class="btn bg-olive btn-xs" data-toggle="modal" data-target="#editModal" >修改</button>                                           </td></tr></tbody>
</body>

?運行結果:

二、面包屑導航(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、查詢下級按鈕

<button ng-if="breadcrumb.length<3" type="button" class="btn bg-olive btn-xs" ng-click="search(entity.id,entity.name)">查詢下級</button>

2、綁定面包屑

                      	    <ol class="breadcrumb"><!--綁定面包屑--><li ng-repeat="pojo in breadcrumb"><a href="#" ng-click="showList($index,pojo.id)">{{pojo.name}}</a></li></ol>

?運行結果:

三、新增商品分類

在哪一級新增商品分類,那新增數據就應該顯示在哪一級,而不是全部顯示在頂級。

關鍵在于查詢時記錄下當前級parentId

itemCatController.js

	//保存 $scope.save=function(){				var serviceObject;//服務層對象  				if($scope.entity.id!=null){//如果有IDserviceObject=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

<div class="modal-body">							<table class="table table-bordered table-striped"  width="800px"><tr><td>上級商品分類</td><td><!--綁定面包屑--><span ng-repeat="pojo in breadcrumb">{{pojo.name}}</span></td></tr><tr><td>商品分類名稱</td><td><input  ng-model="entity.name" class="form-control" placeholder="商品分類名稱" >  </td></tr>			  <tr><td>類型模板</td><td>	      		<input ng-model="entity.typeId" placeholder="商品類型模板" class="form-control" type="text"/></td>		      		      		</tr>		      	</table>				</div><div class="modal-footer">						<button class="btn btn-success" data-dismiss="modal" aria-hidden="true" ng-click="save()">保存</button></div>

注意:

itemCatController.js文件去除了??$socpe.entity={parentId:0}; 這句給parentId賦初值的語句,因為parentId后續在function函數中再次被修改,這兩個操作會發生沖突,導致前端引用$scope.entity對象時出錯,如果要修改,最好使用深拷貝,而非直接賦值

?運行結果:

四、模板下拉列表

itemCatController.js

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

item_cat.html

      	        <tr><td>類型模板</td><td><select ng-model="entity.typeId" ng-options="item.id as item.name for item in typeTemplateList"></select></td></tr>	

運行結果:

五、修改商品分類

item_cat.html

 <button type="button" class="btn bg-olive btn-xs" data-toggle="modal" data-target="#editModal" ng-click="findOne(entity.id)">修改</button>

六、刪除商品分類

itemCatServiceImpl

	/*** 批量刪除*/@Overridepublic void delete(Long[] ids) {for(Long id:ids){List<TbItemCat> 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、復選框,實現多選

<td><input  type="checkbox" ng-click="updateSelection($event,entity.id)"></td>

2、刪除按鈕

<button type="button" class="btn btn-default" title="刪除" ng-click="dele()"><i class="fa fa-trash-o" ></i> 刪除</button>

?七、顯示模板名稱

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

                                    <tr ng-repeat="entity in list"><!--ng-click是勾選復選框,實現多選--><td><input  type="checkbox" ng-click="updateSelection($event,entity.id)"></td><td>{{entity.id}}</td><td>{{entity.name}}</td><td>{{typeTemplateMap[entity.typeId]}}</td><td class="text-center">		                                     <button ng-if="breadcrumb.length<3" type="button" class="btn bg-olive btn-xs" ng-click="search(entity.id,entity.name)">查詢下級</button><button type="button" class="btn bg-olive btn-xs" data-toggle="modal" data-target="#editModal" ng-click="findOne(entity.id)">修改</button></td></tr>

?運行結果:

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/165735.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/165735.shtml
英文地址,請注明出處:http://en.pswp.cn/news/165735.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

多功能回饋式交流電子負載的應用

多功能回饋式交流電子負載是用于模擬和測試電源、電池等電子設備的負載工具。它具有多種應用&#xff0c;可以用于測試和評估各種類型的電源&#xff0c;包括直流電源和交流電源。它可以模擬各種負載條件&#xff0c;如恒定電流、恒定電壓和恒定功率&#xff0c;以驗證電源的性…

小葉子鋼琴智能陪練 助力打牢鋼琴基礎

孩子在練琴過程中&#xff0c;經常會出現錯音錯節奏&#xff0c;為了能夠幫助她更高效的練琴&#xff0c;最近開始使用智能鋼琴陪練工具——小葉子鋼琴智能陪練。 身邊也有很多朋友在用這款應用&#xff0c;它比較知名的功能就是三大練琴模式&#xff0c;也就是識譜模式、提升…

linux centos系統命令安裝

Zip unzip 命令安裝下載 centos 命令常用常用下載 https://rpmfind.net/linux/rpm2html/search.php?queryzip%28x86-64%29&submitSearch…&system&arch 在線安裝zip命令 Centos用yum安裝的話用下面的命令安裝 yum install -y unzip zipUbuntu的的系統可以用下…

java SpringCloud版本b2b2c鴻鵠云商平臺全套解決方案 小程序商城免費搭建

使用技術&#xff1a; Spring CloudSpring BootMybatis微服務服務監控可視化運營 B2B2C平臺&#xff1a; 平臺管理端(包含自營) 商家平臺端(多商戶入駐) PC買家端、手機wap/公眾號買家端 微服務&#xff08;30個通用微服務如&#xff1a;商品、訂單、購物車、個人中心、支…

Ubuntu20.04清理垃圾vscode緩存

使用VM虛擬機安裝了Ubuntu系統&#xff0c;主目錄空間越來越小&#xff0c;硬盤擴容之后很快又空間不足&#xff0c;甚至出現了開機卡黑屏的情況&#xff0c;這里記錄一下解決過程。 1 重新開機進入系統 狀態&#xff1a;卡到了開機黑屏狀態&#xff0c;左上角有一條小橫杠 原…

國外網站文章或網頁采集翻譯為中文

采集國外網站的文章或網頁數據&#xff08;例如英文&#xff0c;西班牙語&#xff0c;法語等&#xff09;&#xff0c;怎么快速批量翻譯為中文&#xff1f; 可以使用簡數采集器來實現&#xff0c;支持自動翻譯&#xff0c;同時翻譯為多種語言&#xff08;不僅中文&#xff09;…

Angular11 MSAL B2C登錄實例 (二)

前言 上文介紹了在app.module.ts里的配置&#xff0c;本文著重講解下在app-routing.module.ts和index.html里的設置。 步驟 在文件中主要需要添加以下代碼 app-routing.module.ts const initialNavigation (!BrowserUtils.isInIframe() && !BrowserUtils.isInPopup…

Linux實驗三:shell程序設計: shell基礎

實驗目的: 進一步鞏固shell程序設計語言基本語法&#xff0c;加深對所學知識理解。 實驗要求 1. 四種變量的使用 2. 配置環境變量 3. 元字符和正則表達式 4. 引號 1. 本地變量 $ var1"hello Linux" //定義本地變量var1 $ read var2 //定義本地變量vae…

Linux常用命令——blkid命令

在線Linux命令查詢工具 blkid 查看塊設備的文件系統類型、LABEL、UUID等信息 補充說明 在Linux下可以使用blkid命令對查詢設備上所采用文件系統類型進行查詢。blkid主要用來對系統的塊設備&#xff08;包括交換分區&#xff09;所使用的文件系統類型、LABEL、UUID等信息進行…

【linux】服務器CPU占用50%,top/htop/ps卻看不到異常進程?使用unhide可以查看!

問題描述 htop發現前32個核全被占滿了&#xff0c;但是卻找不到對應進程號 查殺 安裝unhide查看隱藏進程 apt-get install unhideunhide使用 unhide proc果然發現了隱藏進程 殺死隱藏進程 kill -9 [pid]這么多pid號&#xff0c;我這邊殺了其中一個&#xff0c;發現CPU…

華為 HUAWEI 網絡設備路由交換 基線安全加固操作

目錄 帳號管理 ELK-Huawei-01-01-01 登錄要求 ELK-Huawei-01-02-01 認證和授權 ELK-Huawei-01-03-01 日志配置 ELK-Huawei-02-01-01 通信協議 ELK-Huawei-03-01-01 設備其它安全要求 ELK-Huawei-04-01-01 帳號管理 ELK-Huawei-01-01-01 編號&#xff1a; ELK-Huawei-01-0…

本地websocket服務端暴露至公網訪問【cpolar內網穿透】

本地websocket服務端暴露至公網訪問【cpolar內網穿透】 文章目錄 本地websocket服務端暴露至公網訪問【cpolar內網穿透】1. Java 服務端demo環境2. 在pom文件引入第三包封裝的netty框架maven坐標3. 創建服務端,以接口模式調用,方便外部調用4. 啟動服務,出現以下信息表示啟動成功…

C++設計模式之工廠模式(中)——工廠模式

工廠模式 工廠模式介紹示例示例使用運行結果工廠模式與簡單工廠模式區別 工廠模式 工廠模式在簡單工廠模式的基礎之上進行了改進。當需要生產的產品種類增加&#xff0c;可以通過新增子類工廠來生產&#xff0c;沒有破壞程序設計原則中的開放封閉原則。 介紹 工廠模式先抽象…

1.2.1 C語言結構體初始化方法總結

文章目錄 結構體定義通用定義注冊事項結構體初始化方法一簡述示例方法二簡述示例方法三簡述示例方法四簡述示例方法五簡述示例結構體定義 通用定義 常用的結構體定義,有2種形式, 一種是關鍵字struct 結構體形式,如下

域控操作五:統一熄屏睡眠時間

直接看圖路徑&#xff0c;我只設置了熄屏&#xff0c;如果要睡眠就下面那個啟用設置時間

Pytorch中的Tensorboard常用API

SummaryWriter函數 這個函數用于創建一個tensorboard文件&#xff0c;其中常用參數有 log_dir&#xff1a;tensorboard文件的存放路徑。不設置log_dir默認會在當前程序所在的文件夾下創建個runs文件夾存儲flush_secs&#xff1a;表示寫入tensorboard文件的時間間隔comment&…

一文2000字使用JMeter進行接口測試教程!(建議收藏)

安裝 使用JMeter的前提需要安裝JDK&#xff0c;需要JDK1.7以上版本目前在用的是JMeter5.2版本&#xff0c;大家可自行下載解壓使用 運行 進入解壓路徑如E: \apache-jmeter-5.2\bin&#xff0c;雙擊jmeter.bat啟動運行 啟動后默認為英文版本&#xff0c;可通過Options – Cho…

IIC驅動OLED HAL庫+CubeMX

一.IIC傳輸數據的格式 1.寫操作 2.讀操作 3.IIC信號 二. IIC底層驅動 #define SCL_PIN GPIO_PIN_6 #define SDA_PIN GPIO_PIN_7#define SCL_PORT GPIOB #define SDA_PORT GPIOB/********************** 函數宏定義 **********************/ #d…

Navicat 技術指引 | 連接 GaussDB 主備版

Navicat Premium&#xff08;16.2.8 Windows版或以上&#xff09; 已支持對GaussDB 主備版的管理和開發功能。它不僅具備輕松、便捷的可視化數據查看和編輯功能&#xff0c;還提供強大的高階功能&#xff08;如模型、結構同步、協同合作、數據遷移等&#xff09;&#xff0c;這…

LangChain(0.0.339)官方文檔一:快速入門

LangChain官網、LangChain官方文檔 、langchain Github、langchain API文檔、llm-universe 文章目錄 一、LangChain簡介&#xff08;v0.0.338&#xff09;1.1 整體框架1.2 主要組件1.2.1 Model I/O1.2.2 Retrieval1.2.2.1 RAG1.2.2.2 Retrieval 1.2.3 Chain 1.3 其它組件1.3.1 …