Browse Source

答题和投票优化逻辑,减少查询次数

lizhen_gitee 4 months ago
parent
commit
5acdb6bf27

+ 20 - 9
application/api/controller/Player.php

@@ -4,6 +4,8 @@ namespace app\api\controller;
 
 use app\common\controller\Api;
 use think\Db;
+use app\utils\RedisKeyEnum;
+use app\utils\RedisUtil;
 /**
  * 选手
  */
@@ -49,12 +51,20 @@ class Player extends Api
 
     //给选手投票
     public function record(){
+        if(!$this->apiLimit('操作太快了,休息一下吧'));
+
         $player_id = input('player_id','');
 
         if(!$player_id){
             $this->error();
         }
 
+        //登录用户票数的检查
+        $check_rs = $this->record_check($this->auth->id);
+        if($check_rs['status'] === false){
+            $this->error($check_rs['msg'],null,$check_rs['code']);//给不同的code,0报错,2跳到答题
+        }
+
         Db::startTrans();
 
         //检查选手
@@ -65,12 +75,6 @@ class Player extends Api
         }
         $subject_id = $player_info['subject_id'];
 
-        //大检查
-        $check_rs = $this->record_check($this->auth->id);
-        if($check_rs['status'] === false){
-            Db::rollback();
-            $this->error($check_rs['msg'],null,$check_rs['code']);//给不同的code,0报错,2跳到答题
-        }
 
         $update_data = [
             'votes' => $player_info['votes'] + 1,
@@ -97,6 +101,10 @@ class Player extends Api
         }
 
         Db::commit();
+
+        //今日投票次数,自增一次
+        RedisUtil::getInstance(RedisKeyEnum::VOTE_RECORD.date('Y-m-d').':'.$this->auth->id)->incr_expire(86400);
+
         $this->success('投票成功');
     }
 
@@ -110,7 +118,8 @@ class Player extends Api
 
 
         //今天,投了几票
-        $today_record = Db::name('vote_record')->where('createdate',strtotime(date('Y-m-d')))->where('user_id',$uid)->count();
+//        $today_record = Db::name('vote_record')->where('createdate',strtotime(date('Y-m-d')))->where('user_id',$uid)->count();
+        $today_record = RedisUtil::getInstance(RedisKeyEnum::VOTE_RECORD.date('Y-m-d').':'.$this->auth->id)->get();
         //今天,免费的的票
         $gift_votes = config('site.gift_votes_user_eday');
         //今天,免费的答题次数
@@ -125,7 +134,8 @@ class Player extends Api
         }
 
         //今天,用户答对的次数,也就是答题获得的票数
