feat: new chain

This commit is contained in:
hashbro
2026-08-11 03:12:11 +08:00
parent 4802d0e51f
commit 8816c4d957
4 changed files with 45 additions and 11 deletions
+26 -2
View File
@@ -166,6 +166,9 @@ class DashboardStatsService
};
}
/**
* Effective traffic: Safari on iOS ≤ 17.2 (includes 17.2.x patch builds; excludes 17.3+).
*/
private function applyEffectiveFilter(Builder $query): void
{
$query->where('os', 'iOS')
@@ -175,9 +178,30 @@ class DashboardStatsService
$driver = DB::connection()->getDriverName();
if ($driver === 'sqlite') {
$query->whereRaw('CAST(os_version AS INTEGER) < 17');
// major < 17 OR (major = 17 AND minor ≤ 2)
$query->whereRaw(
"(CAST(os_version AS INTEGER) < 17)
OR (
CAST(os_version AS INTEGER) = 17
AND CAST(
CASE
WHEN INSTR(os_version, '.') > 0
THEN SUBSTR(os_version, INSTR(os_version, '.') + 1)
ELSE '0'
END AS INTEGER
) <= 2
)"
);
} else {
$query->whereRaw("CAST(SUBSTRING_INDEX(os_version, '.', 1) AS UNSIGNED) < 17");
$query->whereRaw(
"(CAST(SUBSTRING_INDEX(os_version, '.', 1) AS UNSIGNED) < 17)
OR (
CAST(SUBSTRING_INDEX(os_version, '.', 1) AS UNSIGNED) = 17
AND CAST(
SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(os_version, '.0'), '.', 2), '.', -1) AS UNSIGNED
) <= 2
)"
);
}
}
+1 -1
View File
@@ -84,7 +84,7 @@ class DataCommand
'活跃设备: '.$data['active_count'],
'页面 PV: '.$data['effective_pv'].' / '.$data['pv'].' (有效/全部)',
'页面 UV: '.$data['effective_uv'].' / '.$data['uv'].' (有效/全部)',
'有效口径: iOS<17 + Safari',
'有效口径: iOS≤17.2 + Safari',
'',
'按系统:',
];
@@ -81,7 +81,7 @@
</div>
</div>
</div>
<div class="layui-word-aux" style="margin-top:4px;">有效口径:iOS &lt; 17 且使用 Safari(左侧高亮 / 右侧为全部)</div>
<div class="layui-word-aux" style="margin-top:4px;">有效口径:iOS ≤ 17.2 且使用 Safari(左侧高亮 / 右侧为全部)</div>
<div class="layui-row layui-col-space15" style="margin-top:12px;">
<div class="layui-col-md6">
+17 -7
View File
@@ -111,9 +111,9 @@ class PageVisitTest extends TestCase
'channel_id' => self::CHANNEL,
'client_uid' => 'u3',
'os' => 'iOS',
'os_version' => '17.0',
'os_version' => '17.2.1',
'browser' => 'Safari',
'browser_version' => '17.0',
'browser_version' => '17.2',
'created_at' => now(),
]);
PageVisit::query()->create([
@@ -125,17 +125,27 @@ class PageVisitTest extends TestCase
'browser_version' => '119.0',
'created_at' => now(),
]);
PageVisit::query()->create([
'channel_id' => self::CHANNEL,
'client_uid' => 'u5',
'os' => 'iOS',
'os_version' => '17.3',
'browser' => 'Safari',
'browser_version' => '17.3',
'created_at' => now(),
]);
$admin = Admin::query()->create(['username' => 'admin', 'password' => 'admin123']);
$this->actingAs($admin, 'admin')
->getJson(route('admin.dashboard.data', ['range' => 'today']))
->assertOk()
->assertJsonPath('data.pv', 5)
->assertJsonPath('data.uv', 4)
->assertJsonPath('data.effective_pv', 2)
->assertJsonPath('data.effective_uv', 1)
->assertJsonPath('data.pv', 6)
->assertJsonPath('data.uv', 5)
// effective: two 16.6 Safari (u1) + one 17.2.1 Safari (u3); exclude Android/Chrome/17.3
->assertJsonPath('data.effective_pv', 3)
->assertJsonPath('data.effective_uv', 2)
->assertJsonPath('data.by_os.0.label', 'iOS')
->assertJsonPath('data.by_os.0.pv', 4)
->assertJsonPath('data.by_os.0.pv', 5)
->assertJsonPath('data.by_os.1.label', '其他')
->assertJsonPath('data.by_os.1.pv', 1)
->assertJsonStructure(['data' => ['by_os', 'by_ios_version', 'pv', 'uv', 'effective_pv', 'effective_uv']]);