完善试卷试题选择

This commit is contained in:
wanggeng 2022-05-26 12:11:30 +08:00
parent 5ed1d971d2
commit 2762f6179a
8 changed files with 265 additions and 131 deletions

View File

@ -1,19 +1,20 @@
package ink.wgink.module.examine.controller.api.paper.question; package ink.wgink.module.examine.controller.api.paper.question;
import ink.wgink.common.base.DefaultBaseController; import ink.wgink.common.base.DefaultBaseController;
import ink.wgink.exceptions.ParamsException;
import ink.wgink.exceptions.SearchException; import ink.wgink.exceptions.SearchException;
import ink.wgink.interfaces.consts.ISystemConstant; import ink.wgink.interfaces.consts.ISystemConstant;
import ink.wgink.module.examine.pojo.dtos.paper.question.PaperQuestionDTO; import ink.wgink.module.examine.pojo.dtos.paper.question.PaperQuestionDTO;
import ink.wgink.module.examine.pojo.dtos.question.QuestionDTO;
import ink.wgink.module.examine.service.paper.question.IPaperQuestionService; import ink.wgink.module.examine.service.paper.question.IPaperQuestionService;
import ink.wgink.pojo.ListPage; import ink.wgink.pojo.ListPage;
import ink.wgink.pojo.result.ErrorResult; import ink.wgink.pojo.result.ErrorResult;
import ink.wgink.pojo.result.SuccessResult;
import ink.wgink.pojo.result.SuccessResultList; import ink.wgink.pojo.result.SuccessResultList;
import ink.wgink.pojo.vos.IdsVO;
import io.swagger.annotations.*; import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -33,6 +34,20 @@ public class PaperQuestionController extends DefaultBaseController {
@Autowired @Autowired
private IPaperQuestionService paperQuestionService; private IPaperQuestionService paperQuestionService;
@ApiOperation(value = "保存试题", notes = "保存试题接口")
@ApiImplicitParams({
@ApiImplicitParam(name = "paperId", value = "试卷ID", paramType = "path"),
})
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
@PostMapping("save/paper-id/{paperId}")
public SuccessResult save(@PathVariable("paperId") String paperId, @RequestBody IdsVO idsVO) {
if(idsVO.getIds().isEmpty()) {
throw new ParamsException("试题列表不能为空");
}
paperQuestionService.save(paperId, idsVO.getIds());
return new SuccessResult();
}
@ApiOperation(value = "试卷试题列表", notes = "试卷试题列表接口") @ApiOperation(value = "试卷试题列表", notes = "试卷试题列表接口")
@ApiImplicitParams({ @ApiImplicitParams({
@ApiImplicitParam(name = "paperId", value = "试卷ID", paramType = "path"), @ApiImplicitParam(name = "paperId", value = "试卷ID", paramType = "path"),
@ -61,4 +76,21 @@ public class PaperQuestionController extends DefaultBaseController {
return paperQuestionService.listPage(paperId, page); return paperQuestionService.listPage(paperId, page);
} }
@ApiOperation(value = "不包含试卷的试题分页列表", notes = "不包含试卷的试题分页列表接口")
@ApiImplicitParams({
@ApiImplicitParam(name = "excludePaperId", value = "不包含的试卷ID", paramType = "path"),
@ApiImplicitParam(name = "page", value = "当前页码", paramType = "query", dataType = "int", defaultValue = "1"),
@ApiImplicitParam(name = "rows", value = "显示数量", paramType = "query", dataType = "int", defaultValue = "20"),
@ApiImplicitParam(name = "keywords", value = "关键字", paramType = "query", dataType = "String"),
@ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", dataType = "String"),
@ApiImplicitParam(name = "endTime", value = "结束时间", paramType = "query", dataType = "String")
})
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
@GetMapping("listpage-question/exclude-paper-id/{excludePaperId}")
public SuccessResultList<List<QuestionDTO>> listPageQuestionByExcludePaperId(@PathVariable("excludePaperId") String excludePaperId, ListPage page) throws SearchException {
Map<String, Object> params = requestParams();
page.setParams(params);
return paperQuestionService.listPageQuestionByExcludePaperId(excludePaperId, page);
}
} }

View File

@ -25,4 +25,10 @@ public class PaperQuestionRouteController {
return modelAndView; return modelAndView;
} }
@GetMapping("save-select")
public ModelAndView saveSelect() {
ModelAndView modelAndView = new ModelAndView("paper/question/save-select");
return modelAndView;
}
} }

