使用element ui
This commit is contained in:
@@ -9,21 +9,12 @@
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.info-card,
|
||||
.hero-card,
|
||||
.error-copy {
|
||||
padding: 18px;
|
||||
border-radius: var(--radius-lg);
|
||||
background: var(--bg-surface);
|
||||
border: 1px solid var(--border-default);
|
||||
}
|
||||
|
||||
.info-card p {
|
||||
.section-card p {
|
||||
margin: 10px 0 0;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.info-card h3 {
|
||||
.section-card h3 {
|
||||
margin: 0 0 var(--space-3);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
@@ -110,10 +101,6 @@
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.error-copy {
|
||||
color: var(--color-danger);
|
||||
}
|
||||
|
||||
.action-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
@@ -147,23 +134,6 @@
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.data-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.data-table th,
|
||||
.data-table td {
|
||||
padding: var(--space-3) 10px;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid var(--border-default);
|
||||
}
|
||||
|
||||
.data-table th {
|
||||
width: 160px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.status-stack {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
@@ -252,11 +222,16 @@
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.field-block {
|
||||
display: grid;
|
||||
gap: var(--space-2);
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
.admin-panel :deep(.el-form-item) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.admin-panel :deep(.el-form-item__label) {
|
||||
color: var(--text-secondary);
|
||||
font-size: var(--text-xs);
|
||||
font-weight: 700;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.manual-hint {
|
||||
|
||||
@@ -65,7 +65,7 @@ onMounted(loadDetail)
|
||||
<section class="admin-panel">
|
||||
<AdminPageHeader title="任务详情" description="查看任务全量信息并执行人工操作。" />
|
||||
|
||||
<p v-if="errorMessage" class="error-copy">{{ errorMessage }}</p>
|
||||
<el-alert v-if="errorMessage" :title="errorMessage" type="error" show-icon :closable="false" />
|
||||
|
||||
<el-skeleton v-if="loading" :rows="6" animated />
|
||||
|
||||
@@ -83,16 +83,52 @@ onMounted(loadDetail)
|
||||
:action-loading="actionLoading"
|
||||
:can-manage-task-lifecycle="canManageTaskLifecycle"
|
||||
:can-close-tasks="canCloseTasks"
|
||||
@retry="runAction(() => retryAdminTask(detail!.task.taskId), '任务已重试', `确认重试任务 ${detail!.task.taskNo} 吗?`)"
|
||||
@regenerate-claim-link="runAction(() => regenerateAdminTaskClaimLink(detail!.task.taskId), '领取链接已重新生成', `确认重新生成任务 ${detail!.task.taskNo} 的领取链接吗?旧链接会失效。`)"
|
||||
@confirm-role="runAction(() => confirmAdminTaskAssistedRole(detail!.task.taskId), '角色已确认', `确认以客服身份锁定任务 ${detail!.task.taskNo} 当前识别到的角色信息吗?`)"
|
||||
@support-redeem="runAction(() => redeemAdminTaskAssisted(detail!.task.taskId), '兑换任务已启动', `确认开始执行任务 ${detail!.task.taskNo} 的自动兑换吗?`)"
|
||||
@retry="
|
||||
runAction(
|
||||
() => retryAdminTask(detail!.task.taskId),
|
||||
'任务已重试',
|
||||
`确认重试任务 ${detail!.task.taskNo} 吗?`,
|
||||
)
|
||||
"
|
||||
@regenerate-claim-link="
|
||||
runAction(
|
||||
() => regenerateAdminTaskClaimLink(detail!.task.taskId),
|
||||
'领取链接已重新生成',
|
||||
`确认重新生成任务 ${detail!.task.taskNo} 的领取链接吗?旧链接会失效。`,
|
||||
)
|
||||
"
|
||||
@confirm-role="
|
||||
runAction(
|
||||
() => confirmAdminTaskAssistedRole(detail!.task.taskId),
|
||||
'角色已确认',
|
||||
`确认以客服身份锁定任务 ${detail!.task.taskNo} 当前识别到的角色信息吗?`,
|
||||
)
|
||||
"
|
||||
@support-redeem="
|
||||
runAction(
|
||||
() => redeemAdminTaskAssisted(detail!.task.taskId),
|
||||
'兑换任务已启动',
|
||||
`确认开始执行任务 ${detail!.task.taskNo} 的自动兑换吗?`,
|
||||
)
|
||||
"
|
||||
@prepare-kuaishou-cloud="submitKuaishouCloudPrepare"
|
||||
@dispatch-kuaishou-cloud="submitKuaishouCloudDispatch"
|
||||
@return-kuaishou-cloud="submitKuaishouCloudReturnNumber"
|
||||
@mark-manual-review="runAction(() => markAdminTaskManualReview(detail!.task.taskId), '任务已转人工处理', `确认将任务 ${detail!.task.taskNo} 转为人工处理吗?`)"
|
||||
@mark-manual-review="
|
||||
runAction(
|
||||
() => markAdminTaskManualReview(detail!.task.taskId),
|
||||
'任务已转人工处理',
|
||||
`确认将任务 ${detail!.task.taskNo} 转为人工处理吗?`,
|
||||
)
|
||||
"
|
||||
@submit-manual-dispatch="submitManualDispatch"
|
||||
@close-task="runAction(() => closeAdminTask(detail!.task.taskId), '任务已关闭', `确认关闭任务 ${detail!.task.taskNo} 吗?关闭后不会自动继续推进。`)"
|
||||
@close-task="
|
||||
runAction(
|
||||
() => closeAdminTask(detail!.task.taskId),
|
||||
'任务已关闭',
|
||||
`确认关闭任务 ${detail!.task.taskNo} 吗?关闭后不会自动继续推进。`,
|
||||
)
|
||||
"
|
||||
/>
|
||||
|
||||
<AdminTaskInfoSection
|
||||
@@ -123,17 +159,20 @@ onMounted(loadDetail)
|
||||
:auto-delivery-summary="resolveTaskAutoDeliverySummary(detail)"
|
||||
/>
|
||||
|
||||
<AdminTaskRedeemResolutionSection
|
||||
v-if="detail.redeemResolution"
|
||||
:detail="detail"
|
||||
/>
|
||||
<AdminTaskRedeemResolutionSection v-if="detail.redeemResolution" :detail="detail" />
|
||||
|
||||
<AdminTaskInventoryBindingsSection
|
||||
v-if="!isKuaishouCloudTask"
|
||||
:detail="detail"
|
||||
:can-view-sensitive-task-data="canViewSensitiveTaskData"
|
||||
:action-loading="actionLoading"
|
||||
@release-binding="runAction(() => releaseAdminTaskInventoryBinding(detail!.task.taskId, $event), '库存绑定已释放', `确认释放该库存绑定吗?`)"
|
||||
@release-binding="
|
||||
runAction(
|
||||
() => releaseAdminTaskInventoryBinding(detail!.task.taskId, $event),
|
||||
'库存绑定已释放',
|
||||
`确认释放该库存绑定吗?`,
|
||||
)
|
||||
"
|
||||
/>
|
||||
|
||||
<AdminTaskManualDispatchSection
|
||||
@@ -146,10 +185,7 @@ onMounted(loadDetail)
|
||||
@submit="submitManualDispatch"
|
||||
/>
|
||||
|
||||
<AdminTaskEventsSection
|
||||
v-if="detail.events.length > 0"
|
||||
:detail="detail"
|
||||
/>
|
||||
<AdminTaskEventsSection v-if="detail.events.length > 0" :detail="detail" />
|
||||
|
||||
<AdminTaskScreenshotSection
|
||||
v-if="detail.screenshotUrl"
|
||||
@@ -159,7 +195,6 @@ onMounted(loadDetail)
|
||||
</template>
|
||||
|
||||
<el-empty v-else description="任务不存在或已被删除" />
|
||||
|
||||
</section>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { onMounted, ref } from "vue";
|
||||
|
||||
import { useAdminAction } from "@/composables/useAdminAction";
|
||||
import { useAdminListPage } from "@/composables/useAdminListPage";
|
||||
@@ -130,6 +130,10 @@ function resetFilters() {
|
||||
dateTo.value = "";
|
||||
void loadTasks(1);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
void loadTasks(1);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -14,30 +14,28 @@ defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="info-card">
|
||||
<el-card shadow="never" class="section-card">
|
||||
<h3>咸鱼自动发货</h3>
|
||||
<p class="section-copy">
|
||||
这里展示这条任务最近一次触发咸鱼自动发货的状态、原因和接口回执摘要。
|
||||
</p>
|
||||
<p class="section-copy">这里展示这条任务最近一次触发咸鱼自动发货的状态、原因和接口回执摘要。</p>
|
||||
|
||||
<div class="redeem-summary-grid">
|
||||
<article class="redeem-summary-card">
|
||||
<el-card shadow="never" class="redeem-summary-card">
|
||||
<span>当前状态</span>
|
||||
<div class="auto-delivery-tag-line">
|
||||
<AdminStatusTag :status="autoDeliveryStatus" />
|
||||
</div>
|
||||
</article>
|
||||
<article class="redeem-summary-card">
|
||||
</el-card>
|
||||
<el-card shadow="never" class="redeem-summary-card">
|
||||
<span>触发来源</span>
|
||||
<strong>{{
|
||||
formatAutoDeliveryTrigger(detail.task.agisoAutoDelivery?.trigger || '')
|
||||
}}</strong>
|
||||
</article>
|
||||
<article class="redeem-summary-card">
|
||||
</el-card>
|
||||
<el-card shadow="never" class="redeem-summary-card">
|
||||
<span>最近执行</span>
|
||||
<strong>{{ formatAdminDateTime(detail.task.agisoAutoDelivery?.updatedAt) }}</strong>
|
||||
</article>
|
||||
<article class="redeem-summary-card">
|
||||
</el-card>
|
||||
<el-card shadow="never" class="redeem-summary-card">
|
||||
<span>接口回执</span>
|
||||
<strong>
|
||||
{{
|
||||
@@ -47,7 +45,7 @@ defineProps<Props>()
|
||||
: '-')
|
||||
}}
|
||||
</strong>
|
||||
</article>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<div class="auto-delivery-note">
|
||||
@@ -62,7 +60,7 @@ defineProps<Props>()
|
||||
请求 ID:{{ detail.task.agisoAutoDelivery.requestId }}
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style scoped src="../AdminTaskDetail.css"></style>
|
||||
|
||||
@@ -11,24 +11,26 @@ defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="info-card">
|
||||
<el-card shadow="never" class="section-card">
|
||||
<h3>任务事件</h3>
|
||||
<table class="data-table">
|
||||
<tbody>
|
||||
<tr v-for="event in detail.events" :key="event.eventId">
|
||||
<th>{{ formatTaskEventType(event.eventType) }}</th>
|
||||
<td>
|
||||
<div class="event-copy">
|
||||
{{ formatTaskEventPayload(event.payload) }}
|
||||
</div>
|
||||
<div class="event-time">
|
||||
{{ formatAdminDateTime(event.createdAt) }}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
<el-table :data="detail.events" size="small">
|
||||
<el-table-column label="事件" width="180">
|
||||
<template #default="{ row: event }">
|
||||
{{ formatTaskEventType(event.eventType) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="内容">
|
||||
<template #default="{ row: event }">
|
||||
<div class="event-copy">
|
||||
{{ formatTaskEventPayload(event.payload) }}
|
||||
</div>
|
||||
<div class="event-time">
|
||||
{{ formatAdminDateTime(event.createdAt) }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style scoped src="../AdminTaskDetail.css"></style>
|
||||
|
||||
@@ -17,7 +17,11 @@ defineProps<Props>()
|
||||
|
||||
<template>
|
||||
<!-- Kuaishou Cloud hero card -->
|
||||
<section v-if="isKuaishouCloudTask && detail.kuaishouCloudFulfillment" class="hero-card">
|
||||
<el-card
|
||||
v-if="isKuaishouCloudTask && detail.kuaishouCloudFulfillment"
|
||||
shadow="never"
|
||||
class="section-card hero-card"
|
||||
>
|
||||
<div class="hero-copy">
|
||||
<span class="hero-eyebrow">{{ detail.task.executorKey || 'task' }}</span>
|
||||
<h2>{{ detail.task.taskNo }}</h2>
|
||||
@@ -29,14 +33,15 @@ defineProps<Props>()
|
||||
</p>
|
||||
</div>
|
||||
<div class="hero-meta-grid">
|
||||
<article
|
||||
<el-card
|
||||
v-for="card in summaryCards"
|
||||
:key="card.label"
|
||||
shadow="never"
|
||||
:class="['hero-metric', `hero-metric--${card.tone}`]"
|
||||
>
|
||||
<span>{{ card.label }}</span>
|
||||
<strong>{{ card.value }}</strong>
|
||||
</article>
|
||||
</el-card>
|
||||
</div>
|
||||
<div class="hero-inline">
|
||||
<span>系统绑定 <AdminStatusTag :status="detail.task.systemBindingStatus" /></span>
|
||||
@@ -51,10 +56,10 @@ defineProps<Props>()
|
||||
<span>客户领取页</span>
|
||||
<strong>已失效</strong>
|
||||
</div>
|
||||
</section>
|
||||
</el-card>
|
||||
|
||||
<!-- Simple info card for other task types -->
|
||||
<section v-else class="info-card">
|
||||
<el-card v-else shadow="never" class="section-card">
|
||||
<h2>{{ detail.task.taskNo }}</h2>
|
||||
<p>
|
||||
状态:<AdminStatusTag :status="detail.task.status" /> · 订单:{{
|
||||
@@ -80,7 +85,7 @@ defineProps<Props>()
|
||||
<a class="claim-link" :href="claimUrl" target="_blank" rel="noreferrer">{{ claimUrl }}</a>
|
||||
</p>
|
||||
<p v-else-if="claimLinkInvalid">领取链接:已失效</p>
|
||||
</section>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style scoped src="../AdminTaskDetail.css"></style>
|
||||
|
||||
@@ -14,106 +14,74 @@ defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="info-card">
|
||||
<el-card shadow="never" class="section-card">
|
||||
<h3>任务信息</h3>
|
||||
<table class="data-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>商品</th>
|
||||
<td>{{ detail.orderItem?.skuName || '-' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>SKU</th>
|
||||
<td>{{ detail.orderItem?.skuCode || '-' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>任务执行器</th>
|
||||
<td>{{ detail.task.executorKey || '-' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>履约状态</th>
|
||||
<td>
|
||||
<AdminStatusTag :status="detail.task.deliveryStatus || ''" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>结果代码</th>
|
||||
<td>{{ detail.task.resultCode || '-' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>结果说明</th>
|
||||
<td>{{ detail.task.resultMessage || '-' }}</td>
|
||||
</tr>
|
||||
<tr v-if="canViewSensitiveTaskData">
|
||||
<th>库存凭据</th>
|
||||
<td>{{ detail.inventory?.displayValue || '-' }}</td>
|
||||
</tr>
|
||||
<tr v-if="canViewSensitiveTaskData">
|
||||
<th>凭据类型</th>
|
||||
<td>{{ detail.inventory?.credentialType || '-' }}</td>
|
||||
</tr>
|
||||
<tr v-if="canViewSensitiveTaskData">
|
||||
<th>库存状态</th>
|
||||
<td>
|
||||
<AdminStatusTag :status="detail.inventory?.status || ''" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="canViewSensitiveTaskData">
|
||||
<th>Claim Token</th>
|
||||
<td>{{ detail.claimToken?.token || '-' }}</td>
|
||||
</tr>
|
||||
<tr v-else>
|
||||
<th>库存 / Token</th>
|
||||
<td>客服账号不可查看库存凭据与原始领取 Token</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Token 状态</th>
|
||||
<td>
|
||||
<AdminStatusTag :status="detail.claimToken?.status || ''" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Token 过期</th>
|
||||
<td>{{ formatAdminDateTime(detail.claimToken?.expiredAt) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>领取链接</th>
|
||||
<td>
|
||||
<a
|
||||
v-if="claimUrl"
|
||||
class="claim-link"
|
||||
:href="claimUrl"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>{{ claimUrl }}</a
|
||||
>
|
||||
<span v-else-if="claimLinkInvalid">已失效</span>
|
||||
<span v-else>-</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>浏览器会话</th>
|
||||
<td>{{ detail.task.browserSessionId || '-' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>用户打开链接</th>
|
||||
<td>{{ formatAdminDateTime(detail.task.claimedAt) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>用户提交绑定</th>
|
||||
<td>{{ formatAdminDateTime(detail.task.roleConfirmedAt) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>完整绑定成功</th>
|
||||
<td>{{ formatAdminDateTime(detail.task.redeemedAt) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>截图路径</th>
|
||||
<td>{{ detail.task.screenshotPath || '-' }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
<el-descriptions :column="2" border>
|
||||
<el-descriptions-item label="商品">{{
|
||||
detail.orderItem?.skuName || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="SKU">{{
|
||||
detail.orderItem?.skuCode || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="任务执行器">
|
||||
{{ detail.task.executorKey || '-' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="履约状态">
|
||||
<AdminStatusTag :status="detail.task.deliveryStatus || ''" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="结果代码">{{
|
||||
detail.task.resultCode || '-'
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="结果说明">
|
||||
{{ detail.task.resultMessage || '-' }}
|
||||
</el-descriptions-item>
|
||||
<template v-if="canViewSensitiveTaskData">
|
||||
<el-descriptions-item label="库存凭据">
|
||||
{{ detail.inventory?.displayValue || '-' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="凭据类型">
|
||||
{{ detail.inventory?.credentialType || '-' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="库存状态">
|
||||
<AdminStatusTag :status="detail.inventory?.status || ''" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="Claim Token">
|
||||
{{ detail.claimToken?.token || '-' }}
|
||||
</el-descriptions-item>
|
||||
</template>
|
||||
<el-descriptions-item v-else label="库存 / Token" :span="2">
|
||||
客服账号不可查看库存凭据与原始领取 Token
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="Token 状态">
|
||||
<AdminStatusTag :status="detail.claimToken?.status || ''" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="Token 过期">
|
||||
{{ formatAdminDateTime(detail.claimToken?.expiredAt) }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="领取链接" :span="2">
|
||||
<a v-if="claimUrl" class="claim-link" :href="claimUrl" target="_blank" rel="noreferrer">{{
|
||||
claimUrl
|
||||
}}</a>
|
||||
<span v-else-if="claimLinkInvalid">已失效</span>
|
||||
<span v-else>-</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="浏览器会话">
|
||||
{{ detail.task.browserSessionId || '-' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="用户打开链接">
|
||||
{{ formatAdminDateTime(detail.task.claimedAt) }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="用户提交绑定">
|
||||
{{ formatAdminDateTime(detail.task.roleConfirmedAt) }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="完整绑定成功">
|
||||
{{ formatAdminDateTime(detail.task.redeemedAt) }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="截图路径" :span="2">
|
||||
{{ detail.task.screenshotPath || '-' }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style scoped src="../AdminTaskDetail.css"></style>
|
||||
|
||||
+71
-72
@@ -18,82 +18,81 @@ const emit = defineEmits<{
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="info-card">
|
||||
<el-card shadow="never" class="section-card">
|
||||
<h3>库存绑定</h3>
|
||||
<p class="section-copy">
|
||||
这里展示任务当前和历史绑定过的库存项,便于核对多库存任务的真实履约轨迹。
|
||||
</p>
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>绑定</th>
|
||||
<th>角色</th>
|
||||
<th>库存项</th>
|
||||
<th>状态</th>
|
||||
<th>凭据内容</th>
|
||||
<th>时间</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-if="detail.inventoryBindings.length === 0">
|
||||
<td colspan="7" class="table-empty">当前任务还没有库存绑定记录</td>
|
||||
</tr>
|
||||
<tr v-for="binding in detail.inventoryBindings" :key="binding.bindingId">
|
||||
<td>
|
||||
<div>#{{ binding.bindingId }}</div>
|
||||
<div v-if="binding.isPrimary" class="binding-primary">主库存项</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>{{ binding.roleKey || '-' }}</div>
|
||||
<div class="binding-meta">数量 {{ binding.quantity }}</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>ID {{ binding.inventoryItemId }}</div>
|
||||
<div>{{ binding.skuCode || '-' }}</div>
|
||||
<div class="binding-meta">
|
||||
{{ binding.credentialType || '-' }} ·
|
||||
{{ binding.batchNo || '无批次' }}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="status-stack">
|
||||
<AdminStatusTag :status="binding.bindingStatus" />
|
||||
<AdminStatusTag :status="binding.inventoryStatus" />
|
||||
</div>
|
||||
<div v-if="binding.invalidReason" class="binding-meta">
|
||||
{{
|
||||
binding.inventoryStatus === 'invalid'
|
||||
? '作废原因'
|
||||
: binding.inventoryStatus === 'consumed'
|
||||
? '消耗原因'
|
||||
: '处理原因'
|
||||
}}:{{ binding.invalidReason }}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
{{ canViewSensitiveTaskData ? binding.displayValue || '-' : '客服不可见' }}
|
||||
</td>
|
||||
<td>
|
||||
<div>绑定 {{ formatAdminDateTime(binding.createdAt) }}</div>
|
||||
<div class="binding-meta">消费 {{ formatAdminDateTime(binding.consumedAt) }}</div>
|
||||
<div class="binding-meta">释放 {{ formatAdminDateTime(binding.releasedAt) }}</div>
|
||||
</td>
|
||||
<td>
|
||||
<el-button
|
||||
v-if="hasAdminRole('admin') && binding.canRelease"
|
||||
:loading="actionLoading"
|
||||
link
|
||||
@click="emit('releaseBinding', binding.bindingId)"
|
||||
>
|
||||
释放绑定
|
||||
</el-button>
|
||||
<span v-else class="binding-meta">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
<el-table :data="detail.inventoryBindings" size="small">
|
||||
<el-table-column label="绑定" width="100">
|
||||
<template #default="{ row: binding }">
|
||||
<div>#{{ binding.bindingId }}</div>
|
||||
<div v-if="binding.isPrimary" class="binding-primary">主库存项</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="角色" min-width="120">
|
||||
<template #default="{ row: binding }">
|
||||
<div>{{ binding.roleKey || '-' }}</div>
|
||||
<div class="binding-meta">数量 {{ binding.quantity }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="库存项" min-width="180">
|
||||
<template #default="{ row: binding }">
|
||||
<div>ID {{ binding.inventoryItemId }}</div>
|
||||
<div>{{ binding.skuCode || '-' }}</div>
|
||||
<div class="binding-meta">
|
||||
{{ binding.credentialType || '-' }} ·
|
||||
{{ binding.batchNo || '无批次' }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" min-width="160">
|
||||
<template #default="{ row: binding }">
|
||||
<div class="status-stack">
|
||||
<AdminStatusTag :status="binding.bindingStatus" />
|
||||
<AdminStatusTag :status="binding.inventoryStatus" />
|
||||
</div>
|
||||
<div v-if="binding.invalidReason" class="binding-meta">
|
||||
{{
|
||||
binding.inventoryStatus === 'invalid'
|
||||
? '作废原因'
|
||||
: binding.inventoryStatus === 'consumed'
|
||||
? '消耗原因'
|
||||
: '处理原因'
|
||||
}}:{{ binding.invalidReason }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="凭据内容" min-width="180">
|
||||
<template #default="{ row: binding }">
|
||||
{{ canViewSensitiveTaskData ? binding.displayValue || '-' : '客服不可见' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="时间" min-width="180">
|
||||
<template #default="{ row: binding }">
|
||||
<div>绑定 {{ formatAdminDateTime(binding.createdAt) }}</div>
|
||||
<div class="binding-meta">消费 {{ formatAdminDateTime(binding.consumedAt) }}</div>
|
||||
<div class="binding-meta">释放 {{ formatAdminDateTime(binding.releasedAt) }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100">
|
||||
<template #default="{ row: binding }">
|
||||
<el-button
|
||||
v-if="hasAdminRole('admin') && binding.canRelease"
|
||||
:loading="actionLoading"
|
||||
link
|
||||
@click="emit('releaseBinding', binding.bindingId)"
|
||||
>
|
||||
释放绑定
|
||||
</el-button>
|
||||
<span v-else class="binding-meta">-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<template #empty>
|
||||
<el-empty description="当前任务还没有库存绑定记录" :image-size="60" />
|
||||
</template>
|
||||
</el-table>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style scoped src="../AdminTaskDetail.css"></style>
|
||||
|
||||
@@ -37,7 +37,7 @@ const emit = defineEmits<{
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="info-card flow-card">
|
||||
<el-card shadow="never" class="section-card flow-card">
|
||||
<div class="flow-card-head">
|
||||
<div>
|
||||
<h3>快手 Cloud 履约面板</h3>
|
||||
@@ -74,34 +74,34 @@ const emit = defineEmits<{
|
||||
</div>
|
||||
|
||||
<div class="redeem-summary-grid">
|
||||
<article class="redeem-summary-card">
|
||||
<el-card shadow="never" class="redeem-summary-card">
|
||||
<span>准备状态</span>
|
||||
<div class="auto-delivery-tag-line">
|
||||
<AdminStatusTag :status="flow.binding.prepareStatus" />
|
||||
</div>
|
||||
</article>
|
||||
<article class="redeem-summary-card">
|
||||
</el-card>
|
||||
<el-card shadow="never" class="redeem-summary-card">
|
||||
<span>发货状态</span>
|
||||
<div class="auto-delivery-tag-line">
|
||||
<AdminStatusTag :status="flow.dispatch.status" />
|
||||
</div>
|
||||
</article>
|
||||
<article class="redeem-summary-card">
|
||||
</el-card>
|
||||
<el-card shadow="never" class="redeem-summary-card">
|
||||
<span>退号状态</span>
|
||||
<div class="auto-delivery-tag-line">
|
||||
<AdminStatusTag :status="flow.returnNumber.status" />
|
||||
</div>
|
||||
</article>
|
||||
<article class="redeem-summary-card">
|
||||
</el-card>
|
||||
<el-card shadow="never" class="redeem-summary-card">
|
||||
<span>当前任务状态</span>
|
||||
<div class="auto-delivery-tag-line">
|
||||
<AdminStatusTag :status="detail.task.status" />
|
||||
</div>
|
||||
</article>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<div class="kuaishou-focus-grid">
|
||||
<article class="flow-block flow-block--spotlight">
|
||||
<el-card shadow="never" class="flow-block flow-block--spotlight">
|
||||
<div class="spotlight-head">
|
||||
<div>
|
||||
<h4>角色信息</h4>
|
||||
@@ -145,9 +145,9 @@ const emit = defineEmits<{
|
||||
<strong>{{ entry.value }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</el-card>
|
||||
|
||||
<article class="flow-block flow-block--checklist">
|
||||
<el-card shadow="never" class="flow-block flow-block--checklist">
|
||||
<h4>流程检查</h4>
|
||||
<p class="flow-copy">
|
||||
客服可以先看这里,快速判断卡在哪一步,再决定是刷新角色、准备资源、发货还是退号。
|
||||
@@ -161,7 +161,7 @@ const emit = defineEmits<{
|
||||
<strong>{{ item.detail }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<el-collapse :model-value="collapsePanels" class="flow-collapse">
|
||||
@@ -302,7 +302,7 @@ const emit = defineEmits<{
|
||||
</div>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</section>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style scoped src="../AdminTaskDetail.css"></style>
|
||||
|
||||
@@ -25,11 +25,10 @@ function updateField(field: keyof ManualDispatchForm, value: string) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="info-card">
|
||||
<el-card shadow="never" class="section-card">
|
||||
<h3>人工履约回写</h3>
|
||||
<div class="manual-grid">
|
||||
<label class="field-block">
|
||||
<span>外部流水 / 单号</span>
|
||||
<el-form label-position="top" class="manual-grid">
|
||||
<el-form-item label="外部流水 / 单号">
|
||||
<el-input
|
||||
:model-value="form.deliveryReference"
|
||||
:disabled="!canManageTaskLifecycle"
|
||||
@@ -37,9 +36,8 @@ function updateField(field: keyof ManualDispatchForm, value: string) {
|
||||
placeholder="例如快递单号、平台消息回执号"
|
||||
@update:model-value="updateField('deliveryReference', $event)"
|
||||
/>
|
||||
</label>
|
||||
<label class="field-block">
|
||||
<span>已交付内容</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="已交付内容">
|
||||
<el-input
|
||||
:model-value="form.deliveredCredential"
|
||||
:disabled="!canManageTaskLifecycle"
|
||||
@@ -49,9 +47,8 @@ function updateField(field: keyof ManualDispatchForm, value: string) {
|
||||
:rows="3"
|
||||
@update:model-value="updateField('deliveredCredential', $event)"
|
||||
/>
|
||||
</label>
|
||||
<label class="field-block">
|
||||
<span>处理备注</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="处理备注">
|
||||
<el-input
|
||||
:model-value="form.resultMessage"
|
||||
:disabled="!canManageTaskLifecycle"
|
||||
@@ -61,25 +58,35 @@ function updateField(field: keyof ManualDispatchForm, value: string) {
|
||||
:rows="4"
|
||||
@update:model-value="updateField('resultMessage', $event)"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<p class="manual-hint">回写后会直接更新任务终态,不再走旧式领取链接流程。</p>
|
||||
<div v-if="detail.manualDispatch" class="manual-summary">
|
||||
<p>
|
||||
最近回写:<AdminStatusTag
|
||||
:status="detail.manualDispatch.outcome || detail.task.deliveryStatus"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-alert
|
||||
title="回写后会直接更新任务终态,不再走旧式领取链接流程。"
|
||||
type="info"
|
||||
show-icon
|
||||
:closable="false"
|
||||
class="mt-4"
|
||||
/>
|
||||
<el-descriptions v-if="detail.manualDispatch" :column="2" border class="manual-summary">
|
||||
<el-descriptions-item label="最近回写">
|
||||
<AdminStatusTag :status="detail.manualDispatch.outcome || detail.task.deliveryStatus" />
|
||||
· {{ formatAdminDateTime(detail.manualDispatch.completedAt) }}
|
||||
</p>
|
||||
<p>
|
||||
处理人:{{ detail.manualDispatch.completedBy?.username || '-' }} /
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="处理人">
|
||||
{{ detail.manualDispatch.completedBy?.username || '-' }} /
|
||||
{{ detail.manualDispatch.completedBy?.role || '-' }}
|
||||
</p>
|
||||
<p>流水号:{{ detail.manualDispatch.deliveryReference || '-' }}</p>
|
||||
<p>交付内容:{{ detail.manualDispatch.deliveredCredential || '-' }}</p>
|
||||
<p>备注:{{ detail.manualDispatch.resultMessage || '-' }}</p>
|
||||
</div>
|
||||
</section>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="流水号">
|
||||
{{ detail.manualDispatch.deliveryReference || '-' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="交付内容">
|
||||
{{ detail.manualDispatch.deliveredCredential || '-' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="备注" :span="2">
|
||||
{{ detail.manualDispatch.resultMessage || '-' }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style scoped src="../AdminTaskDetail.css"></style>
|
||||
|
||||
+13
-12
@@ -11,33 +11,34 @@ defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="info-card">
|
||||
<el-card shadow="never" class="section-card">
|
||||
<h3>兑换重试链路</h3>
|
||||
<p class="section-copy">
|
||||
这里记录自动兑换时每次使用过的 CDK、判定结果,以及是否切换到了新的同类型凭据。
|
||||
</p>
|
||||
|
||||
<div class="redeem-summary-grid">
|
||||
<article class="redeem-summary-card">
|
||||
<el-card shadow="never" class="redeem-summary-card">
|
||||
<span>处理结果</span>
|
||||
<strong>{{ formatRedeemResolutionStatus(detail.redeemResolution!.status) }}</strong>
|
||||
</article>
|
||||
<article class="redeem-summary-card">
|
||||
</el-card>
|
||||
<el-card shadow="never" class="redeem-summary-card">
|
||||
<span>任务收口状态</span>
|
||||
<strong>{{ detail.redeemResolution!.taskStatus || detail.task.status || '-' }}</strong>
|
||||
</article>
|
||||
<article class="redeem-summary-card">
|
||||
</el-card>
|
||||
<el-card shadow="never" class="redeem-summary-card">
|
||||
<span>更换新码次数</span>
|
||||
<strong>{{ detail.redeemResolution!.replacementCount }}</strong>
|
||||
</article>
|
||||
<article class="redeem-summary-card">
|
||||
</el-card>
|
||||
<el-card shadow="never" class="redeem-summary-card">
|
||||
<span>完成时间</span>
|
||||
<strong>{{ formatAdminDateTime(detail.redeemResolution!.finishedAt) }}</strong>
|
||||
</article>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<div v-if="detail.redeemResolution!.attempts.length > 0" class="redeem-attempts">
|
||||
<article
|
||||
<el-card
|
||||
shadow="never"
|
||||
v-for="attempt in detail.redeemResolution!.attempts"
|
||||
:key="`${attempt.attempt}-${attempt.inventoryItemId || 'na'}`"
|
||||
class="redeem-attempt-card"
|
||||
@@ -67,9 +68,9 @@ defineProps<Props>()
|
||||
<p class="redeem-attempt-copy">
|
||||
{{ attempt.resultMessage || '-' }}
|
||||
</p>
|
||||
</article>
|
||||
</el-card>
|
||||
</div>
|
||||
</section>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style scoped src="../AdminTaskDetail.css"></style>
|
||||
|
||||
@@ -8,15 +8,10 @@ defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="info-card">
|
||||
<el-card shadow="never" class="section-card">
|
||||
<h3>{{ sectionTitle }}</h3>
|
||||
<p v-if="!screenshotPreviewUrl" class="screenshot-empty">截图加载中或当前不可读取。</p>
|
||||
<a
|
||||
v-else
|
||||
class="screenshot-link"
|
||||
:href="screenshotPreviewUrl"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
<a v-else class="screenshot-link" :href="screenshotPreviewUrl" target="_blank" rel="noreferrer"
|
||||
>打开原图</a
|
||||
>
|
||||
<img
|
||||
@@ -25,7 +20,7 @@ defineProps<Props>()
|
||||
:src="screenshotPreviewUrl"
|
||||
:alt="sectionTitle"
|
||||
/>
|
||||
</section>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<style scoped src="../AdminTaskDetail.css"></style>
|
||||
|
||||
Reference in New Issue
Block a user