当前位置:网站首页>Order timeout cancellation and commodity query by category
Order timeout cancellation and commodity query by category
2022-07-27 18:50:00 【Fantasia of the cat】
1. Order time out cancellation :
Order time out cancellation , It means that the user fails to complete the payment within the specified time after successfully submitting the order , Then close the order and restore the inventory .
There are usually two solutions to realize the overtime cancellation of orders :
- Timing task ( Circular scanning quartz)
- Delay queue (MQ)
Implementation process :

1.2 quartz Timed task framework usage
1.2.1 Add dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>1.2.2 Create a scheduled task :
Timing task , Perform the task every specified time
Case study : every other 3 Print every second HelloWorld

1.2.3 Start the scheduled task in the startup class :

2.3 Realize order timeout cancellation
2.3.1 stay service Subproject add spring-boot-starter-quartz rely on
2.3.2 stay api Automatically start class addition @EnableScheduling annotation
2.3.3 stay service Add... To the module job package , add to OrderTimeoutCheckJob class
package com.qfedu.fmmall.service.job;
import com.github.wxpay.sdk.WXPay;
import com.qfedu.fmmall.dao.OrdersMapper;
import com.qfedu.fmmall.entity.Orders;
import com.qfedu.fmmall.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.entity.Example;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Description:
* @Author : Jerry
* @create : 2022-07-06 15:36
*/
@Component
public class OrderTimeoutCheckJob {
@Autowired
private OrdersMapper ordersMapper;
@Autowired
private OrderService orderService;
WXPay wxPay = new WXPay(new MyPayConfig());
@Scheduled(cron = "0/5 * * * * ?")
public void checkAndCloseOrder(){
try {
//1. Query over 30min Orders with the status of pending payment
Example example = new Example(Orders.class);
Example.Criteria criteria = example.createCriteria();
criteria.andEqualTo("status","1");
// The current time is pushed forward 30min
Date time = new Date(System.currentTimeMillis() - 30*60*1000);
criteria.andLessThan("createTime",time);
List<Orders> orders = ordersMapper.selectByExample(example);
//2. Access wechat platform interface , Determine the final payment status of the current order
for (int i = 0; i < orders.size(); i++) {
Orders order = orders.get(i);
HashMap<String,String> params = new HashMap<>();
params.put("out_trade_no",order.getOrderId());
Map<String, String> resp = wxPay.orderQuery(params);
System.out.println(resp);
if("SUCCESS".equalsIgnoreCase(resp.get("trade_state"))){
//2.1 If the order has been paid , Then modify the order to " Deliver goods on behalf of / Paid " status2
Orders updateOrder = new Orders();
updateOrder.setOrderId(order.getOrderId());
updateOrder.setStatus("2");
ordersMapper.updateByPrimaryKeySelective(updateOrder);
}else if("NOTPAY".equalsIgnoreCase(resp.get("trade_state"))){
//2.2 If it does not pay Then cancel the order :
// a. Send a request to wechat payment , Close the payment of the current order and continue
Map<String,String> map = wxPay.closeOrder(params);
System.out.println(map);
// b. Close order
orderService.closeOrder(order.getOrderId());
}
}
}catch (Exception e) {
e.printStackTrace();
}
}
}
stay orderService New method in :
SERIALIZABLE Serialization level : All transactions are executed one by one , In this way, there is no interference between transactions .
public void closeOrder(String orderId);
@Override
@Transactional(isolation = Isolation.SERIALIZABLE)
public void closeOrder(String orderId) {
synchronized (this){
// 1. Modify the current order :status=6 closed close_type=1 Overtime unpaid
Orders cancleOrder = new Orders();
cancleOrder.setOrderId(orderId);
cancleOrder.setStatus("6");
cancleOrder.setCloseType(1);
ordersMapper.updateByPrimaryKeySelective(cancleOrder);
// 2. Restore inventory : First, query the product snapshot according to the current order number (skuid buy_count)--> modify product_sku
Example example1 = new Example(OrderItem.class);
Example.Criteria criteria1 = example1.createCriteria();
criteria1.andEqualTo("orderId",orderId);
List<OrderItem> orderItems = orderItemMapper.selectByExample(example1);
// Restore inventory
for (int j = 0; j < orderItems.size(); j++) {
OrderItem orderItem = orderItems.get(j);
// modify
ProductSku productSku = productSkuMapper.selectByPrimaryKey(orderItem.getSkuId());
productSku.setStock( productSku.getStock() + orderItem.getBuyCounts());
productSkuMapper.updateByPrimaryKeySelective(productSku);
}
}
}2. Query products by category :
2.1 Process analysis :

