feat: 全站视觉焕新与悬浮玻璃 TabBar 迁移
@@ -834,11 +834,11 @@
|
||||
.mini-tabbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 56px;
|
||||
height: 58px;
|
||||
padding: 4px 4px calc(4px + env(safe-area-inset-bottom, 0px));
|
||||
background: rgba(255, 255, 255, 0.55);
|
||||
border: 1px solid var(--glass-line);
|
||||
border-radius: var(--radius-lg);
|
||||
border-radius: 32px;
|
||||
box-shadow: 0 -2px 12px rgba(46, 38, 34, 0.1);
|
||||
backdrop-filter: blur(32px) saturate(1.2);
|
||||
-webkit-backdrop-filter: blur(32px) saturate(1.2);
|
||||
@@ -970,7 +970,7 @@
|
||||
}
|
||||
|
||||
.phone-screen .mini-tabbar {
|
||||
margin: 0 12px 12px;
|
||||
margin: 0 18px 18px;
|
||||
}
|
||||
|
||||
.phone-content {
|
||||
@@ -1756,7 +1756,7 @@
|
||||
</div>
|
||||
<div class="empty-title">暂无设计任务</div>
|
||||
<div class="empty-desc">创建第一个任务,把想法变成可预览的方案。</div>
|
||||
<button class="btn btn-md btn-primary" type="button" id="toast-trigger">创建任务</button>
|
||||
<button class="btn btn-lg btn-primary" type="button" id="toast-trigger" style="min-width:140px">创建任务</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2011,9 +2011,7 @@
|
||||
<div class="mock-topbar">
|
||||
<div class="mock-status"><span>11:18</span><span class="mini-capsule"><i></i><i></i><i></i></span></div>
|
||||
<div class="mock-header">
|
||||
<span class="icon-button" style="width:32px;height:32px;min-width:32px;border-radius:50%" type="button" aria-label="返回">
|
||||
<span class="icon" style="width:16px;height:16px"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M19 12H5"/><path d="m12 5-7 7 7 7"/></svg></span>
|
||||
</span>
|
||||
<span style="width:32px"></span>
|
||||
<span class="mock-title" style="flex:1;text-align:center">我的设计清单</span>
|
||||
<span style="font-size:13px;color:var(--accent-secondary);width:32px;text-align:center">管理</span>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
.theme-light{background-color:var(--bg-page,#fff);-webkit-box-sizing:border-box;box-sizing:border-box;min-height:100vh}.theme-dark{background-color:var(--bg-page,#191919);-webkit-box-sizing:border-box;box-sizing:border-box;min-height:100vh}.theme-light{--bg-page:#faf7f2;--bg-card:#fff;--bg-muted:#f3eee7;--bg-input:#f5f1eb;--text-primary:#2e2622;--text-secondary:#8a7e76;--text-muted:#b3a89e;--accent-primary:#d96c6a;--accent-primary-strong:#c75b59;--accent-primary-soft:#f6e0dc;--accent-secondary:#6c7bdb;--accent-secondary-soft:rgba(108,123,219,.12);--success:#4fa477;--success-soft:rgba(79,164,119,.14);--warning:#d99a4e;--warning-soft:rgba(217,154,78,.14);--danger:#d85d5d;--danger-soft:rgba(216,93,93,.14);--border:#ede5dc;--border-strong:#e0d5c8;--glass:hsla(0,0%,100%,.72);--glass-line:hsla(0,0%,100%,.55);--shadow-card:0 8rpx 24rpx rgba(46,38,34,.08);--shadow-elevated:0 12rpx 40rpx rgba(46,38,34,.12)}.theme-dark{--bg-page:#191919;--bg-card:#23201d;--bg-muted:#2b2622;--bg-input:#2b2622;--text-primary:#f5efe8;--text-secondary:#b3a79c;--text-muted:#82766c;--accent-primary:#f09198;--accent-primary-strong:#ffa7ad;--accent-primary-soft:rgba(240,145,152,.14);--accent-secondary:#8e97e8;--accent-secondary-soft:rgba(142,151,232,.14);--success:#67c58e;--success-soft:rgba(103,197,142,.16);--warning:#e0ad68;--warning-soft:hsla(35,66%,64%,.16);--danger:#ef7a7a;--danger-soft:hsla(0,79%,71%,.16);--border:#37312c;--border-strong:#463e37;--glass:rgba(25,25,25,.72);--glass-line:hsla(0,0%,100%,.14);--shadow-card:0 8rpx 24rpx rgba(0,0,0,.32);--shadow-elevated:0 12rpx 40rpx rgba(0,0,0,.48)}page{font-family:-apple-system,BlinkMacSystemFont,PingFang SC,Hiragino Sans GB,Noto Sans SC,Microsoft YaHei,Segoe UI,sans-serif}.surface-card{background:var(--bg-card);border:1rpx solid var(--border);border-radius:24rpx;-webkit-box-shadow:var(--shadow-card);box-shadow:var(--shadow-card)}.container{padding:48rpx}.flex{display:-webkit-flex;display:-ms-flexbox;display:flex}.flex-center{-ms-flex-align:center;-ms-flex-pack:center;-webkit-align-items:center;align-items:center;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:center;justify-content:center}.flex-between{-ms-flex-align:center;-ms-flex-pack:justify;-webkit-align-items:center;align-items:center;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:space-between;justify-content:space-between}.flex-column{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.text-center{text-align:center}.mt-10{margin-top:20rpx}.mt-20{margin-top:40rpx}.mb-10{margin-bottom:20rpx}.mb-20{margin-bottom:40rpx}.btn-primary{background:var(--accent-primary);border-radius:999rpx;color:#fff}.btn-secondary{background:var(--bg-card);border:1rpx solid var(--border-strong);border-radius:999rpx;color:var(--text-primary)}.btn-ghost{background:transparent;color:var(--accent-primary)}.btn-danger{background:var(--danger);border-radius:999rpx;color:#fff}.page-title{color:var(--text-primary);display:block;font-size:80rpx;font-weight:800}.section-title{color:var(--text-primary);display:block;font-size:72rpx;font-weight:700;margin-bottom:48rpx}.badge{border-radius:100rpx;display:inline-block;font-size:44rpx;font-weight:500;padding:16rpx 40rpx}.badge-pink{background:var(--accent-primary-soft);color:var(--accent-primary)}.badge-blue{background:var(--accent-secondary-soft);color:var(--accent-secondary)}.badge-green{background:var(--success-soft);color:var(--success)}.badge-warning{background:var(--warning-soft);color:var(--warning)}.badge-danger{background:var(--danger-soft);color:var(--danger)}.badge-gray{background:var(--bg-muted);color:var(--text-secondary)}.safe-bottom{height:constant(safe-area-inset-bottom);height:env(safe-area-inset-bottom)}.safe-bottom-placeholder{height:400rpx}.page-header{padding-top:calc(env(safe-area-inset-top, 20rpx) + 96rpx)}.back-btn,.edit-back{display:inline-block}.modal-overlay{-ms-flex-align:end;-ms-flex-pack:center;-webkit-align-items:flex-end;align-items:flex-end;background:rgba(0,0,0,.5);bottom:0;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:center;justify-content:center;left:0;position:fixed;right:0;top:0;z-index:600}.addr-picker-sheet{background:var(--bg-card);border-radius:48rpx 48rpx 0 0;border-top:1rpx solid var(--border);-webkit-box-sizing:border-box;box-sizing:border-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;max-height:70vh;padding:48rpx 48rpx calc(48rpx + env(safe-area-inset-bottom));width:100%}.system-theme-detector{height:1rpx;left:-9999rpx;opacity:0;pointer-events:none;position:fixed;top:0;width:1rpx}@media (prefers-color-scheme:dark){.system-theme-detector{opacity:1}}
|
||||
@@ -1 +1 @@
|
||||
{"darkmode":true,"themeLocation":"theme.json","pages":["pages/index/index","pages/shop/index","pages/shop/detail/index","pages/product/index","pages/diy/index","pages/diy/stickerEdit/index","pages/checkout/index","pages/designList/index","pages/orders/index","pages/profile/index","pages/service/index","pages/wordcloud/index","pages/orderDetail/index","pages/address/index","pages/settings/index","pages/agreement/index","pages/userDatabase/index"],"window":{"backgroundTextStyle":"dark","navigationStyle":"custom","navigationBarBackgroundColor":"#ffffff","backgroundColor":"#ffffff","backgroundColorTop":"#ffffff","backgroundColorBottom":"#ffffff","navigationBarTextStyle":"black"},"tabBar":{"custom":true,"list":[{"pagePath":"pages/index/index","text":"首页"},{"pagePath":"pages/shop/index","text":"商品"},{"pagePath":"pages/designList/index","text":"设计清单"},{"pagePath":"pages/orders/index","text":"订单"},{"pagePath":"pages/profile/index","text":"我的"}]}}
|
||||
{"darkmode":true,"themeLocation":"theme.json","pages":["pages/index/index","pages/shop/index","pages/shop/detail/index","pages/product/index","pages/diy/index","pages/diy/stickerEdit/index","pages/checkout/index","pages/designList/index","pages/orders/index","pages/profile/index","pages/service/index","pages/wordcloud/index","pages/orderDetail/index","pages/address/index","pages/settings/index","pages/agreement/index","pages/userDatabase/index"],"window":{"backgroundTextStyle":"dark","navigationStyle":"custom","navigationBarBackgroundColor":"#faf7f2","backgroundColor":"#faf7f2","backgroundColorTop":"#faf7f2","backgroundColorBottom":"#faf7f2","navigationBarTextStyle":"black"},"tabBar":{"custom":true,"list":[{"pagePath":"pages/index/index","text":"首页"},{"pagePath":"pages/shop/index","text":"商品"},{"pagePath":"pages/designList/index","text":"设计清单"},{"pagePath":"pages/orders/index","text":"订单"},{"pagePath":"pages/profile/index","text":"我的"}]}}
|
||||
@@ -0,0 +1 @@
|
||||
.bottom-action-bar{-ms-flex-align:center;-webkit-align-items:center;align-items:center;backdrop-filter:blur(32rpx) saturate(1.2);-webkit-backdrop-filter:blur(32rpx) saturate(1.2);background:hsla(0,0%,100%,.55);border:1rpx solid hsla(0,0%,100%,.55);border-radius:64rpx;bottom:36rpx;-webkit-box-shadow:0 12rpx 40rpx rgba(46,34,34,.18),0 4rpx 12rpx rgba(46,34,34,.08);box-shadow:0 12rpx 40rpx rgba(46,34,34,.18),0 4rpx 12rpx rgba(46,34,34,.08);-webkit-box-sizing:border-box;box-sizing:border-box;display:-webkit-flex;display:-ms-flexbox;display:flex;gap:24rpx;left:36rpx;padding:24rpx 24rpx calc(24rpx + env(safe-area-inset-bottom));position:fixed;right:36rpx;z-index:500}.theme-dark .bottom-action-bar{background:rgba(25,25,25,.55);border-color:hsla(0,0%,100%,.14);-webkit-box-shadow:0 12rpx 40rpx rgba(0,0,0,.5),0 4rpx 12rpx rgba(0,0,0,.3);box-shadow:0 12rpx 40rpx rgba(0,0,0,.5),0 4rpx 12rpx rgba(0,0,0,.3)}
|
||||
@@ -1 +1 @@
|
||||
"use strict";(wx["webpackJsonp"]=wx["webpackJsonp"]||[]).push([[777],{653:function(n,e,t){var a=t(7842),i=t(5544),c=t(118),o=t(758),r=t.n(o),u=t(6540),s=t(8594),l=t(9703),v=t(6606),g=t(8199),f=t(4848),p=[{pagePath:"/pages/index/index",label:"\u9996\u9875",icon:(0,g.uq)("/icon/\u9996\u9875.svg"),iconActive:(0,g.uq)("/icon/\u9996\u9875-fill.svg")},{pagePath:"/pages/shop/index",label:"\u5546\u54c1",icon:(0,g.uq)("/icon/\u5546\u54c1.svg"),iconActive:(0,g.uq)("/icon/\u5546\u54c1-fill.svg")},{pagePath:"/pages/designList/index",label:"\u8bbe\u8ba1\u6e05\u5355",icon:(0,g.uq)("/icon/\u8c03\u8272\u76d8.svg"),iconActive:(0,g.uq)("/icon/\u8c03\u8272\u76d8-fill.svg")},{pagePath:"/pages/orders/index",label:"\u8ba2\u5355",icon:(0,g.uq)("/icon/\u5305\u88f9.svg"),iconActive:(0,g.uq)("/icon/\u5305\u88f9-fill.svg")},{pagePath:"/pages/profile/index",label:"\u6211\u7684",icon:(0,g.uq)("/icon/\u4e2a\u4eba.svg"),iconActive:(0,g.uq)("/icon/\u4e2a\u4eba-fill.svg")}];function d(n){var e=p.findIndex(function(e){return n.endsWith(e.pagePath)});return p[e>=0?e:0].pagePath}function h(){var n,e=(null===(n=r().getCurrentInstance().router)||void 0===n?void 0:n.path)||"pages/index/index";return d(e)}function b(){var n=(0,u.useState)((0,s.eW)((0,s.O4)())),e=(0,i.A)(n,2),t=e[0],a=e[1],o=(0,u.useState)(h),g=(0,i.A)(o,2),b=g[0],x=g[1];(0,u.useEffect)(function(){var n=function(n){return a(n)};return r().eventCenter.on(l.Wo,n),function(){r().eventCenter.off(l.Wo,n)}},[]),(0,u.useEffect)(function(){var n=function(n){var e;x(d(n||(null===(e=r().getCurrentInstance().router)||void 0===e?void 0:e.path)||"pages/index/index"))};return r().eventCenter.on("tabBarChange",n),function(){r().eventCenter.off("tabBarChange",n)}},[]),(0,u.useEffect)(function(){(0,v.G)(t)},[t]);var m=function(n){var e;x(d(n)),r().switchTab({url:n}),null===(e=r().eventCenter)||void 0===e||e.trigger("tabBarChange",n)};return(0,f.jsx)(c.Ss,{className:"custom-tab-bar theme-".concat(t),children:p.map(function(n){var e=n.pagePath===b;return(0,f.jsxs)(c.Ss,{className:"tab-item ".concat(e?"active":""),onTap:function(){return m(n.pagePath)},children:[(0,f.jsx)(c._V,{className:"tab-icon-img ".concat(e?"active":""),src:e?n.iconActive:n.icon,mode:"aspectFit"}),(0,f.jsx)(c.EY,{className:"tab-label",children:n.label})]},n.pagePath)})})}Component((0,a.createComponentConfig)(b,"custom-tab-bar/index"))}},function(n){var e=function(e){return n(n.s=e)};n.O(0,[907,96,76],function(){return e(653)});n.O()}]);
|
||||
"use strict";(wx["webpackJsonp"]=wx["webpackJsonp"]||[]).push([[777],{653:function(e,n,t){var a=t(7842),i=t(5544),c=t(118),o=t(758),r=t.n(o),s=t(6540),u=t(8594),f=t(9703),g=t(6606),h=t(8199),l=t(4848),v=[{pagePath:"/pages/index/index",label:"\u9996\u9875",icon:(0,h.uq)("/icon/\u9996\u9875.svg"),iconActive:(0,h.uq)("/icon/\u9996\u9875-fill.svg")},{pagePath:"/pages/shop/index",label:"\u5546\u54c1",icon:(0,h.uq)("/icon/\u5546\u54c1.svg"),iconActive:(0,h.uq)("/icon/\u5546\u54c1-fill.svg")},{pagePath:"/pages/designList/index",label:"\u8bbe\u8ba1\u6e05\u5355",icon:(0,h.uq)("/icon/\u8c03\u8272\u76d8.svg"),iconActive:(0,h.uq)("/icon/\u8c03\u8272\u76d8-fill.svg")},{pagePath:"/pages/orders/index",label:"\u8ba2\u5355",icon:(0,h.uq)("/icon/\u5305\u88f9.svg"),iconActive:(0,h.uq)("/icon/\u5305\u88f9-fill.svg")},{pagePath:"/pages/profile/index",label:"\u6211\u7684",icon:(0,h.uq)("/icon/\u4e2a\u4eba.svg"),iconActive:(0,h.uq)("/icon/\u4e2a\u4eba-fill.svg")}];function p(e){var n=v.findIndex(function(n){return e.endsWith(n.pagePath)});return v[n>=0?n:0].pagePath}function b(){var e=r().getCurrentInstance().router,n=e&&e.path?e.path:"pages/index/index";return p(n)}function m(){var e=(0,s.useState)((0,u.eW)((0,u.O4)())),n=(0,i.A)(e,2),t=n[0],a=n[1],o=(0,s.useState)(b),h=(0,i.A)(o,2),m=h[0],d=h[1];(0,s.useEffect)(function(){var e=function(e){return a(e)};return r().eventCenter.on(f.Wo,e),function(){r().eventCenter.off(f.Wo,e)}},[]),(0,s.useEffect)(function(){var e=function(e){!e||"dark"!==e.theme&&"light"!==e.theme||((0,u.Rq)(e.theme),"auto"===(0,u.O4)()&&a(e.theme))},n=r();return n.onThemeChange&&n.onThemeChange(e),function(){n.offThemeChange&&n.offThemeChange(e)}},[]),(0,s.useEffect)(function(){var e=function(e){var n=r().getCurrentInstance().router,t=n&&n.path?n.path:"pages/index/index";d(p(e||t))};return r().eventCenter.on("tabBarChange",e),function(){r().eventCenter.off("tabBarChange",e)}},[]),(0,s.useEffect)(function(){(0,g.G)(t)},[t]);var x=function(e){d(p(e)),r().switchTab({url:e}),r().eventCenter.trigger("tabBarChange",e)};return(0,l.jsxs)(c.Ss,{className:"tab-bar-root theme-".concat(t),children:[(0,l.jsx)(c.Ss,{className:"tab-bar-gradient"}),(0,l.jsx)(c.Ss,{className:"custom-tab-bar theme-".concat(t),children:v.map(function(e){var n=e.pagePath===m;return(0,l.jsxs)(c.Ss,{className:"tab-item ".concat(n?"active":""),onTap:function(){return x(e.pagePath)},children:[n&&(0,l.jsx)(c.Ss,{className:"tab-indicator"}),(0,l.jsx)(c._V,{className:"tab-icon-img ".concat(n?"active":""),src:n?e.iconActive:e.icon,mode:"aspectFit"}),(0,l.jsx)(c.EY,{className:"tab-label",children:e.label})]},e.pagePath)})})]})}Component((0,a.createComponentConfig)(m,"custom-tab-bar/index"))}},function(e){var n=function(n){return e(e.s=n)};e.O(0,[907,96,76],function(){return n(653)});e.O()}]);
|
||||
@@ -1 +1 @@
|
||||
.custom-tab-bar{-ms-flex-pack:distribute;-ms-flex-align:center;-webkit-align-items:center;align-items:center;backdrop-filter:blur(20rpx);-webkit-backdrop-filter:blur(20rpx);background:hsla(0,0%,100%,.78);bottom:0;-webkit-box-shadow:0 -8rpx 20rpx rgba(0,0,0,.08);box-shadow:0 -8rpx 20rpx rgba(0,0,0,.08);-webkit-box-sizing:border-box;box-sizing:border-box;display:-webkit-flex;display:-ms-flexbox;display:flex;height:calc(96rpx + constant(safe-area-inset-bottom));height:calc(96rpx + env(safe-area-inset-bottom));-webkit-justify-content:space-around;justify-content:space-around;left:0;padding-bottom:env(safe-area-inset-bottom);position:fixed;right:0;z-index:1000}.custom-tab-bar.theme-dark{backdrop-filter:blur(20rpx);-webkit-backdrop-filter:blur(20rpx);background:rgba(25,25,25,.78);-webkit-box-shadow:0 -8rpx 20rpx rgba(0,0,0,.45);box-shadow:0 -8rpx 20rpx rgba(0,0,0,.45)}.tab-item{-ms-flex-align:center;-ms-flex-pack:center;-webkit-align-items:center;align-items:center;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:1;-ms-flex:1;flex:1;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-justify-content:center;justify-content:center;max-width:160rpx;padding:0 12rpx;position:relative}.tab-icon-img{height:40rpx;margin-bottom:2rpx;opacity:.8;-webkit-transition:-webkit-transform .2s;transition:-webkit-transform .2s;transition:transform .2s;transition:transform .2s,-webkit-transform .2s;width:40rpx}.tab-item.active .tab-icon-img{opacity:1;-webkit-transform:scale(1.08);-ms-transform:scale(1.08);transform:scale(1.08)}.tab-label{color:#b08d8d;font-size:20rpx;font-weight:700;line-height:22rpx;-webkit-transition:color .2s;transition:color .2s}.custom-tab-bar.theme-dark .tab-label{color:#999}.tab-item.active .tab-label{color:#ff9a9e}.custom-tab-bar.theme-dark .tab-item.active .tab-label{color:#ff7eb3}
|
||||
.tab-bar-root{bottom:0;height:160rpx;left:0;pointer-events:none;position:fixed;right:0;z-index:999}.tab-bar-gradient{bottom:0;height:100%;left:0;position:absolute;right:0}.tab-bar-root.theme-light .tab-bar-gradient{background:-webkit-gradient(linear,left bottom,left top,from(hsla(38,44%,96%,.5)),color-stop(50%,hsla(38,44%,96%,.1)),color-stop(86%,hsla(38,44%,96%,0)));background:-webkit-linear-gradient(bottom,hsla(38,44%,96%,.5),hsla(38,44%,96%,.1) 50%,hsla(38,44%,96%,0) 86%);background:linear-gradient(0deg,hsla(38,44%,96%,.5) 0,hsla(38,44%,96%,.1) 50%,hsla(38,44%,96%,0) 86%)}.tab-bar-root.theme-dark .tab-bar-gradient{background:-webkit-gradient(linear,left bottom,left top,from(rgba(25,25,25,.5)),color-stop(50%,rgba(25,25,25,.1)),color-stop(86%,rgba(25,25,25,0)));background:-webkit-linear-gradient(bottom,rgba(25,25,25,.5),rgba(25,25,25,.1) 50%,rgba(25,25,25,0) 86%);background:linear-gradient(0deg,rgba(25,25,25,.5) 0,rgba(25,25,25,.1) 50%,rgba(25,25,25,0) 86%)}.custom-tab-bar{-ms-flex-pack:distribute;-ms-flex-align:center;-webkit-align-items:center;align-items:center;backdrop-filter:blur(32rpx) saturate(1.2);-webkit-backdrop-filter:blur(32rpx) saturate(1.2);background:hsla(0,0%,100%,.55);border:1rpx solid hsla(0,0%,100%,.55);border-radius:64rpx;bottom:36rpx;-webkit-box-shadow:0 12rpx 40rpx rgba(0,0,0,.18),0 4rpx 12rpx rgba(0,0,0,.08);box-shadow:0 12rpx 40rpx rgba(0,0,0,.18),0 4rpx 12rpx rgba(0,0,0,.08);-webkit-box-sizing:border-box;box-sizing:border-box;display:-webkit-flex;display:-ms-flexbox;display:flex;height:116rpx;-webkit-justify-content:space-around;justify-content:space-around;left:36rpx;pointer-events:auto;position:absolute;right:36rpx;z-index:1000}.custom-tab-bar.theme-dark{backdrop-filter:blur(32rpx) saturate(1.2);-webkit-backdrop-filter:blur(32rpx) saturate(1.2);background:rgba(25,25,25,.55);border-color:hsla(0,0%,100%,.14);-webkit-box-shadow:0 12rpx 40rpx rgba(0,0,0,.5),0 4rpx 12rpx rgba(0,0,0,.3);box-shadow:0 12rpx 40rpx rgba(0,0,0,.5),0 4rpx 12rpx rgba(0,0,0,.3)}.tab-item{-ms-flex-align:center;-ms-flex-pack:center;-webkit-align-items:center;align-items:center;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:1;-ms-flex:1;flex:1;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;height:100%;-webkit-justify-content:center;justify-content:center;max-width:160rpx;padding:0 12rpx;position:relative}.tab-indicator{background:rgba(0,0,0,.14);border-radius:50rpx;bottom:6rpx;-webkit-box-shadow:0 0 6rpx rgba(0,0,0,.07);box-shadow:0 0 6rpx rgba(0,0,0,.07);height:100rpx;left:50%;position:absolute;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);width:120rpx}.custom-tab-bar.theme-dark .tab-indicator{background:hsla(0,0%,100%,.14);-webkit-box-shadow:0 0 6rpx hsla(0,0%,100%,.07);box-shadow:0 0 6rpx hsla(0,0%,100%,.07)}.tab-icon-img{height:40rpx;margin-bottom:2rpx;opacity:.8;position:relative;-webkit-transition:-webkit-transform .2s;transition:-webkit-transform .2s;transition:transform .2s;transition:transform .2s,-webkit-transform .2s;width:40rpx;z-index:1}.tab-item.active .tab-icon-img{opacity:1;-webkit-transform:scale(1.08);-ms-transform:scale(1.08);transform:scale(1.08)}.tab-label{color:#8a7e76;font-size:20rpx;font-weight:700;line-height:22rpx;position:relative;-webkit-transition:color .2s;transition:color .2s;z-index:1}.custom-tab-bar.theme-dark .tab-label{color:#b3a79c}.tab-item.active .tab-label{color:#d96c6a}.custom-tab-bar.theme-dark .tab-item.active .tab-label{color:#f09198}
|
||||
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#ff9a9e"><path d="M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8z"/><path d="M5.5 20c.8-3 3.4-4.5 6.5-4.5s5.7 1.5 6.5 4.5"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#d96c6a"><path d="M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8z"/><path d="M5.5 20c.8-3 3.4-4.5 6.5-4.5s5.7 1.5 6.5 4.5"/></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 185 B After Width: | Height: | Size: 185 B |
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#ff9a9e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8z"/><path d="M5.5 20c.8-3 3.4-4.5 6.5-4.5s5.7 1.5 6.5 4.5"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#d96c6a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8z"/><path d="M5.5 20c.8-3 3.4-4.5 6.5-4.5s5.7 1.5 6.5 4.5"/></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 263 B After Width: | Height: | Size: 263 B |
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 3.5h10A1.5 1.5 0 0 1 18.5 5v14A1.5 1.5 0 0 1 17 20.5H7A1.5 1.5 0 0 1 5.5 19V5A1.5 1.5 0 0 1 7 3.5z" fill="#ff9a9e"/><path d="M9 8h6M9 12h6M9 16h3" stroke="#fff" stroke-width="1.6" stroke-linecap="round"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 3.5h10A1.5 1.5 0 0 1 18.5 5v14A1.5 1.5 0 0 1 17 20.5H7A1.5 1.5 0 0 1 5.5 19V5A1.5 1.5 0 0 1 7 3.5z" fill="#d96c6a"/><path d="M9 8h6M9 12h6M9 16h3" stroke="#fff" stroke-width="1.6" stroke-linecap="round"/></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 283 B After Width: | Height: | Size: 283 B |
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#ff9a9e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 3.5h10A1.5 1.5 0 0 1 18.5 5v14A1.5 1.5 0 0 1 17 20.5H7A1.5 1.5 0 0 1 5.5 19V5A1.5 1.5 0 0 1 7 3.5z"/><path d="M9 8h6M9 12h6M9 16h3"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#d96c6a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 3.5h10A1.5 1.5 0 0 1 18.5 5v14A1.5 1.5 0 0 1 17 20.5H7A1.5 1.5 0 0 1 5.5 19V5A1.5 1.5 0 0 1 7 3.5z"/><path d="M9 8h6M9 12h6M9 16h3"/></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 305 B After Width: | Height: | Size: 305 B |
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#ff9a9e"><path d="M5 8h14l-1.2 12H6.2L5 8z"/><path d="M9 8V6a3 3 0 0 1 6 0v2" fill="none" stroke="#ff9a9e" stroke-width="2" stroke-linecap="round"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#d96c6a"><path d="M5 8h14l-1.2 12H6.2L5 8z"/><path d="M9 8V6a3 3 0 0 1 6 0v2" fill="none" stroke="#d96c6a" stroke-width="2" stroke-linecap="round"/></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 221 B After Width: | Height: | Size: 221 B |
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#ff9a9e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 8h14l-1.2 12H6.2L5 8z"/><path d="M9 8V6a3 3 0 0 1 6 0v2"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#d96c6a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 8h14l-1.2 12H6.2L5 8z"/><path d="M9 8V6a3 3 0 0 1 6 0v2"/></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 230 B After Width: | Height: | Size: 230 B |
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#ff9a9e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2.5L14.8 9.2 21.5 12 14.8 14.8 12 21.5 9.2 14.8 2.5 12 9.2 9.2z"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#d96c6a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2.5L14.8 9.2 21.5 12 14.8 14.8 12 21.5 9.2 14.8 2.5 12 9.2 9.2z"/></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 239 B After Width: | Height: | Size: 239 B |
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#ff9a9e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="10.5" cy="10.5" r="6.5"/><path d="M15.5 15.5l4.5 4.5"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#d96c6a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="10.5" cy="10.5" r="6.5"/><path d="M15.5 15.5l4.5 4.5"/></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 227 B After Width: | Height: | Size: 227 B |
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#ff9a9e"><path fill-rule="evenodd" d="M12 4a8 8 0 1 1 0 16 8 8 0 0 1 0-16zm-3 6a1.4 1.4 0 1 0 0 2.8 1.4 1.4 0 0 0 0-2.8zm6 0a1.4 1.4 0 1 0 0 2.8 1.4 1.4 0 0 0 0-2.8zM12 13.6a1.4 1.4 0 1 0 0 2.8 1.4 1.4 0 0 0 0-2.8z"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#d96c6a"><path fill-rule="evenodd" d="M12 4a8 8 0 1 1 0 16 8 8 0 0 1 0-16zm-3 6a1.4 1.4 0 1 0 0 2.8 1.4 1.4 0 0 0 0-2.8zm6 0a1.4 1.4 0 1 0 0 2.8 1.4 1.4 0 0 0 0-2.8zM12 13.6a1.4 1.4 0 1 0 0 2.8 1.4 1.4 0 0 0 0-2.8z"/></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 290 B After Width: | Height: | Size: 290 B |
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#ff9a9e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="8"/><circle cx="9" cy="10" r="1.2" fill="#ff9a9e"/><circle cx="15" cy="10" r="1.2" fill="#ff9a9e"/><circle cx="12" cy="15" r="1.2" fill="#ff9a9e"/><path d="M12 12v3"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#d96c6a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="8"/><circle cx="9" cy="10" r="1.2" fill="#d96c6a"/><circle cx="15" cy="10" r="1.2" fill="#d96c6a"/><circle cx="12" cy="15" r="1.2" fill="#d96c6a"/><path d="M12 12v3"/></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 354 B After Width: | Height: | Size: 354 B |
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#ff9a9e"><path d="M4 11l8-7 8 7v8a1 1 0 0 1-1 1h-4.5v-6h-5v6H5a1 1 0 0 1-1-1z"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#d96c6a"><path d="M4 11l8-7 8 7v8a1 1 0 0 1-1 1h-4.5v-6h-5v6H5a1 1 0 0 1-1-1z"/></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 153 B After Width: | Height: | Size: 153 B |
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#ff9a9e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 11l8-7 8 7"/><path d="M6 9.5V20h12V9.5"/><path d="M10 20v-6h4v6"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#d96c6a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 11l8-7 8 7"/><path d="M6 9.5V20h12V9.5"/><path d="M10 20v-6h4v6"/></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 238 B After Width: | Height: | Size: 238 B |
@@ -1 +1 @@
|
||||
"use strict";(wx["webpackJsonp"]=wx["webpackJsonp"]||[]).push([[301],{6855:function(e,n,t){var a=t(7842),s=t(118),c=t(9703),r=t(9201),i=t(5414),l=t(9674),o=t(4848);function m(){var e=(0,c.wR)(),n=(e.theme,e.resolvedTheme),t=(0,r.c)();(0,i.l)(n);var a=[{title:"\u4e00\u3001\u7528\u6237\u6743\u8d23",content:"\u7528\u6237\u786e\u8ba4\u63d0\u4ea4\u7684\u8bbe\u8ba1\u5185\u5bb9\u4e0d\u4fb5\u72af\u7b2c\u4e09\u65b9\u77e5\u8bc6\u4ea7\u6743\uff0c\u5b9a\u5236\u5546\u54c1\u4e00\u7ecf\u786e\u8ba4\u4e0b\u5355\u5373\u8fdb\u5165\u751f\u4ea7\u6d41\u7a0b\uff0c\u975e\u8d28\u91cf\u95ee\u9898\u4e0d\u652f\u6301\u9000\u6362\u3002"},{title:"\u4e8c\u3001\u9690\u79c1\u4fdd\u62a4",content:"\u6211\u4eec\u4e25\u683c\u4fdd\u62a4\u7528\u6237\u4e2a\u4eba\u4fe1\u606f\uff0c\u5934\u50cf\u4e0e\u6635\u79f0\u4ec5\u7528\u4e8e\u63d0\u5347\u670d\u52a1\u4f53\u9a8c\uff0c\u4e0d\u4e0e\u7b2c\u4e09\u65b9\u5206\u4eab\u3002"},{title:"\u4e09\u3001\u552e\u540e\u8bf4\u660e",content:"\u6536\u5230\u5546\u54c1\u540e\u5982\u6709\u8d28\u91cf\u95ee\u9898\uff0c\u8bf7\u57287\u5929\u5185\u8054\u7cfb\u5ba2\u670d\uff0c\u6211\u4eec\u5c06\u4e3a\u60a8\u514d\u8d39\u91cd\u505a\u6216\u9000\u6b3e\u3002"},{title:"\u56db\u3001\u5b9a\u5236\u6d41\u7a0b",content:"1. \u9009\u62e9\u5546\u54c1\u54c1\u7c7b\u5e76\u52a0\u5165\u8bbe\u8ba1\u6e05\u5355\n2. \u5728DIY\u5de5\u4f5c\u53f0\u4e0a\u4f20\u56fe\u7247\u6216\u8f93\u5165\u6587\u5b57\n3. \u786e\u8ba4\u8bbe\u8ba1\u6548\u679c\u5e76\u63d0\u4ea4\u8ba2\u5355\n4. \u652f\u4ed8\u540e\u8fdb\u5165\u751f\u4ea7\uff0c\u7ea63-7\u4e2a\u5de5\u4f5c\u65e5\u53d1\u8d27\n5. \u7269\u6d41\u8ddf\u8e2a\u81f3\u786e\u8ba4\u6536\u8d27"}];return(0,o.jsxs)(s.Ss,{className:"theme-".concat(n),children:[(0,o.jsx)(l.A,{}),(0,o.jsx)(s.Ss,{className:"agreement-page",children:(0,o.jsxs)(s.Ss,{className:"agreement-content",style:{marginTop:"".concat(t.headerPaddingTop,"px")},children:[(0,o.jsx)(s.EY,{className:"agreement-title",children:"\u5b9a\u5236\u534f\u8bae"}),a.map(function(e,n){return(0,o.jsxs)(s.Ss,{className:"agreement-section",children:[(0,o.jsx)(s.EY,{className:"agreement-h3",children:e.title}),(0,o.jsx)(s.EY,{className:"agreement-p",children:e.content})]},n)})]})})]})}var g={navigationStyle:"custom",enablePageMeta:!0,navigationBarTitleText:"\u5b9a\u5236\u534f\u8bae"};Page((0,a.createPageConfig)(m,"pages/agreement/index",{root:{cn:[]}},g||{}))}},function(e){var n=function(n){return e(e.s=n)};e.O(0,[907,96,76],function(){return n(6855)});e.O()}]);
|
||||
"use strict";(wx["webpackJsonp"]=wx["webpackJsonp"]||[]).push([[301],{6855:function(e,n,t){var a=t(7842),s=t(118),c=t(9703),r=t(9201),i=t(5414),l=t(9674),o=t(4848);function m(){var e=(0,c.wR)(),n=(e.theme,e.resolvedTheme),t=(0,r.c)();(0,i.l)(n);var a=[{title:"\u4e00\u3001\u7528\u6237\u6743\u8d23",content:"\u7528\u6237\u786e\u8ba4\u63d0\u4ea4\u7684\u8bbe\u8ba1\u5185\u5bb9\u4e0d\u4fb5\u72af\u7b2c\u4e09\u65b9\u77e5\u8bc6\u4ea7\u6743\uff0c\u5b9a\u5236\u5546\u54c1\u4e00\u7ecf\u786e\u8ba4\u4e0b\u5355\u5373\u8fdb\u5165\u751f\u4ea7\u6d41\u7a0b\uff0c\u975e\u8d28\u91cf\u95ee\u9898\u4e0d\u652f\u6301\u9000\u6362\u3002"},{title:"\u4e8c\u3001\u9690\u79c1\u4fdd\u62a4",content:"\u6211\u4eec\u4e25\u683c\u4fdd\u62a4\u7528\u6237\u4e2a\u4eba\u4fe1\u606f\uff0c\u5934\u50cf\u4e0e\u6635\u79f0\u4ec5\u7528\u4e8e\u63d0\u5347\u670d\u52a1\u4f53\u9a8c\uff0c\u4e0d\u4e0e\u7b2c\u4e09\u65b9\u5206\u4eab\u3002"},{title:"\u4e09\u3001\u552e\u540e\u8bf4\u660e",content:"\u6536\u5230\u5546\u54c1\u540e\u5982\u6709\u8d28\u91cf\u95ee\u9898\uff0c\u8bf7\u57287\u5929\u5185\u8054\u7cfb\u5ba2\u670d\uff0c\u6211\u4eec\u5c06\u4e3a\u60a8\u514d\u8d39\u91cd\u505a\u6216\u9000\u6b3e\u3002"},{title:"\u56db\u3001\u5b9a\u5236\u6d41\u7a0b",content:"1. \u9009\u62e9\u5546\u54c1\u54c1\u7c7b\u5e76\u52a0\u5165\u8bbe\u8ba1\u6e05\u5355\n2. \u5728DIY\u5de5\u4f5c\u53f0\u4e0a\u4f20\u56fe\u7247\u6216\u8f93\u5165\u6587\u5b57\n3. \u786e\u8ba4\u8bbe\u8ba1\u6548\u679c\u5e76\u63d0\u4ea4\u8ba2\u5355\n4. \u652f\u4ed8\u540e\u8fdb\u5165\u751f\u4ea7\uff0c\u7ea63-7\u4e2a\u5de5\u4f5c\u65e5\u53d1\u8d27\n5. \u7269\u6d41\u8ddf\u8e2a\u81f3\u786e\u8ba4\u6536\u8d27"}];return(0,o.jsxs)(s.Ss,{className:"theme-".concat(n),children:[(0,o.jsx)(l.A,{}),(0,o.jsx)(s.Ss,{className:"agreement-page",children:(0,o.jsxs)(s.Ss,{className:"agreement-content",style:{marginTop:"".concat(t.headerPaddingTop,"px")},children:[(0,o.jsx)(s.EY,{className:"agreement-title",children:"\u5b9a\u5236\u534f\u8bae"}),a.map(function(e,n){return(0,o.jsxs)(s.Ss,{className:"agreement-section surface-card",children:[(0,o.jsx)(s.EY,{className:"agreement-h3",children:e.title}),(0,o.jsx)(s.EY,{className:"agreement-p",children:e.content})]},n)})]})})]})}var g={navigationStyle:"custom",enablePageMeta:!0,navigationBarTitleText:"\u5b9a\u5236\u534f\u8bae"};Page((0,a.createPageConfig)(m,"pages/agreement/index",{root:{cn:[]}},g||{}))}},function(e){var n=function(n){return e(e.s=n)};e.O(0,[907,96,76],function(){return n(6855)});e.O()}]);
|
||||
@@ -1 +1 @@
|
||||
.agreement-page{padding:0 24rpx 24rpx}.agreement-title{color:var(--text-primary);display:block;font-size:40rpx;font-weight:800;margin-bottom:32rpx;padding-top:24rpx}.agreement-content{line-height:1.8;padding:40rpx 32rpx}.agreement-section{margin-bottom:32rpx}.agreement-h3{color:var(--text-primary);display:block;font-size:32rpx;font-weight:700;margin-bottom:16rpx}.agreement-p{color:var(--text-secondary);display:block;font-size:28rpx;line-height:1.8}
|
||||
.agreement-page{-webkit-box-sizing:border-box;box-sizing:border-box;min-height:100vh;padding:0 32rpx calc(24rpx + env(safe-area-inset-bottom))}.agreement-content{line-height:1.8;padding:32rpx 0 48rpx}.agreement-title{color:var(--text-primary);display:block;font-size:44rpx;font-weight:700;letter-spacing:0;line-height:1.2;margin-bottom:32rpx}.agreement-section{display:block;margin-bottom:24rpx;padding:32rpx}.agreement-section:last-child{margin-bottom:0}.agreement-h3{color:var(--text-primary);display:block;font-size:32rpx;font-weight:700;letter-spacing:0;line-height:1.3;margin-bottom:16rpx}.agreement-p{color:var(--text-secondary);display:block;font-size:28rpx;line-height:1.8;white-space:pre-line}
|
||||
@@ -1 +1 @@
|
||||
.service-page{min-height:100vh;padding:0 24rpx 24rpx}.page-header{margin:20rpx 0 0;padding:32rpx 32rpx 24rpx}.service-hero{-ms-flex-align:center;-webkit-align-items:center;align-items:center;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding:50rpx 40rpx;text-align:center}.service-hero-icon{height:56rpx;margin-bottom:20rpx;width:56rpx}.service-title{color:var(--text-primary);display:block;font-size:36rpx;font-weight:700;margin-bottom:12rpx}.service-desc{color:var(--text-secondary);display:block;font-size:24rpx;margin-bottom:32rpx}.service-btn{border-radius:50rpx!important;font-size:30rpx!important;padding:24rpx 56rpx!important}.contact-list{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:20rpx}.contact-item{-ms-flex-align:center;-webkit-align-items:center;align-items:center;display:-webkit-flex;display:-ms-flexbox;display:flex;padding:28rpx 32rpx}.contact-icon{font-size:48rpx;margin-right:24rpx}.contact-icon-img{-ms-flex-negative:0;-webkit-flex-shrink:0;flex-shrink:0;height:32rpx;margin-right:24rpx;width:32rpx}.contact-info{-webkit-flex:1;-ms-flex:1;flex:1}.contact-label{color:var(--text-secondary);display:block;font-size:24rpx;margin-bottom:4rpx}.contact-value{color:var(--text-primary);font-size:30rpx;font-weight:600}.faq-card{margin-bottom:20rpx;padding:28rpx 32rpx}.faq-q{color:var(--text-primary);display:block;font-size:30rpx;font-weight:700;margin-bottom:12rpx}.faq-a{color:var(--text-secondary);font-size:26rpx;line-height:1.6}.enterprise-service{padding:32rpx}.enterprise-icon{height:28rpx;margin-right:12rpx;width:28rpx}.enterprise-title{color:var(--text-primary);display:block;font-size:30rpx;font-weight:700;margin-bottom:8rpx}.enterprise-desc{color:var(--text-secondary);display:block;font-size:24rpx;margin-bottom:24rpx}
|
||||
.service-page{-webkit-box-sizing:border-box;box-sizing:border-box;min-height:100vh;padding:0 32rpx calc(24rpx + env(safe-area-inset-bottom))}.service-page .page-header.service-header{margin:0;padding-bottom:32rpx;padding-left:0;padding-right:0;text-align:center}.service-header .page-title{color:var(--text-primary);font-size:44rpx;font-weight:700;letter-spacing:0;line-height:1.2}.service-hero{-ms-flex-align:center;-webkit-align-items:center;align-items:center;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding:56rpx 40rpx;text-align:center}.service-hero-icon{height:88rpx;margin-bottom:24rpx;width:88rpx}.service-title{color:var(--text-primary);display:block;font-size:36rpx;font-weight:700;letter-spacing:0;margin-bottom:12rpx}.service-desc{color:var(--text-secondary);display:block;font-size:24rpx;line-height:1.5;margin-bottom:32rpx}.service-btn{-ms-flex-align:center;-ms-flex-pack:center;-webkit-align-items:center;align-items:center;-webkit-box-sizing:border-box;box-sizing:border-box;display:-webkit-flex;display:-ms-flexbox;display:flex;font-size:28rpx;font-weight:600;height:80rpx;-webkit-justify-content:center;justify-content:center;min-width:280rpx;padding:0 48rpx}.service-page .section-title{color:var(--text-primary);display:block;font-size:32rpx;font-weight:700;letter-spacing:0;margin-bottom:24rpx}.contact-list.surface-card{overflow:hidden;padding:0 32rpx}.contact-item{-ms-flex-align:center;-webkit-align-items:center;align-items:center;border-bottom:1rpx solid var(--border);display:-webkit-flex;display:-ms-flexbox;display:flex;min-height:112rpx;padding:24rpx 0}.contact-item:last-child{border-bottom:none}.contact-item-link{-webkit-transition:background .16s ease;transition:background .16s ease}.contact-item-link:active{background:var(--bg-muted)}.contact-icon-img{-ms-flex-negative:0;-webkit-flex-shrink:0;flex-shrink:0;height:48rpx;margin-right:24rpx;width:48rpx}.contact-info{-webkit-flex:1;-ms-flex:1;flex:1;min-width:0}.contact-label{color:var(--text-secondary);display:block;font-size:24rpx;line-height:1.4;margin-bottom:4rpx}.contact-value{color:var(--text-primary);display:block;font-size:28rpx;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.contact-arrow{-ms-flex-negative:0;color:var(--text-muted);-webkit-flex-shrink:0;flex-shrink:0;font-size:32rpx;line-height:1;margin-left:16rpx}.faq-card{display:block;margin-bottom:24rpx;padding:32rpx}.faq-q{color:var(--text-primary);display:block;font-size:30rpx;font-weight:700;letter-spacing:0;line-height:1.45;margin-bottom:12rpx}.faq-a{color:var(--text-secondary);display:block;font-size:26rpx;line-height:1.7}.enterprise-service{padding:32rpx}.enterprise-service .flex-center{-ms-flex-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start;margin-bottom:12rpx}.enterprise-icon{-ms-flex-negative:0;-webkit-flex-shrink:0;flex-shrink:0;height:40rpx;margin-right:12rpx;width:40rpx}.enterprise-title{color:var(--text-primary);display:block;font-size:30rpx;font-weight:700;letter-spacing:0}.enterprise-desc{color:var(--text-secondary);display:block;font-size:24rpx;line-height:1.6;margin-bottom:24rpx}.enterprise-btn{-ms-flex-align:center;-ms-flex-pack:center;-webkit-align-items:center;align-items:center;display:-webkit-flex;display:-ms-flexbox;display:flex;font-size:28rpx;font-weight:600;height:80rpx;-webkit-justify-content:center;justify-content:center}
|
||||
@@ -1 +1 @@
|
||||
"use strict";(wx["webpackJsonp"]=wx["webpackJsonp"]||[]).push([[205],{6296:function(s,e,a){var n=a(7842),c=a(118),o=a(758),i=a.n(o),r=a(9703),l=a(9201),d=a(5414),t=a(9674),h=a(5234),p=a(4848);function m(){var s=(0,r.wR)(),e=s.resolvedTheme,a=(0,l.c)();(0,d.l)(e);var n=function(s){i().navigateTo({url:"/pages/shop/detail/index?id=".concat(s)})};return(0,p.jsxs)(c.Ss,{className:"shop-page theme-".concat(e),children:[(0,p.jsx)(t.A,{}),(0,p.jsxs)(c.Ss,{className:"shop-list",children:[(0,p.jsxs)(c.Ss,{className:"shop-header",style:{paddingTop:"".concat(a.headerPaddingTop,"px")},children:[(0,p.jsx)(c.EY,{className:"shop-header-title",children:"\u667a\u7ed8\u7cbe\u9009"}),(0,p.jsx)(c.EY,{className:"shop-header-sub",children:"\u6fc0\u5149\u5fae\u96d5\u5b9a\u5236\u597d\u7269"})]}),(0,p.jsx)(c.Ss,{className:"shop-grid",children:h.zv.map(function(s){var e,a,o,i;return(0,p.jsxs)(c.Ss,{className:"shop-card",onTap:function(){return n(s.id)},children:[(0,p.jsx)(c.Ss,{className:"shop-card-img-wrap",children:(0,p.jsx)(c._V,{className:"shop-card-img",src:(null===(e=s.images)||void 0===e?void 0:e[0])||s.iconImg||"",mode:"aspectFill",lazyLoad:!0})}),(0,p.jsxs)(c.Ss,{className:"shop-card-info",style:{backgroundColor:"rgba(".concat((null===(a=s.tone)||void 0===a?void 0:a[0])||28,", ").concat((null===(o=s.tone)||void 0===o?void 0:o[1])||22,", ").concat((null===(i=s.tone)||void 0===i?void 0:i[2])||18,", 0.92)")},children:[(0,p.jsx)(c.EY,{className:"shop-card-name",children:s.name}),(0,p.jsxs)(c.EY,{className:"shop-card-price",children:["\xa5",s.price]})]})]},s.id)})}),(0,p.jsx)(c.Ss,{style:{height:"160px"}})]})]})}var u={navigationStyle:"custom",enablePageMeta:!0};Page((0,n.createPageConfig)(m,"pages/shop/index",{root:{cn:[]}},u||{}))}},function(s){var e=function(e){return s(s.s=e)};s.O(0,[907,96,76],function(){return e(6296)});s.O()}]);
|
||||
"use strict";(wx["webpackJsonp"]=wx["webpackJsonp"]||[]).push([[205],{6296:function(s,e,a){var c=a(7842),n=a(118),r=a(758),i=a.n(r),o=a(9703),d=a(9201),l=a(5414),h=a(9674),p=a(5234),t=a(4848);function m(){var s=(0,o.wR)(),e=s.resolvedTheme,a=(0,d.c)();(0,l.l)(e);var c=function(s){i().navigateTo({url:"/pages/shop/detail/index?id=".concat(s)})};return(0,t.jsxs)(n.Ss,{className:"shop-page theme-".concat(e),children:[(0,t.jsx)(h.A,{}),(0,t.jsxs)(n.Ss,{className:"shop-list",children:[(0,t.jsxs)(n.Ss,{className:"shop-header",style:{paddingTop:"".concat(a.headerPaddingTop,"px")},children:[(0,t.jsx)(n.EY,{className:"shop-header-title",children:"\u667a\u7ed8\u7cbe\u9009"}),(0,t.jsx)(n.EY,{className:"shop-header-sub",children:"\u6fc0\u5149\u5fae\u96d5\u5b9a\u5236\u597d\u7269"})]}),(0,t.jsx)(n.Ss,{className:"shop-grid",children:p.zv.map(function(s){var e=s.images[0]||s.iconImg||"";return(0,t.jsxs)(n.Ss,{className:"shop-card",onTap:function(){return c(s.id)},children:[(0,t.jsx)(n.Ss,{className:"shop-card-img-wrap",children:(0,t.jsx)(n._V,{className:"shop-card-img",src:e,mode:"aspectFill",lazyLoad:!0})}),(0,t.jsxs)(n.Ss,{className:"shop-card-body",children:[(0,t.jsx)(n.EY,{className:"shop-card-name",children:s.name}),(0,t.jsx)(n.EY,{className:"shop-card-desc",children:s.desc||""}),(0,t.jsxs)(n.EY,{className:"shop-card-price",children:["\xa5",s.price]})]})]},s.id)})})]})]})}var x={navigationStyle:"custom",enablePageMeta:!0};Page((0,c.createPageConfig)(m,"pages/shop/index",{root:{cn:[]}},x||{}))}},function(s){var e=function(e){return s(s.s=e)};s.O(0,[907,96,76],function(){return e(6296)});s.O()}]);
|
||||
@@ -1 +1 @@
|
||||
.shop-list{padding:0 24rpx 24rpx}.shop-header{padding:40rpx 0 24rpx;text-align:center}.shop-header-title{color:var(--text-primary);display:block;font-size:40rpx;font-weight:800;letter-spacing:4rpx}.shop-header-sub{color:var(--text-secondary);display:block;font-size:24rpx;margin-top:8rpx}.shop-grid{display:grid;gap:20rpx;grid-template-columns:1fr 1fr}.shop-card{background:var(--bg-card);border-radius:24rpx;-webkit-box-shadow:var(--shadow-card);box-shadow:var(--shadow-card);overflow:hidden;-webkit-transition:-webkit-transform .15s ease;transition:-webkit-transform .15s ease;transition:transform .15s ease;transition:transform .15s ease,-webkit-transform .15s ease}.shop-card:active{-webkit-transform:scale(.97);-ms-transform:scale(.97);transform:scale(.97)}.shop-card-img-wrap{aspect-ratio:3/4;background:#2a2218;overflow:hidden}.shop-card-img{height:100%;-o-object-fit:cover;object-fit:cover;-webkit-transition:-webkit-transform .4s ease;transition:-webkit-transform .4s ease;transition:transform .4s ease;transition:transform .4s ease,-webkit-transform .4s ease;width:100%}.shop-card-info{padding:16rpx 20rpx 20rpx}.shop-card-name{-webkit-line-clamp:2;-webkit-box-orient:vertical;color:#e8e0d6;display:-webkit-box;font-size:26rpx;line-height:1.4;min-height:74rpx;overflow:hidden}.shop-card-price{color:#ff9a9e;display:block;font-size:30rpx;font-weight:700;margin-top:10rpx}@media (min-width:750rpx){.shop-page{-ms-flex-pack:center;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:center;justify-content:center}}
|
||||
.shop-list{padding:0 32rpx 24rpx}.shop-header{padding:48rpx 0 32rpx;text-align:center}.shop-header-title{color:var(--text-primary);display:block;font-size:44rpx;font-weight:700;letter-spacing:0}.shop-header-sub{color:var(--text-secondary);display:block;font-size:24rpx;margin-top:8rpx}.shop-grid{display:grid;gap:24rpx;grid-template-columns:1fr 1fr}.shop-card{background:var(--bg-card);border:1rpx solid var(--border);border-radius:24rpx;-webkit-box-shadow:var(--shadow-card);box-shadow:var(--shadow-card);overflow:hidden;-webkit-transition:-webkit-transform .15s ease;transition:-webkit-transform .15s ease;transition:transform .15s ease;transition:transform .15s ease,-webkit-transform .15s ease}.shop-card:active{-webkit-transform:scale(.98);-ms-transform:scale(.98);transform:scale(.98)}.shop-card-img-wrap{aspect-ratio:1/1;background:var(--bg-muted);overflow:hidden}.shop-card-img{height:100%;-o-object-fit:cover;object-fit:cover;-webkit-transition:-webkit-transform .4s ease;transition:-webkit-transform .4s ease;transition:transform .4s ease;transition:transform .4s ease,-webkit-transform .4s ease;width:100%}.shop-card-body{padding:20rpx 24rpx 24rpx}.shop-card-name{-webkit-line-clamp:2;-webkit-box-orient:vertical;color:var(--text-primary);display:-webkit-box;font-size:28rpx;font-weight:700;line-height:1.4;overflow:hidden}.shop-card-desc{-webkit-line-clamp:2;-webkit-box-orient:vertical;color:var(--text-secondary);display:-webkit-box;font-size:24rpx;line-height:1.4;margin-top:8rpx;overflow:hidden}.shop-card-price{color:var(--accent-primary);display:block;font-size:32rpx;font-variant:tabular-nums;font-weight:700;margin-top:12rpx}@media (min-width:750rpx){.shop-page{-ms-flex-pack:center;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:center;justify-content:center}}
|
||||
@@ -1,14 +1,14 @@
|
||||
{
|
||||
"light": {
|
||||
"navBgColor": "#ffffff",
|
||||
"navBgColor": "#faf7f2",
|
||||
"navTxtStyle": "black",
|
||||
"bgColor": "#ffffff",
|
||||
"bgColor": "#faf7f2",
|
||||
"bgTxtStyle": "dark",
|
||||
"bgColorTop": "#ffffff",
|
||||
"bgColorBottom": "#ffffff",
|
||||
"tabBarColor": "#b08d8d",
|
||||
"tabBarSelectedColor": "#ff9a9e",
|
||||
"tabBarBgColor": "#ffffff",
|
||||
"bgColorTop": "#faf7f2",
|
||||
"bgColorBottom": "#faf7f2",
|
||||
"tabBarColor": "#8a7e76",
|
||||
"tabBarSelectedColor": "#d96c6a",
|
||||
"tabBarBgColor": "#faf7f2",
|
||||
"tabBarBorderStyle": "black"
|
||||
},
|
||||
"dark": {
|
||||
@@ -18,8 +18,8 @@
|
||||
"bgTxtStyle": "light",
|
||||
"bgColorTop": "#191919",
|
||||
"bgColorBottom": "#191919",
|
||||
"tabBarColor": "#999999",
|
||||
"tabBarSelectedColor": "#ff7eb3",
|
||||
"tabBarColor": "#b3a79c",
|
||||
"tabBarSelectedColor": "#f09198",
|
||||
"tabBarBgColor": "#191919",
|
||||
"tabBarBorderStyle": "white"
|
||||
}
|
||||
|
||||
@@ -129,31 +129,6 @@ page {
|
||||
border-radius: 999rpx;
|
||||
}
|
||||
|
||||
/* 固定底部操作栏 */
|
||||
.action-bar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 48rpx;
|
||||
padding: 40rpx 64rpx calc(40rpx + env(safe-area-inset-bottom));
|
||||
background: rgba(255, 255, 255, 0.55);
|
||||
backdrop-filter: blur(32px) saturate(1.2);
|
||||
-webkit-backdrop-filter: blur(32px) saturate(1.2);
|
||||
border-top: 1rpx solid var(--glass-line);
|
||||
z-index: 500;
|
||||
}
|
||||
|
||||
.theme-dark .action-bar {
|
||||
background: rgba(25, 25, 25, 0.55);
|
||||
backdrop-filter: blur(32px) saturate(1.2);
|
||||
-webkit-backdrop-filter: blur(32px) saturate(1.2);
|
||||
border-top: 1rpx solid var(--glass-line);
|
||||
}
|
||||
|
||||
/* === 标题文字 === */
|
||||
.page-title {
|
||||
font-size: 80rpx;
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
.bottom-action-bar {
|
||||
position: fixed;
|
||||
left: 36rpx;
|
||||
right: 36rpx;
|
||||
bottom: 36rpx;
|
||||
z-index: 500;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24rpx;
|
||||
padding: 24rpx;
|
||||
padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
|
||||
border-radius: 64rpx;
|
||||
background: rgba(255, 255, 255, 0.55);
|
||||
backdrop-filter: blur(32px) saturate(1.2);
|
||||
-webkit-backdrop-filter: blur(32px) saturate(1.2);
|
||||
border: 1rpx solid rgba(255, 255, 255, 0.55);
|
||||
box-shadow: 0 12rpx 40rpx rgba(46, 34, 34, 0.18), 0 4rpx 12rpx rgba(46, 34, 34, 0.08);
|
||||
}
|
||||
|
||||
.theme-dark .bottom-action-bar {
|
||||
background: rgba(25, 25, 25, 0.55);
|
||||
border-color: rgba(255, 255, 255, 0.14);
|
||||
box-shadow: 0 12rpx 40rpx rgba(0, 0, 0, 0.5), 0 4rpx 12rpx rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { View } from '@tarojs/components'
|
||||
import type { CSSProperties, ReactNode } from 'react'
|
||||
import './index.scss'
|
||||
|
||||
export interface BottomActionBarProps {
|
||||
children?: ReactNode
|
||||
className?: string
|
||||
style?: CSSProperties
|
||||
}
|
||||
|
||||
export default function BottomActionBar({ children, className, style }: BottomActionBarProps) {
|
||||
return (
|
||||
<View className={`bottom-action-bar ${className || ''}`} style={style}>
|
||||
{children}
|
||||
</View>
|
||||
)
|
||||
}
|
||||
@@ -36,17 +36,6 @@ export function ThemeProvider({ children }: { children: React.ReactNode }) {
|
||||
setResolved(resolveTheme(mode))
|
||||
}, [])
|
||||
|
||||
const setTheme = useCallback((t: ThemeMode) => {
|
||||
saveTheme(t)
|
||||
set(t)
|
||||
updateResolved(t)
|
||||
}, [updateResolved])
|
||||
|
||||
const toggleTheme = useCallback(() => {
|
||||
const next = resolvedTheme === 'light' ? 'dark' : 'light'
|
||||
setTheme(next)
|
||||
}, [resolvedTheme, setTheme])
|
||||
|
||||
/**
|
||||
* darkmode 只作为系统主题探测通道;选中“跟随系统”时才跟着系统切换,
|
||||
* 固定浅色/深色时由 setTheme 直接决定,不被动绑定系统。
|
||||
@@ -80,6 +69,21 @@ export function ThemeProvider({ children }: { children: React.ReactNode }) {
|
||||
}
|
||||
}, [updateFromSystem])
|
||||
|
||||
const setTheme = useCallback((t: ThemeMode) => {
|
||||
saveTheme(t)
|
||||
set(t)
|
||||
if (t === 'auto') {
|
||||
detectSystemTheme()
|
||||
} else {
|
||||
updateResolved(t)
|
||||
}
|
||||
}, [detectSystemTheme, updateResolved])
|
||||
|
||||
const toggleTheme = useCallback(() => {
|
||||
const next = resolvedTheme === 'light' ? 'dark' : 'light'
|
||||
setTheme(next)
|
||||
}, [resolvedTheme, setTheme])
|
||||
|
||||
useEffect(() => {
|
||||
detectSystemTheme()
|
||||
}, [detectSystemTheme])
|
||||
|
||||
@@ -1,11 +1,36 @@
|
||||
.custom-tab-bar {
|
||||
.tab-bar-root {
|
||||
position: fixed;
|
||||
bottom: 12px;
|
||||
left: 12px;
|
||||
right: 12px;
|
||||
border-radius: 24px;
|
||||
height: calc(96px + constant(safe-area-inset-bottom));
|
||||
height: calc(96px + env(safe-area-inset-bottom));
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 160rpx;
|
||||
pointer-events: none;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.tab-bar-gradient {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.tab-bar-root.theme-light .tab-bar-gradient {
|
||||
background: linear-gradient(to top, rgba(250, 247, 242, 0.5) 0%, rgba(250, 247, 242, 0.1) 50%, rgba(250, 247, 242, 0) 86%);
|
||||
}
|
||||
|
||||
.tab-bar-root.theme-dark .tab-bar-gradient {
|
||||
background: linear-gradient(to top, rgba(25, 25, 25, 0.5) 0%, rgba(25, 25, 25, 0.1) 50%, rgba(25, 25, 25, 0) 86%);
|
||||
}
|
||||
|
||||
.custom-tab-bar {
|
||||
position: absolute;
|
||||
bottom: 36rpx;
|
||||
left: 36rpx;
|
||||
right: 36rpx;
|
||||
border-radius: 64rpx;
|
||||
height: 116rpx;
|
||||
box-sizing: border-box;
|
||||
background: rgba(255, 255, 255, 0.55);
|
||||
backdrop-filter: blur(32px) saturate(1.2);
|
||||
@@ -13,9 +38,9 @@
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
border: 1rpx solid rgba(255, 255, 255, 0.55);
|
||||
box-shadow: 0 12rpx 40rpx rgba(0, 0, 0, 0.18), 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
|
||||
pointer-events: auto;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
@@ -24,7 +49,8 @@
|
||||
background: rgba(25, 25, 25, 0.55);
|
||||
backdrop-filter: blur(32px) saturate(1.2);
|
||||
-webkit-backdrop-filter: blur(32px) saturate(1.2);
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
|
||||
border-color: rgba(255, 255, 255, 0.14);
|
||||
box-shadow: 0 12rpx 40rpx rgba(0, 0, 0, 0.5), 0 4rpx 12rpx rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.tab-item {
|
||||
@@ -35,10 +61,30 @@
|
||||
padding: 0 12px;
|
||||
position: relative;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
max-width: 160px;
|
||||
}
|
||||
|
||||
.tab-indicator {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
bottom: 6rpx;
|
||||
width: 120rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 50rpx;
|
||||
background: rgba(0, 0, 0, 0.14);
|
||||
box-shadow: 0 0 6rpx rgba(0, 0, 0, 0.07);
|
||||
}
|
||||
|
||||
.custom-tab-bar.theme-dark .tab-indicator {
|
||||
background: rgba(255, 255, 255, 0.14);
|
||||
box-shadow: 0 0 6rpx rgba(255, 255, 255, 0.07);
|
||||
}
|
||||
|
||||
.tab-icon-img {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
margin-bottom: 2px;
|
||||
@@ -52,6 +98,8 @@
|
||||
}
|
||||
|
||||
.tab-label {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
font-size: 20px;
|
||||
color: #8a7e76;
|
||||
font-weight: 700;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { View, Text, Image } from '@tarojs/components'
|
||||
import Taro from '@tarojs/taro'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { getTheme, resolveTheme } from '../utils/store'
|
||||
import { getTheme, resolveTheme, setDetectedSystemTheme } from '../utils/store'
|
||||
import { THEME_CHANGE_EVENT } from '../context/ThemeContext'
|
||||
import { applyPageBackground } from '../utils/themeBackground'
|
||||
import { assetUrl } from '../utils/asset'
|
||||
@@ -26,6 +26,11 @@ function currentTabPath(): string {
|
||||
return matchTab(path)
|
||||
}
|
||||
|
||||
type ThemeChangeApi = {
|
||||
onThemeChange?: (listener: (res: { theme?: string }) => void) => void
|
||||
offThemeChange?: (listener: (res: { theme?: string }) => void) => void
|
||||
}
|
||||
|
||||
export default function CustomTabBar() {
|
||||
const [resolvedTheme, setResolvedTheme] = useState<'light' | 'dark'>(resolveTheme(getTheme()))
|
||||
|
||||
@@ -40,6 +45,27 @@ export default function CustomTabBar() {
|
||||
}
|
||||
}, [])
|
||||
|
||||
// 自定义 tabBar 不处在 React Tree 里,额外直接监听系统主题,保证“跟随系统”时也即时切换
|
||||
useEffect(() => {
|
||||
const handler = (res: { theme?: string }) => {
|
||||
if (res && (res.theme === 'dark' || res.theme === 'light')) {
|
||||
setDetectedSystemTheme(res.theme)
|
||||
if (getTheme() === 'auto') {
|
||||
setResolvedTheme(res.theme)
|
||||
}
|
||||
}
|
||||
}
|
||||
const themeApi = Taro as typeof Taro & ThemeChangeApi
|
||||
if (themeApi.onThemeChange) {
|
||||
themeApi.onThemeChange(handler)
|
||||
}
|
||||
return () => {
|
||||
if (themeApi.offThemeChange) {
|
||||
themeApi.offThemeChange(handler)
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
|
||||
// 其它入口(如页面内部调用 switchTab)也会回到 tabBar,收到事件后重新同步选中态
|
||||
useEffect(() => {
|
||||
const handler = (path?: string) => {
|
||||
@@ -66,20 +92,24 @@ export default function CustomTabBar() {
|
||||
}
|
||||
|
||||
return (
|
||||
<View className={`custom-tab-bar theme-${resolvedTheme}`}>
|
||||
{TABS.map((tab) => {
|
||||
const isActive = tab.pagePath === activeTab
|
||||
return (
|
||||
<View
|
||||
key={tab.pagePath}
|
||||
className={`tab-item ${isActive ? 'active' : ''}`}
|
||||
onTap={() => switchTab(tab.pagePath)}
|
||||
>
|
||||
<Image className={`tab-icon-img ${isActive ? 'active' : ''}`} src={isActive ? tab.iconActive : tab.icon} mode='aspectFit' />
|
||||
<Text className='tab-label'>{tab.label}</Text>
|
||||
</View>
|
||||
)
|
||||
})}
|
||||
<View className={`tab-bar-root theme-${resolvedTheme}`}>
|
||||
<View className='tab-bar-gradient' />
|
||||
<View className={`custom-tab-bar theme-${resolvedTheme}`}>
|
||||
{TABS.map((tab) => {
|
||||
const isActive = tab.pagePath === activeTab
|
||||
return (
|
||||
<View
|
||||
key={tab.pagePath}
|
||||
className={`tab-item ${isActive ? 'active' : ''}`}
|
||||
onTap={() => switchTab(tab.pagePath)}
|
||||
>
|
||||
{isActive && <View className='tab-indicator' />}
|
||||
<Image className={`tab-icon-img ${isActive ? 'active' : ''}`} src={isActive ? tab.iconActive : tab.icon} mode='aspectFit' />
|
||||
<Text className='tab-label'>{tab.label}</Text>
|
||||
</View>
|
||||
)
|
||||
})}
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,135 +1,268 @@
|
||||
/* ============================================================
|
||||
Address Page — 收货地址
|
||||
============================================================ */
|
||||
.address-page {
|
||||
padding: 0 24px 24px;
|
||||
padding: 0 32rpx;
|
||||
padding-bottom: calc(48rpx + env(safe-area-inset-bottom));
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* --- Page Header --- */
|
||||
.page-header {
|
||||
margin-bottom: 24rpx;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.page-header-inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
min-height: 88rpx;
|
||||
}
|
||||
|
||||
.back-btn {
|
||||
font-size: 40px;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
flex: 0 0 auto;
|
||||
border-radius: 50%;
|
||||
background: var(--bg-card);
|
||||
border: 1rpx solid var(--border-strong);
|
||||
box-shadow: var(--shadow-card);
|
||||
}
|
||||
|
||||
.back-btn:active {
|
||||
transform: scale(0.96);
|
||||
}
|
||||
|
||||
.back-arrow {
|
||||
font-size: 36rpx;
|
||||
line-height: 1;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.nav-title {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 34rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.nav-placeholder {
|
||||
width: 88rpx;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
/* --- 地址列表 --- */
|
||||
.address-list {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24rpx;
|
||||
}
|
||||
|
||||
.address-card {
|
||||
padding: 24px;
|
||||
margin-bottom: 20px;
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.address-header {
|
||||
margin-bottom: 20px;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.address-user {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
gap: 16rpx;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.address-name {
|
||||
font-size: 32px;
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.address-phone {
|
||||
font-size: 28px;
|
||||
font-size: 24rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.default-tag {
|
||||
margin-left: 12px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
height: 40rpx;
|
||||
padding: 0 16rpx;
|
||||
border-radius: 999rpx;
|
||||
background: var(--accent-primary);
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
padding: 2px 10px;
|
||||
border-radius: 8px;
|
||||
color: var(--bg-page);
|
||||
font-size: 20rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.address-full {
|
||||
font-size: 28px;
|
||||
display: block;
|
||||
font-size: 26rpx;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.5;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.address-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 24px;
|
||||
padding-top: 16px;
|
||||
gap: 16rpx;
|
||||
margin-top: 20rpx;
|
||||
padding-top: 24rpx;
|
||||
border-top: 1rpx solid var(--border);
|
||||
}
|
||||
|
||||
.address-act {
|
||||
font-size: 26px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 56rpx;
|
||||
padding: 0 24rpx;
|
||||
border-radius: 999rpx;
|
||||
background: var(--accent-secondary-soft);
|
||||
color: var(--accent-secondary);
|
||||
font-size: 24rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.address-act.delete {
|
||||
background: var(--danger-soft);
|
||||
color: var(--danger);
|
||||
}
|
||||
|
||||
/* 表单弹窗 */
|
||||
/* --- 空状态 --- */
|
||||
.empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 96rpx 40rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.empty-icon-img {
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.empty-sub {
|
||||
font-size: 26rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* --- 底部操作栏 --- */
|
||||
.bottom-action-bar .btn-primary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
min-height: 96rpx;
|
||||
padding: 0;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* --- 新增 / 编辑弹窗 --- */
|
||||
.modal-overlay {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
padding: 48rpx;
|
||||
}
|
||||
|
||||
.address-form {
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
padding: 40px;
|
||||
max-width: 640rpx;
|
||||
padding: 40rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
display: block;
|
||||
text-align: center;
|
||||
margin-bottom: 32rpx;
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.form-input {
|
||||
width: 100%;
|
||||
height: 80px;
|
||||
background: var(--bg-input);
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 16px;
|
||||
padding: 0 24px;
|
||||
font-size: 28px;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 20px;
|
||||
height: 88rpx;
|
||||
margin-bottom: 20rpx;
|
||||
padding: 0 24rpx;
|
||||
box-sizing: border-box;
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 16rpx;
|
||||
background: var(--bg-input);
|
||||
font-size: 28rpx;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.form-input:focus {
|
||||
border-color: var(--accent-primary);
|
||||
background: var(--bg-card);
|
||||
}
|
||||
|
||||
.form-picker {
|
||||
width: 100%;
|
||||
height: 80px;
|
||||
background: var(--bg-input);
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 24px;
|
||||
margin-bottom: 20px;
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
margin-bottom: 20rpx;
|
||||
padding: 0 24rpx;
|
||||
box-sizing: border-box;
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 16rpx;
|
||||
background: var(--bg-input);
|
||||
}
|
||||
|
||||
.form-picker-val {
|
||||
font-size: 28px;
|
||||
font-size: 28rpx;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.form-picker-ph {
|
||||
font-size: 28px;
|
||||
color: var(--text-secondary);
|
||||
font-size: 28rpx;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.form-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 32px;
|
||||
gap: 24rpx;
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
font-size: 28px;
|
||||
font-size: 28rpx;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 10px;
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
border: 2rpx solid var(--border-strong);
|
||||
border-radius: 12rpx;
|
||||
background: var(--bg-card);
|
||||
transition: background 160ms ease, border-color 160ms ease;
|
||||
}
|
||||
|
||||
.checkbox.checked {
|
||||
@@ -139,39 +272,17 @@
|
||||
|
||||
.form-actions {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.form-actions .btn-secondary,
|
||||
.form-actions .btn-primary {
|
||||
flex: 1;
|
||||
padding: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 空状态(主题适配) */
|
||||
.empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 120px 40px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.empty-icon-img {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.empty-sub {
|
||||
font-size: 26px;
|
||||
color: var(--text-secondary);
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
min-height: 96rpx;
|
||||
padding: 0;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import { useThemeContext } from '../../context/ThemeContext'
|
||||
import { useSafeArea } from '../../hooks/useSafeArea'
|
||||
import { useStatusBar } from '../../hooks/useStatusBar'
|
||||
import ThemedPageMeta from '../../components/ThemedPageMeta'
|
||||
import BottomActionBar from '../../components/BottomActionBar'
|
||||
import { assetUrl } from '../../utils/asset'
|
||||
|
||||
export default function AddressPage() {
|
||||
@@ -98,11 +99,13 @@ export default function AddressPage() {
|
||||
<ThemedPageMeta />
|
||||
<View className='address-page'>
|
||||
|
||||
<View className='page-header surface-card mt-20' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='flex-between' style={{ width: '100%' }}>
|
||||
<Text className='back-btn' onTap={() => Taro.navigateBack()}>←</Text>
|
||||
<Text className='page-title'>收货地址</Text>
|
||||
<View style={{ width: '60px' }} />
|
||||
<View className='page-header' style={{ paddingTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='page-header-inner'>
|
||||
<View className='back-btn' onTap={() => Taro.navigateBack()}>
|
||||
<Text className='back-arrow'>←</Text>
|
||||
</View>
|
||||
<Text className='nav-title'>收货地址</Text>
|
||||
<View className='nav-placeholder' />
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -142,11 +145,11 @@ export default function AddressPage() {
|
||||
<View className='safe-bottom-placeholder' />
|
||||
|
||||
{/* 底部添加按钮 */}
|
||||
<View className='action-bar'>
|
||||
<BottomActionBar>
|
||||
<View className='btn-primary' onTap={openAdd}>
|
||||
<Text>新增收货地址</Text>
|
||||
</View>
|
||||
</View>
|
||||
</BottomActionBar>
|
||||
|
||||
{/* 新增/编辑弹窗 */}
|
||||
{showForm && (
|
||||
|
||||
@@ -1,35 +1,52 @@
|
||||
.agreement-page {
|
||||
padding: 0 32px 32px;
|
||||
}
|
||||
/* ============================================================
|
||||
Agreement Page — 定制协议
|
||||
============================================================ */
|
||||
|
||||
.agreement-title {
|
||||
font-size: 40px;
|
||||
font-weight: 800;
|
||||
color: var(--text-primary);
|
||||
display: block;
|
||||
margin-bottom: 32px;
|
||||
.agreement-page {
|
||||
padding: 0 32rpx calc(24rpx + env(safe-area-inset-bottom));
|
||||
min-height: 100vh;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.agreement-content {
|
||||
padding: 40px 0;
|
||||
padding: 32rpx 0 48rpx;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.agreement-title {
|
||||
display: block;
|
||||
font-size: 44rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 32rpx;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.agreement-section {
|
||||
margin-bottom: 32px;
|
||||
display: block;
|
||||
margin-bottom: 24rpx;
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.agreement-section:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.agreement-h3 {
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
display: block;
|
||||
margin-bottom: 16px;
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1.3;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 16rpx;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.agreement-p {
|
||||
font-size: 28px;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.8;
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
line-height: 1.8;
|
||||
color: var(--text-secondary);
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ export default function AgreementPage() {
|
||||
<View className='agreement-content' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
|
||||
<Text className='agreement-title'>定制协议</Text>
|
||||
{SECTIONS.map((sec, idx) => (
|
||||
<View key={idx} className='agreement-section'>
|
||||
<View key={idx} className='agreement-section surface-card'>
|
||||
<Text className='agreement-h3'>{sec.title}</Text>
|
||||
<Text className='agreement-p'>{sec.content}</Text>
|
||||
</View>
|
||||
|
||||
@@ -1,27 +1,80 @@
|
||||
/* ============================================================
|
||||
Checkout Page — 确认下单
|
||||
============================================================ */
|
||||
.checkout-page {
|
||||
padding: 0 24px 24px;
|
||||
padding: 0 32rpx;
|
||||
padding-bottom: calc(48rpx + env(safe-area-inset-bottom));
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* --- Page Header --- */
|
||||
.page-header {
|
||||
margin-bottom: 24rpx;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.page-header-inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
min-height: 88rpx;
|
||||
}
|
||||
|
||||
.back-btn {
|
||||
font-size: 40px;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
flex: 0 0 auto;
|
||||
border-radius: 50%;
|
||||
background: var(--bg-card);
|
||||
border: 1rpx solid var(--border-strong);
|
||||
box-shadow: var(--shadow-card);
|
||||
}
|
||||
|
||||
/* 画布展示区 */
|
||||
.back-btn:active {
|
||||
transform: scale(0.96);
|
||||
}
|
||||
|
||||
.back-arrow {
|
||||
font-size: 36rpx;
|
||||
line-height: 1;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.nav-title {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 34rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.nav-placeholder {
|
||||
width: 88rpx;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
/* --- 设计预览 --- */
|
||||
.checkout-canvas {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 40px;
|
||||
margin-bottom: 24rpx;
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.canvas-area {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: rgba(0,0,0,0.03);
|
||||
border: 1rpx solid var(--border-strong);
|
||||
max-width: 100%;
|
||||
box-sizing: border-box;
|
||||
background: var(--bg-input);
|
||||
border: 1rpx solid var(--border-strong);
|
||||
}
|
||||
|
||||
.checkout-image {
|
||||
@@ -32,125 +85,153 @@
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
/* 商品信息 */
|
||||
.checkout-info {
|
||||
padding: 24px;
|
||||
/* --- 商品信息 --- */
|
||||
.checkout-info,
|
||||
.checkout-address-card {
|
||||
margin-bottom: 24rpx;
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
display: block;
|
||||
margin-bottom: 24rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 20px 0;
|
||||
gap: 24rpx;
|
||||
padding: 24rpx 0;
|
||||
border-bottom: 1rpx solid var(--border);
|
||||
}
|
||||
|
||||
.info-row:last-child {
|
||||
border-bottom: none;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-size: 28px;
|
||||
flex: 0 0 auto;
|
||||
font-size: 28rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 28px;
|
||||
color: var(--text-primary);
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
color: var(--text-primary);
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.total-row {
|
||||
padding-top: 24px;
|
||||
margin-top: 8px;
|
||||
padding-top: 24rpx;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
|
||||
.info-total {
|
||||
font-size: 40px;
|
||||
font-size: 40rpx;
|
||||
font-weight: 800;
|
||||
color: var(--accent-primary);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
/* 地址卡片 */
|
||||
.checkout-address-card {
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
/* --- 收货地址 --- */
|
||||
.checkout-address-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 16px;
|
||||
gap: 24rpx;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.checkout-address-header .card-title {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.address-change {
|
||||
padding: 6px 16px;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 56rpx;
|
||||
padding: 0 24rpx;
|
||||
border-radius: 999rpx;
|
||||
background: var(--accent-secondary-soft);
|
||||
}
|
||||
|
||||
.change-text {
|
||||
font-size: 24px;
|
||||
font-size: 24rpx;
|
||||
font-weight: 500;
|
||||
color: var(--accent-secondary);
|
||||
}
|
||||
|
||||
.checkout-address-body {
|
||||
padding-top: 8px;
|
||||
padding-top: 8rpx;
|
||||
}
|
||||
|
||||
.addr-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
margin-bottom: 8px;
|
||||
gap: 16rpx;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.addr-name {
|
||||
font-size: 28px;
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.addr-phone {
|
||||
font-size: 26px;
|
||||
font-size: 24rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.addr-detail {
|
||||
font-size: 26px;
|
||||
font-size: 26rpx;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.5;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.checkout-address-empty {
|
||||
padding: 32px 0;
|
||||
padding: 32rpx 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 26px;
|
||||
font-size: 28rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* 底部弹窗 — 地址选择(样式复用 app.scss 全局定义,移除非必要覆写) */
|
||||
|
||||
/* --- 地址选择弹层 --- */
|
||||
.addr-picker-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20px;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.addr-picker-title {
|
||||
font-size: 32px;
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.addr-picker-close {
|
||||
font-size: 28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
border-radius: 50%;
|
||||
background: var(--bg-muted);
|
||||
color: var(--text-secondary);
|
||||
padding: 8px;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.addr-picker-list {
|
||||
@@ -159,69 +240,90 @@
|
||||
}
|
||||
|
||||
.addr-picker-item {
|
||||
padding: 20px 16px;
|
||||
border-bottom: 1rpx solid var(--border);
|
||||
padding: 24rpx;
|
||||
border: 1rpx solid transparent;
|
||||
border-radius: 16rpx;
|
||||
transition: background 160ms ease, border-color 160ms ease;
|
||||
}
|
||||
|
||||
.addr-picker-item + .addr-picker-item {
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
|
||||
.addr-picker-item.active {
|
||||
background: var(--accent-secondary-soft);
|
||||
border-radius: 12px;
|
||||
background: var(--accent-primary-soft);
|
||||
border-color: var(--accent-primary);
|
||||
}
|
||||
|
||||
.addr-picker-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
margin-bottom: 8px;
|
||||
gap: 16rpx;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.addr-picker-name {
|
||||
font-size: 28px;
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.addr-picker-phone {
|
||||
font-size: 26px;
|
||||
font-size: 24rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.addr-picker-default {
|
||||
font-size: 22px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
height: 40rpx;
|
||||
padding: 0 16rpx;
|
||||
border-radius: 999rpx;
|
||||
font-size: 20rpx;
|
||||
font-weight: 600;
|
||||
color: var(--accent-primary);
|
||||
border: 1px solid var(--accent-primary);
|
||||
padding: 2px 8px;
|
||||
border-radius: 6px;
|
||||
background: var(--accent-primary-soft);
|
||||
}
|
||||
|
||||
.addr-picker-detail {
|
||||
font-size: 26px;
|
||||
font-size: 26rpx;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.addr-picker-empty {
|
||||
padding: 40px;
|
||||
padding: 48rpx 32rpx;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
color: var(--text-secondary);
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.addr-picker-add {
|
||||
margin-top: 16px;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 96rpx;
|
||||
margin-top: 24rpx;
|
||||
border: 1rpx solid var(--border-strong);
|
||||
border-radius: 12px;
|
||||
border-radius: 999rpx;
|
||||
background: var(--bg-card);
|
||||
}
|
||||
|
||||
.addr-picker-add-text {
|
||||
font-size: 28px;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: var(--accent-secondary);
|
||||
}
|
||||
|
||||
/* 底部操作 — 毛玻璃规则由全局 .action-bar 提供 */
|
||||
.action-bar .btn-secondary,
|
||||
.action-bar .btn-primary {
|
||||
/* --- 底部操作栏 --- */
|
||||
.bottom-action-bar .btn-secondary,
|
||||
.bottom-action-bar .btn-primary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
min-height: 96rpx;
|
||||
padding: 0;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { useThemeContext } from '../../context/ThemeContext'
|
||||
import { useSafeArea } from '../../hooks/useSafeArea'
|
||||
import { useStatusBar } from '../../hooks/useStatusBar'
|
||||
import ThemedPageMeta from '../../components/ThemedPageMeta'
|
||||
import BottomActionBar from '../../components/BottomActionBar'
|
||||
|
||||
export default function CheckoutPage() {
|
||||
const { theme, resolvedTheme } = useThemeContext()
|
||||
@@ -67,8 +68,14 @@ export default function CheckoutPage() {
|
||||
<View className={`theme-${resolvedTheme}`}>
|
||||
<ThemedPageMeta />
|
||||
<View className='checkout-page'>
|
||||
<View className='page-header surface-card mt-20' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
|
||||
<Text className='page-title'>设计不存在</Text>
|
||||
<View className='page-header' style={{ paddingTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='page-header-inner'>
|
||||
<View className='back-btn' onTap={() => Taro.navigateBack()}>
|
||||
<Text className='back-arrow'>←</Text>
|
||||
</View>
|
||||
<Text className='nav-title'>设计不存在</Text>
|
||||
<View className='nav-placeholder' />
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
@@ -85,20 +92,22 @@ export default function CheckoutPage() {
|
||||
}
|
||||
|
||||
return (
|
||||
<View className={`theme-${resolvedTheme}`}>
|
||||
<ThemedPageMeta />
|
||||
<View className='checkout-page'>
|
||||
<View className={`theme-${resolvedTheme}`}>
|
||||
<ThemedPageMeta />
|
||||
<View className='checkout-page'>
|
||||
|
||||
<View className='page-header surface-card mt-20' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='flex-between' style={{ width: '100%' }}>
|
||||
<Text className='back-btn' onTap={() => Taro.navigateBack()}>←</Text>
|
||||
<Text className='page-title'>设计效果确认</Text>
|
||||
<View style={{ width: '60px' }} />
|
||||
<View className='page-header' style={{ paddingTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='page-header-inner'>
|
||||
<View className='back-btn' onTap={() => Taro.navigateBack()}>
|
||||
<Text className='back-arrow'>←</Text>
|
||||
</View>
|
||||
<Text className='nav-title'>设计效果确认</Text>
|
||||
<View className='nav-placeholder' />
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 效果展示区 */}
|
||||
<View className='checkout-canvas surface-card mt-20'>
|
||||
<View className='checkout-canvas surface-card'>
|
||||
<View className='canvas-area' style={maskStyle}>
|
||||
{hasStickers ? (
|
||||
design.designData.stickers.map((s: any) => (
|
||||
@@ -128,7 +137,8 @@ export default function CheckoutPage() {
|
||||
</View>
|
||||
|
||||
{/* 商品信息 */}
|
||||
<View className='checkout-info surface-card mt-20'>
|
||||
<View className='checkout-info surface-card'>
|
||||
<Text className='card-title'>确认商品</Text>
|
||||
<View className='info-row'>
|
||||
<Text className='info-label'>商品</Text>
|
||||
<Text className='info-value'>{design.productName}</Text>
|
||||
@@ -148,9 +158,9 @@ export default function CheckoutPage() {
|
||||
</View>
|
||||
|
||||
{/* 收货地址 */}
|
||||
<View className='checkout-address-card surface-card mt-20'>
|
||||
<View className='checkout-address-card surface-card'>
|
||||
<View className='checkout-address-header'>
|
||||
<Text className='info-label'>收货地址</Text>
|
||||
<Text className='card-title'>收货地址</Text>
|
||||
<View className='address-change' onTap={() => setShowAddrPicker(true)}>
|
||||
<Text className='change-text'>更改收货地址</Text>
|
||||
</View>
|
||||
@@ -173,14 +183,14 @@ export default function CheckoutPage() {
|
||||
</View>
|
||||
|
||||
{/* 底部操作 */}
|
||||
<View className='action-bar'>
|
||||
<BottomActionBar>
|
||||
<View className='btn-secondary' onTap={() => Taro.navigateBack()}>
|
||||
<Text>返回修改</Text>
|
||||
</View>
|
||||
<View className='btn-primary' onTap={handleConfirm}>
|
||||
<Text>确认下单</Text>
|
||||
</View>
|
||||
</View>
|
||||
</BottomActionBar>
|
||||
|
||||
<View className='safe-bottom-placeholder' />
|
||||
|
||||
|
||||
@@ -1,76 +1,95 @@
|
||||
.design-page {
|
||||
padding: 0 24px 24px;
|
||||
padding: 0 32rpx 24rpx;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.manage-btn {
|
||||
font-size: 28px;
|
||||
color: var(--accent-secondary);
|
||||
font-weight: 500;
|
||||
.page-header.design-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 88rpx;
|
||||
padding-bottom: 16rpx;
|
||||
}
|
||||
|
||||
/* 状态 Tab */
|
||||
.header-spacer {
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.header-manage {
|
||||
width: 88rpx;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
color: var(--accent-secondary);
|
||||
}
|
||||
|
||||
/* 状态筛选 chip-row */
|
||||
.status-tabs {
|
||||
margin: 20px 0;
|
||||
background: var(--bg-card);
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 16px;
|
||||
padding: 8px 0;
|
||||
margin: 8rpx 0 24rpx;
|
||||
}
|
||||
|
||||
.tabs-scroll {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.tab-item {
|
||||
display: inline-block;
|
||||
padding: 20px 32px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tab-label {
|
||||
font-size: 28px;
|
||||
.chip {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 64rpx;
|
||||
padding: 0 32rpx;
|
||||
margin-right: 16rpx;
|
||||
border-radius: 999rpx;
|
||||
background: var(--bg-card);
|
||||
border: 1rpx solid var(--border);
|
||||
color: var(--text-secondary);
|
||||
font-size: 26rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.tab-item.active .tab-label {
|
||||
color: var(--accent-primary);
|
||||
font-weight: 700;
|
||||
.chip.active {
|
||||
background: var(--accent-primary);
|
||||
border-color: var(--accent-primary);
|
||||
color: var(--bg-page);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.tab-underline {
|
||||
position: absolute;
|
||||
bottom: 8px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 40px;
|
||||
height: 4px;
|
||||
background: var(--accent-primary);
|
||||
border-radius: 2px;
|
||||
.chip .tab-label {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
/* 批量管理工具栏 */
|
||||
.batch-bar {
|
||||
padding: 20px 24px;
|
||||
margin-bottom: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 24rpx;
|
||||
padding: 24rpx;
|
||||
background: var(--bg-card);
|
||||
border-radius: 24rpx;
|
||||
box-shadow: var(--shadow-card);
|
||||
}
|
||||
|
||||
.batch-select-all {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.batch-checkbox {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
border-radius: 50%;
|
||||
border: 2rpx solid var(--border-strong);
|
||||
flex-shrink: 0;
|
||||
transition: all 0.2s;
|
||||
transition: background 160ms ease, border-color 160ms ease;
|
||||
}
|
||||
|
||||
.batch-checkbox.checked {
|
||||
@@ -79,14 +98,15 @@
|
||||
}
|
||||
|
||||
.batch-text {
|
||||
font-size: 26px;
|
||||
margin-left: 16rpx;
|
||||
font-size: 26rpx;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.batch-delete {
|
||||
font-size: 26px;
|
||||
font-size: 26rpx;
|
||||
color: var(--text-secondary);
|
||||
padding: 10px 24px;
|
||||
padding: 12rpx 24rpx;
|
||||
}
|
||||
|
||||
.batch-delete.active {
|
||||
@@ -94,15 +114,19 @@
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 设计卡片列表 */
|
||||
/* 设计清单 detail-card */
|
||||
.design-list {
|
||||
padding-bottom: 24px;
|
||||
padding-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.design-card {
|
||||
margin-bottom: 20px;
|
||||
padding: 28px;
|
||||
transition: all 0.2s ease;
|
||||
margin-bottom: 24rpx;
|
||||
padding: 24rpx;
|
||||
background: var(--bg-card);
|
||||
border: 1rpx solid transparent;
|
||||
border-radius: 24rpx;
|
||||
box-shadow: var(--shadow-card);
|
||||
transition: background 160ms ease, border-color 160ms ease;
|
||||
}
|
||||
|
||||
.design-card.selected {
|
||||
@@ -112,48 +136,65 @@
|
||||
|
||||
.design-body {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.design-icon {
|
||||
font-size: 56px;
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.design-icon-img {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
flex-shrink: 0;
|
||||
border-radius: 12rpx;
|
||||
background: var(--bg-input);
|
||||
}
|
||||
|
||||
.design-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.design-title-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 12px;
|
||||
gap: 16rpx;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.design-name {
|
||||
font-size: 32px;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.design-card .badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 40rpx;
|
||||
padding: 0 16rpx;
|
||||
border-radius: 999rpx;
|
||||
font-size: 22rpx;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.design-meta {
|
||||
font-size: 24px;
|
||||
color: var(--text-secondary);
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
font-size: 24rpx;
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.design-total {
|
||||
font-size: 26px;
|
||||
display: block;
|
||||
font-size: 24rpx;
|
||||
font-weight: 600;
|
||||
color: var(--accent-primary);
|
||||
}
|
||||
@@ -161,11 +202,18 @@
|
||||
.design-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
|
||||
.design-btn {
|
||||
padding: 16px 40px;
|
||||
font-size: 26px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 64rpx;
|
||||
padding: 0 32rpx;
|
||||
font-size: 26rpx;
|
||||
font-weight: 600;
|
||||
border-radius: 999rpx;
|
||||
}
|
||||
|
||||
/* 空状态 */
|
||||
@@ -173,25 +221,37 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 100px 40px;
|
||||
padding: 100rpx 40rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.empty-icon-img {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
margin-bottom: 24px;
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 32px;
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 12px;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.empty-sub {
|
||||
font-size: 26px;
|
||||
font-size: 28rpx;
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 32px;
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.empty-state .btn-primary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 320rpx;
|
||||
height: 88rpx;
|
||||
padding: 0 48rpx;
|
||||
border-radius: 999rpx;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ const STATUS_TABS = [
|
||||
{ code: 'ordered', label: '已下单' }
|
||||
]
|
||||
|
||||
const VISIBLE_STATUS_TABS = STATUS_TABS.filter(tab => tab.code !== 'undesigned')
|
||||
|
||||
const STATUS_STYLE: Record<string, { label: string; cls: string }> = {
|
||||
undesigned: { label: '未设计', cls: 'badge-pink' },
|
||||
designing: { label: '设计中', cls: 'badge-blue' },
|
||||
@@ -120,27 +122,24 @@ export default function DesignListPage() {
|
||||
<ThemedPageMeta />
|
||||
<LoginGuard>
|
||||
<View className='design-page'>
|
||||
<View className='page-header surface-card mt-20' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='flex-between' style={{ width: '100%' }}>
|
||||
<Text className='back-btn' onTap={() => Taro.navigateBack()}>←</Text>
|
||||
<Text className='page-title'>我的设计清单</Text>
|
||||
<Text className='manage-btn' onTap={handleManage}>
|
||||
{managing ? '完成' : '管理'}
|
||||
</Text>
|
||||
<View className='page-header design-header' style={{ paddingTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='header-spacer' />
|
||||
<Text className='header-title'>我的设计清单</Text>
|
||||
<View className='header-manage' onTap={handleManage}>
|
||||
<Text>{managing ? '完成' : '管理'}</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 状态筛选 */}
|
||||
<View className='status-tabs'>
|
||||
<ScrollView className='tabs-scroll' scrollX>
|
||||
{STATUS_TABS.map(tab => (
|
||||
{VISIBLE_STATUS_TABS.map(tab => (
|
||||
<View
|
||||
key={tab.code}
|
||||
className={`tab-item ${activeTab === tab.code ? 'active' : ''}`}
|
||||
className={`chip ${activeTab === tab.code ? 'active' : ''}`}
|
||||
onTap={() => setActiveTab(tab.code)}
|
||||
>
|
||||
<Text className='tab-label'>{tab.label}</Text>
|
||||
{activeTab === tab.code && <View className='tab-underline' />}
|
||||
</View>
|
||||
))}
|
||||
</ScrollView>
|
||||
@@ -148,7 +147,7 @@ export default function DesignListPage() {
|
||||
|
||||
{/* 批量管理工具栏 */}
|
||||
{managing && (
|
||||
<View className='batch-bar surface-card'>
|
||||
<View className='batch-bar'>
|
||||
<View className='flex-between' style={{ width: '100%' }}>
|
||||
<View className='batch-select-all' onTap={toggleSelectAll}>
|
||||
<View className={`batch-checkbox ${selected.size === filtered.length && filtered.length > 0 ? 'checked' : ''}`} />
|
||||
@@ -173,7 +172,7 @@ export default function DesignListPage() {
|
||||
return (
|
||||
<View
|
||||
key={item.id}
|
||||
className={`design-card surface-card ${isSelected ? 'selected' : ''}`}
|
||||
className={`design-card ${isSelected ? 'selected' : ''}`}
|
||||
onTap={() => managing ? toggleSelect(item.id) : undefined}
|
||||
>
|
||||
<View className='design-body'>
|
||||
@@ -220,7 +219,6 @@ export default function DesignListPage() {
|
||||
)}
|
||||
</ScrollView>
|
||||
|
||||
<View style={{ height: '40px' }} />
|
||||
</View>
|
||||
</LoginGuard>
|
||||
</View>
|
||||
|
||||
@@ -1,24 +1,91 @@
|
||||
.diy-page {
|
||||
padding: 0 24px 24px;
|
||||
padding: 0 32rpx calc(48rpx + env(safe-area-inset-bottom));
|
||||
min-height: 100vh;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 顶部标题区 */
|
||||
.diy-page .page-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0 0 24rpx;
|
||||
padding-top: 0;
|
||||
padding-bottom: 16rpx;
|
||||
background: transparent;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.diy-page .page-header.surface-card {
|
||||
background: transparent;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.diy-page .page-header .flex-between {
|
||||
min-height: 88rpx;
|
||||
}
|
||||
|
||||
.back-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
flex-shrink: 0;
|
||||
border-radius: 50%;
|
||||
background: var(--bg-card);
|
||||
border: 1rpx solid var(--border-strong);
|
||||
box-shadow: var(--shadow-card);
|
||||
font-size: 36rpx;
|
||||
line-height: 1;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.back-btn:active {
|
||||
transform: scale(0.96);
|
||||
}
|
||||
|
||||
.diy-page .page-title {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
padding: 0 16rpx;
|
||||
text-align: center;
|
||||
font-size: 34rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
letter-spacing: 0;
|
||||
line-height: 1.2;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.header-spacer {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* 画布区域 */
|
||||
.canvas-wrapper {
|
||||
padding: 40px;
|
||||
padding: 24rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 24rpx;
|
||||
}
|
||||
|
||||
.canvas-area {
|
||||
position: relative;
|
||||
background: var(--bg-input);
|
||||
overflow: hidden;
|
||||
border-radius: 16px;
|
||||
min-width: 200px;
|
||||
min-height: 200px;
|
||||
border-radius: 24rpx;
|
||||
min-width: 300rpx;
|
||||
min-height: 400rpx;
|
||||
max-width: 100%;
|
||||
box-sizing: border-box;
|
||||
box-shadow: inset 0 0 0 1rpx var(--border-strong);
|
||||
}
|
||||
|
||||
.mask-border {
|
||||
@@ -37,46 +104,59 @@
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
z-index: 5;
|
||||
border: 2px solid transparent;
|
||||
border: 2rpx solid transparent;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.canvas-image.active {
|
||||
border-color: var(--accent-primary);
|
||||
box-shadow: 0 0 0 8rpx var(--accent-primary-soft);
|
||||
}
|
||||
|
||||
.canvas-image.overlap {
|
||||
border-color: var(--danger);
|
||||
box-shadow: 0 0 12px var(--danger-soft);
|
||||
box-shadow: 0 0 0 8rpx var(--danger-soft);
|
||||
}
|
||||
|
||||
/* 贴纸面板 */
|
||||
.sticker-panel {
|
||||
padding: 28px;
|
||||
padding: 24rpx;
|
||||
}
|
||||
|
||||
.sticker-panel .section-title {
|
||||
display: block;
|
||||
margin-bottom: 20rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.sticker-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.sticker-thumb {
|
||||
position: relative;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
width: 164rpx;
|
||||
height: 164rpx;
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 12px;
|
||||
border-radius: 20rpx;
|
||||
overflow: hidden;
|
||||
background: var(--bg-input);
|
||||
box-shadow: var(--shadow-card);
|
||||
}
|
||||
|
||||
.sticker-thumb.active {
|
||||
border-color: var(--accent-primary);
|
||||
border-width: 2rpx;
|
||||
box-shadow: 0 0 0 6rpx var(--accent-primary-soft);
|
||||
}
|
||||
|
||||
.sticker-thumb.overlap {
|
||||
border-color: var(--danger);
|
||||
box-shadow: 0 0 0 6rpx var(--danger-soft);
|
||||
}
|
||||
|
||||
.sticker-thumb-img {
|
||||
@@ -86,52 +166,59 @@
|
||||
|
||||
.sticker-del {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 4px;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
top: 8rpx;
|
||||
right: 8rpx;
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
background: var(--danger);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 10;
|
||||
box-shadow: var(--shadow-card);
|
||||
}
|
||||
|
||||
.del-icon {
|
||||
color: #fff;
|
||||
font-size: 24px;
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.sticker-add-btn {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 12px;
|
||||
width: 164rpx;
|
||||
height: 164rpx;
|
||||
border: 1rpx solid var(--border-strong);
|
||||
border-radius: 20rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--bg-input);
|
||||
background: var(--bg-muted);
|
||||
}
|
||||
|
||||
.sticker-add-btn:active {
|
||||
transform: scale(0.97);
|
||||
}
|
||||
|
||||
.add-icon {
|
||||
font-size: 48px;
|
||||
font-size: 44rpx;
|
||||
color: var(--accent-primary);
|
||||
line-height: 1;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.add-label {
|
||||
font-size: 22px;
|
||||
font-size: 22rpx;
|
||||
color: var(--text-secondary);
|
||||
margin-top: 8px;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
|
||||
.overlap-hint {
|
||||
display: block;
|
||||
margin-top: 16px;
|
||||
font-size: 26px;
|
||||
margin-top: 16rpx;
|
||||
font-size: 24rpx;
|
||||
color: var(--danger);
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
@@ -139,153 +226,78 @@
|
||||
|
||||
/* 工具栏 */
|
||||
.toolbar {
|
||||
padding: 28px 32px;
|
||||
padding: 24rpx;
|
||||
}
|
||||
|
||||
.tool-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20px;
|
||||
gap: 16rpx;
|
||||
padding: 8rpx 0;
|
||||
}
|
||||
|
||||
.tool-row:last-child {
|
||||
margin-bottom: 0;
|
||||
.tool-row + .tool-row {
|
||||
border-top: 1rpx solid var(--border);
|
||||
margin-top: 8rpx;
|
||||
padding-top: 16rpx;
|
||||
}
|
||||
|
||||
.tool-label {
|
||||
font-size: 28px;
|
||||
font-size: 26rpx;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.tool-btn {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
background: var(--bg-input);
|
||||
border: 1rpx solid var(--border-strong);
|
||||
border-radius: 50%;
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 16rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 32px;
|
||||
font-size: 32rpx;
|
||||
color: var(--text-primary);
|
||||
font-weight: 700;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.tool-btn:active {
|
||||
transform: scale(0.96);
|
||||
background: var(--bg-muted);
|
||||
}
|
||||
|
||||
.tool-value {
|
||||
font-size: 28px;
|
||||
font-size: 26rpx;
|
||||
font-weight: 600;
|
||||
color: var(--accent-primary);
|
||||
min-width: 80px;
|
||||
min-width: 88rpx;
|
||||
text-align: center;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.tool-hint {
|
||||
font-size: 24px;
|
||||
font-size: 24rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* 预览弹窗 */
|
||||
.preview-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
padding: 40px;
|
||||
}
|
||||
|
||||
.preview-card {
|
||||
background: var(--bg-card);
|
||||
width: 100%;
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
padding: 40px;
|
||||
}
|
||||
|
||||
.preview-title {
|
||||
font-size: 36px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
display: block;
|
||||
margin-bottom: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.preview-canvas {
|
||||
background: var(--bg-input);
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
margin: 0 auto 24px;
|
||||
border: 1rpx solid var(--border-strong);
|
||||
position: relative;
|
||||
min-width: 200px;
|
||||
min-height: 200px;
|
||||
max-width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.preview-image {
|
||||
position: absolute;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.preview-image.overlap {
|
||||
border: 2px solid var(--danger);
|
||||
}
|
||||
|
||||
.product-info {
|
||||
text-align: center;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.product-name {
|
||||
font-size: 30px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.product-size {
|
||||
font-size: 24px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.preview-actions {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.preview-actions .btn-secondary,
|
||||
.preview-actions .btn-primary {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.preview-actions .btn-primary.disabled {
|
||||
opacity: 0.5;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* 常驻编辑按钮 */
|
||||
.edit-btn-bar {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
|
||||
.edit-btn {
|
||||
padding: 16px 48px;
|
||||
border-radius: 50px;
|
||||
font-size: 28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 176rpx;
|
||||
height: 88rpx;
|
||||
padding: 0 40rpx;
|
||||
border-radius: 999rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
background: var(--bg-input);
|
||||
@@ -301,19 +313,132 @@
|
||||
}
|
||||
|
||||
.edit-btn.disabled {
|
||||
opacity: 0.45;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* 底部操作栏 — 毛玻璃由 BottomActionBar 提供 */
|
||||
.bottom-action-bar .btn-primary,
|
||||
.bottom-action-bar .btn-secondary {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 28rpx 0;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
/* 预览弹层 */
|
||||
.preview-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.preview-card {
|
||||
width: 100%;
|
||||
max-height: 88vh;
|
||||
overflow-y: auto;
|
||||
padding: 40rpx 32rpx calc(32rpx + env(safe-area-inset-bottom));
|
||||
background: var(--bg-card);
|
||||
border-radius: 32rpx 32rpx 0 0;
|
||||
border: 1rpx solid var(--border);
|
||||
box-shadow: var(--shadow-elevated);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.preview-card::before {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 64rpx;
|
||||
height: 8rpx;
|
||||
margin: 0 auto 32rpx;
|
||||
border-radius: 999rpx;
|
||||
background: var(--bg-muted);
|
||||
}
|
||||
|
||||
.preview-title {
|
||||
font-size: 34rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
display: block;
|
||||
margin-bottom: 24rpx;
|
||||
text-align: center;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.preview-canvas {
|
||||
background: var(--bg-input);
|
||||
border-radius: 24rpx;
|
||||
overflow: hidden;
|
||||
margin: 0 auto 24rpx;
|
||||
border: 1rpx solid var(--border-strong);
|
||||
position: relative;
|
||||
min-width: 300rpx;
|
||||
min-height: 400rpx;
|
||||
max-width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.preview-image {
|
||||
position: absolute;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.preview-image.overlap {
|
||||
border: 2rpx solid var(--danger);
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.product-info {
|
||||
text-align: center;
|
||||
margin-bottom: 28rpx;
|
||||
}
|
||||
|
||||
.product-name {
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
display: block;
|
||||
margin-bottom: 8rpx;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.product-size {
|
||||
font-size: 24rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.preview-actions {
|
||||
display: flex;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.preview-actions .btn-secondary,
|
||||
.preview-actions .btn-primary {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 28rpx 0;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.preview-actions .btn-primary.disabled {
|
||||
opacity: 0.5;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* 底部操作栏 — 毛玻璃规则由全局 .action-bar 提供 */
|
||||
.action-bar .btn-primary,
|
||||
.action-bar .btn-secondary {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 24px 0;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
/* 局部间距 */
|
||||
.mt-20 {
|
||||
margin-top: 20px;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import { useThemeContext } from '../../context/ThemeContext'
|
||||
import { useSafeArea } from '../../hooks/useSafeArea'
|
||||
import { useStatusBar } from '../../hooks/useStatusBar'
|
||||
import ThemedPageMeta from '../../components/ThemedPageMeta'
|
||||
import BottomActionBar from '../../components/BottomActionBar'
|
||||
|
||||
export default function DIYPage() {
|
||||
const { theme, resolvedTheme } = useThemeContext()
|
||||
@@ -275,11 +276,11 @@ export default function DIYPage() {
|
||||
<ThemedPageMeta />
|
||||
<View className='diy-page'>
|
||||
|
||||
<View className='page-header surface-card mt-20' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='page-header surface-card mt-20' style={{ paddingTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='flex-between' style={{ width: '100%' }}>
|
||||
<Text className='back-btn' onTap={goBack}>←</Text>
|
||||
<Text className='page-title'>设计工作台</Text>
|
||||
<View style={{ width: '60px' }} />
|
||||
<View className='header-spacer' />
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -358,14 +359,14 @@ export default function DIYPage() {
|
||||
</View>
|
||||
|
||||
{/* 底部操作按钮 */}
|
||||
<View className='action-bar'>
|
||||
<BottomActionBar>
|
||||
<View className='btn-primary' onTap={() => setPreviewMode(true)}>
|
||||
<Text>预览效果</Text>
|
||||
</View>
|
||||
<View className='btn-secondary' onTap={addSticker}>
|
||||
<Text>添加贴纸</Text>
|
||||
</View>
|
||||
</View>
|
||||
</BottomActionBar>
|
||||
|
||||
{/* 预览弹层 */}
|
||||
{previewMode && (
|
||||
|
||||
@@ -1,37 +1,65 @@
|
||||
.sticker-edit-page {
|
||||
padding: 0 24px 24px;
|
||||
padding: 0 32rpx calc(48rpx + env(safe-area-inset-bottom));
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 顶部导航 */
|
||||
.edit-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: calc(env(safe-area-inset-top, 0px) + 24px) 0 24px;
|
||||
gap: 16rpx;
|
||||
padding-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.edit-back {
|
||||
font-size: 36px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
flex-shrink: 0;
|
||||
border-radius: 50%;
|
||||
background: var(--bg-card);
|
||||
border: 1rpx solid var(--border-strong);
|
||||
box-shadow: var(--shadow-card);
|
||||
font-size: 36rpx;
|
||||
line-height: 1;
|
||||
color: var(--text-primary);
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.edit-back:active {
|
||||
transform: scale(0.96);
|
||||
}
|
||||
|
||||
.edit-title {
|
||||
font-size: 34px;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
text-align: center;
|
||||
font-size: 34rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
text-align: center;
|
||||
flex: 1;
|
||||
letter-spacing: 0;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.edit-save {
|
||||
font-size: 28px;
|
||||
color: var(--accent-primary);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
min-width: 80rpx;
|
||||
font-size: 26rpx;
|
||||
font-weight: 600;
|
||||
width: 60px;
|
||||
text-align: right;
|
||||
color: var(--accent-primary);
|
||||
}
|
||||
|
||||
.edit-save:active {
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
/* 画布区域 */
|
||||
@@ -40,27 +68,30 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px 0;
|
||||
min-height: 400px;
|
||||
padding: 8rpx 0 24rpx;
|
||||
min-height: 480rpx;
|
||||
}
|
||||
|
||||
.edit-canvas {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
height: 480rpx;
|
||||
background: var(--bg-input);
|
||||
border-radius: 16px;
|
||||
border-radius: 24rpx;
|
||||
border: 1rpx solid var(--border-strong);
|
||||
box-shadow: var(--shadow-card);
|
||||
}
|
||||
|
||||
/* 工具面板 */
|
||||
.edit-tools {
|
||||
padding: 32px;
|
||||
padding: 24rpx;
|
||||
}
|
||||
|
||||
.edit-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 32px;
|
||||
gap: 24rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.edit-row:last-child {
|
||||
@@ -68,76 +99,36 @@
|
||||
}
|
||||
|
||||
.edit-label {
|
||||
font-size: 28px;
|
||||
font-weight: 500;
|
||||
font-size: 26rpx;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
width: 120px;
|
||||
width: 96rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.slider-wrap {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.slider-track {
|
||||
flex: 1;
|
||||
height: 8px;
|
||||
border-radius: 4px;
|
||||
background: var(--bg-input);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.slider-fill {
|
||||
height: 100%;
|
||||
border-radius: 4px;
|
||||
background: linear-gradient(90deg, var(--accent-primary), var(--accent-primary-soft));
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.slider-thumb {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
background: #fff;
|
||||
border: 4px solid var(--accent-primary);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
||||
}
|
||||
|
||||
.slider-value {
|
||||
font-size: 24px;
|
||||
color: var(--text-secondary);
|
||||
min-width: 60px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* 快速操作按钮 */
|
||||
.edit-quick-actions {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
gap: 16rpx;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.quick-btn {
|
||||
padding: 16px 28px;
|
||||
border-radius: 40px;
|
||||
font-size: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 64rpx;
|
||||
padding: 0 28rpx;
|
||||
border-radius: 999rpx;
|
||||
font-size: 24rpx;
|
||||
font-weight: 500;
|
||||
background: var(--bg-input);
|
||||
color: var(--text-primary);
|
||||
border: 1rpx solid var(--border);
|
||||
transition: all 0.2s;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.quick-btn:active {
|
||||
opacity: 0.8;
|
||||
opacity: 0.85;
|
||||
transform: scale(0.97);
|
||||
}
|
||||
|
||||
@@ -147,13 +138,67 @@
|
||||
color: var(--accent-primary);
|
||||
}
|
||||
|
||||
/* 底部操作栏 — 毛玻璃规则由全局 .action-bar 提供 */
|
||||
/* 滑块 */
|
||||
.slider-wrap {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12rpx;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.slider-track {
|
||||
flex: 1;
|
||||
height: 8rpx;
|
||||
border-radius: 999rpx;
|
||||
background: var(--bg-input);
|
||||
border: 1rpx solid var(--border);
|
||||
position: relative;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.slider-fill {
|
||||
height: 100%;
|
||||
border-radius: 999rpx;
|
||||
background: linear-gradient(90deg, var(--accent-primary), var(--accent-primary-soft));
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.slider-thumb {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
border-radius: 50%;
|
||||
background: var(--bg-card);
|
||||
border: 4rpx solid var(--accent-primary);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
box-shadow: var(--shadow-card);
|
||||
}
|
||||
|
||||
.slider-thumb.dragging {
|
||||
transform: translate(-50%, -50%) scale(1.12);
|
||||
}
|
||||
|
||||
.slider-value {
|
||||
font-size: 22rpx;
|
||||
color: var(--text-secondary);
|
||||
min-width: 80rpx;
|
||||
text-align: right;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
/* 底部操作栏 — 毛玻璃由 BottomActionBar 提供 */
|
||||
.edit-footer .btn-primary,
|
||||
.edit-footer .btn-secondary {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 24px 0;
|
||||
font-size: 28px;
|
||||
padding: 28rpx 0;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
/* 加载遮罩 */
|
||||
@@ -163,7 +208,7 @@
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0,0,0,0.4);
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -172,7 +217,12 @@
|
||||
}
|
||||
|
||||
.edit-loading-text {
|
||||
font-size: 28px;
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
margin-top: 20px;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
/* 局部间距 */
|
||||
.mt-20 {
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import { useThemeContext } from '../../../context/ThemeContext'
|
||||
import { useSafeArea } from '../../../hooks/useSafeArea'
|
||||
import { useStatusBar } from '../../../hooks/useStatusBar'
|
||||
import ThemedPageMeta from '../../../components/ThemedPageMeta'
|
||||
import BottomActionBar from '../../../components/BottomActionBar'
|
||||
|
||||
/* ============================================================
|
||||
使用 Canvas 实现贴纸编辑(亮度/色相/线稿)
|
||||
@@ -324,7 +325,7 @@ export default function StickerEditPage() {
|
||||
id='editCanvas'
|
||||
type='2d'
|
||||
className='edit-canvas'
|
||||
style={{ width: '100%', height: '400px' }}
|
||||
style={{ width: '100%', height: '480rpx' }}
|
||||
/>
|
||||
</View>
|
||||
|
||||
@@ -415,14 +416,14 @@ export default function StickerEditPage() {
|
||||
|
||||
<View style={{ flex: 1 }} />
|
||||
|
||||
<View className='action-bar edit-footer'>
|
||||
<BottomActionBar className='edit-footer'>
|
||||
<View className='btn-secondary' onTap={() => Taro.navigateBack()}>
|
||||
<Text>取消</Text>
|
||||
</View>
|
||||
<View className='btn-primary' onTap={handleSave}>
|
||||
<Text>保存</Text>
|
||||
</View>
|
||||
</View>
|
||||
</BottomActionBar>
|
||||
|
||||
<View className='safe-bottom-placeholder' />
|
||||
|
||||
|
||||
@@ -1,49 +1,52 @@
|
||||
.index-page {
|
||||
padding: 0 24px 24px;
|
||||
padding: 0 32rpx 24rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 顶部标题栏 */
|
||||
.header-bar {
|
||||
padding: 20px 0 16px;
|
||||
/* 页头 */
|
||||
.home-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-items: flex-end;
|
||||
padding-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 48px;
|
||||
.home-title {
|
||||
font-size: 56rpx;
|
||||
font-weight: 800;
|
||||
color: var(--text-primary);
|
||||
letter-spacing: 4px;
|
||||
letter-spacing: 0;
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
/* 搜索框卡片 */
|
||||
.search-card {
|
||||
padding: 20px 24px;
|
||||
}
|
||||
|
||||
.search-inner {
|
||||
/* 搜索框 */
|
||||
.searchbox {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 88rpx;
|
||||
padding: 0 24rpx;
|
||||
border-radius: 999rpx;
|
||||
background: var(--bg-input);
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 40px;
|
||||
padding: 16px 24px;
|
||||
border: 1rpx solid transparent;
|
||||
transition: border-color 160ms ease, box-shadow 160ms ease, background 160ms ease;
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
font-size: 28px;
|
||||
margin-right: 16px;
|
||||
.searchbox:focus-within {
|
||||
border-color: var(--accent-primary);
|
||||
box-shadow: 0 0 0 6rpx var(--accent-primary-soft);
|
||||
background: var(--bg-card);
|
||||
}
|
||||
|
||||
.search-icon-img {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
margin-right: 16px;
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
margin-right: 12rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
flex: 1;
|
||||
font-size: 28px;
|
||||
height: 88rpx;
|
||||
font-size: 28rpx;
|
||||
color: var(--text-primary);
|
||||
background: transparent;
|
||||
border: none;
|
||||
@@ -51,163 +54,173 @@
|
||||
}
|
||||
|
||||
.search-input::placeholder {
|
||||
color: var(--text-secondary);
|
||||
font-size: 26px;
|
||||
color: var(--text-muted);
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.search-result-hint {
|
||||
margin-top: 16px;
|
||||
padding-top: 16px;
|
||||
border-top: 1rpx solid var(--border);
|
||||
margin: 16rpx 8rpx 0;
|
||||
font-size: 24rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.hint-text {
|
||||
font-size: 24px;
|
||||
color: var(--text-secondary);
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* 成品展示轮播 */
|
||||
.showcase-section {
|
||||
margin-top: 20px;
|
||||
/* 区块标题 */
|
||||
.home-section-title {
|
||||
display: block;
|
||||
margin: 48rpx 0 24rpx;
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
/* 定制成品 hero 轮播 */
|
||||
.showcase-swiper {
|
||||
height: 520rpx;
|
||||
width: 100%;
|
||||
height: 360rpx;
|
||||
}
|
||||
|
||||
.showcase-swiper-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 10rpx;
|
||||
box-sizing: border-box;
|
||||
height: 360rpx;
|
||||
overflow: hidden;
|
||||
border-radius: 24rpx;
|
||||
}
|
||||
|
||||
.showcase-swiper-card {
|
||||
.hero-block {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
box-shadow: var(--shadow-card);
|
||||
box-sizing: border-box;
|
||||
border-radius: 24rpx;
|
||||
background: linear-gradient(150deg, rgba(217, 108, 106, 0.42), rgba(108, 123, 219, 0.18)), var(--bg-muted);
|
||||
}
|
||||
|
||||
.showcase-image-wrapper {
|
||||
width: 100%;
|
||||
height: 320rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.showcase-real-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.showcase-text-area {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
background: var(--bg-card);
|
||||
padding: 16px 20px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.showcase-info .showcase-title {
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.showcase-info .showcase-desc {
|
||||
font-size: 24px;
|
||||
color: var(--text-secondary);
|
||||
display: block;
|
||||
}
|
||||
|
||||
.showcase-tag {
|
||||
.hero-media {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
right: 16px;
|
||||
background: var(--accent-primary);
|
||||
color: #ffffff;
|
||||
font-size: 20px;
|
||||
padding: 4px 16px;
|
||||
border-radius: 20px;
|
||||
font-weight: 600;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.glass-overlay {
|
||||
position: absolute;
|
||||
left: 24rpx;
|
||||
bottom: 24rpx;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
max-width: 78%;
|
||||
padding: 16rpx 24rpx;
|
||||
border-radius: 24rpx;
|
||||
background: rgba(255, 255, 255, 0.72);
|
||||
backdrop-filter: blur(24rpx);
|
||||
-webkit-backdrop-filter: blur(24rpx);
|
||||
border: 1rpx solid rgba(255, 255, 255, 0.6);
|
||||
box-shadow: var(--shadow-card);
|
||||
}
|
||||
|
||||
/* 热门品类 */
|
||||
.category-section {
|
||||
margin-top: 20px;
|
||||
.hero-title {
|
||||
display: block;
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
letter-spacing: 0;
|
||||
line-height: 1.25;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.category-grid {
|
||||
.hero-desc {
|
||||
display: block;
|
||||
margin-top: 8rpx;
|
||||
font-size: 24rpx;
|
||||
color: var(--text-secondary);
|
||||
letter-spacing: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 两列 media-card */
|
||||
.home-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 20px;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 24rpx;
|
||||
}
|
||||
|
||||
.category-item {
|
||||
.media-card {
|
||||
overflow: hidden;
|
||||
border-radius: 24rpx;
|
||||
background: var(--bg-card);
|
||||
border: 1rpx solid var(--border);
|
||||
box-shadow: var(--shadow-card);
|
||||
transition: transform 200ms ease;
|
||||
}
|
||||
|
||||
.media-card:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
.media-card-image {
|
||||
position: relative;
|
||||
aspect-ratio: 1 / 1;
|
||||
overflow: hidden;
|
||||
background: var(--bg-muted);
|
||||
}
|
||||
|
||||
.media-card-img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.media-card-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 20rpx 16rpx 24rpx;
|
||||
text-align: center;
|
||||
padding: 0 0 24px;
|
||||
overflow: hidden;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.category-item:active {
|
||||
transform: scale(0.96);
|
||||
}
|
||||
|
||||
/* 品类顶部实物照片 */
|
||||
.category-img-wrapper {
|
||||
.media-card-title {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 180rpx;
|
||||
overflow: hidden;
|
||||
border-radius: 16px;
|
||||
margin-bottom: 16px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.category-img-real {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.category-name {
|
||||
font-size: 28px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 8px;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.category-desc {
|
||||
font-size: 22px;
|
||||
.media-card-desc {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin-top: 8rpx;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 22rpx;
|
||||
color: var(--text-secondary);
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.category-price {
|
||||
font-size: 30px;
|
||||
.media-card-price {
|
||||
display: block;
|
||||
margin-top: 12rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: var(--accent-primary);
|
||||
margin-top: 8px;
|
||||
letter-spacing: 0;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
/* 空状态 */
|
||||
@@ -215,29 +228,27 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 60px 40px;
|
||||
margin-top: 24rpx;
|
||||
padding: 48rpx 32rpx;
|
||||
border-radius: 24rpx;
|
||||
background: var(--bg-muted);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.empty-icon-img {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin-bottom: 16px;
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 30px;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 8px;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.empty-sub {
|
||||
font-size: 24px;
|
||||
font-size: 24rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* 底部安全区 */
|
||||
.safe-bottom-placeholder {
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
@@ -11,12 +11,48 @@ import ThemedPageMeta from '../../components/ThemedPageMeta'
|
||||
|
||||
// 成品展示配图(从 img 里取对应实物图)
|
||||
const SHOWCASE_LIST = [
|
||||
{ title: '毕业纪念笔记本', desc: '全班名字组成校徽', image: assetUrl('/img/book_small/The1.jpg') },
|
||||
{ title: '铜质杯垫', desc: '金属质感桌面艺术', image: assetUrl('/img/cup/The1.jpg') },
|
||||
{ title: '竹制笔盒', desc: '自然竹纹文房雅器', image: assetUrl('/img/penbox/The1.jpg') },
|
||||
{ title: '书本型灯', desc: '温暖光影点亮心意', image: assetUrl('/img/booklight/The1.jpg') },
|
||||
{ title: '情侣定制礼', desc: '两个人的名字交织', image: assetUrl('/img/book_big/The1.jpg') },
|
||||
{ title: '企业年会礼', desc: '员工名字组成Logo', image: assetUrl('/img/penbox/The2.jpg') }
|
||||
{
|
||||
title: '毕业纪念笔记本',
|
||||
desc: '全班名字组成校徽',
|
||||
priceText: '¥45 起',
|
||||
categoryId: 'notebook-large',
|
||||
image: assetUrl('/img/book_small/The1.jpg')
|
||||
},
|
||||
{
|
||||
title: '铜质杯垫',
|
||||
desc: '金属质感桌面艺术',
|
||||
priceText: '¥25 起',
|
||||
categoryId: 'coaster',
|
||||
image: assetUrl('/img/cup/The1.jpg')
|
||||
},
|
||||
{
|
||||
title: '竹制笔盒',
|
||||
desc: '自然竹纹文房雅器',
|
||||
priceText: '¥75 起',
|
||||
categoryId: 'penbox',
|
||||
image: assetUrl('/img/penbox/The1.jpg')
|
||||
},
|
||||
{
|
||||
title: '书本型灯',
|
||||
desc: '温暖光影点亮心意',
|
||||
priceText: '¥45 起',
|
||||
categoryId: 'booklamp',
|
||||
image: assetUrl('/img/booklight/The1.jpg')
|
||||
},
|
||||
{
|
||||
title: '情侣定制礼',
|
||||
desc: '两个人的名字交织',
|
||||
priceText: '¥45 起',
|
||||
categoryId: 'notebook-large',
|
||||
image: assetUrl('/img/book_big/The1.jpg')
|
||||
},
|
||||
{
|
||||
title: '企业年会礼',
|
||||
desc: '员工名字组成Logo',
|
||||
priceText: '¥75 起',
|
||||
categoryId: 'penbox',
|
||||
image: assetUrl('/img/penbox/The2.jpg')
|
||||
}
|
||||
]
|
||||
|
||||
// 品类对应的实物照片映射(首页卡片顶部大图)
|
||||
@@ -38,6 +74,17 @@ export default function Index() {
|
||||
Taro.navigateTo({ url: `/pages/product/index?id=${categoryId}` })
|
||||
}
|
||||
|
||||
const navigateFromShowcase = (item: { categoryId?: string; title: string }) => {
|
||||
if (item.categoryId) {
|
||||
navigateToProduct(item.categoryId)
|
||||
return
|
||||
}
|
||||
Taro.showToast({
|
||||
title: `“${item.title}”定制通道即将开放`,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
|
||||
const filteredCategories = searchKey.trim()
|
||||
? CATEGORIES.filter(
|
||||
(c) => c.name.includes(searchKey) || c.desc.includes(searchKey)
|
||||
@@ -53,62 +100,51 @@ export default function Index() {
|
||||
<ThemedPageMeta />
|
||||
<View className='index-page'>
|
||||
|
||||
{/* 顶部标题栏 */}
|
||||
<View className='header-bar' style={{ paddingTop: `${safe.headerPaddingTop}px` }}>
|
||||
<Text className='header-title'>智绘微刻</Text>
|
||||
{/* 页头 */}
|
||||
<View className='home-header' style={{ paddingTop: `${safe.headerPaddingTop}px` }}>
|
||||
<Text className='home-title'>智绘微刻</Text>
|
||||
</View>
|
||||
|
||||
{/* 搜索框 */}
|
||||
<View className='search-card surface-card'>
|
||||
<View className='search-inner'>
|
||||
<Image className='search-icon-img' src={assetUrl('/icon/搜索.svg')} mode='aspectFit' />
|
||||
<Input
|
||||
className='search-input'
|
||||
type='text'
|
||||
placeholder='搜索定制品类:笔记本、杯垫、书灯...'
|
||||
value={searchKey}
|
||||
onInput={handleSearch}
|
||||
confirmType='search'
|
||||
/>
|
||||
{/* 搜索 */}
|
||||
<View className='searchbox'>
|
||||
<Image className='search-icon-img' src={assetUrl('/icon/搜索.svg')} mode='aspectFit' />
|
||||
<Input
|
||||
className='search-input'
|
||||
type='text'
|
||||
placeholder='搜索定制品类:笔记本、杯垫、书灯...'
|
||||
value={searchKey}
|
||||
onInput={handleSearch}
|
||||
confirmType='search'
|
||||
/>
|
||||
</View>
|
||||
{searchKey.trim() && (
|
||||
<View className='search-result-hint'>
|
||||
<Text className='hint-text'>
|
||||
{filteredCategories.length > 0
|
||||
? `找到 ${filteredCategories.length} 个相关品类`
|
||||
: '没有找到相关品类,试试看其他关键词'}
|
||||
</Text>
|
||||
</View>
|
||||
{searchKey.trim() && (
|
||||
<View className='search-result-hint'>
|
||||
<Text className='hint-text'>
|
||||
{filteredCategories.length > 0
|
||||
? `找到 ${filteredCategories.length} 个相关品类`
|
||||
: '没有找到相关品类,试试看其他关键词'}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* 成品展示轮播 */}
|
||||
<View className='showcase-section mt-20'>
|
||||
<Text className='section-title'>定制成品展示</Text>
|
||||
{/* 定制成品展示 */}
|
||||
<View className='showcase-section'>
|
||||
<Text className='home-section-title'>定制成品展示</Text>
|
||||
<Swiper
|
||||
className='showcase-swiper'
|
||||
indicatorColor='#e0d5c8'
|
||||
indicatorActiveColor='#d96c6a'
|
||||
circular
|
||||
autoplay
|
||||
interval={3000}
|
||||
duration={500}
|
||||
previousMargin='40rpx'
|
||||
nextMargin='40rpx'
|
||||
indicatorDots
|
||||
>
|
||||
{SHOWCASE_LIST.map((item, idx) => (
|
||||
<SwiperItem key={idx} className='showcase-swiper-item'>
|
||||
<View className='showcase-swiper-card surface-card'>
|
||||
<View className='showcase-image-wrapper'>
|
||||
<Image className='showcase-real-img' src={item.image} mode='aspectFill' />
|
||||
</View>
|
||||
<View className='showcase-text-area'>
|
||||
<View className='showcase-info'>
|
||||
<Text className='showcase-title'>{item.title}</Text>
|
||||
<Text className='showcase-desc'>{item.desc}</Text>
|
||||
</View>
|
||||
<View className='showcase-tag'>成品案例</View>
|
||||
<View className='hero-block'>
|
||||
<Image className='hero-media' src={item.image} mode='aspectFill' />
|
||||
<View className='glass-overlay'>
|
||||
<Text className='hero-title'>{item.title}</Text>
|
||||
<Text className='hero-desc'>{item.desc}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</SwiperItem>
|
||||
@@ -117,30 +153,32 @@ export default function Index() {
|
||||
</View>
|
||||
|
||||
{/* 热门品类 */}
|
||||
<View className='category-section mt-20'>
|
||||
<Text className='section-title'>热门品类</Text>
|
||||
<View className='category-grid'>
|
||||
<View className='category-section'>
|
||||
<Text className='home-section-title'>热门品类</Text>
|
||||
<View className='home-grid'>
|
||||
{filteredCategories.map((cat) => (
|
||||
<View
|
||||
key={cat.id}
|
||||
className='category-item surface-card'
|
||||
onTap={() => navigateToProduct(cat.id)}
|
||||
>
|
||||
<View className='category-img-wrapper'>
|
||||
<Image
|
||||
className='category-img-real'
|
||||
src={PRODUCT_IMG_MAP[cat.id] || assetUrl('/icon/四角星.svg')}
|
||||
mode='aspectFill'
|
||||
/>
|
||||
</View>
|
||||
<Text className='category-name'>{cat.name}</Text>
|
||||
<Text className='category-desc'>{cat.desc}</Text>
|
||||
<Text className='category-price'>¥{cat.price} 起</Text>
|
||||
<View
|
||||
key={cat.id}
|
||||
className='media-card'
|
||||
onTap={() => navigateToProduct(cat.id)}
|
||||
>
|
||||
<View className='media-card-image'>
|
||||
<Image
|
||||
className='media-card-img'
|
||||
src={PRODUCT_IMG_MAP[cat.id] || assetUrl('/icon/四角星.svg')}
|
||||
mode='aspectFill'
|
||||
/>
|
||||
</View>
|
||||
<View className='media-card-body'>
|
||||
<Text className='media-card-title'>{cat.name}</Text>
|
||||
<Text className='media-card-desc'>{cat.desc}</Text>
|
||||
<Text className='media-card-price'>¥{cat.price} 起</Text>
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
{filteredCategories.length === 0 && (
|
||||
<View className='empty-category surface-card'>
|
||||
<View className='empty-category'>
|
||||
<Image className='empty-icon-img' src={assetUrl('/icon/搜索.svg')} mode='aspectFit' />
|
||||
<Text className='empty-text'>未找到匹配的品类</Text>
|
||||
<Text className='empty-sub'>尝试搜索“笔记本”、“杯垫”等</Text>
|
||||
@@ -148,7 +186,29 @@ export default function Index() {
|
||||
)}
|
||||
</View>
|
||||
|
||||
<View className='safe-bottom-placeholder' />
|
||||
{/* 为你推荐 */}
|
||||
<View className='recommend-section'>
|
||||
<Text className='home-section-title'>为你推荐</Text>
|
||||
<View className='home-grid'>
|
||||
{SHOWCASE_LIST.slice(0, 4).map((item, idx) => (
|
||||
<View
|
||||
key={idx}
|
||||
className='media-card'
|
||||
onTap={() => navigateFromShowcase(item)}
|
||||
>
|
||||
<View className='media-card-image'>
|
||||
<Image className='media-card-img' src={item.image} mode='aspectFill' />
|
||||
</View>
|
||||
<View className='media-card-body'>
|
||||
<Text className='media-card-title'>{item.title}</Text>
|
||||
<Text className='media-card-desc'>{item.desc}</Text>
|
||||
<Text className='media-card-price'>{item.priceText}</Text>
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
|
||||
@@ -1,56 +1,148 @@
|
||||
/* ============================================================
|
||||
Order Detail Page — 订单详情
|
||||
============================================================ */
|
||||
.order-detail-page {
|
||||
padding: 0 24px 24px;
|
||||
min-height: 100vh;
|
||||
padding: 0 32rpx;
|
||||
padding-bottom: calc(64rpx + env(safe-area-inset-bottom));
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 返回按钮 */
|
||||
.back-btn {
|
||||
font-size: 40px;
|
||||
padding: 10px;
|
||||
/* --- Page Header --- */
|
||||
.page-header {
|
||||
margin-bottom: 24rpx;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* 状态卡片 */
|
||||
.status-card {
|
||||
padding: 32px;
|
||||
}
|
||||
|
||||
.status-top {
|
||||
.page-header-inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
margin-bottom: 32px;
|
||||
gap: 16rpx;
|
||||
min-height: 88rpx;
|
||||
}
|
||||
|
||||
.status-badge {
|
||||
font-size: 26px;
|
||||
.back-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
flex: 0 0 auto;
|
||||
border-radius: 50%;
|
||||
background: var(--bg-card);
|
||||
border: 1rpx solid var(--border-strong);
|
||||
box-shadow: var(--shadow-card);
|
||||
}
|
||||
|
||||
.back-btn:active {
|
||||
transform: scale(0.96);
|
||||
}
|
||||
|
||||
.back-arrow {
|
||||
font-size: 36rpx;
|
||||
line-height: 1;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.nav-title {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 34rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.nav-placeholder {
|
||||
width: 88rpx;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
/* --- 状态横幅 --- */
|
||||
.status-banner {
|
||||
margin-bottom: 24rpx;
|
||||
padding: 32rpx;
|
||||
background: var(--accent-primary-soft);
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
.status-text {
|
||||
display: block;
|
||||
font-size: 40rpx;
|
||||
font-weight: 800;
|
||||
color: var(--accent-primary);
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.status-desc {
|
||||
font-size: 26px;
|
||||
display: block;
|
||||
margin-top: 8rpx;
|
||||
font-size: 26rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* 物流时间轴 */
|
||||
.logistics-timeline {
|
||||
position: relative;
|
||||
padding-left: 20px;
|
||||
/* --- 通用卡片 --- */
|
||||
.detail-card {
|
||||
margin-bottom: 24rpx;
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.logistics-timeline::before {
|
||||
.card-icon-img {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
|
||||
/* --- 物流信息 --- */
|
||||
.logistics-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16rpx;
|
||||
padding-bottom: 24rpx;
|
||||
margin-bottom: 24rpx;
|
||||
border-bottom: 1rpx solid var(--border);
|
||||
}
|
||||
|
||||
.logistics-header .flex-center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.logistics-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.logistics-num {
|
||||
flex: 0 0 auto;
|
||||
font-size: 22rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.timeline {
|
||||
position: relative;
|
||||
padding-left: 20rpx;
|
||||
}
|
||||
|
||||
.timeline::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
top: 8px;
|
||||
bottom: 8px;
|
||||
width: 2px;
|
||||
left: 8rpx;
|
||||
top: 12rpx;
|
||||
bottom: 12rpx;
|
||||
width: 2rpx;
|
||||
background: var(--border);
|
||||
opacity: 0.3;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.timeline-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 24px;
|
||||
margin-bottom: 32rpx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@@ -59,14 +151,14 @@
|
||||
}
|
||||
|
||||
.timeline-dot {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
width: 20rpx;
|
||||
height: 20rpx;
|
||||
border-radius: 50%;
|
||||
background: var(--bg-card);
|
||||
border: 2rpx solid var(--border-strong);
|
||||
margin-right: 20px;
|
||||
margin-right: 24rpx;
|
||||
margin-left: -30rpx;
|
||||
flex-shrink: 0;
|
||||
margin-left: -20px;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
@@ -77,101 +169,236 @@
|
||||
|
||||
.timeline-content {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.timeline-title {
|
||||
font-size: 28px;
|
||||
color: var(--text-primary);
|
||||
.timeline-status {
|
||||
display: block;
|
||||
margin-bottom: 6px;
|
||||
margin-bottom: 8rpx;
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.timeline-time {
|
||||
font-size: 24px;
|
||||
display: block;
|
||||
margin-bottom: 8rpx;
|
||||
font-size: 22rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* 地址卡片 */
|
||||
.address-card {
|
||||
padding: 32px;
|
||||
.timeline-desc {
|
||||
display: block;
|
||||
font-size: 26rpx;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* --- 商品信息 --- */
|
||||
.product-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24rpx;
|
||||
padding-bottom: 24rpx;
|
||||
border-bottom: 1rpx solid var(--border);
|
||||
}
|
||||
|
||||
.product-icon-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
flex: 0 0 auto;
|
||||
border-radius: 16rpx;
|
||||
background: var(--bg-input);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.product-icon-img {
|
||||
width: 52rpx;
|
||||
height: 52rpx;
|
||||
}
|
||||
|
||||
.product-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.product-name {
|
||||
display: block;
|
||||
margin-bottom: 8rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
line-height: 1.3;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.product-sku {
|
||||
display: block;
|
||||
font-size: 24rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.price-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 24rpx;
|
||||
padding-top: 24rpx;
|
||||
}
|
||||
|
||||
.price-label {
|
||||
font-size: 28rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.price-value {
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: var(--accent-primary);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
/* --- 收货地址 --- */
|
||||
.address-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 16px;
|
||||
gap: 16rpx;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.address-header .flex-center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.address-title {
|
||||
font-size: 30px;
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.address-change {
|
||||
padding: 6px 16px;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 56rpx;
|
||||
padding: 0 24rpx;
|
||||
border-radius: 999rpx;
|
||||
background: var(--accent-secondary-soft);
|
||||
}
|
||||
|
||||
.change-text {
|
||||
font-size: 24px;
|
||||
font-size: 24rpx;
|
||||
font-weight: 500;
|
||||
color: var(--accent-secondary);
|
||||
}
|
||||
|
||||
.address-body {
|
||||
padding-top: 8px;
|
||||
padding-top: 8rpx;
|
||||
}
|
||||
|
||||
.address-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
margin-bottom: 8px;
|
||||
gap: 16rpx;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.address-name {
|
||||
font-size: 28px;
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.address-phone {
|
||||
font-size: 26px;
|
||||
font-size: 24rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.address-detail {
|
||||
font-size: 26px;
|
||||
font-size: 26rpx;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.5;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.address-empty {
|
||||
padding: 32px 0;
|
||||
padding: 32rpx 0;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* 底部弹窗 — 地址选择(样式复用 app.scss 全局定义,移除非必要覆写) */
|
||||
/* --- 订单信息 --- */
|
||||
.meta-title {
|
||||
display: block;
|
||||
margin-bottom: 8rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.meta-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 24rpx;
|
||||
padding: 20rpx 0;
|
||||
border-bottom: 1rpx solid var(--border);
|
||||
}
|
||||
|
||||
.meta-row:last-child {
|
||||
border-bottom: none;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.meta-label {
|
||||
flex: 0 0 auto;
|
||||
font-size: 26rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.meta-value {
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
font-size: 26rpx;
|
||||
font-weight: 500;
|
||||
color: var(--text-primary);
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
/* --- 地址选择弹层 --- */
|
||||
.addr-picker-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20px;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.addr-picker-title {
|
||||
font-size: 32px;
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.addr-picker-close {
|
||||
font-size: 28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
border-radius: 50%;
|
||||
background: var(--bg-muted);
|
||||
color: var(--text-secondary);
|
||||
padding: 8px;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.addr-picker-list {
|
||||
@@ -180,314 +407,82 @@
|
||||
}
|
||||
|
||||
.addr-picker-item {
|
||||
padding: 20px 16px;
|
||||
border-bottom: 1rpx solid var(--border);
|
||||
padding: 24rpx;
|
||||
border: 1rpx solid transparent;
|
||||
border-radius: 16rpx;
|
||||
transition: background 160ms ease, border-color 160ms ease;
|
||||
}
|
||||
|
||||
.addr-picker-item + .addr-picker-item {
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
|
||||
.addr-picker-item.active {
|
||||
background: var(--accent-secondary-soft);
|
||||
border-radius: 12px;
|
||||
background: var(--accent-primary-soft);
|
||||
border-color: var(--accent-primary);
|
||||
}
|
||||
|
||||
.addr-picker-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
margin-bottom: 8px;
|
||||
gap: 16rpx;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.addr-picker-name {
|
||||
font-size: 28px;
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.addr-picker-phone {
|
||||
font-size: 26px;
|
||||
font-size: 24rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.addr-picker-default {
|
||||
font-size: 22px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
height: 40rpx;
|
||||
padding: 0 16rpx;
|
||||
border-radius: 999rpx;
|
||||
font-size: 20rpx;
|
||||
font-weight: 600;
|
||||
color: var(--accent-primary);
|
||||
border: 1rpx solid var(--accent-primary);
|
||||
padding: 2px 8px;
|
||||
border-radius: 6px;
|
||||
background: var(--accent-primary-soft);
|
||||
}
|
||||
|
||||
.addr-picker-detail {
|
||||
font-size: 26px;
|
||||
font-size: 26rpx;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.addr-picker-empty {
|
||||
padding: 40px;
|
||||
padding: 48rpx 32rpx;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
color: var(--text-secondary);
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.addr-picker-add {
|
||||
margin-top: 16px;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
border: 1rpx solid var(--border-strong);
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.addr-picker-add-text {
|
||||
font-size: 28px;
|
||||
color: var(--accent-secondary);
|
||||
}
|
||||
|
||||
/* 卡片标题 icon(物流/地址) */
|
||||
.card-icon-img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
/* 商品卡片 */
|
||||
.product-card {
|
||||
padding: 32px;
|
||||
}
|
||||
|
||||
.product-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.product-icon-wrapper {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: var(--bg-input);
|
||||
border-radius: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 20px;
|
||||
overflow: hidden;
|
||||
padding: 8px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.product-icon-img {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
.product-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.product-name {
|
||||
font-size: 30px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.product-sku {
|
||||
font-size: 24px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.price-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 16px 0;
|
||||
border-top: 1rpx solid var(--border);
|
||||
}
|
||||
|
||||
.price-label {
|
||||
font-size: 26px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.price-value {
|
||||
font-size: 28px;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.price-row.total {
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.total-label {
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.total-value {
|
||||
font-size: 36px;
|
||||
font-weight: 800;
|
||||
color: var(--accent-primary);
|
||||
}
|
||||
|
||||
/* 信息卡片 */
|
||||
.info-card {
|
||||
padding: 32px;
|
||||
}
|
||||
|
||||
.info-card .info-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 16px 0;
|
||||
}
|
||||
|
||||
.info-card .info-label {
|
||||
font-size: 26px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.info-card .info-value {
|
||||
font-size: 26px;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
/* 状态横幅 */
|
||||
.status-text {
|
||||
font-size: 48px;
|
||||
font-weight: 800;
|
||||
color: var(--text-primary);
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* 物流信息 */
|
||||
.logistics-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 24px;
|
||||
padding-bottom: 16px;
|
||||
border-bottom: 1rpx solid var(--border);
|
||||
}
|
||||
|
||||
.logistics-title {
|
||||
font-size: 30px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.logistics-num {
|
||||
font-size: 24px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.timeline {
|
||||
position: relative;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.timeline::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
top: 8px;
|
||||
bottom: 8px;
|
||||
width: 2px;
|
||||
background: var(--border);
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.timeline-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 24px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.timeline-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.timeline-dot {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 50%;
|
||||
background: var(--bg-card);
|
||||
border: 2rpx solid var(--border-strong);
|
||||
margin-right: 20px;
|
||||
flex-shrink: 0;
|
||||
margin-left: -20px;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.timeline-item.active .timeline-dot {
|
||||
background: var(--accent-primary);
|
||||
border-color: var(--accent-primary);
|
||||
}
|
||||
|
||||
.timeline-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.timeline-status {
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
display: block;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.timeline-time {
|
||||
font-size: 24px;
|
||||
color: var(--text-secondary);
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.timeline-desc {
|
||||
font-size: 26px;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
/* 订单信息 */
|
||||
.meta-title {
|
||||
font-size: 30px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
display: block;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.meta-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 16px 0;
|
||||
}
|
||||
|
||||
.meta-label {
|
||||
font-size: 26px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.meta-value {
|
||||
font-size: 26px;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.preview-card {
|
||||
padding: 32px;
|
||||
}
|
||||
|
||||
.design-preview {
|
||||
position: relative;
|
||||
background: var(--bg-input);
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
height: 96rpx;
|
||||
margin-top: 24rpx;
|
||||
border: 1rpx solid var(--border-strong);
|
||||
margin: 0 auto;
|
||||
border-radius: 999rpx;
|
||||
background: var(--bg-card);
|
||||
}
|
||||
|
||||
.preview-sticker {
|
||||
position: absolute;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
.addr-picker-add-text {
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: var(--accent-secondary);
|
||||
}
|
||||
|
||||
/* --- 底部留白 --- */
|
||||
.page-bottom-spacer {
|
||||
height: 48rpx;
|
||||
}
|
||||
|
||||
@@ -56,8 +56,14 @@ export default function OrderDetailPage() {
|
||||
<View className={`theme-${resolvedTheme}`}>
|
||||
<ThemedPageMeta />
|
||||
<View className='order-detail-page'>
|
||||
<View className='page-header surface-card mt-20' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
|
||||
<Text className='page-title'>订单不存在</Text>
|
||||
<View className='page-header' style={{ paddingTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='page-header-inner'>
|
||||
<View className='back-btn' onTap={() => Taro.navigateBack()}>
|
||||
<Text className='back-arrow'>←</Text>
|
||||
</View>
|
||||
<Text className='nav-title'>订单不存在</Text>
|
||||
<View className='nav-placeholder' />
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
@@ -65,20 +71,22 @@ export default function OrderDetailPage() {
|
||||
}
|
||||
|
||||
return (
|
||||
<View className={`theme-${resolvedTheme}`}>
|
||||
<ThemedPageMeta />
|
||||
<View className='order-detail-page'>
|
||||
<View className={`theme-${resolvedTheme}`}>
|
||||
<ThemedPageMeta />
|
||||
<View className='order-detail-page'>
|
||||
|
||||
<View className='page-header surface-card mt-20' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='flex-between' style={{ width: '100%' }}>
|
||||
<Text className='back-btn' onTap={() => Taro.navigateBack()}>←</Text>
|
||||
<Text className='page-title'>订单详情</Text>
|
||||
<View style={{ width: '60px' }} />
|
||||
<View className='page-header' style={{ paddingTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='page-header-inner'>
|
||||
<View className='back-btn' onTap={() => Taro.navigateBack()}>
|
||||
<Text className='back-arrow'>←</Text>
|
||||
</View>
|
||||
<Text className='nav-title'>订单详情</Text>
|
||||
<View className='nav-placeholder' />
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 状态横幅 */}
|
||||
<View className='status-banner surface-card mt-20'>
|
||||
<View className='status-banner surface-card'>
|
||||
<Text className='status-text'>
|
||||
{order.statusCode === 'pending' && '待付款'}
|
||||
{order.statusCode === 'paid' && '待发货'}
|
||||
@@ -95,7 +103,7 @@ export default function OrderDetailPage() {
|
||||
|
||||
{/* 物流信息(仅 shipping/done) */}
|
||||
{(order.statusCode === 'shipping' || order.statusCode === 'done') && (
|
||||
<View className='logistics-card surface-card mt-20'>
|
||||
<View className='logistics-card detail-card surface-card'>
|
||||
<View className='logistics-header'>
|
||||
<View className='flex-center'>
|
||||
<Image className='card-icon-img' src={assetUrl('/icon/包裹.png')} mode='aspectFit' />
|
||||
@@ -133,7 +141,7 @@ export default function OrderDetailPage() {
|
||||
)}
|
||||
|
||||
{/* 商品信息 */}
|
||||
<View className='product-card surface-card mt-20'>
|
||||
<View className='product-card detail-card surface-card'>
|
||||
<View className='product-row'>
|
||||
<View className='product-icon-wrapper'>
|
||||
<Image
|
||||
@@ -154,7 +162,7 @@ export default function OrderDetailPage() {
|
||||
</View>
|
||||
|
||||
{/* 收货地址 */}
|
||||
<View className='address-card surface-card mt-20'>
|
||||
<View className='address-card detail-card surface-card'>
|
||||
<View className='address-header'>
|
||||
<View className='flex-center'>
|
||||
<Image className='card-icon-img' src={assetUrl('/icon/地址.png')} mode='aspectFit' />
|
||||
@@ -182,7 +190,7 @@ export default function OrderDetailPage() {
|
||||
</View>
|
||||
|
||||
{/* 订单信息 */}
|
||||
<View className='meta-card surface-card mt-20'>
|
||||
<View className='meta-card detail-card surface-card'>
|
||||
<Text className='meta-title'>订单信息</Text>
|
||||
<View className='meta-row'>
|
||||
<Text className='meta-label'>订单编号</Text>
|
||||
@@ -198,7 +206,7 @@ export default function OrderDetailPage() {
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={{ height: '40px' }} />
|
||||
<View className='page-bottom-spacer' />
|
||||
|
||||
{/* 地址选择底部弹窗 */}
|
||||
{showAddrPicker && (
|
||||
|
||||
@@ -1,163 +1,260 @@
|
||||
.orders-page {
|
||||
padding: 0 24px 24px;
|
||||
padding: 0 32rpx 48rpx;
|
||||
min-height: 100vh;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
padding: 32px 32px 24px;
|
||||
margin: 20px 0 0;
|
||||
/* 页面主标题 */
|
||||
.orders-page .page-header {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
padding-bottom: 32rpx;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* 状态Tab */
|
||||
.status-tabs {
|
||||
margin: 20px 0;
|
||||
.orders-page .page-title {
|
||||
display: block;
|
||||
font-size: 44rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
color: var(--text-primary);
|
||||
letter-spacing: 0;
|
||||
}
|
||||
.tabs-scroll {
|
||||
|
||||
/* 状态筛选 chip */
|
||||
.orders-page .status-tabs {
|
||||
margin: 8rpx 0 32rpx;
|
||||
}
|
||||
|
||||
.orders-page .tabs-scroll {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.tab-item {
|
||||
display: inline-block;
|
||||
padding: 20px 32px;
|
||||
position: relative;
|
||||
}
|
||||
.tab-label {
|
||||
font-size: 28px;
|
||||
|
||||
.orders-page .tab-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 64rpx;
|
||||
padding: 0 32rpx;
|
||||
margin-right: 16rpx;
|
||||
border-radius: 999rpx;
|
||||
background: var(--bg-card);
|
||||
border: 1rpx solid var(--border);
|
||||
color: var(--text-secondary);
|
||||
font-size: 26rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
.tab-item.active .tab-label {
|
||||
color: var(--accent-primary);
|
||||
font-weight: 700;
|
||||
}
|
||||
.tab-underline {
|
||||
position: absolute;
|
||||
bottom: 8px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 40px;
|
||||
height: 4px;
|
||||
|
||||
.orders-page .tab-item.active {
|
||||
background: var(--accent-primary);
|
||||
border-radius: 4px;
|
||||
border-color: var(--accent-primary);
|
||||
color: var(--bg-page);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 订单卡片 */
|
||||
.orders-list {
|
||||
padding: 0;
|
||||
}
|
||||
.order-card {
|
||||
margin-bottom: 24px;
|
||||
padding: 28px;
|
||||
.orders-page .tab-label {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.order-header {
|
||||
.orders-page .tab-underline {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* 订单列表 */
|
||||
.orders-page .orders-list {
|
||||
padding: 0 0 8rpx;
|
||||
}
|
||||
|
||||
.orders-page .order-card {
|
||||
margin-bottom: 24rpx;
|
||||
padding: 28rpx;
|
||||
border-radius: 24rpx;
|
||||
box-shadow: var(--shadow-card);
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.orders-page .order-card:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
.orders-page .order-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-bottom: 20px;
|
||||
justify-content: space-between;
|
||||
gap: 24rpx;
|
||||
padding-bottom: 20rpx;
|
||||
border-bottom: 1rpx solid var(--border);
|
||||
margin-bottom: 20px;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
.order-date {
|
||||
font-size: 24px;
|
||||
|
||||
.orders-page .order-date {
|
||||
display: block;
|
||||
min-width: 0;
|
||||
font-size: 24rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.order-body {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 20px;
|
||||
.orders-page .order-card .badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 40rpx;
|
||||
padding: 0 16rpx;
|
||||
border-radius: 999rpx;
|
||||
font-size: 22rpx;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.order-icon-wrapper {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
background: var(--bg-input);
|
||||
border-radius: 16px;
|
||||
|
||||
.orders-page .order-body {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.orders-page .order-icon-wrapper {
|
||||
width: 96rpx;
|
||||
height: 96rpx;
|
||||
border-radius: 24rpx;
|
||||
background: var(--bg-muted);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 20px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.order-icon {
|
||||
font-size: 56px;
|
||||
}
|
||||
.order-icon-img {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
}
|
||||
.order-info {
|
||||
flex: 1;
|
||||
}
|
||||
.order-product {
|
||||
font-size: 30px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.order-sku {
|
||||
font-size: 24px;
|
||||
color: var(--text-secondary);
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.order-meta {
|
||||
font-size: 22px;
|
||||
color: var(--text-muted);
|
||||
display: block;
|
||||
|
||||
.orders-page .order-icon-img {
|
||||
width: 56rpx;
|
||||
height: 56rpx;
|
||||
}
|
||||
|
||||
.order-footer {
|
||||
padding-top: 16px;
|
||||
.orders-page .order-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.orders-page .order-product {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1.3;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.orders-page .order-sku {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 24rpx;
|
||||
line-height: 1.4;
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.orders-page .order-meta {
|
||||
display: block;
|
||||
font-size: 22rpx;
|
||||
line-height: 1.4;
|
||||
color: var(--text-muted);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.orders-page .order-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
gap: 16rpx;
|
||||
padding-top: 20rpx;
|
||||
border-top: 1rpx solid var(--border);
|
||||
}
|
||||
.order-price-bar {
|
||||
|
||||
.orders-page .order-price-bar {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: flex-end;
|
||||
margin-bottom: 20px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.price-label {
|
||||
font-size: 24px;
|
||||
|
||||
.orders-page .price-label {
|
||||
font-size: 24rpx;
|
||||
color: var(--text-secondary);
|
||||
margin-right: 8px;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
.price-value {
|
||||
font-size: 36px;
|
||||
|
||||
.orders-page .price-value {
|
||||
font-size: 34rpx;
|
||||
font-weight: 800;
|
||||
line-height: 1.2;
|
||||
color: var(--accent-primary);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
.order-actions {
|
||||
|
||||
.orders-page .order-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
gap: 12rpx;
|
||||
}
|
||||
.order-btn {
|
||||
padding: 14px 28px !important;
|
||||
font-size: 26px !important;
|
||||
border-radius: 999rpx !important;
|
||||
|
||||
.orders-page .order-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 64rpx;
|
||||
padding: 0 28rpx;
|
||||
font-size: 26rpx;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
border-radius: 999rpx;
|
||||
}
|
||||
|
||||
/* 空状态 */
|
||||
.empty-state {
|
||||
.orders-page .empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 120px 40px;
|
||||
padding: 80rpx 32rpx;
|
||||
text-align: center;
|
||||
background: var(--bg-muted);
|
||||
border-radius: 24rpx;
|
||||
}
|
||||
.empty-icon-img {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
margin-bottom: 24px;
|
||||
|
||||
.orders-page .empty-icon-img {
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
.empty-text {
|
||||
font-size: 36px;
|
||||
|
||||
.orders-page .empty-text {
|
||||
display: block;
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 12px;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
.empty-sub {
|
||||
font-size: 28px;
|
||||
|
||||
.orders-page .empty-sub {
|
||||
display: block;
|
||||
font-size: 26rpx;
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 40px;
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.orders-page .empty-state .btn-primary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 280rpx;
|
||||
height: 88rpx;
|
||||
padding: 0 48rpx;
|
||||
border-radius: 999rpx;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ export default function OrdersPage() {
|
||||
<LoginGuard>
|
||||
<View className='orders-page'>
|
||||
|
||||
<View className='page-header surface-card mt-20' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='page-header' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
|
||||
<Text className='page-title'>我的订单</Text>
|
||||
</View>
|
||||
|
||||
@@ -188,7 +188,6 @@ export default function OrdersPage() {
|
||||
)}
|
||||
</ScrollView>
|
||||
|
||||
<View style={{ height: '40px' }} />
|
||||
</View>
|
||||
</LoginGuard>
|
||||
</View>
|
||||
|
||||
@@ -1,237 +1,356 @@
|
||||
.product-page {
|
||||
padding: 0 24px 24px;
|
||||
padding-bottom: calc(24px + 200px); /* 为底部毛玻璃 action-bar 留空 */
|
||||
padding: 0 32rpx 32rpx;
|
||||
padding-bottom: calc(32rpx + 480rpx);
|
||||
}
|
||||
|
||||
/* 通栏页头 */
|
||||
.page-header {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
padding: 0 24rpx 24rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.page-header-inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
min-height: 88rpx;
|
||||
}
|
||||
|
||||
/* 返回按钮 */
|
||||
.back-btn {
|
||||
font-size: 40px;
|
||||
padding: 10px;
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
flex: 0 0 auto;
|
||||
border-radius: 50%;
|
||||
background: var(--bg-card);
|
||||
border: 1rpx solid var(--border-strong);
|
||||
box-shadow: var(--shadow-card);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.back-btn:active {
|
||||
transform: scale(0.96);
|
||||
}
|
||||
|
||||
.back-arrow {
|
||||
font-size: 36rpx;
|
||||
line-height: 1;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.nav-title {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 34rpx;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.nav-placeholder {
|
||||
width: 88rpx;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
/* Hero 轮播 */
|
||||
.hero-section {
|
||||
margin-top: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.hero-swiper {
|
||||
height: 400rpx;
|
||||
height: 560rpx;
|
||||
}
|
||||
|
||||
.hero-card {
|
||||
.hero-block {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.hero-icon {
|
||||
font-size: 100px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.hero-icon-img {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.hero-name {
|
||||
font-size: 36px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
overflow: hidden;
|
||||
border-radius: 24rpx;
|
||||
background: var(--bg-muted);
|
||||
box-shadow: var(--shadow-card);
|
||||
}
|
||||
|
||||
.hero-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
/* 基本信息 */
|
||||
.info-section {
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
.hero-block-fallback {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: linear-gradient(160deg, var(--accent-primary-strong), var(--accent-secondary));
|
||||
}
|
||||
|
||||
.hero-fallback-icon {
|
||||
width: 140rpx;
|
||||
height: 140rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
/* detail-card 版式 */
|
||||
.detail-card {
|
||||
padding: 32rpx;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
|
||||
.price-line {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: space-between;
|
||||
padding: 20px 0;
|
||||
border-bottom: 1rpx solid var(--border);
|
||||
gap: 24rpx;
|
||||
}
|
||||
|
||||
.info-row:last-child {
|
||||
border-bottom: none;
|
||||
.price-left {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-size: 28px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.info-price {
|
||||
font-size: 40px;
|
||||
font-weight: 800;
|
||||
color: var(--accent-primary);
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 28px;
|
||||
.detail-title {
|
||||
display: block;
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1.3;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
/* 详细介绍 */
|
||||
.detail-section {
|
||||
padding: 24px;
|
||||
.detail-desc {
|
||||
display: block;
|
||||
margin-top: 8rpx;
|
||||
font-size: 24rpx;
|
||||
line-height: 1.4;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.price-right {
|
||||
flex: 0 0 auto;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.price {
|
||||
display: block;
|
||||
font-size: 40rpx;
|
||||
font-weight: 800;
|
||||
line-height: 1.2;
|
||||
color: var(--accent-primary);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.price-old {
|
||||
display: block;
|
||||
margin-top: 6rpx;
|
||||
font-size: 24rpx;
|
||||
color: var(--text-muted);
|
||||
text-decoration: line-through;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.spec-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 24rpx;
|
||||
padding: 24rpx 0;
|
||||
border-bottom: 1rpx solid var(--border);
|
||||
}
|
||||
|
||||
.spec-row:last-child {
|
||||
border-bottom: none;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.spec-key {
|
||||
flex: 0 0 auto;
|
||||
font-size: 26rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.spec-value {
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
font-size: 26rpx;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.detail-card .section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.detail-text {
|
||||
font-size: 28px;
|
||||
color: var(--text-secondary);
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
line-height: 1.8;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* 底部操作栏 */
|
||||
.action-bar .price-summary {
|
||||
.bottom-action-bar {
|
||||
gap: 20rpx;
|
||||
padding-left: 32rpx;
|
||||
padding-right: 32rpx;
|
||||
}
|
||||
|
||||
.bottom-action-bar .price-summary {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.summary-label {
|
||||
font-size: 22px;
|
||||
color: var(--text-secondary);
|
||||
display: block;
|
||||
font-size: 22rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.summary-price {
|
||||
font-size: 36px;
|
||||
display: block;
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
color: var(--accent-primary);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.summary-original {
|
||||
display: block;
|
||||
margin-top: 2rpx;
|
||||
font-size: 22rpx;
|
||||
color: var(--text-muted);
|
||||
text-decoration: line-through;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.bottom-action-bar .btn-secondary,
|
||||
.bottom-action-bar .btn-primary {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 28rpx 0;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
/* 弹窗 */
|
||||
.modal-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
padding: 48px;
|
||||
padding: 48rpx;
|
||||
}
|
||||
|
||||
.modal-card {
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
padding: 40px;
|
||||
max-width: 640rpx;
|
||||
padding: 40rpx;
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
font-size: 36px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
text-align: center;
|
||||
margin-bottom: 24px;
|
||||
display: block;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.modal-product {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 16px;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.modal-icon {
|
||||
font-size: 48px;
|
||||
gap: 16rpx;
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.modal-icon-img {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
}
|
||||
|
||||
.modal-name {
|
||||
font-size: 32px;
|
||||
color: var(--text-primary);
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.quantity-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 32px;
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.qty-label {
|
||||
font-size: 28px;
|
||||
font-size: 28rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.qty-control {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
gap: 24rpx;
|
||||
}
|
||||
|
||||
.qty-btn {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 12px;
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
border-radius: 16rpx;
|
||||
background: var(--bg-input);
|
||||
border: 1rpx solid var(--border);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 32px;
|
||||
color: var(--text-primary);
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.qty-num {
|
||||
font-size: 32px;
|
||||
min-width: 48rpx;
|
||||
text-align: center;
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
min-width: 48px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.modal-total {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 32px;
|
||||
padding-top: 24px;
|
||||
margin-bottom: 32rpx;
|
||||
padding-top: 24rpx;
|
||||
border-top: 1rpx solid var(--border);
|
||||
}
|
||||
|
||||
.total-label {
|
||||
font-size: 28px;
|
||||
font-size: 28rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.total-price {
|
||||
font-size: 36px;
|
||||
font-size: 36rpx;
|
||||
font-weight: 800;
|
||||
color: var(--accent-primary);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.modal-actions {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.modal-actions .btn-secondary,
|
||||
.modal-actions .btn-primary {
|
||||
flex: 1;
|
||||
padding: 20px 0;
|
||||
text-align: center;
|
||||
padding: 24rpx 0;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@@ -8,10 +8,9 @@ import { useThemeContext } from '../../context/ThemeContext'
|
||||
import { useSafeArea } from '../../hooks/useSafeArea'
|
||||
import { useStatusBar } from '../../hooks/useStatusBar'
|
||||
import ThemedPageMeta from '../../components/ThemedPageMeta'
|
||||
import BottomActionBar from '../../components/BottomActionBar'
|
||||
import { getProductIconImg } from '../../utils/productConfig'
|
||||
|
||||
const HERO_COLORS = ['var(--accent-primary-soft)', 'var(--bg-muted)', 'var(--accent-secondary-soft)']
|
||||
|
||||
export default function ProductPage() {
|
||||
const { theme, resolvedTheme } = useThemeContext()
|
||||
const safe = useSafeArea()
|
||||
@@ -21,7 +20,7 @@ export default function ProductPage() {
|
||||
|
||||
const router = Taro.getCurrentInstance().router
|
||||
const params = router ? router.params : undefined
|
||||
const productId = params ? params.id : ''
|
||||
const productId = params && params.id ? params.id : ''
|
||||
const product = getProductById(productId)
|
||||
|
||||
if (!product) {
|
||||
@@ -29,14 +28,25 @@ export default function ProductPage() {
|
||||
<View className={`theme-${resolvedTheme}`}>
|
||||
<ThemedPageMeta />
|
||||
<View className='product-page'>
|
||||
<View className='page-header surface-card mt-20' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
|
||||
<Text className='page-title'>商品未找到</Text>
|
||||
<View className='page-header' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='page-header-inner'>
|
||||
<View className='back-btn' onTap={() => Taro.navigateBack()}>
|
||||
<Text className='back-arrow'>←</Text>
|
||||
</View>
|
||||
<Text className='nav-title'>商品未找到</Text>
|
||||
<View className='nav-placeholder' />
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
const craftSpec = product.specs && product.specs.length > 0
|
||||
? product.specs.find(item => item[0].indexOf('工艺') >= 0)
|
||||
: undefined
|
||||
const craftValue = craftSpec ? craftSpec[1] : '激光微雕'
|
||||
|
||||
const handleAddToList = () => {
|
||||
setQuantity(1)
|
||||
setShowModal(true)
|
||||
@@ -64,16 +74,18 @@ export default function ProductPage() {
|
||||
<ThemedPageMeta />
|
||||
<View className='product-page'>
|
||||
|
||||
<View className='page-header surface-card mt-20' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='flex-between'>
|
||||
<Text className='back-btn' onTap={() => Taro.navigateBack()}>←</Text>
|
||||
<Text className='page-title'>商品详情</Text>
|
||||
<View style={{ width: '60px' }} />
|
||||
<View className='page-header' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='page-header-inner'>
|
||||
<View className='back-btn' onTap={() => Taro.navigateBack()}>
|
||||
<Text className='back-arrow'>←</Text>
|
||||
</View>
|
||||
<Text className='nav-title'>商品详情</Text>
|
||||
<View className='nav-placeholder' />
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 轮播 Hero */}
|
||||
<View className='hero-section mt-20'>
|
||||
<View className='hero-section'>
|
||||
<Swiper
|
||||
className='hero-swiper'
|
||||
circular
|
||||
@@ -81,54 +93,71 @@ export default function ProductPage() {
|
||||
interval={3000}
|
||||
duration={500}
|
||||
indicatorDots
|
||||
indicatorColor='#e0d5c8'
|
||||
indicatorActiveColor='#d96c6a'
|
||||
indicatorColor='var(--border-strong)'
|
||||
indicatorActiveColor='var(--accent-primary)'
|
||||
>
|
||||
{product.images && product.images.length > 0 ? (
|
||||
product.images.map((img, idx) => (
|
||||
<SwiperItem key={idx}>
|
||||
<View className='hero-card surface-card'>
|
||||
<Image className='hero-image' src={img} mode='aspectFit' />
|
||||
<View className='hero-block'>
|
||||
<Image className='hero-image' src={img} mode='aspectFill' />
|
||||
</View>
|
||||
</SwiperItem>
|
||||
))
|
||||
) : (
|
||||
HERO_COLORS.map((color, idx) => (
|
||||
<SwiperItem key={idx}>
|
||||
<View className='hero-card surface-card' style={{ background: color }}>
|
||||
<Image className='hero-icon-img' src={getProductIconImg(product)} mode='aspectFit' />
|
||||
<Text className='hero-name'>{product.name}</Text>
|
||||
</View>
|
||||
</SwiperItem>
|
||||
))
|
||||
<SwiperItem>
|
||||
<View className='hero-block hero-block-fallback'>
|
||||
<Image className='hero-fallback-icon' src={getProductIconImg(product)} mode='aspectFit' />
|
||||
</View>
|
||||
</SwiperItem>
|
||||
)}
|
||||
</Swiper>
|
||||
</View>
|
||||
|
||||
{/* 基本信息 */}
|
||||
<View className='info-section surface-card mt-20'>
|
||||
<View className='info-row'>
|
||||
<Text className='info-label'>单价</Text>
|
||||
<Text className='info-price'>¥{product.price}</Text>
|
||||
{/* 商品信息 */}
|
||||
<View className='detail-card surface-card'>
|
||||
<View className='price-line'>
|
||||
<View className='price-left'>
|
||||
<Text className='detail-title'>{product.name}</Text>
|
||||
<Text className='detail-desc'>{product.desc}</Text>
|
||||
</View>
|
||||
<View className='price-right'>
|
||||
<Text className='price'>¥{product.price}</Text>
|
||||
{product.originalPrice && product.originalPrice > product.price && (
|
||||
<Text className='price-old'>¥{product.originalPrice}</Text>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
<View className='info-row'>
|
||||
<Text className='info-label'>工期</Text>
|
||||
<Text className='info-value'>{product.leadTime}</Text>
|
||||
</View>
|
||||
|
||||
{/* 规格信息 */}
|
||||
<View className='detail-card surface-card'>
|
||||
<View className='spec-row'>
|
||||
<Text className='spec-key'>单价</Text>
|
||||
<Text className='spec-value'>¥{product.price}</Text>
|
||||
</View>
|
||||
<View className='info-row'>
|
||||
<Text className='info-label'>尺寸</Text>
|
||||
<Text className='info-value'>{product.mask.width} × {product.mask.height} px</Text>
|
||||
<View className='spec-row'>
|
||||
<Text className='spec-key'>工期</Text>
|
||||
<Text className='spec-value'>{product.leadTime}</Text>
|
||||
</View>
|
||||
<View className='spec-row'>
|
||||
<Text className='spec-key'>尺寸</Text>
|
||||
<Text className='spec-value'>{product.mask.width} × {product.mask.height} px</Text>
|
||||
</View>
|
||||
<View className='spec-row'>
|
||||
<Text className='spec-key'>定制工艺</Text>
|
||||
<Text className='spec-value'>{craftValue}</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 详细介绍 */}
|
||||
<View className='detail-section surface-card mt-20'>
|
||||
<View className='detail-card surface-card'>
|
||||
<Text className='section-title'>商品介绍</Text>
|
||||
<Text className='detail-text'>{product.description}</Text>
|
||||
</View>
|
||||
|
||||
{/* 底部操作栏 */}
|
||||
<View className='action-bar'>
|
||||
<BottomActionBar>
|
||||
<View className='price-summary'>
|
||||
<Text className='summary-label'>起价</Text>
|
||||
<Text className='summary-price'>¥{product.price}</Text>
|
||||
@@ -139,7 +168,7 @@ export default function ProductPage() {
|
||||
<View className='btn-primary' onTap={goToDIY}>
|
||||
<Text>立即下单</Text>
|
||||
</View>
|
||||
</View>
|
||||
</BottomActionBar>
|
||||
|
||||
{/* 安全区占位(防止内容被 action-bar 遮挡) */}
|
||||
<View className='safe-bottom-placeholder' />
|
||||
|
||||
@@ -1,244 +1,272 @@
|
||||
.profile-page {
|
||||
padding: 0 24px 24px;
|
||||
padding: 0 32rpx 48rpx;
|
||||
min-height: 100vh;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 用户头部 */
|
||||
.profile-header {
|
||||
padding: 40px 32px 32px;
|
||||
margin: 20px 0 0;
|
||||
.profile-page .profile-header {
|
||||
padding: 32rpx 32rpx 16rpx;
|
||||
margin: 0 0 32rpx;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
.profile-page .user-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 32px;
|
||||
gap: 24rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
.profile-page .avatar,
|
||||
.profile-page .avatar-placeholder {
|
||||
width: 112rpx;
|
||||
height: 112rpx;
|
||||
border-radius: 50%;
|
||||
border: 1rpx solid var(--border);
|
||||
margin-right: 24px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.avatar-placeholder {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border-radius: 50%;
|
||||
background: var(--bg-muted);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 24px;
|
||||
border: 1rpx solid var(--border);
|
||||
margin-right: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.avatar-icon {
|
||||
font-size: 56px;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 40px;
|
||||
font-weight: 800;
|
||||
color: var(--text-primary);
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.user-level {
|
||||
font-size: 24px;
|
||||
color: var(--text-secondary);
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* 5状态快捷入口 - 2+3布局 */
|
||||
.status-grid {
|
||||
background: var(--bg-card);
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.status-row {
|
||||
.profile-page .avatar-icon-img {
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
}
|
||||
|
||||
.profile-page .user-meta {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.profile-page .user-name {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.profile-page .user-level {
|
||||
display: block;
|
||||
font-size: 24rpx;
|
||||
line-height: 1.4;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* 5 状态快捷入口 */
|
||||
.profile-page .status-grid {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-top: 1rpx solid var(--border);
|
||||
padding-top: 16rpx;
|
||||
}
|
||||
|
||||
.profile-page .status-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
/* 每组(item + divider)作为一个 flex 单元 */
|
||||
.status-group {
|
||||
.profile-page .status-group {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.status-item {
|
||||
.profile-page .status-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 8px 0;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
min-height: 112rpx;
|
||||
padding: 8rpx 0;
|
||||
transition: transform 0.18s ease;
|
||||
}
|
||||
|
||||
.status-num {
|
||||
font-size: 36px;
|
||||
.profile-page .status-item:active {
|
||||
transform: scale(0.97);
|
||||
}
|
||||
|
||||
.profile-page .status-icon-img {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.profile-page .status-num {
|
||||
font-size: 32rpx;
|
||||
font-weight: 800;
|
||||
line-height: 1.2;
|
||||
color: var(--accent-primary);
|
||||
margin-bottom: 8px;
|
||||
margin-bottom: 6rpx;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.status-label {
|
||||
font-size: 24px;
|
||||
.profile-page .status-label {
|
||||
font-size: 24rpx;
|
||||
line-height: 1.2;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.status-divider {
|
||||
width: 2px;
|
||||
height: 48px;
|
||||
.profile-page .status-divider {
|
||||
width: 1rpx;
|
||||
height: 56rpx;
|
||||
background: var(--border);
|
||||
opacity: 0.25;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.status-divider-h {
|
||||
height: 2px;
|
||||
.profile-page .status-divider-h {
|
||||
height: 1rpx;
|
||||
background: var(--border);
|
||||
opacity: 0.15;
|
||||
margin: 0 16px;
|
||||
margin: 4rpx 16rpx 12rpx;
|
||||
}
|
||||
|
||||
/* 菜单网格 */
|
||||
.menu-grid {
|
||||
/* 区块标题 */
|
||||
.profile-page .section-title {
|
||||
display: block;
|
||||
margin: 0 0 24rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1.25;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
/* 功能菜单 */
|
||||
.profile-page .menu-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
gap: 20px;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.menu-card {
|
||||
.profile-page .menu-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 32px 16px;
|
||||
transition: transform 0.2s;
|
||||
justify-content: center;
|
||||
min-height: 148rpx;
|
||||
padding: 28rpx 16rpx;
|
||||
border-radius: 24rpx;
|
||||
box-shadow: var(--shadow-card);
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.menu-card:active {
|
||||
transform: scale(0.96);
|
||||
.profile-page .menu-card:active {
|
||||
transform: scale(0.97);
|
||||
}
|
||||
|
||||
.menu-icon {
|
||||
font-size: 48px;
|
||||
margin-bottom: 12px;
|
||||
.profile-page .menu-icon-img {
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.menu-label {
|
||||
font-size: 26px;
|
||||
color: var(--text-primary);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 企业定制 */
|
||||
.enterprise-section {
|
||||
padding: 32px;
|
||||
}
|
||||
|
||||
.enterprise-title {
|
||||
font-size: 30px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
.profile-page .menu-label {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 26rpx;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.enterprise-desc {
|
||||
font-size: 24px;
|
||||
/* 企业定制入口 */
|
||||
.profile-page .enterprise-section {
|
||||
padding: 28rpx 32rpx;
|
||||
margin: 0 0 48rpx;
|
||||
}
|
||||
|
||||
.profile-page .enterprise-icon {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
margin-right: 12rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.profile-page .enterprise-title {
|
||||
display: block;
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1.3;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.profile-page .enterprise-desc {
|
||||
display: block;
|
||||
font-size: 24rpx;
|
||||
line-height: 1.4;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.enterprise-btn {
|
||||
padding: 16px 32px !important;
|
||||
font-size: 26px !important;
|
||||
border-radius: 40px !important;
|
||||
.profile-page .enterprise-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 80rpx;
|
||||
padding: 0 32rpx;
|
||||
font-size: 26rpx;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
border-radius: 999rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.menu-icon-img {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
/* 状态 icon 图片 */
|
||||
.status-icon-img {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
/* 企业定制icon */
|
||||
.enterprise-icon {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
/* 头像占位图 */
|
||||
.avatar-icon-img {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
/* 登录弹窗头像占位 */
|
||||
.avatar-placeholder-img {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
}
|
||||
.modal-overlay {
|
||||
/* 登录弹窗 */
|
||||
.profile-page .modal-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
padding: 48px;
|
||||
padding: 48rpx;
|
||||
}
|
||||
|
||||
.login-card {
|
||||
.profile-page .login-card {
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
padding: 40px;
|
||||
max-width: 640rpx;
|
||||
padding: 40rpx;
|
||||
text-align: center;
|
||||
border-radius: 32rpx;
|
||||
}
|
||||
|
||||
.login-title {
|
||||
font-size: 36px;
|
||||
.profile-page .login-title {
|
||||
display: block;
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
display: block;
|
||||
margin-bottom: 12px;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.login-desc {
|
||||
font-size: 26px;
|
||||
.profile-page .login-desc {
|
||||
display: block;
|
||||
font-size: 26rpx;
|
||||
color: var(--text-secondary);
|
||||
display: block;
|
||||
margin-bottom: 32px;
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.avatar-btn {
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
.profile-page .avatar-btn {
|
||||
width: 160rpx;
|
||||
height: 160rpx;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto 24px;
|
||||
margin: 0 auto 24rpx;
|
||||
background: var(--bg-input);
|
||||
border: 1rpx solid var(--border);
|
||||
display: flex;
|
||||
@@ -250,39 +278,46 @@
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
.avatar-img {
|
||||
.profile-page .avatar-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.avatar-placeholder {
|
||||
font-size: 24px;
|
||||
color: var(--text-secondary);
|
||||
.profile-page .avatar-placeholder-img {
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
}
|
||||
|
||||
.nickname-input {
|
||||
.profile-page .nickname-input {
|
||||
width: 100%;
|
||||
height: 80px;
|
||||
height: 88rpx;
|
||||
background: var(--bg-input);
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 16px;
|
||||
padding: 0 24px;
|
||||
font-size: 28px;
|
||||
border-radius: 16rpx;
|
||||
padding: 0 24rpx;
|
||||
font-size: 28rpx;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 32px;
|
||||
margin-bottom: 32rpx;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.login-actions {
|
||||
.profile-page .login-actions {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.login-actions .btn-secondary,
|
||||
.login-actions .btn-primary {
|
||||
.profile-page .login-actions .btn-secondary,
|
||||
.profile-page .login-actions .btn-primary {
|
||||
flex: 1;
|
||||
padding: 20px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 88rpx;
|
||||
padding: 0;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
border-radius: 999rpx;
|
||||
}
|
||||
|
||||
@@ -282,7 +282,7 @@ export default function ProfilePage() {
|
||||
<View className='profile-page'>
|
||||
|
||||
{/* 用户信息头部 */}
|
||||
<View className='profile-header surface-card mt-20' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='profile-header surface-card' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='user-info'>
|
||||
{isLoggedIn && userInfo.avatarUrl ? (
|
||||
<Image className='avatar' src={userInfo.avatarUrl} mode='aspectFill' />
|
||||
@@ -360,8 +360,6 @@ export default function ProfilePage() {
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={{ height: '40px' }} />
|
||||
|
||||
{/* 登录弹窗 */}
|
||||
{showLogin && (
|
||||
<View className='modal-overlay'>
|
||||
|
||||
@@ -1,121 +1,208 @@
|
||||
/* ============================================================
|
||||
Service Page — 客服中心
|
||||
============================================================ */
|
||||
|
||||
.service-page {
|
||||
padding: 0 24px 24px;
|
||||
padding: 0 32rpx calc(24rpx + env(safe-area-inset-bottom));
|
||||
min-height: 100vh;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
padding: 32px 32px 24px;
|
||||
margin: 20px 0 0;
|
||||
.service-page .page-header.service-header {
|
||||
margin: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-bottom: 32rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 客服英雄区 */
|
||||
.service-header .page-title {
|
||||
font-size: 44rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
color: var(--text-primary);
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
/* 客服主入口 */
|
||||
.service-hero {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 56rpx 40rpx;
|
||||
text-align: center;
|
||||
padding: 50px 40px;
|
||||
}
|
||||
|
||||
.service-hero-icon {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
margin-bottom: 20px;
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.service-title {
|
||||
font-size: 36px;
|
||||
display: block;
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
display: block;
|
||||
margin-bottom: 12px;
|
||||
margin-bottom: 12rpx;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.service-desc {
|
||||
font-size: 24px;
|
||||
color: var(--text-secondary);
|
||||
display: block;
|
||||
margin-bottom: 32px;
|
||||
font-size: 24rpx;
|
||||
line-height: 1.5;
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.service-btn {
|
||||
padding: 24px 56px !important;
|
||||
font-size: 30px !important;
|
||||
border-radius: 50px !important;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 280rpx;
|
||||
height: 80rpx;
|
||||
padding: 0 48rpx;
|
||||
box-sizing: border-box;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 联系方式 */
|
||||
.contact-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
.service-page .section-title {
|
||||
display: block;
|
||||
margin-bottom: 24rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.contact-list.surface-card {
|
||||
padding: 0 32rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.contact-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 28px 32px;
|
||||
min-height: 112rpx;
|
||||
padding: 24rpx 0;
|
||||
border-bottom: 1rpx solid var(--border);
|
||||
}
|
||||
.contact-icon {
|
||||
font-size: 48px;
|
||||
margin-right: 24px;
|
||||
|
||||
.contact-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.contact-item-link {
|
||||
transition: background 160ms ease;
|
||||
}
|
||||
|
||||
.contact-item-link:active {
|
||||
background: var(--bg-muted);
|
||||
}
|
||||
|
||||
.contact-icon-img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-right: 24px;
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
margin-right: 24rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.contact-info {
|
||||
flex: 1;
|
||||
}
|
||||
.contact-label {
|
||||
font-size: 24px;
|
||||
color: var(--text-secondary);
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.contact-value {
|
||||
font-size: 30px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* FAQ */
|
||||
.faq-card {
|
||||
margin-bottom: 20px;
|
||||
padding: 28px 32px;
|
||||
}
|
||||
.faq-q {
|
||||
font-size: 30px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
.contact-label {
|
||||
display: block;
|
||||
margin-bottom: 12px;
|
||||
font-size: 24rpx;
|
||||
line-height: 1.4;
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.contact-value {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.contact-arrow {
|
||||
flex-shrink: 0;
|
||||
margin-left: 16rpx;
|
||||
font-size: 32rpx;
|
||||
line-height: 1;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* 常见问题 */
|
||||
.faq-card {
|
||||
display: block;
|
||||
margin-bottom: 24rpx;
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.faq-q {
|
||||
display: block;
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1.45;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 12rpx;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.faq-a {
|
||||
font-size: 26px;
|
||||
display: block;
|
||||
font-size: 26rpx;
|
||||
line-height: 1.7;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* 企业专属 */
|
||||
.enterprise-service {
|
||||
padding: 32px;
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.enterprise-service .flex-center {
|
||||
justify-content: flex-start;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.enterprise-icon {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
margin-right: 12px;
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
margin-right: 12rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.enterprise-title {
|
||||
font-size: 30px;
|
||||
display: block;
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.enterprise-desc {
|
||||
font-size: 24px;
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 24px;
|
||||
display: block;
|
||||
font-size: 24rpx;
|
||||
line-height: 1.6;
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.enterprise-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 80rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@@ -23,12 +23,12 @@ export default function ServicePage() {
|
||||
<View className={`theme-${resolvedTheme}`} style={{ minHeight: '100vh' }}>
|
||||
<ThemedPageMeta />
|
||||
<View className='service-page'>
|
||||
<View className='page-header surface-card mt-20' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='page-header service-header' style={{ paddingTop: `${safe.headerPaddingTop}px` }}>
|
||||
<Text className='page-title'>联系客服</Text>
|
||||
</View>
|
||||
|
||||
{/* 客服入口 */}
|
||||
<View className='service-hero surface-card mt-20'>
|
||||
<View className='service-hero surface-card'>
|
||||
<Image className='service-hero-icon' src={assetUrl('/icon/电话.png')} mode='aspectFit' />
|
||||
<Text className='service-title'>智绘微刻客服中心</Text>
|
||||
<Text className='service-desc'>工作日 09:00 - 18:00 在线为您服务</Text>
|
||||
@@ -40,22 +40,23 @@ export default function ServicePage() {
|
||||
{/* 联系方式 */}
|
||||
<View className='mt-20'>
|
||||
<Text className='section-title'>联系方式</Text>
|
||||
<View className='contact-list'>
|
||||
<View className='contact-item surface-card'>
|
||||
<View className='contact-list surface-card'>
|
||||
<View className='contact-item'>
|
||||
<Image className='contact-icon-img' src={assetUrl('/icon/电话.png')} mode='aspectFit' />
|
||||
<View className='contact-info'>
|
||||
<Text className='contact-label'>客服电话</Text>
|
||||
<Text className='contact-value'>400-XXX-XXXX</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View className='contact-item surface-card' onTap={() => Taro.setClipboardData({ data: 'smart_engraving' })}>
|
||||
<View className='contact-item contact-item-link' onTap={() => Taro.setClipboardData({ data: 'smart_engraving' })}>
|
||||
<Image className='contact-icon-img' src={assetUrl('/icon/词云生成.png')} mode='aspectFit' />
|
||||
<View className='contact-info'>
|
||||
<Text className='contact-label'>客服微信</Text>
|
||||
<Text className='contact-value'>smart_engraving(点击复制)</Text>
|
||||
</View>
|
||||
<Text className='contact-arrow'>›</Text>
|
||||
</View>
|
||||
<View className='contact-item surface-card'>
|
||||
<View className='contact-item'>
|
||||
<Image className='contact-icon-img' src={assetUrl('/icon/使用帮助.png')} mode='aspectFit' />
|
||||
<View className='contact-info'>
|
||||
<Text className='contact-label'>商务邮箱</Text>
|
||||
@@ -88,7 +89,7 @@ export default function ServicePage() {
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={{ height: '40px' }} />
|
||||
<View style={{ height: '80rpx' }} />
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
|
||||
@@ -1,60 +1,223 @@
|
||||
/* ============================================================
|
||||
Settings Page — 设置
|
||||
============================================================ */
|
||||
|
||||
.settings-page {
|
||||
padding: 0 24px 24px;
|
||||
}
|
||||
.settings-area {
|
||||
padding-top: calc(env(safe-area-inset-top, 0px));
|
||||
padding: 0 32rpx calc(24rpx + env(safe-area-inset-bottom));
|
||||
min-height: 100vh;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 顶部导航 */
|
||||
.page-header.settings-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
min-height: 88rpx;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-bottom: 24rpx;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.settings-header .back-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
flex: 0 0 auto;
|
||||
border-radius: 50%;
|
||||
background: var(--bg-card);
|
||||
border: 1rpx solid var(--border-strong);
|
||||
box-shadow: var(--shadow-card);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.settings-header .back-btn:active {
|
||||
transform: scale(0.96);
|
||||
}
|
||||
|
||||
.settings-header .back-arrow {
|
||||
font-size: 36rpx;
|
||||
line-height: 1;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.settings-header .page-title {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
text-align: center;
|
||||
font-size: 34rpx;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.header-spacer {
|
||||
width: 88rpx;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
/* 用户卡片 */
|
||||
.settings-user {
|
||||
padding: 24px;
|
||||
padding: 32rpx;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
|
||||
.settings-user .flex-center {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.settings-avatar {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
width: 112rpx;
|
||||
height: 112rpx;
|
||||
border-radius: 50%;
|
||||
border: 1rpx solid var(--border);
|
||||
background: var(--bg-input);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.settings-avatar-placeholder {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
width: 112rpx;
|
||||
height: 112rpx;
|
||||
border-radius: 50%;
|
||||
background: var(--bg-input);
|
||||
border: 1rpx solid var(--border);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 30px;
|
||||
padding: 24rpx;
|
||||
box-sizing: border-box;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.settings-avatar-icon {
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
}
|
||||
|
||||
.settings-meta {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
margin-left: 24rpx;
|
||||
}
|
||||
|
||||
.settings-name {
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1.3;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 8rpx;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.settings-id {
|
||||
font-size: 24px;
|
||||
display: block;
|
||||
font-size: 24rpx;
|
||||
line-height: 1.4;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.arrow {
|
||||
font-size: 36px;
|
||||
flex-shrink: 0;
|
||||
font-size: 36rpx;
|
||||
line-height: 1;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* 外观设置 */
|
||||
.settings-section {
|
||||
padding: 32rpx;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
|
||||
.section-label {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 24rpx;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.theme-options {
|
||||
display: flex;
|
||||
gap: 8rpx;
|
||||
padding: 8rpx;
|
||||
border-radius: 999rpx;
|
||||
background: var(--bg-muted);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.theme-option {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
height: 80rpx;
|
||||
padding: 0 16rpx;
|
||||
border-radius: 999rpx;
|
||||
background: transparent;
|
||||
border: 1rpx solid transparent;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12rpx;
|
||||
color: var(--text-secondary);
|
||||
font-size: 26rpx;
|
||||
font-weight: 500;
|
||||
transition: background 160ms ease, border-color 160ms ease, color 160ms ease, box-shadow 160ms ease;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.theme-option.active {
|
||||
background: var(--bg-card);
|
||||
border-color: var(--border-strong);
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
box-shadow: var(--shadow-card);
|
||||
}
|
||||
|
||||
.theme-option-text {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.theme-check {
|
||||
width: 16rpx;
|
||||
height: 16rpx;
|
||||
border-radius: 50%;
|
||||
background: var(--accent-primary);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.theme-hint {
|
||||
display: block;
|
||||
text-align: center;
|
||||
margin-top: 24rpx;
|
||||
font-size: 24rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* 菜单列表 */
|
||||
.settings-list {
|
||||
padding: 0 24px;
|
||||
padding: 0 32rpx;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
|
||||
.settings-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 28px 0;
|
||||
min-height: 112rpx;
|
||||
padding: 24rpx 0;
|
||||
}
|
||||
|
||||
.settings-item.bordered {
|
||||
@@ -62,83 +225,115 @@
|
||||
}
|
||||
|
||||
.settings-item-icon-img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-right: 16px;
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
margin-right: 24rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
|
||||
.settings-item-label {
|
||||
flex: 1;
|
||||
font-size: 30px;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.logout-btn {
|
||||
text-align: center;
|
||||
padding: 24px 0;
|
||||
color: var(--danger);
|
||||
border: 1rpx solid var(--danger);
|
||||
}
|
||||
|
||||
/* --- 主题选择 --- */
|
||||
.settings-section {
|
||||
padding: 32px;
|
||||
}
|
||||
|
||||
.section-label {
|
||||
font-size: 30px;
|
||||
min-width: 0;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
display: block;
|
||||
margin-bottom: 24px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.theme-options {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.theme-option {
|
||||
flex: 1;
|
||||
min-width: 160px;
|
||||
padding: 24px 16px;
|
||||
border-radius: 20px;
|
||||
background: var(--bg-input);
|
||||
border: 1rpx solid transparent;
|
||||
/* 退出登录 */
|
||||
.logout-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
transition: all 0.2s ease;
|
||||
height: 88rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: var(--danger);
|
||||
border: 1rpx solid var(--danger);
|
||||
background: transparent;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.theme-option.active {
|
||||
border-color: var(--accent-primary);
|
||||
background: var(--accent-primary-soft);
|
||||
/* 编辑弹窗 */
|
||||
.settings-page .modal-overlay {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 48rpx;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.theme-option-text {
|
||||
font-size: 28px;
|
||||
color: var(--text-primary);
|
||||
font-weight: 500;
|
||||
.settings-page .modal-card {
|
||||
width: 100%;
|
||||
max-width: 640rpx;
|
||||
padding: 40rpx;
|
||||
border-radius: 32rpx;
|
||||
background: var(--bg-card);
|
||||
border: 1rpx solid var(--border);
|
||||
box-shadow: var(--shadow-elevated);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.theme-check {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 50%;
|
||||
background: var(--accent-primary);
|
||||
}
|
||||
|
||||
.theme-hint {
|
||||
font-size: 24px;
|
||||
color: var(--text-secondary);
|
||||
margin-top: 20px;
|
||||
.settings-page .modal-title {
|
||||
display: block;
|
||||
text-align: center;
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 32rpx;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
/* 弹窗复用 address 弹窗和 profile 弹窗样式 */
|
||||
.avatar-btn {
|
||||
width: 128rpx;
|
||||
height: 128rpx;
|
||||
margin: 0 auto 32rpx;
|
||||
padding: 0;
|
||||
border-radius: 50%;
|
||||
border: 1rpx solid var(--border);
|
||||
background: var(--bg-input);
|
||||
line-height: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.avatar-img,
|
||||
.avatar-placeholder-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.nickname-input {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
background: var(--bg-input);
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 16rpx;
|
||||
padding: 0 24rpx;
|
||||
font-size: 28rpx;
|
||||
color: var(--text-primary);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.nickname-input::placeholder {
|
||||
color: var(--text-muted);
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
margin-top: 32rpx;
|
||||
}
|
||||
|
||||
.form-actions .btn-secondary,
|
||||
.form-actions .btn-primary {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 80rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@@ -72,12 +72,12 @@ export default function SettingsPage() {
|
||||
<View className='settings-page'>
|
||||
<View className='settings-area'>
|
||||
|
||||
<View className='page-header surface-card mt-20' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='flex-between' style={{ width: '100%' }}>
|
||||
<Text className='back-btn' onTap={() => Taro.navigateBack()}>←</Text>
|
||||
<Text className='page-title'>设置</Text>
|
||||
<View style={{ width: '60px' }} />
|
||||
<View className='page-header settings-header' style={{ paddingTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='back-btn' onTap={() => Taro.navigateBack()}>
|
||||
<Text className='back-arrow'>←</Text>
|
||||
</View>
|
||||
<Text className='page-title'>设置</Text>
|
||||
<View className='header-spacer' />
|
||||
</View>
|
||||
|
||||
{/* 用户卡片 */}
|
||||
@@ -91,7 +91,7 @@ export default function SettingsPage() {
|
||||
<Image className='settings-avatar-icon' src={assetUrl('/icon/个人.png')} mode='aspectFit' />
|
||||
</View>
|
||||
)}
|
||||
<View style={{ marginLeft: '20px' }}>
|
||||
<View className='settings-meta'>
|
||||
<Text className='settings-name'>{user.nickName || '未登录'}</Text>
|
||||
<Text className='settings-id'>ID: {user.openid ? user.openid.slice(-8) : '---'}</Text>
|
||||
</View>
|
||||
@@ -140,7 +140,7 @@ export default function SettingsPage() {
|
||||
</View>
|
||||
)}
|
||||
|
||||
<View style={{ height: '40px' }} />
|
||||
<View style={{ height: '80rpx' }} />
|
||||
|
||||
{/* 编辑弹窗 */}
|
||||
{showEdit && (
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgb(28, 22, 18);
|
||||
background: var(--bg-page);
|
||||
}
|
||||
|
||||
/* --- Fixed Hero Area --- */
|
||||
@@ -18,7 +18,7 @@
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 65vh; /* hero takes 65% viewport height */
|
||||
height: 65vh;
|
||||
z-index: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
@@ -56,22 +56,22 @@
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 2;
|
||||
padding: 80rpx 40rpx 24rpx;
|
||||
padding: 96rpx 40rpx calc(24rpx + env(safe-area-inset-bottom));
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.shop-hero-title {
|
||||
font-size: 40rpx;
|
||||
font-size: 44rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1.3;
|
||||
color: #f0e6d8;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.shop-hero-subtitle {
|
||||
font-size: 22rpx;
|
||||
color: #b0a395;
|
||||
font-size: 24rpx;
|
||||
color: var(--text-secondary);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@@ -92,7 +92,7 @@
|
||||
|
||||
.shop-hero-original {
|
||||
font-size: 26rpx;
|
||||
color: #8a7e72;
|
||||
color: var(--text-muted);
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
}
|
||||
|
||||
.shop-content {
|
||||
min-height: 100vh; /* ensure scrollability */
|
||||
min-height: 100vh;
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 4;
|
||||
padding: 40rpx 40rpx 32rpx;
|
||||
padding: 24rpx 40rpx 24rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10rpx;
|
||||
@@ -122,15 +122,15 @@
|
||||
}
|
||||
|
||||
.shop-band-title {
|
||||
font-size: 44rpx;
|
||||
font-size: 40rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1.3;
|
||||
color: #f0e6d8;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.shop-band-subtitle {
|
||||
font-size: 24rpx;
|
||||
color: #b0a395;
|
||||
color: var(--text-secondary);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@@ -144,59 +144,74 @@
|
||||
}
|
||||
|
||||
.shop-band-price {
|
||||
font-size: 48rpx;
|
||||
font-size: 40rpx;
|
||||
font-weight: 700;
|
||||
color: var(--accent-primary);
|
||||
}
|
||||
|
||||
.shop-band-original {
|
||||
font-size: 26rpx;
|
||||
color: #8a7e72;
|
||||
color: var(--text-muted);
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
/* --- Detail Body --- */
|
||||
.shop-detail-body {
|
||||
padding: 32rpx 40rpx 60rpx;
|
||||
padding: 0 32rpx calc(48rpx + env(safe-area-inset-bottom));
|
||||
will-change: opacity, transform;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.shop-content-card {
|
||||
padding: 32rpx;
|
||||
background: var(--bg-card);
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 32rpx;
|
||||
box-shadow: var(--shadow-card);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.shop-section {
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.shop-section:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.shop-section-title {
|
||||
font-size: 34rpx;
|
||||
font-weight: 700;
|
||||
color: #f0e6d8;
|
||||
margin: 28rpx 0 20rpx;
|
||||
color: var(--text-primary);
|
||||
margin: 0 0 20rpx;
|
||||
display: block;
|
||||
position: relative;
|
||||
padding-left: 20rpx;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.shop-section-title::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 6rpx;
|
||||
bottom: 6rpx;
|
||||
top: 8rpx;
|
||||
bottom: 8rpx;
|
||||
width: 6rpx;
|
||||
border-radius: 4rpx;
|
||||
background: linear-gradient(180deg, var(--accent-primary), var(--accent-primary-soft));
|
||||
border-radius: 999rpx;
|
||||
background: var(--accent-primary);
|
||||
}
|
||||
|
||||
.shop-section-text {
|
||||
font-size: 28rpx;
|
||||
color: #c4b8a8;
|
||||
line-height: 1.75;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.8;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.shop-divider {
|
||||
height: 2rpx;
|
||||
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.08), transparent);
|
||||
margin: 40rpx 0;
|
||||
height: 1rpx;
|
||||
background: var(--border);
|
||||
margin: 32rpx 0;
|
||||
}
|
||||
|
||||
/* --- Tags --- */
|
||||
@@ -208,10 +223,11 @@
|
||||
}
|
||||
|
||||
.shop-tag {
|
||||
padding: 10rpx 28rpx;
|
||||
border-radius: 40rpx;
|
||||
height: 56rpx;
|
||||
padding: 0 28rpx;
|
||||
border-radius: 999rpx;
|
||||
font-size: 22rpx;
|
||||
font-weight: 500;
|
||||
font-weight: 600;
|
||||
background: var(--accent-primary-soft);
|
||||
border: 1rpx solid var(--accent-primary);
|
||||
display: inline-flex;
|
||||
@@ -226,16 +242,16 @@
|
||||
/* --- Spec Table --- */
|
||||
.shop-spec-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border-radius: 16rpx;
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 20rpx;
|
||||
overflow: hidden;
|
||||
font-size: 26rpx;
|
||||
background: var(--bg-muted);
|
||||
}
|
||||
|
||||
.shop-spec-row {
|
||||
display: flex;
|
||||
padding: 20rpx 24rpx;
|
||||
border-bottom: 1rpx solid rgba(255,255,255,0.06);
|
||||
padding: 24rpx 28rpx;
|
||||
border-bottom: 1rpx solid var(--border);
|
||||
}
|
||||
|
||||
.shop-spec-row:last-child {
|
||||
@@ -244,14 +260,16 @@
|
||||
|
||||
.shop-spec-key {
|
||||
width: 35%;
|
||||
color: #8a7e72;
|
||||
color: var(--text-muted);
|
||||
font-weight: 500;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.shop-spec-val {
|
||||
flex: 1;
|
||||
color: #e8e0d6;
|
||||
color: var(--text-primary);
|
||||
font-size: 26rpx;
|
||||
font-weight: 500;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
@@ -268,11 +286,11 @@
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
border-radius: 50%;
|
||||
background: rgba(0, 0, 0, 0.35);
|
||||
backdrop-filter: blur(16rpx) saturate(1.4);
|
||||
-webkit-backdrop-filter: blur(16rpx) saturate(1.4);
|
||||
border: 1rpx solid rgba(255,255,255,0.12);
|
||||
box-shadow: var(--shadow-card);
|
||||
background: rgba(40, 35, 32, 0.5);
|
||||
backdrop-filter: blur(16px) saturate(1.4);
|
||||
-webkit-backdrop-filter: blur(16px) saturate(1.4);
|
||||
border: 1rpx solid var(--glass-line);
|
||||
box-shadow: var(--shadow-elevated);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -285,15 +303,25 @@
|
||||
|
||||
.shop-back-arrow {
|
||||
font-size: 36rpx;
|
||||
color: rgba(255,255,255,0.85);
|
||||
color: var(--text-primary);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* --- Bottom Action Bar — 样式由全局 .action-bar 提供,本地只补充价格摘要 --- */
|
||||
.action-bar .price-summary {
|
||||
/* --- Bottom Action Bar — 毛玻璃由 BottomActionBar 提供,本地只补充价格摘要 --- */
|
||||
.bottom-action-bar .price-summary {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.bottom-action-bar .btn-primary,
|
||||
.bottom-action-bar .btn-secondary {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 28rpx 0;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.summary-label {
|
||||
font-size: 22rpx;
|
||||
color: var(--text-secondary);
|
||||
|
||||
@@ -8,6 +8,7 @@ import { useSafeArea } from '../../../hooks/useSafeArea'
|
||||
import { useStatusBar } from '../../../hooks/useStatusBar'
|
||||
import { useThemeContext } from '../../../context/ThemeContext'
|
||||
import ThemedPageMeta from '../../../components/ThemedPageMeta'
|
||||
import BottomActionBar from '../../../components/BottomActionBar'
|
||||
|
||||
const clamp = (v: number, min: number, max: number) => Math.min(Math.max(v, min), max)
|
||||
const lerp = (a: number, b: number, t: number) => a + (b - a) * t
|
||||
@@ -210,49 +211,59 @@ export default function ShopDetailPage() {
|
||||
transform: `translateY(${heroStyles.contentOffset}px)`
|
||||
}}
|
||||
>
|
||||
{product.story && (
|
||||
<View className="shop-section">
|
||||
<Text className="shop-section-title">设计理念</Text>
|
||||
<Text className="shop-section-text">{product.story}</Text>
|
||||
</View>
|
||||
)}
|
||||
|
||||
<View className="shop-divider" />
|
||||
|
||||
{product.scene && (
|
||||
<View className="shop-section">
|
||||
<Text className="shop-section-title">使用场景</Text>
|
||||
<Text className="shop-section-text">{product.scene}</Text>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{product.tags && product.tags.length > 0 && (
|
||||
<View className="shop-section">
|
||||
<View className="shop-tag-row">
|
||||
{product.tags.map(tag => (
|
||||
<View key={tag} className="shop-tag">
|
||||
<Text className="shop-tag-text">{tag}</Text>
|
||||
</View>
|
||||
))}
|
||||
<View className="shop-content-card">
|
||||
{product.story && (
|
||||
<View className="shop-section">
|
||||
<Text className="shop-section-title">设计理念</Text>
|
||||
<Text className="shop-section-text">{product.story}</Text>
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
)}
|
||||
|
||||
<View className="shop-divider" />
|
||||
{(product.story && product.scene) && (
|
||||
<View className="shop-divider" />
|
||||
)}
|
||||
|
||||
{product.specs && product.specs.length > 0 && (
|
||||
<View className="shop-section">
|
||||
<Text className="shop-section-title">规格参数</Text>
|
||||
<View className="shop-spec-table">
|
||||
{product.specs.map(([k, v]) => (
|
||||
<View key={k} className="shop-spec-row">
|
||||
<Text className="shop-spec-key">{k}</Text>
|
||||
<Text className="shop-spec-val">{v}</Text>
|
||||
</View>
|
||||
))}
|
||||
{product.scene && (
|
||||
<View className="shop-section">
|
||||
<Text className="shop-section-title">使用场景</Text>
|
||||
<Text className="shop-section-text">{product.scene}</Text>
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
)}
|
||||
|
||||
{product.tags && product.tags.length > 0 && (
|
||||
<View className="shop-section">
|
||||
<View className="shop-tag-row">
|
||||
{product.tags.map(tag => (
|
||||
<View key={tag} className="shop-tag">
|
||||
<Text className="shop-tag-text">{tag}</Text>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{((product.story || product.scene) && product.tags && product.tags.length > 0) && (
|
||||
<View className="shop-divider" />
|
||||
)}
|
||||
|
||||
{((product.story || product.scene || (product.tags && product.tags.length > 0)) && product.specs && product.specs.length > 0) && (
|
||||
<View className="shop-divider" />
|
||||
)}
|
||||
|
||||
{product.specs && product.specs.length > 0 && (
|
||||
<View className="shop-section">
|
||||
<Text className="shop-section-title">规格参数</Text>
|
||||
<View className="shop-spec-table">
|
||||
{product.specs.map(([k, v]) => (
|
||||
<View key={k} className="shop-spec-row">
|
||||
<Text className="shop-spec-key">{k}</Text>
|
||||
<Text className="shop-spec-val">{v}</Text>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
|
||||
<View className="shop-bottom-spacer" />
|
||||
</View>
|
||||
@@ -268,8 +279,8 @@ export default function ShopDetailPage() {
|
||||
<Text className="shop-back-arrow">←</Text>
|
||||
</View>
|
||||
|
||||
{/* Bottom CTA — 全局毛玻璃 action-bar,沿用 product/checkout 模式 */}
|
||||
<View className="action-bar">
|
||||
{/* Bottom CTA — 复用毛玻璃 BottomActionBar */}
|
||||
<BottomActionBar>
|
||||
<View className="price-summary">
|
||||
<Text className="summary-label">起价</Text>
|
||||
<Text className="summary-price">¥{product.price}</Text>
|
||||
@@ -283,7 +294,7 @@ export default function ShopDetailPage() {
|
||||
<View className="btn-primary" onTap={() => Taro.navigateTo({ url: `/pages/product/index?id=${product.id}` })}>
|
||||
<Text>立即定制</Text>
|
||||
</View>
|
||||
</View>
|
||||
</BottomActionBar>
|
||||
<View className="safe-bottom-placeholder" />
|
||||
</View>
|
||||
)
|
||||
|
||||
@@ -4,19 +4,19 @@
|
||||
|
||||
/* --- List Layer --- */
|
||||
.shop-list {
|
||||
padding: 0 24rpx 24rpx;
|
||||
padding: 0 32rpx 24rpx;
|
||||
}
|
||||
|
||||
.shop-header {
|
||||
text-align: center;
|
||||
padding: 40rpx 0 24rpx;
|
||||
padding: 48rpx 0 32rpx;
|
||||
}
|
||||
|
||||
.shop-header-title {
|
||||
font-size: 40rpx;
|
||||
font-weight: 800;
|
||||
font-size: 44rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
letter-spacing: 4rpx;
|
||||
letter-spacing: 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
@@ -31,10 +31,11 @@
|
||||
.shop-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 20rpx;
|
||||
gap: 24rpx;
|
||||
}
|
||||
|
||||
.shop-card {
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 24rpx;
|
||||
overflow: hidden;
|
||||
background: var(--bg-card);
|
||||
@@ -43,13 +44,13 @@
|
||||
}
|
||||
|
||||
.shop-card:active {
|
||||
transform: scale(0.97);
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
.shop-card-img-wrap {
|
||||
aspect-ratio: 3 / 4;
|
||||
aspect-ratio: 1 / 1;
|
||||
overflow: hidden;
|
||||
background: #2a2218;
|
||||
background: var(--bg-muted);
|
||||
}
|
||||
|
||||
.shop-card-img {
|
||||
@@ -59,27 +60,39 @@
|
||||
transition: transform 0.4s ease;
|
||||
}
|
||||
|
||||
.shop-card-info {
|
||||
padding: 16rpx 20rpx 20rpx;
|
||||
.shop-card-body {
|
||||
padding: 20rpx 24rpx 24rpx;
|
||||
}
|
||||
|
||||
.shop-card-name {
|
||||
font-size: 26rpx;
|
||||
color: #e8e0d6;
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
line-height: 1.4;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
min-height: 74rpx;
|
||||
}
|
||||
|
||||
.shop-card-desc {
|
||||
font-size: 24rpx;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.4;
|
||||
margin-top: 8rpx;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.shop-card-price {
|
||||
font-size: 30rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: var(--accent-primary);
|
||||
margin-top: 10rpx;
|
||||
margin-top: 12rpx;
|
||||
display: block;
|
||||
font-variant: tabular-nums;
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
|
||||
@@ -27,7 +27,6 @@ export default function ShopPage() {
|
||||
|
||||
<View className="shop-grid">
|
||||
{PRODUCTS.map(product => {
|
||||
const tone = product.tone || [28, 22, 18]
|
||||
const imageSrc = product.images[0] || product.iconImg || ''
|
||||
return (
|
||||
<View
|
||||
@@ -43,13 +42,9 @@ export default function ShopPage() {
|
||||
lazyLoad
|
||||
/>
|
||||
</View>
|
||||
<View
|
||||
className="shop-card-info"
|
||||
style={{
|
||||
backgroundColor: `rgba(${tone[0]}, ${tone[1]}, ${tone[2]}, 0.92)`
|
||||
}}
|
||||
>
|
||||
<View className="shop-card-body">
|
||||
<Text className="shop-card-name">{product.name}</Text>
|
||||
<Text className="shop-card-desc">{product.desc || ''}</Text>
|
||||
<Text className="shop-card-price">¥{product.price}</Text>
|
||||
</View>
|
||||
</View>
|
||||
@@ -57,8 +52,6 @@ export default function ShopPage() {
|
||||
})}
|
||||
</View>
|
||||
|
||||
{/* TabBar spacer so list isn't obscured */}
|
||||
<View style={{ height: '200px' }} />
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
|
||||
@@ -1,90 +1,140 @@
|
||||
/* ============================================================
|
||||
UserDatabase Page — 本地用户数据库
|
||||
============================================================ */
|
||||
|
||||
.udb-page {
|
||||
padding: 0 24px 40px;
|
||||
padding: 0 32rpx calc(24rpx + env(safe-area-inset-bottom));
|
||||
min-height: 100vh;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 锁屏验证 */
|
||||
.udb-lock-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.udb-lock-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 60px 40px;
|
||||
padding: 64rpx 40rpx;
|
||||
text-align: center;
|
||||
margin-top: 48rpx;
|
||||
}
|
||||
|
||||
.udb-lock-icon {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
margin-bottom: 24px;
|
||||
width: 96rpx;
|
||||
height: 96rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.udb-lock-title {
|
||||
font-size: 36px;
|
||||
display: block;
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 12px;
|
||||
display: block;
|
||||
margin-bottom: 12rpx;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.udb-lock-desc {
|
||||
font-size: 26px;
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 32px;
|
||||
display: block;
|
||||
font-size: 26rpx;
|
||||
line-height: 1.6;
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.udb-password-input {
|
||||
width: 100%;
|
||||
height: 80px;
|
||||
height: 88rpx;
|
||||
background: var(--bg-input);
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 16px;
|
||||
padding: 0 24px;
|
||||
font-size: 30px;
|
||||
border-radius: 16rpx;
|
||||
padding: 0 24rpx;
|
||||
box-sizing: border-box;
|
||||
font-size: 30rpx;
|
||||
color: var(--text-primary);
|
||||
text-align: center;
|
||||
margin-bottom: 24px;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.udb-password-input::placeholder {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.udb-error {
|
||||
font-size: 24px;
|
||||
color: var(--danger);
|
||||
margin-bottom: 20px;
|
||||
display: block;
|
||||
font-size: 24rpx;
|
||||
line-height: 1.5;
|
||||
color: var(--danger);
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.udb-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
padding: 20px 0;
|
||||
font-size: 30px;
|
||||
height: 96rpx;
|
||||
box-sizing: border-box;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 顶部标题 */
|
||||
.page-header.udb-header {
|
||||
min-height: 88rpx;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-bottom: 24rpx;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.udb-header .page-title {
|
||||
text-align: center;
|
||||
font-size: 44rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
/* 工具栏 */
|
||||
.udb-toolbar {
|
||||
margin: 20px 0;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin: 8rpx 0 24rpx;
|
||||
}
|
||||
|
||||
.udb-add-btn {
|
||||
padding: 14px 28px;
|
||||
font-size: 26px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 80rpx;
|
||||
padding: 0 32rpx;
|
||||
box-sizing: border-box;
|
||||
font-size: 26rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 数据表格 */
|
||||
.udb-table {
|
||||
background: var(--bg-card);
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 24px;
|
||||
border-radius: 24rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: var(--shadow-card);
|
||||
}
|
||||
|
||||
.udb-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20px 16px;
|
||||
min-height: 112rpx;
|
||||
padding: 16rpx 24rpx;
|
||||
border-bottom: 1rpx solid var(--border);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.udb-row:last-child {
|
||||
@@ -93,31 +143,31 @@
|
||||
|
||||
.udb-header {
|
||||
background: var(--bg-input);
|
||||
padding: 16px;
|
||||
min-height: 80rpx;
|
||||
}
|
||||
|
||||
.udb-header .udb-col {
|
||||
font-weight: 700;
|
||||
font-size: 24px;
|
||||
font-size: 24rpx;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.udb-col {
|
||||
font-size: 24px;
|
||||
font-size: 24rpx;
|
||||
color: var(--text-secondary);
|
||||
flex-shrink: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
padding: 0 6px;
|
||||
padding: 0 8rpx;
|
||||
}
|
||||
|
||||
.col-nick {
|
||||
flex: 0 0 22%;
|
||||
flex: 0 0 24%;
|
||||
}
|
||||
|
||||
.col-id {
|
||||
flex: 0 0 36%;
|
||||
flex: 0 0 32%;
|
||||
}
|
||||
|
||||
.col-stats {
|
||||
@@ -127,10 +177,12 @@
|
||||
|
||||
.col-action {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
gap: 12rpx;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.udb-row.active {
|
||||
@@ -138,11 +190,13 @@
|
||||
}
|
||||
|
||||
.udb-link {
|
||||
padding: 6px 14px;
|
||||
border-radius: 8px;
|
||||
font-size: 22px;
|
||||
padding: 10rpx 20rpx;
|
||||
border-radius: 999rpx;
|
||||
font-size: 22rpx;
|
||||
line-height: 1.2;
|
||||
color: var(--accent-secondary);
|
||||
background: var(--accent-secondary-soft);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.udb-danger {
|
||||
@@ -151,55 +205,78 @@
|
||||
}
|
||||
|
||||
.udb-current {
|
||||
font-size: 22px;
|
||||
font-size: 22rpx;
|
||||
color: var(--accent-secondary);
|
||||
font-weight: 600;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.udb-empty {
|
||||
padding: 40px;
|
||||
padding: 80rpx 24rpx;
|
||||
text-align: center;
|
||||
color: var(--text-secondary);
|
||||
font-size: 28px;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
/* 新建账号弹窗 */
|
||||
.udb-page .modal-overlay {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 48rpx;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
/* 弹窗 */
|
||||
.udb-add-card {
|
||||
padding: 48px 36px;
|
||||
width: 80%;
|
||||
width: 100%;
|
||||
max-width: 640rpx;
|
||||
padding: 40rpx;
|
||||
border-radius: 32rpx;
|
||||
background: var(--bg-card);
|
||||
border: 1rpx solid var(--border);
|
||||
box-shadow: var(--shadow-elevated);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.udb-add-title {
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 24px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 32rpx;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.udb-add-input {
|
||||
width: 100%;
|
||||
height: 80px;
|
||||
height: 88rpx;
|
||||
background: var(--bg-input);
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 16px;
|
||||
padding: 0 24px;
|
||||
font-size: 28px;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 32px;
|
||||
border-radius: 16rpx;
|
||||
padding: 0 24rpx;
|
||||
box-sizing: border-box;
|
||||
font-size: 28rpx;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.udb-add-input::placeholder {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.udb-add-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.udb-add-actions .btn-secondary,
|
||||
.udb-add-actions .btn-primary {
|
||||
flex: 1;
|
||||
padding: 18px 0;
|
||||
text-align: center;
|
||||
height: 80rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@@ -86,8 +86,8 @@ export default function UserDatabasePage() {
|
||||
return (
|
||||
<View className={`theme-${resolvedTheme}`}>
|
||||
<ThemedPageMeta />
|
||||
<View className='udb-page'>
|
||||
<View className='udb-lock-card surface-card mt-20'>
|
||||
<View className='udb-page udb-lock-page' style={{ paddingTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='udb-lock-card surface-card'>
|
||||
<Image className='udb-lock-icon' src={assetUrl('/icon/账号管理.png')} mode='aspectFit' />
|
||||
<Text className='udb-lock-title'>管理员验证</Text>
|
||||
<Text className='udb-lock-desc'>请输入密码以访问用户数据库</Text>
|
||||
@@ -116,7 +116,7 @@ export default function UserDatabasePage() {
|
||||
<ThemedPageMeta />
|
||||
<View className='udb-page'>
|
||||
|
||||
<View className='page-header surface-card mt-20' style={{ marginTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='page-header udb-header' style={{ paddingTop: `${safe.headerPaddingTop}px` }}>
|
||||
<Text className='page-title'>本地用户数据库</Text>
|
||||
</View>
|
||||
|
||||
|
||||
@@ -1,68 +1,125 @@
|
||||
/* ============================================================
|
||||
WordCloud Page — AI 词云生成
|
||||
============================================================ */
|
||||
|
||||
.wordcloud-page {
|
||||
min-height: 100vh;
|
||||
padding: 0 24px 24px;
|
||||
padding: 0 32rpx calc(24rpx + env(safe-area-inset-bottom));
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 顶部导航 */
|
||||
.page-header {
|
||||
padding: calc(env(safe-area-inset-top, 0px) + 44px) 32px 24px;
|
||||
margin: 20px 0 0;
|
||||
.page-header.cloud-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
min-height: 88rpx;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-bottom: 24rpx;
|
||||
margin: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.back-btn {
|
||||
font-size: 40px;
|
||||
.cloud-header .back-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
flex: 0 0 auto;
|
||||
border-radius: 50%;
|
||||
background: var(--bg-card);
|
||||
border: 1rpx solid var(--border-strong);
|
||||
box-shadow: var(--shadow-card);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.cloud-header .back-btn:active {
|
||||
transform: scale(0.96);
|
||||
}
|
||||
|
||||
.cloud-header .back-arrow {
|
||||
font-size: 36rpx;
|
||||
line-height: 1;
|
||||
color: var(--text-primary);
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.cloud-header .page-title {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
text-align: center;
|
||||
font-size: 34rpx;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.header-spacer {
|
||||
width: 88rpx;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
/* 步骤指示器 */
|
||||
.step-indicator {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-items: stretch;
|
||||
justify-content: center;
|
||||
padding: 32px;
|
||||
margin: 0 24px;
|
||||
padding: 32rpx 16rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.step-item {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.step-circle {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border-radius: 50%;
|
||||
background: var(--bg-input);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 12px;
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
border-radius: 50%;
|
||||
background: var(--bg-muted);
|
||||
border: 1rpx solid var(--border);
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 12rpx;
|
||||
transition: background 160ms ease, border-color 160ms ease, box-shadow 160ms ease;
|
||||
}
|
||||
|
||||
.step-circle.active {
|
||||
background: var(--accent-primary);
|
||||
border-color: var(--accent-primary);
|
||||
box-shadow: 0 0 0 8rpx var(--accent-primary-soft);
|
||||
}
|
||||
|
||||
.step-num {
|
||||
font-size: 28px;
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.step-circle.active .step-num {
|
||||
color: #fff;
|
||||
color: var(--bg-page);
|
||||
}
|
||||
|
||||
.step-label {
|
||||
font-size: 24px;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 24rpx;
|
||||
color: var(--text-secondary);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.step-label.active {
|
||||
@@ -72,11 +129,12 @@
|
||||
|
||||
.step-line {
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
top: 31rpx;
|
||||
left: 60%;
|
||||
width: 100%;
|
||||
height: 4px;
|
||||
height: 4rpx;
|
||||
background: var(--bg-input);
|
||||
border-radius: 999rpx;
|
||||
}
|
||||
|
||||
.step-line.active {
|
||||
@@ -85,105 +143,144 @@
|
||||
|
||||
/* 步骤内容 */
|
||||
.step-content {
|
||||
padding: 32px;
|
||||
padding: 0 0 32rpx;
|
||||
}
|
||||
|
||||
/* 上传区域 */
|
||||
/* 上传底图 */
|
||||
.upload-area {
|
||||
min-height: 400px;
|
||||
min-height: 420rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 24rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.upload-placeholder {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 60px;
|
||||
padding: 64rpx 48rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.upload-icon {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
margin-bottom: 24px;
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.upload-title {
|
||||
font-size: 32px;
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 12px;
|
||||
margin-bottom: 12rpx;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.upload-desc {
|
||||
font-size: 26px;
|
||||
font-size: 26rpx;
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 16px;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.upload-tip {
|
||||
font-size: 22px;
|
||||
font-size: 22rpx;
|
||||
line-height: 1.5;
|
||||
color: var(--accent-secondary);
|
||||
background: var(--accent-secondary-soft);
|
||||
padding: 8px 20px;
|
||||
padding: 12rpx 24rpx;
|
||||
border-radius: 999rpx;
|
||||
border: 1rpx solid var(--border);
|
||||
}
|
||||
|
||||
.preview-image {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
border-radius: 24px;
|
||||
height: 420rpx;
|
||||
border-radius: 24rpx;
|
||||
}
|
||||
|
||||
/* 按钮 */
|
||||
/* 按钮组 */
|
||||
.action-btns {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
margin-top: 40px;
|
||||
gap: 20rpx;
|
||||
margin-top: 32rpx;
|
||||
}
|
||||
|
||||
/* 输入区域 */
|
||||
.action-btns .btn-primary,
|
||||
.action-btns .btn-secondary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 96rpx;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 输入名单 */
|
||||
.input-section {
|
||||
padding: 32px;
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 24rpx;
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.input-section .section-title {
|
||||
display: block;
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 0;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.names-input {
|
||||
width: 100%;
|
||||
min-height: 300px;
|
||||
min-height: 320rpx;
|
||||
background: var(--bg-input);
|
||||
border-radius: 16px;
|
||||
padding: 24px;
|
||||
font-size: 28px;
|
||||
line-height: 1.6;
|
||||
box-sizing: border-box;
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 16rpx;
|
||||
padding: 24rpx;
|
||||
margin-top: 24rpx;
|
||||
box-sizing: border-box;
|
||||
font-size: 28rpx;
|
||||
line-height: 1.6;
|
||||
color: var(--text-primary);
|
||||
transition: border-color 160ms ease, background 160ms ease, box-shadow 160ms ease;
|
||||
}
|
||||
|
||||
.names-input:focus {
|
||||
border-color: var(--accent-primary);
|
||||
background: var(--bg-card);
|
||||
box-shadow: 0 0 0 6rpx var(--accent-primary-soft);
|
||||
}
|
||||
|
||||
.names-input::placeholder {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.input-stats {
|
||||
display: block;
|
||||
text-align: right;
|
||||
font-size: 24px;
|
||||
font-size: 24rpx;
|
||||
color: var(--text-secondary);
|
||||
margin-top: 12px;
|
||||
margin-top: 12rpx;
|
||||
}
|
||||
|
||||
.input-tips {
|
||||
margin-top: 24px;
|
||||
margin-top: 24rpx;
|
||||
padding: 24rpx;
|
||||
border-radius: 16rpx;
|
||||
background: var(--bg-muted);
|
||||
}
|
||||
|
||||
.tip-item {
|
||||
display: block;
|
||||
font-size: 24px;
|
||||
font-size: 24rpx;
|
||||
line-height: 1.6;
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 8px;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.tip-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* 生成中 */
|
||||
@@ -191,133 +288,155 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 80px 40px;
|
||||
padding: 96rpx 48rpx;
|
||||
background: var(--bg-card);
|
||||
border: 1rpx solid var(--border);
|
||||
border-radius: 24rpx;
|
||||
box-shadow: var(--shadow-card);
|
||||
}
|
||||
|
||||
.generating-icon {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
width: 104rpx;
|
||||
height: 104rpx;
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% { transform: scale(1); opacity: 1; }
|
||||
50% { transform: scale(1.2); opacity: 0.7; }
|
||||
50% { transform: scale(1.12); opacity: 0.72; }
|
||||
}
|
||||
|
||||
.generating-title {
|
||||
font-size: 40px;
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
margin-top: 40px;
|
||||
margin-top: 32rpx;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.generating-subtitle {
|
||||
font-size: 28px;
|
||||
font-size: 26rpx;
|
||||
color: var(--text-secondary);
|
||||
margin-top: 16px;
|
||||
margin-bottom: 40px;
|
||||
margin-top: 12rpx;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
width: 80%;
|
||||
height: 16px;
|
||||
background: var(--accent-primary-soft);
|
||||
border-radius: 8px;
|
||||
width: 100%;
|
||||
height: 12rpx;
|
||||
background: var(--bg-muted);
|
||||
border-radius: 999rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress-fill {
|
||||
height: 100%;
|
||||
background: var(--accent-primary);
|
||||
border-radius: 8px;
|
||||
border-radius: 999rpx;
|
||||
transition: width 0.5s ease;
|
||||
}
|
||||
|
||||
.progress-text {
|
||||
font-size: 32px;
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
color: var(--accent-primary);
|
||||
margin-top: 16px;
|
||||
margin-top: 16rpx;
|
||||
font-variant: tabular-nums;
|
||||
}
|
||||
|
||||
/* 结果面板 */
|
||||
/* 结果预览 */
|
||||
.result-panel {
|
||||
padding: 20px 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.result-image-wrapper {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
border: 1rpx solid var(--border);
|
||||
overflow: hidden;
|
||||
border-radius: 24rpx;
|
||||
}
|
||||
|
||||
.result-image {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
background: linear-gradient(135deg, var(--accent-primary-soft) 0%, var(--accent-secondary-soft) 100%);
|
||||
height: 520rpx;
|
||||
background: var(--bg-muted);
|
||||
}
|
||||
|
||||
.watermark-badge {
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
right: 24rpx;
|
||||
bottom: 24rpx;
|
||||
padding: 10rpx 20rpx;
|
||||
border-radius: 999rpx;
|
||||
background: var(--glass);
|
||||
border: 1rpx solid var(--glass-line);
|
||||
font-size: 22rpx;
|
||||
color: var(--text-primary);
|
||||
padding: 8px 20px;
|
||||
border-radius: 8px;
|
||||
font-size: 22px;
|
||||
border: 1rpx solid var(--border);
|
||||
backdrop-filter: blur(24rpx);
|
||||
-webkit-backdrop-filter: blur(24rpx);
|
||||
}
|
||||
|
||||
.result-actions {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
margin: 32px 0;
|
||||
gap: 16rpx;
|
||||
margin: 24rpx 0 0;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
padding: 24rpx 8rpx;
|
||||
border-radius: 24rpx;
|
||||
background: var(--bg-card);
|
||||
border: 1rpx solid var(--border);
|
||||
box-shadow: var(--shadow-card);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
gap: 10rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.action-btn:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
.action-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin-bottom: 8px;
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
}
|
||||
|
||||
.action-label {
|
||||
font-size: 24px;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 22rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* 跳转DIY卡片 */
|
||||
/* 跳转DIY卡片(保留旧样式,便于后续扩展) */
|
||||
.diy-jump-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 32px;
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.diy-jump-title {
|
||||
font-size: 32px;
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.diy-jump-desc {
|
||||
font-size: 24px;
|
||||
font-size: 24rpx;
|
||||
color: var(--text-secondary);
|
||||
display: block;
|
||||
}
|
||||
|
||||
.diy-jump-arrow {
|
||||
font-size: 40px;
|
||||
font-size: 40rpx;
|
||||
color: var(--accent-primary);
|
||||
}
|
||||
|
||||
@@ -66,10 +66,12 @@ export default function WordCloudPage() {
|
||||
<ThemedPageMeta />
|
||||
<View className='wordcloud-page'>
|
||||
|
||||
<View className='page-header flex-between' style={{ paddingTop: `${safe.headerPaddingTop}px` }}>
|
||||
<Text className='back-btn' onTap={goBack}>←</Text>
|
||||
<View className='page-header cloud-header' style={{ paddingTop: `${safe.headerPaddingTop}px` }}>
|
||||
<View className='back-btn' onTap={goBack}>
|
||||
<Text className='back-arrow'>←</Text>
|
||||
</View>
|
||||
<Text className='page-title'>AI词云生成</Text>
|
||||
<View style={{ width: '60px' }} />
|
||||
<View className='header-spacer' />
|
||||
</View>
|
||||
|
||||
{/* 步骤指示器 */}
|
||||
|
||||
@@ -0,0 +1,529 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>TabBar 指示器调试器</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg-page: #faf7f2;
|
||||
--bg-card: #ffffff;
|
||||
--text: #2e2622;
|
||||
--text-2: #8a7e76;
|
||||
--border: #ede5dc;
|
||||
--accent: #d96c6a;
|
||||
--glass: rgba(255, 255, 255, 0.55);
|
||||
--glass-line: rgba(255, 255, 255, 0.55);
|
||||
--shadow: rgba(46, 38, 34, 0.18);
|
||||
--ind: rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
html.theme-dark {
|
||||
--bg-page: #191919;
|
||||
--bg-card: #23201d;
|
||||
--text: #f5efe8;
|
||||
--text-2: #b3a79c;
|
||||
--border: #37312c;
|
||||
--accent: #f09198;
|
||||
--glass: rgba(25, 25, 25, 0.55);
|
||||
--glass-line: rgba(255, 255, 255, 0.14);
|
||||
--shadow: rgba(0, 0, 0, 0.5);
|
||||
--ind: rgba(255, 255, 255, 0.16);
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
|
||||
background: var(--bg-page);
|
||||
color: var(--text);
|
||||
min-height: 100vh;
|
||||
transition: background .2s, color .2s;
|
||||
}
|
||||
.appbar {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 5;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
padding: 16px 24px;
|
||||
background: var(--bg-card);
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.appbar h1 { margin: 0; font-size: 18px; font-weight: 700; letter-spacing: 0; }
|
||||
.actions { display: flex; gap: 8px; flex-wrap: wrap; }
|
||||
button {
|
||||
font: inherit;
|
||||
border: 1px solid var(--border);
|
||||
background: var(--bg-card);
|
||||
color: var(--text);
|
||||
border-radius: 999px;
|
||||
padding: 8px 16px;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
}
|
||||
button.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
|
||||
button:active { transform: scale(0.98); }
|
||||
.layout {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(280px, 380px) 1fr;
|
||||
gap: 24px;
|
||||
max-width: 1080px;
|
||||
margin: 0 auto;
|
||||
padding: 24px;
|
||||
}
|
||||
.controls {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
align-self: start;
|
||||
padding: 18px;
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 16px;
|
||||
}
|
||||
.group-title { font-size: 13px; font-weight: 700; margin: 4px 0 8px; letter-spacing: 0; }
|
||||
.group { border-top: 1px solid var(--border); padding-top: 12px; }
|
||||
.field { margin-bottom: 12px; }
|
||||
.field label {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 13px;
|
||||
color: var(--text-2);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.field output { color: var(--accent); font-variant-numeric: tabular-nums; }
|
||||
input[type=range] { width: 100%; accent-color: var(--accent); }
|
||||
.output { margin-top: 4px; }
|
||||
.output .group-title { display: flex; justify-content: space-between; align-items: center; }
|
||||
.output textarea {
|
||||
width: 100%;
|
||||
min-height: 118px;
|
||||
resize: vertical;
|
||||
font: 11px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 10px;
|
||||
padding: 10px;
|
||||
background: var(--bg-page);
|
||||
color: var(--text);
|
||||
}
|
||||
.hint { font-size: 12px; color: var(--text-2); margin: 6px 0 0; line-height: 1.5; }
|
||||
.preview { display: flex; align-items: center; justify-content: center; }
|
||||
.phone {
|
||||
width: min(100%, 380px);
|
||||
aspect-ratio: 9 / 18.5;
|
||||
border-radius: 44px;
|
||||
background: var(--bg-card);
|
||||
box-shadow: 0 24px 60px var(--shadow);
|
||||
padding: 12px;
|
||||
}
|
||||
.screen {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 34px;
|
||||
overflow: hidden;
|
||||
background: var(--bg-page);
|
||||
}
|
||||
.feed {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
padding: 52px 24px 220px;
|
||||
overflow-y: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
touch-action: pan-y;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
.feed::-webkit-scrollbar { display: none; }
|
||||
.card {
|
||||
flex: 0 0 auto;
|
||||
padding: 10px;
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 14px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 7px;
|
||||
}
|
||||
.img { height: 86px; border-radius: 10px; }
|
||||
.g1 { background: linear-gradient(145deg, #e08e8b, #7c8bd6); }
|
||||
.g2 { background: linear-gradient(205deg, #67c58e, #d9a35e); }
|
||||
.g3 { background: linear-gradient(120deg, #d96c6a, #e6c08a); }
|
||||
.g4 { background: linear-gradient(160deg, #8e97e8, #5faa8a); }
|
||||
.ln {
|
||||
height: 9px;
|
||||
border-radius: 6px;
|
||||
background: var(--text-2);
|
||||
opacity: 0.35;
|
||||
}
|
||||
.w90 { width: 90%; }
|
||||
.w85 { width: 85%; }
|
||||
.w80 { width: 80%; }
|
||||
.w75 { width: 75%; }
|
||||
.w70 { width: 70%; }
|
||||
.w65 { width: 65%; }
|
||||
.w60 { width: 60%; }
|
||||
.w55 { width: 55%; }
|
||||
.w50 { width: 50%; }
|
||||
.w45 { width: 45%; }
|
||||
.w40 { width: 40%; }
|
||||
.tiles { display: flex; gap: 8px; }
|
||||
.t { width: 44px; height: 44px; border-radius: 12px; flex: 0 0 auto; }
|
||||
.t1 { background: #e07a72; }
|
||||
.t2 { background: #6c7bdb; }
|
||||
.t3 { background: #4fa477; }
|
||||
.t4 { background: #d9a35e; }
|
||||
.t5 { background: #8e97e8; }
|
||||
.gradient {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
.pill {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
border-radius: 28px;
|
||||
background: var(--glass);
|
||||
border: 1px solid var(--glass-line);
|
||||
backdrop-filter: blur(32px) saturate(1.2);
|
||||
-webkit-backdrop-filter: blur(32px) saturate(1.2);
|
||||
box-shadow: 0 12px 40px var(--shadow);
|
||||
}
|
||||
.tab {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 2px;
|
||||
min-width: 0;
|
||||
color: var(--text-2);
|
||||
font-size: 10px;
|
||||
}
|
||||
.tab.active { color: var(--accent); font-weight: 700; }
|
||||
.tab svg, .tab > span { position: relative; z-index: 1; }
|
||||
.tab svg { width: 22px; height: 22px; }
|
||||
.ind {
|
||||
position: absolute;
|
||||
background: var(--ind);
|
||||
}
|
||||
@media (max-width: 760px) {
|
||||
.layout { grid-template-columns: 1fr; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="theme-light">
|
||||
<header class="appbar">
|
||||
<h1>TabBar 指示器调试器</h1>
|
||||
<div class="actions">
|
||||
<button id="themeBtn">切换到深色</button>
|
||||
<button id="copyCss" type="button">复制 SCSS</button>
|
||||
<button id="copyJson" class="primary" type="button">复制参数</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="layout">
|
||||
<section class="controls" aria-label="参数调节">
|
||||
<div class="group">
|
||||
<div class="group-title">选中指示器</div>
|
||||
<div class="field">
|
||||
<label>高度 <output id="vIndHeight">50</output> px</label>
|
||||
<input id="indHeight" type="range" min="8" max="64" step="1" value="50">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>左右贴边 <output id="vIndSide">-18</output> px</label>
|
||||
<input id="indSide" type="range" min="-20" max="30" step="1" value="-18">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>底部贴边 <output id="vIndBottom">3</output> px</label>
|
||||
<input id="indBottom" type="range" min="-20" max="20" step="1" value="3">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>圆角 <output id="vIndRadius">25</output> px</label>
|
||||
<input id="indRadius" type="range" min="0" max="40" step="1" value="25">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>宽度 <output id="vIndWidth">60</output> px</label>
|
||||
<input id="indWidth" type="range" min="0" max="160" step="1" value="60">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>不透明度 <output id="vIndOpacity">14</output> %</label>
|
||||
<input id="indOpacity" type="range" min="0" max="100" step="1" value="14">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>阴影模糊 <output id="vIndBlur">3</output> px</label>
|
||||
<input id="indBlur" type="range" min="0" max="30" step="1" value="3">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>底色 <output id="vIndColor">#000000</output></label>
|
||||
<input id="indColor" type="color" value="#000000">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="output">
|
||||
<div class="group">
|
||||
<div class="group-title">导出的参数</div>
|
||||
<textarea id="jsonOut" readonly aria-label="导出的参数"></textarea>
|
||||
</div>
|
||||
<p class="hint">点「复制参数」把 JSON 发给我;点「复制 SCSS」得到可直接落地的样式代码。</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="preview" aria-label="预览">
|
||||
<div class="phone">
|
||||
<div class="screen">
|
||||
<div class="feed">
|
||||
<div class="card"><div class="img g1"></div><div class="ln w80"></div><div class="ln w55"></div></div>
|
||||
<div class="card"><div class="img g2"></div><div class="ln w70"></div><div class="ln w45"></div></div>
|
||||
<div class="card">
|
||||
<div class="ln w90"></div><div class="ln w60"></div><div class="ln w75"></div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="tiles"><i class="t t1"></i><i class="t t2"></i><i class="t t3"></i></div>
|
||||
<div class="ln w65"></div>
|
||||
</div>
|
||||
<div class="card"><div class="img g3"></div><div class="ln w80"></div><div class="ln w50"></div></div>
|
||||
<div class="card">
|
||||
<div class="ln w85"></div><div class="ln w60"></div><div class="ln w40"></div>
|
||||
</div>
|
||||
<div class="card"><div class="img g4"></div><div class="ln w75"></div></div>
|
||||
<div class="card">
|
||||
<div class="tiles"><i class="t t4"></i><i class="t t5"></i></div>
|
||||
<div class="ln w70"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gradient" id="gradient"></div>
|
||||
<div class="pill" id="pill"></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
const TABS = [
|
||||
['首页', '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m3 10 9-7 9 7"/><path d="M5 9v11h14V9"/><path d="M9 20v-6h6v6"/></svg>'],
|
||||
['商品', '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M21 8 12 3 3 8v8l9 5 9-5Z"/><path d="M3.5 7.5 12 12l8.5-4.5"/><path d="M12 22V12"/></svg>'],
|
||||
['设计', '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22a10 10 0 1 1 10-10c0 2.21-1.79 4-4 4h-2a2 2 0 0 0-2 2c0 .53.2 1 .54 1.36C14.78 21.4 13.5 22 12 22Z"/><circle cx="7.5" cy="10.5" r="1"/><circle cx="12" cy="7.5" r="1"/><circle cx="16.5" cy="10.5" r="1"/></svg>'],
|
||||
['订单', '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4Z"/><path d="M3 6h18"/><path d="M16 10a4 4 0 0 1-8 0"/></svg>'],
|
||||
['我的', '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="8" r="4"/><path d="M4 21s1-5 8-5 8 5 8 5"/></svg>']
|
||||
]
|
||||
|
||||
const ids = {
|
||||
indHeight: document.getElementById('indHeight'),
|
||||
indSide: document.getElementById('indSide'),
|
||||
indBottom: document.getElementById('indBottom'),
|
||||
indRadius: document.getElementById('indRadius'),
|
||||
indWidth: document.getElementById('indWidth'),
|
||||
indOpacity: document.getElementById('indOpacity'),
|
||||
indBlur: document.getElementById('indBlur'),
|
||||
indColor: document.getElementById('indColor'),
|
||||
gradient: document.getElementById('gradient'),
|
||||
pill: document.getElementById('pill'),
|
||||
indicator: document.getElementById('indicator')
|
||||
}
|
||||
|
||||
const val = (el) => Number(el.value)
|
||||
function hexToRgb(hex) {
|
||||
const h = hex.replace('#', '')
|
||||
return {
|
||||
r: parseInt(h.substring(0, 2), 16),
|
||||
g: parseInt(h.substring(2, 4), 16),
|
||||
b: parseInt(h.substring(4, 6), 16)
|
||||
}
|
||||
}
|
||||
|
||||
function themeColors() {
|
||||
return document.body.classList.contains('theme-dark')
|
||||
? { r: 25, g: 25, b: 25, label: 'dark' }
|
||||
: { r: 250, g: 247, b: 242, label: 'light' }
|
||||
}
|
||||
|
||||
function buildPill() {
|
||||
ids.pill.innerHTML = TABS.map((t, i) =>
|
||||
'<div class="tab' + (i === 0 ? ' active' : '') + '">' +
|
||||
(i === 0 ? '<div class="ind" id="indicator"></div>' : '') +
|
||||
t[1] + '<span>' + t[0] + '</span></div>'
|
||||
).join('')
|
||||
ids.indicator = document.getElementById('indicator')
|
||||
}
|
||||
|
||||
function currentParams() {
|
||||
const c = themeColors()
|
||||
return {
|
||||
theme: c.label,
|
||||
gradient: {
|
||||
height: 80,
|
||||
bottomOpacity: 50,
|
||||
midStop: 50,
|
||||
midOpacity: 10,
|
||||
endStop: 86
|
||||
},
|
||||
tabBar: {
|
||||
bottom: 18,
|
||||
sideMargin: 18,
|
||||
height: 58,
|
||||
radius: 32
|
||||
},
|
||||
indicator: {
|
||||
width: val(ids.indWidth),
|
||||
height: val(ids.indHeight),
|
||||
sideInset: val(ids.indSide),
|
||||
bottomInset: val(ids.indBottom),
|
||||
radius: val(ids.indRadius),
|
||||
opacity: val(ids.indOpacity),
|
||||
blur: val(ids.indBlur),
|
||||
color: ids.indColor.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function render() {
|
||||
const c = themeColors()
|
||||
const p = currentParams()
|
||||
const g = p.gradient
|
||||
const tb = p.tabBar
|
||||
const ind = p.indicator
|
||||
const mid = Math.max(g.midStop, 1)
|
||||
const end = Math.max(g.endStop, mid + 1)
|
||||
const arr = [
|
||||
'rgba(' + c.r + ',' + c.g + ',' + c.b + ',' + (g.bottomOpacity / 100).toFixed(3) + ') 0%',
|
||||
'rgba(' + c.r + ',' + c.g + ',' + c.b + ',' + (g.midOpacity / 100).toFixed(3) + ') ' + mid + '%',
|
||||
'rgba(' + c.r + ',' + c.g + ',' + c.b + ',0) ' + end + '%'
|
||||
]
|
||||
ids.gradient.style.height = g.height + 'px'
|
||||
ids.gradient.style.background = 'linear-gradient(to top, ' + arr.join(', ') + ')'
|
||||
|
||||
ids.pill.style.bottom = tb.bottom + 'px'
|
||||
ids.pill.style.left = tb.sideMargin + 'px'
|
||||
ids.pill.style.right = tb.sideMargin + 'px'
|
||||
ids.pill.style.height = tb.height + 'px'
|
||||
ids.pill.style.borderRadius = tb.radius + 'px'
|
||||
|
||||
const rgb = hexToRgb(ind.color)
|
||||
const alpha = (ind.opacity / 100).toFixed(3)
|
||||
ids.indicator.style.bottom = ind.bottomInset + 'px'
|
||||
ids.indicator.style.height = ind.height + 'px'
|
||||
ids.indicator.style.borderRadius = ind.radius + 'px'
|
||||
ids.indicator.style.background = 'rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + alpha + ')'
|
||||
ids.indicator.style.boxShadow = ind.blur > 0
|
||||
? '0 0 ' + ind.blur + 'px rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + (alpha / 2) + ')'
|
||||
: 'none'
|
||||
if (ind.width > 0) {
|
||||
ids.indicator.style.width = ind.width + 'px'
|
||||
ids.indicator.style.left = '50%'
|
||||
ids.indicator.style.right = 'auto'
|
||||
ids.indicator.style.transform = 'translateX(-50%)'
|
||||
} else {
|
||||
ids.indicator.style.width = 'auto'
|
||||
ids.indicator.style.left = ind.sideInset + 'px'
|
||||
ids.indicator.style.right = ind.sideInset + 'px'
|
||||
ids.indicator.style.transform = 'none'
|
||||
}
|
||||
|
||||
document.getElementById('vIndHeight').textContent = ind.height
|
||||
document.getElementById('vIndSide').textContent = ind.sideInset
|
||||
document.getElementById('vIndBottom').textContent = ind.bottomInset
|
||||
document.getElementById('vIndRadius').textContent = ind.radius
|
||||
document.getElementById('vIndWidth').textContent = ind.width
|
||||
document.getElementById('vIndOpacity').textContent = ind.opacity
|
||||
document.getElementById('vIndBlur').textContent = ind.blur
|
||||
document.getElementById('vIndColor').textContent = ind.color
|
||||
|
||||
document.getElementById('jsonOut').value = JSON.stringify(p, null, 2)
|
||||
}
|
||||
|
||||
function scssSnippet() {
|
||||
const c = themeColors()
|
||||
const p = currentParams()
|
||||
const col = c.label === 'dark' ? '25, 25, 25' : '250, 247, 242'
|
||||
const rpx = (v) => Math.round(v * 2)
|
||||
const ind = p.indicator
|
||||
const irgb = hexToRgb(ind.color)
|
||||
const indLines = []
|
||||
if (ind.width > 0) {
|
||||
indLines.push(' width: ' + rpx(ind.width) + 'rpx;')
|
||||
indLines.push(' left: 50%;')
|
||||
indLines.push(' transform: translateX(-50%);')
|
||||
} else {
|
||||
indLines.push(' left: ' + rpx(ind.sideInset) + 'rpx;')
|
||||
indLines.push(' right: ' + rpx(ind.sideInset) + 'rpx;')
|
||||
}
|
||||
indLines.push(' bottom: ' + rpx(ind.bottomInset) + 'rpx;')
|
||||
indLines.push(' height: ' + rpx(ind.height) + 'rpx;')
|
||||
indLines.push(' border-radius: ' + rpx(ind.radius) + 'rpx;')
|
||||
indLines.push(' background: rgba(' + irgb.r + ', ' + irgb.g + ', ' + irgb.b + ', ' + (ind.opacity / 100).toFixed(2) + ');')
|
||||
if (ind.blur > 0) {
|
||||
indLines.push(' box-shadow: 0 0 ' + rpx(ind.blur) + 'rpx rgba(' + irgb.r + ', ' + irgb.g + ', ' + irgb.b + ', ' + ((ind.opacity / 100) / 2).toFixed(2) + ');')
|
||||
}
|
||||
return [
|
||||
'/* ' + c.label + ' theme */',
|
||||
'.tab-bar-root.' + c.label + ' .tab-bar-gradient {',
|
||||
' height: ' + rpx(p.gradient.height) + 'rpx;',
|
||||
' background: linear-gradient(to top,',
|
||||
' rgba(' + col + ', ' + (p.gradient.bottomOpacity / 100).toFixed(2) + ') 0%,',
|
||||
' rgba(' + col + ', ' + (p.gradient.midOpacity / 100).toFixed(2) + ') ' + p.gradient.midStop + '%,',
|
||||
' rgba(' + col + ', 0) ' + p.gradient.endStop + '%',
|
||||
' );',
|
||||
'}',
|
||||
'.custom-tab-bar {',
|
||||
' bottom: ' + rpx(p.tabBar.bottom) + 'rpx;',
|
||||
' left: ' + rpx(p.tabBar.sideMargin) + 'rpx;',
|
||||
' right: ' + rpx(p.tabBar.sideMargin) + 'rpx;',
|
||||
' height: ' + rpx(p.tabBar.height) + 'rpx;',
|
||||
' border-radius: ' + rpx(p.tabBar.radius) + 'rpx;',
|
||||
'}',
|
||||
'.tab-indicator {',
|
||||
indLines.join('\n'),
|
||||
'}'
|
||||
].join('\n')
|
||||
}
|
||||
|
||||
function copy(text) {
|
||||
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||||
return navigator.clipboard.writeText(text)
|
||||
}
|
||||
const ta = document.createElement('textarea')
|
||||
ta.value = text
|
||||
document.body.appendChild(ta)
|
||||
ta.select()
|
||||
document.execCommand('copy')
|
||||
document.body.removeChild(ta)
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
document.getElementById('themeBtn').addEventListener('click', () => {
|
||||
const dark = document.body.classList.toggle('theme-dark')
|
||||
document.getElementById('themeBtn').textContent = dark ? '切换到浅色' : '切换到深色'
|
||||
render()
|
||||
})
|
||||
|
||||
document.getElementById('copyJson').addEventListener('click', () => {
|
||||
copy(JSON.stringify(currentParams(), null, 2)).then(() => { alert('参数已复制') })
|
||||
})
|
||||
document.getElementById('copyCss').addEventListener('click', () => {
|
||||
copy(scssSnippet()).then(() => { alert('SCSS 已复制') })
|
||||
})
|
||||
|
||||
Object.keys(ids).forEach((k) => {
|
||||
if (k === 'gradient' || k === 'pill' || k === 'indicator') return
|
||||
ids[k].addEventListener('input', render)
|
||||
})
|
||||
|
||||
buildPill()
|
||||
render()
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||