339 lines
10 KiB
Vue
339 lines
10 KiB
Vue
<template>
|
|
<div class="freight-tab-panel">
|
|
<div class="filter-block">
|
|
<el-form :model="searchForm" class="filter-form" @submit.prevent>
|
|
<div class="filter-grid">
|
|
<el-form-item label="结算单号">
|
|
<el-input
|
|
v-model="searchForm.q"
|
|
placeholder="搜索结算单号"
|
|
clearable
|
|
@keyup.enter="handleSearch"
|
|
/>
|
|
</el-form-item>
|
|
</div>
|
|
<div class="filter-actions">
|
|
<div class="filter-actions-end">
|
|
<el-button class="btn-ghost" :loading="loading" @click="handleReset">
|
|
<el-icon><RefreshLeft /></el-icon>重置
|
|
</el-button>
|
|
<el-button class="btn-main" type="primary" :loading="loading" @click="handleSearch">
|
|
<el-icon><Search /></el-icon>搜索
|
|
</el-button>
|
|
</div>
|
|
</div>
|
|
</el-form>
|
|
</div>
|
|
|
|
<div class="list-toolbar">
|
|
<div class="list-toolbar-row">
|
|
<div class="list-toolbar-selected">
|
|
已选 <span class="sel-num">{{ selectedRows.length }}</span> 项
|
|
</div>
|
|
<ListQuickSearchInput
|
|
v-model="quickSearchKeyword"
|
|
placeholder="结算单号"
|
|
@search="handleQuickSearch"
|
|
@clear="handleQuickSearchClear"
|
|
/>
|
|
<el-button
|
|
class="btn-main"
|
|
type="primary"
|
|
:disabled="
|
|
selectedRows.length !== 1 ||
|
|
!selectedRows[0]?.canApprove ||
|
|
!selectedRows[0]?.currentApprovalId
|
|
"
|
|
@click="handleToolbarApprove"
|
|
>
|
|
<el-icon><CircleCheck /></el-icon>通过
|
|
</el-button>
|
|
<el-button
|
|
class="btn-ghost"
|
|
type="danger"
|
|
:disabled="
|
|
selectedRows.length !== 1 ||
|
|
!selectedRows[0]?.canApprove ||
|
|
!selectedRows[0]?.currentApprovalId
|
|
"
|
|
@click="handleToolbarReject"
|
|
>
|
|
<el-icon><CircleClose /></el-icon>驳回
|
|
</el-button>
|
|
<ListToolbarEndActions
|
|
:loading="loading"
|
|
:column-defs="listColumnDefs"
|
|
v-model:visible-columns="visibleColumns"
|
|
v-model:check-all="checkAll"
|
|
:is-indeterminate="isIndeterminate"
|
|
@refresh="fetchData"
|
|
@reset-columns="resetToDefault"
|
|
/>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<div class="list-body list-wrap">
|
|
<el-table
|
|
class="list-table"
|
|
:data="settlementList"
|
|
v-loading="loading"
|
|
stripe
|
|
row-key="id"
|
|
@selection-change="handleSelectionChange"
|
|
@row-dblclick="handleView"
|
|
>
|
|
<el-table-column type="selection" min-width="55" align="center" header-align="center" />
|
|
<el-table-column
|
|
type="index"
|
|
label="序号"
|
|
min-width="68"
|
|
align="center"
|
|
header-align="center"
|
|
:index="(index) => (pagination.page - 1) * pagination.pageSize + index + 1"
|
|
/>
|
|
<el-table-column prop="settlementNo" label="结算单号" min-width="180" show-overflow-tooltip>
|
|
<template #default="{ row }">
|
|
<el-link type="primary" @click="handleView(row)">{{ row.settlementNo }}</el-link>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column
|
|
v-if="isColumnVisible('totalFreight')"
|
|
prop="totalFreight"
|
|
label="运费合计(元)"
|
|
min-width="130"
|
|
align="right"
|
|
>
|
|
<template #default="{ row }">{{ formatAmount(row.totalFreight) }}</template>
|
|
</el-table-column>
|
|
<el-table-column
|
|
v-if="isColumnVisible('planCount')"
|
|
prop="planCount"
|
|
label="关联计划数"
|
|
min-width="110"
|
|
align="center"
|
|
/>
|
|
<el-table-column
|
|
v-if="isColumnVisible('licensePlateSummary')"
|
|
prop="licensePlateSummary"
|
|
label="车牌摘要"
|
|
min-width="140"
|
|
show-overflow-tooltip
|
|
/>
|
|
<el-table-column
|
|
v-if="isColumnVisible('currentApproverName')"
|
|
prop="currentApproverName"
|
|
label="当前审批人"
|
|
min-width="110"
|
|
align="center"
|
|
>
|
|
<template #default="{ row }">{{ row.currentApproverName || '—' }}</template>
|
|
</el-table-column>
|
|
<el-table-column
|
|
v-if="isColumnVisible('submitterName')"
|
|
prop="submitterName"
|
|
label="提交人"
|
|
min-width="100"
|
|
align="center"
|
|
>
|
|
<template #default="{ row }">{{ row.submitterName || '—' }}</template>
|
|
</el-table-column>
|
|
<el-table-column
|
|
v-if="isColumnVisible('createTime')"
|
|
prop="createTime"
|
|
label="提交时间"
|
|
min-width="160"
|
|
align="center"
|
|
>
|
|
<template #default="{ row }">{{ formatDateTime(row.createTime) }}</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
|
|
<div class="pagination list-pager-bar">
|
|
<el-pagination
|
|
v-model:current-page="pagination.page"
|
|
v-model:page-size="pagination.pageSize"
|
|
:total="pagination.total"
|
|
:page-sizes="[10, 20, 50, 100]"
|
|
layout="total, sizes, prev, pager, next"
|
|
@size-change="handleSizeChange"
|
|
@current-change="handlePageChange"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<PlFreightSettlementViewDialog ref="viewDialogRef">
|
|
<template v-if="viewingRow" #hero-actions>
|
|
<el-button
|
|
v-if="viewingRow.canApprove && viewingRow.currentApprovalId"
|
|
class="btn-main"
|
|
type="primary"
|
|
@click="handleApprove(viewingRow)"
|
|
>
|
|
<el-icon><CircleCheck /></el-icon>通过
|
|
</el-button>
|
|
<el-button
|
|
v-if="viewingRow.canApprove && viewingRow.currentApprovalId"
|
|
class="btn-ghost"
|
|
type="danger"
|
|
@click="handleReject(viewingRow)"
|
|
>
|
|
<el-icon><CircleClose /></el-icon>驳回
|
|
</el-button>
|
|
</template>
|
|
</PlFreightSettlementViewDialog>
|
|
<PlFreightApprovalDialog ref="approvalDialogRef" @success="handleMutationSuccess" />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import ListQuickSearchInput from '@/components/business/list-quick-search-input/index.vue'
|
|
import ListToolbarEndActions from '@/components/business/list-toolbar-end-actions/index.vue'
|
|
import { usePersistedListColumns } from '@/composables/usePersistedListColumns'
|
|
import { CircleCheck, CircleClose, RefreshLeft, Search } from '@element-plus/icons-vue'
|
|
import { freightApi, type FreightSettlement } from '@/api/pl'
|
|
import PlFreightApprovalDialog from '@/components/business/pl-freight-approval-dialog/index.vue'
|
|
import PlFreightSettlementViewDialog from '@/components/business/pl-freight-settlement-view-dialog/index.vue'
|
|
import { formatMoneyDisplay } from '@/utils/money-format'
|
|
import { formatDateTime } from '@/utils/format'
|
|
|
|
const listColumnDefs = [
|
|
{ prop: 'totalFreight', label: '运费合计(元)' },
|
|
{ prop: 'planCount', label: '关联计划数' },
|
|
{ prop: 'licensePlateSummary', label: '车牌摘要' },
|
|
{ prop: 'currentApproverName', label: '当前审批人' },
|
|
{ prop: 'submitterName', label: '提交人' },
|
|
{ prop: 'createTime', label: '提交时间' }
|
|
]
|
|
|
|
const {
|
|
visibleColumns,
|
|
checkAll,
|
|
isIndeterminate,
|
|
isColumnVisible,
|
|
resetToDefault
|
|
} = usePersistedListColumns('pl-freight-approval-pending-columns', listColumnDefs)
|
|
|
|
const loading = ref(false)
|
|
const settlementList = ref<FreightSettlement[]>([])
|
|
const selectedRows = ref<FreightSettlement[]>([])
|
|
const viewingRow = ref<FreightSettlement | null>(null)
|
|
const viewDialogRef = ref<InstanceType<typeof PlFreightSettlementViewDialog>>()
|
|
const approvalDialogRef = ref<InstanceType<typeof PlFreightApprovalDialog>>()
|
|
const quickSearchKeyword = ref('')
|
|
|
|
const searchForm = reactive({ q: '' })
|
|
|
|
const pagination = reactive({
|
|
page: 1,
|
|
pageSize: 20,
|
|
total: 0
|
|
})
|
|
|
|
function formatAmount(amount: number) {
|
|
if (!amount) return '¥0.00'
|
|
return formatMoneyDisplay(amount)
|
|
}
|
|
|
|
function handleSelectionChange(selection: FreightSettlement[]) {
|
|
selectedRows.value = selection
|
|
}
|
|
|
|
async function fetchData() {
|
|
loading.value = true
|
|
try {
|
|
const res = await freightApi.list({
|
|
tab: 'approval_pending',
|
|
q: quickSearchKeyword.value.trim() || searchForm.q || undefined,
|
|
page: pagination.page,
|
|
pageSize: pagination.pageSize
|
|
})
|
|
const data = res.data ?? res
|
|
settlementList.value = data.list || []
|
|
pagination.total = data.total || 0
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
function handleSearch() {
|
|
quickSearchKeyword.value = ''
|
|
pagination.page = 1
|
|
fetchData()
|
|
}
|
|
|
|
function handleReset() {
|
|
searchForm.q = ''
|
|
quickSearchKeyword.value = ''
|
|
pagination.page = 1
|
|
fetchData()
|
|
}
|
|
|
|
function handleQuickSearch() {
|
|
pagination.page = 1
|
|
fetchData()
|
|
}
|
|
|
|
function handleQuickSearchClear() {
|
|
quickSearchKeyword.value = ''
|
|
pagination.page = 1
|
|
fetchData()
|
|
}
|
|
|
|
function handlePageChange() {
|
|
fetchData()
|
|
}
|
|
|
|
function handleSizeChange() {
|
|
pagination.page = 1
|
|
fetchData()
|
|
}
|
|
|
|
function handleView(row: FreightSettlement) {
|
|
viewingRow.value = row
|
|
viewDialogRef.value?.open(row.id)
|
|
}
|
|
|
|
function handleApprove(row: FreightSettlement) {
|
|
if (!row.currentApprovalId) return
|
|
approvalDialogRef.value?.openApprove(row.id, row.currentApprovalId)
|
|
}
|
|
|
|
function handleReject(row: FreightSettlement) {
|
|
if (!row.currentApprovalId) return
|
|
approvalDialogRef.value?.openReject(row.id, row.currentApprovalId)
|
|
}
|
|
|
|
function syncViewingRowFromList() {
|
|
if (!viewingRow.value?.id) return
|
|
const updated = settlementList.value.find(row => row.id === viewingRow.value!.id)
|
|
if (updated) viewingRow.value = updated
|
|
}
|
|
|
|
async function handleMutationSuccess() {
|
|
await fetchData()
|
|
syncViewingRowFromList()
|
|
await viewDialogRef.value?.reload()
|
|
}
|
|
|
|
function handleToolbarApprove() {
|
|
if (selectedRows.value.length !== 1) return
|
|
handleApprove(selectedRows.value[0])
|
|
}
|
|
|
|
function handleToolbarReject() {
|
|
if (selectedRows.value.length !== 1) return
|
|
handleReject(selectedRows.value[0])
|
|
}
|
|
|
|
function refresh() {
|
|
fetchData()
|
|
}
|
|
|
|
onMounted(() => {
|
|
fetchData()
|
|
})
|
|
|
|
defineExpose({ refresh })
|
|
</script>
|