You can not 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
2.9 KiB

<?php
namespace App\Services;
use App\Models\SystemSetting;
use App\Models\WechatUser;
use App\Models\WechatUserHomeVisit;
use Illuminate\Support\Carbon;
class WechatHomeVisitService
{
public const KEY_TOTAL_OFFSET = 'home_visit_total_offset';
public const KEY_TODAY_OFFSET = 'home_visit_today_offset';
public const KEY_TODAY_OFFSET_DATE = 'home_visit_today_offset_date';
public function record(WechatUser $user): void
{
WechatUserHomeVisit::query()->create([
'wechat_user_id' => $user->id,
'visited_at' => now(),
]);
}
public function actualTotalVisits(): int
{
return (int) WechatUserHomeVisit::query()->count();
}
public function actualTodayVisits(): int
{
$tz = (string) config('app.timezone');
$start = Carbon::now($tz)->startOfDay();
$end = Carbon::now($tz)->endOfDay();
return (int) WechatUserHomeVisit::query()
->whereBetween('visited_at', [$start, $end])
->count();
}
public function totalVisits(): int
{
return max(0, $this->actualTotalVisits() + $this->totalOffset());
}
public function todayVisits(): int
{
return max(0, $this->actualTodayVisits() + $this->todayOffset());
}
public function totalOffset(): int
{
return SystemSetting::getInt(self::KEY_TOTAL_OFFSET, 0);
}
public function todayOffset(): int
{
$today = Carbon::now((string) config('app.timezone'))->toDateString();
$offsetDate = SystemSetting::getString(self::KEY_TODAY_OFFSET_DATE);
if ($offsetDate !== $today) {
return 0;
}
return SystemSetting::getInt(self::KEY_TODAY_OFFSET, 0);
}
/**
* @return array{
* actual_total: int,
* actual_today: int,
* display_total: int,
* display_today: int,
* total_offset: int,
* today_offset: int
* }
*/
public function visitStatsPayload(): array
{
return [
'actual_total' => $this->actualTotalVisits(),
'actual_today' => $this->actualTodayVisits(),
'display_total' => $this->totalVisits(),
'display_today' => $this->todayVisits(),
'total_offset' => $this->totalOffset(),
'today_offset' => $this->todayOffset(),
];
}
public function updateDisplayValues(int $displayTotal, int $displayToday): void
{
SystemSetting::setInt(
self::KEY_TOTAL_OFFSET,
$displayTotal - $this->actualTotalVisits(),
);
$today = Carbon::now((string) config('app.timezone'))->toDateString();
SystemSetting::setInt(
self::KEY_TODAY_OFFSET,
$displayToday - $this->actualTodayVisits(),
);
SystemSetting::setString(self::KEY_TODAY_OFFSET_DATE, $today);
}
public function totalWechatUsers(): int
{
return (int) WechatUser::query()->count();
}
}