427 lines
12 KiB
HTML
427 lines
12 KiB
HTML
|
|
<!DOCTYPE html>
|
||
|
|
<html lang="zh-CN">
|
||
|
|
<head>
|
||
|
|
<meta charset="UTF-8">
|
||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
|
<title>批量会员等级编辑</title>
|
||
|
|
<style>
|
||
|
|
* {
|
||
|
|
margin: 0;
|
||
|
|
padding: 0;
|
||
|
|
box-sizing: border-box;
|
||
|
|
}
|
||
|
|
|
||
|
|
body {
|
||
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||
|
|
background-color: #f5f5f5;
|
||
|
|
line-height: 1.4;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 顶部标题栏 */
|
||
|
|
.header {
|
||
|
|
background-color: #4CAF50;
|
||
|
|
color: white;
|
||
|
|
padding: 12px 16px;
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
position: sticky;
|
||
|
|
top: 0;
|
||
|
|
z-index: 100;
|
||
|
|
}
|
||
|
|
|
||
|
|
.back-btn {
|
||
|
|
background: none;
|
||
|
|
border: none;
|
||
|
|
color: white;
|
||
|
|
font-size: 18px;
|
||
|
|
margin-right: 12px;
|
||
|
|
cursor: pointer;
|
||
|
|
}
|
||
|
|
|
||
|
|
.header-title {
|
||
|
|
font-size: 16px;
|
||
|
|
font-weight: 500;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 步骤指示器 */
|
||
|
|
.steps {
|
||
|
|
background: white;
|
||
|
|
padding: 16px;
|
||
|
|
display: flex;
|
||
|
|
justify-content: space-between;
|
||
|
|
align-items: center;
|
||
|
|
border-bottom: 1px dashed #e0e0e0;
|
||
|
|
}
|
||
|
|
|
||
|
|
.step {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
flex: 1;
|
||
|
|
position: relative;
|
||
|
|
}
|
||
|
|
|
||
|
|
.step-number {
|
||
|
|
width: 24px;
|
||
|
|
height: 24px;
|
||
|
|
border-radius: 50%;
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: center;
|
||
|
|
font-size: 12px;
|
||
|
|
font-weight: bold;
|
||
|
|
margin-right: 8px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.step.active .step-number {
|
||
|
|
background-color: #4CAF50;
|
||
|
|
color: white;
|
||
|
|
}
|
||
|
|
|
||
|
|
.step.inactive .step-number {
|
||
|
|
background-color: #e0e0e0;
|
||
|
|
color: #999;
|
||
|
|
}
|
||
|
|
|
||
|
|
.step-text {
|
||
|
|
font-size: 14px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.step.active .step-text {
|
||
|
|
color: #4CAF50;
|
||
|
|
}
|
||
|
|
|
||
|
|
.step.inactive .step-text {
|
||
|
|
color: #999;
|
||
|
|
}
|
||
|
|
|
||
|
|
.step:not(:last-child)::after {
|
||
|
|
content: '';
|
||
|
|
position: absolute;
|
||
|
|
right: -20px;
|
||
|
|
top: 50%;
|
||
|
|
transform: translateY(-50%);
|
||
|
|
width: 40px;
|
||
|
|
height: 1px;
|
||
|
|
background-color: #e0e0e0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 操作按钮区 */
|
||
|
|
.action-buttons {
|
||
|
|
background: white;
|
||
|
|
padding: 16px;
|
||
|
|
display: flex;
|
||
|
|
gap: 12px;
|
||
|
|
border-bottom: 1px dashed #e0e0e0;
|
||
|
|
}
|
||
|
|
|
||
|
|
.action-btn {
|
||
|
|
flex: 1;
|
||
|
|
padding: 8px 12px;
|
||
|
|
background: white;
|
||
|
|
border: 1px dashed #ccc;
|
||
|
|
border-radius: 4px;
|
||
|
|
font-size: 14px;
|
||
|
|
cursor: pointer;
|
||
|
|
transition: all 0.2s;
|
||
|
|
}
|
||
|
|
|
||
|
|
.action-btn:hover {
|
||
|
|
border-color: #4CAF50;
|
||
|
|
color: #4CAF50;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 选择摘要 */
|
||
|
|
.selection-summary {
|
||
|
|
background: white;
|
||
|
|
margin: 12px 16px;
|
||
|
|
padding: 12px;
|
||
|
|
border: 1px dashed #4CAF50;
|
||
|
|
border-radius: 4px;
|
||
|
|
color: #4CAF50;
|
||
|
|
font-size: 14px;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 店铺列表 */
|
||
|
|
.shop-list {
|
||
|
|
padding: 0 16px 16px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.shop-item {
|
||
|
|
background: white;
|
||
|
|
margin-bottom: 12px;
|
||
|
|
padding: 16px;
|
||
|
|
border: 1px dashed #e0e0e0;
|
||
|
|
border-radius: 8px;
|
||
|
|
position: relative;
|
||
|
|
}
|
||
|
|
|
||
|
|
.shop-item.selected {
|
||
|
|
border-color: #4CAF50;
|
||
|
|
background-color: #f8fff8;
|
||
|
|
}
|
||
|
|
|
||
|
|
.shop-checkbox {
|
||
|
|
position: absolute;
|
||
|
|
top: 16px;
|
||
|
|
right: 16px;
|
||
|
|
width: 20px;
|
||
|
|
height: 20px;
|
||
|
|
cursor: pointer;
|
||
|
|
}
|
||
|
|
|
||
|
|
.shop-name {
|
||
|
|
font-size: 16px;
|
||
|
|
font-weight: 500;
|
||
|
|
margin-bottom: 8px;
|
||
|
|
padding-right: 40px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.shop-info {
|
||
|
|
display: flex;
|
||
|
|
justify-content: space-between;
|
||
|
|
align-items: center;
|
||
|
|
margin-bottom: 8px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.member-status {
|
||
|
|
font-size: 12px;
|
||
|
|
padding: 2px 8px;
|
||
|
|
border-radius: 12px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.member-status.enabled {
|
||
|
|
background-color: #e8f5e8;
|
||
|
|
color: #4CAF50;
|
||
|
|
border: 1px dashed #4CAF50;
|
||
|
|
}
|
||
|
|
|
||
|
|
.member-status.disabled {
|
||
|
|
background-color: #f5f5f5;
|
||
|
|
color: #999;
|
||
|
|
border: 1px dashed #ccc;
|
||
|
|
}
|
||
|
|
|
||
|
|
.member-count {
|
||
|
|
font-size: 14px;
|
||
|
|
color: #666;
|
||
|
|
}
|
||
|
|
|
||
|
|
.current-level {
|
||
|
|
font-size: 12px;
|
||
|
|
color: #999;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 底部按钮 */
|
||
|
|
.bottom-actions {
|
||
|
|
position: fixed;
|
||
|
|
bottom: 0;
|
||
|
|
left: 0;
|
||
|
|
right: 0;
|
||
|
|
background: white;
|
||
|
|
padding: 16px;
|
||
|
|
display: flex;
|
||
|
|
gap: 12px;
|
||
|
|
border-top: 1px dashed #e0e0e0;
|
||
|
|
}
|
||
|
|
|
||
|
|
.cancel-btn {
|
||
|
|
flex: 1;
|
||
|
|
padding: 12px;
|
||
|
|
background: white;
|
||
|
|
border: 1px dashed #ccc;
|
||
|
|
border-radius: 4px;
|
||
|
|
font-size: 16px;
|
||
|
|
cursor: pointer;
|
||
|
|
}
|
||
|
|
|
||
|
|
.next-btn {
|
||
|
|
flex: 2;
|
||
|
|
padding: 12px;
|
||
|
|
background: #4CAF50;
|
||
|
|
border: 1px dashed #4CAF50;
|
||
|
|
border-radius: 4px;
|
||
|
|
color: white;
|
||
|
|
font-size: 16px;
|
||
|
|
cursor: pointer;
|
||
|
|
}
|
||
|
|
|
||
|
|
.next-btn:disabled {
|
||
|
|
background: #e0e0e0;
|
||
|
|
border-color: #e0e0e0;
|
||
|
|
color: #999;
|
||
|
|
cursor: not-allowed;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* 底部留白 */
|
||
|
|
.bottom-spacer {
|
||
|
|
height: 80px;
|
||
|
|
}
|
||
|
|
</style>
|
||
|
|
</head>
|
||
|
|
<body>
|
||
|
|
<!-- 顶部标题栏 -->
|
||
|
|
<div class="header">
|
||
|
|
<button class="back-btn">←</button>
|
||
|
|
<div class="header-title">批量会员等级编辑</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 步骤指示器 -->
|
||
|
|
<div class="steps">
|
||
|
|
<div class="step active">
|
||
|
|
<div class="step-number">1</div>
|
||
|
|
<div class="step-text">选择店铺</div>
|
||
|
|
</div>
|
||
|
|
<div class="step inactive">
|
||
|
|
<div class="step-number">2</div>
|
||
|
|
<div class="step-text">设置等级</div>
|
||
|
|
</div>
|
||
|
|
<div class="step inactive">
|
||
|
|
<div class="step-number">3</div>
|
||
|
|
<div class="step-text">确认提交</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 操作按钮区 -->
|
||
|
|
<div class="action-buttons">
|
||
|
|
<button class="action-btn" onclick="selectAll()">全选</button>
|
||
|
|
<button class="action-btn" onclick="selectNone()">全不选</button>
|
||
|
|
<button class="action-btn" onclick="selectReverse()">反选</button>
|
||
|
|
<button class="action-btn" onclick="selectEnabled()">仅选启用</button>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 选择摘要 -->
|
||
|
|
<div class="selection-summary">
|
||
|
|
选择摘要 已选择<span id="selectedCount">0</span>个店铺
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 店铺列表 -->
|
||
|
|
<div class="shop-list">
|
||
|
|
<div class="shop-item" data-enabled="true">
|
||
|
|
<input type="checkbox" class="shop-checkbox" onchange="updateSelection()">
|
||
|
|
<div class="shop-name">时尚服装店</div>
|
||
|
|
<div class="shop-info">
|
||
|
|
<div class="member-status enabled">会员功能已启用</div>
|
||
|
|
<div class="member-count">会员数1250</div>
|
||
|
|
</div>
|
||
|
|
<div class="current-level">当前等级lv1-lv4</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="shop-item" data-enabled="false">
|
||
|
|
<input type="checkbox" class="shop-checkbox" onchange="updateSelection()">
|
||
|
|
<div class="shop-name">数码电子城</div>
|
||
|
|
<div class="shop-info">
|
||
|
|
<div class="member-status disabled">会员功能未启用</div>
|
||
|
|
<div class="member-count">会员数850</div>
|
||
|
|
</div>
|
||
|
|
<div class="current-level">当前等级lv1-lv3</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="shop-item" data-enabled="true">
|
||
|
|
<input type="checkbox" class="shop-checkbox" onchange="updateSelection()">
|
||
|
|
<div class="shop-name">美食餐厅</div>
|
||
|
|
<div class="shop-info">
|
||
|
|
<div class="member-status enabled">会员功能已启用</div>
|
||
|
|
<div class="member-count">会员数2100</div>
|
||
|
|
</div>
|
||
|
|
<div class="current-level">当前等级lv1-lv4</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="shop-item" data-enabled="false">
|
||
|
|
<input type="checkbox" class="shop-checkbox" onchange="updateSelection()">
|
||
|
|
<div class="shop-name">家居生活馆</div>
|
||
|
|
<div class="shop-info">
|
||
|
|
<div class="member-status disabled">会员功能未启用</div>
|
||
|
|
<div class="member-count">会员数650</div>
|
||
|
|
</div>
|
||
|
|
<div class="current-level">当前等级lv1-lv2</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="shop-item" data-enabled="true">
|
||
|
|
<input type="checkbox" class="shop-checkbox" onchange="updateSelection()">
|
||
|
|
<div class="shop-name">运动健身店</div>
|
||
|
|
<div class="shop-info">
|
||
|
|
<div class="member-status enabled">会员功能已启用</div>
|
||
|
|
<div class="member-count">会员数980</div>
|
||
|
|
</div>
|
||
|
|
<div class="current-level">当前等级lv1-lv4</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- 底部留白 -->
|
||
|
|
<div class="bottom-spacer"></div>
|
||
|
|
|
||
|
|
<!-- 底部按钮 -->
|
||
|
|
<div class="bottom-actions">
|
||
|
|
<button class="cancel-btn">取消</button>
|
||
|
|
<button class="next-btn" id="nextBtn" disabled>下一步(<span id="nextCount">0</span>)</button>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<script>
|
||
|
|
// 更新选择状态
|
||
|
|
function updateSelection() {
|
||
|
|
const checkboxes = document.querySelectorAll('.shop-checkbox');
|
||
|
|
const shopItems = document.querySelectorAll('.shop-item');
|
||
|
|
let selectedCount = 0;
|
||
|
|
|
||
|
|
checkboxes.forEach((checkbox, index) => {
|
||
|
|
if (checkbox.checked) {
|
||
|
|
selectedCount++;
|
||
|
|
shopItems[index].classList.add('selected');
|
||
|
|
} else {
|
||
|
|
shopItems[index].classList.remove('selected');
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
// 更新选择摘要
|
||
|
|
document.getElementById('selectedCount').textContent = selectedCount;
|
||
|
|
document.getElementById('nextCount').textContent = selectedCount;
|
||
|
|
|
||
|
|
// 更新下一步按钮状态
|
||
|
|
const nextBtn = document.getElementById('nextBtn');
|
||
|
|
nextBtn.disabled = selectedCount === 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 全选
|
||
|
|
function selectAll() {
|
||
|
|
const checkboxes = document.querySelectorAll('.shop-checkbox');
|
||
|
|
checkboxes.forEach(checkbox => {
|
||
|
|
checkbox.checked = true;
|
||
|
|
});
|
||
|
|
updateSelection();
|
||
|
|
}
|
||
|
|
|
||
|
|
// 全不选
|
||
|
|
function selectNone() {
|
||
|
|
const checkboxes = document.querySelectorAll('.shop-checkbox');
|
||
|
|
checkboxes.forEach(checkbox => {
|
||
|
|
checkbox.checked = false;
|
||
|
|
});
|
||
|
|
updateSelection();
|
||
|
|
}
|
||
|
|
|
||
|
|
// 反选
|
||
|
|
function selectReverse() {
|
||
|
|
const checkboxes = document.querySelectorAll('.shop-checkbox');
|
||
|
|
checkboxes.forEach(checkbox => {
|
||
|
|
checkbox.checked = !checkbox.checked;
|
||
|
|
});
|
||
|
|
updateSelection();
|
||
|
|
}
|
||
|
|
|
||
|
|
// 仅选启用
|
||
|
|
function selectEnabled() {
|
||
|
|
const checkboxes = document.querySelectorAll('.shop-checkbox');
|
||
|
|
const shopItems = document.querySelectorAll('.shop-item');
|
||
|
|
|
||
|
|
checkboxes.forEach((checkbox, index) => {
|
||
|
|
const isEnabled = shopItems[index].getAttribute('data-enabled') === 'true';
|
||
|
|
checkbox.checked = isEnabled;
|
||
|
|
});
|
||
|
|
updateSelection();
|
||
|
|
}
|
||
|
|
|
||
|
|
// 初始化
|
||
|
|
updateSelection();
|
||
|
|
</script>
|
||
|
|
</body>
|
||
|
|
</html>
|