86 lines
3.0 KiB
PHP
86 lines
3.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace plugin\produce\app\service\admin;
|
|
|
|
use Illuminate\Database\Query\Builder;
|
|
use plugin\produce\app\model\ExceptionRecord;
|
|
|
|
class ExceptionAnalysisService
|
|
{
|
|
public function overview(array $params): array
|
|
{
|
|
$query = $this->query($params);
|
|
|
|
return [
|
|
'total' => (clone $query)->count(),
|
|
'pending' => (clone $query)->where('status', 0)->count(),
|
|
'processing' => (clone $query)->where('status', 1)->count(),
|
|
'completed' => (clone $query)->where('status', 2)->count(),
|
|
'by_type' => $this->group($params, 'type_code', 'type_name'),
|
|
'by_reason' => $this->group($params, 'reason_code', 'reason_name'),
|
|
'by_issue' => $this->group($params, 'issue_code', 'issue_name'),
|
|
'by_date' => $this->byDate($params),
|
|
];
|
|
}
|
|
|
|
private function group(array $params, string $codeColumn, string $nameColumn): array
|
|
{
|
|
return $this->query($params)
|
|
->selectRaw("{$codeColumn} as code, {$nameColumn} as name, COUNT(*) as total")
|
|
->groupBy($codeColumn, $nameColumn)
|
|
->orderByDesc('total')
|
|
->orderBy($nameColumn)
|
|
->limit(20)
|
|
->get()
|
|
->map(static fn (object $item): array => [
|
|
'code' => (string) $item->code,
|
|
'name' => (string) $item->name,
|
|
'total' => (int) $item->total,
|
|
])
|
|
->all();
|
|
}
|
|
|
|
private function byDate(array $params): array
|
|
{
|
|
$model = new ExceptionRecord();
|
|
$connection = $model->getConnection();
|
|
$table = $connection->getTablePrefix() . $model->getTable();
|
|
|
|
return $this->query($params)
|
|
->selectRaw("DATE_FORMAT(FROM_UNIXTIME({$table}.reported_at), '%Y-%m-%d') as date, COUNT(*) as total")
|
|
->groupBy('date')
|
|
->orderBy('date')
|
|
->get()
|
|
->map(static fn (object $item): array => [
|
|
'date' => (string) $item->date,
|
|
'total' => (int) $item->total,
|
|
])
|
|
->all();
|
|
}
|
|
|
|
private function query(array $params): Builder
|
|
{
|
|
$model = new ExceptionRecord();
|
|
$query = $model->getConnection()->table($model->getTable())->whereNull('deleted_at');
|
|
|
|
foreach (['type_code', 'reason_code', 'issue_code', 'status'] as $field) {
|
|
if (($params[$field] ?? '') !== '') {
|
|
$query->where($field, $params[$field]);
|
|
}
|
|
}
|
|
|
|
if (!empty($params['reported_at_range']) && is_array($params['reported_at_range']) && count($params['reported_at_range']) === 2) {
|
|
$query->whereBetween('reported_at', [
|
|
strtotime((string) $params['reported_at_range'][0] . ' 00:00:00'),
|
|
strtotime((string) $params['reported_at_range'][1] . ' 23:59:59'),
|
|
]);
|
|
} else {
|
|
$query->whereBetween('reported_at', [strtotime('-29 days 00:00:00'), time()]);
|
|
}
|
|
|
|
return $query;
|
|
}
|
|
}
|