Files
TakeoutSaaS.Prototypes/pages/mkt-reduction.html
MSuMshk 7463c595a2 feat: 新增订单管理、评价管理、营销中心、会员中心模块
- 订单管理(4页): 订单大厅(看板)、全部订单、退款售后、订单设置
- 评价管理(1页): 评价列表+统计+回复抽屉
- 营销中心(5页): 优惠券、满减活动、限时折扣(含周期循环)、秒杀活动、新客有礼
- 会员中心(5页): 会员管理、储值卡、积分商城、客户画像、消息触达
- 侧边栏菜单重构: 营销中心拆分为营销中心+会员中心两个一级菜单
2026-02-12 12:08:28 +08:00

423 lines
18 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.
<!-- 满减活动页 -->
<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">&lt;</button>
<button class="fr-page-btn active">1</button>
<button class="fr-page-btn">2</button>
<button class="fr-page-btn">&gt;</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>