View File

@ -7,6 +7,7 @@ import ink.wgink.exceptions.UpdateException;
import ink.wgink.interfaces.init.IInitBaseTable; import ink.wgink.interfaces.init.IInitBaseTable;
import ink.wgink.module.examine.pojo.dtos.paper.PaperDTO; import ink.wgink.module.examine.pojo.dtos.paper.PaperDTO;
import ink.wgink.module.examine.pojo.dtos.paper.question.PaperQuestionDTO; import ink.wgink.module.examine.pojo.dtos.paper.question.PaperQuestionDTO;
import ink.wgink.module.examine.pojo.dtos.question.QuestionDTO;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.util.List; import java.util.List;
@ -62,4 +63,13 @@ public interface IPaperQuestionDao extends IInitBaseTable {
* @throws SearchException * @throws SearchException
*/ */
List<PaperQuestionDTO> list(Map<String, Object> params) throws SearchException; List<PaperQuestionDTO> list(Map<String, Object> params) throws SearchException;
/**
* 试题列表
*
* @param params
* @return
* @throws SearchException
*/
List<QuestionDTO> listQuestion(Map<String, Object> params) throws SearchException;
} }

View File

@ -1,6 +1,7 @@
package ink.wgink.module.examine.service.paper.question; package ink.wgink.module.examine.service.paper.question;
import ink.wgink.module.examine.pojo.dtos.paper.question.PaperQuestionDTO; import ink.wgink.module.examine.pojo.dtos.paper.question.PaperQuestionDTO;
import ink.wgink.module.examine.pojo.dtos.question.QuestionDTO;
import ink.wgink.pojo.ListPage; import ink.wgink.pojo.ListPage;
import ink.wgink.pojo.result.SuccessResultList; import ink.wgink.pojo.result.SuccessResultList;
@ -15,6 +16,14 @@ import java.util.Map;
**/ **/
public interface IPaperQuestionService { public interface IPaperQuestionService {
/**
* 保存
*
* @param paperId
* @param questionIds
*/
void save(String paperId, List<String> questionIds);
/** /**
* 试卷试题列表 * 试卷试题列表
* *
@ -24,6 +33,14 @@ public interface IPaperQuestionService {
*/ */
List<PaperQuestionDTO> list(String paperId, Map<String, Object> params); List<PaperQuestionDTO> list(String paperId, Map<String, Object> params);
/**
* 试卷试题分页列表
*
* @param page
* @return
*/
SuccessResultList<List<PaperQuestionDTO>> listPage(ListPage page);
/** /**
* 试卷试题分页列表 * 试卷试题分页列表
* *
@ -33,4 +50,13 @@ public interface IPaperQuestionService {
*/ */
SuccessResultList<List<PaperQuestionDTO>> listPage(String paperId, ListPage page); SuccessResultList<List<PaperQuestionDTO>> listPage(String paperId, ListPage page);
/**
* 不包含试卷的试题分页列表
*
* @param excludePaperId
* @param page
* @return
*/
SuccessResultList<List<QuestionDTO>> listPageQuestionByExcludePaperId(String excludePaperId, ListPage page);
} }

View File

