| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- <!DOCTYPE html>
- <html lang="zh-CN">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>会友信息考勤打卡系统</title>
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css">
- <style>
- body { padding-top: 20px; }
- .container { max-width: 800px; }
- </style>
- </head>
- <body>
- <div class="container">
- <h1 class="mb-4">会友信息考勤打卡系统</h1>
-
- <div class="form-check form-switch mb-3">
- <input class="form-check-input" type="checkbox" id="apiToggle">
- <label class="form-check-label" for="apiToggle">使用模拟API</label>
- </div>
- <form id="addMemberForm" class="mb-4">
- <div class="input-group">
- <input type="text" id="memberName" class="form-control" placeholder="输入会员姓名" required>
- <button type="submit" class="btn btn-primary">添加会员</button>
- </div>
- </form>
- <h2>会员列表</h2>
- <ul id="memberList" class="list-group mb-4"></ul>
- <h2>设备状态</h2>
- <ul id="deviceList" class="list-group"></ul>
- </div>
- <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
- <script src="/mockApi.js"></script>
- <script>
- const API_URL = '/api';
- let useMockApi = false;
- document.getElementById('apiToggle').addEventListener('change', (e) => {
- useMockApi = e.target.checked;
- fetchMembers();
- fetchDevices();
- });
- async function apiFetch(url, options = {}) {
- if (useMockApi) {
- return window.mockApi.fetch(url, options);
- }
- return fetch(url, options);
- }
- async function fetchMembers() {
- const response = await apiFetch(`${API_URL}/members`);
- const members = await response.json();
- const memberList = document.getElementById('memberList');
- memberList.innerHTML = members.map(member => `
- <li class="list-group-item d-flex justify-content-between align-items-center">
- ${member.name}
- <div>
- <button onclick="recordAttendance('${member._id}')" class="btn btn-sm btn-success">记录考勤</button>
- <button onclick="viewAttendance('${member._id}')" class="btn btn-sm btn-info">查看考勤</button>
- </div>
- </li>
- `).join('');
- }
- document.getElementById('addMemberForm').addEventListener('submit', async (e) => {
- e.preventDefault();
- const name = document.getElementById('memberName').value;
- await apiFetch(`${API_URL}/members`, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ name })
- });
- document.getElementById('memberName').value = '';
- fetchMembers();
- });
- async function recordAttendance(memberId) {
- const date = new Date().toISOString().split('T')[0];
- await apiFetch(`${API_URL}/attendance`, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ memberId, date })
- });
- alert('考勤已记录');
- }
- async function viewAttendance(memberId) {
- const response = await apiFetch(`${API_URL}/attendance/${memberId}`);
- const attendance = await response.json();
- alert(`考勤记录:\n${attendance.join('\n')}`);
- }
- async function fetchDevices() {
- const response = await apiFetch(`${API_URL}/devices`);
- const devices = await response.json();
- const deviceList = document.getElementById('deviceList');
- deviceList.innerHTML = devices.map(device => `
- <li class="list-group-item d-flex justify-content-between align-items-center">
- ${device.name} (${device.deviceId})
- <span class="badge bg-${device.status === 'online' ? 'success' : 'danger'} rounded-pill">${device.status}</span>
- </li>
- `).join('');
- }
- fetchMembers();
- fetchDevices();
- setInterval(fetchDevices, 30000); // 每30秒更新一次设备状态
- </script>
- </body>
- </html>
|