修改订单列表重新计费

This commit is contained in:
wuweihua
2026-11-11 10:49:45 +08:00
parent 02763f092e
commit 5f679b5a6e
2 changed files with 198 additions and 16 deletions
+113 -8
View File
@@ -192,7 +192,7 @@
<el-dialog
v-model="rebillProgressVisible"
:title="rebillDialogTitle"
width="480px"
width="560px"
append-to-body
:close-on-click-modal="false"
:close-on-press-escape="true"
@@ -206,11 +206,33 @@
:striped-flow="batchLoading"
/>
<div class="rebill-progress__msg">{{ rebillProgressMessage }}</div>
<div class="rebill-progress__text">
<div v-if="!batchLoading && rebillFinished" class="rebill-result-stats">
<div class="rebill-result-stats__item">
<span class="rebill-result-stats__label">总数</span>
<strong>{{ rebillProgressTotal }}</strong>
</div>
<div class="rebill-result-stats__item is-success">
<span class="rebill-result-stats__label">成功</span>
<strong>{{ rebillProgressSuccess }}</strong>
</div>
<div class="rebill-result-stats__item is-fail">
<span class="rebill-result-stats__label">失败</span>
<strong>{{ rebillProgressFail }}</strong>
</div>
</div>
<div v-else class="rebill-progress__text">
总数 {{ rebillProgressTotal }}
/ 成功 {{ rebillProgressSuccess }}
/ 失败 {{ rebillProgressFail }}
</div>
<el-alert
v-if="!batchLoading && rebillFailDetail"
:title="rebillFailDetail"
type="warning"
:closable="false"
show-icon
class="rebill-progress__error"
/>
<p v-if="batchLoading" class="rebill-progress__hint">计费在后台进行,可收起弹窗继续操作;请勿关闭或刷新本页</p>
<template #footer>
<el-button v-if="batchLoading" @click="rebillProgressVisible = false">收起</el-button>
@@ -221,7 +243,21 @@
:loading="rebillCancelLoading"
@click="handleCancelRebill"
>取消计费</el-button>
<el-button v-else type="primary" @click="rebillProgressVisible = false">关闭</el-button>
<template v-else>
<el-button
v-if="rebillProgressFail > 0"
type="warning"
plain
@click="viewRebillFailedOrders"
>查看失败订单</el-button>
<el-button
v-if="rebillProgressFail > 0"
type="warning"
:loading="exportLoading"
@click="exportRebillFailedOrders"
>导出失败订单</el-button>
<el-button type="primary" @click="rebillProgressVisible = false">关闭</el-button>
</template>
</template>
</el-dialog>
<el-dialog
@@ -356,6 +392,7 @@ const rebillProgressStatus = ref(undefined)
const rebillProgressTotal = ref(0)
const rebillProgressSuccess = ref(0)
const rebillProgressFail = ref(0)
const rebillFailDetail = ref('')
const rebillTaskId = ref('')
const rebillCancelLoading = ref(false)
let rebillFloatHideTimer = null
@@ -429,6 +466,7 @@ const defaultParams = {
}
const columns = [
{ label: '计费状态', prop: 'billingFailStatus', align: 'center', width: 160, fixed: 'left', slot: 'billingFailStatus' },
{ label: '订单号', prop: 'orderNo', width: 160, fixed: 'left', showOverflowTooltip: true },
{ label: '运单号', prop: 'trackingNo', minWidth: 140, showOverflowTooltip: true },
{ label: '转单号', prop: 'transferNo', minWidth: 140, showOverflowTooltip: true },
@@ -442,7 +480,6 @@ const columns = [
{ label: '实重', prop: 'receiveWeight', align: 'center', width: 90, slot: 'receiveWeight' },
{ label: '收件人邮编', prop: 'destPostcode', minWidth: 120, showOverflowTooltip: true },
{ label: '订单状态', prop: 'orderStatus', align: 'center', width: 110, slot: 'orderStatus' },
{ label: '计费状态', prop: 'billingFailStatus', align: 'center', width: 140, slot: 'billingFailStatus' },
{ label: '计费时间', prop: 'bizDate', align: 'center', width: 170, parseTime: true },
// { label: '下单时间', prop: 'orderTime', align: 'center', width: 170, parseTime: true },
{ label: '提货时间', prop: 'pickupDate', align: 'center', width: 170, parseTime: true },
@@ -767,21 +804,52 @@ function applyRebillProgress(t) {
}
}
function billingFailOnlyStatuses() {
// All statuses except success(0).
return billingFailStatusOptions.map(o => o.value).filter(v => v !== 0)
}
function viewRebillFailedOrders() {
rebillProgressVisible.value = false
const fails = billingFailOnlyStatuses()
tableRef.value?.setQueryParams?.({ billingFailStatuses: fails })
tableRef.value?.handleQuery?.()
}
async function exportRebillFailedOrders() {
if (exportLoading.value) return
const fails = billingFailOnlyStatuses()
// Keep current list filters, force fail statuses for export.
tableRef.value?.setQueryParams?.({ billingFailStatuses: fails })
rebillProgressVisible.value = false
await handleExport()
}
function finishRebillFromTask(task, cancelled) {
const success = Number(task && task.success) || 0
const fail = Number(task && task.fail) || 0
const total = Number(task && task.total) || rebillProgressTotal.value || 0
rebillProgressPercent.value = Math.min(100, Number(task && task.percent) || 100)
rebillProgressStatus.value = cancelled ? 'warning' : (fail > 0 ? 'warning' : 'success')
rebillProgressTotal.value = Number(task && task.total) || rebillProgressTotal.value
rebillProgressTotal.value = total
rebillProgressSuccess.value = success
rebillProgressFail.value = fail
rebillProgressMessage.value = cancelled
? ('已取消:成功 ' + success + ' / 失败 ' + fail)
: ('完成:成功 ' + success + ' / 失败 ' + fail)
rebillFailDetail.value = fail > 0 ? String((task && (task.error || task.message)) || '').trim() : ''
if (cancelled) {
rebillProgressMessage.value = '重新计费已取消:成功 ' + success + ' / 失败 ' + fail + ' / 总数 ' + total
} else if (fail > 0) {
rebillProgressMessage.value = '重新计费完成(含失败):成功 ' + success + ' / 失败 ' + fail + ' / 总数 ' + total
} else {
rebillProgressMessage.value = '重新计费完成:成功 ' + success + ' / 失败 ' + fail + ' / 总数 ' + total
}
rebillFinished.value = true
clearRebillTaskId()
tableRef.value?.refresh?.()
// Always popup result dialog when billing finishes (even if progress was collapsed).
rebillProgressVisible.value = true
if (cancelled) ElMessage.warning(rebillProgressMessage.value)
else if (fail > 0) ElMessage.warning(rebillProgressMessage.value)
else ElMessage.success(rebillProgressMessage.value)
scheduleHideRebillFloat()
}
@@ -799,6 +867,7 @@ async function resumeRebillTask(taskId) {
rebillProgressTotal.value = 0
rebillProgressSuccess.value = 0
rebillProgressFail.value = 0
rebillFailDetail.value = ''
let superseded = false
try {
const result = await pollLocalRebillTask(taskId, applyRebillProgress)
@@ -811,6 +880,7 @@ async function resumeRebillTask(taskId) {
const task = e && e.task
rebillProgressStatus.value = 'exception'
rebillProgressMessage.value = (e && e.message) || '重新计费失败'
rebillFailDetail.value = String((task && task.error) || (e && e.message) || '').trim()
rebillFinished.value = true
if (task) {
rebillProgressPercent.value = Math.min(100, Number(task.percent) || 100)
@@ -875,6 +945,7 @@ async function runLocalRebill(payload, confirmText) {
rebillProgressTotal.value = 0
rebillProgressSuccess.value = 0
rebillProgressFail.value = 0
rebillFailDetail.value = ''
window.setTimeout(() => {
if (batchLoading.value) rebillProgressVisible.value = false
}, 600)
@@ -894,6 +965,7 @@ async function runLocalRebill(payload, confirmText) {
const task = e && e.task
rebillProgressStatus.value = 'exception'
rebillProgressMessage.value = (e && e.message) || '重新计费失败'
rebillFailDetail.value = String((task && task.error) || (e && e.message) || '').trim()
rebillFinished.value = true
if (task) {
rebillProgressPercent.value = Math.min(100, Number(task.percent) || 100)
@@ -1049,6 +1121,39 @@ onBeforeUnmount(() => {
}
.order-identifier-search { width: 100%; }
.rebill-progress__msg { margin-top: 12px; color: var(--el-text-color-regular); }
.rebill-result-stats {
display: flex;
gap: 12px;
margin-top: 14px;
}
.rebill-result-stats__item {
flex: 1;
padding: 10px 12px;
border-radius: 8px;
background: var(--el-fill-color-light);
text-align: center;
}
.rebill-result-stats__item.is-success {
background: var(--el-color-success-light-9);
}
.rebill-result-stats__item.is-fail {
background: var(--el-color-warning-light-9);
}
.rebill-result-stats__label {
display: block;
font-size: 12px;
color: var(--el-text-color-secondary);
margin-bottom: 4px;
}
.rebill-result-stats__item strong {
font-size: 20px;
line-height: 1.2;
color: var(--el-text-color-primary);
}
.rebill-progress__error {
margin-top: 12px;
}
.rebill-progress__text { margin-top: 8px; font-size: 13px; color: var(--el-text-color-secondary); }
.rebill-progress__hint { margin-top: 12px; font-size: 12px; color: var(--el-color-warning); }
.order-bill-query .export-status-float {