Files
TakeoutSaaS.Prototypes/Tenant-Admin-UI-Prototype/pages/mbr-points.html

772 lines
36 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>
.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; display:flex; align-items:center; gap:6px; }
.pt-type-tag { font-size:11px; font-weight:500; padding:1px 6px; border-radius:4px; flex-shrink:0; }
.pt-type-tag.blue { background:color-mix(in srgb, var(--primary) 12%, #fff); color:var(--primary); }
.pt-type-tag.green { background:color-mix(in srgb, var(--g-success) 12%, #fff); color:var(--g-success); }
.pt-type-tag.orange { background:color-mix(in srgb, var(--g-warning) 12%, #fff); color:var(--g-warning); }
.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; }
/* 通知 pill 多选 */
.pt-notify-pills { display:flex; gap:10px; }
.pt-notify-pills .g-pill { position:relative; padding-left:24px; }
.pt-notify-pills .g-pill::before {
content:''; position:absolute; left:8px; top:50%; transform:translateY(-50%);
width:12px; height:12px; border:1.5px solid #ccc; border-radius:3px; transition:all var(--g-transition);
}
.pt-notify-pills .g-pill.checked::before {
background:var(--primary); border-color:var(--primary);
background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 12 12' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M2.5 6L5 8.5L9.5 4' stroke='white' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
/* 兑换记录表格 */
.pt-rec-status { display:inline-flex; align-items:center; gap:4px; font-size:12px; }
.pt-rec-status::before { content:''; width:6px; height:6px; border-radius:50%; }
.pt-rec-status.green::before { background:var(--g-success); }
.pt-rec-status.orange::before { background:var(--g-warning); }
.pt-rec-status.gray::before { background:#bbb; }
.pt-rec-status.red::before { background:var(--g-danger); }
.pt-rec-member { display:flex; flex-direction:column; gap:2px; }
.pt-rec-member-name { font-size:13px; font-weight:500; color:var(--g-text); }
.pt-rec-member-phone { font-size:12px; color:var(--g-text-muted); }
/* 保存栏 */
.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>
<button class="pt-seg-item" onclick="switchPtTab(this, 'records')">兑换记录</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">可乐兑换券<span class="pt-type-tag blue">商品</span></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">凉拌黄瓜<span class="pt-type-tag blue">商品</span></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券<span class="pt-type-tag green">优惠券</span></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">招牌奶茶<span class="pt-type-tag blue">商品</span></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">双人套餐券<span class="pt-type-tag green">优惠券</span></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">定制保温杯<span class="pt-type-tag orange">实物</span></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>
<!-- ==================== TAB 3: 兑换记录 ==================== -->
<div id="ptTabRecords" style="display:none;">
<!-- 筛选工具栏 -->
<div class="pt-toolbar">
<select style="width:120px;">
<option value="">全部类型</option>
<option>兑换商品</option>
<option>兑换优惠券</option>
<option>兑换实物</option>
</select>
<select style="width:120px;">
<option value="">全部状态</option>
<option>待领取</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-sm"><i data-lucide="download" style="width:13px;height:13px;"></i>导出</button>
</div>
<!-- 统计 -->
<div class="pt-stats" style="grid-template-columns:repeat(3,1fr);">
<div class="pt-stat-card">
<div class="pt-stat-label">今日兑换</div>
<div class="pt-stat-value primary">12</div>
</div>
<div class="pt-stat-card">
<div class="pt-stat-label">待领取实物</div>
<div class="pt-stat-value orange">3</div>
</div>
<div class="pt-stat-card">
<div class="pt-stat-label">本月消耗积分</div>
<div class="pt-stat-value">8,400</div>
</div>
</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 style="width:100px;">操作</th>
</tr>
</thead>
<tbody>
<tr>
<td style="font-family:monospace;font-size:12px;">PT20260212001</td>
<td><div class="pt-rec-member"><span class="pt-rec-member-name">张三</span><span class="pt-rec-member-phone">138****6789</span></div></td>
<td>定制保温杯</td>
<td><span class="pt-type-tag orange">实物</span></td>
<td style="font-weight:600;">2,000</td>
<td style="font-size:12px;color:var(--g-text-secondary);">2026-02-12 10:30</td>
<td><span class="pt-rec-status orange">待领取</span></td>
<td><a class="g-action" onclick="openPtVerifyDrawer()">核销</a><a class="g-action">详情</a></td>
</tr>
<tr>
<td style="font-family:monospace;font-size:12px;">PT20260212002</td>
<td><div class="pt-rec-member"><span class="pt-rec-member-name">李四</span><span class="pt-rec-member-phone">139****1234</span></div></td>
<td>可乐兑换券</td>
<td><span class="pt-type-tag blue">商品</span></td>
<td style="font-weight:600;">100</td>
<td style="font-size:12px;color:var(--g-text-secondary);">2026-02-12 09:45</td>
<td><span class="pt-rec-status green">已发放</span></td>
<td><a class="g-action">详情</a></td>
</tr>
<tr>
<td style="font-family:monospace;font-size:12px;">PT20260211003</td>
<td><div class="pt-rec-member"><span class="pt-rec-member-name">王五</span><span class="pt-rec-member-phone">137****5678</span></div></td>
<td>满20减5券</td>
<td><span class="pt-type-tag green">优惠券</span></td>
<td style="font-weight:600;">300</td>
<td style="font-size:12px;color:var(--g-text-secondary);">2026-02-11 18:20</td>
<td><span class="pt-rec-status green">已发放</span></td>
<td><a class="g-action">详情</a></td>
</tr>
<tr>
<td style="font-family:monospace;font-size:12px;">PT20260211004</td>
<td><div class="pt-rec-member"><span class="pt-rec-member-name">赵六</span><span class="pt-rec-member-phone">136****4321</span></div></td>
<td>定制保温杯</td>
<td><span class="pt-type-tag orange">实物</span></td>
<td style="font-weight:600;">2,000</td>
<td style="font-size:12px;color:var(--g-text-secondary);">2026-02-11 14:10</td>
<td><span class="pt-rec-status orange">待领取</span></td>
<td><a class="g-action" onclick="openPtVerifyDrawer()">核销</a><a class="g-action">详情</a></td>
</tr>
<tr>
<td style="font-family:monospace;font-size:12px;">PT20260210005</td>
<td><div class="pt-rec-member"><span class="pt-rec-member-name">孙七</span><span class="pt-rec-member-phone">135****8765</span></div></td>
<td>招牌奶茶</td>
<td><span class="pt-type-tag blue">商品</span></td>
<td style="font-weight:600;">500</td>
<td style="font-size:12px;color:var(--g-text-secondary);">2026-02-10 16:55</td>
<td><span class="pt-rec-status green">已完成</span></td>
<td><a class="g-action">详情</a></td>
</tr>
<tr>
<td style="font-family:monospace;font-size:12px;">PT20260210006</td>
<td><div class="pt-rec-member"><span class="pt-rec-member-name">周八</span><span class="pt-rec-member-phone">133****2222</span></div></td>
<td>双人套餐券</td>
<td><span class="pt-type-tag green">优惠券</span></td>
<td style="font-weight:600;">1,000</td>
<td style="font-size:12px;color:var(--g-text-secondary);">2026-02-10 11:30</td>
<td><span class="pt-rec-status gray">已取消</span></td>
<td><a class="g-action">详情</a></td>
</tr>
<tr>
<td style="font-family:monospace;font-size:12px;">PT20260209007</td>
<td><div class="pt-rec-member"><span class="pt-rec-member-name">吴九</span><span class="pt-rec-member-phone">131****9999</span></div></td>
<td>定制保温杯</td>
<td><span class="pt-type-tag orange">实物</span></td>
<td style="font-weight:600;">2,000</td>
<td style="font-size:12px;color:var(--g-text-secondary);">2026-02-09 09:00</td>
<td><span class="pt-rec-status green">已完成</span></td>
<td><a class="g-action">详情</a></td>
</tr>
</tbody>
</table>
</div>
<!-- 分页 -->
<div class="g-pagination" style="margin-top:16px;">
<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"><i data-lucide="chevron-right" style="width:14px;height:14px;"></i></button>
</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()">&times;</button>
</div>
<div class="g-drawer-bd">
<!-- 兑换类型 -->
<div class="g-form-group">
<label class="g-form-label required">兑换类型</label>
<div class="pt-exchange-pills">
<span class="g-pill checked" onclick="selectPtRedeemType(this, 'product')">兑换商品</span>
<span class="g-pill" onclick="selectPtRedeemType(this, 'coupon')">兑换优惠券</span>
<span class="g-pill" onclick="selectPtRedeemType(this, 'physical')">兑换实物</span>
</div>
<div class="g-hint" id="ptRedeemHintProduct">顾客兑换后系统自动发放商品兑换券,下单时该商品免费</div>
<div class="g-hint" id="ptRedeemHintCoupon" style="display:none;">顾客兑换后优惠券直接发到券包</div>
<div class="g-hint" id="ptRedeemHintPhysical" style="display:none;">实物商品需到店自提,不走线上履约</div>
</div>
<!-- 兑换商品:选择商品 -->
<div id="ptFieldProduct">
<div class="g-form-group">
<label class="g-form-label required">关联商品</label>
<div id="ptSelectedProduct" style="display:none;padding:10px 12px;background:#f8f9fb;border-radius:8px;border:1px solid #e5e7eb;margin-bottom:8px;display:flex;align-items:center;gap:10px;">
<div style="width:40px;height:40px;background:#eee;border-radius:6px;display:flex;align-items:center;justify-content:center;color:#bbb;flex-shrink:0;"><i data-lucide="image" style="width:18px;height:18px;"></i></div>
<div style="flex:1;">
<div style="font-size:13px;font-weight:500;">招牌奶茶</div>
<div style="font-size:12px;color:var(--g-text-muted);">原价 ¥15.00</div>
</div>
<button style="background:none;border:none;color:var(--g-text-muted);cursor:pointer;" onclick="this.parentElement.style.display='none'"><i data-lucide="x" style="width:14px;height:14px;"></i></button>
</div>
<button class="g-btn g-btn-sm" onclick="openProductPicker({title:'选择兑换商品',subtitle:'积分商城',onConfirm:function(){}})"><i data-lucide="plus" style="width:13px;height:13px;"></i>选择商品/套餐</button>
<div class="g-hint">兑换后系统自动生成该商品的兑换券</div>
</div>
</div>
<!-- 兑换优惠券:选择券 -->
<div id="ptFieldCoupon" style="display:none;">
<div class="g-form-group">
<label class="g-form-label required">关联优惠券</label>
<select class="g-select" style="width:100%;">
<option value="">请选择优惠券</option>
<option>新用户满减券满50减15</option>
<option>全场8折券</option>
<option>免配送费券</option>
<option>满30减5券</option>
<option>满80减20券</option>
</select>
<div class="g-hint">选择已在优惠券管理中创建的券,兑换后直接发到顾客券包</div>
</div>
</div>
<!-- 兑换实物:名称+描述 -->
<div id="ptFieldPhysical" style="display:none;">
<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 style="display:flex;gap:8px;">
<span class="g-pill checked" onclick="this.parentElement.querySelectorAll('.g-pill').forEach(function(p){p.classList.remove('checked')});this.classList.add('checked')">到店自提</span>
<span class="g-pill" onclick="this.parentElement.querySelectorAll('.g-pill').forEach(function(p){p.classList.remove('checked')});this.classList.add('checked')">快递配送</span>
</div>
</div>
</div>
<!-- 商品名称(展示名) -->
<div class="g-form-group">
<label class="g-form-label required">展示名称</label>
<input class="g-input" placeholder="如招牌奶茶兑换券、满50减15券">
<div class="g-hint">顾客在积分商城看到的名称</div>
</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" style="margin-bottom:8px;">
<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 class="g-form-group">
<label class="g-form-label">到账通知</label>
<div class="pt-notify-pills" id="ptNotifyPills">
<span class="g-pill checked" onclick="togglePill(this)">站内消息</span>
<span class="g-pill" onclick="togglePill(this)">短信通知</span>
</div>
<div class="g-hint">选择兑换成功后通知顾客的方式,实物商品建议开启短信通知</div>
</div>
</div>
<div class="g-drawer-ft">
<button class="g-btn" onclick="closePtDrawer()">取消</button>
<button class="g-btn g-btn-primary">保存</button>
</div>
</div>
<!-- ==================== 核销抽屉 ==================== -->
<div class="g-drawer-mask" id="ptVerifyMask" onclick="closePtVerifyDrawer()"></div>
<div class="g-drawer" id="ptVerifyDrawer" style="width:440px;">
<div class="g-drawer-hd">
<span class="g-drawer-title">兑换核销</span>
<button class="g-drawer-close" onclick="closePtVerifyDrawer()">&times;</button>
</div>
<div class="g-drawer-bd">
<!-- 兑换信息 -->
<div style="background:#f8f9fb;border-radius:10px;padding:16px;margin-bottom:20px;">
<div style="display:flex;align-items:center;gap:12px;margin-bottom:12px;">
<div style="width:48px;height:48px;background:#eee;border-radius:8px;display:flex;align-items:center;justify-content:center;color:#bbb;flex-shrink:0;"><i data-lucide="image" style="width:22px;height:22px;"></i></div>
<div>
<div style="font-size:14px;font-weight:600;color:var(--g-text);margin-bottom:2px;">定制保温杯</div>
<span class="pt-type-tag orange">实物</span>
</div>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;font-size:13px;">
<div><span style="color:var(--g-text-muted);">兑换单号</span><div style="font-family:monospace;margin-top:2px;">PT20260212001</div></div>
<div><span style="color:var(--g-text-muted);">消耗积分</span><div style="font-weight:600;color:var(--primary);margin-top:2px;">2,000</div></div>
<div><span style="color:var(--g-text-muted);">兑换会员</span><div style="margin-top:2px;">张三 (138****6789)</div></div>
<div><span style="color:var(--g-text-muted);">兑换时间</span><div style="margin-top:2px;">2026-02-12 10:30</div></div>
</div>
</div>
<!-- 核销方式 -->
<div class="g-form-group">
<label class="g-form-label">核销方式</label>
<div style="display:flex;gap:10px;">
<span class="g-pill checked" onclick="this.parentElement.querySelectorAll('.g-pill').forEach(function(p){p.classList.remove('checked')});this.classList.add('checked')">扫码核销</span>
<span class="g-pill" onclick="this.parentElement.querySelectorAll('.g-pill').forEach(function(p){p.classList.remove('checked')});this.classList.add('checked')">手动核销</span>
</div>
</div>
<!-- 备注 -->
<div class="g-form-group">
<label class="g-form-label">核销备注</label>
<textarea class="g-textarea" rows="2" placeholder="可选,如:顾客已到店领取"></textarea>
</div>
</div>
<div class="g-drawer-ft">
<button class="g-btn" onclick="closePtVerifyDrawer()">取消</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';
document.getElementById('ptTabRecords').style.display = tab === 'records' ? '' : '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';
}
/* 兑换类型切换(商品/优惠券/实物) */
function selectPtRedeemType(el, type) {
el.parentElement.querySelectorAll('.g-pill').forEach(function(p) { p.classList.remove('checked'); });
el.classList.add('checked');
document.getElementById('ptFieldProduct').style.display = type === 'product' ? '' : 'none';
document.getElementById('ptFieldCoupon').style.display = type === 'coupon' ? '' : 'none';
document.getElementById('ptFieldPhysical').style.display = type === 'physical' ? '' : 'none';
document.getElementById('ptRedeemHintProduct').style.display = type === 'product' ? '' : 'none';
document.getElementById('ptRedeemHintCoupon').style.display = type === 'coupon' ? '' : 'none';
document.getElementById('ptRedeemHintPhysical').style.display = type === 'physical' ? '' : 'none';
/* 自动设置通知默认值:实物默认勾选短信 */
var pills = document.querySelectorAll('#ptNotifyPills .g-pill');
if (type === 'physical') {
pills.forEach(function(p) { p.classList.add('checked'); });
} else {
pills[0].classList.add('checked');
pills[1].classList.remove('checked');
}
}
/* 兑换方式 pill 单选(纯积分/积分+现金) */
function selectPtExchangeType(el, type) {
el.parentElement.querySelectorAll('.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');
}
/* 通知 pill 多选 */
function togglePill(el) {
el.classList.toggle('checked');
}
/* 核销抽屉 */
function openPtVerifyDrawer() {
document.getElementById('ptVerifyMask').classList.add('open');
document.getElementById('ptVerifyDrawer').classList.add('open');
}
function closePtVerifyDrawer() {
document.getElementById('ptVerifyMask').classList.remove('open');
document.getElementById('ptVerifyDrawer').classList.remove('open');
}
/* 初始化 Lucide 图标 */
if (typeof lucide !== 'undefined') { lucide.createIcons(); }
</script>