feat: refine installation fee card units and action

This commit is contained in:
qiuxiang 2026-10-26 16:40:00 +08:00
parent dfc3dcd0d0
commit 441e321fdc
2 changed files with 95 additions and 40 deletions

View File

@ -18,21 +18,8 @@
background: #ffffff;
color: #171717;
box-shadow: 0 1px 2px rgba(16, 24, 40, 0.04);
font: inherit;
font-family: "JetBrains Mono", "Microsoft YaHei", "PingFang SC", monospace;
text-align: left;
cursor: pointer;
}
.installation-fee-card:hover,
.installation-fee-card:focus-visible {
border-color: #b9954f;
border-left-color: #006395;
background: #fffdf8;
outline: none;
}
.installation-fee-card:focus-visible {
box-shadow: 0 0 0 3px rgba(133, 102, 50, 0.2);
}
.installation-fee-card__top {
@ -75,7 +62,7 @@
font-size: 2.5rem;
font-weight: 700;
line-height: 1;
letter-spacing: -0.035em;
letter-spacing: 0;
font-variant-numeric: tabular-nums;
}
@ -110,6 +97,7 @@
.installation-fee-card__split {
display: flex;
align-items: center;
justify-content: space-between;
gap: 0.45rem;
flex-wrap: wrap;
margin: auto -1rem 0 -1.15rem;
@ -121,6 +109,14 @@
font-variant-numeric: tabular-nums;
}
.installation-fee-card__split-summary {
display: flex;
min-width: 0;
align-items: center;
gap: 0.45rem;
flex-wrap: wrap;
}
.installation-fee-card__split strong {
font-weight: 600;
}
@ -136,6 +132,35 @@
font-weight: 400;
}
.installation-fee-card__detail-button {
display: inline-flex;
min-height: 1.55rem;
align-items: center;
justify-content: center;
gap: 0.25rem;
margin-left: auto;
padding: 0 0.45rem;
border: 0;
border-radius: 0.3rem;
background: transparent;
color: #006395;
cursor: pointer;
font: inherit;
font-size: 0.75rem;
font-weight: 600;
white-space: nowrap;
}
.installation-fee-card__detail-button:hover {
background: #eef6fa;
}
.installation-fee-card__detail-button:focus-visible {
background: #eef6fa;
box-shadow: 0 0 0 3px rgba(0, 99, 149, 0.16);
outline: none;
}
@media (max-width: 720px) {
.installation-fee-card {
height: auto;
@ -162,6 +187,10 @@
padding-right: 0.85rem;
padding-left: 0.95rem;
}
.installation-fee-card__detail-button {
width: 100%;
justify-content: flex-end;
}
}
.installation-fee-dialog {
@ -362,13 +391,9 @@
</style>
<section class="installation-fee-board" aria-label="安装费金额汇总">
<button
type="button"
<div
class="installation-fee-card"
data-installation-fee-open
data-url="{{ route('business.installation-details.summary') }}"
aria-label="查看安装费金额明细"
title="查看安装费金额明细"
data-installation-fee-card
>
<span class="installation-fee-card__top">
<strong class="installation-fee-card__title">安装费金额</strong>
@ -376,16 +401,25 @@
</span>
<span class="installation-fee-card__main">
<strong class="installation-fee-card__value" data-installation-fee-total>0.00</strong>
<span class="installation-fee-card__unit">元</span>
<span class="installation-fee-card__unit">万元</span>
<span class="installation-fee-card__trend" data-installation-fee-trend>—</span>
<span class="installation-fee-card__trend-note">较上月</span>
</span>
<span class="installation-fee-card__split">
<span>包安装 <strong data-installation-fee-package>0.00</strong><span class="installation-fee-card__split-percent" data-installation-fee-package-percent>(0%)</span></span>
<span class="installation-fee-card__split-sep" aria-hidden="true">|</span>
<span>不包安装 <strong data-installation-fee-non-package>0.00</strong><span class="installation-fee-card__split-percent" data-installation-fee-non-package-percent>(0%)</span></span>
<span class="installation-fee-card__split-summary">
<span>包安装 <strong data-installation-fee-package>0.00</strong><span class="installation-fee-card__split-percent" data-installation-fee-package-percent>(0.0%)</span></span>
<span class="installation-fee-card__split-sep" aria-hidden="true">|</span>
<span>不包安装 <strong data-installation-fee-non-package>0.00</strong><span class="installation-fee-card__split-percent" data-installation-fee-non-package-percent>(0.0%)</span></span>
</span>
<button
type="button"
class="installation-fee-card__detail-button"
data-installation-fee-open
data-url="{{ route('business.installation-details.summary') }}"
aria-label="查看安装费金额明细"
>查看明细 →</button>
</span>
</button>
</div>
</section>
<dialog class="installation-fee-dialog" id="installation-fee-dialog" aria-labelledby="installation-fee-dialog-title">
@ -462,9 +496,10 @@
<script>
(function () {
var form = document.getElementById('installationFilterForm');
var card = document.querySelector('[data-installation-fee-open]');
var card = document.querySelector('[data-installation-fee-card]');
var openButton = document.querySelector('[data-installation-fee-open]');
var dialog = document.getElementById('installation-fee-dialog');
if (!form || !card || !dialog) { return; }
if (!form || !card || !openButton || !dialog) { return; }
var fromInput = form.elements.namedItem('date_from');
var toInput = form.elements.namedItem('date_to');
@ -504,6 +539,10 @@
});
}
function wanAmount(value) {
return amount(Number(value || 0) / 10000);
}
function captionRange(value) {
var matchFrom = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value.from);
var matchTo = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value.to);
@ -545,14 +584,23 @@
nonPackageTotal += Number(row.amount || 0);
}
});
var packageRate = total > 0 ? Math.round((packageTotal / total) * 100) : 0;
var nonPackageRate = total > 0 ? 100 - packageRate : 0;
var packageRate = total > 0 ? Math.round((packageTotal / total) * 1000) / 10 : 0;
var nonPackageRate = total > 0 ? Math.round((100 - packageRate) * 10) / 10 : 0;
var percent = function (rate) {
return Number(rate || 0).toLocaleString('zh-CN', {
minimumFractionDigits: 1,
maximumFractionDigits: 1
});
};
cardTotal.textContent = amount(total);
packageAmount.textContent = amount(packageTotal);
nonPackageAmount.textContent = amount(nonPackageTotal);
packagePercent.textContent = '(' + packageRate + '%)';
nonPackagePercent.textContent = '(' + nonPackageRate + '%)';
cardTotal.textContent = wanAmount(total);
cardTotal.title = '¥' + amount(total);
packageAmount.textContent = wanAmount(packageTotal);
packageAmount.title = '¥' + amount(packageTotal);
nonPackageAmount.textContent = wanAmount(nonPackageTotal);
nonPackageAmount.title = '¥' + amount(nonPackageTotal);
packagePercent.textContent = '(' + percent(packageRate) + '%)';
nonPackagePercent.textContent = '(' + percent(nonPackageRate) + '%)';
setTrend(data.change_rate);
status.classList.remove('is-error');
status.textContent = '按客服审核时间 · ' + captionRange(value) + ' · ' + rows.length + ' 单';
@ -562,8 +610,11 @@
cardTotal.textContent = '0.00';
packageAmount.textContent = '0.00';
nonPackageAmount.textContent = '0.00';
packagePercent.textContent = '(0%)';
nonPackagePercent.textContent = '(0%)';
cardTotal.removeAttribute('title');
packageAmount.removeAttribute('title');
nonPackageAmount.removeAttribute('title');
packagePercent.textContent = '(0.0%)';
nonPackagePercent.textContent = '(0.0%)';
setTrend(null);
status.textContent = message;
status.classList.toggle('is-error', message.indexOf('失败') >= 0 || message.indexOf('不能') >= 0);
@ -717,7 +768,7 @@
status.classList.remove('is-error');
status.textContent = '按客服审核时间 · 正在汇总…';
cardTotal.textContent = '…';
var url = new URL(card.dataset.url, window.location.origin);
var url = new URL(openButton.dataset.url, window.location.origin);
url.searchParams.set('customer_review_from', value.from);
url.searchParams.set('customer_review_to', value.to);
@ -758,7 +809,7 @@
timer = window.setTimeout(function () { refresh(true); }, 250);
}
card.addEventListener('click', function () {
openButton.addEventListener('click', function () {
openDialog();
refresh(false);
});

View File

@ -276,9 +276,11 @@ class ManagementCrudTest extends FeatureTestCase
->assertSee("window.CaiWuDatePicker.setup(form)", false)
->assertSee("input.addEventListener('input', syncClear)", false)
->assertSee('结束日期不能早于开始日期。')
->assertSee('data-installation-fee-card', false)
->assertSee('data-installation-fee-open', false)
->assertSee('id="installation-fee-dialog"', false)
->assertSeeText('安装费金额')
->assertSeeText('查看明细 →')
->assertSeeText('较上月')
->assertSeeText('包安装')
->assertSeeText('不包安装')
@ -288,9 +290,11 @@ class ManagementCrudTest extends FeatureTestCase
->assertSee('border-left: 3px solid #006395', false)
->assertSee('height: 8rem', false)
->assertSee('font-size: 2.5rem', false)
->assertSee('<span class="installation-fee-card__unit">元</span>', false)
->assertSee('font-family: "JetBrains Mono", "Microsoft YaHei", "PingFang SC", monospace', false)
->assertSee('<span class="installation-fee-card__unit">万元</span>', false)
->assertSee('function captionRange(value)', false)
->assertSee('function setCardValue(total, rows, value, data)', false)
->assertSee('function wanAmount(value)', false)
->assertSeeText('平台')
->assertSeeText('店铺名称')
->assertSeeText('安装公司')