新增客服一键交接功能

This commit is contained in:
yml2213
2026-08-15 17:27:35 +08:00
parent d9f552577a
commit 4c1fe7439d
12 changed files with 437 additions and 1 deletions
@@ -6,6 +6,7 @@ import { useRoute } from 'vue-router'
import {
adminCloseOrder,
adminForceHandoff,
adminHoldDeposit,
adminMarkOfflineSettlement,
adminMarkOrderAbnormal,
@@ -66,6 +67,9 @@ const refundStatus = ref<RefundStatus | null>(null)
const platformHandoffVisible = ref(false)
const platformHandoffContent = ref('')
const platformHandoffReason = ref('')
const forceHandoffVisible = ref(false)
const forceHandoffContent = ref('')
const forceHandoffReason = ref('')
const platformCheckoutCounterVisible = ref(false)
const platformCheckoutCounterForm = ref({
consumableAmountYuan: 0,
@@ -126,6 +130,7 @@ const canOperate = computed(
)
const resetAction = computed(() => order.value?.admin_actions?.reset_handoff)
const platformHandoffAction = computed(() => order.value?.admin_actions?.platform_handoff)
const forceHandoffAction = computed(() => order.value?.admin_actions?.force_handoff)
const platformCheckoutConfirmAction = computed(
() => order.value?.admin_actions?.platform_checkout_confirm
)
@@ -143,6 +148,12 @@ const resetActionLabel = computed(() => {
})
const canResetHandoff = computed(() => resetAction.value?.enabled === true)
const canPlatformHandoff = computed(() => platformHandoffAction.value?.enabled === true)
const canForceHandoff = computed(() => forceHandoffAction.value?.enabled === true)
const forceHandoffNeedsContent = computed(
() =>
order.value?.handoff_status === 'pending_owner' ||
order.value?.handoff_status === 'owner_timeout'
)
const canPlatformCheckoutConfirm = computed(
() => platformCheckoutConfirmAction.value?.enabled === true
)
@@ -498,6 +509,39 @@ async function submitPlatformHandoff() {
}
}
function openForceHandoff() {
forceHandoffContent.value = ''
forceHandoffReason.value = ''
forceHandoffVisible.value = true
}
async function submitForceHandoff() {
if (!order.value) return
if (!forceHandoffReason.value.trim()) {
ElMessage.warning('请填写客服操作原因')
return
}
if (forceHandoffNeedsContent.value && !forceHandoffContent.value.trim()) {
ElMessage.warning('当前尚无交接说明,请填写交接内容')
return
}
platformSubmitting.value = true
try {
await adminForceHandoff(
order.value.id,
forceHandoffContent.value.trim(),
forceHandoffReason.value.trim()
)
ElMessage.success('客服已确认交接,订单进入使用中')
forceHandoffVisible.value = false
await loadOrder()
} catch (error) {
ElMessage.error(readError(error, '客服一键交接失败'))
} finally {
platformSubmitting.value = false
}
}
function openPlatformCheckoutCounter() {
const checkout = order.value?.checkout
platformCheckoutCounterForm.value = {
@@ -880,6 +924,9 @@ function paymentPaidAt(record: AdminPayment) {
>
{{ platformHandoffAction?.label || '客服代交接' }}
</el-button>
<el-button v-if="canForceHandoff" type="warning" @click="openForceHandoff">
{{ forceHandoffAction?.label || '客服一键交接' }}
</el-button>
<el-button
v-if="canPlatformCheckoutConfirm"
type="primary"
@@ -1433,6 +1480,39 @@ function paymentPaidAt(record: AdminPayment) {
</template>
</el-dialog>
<el-dialog v-model="forceHandoffVisible" title="客服一键交接" width="560px" destroy-on-close>
<div v-if="order" class="dialog-body">
<p>
<strong>{{ order.order_no }}</strong> · 商品编号 {{ listingCode }} · {{ order.title }}
</p>
<el-alert
title="确认后将跳过号主交接与租客确认步骤,订单会立即进入使用中并开始计算租期。"
type="warning"
:closable="false"
show-icon
/>
<el-input
v-if="forceHandoffNeedsContent"
v-model="forceHandoffContent"
type="textarea"
:rows="5"
placeholder="填写可供租客查看的交接说明"
/>
<el-input
v-model="forceHandoffReason"
type="textarea"
:rows="3"
placeholder="填写客服确认双方已完成交接的原因"
/>
</div>
<template #footer>
<el-button @click="forceHandoffVisible = false">取消</el-button>
<el-button type="warning" :loading="platformSubmitting" @click="submitForceHandoff">
确认一键交接
</el-button>
</template>
</el-dialog>
<el-dialog v-model="adminDisputeVisible" title="发起订单申诉" width="620px" destroy-on-close>
<div v-if="order" class="dialog-body">
<p>
@@ -78,6 +78,7 @@ export interface Order {
export interface AdminActions {
reset_handoff?: AdminAction
platform_handoff?: AdminAction
force_handoff?: AdminAction
platform_checkout_confirm?: AdminAction
platform_checkout_counter?: AdminAction
platform_checkout_dispute?: AdminAction
@@ -418,6 +419,14 @@ export async function adminPlatformHandoff(id: number, content: string, reason:
return data.data
}
export async function adminForceHandoff(id: number, content: string, reason: string) {
const { data } = await apiClient.post<ApiResponse<{ received: boolean }>>(
`/admin/orders/${id}/force-handoff`,
{ content, reason }
)
return data.data
}
export async function adminPlatformCheckoutConfirm(id: number, reason: string) {
const { data } = await apiClient.post<ApiResponse<{ confirmed: boolean }>>(
`/admin/orders/${id}/platform-checkout/confirm`,
@@ -242,6 +242,7 @@ export function formatHandoffRecordType(type: string) {
const typeMap: Record<string, string> = {
owner_handoff: '卖家交接',
platform_handoff: '客服代交接',
admin_force_handoff: '客服一键交接',
renter_checkout: '买家结账',
owner_counter_checkout: '卖家反驳结账',
platform_checkout_counter: '客服修改结账',