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
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();
|
|
}
|
|
}
|