You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

111 lines
3.8 KiB
PHTML

2 years ago
<?php
declare(strict_types=1);
namespace App\Service;
use App\Helper\Time;
use App\Model\Player;
use App\Model\PlayerRetention;
use App\Model\Promote;
use App\Model\PromoteCompany;
use Hyperf\DbConnection\Db;
class PlayerService extends Service
{
public function getPlayerRetention(array $params): array
{
$startTime = $params['start_time'] ?? date('Y-m-d');
$endTime = $params['end_time'] ?? date('Y-m-d');
$gameIds = $params['game_ids'] ?? [];
$promoteId = $params['promote_id'] ?? 0;
$companyId = $params['company_id'] ?? 0;
$gameId = $params['game_id'] ?? 0;
if (empty($gameIds) && $gameId) {
$gameIds = [$gameId];
}
$promote = null;
$promoteCompany = null;
if ($promoteId) {
$promote = Promote::where('id', $promoteId)->first(['id', 'chain', 'parent_id']);
} elseif ($companyId) {
$promoteCompany = PromoteCompany::where('id', $promoteId)->first(['id']);
}
$dateList = Time::getDateList($startTime, $endTime);
$startTime = strtotime($startTime . ' 00:00:00');
$endTime = strtotime($endTime . ' 23:59:59');
$dailyData = $this->getDailyRetention($startTime, $endTime, $gameIds, $promote, $promoteCompany);
$dailyRecords = [];
foreach ($dailyData as $item) {
$dailyRecords[$item->date] = $item;
}
$query = Player::select(DB::raw('FROM_UNIXTIME(create_time, "%Y-%m-%d") date'), DB::raw('count(*) count'))
->whereBetween('create_time', [$startTime, $endTime])
->whereIn('game_id', $gameIds);
if ($promote) {
$query->ofPromote($promote, true);
} elseif ($promoteCompany) {
$query->ofPromoteCompany($promoteCompany);
}
$countList = $query->groupBy('date')->get()->pluck('count', 'date');
$records = [];
foreach ($dateList as $date) {
$record = [
'date' => $date,
'register_count' => isset($countList[$date]) ? $countList[$date] : 0,
];
foreach (PlayerRetention::$dayList as $day) {
$item = $dailyRecords[$date] ?? null;
$record['retention_day' . $day] = $item ? $item->{'day' . $day} : 0;
}
$records[] = $record;
}
return $records;
}
public function getDailyRetention($start, $end, $gameIds, $promote = null, $promoteCompany = null)
{
$columns = [
'FROM_UNIXTIME(b.create_time, "%Y-%m-%d") date',
'sum(day1) day1',
'sum(day2) day2',
'sum(day3) day3',
'sum(day4) day4',
'sum(day5) day5',
'sum(day6) day6',
'sum(day7) day7',
'sum(day15) day15',
'sum(day30) day30'
];
$query = PlayerRetention::fromAlias('a')
->select(Db::raw(implode(',', $columns)))
->leftJoin(Player::alias('b'), function ($join) {
$join->on('a.player_id', '=', 'b.id');
})
->whereBetween('b.create_time', [$start, $end])
->whereIn('a.game_id', $gameIds)
->groupBy('date');
$promoteTable = Promote::alias('c');
if ($promote) {
$query->leftJoin($promoteTable, function ($join) {
$join->on('b.promote_id', '=', 'c.id');
})->whereRaw('(c.chain like "'. $promote->chain . $promote->id . '/%" or c.id=' . $promote->id . ')');
} elseif ($promoteCompany) {
$query->leftJoin($promoteTable, function ($join) {
$join->on('b.promote_id', '=', 'c.id');
})->whereRaw('c.company_id = ' . $promoteCompany->id);
}
return $query->get();
}
}