ViewReferralChainAction.php 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. <?php
  2. namespace App\Module\UrsPromotion\AdminControllers\Actions;
  3. use App\Module\UrsPromotion\Models\UrsUserReferral;
  4. use App\Module\UrsPromotion\Models\UrsUserMapping;
  5. use Dcat\Admin\Widgets\Modal;
  6. use UCore\DcatAdmin\RowAction;
  7. /**
  8. * 查看推荐上级链操作
  9. *
  10. * 显示用户的上级推荐链路径
  11. */
  12. class ViewReferralChainAction extends RowAction
  13. {
  14. /**
  15. * 操作按钮标题
  16. *
  17. * @var string
  18. */
  19. protected $title = '上级链';
  20. /**
  21. * 检查是否允许显示此操作
  22. *
  23. * @return bool
  24. */
  25. public function allowed()
  26. {
  27. // 所有记录都允许查看上级链
  28. return true;
  29. }
  30. /**
  31. * 渲染操作按钮
  32. *
  33. * @return string
  34. */
  35. public function render2()
  36. {
  37. $row = $this->getRow();
  38. $ursUserId = $row->urs_user_id;
  39. // 获取推荐上级链数据
  40. $chainData = $this->getReferralChainData($ursUserId);
  41. // 构建链路HTML
  42. $chainHtml = $this->buildChainHtml($chainData);
  43. return Modal::make()
  44. ->xl()
  45. ->title("URS用户 {$ursUserId} 的推荐上级链")
  46. ->body($chainHtml)
  47. ->button("<i class=\"fa fa-link\"></i> {$this->title}");
  48. }
  49. /**
  50. * 获取推荐上级链数据
  51. *
  52. * @param int $ursUserId
  53. * @return array
  54. */
  55. private function getReferralChainData(int $ursUserId): array
  56. {
  57. $chain = [];
  58. $currentUserId = $ursUserId;
  59. $level = 0;
  60. $maxLevels = 30; // 防止无限循环,最多查询10级
  61. // 从当前用户开始,向上查找推荐人
  62. while ($currentUserId && $level < $maxLevels) {
  63. // 查找当前用户的推荐关系
  64. $referral = UrsUserReferral::where('urs_user_id', $currentUserId)
  65. ->where('status', UrsUserReferral::STATUS_VALID)
  66. ->first();
  67. // 获取用户的农场信息
  68. $userMapping = UrsUserMapping::where('urs_user_id', $currentUserId)
  69. ->where('status', UrsUserMapping::STATUS_VALID)
  70. ->with(['user.info'])
  71. ->first();
  72. $userInfo = [
  73. 'urs_user_id' => $currentUserId,
  74. 'farm_user_id' => $userMapping->user_id ?? null,
  75. 'username' => $userMapping->user->username ?? '未进入农场',
  76. 'nickname' => $userMapping->user->info->nickname ?? '无昵称',
  77. 'level' => $level,
  78. 'is_root' => false,
  79. ];
  80. if ($referral) {
  81. $userInfo['referrer_id'] = $referral->urs_referrer_id;
  82. $userInfo['referral_time'] = $referral->referral_time;
  83. $currentUserId = $referral->urs_referrer_id;
  84. } else {
  85. // 没有推荐人,说明是根用户
  86. $userInfo['is_root'] = true;
  87. $currentUserId = null;
  88. }
  89. $chain[] = $userInfo;
  90. $level++;
  91. }
  92. return array_reverse($chain); // 反转数组,从根用户开始显示
  93. }
  94. /**
  95. * 构建上级链HTML
  96. *
  97. * @param array $chainData
  98. * @return string
  99. */
  100. private function buildChainHtml(array $chainData): string
  101. {
  102. $html = '<div class="referral-chain-container">';
  103. // 添加样式
  104. $html .= '<style>
  105. .referral-chain-container {
  106. padding: 20px;
  107. font-family: "Helvetica Neue", Arial, sans-serif;
  108. }
  109. .chain-node {
  110. margin: 10px 0;
  111. padding: 15px;
  112. border: 2px solid #ddd;
  113. border-radius: 8px;
  114. background-color: #f9f9f9;
  115. position: relative;
  116. }
  117. .chain-node.root {
  118. border-color: #dc3545;
  119. background-color: #f8d7da;
  120. }
  121. .chain-node.current {
  122. border-color: #007bff;
  123. background-color: #d1ecf1;
  124. font-weight: bold;
  125. }
  126. .level-badge {
  127. display: inline-block;
  128. padding: 4px 8px;
  129. border-radius: 4px;
  130. color: white;
  131. font-size: 12px;
  132. margin-right: 10px;
  133. }
  134. .level-root { background-color: #dc3545; }
  135. .level-1 { background-color: #fd7e14; }
  136. .level-2 { background-color: #ffc107; color: #333; }
  137. .level-3 { background-color: #28a745; }
  138. .level-4 { background-color: #17a2b8; }
  139. .level-5 { background-color: #6f42c1; }
  140. .user-info {
  141. font-size: 14px;
  142. margin: 5px 0;
  143. }
  144. .user-meta {
  145. font-size: 12px;
  146. color: #666;
  147. margin-top: 8px;
  148. }
  149. .chain-arrow {
  150. text-align: center;
  151. color: #007bff;
  152. font-size: 18px;
  153. margin: 5px 0;
  154. }
  155. </style>';
  156. if (empty($chainData)) {
  157. $html .= '<p class="text-muted">无法获取推荐链信息</p>';
  158. } else {
  159. $totalLevels = count($chainData);
  160. $targetUserId = $chainData[count($chainData) - 1]['urs_user_id'];
  161. $html .= "<h5><i class=\"fa fa-link\"></i> 推荐链路径 (共{$totalLevels}级)</h5>";
  162. foreach ($chainData as $index => $user) {
  163. $isRoot = $user['is_root'];
  164. $isCurrent = ($user['urs_user_id'] == $targetUserId);
  165. $level = $totalLevels - $user['level'] - 1; // 重新计算显示级别
  166. $nodeClass = 'chain-node';
  167. if ($isRoot) {
  168. $nodeClass .= ' root';
  169. $levelName = '根用户';
  170. $badgeClass = 'level-root';
  171. } elseif ($isCurrent) {
  172. $nodeClass .= ' current';
  173. $levelName = '当前用户';
  174. $badgeClass = 'level-' . min($level, 5);
  175. } else {
  176. $levelName = "第{$level}级推荐人";
  177. $badgeClass = 'level-' . min($level, 5);
  178. }
  179. $html .= "<div class='{$nodeClass}'>";
  180. $html .= "<span class='level-badge {$badgeClass}'>{$levelName}</span>";
  181. $html .= "<span class='user-info'>URS-{$user['urs_user_id']}</span>";
  182. if ($user['farm_user_id']) {
  183. $html .= " → 农场用户ID: {$user['farm_user_id']} | {$user['username']} ({$user['nickname']})";
  184. } else {
  185. $html .= " → <span class='text-warning'>未进入农场</span>";
  186. }
  187. $html .= "<div class='user-meta'>";
  188. if (isset($user['referral_time'])) {
  189. $html .= "推荐时间: {$user['referral_time']}";
  190. }
  191. if ($isRoot) {
  192. $html .= "推荐链的起始用户";
  193. } elseif ($isCurrent) {
  194. $html .= "目标用户";
  195. }
  196. $html .= "</div>";
  197. $html .= "</div>";
  198. // 添加箭头(除了最后一个)
  199. if ($index < count($chainData) - 1) {
  200. $html .= '<div class="chain-arrow">↓ 推荐</div>';
  201. }
  202. }
  203. }
  204. $html .= '</div>';
  205. return $html;
  206. }
  207. }