my大众点评作业思路实现:app+跨域+模板引擎+artDialog弹出层+ajax基本增删改查的使用
八、作业
8.1、请完成一个简单的分布式应用,使用Java作为服务器对外发布服务,PC客户端实现“品牌或商品”的管理,移动端实现如下列表:
- a)、分析出数据库的设计,建库、建表 (MySQL)
- b)、创建后台项目,实现5个服务,可以使用RETSFul (IDEA)
- c)、创建PC Web项目(HBuilder),使用AJAX消费后台提供的5个服务 ,完成增加、删除、修改、查询功能
- d)、创建App项目(HBuilder),先完成页面的静态布局,使用AJAX调用服务
- e)、注意跨域、可以选择三方的UI框架,但界面需完全一样
- f)、在PC Web中,添加,删除,编辑、详细功能请使用artDialog弹出层
- g)、在PC Web与App中请使用artTemplate渲染页面HTML
系统结构如下:
- a)、分析出数据库的设计,建库、建表 (MySQL)
- b)、创建后台项目,实现5个服务,可以使用RETSFul (IDEA)
- 使用idea新建maven项目
- 右键变为web项目
- 在pom.xml文件中导入相关的依赖包,并在构建中把依赖包放在lib文件夹里面:
-
添加spring资源文件
- 在web.xml文件中添加相关的配置springmvc DispatcherServlet(中心控制器)
-
开始写相关的后台代码
-
总index.html代码实现与后台效果展示
<%-- Created by IntelliJ IDEA. User: Sunny.by Date: 2017/12/14 Time: 20:07 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>大众点评</title> </head> <link rel="stylesheet" type="text/css" href="js/artDialog6/ui-dialog.css" /> <style type="text/css"> .dialog { width: 350px; height: 250px; margin: auto auto; line-height: 12px; display: none; } .dialog p { text-indent: 2em; } #addForm,#formEmps { display: none; } .pic { width: 50px; height: 50px; } </style> <body> <table id="tab" border="1" cellspacing="1" cellpadding="1" width="90%" align="center"> <tr style="height: 40px;"> <th>编号</th> <th>图片</th> <th>标题</th> <th>地区</th> <th>类别</th> <th>现价</th> <th>条数</th> <th>浏览量</th> <th>操作<button onclick="addBtn()" style="float: right;background: cornflowerblue;width: 55px;height: 33px;">添加</button></th> </tr> <tbody id="tbody"></tbody> </table> <%--弹窗-遍历所有(查询):多个遍历模板引擎开始--%> <script src="js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script src="js/artDialog6/dialog-min.js" type="text/javascript" charset="utf-8"></script> <%--模板引擎:与AJAX结合应用--%> <script src="js/artTemplate3/template.js" type="text/javascript" charset="utf-8"></script> <script type="text/html" id="querytmp"> {{each shoplist as shop}} <tr align="center"> <td>{{shop.id}}</td> <td><img src="images/{{shop.img}}" class="pic"></td> <td>{{shop.title}}</td> <td>{{shop.area}}</td> <td>{{shop.discountText}}</td> <td>{{shop.priceNew | round:'¥'}}</td> <td>{{shop.priceOld | round:'¥'}}</td> <td>{{shop.boughtCound}}</td> <td> <button onclick='del("{{shop.id}}")'>删除</button> <button onclick='exit("{{shop.id}}")'>修改</button> <button onclick='xiangqing("{{shop.id}}")'>详情</button> </td> </tr> {{/each}} </script> <%--弹窗-遍历所有(查询):多个遍历模板引擎结束--%> <%--弹窗-详情:单个模板引擎开始--%> <script type="text/html" id="xiangqingtmp"> <form class="dialog"> <p> <label>图片:</label> <span id="eimg"><img src="images/{{img}}" class="pic"></span> </p> <p> <label>商品编号:</label> <span id="eid">{{id}}</span> </p> <p> <label>标题:</label> <span id="etitle">{{title}}</span> </p> <p> <label>地区:</label> <span id="earea">{{area}}</span> </p> <p> <label>现价:</label> <span id="epriceNew">{{priceNew | round:'¥'}}</span> </p> <p align="right" style="margin-right: 2em;"><button style="background: cornflowerblue;width: 55px;height: 33px;" onclick="sure()">确认</button></p> </form> </script> <%--弹窗-详情:单个模板引擎结束--%> <%--修改模板引擎开始--%> <script type="text/html" id="xiugaitpm"> <form id="formEmps"> <p> <label for="id">编号:</label> <input name="id" id="xid" type="text" value="{{id}}" required="required" maxlength="32"/> </p> <p> <label for="img">图片:</label> <input name="img" id="ximg" value="{{img}}" required="required" maxlength="8"/> </p> <p> <label for="title">标题:</label> <input name="title" id="xtitle" value="{{title}}" type="text" required="required" maxlength="128"/> </p> <p> <label for="area">地区:</label> <input name="area" id="xarea" value="{{area}}" type="text" required="required" maxlength="11"/> </p> <p> <label for="priceNew">现价:</label> <input name="priceNew" id="xpriceNew" value="{{priceNew}}" type="text" required="required" maxlength="11"/> </p> <p> <button type="button" onclick="update()" style="width: 100%; height:40px; background: cornflowerblue;">保存</button> </p> </form> </script> <%--修改模板引擎结束--%> <%--添加弹窗开始--%> <form id="addForm"> <p> <label for="img">图片:</label> <input name="img" id="img" value="" required="required" maxlength="8"/> </p> <p> <label for="id">编号:</label> <input name="id" id="id" type="text" value="" required="required" maxlength="32"/> </p> <p> <label for="title">标题:</label> <input name="title" id="title" value="" type="text" required="required" maxlength="128"/> </p> <p> <label for="area">地区:</label> <input name="area" id="area" value="" type="text" required="required" maxlength="11"/> </p> <p> <label for="discountText">类别:</label> <input name="discountText" id="discountText" value="" type="text" required="required" maxlength="11"/> </p> <p> <label for="priceNew">现价:</label> <input name="priceNew" id="priceNew" value="" type="text" required="required" maxlength="11"/> </p> <p> <button type="button" onclick="add()" style="width: 100%; height:40px; background: cornflowerblue;">添加</button> </p> </form> <%--添加弹窗结束--%> <script type="text/javascript"> /*方法封装*/ var shop = { url:"http://localhost:8080/shop/", init: function() { $.ajax({ url:shop.url, type: "get", success: function(data) { $("#tab tr:gt(0)").remove(); /*$(data.data).each(function(i,h){ $("#tab").append("<tr><td>"+h.boughtCound+"</td></tr>"); console.log(h.boughtCound); });*/ $("#tab").append(template("querytmp",{shoplist:data.data})); } }); //为模板引擎定义辅助函数 template.helper("round",function(value,mark){ return (mark||"")+Math.round(value); }); }, xiangqing: function(id){ //数据需从后台遍历 $.ajax({ url:shop.url+id, type: "get", success: function(data) { //console.log("现价:"+data.priceNew+",图片:"+data.img+",浏览量:"+data.boughtCound); $("body").append(template("xiangqingtmp",data.data)); /*弹窗*/ var d = dialog({ title: '店铺详情信息', content: $(".dialog"), backdropOpacity:0.3 }); d.showModal(); } }); }, del: function(i) { var delflag = confirm("您真的要删除吗?"); if(delflag){ $.ajax({ url:shop.url+i, type:"delete", success:function(){ alert("删除成功"); shop.init(); } }); } }, exit: function(i){ $.ajax({ url:shop.url+i, type: "get", success: function(data) { //console.log("现价:"+data.priceNew+",图片:"+data.img+",浏览量:"+data.boughtCound); $("body").append(template("xiugaitpm",data.data)); /*弹窗*/ var d = dialog({ title: '修改店铺信息', content: $("#formEmps"), backdropOpacity:0.3 }); d.showModal(); } }); }, getUpdataShop: function () { return { "id": $("#xid").val(), "img": $("#ximg").val(), "title": $("#xtitle").val(), "area": $("#xarea").val(), "discountText": $("#xdiscountText").val(), "priceNew": $("#xpriceNew").val(), "priceOld": $("#xpriceOld").val(), "boughtCound": $("#xboughtCound").val() }; }, update: function(){ $.ajax({ url:shop.url, type:"put", contentType: "application/json;charset=utf-8", data:JSON.stringify(shop.getUpdataShop()), dataType: "json", success: function(data) { alert("修改成功"); shop.init(); } }); }, getAddShop: function () { return { "id": $("#id").val(), "img": $("#img").val(), "title": $("#title").val(), "area": $("#area").val(), "discountText": $("#discountText").val(), "priceNew": $("#priceNew").val(), "priceOld": $("#priceOld").val(), "boughtCound": $("#boughtCound").val() }; }, add: function() { $.ajax({ url:shop.url, type:"post", contentType: "application/json;charset=utf-8", data:JSON.stringify(shop.getAddShop()), dataType: "json" }); shop.init(); } } /*方法调用*/ shop.init(); function xiangqing(i){ shop.xiangqing(i); } /*对话框:关闭*/ function sure(){ document.getElementById("dialog").style.display="none"; } function del(i){ shop.del(i); } function exit(i){ shop.exit(i); } function update(){ shop.update(); } function addBtn() { /*弹窗*/ var d = dialog({ title: '添加店铺信息', content: $("#addForm"), backdropOpacity:0.3 }); d.showModal(); } function add(){ shop.add(); } </script> </body> </html>
查询所有效果图
详情弹窗效果图
修改弹窗效果图;添加弹窗效果图
- 创建App项目(HBuilder),先完成页面的静态布局,使用AJAX调用服务;app代码实现
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <!--标准mui.css--> <link rel="stylesheet" href="css/mui.min.css"> <link rel="stylesheet" type="text/css" href="js/artDialog6/ui-dialog.css" /> <!--App自定义的css--> <link rel="stylesheet" type="text/css" href="css/app.css"/> <title>大众App</title> <style> .title{ margin: 20px 15px 10px; color: #6d6d72; font-size: 15px; } .oa-contact-cell.mui-table .mui-table-cell { padding: 11px 0; vertical-align: middle; } .oa-contact-cell { position: relative; margin: -11px 0; } .oa-contact-avatar { width: 75px; } .oa-contact-avatar img { border-radius: 50%; } .oa-contact-content { width: 100%; } .oa-contact-name { margin-right: 20px; } .oa-contact-name, oa-contact-position { float: left; } /*首页:*/ * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: Hiragino Sans GB,Arial,Helvetica,\\5B8B\4F53,sans-serif; font-size: 14px; } #top01 { width: 100%; height: 50px; background: #f63; text-align: center; line-height: 50px; } #top01 span { color: #FFFFFF; font-size: 14px; text-align: center; } .topWeizi { height: 100%; display: inline-block; } #top01 #top01_left{ padding-left: 10px; width: 15%; /*background: #2AC845;*/ float: left; } #top01 #top01_right { width: 10%; /*background: orchid;*/ float: right; } #top01 #top01_right span { font-size: 32px; } #top01 #search { width: 75%; float: left; /*background: blue;*/ } #top01 #search input { width: 100%; height: 30px; background: #FFFFFF; border-radius: 20px; } #nav01 { width: 100%; height: 195px; background: #FFFFFF; } #nav01 .nav01_inner { width: 98%; height: 100%; margin: 0 auto; } #nav01 .nav01_cls { width: 20%; height: 87px; float: left; text-align: center; padding-top: 10px; } #nav01 .nav01_inner img { width: 44px; height: 44px; } #nav01 .nav01_inner span { display: block; } #guanggao01 { width: 100%; height: 280px; background: #FFFFFF; margin: 30px 0 ; } #guanggao01 img { width: 100%; height: 100%; } .img_cls { width: 90px; height: 90px; float: left; } .context_cls { /*background: palevioletred;*/ float: left; padding-left: 20px; } .context_cls div { color: gray; font-size: 14px; line-height: 20px; } .xiaoshouliang { float: right; margin-left: 15px; } .fontcolor { color: #f63; font-size: 15px; } </style> </head> <body> <nav class="mui-bar mui-bar-tab"> <a class="mui-tab-item mui-active" href="#tabbar"> <span class="mui-icon mui-icon-home"></span> <span class="mui-tab-label">首页</span> </a> <a class="mui-tab-item" href="#tabbar-with-chat"> <span class="mui-icon mui-icon-email"><span class="mui-badge">9</span></span> <span class="mui-tab-label">消息</span> </a> <a class="mui-tab-item" href="#tabbar-with-contact"> <span class="mui-icon mui-icon-contact"></span> <span class="mui-tab-label">通讯录</span> </a> <a class="mui-tab-item" href="#tabbar-with-map"> <span class="mui-icon mui-icon-gear"></span> <span class="mui-tab-label">设置</span> </a> </nav> <div class="mui-content"> <div id="tabbar" class="mui-control-content mui-active"> <header id="top01"> <div class="topWeizi" id="top01_left"> <span> 珠海 <span class="mui-icon mui-icon-arrowdown"></span> </span> </div> <div class="topWeizi" id="search"> <input type="text" name="sousuo" id="sousuo" value="" placeholder="输入商户名.地点"/> </div> <div class="topWeizi" id="top01_right"> <span class="mui-icon mui-icon-contact"></span> </div> </header> <nav id="nav01"> <div class="nav01_inner"> <div class="nav01_cls"> <img src="images/nav01.png"/> <span id=""> 美食 </span> </div> <div class="nav01_cls"> <img src="images/nav02.png"/> <span id=""> 猫眼电影 </span> </div> <div class="nav01_cls"> <img src="images/nav03.png"/> <span id=""> 酒店 </span> </div> <div class="nav01_cls"> <img src="images/nav04.png"/> <span id=""> 休闲娱乐 </span> </div> <div class="nav01_cls"> <img src="images/nav05.png"/> <span id=""> 外卖 </span> </div> <div class="nav01_cls"> <img src="images/nav06.png"/> <span id=""> 火锅 </span> </div> <div class="nav01_cls"> <img src="images/nav07.png"/> <span id=""> 丽人 </span> </div> <div class="nav01_cls"> <img src="images/nav08.png"/> <span id=""> 购物 </span> </div> <div class="nav01_cls"> <img src="images/nav09.png"/> <span id=""> 周边游 </span> </div> <div class="nav01_cls"> <img src="images/nav10.png"/> <span id=""> KTV </span> </div> </div> </nav> <div id="guanggao01"> <img src="images/guanggao01.png"/> </div> <!--<div id="section"></div>--> <ul class="mui-table-view" id="section"></ul> <script type="text/html" id="querytmp"> {{each shoplist as pdt}} <li class="mui-table-view-cell mui-media"> <div><img src="images/{{pdt.img}}" class="img_cls"></div><br /> <div class="context_cls"> <div><h4>{{pdt.title}}</h4></div> <div>{{pdt.area}}</div> <div><span class="fontcolor">{{pdt.priceNew | round:'¥'}}/人</span> <span> <del> {{pdt.priceOld | round:'¥'}} </del> </span> <span class="xiaoshouliang"> 销售量:{{pdt.boughtCound}} </span> </div> </div> </li> {{/each}} </script> </div> <div id="tabbar-with-chat" class="mui-control-content"> <div class="title">这是div模式选项卡中的第2个子页面,该页面展示一个消息列表</div> </div> <div id="tabbar-with-contact" class="mui-control-content"> <div class="title">这是div模式选项卡中的第3个子页面,该页面展示一个通讯录示例.</div> </div> <div id="tabbar-with-map" class="mui-control-content"> <div class="title">这是div模式选项卡中的第4个子页面,该页面展示一个常见的设置示例.</div> </div> </div> </body> <script src="js/mui.min.js"></script> <!--/*弹窗*/--> <script src="js/jquery-1.11.3.js" type="text/javascript" charset="utf-8"></script> <script src="js/artDialog6/dialog-min.js" type="text/javascript" charset="utf-8"></script> <!--模板引擎:与AJAX结合应用--> <script src="js/artTemplate3/template.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript" charset="utf-8"> mui.init({ swipeBack:true //启用右滑关闭功能 }); //http://192.168.191.1:8020/kayumuiHW/index.html?__hbt=1513661899526 var shop = { url:"http://192.168.191.1:8080/shop/", init: function() { $.ajax({ url:shop.url, type: "get", success: function(data) { //console.log(data.data.length); $("#section").html(template("querytmp",{shoplist:data.data})); } }); //为模板引擎定义辅助函数 template.helper("round",function(value,mark){ return (mark||"")+Math.round(value); }); } } /*方法调用*/ shop.init(); </script> <script type="text/javascript" src="js/clientWith.js"></script> </html>
重点代码,跨域请求:1.在web项目中的sping资源文件中加入代码
<mvc:cors> <mvc:mapping path="/**" allowed-origins="http://127.0.0.1:8020,http://192.168.191.1:8020" allowed-methods="POST,GET, OPTIONS,DELETE,PUT" allowed-headers="Content-Type,ContentType,Access-Control-Allow-Headers, Authorization, X-Requested-With" allow-credentials="true"/> </mvc:cors>
注意的是要加上http://192.168.191.1:8020(本机地址:doc命令,输入ifconfig);在app页面中跨域,并同步借用到模板引擎
-
<!--模板引擎需导入的JavaScript--> <script src="js/artTemplate3/template.js" type="text/javascript" charset="utf-8"></script> <!--artDialog弹出层(弹框)需导入的JavaScript--> <script src="js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script src="js/artDialog6/dialog-min.js" type="text/javascript" charset="utf-8"></script> <link rel="stylesheet" type="text/css" href="js/artDialog6/ui-dialog.css" />
拓展:
模板引擎使用案例
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>artTemplate</title> </head> <body> <div id="result"> </div> <!--模板引擎需导入的JavaScript--> <script src="js/artTemplate3/template.js" type="text/javascript" charset="utf-8"></script> <script type="text/html" id="template1"> {{if isShow}} <h2>姓名:{{name}}</h2> <ul> {{each hobbies as hobby index}} <li> {{index+1}} {{hobby}} </li> {{/each}} </ul> {{/if}} </script> <script type="text/javascript"> var data={ isShow:true, name:"Tom", hobbies:["看书","上网","运动","电影","购物"] }; //用数据与模板渲染(render)出结果 var html=template("template1",data); document.getElementById("result").innerHTML=html; </script> </body> </html>
artDialog弹出层(弹框)使用案例
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>artDialog</title> </head> <body> <button onclick="btn_dialog()"> 弹出框 </button> <button onclick="btn_loading()"> 加载中 </button> <!--artDialog弹出层(弹框)需导入的JavaScript--> <script src="js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script src="js/artDialog6/dialog-min.js" type="text/javascript" charset="utf-8"></script> <link rel="stylesheet" type="text/css" href="js/artDialog6/ui-dialog.css" /> <script type="text/javascript"> function btn_dialog() { var d = dialog({ title: '消息', content: '风吹起的青色衣衫,夕阳里的温暖容颜,你比以前更加美丽,像盛开的花<br>——许巍《难忘的一天》', okValue: '确 定', ok: function() { var that = this; setTimeout(function() { that.title('提交中..'); }, 2000); return false; }, cancelValue: '取消', cancel: function() { alert('你点了取消按钮') } }); d.show(); } function btn_loading(){ dialog({ modal:true }).show(); } </script> </body> </html>
- 其他(ajax的使用):在后台web的index.html中调用ajax(只有添加和修改可以不传数据,直接封装一个get对象的方法传过后台,但要注意的是需要转为json数据),即必须添加
contentType: "application/json;charset=utf-8",
data:JSON.stringify(shop.getAddShop()),
dataType: "json"var shop = { url:"http://localhost:8080/shop/", init: function() { $.ajax({ url:shop.url, type: "get", success: function(data) { $("#tab tr:gt(0)").remove(); /*$(data.data).each(function(i,h){ $("#tab").append("<tr><td>"+h.boughtCound+"</td></tr>"); console.log(h.boughtCound); });*/ $("#tab").append(template("querytmp",{shoplist:data.data})); } }); //为模板引擎定义辅助函数 template.helper("round",function(value,mark){ return (mark||"")+Math.round(value); }); }, xiangqing: function(id){ //数据需从后台遍历 $.ajax({ url:shop.url+id, type: "get", success: function(data) { //console.log("现价:"+data.priceNew+",图片:"+data.img+",浏览量:"+data.boughtCound); $("body").append(template("xiangqingtmp",data.data)); /*弹窗*/ var d = dialog({ title: '店铺详情信息', content: $(".dialog"), backdropOpacity:0.3 }); d.showModal(); } }); }, del: function(i) { var delflag = confirm("您真的要删除吗?"); if(delflag){ $.ajax({ url:shop.url+i, type:"delete", success:function(){ alert("删除成功"); shop.init(); } }); } }, exit: function(i){ $.ajax({ url:shop.url+i, type: "get", success: function(data) { //console.log("现价:"+data.priceNew+",图片:"+data.img+",浏览量:"+data.boughtCound); $("body").append(template("xiugaitpm",data.data)); /*弹窗*/ var d = dialog({ title: '修改店铺信息', content: $("#formEmps"), backdropOpacity:0.3 }); d.showModal(); } }); }, getUpdataShop: function () { return { "id": $("#xid").val(), "img": $("#ximg").val(), "title": $("#xtitle").val(), "area": $("#xarea").val(), "discountText": $("#xdiscountText").val(), "priceNew": $("#xpriceNew").val(), "priceOld": $("#xpriceOld").val(), "boughtCound": $("#xboughtCound").val() }; }, update: function(){ $.ajax({ url:shop.url, type:"put", contentType: "application/json;charset=utf-8", data:JSON.stringify(shop.getUpdataShop()), dataType: "json", success: function(data) { alert("修改成功"); shop.init(); } }); }, getAddShop: function () { return { "id": $("#id").val(), "img": $("#img").val(), "title": $("#title").val(), "area": $("#area").val(), "discountText": $("#discountText").val(), "priceNew": $("#priceNew").val(), "priceOld": $("#priceOld").val(), "boughtCound": $("#boughtCound").val() }; }, add: function() { $.ajax({ url:shop.url, type:"post", contentType: "application/json;charset=utf-8", data:JSON.stringify(shop.getAddShop()), dataType: "json" }); shop.init(); } }
手机端app访问地址http://192.168.191.1:8020/kayumuiHW/index.html?__hbt=1513661899526- 手机项目生成手机app安装包步骤:
- 项目的
-
-
-
-
-
-
-
最后,把安装包发送下载到手机即可