243 lines
7.2 KiB
PHP
Executable File
243 lines
7.2 KiB
PHP
Executable File
<?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;
|
||
}
|
||
}
|