// 订单管理页面脚本 let currentOrders = []; let currentCoupons = []; let currentOrderId = null; // DOM 元素 const ordersTableBody = document.getElementById('ordersTableBody'); const couponsTableBody = document.getElementById('couponsTableBody'); const searchInput = document.getElementById('searchOrder'); const statusFilter = document.getElementById('statusFilter'); const orderDetailModal = document.getElementById('orderDetailModal'); const shippingModal = document.getElementById('shippingModal'); const createCouponModal = document.getElementById('createCouponModal'); // 页面加载时初始化 document.addEventListener('DOMContentLoaded', function() { loadOrders(); loadCoupons(); }); // 选项卡切换功能 function showTab(tabName) { // 隐藏所有选项卡内容 const tabs = document.querySelectorAll('.tab-content'); tabs.forEach(tab => tab.classList.remove('active')); // 移除所有按钮的活动状态 const buttons = document.querySelectorAll('.tab-btn'); buttons.forEach(btn => btn.classList.remove('active')); // 显示选中的选项卡内容 document.getElementById(tabName + 'Tab').classList.add('active'); // 激活相应按钮 event.target.classList.add('active'); // 根据选项卡加载数据 if (tabName === 'coupons') { loadCoupons(); } else if (tabName === 'orders') { loadOrders(); } } // 加载订单列表 async function loadOrders(search = '', status = '') { try { showLoading(); const params = new URLSearchParams(); if (search) params.append('search', search); if (status) params.append('status', status); const response = await fetch(`/api/admin/orders?${params}`); const data = await response.json(); if (response.ok) { currentOrders = data.orders; updateOrdersTable(data.orders); updateStats(data.stats); } else { throw new Error(data.error || '加载订单失败'); } } catch (error) { console.error('Load orders error:', error); showError('加载订单失败: ' + error.message); } } // 更新订单表格 function updateOrdersTable(orders) { if (!orders || orders.length === 0) { ordersTableBody.innerHTML = '暂无订单数据'; return; } ordersTableBody.innerHTML = orders.map(order => ` ${order.order_id}
${order.customer_name}
${order.customer_phone || '未提供电话'}
${order.shipping_address ? (order.shipping_address.length > 30 ? order.shipping_address.substring(0, 30) + '...' : order.shipping_address) : '未提供地址'}
${order.product_name}
数量: ${order.quantity}
$${order.total_amount.toFixed(2)} ${getStatusText(order.payment_status, 'payment')} ${getStatusText(order.shipping_status, 'shipping')} ${formatDate(order.created_at)} `).join(''); } // 更新统计数据 function updateStats(stats) { if (stats) { const totalElement = document.getElementById('totalOrders'); const pendingElement = document.getElementById('pendingOrders'); const shippedElement = document.getElementById('shippedOrders'); if (totalElement) totalElement.textContent = stats.total || 0; if (pendingElement) pendingElement.textContent = stats.pending_ship || 0; if (shippedElement) shippedElement.textContent = stats.shipped || 0; } } // 搜索订单 function searchOrders() { const search = searchInput.value.trim(); const status = statusFilter.value; loadOrders(search, status); } // 筛选订单 function filterOrders() { const search = searchInput.value.trim(); const status = statusFilter.value; loadOrders(search, status); } // 显示订单详情 async function showOrderDetail(orderId) { try { const response = await fetch(`/api/orders/${orderId}`); const order = await response.json(); if (response.ok) { const detailContent = document.getElementById('orderDetailContent'); detailContent.innerHTML = `

基本信息

订单号: ${order.order_id}
支付ID: ${order.payment_id || '未设置'}
创建时间: ${formatDate(order.created_at)}
更新时间: ${formatDate(order.updated_at)}

客户信息

姓名: ${order.customer_name}
邮箱: ${order.customer_email || '未提供'}
电话: ${order.customer_phone || '未提供'}
收货地址: ${order.shipping_address}

商品信息

