乐优商城项目---day19-下单+微信支付(完结篇--文末附完整代码)

1.订单系统接口

我们不做开发,只讲解

1.1.导入订单服务

把课前资料提供的leyou-order复制到D:\heima\code\leyou目录。

然后在工程内导入:

直接导入Pom坐标就可以了

启动所有微服务:

1.2.Swagger-UI

丝袜哥

1.2.1.什么是OpenAPI

随着互联网技术的发展,现在的网站架构基本都由原来的后端渲染,变成了:前端渲染、前后端分离的形态,而且前端技术和后端技术在各自的道路上越走越远。  前端和后端的唯一联系,变成了API接口;API文档变成了前后端开发人员联系的纽带,变得越来越重要。

没有API文档工具之前,大家都是手写API文档的,在什么地方书写的都有,而且API文档没有统一规范和格式,每个公司都不一样。这无疑给开发带来了灾难。

OpenAPI规范(OpenAPI Specification 简称OAS)是Linux基金会的一个项目,试图通过定义一种用来描述API格式或API定义的语言,来规范RESTful服务开发过程。目前V3.0版本的OpenAPI规范已经发布并开源在github上 。

官网:https://github.com/OAI/OpenAPI-Specification

1.2.2.什么是swagger?

OpenAPI是一个编写API文档的规范,然而如果手动去编写OpenAPI规范的文档,是非常麻烦的。而Swagger就是一个实现了OpenAPI规范的工具集。

官网:https://swagger.io/

看官方的说明:

 

Swagger包含的工具集:

  • Swagger编辑器: Swagger Editor允许您在浏览器中编辑YAML中的OpenAPI规范并实时预览文档。

  • Swagger UI: Swagger UI是HTML,Javascript和CSS资产的集合,可以从符合OAS标准的API动态生成漂亮的文档。

  • Swagger Codegen:允许根据OpenAPI规范自动生成API客户端库(SDK生成),服务器存根和文档。

  • Swagger Parser:用于解析来自Java的OpenAPI定义的独立库

  • Swagger Core:与Java相关的库,用于创建,使用和使用OpenAPI定义

  • Swagger Inspector(免费): API测试工具,可让您验证您的API并从现有API生成OpenAPI定义

  • SwaggerHub(免费和商业): API设计和文档,为使用OpenAPI的团队构建。

 

3)接口声明

在controller的每个handler上添加接口说明注解:

 

@RestController
@RequestMapping("order")
@Api("订单服务接口")
public class OrderController {

    @Autowired
    private OrderService orderService;

    @Autowired
    private PayHelper payHelper;

    /**
     * 创建订单
     *
     * @param order 订单对象
     * @return 订单编号
     */
    @PostMapping
    @ApiOperation(value = "创建订单接口,返回订单编号", notes = "创建订单")
    @ApiImplicitParam(name = "order", required = true, value = "订单的json对象,包含订单条目和物流信息")
    public ResponseEntity<Long> createOrder(@RequestBody @Valid Order order) {
        Long id = this.orderService.createOrder(order);
        return new ResponseEntity<>(id, HttpStatus.CREATED);
    }

