利用redis的bitmap實現用戶簽到功能


一、場景需求

適用場景如簽到送積分、簽到領取獎勵等,大致需求如下:

  • 比如簽到1天送1積分,連續簽到2天送2積分,3天送3積分,3天以上均送3積分等。
  • 如果連續簽到中斷,則重置計數,每月初重置計數。
  • 顯示用戶某個月的簽到次數和首次簽到時間。
  • 在日歷控件上展示用戶每月簽到情況,可以切換年月顯示……等等。

二、代碼

以下代碼沒有積分邏輯,只有簽到

import datetime
import redis

class Redis(object):
    def __init__(self):
        self.redis_store = redis.Redis(
            host="127.0.0.1",
            port="6379",
            db="8"
        )


class RedisSignIn(Redis):
    @staticmethod
    def GetDaliySignKey(time=datetime.datetime.now()):
        # 拼接redis的key
        bitmap_key_daily_sign = "daily_sign_{date}"
        return bitmap_key_daily_sign.format(date=time.date())

    def UserDailySign(self, session):
        user_id = session.get("user")
        if not user_id:
            print( "驗證失敗")
            return
        if self.UserDaliySignByUserId(user_id):
            rec = self.GetSignRecordByUserId(user_id, 7)
            l = len(rec.split('0')[0])
            print(l)
            # 連續簽到
            if l > 1:
                pass
            if l > 6:
                pass
        return
    # 獲取每月的簽到記錄
    def GetUserDailySignRecordMonthly(self, session):
        user_id = session.get("user")
        if not user_id:
            print( "驗證失敗")
            return
        res = self.GetSignRecordByUserId(user_id)
        print(int(res, 2))
        # 二進制數據轉換為10進制,拿到的10進制數返回到前端,前端再解析成二進制數進行判斷
        return int(res, 2)


    def GetSignRecordByUserId(self, user_id, days=30):
        # 開啟管道模擬事務
        with self.redis_store.pipeline(True) as p:
            for i in range(days):
                # 獲取key對應值的二進制表示中的某位的值
                p = p.getbit(self.GetDaliySignKey(datetime.datetime.now() - datetime.timedelta(days=i)), user_id)
            # execute返回命令執行結果列表
            res = p.execute()
            # res是一個[1,0,0,0...]的列表
            print(res)
            # 轉成字符串的二進制
            return ''.join([str(x) for x in res])

    # 通過user_id用戶做每日簽到
    def UserDaliySignByUserId(self, user_id):
        if self.GetDailySignByUserId(user_id):
            print( "今天您已簽到")
            return
        key = self.GetDaliySignKey()
        # key就是簽到日期,將該user_id在key對應的位置上設置為1,表示簽到了
        self.redis_store.setbit(key, user_id, 1)
        # 設置key的過期時間
        self.redis_store.expire(key, 60 * 60 * 24 * 30)
        return True

    # 通過user_id獲取用戶每日簽到信息
    def GetDailySignByUserId(self, user_id):
        return self.redis_store.getbit(self.GetDaliySignKey(), user_id)


if __name__ == '__main__':
    session={"user":1003}
    sign=RedisSignIn()
    sign.UserDailySign(session)
    sign.GetUserDailySignRecordMonthly(session)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM