1、调整凭证
2、调整运单
This commit is contained in:
@@ -0,0 +1,717 @@
|
||||
<template>
|
||||
<basic-container class="transport-plan-dispatch-page">
|
||||
<div v-loading="loading" class="transport-plan-dispatch-page__shell">
|
||||
<!-- 顶部信息区 -->
|
||||
<div class="transport-plan-dispatch-page__top">
|
||||
<div class="transport-plan-dispatch-page__heading">
|
||||
<div class="transport-plan-dispatch-page__heading-title">
|
||||
<el-button icon="el-icon-arrow-left" text @click="handleBack">返回</el-button>
|
||||
<span class="transport-plan-dispatch-page__heading-name">计划调度</span>
|
||||
<span class="transport-plan-dispatch-page__heading-no">
|
||||
{{ planData.planNo || planData.loadingNo || '-' }}
|
||||
</span>
|
||||
<el-tag :type="getStatusTagType(planData.businessStatus)" effect="light" class="status-text">
|
||||
{{ planData.businessStatusName || '-' }}
|
||||
</el-tag>
|
||||
<el-tag type="primary" effect="light">
|
||||
{{ planData.transportTypeName || '公路整车' }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="transport-plan-dispatch-page__summary">
|
||||
<section-card title="基本信息" class="transport-plan-dispatch-page__summary-card">
|
||||
<div class="transport-plan-dispatch-page__summary-grid">
|
||||
<div class="transport-plan-dispatch-page__summary-item">
|
||||
<div class="transport-plan-dispatch-page__summary-label">客户</div>
|
||||
<div class="transport-plan-dispatch-page__summary-value">
|
||||
{{ planData.customerName || '-' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="transport-plan-dispatch-page__summary-item">
|
||||
<div class="transport-plan-dispatch-page__summary-label">项目</div>
|
||||
<div class="transport-plan-dispatch-page__summary-value">
|
||||
{{ planData.projectName || '-' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="transport-plan-dispatch-page__summary-item">
|
||||
<div class="transport-plan-dispatch-page__summary-label">合同编号</div>
|
||||
<div class="transport-plan-dispatch-page__summary-value">
|
||||
{{ planData.contractNo || '-' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="transport-plan-dispatch-page__summary-item">
|
||||
<div class="transport-plan-dispatch-page__summary-label">计划执行时间</div>
|
||||
<div class="transport-plan-dispatch-page__summary-value">
|
||||
{{ formatDateRange(planData.planStartDate, planData.planEndDate) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="transport-plan-dispatch-page__summary-item is-wide">
|
||||
<div class="transport-plan-dispatch-page__summary-label">货物信息</div>
|
||||
<div class="transport-plan-dispatch-page__summary-value">
|
||||
{{ planData.goodsInfo || formatGoodsInfo(planData) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="transport-plan-dispatch-page__summary-item">
|
||||
<div class="transport-plan-dispatch-page__summary-label">附件</div>
|
||||
<div class="transport-plan-dispatch-page__summary-value">
|
||||
<template v-if="attachmentList.length">
|
||||
<el-link
|
||||
v-for="(item, index) in attachmentList"
|
||||
:key="index"
|
||||
type="primary"
|
||||
:href="item.url"
|
||||
:underline="false"
|
||||
target="_blank"
|
||||
class="transport-plan-dispatch-page__attachment-link"
|
||||
>
|
||||
{{ item.name || item.originalName || '附件' }}
|
||||
</el-link>
|
||||
</template>
|
||||
<span v-else>-</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section-card>
|
||||
|
||||
<section-card title="收发货路线" class="transport-plan-dispatch-page__route-card">
|
||||
<div class="transport-plan-dispatch-page__route">
|
||||
<div class="transport-plan-dispatch-page__route-item">
|
||||
<span class="transport-plan-dispatch-page__route-badge is-start">起</span>
|
||||
<div class="transport-plan-dispatch-page__route-body">
|
||||
<div class="transport-plan-dispatch-page__route-title">
|
||||
{{ planData.departureName || '-' }}
|
||||
</div>
|
||||
<div class="transport-plan-dispatch-page__route-address">
|
||||
{{ formatAddress(planData.departureAddress) }}
|
||||
</div>
|
||||
<div class="transport-plan-dispatch-page__route-contact">
|
||||
{{ formatContact(planData.departureContact, planData.departurePhone) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="transport-plan-dispatch-page__route-vehicle">
|
||||
<el-icon><Van /></el-icon>
|
||||
</div>
|
||||
<div class="transport-plan-dispatch-page__route-item">
|
||||
<span class="transport-plan-dispatch-page__route-badge is-end">终</span>
|
||||
<div class="transport-plan-dispatch-page__route-body">
|
||||
<div class="transport-plan-dispatch-page__route-title">
|
||||
{{ planData.arrivalName || '-' }}
|
||||
</div>
|
||||
<div class="transport-plan-dispatch-page__route-address">
|
||||
{{ formatAddress(planData.arrivalAddress) }}
|
||||
</div>
|
||||
<div class="transport-plan-dispatch-page__route-contact">
|
||||
{{ formatContact(planData.arrivalContact, planData.arrivalPhone) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 调度列表 -->
|
||||
<section-card class="transport-plan-dispatch-page__list-card">
|
||||
<template #title>
|
||||
<span>待调度列表</span>
|
||||
<span class="transport-plan-dispatch-page__list-summary">
|
||||
{{ summaryText }}
|
||||
</span>
|
||||
</template>
|
||||
<template #extra>
|
||||
<el-button type="primary" :disabled="!canAddDispatch" @click="handleAdd">
|
||||
新增
|
||||
</el-button>
|
||||
</template>
|
||||
<el-table
|
||||
:data="dispatchList"
|
||||
border
|
||||
height="100%"
|
||||
row-key="id"
|
||||
class="transport-plan-dispatch-page__table"
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="70" align="center" fixed="left" />
|
||||
<el-table-column label="运输方式" min-width="180" align="center" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
{{ row.transportTypeName || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="carrierType" label="承运类型" min-width="150" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="carrierName" label="承运商" min-width="150" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="driverName" label="司机" min-width="260" align="center" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
<span>{{ formatDriver(row) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="vehicleNo" label="车牌号" min-width="150" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="cargoType" label="货物类型" min-width="170" align="center" show-overflow-tooltip />
|
||||
<el-table-column prop="cargoInfo" label="货物信息" min-width="280" align="center" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
{{ row.cargoInfo || formatCargoInfo(row) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="发货地址" min-width="220" align="center" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
{{ formatAddress(row.departureAddress) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="收货地址" min-width="220" align="center" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
{{ formatAddress(row.arrivalAddress) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="quantity" label="数量" min-width="120" align="center">
|
||||
<template #default="{ row }">
|
||||
{{ row.quantity ? `${row.quantity}${row.quantityUnit || '吨'}` : '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="unitPrice" label="单价" min-width="120" align="center" />
|
||||
<el-table-column prop="freight" label="运费" min-width="120" align="center" />
|
||||
<el-table-column prop="otherFeeTotal" label="其他费用" min-width="120" align="center" />
|
||||
<el-table-column prop="freightTotal" label="运费合计" min-width="120" align="center" />
|
||||
<el-table-column label="操作" width="100" align="center" fixed="right">
|
||||
<template #default="{ row, $index }">
|
||||
<div class="transport-plan-dispatch-page__actions">
|
||||
<el-link type="primary" @click="handleEdit(row, $index)">编辑</el-link>
|
||||
<el-link type="danger" @click="handleDelete($index)">删除</el-link>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</section-card>
|
||||
|
||||
<!-- 底部按钮 -->
|
||||
<div class="transport-plan-dispatch-page__footer">
|
||||
<el-button @click="handleBack">关闭</el-button>
|
||||
<el-button type="primary" :loading="saving" @click="handleSubmit">
|
||||
确认生成
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 调度明细编辑弹窗 - 将使用原组件的弹窗 -->
|
||||
<transport-plan-page
|
||||
v-if="transportPlanPageVisible"
|
||||
ref="transportPlanPageRef"
|
||||
:api="api"
|
||||
:config="config"
|
||||
:crud-option="option"
|
||||
style="display: none"
|
||||
/>
|
||||
</basic-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Van } from '@element-plus/icons-vue';
|
||||
import { getDetail, dispatch } from '@/api/business/transport-plan';
|
||||
import SectionCard from '@/components/section-card/main.vue';
|
||||
import TransportPlanPage from './components/transport-plan-page.vue';
|
||||
import * as api from '@/api/business/transport-plan';
|
||||
import { config, option } from '@/option/business/transport-plan';
|
||||
|
||||
const TRANSPORT_PLAN_QUANTITY_UNIT = '吨';
|
||||
|
||||
export default {
|
||||
name: 'TransportPlanDispatch',
|
||||
components: {
|
||||
Van,
|
||||
SectionCard,
|
||||
TransportPlanPage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
saving: false,
|
||||
planData: {},
|
||||
dispatchList: [],
|
||||
attachmentList: [],
|
||||
transportPlanPageVisible: false,
|
||||
api,
|
||||
config,
|
||||
option,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
planId() {
|
||||
return this.$route.query.planId;
|
||||
},
|
||||
summaryText() {
|
||||
const goodsList = this.parseGoodsList(this.planData.goodsJson);
|
||||
if (!goodsList.length) {
|
||||
const total = Number(this.planData.totalQuantity || 0);
|
||||
const dispatched = this.calculateDispatchedQuantity();
|
||||
const remaining = Math.max(total - dispatched, 0);
|
||||
return `共${total}吨 | 已调度 ${dispatched.toFixed(2)}吨,剩余${remaining.toFixed(2)}吨`;
|
||||
}
|
||||
|
||||
const summary = {};
|
||||
goodsList.forEach(goods => {
|
||||
const unit = goods.quantityUnit || TRANSPORT_PLAN_QUANTITY_UNIT;
|
||||
if (!summary[unit]) {
|
||||
summary[unit] = { total: 0, dispatched: 0 };
|
||||
}
|
||||
summary[unit].total += Number(goods.quantity || 0);
|
||||
});
|
||||
|
||||
this.dispatchList.forEach(item => {
|
||||
const unit = item.quantityUnit || TRANSPORT_PLAN_QUANTITY_UNIT;
|
||||
if (!summary[unit]) {
|
||||
summary[unit] = { total: 0, dispatched: 0 };
|
||||
}
|
||||
summary[unit].dispatched += Number(item.quantity || 0);
|
||||
});
|
||||
|
||||
const parts = Object.entries(summary).map(([unit, data]) => {
|
||||
const remaining = Math.max(data.total - data.dispatched, 0);
|
||||
return `${data.total}${unit} | 已调度 ${data.dispatched.toFixed(2)}${unit},剩余${remaining.toFixed(
|
||||
2
|
||||
)}${unit}`;
|
||||
});
|
||||
|
||||
return parts.join(' | ');
|
||||
},
|
||||
canAddDispatch() {
|
||||
const goodsList = this.parseGoodsList(this.planData.goodsJson);
|
||||
if (!goodsList.length) {
|
||||
const total = Number(this.planData.totalQuantity || 0);
|
||||
const dispatched = this.calculateDispatchedQuantity();
|
||||
return dispatched < total;
|
||||
}
|
||||
|
||||
return goodsList.some(goods => {
|
||||
const unit = goods.quantityUnit || TRANSPORT_PLAN_QUANTITY_UNIT;
|
||||
const totalQty = Number(goods.quantity || 0);
|
||||
const dispatchedQty = this.dispatchList
|
||||
.filter(item => item.quantityUnit === unit)
|
||||
.reduce((sum, item) => sum + Number(item.quantity || 0), 0);
|
||||
return dispatchedQty < totalQty;
|
||||
});
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.loadPlanData();
|
||||
},
|
||||
mounted() {
|
||||
// 初始化 transport-plan-page 组件用于打开弹窗
|
||||
this.transportPlanPageVisible = true;
|
||||
},
|
||||
methods: {
|
||||
loadPlanData() {
|
||||
if (!this.planId) {
|
||||
this.$message.error('缺少计划ID参数');
|
||||
this.handleBack();
|
||||
return;
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
getDetail(this.planId)
|
||||
.then(res => {
|
||||
if (res.data?.success) {
|
||||
this.planData = res.data.data || {};
|
||||
this.attachmentList = this.parseAttachments(this.planData.attachmentsJson);
|
||||
this.dispatchList = this.parseDispatchList(this.planData);
|
||||
} else {
|
||||
this.$message.error(res.data?.msg || '加载数据失败');
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('加载计划数据失败:', err);
|
||||
this.$message.error('加载数据失败');
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
parseAttachments(json) {
|
||||
try {
|
||||
const data = JSON.parse(json || '[]');
|
||||
return Array.isArray(data) ? data : [];
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
parseDispatchList(planData) {
|
||||
try {
|
||||
const sources = [
|
||||
planData.waybillList,
|
||||
planData.dispatchRows,
|
||||
planData.dispatchRecordList,
|
||||
planData.dispatchList,
|
||||
];
|
||||
for (const source of sources) {
|
||||
if (Array.isArray(source) && source.length) {
|
||||
return source.map((item, index) => ({
|
||||
...item,
|
||||
id: item.id || `temp-${index}`,
|
||||
}));
|
||||
}
|
||||
}
|
||||
return [];
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
parseGoodsList(json) {
|
||||
try {
|
||||
const data = JSON.parse(json || '[]');
|
||||
return Array.isArray(data) ? data : [];
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
calculateDispatchedQuantity() {
|
||||
return this.dispatchList.reduce((sum, item) => sum + Number(item.quantity || 0), 0);
|
||||
},
|
||||
getStatusTagType(status) {
|
||||
const statusMap = {
|
||||
0: 'info',
|
||||
1: 'warning',
|
||||
2: 'success',
|
||||
3: 'danger',
|
||||
};
|
||||
return statusMap[status] || 'info';
|
||||
},
|
||||
formatDateRange(startDate, endDate) {
|
||||
const dates = [startDate, endDate].filter(Boolean);
|
||||
return dates.length ? dates.join(' ~ ') : '-';
|
||||
},
|
||||
formatAddress(address) {
|
||||
if (!address) return '-';
|
||||
const match = address.match(/^(.*?省)?(.*?市)?(.*?区|.*?县)?/);
|
||||
return match ? match[0] || address : address;
|
||||
},
|
||||
formatContact(contact, phone) {
|
||||
const parts = [contact, phone].filter(Boolean);
|
||||
return parts.length ? parts.join(' / ') : '-';
|
||||
},
|
||||
formatDriver(row) {
|
||||
const parts = [row.driverName, row.driverPhone].filter(Boolean);
|
||||
return parts.length ? parts.join(' / ') : '-';
|
||||
},
|
||||
formatGoodsInfo(data) {
|
||||
const goodsList = this.parseGoodsList(data.goodsJson);
|
||||
if (!goodsList.length) {
|
||||
return data.cargoName || '-';
|
||||
}
|
||||
return goodsList
|
||||
.map(goods => {
|
||||
const parts = [goods.cargoName || goods.goodsName];
|
||||
if (goods.quantity) {
|
||||
parts.push(`${goods.quantity}${goods.quantityUnit || TRANSPORT_PLAN_QUANTITY_UNIT}`);
|
||||
}
|
||||
return parts.join(' ');
|
||||
})
|
||||
.join(';');
|
||||
},
|
||||
formatCargoInfo(row) {
|
||||
const parts = [row.cargoName];
|
||||
if (row.specification) parts.push(row.specification);
|
||||
if (row.model) parts.push(row.model);
|
||||
return parts.filter(Boolean).join(' / ') || '-';
|
||||
},
|
||||
handleBack() {
|
||||
this.$router.back();
|
||||
},
|
||||
handleAdd() {
|
||||
if (!this.canAddDispatch) {
|
||||
this.$message.warning('待调度列表货物总量已达到计划总量,不能新增调度明细');
|
||||
return;
|
||||
}
|
||||
|
||||
// 调用 transport-plan-page 组件的方法打开弹窗
|
||||
this.$nextTick(() => {
|
||||
const component = this.$refs.transportPlanPageRef;
|
||||
if (component) {
|
||||
// 设置调度数据
|
||||
component.dispatchRow = this.planData;
|
||||
component.dispatchRows = [...this.dispatchList];
|
||||
// 打开新增弹窗
|
||||
component.openDispatchItemDialog(-1);
|
||||
}
|
||||
});
|
||||
},
|
||||
handleEdit(row, index) {
|
||||
// 调用 transport-plan-page 组件的方法打开弹窗
|
||||
this.$nextTick(() => {
|
||||
const component = this.$refs.transportPlanPageRef;
|
||||
if (component) {
|
||||
// 设置调度数据
|
||||
component.dispatchRow = this.planData;
|
||||
component.dispatchRows = [...this.dispatchList];
|
||||
// 打开编辑弹窗
|
||||
component.openDispatchItemDialog(index, row);
|
||||
}
|
||||
});
|
||||
},
|
||||
handleDelete(index) {
|
||||
this.$confirm('确定删除该调度明细?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}).then(() => {
|
||||
this.dispatchList.splice(index, 1);
|
||||
this.$message.success('删除成功');
|
||||
});
|
||||
},
|
||||
handleSubmit() {
|
||||
if (!this.dispatchList.length) {
|
||||
this.$message.warning('请先添加调度明细');
|
||||
return;
|
||||
}
|
||||
|
||||
for (const [index, row] of this.dispatchList.entries()) {
|
||||
if (!row.carrierName) {
|
||||
this.$message.warning(`第${index + 1}条调度明细缺少承运商信息`);
|
||||
return;
|
||||
}
|
||||
if (!row.driverName) {
|
||||
this.$message.warning(`第${index + 1}条调度明细缺少司机信息`);
|
||||
return;
|
||||
}
|
||||
if (!row.vehicleNo) {
|
||||
this.$message.warning(`第${index + 1}条调度明细缺少车牌号`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.$confirm(
|
||||
`请确认调度信息,将生成 <span style="color: #409eff; font-size: 20px; padding: 0 4px;">${this.dispatchList.length}</span> 条运单,是否继续?`,
|
||||
'提示',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
dangerouslyUseHTMLString: true,
|
||||
}
|
||||
).then(() => {
|
||||
this.submitDispatch();
|
||||
});
|
||||
},
|
||||
submitDispatch() {
|
||||
this.saving = true;
|
||||
const payload = {
|
||||
id: this.planId,
|
||||
mode: 'submit',
|
||||
waybills: this.dispatchList.map(row => ({
|
||||
...row,
|
||||
taskEntryMode: row.taskEntryMode || 'simple',
|
||||
taskRemark: row.remark || '',
|
||||
estimatedStartTime: row.estimatedStartTime || this.planData.planStartDate || '',
|
||||
estimatedEndTime: row.estimatedEndTime || this.planData.planEndDate || '',
|
||||
goodsJson:
|
||||
row.goodsJson ||
|
||||
JSON.stringify([
|
||||
{
|
||||
cargoName: row.cargoName,
|
||||
cargoType: row.cargoType,
|
||||
quantity: row.quantity,
|
||||
quantityUnit: row.quantityUnit,
|
||||
specification: row.specification,
|
||||
model: row.model,
|
||||
packageType: row.packageType,
|
||||
brand: row.brand,
|
||||
},
|
||||
]),
|
||||
})),
|
||||
};
|
||||
|
||||
dispatch(payload)
|
||||
.then(res => {
|
||||
if (res.data?.success) {
|
||||
this.$message.success('调度成功,运单已生成');
|
||||
this.handleBack();
|
||||
} else {
|
||||
this.$message.error(res.data?.msg || '调度失败');
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('调度失败:', err);
|
||||
this.$message.error('调度失败');
|
||||
})
|
||||
.finally(() => {
|
||||
this.saving = false;
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.transport-plan-dispatch-page {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
&__shell {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&__top {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
&__heading {
|
||||
padding: 16px;
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
|
||||
&-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&-name {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
&-no {
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
}
|
||||
}
|
||||
|
||||
&__summary {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
|
||||
&-card {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
&-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
|
||||
&.is-wide {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
}
|
||||
|
||||
&-label {
|
||||
font-size: 14px;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
&-value {
|
||||
font-size: 14px;
|
||||
color: #303133;
|
||||
}
|
||||
}
|
||||
|
||||
&__route-card {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&__route {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
|
||||
&-item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
&-badge {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
flex-shrink: 0;
|
||||
|
||||
&.is-start {
|
||||
background: #67c23a;
|
||||
}
|
||||
|
||||
&.is-end {
|
||||
background: #409eff;
|
||||
}
|
||||
}
|
||||
|
||||
&-body {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
&-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&-address,
|
||||
&-contact {
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
&-vehicle {
|
||||
font-size: 24px;
|
||||
color: #909399;
|
||||
}
|
||||
}
|
||||
|
||||
&__list-card {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&__list-summary {
|
||||
margin-left: 12px;
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
&__table {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&__actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
&__footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
padding: 16px;
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
&__attachment-link {
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.status-text {
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user