2.2 Interface development :
2.2.1 Query the commodity interface according to the category :
Database analysis sql
Database implementation :
Implementation class :

productMapper New addition :
/**
* According to three-level classification id Page query product information
* @param cid Three levels of classification id
* @param start Starting index
* @param limit Number of query records
* @return
*/
public List<ProductVO> selectProductByCategoryId(@Param("cid") int cid,
@Param("start") int start,
@Param("limit") int limit);
<resultMap id="ProductVOMap2" type="com.qfedu.fmmall.entity.ProductVO" >
<id column="product_id" property="productId" jdbcType="VARCHAR" />
<result column="product_name" property="productName" jdbcType="VARCHAR" />
<result column="category_id" property="categoryId" jdbcType="INTEGER" />
<result column="root_category_id" property="rootCategoryId" jdbcType="INTEGER" />
<result column="sold_num" property="soldNum" jdbcType="INTEGER" />
<result column="product_status" property="productStatus" jdbcType="INTEGER" />
<result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
<result column="update_time" property="updateTime" jdbcType="TIMESTAMP" />
<result column="content" property="content" jdbcType="LONGVARCHAR" />
<!-- According to the goods id Check the package with the lowest price -->
<collection property="skus" column="product_id" select="com.qfedu.fmmall.dao.ProductSkuMapper.selectLowerestPriceByProductId"/>
</resultMap>
<select id="selectProductByCategoryId" resultMap="ProductVOMap2">
select product_id,
product_name,
category_id,
root_category_id,
sold_num,
product_status,
content,
create_time,
update_time
from product
where category_id=#{cid}
limit #{start},#{limit}
</select>Subquery :productSkuMapper:
package com.qfedu.fmmall.dao;
import com.qfedu.fmmall.entity.ProductSku;
import com.qfedu.fmmall.general.GeneralDAO;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface ProductSkuMapper extends GeneralDAO<ProductSku> {
/**
* According to the goods id, Query all packages of current goods The lowest price package
* @param productId
* @return
*/
public List<ProductSku> selectLowerestPriceByProductId(String productId);
}<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.qfedu.fmmall.dao.ProductSkuMapper" >
<resultMap id="BaseResultMap" type="com.qfedu.fmmall.entity.ProductSku" >
<!--
WARNING - @mbg.generated
-->
<id column="sku_id" property="skuId" jdbcType="VARCHAR" />
<result column="product_id" property="productId" jdbcType="VARCHAR" />
<result column="sku_name" property="skuName" jdbcType="VARCHAR" />
<result column="sku_img" property="skuImg" jdbcType="VARCHAR" />
<result column="untitled" property="untitled" jdbcType="VARCHAR" />
<result column="original_price" property="originalPrice" jdbcType="INTEGER" />
<result column="sell_price" property="sellPrice" jdbcType="INTEGER" />
<result column="discounts" property="discounts" jdbcType="DECIMAL" />
<result column="stock" property="stock" jdbcType="INTEGER" />
<result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
<result column="update_time" property="updateTime" jdbcType="TIMESTAMP" />
<result column="status" property="status" jdbcType="INTEGER" />
</resultMap>
<select id="selectLowerestPriceByProductId" resultMap="BaseResultMap">
select sku_id,product_id,sku_name,sku_img,untitled,original_price,
sell_price,discounts,stock,create_time,update_time,status
from product_sku
where product_id = #{productId}
ORDER BY sell_price limit 0,1
</select>
</mapper>productService Interface implementation :
public R getProductsByCategoryId(int categoryId,int pageNum,int limit);@Autowired
private ProductMapper productMapper;
@Override
public R getProductsByCategoryId(int categoryId, int pageNum, int limit) {
//1. Query product data
int start = (pageNum - 1)*limit;
List<ProductVO> productVOS = productMapper.selectProductByCategoryId(categoryId, start, limit);
//2. Query the total number of commodity records under the current category
Example example = new Example(Product.class);
Example.Criteria criteria = example.createCriteria();
criteria.andEqualTo("categoryId",categoryId);
int count = productMapper.selectCountByExample(example);
//3. Calculate the total number of pages
int pageCount = count%limit==0? count/limit : count/limit+1;
//4. Encapsulate return data
PageHelper<ProductVO> pageHelper = new PageHelper<>(count,pageCount,productVOS);
return new R(ResStatus.OK,"success",pageHelper);
}2.2.3 By category id Query the brand interface of all goods under the current category
sql:

