Selaa lähdekoodia

feat: quiz item crud

shc 1 vuosi sitten
vanhempi
commit
f68c33b769
18 muutettua tiedostoa jossa 875 lisäystä ja 0 poistoa
  1. 29 0
      db/10wm_quiz_item.sql
  2. 34 0
      db/9wm_quiz.sql
  3. 31 0
      hnqz-common/hnqz-common-core/src/main/java/com/qunzhixinxi/hnqz/common/core/constant/enums/UpmsState.java
  4. 32 0
      hnqz-common/hnqz-common-core/src/main/java/com/qunzhixinxi/hnqz/common/core/constant/enums/UpmsType.java
  5. 54 0
      hnqz-upms/hnqz-upms-api/src/main/java/com/qunzhixinxi/hnqz/admin/api/dto/WmQuizDTO.java
  6. 108 0
      hnqz-upms/hnqz-upms-api/src/main/java/com/qunzhixinxi/hnqz/admin/api/entity/WmQuiz.java
  7. 86 0
      hnqz-upms/hnqz-upms-api/src/main/java/com/qunzhixinxi/hnqz/admin/api/entity/WmQuizItem.java
  8. 27 0
      hnqz-upms/hnqz-upms-api/src/main/java/com/qunzhixinxi/hnqz/admin/api/vo/WmQuizVO.java
  9. 165 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/controller/WmQuizController.java
  10. 1 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/mapper/SysUserMapper.java
  11. 16 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/mapper/WmQuizItemMapper.java
  12. 16 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/mapper/WmQuizMapper.java
  13. 8 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/SysUserService.java
  14. 66 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/WmQuizItemService.java
  15. 14 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/WmQuizService.java
  16. 19 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/impl/SysUserServiceImpl.java
  17. 147 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/impl/WmQuizItemServiceImpl.java
  18. 22 0
      hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/impl/WmQuizServiceImpl.java

+ 29 - 0
db/10wm_quiz_item.sql

@@ -0,0 +1,29 @@
+USE `hnqzx`;
+
+SET NAMES utf8mb4;
+SET FOREIGN_KEY_CHECKS = 0;
+
+-- ----------------------------
+-- Table structure for wm_quiz_item
+-- ----------------------------
+DROP TABLE IF EXISTS `wm_quiz_item`;
+CREATE TABLE `wm_quiz_item`
+(
+    `item_id`     INT AUTO_INCREMENT COMMENT 'Id',
+    `serial_num`  VARCHAR(64)  NOT NULL COMMENT '序列号',
+    `label`       VARCHAR(64)  NOT NULL COMMENT '标题',
+    `options`     JSON COMMENT '选项',
+    `answer`      VARCHAR(255) NULL COMMENT '答案',
+    `ent_id`      INT UNSIGNED NOT NULL COMMENT '企业信息',
+    `create_by`   VARCHAR(64)  NOT NULL COMMENT '创建人',
+    `update_by`   VARCHAR(64)  NOT NULL COMMENT '修改人',
+    `create_time` DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+    `update_time` DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+    PRIMARY KEY `pk_id` (`item_id`) USING BTREE,
+    UNIQUE KEY `uk_sn` (`serial_num`) USING BTREE,
+    INDEX `idx_eid` (`ent_id`) USING BTREE
+) ENGINE = InnoDB
+    COMMENT ='试卷项表';
+
+
+SET FOREIGN_KEY_CHECKS = 1;

+ 34 - 0
db/9wm_quiz.sql

