@@ -113,7 +113,7 @@ function renderFinance() {
const finHeaderBase = ` <div class="flex items-center gap-2"><button onclick="setFinView('overview')" class="px-3 py-1 rounded text-sm font-medium ${ state . finView === 'overview' ? 'bg-blue-600 text-white' : 'bg-slate-100 text-slate-600 hover:bg-slate-200' } ">总视图</button><span class="text-slate-300 mx-2">|</span><span class="text-sm text-slate-500">按季度:</span> ${ qLabels . map ( ( q , i ) => ` <button onclick="setFinQuarter( ${ i } )" class="px-3 py-1 rounded text-sm font-medium ${ state . finView === 'quarterly' && activeQ === i ? 'bg-blue-600 text-white' : 'bg-slate-100 text-slate-600 hover:bg-slate-200' } "> ${ q } </button> ` ) . join ( '' ) } <span class="text-slate-300 mx-2">|</span><span class="text-sm text-slate-500">按月度:</span> ${ activeMonths . map ( m => { const ms = ` 2026- ${ String ( m ) . padStart ( 2 , '0' ) } ` ; return ` <button onclick="setFinMonth(' ${ ms } ')" class="px-3 py-1 rounded text-sm font-medium ${ state . finView === 'monthly' && state . finMonth === ms ? 'bg-blue-600 text-white' : 'bg-slate-100 text-slate-600 hover:bg-slate-200' } "> ${ m } 月</button> ` ; } ).join('')}</div> ` ;
const finAddBtn = ` <button class="btn btn-primary btn-sm" onclick="openFinanceModal()">新增财务项目</button> ` ;
const finFilterTabs = ` <div class="finance-tabs" style="padding:0;border-bottom:1px solid #e2e8f0;margin-bottom:0"><button onclick="switchFinFilter('overview')" class="finance-tab ${ state . finFilter === 'overview' ? ' active' : '' } " style="font-size:14px;font-weight:600">月度总览 </button><button onclick="switchFinFilter('quarterlyOverview')" class="finance-tab ${ state . finFilter === 'quarterlyOverview' ? ' active' : '' } " style="font-size:14px;font-weight:600">季度总览 </button><button onclick="switchFinFilter('projects')" class="finance-tab ${ state . finFilter === 'projects' ? ' active' : '' } " style="font-size:14px;font-weight:600">项目 ( ${ pfs . length } )</button><button onclick="switchFinFilter('expense')" class="finance-tab ${ state . finFilter === 'expense' ? ' active' : '' } " style="font-size:14px;font-weight:600">平台费用</button></div> ` ;
const finFilterTabs = ` <div class="finance-tabs" style="padding:0;border-bottom:1px solid #e2e8f0;margin-bottom:0"><button onclick="switchFinFilter('overview')" class="finance-tab ${ state . finFilter === 'overview' ? ' active' : '' } " style="font-size:14px;font-weight:600">经营月报 </button><button onclick="switchFinFilter('quarterlyOverview')" class="finance-tab ${ state . finFilter === 'quarterlyOverview' ? ' active' : '' } " style="font-size:14px;font-weight:600">季度月报 </button><button onclick="switchFinFilter('projects')" class="finance-tab ${ state . finFilter === 'projects' ? ' active' : '' } " style="font-size:14px;font-weight:600">项目 ( ${ pfs . length } )</button><button onclick="switchFinFilter('expense')" class="finance-tab ${ state . finFilter === 'expense' ? ' active' : '' } " style="font-size:14px;font-weight:600">平台费用</button></div> ` ;
document . querySelector ( "#finance" ) . innerHTML = ` <div class="grid gap-4">
${ finFilterTabs }
@@ -192,12 +192,12 @@ function renderFinance() {
< p class = "text-lg font-bold text-rose-700" id = "costTotalCost" > ¥ 0 < / p >
< / d i v >
< div class = "bg-purple-50 rounded-lg p-3 text-center border border-purple-100" >
< p class = "text-xs text-purple-600 font-medium" > 总已付 < / p >
< p class = "text-xs text-purple-600 font-medium" > 总支出 < / p >
< p class = "text-lg font-bold text-purple-700" id = "costTotalPaid" > ¥ 0 < / p >
< / d i v >
< / d i v >
< table class = "w-full text-sm border border-slate-200 rounded-lg overflow-hidden" id = "costTable" >
< thead > < tr class = "bg-slate-50 border-b border-slate-200" > < th class = "p-2.5 text-left font-medium text-slate-500" style = "min-width:140px" > 月份 < / t h > < t h c l a s s = " p - 2 . 5 t e x t - l e f t f o n t - m e d i u m t e x t - s l a t e - 5 0 0 " s t y l e = " m i n - w i d t h : 1 2 0 p x " > 费 用 类 型 < / t h > < t h c l a s s = " p - 2 . 5 t e x t - r i g h t f o n t - m e d i u m t e x t - s l a t e - 5 0 0 " > 成 本 < / t h > < t h c l a s s = " p - 2 . 5 t e x t - r i g h t f o n t - m e d i u m t e x t - s l a t e - 5 0 0 " > 已 付 < / t h > < t h c l a s s = " p - 2 . 5 t e x t - l e f t f o n t - m e d i u m t e x t - s l a t e - 5 0 0 " > 备 注 < / t h > < t h c l a s s = " p - 2 . 5 w - 8 " > < / t h > < / t r > < / t h e a d >
< thead > < tr class = "bg-slate-50 border-b border-slate-200" > < th class = "p-2.5 text-left font-medium text-slate-500" style = "min-width:140px" > 月份 < / t h > < t h c l a s s = " p - 2 . 5 t e x t - l e f t f o n t - m e d i u m t e x t - s l a t e - 5 0 0 " s t y l e = " m i n - w i d t h : 1 2 0 p x " > 费 用 类 型 < / t h > < t h c l a s s = " p - 2 . 5 t e x t - r i g h t f o n t - m e d i u m t e x t - s l a t e - 5 0 0 " > 成 本 < / t h > < t h c l a s s = " p - 2 . 5 t e x t - r i g h t f o n t - m e d i u m t e x t - s l a t e - 5 0 0 " > 支 出 < / t h > < t h c l a s s = " p - 2 . 5 t e x t - l e f t f o n t - m e d i u m t e x t - s l a t e - 5 0 0 " > 备 注 < / t h > < t h c l a s s = " p - 2 . 5 w - 8 " > < / t h > < / t r > < / t h e a d >
< tbody id = "costTbody" > < / t b o d y >
< / t a b l e >
< button type = "button" class = "btn btn-ghost btn-sm mt-3" onclick = "addCostRow()" > < i data - lucide = "plus" > < / i > 添 加 月 份 < / b u t t o n >
@@ -252,11 +252,9 @@ function renderFinance() {
{ label : '已确收' , hideUnsigned : true , value : ctx => moneyWan ( ctx . sumRev ) , color : 'text-blue-700' } ,
{ label : '毛利' , value : ctx => money ( ctx . sumGross ) , color : 'text-green-700' } ,
{ label : '成本' , value : ctx => moneyWan ( ctx . sumCost ) , color : 'text-rose-700' } ,
{ label : '项目利润' , value : ctx => { const v = ctx . sumGross ; return { val : moneyWan ( v ) , cls : v >= 0 ? 'text-green-600' : 'text-red-600' } ; } , color : null } ,
{ label : '已回款' , hideUnsigned : true , value : ctx => moneyWan ( ctx . sumPay ) , color : 'text-amber-700' } ,
{ label : '已付 ' , hideUnsigned : true , value : ctx => moneyWan ( ctx . sumPaid ) , color : 'text-purple-700' } ,
{ label : '支出 ' , hideUnsigned : true , value : ctx => moneyWan ( ctx . sumPaid ) , color : 'text-purple-700' } ,
{ label : '现金流' , hideUnsigned : true , value : ctx => { const v = ctx . sumPay - ctx . sumPaid ; return { val : money ( v ) , cls : v >= 0 ? 'text-green-600' : 'text-red-600' } ; } , color : null } ,
{ label : '执行率' , hideUnsigned : true , value : ctx => ctx . sumRev && ctx . signTotal ? Math . round ( ctx . sumRev / ctx . signTotal * 100 ) + '%' : '—' , color : 'text-slate-500' } ,
{ label : '毛利率' , hideUnsigned : true , value : ctx => ctx . sumRev && ctx . sumGross ? Math . round ( ctx . sumGross / ctx . sumRev * 100 ) + '%' : '—' , color : 'text-slate-500' } ,
{ label : '回款率' , hideUnsigned : true , value : ctx => ctx . sumRev && ctx . sumPay ? Math . round ( ctx . sumPay / ctx . sumRev * 100 ) + '%' : '—' , color : 'text-slate-500' } ,
{ label : '付款率' , hideUnsigned : true , value : ctx => ctx . sumCost && ctx . sumPaid ? Math . round ( ctx . sumPaid / ctx . sumCost * 100 ) + '%' : '—' , color : 'text-slate-500' } ,
@@ -288,8 +286,9 @@ function renderFinance() {
const SIGNED _COLS = [
{ key : 'client_name' , label : '客户' } , { key : 'customer_name' , label : '项目名称' } , { key : 'sign_amount' , label : '签约金额' } ,
{ key : 'rev' , label : '已确收' } , { key : 'gross' , label : '毛利' } , { key : 'gross_rate' , label : '毛利率' } ,
{ key : 'payment' , label : '回款' } , { key : 'cashflow' , label : '现金流' } , { key : 'pay_rate' , label : '回款率' } ,
{ key : 'cost' , label : '成本' } , { key : 'paid' , label : '已付 ' } , { key : 'paid_rate' , label : '付款率' } ,
{ key : 'payment' , label : '回款' } , { key : 'pay_rate' , label : '回款率' } ,
{ key : 'cost' , label : '成本' } , { key : 'paid' , label : '支出 ' } , { key : 'paid_rate' , label : '付款率' } ,
{ key : 'cashflow' , label : '现金流' } ,
] ;
const UNSIGNED _COLS = [
{ key : 'client_name' , label : '客户' } , { key : 'customer_name' , label : '项目名称' } , { key : 'sign_amount' , label : '签约金额' } ,
@@ -310,7 +309,7 @@ function renderFinance() {
const cardGrid = isUnsigned ? 'grid-cols-4' : 'grid-cols-6' ;
const subtitle = isUnsigned
? '合同 → 毛利 → 成本 → 项目利润'
: '合同 → 确收 → 毛利 → 成本 → 项目利润 → 回款 → 已付 → 现金流 → 执行率 → 毛利率 → 回款率 → 付款率' ;
: '合同 → 确收 → 毛利 → 成本 → 项目利润 → 回款 → 支出 → 现金流 → 执行率 → 毛利率 → 回款率 → 付款率' ;
return card ( ` <div class="grid ${ cardGrid } gap-3 mb-3"> ${ cards . map ( ( [ l , v , c ] ) => '<div class="metric-card p-3"><span class="flex items-center gap-2 text-sm text-slate-500">' + l + '</span><strong class="mt-2 block text-xl ' + c + '">' + v + '</strong></div>' ) . join ( "" ) } </div> ` , "p-4" ) +
card ( ` <h3 class="text-sm font-bold text-slate-700">项目财务明细</h3><p class="text-xs text-slate-400 mb-3"> ${ subtitle } </p><div class="overflow-x-auto"><table class="w-full text-sm"> ${ thead } ${ tbody } </table></div> ` , "p-4" ) ;
} ;
@@ -326,7 +325,7 @@ function renderFinance() {
const grossR = rev && gross ? Math . round ( gross / rev * 100 ) + '%' : '<span class="text-slate-300">—</span>' ;
const cf = cashflow ? money ( cashflow ) : '<span class="text-slate-300">—</span>' ;
const cfCls = cashflow >= 0 ? 'text-green-600' : 'text-red-600' ;
return ` <tr class="border-b border-slate-100 hover:bg-slate-50 cursor-pointer" onclick="openPfEditModal( ${ pf . id } )"><td class="p-2 text-center align-middle text-sm"> ${ esc ( pf . client _name || "" ) } </td><td class="p-2 text-sm font-medium text-center align-middle truncate" style="min-width:300px;max-width:300px;width:300px" title=" ${ esc ( pf . customer _name ) } "> ${ esc ( pf . customer _name ) } </td><td class="p-2 text-center align-middle text-sm font-medium"> ${ money ( pf . sign _amount ) } </td><td class="p-2 text-center text-blue-700 align-middle"> ${ fmtNoUnit ( rev ) } </td><td class="p-2 text-center align-middle text-sm font-medium"> ${ fmtNoUnit ( gross ) } </td><td class="p-2 text-center align-middle text-sm"> ${ grossR } </td><td class="p-2 text-center text-amber-700 align-middle"> ${ fmtNoUnit ( payment ) } </td><td class="p-2 text-center font-semibold align-middle ${ cfCls } "> ${ cf } </td><td class="p-2 text-center align-middle text-sm"> ${ payR } </td><td class="p-2 text-center text-rose-700 align-middle"> ${ fmtNoUnit ( cost ) } </td><td class="p-2 text-center text-purple-700 align-middle"> ${ fmtNoUnit ( paid ) } </td><td class="p-2 text-center align-middle text-sm"> ${ paidR } </td></tr> ` ;
return ` <tr class="border-b border-slate-100 hover:bg-slate-50 cursor-pointer" onclick="openPfEditModal( ${ pf . id } )"><td class="p-2 text-center align-middle text-sm"> ${ esc ( pf . client _name || "" ) } </td><td class="p-2 text-sm font-medium text-center align-middle truncate" style="min-width:300px;max-width:300px;width:300px" title=" ${ esc ( pf . customer _name ) } "> ${ esc ( pf . customer _name ) } </td><td class="p-2 text-center align-middle text-sm font-medium"> ${ money ( pf . sign _amount ) } </td><td class="p-2 text-center text-blue-700 align-middle"> ${ fmtNoUnit ( rev ) } </td><td class="p-2 text-center align-middle text-sm font-medium"> ${ fmtNoUnit ( gross ) } </td><td class="p-2 text-center align-middle text-sm"> ${ grossR } </td><td class="p-2 text-center text-amber-700 align-middle"> ${ fmtNoUnit ( payment ) } </td><td class="p-2 text-center align-middle text-sm"> ${ payR } </td><td class="p-2 text-center text-rose-700 align-middle"> ${ fmtNoUnit ( cost ) } </td><td class="p-2 text-center text-purple-700 align-middle"> ${ fmtNoUnit ( paid ) } </td><td class="p-2 text-center align-middle text-sm"> ${ paidR } </td><td class="p-2 text-center font-semibold align-middle ${ cfCls } "> ${ cf } </td>< /tr> ` ;
} ;
// 待签约简版行
const tdRowUnsigned = ( pf , cost , gross ) => {
@@ -926,7 +925,7 @@ window.deleteFinanceItem = async () => {
}
}
// 月度总览 渲染
// 经营月报 渲染
function renderFinanceOverview ( ) {
const { summary , financeMonthly } = state . data ;
if ( ! summary ) return ;
@@ -936,22 +935,24 @@ function renderFinanceOverview() {
const card = ( body , cls ) => '<div class="card ' + ( cls || 'p-4' ) + '">' + body + '</div>' ;
const fm = financeMonthly || [ ] ;
const mLbl = [ '1月' , '2月' , '3月' , '4月' , '5月' , '6月' , '7月' , '8月' , '9月' , '10月' , '11月' , '12月' ] ;
const LABELS = [ '合同金额' , '确收金额' , '确收毛利' , '成本' , '已付 ' ] ;
const annualVals = [ m . signed _annual || m . signed _amount || 0 , m . revenue _annual || 0 , m . gross _annual || 0 , m . cost _annual || 0 , m . paid _annual || 0 ] ;
const fmFields = [ 'sign' , 'revenue' , 'gross' , 'cost' , 'paid' ] ;
const LABELS = [ '合同金额' , '确收金额' , '确收毛利' , '成本' , '支出' , '回款' , '项目现金流 ' ] ;
const annualVals = [ m . signed _annual || m . signed _amount || 0 , m . revenue _annual || 0 , m . gross _annual || 0 , m . cost _annual || 0 , m . paid _annual || 0 , m . payment _annual || 0 , ( m . payment _annual || 0 ) - ( m . paid _annual || 0 ) ];
const fmFields = [ 'sign' , 'revenue' , 'gross' , 'cost' , 'paid' , 'payment' , null ];
var thead = '<tr class="border-b border-slate-200"><th class="py-2 text-left text-slate-500 whitespace-nowrap">指标</th><th class="py-2 text-right font-semibold text-slate-700 whitespace-nowrap">年度累计</th>' ;
for ( var mi = 0 ; mi < 12 ; mi ++ ) { thead += '<th class="py-2 text-right font-semibold text-slate-600 whitespace-nowrap">' + mLbl [ mi ] + '</th>' ; }
thead += '</tr>' ;
var tbody = '' ;
for ( var ri = 0 ; ri < 5 ; ri ++ ) {
for ( var ri = 0 ; ri < 7 ; ri ++ ) {
var rowHtml = '<tr class="border-b border-slate-100 last:border-0"><td class="py-2 text-left font-semibold text-slate-700 whitespace-nowrap">' + LABELS [ ri ] + '</td>' ;
rowHtml += '<td class="py-2 text-right font-semibold text-slate-800 whitespace-nowrap">' + moneyIntL ( annualVals [ ri ] ) + '</td>' ;
for ( var mi = 0 ; mi < 12 ; mi ++ ) {
var val = 0 ;
if ( fm [ mi ] ) {
var fk = fmFields [ r i] ; if ( fk ) val = fm [ mi ] [ fk ] || 0 ;
if ( ri === 6 ) { val = ( fm [ m i] . payment || 0 ) - ( fm [ mi ] . paid || 0 ) ; }
else { var fk = fmFields [ ri ] ; if ( fk ) val = fm [ mi ] [ fk ] || 0 ; }
}
var cls = 'text-slate-700' ;
if ( ri === 6 ) cls = val >= 0 ? 'text-green-600' : 'text-red-600' ;
rowHtml += '<td class="py-2 text-right text-sm whitespace-nowrap ' + cls + '">' + moneyIntL ( val ) + '</td>' ;
}
tbody += rowHtml + '</tr>' ;
@@ -1007,7 +1008,7 @@ function renderFinanceOverview() {
var blCfAnnual = cfAnnual - expPaidAnnual ;
var cfRows = [
{ label : '项目现金流' , vals : cfMonthly , annual : cfAnnual } ,
{ label : '平台费用(已付 ) ' , vals : expPaidMonthly , annual : expPaidAnnual } ,
{ label : '平台费用(支出 ) ' , vals : expPaidMonthly , annual : expPaidAnnual } ,
{ label : '业务线现金流' , vals : blCfMonthly , annual : blCfAnnual }
] ;
var cfTbody = '' ;
@@ -1024,16 +1025,16 @@ function renderFinanceOverview() {
}
cfTbody += cfRowHtml + '</tr>' ;
}
var cfCard = card ( '<h3 class="text-sm font-bold text-slate-700">业务线现金流</h3><p class="text-xs text-slate-400 mb-3">项目现金流 - 平台费用(已付 ) = 业务线现金流</p><div class="overflow-x-auto"><table class="w-full text-sm"><thead>' + deptThead + '</thead><tbody>' + cfTbody + '</tbody></table></div>' , 'p-4' ) ;
var cfCard = card ( '<h3 class="text-sm font-bold text-slate-700">业务线现金流</h3><p class="text-xs text-slate-400 mb-3">项目现金流 - 平台费用(支出 ) = 业务线现金流</p><div class="overflow-x-auto"><table class="w-full text-sm"><thead>' + deptThead + '</thead><tbody>' + cfTbody + '</tbody></table></div>' , 'p-4' ) ;
document . querySelector ( "#financeOverview" ) . innerHTML = '<div class="grid gap-5">' +
card ( '<h3 class="text-sm font-bold text-slate-700">业务(项目)财务月度概览</h3><p class="text-xs text-slate-400 mb-3">合同 → 确收 → 毛利 → 成本 → 已付 </p><div class="overflow-x-auto"><table class="w-full text-sm"><thead>' + thead + '</thead><tbody>' + tbody + '</tbody></table></div>' , 'p-4' ) +
card ( '<h3 class="text-sm font-bold text-slate-700">业务(项目)财务月度概览</h3><p class="text-xs text-slate-400 mb-3">合同 → 确收 → 毛利 → 成本 → 支出 </p><div class="overflow-x-auto"><table class="w-full text-sm"><thead>' + thead + '</thead><tbody>' + tbody + '</tbody></table></div>' , 'p-4' ) +
deptCard +
cfCard +
'<div class="grid grid-cols-3 gap-5">' +
card ( '<div class="mb-3 flex items-center justify-between"><h2 class="text-sm font-bold text-slate-600">月度签约趋势</h2><span class="text-xs text-slate-400">2026</span></div><div style="position:relative;height:200px"><canvas id="finChartSign"></canvas></div>' , 'p-4' ) +
card ( '<div class="mb-3 flex items-center justify-between"><h2 class="text-sm font-bold text-slate-600">月度确收与毛利</h2><span class="text-xs text-slate-400">2026</span></div><div style="position:relative;height:200px"><canvas id="finChartRev"></canvas></div>' , 'p-4' ) +
card ( '<div class="mb-3 flex items-center justify-between"><h2 class="text-sm font-bold text-slate-600">月度回款与已付 </h2><span class="text-xs text-slate-400">2026</span></div><div style="position:relative;height:200px"><canvas id="finChartCash"></canvas></div>' , 'p-4' ) +
card ( '<div class="mb-3 flex items-center justify-between"><h2 class="text-sm font-bold text-slate-600">月度回款与支出 </h2><span class="text-xs text-slate-400">2026</span></div><div style="position:relative;height:200px"><canvas id="finChartCash"></canvas></div>' , 'p-4' ) +
'</div></div>' ;
if ( window . lucide ) window . lucide . createIcons ( ) ;
@@ -1042,7 +1043,7 @@ function renderFinanceOverview() {
}
}
// 季度总览 渲染
// 季度月报 渲染
function renderFinanceQuarterlyOverview ( ) {
const { summary , financeMonthly } = state . data ;
if ( ! summary ) return ;
@@ -1050,7 +1051,7 @@ function renderFinanceQuarterlyOverview() {
const moneyIntL = ( v ) => Math . round ( Number ( v || 0 ) ) . toLocaleString ( "zh-CN" ) ;
const card = ( body , cls ) => '<div class="card ' + ( cls || 'p-4' ) + '">' + body + '</div>' ;
const fm = financeMonthly || [ ] ;
const LABELS = [ '合同金额' , '确收金额' , '确收毛利' , '成本' , '已付 ' ] ;
const LABELS = [ '合同金额' , '确收金额' , '确收毛利' , '成本' , '支出 ' ] ;
const qLbl = [ 'Q1' , 'Q2' , 'Q3' , 'Q4' ] ;
const qRanges = [ [ 0 , 1 , 2 ] , [ 3 , 4 , 5 ] , [ 6 , 7 , 8 ] , [ 9 , 10 , 11 ] ] ;
const annualVals = [ m . signed _annual || m . signed _amount || 0 , m . revenue _annual || 0 , m . gross _annual || 0 , m . cost _annual || 0 , m . paid _annual || 0 ] ;
@@ -1088,7 +1089,7 @@ function renderFinanceQuarterlyOverview() {
tbody += rowHtml + '</tr>' ;
}
document . querySelector ( "#financeQuarterlyOverview" ) . innerHTML = '<div class="grid gap-5">' +
card ( '<h3 class="text-sm font-bold text-slate-700">业务(项目)财务季度概览</h3><p class="text-xs text-slate-400 mb-3">合同 → 确收 → 毛利 → 成本 → 项目利润 → 回款 → 已付 → 现金流</p><div class="overflow-x-auto"><table class="w-full text-sm"><thead>' + thead + '</thead><tbody>' + tbody + '</tbody></table></div>' , 'p-4' ) +
card ( '<h3 class="text-sm font-bold text-slate-700">业务(项目)财务季度概览</h3><p class="text-xs text-slate-400 mb-3">合同 → 确收 → 毛利 → 成本 → 项目利润 → 回款 → 支出 → 现金流</p><div class="overflow-x-auto"><table class="w-full text-sm"><thead>' + thead + '</thead><tbody>' + tbody + '</tbody></table></div>' , 'p-4' ) +
'</div>' ;
if ( window . lucide ) window . lucide . createIcons ( ) ;
}
@@ -1112,7 +1113,7 @@ function renderOverviewCharts(data) {
var c3 = document . querySelector ( "#finChartCash" ) ;
if ( c3 && window . Chart ) {
if ( state . finChart3 ) state . finChart3 . destroy ( ) ;
state . finChart3 = new Chart ( c3 , Object . assign ( { } , iconf , { data : { labels : labels , datasets : [ { label : "回款" , data : data . map ( function ( x ) { return x . payment || 0 ; } ) , borderColor : "#d97706" , backgroundColor : "rgba(217,119,6,0.06)" , fill : true , tension : 0.3 } , { label : "已付 " , data : data . map ( function ( x ) { return x . cost || 0 ; } ) , borderColor : "#7c3aed" , backgroundColor : "rgba(124,58,237,0.06)" , fill : true , tension : 0.3 } ] } } ) ) ;
state . finChart3 = new Chart ( c3 , Object . assign ( { } , iconf , { data : { labels : labels , datasets : [ { label : "回款" , data : data . map ( function ( x ) { return x . payment || 0 ; } ) , borderColor : "#d97706" , backgroundColor : "rgba(217,119,6,0.06)" , fill : true , tension : 0.3 } , { label : "支出 " , data : data . map ( function ( x ) { return x . cost || 0 ; } ) , borderColor : "#7c3aed" , backgroundColor : "rgba(124,58,237,0.06)" , fill : true , tension : 0.3 } ] } } ) ) ;
}
var c4 = document . querySelector ( "#finChartProfit" ) ;
if ( c4 && window . Chart ) {