Files
gangyan/chat_web_front/src/views/reading/index.vue

565 lines
14 KiB
Vue
Raw Normal View History

<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>