You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
aquaculture/app/Utils/HomeCacheDataUtil.php

228 lines
8.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace App\Utils;
use App\Enums\HomeCacheEnum;
use App\Enums\SettingKeyEnum;
use App\Models\Category;
use App\Models\CouponTemplate;
use App\Models\Product;
use App\Models\Seckill;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Redis;
class HomeCacheDataUtil
{
/**
* 获取优惠券模板数据并缓存5分钟。
*
* @return \Illuminate\Database\Eloquent\Collection|static[] 优惠券模板的集合
*/
public static function couponTemplates()
{
// 使用缓存记忆功能缓存时间为5分钟
return Cache::remember(
HomeCacheEnum::COUPON_TEMPLATES, // 缓存键
Carbon::now()->addMinutes(5), // 缓存时长
function () {
// 获取今天的日期
$today = Carbon::today()->toDateString();
// 查询所有有效的优惠券模板结束日期大于等于今天并限制3个结果按最新排序
return CouponTemplate::query()
->where('end_date', '>=', $today)
->latest() // 按照结束日期排序
->limit(3) // 限制返回3个
->get(); // 获取结果
}
);
}
/**
* 获取秒杀数据并缓存60秒。
*
* 通过 Redis 获取秒杀商品的具体信息,并过滤已过期或已售罄的秒杀活动。
*
* @return \Illuminate\Support\Collection 过滤后的秒杀商品集合
*/
public static function getSeckillData()
{
return Cache::remember(
HomeCacheEnum::SEC_KILL_DATA, // 缓存键
Carbon::now()->startOfSecond()->addSeconds(60), // 缓存时间为60秒
function () {
// 判断秒杀功能是否开启
$setting = new SettingKeyEnum(SettingKeyEnum::IS_OPEN_SECKILL);
$isOpenSeckill = setting($setting) == 1; // 获取是否开启秒杀功能的设置
if ($isOpenSeckill) {
// 获取当前时间
$now = Carbon::now()->toDateTimeString();
// 查询当前时间段内有效的秒杀活动
$secKills = Seckill::query()
->where('start_at', '<=', $now) // 秒杀开始时间小于等于当前时间
->where('end_at', '>', $now) // 秒杀结束时间大于当前时间
->latest() // 按最新时间排序
->get();
// 使用 Redis 批量获取秒杀商品信息
$res = Redis::connection()
->pipeline(function ($pipe) use ($secKills) {
$secKills->each(function (Seckill $s) use ($pipe) {
// 获取每个秒杀商品的 Redis 键值对应的数据
$pipe->get($s->getRedisModelKey());
});
});
// 处理 Redis 返回的结果
return collect($res)->map(function ($item) {
if (!$item) {
return null; // 如果 Redis 没有数据,返回 null
}
// 将 Redis 数据反序列化为对象
return json_decode($item);
})->filter(function ($model) {
// 过滤掉不符合条件的秒杀活动
if (!is_object($model)) {
return false; // 如果不是对象,返回 false
}
// 如果商品已售罄
if ($model->sale_count == $model->number) {
return false;
}
// 如果秒杀已过期
if (Carbon::now()->gt(Carbon::make($model->end_at))) {
return false;
}
// 满足条件,返回 true
return true;
})->values(); // 返回过滤后的秒杀商品集合
}
}
);
}
/**
* 获取商品分类数据并缓存,缓存时间由外部传入。
*
* 支持强制刷新缓存。
*
* @param int $ttl 缓存时间(秒)
* @param bool $refresh 是否强制刷新缓存
* @return \Illuminate\Database\Eloquent\Collection 商品分类集合
*/
public static function categories($ttl, $refresh = false)
{
if ($refresh) {
Cache::forget(HomeCacheEnum::CATEGORIES); // 强制刷新缓存,删除缓存
}
return Cache::remember(
HomeCacheEnum::CATEGORIES, // 缓存键
Carbon::now()->addSeconds($ttl), // 缓存时长
function () {
// 查询商品分类,并获取分类下的商品数量(通过 withCount 进行关联计数)
return Category::query()
->withCount('products') // 统计每个分类下商品数量
->orderBy('order') // 按照排序字段排序
->take(9) // 限制最多9个分类
->get(); // 获取结果
});
}
/**
* 获取热销商品数据并缓存,缓存时间由外部传入。
*
* 支持强制刷新缓存。
*
* @param int $ttl 缓存时间(秒)
* @param bool $refresh 是否强制刷新缓存
* @return \Illuminate\Database\Eloquent\Collection 热销商品集合
*/
public static function hotProducts($ttl, $refresh = false)
{
if ($refresh) {
Cache::forget(HomeCacheEnum::HOTTEST); // 强制刷新缓存,删除缓存
}
return Cache::remember(
HomeCacheEnum::HOTTEST, // 缓存键
Carbon::now()->addSeconds($ttl), // 缓存时长
function () {
// 查询按销量排序的热销商品限制3个
return Product::query()
->withCount('users') // 获取购买用户数量
->orderBy('sale_count', 'desc') // 按销量降序排序
->take(3) // 限制最多3个热销商品
->get(); // 获取结果
});
}
/**
* 获取最新商品数据并缓存,缓存时间由外部传入。
*
* 支持强制刷新缓存。
*
* @param int $ttl 缓存时间(秒)
* @param bool $refresh 是否强制刷新缓存
* @return \Illuminate\Database\Eloquent\Collection 最新商品集合
*/
public static function latestProducts($ttl, $refresh = false)
{
if ($refresh) {
Cache::forget(HomeCacheEnum::LATEST); // 强制刷新缓存,删除缓存
}
return Cache::remember(
HomeCacheEnum::LATEST, // 缓存键
Carbon::now()->addSeconds($ttl), // 缓存时长
function () {
// 查询按最新时间排序的商品限制9个
return Product::query()
->withCount('users') // 获取购买用户数量
->latest() // 按时间降序排序
->take(9) // 限制最多9个最新商品
->get(); // 获取结果
});
}
/**
* 获取活跃用户数据并缓存,缓存时间由外部传入。
*
* 支持强制刷新缓存。
*
* @param int $ttl 缓存时间(秒)
* @param bool $refresh 是否强制刷新缓存
* @return \Illuminate\Database\Eloquent\Collection 活跃用户集合
*/
public static function users($ttl, $refresh = false)
{
if ($refresh) {
Cache::forget(HomeCacheEnum::USERS); // 强制刷新缓存,删除缓存
}
return Cache::remember(
HomeCacheEnum::USERS, // 缓存键
Carbon::now()->addSeconds($ttl), // 缓存时长
function () {
// 查询登录次数最多的前10个用户
return User::query()
->orderBy('login_count', 'desc') // 按登录次数排序
->take(10) // 限制前10个
->get(['avatar', 'name']); // 获取用户头像和姓名
});
}
}