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: