157 lines
7.5 KiB
JavaScript
157 lines
7.5 KiB
JavaScript
// 采购相关功能
|
||
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 = '<p style="text-align:center;color:#888;padding:40px;">暂无采购记录</p>'; 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 += `<div class="purchase-month-group"><div class="purchase-month-header"><span>${month}</span><span>¥${monthTotal}</span></div>`;
|
||
monthItems.forEach(item => {
|
||
const timeShort = item.created_at.split(' ')[1]?.substring(0,5) || '';
|
||
const dateShort = item.created_at.split(' ')[0]?.substring(5) || '';
|
||
html += `
|
||
<div class="purchase-item" onclick="openDetail('${item.id}')">
|
||
<div class="item-main"><span class="item-name">${escapeHtml(item.item)}</span><span class="item-amount">¥${item.amount}</span></div>
|
||
<div class="item-meta">
|
||
<span>${dateShort} ${timeShort}</span>
|
||
<span>×${item.quantity} ${item.invoice_type !== '无票' ? '· ' + item.invoice_type : ''}</span>
|
||
<span class="status-badge ${item.status==='已完成'?'done':''}">${item.status}</span>
|
||
</div>
|
||
</div>`;
|
||
});
|
||
html += '</div>';
|
||
});
|
||
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 = '<div class="attachments">' + p.attachments.map(a => `<img class="img-thumb" src="${a.file_path}" alt="${a.file_path}" ondblclick="onImgThumbDblClick(this)">`).join('') + '</div>';
|
||
const historyHtml = p.history?.map(h => `<li><span class="history-time">${h.timestamp}</span> ${h.user}: ${h.action}</li>`).join('') || '';
|
||
document.getElementById('detail-content').innerHTML = `
|
||
<div class="detail-row"><strong>数量:</strong>${p.quantity}</div>
|
||
<div class="detail-row"><strong>单价:</strong>¥${p.unit_price}</div>
|
||
<div class="detail-row"><strong>邮费:</strong>¥${p.freight}</div>
|
||
<div class="detail-row"><strong>总金额:</strong>¥${p.amount}</div>
|
||
<div class="detail-row"><strong>付款方式:</strong>${p.payment_method || '未指定'}</div>
|
||
<div class="detail-row"><strong>发票:</strong>${p.invoice_type || '无票'}</div>
|
||
<div class="detail-row"><strong>状态:</strong>${p.status}</div>
|
||
<div class="detail-row"><strong>申请人:</strong>${p.applicant}</div>
|
||
<div class="detail-row"><strong>采购时间:</strong>${p.created_at}</div>
|
||
<div class="detail-row"><strong>备注:</strong>${p.remarks || '无'}</div>
|
||
${attachHtml}
|
||
<h4 style="margin-top:12px;">操作历史</h4>
|
||
<ul class="history-list">${historyHtml}</ul>`;
|
||
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 = '<p>暂无采购记录</p>';
|
||
else {
|
||
summary.forEach(s => {
|
||
html += `<div class="summary-card" onclick="event.stopPropagation(); closeDetailModal(); openPurchasePage('${s.room_id}')" style="margin:8px 0;"><h4>${escapeHtml(s.room_name)}</h4><p>${s.purchase_count} 条,合计 ¥${s.total_amount}</p></div>`;
|
||
});
|
||
}
|
||
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 });
|
||
}
|