    /**
     * 分页查询当前用户订单
     *
     * @param status 订单状态
     * @return 分页订单数据
     */
    @GetMapping("list")
    @ApiOperation(value = "分页查询当前用户订单,并且可以根据订单状态过滤", 
                  notes = "分页查询当前用户订单")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "page", value = "当前页", 
                          defaultValue = "1", type = "Integer"),
        @ApiImplicitParam(name = "rows", value = "每页大小", 
                          defaultValue = "5", type = "Integer"),
        @ApiImplicitParam(
            name = "status", 
            value = "订单状态:1未付款,2已付款未发货,3已发货未确认,4已确认未评价,5交易关闭,6交易成功,已评价", type = "Integer"),
    })
    public ResponseEntity<PageResult<Order>> queryUserOrderList(
        @RequestParam(value = "page", defaultValue = "1") Integer page,
        @RequestParam(value = "rows", defaultValue = "5") Integer rows,
        @RequestParam(value = "status", required = false) Integer status) {
        PageResult<Order> result = this.orderService.queryUserOrderList(page, rows, status);
        if (result == null) {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
        return ResponseEntity.ok(result);
    }

常用注解说明:

/**
 @Api:修饰整个类,描述Controller的作用
 @ApiOperation:描述一个类的一个方法,或者说一个接口
 @ApiParam:单个参数描述
 @ApiModel:用对象来接收参数
 @ApiProperty:用对象接收参数时,描述对象的一个字段
 @ApiResponse:HTTP响应其中1个描述
 @ApiResponses:HTTP响应整体描述
 @ApiIgnore:使用该注解忽略这个API
 @ApiError :发生错误返回的信息
 @ApiImplicitParam:一个请求参数
 @ApiImplicitParams:多个请求参数
 */

4)启动测试

启动服务,然后访问:http://localhost:8089/swagger-ui.html

复制Token信息

订单创建成功

1.3.2.生成ID的方式

订单id的特殊性

订单数据非常庞大,将来一定会做分库分表。那么这种情况下, 要保证id的唯一,就不能靠数据库自增,而是自己来实现算法,生成唯一id。

 

雪花算法

这里的订单id是通过一个工具类生成的:

 

第一位:为未使用

第二部分:41位为毫秒级时间(41位的长度可以使用69年)

第三部分:5位datacenterId和5位workerId(10位的长度最多支持部署1024个节点)

第四部分:最后12位是毫秒内的计数(12位的计数顺序号支持每个节点每毫秒产生4096个ID序号)

snowflake生成的ID整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和workerId作区分),并且效率较高。经测试snowflake每秒能够产生26万个ID。

配置

为了保证不重复,我们给每个部署的节点都配置机器id:

 

1.3.2.查询订单接口

接口说明:

  • 请求方式:GET

  • 请求路径:/order/{id}

  • 请求参数:id,订单编号

  • 返回结果:Order,订单的json对象

 

 

 

扫码付款:查询订单状态(这里如果支付部成功,建议打上断点,看一下,加一个延迟,微信服务器响应得时间能延后一些,状态信息就又了)

跳转到订单结算页面

给结算按钮绑定事件和方法:

toOrder(){
                ly.verify().then(resp=>{
                    ly.store.set("LY_SELECTED",this.selected);
                    window.location="http://www.leyou.com/getOrderInfo.html"
                }).catch(()=>{
                    ly.store.set("LY_CART",this.carts);
                    window.location="http://www.leyou.com/login.html?returnUrl=http://www.leyou.com/cart.html"
                })
            },

前端页面都是Vue得数据渲染,因为没有代码提示,所以非常大得可能会出错,建议写一下看一下,前端代码部熟悉得情况,不能很好得调试:页面数据+勾子函数+计算

 data:{
            	ly,
                addresses:[// 可选地址列表,假数据,需要从后台查询
					{
					    name:"锋哥",// 收件人姓名
						phone:"15800000000",// 电话
						state:"上海",// 省份
						city:"上海",// 城市
						district:"浦东新区",// 区
						address:"航头镇航头路18号传智播客 3号楼",// 街道地址
						zipCode:"210000", // 邮编
						default: true
					},
                    {
                        name:"张三",// 收件人姓名
                        phone:"13600000000",// 电话
                        state:"北京",// 省份
                        city:"北京",// 城市
                        district:"朝阳区",// 区
                        address:"天堂路 3号楼",// 街道地址
                        zipCode:"100000", // 邮编
                        default: false
                    }
				],
				selectedAddress: 0,
				order:{
                	paymentType:2,
					postFee:1000
				},
				carts:[],
				fanxian:500
            },
			created(){
				ly.verify().then(resp=>{
					this.carts=	ly.store.get("LY_SELECTED",this.selected);
				}).catch(()=>{
					window.location="http://www.leyou.com/login.html?returnUrl=http://www.leyou.com/cart.html"
				})
			},
			computed:{
				total(){
					return this.carts.reduce((c1,c2)=>c1+c2.num,0);
				},
				totalPrice(){
					return   this.carts.reduce((c1,c2)=>c1+c2.num*c2.price,0);
				},
				actionPrice(){
					return this.totalPrice+this.order.postFee-this.fanxian;
				}
			},

 

