From e8e49938910bd0d627f1d8cf6dd0eaed01050871 Mon Sep 17 00:00:00 2001 From: zhouwx <1175765986@qq.com> Date: 星期二, 09 七月 2024 09:30:12 +0800 Subject: [PATCH] 题目题库 --- src/layout/components/Sidebar/menu.js | 25 + src/views/onlineEducation/questionBankManagement/components/questionBankDialog.vue | 241 +++++++++++++ src/views/onlineEducation/questionBankManagement/index.vue | 119 ++++++ src/api/onlineEducation/question.js | 43 ++ src/views/onlineEducation/courseManage/index.vue | 2 src/views/onlineEducation/questionBankManagement/questionManage/index.vue | 229 ++++++++++++ src/views/onlineEducation/questionBankManagement/questionManage/components/questionDialog.vue | 377 ++++++++++++++++++++ src/api/onlineEducation/questionBank.js | 42 ++ 8 files changed, 1,059 insertions(+), 19 deletions(-) diff --git a/src/api/onlineEducation/question.js b/src/api/onlineEducation/question.js new file mode 100644 index 0000000..1a6476a --- /dev/null +++ b/src/api/onlineEducation/question.js @@ -0,0 +1,43 @@ +import request from '@/utils/request' + +export function getQuestion(param) { + return request({ + url: '/question/list', + method: 'get', + params: param + }) +} + +export function addQuestion(data) { + return request({ + url: '/question', + method: 'post', + data: data + }) +} + +export function getQuestionById(params) { + return request({ + url: '/question/' +params , + method: 'get', + params: params + }) +} + + +export function editQuestion(params) { + return request({ + url: `/question`, + method: 'put', + data: params + }) +} + + +export function delQuestion(userId) { + return request({ + url: '/question/' + userId, + method: 'delete' + }) +} + diff --git a/src/api/onlineEducation/questionBank.js b/src/api/onlineEducation/questionBank.js new file mode 100644 index 0000000..4207c4f --- /dev/null +++ b/src/api/onlineEducation/questionBank.js @@ -0,0 +1,42 @@ +import request from '@/utils/request' + +export function getQuestionBank(param) { + return request({ + url: '/question-bank/list', + method: 'get', + params: param + }) +} + +export function addQuestionBank(data) { + return request({ + url: '/question-bank', + method: 'post', + data: data + }) +} + + +export function editQuestionBank(params) { + return request({ + url: `/question-bank`, + method: 'put', + data: params + }) +} + + +export function delQuestionBank(userId) { + return request({ + url: '/question-bank/' + userId, + method: 'delete' + }) +} + +export function checkQuestionBankName(data) { + return request({ + url: '/question-bank/checkNameUnique', + method: 'post', + data: data + }) +} diff --git a/src/layout/components/Sidebar/menu.js b/src/layout/components/Sidebar/menu.js index 9803057..d13d638 100644 --- a/src/layout/components/Sidebar/menu.js +++ b/src/layout/components/Sidebar/menu.js @@ -100,7 +100,7 @@ ], companyMenu: [ { - path: '/onlineEducation', + path: '/courseManage', redirect: '/onlineEducation/courseManage', meta: { title: '课程管理',icon: 'form'}, children: [ @@ -117,10 +117,27 @@ ] }, { - path: '/question', - name: 'Question', - meta: { title: '题库管理',icon: 'build',affix: true } + path: '/questionBankManagement', + redirect: '/onlineEducation/questionBankManagement', + meta: { title: '题目题库管理',icon: 'build'}, + children: [ + { + path: 'questionBank', + name: 'questionBank', + meta: { title: '题库列表',icon: 'list'} + } , + { + path: 'question', + name: 'question', + meta: { title: '题目列表',icon: 'education'} + } , + ] }, + // { + // path: '/question', + // name: 'Question', + // meta: { title: '题库管理',icon: 'build',affix: true } + // }, { path: '/class', name: 'Class', diff --git a/src/views/onlineEducation/courseManage/index.vue b/src/views/onlineEducation/courseManage/index.vue index 08dc044..b87d702 100644 --- a/src/views/onlineEducation/courseManage/index.vue +++ b/src/views/onlineEducation/courseManage/index.vue @@ -66,7 +66,7 @@ <el-button link type="primary" @click="toChapters(scope.row)">章节</el-button> <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button> </div> - <div v-else>--</div> + <div v-else><el-button link type="primary" @click="toChapters(scope.row)">章节</el-button></div> </div> <div v-else-if="scope.row.state == 1" > <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button> diff --git a/src/views/onlineEducation/questionBankManagement/components/questionBankDialog.vue b/src/views/onlineEducation/questionBankManagement/components/questionBankDialog.vue new file mode 100644 index 0000000..2144454 --- /dev/null +++ b/src/views/onlineEducation/questionBankManagement/components/questionBankDialog.vue @@ -0,0 +1,241 @@ +<template> + <div class="notice"> + <el-dialog + v-model="dialogVisible" + :title="title" + width="500px" + :before-close="handleClose" + > + <el-form :model="state.form" size="default" ref="busRef" :rules="state.formRules" label-width="150px" > + <el-form-item label="所属公司:" prop="companyName" v-if="!state.isAdmin"> + <el-input v-model.trim="state.form.companyName" disabled></el-input> + </el-form-item> + <el-form-item label="题库名称:" prop="name"> + <el-input v-model.trim="state.form.name" placeholder="请输入题库名称"></el-input> + </el-form-item> + <el-form-item label="课程分类:" prop="categoryId" > + <el-cascader + style="width: 100%" + ref="classifyRef" + v-model="state.form.categoryId" + :options="state.classifyList" + :props="state.props" + clearable + :show-all-levels="false" + @change="handleChange" + /> + </el-form-item> + </el-form> + <template #footer> + <span class="dialog-footer"> + <el-button @click="handleClose" size="default">取 消</el-button> + <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> + </span> + </template> + </el-dialog> + </div> +</template> +<script setup> +import {reactive, ref, toRefs} from 'vue' +import {ElMessage} from "element-plus"; + +import { + getClassification +} from "@/api/onlineEducation/courseClass"; +import {addCourse, checkCourseName, editCourse, getCourseById} from "@/api/onlineEducation/courseManage"; +import {getToken} from "@/utils/auth"; +import {delPic, getBannerById} from "@/api/onlineEducation/banner"; +import Cookies from "js-cookie"; +import {addQuestionBank, checkQuestionBankName, editQuestionBank} from "@/api/onlineEducation/questionBank"; + +const dialogVisible = ref(false); +const title = ref(""); +const busRef = ref(); +const length = ref() +const emit = defineEmits(["getList"]); +const startUsername = ref(''); +const classifyRef = ref(null) + +const validateName = (rule, value, callback)=>{ + if(value === ''){ + callback(new Error('请输入题库名称')) + }else if(title.value === '编辑' && value === startUsername.value){ + callback() + }else{ + let param = {} + if(title.value === '新增') { + param = { + name:value + } + }else if(title.value === '编辑'){ + param = { + name:value, + id: state.form.id + } + } + checkQuestionBankName(param).then((res)=>{ + if(res.data == false){ + callback(new Error('题库名称已被占用,请更换其他名称')) + }else{ + callback() + } + }) + } +} +const state = reactive({ + form: { + id: '', + name: '', + categoryId: null, + companyName: '', + companyId: null + }, + formRules: { + name: [{required: true, trigger: "blur", validator: validateName}], + categoryId: [{required: true, message: '请选择课程分类', trigger: 'blur'}], + }, + classifyList: [], + isAdmin: false, + props: { + checkStrictly: true, + } +}) + +const openDialog = async (type, value) => { + await getClassifyList(); + const userInfo = JSON.parse(Cookies.get('userInfo')) + console.log("userInfo",userInfo) + if(userInfo.userType === 0){ + state.isAdmin = true; + state.form.companyName = '' + state.form.companyId = null + }else { + state.isAdmin = false; + state.form.companyName = userInfo.companyName + state.form.companyId = userInfo.companyId + } + title.value = type === 'addFirst' || type === 'add' ? '新增' : type ==='edit' ? '编辑' : '' ; + if(type === 'edit') { + state.form.id = value.id + state.form.name = value.name + state.form.categoryId = value.categoryId + startUsername.value = value.name; + }else if(type === 'add' && value ){ + state.form.parentId = value.id + } + dialogVisible.value = true; +} +const getClassifyList = async () => { + const res = await getClassification(); + if(res.code === 200){ + state.classifyList = recursion(res.data) + }else{ + ElMessage.warning(res.message) + } +} +const recursion = (data) => { + let tmp = [] + for (let i = 0; i < data.length; i++) { + let item = data[i] + // children为空 + if (item.children&& item.children.length==0) { + tmp.push({ + value: item.id, + label: item.name + }) + // 有children + } else { + tmp.push({ + value: item.id, + label: item.name, + children:recursion(item.children) + }) + } + } + return tmp; +} + +const handleChange = ()=> { + console.log("label====",classifyRef.value.getCheckedNodes()[0].value) + state.form.categoryId = classifyRef.value.getCheckedNodes()[0].value + // 我这里只是打印了一下label的值哦,需要赋值的话自己去赋值哦 +} + +const onSubmit = async () => { + if(state.isAdmin){ + ElMessage({ + type: 'warning', + message: '管理员暂无权限' + }); + return; + } + const valid = await busRef.value.validate(); + if(valid){ + if(title.value === '新增'){ + const {id, ...data} = JSON.parse(JSON.stringify(state.form)) + const res = await addQuestionBank(data) + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '新增成功' + }); + }else{ + ElMessage.warning(res.message) + } + emit("getList") + busRef.value.clearValidate(); + reset(); + dialogVisible.value = false; + }else if(title.value === '编辑'){ + const {...data} = JSON.parse(JSON.stringify(state.form)) + const res = await editQuestionBank(data) + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '编辑成功' + }); + }else{ + ElMessage.warning(res.message) + } + emit("getList") + busRef.value.clearValidate(); + reset(); + dialogVisible.value = false; + } + } +} + +const handleClose = () => { + busRef.value.clearValidate(); + reset(); + dialogVisible.value = false; + emit("getList") + +} +const reset = () => { + state.form = { + id: '', + name: '', + categoryId: null, + companyName: '', + companyId: null + } +} +defineExpose({ + openDialog +}); + +</script> + +<style scoped lang="scss"> +.notice{ + :deep(.el-form .el-form-item__label) { + font-size: 15px; + } + .file { + display: flex; + flex-direction: column; + align-items: flex-start; + } +} +</style> diff --git a/src/views/onlineEducation/questionBankManagement/index.vue b/src/views/onlineEducation/questionBankManagement/index.vue index 0ca17bc..27ede7f 100644 --- a/src/views/onlineEducation/questionBankManagement/index.vue +++ b/src/views/onlineEducation/questionBankManagement/index.vue @@ -1,12 +1,117 @@ <template> -<div>题库管理</div> + <div class="app-container"> + <div style="margin-bottom: 10px"> + <el-button + type="primary" + plain + icon="Plus" + @click="openDialog('add',{})" + >新增</el-button> + </div> + <!-- 表格数据 --> + <el-table v-loading="loading" :data="dataList" :border="true"> + <el-table-column label="序号" type="index" align="center" width="80" /> + <el-table-column label="题库名称" prop="name" align="center" /> + <el-table-column label="分类名称" prop="categoryName" align="center" /> + <el-table-column label="单选题数量" prop="singleCount" align="center" /> + <el-table-column label="多选题数量" prop="multiCount" align="center" /> + <el-table-column label="判断题数量" prop="judgeCount" align="center" /> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180"> + <template #default="scope"> + <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button> + <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button> + </template> + </el-table-column> + </el-table> + + <pagination + v-show="total > 0" + :total="total" + v-model:page="queryParams.pageNum" + v-model:limit="queryParams.pageSize" + @pagination="getList" + /> + + <question-bank-dialog ref="dialogRef" @getList=getList></question-bank-dialog> + </div> </template> + <script setup> +import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue"; +import {ElMessage, ElMessageBox} from "element-plus"; +import questionBankDialog from './components/questionBankDialog.vue' +import Cookies from "js-cookie"; +import {delQuestionBank, getQuestionBank} from "@/api/onlineEducation/questionBank"; + + +const { proxy } = getCurrentInstance(); +const loading = ref(false); +const dialogRef = ref(); +const data = reactive({ + queryParams: { + pageNum: 1, + pageSize: 10, + }, + total: 0, + dataList: [], + isAdmin: false + +}); + +const { queryParams, total, dataList } = toRefs(data); + +onMounted(async ()=>{ + const userInfo = JSON.parse(Cookies.get('userInfo')) + console.log("userInfo",userInfo) + if(userInfo.userType === 0){ + data.isAdmin = true; + }else { + data.isAdmin = false; + } + await getList() +}) +onUnmounted(()=>{ + +}) + +const getList = async () => { + loading.value = true + const res = await getQuestionBank(data.queryParams) + if(res.code == 200){ + data.dataList = res.data.list + data.total = res.data.total + }else{ + ElMessage.warning(res.message) + } + loading.value = false +} + +const openDialog = (type, value) => { + dialogRef.value.openDialog(type, value); +} + +/** 重置新增的表单以及其他数据 */ +function reset() { + proxy.resetForm("roleRef"); +} +const handleDelete = (val) => { + ElMessageBox.confirm( + '确定删除此条数据?', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }) + .then( async() => { + const res = await delQuestionBank(val.id) + if(res.code == 200){ + ElMessage.success('数据删除成功') + await getList() + }else{ + ElMessage.warning(res.message) + } + }) +} </script> - - - -<style scoped lang="scss"> - -</style> diff --git a/src/views/onlineEducation/questionBankManagement/questionManage/components/questionDialog.vue b/src/views/onlineEducation/questionBankManagement/questionManage/components/questionDialog.vue new file mode 100644 index 0000000..c24f4c6 --- /dev/null +++ b/src/views/onlineEducation/questionBankManagement/questionManage/components/questionDialog.vue @@ -0,0 +1,377 @@ +<template> + <div class="notice"> + <el-dialog + v-model="dialogVisible" + :title="title" + width="50%" + :before-close="handleClose" + > + <el-form :model="state.form" size="default" ref="busRef" :rules="state.formRules" label-width="150px" > + <el-form-item label="题目类型:" prop="questionType"> + <el-select v-model="state.form.questionType" placeholder="请选择题型" style="width: 100%"> + <el-option + v-for="item in state.questionTypeList" + :key="item.id" + :label="item.name" + style="width: 100%" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item label="归属题库:" prop="bankName"> + <el-select + v-model="state.form.bankName" + style="width: 100%" + v-loadMoreNew:[reselect]="handleScroll" + :popper-class="reselect.name" + @change="selectValue" + class="item-width" + placeholder="请选择题库" + > + <el-option + v-for="item in state.bankList" + :key="item.id" + :label="item.name" + :value="item.name" + /> + </el-select> + </el-form-item> + <el-form-item label="题目内容:" prop="title"> + <el-input v-model.trim="state.form.title" type="textarea" placeholder="请输入题目内容"></el-input> + </el-form-item> + <el-form-item label="选项:" prop="content"> + <div v-if="state.form.questionType === 1" style="width: 100%"> + <div v-for="(item,index) in 4" :key="index" > + <div style="display: flex;"> + <span>{{item ===1 ? 'A':item ===2 ? 'B' : item ===3 ? 'C' : 'D'}}</span> + <el-input type="textarea" v-model="state.singleQuestion.items[index].content" placeholder="请输入选项内容" style="width: 100%;margin-left: 20px;margin-bottom: 10px"></el-input> + </div> + </div> + <div style="display: flex"> + <span style="width: 50px">解析:</span> + <el-input type="textarea" v-model="state.singleQuestion.analyze" placeholder="请输入题目解析" style="width: 100%;margin-bottom: 10px"></el-input> + </div> + </div> + <div v-else-if="state.form.questionType === 2" style="width: 100%"> + <div v-for="(item,index) in 4" :key="index" > + <div style="display: flex;"> + <span>{{item ===1 ? 'A':item ===2 ? 'B' : item ===3 ? 'C' : 'D'}}</span> + <el-input type="textarea" v-model="state.multiQuestion.items[index].content" placeholder="请输入选项内容" style="width: 100%;margin-left: 20px;margin-bottom: 10px"></el-input> + </div> + </div> + <div style="display: flex"> + <span style="width: 50px">解析:</span> + <el-input type="textarea" v-model="state.multiQuestion.analyze" placeholder="请输入题目解析" style="width: 100%;margin-bottom: 10px"></el-input> + </div> + </div> + <div v-else style="width: 100%"> + <div v-for="(item,index) in 2" :key="index" > + <div style="display: flex;"> + <span>{{item ===1 ? 'A': 'B'}}</span> + <el-input v-model="state.judgeQuestion.items[index].content" style="width: 100%;margin-left: 20px;margin-bottom: 10px" disabled></el-input> + </div> + </div> + <div style="display: flex"> + <span style="width: 50px">解析:</span> + <el-input type="textarea" v-model="state.judgeQuestion.analyze" placeholder="请输入题目解析" style="width: 100%;margin-bottom: 10px"></el-input> + </div> + </div> + </el-form-item> + <el-form-item label="正确答案:" prop="answer"> + <el-radio-group v-model="state.form.answer" v-if="state.form.questionType === 1"> + <el-radio :label="'A'">A</el-radio> + <el-radio :label="'B'">B</el-radio> + <el-radio :label="'C'">C</el-radio> + <el-radio :label="'D'">D</el-radio> + </el-radio-group> + <el-checkbox-group v-model="state.checkList" v-if="state.form.questionType === 2" @change="changeCheckBox"> + <el-checkbox label="A"></el-checkbox> + <el-checkbox label="B"></el-checkbox> + <el-checkbox label="C"></el-checkbox> + <el-checkbox label="D"></el-checkbox> + </el-checkbox-group> + <el-radio-group v-model="state.form.answer" v-if="state.form.questionType === 3"> + <el-radio :label="'A'">A</el-radio> + <el-radio :label="'B'">B</el-radio> + </el-radio-group> + </el-form-item> + </el-form> + <template #footer> + <span class="dialog-footer"> + <el-button @click="handleClose" size="default">取 消</el-button> + <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> + </span> + </template> + </el-dialog> + </div> +</template> +<script setup> +import {reactive, ref, toRefs} from 'vue' +import {ElMessage} from "element-plus"; + +import { + getClassification +} from "@/api/onlineEducation/courseClass"; +import {addCourse, checkCourseName, editCourse, getCourseById} from "@/api/onlineEducation/courseManage"; +import {getToken} from "@/utils/auth"; +import {delPic, getBannerById} from "@/api/onlineEducation/banner"; +import Cookies from "js-cookie"; +import { + addQuestionBank, + checkQuestionBankName, + editQuestionBank, + getQuestionBank +} from "@/api/onlineEducation/questionBank"; +import {addQuestion, editQuestion, getQuestionById} from "@/api/onlineEducation/question"; + +const dialogVisible = ref(false); +const title = ref(""); +const busRef = ref(); +const length = ref() +const emit = defineEmits(["getList"]); +const startUsername = ref(''); +const classifyRef = ref(null) +const state = reactive({ + form: { + id: '', + title: '', + questionType: 1, + bankName: '', + bankId: null, + answer: '' + }, + formRules: { + + questionType: [{required: true, trigger: "blur", message: '请选择题目类型'}], + bankName: [{required: true, trigger: "blur", message: '请选择归属题库'}], + title: [{required: true, trigger: "blur", message: '请输入题目内容'}], + // answer: [{required: true, trigger: "blur", message: '请选择正确答案'}], + }, + classifyList: [], + isAdmin: false, + props: { + checkStrictly: true, + }, + questionTypeList: [ + { + id: 1, + name: '单选题' + }, + { + id: 2, + name: '多选题' + }, + { + id: 3, + name: '判断题' + } + ], + singleQuestion: { + analyze: '', + items: [ + { + prefix:"A", + content: '' + }, + { + prefix:"B", + content: '' + }, + { + prefix:"C", + content: '' + }, + { + prefix:"D", + content: '' + }, + ] + }, + judgeQuestion: { + analyze: '', + items: [ + { + prefix:"A", + content: '是' + }, + { + prefix:"B", + content: '否' + }, + ] + }, + multiQuestion: { + analyze: '', + items: [ + { + prefix:"A", + content: '' + }, + { + prefix:"B", + content: '' + }, + { + prefix:"C", + content: '' + }, + { + prefix:"D", + content: '' + }, + ] + }, + checkList: [], + bankList: [], + bankPageNum: 1, // 当前页码 + bankPageSize: 10, // 每页显示的数量 + hasMoreItems: null, // 是否还有更多选项 + +}) +const reselect = reactive({ + name: 'bank1' +}) +const selectValue = (val) => { + state.bankList.forEach(item => { + if(item.name === val){ + state.form.bankId = item.id + } + }) +} + +const openDialog = async (type, value) => { + await loadMoreBankData(); + const userInfo = JSON.parse(Cookies.get('userInfo')) + console.log("userInfo",userInfo) + if(userInfo.userType === 0){ + state.isAdmin = true; + state.form.companyName = '' + state.form.companyId = null + }else { + state.isAdmin = false; + state.form.companyName = userInfo.companyName + state.form.companyId = userInfo.companyId + } + title.value = type === 'addFirst' || type === 'add' ? '新增' : type ==='edit' ? '编辑' : '' ; + if(type === 'edit') { + const res = await getQuestionById(value.id) + if(res.code === 200){ + state.form = res.data + if(res.data.questionType === 1){ + state.singleQuestion = JSON.parse(res.data.content) + }else if(res.data.questionType === 3) { + state.judgeQuestion = JSON.parse(res.data.content) + }else { + state.multiQuestion = JSON.parse(res.data.content) + state.checkList = res.data.answer.split(',') + } + }else{ + ElMessage.warning(res.message) + } + } + dialogVisible.value = true; +} + +const handleScroll = () => { + if(state.bankPageNum >= state.hasMoreItems) return + state.bankPageNum++; + loadMoreBankData() + +} +const loadMoreBankData = async () => { + const queryParams = { + pageNum: state.bankPageNum, + pageSize: state.bankPageSize, + } + const res = await getQuestionBank(queryParams) + if (res.code == 200) { + state.hasMoreItems = res.data.totalPage + const data = res.data + state.bankList = state.bankList.concat(data.list) + }else{ + ElMessage.warning(res.message) + } +} + + +const onSubmit = async () => { + const valid = await busRef.value.validate(); + if(valid){ + if(title.value === '新增'){ + const {id,bankName, ...data} = JSON.parse(JSON.stringify(state.form)) + data.answer = data.questionType === 1 || data.questionType === 3 ? data.answer : state.checkList.join(',') + data.content = data.questionType === 1 ? JSON.stringify(state.singleQuestion) : data.questionType === 2 ? JSON.stringify(state.multiQuestion) : JSON.stringify(state.judgeQuestion) + console.log('state.form',data) + const res = await addQuestion(data) + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '新增成功' + }); + }else{ + ElMessage.warning(res.message) + } + emit("getList") + busRef.value.clearValidate(); + reset(); + dialogVisible.value = false; + }else if(title.value === '编辑'){ + const {bankName,...data} = JSON.parse(JSON.stringify(state.form)) + data.answer = data.questionType === 1 || data.questionType === 3 ? data.answer : state.checkList.join(',') + data.content = data.questionType === 1 ? JSON.stringify(state.singleQuestion) : data.questionType === 2 ? JSON.stringify(state.multiQuestion) : JSON.stringify(state.judgeQuestion) + const res = await editQuestion(data) + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '编辑成功' + }); + }else{ + ElMessage.warning(res.message) + } + emit("getList") + busRef.value.clearValidate(); + reset(); + dialogVisible.value = false; + } + } +} + +const handleClose = () => { + busRef.value.clearValidate(); + reset(); + dialogVisible.value = false; + emit("getList") + +} +const reset = () => { + state.form = { + id: '', + title: '', + questionType: 1, + bankName: '', + bankId: null, + answer: '' + } + state.bankPageNum = 1; + state.bankPageSize = 10; + state.bankList = [] + state.checkList = [] +} +defineExpose({ + openDialog +}); + +</script> + +<style scoped lang="scss"> +.notice{ + :deep(.el-form .el-form-item__label) { + font-size: 15px; + } + .file { + display: flex; + flex-direction: column; + align-items: flex-start; + } +} +</style> diff --git a/src/views/onlineEducation/questionBankManagement/questionManage/index.vue b/src/views/onlineEducation/questionBankManagement/questionManage/index.vue index d1aebdf..ab257c2 100644 --- a/src/views/onlineEducation/questionBankManagement/questionManage/index.vue +++ b/src/views/onlineEducation/questionBankManagement/questionManage/index.vue @@ -1,12 +1,227 @@ <template> - <div>题目管理</div> + <div class="app-container"> + <div style="margin-bottom: 10px"> + <el-form :model="data.queryParams" ref="queryRef" :inline="true" > + <el-form-item label="题型:"> + <el-select v-model="data.queryParams.questionType" placeholder="请选择题型" clearable> + <el-option + v-for="item in data.questionTypeList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item label="题目内容:" > + <el-input + + v-model="data.queryParams.title" + placeholder="请输入题目内容" + clearable + style="width: 200px" + /> + </el-form-item> + <el-form-item label="题库:" > + <el-select + clearable + v-model="data.queryParams.bankId" + style="width: 200px" + v-loadMoreNew:[reselect]="handleScroll" + :popper-class="reselect.name" + class="item-width" + placeholder="请选择题库" + > + <el-option + v-for="item in data.bankList" + :key="item.id" + :label="item.name" + :value="item.id" + /> + </el-select> + </el-form-item> + <el-form-item> + <el-button type="primary" @click="handleQuery">查询</el-button> + <el-button @click="resetQuery">重置</el-button> + </el-form-item> + </el-form> + <el-button + type="primary" + plain + icon="Plus" + @click="openDialog('add',{})" + >新增</el-button> + </div> + <!-- 表格数据 --> + <el-table v-loading="loading" :data="data.dataList" :border="true"> + <el-table-column label="序号" type="index" align="center" width="80" /> + <el-table-column label="所属题库" prop="bankName" align="center" /> + <el-table-column label="题目类型" prop="questionType" align="center" > + <template #default="scope"> + <span>{{scope.row.questionType === 1 ? '单选题' : scope.row.questionType === 2 ? '多选题' : '判断题'}}</span> + </template> + </el-table-column> + <el-table-column label="题目内容" prop="title" align="center" /> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180"> + <template #default="scope"> + <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button> + <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button> + </template> + </el-table-column> + </el-table> + + <pagination + v-show="data.total > 0" + :total="data.total" + v-model:page="data.queryParams.pageNum" + v-model:limit="data.queryParams.pageSize" + @pagination="getList" + /> + + <question-dialog ref="dialogRef" @getList=getList></question-dialog> + </div> </template> + <script setup> +import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue"; +import {ElMessage, ElMessageBox} from "element-plus"; +import questionDialog from './components/questionDialog.vue' +import Cookies from "js-cookie"; +import {delQuestion, getQuestion} from "@/api/onlineEducation/question"; +import {getQuestionBank} from "@/api/onlineEducation/questionBank"; + + +const { proxy } = getCurrentInstance(); +const loading = ref(false); +const dialogRef = ref(); +const data = reactive({ + queryParams: { + pageNum: 1, + pageSize: 10, + questionType: null, + title: '', + bankId: null + }, + total: 0, + dataList: [], + isAdmin: false, + questionTypeList: [ + { + id: 1, + name: '单选题' + }, + { + id: 2, + name: '多选题' + }, + { + id: 3, + name: '判断题' + } + ], + bankList: [], + bankPageNum: 1, // 当前页码 + bankPageSize: 10, // 每页显示的数量 + hasMoreItems: null, // 是否还有更多选项 + + +}) +const reselect = reactive({ + name: 'bank' +}) + +onMounted(async ()=>{ + const userInfo = JSON.parse(Cookies.get('userInfo')) + console.log("userInfo",userInfo) + if(userInfo.userType === 0){ + data.isAdmin = true; + }else { + data.isAdmin = false; + } + await getList() + await loadMoreBankData() +}) + +onUnmounted(()=>{ + +}) + +const getList = async () => { + console.log(' list'); + loading.value = true + const res = await getQuestion(data.queryParams) + if(res.code == 200){ + data.dataList = res.data.list + data.total = res.data.total + }else{ + ElMessage.warning(res.message) + } + loading.value = false +} + +const handleScroll = () => { + + if(data.bankPageNum >= data.hasMoreItems) return + data.bankPageNum++; + loadMoreBankData() + +} +const loadMoreBankData = async () => { + console.log(' Bank'); + const queryParams = { + pageNum: data.bankPageNum, + pageSize: data.bankPageSize, + } + const res = await getQuestionBank(queryParams) + if (res.code == 200) { + data.hasMoreItems = res.data.totalPage + const state = res.data + data.bankList = data.bankList.concat(state.list) + }else{ + ElMessage.warning(res.message) + } +} + +const handleQuery = () => { + data.queryParams.pageNum = 1; + getList(); +} +const resetQuery = () => { + data.queryParams = { + pageNum: 1, + pageSize: 10, + questionType: null, + title: '', + bankId: null + } + getList(); +} + +const openDialog = (type, value) => { + dialogRef.value.openDialog(type, value); +} + +/** 重置新增的表单以及其他数据 */ +function reset() { + proxy.resetForm("roleRef"); +} +const handleDelete = (val) => { + ElMessageBox.confirm( + '确定删除此条数据?', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }) + .then( async() => { + const res = await delQuestion(val.id) + if(res.code == 200){ + ElMessage.success('数据删除成功') + await getList() + }else{ + ElMessage.warning(res.message) + } + }) +} </script> - - - -<style scoped lang="scss"> - -</style> -- Gitblit v1.9.2