design: 订单详情收据式布局重构(三屏一致)— 单卡+粘土条+撕裂线+去冗余

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
This commit is contained in:
wangjia
2026-07-12 06:54:18 +08:00
parent c3d32a476e
commit bcd3a0bbb1
3 changed files with 63 additions and 44 deletions
+21 -16
View File
@@ -60,12 +60,21 @@
.setting-row .st-trail > svg{ width:18px; height:18px; } .setting-row .st-trail > svg{ width:18px; height:18px; }
.pill-accent .dot{ background:var(--fg-on-accent); } .pill-accent .dot{ background:var(--fg-on-accent); }
/* 订单详情 · 顶部概要 */ /* 订单详情 = 一张「收据」卡:顶部渐变条 + 摘要头(金额左/状态右) + 虚线撕裂线 + 明细 */
.od-summary{ display:flex; flex-direction:column; align-items:flex-start; gap:var(--space-3); .od-receipt{ position:relative; overflow:hidden; padding:0; }
padding:var(--space-5); } .od-receipt::before{ content:""; position:absolute; top:0; left:0; right:0; height:3px;
.od-plan{ font-family:var(--font-sans); font-size:var(--text-sm); font-weight:600; color:var(--fg2); } background:linear-gradient(90deg,var(--clay-500),var(--clay-800)); }
.od-summary{ display:flex; align-items:flex-start; justify-content:space-between; gap:var(--space-3);
padding:calc(var(--space-5) + 3px) var(--space-5) var(--space-4); }
.od-sum-main{ display:flex; flex-direction:column; gap:var(--space-2); min-width:0; }
.od-plan{ font-family:var(--font-sans); font-size:var(--text-caption); font-weight:700; color:var(--fg3);
letter-spacing:var(--tracking-caps); text-transform:uppercase; }
.od-amount{ font-family:var(--font-display); font-size:var(--text-h1); font-weight:700; color:var(--fg1); .od-amount{ font-family:var(--font-display); font-size:var(--text-h1); font-weight:700; color:var(--fg1);
letter-spacing:var(--tracking-tight); font-feature-settings:'tnum' 1; line-height:1; } letter-spacing:var(--tracking-tight); font-feature-settings:'tnum' 1; line-height:1; }
.od-perf-line{ border-top:1.5px dashed var(--border-strong); margin:0 var(--space-5); }
.od-kv{ padding:var(--space-3) var(--space-5) var(--space-5); }
.od-kv .kv-row{ border-top:1px solid var(--border); }
.od-kv .kv-row:first-child{ border-top:none; }
.sec-label{ font-size:var(--text-caption); color:var(--fg3); font-weight:700; .sec-label{ font-size:var(--text-caption); color:var(--fg3); font-weight:700;
letter-spacing:var(--tracking-caps); text-transform:uppercase; letter-spacing:var(--tracking-caps); text-transform:uppercase;
@@ -119,17 +128,16 @@
<!-- 页面 2:订单详情 --> <!-- 页面 2:订单详情 -->
<section class="screen" data-screen="detail"> <section class="screen" data-screen="detail">
<div class="scr stack"> <div class="scr stack">
<div class="card"> <div class="card od-receipt">
<div class="od-summary"> <div class="od-summary">
<div class="od-plan" id="odPlan"></div> <div class="od-sum-main">
<div class="od-amount" id="odAmount"></div> <div class="od-plan" id="odPlan"></div>
<div class="od-amount" id="odAmount"></div>
</div>
<div id="odStatus"></div> <div id="odStatus"></div>
</div> </div>
</div> <div class="od-perf-line"></div>
<div class="od-kv" id="odKv"></div>
<div>
<div class="sec-label" data-i18n="secDetail">Details</div>
<div class="card" id="odKv"></div>
</div> </div>
<div class="od-actions" id="odActions"></div> <div class="od-actions" id="odActions"></div>
@@ -263,13 +271,10 @@ function openDetail(id){
document.getElementById('odStatus').innerHTML = statusPill(o.status); document.getElementById('odStatus').innerHTML = statusPill(o.status);
const endKey = o.endKind === 'valid' ? 'kValid' : 'kDeadline'; const endKey = o.endKind === 'valid' ? 'kValid' : 'kDeadline';
// 摘要头已显套餐/金额/状态,明细只留细粒度字段,去重
const kv = '' const kv = ''
+ kvRow('kOrderNo', esc(o.id), true) + kvRow('kOrderNo', esc(o.id), true)
+ kvRow('kPlan', esc(planLabel(o.plan)), false)
+ kvRow('kAmount', esc(o.amount), false)
+ kvRow('kMethod', esc(methodLabel(o.method)), false) + kvRow('kMethod', esc(methodLabel(o.method)), false)
+ '<div class="kv-row"><span class="kv-label">' + esc(t('kStatus')) + '</span>'
+ '<span class="kv-val kv-status">' + statusPill(o.status) + '</span></div>'
+ kvRow('kCreated', esc(o.created), false) + kvRow('kCreated', esc(o.created), false)
+ kvRow(endKey, esc(o.ended), false) + kvRow(endKey, esc(o.ended), false)
+ kvRow('kTrade', esc(o.trade), o.trade !== '—'); + kvRow('kTrade', esc(o.trade), o.trade !== '—');
+21 -16
View File
@@ -238,14 +238,21 @@
.orders-view{ padding:var(--space-5) var(--space-6) var(--space-8); max-width:600px; margin:0 auto; } .orders-view{ padding:var(--space-5) var(--space-6) var(--space-8); max-width:600px; margin:0 auto; }
.od-screen{ display:none; } .od-screen{ display:none; }
.od-screen.is-active{ display:block; } .od-screen.is-active{ display:block; }
.orders-view .od-summary{ display:flex; flex-direction:column; align-items:flex-start; gap:var(--space-3); padding:var(--space-5); } /* 订单详情 = 一张「收据」卡:顶部渐变条 + 摘要头(金额左/状态右) + 虚线撕裂线 + 明细 */
.orders-view .od-plan{ font-family:var(--font-sans); font-size:var(--text-sm); font-weight:600; color:var(--fg2); } .od-receipt{ position:relative; overflow:hidden; margin-bottom:var(--space-5); padding:0; }
.od-receipt::before{ content:""; position:absolute; top:0; left:0; right:0; height:3px;
background:linear-gradient(90deg,var(--clay-500),var(--clay-800)); }
.orders-view .od-summary{ display:flex; align-items:flex-start; justify-content:space-between; gap:var(--space-4);
padding:calc(var(--space-5) + 3px) var(--space-5) var(--space-4); }
.orders-view .od-sum-main{ display:flex; flex-direction:column; gap:var(--space-2); min-width:0; }
.orders-view .od-plan{ font-family:var(--font-sans); font-size:var(--text-caption); font-weight:700; color:var(--fg3);
letter-spacing:var(--tracking-caps); text-transform:uppercase; }
.orders-view .od-amount{ font-family:var(--font-display); font-size:var(--text-h1); font-weight:700; color:var(--fg1); .orders-view .od-amount{ font-family:var(--font-display); font-size:var(--text-h1); font-weight:700; color:var(--fg1);
letter-spacing:var(--tracking-tight); font-feature-settings:'tnum' 1; line-height:1; } letter-spacing:var(--tracking-tight); font-feature-settings:'tnum' 1; line-height:1; }
.od-sumcard{ margin-bottom:var(--space-5); } .od-perf-line{ border-top:1.5px dashed var(--border-strong); margin:0 var(--space-5); }
.od-detail-sec{ margin-bottom:var(--space-5); } .orders-view .od-kv{ padding:var(--space-3) var(--space-5) var(--space-5); }
.od-sec{ font-size:var(--text-caption); color:var(--fg3); font-weight:700; letter-spacing:var(--tracking-caps); .orders-view .od-kv .kv-row{ border-top:1px solid var(--border); }
text-transform:uppercase; padding:0 var(--space-2) var(--space-2); } .orders-view .od-kv .kv-row:first-child{ border-top:none; }
.orders-view .od-actions{ display:flex; flex-direction:column; gap:var(--space-3); } .orders-view .od-actions{ display:flex; flex-direction:column; gap:var(--space-3); }
.orders-view .setting-row .st-trail .pill{ padding:3px var(--space-2); font-size:11px; } .orders-view .setting-row .st-trail .pill{ padding:3px var(--space-2); font-size:11px; }
.orders-view .setting-row .st-trail > svg{ width:18px; height:18px; } .orders-view .setting-row .st-trail > svg{ width:18px; height:18px; }
@@ -783,16 +790,16 @@
<!-- 详情 --> <!-- 详情 -->
<div class="od-screen" data-oscreen="detail"> <div class="od-screen" data-oscreen="detail">
<div class="card od-sumcard"> <div class="card od-receipt">
<div class="od-summary"> <div class="od-summary">
<div class="od-plan" id="odPlan"></div> <div class="od-sum-main">
<div class="od-amount" id="odAmount"></div> <div class="od-plan" id="odPlan"></div>
<div class="od-amount" id="odAmount"></div>
</div>
<div id="odStatus"></div> <div id="odStatus"></div>
</div> </div>
</div> <div class="od-perf-line"></div>
<div class="od-detail-sec"> <div class="od-kv" id="odKv"></div>
<div class="od-sec" data-i18n="ord.details">明细</div>
<div class="card card-flush" id="odKv"></div>
</div> </div>
<div class="od-actions" id="odActions"></div> <div class="od-actions" id="odActions"></div>
</div> </div>
@@ -1441,12 +1448,10 @@ function openOrderDetail(id){
document.getElementById('odAmount').textContent=o.amount; document.getElementById('odAmount').textContent=o.amount;
document.getElementById('odStatus').innerHTML=ordStatusPill(o.status); document.getElementById('odStatus').innerHTML=ordStatusPill(o.status);
var endKey = o.endKind==='valid' ? 'ord.kValid' : 'ord.kDeadline'; var endKey = o.endKind==='valid' ? 'ord.kValid' : 'ord.kDeadline';
// 摘要头已显套餐/金额/状态,明细只留细粒度字段,去重
var kv='' var kv=''
+ ordKvRow('ord.kOrderNo', ordEsc(o.id), true) + ordKvRow('ord.kOrderNo', ordEsc(o.id), true)
+ ordKvRow('ord.kPlan', ordEsc(ordPlanLabel(o.plan)), false)
+ ordKvRow('ord.kAmount', ordEsc(o.amount), false)
+ ordKvRow('ord.kMethod', ordEsc(ordMethodLabel(o.method)), false) + ordKvRow('ord.kMethod', ordEsc(ordMethodLabel(o.method)), false)
+ '<div class="kv-row"><span class="kv-label">'+ordEsc(I18N['ord.kStatus'][S.lang])+'</span><span class="kv-val kv-status">'+ordStatusPill(o.status)+'</span></div>'
+ ordKvRow('ord.kCreated', ordEsc(o.created), false) + ordKvRow('ord.kCreated', ordEsc(o.created), false)
+ ordKvRow(endKey, ordEsc(o.ended), false) + ordKvRow(endKey, ordEsc(o.ended), false)
+ ordKvRow('ord.kTrade', ordEsc(o.trade), o.trade!=='—'); + ordKvRow('ord.kTrade', ordEsc(o.trade), o.trade!=='—');
+21 -12
View File
@@ -276,10 +276,21 @@
#ordersOverlay .setting-row .st-trail .pill{ padding:3px var(--space-2); font-size:11px; } #ordersOverlay .setting-row .st-trail .pill{ padding:3px var(--space-2); font-size:11px; }
#ordersOverlay .setting-row .st-trail > svg{ width:18px; height:18px; } #ordersOverlay .setting-row .st-trail > svg{ width:18px; height:18px; }
#ordersOverlay .pill-accent .dot{ background:var(--fg-on-accent); } #ordersOverlay .pill-accent .dot{ background:var(--fg-on-accent); }
.ord-summary{ display:flex; flex-direction:column; align-items:flex-start; gap:var(--space-3); padding:var(--space-5); } /* 订单详情 = 一张「收据」卡:顶部渐变条 + 摘要头(金额左/状态右) + 虚线撕裂线 + 明细 */
.ord-plan{ font-family:var(--font-sans); font-size:var(--text-sm); font-weight:600; color:var(--fg2); } .ord-receipt{ position:relative; overflow:hidden; padding:0; }
.ord-receipt::before{ content:""; position:absolute; top:0; left:0; right:0; height:3px;
background:linear-gradient(90deg,var(--clay-500),var(--clay-800)); }
.ord-summary{ display:flex; align-items:flex-start; justify-content:space-between; gap:var(--space-3);
padding:calc(var(--space-5) + 3px) var(--space-5) var(--space-4); }
.ord-sum-main{ display:flex; flex-direction:column; gap:var(--space-2); min-width:0; }
.ord-plan{ font-family:var(--font-sans); font-size:var(--text-caption); font-weight:700; color:var(--fg3);
letter-spacing:var(--tracking-caps); text-transform:uppercase; }
.ord-amount{ font-family:var(--font-display); font-size:var(--text-h1); font-weight:700; color:var(--fg1); .ord-amount{ font-family:var(--font-display); font-size:var(--text-h1); font-weight:700; color:var(--fg1);
letter-spacing:var(--tracking-tight); font-feature-settings:'tnum' 1; line-height:1; } letter-spacing:var(--tracking-tight); font-feature-settings:'tnum' 1; line-height:1; }
.ord-perf-line{ border-top:1.5px dashed var(--border-strong); margin:0 var(--space-5); }
.ord-kv{ padding:var(--space-3) var(--space-5) var(--space-5); }
.ord-kv .kv-row{ border-top:1px solid var(--border); }
.ord-kv .kv-row:first-child{ border-top:none; }
.ord-sec{ font-size:var(--text-caption); color:var(--fg3); font-weight:700; .ord-sec{ font-size:var(--text-caption); color:var(--fg3); font-weight:700;
letter-spacing:var(--tracking-caps); text-transform:uppercase; padding:0 var(--space-2) var(--space-2); } letter-spacing:var(--tracking-caps); text-transform:uppercase; padding:0 var(--space-2) var(--space-2); }
.ord-kv-status{ padding-top:2px; } .ord-kv-status{ padding-top:2px; }
@@ -754,16 +765,16 @@
<!-- 订单详情 --> <!-- 订单详情 -->
<section class="ord-screen" data-screen="detail"> <section class="ord-screen" data-screen="detail">
<div class="ord-scr ord-stack"> <div class="ord-scr ord-stack">
<div class="card"> <div class="card ord-receipt">
<div class="ord-summary"> <div class="ord-summary">
<div class="ord-plan" id="ordDetPlan"></div> <div class="ord-sum-main">
<div class="ord-amount" id="ordDetAmount"></div> <div class="ord-plan" id="ordDetPlan"></div>
<div class="ord-amount" id="ordDetAmount"></div>
</div>
<div id="ordDetStatus"></div> <div id="ordDetStatus"></div>
</div> </div>
</div> <div class="ord-perf-line"></div>
<div> <div class="ord-kv" id="ordDetKv"></div>
<div class="ord-sec" data-i18n="ordSecDetail">Details</div>
<div class="card" id="ordDetKv"></div>
</div> </div>
<div class="ord-actions" id="ordDetActions"></div> <div class="ord-actions" id="ordDetActions"></div>
</div> </div>
@@ -1551,12 +1562,10 @@ function ordOpenDetail(id){
$('#ordDetAmount').textContent=o.amount; $('#ordDetAmount').textContent=o.amount;
$('#ordDetStatus').innerHTML=ordStatusPill(o.status); $('#ordDetStatus').innerHTML=ordStatusPill(o.status);
const endKey=o.endKind==='valid'?'kValid':'kDeadline'; const endKey=o.endKind==='valid'?'kValid':'kDeadline';
// 摘要头已显套餐/金额/状态,明细只留细粒度字段,去重
const kv = '' const kv = ''
+ ordKvRow('kOrderNo', ordEsc(o.id), true) + ordKvRow('kOrderNo', ordEsc(o.id), true)
+ ordKvRow('kPlan', ordEsc(ordPlanLabel(o.plan)), false)
+ ordKvRow('kAmount', ordEsc(o.amount), false)
+ ordKvRow('kMethod', ordEsc(ordMethodLabel(o.method)), false) + ordKvRow('kMethod', ordEsc(ordMethodLabel(o.method)), false)
+ '<div class="kv-row"><span class="kv-label">'+ordEsc(D().kStatus)+'</span><span class="kv-val ord-kv-status">'+ordStatusPill(o.status)+'</span></div>'
+ ordKvRow('kCreated', ordEsc(o.created), false) + ordKvRow('kCreated', ordEsc(o.created), false)
+ ordKvRow(endKey, ordEsc(o.ended), false) + ordKvRow(endKey, ordEsc(o.ended), false)
+ ordKvRow('kTrade', ordEsc(o.trade), o.trade!=='—'); + ordKvRow('kTrade', ordEsc(o.trade), o.trade!=='—');