261 lines
6.5 KiB
Vue
261 lines
6.5 KiB
Vue
<script setup lang="ts">
|
||
import { CircleClose, Loading } from '@element-plus/icons-vue'
|
||
|
||
import ClaimBindingStep from './components/ClaimBindingStep.vue'
|
||
import ClaimConfirmStep from './components/ClaimConfirmStep.vue'
|
||
import ClaimHeaderCard from './components/ClaimHeaderCard.vue'
|
||
import ClaimResultStep from './components/ClaimResultStep.vue'
|
||
import ClaimTicketStep from './components/ClaimTicketStep.vue'
|
||
import { useKuaishouCloudClaim } from './composables/useKuaishouCloudClaim'
|
||
|
||
const props = defineProps<{
|
||
token: string
|
||
}>()
|
||
|
||
const claim = useKuaishouCloudClaim(() => props.token)
|
||
</script>
|
||
|
||
<template>
|
||
<main class="claim-page">
|
||
<ClaimHeaderCard
|
||
:order="claim.order.value"
|
||
:product="claim.product.value"
|
||
:current-step="claim.currentStep.value"
|
||
:progress-text="claim.progressText.value"
|
||
/>
|
||
|
||
<div v-if="claim.loading.value" class="content-card loading-card">
|
||
<el-icon class="large-icon spinning"><Loading /></el-icon>
|
||
<p>正在读取当前领取进度...</p>
|
||
</div>
|
||
|
||
<div v-else-if="claim.errorMessage.value" class="content-card error-card">
|
||
<el-icon class="large-icon error"><CircleClose /></el-icon>
|
||
<p>{{ claim.errorMessage.value }}</p>
|
||
</div>
|
||
|
||
<template v-else-if="claim.detail.value?.flowType === 'kuaishou_feifei' && claim.feifei.value">
|
||
<section class="content-card feifei-card">
|
||
<div class="feifei-main">
|
||
<p class="feifei-label">kuaishou-feifei</p>
|
||
<h2>{{ claim.product.value?.title || claim.orderItem.value?.skuName || '商品领取' }}</h2>
|
||
<p class="feifei-status">
|
||
{{ claim.feifei.value.rechargeStatusLabel || '待领取' }}
|
||
</p>
|
||
</div>
|
||
|
||
<dl class="feifei-meta">
|
||
<div>
|
||
<dt>订单号</dt>
|
||
<dd>{{ claim.order.value?.platformOrderId || '-' }}</dd>
|
||
</div>
|
||
<div>
|
||
<dt>平台单号</dt>
|
||
<dd>{{ claim.feifei.value.orderNo || claim.feifei.value.platformOrderNo || '-' }}</dd>
|
||
</div>
|
||
</dl>
|
||
|
||
<el-button
|
||
type="primary"
|
||
size="large"
|
||
:disabled="!claim.feifei.value.h5.rechargeUrl && !claim.feifei.value.h5.entryUrl"
|
||
@click="claim.openFeifeiUrl(false)"
|
||
>
|
||
打开领取链接
|
||
</el-button>
|
||
|
||
<p v-if="claim.task.value?.lastError" class="feifei-error">
|
||
{{ claim.task.value.lastError }}
|
||
</p>
|
||
</section>
|
||
</template>
|
||
|
||
<template v-else-if="claim.detail.value && claim.flow.value">
|
||
<ClaimTicketStep
|
||
v-if="claim.currentStep.value === 1"
|
||
:ticket-code="claim.ticketCode.value"
|
||
:can-submit-ticket="claim.canSubmitTicket.value"
|
||
:submitting="claim.submitting.value"
|
||
:is-binding-preparing="claim.isBindingPreparing.value"
|
||
:flow="claim.flow.value"
|
||
@update:ticket-code="claim.ticketCode.value = $event"
|
||
@submit-ticket="claim.submitTicket()"
|
||
/>
|
||
|
||
<ClaimBindingStep
|
||
v-else-if="claim.currentStep.value === 2"
|
||
:qr-code-data-url="claim.qrCodeDataUrl.value"
|
||
:is-binding-prepared="claim.isBindingPrepared.value"
|
||
:is-binding-preparing="claim.isBindingPreparing.value"
|
||
:is-customer-role-ready="claim.isCustomerRoleReady.value"
|
||
:confirm-role-disabled-reason="claim.confirmRoleDisabledReason.value"
|
||
:role-name="claim.roleName.value"
|
||
:role-id="claim.roleId.value"
|
||
:refreshing-role="claim.refreshingRole.value"
|
||
:confirming-role="claim.confirmingRole.value"
|
||
:rebinding-role="claim.rebindingRole.value"
|
||
:flow="claim.flow.value"
|
||
:format-date-time="claim.formatAdminDateTime"
|
||
@open-bind-url="claim.openBindUrl($event)"
|
||
@refresh-role="claim.refreshRole()"
|
||
@rebind-role="claim.rebindRole()"
|
||
@confirm-role="claim.confirmRole()"
|
||
/>
|
||
|
||
<ClaimConfirmStep
|
||
v-else-if="claim.currentStep.value === 3"
|
||
:role-name="claim.roleName.value"
|
||
:role-id="claim.roleId.value"
|
||
:product="claim.product.value"
|
||
:redeeming="claim.redeeming.value"
|
||
:rebinding-role="claim.rebindingRole.value"
|
||
@confirm-redeem="claim.confirmRedeem()"
|
||
@rebind-role="claim.rebindRole()"
|
||
/>
|
||
|
||
<ClaimResultStep
|
||
v-else
|
||
:result-title="claim.resultTitle.value"
|
||
:result-description="claim.resultDescription.value"
|
||
:result-variant="claim.resultVariant.value"
|
||
:flow="claim.flow.value"
|
||
:order="claim.order.value"
|
||
:product="claim.product.value"
|
||
:role-name="claim.roleName.value"
|
||
:role-id="claim.roleId.value"
|
||
:format-date-time="claim.formatAdminDateTime"
|
||
/>
|
||
</template>
|
||
|
||
<div v-else class="content-card error-card">
|
||
<el-icon class="large-icon error"><CircleClose /></el-icon>
|
||
<p>流程数据不完整,请联系客服处理</p>
|
||
</div>
|
||
</main>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.claim-page {
|
||
min-height: 100vh;
|
||
padding: 24px;
|
||
background:
|
||
radial-gradient(circle at top right, rgba(59, 130, 246, 0.18), transparent 28%),
|
||
linear-gradient(180deg, #f8fafc 0%, #eef4fb 100%);
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 18px;
|
||
}
|
||
|
||
.content-card {
|
||
width: 100%;
|
||
max-width: 680px;
|
||
background: rgba(255, 255, 255, 0.92);
|
||
border: 1px solid rgba(148, 163, 184, 0.16);
|
||
border-radius: 20px;
|
||
box-shadow: 0 18px 40px rgba(15, 23, 42, 0.08);
|
||
backdrop-filter: blur(12px);
|
||
padding: 28px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 18px;
|
||
}
|
||
|
||
.loading-card,
|
||
.error-card {
|
||
align-items: center;
|
||
justify-content: center;
|
||
text-align: center;
|
||
min-height: 240px;
|
||
}
|
||
|
||
.large-icon {
|
||
font-size: 44px;
|
||
}
|
||
|
||
.large-icon.success {
|
||
color: #16a34a;
|
||
}
|
||
|
||
.large-icon.error {
|
||
color: #dc2626;
|
||
}
|
||
|
||
.feifei-card {
|
||
gap: 22px;
|
||
}
|
||
|
||
.feifei-main {
|
||
display: grid;
|
||
gap: 8px;
|
||
}
|
||
|
||
.feifei-label {
|
||
margin: 0;
|
||
color: #64748b;
|
||
font-size: 13px;
|
||
}
|
||
|
||
.feifei-main h2 {
|
||
margin: 0;
|
||
font-size: 22px;
|
||
color: #0f172a;
|
||
}
|
||
|
||
.feifei-status {
|
||
margin: 0;
|
||
color: #2563eb;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.feifei-meta {
|
||
margin: 0;
|
||
display: grid;
|
||
gap: 12px;
|
||
}
|
||
|
||
.feifei-meta div {
|
||
display: grid;
|
||
gap: 4px;
|
||
}
|
||
|
||
.feifei-meta dt {
|
||
color: #64748b;
|
||
font-size: 13px;
|
||
}
|
||
|
||
.feifei-meta dd {
|
||
margin: 0;
|
||
color: #0f172a;
|
||
word-break: break-all;
|
||
}
|
||
|
||
.feifei-error {
|
||
margin: 0;
|
||
color: #b45309;
|
||
}
|
||
|
||
.spinning {
|
||
animation: spin 1s linear infinite;
|
||
}
|
||
|
||
@keyframes spin {
|
||
from {
|
||
transform: rotate(0deg);
|
||
}
|
||
to {
|
||
transform: rotate(360deg);
|
||
}
|
||
}
|
||
|
||
@media (max-width: 720px) {
|
||
.claim-page {
|
||
padding: 16px;
|
||
}
|
||
|
||
.content-card {
|
||
max-width: 100%;
|
||
}
|
||
}
|
||
</style>
|