Files
study-agent-ui/src/components/Library/LibraryFileList.vue
2026-08-03 15:49:37 +08:00

121 lines
3.9 KiB
Vue

<template>
<div class="file-list">
<library-filter v-if="filterLibraryFileList.length"/>
<div v-for="file in filterLibraryFileList" :key="file.id" class="file-card card-item">
<div class="file-info" @click="viewContentClick(file)">
<div class="file-icon" :class="file.type === 'image' ? 'icon-image' : 'icon-pdf'">
<el-icon v-if="file.type === 'image'" ><Picture /></el-icon>
<el-icon v-else><Document /></el-icon>
</div>
<div class="file-text">
<div class="file-name">{{ file.name }}</div>
<div class="file-meta">{{ filesize(file.size) }} · {{ fromNow(file.uploadTime)}}</div>
</div>
</div>
<div class="card-actions">
<el-button type="primary" v-if="!appStore.isMobile"
:icon="Edit" @click="editClick(file)">编辑</el-button>
<el-button type="primary" :icon="Aim" @click="trainClick(file)">训练</el-button>
<el-button type="danger" v-if="!appStore.isMobile"
:icon="Delete">删除</el-button>
</div>
</div>
<el-empty v-if="!filterLibraryFileList.length" description="暂无数据"/>
</div>
</template>
<script setup lang="ts">
import { Delete, Edit, Picture, Document, Aim } from '@element-plus/icons-vue'
import { useLibraryStore } from '@/stores/library.ts'
import { usePracticeStore } from '@/stores/practice.ts'
import { useQuestionStore } from '@/stores/question.ts'
import { useAppStore } from '@/stores/app.ts'
import type { ILibraryFile } from '@/types/library.ts'
import LibraryFilter from '@/components/Library/LibraryFilter.vue'
import { computed } from 'vue'
import { fromNow } from '@/utils/dayUtil.ts'
import { filesize } from 'filesize'
import { ElLoading, ElMessage } from 'element-plus'
const libraryStore = useLibraryStore()
const practiceStore = usePracticeStore()
const questionStore = useQuestionStore()
const appStore = useAppStore()
const filterLibraryFileList = computed(() => {
const subject = libraryStore.selectedSubject
const module = libraryStore.selectedModule
return libraryStore.fileList.filter((item) => item.subject === subject && item.module === module)
})
const viewContentClick = async (file: ILibraryFile) => {
await libraryStore.queryFileById(file.id)
libraryStore.fileContentDialogVisible = true
}
const editClick = async (file: ILibraryFile) => {
await libraryStore.queryFileById(file.id)
libraryStore.fileApiType = 'UPDATE'
libraryStore.activeStep = 1
libraryStore.fileDialogVisible = true
}
const trainClick = async (file: ILibraryFile) => {
await libraryStore.queryFileById(file.id)
await generateQuestion()
practiceStore.hasStart = true
practiceStore.hasSubmit = false
questionStore.checkList = []
}
const generateQuestion = async () => {
questionStore.questionContent = ''
questionStore.hasGenerateQuestion = false
const loading = ElLoading.service({
lock: true,
text: '题库生成中 请等待',
background: 'rgba(0, 0, 0, 0.7)'
})
try {
const response = await fetch('/study-api/agent/question', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
message: libraryStore.currentFile.content
})
})
if (!response.body) {
throw new Error('未获取到响应流')
}
const reader = response.body.getReader()
const decoder = new TextDecoder('utf-8')
while (true) {
const { value, done } = await reader.read()
if (done) break
questionStore.questionContent += decoder.decode(value, { stream: true })
}
ElMessage.success('生成完成')
questionStore.hasGenerateQuestion = true
questionStore.questionList = JSON.parse(questionStore.questionContent)
libraryStore.fileTrainDialogVisible = true
} catch (error) {
console.log(error)
ElMessage.error('生成失败 请联系管理员')
} finally {
loading.close()
}
}
</script>