TotalUsers.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <?php
  2. namespace App\Admin\Metrics;
  3. use App\Models\User;
  4. use Carbon\Carbon;
  5. use Dcat\Admin\Widgets\Metrics\Card;
  6. use Illuminate\Contracts\Support\Renderable;
  7. use Illuminate\Http\Request;
  8. class TotalUsers extends Card
  9. {
  10. /**
  11. * 卡片底部内容.
  12. *
  13. * @var string|Renderable|\Closure
  14. */
  15. protected $footer;
  16. /**
  17. * 初始化卡片.
  18. */
  19. protected function init()
  20. {
  21. parent::init();
  22. $this->title('用户');
  23. $this->dropdown([
  24. '1' => '当日新增用户',
  25. '7' => '7天新增用户',
  26. '30' => '当月新增用户',
  27. '-1' => '总用户',
  28. ]);
  29. }
  30. /**
  31. * 处理请求.
  32. *
  33. * @param Request $request
  34. *
  35. * @return void
  36. */
  37. public function handle(Request $request)
  38. {
  39. switch ($request->get('option')) {
  40. case '-1':
  41. $this->content($this->getUsers());
  42. $this->up(100);
  43. break;
  44. case '7':
  45. $startAt = Carbon::now()->subDays(7)->toDateString().' 23:59:59';
  46. $endAt = Carbon::now()->toDateString().' 23:59:59';
  47. $today = $this->getUsers($startAt, $endAt);
  48. $this->content($today);
  49. // 计算上7天
  50. $startAt = Carbon::now()->subDays(14)->toDateString().' 23:59:59';
  51. $endAt = Carbon::now()->subDays(7)->toDateString().' 23:59:59';
  52. $this->calcPercent($today, $startAt, $endAt);
  53. break;
  54. case '30':
  55. $startAt = Carbon::now()->subDays(30)->toDateString().' 23:59:59';
  56. $endAt = Carbon::now()->toDateString().' 23:59:59';
  57. $today = $this->getUsers($startAt, $endAt);
  58. $this->content($today);
  59. // 计算上个月
  60. $startAt = Carbon::now()->subDays(60)->toDateString().' 23:59:59';
  61. $endAt = Carbon::now()->subDays(30)->toDateString().' 23:59:59';
  62. $this->calcPercent($today, $startAt, $endAt);
  63. break;
  64. case '1':
  65. default:
  66. $startAt = Carbon::now()->subDay()->toDateString().' 23:59:59';
  67. $endAt = Carbon::now()->toDateString().' 23:59:59';
  68. $today = $this->getUsers($startAt, $endAt);
  69. $this->content($today);
  70. // 计算前天
  71. $startAt = Carbon::now()->subDays(2)->toDateString().' 23:59:59';
  72. $endAt = Carbon::now()->subDay()->toDateString().' 23:59:59';
  73. $this->calcPercent($today, $startAt, $endAt);
  74. break;
  75. }
  76. }
  77. private function calcPercent($today, $startAt, $endAt)
  78. {
  79. $yesterday = $this->getUsers($startAt, $endAt);
  80. // 百分比
  81. $percent = $yesterday ? ($today - $yesterday) / $yesterday : 0;
  82. $percent = round($percent, 2) * 100;
  83. $percent > 0 ? $this->up($percent) : $this->down($percent < 0 ? -$percent : $percent);
  84. }
  85. private function getUsers($startAt = '', $endAt = ''): int
  86. {
  87. return User::when($startAt, function ($query) use ($startAt) {
  88. $query->where('created_at', '>', $startAt);
  89. })->when($endAt, function ($query) use ($endAt) {
  90. $query->where('created_at', '<=', $endAt);
  91. })->count();
  92. }
  93. /**
  94. * @param int $percent
  95. *
  96. * @return $this
  97. */
  98. public function up($percent)
  99. {
  100. return $this->footer(
  101. "<i class=\"feather icon-trending-up text-success\"></i> {$percent}% 增加"
  102. );
  103. }
  104. /**
  105. * @param int $percent
  106. *
  107. * @return $this
  108. */
  109. public function down($percent)
  110. {
  111. return $this->footer(
  112. "<i class=\"feather icon-trending-down text-danger\"></i> {$percent}% 减少"
  113. );
  114. }
  115. /**
  116. * 设置卡片底部内容.
  117. *
  118. * @param string|Renderable|\Closure $footer
  119. *
  120. * @return $this
  121. */
  122. public function footer($footer)
  123. {
  124. $this->footer = $footer;
  125. return $this;
  126. }
  127. /**
  128. * 渲染卡片内容.
  129. *
  130. * @return string
  131. */
  132. public function renderContent()
  133. {
  134. $content = parent::renderContent();
  135. return <<<HTML
  136. <div class="d-flex justify-content-between align-items-center mt-1" style="margin-bottom: 2px">
  137. <h2 class="ml-1 font-lg-1">{$content}</h2>
  138. </div>
  139. <div class="ml-1 mt-1 font-weight-bold text-80">
  140. {$this->renderFooter()}
  141. </div>
  142. HTML;
  143. }
  144. /**
  145. * 渲染卡片底部内容.
  146. *
  147. * @return string
  148. */
  149. public function renderFooter()
  150. {
  151. return $this->toString($this->footer);
  152. }
  153. }