// Trial Periods Page Management // This file handles the standalone trial periods page let trialPeriodsData = []; let trialCurrentPage = 1; let trialPageSize = 10; let trialTotalItems = 0; let trialTotalPages = 0; let customersMap = {}; // Map of customer ID to customer name // Initialize trial periods page function initTrialPeriodsPage() { const addTrialBtn = document.getElementById('addTrialBtn'); const trialPeriodsSection = document.getElementById('trialPeriodsSection'); if (!trialPeriodsSection) return; // Add trial button click if (addTrialBtn) { addTrialBtn.addEventListener('click', function () { openAddTrialModal(); }); } // Pagination controls document.getElementById('trialFirstPage')?.addEventListener('click', () => { trialCurrentPage = 1; loadAllTrialPeriods(); }); document.getElementById('trialPrevPage')?.addEventListener('click', () => { if (trialCurrentPage > 1) { trialCurrentPage--; loadAllTrialPeriods(); } }); document.getElementById('trialNextPage')?.addEventListener('click', () => { if (trialCurrentPage < trialTotalPages) { trialCurrentPage++; loadAllTrialPeriods(); } }); document.getElementById('trialLastPage')?.addEventListener('click', () => { trialCurrentPage = trialTotalPages; loadAllTrialPeriods(); }); document.getElementById('trialPageSizeSelect')?.addEventListener('change', function () { trialPageSize = parseInt(this.value); trialCurrentPage = 1; loadAllTrialPeriods(); }); // Load customers for dropdown loadCustomersForDropdown(); } // Load all customers for dropdown async function loadCustomersForDropdown() { try { console.log('Loading customers for dropdown...'); const response = await authenticatedFetch('/api/customers/list'); if (!response) { console.error('No response from API'); return; } const data = await response.json(); console.log('Customers data:', data); const customers = data.customers || []; console.log('Number of customers:', customers.length); customersMap = {}; const select = document.getElementById('trialCustomerSelect'); if (!select) { console.error('trialCustomerSelect element not found'); return; } // Keep the first option (请选择客户) select.innerHTML = ''; customers.forEach(customer => { customersMap[customer.id] = customer.customerName; const option = document.createElement('option'); option.value = customer.id; option.textContent = customer.customerName; select.appendChild(option); }); console.log('Customers loaded successfully. Total:', customers.length); } catch (error) { console.error('Error loading customers:', error); } } // Load all trial periods async function loadAllTrialPeriods() { try { const response = await authenticatedFetch('/api/trial-periods/all'); const data = await response.json(); trialPeriodsData = data.trialPeriods || []; trialTotalItems = trialPeriodsData.length; trialTotalPages = Math.ceil(trialTotalItems / trialPageSize); renderTrialPeriodsTable(); updateTrialPagination(); } catch (error) { console.error('Error loading trial periods:', error); trialPeriodsData = []; renderTrialPeriodsTable(); } } // Render expiry warning cards function renderExpiryWarnings() { const warningsContainer = document.getElementById('trialExpiryWarnings'); if (!warningsContainer) return; warningsContainer.innerHTML = ''; const now = new Date(); now.setHours(0, 0, 0, 0); // Set to start of today const warnings = []; trialPeriodsData.forEach(period => { const endTime = new Date(period.endTime); endTime.setHours(0, 0, 0, 0); // Set to start of day const daysUntilExpiry = Math.ceil((endTime - now) / (1000 * 60 * 60 * 24)); const customerName = customersMap[period.customerId] || period.customerId; if (daysUntilExpiry >= 0 && daysUntilExpiry <= 3) { warnings.push({ customerName, endTime: period.endTime, daysUntilExpiry, period }); } }); // Sort by days until expiry (most urgent first) warnings.sort((a, b) => a.daysUntilExpiry - b.daysUntilExpiry); warnings.forEach(warning => { const card = document.createElement('div'); let warningClass = 'warning-soon'; let iconClass = 'fa-info-circle'; let title = '试用即将到期'; let message = ''; if (warning.daysUntilExpiry === 0) { warningClass = 'warning-today'; iconClass = 'fa-exclamation-triangle'; title = '试用今日到期'; message = `${warning.customerName} 客户的试用期将于今天到期,请及时跟进!`; } else if (warning.daysUntilExpiry === 1) { warningClass = 'warning-tomorrow'; iconClass = 'fa-exclamation-circle'; title = '试用明日到期'; message = `${warning.customerName} 客户的试用期将于明天到期,请及时跟进!`; } else { warningClass = 'warning-soon'; iconClass = 'fa-info-circle'; title = '试用即将到期'; message = `${warning.customerName} 客户的试用期将于${warning.daysUntilExpiry}天后到期,请及时跟进!`; } const formattedEndTime = formatDateTime(warning.endTime); message += `
试用结束时间:${formattedEndTime}`; card.className = `expiry-warning-card ${warningClass}`; card.innerHTML = `
${title}
${message}
`; warningsContainer.appendChild(card); }); } // Render trial periods table function renderTrialPeriodsTable() { const tbody = document.getElementById('trialPeriodsBody'); if (!tbody) return; tbody.innerHTML = ''; if (trialPeriodsData.length === 0) { const row = document.createElement('tr'); row.innerHTML = '暂无试用时间记录'; tbody.appendChild(row); return; } // Paginate data const startIndex = (trialCurrentPage - 1) * trialPageSize; const endIndex = Math.min(startIndex + trialPageSize, trialPeriodsData.length); const pageData = trialPeriodsData.slice(startIndex, endIndex); pageData.forEach(period => { const row = document.createElement('tr'); // 显示客户名称,如果找不到则显示ID const customerName = customersMap[period.customerId] || period.customerId; const startTime = formatDateTime(period.startTime); const endTime = formatDateTime(period.endTime); const createdAt = formatDateTime(period.createdAt); row.innerHTML = ` ${customerName} ${startTime} ${endTime} ${createdAt} `; tbody.appendChild(row); }); // Add event listeners tbody.querySelectorAll('.edit-btn').forEach(btn => { btn.addEventListener('click', function () { const periodId = this.getAttribute('data-id'); openEditTrialModal(periodId); }); }); tbody.querySelectorAll('.delete-btn').forEach(btn => { btn.addEventListener('click', function () { const periodId = this.getAttribute('data-id'); deleteTrialPeriodFromPage(periodId); }); }); } // Update trial pagination function updateTrialPagination() { const startItem = trialTotalItems === 0 ? 0 : (trialCurrentPage - 1) * trialPageSize + 1; const endItem = Math.min(trialCurrentPage * trialPageSize, trialTotalItems); document.getElementById('trialPaginationInfo').textContent = `显示 ${startItem}-${endItem} 共 ${trialTotalItems} 条`; document.getElementById('trialFirstPage').disabled = trialCurrentPage === 1; document.getElementById('trialPrevPage').disabled = trialCurrentPage === 1; document.getElementById('trialNextPage').disabled = trialCurrentPage === trialTotalPages; document.getElementById('trialLastPage').disabled = trialCurrentPage === trialTotalPages; // Update page numbers const pageNumbers = document.getElementById('trialPageNumbers'); pageNumbers.innerHTML = ''; const maxVisiblePages = 5; let startPage = Math.max(1, trialCurrentPage - Math.floor(maxVisiblePages / 2)); let endPage = Math.min(trialTotalPages, startPage + maxVisiblePages - 1); if (endPage - startPage < maxVisiblePages - 1) { startPage = Math.max(1, endPage - maxVisiblePages + 1); } for (let i = startPage; i <= endPage; i++) { const pageBtn = document.createElement('button'); pageBtn.className = 'page-number'; if (i === trialCurrentPage) { pageBtn.classList.add('active'); } pageBtn.textContent = i; pageBtn.addEventListener('click', () => { trialCurrentPage = i; loadAllTrialPeriods(); }); pageNumbers.appendChild(pageBtn); } } // Open add trial modal function openAddTrialModal() { console.log('Opening add trial modal'); // Load customers first loadCustomersForDropdown().then(() => { console.log('Customers loaded, opening modal'); document.getElementById('trialCustomerSelect').value = ''; document.getElementById('trialStartTime').value = ''; document.getElementById('trialEndTime').value = ''; document.getElementById('addTrialPeriodModal').style.display = 'block'; }); } // Open edit trial modal function openEditTrialModal(periodId) { const period = trialPeriodsData.find(p => p.id === periodId); if (!period) return; document.getElementById('editTrialPeriodId').value = period.id; const startDate = new Date(period.startTime); const endDate = new Date(period.endTime); document.getElementById('editTrialStartTime').value = formatDateTimeLocal(startDate); document.getElementById('editTrialEndTime').value = formatDateTimeLocal(endDate); document.getElementById('editTrialPeriodModal').style.display = 'block'; } // Delete trial period from page async function deleteTrialPeriodFromPage(periodId) { if (!confirm('确定要删除这个试用时间记录吗?')) { return; } try { const response = await authenticatedFetch(`/api/trial-periods/${periodId}`, { method: 'DELETE' }); if (response.ok) { await loadAllTrialPeriods(); alert('试用时间删除成功!'); } else { alert('删除试用时间时出错'); } } catch (error) { console.error('Error deleting trial period:', error); alert('删除试用时间时出错'); } } // Create trial period from page async function createTrialPeriodFromPage() { const customerId = document.getElementById('trialCustomerSelect').value; const startTime = document.getElementById('trialStartTime').value; const endTime = document.getElementById('trialEndTime').value; if (!customerId) { alert('请选择客户'); return; } if (!startTime || !endTime) { alert('请填写开始时间和结束时间'); return; } const formData = { customerId: customerId, startTime: new Date(startTime).toISOString(), endTime: new Date(endTime).toISOString() }; try { const response = await authenticatedFetch('/api/trial-periods', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(formData) }); if (response.ok) { document.getElementById('addTrialPeriodModal').style.display = 'none'; document.getElementById('addTrialPeriodForm').reset(); await loadAllTrialPeriods(); alert('试用时间添加成功!'); } else { alert('添加试用时间时出错'); } } catch (error) { console.error('Error creating trial period:', error); alert('添加试用时间时出错'); } } // Initialize when switching to trial periods section document.addEventListener('DOMContentLoaded', function () { initTrialPeriodsPage(); // Override the form submit for add trial period const addForm = document.getElementById('addTrialPeriodForm'); if (addForm) { addForm.addEventListener('submit', async function (e) { e.preventDefault(); await createTrialPeriodFromPage(); }); } });