1. 程式人生 > >小程式 訂單倒計時系列

小程式 訂單倒計時系列

最近專案遇到了 一個小問題, 當訂單需要支付的時候 , 超過指定時間  自動關閉這個訂單, 未到達訂單結束時間時 , 需要顯示訂單還有多久關閉, 如下圖:

寫出的這個方法支援多個物件, 看到技術群有很多人問這個問題  而沒有人回答 , 決定把這個解決方案貢獻出來(不知道算不算好得解決方案)

我的解決方案是: 後臺給出訂單的結束時間  然後再去請求伺服器當前的時間  互相轉換成時間戳 然後相減  得出的結果是 xxx毫秒 然後 / 1000 就是真正的相差時間了

JS檔案

page({
    data: {
    
    },
    onLoad: function(){
        var that = this; // this 的指向性問題  需要在function 外儲存
        wx.request({
            url: 'xxx',
            data: {xxx},
            success: function(result){
                that.setData({
                    dataSourcesArray: result.data.order // 請求到的資料
                });
                /**
                *  result.data.order 是 請求所有的訂單資訊
                *  serviceTime 是封裝好的請求方法
                *  伺服器的時間格式是   2018/08/01 17:35:08
                *
                *  itemIndex 是防止列表 中的某一條資料已經被購買而導致修改資料時的錯亂
                *
                */
                that.serviceTime(function (res) {
                    // 伺服器的時間戳
                    var nowYear = res.data.serviceTime.split(' ')[0];
                    var nowTime = new Date(res.data.serviceTime).getTime();
                    //  這裡傳入只有未結束的訂單
                    var orderDetail = [];
                    for (var i = 0; i < result.data.order.length; i++) { 
                        // 如果訂單未過期狀態
                        if (result.data.order[i].state == '待付款') {
                            result.data.order[i].itemIndex = i; 
                            orderDetail.push(result.data.order[i]);
                        }
                    }
                    result.data.order = orderDetail;
                    that.operation(result);// 待付款的訂單傳入這個方法內
                });
            }
        })
    },
    /*
        * 這裡應該不要用setInterval  應該用 setTimeout 的  避免造成 網路阻塞
    */
    operation: function(result) { // 接收到沒有結束的訂單資訊
        var that = this;
        time = setInterval(function () { // 迴圈執行
            that.serviceTime(function(res) {// 獲取伺服器時間
                that.resetState(res, result); // 設定未到結束時間訂單的狀態
            });
        }, 1000);
    },
    // 設定未結束訂單的狀態
    /*
        ** res   請求獲取伺服器的時間的結果集
        ** dataSourcesArray 是顯示頁面的訂單資訊
    */
    resetState: function(res, result) {
        var nowTime = new Date(res.data.serviceTime).getTime();// 當前時間的時間戳

        for (let i = 0; i < result.data.order.length; i++) { // 迴圈新增 倒計時
            var index = result.data.order[i].itemIndex;
            var status = "dataSourcesArray[" + index  + "]." + 'state';
            var showTime = "dataSourcesArray[" + index  + "]." + 'showTime';
            var futureTime = new Date(result.data.order[i].expiryTime).getTime();
            // 未來的時間減去現在的時間 ;
            var resTime = (futureTime - nowTime) / 1000;
            // 結束時間
            var zero = futureTime - nowTime;
            if (zero >= 0) { // 認為還沒有到達結束的時間
                var timeSeconds = timestampToTime(resTime);
                this.setData({
                    [showTime]: timeSeconds
                })
            } else { // 結束的時間已經到了
                result.data.order.splice(i, 1); // 該訂單自動結束時間 從這個列表中刪除  就不必老是迴圈他
                this.setData({
                    [showTime]: "超過時間  訂單已經關閉",
                    [status]: "訂單過期"
                });
            }

            if(result.data.order.length == 0){// 如果沒有可支付訂單 則停止這個訂單
                clearInterval(time);
            }
        }
    }
})

// 時間轉換
function timestampToTime(s) {
    var h = Math.floor(s / 3600 % 24);
    var min = Math.floor(s / 60) % 60;
    var sec = s % 60;
    h = add(h);
    min = add(min);
    sec = add(sec);
    return h + ':' + min + ':' + sec
}

// 添 0
function add(m) {
    return m < 10 ? '0' + m : m
}

 wxml檔案

<!-- 如果是待付款狀態則會顯示倒計時 -->
<view wx:for="{{dataSourcesArray}}" wx:for-item="item" wx:key="key">
    <view wx:if="{{item.state == '待付款'}}" class="showTime">
        <text class="title">剩餘支付時間</text>
        <text class="content">{{item["showTime"]}}</text>
    </view>
</view>

最終效果圖 如下(支援多個列表):

(當頁面離開時  應該清除這個定時器  頁面進來時也要觸發!)

QQ微信技術群: 561696357