Files
TakeoutSaaS.Prototypes/pages/mkt-coupon.html

490 lines
20 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<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">&yen;</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">&yen;</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>&lt;</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">&gt;</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>