Files
JuYou/WEB/src/components/creative/TaskStatus.vue
T
2026-08-25 17:59:42 +08:00

113 lines
2.8 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 { computed } from "vue";
import type { GenerationTask } from "@/api/creative";
const props = defineProps<{ status?: string; task?: GenerationTask; cancellable?: boolean }>();
const emit = defineEmits<{ cancel: [task: GenerationTask] }>();
const labels: Record<string, string> = {
pending_submission: "排队中",
submitting: "排队中",
submitted: "已提交",
processing: "处理中",
result_ready: "结果入库中",
downloading: "结果入库中",
succeeded: "已完成",
failed: "失败",
cancel_requested: "取消处理中",
cancelled: "已取消",
draft: "待上传",
uploaded: "待分析",
analyzing: "分析中",
review: "待确认",
generating: "生成中",
completed: "已完成",
};
const value = computed(() => props.task?.status || props.status || "idle");
const label = computed(() => labels[value.value] || (value.value === "idle" ? "未生成" : value.value));
const tone = computed(
() =>
({
succeeded: "success",
completed: "success",
review: "success",
failed: "danger",
cancelled: "muted",
})[value.value] || (["idle", "draft", "uploaded"].includes(value.value) ? "muted" : "active"),
);
const canCancel = computed(
() =>
props.cancellable &&
props.task &&
["pending_submission", "submitted", "processing", "cancel_requested"].includes(value.value),
);
</script>
<template>
<span
class="task-state"
:class="`task-state--${tone}`"
><i></i>{{ label }}</span
>
<button
v-if="canCancel"
class="task-cancel"
type="button"
:disabled="value === 'cancel_requested'"
@click="emit('cancel', task!)"
>
取消
</button>
</template>
<style scoped lang="scss">
.task-state {
display: inline-flex;
align-items: center;
gap: 7px;
color: var(--web-task-idle-text);
font-size: 12px;
white-space: nowrap;
}
.task-state i {
width: 6px;
height: 6px;
background: var(--web-task-idle-dot);
border-radius: 50%;
}
.task-state--active i {
background: var(--creative-accent, var(--web-creative-accent));
box-shadow: 0 0 0 3px var(--web-task-running-ring);
}
.task-state--success {
color: var(--web-task-success-text);
}
.task-state--success i {
background: var(--web-task-success-dot);
}
.task-state--danger {
color: var(--web-task-failed-text);
}
.task-state--danger i {
background: var(--web-task-failed-dot);
}
.task-state--muted {
color: var(--web-empty-text);
}
.task-cancel {
padding: 0;
color: var(--web-task-cancelled);
background: transparent;
border: 0;
font-size: 12px;
cursor: pointer;
}
.task-cancel:hover {
color: var(--creative-accent, var(--web-creative-accent));
}
.task-cancel:disabled {
color: var(--web-task-detail);
cursor: default;
}
</style>