diff --git a/certs/certificate.html b/certs/certificate.html index 29c1da7..8109fd9 100644 --- a/certs/certificate.html +++ b/certs/certificate.html @@ -9,7 +9,7 @@ - +
@@ -84,8 +84,8 @@

© 2026 BI Intelligent Query Interface

- - - + + + diff --git a/certs/index.html b/certs/index.html index df10193..c367747 100644 --- a/certs/index.html +++ b/certs/index.html @@ -9,8 +9,8 @@ - - + +
@@ -89,8 +89,8 @@

© 2026 BI Intelligent Query Interface

- - - + + + diff --git a/js/certs-index.js b/js/certs-index.js index ce51650..fbb167b 100644 --- a/js/certs-index.js +++ b/js/certs-index.js @@ -2,11 +2,17 @@ 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"); + let html5QrCode = null; const scannerOverlay = document.getElementById('scanner-overlay'); document.getElementById('startScanBtn').addEventListener('click', async () => { + if (typeof Html5Qrcode === 'undefined') { + alert("扫码组件加载失败,请刷新页面后重试。"); + return; + } + scannerOverlay.style.display = 'flex'; + html5QrCode = html5QrCode || new Html5Qrcode("reader"); const config = { fps: 15, @@ -46,7 +52,7 @@ const SUPABASE_URL = 'https://chixssrphfgxvqqigkzo.supabase.co'; }); async function closeScanner() { - if (html5QrCode.isScanning) { + if (html5QrCode && html5QrCode.isScanning) { await html5QrCode.stop(); } scannerOverlay.style.display = 'none'; @@ -111,6 +117,10 @@ const SUPABASE_URL = 'https://chixssrphfgxvqqigkzo.supabase.co'; }[char])); } + function encodeUrlParam(value) { + return encodeURIComponent(String(value ?? '')); + } + function renderAwardStats(data, awardRecipientCounts) { const holderCounts = (data || []).reduce((counts, item) => { const holderName = item.holder_name || '未填写'; @@ -205,7 +215,7 @@ const SUPABASE_URL = 'https://chixssrphfgxvqqigkzo.supabase.co'; ${escapeHtml(item.holder_name || '-')} ${escapeHtml(item.honor_title || '-')} ${escapeHtml(item.issue_date || '-')} - + 查看详情 `; }); diff --git a/js/ticket-detail.js b/js/ticket-detail.js index 8ca1f79..76d9a85 100644 --- a/js/ticket-detail.js +++ b/js/ticket-detail.js @@ -48,7 +48,7 @@ const SUPABASE_URL = 'https://chixssrphfgxvqqigkzo.supabase.co';
Ticket Detail
-

${ticket.ticket_number || '-'} / ${ticket.customer_name || '-'}

+

${escapeHtml(ticket.ticket_number || '-')} / ${escapeHtml(ticket.customer_name || '-')}

单据全量信息、处理状态与打印操作在此统一展示。

