|
|
@@ -0,0 +1,188 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace App\Module\User\Services;
|
|
|
+
|
|
|
+use App\Module\LCache\Cache;
|
|
|
+use App\Module\User\Models\UserInfo;
|
|
|
+use Carbon\Carbon;
|
|
|
+use Illuminate\Support\Facades\Log;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 用户活动时间服务类
|
|
|
+ *
|
|
|
+ * 负责处理用户登录时间和活动时间的更新逻辑
|
|
|
+ * 使用缓存机制避免频繁的数据库写入操作
|
|
|
+ */
|
|
|
+class UserActivityService
|
|
|
+{
|
|
|
+ /**
|
|
|
+ * 缓存键前缀
|
|
|
+ */
|
|
|
+ const CACHE_PREFIX = 'user_activity:';
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 缓存过期时间(秒)- 5分钟
|
|
|
+ */
|
|
|
+ const CACHE_TTL = 300;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 活动时间更新间隔(秒)- 1分钟
|
|
|
+ * 只有距离上次更新超过此间隔才会真正更新数据库
|
|
|
+ */
|
|
|
+ const ACTIVITY_UPDATE_INTERVAL = 60;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新用户登录时间
|
|
|
+ *
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @param Carbon|null $loginTime 登录时间,默认为当前时间
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public static function updateLoginTime(int $userId, ?Carbon $loginTime = null): bool
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ $loginTime = $loginTime ?: Carbon::now();
|
|
|
+
|
|
|
+ // 获取或创建用户信息记录
|
|
|
+ $userInfo = UserInfo::firstOrCreate(
|
|
|
+ ['user_id' => $userId],
|
|
|
+ ['status' => \App\Module\User\Enums\STATUS::Normal]
|
|
|
+ );
|
|
|
+
|
|
|
+ // 更新登录时间
|
|
|
+ $userInfo->last_login_time = $loginTime;
|
|
|
+ $userInfo->save();
|
|
|
+
|
|
|
+ // 同时更新活动时间
|
|
|
+ self::updateActivityTime($userId, $loginTime, true);
|
|
|
+
|
|
|
+ Log::info('用户登录时间已更新', [
|
|
|
+ 'user_id' => $userId,
|
|
|
+ 'login_time' => $loginTime->toDateTimeString()
|
|
|
+ ]);
|
|
|
+
|
|
|
+ return true;
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ Log::error('更新用户登录时间失败', [
|
|
|
+ 'user_id' => $userId,
|
|
|
+ 'error' => $e->getMessage()
|
|
|
+ ]);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新用户活动时间
|
|
|
+ *
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @param Carbon|null $activityTime 活动时间,默认为当前时间
|
|
|
+ * @param bool $forceUpdate 是否强制更新,忽略缓存间隔
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public static function updateActivityTime(int $userId, ?Carbon $activityTime = null, bool $forceUpdate = false): bool
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ $activityTime = $activityTime ?: Carbon::now();
|
|
|
+ $cacheKey = self::CACHE_PREFIX . 'last_update:' . $userId;
|
|
|
+
|
|
|
+ // 检查缓存,避免频繁更新
|
|
|
+ if (!$forceUpdate) {
|
|
|
+ $lastUpdate = Cache::get($cacheKey);
|
|
|
+ if ($lastUpdate && (time() - $lastUpdate) < self::ACTIVITY_UPDATE_INTERVAL) {
|
|
|
+ // 距离上次更新时间太短,跳过本次更新
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取或创建用户信息记录
|
|
|
+ $userInfo = UserInfo::firstOrCreate(
|
|
|
+ ['user_id' => $userId],
|
|
|
+ ['status' => \App\Module\User\Enums\STATUS::Normal]
|
|
|
+ );
|
|
|
+
|
|
|
+ // 更新活动时间
|
|
|
+ $userInfo->last_activity_time = $activityTime;
|
|
|
+ $userInfo->save();
|
|
|
+
|
|
|
+ // 更新缓存记录
|
|
|
+ Cache::put($cacheKey, time(), self::CACHE_TTL);
|
|
|
+
|
|
|
+ Log::debug('用户活动时间已更新', [
|
|
|
+ 'user_id' => $userId,
|
|
|
+ 'activity_time' => $activityTime->toDateTimeString(),
|
|
|
+ 'force_update' => $forceUpdate
|
|
|
+ ]);
|
|
|
+
|
|
|
+ return true;
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ Log::error('更新用户活动时间失败', [
|
|
|
+ 'user_id' => $userId,
|
|
|
+ 'error' => $e->getMessage()
|
|
|
+ ]);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取用户最后登录时间
|
|
|
+ *
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @return Carbon|null
|
|
|
+ */
|
|
|
+ public static function getLastLoginTime(int $userId): ?Carbon
|
|
|
+ {
|
|
|
+ $userInfo = UserInfo::where('user_id', $userId)->first();
|
|
|
+ return $userInfo?->last_login_time;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取用户最后活动时间
|
|
|
+ *
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @return Carbon|null
|
|
|
+ */
|
|
|
+ public static function getLastActivityTime(int $userId): ?Carbon
|
|
|
+ {
|
|
|
+ $userInfo = UserInfo::where('user_id', $userId)->first();
|
|
|
+ return $userInfo?->last_activity_time;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 批量更新用户活动时间
|
|
|
+ * 用于定时任务或批量处理场景
|
|
|
+ *
|
|
|
+ * @param array $userActivities 用户活动数据 [['user_id' => 1, 'activity_time' => Carbon], ...]
|
|
|
+ * @return int 成功更新的用户数量
|
|
|
+ */
|
|
|
+ public static function batchUpdateActivityTime(array $userActivities): int
|
|
|
+ {
|
|
|
+ $successCount = 0;
|
|
|
+
|
|
|
+ foreach ($userActivities as $activity) {
|
|
|
+ if (isset($activity['user_id']) && isset($activity['activity_time'])) {
|
|
|
+ if (self::updateActivityTime($activity['user_id'], $activity['activity_time'], true)) {
|
|
|
+ $successCount++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Log::info('批量更新用户活动时间完成', [
|
|
|
+ 'total' => count($userActivities),
|
|
|
+ 'success' => $successCount
|
|
|
+ ]);
|
|
|
+
|
|
|
+ return $successCount;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 清理过期的缓存数据
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public static function cleanExpiredCache(): void
|
|
|
+ {
|
|
|
+ // 这里可以实现清理逻辑,由于使用了TTL,缓存会自动过期
|
|
|
+ // 如果需要主动清理,可以在这里实现
|
|
|
+ Log::debug('用户活动缓存清理完成');
|
|
|
+ }
|
|
|
+}
|