Files
admin-web/src/modules/overseas-master-data/components/TripOperationsFinanceCell.vue
T

41 lines
3.2 KiB
Vue
Raw Normal View History

<script setup lang="ts">
import { onBeforeUnmount, ref, watch } from 'vue'
import { useAccessPreviewStore } from '@/core/access/accessPreview'
import { getApiErrorDetails, type ApiErrorDetails } from '@/shared/api/http'
import ApiErrorMeta from '@/shared/components/ApiErrorMeta.vue'
import { getTripOperationsFinance, type TripFinanceResult } from '../api/tripOperationsFinance'
const props = defineProps<{ tripNo: string }>()
const access = useAccessPreviewStore(), result = ref<TripFinanceResult | null>(null), loading = ref(false), error = ref<ApiErrorDetails | null>(null)
let sequence = 0
async function load() {
if (!access.can('platform:finance:customer-arap:list') || !access.can('platform:fleet:operations:list') || loading.value) return
const current = ++sequence, tripNo = props.tripNo; loading.value = true; error.value = null
try { const data = await getTripOperationsFinance(tripNo); if (current === sequence) result.value = data }
catch (cause) { if (current === sequence) { result.value = null; error.value = getApiErrorDetails(cause, '财务读取失败') } }
finally { if (current === sequence) loading.value = false }
}
watch(() => props.tripNo, () => { sequence++; result.value = null; error.value = null; loading.value = false })
onBeforeUnmount(() => { sequence++ })
</script>
<template>
<span v-if="!access.can('platform:finance:customer-arap:list')">无应收读取权限</span>
<template v-else>
<el-button v-if="!result" class="density-action" :loading="loading" @click="load">{{ error ? '重试财务读取' : '查看应收/实收' }}</el-button>
<span v-if="error">{{ error.message }}<ApiErrorMeta :details="error" /></span>
<template v-if="result">
<div v-for="m in result.finance.totals" :key="m.currency">{{ m.currency }} 应收 {{ m.receivableAmount.toFixed(2) }} / 实收 {{ !result.receiptsVisible ? '无读取权限' : m.receivedAmount == null ? '待分配' : m.receivedAmount.toFixed(2) }}</div>
<span v-if="!result.finance.totals.length || result.finance.status === 'PENDING_ALLOCATION' || result.attributionStatus === 'PENDING_ALLOCATION'">完整金额待分配</span>
<el-popover trigger="click" :width="620" placement="left">
<div class="finance-source-details"><p>{{ result.attributionReason }}</p><p>{{ result.finance.reason }}</p>
<p>排车来源:{{ result.dispatchNos.join(' / ') || '—' }}</p>
<div v-for="s in result.finance.sources" :key="`${s.customerId}:${s.businessNo}:${s.sourceNo}:${s.feeItemName}:${s.sourceVersion}`">{{ s.businessNo }} · {{ s.sourceNo || '—' }} · {{ s.feeItemName }} · 版本 {{ s.sourceVersion }} · {{ s.currency }} {{ s.amount.toFixed(2) }}</div>
<div v-for="d in result.finance.documents" :key="d.billNo">{{ d.billNo }} · {{ d.currency }} {{ d.receivedAmount == null ? '待分配' : d.receivedAmount.toFixed(2) }} · {{ d.reason }}</div>
</div><template #reference><el-button class="density-action">金额来源</el-button></template>
</el-popover>
<el-button class="density-action" :loading="loading" @click="load">刷新</el-button>
</template>
</template>
</template>
<style scoped>.finance-source-details { max-height: 50vh; overflow: auto; }</style>