// 获取DOM元素
|
const phoneInput = document.getElementById('phone');
|
const getCodeBtn = document.getElementById('getCodeBtn');
|
const codeCountSpan = document.getElementById('code-count');
|
const historyBody = document.getElementById('historyBody');
|
|
// 页面初始化
|
document.addEventListener('DOMContentLoaded', function() {
|
loadHistory();
|
setupEventListeners();
|
});
|
|
// 事件监听器
|
function setupEventListeners() {
|
getCodeBtn.addEventListener('click', handleGetCode);
|
phoneInput.addEventListener('input', function(e) {
|
// 只允许输入数字
|
this.value = this.value.replace(/[^\d]/g, '');
|
});
|
}
|
|
// 获取验证码处理
|
function handleGetCode() {
|
const phone = phoneInput.value.trim();
|
|
// 验证手机号
|
if (!phone) {
|
showMessage('请输入手机号');
|
return;
|
}
|
|
if (!/^1[3-9]\d{9}$/.test(phone)) {
|
showMessage('请输入有效的手机号');
|
return;
|
}
|
|
// 检查申请次数
|
const history = getHistoryFromStorage();
|
const phoneRecords = history.filter(record => record.phone === phone && isValid(record.expiryTime));
|
|
if (phoneRecords.length >= 5) {
|
showMessage('该手机号本周期已达到申请次数限制(5次)');
|
return;
|
}
|
|
// 生成验证码和密码
|
const code = generateCode();
|
const password = generatePassword();
|
const currentTime = new Date();
|
const expiryTime = new Date(currentTime.getTime() + 72 * 60 * 60 * 1000);
|
|
// 创建新记录
|
const newRecord = {
|
phone: phone,
|
password: password,
|
requestTime: formatDateTime(currentTime),
|
expiryTime: expiryTime.toISOString(),
|
id: Date.now()
|
};
|
|
// 保存到历史记录
|
history.push(newRecord);
|
localStorage.setItem('loginHistory', JSON.stringify(history));
|
|
// 更新UI
|
updateCodeCount();
|
loadHistory();
|
phoneInput.value = '';
|
|
// 显示成功提示
|
showMessage(`密码已生成:${password}`, 'success');
|
}
|
|
// 生成验证码
|
function generateCode() {
|
return Math.floor(Math.random() * 1000000).toString().padStart(6, '0');
|
}
|
|
// 生成密码(6位数字)
|
function generatePassword() {
|
return Math.floor(Math.random() * 1000000).toString().padStart(6, '0');
|
}
|
|
// 格式化日期时间
|
function formatDateTime(date) {
|
const year = date.getFullYear();
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
const day = String(date.getDate()).padStart(2, '0');
|
const hours = String(date.getHours()).padStart(2, '0');
|
const minutes = String(date.getMinutes()).padStart(2, '0');
|
return `${year}-${month}-${day} ${hours}:${minutes}`;
|
}
|
|
// 检查密码是否有效
|
function isValid(expiryTime) {
|
return new Date(expiryTime) > new Date();
|
}
|
|
// 计算剩余时间
|
function getRemainingTime(expiryTime) {
|
const now = new Date();
|
const expiry = new Date(expiryTime);
|
const diff = expiry - now;
|
|
if (diff <= 0) {
|
return '已过期';
|
}
|
|
const hours = Math.floor(diff / (1000 * 60 * 60));
|
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
|
|
if (hours > 0) {
|
return `${hours}小时${minutes}分钟`;
|
} else {
|
return `${minutes}分钟`;
|
}
|
}
|
|
// 更新申请次数
|
function updateCodeCount() {
|
const phone = phoneInput.value.trim();
|
if (!phone) {
|
codeCountSpan.textContent = '0';
|
return;
|
}
|
|
const history = getHistoryFromStorage();
|
const validRecords = history.filter(record =>
|
record.phone === phone && isValid(record.expiryTime)
|
);
|
codeCountSpan.textContent = validRecords.length;
|
}
|
|
// 从本地存储获取历史记录
|
function getHistoryFromStorage() {
|
const data = localStorage.getItem('loginHistory');
|
return data ? JSON.parse(data) : [];
|
}
|
|
// 加载历史记录到表格
|
function loadHistory() {
|
const history = getHistoryFromStorage();
|
|
// 过滤72小时内的记录
|
const recentHistory = history.filter(record => isValid(record.expiryTime));
|
|
if (recentHistory.length === 0) {
|
historyBody.innerHTML = '<tr class="empty-row"><td colspan="5">暂无记录</td></tr>';
|
return;
|
}
|
|
// 按时间倒序排列
|
recentHistory.sort((a, b) => new Date(b.expiryTime) - new Date(a.expiryTime));
|
|
historyBody.innerHTML = recentHistory.map(record => `
|
<tr>
|
<td><strong>${record.password}</strong></td>
|
<td>${record.requestTime}</td>
|
<td>${formatDateTime(new Date(record.expiryTime))}</td>
|
<td>${getRemainingTime(record.expiryTime)}</td>
|
<td>
|
<button class="btn-action" onclick="copyPassword('${record.password}')">复制</button>
|
</td>
|
</tr>
|
`).join('');
|
|
// 定期更新剩余时间
|
setInterval(() => {
|
const cells = document.querySelectorAll('.history-table tbody tr td:nth-child(4)');
|
let index = 0;
|
recentHistory.forEach(record => {
|
if (cells[index]) {
|
cells[index].textContent = getRemainingTime(record.expiryTime);
|
}
|
index += 5;
|
});
|
}, 60000); // 每分钟更新一次
|
}
|
|
// 复制密码
|
function copyPassword(password) {
|
navigator.clipboard.writeText(password).then(() => {
|
showMessage('密码已复制到剪贴板', 'success');
|
}).catch(() => {
|
// 备用方案
|
const textarea = document.createElement('textarea');
|
textarea.value = password;
|
document.body.appendChild(textarea);
|
textarea.select();
|
document.execCommand('copy');
|
document.body.removeChild(textarea);
|
showMessage('密码已复制到剪贴板', 'success');
|
});
|
}
|
|
// 显示消息提示
|
function showMessage(message, type = 'error') {
|
// 创建消息容器
|
const messageDiv = document.createElement('div');
|
messageDiv.className = 'message-toast';
|
messageDiv.textContent = message;
|
messageDiv.style.cssText = `
|
position: fixed;
|
top: 50%;
|
left: 50%;
|
transform: translate(-50%, -50%);
|
background: ${type === 'success' ? '#4CAF50' : '#f44336'};
|
color: white;
|
padding: 16px 24px;
|
border-radius: 8px;
|
font-size: 14px;
|
z-index: 9999;
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
animation: slideDown 0.3s ease-out;
|
`;
|
|
// 添加样式
|
if (!document.getElementById('toast-styles')) {
|
const style = document.createElement('style');
|
style.id = 'toast-styles';
|
style.textContent = `
|
@keyframes slideDown {
|
from {
|
opacity: 0;
|
transform: translate(-50%, -60%);
|
}
|
to {
|
opacity: 1;
|
transform: translate(-50%, -50%);
|
}
|
}
|
`;
|
document.head.appendChild(style);
|
}
|
|
document.body.appendChild(messageDiv);
|
|
// 2秒后移除
|
setTimeout(() => {
|
messageDiv.style.animation = 'slideDown 0.3s ease-out reverse';
|
setTimeout(() => {
|
document.body.removeChild(messageDiv);
|
}, 300);
|
}, 2000);
|
}
|
|
// 手机号变化时更新申请次数
|
phoneInput.addEventListener('change', updateCodeCount);
|
phoneInput.addEventListener('blur', updateCodeCount);
|
|
// 页面加载时定期更新剩余时间
|
setInterval(() => {
|
const cells = document.querySelectorAll('.history-table tbody tr td:nth-child(4)');
|
cells.forEach(cell => {
|
const row = cell.closest('tr');
|
if (row && row.querySelector('td:nth-child(2)')) {
|
const expiryText = row.querySelector('td:nth-child(3)').textContent;
|
if (expiryText) {
|
cell.textContent = getRemainingTime(expiryText);
|
}
|
}
|
});
|
}, 60000); // 每分钟更新一次
|