6de87ed4e2
- 调整合同管理备注输入框行数和最大长度 - 细化合同变更页面表单项间距和对齐方式 - 统一弹窗表单项的底部间距样式,改为注释禁用 - 调整 port-terminal 和 region 组件的表单项底部间距 - 修改 vite 配置中 API 请求代理地址 - 优化凭证执行详情搜索表单列宽布局 - 在运单管理页面更新型号字段为非必填,调整变更记录内容格式化显示 - 引入并使用 formatRouteChangeContent 工具函数 - 统一明细按钮显示逻辑,草稿状态也显示详情按钮 - 新增路由变更相关工具函数与样式支持
275 lines
8.3 KiB
Vue
275 lines
8.3 KiB
Vue
<template>
|
||
<div class="voucher-folder-page voucher-folder-page--embedded">
|
||
<section class="voucher-folder-page__search">
|
||
<el-form :model="query" label-position="right">
|
||
<div class="voucher-folder-page__search-grid">
|
||
<el-form-item label="车牌号">
|
||
<el-input v-model="query.plateNo" clearable placeholder="请输入" />
|
||
</el-form-item>
|
||
<el-form-item label="是否关联运单">
|
||
<el-select v-model="query.matched" clearable placeholder="全部">
|
||
<el-option label="是" :value="1" />
|
||
<el-option label="否" :value="0" />
|
||
</el-select>
|
||
</el-form-item>
|
||
<div class="voucher-folder-page__search-actions">
|
||
<el-button type="primary" @click="search">查询</el-button>
|
||
<el-button @click="reset">重置</el-button>
|
||
</div>
|
||
</div>
|
||
</el-form>
|
||
</section>
|
||
<section class="voucher-folder-page__table-wrap">
|
||
<div class="voucher-folder-page__title">{{ batchTitle }}</div>
|
||
<el-table v-loading="loading" :data="pageRows" border class="voucher-folder-page__table">
|
||
<el-table-column type="index" label="序号" width="70" :index="rowIndex" />
|
||
<el-table-column prop="voucherNo" label="执行凭证号" min-width="220">
|
||
<template #default="{ row }">
|
||
<el-link type="primary" @click="openViewer(row)">{{ row.voucherNo }}</el-link>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="plateNo" label="车牌号" min-width="150" />
|
||
<el-table-column prop="folderName" label="文件夹名称" min-width="160" />
|
||
<el-table-column prop="matched" label="是否关联运单" width="130">
|
||
<template #default="{ row }">{{ row.matched === 1 ? '是' : '否' }}</template>
|
||
</el-table-column>
|
||
<el-table-column prop="processStatus" label="处理状态" width="130" />
|
||
<el-table-column prop="createTime" label="创建时间" min-width="180" />
|
||
<el-table-column prop="updateTime" label="更新时间" min-width="180" />
|
||
<el-table-column label="操作" width="120" fixed="right">
|
||
<template #default="{ row }">
|
||
<div class="voucher-folder-page__actions">
|
||
<el-link type="primary" @click="openViewer(row)">查看</el-link>
|
||
</div>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
<div class="voucher-folder-page__pagination">
|
||
<el-pagination
|
||
v-model:current-page="page.current"
|
||
v-model:page-size="page.size"
|
||
:total="filteredRows.length"
|
||
:page-sizes="[10, 20, 50]"
|
||
layout="total, prev, pager, next, sizes"
|
||
@size-change="page.current = 1"
|
||
/>
|
||
</div>
|
||
</section>
|
||
|
||
<el-dialog v-model="viewerVisible" title="执行凭证详情" width="960px" destroy-on-close>
|
||
<div v-loading="viewerLoading" class="voucher-folder-page__viewer">
|
||
<div class="voucher-folder-page__viewer-info">
|
||
<span>执行凭证号:{{ viewer.voucherNo || '-' }}</span>
|
||
<span>文件夹名称:{{ viewer.folderName || '-' }}</span>
|
||
<span>是否关联运单:{{ viewer.matched === 1 ? '是' : '否' }}</span>
|
||
<span>
|
||
配载单号:
|
||
<el-link v-if="viewer.loadingNo" type="primary" @click="goToLoading(viewer.loadingNo)">
|
||
{{ viewer.loadingNo }}
|
||
</el-link>
|
||
<template v-else>-</template>
|
||
</span>
|
||
</div>
|
||
<div v-if="viewerFiles.length" class="voucher-folder-page__images">
|
||
<el-image
|
||
v-for="(file, index) in viewerFiles"
|
||
:key="file.id || file.url || index"
|
||
:src="file.url"
|
||
:preview-src-list="viewerFiles.map(item => item.url).filter(Boolean)"
|
||
:initial-index="index"
|
||
fit="cover"
|
||
/>
|
||
</div>
|
||
<el-empty v-else description="暂无凭证文件" />
|
||
</div>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { computed, reactive, ref, watch } from 'vue';
|
||
import { useRouter } from 'vue-router';
|
||
import { ElMessage } from 'element-plus';
|
||
import { getVoucherFolderDetail, getVoucherFolders } from '@/api/business/process-config';
|
||
|
||
const props = defineProps({
|
||
waybillId: {
|
||
type: [String, Number],
|
||
default: '',
|
||
},
|
||
});
|
||
|
||
const router = useRouter();
|
||
const loading = ref(false);
|
||
const rows = ref([]);
|
||
const page = reactive({ current: 1, size: 10 });
|
||
const query = reactive({ plateNo: '', matched: undefined });
|
||
const appliedQuery = reactive({ plateNo: '', matched: undefined });
|
||
const viewerVisible = ref(false);
|
||
const viewerLoading = ref(false);
|
||
const viewer = ref({});
|
||
const viewerFiles = ref([]);
|
||
|
||
const batchTitle = computed(() => {
|
||
const batchNos = [...new Set(rows.value.map(item => item.voucherBatchNo).filter(Boolean))];
|
||
return batchNos.length === 1 ? batchNos[0] : '执行凭证详情';
|
||
});
|
||
const filteredRows = computed(() => {
|
||
const plateNo = String(appliedQuery.plateNo || '').trim();
|
||
return rows.value.filter(item => {
|
||
const plateMatched = !plateNo || String(item.plateNo || '').includes(plateNo);
|
||
const relatedMatched =
|
||
appliedQuery.matched === undefined || appliedQuery.matched === null || appliedQuery.matched === ''
|
||
? true
|
||
: item.matched === appliedQuery.matched;
|
||
return plateMatched && relatedMatched;
|
||
});
|
||
});
|
||
const pageRows = computed(() => {
|
||
const start = (page.current - 1) * page.size;
|
||
return filteredRows.value.slice(start, start + page.size);
|
||
});
|
||
const rowIndex = index => (page.current - 1) * page.size + index + 1;
|
||
|
||
const load = async () => {
|
||
if (!props.waybillId) {
|
||
rows.value = [];
|
||
return;
|
||
}
|
||
loading.value = true;
|
||
try {
|
||
const res = await getVoucherFolders(props.waybillId);
|
||
rows.value = res.data?.data || [];
|
||
} catch (error) {
|
||
rows.value = [];
|
||
ElMessage.error(error.message || '获取执行凭证失败');
|
||
} finally {
|
||
loading.value = false;
|
||
}
|
||
};
|
||
const search = () => {
|
||
appliedQuery.plateNo = query.plateNo;
|
||
appliedQuery.matched = query.matched;
|
||
page.current = 1;
|
||
};
|
||
const reset = () => {
|
||
query.plateNo = '';
|
||
query.matched = undefined;
|
||
search();
|
||
};
|
||
const openViewer = async row => {
|
||
viewerVisible.value = true;
|
||
viewerLoading.value = true;
|
||
viewer.value = row;
|
||
viewerFiles.value = [];
|
||
try {
|
||
const res = await getVoucherFolderDetail(row.voucherId, row.plateNo);
|
||
viewer.value = res.data?.data || row;
|
||
viewerFiles.value = viewer.value.files || [];
|
||
} catch (error) {
|
||
ElMessage.error(error.message || '获取凭证详情失败');
|
||
} finally {
|
||
viewerLoading.value = false;
|
||
}
|
||
};
|
||
const goToLoading = loadingNo => {
|
||
router.push({ path: '/business/loading-manage', query: { loadingNo } });
|
||
};
|
||
|
||
watch(
|
||
() => props.waybillId,
|
||
() => {
|
||
page.current = 1;
|
||
load();
|
||
},
|
||
{ immediate: true }
|
||
);
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.voucher-folder-page {
|
||
&__search {
|
||
padding: 12px 12px 4px;
|
||
margin-bottom: 8px;
|
||
background: #fff;
|
||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
||
}
|
||
&__search-grid {
|
||
display: grid;
|
||
grid-template-columns: 220px 220px 1fr;
|
||
gap: 8px 24px;
|
||
}
|
||
&__search-actions {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
gap: 8px;
|
||
}
|
||
&__table-wrap {
|
||
padding: 12px;
|
||
background: #fff;
|
||
}
|
||
&__title {
|
||
padding-bottom: 12px;
|
||
color: #303133;
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
}
|
||
&__actions {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 8px;
|
||
}
|
||
&__pagination {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
padding-top: 12px;
|
||
}
|
||
&__viewer {
|
||
min-height: 360px;
|
||
}
|
||
&__viewer-info {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 28px;
|
||
padding-bottom: 20px;
|
||
color: #303133;
|
||
}
|
||
&__images {
|
||
display: grid;
|
||
grid-template-columns: repeat(5, 140px);
|
||
gap: 20px;
|
||
}
|
||
&__images :deep(.el-image) {
|
||
width: 140px;
|
||
height: 100px;
|
||
border: 6px solid #cfcfcf;
|
||
cursor: zoom-in;
|
||
}
|
||
:deep(.el-table) {
|
||
--el-table-border-color: #eff1f7;
|
||
}
|
||
:deep(.el-table__body tr:nth-child(even) > td) {
|
||
background: #fafafa;
|
||
}
|
||
:deep(.el-form-item) {
|
||
margin-bottom: 8px;
|
||
}
|
||
:deep(.el-form-item__label) {
|
||
white-space: nowrap;
|
||
}
|
||
:deep(.el-input),
|
||
:deep(.el-select) {
|
||
width: 100%;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 900px) {
|
||
.voucher-folder-page__search-grid {
|
||
grid-template-columns: 1fr 1fr;
|
||
}
|
||
.voucher-folder-page__search-actions {
|
||
grid-column: 1 / -1;
|
||
}
|
||
}
|
||
</style>
|