// 采购相关功能 async function loadPurchases() { if (!Store.currentRoom) return; const token = Store.getToken(); const res = await fetch('/api/rooms/' + Store.currentRoom + '/purchases', { headers: { 'Authorization': `Bearer ${token}` } }); const items = await res.json(); renderPurchasePanel(items); } function renderPurchasePanel(items) { const container = document.getElementById('purchase-panel-body'); if (items.length === 0) { container.innerHTML = '

暂无采购记录

'; return; } const groups = {}; items.forEach(item => { const month = formatMonth(item.created_at); if (!groups[month]) groups[month] = []; groups[month].push(item); }); let html = ''; Object.keys(groups).sort().reverse().forEach(month => { const monthItems = groups[month]; const monthTotal = monthItems.reduce((s, i) => s + (i.amount||0), 0); html += `
${month}¥${monthTotal}
`; monthItems.forEach(item => { const timeShort = item.created_at.split(' ')[1]?.substring(0,5) || ''; const dateShort = item.created_at.split(' ')[0]?.substring(5) || ''; html += `
${escapeHtml(item.item)}¥${item.amount}
${dateShort} ${timeShort} ×${item.quantity} ${item.invoice_type !== '无票' ? '· ' + item.invoice_type : ''} ${item.status}
`; }); html += '
'; }); container.innerHTML = html; } function formatMonth(dateStr) { const clean = dateStr.replace(/-/g, '/'); const parts = clean.split('/'); if (parts.length >= 2) return `${parts[0]}年${parseInt(parts[1], 10)}月`; return dateStr.substring(0,7); } async function openDetail(pid) { const token = Store.getToken(); const res = await fetch('/api/purchases/' + pid, { headers: { 'Authorization': `Bearer ${token}` } }); const p = await res.json(); document.getElementById('detail-title').textContent = p.item; let attachHtml = ''; if (p.attachments?.length) attachHtml = '
' + p.attachments.map(a => `${a.file_path}`).join('') + '
'; const historyHtml = p.history?.map(h => `
  • ${h.timestamp} ${h.user}: ${h.action}
  • `).join('') || ''; document.getElementById('detail-content').innerHTML = `
    数量:${p.quantity}
    单价:¥${p.unit_price}
    邮费:¥${p.freight}
    总金额:¥${p.amount}
    付款方式:${p.payment_method || '未指定'}
    发票:${p.invoice_type || '无票'}
    状态:${p.status}
    申请人:${p.applicant}
    采购时间:${p.created_at}
    备注:${p.remarks || '无'}
    ${attachHtml}

    操作历史

    `; document.getElementById('detail-modal').classList.remove('hidden'); } function closeDetailModal() { document.getElementById('detail-modal').classList.add('hidden'); } async function openSummary() { const token = Store.getToken(); const res = await fetch('/api/summary', { headers: { 'Authorization': `Bearer ${token}` } }); const summary = await res.json(); let html = ''; if (summary.length === 0) html = '

    暂无采购记录

    '; else { summary.forEach(s => { html += `

    ${escapeHtml(s.room_name)}

    ${s.purchase_count} 条,合计 ¥${s.total_amount}

    `; }); } document.getElementById('detail-title').textContent = '采购汇总'; document.getElementById('detail-content').innerHTML = html; document.getElementById('detail-modal').classList.remove('hidden'); } // 群聊管理 function openCreateRoom() { document.getElementById('create-modal').classList.remove('hidden'); } function closeCreateModal() { document.getElementById('create-modal').classList.add('hidden'); } async function confirmCreateRoom() { const name = document.getElementById('new-room-name').value.trim(); if (!name) return alert('请输入名称'); const whiteList = document.getElementById('white-list').value.trim(); const token = Store.getToken(); await fetch('/api/rooms', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ name, whiteList }) }); closeCreateModal(); loadRooms(); } function openManageRoom(roomId) { const room = Store.rooms.find(r => r.id === roomId); if (!room) return; document.getElementById('manage-title').textContent = '编辑群聊'; document.getElementById('manage-room-name').value = room.name; document.getElementById('manage-white-list').value = room.white_list || ''; document.getElementById('manage-modal').dataset.roomId = roomId; document.getElementById('manage-modal').classList.remove('hidden'); } function closeManageModal() { document.getElementById('manage-modal').classList.add('hidden'); } async function saveRoom() { const roomId = document.getElementById('manage-modal').dataset.roomId; const name = document.getElementById('manage-room-name').value.trim(); const whiteList = document.getElementById('manage-white-list').value.trim(); if (!name) return alert('请输入群聊名称'); const token = Store.getToken(); const res = await fetch('/api/rooms/' + roomId, { method: 'PUT', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ name, whiteList }) }); if (res.ok) { closeManageModal(); loadRooms(); } else { const err = await res.json(); alert(err.error || '更新失败'); } } async function deleteRoom() { if (!confirm('确定要删除该群聊吗?所有消息和采购数据将被永久删除。')) return; const roomId = document.getElementById('manage-modal').dataset.roomId; const token = Store.getToken(); const res = await fetch('/api/rooms/' + roomId, { method: 'DELETE', headers: { 'Authorization': `Bearer ${token}` } }); if (res.ok) { closeManageModal(); loadRooms(); if (Store.currentRoom === roomId) showList(); } else { const err = await res.json(); alert(err.error || '删除失败'); } } // 滑动手势 function initSwipeGestures() { const chatPage = document.getElementById('chat-page'); let startX = 0; chatPage.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; }, { passive: true }); chatPage.addEventListener('touchend', (e) => { if (!startX) return; const endX = e.changedTouches[0].clientX; const diffX = endX - startX; if (diffX > 50) backToPurchase(); startX = 0; }, { passive: true }); }