116 lines
4.2 KiB
Vue
116 lines
4.2 KiB
Vue
<template>
|
|
<div class="app-container billing-bill">
|
|
<basic-table
|
|
ref="tableRef"
|
|
:columns="columns"
|
|
:search-columns="searchColumns"
|
|
:query="queryList"
|
|
row-key="billId"
|
|
>
|
|
<template #col-product="{ row }">
|
|
{{ row.productName || '-' }} ({{ row.productCode }})
|
|
</template>
|
|
<template #col-country="{ row }">
|
|
{{ row.countryName || '-' }} ({{ row.countryCode || '-' }})
|
|
</template>
|
|
<template #col-matchSource="{ row }">
|
|
<el-tag size="small" :type="sourceTagType(row.matchSource)">{{ sourceLabel(row.matchSource) }}</el-tag>
|
|
</template>
|
|
<template #col-incomeTotal="{ row }">
|
|
<span class="payable">{{ formatMoney(row.incomeTotal) }}</span>
|
|
</template>
|
|
<template #col-payTotal="{ row }">
|
|
<span class="payable">{{ formatMoney(row.payTotal) }}</span>
|
|
</template>
|
|
<template #col-action="{ row }">
|
|
<el-button link type="primary" icon="View" @click="handleView(row)">查看</el-button>
|
|
</template>
|
|
</basic-table>
|
|
|
|
<bill-detail v-model="open" :title="title" :loading="loading" :detail="detail" />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup name="BillingBill">
|
|
import { listBill, getBill } from '@/api/price/billing'
|
|
import BillDetail from './components/BillDetail.vue'
|
|
|
|
const tableRef = ref()
|
|
const open = ref(false)
|
|
const title = ref('计费详情')
|
|
const loading = ref(false)
|
|
const detail = ref(null)
|
|
|
|
const columns = [
|
|
{ label: '订单号', prop: 'orderNo', minWidth: 140, showOverflowTooltip: true },
|
|
{ label: '运单号', prop: 'trackingNo', minWidth: 140, showOverflowTooltip: true },
|
|
{ label: '客户', prop: 'customerName', minWidth: 140, showOverflowTooltip: true },
|
|
{ label: '客户代码', prop: 'customerCode', width: 120 },
|
|
{ label: '产品', prop: 'product', minWidth: 160, slot: 'product' },
|
|
{ label: '国家', prop: 'country', minWidth: 130, slot: 'country' },
|
|
{ label: '件数', prop: 'pieces', align: 'center', width: 70 },
|
|
{ label: '计费重', prop: 'chargeWeight', align: 'center', width: 90 },
|
|
{ label: '应收总额', prop: 'incomeTotal', align: 'right', width: 120, slot: 'incomeTotal' },
|
|
{ label: '应付总额', prop: 'payTotal', align: 'right', width: 120, slot: 'payTotal' },
|
|
{ label: '计价来源', prop: 'matchSource', align: 'center', width: 130, slot: 'matchSource' },
|
|
{ label: '下单时间', prop: 'orderTime', align: 'center', width: 170, parseTime: true },
|
|
{ label: '操作', prop: 'action', align: 'center', width: 90, fixed: 'right', slot: 'action', showInToolbar: false }
|
|
]
|
|
|
|
const searchColumns = [
|
|
{ label: '订单号', prop: 'orderNo', component: 'input', placeholder: '订单号', width: '160px' },
|
|
{ label: '运单号', prop: 'trackingNo', component: 'input', placeholder: '运单号', width: '160px' },
|
|
{ label: '客户代码', prop: 'customerCode', component: 'input', placeholder: '客户代码', width: '140px' },
|
|
{ label: '产品代码', prop: 'productCode', component: 'input', placeholder: '产品代码', width: '140px' }
|
|
]
|
|
|
|
function queryList(params) {
|
|
return listBill(params)
|
|
}
|
|
|
|
function handleView(row) {
|
|
title.value = '计费详情 #' + (row.orderNo || row.billId)
|
|
open.value = true
|
|
loading.value = true
|
|
detail.value = null
|
|
getBill(row.billId).then(res => {
|
|
detail.value = res.data || null
|
|
}).finally(() => {
|
|
loading.value = false
|
|
})
|
|
}
|
|
|
|
function formatMoney(val) {
|
|
if (val === null || val === undefined || val === '') return '-'
|
|
const num = Number(val)
|
|
if (Number.isNaN(num)) return val
|
|
return num.toFixed(4)
|
|
}
|
|
|
|
function sourceLabel(source) {
|
|
const map = {
|
|
PACKAGE_FIXED: '客户固定价套餐',
|
|
PACKAGE_DISCOUNT: '客户折扣套餐',
|
|
PRODUCT_DEFAULT: '产品默认价',
|
|
FIXED: '客户固定价套餐',
|
|
DISCOUNT: '客户折扣套餐'
|
|
}
|
|
return map[source] || source || '-'
|
|
}
|
|
|
|
function sourceTagType(source) {
|
|
if (source === 'PACKAGE_FIXED' || source === 'FIXED') return 'success'
|
|
if (source === 'PACKAGE_DISCOUNT' || source === 'DISCOUNT') return 'warning'
|
|
if (source === 'PRODUCT_DEFAULT') return 'info'
|
|
return ''
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.billing-bill .payable {
|
|
color: #f56c6c;
|
|
font-weight: 600;
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
</style>
|