Files
ONE-OS/web端/数据分析/业务部业绩明细.jsx
王冕 e1ac94bacf feat(web): 车辆租赁合同合同审批类型、法务上传盖章合同;新增数据分析页面;交车任务查看调整
- 租赁合同列表:合同审批类型筛选与列、需求说明;审批通过且未上传盖章件时法务可更多上传
- 新增/续签/转正式/查看等页同步合同审批类型及需求说明
- 新增数据分析:业务部业绩明细、物流业务月度统计、租赁客户氢费台账、租赁车辆收入明细
- 查看交车任务页面更新

Made-with: Cursor
2026-03-25 15:50:31 +08:00

813 lines
32 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 【重要】必须使用 const Component 作为组件变量名
// 数据分析 - 业务部业绩(明细 + 业绩/成本/利润汇总 Tab
// 明细:进入页面默认统计「上一自然月」;跨月后重新进入或刷新页面,默认月份随系统日期更新为上一个月。
const Component = function () {
var useState = React.useState;
var useMemo = React.useMemo;
var useCallback = React.useCallback;
var antd = window.antd;
var App = antd.App;
var Breadcrumb = antd.Breadcrumb;
var Card = antd.Card;
var Button = antd.Button;
var Table = antd.Table;
var Select = antd.Select;
var DatePicker = antd.DatePicker;
var Row = antd.Row;
var Col = antd.Col;
var Tabs = antd.Tabs;
var Space = antd.Space;
var message = antd.message;
var TableSummary = Table.Summary;
var SummaryRow = TableSummary.Row;
var SummaryCell = TableSummary.Cell;
function filterOption(input, option) {
var label = (option && (option.label || option.children)) || '';
return String(label).toLowerCase().indexOf(String(input || '').toLowerCase()) >= 0;
}
/** 表格正文:千分位 + 两位小数;空或 0 显示 -(利润等可为负,仍正常显示) */
function fmtCell(n) {
if (n === null || n === undefined || n === '') return '-';
var x = Number(n);
if (isNaN(x)) return '-';
if (x === 0) return '-';
return x.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}
/** 总计行 */
function fmtSum(n) {
var x = Number(n);
if (isNaN(x)) return '-';
return x.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 6 });
}
function escapeCsv(v) {
var s = v == null ? '' : String(v);
if (s.indexOf(',') !== -1 || s.indexOf('"') !== -1 || s.indexOf('\n') !== -1 || s.indexOf('\r') !== -1) {
return '"' + s.replace(/"/g, '""') + '"';
}
return s;
}
function downloadCsv(filename, lines) {
var csv = lines.map(function (row) { return row.map(escapeCsv).join(','); }).join('\n');
var blob = new Blob(['\ufeff' + csv], { type: 'text/csv;charset=utf-8' });
var url = URL.createObjectURL(blob);
var a = document.createElement('a');
a.href = url;
a.download = filename;
a.click();
URL.revokeObjectURL(url);
}
/** 统计月份键 YYYY-MM上一自然月每月初「上月」随系统日期变化刷新/重新进入页面即更新) */
function getLastMonthStatKey() {
try {
if (window.dayjs) return window.dayjs().subtract(1, 'month').format('YYYY-MM');
} catch (e1) {}
var d = new Date();
d.setDate(1);
d.setMonth(d.getMonth() - 1);
var y = d.getFullYear();
var mo = d.getMonth() + 1;
return y + '-' + (mo < 10 ? '0' + mo : '' + mo);
}
/** 月份选择器默认值(与 getLastMonthStatKey 同一自然月) */
function getLastMonthPickerValue() {
try {
if (window.dayjs) return window.dayjs().subtract(1, 'month').startOf('month');
} catch (e1) {}
try {
if (window.moment) return window.moment().subtract(1, 'month').startOf('month');
} catch (e2) {}
return null;
}
var layoutStyle = { padding: '16px 24px', background: '#f5f5f5', minHeight: '100vh' };
var filterLabelStyle = { marginBottom: 6, fontSize: 14, color: 'rgba(0,0,0,0.65)' };
var filterItemStyle = { marginBottom: 12 };
var filterControlStyle = { width: '100%' };
/** 与筛选项同一行时,将操作列推到右侧 */
var filterActionsColStyle = { flex: '0 0 auto', marginLeft: 'auto' };
var tableSingleLineStyle =
'.biz-dept-perf-table .ant-table-thead th,.biz-dept-perf-table .ant-table-tbody td,.biz-dept-perf-table .ant-table-summary td{white-space:nowrap;}';
var tabsBarStyle = '.biz-dept-perf-tabs .ant-tabs-nav{margin-bottom:0;}';
var monthlyMetricKeys = ['logistics', 'lease', 'sales', 'hydrogen', 'electricity', 'etc', 'other', 'total'];
function sumMonthlyRows(rows, keys) {
var sums = {};
keys.forEach(function (k) {
sums[k] = (rows || []).reduce(function (acc, row) {
var v = row[k];
var n = v === null || v === undefined || v === '' ? 0 : Number(v);
return acc + (isNaN(n) ? 0 : n);
}, 0);
});
return sums;
}
function monthlyColumnsFor(suffix) {
if (suffix === '业绩') {
return [
{ title: '月份', dataIndex: 'month', key: 'month', width: 72, align: 'center' },
{ title: '物流业绩', dataIndex: 'logistics', key: 'logistics', width: 120, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: '租赁业绩', dataIndex: 'lease', key: 'lease', width: 120, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: '销售业绩', dataIndex: 'sales', key: 'sales', width: 120, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: '氢费业绩', dataIndex: 'hydrogen', key: 'hydrogen', width: 120, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: '电费业绩', dataIndex: 'electricity', key: 'electricity', width: 120, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: 'ETC业绩', dataIndex: 'etc', key: 'etc', width: 110, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: '其他', dataIndex: 'other', key: 'other', width: 110, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: '合计', dataIndex: 'total', key: 'total', width: 120, align: 'center', render: function (v) { return fmtCell(v); } }
];
}
if (suffix === '成本') {
return [
{ title: '月份', dataIndex: 'month', key: 'month', width: 72, align: 'center' },
{ title: '物流成本', dataIndex: 'logistics', key: 'logistics', width: 120, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: '租赁成本', dataIndex: 'lease', key: 'lease', width: 120, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: '销售成本', dataIndex: 'sales', key: 'sales', width: 120, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: '氢费成本', dataIndex: 'hydrogen', key: 'hydrogen', width: 120, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: '电费成本', dataIndex: 'electricity', key: 'electricity', width: 120, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: 'ETC成本', dataIndex: 'etc', key: 'etc', width: 110, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: '其他', dataIndex: 'other', key: 'other', width: 110, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: '合计', dataIndex: 'total', key: 'total', width: 120, align: 'center', render: function (v) { return fmtCell(v); } }
];
}
return [
{ title: '月份', dataIndex: 'month', key: 'month', width: 72, align: 'center' },
{ title: '物流利润', dataIndex: 'logistics', key: 'logistics', width: 120, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: '租赁利润', dataIndex: 'lease', key: 'lease', width: 120, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: '销售利润', dataIndex: 'sales', key: 'sales', width: 120, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: '氢费利润', dataIndex: 'hydrogen', key: 'hydrogen', width: 120, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: '电费利润', dataIndex: 'electricity', key: 'electricity', width: 120, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: 'ETC利润', dataIndex: 'etc', key: 'etc', width: 110, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: '其他', dataIndex: 'other', key: 'other', width: 110, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: '合计', dataIndex: 'total', key: 'total', width: 120, align: 'center', render: function (v) { return fmtCell(v); } }
];
}
function rowTotal(r) {
var keys = ['logistics', 'lease', 'sales', 'hydrogen', 'electricity', 'etc', 'other'];
var s = 0;
var any = false;
keys.forEach(function (k) {
var v = r[k];
if (v === null || v === undefined || v === '') return;
var n = Number(v);
if (isNaN(n)) return;
any = true;
s += n;
});
return any ? s : null;
}
function finalizeMonthlyRow(r) {
var t = r.total != null && r.total !== '' ? r.total : rowTotal(r);
return Object.assign({}, r, { total: t });
}
/** 原型2026 年按月业绩汇总 */
var monthlyPerf2026 = useMemo(function () {
var raw = [
{ month: 1, logistics: 1005557.94, lease: 4004.73, sales: 1495355.18, hydrogen: null, electricity: 88200.5, etc: 12000, other: 5000, total: null },
{ month: 2, logistics: 250000, lease: 180000, sales: null, hydrogen: 3200, electricity: null, etc: null, other: null, total: null },
{ month: 3, logistics: 180000, lease: 95000, sales: 220000, hydrogen: null, electricity: 45000, etc: 8000, other: 1200, total: null },
{ month: 4, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 5, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 6, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 7, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 8, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 9, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 10, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 11, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 12, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null }
];
return raw.map(function (x) {
return finalizeMonthlyRow(Object.assign({ key: 'perf-' + x.month }, x));
});
}, []);
/** 原型2026 年按月成本汇总 */
var monthlyCost2026 = useMemo(function () {
var raw = [
{ month: 1, logistics: 1167787.05, lease: 320000, sales: 980000, hydrogen: 15000, electricity: 72000, etc: 9800, other: 2400, total: null },
{ month: 2, logistics: 210000, lease: 165000, sales: null, hydrogen: 2800, electricity: null, etc: null, other: null, total: null },
{ month: 3, logistics: 155000, lease: 88000, sales: 195000, hydrogen: null, electricity: 38000, etc: 6500, other: 800, total: null },
{ month: 4, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 5, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 6, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 7, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 8, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 9, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 10, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 11, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 12, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null }
];
return raw.map(function (x) {
return finalizeMonthlyRow(Object.assign({ key: 'cost-' + x.month }, x));
});
}, []);
/** 原型2026 年按月利润汇总(可为负) */
var monthlyProfit2026 = useMemo(function () {
var raw = [
{ month: 1, logistics: -162229.11, lease: 45000, sales: null, hydrogen: -1200.5, electricity: 6200, etc: null, other: 800, total: null },
{ month: 2, logistics: null, lease: 15000, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 3, logistics: null, lease: 7000, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 4, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 5, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 6, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 7, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 8, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 9, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 10, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 11, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null },
{ month: 12, logistics: null, lease: null, sales: null, hydrogen: null, electricity: null, etc: null, other: null, total: null }
];
return raw.map(function (x) {
return finalizeMonthlyRow(Object.assign({ key: 'profit-' + x.month }, x));
});
}, []);
var deptOptions = useMemo(function () {
return [
{ value: '华东业务部', label: '华东业务部' },
{ value: '华南业务部', label: '华南业务部' },
{ value: '华北业务部', label: '华北业务部' },
{ value: '西南业务部', label: '西南业务部' }
];
}, []);
var salespersonOptions = useMemo(function () {
return [
{ value: '尚建华', label: '尚建华' },
{ value: '刘念念', label: '刘念念' },
{ value: '谯云', label: '谯云' },
{ value: '董剑煜', label: '董剑煜' }
];
}, []);
var lastMonthStatKey = useMemo(function () {
return getLastMonthStatKey();
}, []);
var allRows = useMemo(function () {
var sm = lastMonthStatKey;
return [
{
key: '1',
statMonth: sm,
salesperson: '尚建华',
dept: '华东业务部',
logistics: 208868.38,
lease: 36000,
sales: null,
hydrogen: null,
electricity: null,
etc: null,
other: 55950.23,
total: 300818.61
},
{
key: '2',
statMonth: sm,
salesperson: '刘念念',
dept: '华南业务部',
logistics: 397181.78,
lease: 223800,
sales: 120000,
hydrogen: 4500.12,
electricity: 25000,
etc: null,
other: 224.14,
total: 770706.04
},
{
key: '3',
statMonth: sm,
salesperson: '谯云',
dept: '华东业务部',
logistics: 391153.33,
lease: 15000,
sales: null,
hydrogen: null,
electricity: null,
etc: 8665.43,
other: null,
total: 414818.76
},
{
key: '4',
statMonth: sm,
salesperson: '董剑煜',
dept: '西南业务部',
logistics: 8354.46,
lease: null,
sales: null,
hydrogen: null,
electricity: null,
etc: null,
other: 657.3,
total: 9011.76
}
];
}, [lastMonthStatKey]);
var mainTabState = useState('detail');
var mainTab = mainTabState[0];
var setMainTab = mainTabState[1];
var draftState = useState(function () {
return {
month: getLastMonthPickerValue(),
dept: undefined,
salesperson: undefined
};
});
var draft = draftState[0];
var setDraft = draftState[1];
var appliedState = useState(function () {
return {
month: getLastMonthPickerValue(),
dept: undefined,
salesperson: undefined
};
});
var applied = appliedState[0];
var setApplied = appliedState[1];
function initialYear2026() {
try {
if (window.dayjs) return window.dayjs('2026-01-01');
} catch (e1) {}
return null;
}
var summaryYearDraftState = useState(initialYear2026);
var summaryYearDraft = summaryYearDraftState[0];
var setSummaryYearDraft = summaryYearDraftState[1];
var summaryYearAppliedState = useState(initialYear2026);
var summaryYearApplied = summaryYearAppliedState[0];
var setSummaryYearApplied = summaryYearAppliedState[1];
var filteredRows = useMemo(function () {
return (allRows || []).filter(function (r) {
if (applied.month && applied.month.format) {
var mk = applied.month.format('YYYY-MM');
if (r.statMonth !== mk) return false;
}
if (applied.dept && r.dept !== applied.dept) return false;
if (applied.salesperson && r.salesperson !== applied.salesperson) return false;
return true;
});
}, [allRows, applied.month, applied.dept, applied.salesperson]);
var metricKeys = useMemo(function () {
return ['logistics', 'lease', 'sales', 'hydrogen', 'electricity', 'etc', 'other', 'total'];
}, []);
var columnSums = useMemo(function () {
var sums = {};
metricKeys.forEach(function (k) {
sums[k] = filteredRows.reduce(function (acc, row) {
var v = row[k];
var n = v === null || v === undefined || v === '' ? 0 : Number(v);
return acc + (isNaN(n) ? 0 : n);
}, 0);
});
return sums;
}, [filteredRows, metricKeys]);
var bizReportTableTitleStyle = {
textAlign: 'center',
marginBottom: 16,
fontSize: 16,
fontWeight: 600,
color: 'rgba(0,0,0,0.88)'
};
/** 与「查询」后已选月份一致x年x月业绩明细表 */
var detailTableTitle = useMemo(function () {
if (applied.month && applied.month.format) {
var y = applied.month.format('YYYY');
var m = applied.month.format('M');
return y + '年' + m + '月业绩明细表';
}
return '业绩明细表';
}, [applied.month]);
/** 与汇总 Tab「查询」后已选年份一致 */
var perfSumTableTitle = useMemo(function () {
if (summaryYearApplied && summaryYearApplied.format) {
return summaryYearApplied.format('YYYY') + '年业绩汇总';
}
return '业绩汇总';
}, [summaryYearApplied]);
var costSumTableTitle = useMemo(function () {
if (summaryYearApplied && summaryYearApplied.format) {
return summaryYearApplied.format('YYYY') + '年成本汇总';
}
return '成本汇总';
}, [summaryYearApplied]);
var profitSumTableTitle = useMemo(function () {
if (summaryYearApplied && summaryYearApplied.format) {
return summaryYearApplied.format('YYYY') + '年利润汇总';
}
return '利润汇总';
}, [summaryYearApplied]);
var monthlyDataSource = useCallback(function (rows) {
var y = summaryYearApplied && summaryYearApplied.format ? summaryYearApplied.format('YYYY') : null;
if (!y) return [];
if (y !== '2026') return [];
return rows;
}, [summaryYearApplied]);
var perfMonthlyRows = useMemo(function () { return monthlyDataSource(monthlyPerf2026); }, [monthlyDataSource, monthlyPerf2026]);
var costMonthlyRows = useMemo(function () { return monthlyDataSource(monthlyCost2026); }, [monthlyDataSource, monthlyCost2026]);
var profitMonthlyRows = useMemo(function () { return monthlyDataSource(monthlyProfit2026); }, [monthlyDataSource, monthlyProfit2026]);
var perfMonthlySums = useMemo(function () { return sumMonthlyRows(perfMonthlyRows, monthlyMetricKeys); }, [perfMonthlyRows]);
var costMonthlySums = useMemo(function () { return sumMonthlyRows(costMonthlyRows, monthlyMetricKeys); }, [costMonthlyRows]);
var profitMonthlySums = useMemo(function () { return sumMonthlyRows(profitMonthlyRows, monthlyMetricKeys); }, [profitMonthlyRows]);
var handleQuery = useCallback(function () {
setApplied(Object.assign({}, draft));
}, [draft]);
var handleReset = useCallback(function () {
var def = { month: getLastMonthPickerValue(), dept: undefined, salesperson: undefined };
setDraft(def);
setApplied(def);
}, []);
var handleSummaryQuery = useCallback(function () {
setSummaryYearApplied(summaryYearDraft);
}, [summaryYearDraft]);
var handleSummaryReset = useCallback(function () {
var y0 = initialYear2026();
setSummaryYearDraft(y0);
setSummaryYearApplied(y0);
}, []);
var handleExportDetail = useCallback(function () {
var rows = filteredRows;
if (!rows || rows.length === 0) {
message.warning('当前无数据可导出');
return;
}
var headers = [
'业务员',
'物流业绩',
'租赁业绩',
'销售业绩',
'氢费业绩',
'电费业绩',
'ETC业绩',
'其他',
'合计'
];
var body = [headers].concat(
rows.map(function (r) {
return [
r.salesperson,
fmtCell(r.logistics),
fmtCell(r.lease),
fmtCell(r.sales),
fmtCell(r.hydrogen),
fmtCell(r.electricity),
fmtCell(r.etc),
fmtCell(r.other),
fmtCell(r.total)
];
})
);
body.push(['总计'].concat(metricKeys.map(function (k) { return fmtSum(columnSums[k] || 0); })));
downloadCsv('业绩明细_' + new Date().getTime() + '.csv', body);
message.success('已导出 ' + rows.length + ' 条记录');
}, [filteredRows, metricKeys, columnSums]);
var exportMonthly = useCallback(function (rows, sums, headerTitles, filePrefix) {
if (!rows || rows.length === 0) {
message.warning('当前无数据可导出,请先选择年份并查询');
return;
}
var body = [headerTitles].concat(
rows.map(function (r) {
return [
String(r.month),
fmtCell(r.logistics),
fmtCell(r.lease),
fmtCell(r.sales),
fmtCell(r.hydrogen),
fmtCell(r.electricity),
fmtCell(r.etc),
fmtCell(r.other),
fmtCell(r.total)
];
})
);
body.push(['总计'].concat(monthlyMetricKeys.map(function (k) { return fmtSum(sums[k] || 0); })));
downloadCsv(filePrefix + '_' + new Date().getTime() + '.csv', body);
message.success('已导出 ' + rows.length + ' 个月度数据');
}, []);
var handleExportPerfMonthly = useCallback(function () {
exportMonthly(
perfMonthlyRows,
perfMonthlySums,
['月份', '物流业绩', '租赁业绩', '销售业绩', '氢费业绩', '电费业绩', 'ETC业绩', '其他', '合计'],
'业绩汇总'
);
}, [exportMonthly, perfMonthlyRows, perfMonthlySums]);
var handleExportCostMonthly = useCallback(function () {
exportMonthly(
costMonthlyRows,
costMonthlySums,
['月份', '物流成本', '租赁成本', '销售成本', '氢费成本', '电费成本', 'ETC成本', '其他', '合计'],
'成本汇总'
);
}, [exportMonthly, costMonthlyRows, costMonthlySums]);
var handleExportProfitMonthly = useCallback(function () {
exportMonthly(
profitMonthlyRows,
profitMonthlySums,
['月份', '物流利润', '租赁利润', '销售利润', '氢费利润', '电费利润', 'ETC利润', '其他', '合计'],
'利润汇总'
);
}, [exportMonthly, profitMonthlyRows, profitMonthlySums]);
var columns = useMemo(function () {
return [
{ title: '业务员', dataIndex: 'salesperson', key: 'salesperson', width: 110, align: 'center' },
{ title: '物流业绩', dataIndex: 'logistics', key: 'logistics', width: 130, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: '租赁业绩', dataIndex: 'lease', key: 'lease', width: 130, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: '销售业绩', dataIndex: 'sales', key: 'sales', width: 130, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: '氢费业绩', dataIndex: 'hydrogen', key: 'hydrogen', width: 130, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: '电费业绩', dataIndex: 'electricity', key: 'electricity', width: 140, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: 'ETC业绩', dataIndex: 'etc', key: 'etc', width: 120, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: '其他', dataIndex: 'other', key: 'other', width: 120, align: 'center', render: function (v) { return fmtCell(v); } },
{ title: '合计', dataIndex: 'total', key: 'total', width: 130, align: 'center', render: function (v) { return fmtCell(v); } }
];
}, []);
var tableSummary = useCallback(function () {
return React.createElement(
TableSummary,
null,
React.createElement(
SummaryRow,
null,
React.createElement(SummaryCell, { index: 0, align: 'center' }, '总计'),
metricKeys.map(function (k, idx) {
return React.createElement(
SummaryCell,
{ key: k, index: idx + 1, align: 'center' },
fmtSum(columnSums[k] || 0)
);
})
)
);
}, [metricKeys, columnSums]);
function renderMonthlySummary(sums) {
return function () {
return React.createElement(
TableSummary,
null,
React.createElement(
SummaryRow,
null,
React.createElement(SummaryCell, { index: 0, align: 'center' }, '总计'),
monthlyMetricKeys.map(function (k, idx) {
return React.createElement(
SummaryCell,
{ key: k, index: idx + 1, align: 'center' },
fmtSum(sums[k] || 0)
);
})
)
);
};
}
var columnsPerfMonthly = useMemo(function () { return monthlyColumnsFor('业绩'); }, []);
var columnsCostMonthly = useMemo(function () { return monthlyColumnsFor('成本'); }, []);
var columnsProfitMonthly = useMemo(function () { return monthlyColumnsFor('利润'); }, []);
var renderYearFilterCard = useCallback(function () {
return React.createElement(Card, { style: { marginBottom: 16 } },
React.createElement(Row, { gutter: [16, 16], align: 'bottom' },
React.createElement(Col, { xs: 24, sm: 12, md: 8, lg: 6 },
React.createElement('div', { style: filterItemStyle },
React.createElement('div', { style: filterLabelStyle }, '选择年份'),
React.createElement(DatePicker, {
picker: 'year',
style: filterControlStyle,
placeholder: '请选择统计年份',
format: 'YYYY',
value: summaryYearDraft,
onChange: function (v) { setSummaryYearDraft(v); }
})
)
),
React.createElement(Col, { xs: 24, sm: 12, md: 8, lg: 6, style: filterActionsColStyle },
React.createElement('div', { style: filterItemStyle },
React.createElement('div', { style: filterLabelStyle }, '\u00a0'),
React.createElement(Space, { size: 8, wrap: true },
React.createElement(Button, { onClick: handleSummaryReset }, '重置'),
React.createElement(Button, { type: 'primary', onClick: handleSummaryQuery }, '查询')
)
)
)
)
);
}, [summaryYearDraft, handleSummaryReset, handleSummaryQuery]);
var tabItems = [
{
key: 'detail',
label: '业绩明细',
children: React.createElement(React.Fragment, null,
React.createElement(Card, { style: { marginBottom: 16 } },
React.createElement(Row, { gutter: [16, 16], align: 'bottom' },
React.createElement(Col, { xs: 24, sm: 12, md: 8, lg: 6 },
React.createElement('div', { style: filterItemStyle },
React.createElement('div', { style: filterLabelStyle }, '选择月份'),
React.createElement(DatePicker, {
picker: 'month',
style: filterControlStyle,
placeholder: '选择器选择月份',
format: 'YYYY-MM',
value: draft.month,
onChange: function (v) { setDraft(function (p) { return Object.assign({}, p, { month: v }); }); }
})
)
),
React.createElement(Col, { xs: 24, sm: 12, md: 8, lg: 6 },
React.createElement('div', { style: filterItemStyle },
React.createElement('div', { style: filterLabelStyle }, '选择业务部门'),
React.createElement(Select, {
placeholder: '选择器选择业务部门',
style: filterControlStyle,
allowClear: true,
options: deptOptions,
value: draft.dept,
onChange: function (v) { setDraft(function (p) { return Object.assign({}, p, { dept: v }); }); },
showSearch: true,
filterOption: filterOption
})
)
),
React.createElement(Col, { xs: 24, sm: 12, md: 8, lg: 6 },
React.createElement('div', { style: filterItemStyle },
React.createElement('div', { style: filterLabelStyle }, '选择业务员'),
React.createElement(Select, {
placeholder: '选择器选择业务员',
style: filterControlStyle,
allowClear: true,
options: salespersonOptions,
value: draft.salesperson,
onChange: function (v) { setDraft(function (p) { return Object.assign({}, p, { salesperson: v }); }); },
showSearch: true,
filterOption: filterOption
})
)
),
React.createElement(Col, { xs: 24, sm: 12, md: 8, lg: 6, style: filterActionsColStyle },
React.createElement('div', { style: filterItemStyle },
React.createElement('div', { style: filterLabelStyle }, '\u00a0'),
React.createElement(Space, { size: 8, wrap: true },
React.createElement(Button, { onClick: handleReset }, '重置'),
React.createElement(Button, { type: 'primary', onClick: handleQuery }, '查询')
)
)
)
)
),
React.createElement(Card, {
extra: React.createElement(Button, { onClick: handleExportDetail }, '导出')
},
React.createElement('div', { style: bizReportTableTitleStyle }, detailTableTitle),
React.createElement('style', null, tableSingleLineStyle),
React.createElement('div', { className: 'biz-dept-perf-table' },
React.createElement(Table, {
rowKey: 'key',
columns: columns,
dataSource: filteredRows,
pagination: false,
size: 'small',
summary: tableSummary,
scroll: { x: 1200 }
})
)
)
)
},
{
key: 'perfSum',
label: '业绩汇总',
children: React.createElement(React.Fragment, null,
renderYearFilterCard(),
React.createElement(Card, {
extra: React.createElement(Button, { onClick: handleExportPerfMonthly }, '导出')
},
React.createElement('div', { style: bizReportTableTitleStyle }, perfSumTableTitle),
React.createElement('style', null, tableSingleLineStyle),
React.createElement('div', { className: 'biz-dept-perf-table' },
React.createElement(Table, {
rowKey: 'key',
columns: columnsPerfMonthly,
dataSource: perfMonthlyRows,
pagination: false,
size: 'small',
summary: renderMonthlySummary(perfMonthlySums),
scroll: { x: 1180 }
})
)
)
)
},
{
key: 'costSum',
label: '成本汇总',
children: React.createElement(React.Fragment, null,
renderYearFilterCard(),
React.createElement(Card, {
extra: React.createElement(Button, { onClick: handleExportCostMonthly }, '导出')
},
React.createElement('div', { style: bizReportTableTitleStyle }, costSumTableTitle),
React.createElement('style', null, tableSingleLineStyle),
React.createElement('div', { className: 'biz-dept-perf-table' },
React.createElement(Table, {
rowKey: 'key',
columns: columnsCostMonthly,
dataSource: costMonthlyRows,
pagination: false,
size: 'small',
summary: renderMonthlySummary(costMonthlySums),
scroll: { x: 1180 }
})
)
)
)
},
{
key: 'profitSum',
label: '利润汇总',
children: React.createElement(React.Fragment, null,
renderYearFilterCard(),
React.createElement(Card, {
extra: React.createElement(Button, { onClick: handleExportProfitMonthly }, '导出')
},
React.createElement('div', { style: bizReportTableTitleStyle }, profitSumTableTitle),
React.createElement('style', null, tableSingleLineStyle),
React.createElement('div', { className: 'biz-dept-perf-table' },
React.createElement(Table, {
rowKey: 'key',
columns: columnsProfitMonthly,
dataSource: profitMonthlyRows,
pagination: false,
size: 'small',
summary: renderMonthlySummary(profitMonthlySums),
scroll: { x: 1180 }
})
)
)
)
}
];
return React.createElement(App, null,
React.createElement('div', { style: layoutStyle },
React.createElement(Breadcrumb, {
style: { marginBottom: 16 },
items: [{ title: '数据分析' }, { title: '业务部业绩' }]
}),
React.createElement(Card, null,
React.createElement('style', null, tabsBarStyle),
React.createElement(Tabs, {
className: 'biz-dept-perf-tabs',
activeKey: mainTab,
onChange: function (k) { setMainTab(k); },
items: tabItems
})
)
)
);
};