介紹
前端的css框架用了bootstrap, 以及bootstrap的JS組件, 以及很好用的angular(angular大法好), 項目一共包含了7個靜態界面, 靜態界面的數據展示都使用了angularJS , 后端是基于java的spring, 容器為tomcat, 項目代碼分享到 https://pan.baidu.com/s/1qYGqI2w, 這個項目的優勢是, 所有的顯示都是在前端完成, 數據交互也是通過ajax完成, 沒有頻繁的頁面跳轉;先上兩張商城的主圖:
圖一:
、
圖2:
該頁面可以完成商品的評價, 添加商品, 商品的搜索等功能 , 界面JSP代碼:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <html> <head> <title>detail.html</title> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="this is my page"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" type="text/css" href="./css/bootstrap-3.2.0/dist/css/bootstrap.min.css"/> <script src="http://cdn.bootcss.com/jquery/2.1.3/jquery.min.js"></script> <script src="http://cdn.bootcss.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> <script src="http://cdn.bootcss.com/angular.js/1.3.15/angular.min.js"></script> <style> .commodity{ margin:10px; } .content{ margin:80px; } .commentBody{ max-heiht:200px; } </style> </head> <body ng-app="app"> <nav class="navbar navbar-default navbar-fixed-top"> <div class="container"> <div class="row"> <ul class="nav navbar-nav"> <li> <c:if test="${name!=null}"> <a href="###"> 歡迎${name} </a> </c:if> </li> <li> <a href="./index.do">首頁</a> </li> <li> <a href="./detail.do">分類頁</a> </li> <li> <a href="./cart.do"> 購物車 </a> </li> <li> <a href="./list.do"> 列表頁 </a> </li> <li><a href="./user.do">用戶</a></li> </ul> </div> </div> </nav> <div class="container content"> <div class="row"> <p> <span class="glyphicon glyphicon-cd" aria-hidden="true"></span> <input class="form-control" id="keyword" placeholder="輸入搜索關鍵詞"><br> <button id="search" class="btn btn-primary">搜索</button> </p> </div> <div id="groups" class="row" ng-controller="groups"> <div ng-repeat="coms in groups"> <h3> <span class="glyphicon glyphicon-fire" aria-hidden="true"></span> <span class="label label-default"> {{coms[0].type}} </span> </h3> <div class="panel panel-default pull-left commodity" ng-repeat="com in coms"> <div class="panel-heading panel-primary"> <p>{{com.name}}</p> </div> <div class="panel-body"> <p>產品介紹{{com.depict}}</p> <p>廠商{{com.manufacturer}}</p> <p>金額{{com.price}}</p> <p>產品圖片<img ng-src={{com.img}} width=50 height=50 /></p> <button class="btn btn-default" ng-click="addToCart(com.id)"> 添加到購物測 </button> <button class="btn btn-default" ng-click="showDetail(com)"> 查看詳細 </button> </div> </div> <div class="clearfix "></div> </div> </div> <div class="row"> <a href="./cart.do" class="btn btn-default" role="button">去結賬</a> </div> </div> <!-- Modal --start --> <div class="modal fade" id="detail" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" ng-controller="detail"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h4 class="modal-title" id="myModalLabel"> 產品信息 </h4> </div> <div class="modal-body"> <p>產品名字{{com.name}}</p> <p>產品描述{{com.depict}}</p> <p>產品公司{{com.manufacturer}}</p> <p>æ產品金額{{com.price}}</p> <p>產品縮略圖<img ng-src={{com.img}} width=50 height=50 /></p> <div class="commentBody"> <div ng-repeat="c in comments"> <span class="glyphicon glyphicon-user" aria-hidden="true"></span> {{c.userName}} <div class="alert" role="alert"> {{c.comment}} </div> </div> <form> <label for="text"></label> <input type="text" name="text" id="text" placehoder="評論內容" ng-model="comment"/> <button id="submit" class="btn btn-success" ng-click="appendComment(com.id)">評論</button> </form> </div> </div> </div> </div> </div> <!-- Modal ---end --> </body> <script> var userId = "${id}"; var app = angular.module("app", []); app.controller("groups", function( $scope ) { $scope.groups = {}; $scope.addToCart = function( comId ) { ajaxModule.addOrder(userId, comId); }; $scope.showDetail = function( com ) { $("#detail").modal('show'); $("#detail").scope().com = com; ajaxModule.getCommentById(com.id, function(res) { $("#detail").scope().comments = res; $("#detail").scope().$apply(); }); }; }); app.controller("detail",function($scope) { $scope.comments = []; //添加評論 $scope.appendComment = function( commodityID ) { if($scope.comment) { ajaxModule.addComment( commodityID, $scope.comment , function() { $scope.comments.push({ userName : "${name}", commment : $scope.comment }); $scope.$apply(); }); }; }; }); function updateIndex() { ajaxModule.getAllCom(function( res ) { var result = util.groupByType(res); $("#groups").scope().groups = result; $("#groups").scope().$apply(); }); }; function bind() { $("#search").click(function() { ajaxModule.search($("#keyword").val(), function(res) { var result = util.groupByType(res); $("#groups").scope().groups = result; $("#groups").scope().$apply(); }); }); }; /** *@desc */ var util = { /** *@desc *@return Object; */ groupByType : function( res ) { var obj = {}; for(var i=0; i<res.length; i++ ) { obj[res[i].type] = obj[res[i].type] || []; obj[res[i].type].push( res[i] ); }; return obj; } }; /** *@desc ajax */ var ajaxModule = { getAllCom : function(cb) { $.post("admin/getAllCom.do", cb); }, addOrder : function(userId, commodityIds ,cb) { $.post("addOrder.do",{userId:userId, commodityIds:commodityIds, commodityCounts:"1"}, function(res) { console.log("addOrder.do response is "+ res); if(res) { alert("添加成功"); }else{ alert("添加失敗"); }; }); }, search : function(keyword, cb) { $.post("search.do", {keyword:keyword}, cb); }, getCommentById : function(id, cb) { $.post("admin/getCommentById.do",{commodityId:id}, cb); }, addComment : function(commodityID, comment ,cb) { $.post("./addComment.do", {userId : '${id}', userName : '${name}',commodityID : commodityID, comment: comment}, function( res ) { if(res) { cb&&cb(); }else{ alert("評論添加失敗"); } }); } }; $(function() { updateIndex(); bind(); }); </script> </html>
主頁2:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <html> <head> <title>index</title> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="this is my page"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" type="text/css" href="./css/bootstrap-3.2.0/dist/css/bootstrap.min.css"/> <script src="http://cdn.bootcss.com/jquery/2.1.3/jquery.min.js"></script> <script src="http://cdn.bootcss.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> <script src="http://cdn.bootcss.com/angular.js/1.3.15/angular.min.js"></script> </head> <style> .com{ margin:20px; height:240px; overflow:hidden; } .padding20{ padding:20px; } #index{ margin-top:100px; } </style> <body ng-app="app"> <nav class="navbar navbar-default navbar-fixed-top"> <div class="container"> <div class="row"> <ul class="nav navbar-nav"> <li> <c:if test="${name!=null}"> <a href="###"> 歡迎${name} </a> </c:if> </li> <li> <a href="./index.do">首頁</a> </li> <li> <a href="./detail.do">類型頁</a> </li> <li> <a href="./cart.do"> 購物車 </a> </li> <li> <a href="./list.do"> 訂單頁 </a> </li> <li><a href="./user.do">用戶信息</a></li> </ul> </div> </div> </nav> <div class="container"> <div id="index" class="row" ng-controller="index"> <div class="panel panel-default"> <div class="panel-body"> <div class="thumbnail pull-left com" ng-repeat="com in coms"> <img ng-src="{{com.img}}" width="40" height="40"> <div class="caption"> <h3>{{com.name}}</h3> <p>{{com.depict}}</p> <p> <a href="#" class="btn btn-primary" role="button" ng-click="addToCart(com.id)">添加商品</a> </p> <p> <button class="btn btn-default" ng-click="showDetail(com)"> 查看詳細 </button> </p> </div> </div> </div> </div> </div> <div class="row"> <a href="./cart.do" class="btn btn-default" role="button">去購物車</a> </div> </div> </div> <!-- Modal --start --> <div class="modal fade" id="detail" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" ng-controller="detail"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h4 class="modal-title" id="myModalLabel"> 產品信息 </h4> </div> <div class="modal-body"> <p>產品名字{{com.name}}</p> <p>產品描述{{com.depict}}</p> <p>產品公司{{com.manufacturer}}</p> <p>æ產品金額{{com.price}}</p> <p>產品縮略圖<img ng-src={{com.img}} width=50 height=50 /></p> <div class="commentBody"> <div ng-repeat="c in comments"> <span class="glyphicon glyphicon-user" aria-hidden="true"></span> {{c.userName}} <div class="alert" role="alert"> {{c.comment}} </div> </div> <form> <label for="text"></label> <input type="text" name="text" id="text" placehoder="評論內容" ng-model="comment"/> <button id="submit" class="btn btn-success" ng-click="appendComment(com.id)">評論</button> </form> </div> </div> </div> </div> </div> <!-- Modal ---end --> <script> var userId = "${id}"; var app = angular.module("app", []); app.controller("index", function( $scope ) { $scope.coms = []; $scope.addToCart = function( comId ) { ajaxModule.addOrder(userId, comId); }; $scope.showDetail = function( com ) { $("#detail").modal('show'); $("#detail").scope().com = com; ajaxModule.getCommentById(com.id, function(res) { $("#detail").scope().comments = res; $("#detail").scope().$apply(); }); }; }); app.controller("detail",function($scope) { $scope.comments = []; //添加評論 $scope.appendComment = function( commodityID ) { if($scope.comment) { ajaxModule.addComment( commodityID, $scope.comment , function() { $scope.comments.push({ userName : "${name}", commment : $scope.comment }); $scope.$apply(); }); }; }; }); var ajaxModule = { getAllCom : function( cb ) { $.post("admin/getAllCom.do",cb); }, addOrder : function(userId, commodityIds ,cb) { $.post("addOrder.do",{userId:userId, commodityIds:commodityIds, commodityCounts:"1"}, function(res) { console.log("addOrder.do response is "+ res); if(res) { alert("添加成功"); }else{ alert("添加失敗"); }; }); }, getCommentById : function(id, cb) { $.post("admin/getCommentById.do",{commodityId:id}, cb); }, addComment : function(commodityID, comment ,cb) { $.post("./addComment.do", {userId : '${id}', userName : '${name}',commodityID : commodityID, comment: comment}, function( res ) { if(res) { cb&&cb(); }else{ alert("評論添加失敗"); } }); } }; function index() { ajaxModule.getAllCom(function( res ) { $("#index").scope().coms = res; $("#index").scope().$apply(); }); }; $(function() { index(); }); </script> </body> </html>
后臺管理界面, 這個界面只允許用戶role值為1用戶查看, 用戶角色是數據庫的用戶表關聯的, 也就是說是管理員的時候, 才能進入后臺頁編輯商品,編輯評論等高級功能:
界面代碼:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <html> <head> <title>admin.html</title> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="this is my page"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" type="text/css" href="../css/bootstrap-3.2.0/dist/css/bootstrap.min.css"/> <script src="http://cdn.bootcss.com/jquery/2.1.3/jquery.min.js"></script> <script src="http://cdn.bootcss.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> <script src="http://cdn.bootcss.com/angular.js/1.3.15/angular.min.js"></script> <style> .bs-example { position: relative; padding: 45px 15px 15px; margin: 0 -15px 15px; border-color: #E5E5E5 #EEE #EEE; border-style: solid; border-width: 1px 0; -webkit-box-shadow: inset 0 3px 6px rgba(0, 0, 0, 0.05); box-shadow: inset 0 3px 6px rgba(0, 0, 0, 0.05); } </style> </head> <body> <div class="container" ng-app="app"> <div class="row"> <h2> <a href="../index.do">首頁</a> </h2> </div> <div class="row"> <div class="bs-example bs-example-tabs" data-example-id="togglable-tabs"> <ul id="myTabs" class="nav nav-tabs" role="tablist"> <li role="presentation" class="active"> <a id="tab0" href="#orderform" id="home-tab" role="tab" data-toggle="tab" aria-controls="orderform" aria-expanded="true">所有訂單</a> </li> <li role="presentation"> <a id="tab1" href="#types" id="types-tab" role="tab" data-toggle="tab" aria-controls="types" aria-expanded="true">商品類型編輯</a> </li> <li role="presentation"> <a id="tab2" href="#pro" role="tab" id="pro-tab" data-toggle="tab" aria-controls="pro">商品編輯</a> </li> <li role="presentation"> <a id="tab3" href="#about" role="tab" id="about-tab" data-toggle="tab" aria-controls="about">所有評論</a> </li> </ul> <div id="myTabContent" class="tab-content"> <div role="tabpanel" class="tab-pane fade in active orderform" id="orderform" aria-labelledby="home-tab" ng-controller="orderform"> <table class="table table-hover table-bordered"> <thead> <tr> <th>訂單id</th> <th>地址</th> <th>總金額</th> <th>手機</th> <th>詳細信息</th> </tr> </thead> <tbody> <tr ng-repeat="item in orderforms"> <th scope="row">{{item.id}}</th> <td>{{item.address}}</td> <td>{{item.totalPrice}}</td> <td>{{item.phone}}</td> <th> <a ng-click="showInfo(item.orderlist)" href="###"> 查看訂單詳細信息 </a> </th> </tr> <tr> </tbody> </table> <div class="row"> <ul class="list-group"> <li class="list-group-item" ng-repeat="com in commoditys"> <p>第{{$index+1}}條: 商品id為{{com.commodityId}}, 的總數是為{{com.commodityCount}}</p> <div commodity-directive id="{{com.commodityId}}"> <p>商品名字{{res.name}}</p> <p>商品描述{{res.depict}}</p> <p>商品廠商{{res.manufacturer}}</p> <p>商品價格{{res.price}}</p> <p>商品logo<img ng-src={{res.img}} width=50 height=50/></p> </div> </li> </ul> </div> </div> <div role="tabpanel" class="tab-pane fade types" id="types" aria-labelledby="type-tab" ng-controller="types"> <div class="row"> <ul class="list-group"> <li class="list-group-item">類型</li> <li class="list-group-item" ng-repeat="type in types"> <div > <p> {{type.name}} <button class="btn btn-default pull-right" ng-click="delType( type.id )">刪除該類型</button> </p> </div> </li> </ul> </div> <div class="row"> <input placeholder="新類型名字" id="new_type" ng-model="new_type"> <button class="btn btn-default" ng-click="new_type_fn()">創建新類型</button> </div> </div> <div id="pro" role="tabpanel" class="tab-pane fade" id="pro" aria-labelledby="pro-tab" ng-controller="pros"> <br> <p> <button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal"> 創建新商品 </button> </p> <ul class="list-group"> <li class="list-group-item" ng-repeat="com in coms"> <p>商品名{{com.name}}</p> <p>商品描述{{com.depict}}</p> <p>商品公司{{com.manufacturer}}</p> <p>商品價格{{com.price}}</p> <p>商品logo<img ng-src={{com.img}} width=50 height=50 /></p> <p> <button class="btn btn-default" ng-click="removePro(com.id)"> 刪除該商品 </button> </p> </li> </ul> </div> <div role="tabpanel" class="comments tab-pane fade" id="about" aria-labelledby="about-tab" ng-controller="comments"> <ul class="list-group"> <li class="list-group-item" ng-repeat="comment in comments"> <p>評論列表:</p> <div commodity-directive id="{{comment.commodityId}}"> <p>商品名字{{res.name}}</p> <p>商品描述{{res.depict}}</p> </div> <div> <strong>{{comment.userName}} <b>說</b></strong> <span>{{comment.comment}}</span> </div> </li> </ul> </div> </div> </div> </div> <!-- Modal start --> <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h4 class="modal-title" id="myModalLabel">創建商品</h4> </div> <div class="modal-body"> <form> <div class="form-group"> <label for="name">name</label> <input type=text class="form-control" id="name" placeholder="商品名"> </div> <div class="form-group"> <label for="depict">depict</label> <input type=text class="form-control" id="depict" placeholder="商品描述"> </div> <div class="form-group"> <label for="price">price</label> <input type=text class="form-control" id="price" placeholder="商品價格"> </div> <div class="form-group"> <label for="amount">amount</label> <input type="text" class="form-control" id="amount" placeholder="商品個數"> </div> <div class="form-group"> <label for="manufacturer">manufacturer</label> <input type="text" class="form-control" id="manufacturer"" placeholder="商品廠商"> </div> <div class="form-group"> <label for="img">img</label> <input type="text" class="form-control" id="img" readonly=true placeholder="圖片路徑"> <input type="file" value=上傳文件 id="upload"> </div> <select id="select" ng-controller="select"> <option ng-repeat="type in types" value="{{type.name}}"> {{type.name}} </option> </select> </form> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> <button id="submit" type="button" class="btn btn-primary">Save changes</button> </div> </div> </div> </div> <!-- Modal end--> <script> var app = angular.module("app", []); app.directive("commodityDirective", function() { return { restrict : "EA", scope : true, link : function( $scope ,$el, $iattrs) { $.post("../getComById.do", {id:$iattrs.id},function( res ) { $scope.res = res[0]; $scope.$apply(); }); } } }); app.controller("orderform", function($scope) { $scope.orderforms = []; $scope.commoditys = []; $scope.showInfo = function( info ) { $scope.commoditys = JSON.parse(info); }; }); $("#tab0").click(function() { ajaxModule.getFormAllList(".orderform"); }); app.controller("types",function($scope) { $scope.types = []; $scope.new_type = ""; $scope.delType = function(id) { ajaxModule.delType(id, function(res) { if(res === true) { $("#tab1").click(); }else{ alert("刪除失敗"); }; }); }; $scope.new_type_fn = function() { ajaxModule.addType($scope.new_type, function(res) { if(res === true) { $("#tab1").click(); }else{ alert("創建失敗"); }; }); }; }); $("#tab1").click(function() { ajaxModule.getTypes(".types"); }); app.controller("pros", function($scope) { $scope.coms = []; $scope.removePro = function(id) { ajaxModule.delPro(id, function(res) { if(res) { $("#tab2").click(); }else{ alert("刪除成功"); }; }); }; }); app.controller("select", function($scope) { $scope.types = []; }) $("#tab2").click(function() { ajaxModule.getAllCom("#pro"); ajaxModule.getTypes("#select"); }); $("#submit").click(function() { ajaxModule.addPro({ name:$("#name").val(), depict:$("#depict").val(), price:$("#price").val(), amount:$("#amount").val(), manufacturer:$("#manufacturer").val(), img:$("#img").val(), type:$("#select").val() },function(res) { if(res) { $('#myModal').modal('hide'); $("#tab2").click(); }else{ alert("添加成功"); $('#myModal').modal('hide') }; }); }); app.controller("comments", function($scope) { $scope.comments = []; }); $("#tab3").click(function() { ajaxModule.getComments(function( res ) { $(".comments").scope().comments = res; $(".comments").scope().$apply(); }) }); $("#upload").change(function(ev) { formData = new FormData(); formData.append("name", ev.target.files[0]); var oReq = new XMLHttpRequest(); oReq.open("POST", "../upload.do"); oReq.onreadystatechange = function() { if( oReq.readyState === 4 ) { $("#img").val( oReq.responseText ); }; }; oReq.send(formData); }); $(function() { $("#tab0").click(); }); var ajaxModule = function() { return { getFormAllList : function( el ) { $.post("../getFormAllList.do", function(res) { $(el).scope().orderforms = res; $(el).scope().$apply(); }) }, getTypes : function(el) { $.post("getTypes.do", function(res) { $(el).scope().types = res; $(el).scope().$apply(); }) }, addType : function( type ,callback) { $.post("addType.do", {type:type}, function(res) { callback(res); }); }, delType : function( id ,callback) { $.post("delType.do", {id:id}, function(res) { callback(res); }); }, getAllCom : function(el) { $.post("./getAllCom.do", function( res ) { $(el).scope().coms = res; $(el).scope().$apply(); }); }, delPro : function(id ,callback) { $.post("./delPro.do",{id:id} , function( res ) { callback(res); }); }, addPro : function(json, callback) { $.post("./addPro.do",json, function(res) { callback(res); }); }, getComments : function( callback ) { $.post("./getComments.do", function(res) { callback(res); }); }, getCommentById : function( id, callback ) { $.post("./getCommentById.do",{commodityId:id}, callback); } }; }(); </script> </body> </html>
用戶信息管理界面, 默認查看當前用戶信息, 如果點擊編輯按鈕, 會切顯示一個編輯的DIV, 可以直接更改用戶的新信息然后提交, 如果是管理員的話, 會有一個后臺管理的入口按鈕:
查看:
編輯:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <html> <head> <title>user.html</title> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="this is my page"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" type="text/css" href="./css/bootstrap-3.2.0/dist/css/bootstrap.min.css"/> <script src="http://cdn.bootcss.com/jquery/2.1.3/jquery.min.js"></script> <script src="http://cdn.bootcss.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> <script src="http://cdn.bootcss.com/angular.js/1.3.15/angular.min.js"></script> </head> <body ng-app="app"> <div class="container"> <div class="row"> <ul class="nav navbar-nav"> <li> <c:if test="${name!=null}"> <a href="###"> 歡迎${name} </a> </c:if> </li> <li> <a href="./index.do">首頁</a> </li> <li> <a href="./detail.do">類型頁</a> </li> <li> <a href="./cart.do"> 購物車 </a> </li> <li> <a href="./list.do"> 訂單頁 </a> </li> </ul> </div> <div class="row"> <c:if test="${name==null}" > <a href="login.do">登錄</a> </c:if> <c:if test='${role==1}' > <a class="btn btn-default" href="admin/admin.do">進入管理界面</a> </c:if> </div> <br> <c:if test="${name!=null}" > <div id="user" class="row" ng-controller="user"> <button class="btn btn-success" ng-click="edit=!edit"> {{edit?"查看用戶信息":"更新用戶信息"}} </button> <br> <br> <div ng-show="!edit" ng-init="edit=false"> <p>用戶名:{{user.name}}</p> <p>默認收貨地址:{{user.defaultAddress}}</p> <p>默認手機:{{user.defaultAddress}}</p> <p>用戶郵箱:{{user.mail}}</p> </div> <div ng-show="edit"> <form> <div class="form-group"> <label for="name">用戶名</label> <input type="text" class="form-control" id="name" placeholder="name" ng-model="user.name" > </div> <div class="form-group"> <label for="password">密碼</label> <input type="text" class="form-control" id="password" placeholder="Password" ng-model="user.password" > </div> <div class="form-group"> <label for="defaultAddress">默認收貨地址</label> <input type="text" class="form-control" name="defaultAddress" id="defaultAddress" ng-model="user.defaultAddress" > </div> <div class="form-group"> <label for="defaultPhone">默認手機</label> <input type="text" class="form-control" name="defaultPhone" id="defaultPhone" ng-model="user.defaultPhone" > </div> <div class="form-group"> <label for="mail">用戶郵箱</label> <input type="text" class="form-control" name="mail" id="mail" ng-model="user.mail" > <div> 金額: {{user.money}}RMB </div> </div> <button id="submit" type="submit" class="btn btn-default">Submit</button> </form> </div> </div> </c:if> </div> <script> var userId = "${id}"; var app = angular.module("app", []); app.controller("user", function( $scope ) { //默認數據 $scope.user = { name : "name", password : "password", defaultAddress : "defaultAddress", defaultPhone : "defaultPhone", mail : "mail" }; }); $("#submit").click(function( ev ) { $.post("updateInfo.do", $.extend({},$("#user").scope().user,{userId:userId}), function( res ) { if( res ) { alert("更新成功!"); }else{ alert("更新失敗"); }; }); }); $(function() { if( userId ) { $.post("getInfo.do",{userId:userId},function( res ) { var scope = $("#user").scope(); scope.user = res; $("#user").scope().$apply() }); }; }); </script> </body> </html>
當用戶點擊界面的添加商品, 那么對應用戶的購物車數據會發生改變;
購物車顯示的是所有的選購商品, 在購物車里面也能隨意的增加或者減少商品的個數, 金額會根據商品的個數,實時更新, 非常方便, 點擊提交信息的話,那么這些購物車的商品就轉換為用戶的訂單, 訂單包含了收貨人的地址和收貨人手機號碼 (前端的手機驗證沒有弄):
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <html> <head> <title>cart.html</title> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="this is my page"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" type="text/css" href="./css/bootstrap-3.2.0/dist/css/bootstrap.min.css"/> <script src="http://cdn.bootcss.com/jquery/2.1.3/jquery.min.js"></script> <script src="http://cdn.bootcss.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> <script src="http://cdn.bootcss.com/angular.js/1.3.15/angular.min.js"></script> </head> <style> .commodity{ margin:10px; } #cart{ margin-top:100px; } </style> <body ng-app="app"> <nav class="navbar navbar-default navbar-fixed-top"> <div class="container"> <div class="row"> <ul class="nav navbar-nav"> <li> <c:if test="${name!=null}"> <a href="###"> 歡迎${name} </a> </c:if> </li> <li> <a href="./index.do">首頁</a> </li> <li> <a href="./detail.do">分類頁</a> </li> <li> <a href="./list.do"> 列表頁 </a> </li> <li><a href="./user.do"> 用戶信息 </a></li> </ul> </div> </div> </nav> <div class="container"> <div id="cart" class="row" ng-controller="cart"> <ul class="list-group"> <li class="list-group-item pull-left commodity" ng-repeat="order in list"> <p>商品</p> <div commodity-directive id="{{order.commodityId}}"> <p>商品名{{res.name}}</p> <p>商品描述{{res.depict}}</p> <p>商品廠商{{res.manufacturer}}</p> <p>商品價格{{res.price}}</p> <p>商品logoï<img ng-src={{res.img}} width=50 height=50/></p> <p> 購買商品個數 <span class="badge"> {{order.commodityCount}} </span> <p style="display:none">{{order.price=res.price}}</p> </p> <button class="btn btn-danger" ng-click="comCount(-1, order.commodityId)">少買一個</button> <button class="btn btn-warning" ng-click="comCount(1, order.commodityId)">再來一個</button> </div> </li> </ul> <div class="clearfix"> <p>總金額{{sum}}</p> </div> <input type="hidden" value="${id}" class="form-control" id="userId"> <br> <label class="clearfix"> 輸入用戶地址 <input type="text" class="form-control" id="address"> </label> <br> <label class="clearfix"> 輸入收貨人手機 <input type="number" class="form-control" id="phone"> </label> <br> <button id="submit" class="btn btn-success"> 提交信息 </button> </div> </div> <script> var userId = "${id}"; var app = angular.module("app", []); app.directive("commodityDirective", function() { return { restrict : "EA", scope : true, link : function( $scope ,$el, $iattrs) { $.post("./getComById.do", {id:$iattrs.id},function( res ) { $scope.res = res[0]; $scope.$apply(); }); } } }); app.controller("cart", function( $scope ) { var list = [];//[{"id":1,"userId":19,"commodityId":1,"commodityCount":1},{"id":2,"userId":19,"commodityId":2,"commodityCount":5},{"id":3,"userId":19,"commodityId":3,"commodityCount":2},{"id":4,"userId":19,"commodityId":5,"commodityCount":4},{"id":5,"userId":19,"commodityId":4,"commodityCount":3}] $scope.list = list; $scope.scope= 0; $scope.comCount = function( constant, commodityId) { $.each($scope.list, function(i, e) { if( e.commodityId == commodityId ) { $scope.list[i].commodityCount+=constant; }; if(e.commodityCount<=0) { e.commodityCount = 0; }; }); $scope.upDateSum(); }; $scope.upDateSum = function() { $scope.sum = util.calcSum( $scope.list ); }; }); var util = { calcSum : function( list ) { var sum = 0; $.each(list, function(i, e) { sum += (e.commodityCount*e.price); }); return sum; } }; if( userId ) { $.post("./getOrderList.do", {userId: userId }, function( res ) { $("#cart").scope().list = JSON.parse(res); setInterval(function() { $("#cart").scope().upDateSum(); $("#cart").scope().$apply(); },1000); }); }; $("#submit").click(function() { $.post("./addForm.do", { userId : $("#userId").val(), address : $("#address").val(), phone : $("#phone").val(), totalPrice : $("#cart").scope().sum, orderList : JSON.stringify($("#cart").scope().list) },function(res) { if(res === true) { location.href="list.do"; }else{ alert("購買失敗"); }; }); }); //addForm </script> </body> </html>
用戶的訂單頁,該節目包含了用戶“已支付”和“待支付”的訂單:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <html> <head> <title>list.html</title> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="this is my page"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" type="text/css" href="./css/bootstrap-3.2.0/dist/css/bootstrap.min.css"/> <script src="http://cdn.bootcss.com/jquery/2.1.3/jquery.min.js"></script> <script src="http://cdn.bootcss.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> <script src="http://cdn.bootcss.com/angular.js/1.3.15/angular.min.js"></script> <style> .list{ margin:20px; } .margin80{ margin-top:80px; } </style> </head> <body ng-app="app"> <nav class="navbar navbar-default navbar-fixed-top"> <div class="container"> <ul class="nav navbar-nav"> <li> <c:if test="${name!=null}"> <a href="###"> 歡迎${name} </a> </c:if> </li> <li><a href="./index.do">首頁</a></li> <li><a href="./detail.do">類型頁</a></li> <li><a href="./cart.do">購物車</a></li> <li><a href="./user.do">用戶信息</a></li> </ul> </div> </nav> <div id="form" class="container margin80" ng-controller="form"> <div class="row"> <h1>未支付列表</h1> <ul class="list-group"> <li class="list-group-item" ng-repeat="item in items" ng-if="item.pay==0"> <p> <span class="glyphicon glyphicon-hand-right" aria-hidden="true"></span> 收貨人地址{{item.address}} </p> <p> <span class="glyphicon glyphicon-hand-right" aria-hidden="true"></span> 收貨人手機{{item.phone}} </p> <p> <span class="glyphicon glyphicon-hand-right" aria-hidden="true"></span> 商品總價格{{item.totalPrice}} </p> <div parse id={{item.orderlist}}> <div class="list pull-left" ng-repeat="order in orderlist"> <div commodity-directive id="{{order.commodityId}}"> <p>商品名{{res.name}}</p> <p>商品描述{{res.depict}}</p> <p>商品廠商{{res.manufacturer}}</p> <p>商品價格{{res.price}}</p> <p>商品logo<img ng-src={{res.img}} width=50 height=50/></p> <p> 購買的商品個數 <span class="badge"> {{order.commodityCount}} </span> </p> </div> </div> </div> <button class="btn btn-default" ng-click="pay(item.id)"> 支付 </button> <div class="clearfix"></div> </li> </ul> <br> <h1>已支付列表</h1> <ul> <li class="list-group-item" ng-repeat="item in items" ng-if="item.pay==1"> <p> <span class="glyphicon glyphicon-hand-right" aria-hidden="true"></span> 收貨人地址{{item.address}} </p> <p> <span class="glyphicon glyphicon-hand-right" aria-hidden="true"></span> 收貨人手機{{item.phone}} </p> <p> <span class="glyphicon glyphicon-hand-right" aria-hidden="true"></span> 商品總價格{{item.totalPrice}} </p> <div parse id={{item.orderlist}}> <div class="list pull-left" ng-repeat="order in orderlist"> <div commodity-directive id="{{order.commodityId}}"> <p>商品名{{res.name}}</p> <p>商品描述{{res.depict}}</p> <p>商品廠商{{res.manufacturer}}</p> <p>商品價格{{res.price}}</p> <p>商品logo<img ng-src={{res.img}} width=50 height=50/></p> <p> 購買的商品個數 <span class="badge"> {{order.commodityCount}} </span> </p> </div> </div> </div> <div class="clearfix"></div> </li> </ul> </div> </div> <script> var userId = "${id}"; var app = angular.module("app", []); app.directive("commodityDirective", function() { return { restrict : "EA", scope : true, link : function( $scope ,$el, $iattrs) { ajaxModule.getComById($iattrs.id, function( res ) { $scope.res = res[0]; $scope.$apply(); }); } } }); app.directive("parse", function() { return { restrict : "EA", scope : true, link : function( $scope ,$el, $iattrs) { $scope.orderlist = JSON.parse($iattrs.id); } } }); app.controller("form", function( $scope ) { $scope.items = []; $scope.pay = function( orderformId ) { ajaxModule.pay(userId , orderformId, function( res ) { if(res) { location.reload(); }else{ alert("支付失敗"); }; }); }; }); var ajaxModule = { getFormList : function( userId, cb ) { $.post("getFormList.do",{userId:userId}, cb); }, pay : function( userId, orderformId, cb) { $.post("pay.do", {userId : userId, orderformId : orderformId }, cb); }, getComById : function(id , cb) { $.post("./getComById.do", {id:id}, cb); } }; if(userId) { $(function() { ajaxModule.getFormList(userId, function( res ) { $("#form").scope().items = res; $("#form").scope().$apply(); }); }); }; </script> </body> </html>
項目是基于tomcat的服務器, 以及spring框架 (spring大法好), 數據庫是mysql; spring:http://spring.io/projects
數據庫的設計
既然是購物網站,那么必須有個 ==》》 商品表:
CREATE TABLE `commodity` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(100) DEFAULT '', `depict` longtext, `price` int(11) DEFAULT '0', `amount` int(11) DEFAULT '0', `manufacturer` varchar(50) DEFAULT '', `img` varchar(100) DEFAULT '', `type` varchar(20) DEFAULT '', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
因為商品有類型之分,所以也要有 ==》》 類型表:
CREATE TABLE `types` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(20) DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8;
當有多個商品的時候,就存在了例外一個表==》》 購物車表:
CREATE TABLE `orderlist` ( `id` int(11) NOT NULL AUTO_INCREMENT, `userId` int(11) NOT NULL DEFAULT '0', `commodityId` int(11) DEFAULT '0', `commodityCount` int(11) DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
把購物車的表添加上用戶的收貨地址和收貨手機就變成了==》》訂單表:
CREATE TABLE `orderform` ( `id` int(11) NOT NULL AUTO_INCREMENT, `userId` int(11) DEFAULT '0', `address` varchar(50) DEFAULT '0', `phone` varchar(20) DEFAULT '0', `totalPrice` int(11) DEFAULT '0', `pay` int(2) DEFAULT '0', `orderlist` longtext, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
登錄的用戶可以為商品添加評論, 所以就有了另外一個關聯表, 用戶評論表:
CREATE TABLE `comments` ( `id` int(11) NOT NULL AUTO_INCREMENT, `userId` int(11) NOT NULL DEFAULT '0', `userName` varchar(20) DEFAULT '0', `commodityId` int(11) NOT NULL DEFAULT '0', `comment` varchar(400) DEFAULT '', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
最后就是貫徹整個系統的用戶表:
CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT '0', `password` varchar(50) DEFAULT '0', `defaultAddress` varchar(50) DEFAULT '0', `defaultPhone` varchar(12) DEFAULT '0', `mail` varchar(50) DEFAULT '0', `money` int(16) DEFAULT '0', `regTime` datetime DEFAULT NULL, `role` int(11) NOT NULL DEFAULT '0' COMMENT '用戶角色', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8;
項目結構
web應用的基本結構如圖:
后臺實現就是spring的路由和數據持久, 項目沒有對惡意字符進行過濾,所以存在注入問題, 有待加強, 基本的功能都夠用了;
最后
有個比較坑事情的要說下, 比如寫了一小時的博客,保存博客的時候發現沒網絡了,心塞.... ,
HTML5有個 window.navigator.onLine判斷瀏覽器是否在線的API, 但是博客園的后臺管理界面不能添加自定義JS, 所以也沒什么用,
不知道有沒有好方法
整個項目代碼在這兒 : https://pan.baidu.com/s/1qYGqI2w;
作者: NONO
出處:http://www.cnblogs.com/diligenceday/
QQ:287101329
文章列表
留言列表