最近较火的还活着么签到系统HTML源码

最近较火的还活着么签到系统HTML源码

系统概述

“还活着么签到系统”是一个轻量级的单页HTML应用,专为个人安全签到设计。用户通过每日签到向紧急联系人确认自身安全状态,当连续多日未签到时,系统会模拟向紧急联系人发送短信通知。所有数据存储在浏览器本地,无需后端支持,开箱即用。

该系统特别适合需要定期确认安全的独居人士、户外工作者或特殊职业人群使用,也可作为个人健康安全管理的简单工具。

技术特点

  • 纯前端实现 – 单HTML文件,无需服务器端支持
  • 本地数据存储 – 使用localStorage保存所有数据
  • 响应式设计 – 适配手机和PC浏览器
  • 模拟短信通知 – 可扩展为真实短信服务
  • 轻量简洁 – 文件体积小,加载速度快

功能特点

🏠 用户注册

  • 手机号注册验证(11位数字)
  • 数据本地存储,保护用户隐私

👨‍👩‍👧 紧急联系人设置

  • 设置亲属或朋友为紧急联系人
  • 支持填写关系说明(如:父亲、母亲、配偶等)
  • 联系人不能是自己,确保安全机制有效

✅ 每日签到

  • 简洁的签到按钮,一键完成签到
  • 显示当天签到状态和签到时间
  • 签到记录本地保存

📊 签到历史

  • 查看所有历史签到记录
  • 按日期排序,最新记录置顶
  • 清晰的日期和时间显示

📱 安全提醒机制

  • 连续3天未签到触发短信通知
  • 模拟向紧急联系人发送提醒短信
  • 可扩展为真实阿里云短信服务

⚙️ 系统配置

  • 预留阿里云短信服务配置界面
  • 支持AccessKey ID、Secret、签名和模板代码配置
  • 界面显示配置状态

使用说明

首次使用

  1. 打开系统页面
  • 将HTML文件保存在任意位置
  • 用浏览器打开该文件
  1. 注册账号
  • 输入11位手机号完成注册
  • 系统会自动跳转到紧急联系人设置
  1. 设置紧急联系人
  • 填写联系人姓名、手机号和关系
  • 联系人手机号不能与注册手机号相同
  • 建议填写直系亲属信息

日常使用

  1. 每日签到
  • 每日访问系统页面
  • 点击”今日签到”按钮
  • 系统记录签到时间和日期
  1. 查看签到历史
  • 在签到页面下方查看历史记录
  • 了解自己的签到习惯
  1. 安全机制
  • 如果连续3天未签到
  • 系统会模拟发送短信给紧急联系人
  • 提示联系人关注用户安全状态

技术实现

数据存储

// 数据存储在localStorage中
let userData = {
    phone: '',
    emergencyContact: {
        name: '',
        phone: '',
        relationship: ''
    },
    checkInHistory: [],
    lastCheckInDate: null
};

// 保存数据
localStorage.setItem('checkInData', JSON.stringify(userData));

签到逻辑

  1. 检查当日是否已签到
  2. 记录签到时间和日期
  3. 更新最后签到日期
  4. 刷新界面显示

安全提醒

  1. 定时检查连续未签到天数
  2. 连续3天未签到触发提醒
  3. 模拟短信发送流程
  4. 提供真实短信接口扩展点

部署方式

最简单部署

  1. 保存HTML文件到本地
  2. 用浏览器直接打开文件
  3. 开始使用

Web服务器部署

  1. 将HTML文件上传到任意Web服务器
  2. 通过URL访问页面
  3. 支持多设备访问(数据在各设备独立)

静态托管服务

  • GitHub Pages
  • Netlify
  • Vercel
  • 云存储静态网站托管

扩展开发

添加后端支持

对于需要数据持久化或多用户支持的场景,可扩展后端功能:

// 示例:添加API调用
async function saveToServer(data) {
    const response = await fetch('https://api.example.com/checkin', {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify(data)
    });
    return response.json();
}

