feat: 更新蓝牙体重秤小程序原型页面及后台管理页面

This commit is contained in:
liuyunqin
2026-07-17 17:28:24 +08:00
parent 6c6e92219a
commit 8a96ead2c8
7 changed files with 674 additions and 235 deletions
+231 -76
View File
@@ -67,7 +67,7 @@
.tag-red{background:#FFF1F0;color:var(--danger);}
.link{color:var(--primary);cursor:pointer;font-size:var(--font-sm);text-decoration:none;}.link:hover{color:#40a9ff;}
.link-danger{color:var(--danger);cursor:pointer;font-size:var(--font-sm);text-decoration:none;}.link-danger:hover{color:#ff7875;}
/* 成员查看弹窗 */
/* 成员管理弹窗 */
.modal-mask{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.45);z-index:1000;display:none;align-items:center;justify-content:center;}
.modal-mask.active{display:flex;}
.modal{background:#fff;border-radius:var(--radius-lg);width:90vw;max-width:1100px;max-height:80vh;display:flex;flex-direction:column;box-shadow:0 8px 40px rgba(0,0,0,0.15);}
@@ -92,6 +92,30 @@
.member-table th:nth-child(7){width:90px;}
.member-table tbody tr:last-child td{border-bottom:none;}
.tag-blue{background:var(--primary-light);color:var(--primary);display:inline-flex;align-items:center;padding:2px 8px;border-radius:10px;font-size:var(--font-xs);}
/* 添加成员按钮 */
.member-toolbar{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px;}
/* 添加成员弹窗 */
.add-member-modal{width:560px;}
.search-wrap{position:relative;margin-bottom:16px;}
.search-wrap input{width:100%;height:40px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);outline:none;}
.search-wrap input:focus{border-color:var(--primary);}
.search-dropdown{position:absolute;top:42px;left:0;right:0;background:#fff;border:1px solid var(--border);border-radius:var(--radius-sm);box-shadow:0 4px 12px rgba(0,0,0,0.12);max-height:200px;overflow-y:auto;display:none;z-index:10;}
.search-dropdown--show{display:block;}
.search-dropdown__item{padding:10px 14px;cursor:pointer;font-size:var(--font-sm);border-bottom:1px solid #f5f5f5;display:flex;justify-content:space-between;align-items:center;}
.search-dropdown__item:hover,.search-dropdown__item.active{background:var(--primary-light);}
.search-dropdown__item:last-child{border-bottom:none;}
.search-dropdown__name{font-weight:500;color:var(--text-primary);}
.search-dropdown__no{font-size:var(--font-xs);color:var(--text-placeholder);}
.employee-card{background:#F5F7FA;border-radius:var(--radius-md);padding:16px;margin-top:16px;display:none;}
.employee-card--show{display:block;}
.employee-card__title{font-size:var(--font-sm);font-weight:600;color:var(--text-primary);margin-bottom:12px;display:flex;align-items:center;gap:6px;}
.employee-card__grid{display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px;}
.employee-card__item{display:flex;flex-direction:column;gap:2px;}
.employee-card__label{font-size:var(--font-xs);color:var(--text-placeholder);}
.employee-card__value{font-size:var(--font-sm);color:var(--text-primary);font-weight:500;}
.modal__footer{display:flex;justify-content:flex-end;gap:12px;padding:16px 24px;border-top:1px solid var(--border);}
.btn-cancel{height:36px;padding:0 24px;border-radius:var(--radius-sm);font-size:var(--font-sm);cursor:pointer;background:#fff;color:var(--text-primary);border:1px solid var(--border);transition:all .2s;}
.btn-cancel:hover{color:var(--primary);border-color:var(--primary);}
/* 分页 */
.pagination{display:flex;align-items:center;justify-content:flex-end;padding:16px 24px;gap:8px;border-top:1px solid var(--border);}
.pagination span{font-size:var(--font-sm);color:var(--text-secondary);}
@@ -169,6 +193,7 @@
<button class="btn btn-default">导出列表数据</button>
<button class="btn btn-default">查看导出任务</button>
<button class="btn btn-success">批量入库导入</button>
<button class="btn btn-success">批量添加成员</button>
<button class="btn btn-default">查看导入任务</button>
</div>
<!-- 数据列表 -->
@@ -177,11 +202,11 @@
<table>
<thead><tr><th>设备编码</th><th>设备名称</th><th>设备厂商</th><th>设备型号</th><th>所属单位</th><th>布放位置</th><th>入库日期</th><th>设备状态</th><th>操作</th></tr></thead>
<tbody>
<tr><td>BT-2024-001</td><td>蓝牙称A1</td><td>华为</td><td>HW-S100</td><td>采油一厂</td><td>职工活动中心1F</td><td>2024-03-15</td><td><span class="tag tag-green">正常</span></td><td><a class="link">详情</a> <a class="link" onclick="openMemberModal(0)">成员查看</a> <a class="link">编辑</a> <a class="link-danger">删除</a></td></tr>
<tr><td>BT-2024-002</td><td>蓝牙称A2</td><td>小米</td><td>MI-Scale2</td><td>采油一厂</td><td>办公楼2F健身房</td><td>2024-03-18</td><td><span class="tag tag-green">正常</span></td><td><a class="link">详情</a> <a class="link" onclick="openMemberModal(1)">成员查看</a> <a class="link">编辑</a> <a class="link-danger">删除</a></td></tr>
<tr><td>BT-2024-003</td><td>蓝牙称B1</td><td>乐心</td><td>LX-Pro</td><td>采油二厂</td><td>员工食堂入口</td><td>2024-04-02</td><td><span class="tag tag-orange">维护中</span></td><td><a class="link">详情</a> <a class="link" onclick="openMemberModal(2)">成员查看</a> <a class="link">编辑</a> <a class="link-danger">删除</a></td></tr>
<tr><td>BT-2024-004</td><td>蓝牙称B2</td><td>华为</td><td>HW-S100</td><td>采油二厂</td><td>宿舍楼大厅</td><td>2024-04-10</td><td><span class="tag tag-green">正常</span></td><td><a class="link">详情</a> <a class="link" onclick="openMemberModal(3)">成员查看</a> <a class="link">编辑</a> <a class="link-danger">删除</a></td></tr>
<tr><td>BT-2024-005</td><td>蓝牙称C1</td><td>小米</td><td>MI-Scale2</td><td>采气厂</td><td>综合办公楼1F</td><td>2024-05-08</td><td><span class="tag tag-red">已停用</span></td><td><a class="link">详情</a> <a class="link" onclick="openMemberModal(4)">成员查看</a> <a class="link">编辑</a> <a class="link-danger">删除</a></td></tr>
<tr><td>BT-2024-001</td><td>蓝牙称A1</td><td>华为</td><td>HW-S100</td><td>采油一厂</td><td>职工活动中心1F</td><td>2024-03-15</td><td><span class="tag tag-green">正常</span></td><td><a class="link">详情</a> <a class="link" onclick="openMemberModal(0)">成员管理</a> <a class="link">编辑</a> <a class="link-danger">删除</a></td></tr>
<tr><td>BT-2024-002</td><td>蓝牙称A2</td><td>小米</td><td>MI-Scale2</td><td>采油一厂</td><td>办公楼2F健身房</td><td>2024-03-18</td><td><span class="tag tag-green">正常</span></td><td><a class="link">详情</a> <a class="link" onclick="openMemberModal(1)">成员管理</a> <a class="link">编辑</a> <a class="link-danger">删除</a></td></tr>
<tr><td>BT-2024-003</td><td>蓝牙称B1</td><td>乐心</td><td>LX-Pro</td><td>采油二厂</td><td>员工食堂入口</td><td>2024-04-02</td><td><span class="tag tag-orange">维护中</span></td><td><a class="link">详情</a> <a class="link" onclick="openMemberModal(2)">成员管理</a> <a class="link">编辑</a> <a class="link-danger">删除</a></td></tr>
<tr><td>BT-2024-004</td><td>蓝牙称B2</td><td>华为</td><td>HW-S100</td><td>采油二厂</td><td>宿舍楼大厅</td><td>2024-04-10</td><td><span class="tag tag-green">正常</span></td><td><a class="link">详情</a> <a class="link" onclick="openMemberModal(3)">成员管理</a> <a class="link">编辑</a> <a class="link-danger">删除</a></td></tr>
<tr><td>BT-2024-005</td><td>蓝牙称C1</td><td>小米</td><td>MI-Scale2</td><td>采气厂</td><td>综合办公楼1F</td><td>2024-05-08</td><td><span class="tag tag-red">已停用</span></td><td><a class="link">详情</a> <a class="link" onclick="openMemberModal(4)">成员管理</a> <a class="link">编辑</a> <a class="link-danger">删除</a></td></tr>
</tbody>
</table>
</div>
@@ -198,77 +223,207 @@
<script>function toggleSubgroup(h){var p=h.parentElement;var sidebar=p.closest("aside");if(sidebar)sidebar.querySelectorAll(".sidebar-subgroup.open").forEach(function(g){if(g!==p)g.classList.remove("open");});p.classList.toggle("open");}(function(){var a=document.querySelector('.sidebar-item.active');if(!a)return;var sidebar=document.querySelector('aside');if(sidebar)sidebar.querySelectorAll('.sidebar-subgroup.open').forEach(function(g){g.classList.remove('open');});var s=a.closest('.sidebar-subgroup');if(s)s.classList.add('open');})();
// 成员查看弹窗数据
var deviceData = [
{ code:'BT-2024-001', name:'蓝牙称A1', dept:'采油一厂' },
{ code:'BT-2024-002', name:'蓝牙称A2', dept:'采油一厂' },
{ code:'BT-2024-003', name:'蓝牙称B1', dept:'采油二厂' },
{ code:'BT-2024-004', name:'蓝牙称B2', dept:'采油二厂' },
{ code:'BT-2024-005', name:'蓝牙称C1', dept:'采气厂' }
];
var memberData = [
[
{ name:'张伟', idCard:'610102199001125517', gender:'男', age:36, height:175, isCQ:true, empNo:'CQ10023' },
{ name:'李娜', idCard:'610103198805083024', gender:'女', age:38, height:162, isCQ:true, empNo:'CQ10045' },
{ name:'王强', idCard:'610104199203176831', gender:'男', age:34, height:180, isCQ:false, empNo:'' }
],
[
{ name:'赵敏', idCard:'610105199106224519', gender:'女', age:35, height:165, isCQ:true, empNo:'CQ10078' },
{ name:'刘洋', idCard:'610106198912081237', gender:'男', age:37, height:172, isCQ:true, empNo:'CQ10091' }
],
[
{ name:'陈磊', idCard:'610107199305142618', gender:'男', age:33, height:178, isCQ:true, empNo:'CQ20015' },
{ name:'周芳', idCard:'610108199008273945', gender:'女', age:36, height:160, isCQ:false, empNo:'' },
{ name:'吴刚', idCard:'610109198711054372', gender:'男', age:39, height:176, isCQ:true, empNo:'CQ20032' },
{ name:'孙丽', idCard:'610110199204186523', gender:'女', age:34, height:163, isCQ:true, empNo:'CQ20041' }
],
[
{ name:'马超', idCard:'610111199107093841', gender:'男', age:35, height:182, isCQ:true, empNo:'CQ20056' }
],
[
{ name:'黄蓉', idCard:'610112199309157264', gender:'女', age:33, height:158, isCQ:true, empNo:'CQ30012' },
{ name:'郭靖', idCard:'610113198806241058', gender:'男', age:38, height:179, isCQ:false, empNo:'' }
]
];
// 成员管理弹窗数据
var deviceData = [
{ code:'BT-2024-001', name:'蓝牙称A1', dept:'采油一厂', model:'HW-S100' },
{ code:'BT-2024-002', name:'蓝牙称A2', dept:'采油一厂', model:'MI-Scale2' },
{ code:'BT-2024-003', name:'蓝牙称B1', dept:'采油二厂', model:'LX-Pro' },
{ code:'BT-2024-004', name:'蓝牙称B2', dept:'采油二厂', model:'HW-S100' },
{ code:'BT-2024-005', name:'蓝牙称C1', dept:'采气厂', model:'MI-Scale2' }
];
var memberData = [
[
{ name:'张伟', idCard:'610102199001125517', gender:'男', age:36, height:175, isCQ:true, empNo:'CQ10023', synced:true },
{ name:'李娜', idCard:'610103198805083024', gender:'女', age:38, height:162, isCQ:true, empNo:'CQ10045', synced:true },
{ name:'王强', idCard:'610104199203176831', gender:'男', age:34, height:180, isCQ:false, empNo:'', synced:false }
],
[
{ name:'赵敏', idCard:'610105199106224519', gender:'女', age:35, height:165, isCQ:true, empNo:'CQ10078', synced:true },
{ name:'刘洋', idCard:'610106198912081237', gender:'男', age:37, height:172, isCQ:true, empNo:'CQ10091', synced:true }
],
[
{ name:'陈磊', idCard:'610107199305142618', gender:'男', age:33, height:178, isCQ:true, empNo:'CQ20015', synced:true },
{ name:'周芳', idCard:'610108199008273945', gender:'女', age:36, height:160, isCQ:false, empNo:'', synced:false },
{ name:'吴刚', idCard:'610109198711054372', gender:'男', age:39, height:176, isCQ:true, empNo:'CQ20032', synced:true },
{ name:'孙丽', idCard:'610110199204186523', gender:'女', age:34, height:163, isCQ:true, empNo:'CQ20041', synced:false }
],
[
{ name:'马超', idCard:'610111199107093841', gender:'男', age:35, height:182, isCQ:true, empNo:'CQ20056', synced:true }
],
[
{ name:'黄蓉', idCard:'610112199309157264', gender:'女', age:33, height:158, isCQ:true, empNo:'CQ30012', synced:true },
{ name:'郭靖', idCard:'610113198806241058', gender:'男', age:38, height:179, isCQ:false, empNo:'', synced:true }
]
];
function openMemberModal(idx) {
var dev = deviceData[idx];
var members = memberData[idx];
document.getElementById('modalDevName').textContent = dev.name;
document.getElementById('modalDevCode').textContent = dev.code;
document.getElementById('modalDevDept').textContent = dev.dept;
var tbody = document.getElementById('memberTbody');
tbody.innerHTML = members.map(function(m) {
var tagHtml = m.isCQ ? '<span class="tag-blue">是</span>' : '<span style="color:#999">否</span>';
var empHtml = m.isCQ ? m.empNo : '-';
return '<tr><td>'+m.name+'</td><td>'+m.idCard+'</td><td>'+m.gender+'</td><td>'+m.age+'</td><td>'+m.height+' cm</td><td>'+tagHtml+'</td><td>'+empHtml+'</td></tr>';
}).join('');
document.getElementById('memberModal').classList.add('active');
}
function closeMemberModal() {
document.getElementById('memberModal').classList.remove('active');
}
</script>
function openMemberModal(idx) {
var dev = deviceData[idx];
var members = memberData[idx];
document.getElementById('modalDevName').textContent = dev.name;
document.getElementById('modalDevCode').textContent = dev.code;
document.getElementById('modalDevDept').textContent = dev.dept;
document.getElementById('modalDevModel').textContent = dev.model;
// 存储当前设备索引,供添加成员时使用
document.getElementById('memberModal').setAttribute('data-device-idx', idx);
var tbody = document.getElementById('memberTbody');
tbody.innerHTML = members.map(function(m) {
var tagHtml = m.isCQ ? '<span class="tag-blue">是</span>' : '<span style="color:#999">否</span>';
var empHtml = m.isCQ ? m.empNo : '-';
var syncHtml = m.synced ? '<span class="tag tag-green">是</span>' : '<span class="tag tag-orange">否</span>';
return '<tr><td>'+m.name+'</td><td>'+m.idCard+'</td><td>'+m.gender+'</td><td>'+m.age+'</td><td>'+m.height+' cm</td><td>'+tagHtml+'</td><td>'+empHtml+'</td><td>'+syncHtml+'</td></tr>';
}).join('');
document.getElementById('memberModal').classList.add('active');
}
function closeMemberModal() {
document.getElementById('memberModal').classList.remove('active');
}
<!-- 成员查看弹窗 -->
<div class="modal-mask" id="memberModal" onclick="if(event.target===this)closeMemberModal()">
<div class="modal">
<div class="modal__header">
<h3>成员查看</h3>
<button class="modal__close" onclick="closeMemberModal()">&times;</button>
</div>
<div class="modal__body">
<div class="device-info">
<div class="device-info__item"><span class="device-info__label">设备名称</span><span class="device-info__value" id="modalDevName">-</span></div>
<div class="device-info__item"><span class="device-info__label">设备编码</span><span class="device-info__value" id="modalDevCode">-</span></div>
<div class="device-info__item"><span class="device-info__label">所属单位</span><span class="device-info__value" id="modalDevDept">-</span></div>
</div>
<table class="member-table">
<thead><tr><th>姓名</th><th>身份证</th><th>性别</th><th>年龄</th><th>身高</th><th>是否为CQ员工</th><th>员工编号</th></tr></thead>
<tbody id="memberTbody"></tbody>
</table>
</div>
</div>
</div>
/* ===== 添加成员 ===== */
var allEmployees = [
{ name:'赵建国', empNo:'CQ10001', gender:'男', age:42, unit:'采油一厂', dept:'技术部-研发组' },
{ name:'钱晓燕', empNo:'CQ10002', gender:'女', age:35, unit:'采油一厂', dept:'综合办公室' },
{ name:'孙志强', empNo:'CQ10003', gender:'男', age:38, unit:'采油一厂', dept:'生产运行部' },
{ name:'李红梅', empNo:'CQ20004', gender:'女', age:31, unit:'采油二厂', dept:'人力资源部' },
{ name:'周文博', empNo:'CQ20005', gender:'男', age:45, unit:'采油二厂', dept:'安全环保部' },
{ name:'吴晓峰', empNo:'CQ30006', gender:'男', age:33, unit:'采气厂', dept:'工程技术部' },
{ name:'郑丽华', empNo:'CQ30007', gender:'女', age:40, unit:'采气厂', dept:'质量监督站' },
{ name:'王大军', empNo:'CQ10008', gender:'男', age:37, unit:'采油一厂', dept:'设备管理部' }
];
var _selectedEmployee = null;
// 点击外部关闭搜索下拉
document.addEventListener('click', function(e) {
var wrap = document.querySelector('.search-wrap');
if (wrap && !wrap.contains(e.target)) {
document.getElementById('searchDropdown').classList.remove('search-dropdown--show');
}
});
function openAddMemberModal() {
document.getElementById('addMemberModal').classList.add('active');
document.getElementById('employeeSearch').value = '';
document.getElementById('employeeCard').classList.remove('employee-card--show');
document.getElementById('searchDropdown').classList.remove('search-dropdown--show');
document.getElementById('btnConfirmAdd').disabled = true;
_selectedEmployee = null;
}
function closeAddMemberModal() {
document.getElementById('addMemberModal').classList.remove('active');
}
function searchEmployee() {
var kw = document.getElementById('employeeSearch').value.trim().toLowerCase();
var dropdown = document.getElementById('searchDropdown');
if (!kw) {
dropdown.classList.remove('search-dropdown--show');
return;
}
var results = allEmployees.filter(function(e) {
return e.name.toLowerCase().indexOf(kw) !== -1 || e.empNo.toLowerCase().indexOf(kw) !== -1;
});
if (results.length === 0) {
dropdown.innerHTML = '<div class="search-dropdown__item" style="color:#999;cursor:default;">未找到匹配的员工</div>';
} else {
dropdown.innerHTML = results.map(function(e) {
return '<div class="search-dropdown__item" onclick="selectEmployee(\''+e.empNo+'\')"><span class="search-dropdown__name">'+e.name+'</span><span class="search-dropdown__no">'+e.empNo+'</span></div>';
}).join('');
}
dropdown.classList.add('search-dropdown--show');
}
function selectEmployee(empNo) {
var emp = allEmployees.find(function(e) { return e.empNo === empNo; });
if (!emp) return;
_selectedEmployee = emp;
document.getElementById('employeeSearch').value = emp.name + ' (' + emp.empNo + ')';
document.getElementById('searchDropdown').classList.remove('search-dropdown--show');
// 填充员工信息卡片
document.getElementById('empName').textContent = emp.name;
document.getElementById('empNo').textContent = emp.empNo;
document.getElementById('empGender').textContent = emp.gender;
document.getElementById('empAge').textContent = emp.age;
document.getElementById('empUnit').textContent = emp.unit;
document.getElementById('empDept').textContent = emp.dept;
document.getElementById('employeeCard').classList.add('employee-card--show');
document.getElementById('btnConfirmAdd').disabled = false;
}
function confirmAddMember() {
if (!_selectedEmployee) return;
var idx = parseInt(document.getElementById('memberModal').getAttribute('data-device-idx')) || 0;
var emp = _selectedEmployee;
// 检查是否已存在
var exists = memberData[idx].some(function(m) { return m.empNo === emp.empNo; });
if (exists) {
alert('该员工已在该设备成员列表中');
return;
}
memberData[idx].push({
name: emp.name, idCard: '', gender: emp.gender, age: emp.age,
height: 170, isCQ: true, empNo: emp.empNo, synced: false
});
// 刷新成员列表
openMemberModal(idx);
closeAddMemberModal();
}
</script>
<!-- 成员管理弹窗 -->
<div class="modal-mask" id="memberModal" onclick="if(event.target===this)closeMemberModal()">
<div class="modal">
<div class="modal__header">
<h3>成员管理</h3>
<button class="modal__close" onclick="closeMemberModal()">&times;</button>
</div>
<div class="modal__body">
<div class="device-info">
<div class="device-info__item"><span class="device-info__label">设备名称</span><span class="device-info__value" id="modalDevName">-</span></div>
<div class="device-info__item"><span class="device-info__label">设备编码</span><span class="device-info__value" id="modalDevCode">-</span></div>
<div class="device-info__item"><span class="device-info__label">设备型号</span><span class="device-info__value" id="modalDevModel">-</span></div>
<div class="device-info__item"><span class="device-info__label">所属单位</span><span class="device-info__value" id="modalDevDept">-</span></div>
</div>
<div class="member-toolbar">
<span style="font-size:var(--font-sm);font-weight:600;color:var(--text-primary);">成员列表</span>
<button class="btn btn-primary" onclick="openAddMemberModal()">+ 添加成员</button>
</div>
<table class="member-table">
<thead><tr><th>姓名</th><th>身份证</th><th>性别</th><th>年龄</th><th>身高</th><th>是否为CQ员工</th><th>员工编号</th><th>同步设备</th></tr></thead>
<tbody id="memberTbody"></tbody>
</table>
</div>
</div>
</div>
<!-- 添加成员弹窗 -->
<div class="modal-mask" id="addMemberModal" onclick="if(event.target===this)closeAddMemberModal()">
<div class="modal add-member-modal">
<div class="modal__header">
<h3>添加成员</h3>
<button class="modal__close" onclick="closeAddMemberModal()">&times;</button>
</div>
<div class="modal__body">
<div class="search-wrap">
<input type="text" id="employeeSearch" placeholder="请输入员工姓名或编号搜索" oninput="searchEmployee()" onfocus="searchEmployee()" autocomplete="off">
<div class="search-dropdown" id="searchDropdown"></div>
</div>
<div class="employee-card" id="employeeCard">
<div class="employee-card__title">📋 员工信息</div>
<div class="employee-card__grid">
<div class="employee-card__item"><span class="employee-card__label">姓名</span><span class="employee-card__value" id="empName">-</span></div>
<div class="employee-card__item"><span class="employee-card__label">员工编号</span><span class="employee-card__value" id="empNo">-</span></div>
<div class="employee-card__item"><span class="employee-card__label">性别</span><span class="employee-card__value" id="empGender">-</span></div>
<div class="employee-card__item"><span class="employee-card__label">年龄</span><span class="employee-card__value" id="empAge">-</span></div>
<div class="employee-card__item"><span class="employee-card__label">单位</span><span class="employee-card__value" id="empUnit">-</span></div>
<div class="employee-card__item"><span class="employee-card__label">部门</span><span class="employee-card__value" id="empDept">-</span></div>
</div>
</div>
</div>
<div class="modal__footer">
<button class="btn-cancel" onclick="closeAddMemberModal()">取消</button>
<button class="btn btn-primary" id="btnConfirmAdd" onclick="confirmAddMember()" disabled>确定</button>
</div>
</div>
</div>
</body>
</html>