From e8e49938910bd0d627f1d8cf6dd0eaed01050871 Mon Sep 17 00:00:00 2001
From: zhouwx <1175765986@qq.com>
Date: Tue, 09 Jul 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