本案例分享介绍的是 “东莞梦幻网络科技”体育直播系统的积分流水与风控策略设计,并附上核心实现思路和部分示例代码(基于 ThinkPHP + MySQL + Redis + WebSocket 等技术栈)。从三个层面讲:防刷、防伪、限频。
// 每日签到积分限额示例
function canAddPoints($userId, $taskType) {
$redisKey = "points:{$userId}:{$taskType}:" . date('Ymd');
$maxDaily = 1; // 每日签到1次积分
$current = \think\facade\Cache::get($redisKey) ?? 0;
if ($current >= $maxDaily) {
return false;
}
return true;
}
function addPoints($userId, $taskType, $points) {
if (!canAddPoints($userId, $taskType)) {
return false;
}
// 写入积分流水
Db::name('points_log')->insert([
'user_id' => $userId,
'task_type' => $taskType,
'points' => $points,
'ip' => request()->ip(),
'device' => request()->header('User-Agent'),
'created_at' => time(),
]);
// 更新Redis计数
$redisKey = "points:{$userId}:{$taskType}:" . date('Ymd');
\think\facade\Cache::inc($redisKey, 1, 86400); // 设置过期1天
return true;
}
function isDeviceNormal($userId) {
$device = request()->header('User-Agent');
$ip = request()->ip();
// 检测设备同日重复行为
$cacheKey = "device_check:{$device}:" . date('Ymd');
$count = \think\facade\Cache::get($cacheKey) ?? 0;
if ($count > 5) return false;
\think\facade\Cache::inc($cacheKey, 1, 86400);
return true;
}
function riskCheck($userId, $taskType) {
$logs = Db::name('points_log')
->where('user_id', $userId)
->where('task_type', $taskType)
->where('created_at', '>=', strtotime('-1 hour'))
->count();
if ($logs > 10) { // 1小时超过10次任务积分异常
Db::name('user')->where('id', $userId)->update(['status' => 2]); // 账号冻结
return false;
}
return true;
}
CREATE TABLE `points_log` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`user_id` bigint unsigned NOT NULL,
`task_type` varchar(50) NOT NULL,
`points` int NOT NULL,
`ip` varchar(50),
`device` varchar(255),
`remark` varchar(255),
`created_at` int NOT NULL,
PRIMARY KEY (`id`),
INDEX(`user_id`),
INDEX(`task_type`),
INDEX(`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
类型 | 限制策略 |
---|---|
每日签到 | 每天 1 次 |
分享任务 | 每小时 1 次 |
趣猜比分 | 每场比赛 1 次 |
充值返积分 | 单日上限 500 |
// Redis 哈希记录每日积分上限
$redisKey = "daily_points_limit:{$userId}:" . date('Ymd');
$current = \think\facade\Cache::hGet($redisKey, $taskType) ?? 0;
$limit = 100;
if ($current + $points > $limit) {
return false; // 超过日限额
}
\think\facade\Cache::hSet($redisKey, $taskType, $current + $points);
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。