Browse Source

feat: update something

shc 1 năm trước cách đây
mục cha
commit
8a97102b34

+ 26 - 1
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/controller/WmDrugQuizController.java

@@ -1,16 +1,25 @@
 package com.qunzhixinxi.hnqz.admin.controller;
 package com.qunzhixinxi.hnqz.admin.controller;
 
 
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.qunzhixinxi.hnqz.admin.api.dto.WmQuizDTO;
 import com.qunzhixinxi.hnqz.admin.api.dto.WmQuizDTO;
+import com.qunzhixinxi.hnqz.admin.api.entity.WmDrugQuizRelation;
 import com.qunzhixinxi.hnqz.admin.service.WmDrugQuizRelationService;
 import com.qunzhixinxi.hnqz.admin.service.WmDrugQuizRelationService;
 import com.qunzhixinxi.hnqz.common.core.util.R;
 import com.qunzhixinxi.hnqz.common.core.util.R;
 import com.qunzhixinxi.hnqz.common.log.annotation.SysLog;
 import com.qunzhixinxi.hnqz.common.log.annotation.SysLog;
 import com.qunzhixinxi.hnqz.common.security.util.SecurityUtils;
 import com.qunzhixinxi.hnqz.common.security.util.SecurityUtils;
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.bind.annotation.RestController;
 
 
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
 /**
 /**
  * 药品试卷前端控制器
  * 药品试卷前端控制器
  *
  *
@@ -25,9 +34,25 @@ public class WmDrugQuizController {
 
 
     @SysLog("药品问卷绑定")
     @SysLog("药品问卷绑定")
     @PostMapping(value = "/drug/quiz/bind")
     @PostMapping(value = "/drug/quiz/bind")
-    private R<Boolean> bind(@Validated @RequestBody WmQuizDTO.OnDrugBind resource) {
+    public R<Boolean> bind(@Validated @RequestBody WmQuizDTO.OnDrugBind resource) {
         return R.ok(drugQuizRelationService.bind(resource, SecurityUtils.getUser()));
         return R.ok(drugQuizRelationService.bind(resource, SecurityUtils.getUser()));
     }
     }
 
 
 
 
+    @GetMapping(value = "/drug/quiz/list")
+    public R<List<Integer>> listDrugQuizzes(@RequestParam(value = "drugId") String drugId) {
+
+        List<WmDrugQuizRelation> relations = drugQuizRelationService.list(Wrappers.<WmDrugQuizRelation>lambdaQuery().eq(WmDrugQuizRelation::getDrugId, Integer.valueOf(drugId)));
+
+        if (CollUtil.isEmpty(relations)) {
+            return R.ok(Collections.emptyList());
+        }
+
+        List<Integer> collect = relations.stream().mapToInt(WmDrugQuizRelation::getQuizId).boxed().distinct().collect(Collectors.toList());
+
+        return R.ok(CollUtil.isEmpty(collect) ? Collections.emptyList() : collect);
+
+    }
+
+
 }
 }

+ 373 - 370
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/controller/WmQuizController.java

@@ -35,6 +35,7 @@ import javax.validation.Valid;
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 
 
@@ -50,375 +51,377 @@ import java.util.stream.Collectors;
 @AllArgsConstructor
 @AllArgsConstructor
 public class WmQuizController {
 public class WmQuizController {
 
 
-	private final SysUserService userService;
-	private final WmQuizService quizService;
-	private final WmQuizItemService quizItemService;
-	private final WmQuestionService questionService;
-	private final UpmsConfig upmsConfig;
-
-	// ~ QUIZ =========
-
-	/**
-	 * 获取试卷详情
-	 *
-	 * @param quizId 试卷ID
-	 * @return 详情信息
-	 */
-	@GetMapping(value = "/quiz/details")
-	public R<Map<String, Object>> getQuizDetails(@RequestParam(value = "quizId") Integer quizId) {
-
-		Map<String, Object> details = quizService.getDetails(quizId);
-
-		return R.ok(details);
-	}
-
-	/**
-	 * 获取试卷分页
-	 *
-	 * @param current    当前页
-	 * @param size       每页记录数
-	 * @param title      试卷标题
-	 * @param createTime 创建时间范围
-	 * @return 分页结果
-	 */
-	@GetMapping(value = "/quiz/page")
-	public R<Page<?>> pageQuizzes(@RequestParam(value = "current", defaultValue = "1") Integer current,
-								  @RequestParam(value = "size", defaultValue = "20") Integer size,
-								  @RequestParam(value = "title", required = false) String title,
-								  @RequestParam(value = "state", required = false) UpmsState.QuizState state,
-								  @RequestParam(value = "createTime", required = false) LocalDateTime[] createTime) {
-
-		LambdaQueryWrapper<WmQuiz> queryWrapper = Wrappers.<WmQuiz>lambdaQuery()
-				.like(StrUtil.isNotBlank(title), WmQuiz::getTitle, title)
-				.eq(state != null, WmQuiz::getState, state)
-				.eq(WmQuiz::getEnterpriseId, SecurityUtils.getUser().getDeptId())
-				.orderByDesc(WmQuiz::getCreateTime);
-
-		if (ArrayUtil.isNotEmpty(createTime)) {
-			LocalDateTime end;
-			if (createTime.length == 1) {
-				end = LocalDateTime.now();
-			} else {
-				end = createTime[1];
-			}
-			queryWrapper.between(WmQuiz::getCreateTime, createTime[0], end);
-		}
-
-
-		Page<WmQuiz> pages = quizService.page(new Page<>(current, size), queryWrapper);
-
-		return R.ok(pages);
-	}
-
-
-	/**
-	 * 获取可用的试卷
-	 *
-	 * @return 可用试卷列表
-	 */
-	@GetMapping(value = "/quiz/avail/list")
-	public R<List<WmQuiz>> listQuizzes() {
-
-		return R.ok(quizService.listEntQuizzes(SecurityUtils.getUser().getDeptId(), UpmsState.QuizState.RELEASE));
-	}
-
-	/**
-	 * 获取平台可用的试卷
-	 *
-	 * @return 可用试卷列表
-	 */
-	@GetMapping(value = "/quiz/plt/avail/list")
-	public R<List<WmQuiz>> listPltQuizzes() {
-
-		return R.ok(quizService.listEntQuizzes(upmsConfig.getPltEntId(), UpmsState.QuizState.RELEASE));
-	}
-
-	/**
-	 * 发布试卷
-	 *
-	 * @param resource 发布试卷
-	 * @return 发布结果
-	 */
-	@SysLog("发布试卷")
-	@PostMapping(value = "/quiz/state/release")
-	public R<Boolean> releaseQuiz(@Valid @RequestBody WmQuizDTO.OnQuizState resource) {
-
-		if (!UpmsState.QuizState.RELEASE.equals(resource.getState())) {
-			log.error("发布请求参数封装错误");
-			throw new BizException("发布请求参数封装错误");
-		}
-
-		Boolean succ = quizService.releaseQuiz(resource.getQuizId(), SecurityUtils.getUser());
-		return succ ? R.ok(true, "发布试卷成功") : R.failed(false, "发布试卷失败");
-	}
-
-	/**
-	 * 创建试卷
-	 *
-	 * @param resource 试卷信息
-	 * @return 创建结果
-	 */
-	@SysLog(value = "创建试卷")
-	@PostMapping(value = "/quiz/create")
-	public R<String> createQuiz(@Valid @RequestBody WmQuizDTO.OnQuizCreate resource) {
-		String sn = quizService.createQuiz(resource, SecurityUtils.getUser());
-		return StrUtil.isNotBlank(sn) ? R.ok(sn, "创建试卷成功") : R.failed("", "创建试卷失败");
-	}
-
-	/**
-	 * 更新试卷
-	 *
-	 * @param resource 试卷信息
-	 * @return 创建结果
-	 */
-	@SysLog("更新试卷")
-	@PostMapping(value = "/quiz/update")
-	public R<Boolean> updateQuiz(@Valid @RequestBody WmQuizDTO.OnQuizUpdate resource) {
-
-		WmQuiz.Expand expand = resource.getExpand();
-
-		if (expand != null) {
-			quizService.checkQuizExpand(expand, resource.getSn());
-		}
-
-
-		Boolean succ = quizService.updateQuiz(resource, SecurityUtils.getUser());
-
-		return succ ? R.ok(true, "更新试卷信息成功") : R.failed(false, "更新试卷信息失败");
-	}
-
-	/**
-	 * 中止试卷
-	 *
-	 * @param resource 试卷信息
-	 * @return 中止结果
-	 */
-	@SysLog("中止试卷")
-	@PostMapping(value = "/quiz/state/stop")
-	public R<Boolean> stopQuiz(@Valid @RequestBody WmQuizDTO.OnQuizState resource) {
-
-		if (!UpmsState.QuizState.STOP.equals(resource.getState())) {
-			log.error("中止请求参数封装错误");
-			throw new BizException("中止请求参数封装错误");
-		}
-
-		Boolean succ = quizService.stopQuiz(resource.getQuizId(), SecurityUtils.getUser());
-		return succ ? R.ok(true, "中止试卷成功") : R.failed(false, "中止试卷失败");
-
-	}
-
-
-	// ~ QUIZ ITEM =========
-
-	/**
-	 * 获取试卷项信息
-	 *
-	 * @param itemId 试卷项ID
-	 * @return 试卷项详情
-	 */
-	@GetMapping(value = "/quiz/item/details")
-	public R<WmQuizItem> getItemDetails(@RequestParam(value = "itemId") Integer itemId) {
-		WmQuizItem item = quizItemService.getItemDetails(itemId);
-		return R.ok(item);
-	}
-
-	/**
-	 * 获取试卷的试卷项列表
-	 *
-	 * @param sn 试卷编号
-	 * @return 试卷项链表
-	 */
-	@GetMapping(value = "/quiz/item/list")
-	public R<List<WmQuizItem>> listItems(@RequestParam(value = "quizSerialNum") String sn) {
-		List<WmQuizItem> items = quizItemService.listItems(sn);
-		return R.ok(items);
-	}
-
-	/**
-	 * 创建试卷项(添加试题)
-	 *
-	 * @param resource 试卷项信息
-	 * @return 创建结果
-	 */
-	@SysLog("创建试卷项(添加试题)")
-	@PostMapping(value = "/quiz/item/create")
-	public R<WmQuizItem> createQuizItem(@Valid @RequestBody WmQuizDTO.OnItemCreate resource) {
-
-		WmQuizItem item = quizItemService.createItem(resource, SecurityUtils.getUser());
-
-		return item != null ? R.ok(item, "添加试卷项成功") : R.failed(null, "添加试卷项失败");
-	}
-
-	/**
-	 * 批量创建试卷项(添加试题)
-	 *
-	 * @param resources 试卷项信息
-	 * @return 创建结果
-	 */
-	@SysLog("批量创建试卷项(添加试题)")
-	@PostMapping(value = "/quiz/item/batch/create")
-	public R<List<WmQuizItem>> createQuizItems(@Valid @RequestBody List<WmQuizDTO.OnItemCreate> resources) {
-
-		List<WmQuizItem> items = quizItemService.createItems(resources, SecurityUtils.getUser());
-
-		return CollUtil.isNotEmpty(items) ? R.ok(items, "批量添加试卷项成功") : R.failed(items, "批量添加试卷项失败");
-	}
-
-	/**
-	 * 更新试卷项
-	 *
-	 * @param resource 试卷项信息
-	 * @return 更新结果
-	 */
-	@SysLog("更新试卷项")
-	@PostMapping(value = "/quiz/item/update")
-	public R<Boolean> updateQuizItem(@Valid @RequestBody WmQuizDTO.OnItemUpdate resource) {
-
-		Boolean succ = quizItemService.updateItem(resource, SecurityUtils.getUser());
-
-		return succ ? R.ok(true, "更新试卷项成功") : R.failed(false, "更新试卷项失败");
-	}
-
-	@SysLog("删除试卷项")
-	@PostMapping(value = "/quiz/item/del")
-	public R<Boolean> delQuizItem(@Valid @RequestBody WmQuizDTO.OnItemDelete resource) {
-
-		Boolean deleted = quizItemService.delQuizItem(resource.getItemId());
-
-		return deleted ? R.ok(true, "删除试卷项成功") : R.failed(false, "删除试卷项失败");
-	}
-
-	// ~ QUESTION =========
-
-	/**
-	 * 获取试题详情
-	 *
-	 * @param questionId 试题ID
-	 * @param sn         试题编号
-	 * @return 详情
-	 */
-	@GetMapping(value = "/quiz/question/details")
-	public R<WmQuestion> getQuestionDetails(@RequestParam(value = "questionId", required = false) Integer questionId,
-											@RequestParam(value = "sn", required = false) String sn) {
-
-		if (questionId == null && StrUtil.isBlank(sn)) {
-			log.error("试题编号或者ID缺失");
-			throw new BizException("试题编号或者ID缺失");
-		}
-
-		WmQuestion item = questionService.getQuestionDetails(questionId, sn);
-		return R.ok(item);
-
-	}
-
-	/**
-	 * 获取试题分页
-	 *
-	 * @param current 当前页
-	 * @param size    每页记录数
-	 * @param label   试题标题
-	 * @return 分页结果
-	 */
-	@GetMapping(value = "/quiz/question/page")
-	public R<Page<?>> pageQuestions(@RequestParam(value = "current", defaultValue = "1") Integer current,
-									@RequestParam(value = "size", defaultValue = "20") Integer size,
-									@RequestParam(value = "label", required = false) String label) {
-
-		HnqzUser operator = SecurityUtils.getUser();
-
-		// 获取试题信息
-		Page<WmQuestion> itemPage = questionService.pageQuestions(current, size, operator.getDeptId(), label);
-
-		List<WmQuestion> records = itemPage.getRecords();
-
-		// 不存在试题的情况
-		if (CollUtil.isEmpty(records)) {
-			return R.ok(itemPage);
-		}
-		// 封装包含创建人的实体信息
-		else {
-			Set<String> usernames = records.stream().map(WmQuestion::getCreateBy).collect(Collectors.toSet());
-
-			Map<String, List<SysUser>> users = userService.mapUsersByUsername(usernames);
-
-			List<WmQuizVO.ToQuestionPageVO> vos = records.stream().map(item -> {
-				WmQuizVO.ToQuestionPageVO vo = new WmQuizVO.ToQuestionPageVO();
-				vo.setLabel(item.getLabel());
-				vo.setCreateTime(item.getCreateTime());
-				vo.setDetails(item);
-				SysUser sysUser = users.get(item.getCreateBy()).get(0);
-				vo.setCreateBy(sysUser == null ? "" : sysUser.getRealname());
-				return vo;
-			}).collect(Collectors.toList());
-
-			Page<WmQuizVO.ToQuestionPageVO> pages = new Page<>();
-			pages.setCurrent(current);
-			pages.setSize(size);
-			pages.setPages(itemPage.getPages());
-			pages.setRecords(vos);
-			pages.setTotal(itemPage.getTotal());
-
-			return R.ok(pages);
-		}
-
-	}
-
-	/**
-	 * 创建试题
-	 *
-	 * @param resource 试卷项内容
-	 * @return 创建结果
-	 */
-	@SysLog("创建试题")
-	@PostMapping(value = "/quiz/question/create")
-	public R<Boolean> createQuestion(@Valid @RequestBody WmQuizDTO.OnQuestionCreate resource) {
-
-		HnqzUser operator = SecurityUtils.getUser();
-		Boolean passed = questionService.checkQuestion(operator, resource.getLabel(), null);
-
-		if (!passed) {
-			String errorMsg = String.format("存在标题重复的试题,[%s]", resource.getLabel());
-			log.error(errorMsg);
-			throw new BizException(errorMsg);
-		}
-
-		Boolean succ = questionService.createQuestion(resource, operator);
-		return succ ? R.ok(true, "添加试题成功") : R.failed(false, "添加试题失败");
-	}
-
-	/**
-	 * 更新试题
-	 *
-	 * @param resource 试卷项
-	 * @return 更新结果
-	 */
-	@SysLog("更新试题")
-	@PostMapping(value = "/quiz/question/update")
-	public R<Boolean> updateQuestion(@Valid @RequestBody WmQuizDTO.OnQuestionUpdate resource) {
-
-		HnqzUser operator = SecurityUtils.getUser();
-		Boolean passed = questionService.checkQuestion(operator, resource.getLabel(), resource.getQuestionId());
-		if (!passed) {
-			String errorMsg = String.format("存在标题重复的试题,[%s]", resource.getLabel());
-			log.error(errorMsg);
-			throw new BizException(errorMsg);
-		}
-		Boolean succ = questionService.updateQuestion(resource, operator);
-		return succ ? R.ok(true, "更新试题成功") : R.failed(false, "更新试题失败");
-
-	}
-
-	/**
-	 * 删除问题
-	 *
-	 * @param resource 问题信息
-	 * @return 删除结果
-	 */
-	@SysLog(value = "删除问题")
-	@PostMapping(value = "/quiz/question/del")
-	public R<Boolean> deleteQuestion(@Valid @RequestBody WmQuizDTO.OnQuestionDel resource) {
-		Boolean deleted = questionService.deleteQuestion(resource);
-		return deleted ? R.ok(true, "删除试题成功") : R.failed(false, "删除试题失败");
-	}
+    private final SysUserService userService;
+    private final WmQuizService quizService;
+    private final WmQuizItemService quizItemService;
+    private final WmQuestionService questionService;
+    private final UpmsConfig upmsConfig;
+
+    // ~ QUIZ =========
+
+    /**
+     * 获取试卷详情
+     *
+     * @param quizId 试卷ID
+     * @return 详情信息
+     */
+    @GetMapping(value = "/quiz/details")
+    public R<Map<String, Object>> getQuizDetails(@RequestParam(value = "quizId") Integer quizId) {
+
+        Map<String, Object> details = quizService.getDetails(quizId);
+
+        return R.ok(details);
+    }
+
+    /**
+     * 获取试卷分页
+     *
+     * @param current    当前页
+     * @param size       每页记录数
+     * @param title      试卷标题
+     * @param createTime 创建时间范围
+     * @return 分页结果
+     */
+    @GetMapping(value = "/quiz/page")
+    public R<Page<?>> pageQuizzes(@RequestParam(value = "current", defaultValue = "1") Integer current,
+                                  @RequestParam(value = "size", defaultValue = "20") Integer size,
+                                  @RequestParam(value = "title", required = false) String title,
+                                  @RequestParam(value = "state", required = false) UpmsState.QuizState state,
+                                  @RequestParam(value = "createTime", required = false) LocalDateTime[] createTime) {
+
+        LambdaQueryWrapper<WmQuiz> queryWrapper = Wrappers.<WmQuiz>lambdaQuery()
+                .like(StrUtil.isNotBlank(title), WmQuiz::getTitle, title)
+                .eq(state != null, WmQuiz::getState, state)
+                .eq(WmQuiz::getEnterpriseId, SecurityUtils.getUser().getDeptId())
+                .orderByDesc(WmQuiz::getCreateTime);
+
+        if (ArrayUtil.isNotEmpty(createTime)) {
+            LocalDateTime end;
+            if (createTime.length == 1) {
+                end = LocalDateTime.now();
+            } else {
+                end = createTime[1];
+            }
+            queryWrapper.between(WmQuiz::getCreateTime, createTime[0], end);
+        }
+
+
+        Page<WmQuiz> pages = quizService.page(new Page<>(current, size), queryWrapper);
+
+        return R.ok(pages);
+    }
+
+
+    /**
+     * 获取可用的试卷
+     *
+     * @return 可用试卷列表
+     */
+    @GetMapping(value = "/quiz/avail/list")
+    public R<List<WmQuiz>> listQuizzes(@RequestParam(value = "deptId", required = false) Integer deptId) {
+
+        Integer entId = Objects.isNull(deptId) ? SecurityUtils.getUser().getDeptId() : deptId;
+
+        return R.ok(quizService.listEntQuizzes(entId, UpmsState.QuizState.RELEASE));
+    }
+
+    /**
+     * 获取平台可用的试卷
+     *
+     * @return 可用试卷列表
+     */
+    @GetMapping(value = "/quiz/plt/avail/list")
+    public R<List<WmQuiz>> listPltQuizzes() {
+
+        return R.ok(quizService.listEntQuizzes(upmsConfig.getPltEntId(), UpmsState.QuizState.RELEASE));
+    }
+
+    /**
+     * 发布试卷
+     *
+     * @param resource 发布试卷
+     * @return 发布结果
+     */
+    @SysLog("发布试卷")
+    @PostMapping(value = "/quiz/state/release")
+    public R<Boolean> releaseQuiz(@Valid @RequestBody WmQuizDTO.OnQuizState resource) {
+
+        if (!UpmsState.QuizState.RELEASE.equals(resource.getState())) {
+            log.error("发布请求参数封装错误");
+            throw new BizException("发布请求参数封装错误");
+        }
+
+        Boolean succ = quizService.releaseQuiz(resource.getQuizId(), SecurityUtils.getUser());
+        return succ ? R.ok(true, "发布试卷成功") : R.failed(false, "发布试卷失败");
+    }
+
+    /**
+     * 创建试卷
+     *
+     * @param resource 试卷信息
+     * @return 创建结果
+     */
+    @SysLog(value = "创建试卷")
+    @PostMapping(value = "/quiz/create")
+    public R<String> createQuiz(@Valid @RequestBody WmQuizDTO.OnQuizCreate resource) {
+        String sn = quizService.createQuiz(resource, SecurityUtils.getUser());
+        return StrUtil.isNotBlank(sn) ? R.ok(sn, "创建试卷成功") : R.failed("", "创建试卷失败");
+    }
+
+    /**
+     * 更新试卷
+     *
+     * @param resource 试卷信息
+     * @return 创建结果
+     */
+    @SysLog("更新试卷")
+    @PostMapping(value = "/quiz/update")
+    public R<Boolean> updateQuiz(@Valid @RequestBody WmQuizDTO.OnQuizUpdate resource) {
+
+        WmQuiz.Expand expand = resource.getExpand();
+
+        if (expand != null) {
+            quizService.checkQuizExpand(expand, resource.getSn());
+        }
+
+
+        Boolean succ = quizService.updateQuiz(resource, SecurityUtils.getUser());
+
+        return succ ? R.ok(true, "更新试卷信息成功") : R.failed(false, "更新试卷信息失败");
+    }
+
+    /**
+     * 中止试卷
+     *
+     * @param resource 试卷信息
+     * @return 中止结果
+     */
+    @SysLog("中止试卷")
+    @PostMapping(value = "/quiz/state/stop")
+    public R<Boolean> stopQuiz(@Valid @RequestBody WmQuizDTO.OnQuizState resource) {
+
+        if (!UpmsState.QuizState.STOP.equals(resource.getState())) {
+            log.error("中止请求参数封装错误");
+            throw new BizException("中止请求参数封装错误");
+        }
+
+        Boolean succ = quizService.stopQuiz(resource.getQuizId(), SecurityUtils.getUser());
+        return succ ? R.ok(true, "中止试卷成功") : R.failed(false, "中止试卷失败");
+
+    }
+
+
+    // ~ QUIZ ITEM =========
+
+    /**
+     * 获取试卷项信息
+     *
+     * @param itemId 试卷项ID
+     * @return 试卷项详情
+     */
+    @GetMapping(value = "/quiz/item/details")
+    public R<WmQuizItem> getItemDetails(@RequestParam(value = "itemId") Integer itemId) {
+        WmQuizItem item = quizItemService.getItemDetails(itemId);
+        return R.ok(item);
+    }
+
+    /**
+     * 获取试卷的试卷项列表
+     *
+     * @param sn 试卷编号
+     * @return 试卷项链表
+     */
+    @GetMapping(value = "/quiz/item/list")
+    public R<List<WmQuizItem>> listItems(@RequestParam(value = "quizSerialNum") String sn) {
+        List<WmQuizItem> items = quizItemService.listItems(sn);
+        return R.ok(items);
+    }
+
+    /**
+     * 创建试卷项(添加试题)
+     *
+     * @param resource 试卷项信息
+     * @return 创建结果
+     */
+    @SysLog("创建试卷项(添加试题)")
+    @PostMapping(value = "/quiz/item/create")
+    public R<WmQuizItem> createQuizItem(@Valid @RequestBody WmQuizDTO.OnItemCreate resource) {
+
+        WmQuizItem item = quizItemService.createItem(resource, SecurityUtils.getUser());
+
+        return item != null ? R.ok(item, "添加试卷项成功") : R.failed(null, "添加试卷项失败");
+    }
+
+    /**
+     * 批量创建试卷项(添加试题)
+     *
+     * @param resources 试卷项信息
+     * @return 创建结果
+     */
+    @SysLog("批量创建试卷项(添加试题)")
+    @PostMapping(value = "/quiz/item/batch/create")
+    public R<List<WmQuizItem>> createQuizItems(@Valid @RequestBody List<WmQuizDTO.OnItemCreate> resources) {
+
+        List<WmQuizItem> items = quizItemService.createItems(resources, SecurityUtils.getUser());
+
+        return CollUtil.isNotEmpty(items) ? R.ok(items, "批量添加试卷项成功") : R.failed(items, "批量添加试卷项失败");
+    }
+
+    /**
+     * 更新试卷项
+     *
+     * @param resource 试卷项信息
+     * @return 更新结果
+     */
+    @SysLog("更新试卷项")
+    @PostMapping(value = "/quiz/item/update")
+    public R<Boolean> updateQuizItem(@Valid @RequestBody WmQuizDTO.OnItemUpdate resource) {
+
+        Boolean succ = quizItemService.updateItem(resource, SecurityUtils.getUser());
+
+        return succ ? R.ok(true, "更新试卷项成功") : R.failed(false, "更新试卷项失败");
+    }
+
+    @SysLog("删除试卷项")
+    @PostMapping(value = "/quiz/item/del")
+    public R<Boolean> delQuizItem(@Valid @RequestBody WmQuizDTO.OnItemDelete resource) {
+
+        Boolean deleted = quizItemService.delQuizItem(resource.getItemId());
+
+        return deleted ? R.ok(true, "删除试卷项成功") : R.failed(false, "删除试卷项失败");
+    }
+
+    // ~ QUESTION =========
+
+    /**
+     * 获取试题详情
+     *
+     * @param questionId 试题ID
+     * @param sn         试题编号
+     * @return 详情
+     */
+    @GetMapping(value = "/quiz/question/details")
+    public R<WmQuestion> getQuestionDetails(@RequestParam(value = "questionId", required = false) Integer questionId,
+                                            @RequestParam(value = "sn", required = false) String sn) {
+
+        if (questionId == null && StrUtil.isBlank(sn)) {
+            log.error("试题编号或者ID缺失");
+            throw new BizException("试题编号或者ID缺失");
+        }
+
+        WmQuestion item = questionService.getQuestionDetails(questionId, sn);
+        return R.ok(item);
+
+    }
+
+    /**
+     * 获取试题分页
+     *
+     * @param current 当前页
+     * @param size    每页记录数
+     * @param label   试题标题
+     * @return 分页结果
+     */
+    @GetMapping(value = "/quiz/question/page")
+    public R<Page<?>> pageQuestions(@RequestParam(value = "current", defaultValue = "1") Integer current,
+                                    @RequestParam(value = "size", defaultValue = "20") Integer size,
+                                    @RequestParam(value = "label", required = false) String label) {
+
+        HnqzUser operator = SecurityUtils.getUser();
+
+        // 获取试题信息
+        Page<WmQuestion> itemPage = questionService.pageQuestions(current, size, operator.getDeptId(), label);
+
+        List<WmQuestion> records = itemPage.getRecords();
+
+        // 不存在试题的情况
+        if (CollUtil.isEmpty(records)) {
+            return R.ok(itemPage);
+        }
+        // 封装包含创建人的实体信息
+        else {
+            Set<String> usernames = records.stream().map(WmQuestion::getCreateBy).collect(Collectors.toSet());
+
+            Map<String, List<SysUser>> users = userService.mapUsersByUsername(usernames);
+
+            List<WmQuizVO.ToQuestionPageVO> vos = records.stream().map(item -> {
+                WmQuizVO.ToQuestionPageVO vo = new WmQuizVO.ToQuestionPageVO();
+                vo.setLabel(item.getLabel());
+                vo.setCreateTime(item.getCreateTime());
+                vo.setDetails(item);
+                SysUser sysUser = users.get(item.getCreateBy()).get(0);
+                vo.setCreateBy(sysUser == null ? "" : sysUser.getRealname());
+                return vo;
+            }).collect(Collectors.toList());
+
+            Page<WmQuizVO.ToQuestionPageVO> pages = new Page<>();
+            pages.setCurrent(current);
+            pages.setSize(size);
+            pages.setPages(itemPage.getPages());
+            pages.setRecords(vos);
+            pages.setTotal(itemPage.getTotal());
+
+            return R.ok(pages);
+        }
+
+    }
+
+    /**
+     * 创建试题
+     *
+     * @param resource 试卷项内容
+     * @return 创建结果
+     */
+    @SysLog("创建试题")
+    @PostMapping(value = "/quiz/question/create")
+    public R<Boolean> createQuestion(@Valid @RequestBody WmQuizDTO.OnQuestionCreate resource) {
+
+        HnqzUser operator = SecurityUtils.getUser();
+        Boolean passed = questionService.checkQuestion(operator, resource.getLabel(), null);
+
+        if (!passed) {
+            String errorMsg = String.format("存在标题重复的试题,[%s]", resource.getLabel());
+            log.error(errorMsg);
+            throw new BizException(errorMsg);
+        }
+
+        Boolean succ = questionService.createQuestion(resource, operator);
+        return succ ? R.ok(true, "添加试题成功") : R.failed(false, "添加试题失败");
+    }
+
+    /**
+     * 更新试题
+     *
+     * @param resource 试卷项
+     * @return 更新结果
+     */
+    @SysLog("更新试题")
+    @PostMapping(value = "/quiz/question/update")
+    public R<Boolean> updateQuestion(@Valid @RequestBody WmQuizDTO.OnQuestionUpdate resource) {
+
+        HnqzUser operator = SecurityUtils.getUser();
+        Boolean passed = questionService.checkQuestion(operator, resource.getLabel(), resource.getQuestionId());
+        if (!passed) {
+            String errorMsg = String.format("存在标题重复的试题,[%s]", resource.getLabel());
+            log.error(errorMsg);
+            throw new BizException(errorMsg);
+        }
+        Boolean succ = questionService.updateQuestion(resource, operator);
+        return succ ? R.ok(true, "更新试题成功") : R.failed(false, "更新试题失败");
+
+    }
+
+    /**
+     * 删除问题
+     *
+     * @param resource 问题信息
+     * @return 删除结果
+     */
+    @SysLog(value = "删除问题")
+    @PostMapping(value = "/quiz/question/del")
+    public R<Boolean> deleteQuestion(@Valid @RequestBody WmQuizDTO.OnQuestionDel resource) {
+        Boolean deleted = questionService.deleteQuestion(resource);
+        return deleted ? R.ok(true, "删除试题成功") : R.failed(false, "删除试题失败");
+    }
 
 
 }
 }