121 lines
3.9 KiB
Vue
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>
|