From e81b954d0ad1c2de04c8f831f852291fd807b9cf Mon Sep 17 00:00:00 2001 From: youda Date: Sat, 19 Apr 2025 02:46:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/controller/Cardextractor.php | 15 +++- app/api/controller/FuLiWu.php | 21 +++++- app/api/controller/Goods.php | 85 +++++++++++++++------ app/api/controller/Infinite.php | 57 +++++++++++--- app/api/controller/Notify.php | 52 +++++++++++++ app/command/UpdateGoodsHeat.php | 108 +++++++++++++++++++++++++++ config/console.php | 1 + 7 files changed, 300 insertions(+), 39 deletions(-) create mode 100644 app/command/UpdateGoodsHeat.php diff --git a/app/api/controller/Cardextractor.php b/app/api/controller/Cardextractor.php index 94affa8..9d26fbd 100755 --- a/app/api/controller/Cardextractor.php +++ b/app/api/controller/Cardextractor.php @@ -98,7 +98,20 @@ class Cardextractor extends Base } $itme['join_user'] = $new_join_user; #参与次数 - $join_count = OrderList::field('id')->where('goods_id', '=', $itme['id'])->where('order_type', '=', 4)->count(); + $redis = (new \app\common\server\RedisHelper())->getRedis(); + $cacheKey = "order_goods_count:{$itme['id']}"; + $join_count = $redis->get($cacheKey); + + // 缓存未命中,从数据库获取并缓存 + if ($join_count === false) { + $join_count = OrderList::field('id')->where('goods_id', '=', $itme['id'])->where('order_type', '=', 4)->count(); + + // 设置缓存,5分钟过期 + $redis->set($cacheKey, $join_count, 300); + } else { + // 转为整数 + $join_count = intval($join_count); + } $itme['join_count'] = $join_count; }); $new_data = [ diff --git a/app/api/controller/FuLiWu.php b/app/api/controller/FuLiWu.php index d699d45..f5305e8 100755 --- a/app/api/controller/FuLiWu.php +++ b/app/api/controller/FuLiWu.php @@ -69,10 +69,23 @@ class FuLiWu extends Base ->toArray(); $itme['goodslist'] = $goodslist; #参与次数 - $join_count = OrderList::field('id') - ->where('goods_id', '=', $itme['id']) - ->where('order_type', '=', $itme['type']) - ->count(); + $redis = (new \app\common\server\RedisHelper())->getRedis(); + $cacheKey = "order_goods_count:{$itme['id']}"; + $join_count = $redis->get($cacheKey); + + // 缓存未命中,从数据库获取并缓存 + if ($join_count === false) { + $join_count = OrderList::field('id') + ->where('goods_id', '=', $itme['id']) + ->where('order_type', '=', $itme['type']) + ->count(); + + // 设置缓存,5分钟过期 + $redis->set($cacheKey, $join_count, 300); + } else { + // 转为整数 + $join_count = intval($join_count); + } $itme['join_count'] = $join_count; }); diff --git a/app/api/controller/Goods.php b/app/api/controller/Goods.php index 3f2a3d7..d756526 100755 --- a/app/api/controller/Goods.php +++ b/app/api/controller/Goods.php @@ -68,6 +68,23 @@ class Goods extends Base // 如果缓存存在,直接返回缓存数据 if ($cache_data) { $cached_data = json_decode($cache_data, true); + + // 在返回缓存数据前,更新参与次数 + if (!empty($cached_data['data'])) { + $redis = (new \app\common\server\RedisHelper())->getRedis(); + foreach ($cached_data['data'] as &$item) { + // 读取商品参与次数缓存 + $goods_id = $item['id']; + $cacheKey = "order_goods_count:{$goods_id}"; + $join_count = $redis->get($cacheKey); + + // 如果参与次数缓存存在,更新数据 + if ($join_count !== false) { + $item['join_count'] = intval($join_count); + } + } + } + return $this->renderSuccess('请求成功', $cached_data); } @@ -172,22 +189,8 @@ class Goods extends Base } // 批量查询所有商品的参与次数 - $joinCountMap = []; - if (!empty($goodsIds)) { - $joinCounts = OrderList::field('goods_id, order_type, COUNT(1) as count') - ->where('shang_id', 'between', self::$shang_count_id) - ->where('goods_id', 'in', $goodsIds) - ->where('parent_goods_list_id', '=', 0) - ->group('goods_id, order_type') - ->select() - ->toArray(); - - // 转为映射关系,键为"goods_id_order_type"格式 - foreach ($joinCounts as $joinCount) { - $key = $joinCount['goods_id'] . '_' . $joinCount['order_type']; - $joinCountMap[$key] = $joinCount['count']; - } - } + // 移除外部查询,使用Redis缓存在循环中查询每个商品的参与次数 + $redis = (new \app\common\server\RedisHelper())->getRedis(); // 批量查询type=10的商品库存 $goodslistMap = []; @@ -222,9 +225,29 @@ class Goods extends Base $item['stock'] = $goodslistData['stock']; } + // 使用Redis缓存获取参与次数 + $goods_id = $item['id']; + $cacheKey = "order_goods_count:{$goods_id}"; + $join_count = $redis->get($cacheKey); + + // 缓存未命中,从数据库获取并缓存 + if ($join_count === false) { + $join_count = OrderList::field('id') + ->where('goods_id', '=', $goods_id) + ->where('num', '=', $item['num']) + ->where('shang_id', 'between', self::$shang_count_id) + ->where('order_type', '=', $item['type']) + ->count(); + + // 设置缓存,5分钟过期 + $redis->set($cacheKey, $join_count, 300); + } else { + // 转为整数 + $join_count = intval($join_count); + } + // 设置参与次数 - $joinCountKey = $item['id'] . '_' . $item['type']; - $item['join_count'] = isset($joinCountMap[$joinCountKey]) ? $joinCountMap[$joinCountKey] : 0; + $item['join_count'] = $join_count; // 设置需要抽奖的数量 $item['need_draw_num'] = $item['type'] == 7 ? 1 : 0; @@ -283,7 +306,7 @@ class Goods extends Base #奖品信息 $goodslist_info = GoodsList::field('num,sum(`surplus_stock`) as all_surplus_stock') ->where(['goods_id' => $goods_id]) - ->where('shang_id', 'not in', [1, 2, 3, 4, 5]) + ->where('shang_id', '>', 5)//[1, 2, 3, 4, 5] ->where('goods_list_id', '=', 0) ->having('all_surplus_stock', '>', 0) ->group('num') @@ -409,11 +432,25 @@ class Goods extends Base $new_join_user[] = $join_user_value['userinfo']['headimg']; } #参与次数 - $join_count = OrderList::field('id')->where('goods_id', '=', $goods_id) - ->where('num', '=', $goods_num) - ->where('shang_id', 'between', self::$shang_count_id) - ->where('order_type', '=', $goods['type']) - ->count(); + $redis = (new \app\common\server\RedisHelper())->getRedis(); + $cacheKey = "order_goods_count:{$goods_id}"; + $join_count = $redis->get($cacheKey); + + // 缓存未命中,从数据库获取并缓存 + if ($join_count === false) { + $join_count = OrderList::field('id') + ->where('goods_id', '=', $goods_id) + ->where('num', '=', $goods_num) + ->where('shang_id', 'between', self::$shang_count_id) + ->where('order_type', '=', $goods['type']) + ->count(); + + // 设置缓存,5分钟过期 + $redis->set($cacheKey, $join_count, 300); + } else { + // 转为整数 + $join_count = intval($join_count); + } #时间配置 $config = getConfig('base'); $goods['three_time'] = $config['three_time']; diff --git a/app/api/controller/Infinite.php b/app/api/controller/Infinite.php index df29f0c..641f72b 100755 --- a/app/api/controller/Infinite.php +++ b/app/api/controller/Infinite.php @@ -44,6 +44,16 @@ class Infinite extends Base // 如果缓存存在,直接返回缓存数据 if ($cache_data) { $cached_data = json_decode($cache_data, true); + + // 检查是否有最新的热度值,并更新缓存中的数据 + $heat_cache_key = "order_goods_count:{$goods_id}"; + $latest_heat = $redis->get($heat_cache_key); + + if ($latest_heat !== false) { + // 更新缓存数据中的热度值 + $cached_data['goods']['join_count'] = intval($latest_heat); + } + return $this->renderSuccess("请求成功", $cached_data); } @@ -107,11 +117,24 @@ class Infinite extends Base } $goods['join_user'] = $new_join_user; #参与次数 - $join_count1 = OrderList::field('id')->where('goods_id', '=', $goods_id) - ->where('shang_id', 'between', [34, 38]) - ->where('order_type', '=', $goods['type']) - ->where('source', '=', 1) - ->count(); + $redis = (new \app\common\server\RedisHelper())->getRedis(); + $cacheKey = "order_goods_count:{$goods_id}"; + $join_count1 = $redis->get($cacheKey); + + // 缓存未命中,从数据库获取并缓存 + if ($join_count1 === false) { + $join_count1 = OrderList::field('id')->where('goods_id', '=', $goods_id) + ->where('shang_id', 'between', [34, 38]) + ->where('order_type', '=', $goods['type']) + ->where('source', '=', 1) + ->count(); + + // 设置缓存,5分钟过期 + $redis->set($cacheKey, $join_count1, 300); + } else { + // 转为整数 + $join_count1 = intval($join_count1); + } $goods['join_count'] = $join_count1; #赏池分类 @@ -256,11 +279,24 @@ class Infinite extends Base } $goods['join_user'] = $new_join_user; #参与次数 - $join_count1 = OrderList::field('id')->where('goods_id', '=', $goods_id) - ->where('shang_id', 'between', [34, 38]) - ->where('order_type', '=', $goods['type']) - ->where('source', '=', 1) - ->count(); + $redis = (new \app\common\server\RedisHelper())->getRedis(); + $cacheKey = "order_goods_count:{$goods_id}"; + $join_count1 = $redis->get($cacheKey); + + // 缓存未命中,从数据库获取并缓存 + if ($join_count1 === false) { + $join_count1 = OrderList::field('id')->where('goods_id', '=', $goods_id) + ->where('shang_id', 'between', [34, 38]) + ->where('order_type', '=', $goods['type']) + ->where('source', '=', 1) + ->count(); + + // 设置缓存,5分钟过期 + $redis->set($cacheKey, $join_count1, 300); + } else { + // 转为整数 + $join_count1 = intval($join_count1); + } $goods['join_count'] = $join_count1; #赏池分类 @@ -321,6 +357,7 @@ class Infinite extends Base // 尝试从缓存获取数据 $cached_data = $redis->get($cache_key); if ($cached_data) { + // 直接返回缓存的数据,这个方法不涉及热度值显示,无需更新 return $this->renderSuccess("请求成功", json_decode($cached_data, true)); } diff --git a/app/api/controller/Notify.php b/app/api/controller/Notify.php index 087743d..55a0cce 100755 --- a/app/api/controller/Notify.php +++ b/app/api/controller/Notify.php @@ -1289,6 +1289,9 @@ class Notify extends Base if ($goodslist) { $res[] = $this->infinite_drawprize_box($goodslist, $prize_num, $order_id, $user_id, $goods_id, $order_type, $infinite_goods); + + // 更新Redis中盒子的热度值(增加本次抽奖次数) + $this->updateGoodsHeat($goods_id, $prize_num); //去除秘宝池次数 if ($infinite_goods['type'] == 9 && $order['is_mibao'] == 1) { @@ -1432,6 +1435,7 @@ class Notify extends Base $res[] = $this->infinite_drawprize_box($goodslist_1, 1, $order_id, $user_id, $goods_id, $order_type, $infinite_goods); } } + return $res; } @@ -2006,6 +2010,9 @@ class Notify extends Base #开奖================================================== $res[] = $this->draw_drawprize($order); #开奖================================================== + + // 更新Redis中盒子的热度值 + $this->updateGoodsHeat($goods_id, $order['prize_num']); } else { $res[] = 0; } @@ -2116,6 +2123,9 @@ class Notify extends Base #开奖================================================== $res[] = $this->draw_drawprize($order); #开奖================================================== + + // 更新Redis中盒子的热度值 + $this->updateGoodsHeat($goods_id, $order['prize_num']); } else { $res[] = 0; } @@ -2190,4 +2200,46 @@ class Notify extends Base return $res; } + + /** + * 更新Redis中盒子的热度值 + * + * @param int $goods_id 盒子ID + * @param int $prize_num 本次抽奖次数 + * @return bool 更新结果 + */ + private function updateGoodsHeat($goods_id, $prize_num) + { + try { + // 获取Redis实例 + $redis = (new \app\common\server\RedisHelper())->getRedis(); + $cacheKey = "order_goods_count:{$goods_id}"; + + // 获取当前热度值 + $current_heat = $redis->get($cacheKey); + + // 如果缓存不存在,先从数据库获取 + if ($current_heat === false) { + $current_heat = \app\common\model\OrderList::where('goods_id', '=', $goods_id) + ->where('shang_id', 'between', [34, 38]) + ->where('parent_goods_list_id', '=', 0) + ->count(); + } else { + // 转为整数 + $current_heat = intval($current_heat); + } + + // 计算新的热度值 + $new_heat = $current_heat + $prize_num; + + // 更新Redis缓存,设置5分钟过期时间 + $redis->set($cacheKey, $new_heat, 300); + + return true; + } catch (\Exception $e) { + // 发生异常时记录日志 + \think\facade\Log::error("更新盒子热度值失败:" . $e->getMessage()); + return false; + } + } } \ No newline at end of file diff --git a/app/command/UpdateGoodsHeat.php b/app/command/UpdateGoodsHeat.php new file mode 100644 index 0000000..0b2f1d1 --- /dev/null +++ b/app/command/UpdateGoodsHeat.php @@ -0,0 +1,108 @@ +setName('update_goods_heat') + ->setDescription('更新所有盒子的热度值到Redis中'); + } + + /** + * 执行命令 + * + * @param Input $input + * @param Output $output + * @return int + */ + protected function execute(Input $input, Output $output) + { + $startTime = microtime(true); + $output->writeln('开始更新盒子热度值到Redis...'); + + // 获取Redis实例 + $redis = (new RedisHelper())->getRedis(); + + try { + // 获取所有上架的盒子ID + $goodsIds = GoodsModel::where('status', 1) + ->field('id') + ->select() + ->column('id'); + + if (empty($goodsIds)) { + $output->writeln('没有找到上架的盒子'); + return 0; + } + + $output->writeln('找到 ' . count($goodsIds) . ' 个上架的盒子'); + + // 更新到Redis + $updatedCount = 0; + $successCount = 0; + $failCount = 0; + + // 逐个查询盒子的参与次数并更新到Redis + foreach ($goodsIds as $goodsId) { + try { + // 查询单个盒子的参与次数(命中索引) + $count = OrderList::where('goods_id', '=', $goodsId) + ->where('shang_id', 'between', $this->shangCountIdRange) + ->where('parent_goods_list_id', '=', 0) + ->count(); + + // 构建缓存键 + $cacheKey = "order_goods_count:{$goodsId}"; + + // 存入Redis,设置5分钟过期时间 + $redis->set($cacheKey, $count, $this->cacheTime); + $successCount++; + } catch (\Exception $e) { + $output->writeln("更新盒子(ID:{$goodsId})热度值失败: {$e->getMessage()}"); + $failCount++; + } + + $updatedCount++; + + // 每处理50个盒子输出一次进度 + if ($updatedCount % 50 == 0) { + $output->writeln("已处理 {$updatedCount} 个盒子..."); + } + } + + $endTime = microtime(true); + $executionTime = round($endTime - $startTime, 2); + + $output->writeln("处理完成! 总计 {$updatedCount} 个盒子,成功 {$successCount} 个,失败 {$failCount} 个"); + $output->writeln("执行耗时: {$executionTime} 秒"); + + return 0; + } catch (\Exception $e) { + $output->writeln("更新盒子热度值失败: {$e->getMessage()}"); + return 1; + } + } +} \ No newline at end of file diff --git a/config/console.php b/config/console.php index 51178f7..de88344 100755 --- a/config/console.php +++ b/config/console.php @@ -8,5 +8,6 @@ return [ 'AutoGoodsOffshelf' => 'app\command\AutoGoodsOffshelf',#自动下架利润率过低的盒子 'CreateOffshelfLogTable' => 'app\command\CreateOffshelfLogTable',#创建盒子自动下架日志表 'FlwOpen' => 'app\command\FlwOpen',#福利屋开奖 + 'UpdateGoodsHeat' => 'app\command\UpdateGoodsHeat',#更新盒子热度值到Redis ], ];