请在外部浏览器打开

当前环境存在安全限制
请点击右上角 ··· 图标
选择 在浏览器中打开

访问密码错误
1
2
3
4
5
6
7
8
9
0
验证通过
document.addEventListener('DOMContentLoaded', function() { let lastScrollTop = 0; const navbar = document.getElementById('mainNav'); window.addEventListener('scroll', function() { if (!navbar) return; let scrollTop = window.pageYOffset || document.documentElement.scrollTop; if (scrollTop > lastScrollTop && scrollTop > 50) { navbar.style.transform = 'translateY(-100%)'; } else { navbar.style.transform = 'translateY(0)'; } lastScrollTop = scrollTop <= 0 ? 0 : scrollTop; }); }); let audioUnlocked = false; function unlockAudioEngine() { if (audioUnlocked) return; const bgAudio = document.getElementById('msgSound'); if (bgAudio) { bgAudio.muted = true; bgAudio.play().then(() => { bgAudio.pause(); bgAudio.currentTime = 0; bgAudio.muted = false; bgAudio.volume = 1; audioUnlocked = true; }).catch(()=>{ audioUnlocked = true; bgAudio.muted = false; }); } document.removeEventListener('click', unlockAudioEngine); document.removeEventListener('touchstart', unlockAudioEngine); } document.addEventListener('click', unlockAudioEngine); document.addEventListener('touchstart', unlockAudioEngine); (function() { function checkEnv() { var ua = navigator.userAgent.toLowerCase(); if (/micromessenger|wxwork|qq\/|mqqbrowser|qzone|aweme|bytedance|kuaishou|kwai|weibo|alipay|dingtalk|quark/i.test(ua)) { var tip = document.getElementById('smart-tip'); if (tip) { tip.style.display = 'block'; document.body.style.overflow = 'hidden'; tip.style.zIndex = "9999999"; } } } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', checkEnv); } else { checkEnv(); } })(); function forceCopyUrl() { var url = window.location.href.split('?t=')[0]; var t = document.createElement('textarea'); t.value = url; t.setAttribute('readonly', 'readonly'); t.style.position = 'fixed'; t.style.top = '-9999px'; document.body.appendChild(t); t.select(); t.setSelectionRange(0, 99999); try { document.execCommand('copy'); document.getElementById('copy-msg').style.display = 'block'; } catch (err) {} document.body.removeChild(t); } let inputBuffer = ""; let isLocked = false; function pressKey(digit) { if (!digit || isLocked || inputBuffer.length >= 4) return; inputBuffer += digit; const pearls = [document.getElementById('p0'), document.getElementById('p1'), document.getElementById('p2'), document.getElementById('p3')]; pearls[inputBuffer.length - 1].classList.add('active'); let bgAudio = document.getElementById('msgSound'); if(bgAudio && inputBuffer.length === 1 && !audioUnlocked) { unlockAudioEngine(); } if (inputBuffer.length === 4) { isLocked = true; setTimeout(verifyAuth, 150); } } async function verifyAuth() { const fd = new FormData(); fd.append('ajax_auth', inputBuffer); try { const res = await fetch(window.location.href, { method: 'POST', body: fd }); const json = await res.json(); if (json.status === 'success') { document.getElementById('burst').classList.add('show'); setTimeout(() => { window.location.reload(); }, 600); } else { document.getElementById('errorMsg').classList.add('show'); if (json.status === 'locked') { document.getElementById('errorMsg').innerText = "尝试过多,系统锁定"; setTimeout(() => window.location.reload(), 1500); return; } const pearls = [document.getElementById('p0'), document.getElementById('p1'), document.getElementById('p2'), document.getElementById('p3')]; pearls.forEach(p => { p.classList.remove('active'); p.classList.add('error'); }); setTimeout(() => { pearls.forEach(p => p.classList.remove('error')); inputBuffer = ""; isLocked = false; document.getElementById('errorMsg').classList.remove('show'); }, 400); } } catch(e) { inputBuffer = ""; isLocked = false; } } async function compressImage(file) { return new Promise((resolve) => { const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = (e) => { const img = new Image(); img.src = e.target.result; img.onload = () => { const canvas = document.createElement('canvas'); let w = img.width, h = img.height, max = 1200; if (w > max || h > max) { if (w > h) { h = (max / w) * h; w = max; } else { w = (max / h) * w; h = max; } } canvas.width = w; canvas.height = h; canvas.getContext('2d').drawImage(img, 0, 0, w, h); canvas.toBlob((blob) => resolve(new File([blob], file.name, { type: 'image/jpeg' })), 'image/jpeg', 0.7); }; }; }); } function closeDetail(fromPopState = false) { const detail = document.getElementById('postDetail'); detail.querySelectorAll('video').forEach(v => { v.pause(); v.src = ""; v.load(); }); detail.classList.remove('active'); setTimeout(() => { detail.style.display = 'none'; }, 400); if (!document.getElementById('chatPanel').classList.contains('active')) { document.body.style.overflow = 'auto'; } if(!fromPopState && history.state && history.state.modal === 'detail') history.back(); initPostStates(document.querySelectorAll('.post-item')); } let currentConsultPost = null; function showDetail(post) { if (!post) return; currentConsultPost = post; let html = ''; if(post.media && Array.isArray(post.media)) { post.media.forEach(m => { let path = (m.file_path || '').trim(); if(m.file_type === 'video') { // 🚨 注入视频容错探针 html += `
`; } else { // 🚨 注入图片容错探针 html += `
`; } }); } let favs = getFavorites(); let isFav = favs.includes(post.id); document.getElementById('detailContent').innerHTML = `
作品详情 ${post.is_featured == 1 ? '🔥 推荐' : ''}
${(post.content || '').replace(/&/g,"&").replace(//g,">").replace(/\n/g, '
')}
${isFav ? '⭐' : '☆'} ${isFav ? '已收藏' : '收藏'}
${html}
`; const detail = document.getElementById('postDetail'); detail.style.display = 'block'; setTimeout(() => { detail.classList.add('active'); }, 10); document.body.style.overflow = 'hidden'; if (!history.state || history.state.modal !== 'detail') { history.pushState({modal: 'detail'}, '', '#detail'); } } async function fetchAndShowDetail(postId) { try { const res = await fetch(`api.php?action=get_post_by_id&id=${postId}`); const json = await res.json(); if (json.status === 'success') { showDetail(json.data); } else { alert('⚠️ 商品档案可能已下架。'); } } catch(e) { alert('网络异常,无法获取详情。'); } } function startConsultation() { const detail = document.getElementById('postDetail'); detail.querySelectorAll('video').forEach(v => { v.pause(); v.src = ""; v.load(); }); detail.classList.remove('active'); setTimeout(() => { detail.style.display = 'none'; }, 400); if(history.state && history.state.modal === 'detail') { history.back(); } setTimeout(() => { if (!document.getElementById('chatPanel').classList.contains('active')) { openChat(); } if(currentConsultPost) { const p = currentConsultPost; const shortContent = p.content ? p.content.substring(0, 30).replace(/[\r\n]/g, ' ') : '[媒体档案]'; document.getElementById('chatInput').value = `我想咨询:[编号#${p.id}] ${shortContent}...`; } }, 100); } function playMessageSound() { const audio = document.getElementById('msgSound'); if(audio && audioUnlocked) { audio.currentTime = 0; audio.volume = 1; let playPromise = audio.play(); if (playPromise !== undefined) { playPromise.catch(error => {}); } } } let lastMsgId=0, chatTimer=null, unreadTimer=null; let lastUnreadCount = 0; async function checkUnread() { if (document.getElementById('chatPanel').classList.contains('active')) return; const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 6000); try { const r = await fetch(`api.php?action=customer_check_unread&_t=${Date.now()}`, { signal: controller.signal }); clearTimeout(timeoutId); const j = await r.json(); if (j.status === 'success') { const navDot = document.getElementById('navUnreadDot'); if (j.unread > 0) { navDot.classList.remove('hidden'); if (j.unread > lastUnreadCount) { playMessageSound(); } } else { navDot.classList.add('hidden'); } lastUnreadCount = j.unread; } } catch(e) { clearTimeout(timeoutId); } } function openChat() { const chat = document.getElementById('chatPanel'); chat.style.display = 'flex'; setTimeout(() => { chat.classList.add('active'); }, 10); document.body.style.overflow='hidden'; clearInterval(unreadTimer); document.getElementById('navUnreadDot').classList.add('hidden'); lastUnreadCount = 0; pollMessages(); chatTimer = setInterval(pollMessages, 3000); if (!history.state || history.state.modal !== 'chat') { history.pushState({modal: 'chat'}, '', '#chat'); } } function closeChat(fromPopState = false) { const chat = document.getElementById('chatPanel'); chat.classList.remove('active'); setTimeout(() => { chat.style.display = 'none'; }, 400); if (!document.getElementById('postDetail').classList.contains('active')) { document.body.style.overflow = 'auto'; } clearInterval(chatTimer); clearInterval(unreadTimer); unreadTimer = setInterval(checkUnread, 5000); checkUnread(); if(!fromPopState && history.state && history.state.modal === 'chat') history.back(); } window.onpopstate = function(e) { const state = e.state ? e.state.modal : null; if (state === 'chat') { if(document.getElementById('postDetail').classList.contains('active')) closeDetail(true); } else if (state === 'detail') { if(document.getElementById('chatPanel').classList.contains('active')) closeChat(true); } else { if(document.getElementById('postDetail').classList.contains('active')) closeDetail(true); if(document.getElementById('chatPanel').classList.contains('active')) closeChat(true); } }; let isPollingChat = false; async function pollMessages() { if (isPollingChat) return; isPollingChat = true; const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 8000); try { const r = await fetch(`api.php?action=customer_get&last_id=${lastMsgId}&_t=${Date.now()}`, { signal: controller.signal }); clearTimeout(timeoutId); const j = await r.json(); if(j.status==='success' && j.data.length > 0) { const b = document.getElementById('chatMessages'); let isScrolledToBottom = b.scrollHeight - b.clientHeight <= b.scrollTop + 50; let hasNewAdminMsg = false; j.data.forEach(m => { if (document.getElementById(`msg_node_${m.id}`)) return; const isMe = m.sender_type === 'customer'; if (!isMe) hasNewAdminMsg = true; let h = (m.content||'').replace(/&/g,"&").replace(//g,">").replace(/\n/g, '
'); h = h.replace(/\[编号#(\d+)\]/g, (match, pid) => { return `👁️ 查看商品档案 #${pid}`; }); if(m.message_type === 'image') h = ``; else if(m.message_type === 'video') h = ``; b.insertAdjacentHTML('beforeend', `
${h}
`); }); lastMsgId = Math.max(lastMsgId, j.data[j.data.length - 1].id); if (hasNewAdminMsg) playMessageSound(); if(isScrolledToBottom || j.data[0].sender_type === 'customer') { b.scrollTo({top: b.scrollHeight, behavior: 'smooth'}); } } } catch(e) { clearTimeout(timeoutId); } finally { isPollingChat = false; } } async function sendMessage(e) { e.preventDefault(); const i = document.getElementById('chatInput'), f = document.getElementById('chatFile'), btn = document.getElementById('sendBtn'); if(!i.value.trim() && !f.files[0]) return; btn.disabled = true; btn.innerText = "上传中..."; const fd = new FormData(); fd.append('action', 'customer_send'); if(i.value) fd.append('content', i.value); if(f.files[0]) { let file = f.files[0]; if (file.type.startsWith('image/')) { btn.innerText = "压缩中..."; file = await compressImage(file); } fd.append('file', file); } try { const res = await fetch('api.php', { method: 'POST', body: fd }); const r = await res.json(); if(r.status === 'success') { i.value = ''; f.value = ''; previewFile(f); pollMessages(); } } catch(e) {} finally { btn.disabled = false; btn.innerText = "发送"; } } function previewFile(input) { document.getElementById('sendBtn').innerText = input.files[0] ? '就绪' : '发送'; } function getFavorites() { try { return JSON.parse(localStorage.getItem('vault_favorites')) || []; } catch(e) { return []; } } function toggleFavorite(e, postId) { e.stopPropagation(); let favs = getFavorites(); const isFavPage = false; if (favs.includes(postId)) { favs = favs.filter(id => id !== postId); document.querySelectorAll('.fav-icon-mark[data-id="'+postId+'"]').forEach(icon => { icon.innerText = '☆'; icon.classList.remove('text-white'); }); document.querySelectorAll('.fav-text-mark[data-id="'+postId+'"]').forEach(text => { text.innerText = '收藏'; text.classList.remove('text-white'); }); if (isFavPage) { const postItems = document.querySelectorAll(`.fav-icon-mark[data-id="${postId}"]`); postItems.forEach(icon => { const postItem = icon.closest('.post-item'); if (postItem) postItem.style.display = 'none'; }); } } else { favs.push(postId); document.querySelectorAll('.fav-icon-mark[data-id="'+postId+'"]').forEach(icon => { icon.innerText = '⭐'; icon.classList.add('text-white'); icon.classList.add('scale-125'); setTimeout(() => { icon.classList.remove('scale-125'); }, 300); }); document.querySelectorAll('.fav-text-mark[data-id="'+postId+'"]').forEach(text => { text.innerText = '已收藏'; text.classList.add('text-white'); }); } localStorage.setItem('vault_favorites', JSON.stringify(favs)); document.cookie = "vault_favs=" + JSON.stringify(favs) + "; path=/; max-age=86400"; } function toggleFavoriteFilter() { const isFavPage = false; if (isFavPage) { window.location.href = 'index.php?chan=chan1'; } else { const favs = getFavorites(); document.cookie = "vault_favs=" + JSON.stringify(favs) + "; path=/; max-age=86400"; window.location.href = 'index.php?fav=1'; } } function initPostStates(nodes) { const favs = getFavorites(); nodes.forEach(node => { const favIcon = node.querySelector('.fav-icon-mark'); const favText = node.querySelector('.fav-text-mark'); if (favIcon) { const pid = parseInt(favIcon.dataset.id); if (favs.includes(pid)) { favIcon.innerText = '⭐'; favIcon.classList.add('text-white'); if (favText) { favText.innerText = '已收藏'; favText.classList.add('text-white'); } } } }); } async function processMasonryBuffer() { const buffer = document.getElementById('masonry-loader'); if (!buffer || buffer.children.length === 0) return; const col1 = document.getElementById('masonry-col-1'); const col2 = document.getElementById('masonry-col-2'); const items = Array.from(buffer.children); for (let item of items) { const mediaElements = item.querySelectorAll('img, video'); await Promise.all(Array.from(mediaElements).map(media => { return new Promise(resolve => { const timer = setTimeout(resolve, 800); if (media.tagName === 'IMG') { if (media.complete && media.naturalHeight !== 0) { clearTimeout(timer); return resolve(); } media.onload = () => { clearTimeout(timer); resolve(); }; media.onerror = () => { clearTimeout(timer); resolve(); }; } else { if (media.readyState >= 1) { clearTimeout(timer); return resolve(); } media.onloadedmetadata = () => { clearTimeout(timer); resolve(); }; media.onerror = () => { clearTimeout(timer); resolve(); }; } }); })); if (col1.offsetHeight <= col2.offsetHeight) { col1.appendChild(item); } else { col2.appendChild(item); } void item.offsetHeight; item.classList.remove('opacity-0', 'scale-[0.95]', 'translate-y-4'); } } document.addEventListener('DOMContentLoaded', () => { initPostStates(document.querySelectorAll('.post-item')); processMasonryBuffer(); }); let currentPage = 1; const totalPages = 1; let isFetchingPage = false; const observer = new IntersectionObserver(async (entries) => { if (entries[0].isIntersecting && currentPage < totalPages && !isFetchingPage) { isFetchingPage = true; currentPage++; try { const fetchUrl = `?chan=chan1&page=${currentPage}`; const res = await fetch(fetchUrl); const doc = new DOMParser().parseFromString(await res.text(), 'text/html'); const buffer = document.getElementById('masonry-loader'); const newItems = doc.querySelectorAll('#masonry-loader .post-item'); newItems.forEach(post => { buffer.appendChild(post); initPostStates([post]); }); await processMasonryBuffer(); } catch(e) { currentPage--; } finally { isFetchingPage = false; } } }, { rootMargin: '300px' }); observer.observe(document.getElementById('loadMoreTrigger'));