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

1 month ago
<?php
namespace App\Services;
5 days ago
use App\Models\SystemSetting;
1 month ago
use App\Models\WechatUser;
use App\Models\WechatUserHomeVisit;
use Illuminate\Support\Carbon;
class WechatHomeVisitService
{
5 days ago
public const KEY_TOTAL_OFFSET = 'home_visit_total_offset';
public const KEY_TODAY_OFFSET = 'home_visit_today_offset';
2 days ago
public const KEY_TODAY_OFFSET_DATE = 'home_visit_today_offset_date';
1 month ago
public function record(WechatUser $user): void
{
WechatUserHomeVisit::query()->create([
'wechat_user_id' => $user->id,
'visited_at' => now(),
]);
}
5 days ago
public function actualTotalVisits(): int
1 month ago
{
return (int) WechatUserHomeVisit::query()->count();
}
5 days ago
public function actualTodayVisits(): int
1 month ago
{
$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();
}
5 days ago
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
{
2 days ago
$today = Carbon::now((string) config('app.timezone'))->toDateString();
$offsetDate = SystemSetting::getString(self::KEY_TODAY_OFFSET_DATE);
if ($offsetDate !== $today) {
return 0;
}
5 days ago
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(),
);
2 days ago
$today = Carbon::now((string) config('app.timezone'))->toDateString();
5 days ago
SystemSetting::setInt(
self::KEY_TODAY_OFFSET,
$displayToday - $this->actualTodayVisits(),
);
2 days ago
SystemSetting::setString(self::KEY_TODAY_OFFSET_DATE, $today);
5 days ago
}
1 month ago
public function totalWechatUsers(): int
{
return (int) WechatUser::query()->count();
}
}