优化任务页面布局和交互控制
This commit is contained in:
parent
bcada6ead5
commit
7e42e4ccd2
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -43,5 +43,7 @@ export default {
|
||||
failed: "Failed",
|
||||
running: "Running",
|
||||
terminated: "Terminated",
|
||||
}
|
||||
},
|
||||
newTask: "New Task",
|
||||
|
||||
}
|
||||
|
@ -42,5 +42,6 @@ export default {
|
||||
failed: "失败",
|
||||
running: "运行中",
|
||||
terminated: "终止",
|
||||
}
|
||||
},
|
||||
newTask: "新任务",
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
8
factorial.py
Normal 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
2
sample.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Hello, World!
|
||||
This is a sample text file.
|
Loading…
x
Reference in New Issue
Block a user