@@ -0,0 +1,34 @@
+USE `hnqzx`;
+
+SET NAMES utf8mb4;
+SET FOREIGN_KEY_CHECKS = 0;
+
+-- ----------------------------
+-- Table structure for wm_quiz
+-- ----------------------------
+DROP TABLE IF EXISTS `wm_quiz`;
+CREATE TABLE `wm_quiz`
+(
+    `quiz_id`      INT AUTO_INCREMENT COMMENT 'Id',
+    `serial_num`   VARCHAR(64)  NOT NULL COMMENT '序列号',
+    `quiz_title`   VARCHAR(64)  NOT NULL COMMENT '标题',
+    `introduction` VARCHAR(255) NULL COMMENT '简介',
+    `source_type`  VARCHAR(8)   NOT NULL COMMENT '问卷来源类型',
+    `quiz_state`   VARCHAR(8)   NOT NULL COMMENT '问卷状态',
+    `ent_id`       INT UNSIGNED NOT NULL COMMENT '企业信息',
+    `quiz_item`    JSON COMMENT '试卷项',
+    `quiz_expand`  JSON COMMENT '试卷统计',
+    `create_by`    VARCHAR(64)  NOT NULL COMMENT '创建人',
+    `update_by`    VARCHAR(64)  NOT NULL COMMENT '修改人',
+    `create_time`  DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+    `update_time`  DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+    PRIMARY KEY `pk_id` (`quiz_id`) USING BTREE,
+    UNIQUE KEY `uk_sn` (`serial_num`) USING BTREE,
+    INDEX `idx_st` (`source_type`) USING BTREE,
+    INDEX `idx_state` (`quiz_state`) USING BTREE,
+    INDEX `idx_eid` (`ent_id`) USING BTREE
+) ENGINE = InnoDB
+    COMMENT ='试卷表';
+
+
+SET FOREIGN_KEY_CHECKS = 1;

+ 31 - 0
hnqz-common/hnqz-common-core/src/main/java/com/qunzhixinxi/hnqz/common/core/constant/enums/UpmsState.java

@@ -0,0 +1,31 @@
+package com.qunzhixinxi.hnqz.common.core.constant.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+/**
+ * UPMS 状态
+ *
+ * @author jimmy
+ * @version 1.0.0
+ * @date 2023-10-16 14:34
+ */
+@NoArgsConstructor(access = AccessLevel.NONE)
+public final class UpmsState {
+
+	@Getter
+	@AllArgsConstructor
+	public enum QuizState {
+		CREATE("CREATE", "未发布"),
+		RELEASE("RELEASE", "收集中"),
+		STOP("STOP", "停止发布");
+
+
+		@EnumValue
+		private String state;
+		private String description;
+	}
+}

+ 32 - 0
hnqz-common/hnqz-common-core/src/main/java/com/qunzhixinxi/hnqz/common/core/constant/enums/UpmsType.java

@@ -0,0 +1,32 @@
+package com.qunzhixinxi.hnqz.common.core.constant.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+/**
+ * UPMS类型枚举
+ *
+ * @author jimmy
+ * @version 1.0.0
+ * @date 2023-10-16 14:31
+ */
+@NoArgsConstructor(access = AccessLevel.NONE)
+public final class UpmsType {
+
+	@Getter
+	@AllArgsConstructor
+	public enum QuizSourceType {
+
+		BLANK("BLK", "空白创建"),
+		TEMPLATE("TMP", "模板");
+
+		@EnumValue
+		private String type;
+
+		private String description;
+
+	}
+}

+ 54 - 0
hnqz-upms/hnqz-upms-api/src/main/java/com/qunzhixinxi/hnqz/admin/api/dto/WmQuizDTO.java

@@ -0,0 +1,54 @@
+package com.qunzhixinxi.hnqz.admin.api.dto;
+
+import com.qunzhixinxi.hnqz.admin.api.entity.WmQuizItem;
+import lombok.AccessLevel;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+/**
+ * 试卷dto
+ *
+ * @author jimmy
+ * @version 1.0.0
+ * @date 2023-10-16 16:07
+ */
+@NoArgsConstructor(access = AccessLevel.NONE)
+public final class WmQuizDTO {
+
+	@Data
+	public static class OnItemCreate {
+		@NotBlank(message = "试题标题必填")
+		@Length(max = 64, message = "试卷标题最多{max}个字符")
+		private String label;
+
+		@Valid
+		@NotEmpty(message = "试题选项必填")
+		private WmQuizItem.Option[] options;
+
+		@NotBlank(message = "试题答案必填")
+		@Length(max = 255, message = "试卷标题最多{max}个字符")
+		private String answer;
+
+	}
+
+	@Data
+	public static class OnItemUpdate {
+
+		@NotNull(message = "试题ID必填")
+		private Integer itemId;
+
+		private String label;
+
+		private WmQuizItem.Option[] options;
+
+		private String answer;
+
+	}
+
+}

+ 108 - 0
hnqz-upms/hnqz-upms-api/src/main/java/com/qunzhixinxi/hnqz/admin/api/entity/WmQuiz.java

