提交第三方接口订单同步功能
This commit is contained in:
@@ -25,3 +25,29 @@ export function getQuote(quoteId) {
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
/** Sync order receivable bill */
|
||||
export function billOrder(data) {
|
||||
return request({
|
||||
url: '/price/billing/bill',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/** Receivable bill list */
|
||||
export function listBill(query) {
|
||||
return request({
|
||||
url: '/price/billing/bill/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
/** Receivable bill detail */
|
||||
export function getBill(billId) {
|
||||
return request({
|
||||
url: '/price/billing/bill/' + billId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,244 @@
|
||||
<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-payableTotal="{ row }">
|
||||
<span class="payable">{{ formatMoney(row.payableTotal) }}</span>
|
||||
</template>
|
||||
<template #col-action="{ row }">
|
||||
<el-button link type="primary" icon="View" @click="handleView(row)">查看</el-button>
|
||||
</template>
|
||||
</basic-table>
|
||||
|
||||
<el-drawer v-model="open" size="780px" :title="title" append-to-body>
|
||||
<div v-loading="loading">
|
||||
<el-empty v-if="!detail" description="暂无详情" />
|
||||
<div v-else class="bill-detail">
|
||||
<div class="sec-title">订单信息</div>
|
||||
<el-descriptions :column="2" border size="small">
|
||||
<el-descriptions-item label="订单号">{{ detail.orderNo || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="运单号">{{ detail.trackingNo || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="客户">{{ displayCustomer(detail) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="仓库">{{ detail.warehouseCode || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="发件人">{{ detail.shipperName || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="收件人">{{ detail.consigneeName || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="目的国/地区">{{ (detail.countryName || '-') + ' (' + (detail.countryCode || '-') + ')' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="目的邮编">{{ detail.destPostcode || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="件数">{{ detail.pieces != null ? detail.pieces : '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="尺寸(cm)">{{ dimLabel(detail) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="实重(kg)">{{ formatMoney(detail.actualWeight) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="材积重(kg)">{{ formatMoney(detail.volumeWeight) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="体积(m³)">{{ formatMoney(detail.volume) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="下单时间">{{ formatDateTime(detail.orderTime) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="订单备注" :span="2">{{ detail.orderRemark || '-' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
|
||||
<div class="sec-title">计费信息</div>
|
||||
<el-descriptions :column="2" border size="small">
|
||||
<el-descriptions-item label="产品">{{ (detail.productName || '-') + ' (' + (detail.productCode || '-') + ')' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="计费重量(kg)">{{ detail.chargeWeight ?? detail.weight ?? '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="重量段">{{ detail.weightLabel || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="计费日期">{{ formatDate(detail.bizDate) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="计价来源">
|
||||
<el-tag size="small" :type="sourceTagType(detail.matchSource)">{{ sourceLabel(detail.matchSource) }}</el-tag>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="套餐">{{ detail.priceSetName || '-' }} {{ detail.priceSetCode ? '(' + detail.priceSetCode + ')' : '' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="币种">
|
||||
<dict-tag :options="bms_currency" :value="displayCurrency(detail.currency)" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="取值方式">{{ roundModeLabel(detail.roundMode) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="运费单价">{{ formatMoney(detail.freightRate) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="运费金额">{{ formatMoney(detail.freightAmount) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="挂号费">{{ formatMoney(detail.registrationFee) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="附加费">{{ formatMoney(detail.surchargeAmount) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="应收总额">
|
||||
<span class="payable">{{ formatMoney(detail.payableTotal) }}</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="命中说明" :span="2">{{ detail.matchMessage || '-' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
|
||||
<el-table
|
||||
v-if="detail.feeDetails && detail.feeDetails.length"
|
||||
:data="detail.feeDetails"
|
||||
border
|
||||
size="small"
|
||||
class="fee-table"
|
||||
>
|
||||
<el-table-column label="费用名称" min-width="140" show-overflow-tooltip>
|
||||
<template #default="{ row }">{{ displayFeeName(row) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="费用类型" width="110" align="center">
|
||||
<template #default="{ row }">{{ feeTypeLabel(row.feeType) || row.feeType }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="金额" min-width="120" align="right">
|
||||
<template #default="{ row }">{{ formatMoney(row.amount) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="币种" width="90" align="center">
|
||||
<template #default="{ row }">
|
||||
<dict-tag :options="bms_currency" :value="displayCurrency(row.currency)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="说明" min-width="160" show-overflow-tooltip>
|
||||
<template #default="{ row }">{{ row.remark || '-' }}</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="BillingBill">
|
||||
import { listBill, getBill } from '@/api/price/billing'
|
||||
|
||||
const { bms_fee_type, bms_currency } = useDict('bms_fee_type', 'bms_currency')
|
||||
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: 'payableTotal', align: 'right', width: 120, slot: 'payableTotal' },
|
||||
{ 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 displayCustomer(row) {
|
||||
if (row.customerName && row.customerCode) return row.customerName + ' (' + row.customerCode + ')'
|
||||
return row.customerName || row.customerCode || row.customerId || '-'
|
||||
}
|
||||
|
||||
function dimLabel(row) {
|
||||
if (row.pkgLength == null && row.pkgWidth == null && row.pkgHeight == null) return '-'
|
||||
return [row.pkgLength, row.pkgWidth, row.pkgHeight].map(v => v == null ? '-' : v).join(' × ')
|
||||
}
|
||||
|
||||
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 formatDate(val) {
|
||||
if (!val) return '-'
|
||||
const d = new Date(val)
|
||||
if (Number.isNaN(d.getTime())) return val
|
||||
return d.toISOString().slice(0, 10)
|
||||
}
|
||||
|
||||
function formatDateTime(val) {
|
||||
if (!val) return '-'
|
||||
const d = new Date(val)
|
||||
if (Number.isNaN(d.getTime())) return val
|
||||
const pad = n => String(n).padStart(2, '0')
|
||||
return d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate()) + ' ' + pad(d.getHours()) + ':' + pad(d.getMinutes()) + ':' + pad(d.getSeconds())
|
||||
}
|
||||
|
||||
function sourceLabel(source) {
|
||||
const map = {
|
||||
PACKAGE_FIXED: '客户固定价套餐',
|
||||
PACKAGE_DISCOUNT: '客户折扣套餐',
|
||||
PRODUCT_DEFAULT: '产品默认价',
|
||||
FIXED: '客户固定价套餐',
|
||||
DISCOUNT: '客户折扣套餐'
|
||||
}
|
||||
return map[source] || source || '-'
|
||||
}
|
||||
|
||||
function roundModeLabel(mode) {
|
||||
const map = { UP: '向上取值', DOWN: '向下取整', HALF_UP: '四舍五入' }
|
||||
return map[mode] || mode || '四舍五入'
|
||||
}
|
||||
|
||||
function feeTypeLabel(type) {
|
||||
const found = (bms_fee_type.value || []).find(d => d.value === type)
|
||||
return found ? found.label : ''
|
||||
}
|
||||
|
||||
function displayCurrency(v) {
|
||||
if (!v || v === 'RMB' || v === 'rmb') return 'CNY'
|
||||
return v
|
||||
}
|
||||
|
||||
function displayFeeName(row) {
|
||||
const typeLabel = feeTypeLabel(row.feeType)
|
||||
const name = String(row.feeName || row.fee_name || '').trim()
|
||||
const isSurcharge = row.feeType === 'SURCHARGE' || row.feeType === '附加费'
|
||||
if (isSurcharge && name && name !== typeLabel && name !== 'SURCHARGE' && name !== '附加费') {
|
||||
return name
|
||||
}
|
||||
return name || typeLabel || row.feeType || '-'
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
.billing-bill .sec-title {
|
||||
margin: 12px 0 8px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.billing-bill .sec-title:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
.billing-bill .fee-table {
|
||||
margin-top: 12px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user