@seasonkoh/webaz 0.1.28 → 0.1.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/README.zh-CN.md +7 -6
- package/dist/currency.js +16 -0
- package/dist/deposit-rails.js +52 -0
- package/dist/direct-pay-aml-monitor.js +67 -0
- package/dist/direct-pay-aml-review.js +40 -0
- package/dist/direct-pay-base-bond-entry.js +5 -0
- package/dist/direct-pay-bond-rail-clearance.js +94 -0
- package/dist/direct-pay-compliance-ingress.js +145 -0
- package/dist/direct-pay-controls.js +136 -0
- package/dist/direct-pay-create.js +162 -0
- package/dist/direct-pay-deferral-quota.js +43 -0
- package/dist/direct-pay-disclosures.js +44 -0
- package/dist/direct-pay-eligibility.js +46 -0
- package/dist/direct-pay-fee-ar.js +241 -0
- package/dist/direct-pay-launch-readiness.js +108 -0
- package/dist/direct-pay-launch-summary.js +68 -0
- package/dist/direct-pay-ledger.js +94 -0
- package/dist/direct-receive-account-qr.js +77 -0
- package/dist/direct-receive-accounts.js +82 -0
- package/dist/direct-receive-deferral.js +142 -0
- package/dist/direct-receive-deposits.js +260 -0
- package/dist/direct-receive-payment-instruction.js +26 -0
- package/dist/fx-rates.js +71 -0
- package/dist/layer0-foundation/L0-1-database/schema.js +531 -1
- package/dist/layer0-foundation/L0-2-state-machine/genuine-sale.js +15 -5
- package/dist/layer0-foundation/L0-2-state-machine/transitions.js +41 -0
- package/dist/layer0-foundation/L0-5-manifest/manifest.js +1 -1
- package/dist/layer1-agent/L1-1-mcp-server/cli.js +64 -0
- package/dist/layer1-agent/L1-1-mcp-server/network-mode.js +11 -0
- package/dist/layer1-agent/L1-1-mcp-server/server.js +18 -16
- package/dist/layer4-economics/L4-4-skill-market/skill-engine.js +4 -4
- package/dist/ledger.js +12 -3
- package/dist/mcp.js +23 -4
- package/dist/merchant-bond-domain.js +64 -0
- package/dist/merchant-bond-exposure.js +78 -0
- package/dist/merchant-bond-watcher.js +26 -0
- package/dist/payment-rails.js +29 -0
- package/dist/product-verification.js +93 -0
- package/dist/pwa/acp-feed.js +3 -2
- package/dist/pwa/contract-fingerprint.js +3 -0
- package/dist/pwa/direct-pay-guards.js +20 -0
- package/dist/pwa/direct-pay-order-redaction.js +24 -0
- package/dist/pwa/endpoint-actions.js +3 -0
- package/dist/pwa/public/app-ai.js +10 -10
- package/dist/pwa/public/app-chat-poll.js +29 -0
- package/dist/pwa/public/app-create-kinds.js +17 -0
- package/dist/pwa/public/app-direct-pay-accounts.js +141 -0
- package/dist/pwa/public/app-direct-pay-buyer.js +72 -0
- package/dist/pwa/public/app-direct-pay-compliance.js +67 -0
- package/dist/pwa/public/app-direct-pay-deferral-admin.js +72 -0
- package/dist/pwa/public/app-direct-pay-deferral.js +61 -0
- package/dist/pwa/public/app-direct-pay-fee-center.js +33 -0
- package/dist/pwa/public/app-direct-pay-fee-ops.js +112 -0
- package/dist/pwa/public/app-direct-pay-product-verify.js +103 -0
- package/dist/pwa/public/app-direct-pay-readiness.js +38 -0
- package/dist/pwa/public/app-direct-pay-store-verify.js +100 -0
- package/dist/pwa/public/app-direct-pay.js +227 -0
- package/dist/pwa/public/app-discover.js +20 -20
- package/dist/pwa/public/app-external-links.js +32 -0
- package/dist/pwa/public/app-listings.js +4 -4
- package/dist/pwa/public/app-prelaunch-waz.js +39 -0
- package/dist/pwa/public/app-price.js +55 -0
- package/dist/pwa/public/app-product-media.js +15 -0
- package/dist/pwa/public/app-profile.js +6 -6
- package/dist/pwa/public/app-seller.js +5 -5
- package/dist/pwa/public/app-shop.js +19 -19
- package/dist/pwa/public/app.js +142 -146
- package/dist/pwa/public/i18n.js +398 -197
- package/dist/pwa/public/index.html +17 -0
- package/dist/pwa/public/openapi.json +495 -1
- package/dist/pwa/routes/admin-analytics.js +4 -2
- package/dist/pwa/routes/admin-direct-receive-deposits.js +321 -0
- package/dist/pwa/routes/buyer-feeds.js +2 -1
- package/dist/pwa/routes/chat.js +6 -1
- package/dist/pwa/routes/dashboards.js +2 -1
- package/dist/pwa/routes/direct-pay-availability.js +196 -0
- package/dist/pwa/routes/direct-pay-disclosure-acks.js +74 -0
- package/dist/pwa/routes/direct-pay-timeouts.js +71 -0
- package/dist/pwa/routes/direct-receive-accounts.js +155 -0
- package/dist/pwa/routes/direct-receive-payment-instructions.js +45 -0
- package/dist/pwa/routes/fx.js +12 -0
- package/dist/pwa/routes/leaderboard.js +47 -9
- package/dist/pwa/routes/listings.js +2 -2
- package/dist/pwa/routes/logistics.js +4 -0
- package/dist/pwa/routes/manifests.js +38 -0
- package/dist/pwa/routes/me-data.js +5 -2
- package/dist/pwa/routes/orders-action.js +117 -9
- package/dist/pwa/routes/orders-create.js +4 -0
- package/dist/pwa/routes/orders-read.js +36 -0
- package/dist/pwa/routes/p2p-products.js +2 -2
- package/dist/pwa/routes/products-create.js +5 -3
- package/dist/pwa/routes/products-links.js +34 -0
- package/dist/pwa/routes/products-list.js +2 -1
- package/dist/pwa/routes/products-update.js +22 -2
- package/dist/pwa/routes/promoter.js +3 -0
- package/dist/pwa/routes/referral.js +4 -0
- package/dist/pwa/routes/returns.js +26 -1
- package/dist/pwa/routes/rewards-apply.js +10 -5
- package/dist/pwa/routes/rewards-clearing-mature.js +96 -0
- package/dist/pwa/routes/rewards-escrow-expire.js +6 -2
- package/dist/pwa/routes/shops.js +2 -1
- package/dist/pwa/routes/url-claim.js +2 -2
- package/dist/pwa/routes/users-public.js +8 -0
- package/dist/pwa/routes/wallet-read.js +3 -0
- package/dist/pwa/routes/webauthn.js +1 -1
- package/dist/pwa/server.js +59 -102
- package/dist/runtime/webaz-schema-helpers.js +104 -0
- package/dist/store-verification.js +77 -0
- package/dist/version.js +1 -1
- package/package.json +71 -2
|
@@ -261,7 +261,7 @@ function profileContentTabs(isOwner, role, active) {
|
|
|
261
261
|
...(isOwner ? [
|
|
262
262
|
{ k: 'reposted', label: '🔁 ' + t('转发') },
|
|
263
263
|
{ k: 'liked', label: '❤ ' + t('赞') },
|
|
264
|
-
{ k: 'bookmarked', label: '★ ' + t('
|
|
264
|
+
{ k: 'bookmarked', label: '★ ' + t('已收藏') },
|
|
265
265
|
] : []),
|
|
266
266
|
]
|
|
267
267
|
return `<div style="display:flex;gap:18px;border-bottom:1px solid #f3f4f6;margin-bottom:12px;overflow-x:auto;-webkit-overflow-scrolling:touch">
|
|
@@ -315,7 +315,7 @@ async function loadUserContentFeed(userId, tab) {
|
|
|
315
315
|
${img ? `<img src="${escHtml(img)}" style="width:100%;aspect-ratio:1;object-fit:cover;display:block" onerror="this.style.display='none'">` : `<div style="aspect-ratio:1;background:#f9fafb;display:flex;align-items:center;justify-content:center;font-size:32px">♻️</div>`}
|
|
316
316
|
<div style="padding:8px">
|
|
317
317
|
<div style="font-size:12px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${escHtml(s.title)}</div>
|
|
318
|
-
<div style="font-size:13px;font-weight:700;color:#dc2626;margin-top:2px">${s.price}
|
|
318
|
+
<div style="font-size:13px;font-weight:700;color:#dc2626;margin-top:2px">${window.fmtPrice(s.price)}</div>
|
|
319
319
|
<div style="font-size:10px;color:#9ca3af;margin-top:2px">${CG[s.condition_grade] || s.condition_grade}${s.status === 'reserved' ? ' · ' + t('已预订') : ''}</div>
|
|
320
320
|
</div>
|
|
321
321
|
</div>`
|
|
@@ -336,7 +336,7 @@ async function loadUserContentFeed(userId, tab) {
|
|
|
336
336
|
${img ? `<img src="${escHtml(img)}" style="width:100%;aspect-ratio:1;object-fit:cover;display:block" onerror="this.style.display='none'">` : `<div style="aspect-ratio:1;background:#f9fafb;display:flex;align-items:center;justify-content:center;font-size:32px">${getCategoryIcon(p.category)}</div>`}
|
|
337
337
|
<div style="padding:8px">
|
|
338
338
|
<div style="font-size:12px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${escHtml(p.title)}</div>
|
|
339
|
-
<div style="font-size:13px;font-weight:700;color:#1f2937;margin-top:2px">${p.price}
|
|
339
|
+
<div style="font-size:13px;font-weight:700;color:#1f2937;margin-top:2px">${window.fmtPrice(p.price)}</div>
|
|
340
340
|
<div style="font-size:10px;color:#9ca3af;margin-top:2px">✅ ${p.completion_count || 0} · ❤ ${p.total_likes || 0}</div>
|
|
341
341
|
</div>
|
|
342
342
|
</div>`
|
|
@@ -631,7 +631,7 @@ async function renderNearby(app) {
|
|
|
631
631
|
<div style="width:38px;height:38px;border-radius:8px;background:#f3f4f6;display:flex;align-items:center;justify-content:center;font-size:18px;flex-shrink:0">${getCategoryIcon(p.category)}</div>
|
|
632
632
|
<div style="flex:1;min-width:0">
|
|
633
633
|
<div style="font-size:13px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${escHtml(p.title)}</div>
|
|
634
|
-
<div style="font-size:11px;color:#6b7280">${p.price}
|
|
634
|
+
<div style="font-size:11px;color:#6b7280">${window.fmtPrice(p.price)} · 🔥 ${p.buyers} ${t('人买')}</div>
|
|
635
635
|
</div>
|
|
636
636
|
</div>
|
|
637
637
|
<span style="font-size:13px;color:#9ca3af">›</span>
|
|
@@ -821,8 +821,8 @@ async function renderNearbyFeed(app) {
|
|
|
821
821
|
<h3 style="font-size:13px;font-weight:700;margin:14px 0 8px">🔥 ${t('近 24h 同城热销商品')}</h3>
|
|
822
822
|
${topProducts.slice(0,5).map(p => `
|
|
823
823
|
<div class="card" style="padding:10px 12px;margin-bottom:6px;cursor:pointer" onclick="navigate('#order-product/${p.id}')">
|
|
824
|
-
<div style="font-size:13px;font-weight:600">${escHtml(p.title)} <span style="color:#dc2626;font-weight:700">${p.price}
|
|
825
|
-
<div style="font-size:11px;color:#6b7280;margin-top:2px">🛒 ${p.buy_count} ${t('单')} ·
|
|
824
|
+
<div style="font-size:13px;font-weight:600">${escHtml(p.title)} <span style="color:#dc2626;font-weight:700">${window.fmtPrice(p.price)}</span></div>
|
|
825
|
+
<div style="font-size:11px;color:#6b7280;margin-top:2px">🛒 ${p.buy_count} ${t('单')} · ${t('同城共鸣')}</div>
|
|
826
826
|
</div>`).join('')}` : ''}
|
|
827
827
|
`
|
|
828
828
|
}
|
|
@@ -44,7 +44,7 @@ async function renderSellerAnalytics(app) {
|
|
|
44
44
|
: `<div style="display:flex;gap:3px;align-items:flex-end;height:80px">
|
|
45
45
|
${trend.map(d => {
|
|
46
46
|
const h = Math.max(3, (Number(d.gmv) / maxGmv) * 70)
|
|
47
|
-
return `<div title="${d.date}: ${Number(d.gmv).toFixed(0)}
|
|
47
|
+
return `<div title="${d.date}: ${Number(d.gmv).toFixed(0)} USDC · ${d.orders} ${t('单')}" style="flex:1;background:linear-gradient(180deg,#6366f1,#a5b4fc);height:${h}px;border-radius:2px 2px 0 0;cursor:help"></div>`
|
|
48
48
|
}).join('')}
|
|
49
49
|
</div>
|
|
50
50
|
<div style="display:flex;justify-content:space-between;font-size:9px;color:#9ca3af;margin-top:4px">
|
|
@@ -59,11 +59,11 @@ async function renderSellerAnalytics(app) {
|
|
|
59
59
|
<div style="font-size:13px;font-weight:700;color:${i === 0 ? '#f59e0b' : i < 3 ? '#6366f1' : '#9ca3af'};width:22px;text-align:center">${i + 1}</div>
|
|
60
60
|
<div style="flex:1;min-width:0">
|
|
61
61
|
<div style="font-size:12px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${escHtml(p.title)}</div>
|
|
62
|
-
<div style="font-size:10px;color:#9ca3af">${p.price}
|
|
62
|
+
<div style="font-size:10px;color:#9ca3af">${window.fmtPrice(p.price)}</div>
|
|
63
63
|
</div>
|
|
64
64
|
<div style="text-align:right">
|
|
65
65
|
<div style="font-size:13px;font-weight:600;color:#16a34a">${p.sales} ${t('单')}</div>
|
|
66
|
-
<div style="font-size:10px;color:#9ca3af">${fmt2(p.revenue)}
|
|
66
|
+
<div style="font-size:10px;color:#9ca3af">${fmt2(p.revenue)} USDC</div>
|
|
67
67
|
</div>
|
|
68
68
|
</div>`).join('')
|
|
69
69
|
|
|
@@ -80,7 +80,7 @@ async function renderSellerAnalytics(app) {
|
|
|
80
80
|
<div style="display:grid;grid-template-columns:repeat(3,1fr);gap:8px;text-align:center">
|
|
81
81
|
<div>
|
|
82
82
|
<div style="font-size:18px;font-weight:700;color:#4f46e5">${fmt2(r.orders.gmv)}${delta(Number(r.orders.gmv), Number(r.prev_window?.gmv))}</div>
|
|
83
|
-
<div style="font-size:10px;color:#6b7280">GMV (
|
|
83
|
+
<div style="font-size:10px;color:#6b7280">GMV (USDC)</div>
|
|
84
84
|
</div>
|
|
85
85
|
<div>
|
|
86
86
|
<div style="font-size:18px;font-weight:700;color:#16a34a">${fmt(r.orders.completed_orders)}${delta(Number(r.orders.completed_orders), Number(r.prev_window?.completed_orders))}</div>
|
|
@@ -88,7 +88,7 @@ async function renderSellerAnalytics(app) {
|
|
|
88
88
|
</div>
|
|
89
89
|
<div>
|
|
90
90
|
<div style="font-size:18px;font-weight:700;color:#f59e0b">${fmt2(r.orders.aov)}</div>
|
|
91
|
-
<div style="font-size:10px;color:#6b7280">${t('客单价')} (
|
|
91
|
+
<div style="font-size:10px;color:#6b7280">${t('客单价')} (USDC)</div>
|
|
92
92
|
</div>
|
|
93
93
|
</div>
|
|
94
94
|
</div>
|
|
@@ -101,10 +101,10 @@ async function renderWishlist(app) {
|
|
|
101
101
|
: items.map(it => {
|
|
102
102
|
const cur = Number(it.current_price), delta = Number(it.price_delta || 0), pct = Number(it.price_delta_pct || 0)
|
|
103
103
|
const priceTag = delta < 0
|
|
104
|
-
? `<span style="color:#dc2626;font-weight:700">${cur}
|
|
104
|
+
? `<span style="color:#dc2626;font-weight:700">${window.fmtPrice(cur)} <span style="font-size:11px;background:#fef2f2;color:#991b1b;padding:1px 6px;border-radius:99px;font-weight:600;margin-left:4px">↓${Math.abs(pct).toFixed(0)}%</span></span>`
|
|
105
105
|
: delta > 0
|
|
106
|
-
? `<span style="color:#374151;font-weight:600">${cur}
|
|
107
|
-
: `<span style="color:#374151;font-weight:600">${cur}
|
|
106
|
+
? `<span style="color:#374151;font-weight:600">${window.fmtPrice(cur)} <span style="font-size:11px;color:#9ca3af">(${t('已涨')} ${pct.toFixed(0)}%)</span></span>`
|
|
107
|
+
: `<span style="color:#374151;font-weight:600">${window.fmtPrice(cur)}</span>`
|
|
108
108
|
const stockTag = Number(it.stock) === 0
|
|
109
109
|
? `<span style="background:#f3f4f6;color:#6b7280;font-size:10px;padding:1px 6px;border-radius:4px">${t('缺货')}</span>`
|
|
110
110
|
: ''
|
|
@@ -178,7 +178,7 @@ async function renderWaitlist(app) {
|
|
|
178
178
|
<div style="flex:1;min-width:0">
|
|
179
179
|
<div style="font-size:14px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${escHtml(it.title)}</div>
|
|
180
180
|
<div style="display:flex;gap:6px;align-items:center;margin-top:4px;font-size:12px">
|
|
181
|
-
<span style="color:#374151;font-weight:600">${it.price}
|
|
181
|
+
<span style="color:#374151;font-weight:600">${window.fmtPrice(it.price)}</span>
|
|
182
182
|
${stockTag}
|
|
183
183
|
${notifiedTag}
|
|
184
184
|
</div>
|
|
@@ -607,14 +607,14 @@ async function renderForYou(app) {
|
|
|
607
607
|
const meta = labels[b]
|
|
608
608
|
const cards = grouped[b].map(p => {
|
|
609
609
|
let imageUrl = ''
|
|
610
|
-
|
|
610
|
+
imageUrl = window.productThumbSrc(p.images) || imageUrl
|
|
611
611
|
return `
|
|
612
612
|
<div class="card" style="padding:8px 10px;margin-bottom:6px;cursor:pointer" onclick="location.hash='#order-product/${p.id}'">
|
|
613
613
|
<div style="display:flex;gap:10px;align-items:center">
|
|
614
|
-
<div style="font-size:24px;flex-shrink:0">${imageUrl ? `<img src="${escHtml(imageUrl)}" style="width:42px;height:42px;border-radius:6px;object-fit:cover">` : getCategoryIcon(p.category) || '📦'}</div>
|
|
614
|
+
<div style="font-size:24px;flex-shrink:0">${imageUrl ? `<img src="${escHtml(imageUrl)}" onerror="this.outerHTML='📦'" style="width:42px;height:42px;border-radius:6px;object-fit:cover">` : getCategoryIcon(p.category) || '📦'}</div>
|
|
615
615
|
<div style="flex:1;min-width:0">
|
|
616
616
|
<div style="font-size:13px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${escHtml(p.title)}</div>
|
|
617
|
-
<div style="font-size:12px;color:#4f46e5;font-weight:600">${p.price}
|
|
617
|
+
<div style="font-size:12px;color:#4f46e5;font-weight:600">${window.fmtPrice(p.price)} <span style="font-size:10px;color:#9ca3af;font-weight:400">· @${escHtml(p.seller_handle || '')}${p.sales_count > 0 ? ' · 🛒 ' + p.sales_count : ''}</span></div>
|
|
618
618
|
</div>
|
|
619
619
|
</div>
|
|
620
620
|
</div>`
|
|
@@ -694,8 +694,8 @@ async function renderCompare(app, ids) {
|
|
|
694
694
|
{ label: t('商品'), render: (p) => `<a href="#order-product/${p.id}" style="font-size:13px;font-weight:600;color:#374151;display:block;overflow:hidden;text-overflow:ellipsis">${escHtml(p.title)}</a>` },
|
|
695
695
|
{ label: t('价格'), render: (p, i) => {
|
|
696
696
|
const sale = flashes[i]?.sale
|
|
697
|
-
if (sale) return `<span style="color:#dc2626;font-weight:700">${sale.sale_price}</span
|
|
698
|
-
return `<span style="color:#4f46e5;font-weight:700">${p.price}</span
|
|
697
|
+
if (sale) return `<span style="color:#dc2626;font-weight:700">${window.fmtPrice(sale.sale_price)}</span><br><span style="font-size:10px;color:#9ca3af;text-decoration:line-through">${p.price} USDC</span>`
|
|
698
|
+
return `<span style="color:#4f46e5;font-weight:700">${window.fmtPrice(p.price)}</span>`
|
|
699
699
|
} },
|
|
700
700
|
{ label: t('库存'), render: (p) => `<span style="color:${Number(p.stock) === 0 ? '#dc2626' : Number(p.stock) <= 3 ? '#d97706' : '#374151'}">${p.stock}</span>` },
|
|
701
701
|
{ label: t('卖家'), render: (p) => `<a href="#shop/${p.seller_id}" style="font-size:11px;color:#6366f1">@${escHtml(p.seller_name || '')}</a>` },
|
|
@@ -787,14 +787,14 @@ async function renderShopPage(app, identifier) {
|
|
|
787
787
|
? `<div style="text-align:center;padding:30px;color:#9ca3af;font-size:13px">${t('该卖家暂无商品')}</div>`
|
|
788
788
|
: products.map(p => {
|
|
789
789
|
let imageUrl = ''
|
|
790
|
-
|
|
790
|
+
imageUrl = window.productThumbSrc(p.images) || imageUrl
|
|
791
791
|
return `
|
|
792
792
|
<div class="card" style="padding:10px 12px;cursor:pointer" onclick="location.hash='#order-product/${p.id}'">
|
|
793
793
|
<div style="display:flex;gap:10px;align-items:center">
|
|
794
|
-
<div style="font-size:28px;flex-shrink:0">${imageUrl ? `<img src="${escHtml(imageUrl)}" style="width:42px;height:42px;border-radius:6px;object-fit:cover">` : getCategoryIcon(p.category) || '📦'}</div>
|
|
794
|
+
<div style="font-size:28px;flex-shrink:0">${imageUrl ? `<img src="${escHtml(imageUrl)}" onerror="this.outerHTML='📦'" style="width:42px;height:42px;border-radius:6px;object-fit:cover">` : getCategoryIcon(p.category) || '📦'}</div>
|
|
795
795
|
<div style="flex:1;min-width:0">
|
|
796
796
|
<div style="font-size:13px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${escHtml(p.title)}</div>
|
|
797
|
-
<div style="font-size:12px;color:#4f46e5;font-weight:600">${p.price}
|
|
797
|
+
<div style="font-size:12px;color:#4f46e5;font-weight:600">${window.fmtPrice(p.price)} <span style="font-size:10px;color:#9ca3af;font-weight:400">· ${stockBadgeHtml(p)}${p.sales_count > 0 ? ' · 🛒 ' + p.sales_count : ''}</span></div>
|
|
798
798
|
</div>
|
|
799
799
|
</div>
|
|
800
800
|
</div>`
|
|
@@ -930,15 +930,15 @@ async function renderEditorPicks(app) {
|
|
|
930
930
|
const sellers = r?.sellers || []
|
|
931
931
|
const productCards = products.map(p => {
|
|
932
932
|
let imageUrl = ''
|
|
933
|
-
|
|
933
|
+
imageUrl = window.productThumbSrc(p.images) || imageUrl
|
|
934
934
|
return `
|
|
935
935
|
<div class="card" style="padding:12px;margin-bottom:8px;cursor:pointer;border-left:3px solid #d97706" onclick="location.hash='#order-product/${p.target_id}'">
|
|
936
936
|
${p.title ? `<div style="font-size:11px;color:#d97706;font-weight:600;margin-bottom:4px">📌 ${escHtml(p.title)}</div>` : ''}
|
|
937
937
|
<div style="display:flex;gap:10px;align-items:center">
|
|
938
|
-
<div style="font-size:32px;flex-shrink:0">${imageUrl ? `<img src="${escHtml(imageUrl)}" style="width:48px;height:48px;border-radius:6px;object-fit:cover">` : getCategoryIcon(p.category) || '📦'}</div>
|
|
938
|
+
<div style="font-size:32px;flex-shrink:0">${imageUrl ? `<img src="${escHtml(imageUrl)}" onerror="this.outerHTML='📦'" style="width:48px;height:48px;border-radius:6px;object-fit:cover">` : getCategoryIcon(p.category) || '📦'}</div>
|
|
939
939
|
<div style="flex:1;min-width:0">
|
|
940
940
|
<div style="font-size:13px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${escHtml(p.product_title)}</div>
|
|
941
|
-
<div style="font-size:12px;color:#4f46e5;font-weight:600">${p.price}
|
|
941
|
+
<div style="font-size:12px;color:#4f46e5;font-weight:600">${window.fmtPrice(p.price)} · @${escHtml(p.seller_handle || '')}</div>
|
|
942
942
|
</div>
|
|
943
943
|
</div>
|
|
944
944
|
${p.note ? `<div style="font-size:11px;color:#374151;margin-top:6px;padding:6px 8px;background:#fef3c7;border-radius:6px">${escHtml(p.note)}</div>` : ''}
|
|
@@ -1118,18 +1118,18 @@ async function renderFlashSalesLive(app) {
|
|
|
1118
1118
|
? `<div style="text-align:center;padding:40px;color:#9ca3af"><div style="font-size:48px">⚡</div><div style="font-size:13px;margin-top:8px">${t('暂无进行中的限时促销')}</div></div>`
|
|
1119
1119
|
: items.map(it => {
|
|
1120
1120
|
let imageUrl = ''
|
|
1121
|
-
|
|
1121
|
+
imageUrl = window.productThumbSrc(it.images) || imageUrl
|
|
1122
1122
|
const save = (Number(it.original_price) - Number(it.sale_price)).toFixed(2)
|
|
1123
1123
|
const pct = ((1 - Number(it.sale_price) / Number(it.original_price)) * 100).toFixed(0)
|
|
1124
1124
|
return `
|
|
1125
1125
|
<div class="card" style="padding:10px 12px;margin-bottom:8px;cursor:pointer;border-left:3px solid #dc2626" onclick="location.hash='#order-product/${it.product_id}'">
|
|
1126
1126
|
<div style="display:flex;gap:10px;align-items:center">
|
|
1127
|
-
<div style="font-size:32px;flex-shrink:0">${imageUrl ? `<img src="${escHtml(imageUrl)}" style="width:48px;height:48px;border-radius:6px;object-fit:cover">` : getCategoryIcon(it.category) || '📦'}</div>
|
|
1127
|
+
<div style="font-size:32px;flex-shrink:0">${imageUrl ? `<img src="${escHtml(imageUrl)}" onerror="this.outerHTML='📦'" style="width:48px;height:48px;border-radius:6px;object-fit:cover">` : getCategoryIcon(it.category) || '📦'}</div>
|
|
1128
1128
|
<div style="flex:1;min-width:0">
|
|
1129
1129
|
<div style="font-size:13px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${escHtml(it.title)}</div>
|
|
1130
1130
|
<div style="font-size:12px;margin-top:2px">
|
|
1131
|
-
<span style="color:#dc2626;font-weight:700">${it.sale_price}
|
|
1132
|
-
<span style="font-size:11px;color:#9ca3af;text-decoration:line-through;margin-left:4px">${it.original_price}</span>
|
|
1131
|
+
<span style="color:#dc2626;font-weight:700">${window.fmtPrice(it.sale_price)}</span>
|
|
1132
|
+
<span style="font-size:11px;color:#9ca3af;text-decoration:line-through;margin-left:4px">${it.original_price} USDC</span>
|
|
1133
1133
|
<span style="font-size:10px;color:#dc2626;background:#fee2e2;padding:1px 5px;border-radius:99px;margin-left:4px;font-weight:600">-${pct}%</span>
|
|
1134
1134
|
</div>
|
|
1135
1135
|
<div style="font-size:10px;color:#9ca3af;margin-top:2px">@${escHtml(it.seller_handle || '')} · ${t('截止')} ${fmtTime(it.ends_at)}${it.max_qty > 0 ? ' · ' + t('限') + ' ' + it.max_qty + ' / ' + t('已售') + ' ' + it.sold_count : ''}</div>
|