123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- <template>
- <div class="exam-train-exam-marking-edit-container layout-padding">
- <div class="exam-train-exam-marking-edit-container-box pd20 h100">
- <splitpanes :horizontal="false">
- <pane min-size="16" max-size="25" size="16" class="left-container">
- <p class="border-title mb20">考试人员</p>
- <el-scrollbar ref="scrollBarRef" style="height: calc(100% - 55px)" always>
- <el-auto-resizer class="table">
- <template #default="{ height }">
- <el-skeleton :loading="state.userLoading" animated :rows="10">
- <template #default>
- <el-tree-v2
- :data="state.userList"
- highlight-current
- :expand-on-click-node="false"
- node-key="userId"
- :props="{ children: 'children', label: 'userName' }"
- @node-click="handleNodeClick"
- :current-node-key="state.userList[0]?.id"
- ref="treeRef"
- :item-size="36"
- empty-text="暂无数据"
- :height="height"
- >
- <template #default="{ node }">
- <span>{{ node.label }}</span>
- </template>
- </el-tree-v2>
- </template>
- </el-skeleton>
- </template>
- </el-auto-resizer>
- </el-scrollbar>
- </pane>
- <pane class="right-container">
- <p class="border-title mb20">阅卷试卷</p>
- <div style="overflow: hidden; width: 100%; height: 100%; flex: 1">
- <el-scrollbar style="height: calc(100% - 32px)" always v-loading="state.loading">
- <div class="h100 w100 exam-container">
- <template v-if="state.examList.length">
- <div v-for="item in state.examList" :key="item.id" class="exam-item">
- <p class="exam-item-questionName">
- 题目:{{ item.title }} <span v-if="item.questionScore">({{ item.questionScore }}分)</span>
- </p>
- <p class="exam-item-answer">回答答案:{{ item.answer }}</p>
- <el-divider></el-divider>
- <p class="exam-item-referenceAnswer">参考答案:{{ item.correctAnswer }}</p>
- <div class="exam-item-score">
- 分数:
- <span v-if="isView">{{ item.score }}</span>
- <el-input-number
- v-model="item.score"
- :step="1"
- :precision="0"
- :min="0"
- :max="item.questionScore"
- placeholder="请填写分数"
- style="width: 200px"
- v-else
- ></el-input-number>
- </div>
- <el-divider></el-divider>
- </div>
- </template>
- <el-empty description="该考试人员暂未考试完成" v-else></el-empty>
- </div>
- </el-scrollbar>
- </div>
- <div class="flex-center-between flex-center-align">
- <el-text type="danger" tag="b" class="mr20" v-if="!isView">温馨提示:保存仅保存当前用户的试卷分数</el-text>
- <span v-else></span>
- <div>
- <el-button type="primary" @click="onSave(ruleFormRef)" :loading="state.loading" v-if="!isView && state.examList.length">保存</el-button>
- <!-- <el-button type="primary" @click="onSubmit" :loading="state.loading">提交</el-button>-->
- <el-button class="default-button" @click="onCancel" :loading="state.loading">取消 </el-button>
- </div>
- </div>
- </pane>
- </splitpanes>
- </div>
- </div>
- </template>
- <script setup lang="ts" name="examTrainExamMarkingEdit">
- import { computed, onMounted, reactive, ref } from 'vue';
- import { ElMessage } from 'element-plus';
- import mittBus from '@/utils/mitt';
- import { useRoute, useRouter } from 'vue-router';
- import { Splitpanes, Pane } from 'splitpanes';
- import 'splitpanes/dist/splitpanes.css';
- import { throttle } from '@/utils/tools';
- import { batchMarking, getMarkingDetailByUser, getMarkingDetailUser } from '@/api/examTrain/marking';
- // 定义变量内容
- const state = reactive<any>({
- loading: false,
- userList: [], // 用户列表
- queryParams: {},
- userLoading: false,
- UserId: null, // 用户ID
- examList: [], // 试卷列表
- });
- const route = useRoute(); // 获取路由
- const router = useRouter(); // 路由跳转
- const ruleFormRef = ref<any>(); // 表单ref
- // 点击人员查询试卷
- const handleNodeClick = (data: any) => {
- state.UserId = data.userId;
- getExamManageDetailData();
- };
- // 获取用户列表
- const routeParams = route.params;
- const getUserList = async () => {
- state.userLoading = true;
- try {
- const { result } = await getMarkingDetailUser({ ExamId: route.params.examId });
- state.userList = result ?? [];
- state.userLoading = false;
- state.UserId = result[0]?.userId;
- await getExamManageDetailData();
- } catch (error) {
- console.error(error);
- state.userLoading = false;
- }
- };
- // 根据用户获取试卷内容
- const getExamManageDetailData = async () => {
- state.loading = true;
- try {
- const { result } = await getMarkingDetailByUser({ ExamId: route.params.examId, UserId: state.UserId });
- state.examList = result ?? [];
- state.loading = false;
- } catch (error) {
- console.error(error);
- state.loading = false;
- }
- };
- // 保存提交
- const onSave = throttle(() => {
- // 校验阅卷是否完成
- for (const item of state.examList) {
- if (item.score === undefined || item.score === null) {
- ElMessage.warning(`请填写【${item.title}】的分数`);
- return;
- }
- }
- const request = state.examList.map((item: any) => {
- return {
- userExamItemId: item.id,
- score: item.score,
- };
- });
- state.loading = true;
- batchMarking({ items: request })
- .then(() => {
- state.loading = false;
- handleSuccess();
- })
- .catch((error) => {
- console.error(error);
- state.loading = false;
- });
- }, 300);
- // 取消
- const onCancel = () => {
- mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 1, ...route }));
- mittBus.emit('clearCache', 'examTrainExamMarking');
- router.push({
- path: '/examTrain/exam/marking',
- });
- };
- // 是否查看
- const isView = computed(() => {
- return route.params.isView === 'true';
- });
- const handleSuccess = () => {
- state.loading = false;
- ElMessage.success('保存成功');
- };
- onMounted(() => {
- state.queryParams.ExamId = routeParams.examId;
- getUserList();
- });
- </script>
- <style lang="scss" scoped>
- .exam-train-exam-marking-edit-container {
- .exam-train-exam-marking-edit-container-box {
- background-color: var(--el-color-white);
- overflow: hidden;
- }
- .right-container {
- height: 100%;
- display: flex;
- flex-direction: column;
- }
- }
- :deep(.el-tree-node__content) {
- height: 40px;
- }
- .exam-container {
- .exam-item {
- margin-bottom: 20px;
- &-questionName {
- font-size: 16px;
- margin-bottom: 10px;
- }
- &-answer {
- text-indent: 1em;
- margin-bottom: 10px;
- }
- &-referenceAnswer {
- display: block;
- background-color: var(--hotline-bg-color);
- margin: 0 10px 10px 10px;
- padding: 10px 5px;
- text-indent: 1em;
- }
- }
- }
- </style>
|