UrsActiveUserService.php 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. <?php
  2. namespace App\Module\UrsPromotion\Services;
  3. use App\Module\UrsPromotion\Models\UrsUserMapping;
  4. use App\Module\User\Models\User;
  5. use Illuminate\Support\Facades\DB;
  6. use Illuminate\Support\Facades\Log;
  7. use Carbon\Carbon;
  8. /**
  9. * URS活跃用户服务
  10. *
  11. * 负责管理URS用户的活跃状态,包括活跃状态检查、更新和统计
  12. */
  13. class UrsActiveUserService
  14. {
  15. /**
  16. * 活跃用户定义:最近15天有活动的用户
  17. */
  18. const ACTIVE_DAYS_THRESHOLD = 15;
  19. /**
  20. * 更新单个用户的活跃状态
  21. *
  22. * @param int $ursUserId URS用户ID
  23. * @return bool
  24. */
  25. public static function updateUserActiveStatus(int $ursUserId): bool
  26. {
  27. try {
  28. // 获取用户映射关系
  29. $mapping = UrsUserMapping::where('urs_user_id', $ursUserId)
  30. ->where('status', UrsUserMapping::STATUS_VALID)
  31. ->with('user')
  32. ->first();
  33. if (!$mapping || !$mapping->user) {
  34. Log::warning('URS用户映射关系不存在或农场用户不存在', [
  35. 'urs_user_id' => $ursUserId
  36. ]);
  37. return false;
  38. }
  39. // 检查用户活跃状态
  40. $isActive = self::checkUserActivity($mapping->user);
  41. $activeDaysCount = self::calculateActiveDaysCount($mapping->user);
  42. // 更新活跃状态
  43. $mapping->update([
  44. 'is_active' => $isActive ? UrsUserMapping::ACTIVE_YES : UrsUserMapping::ACTIVE_NO,
  45. 'last_activity_check' => now(),
  46. 'active_days_count' => $activeDaysCount,
  47. ]);
  48. Log::info('URS用户活跃状态更新成功', [
  49. 'urs_user_id' => $ursUserId,
  50. 'farm_user_id' => $mapping->user_id,
  51. 'is_active' => $isActive,
  52. 'active_days_count' => $activeDaysCount
  53. ]);
  54. return true;
  55. } catch (\Exception $e) {
  56. Log::error('URS用户活跃状态更新失败', [
  57. 'urs_user_id' => $ursUserId,
  58. 'error' => $e->getMessage()
  59. ]);
  60. return false;
  61. }
  62. }
  63. /**
  64. * 批量更新用户活跃状态
  65. *
  66. * @param int $limit 每次处理的用户数量限制
  67. * @return array 更新结果统计
  68. */
  69. public static function batchUpdateActiveStatus(int $limit = 1000): array
  70. {
  71. $stats = [
  72. 'total_processed' => 0,
  73. 'successful_updates' => 0,
  74. 'failed_updates' => 0,
  75. 'active_users' => 0,
  76. 'inactive_users' => 0,
  77. ];
  78. try {
  79. // 获取需要检查的用户
  80. $mappings = UrsUserMapping::getUsersNeedActivityCheck($limit);
  81. $stats['total_processed'] = $mappings->count();
  82. Log::info('开始批量更新URS用户活跃状态', [
  83. 'total_users' => $stats['total_processed'],
  84. 'limit' => $limit
  85. ]);
  86. foreach ($mappings as $mapping) {
  87. try {
  88. if (!$mapping->user) {
  89. $stats['failed_updates']++;
  90. continue;
  91. }
  92. // 检查用户活跃状态
  93. $isActive = self::checkUserActivity($mapping->user);
  94. $activeDaysCount = self::calculateActiveDaysCount($mapping->user);
  95. // 更新活跃状态
  96. $mapping->update([
  97. 'is_active' => $isActive ? UrsUserMapping::ACTIVE_YES : UrsUserMapping::ACTIVE_NO,
  98. 'last_activity_check' => now(),
  99. 'active_days_count' => $activeDaysCount,
  100. ]);
  101. $stats['successful_updates']++;
  102. if ($isActive) {
  103. $stats['active_users']++;
  104. } else {
  105. $stats['inactive_users']++;
  106. }
  107. } catch (\Exception $e) {
  108. $stats['failed_updates']++;
  109. Log::error('单个用户活跃状态更新失败', [
  110. 'urs_user_id' => $mapping->urs_user_id,
  111. 'error' => $e->getMessage()
  112. ]);
  113. }
  114. }
  115. Log::info('批量更新URS用户活跃状态完成', $stats);
  116. } catch (\Exception $e) {
  117. Log::error('批量更新URS用户活跃状态失败', [
  118. 'error' => $e->getMessage(),
  119. 'stats' => $stats
  120. ]);
  121. }
  122. return $stats;
  123. }
  124. /**
  125. * 检查用户活跃状态
  126. *
  127. * @param User $user 农场用户对象
  128. * @return bool
  129. */
  130. public static function checkUserActivity(User $user): bool
  131. {
  132. if (!$user->last_activity_time) {
  133. return false;
  134. }
  135. $threshold = Carbon::now()->subDays(self::ACTIVE_DAYS_THRESHOLD);
  136. return $user->last_activity_time >= $threshold;
  137. }
  138. /**
  139. * 计算用户活跃天数
  140. *
  141. * @param User $user 农场用户对象
  142. * @return int
  143. */
  144. public static function calculateActiveDaysCount(User $user): int
  145. {
  146. if (!$user->last_activity_time) {
  147. return 0;
  148. }
  149. $daysSinceLastActivity = Carbon::now()->diffInDays($user->last_activity_time);
  150. // 如果在活跃期内,返回1,否则返回0
  151. return $daysSinceLastActivity <= self::ACTIVE_DAYS_THRESHOLD ? 1 : 0;
  152. }
  153. /**
  154. * 获取活跃用户统计信息
  155. *
  156. * @return array
  157. */
  158. public static function getActiveUserStats(): array
  159. {
  160. return UrsUserMapping::getActiveUserStats();
  161. }
  162. /**
  163. * 获取指定URS用户的活跃团队成员
  164. *
  165. * @param int $ursUserId URS用户ID
  166. * @return array
  167. */
  168. public static function getActiveTeamMembers(int $ursUserId): array
  169. {
  170. // 获取用户的推荐关系
  171. $teamMembers = UrsReferralService::getTeamMembers($ursUserId, 3); // 获取三代团队
  172. if (empty($teamMembers)) {
  173. return [
  174. 'active_direct_count' => 0,
  175. 'active_total_count' => 0,
  176. 'active_members' => []
  177. ];
  178. }
  179. // 提取所有团队成员的URS用户ID
  180. $allMemberIds = [];
  181. foreach ($teamMembers as $level => $members) {
  182. // $members 是一个简单的用户ID数组,不是对象数组
  183. $allMemberIds = array_merge($allMemberIds, $members);
  184. }
  185. // 获取活跃的团队成员
  186. $activeMemberIds = UrsUserMapping::getActiveUrsUserIds($allMemberIds);
  187. // 统计各层级的活跃人数
  188. $activeDirectCount = 0;
  189. $activeTotalCount = count($activeMemberIds);
  190. $activeMembers = [];
  191. foreach ($teamMembers as $level => $members) {
  192. foreach ($members as $memberId) {
  193. if (in_array($memberId, $activeMemberIds)) {
  194. $activeMembers[] = [
  195. 'urs_user_id' => $memberId,
  196. 'level' => $level
  197. ];
  198. if ($level === 1) { // 直推
  199. $activeDirectCount++;
  200. }
  201. }
  202. }
  203. }
  204. return [
  205. 'active_direct_count' => $activeDirectCount,
  206. 'active_total_count' => $activeTotalCount,
  207. 'active_members' => $activeMembers
  208. ];
  209. }
  210. /**
  211. * 获取活跃用户详细统计
  212. *
  213. * @return array
  214. */
  215. public static function getDetailedActiveStats(): array
  216. {
  217. $baseStats = self::getActiveUserStats();
  218. // 获取最近更新统计
  219. $recentUpdates = UrsUserMapping::where('status', UrsUserMapping::STATUS_VALID)
  220. ->where('last_activity_check', '>=', now()->subDay())
  221. ->count();
  222. // 获取需要检查的用户数量
  223. $needCheckCount = UrsUserMapping::where('status', UrsUserMapping::STATUS_VALID)
  224. ->where(function($query) {
  225. $query->whereNull('last_activity_check')
  226. ->orWhere('last_activity_check', '<', now()->subDay());
  227. })
  228. ->count();
  229. return array_merge($baseStats, [
  230. 'recent_updates' => $recentUpdates,
  231. 'need_check_count' => $needCheckCount,
  232. 'last_update_time' => UrsUserMapping::where('status', UrsUserMapping::STATUS_VALID)
  233. ->whereNotNull('last_activity_check')
  234. ->max('last_activity_check'),
  235. ]);
  236. }
  237. /**
  238. * 重置所有用户的活跃状态(用于测试或重新初始化)
  239. *
  240. * @return array
  241. */
  242. public static function resetAllActiveStatus(): array
  243. {
  244. try {
  245. DB::beginTransaction();
  246. // 重置所有用户的活跃状态
  247. $updated = UrsUserMapping::where('status', UrsUserMapping::STATUS_VALID)
  248. ->update([
  249. 'is_active' => UrsUserMapping::ACTIVE_NO,
  250. 'last_activity_check' => null,
  251. 'active_days_count' => 0,
  252. ]);
  253. DB::commit();
  254. Log::info('重置所有URS用户活跃状态完成', [
  255. 'updated_count' => $updated
  256. ]);
  257. return [
  258. 'success' => true,
  259. 'updated_count' => $updated,
  260. 'message' => '重置完成'
  261. ];
  262. } catch (\Exception $e) {
  263. DB::rollBack();
  264. Log::error('重置URS用户活跃状态失败', [
  265. 'error' => $e->getMessage()
  266. ]);
  267. return [
  268. 'success' => false,
  269. 'updated_count' => 0,
  270. 'message' => '重置失败:' . $e->getMessage()
  271. ];
  272. }
  273. }
  274. }