Files
ONE-OS/web端/运维管理/车辆业务/调拨管理-接收记录.jsx
王冕 c75d1656e3 web端: 车辆/运维模块更新
- 车辆管理、车辆管理-查看:详情 Tab(后装设备/租赁/事故/违章/异动/调拨/证照管理等)
- 车辆业务:异动管理列表与查看页、调拨相关页面与需求说明
- 需求说明文档补充

Made-with: Cursor
2026-03-19 20:19:48 +08:00

448 lines
17 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 App = antd.App;
var Breadcrumb = antd.Breadcrumb;
var Card = antd.Card;
var Button = antd.Button;
var Input = antd.Input;
var Select = antd.Select;
var DatePicker = antd.DatePicker;
var Table = antd.Table;
var Modal = antd.Modal;
var message = antd.message;
function filterOption(input, option) {
var label = (option && (option.label || option.children)) || '';
return String(label).toLowerCase().indexOf(String(input || '').toLowerCase()) >= 0;
}
function getInitialReceiveDate() {
return null;
}
var layoutStyle = { padding: '16px 24px', background: '#f5f5f5', minHeight: '100vh' };
var labelStyle = { marginBottom: 6, fontSize: 14, color: 'rgba(0,0,0,0.65)' };
var formItemStyle = { marginBottom: 12 };
var controlStyle = { width: '100%' };
var reqStarStyle = { color: '#ff4d4f', marginRight: 4 };
var reqStar = React.createElement('span', { style: reqStarStyle }, '*');
var vehicleDb = useMemo(function () {
return [
{ plateNo: '粤A12345', vehicleType: '厢式货车', brand: '东风', model: 'DFH1180', departParking: '天河智慧停车场', h2Unit: 'MPa' },
{ plateNo: '粤B11111', vehicleType: '轿车', brand: '比亚迪', model: '汉', departParking: '南山科技园停车场', h2Unit: '%' },
{ plateNo: '浙A11111', vehicleType: 'SUV', brand: '小鹏', model: 'P7', departParking: '西湖景区停车场', h2Unit: '%' },
{ plateNo: '浙B22222', vehicleType: '轿车', brand: '蔚来', model: 'ET5', departParking: '宁波江北停车场', h2Unit: 'MPa' },
{ plateNo: '沪A30003', vehicleType: '厢式货车', brand: '福田', model: 'BJ1180', departParking: '张江园区停车场', h2Unit: 'MPa' }
];
}, []);
// 调拨单带出:按车牌匹配的出发读数(切换车牌时同步)
var departSnapshotByPlate = useMemo(function () {
return {
'粤A12345': { departMileageKm: '15230.12', departHydrogen: '28.30', h2Unit: 'MPa', departElectricKwh: '68.40' },
'粤B11111': { departMileageKm: '8020.50', departHydrogen: '55.00', h2Unit: '%', departElectricKwh: '62.10' },
'浙A11111': { departMileageKm: '12010.00', departHydrogen: '60.00', h2Unit: '%', departElectricKwh: '55.20' },
'浙B22222': { departMileageKm: '15010.00', departHydrogen: '22.10', h2Unit: 'MPa', departElectricKwh: '58.00' },
'沪A30003': { departMileageKm: '9800.00', departHydrogen: '26.00', h2Unit: 'MPa', departElectricKwh: '69.00' }
};
}, []);
var plateOptions = useMemo(function () {
return vehicleDb.map(function (v) { return { value: v.plateNo, label: v.plateNo }; });
}, [vehicleDb]);
var situationState = useState({
transferDateStr: '2026-02-20',
departRegionText: '广东省-广州市',
receiveRegionText: '浙江省-杭州市',
receivePerson: '王芳',
method: '第三方运输',
reason: '场站资源调整,车辆调度至杭州项目点。',
carrierName: '顺丰同城运输',
carrierPhone: '400-123-4567',
receiveDate: getInitialReceiveDate()
});
var situation = situationState[0];
var setSituation = situationState[1];
var errorsState = useState({});
var errors = errorsState[0];
var setErrors = errorsState[1];
var requirementModalState = useState(false);
var requirementModalOpen = requirementModalState[0];
var setRequirementModalOpen = requirementModalState[1];
var requirementDocContent = [
'一个「数字化资产ONEOS运管平台」中的「调拨管理」「接收记录」模块',
'#面包屑:运维管理-车辆业务-调拨管理-接收记录',
'页面采用多个卡片的方式进行展示',
'1.调拨情况:',
'1.1.调拨日期显示调拨日期格式为YYYY-MM-DD',
'1.2.出发区域:显示出发区域,格式为省-市2级',
'1.3.接收区域:显示接收区域,格式为省-市2级',
'1.4.接收人:显示接收人姓名;',
'1.5.调拨方式:显示调拨方式,选项为:第三方运输、司机驾驶;',
'1.6.调拨原因:显示调拨原因;',
'1.7.运输方名称:显示运输方名称;',
'1.8.运输方联系方式:显示运输方联系方式;',
'1.9.接收日期:日期选择器,精确至天;',
'',
'2.调拨车辆清单;',
'#以列表方式展示:',
'2.1.车牌号:显示车牌号,支持输入框模糊搜索下拉匹配对应选项;',
'2.2.车辆类型:根据所选车辆类型自动反写,默认提示为请先选择车辆;',
'2.3.品牌:根据所选车辆品牌自动反写,默认提示为请先选择车辆;',
'2.4.型号:根据所选车辆型号自动反写,默认提示为请先选择车辆;',
'2.5.出发停车场:根据所选车辆出发时停车场自动反写,默认提示为请先选择车辆;',
'2.6.出发里程显示出发里程输入框精确至2位小数后缀为km',
'2.7.接收里程必填项输入框精确至2位小数后缀为km',
'2.8.出发氢量显示出发氢量输入框精确至2位小数后缀为%或MPa根据所选车辆型号中获取',
'2.9.接收氢量必填项输入框精确至2位小数后缀为%或MPa根据所选车辆型号中获取',
'2.10.出发电量显示出发电量输入框精确至2位小数后缀为kWh',
'2.11.接收电量必填项输入框精确至2位小数后缀为kWh',
'2.12.操作:无;'
].join('\n');
var vehiclesState = useState([
{
id: 1,
plateNo: '粤A12345',
vehicleType: '厢式货车',
brand: '东风',
model: 'DFH1180',
departParking: '天河智慧停车场',
departMileageKm: '15230.12',
departHydrogen: '28.30',
h2Unit: 'MPa',
departElectricKwh: '68.40',
receiveMileageKm: '',
receiveHydrogen: '',
receiveElectricKwh: ''
},
{
id: 2,
plateNo: '浙A11111',
vehicleType: 'SUV',
brand: '小鹏',
model: 'P7',
departParking: '西湖景区停车场',
departMileageKm: '12010.00',
departHydrogen: '60.00',
h2Unit: '%',
departElectricKwh: '55.20',
receiveMileageKm: '',
receiveHydrogen: '',
receiveElectricKwh: ''
}
]);
var vehicles = vehiclesState[0];
var setVehicles = vehiclesState[1];
function toFixed2Input(v) {
var s = String(v === null || v === undefined ? '' : v);
s = s.replace(/[^\d.]/g, '');
var firstDot = s.indexOf('.');
if (firstDot >= 0) {
s = s.slice(0, firstDot + 1) + s.slice(firstDot + 1).replace(/\./g, '');
}
if (firstDot >= 0) {
var a = s.split('.');
s = a[0] + '.' + (a[1] || '').slice(0, 2);
}
return s;
}
var updateRow = useCallback(function (index, patch) {
setVehicles(function (prev) {
var list = prev.slice();
var cur = list[index] || {};
list[index] = Object.assign({}, cur, patch);
return list;
});
}, []);
var handlePlateChange = useCallback(function (index, plateNo) {
var v = vehicleDb.find(function (x) { return x.plateNo === plateNo; });
var snap = departSnapshotByPlate[plateNo] || {};
updateRow(index, {
plateNo: plateNo,
vehicleType: v ? v.vehicleType : '',
brand: v ? v.brand : '',
model: v ? v.model : '',
departParking: v ? v.departParking : '',
h2Unit: v ? v.h2Unit : (snap.h2Unit || ''),
departMileageKm: snap.departMileageKm != null ? String(snap.departMileageKm) : '',
departHydrogen: snap.departHydrogen != null ? String(snap.departHydrogen) : '',
departElectricKwh: snap.departElectricKwh != null ? String(snap.departElectricKwh) : ''
});
}, [vehicleDb, departSnapshotByPlate, updateRow]);
function validate() {
var e = {};
if (!situation.receiveDate) e.receiveDate = '请选择接收日期';
for (var i = 0; i < (vehicles || []).length; i++) {
var r = vehicles[i] || {};
if (!String(r.plateNo || '').trim()) continue;
if (!String(r.receiveMileageKm || '').trim()) e['row_' + i + '_receiveMileageKm'] = '请输入接收里程';
if (!String(r.receiveHydrogen || '').trim()) e['row_' + i + '_receiveHydrogen'] = '请输入接收氢量';
if (!String(r.receiveElectricKwh || '').trim()) e['row_' + i + '_receiveElectricKwh'] = '请输入接收电量';
}
setErrors(e);
return Object.keys(e).length === 0;
}
var handleSubmit = useCallback(function () {
if (!validate()) {
message.error('请完善接收日期及车辆接收信息');
return;
}
Modal.confirm({
title: '确认提交接收记录?',
content: '提交后接收数据将归档(原型)。',
okText: '确定',
cancelText: '取消',
onOk: function () {
message.success('接收记录已提交(原型)');
}
});
}, [situation, vehicles]);
var handleBack = useCallback(function () {
message.info('返回调拨管理页(原型)');
}, []);
var vehicleColumns = useMemo(function () {
return [
{
title: '车牌号',
key: 'plateNo',
width: 130,
render: function (_, r, index) {
return React.createElement(Select, {
placeholder: '请输入或选择车牌号',
style: { width: '100%' },
value: r.plateNo,
onChange: function (v) { handlePlateChange(index, v); },
allowClear: true,
showSearch: true,
options: plateOptions,
filterOption: filterOption
});
}
},
{
title: '车辆类型',
key: 'vehicleType',
width: 110,
render: function (_, r) {
return React.createElement(Input, { value: r.vehicleType ? r.vehicleType : '请先选择车辆', disabled: true });
}
},
{
title: '品牌',
key: 'brand',
width: 90,
render: function (_, r) {
return React.createElement(Input, { value: r.brand ? r.brand : '请先选择车辆', disabled: true });
}
},
{
title: '型号',
key: 'model',
width: 110,
render: function (_, r) {
return React.createElement(Input, { value: r.model ? r.model : '请先选择车辆', disabled: true });
}
},
{
title: '出发停车场',
key: 'departParking',
width: 140,
render: function (_, r) {
return React.createElement(Input, { value: r.departParking ? r.departParking : '请先选择车辆', disabled: true });
}
},
{
title: '出发里程',
key: 'departMileageKm',
width: 120,
render: function (_, r) {
return React.createElement(Input, { value: r.departMileageKm || '', disabled: true, addonAfter: 'km' });
}
},
{
title: React.createElement('span', null, reqStar, '接收里程'),
key: 'receiveMileageKm',
width: 120,
render: function (_, r, index) {
var k = 'row_' + index + '_receiveMileageKm';
return React.createElement(Input, {
value: r.receiveMileageKm,
onChange: function (e) { updateRow(index, { receiveMileageKm: toFixed2Input(e.target.value) }); },
placeholder: '0.00',
addonAfter: 'km',
status: errors[k] ? 'error' : undefined
});
}
},
{
title: '出发氢量',
key: 'departHydrogen',
width: 120,
render: function (_, r) {
var unit = r.h2Unit || '';
return React.createElement(Input, { value: r.departHydrogen || '', disabled: true, addonAfter: unit || '-' });
}
},
{
title: React.createElement('span', null, reqStar, '接收氢量'),
key: 'receiveHydrogen',
width: 120,
render: function (_, r, index) {
var k = 'row_' + index + '_receiveHydrogen';
var unit = r.h2Unit || '%/MPa';
return React.createElement(Input, {
value: r.receiveHydrogen,
onChange: function (e) { updateRow(index, { receiveHydrogen: toFixed2Input(e.target.value) }); },
placeholder: '0.00',
addonAfter: unit,
status: errors[k] ? 'error' : undefined
});
}
},
{
title: '出发电量',
key: 'departElectricKwh',
width: 120,
render: function (_, r) {
return React.createElement(Input, { value: r.departElectricKwh || '', disabled: true, addonAfter: 'kWh' });
}
},
{
title: React.createElement('span', null, reqStar, '接收电量'),
key: 'receiveElectricKwh',
width: 120,
render: function (_, r, index) {
var k = 'row_' + index + '_receiveElectricKwh';
return React.createElement(Input, {
value: r.receiveElectricKwh,
onChange: function (e) { updateRow(index, { receiveElectricKwh: toFixed2Input(e.target.value) }); },
placeholder: '0.00',
addonAfter: 'kWh',
status: errors[k] ? 'error' : undefined
});
}
}
];
}, [plateOptions, errors, handlePlateChange, updateRow]);
return React.createElement(App, null,
React.createElement('div', { style: layoutStyle },
React.createElement('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 16, flexWrap: 'wrap', gap: 8 } },
React.createElement(Breadcrumb, { items: [{ title: '运维管理' }, { title: '车辆业务' }, { title: '调拨管理' }, { title: '接收记录' }] }),
React.createElement(Button, { type: 'link', style: { padding: 0 }, onClick: function () { setRequirementModalOpen(true); } }, '查看需求说明')
),
React.createElement(Modal, {
title: '需求说明',
open: requirementModalOpen,
onCancel: function () { setRequirementModalOpen(false); },
width: 720,
footer: React.createElement(Button, { onClick: function () { setRequirementModalOpen(false); } }, '关闭'),
bodyStyle: { maxHeight: '70vh', overflow: 'auto' }
}, React.createElement('div', { style: { whiteSpace: 'pre-wrap', fontSize: 13, lineHeight: 1.6, color: 'rgba(0,0,0,0.85)' } }, requirementDocContent)),
React.createElement(Card, { title: '调拨情况', style: { marginBottom: 16 } },
React.createElement('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: '16px 24px', alignItems: 'start' } },
React.createElement('div', { style: formItemStyle },
React.createElement('div', { style: labelStyle }, '调拨日期'),
React.createElement(Input, { value: situation.transferDateStr, disabled: true, style: controlStyle })
),
React.createElement('div', { style: formItemStyle },
React.createElement('div', { style: labelStyle }, '出发区域'),
React.createElement(Input, { value: situation.departRegionText, disabled: true, style: controlStyle })
),
React.createElement('div', { style: formItemStyle },
React.createElement('div', { style: labelStyle }, '接收区域'),
React.createElement(Input, { value: situation.receiveRegionText, disabled: true, style: controlStyle })
),
React.createElement('div', { style: formItemStyle },
React.createElement('div', { style: labelStyle }, '接收人'),
React.createElement(Input, { value: situation.receivePerson, disabled: true, style: controlStyle })
),
React.createElement('div', { style: formItemStyle },
React.createElement('div', { style: labelStyle }, '调拨方式'),
React.createElement(Input, { value: situation.method, disabled: true, style: controlStyle })
),
React.createElement('div', { style: formItemStyle }),
React.createElement('div', { style: Object.assign({}, formItemStyle, { gridColumn: 'span 3' }) },
React.createElement('div', { style: labelStyle }, '调拨原因'),
React.createElement(Input.TextArea, { value: situation.reason, disabled: true, autoSize: { minRows: 2, maxRows: 4 } })
),
React.createElement('div', { style: formItemStyle },
React.createElement('div', { style: labelStyle }, '运输方名称'),
React.createElement(Input, { value: situation.carrierName, disabled: true, style: controlStyle })
),
React.createElement('div', { style: formItemStyle },
React.createElement('div', { style: labelStyle }, '运输方联系方式'),
React.createElement(Input, { value: situation.carrierPhone, disabled: true, style: controlStyle })
),
React.createElement('div', { style: formItemStyle },
React.createElement('div', { style: labelStyle }, reqStar, '接收日期'),
React.createElement(DatePicker, {
style: controlStyle,
format: 'YYYY-MM-DD',
placeholder: '请选择接收日期',
value: situation.receiveDate,
onChange: function (v) { setSituation(function (p) { return Object.assign({}, p, { receiveDate: v }); }); },
status: errors.receiveDate ? 'error' : undefined
}),
errors.receiveDate ? React.createElement('div', { style: { marginTop: 4, color: '#ff4d4f', fontSize: 12 } }, errors.receiveDate) : null
)
)
),
React.createElement(Card, { title: '调拨车辆清单', style: { marginBottom: 16 } },
React.createElement(Table, {
rowKey: 'id',
columns: vehicleColumns,
dataSource: vehicles,
size: 'small',
pagination: false,
scroll: { x: 1400 }
})
),
React.createElement('div', { style: { height: 56 } }),
React.createElement('div', {
style: {
position: 'fixed',
left: 0,
right: 0,
bottom: 0,
padding: '12px 24px',
background: '#fff',
borderTop: '1px solid #f0f0f0',
display: 'flex',
gap: 8,
zIndex: 10
}
},
React.createElement(Button, { type: 'primary', onClick: handleSubmit }, '提交'),
React.createElement(Button, { onClick: handleBack }, '返回')
)
)
);
};