@@ -0,0 +1,108 @@
+package com.qunzhixinxi.hnqz.admin.api.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
+import com.qunzhixinxi.hnqz.common.core.constant.enums.UpmsState;
+import com.qunzhixinxi.hnqz.common.core.constant.enums.UpmsType;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 试卷实体
+ *
+ * @author jimmy
+ * @version 1.0.0
+ * @date 2023-10-16 14:20
+ */
+@Data
+@TableName(value = "wm_quiz", autoResultMap = true)
+public final class WmQuiz {
+
+	/**
+	 * 试卷ID
+	 */
+	@TableId(value = "quiz_id", type = IdType.AUTO)
+	private Integer quizId;
+
+	/**
+	 * 问卷序列号
+	 */
+	@TableField(value = "serial_num")
+	private String serialNumber;
+
+	/**
+	 * 标题
+	 */
+	@TableField(value = "quiz_title")
+	private String title;
+
+	/**
+	 * 简介
+	 */
+	private String introduction;
+
+	/**
+	 * 问卷来源类型
+	 */
+	private UpmsType.QuizSourceType sourceType;
+
+	/**
+	 * 问卷状态
+	 */
+	@TableField(value = "quiz_state")
+	private UpmsState.QuizState state;
+
+	/**
+	 * 企业id
+	 */
+	@TableField(value = "ent_id")
+	private Integer enterpriseId;
+
+	@TableField(value = "quiz_item", typeHandler = JacksonTypeHandler.class)
+	private WmQuizItem[] items;
+
+	@TableField(value = "quiz_expand", typeHandler = JacksonTypeHandler.class)
+	private Expand expand;
+
+	/**
+	 * 创建人
+	 */
+	@TableField(fill = FieldFill.INSERT)
+	private String createBy;
+
+	/**
+	 * 修改人
+	 */
+	@TableField(fill = FieldFill.INSERT_UPDATE)
+	private String updateBy;
+
+	/**
+	 * 创建时间
+	 */
+	@TableField(fill = FieldFill.INSERT)
+	private LocalDateTime createTime;
+
+	/**
+	 * 修改时间
+	 */
+	@TableField(fill = FieldFill.INSERT_UPDATE)
+	private LocalDateTime updateTime;
+
+	@Data
+	public static class Expand {
+
+		private Integer itemQty;
+
+		private Integer totalScore;
+
+		private Integer passingScore;
+
+	}
+
+
+}

+ 86 - 0
hnqz-upms/hnqz-upms-api/src/main/java/com/qunzhixinxi/hnqz/admin/api/entity/WmQuizItem.java

@@ -0,0 +1,86 @@
+package com.qunzhixinxi.hnqz.admin.api.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.time.LocalDateTime;
+
+/**
+ * 试卷项
+ *
+ * @author jimmy
+ * @version 1.0.0
+ * @date 2023-10-16 14:58
+ */
+@Data
+@TableName(value = "wm_quiz_item", autoResultMap = true)
+public final class WmQuizItem {
+
+	@TableId(value = "item_id", type = IdType.AUTO)
+	private Integer itemId;
+
+	@TableField(value = "serial_num")
+	private String serialNumber;
+
+	private String label;
+
+	private Option[] options;
+
+	private String answer;
+
+	@TableField(value = "ent_id")
+	private Integer enterpriseId;
+
+	/**
+	 * 创建人
+	 */
+	@TableField(fill = FieldFill.INSERT)
+	private String createBy;
+
+	/**
+	 * 修改人
+	 */
+	@TableField(fill = FieldFill.INSERT_UPDATE)
+	private String updateBy;
+
+	/**
+	 * 创建时间
+	 */
+	@TableField(fill = FieldFill.INSERT)
+	private LocalDateTime createTime;
+
+	/**
+	 * 修改时间
+	 */
+	@TableField(fill = FieldFill.INSERT_UPDATE)
+	private LocalDateTime updateTime;
+
+	/**
+	 * 选项实体
+	 *
+	 * @author jimmy
+	 * @version 1.0.0
+	 * @date 2023-10-16 15:13
+	 */
+	@Data
+	public static class Option {
+
+		/**
+		 * 选项编号
+		 */
+		@NotBlank(message = "选项编号必填")
+		private String no;
+
+		/**
+		 * 选项文本
+		 */
+		@NotBlank(message = "选项文本必填")
+		private String text;
+
+	}
+}

