1、完善发货模板
2、完善运输计划 3、完善运单管理
This commit is contained in:
@@ -92,25 +92,23 @@
|
||||
</span>
|
||||
</template>
|
||||
<template #menu="{ row }">
|
||||
<el-button
|
||||
<el-link
|
||||
type="primary"
|
||||
text
|
||||
v-if="hasPermission('driver_view')"
|
||||
@click="openDriver(row, true)"
|
||||
>
|
||||
查看
|
||||
</el-button>
|
||||
<el-button type="primary" text v-if="hasPermission('driver_edit')" @click="openDriver(row)">
|
||||
</el-link>
|
||||
<el-link type="primary" v-if="hasPermission('driver_edit')" @click="openDriver(row)">
|
||||
修改
|
||||
</el-button>
|
||||
<el-button
|
||||
</el-link>
|
||||
<el-link
|
||||
type="primary"
|
||||
text
|
||||
v-if="hasPermission('driver_status')"
|
||||
@click="handleStatus(row)"
|
||||
>
|
||||
{{ row.status === 1 ? '停用' : '启用' }}
|
||||
</el-button>
|
||||
</el-link>
|
||||
</template>
|
||||
</avue-crud>
|
||||
|
||||
@@ -186,10 +184,15 @@
|
||||
<el-row :gutter="18">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="住址" prop="addressRegion">
|
||||
<el-input
|
||||
v-model="driverForm.addressRegion"
|
||||
maxlength="100"
|
||||
placeholder="省 / 市 / 区"
|
||||
<el-cascader
|
||||
ref="addressRegionCascader"
|
||||
v-model="driverForm.addressRegionPath"
|
||||
:options="regionOptions"
|
||||
:props="regionCascaderProps"
|
||||
:placeholder="driverForm.addressRegion || '请选择省市区'"
|
||||
clearable
|
||||
filterable
|
||||
@change="handleAddressRegionChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -496,6 +499,7 @@ import {
|
||||
recognitionTransportCertificates,
|
||||
} from '@/api/transportCapacity/driver';
|
||||
import { getDeptTree } from '@/api/system/dept';
|
||||
import { getLazyTree } from '@/api/base/region';
|
||||
import { exportBlob } from '@/api/common';
|
||||
import { getToken } from '@/utils/auth';
|
||||
import { getUploadHeaders } from '@/utils/upload';
|
||||
@@ -510,6 +514,7 @@ const emptyForm = () => ({
|
||||
gender: '',
|
||||
nation: '',
|
||||
education: '',
|
||||
addressRegionPath: [],
|
||||
addressRegion: '',
|
||||
address: '',
|
||||
postList: ['司机'],
|
||||
@@ -644,6 +649,7 @@ export default {
|
||||
],
|
||||
relationOptions: ['父母', '配偶', '子女', '兄弟姐妹', '朋友', '同事'],
|
||||
organizationOptions: [],
|
||||
regionOptions: [],
|
||||
formRules: {
|
||||
driverName: [{ required: true, message: '请输入司机姓名', trigger: 'blur' }],
|
||||
idCardNo: [{ required: true, message: '请输入身份证号', trigger: 'blur' }],
|
||||
@@ -709,9 +715,18 @@ export default {
|
||||
}
|
||||
return this.driverForm.id ? '修改司机' : '新增司机';
|
||||
},
|
||||
regionCascaderProps() {
|
||||
return {
|
||||
value: 'id',
|
||||
label: 'title',
|
||||
children: 'children',
|
||||
emitPath: true,
|
||||
};
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.initDeptTree();
|
||||
this.initRegionOptions();
|
||||
},
|
||||
methods: {
|
||||
hasPermission(code) {
|
||||
@@ -738,6 +753,117 @@ export default {
|
||||
});
|
||||
return result;
|
||||
},
|
||||
initRegionOptions() {
|
||||
getLazyTree().then(res => {
|
||||
const regions = this.buildRegionTree(res.data.data || []);
|
||||
this.regionOptions = this.extractChinaRegionOptions(regions);
|
||||
this.syncAddressRegionPath();
|
||||
});
|
||||
},
|
||||
buildRegionTree(regions = []) {
|
||||
const flatRegions = [];
|
||||
const collectRegions = list => {
|
||||
(list || []).forEach(item => {
|
||||
flatRegions.push({
|
||||
...item,
|
||||
children: undefined,
|
||||
});
|
||||
if (item.children?.length) collectRegions(item.children);
|
||||
});
|
||||
};
|
||||
collectRegions(regions);
|
||||
|
||||
const nodeMap = new Map();
|
||||
flatRegions.forEach(item => {
|
||||
const id = item.id === undefined || item.id === null ? item.value : item.id;
|
||||
if (id === undefined || id === null) return;
|
||||
nodeMap.set(String(id), {
|
||||
...item,
|
||||
id: String(id),
|
||||
parentId:
|
||||
item.parentId === undefined || item.parentId === null ? '' : String(item.parentId),
|
||||
children: [],
|
||||
});
|
||||
});
|
||||
|
||||
const rootNodes = [];
|
||||
nodeMap.forEach(node => {
|
||||
const parent = nodeMap.get(node.parentId);
|
||||
if (parent && parent !== node) {
|
||||
parent.children.push(node);
|
||||
} else {
|
||||
rootNodes.push(node);
|
||||
}
|
||||
});
|
||||
return rootNodes.map(item => this.normalizeRegionTreeNode(item));
|
||||
},
|
||||
normalizeRegionTreeNode(region) {
|
||||
const children = (region.children || []).map(item => this.normalizeRegionTreeNode(item));
|
||||
return {
|
||||
...region,
|
||||
children: children.length ? children : undefined,
|
||||
leaf: !children.length,
|
||||
};
|
||||
},
|
||||
isChinaRegion(region = {}) {
|
||||
const title = String(region.title || region.name || '').trim();
|
||||
return title === '中国' || title === '中华人民共和国';
|
||||
},
|
||||
extractChinaRegionOptions(regions) {
|
||||
const china = (regions || []).find(item => this.isChinaRegion(item));
|
||||
if (china?.children?.length) return china.children;
|
||||
if (regions.length === 1 && regions[0].children?.length) return regions[0].children;
|
||||
return regions;
|
||||
},
|
||||
findRegionOption(options, value) {
|
||||
for (const item of options || []) {
|
||||
if (String(item.id) === String(value)) return item;
|
||||
const child = this.findRegionOption(item.children, value);
|
||||
if (child) return child;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
findRegionPathByName(options = [], addressRegion = '', parents = []) {
|
||||
const target = String(addressRegion || '').replace(/\s+/g, '');
|
||||
if (!target) return [];
|
||||
for (const item of options || []) {
|
||||
const nextParents = [...parents, item];
|
||||
const nextName = nextParents.map(region => region.title || region.name || '').join('');
|
||||
if (nextName === target) {
|
||||
return nextParents.map(region => region.id);
|
||||
}
|
||||
const childPath = this.findRegionPathByName(item.children, target, nextParents);
|
||||
if (childPath.length) return childPath;
|
||||
}
|
||||
return [];
|
||||
},
|
||||
getAddressRegionLabels(value) {
|
||||
const nodes = this.$refs.addressRegionCascader?.getCheckedNodes?.() || [];
|
||||
if (nodes.length && nodes[0].pathLabels?.length) {
|
||||
return nodes[0].pathLabels;
|
||||
}
|
||||
return (value || [])
|
||||
.map(code => this.findRegionOption(this.regionOptions, code)?.title)
|
||||
.filter(Boolean);
|
||||
},
|
||||
handleAddressRegionChange(value) {
|
||||
if (!value || !value.length) {
|
||||
this.driverForm.addressRegion = '';
|
||||
this.$refs.driverForm?.validateField('addressRegion');
|
||||
return;
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.driverForm.addressRegion = this.getAddressRegionLabels(value).join('');
|
||||
this.$refs.driverForm?.validateField('addressRegion');
|
||||
});
|
||||
},
|
||||
syncAddressRegionPath() {
|
||||
if (!this.driverForm.addressRegion || this.driverForm.addressRegionPath?.length) return;
|
||||
const path = this.findRegionPathByName(this.regionOptions, this.driverForm.addressRegion);
|
||||
if (path.length) {
|
||||
this.driverForm.addressRegionPath = path;
|
||||
}
|
||||
},
|
||||
validateDrivingLicenseEndDate(rule, value, callback) {
|
||||
if (!this.driverForm.drivingLicenseStartDate) {
|
||||
callback(new Error('请选择驾驶证有效期起'));
|
||||
@@ -768,8 +894,12 @@ export default {
|
||||
this.driverForm = {
|
||||
...emptyForm(),
|
||||
...detail,
|
||||
addressRegionPath: Array.isArray(detail.addressRegionPath)
|
||||
? detail.addressRegionPath
|
||||
: [],
|
||||
postList: detail.posts ? detail.posts.split(',').filter(Boolean) : [],
|
||||
};
|
||||
this.syncAddressRegionPath();
|
||||
this.driverBox = true;
|
||||
});
|
||||
},
|
||||
@@ -817,11 +947,8 @@ export default {
|
||||
});
|
||||
},
|
||||
recognizeDrivingLicense() {
|
||||
const objectKeys = [
|
||||
this.drivingLicenseUploads.drivingLicenseFront || this.driverForm.drivingLicenseFront,
|
||||
this.drivingLicenseUploads.drivingLicenseBack || this.driverForm.drivingLicenseBack,
|
||||
].filter(Boolean);
|
||||
if (!objectKeys.length) {
|
||||
const certificates = this.buildDrivingLicenseRecognitionCertificates();
|
||||
if (!certificates.length) {
|
||||
this.$message.warning('驾驶证图片上传成功,未获取到图片地址,无法自动识别');
|
||||
return;
|
||||
}
|
||||
@@ -830,7 +957,7 @@ export default {
|
||||
text: '驾驶证识别中',
|
||||
background: 'rgba(255, 255, 255, 0.7)',
|
||||
});
|
||||
recognitionTransportCertificates(objectKeys)
|
||||
recognitionTransportCertificates(certificates)
|
||||
.then(res => {
|
||||
const data = res.data.data || {};
|
||||
this.applyDrivingLicenseRecognition(data);
|
||||
@@ -843,8 +970,20 @@ export default {
|
||||
loading.close();
|
||||
});
|
||||
},
|
||||
buildDrivingLicenseRecognitionCertificates() {
|
||||
return ['drivingLicenseFront', 'drivingLicenseBack']
|
||||
.map(prop => {
|
||||
const objectKey = this.drivingLicenseUploads[prop] || this.driverForm[prop];
|
||||
if (!objectKey) return null;
|
||||
return {
|
||||
driverLicenseUrl: objectKey,
|
||||
};
|
||||
})
|
||||
.filter(Boolean);
|
||||
},
|
||||
applyDrivingLicenseRecognition(data = {}) {
|
||||
const driverName = data.driverLicenseName || data.name || this.getOcrValue(data, ['name', '姓名']);
|
||||
const driverName =
|
||||
data.driverLicenseName || data.name || this.getOcrValue(data, ['name', '姓名']);
|
||||
const idCardNo = String(
|
||||
data.driverLicenseIdNo ||
|
||||
data.idNo ||
|
||||
@@ -1021,6 +1160,7 @@ export default {
|
||||
qualificationNo: this.driverForm.qualificationNo || this.driverForm.idCardNo,
|
||||
posts: this.driverForm.postList.join(','),
|
||||
};
|
||||
delete row.addressRegionPath;
|
||||
this.submitLoading = true;
|
||||
submit(row)
|
||||
.then(() => {
|
||||
@@ -1183,18 +1323,6 @@ export default {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
:deep(.avue-crud__search .avue-form__menu),
|
||||
:deep(.avue-crud__search .avue-form__menu--right) {
|
||||
flex: 0 0 auto;
|
||||
width: auto;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
:deep(.avue-crud__search .avue-form__menu--right) {
|
||||
margin-left: 12px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
:deep(.el-table th .cell),
|
||||
:deep(.el-table td .cell) {
|
||||
white-space: nowrap;
|
||||
@@ -1217,6 +1345,7 @@ export default {
|
||||
|
||||
:deep(.el-date-editor.el-input),
|
||||
:deep(.el-date-editor.el-input__wrapper),
|
||||
:deep(.el-cascader),
|
||||
:deep(.el-select),
|
||||
:deep(.el-input) {
|
||||
width: 100%;
|
||||
|
||||
Reference in New Issue
Block a user