Files
ONE-OS/web端/运维管理/车辆业务/证照管理.jsx
王冕 92d3b97bca 运维/财务:完善交车单编辑/查看与还车应结款页面
- 交车单编辑页:布局对齐、检查单合并、照片必填与需求说明
- 新增交车单查看页:只读展示与样例数据
- 还车应结款相关页面与需求说明补齐

Made-with: Cursor
2026-03-18 22:10:05 +08:00

304 lines
14 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 作为组件变量名
// 运维管理 - 车辆管理 - 证照管理
const Component = function () {
var useState = React.useState;
var useMemo = React.useMemo;
var useCallback = React.useCallback;
var antd = window.antd;
var Breadcrumb = antd.Breadcrumb;
var Card = antd.Card;
var Table = antd.Table;
var Button = antd.Button;
var Select = antd.Select;
var Input = antd.Input;
var DatePicker = antd.DatePicker;
var Modal = antd.Modal;
var message = antd.message;
function pad2(n) { return n < 10 ? '0' + n : '' + n; }
function fmtDate(d) { return d.getFullYear() + '-' + pad2(d.getMonth() + 1) + '-' + pad2(d.getDate()); }
function todayPlus(days) { var d = new Date(); d.setDate(d.getDate() + days); return fmtDate(d); }
var layoutStyle = { padding: '16px 24px', background: '#f5f5f5', minHeight: '100vh' };
var cardStyle = { marginBottom: 16 };
// 筛选
var filtersState = useState({
customerName: undefined,
contractCode: undefined,
plateNo: undefined,
vin: undefined,
licenseInspectValid: null,
operationPermitValid: null,
passPermitValid: null
});
var filters = filtersState[0];
var setFilters = filtersState[1];
var moreOpenState = useState(false);
// mock 列表数据
var tableDataState = useState(function () {
var rows = [];
for (var i = 1; i <= 20; i++) {
rows.push({
key: 'row-' + i,
plateNo: i < 10 ? ('粤A1234' + i) : ('京A5432' + i),
vin: 'LJ8ABC' + (100000 + i),
licenseRegDate: todayPlus(-500 - i),
licenseScrapDate: todayPlus(2000 + i),
licenseValidDate: todayPlus(60 + i),
operationCertNo: 'YYZ-' + (10000 + i),
operationRegDate: todayPlus(-480 - i),
operationInspectValid: todayPlus(90 + i),
operationValid: todayPlus(365 + i),
passPermitNo: 'TXZ-' + (20000 + i),
passArea: i % 3 === 0 ? '上海市-浦东新区' : i % 3 === 1 ? '广东省-广州市' : '北京市-朝阳区',
passValid: todayPlus(120 + i),
h2CertCode: 'JQZ-' + (30000 + i),
h2CertInspectDate: todayPlus(-30 - i),
h2CardCode: 'JQK-' + (40000 + i),
safetyValveInspectDate: todayPlus(-20 - i),
safetyValveCycleMonth: 12,
pressureGaugeInspectDate: todayPlus(-10 - i),
pressureGaugeCycleMonth: 12,
h2BottleVendor: i % 2 === 0 ? '亿华' : '中集',
h2BottleInspectDate: todayPlus(-5 - i),
h2BottleCycleMonth: 24
});
}
return rows;
});
var tableData = tableDataState[0];
var setTableData = tableDataState[1];
// 下拉选项(来自列表 mock
var options = useMemo(function () {
var customers = ['嘉兴某某物流有限公司', '上海某某运输公司', '北京某某租赁有限公司'];
var contracts = ['HI-2024-001', 'HI-2024-002', 'HI-2024-003'];
return {
customerName: customers.map(function (v) { return { value: v, label: v }; }),
contractCode: contracts.map(function (v) { return { value: v, label: v }; }),
plateNo: tableData.map(function (r) { return r.plateNo; }).slice(0, 20).map(function (v) { return { value: v, label: v }; }),
vin: tableData.map(function (r) { return r.vin; }).slice(0, 20).map(function (v) { return { value: v, label: v }; })
};
}, [tableData]);
var filteredData = useMemo(function () {
var list = tableData;
if (filters.customerName) {
// mock按 index 分组匹配
list = list.filter(function (_, idx) { return (idx % 3) === 0; });
}
if (filters.contractCode) {
list = list.filter(function (_, idx) { return (idx % 3) === 1; });
}
if (filters.plateNo) list = list.filter(function (r) { return r.plateNo === filters.plateNo; });
if (filters.vin) list = list.filter(function (r) { return r.vin === filters.vin; });
return list;
}, [tableData, filters.customerName, filters.contractCode, filters.plateNo, filters.vin]);
// 选中
var selectedRowKeysState = useState([]);
// 导入弹窗
var importOpenState = useState(false);
var importFileState = useState(null);
function resetFilters() {
setFilters({
customerName: undefined,
contractCode: undefined,
plateNo: undefined,
vin: undefined,
licenseInspectValid: null,
operationPermitValid: null,
passPermitValid: null
});
message.success('已重置');
}
function handleQuery() {
message.success('已查询(原型)');
}
function openAdd() {
message.info('进入证照录入页(原型)');
}
function confirmDeleteSelected() {
var keys = selectedRowKeysState[0] || [];
if (!keys.length) return;
Modal.confirm({
title: '确认删除',
content: '确定要删除选中的证照记录吗?删除后将无法恢复。',
okText: '确认删除',
cancelText: '取消',
onOk: function () {
setTableData(function (p) { return p.filter(function (r) { return keys.indexOf(r.key) === -1; }); });
selectedRowKeysState[1]([]);
message.success('已删除');
}
});
}
function openExport() {
message.info('导出当前筛选结果(原型)');
}
function openImport() {
importFileState[1](null);
importOpenState[1](true);
}
function onPickImportFile(e) {
var f = e && e.target && e.target.files && e.target.files[0];
if (!f) return;
var name = String(f.name || '').toLowerCase();
if (!(name.endsWith('.xls') || name.endsWith('.xlsx'))) {
message.error('仅支持 .xls、.xlsx 格式');
return;
}
importFileState[1](f);
}
function doImportUpload() {
if (!importFileState[0]) {
message.error('请先选取要上传的文件');
return;
}
message.success('上传成功(原型)');
importOpenState[1](false);
}
// 表格列
var columns = useMemo(function () {
return [
{ title: '车牌号', dataIndex: 'plateNo', key: 'plateNo', width: 110, fixed: 'left' },
{
title: 'vin码',
dataIndex: 'vin',
key: 'vin',
width: 150,
render: function (v) {
return React.createElement('span', { style: { color: '#f5222d', fontWeight: 600 } }, v || '-');
}
},
{ title: '行驶证 注册日期', dataIndex: 'licenseRegDate', key: 'licenseRegDate', width: 140 },
{ title: '行驶证 强制报废日期', dataIndex: 'licenseScrapDate', key: 'licenseScrapDate', width: 160 },
{ title: '行驶证 有效期', dataIndex: 'licenseValidDate', key: 'licenseValidDate', width: 130 },
{ title: '营运证 编号', dataIndex: 'operationCertNo', key: 'operationCertNo', width: 140 },
{ title: '营运证 注册日期', dataIndex: 'operationRegDate', key: 'operationRegDate', width: 140 },
{ title: '营运证 审验有效期', dataIndex: 'operationInspectValid', key: 'operationInspectValid', width: 160 },
{ title: '营运证 有效期', dataIndex: 'operationValid', key: 'operationValid', width: 140 },
{ title: '通行证 编号', dataIndex: 'passPermitNo', key: 'passPermitNo', width: 140 },
{ title: '通行区域', dataIndex: 'passArea', key: 'passArea', width: 160, ellipsis: true },
{ title: '通行证 有效期', dataIndex: 'passValid', key: 'passValid', width: 140 },
{ title: '加氢证 编码', dataIndex: 'h2CertCode', key: 'h2CertCode', width: 140 },
{ title: '加氢证 检验日期', dataIndex: 'h2CertInspectDate', key: 'h2CertInspectDate', width: 150 },
{ title: '加氢卡 编码', dataIndex: 'h2CardCode', key: 'h2CardCode', width: 140 },
{ title: '安全阀 检验日期', dataIndex: 'safetyValveInspectDate', key: 'safetyValveInspectDate', width: 150 },
{ title: '安全阀 检验周期:单位 (月)', dataIndex: 'safetyValveCycleMonth', key: 'safetyValveCycleMonth', width: 200 },
{ title: '压力表 检验日期', dataIndex: 'pressureGaugeInspectDate', key: 'pressureGaugeInspectDate', width: 150 },
{ title: '压力表 检验周期:单位 (月)', dataIndex: 'pressureGaugeCycleMonth', key: 'pressureGaugeCycleMonth', width: 200 },
{ title: '氢气瓶 厂家', dataIndex: 'h2BottleVendor', key: 'h2BottleVendor', width: 120 },
{ title: '氢气瓶 检验日期', dataIndex: 'h2BottleInspectDate', key: 'h2BottleInspectDate', width: 150 },
{ title: '氢气瓶 检验周期:单位 (月)', dataIndex: 'h2BottleCycleMonth', key: 'h2BottleCycleMonth', width: 200 },
{
title: '操作',
key: 'action',
width: 120,
fixed: 'right',
render: function (_, r) {
return React.createElement('div', { style: { display: 'flex', gap: 8 } },
React.createElement(Button, { type: 'link', size: 'small', onClick: function () { message.info('编辑:' + (r.plateNo || '')); } }, '编辑'),
React.createElement(Button, { type: 'link', size: 'small', onClick: function () { message.info('查看:' + (r.plateNo || '')); } }, '查看')
);
}
}
];
}, []);
function filterOption(input, opt) {
return String((opt && opt.label) || '').toLowerCase().indexOf(String(input || '').toLowerCase()) !== -1;
}
return React.createElement('div', { style: layoutStyle },
React.createElement('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 16 } },
React.createElement(Breadcrumb, { items: [{ title: '运维管理' }, { title: '车辆管理' }, { title: '证照管理' }] })
),
React.createElement(Card, { title: '筛选与操作区', style: cardStyle },
React.createElement('div', { style: { display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 16 } },
React.createElement('div', { style: { flex: 1 } },
React.createElement('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(4, minmax(0, 1fr))', gap: 12 } },
React.createElement(Select, { placeholder: '请选择客户名称', value: filters.customerName, onChange: function (v) { setFilters(function (p) { var n = {}; for (var k in p) n[k] = p[k]; n.customerName = v; return n; }); }, allowClear: true, showSearch: true, filterOption: filterOption, options: options.customerName }),
React.createElement(Select, { placeholder: '请选择合同编码', value: filters.contractCode, onChange: function (v) { setFilters(function (p) { var n = {}; for (var k in p) n[k] = p[k]; n.contractCode = v; return n; }); }, allowClear: true, showSearch: true, filterOption: filterOption, options: options.contractCode }),
React.createElement(Select, { placeholder: '请选择单车车牌号', value: filters.plateNo, onChange: function (v) { setFilters(function (p) { var n = {}; for (var k in p) n[k] = p[k]; n.plateNo = v; return n; }); }, allowClear: true, showSearch: true, filterOption: filterOption, options: options.plateNo }),
React.createElement(Select, { placeholder: '请选择车辆VIN', value: filters.vin, onChange: function (v) { setFilters(function (p) { var n = {}; for (var k in p) n[k] = p[k]; n.vin = v; return n; }); }, allowClear: true, showSearch: true, filterOption: filterOption, options: options.vin })
),
moreOpenState[0]
? React.createElement('div', { style: { marginTop: 12, display: 'grid', gridTemplateColumns: 'repeat(4, minmax(0, 1fr))', gap: 12 } },
React.createElement(DatePicker, { placeholder: '请选择审验有效期', style: { width: '100%' }, value: filters.licenseInspectValid, onChange: function (v) { setFilters(function (p) { var n = {}; for (var k in p) n[k] = p[k]; n.licenseInspectValid = v; return n; }); } }),
React.createElement(DatePicker, { placeholder: '请选择证件有效期', style: { width: '100%' }, value: filters.operationPermitValid, onChange: function (v) { setFilters(function (p) { var n = {}; for (var k in p) n[k] = p[k]; n.operationPermitValid = v; return n; }); } }),
React.createElement(DatePicker, { placeholder: '请选择有效期', style: { width: '100%' }, value: filters.passPermitValid, onChange: function (v) { setFilters(function (p) { var n = {}; for (var k in p) n[k] = p[k]; n.passPermitValid = v; return n; }); } }),
React.createElement('div', null)
)
: null,
React.createElement('div', { style: { marginTop: 12, display: 'flex', alignItems: 'center', gap: 8 } },
React.createElement(Button, { type: 'link', onClick: function () { moreOpenState[1](!moreOpenState[0]); } }, moreOpenState[0] ? '收起条件 ▲' : '更多条件 ▼'),
React.createElement(Button, { onClick: resetFilters }, '重置'),
React.createElement(Button, { type: 'primary', onClick: handleQuery }, '查询')
)
),
React.createElement('div', { style: { width: 360, display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 10 } },
React.createElement('div', { style: { color: '#666', fontSize: 13 } },
'选中 ', (selectedRowKeysState[0] || []).length, '/', (filteredData || []).length, ' 条'
),
React.createElement('div', { style: { display: 'flex', gap: 8, flexWrap: 'wrap', justifyContent: 'flex-end' } },
React.createElement(Button, { type: 'primary', onClick: openAdd }, '+ 新增'),
React.createElement(Button, { danger: true, disabled: !(selectedRowKeysState[0] || []).length, onClick: confirmDeleteSelected }, '删除'),
React.createElement(Button, { onClick: openExport }, '导出'),
React.createElement(Button, { onClick: openImport }, '导入')
)
)
)
),
React.createElement(Card, { title: '证照列表', style: cardStyle },
React.createElement(Table, {
rowKey: 'key',
size: 'middle',
bordered: true,
columns: columns,
dataSource: filteredData,
rowSelection: {
selectedRowKeys: selectedRowKeysState[0],
onChange: function (keys) { selectedRowKeysState[1](keys || []); }
},
scroll: { x: 2600 },
pagination: { pageSize: 20, showSizeChanger: true, pageSizeOptions: ['20', '50', '100'], showTotal: function (t) { return '共 ' + t + ' 条'; }, showQuickJumper: true }
})
),
React.createElement(Modal, {
title: '证件导入',
open: importOpenState[0],
onCancel: function () { importOpenState[1](false); },
okText: '上传',
cancelText: '取消',
onOk: doImportUpload
},
React.createElement('div', { style: { marginBottom: 12, color: '#666', fontSize: 13 } }, '*支持文件类型 .xls .xlsx'),
React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 10, marginBottom: 12 } },
React.createElement(Button, { onClick: function () { message.info('下载模板:证件信息模板.xlsx原型'); } }, '模板下载'),
React.createElement('input', { type: 'file', accept: '.xls,.xlsx', onChange: onPickImportFile })
),
React.createElement('div', { style: { fontSize: 13, color: '#333' } }, '已选文件:', (importFileState[0] && importFileState[0].name) ? importFileState[0].name : '—')
)
);
};