// 替换localStorage调用
// localStorage.setItem('checkInData', JSON.stringify(userData));
// 改为:
// saveToServer(userData);

集成真实短信服务

  1. 注册阿里云短信服务
  2. 获取AccessKey ID和Secret
  3. 配置短信签名和模板
  4. 替换模拟发送函数为真实API调用
// 真实短信发送示例
async function sendRealSMS(contactPhone, message) {
    // 调用阿里云短信API
    // 实现真实短信发送逻辑
}

添加多语言支持

  1. 创建语言包对象
  2. 根据用户选择切换语言
  3. 更新界面文本显示

增加数据导出功能

  1. 添加导出按钮
  2. 将签到历史导出为CSV或PDF
  3. 支持打印功能

注意事项

隐私安全

  1. 本地存储:所有数据仅保存在用户浏览器中,更换设备或清除缓存会丢失数据
  2. 手机号处理:界面显示时会自动隐藏中间4位保护隐私
  3. 联系人信息:建议告知联系人被设置为紧急联系人

使用限制

  1. 数据持久性:本地存储不适合长期重要数据备份
  2. 多设备同步:不支持多设备间数据同步
  3. 短信功能:当前为模拟发送,需要真实功能需自行集成

浏览器兼容性

  • 支持所有现代浏览器(Chrome、Firefox、Safari、Edge)
  • 需要启用JavaScript
  • 建议使用最新版本浏览器

定制建议

界面定制

  1. 修改CSS样式调整颜色和布局
  2. 添加品牌Logo和名称
  3. 调整响应式断点适应不同设备

功能增强

  1. 添加签到提醒(浏览器通知)
  2. 支持多个紧急联系人
  3. 添加签到备注功能
  4. 实现数据备份到云端

安全加强

  1. 添加登录密码保护
  2. 实现数据加密存储
  3. 添加操作日志记录

免责声明

本系统为个人开发项目,仅供学习和个人使用。系统提供的安全提醒功能为模拟实现,不能替代真实的安全保障措施。用户应对自身安全负责,建议结合其他安全措施使用。

对于因使用本系统造成的任何直接或间接损失,开发者不承担任何责任。

效果预览

图片[1]-最近较火的还活着么签到系统HTML源码-QQ沐编程

