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

chore: update

上级 b3a0067a
差异被折叠。
......@@ -25,15 +25,16 @@
"blueimp-md5": "^2.19.0",
"countup.js": "^2.3.2",
"dayjs": "^1.11.6",
"element-plus": "^2.2.19",
"element-plus": "^2.2.21",
"file-saver": "^2.0.5",
"lodash-es": "^4.17.21",
"pinia": "^2.0.23",
"qs": "^6.11.0",
"ua-parser-js": "^1.0.32",
"video.js": "^7.20.3",
"vue": "^3.2.41",
"vue-router": "^4.1.6"
"vue": "^3.2.45",
"vue-router": "^4.1.6",
"vuedraggable": "^4.1.0"
},
"devDependencies": {
"@rushstack/eslint-patch": "^1.2.0",
......@@ -51,10 +52,10 @@
"chalk": "^5.1.2",
"eslint": "^8.26.0",
"eslint-plugin-vue": "^9.7.0",
"sass": "^1.56.0",
"sass": "^1.56.1",
"typescript": "~4.8.4",
"unplugin-auto-import": "^0.11.4",
"vite": "^3.2.2",
"vite": "^3.2.3",
"vite-plugin-checker": "^0.5.1",
"vue-tsc": "^1.0.9"
}
......
......@@ -25,7 +25,7 @@ onMounted(() => {
<template>
<AppCard title="查看实验指导书">
<template v-if="detail">
<el-descriptions class="descriptions-box">
<el-descriptions>
<el-descriptions-item label="实验指导书名称:">{{ detail.name }}</el-descriptions-item>
<el-descriptions-item label="文件大小:">{{ detail.size_name }}</el-descriptions-item>
<el-descriptions-item label="观看次数:">{{ detail.pv }}</el-descriptions-item>
......
......@@ -37,7 +37,11 @@ const form = reactive<ExperimentCreateItem>({
type: '',
score: 100,
teachers_id: '',
teachers_ids: []
teachers_ids: [],
purpose: '',
requirements: '',
content: '',
procedure: ''
})
watchEffect(() => {
if (!props.data) return
......@@ -108,7 +112,7 @@ function handleUpdate(params: ExperimentCreateItem) {
<template>
<el-dialog :title="title" :close-on-click-modal="false" width="600px" @update:modelValue="$emit('update:modelValue')">
<el-form ref="formRef" :model="form" :rules="rules" label-width="150px">
<el-form ref="formRef" :model="form" :rules="rules" label-width="145px">
<el-form-item label="实验所属部门/学校" prop="organ_id">
<el-select v-model="form.organ_id" style="width: 100%" :disabled="isUpdate" @change="handleOrgChange">
<el-option v-for="item in organizations" :key="item.id" :label="item.name" :value="item.id"></el-option>
......@@ -138,6 +142,42 @@ function handleUpdate(params: ExperimentCreateItem) {
<el-form-item label="实验总成绩" prop="score">
<el-input-number v-model="form.score" :min="1" :max="150" step-strictly style="width: 100%" />
</el-form-item>
<el-form-item label="实验目的" prop="purpose">
<el-input
v-model="form.purpose"
:autosize="{ minRows: 4 }"
type="textarea"
maxlength="200"
show-word-limit
placeholder="请输入实验目的" />
</el-form-item>
<el-form-item label="实验要求" prop="requirements">
<el-input
v-model="form.requirements"
:autosize="{ minRows: 4 }"
type="textarea"
maxlength="200"
show-word-limit
placeholder="请输入实验要求" />
</el-form-item>
<el-form-item label="实验内容及原理" prop="content">
<el-input
v-model="form.content"
:autosize="{ minRows: 4 }"
type="textarea"
maxlength="200"
show-word-limit
placeholder="请输入实验内容及原理" />
</el-form-item>
<el-form-item label="实验步骤及过程" prop="procedure">
<el-input
v-model="form.procedure"
:autosize="{ minRows: 4 }"
type="textarea"
maxlength="200"
show-word-limit
placeholder="请输入实验步骤及过程" />
</el-form-item>
<el-form-item label="有效状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio v-for="item in status" :key="item.id" :label="item.value">{{ item.label }}</el-radio>
......
<script setup lang="ts">
import type { FormInstance } from 'element-plus'
import type { ExperimentItem } from '../types'
import { Plus } from '@element-plus/icons-vue'
import { gradeRuleList } from '@/utils/dictionary'
interface Props {
data: ExperimentItem
}
const props = defineProps<Props>()
const emit = defineEmits<{
(e: 'update'): void
(e: 'update:modelValue', visible: boolean): void
}>()
const formRef = $ref<FormInstance>()
const form = reactive({
is_show: 1,
rule_list: [
{
id: '232',
name: '实验报告',
type: 1,
percent: 100,
rule_mode: 1
}
]
})
// 添加
function handleAdd() {
form.rule_list.push({ id: '0', name: '', type: undefined, percent: 100, rule_mode: 1 })
}
// 删除
function handleRemove(index: number) {
form.rule_list.splice(index, 1)
}
// 提交
function handleSubmit() {
formRef?.validate().then(() => {
console.log(1)
})
}
// 当前评分方法
function currentRuleNames(value: number) {
const typeList = form.rule_list.map(item => item.type)
return gradeRuleList.filter(item => {
return item.value === value || item.value === 5 || !typeList.includes(item.value)
})
}
</script>
<template>
<el-dialog
title="编辑实验成绩规则"
:close-on-click-modal="false"
width="800px"
@update:modelValue="$emit('update:modelValue')">
<el-form ref="formRef" :model="form" label-suffix=":">
<el-form-item label="实验名称">{{ data?.name }}</el-form-item>
<el-form-item label="是否允许查看成绩明细" prop="is_show">
<el-radio-group v-model="form.is_show">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-row justify="space-between" style="width: 100%">
<p>实验成绩规则:</p>
<el-button type="primary" :icon="Plus" @click="handleAdd"></el-button>
</el-row>
<el-table :data="form.rule_list" row-key="id">
<el-table-column prop="name">
<template #default="{ row }">
<el-input v-model="row.name" style="width: 100%" v-if="row.type === 5" />
<el-select v-model="row.type" :disabled="row.type === 1" style="width: 100%" v-else>
<el-option v-for="item in currentRuleNames(row.type)" :key="item.value" v-bind="item"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="percent" align="center" width="200">
<template #default="{ row }"><el-input-number v-model="row.percent" /> %</template>
</el-table-column>
<el-table-column prop="rule_mode">
<template #default="{ row }">
<el-radio-group v-model="row.rule_mode">
<el-radio :label="1">手工评分</el-radio>
<el-radio :label="2" v-if="[2, 3].includes(row.type)">自动评分</el-radio>
</el-radio-group>
</template>
</el-table-column>
<el-table-column prop="rule_mode" align="center" width="90">
<template #default="{ $index }">
<el-button text type="primary" @click="handleRemove($index)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
<el-row justify="center">
<el-button type="primary" round auto-insert-space @click="handleSubmit">保存</el-button>
<el-button round auto-insert-space @click="$emit('update:modelValue', false)">取消</el-button>
</el-row>
</el-dialog>
</template>
<script setup lang="ts">
import type { Component } from 'vue'
import { Delete } from '@element-plus/icons-vue'
import { ElMessageBox } from 'element-plus'
import draggable from 'vuedraggable'
const ReportDesignContent = defineAsyncComponent(() => import('./ReportDesignContent.vue'))
const ReportDesignAttachment = defineAsyncComponent(() => import('./ReportDesignAttachment.vue'))
const ReportDesignQuestion = defineAsyncComponent(() => import('./ReportDesignQuestion.vue'))
const ReportDesignPaper = defineAsyncComponent(() => import('./ReportDesignPaper.vue'))
interface Props {
modelValue: any[]
}
const props = defineProps<Props>()
const emit = defineEmits<{
(e: 'update:modelValue', data: any[]): void
}>()
let datalist = $ref<any[]>([])
watchEffect(() => {
datalist = [...props.modelValue] || []
})
function getComponent(type: number) {
const map: Record<number, Component> = {
1: ReportDesignContent,
2: ReportDesignAttachment,
3: ReportDesignQuestion,
4: ReportDesignPaper
}
return map[type]
}
// 添加
function handleAdd(type: number) {
datalist.unshift({ type })
}
// 删除
function handleRemove(index: number) {
ElMessageBox.confirm('删除组件将导致报告分值的变化,请确认是否删除组件?', '提示').then(() => {
datalist.splice(index, 1)
})
}
function handleChange(data: any, index: number) {
datalist[index] = data
emit('update:modelValue', datalist)
}
</script>
<template>
<div class="report-design">
<div class="report-design-hd">
<el-button-group>
<el-button type="primary" @click="handleAdd(1)">添加内容组件</el-button>
<el-button type="primary" @click="handleAdd(2)">添加附件组件</el-button>
<el-button type="primary" @click="handleAdd(3)">添加思考题组件</el-button>
<el-button type="primary" @click="handleAdd(4)">添加试卷组件</el-button>
</el-button-group>
</div>
<div class="report-design-bd">
<draggable v-model="datalist" item-key="id">
<template #item="{ element, index }">
<div class="report-design-item-card">
<component
:is="getComponent(element.type)"
:data="element"
@change="(data:any) => handleChange(data, index)" />
<el-button type="danger" :icon="Delete" circle @click="handleRemove(index)" />
</div>
</template>
</draggable>
</div>
</div>
</template>
<style lang="scss">
.report-design-item-card {
display: flex;
align-items: center;
.report-design-item {
flex: 1;
margin-right: 20px;
}
}
.report-design-item {
position: relative;
margin: 20px 0;
padding: 10px;
background-color: #e8eff7;
border: 1px solid #bbb;
border-radius: 6px;
}
</style>
<script setup lang="ts">
interface Props {
data: any
}
const props = defineProps<Props>()
const emit = defineEmits<{
(e: 'change', data: any): void
}>()
const form = reactive({
name: '',
type: 1,
categories: [],
rule_mode: 1,
score: 10,
min_score: 0,
has_score: 0,
no_score: 0
})
watchEffect(() => {
const score = props.data.score ? parseFloat(props.data.score) : 0
const minScore = props.data.min_score ? parseFloat(props.data.min_score) : 0
const hasScore = props.data.has_score ? parseFloat(props.data.has_score) : 0
const noScore = props.data.no_score ? parseFloat(props.data.no_score) : 0
Object.assign(form, props.data, { score, min_score: minScore, has_score: hasScore, no_score: noScore })
})
watch(form, value => emit('change', value), { deep: true })
</script>
<template>
<div class="report-design-item">
<el-form :model="form" label-suffix=":">
<el-row :gutter="40">
<el-col :span="6">
<el-form-item label="附件组件名称" prop="name" label-width="130px">
<el-input v-model="form.name" placeholder="例:实验源代码程序包" maxlength="20" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="分值" prop="score">
<el-input-number :min="0" v-model="form.score" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="评分规则" prop="rule_mode">
<el-radio-group v-model="form.rule_mode">
<el-radio :label="1">人工评分</el-radio>
<el-radio :label="2">自动评分</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="最低分" prop="min_score">
<el-input-number :min="0" v-model="form.min_score" v-if="form.rule_mode === 1" />
<template v-else>
<el-form-item label="有附件" label-width="auto" style="margin-right: 10px; margin-bottom: 10px">
<el-input-number :min="0" v-model="form.has_score" />
</el-form-item>
<el-form-item label="无附件" label-width="auto" style="margin-bottom: 10px">
<el-input-number :min="0" v-model="form.no_score" />
</el-form-item>
</template>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="附件类型" prop="categories" label-width="130px">
<el-checkbox-group v-model="form.categories">
<el-checkbox :label="1">实验截图</el-checkbox>
<el-checkbox :label="2">本地文件</el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-form>
</div>
</template>
<script setup lang="ts">
interface Props {
data: any
}
const props = defineProps<Props>()
const emit = defineEmits<{
(e: 'change', data: any): void
}>()
const form = reactive({ name: '', type: 1, notice_message: '', rule_mode: 1, score: 10, min_score: 0 })
watchEffect(() => {
const score = props.data.score ? parseFloat(props.data.score) : 0
const minScore = props.data.min_score ? parseFloat(props.data.min_score) : 0
Object.assign(form, props.data, { score, min_score: minScore })
})
watch(form, value => emit('change', value), { deep: true })
</script>
<template>
<div class="report-design-item">
<el-form :model="form" label-suffix=":">
<el-row :gutter="40">
<el-col :span="6">
<el-form-item label="内容组件名称" prop="name" label-width="130px">
<el-input v-model="form.name" placeholder="例:实验目的" maxlength="20" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="分值" prop="score">
<el-input-number :min="0" v-model="form.score" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="评分规则" prop="rule_mode">
<el-radio-group v-model="form.rule_mode">
<el-radio :label="1">人工评分</el-radio>
<!-- <el-radio :label="2">自动评分</el-radio> -->
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="最低分" prop="min_score">
<el-input-number :min="0" v-model="form.min_score" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="组件提示信息" prop="notice_message" label-width="130px">
<el-input
type="textarea"
v-model="form.notice_message"
:autosize="{ minRows: 4 }"
show-word-limit
maxlength="200" />
</el-form-item>
</el-form>
</div>
</template>
<script setup lang="ts">
interface Props {
data: any
}
const props = defineProps<Props>()
const form = reactive({ name: '', type: 1, notice_message: '', rule_mode: 1, score: 10, min_score: 0 })
watchEffect(() => {
const score = props.data.score ? parseFloat(props.data.score) : 0
const minScore = props.data.min_score ? parseFloat(props.data.min_score) : 0
Object.assign(form, props.data, { score, min_score: minScore })
})
</script>
<template>
<div class="report-design-item">
<el-form :model="form" label-suffix=":">
<el-row :gutter="40">
<el-col :span="6">
<el-form-item label="试卷组件名称" prop="name" label-width="130px">
<el-input v-model="form.name" placeholder="例:商业数据分析基础理论" maxlength="20" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="分值" prop="score">
<el-input-number :min="0" v-model="form.score" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="评分规则" prop="rule_mode">
<el-radio-group v-model="form.rule_mode">
<el-radio :label="1">人工评分</el-radio>
<el-radio :label="2">自动评分</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="最低分" prop="min_score">
<el-input-number :min="0" v-model="form.min_score" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="试卷组卷说明" prop="notice_message" label-width="130px">
<el-input
type="textarea"
v-model="form.notice_message"
:autosize="{ minRows: 4 }"
show-word-limit
maxlength="200" />
</el-form-item>
</el-form>
</div>
</template>
<script setup lang="ts">
interface Props {
data: any
}
const props = defineProps<Props>()
const emit = defineEmits<{
(e: 'change', data: any): void
}>()
const form = reactive({ name: '', type: 1, question_stem: '', rule_mode: 1, score: 10, min_score: 0 })
watchEffect(() => {
const score = props.data.score ? parseFloat(props.data.score) : 0
const minScore = props.data.min_score ? parseFloat(props.data.min_score) : 0
Object.assign(form, props.data, { score, min_score: minScore })
})
watch(form, value => emit('change', value), { deep: true })
</script>
<template>
<div class="report-design-item">
<el-form :model="form" label-suffix=":">
<el-row :gutter="40">
<el-col :span="6">
<el-form-item label="思考题组件名称" prop="name" label-width="130px">
<el-input v-model="form.name" placeholder="例:实验扩展思考" maxlength="20" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="分值" prop="score">
<el-input-number :min="0" v-model="form.score" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="评分规则" prop="rule_mode">
<el-radio-group v-model="form.rule_mode">
<el-radio :label="1">人工评分</el-radio>
<!-- <el-radio :label="2">自动评分</el-radio> -->
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="最低分" prop="min_score">
<el-input-number :min="0" v-model="form.min_score" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="思考题题干内容" prop="question_stem" label-width="130px">
<el-input
type="textarea"
v-model="form.question_stem"
:autosize="{ minRows: 4 }"
show-word-limit
maxlength="200" />
</el-form-item>
</el-form>
</div>
</template>
<script setup lang="ts">
import { reportScoreRule } from '@/utils/dictionary'
interface Props {
data: any
}
const props = defineProps<Props>()
const teacherText = $computed(() => {
if (!props.data) return ''
return props.data.teacher.map(item => item.name).join('、')
})
</script>
<template>
<el-dialog title="预览" class="report-preview">
<h1>实验报告</h1>
<el-form label-suffix=":">
<el-row>
<el-col :span="12">
<el-form-item label="课程名称">{{ data.course_name }}</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="实验名称">{{ data.name }}</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="实验地点"></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="实验日期"></el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="实验类型">{{ data.type_name }}</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="专业"></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="班级"></el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="姓名"></el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="学号"></el-form-item>
</el-col>
</el-row>
<el-divider />
<p class="total-score">总分:{{ data.score }}</p>
<el-form-item v-for="(item, index) in data.detail_list" :key="item.id">
<div class="form-hd">
<h3>{{ index + 1 }}{{ item.name }}</h3>
<p class="score">{{ item.score }}</p>
<p class="rule-mode">{{ reportScoreRule[item.rule_mode] }}</p>
</div>
<el-input
type="textarea"
readonly
:autosize="{ minRows: 6 }"
:value="item.notice_message || item.question_stem" />
</el-form-item>
</el-form>
<el-row justify="center">
<el-button type="primary" round auto-insert-space @click="$emit('update:modelValue', false)">关闭</el-button>
</el-row>
</el-dialog>
</template>
<style lang="scss">
.report-preview {
h1 {
font-size: 24px;
text-align: center;
padding-bottom: 30px;
}
.total-score {
text-align: right;
padding-right: 100px;
}
.form-hd {
display: flex;
width: 100%;
font-size: 14px;
font-weight: bold;
h3 {
flex: 1;
}
.rule-mode {
width: 100px;
text-align: right;
}
}
}
</style>
......@@ -9,7 +9,8 @@ export const routes: Array<RouteRecordRaw> = [
children: [
{ path: 'experiment', component: () => import('./views/Index.vue') },
{ path: 'experiment/:id', component: () => import('./views/View.vue'), props: true },
{ path: 'experiment/group/:id', component: () => import('./views/Group.vue'), props: true }
{ path: 'experiment/group/:id', component: () => import('./views/Group.vue'), props: true },
{ path: 'experiment/report/:id', component: () => import('./views/Report.vue'), props: true }
]
}
]
......@@ -26,6 +26,10 @@ export interface ExperimentItem {
updated_operator: string
updated_operator_name: string
updated_time: string
purpose: string
requirements: string
content: string
procedure: string
}
export interface ExperimentCreateItem {
......@@ -39,6 +43,10 @@ export interface ExperimentCreateItem {
score: number
teachers_id: string
teachers_ids?: string[]
purpose: string
requirements: string
content: string
procedure: string
}
export interface ClassItem {
......
......@@ -63,7 +63,7 @@ function handleRemoveStudent(row: StudentItem) {
<template>
<AppCard title="实验管理">
<el-descriptions class="descriptions-box" :column="2" v-if="detail">
<el-descriptions :column="2" v-if="detail">
<el-descriptions-item label="实验名称:">{{ detail.experiment_name }}</el-descriptions-item>
<el-descriptions-item label="实验课程:">{{ detail.course_name }}</el-descriptions-item>
<el-descriptions-item label="小组名称:">{{ detail.name }}</el-descriptions-item>
......@@ -95,6 +95,5 @@ function handleRemoveStudent(row: StudentItem) {
<SelectStudentDialog
v-model="selectStudentVisible"
@update="handleRefetch"
v-if="selectStudentVisible"
></SelectStudentDialog>
v-if="selectStudentVisible"></SelectStudentDialog>
</template>
......@@ -8,6 +8,7 @@ import { useGetCourseExperimentList } from '../composables/useGetCourseExperimen
import { useMapStore } from '@/stores/map'
const FormDialog = defineAsyncComponent(() => import('../components/FormDialog.vue'))
const GradeRulesDialog = defineAsyncComponent(() => import('../components/GradeRulesDialog.vue'))
// 数据状态
const status = useMapStore().getMapValuesByKey('system_status')
......@@ -113,6 +114,12 @@ function handleUpdate(row: ExperimentItem) {
function onUpdateSuccess() {
appList?.refetch()
}
let gradeRulesDialogVisible = $ref(false)
function handleUpdateGradeRules(row: ExperimentItem) {
rowData.value = row
gradeRulesDialogVisible = true
}
</script>
<template>
......@@ -125,6 +132,13 @@ function onUpdateSuccess() {
</template>
<template #table-x="{ row }: { row: ExperimentItem }">
<el-button type="info" round style="width: 132px; margin-bottom: 12px" @click="handleUpdateGradeRules(row)"
>编辑成绩规则</el-button
><br />
<el-button type="info" round style="width: 132px; margin-bottom: 12px">
<router-link :to="`/admin/lab/experiment/report/${row.id}`" target="_blank">编辑报告规则</router-link>
</el-button>
<br />
<el-button type="primary" round v-permission="'v1-backend-experiment-view'">
<router-link :to="`/admin/lab/experiment/${row.id}`" target="_blank">查看</router-link>
</el-button>
......@@ -138,4 +152,10 @@ function onUpdateSuccess() {
</AppList>
</AppCard>
<FormDialog v-model="dialogVisible" :data="rowData" @update="onUpdateSuccess" v-if="dialogVisible"></FormDialog>
<!-- 编辑实验成绩规则 -->
<GradeRulesDialog
v-model="gradeRulesDialogVisible"
:data="rowData"
@update="onUpdateSuccess"
v-if="gradeRulesDialogVisible && rowData"></GradeRulesDialog>
</template>
<script setup lang="ts">
import type { ExperimentItem } from '../types'
import { ElMessageBox } from 'element-plus'
import ReportDesign from '../components/ReportDesign.vue'
import { getExperiment } from '../api'
const ReportPreview = defineAsyncComponent(() => import('../components/ReportPreview.vue'))
interface Props {
id: string
}
const props = defineProps<Props>()
let detail = $ref<ExperimentItem>()
const teacherText = $computed(() => {
if (!detail) return ''
return detail.teacher.map(item => item.name).join('、')
})
function fetchInfo() {
getExperiment({ experiment_id: props.id }).then(res => {
detail = res.data.info
})
}
const form = reactive({
switch: true,
detail_list: [
{
id: '233434343',
name: '实验目的',
type: 1,
notice_message: '好好学习天线向上',
rule_mode: 1,
score: '10.00',
min_score: '5.00'
},
{
id: '233434344',
name: '实验附件',
type: 2,
rule_mode: 2,
score: '10.00',
min_score: '5.00',
categories: [1, 2],
has_score: '8.00',
no_score: '5.00'
},
{
id: '233434344',
name: '思考题',
type: 3,
rule_mode: 1,
score: '10.00',
min_score: '5.00',
question_stem: '这是思考题的题干'
}
]
})
onMounted(() => fetchInfo())
// 保存
function handleSubmit() {}
// 关闭
function handleClose() {
ElMessageBox.confirm('此操作将不做任何修改,确认关闭该页面?', '提示').then(() => {
window.close()
})
}
// 预览
let previewVisible = $ref(false)
function handlePreview() {
previewVisible = true
}
</script>
<template>
<AppCard title="实验报告规则设置">
<el-form :model="form" label-suffix=":" v-if="detail">
<el-row>
<el-col :span="8">
<el-form-item label="实验名称">{{ detail.name }}</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="实验课程名称">{{ detail.course_name }}</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="所属机构/学校">{{ detail.organ_id_name }}</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="实验类型">{{ detail.type_name }}</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item :span="3" label="指导教师">{{ teacherText }}</el-form-item>
</el-col>
</el-row>
<el-form-item label="实验报告提交方式" prop="switch">
<el-switch
v-model="form.switch"
active-text="上传文件"
inactive-text="在线填写"
style="--el-switch-on-color: #ba143e; --el-switch-off-color: #ba143e" />
</el-form-item>
<ReportDesign v-model="form.detail_list"></ReportDesign>
</el-form>
<el-row justify="center">
<el-space :size="40">
<el-button auto-insert-space @click="handleClose">关闭</el-button>
<el-button type="primary" auto-insert-space @click="handleSubmit">保存</el-button>
<el-button type="primary" auto-insert-space @click="handlePreview">预览</el-button>
</el-space>
</el-row>
<ReportPreview v-model="previewVisible" :data="{ ...detail, ...form }"></ReportPreview>
</AppCard>
</template>
......@@ -18,6 +18,11 @@ const props = defineProps<Props>()
let detail = $ref<ExperimentItem | null>(null)
provide('detail', $$(detail))
const teacherText = $computed(() => {
if (!detail) return ''
return detail.teacher.map(item => item.name).join('、')
})
const appList = $ref<InstanceType<typeof AppList> | null>(null)
// 列表配置
const listOptions = {
......@@ -74,11 +79,24 @@ function handleRemoveClass(row: ClassItem) {
<template>
<AppCard title="实验管理">
<el-descriptions class="descriptions-box" v-if="detail">
<el-descriptions-item label="实验名称:">{{ detail.name }}</el-descriptions-item>
<el-descriptions title="基本信息" v-if="detail">
<template #extra>
<el-button type="primary">查看成绩规则</el-button>
<el-button type="primary">查看报告规则</el-button>
</template>
<el-descriptions-item :span="3" label="实验名称:">{{ detail.name }}</el-descriptions-item>
<el-descriptions-item label="实验课程:">{{ detail.course_name }}</el-descriptions-item>
<el-descriptions-item label="所属机构/学校:">{{ detail.organ_id_name }}</el-descriptions-item>
<el-descriptions-item label="实验总成绩:">{{ detail.score }}</el-descriptions-item>
<el-descriptions-item label="实验类型:">{{ detail.type_name }}</el-descriptions-item>
<el-descriptions-item :span="2" label="实验学时:">{{ detail.length }}学时</el-descriptions-item>
<el-descriptions-item :span="3" label="指导教师:">{{ teacherText }}</el-descriptions-item>
<el-descriptions-item :span="3" label="实验目的:">{{ detail.purpose }}</el-descriptions-item>
<el-descriptions-item :span="3" label="实验要求:">{{ detail.requirements }}</el-descriptions-item>
<el-descriptions-item :span="3" label="实验内容及原理:">{{ detail.content }}</el-descriptions-item>
<el-descriptions-item :span="3" label="实验步骤及过程:">{{ detail.procedure }}</el-descriptions-item>
</el-descriptions>
<el-divider />
<AppList v-bind="listOptions" ref="appList">
<template #header-buttons>
<el-button
......@@ -116,12 +134,10 @@ function handleRemoveClass(row: ClassItem) {
<StudentGroupDialog
v-model="studentGroupVisible"
:data="rowData"
v-if="studentGroupVisible && rowData"
></StudentGroupDialog>
v-if="studentGroupVisible && rowData"></StudentGroupDialog>
<!-- 查看学生 -->
<StudentListDialog
v-model="studentListVisible"
:data="rowData"
v-if="studentListVisible && rowData"
></StudentListDialog>
v-if="studentListVisible && rowData"></StudentListDialog>
</template>
......@@ -36,7 +36,7 @@ onMounted(() => {
<template>
<AppCard title="查看实验操作视频">
<template v-if="detail">
<el-descriptions class="descriptions-box">
<el-descriptions>
<el-descriptions-item label="实验操作视频名称:">{{ detail.name }}</el-descriptions-item>
<el-descriptions-item label="文件大小:">{{ detail.size_name }}</el-descriptions-item>
<el-descriptions-item label="观看次数:">{{ detail.pv }}</el-descriptions-item>
......
......@@ -4,14 +4,14 @@ export const json2Array = function (data: any, isValueToNumber = true) {
}
// 参赛模式
export const contestMode: Record<string, any> = {
export const contestMode: Record<number, any> = {
1: '个人赛'
}
// 参赛模式列表
export const contestModeList = json2Array(contestMode, false)
// 评分规则
export const scoreRule: Record<string, any> = {
export const scoreRule: Record<number, any> = {
1: '平均法',
2: '加权平均法',
3: '综合得分法',
......@@ -19,3 +19,21 @@ export const scoreRule: Record<string, any> = {
}
// 参赛模式列表
export const scoreRuleList = json2Array(scoreRule, false)
// 实验成绩规则
export const gradeRule: Record<number, any> = {
1: '实验报告',
2: '实验准备',
3: '实验结果',
4: '课堂活跃度',
5: '自定义'
}
// 参赛模式列表
export const gradeRuleList = json2Array(gradeRule)
// 实验报告评分规则
export const reportScoreRule: Record<number, any> = {
1: '手工评分',
2: '自动评分'
}
export const reportScoreRuleList = json2Array(reportScoreRule)
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论