完善题库

This commit is contained in:
WenG 2022-05-15 22:13:35 +08:00
parent 78bd5fb444
commit 36ca8ca506
32 changed files with 862 additions and 444 deletions

View File

@ -94,8 +94,9 @@ public class QuestionController extends DefaultBaseController {
@ApiOperation(value = "试题管理列表", notes = "试题管理列表接口")
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
@GetMapping("list")
public List<QuestionDTO> listQuestion() throws SearchException {
public List<QuestionDTO> listQuestion(@RequestParam(name = "questionType", required = false) String questionType) throws SearchException {
Map<String, Object> params = requestParams();
setRequestParams(params, questionType);
return questionService.list(params);
}
@ -109,8 +110,9 @@ public class QuestionController extends DefaultBaseController {
})
@ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
@GetMapping("listpage")
public SuccessResultList<List<QuestionDTO>> listPageQuestion(ListPage page) throws SearchException {
public SuccessResultList<List<QuestionDTO>> listPageQuestion(@RequestParam(name = "questionType", required = false) String questionType, ListPage page) throws SearchException {
Map<String, Object> params = requestParams();
setRequestParams(params, questionType);
page.setParams(params);
return questionService.listPage(page);
}
@ -124,4 +126,11 @@ public class QuestionController extends DefaultBaseController {
return new SuccessResultData<>(count);
}
private void setRequestParams(Map<String, Object> params, String questionType) {
if (!StringUtils.isBlank(questionType)) {
params.remove("questionType");
params.put("questionTypeIds", Arrays.asList(questionType.split(",")));
}
}
}

View File

@ -33,7 +33,7 @@ import java.util.Map;
**/
@Api(tags = ISystemConstant.API_TAGS_SYSTEM_PREFIX + "试题类型接口")
@RestController
@RequestMapping(ISystemConstant.API_PREFIX + "/question/type")
@RequestMapping(ISystemConstant.API_PREFIX + "/question-type")
public class QuestionTypeController extends DefaultBaseController {
@Autowired

View File

@ -19,7 +19,7 @@ import org.springframework.web.servlet.ModelAndView;
**/
@Api(tags = ISystemConstant.API_TAGS_SYSTEM_PREFIX + "题目类型路由")
@Controller
@RequestMapping(ISystemConstant.ROUTE_PREFIX + "/question/type")
@RequestMapping(ISystemConstant.ROUTE_PREFIX + "/question-type")
public class QuestionTypeRouteController {
@GetMapping("list")

View File

@ -4,6 +4,7 @@ import ink.wgink.exceptions.RemoveException;
import ink.wgink.exceptions.SaveException;
import ink.wgink.exceptions.SearchException;
import ink.wgink.exceptions.UpdateException;
import ink.wgink.interfaces.init.IInitBaseTable;
import ink.wgink.module.examine.pojo.dtos.question.QuestionOptionsDTO;
import org.springframework.stereotype.Repository;
@ -18,7 +19,7 @@ import java.util.Map;
* @Version: 1.0
**/
@Repository
public interface IQuestionOptionsDao {
public interface IQuestionOptionsDao extends IInitBaseTable {
/**
* 新增试题选项

View File

@ -0,0 +1,55 @@
package ink.wgink.module.examine.dao.question;
import ink.wgink.exceptions.RemoveException;
import ink.wgink.exceptions.SaveException;
import ink.wgink.exceptions.SearchException;
import ink.wgink.interfaces.init.IInitBaseTable;
import ink.wgink.module.examine.pojo.dtos.question.QuestionTypeDTO;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Map;
/**
* @Description: 试题类型与试题
* @Author: WenG
* @Date: 2022/5/15 17:16
* @Version: 1.0
**/
@Repository
public interface IQuestionTypeQuestionDao extends IInitBaseTable {
/**
* 新增
*
* @param params
* @throws SaveException
*/
void save(Map<String, Object> params) throws SaveException;
/**
* 删除
*
* @param params
* @throws RemoveException
*/
void delete(Map<String, Object> params) throws RemoveException;
/**
* 试题类型ID列表
*
* @param params
* @return
* @throws SearchException
*/
List<String> listQuestionTypeId(Map<String, Object> params) throws SearchException;
/**
* 试题类型列表
*
* @param params
* @return
* @throws SearchException
*/
List<QuestionTypeDTO> listQuestionType(Map<String, Object> params) throws SearchException;
}

View File

@ -43,8 +43,6 @@ public class QuestionDTO {
private String answer;
@ApiModelProperty(name = "gmtCreate", value = "创建时间")
private String gmtCreate;
@ApiModelProperty(name = "isUsed", value = "是否被使用")
private boolean isUsed;
@ApiModelProperty(name = "options", value = "选项")
private List<QuestionOptionsDTO> options;
@ -160,14 +158,6 @@ public class QuestionDTO {
this.gmtCreate = gmtCreate;
}
public boolean isUsed() {
return isUsed;
}
public void setUsed(boolean used) {
isUsed = used;
}
public List<QuestionOptionsDTO> getOptions() {
return options;
}

View File

@ -0,0 +1,40 @@
package ink.wgink.module.examine.pojo.pos.question;
/**
*
* @ClassName: QuestionTypePO
* @Description: 试题类型
* @Author: CodeFactory
* @Date: 2021-04-04 11:40:13
* @Version: 3.0
**/
public class QuestionTypeQuestionPO {
private Long id;
private String questionTypeId;
private String questionId;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getQuestionTypeId() {
return questionTypeId;
}
public void setQuestionTypeId(String questionTypeId) {
this.questionTypeId = questionTypeId;
}
public String getQuestionId() {
return questionId;
}
public void setQuestionId(String questionId) {
this.questionId = questionId;
}
}

View File

@ -23,8 +23,6 @@ public class QuestionVO {
private String subject;
@ApiModelProperty(name = "questionType", value = "试题类型")
private String questionType;
@ApiModelProperty(name = "customQuestionType", value = "自定义试题类型")
private String customQuestionType;
@ApiModelProperty(name = "type", value = "种类")
@CheckEmptyAnnotation(name = "种类", types = {"choice", "tureOrFalse", "fillInTheBlanks", "answer"})
private String type;
@ -62,14 +60,6 @@ public class QuestionVO {
this.questionType = questionType;
}
public String getCustomQuestionType() {
return customQuestionType == null ? "" : customQuestionType.trim();
}
public void setCustomQuestionType(String customQuestionType) {
this.customQuestionType = customQuestionType;
}
public String getType() {
return type == null ? "" : type.trim();
}
@ -141,8 +131,6 @@ public class QuestionVO {
.append(subject).append('\"');
sb.append(",\"questionType\":\"")
.append(questionType).append('\"');
sb.append(",\"customQuestionType\":\"")
.append(customQuestionType).append('\"');
sb.append(",\"type\":\"")
.append(type).append('\"');
sb.append(",\"choiceType\":\"")

View File

@ -37,6 +37,16 @@ public interface IQuestionOptionsService {
*/
String saveAndReturnId(QuestionOptionsVO questionOptionsVO) throws Exception;
/**
* 新增
*
* @param questionId
* @param options
* @return
* @throws Exception
*/
void save(String questionId, List<QuestionOptionsVO> options) throws Exception;
/**
* 删除试题选项物理删除
*

View File

@ -0,0 +1,91 @@
package ink.wgink.module.examine.service.question;
import ink.wgink.module.examine.pojo.dtos.question.QuestionTypeDTO;
import java.util.List;
/**
* @Description: 试题类型与试题
* @Author: WenG
* @Date: 2022/5/15 17:29
* @Version: 1.0
**/
public interface IQuestionTypeQuestionService {
/**
* 新增
*
* @param questionId
* @param questionTypeId
*/
void save(String questionId, String questionTypeId);
/**
* 新增
*
* @param questionId
* @param questionTypeIds
*/
void save(String questionId, List<String> questionTypeIds);
/**
* 删除
*
* @param questionId
*/
void deleteByQuestionId(String questionId);
/**
* 删除
*
* @param questionIds
*/
void deleteByQuestionIds(List<String> questionIds);
/**
* 删除
*
* @param questionTypeId
*/
void deleteByQuestionTypeId(String questionTypeId);
/**
* 删除
*
* @param questionTypeIds
*/
void deleteByQuestionTypeIds(List<String> questionTypeIds);
/**
* 试题类型ID列表
*
* @param questionId
* @return
*/
List<String> listQuestionTypeIdByQuestionId(String questionId);
/**
* 试题类型ID列表
*
* @param questionIds
* @return
*/
List<String> listQuestionTypeIdByQuestionIds(List<String> questionIds);
/**
* 试题类型列表
*
* @param questionId
* @return
*/
List<QuestionTypeDTO> listQuestionTypeByQuestionId(String questionId);
/**
* 试题类型列表
*
* @param questionIds
* @return
*/
List<QuestionTypeDTO> listQuestionTypeByQuestionIds(List<String> questionIds);
}

View File

@ -46,6 +46,17 @@ public class QuestionOptionsServiceImpl extends DefaultBaseService implements IQ
return questionOptionsId;
}
@Override
public void save(String questionId, List<QuestionOptionsVO> options) throws Exception {
// 删除原有选项
deleteByQuestionId(questionId);
// 重新添加新选项
for (QuestionOptionsVO questionOptionsVO : options) {
questionOptionsVO.setQuestionId(questionId);
save(questionOptionsVO);
}
}
@Override
public void delete(List<String> ids) throws RemoveException {
Map<String, Object> params = getHashMap(3);

View File

@ -9,20 +9,22 @@ import ink.wgink.module.examine.dao.question.IQuestionDao;
import ink.wgink.module.examine.enums.question.QuestionTypeEnum;
import ink.wgink.module.examine.pojo.dtos.question.QuestionDTO;
import ink.wgink.module.examine.pojo.dtos.question.QuestionOptionsDTO;
import ink.wgink.module.examine.pojo.dtos.question.QuestionTypeDTO;
import ink.wgink.module.examine.pojo.pos.question.QuestionPO;
import ink.wgink.module.examine.pojo.vos.question.QuestionOptionsVO;
import ink.wgink.module.examine.pojo.vos.question.QuestionVO;
import ink.wgink.module.examine.service.question.IQuestionOptionsService;
import ink.wgink.module.examine.service.question.IQuestionService;
import ink.wgink.module.examine.service.question.IQuestionTypeService;
import ink.wgink.module.examine.service.question.IQuestionTypeQuestionService;
import ink.wgink.pojo.ListPage;
import ink.wgink.pojo.result.SuccessResultList;
import ink.wgink.util.ArrayListUtil;
import ink.wgink.util.UUIDUtil;
import ink.wgink.util.map.HashMapUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@ -40,7 +42,8 @@ public class QuestionServiceImpl extends DefaultBaseService implements IQuestion
private IQuestionDao questionDao;
@Autowired
private IQuestionOptionsService questionOptionsService;
private IQuestionTypeService questionTypeService;
@Autowired
private IQuestionTypeQuestionService questionTypeQuestionService;
@Override
public void save(QuestionVO questionVO) throws Exception {
@ -76,11 +79,10 @@ public class QuestionServiceImpl extends DefaultBaseService implements IQuestion
if (!hasOption) {
return questionId;
}
// 保存选项
for (QuestionOptionsVO questionOptionsVO : questionVO.getOptions()) {
questionOptionsVO.setQuestionId(questionId);
questionOptionsService.save(questionOptionsVO);
}
// 删除原有试题类型
questionOptionsService.save(questionId, questionVO.getOptions());
// 新增试题类型
questionTypeQuestionService.save(questionId, Arrays.asList(questionVO.getQuestionType().split(",")));
return questionId;
}
@ -176,13 +178,10 @@ public class QuestionServiceImpl extends DefaultBaseService implements IQuestion
if (!hasOption) {
return;
}
// 删除原有选项
questionOptionsService.deleteByQuestionId(questionId);
// 重新添加新选项
for (QuestionOptionsVO questionOptionsVO : questionVO.getOptions()) {
questionOptionsVO.setQuestionId(questionId);
questionOptionsService.save(questionOptionsVO);
}
// 删除原有试题类型
questionOptionsService.save(questionId, questionVO.getOptions());
// 新增试题类型
questionTypeQuestionService.save(questionId, Arrays.asList(questionVO.getQuestionType().split(",")));
}
private QuestionPO getPO(Map<String, Object> params) {
@ -206,13 +205,23 @@ public class QuestionServiceImpl extends DefaultBaseService implements IQuestion
List<QuestionOptionsDTO> questionOptionsDTOs = questionOptionsService.listByQuestionId(questionId);
questionDTO.setOptions(questionOptionsDTOs);
}
if (!StringUtils.isBlank(questionDTO.getQuestionType())) {
List<QuestionTypeDTO> questionTypeDTOs = questionTypeQuestionService.listQuestionTypeByQuestionId(questionId);
setQuestionTypeName(questionDTO, questionTypeDTOs);
}
return questionDTO;
}
@Override
public List<QuestionDTO> list(Map<String, Object> params) throws SearchException {
return questionDao.list(params);
List<QuestionDTO> questionDTOs = questionDao.list(params);
if (!questionDTOs.isEmpty()) {
List<String> questionIds = ArrayListUtil.listBeanStringIdValue(questionDTOs, "questionId", QuestionDTO.class);
List<QuestionTypeDTO> questionTypeDTOs = questionTypeQuestionService.listQuestionTypeByQuestionIds(questionIds);
setQuestionTypeName(questionDTOs, questionTypeDTOs);
}
return questionDTOs;
}
@Override
@ -242,4 +251,37 @@ public class QuestionServiceImpl extends DefaultBaseService implements IQuestion
return questionDao.listPO(params);
}
/**
* 设置试题类型名称
*
* @param questionDTOs
* @param questionTypeDTOs
*/
private void setQuestionTypeName(List<QuestionDTO> questionDTOs, List<QuestionTypeDTO> questionTypeDTOs) {
questionDTOs.forEach(questionDTO -> {
setQuestionTypeName(questionDTO, questionTypeDTOs);
});
}
/**
* 设置试题类型名称
*
* @param questionDTO
* @param questionTypeDTOs
*/
private void setQuestionTypeName(QuestionDTO questionDTO, List<QuestionTypeDTO> questionTypeDTOs) {
String questionType = "";
String questionTypeName = "";
for (QuestionTypeDTO questionTypeDTO : questionTypeDTOs) {
if (!StringUtils.isBlank(questionType)) {
questionType += ",";
questionTypeName += ",";
}
questionType += questionTypeDTO.getQuestionTypeId();
questionTypeName += questionTypeDTO.getTypeSummary();
}
questionDTO.setQuestionType(questionType);
questionDTO.setQuestionTypeName(questionTypeName);
}
}

View File

@ -0,0 +1,106 @@
package ink.wgink.module.examine.service.question.impl;
import ink.wgink.common.base.DefaultBaseService;
import ink.wgink.module.examine.dao.question.IQuestionTypeQuestionDao;
import ink.wgink.module.examine.pojo.dtos.question.QuestionTypeDTO;
import ink.wgink.module.examine.service.question.IQuestionTypeQuestionService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* @Description: 试题类型与试题
* @Author: WenG
* @Date: 2022/5/15 17:29
* @Version: 1.0
**/
@Service
public class QuestionTypeQuestionServiceImpl extends DefaultBaseService implements IQuestionTypeQuestionService {
@Autowired
private IQuestionTypeQuestionDao questionTypeQuestionDao;
@Override
public void save(String questionId, String questionTypeId) {
Map<String, Object> params = getHashMap(4);
params.put("questionTypeId", questionTypeId);
params.put("questionId", questionId);
questionTypeQuestionDao.save(params);
}
@Override
public void save(String questionId, List<String> questionTypeIds) {
if (questionTypeIds.isEmpty()) {
return;
}
// 删除已有类型
deleteByQuestionId(questionId);
for (String questionTypeId : questionTypeIds) {
if(StringUtils.isBlank(questionTypeId)) {
continue;
}
save(questionId, questionTypeId);
}
}
@Override
public void deleteByQuestionId(String questionId) {
Map<String, Object> params = getHashMap(2);
params.put("questionIds", Arrays.asList(questionId));
questionTypeQuestionDao.delete(params);
}
@Override
public void deleteByQuestionIds(List<String> questionIds) {
Map<String, Object> params = getHashMap(2);
params.put("questionIds", questionIds);
questionTypeQuestionDao.delete(params);
}
@Override
public void deleteByQuestionTypeId(String questionTypeId) {
Map<String, Object> params = getHashMap(2);
params.put("questionTypeIds", Arrays.asList(questionTypeId));
questionTypeQuestionDao.delete(params);
}
@Override
public void deleteByQuestionTypeIds(List<String> questionTypeIds) {
Map<String, Object> params = getHashMap(2);
params.put("questionTypeIds", questionTypeIds);
questionTypeQuestionDao.delete(params);
}
@Override
public List<String> listQuestionTypeIdByQuestionId(String questionId) {
Map<String, Object> params = getHashMap(2);
params.put("questionId", questionId);
return questionTypeQuestionDao.listQuestionTypeId(params);
}
@Override
public List<String> listQuestionTypeIdByQuestionIds(List<String> questionIds) {
Map<String, Object> params = getHashMap(2);
params.put("questionIds", questionIds);
return questionTypeQuestionDao.listQuestionTypeId(params);
}
@Override
public List<QuestionTypeDTO> listQuestionTypeByQuestionId(String questionId) {
Map<String, Object> params = getHashMap(2);
params.put("questionId", questionId);
return questionTypeQuestionDao.listQuestionType(params);
}
@Override
public List<QuestionTypeDTO> listQuestionTypeByQuestionIds(List<String> questionIds) {
Map<String, Object> params = getHashMap(2);
params.put("questionIds", questionIds);
return questionTypeQuestionDao.listQuestionType(params);
}
}

View File

@ -5,7 +5,6 @@
<resultMap id="questionDTO" type="ink.wgink.module.examine.pojo.dtos.question.QuestionDTO">
<id column="question_id" property="questionId"/>
<result column="subject" property="subject"/>
<result column="question_type" property="questionType"/>
<result column="custom_question_type" property="customQuestionType"/>
<result column="type" property="type"/>
<result column="choice_type" property="choiceType"/>
@ -20,7 +19,6 @@
<resultMap id="questionPO" type="ink.wgink.module.examine.pojo.pos.question.QuestionPO">
<id column="question_id" property="questionId"/>
<result column="subject" property="subject"/>
<result column="question_type" property="questionType"/>
<result column="custom_question_type" property="customQuestionType"/>
<result column="type" property="type"/>
<result column="choice_type" property="choiceType"/>
@ -34,7 +32,24 @@
<!-- 建表 -->
<update id="createTable">
CREATE TABLE IF NOT EXISTS `exam_question` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`question_id` char(36) NOT NULL COMMENT '主键',
`subject` longtext COMMENT '题目',
`type` varchar(255) DEFAULT NULL COMMENT '种类',
`choice_type` varchar(255) DEFAULT NULL COMMENT '选择类别',
`analysis` longtext COMMENT '解析',
`parent_id` varchar(255) DEFAULT NULL COMMENT '上级试题',
`difficulty` int(11) DEFAULT NULL COMMENT '难度',
`source` varchar(255) DEFAULT NULL COMMENT '来源',
`answer` varchar(255) DEFAULT NULL COMMENT '答案',
`creator` char(36) DEFAULT NULL,
`gmt_create` datetime DEFAULT NULL,
`modifier` char(36) DEFAULT NULL,
`gmt_modified` datetime DEFAULT NULL,
`is_delete` int(1) DEFAULT '0',
PRIMARY KEY (`id`,`question_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
</update>
<!-- 新增试题管理 -->
@ -43,7 +58,6 @@
question_id,
subject,
question_type,
custom_question_type,
type,
choice_type,
analysis,
@ -60,7 +74,6 @@
#{questionId},
#{subject},
#{questionType},
#{customQuestionType},
#{type},
#{choiceType},
#{analysis},
@ -110,12 +123,6 @@
<if test="subject != null and subject != ''">
subject = #{subject},
</if>
<if test="questionType != null">
question_type = #{questionType},
</if>
<if test="customQuestionType != null">
custom_question_type = #{customQuestionType},
</if>
<if test="type != null and type != ''">
type = #{type},
</if>
@ -147,8 +154,6 @@
<select id="get" parameterType="map" resultMap="questionDTO">
SELECT
t1.subject,
t1.question_type,
t1.custom_question_type,
t1.type,
t1.choice_type,
t1.analysis,
@ -171,8 +176,6 @@
<select id="getPO" parameterType="map" resultMap="questionPO">
SELECT
t1.subject,
t1.question_type,
t1.custom_question_type,
t1.type,
t1.choice_type,
t1.analysis,
@ -199,8 +202,6 @@
<select id="list" parameterType="map" resultMap="questionDTO">
SELECT
t1.subject,
t1.question_type,
t1.custom_question_type,
t1.type,
t1.choice_type,
t1.parent_id,
@ -214,7 +215,7 @@
t1.is_delete = 0
<if test="keywords != null and keywords != ''">
AND (
t1.subject LIKE CONCAT('%', #{keywords}, '%')
t1.subject LIKE CONCAT('%', #{keywords}, '%')
)
</if>
<if test="startTime != null and startTime != ''">
@ -233,13 +234,6 @@
AND
t1.choice_type = #{choiceType}
</if>
<if test="withoutQuestionIds != null and withoutQuestionIds.size > 0">
AND
t1.question_id NOT IN
<foreach collection="withoutQuestionIds" index="index" open="(" separator="," close=")">
#{withoutQuestionIds[${index}]}
</foreach>
</if>
<if test="questionIds != null and questionIds.size > 0">
AND
t1.question_id IN
@ -262,16 +256,27 @@
AND
t1.difficulty = #{difficulty}
</if>
<if test="questionType != null and questionType != ''">
<if test="withoutQuestionIds != null and withoutQuestionIds.size > 0">
AND
t1.question_type = #{questionType}
</if>
<if test="customQuestionTypes != null and customQuestionTypes.size > 0">
AND
<foreach collection="customQuestionTypes" index="index" open="(" separator="OR" close=")">
t1.custom_question_type LIKE CONCAT('%', #{customQuestionTypes[${index}]}, '%')
t1.question_id NOT IN
<foreach collection="withoutQuestionIds" index="index" open="(" separator="," close=")">
#{withoutQuestionIds[${index}]}
</foreach>
</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>
<!-- 试题管理统计 -->
@ -310,8 +315,6 @@
<select id="listPO" parameterType="map" resultMap="questionPO">
SELECT
t1.subject,
t1.question_type,
t1.custom_question_type,
t1.type,
t1.choice_type,
t1.parent_id,
@ -368,16 +371,20 @@
AND
t1.difficulty = #{difficulty}
</if>
<if test="questionType != null and questionType != ''">
<if test="questionTypeIds != null and questionTypeIds.size > 0">
AND
t1.question_type = #{questionType}
</if>
<if test="customQuestionTypes != null and customQuestionTypes.size > 0">
AND
<foreach collection="customQuestionTypes" index="index" open="(" separator="OR" close=")">
t1.custom_question_type LIKE CONCAT('%', #{customQuestionTypes[${index}]}, '%')
</foreach>
</if>
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>

View File

@ -11,7 +11,14 @@
<!-- 建表 -->
<update id="createTable">
CREATE TABLE IF NOT EXISTS `exam_question_options` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`question_options_id` char(36) NOT NULL COMMENT '主键',
`question_id` char(36) DEFAULT NULL COMMENT '试题',
`question_option` varchar(2) DEFAULT NULL COMMENT '标识',
`content` text COMMENT '内容',
PRIMARY KEY (`id`,`question_options_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
</update>
<!-- 新增试题选项 -->
@ -20,40 +27,15 @@
question_options_id,
question_id,
question_option,
content,
creator,
gmt_create,
modifier,
gmt_modified,
is_delete
content
) VALUES(
#{questionOptionsId},
#{questionId},
#{option},
#{content},
#{creator},
#{gmtCreate},
#{modifier},
#{gmtModified},
#{isDelete}
#{content}
)
</insert>
<!-- 删除试题选项 -->
<update id="remove" parameterType="map">
UPDATE
exam_question_options
SET
is_delete = 1,
modifier = #{modifier},
gmt_modified = #{gmtModified}
WHERE
question_options_id IN
<foreach collection="questionOptionsIds" index="index" open="(" separator="," close=")">
#{questionOptionsIds[${index}]}
</foreach>
</update>
<!-- 删除试题选项(物理) -->
<delete id="delete" parameterType="map">
DELETE FROM
@ -77,18 +59,17 @@
<update id="update" parameterType="map">
UPDATE
exam_question_options
SET
<if test="questionId != null and questionId != ''">
question_id = #{questionId},
</if>
<if test="option != null and option != ''">
question_option = #{option},
</if>
<if test="content != null and content != ''">
content = #{content},
</if>
modifier = #{modifier},
gmt_modified = #{gmtModified}
<set>
<if test="questionId != null and questionId != ''">
question_id = #{questionId},
</if>
<if test="option != null and option != ''">
question_option = #{option},
</if>
<if test="content != null and content != ''">
content = #{content},
</if>
</set>
WHERE
question_options_id = #{questionOptionsId}
</update>
@ -102,12 +83,11 @@
t1.question_options_id
FROM
exam_question_options t1
WHERE
t1.is_delete = 0
<where>
<if test="questionOptionsId != null and questionOptionsId != ''">
AND
t1.question_options_id = #{questionOptionsId}
</if>
</where>
</select>
<!-- 试题选项列表 -->
@ -119,17 +99,15 @@
t1.question_options_id
FROM
exam_question_options t1
WHERE
t1.is_delete = 0
<where>
<if test="questionId != null and questionId != ''">
t1.question_id = #{questionId}
</if>
<if test="keywords != null and keywords != ''">
AND (
t1.content LIKE CONCAT('%', #{keywords}, '%')
)
</if>
<if test="questionId != null and questionId != ''">
AND
t1.question_id = #{questionId}
</if>
<if test="startTime != null and startTime != ''">
AND
LEFT(t1.gmt_create, 10) <![CDATA[ >= ]]> #{startTime}
@ -152,6 +130,7 @@
#{questionIds[${index}]}
</foreach>
</if>
</where>
</select>
<!-- 试题选项统计 -->
@ -160,8 +139,6 @@
COUNT(*)
FROM
exam_question_options t1
WHERE
t1.is_delete = 0
</select>
</mapper>

View File

@ -47,7 +47,19 @@
<!-- 建表 -->
<update id="createTable">
CREATE TABLE IF NOT EXISTS `exam_question_type` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`question_type_id` char(36) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '主键',
`question_type_parent_id` char(36) CHARACTER SET utf8mb4 DEFAULT '0' COMMENT '上级ID',
`type_name` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '类型名称',
`type_summary` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '说明',
`creator` char(36) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '创建人',
`gmt_create` datetime DEFAULT NULL COMMENT '创建时间',
`modifier` char(36) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '修改人',
`gmt_modified` datetime DEFAULT NULL COMMENT '修改时间',
`is_delete` int(1) DEFAULT '0' COMMENT '是否删除',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='试题类型';
</update>
<!-- 新增试题类型 -->

View File

@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="ink.wgink.module.examine.dao.question.IQuestionTypeQuestionDao">
<resultMap id="questionTypeQuestionPO" type="ink.wgink.module.examine.pojo.pos.question.QuestionTypeQuestionPO">
<id column="id" property="id"/>
<result column="question_type_id" property="questionTypeId"/>
<result column="question_id" property="questionId"/>
</resultMap>
<!-- 建表 -->
<update id="createTable">
CREATE TABLE IF NOT EXISTS `exam_question_type_question` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`question_type_id` char(36) DEFAULT NULL,
`question_id` char(36) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='试题类型与试题绑定';
</update>
<!-- 新增 -->
<insert id="save" parameterType="map">
INSERT INTO exam_question_type_question(
question_type_id,
question_id
) VALUES(
#{questionTypeId},
#{questionId}
)
</insert>
<!-- 删除(物理) -->
<update id="delete" parameterType="map">
DELETE FROM
exam_question_type_question
WHERE
<if test="questionIds != null and questionIds != ''">
question_id IN
<foreach collection="questionIds" index="index" open="(" separator="," close=")">
#{questionIds[${index}]}
</foreach>
</if>
<if test="questionTypeIds != null and questionTypeIds != ''">
question_type_id IN
<foreach collection="questionTypeIds" index="index" open="(" separator="," close=")">
#{questionTypeIds[${index}]}
</foreach>
</if>
</update>
<!-- 试题类型ID列表 -->
<select id="listQuestionTypeId" parameterType="map" resultType="java.lang.String">
SELECT
question_type_id
FROM
exam_question_type_question
<where>
<if test="questionId != null and questionId != ''">
question_id = #{questionId}
</if>
<if test="questionIds != null and questionIds.size > 0">
AND
question_id IN
<foreach collection="questionIds" index="index" open="(" separator="," close=")">
#{questionIds[${index}]}
</foreach>
</if>
</where>
</select>
<!-- 试题类型列表 -->
<select id="listQuestionType" parameterType="map" resultMap="ink.wgink.module.examine.dao.question.IQuestionTypeDao.questionTypeDTO">
SELECT
t1.question_type_id,
t1.question_type_parent_id,
t1.type_name,
t1.type_summary
FROM
exam_question_type t1
WHERE
t1.is_delete = 0
AND
t1.question_type_id IN (
SELECT
question_type_id
FROM
exam_question_type_question
<where>
<if test="questionId != null and questionId != ''">
question_id = #{questionId}
</if>
<if test="questionIds != null and questionIds != ''">
AND
question_id IN
<foreach collection="questionIds" index="index" open="(" separator="," close=")">
#{questionIds[${index}]}
</foreach>
</if>
</where>
)
</select>
</mapper>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
!function(e){const t=e["zh-cn"]=e["zh-cn"]||{};t.dictionary=Object.assign(t.dictionary||{},{"%0 of %1":"第 %0 步,共 %1 步",Aquamarine:"海蓝色",Black:"黑色","Block quote":"块引用",Blue:"蓝色",Bold:"加粗","Break text":"","Bulleted List":"项目符号列表",Cancel:"取消","Cannot upload file:":"无法上传的文件:","Centered image":"图片居中","Change image text alternative":"更改图片替换文本","Choose heading":"标题类型",Column:"列","Could not insert image at the current position.":"无法在当前位置插入图片","Could not obtain resized image URL.":"无法获取重设大小的图片URL","Decrease indent":"减少缩进","Delete column":"删除本列","Delete row":"删除本行","Dim grey":"暗灰色",Downloadable:"可下载","Dropdown toolbar":"下拉工具栏","Edit block":"编辑框","Edit link":"修改链接","Editor toolbar":"编辑器工具栏","Enter image caption":"输入图片标题","Full size image":"图片通栏显示",Green:"绿色",Grey:"灰色","Header column":"标题列","Header row":"标题行",Heading:"标题","Heading 1":"标题 1","Heading 2":"标题 2","Heading 3":"标题 3","Heading 4":"标题 4","Heading 5":"标题 5","Heading 6":"标题 6","Image toolbar":"图片工具栏","image widget":"图像小部件","In line":"","Increase indent":"增加缩进","Insert column left":"左侧插入列","Insert column right":"右侧插入列","Insert image":"插入图像","Insert image or file":"插入图片或文件","Insert media":"插入媒体","Insert paragraph after block":"在后面插入段落","Insert paragraph before block":"在前面插入段落","Insert row above":"在上面插入一行","Insert row below":"在下面插入一行","Insert table":"插入表格","Inserting image failed":"插入图片失败",Italic:"倾斜","Left aligned image":"图片左侧对齐","Light blue":"浅蓝色","Light green":"浅绿色","Light grey":"浅灰色",Link:"超链接","Link URL":"链接网址","Media URL":"媒体URL","media widget":"媒体小部件","Merge cell down":"向下合并单元格","Merge cell left":"向左合并单元格","Merge cell right":"向右合并单元格","Merge cell up":"向上合并单元格","Merge cells":"合并单元格",Next:"下一步","Numbered List":"项目编号列表","Open in a new tab":"在新标签页中打开","Open link in new tab":"在新标签页中打开链接",Orange:"橙色",Paragraph:"段落","Paste the media URL in the input.":"在输入中粘贴媒体URL",Previous:"上一步",Purple:"紫色",Red:"红色",Redo:"重做","Rich Text Editor":"富文本编辑器","Rich Text Editor, %0":"富文本编辑器, %0","Right aligned image":"图片右侧对齐",Row:"行",Save:"保存","Select all":"全选","Select column":"选择列","Select row":"选择行","Selecting resized image failed":"选择重设大小的图片失败","Show more items":"显示更多","Side image":"图片侧边显示","Split cell horizontally":"横向拆分单元格","Split cell vertically":"纵向拆分单元格","Table toolbar":"表格工具栏","Text alternative":"替换文本","The URL must not be empty.":"URL不可以为空。","This link has no URL":"此链接没有设置网址","This media URL is not supported.":"不支持此媒体URL。","Tip: Paste the URL into the content to embed faster.":"提示将URL粘贴到内容中可更快地嵌入","Toggle caption off":"","Toggle caption on":"",Turquoise:"青色",Undo:"撤销",Unlink:"取消超链接","Upload failed":"上传失败","Upload in progress":"正在上传",White:"白色","Widget toolbar":"小部件工具栏","Wrap text":"",Yellow:"黄色"}),t.getPluralForm=function(e){return 0}}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -24,7 +24,7 @@
<div class="layui-card">
<div class="layui-card-header"><b>选项</b></div>
<div class="layui-card-body options">
{{# for(var i = 0, item; item = d.questionOptions[i++];) { }}
{{# for(var i = 0, item; item = d.options[i++];) { }}
<div><b>{{item.option}}.</b> <span>{{item.content}}</span></div>
{{# } }}
</div>
@ -69,7 +69,7 @@
// 初始化内容
function initData() {
var loadLayerIndex;
top.restAjax.get(top.restAjax.path('api/question/getquestionbyid/{questionId}', [questionId]), {}, null, function(code, data) {
top.restAjax.get(top.restAjax.path('api/question/get/{questionId}', [questionId]), {}, null, function(code, data) {
data.answerArray = data.answer.split('$_WenG_$');
laytpl(document.getElementById('questionTemplate').innerHTML).render(data, function(html) {
document.getElementById('questionTemplateBox').innerHTML = html;

View File

@ -20,12 +20,6 @@
<div class="layui-inline">
<input type="text" id="keywords" class="layui-input search-item search-item-width-100" placeholder="输入关键字">
</div>
<div class="layui-inline">
<input type="text" id="startTime" class="layui-input search-item search-item-width-100" placeholder="开始时间" readonly>
</div>
<div class="layui-inline">
<input type="text" id="endTime" class="layui-input search-item search-item-width-100" placeholder="结束时间" readonly>
</div>
<div class="layui-inline layui-form search-item">
<select id="type" name="type" lay-filter="typeFilter">
<option value="">选择类型</option>
@ -52,38 +46,13 @@
<option value="5">⭐⭐⭐⭐⭐</option>
</select>
</div>
</div>
<div style="margin-bottom: 10px;">
<div class="layui-inline layui-form search-item search-item-width-100">
<div class="layui-form" id="questionTypeSelectTemplateBox" lay-filter="questionTypeSelectTemplateBox"></div>
<script id="questionTypeSelectTemplate" type="text/html">
<select id="questionType" name="questionType" lay-filter="questionType">
<option value="">选择试题类型</option>
{{# for(var i = 0, item; item = d[i++];) { }}
<option value="{{item.dataId}}">{{item.dataName}}</option>
{{# } }}
</select>
</script>
</div>
<div class="layui-inline">
<input type="hidden" id="customQuestionType" readonly style="cursor: pointer;">
<input type="text" id="customQuestionTypeName" class="layui-input search-item search-item-width-100" placeholder="自定义类型" readonly style="cursor: pointer;">
</div>
<div class="layui-btn-group">
<button type="button" id="search" class="layui-btn layui-btn-sm">
<i class="fa fa-lg fa-search"></i> 搜索
</button>
<button type="button" class="layui-btn layui-btn-sm" id="uploadExcel">
<i class="fa fa-lg fa-cloud-upload"></i> 导入数据
</button>
</div>
<div class="layui-inline layui-form search-item">
<select id="usedStatus" name="usedStatus" lay-filter="usedStatusFilter">
<option value="">筛选列表</option>
<option value="used">已使用</option>
<option value="unUsed">未使用</option>
</select>
<input type="hidden" id="questionType" readonly style="cursor: pointer;">
<input type="text" id="questionTypeName" class="layui-input search-item search-item-width-100" placeholder="试题类型" readonly style="cursor: pointer;">
</div>
<button type="button" id="search" class="layui-btn layui-btn-sm">
<i class="fa fa-lg fa-search"></i> 搜索
</button>
</div>
<table class="layui-hide" id="dataTable" lay-filter="dataTable"></table>
<!-- 表头按钮组 -->
@ -99,7 +68,6 @@
<i class="fa fa-lg fa-trash"></i> 删除
</button>
</div>
</script>
</div>
</div>
@ -123,7 +91,7 @@
var common = layui.common;
var form = layui.form;
var resizeTimeout = null;
var tableUrl = 'api/question/listpagequestion';
var tableUrl = 'api/question/listpage';
function getDifficulty(num) {
var result = '';
@ -133,19 +101,6 @@
return result;
}
// 初始化试题类型下拉选择
function initQuestionTypeSelect() {
top.restAjax.get(top.restAjax.path('api/data/listbyparentid/a7d1ab3d-fbd2-48ca-bfb8-353cad9f3eba', []), {}, null, function(code, data, args) {
laytpl(document.getElementById('questionTypeSelectTemplate').innerHTML).render(data, function(html) {
document.getElementById('questionTypeSelectTemplateBox').innerHTML = html;
});
form.render('select', 'questionTypeSelectTemplateBox');
}, function(code, data) {
top.dialog.msg(data.msg);
});
}
initQuestionTypeSelect();
// 初始化表格
function initTable() {
table.render({
@ -153,7 +108,7 @@
id: 'dataTable',
url: top.restAjax.path(tableUrl, []),
width: admin.screen() > 1 ? '100%' : '',
height: $win.height() - 130,
height: $win.height() - 90,
limit: 20,
limits: [20, 40, 60, 80, 100, 200],
toolbar: '#headerToolBar',
@ -183,15 +138,6 @@
return rowData;
}
},
{field: 'customQuestionTypeName', 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',
templet: function(row) {
var rowData = row[this.field];
@ -254,19 +200,6 @@
return rowData;
}
},
{field: 'used', width: 100, title: '使用状态', align:'center', fixed: 'right',
templet: function(row) {
var rowData = row[this.field];
if(typeof(rowData) === 'undefined' || rowData == null) {
return '-';
}
if(rowData) {
// return '<button class="layui-btn layui-btn layui-btn-sm layui-btn-normal" lay-event="examinationPagerEvent">查看试卷</button>';
return '已使用';
}
return '未使用';
}
},
{field: 'getQuestion', width: 100, title: '详情', fixed: 'right', align:'center', exportType: 'text',
templet: function(row) {
return '<button class="layui-btn layui-btn layui-btn-sm layui-btn-normal" lay-event="getQuestionEvent"><i class="fa fa-search"></i> 查看</button>';
@ -307,18 +240,14 @@
url: top.restAjax.path(tableUrl, []),
where: {
keywords: $('#keywords').val(),
startTime: $('#startTime').val(),
endTime: $('#endTime').val(),
type: $('#type').val(),
choiceType: $('#choiceType').val(),
questionType: $('#questionType').val(),
customQuestionType: $('#customQuestionType').val(),
difficulty: $('#difficulty').val()
},
page: {
curr: currentPage
},
height: $win.height() - 130,
});
}
// 初始化日期
@ -342,7 +271,7 @@
yes: function (index) {
top.dialog.close(index);
var layIndex;
top.restAjax.delete(top.restAjax.path('api/question/removequestion/{ids}', [ids]), {}, null, function (code, data) {
top.restAjax.delete(top.restAjax.path('api/question/remove/{ids}', [ids]), {}, null, function (code, data) {
top.dialog.msg(top.dataMessage.deleteSuccess, {time: 1000});
reloadTable();
}, function (code, data) {
@ -368,17 +297,6 @@
$(document).on('click', '#search', function() {
reloadTable(1);
});
$(document).on('click', '#uploadExcel', function() {
top.dialog.open({
url: top.restAjax.path('route/question/upload/upload-excel', []),
title: '导入试题数据',
width: '300px',
height: '196px',
onClose: function() {
reloadTable();
}
});
});
// 事件 - 增删改
table.on('toolbar(dataTable)', function(obj) {
var layEvent = obj.event;
@ -392,7 +310,7 @@
area: ['100%', '100%'],
shadeClose: true,
anim: 2,
content: top.restAjax.path('route/question/save-question.html', []),
content: top.restAjax.path('route/question/save', []),
end: function() {
reloadTable();
}
@ -410,7 +328,7 @@
area: ['100%', '100%'],
shadeClose: true,
anim: 2,
content: top.restAjax.path('route/question/update-question.html?questionId={questionId}', [checkDatas[0].questionId]),
content: top.restAjax.path('route/question/update?questionId={questionId}', [checkDatas[0].questionId]),
end: function() {
reloadTable();
}
@ -437,7 +355,7 @@
var event = obj.event;
if(event === 'getQuestionEvent') {
top.dialog.open({
url: top.restAjax.path('route/question/get-question.html?questionId={questionId}', [data.questionId]),
url: top.restAjax.path('route/question/get?questionId={questionId}', [data.questionId]),
title: '查看试题,难度:' + getDifficulty(data.difficulty),
width: '500px',
height: '80%',
@ -446,7 +364,7 @@
});
} else if(event === 'examinationPagerEvent') {
top.dialog.open({
url: top.restAjax.path('route/question/get-question.html?questionId={questionId}', [data.questionId]),
url: top.restAjax.path('route/question/get?questionId={questionId}', [data.questionId]),
title: '查看试卷',
width: '500px',
height: '80%',
@ -466,30 +384,30 @@
}
});
$('#customQuestionTypeName').on('click', function() {
$('#questionTypeName').on('click', function() {
top.dialog.open({
url: top.restAjax.path('route/questiontype/list-tree-select.html?questionTypeIds={questionTypeIds}', [$('#customQuestionType').val()]),
url: top.restAjax.path('route/question-type/list-tree-select?questionTypeIds={questionTypeIds}', [$('#questionType').val()]),
title: '选择自定义类型',
width: '200px',
height: '400px',
onClose: function() {
var selectedNodes = top.dialog.dialogData.selectedNodes;
if(selectedNodes.length > 0) {
var customQuestionType = '';
var customQuestionTypeName = '';
var questionType = '';
var questionTypeName = '';
for(var i = 0, item; item = selectedNodes[i++];) {
if(customQuestionType.length > 0) {
customQuestionType += ',';
customQuestionTypeName += ',';
if(questionType.length > 0) {
questionType += ',';
questionTypeName += ',';
}
customQuestionType += item.id;
customQuestionTypeName += item.name;
questionType += item.id;
questionTypeName += item.name;
}
$('#customQuestionType').val(customQuestionType);
$('#customQuestionTypeName').val(customQuestionTypeName);
$('#questionType').val(questionType);
$('#questionTypeName').val(questionTypeName);
} else {
$('#customQuestionType').val('');
$('#customQuestionTypeName').val('');
$('#questionType').val('');
$('#questionTypeName').val('');
}
}
});

View File

@ -35,22 +35,11 @@
<div id="subject"></div>
</div>
</div>
<div class="layui-form-item" pane>
<div class="layui-form-item">
<label class="layui-form-label">试题类型</label>
<div class="layui-input-block">
<div class="layui-form" id="questionTypeCheckboxTemplateBox" lay-filter="questionTypeCheckboxTemplateBox" style="display: inline-block;"></div>
</div>
<script id="questionTypeCheckboxTemplate" type="text/html">
{{# for(var i = 0, item; item = d[i++];) { }}
<input type="checkbox" name="questionType[{{item.dataId}}]" value="{{item.dataId}}" title="{{item.dataName}}">
{{# } }}
</script>
</div>
<div class="layui-form-item">
<label class="layui-form-label">自定义类型</label>
<div class="layui-input-block">
<input type="hidden" id="customQuestionType" name="customQuestionType" class="layui-input">
<input type="text" id="customQuestionTypeName" name="customQuestionTypeName" class="layui-input" placeholder="请选择自定义试题类型" readonly style="cursor: pointer">
<input type="hidden" id="questionType" name="questionType" class="layui-input">
<input type="text" id="questionTypeName" name="questionTypeName" class="layui-input" placeholder="请选择试题类型" readonly style="cursor: pointer">
</div>
</div>
<div class="layui-form-item" pane>
@ -515,12 +504,12 @@
top.dialog.confirm(top.dataMessage.commit, function(index) {
top.dialog.close(index);
var loadLayerIndex;
formData.field['questionType'] = top.restAjax.checkBoxToString(formData.field, 'questionType');
formData.field['subject'] = wangEditorObj['subject'].txt.html();
formData.field['analysis'] = wangEditorObj['analysis'].txt.html();
formData.field['questionOptions'] = choiceOption.optionArray;
top.restAjax.post(top.restAjax.path('api/question/savequestion', []), formData.field, null, function(code, data) {
formData.field['options'] = choiceOption.optionArray;
top.restAjax.post(top.restAjax.path('api/question/save', []), formData.field, null, function(code, data) {
var layerIndex = top.dialog.msg(top.dataMessage.commitSuccess, {
time: 0,
btn: [top.dataMessage.button.yes, top.dataMessage.button.no],
@ -544,23 +533,10 @@
return false;
});
// 初始化知识点复选
function initQuestionTypeCheckbox() {
top.restAjax.get(top.restAjax.path('api/data/listbyparentid/a7d1ab3d-fbd2-48ca-bfb8-353cad9f3eba', []), {}, null, function(code, data, args) {
laytpl(document.getElementById('questionTypeCheckboxTemplate').innerHTML).render(data, function(html) {
document.getElementById('questionTypeCheckboxTemplateBox').innerHTML = html;
});
form.render('checkbox', 'questionTypeCheckboxTemplateBox');
}, function(code, data) {
top.dialog.msg(data.msg);
});
}
// 初始化内容
function initData() {
initSubjectRichText();
initAnalysisRichText();
initQuestionTypeCheckbox();
}
initData();
// 单选事件
@ -586,30 +562,30 @@
}
});
$('#customQuestionTypeName').on('click', function() {
$('#questionTypeName').on('click', function() {
top.dialog.open({
url: top.restAjax.path('route/questiontype/list-tree-select-edit.html?questionTypeIds={questionTypeIds}', [$('#customQuestionType').val()]),
url: top.restAjax.path('route/question-type/list-tree-select-edit?questionTypeIds={questionTypeIds}', [$('#questionType').val()]),
title: '选择自定义类型',
width: '200px',
height: '400px',
onClose: function() {
var selectedNodes = top.dialog.dialogData.selectedNodes;
if(selectedNodes.length > 0) {
var customQuestionType = '';
var customQuestionTypeName = '';
var questionType = '';
var questionTypeName = '';
for(var i = 0, item; item = selectedNodes[i++];) {
if(customQuestionType.length > 0) {
customQuestionType += ',';
customQuestionTypeName += ',';
if(questionType.length > 0) {
questionType += ',';
questionTypeName += ',';
}
customQuestionType += item.id;
customQuestionTypeName += item.name;
questionType += item.id;
questionTypeName += item.name;
}
$('#customQuestionType').val(customQuestionType);
$('#customQuestionTypeName').val(customQuestionTypeName);
$('#questionType').val(questionType);
$('#questionTypeName').val(questionTypeName);
} else {
$('#customQuestionType').val('');
$('#customQuestionTypeName').val('');
$('#questionType').val('');
$('#questionTypeName').val('');
}
}
});

View File

@ -71,7 +71,7 @@
enable: true,
autoLoad: false,
type: 'get',
url: top.restAjax.path('api/questiontype/listztree', []),
url: top.restAjax.path('api/question-type/list-ztree', []),
autoParam: ['id'],
otherParam: {},
dataFilter: function (treeId, parentNode, childNodes) {
@ -108,7 +108,7 @@
if(!questionTypeIds) {
return;
}
top.restAjax.get(top.restAjax.path('api/questiontype/list/{questionTypeIds}', [questionTypeIds]), {}, null, function(code, data) {
top.restAjax.get(top.restAjax.path('api/question-type/list/{questionTypeIds}', [questionTypeIds]), {}, null, function(code, data) {
for(var i = 0, item; item = data[i++];) {
selectedNodesMap[item.questionTypeId] = {
id: item.questionTypeId,
@ -165,7 +165,7 @@
$(document).on('click', '#questionTypeListBtn', function() {
top.dialog.open({
url: top.restAjax.path('route/questiontype/list-tree.html', []),
url: top.restAjax.path('route/question-type/list-tree', []),
title: '编辑自定义类型',
width: '95%',
height: '95%',

View File

@ -59,7 +59,7 @@
enable: true,
autoLoad: false,
type: 'get',
url: top.restAjax.path('api/questiontype/listztree', []),
url: top.restAjax.path('api/question-type/list-ztree', []),
autoParam: ['id'],
otherParam: {},
dataFilter: function (treeId, parentNode, childNodes) {
@ -96,7 +96,7 @@
if(!questionTypeIds) {
return;
}
top.restAjax.get(top.restAjax.path('api/questiontype/list/{questionTypeIds}', [questionTypeIds]), {}, null, function(code, data) {
top.restAjax.get(top.restAjax.path('api/question-type/list/{questionTypeIds}', [questionTypeIds]), {}, null, function(code, data) {
for(var i = 0, item; item = data[i++];) {
selectedNodesMap[item.questionTypeId] = {
id: item.questionTypeId,

View File

@ -15,7 +15,7 @@
<body>
<div class="layui-fluid layui-anim layui-anim-fadein">
<div class="layui-row layui-col-space15">
<div class="layui-col-md2 layui-col-sm2 layui-col-xs2">
<div class="layui-col-md2 layui-col-sm2 layui-col-xs2" style="padding-right: 0px">
<div class="layui-card">
<div class="layui-card-body left-tree-wrap">
<div id="leftTreeWrap">
@ -24,7 +24,7 @@
</div>
</div>
</div>
<div class="layui-col-md10 layui-col-sm10 layui-col-xs10">
<div class="layui-col-md10 layui-col-sm10 layui-col-xs10" style="padding-left: 0px">
<div class="layui-card">
<div id="listContentWrap" class="layui-card-body">
<iframe id="listContent" frameborder="0" class="layadmin-iframe"></iframe>
@ -49,7 +49,7 @@
// 初始化IFrame
function initIFrame() {
$('#listContent').attr('src', top.restAjax.path('route/questiontype/list.html?parentId={parentId}', [parentId]));
$('#listContent').attr('src', top.restAjax.path('route/question-type/list?parentId={parentId}', [parentId]));
}
// 初始化大小
function initSize() {
@ -68,7 +68,7 @@
enable: true,
autoLoad: false,
type: 'get',
url: top.restAjax.path('api/questiontype/listztree', []),
url: top.restAjax.path('api/question-type/list-ztree', []),
autoParam: ['id'],
otherParam: {},
dataFilter: function (treeId, parentNode, childNodes) {

View File

@ -69,7 +69,7 @@
var common = layui.common;
var resizeTimeout = null;
var questionTypeParentId = top.restAjax.params(window.location.href).parentId;
var tableUrl = 'api/questiontype/listpage/{parentId}';
var tableUrl = 'api/question-type/listpage/{parentId}';
// 初始化表格
function initTable() {
@ -175,7 +175,7 @@
yes: function (index) {
top.dialog.close(index);
var layIndex;
top.restAjax.delete(top.restAjax.path('api/questiontype/remove/{ids}', [ids]), {}, null, function (code, data) {
top.restAjax.delete(top.restAjax.path('api/question-type/remove/{ids}', [ids]), {}, null, function (code, data) {
top.dialog.msg(top.dataMessage.deleteSuccess, {time: 1000});
refreshTable();
}, function (code, data) {
@ -202,7 +202,6 @@
reloadTable(1);
});
function refreshTable() {
parent.common.refreshTree('leftTree');
reloadTable();
}
// 事件 - 增删改
@ -218,7 +217,7 @@
area: ['100%', '100%'],
shadeClose: true,
anim: 2,
content: top.restAjax.path('route/questiontype/save.html?questionTypeParentId={questionTypeParentId}', [questionTypeParentId]),
content: top.restAjax.path('route/question-type/save?questionTypeParentId={questionTypeParentId}', [questionTypeParentId]),
end: function() {
refreshTable();
}
@ -236,7 +235,7 @@
area: ['100%', '100%'],
shadeClose: true,
anim: 2,
content: top.restAjax.path('route/questiontype/update.html?questionTypeId={questionTypeId}', [checkDatas[0].questionTypeId]),
content: top.restAjax.path('route/question-type/update?questionTypeId={questionTypeId}', [checkDatas[0].questionTypeId]),
end: function() {
refreshTable();
}
@ -263,7 +262,7 @@
area: ['100%', '100%'],
shadeClose: true,
anim: 2,
content: top.restAjax.path('route/questiontype/save-batch.html?questionTypeParentId={questionTypeParentId}', [questionTypeParentId]),
content: top.restAjax.path('route/question-type/save-batch?questionTypeParentId={questionTypeParentId}', [questionTypeParentId]),
end: function() {
refreshTable();
}

View File

@ -9,7 +9,6 @@
<link rel="stylesheet" href="assets/fonts/font-awesome/css/font-awesome.css"/>
<link rel="stylesheet" href="assets/layuiadmin/layui/css/layui.css" media="all">
<link rel="stylesheet" href="assets/layuiadmin/style/admin.css" media="all">
<link rel="stylesheet" type="text/css" href="assets/js/vendor/viewer/viewer.min.css">
</head>
<body>
<div class="layui-anim layui-anim-fadein">
@ -53,9 +52,6 @@
</div>
</div>
</div>
<script src="assets/js/vendor/wangEditor/wangEditor.min.js"></script>
<script src="assets/js/vendor/ckplayer/ckplayer/ckplayer.js"></script>
<script src="assets/js/vendor/viewer/viewer.min.js"></script>
<script src="assets/layuiadmin/layui/layui.js"></script>
<script>
layui.config({
@ -86,7 +82,7 @@
return;
}
var loadLayerIndex;
top.restAjax.get(top.restAjax.path('api/questiontype/get/{parentId}', [questionTypeParentId]), {}, null, function(code, data) {
top.restAjax.get(top.restAjax.path('api/question-type/get/{parentId}', [questionTypeParentId]), {}, null, function(code, data) {
form.val('dataForm', {
questionTypeParentName: data.typeName
});
@ -106,7 +102,7 @@
top.dialog.confirm(top.dataMessage.commit, function(index) {
top.dialog.close(index);
var loadLayerIndex;
top.restAjax.post(top.restAjax.path('api/questiontype/save', []), formData.field, null, function(code, data) {
top.restAjax.post(top.restAjax.path('api/question-type/save', []), formData.field, null, function(code, data) {
parent.parent.common.refreshTree('leftTree');
var layerIndex = top.dialog.msg(top.dataMessage.commitSuccess, {
time: 0,

View File

@ -9,7 +9,6 @@
<link rel="stylesheet" href="assets/fonts/font-awesome/css/font-awesome.css"/>
<link rel="stylesheet" href="assets/layuiadmin/layui/css/layui.css" media="all">
<link rel="stylesheet" href="assets/layuiadmin/style/admin.css" media="all">
<link rel="stylesheet" type="text/css" href="assets/js/vendor/viewer/viewer.min.css">
</head>
<body>
<div class="layui-anim layui-anim-fadein">
@ -53,9 +52,6 @@
</div>
</div>
</div>
<script src="assets/js/vendor/wangEditor/wangEditor.min.js"></script>
<script src="assets/js/vendor/ckplayer/ckplayer/ckplayer.js"></script>
<script src="assets/js/vendor/viewer/viewer.min.js"></script>
<script src="assets/layuiadmin/layui/layui.js"></script>
<script>
layui.config({
@ -69,73 +65,19 @@
var laydate = layui.laydate;
var questionTypeId = top.restAjax.params(window.location.href).questionTypeId;
var wangEditor = window.wangEditor;
var wangEditorObj = {};
var viewerObj = {};
function closeBox() {
parent.layer.close(parent.layer.getFrameIndex(window.name));
}
function refreshDownloadTemplet(fileName, file) {
var dataRander = {};
dataRander[fileName] = file;
laytpl(document.getElementById(fileName +'FileDownload').innerHTML).render(dataRander, function(html) {
document.getElementById(fileName +'FileBox').innerHTML = html;
});
}
// 初始化文件列表
function initFileList(fileName, ids, callback) {
var dataForm = {};
dataForm[fileName] = ids;
form.val('dataForm', dataForm);
if(!ids) {
refreshDownloadTemplet(fileName, []);
if(callback) {
callback(fileName, []);
}
return;
}
top.restAjax.get(top.restAjax.path('api/file/list', []), {
ids: ids
}, null, function(code, data) {
refreshDownloadTemplet(fileName, data);
if(callback) {
callback(fileName, data);
}
}, function(code, data) {
top.dialog.msg(data.msg);
});
}
// 初始化视频
function initVideo(fileName, data) {
for(var i = 0, item; item = data[i++];) {
var player = new ckplayer({
container: '#'+ fileName + i,
variable: 'player',
flashplayer: false,
video: {
file: 'route/file/download/true/'+ item.fileId,
type: 'video/mp4'
}
});
}
}
// 初始化内容
function initData() {
var loadLayerIndex;
top.restAjax.get(top.restAjax.path('api/questiontype/get/{questionTypeId}', [questionTypeId]), {}, null, function(code, data) {
top.restAjax.get(top.restAjax.path('api/question-type/get/{questionTypeId}', [questionTypeId]), {}, null, function(code, data) {
var dataFormData = {};
for(var i in data) {
dataFormData[i] = data[i] +'';
}
dataFormData.questionTypeParentName = data.questionTypeParentName == '' ? '根节点' : data.questionTypeParentName;
form.val('dataForm', dataFormData);
form.render(null, 'dataForm');
}, function(code, data) {
@ -153,7 +95,8 @@
top.dialog.confirm(top.dataMessage.commit, function(index) {
top.dialog.close(index);
var loadLayerIndex;
top.restAjax.put(top.restAjax.path('api/questiontype/update/{questionTypeId}', [questionTypeId]), formData.field, null, function(code, data) {
top.restAjax.put(top.restAjax.path('api/question-type/update/{questionTypeId}', [questionTypeId]), formData.field, null, function(code, data) {
parent.parent.common.refreshTree('leftTree');
var layerIndex = top.dialog.msg(top.dataMessage.updateSuccess, {
time: 0,
btn: [top.dataMessage.button.yes, top.dataMessage.button.no],

View File

@ -35,22 +35,11 @@
<div id="subject"></div>
</div>
</div>
<div class="layui-form-item" pane>
<label class="layui-form-label">课程类型</label>
<div class="layui-input-block">
<div class="layui-form" id="questionTypeCheckboxTemplateBox" lay-filter="questionTypeCheckboxTemplateBox" style="display: inline-block;"></div>
</div>
<script id="questionTypeCheckboxTemplate" type="text/html">
{{# for(var i = 0, item; item = d[i++];) { }}
<input type="checkbox" name="questionType[{{item.dataId}}]" value="{{item.dataId}}" title="{{item.dataName}}">
{{# } }}
</script>
</div>
<div class="layui-form-item">
<label class="layui-form-label">自定义类型</label>
<label class="layui-form-label">试题类型</label>
<div class="layui-input-block">
<input type="hidden" id="customQuestionType" name="customQuestionType" class="layui-input">
<input type="text" id="customQuestionTypeName" name="customQuestionTypeName" class="layui-input" placeholder="请选择自定义试题类型" readonly style="cursor: pointer">
<input type="hidden" id="questionType" name="questionType" class="layui-input">
<input type="text" id="questionTypeName" name="questionTypeName" class="layui-input" placeholder="请选择试题类型" readonly style="cursor: pointer">
</div>
</div>
<div class="layui-form-item" pane>
@ -374,10 +363,10 @@
}
}
function refreshOptionTemplate(data) {
laytpl(document.getElementById('optionTemplate').innerHTML).render(choiceOption, function(html) {
laytpl(document.getElementById('optionTemplate').innerHTML).render(data, function(html) {
document.getElementById('optionTemplateBox').innerHTML = html;
setQuestionOptionAnswer();
if(choiceOption.choiceType === 'multiple') {
if(data.choiceType === 'multiple') {
form.render('checkbox');
} else {
form.render('radio');
@ -426,16 +415,18 @@
refreshOptionTemplate(choiceOption);
});
// 刷新类型
function refreshType(choice) {
function refreshType(isInit) {
if(type === 'choice') {
$('#choiceTypeBox').show();
$('#optionBox').show();
$('#answerBox').hide();
$('#fillInTheBlanksAnswerBox').hide();
setQuestionOptionContent();
if(!isInit) {
setQuestionOptionContent();
}
refreshOptionTemplate(choiceOption);
} else if(type === 'tureOrFalse') {
choiceOption.choiceType = choice ? choice : 'single';
choiceOption.choiceType = 'single';
form.val('dataForm', {
choiceType: 'single'
});
@ -446,14 +437,18 @@
if(choiceOption.optionArray.length > 2) {
choiceOption.optionArray.splice(2, choiceOption.optionArray.length - 2);
}
setQuestionOptionContent();
if(!isInit) {
setQuestionOptionContent();
}
refreshOptionTemplate(choiceOption);
} else if(type === 'fillInTheBlanks') {
$('#choiceTypeBox').hide();
$('#optionBox').hide();
$('#answerBox').hide()
$('#fillInTheBlanksAnswerBox').show();
setFillInTheBlanksAnswerContent();
if(!isInit) {
setFillInTheBlanksAnswerContent();
}
refreshFillInTheBlanks();
} else if(type === 'answer') {
$('#choiceTypeBox').hide();
@ -533,11 +528,10 @@
top.dialog.confirm(top.dataMessage.commit, function(index) {
top.dialog.close(index);
var loadLayerIndex;
formData.field['questionType'] = top.restAjax.checkBoxToString(formData.field, 'questionType');
formData.field['subject'] = wangEditorObj['subject'].txt.html();
formData.field['analysis'] = wangEditorObj['analysis'].txt.html();
formData.field['questionOptions'] = choiceOption.optionArray;
top.restAjax.put(top.restAjax.path('api/question/updatequestion/{questionId}', [questionId]), formData.field, null, function(code, data) {
formData.field['options'] = choiceOption.optionArray;
top.restAjax.put(top.restAjax.path('api/question/update/{questionId}', [questionId]), formData.field, null, function(code, data) {
var layerIndex = top.dialog.msg(top.dataMessage.updateSuccess, {
time: 0,
btn: [top.dataMessage.button.yes, top.dataMessage.button.no],
@ -561,42 +555,20 @@
return false;
});
// 初始化知识点复选
function initQuestionTypeCheckbox(selectValues) {
top.restAjax.get(top.restAjax.path('api/data/listbyparentid/a7d1ab3d-fbd2-48ca-bfb8-353cad9f3eba', []), {}, null, function(code, data, args) {
laytpl(document.getElementById('questionTypeCheckboxTemplate').innerHTML).render(data, function(html) {
document.getElementById('questionTypeCheckboxTemplateBox').innerHTML = html;
});
form.render('checkbox', 'questionTypeCheckboxTemplateBox');
if(!selectValues) {
return;
}
var checkboxValue = selectValues.split(',');
var checkboxObj = {};
for(var j = 0, checkbox = checkboxValue[j]; checkbox = checkboxValue[j++];) {
checkboxObj['questionType['+ checkbox +']'] = true;
}
form.val('dataForm', checkboxObj);
}, function(code, data) {
top.dialog.msg(data.msg);
});
}
// 初始化内容
function initData() {
var loadLayerIndex;
top.restAjax.get(top.restAjax.path('api/question/getquestionbyid/{questionId}', [questionId]), {}, null, function(code, data) {
top.restAjax.get(top.restAjax.path('api/question/get/{questionId}', [questionId]), {}, null, function(code, data) {
var dataFormData = {};
for(var i in data) {
dataFormData[i] = data[i] +'';
}
initQuestionTypeCheckbox(data['questionType']);
initSubjectRichText(data['subject']);
initAnalysisRichText(data['analysis']);
type = data['type'];
choiceOption.choiceType = data['choiceType'];
if(type === 'choice') {
for(var i = 0, item; item = data['questionOptions'][i++];) {
if(type === 'choice' || type === 'tureOrFalse') {
for(var i = 0, item; item = data['options'][i++];) {
item.id = item.questionOptionsId;
choiceOption.optionArray.push(item)
}
@ -610,7 +582,7 @@
dataFormData['optionAnswer'] = data['answer'];
choiceOptionAnswer[0] = data['answer'];
}
refreshOptionTemplate(choiceOption);
// refreshOptionTemplate(choiceOption);
} else if(type === 'fillInTheBlanks') {
var optionAnswerArray = data['answer'].split(fillTag);
for(var i = 0, item; item = optionAnswerArray[i++];) {
@ -620,11 +592,12 @@
}
fillInBlanksAnswerArray.push(fillInBlanks);
}
refreshFillInTheBlanks();
// refreshFillInTheBlanks();
}
refreshType();
refreshType(true);
form.val('dataForm', dataFormData);
form.render(null, 'dataForm');
}, function(code, data) {
top.dialog.msg(data.msg);
}, function() {
@ -658,31 +631,32 @@
}
});
$('#customQuestionTypeName').on('click', function() {
$('#questionTypeName').on('click', function() {
top.dialog.open({
url: top.restAjax.path('route/questiontype/list-tree-select-edit.html?questionTypeIds={questionTypeIds}', [$('#customQuestionType').val()]),
url: top.restAjax.path('route/question-type/list-tree-select-edit?questionTypeIds={questionTypeIds}', [$('#questionType').val()]),
title: '选择自定义类型',
width: '200px',
height: '400px',
onClose: function() {
var selectedNodes = top.dialog.dialogData.selectedNodes;
if(selectedNodes.length > 0) {
var customQuestionType = '';
var customQuestionTypeName = '';
var questionType = '';
var questionTypeName = '';
for(var i = 0, item; item = selectedNodes[i++];) {
if(customQuestionType.length > 0) {
customQuestionType += ',';
customQuestionTypeName += ',';
if(questionType.length > 0) {
questionType += ',';
questionTypeName += ',';
}
customQuestionType += item.id;
customQuestionTypeName += item.name;
questionType += item.id;
questionTypeName += item.name;
}
$('#customQuestionType').val(customQuestionType);
$('#customQuestionTypeName').val(customQuestionTypeName);
$('#questionType').val(questionType);
$('#questionTypeName').val(questionTypeName);
} else {
$('#customQuestionType').val('');
$('#customQuestionTypeName').val('');
$('#questionType').val('');
$('#questionTypeName').val('');
}
console.log($('#questionType').val())
}
});
})