Chapter16 — 前台 订单
16.1 搭建 order-consumer 开发环境
16.1.1 order 模块
依赖:与project模块相同
主启动类
@EnableFeignClients @EnableEurekaClient @SpringBootApplication public class OrderConsumerMain { public static void main(String[] args) { SpringApplication.run(OrderConsumerMain.class, args); } }
配置文件
server: port: 6000 spring: application: name: atguigu-crowd-order thymeleaf: prefix: classpath:/templates/ suffix: .html redis: host: 54.238.77.83 session: store-type: redis ribbon: ReadTimeout: 60000 ConnectTimeout: 60000 eureka: client: service-url: defaultZone: http://localhost:1000/eureka
16.1.2 其它模块
zuul模块添加配置
zuul: ignored-services: "*" sensitive-headers: "*" routes: crowd-portal: service-id: atguigu-crowd-auth path: /** crowd-project: service-id: atguigu-crowd-project path: /project/** crowd-order: service-id: atguigu-crowd-order path: /order/**
16.2 建模
16.2.1 结构分析
前端页面
结构分析
16.2.2 建表
订单表
CREATE TABLE `project_crowd`.`t_order` ( `id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', `order_num` CHAR(100) COMMENT '订单号', `pay_order_num` CHAR(100) COMMENT '支付宝流水号', `order_amount` DOUBLE(10,5) COMMENT '订单金额', `invoice` INT COMMENT '是否开发票(0 不开, 1 开) ', `invoice_title` CHAR(100) COMMENT '发票抬头', `order_remark` CHAR(100) COMMENT '订单备注', `address_id` CHAR(100) COMMENT '收货地址 id', PRIMARY KEY (`id`) );
收货地址表
CREATE TABLE `project_crowd`.`t_address` ( `id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', `receive_name` CHAR(100) COMMENT '收件人', `phone_num` CHAR(100) COMMENT '手机号', `address` CHAR(200) COMMENT '收货地址', `member_id` INT COMMENT '用户 id', PRIMARY KEY (`id`) );
项目信息表
CREATE TABLE `project_crowd`.`t_order_project` ( `id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', `project_name` CHAR(200) COMMENT '项目名称', `launch_name` CHAR(100) COMMENT '发起人', `return_content` CHAR(200) COMMENT '回报内容', `return_count` INT COMMENT '回报数量', `support_price` INT COMMENT '支持单价', `freight` INT COMMENT '配送费用', `order_id` INT COMMENT '订单表的主键', PRIMARY KEY (`id`) );
16.2.3 逆向工程
修改 generatorConfig.xml
<!-- 数据库表名字和我们的 entity 类对应的映射指定 --> <table tableName="t_order" domainObjectName="OrderPO" /> <table tableName="t_address" domainObjectName="AddressPO" /> <table tableName="t_order_project" domainObjectName="OrderProjectPO" />
生成
资源归位
16.3 确认回报内容
16.3.1 分析
页面
思路
16.3.2 前端代码
修改 project-show-detail.html
<!--<button type="button" class="btn btn-warning btn-lg" onclick="window.location.href='pay-step-1.html'">支持</button>--> <a th:href="'http://www.crowd.com/order/confirm/return/info/'+${detailProjectVO.projectId}+'/'+${return.returnId}" class="btn btn-warning btn-lg">支持</a>
新建 confirm-return.html
<!DOCTYPE html> <html lang="zh-CN" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content=""> <base th:href="@{/}"/> <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="css/font-awesome.min.css"> <link rel="stylesheet" href="css/theme.css"> <style> #footer { padding: 15px 0; background: #fff; border-top: 1px solid #ddd; text-align: center; } #topcontrol { color: #fff; z-index: 99; width: 30px; height: 30px; font-size: 20px; background: #222; position: relative; right: 14px !important; bottom: 11px !important; border-radius: 3px !important; } #topcontrol:after { /*top: -2px;*/ left: 8.5px; content: "\f106"; position: absolute; text-align: center; font-family: FontAwesome; } #topcontrol:hover { color: #fff; background: #18ba9b; -webkit-transition: all 0.3s ease-in-out; -moz-transition: all 0.3s ease-in-out; -o-transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out; } .label-type, .label-status, .label-order { background-color: #fff; color: #f60; padding: 5px; border: 1px #f60 solid; } #typeList :not (:first-child ) { margin-top: 20px; } .label-txt { margin: 10px 10px; border: 1px solid #ddd; padding: 4px; font-size: 14px; } .panel { border-radius: 0; } .progress-bar-default { background-color: #ddd; } </style> </head> <body> <div class="navbar-wrapper"> <div class="container"> <nav class="navbar navbar-inverse navbar-fixed-top" role="navigation"> <div class="container"> <div class="navbar-header"> <a class="navbar-brand" href="index.html" style="font-size: 32px;">尚筹网-创意产品众筹平台</a> </div> <div id="navbar" class="navbar-collapse collapse" style="float: right;"> <ul class="nav navbar-nav"> <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="glyphicon glyphicon-user"></i> [[${session.loginMember.username}]]<span class="caret"></span></a> <ul class="dropdown-menu" role="menu"> <li><a href="member.html"><i class="glyphicon glyphicon-scale"></i> 会员中心</a></li> <li><a href="#"><i class="glyphicon glyphicon-comment"></i> 消息</a></li> <li class="divider"></li> <li><a href="http://www.crowd.com/auth/member/logout"><i class="glyphicon glyphicon-off"></i> 退出系统</a></li> </ul></li> </ul> </div> </div> </nav> </div> </div> <div class="container theme-showcase" role="main"> <div class="container"> <div class="row clearfix"> <div class="col-md-12 column"> <div class="panel panel-default"> <div class="panel-heading" style="text-align: center;"> <div class="container-fluid"> <div class="row clearfix"> <div class="col-md-3 column"> <div class="progress" style="height: 50px; border-radius: 0; position: absolute; width: 75%; right: 49px;"> <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 100%; height: 50px;"> <div style="font-size: 16px; margin-top: 15px;">1. 确认回报内容</div> </div> </div> <div style="right: 0; border: 10px solid #ddd; border-left-color: #88b7d5; border-width: 25px; position: absolute; border-left-color: rgba(92, 184, 92, 1); border-top-color: rgba(92, 184, 92, 0); border-bottom-color: rgba(92, 184, 92, 0); border-right-color: rgba(92, 184, 92, 0);"> </div> </div> <div class="col-md-3 column"> <div class="progress" style="height: 50px; border-radius: 0; position: absolute; width: 75%; right: 49px;"> <div class="progress-bar progress-bar-default" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 100%; height: 50px;"> <div style="font-size: 16px; margin-top: 15px;">2. 确认订单</div> </div> </div> <div style="right: 0; border: 10px solid #ddd; border-left-color: #88b7d5; border-width: 25px; position: absolute; border-left-color: rgba(221, 221, 221, 1); border-top-color: rgba(221, 221, 221, 0); border-bottom-color: rgba(221, 221, 221, 0); border-right-color: rgba(221, 221, 221, 0);"> </div> </div> <div class="col-md-3 column"> <div class="progress" style="height: 50px; border-radius: 0; position: absolute; width: 75%; right: 49px;"> <div class="progress-bar progress-bar-default" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 100%; height: 50px;"> <div style="font-size: 16px; margin-top: 15px;">3. 付款</div> </div> </div> <div style="right: 0; border: 10px solid #ddd; border-left-color: #88b7d5; border-width: 25px; position: absolute; border-left-color: rgba(221, 221, 221, 1); border-top-color: rgba(221, 221, 221, 0); border-bottom-color: rgba(221, 221, 221, 0); border-right-color: rgba(221, 221, 221, 0);"> </div> </div> <div class="col-md-3 column"> <div class="progress" style="height: 50px; border-radius: 0;"> <div class="progress-bar progress-bar-default" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 100%; height: 50px;"> <div style="font-size: 16px; margin-top: 15px;">4. 完成</div> </div> </div> </div> </div> </div> </div> <div class="panel-body"> <div class="container-fluid"> <div class="row clearfix"> <div class="col-md-12 column"> <blockquote style="border-left: 5px solid #f60; color: #f60; padding: 0 0 0 20px;"> <b> 请确认您所选择的回报项信息和购买数量 </b> </blockquote> </div> <div class="col-md-12 column"> <table class="table table-bordered" style="text-align: center;"> <thead> <tr style="background-color: #ddd;"> <td>项目名称</td> <td>发起人</td> <td width="300">回报内容</td> <td width="80">回报数量</td> <td>支持单价</td> <td>配送费用</td> </tr> </thead> <tbody> <tr> <td th:text="${session.orderProjectVO.projectName}">活性富氢净水直饮机</td> <td th:text="${session.orderProjectVO.launchName}">深圳市博实永道电子商务有限公司</td> <td th:text="${session.orderProjectVO.returnContent}">每满1750人抽取一台活性富氢净水直饮机,至少抽取一台。抽取名额(小数点后一位四舍五入)=参与人数÷1750人,由苏宁官方抽取。</td> <td><input id="returnCountInput" type="text" class="form-control" style="width: 60px;" th:value="${session.orderProjectVO.returnCount}"></td> <td style="color: #F60" th:text="${session.orderProjectVO.supportPrice}">¥ 1.00</td> <td th:if="${session.orderProjectVO.freight == 0}">免运费</td> <td th:if="${session.orderProjectVO.freight != 0}" th:text="${session.orderProjectVO.freight}">免运费</td> </tr> </tbody> </table> <div style="float: right;"> <p> 总价(含运费):<span id="totalAmount" style="font-size: 16px; color: #F60;">¥[[${session.orderProjectVO.returnCount*session.orderProjectVO.supportPrice}]]</span> </p> <button id="submitBtn" type="button" class="btn btn-warning btn-lg" style="float: right;"> <i class="glyphicon glyphicon-credit-card"></i> 去结算 </button> </div> </div> <div class="container"> <div class="row clearfix"> <div class="col-md-12 column"> <blockquote> <p> <i class="glyphicon glyphicon-info-sign" style="color: #2a6496;"></i> 提示 </p> <br> <span style="font-size: 12px;">1.众筹并非商品交易,存在一定风险。支持者根据自己的判断选择、支持众筹项目,与发起人共同实现梦想并获得发起人承诺的回报。<br> 2.众筹平台仅提供平台网络空间及技术支持等中介服务,众筹仅存在于发起人和支持者之间,使用众筹平台产生的法律后果由发起人与支持者自行承担。<br> 3.本项目必须在2017-06-04之前达到 ¥1000000.00 的目标才算成功,否则已经支持的订单将取消。订单取消或募集失败的,您支持的金额将原支付路径退回。<br> 4.请在支持项目后15分钟内付款,否则您的支持请求会被自动关闭。<br> 5.众筹成功后由发起人统一进行发货,售后服务由发起人统一提供;如果发生发起人无法发放回报、延迟发放回报、不提供回报后续服务等情况,您需要直接和发起人协商解决。<br> 6.如您不同意上述风险提示内容,您有权选择不支持;一旦选择支持,视为您已确认并同意以上提示内容。 </span> </blockquote> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> <div class="container" style="margin-top: 20px;"> <div class="row clearfix"> <div class="col-md-12 column"> <div id="footer"> <div class="footerNav"> <a rel="nofollow" href="http://www.atguigu.com">关于我们</a> | <a rel="nofollow" href="http://www.atguigu.com">服务条款</a> | <a rel="nofollow" href="http://www.atguigu.com">免责声明</a> | <a rel="nofollow" href="http://www.atguigu.com">网站地图</a> | <a rel="nofollow" href="http://www.atguigu.com">联系我们</a> </div> <div class="copyRight">Copyright ?2010-2014atguigu.com 版权所有 </div> </div> </div> </div> </div> </div> <!-- /container --> <script src="jquery/jquery-2.1.1.min.js"></script> <script src="bootstrap/js/bootstrap.min.js"></script> <script src="script/docs.min.js"></script> <script src="script/back-to-top.js"></script> <script> var signalPurchase = [[${session.orderProjectVO.signalPurchase}]]; var purchase = [[${session.orderProjectVO.purchase}]]; $('#myTab a').click(function(e) { e.preventDefault() $(this).tab('show') }); $("#returnCountInput").change(function(){ var returnCount = $.trim($(this).val()); if(returnCount == null || returnCount == "") { alert("请输入有效数据!"); $(this).val(this.defaultValue); return ; } if(signalPurchase == 1 && returnCount > purchase) { alert("不能超过限购数量!"); return ; } var supportPrice = [[${session.orderProjectVO.supportPrice}]]; $("#totalAmount").text("¥"+(supportPrice * returnCount)); }); $("#submitBtn").click(function(){ var returnCount = $("#returnCountInput").val(); window.location.href = "order/confirm/order/"+returnCount; }); </script> </body> </html>
16.3.3 后端代码
entity 模块创建 OrderProjectVO
@Data @AllArgsConstructor @NoArgsConstructor public class OrderProjectVO implements Serializable { private static final long serialVersionUID = 1L; private Integer id; private String projectName; private String launchName; private String returnContent; private Integer returnCount; private Integer supportPrice; private Integer freight; private Integer orderId; private Integer signalPurchase; private Integer purchase; }
order 模块新建 OrderHandler 类
@Controller public class OrderHandler { @Autowired private MySQLRemoteService mySQLRemoteService; @RequestMapping("/confirm/return/info/{projectId}/{returnId}") public String showReturnConfirmInfo(@PathVariable("projectId") Integer projectId, @PathVariable("returnId") Integer returnId, HttpSession session) { ResultEntity<OrderProjectVO> resultEntity = mySQLRemoteService.getOrderProjectVORemote(projectId, returnId); if (ResultEntity.SUCCESS.equals(resultEntity.getResult())) { OrderProjectVO orderProjectVO = resultEntity.getData(); session.setAttribute("orderProjectVO", orderProjectVO); } return "confirm-return"; } }
api 模块 MySQLRemoteService
@RequestMapping("/get/order/project/vo/remote") ResultEntity<OrderProjectVO> getOrderProjectVORemote(@RequestParam("projectId") Integer projectId, @RequestParam("returnId") Integer returnId);
16.3.4 sql相关 - mysql模块
新建 OrderProviderHandler
@RestController public class OrderProviderHandler { @Autowired private OrderService orderService; @RequestMapping("/get/order/project/vo/remote") ResultEntity<OrderProjectVO> getOrderProjectVORemote(@RequestParam("projectId") Integer projectId, @RequestParam("returnId") Integer returnId) { try { OrderProjectVO orderProjectVO = orderService.getOrderProjectVO(projectId, returnId); return ResultEntity.successWithData(orderProjectVO); } catch (Exception e) { e.printStackTrace(); return ResultEntity.failed(e.getMessage()); } } }
新建 OrderService
@Service public class OrderServiceImpl implements OrderService { @Autowired private OrderPOMapper orderPOMapper; @Autowired private OrderProjectPOMapper orderProjectPOMapper; @Override public OrderProjectVO getOrderProjectVO(Integer projectId, Integer returnId) { return orderProjectPOMapper.selectOrderProjectVO(returnId); } }
OrderProjectPOMapper
OrderProjectVO selectOrderProjectVO(Integer returnId);
OrderProjectPOMapper.xml
<select id="selectOrderProjectVO" resultType="com.atguigu.crowd.entity.vo.OrderProjectVO"> select distinct project_name projectName, content returnContent, description_simple launchName, t_return.supportmoney supportPrice, freight, count returnCount, signalpurchase signalPurchase, purchase from t_project left join t_member_launch_info tmli on t_project.memberid = tmli.memberid left join t_return on t_project.id=t_return.projectid where t_return.id=#{returnId} </select>
16.4 确认订单
16.4.1 思路
思路
确认页面
功能
- 显示收货地址
- 保存新的收货地址
- 保存信息,跳转到付款页面
16.4.2 页面显示-后端代码
创建 AddressVO
@Data @AllArgsConstructor @NoArgsConstructor public class AddressVO implements Serializable { private static final long serialVersionUID = 1L; private Integer id; private String receiveName; private String phoneNum; private String address; private Integer memberId; }
OrderHandler
/** * 跳转到确认订单页面 * @param returnCount 回报数量 * @param session 将orderProjectVO存进session域 * @return 返回确认订单页面视图 */ @RequestMapping("/confirm/order/{returnCount}") public String showConfirmOrderInfo(@PathVariable Integer returnCount, HttpSession session) { // 1.把接收到的回报数量合并到 Session 域 OrderProjectVO orderProjectVO = (OrderProjectVO) session.getAttribute("orderProjectVO"); orderProjectVO.setReturnCount(returnCount); session.setAttribute("orderProjectVO", orderProjectVO); // 2.获取当前已登录用户的 id MemberLoginVO memberLoginVO = (MemberLoginVO) session.getAttribute(CrowdConstant.ATTR_NAME_LOGIN_MEMBER); Integer memberId = memberLoginVO.getId(); // 3.查询目前的收货地址数据 ResultEntity<List<AddressVO>> resultEntity = mySQLRemoteService.getAddressVORemote(memberId); if (ResultEntity.SUCCESS.equals(resultEntity.getResult())) { List<AddressVO> list = resultEntity.getData(); session.setAttribute("addressVOList", list); } return "confirm-order"; }
api接口
@RequestMapping("/get/address/vo/remote") ResultEntity<List<AddressVO>> getAddressVORemote(@RequestParam("memberId") Integer memberId);
16.4.3 sql相关-地址查询
OrderProviderHandler
@RequestMapping("/get/address/vo/remote") ResultEntity<List<AddressVO>> getAddressVORemote(@RequestParam("memberId") Integer memberId) { try { List<AddressVO> addressVOList = orderService.getAddressVOList(memberId); return ResultEntity.successWithData(addressVOList); } catch (Exception e) { e.printStackTrace(); return ResultEntity.failed(e.getMessage()); } }
OrderService
@Override public List<AddressVO> getAddressVOList(Integer memberId) { AddressPOExample example = new AddressPOExample(); example.createCriteria().andMemberIdEqualTo(memberId); List<AddressPO> addressPOList = addressPOMapper.selectByExample(example); List<AddressVO> addressVOList = new ArrayList<>(); for (AddressPO addressPO : addressPOList) { AddressVO addressVO = new AddressVO(); BeanUtils.copyProperties(addressPO, addressVO); addressVOList.add(addressVO); } return addressVOList; }
16.4.4 前端页面
confirm-order.html
<!DOCTYPE html> <html lang="zh-CN" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content=""> <base th:href="@{/}" /> <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="css/font-awesome.min.css"> <link rel="stylesheet" href="css/theme.css"> <style> #footer { padding: 15px 0; background: #fff; border-top: 1px solid #ddd; text-align: center; } #topcontrol { color: #fff; z-index: 99; width: 30px; height: 30px; font-size: 20px; background: #222; position: relative; right: 14px !important; bottom: 11px !important; border-radius: 3px !important; } #topcontrol:after { /*top: -2px;*/ left: 8.5px; content: "\f106"; position: absolute; text-align: center; font-family: FontAwesome; } #topcontrol:hover { color: #fff; background: #18ba9b; -webkit-transition: all 0.3s ease-in-out; -moz-transition: all 0.3s ease-in-out; -o-transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out; } .label-type, .label-status, .label-order { background-color: #fff; color: #f60; padding: 5px; border: 1px #f60 solid; } #typeList :not (:first-child ) { margin-top: 20px; } .label-txt { margin: 10px 10px; border: 1px solid #ddd; padding: 4px; font-size: 14px; } .panel { border-radius: 0; } .progress-bar-default { background-color: #ddd; } </style> </head> <body> <div class="navbar-wrapper"> <div class="container"> <nav class="navbar navbar-inverse navbar-fixed-top" role="navigation"> <div class="container"> <div class="navbar-header"> <a class="navbar-brand" href="index.html" style="font-size: 32px;">尚筹网-创意产品众筹平台</a> </div> <div id="navbar" class="navbar-collapse collapse" style="float: right;"> <ul class="nav navbar-nav"> <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="glyphicon glyphicon-user"></i> [[${session.loginMember.username}]]<span class="caret"></span></a> <ul class="dropdown-menu" role="menu"> <li><a href="member.html"><i class="glyphicon glyphicon-scale"></i> 会员中心</a></li> <li><a href="#"><i class="glyphicon glyphicon-comment"></i> 消息</a></li> <li class="divider"></li> <li><a href="http://www.crowd.com/auth/member/logout"><i class="glyphicon glyphicon-off"></i> 退出系统</a></li> </ul></li> </ul> </div> </div> </nav> </div> </div> <div class="container theme-showcase" role="main"> <div class="container"> <div class="row clearfix"> <div class="col-md-12 column"> <div class="panel panel-default"> <div class="panel-heading" style="text-align: center;"> <div class="container-fluid"> <div class="row clearfix"> <div class="col-md-3 column"> <div class="progress" style="height: 50px; border-radius: 0; position: absolute; width: 75%; right: 49px;"> <div class="progress-bar progress-bar-default" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 100%; height: 50px;"> <div style="font-size: 16px; margin-top: 15px;">1. 确认回报内容</div> </div> </div> <div style="right: 0; border: 10px solid #ddd; border-left-color: #88b7d5; border-width: 25px; position: absolute; border-left-color: rgba(221, 221, 221, 1); border-top-color: rgba(221, 221, 221, 0); border-bottom-color: rgba(221, 221, 221, 0); border-right-color: rgba(221, 221, 221, 0);"> </div> </div> <div class="col-md-3 column"> <div class="progress" style="height: 50px; border-radius: 0; position: absolute; width: 75%; right: 49px;"> <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 100%; height: 50px;"> <div style="font-size: 16px; margin-top: 15px;">2. 确认订单</div> </div> </div> <div style="right: 0; border: 10px solid #ddd; border-left-color: #88b7d5; border-width: 25px; position: absolute; border-left-color: rgba(92, 184, 92, 1); border-top-color: rgba(92, 184, 92, 0); border-bottom-color: rgba(92, 184, 92, 0); border-right-color: rgba(92, 184, 92, 0);"> </div> </div> <div class="col-md-3 column"> <div class="progress" style="height: 50px; border-radius: 0; position: absolute; width: 75%; right: 49px;"> <div class="progress-bar progress-bar-default" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 100%; height: 50px;"> <div style="font-size: 16px; margin-top: 15px;">3. 付款</div> </div> </div> <div style="right: 0; border: 10px solid #ddd; border-left-color: #88b7d5; border-width: 25px; position: absolute; border-left-color: rgba(221, 221, 221, 1); border-top-color: rgba(221, 221, 221, 0); border-bottom-color: rgba(221, 221, 221, 0); border-right-color: rgba(221, 221, 221, 0);"> </div> </div> <div class="col-md-3 column"> <div class="progress" style="height: 50px; border-radius: 0;"> <div class="progress-bar progress-bar-default" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 100%; height: 50px;"> <div style="font-size: 16px; margin-top: 15px;">4. 完成</div> </div> </div> </div> </div> </div> </div> <div class="panel-body"> <div class="container-fluid"> <div class="row clearfix"> <div class="col-md-12 column"> <div class="alert alert-warning alert-dismissable" style="color: red;"> <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button> <i class="glyphicon glyphicon-info-sign"></i> <strong>请在下单后15分钟内付款,否则您的订单会被自动关闭。</strong> </div> </div> </div> </div> <div id="address" class="container-fluid"> <div class="row clearfix"> <div class="col-md-12 column"> <blockquote style="border-left: 5px solid #f60; color: #f60; padding: 0 0 0 20px;"> <b> 收货地址 </b> </blockquote> </div> <div class="col-md-12 column" style="padding: 0 120px;"> <div th:if="${#strings.isEmpty(session.addressVOList)}">尚未创建收货地址</div> <div th:if="${not #strings.isEmpty(session.addressVOList)}"> <div th:each="address : ${session.addressVOList}" class="radio"> <label> <input type="radio" name="addressId" th:value="${address.id}" id="optionsRadios1"/> [[${address.receiveName}]] [[${address.phoneNum}]] [[${address.address}]] </label> </div> </div> <div class="radio"> <label> <input type="radio" name="optionsRadios" id="optionsRadios2" value="option2"> 新地址 </label> </div> <div style="border: 10px solid #f60; border-bottom-color: #eceeef; border-width: 10px; width: 20px; margin-left: 20px; margin-top: -20px; border-left-color: rgba(221, 221, 221, 0); border-top-color: rgba(221, 221, 221, 0); border-right-color: rgba(221, 221, 221, 0);"></div> <div class="panel panel-default" style="border-style: dashed; background-color: #eceeef"> <div class="panel-body"> <div class="col-md-12 column"> <form action="order/save/address" method="post" class="form-horizontal"> <input type="hidden" name="memberId" th:value="${session.loginMember.id}" /> <div class="form-group"> <label class="col-sm-2 control-label">收货人(*)</label> <div class="col-sm-10"> <input type="text" name="receiveName" class="form-control" style="width: 200px;" placeholder="姓名:xxxx"> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">手机(*)</label> <div class="col-sm-10"> <input class="form-control" name="phoneNum" type="text" style="width: 200px;" placeholder="请填写11位手机号码"></input> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">地址(*)</label> <div class="col-sm-10"> <input class="form-control" name="address" type="text" style="width: 400px;" placeholder="请填写11位手机号码"></input> </div> </div> <div class="form-group"> <label for="inputEmail3" class="col-sm-2 control-label"></label> <div class="col-sm-10"> <button type="submit" class="btn btn-primary">确认配送信息</button> </div> </div> </form> </div> </div> </div> </div> </div> </div> <div class="container-fluid"> <div class="row clearfix"> <div class="col-md-12 column"> <blockquote style="border-left: 5px solid #f60; color: #f60; padding: 0 0 0 20px;"> <b> 发票信息 </b> </blockquote> </div> <div class="col-md-12 column" style="padding: 0 120px;"> <div class="radio"> <label> <input type="radio" name="optionsRadio" id="optionsRadio1" value="option1" checked> 无需发票 </label> </div> <div class="radio"> <label> <input type="radio" name="optionsRadio" id="optionsRadio2" value="option2"> 需要发票 </label> </div> <div style="border: 10px solid #f60; border-bottom-color: #eceeef; border-width: 10px; width: 20px; margin-left: 20px; margin-top: -20px; border-left-color: rgba(221, 221, 221, 0); border-top-color: rgba(221, 221, 221, 0); border-right-color: rgba(221, 221, 221, 0);"></div> <div class="panel panel-default" style="border-style: dashed; background-color: #eceeef"> <div class="panel-body"> <div class="col-md-12 column"> <form class="form-horizontal"> <div class="form-group"> <label class="col-sm-2 control-label">发票抬头(*)</label> <div class="col-sm-10"> <input type="text" class="form-control" style="width: 200px;" placeholder="个人"> </div> </div> </form> </div> </div> </div> </div> </div> </div> <div class="container-fluid"> <div class="row clearfix"> <div class="col-md-12 column"> <blockquote style="border-left: 5px solid #f60; color: #f60; padding: 0 0 0 20px;"> <b> 项目信息 <a style="font-size: 12px;" href="pay-step-1.html">修改数量</a> </b> </blockquote> </div> <div class="col-md-12 column"> <table class="table table-bordered" style="text-align: center;"> <thead> <tr style="background-color: #ddd;"> <td>项目名称</td> <td>发起人</td> <td width="300">回报内容</td> <td width="80">回报数量</td> <td>支持单价</td> <td>配送费用</td> </tr> </thead> <tbody> <tr> <td th:text="${session.orderProjectVO.projectName}">活性富氢净水直饮机</td> <td th:text="${session.orderProjectVO.launchName}">深圳市博实永道电子商务有限公司</td> <td th:text="${session.orderProjectVO.returnContent}">每满1750人抽取一台活性富氢净水直饮机,至少抽取一台。抽取名额(小数点后一位四舍五入)=参与人数÷1750人,由苏宁官方抽取。</td> <td th:text="${session.orderProjectVO.returnCount}">55</td> <td style="color: #F60" th:text="${session.orderProjectVO.supportPrice}">¥ 1.00</td> <td th:if="${session.orderProjectVO.freight == 0}">免运费</td> <td th:if="${session.orderProjectVO.freight != 0}" th:text="${session.orderProjectVO.freight}">免运费</td> </tr> </tbody> </table> </div> <div class="col-md-12 column"> <div class="form-group"> <label class="col-sm-2 control-label">备注</label> <div class="col-sm-10"> <textarea class="form-control" rows="1" placeholder="填写关于回报或发起人希望您备注的信息"></textarea> </div> </div> </div> <div class="col-md-12 column"> <blockquote style="border-left: 5px solid #f60; color: #f60; padding: 0 0 0 20px;"> <b> 账单 </b> </blockquote> </div> <div class="col-md-12 column"> <div class="alert alert-warning alert-dismissable" style="text-align: right; border: 2px solid #ffc287;"> <ul style="list-style: none;"> <li style="margin-top: 10px;">支持金额:<span style="color: red;">¥[[${session.orderProjectVO.returnCount*session.orderProjectVO.supportPrice}]]</span></li> <li style="margin-top: 10px;">配送费用:<span style="color: red;">¥[[${session.orderProjectVO.freight}]]</span></li> <li style="margin-top: 10px; margin-bottom: 10px;"><h2> 支付总金额:<span style="color: red;">¥[[${session.orderProjectVO.returnCount*session.orderProjectVO.supportPrice+session.orderProjectVO.freight}]]</span> </h2></li> <li style="margin-top: 10px; padding: 5px; border: 1px solid #F00; display: initial; background: #FFF;"> <i class="glyphicon glyphicon-info-sign"></i> <strong>您需要先 <a href="#address">设置配送信息</a> ,再提交订单 </strong> </li> <li style="margin-top: 10px;"> 请在下单后15分钟内付款,否则您的订单会被自动关闭。</li> <li style="margin-top: 10px;"> <button id="payButton" disabled="disabled" type="button" class="btn btn-warning btn-lg" onclick="window.location.href='pay-step-3.html'"> <i class="glyphicon glyphicon-credit-card"></i> 立即付款 </button> </li> <li style="margin-top: 10px;"> <div class="checkbox"> <label> <input id="knowRoleCheckBox" type="checkbox">我已了解风险和规则 </label> </div> </li> </ul> </div> </div> <div class="container"> <div class="row clearfix"> <div class="col-md-12 column"> <blockquote> <p> <i class="glyphicon glyphicon-info-sign" style="color: #2a6496;"></i> 提示 </p> <br> <span style="font-size: 12px;">1.众筹并非商品交易,存在一定风险。支持者根据自己的判断选择、支持众筹项目,与发起人共同实现梦想并获得发起人承诺的回报。<br> 2.众筹平台仅提供平台网络空间及技术支持等中介服务,众筹仅存在于发起人和支持者之间,使用众筹平台产生的法律后果由发起人与支持者自行承担。<br> 3.本项目必须在2017-06-04之前达到 ¥1000000.00 的目标才算成功,否则已经支持的订单将取消。订单取消或募集失败的,您支持的金额将原支付路径退回。<br> 4.请在支持项目后15分钟内付款,否则您的支持请求会被自动关闭。<br> 5.众筹成功后由发起人统一进行发货,售后服务由发起人统一提供;如果发生发起人无法发放回报、延迟发放回报、不提供回报后续服务等情况,您需要直接和发起人协商解决。<br> 6.如您不同意上述风险提示内容,您有权选择不支持;一旦选择支持,视为您已确认并同意以上提示内容。 </span> </blockquote> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> <div class="container" style="margin-top: 20px;"> <div class="row clearfix"> <div class="col-md-12 column"> <div id="footer"> <div class="footerNav"> <a rel="nofollow" href="http://www.atguigu.com">关于我们</a> | <a rel="nofollow" href="http://www.atguigu.com">服务条款</a> | <a rel="nofollow" href="http://www.atguigu.com">免责声明</a> | <a rel="nofollow" href="http://www.atguigu.com">网站地图</a> | <a rel="nofollow" href="http://www.atguigu.com">联系我们</a> </div> <div class="copyRight">Copyright ?2010-2014atguigu.com 版权所有 </div> </div> </div> </div> </div> </div> <!-- /container --> <script src="jquery/jquery-2.1.1.min.js"></script> <script src="bootstrap/js/bootstrap.min.js"></script> <script src="script/docs.min.js"></script> <script src="script/back-to-top.js"></script> <script> $("#knowRoleCheckBox").click(function(){ var currentStatus = this.checked; if(currentStatus) { $("#payButton").prop("disabled", ""); }else{ $("#payButton").prop("disabled","disabled"); } }); $('#myTab a').click(function(e) { e.preventDefault() $(this).tab('show') }) </script> </body> </html>
16.4.5 新增收获地址
思路
OrderHandler
/** * 保存地址信息 * @param addressVO 新增的地址信息 * @param session 通过session获取地址信息 * @return 通过session中的信息跳转回原页面 */ @RequestMapping("/save/address") public String saveAddress(AddressVO addressVO, HttpSession session) { // 1.保存地址信息 ResultEntity<String> resultEntity = mySQLRemoteService.saveAddressRemote(addressVO); log.info(resultEntity.getResult()); // 2.从Session域中获取orderProjectVO OrderProjectVO orderProjectVO = (OrderProjectVO) session.getAttribute("orderProjectVO"); // 3.获取returnCount Integer returnCount = orderProjectVO.getReturnCount(); // 4.重定向到指定地址,重新进入确定订单页面(数据库中地址信息已更新,页面中显示的是新的地址信息) return "redirect:http://crowd.com/order/confirm/order/"+returnCount; }
api
@RequestMapping("/save/address/vo/remote") ResultEntity<String> saveAddressRemote(@RequestBody AddressVO addressVO);
OrderProviderHandler
@RequestMapping("/save/address/vo/remote") ResultEntity<String> saveAddressRemote(@RequestBody AddressVO addressVO) { try { orderService.saveAddressVO(addressVO); return ResultEntity.successWithoutData(); } catch (Exception e) { e.printStackTrace(); return ResultEntity.failed(e.getMessage()); } }
OrderService
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class) @Override public void saveAddressVO(AddressVO addressVO) { AddressPO addressPO = new AddressPO(); BeanUtils.copyProperties(addressVO, addressPO); addressPOMapper.insert(addressPO); }