// performance.js — 绩效模块 window.renderPerformance = () => { const data = state.data; if (!data) return; if (state.perfQuarter === undefined) state.perfQuarter = Math.floor(new Date().getMonth() / 3); const q = state.perfQuarter; const qLabel = ['Q1 (1-3月)', 'Q2 (4-6月)', 'Q3 (7-9月)', 'Q4 (10-12月)']; const qRanges = [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]; const qRange = qRanges[q]; const storageKey = 'opc-performance-Q' + (q + 1); const pfs = (data.projectFinances || []).filter(p => p.status === '已签约'); const sumQ = (field) => { let total = 0; pfs.forEach(p => { try { JSON.parse(p.budget_data || '[]').forEach(b => { const m = parseInt((b.month || '').substring(5)) || 0; if (qRange.includes(m)) total += parseFloat(b[field] || 0); }); } catch (e) {} }); return Math.round(total); }; const signTotal = Math.round(pfs.filter(x => { const m = parseInt((x.sign_month || '0').substring(5)) || 0; return qRange.includes(m); }).reduce((a, p) => a + (p.sign_amount || 0), 0)); const revTotal = sumQ('rev'); const grossTotal = sumQ('gross'); const paymentTotal = sumQ('payment'); const rows = [ { key: 'sign', label: '签约', complete: signTotal, icon: 'file-text', defWeight: 10 }, { key: 'rev', label: '收入', complete: revTotal, icon: 'dollar-sign', defWeight: 20 }, { key: 'gross', label: '毛利', complete: grossTotal, icon: 'trending-up', defWeight: 50 }, { key: 'payment', label: '回款', complete: paymentTotal, icon: 'coins', defWeight: 20 }, ]; const saved = JSON.parse(localStorage.getItem(storageKey) || '{}'); function val(key, field, def) { const r = saved[key] || {}; return r[field] !== undefined && r[field] !== '' ? Number(r[field]) : def; } function moneyWan(v) { if (v >= 10000) return (v / 10000).toFixed(1) + '万'; return v.toLocaleString(); } let totalScore = 0; const tableRows = rows.map(r => { const targetWan = val(r.key, 'targetWan', 0); const target = Math.round(targetWan * 10000); const weight = val(r.key, 'weight', r.defWeight); const score = target > 0 ? Math.round((r.complete / target) * weight * 10) / 10 : 0; totalScore += score; return `
| 指标 | 目标(万) | 完成情况 | 权重 | 评分 |
|---|---|---|---|---|
| 合计 | — | — | 100 | ${totalScore.toFixed(1)} |