@ -5,9 +5,11 @@ import com.github.pagehelper.PageInfo;
import ink.wgink.common.base.DefaultBaseService; import ink.wgink.common.base.DefaultBaseService;
import ink.wgink.module.examine.dao.paper.question.IPaperQuestionDao; import ink.wgink.module.examine.dao.paper.question.IPaperQuestionDao;
import ink.wgink.module.examine.pojo.dtos.paper.question.PaperQuestionDTO; import ink.wgink.module.examine.pojo.dtos.paper.question.PaperQuestionDTO;
import ink.wgink.module.examine.pojo.dtos.question.QuestionDTO;
import ink.wgink.module.examine.service.paper.question.IPaperQuestionService; import ink.wgink.module.examine.service.paper.question.IPaperQuestionService;
import ink.wgink.pojo.ListPage; import ink.wgink.pojo.ListPage;
import ink.wgink.pojo.result.SuccessResultList; import ink.wgink.pojo.result.SuccessResultList;
import ink.wgink.util.UUIDUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -26,6 +28,18 @@ public class PaperQuestionServiceImpl extends DefaultBaseService implements IPap
@Autowired @Autowired
private IPaperQuestionDao paperQuestionDao; private IPaperQuestionDao paperQuestionDao;
@Override
public void save(String paperId, List<String> questionIds) {
Map<String, Object> params = getHashMap(8);
params.put("paperId", paperId);
params.put("questionSort", "ZZZ-000");
for (String questionId : questionIds) {
params.put("paperQuestionId", UUIDUtil.getUUID());
params.put("questionId", questionId);
paperQuestionDao.save(params);
}
}
@Override @Override
public List<PaperQuestionDTO> list(String paperId, Map<String, Object> params) { public List<PaperQuestionDTO> list(String paperId, Map<String, Object> params) {
params = params == null ? getHashMap(0) : params; params = params == null ? getHashMap(0) : params;
@ -33,10 +47,25 @@ public class PaperQuestionServiceImpl extends DefaultBaseService implements IPap
} }
@Override @Override
public SuccessResultList<List<PaperQuestionDTO>> listPage(String paperId, ListPage page) { public SuccessResultList<List<PaperQuestionDTO>> listPage(ListPage page) {
PageHelper.startPage(page.getPage(), page.getRows()); PageHelper.startPage(page.getPage(), page.getRows());
List<PaperQuestionDTO> paperQuestionDTOS = paperQuestionDao.list(page.getParams()); List<PaperQuestionDTO> paperQuestionDTOS = paperQuestionDao.list(page.getParams());
PageInfo<PaperQuestionDTO> pageInfo = new PageInfo<>(paperQuestionDTOS); PageInfo<PaperQuestionDTO> pageInfo = new PageInfo<>(paperQuestionDTOS);
return new SuccessResultList<>(paperQuestionDTOS, pageInfo.getPageNum(), pageInfo.getTotal()); return new SuccessResultList<>(paperQuestionDTOS, pageInfo.getPageNum(), pageInfo.getTotal());
} }
@Override
public SuccessResultList<List<PaperQuestionDTO>> listPage(String paperId, ListPage page) {
page.getParams().put("paperId", paperId);
return listPage(page);
}
@Override
public SuccessResultList<List<QuestionDTO>> listPageQuestionByExcludePaperId(String excludePaperId, ListPage page) {
page.getParams().put("excludePaperId", excludePaperId);
PageHelper.startPage(page.getPage(), page.getRows());
List<QuestionDTO> questionDTOS = paperQuestionDao.listQuestion(page.getParams());
PageInfo<QuestionDTO> pageInfo = new PageInfo<>(questionDTOS);
return new SuccessResultList<>(questionDTOS, pageInfo.getPageNum(), pageInfo.getTotal());
}
} }

View File

