一、場景需求
適用場景如簽到送積分、簽到領取獎勵等,大致需求如下:
- 比如簽到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)