截止‘运力管理’模块
This commit is contained in:
875
src/views/transportCapacity/driver.vue
Normal file
875
src/views/transportCapacity/driver.vue
Normal file
@@ -0,0 +1,875 @@
|
||||
<template>
|
||||
<basic-container class="driver-page">
|
||||
<div class="driver-toolbar">
|
||||
<div class="driver-toolbar__actions">
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-plus"
|
||||
plain
|
||||
v-if="hasPermission('driver_add')"
|
||||
@click="openDriver()"
|
||||
>新增
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-download"
|
||||
plain
|
||||
v-if="hasPermission('driver_export')"
|
||||
@click="handleExport"
|
||||
>导出
|
||||
</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
icon="el-icon-delete"
|
||||
plain
|
||||
v-if="hasPermission('driver_delete')"
|
||||
@click="handleDelete"
|
||||
>批量删除
|
||||
</el-button>
|
||||
</div>
|
||||
<el-radio-group v-model="query.expireStatus" class="driver-stat" @change="handleExpireChange">
|
||||
<el-radio-button label="">全部({{ expiryStat.total }})</el-radio-button>
|
||||
<el-radio-button label="within30">30天内到期({{ expiryStat.within30 }})</el-radio-button>
|
||||
<el-radio-button label="expired">已到期({{ expiryStat.expired }})</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
|
||||
<avue-crud
|
||||
:option="option"
|
||||
:table-loading="loading"
|
||||
:data="data"
|
||||
v-model:page="page"
|
||||
v-model="form"
|
||||
ref="crud"
|
||||
:permission="permissionList"
|
||||
@search-change="searchChange"
|
||||
@search-reset="searchReset"
|
||||
@selection-change="selectionChange"
|
||||
@current-change="currentChange"
|
||||
@size-change="sizeChange"
|
||||
@refresh-change="refreshChange"
|
||||
@on-load="onLoad"
|
||||
>
|
||||
<template #driverName="{ row }">
|
||||
<el-button type="primary" link @click="openDriver(row, true)">
|
||||
{{ row.driverName }}
|
||||
</el-button>
|
||||
</template>
|
||||
<template #status="{ row }">
|
||||
<el-tag :type="row.status === 1 ? 'primary' : 'info'">
|
||||
{{ row.status === 1 ? '启用' : '停用' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
<template #drivingLicenseEndDate="{ row }">
|
||||
<span :class="getDateClass(row, 'drivingLicenseEndDate', 'drivingLicenseLongTerm')">
|
||||
{{ formatEndDate(row.drivingLicenseEndDate, row.drivingLicenseLongTerm) }}
|
||||
</span>
|
||||
</template>
|
||||
<template #qualificationEndDate="{ row }">
|
||||
<span :class="getDateClass(row, 'qualificationEndDate', 'qualificationLongTerm')">
|
||||
{{ formatEndDate(row.qualificationEndDate, row.qualificationLongTerm) }}
|
||||
</span>
|
||||
</template>
|
||||
<template #menu="{ row }">
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
icon="el-icon-view"
|
||||
v-if="hasPermission('driver_view')"
|
||||
@click="openDriver(row, true)"
|
||||
>
|
||||
查看
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
icon="el-icon-edit"
|
||||
v-if="hasPermission('driver_edit')"
|
||||
@click="openDriver(row)"
|
||||
>
|
||||
修改
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
:icon="row.status === 1 ? 'el-icon-close' : 'el-icon-check'"
|
||||
v-if="hasPermission('driver_status')"
|
||||
@click="handleStatus(row)"
|
||||
>
|
||||
{{ row.status === 1 ? '停用' : '启用' }}
|
||||
</el-button>
|
||||
</template>
|
||||
</avue-crud>
|
||||
|
||||
<el-dialog
|
||||
:title="dialogTitle"
|
||||
append-to-body
|
||||
v-model="driverBox"
|
||||
width="92%"
|
||||
top="4vh"
|
||||
class="driver-dialog"
|
||||
@closed="resetDriver"
|
||||
>
|
||||
<el-form
|
||||
ref="driverForm"
|
||||
:model="driverForm"
|
||||
:rules="formRules"
|
||||
label-position="top"
|
||||
:disabled="readonly"
|
||||
class="driver-form"
|
||||
>
|
||||
<div class="section-title">基础身份信息</div>
|
||||
<el-row :gutter="18">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="司机姓名" prop="driverName">
|
||||
<el-input v-model="driverForm.driverName" maxlength="20" show-word-limit />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="身份证号" prop="idCardNo">
|
||||
<el-input
|
||||
v-model="driverForm.idCardNo"
|
||||
maxlength="18"
|
||||
show-word-limit
|
||||
@input="driverForm.idCardNo = String(driverForm.idCardNo || '').toUpperCase()"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item label="出生年月" prop="birthday">
|
||||
<el-date-picker v-model="driverForm.birthday" type="date" value-format="YYYY-MM-DD" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item label="性别" prop="gender">
|
||||
<el-select v-model="driverForm.gender" clearable>
|
||||
<el-option label="男" value="男" />
|
||||
<el-option label="女" value="女" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item label="民族" prop="nation">
|
||||
<el-input v-model="driverForm.nation" maxlength="20" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item label="学历" prop="education">
|
||||
<el-select v-model="driverForm.education" clearable filterable>
|
||||
<el-option v-for="item in educationOptions" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="住址" prop="addressRegion">
|
||||
<el-input v-model="driverForm.addressRegion" maxlength="100" placeholder="省 / 市 / 区" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="详细地址" prop="address">
|
||||
<el-input v-model="driverForm.address" maxlength="200" show-word-limit />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="driverForm.status">
|
||||
<el-option label="启用" :value="1" />
|
||||
<el-option label="停用" :value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="岗位" prop="postList">
|
||||
<el-checkbox-group v-model="driverForm.postList">
|
||||
<el-checkbox label="司机" />
|
||||
<el-checkbox label="押运员" />
|
||||
<el-checkbox label="装卸管理员" />
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<image-upload-field
|
||||
label="身份证正面照"
|
||||
prop="idCardFront"
|
||||
:value="driverForm.idCardFront"
|
||||
:readonly="readonly"
|
||||
:headers="uploadHeaders"
|
||||
@success="url => setImage('idCardFront', url)"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<image-upload-field
|
||||
label="身份证反面照"
|
||||
prop="idCardBack"
|
||||
:value="driverForm.idCardBack"
|
||||
:readonly="readonly"
|
||||
:headers="uploadHeaders"
|
||||
@success="url => setImage('idCardBack', url)"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<image-upload-field
|
||||
label="大头照"
|
||||
prop="headPhoto"
|
||||
:value="driverForm.headPhoto"
|
||||
:readonly="readonly"
|
||||
:headers="uploadHeaders"
|
||||
@success="url => setImage('headPhoto', url)"
|
||||
/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<div class="section-title">驾驶证信息</div>
|
||||
<el-row :gutter="18">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="准驾车型" prop="drivingType">
|
||||
<el-select v-model="driverForm.drivingType" clearable filterable allow-create default-first-option>
|
||||
<el-option v-for="item in drivingTypeOptions" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="档案编号" prop="drivingLicenseNo">
|
||||
<el-input v-model="driverForm.drivingLicenseNo" maxlength="50" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="有效期" prop="drivingLicenseEndDate">
|
||||
<div class="date-range">
|
||||
<el-date-picker
|
||||
v-model="driverForm.drivingLicenseStartDate"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="起"
|
||||
/>
|
||||
<el-date-picker
|
||||
v-model="driverForm.drivingLicenseEndDate"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="止"
|
||||
:disabled="driverForm.drivingLicenseLongTerm === 1"
|
||||
/>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item label="长期有效" prop="drivingLicenseLongTerm">
|
||||
<el-checkbox v-model="driverForm.drivingLicenseLongTerm" :true-label="1" :false-label="0">
|
||||
是
|
||||
</el-checkbox>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<image-upload-field
|
||||
label="驾驶证主页"
|
||||
prop="drivingLicenseFront"
|
||||
:value="driverForm.drivingLicenseFront"
|
||||
:readonly="readonly"
|
||||
:headers="uploadHeaders"
|
||||
large
|
||||
@success="url => setImage('drivingLicenseFront', url)"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<image-upload-field
|
||||
label="驾驶证副页"
|
||||
prop="drivingLicenseBack"
|
||||
:value="driverForm.drivingLicenseBack"
|
||||
:readonly="readonly"
|
||||
:headers="uploadHeaders"
|
||||
large
|
||||
@success="url => setImage('drivingLicenseBack', url)"
|
||||
/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<div class="section-title">从业资格证信息</div>
|
||||
<el-row :gutter="18">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="从业资格证类型" prop="qualificationType">
|
||||
<el-select v-model="driverForm.qualificationType" clearable filterable allow-create default-first-option>
|
||||
<el-option label="道路运输从业资格证" value="道路运输从业资格证" />
|
||||
<el-option label="危险货物运输从业资格证" value="危险货物运输从业资格证" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="资格证号" prop="qualificationNo">
|
||||
<el-input v-model="driverForm.qualificationNo" maxlength="50" placeholder="默认身份证号" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="有效期" prop="qualificationEndDate">
|
||||
<el-date-picker
|
||||
v-model="driverForm.qualificationEndDate"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
:disabled="driverForm.qualificationLongTerm === 1"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item label="长期有效" prop="qualificationLongTerm">
|
||||
<el-checkbox v-model="driverForm.qualificationLongTerm" :true-label="1" :false-label="0">
|
||||
是
|
||||
</el-checkbox>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<image-upload-field
|
||||
label="封面页"
|
||||
prop="qualificationFront"
|
||||
:value="driverForm.qualificationFront"
|
||||
:readonly="readonly"
|
||||
:headers="uploadHeaders"
|
||||
large
|
||||
@success="url => setImage('qualificationFront', url)"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<image-upload-field
|
||||
label="内容页"
|
||||
prop="qualificationBack"
|
||||
:value="driverForm.qualificationBack"
|
||||
:readonly="readonly"
|
||||
:headers="uploadHeaders"
|
||||
large
|
||||
@success="url => setImage('qualificationBack', url)"
|
||||
/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<div class="section-title">司机联系信息</div>
|
||||
<el-row :gutter="18">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="司机类型" prop="driverType">
|
||||
<el-select v-model="driverForm.driverType">
|
||||
<el-option label="自有" value="自有" />
|
||||
<el-option label="外协" value="外协" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="手机号" prop="mobile">
|
||||
<el-input v-model="driverForm.mobile" maxlength="20" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="紧急联系人姓名" prop="emergencyContactName">
|
||||
<el-input v-model="driverForm.emergencyContactName" maxlength="20" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="紧急联系人手机号" prop="emergencyContactMobile">
|
||||
<el-input v-model="driverForm.emergencyContactMobile" maxlength="20" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="与联系人关系" prop="contactRelation">
|
||||
<el-select v-model="driverForm.contactRelation" clearable filterable allow-create default-first-option>
|
||||
<el-option v-for="item in relationOptions" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="所属组织" prop="organizationName">
|
||||
<el-input v-model="driverForm.organizationName" maxlength="50" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="driverForm.remark" type="textarea" maxlength="200" show-word-limit />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="driverBox = false">取消</el-button>
|
||||
<el-button type="primary" v-if="!readonly" :loading="submitLoading" @click="handleSubmit">
|
||||
确定
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</basic-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import NProgress from 'nprogress';
|
||||
import { option } from '@/option/transportCapacity/driver';
|
||||
import { getList, getDetail, submit, remove, changeStatus, getExpiryStat } from '@/api/transportCapacity/driver';
|
||||
import { exportBlob } from '@/api/common';
|
||||
import { getToken } from '@/utils/auth';
|
||||
import { downloadXls } from '@/utils/util';
|
||||
|
||||
const emptyForm = () => ({
|
||||
id: '',
|
||||
driverName: '',
|
||||
idCardNo: '',
|
||||
birthday: '',
|
||||
gender: '',
|
||||
nation: '',
|
||||
education: '',
|
||||
addressRegion: '',
|
||||
address: '',
|
||||
postList: ['司机'],
|
||||
posts: '',
|
||||
idCardFront: '',
|
||||
idCardBack: '',
|
||||
headPhoto: '',
|
||||
drivingType: '',
|
||||
drivingLicenseNo: '',
|
||||
drivingLicenseStartDate: '',
|
||||
drivingLicenseEndDate: '',
|
||||
drivingLicenseLongTerm: 0,
|
||||
drivingLicenseFront: '',
|
||||
drivingLicenseBack: '',
|
||||
qualificationType: '',
|
||||
qualificationNo: '',
|
||||
qualificationEndDate: '',
|
||||
qualificationLongTerm: 0,
|
||||
qualificationFront: '',
|
||||
qualificationBack: '',
|
||||
driverType: '自有',
|
||||
mobile: '',
|
||||
contactRelation: '',
|
||||
organizationName: '',
|
||||
emergencyContactName: '',
|
||||
emergencyContactMobile: '',
|
||||
remark: '',
|
||||
status: 1,
|
||||
});
|
||||
|
||||
const imageUploadField = {
|
||||
name: 'ImageUploadField',
|
||||
props: {
|
||||
label: String,
|
||||
prop: String,
|
||||
value: String,
|
||||
readonly: Boolean,
|
||||
headers: Object,
|
||||
large: Boolean,
|
||||
},
|
||||
emits: ['success'],
|
||||
methods: {
|
||||
handleSuccess(res) {
|
||||
if (res.code === 200 && res.data) {
|
||||
this.$emit('success', res.data.link || res.data.url || res.data.domain || '');
|
||||
} else {
|
||||
this.$message.error(res.msg || '上传失败');
|
||||
}
|
||||
},
|
||||
beforeUpload(file) {
|
||||
const validType = ['image/jpeg', 'image/png', 'image/jpg', 'image/bmp'].includes(file.type);
|
||||
const validSize = file.size / 1024 / 1024 < 5;
|
||||
if (!validType) {
|
||||
this.$message.error('仅支持 JPG、PNG、BMP 图片');
|
||||
}
|
||||
if (!validSize) {
|
||||
this.$message.error('图片大小不能超过 5MB');
|
||||
}
|
||||
return validType && validSize;
|
||||
},
|
||||
},
|
||||
template: `
|
||||
<el-form-item :label="label" :prop="prop">
|
||||
<el-upload
|
||||
class="driver-uploader"
|
||||
:class="{ 'driver-uploader--large': large }"
|
||||
action="/api/blade-resource/oss/endpoint/put-file"
|
||||
name="file"
|
||||
:headers="headers"
|
||||
:show-file-list="false"
|
||||
:disabled="readonly"
|
||||
:before-upload="beforeUpload"
|
||||
:on-success="handleSuccess"
|
||||
>
|
||||
<img v-if="value" :src="value" class="driver-uploader__image" />
|
||||
<div v-else class="driver-uploader__empty">上传证件图片</div>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
`,
|
||||
};
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ImageUploadField: imageUploadField,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
option,
|
||||
form: {},
|
||||
query: {
|
||||
expireStatus: '',
|
||||
},
|
||||
searchForm: {},
|
||||
loading: true,
|
||||
submitLoading: false,
|
||||
data: [],
|
||||
ids: '',
|
||||
selectionList: [],
|
||||
page: {
|
||||
pageSize: 10,
|
||||
currentPage: 1,
|
||||
total: 0,
|
||||
},
|
||||
expiryStat: {
|
||||
total: 0,
|
||||
within30: 0,
|
||||
expired: 0,
|
||||
},
|
||||
driverBox: false,
|
||||
readonly: false,
|
||||
driverForm: emptyForm(),
|
||||
uploadHeaders: {
|
||||
'Blade-Auth': `bearer ${getToken()}`,
|
||||
'Blade-Requested-With': 'BladeHttpRequest',
|
||||
},
|
||||
educationOptions: ['初中', '高中', '中专', '大专', '本科', '硕士及以上'],
|
||||
drivingTypeOptions: ['A1', 'A2', 'A3', 'B1', 'B2', 'C1', 'C2'],
|
||||
relationOptions: ['父母', '配偶', '子女', '兄弟姐妹', '朋友', '同事'],
|
||||
formRules: {
|
||||
driverName: [{ required: true, message: '请输入司机姓名', trigger: 'blur' }],
|
||||
idCardNo: [{ required: true, message: '请输入身份证号', trigger: 'blur' }],
|
||||
drivingType: [{ required: true, message: '请选择准驾车型', trigger: 'change' }],
|
||||
drivingLicenseEndDate: [{ validator: this.validateDrivingLicenseEndDate, trigger: 'change' }],
|
||||
driverType: [{ required: true, message: '请选择司机类型', trigger: 'change' }],
|
||||
mobile: [{ required: true, message: '请输入手机号', trigger: 'blur' }],
|
||||
emergencyContactName: [{ required: true, message: '请输入紧急联系人姓名', trigger: 'blur' }],
|
||||
emergencyContactMobile: [{ required: true, message: '请输入紧急联系人手机号', trigger: 'blur' }],
|
||||
organizationName: [{ required: true, message: '请输入所属组织', trigger: 'blur' }],
|
||||
idCardFront: [{ required: true, message: '请上传身份证正面照', trigger: 'change' }],
|
||||
idCardBack: [{ required: true, message: '请上传身份证反面照', trigger: 'change' }],
|
||||
drivingLicenseFront: [{ required: true, message: '请上传驾驶证主页', trigger: 'change' }],
|
||||
drivingLicenseBack: [{ required: true, message: '请上传驾驶证副页', trigger: 'change' }],
|
||||
remark: [{ max: 200, message: '备注最多200字', trigger: 'blur' }],
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['permission', 'userInfo']),
|
||||
isAdmin() {
|
||||
const authority = this.userInfo.authority || '';
|
||||
return authority.includes('admin');
|
||||
},
|
||||
permissionList() {
|
||||
return {
|
||||
addBtn: this.hasPermission('driver_add'),
|
||||
viewBtn: this.hasPermission('driver_view'),
|
||||
delBtn: this.hasPermission('driver_delete'),
|
||||
editBtn: this.hasPermission('driver_edit'),
|
||||
};
|
||||
},
|
||||
dialogTitle() {
|
||||
if (this.readonly) {
|
||||
return '查看司机';
|
||||
}
|
||||
return this.driverForm.id ? '修改司机' : '新增司机';
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
hasPermission(code) {
|
||||
return this.isAdmin || this.permission?.[code] === true;
|
||||
},
|
||||
validateDrivingLicenseEndDate(rule, value, callback) {
|
||||
if (this.driverForm.drivingLicenseLongTerm !== 1 && !value) {
|
||||
callback(new Error('请选择驾驶证有效期止'));
|
||||
return;
|
||||
}
|
||||
callback();
|
||||
},
|
||||
openDriver(row, readonly = false) {
|
||||
this.readonly = readonly;
|
||||
if (!row?.id) {
|
||||
this.driverForm = emptyForm();
|
||||
this.driverBox = true;
|
||||
return;
|
||||
}
|
||||
getDetail(row.id).then(res => {
|
||||
const detail = res.data.data || {};
|
||||
this.driverForm = {
|
||||
...emptyForm(),
|
||||
...detail,
|
||||
postList: detail.posts ? detail.posts.split(',').filter(Boolean) : [],
|
||||
};
|
||||
this.driverBox = true;
|
||||
});
|
||||
},
|
||||
resetDriver() {
|
||||
this.driverForm = emptyForm();
|
||||
this.readonly = false;
|
||||
this.submitLoading = false;
|
||||
this.$refs.driverForm?.clearValidate();
|
||||
},
|
||||
setImage(prop, url) {
|
||||
this.driverForm[prop] = url;
|
||||
this.$refs.driverForm?.validateField(prop);
|
||||
},
|
||||
handleSubmit() {
|
||||
this.$refs.driverForm.validate(valid => {
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
const row = {
|
||||
...this.driverForm,
|
||||
qualificationNo: this.driverForm.qualificationNo || this.driverForm.idCardNo,
|
||||
posts: this.driverForm.postList.join(','),
|
||||
};
|
||||
this.submitLoading = true;
|
||||
submit(row)
|
||||
.then(() => {
|
||||
this.$message.success('操作成功');
|
||||
this.driverBox = false;
|
||||
this.onLoad(this.page);
|
||||
})
|
||||
.finally(() => {
|
||||
this.submitLoading = false;
|
||||
});
|
||||
});
|
||||
},
|
||||
handleStatus(row) {
|
||||
const status = row.status === 1 ? 2 : 1;
|
||||
const text = status === 1 ? '启用' : '停用';
|
||||
this.$confirm(`是否${text}该司机?`, '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}).then(() => {
|
||||
changeStatus(row.id, status).then(() => {
|
||||
this.$message.success('操作成功');
|
||||
this.onLoad(this.page);
|
||||
});
|
||||
});
|
||||
},
|
||||
handleDelete() {
|
||||
if (this.selectionList.length === 0) {
|
||||
this.$message.warning('请选择至少一条数据');
|
||||
return;
|
||||
}
|
||||
this.$confirm('是否删除选中的司机数据?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}).then(() => {
|
||||
remove(this.ids).then(() => {
|
||||
this.$message.success('操作成功');
|
||||
this.onLoad(this.page);
|
||||
});
|
||||
});
|
||||
},
|
||||
handleExpireChange() {
|
||||
this.page.currentPage = 1;
|
||||
this.onLoad(this.page);
|
||||
},
|
||||
refreshStat() {
|
||||
getExpiryStat(this.buildQuery(false)).then(res => {
|
||||
this.expiryStat = {
|
||||
total: res.data.data?.total || 0,
|
||||
within30: res.data.data?.within30 || 0,
|
||||
expired: res.data.data?.expired || 0,
|
||||
};
|
||||
});
|
||||
},
|
||||
searchReset() {
|
||||
this.searchForm = {};
|
||||
this.query = {
|
||||
expireStatus: this.query.expireStatus,
|
||||
};
|
||||
this.onLoad(this.page);
|
||||
},
|
||||
searchChange(params, done) {
|
||||
this.searchForm = params;
|
||||
this.page.currentPage = 1;
|
||||
this.onLoad(this.page, params);
|
||||
done();
|
||||
},
|
||||
selectionChange(list) {
|
||||
this.selectionList = list;
|
||||
this.ids = list.map(item => item.id).join(',');
|
||||
},
|
||||
selectionClear() {
|
||||
this.selectionList = [];
|
||||
this.ids = '';
|
||||
this.$refs.crud?.toggleSelection();
|
||||
},
|
||||
currentChange(currentPage) {
|
||||
this.page.currentPage = currentPage;
|
||||
},
|
||||
sizeChange(pageSize) {
|
||||
this.page.pageSize = pageSize;
|
||||
},
|
||||
refreshChange() {
|
||||
this.onLoad(this.page, this.searchForm);
|
||||
},
|
||||
onLoad(page, params = {}) {
|
||||
this.loading = true;
|
||||
getList(page.currentPage, page.pageSize, this.buildQuery(true, params))
|
||||
.then(res => {
|
||||
const data = res.data.data;
|
||||
this.page.total = data.total;
|
||||
this.data = data.records;
|
||||
this.selectionClear();
|
||||
this.refreshStat();
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
buildQuery(includeExpire = true, params = {}) {
|
||||
const query = {
|
||||
...params,
|
||||
...this.searchForm,
|
||||
};
|
||||
if (includeExpire && this.query.expireStatus) {
|
||||
query.expireStatus = this.query.expireStatus;
|
||||
}
|
||||
return query;
|
||||
},
|
||||
handleExport() {
|
||||
this.$confirm('是否导出司机数据?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}).then(() => {
|
||||
NProgress.start();
|
||||
exportBlob('/blade-transport/driver/export-driver', this.buildExportParams())
|
||||
.then(res => {
|
||||
downloadXls(res.data, `司机管理${this.$dayjs().format('YYYY-MM-DD HH:mm:ss')}.xlsx`);
|
||||
})
|
||||
.finally(() => {
|
||||
NProgress.done();
|
||||
});
|
||||
});
|
||||
},
|
||||
buildExportParams() {
|
||||
return {
|
||||
...this.buildQuery(true),
|
||||
ids: this.ids,
|
||||
[this.website.tokenHeader]: getToken(),
|
||||
};
|
||||
},
|
||||
formatEndDate(date, longTerm) {
|
||||
if (longTerm === 1) {
|
||||
return '长期有效';
|
||||
}
|
||||
return date || '-';
|
||||
},
|
||||
getDateClass(row, dateProp, longTermProp) {
|
||||
if (row[longTermProp] === 1 || !row[dateProp]) {
|
||||
return '';
|
||||
}
|
||||
const today = this.$dayjs();
|
||||
const endDate = this.$dayjs(row[dateProp]);
|
||||
if (endDate.isBefore(today, 'day')) {
|
||||
return 'date-danger';
|
||||
}
|
||||
if (endDate.diff(today, 'day') <= 30) {
|
||||
return 'date-warning';
|
||||
}
|
||||
return '';
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.driver-page {
|
||||
.driver-toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.driver-toolbar__actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.driver-stat {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
:deep(.el-table th .cell),
|
||||
:deep(.el-table td .cell) {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.driver-form {
|
||||
.section-title {
|
||||
margin: 18px 0 14px;
|
||||
padding-left: 10px;
|
||||
border-left: 3px solid #e74b5f;
|
||||
color: #303133;
|
||||
font-weight: 600;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.section-title:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
:deep(.el-date-editor.el-input),
|
||||
:deep(.el-date-editor.el-input__wrapper),
|
||||
:deep(.el-select),
|
||||
:deep(.el-input) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.date-range {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.driver-uploader .el-upload) {
|
||||
width: 100%;
|
||||
height: 170px;
|
||||
border: 1px dashed #c0c4cc;
|
||||
background: #fafafa;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
:deep(.driver-uploader--large .el-upload) {
|
||||
height: 260px;
|
||||
}
|
||||
|
||||
:deep(.driver-uploader__image) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
display: block;
|
||||
}
|
||||
|
||||
:deep(.driver-uploader__empty) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.date-warning {
|
||||
color: #f56c6c;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.date-danger {
|
||||
color: #d40000;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
.driver-page {
|
||||
.driver-toolbar {
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user