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

41 lines
3.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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>