当前位置:网站首页>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);
}边栏推荐
- Was not registered for synchronization because synchronization is not active[resolved]
- What if MySQL database forgets its password???
- JS tool - Cookie simple encapsulation
- Knowledge map - Jieba, pyhanlp, smoothnlp tools to realize Chinese word segmentation (part of speech)
- 2021.7.30 note index
- The hero of the aircraft war comes out with bullets
- 如何实现Word、PDF、TXT文件的全文内容检索?
- TS learning notes interface
- was not registered for synchronization because synchronization is not active[已解决]
- 商品名称模糊搜索:
猜你喜欢

How to realize the full-text content retrieval of word, PDF and txt files?

MySQL learning Day1 DDL, DML, DQL basic query

Visual studio code installation tutorial (super detailed)

Complete set of machine learning classification task effect evaluation indicators (including ROC and AUC)

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

uniapp运行到手机(真机调试)

你有没有在MySQL的order by上栽过跟头

MySQL 主从复制数据不一致,怎么办?

Have you ever stumbled on MySQL's order by

机器学习分类任务效果评估指标大全(包含ROC和AUC)
随机推荐
Mode= "widthfix" attribute in image tag
Have you ever stumbled on MySQL's order by
"MySQL things" explains the indexing principle in detail
2021.8.1 notes DBA
微信支付及支付回调
2021.7.13 note sub query
我人都傻了,CompletableFuture和OpenFegin一起使用竟然报错
浴室带除雾化妆镜触摸芯片-DLT8T10S
C basic concepts list description suggestions collection
Using Jieba and pyhanlp tools to extract keyword words and sentences
2021.7.31 note view
The second parameter of fragmenttransaction.replace reports an error
知识图谱 — pyhanlp实现命名体识别(附命名体识别代码)
The hero of the aircraft war comes out with bullets
How to realize the full-text content retrieval of word, PDF and txt files?
订单的提交
Knowledge map - Jieba, pyhanlp, smoothnlp tools to realize Chinese word segmentation (part of speech)
Jianmu continuous integration platform v2.5.2 release
你有没有在MySQL的order by上栽过跟头
Wechat applet multi file upload