180 lines
6.1 KiB
Vue
180 lines
6.1 KiB
Vue
<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>
|