feat: new chain
This commit is contained in:
@@ -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
|
||||
)"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 < 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">
|
||||
|
||||
@@ -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']]);
|
||||
|
||||
Reference in New Issue
Block a user