+ 27 - 0
hnqz-upms/hnqz-upms-api/src/main/java/com/qunzhixinxi/hnqz/admin/api/vo/WmQuizVO.java

@@ -0,0 +1,27 @@
+package com.qunzhixinxi.hnqz.admin.api.vo;
+
+import lombok.AccessLevel;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDateTime;
+
+/**
+ * 试卷模块vo
+ *
+ * @author jimmy
+ * @version 1.0.0
+ * @date 2023-10-16 17:01
+ */
+@NoArgsConstructor(access = AccessLevel.NONE)
+public final class WmQuizVO {
+
+	@Data
+	public static class ToItemPageVO{
+		private Integer itemId;
+		private String serialNum;
+		private String label;
+		private LocalDateTime createTime;
+		private String createBy;
+	}
+}

+ 165 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/controller/WmQuizController.java

@@ -0,0 +1,165 @@
+package com.qunzhixinxi.hnqz.admin.controller;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.qunzhixinxi.hnqz.admin.api.dto.WmQuizDTO;
+import com.qunzhixinxi.hnqz.admin.api.entity.SysUser;
+import com.qunzhixinxi.hnqz.admin.api.entity.WmQuizItem;
+import com.qunzhixinxi.hnqz.admin.api.vo.WmQuizVO;
+import com.qunzhixinxi.hnqz.admin.service.SysUserService;
+import com.qunzhixinxi.hnqz.admin.service.WmQuizItemService;
+import com.qunzhixinxi.hnqz.admin.service.WmQuizService;
+import com.qunzhixinxi.hnqz.common.core.exception.BizException;
+import com.qunzhixinxi.hnqz.common.core.util.R;
+import com.qunzhixinxi.hnqz.common.log.annotation.SysLog;
+import com.qunzhixinxi.hnqz.common.security.service.HnqzUser;
+import com.qunzhixinxi.hnqz.common.security.util.SecurityUtils;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * 试卷前端控制器
+ *
+ * @author jimmy
+ * @version 1.0.0
+ * @date 2023-10-16 16:03
+ */
+@Slf4j
+@RestController
+@AllArgsConstructor
+public class WmQuizController {
+
+	private final SysUserService userService;
+
+	private final WmQuizService quizService;
+	private final WmQuizItemService quizItemService;
+
+
+	/**
+	 * 获取试题详情
+	 *
+	 * @param itemId 试题ID
+	 * @return 详情
+	 */
+	@GetMapping(value = "/quiz/item/details")
+	public R<WmQuizItem> getItemDetails(@RequestParam(value = "itemId", required = false) Integer itemId,
+										@RequestParam(value = "sn", required = false) String sn) {
+
+		if (itemId == null && StrUtil.isBlank(sn)) {
+			log.error("试题编号或者ID缺失");
+			throw new BizException("试题编号或者ID缺失");
+		}
+
+		WmQuizItem item = quizItemService.getItemDetails(itemId, sn);
+		return R.ok(item);
+
+	}
+
+	/**
+	 * 获取试卷项分页
+	 *
+	 * @param current 当前页
+	 * @param size    每页记录数
+	 * @param label   试题标题
+	 * @return 分页结果
+	 */
+	@GetMapping(value = "/quiz/item/page")
+	public R<Page<?>> pageQuizItems(@RequestParam(value = "current", defaultValue = "1") Integer current,
+									@RequestParam(value = "size", defaultValue = "20") Integer size,
+									@RequestParam(value = "label", required = false) String label) {
+		// 获取试题信息
+		Page<WmQuizItem> itemPage = quizItemService.pageQuizItems(current, size, label);
+
+		List<WmQuizItem> records = itemPage.getRecords();
+
+		// 不存在试题的情况
+		if (CollUtil.isEmpty(records)) {
+			return R.ok(itemPage);
+		}
+		// 封装包含创建人的实体信息
+		else {
+			Set<String> usernames = records.stream().map(WmQuizItem::getCreateBy).collect(Collectors.toSet());
+
+			Map<String, List<SysUser>> users = userService.mapUsersByUsername(usernames);
+
+			List<WmQuizVO.ToItemPageVO> vos = records.stream().map(item -> {
+				WmQuizVO.ToItemPageVO vo = new WmQuizVO.ToItemPageVO();
+				vo.setItemId(item.getItemId());
+				vo.setSerialNum(item.getSerialNumber());
+				vo.setLabel(item.getLabel());
+				vo.setCreateTime(item.getCreateTime());
+				SysUser sysUser = users.get(item.getCreateBy()).get(0);
+				vo.setCreateBy(sysUser == null ? "" : sysUser.getRealname());
+				return vo;
+			}).collect(Collectors.toList());
+
+			Page<WmQuizVO.ToItemPageVO> 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/item/create")
+	public R<Boolean> createQuizItem(@Valid @RequestBody WmQuizDTO.OnItemCreate resource) {
+
+		HnqzUser operator = SecurityUtils.getUser();
+		Boolean passed = quizItemService.checkItem(operator, resource.getLabel(), null);
+
+		if (!passed) {
+			String errorMsg = String.format("存在标题重复的试题,[%s]", resource.getLabel());
+			log.error(errorMsg);
+			throw new BizException(errorMsg);
+		}
+
+		Boolean succ = quizItemService.createItem(resource, operator);
+		return succ ? R.ok(succ, "添加试题成功") : R.failed(succ, "添加试题失败");
+	}
+
+	/**
+	 * 更新试卷项
+	 *
+	 * @param resource 试卷项
+	 * @return 更新结果
+	 */
+	@SysLog("更新试卷项")
+	@PostMapping(value = "/quiz/item/update")
+	public R<Boolean> updateQuizItem(@Valid @RequestBody WmQuizDTO.OnItemUpdate resource) {
+
+		HnqzUser operator = SecurityUtils.getUser();
+		Boolean passed = quizItemService.checkItem(operator, resource.getLabel(), resource.getItemId());
+		if (!passed) {
+			String errorMsg = String.format("存在标题重复的试题,[%s]", resource.getLabel());
+			log.error(errorMsg);
+			throw new BizException(errorMsg);
+		}
+		Boolean succ = quizItemService.updateItem(resource, operator);
+		return succ ? R.ok(succ, "更新试题成功") : R.failed(succ, "更新试题失败");
+
+	}
+
+}

+ 1 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/mapper/SysUserMapper.java

@@ -31,6 +31,7 @@ import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
+import java.util.Set;
 
 /**
  * <p>

+ 16 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/mapper/WmQuizItemMapper.java

@@ -0,0 +1,16 @@
+package com.qunzhixinxi.hnqz.admin.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qunzhixinxi.hnqz.admin.api.entity.WmQuizItem;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 试卷项Mapper
+ *
+ * @author jimmy
+ * @version 1.0.0
+ * @date 2023-10-16 15:49
+ */
+@Mapper
+public interface WmQuizItemMapper extends BaseMapper<WmQuizItem> {
+}

+ 16 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/mapper/WmQuizMapper.java

@@ -0,0 +1,16 @@
+package com.qunzhixinxi.hnqz.admin.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qunzhixinxi.hnqz.admin.api.entity.WmQuiz;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 试卷Mapper
+ *
+ * @author jimmy
+ * @version 1.0.0
+ * @date 2023-10-16 15:51
+ */
+@Mapper
+public interface WmQuizMapper extends BaseMapper<WmQuiz> {
+}

+ 8 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/SysUserService.java

@@ -162,4 +162,12 @@ public interface SysUserService extends IService<SysUser> {
 	 * @return 结果
 	 */
 	Map<String, String> checkSixtyYearsOld(UserVO userVO);
+
+	/**
+	 * 根据用户名获取用户信息
+	 *
+	 * @param usernames 用户名
+	 * @return 用户信息map
+	 */
+	Map<String, List<SysUser>> mapUsersByUsername(Collection<String> usernames);
 }

+ 66 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/WmQuizItemService.java

@@ -0,0 +1,66 @@
+package com.qunzhixinxi.hnqz.admin.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qunzhixinxi.hnqz.admin.api.dto.WmQuizDTO;
+import com.qunzhixinxi.hnqz.admin.api.entity.WmQuizItem;
+import com.qunzhixinxi.hnqz.common.security.service.HnqzUser;
+
+/**
+ * 试卷项服务
+ *
+ * @author jimmy
+ * @version 1.0.0
+ * @date 2023-10-16 15:59
+ */
+public interface WmQuizItemService extends IService<WmQuizItem> {
+
+	/**
+	 * 校验试卷项
+	 *
+	 * @param operator 操作人
+	 * @param label    标题
+	 * @param itemId   试卷项ID
+	 * @return 校验结果
+	 */
+	Boolean checkItem(HnqzUser operator, String label, Integer itemId);
+
+	/**
+	 * 创建试题
+	 *
+	 * @param resource 试题信息
+	 * @param operator 操作人
+	 * @return 创建结果
+	 */
+	Boolean createItem(WmQuizDTO.OnItemCreate resource, HnqzUser operator);
+
+	/**
+	 * 创建试题
+	 *
+	 * @param resource 试题信息
+	 * @param operator 操作人
+	 * @return 创建结果
+	 */
+	Boolean updateItem(WmQuizDTO.OnItemUpdate resource, HnqzUser operator);
+
+	/**
+	 * 获取试题分页
+	 *
+	 * @param current 当前页
+	 * @param size    每页记录数
+	 * @param label   标题
+	 * @return 分页结果
+	 */
+	Page<WmQuizItem> pageQuizItems(Integer current, Integer size, String label);
+
+	/**
+	 * 获取试题详情
+	 *
+	 * @param itemId 试题ID
+	 * @param sn     试题唯一序列号
+	 * @return 试题信息
+	 */
+	WmQuizItem getItemDetails(Integer itemId, String sn);
+
+
+}

+ 14 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/WmQuizService.java

@@ -0,0 +1,14 @@
+package com.qunzhixinxi.hnqz.admin.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qunzhixinxi.hnqz.admin.api.entity.WmQuiz;
+
+/**
+ * 试卷服务
+ *
+ * @author jimmy
+ * @version 1.0.0
+ * @date 2023-10-16 15:54
+ */
+public interface WmQuizService extends IService<WmQuiz> {
+}

+ 19 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/impl/SysUserServiceImpl.java

@@ -23,6 +23,7 @@ import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.date.DatePattern;
 import cn.hutool.core.lang.Validator;
+import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.ArrayUtil;
 import cn.hutool.core.util.IdcardUtil;
 import cn.hutool.core.util.StrUtil;
@@ -273,6 +274,24 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
 		return result;
 	}
 
+	/**
+	 * 根据用户名获取用户信息
+	 *
+	 * @param usernames 用户名
+	 * @return 用户信息map
+	 */
+	@Override
+	public Map<String, List<SysUser>> mapUsersByUsername(Collection<String> usernames) {
+
+		if (CollUtil.isEmpty(usernames)){
+			return Collections.emptyMap();
+		}
+
+		List<SysUser> sysUsers = this.list(Wrappers.<SysUser>lambdaQuery().in(SysUser::getUsername, usernames));
+
+		return sysUsers.stream().collect(Collectors.groupingBy(SysUser::getUsername));
+	}
+
 	/**
 	 * 封装错误信息
 	 *

+ 147 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/impl/WmQuizItemServiceImpl.java

@@ -0,0 +1,147 @@
+package com.qunzhixinxi.hnqz.admin.service.impl;
+
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qunzhixinxi.hnqz.admin.api.dto.WmQuizDTO;
+import com.qunzhixinxi.hnqz.admin.api.entity.WmQuizItem;
+import com.qunzhixinxi.hnqz.admin.mapper.WmQuizItemMapper;
+import com.qunzhixinxi.hnqz.admin.service.WmQuizItemService;
+import com.qunzhixinxi.hnqz.common.security.service.HnqzUser;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDateTime;
+
+/**
+ * 试卷项服务实现
+ *
+ * @author jimmy
+ * @version 1.0.0
+ * @date 2023-10-16 16:01
+ */
+@Slf4j
+@Service
+@AllArgsConstructor
+public class WmQuizItemServiceImpl extends ServiceImpl<WmQuizItemMapper, WmQuizItem> implements WmQuizItemService {
+
+	/**
+	 * 校验试卷项
+	 *
+	 * @param operator 操作人
+	 * @param label    标题
+	 * @param itemId   试卷项ID
+	 * @return 校验结果
+	 */
+	@Override
+	public Boolean checkItem(HnqzUser operator, String label, Integer itemId) {
+
+		int count = this.count(Wrappers.<WmQuizItem>lambdaQuery()
+				.eq(WmQuizItem::getLabel, label)
+				.eq(WmQuizItem::getEnterpriseId, operator.getDeptId())
+				.ne(itemId != null, WmQuizItem::getItemId, itemId)
+		);
+
+		return count == 0;
+	}
+
+	/**
+	 * 创建试题
+	 *
+	 * @param resource 试题信息
+	 * @param operator 操作人
+	 * @return 创建结果
+	 */
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public Boolean createItem(WmQuizDTO.OnItemCreate resource, HnqzUser operator) {
+
+		WmQuizItem quizItem = new WmQuizItem();
+		quizItem.setSerialNumber(IdUtil.fastSimpleUUID());
+		quizItem.setLabel(resource.getLabel());
+		quizItem.setOptions(resource.getOptions());
+		quizItem.setAnswer(resource.getAnswer());
+		quizItem.setEnterpriseId(operator.getDeptId());
+		String username = operator.getUsername();
+		quizItem.setCreateBy(username);
+		quizItem.setUpdateBy(username);
+		LocalDateTime now = LocalDateTime.now();
+		quizItem.setCreateTime(now);
+		quizItem.setUpdateTime(now);
+
+		return this.save(quizItem);
+	}
+
+	/**
+	 * 创建试题
+	 *
+	 * @param resource 试题信息
+	 * @param operator 操作人
+	 * @return 创建结果
+	 */
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public Boolean updateItem(WmQuizDTO.OnItemUpdate resource, HnqzUser operator) {
+
+		WmQuizItem quizItem = new WmQuizItem();
+		quizItem.setItemId(resource.getItemId());
+		quizItem.setUpdateBy(operator.getUsername());
+		quizItem.setUpdateTime(LocalDateTime.now());
+
+		if (StrUtil.isNotBlank(resource.getLabel())) {
+			quizItem.setLabel(resource.getLabel());
+		}
+
+		if (ArrayUtil.isNotEmpty(resource.getOptions())) {
+			quizItem.setOptions(resource.getOptions());
+		}
+
+		if (StrUtil.isNotBlank(resource.getAnswer())) {
+			quizItem.setAnswer(resource.getAnswer());
+		}
+
+		return this.updateById(quizItem);
+	}
+
+	/**
+	 * 获取试题分页
+	 *
+	 * @param current 当前页
+	 * @param size    每页记录数
+	 * @param label   标题
+	 * @return 分页结果
+	 */
+	@Override
+	public Page<WmQuizItem> pageQuizItems(Integer current, Integer size, String label) {
+
+		return this.page(new Page<>(current, size),
+				Wrappers.<WmQuizItem>lambdaQuery()
+						.like(StrUtil.isNotBlank(label), WmQuizItem::getLabel, label)
+						.orderByDesc(WmQuizItem::getUpdateTime)
+		);
+	}
+
+	/**
+	 * 获取试题详情
+	 *
+	 * @param itemId 试题ID
+	 * @param sn     试题唯一序列号
+	 * @return 试题信息
+	 */
+	@Override
+	public WmQuizItem getItemDetails(Integer itemId, String sn) {
+
+		if (itemId != null) {
+			return this.getById(itemId);
+		} else if (StrUtil.isNotBlank(sn)) {
+			return this.getOne(Wrappers.<WmQuizItem>lambdaQuery().eq(WmQuizItem::getSerialNumber, sn));
+		} else {
+			return null;
+		}
+	}
+}

+ 22 - 0
hnqz-upms/hnqz-upms-biz/src/main/java/com/qunzhixinxi/hnqz/admin/service/impl/WmQuizServiceImpl.java

@@ -0,0 +1,22 @@
+package com.qunzhixinxi.hnqz.admin.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qunzhixinxi.hnqz.admin.api.entity.WmQuiz;
+import com.qunzhixinxi.hnqz.admin.mapper.WmQuizMapper;
+import com.qunzhixinxi.hnqz.admin.service.WmQuizService;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/**
+ * 试卷服务实现
+ *
+ * @author jimmy
+ * @version 1.0.0
+ * @date 2023-10-16 15:55
+ */
+@Slf4j
+@Service
+@AllArgsConstructor
+public class WmQuizServiceImpl extends ServiceImpl<WmQuizMapper, WmQuiz> implements WmQuizService {
+}