3 changed files with 486 additions and 5 deletions
@ -0,0 +1,428 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html lang="zh-CN"> |
||||
|
<head> |
||||
|
<meta charset="UTF-8"> |
||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> |
||||
|
<title>二维码合集</title> |
||||
|
<style> |
||||
|
* { |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
|
||||
|
body { |
||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; |
||||
|
background-color: #f5f5f5; |
||||
|
color: #333; |
||||
|
-webkit-overflow-scrolling: touch; |
||||
|
overflow-x: hidden; |
||||
|
position: relative; |
||||
|
touch-action: manipulation; |
||||
|
} |
||||
|
|
||||
|
html, body { |
||||
|
height: 100%; |
||||
|
overflow: hidden; |
||||
|
overscroll-behavior: none; |
||||
|
} |
||||
|
|
||||
|
.container { |
||||
|
max-width: 480px; |
||||
|
margin: 0 auto; |
||||
|
background-color: white; |
||||
|
height: 100%; |
||||
|
overflow-y: auto; |
||||
|
-webkit-overflow-scrolling: touch; |
||||
|
position: relative; |
||||
|
padding: 20px; |
||||
|
} |
||||
|
|
||||
|
.header { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
padding: 16px; |
||||
|
background-color: #28a745; |
||||
|
color: white; |
||||
|
position: sticky; |
||||
|
top: 0; |
||||
|
z-index: 100; |
||||
|
margin: -20px -20px 20px; |
||||
|
} |
||||
|
|
||||
|
.header h1 { |
||||
|
font-size: 18px; |
||||
|
font-weight: 600; |
||||
|
} |
||||
|
|
||||
|
.header-actions { |
||||
|
display: flex; |
||||
|
gap: 12px; |
||||
|
} |
||||
|
|
||||
|
.more-btn { |
||||
|
background: none; |
||||
|
border: none; |
||||
|
color: white; |
||||
|
font-size: 18px; |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
|
||||
|
.filter-section { |
||||
|
margin-bottom: 20px; |
||||
|
} |
||||
|
|
||||
|
.filter-section h3 { |
||||
|
font-size: 16px; |
||||
|
color: #333; |
||||
|
margin-bottom: 10px; |
||||
|
} |
||||
|
|
||||
|
.filter-buttons { |
||||
|
display: flex; |
||||
|
flex-wrap: wrap; |
||||
|
gap: 8px; |
||||
|
} |
||||
|
|
||||
|
.filter-btn { |
||||
|
padding: 8px 12px; |
||||
|
border: 1px solid #ddd; |
||||
|
border-radius: 16px; |
||||
|
background-color: white; |
||||
|
color: #666; |
||||
|
font-size: 14px; |
||||
|
cursor: pointer; |
||||
|
transition: all 0.3s; |
||||
|
} |
||||
|
|
||||
|
.filter-btn.active { |
||||
|
background-color: #28a745; |
||||
|
color: white; |
||||
|
border-color: #28a745; |
||||
|
} |
||||
|
|
||||
|
.qr-section { |
||||
|
margin-bottom: 30px; |
||||
|
} |
||||
|
|
||||
|
.qr-section h3 { |
||||
|
font-size: 16px; |
||||
|
color: #333; |
||||
|
margin-bottom: 15px; |
||||
|
padding-bottom: 8px; |
||||
|
border-bottom: 1px solid #f0f0f0; |
||||
|
} |
||||
|
|
||||
|
.qr-grid { |
||||
|
display: grid; |
||||
|
grid-template-columns: repeat(2, 1fr); |
||||
|
gap: 15px; |
||||
|
} |
||||
|
|
||||
|
.qr-item { |
||||
|
background-color: #f8f9fa; |
||||
|
border-radius: 8px; |
||||
|
padding: 12px; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.qr-item img { |
||||
|
max-width: 100%; |
||||
|
max-height: 150px; |
||||
|
margin-bottom: 10px; |
||||
|
border-radius: 4px; |
||||
|
} |
||||
|
|
||||
|
.qr-info { |
||||
|
font-size: 12px; |
||||
|
color: #666; |
||||
|
} |
||||
|
|
||||
|
.qr-info p { |
||||
|
margin-bottom: 4px; |
||||
|
} |
||||
|
|
||||
|
.qr-info .name { |
||||
|
font-weight: 500; |
||||
|
color: #333; |
||||
|
} |
||||
|
|
||||
|
.empty-state { |
||||
|
text-align: center; |
||||
|
padding: 40px 20px; |
||||
|
color: #999; |
||||
|
} |
||||
|
|
||||
|
.empty-state img { |
||||
|
max-width: 100px; |
||||
|
margin-bottom: 15px; |
||||
|
opacity: 0.5; |
||||
|
} |
||||
|
|
||||
|
.action-buttons { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
gap: 15px; |
||||
|
margin-top: 30px; |
||||
|
} |
||||
|
|
||||
|
.btn { |
||||
|
padding: 15px; |
||||
|
border: none; |
||||
|
border-radius: 8px; |
||||
|
font-size: 16px; |
||||
|
font-weight: 500; |
||||
|
cursor: pointer; |
||||
|
text-align: center; |
||||
|
transition: background-color 0.3s; |
||||
|
} |
||||
|
|
||||
|
.btn-primary { |
||||
|
background-color: #28a745; |
||||
|
color: white; |
||||
|
} |
||||
|
|
||||
|
.btn-primary:hover { |
||||
|
background-color: #218838; |
||||
|
} |
||||
|
|
||||
|
.btn-secondary { |
||||
|
background-color: #6c757d; |
||||
|
color: white; |
||||
|
} |
||||
|
|
||||
|
.btn-secondary:hover { |
||||
|
background-color: #5a6268; |
||||
|
} |
||||
|
|
||||
|
.footer { |
||||
|
text-align: center; |
||||
|
margin-top: 40px; |
||||
|
padding: 20px 0; |
||||
|
font-size: 14px; |
||||
|
color: #999; |
||||
|
border-top: 1px solid #f0f0f0; |
||||
|
} |
||||
|
|
||||
|
@media (max-width: 480px) { |
||||
|
.container { |
||||
|
max-width: 100%; |
||||
|
padding: 15px; |
||||
|
} |
||||
|
|
||||
|
.header { |
||||
|
margin: -15px -15px 15px; |
||||
|
} |
||||
|
|
||||
|
.header h1 { |
||||
|
font-size: 16px; |
||||
|
} |
||||
|
|
||||
|
.qr-grid { |
||||
|
grid-template-columns: 1fr; |
||||
|
} |
||||
|
|
||||
|
.qr-item img { |
||||
|
max-height: 200px; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
|
</head> |
||||
|
<body> |
||||
|
<div class="container"> |
||||
|
<div class="header"> |
||||
|
<h1>二维码合集</h1> |
||||
|
<div class="header-actions"> |
||||
|
<button class="more-btn">•••</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="filter-section"> |
||||
|
<h3>筛选</h3> |
||||
|
<div class="filter-buttons"> |
||||
|
<button class="filter-btn active" data-filter="all">全部</button> |
||||
|
<button class="filter-btn" data-filter="me">我的二维码</button> |
||||
|
<button class="filter-btn" data-filter="others">他人二维码</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div id="qrCollection"> |
||||
|
<div class="empty-state"> |
||||
|
<img src="https://api.qrserver.com/v1/create-qr-code/?size=100x100&data=empty" alt="空状态"> |
||||
|
<p>暂无二维码</p> |
||||
|
<p style="font-size: 14px; margin-top: 5px;">请先生成邀请二维码</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="action-buttons"> |
||||
|
<button class="btn btn-primary" onclick="window.location.href='invite.html'">生成邀请二维码</button> |
||||
|
<button class="btn btn-secondary" onclick="window.location.href='certificate.html'">返回主页面</button> |
||||
|
</div> |
||||
|
|
||||
|
<div class="footer"> |
||||
|
技术支持:四川又鸟蛋贸易有限公司 |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<script> |
||||
|
// 加载用户信息 |
||||
|
function loadUserInfo() { |
||||
|
const userInfo = localStorage.getItem('userInfo'); |
||||
|
if (userInfo) { |
||||
|
try { |
||||
|
return JSON.parse(userInfo); |
||||
|
} catch (error) { |
||||
|
console.error('解析用户信息失败:', error); |
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
// 加载二维码合集 |
||||
|
async function loadQrCollection() { |
||||
|
const user = loadUserInfo(); |
||||
|
const qrCollectionElement = document.getElementById('qrCollection'); |
||||
|
|
||||
|
try { |
||||
|
// 从服务器获取二维码合集 |
||||
|
const response = await fetch('/getQrCollection'); |
||||
|
const data = await response.json(); |
||||
|
|
||||
|
if (data.success && data.qrCodes && data.qrCodes.length > 0) { |
||||
|
// 渲染二维码合集 |
||||
|
renderQrCollection(data.qrCodes, user); |
||||
|
} else { |
||||
|
// 显示空状态 |
||||
|
qrCollectionElement.innerHTML = ` |
||||
|
<div class="empty-state"> |
||||
|
<img src="https://api.qrserver.com/v1/create-qr-code/?size=100x100&data=empty" alt="空状态"> |
||||
|
<p>暂无二维码</p> |
||||
|
<p style="font-size: 14px; margin-top: 5px;">请先生成邀请二维码</p> |
||||
|
</div> |
||||
|
`; |
||||
|
} |
||||
|
} catch (error) { |
||||
|
console.error('获取二维码合集失败:', error); |
||||
|
qrCollectionElement.innerHTML = ` |
||||
|
<div class="empty-state"> |
||||
|
<img src="https://api.qrserver.com/v1/create-qr-code/?size=100x100&data=error" alt="错误状态"> |
||||
|
<p>加载失败</p> |
||||
|
<p style="font-size: 14px; margin-top: 5px;">请稍后重试</p> |
||||
|
</div> |
||||
|
`; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 渲染二维码合集 |
||||
|
function renderQrCollection(qrCodes, currentUser) { |
||||
|
const qrCollectionElement = document.getElementById('qrCollection'); |
||||
|
|
||||
|
// 按邀请者分组 |
||||
|
const groupedQrCodes = {}; |
||||
|
qrCodes.forEach(qrCode => { |
||||
|
const inviterName = qrCode.inviter || '未知邀请者'; |
||||
|
if (!groupedQrCodes[inviterName]) { |
||||
|
groupedQrCodes[inviterName] = []; |
||||
|
} |
||||
|
groupedQrCodes[inviterName].push(qrCode); |
||||
|
}); |
||||
|
|
||||
|
// 生成HTML |
||||
|
let html = ''; |
||||
|
Object.keys(groupedQrCodes).forEach(inviterName => { |
||||
|
const inviterQrCodes = groupedQrCodes[inviterName]; |
||||
|
|
||||
|
html += ` |
||||
|
<div class="qr-section"> |
||||
|
<h3>${inviterName}</h3> |
||||
|
<div class="qr-grid"> |
||||
|
`; |
||||
|
|
||||
|
inviterQrCodes.forEach(qrCode => { |
||||
|
// 生成二维码 |
||||
|
const qrCodeUrl = `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(qrCode.url)}`; |
||||
|
|
||||
|
html += ` |
||||
|
<div class="qr-item"> |
||||
|
<img src="${qrCodeUrl}" alt="邀请二维码"> |
||||
|
<div class="qr-info"> |
||||
|
<p class="name">${qrCode.inviter || '未知'}</p> |
||||
|
<p>${qrCode.inviterProjectName || '无职位'}</p> |
||||
|
<p>${qrCode.createdAt || ''}</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
`; |
||||
|
}); |
||||
|
|
||||
|
html += ` |
||||
|
</div> |
||||
|
</div> |
||||
|
`; |
||||
|
}); |
||||
|
|
||||
|
qrCollectionElement.innerHTML = html; |
||||
|
} |
||||
|
|
||||
|
// 筛选二维码 |
||||
|
function filterQrCodes(filter) { |
||||
|
const user = loadUserInfo(); |
||||
|
const qrCollectionElement = document.getElementById('qrCollection'); |
||||
|
|
||||
|
// 更新筛选按钮状态 |
||||
|
document.querySelectorAll('.filter-btn').forEach(btn => { |
||||
|
btn.classList.remove('active'); |
||||
|
if (btn.dataset.filter === filter) { |
||||
|
btn.classList.add('active'); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
// 重新加载并筛选二维码 |
||||
|
fetch('/getQrCollection') |
||||
|
.then(response => response.json()) |
||||
|
.then(data => { |
||||
|
if (data.success && data.qrCodes && data.qrCodes.length > 0) { |
||||
|
let filteredQrCodes = data.qrCodes; |
||||
|
|
||||
|
if (filter === 'me' && user) { |
||||
|
filteredQrCodes = data.qrCodes.filter(qrCode => |
||||
|
qrCode.inviter === (user.name || user.userName) |
||||
|
); |
||||
|
} else if (filter === 'others' && user) { |
||||
|
filteredQrCodes = data.qrCodes.filter(qrCode => |
||||
|
qrCode.inviter !== (user.name || user.userName) |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
if (filteredQrCodes.length > 0) { |
||||
|
renderQrCollection(filteredQrCodes, user); |
||||
|
} else { |
||||
|
qrCollectionElement.innerHTML = ` |
||||
|
<div class="empty-state"> |
||||
|
<img src="https://api.qrserver.com/v1/create-qr-code/?size=100x100&data=empty" alt="空状态"> |
||||
|
<p>暂无二维码</p> |
||||
|
</div> |
||||
|
`; |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
.catch(error => { |
||||
|
console.error('筛选二维码失败:', error); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
// 页面加载时加载二维码合集 |
||||
|
window.onload = function() { |
||||
|
loadQrCollection(); |
||||
|
|
||||
|
// 绑定筛选按钮事件 |
||||
|
document.querySelectorAll('.filter-btn').forEach(btn => { |
||||
|
btn.addEventListener('click', function() { |
||||
|
filterQrCodes(this.dataset.filter); |
||||
|
}); |
||||
|
}); |
||||
|
}; |
||||
|
</script> |
||||
|
</body> |
||||
|
</html> |
||||
Loading…
Reference in new issue