Files
Letters/ticket/index.html
T
biss 87f1ed2dee
Vercel Deploy / deploy (push) Successful in 58s
更新
2026-03-28 20:53:41 +08:00

289 lines
7.9 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>单据查询</title>
<script src="https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2"></script>
<style>
body {
background: #f0f2f5;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto;
}
.ticket-container {
max-width: 900px;
margin: 60px auto;
padding: 32px;
background: #fff;
border-radius: 12px;
box-shadow: 0 8px 24px rgba(0,0,0,0.08);
}
h1 {
text-align: center;
font-size: 24px;
font-weight: 600;
margin-bottom: 20px;
}
.search-form {
margin-bottom: 24px;
padding: 20px;
background: #fafafa;
border-radius: 10px;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 16px;
align-items: end;
}
.form-group {
display: flex;
flex-direction: column;
}
.form-group label {
font-size: 13px;
color: #666;
margin-bottom: 6px;
}
.form-control {
padding: 10px 12px;
border: 1px solid #ddd;
border-radius: 6px;
}
.form-control:focus {
border-color: #4CAF50;
outline: none;
box-shadow: 0 0 0 2px rgba(76,175,80,0.15);
}
.btn {
height: 40px;
background: linear-gradient(135deg, #4CAF50, #43a047);
border-radius: 6px;
color: #fff;
font-weight: 500;
cursor: pointer;
border: none;
}
.btn:hover {
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(76,175,80,0.3);
}
.result-table {
width: 100%;
border-collapse: collapse;
margin-top: 16px;
font-size: 14px;
}
.result-table th {
background: #fafafa;
text-align: left;
padding: 12px;
font-weight: 600;
border-bottom: 1px solid #eee;
}
.result-table td {
padding: 12px;
border-bottom: 1px solid #f0f0f0;
}
.result-table tr:hover {
background: #fafafa;
}
.status {
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
}
.status.done {
background: #e8f5e9;
color: #2e7d32;
}
.status.pending {
background: #fff3e0;
color: #ef6c00;
}
.no-result {
text-align: center;
padding: 60px;
color: #999;
}
.loading {
text-align: center;
padding: 30px;
color: #666;
}
.error-message {
background-color: #fee;
color: #c33;
padding: 10px;
border-radius: 6px;
}
.back-link {
font-size: 14px;
color: #4CAF50;
text-decoration: none;
display: inline-block;
margin-bottom: 20px;
}
.back-link:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div class="ticket-container">
<a href="../index.html" class="back-link">← 返回首页</a>
<h1>单据查询</h1>
<div class="search-form">
<div class="form-group">
<label>编号 / 姓名</label>
<input type="text" id="searchTerm" class="form-control">
</div>
<div class="form-group">
<label>开始日期</label>
<input type="date" id="dateFrom" class="form-control">
</div>
<div class="form-group">
<label>结束日期</label>
<input type="date" id="dateTo" class="form-control">
</div>
<button id="searchBtn" class="btn">查询</button>
</div>
<div id="searchResults"></div>
</div>
<script>
const SUPABASE_URL = 'https://chixssrphfgxvqqigkzo.supabase.co';
const SUPABASE_ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImNoaXhzc3JwaGZneHZxcWlna3pvIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzQ2OTE0OTEsImV4cCI6MjA5MDI2NzQ5MX0.Az_Ew2J2zdOMcSV0UNAjBS-LPqGpqhsaN4IyZ5R7iqU';
// 防止重复初始化
if (!window._sbClient) {
window._sbClient = window.supabase.createClient(
SUPABASE_URL,
SUPABASE_ANON_KEY
);
}
const sbClient = window._sbClient;
async function searchTickets() {
const searchTerm = document.getElementById('searchTerm').value.trim();
const dateFrom = document.getElementById('dateFrom').value;
const dateTo = document.getElementById('dateTo').value;
const resultsDiv = document.getElementById('searchResults');
resultsDiv.innerHTML = '<div class="loading">正在查询...</div>';
try {
let query = sbClient.from('tickets').select('*');
if (searchTerm) {
const escapedTerm = searchTerm
.replace(/%/g, '\\%')
.replace(/_/g, '\\_');
query = query.or(
`ticket_number.ilike.%${escapedTerm}%,customer_name.ilike.%${escapedTerm}%`
);
}
if (dateFrom) query = query.gte('created_at', dateFrom);
if (dateTo) query = query.lte('created_at', dateTo);
const { data, error } = await query;
if (error) throw error;
displayResults(data);
} catch (error) {
resultsDiv.innerHTML = `<div class="error-message">查询失败:${error.message}</div>`;
}
}
function displayResults(tickets) {
const resultsDiv = document.getElementById('searchResults');
if (!tickets || tickets.length === 0) {
resultsDiv.innerHTML = '<div class="no-result">未找到符合条件的单据</div>';
return;
}
let html = `
<table class="result-table">
<thead>
<tr>
<th>编号</th><th>姓名</th><th>事由</th><th>金额</th><th>日期</th><th>状态</th><th>操作</th>
</tr>
</thead>
<tbody>
`;
tickets.forEach(ticket => {
html += `
<tr>
<td>${ticket.ticket_number || ''}</td>
<td>${ticket.customer_name || ''}</td>
<td>${ticket.reason || ''}</td>
<td>¥${Number(ticket.amount || 0).toFixed(2)}</td>
<td>${formatDate(ticket.created_at)}</td>
<td>
<span class="status ${ticket.processed ? 'done' : 'pending'}">
${ticket.processed ? '已处理' : '未处理'}
</span>
</td>
<td>
<button class="btn" onclick="viewDetail('${ticket.id}')">详情</button>
</td>
</tr>
`;
});
html += '</tbody></table>';
resultsDiv.innerHTML = html;
}
function formatDate(dateString) {
if (!dateString) return '';
return new Date(dateString).toLocaleDateString('zh-CN');
}
function viewDetail(id) {
window.location.href = `detail.html?id=${id}`;
}
// 事件绑定(替代 onclick
document.getElementById('searchBtn').addEventListener('click', searchTickets);
document.getElementById('searchTerm').addEventListener('keypress', function(e) {
if (e.key === 'Enter') searchTickets();
});
</script>
</body>
</html>