manghe/app/common/model/UserLoginLog.php
2025-05-12 16:24:11 +08:00

243 lines
7.2 KiB
PHP
Executable File
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
declare(strict_types=1);
namespace app\common\model;
use think\Model;
use think\facade\Db;
class UserLoginLog extends Model
{
// 设置表名
protected $name = 'user_login_log';
// 设置主键
protected $pk = 'id';
// 自动写入时间戳
protected $autoWriteTimestamp = false;
/**
* 记录用户登录
* 一天只记录一次
*
* @param int $user_id 用户ID
* @param string $device 设备类型
* @param string $ip IP地址
* @param string $location 登录地点
* @return bool
*/
public static function recordLogin($user_id, $device = '', $ip = '', $location = '')
{
// 获取今天的日期
$today = date('Y-m-d');
$today_start = strtotime($today . ' 00:00:00');
$today_end = strtotime($today . ' 23:59:59');
// 查询今天是否已记录
$exist = self::where('user_id', $user_id)
->where('login_time', '>=', $today_start)
->where('login_time', '<=', $today_end)
->find();
// 如果今天已记录,则更新最后登录时间
if ($exist) {
return self::where('id', $exist['id'])->update([
'last_login_time' => time(),
'device' => $device,
'ip' => $ip
]);
}
// 添加登录记录
return self::insert([
'user_id' => $user_id,
'login_date' => $today,
'login_time' => time(),
'device' => $device,
'ip' => $ip,
'location' => $location,
'year' => date('Y'),
'month' => date('m'),
'week' => date('W'),
'last_login_time' => time()
]);
}
/**
* 获取每日登录用户数
*
* @param string $start_date 开始日期 格式Y-m-d
* @param string $end_date 结束日期 格式Y-m-d
* @return array
*/
public static function getDailyLoginCount($start_date = '', $end_date = '')
{
$query = Db::name('user_login_log');
if ($start_date) {
$query = $query->where('login_date', '>=', $start_date);
}
if ($end_date) {
$query = $query->where('login_date', '<=', $end_date);
}
return $query->field('login_date, COUNT(DISTINCT user_id) as count')
->group('login_date')
->order('login_date ASC')
->select()
->toArray();
}
/**
* 获取每周登录用户数
*
* @param int $year 年份
* @param int $start_week 开始周数
* @param int $end_week 结束周数
* @return array
*/
public static function getWeeklyLoginCount($year = 0, $start_week = 0, $end_week = 0)
{
$query = Db::name('user_login_log');
if ($year) {
$query = $query->where('year', $year);
}
if ($start_week) {
$query = $query->where('week', '>=', $start_week);
}
if ($end_week) {
$query = $query->where('week', '<=', $end_week);
}
return $query->field('year, week, COUNT(DISTINCT user_id) as count')
->group('year, week')
->order('year ASC, week ASC')
->select()
->toArray();
}
/**
* 获取每月登录用户数
*
* @param int $year 年份
* @param int $start_month 开始月份
* @param int $end_month 结束月份
* @return array
*/
public static function getMonthlyLoginCount($year = 0, $start_month = 0, $end_month = 0)
{
$query = Db::name('user_login_log');
if ($year) {
$query = $query->where('year', $year);
}
if ($start_month) {
$query = $query->where('month', '>=', $start_month);
}
if ($end_month) {
$query = $query->where('month', '<=', $end_month);
}
return $query->field('year, month, COUNT(DISTINCT user_id) as count')
->group('year, month')
->order('year ASC, month ASC')
->select()
->toArray();
}
/**
* 获取指定时间段内的活跃用户数(至少登录一次的用户数量)
*
* @param string $start_date 开始日期 格式Y-m-d
* @param string $end_date 结束日期 格式Y-m-d
* @return int
*/
public static function getActiveUserCount($start_date = '', $end_date = '')
{
$query = Db::name('user_login_log');
if ($start_date) {
$query = $query->where('login_date', '>=', $start_date);
}
if ($end_date) {
$query = $query->where('login_date', '<=', $end_date);
}
return $query->distinct(true)->field('user_id')->count('user_id');
}
/**
* 获取连续登录用户数
*
* @param int $days 连续登录天数
* @param string $end_date 结束日期 格式Y-m-d
* @return array
*/
public static function getContinuousLoginUsers($days = 7, $end_date = '')
{
if (!$end_date) {
$end_date = date('Y-m-d');
}
// 计算开始日期
$start_date = date('Y-m-d', strtotime("-" . ($days - 1) . " days", strtotime($end_date)));
// 按用户分组,查询日期范围内每个用户的登录记录
$user_logins = Db::name('user_login_log')
->where('login_date', '>=', $start_date)
->where('login_date', '<=', $end_date)
->field('user_id, login_date')
->order('user_id, login_date')
->select()
->toArray();
// 统计用户在指定日期范围内的登录天数
$user_login_days = [];
$date_range = [];
// 生成日期范围
$current_date = $start_date;
while ($current_date <= $end_date) {
$date_range[] = $current_date;
$current_date = date('Y-m-d', strtotime("+1 day", strtotime($current_date)));
}
// 统计每个用户的登录天数
foreach ($user_logins as $login) {
if (!isset($user_login_days[$login['user_id']])) {
$user_login_days[$login['user_id']] = [];
}
$user_login_days[$login['user_id']][] = $login['login_date'];
}
// 筛选连续登录的用户
$continuous_users = [];
foreach ($user_login_days as $user_id => $login_dates) {
if (count($login_dates) >= $days) {
// 检查是否连续登录
$is_continuous = true;
for ($i = 0; $i < count($date_range); $i++) {
if (!in_array($date_range[$i], $login_dates)) {
$is_continuous = false;
break;
}
}
if ($is_continuous) {
$continuous_users[] = $user_id;
}
}
}
return $continuous_users;
}
}