mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-08-16 23:40:59 +00:00
feat: 完成任务列表功能
This commit is contained in:
@@ -137,6 +137,8 @@ class TaskWrapper:
|
|||||||
for frame in self.task_stack:
|
for frame in self.task_stack:
|
||||||
exception_traceback += f" File \"{frame.f_code.co_filename}\", line {frame.f_lineno}, in {frame.f_code.co_name}\n"
|
exception_traceback += f" File \"{frame.f_code.co_filename}\", line {frame.f_lineno}, in {frame.f_code.co_name}\n"
|
||||||
|
|
||||||
|
exception_traceback += f" {self.assume_exception().__str__()}\n"
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"id": self.id,
|
"id": self.id,
|
||||||
"task_type": self.task_type,
|
"task_type": self.task_type,
|
||||||
|
|||||||
+1
-1
@@ -69,7 +69,7 @@
|
|||||||
import { getCurrentInstance } from 'vue'
|
import { getCurrentInstance } from 'vue'
|
||||||
import {provide, ref, watch} from 'vue';
|
import {provide, ref, watch} from 'vue';
|
||||||
|
|
||||||
import TaskDialog from '@/components/TaskDialog.vue'
|
import TaskDialog from '@/components/TaskListDialog.vue'
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance()
|
const { proxy } = getCurrentInstance()
|
||||||
|
|
||||||
|
|||||||
@@ -2,19 +2,66 @@
|
|||||||
<div class="task-card">
|
<div class="task-card">
|
||||||
<div class="task-card-icon">
|
<div class="task-card-icon">
|
||||||
<v-progress-circular :size="25" :width="2" indeterminate v-if="task.runtime.state == 'PENDING'" />
|
<v-progress-circular :size="25" :width="2" indeterminate v-if="task.runtime.state == 'PENDING'" />
|
||||||
<v-icon v-else-if="task.runtime.state == 'FINISHED'" style="color: #4caf50;" :size="25" icon="mdi-check" />
|
<v-icon v-else-if="task.runtime.state == 'FINISHED' && task.runtime.exception == null"
|
||||||
|
style="color: #4caf50;" :size="25" icon="mdi-check" />
|
||||||
<v-icon v-else-if="task.runtime.state == 'CANCELLED'" style="color: #f44336;" :size="25" icon="mdi-close" />
|
<v-icon v-else-if="task.runtime.state == 'CANCELLED'" style="color: #f44336;" :size="25" icon="mdi-close" />
|
||||||
|
|
||||||
|
<v-icon v-else-if="task.runtime.state == 'FINISHED' && task.runtime.exception != null" style="color: #f44336;"
|
||||||
|
:size="25" icon="mdi-alert-circle-outline" v-bind="activatorProps" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="task-card-content">
|
<div class="task-card-content">
|
||||||
<div class="task-card-kind">{{ task.kind }}</div>
|
<div class="task-card-kind">{{ task.kind }}</div>
|
||||||
<div class="task-card-label">{{ task.label }}</div>
|
<div class="task-card-label">{{ task.label }}</div>
|
||||||
<v-chip class="task-card-action" color="primary" variant="outlined" size="small" density="compact">正在执行: {{ task.task_context.current_action }}</v-chip>
|
<v-chip class="task-card-action" color="primary" variant="outlined" size="small" density="compact"
|
||||||
|
v-if="task.runtime.state == 'PENDING'">正在执行: {{ task.task_context.current_action }}</v-chip>
|
||||||
|
<v-chip class="task-card-action" color="success" variant="outlined" size="small" density="compact"
|
||||||
|
v-else-if="task.runtime.state == 'FINISHED' && task.runtime.exception == null">完成</v-chip>
|
||||||
|
|
||||||
|
<v-dialog max-width="500" persistent v-model="exceptionDialogShow">
|
||||||
|
<template v-slot:activator="{ props: activatorProps }">
|
||||||
|
<v-chip class="task-card-action" color="error" variant="outlined" size="small" density="compact"
|
||||||
|
v-if="task.runtime.state == 'FINISHED' && task.runtime.exception != null"
|
||||||
|
v-bind="activatorProps">{{ task.runtime.exception }}</v-chip>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<v-card prepend-icon="mdi-alert-circle-outline"
|
||||||
|
:text="task.runtime.exception_traceback"
|
||||||
|
title="任务执行失败">
|
||||||
|
<template v-slot:actions>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
|
||||||
|
<v-btn @click="exceptionDialogShow = false" prepend-icon="mdi-close">
|
||||||
|
关闭
|
||||||
|
</v-btn>
|
||||||
|
</template>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="task-card-actions">
|
<div class="task-card-actions">
|
||||||
<!-- <v-icon icon="mdi-details" /> -->
|
<!-- <v-icon icon="mdi-details" /> -->
|
||||||
<v-btn icon="mdi-information-outline" variant="text" />
|
<v-dialog max-width="500" persistent v-model="detailsDialogShow">
|
||||||
|
<template v-slot:activator="{ props: activatorProps }">
|
||||||
|
<v-btn icon="mdi-file-outline" variant="text" v-bind="activatorProps" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<v-card prepend-icon="mdi-file-outline" id="task-details-card"
|
||||||
|
:title="'任务执行日志 - '+task.label">
|
||||||
|
|
||||||
|
<div id="task-details-log-container">
|
||||||
|
<textarea id="task-details-log" v-model="task.task_context.log" readonly />
|
||||||
|
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
</div>
|
||||||
|
<template v-slot:actions>
|
||||||
|
|
||||||
|
<v-btn @click="detailsDialogShow = false" prepend-icon="mdi-close">
|
||||||
|
关闭
|
||||||
|
</v-btn>
|
||||||
|
</template>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -26,6 +73,11 @@ defineProps({
|
|||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const exceptionDialogShow = ref(false)
|
||||||
|
const detailsDialogShow = ref(false)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@@ -75,4 +127,18 @@ defineProps({
|
|||||||
justify-self: flex-end;
|
justify-self: flex-end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#task-details-log {
|
||||||
|
width: calc(100% - 2rem);
|
||||||
|
height: 10rem;
|
||||||
|
resize: none;
|
||||||
|
border: none;
|
||||||
|
padding: 0.6rem;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
outline: none;
|
||||||
|
overflow: auto;
|
||||||
|
appearance: none;
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
margin-inline: 1rem;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
<v-btn class="ml-auto" text="关闭" prepend-icon="mdi-close" @click="close"></v-btn>
|
<v-btn class="ml-auto" text="关闭" prepend-icon="mdi-close" @click="close"></v-btn>
|
||||||
</template>
|
</template>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@@ -55,7 +56,7 @@ const refresh = () => {
|
|||||||
let refreshTask = null
|
let refreshTask = null
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
refresh()
|
refresh()
|
||||||
refreshTask = setInterval(refresh, 500)
|
refreshTask = setInterval(refresh, 1000)
|
||||||
})
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
Reference in New Issue
Block a user