diff --git a/public/css/admin-components.css b/public/css/admin-components.css index 5a27478..3ef2a5d 100644 --- a/public/css/admin-components.css +++ b/public/css/admin-components.css @@ -418,6 +418,22 @@ text-decoration:none; } +/* 迷你占比:整行可点击(JS 渐进增强把 row 渲染为 ) */ +.adm-mini-share-row-link{ + display:flex; + align-items:center; + gap:10px; + color:inherit; + text-decoration:none; + border-radius:10px; + padding:2px 4px; +} + +.adm-mini-share-row-link:hover{ + background:var(--adm-primary-tint-06, rgba(22, 119, 255, .06)); + text-decoration:none; +} + .adm-mini-rank-name{ width:72px; min-width:72px; diff --git a/public/js/admin.js b/public/js/admin.js index be7720c..ce405f5 100644 --- a/public/js/admin.js +++ b/public/js/admin.js @@ -320,6 +320,22 @@ return; } + // 渐进增强:从下方表格复用“套餐→订单集合”链接口径(避免硬编码 URL 规则)。 + var planIdToHref = {}; + try { + var planLinks = document.querySelectorAll('[data-role="plan-order-share-top5"] a.link[href*="plan_id="]'); + planLinks.forEach(function (a) { + var href = String(a.getAttribute('href') || ''); + var m = href.match(/[?&]plan_id=(\d+)/); + if (!m) { + return; + } + planIdToHref[String(m[1])] = href; + }); + } catch (e) { + planIdToHref = {}; + } + // 视觉口径:bar 宽度按 Top5 内最大值归一(更易读);百分比仍按 total 分母计算。 var maxCnt = 0; points.forEach(function (p) { @@ -339,8 +355,17 @@ var ratio = total > 0 ? Math.max(0, Math.min(1, cnt / total)) : 0; var barRatio = maxCnt > 0 ? Math.max(0, Math.min(1, cnt / maxCnt)) : 0; - var row = document.createElement('div'); - row.className = 'adm-mini-share-row'; + var pid = Number(p && p.plan_id != null ? p.plan_id : 0); + if (!isFinite(pid) || pid < 0) { + pid = 0; + } + var href = planIdToHref[String(pid)] ? String(planIdToHref[String(pid)]) : ''; + + var row = document.createElement(href ? 'a' : 'div'); + row.className = 'adm-mini-share-row' + (href ? ' adm-mini-share-row-link' : ''); + if (href) { + row.setAttribute('href', href); + } var name = document.createElement('div'); name.className = 'adm-mini-share-name'; @@ -371,7 +396,7 @@ // a 标签:避免默认下划线影响视觉(由 CSS 控制);并提升可访问性。 if (href) { row.setAttribute('role', 'link'); - row.setAttribute('aria-label', '进入站点订单集合:' + mname); + row.setAttribute('aria-label', '进入套餐订单集合:' + pname); } el.appendChild(row); diff --git a/resources/views/admin/dashboard.blade.php b/resources/views/admin/dashboard.blade.php index ae9e827..b1f3dc3 100644 --- a/resources/views/admin/dashboard.blade.php +++ b/resources/views/admin/dashboard.blade.php @@ -589,7 +589,7 @@ Top1占比:{{ $shareTop1Pct }}% - +
diff --git a/tests/Feature/AdminJsPlanOrderShareTop5ShouldReuseTablePlanLinksSelectorTest.php b/tests/Feature/AdminJsPlanOrderShareTop5ShouldReuseTablePlanLinksSelectorTest.php new file mode 100644 index 0000000..4253836 --- /dev/null +++ b/tests/Feature/AdminJsPlanOrderShareTop5ShouldReuseTablePlanLinksSelectorTest.php @@ -0,0 +1,20 @@ +assertStringContainsString('[data-role="plan-order-share-top5"] a.link[href*="plan_id="]', $js); + + // 且支持 a/div 二选一(可点击则 ) + $this->assertStringContainsString("document.createElement(href ? 'a' : 'div')", $js); + $this->assertStringContainsString('adm-mini-share-row-link', $js); + } +}
套餐