1、新增结算模块
2、调整业务模块 3、调整客商模块
This commit is contained in:
@@ -500,7 +500,7 @@
|
||||
:headers="uploadHeaders"
|
||||
large
|
||||
class-prefix="ship"
|
||||
@success="url => setImage('ownershipCertImage', url)"
|
||||
@success="url => handleShipCertificateUploadSuccess('ownershipCertImage', url)"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
@@ -512,7 +512,7 @@
|
||||
:headers="uploadHeaders"
|
||||
large
|
||||
class-prefix="ship"
|
||||
@success="url => setImage('safetyCertImage', url)"
|
||||
@success="url => handleShipCertificateUploadSuccess('safetyCertImage', url)"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
@@ -524,7 +524,7 @@
|
||||
:headers="uploadHeaders"
|
||||
large
|
||||
class-prefix="ship"
|
||||
@success="url => setImage('nationalityCertImage', url)"
|
||||
@success="url => handleShipCertificateUploadSuccess('nationalityCertImage', url)"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
@@ -536,7 +536,7 @@
|
||||
:headers="uploadHeaders"
|
||||
large
|
||||
class-prefix="ship"
|
||||
@success="url => setImage('safeManningCertImage', url)"
|
||||
@success="url => handleShipCertificateUploadSuccess('safeManningCertImage', url)"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
@@ -551,7 +551,7 @@
|
||||
:headers="uploadHeaders"
|
||||
large
|
||||
class-prefix="ship"
|
||||
@success="url => setImage('leaseContractImage', url)"
|
||||
@success="url => handleShipCertificateUploadSuccess('leaseContractImage', url)"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
@@ -563,7 +563,7 @@
|
||||
:headers="uploadHeaders"
|
||||
large
|
||||
class-prefix="ship"
|
||||
@success="url => setImage('businessTransportCertImage', url)"
|
||||
@success="url => handleShipCertificateUploadSuccess('businessTransportCertImage', url)"
|
||||
/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -582,6 +582,7 @@
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import NProgress from 'nprogress';
|
||||
import { ElLoading } from 'element-plus';
|
||||
import { InfoFilled } from '@element-plus/icons-vue';
|
||||
import { option } from '@/option/transportCapacity/transport-ship';
|
||||
import { getDeptTree } from '@/api/system/dept';
|
||||
@@ -592,6 +593,7 @@ import {
|
||||
remove,
|
||||
changeStatus,
|
||||
getExpiryStat,
|
||||
recognizeBaiduOcr,
|
||||
} from '@/api/transportCapacity/transport-ship';
|
||||
import { exportBlob } from '@/api/common';
|
||||
import { getToken } from '@/utils/auth';
|
||||
@@ -893,6 +895,155 @@ export default {
|
||||
this.shipForm[prop] = url;
|
||||
this.$refs.shipForm?.validateField(prop);
|
||||
},
|
||||
handleShipCertificateUploadSuccess(prop, url) {
|
||||
this.setImage(prop, url);
|
||||
const documentNameMap = {
|
||||
ownershipCertImage: '船舶所有权证书',
|
||||
safetyCertImage: '内河船舶安全与环保证书',
|
||||
nationalityCertImage: '船舶国籍证书',
|
||||
safeManningCertImage: '内河船舶最低安全配员证书',
|
||||
leaseContractImage: '光船租赁登记证书',
|
||||
businessTransportCertImage: '船舶营业运输证',
|
||||
};
|
||||
this.recognizeBaiduOcr(url, documentNameMap[prop], data => {
|
||||
this.applyShipCertificateRecognition(prop, data);
|
||||
});
|
||||
},
|
||||
recognizeBaiduOcr(url, documentName, applyRecognition) {
|
||||
if (!url) {
|
||||
this.$message.warning(`${documentName}图片上传成功,未获取到图片地址,无法自动识别`);
|
||||
return;
|
||||
}
|
||||
const loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: `${documentName}识别中`,
|
||||
background: 'rgba(255, 255, 255, 0.7)',
|
||||
});
|
||||
recognizeBaiduOcr(url, 'general')
|
||||
.then(res => {
|
||||
applyRecognition(res.data.data?.result || {});
|
||||
this.$message.success(`${documentName}识别完成`);
|
||||
})
|
||||
.catch(() => {
|
||||
this.$message.warning(`${documentName}图片上传成功,自动识别失败,请手动填写证书信息`);
|
||||
})
|
||||
.finally(() => {
|
||||
loading.close();
|
||||
});
|
||||
},
|
||||
applyShipCertificateRecognition(prop, data = {}) {
|
||||
const words = this.getBaiduOcrWords(data);
|
||||
switch (prop) {
|
||||
case 'ownershipCertImage':
|
||||
this.fillShipCertificateText(words, 'ownershipRegistrationNo', ['登记号码', '登记号']);
|
||||
this.fillShipCertificateText(words, 'initialRegistrationNo', ['初次登记号码', '初始登记号码']);
|
||||
this.fillShipCertificateText(words, 'shipOwner', ['船舶所有人', '所有人']);
|
||||
this.fillShipCertificateText(words, 'shipIdentifierNo', ['船舶识别号', '船舶识别号码']);
|
||||
this.fillShipCertificateDate(words, 'ownershipAcquisitionDate', ['取得所有权日期', '取得日期']);
|
||||
break;
|
||||
case 'safetyCertImage':
|
||||
this.fillShipCertificateNumber(words, 'grossTonnage', ['总吨', '总吨位']);
|
||||
this.fillShipCertificateNumber(words, 'netTonnage', ['净吨', '净吨位']);
|
||||
this.fillShipCertificateText(words, 'shipInspectionNo', ['船检登记号', '船检证书号']);
|
||||
this.fillShipCertificateText(words, 'shipType', ['船舶类型']);
|
||||
break;
|
||||
case 'nationalityCertImage':
|
||||
this.fillShipCertificateDateRange(
|
||||
words,
|
||||
'nationalityCertStartDate',
|
||||
'nationalityCertEndDate',
|
||||
'nationalityCertLongTerm'
|
||||
);
|
||||
break;
|
||||
case 'safeManningCertImage':
|
||||
this.fillShipCertificateDateRange(
|
||||
words,
|
||||
'safeManningCertStartDate',
|
||||
'safeManningCertEndDate',
|
||||
'safeManningCertLongTerm'
|
||||
);
|
||||
break;
|
||||
case 'leaseContractImage':
|
||||
this.fillShipCertificateDate(words, 'leaseStartDate', ['起租日期', '租赁开始日期']);
|
||||
this.fillShipCertificateDate(words, 'leaseEndDate', ['终止日期', '租赁终止日期']);
|
||||
this.fillShipCertificateText(words, 'shipLessee', ['船舶承租人', '承租人']);
|
||||
break;
|
||||
case 'businessTransportCertImage':
|
||||
this.fillShipCertificateText(words, 'businessTransportCertNo', ['证书编号', '运输证号']);
|
||||
this.fillShipCertificateDate(words, 'businessTransportCertIssueDate', ['发证日期']);
|
||||
this.fillShipCertificateDate(words, 'businessTransportCertEndDate', ['有效期至', '有效期限']);
|
||||
this.fillShipCertificateText(words, 'shipOperator', ['船舶经营人', '经营人']);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
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.entries(wordsResult)
|
||||
.flatMap(([key, value]) => [key, typeof value === 'object' ? value.words || value.value || '' : value])
|
||||
.filter(Boolean);
|
||||
},
|
||||
getShipCertificateOcrValue(words = [], labels = []) {
|
||||
const normalizedWords = words.map(word => String(word || '').trim()).filter(Boolean);
|
||||
for (const label of labels) {
|
||||
const labelIndex = normalizedWords.findIndex(word =>
|
||||
new RegExp(`^${label}\\s*[::]?$`).test(word)
|
||||
);
|
||||
if (labelIndex >= 0 && normalizedWords[labelIndex + 1]) {
|
||||
return normalizedWords[labelIndex + 1];
|
||||
}
|
||||
const valueLine = normalizedWords.find(word =>
|
||||
new RegExp(`${label}\\s*[::]?\\s*(.+)$`).test(word)
|
||||
);
|
||||
if (valueLine) {
|
||||
return valueLine.replace(new RegExp(`^.*${label}\\s*[::]?\\s*`), '').trim();
|
||||
}
|
||||
}
|
||||
return '';
|
||||
},
|
||||
fillShipCertificateText(words, prop, labels) {
|
||||
const value = this.getShipCertificateOcrValue(words, labels);
|
||||
if (value) this.shipForm[prop] = value.replace(/\s/g, '');
|
||||
},
|
||||
fillShipCertificateNumber(words, prop, labels) {
|
||||
const value = this.getShipCertificateOcrValue(words, labels);
|
||||
const number = Number(String(value || '').replace(/[^\d.]/g, ''));
|
||||
if (!Number.isNaN(number) && value) this.shipForm[prop] = number;
|
||||
},
|
||||
fillShipCertificateDate(words, prop, labels) {
|
||||
const value = this.getShipCertificateOcrValue(words, labels);
|
||||
const date = this.getShipCertificateDates(value)[0];
|
||||
if (date) this.shipForm[prop] = date;
|
||||
},
|
||||
fillShipCertificateDateRange(words, startProp, endProp, longTermProp) {
|
||||
const text =
|
||||
this.getShipCertificateOcrValue(words, ['证书有效期', '有效期限', '有效期至', '有效期']) ||
|
||||
words.join(' ');
|
||||
if (/(长期|永久)/.test(text)) {
|
||||
this.shipForm[longTermProp] = 1;
|
||||
this.shipForm[startProp] = '';
|
||||
this.shipForm[endProp] = '';
|
||||
return;
|
||||
}
|
||||
const dateList = this.getShipCertificateDates(text);
|
||||
if (dateList[0] && dateList[1]) {
|
||||
this.shipForm[startProp] = dateList[0];
|
||||
this.shipForm[endProp] = dateList[dateList.length - 1];
|
||||
this.shipForm[longTermProp] = 0;
|
||||
}
|
||||
},
|
||||
getShipCertificateDates(value = '') {
|
||||
return (String(value || '').match(/\d{4}[-/.年]\d{1,2}[-/.月]\d{1,2}日?/g) || []).map(
|
||||
date => {
|
||||
const [, year, month, day] = date.match(/(\d{4})[-/.年](\d{1,2})[-/.月](\d{1,2})/) || [];
|
||||
return year ? `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}` : '';
|
||||
}
|
||||
);
|
||||
},
|
||||
handleSubmit() {
|
||||
this.$refs.shipForm.validate(valid => {
|
||||
if (!valid) return;
|
||||
|
||||
Reference in New Issue
Block a user