ReferralService.php 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. <?php
  2. namespace App\Module\Promotion\Services;
  3. use App\Module\Promotion\Logics\ReferralLogic;
  4. use App\Module\Promotion\Logics\RelationCacheLogic;
  5. use App\Module\Promotion\Logics\TalentLogic;
  6. use App\Module\Promotion\Models\PromotionUserReferral;
  7. use Illuminate\Support\Facades\Log;
  8. /**
  9. * 推荐关系服务类
  10. *
  11. * 对外提供推荐关系相关的服务,包括获取推荐关系、设置推荐关系、
  12. * 查询团队成员等功能。该类对外提供服务,内部调用逻辑层实现。
  13. */
  14. class ReferralService
  15. {
  16. /**
  17. * 获取用户的直接推荐人
  18. *
  19. * @param int $userId 用户ID
  20. * @return array|null 推荐人信息
  21. */
  22. public static function getUserReferrer(int $userId): ?array
  23. {
  24. try {
  25. $referralLogic = new ReferralLogic();
  26. $referrerId = $referralLogic->getDirectReferrerId($userId);
  27. if (!$referrerId) {
  28. return null;
  29. }
  30. // 获取推荐人信息
  31. $user = app('db')->table('users')->where('id', $referrerId)->first();
  32. if (!$user) {
  33. return null;
  34. }
  35. return [
  36. 'user_id' => $user->id,
  37. 'username' => $user->username ?? '',
  38. 'nickname' => $user->nickname ?? '',
  39. 'avatar' => $user->avatar ?? '',
  40. 'created_at' => $user->created_at
  41. ];
  42. } catch (\Exception $e) {
  43. Log::error("获取用户推荐人失败: " . $e->getMessage());
  44. return null;
  45. }
  46. }
  47. /**
  48. * 获取用户的直接推荐列表
  49. *
  50. * @param int $userId 用户ID
  51. * @param int $page 页码
  52. * @param int $pageSize 每页数量
  53. * @return array
  54. */
  55. public static function getUserDirectReferrals(int $userId, int $page = 1, int $pageSize = 20): array
  56. {
  57. try {
  58. $query = PromotionUserReferral::where('referrer_id', $userId)
  59. ->with('user');
  60. $total = $query->count();
  61. $referrals = $query->orderBy('created_at', 'desc')
  62. ->offset(($page - 1) * $pageSize)
  63. ->limit($pageSize)
  64. ->get();
  65. $result = [];
  66. foreach ($referrals as $referral) {
  67. if ($referral->user) {
  68. $result[] = [
  69. 'user_id' => $referral->user->id,
  70. 'username' => $referral->user->username ?? '',
  71. 'nickname' => $referral->user->nickname ?? '',
  72. 'avatar' => $referral->user->avatar ?? '',
  73. 'created_at' => $referral->created_at
  74. ];
  75. }
  76. }
  77. return [
  78. 'total' => $total,
  79. 'page' => $page,
  80. 'page_size' => $pageSize,
  81. 'total_pages' => ceil($total / $pageSize),
  82. 'referrals' => $result
  83. ];
  84. } catch (\Exception $e) {
  85. Log::error("获取用户直接推荐列表失败: " . $e->getMessage());
  86. return [
  87. 'total' => 0,
  88. 'page' => $page,
  89. 'page_size' => $pageSize,
  90. 'total_pages' => 0,
  91. 'referrals' => []
  92. ];
  93. }
  94. }
  95. /**
  96. * 获取用户的团队成员列表
  97. *
  98. * @param int $userId 用户ID
  99. * @param int $page 页码
  100. * @param int $pageSize 每页数量
  101. * @param int $maxLevel 最大层级
  102. * @return array
  103. */
  104. public static function getUserPromotionMembers(int $userId, int $page = 1, int $pageSize = 20, int $maxLevel = 20): array
  105. {
  106. try {
  107. $referralLogic = new ReferralLogic();
  108. return $referralLogic->getAllPromotionMembers($userId, $maxLevel, $page, $pageSize);
  109. } catch (\Exception $e) {
  110. Log::error("获取用户团队成员列表失败: " . $e->getMessage());
  111. return [
  112. 'total' => 0,
  113. 'page' => $page,
  114. 'page_size' => $pageSize,
  115. 'total_pages' => 0,
  116. 'members' => []
  117. ];
  118. }
  119. }
  120. /**
  121. * 设置用户的推荐人
  122. *
  123. * @param int $userId 用户ID
  124. * @param int $referrerId 推荐人ID
  125. * @param string $reason 设置原因
  126. * @param int $operatorId 操作人ID
  127. * @return array 包含设置结果和消息
  128. */
  129. public static function setUserReferrer(int $userId, int $referrerId, string $reason, int $operatorId): array
  130. {
  131. try {
  132. // 验证用户和推荐人是否存在
  133. $user = app('db')->table('users')->where('id', $userId)->first();
  134. $referrer = app('db')->table('users')->where('id', $referrerId)->first();
  135. if (!$user) {
  136. return [
  137. 'success' => false,
  138. 'message' => '用户不存在'
  139. ];
  140. }
  141. if (!$referrer) {
  142. return [
  143. 'success' => false,
  144. 'message' => '推荐人不存在'
  145. ];
  146. }
  147. // 检查是否自己推荐自己
  148. if ($userId == $referrerId) {
  149. return [
  150. 'success' => false,
  151. 'message' => '不能设置自己为推荐人'
  152. ];
  153. }
  154. $referralLogic = new ReferralLogic();
  155. $talentLogic = new TalentLogic($referralLogic);
  156. // 检查是否形成循环推荐
  157. if ($referralLogic->checkCircularReferral($userId, $referrerId)) {
  158. return [
  159. 'success' => false,
  160. 'message' => '设置此推荐人会形成循环推荐关系'
  161. ];
  162. }
  163. // 设置推荐关系
  164. $result = $referralLogic->updateReferralRelation($userId, $referrerId, $reason, $operatorId);
  165. if (!$result) {
  166. return [
  167. 'success' => false,
  168. 'message' => '设置推荐人失败'
  169. ];
  170. }
  171. // 更新团队统计和达人等级
  172. $talentLogic->updatePromotionCounts($referrerId);
  173. $talentLogic->checkAndUpdateTalentLevel($referrerId);
  174. return [
  175. 'success' => true,
  176. 'message' => '设置推荐人成功'
  177. ];
  178. } catch (\Exception $e) {
  179. Log::error("设置用户推荐人失败: " . $e->getMessage());
  180. return [
  181. 'success' => false,
  182. 'message' => '设置推荐人时发生错误: ' . $e->getMessage()
  183. ];
  184. }
  185. }
  186. /**
  187. * 获取用户的团队统计数据
  188. *
  189. * @param int $userId 用户ID
  190. * @return array
  191. */
  192. public static function getUserPromotionStats(int $userId): array
  193. {
  194. try {
  195. $referralLogic = new ReferralLogic();
  196. $talentLogic = new TalentLogic($referralLogic);
  197. $talent = $talentLogic->getUserTalent($userId);
  198. if (!$talent) {
  199. return [
  200. 'direct_count' => 0,
  201. 'promotion_count' => 0,
  202. 'talent_level' => 0
  203. ];
  204. }
  205. return [
  206. 'direct_count' => $talent->direct_count,
  207. 'promotion_count' => $talent->promotion_count,
  208. 'talent_level' => $talent->talent_level
  209. ];
  210. } catch (\Exception $e) {
  211. Log::error("获取用户团队统计数据失败: " . $e->getMessage());
  212. return [
  213. 'direct_count' => 0,
  214. 'promotion_count' => 0,
  215. 'talent_level' => 0
  216. ];
  217. }
  218. }
  219. /**
  220. * 重建用户的关系缓存
  221. *
  222. * @param int $userId 用户ID
  223. * @return bool
  224. */
  225. public static function rebuildUserRelationCache(int $userId): bool
  226. {
  227. try {
  228. $relationCacheLogic = new RelationCacheLogic();
  229. return $relationCacheLogic->generateUserRelationCache($userId);
  230. } catch (\Exception $e) {
  231. Log::error("重建用户关系缓存失败: " . $e->getMessage());
  232. return false;
  233. }
  234. }
  235. }