From 10a0083cf12eda99e895c87a19e22d237eb64702 Mon Sep 17 00:00:00 2001 From: hashbro Date: Wed, 26 Aug 2026 06:24:27 +0800 Subject: [PATCH] feat: ds --- .../Controllers/Admin/PageVisitController.php | 25 ++++++++++- resources/views/admin/visits/index.blade.php | 12 ++++-- tests/Feature/PageVisitTest.php | 42 +++++++++++++++++++ 3 files changed, 73 insertions(+), 6 deletions(-) diff --git a/app/Http/Controllers/Admin/PageVisitController.php b/app/Http/Controllers/Admin/PageVisitController.php index 715984c..b9bc49b 100644 --- a/app/Http/Controllers/Admin/PageVisitController.php +++ b/app/Http/Controllers/Admin/PageVisitController.php @@ -114,8 +114,9 @@ class PageVisitController extends Controller $q->where('channel_id', 'like', '%'.$channelId.'%'); } - if ($request->query->has('chain') && $request->query('chain') !== '') { - $q->where('chain', (int) $request->query('chain')); + $chain = $this->parseChainFilter($request->query('chain')); + if ($chain !== null) { + $q->where('chain', $chain); } $os = trim((string) $request->query('os', '')); @@ -149,6 +150,26 @@ class PageVisitController extends Controller return $q; } + /** Empty / missing / all = no chain filter. */ + private function parseChainFilter(mixed $raw): ?int + { + if ($raw === null) { + return null; + } + $value = is_string($raw) ? strtolower(trim($raw)) : $raw; + if ($value === '' || $value === 'all' || $value === []) { + return null; + } + if ($value === 0 || $value === '0' || $value === 'coruna') { + return PageVisit::CHAIN_CORUNA; + } + if ($value === 1 || $value === '1' || $value === 'darksword' || $value === 'ds') { + return PageVisit::CHAIN_DARKSWORD; + } + + return null; + } + /** * @return array{0: Carbon, 1: Carbon} */ diff --git a/resources/views/admin/visits/index.blade.php b/resources/views/admin/visits/index.blade.php index 15e5f42..639d3dd 100644 --- a/resources/views/admin/visits/index.blade.php +++ b/resources/views/admin/visits/index.blade.php @@ -23,9 +23,9 @@
@@ -144,7 +144,11 @@ layui.use(['table', 'form', 'layer'], function () { }); form.on('submit(LAY-visit-search)', function (data) { - where = data.field; + var field = data.field || {}; + if (!field.chain || field.chain === 'all') { + delete field.chain; + } + where = field; table.reload('LAY-visit-list', { where: where, page: { curr: 1 } }); return false; }); diff --git a/tests/Feature/PageVisitTest.php b/tests/Feature/PageVisitTest.php index 3c24a0e..914e366 100644 --- a/tests/Feature/PageVisitTest.php +++ b/tests/Feature/PageVisitTest.php @@ -281,6 +281,48 @@ class PageVisitTest extends TestCase ->assertJsonPath('data.0.client_uid', '50624FE26CC4A0DF689EAEA117557C3E'); } + #[Test] + public function visits_data_does_not_filter_chain_until_explicitly_chosen(): void + { + PageVisit::query()->create([ + 'channel_id' => self::CHANNEL, + 'client_uid' => 'aaaaaaaaaaaaaaaa', + 'chain' => PageVisit::CHAIN_CORUNA, + 'os' => 'iOS', + 'created_at' => now(), + ]); + PageVisit::query()->create([ + 'channel_id' => self::CHANNEL, + 'client_uid' => '50624FE26CC4A0DF689EAEA117557C3E', + 'chain' => PageVisit::CHAIN_DARKSWORD, + 'os' => 'iOS', + 'created_at' => now(), + ]); + + $admin = Admin::query()->create(['username' => 'admin', 'password' => 'admin123']); + $this->actingAs($admin, 'admin'); + + foreach (['', 'all'] as $chain) { + $this->getJson(route('admin.visits.data', ['range' => 'today', 'chain' => $chain])) + ->assertOk() + ->assertJsonPath('count', 2); + } + + $this->getJson(route('admin.visits.data', ['range' => 'today'])) + ->assertOk() + ->assertJsonPath('count', 2); + + $this->getJson(route('admin.visits.data', ['range' => 'today', 'chain' => 'coruna'])) + ->assertOk() + ->assertJsonPath('count', 1) + ->assertJsonPath('data.0.chain', 0); + + $this->getJson(route('admin.visits.data', ['range' => 'today', 'chain' => 'darksword'])) + ->assertOk() + ->assertJsonPath('count', 1) + ->assertJsonPath('data.0.chain', 1); + } + #[Test] public function visits_logs_returns_ds_stages(): void {