Files

437 lines
20 KiB
HTML
Raw Permalink 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>
.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>&lt;</button>
<button class="g-page-btn active">1</button>
<button class="g-page-btn">&gt;</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>