feat(pl): 展示各装送段用证配置与独立占用明细并保留历史计量口径。
This commit is contained in:
1 parent
706260ff7a
commit
b764eb02a7
10 files changed
+497
-40
No files matched your search
@@ -64,8 +64,64 @@
|
||||
table-key="pl-plan-quota"
|
||||
v-loading="loading"
|
||||
:data="rows"
|
||||
row-key="id"
|
||||
:expand-row-keys="expandedIds"
|
||||
@expand-change="expand"
|
||||
stripe
|
||||
class="list-table"
|
||||
><el-table-column type="expand"
|
||||
><template #default="{ row }">
|
||||
<div
|
||||
class="quota-expansion"
|
||||
:style="expansionStyle"
|
||||
v-loading="details[row.id]?.loading"
|
||||
>
|
||||
<el-alert
|
||||
v-if="details[row.id]?.error"
|
||||
title="段次用证加载失败"
|
||||
type="error"
|
||||
:closable="false"
|
||||
><el-button @click="loadDetail(row.id)"
|
||||
><el-icon><RefreshLeft /></el-icon>重试</el-button
|
||||
></el-alert
|
||||
>
|
||||
<template v-else-if="details[row.id]?.data">
|
||||
<el-tag
|
||||
size="small"
|
||||
:type="perStop(details[row.id].data) ? 'info' : 'warning'"
|
||||
>{{
|
||||
perStop(details[row.id].data) ? '各装送段分别计量' : '原口径:单侧计量'
|
||||
}}</el-tag
|
||||
>
|
||||
<p class="form-tip"
|
||||
>绑定不代表校验通过;购买证与运输证分别显示各自证面单位的预占和已用量。</p
|
||||
>
|
||||
<el-table :data="stopUsageRows(details[row.id].data!)" stripe>
|
||||
<el-table-column prop="label" label="段产品" min-width="210" />
|
||||
<el-table-column label="合同" min-width="150"
|
||||
><template #default="{ row: item }">{{
|
||||
item.contractNo || '未关联或不可读取'
|
||||
}}</template></el-table-column
|
||||
>
|
||||
<el-table-column prop="partyName" label="单位" min-width="160" />
|
||||
<el-table-column label="需用量" min-width="110"
|
||||
><template #default="{ row: item }"
|
||||
>{{ item.quantity }} {{ item.unit }}</template
|
||||
></el-table-column
|
||||
>
|
||||
<el-table-column
|
||||
prop="purchase"
|
||||
label="购买证 · 预占 / 已用"
|
||||
min-width="300"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="transport"
|
||||
label="运输证 · 预占 / 已用"
|
||||
min-width="300"
|
||||
/>
|
||||
</el-table>
|
||||
</template>
|
||||
</div> </template></el-table-column
|
||||
><el-table-column
|
||||
v-for="column in visibleDefs"
|
||||
:key="column.prop"
|
||||
@@ -132,6 +188,8 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { planQuotaApi, type PlanQuota } from '@/api/pl/quota-cert'
|
||||
import { perStop, stopUsageRows } from '@/components/business/pl-plan-quota-dialog/stop-model'
|
||||
import { useListTableViewportHeight } from '@/composables/useListTableViewportHeight'
|
||||
import ListQuickSearchInput from '@/components/business/list-quick-search-input/index.vue'
|
||||
import ListToolbarEndActions from '@/components/business/list-toolbar-end-actions/index.vue'
|
||||
@@ -162,10 +220,38 @@
|
||||
loading = ref(false),
|
||||
rows = ref<(Plan & { quotaStatus: string })[]>([])
|
||||
const dialog = ref<InstanceType<typeof PlPlanQuotaDialog>>()
|
||||
const expandedIds = ref<string[]>([])
|
||||
const details = reactive<Record<string, { loading: boolean; data?: PlanQuota; error?: boolean }>>(
|
||||
{}
|
||||
)
|
||||
function clearDetails() {
|
||||
expandedIds.value = []
|
||||
Object.keys(details).forEach((id) => delete details[id])
|
||||
}
|
||||
async function loadDetail(id: string) {
|
||||
const current = epoch
|
||||
const state = reactive<{ loading: boolean; data?: PlanQuota; error?: boolean }>({
|
||||
loading: true
|
||||
})
|
||||
details[id] = state
|
||||
try {
|
||||
const value = await planQuotaApi.get(id)
|
||||
if (current === epoch && details[id] === state) state.data = value
|
||||
} catch {
|
||||
if (current === epoch && details[id] === state) state.error = true
|
||||
} finally {
|
||||
if (current === epoch && details[id] === state) state.loading = false
|
||||
}
|
||||
}
|
||||
function expand(row: { id: string }, expanded: { id: string }[]) {
|
||||
expandedIds.value = expanded.map((r) => r.id)
|
||||
if (expanded.some((r) => r.id === row.id) && !details[row.id]) void loadDetail(row.id)
|
||||
}
|
||||
let epoch = 0
|
||||
async function load() {
|
||||
const current = ++epoch
|
||||
loading.value = true
|
||||
clearDetails()
|
||||
try {
|
||||
const value = pickBxData<{ list: (Plan & { quotaStatus: string })[]; total: number }>(
|
||||
await request.get('/transport/quota-certs/plans', {
|
||||
@@ -196,6 +282,7 @@
|
||||
() => JSON.stringify([user.accessToken, user.getUserInfo]),
|
||||
() => {
|
||||
epoch++
|
||||
clearDetails()
|
||||
rows.value = []
|
||||
total.value = 0
|
||||
page.value = 1
|
||||
@@ -255,6 +342,10 @@
|
||||
const tableWrapRef = ref<HTMLElement | null>(null)
|
||||
const pagerRef = ref<HTMLElement | null>(null)
|
||||
const tableRef = ref()
|
||||
const { width: tableViewportWidth } = useElementSize(tableWrapRef)
|
||||
const expansionStyle = computed(() => ({
|
||||
width: tableViewportWidth.value > 0 ? `${tableViewportWidth.value}px` : undefined
|
||||
}))
|
||||
const { tableHeight } = useListTableViewportHeight({
|
||||
tableEl: tableWrapRef,
|
||||
pagerEl: pagerRef,
|
||||
@@ -262,3 +353,12 @@
|
||||
enabled: computed(() => !props.mobile)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.quota-expansion {
|
||||
box-sizing: border-box;
|
||||
max-width: 100%;
|
||||
padding: 16px;
|
||||
text-align: left;
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user