Leyou mall project - day19 - order + wechat payment (end part - full code attached at the end of the article)

Keywords: Vue QRCode github Java

1. Order system interface

We don't do development, we just explain

1.1. Import order service

Copy the Leyou order provided by the pre class materials to the D:\heima\code\leyou directory.

Then import in the project:

Just import the Pom coordinates directly

Start all microservices:

1.2.Swagger-UI

Swagger

1.2.1. What is OpenAPI

With the development of Internet technology, the current website architecture has basically changed from the original back-end rendering to the form of front-end rendering, front-end and back-end separation, and the front-end technology and back-end technology go further and further in their respective paths. The only connection between the front end and the back end becomes the API interface; the API document becomes the link between the front end and the back end developers, and becomes more and more important.

Before there was no API document tool, everyone wrote API documents by hand, everywhere they were written, and there was no uniform specification and format for API documents, so every company was different. This undoubtedly brings disaster to development.

The open API specification (OAS) is a project of Linux foundation, which attempts to standardize the development process of RESTful services by defining a language to describe the API format or API definition. At present, V3.0 version of OpenAPI Specification has been published and open-source on github.

Official website: https://github.com/OAI/OpenAPI-Specification

1.2.2. What is swagger?

OpenAPI is a specification for writing API documents. However, it is very troublesome to manually write OpenAPI documents. Swagger is a toolset that implements the OpenAPI specification.

Official website: https://swagger.io/

See the official instructions:

 

Swagger includes toolsets:

  • Swagger Editor: Swagger Editor allows you to edit the OpenAPI specification in YAML in a browser and preview the document in real time.

  • Swagger UI: swagger UI is a collection of HTML, Javascript and CSS assets, which can dynamically generate beautiful documents from the API conforming to the OAS standard.

  • Swagger Codegen: allows automatic generation of API client libraries (SDK generation), server stubs, and documents according to the OpenAPI specification.

  • Swagger Parser: a standalone library for parsing OpenAPI definitions from Java

  • Swagger Core: Java related libraries for creating, using, and using OpenAPI definitions

  • Swagger Inspector (free): API testing tool that allows you to validate your API and generate OpenAPI definitions from existing APIs

  • SwaggerHub (free and commercial): API design and documentation, built for teams using OpenAPI.

 

3) Interface declaration

Add interface description annotation on each handler of the controller:

 

@RestController
@RequestMapping("order")
@Api("Order service interface")
public class OrderController {

    @Autowired
    private OrderService orderService;

    @Autowired
    private PayHelper payHelper;

    /**
     * Create order
     *
     * @param order Order object
     * @return Order number
     */
    @PostMapping
    @ApiOperation(value = "Create order interface and return order number", notes = "Create order")
    @ApiImplicitParam(name = "order", required = true, value = "Order form json object,Include order entry and logistics information")
    public ResponseEntity<Long> createOrder(@RequestBody @Valid Order order) {
        Long id = this.orderService.createOrder(order);
        return new ResponseEntity<>(id, HttpStatus.CREATED);
    }

    /**
     * Query current user order in pages
     *
     * @param status Order status
     * @return Paging order data
     */
    @GetMapping("list")
    @ApiOperation(value = "Query the current user's order in pages, and filter according to the order status", 
                  notes = "Query current user order in pages")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "page", value = "Current page", 
                          defaultValue = "1", type = "Integer"),
        @ApiImplicitParam(name = "rows", value = "Size per page", 
                          defaultValue = "5", type = "Integer"),
        @ApiImplicitParam(
            name = "status", 
            value = "Order status: 1 unpaid, 2 paid but not shipped, 3 shipped but not confirmed, 4 confirmed but not evaluated, 5 transaction closed, 6 transaction succeeded, evaluated", 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);
    }

Common notes:

/**
 @Api: decorate the whole class to describe the function of Controller
 @ApiOperation: a method, or an interface, that describes a class
 @ApiParam: single parameter description
 @ApiModel: receiving parameters with objects
 @ApiProperty: a field describing an object when receiving parameters with the object
 @ApiResponse: HTTP response one of the descriptions
 @ApiResponses: overall description of HTTP response
 @ApiIgnore: use this annotation to ignore this API
 @ApiError: information returned when an error occurs
 @ApiImplicitParam: a request parameter
 @Apiimplicit params: multiple request parameters
 */

4) Start test

Start the service and access: http://localhost:8089/swagger-ui.html

Copy Token information