Database implementation :
productmapper Interface :
public List<String> selectBrandByCategoryId(int cid);Mapping configuration :
<select id="selectBrandByCategoryId" resultSets="java.util.List" resultType="String">
select Distinct brand
from product_params
where product_id in (
select product_id
from product
where category_id=49
)
</select>service Interface :
public R listBrands(int categoryId);@Override
public R listBrands(int categoryId) {
List<String> brands = productMapper.selectBrandByCategoryId(categoryId);
return new R(ResStatus.OK,"success",brands);
}controller Realization :
// Query the commodity interface according to the category
@GetMapping("/listbycid/{cid}")
public R getProductsByCategoryId(@PathVariable("cid") int cid,int pageNum,int pageSize){
return productService.getProductsByCategoryId(cid,pageNum,pageSize);
}
// Query the commodity brand interface according to the category
@GetMapping("/listbrands/{cid}")
public R getBrandsByCategoryId(@PathVariable("cid") int cid){
return productService.listBrands(cid);
}边栏推荐
- Part of speech list of common words
- 建木持续集成平台v2.5.2发布
- Pandas' to_ SQL function usage
- EN 1155 building hardware swing door opener - CE certification
- Openstack login dashboard prompt authentication error
- 【npm】 无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。
- 你有没有在MySQL的order by上栽过跟头
- Class not found: "the com.parkmanagement.dao.daotest test cannot find the test class
- 2021.7.13 note sub query
- MySQL learning Day1 DDL, DML, DQL basic query
猜你喜欢

2021.7.12 internal and external connection of notes

Uniapp H5 cross domain problem

文件的上传和下载

如何实现Word、PDF、TXT文件的全文内容检索?

Generate PDM file from Navicat export table

Idea packaging war package and war package location

2021.8.1 Notes database design

Knowledge map - Jieba, pyhanlp, smoothnlp tools to realize Chinese word segmentation (part of speech)

LED学习护眼台灯触摸芯片-DLT8T10S-杰力科创

10 SQL optimization schemes summarized by Alibaba P8 (very practical)
随机推荐
Wechat applet multi file upload
Login page tablelayout
Uni app for wechat login (to be finished)
Uni app traversal array rendering data vertical rendering
LED带风扇护眼学习台灯触摸芯片-DLT8S12A
兆骑科创海内外引进高层次人才,创新创业项目对接
[yuntu said] 249 mobile application security service - app's physical examination center, comprehensive testing, safe on the road!
Build a simple knowledge question and answer system
V-bind and V-for
filebeat.yml配置文件关于多个服务的配置问题
MySQL basic statement
Join query and subquery
2021.7.28 notes
mysql视图基本操作
解决Jsp级联问题
MySQL set validate_ Adding skip grant tables after password=off failed to start the service
智能失眠治疗仪产品-DLT8P68SA-杰力科创
图文结合,完美解释MySQL逻辑备份的实现流程
Commonly used built-in methods of mybtis plus
Hbuilder submission code