From 29d521d74498e37631c0466de96b3070cc725992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=9D=BE?= <8605635+zhang3064194730@user.noreply.gitee.com> Date: Fri, 15 Aug 2025 10:15:48 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=BC=E5=AE=B9=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 18 -- app/api/model/Orders.php | 8 +- app/command/SpinningTask3.php | 2 +- app/controller/IndexController.php | 180 +------------------ app/functions.php | 13 +- app/queue/ActivitiesQueue.php | 20 --- app/queue/BaseQueue.php | 30 ---- app/queue/DiscCompensateJob.php | 26 --- app/queue/redis/ActivitiesQueue.php | 18 ++ app/queue/redis/BaseQueue.php | 37 ++++ app/queue/redis/DiscCompensateJob.php | 16 ++ app/queue/{ => redis}/DiscReceiveQueue.php | 4 +- app/queue/{ => redis}/UserPushQueue.php | 7 +- app/utils/WuYouPayUtils.php | 16 +- composer.json | 1 + config/plugin/webman/redis-queue/app.php | 4 + config/plugin/webman/redis-queue/command.php | 7 + config/plugin/webman/redis-queue/log.php | 32 ++++ config/plugin/webman/redis-queue/process.php | 11 ++ config/plugin/webman/redis-queue/redis.php | 21 +++ public/.htaccess | 0 public/nginx.htaccess | 6 + 22 files changed, 185 insertions(+), 292 deletions(-) delete mode 100644 .env.example delete mode 100644 app/queue/ActivitiesQueue.php delete mode 100644 app/queue/BaseQueue.php delete mode 100644 app/queue/DiscCompensateJob.php create mode 100644 app/queue/redis/ActivitiesQueue.php create mode 100644 app/queue/redis/BaseQueue.php create mode 100644 app/queue/redis/DiscCompensateJob.php rename app/queue/{ => redis}/DiscReceiveQueue.php (95%) rename app/queue/{ => redis}/UserPushQueue.php (70%) create mode 100644 config/plugin/webman/redis-queue/app.php create mode 100644 config/plugin/webman/redis-queue/command.php create mode 100644 config/plugin/webman/redis-queue/log.php create mode 100644 config/plugin/webman/redis-queue/process.php create mode 100644 config/plugin/webman/redis-queue/redis.php create mode 100644 public/.htaccess create mode 100644 public/nginx.htaccess diff --git a/.env.example b/.env.example deleted file mode 100644 index 55d4215..0000000 --- a/.env.example +++ /dev/null @@ -1,18 +0,0 @@ -APP_DEBUG = true -URL = http://192.168.1.43:1333/ - -DEFAULT_TIMEZONE = Asia/Shanghai - -default_lang = zh-cn - - -HOSTNAME = rm-gc712o11yndj78x6a6o.mysql.cn-chengdu.rds.aliyuncs.com -USERNAME = video_user -PASSWORD = VideoUser@1 -HOSTPORT = 3306 - -SLAVE_HOSTNAME = rm-gc712o11yndj78x6a6o.mysql.cn-chengdu.rds.aliyuncs.com -SLAVE_USERNAME = video_user -SLAVE_PASSWORD = VideoUser@1 -SLAVE_HOSTPORT = 3306 - diff --git a/app/api/model/Orders.php b/app/api/model/Orders.php index cc05ffa..e992679 100644 --- a/app/api/model/Orders.php +++ b/app/api/model/Orders.php @@ -199,10 +199,10 @@ class Orders extends BaseModel // TODO 异步领取奖励 -// pushQueue(ActivitiesQueue::class, [ -// 'userInfo' => $userInfo, -// 'sourceUser' => $byUser -// ], 1); + pushQueue(ActivitiesQueue::class, [ + 'userInfo' => $userInfo, + 'sourceUser' => $byUser + ], 1); DatabaseRoute::transactionXa(function () use ($userInfo, $byUser, $userId) { self::activities($userInfo, $byUser); }); diff --git a/app/command/SpinningTask3.php b/app/command/SpinningTask3.php index 0536372..79b78b0 100644 --- a/app/command/SpinningTask3.php +++ b/app/command/SpinningTask3.php @@ -3,7 +3,7 @@ namespace app\command; use app\common\library\DatabaseRoute; -use app\queue\DiscCompensateJob; +use app\queue\redis\DiscCompensateJob; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; diff --git a/app/controller/IndexController.php b/app/controller/IndexController.php index fd81188..b829484 100644 --- a/app/controller/IndexController.php +++ b/app/controller/IndexController.php @@ -7,187 +7,21 @@ use app\api\model\CourseDetails; use app\api\model\TbUser; use app\common\library\DatabaseRoute; use app\model\Test; +use app\queue\redis\ActivitiesQueue; use support\Request; use think\facade\Db; +use Webman\RedisQueue\Client; class IndexController { public function index(Request $request) { - \support\Log::info('来了' . date('Y-m-d H:i:s')); - $get['courseId'] = $course_id = '1877654905222135809'; - $user['user_id'] = $user_id = '14240'; - $user = DatabaseRoute::getDb('tb_user', $user_id)->find(); - try { - if(empty($get['courseId'])) { - return json('参数不完整'); - } - $courseId = $get['courseId']; - // 获取短剧详情 - $dd_b = Db::connect('duanju_slave'); - $db_name = $dd_b->name('course'); - $bean = $db_name->where(['course_id' => $courseId])->find(); - if(!$bean) { - return json('短剧不存在'); - } +// Client::send('test', [], 0); - - $courseCollect = DatabaseRoute::getDb('course_collect', $user_id) - ->where(['course_id' => $course_id]) - ->where(['user_id' => $user_id]) - ->where(['classify' => 3]) - ->limit(1) - ->find(); - - - - // 是否追剧 - $collect = DatabaseRoute::getDb('course_collect', $user_id) - ->where(['course_id' => $course_id]) - ->where(['classify' => 1]) - ->limit(1) - ->find(); - - - - - - $db = Db::connect(config('think-orm.search_library')); - $userVip = $db->name('user_vip')->where(['user_id' => $user['user_id']])->find(); - - if ($userVip) { - $user['member'] = $userVip['is_vip']; - $user['end_time'] = $userVip['end_time']; - } - - - - - $userInfo = $user; - - - - - - - if (!empty($userInfo['member']) && $userInfo['member'] == 2) { - $isVip = true; - }else{ - $isVip = false; - } - - - - - - - // 查询用户是否购买了整集 - $courseUser = DatabaseRoute::getDb('course_user', $user_id) - ->where(['course_id' => $course_id]) - ->where(['classify' => 1]) - ->find(); - - - - // 每天购买超过上限,获得免费时间段资格 - $freeWatch = Test::checkFreeWatchPayCount($user['user_id']); - - $startSort = 0; - $endSort = 5; - $dn_course_details = DatabaseRoute::getDb('course_details', ['course_id' => $courseId]); - $sort = null; - if (is_null($sort)) { - - if (!empty($courseCollect)) { - $courseDetails = $dn_course_details->field('sort') - ->where('course_details_id', $courseCollect['course_details_id']) - ->limit(1) - ->find(); - $sort = $courseDetails['sort']; - } - } - - if ($freeWatch || !empty($courseUser)) { - $courseDetailsSetVos = Test::courseSets($courseId, 2, null); - } else { - $courseDetailsSetVos = Test::courseSets($courseId, 1, $bean['wholesale_price']); - } - - // 调整集数范围 - if (!is_null($sort) && $sort > 2) { - $startSort = $sort - 3; - $endSort = $sort + 3; - if (count($courseDetailsSetVos) < $endSort) { - $startSort = count($courseDetailsSetVos) - 5; - $endSort = count($courseDetailsSetVos) + 1; - } - } - - // 已购买剧集ID集合 - $detailsId = []; - if (!$freeWatch) { - $det_db = Db::connect(DatabaseRoute::getConnection('course_user', ['user_id' => $user['user_id']])); - $detailsId = $det_db->name('course_user')->where(['course_id' => $courseId, 'classify' => 2])->column('course_details_id'); - $det_db->close(); - $detailsId = array_flip(array_flip($detailsId)); // 去重 - \support\Log::info('啦啦啦' . date('Y-m-d H:i:s')); - } - // 处理剧集列表 - $current = null; - foreach ($courseDetailsSetVos as &$s) { - $s['wholesalePrice'] = (int) $s['wholesalePrice']; - // 当前播放集 - if (!empty($courseCollect) && $s['courseDetailsId'] == $courseCollect['course_details_id']) { - $s['current'] = 1; - $current = &$s; - } - - // 非免费用户的权限控制 - if ( - !$freeWatch && - $s['sort'] > 3 && - (empty($detailsId) || !in_array($s['courseDetailsId'], $detailsId)) && - empty($courseUser) && - !$isVip - ) { - $s['videoUrl'] = null; - } - - // 检查是否已点赞 - if ($s['sort'] > $startSort && $s['sort'] < $endSort) { - $isGood_db = Db::connect(DatabaseRoute::getConnection('course_collect', ['user_id' => $user['user_id']])); - $isGood = $isGood_db->name('course_collect') - ->where('course_details_id', $s['courseDetailsId']) - ->where('classify', 2) - ->limit(1) - ->count(); - $isGood_db->close(); - $s['isGood'] = empty($isGood) || $isGood == 0 ? 0 : 1; - } - } - - // 如果没有当前播放集,默认第一集 - if (empty($current) && !empty($courseDetailsSetVos)) { - $courseDetailsSetVos[0]['current'] = 1; - $current = &$courseDetailsSetVos[0]; - } - Test::setCourseView($bean); - - $price = ($freeWatch ? 0 : ($bean['price'] ?? 0)); - $price = bccomp($price, '0', 2) <= 0 ? 0 : $price; - // 返回结果 - $map = [ - 'current' => $current, - 'price' => $price, - 'title' => $bean['title'], - 'collect' => empty($collect) || $collect == 0 ? 0 : 1, - 'list' => $courseDetailsSetVos - ]; - \support\Log::info('即将返回' . date('Y-m-d H:i:s')); - return json($map); - } catch (\Exception $e) { - return json($e->getMessage()); - } + pushQueue(ActivitiesQueue::class, [ + 'userInfo' => 1, + 'sourceUser' => 1 + ], 1); } public function view(Request $request) diff --git a/app/functions.php b/app/functions.php index a138b5c..d5f2f49 100644 --- a/app/functions.php +++ b/app/functions.php @@ -1,7 +1,9 @@ uuid(), ]; - Log::info("消息队列发送消息,对列名: $class, 携带数据: ".json_encode($data).', 延时时间: '.$seconds); - if ($seconds > 0) { - Queue::later($seconds, $class, $data); - }else{ - Queue::push($class, $data); - } + Log::info("消息队列发送消息,对列名: $queue, 携带数据: ".json_encode($data).', 延时时间: '.$seconds); + // 投递延迟消息,消息会在60秒后处理 + Client::send($queue, $data, $seconds); } if(!function_exists('daysBetween')) { diff --git a/app/queue/ActivitiesQueue.php b/app/queue/ActivitiesQueue.php deleted file mode 100644 index 12d8032..0000000 --- a/app/queue/ActivitiesQueue.php +++ /dev/null @@ -1,20 +0,0 @@ -run($job, $data); - Log::info("消息队列执行成功:" . static::class); - $job->delete(); - } catch (\Throwable $e) { - Log::error("消息队列执行异常:" . $e->getMessage()); - Log::info($e->getTraceAsString()); - $job->release(10); // 或 $job->fail() - } - - $end = microtime(true); - Log::info("消息队列执行完毕, 耗时:" . ($end - $start) . 's'); - } - - // 子类实现具体逻辑 - abstract public function run(Job $job, $data); -} \ No newline at end of file diff --git a/app/queue/DiscCompensateJob.php b/app/queue/DiscCompensateJob.php deleted file mode 100644 index 47fcb3e..0000000 --- a/app/queue/DiscCompensateJob.php +++ /dev/null @@ -1,26 +0,0 @@ -delete(); // 处理成功删除任务 - } catch (\Exception $e) { - if ($job->attempts() < 3) { - $job->release(5); // 重试3次,间隔5秒 - } else { - $job->delete(); - Log::error("大转盘补偿任务最终失败:ID={$data['id']}"); - } - } - } -} \ No newline at end of file diff --git a/app/queue/redis/ActivitiesQueue.php b/app/queue/redis/ActivitiesQueue.php new file mode 100644 index 0000000..1d327df --- /dev/null +++ b/app/queue/redis/ActivitiesQueue.php @@ -0,0 +1,18 @@ +queue = class_basename(static::class); + Log::info("消息队列启动成功,".$this->queue); + } + + public function consume( $data) + { + $start = microtime(true); + Log::info("消息队列接收到消息,当前队列: ".self::class.", 携带数据: ".json_encode($data)); + $this->run($data); + $end = microtime(true); + Log::info("消息队列执行完毕, 耗时:" . ($end - $start) . 's'); + } + + public function onConsumeFailure(\Throwable $e, $package) + { + Log::error("消息队列执行异常:" . $e->getMessage()); + Log::info($e->getTraceAsString()); + } + + // 子类实现具体逻辑 + abstract public function run($data); +} \ No newline at end of file diff --git a/app/queue/redis/DiscCompensateJob.php b/app/queue/redis/DiscCompensateJob.php new file mode 100644 index 0000000..3186262 --- /dev/null +++ b/app/queue/redis/DiscCompensateJob.php @@ -0,0 +1,16 @@ + true, +]; \ No newline at end of file diff --git a/config/plugin/webman/redis-queue/command.php b/config/plugin/webman/redis-queue/command.php new file mode 100644 index 0000000..8bfe2a1 --- /dev/null +++ b/config/plugin/webman/redis-queue/command.php @@ -0,0 +1,7 @@ + + * @copyright walkor + * @link http://www.workerman.net/ + * @license http://www.opensource.org/licenses/mit-license.php MIT License + */ + +return [ + 'default' => [ + 'handlers' => [ + [ + 'class' => Monolog\Handler\RotatingFileHandler::class, + 'constructor' => [ + runtime_path() . '/logs/redis-queue/queue.log', + 7, //$maxFiles + Monolog\Logger::DEBUG, + ], + 'formatter' => [ + 'class' => Monolog\Formatter\LineFormatter::class, + 'constructor' => [null, 'Y-m-d H:i:s', true], + ], + ] + ], + ] +]; diff --git a/config/plugin/webman/redis-queue/process.php b/config/plugin/webman/redis-queue/process.php new file mode 100644 index 0000000..c8d4da1 --- /dev/null +++ b/config/plugin/webman/redis-queue/process.php @@ -0,0 +1,11 @@ + [ + 'handler' => Webman\RedisQueue\Process\Consumer::class, + 'count' => 8, // 可以设置多进程同时消费 + 'constructor' => [ + // 消费者类目录 + 'consumer_dir' => app_path() . '/queue/redis' + ] + ] +]; \ No newline at end of file diff --git a/config/plugin/webman/redis-queue/redis.php b/config/plugin/webman/redis-queue/redis.php new file mode 100644 index 0000000..6abf860 --- /dev/null +++ b/config/plugin/webman/redis-queue/redis.php @@ -0,0 +1,21 @@ + [ + 'host' => 'redis://127.0.0.1:6379', + 'options' => [ + 'auth' => null, + 'db' => 0, + 'prefix' => '', + 'max_attempts' => 5, + 'retry_seconds' => 5, + ], + // Connection pool, supports only Swoole or Swow drivers. + 'pool' => [ + 'max_connections' => 5, + 'min_connections' => 1, + 'wait_timeout' => 3, + 'idle_timeout' => 60, + 'heartbeat_interval' => 50, + ] + ], +]; diff --git a/public/.htaccess b/public/.htaccess new file mode 100644 index 0000000..e69de29 diff --git a/public/nginx.htaccess b/public/nginx.htaccess new file mode 100644 index 0000000..d92000e --- /dev/null +++ b/public/nginx.htaccess @@ -0,0 +1,6 @@ + location / { + if (!-e $request_filename) { + rewrite ^(.*)$ /index.php?s=/$1 last; + break; + } + } \ No newline at end of file