webman_duanju/app/utils/RedisUtils.php

230 lines
6.7 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\utils;
use app\exception\SysException;
use support\think\Cache;
class RedisUtils
{
const CAN_CREATE_ORDER = 'can_create_order:';
const CREATE_ORDER_LIMIT = 'createOrder:';
const CAN_CASH = 'cash:canCash:';
public static function checkCanCreateOrder($userId)
{
$val = cache(self::CAN_CREATE_ORDER . $userId);
return empty($val);
}
public static function setUserCanCreateOrder($userId, $seconds)
{
cache(self::CAN_CREATE_ORDER . $userId, 1, $seconds);
}
public static function setCreateOrderFlagAndCheckLimit($userId, $orderId): bool
{
// 构造 key
$key = "createOrder:{$userId}:{$orderId}";
// 设置 Redis key值为 orderId过期时间 60 秒
Cache::store('redis')->set($key, (string)$orderId, 60);
// 获取 Redis 原生实例
$redis = Cache::store('redis')->handler();
// 使用 scan 非阻塞统计 key 数量
$pattern = "createOrder:{$userId}:*";
$iterator = null;
$count = 0;
while ($keys = $redis->scan($iterator, $pattern, 100)) {
$count += count($keys);
}
// 超过 22 返回 true
return $count > 22;
}
/**
* 通用的“按周统计”计数器(自动按课程 ID、业务类型区分
*
* @param string $prefix 前缀标识,如 'course:week_play:'
* @param int|string $id 主体 ID如课程 ID
* @param int $expireSeconds 默认过期时间(秒),默认 7 天
* @return int 返回当前统计值
*/
public static function incrWeekCounter(string $prefix, $id, int $expireSeconds = 604800): int
{
$key = $prefix . date('oW') . ':' . $id; // oW 为当前“ISO 年 + 周数”,确保每周一个 key
$count = Cache::store('redis')->inc($key);
// 第一次设置时设定过期时间
if ($count === 1) {
Cache::store('redis')->expire($key, $expireSeconds);
}
return $count;
}
public static function getconfig()
{
return Cache::getConfig();
}
/**
* 获取指定“周统计”计数值
*
* @param string $prefix 前缀
* @param int|string $id 主体 ID
* @return int
*/
public static function getWeekCounter(string $prefix, $id): int
{
$key = $prefix . date('oW') . ':' . $id;
return (int)Cache::store('redis')->get($key, 0);
}
public static function isCanCash($userId)
{
$val = cache(self::CAN_CASH . $userId);
return !empty($val);
}
public static function checkRealCount(int $userId)
{
$key = 'updateAuthCertInfo:' . $userId;
$val = cache($key);
if (!empty($val)) {
throw new SysException("实名修改失败: 每月可修改次数已用完,请联系管理员");
}
}
public static function setRealCount(int $userId)
{
$key = 'updateAuthCertInfo:' . $userId;
cache($key, 2628000);
}
private static function getFreeWatchKey($userId, $permanently = false)
{
if ($permanently) {
return "free:watch:" . $userId;
}
return "free:watch:" . date('Y-m-d') . ':' . $userId;
}
public static function isExpiredSet($key)
{
$redis = Cache::store('redis')->handler();
// 获取 key 的剩余过期时间(单位:秒)
$ttl = $redis->ttl($key);
if ($ttl == -1) {
return false;
}
return $ttl !== -2;
}
public static function getFreeWatchTimeIsExpire($userId)
{
$freeWatchKey = self::getFreeWatchKey($userId, true);
$permanentlyFreeWatch = cache($freeWatchKey);
$watchKey = self::getFreeWatchKey($userId, false);
$payFreeWatchInfo = cache($watchKey);
$expireTime = -1;
$jsonObject = null;
if (!empty($payFreeWatchInfo)) {
$jsonObject = json_decode($payFreeWatchInfo, true);
$expireTime = isset($jsonObject['expireTime']) ? $jsonObject['expireTime'] : -1;
}
$now = time(); // 当前时间戳
if ((!empty($permanentlyFreeWatch) && RedisUtils::isExpiredSet($freeWatchKey)) ||
(!empty($permanentlyFreeWatch) && $now >= $expireTime)) {
if (empty($permanentlyFreeWatch)) {
return null;
}
if (!RedisUtils::isExpiredSet($freeWatchKey)) {
cache($freeWatchKey, intval($permanentlyFreeWatch));
}
return false;
} else {
if (empty($payFreeWatchInfo)) {
return null;
}
$second = isset($jsonObject['second']) ? intval($jsonObject['second']) : 0;
if ($expireTime == -1) {
$jsonObject['expireTime'] = $now + $second;
$tomorrowZero = strtotime(date('Y-m-d', strtotime('+1 day')));
$expire = $tomorrowZero - $now;
cache($watchKey, json_encode($jsonObject), $expire);
return false;
} else {
return $now > $expireTime;
}
}
}
public static function setFreeWatchTime($userId, $second, $isPermanently = false)
{
$now = time();
$tomorrow = strtotime(date('Y-m-d', strtotime('+1 day')));
$freeWatchKey = self::getFreeWatchKey($userId, $isPermanently);
if ($isPermanently) {
$data = cache($freeWatchKey);
if (empty($data)) {
// 永久的,但不设置过期时间(-1
cache($freeWatchKey, $second);
} else {
$expire = Cache::store('redis')->handler()->ttl($freeWatchKey);
if ($expire === -1 || $expire === false || $expire === null) {
$expire = -1;
} else {
$expire += intval($second);
}
$newValue = intval($data) + intval($second);
if ($expire > 0) {
cache($freeWatchKey, $newValue, $expire);
} else {
cache($freeWatchKey, $newValue);
}
}
} else {
// 非永久,临时有效期到明天零点
$expire = $tomorrow - $now;
$jsonObject = [
'expireTime' => -1,
'second' => intval($second)
];
// 如果不存在才设置
if (!Cache::store('redis')->has($freeWatchKey)) {
cache($freeWatchKey, json_encode($jsonObject), $expire);
}
}
}
public static function setCanCashFlag(mixed $userId, int $param)
{
cache("cash:canCash:".$userId, $param,300);
}
}