document.getElementById('transactionForm').addEventListener('submit', function(e) { e.preventDefault(); const customerNameInput = document.getElementById('customerName'); let customerName = customerNameInput.value.trim(); const amount = parseFloat(document.getElementById('amount').value); const remark = document.getElementById('remark').value; if (!customerName || isNaN(amount)) { alert('请填写完整的客户名字和金额'); return; } fetch('/api/transaction', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ customerName, amount, remark }) }) .then(response => response.json()) .then(data => { console.log('Success:', data); currentCustomer = customerName; // 记录当前客户 loadTransactions(customerName); // 保持当前客户的明细页面 }) .catch((error) => { console.error('Error:', error); }); customerNameInput.value = ''; document.getElementById('amount').value = ''; document.getElementById('remark').value = ''; }); let currentCustomer = null; let lastHighlightedCustomer = null; let lastScrollPosition = 0; document.getElementById('accountSummaryHeader').addEventListener('click', function() { loadTransactions(null, true); // 返回到所有客户的页面并收起所有明细 setTimeout(() => { window.scrollTo(0, lastScrollPosition); }, 0); }); function loadTransactions(keepOpenCustomer = null, collapseAll = false) { fetch('/api/transactions') .then(response => response.json()) .then(data => { const customerTable = document.getElementById('customerTable'); customerTable.innerHTML = ''; let totalAllCustomers = 0; const customerMap = {}; data.forEach(transaction => { if (!customerMap[transaction.customerName]) { customerMap[transaction.customerName] = { totalAmount: 0, details: [] }; } customerMap[transaction.customerName].totalAmount += transaction.amount; customerMap[transaction.customerName].details.push(transaction); }); Object.keys(customerMap).forEach(customerName => { const customerData = customerMap[customerName]; const customerRow = document.createElement('tr'); customerRow.classList.add('collapsible'); customerRow.setAttribute('data-customer', customerName); customerRow.innerHTML = ` ${customerName} ${customerData.totalAmount.toFixed(2)} `; customerTable.appendChild(customerRow); const detailsRow = document.createElement('tr'); detailsRow.classList.add('details'); detailsRow.style.display = 'none'; // 初始化时隐藏 detailsRow.innerHTML = `
日期 金额 备注 操作
`; customerTable.appendChild(detailsRow); const detailsBody = detailsRow.querySelector('tbody'); customerData.details.forEach(transaction => { const newDetailRow = document.createElement('tr'); const date = new Date(transaction.created_at).toLocaleDateString(); newDetailRow.innerHTML = ` ${date} ${transaction.amount.toFixed(2)} ${transaction.remark.replace(/\n/g, '
')} `; detailsBody.appendChild(newDetailRow); newDetailRow.querySelector('.delete-button').addEventListener('click', function() { const transactionId = this.getAttribute('data-id'); fetch(`/api/transaction/${transactionId}`, { method: 'DELETE' }) .then(response => response.json()) .then(data => { console.log('Deleted:', data); currentCustomer = customerName; // 记录当前客户 loadTransactions(currentCustomer); // 保持当前客户的明细页面 }) .catch((error) => { console.error('Error:', error); }); }); }); detailsRow.querySelector('.detailsForm').addEventListener('submit', function(event) { event.preventDefault(); const detailAmountInput = this.querySelector('input[type="number"]'); const detailAmount = parseFloat(detailAmountInput.value); const detailRemarkInput = this.querySelector('textarea'); const detailRemark = detailRemarkInput.value; if (!isLoggedIn()) { alert('请先登录'); return; } if (!isNaN(detailAmount)) { fetch('/api/transaction', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ customerName, amount: detailAmount, remark: detailRemark }) }) .then(response => response.json()) .then(data => { console.log('Success:', data); currentCustomer = customerName; // 记录当前客户 loadTransactions(currentCustomer); // 保持当前客户的明细页面 }) .catch((error) => { console.error('Error:', error); }); detailAmountInput.value = ''; detailRemarkInput.value = ''; } }); customerRow.addEventListener('click', function() { if (currentCustomer === customerName) { loadTransactions(); // 返回到所有客户的页面 currentCustomer = null; } else { lastScrollPosition = window.scrollY; currentCustomer = customerName; showCustomerDetails(customerName); } }); if (customerName === keepOpenCustomer && !collapseAll) { detailsRow.style.display = 'table-row'; // 滚动到添加的客户位置 customerRow.scrollIntoView({ behavior: 'smooth', block: 'start' }); } customerRow.querySelector('.delete-button').addEventListener('click', function(e) { e.stopPropagation(); const customerName = this.getAttribute('data-customer'); if (confirm(`确定要删除客户 ${customerName} 及其所有记录吗?`)) { fetch(`/api/transactions?customerName=${customerName}`, { method: 'DELETE' }) .then(response => response.json()) .then(data => { console.log('Deleted:', data); loadTransactions(); }) .catch((error) => { console.error('Error:', error); }); } }); }); totalAllCustomers = Object.values(customerMap).reduce((total, customer) => total + customer.totalAmount, 0); document.getElementById('totalAllCustomers').textContent = totalAllCustomers.toFixed(2); updateLoginStatus(); // 处理滚动位置 if (collapseAll) { setTimeout(() => { window.scrollTo(0, lastScrollPosition); }, 0); } }); } function showCustomerDetails(customerName) { const customerTable = document.getElementById('customerTable'); const rows = customerTable.querySelectorAll('tr'); let showDetails = false; rows.forEach(row => { const dataCustomer = row.getAttribute('data-customer'); if (dataCustomer) { if (dataCustomer === customerName) { row.style.display = 'table-row'; showDetails = true; } else { row.style.display = 'none'; } } else if (row.classList.contains('details')) { if (row.previousElementSibling && row.previousElementSibling.getAttribute('data-customer') === customerName) { row.style.display = 'table-row'; } else { row.style.display = 'none'; } } }); } function isLoggedIn() { return localStorage.getItem('isLoggedIn') === 'true'; } function login() { const username = document.getElementById('username').value.trim(); if (username === 'sca') { localStorage.setItem('isLoggedIn', 'true'); updateLoginStatus(); } else { alert('用户名错误'); } } function logout() { localStorage.setItem('isLoggedIn', 'false'); updateLoginStatus(); } function updateLoginStatus() { const isLoggedIn = localStorage.getItem('isLoggedIn') === 'true'; document.getElementById('loginForm').style.display = isLoggedIn ? 'none' : 'block'; document.getElementById('logoutForm').style.display = isLoggedIn ? 'block' : 'none'; document.getElementById('transactionForm').style.display = isLoggedIn ? 'flex' : 'none'; document.getElementById('exportButton').style.display = isLoggedIn ? 'block' : 'none'; const deleteButtons = document.querySelectorAll('.delete-button'); deleteButtons.forEach(button => { button.style.display = isLoggedIn ? 'inline' : 'none'; }); const detailsForms = document.querySelectorAll('.detailsForm'); detailsForms.forEach(form => { form.style.display = isLoggedIn ? 'flex' : 'none'; }); } document.getElementById('exportButton').addEventListener('click', function() { if (!isLoggedIn()) { alert('请先登录'); return; } fetch('/api/transactions') .then(response => response.json()) .then(data => { let csvContent = "\uFEFF客户名字,金额\n"; // Add BOM for UTF-8 let customerMap = new Map(); // 将交易数据按客户名字分组 data.forEach(transaction => { if (!customerMap.has(transaction.customerName)) { customerMap.set(transaction.customerName, []); } customerMap.get(transaction.customerName).push(transaction); }); // 生成有两条及以上记录的客户的 CSV 内容 let multipleRecords = ''; let singleRecords = ''; customerMap.forEach((transactions, customerName) => { if (transactions.length > 1) { transactions.forEach(transaction => { multipleRecords += `${transaction.customerName},${transaction.amount}\n`; }); multipleRecords += '\n'; // Add a blank line between different customers } else { transactions.forEach(transaction => { singleRecords += `${transaction.customerName},${transaction.amount}\n`; }); } }); csvContent += multipleRecords + singleRecords; const encodedUri = encodeURI('data:text/csv;charset=utf-8,' + csvContent); const link = document.createElement("a"); link.setAttribute("href", encodedUri); // 获取当前日期 const currentDate = new Date(); const year = currentDate.getFullYear(); const month = (currentDate.getMonth() + 1).toString().padStart(2, '0'); const day = currentDate.getDate().toString().padStart(2, '0'); const formattedDate = `${year}-${month}-${day}`; // 设置下载文件名 link.setAttribute("download", `transactions_${formattedDate}.csv`); document.body.appendChild(link); // Required for FF link.click(); document.body.removeChild(link); // Cleanup }); }); updateLoginStatus(); loadTransactions();