123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539 |
- <?php
- namespace App\Console\Commands\Dwbs;
- use App\Repositories\Enums\Dwbs\DayTypeEnum;
- use App\Repositories\Enums\Dwbs\StatisticalResourceTypeEnum;
- use App\Repositories\Enums\ModelStatusEnum;
- use App\Repositories\Models\Base\Setting;
- use App\Repositories\Models\Base\User;
- use App\Repositories\Models\Dwbs\Ranking;
- use App\Repositories\Models\Dwbs\StatisticalResource;
- use Carbon\Carbon;
- use Illuminate\Console\Command;
- use Illuminate\Support\Facades\Log;
- use Illuminate\Support\Facades\Storage;
- use Illuminate\Support\Str;
- use Intervention\Image\Facades\Image;
- /**
- * 生成图片
- * @package Prettus\Repository\Generators\Commands
- * @author Anderson Andrade <contato@andersonandra.de>
- */
- class MakeStatisticalResourceCommand extends Command
- {
- /**
- * The name of command.
- *
- * @var string
- */
- protected $signature = 'make:statistical-resource {date?}';
- /**
- * The description of command.
- *
- * @var string
- */
- protected $description = '制造数据';
- /**
- * The type of class being generated.
- *
- * @var string
- */
- protected $type = 'permission';
- const TotalNums = 50;
- const PageNums = 50;
- /**
- * Execute the command.
- *
- * @return void
- * @see fire()
- */
- public function handle()
- {
- $day = $this->argument('date');
- $now = Carbon::now()->toDateString();
- if (!$day) {
- $day = Carbon::yesterday()->toDateString();
- } else {
- $now = Carbon::parse($day)->toDateString();
- $day = Carbon::parse($day)->subDay()->toDateString();
- }
- $this->line($day);
- $isOpenGroup = (bool)Setting::byCodeGetSetting('h5_paihangbang_is_group_user');
- if ($isOpenGroup) {
- $this->openGroup($day, $now);
- return;
- }
- $this->noOpenGroup($day, $now);
- $this->line('ok');
- }
- /**
- * 开分组
- * @param $day
- * @param $now
- * @return void
- */
- public function openGroup($day, $now)
- {
- $userGroupMaps = User::GroupMaps;
- //1.当天的排行榜
- $startTimeTxt = Carbon::parse($day)->startOfDay()->format('Y年m月d日 H:i');
- $endTimeTxt = Carbon::parse($day)->endOfDay()->format('Y年m月d日 H:i');
- $timeTxt = "{$startTimeTxt}-{$endTimeTxt}";
- foreach ($userGroupMaps as $map) {
- $group_id = $map['id'];
- $model = Ranking::query()->where('group_id', $group_id);
- $rankings = $model->clone()->where('day_type', DayTypeEnum::day)->where('day', $day)->with(['user'])->orderByDesc('xuefen')->limit(self::TotalNums)->get()->toArray();
- $this->makeRangingImg($rankings, $timeTxt, $day, DayTypeEnum::day, $group_id);
- $xueba = $model->clone()->where('day_type', DayTypeEnum::day)->where('day', $day)->with(['user'])->where('is_xueba', ModelStatusEnum::OK)->first();
- $this->makeXueBaImg($xueba, $timeTxt, $day, DayTypeEnum::day, $group_id);
- //2.周排行榜
- $firstDay = Carbon::parse($now)->startOfWeek();
- if (Carbon::parse($now)->isSameDay($firstDay)) {
- $startTimeTxt = Carbon::parse($day)->startOfWeek()->format('Y年m月d日 H:i');
- $endTimeTxt = Carbon::parse($day)->endOfWeek()->format('Y年m月d日 H:i');
- $start_day = Carbon::parse($day)->startOfWeek()->toDateString();
- $timeTxt = "{$startTimeTxt}-{$endTimeTxt}";
- $this->line("周:" . $group_id);
- $rankings = $model->clone()->where('day_type', DayTypeEnum::week)->where('day', $start_day)->with('user')->limit(self::TotalNums)->orderByDesc('xuefen')->get();
- $this->makeRangingImg($rankings, $timeTxt, $start_day, DayTypeEnum::week, $group_id);
- $xueba = $model->clone()->where('day_type', DayTypeEnum::week)->where('day', $start_day)->with(['user'])->where('is_xueba', ModelStatusEnum::OK)->first();
- $this->makeXueBaImg($xueba, $timeTxt, $start_day, DayTypeEnum::week, $group_id);
- }
- //3.月排行榜
- $firstDay = Carbon::parse($now)->startOfMonth();
- if (Carbon::parse($now)->isSameDay($firstDay)) {
- $startTimeTxt = Carbon::parse($day)->startOfMonth()->format('Y年m月d日 H:i');
- $endTimeTxt = Carbon::parse($day)->endOfMonth()->format('Y年m月d日 H:i');
- $start_day = Carbon::parse($day)->startOfMonth()->toDateString();
- $timeTxt = "{$startTimeTxt}-{$endTimeTxt}";
- $rankings = $model->clone()->where('day_type', DayTypeEnum::month)->where('day', $start_day)->with('user')->limit(self::TotalNums)->orderByDesc('xuefen')->get();
- $this->makeRangingImg($rankings, $timeTxt, $start_day, DayTypeEnum::month, $group_id);
- $xueba = $model->clone()->where('day_type', DayTypeEnum::month)->where('day', $start_day)->with(['user'])->where('is_xueba', ModelStatusEnum::OK)->first();
- $this->makeXueBaImg($xueba, $timeTxt, $start_day, DayTypeEnum::month, $group_id);
- }
- //4.季排行榜
- $firstDay = Carbon::parse($now)->startOfQuarter();
- if (Carbon::parse($now)->isSameDay($firstDay)) {
- $startTimeTxt = Carbon::parse($day)->startOfQuarter()->format('Y年m月d日 H:i');
- $endTimeTxt = Carbon::parse($day)->endOfQuarter()->format('Y年m月d日 H:i');
- $this->line("季:{$startTimeTxt}--{$endTimeTxt}");
- $timeTxt = "{$startTimeTxt}-{$endTimeTxt}";
- $start_day = Carbon::parse($day)->startOfQuarter()->toDateString();
- $rankings = $model->clone()->where('day_type', DayTypeEnum::quarter)->where('day', $start_day)->with('user')->limit(self::TotalNums)->orderByDesc('xuefen')->get();
- $this->makeRangingImg($rankings, $timeTxt, $start_day, DayTypeEnum::quarter, $group_id);
- $xueba = $model->clone()->where('day_type', DayTypeEnum::quarter)->where('day', $start_day)->with(['user'])->where('is_xueba', ModelStatusEnum::OK)->first();
- $this->makeXueBaImg($xueba, $timeTxt, $start_day, DayTypeEnum::quarter, $group_id);
- }
- //5.年排行榜
- $firstDay = Carbon::parse($now)->startOfYear();
- if (Carbon::parse($now)->isSameDay($firstDay)) {
- $startTimeTxt = Carbon::parse($day)->startOfYear()->format('Y年m月d日 H:i');
- $endTimeTxt = Carbon::parse($day)->endOfYear()->format('Y年m月d日 H:i');
- $start_day = Carbon::parse($day)->startOfYear()->toDateString();
- $timeTxt = "{$startTimeTxt}-{$endTimeTxt}";
- $rankings = $model->clone()->where('day_type', DayTypeEnum::year)->where('day', $start_day)->with('user')->limit(self::TotalNums)->orderByDesc('xuefen')->get();
- $this->makeRangingImg($rankings, $timeTxt, $start_day, DayTypeEnum::year, $group_id);
- $xueba = $model->clone()->where('day_type', DayTypeEnum::year)->where('day', $start_day)->with(['user'])->where('is_xueba', ModelStatusEnum::OK)->first();
- $this->makeXueBaImg($xueba, $timeTxt, $start_day, DayTypeEnum::year, $group_id);
- }
- }
- }
- /**
- * 没有开分组
- * @param $day
- * @param $now
- * @return void
- */
- public function noOpenGroup($day, $now)
- {
- //1.当天的排行榜
- $startTimeTxt = Carbon::parse($day)->startOfDay()->format('Y年m月d日 H:i');
- $endTimeTxt = Carbon::parse($day)->endOfDay()->format('Y年m月d日 H:i');
- $timeTxt = "{$startTimeTxt}-{$endTimeTxt}";
- $rankings = Ranking::query()->where('day_type', DayTypeEnum::day)->where('day', $day)->with(['user'])->orderByDesc('xuefen')->limit(30)->get()->toArray();
- $this->makeRangingImg($rankings, $timeTxt, $day, DayTypeEnum::day);
- $xueba = Ranking::query()->where('day_type', DayTypeEnum::day)->where('day', $day)->with(['user'])->where('is_xueba', ModelStatusEnum::OK)->first();
- $this->makeXueBaImg($xueba, $timeTxt, $day, DayTypeEnum::day);
- //2.周排行榜
- $firstDay = Carbon::parse($now)->startOfWeek();
- if (Carbon::parse($now)->isSameDay($firstDay)) {
- $startTimeTxt = Carbon::parse($day)->startOfWeek()->format('Y年m月d日 H:i');
- $endTimeTxt = Carbon::parse($day)->endOfWeek()->format('Y年m月d日 H:i');
- $start_day = Carbon::parse($day)->startOfWeek()->toDateString();
- $timeTxt = "{$startTimeTxt}-{$endTimeTxt}";
- $rankings = Ranking::query()->where('day_type', DayTypeEnum::week)->where('day', $start_day)->with('user')->limit(self::TotalNums)->orderByDesc('xuefen')->get();
- $this->makeRangingImg($rankings, $timeTxt, $start_day, DayTypeEnum::week);
- $xueba = Ranking::query()->where('day_type', DayTypeEnum::week)->where('day', $start_day)->with(['user'])->where('is_xueba', ModelStatusEnum::OK)->first();
- $this->makeXueBaImg($xueba, $timeTxt, $start_day, DayTypeEnum::week);
- }
- //3.月排行榜
- $firstDay = Carbon::parse($now)->startOfMonth();
- if (Carbon::parse($now)->isSameDay($firstDay)) {
- $startTimeTxt = Carbon::parse($day)->startOfMonth()->format('Y年m月d日 H:i');
- $endTimeTxt = Carbon::parse($day)->endOfMonth()->format('Y年m月d日 H:i');
- $start_day = Carbon::parse($day)->startOfMonth()->toDateString();
- $timeTxt = "{$startTimeTxt}-{$endTimeTxt}";
- $rankings = Ranking::query()->where('day_type', DayTypeEnum::month)->where('day', $start_day)->with('user')->limit(self::TotalNums)->orderByDesc('xuefen')->get();
- $this->makeRangingImg($rankings, $timeTxt, $start_day, DayTypeEnum::month);
- $xueba = Ranking::query()->where('day_type', DayTypeEnum::month)->where('day', $start_day)->with(['user'])->where('is_xueba', ModelStatusEnum::OK)->first();
- $this->makeXueBaImg($xueba, $timeTxt, $start_day, DayTypeEnum::month);
- }
- //4.季排行榜
- $firstDay = Carbon::parse($now)->startOfQuarter();
- if (Carbon::parse($now)->isSameDay($firstDay)) {
- $startTimeTxt = Carbon::parse($day)->startOfQuarter()->format('Y年m月d日 H:i');
- $endTimeTxt = Carbon::parse($day)->endOfQuarter()->format('Y年m月d日 H:i');
- $this->line("季:{$startTimeTxt}--{$endTimeTxt}");
- $timeTxt = "{$startTimeTxt}-{$endTimeTxt}";
- $start_day = Carbon::parse($day)->startOfQuarter()->toDateString();
- $rankings = Ranking::query()->where('day_type', DayTypeEnum::quarter)->where('day', $start_day)->with('user')->limit(self::TotalNums)->orderByDesc('xuefen')->get();
- $this->makeRangingImg($rankings, $timeTxt, $start_day, DayTypeEnum::quarter);
- $xueba = Ranking::query()->where('day_type', DayTypeEnum::quarter)->where('day', $start_day)->with(['user'])->where('is_xueba', ModelStatusEnum::OK)->first();
- $this->makeXueBaImg($xueba, $timeTxt, $start_day, DayTypeEnum::quarter);
- }
- //5.年排行榜
- $firstDay = Carbon::parse($now)->startOfYear();
- if (Carbon::parse($now)->isSameDay($firstDay)) {
- $startTimeTxt = Carbon::parse($day)->startOfYear()->format('Y年m月d日 H:i');
- $endTimeTxt = Carbon::parse($day)->endOfYear()->format('Y年m月d日 H:i');
- $start_day = Carbon::parse($day)->startOfYear()->toDateString();
- $this->line($timeTxt . '==>' . $start_day . '===' . $start_day);
- $timeTxt = "{$startTimeTxt}-{$endTimeTxt}";
- $rankings = Ranking::query()->where('day_type', DayTypeEnum::year)->where('day', $start_day)->with('user')->limit(self::TotalNums)->orderByDesc('xuefen')->get();
- $this->makeRangingImg($rankings, $timeTxt, $start_day, DayTypeEnum::year);
- $xueba = Ranking::query()->where('day_type', DayTypeEnum::year)->where('day', $start_day)->with(['user'])->where('is_xueba', ModelStatusEnum::OK)->first();
- $this->makeXueBaImg($xueba, $timeTxt, $start_day, DayTypeEnum::year);
- }
- }
- /**
- * 生成学霸
- * @param $rankings
- * @param $timeTxt
- * @param $day
- * @param $day_type
- * @param $type
- * @return void
- */
- public function makeXueBaImg($ranking, $timeTxt, $day, $day_type, $group_id = 0)
- {
- $type = StatisticalResourceTypeEnum::xueba;
- $bgPath = Setting::byCodeGetSetting('h5_base_img_xueba_beijingtu') ?? base_path('Data/xueba_bg.jpg');
- $logo = base_path('Data/xueba_logo.jpg');
- try {
- $image = Image::make($bgPath);
- if (!$ranking) return;
- $user = $ranking['user'];
- $name = $this->filterEmoji($user['nickname']);
- $avatar = Image::make($user['headimg'])->resize(830, 830);
- $avatar = $this->imgCircle($avatar, 830);
- $avatar_x = 120;
- $avatar_y = 570;
- $image->insert($avatar, 'top-left', $avatar_x, $avatar_y);
- $image->insert($logo);
- $length = mb_strlen($name);
- if ($length >= 6) {
- $name = mb_substr($name, 0, 6);
- $h = 835 - 40;
- $y = 80;
- } elseif ($length == 5) {
- $h = 835 - 20;
- $y = 80;
- } elseif ($length == 4) {
- $h = 835;
- $y = 80;
- } elseif ($length == 3) {
- $h = 835 + 40;
- $y = 120;
- } elseif ($length == 2) {
- $h = 835 + 80;
- $y = 160;
- } else {
- $h = 835 + 160;
- $y = 0;
- }
- for ($i = 0; $i < $length; $i++) {
- $this->addText($image, mb_substr($name, $i, 1), 951, $h + $i * $y, 83, 'fff');
- }
- $timeTxt = Carbon::parse($day)->format("m月d日");
- $this->addText($image, $timeTxt, 250, 440, 150, 'FFF', base_path("Data/ziti/zi.otf"));
- $dir = "xuebaImg/" . $day_type . '/' . $day;
- $filename = Str::random() . '.png';
- Storage::disk('public')->put("{$dir}/{$filename}.txt", 1);
- $path = Storage::disk('public')->path("{$dir}/{$filename}");
- $image->save($path);
- Storage::disk('public')->delete("{$dir}/{$filename}.txt");
- StatisticalResource::query()->updateOrCreate([
- 'day_type' => $day_type,
- 'day' => $day,
- 'type' => $type,
- 'group_id' => $group_id,
- ], [
- 'page' => 1,
- 'status' => ModelStatusEnum::OK,
- 'path' => "{$dir}/{$filename}",
- 'user_ids' => [$user['id']]
- ]);
- } catch (\Exception $exception) {
- log_record('排行榜生成异常', compact('ranking', 'bgPath', 'timeTxt', 'day_type', 'day'));
- Log::error($exception);
- }
- }
- /**
- * 生成排行榜
- * @param $rankings
- * @param $timeTxt
- * @param $day
- * @param $day_type
- * @param $type
- * @return void
- */
- public function makeRangingImg($rankings, $timeTxt, $day, $day_type, $group_id = 0)
- {
- $type = StatisticalResourceTypeEnum::paihangbang;
- if ($group_id) {
- $bgPath = Setting::byCodeGetSetting('h5_base_img_ranking_group_' . $group_id);
- } else {
- $bgPath = Setting::byCodeGetSetting('h5_base_img_ranking');
- }
- $bgPath = $bgPath ?? base_path('Data/paihangbang_bg.jpg');
- log_record('学霸', ['bg' => $bgPath, 'day' => $day, 'day_type' => $day_type, 'group_id' => $group_id]);
- $start_x = 90;
- $x_py = 490;
- $start_y = 750;
- $y_py = 0;
- $pageNums = 15;
- $rowY = 77;
- $count = count($rankings);
- if (!$count) return;
- $tPage = ceil($count / self::PageNums);
- try {
- for ($page = 0; $page < $tPage; $page++) {
- $image = Image::make($bgPath);
- $headimgBg = Image::make(base_path('Data/headimg_bg.png'));
- $user_ids = [];
- foreach ($rankings as $k => $ranking) {
- $user = $ranking['user'];
- $user_ids[] = $user['id'];
- $num = $k + 1 + ($page * 30);
- $name = "{$num}." . self::filterEmoji($user['nickname']);
- $avatar = Image::make($user['headimg']);
- $avatar = self::imgCircle($avatar, 60);
- $score = $ranking['xuefen'];
- if ($k >= ($pageNums * 2)) continue;
- $h = $k;
- if ($k >= $pageNums) {
- $start_x += $x_py;
- $h -= $pageNums;
- }
- $avatar_x = $start_x;
- $name_x = $start_x + 83;
- $score_x = $start_x + 367;
- $name_y = $start_y + $h * $rowY;
- $score_y = $start_y + $h * $rowY;
- $avatar_y = $start_y - 40 + $h * $rowY;
- // $avatar_x = 72;
- // $name_x = 155;
- // $score_x = 439;
- //
- // $jt = -300;
- // $avatar_y = 1000 + ($k) * 80 + $jt;
- // $name_y = 1040 + ($k) * 80 + $jt;
- // $score_y = 1040 + ($k) * 80 + $jt;
- //
- // if ($k >= 15) {
- //
- // $avatar_y = 1000 + ($k - 15) * 80 + $jt;
- // $name_y = 1040 + ($k - 15) * 80 + $jt;
- // $score_y = 1040 + ($k - 15) * 80 + $jt;
- //
- // $avatar_x = 578;
- // $name_x = 660;
- // $score_x = 947;
- // }
- $image->insert($avatar, 'top-left', $avatar_x, $avatar_y);
- $image->insert($headimgBg, 'top-left', $avatar_x, $avatar_y);
- $this->addText($image, $name, $name_x, $name_y, 30, '000');
- $this->addText($image, $score, $score_x, $score_y, 30, '000');
- }
- self::addText($image, $timeTxt, 101, 2320, 41, 'F8ECD2');
- $dir = "rankImg/" . $day_type . '/' . $day;
- $filename = Str::random() . '.png';
- Storage::disk('public')->put("{$dir}/{$filename}.txt", 1);
- $path = Storage::disk('public')->path("{$dir}/{$filename}");
- $image->save($path);
- Storage::disk('public')->delete("{$dir}/{$filename}.txt");
- StatisticalResource::query()->updateOrCreate([
- 'day_type' => $day_type,
- 'day' => $day,
- 'type' => $type,
- 'page' => ($page + 1),
- 'group_id' => $group_id
- ], [
- 'user_ids' => $user_ids,
- 'status' => ModelStatusEnum::OK,
- 'path' => "{$dir}/{$filename}"
- ]);
- }
- } catch (\Exception $exception) {
- log_record('排行榜生成异常', compact('rankings', 'bgPath', 'timeTxt', 'day_type', 'day'));
- Log::error($exception);
- }
- }
- public static function addText(&$bgImage, $text, $x, $y, $size, $color, $ziti = '')
- {
- if (!$ziti) $ziti = base_path('Data/ziti/ht.otf');
- // $y += ($size / 2);
- $bgImage->text($text, $x, $y, function ($font) use ($size, $color, $ziti) {
- $font->file($ziti);
- $font->size($size);
- $font->color($color);
- $font->angle(0);
- });
- // return $bgImage;
- }
- /**
- * 处理头像
- * @param $path
- * @return \Intervention\Image\Image
- */
- private static function imgCircle($img2, $size = 60)
- {
- $img2 = $img2->resize($size, $size);
- $r = $img2->width() / 2;
- $img3 = Image::canvas($size, $size);
- for ($x = 0; $x < $img2->width(); $x++) {
- for ($y = 0; $y < $img2->height(); $y++) {
- if (((($x - $r) * ($x - $r) + ($y - $r) * ($y - $r)) < ($r * $r))) {
- $c = $img2->pickColor($x, $y, 'array');
- $img3->pixel($c, $x, $y);
- }
- }
- }
- return $img3;
- }
- /**
- * 过滤符号
- * @param $str
- * @return mixed
- */
- private static function filterEmoji($str, $maxLen = 5)
- {
- $str = json_encode($str);
- $str = json_decode(preg_replace("#(\\\ud[0-9a-f]{3})#i", "", $str));
- if (mb_strlen($str) > $maxLen) {
- $str = mb_substr($str, 0, $maxLen);
- }
- return $str;
- }
- private static function getImgPath($dir_fix, $day_type, $day)
- {
- $dir = "{$dir_fix}/" . $day_type . '/' . $day;
- $filename = Str::random() . '.png';
- Storage::disk('public')->put("{$dir}/{$filename}.txt", 1);
- $path = Storage::disk('public')->path("{$dir}/{$filename}");
- return [
- 'path' => $path,
- 'xd_path' => "{$dir}/{$filename}",
- 'ls_file' => "{$dir}/{$filename}.txt"
- ];
- }
- }
|