按实际纯币金额计算租客优惠与积分
This commit is contained in:
@@ -26,6 +26,7 @@ const evidenceDispute = ref<Dispute | null>(null)
|
||||
const result = ref('release_deposit')
|
||||
const remark = ref('')
|
||||
const amount = ref<number | undefined>()
|
||||
const actualCoinConsumedM = ref<number | undefined>()
|
||||
const currentPage = ref(1)
|
||||
const currentPageSize = ref(20)
|
||||
const total = ref(0)
|
||||
@@ -33,6 +34,15 @@ const keywordFilter = ref('')
|
||||
const statusFilter = ref('')
|
||||
const typeFilter = ref('')
|
||||
const isPartialRefund = computed(() => result.value === 'partial_refund')
|
||||
const isCompletedResult = computed(() =>
|
||||
['deduct_deposit', 'release_deposit', 'compensate_owner'].includes(result.value)
|
||||
)
|
||||
const hasValidActualCoinConsumedM = computed(
|
||||
() =>
|
||||
typeof actualCoinConsumedM.value === 'number' &&
|
||||
Number.isFinite(actualCoinConsumedM.value) &&
|
||||
actualCoinConsumedM.value >= 0
|
||||
)
|
||||
const pendingCount = computed(
|
||||
() => disputes.value.filter(item => ['open', 'processing'].includes(item.status)).length
|
||||
)
|
||||
@@ -46,6 +56,12 @@ const canSubmitArbitration = computed(() => {
|
||||
if (submitting.value || !activeDispute.value) return false
|
||||
if (!result.value || !remark.value.trim()) return false
|
||||
if (isPartialRefund.value && (!amount.value || amount.value <= 0)) return false
|
||||
if (
|
||||
isCompletedResult.value &&
|
||||
!activeDispute.value.checkout_id &&
|
||||
!hasValidActualCoinConsumedM.value
|
||||
)
|
||||
return false
|
||||
return true
|
||||
})
|
||||
function canArbitrate(row: Dispute) {
|
||||
@@ -146,6 +162,7 @@ function openArbitration(row: Dispute) {
|
||||
result.value = row.arbitration_result || 'release_deposit'
|
||||
remark.value = row.arbitration_remark || ''
|
||||
amount.value = undefined
|
||||
actualCoinConsumedM.value = row.checkout_coin_consumed_m ?? undefined
|
||||
}
|
||||
|
||||
function resetFilters() {
|
||||
@@ -276,16 +293,26 @@ async function handleArbitrate() {
|
||||
ElMessage.warning('请填写部分退款金额')
|
||||
return
|
||||
}
|
||||
if (
|
||||
isCompletedResult.value &&
|
||||
!activeDispute.value.checkout_id &&
|
||||
!hasValidActualCoinConsumedM.value
|
||||
) {
|
||||
ElMessage.warning('请填写最终实际哈夫币消耗 M')
|
||||
return
|
||||
}
|
||||
submitting.value = true
|
||||
try {
|
||||
await arbitrateDispute(activeDispute.value.id, {
|
||||
result: result.value,
|
||||
remark: remark.value.trim(),
|
||||
amount_cent: amount.value ? yuanToCent(amount.value) : undefined,
|
||||
actual_coin_consumed_m: isCompletedResult.value ? actualCoinConsumedM.value : undefined,
|
||||
})
|
||||
ElMessage.success('仲裁结果已保存,双方已收到通知')
|
||||
activeDispute.value = null
|
||||
remark.value = ''
|
||||
actualCoinConsumedM.value = undefined
|
||||
await loadDisputes()
|
||||
} catch (error) {
|
||||
ElMessage.error(readError(error, '仲裁失败'))
|
||||
@@ -488,6 +515,18 @@ async function handleArbitrate() {
|
||||
<p v-if="['deduct_deposit', 'compensate_owner'].includes(result)">
|
||||
金额表示从押金中赔付给号主的部分;不填则默认处理全额押金。
|
||||
</p>
|
||||
<div v-if="isCompletedResult" class="arbitration-field">
|
||||
<span>最终实际哈夫币消耗(M)</span>
|
||||
<el-input-number
|
||||
v-model="actualCoinConsumedM"
|
||||
class="full-control"
|
||||
:min="0"
|
||||
:max="1000000000"
|
||||
:precision="2"
|
||||
:step="1"
|
||||
placeholder="实际消耗 M"
|
||||
/>
|
||||
</div>
|
||||
<el-input
|
||||
v-model="remark"
|
||||
class="panel-action"
|
||||
@@ -639,6 +678,18 @@ async function handleArbitrate() {
|
||||
width: 280px;
|
||||
}
|
||||
|
||||
.arbitration-field {
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.arbitration-field span {
|
||||
color: #475569;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.main-cell,
|
||||
.party-cell {
|
||||
display: grid;
|
||||
|
||||
@@ -156,8 +156,7 @@ const canOfflineSettlement = computed(() => offlineSettlementAction.value?.enabl
|
||||
const canAdminCreateDispute = computed(() => canOperate.value && !order.value?.active_dispute)
|
||||
const isPlatformManaged = computed(
|
||||
() =>
|
||||
order.value?.handoff_mode === 'platform' ||
|
||||
order.value?.settlement_mode === 'platform_managed'
|
||||
order.value?.handoff_mode === 'platform' || order.value?.settlement_mode === 'platform_managed'
|
||||
)
|
||||
const offlineSettlementStatus = computed(() => order.value?.offline_settlement_status || 'none')
|
||||
// 押金暂扣:仅进行中、有实付押金、且未暂扣过的订单可暂扣。
|
||||
@@ -267,6 +266,10 @@ const hasOwnerRentBreakdown = computed(() => ownerCoinBasePriceCent.value !== nu
|
||||
const fundSplitRows = computed(() => {
|
||||
if (!order.value) return []
|
||||
const rows: FundSplitRow[] = []
|
||||
rows.push(
|
||||
{ label: '预收纯币原价', amountCent: order.value.pure_coin_original_amount_cent },
|
||||
{ label: '预收额外物品', amountCent: order.value.extra_item_original_amount_cent }
|
||||
)
|
||||
if (Number(order.value.rent_discount_amount_cent || 0) > 0) {
|
||||
rows.push(
|
||||
{ label: '原始租金', amountCent: order.value.rent_original_amount_cent },
|
||||
@@ -276,6 +279,16 @@ const fundSplitRows = computed(() => {
|
||||
}
|
||||
)
|
||||
}
|
||||
if (order.value.status === 'completed') {
|
||||
rows.push(
|
||||
{ label: '最终实际纯币原价', amountCent: order.value.actual_pure_coin_amount_cent },
|
||||
{
|
||||
label: '最终实际纯币优惠',
|
||||
amountCent: -Number(order.value.actual_pure_coin_discount_cent || 0),
|
||||
},
|
||||
{ label: '积分计算纯币基数', amountCent: order.value.growth_points_basis_cent }
|
||||
)
|
||||
}
|
||||
rows.push({ label: '租客租金', amountCent: order.value.rent_amount_cent })
|
||||
if (hasOwnerRentBreakdown.value) {
|
||||
rows.push(
|
||||
@@ -525,7 +538,9 @@ async function submitPlatformCheckoutCounter() {
|
||||
|
||||
function openAdminDispute() {
|
||||
adminDisputeForm.value = {
|
||||
type: ['pending_checkout_confirm', 'pending_checkout_accept'].includes(order.value?.status || '')
|
||||
type: ['pending_checkout_confirm', 'pending_checkout_accept'].includes(
|
||||
order.value?.status || ''
|
||||
)
|
||||
? 'checkout_amount'
|
||||
: 'cannot_login',
|
||||
targetRole: 'renter',
|
||||
@@ -886,12 +901,7 @@ function paymentPaidAt(record: AdminPayment) {
|
||||
<el-button v-if="canOfflineSettlement" type="success" @click="openOfflineSettlement">
|
||||
{{ offlineSettlementAction?.label || '确认线下结算' }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="canAdminCreateDispute"
|
||||
type="warning"
|
||||
plain
|
||||
@click="openAdminDispute"
|
||||
>
|
||||
<el-button v-if="canAdminCreateDispute" type="warning" plain @click="openAdminDispute">
|
||||
发起申诉
|
||||
</el-button>
|
||||
<el-button type="warning" :disabled="!canOperate" @click="openAction('abnormal')"
|
||||
@@ -1176,6 +1186,18 @@ function paymentPaidAt(record: AdminPayment) {
|
||||
<dt>结算租金</dt>
|
||||
<dd>{{ moneyCent(order.checkout.display_amount_cent) }}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>实际纯币原价</dt>
|
||||
<dd>{{ moneyCent(order.checkout.pure_coin_amount_cent) }}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>实际纯币优惠</dt>
|
||||
<dd>{{ moneyCent(order.checkout.pure_coin_discount_cent) }}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>折后纯币金额</dt>
|
||||
<dd>{{ moneyCent(order.checkout.pure_coin_payable_cent) }}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>退还租客</dt>
|
||||
<dd>{{ moneyCent(order.checkout.renter_refund_amount_cent) }}</dd>
|
||||
@@ -1196,6 +1218,14 @@ function paymentPaidAt(record: AdminPayment) {
|
||||
<dt>哈夫币消耗</dt>
|
||||
<dd>{{ quantity(order.checkout.coin_consumed_m) }}M</dd>
|
||||
</div>
|
||||
<div v-if="order.status === 'completed'">
|
||||
<dt>积分计算基数</dt>
|
||||
<dd>{{ moneyCent(order.growth_points_basis_cent) }}</dd>
|
||||
</div>
|
||||
<div v-if="order.status === 'completed'">
|
||||
<dt>本单成长积分</dt>
|
||||
<dd>{{ order.growth_points_awarded || 0 }}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>发起人</dt>
|
||||
<dd>ID {{ order.checkout.initiated_by }}</dd>
|
||||
@@ -1364,12 +1394,7 @@ function paymentPaidAt(record: AdminPayment) {
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
v-model="platformHandoffVisible"
|
||||
title="客服代交接"
|
||||
width="560px"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-dialog v-model="platformHandoffVisible" title="客服代交接" width="560px" destroy-on-close>
|
||||
<div v-if="order" class="dialog-body">
|
||||
<p>
|
||||
<strong>{{ order.order_no }}</strong> · 商品编号 {{ listingCode }} · {{ order.title }}
|
||||
@@ -1395,12 +1420,7 @@ function paymentPaidAt(record: AdminPayment) {
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
v-model="adminDisputeVisible"
|
||||
title="发起订单申诉"
|
||||
width="620px"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-dialog v-model="adminDisputeVisible" title="发起订单申诉" width="620px" destroy-on-close>
|
||||
<div v-if="order" class="dialog-body">
|
||||
<p>
|
||||
<strong>{{ order.order_no }}</strong> · 商品编号 {{ listingCode }} · {{ order.title }}
|
||||
@@ -1440,11 +1460,7 @@ function paymentPaidAt(record: AdminPayment) {
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="adminDisputeVisible = false">取消</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
:loading="adminDisputeSubmitting"
|
||||
@click="submitAdminDispute"
|
||||
>
|
||||
<el-button type="primary" :loading="adminDisputeSubmitting" @click="submitAdminDispute">
|
||||
发起申诉
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user