@ -139,4 +139,89 @@
</if> </if>
</select> </select>
<!-- 试题管理列表 -->
<select id="listQuestion" parameterType="map" resultMap="ink.wgink.module.examine.dao.question.IQuestionDao.questionDTO">
SELECT
t1.subject,
t1.type,
t1.choice_type,
t1.parent_id,
t1.difficulty,
t1.source,
LEFT(t1.gmt_create, 19) gmt_create,
t1.question_id
FROM
exam_question t1
WHERE
t1.is_delete = 0
<if test="excludePaperId != null and excludePaperId != ''">
AND
t1.question_id NOT IN (
SELECT
st1.question_id
FROM
exam_paper_question st1
WHERE
paper_id = #{excludePaperId}
)
</if>
<if test="keywords != null and keywords != ''">
AND (
t1.subject LIKE CONCAT('%', #{keywords}, '%')
)
</if>
<if test="startTime != null and startTime != ''">
AND
LEFT(t1.gmt_create, 10) <![CDATA[ >= ]]> #{startTime}
</if>
<if test="endTime != null and endTime != ''">
AND
LEFT(t1.gmt_create, 10) <![CDATA[ <= ]]> #{endTime}
</if>
<if test="type != null and type != ''">
AND
t1.type = #{type}
</if>
<if test="choiceType != null and choiceType != ''">
AND
t1.choice_type = #{choiceType}
</if>
<if test="questionIds != null and questionIds.size > 0">
AND
t1.question_id IN
<foreach collection="questionIds" index="index" open="(" separator="," close=")">
#{questionIds[${index}]}
</foreach>
</if>
<if test="creator != null and creator != ''">
AND
t1.creator = #{creator}
</if>
<if test="creators != null and creators.size > 0">
AND
t1.creator IN
<foreach collection="creators" index="index" open="(" separator="," close=")">
#{creators[${index}]}
</foreach>
</if>
<if test="difficulty != null">
AND
t1.difficulty = #{difficulty}
</if>
<if test="questionTypeIds != null and questionTypeIds.size > 0">
AND
t1.question_id IN (
SELECT
st1.question_id
FROM
exam_question_type_question st1
WHERE
st1.question_type_id IN
<foreach collection="questionTypeIds" index="index" open="(" separator="," close=")">
#{questionTypeIds[${index}]}
</foreach>
)
</if>
</select>
</mapper> </mapper>

View File

@ -293,39 +293,12 @@
choiceType = ''; choiceType = '';
} }
top.dialog.open({ top.dialog.open({
url: top.restAjax.path('route/question/list-select?selectCount={selectCount}&type={type}&choiceType={choiceType}', [parseInt(selectCount - selectedCount), type, choiceType]), url: top.restAjax.path('route/paper/question/save-select?paperId={paperId}&selectCount={selectCount}&type={type}&choiceType={choiceType}', [paperId, parseInt(selectCount - selectedCount), type, choiceType]),
title: '选择题', title: '选择题',
width: '75%', width: '75%',
height: '80%', height: '80%',
onClose: function() { onClose: function() {
var newSelectedQuestionList = top.dialog.dialogData.newSelectedQuestionList; reloadTable();
if(newSelectedQuestionList.length != 0) {
var questionIds = [];
for(var i = 0, item; item = newSelectedQuestionList[i++];) {
questionIds.push(item.questionId);
}
if(questionIds.length > 0) {
top.dialog.confirm(top.dataMessage.commit, function(index) {
top.dialog.close(index);
var loadLayerIndex;
top.restAjax.post(top.restAjax.path('api/paper/question/save', []), {
paperId: paperId,
questionType: questionType,
questionIds: questionIds
}, null, function(code, data) {
top.dialog.msg('添加成功', {time: 1000});
reloadTable();
}, function(code, data) {
top.dialog.msg(data.msg);
}, function() {
loadLayerIndex = top.dialog.msg(top.dataMessage.committing, {icon: 16, time: 0, shade: 0.3});
}, function() {
top.dialog.close(loadLayerIndex);
});
});
}
}
top.dialog.dialogData.oldSelectedQuestionList = [];
} }
}); });
} else if(layEvent === 'clearSaveEvent') { } else if(layEvent === 'clearSaveEvent') {

View File

@ -53,7 +53,7 @@
<button type="button" id="search" class="layui-btn layui-btn-sm"> <button type="button" id="search" class="layui-btn layui-btn-sm">
<i class="fa fa-lg fa-search"></i> 搜索 <i class="fa fa-lg fa-search"></i> 搜索
</button> </button>
<button type="button" id="confirm" class="layui-btn layui-btn-normal layui-btn-sm" style="float: right;">确定</button> <button type="button" id="saveBtn" class="layui-btn layui-btn-normal layui-btn-sm" style="float: right;">确定</button>
</div> </div>
<table class="layui-hide" id="dataTable" lay-filter="dataTable"></table> <table class="layui-hide" id="dataTable" lay-filter="dataTable"></table>
</div> </div>
@ -77,21 +77,15 @@
var common = layui.common; var common = layui.common;
var form = layui.form; var form = layui.form;
var resizeTimeout = null; var resizeTimeout = null;
var paperId = top.restAjax.params(window.location.href).paperId; var queryParams = top.restAjax.params(window.location.href);
var tableUrl = 'api/paper/question/listpage/{classInfoId}'; var paperId = queryParams.paperId;
var oldSelectedQuestionList = top.dialog.dialogData.oldSelectedQuestionList ? top.dialog.dialogData.oldSelectedQuestionList : []; var selectCount = queryParams.selectCount;
// 清空上次选择 var questionType = queryParams.questionType;
top.dialog.dialogData.newSelectedQuestionList = []; var questionChoiceType = queryParams.questionChoiceType;
var newSelectedQuestionList = [];
var tableData = [];
// 初始化选择列表 var tableUrl = 'api/paper/question/listpage-question/exclude-paper-id/{paperId}?questionType={questionType}&questionChoiceType={questionChoiceType}';
function initNewSelectedQuestionList() {
for(var i = 0, item; item = oldSelectedQuestionList[i++];) { var selectObj = {};
newSelectedQuestionList.push(item);
}
}
initNewSelectedQuestionList();
function getDifficulty(num) { function getDifficulty(num) {
var result = ''; var result = '';
@ -107,7 +101,7 @@
table.render({ table.render({
elem: '#dataTable', elem: '#dataTable',
id: 'dataTable', id: 'dataTable',
url: top.restAjax.path(tableUrl, [classInfoId]), url: top.restAjax.path(tableUrl, [paperId, questionType, questionChoiceType]),
width: admin.screen() > 1 ? '100%' : '', width: admin.screen() > 1 ? '100%' : '',
height: $win.height() - 60, height: $win.height() - 60,
limit: 20, limit: 20,
@ -138,15 +132,6 @@
return rowData; return rowData;
} }
}, },
{field: 'questionTypeName', width: 140, title: '自定义试题类型', align:'center',
templet: function(row) {
var rowData = row[this.field];
if(typeof(rowData) === 'undefined' || rowData == null || rowData == '') {
return '-';
}
return rowData;
}
},
{field: 'type', width: 150, title: '种类', align:'center', {field: 'type', width: 150, title: '种类', align:'center',
templet: function(row) { templet: function(row) {
var rowData = row[this.field]; var rowData = row[this.field];
@ -219,25 +204,12 @@
page: true, page: true,
parseData: function(data) { parseData: function(data) {
for(var i = 0, item; item = data.rows[i++];) { for(var i = 0, item; item = data.rows[i++];) {
if(!newSelectedQuestionList) { if(selectObj[item.questionId]) {
item.checked = false;
continue;
}
var isSelected = false;
for(var j = 0, jItem; jItem = newSelectedQuestionList[j++];) {
if(item.questionId === jItem.questionId) {
isSelected = true;
break;
}
}
if(isSelected) {
item.checked = true; item.checked = true;
} else { } else {
item.checked = false; item.checked = false;
} }
} }
tableData = data.rows;
return { return {
'code': 0, 'code': 0,
'msg': '', 'msg': '',
@ -250,7 +222,6 @@
// 重载表格 // 重载表格
function reloadTable(currentPage) { function reloadTable(currentPage) {
table.reload('dataTable', { table.reload('dataTable', {
url: top.restAjax.path(tableUrl, [classInfoId]),
where: { where: {
keywords: $('#keywords').val(), keywords: $('#keywords').val(),
startTime: $('#startTime').val(), startTime: $('#startTime').val(),
@ -267,68 +238,70 @@
}); });
} }
initTable(); initTable();
function isQuestionSelected(questionId) {
for(var i = 0, item; item = newSelectedQuestionList[i++];) {
if(questionId == item.questionId) {
return true;
}
}
return false;
}
function addQuestionSelected(questionItem) {
if(isQuestionSelected(questionItem.questionId)) {
return;
}
newSelectedQuestionList.push({
questionId: questionItem.questionId,
})
}
function removeQuestionSelected(questionItem) {
for(var i = 0, item; item = newSelectedQuestionList[i++];) {
if(questionItem.questionId == item.questionId) {
newSelectedQuestionList.splice(--i, 1);
i--;
return;
}
}
}
table.on('checkbox(dataTable)', function(obj) {
if(obj.type === 'all') {
if(obj.checked) {
// 添加全部
for(var i = 0, item; item = tableData[i++];) {
addQuestionSelected(item);
}
} else {
// 删除全部
for(var i = 0, item; item = tableData[i++];) {
removeQuestionSelected(item);
}
}
} else {
if(obj.checked) {
addQuestionSelected(obj.data);
} else {
removeQuestionSelected(obj.data);
}
}
});
table.on('radio(dataTable)', function(obj) {
newSelectedQuestionList.splice(0, newSelectedQuestionList.length);
addQuestionSelected(obj.data);
});
$(document).on('click', '#search', function() { $(document).on('click', '#search', function() {
reloadTable(1); reloadTable(1);
}); });
$(document).on('click', '#confirm', function() {
top.dialog.dialogData.newSelectedQuestionList = newSelectedQuestionList; table.on('checkbox(dataTable)', function(obj) {
top.dialog.closeBox(); if(obj.type === 'one') {
if(obj.checked) {
if(selectObj.length >= selectCount) {
obj.checked = !obj.checked;
top.dialog.msg('超过最大可选数量:'+ selectCount);
return;
}
selectObj[obj.data.questionId] = obj.data;
} else {
delete selectObj[obj.data.questionId];
}
} else {
var datas = table.cache.dataTable;
if(obj.checked) {
for(var i = 0, item; item = datas[i++];) {
if(selectObj.length >= selectCount) {
obj.checked = !obj.checked;
top.dialog.msg('超过最大可选数量:'+ selectCount);
return;
}
selectObj[item.questionId] = item;
}
} else {
for(var i = 0, item; item = datas[i++];) {
delete selectObj[item.questionId];
}
}
}
}); });
$(document).on('click', '#saveBtn', function() {
var selectIdArray = [];
for(var k in selectObj) {
selectIdArray.push(k);
}
if(selectIdArray.length === 0) {
top.dialog.msg('请选择试题');
return;
}
top.dialog.confirm('确定保存吗?', function(index) {
top.dialog.close(index);
var loadLayerIndex;
top.restAjax.post(top.restAjax.path('api/paper/question/save/paper-id/{paperId}', [paperId]), {
ids: selectIdArray
}, null, function(code, data) {
top.dialog.msg('提交成功');
reloadTable(1);
}, function(code, data) {
top.dialog.msg(data.msg);
}, function() {
loadLayerIndex = top.dialog.msg('正在提交...', {icon: 16, time: 0, shade: 0.3});
}, function() {
top.dialog.close(loadLayerIndex);
});
});
})
table.on('tool(dataTable)', function(obj) { table.on('tool(dataTable)', function(obj) {
var data = obj.data; var data = obj.data;
var event = obj.event; var event = obj.event;