优化-任务列表和详情页
This commit is contained in:
@@ -4,7 +4,6 @@ import { onMounted, ref } from "vue";
|
||||
import { useAdminAction } from "@/composables/useAdminAction";
|
||||
import { useAdminListPage } from "@/composables/useAdminListPage";
|
||||
import AdminPageHeader from "@/components/admin/AdminPageHeader.vue";
|
||||
import AdminStatusTag from "@/components/admin/AdminStatusTag.vue";
|
||||
import {
|
||||
closeAdminTask,
|
||||
fetchAdminTasks,
|
||||
@@ -127,6 +126,56 @@ function resetFilters() {
|
||||
void loadTasks(1);
|
||||
}
|
||||
|
||||
function resolveResourceStageLabel(status: string) {
|
||||
const normalized = String(status || "").trim();
|
||||
const labelMap: Record<string, string> = {
|
||||
system_bound: "资源已准备",
|
||||
pending_binding: "待准备资源",
|
||||
pending_binding_prepare: "待准备资源",
|
||||
retry_pending: "待重试",
|
||||
manual_review: "人工处理",
|
||||
binding_exception: "资源异常",
|
||||
completed: "已完成",
|
||||
not_started: "未开始",
|
||||
};
|
||||
|
||||
return labelMap[normalized] || normalized || "-";
|
||||
}
|
||||
|
||||
function resolveCustomerStageLabel(status: string) {
|
||||
const normalized = String(status || "").trim();
|
||||
const labelMap: Record<string, string> = {
|
||||
not_started: "待打开链接",
|
||||
waiting_user_claim: "待打开链接",
|
||||
waiting_binding: "待客户绑定",
|
||||
link_opened: "已打开链接",
|
||||
user_binding: "客户绑定中",
|
||||
binding_confirmed: "已提交",
|
||||
binding_in_progress: "处理中",
|
||||
binding_completed: "客户已完成",
|
||||
binding_exception: "客户步骤异常",
|
||||
completed: "已完成",
|
||||
};
|
||||
|
||||
return labelMap[normalized] || normalized || "-";
|
||||
}
|
||||
|
||||
function resolveTaskMainText(item: AdminTaskListItem) {
|
||||
if (item.lastError) return "需要关注";
|
||||
if (["failed", "manual_review", "retry_pending"].includes(item.status)) return "待处理";
|
||||
if (["redeemed", "completed", "closed"].includes(item.status)) return "已完成";
|
||||
if (item.userBindingStatus === "waiting_binding") return "等待客户绑定";
|
||||
if (item.systemBindingStatus === "system_bound") return "资源已准备";
|
||||
if (item.status === "pending_binding_prepare") return "待准备资源";
|
||||
return item.status || "处理中";
|
||||
}
|
||||
|
||||
function resolveTaskTone(item: AdminTaskListItem) {
|
||||
if (item.lastError || ["failed", "manual_review", "retry_pending"].includes(item.status)) return "danger";
|
||||
if (["redeemed", "completed", "closed"].includes(item.status)) return "success";
|
||||
return "warning";
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
void loadTasks(1);
|
||||
});
|
||||
@@ -136,7 +185,7 @@ onMounted(() => {
|
||||
<div class="tasks-page list-page">
|
||||
<AdminPageHeader
|
||||
title="交付任务"
|
||||
description="更紧凑地查看任务状态、角色绑定和异常信息。"
|
||||
description="查看自动履约任务、客户步骤和异常处理。"
|
||||
>
|
||||
<template #extra>
|
||||
<span class="total-badge">共 {{ pagination.total }} 条任务</span>
|
||||
@@ -148,7 +197,7 @@ onMounted(() => {
|
||||
<div class="card-header">
|
||||
<span class="card-title">查询任务</span>
|
||||
<span class="card-desc"
|
||||
>按状态、任务号、订单号、角色标识、SKU 和日期筛选。</span
|
||||
>按状态、任务号、订单号、商品和日期筛选。</span
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
@@ -175,13 +224,13 @@ onMounted(() => {
|
||||
/>
|
||||
<el-input
|
||||
v-model="roleId"
|
||||
placeholder="角色唯一标识"
|
||||
placeholder="角色 ID"
|
||||
clearable
|
||||
@keyup.enter="loadTasks(1)"
|
||||
/>
|
||||
<el-input
|
||||
v-model="skuCode"
|
||||
placeholder="商品 SKU"
|
||||
placeholder="商品名 / SKU"
|
||||
clearable
|
||||
@keyup.enter="loadTasks(1)"
|
||||
/>
|
||||
@@ -245,7 +294,7 @@ onMounted(() => {
|
||||
size="small"
|
||||
class="tasks-table data-table"
|
||||
>
|
||||
<el-table-column label="任务 / 商品" min-width="220">
|
||||
<el-table-column label="任务 / 订单" min-width="230">
|
||||
<template #default="{ row }">
|
||||
<div class="cell-stack">
|
||||
<RouterLink
|
||||
@@ -263,6 +312,12 @@ onMounted(() => {
|
||||
>重试 {{ row.retryCount }} 次</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品" min-width="210">
|
||||
<template #default="{ row }">
|
||||
<div class="cell-stack">
|
||||
<span class="cell-title" :title="row.skuName || row.skuCode">{{
|
||||
row.skuName || row.skuCode
|
||||
}}</span>
|
||||
@@ -270,38 +325,19 @@ onMounted(() => {
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="进度" min-width="160">
|
||||
<el-table-column label="状态" min-width="250">
|
||||
<template #default="{ row }">
|
||||
<div class="cell-stack">
|
||||
<div class="progress-row">
|
||||
<span class="progress-label">任务</span>
|
||||
<AdminStatusTag :status="row.status" />
|
||||
</div>
|
||||
<div class="progress-row">
|
||||
<span class="progress-label">系统</span>
|
||||
<AdminStatusTag :status="row.systemBindingStatus" />
|
||||
</div>
|
||||
<div class="progress-row">
|
||||
<span class="progress-label">完整</span>
|
||||
<AdminStatusTag :status="row.userBindingStatus" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="角色信息" min-width="180">
|
||||
<template #default="{ row }">
|
||||
<div class="cell-stack">
|
||||
<span
|
||||
class="cell-title"
|
||||
:title="row.roleName || row.roleId || '-'"
|
||||
>{{ row.roleName || "-" }}</span
|
||||
>
|
||||
<span class="cell-subline" :title="row.roleId || '-'"
|
||||
>角色ID {{ row.roleId || "-" }}</span
|
||||
>
|
||||
<span class="cell-subline"
|
||||
>登录 {{ row.loginType || "-" }}</span
|
||||
>
|
||||
<div class="task-status-summary">
|
||||
<span class="task-main-chip" :data-tone="resolveTaskTone(row)">
|
||||
{{ resolveTaskMainText(row) }}
|
||||
</span>
|
||||
<p class="task-status-note">
|
||||
客户 {{ resolveCustomerStageLabel(row.userBindingStatus) }}
|
||||
· 资源 {{ resolveResourceStageLabel(row.systemBindingStatus) }}
|
||||
</p>
|
||||
<p v-if="row.roleName || row.roleId" class="task-status-note">
|
||||
角色 {{ row.roleName || "-" }} / {{ row.roleId || "-" }}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -343,21 +379,7 @@ onMounted(() => {
|
||||
size="small"
|
||||
type="danger"
|
||||
plain
|
||||
@click="
|
||||
runAction({
|
||||
id: row.taskId,
|
||||
action: async () => {
|
||||
const response = await retryAdminTask(row.taskId);
|
||||
if (response.data.claimUrl)
|
||||
lastClaimUrl = response.data.claimUrl;
|
||||
},
|
||||
successMessage: '任务已重试',
|
||||
confirmText: `确认重试任务 ${row.taskNo} 吗?`,
|
||||
onAfterAction: async () => {
|
||||
await loadTasks();
|
||||
},
|
||||
})
|
||||
"
|
||||
@click="handleActionCommand('retry', row)"
|
||||
>
|
||||
重试
|
||||
</el-button>
|
||||
@@ -421,37 +443,54 @@ onMounted(() => {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.progress-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
.task-status-summary {
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
min-width: 0;
|
||||
}
|
||||
.progress-row :deep(.el-tag) {
|
||||
min-width: 0;
|
||||
max-width: calc(100% - 42px);
|
||||
}
|
||||
.progress-row :deep(.el-tag__content) {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.progress-label {
|
||||
.task-main-chip {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 34px;
|
||||
min-height: 22px;
|
||||
padding: 0 7px;
|
||||
width: fit-content;
|
||||
min-height: 26px;
|
||||
padding: 0 10px;
|
||||
border-radius: var(--radius-full);
|
||||
background: #f7f9fc;
|
||||
border: 1px solid var(--border-default);
|
||||
border: 1px solid transparent;
|
||||
font-size: var(--text-xs);
|
||||
font-weight: 800;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.task-main-chip[data-tone="success"] {
|
||||
color: #0f766e;
|
||||
background: var(--color-success-light);
|
||||
border-color: #a6f4c5;
|
||||
}
|
||||
|
||||
.task-main-chip[data-tone="warning"] {
|
||||
color: #b54708;
|
||||
background: var(--color-warning-light);
|
||||
border-color: #fedf89;
|
||||
}
|
||||
|
||||
.task-main-chip[data-tone="danger"] {
|
||||
color: var(--color-danger-dark);
|
||||
background: var(--color-danger-light);
|
||||
border-color: #fecaca;
|
||||
}
|
||||
|
||||
.task-status-note {
|
||||
margin: 0;
|
||||
color: var(--text-secondary);
|
||||
font-size: 11px;
|
||||
font-size: var(--text-xs);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.task-status-note + .task-status-note {
|
||||
color: var(--text-primary);
|
||||
font-weight: 700;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.cell-error {
|
||||
|
||||
Reference in New Issue
Block a user