115 lines
4.7 KiB
PHP
115 lines
4.7 KiB
PHP
<?php
|
|
|
|
namespace Modules\EcommerceFinance\View;
|
|
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Carbon;
|
|
use Modules\EcommerceFinance\Repositories\DingWorklogMirrorRepository;
|
|
use Throwable;
|
|
|
|
class DingWorklogStatisticsPageData
|
|
{
|
|
public function __construct(
|
|
private readonly DingWorklogMirrorRepository $repository,
|
|
) {}
|
|
|
|
public function page(Request $request): array
|
|
{
|
|
$latestStatisticsDate = now()->hour < 12
|
|
? now()->subDay()->startOfDay()
|
|
: now()->startOfDay();
|
|
$from = $this->date($request->query('from'))
|
|
?? $latestStatisticsDate->copy()->subDays(13);
|
|
$to = $this->date($request->query('to')) ?? $latestStatisticsDate->copy();
|
|
if ($from->greaterThan($to)) {
|
|
[$from, $to] = [$to, $from];
|
|
}
|
|
if ($from->diffInDays($to) > 90) {
|
|
$from = $to->copy()->subDays(90);
|
|
}
|
|
|
|
$state = $this->repository->available() ? $this->repository->state() : null;
|
|
$errorCode = trim((string) ($state['last_error_code'] ?? ''));
|
|
$syncState = match (true) {
|
|
! $this->repository->available() => 'unavailable',
|
|
$errorCode !== '' => 'failed',
|
|
$state === null => 'pending',
|
|
($state['status'] ?? '') === 'running' => 'syncing',
|
|
($state['status'] ?? '') === 'succeeded' => 'succeeded',
|
|
default => 'pending',
|
|
};
|
|
$permissionRequired = DingWorklogMirrorRepository::isPermissionError($errorCode);
|
|
|
|
$daily = [];
|
|
$selectedDate = $this->date($request->query('date'))?->toDateString();
|
|
$submissions = [];
|
|
if ($this->repository->available()) {
|
|
try {
|
|
$daily = $this->repository->dailySummary($from->toDateString(), $to->toDateString());
|
|
$selectedDate ??= $daily[0]['statistics_date'] ?? $latestStatisticsDate->toDateString();
|
|
$submissions = array_map(static fn (object $row): array => [
|
|
'report_id' => (string) $row->report_id,
|
|
'template_name' => (string) ($row->template_name ?? ''),
|
|
'creator_userid' => (string) ($row->creator_userid ?? ''),
|
|
'creator_name' => (string) ($row->creator_name ?? ''),
|
|
'submitted_at' => (string) $row->submitted_at,
|
|
'statistics_date' => (string) $row->statistics_date,
|
|
], $this->repository->submissionsForDate($selectedDate));
|
|
} catch (Throwable $exception) {
|
|
report($exception);
|
|
$syncState = 'failed';
|
|
$errorCode = 'dingtalk_worklog_read_failed';
|
|
}
|
|
}
|
|
|
|
$currentDate = $latestStatisticsDate->toDateString();
|
|
$current = collect($daily)->firstWhere('statistics_date', $currentDate) ?? [
|
|
'statistics_date' => $currentDate,
|
|
'submission_count' => 0,
|
|
'submitter_count' => 0,
|
|
'first_submitted_at' => null,
|
|
'last_submitted_at' => null,
|
|
];
|
|
|
|
return [
|
|
'view' => 'business.pages.other.log-statistics',
|
|
'worklogFilters' => [
|
|
'from' => $from->toDateString(),
|
|
'to' => $to->toDateString(),
|
|
'date' => $selectedDate,
|
|
],
|
|
'worklogState' => [
|
|
'state' => $syncState,
|
|
'error_code' => $errorCode ?: null,
|
|
'permission_required' => $permissionRequired,
|
|
'permission_apply_url' => $permissionRequired ? $this->repository->permissionApplyUrl() : null,
|
|
'status' => $state['status'] ?? null,
|
|
'last_attempted_at' => $state['last_attempted_at'] ?? null,
|
|
'last_succeeded_at' => $state['last_succeeded_at'] ?? null,
|
|
'mirror_row_count' => (int) ($state['mirror_row_count'] ?? 0),
|
|
],
|
|
'worklogCurrent' => $current,
|
|
'worklogDaily' => $daily,
|
|
'worklogSubmissions' => $submissions,
|
|
'worklogDays' => (int) $from->diffInDays($to) + 1,
|
|
'worklogTotalSubmissions' => array_sum(array_column($daily, 'submission_count')),
|
|
'worklogTemplateName' => (string) config('dingtalk.worklog.display_name', '财务日报 / 日志'),
|
|
'worklogCutoffAt' => $latestStatisticsDate->copy()->addDay()->setTime(12, 0)->toDateTimeString(),
|
|
];
|
|
}
|
|
|
|
private function date(mixed $value): ?Carbon
|
|
{
|
|
$value = trim((string) $value);
|
|
if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $value) !== 1) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
return Carbon::createFromFormat('!Y-m-d', $value)->startOfDay();
|
|
} catch (Throwable) {
|
|
return null;
|
|
}
|
|
}
|
|
}
|