优化任务页面布局和交互控制

This commit is contained in:
aylvn 2025-03-16 18:57:30 +08:00
parent bcada6ead5
commit 7e42e4ccd2
9 changed files with 104 additions and 81 deletions

View File

@ -187,8 +187,11 @@ img.edit:hover {
.main-content {
width: 100%;
height: calc(100vh - 44px);
/** 44 + 16 + 16 */
height: calc(100vh - 76px);
padding: 0px 16px;
margin-top: 16px;
margin-bottom: 16px;
}
/** Element Plus Start */

View File

@ -143,6 +143,10 @@ header {
width: 100%;
height: 44px;
padding: 0px;
/* width: calc(100% -32px);
margin-left: 16px;
margin-right: 16px;
border-radius: 6px; */
background-color: var(--el-fg-color);
display: flex;
justify-content: center;

View File

@ -43,5 +43,7 @@ export default {
failed: "Failed",
running: "Running",
terminated: "Terminated",
}
},
newTask: "New Task",
}

View File

@ -42,5 +42,6 @@ export default {
failed: "失败",
running: "运行中",
terminated: "终止",
}
},
newTask: "新任务",
}

View File

@ -16,7 +16,7 @@ const router = createRouter({
path: 'task',
component: () => import('@/views/task/TaskIndex.vue'),
meta: {
keepAlive: false,
keepAlive: true,
title: "任务列表",
index: 0
}
@ -25,7 +25,7 @@ const router = createRouter({
path: 'task/:id',
component: () => import('@/views/task/TaskInfo.vue'),
meta: {
keepAlive: false,
keepAlive: true,
title: "任务信息",
index: 0
}
@ -34,7 +34,7 @@ const router = createRouter({
path: 'history',
component: () => import('@/views/task/HistoryIndex.vue'),
meta: {
keepAlive: false,
keepAlive: true,
title: "历史记录",
index: 0
}

View File

@ -7,7 +7,7 @@
<div class="blank"></div>
<div class="content">
<div class="title fxc">
<img src="@/assets/img/user.png" class="user-img"/>
<img src="@/assets/img/user.png" class="user-img" />
<el-text>
{{ t('user') }}
</el-text>
@ -50,15 +50,27 @@
</div>
</div>
</div>
<div>
<el-text class="pr-10">{{ t('taskStatus.name') }}:</el-text>
<el-text>{{ taskInfo.status }}</el-text>
</div>
</div>
</el-scrollbar>
<div class="input-area">
<div class="input-tools">
<div class="new-task" v-show="!newTaskFlag">
<el-button round @click="startNewTask">
<el-icon :size="16">
<CirclePlus />
</el-icon>
<span> {{ t('newTask') }} </span>
</el-button>
</div>
<div class="task-status" v-show="taskInfo.taskId != null">
<el-text class="pr-10">{{ t('taskStatus.name') }}:</el-text>
<el-text>{{ taskInfo.status }}</el-text>
</div>
</div>
<div class="input-box">
<el-icon @click="uploadFile" class="add-file-area" :size="24">
<FolderAdd />
@ -68,10 +80,10 @@
@keydown.enter="handleInputEnter" />
<el-link class="send-area">
<el-icon @click="sendPrompt" :size="24" v-show="!loading">
<el-icon @click="sendPrompt" :size="24" v-show="!loading && taskInfo.status != 'running'">
<Promotion />
</el-icon>
<el-icon @click="stop" :size="24" v-show="loading">
<el-icon @click="stop" :size="24" v-show="loading || taskInfo.status == 'running'">
<CircleClose />
</el-icon>
</el-link>
@ -87,7 +99,7 @@
<script setup>
import { ref, reactive, inject, computed, onMounted, onUnmounted } from 'vue'
import { FolderAdd, Promotion, User, CircleClose } from '@element-plus/icons-vue'
import { FolderAdd, Promotion, CirclePlus, CircleClose } from '@element-plus/icons-vue'
import { useConfig } from '@/store/config'
import { useI18n } from 'vue-i18n'
@ -101,7 +113,12 @@ const promptEle = ref(null)
const eventTypes = ['think', 'tool', 'act', 'log', 'run', 'message']
const eventSource = ref(null)
const newTaskFlag = ref(false)
const taskInfo = computed(() => {
if (newTaskFlag.value) {
return {}
}
return config.getCurrTask()
})
@ -251,17 +268,22 @@ const scrollToBottom = () => {
//
function sendPrompt() {
//
if (eventSource.value != null) {
eventSource.value.close()
}
if (utils.isBlank(prompt.value)) {
utils.pop("Please enter a valid prompt", "error")
promptEle.value.focus()
return
}
if (taskInfo.value.status == "running") {
utils.pop("请先终止当前任务", "error")
return
}
//
if (eventSource.value != null) {
eventSource.value.close()
}
utils.post('http://localhost:5172/tasks', { prompt: prompt.value }).then(data => {
if (!data.task_id) {
throw new Error('Invalid task ID')
@ -275,6 +297,7 @@ function sendPrompt() {
}
//
config.addTaskHistory(newTask)
newTaskFlag.value = false
//
prompt.value = ''
// EventSource
@ -289,17 +312,31 @@ function sendPrompt() {
function stop() {
console.log("stop")
loading.value = false
console.log("eventSource:", eventSource.value, "taskInfo:", taskInfo.value)
if (eventSource.value != null) {
eventSource.value.close()
}
taskInfo.value.status = "terminated"
utils.pop("用户终止任务", "error")
}
function startNewTask() {
console.log("startNewTask:", taskInfo.value)
if (taskInfo.value.status == "running") {
utils.pop("请先终止当前任务", "error")
return
}
newTaskFlag.value = true
prompt.value = ''
}
</script>
<style scoped>
.output-area {
flex-grow: 1;
margin-top: 10px;
}
.dialog-user {
@ -335,7 +372,7 @@ function stop() {
margin: 0px 16px 6px 16px;
}
.dialog-user .user-img{
.dialog-user .user-img {
width: 20px;
height: 20px;
margin-right: 2px;
@ -347,7 +384,6 @@ function stop() {
}
.dialog-ai {
margin-bottom: 16px;
background-color: var(--el-fg-color);
border-radius: 12px;
}
@ -360,17 +396,34 @@ function stop() {
.input-area {
flex-grow: 0;
width: 100%;
max-height: 180px;
max-height: 200px;
padding-left: 80px;
padding-right: 80px;
padding-top: 12px;
padding-bottom: 12px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.input-area .input-tools {
width: 100%;
padding-bottom: 10px;
display: flex;
justify-content: space-between;
align-items: center;
}
.input-area .input-tools .new-task {
position: relative;
left: -80px;
}
.input-area .input-tools .task-status {
position: relative;
right: -80px;
}
.input-box {
width: 100%;
border-radius: 16px;
@ -406,7 +459,7 @@ function stop() {
.tips {
color: var(--el-text-color-secondary);
font-size: 12px;
padding-top: 10px;
padding-top: 12px;
}
.sub-step-time {

View File

@ -54,7 +54,7 @@
</div>
</div>
<div>
<div class="task-status" v-show="taskInfo != null">
<el-text class="pr-10">{{ t('taskStatus.name') }}:</el-text>
<el-text>{{ taskInfo.status }}</el-text>
</div>
@ -98,8 +98,6 @@ const taskInfo = computed(() => {
<style scoped>
.output-area {
flex-grow: 1;
margin-top: 10px;
margin-bottom: 10px;
}
.dialog-user {
@ -146,9 +144,7 @@ const taskInfo = computed(() => {
width: 100%;
}
.dialog-ai {
margin-bottom: 16px;
background-color: var(--el-fg-color);
border-radius: 12px;
}
@ -158,56 +154,10 @@ const taskInfo = computed(() => {
font-size: 15px;
}
.input-area {
flex-grow: 0;
width: 100%;
max-height: 180px;
padding-left: 80px;
padding-right: 80px;
.task-status {
align-self: self-start;
padding-top: 12px;
padding-bottom: 12px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.input-box {
width: 100%;
border-radius: 16px;
background-color: var(--el-fg-color);
display: flex;
justify-content: center;
align-items: center;
}
.input-style {
width: 100%;
padding-top: 12px;
padding-bottom: 12px;
}
.input-style :deep(.el-textarea__inner) {
outline: none;
border: none;
resize: none;
box-shadow: none;
}
.add-file-area {
margin-left: 16px;
margin-right: 8px;
}
.send-area {
margin-left: 8px;
margin-right: 16px;
}
.tips {
color: var(--el-text-color-secondary);
font-size: 12px;
padding-top: 10px;
padding-bottom: 16px;
}
.sub-step-time {

8
factorial.py Normal file
View File

@ -0,0 +1,8 @@
def factorial(n):
if n == 0 or n == 1:
return 1
else:
return n * factorial(n - 1)
# Example usage
print(factorial(5))

2
sample.txt Normal file
View File

@ -0,0 +1,2 @@
Hello, World!
This is a sample text file.