feat: 添加防抖指令和任务管理功能
feat(anchor): 新增主播管理模块 feat(account): 完善客服账号管理功能 feat(knowledge): 添加任务列表查看和重新执行功能 feat(router): 增强路由组件动态导入逻辑 refactor: 优化多个视图的按钮防抖处理 style: 统一代码格式和样式 fix: 修复客服账号状态切换逻辑
This commit is contained in:
@@ -8,11 +8,11 @@
|
||||
<span class="header-title">知识库</span>
|
||||
</div>
|
||||
<div class="header-actions">
|
||||
<el-button type="primary" @click="onAddknowledge">
|
||||
<el-button type="primary" v-debounce @click="onAddknowledge">
|
||||
<el-icon><ele-Plus /></el-icon>
|
||||
新建知识库
|
||||
</el-button>
|
||||
<el-button type="success" @click="onOpenModelConfig">
|
||||
<el-button type="success" v-debounce @click="onOpenModelConfig">
|
||||
<el-icon><ele-Setting /></el-icon>
|
||||
模型配置
|
||||
</el-button>
|
||||
@@ -39,12 +39,12 @@
|
||||
<!-- 悬停操作按钮 -->
|
||||
<div class="card-actions" @click.stop>
|
||||
<el-tooltip content="重命名" placement="top">
|
||||
<el-button text size="small" @click="onRenameknowledge(item)">
|
||||
<el-button text size="small" v-debounce @click="onRenameknowledge(item)">
|
||||
<el-icon><ele-Edit /></el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button text size="small" type="danger" @click="onDeleteknowledge(item)">
|
||||
<el-button text size="small" type="danger" v-debounce @click="onDeleteknowledge(item)">
|
||||
<el-icon><ele-Delete /></el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
@@ -125,7 +125,7 @@
|
||||
<el-icon><ele-Search /></el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
<el-button type="primary" @click="onUploadFile">
|
||||
<el-button type="primary" v-debounce @click="onUploadFile">
|
||||
<el-icon><ele-Plus /></el-icon>
|
||||
新增文件
|
||||
</el-button>
|
||||
@@ -146,17 +146,20 @@
|
||||
</el-table-column>
|
||||
<el-table-column prop="vectorStatus" label="向量化" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.vectorStatus === 2 ? 'success' : 'warning'" size="small">
|
||||
{{ row.vectorStatus === 2 ? '已完成' : '未完成' }}
|
||||
<el-tag :type="getVectorStatusType(row.vectorStatus)" size="small">
|
||||
{{ getVectorStatusText(row.vectorStatus) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createdAt" label="上传日期" width="180" />
|
||||
<el-table-column label="动作" width="180" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-button text size="small" @click="onPreviewFile(row)">预览</el-button>
|
||||
<el-button text size="small" type="primary" @click="onGenerateVector(row)">生成向量</el-button>
|
||||
<el-button text size="small" type="danger" @click="onDeleteFile(row)">删除</el-button>
|
||||
<el-button text size="small" v-debounce @click="onPreviewFile(row)">预览</el-button>
|
||||
<el-button v-if="row.vectorStatus === 1" text size="small" type="primary" v-debounce @click="onGenerateVector(row)"
|
||||
>生成向量</el-button
|
||||
>
|
||||
<el-button v-else text size="small" type="primary" v-debounce @click="onViewTaskList(row)">查看任务</el-button>
|
||||
<el-button text size="small" type="danger" v-debounce @click="onDeleteFile(row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -169,7 +172,7 @@
|
||||
<div class="panel-card">
|
||||
<h3>检索测试</h3>
|
||||
<el-input v-model="searchQuery" type="textarea" :rows="3" placeholder="输入问题进行检索测试..." />
|
||||
<el-button type="primary" class="mt15" @click="onSearchTest">测试检索</el-button>
|
||||
<el-button type="primary" class="mt15" v-debounce @click="onSearchTest">测试检索</el-button>
|
||||
<div class="search-results mt15" v-if="searchResults.length > 0">
|
||||
<h4>检索结果</h4>
|
||||
<div class="result-item" v-for="(item, index) in searchResults" :key="index">
|
||||
@@ -215,7 +218,7 @@
|
||||
<el-input-number v-model="settingsForm.chunkOverlap" :min="0" :max="500" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSaveSettings">保存配置</el-button>
|
||||
<el-button type="primary" v-debounce @click="onSaveSettings">保存配置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
@@ -236,7 +239,7 @@
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="showknowledgeDialog = false">取消</el-button>
|
||||
<el-button type="primary" @click="onSaveknowledge" :loading="knowledgeSaving">确定</el-button>
|
||||
<el-button type="primary" v-debounce @click="onSaveknowledge" :loading="knowledgeSaving">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
@@ -261,7 +264,7 @@
|
||||
</el-upload>
|
||||
<template #footer>
|
||||
<el-button @click="showUploadDialog = false">取消</el-button>
|
||||
<el-button type="primary" @click="onConfirmUpload" :loading="uploading" :disabled="uploadFileList.length === 0">
|
||||
<el-button type="primary" v-debounce @click="onConfirmUpload" :loading="uploading" :disabled="uploadFileList.length === 0">
|
||||
上传 ({{ uploadFileList.length }} 个文件)
|
||||
</el-button>
|
||||
</template>
|
||||
@@ -278,7 +281,7 @@
|
||||
<!-- 模型配置弹窗 -->
|
||||
<el-dialog title="模型配置" v-model="showModelConfigDialog" width="1000px" :close-on-click-modal="false">
|
||||
<div class="model-config-list" v-loading="modelConfigLoading">
|
||||
<el-button type="primary" style="margin-bottom: 16px" @click="onCreateModelConfig">
|
||||
<el-button type="primary" style="margin-bottom: 16px" v-debounce @click="onCreateModelConfig">
|
||||
<el-icon><ele-Plus /></el-icon>
|
||||
创建模型配置
|
||||
</el-button>
|
||||
@@ -299,7 +302,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="80" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-button text size="small" type="primary" @click="onEditModelConfig(row)">编辑</el-button>
|
||||
<el-button text size="small" type="primary" v-debounce @click="onEditModelConfig(row)">编辑</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -310,6 +313,53 @@
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 任务列表弹窗 -->
|
||||
<el-dialog title="任务列表" v-model="showTaskListDialog" width="900px" :close-on-click-modal="false">
|
||||
<el-table :data="taskList" style="width: 100%" border v-loading="taskListLoading">
|
||||
<el-table-column prop="taskType" label="任务类型" width="150">
|
||||
<template #default="{ row }">
|
||||
{{ getTaskTypeText(row.taskType) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" label="任务状态" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="getTaskStatusType(row.status)" size="small">
|
||||
{{ getTaskStatusText(row.status) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remark" label="备注" min-width="200" />
|
||||
<el-table-column prop="startTime" label="开始时间" width="180">
|
||||
<template #default="{ row }">
|
||||
{{ row.startTime ? formatDateTime(row.startTime) : '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="endTime" label="结束时间" width="180">
|
||||
<template #default="{ row }">
|
||||
{{ row.endTime ? formatDateTime(row.endTime) : '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="120" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
v-if="row.status === 'FAILED' || row.status === 'COMPLETED'"
|
||||
text
|
||||
size="small"
|
||||
type="primary"
|
||||
v-debounce
|
||||
@click="onReexecuteTask(row)"
|
||||
>重新执行</el-button
|
||||
>
|
||||
<el-button v-else text size="small" type="info" disabled>执行中</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-empty v-if="taskList.length === 0 && !taskListLoading" description="暂无任务" :image-size="60" />
|
||||
<template #footer>
|
||||
<el-button @click="showTaskListDialog = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 创建/编辑模型配置弹窗 -->
|
||||
<el-dialog :title="isEditMode ? '编辑模型配置' : '创建模型配置'" v-model="showCreateModelDialog" width="600px" :close-on-click-modal="false">
|
||||
<div v-loading="modelEnumsLoading || modelFormLoading">
|
||||
@@ -356,7 +406,7 @@
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="showCreateModelDialog = false">取消</el-button>
|
||||
<el-button type="primary" @click="onSaveModelConfig()" :disabled="!selectedModelType || !selectedConfigType"> 保存 </el-button>
|
||||
<el-button type="primary" v-debounce @click="onSaveModelConfig" :disabled="!selectedModelType || !selectedConfigType"> 保存 </el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
@@ -374,7 +424,17 @@ import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import type { FormInstance, FormRules, UploadFile } from 'element-plus';
|
||||
import DocumentDetailDialog from './component/documentDetailDialog.vue';
|
||||
import { listknowledges, createknowledge, updateknowledge, deleteknowledge } from '/@/api/knowledge/dataset';
|
||||
import { listDocuments, uploadFile, createDocument, deleteDocument, updateDocument, generateVector, getDocument } from '/@/api/knowledge/document';
|
||||
import {
|
||||
listDocuments,
|
||||
uploadFile,
|
||||
createDocument,
|
||||
deleteDocument,
|
||||
updateDocument,
|
||||
generateVector,
|
||||
getDocument,
|
||||
listTasks,
|
||||
reexecuteTask,
|
||||
} from '/@/api/knowledge/document';
|
||||
import { listModelConfigs, createModelConfig, updateModelConfig, getModelConfig, getAllModelEnums, getModelFormField } from '/@/api/knowledge/model';
|
||||
|
||||
// 数据集相关
|
||||
@@ -389,6 +449,11 @@ const showModelConfigDialog = ref(false);
|
||||
const modelConfigList = ref<any[]>([]);
|
||||
const modelConfigLoading = ref(false);
|
||||
|
||||
// 任务列表相关
|
||||
const showTaskListDialog = ref(false);
|
||||
const taskList = ref<any[]>([]);
|
||||
const taskListLoading = ref(false);
|
||||
|
||||
// 创建模型配置相关
|
||||
const showCreateModelDialog = ref(false);
|
||||
const modelEnums = ref<any[]>([]);
|
||||
@@ -995,6 +1060,101 @@ const formatDateTime = (dateTime: string) => {
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||
};
|
||||
|
||||
// 获取向量状态文本
|
||||
const getVectorStatusText = (status: number) => {
|
||||
const statusMap: Record<number, string> = {
|
||||
1: '待处理',
|
||||
2: '处理中',
|
||||
3: '已完成',
|
||||
4: '失败',
|
||||
};
|
||||
return statusMap[status] || '未知';
|
||||
};
|
||||
|
||||
// 获取向量状态标签类型
|
||||
const getVectorStatusType = (status: number) => {
|
||||
const typeMap: Record<number, any> = {
|
||||
1: 'warning',
|
||||
2: 'primary',
|
||||
3: 'success',
|
||||
4: 'danger',
|
||||
};
|
||||
return typeMap[status] || 'info';
|
||||
};
|
||||
|
||||
// 获取任务类型文本
|
||||
const getTaskTypeText = (taskType: string) => {
|
||||
const typeMap: Record<string, string> = {
|
||||
EXTRACT_KEYWORDS: '提取关键词',
|
||||
GENERATE_VECTOR: '生成向量',
|
||||
FULL_TEXT_SEARCH: '全文检索',
|
||||
DOC_PARSE: '文档解析',
|
||||
};
|
||||
return typeMap[taskType] || taskType;
|
||||
};
|
||||
|
||||
// 获取任务状态文本
|
||||
const getTaskStatusText = (status: string) => {
|
||||
const statusMap: Record<string, string> = {
|
||||
PENDING: '待执行',
|
||||
RUNNING: '执行中',
|
||||
COMPLETED: '已完成',
|
||||
FAILED: '执行失败',
|
||||
};
|
||||
return statusMap[status] || status;
|
||||
};
|
||||
|
||||
// 获取任务状态标签类型
|
||||
const getTaskStatusType = (status: string) => {
|
||||
const typeMap: Record<string, any> = {
|
||||
PENDING: 'warning',
|
||||
RUNNING: 'primary',
|
||||
COMPLETED: 'success',
|
||||
FAILED: 'danger',
|
||||
};
|
||||
return typeMap[status] || 'info';
|
||||
};
|
||||
|
||||
// 查看任务列表
|
||||
const onViewTaskList = async (row: any) => {
|
||||
showTaskListDialog.value = true;
|
||||
await getTaskList();
|
||||
};
|
||||
|
||||
// 获取任务列表
|
||||
const getTaskList = async () => {
|
||||
taskListLoading.value = true;
|
||||
try {
|
||||
const response = await listTasks();
|
||||
taskList.value = response.data?.list || [];
|
||||
} catch (error) {
|
||||
ElMessage.error('获取任务列表失败');
|
||||
taskList.value = [];
|
||||
} finally {
|
||||
taskListLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 重新执行任务
|
||||
const onReexecuteTask = async (task: any) => {
|
||||
ElMessageBox.confirm(`确定要重新执行任务【${getTaskTypeText(task.taskType)}】吗?`, '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
})
|
||||
.then(async () => {
|
||||
try {
|
||||
await reexecuteTask(task.id);
|
||||
ElMessage.success('重新执行任务成功');
|
||||
// 重新获取任务列表
|
||||
await getTaskList();
|
||||
} catch (error) {
|
||||
ElMessage.error('重新执行任务失败,请重试');
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 页面加载
|
||||
onMounted(() => {
|
||||
getknowledgeList();
|
||||
|
||||
Reference in New Issue
Block a user