基线:全量源码首提(D1 版本控制落地,含第一轮优化 B1-B4/A1/A4/缩放修复)
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>会员管理</title>
|
||||
<style>
|
||||
body { font-family: "Microsoft YaHei UI", "Microsoft YaHei", sans-serif; font-size: 14px; margin: 20px; background: #f5f6f8; }
|
||||
h2 { margin: 0 0 14px; }
|
||||
table { border-collapse: collapse; width: 100%; background: #fff; }
|
||||
th, td { border: 1px solid #d0d4da; padding: 6px 10px; text-align: left; }
|
||||
th { background: #eef1f5; }
|
||||
tr:hover td { background: #f4f8ff; }
|
||||
.bar { margin-bottom: 12px; }
|
||||
button { padding: 5px 14px; cursor: pointer; }
|
||||
input { padding: 4px 8px; }
|
||||
.op button { margin-right: 4px; padding: 2px 8px; font-size: 12px; }
|
||||
#tip { color: #2a7; margin-left: 10px; }
|
||||
dialog { border: 1px solid #99a; border-radius: 6px; padding: 18px; }
|
||||
dialog::backdrop { background: rgba(0,0,0,.3); }
|
||||
dialog div { margin-bottom: 8px; }
|
||||
dialog label { display: inline-block; width: 80px; }
|
||||
dialog input { width: 200px; }
|
||||
.nav { margin-bottom: 16px; }
|
||||
.nav a { margin-right: 14px; color: #247; text-decoration: none; font-weight: 700; }
|
||||
.nav a.cur { color: #f60; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="nav"><a class="cur" href="/admin.html">会员管理</a><a href="/xiangmu-cloud.html">项目云管理</a></div>
|
||||
<h2>会员管理</h2>
|
||||
<div class="bar">
|
||||
手机号: <input id="q手机号" style="width:130px">
|
||||
<button onclick="查询()">查询</button>
|
||||
<button onclick="新增()">新增会员</button>
|
||||
<button onclick="加载()">刷新列表</button>
|
||||
<button onclick="保存()">保存修改</button>
|
||||
<span id="tip"></span>
|
||||
</div>
|
||||
<table id="tbl">
|
||||
<thead>
|
||||
<tr><th style="width:40px"></th><th>手机号</th><th>密码</th><th>会员类型</th><th>有效期</th><th>注册时间</th><th>备注</th></tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
|
||||
<dialog id="dlg新增">
|
||||
<h3>新增会员</h3>
|
||||
<div><label>手机号:</label><input id="n手机号"></div>
|
||||
<div><label>密码:</label><input id="n密码"></div>
|
||||
<div><label>会员类型:</label>
|
||||
<select id="n类型" onchange="n类型改()">
|
||||
<option>试用会员</option><option>月会员</option><option>季会员</option><option>年会员</option><option>永久会员</option>
|
||||
</select>
|
||||
</div>
|
||||
<div><label>有效期:</label><input id="n有效期" placeholder="2027-05-13"></div>
|
||||
<div style="text-align:right;margin-top:10px">
|
||||
<button onclick="dlg新增.close()">取消</button>
|
||||
<button onclick="确定新增()">确定</button>
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<script>
|
||||
var 数据 = [];
|
||||
|
||||
function 提示(s, ok) {
|
||||
var t = document.getElementById('tip');
|
||||
t.textContent = s; t.style.color = ok ? '#2a7' : '#c33';
|
||||
setTimeout(function(){ t.textContent=''; }, 3000);
|
||||
}
|
||||
// 会员类型 → 有效期天数(永久会员=永久);改类型时自动算有效期
|
||||
var 类型天数 = { '试用会员': 30, '月会员': 1, '季会员': 3, '年会员': 12, '永久会员': 0 };
|
||||
function 今天加月(n) {
|
||||
var d = new Date(); d.setMonth(d.getMonth() + n);
|
||||
return d.getFullYear() + '-' + ('0'+(d.getMonth()+1)).slice(-2) + '-' + ('0'+d.getDate()).slice(-2);
|
||||
}
|
||||
function 改类型(i, v) {
|
||||
if (!数据[i]) return;
|
||||
数据[i]['会员类型'] = v;
|
||||
var n = 类型天数[v];
|
||||
if (n === undefined) return; // 自定义类型不动有效期
|
||||
数据[i]['有效期'] = n === 0 ? '永久' : 今天加月(n);
|
||||
渲染(); // 重渲染让有效期输入框同步显示新值
|
||||
}
|
||||
function 加载() {
|
||||
fetch('/api/list').then(r => r.json()).then(j => {
|
||||
数据 = j['会员'] || [];
|
||||
渲染();
|
||||
});
|
||||
}
|
||||
function 渲染() {
|
||||
var q = document.getElementById('q手机号').value.trim();
|
||||
var tb = document.getElementById('tbl').getElementsByTagName('tbody')[0];
|
||||
tb.innerHTML = '';
|
||||
数据.forEach(function (m, i) {
|
||||
if (q && (m['手机号']||'').indexOf(q) < 0) return;
|
||||
var tr = tb.insertRow();
|
||||
tr.insertCell().innerHTML = '<input type="checkbox" data-i="'+i+'" class="sel">';
|
||||
tr.insertCell().innerHTML = '<input value="'+(m['手机号']||'')+'" onchange="改('+i+',\'手机号\',this.value)" style="width:120px">';
|
||||
tr.insertCell().innerHTML = '<input value="'+(m['密码']||'')+'" onchange="改('+i+',\'密码\',this.value)" style="width:100px">';
|
||||
tr.insertCell().innerHTML = '<select onchange="改类型('+i+',this.value)" style="width:90px">'
|
||||
+ ['试用会员','月会员','季会员','年会员','永久会员'].map(function(t){ return '<option'+((m['会员类型']||'')===t?' selected':'')+'>'+t+'</option>'; }).join('')
|
||||
+ '</select>';
|
||||
tr.insertCell().innerHTML = '<input value="'+(m['有效期']||'')+'" onchange="改('+i+',\'有效期\',this.value)" style="width:100px">';
|
||||
tr.insertCell().textContent = m['注册时间'] || '';
|
||||
tr.insertCell().innerHTML = '<input value="'+(m['备注']||'')+'" onchange="改('+i+',\'备注\',this.value)" style="width:120px">';
|
||||
var op = tr.insertCell(); op.className = 'op';
|
||||
var del = document.createElement('button');
|
||||
del.textContent = '删除';
|
||||
del.onclick = function () {
|
||||
if (!confirm('确定删除会员 ' + m['手机号'] + ' ?')) return;
|
||||
数据.splice(i, 1); 渲染(); 保存();
|
||||
};
|
||||
op.appendChild(del);
|
||||
});
|
||||
}
|
||||
function 改(i, k, v) { if (数据[i]) { 数据[i][k] = v; } }
|
||||
// 新增弹窗:选类型 → 自动填有效期(手改过则以手改为准,切类型才覆盖)
|
||||
function n类型改() {
|
||||
var v = document.getElementById('n类型').value;
|
||||
var n = 类型天数[v];
|
||||
if (n === undefined) return;
|
||||
document.getElementById('n有效期').value = n === 0 ? '永久' : 今天加月(n);
|
||||
}
|
||||
function 保存() {
|
||||
fetch('/api/save', { method:'POST', headers:{'Content-Type':'application/json'},
|
||||
body: JSON.stringify({ '会员': 数据 }) })
|
||||
.then(r => r.json()).then(j => 提示(j.ok ? '已保存' : '保存失败:'+(j.msg||''), j.ok));
|
||||
}
|
||||
function 查询() { 渲染(); }
|
||||
function 新增() { document.getElementById('dlg新增').showModal(); }
|
||||
function 确定新增() {
|
||||
var 手机号 = document.getElementById('n手机号').value.trim();
|
||||
var 密码 = document.getElementById('n密码').value.trim();
|
||||
if (!手机号 || !密码) { alert('手机号和密码不能为空'); return; }
|
||||
fetch('/api/register', { method:'POST', headers:{'Content-Type':'application/json'},
|
||||
body: JSON.stringify({ 手机号: 手机号, 密码: 密码 }) })
|
||||
.then(r => r.json()).then(function (j) {
|
||||
if (!j.ok) { alert(j.msg); return; }
|
||||
// 注册默认"试用会员",把用户在弹窗选的类型/有效期补上
|
||||
var 类型 = document.getElementById('n类型').value;
|
||||
var 有效期 = document.getElementById('n有效期').value.trim();
|
||||
加载后设置(手机号, 类型, 有效期);
|
||||
document.getElementById('dlg新增').close();
|
||||
});
|
||||
}
|
||||
function 加载后设置(手机号, 类型, 有效期) {
|
||||
fetch('/api/list').then(r => r.json()).then(function (j) {
|
||||
var list = j['会员'] || [];
|
||||
list.forEach(function (m) {
|
||||
if (m['手机号'] === 手机号) {
|
||||
if (类型) m['会员类型'] = 类型;
|
||||
if (有效期) m['有效期'] = 有效期;
|
||||
}
|
||||
});
|
||||
fetch('/api/save', { method:'POST', headers:{'Content-Type':'application/json'},
|
||||
body: JSON.stringify({ '会员': list }) }).then(function () { 加载(); });
|
||||
});
|
||||
}
|
||||
加载();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user