完成页面数据得渲染:

下单结算页这个前端Vue得代码非常得不好调试,因为页面不出效果,但是页不报具体哪一行出错,只能一点一点得排查,主要得问题,就是单词拼写错误,整体得代码得业务逻辑非常,简单,又一个变量出错,未定义,就一直出不来效果,着不像后端那样,如果未定义,直接编译就不通过,前端代码未定义,页面还能渲染,但是某些功能就一直无法出来,非常得恶心,前端还是得多下功夫学学才行

前端部分代码:

submitOrder(){
					debugger
					ly.verify().then(({data})=>{
						const address=this.addresses[this.selectedAddress];
						let addr={
							receiver: address.name,
							receiverState: address.state,
							receiverCity: address.city,
							receiverAddress: address.address,
							receiverDistrict: address.district,
							receiverMobile: address.phone,
							receiverZip: address.zipCode,
							invoiceType:0,
							sourceTpe:2
						};
						const orderDetail={orderDetails:this.carts};
						debugger
						Object.assign(this.order,addr,orderDetail,{  totalPay: this.totalPrice,
						actualPay: this.actionPrice,buyerMessage:null,buyerNick:data.username});
						ly.http.post("/order/order",this.order,{transformResponse: [
								function (data) {
									return data;
								}
							]}).then(({data})=>{
							window.location="http://www.leyou.com/pay.html?orderId="+data;
						})
					}).catch(()=>{
						window.location="http://www.leyou.com/login.html?returnUrl=http://www.leyou.com/cart.html"
					})
				}

完成

页面二维码得写入:

JS代码:

created(){
				ly.verify().then(resp=>{
					this.orderId=ly.getUrlParam("orderId");
					ly.http.get("/order/order/url/"+this.orderId).then(({data})=>{
						new QRCode(document.getElementById("qrcode"), {
							text: data,
							width: 250,
							height: 250,
							colorDark: "#000000",
							colorLight: "#ffffff",
							correctLevel: QRCode.CorrectLevel.H
						});
					})
					// 开启定时任务,查询付款状态
					const taskId = setInterval(() => {
						ly.http.get("/order/order/state/" + this.orderId)
								.then(resp => {
									let i = resp.data;
									if (i === 1) {
										// 付款成功
										clearInterval(taskId);
										// 跳转到付款成功页
										location.href = "/paysuccess.html?orderId=" + this.orderId;
									} else if (i === 2) {
										// 付款失败
										clearInterval(taskId);
										// 跳转到付款失败页
										location.href = "/payfail.html";
									}
								})
					}, 3000);
				}).catch(()=>{
					window.location="http://www.leyou.com/login.html?returnUrl=http://www.leyou.com/pay.html"
				})

扫码支付成功:

代码地址:https://download.csdn.net/download/zgz102928/12207683

总得来说这个乐友商城得项目还是一个比较全得项目,从后台用得ElementUi,到前台用得也是Vue+ES技术知识点非常得多,可以说时非常得零碎,比较复杂得还是搜索部分,对语法得不熟悉,已经对对Vue前端知识得欠缺,调试起来非常得吃力,这个项目涉及到得支付也是微信支付,也是可以真实支付得,可以说时一个非常大得一个电商得项目,只要虚拟机搭建完成,完全可以部署到线上去用,收获可以说时非常得多了!!!

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值