feat: 新增订单管理、评价管理、营销中心、会员中心模块
- 订单管理(4页): 订单大厅(看板)、全部订单、退款售后、订单设置 - 评价管理(1页): 评价列表+统计+回复抽屉 - 营销中心(5页): 优惠券、满减活动、限时折扣(含周期循环)、秒杀活动、新客有礼 - 会员中心(5页): 会员管理、储值卡、积分商城、客户画像、消息触达 - 侧边栏菜单重构: 营销中心拆分为营销中心+会员中心两个一级菜单
This commit is contained in:
58
index.html
58
index.html
@@ -623,16 +623,22 @@
|
||||
<i data-lucide="chevron-right" class="menu-arrow"></i>
|
||||
</div>
|
||||
<div class="menu-sub" id="menu-order">
|
||||
<div class="menu-item" data-tab="订单列表" onclick="switchTab(this, '订单列表')"><span class="menu-label">订单列表</span></div>
|
||||
<div class="menu-item" data-tab="退款管理" onclick="switchTab(this, '退款管理')"><span class="menu-label">退款管理</span></div>
|
||||
<div class="menu-item" data-tab="配送管理" onclick="switchTab(this, '配送管理')"><span class="menu-label">配送管理</span></div>
|
||||
<div class="menu-item" data-tab="自动接单规则" onclick="switchTab(this, '自动接单规则')"><span class="menu-label">自动接单规则</span></div>
|
||||
<div class="menu-item" data-tab="爆单预警" onclick="switchTab(this, '爆单预警')"><span class="menu-label">爆单预警</span></div>
|
||||
<div class="menu-item" data-tab="出餐时间预估" onclick="switchTab(this, '出餐时间预估')"><span class="menu-label">出餐时间预估</span></div>
|
||||
<div class="menu-item" data-tab="订单大厅" onclick="switchTab(this, '订单大厅')"><span class="menu-label">订单大厅</span></div>
|
||||
<div class="menu-item" data-tab="全部订单" onclick="switchTab(this, '全部订单')"><span class="menu-label">全部订单</span></div>
|
||||
<div class="menu-item" data-tab="退款售后" onclick="switchTab(this, '退款售后')"><span class="menu-label">退款售后</span></div>
|
||||
<div class="menu-item" data-tab="订单设置" onclick="switchTab(this, '订单设置')"><span class="menu-label">订单设置</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 5. 营销中心 -->
|
||||
<!-- 5. 评价管理 -->
|
||||
<div class="menu-parent" data-menu="review">
|
||||
<div class="menu-item" data-tab="评价管理" onclick="switchTab(this, '评价管理')">
|
||||
<i data-lucide="message-square-text" class="menu-icon"></i>
|
||||
<span class="menu-label">评价管理</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 6. 营销中心 -->
|
||||
<div class="menu-parent" data-menu="marketing">
|
||||
<div class="menu-item" onclick="toggleMenu('marketing')">
|
||||
<i data-lucide="megaphone" class="menu-icon"></i>
|
||||
@@ -642,16 +648,25 @@
|
||||
<div class="menu-sub" id="menu-marketing">
|
||||
<div class="menu-item" data-tab="优惠券" onclick="switchTab(this, '优惠券')"><span class="menu-label">优惠券</span></div>
|
||||
<div class="menu-item" data-tab="满减活动" onclick="switchTab(this, '满减活动')"><span class="menu-label">满减活动</span></div>
|
||||
<div class="menu-item" data-tab="限时折扣" onclick="switchTab(this, '限时折扣')"><span class="menu-label">限时折扣</span></div>
|
||||
<div class="menu-item" data-tab="秒杀活动" onclick="switchTab(this, '秒杀活动')"><span class="menu-label">秒杀活动</span></div>
|
||||
<div class="menu-item" data-tab="新客有礼" onclick="switchTab(this, '新客有礼')"><span class="menu-label">新客有礼</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 7. 会员中心 -->
|
||||
<div class="menu-parent" data-menu="member">
|
||||
<div class="menu-item" onclick="toggleMenu('member')">
|
||||
<i data-lucide="crown" class="menu-icon"></i>
|
||||
<span class="menu-label">会员中心</span>
|
||||
<i data-lucide="chevron-right" class="menu-arrow"></i>
|
||||
</div>
|
||||
<div class="menu-sub" id="menu-member">
|
||||
<div class="menu-item" data-tab="会员管理" onclick="switchTab(this, '会员管理')"><span class="menu-label">会员管理</span></div>
|
||||
<div class="menu-item" data-tab="客户标签" onclick="switchTab(this, '客户标签')"><span class="menu-label">客户标签</span></div>
|
||||
<div class="menu-item" data-tab="精准营销" onclick="switchTab(this, '精准营销')"><span class="menu-label">精准营销</span></div>
|
||||
<div class="menu-item" data-tab="消息触达" onclick="switchTab(this, '消息触达')"><span class="menu-label">消息触达</span></div>
|
||||
<div class="menu-item" data-tab="分享有礼" onclick="switchTab(this, '分享有礼')"><span class="menu-label">分享有礼</span></div>
|
||||
<div class="menu-item" data-tab="拼团活动" onclick="switchTab(this, '拼团活动')"><span class="menu-label">拼团活动</span></div>
|
||||
<div class="menu-item" data-tab="砍价活动" onclick="switchTab(this, '砍价活动')"><span class="menu-label">砍价活动</span></div>
|
||||
<div class="menu-item" data-tab="储值卡" onclick="switchTab(this, '储值卡')"><span class="menu-label">储值卡</span></div>
|
||||
<div class="menu-item" data-tab="积分商城" onclick="switchTab(this, '积分商城')"><span class="menu-label">积分商城</span></div>
|
||||
<div class="menu-item" data-tab="会员日" onclick="switchTab(this, '会员日')"><span class="menu-label">会员日</span></div>
|
||||
<div class="menu-item" data-tab="客户画像" onclick="switchTab(this, '客户画像')"><span class="menu-label">客户画像</span></div>
|
||||
<div class="menu-item" data-tab="消息触达" onclick="switchTab(this, '消息触达')"><span class="menu-label">消息触达</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1155,6 +1170,21 @@
|
||||
'时段供应': 'pages/product-schedule.html',
|
||||
'批量工具': 'pages/product-batch.html',
|
||||
'商品详情': 'pages/product-detail.html',
|
||||
'订单大厅': 'pages/order-board.html',
|
||||
'全部订单': 'pages/order-list.html',
|
||||
'退款售后': 'pages/order-refund.html',
|
||||
'订单设置': 'pages/order-settings.html',
|
||||
'评价管理': 'pages/reviews.html',
|
||||
'优惠券': 'pages/mkt-coupon.html',
|
||||
'满减活动': 'pages/mkt-reduction.html',
|
||||
'限时折扣': 'pages/mkt-flash-sale.html',
|
||||
'秒杀活动': 'pages/mkt-seckill.html',
|
||||
'新客有礼': 'pages/mkt-new-customer.html',
|
||||
'会员管理': 'pages/mbr-members.html',
|
||||
'储值卡': 'pages/mbr-prepaid.html',
|
||||
'积分商城': 'pages/mbr-points.html',
|
||||
'客户画像': 'pages/mbr-customers.html',
|
||||
'消息触达': 'pages/mbr-messaging.html',
|
||||
};
|
||||
|
||||
// Page cache
|
||||
|
||||
447
pages/mbr-customers.html
Normal file
447
pages/mbr-customers.html
Normal file
@@ -0,0 +1,447 @@
|
||||
<!-- 客户画像 — mbr-customers.html -->
|
||||
<style>
|
||||
/* ---- page-private: cu- prefix ---- */
|
||||
.cu-toolbar {
|
||||
background: #fff; border-radius: var(--g-radius); padding: 14px 20px;
|
||||
display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
|
||||
box-shadow: var(--g-shadow-sm); border: 1px solid var(--g-border);
|
||||
}
|
||||
.cu-toolbar .g-select,
|
||||
.cu-toolbar .g-input { height: 32px; font-size: 13px; }
|
||||
.cu-search-wrap {
|
||||
position: relative; width: 220px;
|
||||
}
|
||||
.cu-search-wrap .g-input { padding-left: 30px; width: 100%; }
|
||||
.cu-search-wrap i {
|
||||
position: absolute; left: 8px; top: 50%; transform: translateY(-50%);
|
||||
color: var(--g-text-muted); pointer-events: none;
|
||||
}
|
||||
.cu-toolbar-right { margin-left: auto; display: flex; gap: 8px; }
|
||||
|
||||
/* stats */
|
||||
.cu-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin-top: 14px; }
|
||||
.cu-stat-card {
|
||||
background: #fff; border-radius: var(--g-radius); border: 1px solid var(--g-border);
|
||||
padding: 18px 20px; box-shadow: var(--g-shadow-sm);
|
||||
transition: box-shadow var(--g-transition);
|
||||
}
|
||||
.cu-stat-card:hover { box-shadow: var(--g-shadow-md); }
|
||||
.cu-stat-title { font-size: 13px; color: var(--g-text-secondary); margin-bottom: 8px; font-weight: 500; display: flex; align-items: center; gap: 6px; }
|
||||
.cu-stat-title i { width: 16px; height: 16px; }
|
||||
.cu-stat-value { font-size: 28px; font-weight: 700; color: var(--g-text); line-height: 1.2; }
|
||||
.cu-stat-value.green { color: var(--g-success); }
|
||||
.cu-stat-value.orange { color: var(--g-warning); }
|
||||
.cu-stat-value.red { color: var(--g-danger); }
|
||||
.cu-stat-hint { font-size: 11px; color: var(--g-text-muted); margin-top: 6px; }
|
||||
|
||||
/* tag distribution */
|
||||
.cu-tag-dist {
|
||||
background: #fff; border-radius: var(--g-radius); border: 1px solid var(--g-border);
|
||||
padding: 16px 20px; margin-top: 14px; box-shadow: var(--g-shadow-sm);
|
||||
display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
|
||||
}
|
||||
.cu-tag-dist-label {
|
||||
font-size: 13px; font-weight: 600; color: var(--g-text); margin-right: 4px; white-space: nowrap;
|
||||
}
|
||||
.cu-tag-pill {
|
||||
display: inline-flex; align-items: center; gap: 5px; padding: 5px 14px;
|
||||
border-radius: 16px; font-size: 12px; cursor: pointer; user-select: none;
|
||||
transition: all var(--g-transition); border: 1px solid #e8e8e8; background: #fff;
|
||||
}
|
||||
.cu-tag-pill:hover { border-color: var(--primary); }
|
||||
.cu-tag-pill.active { background: color-mix(in srgb, var(--primary) 10%, transparent); border-color: var(--primary); color: var(--primary); font-weight: 500; }
|
||||
.cu-tag-pill .cu-tag-count {
|
||||
background: #f0f0f0; color: var(--g-text-secondary); font-size: 11px;
|
||||
padding: 1px 6px; border-radius: 8px; font-weight: 600;
|
||||
}
|
||||
.cu-tag-pill.active .cu-tag-count { background: color-mix(in srgb, var(--primary) 18%, transparent); color: var(--primary); }
|
||||
|
||||
/* table card */
|
||||
.cu-table-card {
|
||||
background: #fff; border-radius: var(--g-radius); border: 1px solid var(--g-border);
|
||||
margin-top: 14px; box-shadow: var(--g-shadow-sm); overflow: hidden;
|
||||
}
|
||||
.cu-table-card .g-table td { white-space: nowrap; }
|
||||
.cu-tags-cell { display: flex; gap: 4px; flex-wrap: wrap; }
|
||||
.cu-mini-tag {
|
||||
display: inline-block; padding: 1px 7px; border-radius: 3px; font-size: 11px; font-weight: 500;
|
||||
}
|
||||
.cu-mini-tag.green { background: #f6ffed; color: #52c41a; }
|
||||
.cu-mini-tag.blue { background: #e6f7ff; color: #1890ff; }
|
||||
.cu-mini-tag.orange { background: #fff7e6; color: #fa8c16; }
|
||||
.cu-mini-tag.red { background: #fff1f0; color: #f5222d; }
|
||||
.cu-mini-tag.purple { background: #f9f0ff; color: #722ed1; }
|
||||
.cu-mini-tag.gold { background: #fffbe6; color: #d48806; }
|
||||
.cu-row-dimmed td { opacity: 0.55; }
|
||||
.cu-row-dimmed:hover td { opacity: 0.75; }
|
||||
|
||||
/* drawer profile */
|
||||
.cu-profile-hd {
|
||||
display: flex; align-items: center; gap: 16px; margin-bottom: 20px;
|
||||
padding-bottom: 16px; border-bottom: 1px solid #f5f5f5;
|
||||
}
|
||||
.cu-avatar {
|
||||
width: 56px; height: 56px; border-radius: 50%; background: color-mix(in srgb, var(--primary) 12%, #fff);
|
||||
display: flex; align-items: center; justify-content: center; flex-shrink: 0;
|
||||
color: var(--primary);
|
||||
}
|
||||
.cu-profile-name { font-size: 18px; font-weight: 700; color: var(--g-text); }
|
||||
.cu-profile-phone { font-size: 13px; color: var(--g-text-muted); margin-top: 2px; }
|
||||
.cu-profile-meta { display: flex; gap: 8px; margin-top: 6px; align-items: center; flex-wrap: wrap; }
|
||||
|
||||
.cu-section-hd {
|
||||
font-size: 15px; font-weight: 600; color: var(--g-text);
|
||||
padding-left: 10px; border-left: 3px solid var(--primary); margin-bottom: 14px;
|
||||
}
|
||||
.cu-overview-grid {
|
||||
display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-bottom: 20px;
|
||||
}
|
||||
.cu-ov-item {
|
||||
background: var(--g-bg-subtle); border-radius: var(--g-radius-sm); padding: 12px 14px;
|
||||
}
|
||||
.cu-ov-label { font-size: 12px; color: var(--g-text-muted); margin-bottom: 4px; }
|
||||
.cu-ov-val { font-size: 16px; font-weight: 700; color: var(--g-text); }
|
||||
.cu-ov-val.primary { color: var(--primary); }
|
||||
|
||||
.cu-pref-section { margin-bottom: 20px; }
|
||||
.cu-pref-row { margin-bottom: 10px; }
|
||||
.cu-pref-label { font-size: 12px; color: var(--g-text-muted); margin-bottom: 6px; }
|
||||
.cu-pref-pills { display: flex; gap: 6px; flex-wrap: wrap; }
|
||||
.cu-pref-pill {
|
||||
display: inline-block; padding: 4px 12px; border-radius: 14px;
|
||||
font-size: 12px; background: #f5f5f5; color: var(--g-text-secondary);
|
||||
}
|
||||
|
||||
.cu-mini-table { width: 100%; border-collapse: collapse; font-size: 12px; margin-bottom: 4px; }
|
||||
.cu-mini-table th {
|
||||
text-align: left; padding: 8px 10px; font-size: 11px; font-weight: 500;
|
||||
color: var(--g-text-muted); background: var(--g-bg-subtle); border-bottom: 1px solid var(--g-border);
|
||||
}
|
||||
.cu-mini-table td {
|
||||
padding: 8px 10px; border-bottom: 1px solid #f5f5f5; color: var(--g-text);
|
||||
}
|
||||
</style>
|
||||
|
||||
<div>
|
||||
<!-- Toolbar -->
|
||||
<div class="cu-toolbar">
|
||||
<select class="g-select" style="width:180px;">
|
||||
<option>全部门店</option>
|
||||
<option>老三家外卖(朝阳店)</option>
|
||||
<option>老三家外卖(海淀店)</option>
|
||||
<option>老三家外卖(望京店)</option>
|
||||
</select>
|
||||
<select class="g-select" style="width:150px;" id="cuTagFilter" onchange="cuFilterTable()">
|
||||
<option value="">全部标签</option>
|
||||
<option value="高频客户">高频客户</option>
|
||||
<option value="新客">新客</option>
|
||||
<option value="沉睡客户">沉睡客户</option>
|
||||
<option value="流失客户">流失客户</option>
|
||||
<option value="午餐常客">午餐常客</option>
|
||||
<option value="大额消费">大额消费</option>
|
||||
</select>
|
||||
<div class="cu-search-wrap">
|
||||
<i data-lucide="search" style="width:14px;height:14px;"></i>
|
||||
<input class="g-input" placeholder="搜索姓名/手机号" id="cuSearchInput" oninput="cuFilterTable()">
|
||||
</div>
|
||||
<div class="cu-toolbar-right">
|
||||
<button class="g-btn"><i data-lucide="download" style="width:14px;height:14px;"></i> 导出</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Stats -->
|
||||
<div class="cu-stats">
|
||||
<div class="cu-stat-card">
|
||||
<div class="cu-stat-title"><i data-lucide="users" style="color:var(--primary)"></i> 总客户</div>
|
||||
<div class="cu-stat-value">2,156</div>
|
||||
<div class="cu-stat-hint">累计注册客户数</div>
|
||||
</div>
|
||||
<div class="cu-stat-card">
|
||||
<div class="cu-stat-title"><i data-lucide="flame" style="color:var(--g-success)"></i> 高频客户</div>
|
||||
<div class="cu-stat-value green">328</div>
|
||||
<div class="cu-stat-hint">月消费 ≥ 4次</div>
|
||||
</div>
|
||||
<div class="cu-stat-card">
|
||||
<div class="cu-stat-title"><i data-lucide="moon" style="color:var(--g-warning)"></i> 沉睡客户</div>
|
||||
<div class="cu-stat-value orange">456</div>
|
||||
<div class="cu-stat-hint">30天未消费</div>
|
||||
</div>
|
||||
<div class="cu-stat-card">
|
||||
<div class="cu-stat-title"><i data-lucide="user-x" style="color:var(--g-danger)"></i> 流失客户</div>
|
||||
<div class="cu-stat-value red">189</div>
|
||||
<div class="cu-stat-hint">60天未消费</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tag Distribution -->
|
||||
<div class="cu-tag-dist">
|
||||
<span class="cu-tag-dist-label">标签分布</span>
|
||||
<span class="cu-tag-pill" onclick="cuToggleTagPill(this, '高频客户')">高频客户 <span class="cu-tag-count">328</span></span>
|
||||
<span class="cu-tag-pill" onclick="cuToggleTagPill(this, '新客')">新客 <span class="cu-tag-count">86</span></span>
|
||||
<span class="cu-tag-pill" onclick="cuToggleTagPill(this, '午餐常客')">午餐常客 <span class="cu-tag-count">215</span></span>
|
||||
<span class="cu-tag-pill" onclick="cuToggleTagPill(this, '大额消费')">大额消费 <span class="cu-tag-count">142</span></span>
|
||||
<span class="cu-tag-pill" onclick="cuToggleTagPill(this, '沉睡客户')">沉睡客户 <span class="cu-tag-count">456</span></span>
|
||||
<span class="cu-tag-pill" onclick="cuToggleTagPill(this, '流失客户')">流失客户 <span class="cu-tag-count">189</span></span>
|
||||
</div>
|
||||
|
||||
<!-- Customer Table -->
|
||||
<div class="cu-table-card">
|
||||
<table class="g-table" id="cuTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>客户</th>
|
||||
<th>手机号</th>
|
||||
<th>标签</th>
|
||||
<th>累计消费</th>
|
||||
<th>消费次数</th>
|
||||
<th>平均客单价</th>
|
||||
<th>最近消费</th>
|
||||
<th>注册时间</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="cuTableBody"></tbody>
|
||||
</table>
|
||||
|
||||
<!-- Pagination -->
|
||||
<div class="g-pagination" style="padding: 12px 16px;">
|
||||
<span style="margin-right:auto;font-size:12px;color:var(--g-text-muted);">共 2,156 条</span>
|
||||
<button class="g-page-btn" disabled><</button>
|
||||
<button class="g-page-btn active">1</button>
|
||||
<button class="g-page-btn">2</button>
|
||||
<button class="g-page-btn">3</button>
|
||||
<button class="g-page-btn">...</button>
|
||||
<button class="g-page-btn">108</button>
|
||||
<button class="g-page-btn">></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Customer Profile Drawer -->
|
||||
<div class="g-drawer-mask" id="cuDrawerMask" onclick="closeCuDrawer()"></div>
|
||||
<div class="g-drawer" id="cuDrawer" style="width:600px;">
|
||||
<div class="g-drawer-hd">
|
||||
<span class="g-drawer-title" id="cuDrawerTitle">客户画像 - 张**</span>
|
||||
<button class="g-drawer-close" onclick="closeCuDrawer()"><i data-lucide="x" style="width:18px;height:18px;"></i></button>
|
||||
</div>
|
||||
<div class="g-drawer-bd">
|
||||
<!-- 基本信息 -->
|
||||
<div class="cu-profile-hd">
|
||||
<div class="cu-avatar"><i data-lucide="user" style="width:28px;height:28px;"></i></div>
|
||||
<div>
|
||||
<div class="cu-profile-name" id="cuProfileName">张**</div>
|
||||
<div class="cu-profile-phone" id="cuProfilePhone">138****6789</div>
|
||||
<div class="cu-profile-meta" id="cuProfileMeta">
|
||||
<span class="g-tag g-tag-blue">黄金会员</span>
|
||||
<span style="font-size:12px;color:var(--g-text-muted);">注册于 2024-03-15</span>
|
||||
</div>
|
||||
<div class="cu-profile-meta" id="cuProfileTags" style="margin-top:4px;">
|
||||
<span class="cu-mini-tag green">高频客户</span>
|
||||
<span class="cu-mini-tag purple">午餐常客</span>
|
||||
<span class="cu-mini-tag gold">大额消费</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 消费概览 -->
|
||||
<div class="cu-section-hd">消费概览</div>
|
||||
<div class="cu-overview-grid">
|
||||
<div class="cu-ov-item">
|
||||
<div class="cu-ov-label">累计消费</div>
|
||||
<div class="cu-ov-val primary">¥3,680</div>
|
||||
</div>
|
||||
<div class="cu-ov-item">
|
||||
<div class="cu-ov-label">消费次数</div>
|
||||
<div class="cu-ov-val">42次</div>
|
||||
</div>
|
||||
<div class="cu-ov-item">
|
||||
<div class="cu-ov-label">平均客单价</div>
|
||||
<div class="cu-ov-val">¥87.6</div>
|
||||
</div>
|
||||
<div class="cu-ov-item">
|
||||
<div class="cu-ov-label">最近消费</div>
|
||||
<div class="cu-ov-val">2025-02-10</div>
|
||||
</div>
|
||||
<div class="cu-ov-item">
|
||||
<div class="cu-ov-label">常用渠道</div>
|
||||
<div class="cu-ov-val" style="font-size:13px;">外卖(68%) 自提(32%)</div>
|
||||
</div>
|
||||
<div class="cu-ov-item">
|
||||
<div class="cu-ov-label">储值余额</div>
|
||||
<div class="cu-ov-val primary">¥260</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 消费偏好 -->
|
||||
<div class="cu-section-hd">消费偏好</div>
|
||||
<div class="cu-pref-section">
|
||||
<div class="cu-pref-row">
|
||||
<div class="cu-pref-label">常点商品</div>
|
||||
<div class="cu-pref-pills">
|
||||
<span class="cu-pref-pill">宫保鸡丁 (12次)</span>
|
||||
<span class="cu-pref-pill">鱼香肉丝 (8次)</span>
|
||||
<span class="cu-pref-pill">米饭 (42次)</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cu-pref-row">
|
||||
<div class="cu-pref-label">口味偏好</div>
|
||||
<div class="cu-pref-pills">
|
||||
<span class="cu-pref-pill">偏辣</span>
|
||||
<span class="cu-pref-pill">少盐</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cu-pref-row">
|
||||
<div class="cu-pref-label">下单时段</div>
|
||||
<div class="cu-pref-pills">
|
||||
<span class="cu-pref-pill">午餐 (78%)</span>
|
||||
<span class="cu-pref-pill">晚餐 (22%)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 最近订单 -->
|
||||
<div class="cu-section-hd">最近订单</div>
|
||||
<table class="cu-mini-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>日期</th>
|
||||
<th>商品摘要</th>
|
||||
<th>金额</th>
|
||||
<th>渠道</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>2025-02-10</td>
|
||||
<td>宫保鸡丁+米饭+可乐</td>
|
||||
<td>¥52.00</td>
|
||||
<td><span class="g-tag g-tag-blue">外卖</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2025-02-07</td>
|
||||
<td>鱼香肉丝盖饭+蛋花汤</td>
|
||||
<td>¥38.00</td>
|
||||
<td><span class="g-tag g-tag-green">自提</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2025-02-03</td>
|
||||
<td>招牌红烧肉饭+凉菜拼盘</td>
|
||||
<td>¥65.00</td>
|
||||
<td><span class="g-tag g-tag-blue">外卖</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2025-01-28</td>
|
||||
<td>番茄牛腩面+珍珠奶茶</td>
|
||||
<td>¥42.00</td>
|
||||
<td><span class="g-tag g-tag-blue">外卖</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2025-01-22</td>
|
||||
<td>宫保鸡丁+麻婆豆腐+米饭x2</td>
|
||||
<td>¥88.00</td>
|
||||
<td><span class="g-tag g-tag-green">自提</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="g-drawer-ft">
|
||||
<button class="g-btn" onclick="closeCuDrawer()">关闭</button>
|
||||
<button class="g-btn g-btn-primary"><i data-lucide="send" style="width:14px;height:14px;"></i> 发送消息</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Customer data
|
||||
var cuCustomers = [
|
||||
{ name:'张**', phone:'138****6789', tags:['高频客户','午餐常客','大额消费'], total:3680, count:42, avg:87.6, last:'2025-02-10', reg:'2024-03-15', churned:false },
|
||||
{ name:'李**', phone:'139****2345', tags:['高频客户','大额消费'], total:5120, count:58, avg:88.3, last:'2025-02-11', reg:'2023-11-20', churned:false },
|
||||
{ name:'王**', phone:'136****8901', tags:['新客'], total:156, count:2, avg:78.0, last:'2025-02-09', reg:'2025-02-01', churned:false },
|
||||
{ name:'赵**', phone:'158****4567', tags:['午餐常客'], total:1890, count:28, avg:67.5, last:'2025-02-08', reg:'2024-06-10', churned:false },
|
||||
{ name:'陈**', phone:'137****3210', tags:['沉睡客户'], total:960, count:12, avg:80.0, last:'2025-01-05', reg:'2024-04-22', churned:false },
|
||||
{ name:'刘**', phone:'155****7654', tags:['流失客户'], total:420, count:5, avg:84.0, last:'2024-11-18', reg:'2024-08-03', churned:true },
|
||||
{ name:'周**', phone:'186****9012', tags:['高频客户','午餐常客'], total:2760, count:35, avg:78.9, last:'2025-02-11', reg:'2024-01-08', churned:false },
|
||||
{ name:'吴**', phone:'133****5678', tags:['流失客户','大额消费'], total:1540, count:11, avg:140.0, last:'2024-12-02', reg:'2024-05-15', churned:true },
|
||||
];
|
||||
|
||||
var cuTagColorMap = {
|
||||
'高频客户': 'green',
|
||||
'新客': 'blue',
|
||||
'沉睡客户': 'orange',
|
||||
'流失客户': 'red',
|
||||
'午餐常客': 'purple',
|
||||
'大额消费': 'gold'
|
||||
};
|
||||
|
||||
var cuActiveTagFilter = '';
|
||||
|
||||
function cuRenderTable() {
|
||||
var kw = (document.getElementById('cuSearchInput').value || '').trim().toLowerCase();
|
||||
var tagSel = document.getElementById('cuTagFilter').value;
|
||||
var filterTag = cuActiveTagFilter || tagSel;
|
||||
var tbody = document.getElementById('cuTableBody');
|
||||
var html = '';
|
||||
cuCustomers.forEach(function(c) {
|
||||
if (kw && c.name.toLowerCase().indexOf(kw) === -1 && c.phone.indexOf(kw) === -1) return;
|
||||
if (filterTag && c.tags.indexOf(filterTag) === -1) return;
|
||||
var tagsHtml = c.tags.map(function(t) {
|
||||
return '<span class="cu-mini-tag ' + (cuTagColorMap[t] || 'gray') + '">' + t + '</span>';
|
||||
}).join('');
|
||||
var rowClass = c.churned ? ' class="cu-row-dimmed"' : '';
|
||||
html += '<tr' + rowClass + '>'
|
||||
+ '<td style="font-weight:500;">' + c.name + '</td>'
|
||||
+ '<td>' + c.phone + '</td>'
|
||||
+ '<td><div class="cu-tags-cell">' + tagsHtml + '</div></td>'
|
||||
+ '<td>¥' + c.total.toLocaleString() + '</td>'
|
||||
+ '<td>' + c.count + '次</td>'
|
||||
+ '<td>¥' + c.avg.toFixed(1) + '</td>'
|
||||
+ '<td>' + c.last + '</td>'
|
||||
+ '<td>' + c.reg + '</td>'
|
||||
+ '<td><a class="g-action" onclick="openCuDrawer(\'' + c.name + '\')">画像</a></td>'
|
||||
+ '</tr>';
|
||||
});
|
||||
if (!html) {
|
||||
html = '<tr><td colspan="9" style="text-align:center;padding:40px;color:var(--g-text-muted);">暂无匹配客户</td></tr>';
|
||||
}
|
||||
tbody.innerHTML = html;
|
||||
}
|
||||
|
||||
function cuFilterTable() {
|
||||
cuActiveTagFilter = '';
|
||||
document.querySelectorAll('.cu-tag-pill').forEach(function(p) { p.classList.remove('active'); });
|
||||
cuRenderTable();
|
||||
}
|
||||
|
||||
function cuToggleTagPill(el, tag) {
|
||||
var wasActive = el.classList.contains('active');
|
||||
document.querySelectorAll('.cu-tag-pill').forEach(function(p) { p.classList.remove('active'); });
|
||||
if (wasActive) {
|
||||
cuActiveTagFilter = '';
|
||||
} else {
|
||||
el.classList.add('active');
|
||||
cuActiveTagFilter = tag;
|
||||
}
|
||||
document.getElementById('cuTagFilter').value = '';
|
||||
cuRenderTable();
|
||||
}
|
||||
|
||||
function openCuDrawer(name) {
|
||||
var c = cuCustomers.find(function(x) { return x.name === name; });
|
||||
if (c) {
|
||||
document.getElementById('cuDrawerTitle').textContent = '客户画像 - ' + c.name;
|
||||
document.getElementById('cuProfileName').textContent = c.name;
|
||||
document.getElementById('cuProfilePhone').textContent = c.phone;
|
||||
}
|
||||
document.getElementById('cuDrawerMask').classList.add('open');
|
||||
document.getElementById('cuDrawer').classList.add('open');
|
||||
if (typeof lucide !== 'undefined') lucide.createIcons();
|
||||
}
|
||||
|
||||
function closeCuDrawer() {
|
||||
document.getElementById('cuDrawerMask').classList.remove('open');
|
||||
document.getElementById('cuDrawer').classList.remove('open');
|
||||
}
|
||||
|
||||
// Init
|
||||
cuRenderTable();
|
||||
if (typeof lucide !== 'undefined') lucide.createIcons();
|
||||
</script>
|
||||
402
pages/mbr-members.html
Normal file
402
pages/mbr-members.html
Normal file
@@ -0,0 +1,402 @@
|
||||
<!-- 会员管理页 -->
|
||||
<style>
|
||||
.mm-toolbar { display:flex; align-items:center; gap:12px; margin-bottom:16px; box-shadow:var(--g-shadow-sm); border-radius:10px; padding:12px 16px; background:#fff; flex-wrap:wrap; }
|
||||
.mm-toolbar .mm-right { margin-left:auto; display:flex; gap:8px; }
|
||||
.mm-stats { display:grid; grid-template-columns:repeat(4,1fr); gap:12px; margin-bottom:16px; }
|
||||
.mm-stat-card { background:#fff; border-radius:10px; padding:16px 20px; box-shadow:var(--g-shadow-sm); transition:all var(--g-transition); }
|
||||
.mm-stat-card:hover { box-shadow:var(--g-shadow-md); transform:translateY(-1px); }
|
||||
.mm-stat-label { font-size:13px; color:var(--g-text-muted); margin-bottom:6px; }
|
||||
.mm-stat-value { font-size:24px; font-weight:700; color:var(--g-text); }
|
||||
.mm-stat-value.blue { color:var(--primary); }
|
||||
.mm-stat-value.green { color:var(--g-success); }
|
||||
.mm-stat-value.orange { color:var(--g-warning); }
|
||||
.mm-stat-sub { font-size:11px; color:var(--g-text-muted); margin-top:4px; }
|
||||
.mm-table-wrap { background:#fff; border-radius:10px; box-shadow:var(--g-shadow-sm); overflow:hidden; }
|
||||
.mm-member-cell { display:flex; align-items:center; gap:10px; }
|
||||
.mm-avatar { width:34px; height:34px; border-radius:50%; display:flex; align-items:center; justify-content:center; color:#fff; font-size:13px; font-weight:600; flex-shrink:0; }
|
||||
|
||||
/* 等级体系 Tab */
|
||||
.mm-level-grid { display:grid; grid-template-columns:repeat(4,1fr); gap:16px; margin-bottom:24px; }
|
||||
.mm-level-card { background:#fff; border-radius:10px; padding:24px 20px; box-shadow:var(--g-shadow-sm); border:1px solid var(--g-border); transition:all var(--g-transition); display:flex; flex-direction:column; align-items:center; text-align:center; }
|
||||
.mm-level-card:hover { box-shadow:var(--g-shadow-md); transform:translateY(-1px); }
|
||||
.mm-level-icon { width:56px; height:56px; border-radius:50%; display:flex; align-items:center; justify-content:center; margin-bottom:12px; }
|
||||
.mm-level-name { font-size:16px; font-weight:600; color:var(--g-text); margin-bottom:4px; }
|
||||
.mm-level-cond { font-size:12px; color:var(--g-text-muted); margin-bottom:14px; padding:3px 10px; background:var(--g-bg-subtle); border-radius:10px; }
|
||||
.mm-level-perks { width:100%; text-align:left; margin-bottom:16px; }
|
||||
.mm-level-perk { display:flex; align-items:center; gap:6px; font-size:13px; color:var(--g-text-secondary); padding:5px 0; }
|
||||
.mm-level-perk i { color:var(--g-success); flex-shrink:0; }
|
||||
|
||||
.mm-section-hd { font-size:15px; font-weight:600; color:var(--g-text); padding-left:10px; border-left:3px solid var(--primary); margin-bottom:16px; }
|
||||
.mm-day-card { background:#fff; border-radius:10px; padding:20px 24px; box-shadow:var(--g-shadow-sm); border:1px solid var(--g-border); }
|
||||
.mm-day-row { display:flex; align-items:center; gap:16px; margin-bottom:14px; }
|
||||
.mm-day-row:last-child { margin-bottom:0; }
|
||||
.mm-day-label { width:80px; font-size:13px; color:var(--g-text-secondary); flex-shrink:0; }
|
||||
|
||||
/* 抽屉内 */
|
||||
.mm-drawer-header { display:flex; align-items:center; gap:14px; margin-bottom:20px; padding-bottom:16px; border-bottom:1px solid #f5f5f5; }
|
||||
.mm-drawer-avatar { width:48px; height:48px; border-radius:50%; display:flex; align-items:center; justify-content:center; color:#fff; font-size:18px; font-weight:600; flex-shrink:0; background:var(--primary); }
|
||||
.mm-drawer-name { font-size:16px; font-weight:600; color:var(--g-text); }
|
||||
.mm-drawer-meta { font-size:12px; color:var(--g-text-muted); margin-top:3px; }
|
||||
.mm-overview { display:grid; grid-template-columns:repeat(5,1fr); gap:12px; margin-bottom:20px; }
|
||||
.mm-ov-item { text-align:center; padding:12px 8px; background:var(--g-bg-subtle); border-radius:8px; }
|
||||
.mm-ov-val { font-size:18px; font-weight:700; color:var(--g-text); }
|
||||
.mm-ov-label { font-size:11px; color:var(--g-text-muted); margin-top:4px; }
|
||||
.mm-mini-table { width:100%; border-collapse:collapse; font-size:12px; margin-top:10px; }
|
||||
.mm-mini-table th { text-align:left; padding:8px 10px; background:var(--g-bg-subtle); color:var(--g-text-muted); font-weight:500; font-size:11px; }
|
||||
.mm-mini-table td { padding:8px 10px; border-bottom:1px solid #f5f5f5; color:var(--g-text); }
|
||||
.mm-tag-list { display:flex; gap:6px; flex-wrap:wrap; margin-top:10px; }
|
||||
</style>
|
||||
|
||||
<div>
|
||||
<!-- 分段切换 -->
|
||||
<div class="g-seg" style="width:240px;margin-bottom:16px;">
|
||||
<div class="g-seg-item active" onclick="switchMmTab(this,'list')">会员列表</div>
|
||||
<div class="g-seg-item" onclick="switchMmTab(this,'levels')">等级体系</div>
|
||||
</div>
|
||||
|
||||
<!-- ==================== TAB 1: 会员列表 ==================== -->
|
||||
<div id="mmTabList">
|
||||
<!-- 工具栏 -->
|
||||
<div class="mm-toolbar">
|
||||
<select class="g-select" style="width:180px;">
|
||||
<option>全部门店</option>
|
||||
<option>老三家外卖(朝阳店)</option>
|
||||
<option>老三家外卖(海淀店)</option>
|
||||
<option>老三家外卖(望京店)</option>
|
||||
</select>
|
||||
<select class="g-select" style="width:140px;" id="mmLevelFilter">
|
||||
<option value="">全部等级</option>
|
||||
<option>普通会员</option>
|
||||
<option>银卡</option>
|
||||
<option>金卡</option>
|
||||
<option>钻石</option>
|
||||
</select>
|
||||
<div style="position:relative;">
|
||||
<i data-lucide="search" style="position:absolute;left:10px;top:50%;transform:translateY(-50%);width:14px;height:14px;color:var(--g-text-muted);pointer-events:none;"></i>
|
||||
<input class="g-input" style="width:200px;padding-left:32px;" placeholder="搜索姓名/手机号">
|
||||
</div>
|
||||
<div class="mm-right">
|
||||
<button class="g-btn"><i data-lucide="download" style="width:14px;height:14px;"></i>导出</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 统计卡片 -->
|
||||
<div class="mm-stats">
|
||||
<div class="mm-stat-card">
|
||||
<div class="mm-stat-label">会员总数</div>
|
||||
<div class="mm-stat-value blue">1,286</div>
|
||||
</div>
|
||||
<div class="mm-stat-card">
|
||||
<div class="mm-stat-label">本月新增</div>
|
||||
<div class="mm-stat-value green">86</div>
|
||||
</div>
|
||||
<div class="mm-stat-card">
|
||||
<div class="mm-stat-label">活跃会员</div>
|
||||
<div class="mm-stat-value">658</div>
|
||||
<div class="mm-stat-sub">30天内有消费</div>
|
||||
</div>
|
||||
<div class="mm-stat-card">
|
||||
<div class="mm-stat-label">沉睡会员</div>
|
||||
<div class="mm-stat-value orange">328</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 表格 -->
|
||||
<div class="mm-table-wrap">
|
||||
<table class="g-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>会员</th>
|
||||
<th>手机号</th>
|
||||
<th>等级</th>
|
||||
<th>累计消费</th>
|
||||
<th>消费次数</th>
|
||||
<th>最近消费</th>
|
||||
<th>储值余额</th>
|
||||
<th>积分</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><div class="mm-member-cell"><div class="mm-avatar" style="background:#1890ff;">张</div><span>张**</span></div></td>
|
||||
<td>138****6721</td>
|
||||
<td><span class="g-tag" style="color:#722ed1;background:#f9f0ff;border:1px solid #d3adf7;">钻石</span></td>
|
||||
<td>¥15,280</td>
|
||||
<td>186</td>
|
||||
<td>2026-02-11</td>
|
||||
<td>¥2,350.00</td>
|
||||
<td>8,620</td>
|
||||
<td><a class="g-action" onclick="openMmDrawer(0)">详情</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div class="mm-member-cell"><div class="mm-avatar" style="background:#fa8c16;">李</div><span>李**</span></div></td>
|
||||
<td>139****3345</td>
|
||||
<td><span class="g-tag g-tag-orange">金卡</span></td>
|
||||
<td>¥4,560</td>
|
||||
<td>72</td>
|
||||
<td>2026-02-10</td>
|
||||
<td>¥800.00</td>
|
||||
<td>3,240</td>
|
||||
<td><a class="g-action" onclick="openMmDrawer(1)">详情</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div class="mm-member-cell"><div class="mm-avatar" style="background:#52c41a;">王</div><span>王**</span></div></td>
|
||||
<td>136****8890</td>
|
||||
<td><span class="g-tag g-tag-blue">银卡</span></td>
|
||||
<td>¥1,230</td>
|
||||
<td>28</td>
|
||||
<td>2026-02-08</td>
|
||||
<td>¥200.00</td>
|
||||
<td>1,560</td>
|
||||
<td><a class="g-action" onclick="openMmDrawer(2)">详情</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div class="mm-member-cell"><div class="mm-avatar" style="background:#722ed1;">赵</div><span>赵**</span></div></td>
|
||||
<td>158****2210</td>
|
||||
<td><span class="g-tag g-tag-gray">普通</span></td>
|
||||
<td>¥320</td>
|
||||
<td>8</td>
|
||||
<td>2026-01-25</td>
|
||||
<td>¥0.00</td>
|
||||
<td>420</td>
|
||||
<td><a class="g-action" onclick="openMmDrawer(3)">详情</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div class="mm-member-cell"><div class="mm-avatar" style="background:#eb2f96;">陈</div><span>陈**</span></div></td>
|
||||
<td>137****5567</td>
|
||||
<td><span class="g-tag g-tag-orange">金卡</span></td>
|
||||
<td>¥3,890</td>
|
||||
<td>56</td>
|
||||
<td>2026-02-09</td>
|
||||
<td>¥1,200.00</td>
|
||||
<td>2,780</td>
|
||||
<td><a class="g-action" onclick="openMmDrawer(4)">详情</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div class="mm-member-cell"><div class="mm-avatar" style="background:#13c2c2;">刘</div><span>刘**</span></div></td>
|
||||
<td>155****9901</td>
|
||||
<td><span class="g-tag g-tag-blue">银卡</span></td>
|
||||
<td>¥980</td>
|
||||
<td>18</td>
|
||||
<td>2026-02-05</td>
|
||||
<td>¥150.00</td>
|
||||
<td>890</td>
|
||||
<td><a class="g-action" onclick="openMmDrawer(5)">详情</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div class="mm-member-cell"><div class="mm-avatar" style="background:#f5222d;">孙</div><span>孙**</span></div></td>
|
||||
<td>186****4432</td>
|
||||
<td><span class="g-tag" style="color:#722ed1;background:#f9f0ff;border:1px solid #d3adf7;">钻石</span></td>
|
||||
<td>¥12,600</td>
|
||||
<td>142</td>
|
||||
<td>2026-02-12</td>
|
||||
<td>¥3,800.00</td>
|
||||
<td>7,150</td>
|
||||
<td><a class="g-action" onclick="openMmDrawer(6)">详情</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><div class="mm-member-cell"><div class="mm-avatar" style="background:#2f54eb;">周</div><span>周**</span></div></td>
|
||||
<td>133****7788</td>
|
||||
<td><span class="g-tag g-tag-gray">普通</span></td>
|
||||
<td>¥160</td>
|
||||
<td>4</td>
|
||||
<td>2026-01-18</td>
|
||||
<td>¥0.00</td>
|
||||
<td>210</td>
|
||||
<td><a class="g-action" onclick="openMmDrawer(7)">详情</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="g-pagination">
|
||||
<span style="margin-right:8px;">共 1,286 条</span>
|
||||
<button class="g-page-btn" disabled><</button>
|
||||
<button class="g-page-btn active">1</button>
|
||||
<button class="g-page-btn">2</button>
|
||||
<button class="g-page-btn">3</button>
|
||||
<button class="g-page-btn">...</button>
|
||||
<button class="g-page-btn">129</button>
|
||||
<button class="g-page-btn">></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ==================== TAB 2: 等级体系 ==================== -->
|
||||
<div id="mmTabLevels" style="display:none;">
|
||||
<div class="mm-section-hd">会员等级</div>
|
||||
<div class="mm-level-grid">
|
||||
<!-- 普通 -->
|
||||
<div class="mm-level-card">
|
||||
<div class="mm-level-icon" style="background:#f5f5f5;color:#999;">
|
||||
<i data-lucide="user" style="width:28px;height:28px;"></i>
|
||||
</div>
|
||||
<div class="mm-level-name">普通会员</div>
|
||||
<div class="mm-level-cond">注册即享</div>
|
||||
<div class="mm-level-perks">
|
||||
<div class="mm-level-perk"><i data-lucide="check" style="width:14px;height:14px;"></i>积分累计</div>
|
||||
<div class="mm-level-perk"><i data-lucide="check" style="width:14px;height:14px;"></i>会员价商品</div>
|
||||
</div>
|
||||
<button class="g-btn g-btn-sm" style="width:100%;">编辑</button>
|
||||
</div>
|
||||
<!-- 银卡 -->
|
||||
<div class="mm-level-card">
|
||||
<div class="mm-level-icon" style="background:#e6f7ff;color:#1890ff;">
|
||||
<i data-lucide="award" style="width:28px;height:28px;"></i>
|
||||
</div>
|
||||
<div class="mm-level-name" style="color:#1890ff;">银卡会员</div>
|
||||
<div class="mm-level-cond">累计消费满 ¥500</div>
|
||||
<div class="mm-level-perks">
|
||||
<div class="mm-level-perk"><i data-lucide="check" style="width:14px;height:14px;"></i>全场9.8折</div>
|
||||
<div class="mm-level-perk"><i data-lucide="check" style="width:14px;height:14px;"></i>生日专属券</div>
|
||||
<div class="mm-level-perk"><i data-lucide="check" style="width:14px;height:14px;"></i>积分1.2倍</div>
|
||||
</div>
|
||||
<button class="g-btn g-btn-sm" style="width:100%;">编辑</button>
|
||||
</div>
|
||||
<!-- 金卡 -->
|
||||
<div class="mm-level-card">
|
||||
<div class="mm-level-icon" style="background:#fff7e6;color:#fa8c16;">
|
||||
<i data-lucide="trophy" style="width:28px;height:28px;"></i>
|
||||
</div>
|
||||
<div class="mm-level-name" style="color:#fa8c16;">金卡会员</div>
|
||||
<div class="mm-level-cond">累计消费满 ¥2,000</div>
|
||||
<div class="mm-level-perks">
|
||||
<div class="mm-level-perk"><i data-lucide="check" style="width:14px;height:14px;"></i>全场9.5折</div>
|
||||
<div class="mm-level-perk"><i data-lucide="check" style="width:14px;height:14px;"></i>生日双倍积分</div>
|
||||
<div class="mm-level-perk"><i data-lucide="check" style="width:14px;height:14px;"></i>每月专属优惠券</div>
|
||||
<div class="mm-level-perk"><i data-lucide="check" style="width:14px;height:14px;"></i>积分1.5倍</div>
|
||||
</div>
|
||||
<button class="g-btn g-btn-sm" style="width:100%;">编辑</button>
|
||||
</div>
|
||||
<!-- 钻石 -->
|
||||
<div class="mm-level-card">
|
||||
<div class="mm-level-icon" style="background:#f9f0ff;color:#722ed1;">
|
||||
<i data-lucide="gem" style="width:28px;height:28px;"></i>
|
||||
</div>
|
||||
<div class="mm-level-name" style="color:#722ed1;">钻石会员</div>
|
||||
<div class="mm-level-cond">累计消费满 ¥5,000</div>
|
||||
<div class="mm-level-perks">
|
||||
<div class="mm-level-perk"><i data-lucide="check" style="width:14px;height:14px;"></i>全场9折</div>
|
||||
<div class="mm-level-perk"><i data-lucide="check" style="width:14px;height:14px;"></i>生日礼品</div>
|
||||
<div class="mm-level-perk"><i data-lucide="check" style="width:14px;height:14px;"></i>专属客服</div>
|
||||
<div class="mm-level-perk"><i data-lucide="check" style="width:14px;height:14px;"></i>优先配送</div>
|
||||
<div class="mm-level-perk"><i data-lucide="check" style="width:14px;height:14px;"></i>积分2倍</div>
|
||||
</div>
|
||||
<button class="g-btn g-btn-sm" style="width:100%;">编辑</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 会员日设置 -->
|
||||
<div class="mm-section-hd">会员日设置</div>
|
||||
<div class="mm-day-card">
|
||||
<div class="mm-day-row">
|
||||
<div class="mm-day-label">启用会员日</div>
|
||||
<div class="g-toggle on" onclick="this.classList.toggle('on')"></div>
|
||||
</div>
|
||||
<div class="mm-day-row">
|
||||
<div class="mm-day-label">会员日</div>
|
||||
<select class="g-select" style="width:160px;">
|
||||
<option>每周二</option>
|
||||
<option>每周一</option>
|
||||
<option>每周三</option>
|
||||
<option>每周四</option>
|
||||
<option>每周五</option>
|
||||
<option>每周六</option>
|
||||
<option>每周日</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mm-day-row">
|
||||
<div class="mm-day-label">会员日权益</div>
|
||||
<div style="display:flex;align-items:center;gap:8px;">
|
||||
<span style="font-size:13px;color:var(--g-text-secondary);">额外</span>
|
||||
<input class="g-input" style="width:80px;text-align:center;" placeholder="如:9" value="9">
|
||||
<span style="font-size:13px;color:var(--g-text-secondary);">折优惠</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 会员详情抽屉 -->
|
||||
<div class="g-drawer-mask" id="mmDrawerMask" onclick="closeMmDrawer()"></div>
|
||||
<div class="g-drawer" id="mmDrawer" style="width:560px;">
|
||||
<div class="g-drawer-hd">
|
||||
<div class="g-drawer-title">会员详情</div>
|
||||
<button class="g-drawer-close" onclick="closeMmDrawer()"><i data-lucide="x" style="width:18px;height:18px;"></i></button>
|
||||
</div>
|
||||
<div class="g-drawer-bd">
|
||||
<!-- 头部信息 -->
|
||||
<div class="mm-drawer-header">
|
||||
<div class="mm-drawer-avatar" id="mmDrAvatar">张</div>
|
||||
<div>
|
||||
<div style="display:flex;align-items:center;gap:8px;">
|
||||
<span class="mm-drawer-name" id="mmDrName">张**</span>
|
||||
<span class="g-tag" id="mmDrLevel" style="color:#722ed1;background:#f9f0ff;border:1px solid #d3adf7;">钻石</span>
|
||||
</div>
|
||||
<div class="mm-drawer-meta" id="mmDrMeta">138****6721 | 注册于 2024-03-15</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 消费概览 -->
|
||||
<div class="mm-section-hd">消费概览</div>
|
||||
<div class="mm-overview" id="mmDrOverview">
|
||||
<div class="mm-ov-item"><div class="mm-ov-val">¥15,280</div><div class="mm-ov-label">累计消费</div></div>
|
||||
<div class="mm-ov-item"><div class="mm-ov-val">186</div><div class="mm-ov-label">消费次数</div></div>
|
||||
<div class="mm-ov-item"><div class="mm-ov-val">¥82.2</div><div class="mm-ov-label">平均客单价</div></div>
|
||||
<div class="mm-ov-item"><div class="mm-ov-val">¥2,350</div><div class="mm-ov-label">储值余额</div></div>
|
||||
<div class="mm-ov-item"><div class="mm-ov-val">8,620</div><div class="mm-ov-label">积分</div></div>
|
||||
</div>
|
||||
|
||||
<!-- 最近订单 -->
|
||||
<div class="mm-section-hd">最近订单</div>
|
||||
<table class="mm-mini-table">
|
||||
<thead><tr><th>日期</th><th>订单号</th><th>金额</th><th>状态</th></tr></thead>
|
||||
<tbody id="mmDrOrders">
|
||||
<tr><td>2026-02-11</td><td>OD20260211086</td><td>¥68.00</td><td><span class="g-tag g-tag-green">已完成</span></td></tr>
|
||||
<tr><td>2026-02-08</td><td>OD20260208052</td><td>¥95.50</td><td><span class="g-tag g-tag-green">已完成</span></td></tr>
|
||||
<tr><td>2026-02-05</td><td>OD20260205031</td><td>¥42.00</td><td><span class="g-tag g-tag-green">已完成</span></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- 会员标签 -->
|
||||
<div style="margin-top:20px;">
|
||||
<div class="mm-section-hd">会员标签</div>
|
||||
<div class="mm-tag-list">
|
||||
<span class="g-pill checked" onclick="this.classList.toggle('checked')">高频</span>
|
||||
<span class="g-pill checked" onclick="this.classList.toggle('checked')">午餐常客</span>
|
||||
<span class="g-pill checked" onclick="this.classList.toggle('checked')">偏好辣味</span>
|
||||
<span class="g-pill" onclick="this.classList.toggle('checked')">下午茶</span>
|
||||
<span class="g-pill" onclick="this.classList.toggle('checked')">家庭聚餐</span>
|
||||
<span class="g-pill" onclick="this.classList.toggle('checked')">外卖为主</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="g-drawer-ft">
|
||||
<button class="g-btn" onclick="closeMmDrawer()">关闭</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* Tab 切换 */
|
||||
function switchMmTab(el, tab) {
|
||||
el.parentElement.querySelectorAll('.g-seg-item').forEach(function(s){ s.classList.remove('active'); });
|
||||
el.classList.add('active');
|
||||
document.getElementById('mmTabList').style.display = tab === 'list' ? '' : 'none';
|
||||
document.getElementById('mmTabLevels').style.display = tab === 'levels' ? '' : 'none';
|
||||
if (typeof lucide !== 'undefined') lucide.createIcons();
|
||||
}
|
||||
|
||||
/* 抽屉 */
|
||||
function openMmDrawer(idx) {
|
||||
document.getElementById('mmDrawerMask').classList.add('open');
|
||||
document.getElementById('mmDrawer').classList.add('open');
|
||||
if (typeof lucide !== 'undefined') lucide.createIcons();
|
||||
}
|
||||
function closeMmDrawer() {
|
||||
document.getElementById('mmDrawerMask').classList.remove('open');
|
||||
document.getElementById('mmDrawer').classList.remove('open');
|
||||
}
|
||||
|
||||
if (typeof lucide !== 'undefined') lucide.createIcons();
|
||||
</script>
|
||||
436
pages/mbr-messaging.html
Normal file
436
pages/mbr-messaging.html
Normal file
@@ -0,0 +1,436 @@
|
||||
<!-- 消息触达页 -->
|
||||
<style>
|
||||
.msg-toolbar { display:flex; align-items:center; gap:10px; margin-bottom:16px; background:#fff; border-radius:10px; box-shadow:var(--g-shadow-sm); padding:12px 16px; flex-wrap:wrap; }
|
||||
.msg-spacer { flex:1; }
|
||||
.msg-stats { display:grid; grid-template-columns:repeat(4,1fr); gap:14px; margin-bottom:16px; }
|
||||
.msg-stat-card { background:#fff; border-radius:10px; box-shadow:var(--g-shadow-sm); padding:16px 20px; transition:box-shadow var(--g-transition), transform var(--g-transition); }
|
||||
.msg-stat-card:hover { box-shadow:var(--g-shadow-md); transform:translateY(-1px); }
|
||||
.msg-stat-label { font-size:12px; color:var(--g-text-muted); margin-bottom:6px; }
|
||||
.msg-stat-value { font-size:22px; font-weight:700; color:var(--g-text); }
|
||||
.msg-stat-value .msg-stat-unit { font-size:13px; font-weight:400; color:var(--g-text-secondary); margin-left:2px; }
|
||||
.msg-channel-dot { display:inline-block; width:6px; height:6px; border-radius:50%; margin-right:4px; vertical-align:middle; }
|
||||
.msg-open-rate { font-size:11px; color:var(--g-text-muted); margin-top:2px; }
|
||||
|
||||
/* Template cards */
|
||||
.msg-tpl-grid { display:grid; grid-template-columns:1fr 1fr; gap:14px; }
|
||||
.msg-tpl-card { background:#fff; border-radius:10px; box-shadow:var(--g-shadow-sm); padding:18px 20px; transition:box-shadow var(--g-transition), transform var(--g-transition); display:flex; flex-direction:column; }
|
||||
.msg-tpl-card:hover { box-shadow:var(--g-shadow-md); transform:translateY(-1px); }
|
||||
.msg-tpl-hd { display:flex; align-items:center; gap:8px; margin-bottom:10px; }
|
||||
.msg-tpl-name { font-size:14px; font-weight:600; color:var(--g-text); flex:1; }
|
||||
.msg-tpl-preview { font-size:12px; color:var(--g-text-secondary); line-height:1.6; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; margin-bottom:12px; flex:1; }
|
||||
.msg-tpl-ft { display:flex; align-items:center; justify-content:space-between; margin-top:auto; }
|
||||
.msg-tpl-usage { font-size:12px; color:var(--g-text-muted); }
|
||||
.msg-tpl-actions { display:flex; align-items:center; gap:10px; }
|
||||
.msg-tpl-actions a { font-size:12px; color:var(--primary); cursor:pointer; text-decoration:none; transition:var(--g-transition); }
|
||||
.msg-tpl-actions a:hover { text-decoration:underline; }
|
||||
.msg-tpl-actions a.msg-tpl-danger { color:var(--g-danger); }
|
||||
|
||||
/* Drawer: tag pills for target audience */
|
||||
.msg-tag-pills { display:flex; flex-wrap:wrap; gap:8px; margin-top:10px; }
|
||||
.msg-reach { font-size:12px; color:var(--primary); margin-top:10px; display:flex; align-items:center; gap:4px; }
|
||||
.msg-tpl-link { font-size:13px; color:var(--primary); cursor:pointer; text-decoration:none; display:inline-flex; align-items:center; gap:4px; margin-top:8px; transition:var(--g-transition); }
|
||||
.msg-tpl-link:hover { text-decoration:underline; }
|
||||
</style>
|
||||
|
||||
<div>
|
||||
<!-- Tabs -->
|
||||
<div class="g-seg" style="margin-bottom:16px;">
|
||||
<div class="g-seg-item active" onclick="switchMsgTab(this,'list')">消息列表</div>
|
||||
<div class="g-seg-item" onclick="switchMsgTab(this,'tpl')">消息模板</div>
|
||||
</div>
|
||||
|
||||
<!-- TAB 1: 消息列表 -->
|
||||
<div id="msgTabList">
|
||||
<div class="msg-toolbar">
|
||||
<select class="g-select" style="min-width:100px">
|
||||
<option>全部状态</option>
|
||||
<option>已发送</option>
|
||||
<option>待发送</option>
|
||||
<option>草稿</option>
|
||||
</select>
|
||||
<select class="g-select" style="min-width:100px">
|
||||
<option>全部渠道</option>
|
||||
<option>站内信</option>
|
||||
<option>短信</option>
|
||||
<option>微信</option>
|
||||
</select>
|
||||
<input class="g-input" placeholder="搜索消息标题" style="width:180px" />
|
||||
<span class="msg-spacer"></span>
|
||||
<button class="g-btn g-btn-primary" onclick="openMsgDrawer()"><i data-lucide="plus" style="width:14px;height:14px;vertical-align:-2px;margin-right:2px;"></i> 创建消息</button>
|
||||
</div>
|
||||
|
||||
<!-- Stats -->
|
||||
<div class="msg-stats">
|
||||
<div class="msg-stat-card">
|
||||
<div class="msg-stat-label">本月发送</div>
|
||||
<div class="msg-stat-value">12<span class="msg-stat-unit">条</span></div>
|
||||
</div>
|
||||
<div class="msg-stat-card">
|
||||
<div class="msg-stat-label">触达人数</div>
|
||||
<div class="msg-stat-value">3,680<span class="msg-stat-unit">人</span></div>
|
||||
</div>
|
||||
<div class="msg-stat-card">
|
||||
<div class="msg-stat-label">打开率</div>
|
||||
<div class="msg-stat-value">45.2<span class="msg-stat-unit">%</span></div>
|
||||
</div>
|
||||
<div class="msg-stat-card">
|
||||
<div class="msg-stat-label">转化率</div>
|
||||
<div class="msg-stat-value">12.8<span class="msg-stat-unit">%</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Table -->
|
||||
<div class="g-card">
|
||||
<table class="g-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>消息标题</th>
|
||||
<th>推送渠道</th>
|
||||
<th>目标人群</th>
|
||||
<th>触达人数</th>
|
||||
<th>发送时间</th>
|
||||
<th>状态</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div style="font-weight:500;color:var(--g-text)">新品上线通知</div>
|
||||
<div class="msg-open-rate">打开率 52.3% | 转化率 15.6%</div>
|
||||
</td>
|
||||
<td><span class="g-tag g-tag-blue">站内信</span></td>
|
||||
<td>全部会员</td>
|
||||
<td>1,280</td>
|
||||
<td>2026-02-10 10:00</td>
|
||||
<td><span class="g-tag g-tag-green">已发送</span></td>
|
||||
<td><a class="g-action">详情</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div style="font-weight:500;color:var(--g-text)">春节优惠活动</div>
|
||||
<div class="msg-open-rate">打开率 48.1% | 转化率 18.2%</div>
|
||||
</td>
|
||||
<td><span class="g-tag g-tag-green">短信</span></td>
|
||||
<td>全部会员</td>
|
||||
<td>2,400</td>
|
||||
<td>2026-02-08 09:30</td>
|
||||
<td><span class="g-tag g-tag-green">已发送</span></td>
|
||||
<td><a class="g-action">详情</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div style="font-weight:500;color:var(--g-text)">沉睡客户召回</div>
|
||||
<div class="msg-open-rate">打开率 35.7% | 转化率 8.4%</div>
|
||||
</td>
|
||||
<td><span class="g-tag g-tag-orange">微信模板</span></td>
|
||||
<td>沉睡客户(456人)</td>
|
||||
<td>456</td>
|
||||
<td>2026-02-05 14:00</td>
|
||||
<td><span class="g-tag g-tag-green">已发送</span></td>
|
||||
<td><a class="g-action">详情</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div style="font-weight:500;color:var(--g-text)">会员日提醒</div>
|
||||
</td>
|
||||
<td><span class="g-tag g-tag-blue">站内信</span></td>
|
||||
<td>高频客户(328人)</td>
|
||||
<td>328</td>
|
||||
<td>2026-02-15 08:00</td>
|
||||
<td><span class="g-tag g-tag-blue">待发送</span></td>
|
||||
<td><a class="g-action">详情</a><a class="g-action-danger">删除</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div style="font-weight:500;color:var(--g-text)">储值优惠推送</div>
|
||||
</td>
|
||||
<td><span class="g-tag g-tag-green">短信</span></td>
|
||||
<td>全部会员</td>
|
||||
<td>—</td>
|
||||
<td>—</td>
|
||||
<td><span class="g-tag g-tag-gray">草稿</span></td>
|
||||
<td><a class="g-action">详情</a><a class="g-action">编辑</a><a class="g-action-danger">删除</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div style="font-weight:500;color:var(--g-text)">新客欢迎礼</div>
|
||||
</td>
|
||||
<td><span class="g-tag g-tag-orange">微信模板</span></td>
|
||||
<td>新客(86人)</td>
|
||||
<td>—</td>
|
||||
<td>—</td>
|
||||
<td><span class="g-tag g-tag-gray">草稿</span></td>
|
||||
<td><a class="g-action">详情</a><a class="g-action">编辑</a><a class="g-action-danger">删除</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="g-pagination" style="margin-top:16px;">
|
||||
<span style="font-size:13px;color:var(--g-text-secondary);">共 6 条</span>
|
||||
<button class="g-page-btn" disabled><</button>
|
||||
<button class="g-page-btn active">1</button>
|
||||
<button class="g-page-btn">></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- TAB 2: 消息模板 -->
|
||||
<div id="msgTabTpl" style="display:none">
|
||||
<div class="msg-toolbar">
|
||||
<select class="g-select" style="min-width:100px">
|
||||
<option>全部分类</option>
|
||||
<option>营销</option>
|
||||
<option>通知</option>
|
||||
<option>召回</option>
|
||||
</select>
|
||||
<input class="g-input" placeholder="搜索模板名称" style="width:180px" />
|
||||
<span class="msg-spacer"></span>
|
||||
<button class="g-btn g-btn-primary"><i data-lucide="plus" style="width:14px;height:14px;vertical-align:-2px;margin-right:2px;"></i> 新建模板</button>
|
||||
</div>
|
||||
|
||||
<div class="msg-tpl-grid">
|
||||
<!-- Template 1 -->
|
||||
<div class="msg-tpl-card">
|
||||
<div class="msg-tpl-hd">
|
||||
<span class="msg-tpl-name">新品上线通知</span>
|
||||
<span class="g-tag g-tag-blue">通知</span>
|
||||
</div>
|
||||
<div class="msg-tpl-preview">亲爱的{name},我们上新啦!{product}现已上线,口感升级,诚意满满,快来尝鲜吧!</div>
|
||||
<div class="msg-tpl-ft">
|
||||
<span class="msg-tpl-usage"><i data-lucide="bar-chart-2" style="width:12px;height:12px;vertical-align:-1px;margin-right:2px;"></i>已使用 28次</span>
|
||||
<div class="msg-tpl-actions">
|
||||
<button class="g-btn g-btn-sm g-btn-primary" onclick="useMsgTemplate('新品上线通知','亲爱的{name},我们上新啦!{product}现已上线,口感升级,诚意满满,快来尝鲜吧!')">使用</button>
|
||||
<a>编辑</a>
|
||||
<a class="msg-tpl-danger">删除</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Template 2 -->
|
||||
<div class="msg-tpl-card">
|
||||
<div class="msg-tpl-hd">
|
||||
<span class="msg-tpl-name">节日问候</span>
|
||||
<span class="g-tag g-tag-orange">营销</span>
|
||||
</div>
|
||||
<div class="msg-tpl-preview">亲爱的{name},{holiday}快乐!为您准备了专属优惠,下单立享折扣,温暖过节从一顿好饭开始!</div>
|
||||
<div class="msg-tpl-ft">
|
||||
<span class="msg-tpl-usage"><i data-lucide="bar-chart-2" style="width:12px;height:12px;vertical-align:-1px;margin-right:2px;"></i>已使用 15次</span>
|
||||
<div class="msg-tpl-actions">
|
||||
<button class="g-btn g-btn-sm g-btn-primary" onclick="useMsgTemplate('节日问候','亲爱的{name},{holiday}快乐!为您准备了专属优惠,下单立享折扣,温暖过节从一顿好饭开始!')">使用</button>
|
||||
<a>编辑</a>
|
||||
<a class="msg-tpl-danger">删除</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Template 3 -->
|
||||
<div class="msg-tpl-card">
|
||||
<div class="msg-tpl-hd">
|
||||
<span class="msg-tpl-name">沉睡客户召回</span>
|
||||
<span class="g-tag g-tag-red">召回</span>
|
||||
</div>
|
||||
<div class="msg-tpl-preview">{name},好久不见!我们很想念您,特送上一份专属回归礼券,期待与您再次相遇!</div>
|
||||
<div class="msg-tpl-ft">
|
||||
<span class="msg-tpl-usage"><i data-lucide="bar-chart-2" style="width:12px;height:12px;vertical-align:-1px;margin-right:2px;"></i>已使用 42次</span>
|
||||
<div class="msg-tpl-actions">
|
||||
<button class="g-btn g-btn-sm g-btn-primary" onclick="useMsgTemplate('沉睡客户召回','{name},好久不见!我们很想念您,特送上一份专属回归礼券,期待与您再次相遇!')">使用</button>
|
||||
<a>编辑</a>
|
||||
<a class="msg-tpl-danger">删除</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Template 4 -->
|
||||
<div class="msg-tpl-card">
|
||||
<div class="msg-tpl-hd">
|
||||
<span class="msg-tpl-name">储值优惠提醒</span>
|
||||
<span class="g-tag g-tag-orange">营销</span>
|
||||
</div>
|
||||
<div class="msg-tpl-preview">限时充值优惠!充{amount}送{gift},多充多送,优惠截止本周日,别错过!</div>
|
||||
<div class="msg-tpl-ft">
|
||||
<span class="msg-tpl-usage"><i data-lucide="bar-chart-2" style="width:12px;height:12px;vertical-align:-1px;margin-right:2px;"></i>已使用 19次</span>
|
||||
<div class="msg-tpl-actions">
|
||||
<button class="g-btn g-btn-sm g-btn-primary" onclick="useMsgTemplate('储值优惠提醒','限时充值优惠!充{amount}送{gift},多充多送,优惠截止本周日,别错过!')">使用</button>
|
||||
<a>编辑</a>
|
||||
<a class="msg-tpl-danger">删除</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Template 5 -->
|
||||
<div class="msg-tpl-card">
|
||||
<div class="msg-tpl-hd">
|
||||
<span class="msg-tpl-name">订单完成感谢</span>
|
||||
<span class="g-tag g-tag-blue">通知</span>
|
||||
</div>
|
||||
<div class="msg-tpl-preview">感谢您的订单!期待下次光临,如有任何问题请随时联系我们,祝您用餐愉快!</div>
|
||||
<div class="msg-tpl-ft">
|
||||
<span class="msg-tpl-usage"><i data-lucide="bar-chart-2" style="width:12px;height:12px;vertical-align:-1px;margin-right:2px;"></i>已使用 56次</span>
|
||||
<div class="msg-tpl-actions">
|
||||
<button class="g-btn g-btn-sm g-btn-primary" onclick="useMsgTemplate('订单完成感谢','感谢您的订单!期待下次光临,如有任何问题请随时联系我们,祝您用餐愉快!')">使用</button>
|
||||
<a>编辑</a>
|
||||
<a class="msg-tpl-danger">删除</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Template 6 -->
|
||||
<div class="msg-tpl-card">
|
||||
<div class="msg-tpl-hd">
|
||||
<span class="msg-tpl-name">会员升级通知</span>
|
||||
<span class="g-tag g-tag-blue">通知</span>
|
||||
</div>
|
||||
<div class="msg-tpl-preview">恭喜{name}升级为{level}会员!解锁更多专属权益,感谢您一路以来的支持与信赖!</div>
|
||||
<div class="msg-tpl-ft">
|
||||
<span class="msg-tpl-usage"><i data-lucide="bar-chart-2" style="width:12px;height:12px;vertical-align:-1px;margin-right:2px;"></i>已使用 33次</span>
|
||||
<div class="msg-tpl-actions">
|
||||
<button class="g-btn g-btn-sm g-btn-primary" onclick="useMsgTemplate('会员升级通知','恭喜{name}升级为{level}会员!解锁更多专属权益,感谢您一路以来的支持与信赖!')">使用</button>
|
||||
<a>编辑</a>
|
||||
<a class="msg-tpl-danger">删除</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Drawer mask -->
|
||||
<div class="g-drawer-mask" id="msgDrawerMask" onclick="closeMsgDrawer()"></div>
|
||||
|
||||
<!-- Create message drawer -->
|
||||
<div class="g-drawer" id="msgDrawer" style="width:560px;">
|
||||
<div class="g-drawer-hd">
|
||||
<span class="g-drawer-title">创建消息</span>
|
||||
<button class="g-drawer-close" onclick="closeMsgDrawer()"><i data-lucide="x" style="width:18px;height:18px;"></i></button>
|
||||
</div>
|
||||
<div class="g-drawer-bd">
|
||||
<!-- 消息标题 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required">消息标题</label>
|
||||
<input class="g-input" id="msgTitle" placeholder="如:新品上线通知" />
|
||||
</div>
|
||||
|
||||
<!-- 推送渠道 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required">推送渠道</label>
|
||||
<div style="display:flex;gap:8px;">
|
||||
<span class="g-pill checked" onclick="selectMsgChannel(this)">站内信</span>
|
||||
<span class="g-pill" onclick="selectMsgChannel(this)">短信</span>
|
||||
<span class="g-pill" onclick="selectMsgChannel(this)">微信模板消息</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 目标人群 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required">目标人群</label>
|
||||
<select class="g-select" id="msgTargetSelect" onchange="selectMsgTarget(this)">
|
||||
<option value="all">全部会员</option>
|
||||
<option value="tag">按标签筛选</option>
|
||||
</select>
|
||||
<div id="msgTagSection" style="display:none;">
|
||||
<div class="msg-tag-pills">
|
||||
<span class="g-pill" onclick="toggleMsgTagPill(this)">高频客户</span>
|
||||
<span class="g-pill" onclick="toggleMsgTagPill(this)">新客</span>
|
||||
<span class="g-pill" onclick="toggleMsgTagPill(this)">沉睡客户</span>
|
||||
<span class="g-pill" onclick="toggleMsgTagPill(this)">流失客户</span>
|
||||
<span class="g-pill" onclick="toggleMsgTagPill(this)">午餐常客</span>
|
||||
<span class="g-pill" onclick="toggleMsgTagPill(this)">大额消费</span>
|
||||
</div>
|
||||
<div class="msg-reach" id="msgReach">
|
||||
<i data-lucide="users" style="width:14px;height:14px;"></i>
|
||||
<span>预计触达 456人</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 消息内容 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required">消息内容</label>
|
||||
<textarea class="g-textarea" id="msgContent" rows="5" placeholder="支持变量:{name}姓名 {level}等级"></textarea>
|
||||
<div class="g-hint">可使用变量实现个性化推送</div>
|
||||
</div>
|
||||
|
||||
<!-- 发送时间 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required">发送时间</label>
|
||||
<div style="display:flex;gap:8px;">
|
||||
<span class="g-pill checked" onclick="selectMsgSendTime(this,'now')">立即发送</span>
|
||||
<span class="g-pill" onclick="selectMsgSendTime(this,'scheduled')">定时发送</span>
|
||||
</div>
|
||||
<div id="msgScheduleTime" style="display:none;margin-top:10px;">
|
||||
<input class="g-input" type="datetime-local" style="width:240px;" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 选择模板 -->
|
||||
<div class="g-form-group">
|
||||
<a class="msg-tpl-link" onclick="switchMsgTab(document.querySelectorAll('.g-seg-item')[1],'tpl');closeMsgDrawer();">
|
||||
<i data-lucide="file-text" style="width:14px;height:14px;"></i>
|
||||
从模板选择
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="g-drawer-ft">
|
||||
<button class="g-btn" onclick="closeMsgDrawer()">存为草稿</button>
|
||||
<button class="g-btn g-btn-primary" onclick="closeMsgDrawer()">发送</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* Tab switching */
|
||||
function switchMsgTab(el, tab) {
|
||||
document.querySelectorAll('.g-seg-item').forEach(function(s){ s.classList.remove('active'); });
|
||||
el.classList.add('active');
|
||||
document.getElementById('msgTabList').style.display = tab === 'list' ? '' : 'none';
|
||||
document.getElementById('msgTabTpl').style.display = tab === 'tpl' ? '' : 'none';
|
||||
}
|
||||
|
||||
/* Drawer open/close */
|
||||
function openMsgDrawer() {
|
||||
document.getElementById('msgDrawerMask').classList.add('open');
|
||||
document.getElementById('msgDrawer').classList.add('open');
|
||||
}
|
||||
function closeMsgDrawer() {
|
||||
document.getElementById('msgDrawerMask').classList.remove('open');
|
||||
document.getElementById('msgDrawer').classList.remove('open');
|
||||
}
|
||||
|
||||
/* Channel pill: single select */
|
||||
function selectMsgChannel(el) {
|
||||
var pills = el.parentElement.querySelectorAll('.g-pill');
|
||||
pills.forEach(function(p){ p.classList.remove('checked'); });
|
||||
el.classList.add('checked');
|
||||
}
|
||||
|
||||
/* Target audience */
|
||||
function selectMsgTarget(el) {
|
||||
var section = document.getElementById('msgTagSection');
|
||||
section.style.display = el.value === 'tag' ? '' : 'none';
|
||||
}
|
||||
|
||||
/* Tag pill toggle (multi-select) */
|
||||
function toggleMsgTagPill(el) {
|
||||
el.classList.toggle('checked');
|
||||
var count = el.parentElement.querySelectorAll('.g-pill.checked').length;
|
||||
var reachMap = [0, 456, 712, 980, 1240, 1580, 1860];
|
||||
var reach = reachMap[count] || 0;
|
||||
document.getElementById('msgReach').querySelector('span').textContent = '预计触达 ' + reach + '人';
|
||||
}
|
||||
|
||||
/* Send time pill: single select */
|
||||
function selectMsgSendTime(el, mode) {
|
||||
var pills = el.parentElement.querySelectorAll('.g-pill');
|
||||
pills.forEach(function(p){ p.classList.remove('checked'); });
|
||||
el.classList.add('checked');
|
||||
document.getElementById('msgScheduleTime').style.display = mode === 'scheduled' ? '' : 'none';
|
||||
}
|
||||
|
||||
/* Use template: pre-fill drawer */
|
||||
function useMsgTemplate(title, content) {
|
||||
openMsgDrawer();
|
||||
document.getElementById('msgTitle').value = title;
|
||||
document.getElementById('msgContent').value = content;
|
||||
}
|
||||
|
||||
if (typeof lucide !== 'undefined') lucide.createIcons();
|
||||
</script>
|
||||
448
pages/mbr-points.html
Normal file
448
pages/mbr-points.html
Normal file
@@ -0,0 +1,448 @@
|
||||
<!-- 积分商城页 -->
|
||||
<style>
|
||||
.page-pt { max-width:1100px; }
|
||||
|
||||
/* 分段 Tab */
|
||||
.pt-seg { display:flex; background:#f5f5f5; border-radius:var(--g-radius); overflow:hidden; border:1px solid #e8e8e8; width:fit-content; margin-bottom:16px; }
|
||||
.pt-seg-item {
|
||||
padding:8px 28px; font-size:13px; cursor:pointer; color:var(--g-text-muted);
|
||||
transition:all var(--g-transition); user-select:none; border-right:1px solid #e8e8e8;
|
||||
background:transparent; border-top:none; border-bottom:none; border-left:none;
|
||||
}
|
||||
.pt-seg-item:last-child { border-right:none; }
|
||||
.pt-seg-item:hover { color:var(--g-text-secondary); background:#f0f0f0; }
|
||||
.pt-seg-item.active { background:#fff; color:var(--primary); font-weight:600; box-shadow:0 1px 4px rgba(0,0,0,.06); }
|
||||
|
||||
/* 统计卡片 */
|
||||
.pt-stats { display:grid; grid-template-columns:repeat(4,1fr); gap:12px; margin-bottom:16px; }
|
||||
.pt-stat-card {
|
||||
background:#fff; border-radius:10px; padding:16px 20px;
|
||||
box-shadow:var(--g-shadow-sm); transition:all var(--g-transition);
|
||||
}
|
||||
.pt-stat-card:hover { box-shadow:var(--g-shadow-md); transform:translateY(-1px); }
|
||||
.pt-stat-label { font-size:13px; color:var(--g-text-muted); margin-bottom:6px; }
|
||||
.pt-stat-value { font-size:24px; font-weight:700; color:var(--g-text); }
|
||||
.pt-stat-value.primary { color:var(--primary); }
|
||||
.pt-stat-value.green { color:var(--g-success); }
|
||||
.pt-stat-value.orange { color:var(--g-warning); }
|
||||
|
||||
/* 规则卡片 section 标题 */
|
||||
.pt-section-hd {
|
||||
font-size:15px; font-weight:600; color:var(--g-text);
|
||||
padding-left:10px; border-left:3px solid var(--primary); margin-bottom:16px;
|
||||
}
|
||||
|
||||
/* 规则行 */
|
||||
.pt-rule-row {
|
||||
display:flex; align-items:center; gap:12px; padding:14px 0;
|
||||
border-bottom:1px solid #f5f5f5; font-size:13px; color:var(--g-text);
|
||||
}
|
||||
.pt-rule-row:last-child { border-bottom:none; }
|
||||
.pt-rule-row .g-toggle { flex-shrink:0; }
|
||||
.pt-rule-label { min-width:110px; font-weight:500; flex-shrink:0; }
|
||||
.pt-rule-row input[type="number"] {
|
||||
width:70px; height:32px; padding:0 8px; border:1px solid #d9d9d9; border-radius:var(--g-radius-sm);
|
||||
font-size:13px; outline:none; text-align:center; transition:all var(--g-transition);
|
||||
}
|
||||
.pt-rule-row input[type="number"]:focus { border-color:var(--primary); box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 10%, transparent); }
|
||||
.pt-rule-text { color:var(--g-text-secondary); }
|
||||
|
||||
/* 有效期 pill */
|
||||
.pt-expiry-pills { display:flex; gap:10px; margin-bottom:12px; }
|
||||
|
||||
/* 工具栏 */
|
||||
.pt-toolbar {
|
||||
display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin-bottom:16px;
|
||||
box-shadow:var(--g-shadow-sm); border-radius:10px; padding:10px 14px; background:#fff;
|
||||
}
|
||||
.pt-toolbar select,
|
||||
.pt-toolbar input[type="text"] {
|
||||
height:34px; padding:0 10px; border:1px solid #e5e7eb; border-radius:8px;
|
||||
font-size:13px; outline:none; transition:all var(--g-transition); background:#fff;
|
||||
}
|
||||
.pt-toolbar select:focus,
|
||||
.pt-toolbar input[type="text"]:focus { border-color:var(--primary); box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 12%, transparent); }
|
||||
|
||||
/* 商品网格 */
|
||||
.pt-grid { display:grid; grid-template-columns:repeat(3,1fr); gap:16px; margin-bottom:16px; }
|
||||
.pt-prod-card {
|
||||
background:#fff; border-radius:10px; overflow:hidden;
|
||||
box-shadow:var(--g-shadow-sm); transition:all var(--g-transition);
|
||||
}
|
||||
.pt-prod-card:hover { box-shadow:var(--g-shadow-md); transform:translateY(-1px); }
|
||||
.pt-prod-card.pt-off { opacity:.55; }
|
||||
.pt-prod-img {
|
||||
width:100%; height:120px; background:#f0f0f0; display:flex;
|
||||
align-items:center; justify-content:center; color:#ccc;
|
||||
}
|
||||
.pt-prod-bd { padding:14px 16px; }
|
||||
.pt-prod-name { font-size:14px; font-weight:600; color:var(--g-text); margin-bottom:8px; }
|
||||
.pt-prod-price { font-size:18px; font-weight:700; color:var(--primary); margin-bottom:6px; }
|
||||
.pt-prod-price .pt-cash { font-size:13px; font-weight:500; color:var(--g-text-secondary); margin-left:4px; }
|
||||
.pt-prod-meta { display:flex; gap:16px; font-size:12px; color:var(--g-text-muted); margin-bottom:10px; }
|
||||
.pt-prod-ft {
|
||||
display:flex; align-items:center; gap:6px; padding-top:10px;
|
||||
border-top:1px solid #f5f5f5;
|
||||
}
|
||||
.pt-prod-ft .g-tag { margin-left:auto; }
|
||||
|
||||
/* 抽屉内上传占位 */
|
||||
.pt-upload-placeholder {
|
||||
width:100%; height:120px; border:2px dashed #d9d9d9; border-radius:var(--g-radius);
|
||||
display:flex; flex-direction:column; align-items:center; justify-content:center;
|
||||
color:var(--g-text-muted); font-size:13px; gap:6px; cursor:pointer;
|
||||
transition:all var(--g-transition); background:var(--g-bg-subtle);
|
||||
}
|
||||
.pt-upload-placeholder:hover { border-color:var(--primary); color:var(--primary); background:color-mix(in srgb, var(--primary) 4%, #fff); }
|
||||
|
||||
/* 兑换方式 pill 组 */
|
||||
.pt-exchange-pills { display:flex; gap:10px; }
|
||||
|
||||
/* 保存栏 */
|
||||
.pt-save-bar { margin-top:20px; display:flex; justify-content:flex-end; }
|
||||
</style>
|
||||
|
||||
<div class="page-pt">
|
||||
<!-- 分段 Tab -->
|
||||
<div class="pt-seg">
|
||||
<button class="pt-seg-item active" onclick="switchPtTab(this, 'rules')">积分规则</button>
|
||||
<button class="pt-seg-item" onclick="switchPtTab(this, 'products')">兑换商品</button>
|
||||
</div>
|
||||
|
||||
<!-- ==================== TAB 1: 积分规则 ==================== -->
|
||||
<div id="ptTabRules">
|
||||
|
||||
<!-- 统计卡片 -->
|
||||
<div class="pt-stats">
|
||||
<div class="pt-stat-card">
|
||||
<div class="pt-stat-label">累计发放积分</div>
|
||||
<div class="pt-stat-value primary">128,600</div>
|
||||
</div>
|
||||
<div class="pt-stat-card">
|
||||
<div class="pt-stat-label">已兑换积分</div>
|
||||
<div class="pt-stat-value orange">45,200</div>
|
||||
</div>
|
||||
<div class="pt-stat-card">
|
||||
<div class="pt-stat-label">积分用户</div>
|
||||
<div class="pt-stat-value">856人</div>
|
||||
</div>
|
||||
<div class="pt-stat-card">
|
||||
<div class="pt-stat-label">兑换率</div>
|
||||
<div class="pt-stat-value green">35.1%</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 积分获取规则 -->
|
||||
<div class="g-card" style="margin-bottom:16px;">
|
||||
<div class="pt-section-hd">积分获取规则</div>
|
||||
|
||||
<div class="pt-rule-row">
|
||||
<div class="g-toggle on" onclick="toggleSwitch(this)"></div>
|
||||
<span class="pt-rule-label">消费获取</span>
|
||||
<span class="pt-rule-text">每消费</span>
|
||||
<input type="number" value="1" min="0" placeholder="如:1">
|
||||
<span class="pt-rule-text">元获得</span>
|
||||
<input type="number" value="1" min="0" placeholder="如:1">
|
||||
<span class="pt-rule-text">积分</span>
|
||||
</div>
|
||||
|
||||
<div class="pt-rule-row">
|
||||
<div class="g-toggle on" onclick="toggleSwitch(this)"></div>
|
||||
<span class="pt-rule-label">评价奖励</span>
|
||||
<span class="pt-rule-text">发表评价奖励</span>
|
||||
<input type="number" value="10" min="0" placeholder="如:10">
|
||||
<span class="pt-rule-text">积分</span>
|
||||
</div>
|
||||
|
||||
<div class="pt-rule-row">
|
||||
<div class="g-toggle on" onclick="toggleSwitch(this)"></div>
|
||||
<span class="pt-rule-label">注册奖励</span>
|
||||
<span class="pt-rule-text">新用户注册赠送</span>
|
||||
<input type="number" value="100" min="0" placeholder="如:100">
|
||||
<span class="pt-rule-text">积分</span>
|
||||
</div>
|
||||
|
||||
<div class="pt-rule-row">
|
||||
<div class="g-toggle" onclick="toggleSwitch(this)"></div>
|
||||
<span class="pt-rule-label">签到奖励</span>
|
||||
<span class="pt-rule-text">每日签到奖励</span>
|
||||
<input type="number" value="5" min="0" placeholder="如:5">
|
||||
<span class="pt-rule-text">积分</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 积分有效期 -->
|
||||
<div class="g-card" style="margin-bottom:16px;">
|
||||
<div class="pt-section-hd">积分有效期</div>
|
||||
|
||||
<div class="pt-expiry-pills">
|
||||
<span class="g-pill" onclick="selectPtExpiry(this)">永久有效</span>
|
||||
<span class="g-pill checked" onclick="selectPtExpiry(this)">按年清零</span>
|
||||
</div>
|
||||
<div class="g-hint" id="ptExpiryHint">每年12月31日清零当年获得的积分,请提前通知会员</div>
|
||||
</div>
|
||||
|
||||
<!-- 保存按钮 -->
|
||||
<div class="pt-save-bar">
|
||||
<button class="g-btn g-btn-primary g-btn-lg">
|
||||
<i data-lucide="save" style="width:15px;height:15px;"></i>保存规则
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ==================== TAB 2: 兑换商品 ==================== -->
|
||||
<div id="ptTabProducts" style="display:none;">
|
||||
|
||||
<!-- 工具栏 -->
|
||||
<div class="pt-toolbar">
|
||||
<select style="width:130px;">
|
||||
<option value="">全部状态</option>
|
||||
<option>上架</option>
|
||||
<option>下架</option>
|
||||
</select>
|
||||
<input type="text" placeholder="搜索兑换商品" style="width:200px;">
|
||||
<div style="flex:1;"></div>
|
||||
<button class="g-btn g-btn-primary" onclick="openPtDrawer()">
|
||||
<i data-lucide="plus" style="width:14px;height:14px;"></i>添加兑换商品
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 商品网格 -->
|
||||
<div class="pt-grid">
|
||||
|
||||
<!-- 商品1 -->
|
||||
<div class="pt-prod-card">
|
||||
<div class="pt-prod-img"><i data-lucide="image" style="width:32px;height:32px;"></i></div>
|
||||
<div class="pt-prod-bd">
|
||||
<div class="pt-prod-name">可乐兑换券</div>
|
||||
<div class="pt-prod-price">100积分</div>
|
||||
<div class="pt-prod-meta">
|
||||
<span>库存 50</span>
|
||||
<span>已兑换 28</span>
|
||||
</div>
|
||||
<div class="pt-prod-ft">
|
||||
<a class="g-action" onclick="openPtDrawer()">编辑</a>
|
||||
<a class="g-action">下架</a>
|
||||
<a class="g-action g-action-danger">删除</a>
|
||||
<span class="g-tag g-tag-green">上架</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 商品2 -->
|
||||
<div class="pt-prod-card">
|
||||
<div class="pt-prod-img"><i data-lucide="image" style="width:32px;height:32px;"></i></div>
|
||||
<div class="pt-prod-bd">
|
||||
<div class="pt-prod-name">凉拌黄瓜</div>
|
||||
<div class="pt-prod-price">200积分</div>
|
||||
<div class="pt-prod-meta">
|
||||
<span>库存 30</span>
|
||||
<span>已兑换 45</span>
|
||||
</div>
|
||||
<div class="pt-prod-ft">
|
||||
<a class="g-action" onclick="openPtDrawer()">编辑</a>
|
||||
<a class="g-action">下架</a>
|
||||
<a class="g-action g-action-danger">删除</a>
|
||||
<span class="g-tag g-tag-green">上架</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 商品3 -->
|
||||
<div class="pt-prod-card">
|
||||
<div class="pt-prod-img"><i data-lucide="image" style="width:32px;height:32px;"></i></div>
|
||||
<div class="pt-prod-bd">
|
||||
<div class="pt-prod-name">满20减5券</div>
|
||||
<div class="pt-prod-price">300积分</div>
|
||||
<div class="pt-prod-meta">
|
||||
<span>库存 100</span>
|
||||
<span>已兑换 67</span>
|
||||
</div>
|
||||
<div class="pt-prod-ft">
|
||||
<a class="g-action" onclick="openPtDrawer()">编辑</a>
|
||||
<a class="g-action">下架</a>
|
||||
<a class="g-action g-action-danger">删除</a>
|
||||
<span class="g-tag g-tag-green">上架</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 商品4 -->
|
||||
<div class="pt-prod-card">
|
||||
<div class="pt-prod-img"><i data-lucide="image" style="width:32px;height:32px;"></i></div>
|
||||
<div class="pt-prod-bd">
|
||||
<div class="pt-prod-name">招牌奶茶</div>
|
||||
<div class="pt-prod-price">500积分<span class="pt-cash">+ ¥3.00</span></div>
|
||||
<div class="pt-prod-meta">
|
||||
<span>库存 20</span>
|
||||
<span>已兑换 12</span>
|
||||
</div>
|
||||
<div class="pt-prod-ft">
|
||||
<a class="g-action" onclick="openPtDrawer()">编辑</a>
|
||||
<a class="g-action">下架</a>
|
||||
<a class="g-action g-action-danger">删除</a>
|
||||
<span class="g-tag g-tag-green">上架</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 商品5 -->
|
||||
<div class="pt-prod-card">
|
||||
<div class="pt-prod-img"><i data-lucide="image" style="width:32px;height:32px;"></i></div>
|
||||
<div class="pt-prod-bd">
|
||||
<div class="pt-prod-name">双人套餐券</div>
|
||||
<div class="pt-prod-price">1000积分</div>
|
||||
<div class="pt-prod-meta">
|
||||
<span>库存 10</span>
|
||||
<span>已兑换 8</span>
|
||||
</div>
|
||||
<div class="pt-prod-ft">
|
||||
<a class="g-action" onclick="openPtDrawer()">编辑</a>
|
||||
<a class="g-action">下架</a>
|
||||
<a class="g-action g-action-danger">删除</a>
|
||||
<span class="g-tag g-tag-green">上架</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 商品6:已下架 -->
|
||||
<div class="pt-prod-card pt-off">
|
||||
<div class="pt-prod-img"><i data-lucide="image" style="width:32px;height:32px;"></i></div>
|
||||
<div class="pt-prod-bd">
|
||||
<div class="pt-prod-name">定制保温杯</div>
|
||||
<div class="pt-prod-price">2000积分</div>
|
||||
<div class="pt-prod-meta">
|
||||
<span>库存 0</span>
|
||||
<span>已兑换 15</span>
|
||||
</div>
|
||||
<div class="pt-prod-ft">
|
||||
<a class="g-action" onclick="openPtDrawer()">编辑</a>
|
||||
<a class="g-action">上架</a>
|
||||
<a class="g-action g-action-danger">删除</a>
|
||||
<span class="g-tag g-tag-gray">下架</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ==================== 添加/编辑兑换商品抽屉 ==================== -->
|
||||
<div class="g-drawer-mask" id="ptDrawerMask" onclick="closePtDrawer()"></div>
|
||||
<div class="g-drawer" id="ptDrawer" style="width:520px;">
|
||||
<div class="g-drawer-hd">
|
||||
<span class="g-drawer-title">添加兑换商品</span>
|
||||
<button class="g-drawer-close" onclick="closePtDrawer()">×</button>
|
||||
</div>
|
||||
<div class="g-drawer-bd">
|
||||
|
||||
<!-- 商品名称 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required">商品名称</label>
|
||||
<input class="g-input" placeholder="请输入兑换商品名称">
|
||||
</div>
|
||||
|
||||
<!-- 商品图片 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label">商品图片</label>
|
||||
<div class="pt-upload-placeholder">
|
||||
<i data-lucide="upload-cloud" style="width:28px;height:28px;"></i>
|
||||
<span>点击上传商品图片</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 兑换方式 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required">兑换方式</label>
|
||||
<div class="pt-exchange-pills">
|
||||
<span class="g-pill checked" onclick="selectPtExchangeType(this, 'points')">纯积分</span>
|
||||
<span class="g-pill" onclick="selectPtExchangeType(this, 'mixed')">积分+现金</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 所需积分 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required">所需积分</label>
|
||||
<input class="g-input" type="number" placeholder="请输入所需积分数量" min="0">
|
||||
</div>
|
||||
|
||||
<!-- 现金部分(默认隐藏) -->
|
||||
<div class="g-form-group" id="ptCashField" style="display:none;">
|
||||
<label class="g-form-label required">现金部分</label>
|
||||
<input class="g-input" type="number" placeholder="请输入需额外支付的金额" min="0" step="0.01">
|
||||
<div class="g-hint">用户兑换时需额外支付的现金金额</div>
|
||||
</div>
|
||||
|
||||
<!-- 库存数量 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required">库存数量</label>
|
||||
<input class="g-input" type="number" placeholder="请输入库存数量" min="0">
|
||||
</div>
|
||||
|
||||
<!-- 兑换限制 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label">兑换限制</label>
|
||||
<div style="display:flex; align-items:center; gap:8px;">
|
||||
<span style="font-size:13px; color:var(--g-text-secondary);">每人限兑</span>
|
||||
<input class="g-input" type="number" placeholder="不限" min="0" style="width:100px;">
|
||||
<span style="font-size:13px; color:var(--g-text-secondary);">次</span>
|
||||
</div>
|
||||
<div class="g-hint">留空或填0表示不限制兑换次数</div>
|
||||
</div>
|
||||
|
||||
<!-- 商品描述 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label">商品描述</label>
|
||||
<textarea class="g-textarea" rows="4" placeholder="请输入商品描述信息,如使用规则、有效期等"></textarea>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="g-drawer-ft">
|
||||
<button class="g-btn" onclick="closePtDrawer()">取消</button>
|
||||
<button class="g-btn g-btn-primary">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* Tab 切换 */
|
||||
function switchPtTab(el, tab) {
|
||||
document.querySelectorAll('.pt-seg-item').forEach(function(item) { item.classList.remove('active'); });
|
||||
el.classList.add('active');
|
||||
document.getElementById('ptTabRules').style.display = tab === 'rules' ? '' : 'none';
|
||||
document.getElementById('ptTabProducts').style.display = tab === 'products' ? '' : 'none';
|
||||
}
|
||||
|
||||
/* Toggle 开关 */
|
||||
function toggleSwitch(el) {
|
||||
el.classList.toggle('on');
|
||||
}
|
||||
|
||||
/* 有效期 pill 单选 */
|
||||
function selectPtExpiry(el) {
|
||||
document.querySelectorAll('.pt-expiry-pills .g-pill').forEach(function(p) { p.classList.remove('checked'); });
|
||||
el.classList.add('checked');
|
||||
var hint = document.getElementById('ptExpiryHint');
|
||||
hint.style.display = el.textContent.trim() === '按年清零' ? '' : 'none';
|
||||
}
|
||||
|
||||
/* 兑换方式 pill 单选 */
|
||||
function selectPtExchangeType(el, type) {
|
||||
document.querySelectorAll('.pt-exchange-pills .g-pill').forEach(function(p) { p.classList.remove('checked'); });
|
||||
el.classList.add('checked');
|
||||
document.getElementById('ptCashField').style.display = type === 'mixed' ? '' : 'none';
|
||||
}
|
||||
|
||||
/* 抽屉开关 */
|
||||
function openPtDrawer() {
|
||||
document.getElementById('ptDrawerMask').classList.add('open');
|
||||
document.getElementById('ptDrawer').classList.add('open');
|
||||
}
|
||||
function closePtDrawer() {
|
||||
document.getElementById('ptDrawerMask').classList.remove('open');
|
||||
document.getElementById('ptDrawer').classList.remove('open');
|
||||
}
|
||||
|
||||
/* 初始化 Lucide 图标 */
|
||||
if (typeof lucide !== 'undefined') { lucide.createIcons(); }
|
||||
</script>
|
||||
463
pages/mbr-prepaid.html
Normal file
463
pages/mbr-prepaid.html
Normal file
@@ -0,0 +1,463 @@
|
||||
<!-- 储值卡页 -->
|
||||
<style>
|
||||
/* 分段 Tab */
|
||||
.pv-tabs { display:flex; background:#f8f9fb; border-radius:8px; padding:3px; gap:2px; width:fit-content; margin-bottom:16px; }
|
||||
.pv-tab { padding:7px 22px; border-radius:6px; font-size:13px; cursor:pointer; color:#4b5563; transition:var(--g-transition); border:none; background:none; font-weight:500; }
|
||||
.pv-tab.active { background:#fff; color:var(--primary); font-weight:600; box-shadow:var(--g-shadow-sm); }
|
||||
|
||||
/* 统计卡片 */
|
||||
.pv-stats { display:grid; grid-template-columns:repeat(4,1fr); gap:12px; margin-bottom:16px; }
|
||||
.pv-stat-card { background:#fff; border-radius:10px; padding:16px 20px; box-shadow:var(--g-shadow-sm); transition:var(--g-transition); }
|
||||
.pv-stat-card:hover { box-shadow:var(--g-shadow-md); transform:translateY(-1px); }
|
||||
.pv-stat-label { font-size:13px; color:#9ca3af; margin-bottom:6px; }
|
||||
.pv-stat-value { font-size:24px; font-weight:700; color:#1a1a2e; }
|
||||
.pv-stat-value.green { color:var(--g-success); }
|
||||
.pv-stat-value.orange { color:var(--g-warning); }
|
||||
|
||||
/* 方案卡片网格 */
|
||||
.pv-plan-grid { display:grid; grid-template-columns:repeat(3,1fr); gap:16px; margin-bottom:16px; }
|
||||
.pv-plan-card {
|
||||
background:#fff; border-radius:12px; padding:0; overflow:hidden;
|
||||
box-shadow:var(--g-shadow-sm); transition:var(--g-transition); position:relative;
|
||||
}
|
||||
.pv-plan-card:hover { box-shadow:var(--g-shadow-md); transform:translateY(-1px); }
|
||||
.pv-plan-card.disabled { opacity:0.5; }
|
||||
|
||||
.pv-plan-hd {
|
||||
background:linear-gradient(135deg, hsl(212,100%,45%) 0%, hsl(212,80%,55%) 100%);
|
||||
padding:24px 20px 18px; color:#fff; position:relative; overflow:hidden;
|
||||
}
|
||||
.pv-plan-hd::after {
|
||||
content:''; position:absolute; right:-20px; top:-20px;
|
||||
width:80px; height:80px; border-radius:50%;
|
||||
background:rgba(255,255,255,0.08);
|
||||
}
|
||||
.pv-plan-amount { font-size:28px; font-weight:700; letter-spacing:-0.5px; }
|
||||
.pv-plan-amount span { font-size:15px; font-weight:400; opacity:0.8; }
|
||||
.pv-plan-gift {
|
||||
display:inline-block; margin-top:8px; padding:3px 10px; border-radius:999px;
|
||||
background:rgba(255,255,255,0.2); font-size:13px; font-weight:600; color:#fff;
|
||||
}
|
||||
.pv-plan-gift .pv-gift-num { color:#ffd666; }
|
||||
.pv-plan-effective {
|
||||
margin-top:8px; font-size:13px; opacity:0.85;
|
||||
}
|
||||
|
||||
.pv-plan-bd { padding:14px 20px; }
|
||||
.pv-plan-meta { display:flex; justify-content:space-between; align-items:center; margin-bottom:12px; }
|
||||
.pv-plan-meta-item { font-size:12px; color:var(--g-text-muted); }
|
||||
.pv-plan-meta-item span { font-weight:600; color:var(--g-text-secondary); }
|
||||
|
||||
.pv-plan-ft { display:flex; align-items:center; justify-content:space-between; padding:0 20px 14px; }
|
||||
.pv-plan-actions { display:flex; gap:6px; }
|
||||
|
||||
/* 工具栏 */
|
||||
.pv-toolbar {
|
||||
display:flex; align-items:center; gap:12px; flex-wrap:wrap;
|
||||
margin-bottom:16px; box-shadow:var(--g-shadow-sm); border-radius:10px;
|
||||
padding:10px 14px; background:#fff;
|
||||
}
|
||||
.pv-toolbar input[type="text"],
|
||||
.pv-toolbar input[type="date"] {
|
||||
height:34px; padding:0 10px; border:1px solid #e5e7eb; border-radius:8px;
|
||||
font-size:13px; outline:none; transition:var(--g-transition); background:#fff;
|
||||
}
|
||||
.pv-toolbar input:focus { border-color:var(--primary); box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 12%, transparent); }
|
||||
|
||||
/* 分页 */
|
||||
.pv-pagination {
|
||||
display:flex; align-items:center; justify-content:flex-end;
|
||||
padding:12px 16px; gap:6px; font-size:13px; color:#4b5563;
|
||||
background:#fff; border-radius:10px; box-shadow:var(--g-shadow-sm);
|
||||
}
|
||||
|
||||
/* 抽屉内赠送比例提示 */
|
||||
.pv-ratio-hint {
|
||||
display:inline-flex; align-items:center; gap:4px;
|
||||
padding:4px 10px; border-radius:6px; font-size:12px; font-weight:500;
|
||||
background:color-mix(in srgb, var(--primary) 8%, #fff);
|
||||
color:var(--primary); margin-top:6px;
|
||||
}
|
||||
|
||||
.pv-section-hd {
|
||||
font-size:15px; font-weight:600; color:var(--g-text);
|
||||
padding-left:10px; border-left:3px solid var(--primary); margin-bottom:16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="page-pv">
|
||||
<!-- 分段 Tab -->
|
||||
<div class="pv-tabs">
|
||||
<button class="pv-tab active" onclick="switchPvTab(this, 'plans')">充值方案</button>
|
||||
<button class="pv-tab" onclick="switchPvTab(this, 'records')">充值记录</button>
|
||||
</div>
|
||||
|
||||
<!-- ========== TAB 1: 充值方案 ========== -->
|
||||
<div id="pvTabPlans">
|
||||
<!-- 统计卡片 -->
|
||||
<div class="pv-stats">
|
||||
<div class="pv-stat-card">
|
||||
<div class="pv-stat-label">储值总额</div>
|
||||
<div class="pv-stat-value">¥186,500</div>
|
||||
</div>
|
||||
<div class="pv-stat-card">
|
||||
<div class="pv-stat-label">赠金总额</div>
|
||||
<div class="pv-stat-value orange">¥18,650</div>
|
||||
</div>
|
||||
<div class="pv-stat-card">
|
||||
<div class="pv-stat-label">本月充值</div>
|
||||
<div class="pv-stat-value green">¥12,800</div>
|
||||
</div>
|
||||
<div class="pv-stat-card">
|
||||
<div class="pv-stat-label">储值用户</div>
|
||||
<div class="pv-stat-value">326人</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 方案卡片 -->
|
||||
<div class="pv-section-hd">充值方案</div>
|
||||
<div class="pv-plan-grid">
|
||||
|
||||
<!-- 方案1: 100送10 -->
|
||||
<div class="pv-plan-card">
|
||||
<div class="pv-plan-hd">
|
||||
<div class="pv-plan-amount"><span>充</span> ¥100</div>
|
||||
<div class="pv-plan-gift">送 <span class="pv-gift-num">¥10</span></div>
|
||||
<div class="pv-plan-effective">到账 ¥110</div>
|
||||
</div>
|
||||
<div class="pv-plan-bd">
|
||||
<div class="pv-plan-meta">
|
||||
<span class="pv-plan-meta-item">累计充值 <span>286次</span></span>
|
||||
<span class="pv-plan-meta-item">合计 <span>¥28,600</span></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pv-plan-ft">
|
||||
<div class="g-toggle on" onclick="toggleSwitch(this)"><div class="g-toggle-dot"></div></div>
|
||||
<div class="pv-plan-actions">
|
||||
<a class="g-action" onclick="openPvDrawer('edit')">编辑</a>
|
||||
<a class="g-action g-action-danger">删除</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 方案2: 200送30 -->
|
||||
<div class="pv-plan-card">
|
||||
<div class="pv-plan-hd">
|
||||
<div class="pv-plan-amount"><span>充</span> ¥200</div>
|
||||
<div class="pv-plan-gift">送 <span class="pv-gift-num">¥30</span></div>
|
||||
<div class="pv-plan-effective">到账 ¥230</div>
|
||||
</div>
|
||||
<div class="pv-plan-bd">
|
||||
<div class="pv-plan-meta">
|
||||
<span class="pv-plan-meta-item">累计充值 <span>198次</span></span>
|
||||
<span class="pv-plan-meta-item">合计 <span>¥39,600</span></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pv-plan-ft">
|
||||
<div class="g-toggle on" onclick="toggleSwitch(this)"><div class="g-toggle-dot"></div></div>
|
||||
<div class="pv-plan-actions">
|
||||
<a class="g-action" onclick="openPvDrawer('edit')">编辑</a>
|
||||
<a class="g-action g-action-danger">删除</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 方案3: 300送50 -->
|
||||
<div class="pv-plan-card">
|
||||
<div class="pv-plan-hd">
|
||||
<div class="pv-plan-amount"><span>充</span> ¥300</div>
|
||||
<div class="pv-plan-gift">送 <span class="pv-gift-num">¥50</span></div>
|
||||
<div class="pv-plan-effective">到账 ¥350</div>
|
||||
</div>
|
||||
<div class="pv-plan-bd">
|
||||
<div class="pv-plan-meta">
|
||||
<span class="pv-plan-meta-item">累计充值 <span>145次</span></span>
|
||||
<span class="pv-plan-meta-item">合计 <span>¥43,500</span></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pv-plan-ft">
|
||||
<div class="g-toggle on" onclick="toggleSwitch(this)"><div class="g-toggle-dot"></div></div>
|
||||
<div class="pv-plan-actions">
|
||||
<a class="g-action" onclick="openPvDrawer('edit')">编辑</a>
|
||||
<a class="g-action g-action-danger">删除</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 方案4: 500送100 -->
|
||||
<div class="pv-plan-card">
|
||||
<div class="pv-plan-hd">
|
||||
<div class="pv-plan-amount"><span>充</span> ¥500</div>
|
||||
<div class="pv-plan-gift">送 <span class="pv-gift-num">¥100</span></div>
|
||||
<div class="pv-plan-effective">到账 ¥600</div>
|
||||
</div>
|
||||
<div class="pv-plan-bd">
|
||||
<div class="pv-plan-meta">
|
||||
<span class="pv-plan-meta-item">累计充值 <span>92次</span></span>
|
||||
<span class="pv-plan-meta-item">合计 <span>¥46,000</span></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pv-plan-ft">
|
||||
<div class="g-toggle on" onclick="toggleSwitch(this)"><div class="g-toggle-dot"></div></div>
|
||||
<div class="pv-plan-actions">
|
||||
<a class="g-action" onclick="openPvDrawer('edit')">编辑</a>
|
||||
<a class="g-action g-action-danger">删除</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 方案5: 1000送250 -->
|
||||
<div class="pv-plan-card">
|
||||
<div class="pv-plan-hd">
|
||||
<div class="pv-plan-amount"><span>充</span> ¥1000</div>
|
||||
<div class="pv-plan-gift">送 <span class="pv-gift-num">¥250</span></div>
|
||||
<div class="pv-plan-effective">到账 ¥1250</div>
|
||||
</div>
|
||||
<div class="pv-plan-bd">
|
||||
<div class="pv-plan-meta">
|
||||
<span class="pv-plan-meta-item">累计充值 <span>38次</span></span>
|
||||
<span class="pv-plan-meta-item">合计 <span>¥38,000</span></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pv-plan-ft">
|
||||
<div class="g-toggle on" onclick="toggleSwitch(this)"><div class="g-toggle-dot"></div></div>
|
||||
<div class="pv-plan-actions">
|
||||
<a class="g-action" onclick="openPvDrawer('edit')">编辑</a>
|
||||
<a class="g-action g-action-danger">删除</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 方案6: 2000送600 (已停用) -->
|
||||
<div class="pv-plan-card disabled">
|
||||
<div class="pv-plan-hd" style="background:linear-gradient(135deg, #9ca3af 0%, #b0b8c4 100%);">
|
||||
<div class="pv-plan-amount"><span>充</span> ¥2000</div>
|
||||
<div class="pv-plan-gift">送 <span class="pv-gift-num" style="color:#ddd;">¥600</span></div>
|
||||
<div class="pv-plan-effective">到账 ¥2600</div>
|
||||
</div>
|
||||
<div class="pv-plan-bd">
|
||||
<div class="pv-plan-meta">
|
||||
<span class="pv-plan-meta-item">累计充值 <span>5次</span></span>
|
||||
<span class="pv-plan-meta-item">合计 <span>¥10,000</span></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pv-plan-ft">
|
||||
<div class="g-toggle" onclick="toggleSwitch(this)"><div class="g-toggle-dot"></div></div>
|
||||
<div class="pv-plan-actions">
|
||||
<a class="g-action" onclick="openPvDrawer('edit')">编辑</a>
|
||||
<a class="g-action g-action-danger">删除</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<button class="g-btn g-btn-primary" onclick="openPvDrawer('create')">
|
||||
<i data-lucide="plus" style="width:14px;height:14px;"></i>添加充值方案
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- ========== TAB 2: 充值记录 ========== -->
|
||||
<div id="pvTabRecords" style="display:none;">
|
||||
<!-- 工具栏 -->
|
||||
<div class="pv-toolbar">
|
||||
<input type="date" value="2026-01-01" />
|
||||
<span style="color:var(--g-text-muted); font-size:13px;">至</span>
|
||||
<input type="date" value="2026-02-12" />
|
||||
<input type="text" placeholder="搜索会员姓名/手机号" style="width:200px;" />
|
||||
<div style="flex:1;"></div>
|
||||
<button class="g-btn"><i data-lucide="download" style="width:14px;height:14px;"></i>导出</button>
|
||||
</div>
|
||||
|
||||
<!-- 表格 -->
|
||||
<div class="g-card" style="padding:0;">
|
||||
<table class="g-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>充值单号</th>
|
||||
<th>会员</th>
|
||||
<th>手机号</th>
|
||||
<th>充值金额</th>
|
||||
<th>赠送金额</th>
|
||||
<th>到账金额</th>
|
||||
<th>支付方式</th>
|
||||
<th>充值时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="font-family:monospace; font-size:12px;">CZ20260212001</td>
|
||||
<td>张三</td>
|
||||
<td>138****6789</td>
|
||||
<td style="font-weight:600;">¥500.00</td>
|
||||
<td style="color:var(--g-warning); font-weight:500;">¥100.00</td>
|
||||
<td style="font-weight:600;">¥600.00</td>
|
||||
<td><span class="g-tag g-tag-green">微信支付</span></td>
|
||||
<td>2026-02-12 14:32</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-family:monospace; font-size:12px;">CZ20260212002</td>
|
||||
<td>李四</td>
|
||||
<td>139****2345</td>
|
||||
<td style="font-weight:600;">¥300.00</td>
|
||||
<td style="color:var(--g-warning); font-weight:500;">¥50.00</td>
|
||||
<td style="font-weight:600;">¥350.00</td>
|
||||
<td><span class="g-tag g-tag-green">微信支付</span></td>
|
||||
<td>2026-02-12 11:18</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-family:monospace; font-size:12px;">CZ20260211003</td>
|
||||
<td>王五</td>
|
||||
<td>136****8901</td>
|
||||
<td style="font-weight:600;">¥1000.00</td>
|
||||
<td style="color:var(--g-warning); font-weight:500;">¥250.00</td>
|
||||
<td style="font-weight:600;">¥1250.00</td>
|
||||
<td><span class="g-tag g-tag-blue">支付宝</span></td>
|
||||
<td>2026-02-11 19:45</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-family:monospace; font-size:12px;">CZ20260211004</td>
|
||||
<td>赵六</td>
|
||||
<td>158****4567</td>
|
||||
<td style="font-weight:600;">¥200.00</td>
|
||||
<td style="color:var(--g-warning); font-weight:500;">¥30.00</td>
|
||||
<td style="font-weight:600;">¥230.00</td>
|
||||
<td><span class="g-tag g-tag-green">微信支付</span></td>
|
||||
<td>2026-02-11 16:22</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-family:monospace; font-size:12px;">CZ20260210005</td>
|
||||
<td>孙七</td>
|
||||
<td>137****3456</td>
|
||||
<td style="font-weight:600;">¥100.00</td>
|
||||
<td style="color:var(--g-warning); font-weight:500;">¥10.00</td>
|
||||
<td style="font-weight:600;">¥110.00</td>
|
||||
<td><span class="g-tag g-tag-orange">现金</span></td>
|
||||
<td>2026-02-10 12:08</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-family:monospace; font-size:12px;">CZ20260210006</td>
|
||||
<td>周八</td>
|
||||
<td>155****7890</td>
|
||||
<td style="font-weight:600;">¥500.00</td>
|
||||
<td style="color:var(--g-warning); font-weight:500;">¥100.00</td>
|
||||
<td style="font-weight:600;">¥600.00</td>
|
||||
<td><span class="g-tag g-tag-blue">支付宝</span></td>
|
||||
<td>2026-02-10 10:35</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-family:monospace; font-size:12px;">CZ20260209007</td>
|
||||
<td>吴九</td>
|
||||
<td>132****1234</td>
|
||||
<td style="font-weight:600;">¥300.00</td>
|
||||
<td style="color:var(--g-warning); font-weight:500;">¥50.00</td>
|
||||
<td style="font-weight:600;">¥350.00</td>
|
||||
<td><span class="g-tag g-tag-green">微信支付</span></td>
|
||||
<td>2026-02-09 20:15</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-family:monospace; font-size:12px;">CZ20260209008</td>
|
||||
<td>郑十</td>
|
||||
<td>186****5678</td>
|
||||
<td style="font-weight:600;">¥200.00</td>
|
||||
<td style="color:var(--g-warning); font-weight:500;">¥30.00</td>
|
||||
<td style="font-weight:600;">¥230.00</td>
|
||||
<td><span class="g-tag g-tag-green">微信支付</span></td>
|
||||
<td>2026-02-09 09:50</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pv-pagination" style="margin-top:16px;">
|
||||
<span>共 86 条</span>
|
||||
<button class="g-page-btn"><</button>
|
||||
<button class="g-page-btn active">1</button>
|
||||
<button class="g-page-btn">2</button>
|
||||
<button class="g-page-btn">3</button>
|
||||
<button class="g-page-btn">...</button>
|
||||
<button class="g-page-btn">11</button>
|
||||
<button class="g-page-btn">></button>
|
||||
<span style="margin-left:8px;">8 条/页</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 添加/编辑充值方案抽屉 -->
|
||||
<div class="g-drawer-mask" id="pvDrawerMask" onclick="closePvDrawer()"></div>
|
||||
<div class="g-drawer" id="pvDrawer" style="width:480px">
|
||||
<div class="g-drawer-hd">
|
||||
<div class="g-drawer-title" id="pvDrawerTitle">添加充值方案</div>
|
||||
<button class="g-drawer-close" onclick="closePvDrawer()"><i data-lucide="x" style="width:18px;height:18px;"></i></button>
|
||||
</div>
|
||||
<div class="g-drawer-bd">
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required">充值金额</label>
|
||||
<input class="g-input" id="pvAmountInput" type="number" placeholder="如:100" oninput="calcPvRatio()" />
|
||||
</div>
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required">赠送金额</label>
|
||||
<input class="g-input" id="pvGiftInput" type="number" placeholder="如:10" oninput="calcPvRatio()" />
|
||||
<div class="pv-ratio-hint" id="pvRatioHint">
|
||||
<i data-lucide="info" style="width:13px;height:13px;"></i>
|
||||
<span id="pvRatioText">赠送比例 --</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label">排序</label>
|
||||
<input class="g-input" type="number" placeholder="数字越小越靠前,如:1" style="width:160px;" />
|
||||
<div class="g-hint">数字越小排序越靠前</div>
|
||||
</div>
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label">启用状态</label>
|
||||
<div style="display:flex; align-items:center; gap:10px;">
|
||||
<div class="g-toggle on" onclick="toggleSwitch(this)"><div class="g-toggle-dot"></div></div>
|
||||
<span style="font-size:13px; color:var(--g-text-secondary);">启用后会员可选择此方案充值</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="g-drawer-ft">
|
||||
<button class="g-btn" onclick="closePvDrawer()">取消</button>
|
||||
<button class="g-btn g-btn-primary" onclick="closePvDrawer()">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* Tab 切换 */
|
||||
function switchPvTab(el, tab) {
|
||||
document.querySelectorAll('.pv-tab').forEach(function(t) { t.classList.remove('active'); });
|
||||
el.classList.add('active');
|
||||
document.getElementById('pvTabPlans').style.display = tab === 'plans' ? '' : 'none';
|
||||
document.getElementById('pvTabRecords').style.display = tab === 'records' ? '' : 'none';
|
||||
}
|
||||
|
||||
/* 抽屉开关 */
|
||||
function openPvDrawer(mode) {
|
||||
document.getElementById('pvDrawerMask').classList.add('open');
|
||||
document.getElementById('pvDrawer').classList.add('open');
|
||||
document.getElementById('pvDrawerTitle').textContent = mode === 'edit' ? '编辑充值方案' : '添加充值方案';
|
||||
if (window.lucide) lucide.createIcons();
|
||||
}
|
||||
function closePvDrawer() {
|
||||
document.getElementById('pvDrawerMask').classList.remove('open');
|
||||
document.getElementById('pvDrawer').classList.remove('open');
|
||||
}
|
||||
|
||||
/* Toggle 开关 */
|
||||
function toggleSwitch(el) {
|
||||
el.classList.toggle('on');
|
||||
}
|
||||
|
||||
/* 赠送比例自动计算 */
|
||||
function calcPvRatio() {
|
||||
var amount = parseFloat(document.getElementById('pvAmountInput').value) || 0;
|
||||
var gift = parseFloat(document.getElementById('pvGiftInput').value) || 0;
|
||||
var text = '赠送比例 --';
|
||||
if (amount > 0 && gift > 0) {
|
||||
var ratio = ((gift / amount) * 100).toFixed(1);
|
||||
text = '赠送比例 ' + ratio + '%';
|
||||
}
|
||||
document.getElementById('pvRatioText').textContent = text;
|
||||
}
|
||||
</script>
|
||||
489
pages/mkt-coupon.html
Normal file
489
pages/mkt-coupon.html
Normal file
@@ -0,0 +1,489 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<style>
|
||||
/* ===== 优惠券页面私有样式 (cp- prefix) ===== */
|
||||
.cp-toolbar {
|
||||
display: flex; align-items: center; gap: 10px; margin-bottom: 16px; flex-wrap: wrap;
|
||||
}
|
||||
.cp-toolbar .g-select, .cp-toolbar .g-input { width: auto; min-width: 140px; }
|
||||
.cp-toolbar .g-input { min-width: 180px; }
|
||||
.cp-toolbar-right { margin-left: auto; flex-shrink: 0; }
|
||||
|
||||
/* 统计行 */
|
||||
.cp-stats {
|
||||
display: flex; gap: 16px; margin-bottom: 20px;
|
||||
}
|
||||
.cp-stat-item {
|
||||
display: flex; align-items: center; gap: 8px; padding: 12px 20px;
|
||||
background: #fff; border: 1px solid var(--g-border); border-radius: var(--g-radius);
|
||||
font-size: 13px; color: var(--g-text-secondary); transition: box-shadow var(--g-transition);
|
||||
flex: 1;
|
||||
}
|
||||
.cp-stat-item:hover { box-shadow: var(--g-shadow-md); }
|
||||
.cp-stat-icon {
|
||||
width: 36px; height: 36px; border-radius: 8px; display: flex; align-items: center; justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.cp-stat-icon.blue { background: #e6f7ff; color: #1890ff; }
|
||||
.cp-stat-icon.green { background: #f6ffed; color: #52c41a; }
|
||||
.cp-stat-icon.orange { background: #fff7e6; color: #fa8c16; }
|
||||
.cp-stat-icon.purple { background: #f9f0ff; color: #722ed1; }
|
||||
.cp-stat-val { font-size: 22px; font-weight: 700; color: var(--g-text); line-height: 1; }
|
||||
.cp-stat-label { font-size: 12px; color: var(--g-text-muted); margin-top: 2px; }
|
||||
|
||||
/* 优惠券卡片列表 */
|
||||
.cp-list { display: flex; flex-direction: column; gap: 12px; }
|
||||
|
||||
.cp-coupon {
|
||||
display: flex; border-radius: var(--g-radius); overflow: hidden;
|
||||
border: 1px solid var(--g-border); background: #fff;
|
||||
transition: box-shadow var(--g-transition);
|
||||
}
|
||||
.cp-coupon:hover { box-shadow: var(--g-shadow-md); }
|
||||
.cp-coupon.cp-dimmed { opacity: 0.55; }
|
||||
|
||||
/* 左侧券面 */
|
||||
.cp-left {
|
||||
width: 160px; min-height: 130px; flex-shrink: 0;
|
||||
display: flex; flex-direction: column; align-items: center; justify-content: center;
|
||||
color: #fff; position: relative; padding: 16px 12px;
|
||||
}
|
||||
.cp-left::after {
|
||||
content: '';
|
||||
position: absolute; right: -6px; top: 50%; transform: translateY(-50%);
|
||||
width: 12px; height: 12px; background: #fff; border-radius: 50%;
|
||||
box-shadow: inset 2px 0 4px rgba(0,0,0,.06);
|
||||
}
|
||||
.cp-left.cp-red { background: linear-gradient(135deg, #ff6b6b, #ee5a24); }
|
||||
.cp-left.cp-blue { background: linear-gradient(135deg, #4facfe, #0078d4); }
|
||||
.cp-left.cp-green { background: linear-gradient(135deg, #43e97b, #38f9d7); color: #1a5c3a; }
|
||||
.cp-left-amount { font-size: 32px; font-weight: 800; line-height: 1.1; }
|
||||
.cp-left-amount .cp-unit { font-size: 16px; font-weight: 600; }
|
||||
.cp-left-cond { font-size: 12px; margin-top: 6px; opacity: 0.85; }
|
||||
|
||||
/* 右侧详情 */
|
||||
.cp-right {
|
||||
flex: 1; padding: 14px 18px; display: flex; flex-direction: column; justify-content: center; gap: 6px;
|
||||
min-width: 0;
|
||||
}
|
||||
.cp-name { font-size: 15px; font-weight: 600; color: var(--g-text); }
|
||||
.cp-validity { font-size: 12px; color: var(--g-text-muted); display: flex; align-items: center; gap: 4px; }
|
||||
.cp-rules { font-size: 12px; color: var(--g-text-secondary); }
|
||||
.cp-stats-row { display: flex; align-items: center; gap: 12px; font-size: 12px; color: var(--g-text-secondary); }
|
||||
.cp-progress-wrap { flex: 1; max-width: 200px; }
|
||||
.cp-progress-bar {
|
||||
height: 6px; background: #f0f0f0; border-radius: 3px; overflow: hidden;
|
||||
}
|
||||
.cp-progress-fill { height: 100%; border-radius: 3px; transition: width var(--g-transition); }
|
||||
.cp-progress-fill.red { background: linear-gradient(90deg, #ff6b6b, #ee5a24); }
|
||||
.cp-progress-fill.blue { background: linear-gradient(90deg, #4facfe, #0078d4); }
|
||||
.cp-progress-fill.green { background: linear-gradient(90deg, #43e97b, #38f9d7); }
|
||||
.cp-bottom-row {
|
||||
display: flex; align-items: center; justify-content: space-between; margin-top: 2px;
|
||||
}
|
||||
.cp-actions { display: flex; align-items: center; gap: 12px; }
|
||||
|
||||
/* 抽屉 */
|
||||
.cp-drawer { width: 560px; }
|
||||
.cp-type-pills { display: flex; gap: 8px; }
|
||||
.cp-amount-row { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--g-text-secondary); }
|
||||
.cp-amount-row .g-input { width: 100px; }
|
||||
.cp-valid-section { margin-top: 8px; }
|
||||
.cp-channel-pills { display: flex; gap: 8px; flex-wrap: wrap; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- 工具栏 -->
|
||||
<div class="cp-toolbar">
|
||||
<select class="g-select" style="min-width:170px;">
|
||||
<option>全部门店</option>
|
||||
<option>老三家外卖(朝阳店)</option>
|
||||
<option>老三家外卖(海淀店)</option>
|
||||
<option>老三家外卖(望京店)</option>
|
||||
<option>老三家外卖(通州店)</option>
|
||||
<option>老三家外卖(丰台店)</option>
|
||||
</select>
|
||||
<select class="g-select" id="cpStatusFilter">
|
||||
<option value="">全部状态</option>
|
||||
<option value="进行中">进行中</option>
|
||||
<option value="未开始">未开始</option>
|
||||
<option value="已结束">已结束</option>
|
||||
<option value="已停用">已停用</option>
|
||||
</select>
|
||||
<select class="g-select" id="cpTypeFilter">
|
||||
<option value="">全部类型</option>
|
||||
<option value="满减券">满减券</option>
|
||||
<option value="折扣券">折扣券</option>
|
||||
<option value="免配送费券">免配送费券</option>
|
||||
</select>
|
||||
<input class="g-input" placeholder="搜索券名称" id="cpSearch" style="min-width:160px;">
|
||||
<div class="cp-toolbar-right">
|
||||
<button class="g-btn g-btn-primary" onclick="openCpDrawer('create')">
|
||||
<i data-lucide="plus" style="width:15px;height:15px;"></i> 创建优惠券
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 统计行 -->
|
||||
<div class="cp-stats">
|
||||
<div class="cp-stat-item">
|
||||
<div class="cp-stat-icon blue"><i data-lucide="ticket" style="width:18px;height:18px;"></i></div>
|
||||
<div><div class="cp-stat-val">28</div><div class="cp-stat-label">优惠券总数</div></div>
|
||||
</div>
|
||||
<div class="cp-stat-item">
|
||||
<div class="cp-stat-icon green"><i data-lucide="play-circle" style="width:18px;height:18px;"></i></div>
|
||||
<div><div class="cp-stat-val">12</div><div class="cp-stat-label">进行中</div></div>
|
||||
</div>
|
||||
<div class="cp-stat-item">
|
||||
<div class="cp-stat-icon orange"><i data-lucide="download" style="width:18px;height:18px;"></i></div>
|
||||
<div><div class="cp-stat-val">3,680</div><div class="cp-stat-label">已领取(张)</div></div>
|
||||
</div>
|
||||
<div class="cp-stat-item">
|
||||
<div class="cp-stat-icon purple"><i data-lucide="check-circle" style="width:18px;height:18px;"></i></div>
|
||||
<div><div class="cp-stat-val">2,156</div><div class="cp-stat-label">已核销(核销率 58.6%)</div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 优惠券卡片列表 -->
|
||||
<div class="cp-list" id="cpList">
|
||||
|
||||
<!-- 1. 满减券 - 进行中 -->
|
||||
<div class="cp-coupon">
|
||||
<div class="cp-left cp-red">
|
||||
<div class="cp-left-amount"><span class="cp-unit">¥</span>15</div>
|
||||
<div class="cp-left-cond">满50可用</div>
|
||||
</div>
|
||||
<div class="cp-right">
|
||||
<div class="cp-name">新用户满减券</div>
|
||||
<div class="cp-validity"><i data-lucide="calendar" style="width:12px;height:12px;"></i> 2025.02.01 - 2025.03.01</div>
|
||||
<div class="cp-rules">每人限领1张 | 仅外卖可用</div>
|
||||
<div class="cp-stats-row">
|
||||
<span>已领 580/1000</span>
|
||||
<div class="cp-progress-wrap">
|
||||
<div class="cp-progress-bar"><div class="cp-progress-fill red" style="width:58%;"></div></div>
|
||||
</div>
|
||||
<span>已用 320</span>
|
||||
</div>
|
||||
<div class="cp-bottom-row">
|
||||
<span class="g-tag g-tag-green">进行中</span>
|
||||
<div class="cp-actions">
|
||||
<a class="g-action" onclick="openCpDrawer('edit')">编辑</a>
|
||||
<a class="g-action" onclick="void(0)">停用</a>
|
||||
<a class="g-action g-action-danger" onclick="void(0)">删除</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 2. 折扣券 - 进行中 -->
|
||||
<div class="cp-coupon">
|
||||
<div class="cp-left cp-blue">
|
||||
<div class="cp-left-amount">8<span class="cp-unit">折</span></div>
|
||||
<div class="cp-left-cond">全场通用</div>
|
||||
</div>
|
||||
<div class="cp-right">
|
||||
<div class="cp-name">周末全场8折券</div>
|
||||
<div class="cp-validity"><i data-lucide="calendar" style="width:12px;height:12px;"></i> 2025.01.15 - 2025.04.15</div>
|
||||
<div class="cp-rules">每人限领2张 | 外卖/自提可用</div>
|
||||
<div class="cp-stats-row">
|
||||
<span>已领 1,200/2000</span>
|
||||
<div class="cp-progress-wrap">
|
||||
<div class="cp-progress-bar"><div class="cp-progress-fill blue" style="width:60%;"></div></div>
|
||||
</div>
|
||||
<span>已用 860</span>
|
||||
</div>
|
||||
<div class="cp-bottom-row">
|
||||
<span class="g-tag g-tag-green">进行中</span>
|
||||
<div class="cp-actions">
|
||||
<a class="g-action" onclick="openCpDrawer('edit')">编辑</a>
|
||||
<a class="g-action" onclick="void(0)">停用</a>
|
||||
<a class="g-action g-action-danger" onclick="void(0)">删除</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 3. 免配送费券 - 未开始 -->
|
||||
<div class="cp-coupon">
|
||||
<div class="cp-left cp-green">
|
||||
<div class="cp-left-amount" style="font-size:24px;">免配送</div>
|
||||
<div class="cp-left-cond">无门槛</div>
|
||||
</div>
|
||||
<div class="cp-right">
|
||||
<div class="cp-name">春季免配送费券</div>
|
||||
<div class="cp-validity"><i data-lucide="calendar" style="width:12px;height:12px;"></i> 2025.03.01 - 2025.03.31</div>
|
||||
<div class="cp-rules">每人限领3张 | 仅外卖可用</div>
|
||||
<div class="cp-stats-row">
|
||||
<span>已领 0/5000</span>
|
||||
<div class="cp-progress-wrap">
|
||||
<div class="cp-progress-bar"><div class="cp-progress-fill green" style="width:0%;"></div></div>
|
||||
</div>
|
||||
<span>已用 0</span>
|
||||
</div>
|
||||
<div class="cp-bottom-row">
|
||||
<span class="g-tag g-tag-blue">未开始</span>
|
||||
<div class="cp-actions">
|
||||
<a class="g-action" onclick="openCpDrawer('edit')">编辑</a>
|
||||
<a class="g-action" onclick="void(0)">停用</a>
|
||||
<a class="g-action g-action-danger" onclick="void(0)">删除</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 4. 满减券 - 已结束 (dimmed) -->
|
||||
<div class="cp-coupon cp-dimmed">
|
||||
<div class="cp-left cp-red">
|
||||
<div class="cp-left-amount"><span class="cp-unit">¥</span>10</div>
|
||||
<div class="cp-left-cond">满30可用</div>
|
||||
</div>
|
||||
<div class="cp-right">
|
||||
<div class="cp-name">元旦满减券</div>
|
||||
<div class="cp-validity"><i data-lucide="calendar" style="width:12px;height:12px;"></i> 2024.12.28 - 2025.01.03</div>
|
||||
<div class="cp-rules">每人限领1张 | 全渠道可用</div>
|
||||
<div class="cp-stats-row">
|
||||
<span>已领 900/1000</span>
|
||||
<div class="cp-progress-wrap">
|
||||
<div class="cp-progress-bar"><div class="cp-progress-fill red" style="width:90%;"></div></div>
|
||||
</div>
|
||||
<span>已用 756</span>
|
||||
</div>
|
||||
<div class="cp-bottom-row">
|
||||
<span class="g-tag g-tag-gray">已结束</span>
|
||||
<div class="cp-actions">
|
||||
<a class="g-action" onclick="void(0)">查看</a>
|
||||
<a class="g-action g-action-danger" onclick="void(0)">删除</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 5. 折扣券 - 已停用 (dimmed) -->
|
||||
<div class="cp-coupon cp-dimmed">
|
||||
<div class="cp-left cp-blue">
|
||||
<div class="cp-left-amount">7<span class="cp-unit">折</span></div>
|
||||
<div class="cp-left-cond">满80可用</div>
|
||||
</div>
|
||||
<div class="cp-right">
|
||||
<div class="cp-name">会员专享7折券</div>
|
||||
<div class="cp-validity"><i data-lucide="calendar" style="width:12px;height:12px;"></i> 2025.01.01 - 2025.06.30</div>
|
||||
<div class="cp-rules">每人限领1张 | 仅堂食可用</div>
|
||||
<div class="cp-stats-row">
|
||||
<span>已领 200/500</span>
|
||||
<div class="cp-progress-wrap">
|
||||
<div class="cp-progress-bar"><div class="cp-progress-fill blue" style="width:40%;"></div></div>
|
||||
</div>
|
||||
<span>已用 120</span>
|
||||
</div>
|
||||
<div class="cp-bottom-row">
|
||||
<span class="g-tag g-tag-red">已停用</span>
|
||||
<div class="cp-actions">
|
||||
<a class="g-action" onclick="void(0)">启用</a>
|
||||
<a class="g-action g-action-danger" onclick="void(0)">删除</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="g-pagination">
|
||||
<span style="margin-right:8px;">共 28 条</span>
|
||||
<button class="g-page-btn" disabled><</button>
|
||||
<button class="g-page-btn active">1</button>
|
||||
<button class="g-page-btn">2</button>
|
||||
<button class="g-page-btn">3</button>
|
||||
<button class="g-page-btn">></button>
|
||||
</div>
|
||||
|
||||
<!-- 抽屉遮罩 -->
|
||||
<div class="g-drawer-mask" id="cpDrawerMask" onclick="closeCpDrawer()"></div>
|
||||
|
||||
<!-- 创建/编辑抽屉 -->
|
||||
<div class="g-drawer cp-drawer" id="cpDrawer">
|
||||
<div class="g-drawer-hd">
|
||||
<div class="g-drawer-title" id="cpDrawerTitle">创建优惠券</div>
|
||||
<button class="g-drawer-close" onclick="closeCpDrawer()"><i data-lucide="x" style="width:18px;height:18px;"></i></button>
|
||||
</div>
|
||||
<div class="g-drawer-bd">
|
||||
|
||||
<!-- 券名称 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required">券名称</label>
|
||||
<input class="g-input" placeholder="如:新用户满减券" id="cpName">
|
||||
</div>
|
||||
|
||||
<!-- 券类型 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required">券类型</label>
|
||||
<div class="cp-type-pills">
|
||||
<span class="g-pill checked" onclick="selectCpType(this, 'reduce')">满减券</span>
|
||||
<span class="g-pill" onclick="selectCpType(this, 'discount')">折扣券</span>
|
||||
<span class="g-pill" onclick="selectCpType(this, 'free_delivery')">免配送费券</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 面额设置 - 满减 -->
|
||||
<div class="g-form-group" id="cpAmountReduce">
|
||||
<label class="g-form-label required">面额设置</label>
|
||||
<div class="cp-amount-row">
|
||||
<span>满</span>
|
||||
<input class="g-input" type="number" placeholder="如:50" id="cpThresholdInput">
|
||||
<span>元减</span>
|
||||
<input class="g-input" type="number" placeholder="如:15">
|
||||
<span>元</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 面额设置 - 折扣 -->
|
||||
<div class="g-form-group" id="cpAmountDiscount" style="display:none;">
|
||||
<label class="g-form-label required">折扣力度</label>
|
||||
<div class="cp-amount-row">
|
||||
<input class="g-input" type="number" placeholder="如:8 表示8折" style="width:160px;">
|
||||
<span>折</span>
|
||||
</div>
|
||||
<div class="g-hint">输入 8 表示打8折,即优惠20%</div>
|
||||
</div>
|
||||
|
||||
<!-- 面额设置 - 免配送费 -->
|
||||
<div class="g-form-group" id="cpAmountFreeDelivery" style="display:none;">
|
||||
<label class="g-form-label">面额设置</label>
|
||||
<div style="font-size:13px;color:var(--g-text-muted);padding:8px 0;">免配送费券无需设置面额</div>
|
||||
</div>
|
||||
|
||||
<div class="g-divider"></div>
|
||||
|
||||
<!-- 发放总量 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required">发放总量</label>
|
||||
<input class="g-input" type="number" placeholder="如:1000" style="width:200px;">
|
||||
<div class="g-hint">设置后不可减少,可增加</div>
|
||||
</div>
|
||||
|
||||
<!-- 每人限领 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label">每人限领</label>
|
||||
<input class="g-input" type="number" placeholder="如:1" style="width:200px;">
|
||||
<div class="g-hint">不填则不限制</div>
|
||||
</div>
|
||||
|
||||
<div class="g-divider"></div>
|
||||
|
||||
<!-- 有效期类型 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required">有效期类型</label>
|
||||
<div class="cp-type-pills">
|
||||
<span class="g-pill checked" onclick="selectCpValidType(this, 'fixed')">固定时间</span>
|
||||
<span class="g-pill" onclick="selectCpValidType(this, 'days')">领取后N天</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 固定时间 -->
|
||||
<div class="g-form-group cp-valid-section" id="cpValidFixed">
|
||||
<label class="g-form-label required">有效时间范围</label>
|
||||
<div style="display:flex;align-items:center;gap:8px;">
|
||||
<input class="g-input" type="date" style="width:180px;">
|
||||
<span style="color:var(--g-text-muted);">至</span>
|
||||
<input class="g-input" type="date" style="width:180px;">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 领取后N天 -->
|
||||
<div class="g-form-group cp-valid-section" id="cpValidDays" style="display:none;">
|
||||
<label class="g-form-label required">领取后有效天数</label>
|
||||
<div class="cp-amount-row">
|
||||
<span>领取后</span>
|
||||
<input class="g-input" type="number" placeholder="如:7" style="width:120px;">
|
||||
<span>天内有效</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="g-divider"></div>
|
||||
|
||||
<!-- 使用门槛 -->
|
||||
<div class="g-form-group" id="cpThresholdGroup">
|
||||
<label class="g-form-label">使用门槛</label>
|
||||
<div class="cp-amount-row">
|
||||
<span>订单满</span>
|
||||
<input class="g-input" type="number" placeholder="如:50" style="width:140px;" id="cpThresholdVal">
|
||||
<span>元可用</span>
|
||||
</div>
|
||||
<div class="g-hint">不填则无门槛</div>
|
||||
</div>
|
||||
|
||||
<!-- 适用渠道 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label">适用渠道</label>
|
||||
<div class="cp-channel-pills">
|
||||
<span class="g-pill checked" onclick="toggleCpPill(this)">外卖</span>
|
||||
<span class="g-pill checked" onclick="toggleCpPill(this)">自提</span>
|
||||
<span class="g-pill checked" onclick="toggleCpPill(this)">堂食</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 适用门店 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label">适用门店</label>
|
||||
<select class="g-select">
|
||||
<option>全部门店</option>
|
||||
<option>老三家外卖(朝阳店)</option>
|
||||
<option>老三家外卖(海淀店)</option>
|
||||
<option>老三家外卖(望京店)</option>
|
||||
<option>老三家外卖(通州店)</option>
|
||||
<option>老三家外卖(丰台店)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="g-drawer-ft">
|
||||
<button class="g-btn" onclick="closeCpDrawer()">取消</button>
|
||||
<button class="g-btn g-btn-primary">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* ===== 抽屉开关 ===== */
|
||||
function openCpDrawer(mode) {
|
||||
document.getElementById('cpDrawerMask').classList.add('open');
|
||||
document.getElementById('cpDrawer').classList.add('open');
|
||||
document.getElementById('cpDrawerTitle').textContent = mode === 'edit' ? '编辑优惠券' : '创建优惠券';
|
||||
if (typeof lucide !== 'undefined') lucide.createIcons();
|
||||
}
|
||||
function closeCpDrawer() {
|
||||
document.getElementById('cpDrawerMask').classList.remove('open');
|
||||
document.getElementById('cpDrawer').classList.remove('open');
|
||||
}
|
||||
|
||||
/* ===== 券类型切换 ===== */
|
||||
function selectCpType(el, type) {
|
||||
el.parentElement.querySelectorAll('.g-pill').forEach(function(p) { p.classList.remove('checked'); });
|
||||
el.classList.add('checked');
|
||||
document.getElementById('cpAmountReduce').style.display = type === 'reduce' ? '' : 'none';
|
||||
document.getElementById('cpAmountDiscount').style.display = type === 'discount' ? '' : 'none';
|
||||
document.getElementById('cpAmountFreeDelivery').style.display = type === 'free_delivery' ? '' : 'none';
|
||||
// 免配送费时隐藏使用门槛
|
||||
document.getElementById('cpThresholdGroup').style.display = type === 'free_delivery' ? 'none' : '';
|
||||
}
|
||||
|
||||
/* ===== 有效期类型切换 ===== */
|
||||
function selectCpValidType(el, type) {
|
||||
el.parentElement.querySelectorAll('.g-pill').forEach(function(p) { p.classList.remove('checked'); });
|
||||
el.classList.add('checked');
|
||||
document.getElementById('cpValidFixed').style.display = type === 'fixed' ? '' : 'none';
|
||||
document.getElementById('cpValidDays').style.display = type === 'days' ? '' : 'none';
|
||||
}
|
||||
|
||||
/* ===== Pill 多选切换 ===== */
|
||||
function toggleCpPill(el) {
|
||||
el.classList.toggle('checked');
|
||||
}
|
||||
|
||||
/* ===== 初始化图标 ===== */
|
||||
if (typeof lucide !== 'undefined') lucide.createIcons();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
472
pages/mkt-flash-sale.html
Normal file
472
pages/mkt-flash-sale.html
Normal file
@@ -0,0 +1,472 @@
|
||||
<!-- 限时折扣页 -->
|
||||
<style>
|
||||
.fs-toolbar { display:flex; align-items:center; gap:12px; margin-bottom:16px; box-shadow:var(--g-shadow-sm); border-radius:10px; padding:12px 16px; background:#fff; flex-wrap:wrap; }
|
||||
.fs-search { position:relative; }
|
||||
.fs-search input { height:34px; padding:0 10px 0 32px; border:1px solid #e5e7eb; border-radius:8px; font-size:13px; outline:none; width:200px; transition:var(--g-transition); }
|
||||
.fs-search input:focus { border-color:var(--primary); box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 12%, transparent); }
|
||||
.fs-search i { position:absolute; left:9px; top:50%; transform:translateY(-50%); color:#bbb; pointer-events:none; }
|
||||
.fs-stats { display:flex; gap:24px; margin-bottom:16px; padding:10px 16px; background:#fff; border-radius:10px; box-shadow:var(--g-shadow-sm); font-size:13px; color:#4b5563; }
|
||||
.fs-stats span { display:flex; align-items:center; gap:6px; }
|
||||
.fs-stats strong { color:#1a1a2e; font-weight:600; }
|
||||
.fs-card { background:#fff; border-radius:10px; box-shadow:var(--g-shadow-sm); padding:20px; margin-bottom:16px; transition:box-shadow var(--g-transition); }
|
||||
.fs-card:hover { box-shadow:var(--g-shadow-md); }
|
||||
.fs-card.ended { opacity:.5; }
|
||||
.fs-card-hd { display:flex; align-items:center; gap:10px; margin-bottom:14px; flex-wrap:wrap; }
|
||||
.fs-card-name { font-size:15px; font-weight:600; color:#1a1a2e; }
|
||||
.fs-card-time { font-size:12px; color:var(--g-text-muted); display:flex; align-items:center; gap:4px; }
|
||||
.fs-tag-running { background:#dcfce7; color:#22c55e; border:1px solid #bbf7d0; border-radius:6px; font-weight:600; }
|
||||
.fs-tag-ended { background:#f8f9fb; color:#9ca3af; border:1px solid #e5e7eb; border-radius:6px; font-weight:600; }
|
||||
.fs-prod-table { width:100%; border-collapse:collapse; font-size:13px; margin-bottom:14px; }
|
||||
.fs-prod-table th { background:#f8f9fb; padding:8px 12px; text-align:left; font-weight:600; color:#6b7280; border-bottom:1px solid #e5e7eb; font-size:12px; }
|
||||
.fs-prod-table td { padding:8px 12px; border-bottom:1px solid #f3f4f6; color:#1a1a2e; }
|
||||
.fs-prod-table tr:last-child td { border-bottom:none; }
|
||||
.fs-prod-table tr:hover td { background:color-mix(in srgb, var(--primary) 3%, #fff); }
|
||||
.fs-orig-price { color:var(--g-text-muted); text-decoration:line-through; font-size:12px; }
|
||||
.fs-disc-price { color:#ef4444; font-weight:600; }
|
||||
.fs-disc-rate { display:inline-block; padding:1px 6px; border-radius:4px; background:#fff1f0; color:#ef4444; font-size:11px; font-weight:600; }
|
||||
.fs-card-summary { display:flex; gap:24px; font-size:12px; color:#4b5563; margin-bottom:12px; padding:10px 12px; background:#f8f9fb; border-radius:8px; }
|
||||
.fs-card-summary strong { color:#1a1a2e; font-weight:600; }
|
||||
.fs-card-ft { display:flex; gap:16px; border-top:1px solid #f3f4f6; padding-top:12px; }
|
||||
/* 抽屉内折扣商品列表 */
|
||||
.fs-drawer-prod { border:1px solid #e5e7eb; border-radius:8px; overflow:hidden; margin-bottom:12px; }
|
||||
.fs-drawer-prod-hd { display:flex; align-items:center; justify-content:space-between; padding:8px 12px; background:#f8f9fb; border-bottom:1px solid #e5e7eb; }
|
||||
.fs-drawer-prod-hd span { font-size:13px; font-weight:500; color:#1a1a2e; }
|
||||
.fs-drawer-prod-remove { background:none; border:none; color:#9ca3af; cursor:pointer; display:flex; align-items:center; justify-content:center; width:24px; height:24px; border-radius:6px; transition:var(--g-transition); }
|
||||
.fs-drawer-prod-remove:hover { color:#ef4444; background:#fef2f2; }
|
||||
.fs-drawer-prod-bd { padding:10px 12px; display:flex; gap:12px; align-items:center; flex-wrap:wrap; }
|
||||
.fs-drawer-prod-bd .fs-field { display:flex; flex-direction:column; gap:4px; }
|
||||
.fs-drawer-prod-bd .fs-field label { font-size:11px; color:#6b7280; }
|
||||
.fs-drawer-prod-bd .fs-field input { width:100px; height:30px; padding:0 8px; border:1px solid #e5e7eb; border-radius:6px; font-size:13px; outline:none; transition:var(--g-transition); }
|
||||
.fs-drawer-prod-bd .fs-field input:focus { border-color:var(--primary); box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 12%, transparent); }
|
||||
.fs-drawer-prod-bd .fs-field input[readonly] { background:#f8f9fb; color:var(--g-text-muted); cursor:default; }
|
||||
.fs-drawer-prod-bd .fs-field .fs-auto-rate { font-size:12px; color:#ef4444; font-weight:600; min-width:36px; line-height:30px; }
|
||||
.fs-pill-group { display:flex; gap:8px; flex-wrap:wrap; }
|
||||
.fs-pill { padding:6px 16px; border-radius:8px; border:1px solid #e5e7eb; background:#fff; font-size:13px; cursor:pointer; color:#4b5563; transition:var(--g-transition); }
|
||||
.fs-pill:hover { border-color:var(--primary); color:var(--primary); }
|
||||
.fs-pill.checked { background:var(--primary); color:#fff; border-color:var(--primary); }
|
||||
.fs-limit-row { display:flex; align-items:center; gap:8px; }
|
||||
.fs-limit-row input { width:80px; }
|
||||
.fs-limit-row .fs-unit { font-size:13px; color:var(--g-text-secondary); }
|
||||
.fs-tag-recurring { background:#f0f5ff; color:var(--primary); border:1px solid #adc6ff; border-radius:6px; font-weight:600; }
|
||||
.fs-tag-notstarted { background:#f0f5ff; color:var(--primary); border:1px solid #adc6ff; border-radius:6px; font-weight:600; }
|
||||
.fs-recur-badge { display:inline-flex; align-items:center; gap:3px; padding:2px 8px; border-radius:4px; font-size:11px; font-weight:600; background:#f0f5ff; color:var(--primary); border:1px solid #adc6ff; }
|
||||
.fs-day-sel { display:flex; gap:6px; flex-wrap:wrap; margin-bottom:8px; }
|
||||
.fs-day { width:40px; height:28px; border-radius:14px; font-size:12px; display:inline-flex; align-items:center; justify-content:center; border:1px solid #e5e7eb; color:#9ca3af; background:#f8f9fb; cursor:pointer; transition:var(--g-transition); }
|
||||
.fs-day.active { background:var(--primary); color:#fff; border-color:var(--primary); }
|
||||
.fs-day-quick { display:flex; gap:6px; }
|
||||
.fs-cycle-section { display:none; }
|
||||
.fs-cycle-section.show { display:block; }
|
||||
.fs-date-section { display:block; }
|
||||
.fs-date-section.hide { display:none; }
|
||||
</style>
|
||||
|
||||
<div class="fs-toolbar">
|
||||
<select class="g-select" style="width:200px;">
|
||||
<option>老三家外卖(朝阳店)</option>
|
||||
<option>老三家外卖(海淀店)</option>
|
||||
<option>老三家外卖(望京店)</option>
|
||||
<option>老三家外卖(通州店)</option>
|
||||
<option>老三家外卖(丰台店)</option>
|
||||
</select>
|
||||
<select class="g-select" style="width:120px;">
|
||||
<option value="">全部状态</option>
|
||||
<option>进行中</option>
|
||||
<option>已结束</option>
|
||||
<option>未开始</option>
|
||||
</select>
|
||||
<div class="fs-search">
|
||||
<i data-lucide="search" style="width:14px;height:14px;"></i>
|
||||
<input type="text" placeholder="搜索活动名称…" />
|
||||
</div>
|
||||
<div style="flex:1;"></div>
|
||||
<button class="g-btn g-btn-primary" onclick="openFsDrawer('add')"><i data-lucide="plus" style="width:14px;height:14px;"></i>创建限时折扣</button>
|
||||
</div>
|
||||
|
||||
<div class="fs-stats">
|
||||
<span>活动总数 <strong>6</strong></span>
|
||||
<span>进行中 <strong>3</strong></span>
|
||||
<span>参与商品 <strong>18</strong>件</span>
|
||||
<span>本月折扣销量 <strong>560</strong>单</span>
|
||||
</div>
|
||||
|
||||
<!-- 活动卡片列表 -->
|
||||
<div id="fsActivityList">
|
||||
|
||||
<!-- 午市特惠 - 进行中 -->
|
||||
<div class="fs-card">
|
||||
<div class="fs-card-hd">
|
||||
<span class="fs-card-name">午市特惠</span>
|
||||
<span class="g-tag fs-tag-running">进行中</span>
|
||||
<span class="fs-card-time"><i data-lucide="clock" style="width:12px;height:12px;"></i>每天 11:00 - 14:00</span>
|
||||
<span class="fs-card-time"><i data-lucide="calendar" style="width:12px;height:12px;"></i>2026-01-01 ~ 2026-03-31</span>
|
||||
</div>
|
||||
<table class="fs-prod-table">
|
||||
<thead><tr><th>商品名</th><th>原价</th><th>折扣价</th><th>折扣力度</th><th>限购</th><th>已售</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>香辣鸡腿堡套餐</td><td class="fs-orig-price">¥32.00</td><td class="fs-disc-price">¥25.60</td><td><span class="fs-disc-rate">8折</span></td><td>2件/人</td><td>86</td></tr>
|
||||
<tr><td>牛肉拌面</td><td class="fs-orig-price">¥28.00</td><td class="fs-disc-price">¥19.60</td><td><span class="fs-disc-rate">7折</span></td><td>1件/人</td><td>52</td></tr>
|
||||
<tr><td>招牌卤肉饭</td><td class="fs-orig-price">¥22.00</td><td class="fs-disc-price">¥17.60</td><td><span class="fs-disc-rate">8折</span></td><td>2件/人</td><td>42</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="fs-card-summary">
|
||||
<span>活动销量 <strong>180</strong>单</span>
|
||||
<span>折扣总额 <strong>¥1,260</strong></span>
|
||||
</div>
|
||||
<div class="fs-card-ft">
|
||||
<span class="g-action" onclick="openFsDrawer('edit','午市特惠')">编辑</span>
|
||||
<span class="g-action">停用</span>
|
||||
<span class="g-action g-action-danger">删除</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 新品尝鲜 - 进行中 -->
|
||||
<div class="fs-card">
|
||||
<div class="fs-card-hd">
|
||||
<span class="fs-card-name">新品尝鲜</span>
|
||||
<span class="g-tag fs-tag-running">进行中</span>
|
||||
<span class="fs-card-time"><i data-lucide="clock" style="width:12px;height:12px;"></i>每天 10:00 - 22:00</span>
|
||||
<span class="fs-card-time"><i data-lucide="calendar" style="width:12px;height:12px;"></i>2026-02-01 ~ 2026-02-28</span>
|
||||
</div>
|
||||
<table class="fs-prod-table">
|
||||
<thead><tr><th>商品名</th><th>原价</th><th>折扣价</th><th>折扣力度</th><th>限购</th><th>已售</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>黑松露鸡肉卷</td><td class="fs-orig-price">¥38.00</td><td class="fs-disc-price">¥26.60</td><td><span class="fs-disc-rate">7折</span></td><td>1件/人</td><td>67</td></tr>
|
||||
<tr><td>芝士焗虾饭</td><td class="fs-orig-price">¥35.00</td><td class="fs-disc-price">¥28.00</td><td><span class="fs-disc-rate">8折</span></td><td>1件/人</td><td>45</td></tr>
|
||||
<tr><td>抹茶冰淇淋</td><td class="fs-orig-price">¥18.00</td><td class="fs-disc-price">¥9.00</td><td><span class="fs-disc-rate">5折</span></td><td>2件/人</td><td>120</td></tr>
|
||||
<tr><td>鲜榨牛油果汁</td><td class="fs-orig-price">¥22.00</td><td class="fs-disc-price">¥15.40</td><td><span class="fs-disc-rate">7折</span></td><td>1件/人</td><td>38</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="fs-card-summary">
|
||||
<span>活动销量 <strong>270</strong>单</span>
|
||||
<span>折扣总额 <strong>¥2,480</strong></span>
|
||||
</div>
|
||||
<div class="fs-card-ft">
|
||||
<span class="g-action" onclick="openFsDrawer('edit','新品尝鲜')">编辑</span>
|
||||
<span class="g-action">停用</span>
|
||||
<span class="g-action g-action-danger">删除</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 周末狂欢 - 已结束 -->
|
||||
<div class="fs-card ended">
|
||||
<div class="fs-card-hd">
|
||||
<span class="fs-card-name">周末狂欢</span>
|
||||
<span class="g-tag fs-tag-ended">已结束</span>
|
||||
<span class="fs-recur-badge"><i data-lucide="repeat" style="width:11px;height:11px;"></i>每周六、日</span>
|
||||
<span class="fs-card-time"><i data-lucide="clock" style="width:12px;height:12px;"></i>17:00 - 21:00</span>
|
||||
<span class="fs-card-time"><i data-lucide="calendar" style="width:12px;height:12px;"></i>2025-12-01 ~ 2026-01-31</span>
|
||||
</div>
|
||||
<table class="fs-prod-table">
|
||||
<thead><tr><th>商品名</th><th>原价</th><th>折扣价</th><th>折扣力度</th><th>限购</th><th>已售</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>烤鸡翅拼盘</td><td class="fs-orig-price">¥48.00</td><td class="fs-disc-price">¥33.60</td><td><span class="fs-disc-rate">7折</span></td><td>1件/人</td><td>95</td></tr>
|
||||
<tr><td>小龙虾套餐</td><td class="fs-orig-price">¥68.00</td><td class="fs-disc-price">¥47.60</td><td><span class="fs-disc-rate">7折</span></td><td>1件/人</td><td>62</td></tr>
|
||||
<tr><td>啤酒6连包</td><td class="fs-orig-price">¥36.00</td><td class="fs-disc-price">¥21.60</td><td><span class="fs-disc-rate">6折</span></td><td>2件/人</td><td>78</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="fs-card-summary">
|
||||
<span>活动销量 <strong>235</strong>单</span>
|
||||
<span>折扣总额 <strong>¥3,920</strong></span>
|
||||
</div>
|
||||
<div class="fs-card-ft">
|
||||
<span class="g-action" onclick="openFsDrawer('edit','周末狂欢')">编辑</span>
|
||||
<span class="g-action">启用</span>
|
||||
<span class="g-action g-action-danger">删除</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 疯狂星期四 - 进行中(周期循环) -->
|
||||
<div class="fs-card">
|
||||
<div class="fs-card-hd">
|
||||
<span class="fs-card-name">疯狂星期四</span>
|
||||
<span class="g-tag fs-tag-running">进行中</span>
|
||||
<span class="fs-recur-badge"><i data-lucide="repeat" style="width:11px;height:11px;"></i>每周四</span>
|
||||
<span class="fs-card-time"><i data-lucide="clock" style="width:12px;height:12px;"></i>11:00 - 22:00</span>
|
||||
<span class="fs-card-time"><i data-lucide="calendar" style="width:12px;height:12px;"></i>长期有效</span>
|
||||
</div>
|
||||
<table class="fs-prod-table">
|
||||
<thead><tr><th>商品名</th><th>原价</th><th>折扣价</th><th>折扣力度</th><th>限购</th><th>已售</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>香辣鸡腿堡</td><td class="fs-orig-price">¥22.00</td><td class="fs-disc-price">¥9.90</td><td><span class="fs-disc-rate">4.5折</span></td><td>2件/人</td><td>326</td></tr>
|
||||
<tr><td>黄金脆皮鸡</td><td class="fs-orig-price">¥39.90</td><td class="fs-disc-price">¥19.90</td><td><span class="fs-disc-rate">5折</span></td><td>1件/人</td><td>218</td></tr>
|
||||
<tr><td>薯条(大)</td><td class="fs-orig-price">¥16.00</td><td class="fs-disc-price">¥6.00</td><td><span class="fs-disc-rate">3.8折</span></td><td>3件/人</td><td>485</td></tr>
|
||||
<tr><td>可乐(大杯)</td><td class="fs-orig-price">¥12.00</td><td class="fs-disc-price">¥1.00</td><td><span class="fs-disc-rate">0.8折</span></td><td>1件/人</td><td>512</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="fs-card-summary">
|
||||
<span>活动销量 <strong>1,541</strong>单</span>
|
||||
<span>折扣总额 <strong>¥18,260</strong></span>
|
||||
<span>已循环 <strong>12</strong>周</span>
|
||||
</div>
|
||||
<div class="fs-card-ft">
|
||||
<span class="g-action" onclick="openFsDrawer('edit','疯狂星期四')">编辑</span>
|
||||
<span class="g-action">停用</span>
|
||||
<span class="g-action g-action-danger">删除</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="g-pagination" style="margin-top:8px;">
|
||||
<button class="g-page-btn" disabled><i data-lucide="chevron-left" style="width:14px;height:14px;"></i></button>
|
||||
<button class="g-page-btn active">1</button>
|
||||
<button class="g-page-btn">2</button>
|
||||
<button class="g-page-btn"><i data-lucide="chevron-right" style="width:14px;height:14px;"></i></button>
|
||||
<span style="font-size:12px;color:var(--g-text-muted);margin-left:8px;">共 6 条</span>
|
||||
</div>
|
||||
|
||||
<!-- 创建/编辑抽屉 -->
|
||||
<div class="g-drawer-mask" id="fsDrawerMask" onclick="closeFsDrawer()"></div>
|
||||
<div class="g-drawer" id="fsDrawer" style="width:560px">
|
||||
<div class="g-drawer-hd">
|
||||
<span class="g-drawer-title" id="fsDrawerTitle">创建限时折扣</span>
|
||||
<button class="g-drawer-close" onclick="closeFsDrawer()"><i data-lucide="x" style="width:18px;height:18px;"></i></button>
|
||||
</div>
|
||||
<div class="g-drawer-bd">
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required">活动名称</label>
|
||||
<input class="g-input" id="fsName" placeholder="请输入活动名称,如:午市特惠、新品尝鲜">
|
||||
</div>
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required">活动周期</label>
|
||||
<div class="fs-pill-group" style="margin-bottom:10px;">
|
||||
<span class="fs-pill checked" onclick="selectFsCycle(this,'once')">一次性活动</span>
|
||||
<span class="fs-pill" onclick="selectFsCycle(this,'recurring')">周期循环</span>
|
||||
</div>
|
||||
<div class="g-hint">周期循环适合固定日期的促销,如"疯狂星期四"、"周末特惠"</div>
|
||||
</div>
|
||||
<div class="g-form-group fs-date-section" id="fsDateSection">
|
||||
<label class="g-form-label required">活动时间</label>
|
||||
<div style="display:flex;gap:8px;align-items:center;">
|
||||
<input class="g-input" type="date" id="fsDateStart" value="2026-02-01" style="flex:1;">
|
||||
<span style="color:var(--g-text-muted);">~</span>
|
||||
<input class="g-input" type="date" id="fsDateEnd" value="2026-03-31" style="flex:1;">
|
||||
</div>
|
||||
</div>
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label">每日时段</label>
|
||||
<div style="display:flex;gap:8px;align-items:center;">
|
||||
<input class="g-input" type="time" id="fsTimeStart" value="11:00" style="flex:1;">
|
||||
<span style="color:var(--g-text-muted);">~</span>
|
||||
<input class="g-input" type="time" id="fsTimeEnd" value="14:00" style="flex:1;">
|
||||
</div>
|
||||
<div class="g-hint">留空则全天有效</div>
|
||||
</div>
|
||||
<div class="g-form-group fs-cycle-section" id="fsCycleSection">
|
||||
<label class="g-form-label required">循环日期</label>
|
||||
<div class="fs-day-sel" id="fsDaySel">
|
||||
<span class="fs-day" onclick="toggleFsDay(this)">周一</span>
|
||||
<span class="fs-day" onclick="toggleFsDay(this)">周二</span>
|
||||
<span class="fs-day" onclick="toggleFsDay(this)">周三</span>
|
||||
<span class="fs-day active" onclick="toggleFsDay(this)">周四</span>
|
||||
<span class="fs-day" onclick="toggleFsDay(this)">周五</span>
|
||||
<span class="fs-day" onclick="toggleFsDay(this)">周六</span>
|
||||
<span class="fs-day" onclick="toggleFsDay(this)">周日</span>
|
||||
</div>
|
||||
<div class="fs-day-quick">
|
||||
<button class="g-btn g-btn-sm" onclick="fsDayQuick('weekday')">工作日</button>
|
||||
<button class="g-btn g-btn-sm" onclick="fsDayQuick('weekend')">周末</button>
|
||||
<button class="g-btn g-btn-sm" onclick="fsDayQuick('all')">全选</button>
|
||||
</div>
|
||||
<div class="g-hint" style="margin-top:8px;">活动将在选中的每个星期自动生效,无需手动开启</div>
|
||||
</div>
|
||||
|
||||
<!-- 折扣商品 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required" style="margin-bottom:10px;">折扣商品</label>
|
||||
<div id="fsProductList">
|
||||
<!-- 预填商品 1 -->
|
||||
<div class="fs-drawer-prod">
|
||||
<div class="fs-drawer-prod-hd">
|
||||
<span>香辣鸡腿堡套餐</span>
|
||||
<button class="fs-drawer-prod-remove" onclick="removeFsProduct(this)"><i data-lucide="x" style="width:14px;height:14px;"></i></button>
|
||||
</div>
|
||||
<div class="fs-drawer-prod-bd">
|
||||
<div class="fs-field">
|
||||
<label>原价</label>
|
||||
<input type="text" value="¥32.00" readonly>
|
||||
</div>
|
||||
<div class="fs-field">
|
||||
<label>折扣价</label>
|
||||
<input type="number" value="25.60" step="0.01" placeholder="请输入折扣价" oninput="calcFsRate(this)">
|
||||
</div>
|
||||
<div class="fs-field">
|
||||
<label>折扣</label>
|
||||
<span class="fs-auto-rate">8折</span>
|
||||
</div>
|
||||
<div class="fs-field">
|
||||
<label>限购/人</label>
|
||||
<input type="number" value="2" min="0" placeholder="不限则留空">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 预填商品 2 -->
|
||||
<div class="fs-drawer-prod">
|
||||
<div class="fs-drawer-prod-hd">
|
||||
<span>牛肉拌面</span>
|
||||
<button class="fs-drawer-prod-remove" onclick="removeFsProduct(this)"><i data-lucide="x" style="width:14px;height:14px;"></i></button>
|
||||
</div>
|
||||
<div class="fs-drawer-prod-bd">
|
||||
<div class="fs-field">
|
||||
<label>原价</label>
|
||||
<input type="text" value="¥28.00" readonly>
|
||||
</div>
|
||||
<div class="fs-field">
|
||||
<label>折扣价</label>
|
||||
<input type="number" value="19.60" step="0.01" placeholder="请输入折扣价" oninput="calcFsRate(this)">
|
||||
</div>
|
||||
<div class="fs-field">
|
||||
<label>折扣</label>
|
||||
<span class="fs-auto-rate">7折</span>
|
||||
</div>
|
||||
<div class="fs-field">
|
||||
<label>限购/人</label>
|
||||
<input type="number" value="1" min="0" placeholder="不限则留空">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 预填商品 3 -->
|
||||
<div class="fs-drawer-prod">
|
||||
<div class="fs-drawer-prod-hd">
|
||||
<span>招牌卤肉饭</span>
|
||||
<button class="fs-drawer-prod-remove" onclick="removeFsProduct(this)"><i data-lucide="x" style="width:14px;height:14px;"></i></button>
|
||||
</div>
|
||||
<div class="fs-drawer-prod-bd">
|
||||
<div class="fs-field">
|
||||
<label>原价</label>
|
||||
<input type="text" value="¥22.00" readonly>
|
||||
</div>
|
||||
<div class="fs-field">
|
||||
<label>折扣价</label>
|
||||
<input type="number" value="17.60" step="0.01" placeholder="请输入折扣价" oninput="calcFsRate(this)">
|
||||
</div>
|
||||
<div class="fs-field">
|
||||
<label>折扣</label>
|
||||
<span class="fs-auto-rate">8折</span>
|
||||
</div>
|
||||
<div class="fs-field">
|
||||
<label>限购/人</label>
|
||||
<input type="number" value="2" min="0" placeholder="不限则留空">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="g-btn g-btn-sm" style="margin-top:4px;" onclick="openProductPicker({title:'添加折扣商品',subtitle:'限时折扣',onConfirm:addFsProducts})"><i data-lucide="plus" style="width:13px;height:13px;"></i>添加商品</button>
|
||||
</div>
|
||||
|
||||
<!-- 适用渠道 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label">适用渠道</label>
|
||||
<div class="fs-pill-group">
|
||||
<span class="fs-pill checked" onclick="toggleFsPill(this)">外卖配送</span>
|
||||
<span class="fs-pill checked" onclick="toggleFsPill(this)">到店自取</span>
|
||||
<span class="fs-pill" onclick="toggleFsPill(this)">堂食点餐</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 限购设置 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label">每人限购</label>
|
||||
<div class="fs-limit-row">
|
||||
<input class="g-input" type="number" value="5" min="0" placeholder="不限则留空" style="width:100px;">
|
||||
<span class="fs-unit">件</span>
|
||||
</div>
|
||||
<div class="g-hint">活动期间每人累计可购买的折扣商品总数,留空不限</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="g-drawer-ft">
|
||||
<button class="g-btn" onclick="closeFsDrawer()">取消</button>
|
||||
<button class="g-btn g-btn-primary" onclick="closeFsDrawer()">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function openFsDrawer(mode, name) {
|
||||
document.getElementById('fsDrawerMask').classList.add('open');
|
||||
document.getElementById('fsDrawer').classList.add('open');
|
||||
if (mode === 'edit') {
|
||||
document.getElementById('fsDrawerTitle').textContent = '编辑限时折扣';
|
||||
document.getElementById('fsName').value = name || '';
|
||||
} else {
|
||||
document.getElementById('fsDrawerTitle').textContent = '创建限时折扣';
|
||||
document.getElementById('fsName').value = '';
|
||||
}
|
||||
if (typeof lucide !== 'undefined') lucide.createIcons();
|
||||
}
|
||||
|
||||
function closeFsDrawer() {
|
||||
document.getElementById('fsDrawerMask').classList.remove('open');
|
||||
document.getElementById('fsDrawer').classList.remove('open');
|
||||
}
|
||||
|
||||
function removeFsProduct(btn) {
|
||||
btn.closest('.fs-drawer-prod').remove();
|
||||
}
|
||||
|
||||
function toggleFsPill(el) {
|
||||
el.classList.toggle('checked');
|
||||
}
|
||||
|
||||
/* 自动计算折扣率 */
|
||||
function calcFsRate(input) {
|
||||
var row = input.closest('.fs-drawer-prod-bd');
|
||||
var origText = row.querySelector('input[readonly]').value.replace(/[¥,]/g, '');
|
||||
var orig = parseFloat(origText);
|
||||
var disc = parseFloat(input.value);
|
||||
var rateEl = row.querySelector('.fs-auto-rate');
|
||||
if (orig > 0 && disc > 0 && disc <= orig) {
|
||||
var r = Math.round((disc / orig) * 10);
|
||||
rateEl.textContent = r + '折';
|
||||
} else {
|
||||
rateEl.textContent = '-';
|
||||
}
|
||||
}
|
||||
|
||||
/* 活动周期切换 */
|
||||
function selectFsCycle(el, type) {
|
||||
el.parentElement.querySelectorAll('.fs-pill').forEach(function(p) { p.classList.remove('checked'); });
|
||||
el.classList.add('checked');
|
||||
var dateSection = document.getElementById('fsDateSection');
|
||||
var cycleSection = document.getElementById('fsCycleSection');
|
||||
if (type === 'recurring') {
|
||||
dateSection.classList.add('hide');
|
||||
cycleSection.classList.add('show');
|
||||
} else {
|
||||
dateSection.classList.remove('hide');
|
||||
cycleSection.classList.remove('show');
|
||||
}
|
||||
}
|
||||
|
||||
function toggleFsDay(el) {
|
||||
el.classList.toggle('active');
|
||||
}
|
||||
|
||||
function fsDayQuick(mode) {
|
||||
var days = document.querySelectorAll('#fsDaySel .fs-day');
|
||||
days.forEach(function(d, i) {
|
||||
if (mode === 'all') d.classList.add('active');
|
||||
else if (mode === 'weekday') d.classList.toggle('active', i < 5);
|
||||
else if (mode === 'weekend') d.classList.toggle('active', i >= 5);
|
||||
});
|
||||
}
|
||||
|
||||
/* 商品选择器回调 */
|
||||
function addFsProducts(items) {
|
||||
var list = document.getElementById('fsProductList');
|
||||
items.forEach(function(p) {
|
||||
var price = p.price || (Math.floor(Math.random() * 30 + 15) + '.00');
|
||||
var div = document.createElement('div');
|
||||
div.className = 'fs-drawer-prod';
|
||||
div.innerHTML =
|
||||
'<div class="fs-drawer-prod-hd"><span>' + p.name + '</span>' +
|
||||
'<button class="fs-drawer-prod-remove" onclick="removeFsProduct(this)"><i data-lucide="x" style="width:14px;height:14px;"></i></button></div>' +
|
||||
'<div class="fs-drawer-prod-bd">' +
|
||||
'<div class="fs-field"><label>原价</label><input type="text" value="¥' + price + '" readonly></div>' +
|
||||
'<div class="fs-field"><label>折扣价</label><input type="number" step="0.01" placeholder="请输入折扣价" oninput="calcFsRate(this)"></div>' +
|
||||
'<div class="fs-field"><label>折扣</label><span class="fs-auto-rate">-</span></div>' +
|
||||
'<div class="fs-field"><label>限购/人</label><input type="number" min="0" placeholder="不限则留空"></div>' +
|
||||
'</div>';
|
||||
list.appendChild(div);
|
||||
});
|
||||
if (typeof lucide !== 'undefined') lucide.createIcons();
|
||||
}
|
||||
</script>
|
||||
396
pages/mkt-new-customer.html
Normal file
396
pages/mkt-new-customer.html
Normal file
@@ -0,0 +1,396 @@
|
||||
<!-- 新客有礼页 -->
|
||||
<style>
|
||||
.page-nc { max-width:960px; }
|
||||
.nc-toolbar { display:flex; align-items:center; gap:12px; margin-bottom:16px; box-shadow:var(--g-shadow-sm); border-radius:10px; padding:10px 14px; background:#fff; }
|
||||
.nc-toolbar select { height:34px; padding:0 10px; border:1px solid #e5e7eb; border-radius:8px; font-size:13px; outline:none; background:#fff; transition:var(--g-transition); }
|
||||
.nc-toolbar select:focus { border-color:var(--primary); box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 12%, transparent); }
|
||||
.nc-banner { display:flex; align-items:center; gap:12px; padding:14px 18px; background:linear-gradient(135deg, color-mix(in srgb, var(--primary) 8%, #fff), color-mix(in srgb, var(--primary) 3%, #fff)); border:1px solid color-mix(in srgb, var(--primary) 15%, #fff); border-radius:10px; margin-bottom:16px; }
|
||||
.nc-banner-icon { width:40px; height:40px; border-radius:10px; background:color-mix(in srgb, var(--primary) 12%, #fff); display:flex; align-items:center; justify-content:center; color:var(--primary); flex-shrink:0; }
|
||||
.nc-banner-text { font-size:13px; color:var(--g-text-secondary); line-height:1.6; }
|
||||
.nc-banner-text strong { color:var(--g-text); font-weight:600; }
|
||||
.nc-stats { display:grid; grid-template-columns:repeat(3,1fr); gap:16px; margin-bottom:16px; }
|
||||
.nc-stat-card { background:#fff; border:1px solid var(--g-border); border-radius:10px; padding:18px 20px; transition:box-shadow var(--g-transition); }
|
||||
.nc-stat-card:hover { box-shadow:var(--g-shadow-md); }
|
||||
.nc-stat-label { font-size:12px; color:var(--g-text-muted); margin-bottom:8px; display:flex; align-items:center; gap:6px; }
|
||||
.nc-stat-val { font-size:28px; font-weight:700; color:var(--g-text); display:flex; align-items:baseline; gap:8px; }
|
||||
.nc-stat-unit { font-size:13px; font-weight:400; color:var(--g-text-muted); }
|
||||
.nc-stat-trend { font-size:12px; font-weight:500; display:inline-flex; align-items:center; gap:2px; }
|
||||
.nc-stat-trend.up { color:var(--g-success); }
|
||||
.nc-stat-sub { font-size:11px; color:var(--g-text-muted); margin-top:4px; }
|
||||
.nc-section-hd { font-size:15px; font-weight:600; color:var(--g-text); padding-left:10px; border-left:3px solid var(--primary); margin-bottom:16px; }
|
||||
.nc-row { display:flex; align-items:flex-start; gap:16px; padding:14px 0; border-bottom:1px solid #f3f4f6; }
|
||||
.nc-row:last-child { border-bottom:none; }
|
||||
.nc-row-label { width:120px; flex-shrink:0; font-size:13px; font-weight:500; color:var(--g-text); line-height:22px; padding-top:5px; }
|
||||
.nc-row-ctrl { flex:1; display:flex; flex-direction:column; gap:6px; }
|
||||
.nc-row-ctrl-inline { display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
|
||||
.nc-row-hint { font-size:11px; color:var(--g-text-muted); }
|
||||
.nc-coupon-list { display:flex; flex-direction:column; gap:10px; }
|
||||
.nc-coupon-item { display:flex; align-items:center; gap:12px; padding:12px 14px; background:#fff; border:1px solid var(--g-border); border-radius:8px; border-left:3px solid var(--primary); transition:box-shadow var(--g-transition); }
|
||||
.nc-coupon-item:nth-child(2) { border-left-color:var(--g-success); }
|
||||
.nc-coupon-item:nth-child(3) { border-left-color:var(--g-warning); }
|
||||
.nc-coupon-item:hover { box-shadow:var(--g-shadow); }
|
||||
.nc-coupon-info { flex:1; }
|
||||
.nc-coupon-name { font-size:14px; font-weight:600; color:var(--g-text); }
|
||||
.nc-coupon-desc { font-size:11px; color:var(--g-text-muted); margin-top:2px; }
|
||||
.nc-coupon-validity { font-size:12px; color:var(--g-text-secondary); display:flex; align-items:center; gap:4px; }
|
||||
.nc-add-coupon-btn { display:flex; align-items:center; justify-content:center; gap:6px; padding:12px; border:2px dashed #d9d9d9; border-radius:8px; color:var(--g-text-muted); font-size:13px; cursor:pointer; transition:all var(--g-transition); background:none; width:100%; }
|
||||
.nc-add-coupon-btn:hover { border-color:var(--primary); color:var(--primary); background:color-mix(in srgb, var(--primary) 3%, #fff); }
|
||||
.nc-direct-panel { display:flex; flex-direction:column; gap:12px; }
|
||||
.nc-share-url { display:flex; align-items:center; gap:8px; }
|
||||
.nc-share-url input { flex:1; }
|
||||
.nc-invite-table { margin-top:8px; }
|
||||
.nc-save-bar { margin-top:20px; display:flex; justify-content:flex-end; gap:8px; }
|
||||
.nc-num-input { width:100px; height:34px; padding:0 10px; border:1px solid #e5e7eb; border-radius:8px; font-size:13px; outline:none; transition:var(--g-transition); }
|
||||
.nc-num-input:focus { border-color:var(--primary); box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 12%, transparent); }
|
||||
.nc-suffix { font-size:13px; color:var(--g-text-secondary); white-space:nowrap; }
|
||||
</style>
|
||||
|
||||
<div class="page-nc">
|
||||
<!-- 顶部工具栏 -->
|
||||
<div class="nc-toolbar">
|
||||
<select style="width:200px;">
|
||||
<option>老三家外卖(朝阳店)</option>
|
||||
<option>老三家外卖(海淀店)</option>
|
||||
<option>老三家外卖(望京店)</option>
|
||||
<option>老三家外卖(通州店)</option>
|
||||
<option>老三家外卖(丰台店)</option>
|
||||
</select>
|
||||
<div style="flex:1;"></div>
|
||||
</div>
|
||||
|
||||
<!-- 说明横幅 -->
|
||||
<div class="nc-banner">
|
||||
<div class="nc-banner-icon"><i data-lucide="gift" style="width:20px;height:20px;"></i></div>
|
||||
<div class="nc-banner-text"><strong>新客有礼</strong> — 新用户首次下单自动发放优惠礼包,提升新客转化率。开启后,每位新注册用户将自动收到您配置的欢迎礼包。</div>
|
||||
</div>
|
||||
|
||||
<!-- 统计卡片 -->
|
||||
<div class="nc-stats">
|
||||
<div class="nc-stat-card">
|
||||
<div class="nc-stat-label"><i data-lucide="user-plus" style="width:14px;height:14px;color:var(--primary);"></i>本月新客</div>
|
||||
<div class="nc-stat-val">86<span class="nc-stat-unit">人</span><span class="nc-stat-trend up"><i data-lucide="trending-up" style="width:14px;height:14px;"></i>+23%</span></div>
|
||||
<div class="nc-stat-sub">较上月增长 16 人</div>
|
||||
</div>
|
||||
<div class="nc-stat-card">
|
||||
<div class="nc-stat-label"><i data-lucide="ticket" style="width:14px;height:14px;color:var(--g-warning);"></i>礼包领取率</div>
|
||||
<div class="nc-stat-val">92.4<span class="nc-stat-unit">%</span></div>
|
||||
<div class="nc-stat-sub">86 人中 80 人已领取</div>
|
||||
</div>
|
||||
<div class="nc-stat-card">
|
||||
<div class="nc-stat-label"><i data-lucide="shopping-bag" style="width:14px;height:14px;color:var(--g-success);"></i>新客转化率</div>
|
||||
<div class="nc-stat-val">68.5<span class="nc-stat-unit">%</span></div>
|
||||
<div class="nc-stat-sub">首单完成率,59 人已下单</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 新客礼包配置 -->
|
||||
<div class="g-card" style="padding:0; margin-bottom:16px;">
|
||||
<div style="padding:18px 18px 0;">
|
||||
<div class="nc-section-hd">新客礼包配置</div>
|
||||
</div>
|
||||
<div style="padding:0 18px 18px;">
|
||||
<!-- 启用状态 -->
|
||||
<div class="nc-row">
|
||||
<div class="nc-row-label">启用状态</div>
|
||||
<div class="nc-row-ctrl">
|
||||
<div class="nc-row-ctrl-inline">
|
||||
<div class="g-toggle on" onclick="toggleSwitch(this)"></div>
|
||||
<span class="g-toggle-label">开启后新用户注册即发放礼包</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 礼包类型 -->
|
||||
<div class="nc-row">
|
||||
<div class="nc-row-label">礼包类型</div>
|
||||
<div class="nc-row-ctrl">
|
||||
<div class="nc-row-ctrl-inline">
|
||||
<span class="g-pill checked" onclick="selectNcType('coupon',this)">优惠券包</span>
|
||||
<span class="g-pill" onclick="selectNcType('direct',this)">首单直减</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 优惠券包内容 -->
|
||||
<div id="ncTypeCoupon">
|
||||
<div class="nc-row" style="flex-direction:column; gap:12px;">
|
||||
<div class="nc-row-label" style="width:auto;">券包内容</div>
|
||||
<div class="nc-coupon-list" id="ncCouponList">
|
||||
<div class="nc-coupon-item" data-idx="0">
|
||||
<div class="nc-coupon-info">
|
||||
<div class="nc-coupon-name">满30减5</div>
|
||||
<div class="nc-coupon-desc">订单满 30 元可用</div>
|
||||
</div>
|
||||
<div class="nc-coupon-validity"><i data-lucide="clock" style="width:12px;height:12px;"></i>领取后7天</div>
|
||||
<button class="g-btn g-btn-sm g-btn-danger" onclick="removeNcCoupon(this)"><i data-lucide="trash-2" style="width:12px;height:12px;"></i></button>
|
||||
</div>
|
||||
<div class="nc-coupon-item" data-idx="1">
|
||||
<div class="nc-coupon-info">
|
||||
<div class="nc-coupon-name">满50享8折</div>
|
||||
<div class="nc-coupon-desc">订单满 50 元可用</div>
|
||||
</div>
|
||||
<div class="nc-coupon-validity"><i data-lucide="clock" style="width:12px;height:12px;"></i>领取后7天</div>
|
||||
<button class="g-btn g-btn-sm g-btn-danger" onclick="removeNcCoupon(this)"><i data-lucide="trash-2" style="width:12px;height:12px;"></i></button>
|
||||
</div>
|
||||
<div class="nc-coupon-item" data-idx="2">
|
||||
<div class="nc-coupon-info">
|
||||
<div class="nc-coupon-name">免配送费</div>
|
||||
<div class="nc-coupon-desc">无门槛,减免配送费</div>
|
||||
</div>
|
||||
<div class="nc-coupon-validity"><i data-lucide="clock" style="width:12px;height:12px;"></i>领取后7天</div>
|
||||
<button class="g-btn g-btn-sm g-btn-danger" onclick="removeNcCoupon(this)"><i data-lucide="trash-2" style="width:12px;height:12px;"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<button class="nc-add-coupon-btn" onclick="openNcDrawer()"><i data-lucide="plus" style="width:14px;height:14px;"></i>添加优惠券</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 首单直减 -->
|
||||
<div id="ncTypeDirect" style="display:none;">
|
||||
<div class="nc-row">
|
||||
<div class="nc-row-label">直减金额</div>
|
||||
<div class="nc-row-ctrl">
|
||||
<div class="nc-row-ctrl-inline">
|
||||
<span class="nc-suffix">¥</span>
|
||||
<input type="number" class="nc-num-input" placeholder="如:10" value="10" />
|
||||
</div>
|
||||
<div class="nc-row-hint">新用户首单自动减免的金额</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="nc-row">
|
||||
<div class="nc-row-label">使用门槛</div>
|
||||
<div class="nc-row-ctrl">
|
||||
<div class="nc-row-ctrl-inline">
|
||||
<span class="nc-suffix">订单满</span>
|
||||
<input type="number" class="nc-num-input" placeholder="如:30" value="30" />
|
||||
<span class="nc-suffix">元可用</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 老带新分享 -->
|
||||
<div class="g-card" style="padding:0; margin-bottom:16px;">
|
||||
<div style="padding:18px 18px 0;">
|
||||
<div class="nc-section-hd">老带新分享</div>
|
||||
</div>
|
||||
<div style="padding:0 18px 18px;">
|
||||
<div class="nc-row">
|
||||
<div class="nc-row-label">启用状态</div>
|
||||
<div class="nc-row-ctrl">
|
||||
<div class="nc-row-ctrl-inline">
|
||||
<div class="g-toggle on" onclick="toggleSwitch(this)"></div>
|
||||
<span class="g-toggle-label">开启后顾客可在小程序内分享邀请好友</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="nc-row" style="flex-direction:column; gap:12px;">
|
||||
<div class="nc-row-label" style="width:auto;">邀请人奖励 <span style="font-weight:400;color:var(--g-text-muted);font-size:12px;">成功邀请新用户下单后发放</span></div>
|
||||
<div class="nc-coupon-list" id="ncInviterList">
|
||||
<div class="nc-coupon-item">
|
||||
<div class="nc-coupon-info">
|
||||
<div class="nc-coupon-name">满30减5</div>
|
||||
<div class="nc-coupon-desc">订单满 30 元可用</div>
|
||||
</div>
|
||||
<div class="nc-coupon-validity"><i data-lucide="clock" style="width:12px;height:12px;"></i>领取后7天</div>
|
||||
<button class="g-btn g-btn-sm g-btn-danger" onclick="removeNcCoupon(this)"><i data-lucide="trash-2" style="width:12px;height:12px;"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<button class="nc-add-coupon-btn" onclick="openNcDrawer('inviter')"><i data-lucide="plus" style="width:14px;height:14px;"></i>添加奖励券</button>
|
||||
</div>
|
||||
<div class="nc-row" style="flex-direction:column; gap:12px;">
|
||||
<div class="nc-row-label" style="width:auto;">被邀请人奖励 <span style="font-weight:400;color:var(--g-text-muted);font-size:12px;">新用户通过邀请注册后额外获得,叠加新客礼包</span></div>
|
||||
<div class="nc-coupon-list" id="ncInviteeList">
|
||||
<div class="nc-coupon-item">
|
||||
<div class="nc-coupon-info">
|
||||
<div class="nc-coupon-name">满20减3</div>
|
||||
<div class="nc-coupon-desc">订单满 20 元可用</div>
|
||||
</div>
|
||||
<div class="nc-coupon-validity"><i data-lucide="clock" style="width:12px;height:12px;"></i>领取后7天</div>
|
||||
<button class="g-btn g-btn-sm g-btn-danger" onclick="removeNcCoupon(this)"><i data-lucide="trash-2" style="width:12px;height:12px;"></i></button>
|
||||
</div>
|
||||
<div class="nc-coupon-item">
|
||||
<div class="nc-coupon-info">
|
||||
<div class="nc-coupon-name">免配送费</div>
|
||||
<div class="nc-coupon-desc">无门槛,减免配送费</div>
|
||||
</div>
|
||||
<div class="nc-coupon-validity"><i data-lucide="clock" style="width:12px;height:12px;"></i>领取后7天</div>
|
||||
<button class="g-btn g-btn-sm g-btn-danger" onclick="removeNcCoupon(this)"><i data-lucide="trash-2" style="width:12px;height:12px;"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<button class="nc-add-coupon-btn" onclick="openNcDrawer('invitee')"><i data-lucide="plus" style="width:14px;height:14px;"></i>添加奖励券</button>
|
||||
</div>
|
||||
<div class="nc-row">
|
||||
<div class="nc-row-label">分享渠道</div>
|
||||
<div class="nc-row-ctrl">
|
||||
<div style="display:flex;gap:8px;">
|
||||
<span class="g-pill checked" onclick="this.classList.toggle('checked')">微信好友</span>
|
||||
<span class="g-pill checked" onclick="this.classList.toggle('checked')">朋友圈</span>
|
||||
<span class="g-pill" onclick="this.classList.toggle('checked')">短信</span>
|
||||
</div>
|
||||
<div class="nc-row-hint">顾客在小程序内可通过以上渠道分享邀请</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="nc-row" style="flex-direction:column; gap:12px;">
|
||||
<div class="nc-row-label" style="width:auto;">邀请记录(近期)</div>
|
||||
<div class="nc-invite-table" style="width:100%;">
|
||||
<table class="g-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>邀请人</th>
|
||||
<th>被邀请人</th>
|
||||
<th>邀请时间</th>
|
||||
<th>状态</th>
|
||||
<th>奖励发放</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>张**</td>
|
||||
<td>李**</td>
|
||||
<td>2025-02-10 14:32</td>
|
||||
<td><span class="g-tag g-tag-green">已下单</span></td>
|
||||
<td><span class="g-tag g-tag-green">已发放</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>王**</td>
|
||||
<td>赵**</td>
|
||||
<td>2025-02-09 09:15</td>
|
||||
<td><span class="g-tag g-tag-orange">待下单</span></td>
|
||||
<td><span class="g-tag g-tag-gray">待触发</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>张**</td>
|
||||
<td>孙**</td>
|
||||
<td>2025-02-08 18:47</td>
|
||||
<td><span class="g-tag g-tag-green">已下单</span></td>
|
||||
<td><span class="g-tag g-tag-green">已发放</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部保存 -->
|
||||
<div class="g-card" style="padding:14px 18px;">
|
||||
<div style="display:flex; justify-content:flex-end; gap:8px;">
|
||||
<button class="g-btn"><i data-lucide="rotate-ccw" style="width:14px;height:14px;"></i>重置</button>
|
||||
<button class="g-btn g-btn-primary"><i data-lucide="save" style="width:14px;height:14px;"></i>保存设置</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 添加优惠券抽屉 -->
|
||||
<div class="g-drawer-mask" id="ncDrawerMask" onclick="closeNcDrawer()"></div>
|
||||
<div class="g-drawer" id="ncDrawer" style="width:480px;">
|
||||
<div class="g-drawer-hd">
|
||||
<span class="g-drawer-title">添加优惠券</span>
|
||||
<button class="g-drawer-close" onclick="closeNcDrawer()"><i data-lucide="x" style="width:18px;height:18px;"></i></button>
|
||||
</div>
|
||||
<div class="g-drawer-bd">
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required">券类型</label>
|
||||
<div style="display:flex; gap:8px;">
|
||||
<span class="g-pill checked" onclick="selectNcCouponType('reduce',this)">满减券</span>
|
||||
<span class="g-pill" onclick="selectNcCouponType('discount',this)">折扣券</span>
|
||||
<span class="g-pill" onclick="selectNcCouponType('shipping',this)">免配送费</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 满减券面额 -->
|
||||
<div id="ncCouponReduce">
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required">减免金额</label>
|
||||
<div style="display:flex; align-items:center; gap:8px;">
|
||||
<span style="font-size:13px; color:var(--g-text-secondary);">¥</span>
|
||||
<input class="g-input" type="number" placeholder="如:5" style="width:120px;" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 折扣券面额 -->
|
||||
<div id="ncCouponDiscount" style="display:none;">
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required">折扣</label>
|
||||
<div style="display:flex; align-items:center; gap:8px;">
|
||||
<input class="g-input" type="number" placeholder="如:8(即8折)" style="width:160px;" />
|
||||
<span style="font-size:13px; color:var(--g-text-secondary);">折</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 免配送费无额外字段 -->
|
||||
<div id="ncCouponShipping" style="display:none;">
|
||||
<div class="g-form-group">
|
||||
<div style="padding:16px; background:#f8f9fb; border-radius:8px; font-size:13px; color:var(--g-text-secondary); text-align:center;">
|
||||
<i data-lucide="truck" style="width:20px;height:20px;color:var(--g-text-muted);display:block;margin:0 auto 6px;"></i>
|
||||
免配送费券无需设置面额
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label">使用门槛</label>
|
||||
<div style="display:flex; align-items:center; gap:8px;">
|
||||
<span style="font-size:13px; color:var(--g-text-secondary);">订单满</span>
|
||||
<input class="g-input" type="number" placeholder="如:30" style="width:120px;" />
|
||||
<span style="font-size:13px; color:var(--g-text-secondary);">元可用</span>
|
||||
</div>
|
||||
<div class="g-hint">留空或填 0 表示无门槛</div>
|
||||
</div>
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required">有效期</label>
|
||||
<div style="display:flex; align-items:center; gap:8px;">
|
||||
<span style="font-size:13px; color:var(--g-text-secondary);">领取后</span>
|
||||
<input class="g-input" type="number" placeholder="如:7" style="width:100px;" value="7" />
|
||||
<span style="font-size:13px; color:var(--g-text-secondary);">天</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="g-drawer-ft">
|
||||
<button class="g-btn" onclick="closeNcDrawer()">取消</button>
|
||||
<button class="g-btn g-btn-primary" onclick="closeNcDrawer()">添加</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function toggleSwitch(el) {
|
||||
el.classList.toggle('on');
|
||||
}
|
||||
|
||||
function selectNcType(type, el) {
|
||||
el.parentElement.querySelectorAll('.g-pill').forEach(function(p) { p.classList.remove('checked'); });
|
||||
el.classList.add('checked');
|
||||
document.getElementById('ncTypeCoupon').style.display = type === 'coupon' ? '' : 'none';
|
||||
document.getElementById('ncTypeDirect').style.display = type === 'direct' ? '' : 'none';
|
||||
}
|
||||
|
||||
function openNcDrawer() {
|
||||
document.getElementById('ncDrawerMask').classList.add('open');
|
||||
document.getElementById('ncDrawer').classList.add('open');
|
||||
if (typeof lucide !== 'undefined') lucide.createIcons();
|
||||
}
|
||||
|
||||
function closeNcDrawer() {
|
||||
document.getElementById('ncDrawerMask').classList.remove('open');
|
||||
document.getElementById('ncDrawer').classList.remove('open');
|
||||
}
|
||||
|
||||
function removeNcCoupon(btn) {
|
||||
var item = btn.closest('.nc-coupon-item');
|
||||
if (item) { item.style.transition = 'opacity 200ms, transform 200ms'; item.style.opacity = '0'; item.style.transform = 'translateX(20px)'; setTimeout(function() { item.remove(); }, 200); }
|
||||
}
|
||||
|
||||
function selectNcCouponType(type, el) {
|
||||
el.parentElement.querySelectorAll('.g-pill').forEach(function(p) { p.classList.remove('checked'); });
|
||||
el.classList.add('checked');
|
||||
document.getElementById('ncCouponReduce').style.display = type === 'reduce' ? '' : 'none';
|
||||
document.getElementById('ncCouponDiscount').style.display = type === 'discount' ? '' : 'none';
|
||||
document.getElementById('ncCouponShipping').style.display = type === 'shipping' ? '' : 'none';
|
||||
}
|
||||
|
||||
function copyNcLink() {
|
||||
var input = document.querySelector('.nc-share-url input');
|
||||
input.select();
|
||||
document.execCommand('copy');
|
||||
}
|
||||
|
||||
if (typeof lucide !== 'undefined') { lucide.createIcons(); }
|
||||
</script>
|
||||
422
pages/mkt-reduction.html
Normal file
422
pages/mkt-reduction.html
Normal file
@@ -0,0 +1,422 @@
|
||||
<!-- 满减活动页 -->
|
||||
<style>
|
||||
.fr-toolbar { display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin-bottom:16px; box-shadow:var(--g-shadow-sm); border-radius:10px; padding:10px 14px; background:#fff; }
|
||||
.fr-toolbar select,
|
||||
.fr-toolbar input[type="text"] {
|
||||
height:34px; padding:0 10px; border:1px solid #e5e7eb; border-radius:8px;
|
||||
font-size:13px; outline:none; transition:var(--g-transition); background:#fff;
|
||||
}
|
||||
.fr-toolbar select:focus,
|
||||
.fr-toolbar input[type="text"]:focus { border-color:var(--primary); box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 12%, transparent); }
|
||||
|
||||
/* 统计卡片 */
|
||||
.fr-stats { display:grid; grid-template-columns:repeat(4,1fr); gap:12px; margin-bottom:16px; }
|
||||
.fr-stat-card {
|
||||
background:#fff; border-radius:10px; padding:16px 20px;
|
||||
box-shadow:var(--g-shadow-sm); transition:var(--g-transition);
|
||||
}
|
||||
.fr-stat-card:hover { box-shadow:var(--g-shadow-md); transform:translateY(-1px); }
|
||||
.fr-stat-card .fr-stat-label { font-size:13px; color:#9ca3af; margin-bottom:6px; }
|
||||
.fr-stat-card .fr-stat-value { font-size:24px; font-weight:700; color:#1a1a2e; }
|
||||
.fr-stat-card .fr-stat-value.green { color:var(--g-success); }
|
||||
.fr-stat-card .fr-stat-value.orange { color:var(--g-warning); }
|
||||
|
||||
/* 活动卡片列表 */
|
||||
.fr-list { display:flex; flex-direction:column; gap:12px; margin-bottom:16px; }
|
||||
.fr-card {
|
||||
background:#fff; border-radius:10px; padding:20px 24px;
|
||||
box-shadow:var(--g-shadow-sm); transition:var(--g-transition);
|
||||
}
|
||||
.fr-card:hover { box-shadow:var(--g-shadow-md); }
|
||||
.fr-card.fr-ended { opacity:0.55; }
|
||||
|
||||
.fr-card-hd { display:flex; align-items:center; gap:10px; margin-bottom:14px; }
|
||||
.fr-card-name { font-size:15px; font-weight:600; color:var(--g-text); }
|
||||
.fr-card-hd .g-tag { flex-shrink:0; }
|
||||
|
||||
/* 阶梯规则可视化 */
|
||||
.fr-tiers { display:flex; align-items:center; gap:0; margin-bottom:14px; flex-wrap:wrap; }
|
||||
.fr-tier-pill {
|
||||
display:inline-flex; align-items:center; padding:6px 14px; border-radius:999px;
|
||||
background:color-mix(in srgb, var(--primary) 8%, #fff);
|
||||
border:1px solid color-mix(in srgb, var(--primary) 20%, transparent);
|
||||
font-size:13px; font-weight:500; color:var(--primary); white-space:nowrap;
|
||||
}
|
||||
.fr-tier-arrow {
|
||||
display:inline-flex; align-items:center; padding:0 6px; color:#c0c6cf;
|
||||
}
|
||||
|
||||
/* 活动信息行 */
|
||||
.fr-meta { display:flex; flex-wrap:wrap; gap:8px 24px; font-size:13px; color:var(--g-text-secondary); margin-bottom:12px; }
|
||||
.fr-meta-item { display:flex; align-items:center; gap:5px; }
|
||||
.fr-meta-item i { width:14px; height:14px; color:#9ca3af; }
|
||||
|
||||
/* 活动数据行 */
|
||||
.fr-data { display:flex; gap:24px; font-size:13px; color:var(--g-text-secondary); margin-bottom:14px; padding:10px 14px; background:#f8f9fb; border-radius:8px; }
|
||||
.fr-data-item span { font-weight:600; color:var(--g-text); }
|
||||
|
||||
/* 操作行 */
|
||||
.fr-card-ft { display:flex; align-items:center; gap:6px; border-top:1px solid #f3f4f6; padding-top:12px; }
|
||||
|
||||
/* 分页 */
|
||||
.fr-pagination {
|
||||
display:flex; align-items:center; justify-content:flex-end;
|
||||
padding:12px 16px; gap:6px; font-size:13px; color:#4b5563;
|
||||
background:#fff; border-radius:10px; box-shadow:var(--g-shadow-sm);
|
||||
}
|
||||
.fr-page-btn {
|
||||
min-width:34px; height:34px; border:1px solid #e5e7eb; border-radius:8px;
|
||||
background:#fff; cursor:pointer; display:flex; align-items:center;
|
||||
justify-content:center; font-size:13px; transition:var(--g-transition);
|
||||
}
|
||||
.fr-page-btn:hover { border-color:var(--primary); color:var(--primary); }
|
||||
.fr-page-btn.active { background:var(--primary); color:#fff; border-color:var(--primary); box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 12%, transparent); }
|
||||
|
||||
/* 抽屉内:阶梯规则行 */
|
||||
.fr-tier-row { display:flex; align-items:center; gap:8px; margin-bottom:10px; font-size:13px; color:var(--g-text); }
|
||||
.fr-tier-row input[type="number"] {
|
||||
width:80px; height:34px; padding:0 10px; border:1px solid #e5e7eb; border-radius:8px;
|
||||
font-size:13px; outline:none; transition:var(--g-transition); text-align:center;
|
||||
}
|
||||
.fr-tier-row input[type="number"]:focus { border-color:var(--primary); box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 12%, transparent); }
|
||||
.fr-tier-del {
|
||||
width:30px; height:30px; border:none; background:none; cursor:pointer;
|
||||
display:flex; align-items:center; justify-content:center; border-radius:6px;
|
||||
color:#999; transition:var(--g-transition);
|
||||
}
|
||||
.fr-tier-del:hover { background:#fef2f2; color:var(--g-danger); }
|
||||
.fr-add-tier {
|
||||
display:inline-flex; align-items:center; gap:4px; padding:6px 14px;
|
||||
border:1px dashed #d0d5dd; border-radius:8px; background:none;
|
||||
font-size:13px; color:var(--g-text-secondary); cursor:pointer;
|
||||
transition:var(--g-transition);
|
||||
}
|
||||
.fr-add-tier:hover { border-color:var(--primary); color:var(--primary); background:color-mix(in srgb, var(--primary) 4%, #fff); }
|
||||
|
||||
.fr-section-hd {
|
||||
font-size:15px; font-weight:600; color:var(--g-text);
|
||||
padding-left:10px; border-left:3px solid var(--primary); margin-bottom:16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="page-fr">
|
||||
<!-- 工具栏 -->
|
||||
<div class="fr-toolbar">
|
||||
<select style="width:200px;">
|
||||
<option value="">全部门店</option>
|
||||
<option>老三家外卖(朝阳店)</option>
|
||||
<option>老三家外卖(海淀店)</option>
|
||||
<option>老三家外卖(望京店)</option>
|
||||
<option>老三家外卖(通州店)</option>
|
||||
<option>老三家外卖(丰台店)</option>
|
||||
</select>
|
||||
<select style="width:130px;">
|
||||
<option value="">全部状态</option>
|
||||
<option>进行中</option>
|
||||
<option>未开始</option>
|
||||
<option>已结束</option>
|
||||
</select>
|
||||
<input type="text" placeholder="搜索活动名称" style="width:200px;" />
|
||||
<div style="flex:1;"></div>
|
||||
<button class="g-btn g-btn-primary" onclick="openFrDrawer('create')">
|
||||
<i data-lucide="plus" style="width:14px;height:14px;"></i>创建满减活动
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 统计卡片 -->
|
||||
<div class="fr-stats">
|
||||
<div class="fr-stat-card">
|
||||
<div class="fr-stat-label">活动总数</div>
|
||||
<div class="fr-stat-value">8</div>
|
||||
</div>
|
||||
<div class="fr-stat-card">
|
||||
<div class="fr-stat-label">进行中</div>
|
||||
<div class="fr-stat-value green">3</div>
|
||||
</div>
|
||||
<div class="fr-stat-card">
|
||||
<div class="fr-stat-label">本月带动销售额</div>
|
||||
<div class="fr-stat-value orange">¥12,680</div>
|
||||
</div>
|
||||
<div class="fr-stat-card">
|
||||
<div class="fr-stat-label">平均客单价提升</div>
|
||||
<div class="fr-stat-value">¥8.5</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 活动卡片列表 -->
|
||||
<div class="fr-list">
|
||||
|
||||
<!-- 活动1:进行中 -->
|
||||
<div class="fr-card">
|
||||
<div class="fr-card-hd">
|
||||
<span class="fr-card-name">午市满减优惠</span>
|
||||
<span class="g-tag g-tag-green">进行中</span>
|
||||
</div>
|
||||
<div class="fr-tiers">
|
||||
<span class="fr-tier-pill">满30减5</span>
|
||||
<span class="fr-tier-arrow"><i data-lucide="chevron-right" style="width:16px;height:16px;"></i></span>
|
||||
<span class="fr-tier-pill">满50减10</span>
|
||||
<span class="fr-tier-arrow"><i data-lucide="chevron-right" style="width:16px;height:16px;"></i></span>
|
||||
<span class="fr-tier-pill">满80减20</span>
|
||||
</div>
|
||||
<div class="fr-meta">
|
||||
<span class="fr-meta-item"><i data-lucide="calendar" style="width:14px;height:14px;"></i>2026-01-01 ~ 2026-03-31</span>
|
||||
<span class="fr-meta-item"><i data-lucide="truck" style="width:14px;height:14px;"></i>外卖 / 自提</span>
|
||||
<span class="fr-meta-item"><i data-lucide="store" style="width:14px;height:14px;"></i>全部门店</span>
|
||||
</div>
|
||||
<div class="fr-data">
|
||||
<span class="fr-data-item">参与订单 <span>286单</span></span>
|
||||
<span class="fr-data-item">优惠总额 <span>¥2,860</span></span>
|
||||
<span class="fr-data-item">客单价提升 <span>¥8.2</span></span>
|
||||
</div>
|
||||
<div class="fr-card-ft">
|
||||
<a class="g-action" onclick="openFrDrawer('edit')">编辑</a>
|
||||
<a class="g-action">停用</a>
|
||||
<a class="g-action g-action-danger">删除</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 活动2:进行中 -->
|
||||
<div class="fr-card">
|
||||
<div class="fr-card-hd">
|
||||
<span class="fr-card-name">晚市大额满减</span>
|
||||
<span class="g-tag g-tag-green">进行中</span>
|
||||
</div>
|
||||
<div class="fr-tiers">
|
||||
<span class="fr-tier-pill">满50减8</span>
|
||||
<span class="fr-tier-arrow"><i data-lucide="chevron-right" style="width:16px;height:16px;"></i></span>
|
||||
<span class="fr-tier-pill">满80减15</span>
|
||||
<span class="fr-tier-arrow"><i data-lucide="chevron-right" style="width:16px;height:16px;"></i></span>
|
||||
<span class="fr-tier-pill">满120减30</span>
|
||||
</div>
|
||||
<div class="fr-meta">
|
||||
<span class="fr-meta-item"><i data-lucide="calendar" style="width:14px;height:14px;"></i>2026-01-15 ~ 2026-04-15</span>
|
||||
<span class="fr-meta-item"><i data-lucide="truck" style="width:14px;height:14px;"></i>外卖</span>
|
||||
<span class="fr-meta-item"><i data-lucide="store" style="width:14px;height:14px;"></i>朝阳店 / 海淀店</span>
|
||||
</div>
|
||||
<div class="fr-data">
|
||||
<span class="fr-data-item">参与订单 <span>152单</span></span>
|
||||
<span class="fr-data-item">优惠总额 <span>¥1,920</span></span>
|
||||
<span class="fr-data-item">客单价提升 <span>¥10.5</span></span>
|
||||
</div>
|
||||
<div class="fr-card-ft">
|
||||
<a class="g-action" onclick="openFrDrawer('edit')">编辑</a>
|
||||
<a class="g-action">停用</a>
|
||||
<a class="g-action g-action-danger">删除</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 活动3:未开始 -->
|
||||
<div class="fr-card">
|
||||
<div class="fr-card-hd">
|
||||
<span class="fr-card-name">春季新客满减</span>
|
||||
<span class="g-tag g-tag-blue">未开始</span>
|
||||
</div>
|
||||
<div class="fr-tiers">
|
||||
<span class="fr-tier-pill">满25减3</span>
|
||||
<span class="fr-tier-arrow"><i data-lucide="chevron-right" style="width:16px;height:16px;"></i></span>
|
||||
<span class="fr-tier-pill">满45减8</span>
|
||||
<span class="fr-tier-arrow"><i data-lucide="chevron-right" style="width:16px;height:16px;"></i></span>
|
||||
<span class="fr-tier-pill">满70减15</span>
|
||||
</div>
|
||||
<div class="fr-meta">
|
||||
<span class="fr-meta-item"><i data-lucide="calendar" style="width:14px;height:14px;"></i>2026-03-01 ~ 2026-05-31</span>
|
||||
<span class="fr-meta-item"><i data-lucide="truck" style="width:14px;height:14px;"></i>外卖 / 自提 / 堂食</span>
|
||||
<span class="fr-meta-item"><i data-lucide="store" style="width:14px;height:14px;"></i>全部门店</span>
|
||||
</div>
|
||||
<div class="fr-data">
|
||||
<span class="fr-data-item">参与订单 <span>0单</span></span>
|
||||
<span class="fr-data-item">优惠总额 <span>¥0</span></span>
|
||||
<span class="fr-data-item">客单价提升 <span>--</span></span>
|
||||
</div>
|
||||
<div class="fr-card-ft">
|
||||
<a class="g-action" onclick="openFrDrawer('edit')">编辑</a>
|
||||
<a class="g-action">停用</a>
|
||||
<a class="g-action g-action-danger">删除</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 活动4:已结束(弱化) -->
|
||||
<div class="fr-card fr-ended">
|
||||
<div class="fr-card-hd">
|
||||
<span class="fr-card-name">元旦满减狂欢</span>
|
||||
<span class="g-tag g-tag-gray">已结束</span>
|
||||
</div>
|
||||
<div class="fr-tiers">
|
||||
<span class="fr-tier-pill">满20减3</span>
|
||||
<span class="fr-tier-arrow"><i data-lucide="chevron-right" style="width:16px;height:16px;"></i></span>
|
||||
<span class="fr-tier-pill">满40减8</span>
|
||||
<span class="fr-tier-arrow"><i data-lucide="chevron-right" style="width:16px;height:16px;"></i></span>
|
||||
<span class="fr-tier-pill">满60减15</span>
|
||||
</div>
|
||||
<div class="fr-meta">
|
||||
<span class="fr-meta-item"><i data-lucide="calendar" style="width:14px;height:14px;"></i>2025-12-25 ~ 2026-01-05</span>
|
||||
<span class="fr-meta-item"><i data-lucide="truck" style="width:14px;height:14px;"></i>外卖 / 自提</span>
|
||||
<span class="fr-meta-item"><i data-lucide="store" style="width:14px;height:14px;"></i>望京店 / 通州店</span>
|
||||
</div>
|
||||
<div class="fr-data">
|
||||
<span class="fr-data-item">参与订单 <span>410单</span></span>
|
||||
<span class="fr-data-item">优惠总额 <span>¥3,680</span></span>
|
||||
<span class="fr-data-item">客单价提升 <span>¥6.8</span></span>
|
||||
</div>
|
||||
<div class="fr-card-ft">
|
||||
<a class="g-action" onclick="openFrDrawer('edit')">编辑</a>
|
||||
<a class="g-action g-action-danger">删除</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="fr-pagination">
|
||||
<span>共 8 条</span>
|
||||
<button class="fr-page-btn"><</button>
|
||||
<button class="fr-page-btn active">1</button>
|
||||
<button class="fr-page-btn">2</button>
|
||||
<button class="fr-page-btn">></button>
|
||||
<span style="margin-left:8px;">4 条/页</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 创建/编辑抽屉 -->
|
||||
<div class="g-drawer-mask" id="frDrawerMask" onclick="closeFrDrawer()"></div>
|
||||
<div class="g-drawer" id="frDrawer" style="width:560px">
|
||||
<div class="g-drawer-hd">
|
||||
<div class="g-drawer-title" id="frDrawerTitle">创建满减活动</div>
|
||||
<button class="g-drawer-close" onclick="closeFrDrawer()"><i data-lucide="x" style="width:18px;height:18px;"></i></button>
|
||||
</div>
|
||||
<div class="g-drawer-bd">
|
||||
<!-- 活动名称 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required">活动名称</label>
|
||||
<input class="g-input" placeholder="如:午市满减优惠" />
|
||||
</div>
|
||||
|
||||
<!-- 满减规则 -->
|
||||
<div class="fr-section-hd" style="margin-top:8px;">满减规则</div>
|
||||
<div id="frTierList">
|
||||
<div class="fr-tier-row">
|
||||
<span>满</span>
|
||||
<input type="number" value="30" placeholder="金额" />
|
||||
<span>元减</span>
|
||||
<input type="number" value="5" placeholder="金额" />
|
||||
<span>元</span>
|
||||
<button class="fr-tier-del" onclick="removeFrTier(this)" title="删除"><i data-lucide="trash-2" style="width:14px;height:14px;"></i></button>
|
||||
</div>
|
||||
<div class="fr-tier-row">
|
||||
<span>满</span>
|
||||
<input type="number" value="50" placeholder="金额" />
|
||||
<span>元减</span>
|
||||
<input type="number" value="10" placeholder="金额" />
|
||||
<span>元</span>
|
||||
<button class="fr-tier-del" onclick="removeFrTier(this)" title="删除"><i data-lucide="trash-2" style="width:14px;height:14px;"></i></button>
|
||||
</div>
|
||||
<div class="fr-tier-row">
|
||||
<span>满</span>
|
||||
<input type="number" value="80" placeholder="金额" />
|
||||
<span>元减</span>
|
||||
<input type="number" value="20" placeholder="金额" />
|
||||
<span>元</span>
|
||||
<button class="fr-tier-del" onclick="removeFrTier(this)" title="删除"><i data-lucide="trash-2" style="width:14px;height:14px;"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<button class="fr-add-tier" onclick="addFrTier()">
|
||||
<i data-lucide="plus" style="width:14px;height:14px;"></i>添加阶梯
|
||||
</button>
|
||||
|
||||
<!-- 活动时间 -->
|
||||
<div class="g-form-group" style="margin-top:20px;">
|
||||
<label class="g-form-label required">活动时间</label>
|
||||
<div style="display:flex; align-items:center; gap:8px;">
|
||||
<input class="g-input" type="date" style="flex:1;" />
|
||||
<span style="color:var(--g-text-muted);">至</span>
|
||||
<input class="g-input" type="date" style="flex:1;" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 适用渠道 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label">适用渠道</label>
|
||||
<div style="display:flex; gap:8px; flex-wrap:wrap;">
|
||||
<span class="g-pill checked" onclick="this.classList.toggle('checked')">外卖</span>
|
||||
<span class="g-pill checked" onclick="this.classList.toggle('checked')">自提</span>
|
||||
<span class="g-pill" onclick="this.classList.toggle('checked')">堂食</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 适用门店 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label">适用门店</label>
|
||||
<select class="g-select">
|
||||
<option>全部门店</option>
|
||||
<option>老三家外卖(朝阳店)</option>
|
||||
<option>老三家外卖(海淀店)</option>
|
||||
<option>老三家外卖(望京店)</option>
|
||||
<option>老三家外卖(通州店)</option>
|
||||
<option>老三家外卖(丰台店)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- 叠加规则 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label">叠加规则</label>
|
||||
<div style="display:flex; gap:8px; flex-wrap:wrap;">
|
||||
<span class="g-pill checked" onclick="frToggleStack(this, 'no')">不可叠加优惠券</span>
|
||||
<span class="g-pill" onclick="frToggleStack(this, 'yes')">可叠加优惠券</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 活动说明 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label">活动说明</label>
|
||||
<textarea class="g-textarea" rows="3" placeholder="如:每单限享一次满减优惠"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="g-drawer-ft">
|
||||
<button class="g-btn" onclick="closeFrDrawer()">取消</button>
|
||||
<button class="g-btn g-btn-primary" onclick="closeFrDrawer()">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* 抽屉开关 */
|
||||
function openFrDrawer(mode) {
|
||||
document.getElementById('frDrawerMask').classList.add('open');
|
||||
document.getElementById('frDrawer').classList.add('open');
|
||||
document.getElementById('frDrawerTitle').textContent = mode === 'edit' ? '编辑满减活动' : '创建满减活动';
|
||||
}
|
||||
function closeFrDrawer() {
|
||||
document.getElementById('frDrawerMask').classList.remove('open');
|
||||
document.getElementById('frDrawer').classList.remove('open');
|
||||
}
|
||||
|
||||
/* 添加阶梯行 */
|
||||
function addFrTier() {
|
||||
var list = document.getElementById('frTierList');
|
||||
var row = document.createElement('div');
|
||||
row.className = 'fr-tier-row';
|
||||
row.innerHTML = '<span>满</span>' +
|
||||
'<input type="number" placeholder="金额" />' +
|
||||
'<span>元减</span>' +
|
||||
'<input type="number" placeholder="金额" />' +
|
||||
'<span>元</span>' +
|
||||
'<button class="fr-tier-del" onclick="removeFrTier(this)" title="删除"><i data-lucide="trash-2" style="width:14px;height:14px;"></i></button>';
|
||||
list.appendChild(row);
|
||||
if (window.lucide) lucide.createIcons();
|
||||
}
|
||||
|
||||
/* 删除阶梯行 */
|
||||
function removeFrTier(btn) {
|
||||
var row = btn.closest('.fr-tier-row');
|
||||
if (document.querySelectorAll('.fr-tier-row').length > 1) {
|
||||
row.remove();
|
||||
}
|
||||
}
|
||||
|
||||
/* 叠加规则互斥切换 */
|
||||
function frToggleStack(el, type) {
|
||||
var pills = el.parentElement.querySelectorAll('.g-pill');
|
||||
pills.forEach(function(p) { p.classList.remove('checked'); });
|
||||
el.classList.add('checked');
|
||||
}
|
||||
</script>
|
||||
567
pages/mkt-seckill.html
Normal file
567
pages/mkt-seckill.html
Normal file
@@ -0,0 +1,567 @@
|
||||
<!-- 秒杀活动页 -->
|
||||
<style>
|
||||
.sk-toolbar { display:flex; align-items:center; gap:12px; margin-bottom:16px; box-shadow:var(--g-shadow-sm); border-radius:10px; padding:12px 16px; background:#fff; flex-wrap:wrap; }
|
||||
.sk-search { position:relative; }
|
||||
.sk-search input { height:34px; padding:0 10px 0 32px; border:1px solid #e5e7eb; border-radius:8px; font-size:13px; outline:none; width:200px; transition:var(--g-transition); }
|
||||
.sk-search input:focus { border-color:var(--primary); box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 12%, transparent); }
|
||||
.sk-search i { position:absolute; left:9px; top:50%; transform:translateY(-50%); color:#bbb; pointer-events:none; }
|
||||
|
||||
.sk-stats { display:flex; gap:24px; margin-bottom:16px; padding:10px 16px; background:#fff; border-radius:10px; box-shadow:var(--g-shadow-sm); font-size:13px; color:#4b5563; }
|
||||
.sk-stats span { display:flex; align-items:center; gap:6px; }
|
||||
.sk-stats strong { color:#1a1a2e; font-weight:600; }
|
||||
|
||||
.sk-card { background:#fff; border-radius:10px; box-shadow:var(--g-shadow-sm); padding:20px; margin-bottom:16px; transition:box-shadow var(--g-transition); }
|
||||
.sk-card:hover { box-shadow:var(--g-shadow-md); }
|
||||
.sk-card.ended { opacity:.5; }
|
||||
|
||||
.sk-card-hd { display:flex; align-items:center; gap:10px; margin-bottom:14px; flex-wrap:wrap; }
|
||||
.sk-card-name { font-size:15px; font-weight:600; color:#1a1a2e; }
|
||||
.sk-card-time { font-size:12px; color:var(--g-text-muted); display:flex; align-items:center; gap:4px; }
|
||||
|
||||
.sk-tag-running { background:#dcfce7; color:#22c55e; border:1px solid #bbf7d0; border-radius:6px; font-weight:600; }
|
||||
.sk-tag-notstarted { background:#f0f5ff; color:var(--primary); border:1px solid #adc6ff; border-radius:6px; font-weight:600; }
|
||||
.sk-tag-ended { background:#f8f9fb; color:#9ca3af; border:1px solid #e5e7eb; border-radius:6px; font-weight:600; }
|
||||
|
||||
/* 秒杀商品行 */
|
||||
.sk-prod-list { margin-bottom:14px; }
|
||||
.sk-prod-row { display:flex; align-items:center; gap:16px; padding:10px 12px; border-bottom:1px solid #f3f4f6; font-size:13px; }
|
||||
.sk-prod-row:last-child { border-bottom:none; }
|
||||
.sk-prod-row:hover { background:color-mix(in srgb, var(--primary) 3%, #fff); border-radius:6px; }
|
||||
.sk-prod-name { width:140px; font-weight:500; color:#1a1a2e; flex-shrink:0; }
|
||||
.sk-prod-prices { display:flex; align-items:baseline; gap:8px; width:140px; flex-shrink:0; }
|
||||
.sk-orig-price { color:var(--g-text-muted); text-decoration:line-through; font-size:12px; }
|
||||
.sk-seckill-price { color:#ef4444; font-weight:700; font-size:16px; }
|
||||
|
||||
/* 进度条 */
|
||||
.sk-progress-wrap { flex:1; min-width:160px; display:flex; align-items:center; gap:8px; }
|
||||
.sk-progress { position:relative; height:16px; background:#f3f4f6; border-radius:8px; overflow:hidden; flex:1; }
|
||||
.sk-progress-fill { height:100%; border-radius:8px; transition:width 0.3s ease; }
|
||||
.sk-progress-fill.green { background:linear-gradient(90deg, #52c41a, #73d13d); }
|
||||
.sk-progress-fill.orange { background:linear-gradient(90deg, #fa8c16, #ffa940); }
|
||||
.sk-progress-fill.red { background:linear-gradient(90deg, #f5222d, #ff4d4f); }
|
||||
.sk-progress-text { position:absolute; inset:0; display:flex; align-items:center; justify-content:center; font-size:11px; font-weight:600; color:#fff; text-shadow:0 1px 2px rgba(0,0,0,.2); white-space:nowrap; }
|
||||
.sk-sold-out { display:inline-flex; align-items:center; gap:3px; padding:2px 8px; border-radius:4px; font-size:11px; font-weight:600; background:#fff1f0; color:#f5222d; border:1px solid #ffa39e; white-space:nowrap; }
|
||||
|
||||
.sk-card-summary { display:flex; gap:24px; font-size:12px; color:#4b5563; margin-bottom:12px; padding:10px 12px; background:#f8f9fb; border-radius:8px; }
|
||||
.sk-card-summary strong { color:#1a1a2e; font-weight:600; }
|
||||
.sk-card-ft { display:flex; gap:16px; border-top:1px solid #f3f4f6; padding-top:12px; }
|
||||
|
||||
/* 抽屉内秒杀商品 */
|
||||
.sk-drawer-prod { border:1px solid #e5e7eb; border-radius:8px; overflow:hidden; margin-bottom:12px; }
|
||||
.sk-drawer-prod-hd { display:flex; align-items:center; justify-content:space-between; padding:8px 12px; background:#f8f9fb; border-bottom:1px solid #e5e7eb; }
|
||||
.sk-drawer-prod-hd span { font-size:13px; font-weight:500; color:#1a1a2e; }
|
||||
.sk-drawer-prod-remove { background:none; border:none; color:#9ca3af; cursor:pointer; display:flex; align-items:center; justify-content:center; width:24px; height:24px; border-radius:6px; transition:var(--g-transition); }
|
||||
.sk-drawer-prod-remove:hover { color:#ef4444; background:#fef2f2; }
|
||||
.sk-drawer-prod-bd { padding:10px 12px; display:flex; gap:12px; align-items:center; flex-wrap:wrap; }
|
||||
.sk-drawer-prod-bd .sk-field { display:flex; flex-direction:column; gap:4px; }
|
||||
.sk-drawer-prod-bd .sk-field label { font-size:11px; color:#6b7280; }
|
||||
.sk-drawer-prod-bd .sk-field input { width:100px; height:30px; padding:0 8px; border:1px solid #e5e7eb; border-radius:6px; font-size:13px; outline:none; transition:var(--g-transition); }
|
||||
.sk-drawer-prod-bd .sk-field input:focus { border-color:var(--primary); box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 12%, transparent); }
|
||||
.sk-drawer-prod-bd .sk-field input[readonly] { background:#f8f9fb; color:var(--g-text-muted); cursor:default; }
|
||||
|
||||
.sk-pill-group { display:flex; gap:8px; flex-wrap:wrap; }
|
||||
.sk-pill { padding:6px 16px; border-radius:8px; border:1px solid #e5e7eb; background:#fff; font-size:13px; cursor:pointer; color:#4b5563; transition:var(--g-transition); }
|
||||
.sk-pill:hover { border-color:var(--primary); color:var(--primary); }
|
||||
.sk-pill.checked { background:var(--primary); color:#fff; border-color:var(--primary); }
|
||||
|
||||
/* 场次设置 */
|
||||
.sk-session-section { display:none; margin-top:12px; }
|
||||
.sk-session-section.show { display:block; }
|
||||
.sk-date-section { display:block; margin-top:12px; }
|
||||
.sk-date-section.hide { display:none; }
|
||||
.sk-session-row { display:flex; align-items:center; gap:8px; margin-bottom:8px; padding:8px 12px; background:#f8f9fb; border-radius:6px; border:1px solid #f0f0f0; }
|
||||
.sk-session-row input { width:90px; }
|
||||
.sk-session-label { font-size:12px; color:var(--g-text-secondary); }
|
||||
.sk-session-remove { background:none; border:none; color:#9ca3af; cursor:pointer; display:flex; align-items:center; justify-content:center; width:24px; height:24px; border-radius:6px; transition:var(--g-transition); }
|
||||
.sk-session-remove:hover { color:#ef4444; background:#fef2f2; }
|
||||
|
||||
.sk-limit-row { display:flex; align-items:center; gap:8px; }
|
||||
.sk-limit-row input { width:80px; }
|
||||
.sk-unit { font-size:13px; color:var(--g-text-secondary); }
|
||||
|
||||
.sk-preheat-row { display:flex; align-items:center; gap:10px; margin-top:8px; }
|
||||
.sk-preheat-row input { width:60px; }
|
||||
</style>
|
||||
|
||||
<!-- 工具栏 -->
|
||||
<div class="sk-toolbar">
|
||||
<select class="g-select" style="width:200px;">
|
||||
<option>老三家外卖(朝阳店)</option>
|
||||
<option>老三家外卖(海淀店)</option>
|
||||
<option>老三家外卖(望京店)</option>
|
||||
<option>老三家外卖(通州店)</option>
|
||||
<option>老三家外卖(丰台店)</option>
|
||||
</select>
|
||||
<select class="g-select" style="width:120px;">
|
||||
<option value="">全部状态</option>
|
||||
<option>进行中</option>
|
||||
<option>未开始</option>
|
||||
<option>已结束</option>
|
||||
</select>
|
||||
<div class="sk-search">
|
||||
<i data-lucide="search" style="width:14px;height:14px;"></i>
|
||||
<input type="text" placeholder="搜索秒杀活动名称…" />
|
||||
</div>
|
||||
<div style="flex:1;"></div>
|
||||
<button class="g-btn g-btn-primary" onclick="openSkDrawer('add')"><i data-lucide="plus" style="width:14px;height:14px;"></i>创建秒杀</button>
|
||||
</div>
|
||||
|
||||
<!-- 统计栏 -->
|
||||
<div class="sk-stats">
|
||||
<span>秒杀活动 <strong>6</strong></span>
|
||||
<span>进行中 <strong>2</strong></span>
|
||||
<span>本月秒杀销量 <strong>860</strong>单</span>
|
||||
<span>秒杀转化率 <strong>78.5%</strong></span>
|
||||
</div>
|
||||
|
||||
<!-- 活动卡片列表 -->
|
||||
<div id="skActivityList">
|
||||
|
||||
<!-- 午间秒杀 - 进行中 -->
|
||||
<div class="sk-card">
|
||||
<div class="sk-card-hd">
|
||||
<span class="sk-card-name">午间秒杀</span>
|
||||
<span class="g-tag sk-tag-running">进行中</span>
|
||||
<span class="sk-card-time"><i data-lucide="clock" style="width:12px;height:12px;"></i>每天 11:00 - 13:00</span>
|
||||
</div>
|
||||
<div class="sk-prod-list">
|
||||
<div class="sk-prod-row">
|
||||
<span class="sk-prod-name">招牌卤肉饭</span>
|
||||
<span class="sk-prod-prices">
|
||||
<span class="sk-orig-price">¥22</span>
|
||||
<span class="sk-seckill-price">¥9.9</span>
|
||||
</span>
|
||||
<div class="sk-progress-wrap">
|
||||
<div class="sk-progress">
|
||||
<div class="sk-progress-fill orange" style="width:84%;"></div>
|
||||
<span class="sk-progress-text">已抢 42/50</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sk-prod-row">
|
||||
<span class="sk-prod-name">冰粉</span>
|
||||
<span class="sk-prod-prices">
|
||||
<span class="sk-orig-price">¥8</span>
|
||||
<span class="sk-seckill-price">¥1</span>
|
||||
</span>
|
||||
<div class="sk-progress-wrap">
|
||||
<div class="sk-progress">
|
||||
<div class="sk-progress-fill red" style="width:100%;"></div>
|
||||
<span class="sk-progress-text">已抢 50/50</span>
|
||||
</div>
|
||||
<span class="sk-sold-out"><i data-lucide="flame" style="width:11px;height:11px;"></i>已抢光</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sk-card-summary">
|
||||
<span>参与人数 <strong>286</strong>人</span>
|
||||
<span>成交 <strong>218</strong>单</span>
|
||||
<span>转化率 <strong>76.2%</strong></span>
|
||||
</div>
|
||||
<div class="sk-card-ft">
|
||||
<span class="g-action" onclick="openSkDrawer('edit','午间秒杀')">编辑</span>
|
||||
<span class="g-action">停用</span>
|
||||
<span class="g-action g-action-danger">删除</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 整点特惠 - 进行中 -->
|
||||
<div class="sk-card">
|
||||
<div class="sk-card-hd">
|
||||
<span class="sk-card-name">整点特惠</span>
|
||||
<span class="g-tag sk-tag-running">进行中</span>
|
||||
<span class="sk-card-time"><i data-lucide="clock" style="width:12px;height:12px;"></i>每天 10:00 场 / 14:00 场 / 18:00 场</span>
|
||||
</div>
|
||||
<div class="sk-prod-list">
|
||||
<div class="sk-prod-row">
|
||||
<span class="sk-prod-name">黄焖鸡米饭</span>
|
||||
<span class="sk-prod-prices">
|
||||
<span class="sk-orig-price">¥28</span>
|
||||
<span class="sk-seckill-price">¥14.9</span>
|
||||
</span>
|
||||
<div class="sk-progress-wrap">
|
||||
<div class="sk-progress">
|
||||
<div class="sk-progress-fill orange" style="width:70%;"></div>
|
||||
<span class="sk-progress-text">已抢 28/40</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sk-prod-row">
|
||||
<span class="sk-prod-name">奶茶(大杯)</span>
|
||||
<span class="sk-prod-prices">
|
||||
<span class="sk-orig-price">¥15</span>
|
||||
<span class="sk-seckill-price">¥5</span>
|
||||
</span>
|
||||
<div class="sk-progress-wrap">
|
||||
<div class="sk-progress">
|
||||
<div class="sk-progress-fill orange" style="width:70%;"></div>
|
||||
<span class="sk-progress-text">已抢 35/50</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sk-prod-row">
|
||||
<span class="sk-prod-name">炸鸡翅(6只)</span>
|
||||
<span class="sk-prod-prices">
|
||||
<span class="sk-orig-price">¥25</span>
|
||||
<span class="sk-seckill-price">¥12.9</span>
|
||||
</span>
|
||||
<div class="sk-progress-wrap">
|
||||
<div class="sk-progress">
|
||||
<div class="sk-progress-fill green" style="width:60%;"></div>
|
||||
<span class="sk-progress-text">已抢 18/30</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sk-card-summary">
|
||||
<span>参与人数 <strong>198</strong>人</span>
|
||||
<span>成交 <strong>156</strong>单</span>
|
||||
<span>转化率 <strong>78.8%</strong></span>
|
||||
</div>
|
||||
<div class="sk-card-ft">
|
||||
<span class="g-action" onclick="openSkDrawer('edit','整点特惠')">编辑</span>
|
||||
<span class="g-action">停用</span>
|
||||
<span class="g-action g-action-danger">删除</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 新品首发秒杀 - 未开始 -->
|
||||
<div class="sk-card">
|
||||
<div class="sk-card-hd">
|
||||
<span class="sk-card-name">新品首发秒杀</span>
|
||||
<span class="g-tag sk-tag-notstarted">未开始</span>
|
||||
<span class="sk-card-time"><i data-lucide="calendar" style="width:12px;height:12px;"></i>2026-02-20 10:00 开始</span>
|
||||
</div>
|
||||
<div class="sk-prod-list">
|
||||
<div class="sk-prod-row">
|
||||
<span class="sk-prod-name">黑松露鸡肉卷</span>
|
||||
<span class="sk-prod-prices">
|
||||
<span class="sk-orig-price">¥38</span>
|
||||
<span class="sk-seckill-price">¥19.9</span>
|
||||
</span>
|
||||
<div class="sk-progress-wrap">
|
||||
<div class="sk-progress">
|
||||
<div class="sk-progress-fill green" style="width:0%;"></div>
|
||||
<span class="sk-progress-text" style="color:#999;">0/100</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sk-prod-row">
|
||||
<span class="sk-prod-name">芝士焗虾饭</span>
|
||||
<span class="sk-prod-prices">
|
||||
<span class="sk-orig-price">¥35</span>
|
||||
<span class="sk-seckill-price">¥17.5</span>
|
||||
</span>
|
||||
<div class="sk-progress-wrap">
|
||||
<div class="sk-progress">
|
||||
<div class="sk-progress-fill green" style="width:0%;"></div>
|
||||
<span class="sk-progress-text" style="color:#999;">0/80</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sk-card-ft">
|
||||
<span class="g-action" onclick="openSkDrawer('edit','新品首发秒杀')">编辑</span>
|
||||
<span class="g-action">停用</span>
|
||||
<span class="g-action g-action-danger">删除</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 周年庆秒杀 - 已结束 -->
|
||||
<div class="sk-card ended">
|
||||
<div class="sk-card-hd">
|
||||
<span class="sk-card-name">周年庆秒杀</span>
|
||||
<span class="g-tag sk-tag-ended">已结束</span>
|
||||
<span class="sk-card-time"><i data-lucide="calendar" style="width:12px;height:12px;"></i>2026-01-15 ~ 2026-01-17</span>
|
||||
</div>
|
||||
<div class="sk-prod-list">
|
||||
<div class="sk-prod-row">
|
||||
<span class="sk-prod-name">全场5折套餐</span>
|
||||
<span class="sk-prod-prices">
|
||||
<span class="sk-orig-price">¥49</span>
|
||||
<span class="sk-seckill-price">¥24.5</span>
|
||||
</span>
|
||||
<div class="sk-progress-wrap">
|
||||
<div class="sk-progress">
|
||||
<div class="sk-progress-fill red" style="width:100%;"></div>
|
||||
<span class="sk-progress-text">已抢 200/200</span>
|
||||
</div>
|
||||
<span class="sk-sold-out"><i data-lucide="flame" style="width:11px;height:11px;"></i>已抢光</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sk-card-summary">
|
||||
<span>参与人数 <strong>520</strong>人</span>
|
||||
<span>成交 <strong>412</strong>单</span>
|
||||
</div>
|
||||
<div class="sk-card-ft">
|
||||
<span class="g-action" onclick="openSkDrawer('edit','周年庆秒杀')">编辑</span>
|
||||
<span class="g-action">启用</span>
|
||||
<span class="g-action g-action-danger">删除</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="g-pagination" style="margin-top:8px;">
|
||||
<button class="g-page-btn" disabled><i data-lucide="chevron-left" style="width:14px;height:14px;"></i></button>
|
||||
<button class="g-page-btn active">1</button>
|
||||
<button class="g-page-btn">2</button>
|
||||
<button class="g-page-btn"><i data-lucide="chevron-right" style="width:14px;height:14px;"></i></button>
|
||||
<span style="font-size:12px;color:var(--g-text-muted);margin-left:8px;">共 6 条</span>
|
||||
</div>
|
||||
|
||||
<!-- 创建/编辑抽屉 -->
|
||||
<div class="g-drawer-mask" id="skDrawerMask" onclick="closeSkDrawer()"></div>
|
||||
<div class="g-drawer" id="skDrawer" style="width:560px">
|
||||
<div class="g-drawer-hd">
|
||||
<span class="g-drawer-title" id="skDrawerTitle">创建秒杀活动</span>
|
||||
<button class="g-drawer-close" onclick="closeSkDrawer()"><i data-lucide="x" style="width:18px;height:18px;"></i></button>
|
||||
</div>
|
||||
<div class="g-drawer-bd">
|
||||
<!-- 活动名称 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required">活动名称</label>
|
||||
<input class="g-input" id="skName" placeholder="如:午间秒杀、整点特惠">
|
||||
</div>
|
||||
|
||||
<!-- 活动类型 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required">活动类型</label>
|
||||
<div class="sk-pill-group">
|
||||
<span class="sk-pill checked" onclick="selectSkType(this,'timed')">限时秒杀</span>
|
||||
<span class="sk-pill" onclick="selectSkType(this,'hourly')">整点秒杀</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 限时秒杀:日期+时间范围 -->
|
||||
<div class="g-form-group sk-date-section" id="skDateSection">
|
||||
<label class="g-form-label required">活动时间</label>
|
||||
<div style="display:flex;gap:8px;align-items:center;">
|
||||
<input class="g-input" type="date" value="2026-02-15" style="flex:1;" placeholder="开始日期">
|
||||
<span style="color:var(--g-text-muted);">~</span>
|
||||
<input class="g-input" type="date" value="2026-03-15" style="flex:1;" placeholder="结束日期">
|
||||
</div>
|
||||
<div style="display:flex;gap:8px;align-items:center;margin-top:8px;">
|
||||
<input class="g-input" type="time" value="11:00" style="flex:1;" placeholder="开始时间">
|
||||
<span style="color:var(--g-text-muted);">~</span>
|
||||
<input class="g-input" type="time" value="13:00" style="flex:1;" placeholder="结束时间">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 整点秒杀:场次设置 -->
|
||||
<div class="g-form-group sk-session-section" id="skSessionSection">
|
||||
<label class="g-form-label required">场次设置</label>
|
||||
<div id="skSessionList">
|
||||
<div class="sk-session-row">
|
||||
<input class="g-input" type="time" value="10:00" placeholder="场次时间">
|
||||
<span class="sk-session-label">持续</span>
|
||||
<input class="g-input" type="number" value="60" min="1" style="width:70px;" placeholder="分钟">
|
||||
<span class="sk-session-label">分钟</span>
|
||||
<button class="sk-session-remove" onclick="removeSkSession(this)"><i data-lucide="x" style="width:14px;height:14px;"></i></button>
|
||||
</div>
|
||||
<div class="sk-session-row">
|
||||
<input class="g-input" type="time" value="14:00" placeholder="场次时间">
|
||||
<span class="sk-session-label">持续</span>
|
||||
<input class="g-input" type="number" value="60" min="1" style="width:70px;" placeholder="分钟">
|
||||
<span class="sk-session-label">分钟</span>
|
||||
<button class="sk-session-remove" onclick="removeSkSession(this)"><i data-lucide="x" style="width:14px;height:14px;"></i></button>
|
||||
</div>
|
||||
<div class="sk-session-row">
|
||||
<input class="g-input" type="time" value="18:00" placeholder="场次时间">
|
||||
<span class="sk-session-label">持续</span>
|
||||
<input class="g-input" type="number" value="60" min="1" style="width:70px;" placeholder="分钟">
|
||||
<span class="sk-session-label">分钟</span>
|
||||
<button class="sk-session-remove" onclick="removeSkSession(this)"><i data-lucide="x" style="width:14px;height:14px;"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<button class="g-btn g-btn-sm" style="margin-top:4px;" onclick="addSkSession()"><i data-lucide="plus" style="width:13px;height:13px;"></i>添加场次</button>
|
||||
</div>
|
||||
|
||||
<!-- 秒杀商品 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required" style="margin-bottom:10px;">秒杀商品</label>
|
||||
<div id="skProductList">
|
||||
<!-- 预填商品 1 -->
|
||||
<div class="sk-drawer-prod">
|
||||
<div class="sk-drawer-prod-hd">
|
||||
<span>招牌卤肉饭</span>
|
||||
<button class="sk-drawer-prod-remove" onclick="removeSkProduct(this)"><i data-lucide="x" style="width:14px;height:14px;"></i></button>
|
||||
</div>
|
||||
<div class="sk-drawer-prod-bd">
|
||||
<div class="sk-field">
|
||||
<label>原价</label>
|
||||
<input type="text" value="¥22.00" readonly>
|
||||
</div>
|
||||
<div class="sk-field">
|
||||
<label>秒杀价</label>
|
||||
<input type="number" value="9.90" step="0.01" placeholder="请输入秒杀价">
|
||||
</div>
|
||||
<div class="sk-field">
|
||||
<label>限量(份)</label>
|
||||
<input type="number" value="50" min="1" placeholder="如:50">
|
||||
</div>
|
||||
<div class="sk-field">
|
||||
<label>每人限购</label>
|
||||
<input type="number" value="1" min="0" placeholder="不限则留空">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 预填商品 2 -->
|
||||
<div class="sk-drawer-prod">
|
||||
<div class="sk-drawer-prod-hd">
|
||||
<span>冰粉</span>
|
||||
<button class="sk-drawer-prod-remove" onclick="removeSkProduct(this)"><i data-lucide="x" style="width:14px;height:14px;"></i></button>
|
||||
</div>
|
||||
<div class="sk-drawer-prod-bd">
|
||||
<div class="sk-field">
|
||||
<label>原价</label>
|
||||
<input type="text" value="¥8.00" readonly>
|
||||
</div>
|
||||
<div class="sk-field">
|
||||
<label>秒杀价</label>
|
||||
<input type="number" value="1.00" step="0.01" placeholder="请输入秒杀价">
|
||||
</div>
|
||||
<div class="sk-field">
|
||||
<label>限量(份)</label>
|
||||
<input type="number" value="50" min="1" placeholder="如:50">
|
||||
</div>
|
||||
<div class="sk-field">
|
||||
<label>每人限购</label>
|
||||
<input type="number" value="1" min="0" placeholder="不限则留空">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="g-btn g-btn-sm" style="margin-top:4px;" onclick="addSkProducts()"><i data-lucide="plus" style="width:13px;height:13px;"></i>添加商品</button>
|
||||
</div>
|
||||
|
||||
<!-- 适用渠道 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label">适用渠道</label>
|
||||
<div class="sk-pill-group">
|
||||
<span class="sk-pill checked" onclick="toggleSkPill(this)">外卖</span>
|
||||
<span class="sk-pill checked" onclick="toggleSkPill(this)">自提</span>
|
||||
<span class="sk-pill checked" onclick="toggleSkPill(this)">堂食</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 每人限购 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label">每人限购</label>
|
||||
<div class="sk-limit-row">
|
||||
<input class="g-input" type="number" value="2" min="0" placeholder="不限则留空" style="width:100px;">
|
||||
<span class="sk-unit">件</span>
|
||||
</div>
|
||||
<div class="g-hint">活动期间每人累计可秒杀的商品总数,留空不限</div>
|
||||
</div>
|
||||
|
||||
<!-- 预热设置 -->
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label">预热设置</label>
|
||||
<div class="g-toggle-wrap">
|
||||
<div class="g-toggle on" id="skPreheatToggle" onclick="this.classList.toggle('on')"></div>
|
||||
<span class="g-toggle-label">开启预热</span>
|
||||
</div>
|
||||
<div class="sk-preheat-row">
|
||||
<span class="sk-session-label">提前</span>
|
||||
<input class="g-input" type="number" value="2" min="1" placeholder="小时" style="width:60px;">
|
||||
<span class="sk-session-label">小时</span>
|
||||
</div>
|
||||
<div class="g-hint">在商品页展示秒杀预告,吸引用户提前关注</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="g-drawer-ft">
|
||||
<button class="g-btn" onclick="closeSkDrawer()">取消</button>
|
||||
<button class="g-btn g-btn-primary" onclick="closeSkDrawer()">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* 抽屉开关 */
|
||||
function openSkDrawer(mode, name) {
|
||||
document.getElementById('skDrawerMask').classList.add('open');
|
||||
document.getElementById('skDrawer').classList.add('open');
|
||||
if (mode === 'edit') {
|
||||
document.getElementById('skDrawerTitle').textContent = '编辑秒杀活动';
|
||||
document.getElementById('skName').value = name || '';
|
||||
} else {
|
||||
document.getElementById('skDrawerTitle').textContent = '创建秒杀活动';
|
||||
document.getElementById('skName').value = '';
|
||||
}
|
||||
if (typeof lucide !== 'undefined') lucide.createIcons();
|
||||
}
|
||||
|
||||
function closeSkDrawer() {
|
||||
document.getElementById('skDrawerMask').classList.remove('open');
|
||||
document.getElementById('skDrawer').classList.remove('open');
|
||||
}
|
||||
|
||||
/* 活动类型切换 */
|
||||
function selectSkType(el, type) {
|
||||
el.parentElement.querySelectorAll('.sk-pill').forEach(function(p) { p.classList.remove('checked'); });
|
||||
el.classList.add('checked');
|
||||
var dateSection = document.getElementById('skDateSection');
|
||||
var sessionSection = document.getElementById('skSessionSection');
|
||||
if (type === 'hourly') {
|
||||
dateSection.classList.add('hide');
|
||||
sessionSection.classList.add('show');
|
||||
} else {
|
||||
dateSection.classList.remove('hide');
|
||||
sessionSection.classList.remove('show');
|
||||
}
|
||||
}
|
||||
|
||||
/* 场次管理 */
|
||||
function addSkSession() {
|
||||
var list = document.getElementById('skSessionList');
|
||||
var row = document.createElement('div');
|
||||
row.className = 'sk-session-row';
|
||||
row.innerHTML =
|
||||
'<input class="g-input" type="time" placeholder="场次时间">' +
|
||||
'<span class="sk-session-label">持续</span>' +
|
||||
'<input class="g-input" type="number" value="60" min="1" style="width:70px;" placeholder="分钟">' +
|
||||
'<span class="sk-session-label">分钟</span>' +
|
||||
'<button class="sk-session-remove" onclick="removeSkSession(this)"><i data-lucide="x" style="width:14px;height:14px;"></i></button>';
|
||||
list.appendChild(row);
|
||||
if (typeof lucide !== 'undefined') lucide.createIcons();
|
||||
}
|
||||
|
||||
function removeSkSession(btn) {
|
||||
btn.closest('.sk-session-row').remove();
|
||||
}
|
||||
|
||||
/* 商品管理 */
|
||||
function addSkProducts() {
|
||||
var names = ['黄焖鸡米饭', '奶茶(大杯)', '炸鸡翅(6只)'];
|
||||
var prices = ['28.00', '15.00', '25.00'];
|
||||
var idx = Math.floor(Math.random() * names.length);
|
||||
var list = document.getElementById('skProductList');
|
||||
var div = document.createElement('div');
|
||||
div.className = 'sk-drawer-prod';
|
||||
div.innerHTML =
|
||||
'<div class="sk-drawer-prod-hd"><span>' + names[idx] + '</span>' +
|
||||
'<button class="sk-drawer-prod-remove" onclick="removeSkProduct(this)"><i data-lucide="x" style="width:14px;height:14px;"></i></button></div>' +
|
||||
'<div class="sk-drawer-prod-bd">' +
|
||||
'<div class="sk-field"><label>原价</label><input type="text" value="¥' + prices[idx] + '" readonly></div>' +
|
||||
'<div class="sk-field"><label>秒杀价</label><input type="number" step="0.01" placeholder="请输入秒杀价"></div>' +
|
||||
'<div class="sk-field"><label>限量(份)</label><input type="number" min="1" placeholder="如:50"></div>' +
|
||||
'<div class="sk-field"><label>每人限购</label><input type="number" min="0" placeholder="不限则留空"></div>' +
|
||||
'</div>';
|
||||
list.appendChild(div);
|
||||
if (typeof lucide !== 'undefined') lucide.createIcons();
|
||||
}
|
||||
|
||||
function removeSkProduct(btn) {
|
||||
btn.closest('.sk-drawer-prod').remove();
|
||||
}
|
||||
|
||||
/* Pill 切换 */
|
||||
function toggleSkPill(el) {
|
||||
el.classList.toggle('checked');
|
||||
}
|
||||
|
||||
/* 初始化图标 */
|
||||
if (typeof lucide !== 'undefined') lucide.createIcons();
|
||||
</script>
|
||||
662
pages/order-board.html
Normal file
662
pages/order-board.html
Normal file
@@ -0,0 +1,662 @@
|
||||
<!-- 订单大厅 - 实时看板 -->
|
||||
<style>
|
||||
/* ===== Page Layout ===== */
|
||||
.ob-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
font-size: 13px;
|
||||
color: var(--g-text);
|
||||
height: calc(100vh - var(--header-height) - var(--tabbar-height) - 32px);
|
||||
}
|
||||
|
||||
/* ===== Toolbar ===== */
|
||||
.ob-toolbar {
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
box-shadow: var(--g-shadow-sm);
|
||||
padding: 14px 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.ob-toolbar-right {
|
||||
margin-left: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.ob-icon-btn {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: var(--g-radius-sm);
|
||||
border: 1px solid var(--g-border-hover);
|
||||
background: #fff;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--g-text-secondary);
|
||||
transition: all var(--g-transition);
|
||||
}
|
||||
.ob-icon-btn:hover {
|
||||
border-color: var(--primary);
|
||||
color: var(--primary);
|
||||
}
|
||||
.ob-icon-btn.active {
|
||||
background: var(--primary);
|
||||
border-color: var(--primary);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* ===== Channel Filter Pills ===== */
|
||||
.ob-channels {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
}
|
||||
.ob-channel {
|
||||
height: 30px;
|
||||
padding: 0 14px;
|
||||
border-radius: 15px;
|
||||
border: 1px solid var(--g-border-hover);
|
||||
background: #fff;
|
||||
font-size: 12px;
|
||||
color: var(--g-text-secondary);
|
||||
cursor: pointer;
|
||||
transition: all var(--g-transition);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.ob-channel:hover {
|
||||
border-color: var(--primary);
|
||||
color: var(--primary);
|
||||
}
|
||||
.ob-channel.active {
|
||||
background: color-mix(in srgb, var(--primary) 10%, transparent);
|
||||
border-color: var(--primary);
|
||||
color: var(--primary);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* ===== Stats Row ===== */
|
||||
.ob-stats {
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
box-shadow: var(--g-shadow-sm);
|
||||
padding: 12px 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.ob-stat-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 0 20px;
|
||||
border-right: 1px solid var(--g-border);
|
||||
}
|
||||
.ob-stat-item:first-child { padding-left: 0; }
|
||||
.ob-stat-item:last-child { border-right: none; }
|
||||
.ob-stat-label {
|
||||
font-size: 12px;
|
||||
color: var(--g-text-muted);
|
||||
}
|
||||
.ob-stat-value {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: var(--g-text);
|
||||
}
|
||||
.ob-stat-item.highlight .ob-stat-value {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
/* ===== Kanban Board ===== */
|
||||
.ob-board {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
flex: 1;
|
||||
overflow-x: auto;
|
||||
min-height: 0;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
.ob-board::-webkit-scrollbar { height: 6px; }
|
||||
.ob-board::-webkit-scrollbar-thumb { background: #d9d9d9; border-radius: 3px; }
|
||||
|
||||
/* ===== Column ===== */
|
||||
.ob-column {
|
||||
min-width: 280px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: #f8f9fb;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.ob-col-hd {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 14px 16px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: var(--g-text);
|
||||
flex-shrink: 0;
|
||||
border-left: 3px solid transparent;
|
||||
}
|
||||
.ob-col-hd.pending { border-left-color: #fa8c16; }
|
||||
.ob-col-hd.making { border-left-color: var(--primary); }
|
||||
.ob-col-hd.delivering { border-left-color: #52c41a; }
|
||||
.ob-col-hd.done { border-left-color: #d9d9d9; }
|
||||
|
||||
.ob-col-count {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 20px;
|
||||
height: 20px;
|
||||
padding: 0 6px;
|
||||
border-radius: 10px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
}
|
||||
.ob-col-hd.pending .ob-col-count { background: #fa8c16; }
|
||||
.ob-col-hd.making .ob-col-count { background: var(--primary); }
|
||||
.ob-col-hd.delivering .ob-col-count { background: #52c41a; }
|
||||
.ob-col-hd.done .ob-col-count { background: #d9d9d9; color: #666; }
|
||||
|
||||
.ob-col-body {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 0 10px 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
.ob-col-body::-webkit-scrollbar { width: 4px; }
|
||||
.ob-col-body::-webkit-scrollbar-thumb { background: #d9d9d9; border-radius: 2px; }
|
||||
|
||||
/* ===== Order Card ===== */
|
||||
.ob-order {
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
box-shadow: var(--g-shadow-sm);
|
||||
padding: 14px;
|
||||
border-left: 3px solid transparent;
|
||||
transition: box-shadow var(--g-transition);
|
||||
cursor: default;
|
||||
}
|
||||
.ob-order:hover {
|
||||
box-shadow: var(--g-shadow-md);
|
||||
}
|
||||
.ob-order.border-orange { border-left-color: #fa8c16; }
|
||||
.ob-order.border-blue { border-left-color: var(--primary); }
|
||||
.ob-order.border-green { border-left-color: #52c41a; }
|
||||
.ob-order.border-gray { border-left-color: #d9d9d9; }
|
||||
.ob-order.dimmed { opacity: 0.6; }
|
||||
|
||||
/* Pulse animation for new orders */
|
||||
@keyframes ob-pulse-border {
|
||||
0%, 100% { border-left-color: #fa8c16; }
|
||||
50% { border-left-color: #ffd591; }
|
||||
}
|
||||
.ob-order.pulse {
|
||||
animation: ob-pulse-border 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* ===== Order Header ===== */
|
||||
.ob-order-hd {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.ob-order-no {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: var(--g-text);
|
||||
}
|
||||
.ob-order-time {
|
||||
margin-left: auto;
|
||||
font-size: 11px;
|
||||
color: var(--g-text-muted);
|
||||
}
|
||||
|
||||
/* ===== Order Info ===== */
|
||||
.ob-order-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
margin-bottom: 12px;
|
||||
font-size: 12px;
|
||||
color: var(--g-text-secondary);
|
||||
}
|
||||
.ob-order-info-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
.ob-order-info-row i {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
color: var(--g-text-muted);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.ob-order-items {
|
||||
color: var(--g-text);
|
||||
line-height: 1.5;
|
||||
}
|
||||
.ob-order-total {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 4px;
|
||||
}
|
||||
.ob-order-total-label {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: var(--g-text-muted);
|
||||
}
|
||||
.ob-tag-reserve {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 3px;
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
background: #fff7e6;
|
||||
color: #d46b08;
|
||||
border: 1px solid #ffe58f;
|
||||
}
|
||||
.ob-tag-urge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 3px;
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
background: #fff1f0;
|
||||
color: var(--g-danger);
|
||||
border: 1px solid #ffa39e;
|
||||
animation: ob-urge-blink 1.2s ease-in-out infinite;
|
||||
}
|
||||
@keyframes ob-urge-blink {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.5; }
|
||||
}
|
||||
.ob-order-status-line {
|
||||
font-size: 12px;
|
||||
color: var(--primary);
|
||||
font-weight: 500;
|
||||
}
|
||||
.ob-order-status-line.green {
|
||||
color: #52c41a;
|
||||
}
|
||||
.ob-order-complete-time {
|
||||
font-size: 12px;
|
||||
color: var(--g-text-muted);
|
||||
}
|
||||
.ob-order-rider, .ob-order-pickup, .ob-order-table {
|
||||
font-size: 12px;
|
||||
color: var(--g-text-secondary);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
/* ===== Order Footer ===== */
|
||||
.ob-order-ft {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding-top: 10px;
|
||||
border-top: 1px solid #f5f5f5;
|
||||
}
|
||||
.ob-order-ft .g-btn { flex: 1; }
|
||||
</style>
|
||||
|
||||
<div class="ob-page">
|
||||
<!-- Toolbar -->
|
||||
<div class="ob-toolbar">
|
||||
<select class="g-select" style="width:200px;">
|
||||
<option>万达广场店</option>
|
||||
<option>银泰城店</option>
|
||||
<option>大学城店</option>
|
||||
<option>火车站店</option>
|
||||
<option>科技园店</option>
|
||||
</select>
|
||||
|
||||
<div class="ob-channels">
|
||||
<span class="ob-channel active" onclick="filterObChannel(this)">全部</span>
|
||||
<span class="ob-channel" onclick="filterObChannel(this)">外卖</span>
|
||||
<span class="ob-channel" onclick="filterObChannel(this)">自提</span>
|
||||
<span class="ob-channel" onclick="filterObChannel(this)">堂食</span>
|
||||
</div>
|
||||
|
||||
<div class="ob-toolbar-right">
|
||||
<button class="ob-icon-btn active" title="提示音" onclick="this.classList.toggle('active')">
|
||||
<i data-lucide="volume-2" style="width:16px;height:16px;"></i>
|
||||
</button>
|
||||
<button class="ob-icon-btn" title="刷新" onclick="refreshBoard()">
|
||||
<i data-lucide="refresh-cw" style="width:16px;height:16px;"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Stats -->
|
||||
<div class="ob-stats">
|
||||
<div class="ob-stat-item highlight">
|
||||
<span class="ob-stat-label">今日订单</span>
|
||||
<span class="ob-stat-value">128</span>
|
||||
</div>
|
||||
<div class="ob-stat-item">
|
||||
<span class="ob-stat-label">待接单</span>
|
||||
<span class="ob-stat-value" style="color:#fa8c16;">5</span>
|
||||
</div>
|
||||
<div class="ob-stat-item">
|
||||
<span class="ob-stat-label">制作中</span>
|
||||
<span class="ob-stat-value" style="color:var(--primary);">8</span>
|
||||
</div>
|
||||
<div class="ob-stat-item">
|
||||
<span class="ob-stat-label">配送中</span>
|
||||
<span class="ob-stat-value" style="color:#52c41a;">12</span>
|
||||
</div>
|
||||
<div class="ob-stat-item">
|
||||
<span class="ob-stat-label">已完成</span>
|
||||
<span class="ob-stat-value">103</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Kanban Board -->
|
||||
<div class="ob-board">
|
||||
|
||||
<!-- Column: 待接单 -->
|
||||
<div class="ob-column">
|
||||
<div class="ob-col-hd pending">
|
||||
<span>待接单</span>
|
||||
<span class="ob-col-count">3</span>
|
||||
</div>
|
||||
<div class="ob-col-body">
|
||||
|
||||
<!-- Order 1 -->
|
||||
<div class="ob-order border-orange pulse">
|
||||
<div class="ob-order-hd">
|
||||
<span class="ob-order-no">#20250212001</span>
|
||||
<span class="g-tag g-tag-blue">外卖</span>
|
||||
<span class="ob-order-time">3分钟前</span>
|
||||
</div>
|
||||
<div class="ob-order-info">
|
||||
<div class="ob-order-info-row">
|
||||
<i data-lucide="user"></i>
|
||||
<span>张** 138****6789</span>
|
||||
</div>
|
||||
<div class="ob-order-items">宫保鸡丁x1, 米饭x1 等3件</div>
|
||||
<div class="ob-order-total"><span class="ob-order-total-label">实付</span>¥68.00</div>
|
||||
</div>
|
||||
<div class="ob-order-ft">
|
||||
<button class="g-btn g-btn-primary g-btn-sm">接单</button>
|
||||
<button class="g-btn g-btn-sm">拒单</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Order 2 -->
|
||||
<div class="ob-order border-orange pulse">
|
||||
<div class="ob-order-hd">
|
||||
<span class="ob-order-no">#20250212002</span>
|
||||
<span class="g-tag g-tag-green">自提</span>
|
||||
<span class="ob-tag-reserve"><i data-lucide="clock" style="width:11px;height:11px;"></i>预约 18:00</span>
|
||||
<span class="ob-order-time">5分钟前</span>
|
||||
</div>
|
||||
<div class="ob-order-info">
|
||||
<div class="ob-order-info-row">
|
||||
<i data-lucide="user"></i>
|
||||
<span>李** 159****3210</span>
|
||||
</div>
|
||||
<div class="ob-order-items">麻辣香锅(大份)x1, 可乐x2</div>
|
||||
<div class="ob-order-total"><span class="ob-order-total-label">实付</span>¥95.50</div>
|
||||
</div>
|
||||
<div class="ob-order-ft">
|
||||
<button class="g-btn g-btn-primary g-btn-sm">接单</button>
|
||||
<button class="g-btn g-btn-sm">拒单</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Order 3 -->
|
||||
<div class="ob-order border-orange pulse">
|
||||
<div class="ob-order-hd">
|
||||
<span class="ob-order-no">#20250212003</span>
|
||||
<span class="g-tag g-tag-orange">堂食</span>
|
||||
<span class="ob-order-time">1分钟前</span>
|
||||
</div>
|
||||
<div class="ob-order-info">
|
||||
<div class="ob-order-info-row">
|
||||
<i data-lucide="user"></i>
|
||||
<span>王** (桌号 B5)</span>
|
||||
</div>
|
||||
<div class="ob-order-items">鱼香肉丝x1, 蛋炒饭x2, 紫菜蛋花汤x1</div>
|
||||
<div class="ob-order-total"><span class="ob-order-total-label">实付</span>¥52.00</div>
|
||||
</div>
|
||||
<div class="ob-order-ft">
|
||||
<button class="g-btn g-btn-primary g-btn-sm">接单</button>
|
||||
<button class="g-btn g-btn-sm">拒单</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Column: 制作中 -->
|
||||
<div class="ob-column">
|
||||
<div class="ob-col-hd making">
|
||||
<span>制作中</span>
|
||||
<span class="ob-col-count">3</span>
|
||||
</div>
|
||||
<div class="ob-col-body">
|
||||
|
||||
<!-- Order 4 -->
|
||||
<div class="ob-order border-blue">
|
||||
<div class="ob-order-hd">
|
||||
<span class="ob-order-no">#20250212004</span>
|
||||
<span class="g-tag g-tag-blue">外卖</span>
|
||||
<span class="ob-order-time">12:08 接单</span>
|
||||
</div>
|
||||
<div class="ob-order-info">
|
||||
<div class="ob-order-status-line">已接单 5分钟</div>
|
||||
<div class="ob-order-info-row">
|
||||
<i data-lucide="user"></i>
|
||||
<span>赵** 136****8877</span>
|
||||
</div>
|
||||
<div class="ob-order-items">红烧牛肉面x2, 凉拌黄瓜x1</div>
|
||||
<div class="ob-order-total"><span class="ob-order-total-label">实付</span>¥76.00</div>
|
||||
</div>
|
||||
<div class="ob-order-ft">
|
||||
<button class="g-btn g-btn-primary g-btn-sm">出餐完成</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Order 5 -->
|
||||
<div class="ob-order border-blue">
|
||||
<div class="ob-order-hd">
|
||||
<span class="ob-order-no">#20250212005</span>
|
||||
<span class="g-tag g-tag-green">自提</span>
|
||||
<span class="ob-order-time">12:02 接单</span>
|
||||
</div>
|
||||
<div class="ob-order-info">
|
||||
<div class="ob-order-status-line">已接单 11分钟</div>
|
||||
<span class="ob-tag-urge"><i data-lucide="alert-circle" style="width:11px;height:11px;"></i>顾客催单</span>
|
||||
<div class="ob-order-info-row">
|
||||
<i data-lucide="user"></i>
|
||||
<span>孙** 177****4455</span>
|
||||
</div>
|
||||
<div class="ob-order-items">烤鸭套餐x1, 酸梅汤x2 等5件</div>
|
||||
<div class="ob-order-total"><span class="ob-order-total-label">实付</span>¥138.00</div>
|
||||
</div>
|
||||
<div class="ob-order-ft">
|
||||
<button class="g-btn g-btn-primary g-btn-sm">出餐完成</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Order 6 -->
|
||||
<div class="ob-order border-blue">
|
||||
<div class="ob-order-hd">
|
||||
<span class="ob-order-no">#20250212006</span>
|
||||
<span class="g-tag g-tag-orange">堂食</span>
|
||||
<span class="ob-order-time">12:10 接单</span>
|
||||
</div>
|
||||
<div class="ob-order-info">
|
||||
<div class="ob-order-status-line">已接单 3分钟</div>
|
||||
<div class="ob-order-info-row">
|
||||
<i data-lucide="user"></i>
|
||||
<span>周** (桌号 A1)</span>
|
||||
</div>
|
||||
<div class="ob-order-items">水煮鱼x1, 米饭x3</div>
|
||||
<div class="ob-order-total"><span class="ob-order-total-label">实付</span>¥89.00</div>
|
||||
</div>
|
||||
<div class="ob-order-ft">
|
||||
<button class="g-btn g-btn-primary g-btn-sm">出餐完成</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Column: 配送/取餐中 -->
|
||||
<div class="ob-column">
|
||||
<div class="ob-col-hd delivering">
|
||||
<span>配送/取餐中</span>
|
||||
<span class="ob-col-count">2</span>
|
||||
</div>
|
||||
<div class="ob-col-body">
|
||||
|
||||
<!-- Order 7 - 外卖配送 -->
|
||||
<div class="ob-order border-green">
|
||||
<div class="ob-order-hd">
|
||||
<span class="ob-order-no">#20250212007</span>
|
||||
<span class="g-tag g-tag-blue">外卖</span>
|
||||
<span class="ob-order-time">11:50 出餐</span>
|
||||
</div>
|
||||
<div class="ob-order-info">
|
||||
<div class="ob-order-status-line green">配送中</div>
|
||||
<div class="ob-order-rider">
|
||||
<i data-lucide="bike" style="width:14px;height:14px;"></i>
|
||||
<span>骑手: 李师傅 138****5678</span>
|
||||
</div>
|
||||
<div class="ob-order-info-row">
|
||||
<i data-lucide="user"></i>
|
||||
<span>陈** 150****9900</span>
|
||||
</div>
|
||||
<div class="ob-order-items">黄焖鸡米饭x1, 加辣 等2件</div>
|
||||
<div class="ob-order-total"><span class="ob-order-total-label">实付</span>¥35.00</div>
|
||||
</div>
|
||||
<div class="ob-order-ft">
|
||||
<button class="g-btn g-btn-primary g-btn-sm">确认送达</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Order 8 - 自提 -->
|
||||
<div class="ob-order border-green">
|
||||
<div class="ob-order-hd">
|
||||
<span class="ob-order-no">#20250212008</span>
|
||||
<span class="g-tag g-tag-green">自提</span>
|
||||
<span class="ob-order-time">11:55 出餐</span>
|
||||
</div>
|
||||
<div class="ob-order-info">
|
||||
<div class="ob-order-status-line green">等待取餐</div>
|
||||
<div class="ob-order-pickup">
|
||||
<i data-lucide="hash" style="width:14px;height:14px;"></i>
|
||||
<span>取餐码: <strong style="font-size:16px;color:var(--g-text);">A088</strong></span>
|
||||
</div>
|
||||
<div class="ob-order-info-row">
|
||||
<i data-lucide="user"></i>
|
||||
<span>吴** 133****2211</span>
|
||||
</div>
|
||||
<div class="ob-order-items">炸鸡桶x1, 薯条x2, 可乐x2</div>
|
||||
<div class="ob-order-total"><span class="ob-order-total-label">实付</span>¥79.00</div>
|
||||
</div>
|
||||
<div class="ob-order-ft">
|
||||
<button class="g-btn g-btn-primary g-btn-sm">确认取餐</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Column: 已完成 -->
|
||||
<div class="ob-column">
|
||||
<div class="ob-col-hd done">
|
||||
<span>已完成</span>
|
||||
<span class="ob-col-count">103</span>
|
||||
</div>
|
||||
<div class="ob-col-body">
|
||||
|
||||
<!-- Order 9 -->
|
||||
<div class="ob-order border-gray dimmed">
|
||||
<div class="ob-order-hd">
|
||||
<span class="ob-order-no">#20250212009</span>
|
||||
<span class="g-tag g-tag-blue">外卖</span>
|
||||
<span class="ob-order-time">12:35 完成</span>
|
||||
</div>
|
||||
<div class="ob-order-info">
|
||||
<div class="ob-order-info-row">
|
||||
<i data-lucide="user"></i>
|
||||
<span>刘** 186****7766</span>
|
||||
</div>
|
||||
<div class="ob-order-items">麻婆豆腐x1, 米饭x1</div>
|
||||
<div class="ob-order-total"><span class="ob-order-total-label">实付</span>¥32.00</div>
|
||||
</div>
|
||||
<div class="ob-order-ft">
|
||||
<a class="g-action">查看详情</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Order 10 -->
|
||||
<div class="ob-order border-gray dimmed">
|
||||
<div class="ob-order-hd">
|
||||
<span class="ob-order-no">#20250212010</span>
|
||||
<span class="g-tag g-tag-orange">堂食</span>
|
||||
<span class="ob-order-time">12:20 完成</span>
|
||||
</div>
|
||||
<div class="ob-order-info">
|
||||
<div class="ob-order-info-row">
|
||||
<i data-lucide="user"></i>
|
||||
<span>杨** (桌号 A3)</span>
|
||||
</div>
|
||||
<div class="ob-order-items">剁椒鱼头x1, 蒜蓉西兰花x1, 米饭x2</div>
|
||||
<div class="ob-order-total"><span class="ob-order-total-label">实付</span>¥118.00</div>
|
||||
</div>
|
||||
<div class="ob-order-ft">
|
||||
<a class="g-action">查看详情</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* 渠道筛选切换 */
|
||||
function filterObChannel(el) {
|
||||
el.parentElement.querySelectorAll('.ob-channel').forEach(function(c) {
|
||||
c.classList.remove('active');
|
||||
});
|
||||
el.classList.add('active');
|
||||
}
|
||||
|
||||
/* 刷新看板(原型占位) */
|
||||
function refreshBoard() {
|
||||
// 原型演示,无真实刷新逻辑
|
||||
}
|
||||
|
||||
/* 初始化 Lucide 图标 */
|
||||
if (typeof lucide !== 'undefined') {
|
||||
lucide.createIcons();
|
||||
}
|
||||
</script>
|
||||
442
pages/order-list.html
Normal file
442
pages/order-list.html
Normal file
@@ -0,0 +1,442 @@
|
||||
<!-- 全部订单 — order-list.html -->
|
||||
<style>
|
||||
/* ---- page-private: ol- prefix ---- */
|
||||
.ol-toolbar {
|
||||
background: #fff; border-radius: var(--g-radius); padding: 16px 20px;
|
||||
display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
|
||||
box-shadow: var(--g-shadow-sm); border: 1px solid var(--g-border);
|
||||
}
|
||||
.ol-toolbar .g-select,
|
||||
.ol-toolbar .g-input { height: 32px; font-size: 13px; }
|
||||
.ol-search-wrap {
|
||||
position: relative; width: 200px;
|
||||
}
|
||||
.ol-search-wrap .g-input { padding-left: 30px; width: 100%; }
|
||||
.ol-search-wrap i {
|
||||
position: absolute; left: 8px; top: 50%; transform: translateY(-50%);
|
||||
color: var(--g-text-muted); pointer-events: none;
|
||||
}
|
||||
.ol-toolbar-right { margin-left: auto; }
|
||||
.ol-date-sep { color: var(--g-text-muted); font-size: 13px; line-height: 32px; }
|
||||
|
||||
/* stats row */
|
||||
.ol-stats {
|
||||
display: flex; gap: 24px; padding: 12px 0 4px; font-size: 13px; color: var(--g-text-secondary);
|
||||
}
|
||||
.ol-stats span { white-space: nowrap; }
|
||||
.ol-stats strong { color: var(--g-text); font-weight: 600; margin-left: 4px; }
|
||||
|
||||
/* table card */
|
||||
.ol-table-card {
|
||||
background: #fff; border-radius: var(--g-radius); border: 1px solid var(--g-border);
|
||||
margin-top: 12px; overflow: hidden;
|
||||
}
|
||||
.ol-table-card .g-table th { white-space: nowrap; }
|
||||
.ol-table-card .g-table td { vertical-align: middle; }
|
||||
|
||||
/* dimmed row for cancelled / refunded */
|
||||
.ol-row-dim td { opacity: .55; }
|
||||
.ol-row-dim:hover td { opacity: .75; }
|
||||
|
||||
/* items cell */
|
||||
.ol-items { max-width: 180px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
|
||||
/* amount */
|
||||
.ol-amount { font-weight: 600; white-space: nowrap; }
|
||||
|
||||
/* drawer */
|
||||
.ol-drawer { width: 560px; }
|
||||
|
||||
/* drawer sections */
|
||||
.ol-section { margin-bottom: 22px; }
|
||||
.ol-section-hd {
|
||||
font-size: 14px; font-weight: 600; color: var(--g-text);
|
||||
padding-left: 10px; border-left: 3px solid var(--primary); margin-bottom: 14px;
|
||||
}
|
||||
.ol-info-grid {
|
||||
display: grid; grid-template-columns: 1fr 1fr; gap: 10px 20px; font-size: 13px;
|
||||
}
|
||||
.ol-info-label { color: var(--g-text-muted); }
|
||||
.ol-info-val { color: var(--g-text); }
|
||||
.ol-info-full { grid-column: 1 / -1; }
|
||||
|
||||
/* mini product table */
|
||||
.ol-prod-table { width: 100%; border-collapse: collapse; font-size: 13px; }
|
||||
.ol-prod-table th {
|
||||
text-align: left; padding: 8px 10px; font-size: 12px; font-weight: 500;
|
||||
color: var(--g-text-muted); background: var(--g-bg-subtle); border-bottom: 1px solid var(--g-border);
|
||||
}
|
||||
.ol-prod-table td { padding: 8px 10px; border-bottom: 1px solid #f5f5f5; color: var(--g-text); }
|
||||
.ol-prod-table .ol-sum-row td {
|
||||
font-weight: 600; border-bottom: none; padding-top: 10px;
|
||||
}
|
||||
|
||||
/* timeline */
|
||||
.ol-timeline { position: relative; padding-left: 22px; }
|
||||
.ol-tl-item {
|
||||
position: relative; padding-bottom: 18px; font-size: 13px;
|
||||
}
|
||||
.ol-tl-item:last-child { padding-bottom: 0; }
|
||||
.ol-tl-item::before {
|
||||
content: ''; position: absolute; left: -22px; top: 5px;
|
||||
width: 10px; height: 10px; border-radius: 50%;
|
||||
background: var(--primary); border: 2px solid var(--primary-light);
|
||||
}
|
||||
.ol-tl-item:not(:last-child)::after {
|
||||
content: ''; position: absolute; left: -18px; top: 17px;
|
||||
width: 2px; height: calc(100% - 12px); background: #e8e8e8;
|
||||
}
|
||||
.ol-tl-label { color: var(--g-text); font-weight: 500; }
|
||||
.ol-tl-time { color: var(--g-text-muted); margin-left: 8px; }
|
||||
|
||||
/* remark */
|
||||
.ol-remark {
|
||||
background: var(--g-bg-subtle); border-radius: var(--g-radius-sm);
|
||||
padding: 10px 14px; font-size: 13px; color: var(--g-text-secondary);
|
||||
border: 1px solid var(--g-border);
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- 顶部筛选栏 -->
|
||||
<div class="ol-toolbar">
|
||||
<select class="g-select" style="width:200px;">
|
||||
<option>全部门店</option>
|
||||
<option>老三家外卖(朝阳店)</option>
|
||||
<option>老三家外卖(海淀店)</option>
|
||||
<option>老三家外卖(望京店)</option>
|
||||
<option>老三家外卖(通州店)</option>
|
||||
<option>老三家外卖(丰台店)</option>
|
||||
</select>
|
||||
<input type="date" class="g-input" style="width:145px;" value="2025-02-12">
|
||||
<span class="ol-date-sep">~</span>
|
||||
<input type="date" class="g-input" style="width:145px;" value="2025-02-12">
|
||||
<select class="g-select" style="width:120px;" onchange="filterOlStatus()">
|
||||
<option>全部状态</option>
|
||||
<option>待接单</option>
|
||||
<option>制作中</option>
|
||||
<option>配送中</option>
|
||||
<option>待取餐</option>
|
||||
<option>已完成</option>
|
||||
<option>已取消</option>
|
||||
<option>已退款</option>
|
||||
</select>
|
||||
<select class="g-select" style="width:110px;">
|
||||
<option>全部渠道</option>
|
||||
<option>外卖</option>
|
||||
<option>自提</option>
|
||||
<option>堂食</option>
|
||||
</select>
|
||||
<select class="g-select" style="width:120px;">
|
||||
<option>全部支付</option>
|
||||
<option>微信支付</option>
|
||||
<option>支付宝</option>
|
||||
<option>余额支付</option>
|
||||
</select>
|
||||
<div class="ol-search-wrap">
|
||||
<i data-lucide="search" style="width:14px;height:14px;"></i>
|
||||
<input class="g-input" placeholder="订单号/手机号" oninput="searchOlOrders(this.value)">
|
||||
</div>
|
||||
<div class="ol-toolbar-right">
|
||||
<button class="g-btn" onclick="exportOrders()">
|
||||
<i data-lucide="download" style="width:14px;height:14px;"></i> 导出
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 统计行 -->
|
||||
<div class="ol-stats">
|
||||
<span>筛选结果<strong>128 单</strong></span>
|
||||
<span>总金额<strong>¥12,680.00</strong></span>
|
||||
<span>平均客单价<strong>¥99.06</strong></span>
|
||||
<span>退款<strong style="color:var(--g-danger);">3 单</strong></span>
|
||||
</div>
|
||||
|
||||
<!-- 表格 -->
|
||||
<div class="ol-table-card">
|
||||
<table class="g-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>订单号</th>
|
||||
<th>下单时间</th>
|
||||
<th>渠道</th>
|
||||
<th>顾客</th>
|
||||
<th>商品</th>
|
||||
<th>金额</th>
|
||||
<th>状态</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="font-family:monospace;">#20250212001</td>
|
||||
<td>2025-02-12 12:00:15</td>
|
||||
<td><span class="g-tag g-tag-blue">外卖</span></td>
|
||||
<td>张**</td>
|
||||
<td class="ol-items">宫保鸡丁等3件</td>
|
||||
<td class="ol-amount">¥89.00</td>
|
||||
<td><span class="g-tag g-tag-green">已完成</span></td>
|
||||
<td><a class="g-action" onclick="openOlDrawer('#20250212001')">详情</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-family:monospace;">#20250212002</td>
|
||||
<td>2025-02-12 12:05:30</td>
|
||||
<td><span class="g-tag g-tag-green">自提</span></td>
|
||||
<td>李**</td>
|
||||
<td class="ol-items">双人超值套餐等2件</td>
|
||||
<td class="ol-amount">¥128.00</td>
|
||||
<td><span class="g-tag g-tag-green">已完成</span></td>
|
||||
<td><a class="g-action" onclick="openOlDrawer('#20250212002')">详情</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-family:monospace;">#20250212003</td>
|
||||
<td>2025-02-12 12:12:08</td>
|
||||
<td><span class="g-tag g-tag-blue">外卖</span></td>
|
||||
<td>王**</td>
|
||||
<td class="ol-items">鱼香肉丝盖饭等1件</td>
|
||||
<td class="ol-amount">¥35.50</td>
|
||||
<td><span class="g-tag g-tag-blue">制作中</span></td>
|
||||
<td><a class="g-action" onclick="openOlDrawer('#20250212003')">详情</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-family:monospace;">#20250212004</td>
|
||||
<td>2025-02-12 12:18:45</td>
|
||||
<td><span class="g-tag g-tag-orange">堂食</span></td>
|
||||
<td>赵**</td>
|
||||
<td class="ol-items">招牌红烧肉饭等4件</td>
|
||||
<td class="ol-amount">¥168.00</td>
|
||||
<td><span class="g-tag g-tag-green">已完成</span></td>
|
||||
<td><a class="g-action" onclick="openOlDrawer('#20250212004')">详情</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-family:monospace;">#20250212005</td>
|
||||
<td>2025-02-12 12:25:10</td>
|
||||
<td><span class="g-tag g-tag-blue">外卖</span></td>
|
||||
<td>刘**</td>
|
||||
<td class="ol-items">番茄牛腩面等2件</td>
|
||||
<td class="ol-amount">¥56.00</td>
|
||||
<td><span class="g-tag g-tag-blue">配送中</span></td>
|
||||
<td><a class="g-action" onclick="openOlDrawer('#20250212005')">详情</a></td>
|
||||
</tr>
|
||||
<tr class="ol-row-dim">
|
||||
<td style="font-family:monospace;">#20250212006</td>
|
||||
<td>2025-02-12 12:30:22</td>
|
||||
<td><span class="g-tag g-tag-blue">外卖</span></td>
|
||||
<td>陈**</td>
|
||||
<td class="ol-items">香辣鸡腿堡套餐等1件</td>
|
||||
<td class="ol-amount">¥45.00</td>
|
||||
<td><span class="g-tag g-tag-gray">已取消</span></td>
|
||||
<td><a class="g-action" onclick="openOlDrawer('#20250212006')">详情</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-family:monospace;">#20250212007</td>
|
||||
<td>2025-02-12 12:35:50</td>
|
||||
<td><span class="g-tag g-tag-green">自提</span></td>
|
||||
<td>孙**</td>
|
||||
<td class="ol-items">麻婆豆腐等3件</td>
|
||||
<td class="ol-amount">¥72.00</td>
|
||||
<td><span class="g-tag g-tag-green">已完成</span></td>
|
||||
<td><a class="g-action" onclick="openOlDrawer('#20250212007')">详情</a></td>
|
||||
</tr>
|
||||
<tr class="ol-row-dim">
|
||||
<td style="font-family:monospace;">#20250212008</td>
|
||||
<td>2025-02-12 12:40:18</td>
|
||||
<td><span class="g-tag g-tag-blue">外卖</span></td>
|
||||
<td>周**</td>
|
||||
<td class="ol-items">酸辣土豆丝等2件</td>
|
||||
<td class="ol-amount">¥42.00</td>
|
||||
<td><span class="g-tag g-tag-red">已退款</span></td>
|
||||
<td><a class="g-action" onclick="openOlDrawer('#20250212008')">详情</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-family:monospace;">#20250212009</td>
|
||||
<td>2025-02-12 12:48:33</td>
|
||||
<td><span class="g-tag g-tag-orange">堂食</span></td>
|
||||
<td>吴**</td>
|
||||
<td class="ol-items">皮蛋豆腐等5件</td>
|
||||
<td class="ol-amount">¥156.00</td>
|
||||
<td><span class="g-tag g-tag-green">已完成</span></td>
|
||||
<td><a class="g-action" onclick="openOlDrawer('#20250212009')">详情</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-family:monospace;">#20250212010</td>
|
||||
<td>2025-02-12 12:55:02</td>
|
||||
<td><span class="g-tag g-tag-blue">外卖</span></td>
|
||||
<td>郑**</td>
|
||||
<td class="ol-items">蛋炒饭等2件</td>
|
||||
<td class="ol-amount">¥38.00</td>
|
||||
<td><span class="g-tag g-tag-blue">制作中</span></td>
|
||||
<td><a class="g-action" onclick="openOlDrawer('#20250212010')">详情</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="g-pagination">
|
||||
<span>共 128 条</span>
|
||||
<button class="g-page-btn" disabled><</button>
|
||||
<button class="g-page-btn active">1</button>
|
||||
<button class="g-page-btn">2</button>
|
||||
<button class="g-page-btn">3</button>
|
||||
<button class="g-page-btn">4</button>
|
||||
<button class="g-page-btn">5</button>
|
||||
<button class="g-page-btn">></button>
|
||||
</div>
|
||||
|
||||
<!-- 订单详情抽屉 -->
|
||||
<div class="g-drawer-mask" id="olDrawerMask" onclick="closeOlDrawer()"></div>
|
||||
<div class="g-drawer ol-drawer" id="olDrawer">
|
||||
<div class="g-drawer-hd">
|
||||
<span class="g-drawer-title" id="olDrawerTitle">订单详情 #20250212001</span>
|
||||
<button class="g-drawer-close" onclick="closeOlDrawer()"><i data-lucide="x" style="width:18px;height:18px;"></i></button>
|
||||
</div>
|
||||
<div class="g-drawer-bd">
|
||||
|
||||
<!-- 基本信息 -->
|
||||
<div class="ol-section">
|
||||
<div class="ol-section-hd">基本信息</div>
|
||||
<div class="ol-info-grid">
|
||||
<div><span class="ol-info-label">订单号:</span><span class="ol-info-val" style="font-family:monospace;">#20250212001</span></div>
|
||||
<div><span class="ol-info-label">渠道:</span><span class="g-tag g-tag-blue">外卖</span></div>
|
||||
<div><span class="ol-info-label">状态:</span><span class="g-tag g-tag-green">已完成</span></div>
|
||||
<div><span class="ol-info-label">支付方式:</span><span class="ol-info-val">微信支付</span></div>
|
||||
<div><span class="ol-info-label">下单时间:</span><span class="ol-info-val">2025-02-12 12:00:00</span></div>
|
||||
<div><span class="ol-info-label">支付时间:</span><span class="ol-info-val">2025-02-12 12:00:15</span></div>
|
||||
<div><span class="ol-info-label">完成时间:</span><span class="ol-info-val">2025-02-12 12:35:00</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 顾客信息 -->
|
||||
<div class="ol-section">
|
||||
<div class="ol-section-hd">顾客信息</div>
|
||||
<div class="ol-info-grid">
|
||||
<div><span class="ol-info-label">姓名:</span><span class="ol-info-val">张**</span></div>
|
||||
<div><span class="ol-info-label">手机号:</span><span class="ol-info-val">138****6789</span></div>
|
||||
<div class="ol-info-full"><span class="ol-info-label">收货地址:</span><span class="ol-info-val">北京市朝阳区建国路88号院3号楼1单元502</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 商品明细 -->
|
||||
<div class="ol-section">
|
||||
<div class="ol-section-hd">商品明细</div>
|
||||
<table class="ol-prod-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>商品</th>
|
||||
<th>规格</th>
|
||||
<th>数量</th>
|
||||
<th>单价</th>
|
||||
<th style="text-align:right;">小计</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>宫保鸡丁</td>
|
||||
<td>大份</td>
|
||||
<td>1</td>
|
||||
<td>¥38.00</td>
|
||||
<td style="text-align:right;">¥38.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>酸辣土豆丝</td>
|
||||
<td>标准</td>
|
||||
<td>1</td>
|
||||
<td>¥14.00</td>
|
||||
<td style="text-align:right;">¥14.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>米饭</td>
|
||||
<td>标准</td>
|
||||
<td>2</td>
|
||||
<td>¥3.00</td>
|
||||
<td style="text-align:right;">¥6.00</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div style="font-size:13px; padding:12px 10px 0; display:flex; flex-direction:column; gap:6px;">
|
||||
<div style="display:flex; justify-content:space-between; color:var(--g-text-secondary);">
|
||||
<span>商品合计</span><span>¥58.00</span>
|
||||
</div>
|
||||
<div style="display:flex; justify-content:space-between; color:var(--g-text-secondary);">
|
||||
<span>配送费</span><span>¥5.00</span>
|
||||
</div>
|
||||
<div style="display:flex; justify-content:space-between; color:var(--g-text-secondary);">
|
||||
<span>优惠减免</span><span style="color:var(--g-danger);">-¥8.00</span>
|
||||
</div>
|
||||
<div style="display:flex; justify-content:space-between; font-weight:600; color:var(--g-text); border-top:1px solid var(--g-border); padding-top:8px; margin-top:4px;">
|
||||
<span>实付金额</span><span style="color:var(--primary); font-size:15px;">¥55.00</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 状态时间线 -->
|
||||
<div class="ol-section">
|
||||
<div class="ol-section-hd">状态时间线</div>
|
||||
<div class="ol-timeline">
|
||||
<div class="ol-tl-item">
|
||||
<span class="ol-tl-label">下单</span>
|
||||
<span class="ol-tl-time">12:00:00</span>
|
||||
</div>
|
||||
<div class="ol-tl-item">
|
||||
<span class="ol-tl-label">支付成功</span>
|
||||
<span class="ol-tl-time">12:00:15</span>
|
||||
</div>
|
||||
<div class="ol-tl-item">
|
||||
<span class="ol-tl-label">商家接单</span>
|
||||
<span class="ol-tl-time">12:01:30</span>
|
||||
</div>
|
||||
<div class="ol-tl-item">
|
||||
<span class="ol-tl-label">开始制作</span>
|
||||
<span class="ol-tl-time">12:01:30</span>
|
||||
</div>
|
||||
<div class="ol-tl-item">
|
||||
<span class="ol-tl-label">出餐完成</span>
|
||||
<span class="ol-tl-time">12:15:00</span>
|
||||
</div>
|
||||
<div class="ol-tl-item">
|
||||
<span class="ol-tl-label">骑手取餐</span>
|
||||
<span class="ol-tl-time">12:16:20</span>
|
||||
</div>
|
||||
<div class="ol-tl-item">
|
||||
<span class="ol-tl-label">已送达</span>
|
||||
<span class="ol-tl-time">12:35:00</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 备注 -->
|
||||
<div class="ol-section">
|
||||
<div class="ol-section-hd">备注</div>
|
||||
<div class="ol-remark">少放辣,多加饭</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="g-drawer-ft">
|
||||
<button class="g-btn" onclick="closeOlDrawer()">关闭</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* 抽屉开关 */
|
||||
function openOlDrawer(orderNo) {
|
||||
document.getElementById('olDrawerTitle').textContent = '订单详情 ' + orderNo;
|
||||
document.getElementById('olDrawerMask').classList.add('open');
|
||||
document.getElementById('olDrawer').classList.add('open');
|
||||
if (typeof lucide !== 'undefined') lucide.createIcons();
|
||||
}
|
||||
function closeOlDrawer() {
|
||||
document.getElementById('olDrawerMask').classList.remove('open');
|
||||
document.getElementById('olDrawer').classList.remove('open');
|
||||
}
|
||||
|
||||
/* 筛选占位 */
|
||||
function filterOlStatus() {
|
||||
/* 原型占位,无真实逻辑 */
|
||||
}
|
||||
function searchOlOrders(keyword) {
|
||||
/* 原型占位,无真实逻辑 */
|
||||
}
|
||||
function exportOrders() {
|
||||
alert('导出功能仅为原型演示');
|
||||
}
|
||||
</script>
|
||||
402
pages/order-refund.html
Normal file
402
pages/order-refund.html
Normal file
@@ -0,0 +1,402 @@
|
||||
<!-- 退款售后页 -->
|
||||
<style>
|
||||
.orf-toolbar { display:flex; align-items:center; gap:12px; margin-bottom:16px; box-shadow:var(--g-shadow-sm); border-radius:10px; padding:12px 16px; background:#fff; flex-wrap:wrap; }
|
||||
.orf-toolbar .g-select { width:200px; }
|
||||
.orf-toolbar input[type="date"] { height:34px; padding:0 10px; border:1px solid #e5e7eb; border-radius:8px; font-size:13px; outline:none; background:#fff; transition:var(--g-transition); color:var(--g-text); }
|
||||
.orf-toolbar input[type="date"]:focus { border-color:var(--primary); box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 12%, transparent); }
|
||||
.orf-date-sep { color:var(--g-text-muted); font-size:13px; }
|
||||
.orf-search { width:220px; }
|
||||
|
||||
/* 统计卡片 */
|
||||
.orf-stats { display:grid; grid-template-columns:repeat(3,1fr); gap:16px; margin-bottom:16px; }
|
||||
.orf-stat-card { background:#fff; border-radius:10px; padding:18px 20px; box-shadow:var(--g-shadow-sm); display:flex; align-items:flex-start; gap:14px; transition:box-shadow var(--g-transition); }
|
||||
.orf-stat-card:hover { box-shadow:var(--g-shadow-md); }
|
||||
.orf-stat-icon { width:42px; height:42px; border-radius:10px; display:flex; align-items:center; justify-content:center; flex-shrink:0; }
|
||||
.orf-stat-icon.blue { background:color-mix(in srgb, var(--primary) 10%, #fff); color:var(--primary); }
|
||||
.orf-stat-icon.orange { background:color-mix(in srgb, var(--g-warning) 10%, #fff); color:var(--g-warning); }
|
||||
.orf-stat-icon.green { background:color-mix(in srgb, var(--g-success) 10%, #fff); color:var(--g-success); }
|
||||
.orf-stat-body { flex:1; }
|
||||
.orf-stat-label { font-size:12px; color:var(--g-text-muted); margin-bottom:6px; }
|
||||
.orf-stat-value { font-size:22px; font-weight:700; color:var(--g-text); }
|
||||
.orf-stat-trend { font-size:11px; margin-top:4px; display:flex; align-items:center; gap:3px; }
|
||||
.orf-stat-trend.good { color:var(--g-success); }
|
||||
.orf-stat-trend.bad { color:var(--g-danger); }
|
||||
|
||||
/* 表格区域 */
|
||||
.orf-panel { background:#fff; border-radius:10px; box-shadow:var(--g-shadow-sm); padding:16px 18px; }
|
||||
.orf-seg-wrap { margin-bottom:16px; }
|
||||
.orf-table-wrap { overflow-x:auto; }
|
||||
.orf-dimmed { opacity:0.55; }
|
||||
|
||||
/* 抽屉内信息块 */
|
||||
.orf-info-section { margin-bottom:20px; }
|
||||
.orf-info-title { font-size:14px; font-weight:600; color:var(--g-text); padding-left:10px; border-left:3px solid var(--primary); margin-bottom:12px; }
|
||||
.orf-info-grid { display:grid; grid-template-columns:1fr 1fr; gap:8px 24px; }
|
||||
.orf-info-item { display:flex; flex-direction:column; gap:2px; }
|
||||
.orf-info-label { font-size:12px; color:var(--g-text-muted); }
|
||||
.orf-info-value { font-size:13px; color:var(--g-text); font-weight:500; }
|
||||
.orf-reason-text { font-size:13px; color:var(--g-text); line-height:1.6; margin-bottom:10px; }
|
||||
.orf-photo-placeholder { width:80px; height:80px; background:#f8f9fb; border:1px dashed #e5e7eb; border-radius:8px; display:flex; align-items:center; justify-content:center; color:var(--g-text-muted); font-size:11px; text-align:center; line-height:1.3; }
|
||||
.orf-product-row { display:flex; align-items:center; gap:12px; padding:10px 0; border-bottom:1px solid #f3f4f6; }
|
||||
.orf-product-row:last-child { border-bottom:none; }
|
||||
.orf-product-img { width:48px; height:48px; background:#f8f9fb; border-radius:8px; display:flex; align-items:center; justify-content:center; color:var(--g-text-muted); flex-shrink:0; }
|
||||
.orf-product-info { flex:1; }
|
||||
.orf-product-name { font-size:13px; font-weight:500; color:var(--g-text); }
|
||||
.orf-product-spec { font-size:12px; color:var(--g-text-muted); margin-top:2px; }
|
||||
.orf-product-price { font-size:13px; font-weight:600; color:var(--g-text); white-space:nowrap; }
|
||||
|
||||
/* 处理操作 */
|
||||
.orf-action-pills { display:flex; gap:10px; margin-bottom:14px; }
|
||||
.orf-action-pill { padding:8px 20px; border-radius:8px; font-size:13px; cursor:pointer; border:1px solid #e5e7eb; background:#fff; color:var(--g-text-secondary); transition:var(--g-transition); font-weight:500; }
|
||||
.orf-action-pill:hover { border-color:var(--primary); color:var(--primary); }
|
||||
.orf-action-pill.selected-approve { border-color:var(--g-success); background:color-mix(in srgb, var(--g-success) 8%, #fff); color:var(--g-success); }
|
||||
.orf-action-pill.selected-reject { border-color:var(--g-danger); background:color-mix(in srgb, var(--g-danger) 8%, #fff); color:var(--g-danger); }
|
||||
</style>
|
||||
|
||||
<!-- 顶部工具栏 -->
|
||||
<div class="orf-toolbar">
|
||||
<select class="g-select" style="width:200px;">
|
||||
<option>老三家外卖(总店)</option>
|
||||
<option>老三家外卖(朝阳店)</option>
|
||||
<option>老三家外卖(海淀店)</option>
|
||||
<option>老三家外卖(丰台店)</option>
|
||||
<option>老三家外卖(通州店)</option>
|
||||
</select>
|
||||
<input type="date" value="2025-02-01" />
|
||||
<span class="orf-date-sep">至</span>
|
||||
<input type="date" value="2025-02-12" />
|
||||
<input class="g-input orf-search" placeholder="订单号/退款单号" />
|
||||
<div style="flex:1;"></div>
|
||||
<button class="g-btn"><i data-lucide="download" style="width:14px;height:14px;"></i> 导出</button>
|
||||
</div>
|
||||
|
||||
<!-- 统计卡片 -->
|
||||
<div class="orf-stats">
|
||||
<div class="orf-stat-card">
|
||||
<div class="orf-stat-icon blue"><i data-lucide="trending-down" style="width:20px;height:20px;"></i></div>
|
||||
<div class="orf-stat-body">
|
||||
<div class="orf-stat-label">本月退款笔数</div>
|
||||
<div class="orf-stat-value">23</div>
|
||||
<div class="orf-stat-trend good"><i data-lucide="arrow-down-right" style="width:12px;height:12px;"></i> 较上月减少5笔</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="orf-stat-card">
|
||||
<div class="orf-stat-icon orange"><i data-lucide="dollar-sign" style="width:20px;height:20px;"></i></div>
|
||||
<div class="orf-stat-body">
|
||||
<div class="orf-stat-label">本月退款金额</div>
|
||||
<div class="orf-stat-value">¥1,856.00</div>
|
||||
<div class="orf-stat-trend good"><i data-lucide="arrow-down-right" style="width:12px;height:12px;"></i> 较上月↓¥320</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="orf-stat-card">
|
||||
<div class="orf-stat-icon green"><i data-lucide="percent" style="width:20px;height:20px;"></i></div>
|
||||
<div class="orf-stat-body">
|
||||
<div class="orf-stat-label">退款率</div>
|
||||
<div class="orf-stat-value">2.8%</div>
|
||||
<div class="orf-stat-trend good"><i data-lucide="arrow-down-right" style="width:12px;height:12px;"></i> 较上月↓0.3%</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 表格面板 -->
|
||||
<div class="orf-panel">
|
||||
<!-- 分段控制器 -->
|
||||
<div class="orf-seg-wrap">
|
||||
<div class="g-seg">
|
||||
<div class="g-seg-item active" onclick="switchOrfTab(this)" data-tab="pending">待处理(3)</div>
|
||||
<div class="g-seg-item" onclick="switchOrfTab(this)" data-tab="processed">已处理(20)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 待处理表格 -->
|
||||
<div id="orfTabPending" class="orf-table-wrap">
|
||||
<table class="g-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>退款单号</th>
|
||||
<th>关联订单</th>
|
||||
<th>申请时间</th>
|
||||
<th>顾客</th>
|
||||
<th>退款原因</th>
|
||||
<th>退款金额</th>
|
||||
<th style="width:80px;">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="font-weight:500;">RF20250212001</td>
|
||||
<td style="color:var(--primary);cursor:pointer;">#20250212003</td>
|
||||
<td>今天 12:30</td>
|
||||
<td>王**</td>
|
||||
<td>商品与描述不符</td>
|
||||
<td style="font-weight:600;">¥68.00</td>
|
||||
<td>
|
||||
<a class="g-action" onclick="openOrfDrawer('RF20250212001')">处理</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-weight:500;">RF20250212002</td>
|
||||
<td style="color:var(--primary);cursor:pointer;">#20250212005</td>
|
||||
<td>今天 11:45</td>
|
||||
<td>赵**</td>
|
||||
<td>配送超时</td>
|
||||
<td style="font-weight:600;">¥35.00</td>
|
||||
<td>
|
||||
<a class="g-action" onclick="openOrfDrawer('RF20250212002')">处理</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="font-weight:500;">RF20250212003</td>
|
||||
<td style="color:var(--primary);cursor:pointer;">#20250212008</td>
|
||||
<td>今天 10:20</td>
|
||||
<td>孙**</td>
|
||||
<td>少送商品</td>
|
||||
<td style="font-weight:600;">¥15.00</td>
|
||||
<td>
|
||||
<a class="g-action" onclick="openOrfDrawer('RF20250212003')">处理</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="g-pagination">
|
||||
<span style="font-size:13px;color:var(--g-text-secondary);margin-right:12px;">共 3 条</span>
|
||||
<button class="g-page-btn" disabled><i data-lucide="chevron-left" style="width:14px;height:14px;"></i></button>
|
||||
<button class="g-page-btn active">1</button>
|
||||
<button class="g-page-btn" disabled><i data-lucide="chevron-right" style="width:14px;height:14px;"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 已处理表格 -->
|
||||
<div id="orfTabProcessed" class="orf-table-wrap" style="display:none;">
|
||||
<table class="g-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>退款单号</th>
|
||||
<th>关联订单</th>
|
||||
<th>申请时间</th>
|
||||
<th>顾客</th>
|
||||
<th>退款原因</th>
|
||||
<th>退款金额</th>
|
||||
<th>处理结果</th>
|
||||
<th>处理时间</th>
|
||||
<th style="width:60px;">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="font-weight:500;">RF20250211012</td>
|
||||
<td style="color:var(--primary);cursor:pointer;">#20250211018</td>
|
||||
<td>昨天 14:20</td>
|
||||
<td>李**</td>
|
||||
<td>商品质量问题</td>
|
||||
<td style="font-weight:600;">¥42.00</td>
|
||||
<td><span class="g-tag g-tag-green">已退款</span></td>
|
||||
<td>昨天 15:05</td>
|
||||
<td><a class="g-action" onclick="openOrfDrawer('RF20250211012')">详情</a></td>
|
||||
<tr>
|
||||
<td style="font-weight:500;">RF20250211008</td>
|
||||
<td style="color:var(--primary);cursor:pointer;">#20250211010</td>
|
||||
<td>昨天 11:30</td>
|
||||
<td>张**</td>
|
||||
<td>配送超时</td>
|
||||
<td style="font-weight:600;">¥28.50</td>
|
||||
<td><span class="g-tag g-tag-green">已退款</span></td>
|
||||
<td>昨天 12:10</td>
|
||||
<td><a class="g-action" onclick="openOrfDrawer('RF20250211008')">详情</a></td>
|
||||
<tr class="orf-dimmed">
|
||||
<td style="font-weight:500;">RF20250210015</td>
|
||||
<td style="color:var(--primary);cursor:pointer;">#20250210022</td>
|
||||
<td>02-10 16:45</td>
|
||||
<td>周**</td>
|
||||
<td>不想要了</td>
|
||||
<td style="font-weight:600;">¥56.00</td>
|
||||
<td><span class="g-tag g-tag-red">已拒绝</span></td>
|
||||
<td>02-10 17:20</td>
|
||||
<td><a class="g-action" onclick="openOrfDrawer('RF20250210015')">详情</a></td>
|
||||
<tr>
|
||||
<td style="font-weight:500;">RF20250210009</td>
|
||||
<td style="color:var(--primary);cursor:pointer;">#20250210014</td>
|
||||
<td>02-10 12:00</td>
|
||||
<td>吴**</td>
|
||||
<td>少送商品</td>
|
||||
<td style="font-weight:600;">¥18.00</td>
|
||||
<td><span class="g-tag g-tag-green">已退款</span></td>
|
||||
<td>02-10 13:30</td>
|
||||
<td><a class="g-action" onclick="openOrfDrawer('RF20250210009')">详情</a></td>
|
||||
<tr class="orf-dimmed">
|
||||
<td style="font-weight:500;">RF20250209021</td>
|
||||
<td style="color:var(--primary);cursor:pointer;">#20250209030</td>
|
||||
<td>02-09 19:10</td>
|
||||
<td>陈**</td>
|
||||
<td>商品与描述不符</td>
|
||||
<td style="font-weight:600;">¥75.00</td>
|
||||
<td><span class="g-tag g-tag-red">已拒绝</span></td>
|
||||
<td>02-09 20:00</td>
|
||||
<td><a class="g-action" onclick="openOrfDrawer('RF20250209021')">详情</a></td>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="g-pagination">
|
||||
<span style="font-size:13px;color:var(--g-text-secondary);margin-right:12px;">共 20 条</span>
|
||||
<button class="g-page-btn" disabled><i data-lucide="chevron-left" style="width:14px;height:14px;"></i></button>
|
||||
<button class="g-page-btn active">1</button>
|
||||
<button class="g-page-btn">2</button>
|
||||
<button class="g-page-btn">3</button>
|
||||
<button class="g-page-btn">4</button>
|
||||
<button class="g-page-btn"><i data-lucide="chevron-right" style="width:14px;height:14px;"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 退款处理抽屉 -->
|
||||
<div class="g-drawer-mask" id="orfDrawerMask" onclick="closeOrfDrawer()"></div>
|
||||
<div class="g-drawer" id="orfDrawer" style="width:480px;">
|
||||
<div class="g-drawer-hd">
|
||||
<span class="g-drawer-title">退款处理</span>
|
||||
<span class="g-drawer-close" onclick="closeOrfDrawer()"><i data-lucide="x" style="width:18px;height:18px;"></i></span>
|
||||
</div>
|
||||
<div class="g-drawer-bd">
|
||||
<!-- 退款信息 -->
|
||||
<div class="orf-info-section">
|
||||
<div class="orf-info-title">退款信息</div>
|
||||
<div class="orf-info-grid">
|
||||
<div class="orf-info-item">
|
||||
<span class="orf-info-label">退款单号</span>
|
||||
<span class="orf-info-value" id="orfDetailNo">RF20250212001</span>
|
||||
</div>
|
||||
<div class="orf-info-item">
|
||||
<span class="orf-info-label">关联订单</span>
|
||||
<span class="orf-info-value" style="color:var(--primary);cursor:pointer;" id="orfDetailOrder">#20250212003</span>
|
||||
</div>
|
||||
<div class="orf-info-item">
|
||||
<span class="orf-info-label">申请时间</span>
|
||||
<span class="orf-info-value" id="orfDetailTime">今天 12:30</span>
|
||||
</div>
|
||||
<div class="orf-info-item">
|
||||
<span class="orf-info-label">顾客</span>
|
||||
<span class="orf-info-value" id="orfDetailCustomer">王**</span>
|
||||
</div>
|
||||
<div class="orf-info-item">
|
||||
<span class="orf-info-label">退款金额</span>
|
||||
<span class="orf-info-value" style="color:var(--g-danger);font-size:16px;" id="orfDetailAmount">¥68.00</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 退款原因 -->
|
||||
<div class="orf-info-section">
|
||||
<div class="orf-info-title">退款原因</div>
|
||||
<div class="orf-reason-text" id="orfDetailReason">商品与描述不符,收到的菜品和图片差距较大,口味也不对。</div>
|
||||
<div class="orf-photo-placeholder"><i data-lucide="image" style="width:20px;height:20px;margin-bottom:2px;"></i><br/>顾客上传图片</div>
|
||||
</div>
|
||||
|
||||
<!-- 商品信息 -->
|
||||
<div class="orf-info-section">
|
||||
<div class="orf-info-title">商品信息</div>
|
||||
<div class="orf-product-row">
|
||||
<div class="orf-product-img"><i data-lucide="utensils" style="width:20px;height:20px;"></i></div>
|
||||
<div class="orf-product-info">
|
||||
<div class="orf-product-name">香辣鸡腿堡套餐</div>
|
||||
<div class="orf-product-spec">大份 / 微辣 x1</div>
|
||||
</div>
|
||||
<div class="orf-product-price">¥38.00</div>
|
||||
</div>
|
||||
<div class="orf-product-row">
|
||||
<div class="orf-product-img"><i data-lucide="cup-soda" style="width:20px;height:20px;"></i></div>
|
||||
<div class="orf-product-info">
|
||||
<div class="orf-product-name">冰红茶(大杯)</div>
|
||||
<div class="orf-product-spec">加冰 x1</div>
|
||||
</div>
|
||||
<div class="orf-product-price">¥12.00</div>
|
||||
</div>
|
||||
<div class="orf-product-row">
|
||||
<div class="orf-product-img"><i data-lucide="cookie" style="width:20px;height:20px;"></i></div>
|
||||
<div class="orf-product-info">
|
||||
<div class="orf-product-name">蛋挞(2只装)</div>
|
||||
<div class="orf-product-spec">x1</div>
|
||||
</div>
|
||||
<div class="orf-product-price">¥18.00</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 处理操作 -->
|
||||
<div class="orf-info-section">
|
||||
<div class="orf-info-title">处理操作</div>
|
||||
<div class="orf-action-pills">
|
||||
<div class="orf-action-pill" onclick="selectOrfAction(this, 'approve')"><i data-lucide="check" style="width:14px;height:14px;vertical-align:-2px;margin-right:4px;"></i>同意退款</div>
|
||||
<div class="orf-action-pill" onclick="selectOrfAction(this, 'reject')"><i data-lucide="x" style="width:14px;height:14px;vertical-align:-2px;margin-right:4px;"></i>拒绝退款</div>
|
||||
</div>
|
||||
<div id="orfRejectArea" style="display:none;">
|
||||
<div class="g-form-group">
|
||||
<label class="g-form-label required">拒绝原因</label>
|
||||
<textarea class="g-textarea" rows="3" placeholder="请输入拒绝原因,如:商品已确认送达"></textarea>
|
||||
<div class="g-hint">拒绝原因将通知顾客,请认真填写</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="g-drawer-ft">
|
||||
<button class="g-btn" onclick="closeOrfDrawer()">取消</button>
|
||||
<button class="g-btn g-btn-primary">提交</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* 切换待处理/已处理 tab */
|
||||
function switchOrfTab(el) {
|
||||
var tab = el.getAttribute('data-tab');
|
||||
el.parentElement.querySelectorAll('.g-seg-item').forEach(function(item) {
|
||||
item.classList.remove('active');
|
||||
});
|
||||
el.classList.add('active');
|
||||
document.getElementById('orfTabPending').style.display = tab === 'pending' ? '' : 'none';
|
||||
document.getElementById('orfTabProcessed').style.display = tab === 'processed' ? '' : 'none';
|
||||
}
|
||||
|
||||
/* 退款详情数据映射(原型模拟) */
|
||||
var orfMockData = {
|
||||
'RF20250212001': { no:'RF20250212001', order:'#20250212003', time:'今天 12:30', customer:'王**', amount:'¥68.00', reason:'商品与描述不符,收到的菜品和图片差距较大,口味也不对。' },
|
||||
'RF20250212002': { no:'RF20250212002', order:'#20250212005', time:'今天 11:45', customer:'赵**', amount:'¥35.00', reason:'配送超时,等了将近一个小时才送到,食物已经凉了。' },
|
||||
'RF20250212003': { no:'RF20250212003', order:'#20250212008', time:'今天 10:20', customer:'孙**', amount:'¥15.00', reason:'少送了一份蛋挞,订单里有但是没收到。' }
|
||||
};
|
||||
|
||||
/* 打开抽屉 */
|
||||
function openOrfDrawer(refundNo) {
|
||||
var data = orfMockData[refundNo];
|
||||
if (data) {
|
||||
document.getElementById('orfDetailNo').textContent = data.no;
|
||||
document.getElementById('orfDetailOrder').textContent = data.order;
|
||||
document.getElementById('orfDetailTime').textContent = data.time;
|
||||
document.getElementById('orfDetailCustomer').textContent = data.customer;
|
||||
document.getElementById('orfDetailAmount').textContent = data.amount;
|
||||
document.getElementById('orfDetailReason').textContent = data.reason;
|
||||
}
|
||||
/* 重置操作状态 */
|
||||
document.querySelectorAll('.orf-action-pill').forEach(function(p) {
|
||||
p.classList.remove('selected-approve', 'selected-reject');
|
||||
});
|
||||
document.getElementById('orfRejectArea').style.display = 'none';
|
||||
|
||||
document.getElementById('orfDrawerMask').classList.add('open');
|
||||
document.getElementById('orfDrawer').classList.add('open');
|
||||
}
|
||||
|
||||
/* 关闭抽屉 */
|
||||
function closeOrfDrawer() {
|
||||
document.getElementById('orfDrawerMask').classList.remove('open');
|
||||
document.getElementById('orfDrawer').classList.remove('open');
|
||||
}
|
||||
|
||||
/* 选择同意/拒绝 */
|
||||
function selectOrfAction(el, action) {
|
||||
document.querySelectorAll('.orf-action-pill').forEach(function(p) {
|
||||
p.classList.remove('selected-approve', 'selected-reject');
|
||||
});
|
||||
if (action === 'approve') {
|
||||
el.classList.add('selected-approve');
|
||||
document.getElementById('orfRejectArea').style.display = 'none';
|
||||
} else {
|
||||
el.classList.add('selected-reject');
|
||||
document.getElementById('orfRejectArea').style.display = '';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
318
pages/order-settings.html
Normal file
318
pages/order-settings.html
Normal file
@@ -0,0 +1,318 @@
|
||||
<!-- 订单设置页 -->
|
||||
<style>
|
||||
.page-order-settings { max-width:960px; }
|
||||
.os-toolbar { display:flex; align-items:center; gap:12px; margin-bottom:16px; box-shadow:var(--g-shadow-sm); border-radius:10px; padding:10px 14px; background:#fff; }
|
||||
.os-toolbar select { height:34px; padding:0 10px; border:1px solid #e5e7eb; border-radius:8px; font-size:13px; outline:none; background:#fff; transition:var(--g-transition); }
|
||||
.os-toolbar select:focus { border-color:var(--primary); box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 12%, transparent); }
|
||||
.os-toolbar .os-page-title { font-size:15px; font-weight:600; color:var(--g-text); }
|
||||
|
||||
.os-section-hd { font-size:15px; font-weight:600; color:var(--g-text); padding-left:10px; border-left:3px solid var(--primary); margin-bottom:16px; }
|
||||
|
||||
.os-row { display:flex; align-items:flex-start; gap:16px; padding:14px 0; border-bottom:1px solid #f3f4f6; }
|
||||
.os-row:last-child { border-bottom:none; }
|
||||
.os-row-label { width:200px; flex-shrink:0; }
|
||||
.os-row-label .os-label-main { font-size:13px; font-weight:500; color:var(--g-text); }
|
||||
.os-row-label .os-label-sub { font-size:11px; color:var(--g-text-muted); margin-top:2px; }
|
||||
.os-row-ctrl { flex:1; display:flex; flex-direction:column; gap:6px; }
|
||||
.os-row-ctrl-inline { display:flex; align-items:center; gap:8px; }
|
||||
.os-row-hint { font-size:11px; color:var(--g-text-muted); margin-top:2px; }
|
||||
|
||||
.os-num-input { width:120px; height:34px; padding:0 10px; border:1px solid #e5e7eb; border-radius:8px; font-size:13px; outline:none; transition:var(--g-transition); }
|
||||
.os-num-input:focus { border-color:var(--primary); box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 12%, transparent); }
|
||||
.os-text-input { width:160px; height:34px; padding:0 10px; border:1px solid #e5e7eb; border-radius:8px; font-size:13px; outline:none; transition:var(--g-transition); }
|
||||
.os-text-input:focus { border-color:var(--primary); box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 12%, transparent); }
|
||||
.os-suffix { font-size:13px; color:var(--g-text-secondary); white-space:nowrap; }
|
||||
|
||||
.os-select { height:34px; padding:0 10px; border:1px solid #e5e7eb; border-radius:8px; font-size:13px; outline:none; background:#fff; transition:var(--g-transition); min-width:140px; }
|
||||
.os-select:focus { border-color:var(--primary); box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 12%, transparent); }
|
||||
|
||||
.os-checkbox-group { display:flex; flex-wrap:wrap; gap:10px 20px; }
|
||||
.os-checkbox-item { display:flex; align-items:center; gap:6px; cursor:pointer; font-size:13px; color:var(--g-text); }
|
||||
.os-checkbox-item input[type=checkbox] { width:16px; height:16px; accent-color:var(--primary); cursor:pointer; }
|
||||
|
||||
.os-preview { display:inline-flex; align-items:center; gap:6px; padding:8px 14px; background:#f8f9fb; border:1px dashed #e5e7eb; border-radius:8px; font-size:13px; color:var(--g-text-secondary); font-family:monospace; letter-spacing:0.5px; margin-top:4px; }
|
||||
|
||||
.os-save-bar { position:sticky; bottom:0; background:#fff; border-top:1px solid #f0f0f0; padding:14px 18px; display:flex; justify-content:flex-end; gap:8px; margin:0 -18px -20px; border-radius:0 0 10px 10px; }
|
||||
</style>
|
||||
|
||||
<div class="page-order-settings">
|
||||
<!-- 顶部工具栏 -->
|
||||
<div class="os-toolbar">
|
||||
<select style="width:200px;">
|
||||
<option>老三家外卖(朝阳店)</option>
|
||||
<option>老三家外卖(海淀店)</option>
|
||||
<option>老三家外卖(望京店)</option>
|
||||
<option>老三家外卖(通州店)</option>
|
||||
<option>老三家外卖(丰台店)</option>
|
||||
</select>
|
||||
<div style="flex:1;"></div>
|
||||
<span class="os-page-title">订单设置</span>
|
||||
</div>
|
||||
|
||||
<!-- 接单设置 -->
|
||||
<div class="g-card" style="padding:0; margin-bottom:16px;">
|
||||
<div style="padding:18px 18px 0;">
|
||||
<div class="os-section-hd">接单设置</div>
|
||||
</div>
|
||||
<div style="padding:0 18px 18px;">
|
||||
<div class="os-row">
|
||||
<div class="os-row-label"><div class="os-label-main">自动接单</div></div>
|
||||
<div class="os-row-ctrl">
|
||||
<div class="os-row-ctrl-inline">
|
||||
<div class="g-toggle on" onclick="toggleSwitch(this)"></div>
|
||||
<span class="g-toggle-label">开启后新订单将自动接单</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="os-row">
|
||||
<div class="os-row-label"><div class="os-label-main">自动接单延迟</div></div>
|
||||
<div class="os-row-ctrl">
|
||||
<div class="os-row-ctrl-inline">
|
||||
<input type="number" class="os-num-input" placeholder="如:30" value="30" />
|
||||
<span class="os-suffix">秒</span>
|
||||
</div>
|
||||
<div class="os-row-hint">设置自动接单前的等待时间,方便商家提前查看订单</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="os-row">
|
||||
<div class="os-row-label"><div class="os-label-main">默认出餐时间</div></div>
|
||||
<div class="os-row-ctrl">
|
||||
<div class="os-row-ctrl-inline">
|
||||
<input type="number" class="os-num-input" placeholder="如:20" value="20" />
|
||||
<span class="os-suffix">分钟</span>
|
||||
</div>
|
||||
<div class="os-row-hint">预计出餐时间,将展示给顾客</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 超时设置 -->
|
||||
<div class="g-card" style="padding:0; margin-bottom:16px;">
|
||||
<div style="padding:18px 18px 0;">
|
||||
<div class="os-section-hd">超时设置</div>
|
||||
</div>
|
||||
<div style="padding:0 18px 18px;">
|
||||
<div class="os-row">
|
||||
<div class="os-row-label"><div class="os-label-main">未接单自动取消</div></div>
|
||||
<div class="os-row-ctrl">
|
||||
<div class="os-row-ctrl-inline">
|
||||
<input type="number" class="os-num-input" placeholder="如:5" value="5" />
|
||||
<span class="os-suffix">分钟</span>
|
||||
</div>
|
||||
<div class="os-row-hint">超过该时间未接单,订单将自动取消并退款</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="os-row">
|
||||
<div class="os-row-label"><div class="os-label-main">催单提醒阈值</div></div>
|
||||
<div class="os-row-ctrl">
|
||||
<div class="os-row-ctrl-inline">
|
||||
<input type="number" class="os-num-input" placeholder="如:10" value="10" />
|
||||
<span class="os-suffix">分钟</span>
|
||||
</div>
|
||||
<div class="os-row-hint">订单超过该时间未出餐,系统将发送催单提醒</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 提醒设置 -->
|
||||
<div class="g-card" style="padding:0; margin-bottom:16px;">
|
||||
<div style="padding:18px 18px 0;">
|
||||
<div class="os-section-hd">提醒设置</div>
|
||||
</div>
|
||||
<div style="padding:0 18px 18px;">
|
||||
<div class="os-row">
|
||||
<div class="os-row-label"><div class="os-label-main">新订单提示音</div></div>
|
||||
<div class="os-row-ctrl">
|
||||
<div class="os-row-ctrl-inline">
|
||||
<div class="g-toggle on" onclick="toggleSwitch(this)"></div>
|
||||
<span class="g-toggle-label">新订单到达时播放提示音</span>
|
||||
<select class="os-select" style="margin-left:12px;">
|
||||
<option>叮咚提示音</option>
|
||||
<option>语音播报</option>
|
||||
<option>铃声提示</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="os-row">
|
||||
<div class="os-row-label"><div class="os-label-main">催单提示音</div></div>
|
||||
<div class="os-row-ctrl">
|
||||
<div class="os-row-ctrl-inline">
|
||||
<div class="g-toggle on" onclick="toggleSwitch(this)"></div>
|
||||
<span class="g-toggle-label">收到催单时播放提示音</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="os-row">
|
||||
<div class="os-row-label"><div class="os-label-main">退款提醒</div></div>
|
||||
<div class="os-row-ctrl">
|
||||
<div class="os-row-ctrl-inline">
|
||||
<div class="g-toggle on" onclick="toggleSwitch(this)"></div>
|
||||
<span class="g-toggle-label">收到退款申请时提醒</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="os-row">
|
||||
<div class="os-row-label"><div class="os-label-main">爆单预警</div></div>
|
||||
<div class="os-row-ctrl">
|
||||
<div class="os-row-ctrl-inline">
|
||||
<div class="g-toggle" onclick="toggleSwitch(this)"></div>
|
||||
<span class="g-toggle-label">当待处理订单超过阈值时预警</span>
|
||||
</div>
|
||||
<div class="os-row-hint">开启后,待处理订单数量超过设定值时将发出预警通知</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="os-row">
|
||||
<div class="os-row-label"><div class="os-label-main">预警阈值</div></div>
|
||||
<div class="os-row-ctrl">
|
||||
<div class="os-row-ctrl-inline">
|
||||
<input type="number" class="os-num-input" placeholder="如:20" value="20" />
|
||||
<span class="os-suffix">单</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 打印设置 -->
|
||||
<div class="g-card" style="padding:0; margin-bottom:16px;">
|
||||
<div style="padding:18px 18px 0;">
|
||||
<div class="os-section-hd">打印设置</div>
|
||||
</div>
|
||||
<div style="padding:0 18px 18px;">
|
||||
<div class="os-row">
|
||||
<div class="os-row-label"><div class="os-label-main">自动打印</div></div>
|
||||
<div class="os-row-ctrl">
|
||||
<div class="os-row-ctrl-inline">
|
||||
<div class="g-toggle on" onclick="toggleSwitch(this)"></div>
|
||||
<span class="g-toggle-label">接单后自动打印小票</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="os-row">
|
||||
<div class="os-row-label"><div class="os-label-main">打印份数</div></div>
|
||||
<div class="os-row-ctrl">
|
||||
<div class="os-row-ctrl-inline">
|
||||
<input type="number" class="os-num-input" placeholder="如:2" value="2" min="1" />
|
||||
<span class="os-suffix">份</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="os-row">
|
||||
<div class="os-row-label"><div class="os-label-main">小票模板</div></div>
|
||||
<div class="os-row-ctrl">
|
||||
<div class="os-row-ctrl-inline">
|
||||
<span class="g-pill checked" onclick="selectOsTemplate(this)">标准模板</span>
|
||||
<span class="g-pill" onclick="selectOsTemplate(this)">简洁模板</span>
|
||||
<span class="g-pill" onclick="selectOsTemplate(this)">详细模板</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="os-row">
|
||||
<div class="os-row-label"><div class="os-label-main">打印内容</div></div>
|
||||
<div class="os-row-ctrl">
|
||||
<div class="os-checkbox-group">
|
||||
<label class="os-checkbox-item"><input type="checkbox" checked />订单号</label>
|
||||
<label class="os-checkbox-item"><input type="checkbox" checked />下单时间</label>
|
||||
<label class="os-checkbox-item"><input type="checkbox" checked />顾客信息</label>
|
||||
<label class="os-checkbox-item"><input type="checkbox" checked />商品明细</label>
|
||||
<label class="os-checkbox-item"><input type="checkbox" checked />备注</label>
|
||||
<label class="os-checkbox-item"><input type="checkbox" checked />配送信息</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="os-row">
|
||||
<div class="os-row-label"><div class="os-label-main">后厨联</div></div>
|
||||
<div class="os-row-ctrl">
|
||||
<div class="os-row-ctrl-inline">
|
||||
<div class="g-toggle on" onclick="toggleSwitch(this)"></div>
|
||||
<span class="g-toggle-label">同时打印后厨联(仅含商品和备注)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 订单编号 -->
|
||||
<div class="g-card" style="padding:0; margin-bottom:16px;">
|
||||
<div style="padding:18px 18px 0;">
|
||||
<div class="os-section-hd">订单编号</div>
|
||||
</div>
|
||||
<div style="padding:0 18px 18px;">
|
||||
<div class="os-row">
|
||||
<div class="os-row-label"><div class="os-label-main">编号前缀</div></div>
|
||||
<div class="os-row-ctrl">
|
||||
<div class="os-row-ctrl-inline">
|
||||
<input type="text" class="os-text-input" placeholder="如:DD" value="DD" id="osPrefix" oninput="updateOsPreview()" />
|
||||
</div>
|
||||
<div class="os-row-hint">订单号将以此前缀开头,如 DD20250212001</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="os-row">
|
||||
<div class="os-row-label"><div class="os-label-main">流水号位数</div></div>
|
||||
<div class="os-row-ctrl">
|
||||
<div class="os-row-ctrl-inline">
|
||||
<select class="os-select" id="osDigits" onchange="updateOsPreview()">
|
||||
<option value="4">4位</option>
|
||||
<option value="6" selected>6位</option>
|
||||
<option value="8">8位</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="os-row">
|
||||
<div class="os-row-label"><div class="os-label-main">每日重置</div></div>
|
||||
<div class="os-row-ctrl">
|
||||
<div class="os-row-ctrl-inline">
|
||||
<div class="g-toggle on" onclick="toggleSwitch(this)"></div>
|
||||
<span class="g-toggle-label">每天从001开始重新编号</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="os-row">
|
||||
<div class="os-row-label"><div class="os-label-main">编号预览</div></div>
|
||||
<div class="os-row-ctrl">
|
||||
<div class="os-preview" id="osPreviewBox">
|
||||
<i data-lucide="hash" style="width:14px;height:14px;opacity:0.4;"></i>
|
||||
<span id="osPreviewText">DD250212000001</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部保存栏 -->
|
||||
<div class="g-card" style="padding:14px 18px; margin-bottom:16px;">
|
||||
<div style="display:flex; justify-content:flex-end; gap:8px;">
|
||||
<button class="g-btn"><i data-lucide="rotate-ccw" style="width:14px;height:14px;"></i>重置</button>
|
||||
<button class="g-btn g-btn-primary"><i data-lucide="save" style="width:14px;height:14px;"></i>保存设置</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function toggleSwitch(el) {
|
||||
el.classList.toggle('on');
|
||||
}
|
||||
|
||||
function selectOsTemplate(el) {
|
||||
el.parentElement.querySelectorAll('.g-pill').forEach(function(p) { p.classList.remove('checked'); });
|
||||
el.classList.add('checked');
|
||||
}
|
||||
|
||||
function updateOsPreview() {
|
||||
var prefix = document.getElementById('osPrefix').value || 'DD';
|
||||
var digits = parseInt(document.getElementById('osDigits').value) || 6;
|
||||
var now = new Date();
|
||||
var y = String(now.getFullYear()).slice(2);
|
||||
var m = String(now.getMonth() + 1).padStart(2, '0');
|
||||
var d = String(now.getDate()).padStart(2, '0');
|
||||
var seq = '1'.padStart(digits, '0');
|
||||
document.getElementById('osPreviewText').textContent = prefix + y + m + d + seq;
|
||||
}
|
||||
|
||||
/* 初始化 Lucide 图标 */
|
||||
if (typeof lucide !== 'undefined') { lucide.createIcons(); }
|
||||
</script>
|
||||
549
pages/reviews.html
Normal file
549
pages/reviews.html
Normal file
@@ -0,0 +1,549 @@
|
||||
<!-- 评价管理 — reviews.html -->
|
||||
<style>
|
||||
/* ---- page-private: rv- prefix ---- */
|
||||
.rv-toolbar {
|
||||
background: #fff; border-radius: var(--g-radius); padding: 16px 20px;
|
||||
display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
|
||||
box-shadow: var(--g-shadow-sm); border: 1px solid var(--g-border);
|
||||
}
|
||||
.rv-toolbar .g-select,
|
||||
.rv-toolbar .g-input { height: 32px; font-size: 13px; }
|
||||
.rv-search-wrap {
|
||||
position: relative; width: 200px;
|
||||
}
|
||||
.rv-search-wrap .g-input { padding-left: 30px; width: 100%; }
|
||||
.rv-search-wrap i {
|
||||
position: absolute; left: 8px; top: 50%; transform: translateY(-50%);
|
||||
color: var(--g-text-muted); pointer-events: none;
|
||||
}
|
||||
.rv-toolbar-right { margin-left: auto; }
|
||||
.rv-date-sep { color: var(--g-text-muted); font-size: 13px; line-height: 32px; }
|
||||
|
||||
/* stats row */
|
||||
.rv-stats { display: flex; gap: 16px; margin-top: 12px; }
|
||||
.rv-stat-card {
|
||||
flex: 1; background: #fff; border-radius: var(--g-radius); border: 1px solid var(--g-border);
|
||||
padding: 18px 20px; box-shadow: var(--g-shadow-sm);
|
||||
transition: box-shadow var(--g-transition);
|
||||
}
|
||||
.rv-stat-card:hover { box-shadow: var(--g-shadow-md); }
|
||||
.rv-stat-value { font-size: 28px; font-weight: 700; color: var(--g-text); line-height: 1.2; }
|
||||
.rv-stat-value.green { color: var(--g-success); }
|
||||
.rv-stat-value.orange { color: var(--g-warning); }
|
||||
.rv-stat-value.primary { color: var(--primary); }
|
||||
.rv-stat-label { font-size: 12px; color: var(--g-text-muted); margin-top: 6px; }
|
||||
.rv-stat-title { font-size: 13px; color: var(--g-text-secondary); margin-bottom: 8px; font-weight: 500; }
|
||||
.rv-stars-inline { display: inline-flex; gap: 2px; vertical-align: middle; margin-left: 6px; }
|
||||
.rv-stars-inline i { width: 16px; height: 16px; }
|
||||
|
||||
/* distribution card */
|
||||
.rv-dist {
|
||||
background: #fff; border-radius: var(--g-radius); border: 1px solid var(--g-border);
|
||||
padding: 20px 24px; margin-top: 12px; box-shadow: var(--g-shadow-sm);
|
||||
}
|
||||
.rv-dist-title {
|
||||
font-size: 15px; font-weight: 600; color: var(--g-text);
|
||||
padding-left: 10px; border-left: 3px solid var(--primary); margin-bottom: 16px;
|
||||
}
|
||||
.rv-dist-row {
|
||||
display: flex; align-items: center; gap: 12px; margin-bottom: 10px; font-size: 13px;
|
||||
}
|
||||
.rv-dist-row:last-child { margin-bottom: 0; }
|
||||
.rv-dist-label { width: 32px; color: var(--g-text-secondary); flex-shrink: 0; text-align: right; }
|
||||
.rv-dist-bar {
|
||||
flex: 1; height: 18px; background: #f5f5f5; border-radius: 9px; overflow: hidden;
|
||||
}
|
||||
.rv-dist-fill {
|
||||
height: 100%; border-radius: 9px; transition: width var(--g-transition);
|
||||
}
|
||||
.rv-dist-fill.green { background: var(--g-success); }
|
||||
.rv-dist-fill.yellow { background: var(--g-warning); }
|
||||
.rv-dist-fill.red { background: var(--g-danger); }
|
||||
.rv-dist-count { width: 36px; color: var(--g-text); font-weight: 500; text-align: right; flex-shrink: 0; }
|
||||
.rv-dist-pct { width: 48px; color: var(--g-text-muted); text-align: right; flex-shrink: 0; }
|
||||
|
||||
/* review list */
|
||||
.rv-list {
|
||||
margin-top: 12px;
|
||||
background: #fff; border-radius: var(--g-radius); border: 1px solid var(--g-border);
|
||||
box-shadow: var(--g-shadow-sm); overflow: hidden;
|
||||
}
|
||||
.rv-list-hd {
|
||||
font-size: 15px; font-weight: 600; color: var(--g-text);
|
||||
padding: 18px 24px 0; margin-bottom: 4px;
|
||||
display: flex; align-items: center;
|
||||
padding-left: 34px;
|
||||
}
|
||||
.rv-list-hd::before {
|
||||
content: ''; display: inline-block; width: 3px; height: 16px;
|
||||
background: var(--primary); border-radius: 2px; margin-right: 10px; margin-left: -10px;
|
||||
}
|
||||
.rv-card {
|
||||
padding: 18px 24px; border-bottom: 1px solid #f5f5f5;
|
||||
transition: background var(--g-transition);
|
||||
}
|
||||
.rv-card:last-child { border-bottom: none; }
|
||||
.rv-card:hover { background: color-mix(in srgb, var(--primary) 2%, #fff); }
|
||||
.rv-card-hd {
|
||||
display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 8px;
|
||||
}
|
||||
.rv-stars { display: inline-flex; gap: 2px; }
|
||||
.rv-star { width: 14px; height: 14px; }
|
||||
.rv-star.filled { color: #faad14; }
|
||||
.rv-star.empty { color: #e5e7eb; }
|
||||
.rv-star.half { color: #faad14; }
|
||||
.rv-customer { font-size: 13px; font-weight: 500; color: var(--g-text); }
|
||||
.rv-time { font-size: 12px; color: var(--g-text-muted); }
|
||||
.rv-order-link {
|
||||
font-size: 12px; color: var(--primary); cursor: pointer; font-family: monospace;
|
||||
text-decoration: none;
|
||||
}
|
||||
.rv-order-link:hover { text-decoration: underline; }
|
||||
.rv-content { font-size: 13px; color: var(--g-text); line-height: 1.6; margin-bottom: 10px; }
|
||||
.rv-images { display: flex; gap: 8px; margin-bottom: 10px; }
|
||||
.rv-img-placeholder {
|
||||
width: 60px; height: 60px; background: #f5f5f5; border-radius: var(--g-radius-sm);
|
||||
border: 1px solid var(--g-border); display: flex; align-items: center; justify-content: center;
|
||||
font-size: 11px; color: var(--g-text-muted);
|
||||
}
|
||||
.rv-products { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
|
||||
.rv-product-tag {
|
||||
display: inline-block; padding: 2px 10px; border-radius: 12px;
|
||||
background: #f5f5f5; font-size: 12px; color: var(--g-text-secondary); border: 1px solid var(--g-border);
|
||||
}
|
||||
.rv-reply-box {
|
||||
background: var(--g-bg-subtle); border-radius: var(--g-radius-sm);
|
||||
padding: 10px 14px; font-size: 13px; color: var(--g-text-secondary);
|
||||
border: 1px solid var(--g-border); margin-top: 4px;
|
||||
}
|
||||
.rv-reply-prefix { font-weight: 600; color: var(--g-text); margin-right: 4px; }
|
||||
.rv-reply-time { font-size: 11px; color: var(--g-text-muted); margin-top: 4px; }
|
||||
|
||||
/* drawer */
|
||||
.rv-drawer { width: 480px; }
|
||||
.rv-section { margin-bottom: 20px; }
|
||||
.rv-section-hd {
|
||||
font-size: 14px; font-weight: 600; color: var(--g-text);
|
||||
padding-left: 10px; border-left: 3px solid var(--primary); margin-bottom: 14px;
|
||||
}
|
||||
.rv-info-row {
|
||||
display: flex; gap: 10px; font-size: 13px; margin-bottom: 8px; align-items: center;
|
||||
}
|
||||
.rv-info-label { color: var(--g-text-muted); width: 70px; flex-shrink: 0; }
|
||||
.rv-info-val { color: var(--g-text); }
|
||||
.rv-quick-replies { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
|
||||
.rv-quick-reply {
|
||||
display: inline-block; padding: 5px 12px; border-radius: 14px;
|
||||
border: 1px solid #d9d9d9; font-size: 12px; cursor: pointer;
|
||||
background: #fff; color: var(--g-text-secondary);
|
||||
transition: all var(--g-transition); user-select: none;
|
||||
}
|
||||
.rv-quick-reply:hover {
|
||||
border-color: var(--primary); color: var(--primary);
|
||||
background: color-mix(in srgb, var(--primary) 6%, #fff);
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- 顶部筛选栏 -->
|
||||
<div class="rv-toolbar">
|
||||
<select class="g-select" style="width:200px;">
|
||||
<option>全部门店</option>
|
||||
<option>老三家外卖(朝阳店)</option>
|
||||
<option>老三家外卖(海淀店)</option>
|
||||
<option>老三家外卖(望京店)</option>
|
||||
<option>老三家外卖(通州店)</option>
|
||||
<option>老三家外卖(丰台店)</option>
|
||||
</select>
|
||||
<select class="g-select" style="width:120px;" onchange="filterRvStars()">
|
||||
<option>全部评分</option>
|
||||
<option>5星</option>
|
||||
<option>4星</option>
|
||||
<option>3星</option>
|
||||
<option>2星</option>
|
||||
<option>1星</option>
|
||||
</select>
|
||||
<select class="g-select" style="width:120px;">
|
||||
<option>全部状态</option>
|
||||
<option>待回复</option>
|
||||
<option>已回复</option>
|
||||
</select>
|
||||
<input type="date" class="g-input" style="width:145px;" value="2025-01-01">
|
||||
<span class="rv-date-sep">~</span>
|
||||
<input type="date" class="g-input" style="width:145px;" value="2025-02-12">
|
||||
<div class="rv-search-wrap">
|
||||
<i data-lucide="search" style="width:14px;height:14px;"></i>
|
||||
<input class="g-input" placeholder="搜索评价内容/订单号">
|
||||
</div>
|
||||
<div class="rv-toolbar-right">
|
||||
<button class="g-btn">
|
||||
<i data-lucide="download" style="width:14px;height:14px;"></i> 导出
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 统计卡片 -->
|
||||
<div class="rv-stats">
|
||||
<div class="rv-stat-card">
|
||||
<div class="rv-stat-title">综合评分</div>
|
||||
<div class="rv-stat-value">
|
||||
4.8
|
||||
<span class="rv-stars-inline">
|
||||
<i data-lucide="star" style="fill:#faad14;color:#faad14;"></i>
|
||||
<i data-lucide="star" style="fill:#faad14;color:#faad14;"></i>
|
||||
<i data-lucide="star" style="fill:#faad14;color:#faad14;"></i>
|
||||
<i data-lucide="star" style="fill:#faad14;color:#faad14;"></i>
|
||||
<i data-lucide="star-half" style="fill:#faad14;color:#faad14;"></i>
|
||||
</span>
|
||||
</div>
|
||||
<div class="rv-stat-label">共 856 条评价</div>
|
||||
</div>
|
||||
<div class="rv-stat-card">
|
||||
<div class="rv-stat-title">好评率</div>
|
||||
<div class="rv-stat-value green">96.2%</div>
|
||||
<div class="rv-stat-label">5星+4星占比</div>
|
||||
</div>
|
||||
<div class="rv-stat-card">
|
||||
<div class="rv-stat-title">待回复</div>
|
||||
<div class="rv-stat-value orange">12</div>
|
||||
<div class="rv-stat-label">建议24小时内回复</div>
|
||||
</div>
|
||||
<div class="rv-stat-card">
|
||||
<div class="rv-stat-title">本月评价</div>
|
||||
<div class="rv-stat-value primary">128</div>
|
||||
<div class="rv-stat-label">较上月 ↑15%</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 评分分布 -->
|
||||
<div class="rv-dist">
|
||||
<div class="rv-dist-title">评分分布</div>
|
||||
<div class="rv-dist-row">
|
||||
<span class="rv-dist-label">5星</span>
|
||||
<div class="rv-dist-bar"><div class="rv-dist-fill green" style="width:79.4%;"></div></div>
|
||||
<span class="rv-dist-count">680</span>
|
||||
<span class="rv-dist-pct">79.4%</span>
|
||||
</div>
|
||||
<div class="rv-dist-row">
|
||||
<span class="rv-dist-label">4星</span>
|
||||
<div class="rv-dist-bar"><div class="rv-dist-fill green" style="width:16.8%;"></div></div>
|
||||
<span class="rv-dist-count">144</span>
|
||||
<span class="rv-dist-pct">16.8%</span>
|
||||
</div>
|
||||
<div class="rv-dist-row">
|
||||
<span class="rv-dist-label">3星</span>
|
||||
<div class="rv-dist-bar"><div class="rv-dist-fill yellow" style="width:2.1%;"></div></div>
|
||||
<span class="rv-dist-count">18</span>
|
||||
<span class="rv-dist-pct">2.1%</span>
|
||||
</div>
|
||||
<div class="rv-dist-row">
|
||||
<span class="rv-dist-label">2星</span>
|
||||
<div class="rv-dist-bar"><div class="rv-dist-fill red" style="width:0.9%;"></div></div>
|
||||
<span class="rv-dist-count">8</span>
|
||||
<span class="rv-dist-pct">0.9%</span>
|
||||
</div>
|
||||
<div class="rv-dist-row">
|
||||
<span class="rv-dist-label">1星</span>
|
||||
<div class="rv-dist-bar"><div class="rv-dist-fill red" style="width:0.7%;"></div></div>
|
||||
<span class="rv-dist-count">6</span>
|
||||
<span class="rv-dist-pct">0.7%</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 评价列表 -->
|
||||
<div class="rv-list">
|
||||
<div class="rv-list-hd">评价列表</div>
|
||||
|
||||
<!-- 评价 1: 5星, 已回复 -->
|
||||
<div class="rv-card">
|
||||
<div class="rv-card-hd">
|
||||
<div class="rv-stars">
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;"></i>
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;"></i>
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;"></i>
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;"></i>
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;"></i>
|
||||
</div>
|
||||
<span class="rv-customer">张**</span>
|
||||
<span class="rv-time">2025-02-12 12:30</span>
|
||||
<span class="g-tag g-tag-blue">外卖</span>
|
||||
<a class="rv-order-link">#20250212001</a>
|
||||
</div>
|
||||
<div class="rv-content">味道很好,配送也快,下次还会点!</div>
|
||||
<div class="rv-products">
|
||||
<span class="rv-product-tag">宫保鸡丁</span>
|
||||
<span class="rv-product-tag">米饭</span>
|
||||
<span class="rv-product-tag">可乐</span>
|
||||
</div>
|
||||
<div class="rv-reply-box">
|
||||
<span class="rv-reply-prefix">商家回复:</span>感谢您的好评,您的满意是我们最大的动力!期待下次为您服务~
|
||||
<div class="rv-reply-time">2025-02-12 14:00</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 评价 2: 5星, 已回复 -->
|
||||
<div class="rv-card">
|
||||
<div class="rv-card-hd">
|
||||
<div class="rv-stars">
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;"></i>
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;"></i>
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;"></i>
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;"></i>
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;"></i>
|
||||
</div>
|
||||
<span class="rv-customer">李**</span>
|
||||
<span class="rv-time">2025-02-12 11:45</span>
|
||||
<span class="g-tag g-tag-green">自提</span>
|
||||
<a class="rv-order-link">#20250212002</a>
|
||||
</div>
|
||||
<div class="rv-content">套餐很划算,分量足,味道也不错,性价比很高。</div>
|
||||
<div class="rv-products">
|
||||
<span class="rv-product-tag">双人超值套餐</span>
|
||||
<span class="rv-product-tag">酸梅汤</span>
|
||||
</div>
|
||||
<div class="rv-reply-box">
|
||||
<span class="rv-reply-prefix">商家回复:</span>感谢您的支持!我们会继续保持品质,欢迎再次光临!
|
||||
<div class="rv-reply-time">2025-02-12 13:20</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 评价 3: 4星, 待回复 -->
|
||||
<div class="rv-card">
|
||||
<div class="rv-card-hd">
|
||||
<div class="rv-stars">
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;"></i>
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;"></i>
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;"></i>
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;"></i>
|
||||
<i data-lucide="star" class="rv-star empty" style="color:#e5e7eb;"></i>
|
||||
</div>
|
||||
<span class="rv-customer">王**</span>
|
||||
<span class="rv-time">2025-02-11 18:20</span>
|
||||
<span class="g-tag g-tag-orange">堂食</span>
|
||||
<a class="rv-order-link">#20250211008</a>
|
||||
<span class="g-tag g-tag-orange">待回复</span>
|
||||
</div>
|
||||
<div class="rv-content">菜品不错,就是等了比较久,高峰期可以理解,希望能优化一下出餐速度。</div>
|
||||
<div class="rv-products">
|
||||
<span class="rv-product-tag">红烧肉套餐</span>
|
||||
<span class="rv-product-tag">紫菜蛋花汤</span>
|
||||
</div>
|
||||
<div style="margin-top:8px;">
|
||||
<button class="g-btn g-btn-sm" onclick="openRvDrawer('rv3')">
|
||||
<i data-lucide="message-square" style="width:12px;height:12px;"></i> 回复
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 评价 4: 3星, 待回复, 有图片 -->
|
||||
<div class="rv-card">
|
||||
<div class="rv-card-hd">
|
||||
<div class="rv-stars">
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;"></i>
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;"></i>
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;"></i>
|
||||
<i data-lucide="star" class="rv-star empty" style="color:#e5e7eb;"></i>
|
||||
<i data-lucide="star" class="rv-star empty" style="color:#e5e7eb;"></i>
|
||||
</div>
|
||||
<span class="rv-customer">赵**</span>
|
||||
<span class="rv-time">2025-02-11 12:50</span>
|
||||
<span class="g-tag g-tag-blue">外卖</span>
|
||||
<a class="rv-order-link">#20250211005</a>
|
||||
<span class="g-tag g-tag-orange">待回复</span>
|
||||
</div>
|
||||
<div class="rv-content">包装有点漏了,汤洒了一些出来,味道还行但体验打了折扣。</div>
|
||||
<div class="rv-images">
|
||||
<div class="rv-img-placeholder"><i data-lucide="image" style="width:16px;height:16px;"></i></div>
|
||||
<div class="rv-img-placeholder"><i data-lucide="image" style="width:16px;height:16px;"></i></div>
|
||||
<div class="rv-img-placeholder"><i data-lucide="image" style="width:16px;height:16px;"></i></div>
|
||||
</div>
|
||||
<div class="rv-products">
|
||||
<span class="rv-product-tag">番茄牛腩面</span>
|
||||
<span class="rv-product-tag">卤蛋</span>
|
||||
</div>
|
||||
<div style="margin-top:8px;">
|
||||
<button class="g-btn g-btn-sm" onclick="openRvDrawer('rv4')">
|
||||
<i data-lucide="message-square" style="width:12px;height:12px;"></i> 回复
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 评价 5: 2星, 待回复 -->
|
||||
<div class="rv-card">
|
||||
<div class="rv-card-hd">
|
||||
<div class="rv-stars">
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;"></i>
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;"></i>
|
||||
<i data-lucide="star" class="rv-star empty" style="color:#e5e7eb;"></i>
|
||||
<i data-lucide="star" class="rv-star empty" style="color:#e5e7eb;"></i>
|
||||
<i data-lucide="star" class="rv-star empty" style="color:#e5e7eb;"></i>
|
||||
</div>
|
||||
<span class="rv-customer">孙**</span>
|
||||
<span class="rv-time">2025-02-10 19:30</span>
|
||||
<span class="g-tag g-tag-blue">外卖</span>
|
||||
<a class="rv-order-link">#20250210012</a>
|
||||
<span class="g-tag g-tag-orange">待回复</span>
|
||||
</div>
|
||||
<div class="rv-content">配送太慢了,等了将近一个小时,饭都凉了,体验很差。</div>
|
||||
<div class="rv-products">
|
||||
<span class="rv-product-tag">鱼香肉丝盖饭</span>
|
||||
<span class="rv-product-tag">米饭</span>
|
||||
</div>
|
||||
<div style="margin-top:8px;">
|
||||
<button class="g-btn g-btn-sm" onclick="openRvDrawer('rv5')">
|
||||
<i data-lucide="message-square" style="width:12px;height:12px;"></i> 回复
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 评价 6: 5星, 已回复 -->
|
||||
<div class="rv-card">
|
||||
<div class="rv-card-hd">
|
||||
<div class="rv-stars">
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;"></i>
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;"></i>
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;"></i>
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;"></i>
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;"></i>
|
||||
</div>
|
||||
<span class="rv-customer">周**</span>
|
||||
<span class="rv-time">2025-02-10 12:15</span>
|
||||
<span class="g-tag g-tag-green">自提</span>
|
||||
<a class="rv-order-link">#20250210003</a>
|
||||
</div>
|
||||
<div class="rv-content">每次来都很满意,老顾客了,菜品质量一直很稳定,值得推荐!</div>
|
||||
<div class="rv-products">
|
||||
<span class="rv-product-tag">招牌红烧肉</span>
|
||||
<span class="rv-product-tag">清炒时蔬</span>
|
||||
<span class="rv-product-tag">米饭</span>
|
||||
</div>
|
||||
<div class="rv-reply-box">
|
||||
<span class="rv-reply-prefix">商家回复:</span>感谢老顾客的一直支持!我们会继续努力,期待每次为您服务!
|
||||
<div class="rv-reply-time">2025-02-10 15:30</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="g-pagination">
|
||||
<span>共 856 条</span>
|
||||
<button class="g-page-btn" disabled><</button>
|
||||
<button class="g-page-btn active">1</button>
|
||||
<button class="g-page-btn">2</button>
|
||||
<button class="g-page-btn">3</button>
|
||||
<button class="g-page-btn">...</button>
|
||||
<button class="g-page-btn">86</button>
|
||||
<button class="g-page-btn">></button>
|
||||
</div>
|
||||
|
||||
<!-- 回复抽屉 -->
|
||||
<div class="g-drawer-mask" id="rvDrawerMask" onclick="closeRvDrawer()"></div>
|
||||
<div class="g-drawer rv-drawer" id="rvDrawer">
|
||||
<div class="g-drawer-hd">
|
||||
<span class="g-drawer-title">回复评价</span>
|
||||
<button class="g-drawer-close" onclick="closeRvDrawer()">×</button>
|
||||
</div>
|
||||
<div class="g-drawer-bd">
|
||||
<!-- 评价信息 -->
|
||||
<div class="rv-section">
|
||||
<div class="rv-section-hd">评价信息</div>
|
||||
<div class="rv-info-row">
|
||||
<span class="rv-info-label">评分</span>
|
||||
<span class="rv-info-val">
|
||||
<span class="rv-stars">
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;width:14px;height:14px;"></i>
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;width:14px;height:14px;"></i>
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;width:14px;height:14px;"></i>
|
||||
<i data-lucide="star" class="rv-star filled" style="fill:#faad14;color:#faad14;width:14px;height:14px;"></i>
|
||||
<i data-lucide="star" class="rv-star empty" style="color:#e5e7eb;width:14px;height:14px;"></i>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="rv-info-row">
|
||||
<span class="rv-info-label">顾客</span>
|
||||
<span class="rv-info-val">王**</span>
|
||||
</div>
|
||||
<div class="rv-info-row">
|
||||
<span class="rv-info-label">时间</span>
|
||||
<span class="rv-info-val">2025-02-11 18:20</span>
|
||||
</div>
|
||||
<div class="rv-info-row" style="align-items:flex-start;">
|
||||
<span class="rv-info-label">内容</span>
|
||||
<span class="rv-info-val">菜品不错,就是等了比较久,高峰期可以理解,希望能优化一下出餐速度。</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 关联订单 -->
|
||||
<div class="rv-section">
|
||||
<div class="rv-section-hd">关联订单</div>
|
||||
<div class="rv-info-row">
|
||||
<span class="rv-info-label">订单号</span>
|
||||
<span class="rv-info-val"><a class="rv-order-link">#20250211008</a></span>
|
||||
</div>
|
||||
<div class="rv-info-row">
|
||||
<span class="rv-info-label">渠道</span>
|
||||
<span class="rv-info-val"><span class="g-tag g-tag-orange">堂食</span></span>
|
||||
</div>
|
||||
<div class="rv-info-row">
|
||||
<span class="rv-info-label">金额</span>
|
||||
<span class="rv-info-val" style="font-weight:600;">¥68.00</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 商品 -->
|
||||
<div class="rv-section">
|
||||
<div class="rv-section-hd">商品</div>
|
||||
<div class="rv-products">
|
||||
<span class="rv-product-tag">红烧肉套餐</span>
|
||||
<span class="rv-product-tag">紫菜蛋花汤</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 回复内容 -->
|
||||
<div class="rv-section">
|
||||
<div class="rv-section-hd">回复内容</div>
|
||||
<div class="g-form-group">
|
||||
<textarea class="g-textarea" id="rvReplyText" rows="4" placeholder="请输入回复内容,建议真诚友好地回应顾客反馈"></textarea>
|
||||
</div>
|
||||
<div class="g-hint" style="margin-bottom:10px;">快捷回复</div>
|
||||
<div class="rv-quick-replies">
|
||||
<span class="rv-quick-reply" onclick="fillQuickReply('感谢您的好评,期待下次光临!')">感谢您的好评,期待下次光临!</span>
|
||||
<span class="rv-quick-reply" onclick="fillQuickReply('非常抱歉给您带来不好的体验,我们会改进!')">非常抱歉给您带来不好的体验,我们会改进!</span>
|
||||
<span class="rv-quick-reply" onclick="fillQuickReply('感谢反馈,已记录并会尽快优化!')">感谢反馈,已记录并会尽快优化!</span>
|
||||
<span class="rv-quick-reply" onclick="fillQuickReply('谢谢支持,欢迎再次光临!')">谢谢支持,欢迎再次光临!</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="g-drawer-ft">
|
||||
<button class="g-btn" onclick="closeRvDrawer()">取消</button>
|
||||
<button class="g-btn g-btn-primary" onclick="closeRvDrawer()">发送回复</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* 抽屉开关 */
|
||||
function openRvDrawer(reviewId) {
|
||||
document.getElementById('rvDrawerMask').classList.add('open');
|
||||
document.getElementById('rvDrawer').classList.add('open');
|
||||
}
|
||||
function closeRvDrawer() {
|
||||
document.getElementById('rvDrawerMask').classList.remove('open');
|
||||
document.getElementById('rvDrawer').classList.remove('open');
|
||||
document.getElementById('rvReplyText').value = '';
|
||||
}
|
||||
|
||||
/* 快捷回复 */
|
||||
function fillQuickReply(text) {
|
||||
document.getElementById('rvReplyText').value = text;
|
||||
document.getElementById('rvReplyText').focus();
|
||||
}
|
||||
|
||||
/* 评分筛选(占位) */
|
||||
function filterRvStars() {
|
||||
// 原型占位,无真实逻辑
|
||||
}
|
||||
|
||||
/* 初始化 Lucide 图标 */
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
if (typeof lucide !== 'undefined') { lucide.createIcons(); }
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user