产品名称: ${order.product_name}
单价: $${order.unit_price.toFixed(2)}
数量: ${order.quantity}
总金额: $${order.total_amount.toFixed(2)}

状态信息

支付状态: ${getStatusText(order.payment_status, 'payment')}
发货状态: ${getStatusText(order.shipping_status, 'shipping')}
${order.tracking_number ? `
快递单号: ${order.tracking_number}
` : ''} ${order.shipping_notes ? `
发货备注: ${order.shipping_notes}
` : ''}
`; orderDetailModal.style.display = 'flex'; } else { throw new Error(order.error || '获取订单详情失败'); } } catch (error) { console.error('Show order detail error:', error); alert('获取订单详情失败: ' + error.message); } } // 复制订单收货信息 function copyOrderInfo(orderId) { const order = currentOrders.find(o => o.order_id === orderId); if (!order) return; // 组合收货信息:姓名, 电话, 地址 let infoText = order.customer_name; if (order.customer_phone) { infoText += ', ' + order.customer_phone; } infoText += ', ' + order.shipping_address; // 复制到剪贴板 copyText(infoText); } // 显示发货模态框 function showShippingModal(orderId) { currentOrderId = orderId; const order = currentOrders.find(o => o.order_id === orderId); if (!order) return; // 清空表单 document.getElementById('trackingNumber').value = ''; document.getElementById('shippingNotes').value = ''; // 显示模态框 shippingModal.style.display = 'flex'; document.getElementById('trackingNumber').focus(); } // 关闭发货模态框 function closeShippingModal() { shippingModal.style.display = 'none'; currentOrderId = null; } // 确认发货 async function confirmShipping() { const trackingNumber = document.getElementById('trackingNumber').value.trim(); const shippingNotes = document.getElementById('shippingNotes').value.trim(); if (!trackingNumber) { alert('请输入运单号'); document.getElementById('trackingNumber').focus(); return; } if (!currentOrderId) { alert('订单ID错误'); return; } try { const response = await fetch(`/api/admin/orders/${currentOrderId}/shipping`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ shipping_status: 'shipped', tracking_number: trackingNumber, shipping_notes: shippingNotes }) }); const result = await response.json(); if (response.ok) { alert('订单已成功发货!'); closeShippingModal(); loadOrders(); // 重新加载订单列表 } else { throw new Error(result.error || '发货失败'); } } catch (error) { console.error('Shipping error:', error); alert('发货失败: ' + error.message); } } // 确认并标记为已发货 function confirmMarkAsShipped(orderId) { if (confirm('确认标记此订单为已发货吗?')) { markAsShipped(orderId); } } // 一键标记为已发货 async function markAsShipped(orderId) { try { const response = await fetch(`/api/admin/orders/${orderId}/shipping`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ shipping_status: 'shipped' }) }); const result = await response.json(); if (response.ok) { alert('订单已标记为发货!'); loadOrders(); // 重新加载订单列表 } else { throw new Error(result.error || '标记发货失败'); } } catch (error) { console.error('Mark as shipped error:', error); alert('标记发货失败: ' + error.message); } } // 复制文本到剪贴板 async function copyText(text) { try { await navigator.clipboard.writeText(text); // 显示复制成功提示 showCopySuccess(); } catch (err) { // 降级方案:使用传统方法 const textArea = document.createElement('textarea'); textArea.value = text; document.body.appendChild(textArea); textArea.select(); document.execCommand('copy'); document.body.removeChild(textArea); showCopySuccess(); } } // 显示复制成功提示 function showCopySuccess() { // 创建提示元素 const toast = document.createElement('div'); toast.className = 'copy-toast'; toast.textContent = '已复制到剪贴板'; document.body.appendChild(toast); // 3秒后移除提示 setTimeout(() => { if (toast.parentNode) { toast.parentNode.removeChild(toast); } }, 3000); } // 关闭订单详情模态框 function closeOrderDetail() { orderDetailModal.style.display = 'none'; } // 获取状态文本 function getStatusText(status, type) { if (type === 'payment') { switch(status) { case 'pending': return '未支付'; case 'finished': return '已支付'; case 'failed': return '支付失败'; case 'confirming': return '确认中'; default: return status || '未知'; } } else if (type === 'shipping') { switch(status) { case 'pending': return '未发货'; case 'shipped': return '已发货'; default: return status || '未知'; } } return status || '未知'; } // 显示加载状态 function showLoading() { ordersTableBody.innerHTML = '加载中...'; } // 显示错误信息 function showError(message) { ordersTableBody.innerHTML = `错误: ${message}`; } // 格式化日期 function formatDate(dateString) { if (!dateString) return '未设置'; const date = new Date(dateString); return date.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' }); } // 加载优惠码列表 async function loadCoupons() { try { showCouponsLoading(); const response = await fetch('/api/admin/coupons'); const data = await response.json(); if (response.ok) { currentCoupons = data.coupons; updateCouponsTable(data.coupons); } else { throw new Error(data.error || '加载优惠码失败'); } } catch (error) { console.error('Load coupons error:', error); showCouponsError('加载优惠码失败: ' + error.message); } } // 更新优惠码表格 function updateCouponsTable(coupons) { if (!coupons || coupons.length === 0) { couponsTableBody.innerHTML = '暂无优惠码数据'; return; } couponsTableBody.innerHTML = coupons.map(coupon => ` ${coupon.code} ${coupon.name} ${coupon.discount_type === 'percentage' ? coupon.discount_value + '%' : '$' + coupon.discount_value.toFixed(2)} ${coupon.discount_type === 'percentage' ? '百分比' : '固定金额'}
已使用: ${coupon.used_count} / ${coupon.max_uses === 999999 ? '无限' : coupon.max_uses}
${coupon.is_reusable ? '可重复使用' : '一次性使用'}
${coupon.is_active ? '启用' : '禁用'} ${formatDate(coupon.created_at)} `).join(''); } // 显示创建优惠码模态框 function showCreateCouponModal() { // 清空表单 document.getElementById('couponCode').value = ''; document.getElementById('couponName').value = ''; document.getElementById('discountType').value = 'percentage'; document.getElementById('discountValue').value = ''; document.getElementById('isReusable').checked = false; document.getElementById('maxUses').value = '1'; document.getElementById('maxUsesGroup').style.display = 'none'; onDiscountTypeChange(); // 更新提示文本 createCouponModal.style.display = 'flex'; document.getElementById('couponCode').focus(); } // 关闭创建优惠码模态框 function closeCreateCouponModal() { createCouponModal.style.display = 'none'; } // 折扣类型变化处理 function onDiscountTypeChange() { const discountType = document.getElementById('discountType').value; const hint = document.getElementById('discountHint'); if (discountType === 'percentage') { hint.textContent = '输入百分比数值,如:10 表示10%折扣'; } else { hint.textContent = '输入固定金额,如:5 表示减5美元'; } } // 可重复使用变化处理 function onReusableChange() { const isReusable = document.getElementById('isReusable').checked; const maxUsesGroup = document.getElementById('maxUsesGroup'); if (isReusable) { maxUsesGroup.style.display = 'block'; document.getElementById('maxUses').value = '10'; // 默认10次 } else { maxUsesGroup.style.display = 'none'; document.getElementById('maxUses').value = '1'; } } // 创建优惠码 async function createCoupon() { const code = document.getElementById('couponCode').value.trim(); const name = document.getElementById('couponName').value.trim(); const discountType = document.getElementById('discountType').value; const discountValue = parseFloat(document.getElementById('discountValue').value); const isReusable = document.getElementById('isReusable').checked; const maxUses = parseInt(document.getElementById('maxUses').value); // 验证表单 if (!code || !name || !discountValue) { alert('请填写所有必填字段'); return; } if (discountValue <= 0) { alert('折扣值必须大于0'); return; } if (discountType === 'percentage' && discountValue > 100) { alert('百分比折扣不能超过100%'); return; } if (isReusable && (!maxUses || maxUses < 1)) { alert('最大使用次数必须大于0'); return; } try { console.log('Creating coupon with data:', { code, name, discount_type: discountType, discount_value: discountValue, is_reusable: isReusable, max_uses: maxUses }); const response = await fetch('/api/admin/coupons', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ code: code, name: name, discount_type: discountType, discount_value: discountValue, is_reusable: isReusable, max_uses: maxUses }) }); console.log('Response status:', response.status); console.log('Response headers:', response.headers); const responseText = await response.text(); console.log('Response text:', responseText); let result; try { result = JSON.parse(responseText); } catch (parseError) { console.error('Failed to parse JSON:', parseError); console.error('Response was:', responseText.substring(0, 200)); throw new Error('服务器返回了无效的响应格式'); } if (response.ok) { alert('优惠码创建成功!'); closeCreateCouponModal(); loadCoupons(); // 重新加载优惠码列表 } else { throw new Error(result.error || '创建优惠码失败'); } } catch (error) { console.error('Create coupon error:', error); alert('创建优惠码失败: ' + error.message); } } // 切换优惠码状态 async function toggleCouponStatus(couponId, isActive) { try { const response = await fetch(`/api/admin/coupons/${couponId}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ is_active: isActive }) }); const result = await response.json(); if (response.ok) { alert(`优惠码已${isActive ? '启用' : '禁用'}!`); loadCoupons(); // 重新加载优惠码列表 } else { throw new Error(result.error || '更新优惠码状态失败'); } } catch (error) { console.error('Toggle coupon status error:', error); alert('更新优惠码状态失败: ' + error.message); } } // 确认删除优惠码 function confirmDeleteCoupon(couponId) { const coupon = currentCoupons.find(c => c.id === couponId); if (!coupon) { alert('优惠码未找到'); return; } const confirmMessage = `确认删除以下优惠码吗?\n\n优惠码:${coupon.code}\n名称:${coupon.name}\n已使用次数:${coupon.used_count}\n\n⚠️ 此操作不可撤销!`; if (confirm(confirmMessage)) { deleteCoupon(couponId); } } // 删除优惠码 async function deleteCoupon(couponId) { try { const response = await fetch(`/api/admin/coupons/${couponId}`, { method: 'DELETE' }); const result = await response.json(); if (response.ok) { alert('优惠码已成功删除!'); loadCoupons(); // 重新加载优惠码列表 } else { throw new Error(result.error || '删除优惠码失败'); } } catch (error) { console.error('Delete coupon error:', error); alert('删除优惠码失败: ' + error.message); } } // 显示优惠码加载状态 function showCouponsLoading() { couponsTableBody.innerHTML = '加载中...'; } // 显示优惠码错误信息 function showCouponsError(message) { couponsTableBody.innerHTML = `错误: ${message}`; } // 确认删除订单 function confirmDeleteOrder(orderId) { const order = currentOrders.find(o => o.order_id === orderId); if (!order) { alert('订单未找到'); return; } const confirmMessage = `确认删除以下订单吗?\n\n订单号:${orderId}\n客户:${order.customer_name}\n金额:$${order.total_amount.toFixed(2)} USDT\n\n⚠️ 此操作不可撤销!`; if (confirm(confirmMessage)) { deleteOrder(orderId); } } // 删除订单 async function deleteOrder(orderId) { try { const response = await fetch(`/api/admin/orders/${orderId}`, { method: 'DELETE', headers: { 'Content-Type': 'application/json' } }); const result = await response.json(); if (response.ok) { alert('订单已成功删除!'); loadOrders(); // 重新加载订单列表 } else { throw new Error(result.error || '删除订单失败'); } } catch (error) { console.error('Delete order error:', error); alert('删除订单失败: ' + error.message); } } // 键盘事件监听 document.addEventListener('keydown', function(e) { if (e.key === 'Escape') { closeOrderDetail(); closeShippingModal(); } }); // 搜索框回车事件 searchInput.addEventListener('keypress', function(e) { if (e.key === 'Enter') { searchOrders(); } });