@@ -1593,17 +1593,40 @@ export default {
|
|||||||
const fullNation = `${nation}族`;
|
const fullNation = `${nation}族`;
|
||||||
return this.nationOptions.includes(fullNation) ? fullNation : nation;
|
return this.nationOptions.includes(fullNation) ? fullNation : nation;
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* OCR / 手工录入日期归一化:对齐车辆侧与后端 FlexibleLocalDateDeserializer。
|
||||||
|
* 支持 yyyyMMdd、yyyy-MM-dd、2018.3.9、2030年05月20日及任意非数字分隔;无法识别返回空串。
|
||||||
|
*/
|
||||||
normalizeBirthday(value = '') {
|
normalizeBirthday(value = '') {
|
||||||
const birthday = String(value || '').trim();
|
const birthday = String(value || '').trim();
|
||||||
const compactMatch = birthday.match(/^(\d{4})(\d{2})(\d{2})$/);
|
if (!birthday) return '';
|
||||||
if (compactMatch) {
|
if (/长期|永久/.test(birthday)) return '';
|
||||||
const [, year, month, day] = compactMatch;
|
const looseMatch = birthday.match(/(\d{4})\D+(\d{1,2})\D+(\d{1,2})/);
|
||||||
return `${year}-${month}-${day}`;
|
if (looseMatch) {
|
||||||
|
return this.toValidDateText(looseMatch[1], looseMatch[2], looseMatch[3]);
|
||||||
}
|
}
|
||||||
const match = birthday.match(/^(\d{4})[-/.年](\d{1,2})[-/.月](\d{1,2})日?$/);
|
const compact = birthday.replace(/\D/g, '');
|
||||||
if (!match) return birthday;
|
if (compact.length === 8) {
|
||||||
const [, year, month, day] = match;
|
return this.toValidDateText(compact.slice(0, 4), compact.slice(4, 6), compact.slice(6, 8));
|
||||||
return `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}`;
|
}
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
toValidDateText(yearText, monthText, dayText) {
|
||||||
|
const year = Number(yearText);
|
||||||
|
const month = Number(monthText);
|
||||||
|
const day = Number(dayText);
|
||||||
|
if (!Number.isInteger(year) || !Number.isInteger(month) || !Number.isInteger(day)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
const date = new Date(year, month - 1, day);
|
||||||
|
if (
|
||||||
|
date.getFullYear() !== year ||
|
||||||
|
date.getMonth() !== month - 1 ||
|
||||||
|
date.getDate() !== day
|
||||||
|
) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return `${String(year).padStart(4, '0')}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
|
||||||
},
|
},
|
||||||
parseIdCardInfo(idCardNo = '') {
|
parseIdCardInfo(idCardNo = '') {
|
||||||
if (!/^\d{17}[\dX]$/.test(idCardNo)) {
|
if (!/^\d{17}[\dX]$/.test(idCardNo)) {
|
||||||
|
|||||||
@@ -1174,37 +1174,59 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* OCR 日期常为区间(如 2022-08-17至2024-01-05)或含无效日(如 01-65)。
|
* OCR 日期常为区间(如 2022-08-17至2024-01-05)、无分隔符(如 20260317)、
|
||||||
* 提取可解析的合法日期;prefer=first 取登记类起始日,prefer=last 取有效期截止日。
|
* 年月日/点分(2030年05月20日、2018.3.9)或任意非数字分隔。
|
||||||
|
* 对齐司机侧 normalizeBirthday / 后端 OcrFieldSupport:年与月、月与日之间允许任意非数字。
|
||||||
|
* prefer=first 取登记类起始日,prefer=last 取有效期截止日。
|
||||||
|
* 返回值统一为 YYYY-MM-DD,供 el-date-picker 展示与后端 LocalDate 反序列化。
|
||||||
*/
|
*/
|
||||||
normalizeDate(value = '', prefer = 'first') {
|
normalizeDate(value = '', prefer = 'first') {
|
||||||
const dateValue = String(value || '').trim();
|
const dateValue = String(value || '').trim();
|
||||||
if (!dateValue) return '';
|
if (!dateValue) return '';
|
||||||
const segments = dateValue.match(/\d{4}[-/.年]\d{1,2}[-/.月]\d{1,2}日?/g) || [];
|
if (/长期|永久/.test(dateValue)) return '';
|
||||||
const sourceList = segments.length ? segments : [dateValue];
|
const candidates = [];
|
||||||
const candidates = sourceList
|
const loosePattern = /(\d{4})\D+(\d{1,2})\D+(\d{1,2})/g;
|
||||||
.map(item => {
|
let match = loosePattern.exec(dateValue);
|
||||||
const match = String(item)
|
while (match) {
|
||||||
.trim()
|
const normalized = this.toValidDateText(match[1], match[2], match[3]);
|
||||||
.match(/^(\d{4})[-/.年](\d{1,2})[-/.月](\d{1,2})日?$/);
|
if (normalized) {
|
||||||
if (!match) return '';
|
candidates.push(normalized);
|
||||||
const year = Number(match[1]);
|
}
|
||||||
const month = Number(match[2]);
|
match = loosePattern.exec(dateValue);
|
||||||
const day = Number(match[3]);
|
}
|
||||||
const date = new Date(year, month - 1, day);
|
if (!candidates.length) {
|
||||||
if (
|
const compact = dateValue.replace(/\D/g, '');
|
||||||
date.getFullYear() !== year ||
|
if (compact.length === 8) {
|
||||||
date.getMonth() !== month - 1 ||
|
const normalized = this.toValidDateText(
|
||||||
date.getDate() !== day
|
compact.slice(0, 4),
|
||||||
) {
|
compact.slice(4, 6),
|
||||||
return '';
|
compact.slice(6, 8)
|
||||||
|
);
|
||||||
|
if (normalized) {
|
||||||
|
candidates.push(normalized);
|
||||||
}
|
}
|
||||||
return `${String(year).padStart(4, '0')}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
|
}
|
||||||
})
|
}
|
||||||
.filter(Boolean);
|
|
||||||
if (!candidates.length) return '';
|
if (!candidates.length) return '';
|
||||||
return prefer === 'last' ? candidates[candidates.length - 1] : candidates[0];
|
return prefer === 'last' ? candidates[candidates.length - 1] : candidates[0];
|
||||||
},
|
},
|
||||||
|
toValidDateText(yearText, monthText, dayText) {
|
||||||
|
const year = Number(yearText);
|
||||||
|
const month = Number(monthText);
|
||||||
|
const day = Number(dayText);
|
||||||
|
if (!Number.isInteger(year) || !Number.isInteger(month) || !Number.isInteger(day)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
const date = new Date(year, month - 1, day);
|
||||||
|
if (
|
||||||
|
date.getFullYear() !== year ||
|
||||||
|
date.getMonth() !== month - 1 ||
|
||||||
|
date.getDate() !== day
|
||||||
|
) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return `${String(year).padStart(4, '0')}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
|
||||||
|
},
|
||||||
normalizeVehicleDateFields(form = {}) {
|
normalizeVehicleDateFields(form = {}) {
|
||||||
const dateFields = [
|
const dateFields = [
|
||||||
['compulsoryScrapDate', 'first'],
|
['compulsoryScrapDate', 'first'],
|
||||||
@@ -1216,8 +1238,13 @@ export default {
|
|||||||
['registrationDate', 'first'],
|
['registrationDate', 'first'],
|
||||||
];
|
];
|
||||||
dateFields.forEach(([prop, prefer]) => {
|
dateFields.forEach(([prop, prefer]) => {
|
||||||
if (form[prop] === undefined || form[prop] === null || form[prop] === '') return;
|
if (form[prop] === undefined || form[prop] === null || form[prop] === '') {
|
||||||
form[prop] = this.normalizeDate(form[prop], prefer);
|
form[prop] = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const normalized = this.normalizeDate(form[prop], prefer);
|
||||||
|
// 无法识别或空串统一置 null,避免把 "" / "20260317" 原样提交给 LocalDate
|
||||||
|
form[prop] = normalized || null;
|
||||||
});
|
});
|
||||||
return form;
|
return form;
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user