[全量] 初始化项目代码、配置、文档及Agent协同harness
This commit is contained in:
565
chat_web_front/src/views/reading/index.vue
Normal file
565
chat_web_front/src/views/reading/index.vue
Normal file
@@ -0,0 +1,565 @@
|
||||
<template>
|
||||
<div class="reading">
|
||||
<div class="reading-header">
|
||||
<p>我的文献</p>
|
||||
<div class="reading-operate">
|
||||
<el-input style="width: 316px; height: 32px" v-model="searchWord" placeholder="请输入文件夹标题关键字搜索">
|
||||
<template #suffix>
|
||||
<img src="@/assets/images/search.png" class="reading-search" >
|
||||
</template>
|
||||
</el-input>
|
||||
<div class="reading-operate-btn reading-create" @click="createFolder()">
|
||||
<img src="@/assets/images/reading/create.png" alt="">
|
||||
<p class="reading-operate-tip">新建文件夹</p>
|
||||
</div>
|
||||
<div class="reading-operate-btn reading-del" @click="delBatch">
|
||||
<img src="@/assets/images/reading/del.png" alt="">
|
||||
<p class="reading-operate-tip">批量删除</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="empty-list" v-if="materialList.length === 0">
|
||||
<div class="empty-list-container">
|
||||
<img src="@/assets/images/reading/empty.png" alt="">
|
||||
<div class="empty-list-tips">
|
||||
暂未发现文件夹,<span class="go-create" @click="createFolder()">点击创建</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list" v-if="materialList.length > 0">
|
||||
<div v-for="(item, index) in materialList" :key="item.id" class="material-list-item">
|
||||
<img src="@/assets/images/reading/folder.png" alt="" @click="fileList(item.id,item.name)" style="cursor: pointer">
|
||||
<div class="material-list-item-info">
|
||||
<div class="top" @click="fileList(item.id,item.name)">
|
||||
<div class="title" :title="item.name">{{ item.name }}</div>
|
||||
<div class="operate-img" @click.stop="showOperates(index)">
|
||||
<img src="@/assets/images/reading/operates.png" alt="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom">
|
||||
<el-checkbox v-model="item.checked"></el-checkbox>
|
||||
</div>
|
||||
<div class="operates" v-if="index === showOperatesIndex">
|
||||
<div class="btn update-name" @click="createFolder(item)">修改名称</div>
|
||||
<div class="btn del-folder" @click="delFolder(item)">删除</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 创建文件夹/重命名文件夹弹框 -->
|
||||
<div class="create-folder-dialog" v-if="dialogVisible">
|
||||
<div class="cus-container">
|
||||
<div class="cus-header">
|
||||
<div class="cus-title">{{ dialogTitle }}</div>
|
||||
<img src="@/assets/images/close.png" alt="" @click="cancelSubmitFolderName">
|
||||
</div>
|
||||
|
||||
<div class="cus-content">
|
||||
<el-input v-model="submitFolderParam.name" placeholder="请输入文件夹名称" style="height: 52px" @keyup.enter="submitFolderName"></el-input>
|
||||
</div>
|
||||
|
||||
<div class="cus-footer">
|
||||
<div class="submit" @click="submitFolderName">确定</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<page-footer></page-footer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {onMounted, ref, onUnmounted, reactive, computed} from "vue";
|
||||
import { getKnowledgeBaseList, addKnowledgeBase, editKnowledgeBase, delKnowledgeBase } from "@/api";
|
||||
import { withLoading } from "@/utils/loading";
|
||||
import {useRouter} from "vue-router";
|
||||
import PageFooter from "@/components/pageFooter.vue";
|
||||
|
||||
// 检索词
|
||||
const searchWord = ref('');
|
||||
|
||||
|
||||
// 文献列表
|
||||
|
||||
const netFolderList=ref([]);
|
||||
|
||||
// 创建文件夹/重命名弹框
|
||||
const dialogVisible = ref(false);
|
||||
const dialogTitle = ref("新建文件夹");
|
||||
interface FolderParam {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
const submitFolderParam = reactive<FolderParam>({
|
||||
id: 0,
|
||||
name: "",
|
||||
})
|
||||
|
||||
const router = useRouter();
|
||||
const fileList=(id:any,fileName:string)=>{
|
||||
router.push({
|
||||
name: 'FileList',
|
||||
state: {
|
||||
folderId:id,
|
||||
fileName:fileName
|
||||
}
|
||||
});
|
||||
}
|
||||
// 控制文件夹操作弹框的显隐
|
||||
const showOperatesIndex = ref(-1);
|
||||
/**
|
||||
* 获取我的知识库列表,这里是文件夹列表
|
||||
*/
|
||||
const getMyMaterialList = async () => {
|
||||
try {
|
||||
searchWord.value='';
|
||||
let res = await withLoading(getKnowledgeBaseList<JSON>)({
|
||||
folderType: "0",
|
||||
});
|
||||
if (res && res.data !== null) {
|
||||
netFolderList.value=res.data;
|
||||
}
|
||||
} catch (error: any) {
|
||||
ElMessage.error(error && error.message ? error.message : '未知错误');
|
||||
}
|
||||
}
|
||||
|
||||
const materialList=computed(()=>{
|
||||
if(searchWord.value===''||searchWord.value.trim()===''){
|
||||
return netFolderList.value;
|
||||
}
|
||||
return netFolderList.value.filter((item, index) => {
|
||||
return item.name.toLowerCase().includes(searchWord.value.toLowerCase())
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* 打开创建文件夹弹框
|
||||
*/
|
||||
const createFolder = (item: any = null) => {
|
||||
if (item) {
|
||||
submitFolderParam.id = item.id;
|
||||
submitFolderParam.name = item.name;
|
||||
dialogTitle.value = "重命名文件夹";
|
||||
dialogVisible.value = true;
|
||||
return;
|
||||
}
|
||||
|
||||
submitFolderParam.name = "";
|
||||
submitFolderParam.id=0;
|
||||
dialogTitle.value = "新建文件夹";
|
||||
dialogVisible.value = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*/
|
||||
const delBatch = async () => {
|
||||
let selectedMaterialList = materialList.value.filter(item => item.checked)
|
||||
|
||||
if (selectedMaterialList.length === 0) {
|
||||
ElMessage.warning('请选择要删除的文件夹');
|
||||
return;
|
||||
}
|
||||
|
||||
ElMessageBox.confirm("确定删除文件夹?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
}).then(async () => {
|
||||
let errorList: string[] = [];
|
||||
await withLoading(delBatchSubmit)(selectedMaterialList, errorList);
|
||||
|
||||
if (errorList.length > 0) {
|
||||
ElMessage.error(`文件夹${errorList.join('、')}删除失败`);
|
||||
} else {
|
||||
ElMessage.success('文件夹删除成功')
|
||||
}
|
||||
|
||||
getMyMaterialList();
|
||||
}).catch(() => {
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 循环调用删除接口,实现批量删除
|
||||
* @param selectedMaterialList
|
||||
* @param errorList
|
||||
*/
|
||||
const delBatchSubmit = async (selectedMaterialList: any, errorList: string[]) => {
|
||||
for (let i = 0; i < selectedMaterialList.length; i++) {
|
||||
try {
|
||||
let res = await delKnowledgeBase<JSON>({
|
||||
knowledgeBaseId: selectedMaterialList[i].id + "",
|
||||
folderType: "0"
|
||||
})
|
||||
|
||||
if (!res || res.code != 200) {
|
||||
errorList.push(selectedMaterialList[i].name);
|
||||
}
|
||||
|
||||
} catch (error: any) {
|
||||
errorList.push(selectedMaterialList[i].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交
|
||||
*/
|
||||
const submitFolderName = async () => {
|
||||
if (submitFolderParam.name.trim().length === 0) {
|
||||
ElMessage.warning("请输入文件夹名称");
|
||||
return;
|
||||
}
|
||||
if (submitFolderParam.id != 0) {
|
||||
submitUpdateFolder();
|
||||
return;
|
||||
}
|
||||
submitCreateFolder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 新建文件夹
|
||||
*/
|
||||
const submitCreateFolder = async () => {
|
||||
try {
|
||||
let res = await withLoading(addKnowledgeBase<JSON>)({
|
||||
name: submitFolderParam.name.trim()
|
||||
})
|
||||
if (res && res.code === 200) {
|
||||
ElMessage.success("文件夹创建成功");
|
||||
dialogVisible.value = false;
|
||||
getMyMaterialList();
|
||||
} else {
|
||||
ElMessage.error(res.msg);
|
||||
}
|
||||
} catch (error: any) {
|
||||
ElMessage.error(error && error.message ? error.message : '未知错误');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重命名文件夹
|
||||
*/
|
||||
const submitUpdateFolder = async () => {
|
||||
try {
|
||||
let res = await withLoading(editKnowledgeBase<JSON>)({
|
||||
id: submitFolderParam.id + "",
|
||||
name: submitFolderParam.name.trim(),
|
||||
folderType: "0"
|
||||
})
|
||||
|
||||
if (res && res.code === 200) {
|
||||
ElMessage.success("文件夹重命名成功");
|
||||
dialogVisible.value = false;
|
||||
getMyMaterialList();
|
||||
} else {
|
||||
ElMessage.error(res.msg);
|
||||
}
|
||||
} catch (error: any) {
|
||||
ElMessage.error(error && error.message ? error.message : '未知错误');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭创建文件夹/重命名文件夹弹框
|
||||
*/
|
||||
const cancelSubmitFolderName = () => {
|
||||
dialogVisible.value = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示修改文件名称、删除按钮
|
||||
* @param index
|
||||
*/
|
||||
const showOperates = (index: number) => {
|
||||
showOperatesIndex.value = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭文件夹操作弹框
|
||||
*/
|
||||
const closeOperates = () => {
|
||||
if (showOperatesIndex.value != -1) {
|
||||
showOperatesIndex.value = -1;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除文件夹
|
||||
*/
|
||||
const delFolder = async (item: any) => {
|
||||
ElMessageBox.confirm("确定删除该文件夹?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
}).then(async () => {
|
||||
try {
|
||||
let res = await withLoading(delKnowledgeBase<JSON>)({
|
||||
knowledgeBaseId: item.id + "",
|
||||
folderType: "0"
|
||||
})
|
||||
|
||||
if (res && res.code === 200) {
|
||||
ElMessage.success("文件夹删除成功");
|
||||
getMyMaterialList();
|
||||
} else {
|
||||
ElMessage.error(res.msg);
|
||||
}
|
||||
} catch (error: any) {
|
||||
ElMessage.error(error && error.message ? error.message : '未知错误');
|
||||
}
|
||||
|
||||
}).catch(() => {
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getMyMaterialList();
|
||||
document.addEventListener('click', closeOperates);
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
document.removeEventListener('click', closeOperates);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.reading {
|
||||
width: 100%;
|
||||
padding: 20px 50px;
|
||||
position: relative;
|
||||
|
||||
.reading-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
p {
|
||||
width: 90px;
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.reading-operate {
|
||||
width: 555px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.reading-search {
|
||||
cursor: pointer;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.reading-operate-btn {
|
||||
height: 32px;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.reading-operate-tip {
|
||||
font-weight: normal;
|
||||
font-size: 14px;
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
.reading-create {
|
||||
width: 110px;
|
||||
background: #004EA0;
|
||||
text-align: center;
|
||||
img {
|
||||
width: 16px;
|
||||
}
|
||||
p {
|
||||
width: 70px;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
.reading-del {
|
||||
width: 96px;
|
||||
background: #FFFFFF;
|
||||
border: 1px solid #004EA0;
|
||||
img {
|
||||
width: 16px;
|
||||
}
|
||||
p {
|
||||
width: 56px;
|
||||
color: #004EA0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.empty-list {
|
||||
width: 100%;
|
||||
height: calc(100% - 63px);
|
||||
text-align: center;
|
||||
position: relative;
|
||||
.empty-list-container {
|
||||
position: absolute;
|
||||
top: 30%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
img {
|
||||
width: 196px;
|
||||
height: 196px;
|
||||
}
|
||||
|
||||
.empty-list-tips {
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
color: #000000;
|
||||
|
||||
.go-create {
|
||||
color: #004EA0;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.list {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
.material-list-item {
|
||||
width: 242px;
|
||||
height: 70px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #D5DDFF;
|
||||
padding: 12px 14px 16px 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-right: 16px;
|
||||
margin-bottom: 10px;
|
||||
img {
|
||||
width: 45.39px;
|
||||
height: 38px;
|
||||
}
|
||||
.material-list-item-info {
|
||||
width: calc(100% - 57.39px);
|
||||
margin-left: 12px;
|
||||
position: relative;
|
||||
.top {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.title {
|
||||
max-width: 136px;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
color: #004EA0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
cursor: pointer;
|
||||
}
|
||||
.operate-img {
|
||||
width: 12px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
img {
|
||||
width: 2px;
|
||||
height: 11.11px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.bottom {
|
||||
text-align: right;
|
||||
padding-right: 6px;
|
||||
}
|
||||
.operates {
|
||||
width: 88px;
|
||||
height: 72px;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 0px 8px 1px rgba(180,189,221,0.56);
|
||||
border-radius: 8px 8px 8px 8px;
|
||||
border: 1px solid #D5DDFF;
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
left: 151px;
|
||||
z-index: 2;
|
||||
.btn {
|
||||
height: 36px;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
line-height: 36px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.update-name {
|
||||
color: #000000;
|
||||
border-bottom: 1px solid #D5DDFF;
|
||||
}
|
||||
.del-folder {
|
||||
color: #BE0000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.create-folder-dialog {
|
||||
background: rgba(0, 0, 0, 0);
|
||||
z-index: 999;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
.cus-container {
|
||||
width: 715px;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 0px 8px 1px rgba(180,189,221,0.56);
|
||||
border-radius: 16px 16px 16px 16px;
|
||||
border: 1px solid #D5DDFF;
|
||||
margin: 30vh auto;
|
||||
.cus-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 16px 20px 16px 20px;
|
||||
border-bottom: 1px solid #E6EDFF;
|
||||
margin-bottom: 16px;
|
||||
.cus-title {
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
color: #000000;
|
||||
}
|
||||
img {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.cus-content {
|
||||
padding: 0 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.cus-footer {
|
||||
margin-bottom: 20px;
|
||||
.submit {
|
||||
width: 68px;
|
||||
height: 32px;
|
||||
background: #004EA0;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
color: #FAFBFF;
|
||||
text-align: center;
|
||||
line-height: 32px;
|
||||
margin: auto;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user