UrsPromotionRankingCard.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. <?php
  2. namespace App\Module\UrsPromotion\AdminControllers\Metrics;
  3. use App\Module\UrsPromotion\Models\UrsUserMapping;
  4. use App\Module\User\Models\User;
  5. use Dcat\Admin\Widgets\Metrics\Card;
  6. use Illuminate\Http\Request;
  7. use Illuminate\Support\Facades\DB;
  8. /**
  9. * URS推广用户排名卡片
  10. * 显示直推、间推、三推、团队推广用户数量排名
  11. */
  12. class UrsPromotionRankingCard extends Card
  13. {
  14. /**
  15. * 卡片高度
  16. */
  17. protected $height = 400;
  18. /**
  19. * 卡片标题
  20. */
  21. protected $title = 'URS推广排行榜';
  22. /**
  23. * 初始化卡片
  24. */
  25. public function __construct()
  26. {
  27. if ($options = $this->defaultChartOptions()) {
  28. $this->chartOptions = $options;
  29. }
  30. $this->init();
  31. }
  32. /**
  33. * 处理请求
  34. *
  35. * @param Request $request
  36. * @return mixed|void
  37. */
  38. public function handle(Request $request)
  39. {
  40. $rankings = $this->getPromotionRankings();
  41. $this->withContent($rankings);
  42. }
  43. /**
  44. * 获取推广排名数据
  45. *
  46. * @return array
  47. */
  48. private function getPromotionRankings(): array
  49. {
  50. // 获取直推排名前10
  51. $directRanking = $this->getDirectRanking();
  52. // 获取间推排名前10
  53. $indirectRanking = $this->getIndirectRanking();
  54. // 获取三推排名前10
  55. $thirdRanking = $this->getThirdRanking();
  56. // 获取团队总数排名前10
  57. $teamRanking = $this->getTeamRanking();
  58. return [
  59. 'direct' => $directRanking,
  60. 'indirect' => $indirectRanking,
  61. 'third' => $thirdRanking,
  62. 'team' => $teamRanking,
  63. ];
  64. }
  65. /**
  66. * 获取直推排名
  67. *
  68. * @return array
  69. */
  70. private function getDirectRanking(): array
  71. {
  72. return UrsUserMapping::select([
  73. 'urs_promotion_user_mappings.urs_user_id',
  74. 'urs_promotion_user_mappings.user_id',
  75. 'urs_promotion_user_mappings.direct_count',
  76. 'users.nickname'
  77. ])
  78. ->leftJoin('users', 'urs_promotion_user_mappings.user_id', '=', 'users.id')
  79. ->where('urs_promotion_user_mappings.status', UrsUserMapping::STATUS_VALID)
  80. ->where('urs_promotion_user_mappings.direct_count', '>', 0)
  81. ->orderBy('urs_promotion_user_mappings.direct_count', 'desc')
  82. ->limit(10)
  83. ->get()
  84. ->toArray();
  85. }
  86. /**
  87. * 获取间推排名
  88. *
  89. * @return array
  90. */
  91. private function getIndirectRanking(): array
  92. {
  93. return UrsUserMapping::select([
  94. 'urs_promotion_user_mappings.urs_user_id',
  95. 'urs_promotion_user_mappings.user_id',
  96. 'urs_promotion_user_mappings.indirect_count',
  97. 'users.nickname'
  98. ])
  99. ->leftJoin('users', 'urs_promotion_user_mappings.user_id', '=', 'users.id')
  100. ->where('urs_promotion_user_mappings.status', UrsUserMapping::STATUS_VALID)
  101. ->where('urs_promotion_user_mappings.indirect_count', '>', 0)
  102. ->orderBy('urs_promotion_user_mappings.indirect_count', 'desc')
  103. ->limit(10)
  104. ->get()
  105. ->toArray();
  106. }
  107. /**
  108. * 获取三推排名
  109. *
  110. * @return array
  111. */
  112. private function getThirdRanking(): array
  113. {
  114. return UrsUserMapping::select([
  115. 'urs_promotion_user_mappings.urs_user_id',
  116. 'urs_promotion_user_mappings.user_id',
  117. 'urs_promotion_user_mappings.third_count',
  118. 'users.nickname'
  119. ])
  120. ->leftJoin('users', 'urs_promotion_user_mappings.user_id', '=', 'users.id')
  121. ->where('urs_promotion_user_mappings.status', UrsUserMapping::STATUS_VALID)
  122. ->where('urs_promotion_user_mappings.third_count', '>', 0)
  123. ->orderBy('urs_promotion_user_mappings.third_count', 'desc')
  124. ->limit(10)
  125. ->get()
  126. ->toArray();
  127. }
  128. /**
  129. * 获取团队总数排名
  130. *
  131. * @return array
  132. */
  133. private function getTeamRanking(): array
  134. {
  135. return UrsUserMapping::select([
  136. 'urs_promotion_user_mappings.urs_user_id',
  137. 'urs_promotion_user_mappings.user_id',
  138. 'urs_promotion_user_mappings.promotion_count',
  139. 'users.nickname'
  140. ])
  141. ->leftJoin('users', 'urs_promotion_user_mappings.user_id', '=', 'users.id')
  142. ->where('urs_promotion_user_mappings.status', UrsUserMapping::STATUS_VALID)
  143. ->where('urs_promotion_user_mappings.promotion_count', '>', 0)
  144. ->orderBy('urs_promotion_user_mappings.promotion_count', 'desc')
  145. ->limit(10)
  146. ->get()
  147. ->toArray();
  148. }
  149. /**
  150. * 设置卡片内容
  151. *
  152. * @param array $rankings 排名数据
  153. * @return $this
  154. */
  155. public function withContent(array $rankings)
  156. {
  157. $directHtml = $this->buildRankingHtml($rankings['direct'], 'direct_count', '直推');
  158. $indirectHtml = $this->buildRankingHtml($rankings['indirect'], 'indirect_count', '间推');
  159. $thirdHtml = $this->buildRankingHtml($rankings['third'], 'third_count', '三推');
  160. $teamHtml = $this->buildRankingHtml($rankings['team'], 'promotion_count', '团队');
  161. return $this->content(
  162. <<<HTML
  163. <div class="row">
  164. <div class="col-6">
  165. <h6 class="text-primary">直推排行榜</h6>
  166. {$directHtml}
  167. </div>
  168. <div class="col-6">
  169. <h6 class="text-success">间推排行榜</h6>
  170. {$indirectHtml}
  171. </div>
  172. </div>
  173. <div class="row mt-3">
  174. <div class="col-6">
  175. <h6 class="text-warning">三推排行榜</h6>
  176. {$thirdHtml}
  177. </div>
  178. <div class="col-6">
  179. <h6 class="text-info">团队排行榜</h6>
  180. {$teamHtml}
  181. </div>
  182. </div>
  183. HTML
  184. );
  185. }
  186. /**
  187. * 构建排名HTML
  188. *
  189. * @param array $data 排名数据
  190. * @param string $countField 数量字段
  191. * @param string $type 类型名称
  192. * @return string
  193. */
  194. private function buildRankingHtml(array $data, string $countField, string $type): string
  195. {
  196. if (empty($data)) {
  197. return '<small class="text-muted">暂无数据</small>';
  198. }
  199. $html = '<div class="ranking-list">';
  200. foreach ($data as $index => $item) {
  201. $rank = $index + 1;
  202. $nickname = $item['nickname'] ?? 'URS用户' . $item['urs_user_id'];
  203. $count = $item[$countField] ?? 0;
  204. $badgeClass = $rank <= 3 ? 'badge-warning' : 'badge-secondary';
  205. $html .= <<<HTML
  206. <div class="d-flex justify-content-between align-items-center mb-1">
  207. <span class="badge {$badgeClass}">{$rank}</span>
  208. <span class="text-truncate mx-2" style="max-width: 80px;" title="{$nickname}">{$nickname}</span>
  209. <span class="font-weight-bold">{$count}</span>
  210. </div>
  211. HTML;
  212. }
  213. $html .= '</div>';
  214. return $html;
  215. }
  216. }