|
|
@@ -0,0 +1,239 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace App\Module\UrsPromotion\AdminControllers\Metrics;
|
|
|
+
|
|
|
+use App\Module\UrsPromotion\Models\UrsUserMapping;
|
|
|
+use App\Module\User\Models\User;
|
|
|
+use Dcat\Admin\Widgets\Metrics\Card;
|
|
|
+use Illuminate\Http\Request;
|
|
|
+use Illuminate\Support\Facades\DB;
|
|
|
+
|
|
|
+/**
|
|
|
+ * URS推广用户排名卡片
|
|
|
+ * 显示直推、间推、三推、团队推广用户数量排名
|
|
|
+ */
|
|
|
+class UrsPromotionRankingCard extends Card
|
|
|
+{
|
|
|
+ /**
|
|
|
+ * 卡片高度
|
|
|
+ */
|
|
|
+ protected $height = 400;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 卡片标题
|
|
|
+ */
|
|
|
+ protected $title = 'URS推广排行榜';
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 初始化卡片
|
|
|
+ */
|
|
|
+ public function __construct()
|
|
|
+ {
|
|
|
+ if ($options = $this->defaultChartOptions()) {
|
|
|
+ $this->chartOptions = $options;
|
|
|
+ }
|
|
|
+
|
|
|
+ $this->init();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理请求
|
|
|
+ *
|
|
|
+ * @param Request $request
|
|
|
+ * @return mixed|void
|
|
|
+ */
|
|
|
+ public function handle(Request $request)
|
|
|
+ {
|
|
|
+ $rankings = $this->getPromotionRankings();
|
|
|
+ $this->withContent($rankings);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取推广排名数据
|
|
|
+ *
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ private function getPromotionRankings(): array
|
|
|
+ {
|
|
|
+ // 获取直推排名前10
|
|
|
+ $directRanking = $this->getDirectRanking();
|
|
|
+
|
|
|
+ // 获取间推排名前10
|
|
|
+ $indirectRanking = $this->getIndirectRanking();
|
|
|
+
|
|
|
+ // 获取三推排名前10
|
|
|
+ $thirdRanking = $this->getThirdRanking();
|
|
|
+
|
|
|
+ // 获取团队总数排名前10
|
|
|
+ $teamRanking = $this->getTeamRanking();
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'direct' => $directRanking,
|
|
|
+ 'indirect' => $indirectRanking,
|
|
|
+ 'third' => $thirdRanking,
|
|
|
+ 'team' => $teamRanking,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取直推排名
|
|
|
+ *
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ private function getDirectRanking(): array
|
|
|
+ {
|
|
|
+ return UrsUserMapping::select([
|
|
|
+ 'urs_promotion_user_mappings.urs_user_id',
|
|
|
+ 'urs_promotion_user_mappings.user_id',
|
|
|
+ 'urs_promotion_user_mappings.direct_count',
|
|
|
+ 'users.nickname'
|
|
|
+ ])
|
|
|
+ ->leftJoin('users', 'urs_promotion_user_mappings.user_id', '=', 'users.id')
|
|
|
+ ->where('urs_promotion_user_mappings.status', UrsUserMapping::STATUS_VALID)
|
|
|
+ ->where('urs_promotion_user_mappings.direct_count', '>', 0)
|
|
|
+ ->orderBy('urs_promotion_user_mappings.direct_count', 'desc')
|
|
|
+ ->limit(10)
|
|
|
+ ->get()
|
|
|
+ ->toArray();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取间推排名
|
|
|
+ *
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ private function getIndirectRanking(): array
|
|
|
+ {
|
|
|
+ return UrsUserMapping::select([
|
|
|
+ 'urs_promotion_user_mappings.urs_user_id',
|
|
|
+ 'urs_promotion_user_mappings.user_id',
|
|
|
+ 'urs_promotion_user_mappings.indirect_count',
|
|
|
+ 'users.nickname'
|
|
|
+ ])
|
|
|
+ ->leftJoin('users', 'urs_promotion_user_mappings.user_id', '=', 'users.id')
|
|
|
+ ->where('urs_promotion_user_mappings.status', UrsUserMapping::STATUS_VALID)
|
|
|
+ ->where('urs_promotion_user_mappings.indirect_count', '>', 0)
|
|
|
+ ->orderBy('urs_promotion_user_mappings.indirect_count', 'desc')
|
|
|
+ ->limit(10)
|
|
|
+ ->get()
|
|
|
+ ->toArray();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取三推排名
|
|
|
+ *
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ private function getThirdRanking(): array
|
|
|
+ {
|
|
|
+ return UrsUserMapping::select([
|
|
|
+ 'urs_promotion_user_mappings.urs_user_id',
|
|
|
+ 'urs_promotion_user_mappings.user_id',
|
|
|
+ 'urs_promotion_user_mappings.third_count',
|
|
|
+ 'users.nickname'
|
|
|
+ ])
|
|
|
+ ->leftJoin('users', 'urs_promotion_user_mappings.user_id', '=', 'users.id')
|
|
|
+ ->where('urs_promotion_user_mappings.status', UrsUserMapping::STATUS_VALID)
|
|
|
+ ->where('urs_promotion_user_mappings.third_count', '>', 0)
|
|
|
+ ->orderBy('urs_promotion_user_mappings.third_count', 'desc')
|
|
|
+ ->limit(10)
|
|
|
+ ->get()
|
|
|
+ ->toArray();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取团队总数排名
|
|
|
+ *
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ private function getTeamRanking(): array
|
|
|
+ {
|
|
|
+ return UrsUserMapping::select([
|
|
|
+ 'urs_promotion_user_mappings.urs_user_id',
|
|
|
+ 'urs_promotion_user_mappings.user_id',
|
|
|
+ 'urs_promotion_user_mappings.promotion_count',
|
|
|
+ 'users.nickname'
|
|
|
+ ])
|
|
|
+ ->leftJoin('users', 'urs_promotion_user_mappings.user_id', '=', 'users.id')
|
|
|
+ ->where('urs_promotion_user_mappings.status', UrsUserMapping::STATUS_VALID)
|
|
|
+ ->where('urs_promotion_user_mappings.promotion_count', '>', 0)
|
|
|
+ ->orderBy('urs_promotion_user_mappings.promotion_count', 'desc')
|
|
|
+ ->limit(10)
|
|
|
+ ->get()
|
|
|
+ ->toArray();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设置卡片内容
|
|
|
+ *
|
|
|
+ * @param array $rankings 排名数据
|
|
|
+ * @return $this
|
|
|
+ */
|
|
|
+ public function withContent(array $rankings)
|
|
|
+ {
|
|
|
+ $directHtml = $this->buildRankingHtml($rankings['direct'], 'direct_count', '直推');
|
|
|
+ $indirectHtml = $this->buildRankingHtml($rankings['indirect'], 'indirect_count', '间推');
|
|
|
+ $thirdHtml = $this->buildRankingHtml($rankings['third'], 'third_count', '三推');
|
|
|
+ $teamHtml = $this->buildRankingHtml($rankings['team'], 'promotion_count', '团队');
|
|
|
+
|
|
|
+ return $this->content(
|
|
|
+ <<<HTML
|
|
|
+<div class="row">
|
|
|
+ <div class="col-6">
|
|
|
+ <h6 class="text-primary">直推排行榜</h6>
|
|
|
+ {$directHtml}
|
|
|
+ </div>
|
|
|
+ <div class="col-6">
|
|
|
+ <h6 class="text-success">间推排行榜</h6>
|
|
|
+ {$indirectHtml}
|
|
|
+ </div>
|
|
|
+</div>
|
|
|
+<div class="row mt-3">
|
|
|
+ <div class="col-6">
|
|
|
+ <h6 class="text-warning">三推排行榜</h6>
|
|
|
+ {$thirdHtml}
|
|
|
+ </div>
|
|
|
+ <div class="col-6">
|
|
|
+ <h6 class="text-info">团队排行榜</h6>
|
|
|
+ {$teamHtml}
|
|
|
+ </div>
|
|
|
+</div>
|
|
|
+HTML
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建排名HTML
|
|
|
+ *
|
|
|
+ * @param array $data 排名数据
|
|
|
+ * @param string $countField 数量字段
|
|
|
+ * @param string $type 类型名称
|
|
|
+ * @return string
|
|
|
+ */
|
|
|
+ private function buildRankingHtml(array $data, string $countField, string $type): string
|
|
|
+ {
|
|
|
+ if (empty($data)) {
|
|
|
+ return '<small class="text-muted">暂无数据</small>';
|
|
|
+ }
|
|
|
+
|
|
|
+ $html = '<div class="ranking-list">';
|
|
|
+ foreach ($data as $index => $item) {
|
|
|
+ $rank = $index + 1;
|
|
|
+ $nickname = $item['nickname'] ?? 'URS用户' . $item['urs_user_id'];
|
|
|
+ $count = $item[$countField] ?? 0;
|
|
|
+
|
|
|
+ $badgeClass = $rank <= 3 ? 'badge-warning' : 'badge-secondary';
|
|
|
+
|
|
|
+ $html .= <<<HTML
|
|
|
+<div class="d-flex justify-content-between align-items-center mb-1">
|
|
|
+ <span class="badge {$badgeClass}">{$rank}</span>
|
|
|
+ <span class="text-truncate mx-2" style="max-width: 80px;" title="{$nickname}">{$nickname}</span>
|
|
|
+ <span class="font-weight-bold">{$count}</span>
|
|
|
+</div>
|
|
|
+HTML;
|
|
|
+ }
|
|
|
+ $html .= '</div>';
|
|
|
+
|
|
|
+ return $html;
|
|
|
+ }
|
|
|
+}
|