国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

商城系統(tǒng)中30分鐘未付款自動取消訂單怎么實現(xiàn)(簡單幾種方法)

這篇具有很好參考價值的文章主要介紹了商城系統(tǒng)中30分鐘未付款自動取消訂單怎么實現(xiàn)(簡單幾種方法)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

商城系統(tǒng)中30分鐘未付款自動取消訂單怎么實現(xiàn)(簡單幾種方法),java,spring boot,商城

實現(xiàn)以上功能

方法1:定時任務(wù)批量執(zhí)行

寫一個定時任務(wù),每隔 30分鐘執(zhí)行一次,列出所有超出時間范圍得訂單id的列表

@Async
    @Scheduled(cron = "20 20 1 * * ?")
    public void cancelOrder(){
        log.info("【取消訂單任務(wù)開始】");
        QueryWrapper<Order> qw = new QueryWrapper<>();
        qw.eq("status", Constants.OrderStatus.NOTPAID);
        qw.eq("aftersale_status", 1);
        List<Order> orderList = orderMapper.selectList(qw);
        List<Long> idList = orderList.stream()
                .filter(order -> LocalDateTimeUtil.between(order.getCreateTime(), LocalDateTime.now()).toMinutes() >= 15)
                .map(Order::getId)
                .collect(Collectors.toList());
        CancelOrderRequest request = new CancelOrderRequest();
        request.setIdList(idList);
        h5OrderService.orderBatchCancel(request, null);
        log.info("【取消訂單任務(wù)結(jié)束】");
    }

批量執(zhí)行取消訂單操作

@Transactional
    public String orderBatchCancel(CancelOrderRequest request, Long userId) {
        LocalDateTime optDate = LocalDateTime.now();
        if (CollectionUtil.isEmpty(request.getIdList())) {
            throw new RuntimeException("未指定需要取消的訂單號");
        }
        QueryWrapper<Order> orderQw = new QueryWrapper<>();
        orderQw.in("id", request.getIdList());
        List<Order> orderList = orderMapper.selectList(orderQw);
        if (orderList.size() < request.getIdList().size()) {
            throw new RuntimeException("未查詢到訂單信息");
        }
        Order order = orderList.get(0);

        //查orderItem
        QueryWrapper<OrderItem> qw = new QueryWrapper<>();
        qw.in("order_id", request.getIdList());
        List<OrderItem> orderItems = orderItemMapper.selectList(qw);
        if (CollectionUtil.isEmpty(orderItems)) {
            throw new RuntimeException("未查詢到訂單信息");
        }
        long count = orderList.stream().filter(it -> !Constants.H5OrderStatus.UN_PAY.equals(it.getStatus())).count();
        if (count > 0) {
            throw new RuntimeException("訂單狀態(tài)已更新,請刷新頁面");
        }
        List<OrderOperateHistory> addHistoryList = new ArrayList<>();
        orderList.forEach(item -> {
            item.setStatus(Constants.H5OrderStatus.CLOSED);
            item.setUpdateTime(optDate);
            item.setUpdateBy(userId);
            OrderOperateHistory history = new OrderOperateHistory();
            history.setOrderId(item.getId());
            history.setOrderSn(item.getOrderSn());
            history.setOperateMan(userId == null ? "后臺管理員" : "" + item.getMemberId());
            history.setOrderStatus(Constants.H5OrderStatus.CLOSED);
            history.setCreateTime(optDate);
            history.setCreateBy(userId);
            history.setUpdateBy(userId);
            history.setUpdateTime(optDate);
            addHistoryList.add(history);
        });
        //取消訂單
        int rows = orderMapper.cancelBatch(orderList);
        if (rows < 1) {
            throw new RuntimeException("更改訂單狀態(tài)失敗");
        }
        orderItems.stream().collect(Collectors.groupingBy(it -> it.getSkuId())).forEach((k, v) -> {
            AtomicReference<Integer> totalCount = new AtomicReference<>(0);
            v.forEach(it -> totalCount.updateAndGet(v1 -> v1 + it.getQuantity()));
            skuMapper.updateStockById(k, optDate, -1 * totalCount.get());
        });
        //創(chuàng)建訂單操作記錄
        boolean flag = orderOperateHistoryService.saveBatch(addHistoryList);
        if (!flag) {
            throw new RuntimeException("創(chuàng)建訂單操作記錄失敗");
        }
        // 根據(jù)order 退還積分
        orderUsePointsService.refundOrderUsePoints(order.getId());
        return "取消訂單成功";
    }

