|
|
|
@ -16,151 +16,209 @@ 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),
|
|
|
|
|
HomeCacheEnum::COUPON_TEMPLATES, // 缓存键
|
|
|
|
|
Carbon::now()->addMinutes(5), // 缓存时长
|
|
|
|
|
function () {
|
|
|
|
|
|
|
|
|
|
$today = Carbon::today()->toDateString();
|
|
|
|
|
return CouponTemplate::query()
|
|
|
|
|
->where('end_date', '>=', $today)
|
|
|
|
|
->latest()
|
|
|
|
|
->limit(3)
|
|
|
|
|
->get();
|
|
|
|
|
});
|
|
|
|
|
// 获取今天的日期
|
|
|
|
|
$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),
|
|
|
|
|
HomeCacheEnum::SEC_KILL_DATA, // 缓存键
|
|
|
|
|
Carbon::now()->startOfSecond()->addSeconds(60), // 缓存时间为60秒
|
|
|
|
|
function () {
|
|
|
|
|
|
|
|
|
|
// 判断秒杀功能是否开启
|
|
|
|
|
$setting = new SettingKeyEnum(SettingKeyEnum::IS_OPEN_SECKILL);
|
|
|
|
|
$isOpenSeckill = setting($setting) == 1;
|
|
|
|
|
$isOpenSeckill = setting($setting) == 1; // 获取是否开启秒杀功能的设置
|
|
|
|
|
|
|
|
|
|
if ($isOpenSeckill) {
|
|
|
|
|
|
|
|
|
|
// 获取当前时间
|
|
|
|
|
$now = Carbon::now()->toDateTimeString();
|
|
|
|
|
|
|
|
|
|
// 查询当前时间段内有效的秒杀活动
|
|
|
|
|
$secKills = Seckill::query()
|
|
|
|
|
->where('start_at', '<=', $now)
|
|
|
|
|
->where('end_at', '>', $now)
|
|
|
|
|
->latest()
|
|
|
|
|
->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());
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return collect($res)->map(function ($item) {
|
|
|
|
|
|
|
|
|
|
if (! $item) {
|
|
|
|
|
return null;
|
|
|
|
|
// 处理 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;
|
|
|
|
|
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();
|
|
|
|
|
})->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);
|
|
|
|
|
Cache::forget(HomeCacheEnum::CATEGORIES); // 强制刷新缓存,删除缓存
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Cache::remember(
|
|
|
|
|
HomeCacheEnum::CATEGORIES,
|
|
|
|
|
Carbon::now()->addSeconds($ttl),
|
|
|
|
|
HomeCacheEnum::CATEGORIES, // 缓存键
|
|
|
|
|
Carbon::now()->addSeconds($ttl), // 缓存时长
|
|
|
|
|
function () {
|
|
|
|
|
|
|
|
|
|
// 查询商品分类,并获取分类下的商品数量(通过 withCount 进行关联计数)
|
|
|
|
|
return Category::query()
|
|
|
|
|
->withCount('products')
|
|
|
|
|
->orderBy('order')
|
|
|
|
|
->take(9)
|
|
|
|
|
->get();
|
|
|
|
|
->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);
|
|
|
|
|
Cache::forget(HomeCacheEnum::HOTTEST); // 强制刷新缓存,删除缓存
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Cache::remember(
|
|
|
|
|
HomeCacheEnum::HOTTEST,
|
|
|
|
|
Carbon::now()->addSeconds($ttl),
|
|
|
|
|
HomeCacheEnum::HOTTEST, // 缓存键
|
|
|
|
|
Carbon::now()->addSeconds($ttl), // 缓存时长
|
|
|
|
|
function () {
|
|
|
|
|
|
|
|
|
|
// 查询按销量排序的热销商品,限制3个
|
|
|
|
|
return Product::query()
|
|
|
|
|
->withCount('users')
|
|
|
|
|
->orderBy('sale_count', 'desc')
|
|
|
|
|
->take(3)
|
|
|
|
|
->get();
|
|
|
|
|
->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);
|
|
|
|
|
Cache::forget(HomeCacheEnum::LATEST); // 强制刷新缓存,删除缓存
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Cache::remember(
|
|
|
|
|
HomeCacheEnum::LATEST,
|
|
|
|
|
Carbon::now()->addSeconds($ttl),
|
|
|
|
|
HomeCacheEnum::LATEST, // 缓存键
|
|
|
|
|
Carbon::now()->addSeconds($ttl), // 缓存时长
|
|
|
|
|
function () {
|
|
|
|
|
|
|
|
|
|
// 查询按最新时间排序的商品,限制9个
|
|
|
|
|
return Product::query()
|
|
|
|
|
->withCount('users')
|
|
|
|
|
->latest()
|
|
|
|
|
->take(9)
|
|
|
|
|
->get();
|
|
|
|
|
->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);
|
|
|
|
|
Cache::forget(HomeCacheEnum::USERS); // 强制刷新缓存,删除缓存
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Cache::remember(
|
|
|
|
|
HomeCacheEnum::USERS,
|
|
|
|
|
Carbon::now()->addSeconds($ttl),
|
|
|
|
|
HomeCacheEnum::USERS, // 缓存键
|
|
|
|
|
Carbon::now()->addSeconds($ttl), // 缓存时长
|
|
|
|
|
function () {
|
|
|
|
|
|
|
|
|
|
// 查询登录次数最多的前10个用户
|
|
|
|
|
return User::query()
|
|
|
|
|
->orderBy('login_count', 'desc')
|
|
|
|
|
->take(10)
|
|
|
|
|
->get(['avatar', 'name']);
|
|
|
|
|
->orderBy('login_count', 'desc') // 按登录次数排序
|
|
|
|
|
->take(10) // 限制前10个
|
|
|
|
|
->get(['avatar', 'name']); // 获取用户头像和姓名
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|