首页/ mobileweb/ 小草水果店/ 代码预览

💻 代码预览 · 小草水果店

mw_shop · 上传者 小草
← 返回详情
小草水果店_H5/gen.py · 约 65484 字符
1#!/usr/bin/env python32# -*- coding: utf-8 -*-3"""生成小草水果店 H5 项目所有文件(8页:index/category/detail/cart/order/orders/member/mine)"""4import os5import re67OUT = os.path.dirname(os.path.abspath(__file__))89CSS = """/* 小草水果店 · 移动端 H5 样式(鲜橙+叶绿主题) */10*{margin:0;padding:0;box-sizing:border-box}11body{font-family:-apple-system,"PingFang SC","Microsoft YaHei",sans-serif;background:#fdf8f2;color:#2d2418;max-width:430px;margin:0 auto;min-height:100vh}12a{text-decoration:none;color:inherit}13ul{list-style:none}14:root{--primary:#ea580c;--primary-dark:#c2410c;--primary-light:#ffedd5;--secondary:#16a34a;--accent:#ca8a04;--gold:#b8860b;--dark:#7c2d12;--gray:#c2ad94;--light-gray:#faf3ea;--green:#16a34a;--blue:#2563eb;--orange:#ea580c;--red:#dc2626}15.header{background:linear-gradient(135deg,#c2410c,#ea580c);color:#fff;padding:12px 16px;display:flex;align-items:center;justify-content:space-between;position:sticky;top:0;z-index:100;box-shadow:0 2px 8px rgba(194,65,12,.3)}16.header .back{font-size:22px;cursor:pointer;width:32px}17.header h1{font-size:17px;font-weight:600;flex:1;text-align:center}18.header .right{width:32px;text-align:right;font-size:14px}19.tabbar{position:fixed;bottom:0;left:50%;transform:translateX(-50%);width:100%;max-width:430px;background:#fff;border-top:1px solid #eee;display:flex;z-index:100;padding-bottom:env(safe-area-inset-bottom)}20.tabbar a{flex:1;text-align:center;padding:8px 0;color:#999;font-size:11px}21.tabbar a.active{color:var(--primary)}22.tabbar a .icon{font-size:22px;display:block;margin-bottom:2px}23.card{background:#fff;border-radius:12px;margin:12px;padding:16px;box-shadow:0 1px 4px rgba(0,0,0,.05)}24.section-title{font-size:16px;font-weight:700;margin:16px 16px 8px;display:flex;justify-content:space-between;align-items:center}25.section-title span{font-size:12px;color:#999;font-weight:400}26.btn{display:block;width:100%;padding:13px;border:none;border-radius:25px;font-size:15px;font-weight:600;cursor:pointer;text-align:center}27.btn-primary{background:linear-gradient(135deg,#c2410c,#ea580c);color:#fff}28.btn-gold{background:linear-gradient(135deg,#ca8a04,#eab308);color:#fff}29.btn-outline{background:#fff;border:1px solid var(--primary);color:var(--primary)}30.btn-red{background:linear-gradient(135deg,#dc2626,#ea580c);color:#fff}31.badge{display:inline-block;padding:2px 8px;border-radius:10px;font-size:11px;font-weight:600}32.badge-hot{background:#fff1f0;color:#dc2626}33.badge-new{background:#eef2ff;color:var(--blue)}34.badge-sale{background:#fff7e6;color:var(--orange)}35.badge-org{background:#dcf3e3;color:#166534}36.tag{display:inline-block;padding:2px 6px;border-radius:4px;font-size:11px;background:var(--light-gray);color:#9a5b1f;margin:2px 4px 0 0}37/* 首页 */38.banner{height:168px;margin:12px;border-radius:14px;background:linear-gradient(135deg,#c2410c,#ea580c,#f59e0b);color:#fff;display:flex;align-items:center;padding:20px;position:relative;overflow:hidden}39.banner .bn-title{font-size:22px;font-weight:800;letter-spacing:1px}40.banner .bn-sub{font-size:12px;opacity:.94;margin-top:6px;line-height:1.7}41.banner .bn-badge{display:inline-block;background:rgba(255,255,255,.22);padding:4px 12px;border-radius:14px;font-size:11px;margin-top:10px}42.banner .bn-emoji{position:absolute;right:10px;font-size:68px;opacity:.95}43.search-box{margin:12px;background:#fff;border-radius:22px;padding:11px 16px;display:flex;align-items:center;gap:8px;box-shadow:0 1px 4px rgba(0,0,0,.05)}44.search-box .s-ico{font-size:18px}45.search-box input{border:none;outline:none;flex:1;font-size:13px;color:#2d2418}46.search-box .s-btn{background:linear-gradient(135deg,#c2410c,#ea580c);color:#fff;padding:6px 14px;border-radius:16px;font-size:12px;font-weight:700}47.cat-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;padding:0 12px}48.cat-grid a{background:#fff;border-radius:12px;padding:14px 4px;text-align:center;box-shadow:0 1px 4px rgba(0,0,0,.04)}49.cat-grid a .c-emoji{font-size:28px;display:block}50.cat-grid a .c-name{font-size:12px;margin-top:6px;color:#9a5b1f;font-weight:600}51.quick-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:6px;padding:16px 10px;background:#fff;margin:12px;border-radius:14px}52.quick-grid a{text-align:center;font-size:11px;color:#9a5b1f}53.quick-grid a .qicon{width:44px;height:44px;margin:0 auto 5px;border-radius:50%;background:var(--primary-light);display:flex;align-items:center;justify-content:center;font-size:22px}54.price-news{background:#fff;border-radius:14px;margin:12px;padding:14px;box-shadow:0 1px 4px rgba(0,0,0,.05)}55.price-news .pn-head{display:flex;align-items:center;gap:8px;font-size:14px;font-weight:700}56.price-news .pn-head .pn-tag{background:#ffedd5;color:var(--primary-dark);font-size:11px;padding:2px 8px;border-radius:10px}57.price-news .pn-item{display:flex;align-items:center;gap:10px;padding:9px 0;border-bottom:1px solid #f8efe2;font-size:12px}58.price-news .pn-item:last-child{border-bottom:none}59.price-news .pn-item .pn-name{flex:1}60.price-news .pn-item .pn-price{font-weight:700;color:var(--primary-dark)}61.price-news .pn-item .pn-chg.up{color:var(--red)}62.price-news .pn-item .pn-chg.down{color:var(--green)}63.seckill{background:#fff;border-radius:14px;margin:12px;overflow:hidden;box-shadow:0 1px 4px rgba(0,0,0,.05)}64.seckill .sk-head{background:linear-gradient(135deg,#dc2626,#ea580c);color:#fff;padding:10px 14px;display:flex;align-items:center;gap:10px}65.seckill .sk-head b{font-size:15px}66.seckill .sk-head .sk-time{display:flex;gap:3px;margin-left:auto}67.seckill .sk-head .sk-time i{background:rgba(255,255,255,.25);padding:2px 6px;border-radius:4px;font-size:13px;font-style:normal;font-weight:700}68.seckill .sk-body{display:flex;gap:10px;padding:12px;overflow-x:auto;scrollbar-width:none}69.seckill .sk-item{width:96px;flex-shrink:0;text-align:center}70.seckill .sk-item .sk-img{height:72px;border-radius:10px;background:var(--primary-light);display:flex;align-items:center;justify-content:center;font-size:36px}71.seckill .sk-item .sk-name{font-size:11px;margin-top:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}72.seckill .sk-item .sk-price{color:var(--red);font-weight:800;font-size:14px;margin-top:2px}73.seckill .sk-item .sk-old{color:#c9b8a0;font-size:10px;text-decoration:line-through}74.cert-bar{background:linear-gradient(135deg,#166534,#16a34a);margin:12px;border-radius:14px;padding:14px;color:#fff;display:flex;align-items:center;gap:12px}75.cert-bar .cb-ico{font-size:34px}76.cert-bar .cb-body b{font-size:14px;display:block}77.cert-bar .cb-body span{font-size:11px;opacity:.9;display:block;margin-top:2px;line-height:1.6}78.cert-bar .cb-btn{margin-left:auto;background:rgba(255,255,255,.22);padding:7px 12px;border-radius:14px;font-size:11px;font-weight:700}79.beef-card{background:#fff;border-radius:14px;margin:10px 12px;padding:12px;display:flex;gap:12px;box-shadow:0 1px 4px rgba(0,0,0,.05)}80.beef-card .bc-img{width:92px;height:92px;border-radius:10px;background:linear-gradient(135deg,#ffedd5,#fed7aa);display:flex;align-items:center;justify-content:center;font-size:44px;flex-shrink:0}81.beef-card .bc-body{flex:1;min-width:0}82.beef-card .bc-name{font-size:14px;font-weight:700}83.beef-card .bc-desc{font-size:11px;color:#b09a7e;margin-top:3px}84.beef-card .bc-meta{font-size:10px;color:#c4b299;margin-top:3px}85.beef-card .bc-foot{display:flex;justify-content:space-between;align-items:center;margin-top:6px}86.beef-card .bc-price{color:var(--red);font-weight:800;font-size:17px}87.beef-card .bc-price small{font-size:11px;color:#c4b299;font-weight:400}88.beef-card .bc-add{background:linear-gradient(135deg,#c2410c,#ea580c);color:#fff;width:28px;height:28px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:17px;font-weight:700}89/* 选购 */90.cat-tabs{display:flex;gap:8px;padding:0 12px;overflow-x:auto;padding-bottom:4px;scrollbar-width:none;position:sticky;top:0;z-index:99;background:#fdf8f2}91.cat-tab{padding:8px 14px;border:1px solid #f2d8b8;border-radius:20px;font-size:12px;cursor:pointer;background:#fff;white-space:nowrap;flex-shrink:0}92.cat-tab.sel{border-color:var(--primary);background:var(--primary-light);color:var(--primary-dark);font-weight:600}93.sort-bar{display:flex;gap:14px;padding:10px 12px;font-size:13px;color:#9a5b1f}94.sort-bar span.on{color:var(--primary);font-weight:700}95.cart-float{position:fixed;bottom:0;left:50%;transform:translateX(-50%);width:100%;max-width:430px;background:#fff;border-top:1px solid #eee;display:flex;align-items:center;padding:10px 12px;padding-bottom:calc(10px + env(safe-area-inset-bottom));z-index:100;gap:10px;box-shadow:0 -2px 8px rgba(0,0,0,.06)}96.cart-float .cf-cart{display:flex;align-items:center;gap:6px;font-size:12px;color:#9a5b1f}97.cart-float .cf-cart .ico{font-size:24px;position:relative}98.cart-float .cf-cart .num{position:absolute;top:-6px;right:-10px;background:var(--red);color:#fff;border-radius:9px;font-size:9px;padding:1px 5px}99.cart-float .cf-total{flex:1;text-align:right;font-size:12px;color:#b09a7e}100.cart-float .cf-total b{color:var(--red);font-size:18px}101.cart-float .cf-btn{background:linear-gradient(135deg,#c2410c,#ea580c);color:#fff;border-radius:20px;padding:11px 22px;font-size:14px;font-weight:600}102/* 详情 */103.detail-img{height:230px;background:linear-gradient(135deg,#ffedd5,#fed7aa);display:flex;align-items:center;justify-content:center;font-size:84px;position:relative}104.detail-img .di-badge{position:absolute;top:12px;left:12px;background:rgba(0,0,0,.45);color:#fff;padding:4px 10px;border-radius:12px;font-size:11px}105.detail-price{background:#fff;margin:12px;border-radius:14px;padding:16px}106.detail-price .dp-num{font-size:26px;font-weight:800;color:var(--red)}107.detail-price .dp-num small{font-size:12px;color:#999}108.detail-price .dp-meta{font-size:12px;color:#b09a7e;margin-top:4px;line-height:1.7}109.detail-price .dp-row{display:flex;gap:8px;margin-top:10px}110.detail-price .dp-cell{flex:1;background:var(--light-gray);border-radius:10px;padding:8px;text-align:center;font-size:11px;color:#9a5b1f}111.tier-box{background:#fff;margin:12px;border-radius:14px;padding:16px}112.tier-box .tb-title{font-size:14px;font-weight:700;margin-bottom:10px;display:flex;align-items:center;gap:6px}113.tier-row{display:flex;align-items:center;gap:10px;padding:9px 0;border-bottom:1px solid #f8efe2;font-size:13px}114.tier-row:last-child{border-bottom:none}115.tier-row .tr-label{width:96px;color:#9a5b1f;flex-shrink:0}116.tier-row .tr-price{flex:1;text-align:right;font-weight:700;color:var(--primary-dark)}117.tier-row .tr-price b{font-size:16px}118.tier-row.cur{background:var(--primary-light);border-radius:8px;margin:0 -8px;padding:9px 8px}119.tier-row.cur .tr-label{color:var(--primary-dark);font-weight:700}120.spec-box{background:#fff;margin:12px;border-radius:14px;padding:16px}121.spec-box .sb-title{font-size:14px;font-weight:700;margin-bottom:10px}122.spec-row{display:flex;align-items:center;gap:10px;padding:8px 0;border-bottom:1px solid #f8efe2}123.spec-row:last-child{border-bottom:none}124.spec-row .sr-label{width:70px;font-size:13px;color:#9a5b1f;flex-shrink:0}125.spec-row .sr-opts{display:flex;gap:8px;flex:1;flex-wrap:wrap}126.spec-opt{padding:6px 12px;border:1px solid #f2d8b8;border-radius:14px;font-size:12px;cursor:pointer;background:#fff}127.spec-opt.sel{border-color:var(--primary);background:var(--primary-light);color:var(--primary-dark);font-weight:600}128.spec-row .sr-num{display:flex;align-items:center;gap:8px;margin-left:auto}129.spec-row .sr-num i{width:26px;height:26px;border:1px solid #f2d8b8;border-radius:50%;display:flex;align-items:center;justify-content:center;font-style:normal;cursor:pointer}130.eval-card{background:#fff;border-radius:14px;margin:10px 12px;padding:12px;box-shadow:0 1px 4px rgba(0,0,0,.05)}131.eval-card .ev-head{display:flex;align-items:center;gap:8px;font-size:12px}132.eval-card .ev-avatar{width:28px;height:28px;border-radius:50%;background:var(--primary-light);display:flex;align-items:center;justify-content:center;font-size:14px}133.eval-card .ev-star{color:var(--accent);font-size:11px}134.eval-card .ev-text{font-size:12px;color:#6b5842;line-height:1.7;margin-top:6px}135.buy-bar{position:fixed;bottom:0;left:50%;transform:translateX(-50%);width:100%;max-width:430px;background:#fff;border-top:1px solid #eee;display:flex;align-items:center;padding:10px 12px;padding-bottom:calc(10px + env(safe-area-inset-bottom));z-index:100;gap:10px}136.buy-bar .bb-cart{display:flex;align-items:center;gap:6px;font-size:12px;color:#9a5b1f}137.buy-bar .bb-cart .ico{font-size:24px;position:relative}138.buy-bar .bb-cart .num{position:absolute;top:-6px;right:-10px;background:var(--red);color:#fff;border-radius:9px;font-size:9px;padding:1px 5px}139.buy-bar .bb-btn{flex:1;border-radius:20px;padding:11px;text-align:center;color:#fff;font-size:14px;font-weight:600}140.buy-bar .bb-btn.buy{background:linear-gradient(135deg,#ca8a04,#eab308)}141.buy-bar .bb-btn.now{background:linear-gradient(135deg,#c2410c,#ea580c)}142/* 购物车 */143.cart-item{background:#fff;border-radius:14px;margin:10px 12px;padding:12px;display:flex;gap:12px;align-items:center;box-shadow:0 1px 4px rgba(0,0,0,.05)}144.ci-check{width:22px;height:22px;border-radius:50%;border:2px solid #e8c9a4;flex-shrink:0;display:flex;align-items:center;justify-content:center;color:#fff;font-size:12px;background:#fff}145.ci-check.on,.cart-item.checked .ci-check{background:var(--primary);border-color:var(--primary)}146.cart-item .ci-img{width:70px;height:70px;border-radius:10px;background:var(--primary-light);display:flex;align-items:center;justify-content:center;font-size:32px;flex-shrink:0}147.cart-item .ci-body{flex:1;min-width:0}148.cart-item .ci-name{font-size:13px;font-weight:700}149.cart-item .ci-spec{font-size:11px;color:#b09a7e;margin-top:2px}150.cart-item .ci-foot{display:flex;justify-content:space-between;align-items:center;margin-top:6px}151.cart-item .ci-price{color:var(--red);font-weight:800}152.cart-item .ci-num{display:flex;align-items:center;gap:8px}153.cart-item .ci-num i{width:24px;height:24px;border:1px solid #f2d8b8;border-radius:50%;display:flex;align-items:center;justify-content:center;font-style:normal;font-size:13px}154.settle-bar{position:fixed;bottom:0;left:50%;transform:translateX(-50%);width:100%;max-width:430px;background:#fff;border-top:1px solid #eee;display:flex;align-items:center;padding:10px 12px;padding-bottom:calc(10px + env(safe-area-inset-bottom));z-index:100;gap:10px}155.settle-bar .sb-all{display:flex;align-items:center;gap:6px;font-size:12px;color:#9a5b1f}156.settle-bar .sb-total{flex:1;text-align:right;font-size:12px;color:#b09a7e}157.settle-bar .sb-total b{color:var(--red);font-size:18px}158.settle-bar .sb-btn{background:linear-gradient(135deg,#c2410c,#ea580c);color:#fff;border-radius:20px;padding:11px 26px;font-size:14px;font-weight:600}159.check-box{background:#fff;border-radius:14px;margin:12px;padding:16px}160.check-box .cb-row{display:flex;align-items:center;gap:10px;padding:10px 0;border-bottom:1px solid #f8efe2;font-size:13px}161.check-box .cb-row:last-child{border-bottom:none}162.check-box .cb-label{width:86px;color:#9a5b1f;flex-shrink:0}163.check-box .cb-val{flex:1;text-align:right;color:#2d2418}164.check-box .cb-val.dim{color:#c9b8a0}165.check-box .cb-val .opt{padding:5px 10px;border:1px solid #f2d8b8;border-radius:12px;font-size:12px;margin-left:6px}166.check-box .cb-val .opt.sel{border-color:var(--primary);background:var(--primary-light);color:var(--primary-dark)}167/* 提交订单 */168.pay-card{background:#fff;border-radius:14px;margin:12px;padding:16px}169.pay-card .pc-row{display:flex;align-items:center;gap:10px;padding:11px 0;border-bottom:1px solid #f8efe2;font-size:13px}170.pay-card .pc-row:last-child{border-bottom:none}171.pay-card .pc-label{width:72px;color:#9a5b1f;flex-shrink:0}172.pay-card .pc-val{flex:1;color:#2d2418}173.pay-card .pc-val.dim{color:#c9b8a0}174.pay-way{background:#fff;border-radius:14px;margin:12px;padding:16px}175.pay-way .pw-title{font-size:14px;font-weight:700;margin-bottom:8px}176.pay-way .pw-item{display:flex;align-items:center;gap:10px;padding:12px 0;border-bottom:1px solid #f8efe2;font-size:14px}177.pay-way .pw-item:last-child{border-bottom:none}178.pay-way .pw-ico{font-size:24px}179.pay-way .pw-radio{margin-left:auto;width:20px;height:20px;border-radius:50%;border:2px solid #e8c9a4;display:flex;align-items:center;justify-content:center;color:#fff;font-size:11px}180.pay-way .pw-item.sel .pw-radio{background:var(--primary);border-color:var(--primary)}181/* 订单/配送状态 */182.order-tabs{display:flex;background:#fff;border-bottom:1px solid #f8efe2;position:sticky;top:0;z-index:99}183.order-tabs a{flex:1;text-align:center;padding:12px 4px;font-size:13px;color:#9a5b1f;position:relative}184.order-tabs a.active{color:var(--primary);font-weight:700}185.order-tabs a.active::after{content:"";position:absolute;bottom:0;left:25%;width:50%;height:3px;background:var(--primary);border-radius:3px}186.order-card{background:#fff;border-radius:14px;margin:10px 12px;padding:14px;box-shadow:0 1px 4px rgba(0,0,0,.05)}187.order-card .oc-head{display:flex;justify-content:space-between;font-size:12px;color:#b09a7e;padding-bottom:10px;border-bottom:1px solid #f8efe2}188.order-card .oc-head .st{color:var(--primary);font-weight:700}189.order-card .oc-goods{display:flex;gap:10px;padding:10px 0;align-items:center}190.order-card .oc-goods .og-img{width:52px;height:52px;border-radius:8px;background:var(--primary-light);display:flex;align-items:center;justify-content:center;font-size:24px}191.order-card .oc-goods .og-name{font-size:13px;font-weight:600;flex:1}192.order-card .oc-goods .og-price{font-size:12px;color:#b09a7e}193.order-card .oc-foot{display:flex;justify-content:space-between;align-items:center;font-size:12px;color:#b09a7e}194.order-card .oc-foot b{color:var(--red);font-size:15px}195.order-card .oc-ops{display:flex;gap:8px;margin-top:10px;justify-content:flex-end}196.order-card .oc-ops i{padding:6px 14px;border:1px solid #f2d8b8;border-radius:15px;font-style:normal;font-size:12px}197.order-card .oc-ops i.main{background:linear-gradient(135deg,#c2410c,#ea580c);color:#fff;border-color:transparent}198.call-bar{display:flex;gap:8px;margin:10px 12px}199.call-bar i{flex:1;text-align:center;padding:9px 0;border:1px solid #f2d8b8;border-radius:14px;font-style:normal;font-size:12px;color:#9a5b1f}200.call-bar i.main{background:var(--primary-light);color:var(--primary-dark);border-color:var(--primary);font-weight:600}201.status-line{background:#fff;border-radius:14px;margin:12px;padding:16px}202.status-line .sl-dot{display:flex;gap:12px;position:relative;padding-bottom:16px}203.status-line .sl-dot:last-child{padding-bottom:0}204.status-line .sl-c{width:14px;height:14px;border-radius:50%;background:#f0e2cd;flex-shrink:0;margin-top:2px;position:relative;z-index:1}205.status-line .sl-dot.done .sl-c{background:var(--green)}206.status-line .sl-dot.now .sl-c{background:var(--accent);box-shadow:0 0 0 4px #fdf3d9}207.status-line .sl-dot::before{content:"";position:absolute;left:6px;top:16px;bottom:-2px;width:2px;background:#f2e8d6}208.status-line .sl-dot:last-child::before{display:none}209.status-line .sl-title{font-size:13px;font-weight:600}210.status-line .sl-time{font-size:11px;color:#b09a7e;margin-top:2px}211.track-bar{background:#fff;border-radius:14px;margin:12px;padding:16px;display:flex;align-items:center;gap:12px}212.track-bar .tb-ico{font-size:30px}213.track-bar .tb-body{flex:1}214.track-bar .tb-body b{font-size:14px}215.track-bar .tb-body span{font-size:11px;color:#b09a7e;display:block;margin-top:2px}216.track-bar .tb-btn{background:var(--primary-light);color:var(--primary-dark);padding:8px 14px;border-radius:16px;font-size:12px;font-weight:700}217/* 会员中心 */218.vip-card{background:linear-gradient(135deg,#c2410c,#ea580c,#f59e0b);margin:12px;border-radius:16px;color:#fff;padding:20px;position:relative;overflow:hidden}219.vip-card::after{content:"FRESH";position:absolute;right:12px;top:10px;font-size:32px;font-weight:800;opacity:.15}220.vip-card .vc-level{font-size:13px;opacity:.9}221.vip-card .vc-name{font-size:20px;font-weight:800;margin-top:2px}222.vip-card .vc-exp{font-size:11px;opacity:.85;margin-top:4px}223.vip-card .vc-bar{height:6px;background:rgba(255,255,255,.25);border-radius:3px;margin-top:14px;position:relative}224.vip-card .vc-bar i{display:block;height:100%;width:68%;background:linear-gradient(90deg,#84cc16,#eab308);border-radius:3px}225.assets{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;padding:0 12px}226.asset-item{background:#fff;border-radius:12px;text-align:center;padding:14px 4px;box-shadow:0 1px 4px rgba(0,0,0,.05)}227.asset-item b{display:block;font-size:19px;color:var(--primary-dark)}228.asset-item span{font-size:11px;color:#b09a7e}229.sign-btn{background:linear-gradient(135deg,#ca8a04,#eab308);color:#fff;border-radius:20px;padding:11px;text-align:center;font-size:14px;font-weight:700;margin:12px;cursor:pointer}230.sign-btn.done{background:#f0e2cd;color:#a08c6e}231.vip-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:10px;padding:0 12px}232.vip-item{background:#fff;border-radius:12px;padding:14px;box-shadow:0 1px 4px rgba(0,0,0,.05)}233.vip-item .vi-emoji{font-size:26px}234.vip-item .vi-name{font-size:13px;font-weight:700;margin-top:4px}235.vip-item .vi-desc{font-size:10px;color:#b09a7e;margin-top:2px;line-height:1.5}236.recharge-box{background:#fff;border-radius:14px;margin:12px;padding:16px}237.recharge-box .rb-title{font-size:14px;font-weight:700;margin-bottom:10px}238.recharge-opts{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}239.recharge-opt{border:1px solid #f2d8b8;border-radius:10px;text-align:center;padding:10px 4px;font-size:12px}240.recharge-opt.sel{border-color:var(--primary);background:var(--primary-light);color:var(--primary-dark)}241.recharge-opt b{display:block;font-size:14px}242.recharge-opt span{color:#c9b8a0;font-size:10px}243.plan-box{background:#fff;border-radius:14px;margin:12px;padding:16px}244.plan-box .pb-title{font-size:14px;font-weight:700;margin-bottom:10px}245.plan-item{display:flex;align-items:center;gap:10px;padding:10px 0;border-bottom:1px solid #f8efe2;font-size:13px}246.plan-item:last-child{border-bottom:none}247.plan-item .pi-day{width:80px;color:#9a5b1f;flex-shrink:0}248.plan-item .pi-detail{flex:1;color:#6b5842}249.plan-item .pi-switch{width:42px;height:24px;border-radius:12px;background:var(--primary);position:relative;flex-shrink:0}250.plan-item .pi-switch i{position:absolute;top:2px;right:2px;width:20px;height:20px;border-radius:50%;background:#fff}251.plan-item.off .pi-switch{background:#f0e2cd}252.plan-item.off .pi-switch i{right:auto;left:2px}253.credit-box{background:linear-gradient(135deg,#b45309,#c2410c);margin:12px;border-radius:14px;padding:16px;color:#fff;display:flex;align-items:center;gap:12px}254.credit-box .cb-left{flex:1}255.credit-box .cb-left b{font-size:18px;display:block}256.credit-box .cb-left span{font-size:11px;opacity:.9}257.credit-box .cb-btn{background:rgba(255,255,255,.22);color:#fff;padding:8px 14px;border-radius:16px;font-size:12px;font-weight:700}258/* 我的 */259.user-card{background:linear-gradient(135deg,#c2410c,#ea580c);margin:12px;border-radius:14px;color:#fff;padding:18px;display:flex;align-items:center;gap:12px}260.user-card .uc-avatar{width:56px;height:56px;border-radius:50%;background:rgba(255,255,255,.25);display:flex;align-items:center;justify-content:center;font-size:30px}261.user-card .uc-name{font-size:17px;font-weight:600}262.user-card .uc-level{font-size:12px;opacity:.9;margin-top:3px}263.order-entry{background:#fff;border-radius:12px;margin:12px;display:flex;padding:14px 0}264.order-entry a{flex:1;text-align:center;font-size:11px;color:#9a5b1f}265.order-entry a .oe-ico{font-size:22px;display:block;margin-bottom:4px;position:relative}266.order-entry a .oe-num{position:absolute;top:-6px;right:-8px;background:var(--red);color:#fff;border-radius:8px;font-size:9px;padding:1px 4px}267.menu-list{background:#fff;border-radius:12px;margin:12px;overflow:hidden}268.menu-list a{display:flex;align-items:center;justify-content:space-between;padding:14px 16px;border-bottom:1px solid #f8efe2;font-size:14px}269.menu-list a:last-child{border-bottom:none}270.menu-list a .ml-l{display:flex;align-items:center;gap:10px}271.menu-list a .ml-l .ico{font-size:20px}272.menu-list a .ml-r{color:#ccc;font-size:12px}273.empty{text-align:center;color:#c9b8a0;font-size:13px;padding:40px 0}274.empty .e-icon{font-size:44px;display:block;margin-bottom:8px}275"""276DATA = """// 小草水果店 · 演示数据277window.DATA = {278  categories: ["当季鲜果", "进口水果", "热带水果", "时令瓜果", "果切鲜榨", "礼盒果篮"],279  units: ["斤", "个", "盒"],280  products: [281    { id: 1, img: "🍎", name: "烟台红富士苹果", cat: "当季鲜果", price: 8.8, unit: "斤", old: 12.8, sales: 26000, origin: "山东烟台", grade: { retail: 8.8, wholesale: 7.8, vip: 6.9 }, tags: ["脆甜多汁", "95#果径"], desc: "烟台主产区红富士,脆甜多汁不打蜡,95#以上大果径", hot: true, new: false },282    { id: 2, img: "🍇", name: "云南阳光玫瑰青提", cat: "热带水果", price: 19.9, unit: "斤", old: 28.8, sales: 18000, origin: "云南宾川", grade: { retail: 19.9, wholesale: 17.9, vip: 15.9 }, tags: ["无籽", "玫瑰香"], desc: "云南阳光玫瑰青提,无籽脆甜带玫瑰香,颗颗饱满", hot: true, new: false },283    { id: 3, img: "🍑", name: "无锡阳山水蜜桃", cat: "当季鲜果", price: 15.8, unit: "斤", old: 22, sales: 15000, origin: "江苏无锡", grade: { retail: 15.8, wholesale: 13.8, vip: 12.5 }, tags: ["软糯多汁", "头茬"], desc: "阳山核心产区水蜜桃,熟透软糯汁水丰盈,头茬果", hot: true, new: false },284    { id: 4, img: "🍉", name: "宁夏硒砂瓜", cat: "时令瓜果", price: 2.9, unit: "斤", old: 4.5, sales: 32000, origin: "宁夏中卫", grade: { retail: 2.9, wholesale: 2.4, vip: 2.2 }, tags: ["沙瓤甜", "5斤起"], desc: "宁夏硒砂压砂西瓜,沙瓤爆汁糖度14+,5斤起称", hot: true, new: false },285    { id: 5, img: "🍊", name: "赣南脐橙", cat: "进口水果", price: 5.9, unit: "斤", old: 8.8, sales: 21000, origin: "江西赣州", grade: { retail: 5.9, wholesale: 4.9, vip: 4.5 }, tags: ["现摘现发", "皮薄"], desc: "赣南脐橙现摘现发,皮薄核少汁多,酸甜比刚刚好", hot: true, new: false },286    { id: 6, img: "🥭", name: "海南金煌芒果", cat: "热带水果", price: 9.9, unit: "斤", old: 15.8, sales: 19000, origin: "海南三亚", grade: { retail: 9.9, wholesale: 8.5, vip: 7.8 }, tags: ["核薄肉厚", "自然熟"], desc: "海南金煌芒,核薄肉厚自然催熟,甜到心里不涩口", hot: true, new: false },287    { id: 7, img: "🍌", name: "厄瓜多尔香蕉", cat: "进口水果", price: 6.8, unit: "斤", old: 9.9, sales: 16000, origin: "厄瓜多尔", grade: { retail: 6.8, wholesale: 5.8, vip: 5.2 }, tags: ["进口直采", "粉糯"], desc: "厄瓜多尔直采香蕉,海运冷链直达,粉糯香甜", hot: false, new: false },288    { id: 8, img: "🍓", name: "丹东99草莓", cat: "当季鲜果", price: 39.9, unit: "盒", old: 58, sales: 8600, origin: "辽宁丹东", grade: { retail: 39.9, wholesale: 33.9, vip: 29.9 }, tags: ["A级果", "500g"], desc: "丹东99草莓A级果500g盒装,果面红润香气浓郁", hot: true, new: true },289    { id: 9, img: "🍍", name: "海南香水菠萝", cat: "热带水果", price: 4.5, unit: "个", old: 6.8, sales: 12000, origin: "海南琼海", grade: { retail: 4.5, wholesale: 3.8, vip: 3.4 }, tags: ["不泡盐水", "2.5斤"], desc: "琼海香水菠萝约2.5斤/个,不泡盐水直接吃,甜过蜂蜜", hot: false, new: false },290    { id: 10, img: "🫐", name: "云南蓝莓125g", cat: "进口水果", price: 25.9, unit: "盒", old: 35.9, sales: 9800, origin: "云南澄江", grade: { retail: 25.9, wholesale: 21.9, vip: 19.9 }, tags: ["18mm+", "4盒装"], desc: "澄江蓝莓18mm以上大果,125g×4盒装,花青素满满", hot: true, new: true },291    { id: 11, img: "🍈", name: "甘肃蜜宝甜瓜", cat: "时令瓜果", price: 3.9, unit: "斤", old: 5.8, sales: 11000, origin: "甘肃民乐", grade: { retail: 3.9, wholesale: 3.2, vip: 2.9 }, tags: ["网纹", "脆甜"], desc: "民乐网纹蜜宝甜瓜,皮薄瓤脆甜度16+,冰镇更绝", hot: false, new: false },292    { id: 12, img: "🥝", name: "徐庄绿心猕猴桃", cat: "进口水果", price: 7.9, unit: "斤", old: 11.9, sales: 10000, origin: "陕西眉县", grade: { retail: 7.9, wholesale: 6.6, vip: 5.9 }, tags: ["维C炸弹", "绿心"], desc: "眉县徐庄绿心猕猴桃,维C含量是橙子的8倍,酸甜开胃", hot: false, new: false },293    { id: 13, img: "🍉", name: "鲜榨西瓜汁杯", cat: "果切鲜榨", price: 12, unit: "杯", old: 18, sales: 13000, origin: "门店现榨", grade: { retail: 12, wholesale: 10, vip: 9 }, tags: ["无添加", "500ml"], desc: "门店现榨西瓜汁500ml,不加一滴水不放糖,清甜解暑", hot: true, new: false },294    { id: 14, img: "🍎", name: "缤纷果切拼盘", cat: "果切鲜榨", price: 25.9, unit: "盒", old: 35.9, sales: 14000, origin: "门店现切", grade: { retail: 25.9, wholesale: 21.9, vip: 19.9 }, tags: ["6种水果", "750g"], desc: "缤纷果切拼盘750g,6种当季水果现切现装,办公下午茶", hot: true, new: false },295    { id: 15, img: "🎁", name: "中秋四拼水果礼盒", cat: "礼盒果篮", price: 128, unit: "盒", old: 168, sales: 6800, origin: "产地严选", grade: { retail: 128, wholesale: 108, vip: 98 }, tags: ["四拼", "配礼袋"], desc: "中秋四拼礼盒:苹果+橙子+提子+猕猴桃,配礼袋提绳", hot: true, new: true }296  ],297  combos: [298    { img: "🧺", name: "一周维C补给包", price: 69.9, old: 89.9, desc: "橙子4斤+猕猴桃2斤+柠檬2个" },299    { img: "🥤", name: "榨汁神器组合", price: 49.9, old: 69.9, desc: "菠萝1个+西瓜2斤+柠檬2个" }300  ],301  seckills: [302    { img: "🍉", name: "硒砂瓜", price: 1.9, old: 2.9 },303    { img: "🍎", name: "红富士", price: 5.9, old: 8.8 },304    { img: "🍊", name: "赣南脐橙", price: 3.9, old: 5.9 },305    { img: "🥭", name: "金煌芒", price: 6.9, old: 9.9 }306  ],307  priceNews: [308    { name: "阳光玫瑰青提", price: "19.9/斤", chg: "-8%", dir: "down" },309    { name: "红富士苹果", price: "8.8/斤", chg: "+2%", dir: "up" },310    { name: "赣南脐橙", price: "5.9/斤", chg: "-5%", dir: "down" },311    { name: "阳山水蜜桃", price: "15.8/斤", chg: "+6%", dir: "up" }312  ],313  evals: [314    { avatar: "👩", name: "宝妈 刘女士", star: "★★★★★", text: "阳光玫瑰和草莓都是当季最甜的,坏果赔付秒到账,给娃吃很放心。" },315    { avatar: "👨", name: "办公室白领 张先生", star: "★★★★★", text: "果切拼盘下午茶刚需,1小时送到公司,切得干净不泡水。" },316    { avatar: "👵", name: "社区王阿姨", star: "★★★★☆", text: "水果卡充500送50很划算,每周固定送两次,西瓜甜得没话说。" }317  ],318  coupons: [319    { name: "新客无门槛券", val: "¥10", cond: "满 30 可用" },320    { name: "满减券", val: "¥20", cond: "满 88 可用" },321    { name: "果切券", val: "¥8", cond: "果切鲜榨专享" }322  ],323  recharge: [324    { val: "500", gift: "送 50 元券" },325    { val: "1000", gift: "送 120 元券" },326    { val: "2000", gift: "送 300 元券" }327  ],328  stores: [329    { name: "城南水果总店", dist: "1.2km", time: "07:00-22:00", addr: "城南农贸市场东门 12 号" },330    { name: "滨江自提柜", dist: "2.6km", time: "08:00-21:00", addr: "滨江小区北门智能柜" }331  ],332  creditLevels: [333    { level: "普通会员", discount: "9.8 折", credit: "¥0", note: "散客/家庭" },334    { level: "银卡 · 果友", discount: "9.5 折", credit: "¥500", note: "月消费满 300" },335    { level: "金卡 · 鲜果达人", discount: "9 折免运", credit: "¥2000", note: "月消费满 1000" },336    { level: "钻石 · 果卡会员", discount: "8.5 折", credit: "¥5000", note: "预存 2000 以上" }337  ],338  regularPlans: [339    { day: "每周一", detail: "红富士 4 斤 + 脐橙 4 斤", on: true },340    { day: "每周三", detail: "青提 2 斤 + 蓝莓 1 盒", on: true },341    { day: "每周五", detail: "西瓜 1 个 + 果切拼盘 1 盒", on: false }342  ],343  orderStatus: [344    { title: "已接单 · 门店备货中", time: "10:12", done: true },345    { title: "已分拣 · 鲜果质检称重", time: "10:40", now: true },346    { title: "配送中 · 骑手已出发", time: "预计 11:30", done: false },347    { title: "已送达 · 请确认收货", time: "待送达", done: false }348  ]349};350"""351352APP = """// 小草水果店 · 交互逻辑353document.addEventListener('click', function (e) {354  var t = e.target.closest('[data-toast]');355  if (t) { toast(t.getAttribute('data-toast')); }356  var ct = e.target.closest('.cat-tab');357  if (ct) {358    var wrap = ct.parentElement;359    [].forEach.call(wrap.children, function (x) { x.classList.remove('sel'); });360    ct.classList.add('sel');361    var kw = ct.textContent;362    var cards = document.querySelectorAll('.beef-card');363    [].forEach.call(cards, function (c) {364      c.style.display = (kw === '全部' || c.getAttribute('data-cat') === kw) ? 'flex' : 'none';365    });366  }367  var so = e.target.closest('.sort-bar span');368  if (so) {369    var w2 = so.parentElement;370    [].forEach.call(w2.children, function (x) { x.classList.remove('on'); });371    so.classList.add('on');372  }373  var sp = e.target.closest('.spec-opt');374  if (sp) {375    var grp = sp.parentElement;376    [].forEach.call(grp.children, function (x) { x.classList.remove('sel'); });377    sp.classList.add('sel');378  }379  var sn = e.target.closest('.sr-num i');380  if (sn) {381    var b = sn.parentElement.querySelector('b');382    var v = parseInt(b.textContent) || 1;383    v = sn.textContent === '+' ? v + 1 : Math.max(1, v - 1);384    b.textContent = v;385  }386  var ci = e.target.closest('.ci-num i');387  if (ci) {388    var b = ci.parentElement.querySelector('b');389    var v = parseInt(b.textContent) || 1;390    v = ci.textContent === '+' ? v + 1 : Math.max(1, v - 1);391    b.textContent = v;392  }393  var ck = e.target.closest('.ci-check');394  if (ck) { ck.parentElement.classList.toggle('checked'); ck.classList.toggle('on'); }395  var opt = e.target.closest('.cb-val .opt');396  if (opt) {397    var grp = opt.parentElement;398    [].forEach.call(grp.children, function (x) { x.classList.remove('sel'); });399    opt.classList.add('sel');400  }401  var pw = e.target.closest('.pw-item');402  if (pw) {403    var box = pw.parentElement;404    [].forEach.call(box.children, function (x) { x.classList.remove('sel'); });405    pw.classList.add('sel');406  }407  var sg = e.target.closest('.sign-btn');408  if (sg && !sg.classList.contains('done')) { sg.classList.add('done'); sg.textContent = '今日已签到 +10 积分'; toast('签到成功,积分 +10'); }409  var rg = e.target.closest('.recharge-opt');410  if (rg) {411    var grp = rg.parentElement;412    [].forEach.call(grp.children, function (x) { x.classList.remove('sel'); });413    rg.classList.add('sel');414  }415  var cp = e.target.closest('.cc-btn');416  if (cp) { cp.textContent = '已领取'; cp.style.opacity = '.6'; toast('优惠券已到账'); }417  var pl = e.target.closest('.pi-switch');418  if (pl) { pl.parentElement.classList.toggle('off'); }419});420// 秒杀倒计时421(function () {422  var box = document.querySelector('.sk-time');423  if (!box) return;424  var total = 2 * 3600 + 12 * 60 + 40;425  setInterval(function () {426    total--;427    if (total < 0) total = 86399;428    var h = Math.floor(total / 3600), m = Math.floor(total % 3600 / 60), s = total % 60;429    var z = function (n) { return n < 10 ? '0' + n : '' + n; };430    box.innerHTML = '<i>' + z(h) + '</i>:<i>' + z(m) + '</i>:<i>' + z(s) + '</i>';431  }, 1000);432})();433function toast(msg) {434  var d = document.createElement('div');435  d.style.cssText = 'position:fixed;left:50%;bottom:110px;transform:translateX(-50%);background:rgba(194,65,12,.92);color:#fff;padding:10px 20px;border-radius:20px;font-size:13px;z-index:999';436  d.textContent = msg;437  document.body.appendChild(d);438  setTimeout(function () { d.remove(); }, 1800);439}440"""441442def page(title, active, body, tabbar):443    inline_scripts = re.findall(r'<script>(.*?)</script>', body, re.S)444    body_clean = re.sub(r'<script>.*?</script>', '', body, flags=re.S)445    inline_html = "".join("<script>" + s + "</script>" for s in inline_scripts)446    return """<!DOCTYPE html>447<html lang="zh-CN">448<head>449<meta charset="UTF-8"/>450<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"/>451<title>""" + title + """</title>452<link rel="stylesheet" href="style.css"/>453</head>454<body>455""" + body_clean + """456""" + tabbar + """457<script src="data.js"></script>458""" + inline_html + """459<script src="app.js"></script>460</body>461</html>"""462463def tabbar(active):464    items = [465        ("index.html", "🏠", "首页"),466        ("category.html", "🍎", "选购"),467        ("cart.html", "🛒", "购物车"),468        ("member.html", "👑", "会员"),469        ("mine.html", "👤", "我的"),470    ]471    h = '<nav class="tabbar">'472    for href, icon, name in items:473        cls = ' active' if name == active else ''474        h += '<a class="' + cls + '" href="' + href + '"><span class="icon">' + icon + '</span>' + name + '</a>'475    return h + '</nav>'476477def header(title, back=True, right=""):478    b = '<a class="back" onclick="history.back()">‹</a>' if back else '<span class="back"></span>'479    return '<header class="header">' + b + '<h1>' + title + '</h1><span class="right">' + right + '</span></header>'480481INDEX = """482<div class="banner">483  <div>484    <div class="bn-title">小草水果店</div>485    <div class="bn-sub">产地直采 · 坏果秒赔 · 1 小时极速达<br/>当季鲜果 · 果切鲜榨 · 礼盒果篮 · 支持预售锁单</div>486    <div class="bn-badge">🎁 新客首单立减 10 元</div>487  </div>488  <div class="bn-emoji">🍉</div>489</div>490<div class="search-box" data-toast="拍照找果:上传水果图自动匹配">491  <span class="s-ico">🔍</span>492  <input placeholder="搜索阳光玫瑰 / 草莓 / 西瓜 / 果切…"/>493  <span class="s-btn">搜索</span>494</div>495<div class="cert-bar">496  <div class="cb-ico">🥇</div>497  <div class="cb-body">498    <b>产地直采 · 甜度检测可溯源</b>499    <span>每批鲜果附产地证明 + 甜度检测,扫码可查采摘与质检信息</span>500  </div>501  <div class="cb-btn" data-toast="已查看产地与甜度检测">查看溯源</div>502</div>503<div class="cat-grid">504  <a href="category.html"><span class="c-emoji">🍎</span><span class="c-name">当季鲜果</span></a>505  <a href="category.html"><span class="c-emoji">🍇</span><span class="c-name">进口水果</span></a>506  <a href="category.html"><span class="c-emoji">🥭</span><span class="c-name">热带水果</span></a>507  <a href="category.html"><span class="c-emoji">🍉</span><span class="c-name">时令瓜果</span></a>508  <a href="category.html"><span class="c-emoji">🧃</span><span class="c-name">果切鲜榨</span></a>509  <a href="category.html"><span class="c-emoji">🎁</span><span class="c-name">礼盒果篮</span></a>510</div>511<div class="quick-grid">512  <a href="category.html"><div class="qicon">🧺</div>当季鲜果</a>513  <a data-toast="已为你开启每周固定配送"><div class="qicon">🔁</div>定期配送</a>514  <a href="member.html"><div class="qicon">💳</div>水果卡</a>515  <a href="cart.html"><div class="qicon">🛒</div>购物车</a>516  <a data-toast="邀请好友各得 5 元券"><div class="qicon">🤝</div>邀请有礼</a>517</div>518<div class="price-news">519  <div class="pn-head">📈 今日鲜果行情 <span class="pn-tag">实时更新</span></div>520  <div id="priceList"></div>521</div>522<div class="seckill">523  <div class="sk-head"><b>⚡ 限时秒杀 · 鲜果特价</b><div class="sk-time"><i>02</i>:<i>12</i>:<i>40</i></div></div>524  <div class="sk-body" id="skList"></div>525</div>526<div class="coupon-card" style="background:linear-gradient(135deg,#c2410c,#ea580c);margin:12px;border-radius:14px;padding:14px;display:flex;align-items:center;gap:12px;color:#fff">527  <div style="flex:1"><b style="font-size:18px;display:block">新客无门槛 10 元券</b><span style="font-size:11px;opacity:.9">满 30 可用 · 30 天内有效</span></div>528  <div class="cc-btn" data-toast="优惠券已到账" style="background:#fff;color:#c2410c;padding:8px 16px;border-radius:16px;font-size:12px;font-weight:700">立即领取</div>529</div>530<div class="section-title">🔥 产地当季爆品 <span>月供 5 万斤+</span></div>531<div class="beef-card" data-toast="已加入购物车">532  <div class="bc-img">🍇</div>533  <div class="bc-body">534    <div class="bc-name">云南阳光玫瑰青提 <span class="badge badge-org">产地直采</span></div>535    <div class="bc-desc">云南宾川阳光玫瑰,无籽脆甜带玫瑰香,颗颗饱满</div>536    <div class="bc-meta">月供 1.8 万斤+ · 云南宾川 · 18mm+</div>537    <div class="bc-foot"><div class="bc-price">¥19.9<small> /斤 原28.8</small></div><div class="bc-add">+</div></div>538  </div>539</div>540<div class="section-title">🧺 组合水果包</div>541<div id="comboList"></div>542<div class="section-title">🏪 自提 / 配送点</div>543<div id="storeList"></div>544<script>545  var pl = document.getElementById('priceList');546  var h0 = '';547  window.DATA.priceNews.forEach(function (x) {548    h0 += '<div class="pn-item"><span class="pn-name">' + x.name + '</span><span class="pn-price">' + x.price + '</span>'549      + '<span class="pn-chg ' + x.dir + '">' + x.chg + '</span></div>';550  });551  pl.innerHTML = h0;552  var sk = document.getElementById('skList');553  var h = '';554  window.DATA.seckills.forEach(function (x) {555    h += '<div class="sk-item"><div class="sk-img">' + x.img + '</div><div class="sk-name">' + x.name + '</div>'556      + '<div class="sk-price">¥' + x.price + '</div><div class="sk-old">¥' + x.old + '</div></div>';557  });558  sk.innerHTML = h;559  var cl = document.getElementById('comboList');560  var h2 = '';561  window.DATA.combos.forEach(function (c) {562    h2 += '<div class="beef-card"><div class="bc-img">' + c.img + '</div><div class="bc-body">'563      + '<div class="bc-name">' + c.name + ' <span class="badge badge-sale">组合</span></div>'564      + '<div class="bc-desc">' + c.desc + '</div>'565      + '<div class="bc-foot"><div class="bc-price">¥' + c.price + '<small> /原' + c.old + '</small></div>'566      + '<div class="bc-add" data-toast="组合已加入购物车">+</div></div></div></div>';567  });568  cl.innerHTML = h2;569  var sl = document.getElementById('storeList');570  var h3 = '';571  window.DATA.stores.slice(0, 2).forEach(function (s) {572    h3 += '<div class="beef-card"><div class="bc-img">🏪</div><div class="bc-body">'573      + '<div class="bc-name">' + s.name + ' <span class="tag">' + s.dist + '</span></div>'574      + '<div class="bc-desc">' + s.addr + ' · 营业 ' + s.time + '</div>'575      + '<div class="bc-foot"><div class="bc-add" data-toast="已选择该自提点" style="width:auto;height:auto;border-radius:14px;padding:6px 14px;font-size:12px">选点</div></div></div></div>';576  });577  sl.innerHTML = h3;578</script>579"""580581582CATEGORY = """583""" + header("鲜果选购", back=False, right="🔍") + """584<div class="cat-tabs"></div>585<div class="sort-bar"><span class="on">综合排序</span><span>销量优先</span><span>价格从低到高</span></div>586<div id="catList"></div>587<div class="cart-float">588  <div class="cf-cart"><span class="ico">🛒<span class="num">5</span></span>购物车</div>589  <div class="cf-total"><b>¥86</b></div>590  <div class="cf-btn" data-toast="已跳转购物车">去结算</div>591</div>592<script>593  var ctw = document.querySelector('.cat-tabs');594  var h0 = '<div class="cat-tab sel">全部</div>';595  window.DATA.categories.forEach(function (c) {596    h0 += '<div class="cat-tab">' + c + '</div>';597  });598  ctw.innerHTML = h0;599  var cl = document.getElementById('catList');600  var h = '';601  window.DATA.products.forEach(function (b) {602    h += '<div class="beef-card" data-cat="' + b.cat + '"><div class="bc-img">' + b.img + '</div><div class="bc-body">'603      + '<div class="bc-name">' + b.name + (b.hot ? ' <span class="badge badge-hot">热卖</span>' : '') + (b.new ? ' <span class="badge badge-new">新品</span>' : '') + '</div>'604      + '<div class="bc-desc">' + b.desc + '</div>'605      + '<div class="bc-meta">月供 ' + b.sales.toLocaleString() + '+ · ' + b.origin + ' · ' + b.tags.join('/') + '</div>'606      + '<div class="bc-foot"><div class="bc-price">¥' + b.price + '<small> /' + b.unit + (b.old ? ' 原' + b.old : '') + '</small></div>'607      + '<div class="bc-add" data-toast="已加入购物车">+</div></div></div></div>';608  });609  cl.innerHTML = h;610</script>611"""612613DETAIL = """614""" + header("商品详情") + """615<div class="detail-img"><div class="di-badge">📷 实拍 · 产地溯源码</div>🍇</div>616<div class="detail-price">617  <div class="dp-num">¥19.9<small> /斤</small> <span style="color:#dc2626;font-size:13px">会员 ¥15.9 起</span></div>618  <div class="dp-meta">云南阳光玫瑰青提 · 产地直采 · 18mm+ 大果 · 带溯源码 · 家庭办公通用</div>619  <div class="dp-row">620    <div class="dp-cell">🌱 产地直采</div>621    <div class="dp-cell">🥇 甜度检测</div>622    <div class="dp-cell">❄️ 冷链到家</div>623    <div class="dp-cell">🚚 1h 达</div>624  </div>625</div>626<div class="tier-box">627  <div class="tb-title">💎 一客一价 · 您的等级价</div>628  <div class="tier-row"><span class="tr-label">零售价</span><span class="tr-price">¥<b>19.9</b>/斤</span></div>629  <div class="tier-row"><span class="tr-label">批发价</span><span class="tr-price">¥<b>17.9</b>/斤</span></div>630  <div class="tier-row cur"><span class="tr-label">金卡会员价</span><span class="tr-price">¥<b>15.9</b>/斤</span></div>631  <div style="text-align:right;font-size:11px;color:#c4b299;margin-top:8px">采购量越大越优惠 · 当前显示金卡会员价</div>632</div>633<div class="spec-box">634  <div class="sb-title">选择规格</div>635  <div class="spec-row"><span class="sr-label">包装</span><div class="sr-opts"><div class="spec-opt sel">散装(斤)</div><div class="spec-opt">盒装 2 斤</div><div class="spec-opt">礼盒 5 斤</div></div></div>636  <div class="spec-row"><span class="sr-label">果径</span><div class="sr-opts"><div class="spec-opt sel">18mm+</div><div class="spec-opt">20mm+</div><div class="spec-opt">22mm+ 特级</div></div></div>637  <div class="spec-row"><span class="sr-label">数量</span><div class="sr-num"><i>-</i><b>2</b><i>+</i></div></div>638</div>639<div class="section-title">📋 关于这箱果</div>640<div class="card" style="margin-top:0;font-size:12px;color:#6b5842;line-height:2">641  产地溯源:云南宾川核心产区,每箱附采摘日期 + 溯源码,扫码可查<br/>642  甜度检测:到店逐箱测糖度,16 度以上方可上架,甜度不达标包退<br/>643  果径分级:18mm/20mm/22mm 三档分级,果径越大单价越高<br/>644  冷链锁鲜:顺丰冷运或自有前置仓,冰袋 + 保温箱锁鲜到家<br/>645  坏果赔付:签收 24h 内拍照理赔,坏果按斤秒赔无需退整箱646</div>647<div class="section-title">💬 果友评价(1200+)</div>648<div id="evalList"></div>649<div class="section-title">❤️ 猜你喜欢</div>650<div id="guessList" style="display:flex;gap:10px;overflow-x:auto;padding:0 12px;scrollbar-width:none"></div>651<div style="height:70px"></div>652<div class="buy-bar">653  <div class="bb-cart"><span class="ico">🛒<span class="num">5</span></span>购物车</div>654  <div class="bb-btn buy" data-toast="已加入购物车">加入购物车</div>655  <div class="bb-btn now" data-toast="订单提交成功">立即购买</div>656</div>657<script>658  var el = document.getElementById('evalList');659  var h = '';660  window.DATA.evals.forEach(function (x) {661    h += '<div class="eval-card"><div class="ev-head"><div class="ev-avatar">' + x.avatar + '</div>'662      + '<div>' + x.name + '</div><div class="ev-star">' + x.star + '</div>'663      + '</div><div class="ev-text">' + x.text + '</div></div>';664  });665  el.innerHTML = h;666  var gl = document.getElementById('guessList');667  var h2 = '';668  window.DATA.products.slice(1, 5).forEach(function (b) {669    h2 += '<div class="sk-item" style="width:110px"><div class="sk-img" style="height:80px">' + b.img + '</div>'670      + '<div class="sk-name">' + b.name + '</div><div class="sk-price">¥' + b.price + '</div></div>';671  });672  gl.innerHTML = h2;673</script>674"""675676CART = """677""" + header("购物车") + """678<div class="cart-item checked">679  <div class="ci-check on">✓</div>680  <div class="ci-img">🍇</div>681  <div class="ci-body">682    <div class="ci-name">云南阳光玫瑰青提 <span class="badge badge-org">产地直采</span></div>683    <div class="ci-spec">散装 · 18mm+ · 会员价</div>684    <div class="ci-foot"><div class="ci-price">¥15.9/斤</div><div class="ci-num"><i>-</i><b>2</b><i>+</i></div></div>685  </div>686</div>687<div class="cart-item checked">688  <div class="ci-check on">✓</div>689  <div class="ci-img">🍓</div>690  <div class="ci-body">691    <div class="ci-name">丹东 99 草莓 <span class="badge badge-new">新品</span></div>692    <div class="ci-spec">A 级果 · 500g 盒装 · 会员价</div>693    <div class="ci-foot"><div class="ci-price">¥29.9/盒</div><div class="ci-num"><i>-</i><b>1</b><i>+</i></div></div>694  </div>695</div>696<div class="cart-item">697  <div class="ci-check"></div>698  <div class="ci-img">🍉</div>699  <div class="ci-body">700    <div class="ci-name">宁夏硒砂瓜</div>701    <div class="ci-spec">沙瓤 · 5 斤起称 · 零售价</div>702    <div class="ci-foot"><div class="ci-price">¥2.9/斤</div><div class="ci-num"><i>-</i><b>5</b><i>+</i></div></div>703  </div>704</div>705<div class="coupon-card" style="margin-top:12px;background:linear-gradient(135deg,#c2410c,#ea580c);border-radius:14px;padding:14px;display:flex;align-items:center;gap:12px;color:#fff">706  <div style="flex:1"><b style="font-size:18px;display:block">满 88 减 20 券</b><span style="font-size:11px;opacity:.9">购物车金额 92 元 · 已自动可用</span></div>707  <div class="cc-btn" data-toast="已抵扣 20 元" style="background:#fff;color:#c2410c;padding:8px 16px;border-radius:16px;font-size:12px;font-weight:700">已用券</div>708</div>709<div class="check-box">710  <div class="cb-row"><span class="cb-label">自提点</span><span class="cb-val">城南水果总店 <span class="tag">1.2km</span></span></div>711  <div class="cb-row"><span class="cb-label">配送方式</span><span class="cb-val"><span class="opt sel">🚚 1h 极速达</span><span class="opt">🏪 到店自提</span><span class="opt">⏰ 预约配送</span></span></div>712  <div class="cb-row"><span class="cb-label">预约时间</span><span class="cb-val dim">今日 18:00 前达 ›</span></div>713  <div class="cb-row"><span class="cb-label">订单备注</span><span class="cb-val dim">果切帮忙切 / 冰袋加量 ›</span></div>714</div>715<div style="height:80px"></div>716<div class="settle-bar">717  <div class="sb-all"><span class="ci-check on">✓</span>全选</div>718  <div class="sb-total">合计 <b>¥72</b><br/>已抵扣 20 元</div>719  <div class="sb-btn" data-toast="已跳转结算">去结算</div>720</div>721"""722723ORDER = """724""" + header("确认订单") + """725<div class="pay-card">726  <div class="pc-row"><span class="pc-label">配送点</span><span class="pc-val">城南水果总店 · 城南农贸市场东门 12 号 ›</span></div>727  <div class="pc-row"><span class="pc-label">配送方式</span><span class="pc-val">🚚 1h 极速达(满 30 免配送费)</span></div>728  <div class="pc-row"><span class="pc-label">预约时间</span><span class="pc-val">今日 11:00 前送达</span></div>729  <div class="pc-row"><span class="pc-label">订单备注</span><span class="pc-val dim">果切帮忙切 / 冰袋加量 ›</span></div>730</div>731<div class="card" style="margin-top:-4px">732  <div style="display:flex;gap:10px;align-items:center;padding:6px 0"><div class="ci-img" style="width:48px;height:48px;border-radius:8px;background:var(--primary-light);display:flex;align-items:center;justify-content:center;font-size:22px">🍇</div><div style="flex:1;font-size:13px;font-weight:600">云南阳光玫瑰青提 ×2 斤(18mm+)</div><div style="font-size:12px;color:#b09a7e">¥31.8</div></div>733  <div style="display:flex;gap:10px;align-items:center;padding:6px 0"><div class="ci-img" style="width:48px;height:48px;border-radius:8px;background:var(--primary-light);display:flex;align-items:center;justify-content:center;font-size:22px">🍓</div><div style="flex:1;font-size:13px;font-weight:600">丹东 99 草莓 ×1 盒(A 级)</div><div style="font-size:12px;color:#b09a7e">¥29.9</div></div>734  <div style="display:flex;gap:10px;align-items:center;padding:6px 0"><div class="ci-img" style="width:48px;height:48px;border-radius:8px;background:var(--primary-light);display:flex;align-items:center;justify-content:center;font-size:22px">🍉</div><div style="flex:1;font-size:13px;font-weight:600">宁夏硒砂瓜 ×5 斤</div><div style="font-size:12px;color:#b09a7e">¥14.5</div></div>735</div>736<div class="pay-card" style="margin-top:-4px">737  <div class="pc-row"><span class="pc-label">会员等级</span><span class="pc-val">金卡会员 · 9 折已享</span></div>738  <div class="pc-row"><span class="pc-label">优惠券</span><span class="pc-val" style="color:#dc2626">¥20 满减券 ▾</span></div>739  <div class="pc-row"><span class="pc-label">实付金额</span><span class="pc-val"><b style="font-size:20px;color:var(--red)">¥60.2</b></span></div>740</div>741<div class="pay-way">742  <div class="pw-title">选择支付方式</div>743  <div class="pw-item sel"><span class="pw-ico">💳</span>水果卡余额(¥520)<div class="pw-radio">✓</div></div>744  <div class="pw-item"><span class="pw-ico">💚</span>微信支付<div class="pw-radio"></div></div>745  <div class="pw-item"><span class="pw-ico">💙</span>支付宝<div class="pw-radio"></div></div>746</div>747<div style="height:80px"></div>748<div class="settle-bar">749  <div class="sb-total" style="text-align:left">应付 <b>¥60.2</b></div>750  <div class="sb-btn" data-toast="下单成功,已转门店分拣备货">提交订单 ¥60.2</div>751</div>752"""753754ORDERS = """755""" + header("配送订单") + """756<div class="order-tabs">757  <a class="active">进行中</a><a>配送中</a><a>已完成</a>758</div>759<div class="track-bar">760  <div class="tb-ico">🚚</div>761  <div class="tb-body"><b>骑手 阿强 已出发</b><span>保温箱锁鲜 · 预计 11:30 送达城南水果总店</span></div>762  <div class="tb-btn" data-toast="已查看实时位置">查看轨迹</div>763</div>764<div class="order-card">765  <div class="oc-head"><span>城南总店 · 2026-08-30 10:12 <span class="tag">单号 GX202608301012</span></span><span class="st">配送中</span></div>766  <div class="oc-goods"><div class="og-img">🍇</div><div class="og-name">云南阳光玫瑰青提 ×2 斤<br/><span style="font-size:11px;color:#b09a7e">散装 · 18mm+ · 会员价</span></div><div class="og-price">¥31.8</div></div>767  <div class="oc-goods"><div class="og-img">🍓</div><div class="og-name">丹东 99 草莓 ×1 盒(A 级)</div><div class="og-price">¥29.9</div></div>768  <div class="oc-foot"><span>共 2 种 · 实付</span><b>¥51.7</b></div>769  <div class="call-bar">770    <i data-toast="已发起坏果赔付">🍂 坏果赔付</i>771    <i data-toast="已催单">📞 催单</i>772    <i class="main" data-toast="已通知骑手拍照签收">📷 签收拍照</i>773  </div>774</div>775<div class="section-title">📡 订单实时进度</div>776<div class="status-line" id="statusList"></div>777<div class="order-card" style="margin-top:12px">778  <div class="oc-head"><span>滨江自提柜 · 2026-08-29 09:05</span><span class="st" style="color:#16a34a">已签收</span></div>779  <div class="oc-goods"><div class="og-img">🍉</div><div class="og-name">宁夏硒砂瓜 ×1 个(约 12 斤)<br/><span style="font-size:11px;color:#b09a7e">沙瓤 · 5 斤起称</span></div><div class="og-price">¥34.8</div></div>780  <div class="oc-foot"><span>共 1 种 · 实付</span><b>¥34.8</b></div>781  <div class="oc-ops"><i class="main">去评价</i><i>再次购买</i></div>782</div>783<script>784  var sl = document.getElementById('statusList');785  var h = '';786  window.DATA.orderStatus.forEach(function (t) {787    var cls = t.now ? 'now' : (t.done ? 'done' : '');788    h += '<div class="sl-dot ' + cls + '"><div class="sl-c"></div><div>'789      + '<div class="sl-title">' + t.title + '</div><div class="sl-time">' + (t.time || '待处理') + '</div></div></div>';790  });791  sl.innerHTML = h;792</script>793"""794795MEMBER = """796""" + header("会员中心", back=False, right="⚙️") + """797<div class="vip-card">798  <div class="vc-level">👑 金卡 · 鲜果达人 · 尊享 9 折免运</div>799  <div class="vc-name">小草·金卡果友</div>800  <div class="vc-exp">距离钻石会员还差 182 成长值 · 预存越多权益越多</div>801  <div class="vc-bar"><i></i></div>802</div>803<div class="credit-box">804  <div class="cb-left"><b>水果卡余额 ¥520</b><span>充 500 送 50 · 全渠道通用</span></div>805  <div class="cb-btn" data-toast="已跳转充值">去充值</div>806</div>807<div class="assets">808  <div class="asset-item"><b>620</b><span>积分</span></div>809  <div class="asset-item"><b>3 张</b><span>优惠券</span></div>810  <div class="asset-item"><b>¥20</b><span>待赔付</span></div>811</div>812<div class="sign-btn">📅 每日签到 +10 积分</div>813<div class="section-title">🪪 会员等级与权益</div>814<div class="recharge-box">815  <div class="rb-title">等级越高价越低 · 折扣免运</div>816  <div id="creditList"></div>817</div>818<div class="section-title">🔁 定期配送计划</div>819<div class="plan-box">820  <div class="pb-title">到点自动生成订单,无需每天重复下单</div>821  <div id="planList"></div>822</div>823<div class="section-title">💎 水果卡预存有礼</div>824<div class="recharge-box">825  <div class="rb-title">预存多充多赠 · 全渠道通用</div>826  <div class="recharge-opts">827    <div class="recharge-opt sel"><b>¥500</b><span>送 50 元券</span></div>828    <div class="recharge-opt"><b>¥1000</b><span>送 120 元券</span></div>829    <div class="recharge-opt"><b>¥2000</b><span>送 300 元券</span></div>830  </div>831  <div class="btn btn-gold" style="margin-top:14px" data-toast="充值成功,券已到账">立即预存</div>832</div>833<div class="section-title">🚀 活动与邀请</div>834<div class="vip-grid">835  <div class="vip-item" data-toast="已发起附近果友拼单"><div class="vi-emoji">👥</div><div class="vi-name">邻近拼单</div><div class="vi-desc">合并需求降配送费</div></div>836  <div class="vip-item" data-toast="社区集采价已开启"><div class="vi-emoji">🏘️</div><div class="vi-name">社区集采</div><div class="vi-desc">集采享专属批发价</div></div>837  <div class="vip-item" data-toast="邀请好友各得 5 元券"><div class="vi-emoji">🤝</div><div class="vi-name">邀请有礼</div><div class="vi-desc">好友下单返 5%</div></div>838  <div class="vip-item" data-toast="中秋礼盒预订已开启"><div class="vi-emoji">🎁</div><div class="vi-name">节庆礼盒</div><div class="vi-desc">中秋/春节预订</div></div>839</div>840<script>841  var cl = document.getElementById('creditList');842  var h = '';843  window.DATA.creditLevels.forEach(function (c) {844    h += '<div class="tier-row"><span class="tr-label">' + c.level + '</span><span class="tr-price" style="flex:1;text-align:right">' + c.discount + ' · 预存 ' + c.credit + '<br/><span style="font-size:10px;color:#b09a7e;font-weight:400">' + c.note + '</span></span></div>';845  });846  cl.innerHTML = h;847  var pl = document.getElementById('planList');848  var h2 = '';849  window.DATA.regularPlans.forEach(function (p) {850    h2 += '<div class="plan-item' + (p.on ? '' : ' off') + '"><div class="pi-day">' + p.day + '</div><div class="pi-detail">' + p.detail + '</div><div class="pi-switch"><i></i></div></div>';851  });852  pl.innerHTML = h2;853</script>854"""855856MINE = """857<div class="user-card">858  <div class="uc-avatar">🧑‍🌾</div>859  <div>860    <div class="uc-name">小草·金卡果友</div>861    <div class="uc-level">👑 金卡会员 · 成长值 1820 · 累计省 ¥980</div>862  </div>863</div>864<div class="order-entry">865  <a data-toast="1 单配送中"><span class="oe-ico">🚚</span>配送中<span class="oe-num">1</span></a>866  <a data-toast="暂无待付款"><span class="oe-ico">💰</span>待付款</a>867  <a data-toast="1 单待签收"><span class="oe-ico">📦</span>待签收<span class="oe-num">1</span></a>868  <a data-toast="1 单待评价"><span class="oe-ico">⭐</span>待评价<span class="oe-num">1</span></a>869  <a data-toast="1 单坏果赔付中"><span class="oe-ico">↩️</span>赔付<span class="oe-num">1</span></a>870</div>871<div class="menu-list">872  <a href="orders.html"><span class="ml-l"><span class="ico">🧾</span>我的订单</span><span class="ml-r">›</span></a>873  <a href="member.html"><span class="ml-l"><span class="ico">👑</span>会员中心</span><span class="ml-r">›</span></a>874  <a data-toast="水果卡余额 ¥520"><span class="ml-l"><span class="ico">💳</span>水果卡余额</span><span class="ml-r">¥520</span></a>875  <a data-toast="积分 620"><span class="ml-l"><span class="ico">⭐</span>我的积分</span><span class="ml-r">620</span></a>876  <a data-toast="优惠券 3 张可用"><span class="ml-l"><span class="ico">🎟️</span>优惠券</span><span class="ml-r">3 张</span></a>877  <a data-toast="自提/配送点 2 个"><span class="ml-l"><span class="ico">📍</span>自提配送点</span><span class="ml-r">2 个</span></a>878  <a data-toast="收藏 8 款鲜果"><span class="ml-l"><span class="ico">❤️</span>我的收藏</span><span class="ml-r">8</span></a>879  <a data-toast="邀请好友各得 5 元券"><span class="ml-l"><span class="ico">🤝</span>邀请有礼</span><span class="ml-r">›</span></a>880  <a data-toast="客服在线 00:00-22:00"><span class="ml-l"><span class="ico">🎧</span>联系客服</span><span class="ml-r">400-666-2288</span></a>881</div>882"""883884README = """# 小草水果店(移动端 H5)885886社区水果生鲜一站式 H5 商城,主打产地直采、甜度检测溯源、1 小时极速达、坏果秒赔,功能对标叮咚买菜/百果园/果多美等头部社区生鲜 O2O,纯原生零依赖,移动端优先(390×844)。887888## 页面(8 页)889- index.html 首页:品牌 Banner、产地直采溯源条、搜索/拍照找果、六大分类导航(当季鲜果/进口水果/热带水果/时令瓜果/果切鲜榨/礼盒果篮)、快捷入口(当季鲜果/定期配送/水果卡/购物车/邀请有礼)、今日鲜果行情、限时秒杀、新客无门槛券、产地当季爆品、组合水果包、自提/配送点890- category.html 选购:六大分类切换、综合/销量/价格排序、鲜果卡(图/名/价/月供/产地/标签/加购)、底部购物车浮条891- detail.html 商品详情:一客一价三级定价(零售/批发/金卡会员价)、包装/果径规格、数量步进、产地溯源与甜度检测、果友评价、猜你喜欢、加入购物车/立即购买892- cart.html 购物车:多商品勾选、数量调整、满减券抵扣提示、自提点/配送方式/预约时间/备注、全选结算893- order.html 确认订单:配送信息确认、商品清单、会员折扣+满减券、实付金额、支付方式(水果卡余额/微信/支付宝)、提交订单894- orders.html 配送订单:进行中/配送中/已完成 Tab、实时配送轨迹、订单卡(单号/坏果赔付/催单/签收拍照)、实时进度时间线(已接单→已分拣→配送中→已送达)895- member.html 会员中心:会员等级卡(成长值)、水果卡余额、积分/券/待赔付资产、每日签到、会员等级权益、定期配送计划、水果卡预存多充多赠、拼单/集采/邀请有礼/节庆礼盒896- mine.html 个人中心:用户卡、订单快捷入口(配送中/待付款/待签收/待评价/赔付)、水果卡余额/积分/优惠券/自提点/收藏/邀请有礼/客服897898## 文件899- style.css 移动端优先样式(鲜橙+叶绿主题)900- app.js 零依赖交互逻辑(秒杀倒计时/分类筛选/排序/规格选择/数量步进/勾选/领券/签到/预存选择/定期计划开关/Toast)901- data.js 演示数据集中管理(商品/套餐/秒杀/行情/评价/优惠券/预存档位/自提配送点/会员等级/定期计划/订单状态)902"""903904def main():905    files = {906        "index.html": page("首页 · 小草水果店", "index", INDEX, tabbar("首页")),907        "category.html": page("鲜果选购 · 小草水果店", "category", CATEGORY, tabbar("选购")),908        "detail.html": page("商品详情 · 小草水果店", "detail", DETAIL, tabbar("选购")),909        "cart.html": page("购物车 · 小草水果店", "cart", CART, tabbar("购物车")),910        "order.html": page("确认订单 · 小草水果店", "order", ORDER, tabbar("购物车")),911        "orders.html": page("配送订单 · 小草水果店", "orders", ORDERS, tabbar("购物车")),912        "member.html": page("会员中心 · 小草水果店", "member", MEMBER, tabbar("会员")),913        "mine.html": page("个人中心 · 小草水果店", "mine", MINE, tabbar("我的")),914        "style.css": CSS,915        "data.js": DATA,916        "app.js": APP,917        "README.md": README,918    }919    for name, content in files.items():920        with open(os.path.join(OUT, name), "w", encoding="utf-8") as f:921            f.write(content)922        print("  +", name)923924if __name__ == "__main__":925    main()926