939 lines
46 KiB
JavaScript
Executable File
939 lines
46 KiB
JavaScript
Executable File
// 【重要】必须使用 const Component 作为组件变量名
|
||
// 车辆上牌管理 - 车辆资产管理后台模块
|
||
var ARCO_TOKEN = {
|
||
primary: '#165DFF',
|
||
primaryHover: '#4080FF',
|
||
danger: '#F53F3F',
|
||
success: '#00B42A',
|
||
neutral1: '#FFFFFF',
|
||
neutral2: '#F7F8FA',
|
||
neutral3: '#F2F3F5',
|
||
neutral4: '#E5E6EB',
|
||
neutral5: '#C9CDD4',
|
||
neutral6: '#86909C',
|
||
neutral7: '#4E5969',
|
||
neutral8: '#1D2129',
|
||
border: '#E5E6EB',
|
||
fill: '#F2F3F5',
|
||
fillSecondary: '#F7F8FA',
|
||
shadowLight: '0 1px 2px rgba(0,0,0,0.05)',
|
||
shadowMedium: '0 2px 8px rgba(0,0,0,0.08)',
|
||
radiusSmall: '2px',
|
||
radiusMedium: '4px',
|
||
radiusLarge: '8px',
|
||
spacing8: '8px',
|
||
spacing12: '12px',
|
||
spacing16: '16px',
|
||
spacing24: '24px',
|
||
fontSize14: '14px',
|
||
fontSize16: '16px',
|
||
fontFamily: '-apple-system, BlinkMacSystemFont, "PingFang SC", "Helvetica Neue", Arial, sans-serif',
|
||
link: '#165DFF'
|
||
};
|
||
|
||
const Component = function () {
|
||
var antd = window.antd;
|
||
var Input = antd.Input;
|
||
var Select = antd.Select;
|
||
var Button = antd.Button;
|
||
var DatePicker = antd.DatePicker;
|
||
var Table = antd.Table;
|
||
var Modal = antd.Modal;
|
||
var message = antd.message;
|
||
var Option = Select.Option;
|
||
var Spin = antd.Spin;
|
||
|
||
var _useState = React.useState('');
|
||
var filterDateStart = _useState[0];
|
||
var setFilterDateStart = _useState[1];
|
||
|
||
var _useState2 = React.useState('');
|
||
var filterDateEnd = _useState2[0];
|
||
var setFilterDateEnd = _useState2[1];
|
||
|
||
var _useState3 = React.useState('');
|
||
var filterOperator = _useState3[0];
|
||
var setFilterOperator = _useState3[1];
|
||
|
||
var _useState4 = React.useState('');
|
||
var filterPlateNo = _useState4[0];
|
||
var setFilterPlateNo = _useState4[1];
|
||
|
||
var _useState5 = React.useState('');
|
||
var filterVin = _useState5[0];
|
||
var setFilterVin = _useState5[1];
|
||
|
||
var _useState5h = React.useState('');
|
||
var appliedDateStart = _useState5h[0];
|
||
var setAppliedDateStart = _useState5h[1];
|
||
var _useState5i = React.useState('');
|
||
var appliedDateEnd = _useState5i[0];
|
||
var setAppliedDateEnd = _useState5i[1];
|
||
var _useState5j = React.useState('');
|
||
var appliedOperator = _useState5j[0];
|
||
var setAppliedOperator = _useState5j[1];
|
||
var _useState5k = React.useState('');
|
||
var appliedPlateNo = _useState5k[0];
|
||
var setAppliedPlateNo = _useState5k[1];
|
||
var _useState5l = React.useState('');
|
||
var appliedVin = _useState5l[0];
|
||
var setAppliedVin = _useState5l[1];
|
||
|
||
var _useState6 = React.useState(1);
|
||
var currentPage = _useState6[0];
|
||
var setCurrentPage = _useState6[1];
|
||
|
||
var _useState7 = React.useState(10);
|
||
var pageSize = _useState7[0];
|
||
var setPageSize = _useState7[1];
|
||
|
||
var _useState9 = React.useState(null);
|
||
var viewPhotoRecord = _useState9[0];
|
||
var setViewPhotoRecord = _useState9[1];
|
||
|
||
var _useState10 = React.useState(false);
|
||
var ocrModalVisible = _useState10[0];
|
||
var setOcrModalVisible = _useState10[1];
|
||
|
||
var _useState11 = React.useState(false);
|
||
var confirmModalVisible = _useState11[0];
|
||
var setConfirmModalVisible = _useState11[1];
|
||
|
||
var _useState12 = React.useState(null);
|
||
var confirmData = _useState12[0];
|
||
var setConfirmData = _useState12[1];
|
||
|
||
var _useState13 = React.useState([]);
|
||
var batchConfirmList = _useState13[0];
|
||
var setBatchConfirmList = _useState13[1];
|
||
|
||
var _useState14 = React.useState(0);
|
||
var batchConfirmIndex = _useState14[0];
|
||
var setBatchConfirmIndex = _useState14[1];
|
||
|
||
var _useState15 = React.useState(false);
|
||
var isBatchMode = _useState15[0];
|
||
var setIsBatchMode = _useState15[1];
|
||
|
||
var _useState15b = React.useState(0);
|
||
var batchTotalCount = _useState15b[0];
|
||
var setBatchTotalCount = _useState15b[1];
|
||
|
||
var _useState16 = React.useState('');
|
||
var confirmVin = _useState16[0];
|
||
var setConfirmVin = _useState16[1];
|
||
|
||
var _useState17 = React.useState('');
|
||
var confirmPlateNo = _useState17[0];
|
||
var setConfirmPlateNo = _useState17[1];
|
||
|
||
var _useState17a = React.useState('');
|
||
var confirmScrapDate = _useState17a[0];
|
||
var setConfirmScrapDate = _useState17a[1];
|
||
|
||
var _useState17b = React.useState('');
|
||
var confirmInspectionExpiry = _useState17b[0];
|
||
var setConfirmInspectionExpiry = _useState17b[1];
|
||
|
||
var _useState18b = React.useState(false);
|
||
var showRequirementModal = _useState18b[0];
|
||
var setShowRequirementModal = _useState18b[1];
|
||
|
||
var _useState18c = React.useState(false);
|
||
var batchTaskCardVisible = _useState18c[0];
|
||
var setBatchTaskCardVisible = _useState18c[1];
|
||
|
||
var fileInputRef = React.useRef(null);
|
||
var batchFullListRef = React.useRef(null);
|
||
var batchUploadFromCardRef = React.useRef(false);
|
||
var batchFileInputRef = React.useRef(null);
|
||
|
||
var _useState18e = React.useState([]);
|
||
var batchTaskList = _useState18e[0];
|
||
var setBatchTaskList = _useState18e[1];
|
||
|
||
var mockVehicleList = [
|
||
{ id: 'v001', frameNo: 'LGW123456', brand: '比亚迪', model: '秦', vehicleType: '轿车' },
|
||
{ id: 'v002', frameNo: 'LGW789012', brand: '特斯拉', model: 'Model 3', vehicleType: '轿车' },
|
||
{ id: 'v003', frameNo: 'HZ111222', brand: '小鹏', model: 'P7', vehicleType: '轿车' }
|
||
];
|
||
|
||
var initialRecordList = [
|
||
{
|
||
id: 'r001',
|
||
plateDate: '2025-02-01',
|
||
operator: '张明',
|
||
plateNo: '粤A12345',
|
||
vin: 'LGW123456',
|
||
vehicleType: '轿车',
|
||
brand: '比亚迪',
|
||
model: '秦',
|
||
photoUrl: 'https://picsum.photos/300/200?random=1'
|
||
},
|
||
{
|
||
id: 'r002',
|
||
plateDate: '2025-02-03',
|
||
operator: '王芳',
|
||
plateNo: '粤A67890',
|
||
vin: 'LGW789012',
|
||
vehicleType: '轿车',
|
||
brand: '特斯拉',
|
||
model: 'Model 3',
|
||
photoUrl: 'https://picsum.photos/300/200?random=2'
|
||
}
|
||
];
|
||
|
||
// 近5条批量上牌任务(时间、照片数量、完成进度);进度100%时有 items 用于「识别」进入确认界面
|
||
var getInitialBatchTaskList = function () {
|
||
return [
|
||
{ id: 'bt1', createTime: '2025-02-12 10:30', photoCount: 3, progress: 100, items: [
|
||
{ photoUrl: 'https://picsum.photos/300/200?random=b1', vin: 'LGW123456', plateNo: '粤A11111', vehicle: mockVehicleList[0] },
|
||
{ photoUrl: 'https://picsum.photos/300/200?random=b2', vin: 'LGW789012', plateNo: '粤A22222', vehicle: mockVehicleList[1] },
|
||
{ photoUrl: 'https://picsum.photos/300/200?random=b3', vin: 'HZ111222', plateNo: '粤A33333', vehicle: mockVehicleList[2] }
|
||
]},
|
||
{ id: 'bt2', createTime: '2025-02-12 09:15', photoCount: 5, progress: 100, items: [
|
||
{ photoUrl: 'https://picsum.photos/300/200?random=b4', vin: 'LGW123456', plateNo: '粤A44444', vehicle: mockVehicleList[0] },
|
||
{ photoUrl: 'https://picsum.photos/300/200?random=b5', vin: 'LGW789012', plateNo: '粤A55555', vehicle: mockVehicleList[1] }
|
||
]},
|
||
{ id: 'bt3', createTime: '2025-02-11 16:20', photoCount: 4, progress: 80, items: null },
|
||
{ id: 'bt4', createTime: '2025-02-11 14:00', photoCount: 2, progress: 50, items: null },
|
||
{ id: 'bt5', createTime: '2025-02-10 11:30', photoCount: 6, progress: 30, items: null }
|
||
];
|
||
};
|
||
|
||
React.useEffect(function () {
|
||
setBatchTaskList(function (prev) {
|
||
if (prev.length === 0) return getInitialBatchTaskList();
|
||
return prev;
|
||
});
|
||
}, []);
|
||
|
||
var _useState18 = React.useState(initialRecordList);
|
||
var recordList = _useState18[0];
|
||
var setRecordList = _useState18[1];
|
||
|
||
var getUniqueOperators = function () {
|
||
var seen = {};
|
||
var list = [];
|
||
recordList.forEach(function (r) {
|
||
if (r.operator && !seen[r.operator]) {
|
||
seen[r.operator] = true;
|
||
list.push(r.operator);
|
||
}
|
||
});
|
||
return list.sort();
|
||
};
|
||
|
||
var getUniquePlateNos = function () {
|
||
var seen = {};
|
||
var list = [];
|
||
recordList.forEach(function (r) {
|
||
if (r.plateNo && !seen[r.plateNo]) {
|
||
seen[r.plateNo] = true;
|
||
list.push(r.plateNo);
|
||
}
|
||
});
|
||
return list.sort();
|
||
};
|
||
|
||
var getUniqueVins = function () {
|
||
var seen = {};
|
||
var list = [];
|
||
recordList.forEach(function (r) {
|
||
if (r.vin && !seen[r.vin]) {
|
||
seen[r.vin] = true;
|
||
list.push(r.vin);
|
||
}
|
||
});
|
||
mockVehicleList.forEach(function (v) {
|
||
if (v.frameNo && !seen[v.frameNo]) {
|
||
seen[v.frameNo] = true;
|
||
list.push(v.frameNo);
|
||
}
|
||
});
|
||
return list.sort();
|
||
};
|
||
|
||
var allOperators = getUniqueOperators();
|
||
var allPlateNos = getUniquePlateNos();
|
||
var allVins = getUniqueVins();
|
||
|
||
var getFilteredList = function () {
|
||
var list = recordList;
|
||
if (appliedDateStart) {
|
||
list = list.filter(function (r) { return r.plateDate >= appliedDateStart; });
|
||
}
|
||
if (appliedDateEnd) {
|
||
list = list.filter(function (r) { return r.plateDate <= appliedDateEnd; });
|
||
}
|
||
if (appliedOperator) {
|
||
list = list.filter(function (r) {
|
||
return r.operator && r.operator.indexOf(appliedOperator) >= 0;
|
||
});
|
||
}
|
||
if (appliedPlateNo) {
|
||
list = list.filter(function (r) {
|
||
return r.plateNo && r.plateNo.indexOf(appliedPlateNo) >= 0;
|
||
});
|
||
}
|
||
if (appliedVin) {
|
||
list = list.filter(function (r) {
|
||
return r.vin && r.vin.indexOf(appliedVin) >= 0;
|
||
});
|
||
}
|
||
return list;
|
||
};
|
||
|
||
var filteredList = getFilteredList();
|
||
var totalItems = filteredList.length;
|
||
var totalPages = Math.ceil(totalItems / pageSize) || 1;
|
||
var validPage = currentPage > totalPages && totalPages > 0 ? 1 : (currentPage < 1 ? 1 : currentPage);
|
||
var startIndex = (validPage - 1) * pageSize;
|
||
var endIndex = startIndex + pageSize;
|
||
var paginatedList = filteredList.slice(startIndex, endIndex);
|
||
|
||
var findVehicleByVin = function (vin) {
|
||
return mockVehicleList.find(function (v) { return v.frameNo === vin; });
|
||
};
|
||
|
||
var todayStr = function () {
|
||
var d = new Date();
|
||
var y = d.getFullYear();
|
||
var m = (d.getMonth() + 1).toString();
|
||
var day = d.getDate().toString();
|
||
if (m.length === 1) { m = '0' + m; }
|
||
if (day.length === 1) { day = '0' + day; }
|
||
return y + '-' + m + '-' + day;
|
||
};
|
||
|
||
var sampleScrapDates = ['2035-12-31', '2030-06-15', '2028-03-20'];
|
||
var sampleInspectionExpiries = ['2026-06', '2025-12', '2027-03'];
|
||
var getSampleScrapDate = function () { return sampleScrapDates[Math.floor(Math.random() * sampleScrapDates.length)]; };
|
||
var getSampleInspectionExpiry = function () { return sampleInspectionExpiries[Math.floor(Math.random() * sampleInspectionExpiries.length)]; };
|
||
|
||
var processFileAndGetItem = function (file, callback) {
|
||
var reader = new FileReader();
|
||
reader.onload = function () {
|
||
var photoUrl = reader.result;
|
||
var mockVin = mockVehicleList[0].frameNo;
|
||
var mockPlate = '粤A' + Math.floor(Math.random() * 90000 + 10000).toString();
|
||
var vehicle = findVehicleByVin(mockVin);
|
||
var item = {
|
||
photoUrl: photoUrl,
|
||
vin: mockVin,
|
||
plateNo: mockPlate,
|
||
vehicle: vehicle
|
||
};
|
||
callback(item);
|
||
};
|
||
reader.readAsDataURL(file);
|
||
};
|
||
|
||
var simulateOcrAndConfirm = function (items, isMulti) {
|
||
setOcrModalVisible(false);
|
||
if (isMulti && items.length > 1) {
|
||
batchFullListRef.current = items.slice();
|
||
setBatchConfirmList(items);
|
||
setBatchConfirmIndex(0);
|
||
setBatchTotalCount(items.length);
|
||
setConfirmData(items[0]);
|
||
setConfirmVin(items[0].vin);
|
||
setConfirmPlateNo(items[0].plateNo);
|
||
setConfirmScrapDate(getSampleScrapDate());
|
||
setConfirmInspectionExpiry(getSampleInspectionExpiry());
|
||
setConfirmModalVisible(true);
|
||
setIsBatchMode(true);
|
||
} else if (items.length > 0) {
|
||
setConfirmData(items[0]);
|
||
setConfirmVin(items[0].vin);
|
||
setConfirmPlateNo(items[0].plateNo);
|
||
setConfirmScrapDate(getSampleScrapDate());
|
||
setConfirmInspectionExpiry(getSampleInspectionExpiry());
|
||
setConfirmModalVisible(true);
|
||
setIsBatchMode(false);
|
||
}
|
||
};
|
||
|
||
var handleUpload = function (e, isBatch) {
|
||
var files = e.target.files;
|
||
if (!files || files.length === 0) return;
|
||
// 从批量上传弹框内「上传车牌」触发:不进入识别/确认页,只在弹框中新增一条识别任务
|
||
if (batchUploadFromCardRef.current) {
|
||
batchUploadFromCardRef.current = false;
|
||
var fileCount = files.length;
|
||
var collected = [];
|
||
var processed = 0;
|
||
var checkDone = function () {
|
||
processed = processed + 1;
|
||
if (processed === fileCount) {
|
||
var now = new Date();
|
||
var timeStr = now.getFullYear() + '-' + String(now.getMonth() + 1).padStart(2, '0') + '-' + String(now.getDate()).padStart(2, '0') + ' ' + String(now.getHours()).padStart(2, '0') + ':' + String(now.getMinutes()).padStart(2, '0');
|
||
setBatchTaskList(function (prev) {
|
||
var next = [{ id: 'bt' + Date.now(), createTime: timeStr, photoCount: collected.length, progress: 100, items: collected }].concat(prev);
|
||
return next.slice(0, 5);
|
||
});
|
||
}
|
||
};
|
||
for (var i = 0; i < fileCount; i++) {
|
||
(function (idx) {
|
||
processFileAndGetItem(files[idx], function (item) {
|
||
collected.push(item);
|
||
checkDone();
|
||
});
|
||
})(i);
|
||
}
|
||
e.target.value = '';
|
||
return;
|
||
}
|
||
setOcrModalVisible(true);
|
||
var fileCount = files.length;
|
||
var collected = [];
|
||
var processed = 0;
|
||
var checkDone = function () {
|
||
processed = processed + 1;
|
||
if (processed === fileCount) {
|
||
setTimeout(function () {
|
||
simulateOcrAndConfirm(collected, isBatch && collected.length > 1);
|
||
}, 1500);
|
||
}
|
||
};
|
||
for (var i = 0; i < fileCount; i++) {
|
||
(function (idx) {
|
||
processFileAndGetItem(files[idx], function (item) {
|
||
collected.push(item);
|
||
checkDone();
|
||
});
|
||
})(i);
|
||
}
|
||
e.target.value = '';
|
||
};
|
||
|
||
var handleConfirmSubmit = function () {
|
||
var vehicle = confirmData && confirmData.vehicle;
|
||
var newRecord = {
|
||
id: 'r' + Date.now(),
|
||
plateDate: todayStr(),
|
||
operator: '当前用户',
|
||
plateNo: confirmPlateNo,
|
||
vin: confirmVin,
|
||
vehicleType: vehicle ? vehicle.vehicleType : '轿车',
|
||
brand: vehicle ? vehicle.brand : '-',
|
||
model: vehicle ? vehicle.model : '-',
|
||
photoUrl: confirmData && confirmData.photoUrl ? confirmData.photoUrl : 'https://picsum.photos/300/200?random=' + Date.now()
|
||
};
|
||
var nextList = recordList.slice();
|
||
nextList.unshift(newRecord);
|
||
setRecordList(nextList);
|
||
message.success('车辆上牌成功');
|
||
if (isBatchMode && batchConfirmList.length > 1) {
|
||
var nextBatch = batchConfirmList.slice(1);
|
||
var nextItem = nextBatch[0];
|
||
setBatchConfirmList(nextBatch);
|
||
setBatchConfirmIndex(batchConfirmIndex + 1);
|
||
if (nextItem) {
|
||
setConfirmData(nextItem);
|
||
setConfirmVin(nextItem.vin);
|
||
setConfirmPlateNo(nextItem.plateNo);
|
||
setConfirmScrapDate(getSampleScrapDate());
|
||
setConfirmInspectionExpiry(getSampleInspectionExpiry());
|
||
} else {
|
||
var fullList = batchFullListRef.current;
|
||
if (fullList && fullList.length > 0) {
|
||
var now = new Date();
|
||
var timeStr = now.getFullYear() + '-' + String(now.getMonth() + 1).padStart(2, '0') + '-' + String(now.getDate()).padStart(2, '0') + ' ' + String(now.getHours()).padStart(2, '0') + ':' + String(now.getMinutes()).padStart(2, '0');
|
||
setBatchTaskList(function (prev) {
|
||
var next = [{ id: 'bt' + Date.now(), createTime: timeStr, photoCount: fullList.length, progress: 100, items: fullList }].concat(prev);
|
||
return next.slice(0, 5);
|
||
});
|
||
batchFullListRef.current = null;
|
||
}
|
||
setConfirmModalVisible(false);
|
||
setConfirmData(null);
|
||
setConfirmVin('');
|
||
setConfirmPlateNo('');
|
||
setConfirmScrapDate('');
|
||
setConfirmInspectionExpiry('');
|
||
setBatchConfirmList([]);
|
||
setBatchTotalCount(0);
|
||
setIsBatchMode(false);
|
||
}
|
||
} else {
|
||
setConfirmModalVisible(false);
|
||
setConfirmData(null);
|
||
setConfirmVin('');
|
||
setConfirmPlateNo('');
|
||
setConfirmScrapDate('');
|
||
setConfirmInspectionExpiry('');
|
||
setBatchConfirmList([]);
|
||
setBatchTotalCount(0);
|
||
setIsBatchMode(false);
|
||
}
|
||
};
|
||
|
||
var handleConfirmCancel = function () {
|
||
setConfirmModalVisible(false);
|
||
setConfirmData(null);
|
||
setConfirmVin('');
|
||
setConfirmPlateNo('');
|
||
setConfirmScrapDate('');
|
||
setConfirmInspectionExpiry('');
|
||
setBatchConfirmList([]);
|
||
setBatchConfirmIndex(0);
|
||
setBatchTotalCount(0);
|
||
setIsBatchMode(false);
|
||
};
|
||
|
||
var t = ARCO_TOKEN;
|
||
var styles = {
|
||
page: { padding: t.spacing24, fontFamily: t.fontFamily, backgroundColor: t.fill, minHeight: '100vh' },
|
||
breadcrumb: { marginBottom: t.spacing16, fontSize: t.fontSize14, color: t.neutral6, display: 'flex', alignItems: 'center', justifyContent: 'space-between' },
|
||
breadcrumbLeft: { display: 'flex', alignItems: 'center' },
|
||
breadcrumbLink: { color: t.link, textDecoration: 'none', marginRight: t.spacing8 },
|
||
breadcrumbCurrent: { color: t.neutral8 },
|
||
breadcrumbRight: { display: 'flex', alignItems: 'center' },
|
||
requirementLink: { color: t.link, textDecoration: 'none', fontSize: t.fontSize14, cursor: 'pointer' },
|
||
card: { backgroundColor: t.neutral1, borderRadius: t.radiusLarge, boxShadow: t.shadowLight, marginBottom: t.spacing16, padding: t.spacing16 },
|
||
filterRow: { display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: t.spacing12 },
|
||
filterRowRight: { display: 'flex', alignItems: 'center', gap: t.spacing8, marginLeft: 'auto' },
|
||
label: { marginRight: t.spacing8, fontSize: t.fontSize14, color: t.neutral8, whiteSpace: 'nowrap' },
|
||
input: { padding: '0 10px', height: '32px', width: '180px', borderRadius: '2px', border: '1px solid ' + t.border, fontSize: t.fontSize14, boxSizing: 'border-box' },
|
||
btn: { padding: t.spacing8 + ' ' + t.spacing16, borderRadius: t.radiusMedium, cursor: 'pointer', fontSize: t.fontSize14, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: '6px', boxSizing: 'border-box' },
|
||
btnFixed: { width: '82px', height: '32px', padding: 0, borderRadius: '2px', lineHeight: '1' },
|
||
btnIcon: { width: '14px', height: '14px', flexShrink: 0, display: 'block' },
|
||
btnFillBlue: { backgroundColor: t.primary, color: t.neutral1, border: 'none' },
|
||
btnOutlineBlue: { backgroundColor: t.neutral1, color: t.primary, border: '1px solid ' + t.primary },
|
||
btnDefault: { backgroundColor: t.neutral1, color: t.neutral8, border: '1px solid ' + t.border },
|
||
btnSize82: { width: '82px', height: '32px', padding: 0, lineHeight: '1', boxSizing: 'border-box' },
|
||
toolbar: { display: 'flex', alignItems: 'center', justifyContent: 'flex-end', gap: t.spacing12, marginBottom: t.spacing16 },
|
||
tableWrap: { overflowX: 'auto', backgroundColor: t.neutral1, borderRadius: t.radiusMedium, border: '1px solid ' + t.neutral4 },
|
||
table: { width: '100%', borderCollapse: 'separate', borderSpacing: 0, fontSize: t.fontSize14 },
|
||
th: { textAlign: 'left', padding: '12px 16px', backgroundColor: t.fillSecondary, borderBottom: '1px solid ' + t.neutral4, fontWeight: 600, color: t.neutral8, fontSize: t.fontSize14, whiteSpace: 'nowrap' },
|
||
td: { padding: '12px 16px', borderBottom: '1px solid ' + t.neutral4, color: t.neutral8, fontSize: t.fontSize14 },
|
||
pagination: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '16px', borderTop: '1px solid ' + t.neutral4, backgroundColor: t.neutral1 },
|
||
paginationLeft: { display: 'flex', alignItems: 'center', gap: '8px', fontSize: t.fontSize14, color: t.neutral7 },
|
||
paginationRight: { display: 'flex', alignItems: 'center', gap: '8px' },
|
||
paginationSelect: { padding: '4px 8px', height: '28px', borderRadius: '2px', border: '1px solid ' + t.border, fontSize: t.fontSize14, backgroundColor: t.neutral1 },
|
||
paginationBtn: { minWidth: '28px', height: '28px', padding: '0 8px', borderRadius: '2px', border: '1px solid ' + t.border, backgroundColor: t.neutral1, color: t.neutral8, cursor: 'pointer', fontSize: t.fontSize14, display: 'inline-flex', alignItems: 'center', justifyContent: 'center' },
|
||
paginationBtnActive: { backgroundColor: t.primary, color: t.neutral1, borderColor: t.primary },
|
||
paginationBtnDisabled: { opacity: 0.5, cursor: 'not-allowed' },
|
||
paginationInput: { width: '50px', height: '28px', padding: '0 8px', borderRadius: '2px', border: '1px solid ' + t.border, fontSize: t.fontSize14, textAlign: 'center' },
|
||
actionLink: { color: t.link, cursor: 'pointer', marginRight: t.spacing12, fontSize: t.fontSize14 },
|
||
modalMask: { position: 'fixed', left: 0, top: 0, right: 0, bottom: 0, backgroundColor: 'rgba(0,0,0,0.45)', zIndex: 1000, display: 'flex', alignItems: 'center', justifyContent: 'center' },
|
||
modalBox: { backgroundColor: t.neutral1, borderRadius: t.radiusLarge, maxWidth: '90%', maxHeight: '90%', overflow: 'auto', padding: t.spacing24, minWidth: '500px', position: 'relative' },
|
||
modalTitle: { fontSize: t.fontSize16, fontWeight: 600, marginBottom: t.spacing16, color: t.neutral8 },
|
||
modalFooter: { marginTop: t.spacing24, display: 'flex', justifyContent: 'flex-end', gap: t.spacing8 },
|
||
toast: { position: 'fixed', top: t.spacing24, left: '50%', transform: 'translateX(-50%)', backgroundColor: 'rgba(0,0,0,0.75)', color: t.neutral1, padding: '10px 20px', borderRadius: t.radiusMedium, zIndex: 2000, fontSize: t.fontSize14 },
|
||
autocompleteWrap: { position: 'relative', width: '180px', display: 'inline-block' },
|
||
autocompletePanel: { position: 'absolute', left: 0, top: '100%', marginTop: '4px', backgroundColor: t.neutral1, borderRadius: t.radiusMedium, border: '1px solid ' + t.border, boxShadow: t.shadowMedium, zIndex: 100, minWidth: '100%', maxHeight: '200px', overflowY: 'auto' },
|
||
autocompleteOption: { padding: '8px 12px', fontSize: t.fontSize14, color: t.neutral8, cursor: 'pointer' },
|
||
autocompleteOptionHover: { backgroundColor: t.fill },
|
||
confirmCard: { display: 'flex', gap: t.spacing24, marginTop: t.spacing16 },
|
||
confirmPhoto: { flex: '0 0 300px', height: '200px', borderRadius: t.radiusMedium, overflow: 'hidden', backgroundColor: t.neutral3 },
|
||
confirmPhotoImg: { width: '100%', height: '100%', objectFit: 'cover' },
|
||
confirmForm: { flex: 1, display: 'flex', flexDirection: 'column', gap: t.spacing16 },
|
||
formLabel: { display: 'block', marginBottom: '6px', fontSize: t.fontSize14, color: t.neutral8 },
|
||
formInput: { padding: '8px 12px', height: '36px', borderRadius: t.radiusMedium, border: '1px solid ' + t.border, fontSize: t.fontSize14, width: '100%', boxSizing: 'border-box' },
|
||
photoViewModal: { maxWidth: '800px', textAlign: 'center' },
|
||
photoViewImg: { maxWidth: '100%', maxHeight: '70vh', borderRadius: t.radiusMedium },
|
||
modalCloseBtn: { position: 'absolute', right: t.spacing16, top: t.spacing16, width: '24px', height: '24px', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', borderRadius: t.radiusMedium, backgroundColor: 'transparent', border: 'none', color: t.neutral6, fontSize: '18px', lineHeight: '1', padding: 0 },
|
||
modalContent: { fontSize: t.fontSize14, color: t.neutral8, lineHeight: '1.6' },
|
||
requirementSection: { marginBottom: t.spacing16 },
|
||
requirementSectionTitle: { fontSize: t.fontSize16, fontWeight: 600, color: t.neutral8, marginBottom: t.spacing8 },
|
||
flowWrap: { marginTop: t.spacing8, marginBottom: t.spacing16 },
|
||
flowCol: { display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 0 },
|
||
flowArrow: { width: '2px', height: '20px', backgroundColor: t.neutral5 },
|
||
flowNodeOval: { padding: '8px 20px', borderRadius: '20px', border: '1px solid ' + t.neutral5, backgroundColor: t.neutral2, fontSize: t.fontSize14, color: t.neutral8 },
|
||
flowNodeRect: { padding: '8px 20px', border: '1px solid ' + t.neutral5, backgroundColor: t.neutral1, fontSize: t.fontSize14, color: t.neutral8 },
|
||
flowNodeDiamond: { padding: '10px 16px', border: '1px solid ' + t.neutral5, backgroundColor: t.fillSecondary, fontSize: t.fontSize14, color: t.neutral8, transform: 'rotate(0deg)', width: '140px', textAlign: 'center', boxSizing: 'border-box', clipPath: 'polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%)' },
|
||
flowNodeDiamondWrap: { padding: '8px 16px', border: '1px solid ' + t.neutral5, backgroundColor: t.fillSecondary, fontSize: t.fontSize14, color: t.neutral8, minWidth: '120px', textAlign: 'center' },
|
||
flowNodeToast: { padding: '8px 16px', borderRadius: '8px', border: '1px solid ' + t.neutral4, backgroundColor: t.neutral2, fontSize: t.fontSize14, color: t.neutral7 },
|
||
flowRow: { display: 'flex', alignItems: 'flex-start', justifyContent: 'center', gap: '24px', flexWrap: 'wrap' },
|
||
flowBranch: { display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 0 },
|
||
requirementItem: { marginBottom: t.spacing8, paddingLeft: t.spacing16 },
|
||
requirementSubItem: { marginBottom: t.spacing4, paddingLeft: t.spacing16, fontSize: t.fontSize14, color: t.neutral7 },
|
||
batchTaskCardHeader: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: t.spacing16 },
|
||
batchTaskTable: { width: '100%', borderCollapse: 'collapse', fontSize: t.fontSize14 },
|
||
batchTaskTh: { textAlign: 'left', padding: '10px 12px', borderBottom: '1px solid ' + t.neutral4, color: t.neutral7, fontWeight: 500 },
|
||
batchTaskTd: { padding: '10px 12px', borderBottom: '1px solid ' + t.neutral4, color: t.neutral8 },
|
||
progressWrap: { width: '120px', height: '8px', backgroundColor: t.neutral4, borderRadius: '4px', overflow: 'hidden' },
|
||
progressBar: { height: '100%', backgroundColor: t.primary, borderRadius: '4px', transition: 'width 0.2s' },
|
||
recognizeLink: { color: t.link, cursor: 'pointer', fontSize: t.fontSize14 },
|
||
dateRangeWrap: { position: 'relative', display: 'inline-block' },
|
||
dateRangeTrigger: { display: 'flex', alignItems: 'center', height: '32px', padding: '0 12px', border: '1px solid ' + t.border, borderRadius: '2px', backgroundColor: t.neutral1, cursor: 'pointer', minWidth: '280px', boxSizing: 'border-box' },
|
||
dateRangeTriggerFocused: { borderColor: t.primary, outline: 'none' },
|
||
dateRangeLabel: { display: 'flex', alignItems: 'center', gap: '6px', padding: '0 8px', height: '100%', fontSize: t.fontSize14, color: t.neutral8 },
|
||
dateRangeLabelActive: { backgroundColor: 'rgba(22,93,255,0.1)', color: t.primary, borderBottom: '2px solid ' + t.primary },
|
||
dateRangeLabelText: { whiteSpace: 'nowrap' },
|
||
dateRangeDash: { color: t.neutral5, margin: '0 4px', fontSize: t.fontSize14 },
|
||
dateRangeIcon: { marginLeft: 'auto', width: '16px', height: '16px', color: t.neutral6, flexShrink: 0 },
|
||
dateRangePanel: { position: 'absolute', left: 0, top: '100%', marginTop: '4px', backgroundColor: t.neutral1, borderRadius: t.radiusMedium, border: '1px solid ' + t.border, boxShadow: t.shadowMedium, zIndex: 100, padding: '16px', display: 'flex', gap: '24px' },
|
||
dateRangeCalendar: { width: '280px' },
|
||
dateRangeCalendarHeader: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '12px', padding: '0 4px' },
|
||
dateRangeCalendarTitle: { fontSize: t.fontSize14, fontWeight: 500, color: t.neutral8 },
|
||
dateRangeCalendarNav: { display: 'flex', alignItems: 'center', gap: '4px' },
|
||
dateRangeNavBtn: { width: '28px', height: '28px', display: 'flex', alignItems: 'center', justifyContent: 'center', border: 'none', backgroundColor: 'transparent', color: t.neutral6, cursor: 'pointer', borderRadius: t.radiusSmall },
|
||
dateRangeNavBtnHover: { color: t.primary, backgroundColor: t.fill },
|
||
dateRangeWeekRow: { display: 'flex', marginBottom: '4px' },
|
||
dateRangeWeekCell: { width: '36px', height: '28px', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '12px', color: t.neutral6 },
|
||
dateRangeDayRow: { display: 'flex' },
|
||
dateRangeDayCell: { width: '36px', height: '36px', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', fontSize: t.fontSize14, cursor: 'pointer', borderRadius: t.radiusSmall, color: t.neutral8 },
|
||
dateRangeDayCellOther: { color: t.neutral5 },
|
||
dateRangeDayCellSelected: { color: t.primary },
|
||
dateRangeDayCellInRange: { backgroundColor: 'rgba(22,93,255,0.08)', color: t.primary },
|
||
dateRangeDayDot: { width: '4px', height: '4px', borderRadius: '50%', backgroundColor: t.primary, marginTop: '2px' }
|
||
};
|
||
|
||
var renderFilterSelect = function (value, setValue, options, placeholder) {
|
||
var opts = (options || []).map(function (o) { return React.createElement(Option, { key: o, value: o }, o); });
|
||
return React.createElement(Select, {
|
||
placeholder: placeholder || '请选择或输入搜索',
|
||
style: { width: 180 },
|
||
value: value || undefined,
|
||
onChange: function (v) { setValue(v || ''); },
|
||
showSearch: true,
|
||
allowClear: true,
|
||
filterOption: function (input, opt) {
|
||
var c = opt && opt.children;
|
||
return c && String(c).toLowerCase().indexOf((input || '').toLowerCase()) >= 0;
|
||
}
|
||
}, opts);
|
||
};
|
||
|
||
return React.createElement(
|
||
'div',
|
||
{ style: styles.page },
|
||
React.createElement(
|
||
'div',
|
||
{ style: styles.breadcrumb },
|
||
React.createElement(
|
||
'div',
|
||
{ style: styles.breadcrumbLeft },
|
||
React.createElement('a', { href: '#', style: styles.breadcrumbLink, onClick: function (e) { e.preventDefault(); } }, '运维管理'),
|
||
React.createElement('span', { style: { marginRight: '8px' } }, '/'),
|
||
React.createElement('a', { href: '#', style: styles.breadcrumbLink, onClick: function (e) { e.preventDefault(); } }, '车辆业务'),
|
||
React.createElement('span', { style: { marginRight: '8px' } }, '/'),
|
||
React.createElement('span', { style: styles.breadcrumbCurrent }, '上牌管理')
|
||
),
|
||
React.createElement(
|
||
'div',
|
||
{ style: styles.breadcrumbRight },
|
||
React.createElement('a', { href: '#', style: styles.requirementLink, onClick: function (e) { e.preventDefault(); setShowRequirementModal(true); } }, '查看需求说明')
|
||
)
|
||
),
|
||
React.createElement(
|
||
'div',
|
||
{ style: styles.card },
|
||
React.createElement(
|
||
'div',
|
||
{ style: styles.filterRow },
|
||
React.createElement('span', { style: styles.label }, '上牌日期:'),
|
||
React.createElement(DatePicker, {
|
||
style: { width: 180 },
|
||
format: 'YYYY-MM-DD',
|
||
placeholder: '开始日期',
|
||
value: filterDateStart && window.moment ? window.moment(filterDateStart, 'YYYY-MM-DD') : null,
|
||
onChange: function (d, dateStr) { setFilterDateStart(dateStr || ''); }
|
||
}),
|
||
React.createElement('span', { style: { color: t.neutral6, margin: '0 4px' } }, '至'),
|
||
React.createElement(DatePicker, {
|
||
style: { width: 180 },
|
||
format: 'YYYY-MM-DD',
|
||
placeholder: '结束日期',
|
||
value: filterDateEnd && window.moment ? window.moment(filterDateEnd, 'YYYY-MM-DD') : null,
|
||
onChange: function (d, dateStr) { setFilterDateEnd(dateStr || ''); }
|
||
}),
|
||
React.createElement('span', { style: styles.label }, '操作人:'),
|
||
renderFilterSelect(filterOperator, setFilterOperator, allOperators, '请选择操作人'),
|
||
React.createElement('span', { style: styles.label }, '车牌号:'),
|
||
renderFilterSelect(filterPlateNo, setFilterPlateNo, allPlateNos, '请选择车牌号'),
|
||
React.createElement('span', { style: styles.label }, '车辆识别代码:'),
|
||
renderFilterSelect(filterVin, setFilterVin, allVins, '请选择车辆识别代码'),
|
||
React.createElement(
|
||
'div',
|
||
{ style: styles.filterRowRight },
|
||
React.createElement(Button, {
|
||
type: 'primary',
|
||
onClick: function () {
|
||
setAppliedDateStart(filterDateStart);
|
||
setAppliedDateEnd(filterDateEnd);
|
||
setAppliedOperator(filterOperator);
|
||
setAppliedPlateNo(filterPlateNo);
|
||
setAppliedVin(filterVin);
|
||
setCurrentPage(1);
|
||
message.success('查询成功');
|
||
}
|
||
}, '查询'),
|
||
React.createElement(Button, {
|
||
onClick: function () {
|
||
setFilterDateStart('');
|
||
setFilterDateEnd('');
|
||
setAppliedDateStart('');
|
||
setAppliedDateEnd('');
|
||
setFilterOperator('');
|
||
setFilterPlateNo('');
|
||
setFilterVin('');
|
||
setAppliedOperator('');
|
||
setAppliedPlateNo('');
|
||
setAppliedVin('');
|
||
setCurrentPage(1);
|
||
}
|
||
}, '重置')
|
||
)
|
||
)
|
||
),
|
||
React.createElement(
|
||
'div',
|
||
{ style: styles.card },
|
||
React.createElement(
|
||
'div',
|
||
{ style: styles.toolbar },
|
||
React.createElement('input', {
|
||
type: 'file',
|
||
ref: fileInputRef,
|
||
accept: 'image/*',
|
||
style: { display: 'none' },
|
||
onChange: function (e) { handleUpload(e, false); }
|
||
}),
|
||
React.createElement('input', {
|
||
type: 'file',
|
||
ref: batchFileInputRef,
|
||
accept: 'image/*',
|
||
multiple: true,
|
||
style: { display: 'none' },
|
||
onChange: function (e) { handleUpload(e, true); }
|
||
}),
|
||
React.createElement(Button, {
|
||
type: 'primary',
|
||
onClick: function () { if (fileInputRef.current) fileInputRef.current.click(); }
|
||
}, '新增'),
|
||
React.createElement(Button, {
|
||
onClick: function () { setBatchTaskCardVisible(true); }
|
||
}, '批量上传')
|
||
),
|
||
React.createElement(Table, {
|
||
rowKey: 'id',
|
||
size: 'small',
|
||
columns: [
|
||
{ title: '上牌日期', dataIndex: 'plateDate', key: 'plateDate', width: 120 },
|
||
{ title: '操作人', dataIndex: 'operator', key: 'operator', width: 100 },
|
||
{ title: '车牌号', dataIndex: 'plateNo', key: 'plateNo', width: 120 },
|
||
{ title: '车辆识别代码', dataIndex: 'vin', key: 'vin', width: 140 },
|
||
{ title: '车辆类型', dataIndex: 'vehicleType', key: 'vehicleType', width: 100 },
|
||
{ title: '品牌', dataIndex: 'brand', key: 'brand', width: 100 },
|
||
{ title: '型号', dataIndex: 'model', key: 'model', width: 120 },
|
||
{ title: '操作', key: 'action', width: 80, render: function (_, row) { return React.createElement(Button, { type: 'link', size: 'small', onClick: function () { setViewPhotoRecord(row); } }, '查看'); } }
|
||
],
|
||
dataSource: paginatedList,
|
||
pagination: {
|
||
current: validPage,
|
||
pageSize: pageSize,
|
||
total: totalItems,
|
||
showSizeChanger: true,
|
||
showQuickJumper: true,
|
||
pageSizeOptions: ['10', '20', '50', '100'],
|
||
showTotal: function (total) { return '共 ' + total + ' 条'; },
|
||
onChange: function (page, size) {
|
||
setCurrentPage(page);
|
||
if (size !== pageSize) setPageSize(size);
|
||
}
|
||
}
|
||
})
|
||
),
|
||
React.createElement(Modal, {
|
||
title: '识别中,请勿关闭页面',
|
||
visible: ocrModalVisible,
|
||
footer: null,
|
||
closable: false,
|
||
maskClosable: false,
|
||
children: React.createElement('div', { style: { padding: '24px 0', textAlign: 'center' } },
|
||
React.createElement(Spin, { size: 'large' }),
|
||
React.createElement('p', { style: { marginTop: 12, color: t.neutral6 } }, '正在识别行驶证信息...')
|
||
)
|
||
}),
|
||
React.createElement(Modal, {
|
||
title: isBatchMode && batchTotalCount > 1 ? '确认上牌信息(' + (batchTotalCount - batchConfirmList.length + 1) + '/' + batchTotalCount + ')' : '确认上牌信息',
|
||
visible: confirmModalVisible && !!confirmData,
|
||
onCancel: handleConfirmCancel,
|
||
onOk: handleConfirmSubmit,
|
||
okText: '确认',
|
||
cancelText: '取消',
|
||
width: 560,
|
||
children: confirmData ? React.createElement(
|
||
'div',
|
||
{ style: styles.confirmCard },
|
||
React.createElement('div', { style: styles.confirmPhoto },
|
||
React.createElement('img', { src: confirmData.photoUrl, alt: '行驶证', style: styles.confirmPhotoImg })
|
||
),
|
||
React.createElement('div', { style: styles.confirmForm },
|
||
React.createElement('div', { style: { marginBottom: 16 } },
|
||
React.createElement('label', { style: styles.formLabel }, '车辆识别代号'),
|
||
React.createElement(Input, {
|
||
style: { width: '100%' },
|
||
value: confirmVin,
|
||
onChange: function (e) { setConfirmVin(e.target.value); }
|
||
})
|
||
),
|
||
React.createElement('div', { style: { marginBottom: 16 } },
|
||
React.createElement('label', { style: styles.formLabel }, '车牌号'),
|
||
React.createElement(Input, {
|
||
style: { width: '100%' },
|
||
value: confirmPlateNo,
|
||
onChange: function (e) { setConfirmPlateNo(e.target.value); }
|
||
})
|
||
),
|
||
React.createElement('div', { style: { marginBottom: 16 } },
|
||
React.createElement('label', { style: styles.formLabel }, '强制报废日期'),
|
||
React.createElement(Input, {
|
||
style: { width: '100%' },
|
||
placeholder: 'YYYY-MM-DD',
|
||
value: confirmScrapDate,
|
||
onChange: function (e) { setConfirmScrapDate(e.target.value); }
|
||
})
|
||
),
|
||
React.createElement('div', null,
|
||
React.createElement('label', { style: styles.formLabel }, '检验有效期'),
|
||
React.createElement(Input, {
|
||
style: { width: '100%' },
|
||
placeholder: 'YYYY-MM',
|
||
value: confirmInspectionExpiry,
|
||
onChange: function (e) { setConfirmInspectionExpiry(e.target.value); }
|
||
})
|
||
)
|
||
)
|
||
) : null
|
||
}),
|
||
React.createElement(Modal, {
|
||
title: '行驶证照片',
|
||
visible: !!viewPhotoRecord,
|
||
footer: React.createElement(Button, { onClick: function () { setViewPhotoRecord(null); } }, '关闭'),
|
||
onCancel: function () { setViewPhotoRecord(null); },
|
||
width: 640,
|
||
children: viewPhotoRecord ? React.createElement('img', { src: viewPhotoRecord.photoUrl, alt: '行驶证', style: Object.assign({}, styles.photoViewImg, { width: '100%' }) }) : null
|
||
}),
|
||
React.createElement(Modal, {
|
||
title: '批量上牌任务',
|
||
visible: batchTaskCardVisible,
|
||
onCancel: function () { setBatchTaskCardVisible(false); },
|
||
footer: React.createElement(Button, { onClick: function () { setBatchTaskCardVisible(false); } }, '关闭'),
|
||
width: 560,
|
||
children: React.createElement(React.Fragment, null,
|
||
React.createElement('div', { style: Object.assign({}, styles.batchTaskCardHeader, { marginBottom: 16 }) },
|
||
React.createElement(Button, {
|
||
type: 'primary',
|
||
onClick: function () {
|
||
batchUploadFromCardRef.current = true;
|
||
if (batchFileInputRef.current) batchFileInputRef.current.click();
|
||
}
|
||
}, '批量上传')
|
||
),
|
||
React.createElement(Table, {
|
||
rowKey: 'id',
|
||
size: 'small',
|
||
columns: [
|
||
{ title: '任务时间', dataIndex: 'createTime', key: 'createTime', width: 160 },
|
||
{ title: '照片数量', dataIndex: 'photoCount', key: 'photoCount', width: 100, render: function (c) { return c + ' 张'; } },
|
||
{ title: '完成进度', key: 'progress', width: 160, render: function (_, task) {
|
||
return React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 8 } },
|
||
React.createElement('div', { style: styles.progressWrap },
|
||
React.createElement('div', { style: Object.assign({}, styles.progressBar, { width: (task.progress || 0) + '%' }) })
|
||
),
|
||
React.createElement('span', { style: { fontSize: t.fontSize14, color: t.neutral7, minWidth: 36 } }, (task.progress || 0) + '%')
|
||
);
|
||
} },
|
||
{ title: '操作', key: 'action', width: 80, render: function (_, task) {
|
||
return task.progress === 100 && task.items && task.items.length > 0
|
||
? React.createElement(Button, { type: 'link', size: 'small', onClick: function () {
|
||
setBatchConfirmList(task.items);
|
||
setBatchConfirmIndex(0);
|
||
setBatchTotalCount(task.items.length);
|
||
setConfirmData(task.items[0]);
|
||
setConfirmVin(task.items[0].vin);
|
||
setConfirmPlateNo(task.items[0].plateNo);
|
||
setConfirmScrapDate(getSampleScrapDate());
|
||
setConfirmInspectionExpiry(getSampleInspectionExpiry());
|
||
setConfirmModalVisible(true);
|
||
setIsBatchMode(true);
|
||
setBatchTaskCardVisible(false);
|
||
} }, '识别')
|
||
: React.createElement('span', { style: { color: t.neutral5, fontSize: t.fontSize14 } }, '-');
|
||
} }
|
||
],
|
||
dataSource: batchTaskList.slice(0, 5),
|
||
pagination: false
|
||
})
|
||
)
|
||
}),
|
||
React.createElement(Modal, {
|
||
title: '需求说明',
|
||
visible: showRequirementModal,
|
||
onCancel: function () { setShowRequirementModal(false); },
|
||
footer: React.createElement(Button, { onClick: function () { setShowRequirementModal(false); } }, '关闭'),
|
||
width: 720,
|
||
children: React.createElement('div', { style: styles.modalContent },
|
||
React.createElement('div', { style: Object.assign({}, styles.requirementSection, { marginBottom: t.spacing24 }) },
|
||
React.createElement('div', { style: Object.assign({}, styles.requirementSectionTitle, { fontSize: '18px', marginBottom: t.spacing12 }) }, '上牌管理'),
|
||
React.createElement('div', { style: Object.assign({}, styles.requirementItem, { marginTop: 0, color: t.neutral7 }) }, '用以识别行驶证正反面,识别车架号、车牌号、强制报废日期(YYYY-MM-DD)、检验有效期(YYYY-MM)')
|
||
),
|
||
React.createElement('div', { style: styles.requirementSection },
|
||
React.createElement('div', { style: styles.requirementSectionTitle }, '1.面包屑:'),
|
||
React.createElement('div', { style: styles.requirementItem }, '运维管理-车辆业务-上牌管理')
|
||
),
|
||
React.createElement('div', { style: styles.requirementSection },
|
||
React.createElement('div', { style: styles.requirementSectionTitle }, '2.筛选:'),
|
||
React.createElement('div', { style: styles.requirementSubItem }, '2.1.上牌日期:双日历日期选择器,支持选择开始-结束时间,支持手动修改日期,但检验格式及判断结束日期不得早于开始日期;'),
|
||
React.createElement('div', { style: styles.requirementSubItem }, '2.2.操作人:选择器,支持从输入框输入内容模糊搜索,默认提示内容为:请选择操作人;'),
|
||
React.createElement('div', { style: styles.requirementSubItem }, '2.3.车牌号:选择器,支持从输入框输入内容模糊搜索,默认提示内容为:请选择车牌号;'),
|
||
React.createElement('div', { style: styles.requirementSubItem }, '2.4.车辆识别代码:选择器,支持从输入框输入内容模糊搜索,默认提示内容为:请选择车辆识别代码;')
|
||
),
|
||
React.createElement('div', { style: styles.requirementSection },
|
||
React.createElement('div', { style: styles.requirementSectionTitle }, '3.列表:'),
|
||
React.createElement('div', { style: styles.requirementItem }, '列表右侧按钮为新增、批量上传,字段依次为上牌日期、操作人、车牌号、车辆识别代码、车辆类型、品牌、型号、操作;'),
|
||
React.createElement('div', { style: styles.requirementSubItem }, '3.1.上牌日期:车辆上牌操作完成日期,格式为YYYY-MM-DD'),
|
||
React.createElement('div', { style: styles.requirementSubItem }, '3.2.操作人:车辆上牌记录操作用户姓名;'),
|
||
React.createElement('div', { style: styles.requirementSubItem }, '3.3.车牌号:显示上牌车牌号;通过新增按钮上传行驶证照片后,通过OCR识别技术,自动识别出该车辆识别代号对应车牌号,确认无误提交后自动反写'),
|
||
React.createElement('div', { style: styles.requirementSubItem }, '3.4.车辆识别代码:显示上牌车辆车辆识别代码;'),
|
||
React.createElement('div', { style: styles.requirementSubItem }, '3.5.车辆类型:显示该车辆识别代码对应车辆类型;'),
|
||
React.createElement('div', { style: styles.requirementSubItem }, '3.6.品牌:显示该车辆识别代码对应品牌;'),
|
||
React.createElement('div', { style: styles.requirementSubItem }, '3.7.型号:显示该车辆识别代码对应型号;'),
|
||
React.createElement('div', { style: styles.requirementSubItem }, '3.8.操作:行驶证,点击放大预览行驶证照片;'),
|
||
React.createElement('div', { style: styles.requirementItem }, '下方增加分页功能,支持选择单页数据条数;')
|
||
),
|
||
React.createElement('div', { style: styles.requirementSection },
|
||
React.createElement('div', { style: styles.requirementSectionTitle }, '4.新增:'),
|
||
React.createElement('div', { style: styles.requirementSubItem }, '4.1.点击新增按钮,上传行驶证照片附件,上传后OCR识别过程中弹出卡片提示:识别中,请勿关闭页面;如果照片识别失败,则提示:识别失败,请重新尝试;'),
|
||
React.createElement('div', { style: styles.requirementSubItem }, '4.2.上传成功后确认卡片中显示照片、车辆识别代码、车牌号、强制报废日期、检验有效期,可通过二次编辑进行校正;'),
|
||
React.createElement('div', { style: styles.requirementSubItem }, '4.3.点击卡片页面底部"确认"按钮,确认根据车辆识别代码判断是否存在该车辆,如果是则toast提示"上牌成功",并在列表中生成操作,如果否则toast提示:该车辆不存在。')
|
||
),
|
||
React.createElement('div', { style: styles.requirementSection },
|
||
React.createElement('div', { style: styles.requirementSectionTitle }, '5.批量上传:'),
|
||
React.createElement('div', { style: styles.requirementItem }, '5.1.点击批量上牌按钮,弹出批量上牌任务卡片,再点击右上角上传车牌,上传多张行驶证照片附件,上传后弹出批量上牌任务卡片:卡片中记录最近5条批量上牌任务,任务字段为任务时间、照片数量、识别错误、完成进度、操作;'),
|
||
React.createElement('div', { style: styles.requirementSubItem }, '5.1.1.任务时间:上传批量照片的时间,精确至分钟,格式为YYYY-MM-DD HH:MM;'),
|
||
React.createElement('div', { style: styles.requirementSubItem }, '5.1.2.照片数量:显示这一批照片总数;'),
|
||
React.createElement('div', { style: styles.requirementSubItem }, '5.1.3.识别错误:显示识别失败的照片总数,hover时气泡卡片显示识别失败的照片名称,以;分隔;'),
|
||
React.createElement('div', { style: styles.requirementSubItem }, '5.1.4.完成进度:显示ocr识别进度条和已完成百分比;'),
|
||
React.createElement('div', { style: styles.requirementSubItem }, '5.1.5.操作:已完成任务操作栏显示识别,未完成任务操作栏显示-;'),
|
||
React.createElement('div', { style: styles.requirementItem }, '5.2.识别:点击识别确认卡片中当前张数、显示照片、车辆识别代码、车牌号、强制报废日期、检验有效期,可通过二次编辑进行校正;当前张数显示在确认上牌信息标题右侧,格式为(当前/总计),依次操作直到完成所有记录提交完成,全部完成后toast提示:批量上传成功;'),
|
||
React.createElement('div', { style: styles.requirementItem }, '5.3.在识别确认卡片中点击确认后将立刻上传该照片,可再次通过点击批量上传拉取上传任务框的方式,自动跳转至最后一条上传记录进行操作;'),
|
||
React.createElement('div', { style: styles.requirementItem }, '5.4.批量上传任务中照片全部识别完成后,不再显示识别按钮;'),
|
||
React.createElement('div', { style: styles.requirementItem }, '5.5.具体识别流程请参考axure菜单目录中上牌管理下的流程图;')
|
||
)
|
||
)
|
||
})
|
||
);
|
||
};
|
||
if (typeof window !== 'undefined') {
|
||
window.Component = Component;
|
||
function mount() {
|
||
var rootEl = document.getElementById('root');
|
||
if (rootEl && window.ReactDOM && window.React) {
|
||
var root = ReactDOM.createRoot(rootEl);
|
||
root.render(React.createElement(Component));
|
||
}
|
||
}
|
||
if (document.readyState === 'loading') {
|
||
document.addEventListener('DOMContentLoaded', mount);
|
||
} else {
|
||
setTimeout(mount, 0);
|
||
}
|
||
}
|