Selaa lähdekoodia

推送到队列,以及队列任务

lizhen_gitee 6 kuukautta sitten
vanhempi
commit
fb5df1d951

+ 5 - 28
app/Controller/Api/v1/PlayerController.php

@@ -13,6 +13,7 @@ use Hyperf\DbConnection\Db;
 use App\Request\Api\v1\Player\RecordRequest;
 use App\Master\Enum\RedisKeyEnum;
 use App\Utils\RedisUtil;
+use App\Service\QueueService;
 
 /**
  * 选手接口
@@ -23,6 +24,8 @@ class PlayerController extends AbstractController
     // 日志模块名称
     const LOG_MODULE = 'v1/PlayerController';
 
+    #[Inject]
+    protected QueueService $service;
 
     //给选手投票
     public function record(RecordRequest $request){
@@ -45,45 +48,19 @@ class PlayerController extends AbstractController
             return AppResult::response_fast($check_rs['code'],$check_rs['msg']);//给不同的code,0报错,2跳到答题
         }
 
-        Db::startTrans();
-
         //检查选手
-        $player_info = Db::name('vote_player')->field('id,subject_id,votes')->where(['id'=>$player_id])->lock(true)->find();
+        $player_info = Db::table('vote_player')->select('id,subject_id,votes')->where('id',$player_id)->first();
         if(!$player_info){
-            Db::rollback();
             return AppResult::error('不存在的选手');
         }
 
         //给选手加票
-        $update_data = [
-            'votes' => $player_info['votes'] + 1,
-        ];
-        $update_rs = Db::name('vote_player')->where('id',$player_id)->update($update_data);
-        if($update_rs === false){
-            Db::rollback();
-            $this->error('投票失败');
-        }
-
+        $this->service->playerPush(['player_id' => $player_id, 'user_id' => $user['id']], 0);
         //日志
-        $data = [
-            'user_id' => $user['id'],
-            'subject_id' => $player_info['subject_id'],
-            'player_id' => $player_id,
-            'createdate' => strtotime(date('Y-m-d')),
-            'createtime' => time(),
-        ];
-        $log_id = Db::name('vote_record')->insertGetId($data);
-        if(!$log_id){
-            Db::rollback();
-            $this->error('投票失败');
-        }
-
-        Db::commit();
 
         //今日投票次数,自增一次
         RedisUtil::getInstance(RedisKeyEnum::VOTE_RECORD.date('Y-m-d').':'.$user['id'])->incr_expire(86400);
 
-
         //剩余票数,
         $a = $check_rs['uservote'] - 1;
 

+ 80 - 0
app/Job/PlayerJob.php

@@ -0,0 +1,80 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Job;
+
+use App\Utils\LogUtil;
+use Hyperf\AsyncQueue\Job;
+use Hyperf\DbConnection\Db;
+
+class PlayerJob extends Job
+{
+    //日志板块
+    private const LOG_MODULE = 'PlayerJob';
+
+    public $params;
+
+    /**
+     * 任务执行失败后的重试次数,即最大执行次数为 $maxAttempts+1 次
+     */
+    protected int $maxAttempts = 2;
+
+    public function __construct($params)
+    {
+        // 这里最好是普通数据,不要使用携带 IO 的对象,比如 PDO 对象
+        $this->params = $params;
+    }
+
+    /**
+     * Execute the job.
+     *
+     * @return void
+     */
+    public function handle()
+    {
+        //日志统一写入
+        LogUtil::getInstance('Queues/');//设置日志存入通道
+        LogUtil::info('开始处理', self::LOG_MODULE, __FUNCTION__, ['params' => $this->params]);
+        // 根据参数处理具体逻辑
+        // 通过具体参数获取模型等
+        // 这里的逻辑会在 ConsumerProcess 进程中执行
+//        var_dump($this->params);
+
+        $this->recode($this->params['player_id'],$this->params['user_id']);
+
+        LogUtil::info('处理结果', self::LOG_MODULE, __FUNCTION__);
+        LogUtil::close();
+    }
+
+    public function recode($player_id,$user_id){
+        Db::beginTransaction();
+
+        //检查选手
+
+        //给选手加票
+        $update_rs = Db::table('vote_player')->where('id',$player_id)->increment('votes');
+        if($update_rs === false){
+            Db::rollBack();
+            return false;
+        }
+
+        //日志
+        $data = [
+            'user_id' => $user_id,
+            'subject_id' => 1,
+            'player_id' => $player_id,
+            'createdate' => strtotime(date('Y-m-d')),
+            'createtime' => time(),
+        ];
+        $log_id = Db::table('vote_record')->insertGetId($data);
+        if(!$log_id){
+            Db::rollBack();
+            return false;
+        }
+
+        Db::commit();
+        return true;
+
+    }
+}

+ 81 - 0
app/Job/QuestionJob.php

