304 lines
14 KiB
JavaScript
304 lines
14 KiB
JavaScript
// 【重要】必须使用 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 : '—')
|
||
)
|
||
);
|
||
};
|
||
|