09 谷粒订单提交_第1页
09 谷粒订单提交_第2页
09 谷粒订单提交_第3页
09 谷粒订单提交_第4页
09 谷粒订单提交_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Xxxx课程系列谷粒商城 版本:V 2.0订单一、 业务介绍当前的位置 订单业务在整个电商平台中处于核心位置,也是比较复杂的一块业务。是把“物”变为“钱”的一个中转站。 整个订单模块一共分四部分组成:1. 结算2. 下单3. 对接支付服务4. 对接库存管理系统二、 结算 入口:购物车点击计算按钮1 搭建模块=tocol=zookeeperspring.dubbo.registry.address=63:2181spring.dubbo.base-package==dubbospring.dubbo.consumer.timeout=10000spring.dubbo.consumer.check=falseserver.port=8088spring.thymeleaf.cache=falsespring.thymeleaf.mode=LEGACYHTML5拷贝静态资源文件和htmlhost文件# gmall63 2 功能分析 分析页面需要的数据:1、 用户地址列表(已完成)2、 购物车中选择的商品列表3、 点击结算后是否要更新数据库 3 购物车中选择的商品列表3.1 订单模块要引入CartService,并增加购物车列表方法public List getCartCheckedList(String userId) /优先从缓存中取值 Jedis jedis = redisUtil.getJedis(); List skuJsonlist = jedis.hvals(user: + userId + :cartChecked); List cartInfoList=new ArrayList(); if(skuJsonlist!=null &skuJsonlist.size()!=0) /序列化 for (String skuJson : skuJsonlist) CartInfo cartInfo = JSON.parseObject(skuJson, CartInfo.class); cartInfoList.add( cartInfo); return cartInfoList;要把查询出来的cartInfoList装配到orderDetailList中3.2 结算页面 商品清单部分 商家:自营 总金额 应付总额: 提交订单点击提交购物车列表结算到订单确认页面三、 提交订单1 数据结构订单表id主键member_id会员idcoupon_id优惠券idorder_sn订单编号(外部订单号)create_time创建时间member_username会员账号total_amount订单总金额pay_amount应付金额(实际支付金额)freight_amount运费金额promotion_amount促销优化金额(促销价、满减、阶梯价)integration_amount积分抵扣金额coupon_amount优惠券抵扣金额discount_amount管理员后台调整订单使用的折扣金额pay_type支付方式:0-未支付;1-支付宝;2-微信source_type订单来源:0-PC订单;1-app订单status订单状态:0-待付款;1-待发货;2-已发货;3-已完成;4-已关闭;5-无效订单order_type订单类型:0-正常订单;1-秒杀订单delivery_company物流公司(配送方式)delivery_sn物流单号auto_confirm_day自动确认时间(天)integration可以获得的积分growth可以活动的成长值promotion_info活动信息bill_type发票类型:0-不开发票;1-电子发票;2-纸质发票bill_header发票抬头bill_content发票内容bill_receiver_phone收票人电话bill_receiver_email收票人邮箱receiver_name收货人姓名receiver_phone收货人电话receiver_post_code收货人邮编receiver_province省份/直辖市receiver_city城市receiver_region区receiver_detail_address详细地址note订单备注confirm_status确认收货状态:0-未确认;1-已确认delete_status删除状态:0-未删除;1-已删除use_integration下单时使用的积分payment_time支付时间delivery_time发货时间receive_time确认收货时间comment_time评价时间modify_time修改时间订单详情表id主键order_id订单idorder_sn订单编号(外部订单号)product_id商品id(对应spu_id)product_pic商品图片product_name商品名称product_brand品牌product_sn商品编号(仓库)product_price商品价格product_quantity商品重量product_sku_idSku_idproduct_sku_codeSku条码product_category_id商品分类id(三级分类)sp1销售属性1sp2销售属性2sp3销售属性3promotion_name促销名称promotion_amount商品促销分解金额coupon_amount商品优惠券分解金额integration_amount积分分解金额real_amount该商品经过优惠后的分解金额gift_integration积分成长gift_growth成长值product_attr商品销售属性:key:颜色,value:颜色,key:容量,value:4G2 功能分析:1. 保存单据前要做交易:验库存、验价 2. 保存单据3. 保存以后把购物车中的商品删除4. 重定向到支付页面3 订单服务模块3.1 搭建gmall-order-service1 pom.xml 4.0.0 com.atguigu.gmall gmall-order-service 0.0.1-SNAPSHOT jar gmall-order-service Demo project for Spring Boot com.atguigu.gmall gmall-parent 1.0-SNAPSHOT com.atguigu.gmall gmall-interface 1.0-SNAPSHOT com.atguigu.gmall gmall-service-util 1.0-SNAPSHOT org.springframework.boot spring-boot-maven-plugin 2 pertiesserver.port=8078logging.level.root==tocol=zookeeperspring.dubbo.registry.address=63:2181spring.dubbo.base-package==dubbospring.dubbo.consumer.timeout=100000spring.dubbo.consumer.check=falsespring.datasource.url=jdbc:mysql:/36:3306/gmall?characterEncoding=UTF-8spring.datasource.username=rootspring.datasource.password=123456mybatis.mapper-locations=classpath:mapper/*Mapper.xmlmybatis.configuration.mapUnderscoreToCamelCase=truespring.redis.host=63spring.redis.port=6379spring.redis.database=0GmallOrderServiceApplicationSpringBootApplicationMapperScan(basePackages = com.atguigu.gmall.order.mapper)ComponentScan(basePackages = com.atguigu.gmall)public class GmallOrderServiceApplication public static void main(String args) SpringApplication.run(GmallOrderServiceApplication.class, args); 3.2 增加订单服务类OrderServiceImplServicepublic class OrderServiceImpl implements OrderService Autowired OrderInfoMapper orderInfoMapper; Autowired OrderDetailMapper orderDetailMapper; Override Transactional public void saveOrder(OrderInfo orderInfo) /增加时间、状态、生成外部流水号 orderInfo.setCreateTime(new Date(); if(orderInfo.getOrderStatus()=null) orderInfo.setOrderStatus(ProcessStatus.UNPAID.getOrderStatus(); if(orderInfo.getProcessStatus()=null) orderInfo.setProcessStatus(ProcessStatus.UNPAID); orderInfo.setOutTradeNo(OrderConst.out_trade_no_prefix+System.currentTimeMillis()+000+new Random().nextInt(1000); orderInfoMapper.insertSelective(orderInfo); System.out.println(orderInfo); List orderDetailList=orderInfo.getOrderDetailList(); for (OrderDetail orderDetail : orderDetailList) orderDetail.setOrderId(orderInfo.getId(); orderDetailMapper.insertSelective(orderDetail); 3.3 增加删除购物车方法CartServiceImpl中public void delCartCheckedList(String userId,List skuIds) Example example=new Example(CartInfo.class); example.createCriteria().andIn(skuId,skuIds); cartInfoMapper.deleteByExample(example); Jedis jedis=redisUtil.getJedis(); jedis.pipelined(); for (String skuId : skuIds) jedis.hdel(user: + userId + :cartChecked,skuId); jedis.hdel(user: + userId + :cart,skuId); jedis.sync(); jedis.close();3.4 实现OrderController3.5 实现页面trade.html4 如何解决用户利用浏览器刷新和回退重复提交订单?在进入结算页面时,生成一个结算流水号,然后保存到结算页面的隐藏元素中,每次用户提交都检查该流水号与页面提交的是否相符,订单保存以后把后台的流水号删除掉。那么第二次用户用同一个页面提交的话流水号就会匹配失败,无法重复保存订单。 4.1 修改结算页增加流水号的生成4.1.1 OrderServiceImpl/生成流水号Overridepublic String genTradeNo(String userId) Jedis jedis = redisUtil.getJedis(); String userTradeNoKey=user:+userId+:tradeNo; UUID uuid = UUID.randomUUID(); jedis.setex(userTradeNoKey,OrderConst.tradeExpire,uuid.toString(); return uuid.toString();/验证流水号Overridepublic boolean checkTradeNo(String userId,String trackNo) Jedis jedis = redisUtil.getJedis(); String userTradeNoKey=user:+userId+:tradeNo; String uuid = jedis.get(userTradeNoKey); if(trackNo!=null&trackNo.equals(uuid) return true; return false;/删除流水号Overridepublic void delTradeNo(String userId ) Jedis jedis = redisUtil.getJedis(); String userTradeNoKey=user:+userId+:tradeNo; jedis.del(userTradeNoKey); return ;4.2 OrderController中的trade方法中String tradeNo = orderService.genTradeNo(userId);request.setAttribute(tradeNo,tradeNo);4.3 OrderController中的submitOrder方法中RequestMapping(value = submitOrder ,method = RequestMethod.POST)LoginRequire(debugUserId = 8)public String submitOrder(OrderInfo orderInfo , HttpServletRequest request) String userId = (String) request.getAttribute(userId); String tradeNo= request.getParameter(tradeNo); Boolean hasTradeNo=orderService.checkTradeNo(userId,tradeNo); if(!hasTradeNo) request.setAttribute(errMsg,结算页面过期或已失效,请重新结算。); return tradeFail; List orderDetailList = orderInfo.getOrderDetailList(); for (OrderDetail orderDetail : orderDetailList) SkuInfo skuInfo = manageService.getSkuInfo(orderDetail.getSkuId(); /验价 if(!orderDetail.getOrderPrice().equals(skuInfo.getPrice() cartService.loadCartCache(userId); request.setAttribute(errMsg,商品+skuInfo.getSkuName()+价格已发生变化,请在购物车页面重新进行结算); return tradeFail; orderDetail.setImgUrl(skuInfo.getSkuDefaultImg(); orderDetail.setSkuName(skuInfo.getSkuName(); orderInfo.setUserId(userId); orderInfo.sumTotalAmount(); orderService.saveOrder(orderInfo); List skuIdList =new ArrayList(); for (OrderDetail orderDetail : orderDetailList) skuIdList.add(orderDetail.getSkuId(); cartService.delCartCheckedList(userId,skuIdList); orderService.delTradeNo(userId); return redirect://index;4.4 redis+lua脚本防止重复提交攻击/对比防重删令牌String script = if redis.call(get, KEYS1) = ARGV1 then return redis.call(del, KEYS1) else return 0 end;Jedis jedis = jedisPool.getResource();Long eval = (Long) jedis.eval(script, Collections.singletonList(KEYS1), Collections.singletonList(ARGV1);5 验库存通过restful接口查询商品是否有库存 一般电商系统的商品库存,都不由电商系统本身来管理,由另外一套仓库管理系统,或者进销存系统来管理,电商系统通过第三方接口调用该系统。 由于库管系统可能是异构的系统,所以不在dubbo的分布式体系之内。只支持restful风格的webservice调用和消息队列的调用。详见库存管理系统手册根据手册中的接口文档,编写调用代码。5.1 OrderController 中注入perties的值 Value($ware_sys_url)public String ware_sys_url;增加方法private String hasStorkBySkuidAndNum(String skuid,String num) String url=ware_sys_url+/hasStock; url=url+?skuId=+skuid+&num=+num; String result = HttpclientUtil.doGet(url); return result;5.2 submitOrder中增加 方法RequestMapping(value = submitOrder ,method = RequestMethod.POST)LoginRequire(debugUserId = 8)public String submitOrder(OrderInfo orderInfo , HttpServletRequest request) String userId = (String) request.getAttribute(userId); String tradeNo= request.getParameter(tradeNo); Boolean hasTradeNo=orderService.checkTradeNo(userId,tradeNo); if(!hasTradeNo) request.setAttribute(errMsg,结算页面过期或已失效,请重新结算。); return tradeFail; List orderDetailList = orderInfo.getOrderDetailList(); for (OrderDe

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论