853 lines
26 KiB
Vue
853 lines
26 KiB
Vue
<template>
|
||
<basic-container class="maintenance-record-page">
|
||
<avue-crud
|
||
:option="option"
|
||
:table-loading="loading"
|
||
:data="data"
|
||
v-model:page="page"
|
||
:permission="permissionList"
|
||
:before-open="beforeOpen"
|
||
v-model="form"
|
||
ref="crud"
|
||
@row-update="rowUpdate"
|
||
@row-save="rowSave"
|
||
@row-del="rowDel"
|
||
@search-change="searchChange"
|
||
@search-reset="searchReset"
|
||
@selection-change="selectionChange"
|
||
@current-change="currentChange"
|
||
@size-change="sizeChange"
|
||
@refresh-change="refreshChange"
|
||
@on-load="onLoad"
|
||
>
|
||
<template #menu-left>
|
||
<el-button
|
||
type="primary"
|
||
icon="el-icon-upload"
|
||
plain
|
||
v-if="hasPermission('maintenance_record_import')"
|
||
@click="handleImport"
|
||
>批量导入
|
||
</el-button>
|
||
<el-button
|
||
type="primary"
|
||
icon="el-icon-download"
|
||
plain
|
||
v-if="hasPermission('maintenance_record_template')"
|
||
@click="handleTemplate"
|
||
>下载模板
|
||
</el-button>
|
||
<el-button
|
||
type="primary"
|
||
icon="el-icon-download"
|
||
plain
|
||
v-if="hasPermission('maintenance_record_export')"
|
||
@click="handleExport"
|
||
>批量导出
|
||
</el-button>
|
||
<el-button
|
||
type="danger"
|
||
icon="el-icon-delete"
|
||
plain
|
||
v-if="hasPermission('maintenance_record_delete')"
|
||
@click="handleDelete"
|
||
>批量删除
|
||
</el-button>
|
||
</template>
|
||
<template #vehicleNo="{ row, index }">
|
||
<el-button type="primary" link @click="$refs.crud.rowView(row, index)">
|
||
{{ row.vehicleNo }}
|
||
</el-button>
|
||
</template>
|
||
<template #vehicleNoForm>
|
||
<el-select
|
||
v-model="form.vehicleNo"
|
||
:disabled="boxType === 'view'"
|
||
:loading="vehicleOptionsLoading"
|
||
:placeholder="vehicleNoPlaceholder"
|
||
clearable
|
||
filterable
|
||
remote
|
||
:remote-method="loadVehicleOptions"
|
||
@visible-change="handleVehicleSelectVisible"
|
||
>
|
||
<el-option
|
||
v-for="item in vehicleOptions"
|
||
:key="item.value"
|
||
:label="item.label"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
</template>
|
||
<template #vehicleNo-form>
|
||
<el-select
|
||
v-model="form.vehicleNo"
|
||
:disabled="boxType === 'view'"
|
||
:loading="vehicleOptionsLoading"
|
||
:placeholder="vehicleNoPlaceholder"
|
||
clearable
|
||
filterable
|
||
remote
|
||
:remote-method="loadVehicleOptions"
|
||
@visible-change="handleVehicleSelectVisible"
|
||
>
|
||
<el-option
|
||
v-for="item in vehicleOptions"
|
||
:key="item.value"
|
||
:label="item.label"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
</template>
|
||
<template #address-form>
|
||
<el-input
|
||
v-model="form.address"
|
||
:disabled="boxType === 'view'"
|
||
readonly
|
||
placeholder="点击地图选址"
|
||
@click="openAddressMapPicker"
|
||
/>
|
||
</template>
|
||
<template #costForm>
|
||
<el-input
|
||
v-model="form.cost"
|
||
:disabled="boxType === 'view'"
|
||
inputmode="decimal"
|
||
placeholder="请输入"
|
||
@input="value => normalizeDecimalInput('cost', value)"
|
||
>
|
||
<template #append>元</template>
|
||
</el-input>
|
||
</template>
|
||
<template #mileageForm>
|
||
<el-input
|
||
v-model="form.mileage"
|
||
:disabled="boxType === 'view'"
|
||
inputmode="decimal"
|
||
placeholder="请输入"
|
||
@input="value => normalizeDecimalInput('mileage', value)"
|
||
/>
|
||
</template>
|
||
<template #mileage="{ row }">
|
||
<span>{{ formatMileage(row.mileage, row.mileageUnit) }}</span>
|
||
</template>
|
||
<template #attachments="{ row }">
|
||
<span>{{ formatAttachments(row.attachments) }}</span>
|
||
</template>
|
||
<template #attachmentsForm>
|
||
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||
</template>
|
||
<template #attachments-form>
|
||
<vehicle-attachment-table v-model="form.attachments" :readonly="boxType === 'view'" />
|
||
</template>
|
||
</avue-crud>
|
||
<el-dialog title="维修记录数据导入" append-to-body v-model="excelBox" width="555px">
|
||
<avue-form :option="excelOption" v-model="excelForm">
|
||
<template #excelTemplate>
|
||
<el-button type="primary" @click="handleTemplate">
|
||
点击下载<i class="el-icon-download el-icon--right"></i>
|
||
</el-button>
|
||
</template>
|
||
</avue-form>
|
||
</el-dialog>
|
||
<address-map-picker
|
||
v-model="addressMapPickerVisible"
|
||
:address="form.address"
|
||
@confirm="handleAddressMapConfirm"
|
||
/>
|
||
</basic-container>
|
||
</template>
|
||
|
||
<script>
|
||
import { getList, getDetail, add, update, remove } from '@/api/vehicle/maintenance-record';
|
||
import { getList as getVehicleList } from '@/api/transportCapacity/transport-vehicle';
|
||
import { getList as getShipList } from '@/api/transportCapacity/transport-ship';
|
||
import { getDeptTree } from '@/api/system/dept';
|
||
import { exportBlob } from '@/api/common';
|
||
import { downloadXls } from '@/utils/util';
|
||
import { openImportDialog } from '@/utils/import-excel';
|
||
import { formatUpdateUserName } from '@/utils/audit';
|
||
import { getToken } from '@/utils/auth';
|
||
import { normalizeSearchRangeParams } from '@/utils/search-range';
|
||
import AddressMapPicker from '@/components/address-map-picker/main.vue';
|
||
import VehicleAttachmentTable from '@/components/vehicle-attachment-table/main.vue';
|
||
import { mapGetters } from 'vuex';
|
||
import NProgress from 'nprogress';
|
||
import 'nprogress/nprogress.css';
|
||
|
||
const createTimeRangeMap = {
|
||
createTimeRange: ['createTimeStart', 'createTimeEnd'],
|
||
};
|
||
|
||
const exportColumns = [
|
||
{ prop: 'vehicleType', label: '车船类型' },
|
||
{ prop: 'vehicleNo', label: '车牌号/船号' },
|
||
{ prop: 'maintainer', label: '维修人' },
|
||
{ prop: 'maintenanceTime', label: '维修时间' },
|
||
{ prop: 'location', label: '维修位置' },
|
||
{ prop: 'replacedPart', label: '更换零件' },
|
||
{ prop: 'cost', label: '费用' },
|
||
{ prop: 'company', label: '维修单位' },
|
||
{ prop: 'contact', label: '联系方式' },
|
||
{ prop: 'address', label: '地址' },
|
||
{ prop: 'factoryTime', label: '出厂时间' },
|
||
{ prop: 'mileage', label: '里程/航程数' },
|
||
{ prop: 'remark', label: '备注' },
|
||
];
|
||
|
||
export default {
|
||
components: {
|
||
AddressMapPicker,
|
||
VehicleAttachmentTable,
|
||
},
|
||
data() {
|
||
const validateNonNegative = (rule, value, callback) => {
|
||
if (value === undefined || value === null || value === '') {
|
||
callback();
|
||
} else if (Number(value) < 0) {
|
||
callback(new Error('不能小于 0'));
|
||
} else {
|
||
callback();
|
||
}
|
||
};
|
||
return {
|
||
form: {},
|
||
query: {},
|
||
loading: true,
|
||
excelBox: false,
|
||
addressMapPickerVisible: false,
|
||
excelForm: {},
|
||
isDetailLoading: false,
|
||
page: {
|
||
pageSize: 10,
|
||
pageSizes: [10, 20, 50, 100],
|
||
currentPage: 1,
|
||
total: 0,
|
||
},
|
||
selectionList: [],
|
||
boxType: '',
|
||
vehicleOptions: [],
|
||
vehicleOptionsLoading: false,
|
||
vehicleOptionsRequestId: 0,
|
||
option: {
|
||
height: 'auto',
|
||
calcHeight: 32,
|
||
dialogWidth: 960,
|
||
labelPosition: 'right',
|
||
labelWidth: 'auto',
|
||
searchLabelWidth: 88,
|
||
tip: false,
|
||
searchShow: true,
|
||
searchMenuSpan: 24,
|
||
searchIcon: true,
|
||
searchIndex: 4,
|
||
searchMenuPosition: 'right',
|
||
border: true,
|
||
index: true,
|
||
indexLabel: '序号',
|
||
indexWidth: 90,
|
||
viewBtn: true,
|
||
selection: true,
|
||
dialogClickModal: false,
|
||
menuWidth: 180,
|
||
column: [
|
||
{
|
||
label: '车船类型',
|
||
prop: 'vehicleType',
|
||
type: 'radio',
|
||
minWidth: 110,
|
||
dicData: [
|
||
{ label: '车辆', value: '车辆' },
|
||
{ label: '船舶', value: '船舶' },
|
||
],
|
||
value: '车辆',
|
||
search: true,
|
||
span: 24,
|
||
change: ({ value }) => this.updateVehicleType(value || '车辆'),
|
||
rules: [{ required: true, message: '请选择车船类型', trigger: 'change' }],
|
||
},
|
||
{
|
||
label: '车牌号/船号',
|
||
prop: 'vehicleNo',
|
||
type: 'select',
|
||
slot: true,
|
||
formslot: true,
|
||
search: true,
|
||
searchType: 'input',
|
||
minWidth: 130,
|
||
span: 12,
|
||
placeholder: '请选择车牌号/船号',
|
||
rules: [
|
||
{ required: true, message: '请选择车牌号/船号', trigger: 'change' },
|
||
{ max: 30, message: '最多 30 个字符', trigger: 'change' },
|
||
],
|
||
},
|
||
{
|
||
label: '维修人',
|
||
prop: 'maintainer',
|
||
span: 12,
|
||
placeholder: '请输入',
|
||
rules: [{ max: 20, message: '最多 20 个字符', trigger: 'blur' }],
|
||
},
|
||
{
|
||
label: '维修时间',
|
||
prop: 'maintenanceTime',
|
||
sortable: true,
|
||
type: 'datetime',
|
||
format: 'YYYY-MM-DD HH:mm:ss',
|
||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||
minWidth: 170,
|
||
span: 12,
|
||
placeholder: '日期时间选择器',
|
||
rules: [{ required: true, message: '请选择维修时间', trigger: 'click' }],
|
||
},
|
||
{
|
||
label: '维修位置',
|
||
prop: 'location',
|
||
minWidth: 160,
|
||
span: 12,
|
||
placeholder: '请输入',
|
||
rules: [{ max: 100, message: '最多 100 个字符', trigger: 'blur' }],
|
||
},
|
||
{
|
||
label: '更换零件',
|
||
prop: 'replacedPart',
|
||
minWidth: 160,
|
||
overHidden: true,
|
||
span: 12,
|
||
placeholder: '请输入',
|
||
rules: [{ max: 200, message: '最多 200 个字符', trigger: 'blur' }],
|
||
},
|
||
{
|
||
label: '费用',
|
||
prop: 'cost',
|
||
type: 'input',
|
||
slot: true,
|
||
span: 12,
|
||
placeholder: '请输入',
|
||
rules: [
|
||
{ required: true, message: '请输入费用', trigger: 'blur' },
|
||
{ validator: validateNonNegative, trigger: 'blur' },
|
||
],
|
||
},
|
||
{
|
||
label: '维修单位',
|
||
prop: 'company',
|
||
minWidth: 180,
|
||
span: 12,
|
||
placeholder: '请输入',
|
||
rules: [{ max: 50, message: '最多 50 个字符', trigger: 'blur' }],
|
||
},
|
||
{
|
||
label: '联系方式',
|
||
prop: 'contact',
|
||
minWidth: 150,
|
||
span: 12,
|
||
placeholder: '请输入',
|
||
rules: [{ max: 20, message: '最多 20 个字符', trigger: 'blur' }],
|
||
},
|
||
{
|
||
label: '地址',
|
||
prop: 'address',
|
||
slot: true,
|
||
formslot: true,
|
||
minWidth: 180,
|
||
overHidden: true,
|
||
span: 24,
|
||
placeholder: '地图选址',
|
||
rules: [{ max: 100, message: '最多 100 个字符', trigger: 'blur' }],
|
||
},
|
||
{
|
||
label: '出厂时间',
|
||
prop: 'factoryTime',
|
||
sortable: true,
|
||
type: 'datetime',
|
||
format: 'YYYY-MM-DD HH:mm:ss',
|
||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||
minWidth: 170,
|
||
span: 12,
|
||
placeholder: '日期时间选择器',
|
||
},
|
||
{
|
||
label: '里程/航程数(公里)',
|
||
prop: 'mileage',
|
||
renderHeader: () => '里程/航程数',
|
||
type: 'input',
|
||
minWidth: 130,
|
||
slot: true,
|
||
span: 12,
|
||
placeholder: '请输入',
|
||
rules: [{ validator: validateNonNegative, trigger: 'blur' }],
|
||
},
|
||
{
|
||
label: '里程单位',
|
||
prop: 'mileageUnit',
|
||
type: 'select',
|
||
dicData: [
|
||
{ label: '公里', value: '公里' },
|
||
{ label: '海里', value: '海里' },
|
||
],
|
||
value: '公里',
|
||
hide: true,
|
||
},
|
||
{
|
||
label: '备注',
|
||
prop: 'remark',
|
||
type: 'textarea',
|
||
minRows: 2,
|
||
span: 24,
|
||
hide: true,
|
||
placeholder: '请输入',
|
||
rules: [{ max: 500, message: '最多 500 个字符', trigger: 'blur' }],
|
||
},
|
||
{
|
||
label: '附件',
|
||
prop: 'attachments',
|
||
hide: true,
|
||
span: 24,
|
||
minWidth: 100,
|
||
slot: true,
|
||
formslot: true,
|
||
},
|
||
{
|
||
label: '创建时间',
|
||
prop: 'createTime',
|
||
sortable: true,
|
||
type: 'date',
|
||
format: 'YYYY-MM-DD HH:mm:ss',
|
||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||
addDisplay: false,
|
||
editDisplay: false,
|
||
viewDisplay: false,
|
||
display: false,
|
||
minWidth: 170,
|
||
},
|
||
{
|
||
label: '创建时间',
|
||
prop: 'createTimeRange',
|
||
type: 'date',
|
||
format: 'YYYY-MM-DD',
|
||
valueFormat: 'YYYY-MM-DD',
|
||
searchRange: true,
|
||
search: true,
|
||
hide: true,
|
||
addDisplay: false,
|
||
editDisplay: false,
|
||
viewDisplay: false,
|
||
},
|
||
{
|
||
label: '组织',
|
||
prop: 'createDept',
|
||
type: 'tree',
|
||
dicData: [],
|
||
props: {
|
||
label: 'title',
|
||
value: 'id',
|
||
},
|
||
checkStrictly: true,
|
||
search: true,
|
||
hide: true,
|
||
addDisplay: false,
|
||
editDisplay: false,
|
||
viewDisplay: false,
|
||
},
|
||
{
|
||
label: '更新人',
|
||
prop: 'updateUserName',
|
||
formatter: formatUpdateUserName,
|
||
addDisplay: false,
|
||
editDisplay: false,
|
||
display: false,
|
||
minWidth: 180,
|
||
},
|
||
{
|
||
label: '更新时间',
|
||
prop: 'updateTime',
|
||
sortable: true,
|
||
type: 'datetime',
|
||
format: 'YYYY-MM-DD HH:mm:ss',
|
||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||
addDisplay: false,
|
||
editDisplay: false,
|
||
display: false,
|
||
minWidth: 170,
|
||
},
|
||
],
|
||
},
|
||
excelOption: {
|
||
labelPosition: 'right',
|
||
submitBtn: false,
|
||
emptyBtn: false,
|
||
column: [
|
||
{
|
||
label: '模板上传',
|
||
prop: 'excelFile',
|
||
type: 'upload',
|
||
drag: true,
|
||
loadText: '模板上传中,请稍等',
|
||
span: 24,
|
||
propsHttp: {
|
||
res: 'data',
|
||
},
|
||
tip: '请上传 .xls,.xlsx 标准格式文件',
|
||
action: '/blade-transport/maintenance-record/import-maintenance-record',
|
||
},
|
||
{
|
||
label: '模板下载',
|
||
prop: 'excelTemplate',
|
||
formslot: true,
|
||
span: 24,
|
||
},
|
||
],
|
||
},
|
||
data: [],
|
||
};
|
||
},
|
||
created() {
|
||
this.initDeptTree();
|
||
},
|
||
computed: {
|
||
...mapGetters(['permission', 'userInfo']),
|
||
isAdmin() {
|
||
const authority = this.userInfo.authority || '';
|
||
return authority.includes('admin');
|
||
},
|
||
permissionList() {
|
||
return {
|
||
addBtn: this.hasPermission('maintenance_record_add'),
|
||
viewBtn: this.hasPermission('maintenance_record_view'),
|
||
delBtn: this.hasPermission('maintenance_record_delete'),
|
||
editBtn: this.hasPermission('maintenance_record_edit'),
|
||
};
|
||
},
|
||
vehicleNoPlaceholder() {
|
||
return this.form.vehicleType === '船舶' ? '请选择船号' : '请选择车牌号';
|
||
},
|
||
ids() {
|
||
let ids = [];
|
||
this.selectionList.forEach(ele => {
|
||
ids.push(ele.id);
|
||
});
|
||
return ids.join(',');
|
||
},
|
||
},
|
||
watch: {
|
||
'form.vehicleType': {
|
||
handler(value, oldValue) {
|
||
this.updateVehicleType(value || '车辆', oldValue);
|
||
},
|
||
immediate: true,
|
||
},
|
||
},
|
||
methods: {
|
||
openAddressMapPicker() {
|
||
if (this.boxType !== 'view') {
|
||
this.addressMapPickerVisible = true;
|
||
}
|
||
},
|
||
handleAddressMapConfirm(address) {
|
||
this.form.address = address;
|
||
},
|
||
hasPermission(code) {
|
||
return this.isAdmin || this.validData(this.permission[code], false);
|
||
},
|
||
updateVehicleType(vehicleType, oldValue) {
|
||
const mileageUnit = vehicleType === '船舶' ? '海里' : '公里';
|
||
const vehicleTypeColumn = this.findColumn(this.option.column, 'vehicleType');
|
||
const vehicleNoColumn = this.findColumn(this.option.column, 'vehicleNo');
|
||
const mileageColumn = this.findColumn(this.option.column, 'mileage');
|
||
const mileageUnitColumn = this.findColumn(this.option.column, 'mileageUnit');
|
||
vehicleNoColumn.placeholder =
|
||
vehicleType === '船舶' ? '请选择船号' : '请选择车牌号';
|
||
vehicleTypeColumn.disabled = Boolean(this.form.id);
|
||
mileageColumn.label = `里程/航程数(${mileageUnit})`;
|
||
mileageUnitColumn.value = mileageUnit;
|
||
this.form.mileageUnit = mileageUnit;
|
||
if (!this.isDetailLoading && oldValue && vehicleType !== oldValue) {
|
||
this.form.vehicleNo = '';
|
||
this.vehicleOptions = [];
|
||
this.loadVehicleOptions('');
|
||
}
|
||
},
|
||
handleVehicleSelectVisible(visible) {
|
||
if (visible && !this.vehicleOptions.length) this.loadVehicleOptions('');
|
||
},
|
||
loadVehicleOptions(queryString = '') {
|
||
const vehicleType = this.form.vehicleType || '车辆';
|
||
const isShip = vehicleType === '船舶';
|
||
const request = isShip ? getShipList : getVehicleList;
|
||
const params = isShip ? { shipIdentifierNo: queryString } : { plateNo: queryString };
|
||
const requestId = ++this.vehicleOptionsRequestId;
|
||
this.vehicleOptionsLoading = true;
|
||
request(1, 20, params)
|
||
.then(res => {
|
||
if (requestId !== this.vehicleOptionsRequestId) return;
|
||
const values = (res.data.data.records || [])
|
||
.map(item => (isShip ? item.shipIdentifierNo || item.shipName : item.plateNo))
|
||
.filter(Boolean);
|
||
this.vehicleOptions = [...new Set(values)].map(value => ({ label: value, value }));
|
||
if (this.form.vehicleNo && !this.vehicleOptions.some(item => item.value === this.form.vehicleNo)) {
|
||
this.vehicleOptions.unshift({ label: this.form.vehicleNo, value: this.form.vehicleNo });
|
||
}
|
||
})
|
||
.catch(() => {
|
||
if (requestId === this.vehicleOptionsRequestId) this.vehicleOptions = [];
|
||
})
|
||
.finally(() => {
|
||
if (requestId === this.vehicleOptionsRequestId) this.vehicleOptionsLoading = false;
|
||
});
|
||
},
|
||
formatMileage(value, unit) {
|
||
if (this.normalizeMileageValue(value) === null) return '';
|
||
return `${Math.max(Number(value), 0)} ${unit || '公里'}`;
|
||
},
|
||
normalizeMileageValue(value) {
|
||
if (value === undefined || value === null || value === '' || Number(value) === -1)
|
||
return null;
|
||
return value;
|
||
},
|
||
formatAttachments(value) {
|
||
if (!value) return '';
|
||
if (Array.isArray(value)) return `${value.length} 个`;
|
||
if (typeof value !== 'string') return '1 个';
|
||
try {
|
||
const attachments = JSON.parse(value);
|
||
return Array.isArray(attachments) ? `${attachments.length} 个` : '1 个';
|
||
} catch (error) {
|
||
return (
|
||
value
|
||
.split(',')
|
||
.map(item => item.trim())
|
||
.filter(Boolean).length + ' 个'
|
||
);
|
||
}
|
||
},
|
||
parseAttachments(value) {
|
||
if (!value || Array.isArray(value)) return value;
|
||
if (typeof value !== 'string') return [];
|
||
try {
|
||
const attachments = JSON.parse(value);
|
||
return Array.isArray(attachments) ? attachments : [];
|
||
} catch (error) {
|
||
return value
|
||
.split(',')
|
||
.map(item => ({ name: item.trim(), url: item.trim() }))
|
||
.filter(item => item.url);
|
||
}
|
||
},
|
||
stringifyAttachments(value) {
|
||
if (!value || typeof value === 'string') return value;
|
||
return JSON.stringify(value);
|
||
},
|
||
normalizeDecimalInput(prop, value) {
|
||
const sanitized = String(value ?? '').replace(/[^\d.]/g, '');
|
||
const [integerPart, ...decimalParts] = sanitized.split('.');
|
||
this.form[prop] = decimalParts.length
|
||
? `${integerPart || '0'}.${decimalParts.join('').slice(0, 2)}`
|
||
: integerPart;
|
||
},
|
||
initDeptTree() {
|
||
getDeptTree(this.userInfo.tenantId).then(res => {
|
||
const column = this.findColumn(this.option.column, 'createDept');
|
||
column.dicData = res.data.data;
|
||
});
|
||
},
|
||
normalizeRow(row) {
|
||
const values = { ...row };
|
||
values.vehicleType = values.vehicleType || '车辆';
|
||
values.mileageUnit = values.vehicleType === '船舶' ? '海里' : '公里';
|
||
values.mileage = this.normalizeMileageValue(values.mileage);
|
||
if (values.vehicleNo) {
|
||
values.vehicleNo =
|
||
values.vehicleType === '船舶'
|
||
? values.vehicleNo.trim()
|
||
: values.vehicleNo.trim().toUpperCase();
|
||
}
|
||
values.attachments = this.stringifyAttachments(values.attachments);
|
||
return values;
|
||
},
|
||
rowSave(row, done, loading) {
|
||
add(this.normalizeRow(row)).then(
|
||
() => {
|
||
this.onLoad(this.page);
|
||
this.$message({ type: 'success', message: '操作成功!' });
|
||
done();
|
||
},
|
||
error => {
|
||
window.console.log(error);
|
||
loading();
|
||
}
|
||
);
|
||
},
|
||
rowUpdate(row, index, done, loading) {
|
||
update(this.normalizeRow(row)).then(
|
||
() => {
|
||
this.onLoad(this.page);
|
||
this.$message({ type: 'success', message: '操作成功!' });
|
||
done();
|
||
},
|
||
error => {
|
||
window.console.log(error);
|
||
loading();
|
||
}
|
||
);
|
||
},
|
||
rowDel(row) {
|
||
this.$confirm('确定将选择数据删除?', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning',
|
||
})
|
||
.then(() => remove(row.id))
|
||
.then(() => {
|
||
this.onLoad(this.page);
|
||
this.$message({ type: 'success', message: '操作成功!' });
|
||
});
|
||
},
|
||
handleDelete() {
|
||
if (this.selectionList.length === 0) {
|
||
this.$message.warning('请选择至少一条数据');
|
||
return;
|
||
}
|
||
this.$confirm('确定将选择数据删除?', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning',
|
||
})
|
||
.then(() => remove(this.ids))
|
||
.then(() => {
|
||
this.onLoad(this.page);
|
||
this.$message({ type: 'success', message: '操作成功!' });
|
||
this.$refs.crud.toggleSelection();
|
||
});
|
||
},
|
||
beforeOpen(done, type) {
|
||
this.boxType = type;
|
||
if (type === 'add') {
|
||
this.form = {
|
||
vehicleType: '车辆',
|
||
mileageUnit: '公里',
|
||
};
|
||
this.updateVehicleType('车辆');
|
||
this.vehicleOptions = [];
|
||
this.loadVehicleOptions('');
|
||
}
|
||
if (['edit', 'view'].includes(type)) {
|
||
this.isDetailLoading = true;
|
||
getDetail(this.form.id)
|
||
.then(res => {
|
||
const detail = res.data.data;
|
||
detail.attachments = this.parseAttachments(detail.attachments);
|
||
detail.vehicleType = detail.vehicleType || '车辆';
|
||
detail.mileageUnit = detail.vehicleType === '船舶' ? '海里' : '公里';
|
||
detail.mileage = this.normalizeMileageValue(detail.mileage);
|
||
this.form = detail;
|
||
this.updateVehicleType(detail.vehicleType);
|
||
this.vehicleOptions = [];
|
||
this.loadVehicleOptions(detail.vehicleNo || '');
|
||
})
|
||
.finally(() => {
|
||
this.isDetailLoading = false;
|
||
});
|
||
}
|
||
done();
|
||
},
|
||
searchReset() {
|
||
this.query = {};
|
||
this.onLoad(this.page);
|
||
},
|
||
searchChange(params, done) {
|
||
this.query = this.buildQuery(params);
|
||
this.page.currentPage = 1;
|
||
this.onLoad(this.page);
|
||
done();
|
||
},
|
||
selectionChange(list) {
|
||
this.selectionList = list;
|
||
},
|
||
selectionClear() {
|
||
this.selectionList = [];
|
||
this.$refs.crud.toggleSelection();
|
||
},
|
||
currentChange(currentPage) {
|
||
this.page.currentPage = currentPage;
|
||
},
|
||
sizeChange(pageSize) {
|
||
this.page.pageSize = pageSize;
|
||
},
|
||
refreshChange() {
|
||
this.onLoad(this.page, this.query);
|
||
},
|
||
onLoad(page, params = {}) {
|
||
this.loading = true;
|
||
getList(page.currentPage, page.pageSize, this.buildQuery(params))
|
||
.then(res => {
|
||
const data = res.data.data;
|
||
this.page.total = data.total;
|
||
this.data = data.records;
|
||
this.selectionClear();
|
||
})
|
||
.finally(() => {
|
||
this.loading = false;
|
||
});
|
||
},
|
||
handleImport() {
|
||
openImportDialog(this, '维修记录');
|
||
},
|
||
handleExport() {
|
||
this.$confirm('是否导出维修记录数据?', '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning',
|
||
}).then(() => {
|
||
NProgress.start();
|
||
exportBlob(
|
||
'/blade-transport/maintenance-record/export-maintenance-record',
|
||
this.buildExportParams(),
|
||
{ feedback: true }
|
||
)
|
||
.then(res => {
|
||
downloadXls(res.data, `维修记录${this.$dayjs().format('YYYY-MM-DD HH:mm:ss')}.xlsx`);
|
||
})
|
||
.finally(() => {
|
||
NProgress.done();
|
||
});
|
||
});
|
||
},
|
||
buildExportParams() {
|
||
return {
|
||
...this.buildQuery(),
|
||
ids: this.ids,
|
||
exportColumns: JSON.stringify(exportColumns),
|
||
[this.website.tokenHeader]: getToken(),
|
||
};
|
||
},
|
||
buildQuery(params = {}) {
|
||
return normalizeSearchRangeParams({ ...params, ...this.query }, createTimeRangeMap);
|
||
},
|
||
handleTemplate() {
|
||
exportBlob(
|
||
'/blade-transport/maintenance-record/export-template',
|
||
{ exportColumns: JSON.stringify(exportColumns), [this.website.tokenHeader]: getToken() },
|
||
{ feedback: true }
|
||
).then(res => {
|
||
downloadXls(res.data, '维修记录模板.xlsx');
|
||
});
|
||
},
|
||
},
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.maintenance-record-page {
|
||
:deep(.el-table th .cell),
|
||
:deep(.el-table td .cell) {
|
||
white-space: nowrap;
|
||
}
|
||
|
||
&__input {
|
||
width: 100%;
|
||
}
|
||
}
|
||
</style>
|