@@ -76,8 +76,8 @@ const SUPABASE_URL = 'https://chixssrphfgxvqqigkzo.supabase.co'; function item(label, value, extraClass = '', isHTML = false, isWide = false) { return `
- ${label} -
${isHTML ? value : (value || '无')}
+ ${escapeHtml(label)} +
${isHTML ? value : escapeHtml(value || '无')}
`; } @@ -94,7 +94,17 @@ const SUPABASE_URL = 'https://chixssrphfgxvqqigkzo.supabase.co'; function showError(msg) { const el = document.getElementById('detailContent'); el.classList.add('feedback-card'); - el.innerHTML = `
${msg}
`; + el.innerHTML = `
${escapeHtml(msg)}
`; + } + + function escapeHtml(value) { + return String(value ?? '').replace(/[&<>"']/g, char => ({ + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }[char])); } document.addEventListener('DOMContentLoaded', loadTicketDetail); diff --git a/js/ticket-index.js b/js/ticket-index.js index 8488d38..4a9f6a3 100644 --- a/js/ticket-index.js +++ b/js/ticket-index.js @@ -5,6 +5,11 @@ const SUPABASE_URL = 'https://chixssrphfgxvqqigkzo.supabase.co'; let html5QrCode = null; document.getElementById('startScanBtn').addEventListener('click', async () => { + if (typeof Html5Qrcode === 'undefined') { + alert("扫码组件加载失败,请刷新页面后重试。"); + return; + } + document.getElementById('scanner-overlay').style.display = 'flex'; if (html5QrCode) { try { @@ -34,6 +39,20 @@ const SUPABASE_URL = 'https://chixssrphfgxvqqigkzo.supabase.co'; document.getElementById('stopScanBtn').addEventListener('click', closeScanner); + function escapeHtml(value) { + return String(value ?? '').replace(/[&<>"']/g, char => ({ + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }[char])); + } + + function encodeUrlParam(value) { + return encodeURIComponent(String(value ?? '')); + } + async function handleSearch() { const searchTerm = document.getElementById('searchTerm').value.trim(); const dateFrom = document.getElementById('dateFrom').value; @@ -55,7 +74,7 @@ const SUPABASE_URL = 'https://chixssrphfgxvqqigkzo.supabase.co'; displayResults(data); } catch (error) { - resultsDiv.innerHTML = `
查询失败:${error.message}
`; + resultsDiv.innerHTML = `
查询失败:${escapeHtml(error.message)}
`; } } @@ -87,22 +106,22 @@ const SUPABASE_URL = 'https://chixssrphfgxvqqigkzo.supabase.co'; const amount = (ticket.amount || 0).toLocaleString('zh-CN', { style: 'currency', currency: 'CNY' }); const reason = ticket.reason || ''; const displayReason = reason.length > 18 - ? `${reason}` - : reason; + ? `${escapeHtml(reason)}` + : escapeHtml(reason); html += ` - ${ticket.ticket_number || ''} - ${ticket.customer_name || ''} + ${escapeHtml(ticket.ticket_number || '')} + ${escapeHtml(ticket.customer_name || '')} ${displayReason} ${amount} - ${ticket.created_at ? new Date(ticket.created_at).toLocaleDateString('zh-CN') : '-'} + ${escapeHtml(ticket.created_at ? new Date(ticket.created_at).toLocaleDateString('zh-CN') : '-')} ${ticket.processed ? '已处理' : '未处理'} - + 查看详情 `; }); diff --git a/js/xinhan-index.js b/js/xinhan-index.js index a929d39..3440e5f 100644 --- a/js/xinhan-index.js +++ b/js/xinhan-index.js @@ -2,6 +2,16 @@ const SUPABASE_URL = 'https://chixssrphfgxvqqigkzo.supabase.co'; const SUPABASE_ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImNoaXhzc3JwaGZneHZxcWlna3pvIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzQ2OTE0OTEsImV4cCI6MjA5MDI2NzQ5MX0.Az_Ew2J2zdOMcSV0UNAjBS-LPqGpqhsaN4IyZ5R7iqU'; const sb = supabase.createClient(SUPABASE_URL, SUPABASE_ANON_KEY); + function escapeHtml(value) { + return String(value ?? '').replace(/[&<>"']/g, char => ({ + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }[char])); + } + async function handleSearch() { const recipientTerm = document.getElementById('recipientTerm').value.trim(); const contentTerm = document.getElementById('searchTerm').value.trim(); @@ -19,7 +29,7 @@ const SUPABASE_URL = 'https://chixssrphfgxvqqigkzo.supabase.co'; const { data, error } = await q.order('sent_date', { ascending: false }); if (error) { - out.innerHTML = `
查询失败:${error.message}
`; + out.innerHTML = `
查询失败:${escapeHtml(error.message)}
`; return; } renderResults(data || []); @@ -51,16 +61,16 @@ const SUPABASE_URL = 'https://chixssrphfgxvqqigkzo.supabase.co'; rows.forEach(row => { const content = row.content || ''; const summary = content.length > 60 - ? `${content}` - : content; + ? `${escapeHtml(content)}` + : escapeHtml(content); html += ` - ${row.id} - ${row.recipient || ''} - ${row.destination || ''} - ${row.sent_date || ''} - ${row.arrival_date || ''} + ${escapeHtml(row.id)} + ${escapeHtml(row.recipient || '')} + ${escapeHtml(row.destination || '')} + ${escapeHtml(row.sent_date || '')} + ${escapeHtml(row.arrival_date || '')} ${summary} `; diff --git a/notice/index.html b/notice/index.html index 25c5ad8..5ba9561 100644 --- a/notice/index.html +++ b/notice/index.html @@ -65,6 +65,6 @@
- + diff --git a/pages/fmx.html b/pages/fmx.html index 488a676..4723e77 100644 --- a/pages/fmx.html +++ b/pages/fmx.html @@ -32,6 +32,6 @@ - + diff --git a/pages/ljq.html b/pages/ljq.html index 35597e6..c0f8ac6 100644 --- a/pages/ljq.html +++ b/pages/ljq.html @@ -32,6 +32,6 @@ - + diff --git a/pages/wyj.html b/pages/wyj.html index fbd8e66..97797d1 100644 --- a/pages/wyj.html +++ b/pages/wyj.html @@ -32,6 +32,6 @@ - + diff --git a/pages/wzy.html b/pages/wzy.html index 476fb38..eee0bdd 100644 --- a/pages/wzy.html +++ b/pages/wzy.html @@ -32,6 +32,6 @@ - + diff --git a/pages/zjq.html b/pages/zjq.html index 9becc2c..0b27659 100644 --- a/pages/zjq.html +++ b/pages/zjq.html @@ -32,6 +32,6 @@ - + diff --git a/ticket/detail.html b/ticket/detail.html index ea0cf28..43e6618 100644 --- a/ticket/detail.html +++ b/ticket/detail.html @@ -9,7 +9,7 @@ - +
@@ -30,8 +30,8 @@

© 2026 BI Intelligent Query Interface

- - - + + + diff --git a/ticket/index.html b/ticket/index.html index b3e7542..6c09240 100644 --- a/ticket/index.html +++ b/ticket/index.html @@ -9,9 +9,9 @@ - - - + + +
@@ -90,7 +90,7 @@

© 2026 BI Intelligent Query Interface

- - + + diff --git a/ticket/print.html b/ticket/print.html index b30b043..295987a 100644 --- a/ticket/print.html +++ b/ticket/print.html @@ -37,10 +37,10 @@ - + - - - + + + diff --git a/xinhan/index.html b/xinhan/index.html index b4857e0..6dcdcbb 100644 --- a/xinhan/index.html +++ b/xinhan/index.html @@ -9,7 +9,7 @@ - +
@@ -78,7 +78,7 @@

© 2026 BI Intelligent Query Interface

- - + +