源代码

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>活着么签到系统-QQ沐编程qqmu.com</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
        }
         
        body {
            background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 20px;
        }
         
        .container {
            width: 100%;
            max-width: 500px;
            background: white;
            border-radius: 16px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
            overflow: hidden;
        }
         
        .header {
            background: #4a6bdf;
            color: white;
            padding: 25px 20px;
            text-align: center;
        }
         
        .header h1 {
            font-size: 24px;
            font-weight: 600;
        }
         
        .form-container {
            padding: 25px;
        }
         
        .form-group {
            margin-bottom: 20px;
        }
         
        .form-group label {
            display: block;
            margin-bottom: 8px;
            font-weight: 500;
            color: #333;
        }
         
        .form-group input {
            width: 100%;
            padding: 14px;
            border: 1px solid #ddd;
            border-radius: 8px;
            font-size: 16px;
            transition: border-color 0.3s;
        }
         
        .form-group input:focus {
            border-color: #4a6bdf;
            outline: none;
            box-shadow: 0 0 0 2px rgba(74, 107, 223, 0.2);
        }
         
        .btn {
            width: 100%;
            padding: 14px;
            background: #4a6bdf;
            color: white;
            border: none;
            border-radius: 8px;
            font-size: 16px;
            font-weight: 500;
            cursor: pointer;
            transition: background 0.3s;
        }
         
        .btn:hover {
            background: #3a5bce;
        }
         
        .btn:disabled {
            background: #b0b0b0;
            cursor: not-allowed;
        }
         
        .view {
            display: none;
        }
         
        .view.active {
            display: block;
            animation: fadeIn 0.3s ease;
        }
         
        @keyframes fadeIn {
            from { opacity: 0; }
            to { opacity: 1; }
        }
         
        .user-info {
            background: #f9f9f9;
            padding: 15px;
            border-radius: 8px;
            margin-bottom: 20px;
        }
         
        .user-info p {
            margin-bottom: 8px;
            color: #555;
        }
         
        .user-info span {
            font-weight: 500;
            color: #333;
        }
         
        .checkin-status {
            text-align: center;
            padding: 20px;
            border-radius: 8px;
            margin-bottom: 20px;
            font-weight: 500;
        }
         
        .checked-in {
            background: #e8f5e9;
            color: #2e7d32;
        }
         
        .not-checked-in {
            background: #fff3e0;
            color: #ef6c00;
        }
         
        .history {
            margin-top: 25px;
        }
         
        .history h3 {
            margin-bottom: 15px;
            color: #333;
            padding-bottom: 8px;
            border-bottom: 1px solid #eee;
        }
         
        .history-list {
            max-height: 200px;
            overflow-y: auto;
        }
         
        .history-item {
            padding: 12px 15px;
            background: #f9f9f9;
            border-radius: 8px;
            margin-bottom: 10px;
            display: flex;
            justify-content: space-between;
        }
         
        .history-date {
            color: #555;
        }
         
        .history-time {
            color: #888;
            font-size: 14px;
        }
         
        .alert {
            padding: 15px;
            border-radius: 8px;
            margin-bottom: 20px;
            font-size: 14px;
        }
         
        .alert-warning {
            background: #fff3e0;
            color: #ef6c00;
            border-left: 4px solid #ff9800;
        }
         
        .alert-info {
            background: #e3f2fd;
            color: #1565c0;
            border-left: 4px solid #2196f3;
        }
         
        .sms-config {
            background: #f9f9f9;
            padding: 15px;
            border-radius: 8px;
            margin-top: 20px;
            font-size: 14px;
        }
         
        .sms-config h4 {
            margin-bottom: 10px;
            color: #333;
        }
         
        .sms-config p {
            margin-bottom: 8px;
            color: #555;
        }
         
        [url=home.php?mod=space&uid=945662]@media[/url] (max-width: 600px) {
            .container {
                border-radius: 12px;
            }
             
            .header {
                padding: 20px 15px;
            }
             
            .form-container {
                padding: 20px 15px;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>活着么签到系统</h1>
        </div>
         
        <!-- 注册视图 -->
        <div id="register-view" class="view active">
            <div class="form-container">
                <h2>手机号注册</h2>
                <div class="alert alert-info">
                    请输入您的手机号进行注册,注册后需要设置紧急联系人才能开始签到
                </div>
                 
                <div class="form-group">
                    <label for="phone">手机号</label>
                    <input type="tel" id="phone" placeholder="请输入11位手机号" pattern="[0-9]{11}" required>
                </div>
                 
                <button id="register-btn" class="btn">注册</button>
            </div>
        </div>
         
        <!-- 紧急联系人视图 -->
        <div id="emergency-contact-view" class="view">
            <div class="form-container">
                <h2>设置紧急联系人</h2>
                <div class="alert alert-warning">
                    紧急联系人不能是自己,建议填写直系亲属信息
                </div>
                 
                <div class="form-group">
                    <label for="contact-name">联系人姓名</label>
                    <input type="text" id="contact-name" placeholder="请输入联系人姓名" required>
                </div>
                 
                <div class="form-group">
                    <label for="contact-phone">联系人手机号</label>
                    <input type="tel" id="contact-phone" placeholder="请输入11位手机号" pattern="[0-9]{11}" required>
                </div>
                 
                <div class="form-group">
                    <label for="relationship">与您的关系</label>
                    <input type="text" id="relationship" placeholder="例如:父亲、母亲、配偶等" required>
                </div>
                 
                <button id="set-contact-btn" class="btn">完成设置</button>
            </div>
        </div>
         
        <!-- 主视图 -->
        <div id="main-view" class="view">
            <div class="form-container">
                <h2>每日打卡</h2>
                 
                <div class="user-info">
                    <p>手机号: <span id="user-phone"></span></p>
                    <p>紧急联系人: <span id="emergency-contact"></span> (<span id="contact-relationship"></span>)</p>
                </div>
                 
                <div id="checkin-status" class="checkin-status not-checked-in">
                    今日尚未签到,请点击下方按钮签到
                </div>
                 
                <button id="checkin-btn" class="btn">今日签到</button>
                 
                <div class="history">
                    <h3>签到历史</h3>
                    <div id="history-list" class="history-list">
                        <!-- 签到历史将在这里显示 -->
                    </div>
                </div>
                 
                <div class="sms-config">
                    <h4>阿里云短信服务配置</h4>
                    <p>AccessKey ID: <span id="access-key-id">已配置</span></p>
                    <p>AccessKey Secret: <span id="access-key-secret">已配置</span></p>
                    <p>签名: <span id="sms-sign">已配置</span></p>
                    <p>模板代码: <span id="template-code">已配置</span></p>
                </div>
            </div>
        </div>
    </div>
 
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            // 初始化数据
            let userData = {
                phone: '',
                emergencyContact: {
                    name: '',
                    phone: '',
                    relationship: ''
                },
                checkInHistory: [],
                lastCheckInDate: null
            };
             
            // 从localStorage加载数据
            function loadData() {
                const savedData = localStorage.getItem('checkInData');
                if (savedData) {
                    userData = JSON.parse(savedData);
                    updateUI();
                }
            }
             
            // 保存数据到localStorage
            function saveData() {
                localStorage.setItem('checkInData', JSON.stringify(userData));
            }
             
            // 更新UI
            function updateUI() {
                if (userData.phone && !userData.emergencyContact.name) {
                    showView('emergency-contact-view');
                } else if (userData.phone && userData.emergencyContact.name) {
                    showView('main-view');
                    updateMainView();
                } else {
                    showView('register-view');
                }
            }
             
            // 显示指定视图
            function showView(viewId) {
                document.querySelectorAll('.view').forEach(view => {
                    view.classList.remove('active');
                });
                document.getElementById(viewId).classList.add('active');
            }
             
            // 更新主视图
            function updateMainView() {
                document.getElementById('user-phone').textContent = userData.phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
                document.getElementById('emergency-contact').textContent = userData.emergencyContact.name;
                document.getElementById('contact-relationship').textContent = userData.emergencyContact.relationship;
                 
                // 更新签到状态
                const today = new Date().toISOString().split('T')[0];
                const hasCheckedIn = userData.checkInHistory.some(record => record.date === today);
                 
                const checkinStatus = document.getElementById('checkin-status');
                const checkinBtn = document.getElementById('checkin-btn');
                 
                if (hasCheckedIn) {
                    checkinStatus.textContent = `您今天已于 ${userData.checkInHistory.find(r => r.date === today).time} 签到成功!`;
                    checkinStatus.className = 'checkin-status checked-in';
                    checkinBtn.textContent = '今日已签到';
                    checkinBtn.disabled = true;
                } else {
                    checkinStatus.textContent = '今日尚未签到,请点击下方按钮签到';
                    checkinStatus.className = 'checkin-status not-checked-in';
                    checkinBtn.textContent = '今日签到';
                    checkinBtn.disabled = false;
                }
                 
                // 更新签到历史
                const historyList = document.getElementById('history-list');
                historyList.innerHTML = '';
                 
                if (userData.checkInHistory.length === 0) {
                    historyList.innerHTML = '<div class="history-item">暂无签到记录</div>';
                } else {
                    // 按日期降序排列
                    const sortedHistory = [...userData.checkInHistory].sort((a, b) => new Date(b.date) - new Date(a.date));
                     
                    sortedHistory.forEach(record => {
                        const item = document.createElement('div');
                        item.className = 'history-item';
                        item.innerHTML = `
                            <div>
                                <div class="history-date">${record.date}</div>
                            </div>
                            <div class="history-time">${record.time}</div>
                        `;
                        historyList.appendChild(item);
                    });
                }
                 
                // 检查连续未签到天数
                checkConsecutiveMissedDays();
            }
             
            // 检查连续未签到天数
            function checkConsecutiveMissedDays() {
                if (!userData.lastCheckInDate) return;
                 
                const lastCheckIn = new Date(userData.lastCheckInDate);
                const today = new Date();
                today.setHours(0, 0, 0, 0);
                 
                const diffTime = Math.abs(today - lastCheckIn);
                const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
                 
                if (diffDays >= 3) {
                    // 模拟发送短信
                    sendSMSNotification(diffDays);
                }
            }
             
            // 模拟发送短信通知
            function sendSMSNotification(daysMissed) {
                // 在实际应用中,这里会调用阿里云短信API
                console.log(`正在发送短信通知紧急联系人 ${userData.emergencyContact.name} (${userData.emergencyContact.phone})`);
                console.log(`短信内容: 您的亲属 ${userData.phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')} 已连续 ${daysMissed} 天未签到,请及时联系确认安全。`);
                 
                alert(`模拟短信发送成功!\n\n已向紧急联系人 ${userData.emergencyContact.name} (${userData.emergencyContact.phone}) 发送通知:\n"您的亲属已连续 ${daysMissed} 天未签到,请及时联系确认安全。"`);
                 
                // 重置计数器(在实际应用中,可能需要更复杂的逻辑)
                userData.lastCheckInDate = new Date().toISOString().split('T')[0];
                saveData();
            }
             
            // 注册按钮点击事件
            document.getElementById('register-btn').addEventListener('click', function() {
                const phone = document.getElementById('phone').value;
                 
                if (!/^\d{11}$/.test(phone)) {
                    alert('请输入有效的11位手机号!');
                    return;
                }
                 
                userData.phone = phone;
                saveData();
                updateUI();
            });
             
            // 设置紧急联系人按钮点击事件
            document.getElementById('set-contact-btn').addEventListener('click', function() {
                const name = document.getElementById('contact-name').value;
                const phone = document.getElementById('contact-phone').value;
                const relationship = document.getElementById('relationship').value;
                 
                if (!name || !/^\d{11}$/.test(phone) || !relationship) {
                    alert('请填写完整的紧急联系人信息!');
                    return;
                }
                 
                if (phone === userData.phone) {
                    alert('紧急联系人不能是自己!');
                    return;
                }
                 
                userData.emergencyContact = {
                    name,
                    phone,
                    relationship
                };
                 
                saveData();
                updateUI();
            });
             
            // 签到按钮点击事件
            document.getElementById('checkin-btn').addEventListener('click', function() {
                const today = new Date().toISOString().split('T')[0];
                const now = new Date();
                const time = now.toTimeString().split(' ')[0].substring(0, 5);
                 
                // 检查今天是否已经签到
                const hasCheckedIn = userData.checkInHistory.some(record => record.date === today);
                if (hasCheckedIn) {
                    alert('您今天已经签到过了!');
                    return;
                }
                 
                // 添加签到记录
                userData.checkInHistory.push({
                    date: today,
                    time: time
                });
                 
                // 更新最后签到日期
                userData.lastCheckInDate = today;
                 
                saveData();
                updateUI();
                 
                alert('签到成功!');
            });
             
            // 初始化应用
            loadData();
             
            // 每天检查一次连续未签到情况(在实际应用中,这应该在后端完成)
            setInterval(checkConsecutiveMissedDays, 24 * 60 * 60 * 1000);
        });
    </script>
</body>
</html>

© 版权声明
THE END
喜欢就支持一下吧
点赞15赞赏 分享