Files
jiu/backend/internal/handler/templates/public_product.html
T
wangjia d19e88e3f4 feat(backend): 公开页视觉改版——酒背标美学 + 页脚品牌链接/ICP + 图片区常驻
- 宣纸暖白底 × 宋体衬线题名 × 酒红「正品」印章,信息行点线引导(酒单式)
- 图片区永远存在:无图时显示酒瓶线稿占位「实物图整理中」
- 页脚:岩美酒库链接(jiu.51yanmei.com)+ 京ICP备2026039814号(链工信部)
- 仍零 JS、零外部资源,整页 ~9KB;入场动效纯 CSS,reduced-motion 降级

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JJ1g8XV1YhhmHRzhwWEW7o
2026-07-07 11:27:17 +08:00

196 lines
10 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{.PageTitle}}</title>{{.OGTags}}
<style>
/* 酒背标美学:宣纸暖白 × 墨色衬线 × 酒红印章。零 JS、零外部资源。 */
:root{
--paper:#F6F1E7; --card:#FCFAF4; --ink:#2A2420; --muted:#8A7F70;
--wine:#8B2331; --gold:#9A6B2F; --line:#E2D7C3; --line-soft:#EDE5D4;
}
*{box-sizing:border-box;margin:0;padding:0;}
body{
background-color:var(--paper);
background-image:
radial-gradient(circle at 12% 8%, rgba(154,107,47,.06), transparent 42%),
radial-gradient(circle at 88% 92%, rgba(139,35,49,.05), transparent 42%);
color:var(--ink);
font:15px/1.75 -apple-system,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;
-webkit-font-smoothing:antialiased;
}
.serif{font-family:"Songti SC","STSong","Noto Serif CJK SC","SimSun",serif;}
.page{max-width:560px;margin:0 auto;padding:0 18px 44px;}
a{color:var(--wine);text-decoration:none;}
/* 顶部题签 */
.mast{
display:flex;align-items:center;justify-content:center;gap:10px;
padding:20px 0 14px;color:var(--muted);font-size:12px;letter-spacing:.35em;
border-bottom:1px solid var(--line);position:relative;
}
.mast::after{content:"";position:absolute;left:0;right:0;bottom:3px;border-bottom:1px solid var(--line-soft);}
.mast a{color:var(--ink);font-weight:600;letter-spacing:.35em;}
/* 图片区(永远存在):细双线画框 + 右上酒红印章 */
.hero{margin:22px 0 0;position:relative;animation:rise .6s ease both;}
.frame{
position:relative;background:var(--card);border:1px solid var(--line);border-radius:6px;overflow:hidden;
}
.frame::after{content:"";position:absolute;inset:5px;border:1px solid rgba(154,107,47,.28);border-radius:3px;pointer-events:none;z-index:2;}
.gallery{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;}
.gallery img{width:100%;flex:0 0 100%;scroll-snap-align:center;aspect-ratio:1/1;object-fit:contain;background:var(--card);display:block;}
.placeholder{
aspect-ratio:16/10;display:flex;flex-direction:column;align-items:center;justify-content:center;
gap:10px;color:var(--muted);font-size:12px;letter-spacing:.25em;
}
.placeholder svg{width:46px;height:70px;stroke:var(--gold);opacity:.55;}
.seal{
position:absolute;top:12px;right:12px;z-index:3;width:58px;height:58px;border-radius:50%;
border:2px solid rgba(139,35,49,.75);color:var(--wine);background:rgba(246,241,231,.72);
display:flex;align-items:center;justify-content:center;transform:rotate(8deg);
font-size:15px;font-weight:700;letter-spacing:.18em;text-indent:.18em;
font-family:"Songti SC","STSong","Noto Serif CJK SC","SimSun",serif;
box-shadow:inset 0 0 0 2px rgba(246,241,231,.9);
}
/* 题名 */
.head{ text-align:center;padding:22px 6px 4px;animation:rise .6s ease .08s both;}
h1{font-size:24px;line-height:1.45;font-weight:700;font-family:"Songti SC","STSong","Noto Serif CJK SC","SimSun",serif;}
.sub{color:var(--muted);font-size:13px;letter-spacing:.18em;margin-top:6px;}
.price{
margin-top:12px;color:var(--wine);font-size:26px;font-weight:700;
font-family:"Songti SC","STSong","Noto Serif CJK SC","SimSun",serif;
}
.price small{font-size:12px;color:var(--muted);font-weight:400;font-family:-apple-system,"PingFang SC",sans-serif;letter-spacing:.1em;}
.chips{display:flex;flex-wrap:wrap;gap:8px;justify-content:center;margin-top:14px;}
.chip{font-size:11.5px;letter-spacing:.12em;color:var(--gold);border:1px solid rgba(154,107,47,.4);border-radius:2px;padding:2px 10px;background:rgba(154,107,47,.05);}
/* 分节:―― 节名 ―― */
.sec{margin-top:26px;animation:rise .6s ease .16s both;}
.sec-t{
display:flex;align-items:center;gap:14px;color:var(--wine);font-size:13px;letter-spacing:.4em;text-indent:.4em;
font-weight:700;justify-content:center;margin-bottom:12px;
font-family:"Songti SC","STSong","Noto Serif CJK SC","SimSun",serif;
}
.sec-t::before,.sec-t::after{content:"";height:1px;background:var(--line);flex:1;max-width:64px;}
.card{background:var(--card);border:1px solid var(--line);border-radius:6px;padding:6px 18px;position:relative;}
.card::after{content:"";position:absolute;inset:4px;border:1px solid rgba(154,107,47,.14);border-radius:3px;pointer-events:none;}
/* 信息行:label ⋯⋯ value 点线引导 */
.row{display:flex;align-items:baseline;padding:10px 0;font-size:14px;}
.row+.row{border-top:1px solid var(--line-soft);}
.row span{color:var(--muted);flex:none;letter-spacing:.08em;}
.row .dots{flex:1;margin:0 10px;border-bottom:1px dotted var(--line);transform:translateY(-4px);min-width:16px;}
.row b{font-weight:600;text-align:right;word-break:break-all;max-width:70%;}
.row b.mono,.mono{font-family:ui-monospace,Menlo,monospace;font-size:13px;letter-spacing:.02em;}
.row b a{font-family:"Songti SC","STSong","Noto Serif CJK SC","SimSun",serif;font-weight:700;}
.desc{padding:14px 2px;font-size:14px;color:var(--ink);white-space:pre-wrap;text-align:justify;}
.more{display:block;text-align:center;padding:12px 0 10px;font-size:13.5px;letter-spacing:.1em;border-top:1px solid var(--line-soft);}
/* 页脚 */
.foot{margin-top:34px;text-align:center;color:var(--muted);font-size:12px;line-height:2.1;animation:rise .6s ease .24s both;}
.foot-rule{display:flex;align-items:center;gap:12px;margin-bottom:10px;color:var(--gold);}
.foot-rule::before,.foot-rule::after{content:"";height:1px;background:var(--line);flex:1;}
.foot a{color:var(--muted);}
.foot .brand{color:var(--wine);font-weight:600;letter-spacing:.1em;}
.foot .icp{font-size:11px;opacity:.85;}
.empty{text-align:center;padding:80px 20px 60px;animation:rise .6s ease both;}
.empty h1{font-size:20px;margin-bottom:10px;}
.empty p{color:var(--muted);font-size:13px;}
@keyframes rise{from{opacity:0;transform:translateY(10px);}to{opacity:1;transform:none;}}
@media (prefers-reduced-motion:reduce){*{animation:none!important;}}
</style>
</head>
<body>
<div class="page">
<header class="mast"><a href="https://jiu.51yanmei.com">岩美酒库</a><span>正品溯源</span></header>
{{if .Found}}
<div class="hero">
<div class="frame">
{{if .Images}}
<div class="gallery">
{{range $i, $img := .Images}}<img src="{{$img}}" alt="{{$.Name}}" decoding="async"{{if $i}} loading="lazy"{{end}}>{{end}}
</div>
{{else}}
<div class="placeholder">
<svg viewBox="0 0 40 64" fill="none" stroke-width="1.4" stroke-linecap="round">
<path d="M16 2h8M17 2v14c0 3 6 3 6 0V2M17 12c-6 5-9 9-9 16v28a4 4 0 0 0 4 4h16a4 4 0 0 0 4-4V28c0-7-3-11-9-16"/>
<path d="M8 38h24" stroke-dasharray="2 3"/>
</svg>
<span>实物图整理中</span>
</div>
{{end}}
<div class="seal">正品</div>
</div>
</div>
<div class="head">
<h1>{{.Name}}</h1>
{{if or .Series .Spec}}<div class="sub">{{.Series}}{{if and .Series .Spec}} · {{end}}{{.Spec}}</div>{{end}}
{{if .Price}}<div class="price">{{.Price}}{{if .Unit}} <small>/ {{.Unit}}</small>{{end}}</div>{{end}}
{{if .Keywords}}<div class="chips">{{range .Keywords}}<span class="chip">{{.}}</span>{{end}}</div>{{end}}
</div>
<div class="sec">
<div class="sec-t">商品信息</div>
<div class="card">
{{if .Code}}<div class="row"><span>商品编号</span><i class="dots"></i><b class="mono">{{.Code}}</b></div>{{end}}
{{if .Series}}<div class="row"><span>系列</span><i class="dots"></i><b>{{.Series}}</b></div>{{end}}
{{if .Spec}}<div class="row"><span>规格</span><i class="dots"></i><b>{{.Spec}}</b></div>{{end}}
{{if .Origin}}<div class="row"><span>产地</span><i class="dots"></i><b>{{.Origin}}</b></div>{{end}}
<div class="row"><span>保质期</span><i class="dots"></i><b>{{.ShelfLife}}</b></div>
<div class="row"><span>储存方式</span><i class="dots"></i><b>{{.Storage}}</b></div>
</div>
</div>
{{if .HasBatch}}
<div class="sec">
<div class="sec-t">批次信息</div>
<div class="card">
{{if .ProdDate}}<div class="row"><span>生产日期</span><i class="dots"></i><b class="mono">{{.ProdDate}}</b></div>{{end}}
{{if .BatchNo}}<div class="row"><span>批次号</span><i class="dots"></i><b class="mono">{{.BatchNo}}</b></div>{{end}}
{{if .InDate}}<div class="row"><span>入库日期</span><i class="dots"></i><b class="mono">{{.InDate}}</b></div>{{end}}
</div>
</div>
{{end}}
{{if .DescBody}}
<div class="sec">
<div class="sec-t">{{.DescTitle}}</div>
<div class="card"><div class="desc">{{.DescBody}}</div></div>
</div>
{{end}}
{{if .HasShop}}
<div class="sec">
<div class="sec-t">门店信息</div>
<div class="card">
<div class="row"><span>门店</span><i class="dots"></i><b>{{if .ShopCode}}<a href="/shop/{{.ShopCode}}">{{.ShopName}} </a>{{else}}{{.ShopName}}{{end}}</b></div>
{{if .ShopPhone}}<div class="row"><span>电话</span><i class="dots"></i><b class="mono"><a href="tel:{{.ShopPhone}}">{{.ShopPhone}}</a></b></div>{{end}}
{{if .ShopAddr}}<div class="row"><span>地址</span><i class="dots"></i><b>{{.ShopAddr}}</b></div>{{end}}
{{if .ShopHours}}<div class="row"><span>营业时间</span><i class="dots"></i><b>{{.ShopHours}}</b></div>{{end}}
{{if .ShopWx}}<div class="row"><span>微信</span><i class="dots"></i><b class="mono">{{.ShopWx}}</b></div>{{end}}
{{if .ShopCode}}<a class="more" href="/shop/{{.ShopCode}}">查看本店更多商品 </a>{{end}}
</div>
</div>
{{end}}
{{else}}
<div class="empty">
<h1 class="serif">商品不存在或已下架</h1>
<p>请确认链接来源,或联系门店核实。</p>
</div>
{{end}}
<footer class="foot">
<div class="foot-rule"></div>
<div><a class="brand" href="https://jiu.51yanmei.com">岩美酒库</a> · 正品溯源{{if .AppURL}} · <a href="{{.AppURL}}">在 App 中查看</a>{{end}}</div>
<div class="icp"><a href="https://beian.miit.gov.cn" target="_blank" rel="noopener">京ICP备2026039814号</a></div>
</footer>
</div>
</body>
</html>