feat(web): 同步 web 端目录更新至 Gitea
包含加氢站站点信息、运维交车/故障、台账与数据分析等页面新增与改动。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -48,22 +48,36 @@ const Component = function () {
|
||||
|
||||
// 交车明细列表(序号、品牌、型号、车牌号可编辑、实际交车日期、交车人、交车状态、操作)
|
||||
var detailListState = useState([
|
||||
{ key: 1, seq: 1, brand: '东风', model: 'DFH1180', plateNo: '京A12345', actualDate: '2025-02-28', deliveryPerson: '张三', status: '已签章' },
|
||||
{ key: 2, seq: 2, brand: '东风', model: 'DFH1250', plateNo: '京C11111', actualDate: '2025-02-28', deliveryPerson: '张三', status: '已签章' },
|
||||
{ key: 3, seq: 3, brand: '福田', model: 'BJ1180', plateNo: '浙A10001', actualDate: '2025-03-01', deliveryPerson: '李四', status: '已签章' },
|
||||
{ key: 4, seq: 4, brand: '福田', model: 'BJ1250', plateNo: '浙F80088', actualDate: '2025-03-01', deliveryPerson: '李四', status: '已签章' },
|
||||
{ key: 5, seq: 5, brand: '重汽', model: 'HOWO-T5G', plateNo: '沪A30003', actualDate: '2025-03-02', deliveryPerson: '王五', status: '已签章' },
|
||||
{ key: 6, seq: 6, brand: '陕汽', model: '德龙X3000', plateNo: '京D22222', actualDate: '2025-03-02', deliveryPerson: '王五', status: '已完成' },
|
||||
{ key: 7, seq: 7, brand: '解放', model: 'J6P', plateNo: '', actualDate: '', deliveryPerson: '', status: '待提交' },
|
||||
{ key: 8, seq: 8, brand: '欧曼', model: 'EST-A', plateNo: '', actualDate: '', deliveryPerson: '', status: '待提交' },
|
||||
{ key: 9, seq: 9, brand: '江淮', model: '格尔发K7', plateNo: '', actualDate: '', deliveryPerson: '', status: '待提交' },
|
||||
{ key: 10, seq: 10, brand: '红岩', model: '杰狮C6', plateNo: '', actualDate: '', deliveryPerson: '', status: '待提交' }
|
||||
{ key: 1, seq: 1, brand: '东风', model: 'DFH1180', plateNo: '京A12345', actualDate: '2025-02-28', deliveryPerson: '张三', status: '客户已签章' },
|
||||
{ key: 2, seq: 2, brand: '东风', model: 'DFH1250', plateNo: '京C11111', actualDate: '2025-02-28', deliveryPerson: '张三', status: '客户已签章' },
|
||||
{ key: 3, seq: 3, brand: '福田', model: 'BJ1180', plateNo: '浙A10001', actualDate: '2025-03-01', deliveryPerson: '李四', status: '待客户签章' },
|
||||
{ key: 4, seq: 4, brand: '福田', model: 'BJ1250', plateNo: '浙F80088', actualDate: '2025-03-01', deliveryPerson: '李四', status: '待客户签章' },
|
||||
{ key: 5, seq: 5, brand: '重汽', model: 'HOWO-T5G', plateNo: '沪A30003', actualDate: '2025-03-02', deliveryPerson: '王五', status: '已保存' },
|
||||
{ key: 6, seq: 6, brand: '陕汽', model: '德龙X3000', plateNo: '京D22222', actualDate: '2025-03-02', deliveryPerson: '王五', status: '已保存' },
|
||||
{ key: 7, seq: 7, brand: '解放', model: 'J6P', plateNo: '', actualDate: '', deliveryPerson: '', status: '未开始' },
|
||||
{ key: 8, seq: 8, brand: '欧曼', model: 'EST-A', plateNo: '', actualDate: '', deliveryPerson: '', status: '未开始' },
|
||||
{ key: 9, seq: 9, brand: '江淮', model: '格尔发K7', plateNo: '', actualDate: '', deliveryPerson: '', status: '未开始' },
|
||||
{ key: 10, seq: 10, brand: '红岩', model: '杰狮C6', plateNo: '', actualDate: '', deliveryPerson: '', status: '未开始' }
|
||||
]);
|
||||
var detailList = detailListState[0];
|
||||
var setDetailList = detailListState[1];
|
||||
|
||||
var allSigned = useMemo(function () {
|
||||
return detailList.length > 0 && detailList.every(function (row) { return row.status === '已签章'; });
|
||||
function isDetailHistoryStatus(status) {
|
||||
return status === '客户已签章' || status === '已签章';
|
||||
}
|
||||
|
||||
function canEditDetailRow(record) {
|
||||
var s = record.status;
|
||||
return s === '未开始' || s === '已保存';
|
||||
}
|
||||
|
||||
function hasPlateSelected(record) {
|
||||
var p = record.plateNo;
|
||||
return p && String(p).trim() !== '' && p !== '-';
|
||||
}
|
||||
|
||||
var allCustomerSigned = useMemo(function () {
|
||||
return detailList.length > 0 && detailList.every(function (row) { return isDetailHistoryStatus(row.status); });
|
||||
}, [detailList]);
|
||||
|
||||
var updateDetailRow = useCallback(function (index, field, value) {
|
||||
@@ -76,10 +90,10 @@ const Component = function () {
|
||||
}, []);
|
||||
|
||||
var handleSubmit = useCallback(function () {
|
||||
if (!allSigned) return;
|
||||
if (!allCustomerSigned) return;
|
||||
message.success('提交成功(原型)');
|
||||
if (typeof window !== 'undefined' && window.history) window.history.back();
|
||||
}, [allSigned]);
|
||||
}, [allCustomerSigned]);
|
||||
|
||||
var handleCancel = useCallback(function () {
|
||||
if (typeof window !== 'undefined' && window.history) window.history.back();
|
||||
@@ -140,12 +154,11 @@ const Component = function () {
|
||||
dataIndex: 'plateNo',
|
||||
key: 'plateNo',
|
||||
width: 120,
|
||||
render: function (v, record, index) {
|
||||
var isDelivered = record.status === '已签章' || record.status === '已完成';
|
||||
if (isDelivered) {
|
||||
render: function (v, record) {
|
||||
if (hasPlateSelected(record)) {
|
||||
return React.createElement(Input, { value: v || '', disabled: true, style: { width: '100%', background: '#f5f5f5' } });
|
||||
}
|
||||
return React.createElement(Input, { value: '-', disabled: true, style: { width: '100%', background: '#f5f5f5' } });
|
||||
return React.createElement(Input, { value: '车牌待选', disabled: true, style: { width: '100%', background: '#f5f5f5', color: '#d48806' } });
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -162,7 +175,7 @@ const Component = function () {
|
||||
width: 90,
|
||||
render: function (v) { return React.createElement(Input, { value: v || '', disabled: true, style: { width: '100%', background: '#f5f5f5' } }); }
|
||||
},
|
||||
{ title: '交车状态', dataIndex: 'status', key: 'status', width: 90, render: function (v) { return v || '-'; } },
|
||||
{ title: '交车状态', dataIndex: 'status', key: 'status', width: 108, render: function (v) { return v || '-'; } },
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
@@ -171,8 +184,8 @@ const Component = function () {
|
||||
render: function (_, record, index) {
|
||||
return React.createElement(React.Fragment, null,
|
||||
React.createElement(Button, { type: 'link', size: 'small', onClick: function () { handleViewDetail(record); } }, '查看'),
|
||||
record.status === '待提交' ? React.createElement(Button, { type: 'link', size: 'small', onClick: function () { handleEditDetail(record, index); } }, '编辑') : null,
|
||||
record.status === '已签章' ? React.createElement(Button, { type: 'link', size: 'small', onClick: function () { handleDownloadSign(record); } }, '下载签章文件') : null
|
||||
canEditDetailRow(record) ? React.createElement(Button, { type: 'link', size: 'small', onClick: function () { handleEditDetail(record, index); } }, '编辑') : null,
|
||||
isDetailHistoryStatus(record.status) ? React.createElement(Button, { type: 'link', size: 'small', onClick: function () { handleDownloadSign(record); } }, '下载签章文件') : null
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -214,7 +227,7 @@ const Component = function () {
|
||||
|
||||
React.createElement('div', { style: { height: 60 } }),
|
||||
React.createElement('div', { style: styles.footer },
|
||||
React.createElement(Button, { type: 'primary', disabled: !allSigned, onClick: handleSubmit }, '提交'),
|
||||
React.createElement(Button, { type: 'primary', disabled: !allCustomerSigned, onClick: handleSubmit }, '提交'),
|
||||
React.createElement(Button, { onClick: handleCancel }, '取消')
|
||||
),
|
||||
|
||||
|
||||
503
web端/运维管理/车辆业务/交车管理-编辑抽屉.jsx
Normal file
503
web端/运维管理/车辆业务/交车管理-编辑抽屉.jsx
Normal file
@@ -0,0 +1,503 @@
|
||||
// 交车管理 - 列表内编辑抽屉(参照 交车管理-交车单-编辑.jsx)
|
||||
// 使用方式:window.DeliveryEditDrawer(props)
|
||||
|
||||
function DeliveryEditDrawer(props) {
|
||||
var useState = React.useState;
|
||||
var useMemo = React.useMemo;
|
||||
var useCallback = React.useCallback;
|
||||
var useRef = React.useRef;
|
||||
var useEffect = React.useEffect;
|
||||
|
||||
var open = props.open;
|
||||
var record = props.record;
|
||||
var onClose = props.onClose;
|
||||
var onSave = props.onSave;
|
||||
var onSubmit = props.onSubmit;
|
||||
|
||||
var antd = window.antd;
|
||||
var Drawer = antd.Drawer;
|
||||
var Button = antd.Button;
|
||||
var Input = antd.Input;
|
||||
var Select = antd.Select;
|
||||
var Switch = antd.Switch;
|
||||
var Modal = antd.Modal;
|
||||
var Table = antd.Table;
|
||||
var Tag = antd.Tag;
|
||||
var message = antd.message;
|
||||
|
||||
function RequiredLabel(text) {
|
||||
return React.createElement('span', { style: { display: 'inline-flex', alignItems: 'center', gap: 4 } },
|
||||
React.createElement('span', { style: { color: '#ef4444', fontWeight: 600 } }, '*'),
|
||||
React.createElement('span', null, text)
|
||||
);
|
||||
}
|
||||
|
||||
function isEmpty(v) {
|
||||
return v === null || v === undefined || String(v).trim() === '';
|
||||
}
|
||||
|
||||
function filterOption(input, option) {
|
||||
var label = (option && (option.label || option.children)) || '';
|
||||
return String(label).toLowerCase().indexOf(String(input || '').toLowerCase()) >= 0;
|
||||
}
|
||||
|
||||
function fileToDataUrl(file, cb) {
|
||||
try {
|
||||
var reader = new FileReader();
|
||||
reader.onload = function (e) { cb(null, (e && e.target && e.target.result) || ''); };
|
||||
reader.onerror = function () { cb(new Error('read error')); };
|
||||
reader.readAsDataURL(file);
|
||||
} catch (e) { cb(e); }
|
||||
}
|
||||
|
||||
var reserveVehicles = useMemo(function () {
|
||||
return [
|
||||
{ plateNo: '京A12345', vehicleType: '牵引车', brand: '东风', model: 'DFH1180', vin: 'LJNAU1A2XK1234567', hasAd: true, adPhoto: [{ uid: 'ad1', name: '广告照片.jpg', url: 'https://dummyimage.com/600x400/e2e8f0/475569&text=Ad' }], bigWordPhoto: [{ uid: 'bw1', name: '放大字.jpg', url: 'https://dummyimage.com/600x400/e2e8f0/475569&text=BigWord' }], hasTailboard: true },
|
||||
{ plateNo: '浙F80088', vehicleType: '厢式车', brand: '福田', model: 'BJ1180', vin: 'LJNAU1A2XK7654321', hasAd: false, adPhoto: [], bigWordPhoto: [], hasTailboard: false },
|
||||
{ plateNo: '沪A30003', vehicleType: '厢式车', brand: '重汽', model: 'HOWO-T5G', vin: 'LJNAU1A2XK9999000', hasAd: true, adPhoto: [{ uid: 'ad2', name: '广告2.jpg', url: 'https://dummyimage.com/600x400/e2e8f0/475569&text=Ad2' }], bigWordPhoto: [{ uid: 'bw2', name: '放大字2.jpg', url: 'https://dummyimage.com/600x400/e2e8f0/475569&text=BW2' }], hasTailboard: true },
|
||||
{ plateNo: '粤AGP4598', vehicleType: '4.5吨冷链车', brand: '现代', model: '帕力安牌4.5吨冷链车', vin: 'LNBSCPKB9RR223402', hasAd: false, adPhoto: [], bigWordPhoto: [], hasTailboard: false }
|
||||
];
|
||||
}, []);
|
||||
|
||||
var plateOptions = useMemo(function () {
|
||||
return reserveVehicles.map(function (v) { return { value: v.plateNo, label: v.plateNo }; });
|
||||
}, [reserveVehicles]);
|
||||
|
||||
var vehicleByPlate = useMemo(function () {
|
||||
var map = {};
|
||||
reserveVehicles.forEach(function (v) { map[v.plateNo] = v; });
|
||||
return map;
|
||||
}, [reserveVehicles]);
|
||||
|
||||
function buildInitialForm(rec) {
|
||||
var plate = (rec && rec.plateNo && String(rec.plateNo).trim()) || undefined;
|
||||
var veh = plate ? vehicleByPlate[plate] : null;
|
||||
if (!veh && rec && rec.brand) {
|
||||
veh = { plateNo: plate, vehicleType: rec.vehicleType || '', brand: rec.brand || '', model: rec.model || '', vin: rec.vin || '', hasAd: false, adPhoto: [], bigWordPhoto: [], hasTailboard: false };
|
||||
}
|
||||
return {
|
||||
plateNo: plate,
|
||||
vehicleType: (veh && veh.vehicleType) || (rec && rec.vehicleType) || '',
|
||||
brand: (veh && veh.brand) || (rec && rec.brand) || '',
|
||||
model: (veh && veh.model) || (rec && rec.model) || '',
|
||||
vin: (veh && veh.vin) || (rec && rec.vin) || '',
|
||||
hasAd: !!(veh && veh.hasAd),
|
||||
adPhoto: (veh && veh.adPhoto) || [],
|
||||
bigWordPhoto: (veh && veh.bigWordPhoto) || [],
|
||||
hasTailboard: !!(veh && veh.hasTailboard),
|
||||
spareTirePhoto: [],
|
||||
spareTireDepth: '',
|
||||
trainingRecognized: false,
|
||||
driverLicenses: [],
|
||||
mileageKm: rec && rec.deliveryMileage != null ? String(rec.deliveryMileage) : '',
|
||||
batteryPct: rec && rec.deliveryElec != null ? String(rec.deliveryElec) : '',
|
||||
hydrogenAmount: rec && rec.deliveryH2 != null ? String(rec.deliveryH2) : '',
|
||||
hydrogenUnit: (rec && rec.deliveryH2Unit === 'MPa') ? 'MPa' : '%',
|
||||
serviceFee: ''
|
||||
};
|
||||
}
|
||||
|
||||
var formState = useState(buildInitialForm(null));
|
||||
var form = formState[0];
|
||||
var setForm = formState[1];
|
||||
var activeSectionState = useState('basic');
|
||||
var activeSection = activeSectionState[0];
|
||||
var setActiveSection = activeSectionState[1];
|
||||
var submittingState = useState(false);
|
||||
var submitting = submittingState[0];
|
||||
var setSubmitting = submittingState[1];
|
||||
var previewState = useState({ open: false, url: '', title: '' });
|
||||
var ocrModalState = useState({ open: false, photoUrl: '', depth: '6.50' });
|
||||
var inspectionOpenState = useState(false);
|
||||
var trainingInputRef = useRef(null);
|
||||
|
||||
useEffect(function () {
|
||||
if (open && record) {
|
||||
setForm(buildInitialForm(record));
|
||||
setActiveSection('basic');
|
||||
setSubmitting(false);
|
||||
}
|
||||
}, [open, record && record.id]);
|
||||
|
||||
function updateForm(patch) {
|
||||
setForm(function (p) { return Object.assign({}, p, patch); });
|
||||
}
|
||||
|
||||
function handlePlateChange(v) {
|
||||
var veh = vehicleByPlate[v];
|
||||
updateForm({
|
||||
plateNo: v,
|
||||
vehicleType: (veh && veh.vehicleType) || '',
|
||||
brand: (veh && veh.brand) || '',
|
||||
model: (veh && veh.model) || '',
|
||||
vin: (veh && veh.vin) || '',
|
||||
hasAd: !!(veh && veh.hasAd),
|
||||
adPhoto: (veh && (veh.adPhoto || [])) || [],
|
||||
bigWordPhoto: (veh && (veh.bigWordPhoto || [])) || [],
|
||||
hasTailboard: !!(veh && veh.hasTailboard),
|
||||
spareTirePhoto: [],
|
||||
spareTireDepth: '',
|
||||
trainingRecognized: false,
|
||||
driverLicenses: []
|
||||
});
|
||||
}
|
||||
|
||||
function makeThumb(url, onPreview, onRemove) {
|
||||
return React.createElement('div', { style: { width: 72, height: 72, borderRadius: 8, border: '1px solid #e2e8f0', overflow: 'hidden', position: 'relative', background: '#f8fafc' } },
|
||||
React.createElement('img', { src: url, style: { width: '100%', height: '100%', objectFit: 'cover', cursor: 'pointer' }, onClick: onPreview }),
|
||||
onRemove ? React.createElement('button', {
|
||||
type: 'button',
|
||||
'aria-label': '删除图片',
|
||||
style: { position: 'absolute', right: 4, top: 4, width: 22, height: 22, borderRadius: 999, border: 'none', background: 'rgba(15,23,42,.65)', color: '#fff', cursor: 'pointer', fontSize: 12, lineHeight: '22px', padding: 0 },
|
||||
onClick: function (e) { e.stopPropagation(); onRemove(); }
|
||||
}, '×') : null
|
||||
);
|
||||
}
|
||||
|
||||
function UploadBox(uploadProps) {
|
||||
var label = uploadProps.label;
|
||||
var value = uploadProps.value || [];
|
||||
var max = uploadProps.max || 1;
|
||||
var onChange = uploadProps.onChange;
|
||||
function handlePick(e) {
|
||||
var f = e && e.target && e.target.files && e.target.files[0];
|
||||
if (!f) return;
|
||||
fileToDataUrl(f, function (err, url) {
|
||||
if (err) { message.error('上传失败'); return; }
|
||||
var next = value.slice();
|
||||
next.push({ uid: String(Date.now()), name: f.name || 'image', url: url });
|
||||
if (next.length > max) next = next.slice(next.length - max);
|
||||
onChange && onChange(next);
|
||||
});
|
||||
e.target.value = '';
|
||||
}
|
||||
return React.createElement('div', null,
|
||||
label ? React.createElement('div', { style: { fontSize: 13, color: '#475569', marginBottom: 8, fontWeight: 500 } }, label) : null,
|
||||
React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' } },
|
||||
value.map(function (f) {
|
||||
return React.createElement('div', { key: f.uid },
|
||||
makeThumb(f.url, function () { previewState[1]({ open: true, url: f.url, title: f.name }); }, function () { onChange && onChange(value.filter(function (x) { return x.uid !== f.uid; })); })
|
||||
);
|
||||
}),
|
||||
value.length >= max ? null : React.createElement('label', { style: { width: 72, height: 72, borderRadius: 8, border: '1px dashed #cbd5e1', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#64748b', cursor: 'pointer', fontSize: 13, background: '#fff', transition: 'border-color .2s' } },
|
||||
React.createElement('input', { type: 'file', accept: 'image/*', style: { display: 'none' }, onChange: handlePick }),
|
||||
'上传'
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function FormItem(itemProps) {
|
||||
return React.createElement('div', { style: { marginBottom: 16, minWidth: 0 } },
|
||||
React.createElement('div', { style: { fontSize: 13, color: '#475569', marginBottom: 6, fontWeight: 500 } },
|
||||
itemProps.required ? RequiredLabel(itemProps.label) : itemProps.label
|
||||
),
|
||||
itemProps.children
|
||||
);
|
||||
}
|
||||
|
||||
var inspectionListState = useState([{ key: 'ins-1', category: '车灯', item: '大灯', checked: true, treadDepth: '', remark: '' }]);
|
||||
var inspectionList = inspectionListState[0];
|
||||
|
||||
var sectionNav = [
|
||||
{ key: 'basic', label: '车辆信息' },
|
||||
{ key: 'equip', label: '设备证照' },
|
||||
{ key: 'metrics', label: '交车数据' },
|
||||
{ key: 'photos', label: '交车照片' }
|
||||
];
|
||||
|
||||
function scrollToSection(key) {
|
||||
setActiveSection(key);
|
||||
var el = document.getElementById('dv-edit-section-' + key);
|
||||
if (el && el.scrollIntoView) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
}
|
||||
|
||||
function validateSubmit() {
|
||||
if (isEmpty(form.plateNo)) return '请选择车牌号';
|
||||
if (form.hasAd) {
|
||||
if (!form.adPhoto.length) return '请上传广告照片';
|
||||
if (!form.bigWordPhoto.length) return '请上传放大字照片';
|
||||
}
|
||||
if (!form.spareTirePhoto.length) return '请上传备胎照片';
|
||||
if (isEmpty(form.spareTireDepth)) return '请填写备胎胎纹深度';
|
||||
if (!form.trainingRecognized) return '请上传验车码并完成识别';
|
||||
if (isEmpty(form.mileageKm)) return '请填写交车里程';
|
||||
if (isEmpty(form.batteryPct)) return '请填写交车电量';
|
||||
if (isEmpty(form.hydrogenAmount)) return '请填写交车氢量';
|
||||
return '';
|
||||
}
|
||||
|
||||
function buildPatchFromForm() {
|
||||
return {
|
||||
plateNo: form.plateNo || '',
|
||||
vehicleType: form.vehicleType,
|
||||
brand: form.brand,
|
||||
model: form.model,
|
||||
vin: form.vin,
|
||||
deliveryMileage: form.mileageKm === '' ? null : Number(form.mileageKm),
|
||||
deliveryElec: form.batteryPct === '' ? null : Number(form.batteryPct),
|
||||
deliveryH2: form.hydrogenAmount === '' ? null : Number(form.hydrogenAmount),
|
||||
deliveryH2Unit: form.hydrogenUnit,
|
||||
deliveryStatus: '已保存'
|
||||
};
|
||||
}
|
||||
|
||||
function handleSaveClick() {
|
||||
onSave && onSave(buildPatchFromForm());
|
||||
message.success('已保存');
|
||||
}
|
||||
|
||||
function handleSubmitClick() {
|
||||
var err = validateSubmit();
|
||||
if (err) { message.error(err); return; }
|
||||
Modal.confirm({
|
||||
title: '确认交车',
|
||||
content: '请确认信息填写无误,点击确认完成该车辆交车。',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: function () {
|
||||
setSubmitting(true);
|
||||
setTimeout(function () {
|
||||
setSubmitting(false);
|
||||
onSubmit && onSubmit(buildPatchFromForm());
|
||||
message.success('交车成功');
|
||||
onClose && onClose();
|
||||
}, 400);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleTrainingPick(e) {
|
||||
var f = e && e.target && e.target.files && e.target.files[0];
|
||||
if (!f) return;
|
||||
setTimeout(function () {
|
||||
updateForm({
|
||||
trainingRecognized: true,
|
||||
driverLicenses: [
|
||||
{ uid: 'id1', name: '身份证正面', url: 'https://dummyimage.com/600x400/e2e8f0/475569&text=ID-F' },
|
||||
{ uid: 'id2', name: '身份证反面', url: 'https://dummyimage.com/600x400/e2e8f0/475569&text=ID-B' },
|
||||
{ uid: 'dl', name: '驾驶证', url: 'https://dummyimage.com/600x400/e2e8f0/475569&text=DL' },
|
||||
{ uid: 'qc', name: '从业资格证', url: 'https://dummyimage.com/600x400/e2e8f0/475569&text=QC' }
|
||||
]
|
||||
});
|
||||
message.success('验车码识别成功');
|
||||
}, 500);
|
||||
e.target.value = '';
|
||||
}
|
||||
|
||||
if (!open) return null;
|
||||
|
||||
var drawerTitle = React.createElement('div', { style: { paddingRight: 24 } },
|
||||
React.createElement('div', { style: { fontSize: 16, fontWeight: 700, color: '#0f172a', lineHeight: 1.4 } }, '编辑交车单'),
|
||||
record ? React.createElement('div', { style: { marginTop: 6, fontSize: 13, color: '#64748b', display: 'flex', flexWrap: 'wrap', gap: 8, alignItems: 'center' } },
|
||||
React.createElement(Tag, { style: { margin: 0, border: 'none', background: '#eff6ff', color: '#2563eb', fontWeight: 600 } }, record.customerName || '-'),
|
||||
React.createElement('span', null, record.contractCode || '-'),
|
||||
React.createElement(Tag, { style: { margin: 0, border: 'none', background: '#f1f5f9', color: '#475569' } }, record.deliveryStatus || '未开始')
|
||||
) : null
|
||||
);
|
||||
|
||||
var summaryCard = record ? React.createElement('div', { style: { marginBottom: 16, padding: '12px 14px', borderRadius: 10, background: 'linear-gradient(135deg,#f8fafc 0%,#fff 100%)', border: '1px solid #e2e8f0', display: 'grid', gridTemplateColumns: 'repeat(2,minmax(0,1fr))', gap: '8px 16px', fontSize: 13 } },
|
||||
React.createElement('div', null, React.createElement('span', { style: { color: '#94a3b8' } }, '项目:'), record.projectName || '-'),
|
||||
React.createElement('div', null, React.createElement('span', { style: { color: '#94a3b8' } }, '交车地点:'), record.deliveryAddress || '-'),
|
||||
React.createElement('div', null, React.createElement('span', { style: { color: '#94a3b8' } }, '品牌型号:'), (record.brand || '-') + ' / ' + (record.model || '-')),
|
||||
React.createElement('div', null, React.createElement('span', { style: { color: '#94a3b8' } }, '任务来源:'), record.taskSource || '-')
|
||||
) : null;
|
||||
|
||||
var sectionNavEl = React.createElement('div', { style: { position: 'sticky', top: 0, zIndex: 3, background: '#fff', padding: '8px 0 12px', marginBottom: 8, borderBottom: '1px solid #f1f5f9', display: 'flex', gap: 8, flexWrap: 'wrap' } },
|
||||
sectionNav.map(function (s) {
|
||||
var active = activeSection === s.key;
|
||||
return React.createElement('button', {
|
||||
key: s.key,
|
||||
type: 'button',
|
||||
onClick: function () { scrollToSection(s.key); },
|
||||
style: {
|
||||
border: 'none',
|
||||
cursor: 'pointer',
|
||||
padding: '6px 14px',
|
||||
borderRadius: 999,
|
||||
fontSize: 13,
|
||||
fontWeight: active ? 600 : 500,
|
||||
background: active ? '#2563eb' : '#f1f5f9',
|
||||
color: active ? '#fff' : '#475569',
|
||||
transition: 'background .2s,color .2s'
|
||||
}
|
||||
}, s.label);
|
||||
})
|
||||
);
|
||||
|
||||
var sectionBasic = React.createElement('div', { id: 'dv-edit-section-basic', style: { scrollMarginTop: 56 } },
|
||||
React.createElement('div', { style: { fontSize: 14, fontWeight: 700, color: '#0f172a', marginBottom: 12, paddingLeft: 10, borderLeft: '3px solid #2563eb' } }, '车辆信息'),
|
||||
React.createElement('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(2,minmax(0,1fr))', gap: '0 16px' } },
|
||||
React.createElement(FormItem, { label: '车牌号', required: true },
|
||||
React.createElement(Select, { value: form.plateNo, options: plateOptions, showSearch: true, filterOption: filterOption, placeholder: '请输入或选择车牌号', allowClear: true, style: { width: '100%' }, onChange: handlePlateChange })
|
||||
),
|
||||
React.createElement(FormItem, { label: '车辆类型' }, React.createElement(Input, { value: form.vehicleType, disabled: true })),
|
||||
React.createElement(FormItem, { label: '品牌' }, React.createElement(Input, { value: form.brand, disabled: true })),
|
||||
React.createElement(FormItem, { label: '型号' }, React.createElement(Input, { value: form.model, disabled: true })),
|
||||
React.createElement(FormItem, { label: '车辆识别代码' }, React.createElement(Input, { value: form.vin, disabled: true }))
|
||||
)
|
||||
);
|
||||
|
||||
var sectionEquip = React.createElement('div', { id: 'dv-edit-section-equip', style: { scrollMarginTop: 56, marginTop: 24 } },
|
||||
React.createElement('div', { style: { fontSize: 14, fontWeight: 700, color: '#0f172a', marginBottom: 12, paddingLeft: 10, borderLeft: '3px solid #2563eb' } }, '设备与证照'),
|
||||
React.createElement(FormItem, { label: '车身广告及放大字', required: true },
|
||||
React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 10 } },
|
||||
React.createElement(Switch, { checked: !!form.hasAd, onChange: function (v) { updateForm({ hasAd: !!v }); } }),
|
||||
React.createElement('span', { style: { fontSize: 13, color: '#64748b' } }, form.hasAd ? '有车身广告' : '无车身广告')
|
||||
)
|
||||
),
|
||||
form.hasAd ? React.createElement('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16, marginBottom: 8 } },
|
||||
React.createElement(UploadBox, { label: RequiredLabel('广告照片'), value: form.adPhoto, max: 1, onChange: function (l) { updateForm({ adPhoto: l }); } }),
|
||||
React.createElement(UploadBox, { label: RequiredLabel('放大字照片'), value: form.bigWordPhoto, max: 1, onChange: function (l) { updateForm({ bigWordPhoto: l }); } })
|
||||
) : null,
|
||||
React.createElement(FormItem, { label: '尾板', required: true },
|
||||
React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 10 } },
|
||||
React.createElement(Switch, { checked: !!form.hasTailboard, onChange: function (v) { updateForm({ hasTailboard: !!v }); } }),
|
||||
React.createElement('span', { style: { fontSize: 13, color: '#64748b' } }, form.hasTailboard ? '有尾板' : '无尾板')
|
||||
)
|
||||
),
|
||||
React.createElement('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 } },
|
||||
React.createElement(UploadBox, { label: RequiredLabel('备胎照片'), value: form.spareTirePhoto, max: 1, onChange: function (l) { updateForm({ spareTirePhoto: l }); if (l && l.length) ocrModalState[1]({ open: true, photoUrl: l[0].url, depth: '6.50' }); } }),
|
||||
React.createElement(FormItem, { label: '备胎胎纹深度', required: true },
|
||||
React.createElement(Input, { value: form.spareTireDepth, placeholder: '请输入', addonAfter: 'mm', onChange: function (e) { updateForm({ spareTireDepth: e.target.value }); } })
|
||||
)
|
||||
),
|
||||
React.createElement(FormItem, { label: '驾驶培训', required: true },
|
||||
form.trainingRecognized
|
||||
? React.createElement('span', { style: { color: '#16a34a', fontWeight: 600, fontSize: 13 } }, '已完成视频培训')
|
||||
: React.createElement(React.Fragment, null,
|
||||
React.createElement('input', { type: 'file', ref: trainingInputRef, accept: 'image/*', style: { display: 'none' }, onChange: handleTrainingPick }),
|
||||
React.createElement(Button, { onClick: function () { trainingInputRef.current && trainingInputRef.current.click(); } }, '上传验车码')
|
||||
)
|
||||
),
|
||||
form.driverLicenses && form.driverLicenses.length ? React.createElement(FormItem, { label: '司机证照' },
|
||||
React.createElement('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(4,minmax(0,1fr))', gap: 12 } },
|
||||
form.driverLicenses.map(function (f) {
|
||||
return React.createElement('div', { key: f.uid },
|
||||
makeThumb(f.url, function () { previewState[1]({ open: true, url: f.url, title: f.name }); }),
|
||||
React.createElement('div', { style: { marginTop: 4, fontSize: 12, color: '#64748b', textAlign: 'center' } }, f.name)
|
||||
);
|
||||
})
|
||||
)
|
||||
) : null,
|
||||
React.createElement(FormItem, { label: '车辆检查' },
|
||||
React.createElement(Button, { onClick: function () { inspectionOpenState[1](true); } }, '交车检查单')
|
||||
)
|
||||
);
|
||||
|
||||
var sectionMetrics = React.createElement('div', { id: 'dv-edit-section-metrics', style: { scrollMarginTop: 56, marginTop: 24 } },
|
||||
React.createElement('div', { style: { fontSize: 14, fontWeight: 700, color: '#0f172a', marginBottom: 12, paddingLeft: 10, borderLeft: '3px solid #2563eb' } }, '交车数据'),
|
||||
React.createElement('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(2,minmax(0,1fr))', gap: '0 16px' } },
|
||||
React.createElement(FormItem, { label: '交车里程', required: true },
|
||||
React.createElement(Input, { value: form.mileageKm, placeholder: '请输入', addonAfter: 'km', onChange: function (e) { updateForm({ mileageKm: e.target.value }); } })
|
||||
),
|
||||
React.createElement(FormItem, { label: '交车电量', required: true },
|
||||
React.createElement(Input, { value: form.batteryPct, placeholder: '请输入', addonAfter: '%', onChange: function (e) { updateForm({ batteryPct: e.target.value }); } })
|
||||
),
|
||||
React.createElement(FormItem, { label: '交车氢量', required: true },
|
||||
React.createElement(Input, { value: form.hydrogenAmount, placeholder: '请输入', addonAfter: form.hydrogenUnit, onChange: function (e) { updateForm({ hydrogenAmount: e.target.value }); } })
|
||||
),
|
||||
React.createElement(FormItem, { label: '送车服务费' },
|
||||
React.createElement(Input, { value: form.serviceFee, placeholder: '选填', addonAfter: '元', onChange: function (e) { updateForm({ serviceFee: e.target.value }); } })
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
var photoKeys = ['仪表盘', '车辆正面', '车辆左前方'];
|
||||
var photoState = useState({ vehicle: { '仪表盘': [], '车辆正面': [], '车辆左前方': [] } });
|
||||
var photos = photoState[0];
|
||||
var setPhotos = photoState[1];
|
||||
|
||||
var sectionPhotos = React.createElement('div', { id: 'dv-edit-section-photos', style: { scrollMarginTop: 56, marginTop: 24, marginBottom: 24 } },
|
||||
React.createElement('div', { style: { fontSize: 14, fontWeight: 700, color: '#0f172a', marginBottom: 12, paddingLeft: 10, borderLeft: '3px solid #2563eb' } }, '交车照片'),
|
||||
React.createElement('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(3,minmax(0,1fr))', gap: 16 } },
|
||||
photoKeys.map(function (k) {
|
||||
return React.createElement(UploadBox, {
|
||||
key: k,
|
||||
label: RequiredLabel(k),
|
||||
value: photos.vehicle[k] || [],
|
||||
max: 1,
|
||||
onChange: function (l) {
|
||||
setPhotos(function (p) {
|
||||
var n = Object.assign({}, p);
|
||||
n.vehicle = Object.assign({}, p.vehicle);
|
||||
n.vehicle[k] = l;
|
||||
return n;
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
),
|
||||
React.createElement('div', { style: { marginTop: 8, fontSize: 12, color: '#94a3b8' } }, '原型:完整照片清单见交车单编辑页需求说明')
|
||||
);
|
||||
|
||||
return React.createElement(React.Fragment, null,
|
||||
React.createElement(Drawer, {
|
||||
open: open,
|
||||
onClose: onClose,
|
||||
width: Math.min(960, typeof window !== 'undefined' ? window.innerWidth - 24 : 960),
|
||||
title: drawerTitle,
|
||||
destroyOnClose: true,
|
||||
styles: {
|
||||
body: { padding: '16px 20px 88px', background: '#f8fafc' },
|
||||
footer: { borderTop: '1px solid #e2e8f0', padding: '12px 20px' }
|
||||
},
|
||||
footer: React.createElement('div', { style: { display: 'flex', justifyContent: 'flex-end', gap: 10 } },
|
||||
React.createElement(Button, { onClick: onClose, disabled: submitting }, '取消'),
|
||||
React.createElement(Button, { onClick: handleSaveClick, disabled: submitting }, '保存'),
|
||||
React.createElement(Button, { type: 'primary', loading: submitting, onClick: handleSubmitClick }, '提交')
|
||||
)
|
||||
},
|
||||
summaryCard,
|
||||
sectionNavEl,
|
||||
React.createElement('div', { style: { background: '#fff', borderRadius: 12, border: '1px solid #e2e8f0', padding: '16px 16px 8px' } },
|
||||
sectionBasic,
|
||||
sectionEquip,
|
||||
sectionMetrics,
|
||||
sectionPhotos
|
||||
)
|
||||
),
|
||||
React.createElement(Modal, {
|
||||
open: !!previewState[0].open,
|
||||
title: previewState[0].title || '预览',
|
||||
footer: null,
|
||||
onCancel: function () { previewState[1]({ open: false, url: '', title: '' }); },
|
||||
width: 860
|
||||
}, previewState[0].url ? React.createElement('img', { src: previewState[0].url, alt: previewState[0].title, style: { width: '100%', maxHeight: '70vh', objectFit: 'contain' } }) : null),
|
||||
React.createElement(Modal, {
|
||||
open: !!ocrModalState[0].open,
|
||||
title: '备胎识别',
|
||||
onCancel: function () { ocrModalState[1](Object.assign({}, ocrModalState[0], { open: false })); },
|
||||
onOk: function () { updateForm({ spareTireDepth: ocrModalState[0].depth }); ocrModalState[1](Object.assign({}, ocrModalState[0], { open: false })); message.success('已反写胎纹深度'); },
|
||||
okText: '确认',
|
||||
cancelText: '取消'
|
||||
},
|
||||
React.createElement(Input, { value: ocrModalState[0].depth, addonAfter: 'mm', onChange: function (e) { ocrModalState[1](Object.assign({}, ocrModalState[0], { depth: e.target.value })); } })
|
||||
),
|
||||
React.createElement(Drawer, {
|
||||
open: inspectionOpenState[0],
|
||||
title: '交车检查单',
|
||||
width: 720,
|
||||
onClose: function () { inspectionOpenState[1](false); },
|
||||
footer: React.createElement(Button, { type: 'primary', onClick: function () { message.success('检查单已保存'); inspectionOpenState[1](false); } }, '确定')
|
||||
},
|
||||
React.createElement(Table, {
|
||||
rowKey: 'key',
|
||||
size: 'small',
|
||||
pagination: false,
|
||||
bordered: true,
|
||||
dataSource: inspectionList,
|
||||
columns: [
|
||||
{ title: '类别', dataIndex: 'category', width: 100 },
|
||||
{ title: '检查项目', dataIndex: 'item', width: 140 },
|
||||
{ title: '检查情况', dataIndex: 'checked', width: 100, render: function (v) { return React.createElement(Switch, { checked: !!v, disabled: true }); } },
|
||||
{ title: '备注', dataIndex: 'remark' }
|
||||
]
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
window.DeliveryEditDrawer = DeliveryEditDrawer;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
267
web端/运维管理/车辆业务/故障管理-编辑.jsx
Normal file
267
web端/运维管理/车辆业务/故障管理-编辑.jsx
Normal file
@@ -0,0 +1,267 @@
|
||||
// 【重要】必须使用 const Component 作为组件变量名
|
||||
// ONEOS-web - 运维管理 - 车辆业务 - 故障管理-编辑(已回填数据,可修改)
|
||||
|
||||
const Component = function () {
|
||||
var antd = window.antd;
|
||||
var Button = antd.Button;
|
||||
var Input = antd.Input;
|
||||
var Select = antd.Select;
|
||||
var DatePicker = antd.DatePicker;
|
||||
var Form = antd.Form;
|
||||
var Row = antd.Row;
|
||||
var Col = antd.Col;
|
||||
var Breadcrumb = antd.Breadcrumb;
|
||||
var Layout = antd.Layout;
|
||||
var message = antd.message;
|
||||
var Card = antd.Card;
|
||||
var Upload = antd.Upload;
|
||||
|
||||
var _form = Form.useForm();
|
||||
var faultForm = _form[0];
|
||||
|
||||
// 故障等级枚举
|
||||
var faultLevelOptions = [
|
||||
{ label: '特急', value: '特急' },
|
||||
{ label: '紧急', value: '紧急' },
|
||||
{ label: '一般', value: '一般' },
|
||||
{ label: '提示', value: '提示' }
|
||||
];
|
||||
|
||||
// 故障类型枚举
|
||||
var faultTypeOptions = [
|
||||
{ label: '底盘故障', value: '底盘故障' },
|
||||
{ label: '三电故障', value: '三电故障' },
|
||||
{ label: '整车系统', value: '整车系统' },
|
||||
{ label: '燃料电池系统故障', value: '燃料电池系统故障' },
|
||||
{ label: '供氢系统故障', value: '供氢系统故障' },
|
||||
{ label: '空调系统故障', value: '空调系统故障' },
|
||||
{ label: '冷机故障', value: '冷机故障' },
|
||||
{ label: '其他故障', value: '其他故障' }
|
||||
];
|
||||
|
||||
// 故障来源枚举
|
||||
var faultSourceOptions = [
|
||||
{ label: '客户报告', value: '客户报告' },
|
||||
{ label: '定期保养', value: '定期保养' },
|
||||
{ label: '司机操作问题', value: '司机操作问题' }
|
||||
];
|
||||
|
||||
// 解决情况枚举
|
||||
var resolveStatusOptions = [
|
||||
{ label: '未解决', value: '未解决' },
|
||||
{ label: '临时排故', value: '临时排故' },
|
||||
{ label: '已解决', value: '已解决' }
|
||||
];
|
||||
|
||||
var plateOptions = [
|
||||
{ label: '沪A12345', value: '沪A12345', brand: '一汽解放', model: 'J6P', company: '上海羚牛', vin: 'LNW1234567890ABCD' },
|
||||
{ label: '浙B88888', value: '浙B88888', brand: '东风商用车', model: '天龙', company: '浙江羚牛', vin: 'LNW0987654321EFGH' },
|
||||
{ label: '苏C66666', value: '苏C66666', brand: '福田欧曼', model: 'EST', company: '苏州冷链速运有限公司', vin: 'LNW1357924680IJKL' },
|
||||
{ label: '沪D99999', value: '沪D99999', brand: '陕汽重卡', model: '德龙', company: '上海城配物流有限公司', vin: 'LNW2468013579MNOP' }
|
||||
];
|
||||
|
||||
var PlusIcon = function() { return React.createElement('svg', { viewBox: '0 0 1024 1024', width: 14, height: 14, fill: 'currentColor' }, React.createElement('path', { d: 'M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z' }), React.createElement('path', { d: 'M192 474h672q8 0 8 8v60q0 8-8 8H192q-8 0-8-8v-60q0-8 8-8z' })); };
|
||||
|
||||
var handleBack = function () {
|
||||
message.info('返回列表');
|
||||
};
|
||||
|
||||
// 编辑态:模拟从列表带入的已存在数据(实际接入路由/接口后替换为 record)
|
||||
React.useEffect(function () {
|
||||
var initial = {
|
||||
code: 'F-2024-001',
|
||||
plate: '沪A12345',
|
||||
brand: '一汽解放',
|
||||
model: 'J6P',
|
||||
company: '上海羚牛',
|
||||
vin: 'LNW1234567890ABCD',
|
||||
type: '底盘故障',
|
||||
source: '客户报告',
|
||||
level: '紧急',
|
||||
reportTime: '2024-05-10 08:30:00',
|
||||
status: '未解决',
|
||||
desc: '车辆重载下制动踏板偏软,制动距离明显变长'
|
||||
};
|
||||
if (initial.reportTime) {
|
||||
if (typeof window.dayjs === 'function') {
|
||||
initial.reportTime = window.dayjs(initial.reportTime);
|
||||
} else if (typeof window.moment === 'function') {
|
||||
initial.reportTime = window.moment(initial.reportTime);
|
||||
}
|
||||
}
|
||||
faultForm.setFieldsValue(initial);
|
||||
}, []);
|
||||
|
||||
return React.createElement(Layout, { className: 'arco-theme-overrides', style: { minHeight: '100vh', background: '#f2f3f5', fontFamily: 'Inter, Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif' } },
|
||||
React.createElement('style', null, `
|
||||
.arco-theme-overrides .ant-btn { border-radius: 4px; }
|
||||
.arco-theme-overrides .ant-btn-primary { background-color: #165dff; border-color: #165dff; }
|
||||
.arco-theme-overrides .ant-btn-primary:hover { background-color: #4080ff; border-color: #4080ff; }
|
||||
|
||||
.arco-grouped-form-page { display: flex; flex-direction: column; min-height: 100vh; }
|
||||
.arco-grouped-form-page-content { flex: 1; padding: 16px 20px 24px; }
|
||||
.arco-grouped-form-page .ant-card { margin-bottom: 16px; border-radius: 4px; border: none; box-shadow: 0 1px 2px rgba(0,0,0,0.06); }
|
||||
.arco-grouped-form-page .ant-card-head { border-bottom: none; padding: 20px 24px 0; min-height: auto; }
|
||||
.arco-grouped-form-page .ant-card-head-title { font-size: 16px; font-weight: 500; color: #1d2129; padding: 0; }
|
||||
.arco-grouped-form-page .ant-card-body { padding: 24px; }
|
||||
.arco-grouped-form-page .ant-form-vertical .ant-form-item-label { padding-bottom: 8px; height: auto; line-height: 1.5715; }
|
||||
.arco-grouped-form-page .ant-form-item { margin-bottom: 24px; }
|
||||
|
||||
.arco-grouped-form-page .ant-input,
|
||||
.arco-grouped-form-page .ant-select-selector,
|
||||
.arco-grouped-form-page .ant-picker,
|
||||
.arco-grouped-form-page .ant-input-affix-wrapper { background-color: #f2f3f5; border: 1px solid #e5e6eb; border-radius: 2px; transition: all 0.1s cubic-bezier(0, 0, 1, 1); }
|
||||
.arco-grouped-form-page .ant-input:hover,
|
||||
.arco-grouped-form-page .ant-select:not(.ant-select-disabled):hover .ant-select-selector,
|
||||
.arco-grouped-form-page .ant-picker:hover,
|
||||
.arco-grouped-form-page .ant-input-affix-wrapper:hover { background-color: #f2f3f5; border-color: #165dff; }
|
||||
.arco-grouped-form-page .ant-input:focus,
|
||||
.arco-grouped-form-page .ant-input-focused,
|
||||
.arco-grouped-form-page .ant-select-focused .ant-select-selector,
|
||||
.arco-grouped-form-page .ant-picker-focused,
|
||||
.arco-grouped-form-page .ant-input-affix-wrapper-focused { background-color: #fff; border: 1px solid #165dff !important; box-shadow: 0 0 0 2px rgba(22, 93, 255, 0.2) !important; outline: 0; }
|
||||
.arco-grouped-form-page .ant-input[disabled],
|
||||
.arco-grouped-form-page .ant-select-disabled .ant-select-selector,
|
||||
.arco-grouped-form-page .ant-picker-disabled { color: #86909c; background-color: #f2f3f5; border-color: #e5e6eb; cursor: not-allowed; }
|
||||
.arco-grouped-form-page .ant-input-affix-wrapper[disabled] { background-color: #f2f3f5; border-color: #e5e6eb; cursor: not-allowed; }
|
||||
.arco-grouped-form-page .ant-input-affix-wrapper > input.ant-input { background-color: transparent; }
|
||||
.arco-grouped-form-page .ant-input-affix-wrapper > input.ant-input:focus { background-color: transparent; box-shadow: none !important; border: none !important; }
|
||||
|
||||
.arco-grouped-form-footer { background: #fff; padding: 16px 24px; border-top: 1px solid #e5e6eb; display: flex; justify-content: flex-end; align-items: center; gap: 12px; position: sticky; bottom: 0; z-index: 100; box-shadow: 0 -2px 10px rgba(0,0,0,0.05); }
|
||||
.arco-grouped-form-footer .ant-btn { border-radius: 5px; height: 32px; padding: 4px 16px; font-size: 14px; }
|
||||
|
||||
.arco-theme-overrides .ant-breadcrumb { color: #86909c; font-size: 14px; white-space: nowrap; flex-shrink: 0; margin-bottom: 20px; }
|
||||
.arco-theme-overrides .ant-breadcrumb a { color: #4e5969; }
|
||||
.arco-theme-overrides .ant-breadcrumb a:hover { color: #165dff; background-color: transparent; }
|
||||
.arco-theme-overrides .ant-form-item-label > label { color: #4e5969; white-space: nowrap; }
|
||||
.arco-theme-overrides .ant-form-item-label > label::after { display: none !important; content: "" !important; margin: 0 !important; }
|
||||
`),
|
||||
React.createElement('div', { className: 'arco-grouped-form-page' },
|
||||
React.createElement('div', { className: 'arco-grouped-form-page-content' },
|
||||
React.createElement(Breadcrumb, {
|
||||
separator: React.createElement('span', { style: { color: '#c9cdd4' } }, '/'),
|
||||
items: [
|
||||
{ title: '首页' },
|
||||
{ title: '运维管理' },
|
||||
{ title: '车辆业务' },
|
||||
{ title: React.createElement('a', { onClick: function(e) { e.preventDefault(); handleBack(); } }, '故障管理') },
|
||||
{ title: React.createElement('span', { style: { color: '#1d2129' } }, '编辑故障单') }
|
||||
]
|
||||
}),
|
||||
|
||||
React.createElement(Form, { form: faultForm, layout: 'vertical' },
|
||||
React.createElement(Card, { title: '车辆信息', bordered: false },
|
||||
React.createElement(Row, { gutter: 24 },
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '故障编码', name: 'code' },
|
||||
React.createElement(Input, { disabled: true, style: { backgroundColor: '#f2f3f5', color: '#86909c' } })
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '车牌号', name: 'plate', rules: [{ required: true, message: '请选择车牌号' }] },
|
||||
React.createElement(Select, {
|
||||
placeholder: '请选择车牌号',
|
||||
options: plateOptions,
|
||||
showSearch: true,
|
||||
onChange: function(val, option) {
|
||||
if (option) {
|
||||
faultForm.setFieldsValue({
|
||||
brand: option.brand,
|
||||
model: option.model,
|
||||
company: option.company,
|
||||
vin: option.vin
|
||||
});
|
||||
} else {
|
||||
faultForm.setFieldsValue({ brand: undefined, model: undefined, company: undefined, vin: undefined });
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '车辆品牌', name: 'brand' },
|
||||
React.createElement(Input, { placeholder: '自动带入', disabled: true, style: { backgroundColor: '#f2f3f5', color: '#86909c' } })
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '车辆型号', name: 'model' },
|
||||
React.createElement(Input, { placeholder: '自动带入', disabled: true, style: { backgroundColor: '#f2f3f5', color: '#86909c' } })
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '运营公司', name: 'company' },
|
||||
React.createElement(Input, { placeholder: '自动带入', disabled: true, style: { backgroundColor: '#f2f3f5', color: '#86909c' } })
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '车辆识别代码', name: 'vin' },
|
||||
React.createElement(Input, { placeholder: '自动带入', disabled: true, style: { backgroundColor: '#f2f3f5', color: '#86909c' } })
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
React.createElement(Card, { title: '故障信息', bordered: false },
|
||||
React.createElement(Row, { gutter: 24 },
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '故障类型', name: 'type', rules: [{ required: true, message: '请选择故障类型' }] },
|
||||
React.createElement(Select, { placeholder: '请选择故障类型', options: faultTypeOptions })
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '故障来源', name: 'source', rules: [{ required: true, message: '请选择故障来源' }] },
|
||||
React.createElement(Select, { placeholder: '请选择故障来源', options: faultSourceOptions })
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '故障等级', name: 'level', rules: [{ required: true, message: '请选择故障等级' }] },
|
||||
React.createElement(Select, { placeholder: '请选择故障等级', options: faultLevelOptions })
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '故障上报时间', name: 'reportTime', rules: [{ required: true, message: '请选择故障上报时间' }] },
|
||||
React.createElement(DatePicker, { style: { width: '100%' }, placeholder: '请选择上报时间', showTime: true })
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '解决情况', name: 'status', rules: [{ required: true, message: '请选择故障解决情况' }] },
|
||||
React.createElement(Select, { placeholder: '请选择故障解决情况', options: resolveStatusOptions })
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
React.createElement(Card, { title: '故障证据与描述', bordered: false },
|
||||
React.createElement(Row, { gutter: 24 },
|
||||
React.createElement(Col, { span: 24 },
|
||||
React.createElement(Form.Item, { label: '故障描述', name: 'desc', rules: [{ required: true, message: '请填写故障描述' }] },
|
||||
React.createElement(Input.TextArea, {
|
||||
placeholder: '在何种状态下,产生何种现象,导致何种事故',
|
||||
style: { height: 80, minHeight: 80, resize: 'none' }
|
||||
})
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 24 },
|
||||
React.createElement(Form.Item, { label: '故障证据', name: 'evidence' },
|
||||
React.createElement(Upload, { listType: 'picture-card' },
|
||||
React.createElement('div', null,
|
||||
React.createElement(PlusIcon, null),
|
||||
React.createElement('div', { style: { marginTop: 8 } }, '上传文件')
|
||||
)
|
||||
),
|
||||
React.createElement('div', { style: { fontSize: 12, color: '#86909c', marginTop: 8 } }, '支持上传照片、视频、录音')
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
React.createElement('div', { className: 'arco-grouped-form-footer' },
|
||||
React.createElement(Button, { onClick: handleBack, style: { borderRadius: 5 } }, '取消'),
|
||||
React.createElement(Button, { type: 'primary', onClick: function () { faultForm.submit(); message.success('保存成功'); }, style: { borderRadius: 5 } }, '保存')
|
||||
)
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
if (typeof module !== 'undefined' && module.exports) module.exports = Component;
|
||||
503
web端/运维管理/车辆业务/故障管理.jsx
Normal file
503
web端/运维管理/车辆业务/故障管理.jsx
Normal file
@@ -0,0 +1,503 @@
|
||||
// 【重要】必须使用 const Component 作为组件变量名
|
||||
// ONEOS-web - 运维管理 - 车辆业务 - 故障管理(列表与表单)
|
||||
|
||||
const Component = function () {
|
||||
var useState = React.useState;
|
||||
var useEffect = React.useEffect;
|
||||
|
||||
var antd = window.antd;
|
||||
var Table = antd.Table;
|
||||
var Button = antd.Button;
|
||||
var Space = antd.Space;
|
||||
var Input = antd.Input;
|
||||
var Select = antd.Select;
|
||||
var DatePicker = antd.DatePicker;
|
||||
var Form = antd.Form;
|
||||
var Row = antd.Row;
|
||||
var Col = antd.Col;
|
||||
var Divider = antd.Divider;
|
||||
var Breadcrumb = antd.Breadcrumb;
|
||||
var Layout = antd.Layout;
|
||||
var message = antd.message;
|
||||
var Tag = antd.Tag;
|
||||
var Card = antd.Card;
|
||||
var Modal = antd.Modal;
|
||||
var Tabs = antd.Tabs;
|
||||
var Tooltip = antd.Tooltip;
|
||||
var RangePicker = DatePicker.RangePicker;
|
||||
|
||||
var _filterFormInst = Form.useForm();
|
||||
var filterForm = _filterFormInst[0];
|
||||
|
||||
var _specOpen = useState(false);
|
||||
var specModalOpen = _specOpen[0];
|
||||
var setSpecModalOpen = _specOpen[1];
|
||||
|
||||
var _listTab = useState('pending');
|
||||
var listTab = _listTab[0];
|
||||
var setListTab = _listTab[1];
|
||||
|
||||
var _tableRows = useState(null);
|
||||
var tableRowsOverride = _tableRows[0];
|
||||
var setTableRowsOverride = _tableRows[1];
|
||||
|
||||
var faultLevelOptions = [
|
||||
{ label: 'L1-特急', value: '特急' },
|
||||
{ label: 'L2-紧急', value: '紧急' },
|
||||
{ label: 'L3-一般', value: '一般' },
|
||||
{ label: 'L4-提示', value: '提示' }
|
||||
];
|
||||
|
||||
var lastOperatorOptions = [
|
||||
{ label: '王婷婷', value: '王婷婷' },
|
||||
{ label: '刘若楠', value: '刘若楠' },
|
||||
{ label: '陈嘉豪', value: '陈嘉豪' },
|
||||
{ label: '赵海峰', value: '赵海峰' }
|
||||
];
|
||||
|
||||
// 故障类型枚举
|
||||
var faultTypeOptions = [
|
||||
{ label: '底盘故障', value: '底盘故障' },
|
||||
{ label: '三电故障', value: '三电故障' },
|
||||
{ label: '整车系统', value: '整车系统' },
|
||||
{ label: '燃料电池系统故障', value: '燃料电池系统故障' },
|
||||
{ label: '供氢系统故障', value: '供氢系统故障' },
|
||||
{ label: '空调系统故障', value: '空调系统故障' },
|
||||
{ label: '冷机故障', value: '冷机故障' },
|
||||
{ label: '其他故障', value: '其他故障' }
|
||||
];
|
||||
|
||||
// 解决情况枚举
|
||||
var resolveStatusOptions = [
|
||||
{ label: '未解决', value: '未解决' },
|
||||
{ label: '临时排故', value: '临时排故' },
|
||||
{ label: '已解决', value: '已解决' }
|
||||
];
|
||||
|
||||
var SearchIcon = function() { return React.createElement('svg', { viewBox: '0 0 1024 1024', width: 14, height: 14, fill: 'currentColor' }, React.createElement('path', { d: 'M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z' })); };
|
||||
var FileTextIcon = function() { return React.createElement('svg', { viewBox: '0 0 1024 1024', width: 16, height: 16, fill: 'currentColor' }, React.createElement('path', { d: 'M854.6 288.7L639.4 73.4c-6-6-14.2-9.4-22.7-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216c0 22.1 17.9 40 40 40h216v494zM504 618H320c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h184c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zM702 458H320c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h382c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8z' })); };
|
||||
var ResetIcon = function() { return React.createElement('svg', { viewBox: '0 0 1024 1024', width: 14, height: 14, fill: 'currentColor' }, React.createElement('path', { d: 'M793 242H366v-74c0-6.7-7.7-10.4-12.9-6.3l-142 112a8 8 0 000 12.6l142 112c5.2 4.1 12.9.4 12.9-6.3v-74h415v470H175c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h618c35.3 0 64-28.7 64-64V306c0-35.3-28.7-64-64-64z' })); };
|
||||
var PlusIcon = function() { return React.createElement('svg', { viewBox: '0 0 1024 1024', width: 14, height: 14, fill: 'currentColor' }, React.createElement('path', { d: 'M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z' }), React.createElement('path', { d: 'M192 474h672q8 0 8 8v60q0 8-8 8H192q-8 0-8-8v-60q0-8 8-8z' })); };
|
||||
var DownloadIcon = function() { return React.createElement('svg', { viewBox: '0 0 1024 1024', width: 16, height: 16, fill: 'currentColor' }, React.createElement('path', { d: 'M505.7 661a8 8 0 0012.6 0l112-141.7c4.1-5.2.4-12.9-6.3-12.9h-74.1V168c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v338.3H400c-6.7 0-10.4 7.7-6.3 12.9l112 141.8zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8z' })); };
|
||||
var ListIcon = function() { return React.createElement('svg', { viewBox: '0 0 48 48', width: 14, height: 14, fill: 'none', stroke: 'currentColor', strokeWidth: 4, strokeLinecap: 'butt', strokeLinejoin: 'miter' }, React.createElement('path', { d: 'M17 12H42' }), React.createElement('path', { d: 'M17 24H42' }), React.createElement('path', { d: 'M17 36H42' }), React.createElement('path', { d: 'M8 12H9' }), React.createElement('path', { d: 'M8 24H9' }), React.createElement('path', { d: 'M8 36H9' })); };
|
||||
var UploadIcon = function() { return React.createElement('svg', { viewBox: '0 0 1024 1024', width: 14, height: 14, fill: 'currentColor' }, React.createElement('path', { d: 'M512 256l-256 256h160v256h192V512h160L512 256zM256 832v64h512v-64H256z' })); };
|
||||
|
||||
var levelLabelMap = { 特急: 'L1-特急', 紧急: 'L2-紧急', 一般: 'L3-一般', 提示: 'L4-提示' };
|
||||
var renderFaultLevel = function (text) {
|
||||
var color = 'default';
|
||||
if (text === '特急') color = 'red';
|
||||
else if (text === '紧急') color = 'orange';
|
||||
else if (text === '一般') color = 'blue';
|
||||
else if (text === '提示') color = 'green';
|
||||
var label = levelLabelMap[text] || text;
|
||||
return React.createElement(Tag, { color: color }, label);
|
||||
};
|
||||
|
||||
var renderResolveStatus = function (text) {
|
||||
var dot = '#86909c';
|
||||
if (text === '已解决') dot = '#00b42a';
|
||||
else if (text === '临时排故') dot = '#ff7d00';
|
||||
else if (text === '未解决') dot = '#f53f3f';
|
||||
return React.createElement(Space, { size: 6 },
|
||||
React.createElement('span', { style: { display: 'inline-block', width: 6, height: 6, borderRadius: '50%', backgroundColor: dot } }),
|
||||
React.createElement('span', null, text)
|
||||
);
|
||||
};
|
||||
|
||||
var columns = [
|
||||
{ title: '故障编码', dataIndex: 'code', key: 'code', width: 132, fixed: 'left' },
|
||||
{ title: '解决情况', dataIndex: 'status', key: 'status', width: 120, render: renderResolveStatus },
|
||||
{ title: '车牌号码', dataIndex: 'plate', key: 'plate', width: 112 },
|
||||
{ title: '车辆品牌', dataIndex: 'brand', key: 'brand', width: 100, ellipsis: true },
|
||||
{ title: '车辆型号', dataIndex: 'model', key: 'model', width: 100, ellipsis: true },
|
||||
{ title: '运营公司', dataIndex: 'company', key: 'company', width: 140, ellipsis: true },
|
||||
{ title: '故障等级', dataIndex: 'level', key: 'level', width: 108, render: renderFaultLevel },
|
||||
{ title: '故障类型', dataIndex: 'type', key: 'type', width: 128, ellipsis: true },
|
||||
{
|
||||
title: '故障描述',
|
||||
dataIndex: 'desc',
|
||||
key: 'desc',
|
||||
width: 200,
|
||||
ellipsis: { showTitle: false },
|
||||
render: function (text) {
|
||||
return React.createElement(Tooltip, { placement: 'topLeft', title: text },
|
||||
React.createElement('span', { style: { cursor: 'default' } }, text)
|
||||
);
|
||||
}
|
||||
},
|
||||
{ title: '故障上报时间', dataIndex: 'reportTime', key: 'reportTime', width: 176, ellipsis: true, className: 'fault-col-report-time' },
|
||||
{ title: '最后操作时间', dataIndex: 'lastOperationTime', key: 'lastOperationTime', width: 176, ellipsis: true },
|
||||
{ title: '最后操作人', dataIndex: 'lastOperator', key: 'lastOperator', width: 104, ellipsis: true },
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
fixed: 'right',
|
||||
width: listTab === 'history' ? 72 : 104,
|
||||
render: function (_, record) {
|
||||
if (listTab === 'history') {
|
||||
return React.createElement(Button, { type: 'link', size: 'small', style: { padding: '0 4px' }, onClick: function () { handleView(record); } }, '查看');
|
||||
}
|
||||
return React.createElement(Space, { size: 0, split: React.createElement('span', { style: { color: '#e5e6eb' } }, '|') },
|
||||
React.createElement(Button, { type: 'link', size: 'small', style: { padding: '0 4px' }, onClick: function () { handleView(record); } }, '查看'),
|
||||
React.createElement(Button, { type: 'link', size: 'small', style: { padding: '0 4px' }, onClick: function () { handleEdit(record); } }, '编辑')
|
||||
);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
var ALL_DATA = [
|
||||
{ key: '1', code: 'F-2024-001', plate: '沪A12345', brand: '一汽解放', model: 'J6P', company: '上海羚牛', type: '底盘故障', level: '紧急', source: '客户报告', status: '未解决', reportTime: '2024-05-10 08:30:00', lastOperator: '王婷婷', lastOperationTime: '2024-05-10 09:00:00', desc: '车辆重载下制动踏板偏软,制动距离明显变长' },
|
||||
{ key: '2', code: 'F-2024-002', plate: '浙B88888', brand: '东风商用车', model: '天龙', company: '浙江羚牛', type: '三电故障', level: '特急', source: '司机操作问题', status: '临时排故', reportTime: '2024-05-11 14:15:00', lastOperator: '刘若楠', lastOperationTime: '2024-05-11 16:20:00', desc: '高压系统绝缘报警频繁触发,车辆进入限扭模式' },
|
||||
{ key: '3', code: 'F-2024-003', plate: '苏C66666', brand: '福田欧曼', model: 'EST', company: '苏州冷链速运有限公司', type: '整车系统', level: '一般', source: '定期保养', status: '已解决', reportTime: '2024-05-12 10:00:00', lastOperator: '陈嘉豪', lastOperationTime: '2024-05-12 11:30:00', desc: '后桥轮胎偏磨,建议更换并做四轮定位' },
|
||||
{ key: '4', code: 'F-2024-004', plate: '沪D99999', brand: '陕汽重卡', model: '德龙', company: '上海城配物流有限公司', type: '空调系统故障', level: '提示', source: '客户报告', status: '已解决', reportTime: '2024-05-13 09:45:00', lastOperator: '赵海峰', lastOperationTime: '2024-05-13 10:10:00', desc: '空调制冷效果差,出风口温度偏高' }
|
||||
];
|
||||
|
||||
var parseReportTime = function (str) {
|
||||
if (!str) return null;
|
||||
var p = str.replace(/-/g, '/');
|
||||
var t = new Date(p);
|
||||
return isNaN(t.getTime()) ? null : t;
|
||||
};
|
||||
|
||||
var applyListFilter = function () {
|
||||
var v = filterForm.getFieldsValue();
|
||||
var rows = ALL_DATA.filter(function (r) {
|
||||
if (listTab === 'pending') return r.status !== '已解决';
|
||||
return r.status === '已解决';
|
||||
});
|
||||
if (v.filterPlate && String(v.filterPlate).trim()) {
|
||||
var q = String(v.filterPlate).trim();
|
||||
rows = rows.filter(function (r) { return (r.plate || '').indexOf(q) !== -1; });
|
||||
}
|
||||
if (v.filterLevels && v.filterLevels.length) {
|
||||
rows = rows.filter(function (r) { return v.filterLevels.indexOf(r.level) !== -1; });
|
||||
}
|
||||
if (v.filterTypes && v.filterTypes.length) {
|
||||
rows = rows.filter(function (r) { return v.filterTypes.indexOf(r.type) !== -1; });
|
||||
}
|
||||
if (v.filterLastOperator) {
|
||||
rows = rows.filter(function (r) { return r.lastOperator === v.filterLastOperator; });
|
||||
}
|
||||
if (v.filterDateRange && v.filterDateRange.length === 2 && v.filterDateRange[0] && v.filterDateRange[1]) {
|
||||
var start = v.filterDateRange[0];
|
||||
var end = v.filterDateRange[1];
|
||||
var startMs = start.valueOf ? start.valueOf() : new Date(start).getTime();
|
||||
var endMs = end.valueOf ? end.valueOf() : new Date(end).getTime();
|
||||
var startDay = new Date(startMs);
|
||||
startDay.setHours(0, 0, 0, 0);
|
||||
startMs = startDay.getTime();
|
||||
var endDay = new Date(endMs);
|
||||
endDay.setHours(23, 59, 59, 999);
|
||||
endMs = endDay.getTime();
|
||||
rows = rows.filter(function (r) {
|
||||
var rt = parseReportTime(r.reportTime);
|
||||
if (!rt) return false;
|
||||
var m = rt.getTime();
|
||||
return m >= startMs && m <= endMs;
|
||||
});
|
||||
}
|
||||
setTableRowsOverride(rows);
|
||||
};
|
||||
|
||||
useEffect(function () {
|
||||
applyListFilter();
|
||||
}, [listTab]);
|
||||
|
||||
var displayData = tableRowsOverride !== null && tableRowsOverride !== undefined
|
||||
? tableRowsOverride
|
||||
: ALL_DATA.filter(function (r) {
|
||||
if (listTab === 'pending') return r.status !== '已解决';
|
||||
return r.status === '已解决';
|
||||
});
|
||||
|
||||
var handleCreate = function () {
|
||||
message.info('跳转到新增故障页面');
|
||||
};
|
||||
|
||||
var handleEdit = function (record) {
|
||||
message.info('跳转到编辑故障页面');
|
||||
};
|
||||
|
||||
var handleView = function (record) {
|
||||
message.info('跳转到查看故障页面');
|
||||
};
|
||||
|
||||
|
||||
var formItemLayout = {
|
||||
labelAlign: 'left',
|
||||
colon: false,
|
||||
labelCol: { flex: '0 0 100px' },
|
||||
wrapperCol: { flex: '1 1 0' }
|
||||
};
|
||||
|
||||
var specSection = function (title, children) {
|
||||
return React.createElement('div', { style: { marginBottom: 16 } },
|
||||
React.createElement('div', { style: { fontWeight: 600, color: '#1d2129', marginBottom: 8, fontSize: 14 } }, title),
|
||||
children
|
||||
);
|
||||
};
|
||||
var specLine = function (text) {
|
||||
return React.createElement('div', { style: { fontSize: 13, color: '#4e5969', lineHeight: 1.75, paddingLeft: 0 } }, text);
|
||||
};
|
||||
|
||||
var renderSpecModal = function () {
|
||||
return React.createElement(Modal, {
|
||||
title: '故障列表页 — 需求说明',
|
||||
open: specModalOpen,
|
||||
onCancel: function () { setSpecModalOpen(false); },
|
||||
footer: React.createElement(Button, { type: 'primary', onClick: function () { setSpecModalOpen(false); } }, '知道了'),
|
||||
width: 720,
|
||||
centered: true,
|
||||
destroyOnClose: true
|
||||
},
|
||||
React.createElement('div', { style: { maxHeight: '70vh', overflowY: 'auto', paddingRight: 4 } },
|
||||
specSection('2. 故障列表页', React.createElement(React.Fragment, null,
|
||||
specLine('用于展示待处理与历史记录,支持多条件检索、查看、编辑、删除、导入导出。')
|
||||
)),
|
||||
specSection('2.1 顶部筛选区(支持单条件或多条件组合)', React.createElement(React.Fragment, null,
|
||||
specLine('2.1.1 车牌号:输入框,支持模糊搜索;'),
|
||||
specLine('2.1.2 故障等级:多选下拉,选项:L1-特急、L2-紧急、L3-一般、L4-提示;'),
|
||||
specLine('2.1.3 上报时间:日期范围选择(开始~结束);'),
|
||||
specLine('2.1.4 故障类型:多选下拉,选项为故障类型枚举;'),
|
||||
specLine('2.1.5 最后操作人:下拉选择器;'),
|
||||
specLine('2.1.6 查询按钮:执行筛选;'),
|
||||
specLine('2.1.7 重置按钮:清空筛选条件。')
|
||||
)),
|
||||
specSection('2.2 列表工具栏', React.createElement(React.Fragment, null,
|
||||
specLine('2.2.1 新建:进入故障表单页;'),
|
||||
specLine('2.2.2 导出:导出当前筛选结果;'),
|
||||
specLine('2.2.3 导入:批量导入故障数据;'),
|
||||
specLine('2.2.4 展示设置:字段展示配置(当前版本可预留)。')
|
||||
)),
|
||||
specSection('2.3 Tab分区', React.createElement(React.Fragment, null,
|
||||
specLine('2.3.1 待处理;'),
|
||||
specLine('2.3.2 历史记录。')
|
||||
)),
|
||||
specSection('2.4 列表字段展示(当前版本)', React.createElement(React.Fragment, null,
|
||||
specLine('故障编码、解决情况、车牌号码、车辆品牌、车辆型号、运营公司、故障等级、故障类型、故障描述(省略展示,悬停显示完整)、故障上报时间、最后操作时间、最后操作人、操作(待处理:查看/编辑;历史记录:仅查看)。'),
|
||||
specLine('说明:车辆识别代码不在列表展示,仅在表单车辆信息中展示。')
|
||||
)),
|
||||
specSection('2.5 状态与操作规则', React.createElement(React.Fragment, null,
|
||||
specLine('2.5.1 解决情况状态值:临时排故、已解决、未解决;'),
|
||||
specLine('2.5.2 操作列:待处理 Tab 为查看、编辑(无删除);历史记录 Tab 仅查看;'),
|
||||
specLine('2.5.3 分页:每页10条(固定分页)。')
|
||||
))
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
return React.createElement(Layout, { className: 'arco-theme-overrides', style: { minHeight: '100vh', background: '#f2f3f5', fontFamily: 'Inter, Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif' } },
|
||||
React.createElement('style', null, `
|
||||
.arco-theme-overrides .ant-btn { border-radius: 4px; }
|
||||
.arco-theme-overrides .ant-btn-primary { background-color: #165dff; border-color: #165dff; }
|
||||
.arco-theme-overrides .ant-btn-primary:hover { background-color: #4080ff; border-color: #4080ff; }
|
||||
.arco-theme-overrides .ant-btn-link { color: #165dff; }
|
||||
.arco-theme-overrides .ant-btn-link:hover { background-color: transparent; color: #4080ff; }
|
||||
|
||||
.arco-theme-overrides .ant-table-thead > tr > th {
|
||||
background-color: #f2f3f5;
|
||||
color: #909399;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
height: 40px;
|
||||
padding: 9px 16px;
|
||||
line-height: 22px;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 1px solid #e5e6eb;
|
||||
border-top: none;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.arco-theme-overrides .ant-table-thead > tr > th .ant-table-column-title {
|
||||
font-size: 14px;
|
||||
color: #909399;
|
||||
line-height: 22px;
|
||||
min-height: 22px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.arco-theme-overrides .ant-table-thead > tr > th::before { display: none !important; }
|
||||
.arco-theme-overrides .ant-table-tbody > tr > td { border-bottom: 1px solid #e5e6eb; padding: 13px 16px; color: #4e5969; vertical-align: middle; line-height: 22px; }
|
||||
.arco-theme-overrides .ant-table-tbody > tr { height: 52px; }
|
||||
.arco-theme-overrides .customer-table-scroll-wrap { width: 100%; min-width: 0; max-width: 100%; }
|
||||
.arco-theme-overrides .ant-table-wrapper { border: none; }
|
||||
.arco-theme-overrides .ant-table { border: none; }
|
||||
.arco-theme-overrides .ant-table-container { border: none; }
|
||||
.arco-theme-overrides .ant-table-pagination.ant-pagination { margin: 16px 0 0 0; }
|
||||
|
||||
.arco-theme-overrides .ant-card { border: none; border-radius: 4px; }
|
||||
.arco-theme-overrides .customer-page-card.ant-card { border: 1px solid #e5e6eb !important; border-radius: 4px; box-shadow: 0 1px 2px rgba(0,0,0,0.06); background: #fff; }
|
||||
.arco-theme-overrides .customer-page-card .ant-card-body { padding: 20px 24px 24px; }
|
||||
|
||||
.arco-theme-overrides .ant-input, .arco-theme-overrides .ant-select-selector, .arco-theme-overrides .ant-picker, .arco-theme-overrides .ant-input-affix-wrapper { border-radius: 2px; border: 1px solid #e5e6eb; background-color: #fff; transition: all 0.1s cubic-bezier(0, 0, 1, 1); }
|
||||
.arco-theme-overrides .ant-input:hover, .arco-theme-overrides .ant-select:not(.ant-select-disabled):hover .ant-select-selector, .arco-theme-overrides .ant-picker:hover, .arco-theme-overrides .ant-input-affix-wrapper:hover { background-color: #fff; border-color: #165dff; }
|
||||
.arco-theme-overrides .ant-input:focus, .arco-theme-overrides .ant-input-focused, .arco-theme-overrides .ant-select-focused .ant-select-selector, .arco-theme-overrides .ant-picker-focused, .arco-theme-overrides .ant-input-affix-wrapper-focused { background-color: #fff; border: 1px solid #165dff !important; box-shadow: 0 0 0 2px rgba(22, 93, 255, 0.2) !important; outline: 0; }
|
||||
|
||||
.arco-theme-overrides .ant-breadcrumb { color: #86909c; font-size: 14px; white-space: nowrap; flex-shrink: 0; }
|
||||
.arco-theme-overrides .customer-page-header-row { display: flex; align-items: center; flex-wrap: nowrap; gap: 0; margin-bottom: 20px; }
|
||||
.arco-theme-overrides .ant-breadcrumb a { color: #4e5969; }
|
||||
.arco-theme-overrides .ant-breadcrumb a:hover { color: #165dff; background-color: transparent; }
|
||||
|
||||
.arco-theme-overrides .ant-form-item-label { padding: 0 16px 0 0 !important; line-height: 32px; height: 32px; display: flex; align-items: center; }
|
||||
.arco-theme-overrides .ant-form-item-control { display: flex; align-items: center; line-height: 32px; min-height: 32px; }
|
||||
.arco-theme-overrides .ant-form-item-control-input { min-height: 32px; width: 100%; display: flex; align-items: center; }
|
||||
.arco-theme-overrides .ant-form-item-control-input-content { display: flex; align-items: center; width: 100%; height: 100%; }
|
||||
.arco-theme-overrides .ant-select { width: 100%; height: 32px; }
|
||||
.arco-theme-overrides .ant-select-selector { height: 32px !important; min-height: 32px !important; display: flex; align-items: center; width: 100%; padding: 0 12px; }
|
||||
.arco-theme-overrides .ant-input { height: 32px; padding: 4px 12px; }
|
||||
.arco-theme-overrides .ant-input-affix-wrapper { height: 32px; padding: 0 12px; display: flex; align-items: center; }
|
||||
.arco-theme-overrides .ant-input-affix-wrapper > input.ant-input,
|
||||
.arco-theme-overrides .ant-input-affix-wrapper > input.ant-input:focus,
|
||||
.arco-theme-overrides .ant-input-affix-wrapper > input.ant-input:hover { height: 100%; padding: 0; border: none !important; box-shadow: none !important; outline: none !important; background-color: transparent !important; }
|
||||
.arco-theme-overrides .ant-picker { height: 32px !important; min-height: 32px !important; display: flex; align-items: center; padding: 4px 12px; width: 100%; }
|
||||
.arco-theme-overrides .ant-form-item-label > label { color: #4e5969; white-space: nowrap; }
|
||||
.arco-theme-overrides .ant-form-item-label > label::after { display: none !important; content: "" !important; margin: 0 !important; }
|
||||
.arco-theme-overrides .ant-select-multiple .ant-select-selector { height: auto !important; min-height: 32px !important; align-items: center; padding-top: 2px; padding-bottom: 2px; }
|
||||
.arco-theme-overrides .fault-col-report-time { white-space: nowrap; }
|
||||
`),
|
||||
React.createElement('div', { style: { padding: '16px 20px 24px', display: 'flex', flexDirection: 'column', flex: 1 } },
|
||||
React.createElement(Card, { className: 'customer-page-card', bordered: false },
|
||||
React.createElement('div', { className: 'customer-page-header-row', style: { marginBottom: 16, justifyContent: 'space-between', width: '100%' } },
|
||||
React.createElement(Breadcrumb, {
|
||||
separator: React.createElement('span', { style: { color: '#c9cdd4' } }, '/'),
|
||||
items: [
|
||||
{ title: React.createElement(ListIcon, { style: { display: 'inline-flex', alignItems: 'center', fontSize: 14, transform: 'translate(-2px, 1px)' } }) },
|
||||
{ title: '运维管理' },
|
||||
{ title: '车辆业务' },
|
||||
{ title: React.createElement('span', { style: { color: '#1d2129', fontWeight: 700, fontSize: 16, lineHeight: '22px' } }, '故障管理') }
|
||||
]
|
||||
}),
|
||||
React.createElement(Button, {
|
||||
type: 'link',
|
||||
icon: React.createElement(FileTextIcon, null),
|
||||
style: { display: 'flex', alignItems: 'center', gap: 4, padding: '0 4px', color: '#165dff', fontWeight: 500 },
|
||||
onClick: function () { setSpecModalOpen(true); }
|
||||
}, '查看需求说明')
|
||||
),
|
||||
React.createElement('div', { style: { fontSize: 18, fontWeight: 600, color: '#1d2129', lineHeight: '26px', marginBottom: 20 } }, '故障管理'),
|
||||
|
||||
// 搜索表单区域
|
||||
React.createElement('div', { style: { marginBottom: 0 } },
|
||||
React.createElement(Row, { style: { flexWrap: 'nowrap', alignItems: 'stretch' } },
|
||||
React.createElement(Col, { flex: 1, style: { minWidth: 0, paddingRight: 40 } },
|
||||
React.createElement(Form, Object.assign({ layout: 'horizontal', form: filterForm }, formItemLayout),
|
||||
React.createElement(Row, { gutter: 24, style: { rowGap: 0 } },
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { name: 'filterPlate', label: '车牌号', style: { marginBottom: 16 } },
|
||||
React.createElement(Input, { placeholder: '支持模糊搜索', allowClear: true })
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { name: 'filterLevels', label: '故障等级', style: { marginBottom: 16 } },
|
||||
React.createElement(Select, {
|
||||
mode: 'multiple',
|
||||
allowClear: true,
|
||||
placeholder: '多选:L1~L4',
|
||||
options: faultLevelOptions,
|
||||
maxTagCount: 'responsive'
|
||||
})
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { name: 'filterDateRange', label: '上报时间', style: { marginBottom: 16 } },
|
||||
React.createElement(RangePicker, { style: { width: '100%' }, showTime: false, placeholder: ['开始', '结束'] })
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { name: 'filterTypes', label: '故障类型', style: { marginBottom: 16 } },
|
||||
React.createElement(Select, {
|
||||
mode: 'multiple',
|
||||
allowClear: true,
|
||||
placeholder: '多选故障类型',
|
||||
options: faultTypeOptions,
|
||||
maxTagCount: 'responsive'
|
||||
})
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { name: 'filterLastOperator', label: '最后操作人', style: { marginBottom: 16 } },
|
||||
React.createElement(Select, {
|
||||
allowClear: true,
|
||||
placeholder: '请选择',
|
||||
options: lastOperatorOptions
|
||||
})
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
React.createElement(Divider, {
|
||||
type: 'vertical',
|
||||
style: {
|
||||
alignSelf: 'stretch',
|
||||
height: 'auto',
|
||||
minHeight: 100,
|
||||
borderLeftColor: 'rgb(229, 230, 235)',
|
||||
borderLeftStyle: 'dashed',
|
||||
marginLeft: 20,
|
||||
marginRight: 20
|
||||
}
|
||||
}),
|
||||
React.createElement(Col, { flex: 'none', style: { textAlign: 'right', display: 'flex', flexDirection: 'column', alignItems: 'flex-end', minWidth: 100, maxWidth: 168 } },
|
||||
React.createElement(Space, { direction: 'vertical', size: 12, style: { width: '100%', alignItems: 'flex-end' } },
|
||||
React.createElement(Button, { type: 'primary', icon: React.createElement(SearchIcon, null), style: { display: 'flex', alignItems: 'center', gap: 6, justifyContent: 'center', width: 86 }, onClick: function () { applyListFilter(); message.success('已按条件筛选'); } }, '查询'),
|
||||
React.createElement(Button, {
|
||||
icon: React.createElement(ResetIcon, null),
|
||||
style: { display: 'flex', alignItems: 'center', gap: 6, justifyContent: 'center', width: 86 },
|
||||
onClick: function () {
|
||||
filterForm.resetFields();
|
||||
applyListFilter();
|
||||
message.info('已清空筛选条件');
|
||||
}
|
||||
}, '重置')
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
React.createElement(Divider, { style: { margin: '16px 0 20px', borderColor: '#e5e6eb' } }),
|
||||
|
||||
// 工具栏 + 表格
|
||||
React.createElement('div', { style: { display: 'flex', flexDirection: 'column', flex: 1, minWidth: 0 } },
|
||||
React.createElement(Row, { justify: 'space-between', align: 'middle', style: { marginBottom: 16 } },
|
||||
React.createElement(Col, null,
|
||||
React.createElement(Space, { size: 12 },
|
||||
React.createElement(Button, { type: 'primary', icon: React.createElement(PlusIcon, null), style: { display: 'flex', alignItems: 'center', gap: 6 }, onClick: handleCreate }, '新建'),
|
||||
React.createElement(Button, {
|
||||
style: { padding: '4px 10px', height: 32, display: 'flex', alignItems: 'center', gap: 6, color: '#4e5969' },
|
||||
onClick: function () { message.info('已导出当前筛选结果'); }
|
||||
}, React.createElement(DownloadIcon, null), React.createElement('span', null, '导出')),
|
||||
React.createElement(Button, { icon: React.createElement(UploadIcon, null), style: { display: 'flex', alignItems: 'center', gap: 6 }, onClick: function () { message.info('批量导入故障数据'); } }, '导入'),
|
||||
React.createElement(Button, { style: { color: '#4e5969' }, onClick: function () { message.info('字段展示配置(当前版本预留)'); } }, '展示设置')
|
||||
)
|
||||
),
|
||||
React.createElement(Col, null)
|
||||
),
|
||||
React.createElement(Tabs, {
|
||||
activeKey: listTab,
|
||||
onChange: function (k) {
|
||||
setListTab(k);
|
||||
},
|
||||
style: { marginBottom: 12 },
|
||||
items: [
|
||||
{ key: 'pending', label: '待处理' },
|
||||
{ key: 'history', label: '历史记录' }
|
||||
]
|
||||
}),
|
||||
React.createElement('div', { className: 'customer-table-scroll-wrap', style: { flex: 1, minHeight: 0, minWidth: 0 } },
|
||||
React.createElement(Table, {
|
||||
columns: columns,
|
||||
dataSource: displayData,
|
||||
pagination: {
|
||||
pageSize: 10,
|
||||
showSizeChanger: false,
|
||||
showTotal: function (total) { return '共 ' + total + ' 条'; }
|
||||
},
|
||||
scroll: { x: 2100 }
|
||||
})
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
renderSpecModal()
|
||||
);
|
||||
};
|
||||
|
||||
if (typeof module !== 'undefined' && module.exports) module.exports = Component;
|
||||
417
web端/运维管理/车辆业务/新增故障.jsx
Normal file
417
web端/运维管理/车辆业务/新增故障.jsx
Normal file
@@ -0,0 +1,417 @@
|
||||
// 【重要】必须使用 const Component 作为组件变量名
|
||||
// ONEOS-web - 运维管理 - 车辆业务 - 新增故障
|
||||
|
||||
const Component = function () {
|
||||
var useState = React.useState;
|
||||
var useEffect = React.useEffect;
|
||||
|
||||
var antd = window.antd;
|
||||
var Button = antd.Button;
|
||||
var Input = antd.Input;
|
||||
var Select = antd.Select;
|
||||
var DatePicker = antd.DatePicker;
|
||||
var Form = antd.Form;
|
||||
var Row = antd.Row;
|
||||
var Col = antd.Col;
|
||||
var Breadcrumb = antd.Breadcrumb;
|
||||
var Layout = antd.Layout;
|
||||
var message = antd.message;
|
||||
var Card = antd.Card;
|
||||
var Upload = antd.Upload;
|
||||
var Modal = antd.Modal;
|
||||
|
||||
var _form = Form.useForm();
|
||||
var faultForm = _form[0];
|
||||
|
||||
var _specOpen = useState(false);
|
||||
var specModalOpen = _specOpen[0];
|
||||
var setSpecModalOpen = _specOpen[1];
|
||||
|
||||
var _formDirty = useState(false);
|
||||
var formDirty = _formDirty[0];
|
||||
var setFormDirty = _formDirty[1];
|
||||
|
||||
var faultLevelOptions = [
|
||||
{ label: 'L1-特急', value: '特急' },
|
||||
{ label: 'L2-紧急', value: '紧急' },
|
||||
{ label: 'L3-一般', value: '一般' },
|
||||
{ label: 'L4-提示', value: '提示' }
|
||||
];
|
||||
|
||||
var faultTypeOptions = [
|
||||
{ label: '底盘故障', value: '底盘故障' },
|
||||
{ label: '三电故障', value: '三电故障' },
|
||||
{ label: '整车系统', value: '整车系统' },
|
||||
{ label: '燃料电池系统故障', value: '燃料电池系统故障' },
|
||||
{ label: '供氢系统故障', value: '供氢系统故障' },
|
||||
{ label: '空调系统故障', value: '空调系统故障' },
|
||||
{ label: '冷机故障', value: '冷机故障' },
|
||||
{ label: '其他故障', value: '其他故障' }
|
||||
];
|
||||
|
||||
var faultSourceOptions = [
|
||||
{ label: '客户报告', value: '客户报告' },
|
||||
{ label: '定期保养', value: '定期保养' },
|
||||
{ label: '周期性维护', value: '周期性维护' },
|
||||
{ label: '预防性维护', value: '预防性维护' },
|
||||
{ label: '整备', value: '整备' }
|
||||
];
|
||||
|
||||
var resolveStatusOptions = [
|
||||
{ label: '未解决', value: '未解决' },
|
||||
{ label: '临时排故', value: '临时排故' },
|
||||
{ label: '已解决', value: '已解决' }
|
||||
];
|
||||
|
||||
/** 运营公司枚举:浙江羚牛、上海羚牛、广东羚牛 */
|
||||
var plateOptions = [
|
||||
{ label: '沪A12345', value: '沪A12345', brand: '一汽解放', model: 'J6P', company: '上海羚牛', vin: 'LNW1234567890ABCD' },
|
||||
{ label: '浙B88888', value: '浙B88888', brand: '东风商用车', model: '天龙', company: '浙江羚牛', vin: 'LNW0987654321EFGH' },
|
||||
{ label: '粤A00001', value: '粤A00001', brand: '福田欧曼', model: 'EST', company: '广东羚牛', vin: 'LNW1357924680IJKL' },
|
||||
{ label: '沪D99999', value: '沪D99999', brand: '陕汽重卡', model: '德龙', company: '上海羚牛', vin: 'LNW2468013579MNOP' }
|
||||
];
|
||||
|
||||
var PlusIcon = function() { return React.createElement('svg', { viewBox: '0 0 1024 1024', width: 14, height: 14, fill: 'currentColor' }, React.createElement('path', { d: 'M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z' }), React.createElement('path', { d: 'M192 474h672q8 0 8 8v60q0 8-8 8H192q-8 0-8-8v-60q0-8 8-8z' })); };
|
||||
var FileTextIcon = function() { return React.createElement('svg', { viewBox: '0 0 1024 1024', width: 16, height: 16, fill: 'currentColor' }, React.createElement('path', { d: 'M854.6 288.7L639.4 73.4c-6-6-14.2-9.4-22.7-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216c0 22.1 17.9 40 40 40h216v494zM504 618H320c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h184c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zM702 458H320c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h382c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8z' })); };
|
||||
|
||||
var DESC_PLACEHOLDER = '在何种状态下\n产生何种现象\n导致何种事故';
|
||||
|
||||
var goBackList = function () {
|
||||
message.info('返回列表');
|
||||
};
|
||||
|
||||
var requestExit = function () {
|
||||
if (formDirty) {
|
||||
Modal.confirm({
|
||||
title: '确定要退出吗?',
|
||||
content: '未保存的数据将丢失',
|
||||
okText: '确定',
|
||||
cancelText: '取消',
|
||||
onOk: function () {
|
||||
setFormDirty(false);
|
||||
goBackList();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
goBackList();
|
||||
}
|
||||
};
|
||||
|
||||
var openResultModal = function (title, okText, cancelText, onPrimary) {
|
||||
Modal.success({
|
||||
title: title,
|
||||
content: title === '提交成功' ? '故障已提交并加入历史记录。' : '单据已保存在待处理,可继续编辑或稍后提交。',
|
||||
okText: okText,
|
||||
cancelText: cancelText,
|
||||
okCancel: true,
|
||||
centered: true,
|
||||
onOk: function () {
|
||||
if (onPrimary) onPrimary();
|
||||
},
|
||||
onCancel: function () {}
|
||||
});
|
||||
};
|
||||
|
||||
var handleSave = function () {
|
||||
// 弱校验:不触发表单校验;落库时解决情况空值按「未解决」与列表一致
|
||||
faultForm.getFieldsValue();
|
||||
setFormDirty(false);
|
||||
openResultModal('保存成功', '返回列表', '确定', goBackList);
|
||||
};
|
||||
|
||||
var runSubmit = function () {
|
||||
faultForm.validateFields(['plate', 'type', 'source', 'level', 'reportTime', 'desc']).then(function () {
|
||||
var list = faultForm.getFieldValue('evidence') || [];
|
||||
if (!list.length) {
|
||||
message.error('请上传故障证据');
|
||||
return;
|
||||
}
|
||||
setFormDirty(false);
|
||||
openResultModal('提交成功', '返回列表', '确定', goBackList);
|
||||
}).catch(function () {});
|
||||
};
|
||||
|
||||
var handleSubmitClick = function () {
|
||||
Modal.confirm({
|
||||
title: '确认提交',
|
||||
content: '故障提交后无法修改,如未完成所有步骤填写请先进行保存。点击确认加入历史记录',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
centered: true,
|
||||
onOk: function () {
|
||||
runSubmit();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(function () {
|
||||
var fn = function (e) {
|
||||
if (formDirty) {
|
||||
e.preventDefault();
|
||||
e.returnValue = '';
|
||||
}
|
||||
};
|
||||
window.addEventListener('beforeunload', fn);
|
||||
return function () { window.removeEventListener('beforeunload', fn); };
|
||||
}, [formDirty]);
|
||||
|
||||
var specSection = function (title, lines) {
|
||||
return React.createElement('div', { style: { marginBottom: 16 } },
|
||||
React.createElement('div', { style: { fontWeight: 600, color: '#1d2129', marginBottom: 8, fontSize: 14 } }, title),
|
||||
lines.map(function (text, i) {
|
||||
return React.createElement('div', { key: i, style: { fontSize: 13, color: '#4e5969', lineHeight: 1.75 } }, text);
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
var renderSpecModal = function () {
|
||||
return React.createElement(Modal, {
|
||||
title: '故障信息表单页 — 需求说明',
|
||||
open: specModalOpen,
|
||||
onCancel: function () { setSpecModalOpen(false); },
|
||||
footer: React.createElement(Button, { type: 'primary', onClick: function () { setSpecModalOpen(false); } }, '知道了'),
|
||||
width: 720,
|
||||
centered: true,
|
||||
destroyOnClose: true
|
||||
},
|
||||
React.createElement('div', { style: { maxHeight: '70vh', overflowY: 'auto', paddingRight: 4 } },
|
||||
specSection('3. 故障信息表单页', ['用于新增/编辑故障记录,保存到待处理或提交到历史记录。']),
|
||||
specSection('3.1 车辆信息卡片(自动带出)', [
|
||||
'3.1.1 车牌号:必填,下拉可搜索;',
|
||||
'3.1.2 车辆品牌:禁用,随车牌自动反填;',
|
||||
'3.1.3 车辆型号:禁用,随车牌自动反填;',
|
||||
'3.1.4 车辆识别代码:禁用,随车牌自动反填;',
|
||||
'3.1.5 运营公司:禁用,随车牌自动反填。',
|
||||
'3.1.6 运营公司枚举统一为:浙江羚牛、上海羚牛、广东羚牛。'
|
||||
]),
|
||||
specSection('3.2 故障信息卡片', [
|
||||
'3.2.1 故障类型:必填,下拉选择;',
|
||||
'3.2.2 故障来源:必填,下拉选择,选项:客户报告、定期保养、周期性维护、预防性维护、整备;',
|
||||
'3.2.3 故障等级:必填,下拉选择;',
|
||||
'3.2.4 故障上报时间:必填,日期时间选择器;',
|
||||
'3.2.5 解决情况:选填,下拉选择,选项:临时排故、已解决、未解决。'
|
||||
]),
|
||||
specSection('3.3 故障描述与证据卡片(顺序已调整)', [
|
||||
'3.3.1 故障描述:必填,多行文本,默认引导语:在何种状态下 / 产生何种现象 / 导致何种事故;',
|
||||
'3.3.2 故障证据:提交时必填,上传控件,支持照片/视频/录音;',
|
||||
'提示文案:支持上传照片、视频、录音。'
|
||||
]),
|
||||
specSection('4. 底部操作按钮组', [
|
||||
'控制保存与提交流程。',
|
||||
'4.1 保存按钮:保存当前已填写内容,不做严格必填校验,单据留在待处理;',
|
||||
'4.2 提交按钮:执行严格校验(含带*字段及故障证据);',
|
||||
'4.3 点击提交先弹确认提示:故障提交后无法修改… 按钮:取消 / 确认;',
|
||||
'4.4 提交成功后提示提交成功,并提供确定/返回列表;',
|
||||
'4.5 保存成功后提示保存成功,并提供确定/返回列表。'
|
||||
]),
|
||||
specSection('5. 联动与校验规则', [
|
||||
'5.1 车牌联动:自动反填车辆品牌、车辆型号、车辆识别代码、运营公司;',
|
||||
'5.2 保存校验:弱校验(允许未填必填项);',
|
||||
'5.3 提交校验:强校验(必填项+故障证据);',
|
||||
'5.4 解决情况默认值兜底:未填写时按未解决处理(列表展示与保存一致)。'
|
||||
]),
|
||||
specSection('6. 退出与返回拦截规则', [
|
||||
'6.1 表单发生修改且未保存时,触发返回/关闭/刷新拦截;',
|
||||
'6.2 弹窗文案:确定要退出吗?未保存的数据将丢失;',
|
||||
'6.3 按钮:确定 / 取消;',
|
||||
'6.4 已保存后再退出,不触发该拦截。'
|
||||
])
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
return React.createElement(Layout, { className: 'arco-theme-overrides', style: { minHeight: '100vh', background: '#f2f3f5', fontFamily: 'Inter, Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif' } },
|
||||
React.createElement('style', null, `
|
||||
.arco-theme-overrides .ant-btn { border-radius: 4px; }
|
||||
.arco-theme-overrides .ant-btn-primary { background-color: #165dff; border-color: #165dff; }
|
||||
.arco-theme-overrides .ant-btn-primary:hover { background-color: #4080ff; border-color: #4080ff; }
|
||||
|
||||
.arco-grouped-form-page { display: flex; flex-direction: column; min-height: 100vh; }
|
||||
.arco-grouped-form-page-content { flex: 1; padding: 16px 20px 24px; }
|
||||
.arco-grouped-form-page .ant-card { margin-bottom: 16px; border-radius: 4px; border: none; box-shadow: 0 1px 2px rgba(0,0,0,0.06); }
|
||||
.arco-grouped-form-page .ant-card-head { border-bottom: none; padding: 20px 24px 0; min-height: auto; }
|
||||
.arco-grouped-form-page .ant-card-head-title { font-size: 16px; font-weight: 500; color: #1d2129; padding: 0; }
|
||||
.arco-grouped-form-page .ant-card-body { padding: 24px; }
|
||||
.arco-grouped-form-page .ant-form-vertical .ant-form-item-label { padding-bottom: 8px; height: auto; line-height: 1.5715; }
|
||||
.arco-grouped-form-page .ant-form-item { margin-bottom: 24px; }
|
||||
|
||||
.arco-grouped-form-page .ant-input,
|
||||
.arco-grouped-form-page .ant-select-selector,
|
||||
.arco-grouped-form-page .ant-picker,
|
||||
.arco-grouped-form-page .ant-input-affix-wrapper { background-color: #f2f3f5; border: 1px solid #e5e6eb; border-radius: 2px; transition: all 0.1s cubic-bezier(0, 0, 1, 1); }
|
||||
.arco-grouped-form-page .ant-input:hover,
|
||||
.arco-grouped-form-page .ant-select:not(.ant-select-disabled):hover .ant-select-selector,
|
||||
.arco-grouped-form-page .ant-picker:hover,
|
||||
.arco-grouped-form-page .ant-input-affix-wrapper:hover { background-color: #f2f3f5; border-color: #165dff; }
|
||||
.arco-grouped-form-page .ant-input:focus,
|
||||
.arco-grouped-form-page .ant-input-focused,
|
||||
.arco-grouped-form-page .ant-select-focused .ant-select-selector,
|
||||
.arco-grouped-form-page .ant-picker-focused,
|
||||
.arco-grouped-form-page .ant-input-affix-wrapper-focused { background-color: #fff; border: 1px solid #165dff !important; box-shadow: 0 0 0 2px rgba(22, 93, 255, 0.2) !important; outline: 0; }
|
||||
.arco-grouped-form-page .ant-input[disabled],
|
||||
.arco-grouped-form-page .ant-select-disabled .ant-select-selector,
|
||||
.arco-grouped-form-page .ant-picker-disabled { color: #86909c; background-color: #f2f3f5; border-color: #e5e6eb; cursor: not-allowed; }
|
||||
.arco-grouped-form-page .ant-input-affix-wrapper[disabled] { background-color: #f2f3f5; border-color: #e5e6eb; cursor: not-allowed; }
|
||||
.arco-grouped-form-page .ant-input-affix-wrapper > input.ant-input { background-color: transparent; }
|
||||
.arco-grouped-form-page .ant-input-affix-wrapper > input.ant-input:focus { background-color: transparent; box-shadow: none !important; border: none !important; }
|
||||
|
||||
.arco-grouped-form-footer { background: #fff; padding: 16px 24px; border-top: 1px solid #e5e6eb; display: flex; justify-content: flex-end; align-items: center; gap: 12px; position: sticky; bottom: 0; z-index: 100; box-shadow: 0 -2px 10px rgba(0,0,0,0.05); }
|
||||
.arco-grouped-form-footer .ant-btn { border-radius: 5px; height: 32px; padding: 4px 16px; font-size: 14px; }
|
||||
|
||||
.arco-theme-overrides .ant-breadcrumb { color: #86909c; font-size: 14px; white-space: nowrap; flex-shrink: 0; margin-bottom: 0; }
|
||||
.arco-theme-overrides .ant-breadcrumb a { color: #4e5969; }
|
||||
.arco-theme-overrides .ant-breadcrumb a:hover { color: #165dff; background-color: transparent; }
|
||||
.arco-theme-overrides .ant-form-item-label > label { color: #4e5969; white-space: nowrap; }
|
||||
.arco-theme-overrides .ant-form-item-label > label::after { display: none !important; content: "" !important; margin: 0 !important; }
|
||||
`),
|
||||
React.createElement('div', { className: 'arco-grouped-form-page' },
|
||||
React.createElement('div', { className: 'arco-grouped-form-page-content' },
|
||||
React.createElement('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 20, flexWrap: 'nowrap', gap: 12 } },
|
||||
React.createElement(Breadcrumb, {
|
||||
separator: React.createElement('span', { style: { color: '#c9cdd4' } }, '/'),
|
||||
items: [
|
||||
{ title: '首页' },
|
||||
{ title: '运维管理' },
|
||||
{ title: '车辆业务' },
|
||||
{ title: React.createElement('a', { href: '#', onClick: function (e) { e.preventDefault(); requestExit(); } }, '故障管理') },
|
||||
{ title: React.createElement('span', { style: { color: '#1d2129' } }, '新建故障单') }
|
||||
]
|
||||
}),
|
||||
React.createElement(Button, {
|
||||
type: 'link',
|
||||
icon: React.createElement(FileTextIcon, null),
|
||||
style: { display: 'flex', alignItems: 'center', gap: 4, padding: '0 4px', color: '#165dff', fontWeight: 500, flexShrink: 0 },
|
||||
onClick: function () { setSpecModalOpen(true); }
|
||||
}, '查看需求说明')
|
||||
),
|
||||
|
||||
React.createElement(Form, {
|
||||
form: faultForm,
|
||||
layout: 'vertical',
|
||||
onValuesChange: function () {
|
||||
setFormDirty(true);
|
||||
}
|
||||
},
|
||||
React.createElement(Card, { title: '车辆信息', bordered: false },
|
||||
React.createElement(Row, { gutter: 24 },
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '车牌号', name: 'plate', rules: [{ required: true, message: '请选择车牌号' }] },
|
||||
React.createElement(Select, {
|
||||
placeholder: '请选择车牌号(可搜索)',
|
||||
options: plateOptions,
|
||||
showSearch: true,
|
||||
optionFilterProp: 'label',
|
||||
onChange: function (val, option) {
|
||||
if (option) {
|
||||
faultForm.setFieldsValue({
|
||||
brand: option.brand,
|
||||
model: option.model,
|
||||
company: option.company,
|
||||
vin: option.vin
|
||||
});
|
||||
} else {
|
||||
faultForm.setFieldsValue({ brand: undefined, model: undefined, company: undefined, vin: undefined });
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '车辆品牌', name: 'brand' },
|
||||
React.createElement(Input, { placeholder: '自动带入', disabled: true, style: { backgroundColor: '#f2f3f5', color: '#86909c' } })
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '车辆型号', name: 'model' },
|
||||
React.createElement(Input, { placeholder: '自动带入', disabled: true, style: { backgroundColor: '#f2f3f5', color: '#86909c' } })
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '车辆识别代码', name: 'vin' },
|
||||
React.createElement(Input, { placeholder: '自动带入', disabled: true, style: { backgroundColor: '#f2f3f5', color: '#86909c' } })
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '运营公司', name: 'company' },
|
||||
React.createElement(Input, { placeholder: '自动带入', disabled: true, style: { backgroundColor: '#f2f3f5', color: '#86909c' } })
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
React.createElement(Card, { title: '故障信息', bordered: false },
|
||||
React.createElement(Row, { gutter: 24 },
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '故障类型', name: 'type', rules: [{ required: true, message: '请选择故障类型' }] },
|
||||
React.createElement(Select, { placeholder: '请选择故障类型', options: faultTypeOptions })
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '故障来源', name: 'source', rules: [{ required: true, message: '请选择故障来源' }] },
|
||||
React.createElement(Select, { placeholder: '请选择故障来源', options: faultSourceOptions })
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '故障等级', name: 'level', rules: [{ required: true, message: '请选择故障等级' }] },
|
||||
React.createElement(Select, { placeholder: '请选择故障等级', options: faultLevelOptions })
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '故障上报时间', name: 'reportTime', rules: [{ required: true, message: '请选择故障上报时间' }] },
|
||||
React.createElement(DatePicker, { style: { width: '100%' }, placeholder: '请选择上报时间', showTime: true })
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '解决情况', name: 'status', extra: '选填;保存时未填按「未解决」处理' },
|
||||
React.createElement(Select, { allowClear: true, placeholder: '请选择(可选)', options: resolveStatusOptions })
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
React.createElement(Card, { title: '故障描述与证据', bordered: false },
|
||||
React.createElement(Row, { gutter: 24 },
|
||||
React.createElement(Col, { span: 24 },
|
||||
React.createElement(Form.Item, { label: '故障描述', name: 'desc', rules: [{ required: true, message: '请填写故障描述' }] },
|
||||
React.createElement(Input.TextArea, {
|
||||
placeholder: DESC_PLACEHOLDER,
|
||||
style: { minHeight: 104, height: 104, resize: 'none' }
|
||||
})
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 24 },
|
||||
React.createElement(Form.Item, {
|
||||
label: '故障证据',
|
||||
name: 'evidence',
|
||||
valuePropName: 'fileList',
|
||||
getValueFromEvent: function (e) { return (e && e.fileList) ? e.fileList : []; }
|
||||
},
|
||||
React.createElement(Upload, {
|
||||
listType: 'picture-card',
|
||||
beforeUpload: function () { return false; },
|
||||
multiple: true,
|
||||
accept: 'image/*,video/*,audio/*'
|
||||
},
|
||||
React.createElement('div', null,
|
||||
React.createElement(PlusIcon, null),
|
||||
React.createElement('div', { style: { marginTop: 8 } }, '上传文件')
|
||||
)
|
||||
),
|
||||
React.createElement('div', { style: { fontSize: 12, color: '#86909c', marginTop: 8 } }, '支持上传照片、视频、录音')
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
React.createElement('div', { className: 'arco-grouped-form-footer' },
|
||||
React.createElement(Button, { onClick: requestExit, style: { borderRadius: 5 } }, '取消'),
|
||||
React.createElement(Button, { onClick: handleSave, style: { borderRadius: 5 } }, '保存'),
|
||||
React.createElement(Button, { type: 'primary', onClick: handleSubmitClick, style: { borderRadius: 5 } }, '提交')
|
||||
)
|
||||
),
|
||||
renderSpecModal()
|
||||
);
|
||||
};
|
||||
|
||||
if (typeof module !== 'undefined' && module.exports) module.exports = Component;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
// 【重要】必须使用 const Component 作为组件变量名
|
||||
// 运维管理 - 车辆业务 - 替换车管理 - 查看(2026年3月3日版本)
|
||||
// 运维管理 - 车辆业务 - 替换车管理 - 查看
|
||||
|
||||
const Component = function () {
|
||||
var useState = React.useState;
|
||||
@@ -10,61 +10,290 @@ const Component = function () {
|
||||
var Input = antd.Input;
|
||||
var Button = antd.Button;
|
||||
var Modal = antd.Modal;
|
||||
var Tag = antd.Tag;
|
||||
var Steps = antd.Steps;
|
||||
|
||||
var EMPTY_PROJECT = {
|
||||
contractId: '',
|
||||
projectId: '',
|
||||
projectName: '',
|
||||
projectType: '',
|
||||
customerName: '',
|
||||
contractCode: '',
|
||||
deliveryRegion: ''
|
||||
};
|
||||
|
||||
var activeContracts = [
|
||||
{
|
||||
contractId: 'c1',
|
||||
contractStatus: '合同进行中',
|
||||
projectId: 'p1',
|
||||
projectName: '嘉兴氢能示范项目',
|
||||
projectType: '租赁',
|
||||
contractCode: 'HT-ZL-2025-001',
|
||||
customerName: '嘉兴某某物流有限公司',
|
||||
deliveryRegion: '浙江省-嘉兴市'
|
||||
}
|
||||
];
|
||||
|
||||
var MOCK_PAIRS = [
|
||||
{
|
||||
id: 'pair_1',
|
||||
replaceType: '永久替换',
|
||||
replaceReason: '车辆原因',
|
||||
replaceReasonDesc: '原车故障需维修,临时用替换车保障客户用车。',
|
||||
originalPlate: '浙A12345',
|
||||
originalBrand: '东风',
|
||||
originalModel: 'DFH1180',
|
||||
contractId: 'c1',
|
||||
replacePlate: '浙A67890',
|
||||
replaceBrand: '福田',
|
||||
replaceModel: 'BJ1180'
|
||||
},
|
||||
{
|
||||
id: 'pair_2',
|
||||
replaceType: '临时替换',
|
||||
replaceReason: '客户原因',
|
||||
replaceReasonDesc: '',
|
||||
originalPlate: '浙A55555',
|
||||
originalBrand: '重汽',
|
||||
originalModel: 'ZZ1160',
|
||||
contractId: 'c1',
|
||||
replacePlate: '浙A66666',
|
||||
replaceBrand: '江淮',
|
||||
replaceModel: 'HFC1190'
|
||||
}
|
||||
];
|
||||
|
||||
var contractById = (function () {
|
||||
var map = {};
|
||||
activeContracts.forEach(function (c) { map[c.contractId] = c; });
|
||||
return map;
|
||||
})();
|
||||
|
||||
var pairs = MOCK_PAIRS;
|
||||
var requirementModalVisible = useState(false);
|
||||
var setRequirementModalVisible = requirementModalVisible[1];
|
||||
|
||||
// 模拟:根据已填信息反查的一条替换车记录(实际由路由参数或接口拉取)
|
||||
var detail = useState({
|
||||
projectName: '嘉兴氢能示范项目',
|
||||
contractCode: 'HT-ZL-2025-001',
|
||||
customerName: '嘉兴某某物流有限公司',
|
||||
contactPerson: '张三',
|
||||
signDate: '2025-01-15',
|
||||
contactPhone: '13800138001',
|
||||
businessDept: '业务1部',
|
||||
businessPerson: '张经理',
|
||||
replaceDate: '2026-02-18',
|
||||
replaceType: '永久替换',
|
||||
replaceReason: '车辆原因',
|
||||
replaceReasonDesc: '原车故障需维修,临时用替换车保障客户用车。',
|
||||
originalPlate: '浙A12345',
|
||||
originalVin: 'LGHXCAE28M1234567',
|
||||
originalBrand: '东风',
|
||||
originalModel: 'DFH1180',
|
||||
replacePlate: '浙A67890',
|
||||
replaceVin: 'LGHXCAE28M6789012',
|
||||
replaceBrand: '福田',
|
||||
replaceModel: 'BJ1180'
|
||||
});
|
||||
var data = detail[0];
|
||||
var projectInfo = (function () {
|
||||
var anchor = pairs.find(function (p) { return p.originalPlate && p.contractId; });
|
||||
if (!anchor || !anchor.contractId) return EMPTY_PROJECT;
|
||||
var c = contractById[anchor.contractId];
|
||||
if (!c) return EMPTY_PROJECT;
|
||||
return {
|
||||
contractId: c.contractId,
|
||||
projectId: c.projectId,
|
||||
projectName: c.projectName,
|
||||
projectType: c.projectType,
|
||||
customerName: c.customerName,
|
||||
contractCode: c.contractCode,
|
||||
deliveryRegion: c.deliveryRegion
|
||||
};
|
||||
})();
|
||||
|
||||
var handleBack = function () {
|
||||
// 返回替换车管理列表页(实际为路由或平台跳转)
|
||||
if (window.__replaceCarBack) {
|
||||
window.__replaceCarBack();
|
||||
} else {
|
||||
antd.message.info('返回替换车管理列表(原型)');
|
||||
}
|
||||
};
|
||||
|
||||
var layoutStyle = { padding: '16px 24px', background: '#f5f5f5', minHeight: '100vh' };
|
||||
var cardStyle = { marginBottom: 16 };
|
||||
var labelStyle = { marginBottom: 6, fontSize: 14, color: 'rgba(0,0,0,0.65)' };
|
||||
var formRowStyle = { display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: '16px 24px', marginBottom: 16 };
|
||||
var formItemStyle = { marginBottom: 12 };
|
||||
|
||||
// 审批情况(竖排步骤条,参照提车应收款-审核)
|
||||
var approvalSteps = [
|
||||
{ title: '业务部主管', person: '姚守涛', status: 'finish', approveTime: '2026-02-20 09:30' },
|
||||
{ title: '事业部主管', person: '尚建华', status: 'finish', approveTime: '2026-02-20 10:15' },
|
||||
{ title: '运维主管', person: '王运维', status: 'finish', approveTime: '2026-02-20 11:00' }
|
||||
];
|
||||
var requirementContent = '替换车管理-查看(2026年3月3日版本)\n一个「数字化资产ONEOS运管平台」中的「运维管理」「车辆业务」「替换车管理」「查看」模块\n1.面包屑:\n#运维管理-车辆业务-替换车管理-查看\n页面由选择项目、替换车详情、两个单独卡片组成;\n\n2.选择项目:\n#可通过选择进行中的车辆租赁合同,拉取租赁合同中对应车辆进行替换;\n2.1.项目名称:根据已填信息反查,不可编辑;\n2.2.合同编码:根据项目名称自动反查,不可编辑;\n2.3.客户名称:根据项目名称自动反查,不可编辑;\n2.4.对接人:根据项目名称自动反查,不可编辑;\n2.5.合同签订时间:根据项目名称自动反查,不可编辑;\n2.6.客户联系电话:根据项目名称自动反查,不可编辑;\n2.7.业务部门:根据项目名称自动反查,不可编辑;\n2.8.业务人员:根据项目名称自动反查,不可编辑;\n\n3.替换车详情:\n3.1.替换时间:日期选择器(禁用),显示退换时间,格式为YYYY-MM-DD;\n3.2.替换类型:选择器,根据已填信息反查,不可编辑;\n 3.2.1.类型为永久替换时,该申请通过审核后替换车进行交车(交车时间为流程结束当天),由运维手动将被替换车进行还车;\n 3.2.2.类型为临时替换时,该申请通过审核后替换车进行交车(交车时间为流程结束当天),被替换车不用还车,在被替换车重新交付客户时,由运维手动将替换车进行还车;\n 重新生成交车任务时,交车地点会自动继承自合同,由对应区域运维人员才能操作;\n 交车任务完成后,所有涉及到被替换车辆显示(例如车辆租赁合同、租赁账单、提车应收款等功能)会替换为新替换车的对应信息,如果是临时替换,在新替换车完成还车后,对应车辆记录会恢复为原有车辆数据。如果是永久替换,则由运维自主进行被替换车辆还车;\n3.3.替换原因:选择器,根据已填信息反查,不可编辑;\n3.4.替换原因说明:文本域,根据已填信息反查,不可编辑;\n3.5.被替换车牌号:选择器,根据已填信息反查,不可编辑;\n3.6.被替换车识别代码:输入框(禁用),选择被替换车车牌号后自动反写该车识别代码;\n3.7.被替换车品牌:输入框(禁用),选择被替换车车牌号后自动反写该车品牌;\n3.8.被替换车型号:输入框(禁用),选择被替换车车牌号后自动反写该车型号;\n3.9.替换车车牌号:选择器,根据已填信息反查,不可编辑;\n3.10.替换车识别代码:输入框(禁用),选择替换车车牌号后自动反写该车识别代码;\n3.11.替换车品牌:输入框(禁用),选择替换车车牌号后自动反写该车品牌;\n3.12.替换车型号:输入框(禁用),选择替换车车牌号后自动反写该车型号;\n\n下方为返回按钮;\n4.1.点击返回,返回替换车管理列表页;';
|
||||
|
||||
return React.createElement('div', { style: layoutStyle },
|
||||
React.createElement('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 16 } },
|
||||
var handleBack = function () {
|
||||
if (window.__replaceCarBack) window.__replaceCarBack();
|
||||
else antd.message.info('返回替换车管理列表(原型)');
|
||||
};
|
||||
|
||||
var pageCss =
|
||||
'.vr-add-page{font-family:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif}' +
|
||||
'.vr-add-page .vr-page-header{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;margin-bottom:20px}' +
|
||||
'.vr-add-page .vr-main-card{border-radius:16px;border:none;box-shadow:0 4px 24px -6px rgba(15,23,42,0.08),0 0 0 1px rgba(15,23,42,0.05)}' +
|
||||
'.vr-add-page .vr-main-card>.ant-card-head{border-bottom:1px solid #f1f5f9;padding:16px 24px;min-height:auto}' +
|
||||
'.vr-add-page .vr-main-card>.ant-card-head .ant-card-head-title{font-size:16px;font-weight:600;color:#0f172a;padding:0}' +
|
||||
'.vr-add-page .vr-main-card>.ant-card-body{padding:20px 24px 24px}' +
|
||||
'.vr-add-page .vr-approval-card{border-radius:16px;border:none;box-shadow:0 4px 24px -6px rgba(15,23,42,0.08),0 0 0 1px rgba(15,23,42,0.05);margin-top:16px}' +
|
||||
'.vr-add-page .vr-pair-list{display:flex;flex-direction:column;gap:16px}' +
|
||||
'.vr-add-page .vr-pair-card{border-radius:12px;border:1px solid #e2e8f0;background:#f8fafc;overflow:hidden}' +
|
||||
'.vr-add-page .vr-pair-card__head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 16px;background:#f0f9ff;border-bottom:1px solid #e0f2fe}' +
|
||||
'.vr-add-page .vr-pair-card__title{display:flex;align-items:center;gap:8px;font-size:14px;font-weight:600;color:#0f172a;flex-wrap:wrap}' +
|
||||
'.vr-add-page .vr-pair-card__arrow{display:inline-flex;align-items:center;justify-content:center;color:#1677ff;font-size:16px;font-weight:600;line-height:1;padding:0 2px;flex-shrink:0}' +
|
||||
'.vr-add-page .vr-pair-card__index{display:inline-flex;align-items:center;justify-content:center;min-width:24px;height:24px;padding:0 8px;border-radius:6px;background:#1677ff;color:#fff;font-size:12px;font-weight:700}' +
|
||||
'.vr-add-page .vr-pair-card__body{padding:16px}' +
|
||||
'.vr-add-page .vr-block{margin-bottom:14px}' +
|
||||
'.vr-add-page .vr-block:last-child{margin-bottom:0}' +
|
||||
'.vr-add-page .vr-block-label{font-size:12px;font-weight:600;color:#475569;margin-bottom:10px}' +
|
||||
'.vr-add-page .vr-block-label--new{color:#047857}' +
|
||||
'.vr-add-page .vr-form-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px 16px}' +
|
||||
'.vr-add-page .vr-form-grid--reason .vr-field:last-child{grid-column:1/-1}' +
|
||||
'@media(max-width:900px){.vr-add-page .vr-form-grid{grid-template-columns:1fr}}' +
|
||||
'.vr-add-page .vr-field{display:flex;flex-direction:column;gap:6px;min-width:0}' +
|
||||
'.vr-add-page .vr-field__label{font-size:13px;font-weight:500;color:#334155}' +
|
||||
'.vr-add-page .vr-swap-divider{display:flex;align-items:center;gap:12px;margin:14px 0;color:#94a3b8;font-size:12px;font-weight:500}' +
|
||||
'.vr-add-page .vr-swap-divider::before,.vr-add-page .vr-swap-divider::after{content:"";flex:1;height:1px;background:linear-gradient(90deg,transparent,#cbd5e1,transparent)}' +
|
||||
'.vr-add-page .vr-swap-divider__icon{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:50%;background:#eff6ff;color:#1677ff;font-size:14px}' +
|
||||
'.vr-add-page .vr-vehicle-summary{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px 16px;padding:12px 14px;margin-bottom:14px;border-radius:8px;background:#fffbeb;border:1px solid #fde68a}' +
|
||||
'.vr-add-page .vr-project-panel{margin-top:20px;padding:16px 18px;border-radius:12px;background:#f8fafc;border:1px solid #e2e8f0}' +
|
||||
'.vr-add-page .vr-project-panel__title{font-size:14px;font-weight:600;color:#0f172a;margin-bottom:14px}' +
|
||||
'.vr-add-page .vr-project-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px 20px}' +
|
||||
'.vr-add-page .vr-readonly{display:flex;flex-direction:column;gap:4px}' +
|
||||
'.vr-add-page .vr-readonly__label{font-size:12px;color:#64748b;font-weight:500}' +
|
||||
'.vr-add-page .vr-readonly__value{font-size:14px;color:#0f172a;font-weight:500}' +
|
||||
'.vr-add-page .vr-footer{display:flex;gap:10px;margin-top:24px;padding-top:20px;border-top:1px solid #f1f5f9}' +
|
||||
'.vr-req-doc{padding:4px 2px 8px}' +
|
||||
'.vr-req-doc__meta{font-size:12px;color:#64748b;line-height:1.6;margin-bottom:16px;padding-bottom:12px;border-bottom:1px solid #f1f5f9}' +
|
||||
'.vr-req-doc__section{margin-bottom:20px}' +
|
||||
'.vr-req-doc__title{font-size:15px;font-weight:600;color:#0f172a;margin:0 0 10px}' +
|
||||
'.vr-req-doc__line{font-size:13px;color:#475569;line-height:1.75;margin:0 0 6px}' +
|
||||
'.vr-req-doc__line--sub{padding-left:14px;color:#64748b}';
|
||||
|
||||
function specSection(title, lines) {
|
||||
return React.createElement(
|
||||
'section',
|
||||
{ className: 'vr-req-doc__section' },
|
||||
React.createElement('h3', { className: 'vr-req-doc__title' }, title),
|
||||
(lines || []).map(function (text, i) {
|
||||
var isSub = text.indexOf(' ') === 0;
|
||||
return React.createElement('p', { key: i, className: 'vr-req-doc__line' + (isSub ? ' vr-req-doc__line--sub' : '') }, text);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function renderRequirementDoc() {
|
||||
return React.createElement(
|
||||
'div',
|
||||
{ className: 'vr-req-doc' },
|
||||
React.createElement('div', { className: 'vr-req-doc__meta' }, '数字化资产 ONEOS 运管平台 · 运维管理 · 车辆业务 · 替换车管理 · 查看'),
|
||||
specSection('1. 页面定位', ['只读查看替换车申请详情,布局与新增/编辑一致,不可修改任何字段。']),
|
||||
specSection('2. 展示内容', [
|
||||
'2.1 车辆替换明细:每条被替换车一张卡片,含被替换车信息、替换说明、替换车辆;卡片标题展示被替换与替换车牌。',
|
||||
'2.2 项目信息:客户名称、项目名称、项目类型(全单一份)。',
|
||||
'2.3 审批情况:竖向步骤条展示审批节点、审批人、审批时间。'
|
||||
]),
|
||||
specSection('3. 操作', ['底部仅「返回」按钮,返回替换车管理列表。'])
|
||||
);
|
||||
}
|
||||
|
||||
function renderField(label, node) {
|
||||
return React.createElement(
|
||||
'div',
|
||||
{ className: 'vr-field' },
|
||||
React.createElement('div', { className: 'vr-field__label' }, label),
|
||||
node
|
||||
);
|
||||
}
|
||||
|
||||
function renderPairCard(pair, index) {
|
||||
return React.createElement(
|
||||
'article',
|
||||
{ key: pair.id, className: 'vr-pair-card' },
|
||||
React.createElement(
|
||||
'div',
|
||||
{ className: 'vr-pair-card__head' },
|
||||
React.createElement(
|
||||
'div',
|
||||
{ className: 'vr-pair-card__title' },
|
||||
React.createElement('span', { className: 'vr-pair-card__index' }, index + 1),
|
||||
React.createElement('span', null, '车辆替换'),
|
||||
React.createElement(Tag, { style: { margin: 0 } }, pair.originalPlate),
|
||||
pair.replacePlate
|
||||
? React.createElement('span', { className: 'vr-pair-card__arrow', 'aria-hidden': true }, '→')
|
||||
: null,
|
||||
pair.replacePlate
|
||||
? React.createElement(Tag, { color: 'processing', style: { margin: 0 } }, pair.replacePlate)
|
||||
: null
|
||||
)
|
||||
),
|
||||
React.createElement(
|
||||
'div',
|
||||
{ className: 'vr-pair-card__body' },
|
||||
React.createElement(
|
||||
'div',
|
||||
{ className: 'vr-vehicle-summary' },
|
||||
renderField('车牌号', React.createElement(Input, { value: pair.originalPlate, disabled: true })),
|
||||
renderField('品牌', React.createElement(Input, { value: pair.originalBrand, disabled: true })),
|
||||
renderField('型号', React.createElement(Input, { value: pair.originalModel, disabled: true }))
|
||||
),
|
||||
React.createElement(
|
||||
'div',
|
||||
{ className: 'vr-block' },
|
||||
React.createElement('div', { className: 'vr-block-label' }, '替换说明'),
|
||||
React.createElement(
|
||||
'div',
|
||||
{ className: 'vr-form-grid vr-form-grid--reason' },
|
||||
renderField('替换类型', React.createElement(Input, { value: pair.replaceType, disabled: true })),
|
||||
renderField('替换原因', React.createElement(Input, { value: pair.replaceReason, disabled: true })),
|
||||
renderField(
|
||||
'替换原因说明',
|
||||
React.createElement(Input.TextArea, {
|
||||
value: pair.replaceReasonDesc || '—',
|
||||
disabled: true,
|
||||
rows: 2,
|
||||
style: { width: '100%' }
|
||||
})
|
||||
)
|
||||
)
|
||||
),
|
||||
React.createElement(
|
||||
'div',
|
||||
{ className: 'vr-swap-divider' },
|
||||
React.createElement('span', { className: 'vr-swap-divider__icon' }, '↓'),
|
||||
React.createElement('span', null, '替换为')
|
||||
),
|
||||
React.createElement(
|
||||
'div',
|
||||
{ className: 'vr-block' },
|
||||
React.createElement('div', { className: 'vr-block-label vr-block-label--new' }, '替换车辆'),
|
||||
React.createElement(
|
||||
'div',
|
||||
{ className: 'vr-form-grid' },
|
||||
renderField('新车', React.createElement(Input, { value: pair.replacePlate, disabled: true })),
|
||||
renderField('品牌', React.createElement(Input, { value: pair.replaceBrand, disabled: true })),
|
||||
renderField('型号', React.createElement(Input, { value: pair.replaceModel, disabled: true }))
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function renderProjectPanel() {
|
||||
return React.createElement(
|
||||
'section',
|
||||
{ className: 'vr-project-panel' },
|
||||
React.createElement('div', { className: 'vr-project-panel__title' }, '项目信息'),
|
||||
React.createElement(
|
||||
'div',
|
||||
{ className: 'vr-project-grid' },
|
||||
React.createElement(
|
||||
'div',
|
||||
{ className: 'vr-readonly' },
|
||||
React.createElement('span', { className: 'vr-readonly__label' }, '客户名称'),
|
||||
React.createElement('span', { className: 'vr-readonly__value' }, projectInfo.customerName)
|
||||
),
|
||||
React.createElement(
|
||||
'div',
|
||||
{ className: 'vr-readonly' },
|
||||
React.createElement('span', { className: 'vr-readonly__label' }, '项目名称'),
|
||||
React.createElement('span', { className: 'vr-readonly__value' }, projectInfo.projectName)
|
||||
),
|
||||
React.createElement(
|
||||
'div',
|
||||
{ className: 'vr-readonly' },
|
||||
React.createElement('span', { className: 'vr-readonly__label' }, '项目类型'),
|
||||
React.createElement(
|
||||
'span',
|
||||
{ className: 'vr-readonly__value' },
|
||||
React.createElement(Tag, { color: projectInfo.projectType === '自营' ? 'purple' : 'blue', style: { margin: 0 } }, projectInfo.projectType)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return React.createElement(
|
||||
'div',
|
||||
{ className: 'vr-add-page', style: { padding: '20px 24px 32px', minHeight: '100vh', background: 'linear-gradient(165deg,#eef4ff 0%,#f5f7fa 42%,#f0f2f5 100%)' } },
|
||||
React.createElement('style', null, pageCss),
|
||||
React.createElement(
|
||||
'header',
|
||||
{ className: 'vr-page-header' },
|
||||
React.createElement(Breadcrumb, {
|
||||
items: [
|
||||
{ title: '运维管理' },
|
||||
@@ -75,126 +304,49 @@ const Component = function () {
|
||||
}),
|
||||
React.createElement(Button, { type: 'link', style: { padding: 0 }, onClick: function () { setRequirementModalVisible(true); } }, '查看需求说明')
|
||||
),
|
||||
React.createElement(Card, { title: '选择项目', style: cardStyle },
|
||||
React.createElement('div', { style: formRowStyle },
|
||||
React.createElement('div', { style: formItemStyle },
|
||||
React.createElement('div', { style: labelStyle }, '项目名称'),
|
||||
React.createElement(Input, { value: data.projectName || '', disabled: true })
|
||||
),
|
||||
React.createElement('div', { style: formItemStyle },
|
||||
React.createElement('div', { style: labelStyle }, '合同编码'),
|
||||
React.createElement(Input, { value: data.contractCode || '', disabled: true })
|
||||
),
|
||||
React.createElement('div', { style: formItemStyle },
|
||||
React.createElement('div', { style: labelStyle }, '客户名称'),
|
||||
React.createElement(Input, { value: data.customerName || '', disabled: true })
|
||||
),
|
||||
React.createElement('div', { style: formItemStyle },
|
||||
React.createElement('div', { style: labelStyle }, '对接人'),
|
||||
React.createElement(Input, { value: data.contactPerson || '', disabled: true })
|
||||
),
|
||||
React.createElement('div', { style: formItemStyle },
|
||||
React.createElement('div', { style: labelStyle }, '合同签订时间'),
|
||||
React.createElement(Input, { value: data.signDate || '', disabled: true })
|
||||
),
|
||||
React.createElement('div', { style: formItemStyle },
|
||||
React.createElement('div', { style: labelStyle }, '客户联系电话'),
|
||||
React.createElement(Input, { value: data.contactPhone || '', disabled: true })
|
||||
),
|
||||
React.createElement('div', { style: formItemStyle },
|
||||
React.createElement('div', { style: labelStyle }, '业务部门'),
|
||||
React.createElement(Input, { value: data.businessDept || '', disabled: true })
|
||||
),
|
||||
React.createElement('div', { style: formItemStyle },
|
||||
React.createElement('div', { style: labelStyle }, '业务人员'),
|
||||
React.createElement(Input, { value: data.businessPerson || '', disabled: true })
|
||||
React.createElement(
|
||||
Card,
|
||||
{
|
||||
className: 'vr-main-card',
|
||||
title: React.createElement(
|
||||
'span',
|
||||
null,
|
||||
'查看替换车 ',
|
||||
React.createElement(Tag, { style: { marginLeft: 8, fontWeight: 400 } }, pairs.length + ' 辆车')
|
||||
)
|
||||
)
|
||||
},
|
||||
React.createElement('div', { className: 'vr-pair-list' }, pairs.map(function (pair, index) { return renderPairCard(pair, index); })),
|
||||
renderProjectPanel(),
|
||||
React.createElement('div', { className: 'vr-footer' }, React.createElement(Button, { size: 'large', onClick: handleBack }, '返回'))
|
||||
),
|
||||
React.createElement(Card, { title: '替换车详情', style: cardStyle },
|
||||
React.createElement('div', { style: formRowStyle },
|
||||
React.createElement('div', { style: formItemStyle },
|
||||
React.createElement('div', { style: labelStyle }, '替换时间'),
|
||||
React.createElement(Input, { value: data.replaceDate || '', disabled: true, placeholder: 'YYYY-MM-DD' })
|
||||
),
|
||||
React.createElement('div', { style: formItemStyle },
|
||||
React.createElement('div', { style: labelStyle }, '替换类型'),
|
||||
React.createElement(Input, { value: data.replaceType || '', disabled: true })
|
||||
),
|
||||
React.createElement('div', { style: formItemStyle },
|
||||
React.createElement('div', { style: labelStyle }, '替换原因'),
|
||||
React.createElement(Input, { value: data.replaceReason || '', disabled: true })
|
||||
),
|
||||
React.createElement('div', { style: Object.assign({}, formItemStyle, { gridColumn: '1 / -1' }) },
|
||||
React.createElement('div', { style: labelStyle }, '替换原因说明'),
|
||||
React.createElement(Input.TextArea, { value: data.replaceReasonDesc || '', disabled: true, rows: 3, style: { width: '100%' } })
|
||||
),
|
||||
React.createElement('div', { style: formItemStyle },
|
||||
React.createElement('div', { style: labelStyle }, '被替换车牌号'),
|
||||
React.createElement(Input, { value: data.originalPlate || '', disabled: true })
|
||||
),
|
||||
React.createElement('div', { style: formItemStyle },
|
||||
React.createElement('div', { style: labelStyle }, '被替换车识别代码'),
|
||||
React.createElement(Input, { value: data.originalVin || '', disabled: true })
|
||||
),
|
||||
React.createElement('div', { style: formItemStyle },
|
||||
React.createElement('div', { style: labelStyle }, '被替换车品牌'),
|
||||
React.createElement(Input, { value: data.originalBrand || '', disabled: true })
|
||||
),
|
||||
React.createElement('div', { style: formItemStyle },
|
||||
React.createElement('div', { style: labelStyle }, '被替换车型号'),
|
||||
React.createElement(Input, { value: data.originalModel || '', disabled: true })
|
||||
),
|
||||
React.createElement('div', { style: { gridColumn: '1 / -1', width: '100%' } }),
|
||||
React.createElement('div', { style: formItemStyle },
|
||||
React.createElement('div', { style: labelStyle }, '替换车车牌号'),
|
||||
React.createElement(Input, { value: data.replacePlate || '', disabled: true })
|
||||
),
|
||||
React.createElement('div', { style: formItemStyle },
|
||||
React.createElement('div', { style: labelStyle }, '替换车识别代码'),
|
||||
React.createElement(Input, { value: data.replaceVin || '', disabled: true })
|
||||
),
|
||||
React.createElement('div', { style: formItemStyle },
|
||||
React.createElement('div', { style: labelStyle }, '替换车品牌'),
|
||||
React.createElement(Input, { value: data.replaceBrand || '', disabled: true })
|
||||
),
|
||||
React.createElement('div', { style: formItemStyle },
|
||||
React.createElement('div', { style: labelStyle }, '替换车型号'),
|
||||
React.createElement(Input, { value: data.replaceModel || '', disabled: true })
|
||||
)
|
||||
),
|
||||
React.createElement('div', { style: { display: 'flex', gap: 8, marginTop: 24 } },
|
||||
React.createElement(Button, { onClick: handleBack }, '返回')
|
||||
)
|
||||
),
|
||||
React.createElement(Card, { title: '审批情况', style: cardStyle },
|
||||
React.createElement(
|
||||
Card,
|
||||
{ className: 'vr-approval-card', title: '审批情况' },
|
||||
React.createElement(Steps, {
|
||||
direction: 'vertical',
|
||||
current: approvalSteps.length,
|
||||
items: approvalSteps.map(function (s) {
|
||||
var statusText = s.status === 'finish' ? '审批通过' : '待审批';
|
||||
var desc = React.createElement('div', { style: { fontSize: 13, color: 'rgba(0,0,0,0.65)', marginTop: 4 } },
|
||||
React.createElement('div', null, '审批状态:', statusText),
|
||||
React.createElement('div', null, '审批人:', s.person || '—'),
|
||||
s.approveTime ? React.createElement('div', null, '审批时间:', s.approveTime) : null
|
||||
);
|
||||
return {
|
||||
title: s.title,
|
||||
description: desc,
|
||||
status: s.status === 'finish' ? 'finish' : 'wait'
|
||||
status: s.status === 'finish' ? 'finish' : 'wait',
|
||||
description: React.createElement(
|
||||
'div',
|
||||
{ style: { fontSize: 13, color: 'rgba(0,0,0,0.65)', marginTop: 4 } },
|
||||
React.createElement('div', null, '审批状态:', s.status === 'finish' ? '审批通过' : '待审批'),
|
||||
React.createElement('div', null, '审批人:', s.person || '—'),
|
||||
s.approveTime ? React.createElement('div', null, '审批时间:', s.approveTime) : null
|
||||
)
|
||||
};
|
||||
})
|
||||
})
|
||||
),
|
||||
React.createElement(Modal, {
|
||||
title: '需求说明',
|
||||
title: '替换车管理 - 查看 · 需求说明',
|
||||
open: requirementModalVisible[0],
|
||||
onCancel: function () { setRequirementModalVisible(false); },
|
||||
width: 720,
|
||||
footer: React.createElement(Button, { onClick: function () { setRequirementModalVisible(false); } }, '关闭'),
|
||||
bodyStyle: { maxHeight: '70vh', overflow: 'auto' }
|
||||
}, React.createElement('div', { style: { padding: '8px 0' } },
|
||||
React.createElement('div', { style: { whiteSpace: 'pre-wrap', fontSize: 13, lineHeight: 1.6 } }, requirementContent))
|
||||
)
|
||||
width: 760,
|
||||
footer: React.createElement(Button, { type: 'primary', onClick: function () { setRequirementModalVisible(false); } }, '关闭'),
|
||||
bodyStyle: { maxHeight: '72vh', overflow: 'auto', paddingTop: 8 }
|
||||
}, renderRequirementDoc())
|
||||
);
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,6 +17,11 @@ const Component = function () {
|
||||
var Modal = antd.Modal;
|
||||
var Input = antd.Input;
|
||||
var message = antd.message;
|
||||
var Tag = antd.Tag;
|
||||
var Empty = antd.Empty;
|
||||
var App = antd.App;
|
||||
var Badge = antd.Badge;
|
||||
var Popover = antd.Popover;
|
||||
|
||||
var RangePicker = DatePicker.RangePicker;
|
||||
|
||||
@@ -50,8 +55,29 @@ const Component = function () {
|
||||
var _withdrawModalRecord = useState(null);
|
||||
var _toPermanentModalVisible = useState(false);
|
||||
var _toPermanentModalRecord = useState(null);
|
||||
var _deleteModalVisible = useState(false);
|
||||
var _deleteModalRecord = useState(null);
|
||||
var _deletedIds = useState([]);
|
||||
var _requirementModalVisible = useState(false);
|
||||
|
||||
function ensureReplaceDateTime(dateStr, fallbackTime) {
|
||||
if (!dateStr) return '';
|
||||
if (dateStr.length > 10) return dateStr;
|
||||
return dateStr + ' ' + (fallbackTime || '09:00:00');
|
||||
}
|
||||
|
||||
function enrichListRow(row, timeSuffix) {
|
||||
var next = Object.assign({}, row);
|
||||
next.replaceDate = ensureReplaceDateTime(row.replaceDate, timeSuffix);
|
||||
if (!row.currentApprover) {
|
||||
if (row.approvalStatus === '审批中') next.currentApprover = '姚守涛';
|
||||
else if (row.approvalStatus === '待审批') next.currentApprover = '业务部主管';
|
||||
else if (row.approvalStatus === '审批驳回') next.currentApprover = '尚建华';
|
||||
else next.currentApprover = '—';
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
var replaceTypeOptions = [
|
||||
{ value: '永久替换', label: '永久替换' },
|
||||
{ value: '临时替换', label: '临时替换' }
|
||||
@@ -89,12 +115,12 @@ const Component = function () {
|
||||
];
|
||||
|
||||
// 进行中:未结束、暂存,审批状态为 待审批、审批中、审批驳回、未提交、撤回
|
||||
var ongoingList = [
|
||||
{ id: 'o1', replaceDate: '2025-03-05', replaceType: '临时替换', projectName: '嘉兴氢能示范项目', approvalStatus: '待审批', originalPlate: '浙A12345', originalBrand: '东风', originalModel: 'DFH1180', replacePlate: '浙A67890', replaceBrand: '福田', replaceModel: 'BJ1180', replaceReason: '车辆原因', replaceReasonDesc: '原车维修', creator: '张三', createTime: '2025-03-01 10:00' },
|
||||
{ id: 'o2', replaceDate: '2025-03-06', replaceType: '永久替换', projectName: '上海物流租赁项目', approvalStatus: '审批中', originalPlate: '浙B11111', originalBrand: '江淮', originalModel: 'HFC1180', replacePlate: '浙B22222', replaceBrand: '重汽', replaceModel: 'ZZ1180', replaceReason: '客户原因', replaceReasonDesc: '客户要求换型', creator: '李四', createTime: '2025-03-01 14:30' },
|
||||
{ id: 'o3', replaceDate: '2025-03-07', replaceType: '临时替换', projectName: '杭州城配租赁项目', approvalStatus: '审批驳回', originalPlate: '浙C33333', originalBrand: '东风', originalModel: 'DFH1190', replacePlate: '浙C44444', replaceBrand: '福田', replaceModel: 'BJ1190', replaceReason: '车辆原因', replaceReasonDesc: '事故替换', creator: '王五', createTime: '2025-03-02 09:15' },
|
||||
{ id: 'o4', replaceDate: '2025-03-08', replaceType: '永久替换', projectName: '嘉兴氢能示范项目', approvalStatus: '未提交', originalPlate: '浙A55555', originalBrand: '重汽', originalModel: 'ZZ1160', replacePlate: '浙A66666', replaceBrand: '江淮', replaceModel: 'HFC1190', replaceReason: '车辆原因', replaceReasonDesc: '保养替换', creator: '赵六', createTime: '2025-03-02 16:00' },
|
||||
{ id: 'o5', replaceDate: '2025-03-09', replaceType: '临时替换', projectName: '上海物流租赁项目', approvalStatus: '撤回', originalPlate: '浙F77777', originalBrand: '福田', originalModel: 'BJ1180', replacePlate: '浙F88888', replaceBrand: '东风', replaceModel: 'DFH1180', replaceReason: '客户原因', replaceReasonDesc: '年检替换', creator: '张三', createTime: '2025-03-03 11:20' },
|
||||
var ongoingListRaw = [
|
||||
{ id: 'o1', replaceDate: '2025-03-05', replaceType: '临时替换', projectName: '嘉兴氢能示范项目', approvalStatus: '待审批', currentApprover: '业务部主管', originalPlate: '浙A12345', originalBrand: '东风', originalModel: 'DFH1180', replacePlate: '浙A67890', replaceBrand: '福田', replaceModel: 'BJ1180', replaceReason: '车辆原因', replaceReasonDesc: '原车维修', creator: '张三', createTime: '2025-03-01 10:00:00' },
|
||||
{ id: 'o2', replaceDate: '2025-03-06', replaceType: '永久替换', projectName: '上海物流租赁项目', approvalStatus: '审批中', currentApprover: '姚守涛', originalPlate: '浙B11111', originalBrand: '江淮', originalModel: 'HFC1180', replacePlate: '浙B22222', replaceBrand: '重汽', replaceModel: 'ZZ1180', replaceReason: '客户原因', replaceReasonDesc: '客户要求换型', creator: '李四', createTime: '2025-03-01 14:30:00' },
|
||||
{ id: 'o3', replaceDate: '2025-03-07', replaceType: '临时替换', projectName: '杭州城配租赁项目', approvalStatus: '审批驳回', currentApprover: '尚建华', originalPlate: '浙C33333', originalBrand: '东风', originalModel: 'DFH1190', replacePlate: '浙C44444', replaceBrand: '福田', replaceModel: 'BJ1190', replaceReason: '车辆原因', replaceReasonDesc: '事故替换', creator: '王五', createTime: '2025-03-02 09:15:00' },
|
||||
{ id: 'o4', replaceDate: '2025-03-08', replaceType: '永久替换', projectName: '嘉兴氢能示范项目', approvalStatus: '未提交', currentApprover: '—', originalPlate: '浙A55555', originalBrand: '重汽', originalModel: 'ZZ1160', replacePlate: '浙A66666', replaceBrand: '江淮', replaceModel: 'HFC1190', replaceReason: '车辆原因', replaceReasonDesc: '保养替换', creator: '赵六', createTime: '2025-03-02 16:00:00' },
|
||||
{ id: 'o5', replaceDate: '2025-03-09', replaceType: '临时替换', projectName: '上海物流租赁项目', approvalStatus: '撤回', currentApprover: '—', originalPlate: '浙F77777', originalBrand: '福田', originalModel: 'BJ1180', replacePlate: '浙F88888', replaceBrand: '东风', replaceModel: 'DFH1180', replaceReason: '客户原因', replaceReasonDesc: '年检替换', creator: '张三', createTime: '2025-03-03 11:20:00' },
|
||||
{ id: 'o6', replaceDate: '2025-03-10', replaceType: '永久替换', projectName: '杭州城配租赁项目', approvalStatus: '待审批', originalPlate: '浙A11201', originalBrand: '江淮', originalModel: 'HFC1160', replacePlate: '浙A11202', replaceBrand: '东风', replaceModel: 'DFH1160', replaceReason: '车辆原因', replaceReasonDesc: '发动机故障', creator: '李四', createTime: '2025-03-04 08:45' },
|
||||
{ id: 'o7', replaceDate: '2025-03-11', replaceType: '临时替换', projectName: '嘉兴氢能示范项目', approvalStatus: '审批中', originalPlate: '浙B22301', originalBrand: '重汽', originalModel: 'ZZ1160', replacePlate: '浙B22302', replaceBrand: '福田', replaceModel: 'BJ1160', replaceReason: '客户原因', replaceReasonDesc: '临时增运力', creator: '王五', createTime: '2025-03-04 13:00' },
|
||||
{ id: 'o8', replaceDate: '2025-03-12', replaceType: '永久替换', projectName: '上海物流租赁项目', approvalStatus: '审批驳回', originalPlate: '浙C33401', originalBrand: '东风', originalModel: 'DFH1190', replacePlate: '浙C33402', replaceBrand: '江淮', replaceModel: 'HFC1190', replaceReason: '车辆原因', replaceReasonDesc: '底盘大修', creator: '赵六', createTime: '2025-03-05 10:20' },
|
||||
@@ -109,12 +135,16 @@ const Component = function () {
|
||||
{ id: 'o17', replaceDate: '2025-03-21', replaceType: '临时替换', projectName: '上海物流租赁项目', approvalStatus: '审批中', originalPlate: '浙F30301', originalBrand: '福田', originalModel: 'BJ1190', replacePlate: '浙F30302', replaceBrand: '重汽', replaceModel: 'ZZ1190', replaceReason: '客户原因', replaceReasonDesc: '区域调配', creator: '张三', createTime: '2025-03-09 15:00' },
|
||||
{ id: 'o18', replaceDate: '2025-03-22', replaceType: '永久替换', projectName: '杭州城配租赁项目', approvalStatus: '审批驳回', originalPlate: '浙A40401', originalBrand: '江淮', originalModel: 'HFC1160', replacePlate: '浙A40402', replaceBrand: '东风', replaceModel: 'DFH1160', replaceReason: '车辆原因', replaceReasonDesc: '车身锈蚀', creator: '李四', createTime: '2025-03-10 09:45' },
|
||||
{ id: 'o19', replaceDate: '2025-03-23', replaceType: '临时替换', projectName: '嘉兴氢能示范项目', approvalStatus: '未提交', originalPlate: '浙B50501', originalBrand: '重汽', originalModel: 'ZZ1160', replacePlate: '浙B50502', replaceBrand: '福田', replaceModel: 'BJ1160', replaceReason: '客户原因', replaceReasonDesc: '试运行换车', creator: '王五', createTime: '2025-03-10 14:30' },
|
||||
{ id: 'o20', replaceDate: '2025-03-24', replaceType: '永久替换', projectName: '上海物流租赁项目', approvalStatus: '撤回', originalPlate: '浙C60601', originalBrand: '东风', originalModel: 'DFH1190', replacePlate: '浙C60602', replaceBrand: '江淮', replaceModel: 'HFC1190', replaceReason: '车辆原因', replaceReasonDesc: '排放升级', creator: '赵六', createTime: '2025-03-11 11:15' }
|
||||
{ id: 'o20', replaceDate: '2025-03-24', replaceType: '永久替换', projectName: '上海物流租赁项目', approvalStatus: '撤回', currentApprover: '—', originalPlate: '浙C60601', originalBrand: '东风', originalModel: 'DFH1190', replacePlate: '浙C60602', replaceBrand: '江淮', replaceModel: 'HFC1190', replaceReason: '车辆原因', replaceReasonDesc: '排放升级', creator: '赵六', createTime: '2025-03-11 11:15:00' }
|
||||
];
|
||||
function pad2(n) { return n < 10 ? '0' + n : String(n); }
|
||||
var ongoingList = ongoingListRaw.map(function (r, i) {
|
||||
return enrichListRow(r, pad2(8 + (i % 12)) + ':' + pad2((i * 7) % 60) + ':00');
|
||||
});
|
||||
|
||||
// 历史记录:审批完成,审批状态均为审批完成
|
||||
var historyList = [
|
||||
{ id: 'h1', replaceDate: '2025-02-15', replaceType: '永久替换', projectName: '嘉兴氢能示范项目', approvalStatus: '审批完成', originalPlate: '浙A10001', originalBrand: '东风', originalModel: 'DFH1180', replacePlate: '浙A10002', replaceBrand: '福田', replaceModel: 'BJ1180', replaceReason: '车辆原因', replaceReasonDesc: '原车报废', creator: '张三', createTime: '2025-02-10 09:00' },
|
||||
var historyListRaw = [
|
||||
{ id: 'h1', replaceDate: '2025-02-15', replaceType: '永久替换', projectName: '嘉兴氢能示范项目', approvalStatus: '审批完成', currentApprover: '—', originalPlate: '浙A10001', originalBrand: '东风', originalModel: 'DFH1180', replacePlate: '浙A10002', replaceBrand: '福田', replaceModel: 'BJ1180', replaceReason: '车辆原因', replaceReasonDesc: '原车报废', creator: '张三', createTime: '2025-02-10 09:00:00' },
|
||||
{ id: 'h2', replaceDate: '2025-02-14', replaceType: '临时替换', projectName: '上海物流租赁项目', approvalStatus: '审批完成', originalPlate: '浙B20001', originalBrand: '江淮', originalModel: 'HFC1180', replacePlate: '浙B20002', replaceBrand: '重汽', replaceModel: 'ZZ1180', replaceReason: '客户原因', replaceReasonDesc: '客户临时需求', creator: '李四', createTime: '2025-02-09 14:00' },
|
||||
{ id: 'h3', replaceDate: '2025-02-13', replaceType: '永久替换', projectName: '杭州城配租赁项目', approvalStatus: '审批完成', originalPlate: '浙C30001', originalBrand: '重汽', originalModel: 'ZZ1160', replacePlate: '浙C30002', replaceBrand: '东风', replaceModel: 'DFH1160', replaceReason: '车辆原因', replaceReasonDesc: '使用年限到期', creator: '王五', createTime: '2025-02-08 10:30' },
|
||||
{ id: 'h4', replaceDate: '2025-02-12', replaceType: '临时替换', projectName: '嘉兴氢能示范项目', approvalStatus: '审批完成', originalPlate: '浙A40001', originalBrand: '福田', originalModel: 'BJ1180', replacePlate: '浙A40002', replaceBrand: '江淮', replaceModel: 'HFC1180', replaceReason: '客户原因', replaceReasonDesc: '旺季加车', creator: '赵六', createTime: '2025-02-07 15:20' },
|
||||
@@ -133,18 +163,24 @@ const Component = function () {
|
||||
{ id: 'h17', replaceDate: '2025-01-30', replaceType: '永久替换', projectName: '上海物流租赁项目', approvalStatus: '审批完成', originalPlate: '浙B08001', originalBrand: '东风', originalModel: 'DFH1190', replacePlate: '浙B08002', replaceBrand: '重汽', replaceModel: 'ZZ1190', replaceReason: '车辆原因', replaceReasonDesc: '油耗过高', creator: '张三', createTime: '2025-01-25 14:30' },
|
||||
{ id: 'h18', replaceDate: '2025-01-29', replaceType: '临时替换', projectName: '杭州城配租赁项目', approvalStatus: '审批完成', originalPlate: '浙C09001', originalBrand: '江淮', originalModel: 'HFC1160', replacePlate: '浙C09002', replaceBrand: '福田', replaceModel: 'BJ1160', replaceReason: '客户原因', replaceReasonDesc: '活动保障', creator: '李四', createTime: '2025-01-24 10:20' },
|
||||
{ id: 'h19', replaceDate: '2025-01-28', replaceType: '永久替换', projectName: '嘉兴氢能示范项目', approvalStatus: '审批完成', originalPlate: '浙A10003', originalBrand: '重汽', originalModel: 'ZZ1180', replacePlate: '浙A10004', replaceBrand: '东风', replaceModel: 'DFH1180', replaceReason: '车辆原因', replaceReasonDesc: '配件停产', creator: '王五', createTime: '2025-01-23 16:45' },
|
||||
{ id: 'h20', replaceDate: '2025-01-27', replaceType: '临时替换', projectName: '上海物流租赁项目', approvalStatus: '审批完成', originalPlate: '浙B11001', originalBrand: '福田', originalModel: 'BJ1190', replacePlate: '浙B11002', replaceBrand: '江淮', replaceModel: 'HFC1190', replaceReason: '客户原因', replaceReasonDesc: '新业务启动', creator: '赵六', createTime: '2025-01-22 08:30' }
|
||||
{ id: 'h20', replaceDate: '2025-01-27', replaceType: '临时替换', projectName: '上海物流租赁项目', approvalStatus: '审批完成', currentApprover: '—', originalPlate: '浙B11001', originalBrand: '福田', originalModel: 'BJ1190', replacePlate: '浙B11002', replaceBrand: '江淮', replaceModel: 'HFC1190', replaceReason: '客户原因', replaceReasonDesc: '新业务启动', creator: '赵六', createTime: '2025-01-22 08:30:00' }
|
||||
];
|
||||
var historyList = historyListRaw.map(function (r, i) {
|
||||
return enrichListRow(r, pad2(10 + (i % 10)) + ':' + pad2((i * 5) % 60) + ':00');
|
||||
});
|
||||
|
||||
var deletedIds = _deletedIds[0];
|
||||
var appliedFilter = _appliedFilter[0];
|
||||
|
||||
var filteredOngoing = useMemo(function () {
|
||||
var list = ongoingList.filter(function (r) {
|
||||
if (deletedIds.indexOf(r.id) !== -1) return false;
|
||||
if (appliedFilter.replaceDateRange && appliedFilter.replaceDateRange.length === 2) {
|
||||
var start = appliedFilter.replaceDateRange[0] && appliedFilter.replaceDateRange[0].format ? appliedFilter.replaceDateRange[0].format('YYYY-MM-DD') : '';
|
||||
var end = appliedFilter.replaceDateRange[1] && appliedFilter.replaceDateRange[1].format ? appliedFilter.replaceDateRange[1].format('YYYY-MM-DD') : '';
|
||||
if (start && (r.replaceDate || '') < start) return false;
|
||||
if (end && (r.replaceDate || '') > end) return false;
|
||||
var rd = (r.replaceDate || '').slice(0, 10);
|
||||
if (start && rd < start) return false;
|
||||
if (end && rd > end) return false;
|
||||
}
|
||||
if (appliedFilter.replaceType && r.replaceType !== appliedFilter.replaceType) return false;
|
||||
if (appliedFilter.projectName && r.projectName !== appliedFilter.projectName) return false;
|
||||
@@ -164,15 +200,17 @@ const Component = function () {
|
||||
return true;
|
||||
});
|
||||
return list;
|
||||
}, [appliedFilter]);
|
||||
}, [appliedFilter, deletedIds]);
|
||||
|
||||
var filteredHistory = useMemo(function () {
|
||||
var list = historyList.filter(function (r) {
|
||||
if (deletedIds.indexOf(r.id) !== -1) return false;
|
||||
if (appliedFilter.replaceDateRange && appliedFilter.replaceDateRange.length === 2) {
|
||||
var start = appliedFilter.replaceDateRange[0] && appliedFilter.replaceDateRange[0].format ? appliedFilter.replaceDateRange[0].format('YYYY-MM-DD') : '';
|
||||
var end = appliedFilter.replaceDateRange[1] && appliedFilter.replaceDateRange[1].format ? appliedFilter.replaceDateRange[1].format('YYYY-MM-DD') : '';
|
||||
if (start && (r.replaceDate || '') < start) return false;
|
||||
if (end && (r.replaceDate || '') > end) return false;
|
||||
var rd = (r.replaceDate || '').slice(0, 10);
|
||||
if (start && rd < start) return false;
|
||||
if (end && rd > end) return false;
|
||||
}
|
||||
if (appliedFilter.replaceType && r.replaceType !== appliedFilter.replaceType) return false;
|
||||
if (appliedFilter.projectName && r.projectName !== appliedFilter.projectName) return false;
|
||||
@@ -190,7 +228,7 @@ const Component = function () {
|
||||
return true;
|
||||
});
|
||||
return list;
|
||||
}, [appliedFilter]);
|
||||
}, [appliedFilter, deletedIds]);
|
||||
|
||||
var handleQuery = useCallback(function () {
|
||||
_appliedFilter[1]({
|
||||
@@ -240,10 +278,163 @@ const Component = function () {
|
||||
_approvalStatus[1](v);
|
||||
}, []);
|
||||
|
||||
var filterLabelStyle = { marginBottom: 6, fontSize: 14, color: 'rgba(0,0,0,0.65)' };
|
||||
var filterItemStyle = { marginBottom: 12 };
|
||||
var filterLabelStyle = { marginBottom: 6, fontSize: 13, fontWeight: 500, color: '#475569', lineHeight: 1.4 };
|
||||
var filterItemStyle = { marginBottom: 0 };
|
||||
var filterControlStyle = { width: '100%' };
|
||||
|
||||
var pageStyles =
|
||||
'.vr-list-page{font-family:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif}' +
|
||||
'.vr-list-page .vr-page-header{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:20px;flex-wrap:wrap}' +
|
||||
'.vr-list-page .vr-filter-card,.vr-list-page .vr-list-card{border-radius:16px;border:none;box-shadow:0 4px 24px -6px rgba(15,23,42,0.08),0 0 0 1px rgba(15,23,42,0.05);margin-bottom:16px}' +
|
||||
'.vr-list-page .vr-filter-card>.ant-card-head,.vr-list-page .vr-list-card>.ant-card-head{border-bottom:1px solid #f1f5f9;min-height:auto;padding:14px 20px}' +
|
||||
'.vr-list-page .vr-filter-card>.ant-card-head .ant-card-head-title,.vr-list-page .vr-list-card>.ant-card-head .ant-card-head-title{font-size:15px;font-weight:600;color:#0f172a;padding:0}' +
|
||||
'.vr-list-page .vr-filter-card>.ant-card-body{padding:16px 20px 20px}' +
|
||||
'.vr-list-page .vr-list-card>.ant-card-body{padding:12px 16px 16px}' +
|
||||
'.vr-list-page .vr-filter-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px 20px;align-items:start}' +
|
||||
'@media(max-width:900px){.vr-list-page .vr-filter-grid{grid-template-columns:1fr}}' +
|
||||
'.vr-list-page .vr-filter-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:16px;padding-top:16px;border-top:1px solid #f1f5f9}' +
|
||||
'.vr-list-page .vr-swap-arrow{color:#94a3b8;font-size:12px;margin:0 4px}' +
|
||||
'.vr-list-page .vr-reason-text{display:block;max-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#475569}' +
|
||||
'.vr-list-page .vr-list-table .ant-table-thead>tr>th{background:#f8fafc!important;color:#475569;font-weight:600;font-size:13px}' +
|
||||
'.vr-list-page .vr-list-table .ant-table-tbody>tr:hover>td{background:#f0f9ff!important}' +
|
||||
'.vr-list-page .vr-list-table .ant-table-thead th,.vr-list-page .vr-list-table .ant-table-tbody td{white-space:nowrap}' +
|
||||
'.vr-list-page .vr-list-table .ant-table-tbody>tr.ant-table-row-selected>td{background:#eff6ff!important}' +
|
||||
'.vr-list-page .vr-tabs .ant-tabs-nav{margin-bottom:0}' +
|
||||
'.vr-list-page .vr-empty{padding:48px 16px}' +
|
||||
'.vr-approval-flow-popover .ant-popover-inner{padding:14px 16px;border-radius:8px}' +
|
||||
'.vr-approval-flow{width:300px;max-width:min(340px,92vw)}' +
|
||||
'.vr-approval-flow__item{display:flex;gap:12px;position:relative;padding-bottom:22px}' +
|
||||
'.vr-approval-flow__item:last-child{padding-bottom:0}' +
|
||||
'.vr-approval-flow__item:not(:last-child) .vr-approval-flow__line{position:absolute;left:15px;top:34px;bottom:0;width:2px;background:#e5e7eb}' +
|
||||
'.vr-approval-flow__avatar-wrap{position:relative;flex-shrink:0;z-index:1}' +
|
||||
'.vr-approval-flow__avatar{width:32px;height:32px;border-radius:50%;background:#1677ff;color:#fff;font-size:12px;font-weight:600;display:inline-flex;align-items:center;justify-content:center;line-height:1}' +
|
||||
'.vr-approval-flow__body{flex:1;min-width:0;padding-top:2px}' +
|
||||
'.vr-approval-flow__head{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:4px}' +
|
||||
'.vr-approval-flow__role{font-size:14px;font-weight:600;color:rgba(0,0,0,0.88);line-height:1.4}' +
|
||||
'.vr-approval-flow__meta{font-size:12px;color:rgba(0,0,0,0.45);line-height:1.5}' +
|
||||
'.vr-list-page .vr-approval-status-trigger{display:inline-flex;cursor:pointer;border-radius:4px;transition:opacity .15s ease}' +
|
||||
'.vr-list-page .vr-approval-status-trigger:hover{opacity:.88}';
|
||||
|
||||
function formatFlowTime(timeStr) {
|
||||
if (!timeStr) return '—';
|
||||
var s = String(timeStr).trim();
|
||||
if (s.length >= 19) return s.slice(0, 19);
|
||||
if (/^\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}$/.test(s)) return s + ':00';
|
||||
return s;
|
||||
}
|
||||
|
||||
function offsetFlowTime(timeStr, minutes) {
|
||||
if (!timeStr) return '—';
|
||||
var s = String(timeStr).trim().replace(/-/g, '/');
|
||||
var d = new Date(s);
|
||||
if (isNaN(d.getTime())) return formatFlowTime(timeStr);
|
||||
d.setMinutes(d.getMinutes() + (minutes || 0));
|
||||
function p2(n) { return n < 10 ? '0' + n : '' + n; }
|
||||
return d.getFullYear() + '-' + p2(d.getMonth() + 1) + '-' + p2(d.getDate()) + ' ' + p2(d.getHours()) + ':' + p2(d.getMinutes()) + ':' + p2(d.getSeconds());
|
||||
}
|
||||
|
||||
function getApproverRoleTitle(approverName) {
|
||||
if (approverName === '姚守涛') return '业务部主管';
|
||||
if (approverName === '尚建华') return '事业部主管';
|
||||
if (approverName === '业务部主管') return '业务部主管';
|
||||
return '运维主管';
|
||||
}
|
||||
|
||||
function getApprovalFlowSteps(record) {
|
||||
var creator = record.creator || '张三';
|
||||
var createTime = formatFlowTime(record.createTime);
|
||||
var approver = record.currentApprover || '姚守涛';
|
||||
var approverPerson = approver === '业务部主管' ? '姚守涛' : approver;
|
||||
var roleTitle = getApproverRoleTitle(approver);
|
||||
var avatarFromName = function (name) {
|
||||
var n = String(name || '').trim();
|
||||
if (!n || n === '—') return '用户';
|
||||
return n.length >= 2 ? n.slice(-2) : n;
|
||||
};
|
||||
var steps = [
|
||||
{
|
||||
role: roleTitle,
|
||||
actionLabel: '审批中',
|
||||
tagColor: 'processing',
|
||||
person: approverPerson,
|
||||
time: '待处理',
|
||||
avatarText: avatarFromName(approverPerson)
|
||||
},
|
||||
{
|
||||
role: '发起审批',
|
||||
actionLabel: '通过',
|
||||
tagColor: 'success',
|
||||
person: creator,
|
||||
time: createTime,
|
||||
avatarText: avatarFromName(creator)
|
||||
}
|
||||
];
|
||||
if (roleTitle === '运维主管') {
|
||||
steps.splice(1, 0, {
|
||||
role: '业务部主管',
|
||||
actionLabel: '通过',
|
||||
tagColor: 'success',
|
||||
person: '尚建华',
|
||||
time: offsetFlowTime(record.createTime, 1),
|
||||
avatarText: '建华'
|
||||
});
|
||||
}
|
||||
return steps;
|
||||
}
|
||||
|
||||
function renderApprovalFlowContent(record) {
|
||||
var steps = getApprovalFlowSteps(record);
|
||||
return React.createElement('div', { className: 'vr-approval-flow' },
|
||||
steps.map(function (step, idx) {
|
||||
return React.createElement('div', { key: idx, className: 'vr-approval-flow__item' },
|
||||
React.createElement('div', { className: 'vr-approval-flow__avatar-wrap' },
|
||||
React.createElement('span', { className: 'vr-approval-flow__avatar', title: step.person }, step.avatarText),
|
||||
idx < steps.length - 1 ? React.createElement('span', { className: 'vr-approval-flow__line' }) : null
|
||||
),
|
||||
React.createElement('div', { className: 'vr-approval-flow__body' },
|
||||
React.createElement('div', { className: 'vr-approval-flow__head' },
|
||||
React.createElement('span', { className: 'vr-approval-flow__role' }, step.role),
|
||||
React.createElement(Tag, { color: step.tagColor, style: { margin: 0, fontSize: 12, lineHeight: '20px' } }, step.actionLabel)
|
||||
),
|
||||
React.createElement('div', { className: 'vr-approval-flow__meta' },
|
||||
step.person + ' ' + step.time
|
||||
)
|
||||
)
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function renderApprovalStatusCell(status, record) {
|
||||
var tag = renderApprovalTag(status);
|
||||
if (status !== '审批中' || !record) return tag;
|
||||
return React.createElement(Popover, {
|
||||
content: renderApprovalFlowContent(record),
|
||||
trigger: 'hover',
|
||||
placement: 'rightTop',
|
||||
overlayClassName: 'vr-approval-flow-popover',
|
||||
mouseEnterDelay: 0.15,
|
||||
mouseLeaveDelay: 0.12,
|
||||
destroyTooltipOnHide: true
|
||||
}, React.createElement('span', { className: 'vr-approval-status-trigger' }, tag));
|
||||
}
|
||||
|
||||
function renderApprovalTag(status) {
|
||||
var color = 'default';
|
||||
if (status === '待审批') color = 'processing';
|
||||
else if (status === '审批中') color = 'blue';
|
||||
else if (status === '审批驳回') color = 'error';
|
||||
else if (status === '未提交') color = 'default';
|
||||
else if (status === '撤回') color = 'warning';
|
||||
else if (status === '审批完成') color = 'success';
|
||||
return React.createElement(Tag, { color: color, style: { margin: 0, fontWeight: 500 } }, status || '—');
|
||||
}
|
||||
|
||||
function renderReplaceTypeTag(type) {
|
||||
var color = type === '永久替换' ? 'geekblue' : type === '临时替换' ? 'gold' : 'default';
|
||||
return React.createElement(Tag, { color: color, style: { margin: 0 } }, type || '—');
|
||||
}
|
||||
|
||||
function getOperationButtons(record, isHistory) {
|
||||
if (isHistory) {
|
||||
var viewBtn = React.createElement(Button, { key: 'view', type: 'link', size: 'small', onClick: function () { message.info('查看(跳转替换车管理-查看)'); } }, '查看');
|
||||
@@ -258,6 +449,18 @@ const Component = function () {
|
||||
if (['未提交', '审批驳回', '撤回'].indexOf(status) !== -1) {
|
||||
items.push(React.createElement(Button, { key: 'edit', type: 'link', size: 'small', onClick: function () { message.info('编辑(跳转替换车管理-编辑)'); } }, '编辑'));
|
||||
}
|
||||
if (['撤回', '审批驳回'].indexOf(status) !== -1) {
|
||||
items.push(React.createElement(Button, {
|
||||
key: 'delete',
|
||||
type: 'link',
|
||||
size: 'small',
|
||||
danger: true,
|
||||
onClick: function () {
|
||||
_deleteModalRecord[1](record);
|
||||
_deleteModalVisible[1](true);
|
||||
}
|
||||
}, '删除'));
|
||||
}
|
||||
if (status === '审批中') {
|
||||
items.push(React.createElement(Button, { key: 'withdraw', type: 'link', size: 'small', danger: true, onClick: function () { _withdrawModalRecord[1](record); _withdrawModalVisible[1](true); } }, '撤回'));
|
||||
}
|
||||
@@ -265,21 +468,50 @@ const Component = function () {
|
||||
}
|
||||
|
||||
var tableColumns = [
|
||||
{ title: '替换日期', dataIndex: 'replaceDate', key: 'replaceDate', width: 110, fixed: 'left' },
|
||||
{ title: '替换类型', dataIndex: 'replaceType', key: 'replaceType', width: 100, fixed: 'left' },
|
||||
{ title: '项目名称', dataIndex: 'projectName', key: 'projectName', width: 140, fixed: 'left' },
|
||||
{ title: '审批状态', dataIndex: 'approvalStatus', key: 'approvalStatus', width: 100 },
|
||||
{ title: '被替换车车牌号', dataIndex: 'originalPlate', key: 'originalPlate', width: 120 },
|
||||
{ title: '被替换车品牌', dataIndex: 'originalBrand', key: 'originalBrand', width: 100 },
|
||||
{ title: '被替换车型号', dataIndex: 'originalModel', key: 'originalModel', width: 110 },
|
||||
{ title: '替换车车牌号', dataIndex: 'replacePlate', key: 'replacePlate', width: 120 },
|
||||
{ title: '替换车品牌', dataIndex: 'replaceBrand', key: 'replaceBrand', width: 100 },
|
||||
{ title: '替换车型号', dataIndex: 'replaceModel', key: 'replaceModel', width: 110 },
|
||||
{ title: '替换日期', dataIndex: 'replaceDate', key: 'replaceDate', width: 168, fixed: 'left' },
|
||||
{
|
||||
title: '审批状态',
|
||||
dataIndex: 'approvalStatus',
|
||||
key: 'approvalStatus',
|
||||
width: 108,
|
||||
render: function (v, record) { return renderApprovalStatusCell(v, record); }
|
||||
},
|
||||
{
|
||||
title: '当前审批人',
|
||||
dataIndex: 'currentApprover',
|
||||
key: 'currentApprover',
|
||||
width: 110,
|
||||
render: function (v) {
|
||||
return React.createElement('span', { style: { color: v && v !== '—' ? '#334155' : '#94a3b8' } }, v || '—');
|
||||
}
|
||||
},
|
||||
{ title: '被替换车(旧车)', dataIndex: 'originalPlate', key: 'originalPlate', width: 130 },
|
||||
{ title: '品牌', dataIndex: 'originalBrand', key: 'originalBrand', width: 88 },
|
||||
{ title: '型号', dataIndex: 'originalModel', key: 'originalModel', width: 100 },
|
||||
{ title: '新车', dataIndex: 'replacePlate', key: 'replacePlate', width: 110 },
|
||||
{ title: '品牌', dataIndex: 'replaceBrand', key: 'replaceBrandNew', width: 88 },
|
||||
{ title: '型号', dataIndex: 'replaceModel', key: 'replaceModelNew', width: 100 },
|
||||
{
|
||||
title: '替换类型',
|
||||
dataIndex: 'replaceType',
|
||||
key: 'replaceType',
|
||||
width: 108,
|
||||
render: function (v) { return renderReplaceTypeTag(v); }
|
||||
},
|
||||
{ title: '替换原因', dataIndex: 'replaceReason', key: 'replaceReason', width: 100 },
|
||||
{ title: '替换原因说明', dataIndex: 'replaceReasonDesc', key: 'replaceReasonDesc', width: 120, ellipsis: true },
|
||||
{
|
||||
title: '替换原因说明',
|
||||
dataIndex: 'replaceReasonDesc',
|
||||
key: 'replaceReasonDesc',
|
||||
width: 140,
|
||||
ellipsis: true,
|
||||
render: function (v) {
|
||||
return React.createElement('span', { className: 'vr-reason-text', title: v || '' }, v || '—');
|
||||
}
|
||||
},
|
||||
{ title: '创建人', dataIndex: 'creator', key: 'creator', width: 90 },
|
||||
{ title: '创建时间', dataIndex: 'createTime', key: 'createTime', width: 150 },
|
||||
{ title: '操作', key: 'action', width: 160, fixed: 'right', render: function (_, record) { return getOperationButtons(record, _activeTab[0] === 'history'); } }
|
||||
{ title: '创建时间', dataIndex: 'createTime', key: 'createTime', width: 168 },
|
||||
{ title: '操作', key: 'action', width: 200, fixed: 'right', render: function (_, record) { return getOperationButtons(record, _activeTab[0] === 'history'); } }
|
||||
];
|
||||
|
||||
var filterItems = [
|
||||
@@ -296,10 +528,10 @@ const Component = function () {
|
||||
React.createElement('div', { style: filterLabelStyle }, '审批状态'),
|
||||
React.createElement(Select, { mode: 'multiple', placeholder: '请选择', style: filterControlStyle, value: _approvalStatus[0], onChange: handleApprovalStatusChange, options: approvalStatusOptions })),
|
||||
React.createElement('div', { key: 'originalPlate', style: filterItemStyle },
|
||||
React.createElement('div', { style: filterLabelStyle }, '被替换车车牌号'),
|
||||
React.createElement('div', { style: filterLabelStyle }, '被替换车(旧车)'),
|
||||
React.createElement(Select, { placeholder: '请输入或选择车牌号', style: filterControlStyle, value: _originalPlate[0], onChange: function (v) { _originalPlate[1](v); }, allowClear: true, showSearch: true, options: plateOptions, filterOption: function (input, opt) { return (opt.label || '').toString().toLowerCase().indexOf((input || '').toLowerCase()) !== -1; } })),
|
||||
React.createElement('div', { key: 'replacePlate', style: filterItemStyle },
|
||||
React.createElement('div', { style: filterLabelStyle }, '替换车车牌号'),
|
||||
React.createElement('div', { style: filterLabelStyle }, '新车'),
|
||||
React.createElement(Select, { placeholder: '请输入或选择车牌号', style: filterControlStyle, value: _replacePlate[0], onChange: function (v) { _replacePlate[1](v); }, allowClear: true, showSearch: true, options: plateOptions, filterOption: function (input, opt) { return (opt.label || '').toString().toLowerCase().indexOf((input || '').toLowerCase()) !== -1; } })),
|
||||
React.createElement('div', { key: 'replaceReason', style: filterItemStyle },
|
||||
React.createElement('div', { style: filterLabelStyle }, '替换原因'),
|
||||
@@ -330,12 +562,49 @@ const Component = function () {
|
||||
return currentList.slice(start, start + pageSize);
|
||||
}, [currentList, page, pageSize]);
|
||||
|
||||
var listStats = useMemo(function () {
|
||||
return {
|
||||
ongoing: filteredOngoing.length,
|
||||
history: filteredHistory.length,
|
||||
selected: (_selectedRowKeys[0] || []).length
|
||||
};
|
||||
}, [filteredOngoing.length, filteredHistory.length, _selectedRowKeys[0]]);
|
||||
|
||||
var rowSelection = {
|
||||
selectedRowKeys: _selectedRowKeys[0],
|
||||
onChange: function (keys) { _selectedRowKeys[1](keys); },
|
||||
fixed: true
|
||||
};
|
||||
|
||||
var tablePagination = {
|
||||
current: page,
|
||||
pageSize: pageSize,
|
||||
total: currentList.length,
|
||||
showSizeChanger: true,
|
||||
showQuickJumper: true,
|
||||
showTotal: function (t) { return '共 ' + t + ' 条'; },
|
||||
onChange: function (p, ps) { setPage(p); if (ps) setPageSize(ps); }
|
||||
};
|
||||
|
||||
function renderTableBody() {
|
||||
if (displayList.length === 0) {
|
||||
return React.createElement(Empty, {
|
||||
className: 'vr-empty',
|
||||
image: Empty.PRESENTED_IMAGE_SIMPLE,
|
||||
description: '暂无符合条件的替换车记录,请调整筛选条件后重试'
|
||||
});
|
||||
}
|
||||
return React.createElement(Table, {
|
||||
rowKey: 'id',
|
||||
rowSelection: rowSelection,
|
||||
columns: tableColumns,
|
||||
dataSource: displayList,
|
||||
size: 'small',
|
||||
scroll: { x: 1900 },
|
||||
pagination: tablePagination
|
||||
});
|
||||
}
|
||||
|
||||
var requirementContent = `替换车管理(2026年3月3日版本)
|
||||
一个「数字化资产ONEOS运管平台」中的「运维管理」「车辆业务」「替换车管理」模块
|
||||
|
||||
@@ -351,39 +620,27 @@ const Component = function () {
|
||||
2.2.替换类型:选择器,分为永久替换、临时替换两种方式;
|
||||
2.3.项目名称:选择器,支持输入框中输入关键内容进行搜索,下拉匹配相应项;
|
||||
2.4.审批状态:选择器,分为全部、待审批、审批中、审批驳回、未提交、撤回;
|
||||
2.5.被替换车车牌号:选择器,支持输入框中输入关键内容进行搜索,下拉匹配相应项;
|
||||
2.6.替换车车牌号:选择器,支持输入框中输入关键内容进行搜索,下拉匹配相应项;
|
||||
2.5.被替换车(旧车):选择器,支持输入框中输入关键内容进行搜索,下拉匹配相应项;
|
||||
2.6.新车:选择器,支持输入框中输入关键内容进行搜索,下拉匹配相应项;
|
||||
2.7.替换原因:选择器,分为全部、客户原因、车辆原因;
|
||||
2.8.创建人:选择器,下拉选择所有创建人;
|
||||
2.9.创建时间:日期选择器,支持单输入框内双日历选择开始-结束时间,默认提示文本为:请选择开始时间、请选择结束时间;
|
||||
|
||||
3.列表:列表右上角为新增、导出,首列为多选,支持多选后导出对应条目;
|
||||
列表展示所有替换车记录,分为进行中、历史记录两个tab,字段依次为:替换日期、替换类型、项目名称、审批状态、被替换车车牌号、被替换车品牌、被替换车型号、替换车车牌号、替换车品牌、替换车型号、替换原因、替换原因说明、创建人、创建时间、操作;
|
||||
列表展示所有替换车记录,分为进行中、历史记录两个tab,字段依次为:替换日期、审批状态、当前审批人、被替换车(旧车)、品牌、型号、新车、品牌、型号、替换类型、替换原因、替换原因说明、创建人、创建时间、操作;
|
||||
|
||||
3.1.进行中:显示替换车申请流程未结束、暂存的记录;
|
||||
3.1.1.替换日期:显示格式为:YYYY-MM-DD,显示替换车申请表单中设置的替换日期;
|
||||
3.1.2.替换类型:分为:临时替换、永久替换两种,根据替换车申请表单中设置的替换类型显示;
|
||||
3.1.3.项目名称:显示替换车申请表单中设置的项目名称;
|
||||
3.1.4.审批状态:显示替换车申请当前审批状态,分为待审批、审批中、审批驳回、未提交、撤回;
|
||||
3.1.4.1.待审批:发起人已提交,但还没有任何流程节点完成审批;
|
||||
3.1.4.2.审批中:发起人已提交,已有1个以上节点完成审批,但未完成最终节点审批;
|
||||
3.1.4.3.审批驳回:发起人已提交,任意流程节点驳回,该状态下操作列支持编辑和重新提交;
|
||||
3.1.4.4.未提交:发起人仅保存,但未提交审批;
|
||||
3.1.4.5.撤回:发起人主动撤回审批流程;
|
||||
3.1.5.被替换车车牌号:显示替换车申请表单中被替换车车牌号;
|
||||
3.1.6.被替换车品牌:显示替换车申请表单中被替换车品牌;
|
||||
3.1.7.被替换车型号:显示替换车申请表单中被替换车型号;
|
||||
3.1.8.替换车车牌号:显示替换车申请表单中替换车车牌号;
|
||||
3.1.9.替换车品牌:显示替换车申请表单中替换车品牌;
|
||||
3.1.10.替换车型号:显示替换车申请表单中替换车型号;
|
||||
3.1.11.替换原因:显示替换车申请表单中替换原因;
|
||||
3.1.12.替换原因说明:显示替换车申请表单中替换原因说明;
|
||||
3.1.13.创建人:显示替换车申请表单中创建人;
|
||||
3.1.14.创建时间:显示替换车申请表单中创建时间,显示格式为:YYYY-MM-DD HH:MM;
|
||||
3.1.15.操作:查看、编辑、撤回;
|
||||
3.1.15.1.查看:当「审批状态」为「待审批」「审批中」「审批驳回」「未提交」「撤回」时显示,点击跳转替换车管理-查看页面;
|
||||
3.1.15.2.编辑:当「审批状态」为「未提交」「审批驳回」「撤回」时显示,点击跳转替换车管理-编辑页面;
|
||||
3.1.15.3.撤回:当「审批状态」为「审批中」时显示,点击撤回合同时进行二次确认,提示语:是否确认撤回该替换车申请;
|
||||
3.1.1.替换日期:显示格式为:YYYY-MM-DD HH:MM:SS;
|
||||
3.1.2.审批状态:分为待审批、审批中、审批驳回、未提交、撤回;
|
||||
3.1.3.当前审批人:显示当前待审批节点审批人,未提交/撤回等为「—」;
|
||||
3.1.4.被替换车(旧车)、品牌、型号、新车、品牌、型号:展示申请表单车辆信息;
|
||||
3.1.5.替换类型:临时替换、永久替换;
|
||||
3.1.6.替换原因、替换原因说明、创建人、创建时间(YYYY-MM-DD HH:MM:SS);
|
||||
3.1.7.操作:查看、编辑、撤回、删除(逻辑删除);
|
||||
3.1.7.1.查看:审批状态为待审批/审批中/审批驳回/未提交/撤回时显示;
|
||||
3.1.7.2.编辑:审批状态为未提交/审批驳回/撤回时显示;
|
||||
3.1.7.3.撤回:审批状态为审批中时显示,二次确认;
|
||||
3.1.7.4.删除:审批状态为撤回/审批驳回时显示,逻辑删除,二次确认;
|
||||
|
||||
3.2.历史记录:显示替换车申请流程已结束的记录;
|
||||
3.2.1.替换日期:显示格式为:YYYY-MM-DD,显示替换车申请表单中设置的替换日期;
|
||||
@@ -406,88 +663,99 @@ const Component = function () {
|
||||
|
||||
列表右下方为分页符。`;
|
||||
|
||||
var layoutStyle = { padding: '16px 24px', background: '#f5f5f5', minHeight: '100vh' };
|
||||
var reqTitleStyle = { fontSize: 18, fontWeight: 600, marginBottom: 16, color: 'rgba(0,0,0,0.85)' };
|
||||
var reqSectionStyle = { fontSize: 15, fontWeight: 600, marginTop: 16, marginBottom: 8, color: 'rgba(0,0,0,0.85)' };
|
||||
var reqItemStyle = { fontSize: 13, marginLeft: 32, marginTop: 4, marginBottom: 2, lineHeight: 1.6, color: 'rgba(0,0,0,0.75)' };
|
||||
var activeTab = _activeTab[0];
|
||||
var selectedCount = (_selectedRowKeys[0] || []).length;
|
||||
|
||||
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(Button, { type: 'link', style: { padding: 0 }, onClick: function () { _requirementModalVisible[1](true); } }, '查看需求说明')
|
||||
),
|
||||
React.createElement(Card, { style: { marginBottom: 16 } },
|
||||
React.createElement('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: '16px 24px', alignItems: 'start' } }, filterNodes),
|
||||
React.createElement('div', { style: { display: 'flex', justifyContent: 'flex-end', gap: 8, marginTop: 16 } },
|
||||
React.createElement(Button, { onClick: handleReset }, '重置'),
|
||||
React.createElement(Button, { type: 'primary', onClick: handleQuery }, '查询'),
|
||||
React.createElement(Button, { type: 'link', size: 'small', onClick: function () { _filterExpanded[1](!_filterExpanded[0]); } }, _filterExpanded[0] ? '收起' : '展开')
|
||||
)
|
||||
),
|
||||
React.createElement(Card, null,
|
||||
React.createElement('div', { style: { marginBottom: 16, display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
|
||||
React.createElement(Tabs, {
|
||||
activeKey: _activeTab[0],
|
||||
onChange: function (k) { _activeTab[1](k); _selectedRowKeys[1]([]); setPage(1); },
|
||||
return React.createElement(App, null,
|
||||
React.createElement('div', { className: 'vr-list-page', style: { minHeight: '100vh', padding: '20px 24px 32px', background: 'linear-gradient(180deg,#f8fafc 0%,#f1f5f9 100%)' } },
|
||||
React.createElement('style', null, pageStyles),
|
||||
React.createElement('div', { className: 'vr-page-header' },
|
||||
React.createElement(Breadcrumb, {
|
||||
items: [
|
||||
{ key: 'ongoing', label: '进行中' },
|
||||
{ key: 'history', label: '历史记录' }
|
||||
{ title: '运维管理' },
|
||||
{ title: '车辆业务' },
|
||||
{ title: '替换车管理' }
|
||||
]
|
||||
}),
|
||||
React.createElement('div', { style: { display: 'flex', gap: 8 } },
|
||||
React.createElement(Button, { type: 'primary', onClick: function () { message.info('新增替换车申请(原型)'); } }, '新增'),
|
||||
React.createElement(Button, { onClick: function () { message.info('导出选中记录(原型)'); } }, '导出')
|
||||
React.createElement(Button, { type: 'link', style: { padding: 0, color: '#2563eb', fontWeight: 500 }, onClick: function () { _requirementModalVisible[1](true); } }, '查看需求说明')
|
||||
),
|
||||
React.createElement(Card, { className: 'vr-filter-card', title: '筛选条件' },
|
||||
React.createElement('div', { className: 'vr-filter-grid' }, filterNodes),
|
||||
React.createElement('div', { className: 'vr-filter-actions' },
|
||||
React.createElement(Button, { onClick: handleReset }, '重置'),
|
||||
React.createElement(Button, { type: 'primary', onClick: handleQuery }, '查询'),
|
||||
React.createElement(Button, { type: 'link', size: 'small', onClick: function () { _filterExpanded[1](!_filterExpanded[0]); } }, _filterExpanded[0] ? '收起' : '展开')
|
||||
)
|
||||
),
|
||||
React.createElement(Table, {
|
||||
rowKey: 'id',
|
||||
rowSelection: rowSelection,
|
||||
columns: tableColumns,
|
||||
dataSource: displayList,
|
||||
size: 'small',
|
||||
scroll: { x: 1600 },
|
||||
pagination: {
|
||||
current: page,
|
||||
pageSize: pageSize,
|
||||
total: currentList.length,
|
||||
showSizeChanger: true,
|
||||
showQuickJumper: true,
|
||||
showTotal: function (t) { return '共 ' + t + ' 条'; },
|
||||
onChange: function (p, ps) { setPage(p); if (ps) setPageSize(ps); }
|
||||
}
|
||||
})
|
||||
),
|
||||
React.createElement(Modal, {
|
||||
title: '是否确认撤回该替换车申请',
|
||||
open: _withdrawModalVisible[0],
|
||||
onCancel: function () { _withdrawModalVisible[1](false); _withdrawModalRecord[1](null); },
|
||||
onOk: function () { message.success('已撤回(原型)'); _withdrawModalVisible[1](false); _withdrawModalRecord[1](null); },
|
||||
okText: '确定',
|
||||
cancelText: '取消'
|
||||
}),
|
||||
React.createElement(Modal, {
|
||||
title: '是否确认转永久替换',
|
||||
open: _toPermanentModalVisible[0],
|
||||
onCancel: function () { _toPermanentModalVisible[1](false); _toPermanentModalRecord[1](null); },
|
||||
onOk: function () { message.success('已转为永久替换(原型)'); _toPermanentModalVisible[1](false); _toPermanentModalRecord[1](null); },
|
||||
okText: '提交',
|
||||
cancelText: '取消'
|
||||
}),
|
||||
React.createElement(Modal, {
|
||||
title: '需求说明',
|
||||
open: _requirementModalVisible[0],
|
||||
onCancel: function () { _requirementModalVisible[1](false); },
|
||||
width: 720,
|
||||
footer: React.createElement(Button, { onClick: function () { _requirementModalVisible[1](false); } }, '关闭'),
|
||||
bodyStyle: { maxHeight: '70vh', overflow: 'auto' }
|
||||
}, React.createElement('div', { style: { padding: '8px 0' } },
|
||||
React.createElement('div', { style: { whiteSpace: 'pre-wrap', fontSize: 13, lineHeight: 1.6 } }, requirementContent))
|
||||
React.createElement(Card, { className: 'vr-list-card', title: '替换车列表' },
|
||||
React.createElement('div', { className: 'vr-list-table' },
|
||||
React.createElement(Tabs, {
|
||||
className: 'vr-tabs',
|
||||
activeKey: activeTab,
|
||||
onChange: function (k) { _activeTab[1](k); _selectedRowKeys[1]([]); setPage(1); },
|
||||
tabBarExtraContent: React.createElement('div', { style: { display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' } },
|
||||
React.createElement(Button, { type: 'primary', onClick: function () { message.info('新增替换车申请(原型)'); } }, '新增'),
|
||||
selectedCount > 0
|
||||
? React.createElement(Badge, { count: selectedCount, size: 'small', offset: [-4, 4] },
|
||||
React.createElement(Button, { onClick: function () { message.info('导出选中 ' + selectedCount + ' 条(原型)'); } }, '导出')
|
||||
)
|
||||
: React.createElement(Button, { onClick: function () { message.info('请先勾选需要导出的记录'); } }, '导出')
|
||||
),
|
||||
destroyInactiveTabPane: true,
|
||||
items: [
|
||||
{ key: 'ongoing', label: '进行中 (' + listStats.ongoing + ')', children: activeTab === 'ongoing' ? renderTableBody() : null },
|
||||
{ key: 'history', label: '历史记录 (' + listStats.history + ')', children: activeTab === 'history' ? renderTableBody() : null }
|
||||
]
|
||||
})
|
||||
)
|
||||
),
|
||||
React.createElement(Modal, {
|
||||
title: '是否确认撤回该替换车申请',
|
||||
open: _withdrawModalVisible[0],
|
||||
onCancel: function () { _withdrawModalVisible[1](false); _withdrawModalRecord[1](null); },
|
||||
onOk: function () { message.success('已撤回(原型)'); _withdrawModalVisible[1](false); _withdrawModalRecord[1](null); },
|
||||
okText: '确定',
|
||||
cancelText: '取消'
|
||||
}),
|
||||
React.createElement(Modal, {
|
||||
title: '是否确认转永久替换',
|
||||
open: _toPermanentModalVisible[0],
|
||||
onCancel: function () { _toPermanentModalVisible[1](false); _toPermanentModalRecord[1](null); },
|
||||
onOk: function () { message.success('已转为永久替换(原型)'); _toPermanentModalVisible[1](false); _toPermanentModalRecord[1](null); },
|
||||
okText: '提交',
|
||||
cancelText: '取消'
|
||||
}),
|
||||
React.createElement(Modal, {
|
||||
title: '是否确认逻辑删除该替换车申请?',
|
||||
open: _deleteModalVisible[0],
|
||||
onCancel: function () { _deleteModalVisible[1](false); _deleteModalRecord[1](null); },
|
||||
onOk: function () {
|
||||
var rec = _deleteModalRecord[0];
|
||||
if (rec && rec.id) {
|
||||
_deletedIds[1](function (prev) {
|
||||
if (prev.indexOf(rec.id) !== -1) return prev;
|
||||
return prev.concat(rec.id);
|
||||
});
|
||||
_selectedRowKeys[1](function (prev) { return prev.filter(function (k) { return k !== rec.id; }); });
|
||||
}
|
||||
message.success('已逻辑删除(原型)');
|
||||
_deleteModalVisible[1](false);
|
||||
_deleteModalRecord[1](null);
|
||||
},
|
||||
okText: '确定',
|
||||
cancelText: '取消',
|
||||
okButtonProps: { danger: true }
|
||||
}),
|
||||
React.createElement(Modal, {
|
||||
title: '需求说明',
|
||||
open: _requirementModalVisible[0],
|
||||
onCancel: function () { _requirementModalVisible[1](false); },
|
||||
width: 720,
|
||||
footer: React.createElement(Button, { onClick: function () { _requirementModalVisible[1](false); } }, '关闭'),
|
||||
bodyStyle: { maxHeight: '70vh', overflow: 'auto' }
|
||||
}, React.createElement('div', { style: { padding: '8px 0' } },
|
||||
React.createElement('div', { style: { whiteSpace: 'pre-wrap', fontSize: 13, lineHeight: 1.6, color: '#334155' } }, requirementContent))
|
||||
)
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
226
web端/运维管理/车辆业务/查看故障.jsx
Normal file
226
web端/运维管理/车辆业务/查看故障.jsx
Normal file
@@ -0,0 +1,226 @@
|
||||
// 【重要】必须使用 const Component 作为组件变量名
|
||||
// ONEOS-web - 运维管理 - 车辆业务 - 查看故障
|
||||
|
||||
const Component = function () {
|
||||
var useState = React.useState;
|
||||
|
||||
var antd = window.antd;
|
||||
var Button = antd.Button;
|
||||
var Input = antd.Input;
|
||||
var Select = antd.Select;
|
||||
var DatePicker = antd.DatePicker;
|
||||
var Form = antd.Form;
|
||||
var Row = antd.Row;
|
||||
var Col = antd.Col;
|
||||
var Breadcrumb = antd.Breadcrumb;
|
||||
var Layout = antd.Layout;
|
||||
var message = antd.message;
|
||||
var Card = antd.Card;
|
||||
var Upload = antd.Upload;
|
||||
|
||||
var _form = Form.useForm();
|
||||
var faultForm = _form[0];
|
||||
|
||||
// 故障等级枚举
|
||||
var faultLevelOptions = [
|
||||
{ label: '特急', value: '特急' },
|
||||
{ label: '紧急', value: '紧急' },
|
||||
{ label: '一般', value: '一般' },
|
||||
{ label: '提示', value: '提示' }
|
||||
];
|
||||
|
||||
// 故障类型枚举
|
||||
var faultTypeOptions = [
|
||||
{ label: '底盘故障', value: '底盘故障' },
|
||||
{ label: '三电故障', value: '三电故障' },
|
||||
{ label: '整车系统', value: '整车系统' },
|
||||
{ label: '燃料电池系统故障', value: '燃料电池系统故障' },
|
||||
{ label: '供氢系统故障', value: '供氢系统故障' },
|
||||
{ label: '空调系统故障', value: '空调系统故障' },
|
||||
{ label: '冷机故障', value: '冷机故障' },
|
||||
{ label: '其他故障', value: '其他故障' }
|
||||
];
|
||||
|
||||
// 故障来源枚举
|
||||
var faultSourceOptions = [
|
||||
{ label: '客户报告', value: '客户报告' },
|
||||
{ label: '定期保养', value: '定期保养' },
|
||||
{ label: '司机操作问题', value: '司机操作问题' }
|
||||
];
|
||||
|
||||
// 解决情况枚举
|
||||
var resolveStatusOptions = [
|
||||
{ label: '未解决', value: '未解决' },
|
||||
{ label: '临时排故', value: '临时排故' },
|
||||
{ label: '已解决', value: '已解决' }
|
||||
];
|
||||
|
||||
var plateOptions = [
|
||||
{ label: '沪A12345', value: '沪A12345', brand: '一汽解放', model: 'J6P', company: '上海羚牛', vin: 'LNW1234567890ABCD' },
|
||||
{ label: '浙B88888', value: '浙B88888', brand: '东风商用车', model: '天龙', company: '浙江羚牛', vin: 'LNW0987654321EFGH' },
|
||||
{ label: '苏C66666', value: '苏C66666', brand: '福田欧曼', model: 'EST', company: '苏州冷链速运有限公司', vin: 'LNW1357924680IJKL' },
|
||||
{ label: '沪D99999', value: '沪D99999', brand: '陕汽重卡', model: '德龙', company: '上海城配物流有限公司', vin: 'LNW2468013579MNOP' }
|
||||
];
|
||||
|
||||
var handleBack = function () {
|
||||
message.info('返回列表');
|
||||
};
|
||||
|
||||
// 模拟数据加载
|
||||
React.useEffect(function() {
|
||||
var mockData = { key: '1', code: 'F-2024-001', plate: '沪A12345', brand: '一汽解放', model: 'J6P', company: '上海羚牛', type: '底盘故障', level: '紧急', source: '客户报告', status: '未解决', reportTime: '2024-05-10 08:30:00', lastOperator: '王婷婷', lastOperationTime: '2024-05-10 09:00:00', desc: '车辆重载下制动踏板偏软,制动距离明显变长' };
|
||||
if (mockData.reportTime) {
|
||||
if (typeof window.dayjs === 'function') {
|
||||
mockData.reportTime = window.dayjs(mockData.reportTime);
|
||||
} else if (typeof window.moment === 'function') {
|
||||
mockData.reportTime = window.moment(mockData.reportTime);
|
||||
}
|
||||
}
|
||||
faultForm.setFieldsValue(mockData);
|
||||
}, []);
|
||||
|
||||
return React.createElement(Layout, { className: 'arco-theme-overrides', style: { minHeight: '100vh', background: '#f2f3f5', fontFamily: 'Inter, Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif' } },
|
||||
React.createElement('style', null, `
|
||||
.arco-theme-overrides .ant-btn { border-radius: 4px; }
|
||||
.arco-theme-overrides .ant-btn-primary { background-color: #165dff; border-color: #165dff; }
|
||||
.arco-theme-overrides .ant-btn-primary:hover { background-color: #4080ff; border-color: #4080ff; }
|
||||
|
||||
.arco-grouped-form-page { display: flex; flex-direction: column; min-height: 100vh; }
|
||||
.arco-grouped-form-page-content { flex: 1; padding: 16px 20px 24px; }
|
||||
.arco-grouped-form-page .ant-card { margin-bottom: 16px; border-radius: 4px; border: none; box-shadow: 0 1px 2px rgba(0,0,0,0.06); }
|
||||
.arco-grouped-form-page .ant-card-head { border-bottom: none; padding: 20px 24px 0; min-height: auto; }
|
||||
.arco-grouped-form-page .ant-card-head-title { font-size: 16px; font-weight: 500; color: #1d2129; padding: 0; }
|
||||
.arco-grouped-form-page .ant-card-body { padding: 24px; }
|
||||
.arco-grouped-form-page .ant-form-vertical .ant-form-item-label { padding-bottom: 8px; height: auto; line-height: 1.5715; }
|
||||
.arco-grouped-form-page .ant-form-item { margin-bottom: 24px; }
|
||||
|
||||
.arco-grouped-form-page .ant-input,
|
||||
.arco-grouped-form-page .ant-select-selector,
|
||||
.arco-grouped-form-page .ant-picker,
|
||||
.arco-grouped-form-page .ant-input-affix-wrapper { background-color: #f2f3f5; border: 1px solid #e5e6eb; border-radius: 2px; transition: all 0.1s cubic-bezier(0, 0, 1, 1); }
|
||||
|
||||
.arco-grouped-form-page .ant-input[disabled],
|
||||
.arco-grouped-form-page .ant-select-disabled .ant-select-selector,
|
||||
.arco-grouped-form-page .ant-picker-disabled { color: #86909c; background-color: #f2f3f5; border-color: #e5e6eb; cursor: not-allowed; }
|
||||
.arco-grouped-form-page .ant-input-affix-wrapper[disabled] { background-color: #f2f3f5; border-color: #e5e6eb; cursor: not-allowed; }
|
||||
.arco-grouped-form-page .ant-input-affix-wrapper > input.ant-input { background-color: transparent; }
|
||||
|
||||
.arco-grouped-form-footer { background: #fff; padding: 16px 24px; border-top: 1px solid #e5e6eb; display: flex; justify-content: flex-end; align-items: center; gap: 12px; position: sticky; bottom: 0; z-index: 100; box-shadow: 0 -2px 10px rgba(0,0,0,0.05); }
|
||||
.arco-grouped-form-footer .ant-btn { border-radius: 5px; height: 32px; padding: 4px 16px; font-size: 14px; }
|
||||
|
||||
.arco-theme-overrides .ant-breadcrumb { color: #86909c; font-size: 14px; white-space: nowrap; flex-shrink: 0; margin-bottom: 20px; }
|
||||
.arco-theme-overrides .ant-breadcrumb a { color: #4e5969; }
|
||||
.arco-theme-overrides .ant-breadcrumb a:hover { color: #165dff; background-color: transparent; }
|
||||
.arco-theme-overrides .ant-form-item-label > label { color: #4e5969; white-space: nowrap; }
|
||||
.arco-theme-overrides .ant-form-item-label > label::after { display: none !important; content: "" !important; margin: 0 !important; }
|
||||
`),
|
||||
React.createElement('div', { className: 'arco-grouped-form-page' },
|
||||
React.createElement('div', { className: 'arco-grouped-form-page-content' },
|
||||
React.createElement(Breadcrumb, {
|
||||
separator: React.createElement('span', { style: { color: '#c9cdd4' } }, '/'),
|
||||
items: [
|
||||
{ title: '首页' },
|
||||
{ title: '运维管理' },
|
||||
{ title: '车辆业务' },
|
||||
{ title: React.createElement('a', { onClick: function(e) { e.preventDefault(); handleBack(); } }, '故障管理') },
|
||||
{ title: React.createElement('span', { style: { color: '#1d2129' } }, '查看故障单') }
|
||||
]
|
||||
}),
|
||||
|
||||
React.createElement(Form, { form: faultForm, layout: 'vertical', disabled: true },
|
||||
// 车辆信息
|
||||
React.createElement(Card, { title: '车辆信息', bordered: false },
|
||||
React.createElement(Row, { gutter: 24 },
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '车牌号', name: 'plate', rules: [{ required: true, message: '请选择车牌号' }] },
|
||||
React.createElement(Select, {
|
||||
placeholder: '请选择车牌号',
|
||||
options: plateOptions,
|
||||
showSearch: true
|
||||
})
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '车辆品牌', name: 'brand' },
|
||||
React.createElement(Input, { placeholder: '自动带入', disabled: true, style: { backgroundColor: '#f2f3f5', color: '#86909c' } })
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '车辆型号', name: 'model' },
|
||||
React.createElement(Input, { placeholder: '自动带入', disabled: true, style: { backgroundColor: '#f2f3f5', color: '#86909c' } })
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '运营公司', name: 'company' },
|
||||
React.createElement(Input, { placeholder: '自动带入', disabled: true, style: { backgroundColor: '#f2f3f5', color: '#86909c' } })
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '车辆识别代码', name: 'vin' },
|
||||
React.createElement(Input, { placeholder: '自动带入', disabled: true, style: { backgroundColor: '#f2f3f5', color: '#86909c' } })
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
// 故障信息
|
||||
React.createElement(Card, { title: '故障信息', bordered: false },
|
||||
React.createElement(Row, { gutter: 24 },
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '故障类型', name: 'type', rules: [{ required: true, message: '请选择故障类型' }] },
|
||||
React.createElement(Select, { placeholder: '请选择故障类型', options: faultTypeOptions })
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '故障来源', name: 'source', rules: [{ required: true, message: '请选择故障来源' }] },
|
||||
React.createElement(Select, { placeholder: '请选择故障来源', options: faultSourceOptions })
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '故障等级', name: 'level', rules: [{ required: true, message: '请选择故障等级' }] },
|
||||
React.createElement(Select, { placeholder: '请选择故障等级', options: faultLevelOptions })
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '故障上报时间', name: 'reportTime', rules: [{ required: true, message: '请选择故障上报时间' }] },
|
||||
React.createElement(DatePicker, { style: { width: '100%' }, placeholder: '请选择上报时间', showTime: true })
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 8 },
|
||||
React.createElement(Form.Item, { label: '解决情况', name: 'status', rules: [{ required: true, message: '请选择故障解决情况' }] },
|
||||
React.createElement(Select, { placeholder: '请选择故障解决情况', options: resolveStatusOptions })
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
// 故障证据与描述
|
||||
React.createElement(Card, { title: '故障证据与描述', bordered: false },
|
||||
React.createElement(Row, { gutter: 24 },
|
||||
React.createElement(Col, { span: 24 },
|
||||
React.createElement(Form.Item, { label: '故障描述', name: 'desc', rules: [{ required: true, message: '请填写故障描述' }] },
|
||||
React.createElement(Input.TextArea, {
|
||||
placeholder: '在何种状态下,产生何种现象,导致何种事故',
|
||||
style: { height: 80, minHeight: 80, resize: 'none' }
|
||||
})
|
||||
)
|
||||
),
|
||||
React.createElement(Col, { span: 24 },
|
||||
React.createElement(Form.Item, { label: '故障证据', name: 'evidence' },
|
||||
React.createElement(Upload, { listType: 'picture-card' }),
|
||||
React.createElement('div', { style: { fontSize: 12, color: '#86909c', marginTop: 8 } }, '支持上传照片、视频、录音')
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
// 底部操作栏
|
||||
React.createElement('div', { className: 'arco-grouped-form-footer' },
|
||||
React.createElement(Button, { onClick: handleBack, style: { borderRadius: 5 } }, '返回列表')
|
||||
)
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
if (typeof module !== 'undefined' && module.exports) module.exports = Component;
|
||||
Reference in New Issue
Block a user