方法2:使用jdk自帶的阻塞隊列

實現(xiàn)一個簡單的隊列,每隔一定時間執(zhí)行隊列。

/**
     * (30分鐘掃描三十分鐘內(nèi)需要發(fā)送的訂單)
     */
    @Scheduled(cron = "0 0/30 * * * ?")
    public void checkOrderStatus() {
        DelayQueue<ItemVo<Order>> queue = new DelayQueue<ItemVo<Order>>();
        try {
            // 插入訂單
            new Thread(new PutOrder(queue)).start();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

這里使用隊列的優(yōu)勢可以跟前端時間匹配上,前端讀秒幾秒這里就什么時候取消?



import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.toolkit.CollectionUtils;
import com.kxmall.market.biz.BeanContext;
import com.kxmall.market.data.dto.PrivatePlanAndDetailDO;
import com.kxmall.market.data.mapper.PrivatePlanMapper;
import com.kxmall.market.data.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.List;
import java.util.concurrent.DelayQueue;

/**
 * 模擬訂單插入的功能
 */

public class PutOrder implements Runnable {

    private static final Logger logger = LoggerFactory.getLogger(PutOrder.class);

    //    public static PutOrder putOrder;
    @Autowired
    private PrivatePlanMapper privatePlanMapper;

    // 使用DelayQueue:一個使用優(yōu)先級隊列實現(xiàn)的無界阻塞隊列。
    private DelayQueue<ItemVo<Order>> queue;

    public PutOrder(DelayQueue<ItemVo<Order>> queue) {
        super();
        this.queue = queue;
    }

    @Override
    public void run() {
        Date startTime = new Date();
        privatePlanMapper = BeanContext.getApplicationContext().getBean(PrivatePlanMapper.class);
        // 每隔半小時獲取半小時內(nèi)需要取消的
        List<PrivatePlanAndDetailDO> privatePlanDOS = privatePlanMapper.getPrivatePlanDetailList();
        logger.info("待取消清單->{}", JSON.toJSONString(privatePlanDOS));
        if (CollectionUtils.isNotEmpty(privatePlanDOS)) {
            privatePlanDOS.forEach(s -> {
                long count = DateUtil.calLastedTime(startTime,s.getTodoTime() )*1000;
                Order tbOrder = new Order(s.getId().toString(), 0.0);
                ItemVo<Order> itemVoTb = new ItemVo<Order>(count, tbOrder);
                queue.offer(itemVoTb);
                logger.info("訂單{}將在->{}秒后取消", s.getId().toString(),count/1000);
            });
            // 取出過期訂單的線程
            new Thread(new FetchOrder(queue)).start();
        }else {
            logger.info("沒有待發(fā)送訂單->");
        }
    }
}


import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
/**
 * 存到隊列里的元素
 * 支持延時獲取的元素的阻塞隊列,元素必須要實現(xiàn)Delayed接口。
 * 根據(jù)訂單有效時間作為隊列的優(yōu)先級
 * @param <T>
 */
public class ItemVo<T> implements Delayed{
    // 到期時間 單位:ms
    private long activeTime;
    // 訂單實體(使用泛型是因為后續(xù)擴(kuò)展其他業(yè)務(wù)共用此業(yè)務(wù)類)
    private T data;

    public ItemVo(long activeTime, T data) {
        super();
        // 將傳入的時間轉(zhuǎn)換為超時的時刻
        this.activeTime = TimeUnit.NANOSECONDS.convert(activeTime, TimeUnit.MILLISECONDS)
                + System.nanoTime();
        this.data = data;
    }

    public long getActiveTime() {
        return activeTime;
    }
    public T getData() {
        return data;
    }

    // 按照剩余時間進(jìn)行排序
    @Override
    public int compareTo(Delayed o) {
        // 訂單剩余時間-當(dāng)前傳入的時間= 實際剩余時間(單位納秒)
        long d = getDelay(TimeUnit.NANOSECONDS) - o.getDelay(TimeUnit.NANOSECONDS);
        // 根據(jù)剩余時間判斷等于0 返回1 不等于0
        // 有可能大于0 有可能小于0  大于0返回1  小于返回-1
        return (d == 0) ? 0 : ((d > 0) ? 1 : -1);
    }

    // 獲取剩余時間
    @Override
    public long getDelay(TimeUnit unit) {
        // 剩余時間= 到期時間-當(dāng)前系統(tǒng)時間,系統(tǒng)一般是納秒級的,所以這里做一次轉(zhuǎn)換
        long d = unit.convert(activeTime-System.nanoTime(), TimeUnit.NANOSECONDS);
        return d;
    }

}

方法3:分布式場景(mq隊列)

使用mq隊列,消費消息。如果消息到達(dá)30分鐘沒有付款,那么就取消

方法4:分布式場景(redis)

使用redis商品下單,設(shè)置過期時間 30分鐘,并且寫一個redis監(jiān)聽器,監(jiān)聽過期需要操作的key,然后判單是否過期文章來源地址http://www.zghlxwxcb.cn/news/detail-820794.html

到了這里,關(guān)于商城系統(tǒng)中30分鐘未付款自動取消訂單怎么實現(xiàn)(簡單幾種方法)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 超簡單的RabbitMq實現(xiàn)訂單超時自動取消

    超簡單的RabbitMq實現(xiàn)訂單超時自動取消

    很簡單的實現(xiàn)方法,大家?guī)兔纯茨懿荒芾^續(xù)完善。 步驟: 添加rabbitmq配置 添加rabbitmq配置類 添加訂單生產(chǎn)者 添加訂單消費者(修改狀態(tài)) 1、添加rabbitmq配置 注意一定要開啟手動應(yīng)答,不然可能會報錯 2、添加rabbitmq配置類 下面這段代碼看著有點繁瑣,我解釋一下邏輯關(guān)系

    2024年02月11日
    瀏覽(25)
  • 訂單超時自動取消的技術(shù)方案解析及代碼實現(xiàn)

    訂單超時自動取消的技術(shù)方案解析及代碼實現(xiàn)

    訂單超時自動取消是電商平臺中常見的功能之一,例如在淘寶、京東、拼多多等商城下單后,如果在一定的時間內(nèi)沒有付款,那么訂單會自動被取消,是怎么做到的呢?作為技術(shù)人員我們應(yīng)該了解自動取消的原理和實現(xiàn)邏輯,本文將介紹幾種常用的技術(shù)方案,幫助開發(fā)者實現(xiàn)

    2024年02月16日
    瀏覽(26)
  • SpringBoot+RabbitMQ實現(xiàn)超時未支付訂單自動取消,localhost:15672沒有登錄頁面。

    SpringBoot+RabbitMQ實現(xiàn)超時未支付訂單自動取消,localhost:15672沒有登錄頁面。

    簡介 安裝RabbitMQ需要安裝Erlang/OTP,并保持版本匹配。 RabbitMQ官網(wǎng):RabbitMQ: One broker to queue them all | RabbitMQ RabbitMQ與Erlang/OTP版本對照表:Erlang Version Requirements | RabbitMQ Erlang官網(wǎng)下載:Downloads - Erlang/OTP 1.Windows上安裝RabbitMQ前需要安裝Erlang。(下載安裝不做敘述,除了需要自定義安

    2024年04月15日
    瀏覽(19)
  • Django圖書商城系統(tǒng)實戰(zhàn)開發(fā)-實現(xiàn)訂單管理

    在本教程中,我們將繼續(xù)基于Django框架開發(fā)圖書商城系統(tǒng),這次的重點是實現(xiàn)訂單管理功能。訂單管理是一個電子商務(wù)系統(tǒng)中非常重要的部分,它涉及到用戶下單、支付、發(fā)貨以及訂單狀態(tài)的管理等方面。通過學(xué)習(xí)本教程,您將了解如何使用Django框架來構(gòu)建強(qiáng)大的訂單管理系

    2024年02月12日
    瀏覽(25)
  • App支付報錯"商家訂單參數(shù)異常,請重新發(fā)起付款"排查流程

    ? 今天在對接支付寶 APP 支付的時候遇到了一個報錯,記錄下問題的排查過程~ ? ? APP 中彈窗提示的報錯“商家訂單參數(shù)異常,請重新發(fā)起付款”,檢查了下參數(shù)感覺沒啥問題,不知道是啥問題導(dǎo)致的。 ? 去官網(wǎng)搜了下,折騰排查了一遍,發(fā)現(xiàn)是環(huán)境問題,沙箱環(huán)境沒有切回

    2024年02月07日
    瀏覽(36)
  • 帝國CMS商城系統(tǒng)實現(xiàn)在線支付后發(fā)送訂單郵件提醒功能

    本文實例講述了帝國CMS商城系統(tǒng)實現(xiàn)在線支付后發(fā)送訂單郵件提醒功能。分享給大家供大家參考,具體如下: 帝國CMS是個強(qiáng)大的內(nèi)容管理系統(tǒng),其商城的功能也很強(qiáng)大,當(dāng)用戶下單,支付后我們怎么知道有用戶下單了呢?因為我們不能時時刻刻都在網(wǎng)站后臺,不斷的刷新頁面去看

    2023年04月24日
    瀏覽(91)
  • Spring Boot + Vue + Element UI的網(wǎng)上商城后臺管理之訂單管理系統(tǒng)

    以下是訂單管理系統(tǒng)的思維導(dǎo)圖,展示了系統(tǒng)的主要功能和模塊之間的關(guān)系。 根節(jié)點 訂單列表 查看訂單列表 搜索訂單 排序訂單 導(dǎo)出訂單列表 訂單詳情 查看訂單詳情 修改訂單信息 修改商品信息 修改價格 修改收貨地址 取消訂單 處理訂單 處理訂單操作 確認(rèn)訂單 拒絕訂單

    2024年02月03日
    瀏覽(40)
  • 怎么取消手機(jī)APP自動續(xù)費?詳細(xì)方法來了,輕松易懂

    怎么取消手機(jī)APP自動續(xù)費?詳細(xì)方法來了,輕松易懂

    在使用手機(jī)上網(wǎng)的時候,無論是游戲、外賣、看視頻、聽音樂等等,都擁有會員服務(wù)。每次開通會員的時候,平臺會推出一種優(yōu)惠政策,只需要同意自動續(xù)費的服務(wù),就能夠以極低的價格開通會員服務(wù)??僧?dāng)自己不再需要會員的時候, 怎么取消手機(jī)APP自動續(xù)費呢? 其實很簡

    2024年02月09日
    瀏覽(17)
  • 支付超時取消訂單實現(xiàn)方案 - 定時任務(wù)、延遲隊列、消息隊列等

    支付超時取消訂單實現(xiàn)方案 - 定時任務(wù)、延遲隊列、消息隊列等

    在實際業(yè)務(wù)場景中,我們經(jīng)常會碰到類似一下場景: 淘寶等購物平臺在訂單支付時,如果30分鐘內(nèi)未支付自動取消。 騰訊會議預(yù)約會議后,在會議開始前15分鐘提醒。 未使用的優(yōu)惠券有效期結(jié)束后,自動將優(yōu)惠券狀態(tài)更新為已過期。 等等。。。 像這種支付超時取消的場景需

    2024年04月22日
    瀏覽(33)
  • tp6的runtime/Logs目錄下產(chǎn)生大量日記文件,怎么取消自動生成?

    tp6的runtime/Logs目錄下產(chǎn)生大量日記文件,怎么取消自動生成?

    一開始查了好多網(wǎng)上提供的,很幸運都是抄襲別人的,沒一個成功,最后無奈只能自己解決方法 其實很簡單,不用修改config/log.php文件,沒用因為只要有登入錯誤,警告,消息或者sql錯誤都會寫入 解決方法: 關(guān)閉調(diào)試模式 配置數(shù)據(jù)庫文件 ?.env文件 true改為false即可 ?總結(jié):

    2024年02月16日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包