提交 cb3225f6 authored 作者: 王鹏飞's avatar 王鹏飞

chore: update

上级 a4686548
......@@ -21,6 +21,7 @@
"dayjs": "^1.11.6",
"element-plus": "^2.2.21",
"file-saver": "^2.0.5",
"html-to-image": "^1.10.8",
"lodash-es": "^4.17.21",
"pinia": "^2.0.24",
"qs": "^6.11.0",
......@@ -2798,6 +2799,11 @@
"resolved": "https://registry.npmmirror.com/hookable/-/hookable-5.4.2.tgz",
"integrity": "sha512-6rOvaUiNKy9lET1X0ECnyZ5O5kSV0PJbtA5yZUgdEF7fGJEVwSLSislltyt7nFwVVALYHQJtfGeAR2Y0A0uJkg=="
},
"node_modules/html-to-image": {
"version": "1.10.8",
"resolved": "https://registry.npmmirror.com/html-to-image/-/html-to-image-1.10.8.tgz",
"integrity": "sha512-t+JyFJwKDCp4ZwBp4iC/wqw0meQDDc77Qs8OFl5P7RGlIP3LQMvwpD7VXxqQfC7/TfC+GKYlFP6WDYfXTmXHfw=="
},
"node_modules/http-errors": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.0.tgz",
......@@ -7060,6 +7066,11 @@
"resolved": "https://registry.npmmirror.com/hookable/-/hookable-5.4.2.tgz",
"integrity": "sha512-6rOvaUiNKy9lET1X0ECnyZ5O5kSV0PJbtA5yZUgdEF7fGJEVwSLSislltyt7nFwVVALYHQJtfGeAR2Y0A0uJkg=="
},
"html-to-image": {
"version": "1.10.8",
"resolved": "https://registry.npmmirror.com/html-to-image/-/html-to-image-1.10.8.tgz",
"integrity": "sha512-t+JyFJwKDCp4ZwBp4iC/wqw0meQDDc77Qs8OFl5P7RGlIP3LQMvwpD7VXxqQfC7/TfC+GKYlFP6WDYfXTmXHfw=="
},
"http-errors": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.0.tgz",
......
......@@ -27,6 +27,7 @@
"dayjs": "^1.11.6",
"element-plus": "^2.2.21",
"file-saver": "^2.0.5",
"html-to-image": "^1.10.8",
"lodash-es": "^4.17.21",
"pinia": "^2.0.24",
"qs": "^6.11.0",
......
......@@ -2,6 +2,7 @@
import { getExperimentReport } from '../api'
const props = defineProps({ id: String })
const emit = defineEmits(['ready'])
let experiment = $ref()
let report = $ref()
......@@ -24,7 +25,7 @@ function fetchInfo() {
report = res.data.report
let detail = []
// 已批改
if (report.status === '3') {
if (report.is_comment === '1') {
try {
detail = JSON.parse(report.score_detail).map(item => {
return { ...item, commit_score: parseFloat(item.commit_score) }
......@@ -40,9 +41,12 @@ function fetchInfo() {
}
}
report = Object.assign(report, { detail, score: parseFloat(report.score) })
nextTick(() => {
emit('ready')
})
})
}
onMounted(() => {
watchEffect(() => {
fetchInfo()
})
......@@ -54,95 +58,97 @@ function handleClose() {
<template>
<div class="report-preview">
<h1 class="report-title">实验报告</h1>
<el-form label-suffix=":" hide-required-asterisk v-if="experiment">
<el-row>
<el-col :span="12">
<el-form-item label="课程名称">{{ experiment.course.name }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="实验名称">{{ experiment.name }}</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="实验地点">{{ report.experiment_address }} </el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="实验日期"> {{ report.experiment_date }} </el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="实验类型">{{ experiment.type_level }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="指导教师">{{ teacherText }}</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="专业">{{ experiment.student.specialty.name }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="班级">{{ classText }}</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="姓名">{{ experiment.student.name }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="学号">{{ experiment.student.sno_number }}</el-form-item>
</el-col>
</el-row>
<el-divider />
<template v-if="isCommit">
<p class="report-score">实验报告得分:{{ report.score }}</p>
<div class="comment is-all">
<div class="comment-hd">实验报告整体评价</div>
<div class="comment-bd">{{ report.comment }}</div>
</div>
</template>
<el-form-item v-for="(item, index) in report.detail" :key="item.id" class="report-form-item">
<div class="form-hd">
<h3>{{ index + 1 }}、{{ item.name }}</h3>
<p>得分:{{ item.commit_score }}分</p>
</div>
<!-- 内容 -->
<template v-if="item.type === 1">
<p class="report-form-item__tips">{{ item.notice_message }}</p>
<div class="report-form-item__content" v-html="item.content"></div>
<div class="report-preview__inner">
<h1 class="report-title">实验报告</h1>
<el-form label-suffix=":" hide-required-asterisk v-if="experiment">
<el-row>
<el-col :span="12">
<el-form-item label="课程名称">{{ experiment.course.name }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="实验名称">{{ experiment.name }}</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="实验地点">{{ report.experiment_address }} </el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="实验日期"> {{ report.experiment_date }} </el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="实验类型">{{ experiment.type_level }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="指导教师">{{ teacherText }}</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="专业">{{ experiment.student.specialty.name }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="班级">{{ classText }}</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="姓名">{{ experiment.student.name }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="学号">{{ experiment.student.sno_number }}</el-form-item>
</el-col>
</el-row>
<el-divider />
<template v-if="isCommit">
<p class="report-score">实验报告得分:{{ report.score }}</p>
<div class="comment is-all">
<div class="comment-hd">实验报告整体评价</div>
<div class="comment-bd">{{ report.comment }}</div>
</div>
</template>
<!-- 附件 -->
<template v-if="item.type === 2">
<el-table :data="item.files" stripe :header-cell-style="{ background: '#ededed' }" style="margin-top: 20px">
<el-table-column label="序号" type="index" width="80" align="center"></el-table-column>
<el-table-column label="附件类型" prop="type" align="center">
<template #default="{ row }">
{{ row.type === '1' ? '本地上传' : '实验截图' }}
</template>
</el-table-column>
<el-table-column label="附件名称" prop="name" align="center"></el-table-column>
<el-table-column label="更新时间" prop="updated_time" align="center"></el-table-column>
<el-table-column label="操作" width="100" align="center">
<template #default="{ row }">
<el-button text type="primary"><a :href="row.url" target="_blank">查看</a></el-button>
</template>
</el-table-column>
</el-table>
</template>
<!-- 思考题 -->
<template v-if="item.type === 3">
<p class="report-form-item__tips">{{ item.question_stem }}</p>
<div class="report-form-item__content" v-html="item.content"></div>
</template>
<div class="comment" v-if="isCommit">
<div class="comment-hd">教师评价:</div>
<div class="comment-bd">{{ item.comment }}</div>
</div>
</el-form-item>
</el-form>
<el-form-item v-for="(item, index) in report.detail" :key="item.id" class="report-form-item">
<div class="form-hd">
<h3>{{ index + 1 }}、{{ item.name }}</h3>
<p v-if="isCommit">得分:{{ item.commit_score }}分</p>
</div>
<!-- 内容 -->
<template v-if="item.type === 1">
<p class="report-form-item__tips">{{ item.notice_message }}</p>
<div class="report-form-item__content" v-html="item.content"></div>
</template>
<!-- 附件 -->
<template v-if="item.type === 2">
<el-table :data="item.files" stripe :header-cell-style="{ background: '#ededed' }" style="margin-top: 20px">
<el-table-column label="序号" type="index" width="80" align="center"></el-table-column>
<el-table-column label="附件类型" prop="type" align="center">
<template #default="{ row }">
{{ row.type === '1' ? '本地上传' : '实验截图' }}
</template>
</el-table-column>
<el-table-column label="附件名称" prop="name" align="center"></el-table-column>
<el-table-column label="更新时间" prop="updated_time" align="center"></el-table-column>
<el-table-column label="操作" width="100" align="center">
<template #default="{ row }">
<el-button text type="primary"><a :href="row.url" target="_blank">查看</a></el-button>
</template>
</el-table-column>
</el-table>
</template>
<!-- 思考题 -->
<template v-if="item.type === 3">
<p class="report-form-item__tips">{{ item.question_stem }}</p>
<div class="report-form-item__content" v-html="item.content"></div>
</template>
<div class="comment" v-if="isCommit">
<div class="comment-hd">教师评价:</div>
<div class="comment-bd">{{ item.comment }}</div>
</div>
</el-form-item>
</el-form>
</div>
<el-row justify="center">
<el-button type="primary" plain auto-insert-space @click="handleClose">关闭</el-button>
</el-row>
......@@ -150,6 +156,10 @@ function handleClose() {
</template>
<style lang="scss" scoped>
.report-preview__inner {
padding: 40px;
background-color: #fff;
}
.report-title {
padding: 20px;
font-size: 20px;
......
<script setup lang="ts">
import type { ExperimentRecord } from '../types'
import { ElMessageBox } from 'element-plus'
import type { ExperimentRecord, ExperimentRecordFile } from '../types'
import { ElMessage, ElMessageBox } from 'element-plus'
import ImageViewer from '@/components/ImageViewer.vue'
import { uploadExperimentPicture } from '../api'
import { uploadExperimentPicture, getExperimentReport, getExperimentReportCache } from '../api'
const ResultScoreDialog = defineAsyncComponent(() => import('./ResultScoreDialog.vue'))
interface Props {
......@@ -29,7 +29,40 @@ function handlePreview(index: number) {
imageViewerIndex = index
}
// 删除
function handleRemove(index: number) {
async function handleRemove(index: number, file: ExperimentRecordFile) {
if (!props.experiment_id) return
let reportDetail: any = []
await getExperimentReportCache({ experiment_id: props.experiment_id }).then(res => {
const report = res.data.report
if (report.detail) {
try {
reportDetail = JSON.parse(report.detail)
} catch (error) {
console.log(error)
}
}
})
await getExperimentReport({ experiment_id: props.experiment_id }).then(res => {
const report = res.data.report
if (report.detail) {
try {
reportDetail = JSON.parse(report.detail)
} catch (error) {
console.log(error)
}
}
})
const reportFiles: any[] = reportDetail.reduce((result: any[], item: any) => {
if (item.type === 2) {
result = result.concat(item.files)
}
return result
}, [])
const found = reportFiles.find(item => item.url === file.url)
if (found) {
ElMessage.error('不能删除实验报告中的截图,请先删除实验报告关联的截图!')
return
}
ElMessageBox.confirm('删除之后无法恢复,确认删除该截图吗?', '提示').then(() => {
if (!props.experiment_id) return
const pictures = detail?.pictures.filter((item, i) => i !== index)
......@@ -60,7 +93,7 @@ function handleRemove(index: number) {
<div class="cover">
<div class="cover-inner">
<el-button type="primary" plain round @click="handlePreview(index)">查看</el-button>
<el-button type="primary" plain round @click="handleRemove(index)" v-if="canRemove">删除</el-button>
<el-button type="primary" plain round @click="handleRemove(index, item)" v-if="canRemove">删除</el-button>
</div>
</div>
</li>
......
......@@ -8,6 +8,7 @@ import { upload } from '@/utils/upload'
import { getExperiment, getExperimentRecord, uploadExperimentPicture, submitExperimentRecord } from '../api'
import dayjs from 'dayjs'
import { saveAs } from 'file-saver'
import { toBlob } from 'html-to-image'
const Info = defineAsyncComponent(() => import('../components/Info.vue'))
const Book = defineAsyncComponent(() => import('../components/Book.vue'))
......@@ -18,7 +19,7 @@ const ReportDialog = defineAsyncComponent(() => import('../components/ReportDial
const ReportFilePreview = defineAsyncComponent(() => import('../components/ReportFilePreview.vue'))
const PrepareDialog = defineAsyncComponent(() => import('../components/PrepareDialog.vue'))
const ResultDialog = defineAsyncComponent(() => import('../components/ResultDialog.vue'))
// const ReportPreview = defineAsyncComponent(() => import('../components/ReportPreview.vue'))
const ReportPreview = defineAsyncComponent(() => import('../components/ReportPreview.vue'))
const route = useRoute()
......@@ -179,16 +180,30 @@ function handleReportView() {
}
// 导出实验报告
let isExport = $ref(false)
function handleReportExport() {
if (!detail) return
const fileName = `${detail.student.sno_number}_${detail.student.name}_${detail.experiment.name}_实验报告`
// 在线报告
if (experimentInfo?.report_upload_way === 2) {
console.log('在线报告导出')
isExport = true
} else {
saveAs(detail.file.url, fileName)
}
}
function handleReportPreviewReady() {
if (!detail) return
const fileName = `${detail.student.sno_number}_${detail.student.name}_${detail.experiment.name}_实验报告`
const el: HTMLElement | null = document.querySelector('.report-preview__inner')
if (!el) return
setTimeout(() => {
toBlob(el).then(res => {
res && saveAs(res, fileName)
isExport = false
})
}, 100)
}
</script>
<template>
......@@ -296,9 +311,9 @@ function handleReportExport() {
v-if="resultDialogVisible && experimentInfo"></ResultDialog>
<!-- 导出在线报告 -->
<!-- <template v-if="experimentInfo?.id">
<ReportPreview :id="experimentInfo?.id"></ReportPreview>
</template> -->
<template v-if="experimentInfo?.id && isExport">
<ReportPreview :id="experimentInfo?.id" @ready="handleReportPreviewReady"></ReportPreview>
</template>
</template>
<style lang="scss" scoped>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论