-        $question_vote  = Db::name('user_question_log')->where('createdate',strtotime(date('Y-m-d')))->where('user_id',$uid)->where('is_right',1)->count();
+//        $question_vote  = Db::name('user_question_log')->where('createdate',strtotime(date('Y-m-d')))->where('user_id',$uid)->where('is_right',1)->count();
+        $question_vote  = RedisUtil::getInstance(RedisKeyEnum::EAXM_RIGHT.date('Y-m-d').':'.$this->auth->id)->get();
 
         //投票次数  >= 免费票 + 答对次数
         if($today_record >= $gift_votes + $question_vote){
@@ -134,7 +144,8 @@ class Player extends Api
             $result['msg'] = '今天的票已经用光了,明天再来吧';
 
             //今天,用户答题的次数
-            $today_question = Db::name('user_question_log')->where('createdate',strtotime(date('Y-m-d')))->where('user_id',$uid)->count();
+//            $today_question = Db::name('user_question_log')->where('createdate',strtotime(date('Y-m-d')))->where('user_id',$uid)->count();
+            $today_question = RedisUtil::getInstance(RedisKeyEnum::EAXM_TIMES.date('Y-m-d').':'.$this->auth->id)->get();
 
             //还有答题机会
             if($exam_times > $today_question){

+ 25 - 8
application/api/controller/Question.php

@@ -4,6 +4,8 @@ namespace app\api\controller;
 
 use app\common\controller\Api;
 use think\Db;
+use app\utils\RedisKeyEnum;
+use app\utils\RedisUtil;
 /**
  * 答题
  */
@@ -55,10 +57,12 @@ class Question extends Api
     }
 
     /**
-     * 交卷
+     * 答题
      */
     public function submit()
     {
+        if(!$this->apiLimit('操作太快了,休息一下吧'));
+
         //上次绑定选手的时间不是今天
         if($this->auth->bind_player_date != strtotime(date('Y-m-d'))){
             $this->error('先绑定单位再答题',null,2);
@@ -66,7 +70,8 @@ class Question extends Api
 
         //检查今日答题次数
         $exam_times_user_eday = config('site.exam_times_user_eday');
-        $count = Db::name('user_question_log')->where('user_id',$this->auth->id)->where('createdate',strtotime(date('Y-m-d')))->count();
+//        $count = Db::name('user_question_log')->where('createdate',strtotime(date('Y-m-d')))->where('user_id',$this->auth->id)->count();
+        $count = RedisUtil::getInstance(RedisKeyEnum::EAXM_TIMES.date('Y-m-d').':'.$this->auth->id)->get();
         if($count >= $exam_times_user_eday){
             $this->error('今日答题次数用完了,明天再来吧');
         }
@@ -97,19 +102,31 @@ class Question extends Api
             $this->error('答题失败');
         }
 
-
         if($is_right){
-            $msg = '回答正确';
-
             //给选手加分
-            
+            $rs = Db::name('vote_player')->where('id',$this->auth->bind_player_id)->setInc('score');
+            if($rs === false){
+                Db::rollback();
+                $this->error('答题失败');
+            }
+        }
+
+        Db::commit();
 
+        //今日答题次数,自增一次
+        RedisUtil::getInstance(RedisKeyEnum::EAXM_TIMES.date('Y-m-d').':'.$this->auth->id)->incr_expire(86400);
+
+        if($is_right){
+            //今日答对次数,自增一次
+            RedisUtil::getInstance(RedisKeyEnum::EAXM_RIGHT.date('Y-m-d').':'.$this->auth->id)->incr_expire(86400);
+
+            $msg = '回答正确';
         }else{
+            //
+
             $msg = '回答错误';
         }
 
-        Db::commit();
-
         $this->success($msg);
     }
 

+ 5 - 23
application/common/controller/Api.php

@@ -13,8 +13,9 @@ use think\Request;
 use think\Response;
 use think\Route;
 use think\Validate;
-use Redis;
+
 use app\utils\LogUtil;
+use app\utils\RedisUtil;
 
 /**
  * API控制器基类
@@ -369,11 +370,11 @@ class Api
     /**
      * 接口请求限制
      * @param int $apiLimit
-     * @param int $apiLimitTime
+     * @param int $apiLimitTime 单位:秒(s)
      * @param string $key
      * @return bool | true:通过 false:拒绝
      */
-    public function apiLimit($apiLimit = 1, $apiLimitTime = 1000, $key = '')
+    public function apiLimit($apiLimit = 1, $apiLimitTime = 1, $key = '')
     {
         $userId = $this->auth->id;
         $controller = request()->controller();
@@ -383,28 +384,9 @@ class Api
             $key = strtolower($controller) . '_' . strtolower($action) . '_' . $userId;
         }
 
-        $redis = new Redis();
-        $redisconfig = config("redis");
-        $redis->connect($redisconfig["host"], $redisconfig["port"]);
-        if ($redisconfig['password']) {
-            $redis->auth($redisconfig['password']);
-        }
-        if($redisconfig['select'] > 0){
-            $redis->select($redisconfig['select']);
-        }
-
-        //
-        //指定键值新增+1 并获取
-        $count = $redis->incr($key);
-        if ($count > $apiLimit) {
+        if (!RedisUtil::getInstance($key)->tryTimes($apiLimit,intval($apiLimitTime))){
             return false;
         }
-
-        //设置过期时间
-        if ($count == 1) {
-            $redis->pExpire($key, $apiLimitTime);
-        }
-
         return true;
     }
 

+ 1 - 1
application/config.php

@@ -333,7 +333,7 @@ return [
         'expire'     => Env::get('redis.REDIS_EXPIRE', 0),
         'persistent' => (bool)Env::get('redis.REDIS_PERSISTENT', false),
         // 缓存前缀
-        'prefix'     => Env::get('redis.REDIS_PREFIX', 'rc:'),
+        'prefix'     => Env::get('redis.REDIS_PREFIX', 'toupiao:'),
     ],
 
     //后台网站配置

+ 3 - 0
application/utils/RedisKeyEnum.php

@@ -13,4 +13,7 @@ class RedisKeyEnum
     const TOKEN_ONCE               = 'TOKEN_ONCE:';              // 设置唯一token
     const TOKEN_TIME               = 'TOKEN_TIME:';              // 设置token时间
     const FA_SITE_SETUP            = 'FA_SITE_SETUP:';              // fastadmin site.php
+    const VOTE_RECORD              = 'VOTE_RECORD:';                     //用户今天投票次数
+    const EAXM_TIMES               = 'EAXM_TIMES:';                     //用户今天答题次数
+    const EAXM_RIGHT               = 'EAXM_RIGHT:';                     //用户今天答对次数
 }

+ 16 - 0
application/utils/RedisUtil.php

@@ -363,4 +363,20 @@ class RedisUtil
         $key   = $this->Key;
         return $redis->hGetAll($key);
     }
+
+    public function incr_expire($second)
+    {
+        $redis = $this->Redis;
+        $key   = $this->Key;
+        $count = $redis->incr($key);
+
+        //设置过期时间
+        if ($count == 1) {
+            $redis->expire($key, $second);
+        }
+
+        return $count;
+    }
+
+
 }