diff --git a/public/js/admin.js b/public/js/admin.js index 4f19b00..14ea55d 100644 --- a/public/js/admin.js +++ b/public/js/admin.js @@ -120,6 +120,71 @@ }); })(); + // 仪表盘:卡片高度对齐(趋势/收费工作台 与 最近平台订单对齐) + // 说明:运营端希望两列的高度视觉一致,减少右侧“短一截”的割裂感。 + // 策略:以“最近平台订单”卡片的实际高度作为基准,将同列的趋势/收费工作台设置为同样的 minHeight(仅增不减)。 + (function () { + var root = qs('[data-page="admin.dashboard"]'); + if (!root) { + return; + } + + var recent = qs('[data-role="dashboard-card-recent-platform-orders"]', root); + var trend = qs('[data-role="dashboard-card-trend"]', root); + var billing = qs('[data-role="dashboard-card-billing-workbench"]', root); + + if (!recent || (!trend && !billing)) { + return; + } + + function sync() { + try { + var h = recent.getBoundingClientRect().height; + if (!h || h <= 0) { + return; + } + + // 仅增不减:避免小屏/内容变少时出现“强行撑高”的奇怪滚动体验。 + [trend, billing].forEach(function (el) { + if (!el) { + return; + } + try { + var cur = el.getBoundingClientRect().height; + if (!cur || cur <= 0) { + cur = 0; + } + if (cur < h) { + el.style.minHeight = Math.round(h) + 'px'; + } + } catch (e) {} + }); + } catch (e) {} + } + + // 首次 + 下一帧(等待图片/字体/表格渲染稳定) + sync(); + try { + window.requestAnimationFrame(sync); + window.setTimeout(sync, 60); + window.setTimeout(sync, 200); + } catch (e) {} + + // 监听 resize + try { + window.addEventListener('resize', function () { + // 清空后重新计算(避免从大到小的缩放残留) + if (trend) { + trend.style.minHeight = ''; + } + if (billing) { + billing.style.minHeight = ''; + } + sync(); + }); + } catch (e) {} + })(); + // 仪表盘:迷你图表(趋势图渐进增强) // 说明:不引入图表库,避免构建链;用 div bar 方式渲染。 (function () { diff --git a/resources/views/admin/dashboard.blade.php b/resources/views/admin/dashboard.blade.php index a761f64..2374562 100644 --- a/resources/views/admin/dashboard.blade.php +++ b/resources/views/admin/dashboard.blade.php @@ -78,7 +78,7 @@
-
+

趋势

近7天|平台订单(按天)
@@ -248,7 +248,7 @@
-
+

收费工作台(快捷治理)

聚焦收费闭环的日常治理入口:订单 → 订阅 → 套餐。
@@ -298,7 +298,7 @@
-
+

最近平台订单

@php diff --git a/tests/Feature/AdminDashboardCardsHeightSyncRolesShouldRenderTest.php b/tests/Feature/AdminDashboardCardsHeightSyncRolesShouldRenderTest.php new file mode 100644 index 0000000..d4dd32d --- /dev/null +++ b/tests/Feature/AdminDashboardCardsHeightSyncRolesShouldRenderTest.php @@ -0,0 +1,35 @@ +seed(); + + $this->post('/admin/login', [ + 'email' => 'platform.admin@demo.local', + 'password' => 'Platform@123456', + ])->assertRedirect('/admin'); + } + + public function test_dashboard_should_render_height_sync_roles(): void + { + $this->loginAsPlatformAdmin(); + + $res = $this->get('/admin'); + $res->assertOk(); + + $html = (string) $res->getContent(); + + $this->assertStringContainsString('data-role="dashboard-card-trend"', $html); + $this->assertStringContainsString('data-role="dashboard-card-billing-workbench"', $html); + $this->assertStringContainsString('data-role="dashboard-card-recent-platform-orders"', $html); + } +} diff --git a/tests/Feature/AdminJsDashboardCardsHeightSyncShouldUseRecentOrdersHeightTest.php b/tests/Feature/AdminJsDashboardCardsHeightSyncShouldUseRecentOrdersHeightTest.php new file mode 100644 index 0000000..ef4f29e --- /dev/null +++ b/tests/Feature/AdminJsDashboardCardsHeightSyncShouldUseRecentOrdersHeightTest.php @@ -0,0 +1,20 @@ +assertStringContainsString('dashboard-card-recent-platform-orders', $js); + $this->assertStringContainsString('dashboard-card-trend', $js); + $this->assertStringContainsString('dashboard-card-billing-workbench', $js); + } +}