Files
TakeoutSaaS.Prototypes/pages/store-pickup.html

246 lines
24 KiB
HTML

<!-- 自提设置页 -->
<style>
.page-pickup { max-width:960px; }
.pp-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; }
.pp-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); }
.pp-card { background:#fff; border-radius:10px; border:none; box-shadow:var(--g-shadow-sm); margin-bottom:16px; overflow:hidden; transition:var(--g-transition); }
.pp-card:hover { box-shadow:var(--g-shadow-md); }
.pp-card-header { padding:14px 18px; font-size:14px; font-weight:600; color:#1a1a2e; border-bottom:1px solid #f3f4f6; display:flex; align-items:center; justify-content:space-between; background:#f8f9fb; }
.pp-card-body { padding:16px 18px; }
.pp-form-row { display:flex; align-items:center; padding:12px 0; border-bottom:1px solid #f3f4f6; gap:12px; }
.pp-form-row:last-child { border-bottom:none; }
.pp-label { width:130px; font-size:13px; font-weight:500; color:#4b5563; flex-shrink:0; }
.pp-control { display:flex; align-items:center; gap:8px; flex:1; }
.pp-input { height:34px; padding:0 10px; border:1px solid #e5e7eb; border-radius:8px; font-size:13px; outline:none; background:#fff; width:120px; transition:var(--g-transition); }
.pp-input:focus { border-color:var(--primary); box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 12%, transparent); }
.pp-unit { font-size:12px; color:#9ca3af; }
.pp-hint { font-size:12px; color:#9ca3af; margin-left:8px; }
.pp-form-actions { display:flex; justify-content:flex-end; gap:8px; padding-top:14px; border-top:1px solid #f3f4f6; margin-top:4px; }
.pp-table { width:100%; border-collapse:collapse; font-size:13px; }
.pp-table th { background:#f8f9fb; padding:10px 12px; text-align:left; font-weight:600; color:#6b7280; border-bottom:1px solid #e5e7eb; white-space:nowrap; }
.pp-table td { padding:10px 12px; border-bottom:1px solid #f3f4f6; color:#1a1a2e; }
.pp-table tr:last-child td { border-bottom:none; }
.pp-table tr:hover td { background:color-mix(in srgb, var(--primary) 3%, #fff); }
.pp-progress { display:flex; align-items:center; gap:6px; }
.pp-progress-bar { width:60px; height:6px; background:#e5e7eb; border-radius:3px; overflow:hidden; }
.pp-progress-fill { height:100%; border-radius:3px; background:var(--primary); }
.pp-progress-text { font-size:11px; color:#9ca3af; white-space:nowrap; }
.pp-weekday { display:inline-block; padding:1px 8px; border-radius:6px; font-size:11px; font-weight:600; background:#f0f5ff; color:#597ef7; }
.pp-mode-switch { display:flex; background:#f8f9fb; border-radius:8px; padding:3px; gap:2px; width:fit-content; margin-bottom:16px; }
.pp-mode-item { padding:6px 18px; border-radius:6px; font-size:13px; cursor:pointer; color:#4b5563; border:none; background:none; transition:var(--g-transition); }
.pp-mode-item.active { background:#fff; color:var(--primary); font-weight:600; box-shadow:var(--g-shadow-sm); }
.pp-day-tabs { display:flex; gap:8px; margin-bottom:14px; }
.pp-day-tab { padding:8px 16px; border-radius:8px; font-size:13px; cursor:pointer; border:1px solid #e5e7eb; background:#fff; color:#4b5563; transition:var(--g-transition); }
.pp-day-tab.active { background:var(--primary); border-color:var(--primary); color:#fff; }
.pp-day-tab .dt-date { font-weight:500; }
.pp-day-tab .dt-sub { font-size:11px; opacity:0.8; }
.pp-slot-grid { display:flex; flex-wrap:wrap; gap:8px; }
.pp-slot-cell { width:82px; padding:8px 6px; border-radius:8px; text-align:center; border:1px solid #e5e7eb; transition:var(--g-transition); }
.pp-slot-cell .sc-time { font-size:13px; font-weight:500; }
.pp-slot-cell .sc-status { font-size:11px; margin-top:2px; }
.pp-slot-cell.expired { background:#f8f9fb; color:#bbb; border-color:#e5e7eb; }
.pp-slot-cell.available { background:#f0fdf4; color:#16a34a; border-color:#bbf7d0; }
.pp-slot-cell.almost { background:#fffbeb; color:#d97706; border-color:#fde68a; }
.pp-slot-cell.full { background:#fef2f2; color:#ef4444; border-color:#fecaca; }
.pp-legend { display:flex; gap:16px; font-size:12px; color:#9ca3af; margin-top:14px; }
.pp-legend span { display:flex; align-items:center; gap:4px; }
.pp-legend-dot { width:10px; height:10px; border-radius:2px; }
.pp-fg { margin-bottom:18px; }
.pp-fg-label { font-size:13px; font-weight:500; color:#4b5563; margin-bottom:6px; display:block; }
.pp-fg-hint { font-size:11px; color:#9ca3af; margin-top:4px; }
.pp-fg-input { height:34px; border:1px solid #e5e7eb; border-radius:8px; font-size:13px; padding:0 10px; outline:none; background:#fff; transition:var(--g-transition); }
.pp-fg-input:focus { border-color:var(--primary); box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 12%, transparent); }
.pp-day-pills { display:flex; gap:6px; }
.pp-day-pill { width:42px; height:34px; border-radius:8px; font-size:12px; cursor:pointer; border:1px solid #e5e7eb; background:#fff; color:#4b5563; display:flex; align-items:center; justify-content:center; transition:var(--g-transition); }
.pp-day-pill.selected { background:var(--primary); border-color:var(--primary); color:#fff; }
.pp-qk-btns { display:flex; gap:8px; margin-top:8px; }
.pp-qk-btn { font-size:11px; color:var(--primary); cursor:pointer; background:none; border:none; padding:0; transition:var(--g-transition); }
.pp-qk-btn:hover { text-decoration:underline; }
</style>
<div class="page-pickup">
<div class="pp-toolbar">
<select style="width:200px;">
<option>老三家外卖(朝阳店)</option>
<option>老三家外卖(海淀店)</option>
<option>老三家外卖(望京店)</option>
<option>老三家外卖(通州店)</option>
<option>老三家外卖(丰台店)</option>
</select>
<div style="flex:1;"></div>
<button class="g-btn" onclick="openCopyStoreModal('复制自提设置到其他门店')">
<i data-lucide="copy" style="width:14px;height:14px;"></i>复制到其他门店
</button>
</div>
<div class="pp-card">
<div class="pp-card-header">基本设置</div>
<div class="pp-card-body">
<div class="pp-form-row">
<div class="pp-label">允许当天自提</div>
<div class="pp-control"><label class="g-toggle-input"><input type="checkbox" checked><span class="g-toggle-sl"></span></label><span class="pp-hint">开启后顾客可选择当天自提</span></div>
</div>
<div class="pp-form-row">
<div class="pp-label">可预约天数</div>
<div class="pp-control"><input type="number" class="pp-input" value="3" style="width:80px;"><span class="pp-unit"></span><span class="pp-hint">顾客可提前预约的天数</span></div>
</div>
<div class="pp-form-row">
<div class="pp-label">单笔最大数量</div>
<div class="pp-control"><input type="number" class="pp-input" value="20" style="width:80px;"><span class="pp-unit"></span><span class="pp-hint">留空则不限制</span></div>
</div>
<div class="pp-form-actions"><button class="g-btn">重置</button><button class="g-btn g-btn-primary"><i data-lucide="save" style="width:14px;height:14px;"></i>保存设置</button></div>
</div>
</div>
<div class="pp-mode-switch">
<button class="pp-mode-item active" onclick="switchPickupMode('big')">大时段模式</button>
<button class="pp-mode-item" onclick="switchPickupMode('fine')">精细时段模式</button>
</div>
<div id="bigSlotSection">
<div class="pp-card">
<div class="pp-card-header">自提时段<button class="g-btn g-btn-primary g-btn-sm" onclick="openPickupDrawer('add')"><i data-lucide="plus" style="width:13px;height:13px;"></i>添加时段</button></div>
<div class="pp-card-body" style="padding:0;">
<table class="pp-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-weight:500;">上午时段</td><td>09:00-11:30</td><td>30</td><td>20</td><td><div class="pp-progress"><div class="pp-progress-bar"><div class="pp-progress-fill" style="width:25%;"></div></div><span class="pp-progress-text">5/20</span></div></td><td><span class="pp-weekday">周一至周五</span></td><td><label class="g-toggle-input"><input type="checkbox" checked><span class="g-toggle-sl"></span></label></td><td><a class="g-action" onclick="openPickupDrawer('edit',{name:'上午时段',start:'09:00',end:'11:30',cutoff:30,cap:20,days:'weekday'})">编辑</a><a class="g-action g-action-danger">删除</a></td></tr>
<tr><td style="font-weight:500;">午间时段</td><td>11:30-14:00</td><td>20</td><td>30</td><td><div class="pp-progress"><div class="pp-progress-bar"><div class="pp-progress-fill" style="width:40%;"></div></div><span class="pp-progress-text">12/30</span></div></td><td><span class="pp-weekday">每天</span></td><td><label class="g-toggle-input"><input type="checkbox" checked><span class="g-toggle-sl"></span></label></td><td><a class="g-action" onclick="openPickupDrawer('edit',{name:'午间时段',start:'11:30',end:'14:00',cutoff:20,cap:30,days:'all'})">编辑</a><a class="g-action g-action-danger">删除</a></td></tr>
<tr><td style="font-weight:500;">下午时段</td><td>14:00-17:00</td><td>30</td><td>15</td><td><div class="pp-progress"><div class="pp-progress-bar"><div class="pp-progress-fill" style="width:20%;"></div></div><span class="pp-progress-text">3/15</span></div></td><td><span class="pp-weekday">周一至周五</span></td><td><label class="g-toggle-input"><input type="checkbox" checked><span class="g-toggle-sl"></span></label></td><td><a class="g-action" onclick="openPickupDrawer('edit',{name:'下午时段',start:'14:00',end:'17:00',cutoff:30,cap:15,days:'weekday'})">编辑</a><a class="g-action g-action-danger">删除</a></td></tr>
<tr><td style="font-weight:500;">晚间时段</td><td>17:00-20:30</td><td>30</td><td>25</td><td><div class="pp-progress"><div class="pp-progress-bar"><div class="pp-progress-fill" style="width:32%;"></div></div><span class="pp-progress-text">8/25</span></div></td><td><span class="pp-weekday">每天</span></td><td><label class="g-toggle-input"><input type="checkbox" checked><span class="g-toggle-sl"></span></label></td><td><a class="g-action" onclick="openPickupDrawer('edit',{name:'晚间时段',start:'17:00',end:'20:30',cutoff:30,cap:25,days:'all'})">编辑</a><a class="g-action g-action-danger">删除</a></td></tr>
<tr><td style="font-weight:500;">周末特惠</td><td>10:00-15:00</td><td>45</td><td>40</td><td><div class="pp-progress"><div class="pp-progress-bar"><div class="pp-progress-fill" style="width:45%;background:#faad14;"></div></div><span class="pp-progress-text">18/40</span></div></td><td><span class="pp-weekday">周六周日</span></td><td><label class="g-toggle-input"><input type="checkbox"><span class="g-toggle-sl"></span></label></td><td><a class="g-action" onclick="openPickupDrawer('edit',{name:'周末特惠',start:'10:00',end:'15:00',cutoff:45,cap:40,days:'weekend'})">编辑</a><a class="g-action g-action-danger">删除</a></td></tr>
</tbody></table>
</div>
</div>
</div>
<div id="fineSlotSection" style="display:none;">
<div class="pp-card">
<div class="pp-card-header">生成规则</div>
<div class="pp-card-body">
<div style="display:grid;grid-template-columns:1fr 1fr;gap:14px 24px;">
<div class="pp-fg"><label class="pp-fg-label">时间间隔</label><select class="pp-input" style="width:100%;"><option>15 分钟</option><option>20 分钟</option><option>25 分钟</option><option selected>30 分钟</option><option>45 分钟</option><option>60 分钟</option></select></div>
<div class="pp-fg"><label class="pp-fg-label">每个时段容量</label><div style="display:flex;align-items:center;gap:6px;"><input type="number" class="pp-input" value="5" style="width:80px;"><span class="pp-unit"></span></div><div class="pp-fg-hint">每个时间窗口最大接单量</div></div>
<div class="pp-fg"><label class="pp-fg-label">每日开始时间</label><input type="time" class="pp-input" value="09:00" style="width:100%;"></div>
<div class="pp-fg"><label class="pp-fg-label">每日结束时间</label><input type="time" class="pp-input" value="20:30" style="width:100%;"></div>
<div class="pp-fg"><label class="pp-fg-label">最少提前预约</label><div style="display:flex;align-items:center;gap:6px;"><input type="number" class="pp-input" value="2" style="width:80px;"><span class="pp-unit">小时</span></div><div class="pp-fg-hint">下单时间距取餐时间的最小间隔</div></div>
</div>
<div class="pp-fg" style="margin-top:4px;"><label class="pp-fg-label">适用星期</label>
<div class="pp-day-pills" id="fineDayPills">
<button class="pp-day-pill selected" onclick="this.classList.toggle('selected')">周一</button>
<button class="pp-day-pill selected" onclick="this.classList.toggle('selected')">周二</button>
<button class="pp-day-pill selected" onclick="this.classList.toggle('selected')">周三</button>
<button class="pp-day-pill selected" onclick="this.classList.toggle('selected')">周四</button>
<button class="pp-day-pill selected" onclick="this.classList.toggle('selected')">周五</button>
<button class="pp-day-pill selected" onclick="this.classList.toggle('selected')">周六</button>
<button class="pp-day-pill selected" onclick="this.classList.toggle('selected')">周日</button>
</div>
<div class="pp-qk-btns"><button class="pp-qk-btn" onclick="ppQuickDays('all','fineDayPills')">全选</button><button class="pp-qk-btn" onclick="ppQuickDays('weekday','fineDayPills')">工作日</button><button class="pp-qk-btn" onclick="ppQuickDays('weekend','fineDayPills')">周末</button></div>
</div>
<div class="pp-form-actions"><button class="g-btn">重置</button><button class="g-btn g-btn-primary"><i data-lucide="save" style="width:14px;height:14px;"></i>保存规则</button></div>
</div>
</div>
<div class="pp-card">
<div class="pp-card-header">时段预览<span style="font-size:12px;font-weight:400;color:#999;">根据规则自动生成,以下为预览效果</span></div>
<div class="pp-card-body">
<div class="pp-day-tabs">
<button class="pp-day-tab active" onclick="switchPreviewDay(this)"><span class="dt-date">2/11</span> <span class="dt-sub">周三 今天</span></button>
<button class="pp-day-tab" onclick="switchPreviewDay(this)"><span class="dt-date">2/12</span> <span class="dt-sub">周四 明天</span></button>
<button class="pp-day-tab" onclick="switchPreviewDay(this)"><span class="dt-date">2/13</span> <span class="dt-sub">周五 后天</span></button>
</div>
<div class="pp-slot-grid"><div class="pp-slot-cell expired"><div class="sc-time">09:00</div><div class="sc-status">已过期</div></div><div class="pp-slot-cell expired"><div class="sc-time">09:30</div><div class="sc-status">已过期</div></div><div class="pp-slot-cell expired"><div class="sc-time">10:00</div><div class="sc-status">已过期</div></div><div class="pp-slot-cell expired"><div class="sc-time">10:30</div><div class="sc-status">已过期</div></div><div class="pp-slot-cell available"><div class="sc-time">11:00</div><div class="sc-status">剩余 3</div></div><div class="pp-slot-cell available"><div class="sc-time">11:30</div><div class="sc-status">剩余 5</div></div><div class="pp-slot-cell almost"><div class="sc-time">12:00</div><div class="sc-status">剩余 1</div></div><div class="pp-slot-cell full"><div class="sc-time">12:30</div><div class="sc-status">已满</div></div><div class="pp-slot-cell full"><div class="sc-time">13:00</div><div class="sc-status">已满</div></div><div class="pp-slot-cell available"><div class="sc-time">13:30</div><div class="sc-status">剩余 2</div></div><div class="pp-slot-cell available"><div class="sc-time">14:00</div><div class="sc-status">剩余 5</div></div><div class="pp-slot-cell available"><div class="sc-time">14:30</div><div class="sc-status">剩余 5</div></div><div class="pp-slot-cell available"><div class="sc-time">15:00</div><div class="sc-status">剩余 4</div></div><div class="pp-slot-cell available"><div class="sc-time">15:30</div><div class="sc-status">剩余 5</div></div><div class="pp-slot-cell available"><div class="sc-time">16:00</div><div class="sc-status">剩余 5</div></div><div class="pp-slot-cell available"><div class="sc-time">16:30</div><div class="sc-status">剩余 5</div></div><div class="pp-slot-cell available"><div class="sc-time">17:00</div><div class="sc-status">剩余 3</div></div><div class="pp-slot-cell available"><div class="sc-time">17:30</div><div class="sc-status">剩余 5</div></div><div class="pp-slot-cell almost"><div class="sc-time">18:00</div><div class="sc-status">剩余 1</div></div><div class="pp-slot-cell available"><div class="sc-time">18:30</div><div class="sc-status">剩余 5</div></div><div class="pp-slot-cell available"><div class="sc-time">19:00</div><div class="sc-status">剩余 5</div></div><div class="pp-slot-cell available"><div class="sc-time">19:30</div><div class="sc-status">剩余 4</div></div><div class="pp-slot-cell available"><div class="sc-time">20:00</div><div class="sc-status">剩余 5</div></div></div>
<div class="pp-legend">
<span><span class="pp-legend-dot" style="background:#d9d9d9;"></span>已过期</span>
<span><span class="pp-legend-dot" style="background:#b7eb8f;"></span>可预约</span>
<span><span class="pp-legend-dot" style="background:#ffd591;"></span>即将满</span>
<span><span class="pp-legend-dot" style="background:#ffa39e;"></span>已满</span>
</div>
</div>
</div>
</div>
</div>
<div class="g-drawer-mask" id="ppDrawerMask" onclick="closePickupDrawer()"></div>
<div class="g-drawer" id="ppSlotDrawer" style="width:480px;">
<div class="g-drawer-hd"><span class="g-drawer-title" id="ppDrawerTitle">添加时段</span><button class="g-drawer-close" onclick="closePickupDrawer()"><i data-lucide="x" style="width:18px;height:18px;"></i></button></div>
<div class="g-drawer-bd">
<div class="pp-fg"><label class="pp-fg-label">时段名称</label><input type="text" class="pp-fg-input" id="ppName" placeholder="如:上午时段" style="width:100%;" /></div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;">
<div class="pp-fg"><label class="pp-fg-label">开始时间</label><input type="time" class="pp-fg-input" id="ppStart" value="09:00" style="width:100%;" /></div>
<div class="pp-fg"><label class="pp-fg-label">结束时间</label><input type="time" class="pp-fg-input" id="ppEnd" value="17:00" style="width:100%;" /></div>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;">
<div class="pp-fg"><label class="pp-fg-label">截止时间</label><div style="display:flex;align-items:center;gap:6px;"><input type="number" class="pp-fg-input" id="ppCutoff" value="30" style="width:80px;"><span class="pp-unit">分钟</span></div><div class="pp-fg-hint">时段开始前停止接单</div></div>
<div class="pp-fg"><label class="pp-fg-label">容量上限</label><div style="display:flex;align-items:center;gap:6px;"><input type="number" class="pp-fg-input" id="ppCap" value="20" style="width:80px;"><span class="pp-unit"></span></div><div class="pp-fg-hint">该时段最大接单数</div></div>
</div>
<div class="pp-fg"><label class="pp-fg-label">适用星期</label>
<div class="pp-day-pills" id="ppDayPills">
<button class="pp-day-pill selected" onclick="this.classList.toggle('selected')">周一</button>
<button class="pp-day-pill selected" onclick="this.classList.toggle('selected')">周二</button>
<button class="pp-day-pill selected" onclick="this.classList.toggle('selected')">周三</button>
<button class="pp-day-pill selected" onclick="this.classList.toggle('selected')">周四</button>
<button class="pp-day-pill selected" onclick="this.classList.toggle('selected')">周五</button>
<button class="pp-day-pill" onclick="this.classList.toggle('selected')">周六</button>
<button class="pp-day-pill" onclick="this.classList.toggle('selected')">周日</button>
</div>
<div class="pp-qk-btns"><button class="pp-qk-btn" onclick="ppQuickDays('all','ppDayPills')">全选</button><button class="pp-qk-btn" onclick="ppQuickDays('weekday','ppDayPills')">工作日</button><button class="pp-qk-btn" onclick="ppQuickDays('weekend','ppDayPills')">周末</button></div>
</div>
<div class="pp-fg"><label class="pp-fg-label">启用状态</label><label class="g-toggle-input"><input type="checkbox" id="ppEnabled" checked><span class="g-toggle-sl"></span></label></div>
</div>
<div class="g-drawer-ft"><button class="g-btn" onclick="closePickupDrawer()">取消</button><button class="g-btn g-btn-primary" id="ppSubmitBtn" onclick="closePickupDrawer()">确认添加</button></div>
</div>
<script>
function switchPickupMode(mode) {
document.querySelectorAll('.pp-mode-item').forEach(function(b){ b.classList.remove('active'); });
event.currentTarget.classList.add('active');
document.getElementById('bigSlotSection').style.display = mode==='big' ? '' : 'none';
document.getElementById('fineSlotSection').style.display = mode==='fine' ? '' : 'none';
}
function openPickupDrawer(mode, data) {
document.getElementById('ppDrawerMask').classList.add('open');
document.getElementById('ppSlotDrawer').classList.add('open');
var weekdays=['周一','周二','周三','周四','周五'], weekends=['周六','周日'];
if (mode==='edit' && data) {
document.getElementById('ppDrawerTitle').textContent='编辑时段 - '+data.name;
document.getElementById('ppSubmitBtn').textContent='保存修改';
document.getElementById('ppName').value=data.name||'';
document.getElementById('ppStart').value=data.start||'';
document.getElementById('ppEnd').value=data.end||'';
document.getElementById('ppCutoff').value=data.cutoff||30;
document.getElementById('ppCap').value=data.cap||20;
document.querySelectorAll('#ppDayPills .pp-day-pill').forEach(function(p){
var d=p.textContent;
if(data.days==='all') p.classList.add('selected');
else if(data.days==='weekday') p.classList.toggle('selected',weekdays.includes(d));
else if(data.days==='weekend') p.classList.toggle('selected',weekends.includes(d));
});
} else {
document.getElementById('ppDrawerTitle').textContent='添加时段';
document.getElementById('ppSubmitBtn').textContent='确认添加';
document.getElementById('ppName').value='';
document.getElementById('ppStart').value='09:00';
document.getElementById('ppEnd').value='17:00';
document.getElementById('ppCutoff').value=30;
document.getElementById('ppCap').value=20;
ppQuickDays('weekday','ppDayPills');
}
if(typeof lucide!=='undefined') lucide.createIcons();
}
function closePickupDrawer() {
document.getElementById('ppDrawerMask').classList.remove('open');
document.getElementById('ppSlotDrawer').classList.remove('open');
}
function ppQuickDays(mode, containerId) {
var pills=document.querySelectorAll('#'+containerId+' .pp-day-pill');
var weekdays=['周一','周二','周三','周四','周五'], weekends=['周六','周日'];
pills.forEach(function(p){
var d=p.textContent;
if(mode==='all') p.classList.add('selected');
else if(mode==='weekday') p.classList.toggle('selected',weekdays.includes(d));
else if(mode==='weekend') p.classList.toggle('selected',weekends.includes(d));
});
}
function switchPreviewDay(el) {
document.querySelectorAll('.pp-day-tab').forEach(function(b){ b.classList.remove('active'); });
el.classList.add('active');
}
</script>