Files
order_site/apps/frontend/src/components/admin/AdminPlatformNinetyoneSection.vue
T
2026-05-14 19:05:08 +08:00

180 lines
6.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import type { AdminNinetyoneOrderItem, AdminNinetyoneOrderListResult } from '@/types/admin'
import { formatAdminDateTime } from '@/utils/admin-time'
type Props = {
ninetyoneLoading: boolean
ninetyoneActionLoadingId: number | null
ninetyoneResultError: string
ninetyoneStatus: 'pending_config' | 'all' | 'manual_failed'
ninetyoneOrders: AdminNinetyoneOrderListResult
ninetyoneStats: {
total: number
currentCount: number
pendingCount: number
failedCount: number
taskReadyCount: number
}
loadNinetyoneOrders: (page?: number) => void | Promise<void>
handleNinetyoneStatusChange: (status: 'pending_config' | 'all' | 'manual_failed') => void | Promise<void>
handleNinetyoneRetryOrder: (item: AdminNinetyoneOrderItem) => void | Promise<void>
handleNinetyoneFailOrder: (item: AdminNinetyoneOrderItem) => void | Promise<void>
}
defineProps<Props>()
</script>
<template>
<div class="platform-section">
<!-- 说明信息 -->
<el-card class="section-card">
<template #header>
<span class="card-title">说明信息</span>
</template>
<el-descriptions :column="1" border size="small">
<el-descriptions-item label="职责">
接收 91卡券推送订单,未命中履约配置时先进入待补全队列,补完商品规则后可手动重试生成任务。
</el-descriptions-item>
<el-descriptions-item label="处理建议">
先到"快手 Cloud 新履约"页为 91 的 productNo 配置规则,再回到这里点击重试。
</el-descriptions-item>
</el-descriptions>
</el-card>
<!-- 订单队列 -->
<el-card class="section-card">
<template #header>
<div class="card-header">
<div>
<span class="card-title">91卡券订单队列</span>
<p class="card-desc">
当前筛选 {{ ninetyoneStats.currentCount }} 条,总计 {{ ninetyoneStats.total }} 条,已生成任务 {{ ninetyoneStats.taskReadyCount }} 条。
</p>
</div>
<div class="card-actions">
<el-radio-group
:model-value="ninetyoneStatus"
size="small"
@update:model-value="(v: string | number | boolean | undefined) => handleNinetyoneStatusChange(v as 'pending_config' | 'all' | 'manual_failed')"
>
<el-radio-button value="pending_config">待补全</el-radio-button>
<el-radio-button value="manual_failed">失败</el-radio-button>
<el-radio-button value="all">全部</el-radio-button>
</el-radio-group>
<el-button :loading="ninetyoneLoading" @click="loadNinetyoneOrders(ninetyoneOrders.page)">刷新</el-button>
</div>
</div>
</template>
<el-alert
v-if="ninetyoneResultError"
:title="ninetyoneResultError"
type="error"
show-icon
:closable="false"
style="margin-bottom: 16px"
/>
<el-table
:data="ninetyoneOrders.items"
stripe
size="small"
v-loading="ninetyoneLoading"
element-loading-text="正在读取 91卡券订单..."
>
<el-table-column label="订单" min-width="180">
<template #default="{ row }">
<div>
<div style="font-weight: 600">{{ row.orderNo }}</div>
<div style="font-size: var(--text-xs); color: var(--text-muted)">{{ row.outTradeNo || '-' }}</div>
</div>
</template>
</el-table-column>
<el-table-column label="商品" min-width="180">
<template #default="{ row }">
<div>
<div style="font-weight: 600">{{ row.productName || row.productNo || '-' }}</div>
<div style="font-size: var(--text-xs); color: var(--text-muted)">productNo: {{ row.productNo || '-' }}</div>
<div style="font-size: var(--text-xs); color: var(--text-muted)">数量:{{ row.buyNum || 0 }}</div>
</div>
</template>
</el-table-column>
<el-table-column label="状态" min-width="140">
<template #default="{ row }">
<div>
<el-tag size="small">{{ row.orderStatus }}</el-tag>
<div style="font-size: var(--text-xs); color: var(--text-muted); margin-top: 4px">任务 {{ row.taskCount }}</div>
<div v-if="row.failReason" style="font-size: var(--text-xs); color: var(--color-danger)">{{ row.failReason }}</div>
</div>
</template>
</el-table-column>
<el-table-column label="时间" width="180">
<template #default="{ row }">{{ formatAdminDateTime(row.updatedAt || row.createdAt) }}</template>
</el-table-column>
<el-table-column label="操作" width="200" align="center">
<template #default="{ row }">
<el-button
:loading="ninetyoneActionLoadingId === row.orderId"
size="small"
type="primary"
@click="handleNinetyoneRetryOrder(row)"
>
重试生成任务
</el-button>
<el-button
v-if="row.orderStatus !== 'manual_failed'"
:loading="ninetyoneActionLoadingId === row.orderId"
size="small"
type="danger"
@click="handleNinetyoneFailOrder(row)"
>
标记失败
</el-button>
</template>
</el-table-column>
<template #empty>
<el-empty description="当前没有 91卡券订单。" :image-size="60" />
</template>
</el-table>
</el-card>
</div>
</template>
<style scoped>
.platform-section {
display: grid;
gap: var(--space-4);
}
.section-card {
border-radius: var(--radius-lg);
}
.card-title {
font-size: var(--text-lg);
font-weight: 600;
color: var(--text-primary);
}
.card-desc {
margin: var(--space-1) 0 0;
font-size: var(--text-sm);
color: var(--text-secondary);
}
.card-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
flex-wrap: wrap;
gap: var(--space-3);
}
.card-actions {
display: flex;
gap: var(--space-2);
flex-shrink: 0;
flex-wrap: wrap;
}
</style>