@@ -0,0 +1,81 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Job;
+
+use App\Utils\LogUtil;
+use Hyperf\AsyncQueue\Job;
+use Hyperf\DbConnection\Db;
+
+class QuestionJob extends Job
+{
+    //日志板块
+private const LOG_MODULE = 'QuestionJob';
+
+    public $params;
+
+    /**
+     * 任务执行失败后的重试次数,即最大执行次数为 $maxAttempts+1 次
+     */
+    protected int $maxAttempts = 2;
+
+    public function __construct($params)
+    {
+        // 这里最好是普通数据,不要使用携带 IO 的对象,比如 PDO 对象
+        $this->params = $params;
+    }
+
+    /**
+     * Execute the job.
+     *
+     * @return void
+     */
+    public function handle()
+    {
+        //日志统一写入
+        LogUtil::getInstance('Queues/');//设置日志存入通道
+        LogUtil::info('开始处理', self::LOG_MODULE, __FUNCTION__, ['params' => $this->params]);
+        // 根据参数处理具体逻辑
+        // 通过具体参数获取模型等
+        // 这里的逻辑会在 ConsumerProcess 进程中执行
+//        var_dump($this->params);
+
+        $this->submit($this->params['user_id'],$this->params['question_id'],$this->params['is_right'],$this->params['bind_player_id']);
+
+        LogUtil::info('处理结果', self::LOG_MODULE, __FUNCTION__);
+        LogUtil::close();
+    }
+
+    public function submit($user_id,$question_id,$is_right,$bind_player_id){
+        Db::beginTransaction();
+
+        //答题日志
+        $log = [
+            'user_id'     => $user_id,
+            'question_id' => $question_id,
+            'is_right'    => $is_right ? 1 : 0,
+            'player_id'   => $bind_player_id,
+            'createtime'  => time(),
+            'createdate'  => strtotime(date('Y-m-d')),
+        ];
+        $log_id = Db::table('user_question_log')->insertGetId($log);
+        if(!$log_id){
+            Db::rollBack();
+            return false;
+        }
+
+        if($is_right){
+            //给选手加分
+            $rs = Db::table('vote_player')->where('id',$bind_player_id)->increment('score');
+            if($rs === false){
+                Db::rollBack();
+                return false;
+            }
+        }
+
+        Db::commit();
+        return true;
+
+    }
+}

+ 16 - 36
app/Service/QueueService.php

@@ -4,11 +4,10 @@ declare(strict_types=1);
 
 namespace App\Service;
 
-use App\Job\CancelOrderJob;
 use App\Job\DemoJob;
-use App\Job\DemoTwoJob;
-use App\Job\PushGeTuiJob;
-use App\Job\PushOrderJob;
+use App\Job\PlayerJob;
+use App\Job\QuestionJob;
+
 use Hyperf\AsyncQueue\Driver\DriverFactory;
 use Hyperf\AsyncQueue\Driver\DriverInterface;
 
@@ -34,47 +33,28 @@ class QueueService
         // 所以这里也不推荐使用 `make` 方法来创建 `Job` 对象。
         return $this->driver->push(new DemoJob($params), $delay);
     }
-
     /**
-     * 生产消息 02.
+     * 生产消息.
      * @param mixed $params 数据
      * @param int $delay 延时时间 单位秒
      */
-    public function demoTwoPush($params, int $delay = 0): bool
-    {
-        return $this->driver->push(new DemoTwoJob($params), $delay);
-    }
-
-    /**
-     * 加入提醒司机接单队列.
-     * @param array $params
-     * @param int $delay 延时时间 单位秒
-     * @return bool
-     */
-    public function pushOrder(array $params, int $delay = 0): bool
-    {
-        return $this->driver->push(new PushOrderJob($params), $delay);
-    }
-
-    /**
-     * 加入个推消息队列.
-     * @param array $params
-     * @param int $delay 延时时间 单位秒
-     * @return bool
-     */
-    public function pushGeTui(array $params, int $delay = 0): bool
+    public function playerPush($params, int $delay = 0): bool
     {
-        return $this->driver->push(new PushGeTuiJob($params), $delay);
+        // 这里的 `DemoJob` 会被序列化存到 Redis 中,所以内部变量最好只传入普通数据
+        // 同理,如果内部使用了注解 @Value 会把对应对象一起序列化,导致消息体变大。
+        // 所以这里也不推荐使用 `make` 方法来创建 `Job` 对象。
+        return $this->driver->push(new PlayerJob($params), $delay);
     }
-
     /**
-     * 加入订单超时取消消息队列.
-     * @param array $params
+     * 生产消息.
+     * @param mixed $params 数据
      * @param int $delay 延时时间 单位秒
-     * @return bool
      */
-    public function cancelOrder(array $params, int $delay = 0): bool
+    public function questionPush($params, int $delay = 0): bool
     {
-        return $this->driver->push(new CancelOrderJob($params), $delay);
+        // 这里的 `DemoJob` 会被序列化存到 Redis 中,所以内部变量最好只传入普通数据
+        // 同理,如果内部使用了注解 @Value 会把对应对象一起序列化,导致消息体变大。
+        // 所以这里也不推荐使用 `make` 方法来创建 `Job` 对象。
+        return $this->driver->push(new QuestionJob($params), $delay);
     }
 }