const SUPABASE_URL = 'https://chixssrphfgxvqqigkzo.supabase.co'; const SUPABASE_ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImNoaXhzc3JwaGZneHZxcWlna3pvIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzQ2OTE0OTEsImV4cCI6MjA5MDI2NzQ5MX0.Az_Ew2J2zdOMcSV0UNAjBS-LPqGpqhsaN4IyZ5R7iqU'; const sbClient = supabase.createClient(SUPABASE_URL, SUPABASE_ANON_KEY); const html5QrCode = new Html5Qrcode("reader"); const scannerOverlay = document.getElementById('scanner-overlay'); document.getElementById('startScanBtn').addEventListener('click', async () => { scannerOverlay.style.display = 'flex'; const config = { fps: 15, qrbox: { width: 320, height: 140 }, aspectRatio: 1.0 }; if (typeof Html5QrcodeSupportedFormats !== 'undefined') { config.formatsToSupport = [ Html5QrcodeSupportedFormats.CODE_128, Html5QrcodeSupportedFormats.CODE_39, Html5QrcodeSupportedFormats.CODE_93, Html5QrcodeSupportedFormats.EAN_13, Html5QrcodeSupportedFormats.EAN_8, Html5QrcodeSupportedFormats.UPC_A, Html5QrcodeSupportedFormats.UPC_E, Html5QrcodeSupportedFormats.ITF, Html5QrcodeSupportedFormats.CODABAR ]; } try { await html5QrCode.start( { facingMode: "environment" }, config, (decodedText) => { document.getElementById('searchTerm').value = decodedText; closeScanner(); handleSearch(); }, () => {} ); } catch (err) { alert("无法启动摄像头,请检查 HTTPS 权限或设备连接。"); scannerOverlay.style.display = 'none'; } }); async function closeScanner() { if (html5QrCode.isScanning) { await html5QrCode.stop(); } scannerOverlay.style.display = 'none'; } document.getElementById('stopScanBtn').addEventListener('click', closeScanner); async function handleSearch() { const term = document.getElementById('searchTerm').value.trim(); const start = document.getElementById('dateStart').value; const end = document.getElementById('dateEnd').value; const display = document.getElementById('resultsArea'); if (!term) { alert("请输入证书编号、持有人姓名或奖项名。"); return; } display.innerHTML = '
正在连接证书数据库并执行检索...
'; try { let query = sbClient.from('certificates').select('*'); query = query.or(`cert_number.ilike.%${term}%,holder_name.ilike.%${term}%,honor_title.ilike.%${term}%`); if (start) query = query.gte('issue_date', start); if (end) query = query.lte('issue_date', end); const { data, error } = await query.order('issue_date', { ascending: false }); if (error) throw error; const awardRecipientCounts = await loadAwardRecipientCounts(data); renderResults(data, awardRecipientCounts); } catch (err) { display.innerHTML = `
检索失败:${err.message}
`; } } async function loadAwardRecipientCounts(data) { const awardTitles = [...new Set((data || []).map(item => item.honor_title).filter(Boolean))]; if (awardTitles.length === 0) return {}; const countPairs = await Promise.all(awardTitles.map(async title => { const { count, error } = await sbClient .from('certificates') .select('id', { count: 'exact', head: true }) .eq('honor_title', title); if (error) throw error; return [title, count || 0]; })); return Object.fromEntries(countPairs); } function escapeHtml(value) { return String(value ?? '').replace(/[&<>"']/g, char => ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[char])); } function renderAwardStats(data, awardRecipientCounts) { const holderCounts = (data || []).reduce((counts, item) => { const holderName = item.holder_name || '未填写'; counts[holderName] = (counts[holderName] || 0) + 1; return counts; }, {}); const holderStats = Object.entries(holderCounts) .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0], 'zh-CN')); const maxHolderCount = Math.max(...holderStats.map(([, count]) => count), 1); const awardStats = [...new Set((data || []).map(item => item.honor_title).filter(Boolean))] .map(title => ({ title, count: awardRecipientCounts[title] || 0 })) .sort((a, b) => b.count - a.count || a.title.localeCompare(b.title, 'zh-CN')); const holderBars = holderStats.map(([name, count]) => `
${escapeHtml(name)}
${count} 项
`).join(''); const awardChips = awardStats.map(item => `
${escapeHtml(item.title)} ${item.count} 人获得
`).join(''); return `
查询结果 ${data.length}
涉及人员 ${holderStats.length}
奖项种类 ${awardStats.length}
个人奖项数量
${holderBars}
查询奖项获得人数
${awardChips || '
暂无奖项名称
'}
`; } function renderResults(data, awardRecipientCounts = {}) { const display = document.getElementById('resultsArea'); if (!data || data.length === 0) { display.innerHTML = '
未找到匹配的证书记录。
'; return; } let html = ` ${renderAwardStats(data, awardRecipientCounts)}
`; data.forEach(item => { html += ` `; }); html += '
证书编号 持有人 荣誉标题 颁发日期 操作
${escapeHtml(item.cert_number || '-')} ${escapeHtml(item.holder_name || '-')} ${escapeHtml(item.honor_title || '-')} ${escapeHtml(item.issue_date || '-')}
'; display.innerHTML = html; } function goToDetail(id) { window.location.href = `certificate.html?id=${id}`; } function initializeSearchTermFromUrl() { const params = new URLSearchParams(window.location.search); const presetTerm = params.get('searchTerm') || params.get('term') || params.get('keyword') || params.get('cert_number') || params.get('certNumber') || params.get('number') || params.get('awardName') || params.get('honor_title') || params.get('honorTitle') || params.get('award') || params.get('q') || ''; if (presetTerm) { document.getElementById('searchTerm').value = presetTerm; } } document.getElementById('searchBtn').addEventListener('click', handleSearch); document.getElementById('searchTerm').addEventListener('keypress', e => { if (e.key === 'Enter') handleSearch(); }); initializeSearchTermFromUrl();