feat(web): 同步 web 端目录更新至 Gitea
包含加氢站站点信息、运维交车/故障、台账与数据分析等页面新增与改动。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
515
web端/台账数据/保险分摊明细.jsx
Normal file
515
web端/台账数据/保险分摊明细.jsx
Normal file
@@ -0,0 +1,515 @@
|
||||
// 【重要】必须使用 const Component 作为组件变量名
|
||||
// 台账数据 - 车辆保险台账(保险分摊明细)
|
||||
// 原型:客户名称 + 结算周期筛选、导出;日成本与分摊成本按业务公式计算(联调可替换为接口)
|
||||
|
||||
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 Space = antd.Space;
|
||||
var message = antd.message;
|
||||
|
||||
var CUSTOMER_OPTIONS = [
|
||||
{ value: '浙江羚牛氢能科技有限公司', label: '浙江羚牛氢能科技有限公司' },
|
||||
{ value: '杭州绿运物流有限公司', label: '杭州绿运物流有限公司' },
|
||||
{ value: '宁波港城新能源车队', label: '宁波港城新能源车队' },
|
||||
{ value: '绍兴氢能示范运营中心', label: '绍兴氢能示范运营中心' }
|
||||
];
|
||||
|
||||
var PROJECT_BY_CUSTOMER = {
|
||||
'浙江羚牛氢能科技有限公司': ['氢能重卡租赁一期', '园区通勤包车'],
|
||||
'杭州绿运物流有限公司': ['城配氢能车辆项目', '冷链专线'],
|
||||
'宁波港城新能源车队': ['港口短驳氢能车', '堆场转运'],
|
||||
'绍兴氢能示范运营中心': ['示范线路运营', '加氢站接驳']
|
||||
};
|
||||
|
||||
var PLATE_PREFIX = ['浙A', '浙B', '浙D', '浙G'];
|
||||
|
||||
function filterOption(input, option) {
|
||||
var label = (option && (option.label || option.children)) || '';
|
||||
return String(label).toLowerCase().indexOf(String(input || '').toLowerCase()) >= 0;
|
||||
}
|
||||
|
||||
function numOrZero(v) {
|
||||
if (v === null || v === undefined || v === '') return 0;
|
||||
var n = Number(v);
|
||||
return isNaN(n) ? 0 : n;
|
||||
}
|
||||
|
||||
function fmtMoney(n, digits) {
|
||||
if (n === null || n === undefined || n === '') return '-';
|
||||
var x = Number(n);
|
||||
if (isNaN(x)) return '-';
|
||||
var d = digits === undefined ? 2 : digits;
|
||||
return x.toLocaleString('zh-CN', { minimumFractionDigits: d, maximumFractionDigits: d });
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
function initialSettlementMonth() {
|
||||
try {
|
||||
if (window.dayjs) return window.dayjs('2026-05-01');
|
||||
} catch (e1) {}
|
||||
return null;
|
||||
}
|
||||
|
||||
function settlementYm(d) {
|
||||
if (!d || !window.dayjs) return '';
|
||||
try {
|
||||
return window.dayjs(d).format('YYYY-MM');
|
||||
} catch (e2) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/** 日成本 = 缴费金额 / 生效天数 */
|
||||
function dailyCost(payment, effectiveDays) {
|
||||
var pay = numOrZero(payment);
|
||||
var days = numOrZero(effectiveDays);
|
||||
if (days <= 0) return null;
|
||||
return Math.round((pay / days) * 10000) / 10000;
|
||||
}
|
||||
|
||||
/** 保险分摊成本 = Σ(各险日成本 × 分摊天数) */
|
||||
function calcApportionCost(row) {
|
||||
var d = numOrZero(row.apportionDays);
|
||||
if (d <= 0) return null;
|
||||
var sum = 0;
|
||||
var has = false;
|
||||
['compulsoryDaily', 'commercialDaily', 'excessDaily', 'cargoDaily'].forEach(function (k) {
|
||||
var v = row[k];
|
||||
if (v !== null && v !== undefined && !isNaN(Number(v))) {
|
||||
sum += Number(v) * d;
|
||||
has = true;
|
||||
}
|
||||
});
|
||||
if (!has) return null;
|
||||
return Math.round(sum * 100) / 100;
|
||||
}
|
||||
|
||||
function buildMockRows(ym) {
|
||||
var rows = [];
|
||||
var seed = 0;
|
||||
CUSTOMER_OPTIONS.forEach(function (cust, ci) {
|
||||
var projects = PROJECT_BY_CUSTOMER[cust.value] || ['默认项目'];
|
||||
projects.forEach(function (proj, pi) {
|
||||
seed += 1;
|
||||
var plate = PLATE_PREFIX[ci % PLATE_PREFIX.length] + String(10000 + seed).slice(-5) + 'F';
|
||||
var effDays = 365;
|
||||
var compulsoryPay = 950 + seed * 3;
|
||||
var commercialPay = 4200 + seed * 17;
|
||||
var excessPay = seed % 3 === 0 ? 1800 + seed * 5 : 0;
|
||||
var cargoPay = seed % 2 === 0 ? 600 + seed * 2 : 0;
|
||||
var apportionDays = 18 + ((seed + (ym ? ym.length : 0)) % 13);
|
||||
|
||||
var row = {
|
||||
key: 'r' + seed,
|
||||
seq: seed,
|
||||
settlementCycle: ym || '2026-05',
|
||||
customerName: cust.value,
|
||||
projectName: proj,
|
||||
plateNo: plate,
|
||||
compulsoryDaily: dailyCost(compulsoryPay, effDays),
|
||||
commercialDaily: dailyCost(commercialPay, effDays),
|
||||
excessDaily: excessPay > 0 ? dailyCost(excessPay, effDays) : null,
|
||||
cargoDaily: cargoPay > 0 ? dailyCost(cargoPay, effDays) : null,
|
||||
apportionDays: apportionDays
|
||||
};
|
||||
row.apportionCost = calcApportionCost(row);
|
||||
rows.push(row);
|
||||
});
|
||||
});
|
||||
return rows;
|
||||
}
|
||||
|
||||
|
||||
var layoutStyle = {
|
||||
padding: '16px 24px 24px',
|
||||
minHeight: '100vh',
|
||||
background: 'linear-gradient(165deg, #eef4ff 0%, #f5f7fa 42%, #f0f2f5 100%)'
|
||||
};
|
||||
var filterLabelStyle = { marginBottom: 6, fontSize: 13, color: 'rgba(0,0,0,0.55)', fontWeight: 500 };
|
||||
var filterItemStyle = { marginBottom: 12 };
|
||||
var filterControlStyle = { width: '100%' };
|
||||
var filterActionsColStyle = { flex: '0 0 auto', marginLeft: 'auto' };
|
||||
|
||||
var filterCardStyle = {
|
||||
marginBottom: 20,
|
||||
borderRadius: 16,
|
||||
boxShadow: '0 4px 20px -4px rgba(16,24,40,0.03), 0 0 0 1px rgba(16,24,40,0.06)',
|
||||
border: 'none',
|
||||
background: '#ffffff'
|
||||
};
|
||||
|
||||
var tableCardStyle = {
|
||||
borderRadius: 16,
|
||||
boxShadow: '0 10px 32px -4px rgba(16,24,40,0.06), 0 0 0 1px rgba(16,24,40,0.04)',
|
||||
border: 'none',
|
||||
background: '#ffffff',
|
||||
overflow: 'hidden'
|
||||
};
|
||||
|
||||
var ledgerTableStyle =
|
||||
'.ins-ledger-table-wrap{border-radius:12px;overflow:hidden;box-shadow:0 4px 24px -6px rgba(15,23,42,0.05),0 0 0 1px rgba(22,119,255,0.1)}' +
|
||||
'.ins-ledger-table .ant-table-thead>tr>th{white-space:nowrap;color:#1e293b!important;font-weight:600!important;font-size:13px!important;' +
|
||||
'background:#e8f4fc!important;border-bottom:1px solid #bae6fd!important;border-inline-end:1px solid #dbeafe!important;padding:0 8px!important;height:38px!important}' +
|
||||
'.ins-ledger-table .ant-table-tbody>tr:not(.ant-table-measure-row)>td{white-space:nowrap;font-variant-numeric:tabular-nums;color:#334155;border-bottom:1px solid #f1f5f9!important;border-inline-end:1px solid #f8fafc!important;padding:0 8px!important;height:38px!important}' +
|
||||
'.ins-ledger-table .ant-table-tbody>tr.ins-row-data:hover>td{background:#f0f9ff!important}' +
|
||||
'.ins-ledger-table .ant-table-summary>tr>td{font-weight:700;background:#f8fafc!important;color:#0f172a!important;border-top:2px solid #cbd5e1!important;padding:0 8px!important;height:38px!important}';
|
||||
|
||||
var customerDraftState = useState(undefined);
|
||||
var customerDraft = customerDraftState[0];
|
||||
var setCustomerDraft = customerDraftState[1];
|
||||
|
||||
var monthDraftState = useState(initialSettlementMonth);
|
||||
var monthDraft = monthDraftState[0];
|
||||
var setMonthDraft = monthDraftState[1];
|
||||
|
||||
var customerAppliedState = useState(undefined);
|
||||
var customerApplied = customerAppliedState[0];
|
||||
var setCustomerApplied = customerAppliedState[1];
|
||||
|
||||
var monthAppliedState = useState(initialSettlementMonth);
|
||||
var monthApplied = monthAppliedState[0];
|
||||
var setMonthApplied = monthAppliedState[1];
|
||||
|
||||
var appliedYm = useMemo(function () {
|
||||
return settlementYm(monthApplied) || '2026-05';
|
||||
}, [monthApplied]);
|
||||
|
||||
var allRows = useMemo(function () {
|
||||
return buildMockRows(appliedYm);
|
||||
}, [appliedYm]);
|
||||
|
||||
var dataSource = useMemo(function () {
|
||||
var list = allRows.filter(function (r) {
|
||||
if (customerApplied && r.customerName !== customerApplied) return false;
|
||||
return true;
|
||||
});
|
||||
return list.map(function (r, idx) {
|
||||
return Object.assign({}, r, { seq: idx + 1 });
|
||||
});
|
||||
}, [allRows, customerApplied]);
|
||||
|
||||
var totalApportionCost = useMemo(function () {
|
||||
return dataSource.reduce(function (acc, r) {
|
||||
return acc + numOrZero(r.apportionCost);
|
||||
}, 0);
|
||||
}, [dataSource]);
|
||||
|
||||
var customerDisplayLabel = customerApplied || '默认全量数据';
|
||||
var cycleDisplayLabel = appliedYm || '-';
|
||||
|
||||
var handleQuery = useCallback(function () {
|
||||
setCustomerApplied(customerDraft);
|
||||
setMonthApplied(monthDraft);
|
||||
message.success('查询成功');
|
||||
}, [customerDraft, monthDraft]);
|
||||
|
||||
var handleReset = useCallback(function () {
|
||||
setCustomerDraft(undefined);
|
||||
setMonthDraft(initialSettlementMonth());
|
||||
setCustomerApplied(undefined);
|
||||
setMonthApplied(initialSettlementMonth());
|
||||
}, []);
|
||||
|
||||
var handleExport = useCallback(function () {
|
||||
var headers = [
|
||||
'序号',
|
||||
'结算周期',
|
||||
'客户名称',
|
||||
'项目名称',
|
||||
'车牌号',
|
||||
'交强险日成本',
|
||||
'商业险日成本',
|
||||
'超赔险日成本',
|
||||
'货物险日成本',
|
||||
'分摊天数',
|
||||
'保险分摊成本'
|
||||
];
|
||||
var body = dataSource.map(function (r) {
|
||||
return [
|
||||
r.seq,
|
||||
r.settlementCycle,
|
||||
r.customerName,
|
||||
r.projectName,
|
||||
r.plateNo,
|
||||
r.compulsoryDaily,
|
||||
r.commercialDaily,
|
||||
r.excessDaily,
|
||||
r.cargoDaily,
|
||||
r.apportionDays,
|
||||
r.apportionCost
|
||||
];
|
||||
});
|
||||
body.push(['合计', '', '', '', '', '', '', '', '', '', totalApportionCost]);
|
||||
downloadCsv('车辆保险台账_' + cycleDisplayLabel + '_' + new Date().getTime() + '.csv', [headers].concat(body));
|
||||
message.success('已导出 CSV');
|
||||
}, [dataSource, cycleDisplayLabel, totalApportionCost]);
|
||||
|
||||
var columns = useMemo(function () {
|
||||
return [
|
||||
{
|
||||
title: '序号',
|
||||
dataIndex: 'seq',
|
||||
key: 'seq',
|
||||
width: 64,
|
||||
align: 'center',
|
||||
fixed: 'left'
|
||||
},
|
||||
{
|
||||
title: '结算周期',
|
||||
dataIndex: 'settlementCycle',
|
||||
key: 'settlementCycle',
|
||||
width: 100,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '客户名称',
|
||||
dataIndex: 'customerName',
|
||||
key: 'customerName',
|
||||
width: 200,
|
||||
align: 'center',
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
title: '项目名称',
|
||||
dataIndex: 'projectName',
|
||||
key: 'projectName',
|
||||
width: 160,
|
||||
align: 'center',
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
title: '车牌号',
|
||||
dataIndex: 'plateNo',
|
||||
key: 'plateNo',
|
||||
width: 110,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '交强险日成本',
|
||||
dataIndex: 'compulsoryDaily',
|
||||
key: 'compulsoryDaily',
|
||||
width: 130,
|
||||
align: 'right',
|
||||
render: function (v) { return fmtMoney(v, 4); }
|
||||
},
|
||||
{
|
||||
title: '商业险日成本',
|
||||
dataIndex: 'commercialDaily',
|
||||
key: 'commercialDaily',
|
||||
width: 130,
|
||||
align: 'right',
|
||||
render: function (v) { return fmtMoney(v, 4); }
|
||||
},
|
||||
{
|
||||
title: '超赔险日成本',
|
||||
dataIndex: 'excessDaily',
|
||||
key: 'excessDaily',
|
||||
width: 130,
|
||||
align: 'right',
|
||||
render: function (v) { return fmtMoney(v, 4); }
|
||||
},
|
||||
{
|
||||
title: '货物险日成本',
|
||||
dataIndex: 'cargoDaily',
|
||||
key: 'cargoDaily',
|
||||
width: 130,
|
||||
align: 'right',
|
||||
render: function (v) { return fmtMoney(v, 4); }
|
||||
},
|
||||
{
|
||||
title: '分摊天数',
|
||||
dataIndex: 'apportionDays',
|
||||
key: 'apportionDays',
|
||||
width: 120,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '保险分摊成本',
|
||||
dataIndex: 'apportionCost',
|
||||
key: 'apportionCost',
|
||||
width: 140,
|
||||
align: 'right',
|
||||
fixed: 'right',
|
||||
render: function (v) { return fmtMoney(v, 2); }
|
||||
}
|
||||
];
|
||||
}, []);
|
||||
|
||||
var tableSummary = useCallback(function () {
|
||||
return React.createElement(
|
||||
Table.Summary,
|
||||
null,
|
||||
React.createElement(
|
||||
Table.Summary.Row,
|
||||
null,
|
||||
React.createElement(Table.Summary.Cell, { index: 0, align: 'center', colSpan: 1 }, '合计'),
|
||||
React.createElement(Table.Summary.Cell, { index: 1, colSpan: 9 }),
|
||||
React.createElement(Table.Summary.Cell, { index: 10, align: 'right' }, fmtMoney(totalApportionCost, 2))
|
||||
)
|
||||
);
|
||||
}, [totalApportionCost]);
|
||||
|
||||
return React.createElement(
|
||||
App,
|
||||
null,
|
||||
React.createElement('style', null, ledgerTableStyle),
|
||||
React.createElement(
|
||||
'div',
|
||||
{ style: layoutStyle },
|
||||
React.createElement(Breadcrumb, {
|
||||
style: { marginBottom: 12 },
|
||||
items: [{ title: '台账数据' }, { title: '保险分摊明细' }]
|
||||
}),
|
||||
React.createElement(
|
||||
Card,
|
||||
{ style: filterCardStyle, bodyStyle: { paddingBottom: 4 } },
|
||||
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(Select, {
|
||||
allowClear: true,
|
||||
showSearch: true,
|
||||
placeholder: '默认全量数据',
|
||||
style: filterControlStyle,
|
||||
value: customerDraft,
|
||||
onChange: function (v) { setCustomerDraft(v); },
|
||||
options: CUSTOMER_OPTIONS,
|
||||
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(DatePicker, {
|
||||
picker: 'month',
|
||||
style: filterControlStyle,
|
||||
placeholder: '请选择结算周期',
|
||||
format: 'YYYY-MM',
|
||||
value: monthDraft,
|
||||
onChange: function (v) { setMonthDraft(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,
|
||||
{ wrap: true },
|
||||
React.createElement(Button, { onClick: handleReset }, '重置'),
|
||||
React.createElement(Button, { type: 'primary', onClick: handleQuery }, '查询')
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
React.createElement(
|
||||
Card,
|
||||
{ style: tableCardStyle, bodyStyle: { padding: '20px 20px 24px' } },
|
||||
React.createElement(
|
||||
'div',
|
||||
{ style: { position: 'relative', marginBottom: 8, minHeight: 36 } },
|
||||
React.createElement(
|
||||
'div',
|
||||
{
|
||||
style: {
|
||||
textAlign: 'center',
|
||||
fontSize: 18,
|
||||
fontWeight: 700,
|
||||
color: 'rgba(15,23,42,0.92)',
|
||||
letterSpacing: '0.02em',
|
||||
padding: '0 88px'
|
||||
}
|
||||
},
|
||||
'车辆保险台账'
|
||||
),
|
||||
React.createElement(
|
||||
'div',
|
||||
{ style: { position: 'absolute', right: 0, top: '50%', transform: 'translateY(-50%)' } },
|
||||
React.createElement(Button, { onClick: handleExport }, '导出')
|
||||
)
|
||||
),
|
||||
React.createElement(
|
||||
'div',
|
||||
{
|
||||
style: {
|
||||
textAlign: 'center',
|
||||
marginBottom: 16,
|
||||
fontSize: 13,
|
||||
color: 'rgba(15,23,42,0.55)',
|
||||
fontWeight: 500
|
||||
}
|
||||
},
|
||||
'结算周期:',
|
||||
cycleDisplayLabel,
|
||||
'\u00A0\u00A0\u00A0\u00A0客户:',
|
||||
customerDisplayLabel
|
||||
),
|
||||
React.createElement(
|
||||
'div',
|
||||
{ className: 'ins-ledger-table-wrap' },
|
||||
React.createElement(Table, {
|
||||
className: 'ins-ledger-table',
|
||||
size: 'small',
|
||||
bordered: true,
|
||||
rowKey: 'key',
|
||||
columns: columns,
|
||||
dataSource: dataSource,
|
||||
pagination: false,
|
||||
rowClassName: function () { return 'ins-row-data'; },
|
||||
scroll: { x: 'max-content', y: 'calc(100vh - 320px)' },
|
||||
sticky: true,
|
||||
summary: tableSummary
|
||||
})
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
};
|
||||
199
web端/台账数据/氢费采购端汇总报表-需求文档.md
Normal file
199
web端/台账数据/氢费采购端汇总报表-需求文档.md
Normal file
@@ -0,0 +1,199 @@
|
||||
# 氢费(采购端)汇总报表 — 产品需求说明(PRD)
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| 文档版本 | v1.0(业务版) |
|
||||
| 产品模块 | 台账数据 → 氢费(采购端)汇总报表 |
|
||||
| 文档类型 | 产品需求说明 |
|
||||
| 适用读者 | 产品、采购、财务、运营、测试、项目 |
|
||||
|
||||
---
|
||||
|
||||
## 一、为什么做这件事
|
||||
|
||||
### 1.1 业务痛点
|
||||
|
||||
- 采购侧需按加氢站维度掌握氢费规模、应付与实付、开票与预付余额,现有数据分散在车辆氢费明细、打款、开票等模块,缺少一站汇总视图。
|
||||
- 财务对账需快速识别「未付金额」「站点欠费」等风险,并下钻到账单、流水、发票凭据。
|
||||
|
||||
### 1.2 产品价值
|
||||
|
||||
| 价值点 | 说明 |
|
||||
|--------|------|
|
||||
| 站点汇总 | 一行一站,看清加氢量、应付、已付、未付、开票、未开票、当前余额 |
|
||||
| 对账效率 | 顶部合计条随筛选即时汇总,支撑采购与财务日常核对 |
|
||||
| 可追溯 | 关键金额可钻取明细,付款凭据、发票支持在线预览与下载 |
|
||||
| 风险可见 | 未付/未开票金额为正、当前余额为负时突出展示 |
|
||||
|
||||
### 1.3 本期目标
|
||||
|
||||
建设 Web 端「氢费(采购端)汇总报表」,按地区、加氢站、结算方式查询,展示站点汇总列表及合计;支持多类钻取与 CSV 导出。
|
||||
|
||||
### 1.4 本期不做
|
||||
|
||||
- 报表内直接发起打款、开票(跳转或对接后续迭代)。
|
||||
- 跨年度历史数据全量迁移方案(本期以 2026 年起统计口径描述为准,上线以数据准备结果为准)。
|
||||
|
||||
---
|
||||
|
||||
## 二、谁在用、用来干什么
|
||||
|
||||
### 2.1 用户角色
|
||||
|
||||
| 角色 | 典型诉求 |
|
||||
|------|----------|
|
||||
| **采购人员** | 按站点查看氢费与支付进度,核对当前余额、欠费站点 |
|
||||
| **财务人员** | 核对应付/实付/未付/已开票,查看付款证明与发票附件 |
|
||||
| **运营/主管** | 按地区、结算方式浏览整体规模与异常站点 |
|
||||
|
||||
### 2.2 核心使用场景
|
||||
|
||||
1. **日常巡检**:按地区或结算方式筛选,查看顶部合计与列表,关注未付、已欠费站点。
|
||||
2. **站点下钻**:点击加氢总量、应付总金额等,打开明细弹窗核对构成。
|
||||
3. **付款与发票核查**:从已付总金额、已开票金额钻取,预览付款凭据或发票。
|
||||
4. **导出报送**:按当前筛选结果导出 CSV。
|
||||
|
||||
---
|
||||
|
||||
## 三、页面功能说明
|
||||
|
||||
### 3.1 页面组成
|
||||
|
||||
路径:**台账数据 → 氢费(采购端)汇总报表**
|
||||
|
||||
自上而下:
|
||||
|
||||
1. **查询条件区** — 地区、加氢站全称、结算方式
|
||||
2. **汇总列表区** — 标题、导出、筛选摘要、顶部合计条、站点表格
|
||||
3. **弹窗** — 需求说明、各类钻取明细、附件预览
|
||||
|
||||
面包屑行右上角提供 **「查看需求说明」**(本文档);汇总列表标题右侧提供 **「导出」**。
|
||||
|
||||
### 3.2 查询条件
|
||||
|
||||
| 查询项 | 业务说明 |
|
||||
|--------|----------|
|
||||
| 地区 | 加氢站所属省/市,支持搜索;空为全部 |
|
||||
| 加氢站全称 | 从加氢站主数据选择;空为全部 |
|
||||
| 结算方式 | 预付 / 月结;空为全部 |
|
||||
|
||||
**交互:** 修改条件后点击 **「查询」** 生效;**「重置」** 清空条件。查询成功给予简短提示。列表上方展示当前筛选摘要(地区、加氢站、结算方式)。
|
||||
|
||||
### 3.3 顶部合计条
|
||||
|
||||
表格上方独立展示(随当前列表筛选结果汇总):
|
||||
|
||||
| 合计项 | 计算口径 |
|
||||
|--------|----------|
|
||||
| 加氢总量(kg) | 列表各行加氢总量之和 |
|
||||
| 应付总金额(元) | 列表各行应付总金额之和 |
|
||||
| 已付总金额(元) | 列表各行已付总金额之和 |
|
||||
| 未付总金额(元) | **应付总金额合计 − 已付总金额合计**;大于 0 时红色显示 |
|
||||
| 未开票总金额(元) | **应付总金额合计 − 已开票总金额合计**;大于 0 时红色显示 |
|
||||
| 充值总额(元) | 列表各行充值总额之和 |
|
||||
| 当前总余额(元) | 列表各行当前余额之和;合计为负时红色显示 |
|
||||
|
||||
### 3.4 汇总列表字段
|
||||
|
||||
**列顺序(左→右):**
|
||||
序号 → 地区 → 加氢站全称 → 结算方式 → 加氢总量(kg) → 应付总金额(元) → 已付总金额(元) → 未付总金额(元) → 已开票金额(元) → 未开票金额(元) → 充值总额(元) → 当前余额(元)
|
||||
|
||||
**表头列宽:** 支持鼠标拖动表头右侧调整列宽(最小宽度限制),便于长站名与金额列阅读。
|
||||
|
||||
| 字段 | 业务口径 | 交互 |
|
||||
|------|----------|------|
|
||||
| 结算方式 | 预付 / 月结 | 只读 |
|
||||
| 加氢总量(kg) | 自 **2026 年起** 该站全部氢费加氢量之和 | 点击钻取 **加氢量明细**(仅加氢量,不含金额) |
|
||||
| 应付总金额(元) | 该站「车辆氢费明细」**加氢总价(元)** 求和 | 点击钻取明细(加氢量、成本单价、成本总价) |
|
||||
| 已付总金额(元) | 加氢站打款管理中 **已支付金额** 求和 | 点击钻取支付账单明细 |
|
||||
| 未付总金额(元) | **应付总金额 − 已付总金额**(行内计算) | 只读;大于 0 红色 |
|
||||
| 已开票金额(元) | 该站已开票金额合计 | 点击钻取开票记录 |
|
||||
| 未开票金额(元) | **应付总金额 − 已开票金额**(行内计算) | 只读;大于 0 红色 |
|
||||
| 充值总额(元) | 该站预充值(打款入账)金额合计 | 点击钻取充值明细 |
|
||||
| 当前余额(元) | 2026 年期初余额,扣减 2025 年及以前未扣款记录后的实时余额 | 点击钻取余额变更明细;**为负** 时金额红色 + 左侧 **「已欠费」** 标签 |
|
||||
|
||||
### 3.5 钻取明细说明
|
||||
|
||||
#### (1)加氢量明细(由加氢总量进入)
|
||||
|
||||
| 列 | 说明 |
|
||||
|----|------|
|
||||
| 序号、加氢时间、订单编号、车牌号、加氢量(kg) | 来源于车辆氢费明细,按当前加氢站筛选 |
|
||||
| 合计 | 加氢量合计 |
|
||||
|
||||
#### (2)应付总金额明细
|
||||
|
||||
| 列 | 说明 |
|
||||
|----|------|
|
||||
| 序号、加氢时间、订单编号、车牌号、加氢量(kg)、成本单价(元/kg)、成本总价(元) | 按站筛选的车辆氢费明细 |
|
||||
| 合计 | 加氢量、成本总价;弹窗标题含站名 |
|
||||
|
||||
#### (3)已付总金额明细(由已付总金额进入)
|
||||
|
||||
| 列 | 说明 |
|
||||
|----|------|
|
||||
| 加氢站全称、账单开始时间、账单结束时间、应付总金额(元)、已付总金额(元)、银行付款证明 | 按账单维度展示 |
|
||||
| 银行付款证明 | **查看付款凭据** — 预览付款证明图片 |
|
||||
| 合计 | 应付、实付合计 |
|
||||
|
||||
#### (4)已开票明细(由已开票金额进入)
|
||||
|
||||
| 列 | 说明 |
|
||||
|----|------|
|
||||
| 加氢站全称、开票时间、开票金额(元)、发票 | |
|
||||
| 发票 | **查看发票** — 在线预览 PDF/图片;**下载发票** — 下载 PDF/图片文件 |
|
||||
| 合计 | 开票金额合计 |
|
||||
|
||||
#### (5)充值总额明细(由充值总额进入)
|
||||
|
||||
| 列 | 说明 |
|
||||
|----|------|
|
||||
| 加氢站全称、支付时间、预充金额(元)、付款凭证 | 支付时间为 **YYYY-MM-DD** |
|
||||
| 付款凭证 | **预览** — 在线查看;**下载** — 下载凭证文件 |
|
||||
| 合计 | 预充金额(充值总额)合计 |
|
||||
|
||||
#### (6)余额变更明细(由当前余额进入)
|
||||
|
||||
| 列 | 说明 |
|
||||
|----|------|
|
||||
| 加氢站全称、收入金额(元)、支出金额(元)、余额(元)、订单编号 | 收入/支出为空显示「—」;余额为负红色 |
|
||||
| 合计 | 收入合计、支出合计、末行余额(与列表该行当前余额一致) |
|
||||
|
||||
### 3.6 附件预览
|
||||
|
||||
- 付款凭据、发票在弹窗中预览;PDF 使用文档预览,图片直接展示。
|
||||
- 发票支持下载,文件名与开票记录一致。
|
||||
|
||||
### 3.7 导出
|
||||
|
||||
- 点击 **「导出」** 下载当前筛选结果 CSV(含列表字段及合计行)。
|
||||
- 编码 UTF-8(带 BOM),便于 Excel 打开。
|
||||
|
||||
---
|
||||
|
||||
## 四、业务规则摘要
|
||||
|
||||
| 规则 | 说明 |
|
||||
|------|------|
|
||||
| 统计起点 | 加氢总量等业务口径默认 **2026 年起**(与车辆氢费明细、主数据生效规则一致) |
|
||||
| 未付(行) | 应付总金额 − 已付总金额 |
|
||||
| 未付(合计条) | 各站未付之和,等价于应付合计 − 已付合计 |
|
||||
| 未开票(行) | 应付总金额 − 已开票金额 |
|
||||
| 未开票(合计条) | 各站未开票之和,等价于应付合计 − 已开票合计 |
|
||||
| 已欠费 | 仅 **当前余额 < 0** 时展示标签 |
|
||||
| 钻取范围 | 均限定为 **当前汇总行对应加氢站** |
|
||||
|
||||
---
|
||||
|
||||
## 五、验收要点(业务)
|
||||
|
||||
1. 查询、重置、筛选摘要、合计条与列表数据一致。
|
||||
2. 各可点击金额/加氢量钻取弹窗字段与上文一致,合计正确。
|
||||
3. 未付、已欠费展示规则符合第四节。
|
||||
4. 付款凭据可预览;发票可预览与下载。
|
||||
5. 列宽可拖动;导出字段完整。
|
||||
6. 「查看需求说明」可打开本 PRD 全文。
|
||||
|
||||
---
|
||||
|
||||
**文档结束**
|
||||
2329
web端/台账数据/氢费采购端汇总报表.jsx
Normal file
2329
web端/台账数据/氢费采购端汇总报表.jsx
Normal file
File diff suppressed because it is too large
Load Diff
@@ -3,11 +3,11 @@ var H2_LEDGER_REQUIREMENT_DOC = `# 车辆氢费明细 — 产品需求说明(P
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| 文档版本 | v2.0(业务版) |
|
||||
| 文档版本 | v2.1(业务版) |
|
||||
| 产品模块 | 台账数据 → 车辆氢费明细 |
|
||||
| 文档类型 | 产品需求说明 |
|
||||
| 适用读者 | 产品、业务、运营、测试、项目 |
|
||||
| 修订说明 | 从业务与使用场景出发描述需求,不展开技术实现细节 |
|
||||
| 修订说明 | 同步列表字段顺序、顶部合计条、承担方式、系统带出字段等现行页面行为 |
|
||||
|
||||
---
|
||||
|
||||
@@ -130,9 +130,9 @@ flowchart LR
|
||||
| 客户名称 | 从客户库选择 |
|
||||
| 加氢站名称 | 从加氢站库选择 |
|
||||
| 业务员 | 按客户归属业务员筛选 |
|
||||
| 结算状态 | 客户承担 / 我司承担 |
|
||||
| 付款状态 | 未付款 / 已付款 / 部分付款 |
|
||||
| 开票公司 | 从开票主体选择 |
|
||||
| 承担方式 | 客户承担 / 我司承担 / 客户自行结算 / 其他结算 |
|
||||
| 客户收款状态 | 已付款 / 未付款(系统带出,用于筛选) |
|
||||
| 开票公司 | 从开票主体选择(系统带出字段对应公司) |
|
||||
|
||||
查询成功给予简短成功提示。
|
||||
|
||||
@@ -154,7 +154,17 @@ flowchart LR
|
||||
|
||||
不同区域之间有明显分隔,已对账区背景略灰、待保存区背景略黄,降低误操作概率。
|
||||
|
||||
**底部合计:** 对当前列表可见记录,合计 **加氢量、成本总价、加氢总价**(随筛选与「仅看异常」变化)。
|
||||
**顶部合计条:** 表格上方独立展示 **加氢量(kg)、成本总价(元)、加氢总价(元)** 三项合计。
|
||||
|
||||
- **统计范围:** 与当前列表可见行一致。
|
||||
- **随查询重算:** 点击「查询」应用筛选条件后,合计立即按新结果重新汇总。
|
||||
- **随「仅显示异常数据」变化:** 开关开启时,仅对当前可见的异常记录(及本人待保存行)合计。
|
||||
- **说明:** 合计条含「待保存 / 未对账 / 已对账」等当前列表中的全部可见记录,与导出范围(仅未对账+已对账)不同。
|
||||
|
||||
**列表列顺序(左→右,业务视角):**
|
||||
序号 → 加氢日期 → 加氢时间 → 加氢站名称 → 客户名称 → 车牌号 → 加氢量 → 成本单价 → 成本总价 → 加氢单价 → 加氢总价 → 行驶里程 → 备注 → 业务员 → 承担方式 → 对账日期 → **收票日期** → **加氢站付款状态** → **开票日期** → **客户收款状态** → **开票公司** → 状态 → 订单编号 → 操作(操作列固定右侧)。
|
||||
|
||||
**系统带出字段(不可手工维护):** 收票日期、加氢站付款状态、开票日期、客户收款状态、开票公司;选择/变更客户等信息后由系统自动刷新,单元格为浅灰底只读样式。
|
||||
|
||||
**列表勾选:** 仅 **未对账** 记录可勾选,用于批量「完成对账」。
|
||||
|
||||
@@ -178,26 +188,28 @@ flowchart LR
|
||||
|
||||
| 信息项 | 用户是否填写 | 业务说明 |
|
||||
|--------|--------------|----------|
|
||||
| 状态 | 否 | 展示「未对账」「已对账」;待保存不显示标签 |
|
||||
| 订单编号 | 否 | 系统按规则自动生成,不可改 |
|
||||
| 加氢时间 | 是* | 精确到秒,必填 |
|
||||
| 加氢日期 | 否 | 由加氢时间自动得出 |
|
||||
| 加氢日期 | 否 | 由加氢时间自动得出,只读 |
|
||||
| 加氢站名称 | 是* | 必选 |
|
||||
| 客户名称 | 是* | 必选,位于加氢站右侧;决定业务员与系统带出信息 |
|
||||
| 车牌号 | 是* | 必选,须为公司登记车辆 |
|
||||
| 行驶里程 | 否 | 选填,用于业务留痕 |
|
||||
| 加氢量(kg) | 是* | 必填,用于算总价 |
|
||||
| 成本单价 | 是* | 必填,向站点的采购成本价 |
|
||||
| 成本总价 | 否 | 加氢量 × 成本单价,自动计算 |
|
||||
| 客户名称 | 是* | 必选,决定业务员与财务带出信息 |
|
||||
| 加氢单价 | 是* | 必填,对客户的销售单价 |
|
||||
| 加氢总价 | 否 | 加氢量 × 加氢单价,自动计算 |
|
||||
| 业务员 | 否 | 选客户后自动带出 |
|
||||
| 结算状态 | 是* | 客户承担 / 我司承担 |
|
||||
| 开票日期 | 否 | 系统按客户等业务规则带出 |
|
||||
| 对账日期 | 否 | 系统带出 |
|
||||
| 付款状态 | 否 | 系统带出 |
|
||||
| 开票公司 | 否 | 系统带出 |
|
||||
| 行驶里程 | 否 | 选填,位于加氢总价之后 |
|
||||
| 备注 | 否 | 自由文本 |
|
||||
| 业务员 | 否 | 选客户后自动带出 |
|
||||
| 承担方式 | 是* | 客户承担 / 我司承担 / 客户自行结算 / 其他结算 |
|
||||
| 对账日期 | 否 | 完成对账等流程带出,只读 |
|
||||
| 收票日期 | 否 | 由财务/收票模块自动带出,不可编辑 |
|
||||
| 加氢站付款状态 | 否 | 已付款 / 未付款,由加氢站打款管理带出 |
|
||||
| 开票日期 | 否 | 由开票模块自动带出 |
|
||||
| 客户收款状态 | 否 | 已付款 / 未付款,由客户收款模块带出 |
|
||||
| 开票公司 | 否 | 显示开票公司名称,系统自动带出 |
|
||||
| 状态 | 否 | 展示「未对账」「已对账」;待保存不显示标签;列在列表末尾 |
|
||||
| 订单编号 | 否 | 系统按规则自动生成,不可改;列在列表末尾 |
|
||||
|
||||
\\* 保存时校验,缺失则标红提示。
|
||||
|
||||
@@ -267,7 +279,7 @@ flowchart LR
|
||||
### 8.1 表头批量改价 / 改结算
|
||||
|
||||
- 在 **成本单价**、**加氢单价** 列表头可批量填入统一单价,作用于当前可编辑的所有记录(待保存 + 未对账)。
|
||||
- 在 **结算状态** 列表头可批量改为「客户承担」或「我司承担」。
|
||||
- 在 **承担方式** 列表头可批量改为四种承担方式之一。
|
||||
- **已对账** 记录不参与批量修改。
|
||||
|
||||
### 8.2 批量导入
|
||||
@@ -277,11 +289,11 @@ flowchart LR
|
||||
**流程:**
|
||||
|
||||
1. 点击「批量导入」→ 下载标准模板
|
||||
2. 按模板填写(无需填开票日期、对账日期、付款状态、开票公司)
|
||||
2. 按模板填写(无需填对账日期及收票/开票/付款等系统带出字段)
|
||||
3. 上传文件 → 系统生成多条 **待保存** 记录
|
||||
4. 业务核对列表 → 点击 **保存** 进入未对账
|
||||
|
||||
**模板包含列:** 加氢时间、加氢站名称、车牌号、行驶里程、加氢量、成本单价、客户名称、加氢单价、结算状态、备注。
|
||||
**模板包含列:** 加氢时间、加氢站名称、车牌号、加氢量、成本单价、客户名称、加氢单价、承担方式、备注(行驶里程可在备注前按业务需要填写,导入模板列顺序以页面下载为准)。
|
||||
|
||||
**导入后状态:** 均为待保存,与手工新增一致,须保存后才参与对账与导出。
|
||||
|
||||
@@ -297,7 +309,7 @@ flowchart LR
|
||||
- 弹窗文案:「请选择导出的列」;支持全选/取消全选;默认勾选全部可导出列。
|
||||
- 无符合条件数据时提示:暂无未对账或已对账数据可导出。
|
||||
|
||||
**可导出列(业务名称):** 序号、状态、订单编号、加氢时间、加氢日期、加氢站名称、车牌号、行驶里程、加氢量、成本单价、成本总价、客户名称、加氢单价、加氢总价、业务员、结算状态、开票日期、对账日期、付款状态、开票公司、备注。
|
||||
**可导出列(业务名称):** 序号、状态、订单编号、加氢时间、加氢日期、加氢站名称、车牌号、加氢量、成本单价、成本总价、客户名称、加氢单价、加氢总价、行驶里程、业务员、承担方式、对账日期、备注、收票日期、加氢站付款状态、开票日期、客户收款状态、开票公司。
|
||||
|
||||
---
|
||||
|
||||
@@ -326,7 +338,7 @@ flowchart LR
|
||||
### 10.1 保存
|
||||
|
||||
- 一次保存处理页面上**全部**待保存记录。
|
||||
- 必填:加氢时间、加氢站、车牌(须为登记车辆)、客户、加氢量、成本单价、加氢单价、结算状态。
|
||||
- 必填:加氢时间、加氢站、车牌(须为登记车辆)、客户、加氢量、成本单价、加氢单价、承担方式。
|
||||
- 校验失败:仅格子标红,无「保存成功」类提示。
|
||||
|
||||
### 10.2 完成对账
|
||||
@@ -338,8 +350,8 @@ flowchart LR
|
||||
### 10.3 筛选与列表
|
||||
|
||||
- 查询点击后生效;重置恢复。
|
||||
- 筛选后合计与所见列表一致。
|
||||
- 本人待保存新增行在筛选后仍可见。
|
||||
- **顶部合计条** 对当前列表可见行实时汇总;修改筛选并点击「查询」后重新计算;「仅显示异常数据」开启时仅统计可见行。
|
||||
- 本人待保存新增行在筛选后仍可见(合计亦包含这些行,若其在列表中展示)。
|
||||
|
||||
### 10.4 导出
|
||||
|
||||
@@ -375,9 +387,13 @@ flowchart LR
|
||||
| 待保存 | 草稿,未进入对账流程 |
|
||||
| 未对账 | 已保存,等待业务确认并完成对账 |
|
||||
| 已对账 | 对账完成,业务员不可随意改动 |
|
||||
| 客户承担 | 氢费由客户结算 |
|
||||
| 我司承担 | 氢费由公司承担 |
|
||||
| 未付款 / 已付款 / 部分付款 | 系统带出的付款进度,业务只读 |
|
||||
| 客户承担 | 氢费由客户承担 |
|
||||
| 我司承担 | 氢费由我司承担 |
|
||||
| 客户自行结算 | 由客户自行与加氢站等方结算 |
|
||||
| 其他结算 | 其他结算方式 |
|
||||
| 加氢站付款状态 | 加氢站侧是否已付款,已付款 / 未付款 |
|
||||
| 客户收款状态 | 客户侧是否已收款,已付款 / 未付款 |
|
||||
| 收票日期 | 财务收票日期,系统带出 |
|
||||
| 标准价 | 公司维护的、按加氢站与生效时段确定的参考单价 |
|
||||
|
||||
---
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| 文档版本 | v2.0(业务版) |
|
||||
| 文档版本 | v2.1(业务版) |
|
||||
| 产品模块 | 台账数据 → 车辆氢费明细 |
|
||||
| 文档类型 | 产品需求说明 |
|
||||
| 适用读者 | 产品、业务、运营、测试、项目 |
|
||||
| 修订说明 | 从业务与使用场景出发描述需求,不展开技术实现细节 |
|
||||
| 修订说明 | 同步列表字段顺序、顶部合计条、承担方式、系统带出字段等现行页面行为 |
|
||||
|
||||
---
|
||||
|
||||
@@ -75,14 +75,14 @@
|
||||
|
||||
### 3.1 端到端流程(推荐操作顺序)
|
||||
|
||||
```mermaid
|
||||
\`\`\`mermaid
|
||||
flowchart LR
|
||||
A[录入/复制] --> B[待保存]
|
||||
B --> C[点击保存]
|
||||
C[保存/导入] --> D[未对账]
|
||||
D --> E[勾选并完成对账]
|
||||
E --> F[已对账]
|
||||
```
|
||||
\`\`\`
|
||||
|
||||
**说明:**
|
||||
|
||||
@@ -129,9 +129,9 @@ flowchart LR
|
||||
| 客户名称 | 从客户库选择 |
|
||||
| 加氢站名称 | 从加氢站库选择 |
|
||||
| 业务员 | 按客户归属业务员筛选 |
|
||||
| 结算状态 | 客户承担 / 我司承担 |
|
||||
| 付款状态 | 未付款 / 已付款 / 部分付款 |
|
||||
| 开票公司 | 从开票主体选择 |
|
||||
| 承担方式 | 客户承担 / 我司承担 / 客户自行结算 / 其他结算 |
|
||||
| 客户收款状态 | 已付款 / 未付款(系统带出,用于筛选) |
|
||||
| 开票公司 | 从开票主体选择(系统带出字段对应公司) |
|
||||
|
||||
查询成功给予简短成功提示。
|
||||
|
||||
@@ -153,7 +153,17 @@ flowchart LR
|
||||
|
||||
不同区域之间有明显分隔,已对账区背景略灰、待保存区背景略黄,降低误操作概率。
|
||||
|
||||
**底部合计:** 对当前列表可见记录,合计 **加氢量、成本总价、加氢总价**(随筛选与「仅看异常」变化)。
|
||||
**顶部合计条:** 表格上方独立展示 **加氢量(kg)、成本总价(元)、加氢总价(元)** 三项合计。
|
||||
|
||||
- **统计范围:** 与当前列表可见行一致。
|
||||
- **随查询重算:** 点击「查询」应用筛选条件后,合计立即按新结果重新汇总。
|
||||
- **随「仅显示异常数据」变化:** 开关开启时,仅对当前可见的异常记录(及本人待保存行)合计。
|
||||
- **说明:** 合计条含「待保存 / 未对账 / 已对账」等当前列表中的全部可见记录,与导出范围(仅未对账+已对账)不同。
|
||||
|
||||
**列表列顺序(左→右,业务视角):**
|
||||
序号 → 加氢日期 → 加氢时间 → 加氢站名称 → 客户名称 → 车牌号 → 加氢量 → 成本单价 → 成本总价 → 加氢单价 → 加氢总价 → 行驶里程 → 备注 → 业务员 → 承担方式 → 对账日期 → **收票日期** → **加氢站付款状态** → **开票日期** → **客户收款状态** → **开票公司** → 状态 → 订单编号 → 操作(操作列固定右侧)。
|
||||
|
||||
**系统带出字段(不可手工维护):** 收票日期、加氢站付款状态、开票日期、客户收款状态、开票公司;选择/变更客户等信息后由系统自动刷新,单元格为浅灰底只读样式。
|
||||
|
||||
**列表勾选:** 仅 **未对账** 记录可勾选,用于批量「完成对账」。
|
||||
|
||||
@@ -177,28 +187,30 @@ flowchart LR
|
||||
|
||||
| 信息项 | 用户是否填写 | 业务说明 |
|
||||
|--------|--------------|----------|
|
||||
| 状态 | 否 | 展示「未对账」「已对账」;待保存不显示标签 |
|
||||
| 订单编号 | 否 | 系统按规则自动生成,不可改 |
|
||||
| 加氢时间 | 是* | 精确到秒,必填 |
|
||||
| 加氢日期 | 否 | 由加氢时间自动得出 |
|
||||
| 加氢日期 | 否 | 由加氢时间自动得出,只读 |
|
||||
| 加氢站名称 | 是* | 必选 |
|
||||
| 客户名称 | 是* | 必选,位于加氢站右侧;决定业务员与系统带出信息 |
|
||||
| 车牌号 | 是* | 必选,须为公司登记车辆 |
|
||||
| 行驶里程 | 否 | 选填,用于业务留痕 |
|
||||
| 加氢量(kg) | 是* | 必填,用于算总价 |
|
||||
| 成本单价 | 是* | 必填,向站点的采购成本价 |
|
||||
| 成本总价 | 否 | 加氢量 × 成本单价,自动计算 |
|
||||
| 客户名称 | 是* | 必选,决定业务员与财务带出信息 |
|
||||
| 加氢单价 | 是* | 必填,对客户的销售单价 |
|
||||
| 加氢总价 | 否 | 加氢量 × 加氢单价,自动计算 |
|
||||
| 业务员 | 否 | 选客户后自动带出 |
|
||||
| 结算状态 | 是* | 客户承担 / 我司承担 |
|
||||
| 开票日期 | 否 | 系统按客户等业务规则带出 |
|
||||
| 对账日期 | 否 | 系统带出 |
|
||||
| 付款状态 | 否 | 系统带出 |
|
||||
| 开票公司 | 否 | 系统带出 |
|
||||
| 行驶里程 | 否 | 选填,位于加氢总价之后 |
|
||||
| 备注 | 否 | 自由文本 |
|
||||
| 业务员 | 否 | 选客户后自动带出 |
|
||||
| 承担方式 | 是* | 客户承担 / 我司承担 / 客户自行结算 / 其他结算 |
|
||||
| 对账日期 | 否 | 完成对账等流程带出,只读 |
|
||||
| 收票日期 | 否 | 由财务/收票模块自动带出,不可编辑 |
|
||||
| 加氢站付款状态 | 否 | 已付款 / 未付款,由加氢站打款管理带出 |
|
||||
| 开票日期 | 否 | 由开票模块自动带出 |
|
||||
| 客户收款状态 | 否 | 已付款 / 未付款,由客户收款模块带出 |
|
||||
| 开票公司 | 否 | 显示开票公司名称,系统自动带出 |
|
||||
| 状态 | 否 | 展示「未对账」「已对账」;待保存不显示标签;列在列表末尾 |
|
||||
| 订单编号 | 否 | 系统按规则自动生成,不可改;列在列表末尾 |
|
||||
|
||||
\* 保存时校验,缺失则标红提示。
|
||||
\\* 保存时校验,缺失则标红提示。
|
||||
|
||||
### 5.2 订单编号规则(业务口径)
|
||||
|
||||
@@ -266,7 +278,7 @@ flowchart LR
|
||||
### 8.1 表头批量改价 / 改结算
|
||||
|
||||
- 在 **成本单价**、**加氢单价** 列表头可批量填入统一单价,作用于当前可编辑的所有记录(待保存 + 未对账)。
|
||||
- 在 **结算状态** 列表头可批量改为「客户承担」或「我司承担」。
|
||||
- 在 **承担方式** 列表头可批量改为四种承担方式之一。
|
||||
- **已对账** 记录不参与批量修改。
|
||||
|
||||
### 8.2 批量导入
|
||||
@@ -276,11 +288,11 @@ flowchart LR
|
||||
**流程:**
|
||||
|
||||
1. 点击「批量导入」→ 下载标准模板
|
||||
2. 按模板填写(无需填开票日期、对账日期、付款状态、开票公司)
|
||||
2. 按模板填写(无需填对账日期及收票/开票/付款等系统带出字段)
|
||||
3. 上传文件 → 系统生成多条 **待保存** 记录
|
||||
4. 业务核对列表 → 点击 **保存** 进入未对账
|
||||
|
||||
**模板包含列:** 加氢时间、加氢站名称、车牌号、行驶里程、加氢量、成本单价、客户名称、加氢单价、结算状态、备注。
|
||||
**模板包含列:** 加氢时间、加氢站名称、车牌号、加氢量、成本单价、客户名称、加氢单价、承担方式、备注(行驶里程可在备注前按业务需要填写,导入模板列顺序以页面下载为准)。
|
||||
|
||||
**导入后状态:** 均为待保存,与手工新增一致,须保存后才参与对账与导出。
|
||||
|
||||
@@ -296,7 +308,7 @@ flowchart LR
|
||||
- 弹窗文案:「请选择导出的列」;支持全选/取消全选;默认勾选全部可导出列。
|
||||
- 无符合条件数据时提示:暂无未对账或已对账数据可导出。
|
||||
|
||||
**可导出列(业务名称):** 序号、状态、订单编号、加氢时间、加氢日期、加氢站名称、车牌号、行驶里程、加氢量、成本单价、成本总价、客户名称、加氢单价、加氢总价、业务员、结算状态、开票日期、对账日期、付款状态、开票公司、备注。
|
||||
**可导出列(业务名称):** 序号、状态、订单编号、加氢时间、加氢日期、加氢站名称、车牌号、加氢量、成本单价、成本总价、客户名称、加氢单价、加氢总价、行驶里程、业务员、承担方式、对账日期、备注、收票日期、加氢站付款状态、开票日期、客户收款状态、开票公司。
|
||||
|
||||
---
|
||||
|
||||
@@ -325,7 +337,7 @@ flowchart LR
|
||||
### 10.1 保存
|
||||
|
||||
- 一次保存处理页面上**全部**待保存记录。
|
||||
- 必填:加氢时间、加氢站、车牌(须为登记车辆)、客户、加氢量、成本单价、加氢单价、结算状态。
|
||||
- 必填:加氢时间、加氢站、车牌(须为登记车辆)、客户、加氢量、成本单价、加氢单价、承担方式。
|
||||
- 校验失败:仅格子标红,无「保存成功」类提示。
|
||||
|
||||
### 10.2 完成对账
|
||||
@@ -337,8 +349,8 @@ flowchart LR
|
||||
### 10.3 筛选与列表
|
||||
|
||||
- 查询点击后生效;重置恢复。
|
||||
- 筛选后合计与所见列表一致。
|
||||
- 本人待保存新增行在筛选后仍可见。
|
||||
- **顶部合计条** 对当前列表可见行实时汇总;修改筛选并点击「查询」后重新计算;「仅显示异常数据」开启时仅统计可见行。
|
||||
- 本人待保存新增行在筛选后仍可见(合计亦包含这些行,若其在列表中展示)。
|
||||
|
||||
### 10.4 导出
|
||||
|
||||
@@ -374,9 +386,13 @@ flowchart LR
|
||||
| 待保存 | 草稿,未进入对账流程 |
|
||||
| 未对账 | 已保存,等待业务确认并完成对账 |
|
||||
| 已对账 | 对账完成,业务员不可随意改动 |
|
||||
| 客户承担 | 氢费由客户结算 |
|
||||
| 我司承担 | 氢费由公司承担 |
|
||||
| 未付款 / 已付款 / 部分付款 | 系统带出的付款进度,业务只读 |
|
||||
| 客户承担 | 氢费由客户承担 |
|
||||
| 我司承担 | 氢费由我司承担 |
|
||||
| 客户自行结算 | 由客户自行与加氢站等方结算 |
|
||||
| 其他结算 | 其他结算方式 |
|
||||
| 加氢站付款状态 | 加氢站侧是否已付款,已付款 / 未付款 |
|
||||
| 客户收款状态 | 客户侧是否已收款,已付款 / 未付款 |
|
||||
| 收票日期 | 财务收票日期,系统带出 |
|
||||
| 标准价 | 公司维护的、按加氢站与生效时段确定的参考单价 |
|
||||
|
||||
---
|
||||
|
||||
1823
web端/台账数据/车辆维修明细.jsx
Normal file
1823
web端/台账数据/车辆维修明细.jsx
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user