// expense.js — 费用管理模块 function renderExpense() { const records = state.data.expense || []; const money = (v) => `¥ ${(Number(v || 0)).toLocaleString("zh-CN", { minimumFractionDigits: 0, maximumFractionDigits: 2 })}`; const badge = (s) => { const m = { "已审批": "green", "已采购": "blue", "已完成": "slate", "待审批": "amber" }; const c = m[s] || "amber"; return `${s}`; }; const esc = (s) => (s || "").replace(/&/g, "&").replace(//g, ">").replace(/"/g, """); const totalAmount = records.reduce((s, r) => s + (r.amount || 0), 0); document.querySelector("#expense").innerHTML = `
费用记录${records.length}
费用金额${money(totalAmount)}
待审批${records.filter(r => r.status === '待审批').length}

费用列表 (${records.length})

${records.length ? records.map(r => ``).join("") : ''}
项目名称采购内容供应商金额采购日期状态分类备注
${esc(r.project_name)}${esc(r.purchase_item)}${esc(r.supplier)}${money(r.amount)}${r.purchase_date || '—'}${badge(r.status)}${esc(r.category)}${esc(r.notes) || '—'}
暂无费用记录
合计(${records.length} 条)${money(totalAmount)}
`; if (window.lucide) window.lucide.createIcons(); } window.openExpenseModal = () => { const form = document.querySelector("#expenseModal form"); form.reset(); form.querySelector('[name="expense_id"]').value = ""; document.querySelector("#expenseModalTitle").textContent = "新增费用"; document.querySelector("#expenseDeleteBtn").classList.add("hidden"); document.querySelector("#expenseModal").classList.remove("hidden"); }; window.closeExpenseModal = () => { document.querySelector("#expenseModal").classList.add("hidden"); }; window.openExpenseEdit = (id) => { const r = (state.data.expense || []).find(x => x.id === id); if (!r) return; const form = document.querySelector("#expenseModal form"); form.reset(); const setVal = (name, val) => { const el = form.querySelector(`[name="${name}"]`); if (el) el.value = val || ""; }; setVal("expense_id", r.id); setVal("project_name", r.project_name); setVal("purchase_item", r.purchase_item); setVal("supplier", r.supplier); setVal("amount", r.amount); setVal("purchase_date", r.purchase_date); setVal("status", r.status); setVal("category", r.category); setVal("notes", r.notes); document.querySelector("#expenseModalTitle").textContent = "编辑费用"; document.querySelector("#expenseDeleteBtn").classList.remove("hidden"); document.querySelector("#expenseModal").classList.remove("hidden"); }; window.saveExpense = async (event) => { event.preventDefault(); const form = event.target; const data = Object.fromEntries(new FormData(form).entries()); const isEdit = !!data.expense_id; delete data.expense_id; const url = isEdit ? `/api/expense/${form.querySelector('[name="expense_id"]').value}` : "/api/expense"; const method = isEdit ? "PUT" : "POST"; const resp = await fetch(url, { method, headers: { "Content-Type": "application/json" }, body: JSON.stringify({ data: { ...data, tenant: state.tenant } }) }); if (!resp.ok) { alert("保存失败"); return; } // Refresh data const bResp = await fetch(`/api/bootstrap?tenant=${encodeURIComponent(state.tenant)}`); if (bResp.ok) { const bd = await bResp.json(); state.data = bd; applyUserTenants(); renderExpense(); } closeExpenseModal(); }; window.deleteExpenseItem = async () => { const id = document.querySelector("#expenseModal form [name='expense_id']").value; if (!id || !confirm("确定删除?")) return; const resp = await fetch(`/api/expense/${id}`, { method: "DELETE" }); if (!resp.ok) { alert("删除失败"); return; } const bResp = await fetch(`/api/bootstrap?tenant=${encodeURIComponent(state.tenant)}`); if (bResp.ok) { const bd = await bResp.json(); state.data = bd; applyUserTenants(); renderExpense(); } closeExpenseModal(); };