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

chore: 优化实验成绩管理

上级 70618bc3
......@@ -20,6 +20,10 @@ let detail = $ref<RecordItem>()
function fetchInfo() {
getExperimentRecord({ experiment_id: props.data.experiment_id, student_id: props.data.student_id }).then(res => {
detail = res.data
const score = res.data.score_details || {}
form.file = score.file ? parseFloat(score.file) : 0
form.operate = score.operate ? parseFloat(score.operate) : 0
form.result = score.result ? parseFloat(score.result) : 0
})
}
watchEffect(() => {
......@@ -80,8 +84,7 @@ function handleSubmit() {
title="学生实验评分"
:close-on-click-modal="false"
width="700px"
@update:modelValue="$emit('update:modelValue')"
>
@update:modelValue="$emit('update:modelValue')">
<el-form :rules="rules" label-width="120px" label-suffix=":" v-if="detail">
<el-row>
<el-col :span="12">
......@@ -116,8 +119,7 @@ function handleSubmit() {
hide-required-asterisk
inline
label-position="top"
style="padding: 5px 0 20px"
>
style="padding: 5px 0 20px">
<el-form-item label="实验操作" prop="operate">
<el-input-number :min="1" :max="100" :controls="false" step-strictly v-model="form.operate" />
</el-form-item>
......
<script setup lang="ts">
import type { RecordItem } from '../types'
import AppList from '@/components/base/AppList.vue'
import { getExperimentRecord } from '../api'
interface Props {
data: RecordItem
}
const props = defineProps<Props>()
let detail = $ref<RecordItem>()
function fetchInfo() {
getExperimentRecord({ experiment_id: props.data.experiment_id, student_id: props.data.student_id }).then(res => {
detail = res.data
})
}
watchEffect(() => {
fetchInfo()
})
const appList = $ref<InstanceType<typeof AppList> | null>(null)
// 列表配置
const listOptions = $computed(() => {
return {
columns: [
{ label: '序号', type: 'index', width: 60 },
{ label: '姓名', prop: 'student_name', slots: 'table-name' },
{ label: '学号', prop: 'sno_number', slots: 'table-number' },
{ label: '实验操作成绩', prop: 'operate' },
{ label: '实验结果成绩', prop: 'result' },
{ label: '实验报告成绩', prop: 'file' },
{ label: '综合实验成绩', prop: 'score' },
{ label: '评分时间', prop: 'check_time' },
{ label: '评分人', prop: 'checker_id_name' }
],
data: detail?.score_log
}
})
</script>
<template>
<el-dialog title="查看历史成绩">
<AppList v-bind="listOptions" ref="appList">
<template #table-name>{{ detail.student_name }}</template>
<template #table-number>{{ detail.sno_number }}</template>
</AppList>
</el-dialog>
</template>
<style lang="scss" scoped>
.file-item {
display: flex;
align-items: center;
color: var(--main-color);
.el-icon {
margin-right: 5px;
}
}
.picture-list {
width: 100%;
li {
display: flex;
justify-content: space-between;
}
a {
color: var(--main-color);
}
.t1 {
flex: 1;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
}
.form-item-score {
padding-top: 10px;
background-color: #f8f9fb;
border-radius: 16px;
:deep(.el-form-item__label) {
text-align: center;
}
.el-input-number {
width: 100px;
}
}
</style>
......@@ -18,6 +18,7 @@ export interface RecordItem {
status_name: string
student_id: string
student_name: string
score_log: ScoreLog[]
}
export interface FileItem {
......@@ -25,3 +26,13 @@ export interface FileItem {
url: string
upload_time: string
}
export interface ScoreLog {
operate: string
result: string
file: string
score: string
checker_id: string
check_time: string
checker_id_name: string
}
......@@ -7,6 +7,7 @@ import { useFilterList } from '../composables/useFilterList'
const ScoreDialog = defineAsyncComponent(() => import('../components/ScoreDialog.vue'))
const ImportDialog = defineAsyncComponent(() => import('../components/ImportDialog.vue'))
const ScoreLogDialog = defineAsyncComponent(() => import('../components/ScoreLogDialog.vue'))
const { courses, experiments, specialties, classes } = useFilterList()
......@@ -95,18 +96,24 @@ const listOptions = $computed(() => {
{ label: '提交状态', prop: 'status_name', slots: 'table-status' },
{ label: '实验成绩', prop: 'score', slots: 'table-score' },
{ label: '更新时间', prop: 'commit_time' },
{ label: '操作', slots: 'table-x', width: 100 }
{ label: '操作', slots: 'table-x', width: 210 }
]
}
})
const importVisible = $ref(false)
let dialogVisible = $ref(false)
let scoreLogVisible = $ref(false)
const rowData = ref<RecordItem>()
// 评分
function handleScore(row: RecordItem) {
rowData.value = row
dialogVisible = true
}
// 历史成绩
function handleScoreLog(row: RecordItem) {
rowData.value = row
scoreLogVisible = true
}
function onUpdateSuccess() {
appList?.refetch()
}
......@@ -140,11 +147,19 @@ function onUpdateSuccess() {
<el-button
text
type="primary"
v-if="row.status === 1"
v-if="row.status === 1 || row.status === 2"
@click="handleScore(row)"
v-permission="'v1-teacher-record-check'"
>打分</el-button
>
<el-button
text
type="primary"
v-if="row.has_score_log"
@click="handleScoreLog(row)"
v-permission="'v1-teacher-record-check'"
>查看历史成绩</el-button
>
</template>
</AppList>
</AppCard>
......@@ -153,8 +168,9 @@ function onUpdateSuccess() {
v-model="dialogVisible"
:data="rowData"
@update="onUpdateSuccess"
v-if="dialogVisible && rowData"
></ScoreDialog>
v-if="dialogVisible && rowData"></ScoreDialog>
<!-- 历史成绩 -->
<ScoreLogDialog v-model="scoreLogVisible" :data="rowData" v-if="scoreLogVisible && rowData"></ScoreLogDialog>
<!-- 批量导入 -->
<ImportDialog v-model="importVisible" @update="onUpdateSuccess" v-if="importVisible"></ImportDialog>
</template>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论