diff --git a/src/api/transportCapacity/driver.js b/src/api/transportCapacity/driver.js index bbab4f1..d95d82d 100644 --- a/src/api/transportCapacity/driver.js +++ b/src/api/transportCapacity/driver.js @@ -91,3 +91,14 @@ export const recognizeBaiduOcr = (imageUrl, type, side = '') => { }, }); }; + +export const recognizeQualificationCertificateOcr = imageUrl => { + return request({ + url: '/blade-transport/baidu-ocr/qualification-certificate', + method: 'post', + timeout: 60000, + params: { + imageUrl, + }, + }); +}; diff --git a/src/views/transportCapacity/driver.vue b/src/views/transportCapacity/driver.vue index c694ff3..ab82766 100644 --- a/src/views/transportCapacity/driver.vue +++ b/src/views/transportCapacity/driver.vue @@ -689,6 +689,7 @@ import { recognitionIDCard, recognitionTransportCertificates, recognizeBaiduOcr, + recognizeQualificationCertificateOcr, } from '@/api/transportCapacity/driver'; import { getList as getVehicleList } from '@/api/transportCapacity/transport-vehicle'; import { getDeptTree } from '@/api/system/dept'; @@ -1322,9 +1323,29 @@ export default { }, handleQualificationUploadSuccess(prop, url) { this.setImage(prop, url); - this.recognizeBaiduOcr(url, 'general', '', '从业资格证', data => { - this.applyQualificationRecognition(data); + this.recognizeQualificationCertificate(url); + }, + recognizeQualificationCertificate(url) { + if (!url) { + this.$message.warning('从业资格证图片上传成功,未获取到图片地址,无法自动识别'); + return; + } + const loading = ElLoading.service({ + lock: true, + text: '从业资格证识别中', + background: 'rgba(255, 255, 255, 0.7)', }); + recognizeQualificationCertificateOcr(url) + .then(res => { + this.applyQualificationRecognition(res?.data?.data || {}); + this.$message.success('从业资格证识别完成'); + }) + .catch(() => { + this.$message.warning('从业资格证图片上传成功,自动识别失败,请手动填写相关信息'); + }) + .finally(() => { + loading.close(); + }); }, recognizeBaiduOcr(url, type, side, documentName, applyRecognition) { if (!url) { @@ -1614,25 +1635,43 @@ export default { return typeof value === 'object' ? value.words || value.value || '' : value || ''; }, applyQualificationRecognition(data = {}) { - const qualificationType = this.getQualificationType(data); - const qualificationNo = this.getQualificationNo(data); + const fields = this.normalizeQualificationOcrFields(data); + const qualificationType = this.getQualificationOcrValue(fields, [ + 'qualification_category', + '从业资格类别', + '从业资格类型', + ]).replace(/[,,;;]+$/, ''); + const qualificationNo = this.getQualificationOcrValue(fields, [ + 'certificate_no', + '证号', + '从业资格证号', + '资格证号', + '证书编号', + ]); + const validFrom = this.getQualificationOcrValue(fields, ['valid_from', '有效起始日期']); + const validUntil = this.getQualificationOcrValue(fields, ['valid_until', '有效期限', '有效期']); const matchedType = this.matchQualificationType(qualificationType); if (matchedType) { this.driverForm.qualificationType = matchedType; } else if (qualificationType && !this.qualificationTypeOptions.length) { this.driverForm.qualificationType = qualificationType; } - if (qualificationNo && !this.driverForm.qualificationNo) { + if (qualificationNo) { this.driverForm.qualificationNo = String(qualificationNo).replace(/\s/g, ''); } - const words = this.getBaiduOcrWords(data).join(' '); - const dateList = words.match(/\d{4}[-/.年]\d{1,2}[-/.月]\d{1,2}日?/g) || []; - if (/(长期|永久有效)/.test(words)) { + const startDate = this.normalizeBirthday(validFrom); + if (startDate) { + this.driverForm.qualificationStartDate = startDate; + } + if (/(长期|永久)/.test(validUntil)) { this.driverForm.qualificationLongTerm = 1; this.driverForm.qualificationEndDate = ''; - } else if (dateList.length) { - this.driverForm.qualificationEndDate = this.normalizeBirthday(dateList[dateList.length - 1]); - this.driverForm.qualificationLongTerm = 0; + } else { + const endDate = this.normalizeBirthday(validUntil); + if (endDate) { + this.driverForm.qualificationEndDate = endDate; + this.driverForm.qualificationLongTerm = 0; + } } this.$nextTick(() => { ['qualificationType', 'qualificationNo', 'qualificationEndDate'].forEach(prop => { @@ -1640,22 +1679,25 @@ export default { }); }); }, - getQualificationType(data = {}) { - const fieldValue = this.getOcrValue(data, ['从业资格类别', '从业资格类型']); - if (fieldValue) return String(fieldValue).trim(); - const words = this.getBaiduOcrWords(data); - const labelIndex = words.findIndex(word => /从业资格类别|从业资格类型/.test(word)); - if (labelIndex < 0) return ''; - const firstValue = words[labelIndex].replace(/^.*?(?:从业资格类别|从业资格类型)\s*[::]?/, '').trim(); - const values = firstValue ? [firstValue] : []; - for (let index = labelIndex + 1; index < words.length; index += 1) { - const word = String(words[index] || '').trim(); - if (!word || /^(有效起始日期|有效期限|核发机关|继续教育信息|诚信考核信息)/.test(word)) { - break; - } - values.push(word); + normalizeQualificationOcrFields(result = {}) { + if (result.fields && typeof result.fields === 'object' && !Array.isArray(result.fields)) { + return result.fields; } - return values.join('').replace(/[,,;;]+$/, '').trim(); + const keyInfos = result.key_info || result.keyInfo || result.keyInfos || []; + if (!Array.isArray(keyInfos)) return {}; + return Object.fromEntries( + keyInfos + .filter(item => item && item.key) + .map(item => [String(item.key).trim(), String(item.value ?? '').trim()]) + .filter(([, value]) => value) + ); + }, + getQualificationOcrValue(fields = {}, keys = []) { + const normalizedKeys = keys.map(key => String(key).toLowerCase()); + const entry = Object.entries(fields).find(([key]) => + normalizedKeys.includes(String(key).toLowerCase()) + ); + return entry ? String(entry[1] || '').trim() : ''; }, matchQualificationType(value = '') { const text = String(value || '').replace(/\s/g, ''); @@ -1673,27 +1715,6 @@ export default { ); return matched?.value || ''; }, - getQualificationNo(data = {}) { - const fieldValue = this.getOcrValue(data, ['从业资格证号', '资格证号', '证书编号']); - if (fieldValue) return fieldValue; - const words = this.getBaiduOcrWords(data); - const labelIndex = words.findIndex(word => /^(?:(?:从业)?资格证号?|证书编号)[::]?$/.test(word)); - if (labelIndex >= 0 && words[labelIndex + 1]) { - return words[labelIndex + 1]; - } - const certificateLine = words.find(word => /(?:从业)?资格证号?|证书编号/.test(word)); - const match = certificateLine?.match(/(?:(?:从业)?资格证号?|证书编号)\s*[::]?\s*([A-Z0-9-]{6,})/i); - return match?.[1] || ''; - }, - getBaiduOcrWords(data = {}) { - const wordsResult = data.words_result || data.wordsResult || {}; - if (Array.isArray(wordsResult)) { - return wordsResult.map(item => item.words || item.value || '').filter(Boolean); - } - return Object.values(wordsResult) - .map(item => (typeof item === 'object' ? item.words || item.value || '' : item || '')) - .filter(Boolean); - }, normalizeNation(value = '') { const nation = String(value || '').trim(); if (!nation) return '';