1、调整凭证
2、调整运单
This commit is contained in:
@@ -0,0 +1,671 @@
|
||||
<template>
|
||||
<basic-container class="transport-plan-import-page">
|
||||
<div class="transport-plan-import-page__form-wrapper">
|
||||
<div class="transport-plan-import-page__title">导入运输计划</div>
|
||||
|
||||
<el-form
|
||||
ref="importFormRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-position="right"
|
||||
label-width="auto"
|
||||
class="transport-plan-import-page__form"
|
||||
>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="项目" prop="projectId" required>
|
||||
<el-select
|
||||
v-model="form.projectId"
|
||||
placeholder="模糊查询后选择"
|
||||
filterable
|
||||
clearable
|
||||
:loading="projectLoading"
|
||||
@visible-change="visible => visible && loadProjectOptions()"
|
||||
@change="handleProjectChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in projectOptions"
|
||||
:key="item.id"
|
||||
:label="item.projectName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="客户" prop="customerName" required>
|
||||
<el-input v-model="form.customerName" disabled placeholder="选择项目后带出" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="客户合同" prop="contractId" required>
|
||||
<el-select
|
||||
v-model="form.contractId"
|
||||
placeholder="选择项目后选择"
|
||||
filterable
|
||||
clearable
|
||||
:loading="contractLoading"
|
||||
:disabled="!form.projectId"
|
||||
@change="handleContractChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in contractOptions"
|
||||
:key="item.id"
|
||||
:label="item.contractName"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item
|
||||
label="计划明细表"
|
||||
prop="file"
|
||||
required
|
||||
class="transport-plan-import-page__file-item"
|
||||
>
|
||||
<el-upload
|
||||
action="#"
|
||||
accept=".xls,.xlsx"
|
||||
:auto-upload="false"
|
||||
:limit="1"
|
||||
:file-list="files"
|
||||
:on-change="handleFileChange"
|
||||
:on-remove="handleFileRemove"
|
||||
>
|
||||
<el-button type="primary">添加附件</el-button>
|
||||
</el-upload>
|
||||
<span class="transport-plan-import-page__file-tip">
|
||||
请上传计划明细表,仅支持 Excel 格式
|
||||
</span>
|
||||
<el-link type="primary" @click="handleTemplateDownload">下载模板</el-link>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<section v-if="rows.length" class="transport-plan-import-page__preview">
|
||||
<div class="transport-plan-import-page__preview-head">
|
||||
<div class="dialog-section-title">数据明细</div>
|
||||
<el-button type="danger" plain :disabled="!selection.length" @click="removeSelectedRows">
|
||||
批量删除
|
||||
</el-button>
|
||||
</div>
|
||||
<el-tabs v-model="activeTab" type="border-card" class="transport-plan-import-page__tabs">
|
||||
<el-tab-pane :label="`计划单数(${rows.length})`" name="all" />
|
||||
<el-tab-pane :label="`疑似重复(${duplicateCount})`" name="duplicate" />
|
||||
</el-tabs>
|
||||
<div class="transport-plan-import-page__table">
|
||||
<el-table
|
||||
:data="visibleRows"
|
||||
border
|
||||
row-key="_key"
|
||||
empty-text="暂无明细数据"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="52" fixed="left" />
|
||||
<el-table-column type="index" label="序号" width="70" fixed="left" />
|
||||
<el-table-column label="计划单号" min-width="150">
|
||||
<template #default>待生成</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
v-for="column in previewColumns"
|
||||
:key="column.prop"
|
||||
:label="column.label"
|
||||
:min-width="column.width"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-select
|
||||
v-if="isEditingRow(row) && column.prop === 'quantityUnit'"
|
||||
v-model="row[column.prop]"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in quantityUnitOptions"
|
||||
:key="item"
|
||||
:label="item"
|
||||
:value="item"
|
||||
/>
|
||||
</el-select>
|
||||
<el-input
|
||||
v-else-if="isEditingRow(row)"
|
||||
v-model="row[column.prop]"
|
||||
:maxlength="column.prop === 'remark' ? 200 : undefined"
|
||||
:show-word-limit="column.prop === 'remark'"
|
||||
/>
|
||||
<span v-else>{{ row[column.prop] || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="170" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<div class="transport-plan-import-page__actions">
|
||||
<template v-if="isEditingRow(row)">
|
||||
<el-link type="primary" @click="saveRow">保存</el-link>
|
||||
<el-link type="primary" @click="cancelEditRow(row)">取消</el-link>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-link type="primary" @click="editRow(row)">编辑</el-link>
|
||||
<el-link type="danger" @click="removeRow(row)">删除</el-link>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="transport-plan-import-page__footer">
|
||||
<el-button :disabled="loading" @click="handleCancel">取消</el-button>
|
||||
<el-button type="primary" :loading="loading" @click="handleSubmit">提交</el-button>
|
||||
</div>
|
||||
</basic-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { exportBlob } from '@/api/common';
|
||||
import { getList as getContractList } from '@/api/business/contract-manage';
|
||||
import { getList as getProjectList } from '@/api/business/project-apply';
|
||||
import { importTransportPlan } from '@/api/business/transport-plan';
|
||||
import { config } from '@/option/business/transport-plan';
|
||||
import { downloadXls } from '@/utils/util';
|
||||
|
||||
const importColumns = [
|
||||
['计划名称', 'planName'],
|
||||
['运输类型', 'transportType'],
|
||||
['发货地址', 'departureAddress'],
|
||||
['发货联系人', 'departureContact'],
|
||||
['发货联系人电话', 'departurePhone'],
|
||||
['到货地址', 'arrivalAddress'],
|
||||
['收货联系人', 'arrivalContact'],
|
||||
['收货联系人电话', 'arrivalPhone'],
|
||||
['货物名称', 'cargoName'],
|
||||
['货物类型', 'cargoType'],
|
||||
['数量', 'quantity'],
|
||||
['计量单位', 'quantityUnit'],
|
||||
['包装', 'packageType'],
|
||||
['规格', 'specification'],
|
||||
['型号', 'model'],
|
||||
['里程(km)', 'mileage'],
|
||||
['计划开始时间', 'planStartDate'],
|
||||
['计划结束时间', 'planEndDate'],
|
||||
['备注', 'remark'],
|
||||
['同一计划标识号', 'planGroupId'],
|
||||
];
|
||||
|
||||
const previewColumns = [
|
||||
{ label: '计划名称', prop: 'planName', width: 180 },
|
||||
{ label: '运输类型', prop: 'transportType', width: 120 },
|
||||
{ label: '发货地址', prop: 'departureAddress', width: 260 },
|
||||
{ label: '发货联系人', prop: 'departureContact', width: 120 },
|
||||
{ label: '发货联系人电话', prop: 'departurePhone', width: 140 },
|
||||
{ label: '到货地址', prop: 'arrivalAddress', width: 260 },
|
||||
{ label: '收货联系人', prop: 'arrivalContact', width: 120 },
|
||||
{ label: '收货联系人电话', prop: 'arrivalPhone', width: 140 },
|
||||
{ label: '货物名称', prop: 'cargoName', width: 140 },
|
||||
{ label: '货物类型', prop: 'cargoType', width: 120 },
|
||||
{ label: '数量', prop: 'quantity', width: 100 },
|
||||
{ label: '计量单位', prop: 'quantityUnit', width: 110 },
|
||||
{ label: '包装', prop: 'packageType', width: 100 },
|
||||
{ label: '规格', prop: 'specification', width: 120 },
|
||||
{ label: '型号', prop: 'model', width: 120 },
|
||||
{ label: '里程(km)', prop: 'mileage', width: 120 },
|
||||
{ label: '计划开始时间', prop: 'planStartDate', width: 140 },
|
||||
{ label: '计划结束时间', prop: 'planEndDate', width: 140 },
|
||||
{ label: '备注', prop: 'remark', width: 180 },
|
||||
{ label: '同一计划标识号', prop: 'planGroupId', width: 150 },
|
||||
];
|
||||
|
||||
const extractRecords = res => {
|
||||
const data = res?.data?.data || res?.data || res;
|
||||
if (Array.isArray(data)) return data;
|
||||
if (Array.isArray(data?.records)) return data.records;
|
||||
if (Array.isArray(data?.data)) return data.data;
|
||||
if (Array.isArray(data?.data?.records)) return data.data.records;
|
||||
return [];
|
||||
};
|
||||
|
||||
const defaultForm = () => ({
|
||||
projectId: '',
|
||||
projectName: '',
|
||||
customerName: '',
|
||||
contractId: '',
|
||||
contractName: '',
|
||||
file: null,
|
||||
});
|
||||
|
||||
export default {
|
||||
name: 'TransportPlanImport',
|
||||
data() {
|
||||
return {
|
||||
form: defaultForm(),
|
||||
rules: {
|
||||
projectId: [{ required: true, message: '请选择项目', trigger: 'change' }],
|
||||
customerName: [{ required: true, message: '请选择项目后带出客户', trigger: 'change' }],
|
||||
contractId: [{ required: true, message: '请选择项目后带出客户合同', trigger: 'change' }],
|
||||
file: [{ required: true, message: '请上传计划明细表', trigger: 'change' }],
|
||||
},
|
||||
projectOptions: [],
|
||||
projectLoading: false,
|
||||
contractOptions: [],
|
||||
contractLoading: false,
|
||||
files: [],
|
||||
sourceFile: null,
|
||||
rows: [],
|
||||
selection: [],
|
||||
activeTab: 'all',
|
||||
editingKey: '',
|
||||
editSnapshot: null,
|
||||
loading: false,
|
||||
previewColumns,
|
||||
quantityUnitOptions: ['吨', '千克', '立方米', '件', '车', '箱', '托盘'],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
duplicateCount() {
|
||||
return this.rows.filter(row => row._duplicate).length;
|
||||
},
|
||||
visibleRows() {
|
||||
return this.activeTab === 'duplicate' ? this.rows.filter(row => row._duplicate) : this.rows;
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.loadProjectOptions();
|
||||
},
|
||||
methods: {
|
||||
loadProjectOptions() {
|
||||
if (this.projectLoading) return;
|
||||
this.projectLoading = true;
|
||||
getProjectList(1, 9999, config.projectQueryParams || {})
|
||||
.then(res => {
|
||||
this.projectOptions = extractRecords(res);
|
||||
})
|
||||
.finally(() => {
|
||||
this.projectLoading = false;
|
||||
});
|
||||
},
|
||||
handleProjectChange(projectId) {
|
||||
const project = this.projectOptions.find(item => String(item.id) === String(projectId));
|
||||
this.form.customerName =
|
||||
project?.customerName || project?.customerNames || project?.customer || '';
|
||||
this.form.projectName = project?.projectName || '';
|
||||
this.form.contractId = '';
|
||||
this.form.contractName = '';
|
||||
this.contractOptions = [];
|
||||
if (!projectId) return;
|
||||
this.contractLoading = true;
|
||||
getContractList(1, 9999, {
|
||||
projectId,
|
||||
projectName: project?.projectName,
|
||||
...(config.contractQueryParams || {}),
|
||||
})
|
||||
.then(res => {
|
||||
this.contractOptions = extractRecords(res);
|
||||
const contract = this.contractOptions[0];
|
||||
this.form.customerName =
|
||||
this.form.customerName || contract?.customerName || contract?.partyA || '';
|
||||
this.form.contractId = contract?.id || '';
|
||||
this.form.contractName = contract?.contractName || '';
|
||||
})
|
||||
.finally(() => {
|
||||
this.contractLoading = false;
|
||||
});
|
||||
},
|
||||
handleContractChange(contractId) {
|
||||
const contract = this.contractOptions.find(item => String(item.id) === String(contractId));
|
||||
this.form.contractName = contract?.contractName || '';
|
||||
this.form.customerName =
|
||||
contract?.customerName || contract?.partyA || this.form.customerName || '';
|
||||
},
|
||||
async handleFileChange(file, fileList) {
|
||||
if (!/\.(xls|xlsx)$/i.test(file.name || '')) {
|
||||
this.$message.error('请上传 .xls 或 .xlsx 格式文件');
|
||||
this.files = [];
|
||||
this.form.file = null;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const XLSX = await import('xlsx');
|
||||
const workbook = XLSX.read(await file.raw.arrayBuffer(), {
|
||||
type: 'array',
|
||||
cellDates: false,
|
||||
});
|
||||
const worksheet = workbook.Sheets[workbook.SheetNames[0]];
|
||||
const values = XLSX.utils.sheet_to_json(worksheet, {
|
||||
header: 1,
|
||||
defval: '',
|
||||
raw: false,
|
||||
blankrows: false,
|
||||
});
|
||||
const headers = values[0] || [];
|
||||
const headerMap = headers.reduce((result, label, index) => {
|
||||
const normalized = String(label || '')
|
||||
.replace(/^\*/, '')
|
||||
.trim();
|
||||
if (normalized) result[normalized] = index;
|
||||
return result;
|
||||
}, {});
|
||||
const rows = values.slice(1).reduce((result, cells, index) => {
|
||||
const row = { _key: `${Date.now()}-${index}-${Math.random().toString(36).slice(2)}` };
|
||||
importColumns.forEach(([label, prop]) => {
|
||||
row[prop] = String(cells[headerMap[label]] ?? '').trim();
|
||||
});
|
||||
if (importColumns.some(([, prop]) => row[prop])) result.push(row);
|
||||
return result;
|
||||
}, []);
|
||||
if (!rows.length) {
|
||||
this.$message.warning('未读取到计划明细数据');
|
||||
this.handleFileRemove();
|
||||
return;
|
||||
}
|
||||
this.files = fileList.slice(-1);
|
||||
this.sourceFile = file.raw;
|
||||
this.form.file = file.raw;
|
||||
this.rows = rows;
|
||||
this.markDuplicates();
|
||||
this.$refs.importFormRef?.validateField('file');
|
||||
this.$message.success(`已读取${rows.length}条计划明细`);
|
||||
} catch (error) {
|
||||
this.handleFileRemove();
|
||||
this.$message.error('计划明细表读取失败,请检查文件格式');
|
||||
}
|
||||
},
|
||||
handleFileRemove() {
|
||||
this.files = [];
|
||||
this.sourceFile = null;
|
||||
this.form.file = null;
|
||||
this.rows = [];
|
||||
this.selection = [];
|
||||
this.editingKey = '';
|
||||
this.editSnapshot = null;
|
||||
},
|
||||
duplicateKey(row) {
|
||||
return importColumns.map(([, prop]) => String(row[prop] || '').trim()).join('\u0001');
|
||||
},
|
||||
markDuplicates() {
|
||||
const countMap = this.rows.reduce((result, row) => {
|
||||
const key = this.duplicateKey(row);
|
||||
result[key] = (result[key] || 0) + 1;
|
||||
return result;
|
||||
}, {});
|
||||
this.rows.forEach(row => {
|
||||
row._duplicate = countMap[this.duplicateKey(row)] > 1;
|
||||
});
|
||||
},
|
||||
handleSelectionChange(rows) {
|
||||
this.selection = rows;
|
||||
},
|
||||
isEditingRow(row) {
|
||||
return this.editingKey === row._key;
|
||||
},
|
||||
editRow(row) {
|
||||
if (this.editingKey && this.editingKey !== row._key) {
|
||||
this.$message.warning('请先保存或取消当前编辑');
|
||||
return;
|
||||
}
|
||||
this.editingKey = row._key;
|
||||
this.editSnapshot = { ...row };
|
||||
},
|
||||
saveRow() {
|
||||
this.editingKey = '';
|
||||
this.editSnapshot = null;
|
||||
this.markDuplicates();
|
||||
},
|
||||
cancelEditRow(row) {
|
||||
Object.assign(row, this.editSnapshot || {});
|
||||
this.editingKey = '';
|
||||
this.editSnapshot = null;
|
||||
this.markDuplicates();
|
||||
},
|
||||
removeRow(row) {
|
||||
this.rows = this.rows.filter(item => item._key !== row._key);
|
||||
this.selection = this.selection.filter(item => item._key !== row._key);
|
||||
this.markDuplicates();
|
||||
},
|
||||
removeSelectedRows() {
|
||||
const selectedKeys = new Set(this.selection.map(row => row._key));
|
||||
this.rows = this.rows.filter(row => !selectedKeys.has(row._key));
|
||||
this.selection = [];
|
||||
this.markDuplicates();
|
||||
},
|
||||
validateRows() {
|
||||
if (!this.rows.length) {
|
||||
this.$message.warning('请保留至少一条计划明细');
|
||||
return false;
|
||||
}
|
||||
const requiredFields = [
|
||||
['planName', '计划名称'],
|
||||
['transportType', '运输类型'],
|
||||
['departureAddress', '发货地址'],
|
||||
['arrivalAddress', '到货地址'],
|
||||
['cargoType', '货物类型'],
|
||||
];
|
||||
const isValidDate = value => {
|
||||
const match = String(value || '').match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
||||
if (!match) return false;
|
||||
const [, year, month, day] = match;
|
||||
const date = new Date(Number(year), Number(month) - 1, Number(day));
|
||||
return (
|
||||
date.getFullYear() === Number(year) &&
|
||||
date.getMonth() === Number(month) - 1 &&
|
||||
date.getDate() === Number(day)
|
||||
);
|
||||
};
|
||||
for (const [index, row] of this.rows.entries()) {
|
||||
const emptyField = requiredFields.find(([prop]) => !String(row[prop] || '').trim());
|
||||
if (emptyField) {
|
||||
this.$message.warning(`第${index + 1}行${emptyField[1]}不能为空`);
|
||||
return false;
|
||||
}
|
||||
if (row.planStartDate && !isValidDate(row.planStartDate)) {
|
||||
this.$message.warning(`第${index + 1}行计划开始时间格式必须为 YYYY-MM-DD`);
|
||||
return false;
|
||||
}
|
||||
if (row.planEndDate && !isValidDate(row.planEndDate)) {
|
||||
this.$message.warning(`第${index + 1}行计划结束时间格式必须为 YYYY-MM-DD`);
|
||||
return false;
|
||||
}
|
||||
if (row.planStartDate && row.planEndDate && row.planEndDate < row.planStartDate) {
|
||||
this.$message.warning(`第${index + 1}行计划结束时间不能早于计划开始时间`);
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
row.quantity !== '' &&
|
||||
(!Number.isFinite(Number(row.quantity)) || Number(row.quantity) < 0)
|
||||
) {
|
||||
this.$message.warning(`第${index + 1}行数量必须为非负数`);
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
row.mileage !== '' &&
|
||||
(!Number.isFinite(Number(row.mileage)) || Number(row.mileage) < 0)
|
||||
) {
|
||||
this.$message.warning(`第${index + 1}行里程必须为非负数`);
|
||||
return false;
|
||||
}
|
||||
if (String(row.remark || '').length > 200) {
|
||||
this.$message.warning(`第${index + 1}行备注不能超过200个字`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
async buildImportFile() {
|
||||
const XLSX = await import('xlsx');
|
||||
const requiredLabels = [
|
||||
'计划名称',
|
||||
'运输类型',
|
||||
'发货地址',
|
||||
'到货地址',
|
||||
'货物类型',
|
||||
];
|
||||
const values = [
|
||||
importColumns.map(([label]) => (requiredLabels.includes(label) ? `*${label}` : label)),
|
||||
...this.rows.map(row => importColumns.map(([, prop]) => String(row[prop] ?? ''))),
|
||||
];
|
||||
const workbook = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(workbook, XLSX.utils.aoa_to_sheet(values), '运输计划导入模板');
|
||||
const binary = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
|
||||
const fileName = (this.sourceFile?.name || '运输计划导入模板.xlsx').replace(
|
||||
/\.xls$/i,
|
||||
'.xlsx'
|
||||
);
|
||||
return new File([binary], fileName, {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
});
|
||||
},
|
||||
handleTemplateDownload() {
|
||||
exportBlob(config.transportPlanTemplateUrl, {}, { feedback: true }).then(res => {
|
||||
downloadXls(res.data, '运输计划导入模板.xlsx');
|
||||
});
|
||||
},
|
||||
async handleSubmit() {
|
||||
const valid = await this.$refs.importFormRef?.validate().catch(() => false);
|
||||
if (!valid || this.loading || !this.validateRows()) return;
|
||||
this.loading = true;
|
||||
try {
|
||||
const file = await this.buildImportFile();
|
||||
const res = await importTransportPlan({ ...this.form, file });
|
||||
const contentType = res.headers?.['content-type'] || res.data?.type || '';
|
||||
if (
|
||||
contentType.includes('application/vnd.ms-excel') ||
|
||||
contentType.includes('spreadsheetml')
|
||||
) {
|
||||
downloadXls(
|
||||
res.data,
|
||||
`运输计划导入失败明细${this.$dayjs().format('YYYY-MM-DD HH:mm:ss')}.xlsx`
|
||||
);
|
||||
this.$message.warning('部分数据导入失败,已下载失败明细');
|
||||
} else {
|
||||
const text = await res.data.text();
|
||||
const result = text ? JSON.parse(text) : {};
|
||||
if (result.code !== 200) throw new Error(result.msg || '导入失败');
|
||||
this.$message.success('导入完成');
|
||||
}
|
||||
this.$router.push('/business/transport-plan');
|
||||
} catch (error) {
|
||||
this.$message.error(error.message || '导入失败');
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
handleCancel() {
|
||||
this.$router.push('/business/transport-plan');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.transport-plan-import-page {
|
||||
min-height: calc(100vh - 112px);
|
||||
|
||||
&__form-wrapper {
|
||||
background: #ffffff;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
&__title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 18px 24px;
|
||||
border-bottom: 1px solid #eff1f7;
|
||||
color: #303133;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
|
||||
&::before {
|
||||
width: 4px;
|
||||
height: 18px;
|
||||
background: #409eff;
|
||||
content: '';
|
||||
}
|
||||
}
|
||||
|
||||
&__form {
|
||||
padding: 24px 24px 4px;
|
||||
|
||||
.el-select,
|
||||
.el-input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&__file-item {
|
||||
margin-top: 12px;
|
||||
|
||||
:deep(.el-form-item__content) {
|
||||
gap: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&__file-tip {
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
&__preview {
|
||||
margin: 8px 24px 0;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid #eff1f7;
|
||||
}
|
||||
|
||||
&__preview-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
margin-bottom: 12px;
|
||||
|
||||
.dialog-section-title {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__tabs {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
&__table {
|
||||
overflow-x: auto;
|
||||
|
||||
:deep(.el-table) {
|
||||
min-width: 2400px;
|
||||
}
|
||||
|
||||
:deep(.el-table__cell) {
|
||||
border-color: #eff1f7;
|
||||
}
|
||||
|
||||
:deep(.el-table__row:nth-child(even) td) {
|
||||
background: #fafafa;
|
||||
}
|
||||
}
|
||||
|
||||
&__actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
&__footer {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
left: 230px;
|
||||
bottom: 0;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
padding: 12px 24px;
|
||||
border-top: 1px solid #eff1f7;
|
||||
background: #fff;
|
||||
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
}
|
||||
|
||||
:global(.avue--collapse .transport-plan-import-page__footer) {
|
||||
left: 60px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user