|
|
|
@ -1,7 +1,11 @@
|
|
|
|
|
<template>
|
|
|
|
|
<!-- 使用Ant Design的a-card组件作为外层容器,设置无边框 -->
|
|
|
|
|
<a-card :bordered="false">
|
|
|
|
|
<!-- 定义操作按钮的工具栏区域 -->
|
|
|
|
|
<div id="toolbar">
|
|
|
|
|
<!-- 新建按钮,类型为主要按钮(primary),带有加号图标,点击时调用$refs.createQuestionModal.create()方法来触发新建操作 -->
|
|
|
|
|
<a-button type="primary" icon="plus" @click="$refs.createQuestionModal.create()">新建</a-button>
|
|
|
|
|
<!-- 全量刷新按钮,类型为主要按钮(primary),带有刷新图标,点击时调用loadAll()方法来重新加载所有题目数据 -->
|
|
|
|
|
<a-button type="primary" icon="reload" @click="loadAll()">全量刷新</a-button>
|
|
|
|
|
</div>
|
|
|
|
|
<BootstrapTable
|
|
|
|
@ -12,8 +16,11 @@
|
|
|
|
|
/>
|
|
|
|
|
<!-- ref是为了方便用this.$refs.modal直接引用,下同 -->
|
|
|
|
|
<step-by-step-question-modal ref="createQuestionModal" @ok="handleOk" />
|
|
|
|
|
<!-- 更新题目模态框 -->
|
|
|
|
|
<summernote-update-modal ref="questionUpdateModal" @ok="handleOk" />
|
|
|
|
|
<!-- 查看题目模态框 -->
|
|
|
|
|
<question-view-modal ref="modalView" @ok="handleOk" />
|
|
|
|
|
<!-- 编辑题目模态框 -->
|
|
|
|
|
<question-edit-modal ref="modalEdit" @ok="handleOk" />
|
|
|
|
|
</a-card>
|
|
|
|
|
</template>
|
|
|
|
@ -28,6 +35,15 @@ import SummernoteUpdateModal from '@views/list/modules/SummernoteUpdateModal'
|
|
|
|
|
import $ from 'jquery'
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
/**
|
|
|
|
|
* 名称:QuestionTableList 组件
|
|
|
|
|
* 描述:此组件用于显示问题表格列表,并提供对问题进行详细操作的功能
|
|
|
|
|
* 组件包含:
|
|
|
|
|
* - SummernoteUpdateModal: 用于更新问题描述的模态框
|
|
|
|
|
* - StepByStepQuestionModal: 用于逐步解答问题的模态框
|
|
|
|
|
* - QuestionViewModal: 用于查看问题详情的模态框
|
|
|
|
|
* - QuestionEditModal: 用于编辑问题的模态框
|
|
|
|
|
*/
|
|
|
|
|
name: 'QuestionTableList',
|
|
|
|
|
components: {
|
|
|
|
|
SummernoteUpdateModal,
|
|
|
|
@ -44,69 +60,113 @@ export default {
|
|
|
|
|
title: '序号',
|
|
|
|
|
field: 'serial',
|
|
|
|
|
formatter: function (value, row, index) {
|
|
|
|
|
// 格式化函数,用于生成序号
|
|
|
|
|
// 参数:
|
|
|
|
|
// value: 当前单元格的值
|
|
|
|
|
// row: 当前行的数据
|
|
|
|
|
// index: 当前行的索引
|
|
|
|
|
return index + 1 // 这样的话每翻一页都会重新从1开始,
|
|
|
|
|
// 注释解释了代码的功能和潜在的行为特点
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
// 定义表格列的配置对象
|
|
|
|
|
{
|
|
|
|
|
// 列标题
|
|
|
|
|
title: '题干',
|
|
|
|
|
// 对应的数据字段
|
|
|
|
|
field: 'name',
|
|
|
|
|
// 列宽度
|
|
|
|
|
width: 200,
|
|
|
|
|
formatter: (value, row) => {
|
|
|
|
|
// 返回格式化后的HTML,包装题干文本到一个div中
|
|
|
|
|
return '<div class="question-name" style="height: 100%;width: 100%">' + value + '</div>'
|
|
|
|
|
},
|
|
|
|
|
// 定义列相关的事件处理函数
|
|
|
|
|
events: {
|
|
|
|
|
'click .question-name': function (e, value, row, index) {
|
|
|
|
|
// 调用编辑题干的模态框组件,传递所需参数和回调函数
|
|
|
|
|
that.$refs.questionUpdateModal.edit('summernote-question-name-update', row, 'name', '更新题干', questionUpdate)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
// 定义表格列的标题
|
|
|
|
|
title: '解析',
|
|
|
|
|
// 定义表格列对应的数据字段
|
|
|
|
|
field: 'description',
|
|
|
|
|
// 设置列的宽度
|
|
|
|
|
width: 200,
|
|
|
|
|
formatter: (value, row) => {
|
|
|
|
|
// 将当前行的描述值包装在名为question-desc的div中
|
|
|
|
|
return '<div class="question-desc">' + value + '</div>'
|
|
|
|
|
},
|
|
|
|
|
// 定义列相关事件的处理函数
|
|
|
|
|
events: {
|
|
|
|
|
// 定义点击question-desc类元素的事件处理函数
|
|
|
|
|
'click .question-desc': function (e, value, row, index) {
|
|
|
|
|
that.$refs.questionUpdateModal.edit('summernote-question-desc-update', row, 'description', '更新题目解析', questionUpdate)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
// 定义表格列的标题
|
|
|
|
|
title: '分数',
|
|
|
|
|
// 定义表格列的数据字段
|
|
|
|
|
field: 'score',
|
|
|
|
|
// 定义单元格内容的格式化函数
|
|
|
|
|
formatter: (value, row) => {
|
|
|
|
|
// 将分数值包裹在div中,以便于后续的事件处理
|
|
|
|
|
return '<div class="question-score">' + value + '</div>'
|
|
|
|
|
},
|
|
|
|
|
// 定义与列相关的事件处理函数
|
|
|
|
|
events: {
|
|
|
|
|
// 当点击分数所在的单元格时触发的事件
|
|
|
|
|
'click .question-score': function (e, value, row, index) {
|
|
|
|
|
// 将事件目标元素转换为jQuery对象,以便使用jQuery方法
|
|
|
|
|
const $element = $(e.target) // 把元素转换成html对象
|
|
|
|
|
$element.html('<input type="text" value="' + value + '">')
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* 配置表格列标题和数据字段
|
|
|
|
|
*
|
|
|
|
|
* @param {String} title - 表格列的标题,用于显示在表头
|
|
|
|
|
* @param {String} field - 表格列的数据字段,用于绑定数据源中的属性
|
|
|
|
|
*/
|
|
|
|
|
title: '创建人',
|
|
|
|
|
field: 'creator'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
// 列的标题
|
|
|
|
|
title: '难度',
|
|
|
|
|
// 列的数据字段
|
|
|
|
|
field: 'level',
|
|
|
|
|
formatter: (value, row) => {
|
|
|
|
|
// 格式化列的显示内容
|
|
|
|
|
// 参数 value: 当前单元格的值
|
|
|
|
|
// 参数 row: 当前行的数据
|
|
|
|
|
return '<div class="question-level">' + value + '</div>'
|
|
|
|
|
},
|
|
|
|
|
events: {
|
|
|
|
|
'click .question-level': function (e, value, row, index) {
|
|
|
|
|
// 点击难度列的事件处理函数
|
|
|
|
|
// 参数 e: 事件对象
|
|
|
|
|
// 参数 value: 当前单元格的值
|
|
|
|
|
// 参数 row: 当前行的数据
|
|
|
|
|
// 参数 index: 当前行的索引
|
|
|
|
|
const $element = $(e.target) // 把元素转换成html对象
|
|
|
|
|
if ($element.children().length > 0) return // 防止重复渲染
|
|
|
|
|
getQuestionSelection().then(res => {
|
|
|
|
|
// 获取问题下拉选项的异步处理函数
|
|
|
|
|
console.log(res)
|
|
|
|
|
if (res.code === 0) {
|
|
|
|
|
console.log(res.data)
|
|
|
|
|
const levels = res.data.levels
|
|
|
|
|
let inner = '<select>'
|
|
|
|
|
for (let i = 0; i < levels.length; i++) {
|
|
|
|
|
// 生成下拉选项
|
|
|
|
|
if (levels[i].description === value) {
|
|
|
|
|
// 设置默认的选中值为当前的值
|
|
|
|
|
inner += '<option value ="' + levels[i].id + '" name="' + levels[i].name + '" selected="selected">' + levels[i].description + '</option>'
|
|
|
|
@ -117,6 +177,7 @@ export default {
|
|
|
|
|
inner += '</select>'
|
|
|
|
|
$element.html(inner)
|
|
|
|
|
} else {
|
|
|
|
|
// 显示错误通知
|
|
|
|
|
that.$notification.error({
|
|
|
|
|
message: '获取问题下拉选项失败',
|
|
|
|
|
description: res.msg
|
|
|
|
@ -127,16 +188,27 @@ export default {
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
// 列的标题
|
|
|
|
|
title: '题型',
|
|
|
|
|
// 对应的数据字段
|
|
|
|
|
field: 'type',
|
|
|
|
|
formatter: (value, row) => {
|
|
|
|
|
// 格式化函数,用于渲染单元格内容
|
|
|
|
|
// value: 当前单元格的值
|
|
|
|
|
// row: 当前行的数据
|
|
|
|
|
return '<div class="question-type">' + value + '</div>'
|
|
|
|
|
},
|
|
|
|
|
events: {
|
|
|
|
|
'click .question-type': function (e, value, row, index) {
|
|
|
|
|
// 点击事件处理函数
|
|
|
|
|
// e: 事件对象
|
|
|
|
|
// value: 当前单元格的值
|
|
|
|
|
// row: 当前行的数据
|
|
|
|
|
// index: 当前行的索引
|
|
|
|
|
const $element = $(e.target) // 把元素转换成html对象
|
|
|
|
|
if ($element.children().length > 0) return // 防止重复渲染
|
|
|
|
|
getQuestionSelection().then(res => {
|
|
|
|
|
// 获取问题下拉选项
|
|
|
|
|
console.log(res)
|
|
|
|
|
if (res.code === 0) {
|
|
|
|
|
console.log(res.data)
|
|
|
|
@ -163,21 +235,27 @@ export default {
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
// 列的标题
|
|
|
|
|
title: '学科',
|
|
|
|
|
// 对应的数据字段
|
|
|
|
|
field: 'category',
|
|
|
|
|
formatter: (value, row) => {
|
|
|
|
|
// 数据格式化函数
|
|
|
|
|
// 返回学科列的HTML,用于在界面上显示
|
|
|
|
|
return '<div class="question-category">' + value + '</div>'
|
|
|
|
|
},
|
|
|
|
|
events: {
|
|
|
|
|
'click .question-category': function (e, value, row, index) {
|
|
|
|
|
const $element = $(e.target) // 把元素转换成html对象
|
|
|
|
|
if ($element.children().length > 0) return // 防止重复渲染
|
|
|
|
|
// 异步获取问题选择数据
|
|
|
|
|
getQuestionSelection().then(res => {
|
|
|
|
|
console.log(res)
|
|
|
|
|
if (res.code === 0) {
|
|
|
|
|
console.log(res.data)
|
|
|
|
|
const categories = res.data.categories
|
|
|
|
|
let inner = '<select>'
|
|
|
|
|
// 遍历学科类别数组,生成<option>元素
|
|
|
|
|
for (let i = 0; i < categories.length; i++) {
|
|
|
|
|
if (categories[i].name === value) { // 学科还是用名字吧
|
|
|
|
|
// 设置默认的选中值为当前的值
|
|
|
|
@ -189,6 +267,7 @@ export default {
|
|
|
|
|
inner += '</select>'
|
|
|
|
|
$element.html(inner)
|
|
|
|
|
} else {
|
|
|
|
|
// 如果获取数据失败,显示错误通知
|
|
|
|
|
that.$notification.error({
|
|
|
|
|
message: '获取问题下拉选项失败',
|
|
|
|
|
description: res.msg
|
|
|
|
@ -199,22 +278,32 @@ export default {
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
// 列标题
|
|
|
|
|
title: '更新时间',
|
|
|
|
|
// 列数据字段
|
|
|
|
|
field: 'updateTime'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
// 列标题
|
|
|
|
|
title: '操作',
|
|
|
|
|
// 列数据字段
|
|
|
|
|
field: 'action',
|
|
|
|
|
// 列对齐方式
|
|
|
|
|
align: 'center',
|
|
|
|
|
// 自定义列内容格式化函数
|
|
|
|
|
formatter: (value, row) => {
|
|
|
|
|
// 返回操作按钮组的HTML字符串
|
|
|
|
|
return '<button type="button" class="btn btn-success view-question">详情</button>' +
|
|
|
|
|
' ' +
|
|
|
|
|
'<button type="button" class="btn btn-success edit-question">编辑</button>'
|
|
|
|
|
},
|
|
|
|
|
// 定义列内元素的事件监听器
|
|
|
|
|
events: {
|
|
|
|
|
// 点击详情按钮事件处理函数
|
|
|
|
|
'click .view-question': function (e, value, row, index) {
|
|
|
|
|
that.handleSub(row)
|
|
|
|
|
},
|
|
|
|
|
// 点击编辑按钮事件处理函数
|
|
|
|
|
'click .edit-question': function (e, value, row, index) {
|
|
|
|
|
that.handleEdit(row)
|
|
|
|
|
}
|
|
|
|
@ -223,14 +312,20 @@ export default {
|
|
|
|
|
],
|
|
|
|
|
tableData: [], // bootstrap-table的数据
|
|
|
|
|
// custom bootstrap-table
|
|
|
|
|
// 自定义bootstrap-table配置选项
|
|
|
|
|
options: {
|
|
|
|
|
// 启用搜索功能
|
|
|
|
|
search: true,
|
|
|
|
|
// 显示列选择下拉框
|
|
|
|
|
showColumns: true,
|
|
|
|
|
// 显示导出按钮
|
|
|
|
|
showExport: true,
|
|
|
|
|
// 启用分页
|
|
|
|
|
pagination: true,
|
|
|
|
|
toolbar: '#toolbar',
|
|
|
|
|
// 下面两行是支持高级搜索,即按照字段搜索
|
|
|
|
|
advancedSearch: true,
|
|
|
|
|
// 下面两行是支持高级搜索,即按照字段搜索
|
|
|
|
|
idTable: 'advancedTable',
|
|
|
|
|
// 下面是常用的事件,更多的点击事件可以参考:http://www.itxst.com/bootstrap-table-events/tutorial.html
|
|
|
|
|
// onClickRow: that.clickRow,
|
|
|
|
@ -243,17 +338,35 @@ export default {
|
|
|
|
|
this.loadAll() // 加载所有问题的数据
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
/**
|
|
|
|
|
* 编辑问题
|
|
|
|
|
* @param {Object} record - 问题记录
|
|
|
|
|
*/
|
|
|
|
|
handleEdit (record) {
|
|
|
|
|
this.$refs.modalEdit.edit(record)
|
|
|
|
|
},
|
|
|
|
|
handleSub (record) {
|
|
|
|
|
// 查看题目
|
|
|
|
|
/**
|
|
|
|
|
* 查看问题
|
|
|
|
|
* @param {Object} record - 问题记录
|
|
|
|
|
*/
|
|
|
|
|
console.log(record)
|
|
|
|
|
this.$refs.modalView.edit(record)
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 确认操作后重新加载数据
|
|
|
|
|
*/
|
|
|
|
|
handleOk () {
|
|
|
|
|
this.loadAll() // 加载所有问题的数据
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 双击表格单元格进行编辑
|
|
|
|
|
* @param {String} field - 字段名
|
|
|
|
|
* @param {String} value - 字段值
|
|
|
|
|
* @param {Object} row - 行记录
|
|
|
|
|
* @param {Object} $element - DOM元素
|
|
|
|
|
*/
|
|
|
|
|
dblClickCell (field, value, row, $element) {
|
|
|
|
|
if (field === 'score') { // 更新分数
|
|
|
|
|
const childrenInput = $element.children('.question-score').children('input') // 获取输入框的值
|
|
|
|
@ -274,18 +387,24 @@ export default {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (field === 'level') { // 更新难度
|
|
|
|
|
// 获取输入框的值
|
|
|
|
|
const childrenSelect = $element.children('.question-level').children('select') // 获取输入框的值
|
|
|
|
|
if (childrenSelect.length === 0) return
|
|
|
|
|
// 找到选中的选项
|
|
|
|
|
const optionSelected = $(childrenSelect[0]).find('option:selected')
|
|
|
|
|
// 更新行数据的难度ID和难度名称
|
|
|
|
|
row.levelId = optionSelected.val()
|
|
|
|
|
console.log(row.levelId)
|
|
|
|
|
// 调用问题更新API进行异步更新
|
|
|
|
|
row.level = optionSelected.text()
|
|
|
|
|
// 成功就跳转到结果页面
|
|
|
|
|
console.log(row.level)
|
|
|
|
|
const that = this
|
|
|
|
|
questionUpdate(row).then(res => {
|
|
|
|
|
// 成功就跳转到结果页面
|
|
|
|
|
console.log(res)
|
|
|
|
|
if (res.code === 0) {
|
|
|
|
|
// 更新成功后,修改页面显示的难度,并显示成功通知
|
|
|
|
|
$element.children('.question-level').text(row.level)
|
|
|
|
|
that.$notification.success({
|
|
|
|
|
message: '更新成功',
|
|
|
|
@ -296,17 +415,24 @@ export default {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (field === 'type') { // 更新题型
|
|
|
|
|
// 获取输入框的值
|
|
|
|
|
const childrenSelect = $element.children('.question-type').children('select') // 获取输入框的值
|
|
|
|
|
if (childrenSelect.length === 0) return
|
|
|
|
|
// 找到选中的选项
|
|
|
|
|
const optionSelected = $(childrenSelect[0]).find('option:selected')
|
|
|
|
|
// 更新row对象的typeId和type属性
|
|
|
|
|
row.typeId = optionSelected.val()
|
|
|
|
|
row.type = optionSelected.text()
|
|
|
|
|
// 保存this的引用以便在promise中使用
|
|
|
|
|
const that = this
|
|
|
|
|
// 调用questionUpdate函数更新问题,然后根据结果进行处理
|
|
|
|
|
questionUpdate(row).then(res => {
|
|
|
|
|
// 成功就跳转到结果页面
|
|
|
|
|
console.log(res)
|
|
|
|
|
if (res.code === 0) {
|
|
|
|
|
// 更新页面上显示的题型
|
|
|
|
|
$element.children('.question-type').text(row.type)
|
|
|
|
|
// 显示成功通知
|
|
|
|
|
that.$notification.success({
|
|
|
|
|
message: '更新成功',
|
|
|
|
|
description: '更新成功'
|
|
|
|
@ -316,18 +442,24 @@ export default {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (field === 'category') { // 更新学科
|
|
|
|
|
// 获取输入框的值
|
|
|
|
|
const childrenSelect = $element.children('.question-category').children('select') // 获取输入框的值
|
|
|
|
|
console.log(childrenSelect)
|
|
|
|
|
if (childrenSelect.length === 0) return
|
|
|
|
|
// 找到选中的选项
|
|
|
|
|
const optionSelected = $(childrenSelect[0]).find('option:selected')
|
|
|
|
|
// 更新行数据的学科ID和学科名称
|
|
|
|
|
row.categoryId = optionSelected.val()
|
|
|
|
|
row.category = optionSelected.text()
|
|
|
|
|
const that = this
|
|
|
|
|
// 调用问题更新API
|
|
|
|
|
questionUpdate(row).then(res => {
|
|
|
|
|
// 成功就跳转到结果页面
|
|
|
|
|
console.log(res)
|
|
|
|
|
if (res.code === 0) {
|
|
|
|
|
// 更新成功后,修改界面上的学科名称
|
|
|
|
|
$element.children('.question-category').text(row.category)
|
|
|
|
|
// 显示成功的通知
|
|
|
|
|
that.$notification.success({
|
|
|
|
|
message: '更新成功',
|
|
|
|
|
description: '更新成功'
|
|
|
|
@ -336,14 +468,24 @@ export default {
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 加载所有问题数据
|
|
|
|
|
* 此方法通过调用后端API来获取所有问题的列表,并将其用于更新表格数据
|
|
|
|
|
*/
|
|
|
|
|
loadAll () {
|
|
|
|
|
// 创建一个指向当前组件实例的引用,以避免在回调函数中直接使用this
|
|
|
|
|
const that = this
|
|
|
|
|
// 调用获取所有问题的API
|
|
|
|
|
getQuestionAll()
|
|
|
|
|
.then(res => {
|
|
|
|
|
// 检查返回的响应码
|
|
|
|
|
if (res.code === 0) {
|
|
|
|
|
// 如果成功,更新表格数据
|
|
|
|
|
that.tableData = res.data
|
|
|
|
|
// 调用表格组件的初始化方法,以应用新的数据
|
|
|
|
|
that.$refs.table._initTable()
|
|
|
|
|
} else {
|
|
|
|
|
// 如果失败,显示错误通知
|
|
|
|
|
that.$notification.error({
|
|
|
|
|
message: '获取全部问题的列表失败',
|
|
|
|
|
description: res.msg
|
|
|
|
|