Order created successfully

1.3.2. How to generate ID

Particularity of order id

The order data is very large, so we will do sub warehouse and sub table in the future. In this case, to ensure the uniqueness of id, we can't rely on the self increasing database, but we can implement the algorithm to generate unique id.

 

Snowflake algorithm

The order id here is generated by a tool class:

 

First: not used

Part II: 41 bits is millisecond time (the length of 41 bits can be used for 69 years)

Part 3: 5-bit datacenterId and 5-bit workerId(10 bit length supports deployment of up to 1024 nodes)

Part 4: the last 12 bits are counts in milliseconds (the 12 bit count sequence number supports 4096 ID sequence numbers per millisecond for each node)

The IDs generated by snowflake are sorted according to the increasing time on the whole, and there is no ID collision in the whole distributed system (differentiated by datacenter and workerId), and the efficiency is high. Snowflake has been tested to generate 260000 IDS per second.

To configure

To ensure no repetition, we configure machine id for each deployed node:

 

1.3.2. Query order interface

Interface Description:

  • Request method: GET

  • Request path / order/{id}

  • Request parameter: id, order No

  • Return result: Order, json object of the Order

 

 

 

Code scanning payment: query the order status (here, if the payment department is successful, it is recommended to set a breakpoint. Take a look, add a delay, the response time of wechat server can be delayed, and the status information will be returned)

Jump to order settlement page

Bind events and methods to settlement buttons:

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"
                })
            },

The front-end pages are all the data rendering of Vue, because there is no code prompt, so it is very likely to make mistakes. It is recommended to write it down. The front-end code department is familiar with the situation and can not debug well: page data + hook subfunction + calculation

 data:{
            	ly,
                addresses:[// Optional address list, false data, need to be queried from the background
					{
					    name:"Front brother",// Recipient's name
						phone:"15800000000",// Telephone
						state:"Shanghai",// Province
						city:"Shanghai",// City
						district:"Pudong New Area",// area
						address:"Building 3, Chuanzhi podcast, No. 18, hangtou Road, hangtou town",// Street address
						zipCode:"210000", // Zip code
						default: true
					},
                    {
                        name:"Zhang San",// Recipient's name
                        phone:"13600000000",// Telephone
                        state:"Beijing",// Province
                        city:"Beijing",// City
                        district:"Chaoyang District",// area
                        address:"Building 3, Tiantang Road",// Street address
                        zipCode:"100000", // Zip code
                        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;
				}
			},

 

Complete rendering of page data:

The Vue code at the front end of the order settlement page is very bad for debugging, because the page does not work, but the page does not report which line is wrong, and it can only be checked bit by bit. The main problem is that the spelling of the words is wrong. The overall business logic of the code is very simple, and another variable is wrong, undefined, so it has no effect. Unlike the back end, if it is not Definition, direct compilation fails, front-end code is undefined, and the page can render, but some functions can't come out all the time. It's disgusting. The front-end still has to work hard to learn

Front end part code:

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"
					})
				}

complete

Page QR code writing:

JS Code:

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
						});
					})
					// Enable scheduled task and query payment status
					const taskId = setInterval(() => {
						ly.http.get("/order/order/state/" + this.orderId)
								.then(resp => {
									let i = resp.data;
									if (i === 1) {
										// Successful payment
										clearInterval(taskId);
										// Jump to payment success page
										location.href = "/paysuccess.html?orderId=" + this.orderId;
									} else if (i === 2) {
										// Payment failed
										clearInterval(taskId);
										// Jump to payment failure page
										location.href = "/payfail.html";
									}
								})
					}, 3000);
				}).catch(()=>{
					window.location="http://www.leyou.com/login.html?returnUrl=http://www.leyou.com/pay.html"
				})

Scanning payment succeeded:

Code address: https://download.csdn.net/download/zgz102928/12207683

In general, the project of Leyou mall is a comprehensive one. ElementUi is used from the background, It also uses a lot of Vue+ES technical knowledge points to the front desk, which can be said to be very fragmentary, more complex or search part, not familiar with the syntax, already lack of knowledge about the Vue front end, and very hard to debug. This project involves wechat payment, but also real payment, which can be said to be a very large e-commerce project As long as the virtual machine is built, it can be deployed to the online, and the harvest can be very much!!!

Published 129 original articles, won praise 13, visited 10000+
Private letter follow

Posted by loveranger on Mon, 02 Mar 2020 22:36:24 -0800