Przeglądaj źródła

考试代码提交

pans 7 miesięcy temu
rodzic
commit
f0d4007ee7
34 zmienionych plików z 1466 dodań i 162 usunięć
  1. 3 1
      snowy-plugin/snowy-plugin-dev/snowy-plugin-dev-func/src/main/java/vip/xiaonuo/dev/modular/job/service/impl/DevJobServiceImpl.java
  2. 132 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/controller/ResourceFootprintController.java
  3. 91 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/domain/ResourceFootprint.java
  4. 34 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/enums/ResourceFootprintEnum.java
  5. 26 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/ResourceFootprintMapper.java
  6. 5 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/mapping/ResourceFootprintMapper.xml
  7. 57 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/param/footprint/ResourceFootprintAddParam.java
  8. 67 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/param/footprint/ResourceFootprintEditParam.java
  9. 35 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/param/footprint/ResourceFootprintIdParam.java
  10. 51 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/param/footprint/ResourceFootprintPageParam.java
  11. 81 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/ResourceFootprintService.java
  12. 96 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/impl/ResourceFootprintServiceImpl.java
  13. 5 0
      snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/pom.xml
  14. 6 10
      snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/controller/admin/QuestionController.java
  15. 3 3
      snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/controller/admin/TExamController.java
  16. 3 3
      snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/controller/student/TExamController.java
  17. 31 0
      snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/domain/Question.java
  18. 11 1
      snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/domain/TExam.java
  19. 5 3
      snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/domain/exam/TExamAddParam.java
  20. 7 2
      snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/domain/exam/TExamEditParam.java
  21. 7 1
      snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/domain/exam/TExamPageParam.java
  22. 4 1
      snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/mapper/QuestionMapper.java
  23. 7 0
      snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/mapper/TExamMapper.java
  24. 89 11
      snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/mapper/mapping/QuestionMapper.xml
  25. 75 1
      snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/mapper/mapping/TExamMapper.xml
  26. 2 2
      snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/service/QuestionService.java
  27. 3 2
      snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/service/TExamService.java
  28. 5 10
      snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/service/impl/ExamPaperServiceImpl.java
  29. 45 39
      snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/service/impl/QuestionServiceImpl.java
  30. 19 69
      snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/service/impl/TExamServiceImpl.java
  31. 63 3
      snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/viewmodel/admin/question/QuestionEditRequestVM.java
  32. 31 0
      snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/viewmodel/admin/question/QuestionPageRequestVM.java
  33. 270 0
      snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/vo/QuestionVo.java
  34. 97 0
      snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/vo/TExamVo.java

+ 3 - 1
snowy-plugin/snowy-plugin-dev/snowy-plugin-dev-func/src/main/java/vip/xiaonuo/dev/modular/job/service/impl/DevJobServiceImpl.java

@@ -126,7 +126,9 @@ public class DevJobServiceImpl extends ServiceImpl<DevJobMapper, DevJob> impleme
         }
         boolean hasSameJob = this.count(new LambdaQueryWrapper<DevJob>()
                 .eq(DevJob::getActionClass, devJobAddParam.getActionClass())
-                .eq(DevJob::getCronExpression, devJobAddParam.getCronExpression())) > 0;
+                .eq(DevJob::getCronExpression, devJobAddParam.getCronExpression())
+                .eq(DevJob::getName, devJobAddParam.getName())
+                )> 0;
         if (hasSameJob) {
             throw new CommonException("存在重复执行的定时任务,名称为:{}", devJobAddParam.getName());
         }

+ 132 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/controller/ResourceFootprintController.java

@@ -0,0 +1,132 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.disk.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import com.github.xiaoymin.knife4j.annotations.ApiSupport;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+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.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+import vip.xiaonuo.common.annotation.CommonLog;
+import vip.xiaonuo.common.pojo.CommonResult;
+import vip.xiaonuo.common.pojo.CommonValidList;
+import vip.xiaonuo.disk.domain.ResourceFootprint;
+import vip.xiaonuo.disk.param.footprint.ResourceFootprintAddParam;
+import vip.xiaonuo.disk.param.footprint.ResourceFootprintEditParam;
+import vip.xiaonuo.disk.param.footprint.ResourceFootprintIdParam;
+import vip.xiaonuo.disk.param.footprint.ResourceFootprintPageParam;
+import vip.xiaonuo.disk.service.ResourceFootprintService;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import javax.validation.constraints.NotEmpty;
+
+/**
+ * RESOURCE_FOOTPRINT控制器
+ *
+ * @author pans
+ * @date  2025/07/31 14:10
+ */
+@Api(tags = "RESOURCE_FOOTPRINT控制器")
+@ApiSupport(author = "SNOWY_TEAM", order = 1)
+@RestController
+@Validated
+public class ResourceFootprintController {
+
+    @Resource
+    private ResourceFootprintService resourceFootprintService;
+
+    /**
+     * 获取RESOURCE_FOOTPRINT分页
+     *
+     * @author pans
+     * @date  2025/07/31 14:10
+     */
+    @ApiOperationSupport(order = 1)
+    @ApiOperation("获取RESOURCE_FOOTPRINT分页")
+    @SaCheckPermission("/disk/footprint/page")
+    @GetMapping("/disk/footprint/page")
+    public CommonResult<Page<ResourceFootprint>> page(ResourceFootprintPageParam resourceFootprintPageParam) {
+        return CommonResult.data(resourceFootprintService.page(resourceFootprintPageParam));
+    }
+
+    /**
+     * 添加RESOURCE_FOOTPRINT
+     *
+     * @author pans
+     * @date  2025/07/31 14:10
+     */
+    @ApiOperationSupport(order = 2)
+    @ApiOperation("添加RESOURCE_FOOTPRINT")
+    @CommonLog("添加RESOURCE_FOOTPRINT")
+    @SaCheckPermission("/disk/footprint/add")
+    @PostMapping("/disk/footprint/add")
+    public CommonResult<String> add(@RequestBody @Valid ResourceFootprintAddParam resourceFootprintAddParam) {
+        resourceFootprintService.add(resourceFootprintAddParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 编辑RESOURCE_FOOTPRINT
+     *
+     * @author pans
+     * @date  2025/07/31 14:10
+     */
+    @ApiOperationSupport(order = 3)
+    @ApiOperation("编辑RESOURCE_FOOTPRINT")
+    @CommonLog("编辑RESOURCE_FOOTPRINT")
+    @SaCheckPermission("/disk/footprint/edit")
+    @PostMapping("/disk/footprint/edit")
+    public CommonResult<String> edit(@RequestBody @Valid ResourceFootprintEditParam resourceFootprintEditParam) {
+        resourceFootprintService.edit(resourceFootprintEditParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 删除RESOURCE_FOOTPRINT
+     *
+     * @author pans
+     * @date  2025/07/31 14:10
+     */
+    @ApiOperationSupport(order = 4)
+    @ApiOperation("删除RESOURCE_FOOTPRINT")
+    @CommonLog("删除RESOURCE_FOOTPRINT")
+    @SaCheckPermission("/disk/footprint/delete")
+    @PostMapping("/disk/footprint/delete")
+    public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
+                                                   CommonValidList<ResourceFootprintIdParam> resourceFootprintIdParamList) {
+        resourceFootprintService.delete(resourceFootprintIdParamList);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 获取RESOURCE_FOOTPRINT详情
+     *
+     * @author pans
+     * @date  2025/07/31 14:10
+     */
+    @ApiOperationSupport(order = 5)
+    @ApiOperation("获取RESOURCE_FOOTPRINT详情")
+    @SaCheckPermission("/disk/footprint/detail")
+    @GetMapping("/disk/footprint/detail")
+    public CommonResult<ResourceFootprint> detail(@Valid ResourceFootprintIdParam resourceFootprintIdParam) {
+        return CommonResult.data(resourceFootprintService.detail(resourceFootprintIdParam));
+    }
+
+}

+ 91 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/domain/ResourceFootprint.java

@@ -0,0 +1,91 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.disk.domain;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+/**
+ * RESOURCE_FOOTPRINT实体
+ *
+ * @author pans
+ * @date  2025/07/31 14:10
+ **/
+@Getter
+@Setter
+@TableName("RESOURCE_FOOTPRINT")
+public class ResourceFootprint {
+
+    /** ID */
+    @TableId
+    @ApiModelProperty(value = "ID", position = 1)
+    private String id;
+
+    /** 文件id */
+    @ApiModelProperty(value = "文件id", position = 2)
+    private String userFileId;
+
+    /** 扩展名 */
+    @ApiModelProperty(value = "扩展名", position = 3)
+    private String extendName;
+
+    /** 文件id */
+    @ApiModelProperty(value = "文件id", position = 4)
+    private String fileId;
+
+    /** 文件名称 */
+    @ApiModelProperty(value = "文件名称", position = 5)
+    private String fileName;
+
+    /** 文件路径 */
+    @ApiModelProperty(value = "文件路径", position = 6)
+    private String filePath;
+
+    /** DELETE_FLAG */
+    @ApiModelProperty(value = "DELETE_FLAG", position = 7)
+    @TableLogic
+    @TableField(fill = FieldFill.INSERT)
+    private String deleteFlag;
+
+    /** CREATE_TIME */
+    @ApiModelProperty(value = "CREATE_TIME", position = 8)
+    @TableField(fill = FieldFill.INSERT)
+    private Date createTime;
+
+    /** CREATE_USER */
+    @ApiModelProperty(value = "CREATE_USER", position = 9)
+    @TableField(fill = FieldFill.INSERT)
+    private String createUser;
+
+    /** UPDATE_TIME */
+    @ApiModelProperty(value = "UPDATE_TIME", position = 10)
+    @TableField(fill = FieldFill.UPDATE)
+    private Date updateTime;
+
+    /** UPDATE_USER */
+    @ApiModelProperty(value = "UPDATE_USER", position = 11)
+    @TableField(fill = FieldFill.UPDATE)
+    private String updateUser;
+
+    /** 用户id */
+    @ApiModelProperty(value = "用户id", position = 12)
+    private String userId;
+
+    /** 文件记录id */
+    @ApiModelProperty(value = "文件记录id", position = 13)
+    private String resourceRecordId;
+}

+ 34 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/enums/ResourceFootprintEnum.java

@@ -0,0 +1,34 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.disk.enums;
+
+import lombok.Getter;
+
+/**
+ * RESOURCE_FOOTPRINT枚举
+ *
+ * @author pans
+ * @date  2025/07/31 14:10
+ **/
+@Getter
+public enum ResourceFootprintEnum {
+
+    /** 测试 */
+    TEST("TEST");
+
+    private final String value;
+
+    ResourceFootprintEnum(String value) {
+        this.value = value;
+    }
+}

+ 26 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/ResourceFootprintMapper.java

@@ -0,0 +1,26 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.disk.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import vip.xiaonuo.disk.domain.ResourceFootprint;
+
+
+/**
+ * RESOURCE_FOOTPRINTMapper接口
+ *
+ * @author pans
+ * @date  2025/07/31 14:10
+ **/
+public interface ResourceFootprintMapper extends BaseMapper<ResourceFootprint> {
+}

+ 5 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/mapping/ResourceFootprintMapper.xml

@@ -0,0 +1,5 @@
+<?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="vip.xiaonuo.disk.modular.footprint.mapper.ResourceFootprintMapper">
+
+</mapper>

+ 57 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/param/footprint/ResourceFootprintAddParam.java

@@ -0,0 +1,57 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.disk.param.footprint;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * RESOURCE_FOOTPRINT添加参数
+ *
+ * @author pans
+ * @date  2025/07/31 14:10
+ **/
+@Getter
+@Setter
+public class ResourceFootprintAddParam {
+
+    /** 文件id */
+    @ApiModelProperty(value = "文件id", position = 2)
+    private String userFileId;
+
+    /** 扩展名 */
+    @ApiModelProperty(value = "扩展名", position = 3)
+    private String extendName;
+
+    /** 文件id */
+    @ApiModelProperty(value = "文件id", position = 4)
+    private String fileId;
+
+    /** 文件名称 */
+    @ApiModelProperty(value = "文件名称", position = 5)
+    private String fileName;
+
+    /** 文件路径 */
+    @ApiModelProperty(value = "文件路径", position = 6)
+    private String filePath;
+
+    /** 用户id */
+    @ApiModelProperty(value = "用户id", position = 12)
+    private String userId;
+
+    /** 文件记录id */
+    @ApiModelProperty(value = "文件记录id", position = 13)
+    private String resourceRecordId;
+
+}

+ 67 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/param/footprint/ResourceFootprintEditParam.java

@@ -0,0 +1,67 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.disk.param.footprint;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * RESOURCE_FOOTPRINT编辑参数
+ *
+ * @author pans
+ * @date  2025/07/31 14:10
+ **/
+@Getter
+@Setter
+public class ResourceFootprintEditParam {
+
+    /** ID */
+    @ApiModelProperty(value = "ID", required = true, position = 1)
+    @NotBlank(message = "id不能为空")
+    private String id;
+
+    /** 文件id */
+    @ApiModelProperty(value = "文件id", position = 2)
+    private String userFileId;
+
+    /** 扩展名 */
+    @ApiModelProperty(value = "扩展名", position = 3)
+    private String extendName;
+
+    /** 文件id */
+    @ApiModelProperty(value = "文件id", position = 4)
+    private String fileId;
+
+    /** 文件名称 */
+    @ApiModelProperty(value = "文件名称", position = 5)
+    private String fileName;
+
+    /** 文件路径 */
+    @ApiModelProperty(value = "文件路径", position = 6)
+    private String filePath;
+
+    /** 用户id */
+    @ApiModelProperty(value = "用户id", position = 12)
+    private String userId;
+
+    /** 文件记录id */
+    @ApiModelProperty(value = "文件记录id", position = 13)
+    private String resourceRecordId;
+
+}

+ 35 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/param/footprint/ResourceFootprintIdParam.java

@@ -0,0 +1,35 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.disk.param.footprint;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * RESOURCE_FOOTPRINTId参数
+ *
+ * @author pans
+ * @date  2025/07/31 14:10
+ **/
+@Getter
+@Setter
+public class ResourceFootprintIdParam {
+
+    /** ID */
+    @ApiModelProperty(value = "ID", required = true)
+    @NotBlank(message = "id不能为空")
+    private String id;
+}

+ 51 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/param/footprint/ResourceFootprintPageParam.java

@@ -0,0 +1,51 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.disk.param.footprint;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * RESOURCE_FOOTPRINT查询参数
+ *
+ * @author pans
+ * @date  2025/07/31 14:10
+ **/
+@Getter
+@Setter
+public class ResourceFootprintPageParam {
+
+    /** 当前页 */
+    @ApiModelProperty(value = "当前页码")
+    private Integer current;
+
+    /** 每页条数 */
+    @ApiModelProperty(value = "每页条数")
+    private Integer size;
+
+    /** 排序字段 */
+    @ApiModelProperty(value = "排序字段,字段驼峰名称,如:userName")
+    private String sortField;
+
+    /** 排序方式 */
+    @ApiModelProperty(value = "排序方式,升序:ASCEND;降序:DESCEND")
+    private String sortOrder;
+
+    /** 关键词 */
+    @ApiModelProperty(value = "关键词")
+    private String searchKey;
+
+}

+ 81 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/ResourceFootprintService.java

@@ -0,0 +1,81 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.disk.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import vip.xiaonuo.disk.domain.ResourceFootprint;
+import vip.xiaonuo.disk.param.footprint.ResourceFootprintAddParam;
+import vip.xiaonuo.disk.param.footprint.ResourceFootprintEditParam;
+import vip.xiaonuo.disk.param.footprint.ResourceFootprintIdParam;
+import vip.xiaonuo.disk.param.footprint.ResourceFootprintPageParam;
+
+import java.util.List;
+
+/**
+ * RESOURCE_FOOTPRINTService接口
+ *
+ * @author pans
+ * @date  2025/07/31 14:10
+ **/
+public interface ResourceFootprintService extends IService<ResourceFootprint> {
+
+    /**
+     * 获取RESOURCE_FOOTPRINT分页
+     *
+     * @author pans
+     * @date  2025/07/31 14:10
+     */
+    Page<ResourceFootprint> page(ResourceFootprintPageParam resourceFootprintPageParam);
+
+    /**
+     * 添加RESOURCE_FOOTPRINT
+     *
+     * @author pans
+     * @date  2025/07/31 14:10
+     */
+    void add(ResourceFootprintAddParam resourceFootprintAddParam);
+
+    /**
+     * 编辑RESOURCE_FOOTPRINT
+     *
+     * @author pans
+     * @date  2025/07/31 14:10
+     */
+    void edit(ResourceFootprintEditParam resourceFootprintEditParam);
+
+    /**
+     * 删除RESOURCE_FOOTPRINT
+     *
+     * @author pans
+     * @date  2025/07/31 14:10
+     */
+    void delete(List<ResourceFootprintIdParam> resourceFootprintIdParamList);
+
+    /**
+     * 获取RESOURCE_FOOTPRINT详情
+     *
+     * @author pans
+     * @date  2025/07/31 14:10
+     */
+    ResourceFootprint detail(ResourceFootprintIdParam resourceFootprintIdParam);
+
+    /**
+     * 获取RESOURCE_FOOTPRINT详情
+     *
+     * @author pans
+     * @date  2025/07/31 14:10
+     **/
+    ResourceFootprint queryEntity(String id);
+
+}

+ 96 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/impl/ResourceFootprintServiceImpl.java

@@ -0,0 +1,96 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.disk.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollStreamUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import vip.xiaonuo.common.enums.CommonSortOrderEnum;
+import vip.xiaonuo.common.exception.CommonException;
+import vip.xiaonuo.common.page.CommonPageRequest;
+import vip.xiaonuo.disk.domain.ResourceFootprint;
+import vip.xiaonuo.disk.mapper.ResourceFootprintMapper;
+import vip.xiaonuo.disk.param.footprint.ResourceFootprintAddParam;
+import vip.xiaonuo.disk.param.footprint.ResourceFootprintEditParam;
+import vip.xiaonuo.disk.param.footprint.ResourceFootprintIdParam;
+import vip.xiaonuo.disk.param.footprint.ResourceFootprintPageParam;
+import vip.xiaonuo.disk.service.ResourceFootprintService;
+
+import java.util.List;
+
+/**
+ * RESOURCE_FOOTPRINTService接口实现类
+ *
+ * @author pans
+ * @date  2025/07/31 14:10
+ **/
+@Service
+public class ResourceFootprintServiceImpl extends ServiceImpl<ResourceFootprintMapper, ResourceFootprint> implements ResourceFootprintService {
+
+
+    @Override
+    public Page<ResourceFootprint> page(ResourceFootprintPageParam resourceFootprintPageParam) {
+        QueryWrapper<ResourceFootprint> queryWrapper = new QueryWrapper<>();
+        if(ObjectUtil.isAllNotEmpty(resourceFootprintPageParam.getSortField(), resourceFootprintPageParam.getSortOrder())) {
+            CommonSortOrderEnum.validate(resourceFootprintPageParam.getSortOrder());
+            queryWrapper.orderBy(true, resourceFootprintPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
+                    StrUtil.toUnderlineCase(resourceFootprintPageParam.getSortField()));
+        } else {
+            queryWrapper.lambda().orderByAsc(ResourceFootprint::getId);
+        }
+        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void add(ResourceFootprintAddParam resourceFootprintAddParam) {
+        ResourceFootprint resourceFootprint = BeanUtil.toBean(resourceFootprintAddParam, ResourceFootprint.class);
+        this.save(resourceFootprint);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void edit(ResourceFootprintEditParam resourceFootprintEditParam) {
+        ResourceFootprint resourceFootprint = this.queryEntity(resourceFootprintEditParam.getId());
+        BeanUtil.copyProperties(resourceFootprintEditParam, resourceFootprint);
+        this.updateById(resourceFootprint);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void delete(List<ResourceFootprintIdParam> resourceFootprintIdParamList) {
+        // 执行删除
+        this.removeByIds(CollStreamUtil.toList(resourceFootprintIdParamList, ResourceFootprintIdParam::getId));
+    }
+
+    @Override
+    public ResourceFootprint detail(ResourceFootprintIdParam resourceFootprintIdParam) {
+        return this.queryEntity(resourceFootprintIdParam.getId());
+    }
+
+    @Override
+    public ResourceFootprint queryEntity(String id) {
+        ResourceFootprint resourceFootprint = this.getById(id);
+        if(ObjectUtil.isEmpty(resourceFootprint)) {
+            throw new CommonException("RESOURCE_FOOTPRINT不存在,id值为:{}", id);
+        }
+        return resourceFootprint;
+    }
+
+}

+ 5 - 0
snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/pom.xml

@@ -124,5 +124,10 @@
             <groupId>vip.xiaonuo</groupId>
             <artifactId>snowy-plugin-disk-api</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>vip.xiaonuo</groupId>
+            <artifactId>snowy-plugin-disk-func</artifactId>
+        </dependency>
     </dependencies>
 </project>

+ 6 - 10
snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/controller/admin/QuestionController.java

@@ -1,27 +1,23 @@
 package vip.xiaonuo.exam.controller.admin;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 import vip.xiaonuo.common.pojo.CommonResult;
 import vip.xiaonuo.exam.base.BaseApiController;
-import vip.xiaonuo.exam.base.RestResponse;
 import vip.xiaonuo.exam.base.SystemCode;
-import vip.xiaonuo.exam.domain.ExamPaper;
 import vip.xiaonuo.exam.domain.Question;
 import vip.xiaonuo.exam.domain.TextContent;
 import vip.xiaonuo.exam.domain.enums.QuestionTypeEnum;
 import vip.xiaonuo.exam.domain.question.QuestionObject;
 import vip.xiaonuo.exam.service.QuestionService;
 import vip.xiaonuo.exam.service.TextContentService;
-
 import vip.xiaonuo.exam.utility.*;
 import vip.xiaonuo.exam.viewmodel.admin.question.QuestionEditRequestVM;
 import vip.xiaonuo.exam.viewmodel.admin.question.QuestionPageRequestVM;
-import vip.xiaonuo.exam.viewmodel.admin.question.QuestionResponseVM;
-import com.github.pagehelper.PageInfo;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
+import vip.xiaonuo.exam.vo.QuestionVo;
 
 import javax.validation.Valid;
 
@@ -39,8 +35,8 @@ public class QuestionController extends BaseApiController {
     }
 
     @RequestMapping(value = "/page", method = RequestMethod.POST)
-    public CommonResult<Page<Question>> pageList(@RequestBody QuestionPageRequestVM model) {
-        Page<Question> pageInfo = questionService.page(model);
+    public CommonResult<Page<QuestionVo>> pageList(@RequestBody QuestionPageRequestVM model) {
+        Page<QuestionVo> pageInfo = questionService.page(model);
         pageInfo.getRecords().forEach(question -> {
             question.setCreateTimeStr(DateTimeUtil.dateFormat(question.getCreateTime()));
             question.setScoreStr(ExamUtil.scoreToVM(question.getScore()));

+ 3 - 3
snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/controller/admin/TExamController.java

@@ -24,12 +24,12 @@ import vip.xiaonuo.common.annotation.CommonLog;
 import vip.xiaonuo.common.pojo.CommonResult;
 import vip.xiaonuo.common.pojo.CommonValidList;
 import vip.xiaonuo.exam.base.BaseApiController;
-import vip.xiaonuo.exam.domain.TExam;
 import vip.xiaonuo.exam.domain.exam.TExamAddParam;
 import vip.xiaonuo.exam.domain.exam.TExamEditParam;
 import vip.xiaonuo.exam.domain.exam.TExamIdParam;
 import vip.xiaonuo.exam.domain.exam.TExamPageParam;
 import vip.xiaonuo.exam.service.TExamService;
+import vip.xiaonuo.exam.vo.TExamVo;
 
 import javax.annotation.Resource;
 import javax.validation.Valid;
@@ -61,7 +61,7 @@ public class TExamController extends BaseApiController {
     @ApiOperation("获取考试表分页")
     @SaCheckPermission("/api/admin/t_exam/page")
     @GetMapping("/page")
-    public CommonResult<Page<TExam>> page(TExamPageParam tExamPageParam) {
+    public CommonResult<Page<TExamVo>> page(TExamPageParam tExamPageParam) {
         return CommonResult.data(tExamService.page(tExamPageParam));
     }
 
@@ -124,7 +124,7 @@ public class TExamController extends BaseApiController {
     @ApiOperation("获取考试表详情")
     @SaCheckPermission("/api/admin/t_exam/detail")
     @GetMapping("/detail")
-    public CommonResult<TExam> detail(@Valid TExamIdParam tExamIdParam) {
+    public CommonResult<TExamVo> detail(@Valid TExamIdParam tExamIdParam) {
         return CommonResult.data(tExamService.detail(tExamIdParam));
     }
 

+ 3 - 3
snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/controller/student/TExamController.java

@@ -25,10 +25,10 @@ import org.springframework.web.bind.annotation.RestController;
 import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
 import vip.xiaonuo.common.pojo.CommonResult;
 import vip.xiaonuo.exam.base.BaseApiController;
-import vip.xiaonuo.exam.domain.TExam;
 import vip.xiaonuo.exam.domain.exam.TExamIdParam;
 import vip.xiaonuo.exam.domain.exam.TExamPageParam;
 import vip.xiaonuo.exam.service.TExamService;
+import vip.xiaonuo.exam.vo.TExamVo;
 
 import javax.annotation.Resource;
 import javax.validation.Valid;
@@ -59,7 +59,7 @@ public class TExamController extends BaseApiController {
     @ApiOperation("获取考试表分页")
     @SaCheckPermission("/api/admin/s_exam/page")
     @GetMapping("/page")
-    public CommonResult<Page<TExam>> page(TExamPageParam tExamPageParam) {
+    public CommonResult<Page<TExamVo>> page(TExamPageParam tExamPageParam) {
          tExamPageParam.setUserId(StpLoginUserUtil.getLoginUser().getId());
         return CommonResult.data(tExamService.page(tExamPageParam));
     }
@@ -74,7 +74,7 @@ public class TExamController extends BaseApiController {
     @ApiOperation("获取考试表详情")
     @SaCheckPermission("/api/admin/s_exam/detail")
     @GetMapping("/detail")
-    public CommonResult<TExam> detail(@Valid TExamIdParam tExamIdParam) {
+    public CommonResult<TExamVo> detail(@Valid TExamIdParam tExamIdParam) {
         return CommonResult.data(tExamService.detail(tExamIdParam));
     }
 

+ 31 - 0
snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/domain/Question.java

@@ -77,6 +77,37 @@ public class Question implements Serializable {
 
     private String shortTitle;
 
+    private Integer majorId;
+
+    private String semesterId;
+
+    private String courseId;
+
+
+    public Integer getMajorId() {
+        return majorId;
+    }
+
+    public void setMajorId(Integer majorId) {
+        this.majorId = majorId;
+    }
+
+    public String getSemesterId() {
+        return semesterId;
+    }
+
+    public void setSemesterId(String semesterId) {
+        this.semesterId = semesterId;
+    }
+
+    public String getCourseId() {
+        return courseId;
+    }
+
+    public void setCourseId(String courseId) {
+        this.courseId = courseId;
+    }
+
     public Integer getId() {
         return id;
     }

+ 11 - 1
snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/domain/TExam.java

@@ -16,7 +16,7 @@ import com.baomidou.mybatisplus.annotation.*;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Getter;
 import lombok.Setter;
-import java.math.BigDecimal;
+
 import java.util.Date;
 
 /**
@@ -91,4 +91,14 @@ public class TExam {
     /** 考试类型 1 考试 2 章节测验 3 调查问卷  */
     @ApiModelProperty(value = "考试类型", position = 15)
     private String examType;
+
+    @ApiModelProperty(value = "专业id", position = 15)
+    private String majorId;
+    @ApiModelProperty(value = "学期id", position = 15)
+    private String semesterId;
+    @ApiModelProperty(value = "课程id", position = 15)
+    private String courseId;
+
+
+
 }

+ 5 - 3
snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/domain/exam/TExamAddParam.java

@@ -18,9 +18,6 @@ import io.swagger.annotations.ApiModelProperty;
 import lombok.Getter;
 import lombok.Setter;
 
-import javax.validation.constraints.NotBlank;
-import javax.validation.constraints.NotNull;
-import java.math.BigDecimal;
 import java.util.Date;
 
 /**
@@ -81,4 +78,9 @@ public class TExamAddParam {
     @ApiModelProperty(value = "课时ID", position = 14)
     private String hourId;
 
+    @ApiModelProperty(value = "专业id", position = 15)
+    private String majorId;
+
+    @ApiModelProperty(value = "学期id", position = 15)
+    private String semesterId;
 }

+ 7 - 2
snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/domain/exam/TExamEditParam.java

@@ -18,9 +18,7 @@ import io.swagger.annotations.ApiModelProperty;
 import lombok.Getter;
 import lombok.Setter;
 
-import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotNull;
-import java.math.BigDecimal;
 import java.util.Date;
 
 /**
@@ -76,4 +74,11 @@ public class TExamEditParam {
 
     @ApiModelProperty(value = "任务ID", position = 13)
     private String jobId;
+
+
+    @ApiModelProperty(value = "专业id", position = 15)
+    private String majorId;
+
+    @ApiModelProperty(value = "学期id", position = 15)
+    private String semesterId;
 }

+ 7 - 1
snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/domain/exam/TExamPageParam.java

@@ -17,7 +17,7 @@ import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Getter;
 import lombok.Setter;
-import java.math.BigDecimal;
+
 import java.util.Date;
 
 /**
@@ -83,4 +83,10 @@ public class TExamPageParam {
     /** 考试类型 1 考试 2 章节测验 3 调查问卷  */
     @ApiModelProperty(value = "考试类型", position = 12)
     private String examType;
+
+    @ApiModelProperty(value = "专业id", position = 15)
+    private String majorId;
+
+    @ApiModelProperty(value = "学期id", position = 15)
+    private String semesterId;
 }

+ 4 - 1
snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/mapper/QuestionMapper.java

@@ -6,6 +6,7 @@ import vip.xiaonuo.exam.domain.Question;
 import vip.xiaonuo.exam.viewmodel.admin.question.QuestionPageRequestVM;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
+import vip.xiaonuo.exam.vo.QuestionVo;
 
 import java.util.Date;
 import java.util.List;
@@ -13,11 +14,13 @@ import java.util.List;
 @Mapper
 public interface QuestionMapper extends BaseMapper<Question> {
 
-    Page<Question> page(@Param("bo") QuestionPageRequestVM requestVM, @Param("page") Page page);
+    Page<QuestionVo> page(@Param("bo") QuestionPageRequestVM requestVM, @Param("page") Page page);
 
     List<Question> selectByIds(@Param("ids") List<Integer> ids);
 
     Integer selectAllCount();
 
     List<KeyValue> selectCountByDate(@Param("startTime") Date startTime,@Param("endTime") Date endTime);
+
+    Question detail(Integer questionId);
 }

+ 7 - 0
snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/mapper/TExamMapper.java

@@ -13,7 +13,11 @@
 package vip.xiaonuo.exam.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Param;
 import vip.xiaonuo.exam.domain.TExam;
+import vip.xiaonuo.exam.domain.exam.TExamPageParam;
+import vip.xiaonuo.exam.vo.TExamVo;
 
 /**
  * 考试表Mapper接口
@@ -22,4 +26,7 @@ import vip.xiaonuo.exam.domain.TExam;
  * @date  2025/07/22 10:51
  **/
 public interface TExamMapper extends BaseMapper<TExam> {
+    Page<TExamVo> queryList(@Param("page") Page<Object> objectPage, @Param("tExamPageParam") TExamPageParam tExamPageParam);
+
+    TExamVo detail(String id);
 }

+ 89 - 11
snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/mapper/mapping/QuestionMapper.xml

@@ -84,6 +84,15 @@
       <if test="deleted != null">
         deleted,
       </if>
+      <if test="majorId != null">
+        MAJOR_ID,
+      </if>
+      <if test="semesterId != null">
+        SEMESTER_ID,
+      </if>
+      <if test="courseId != null">
+        COURSE_ID
+      </if>
     </trim>
     <trim prefix="values (" suffix=")" suffixOverrides=",">
       <if test="id != null">
@@ -125,6 +134,15 @@
       <if test="deleted != null">
         #{deleted,jdbcType=BIT},
       </if>
+      <if test="majorId != null">
+         #{majorId},
+      </if>
+      <if test="semesterId != null">
+         #{semesterId},
+      </if>
+      <if test="courseId != null">
+         #{courseId}
+      </if>
     </trim>
   </insert>
   <update id="updateByPrimaryKeySelective" parameterType="vip.xiaonuo.exam.domain.Question">
@@ -166,6 +184,16 @@
       <if test="deleted != null">
         deleted = #{deleted,jdbcType=BIT},
       </if>
+
+      <if test="majorId != null">
+        MAJOR_ID = #{majorId},
+      </if>
+      <if test="semesterId != null">
+        SEMESTER_ID = #{semesterId},
+      </if>
+      <if test="courseId != null">
+        COURSE_ID = #{courseId}
+      </if>
     </set>
     where id = #{id,jdbcType=INTEGER}
   </update>
@@ -191,32 +219,58 @@
 
 
 
-  <select id="page" resultMap="BaseResultMap" parameterType="vip.xiaonuo.exam.viewmodel.admin.question.QuestionPageRequestVM">
+  <select id="page" resultType="vip.xiaonuo.exam.vo.QuestionVo" parameterType="vip.xiaonuo.exam.viewmodel.admin.question.QuestionPageRequestVM">
     SELECT
-    <include refid="Base_Column_List"/>
-    FROM t_question
+      a.id,
+      a.question_type questionType,
+      a.subject_id subjectId,
+      a.score score,
+      a.grade_level gradeLevel,
+      a.difficult difficult,
+      a.correct,
+      a.info_text_content_id infoTextContentId,
+      a.create_user createUser,
+      a.status,
+      a.BANK_TYPE bankType,
+      a.create_time createTime,
+      a.deleted deleted,
+      a.major_id majorId,
+      b.major_name majorName,
+      a.semester_id semesterId,
+      c.name semesterName,
+      a.course_id
+    FROM
+    t_question a
+    LEFT JOIN "major" b ON   a.MAJOR_ID = b."id"
+    LEFT JOIN SEMESTER c ON  a.SEMESTER_ID = c.ID
     <where>
-        and deleted=0
       <if test="bo.id != null ">
-        and id= #{bo.id}
+        and a.id= #{bo.id}
       </if>
       <if test="bo.level != null ">
-        and grade_level= #{bo.level}
+        and a.grade_level= #{bo.level}
       </if>
       <if test="bo.subjectId != null ">
-        and subject_id= #{bo.subjectId}
+        and a.subject_id= #{bo.subjectId}
       </if>
       <if test="bo.questionType != null ">
-        and question_type= #{bo.questionType}
+        and a.question_type= #{bo.questionType}
       </if>
       <if test="bo.content != null">
-        and info_text_content_id in (SELECT id FROM t_text_content WHERE content like concat('%',#{bo.content},'%') )
+        and a.info_text_content_id in (SELECT id FROM t_text_content WHERE content like concat('%',#{bo.content},'%') )
       </if>
       <if test="bo.bankType != null">
-        and BANK_TYPE = #{bo.bankType}
+        and a.BANK_TYPE = #{bo.bankType}
+      </if>
+      <if test="bo.semesterId != null">
+        and a.semester_id = #{semesterId}
+      </if>
+      <if test="bo.majorId != null">
+        and a.major_id = #{majorId}
       </if>
+      and a.deleted=0
     </where>
-    order by create_time desc
+    order by a.create_time desc
   </select>
 
 
@@ -245,4 +299,28 @@
 		GROUP BY create_time
 	</select>
 
+
+  <select id="detail" resultType="vip.xiaonuo.exam.domain.Question">
+    SELECT
+      "id",
+      "question_type",
+      "subject_id",
+      "score",
+      "grade_level",
+      "difficult",
+      "correct",
+      "info_text_content_id",
+      "create_user",
+      "status",
+      "create_time",
+      "deleted",
+      BANK_TYPE,
+      MAJOR_ID,
+      SEMESTER_ID,
+      COURSE_ID
+    FROM
+      ONLINEEDU."t_question"
+    where id=#{questionId}
+  </select>
+
 </mapper>

+ 75 - 1
snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/mapper/mapping/TExamMapper.xml

@@ -1,5 +1,79 @@
 <?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="vip.xiaonuo.exam.modular.exam.mapper.TExamMapper">
+<mapper namespace="vip.xiaonuo.exam.mapper.TExamMapper">
+   <select id="queryList" resultType="vip.xiaonuo.exam.vo.TExamVo">
+       SELECT
+           a.ID id,
+           a.EXAM_NAME examName,
+           a.STUDENT_IDS studentIds,
+           a.EXAM_STATUS examStatus,
+           a.CREATE_TIME createTime,
+           a.CREATE_USER createUser,
+           a.UPDATE_TIME updateTime,
+           a.CHAPTER_ID chapterId,
+           a.START_TIME startTime,
+           a.END_TIME endTime,
+           a.PAPER_ID paperId,
+           a.DELETED deleted,
+           a.START_JOB_ID startJobId,
+           a.END_JOB_ID endJobId,
+           a.EXAM_TYPE examType,
+           a.MAJOR_ID majorId,
+           a.SEMESTER_ID semesterId,
+           b.major_name majorName,
+           c.name semesterName,
+           a.course_id courseId
+       FROM
+           ONLINEEDU.T_EXAM a
+       LEFT JOIN "major" b ON a.MAJOR_ID =b."id"
+       LEFT JOIN  SEMESTER c ON a.SEMESTER_ID =c.ID
+    <where>
+       <if test="tExamPageParam.examName != null and tExamPageParam.examName != ''">
+           a.EXAM_NAME like '%'||#{tExamPageParam.examName}||'%'
+       </if>
+        <if test="tExamPageParam.examStatus != null and tExamPageParam.examStatus != ''">
+            and a.EXAM_STATUS = #{tExamPageParam.examStatus}
+        </if>
+        <if test="tExamPageParam.semesterId != null and tExamPageParam.semesterId != ''">
+            and a.SEMESTER_ID = #{tExamPageParam.semesterId}
+        </if>
+        <if test="tExamPageParam.majorId != null and tExamPageParam.majorId != ''">
+            and a.MAJOR_ID = #{tExamPageParam.majorId}
+        </if>
+        <if test="tExamPageParam.examType != null and tExamPageParam.examType != ''">
+            and a.EXAM_TYPE = #{tExamPageParam.examType}
+        </if>
+        and  a.DELETED=0
+    </where>
+    order by a.CREATE_TIME desc
+   </select>
 
+    <select id="detail" resultType="vip.xiaonuo.exam.vo.TExamVo">
+        SELECT
+            a.ID id,
+            a.EXAM_NAME examName,
+            a.STUDENT_IDS studentIds,
+            a.EXAM_STATUS examStatus,
+            a.CREATE_TIME createTime,
+            a.CREATE_USER createUser,
+            a.UPDATE_TIME updateTime,
+            a.CHAPTER_ID chapterId,
+            a.START_TIME startTime,
+            a.END_TIME endTime,
+            a.PAPER_ID paperId,
+            a.DELETED deleted,
+            a.START_JOB_ID startJobId,
+            a.END_JOB_ID endJobId,
+            a.EXAM_TYPE examType,
+            a.MAJOR_ID majorId,
+            a.SEMESTER_ID semesterId,
+            b.major_name majorName,
+            c.name semesterName,
+            a.course_id courseId
+        FROM
+            ONLINEEDU.T_EXAM a
+        LEFT JOIN "major" b ON a.MAJOR_ID =b."id"
+        LEFT JOIN  SEMESTER c ON a.SEMESTER_ID =c.ID
+        where a.ID=#{id}
+    </select>
 </mapper>

+ 2 - 2
snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/service/QuestionService.java

@@ -7,13 +7,13 @@ import vip.xiaonuo.auth.core.pojo.SaBaseLoginUser;
 import vip.xiaonuo.exam.domain.Question;
 import vip.xiaonuo.exam.viewmodel.admin.question.QuestionEditRequestVM;
 import vip.xiaonuo.exam.viewmodel.admin.question.QuestionPageRequestVM;
-import com.github.pagehelper.PageInfo;
+import vip.xiaonuo.exam.vo.QuestionVo;
 
 import java.util.List;
 
 public interface QuestionService extends BaseService<Question> {
 
-    Page<Question> page(QuestionPageRequestVM requestVM);
+    Page<QuestionVo> page(QuestionPageRequestVM requestVM);
 
     Question insertFullQuestion(QuestionEditRequestVM model, String userId);
 

+ 3 - 2
snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/service/TExamService.java

@@ -19,6 +19,7 @@ import vip.xiaonuo.exam.domain.exam.TExamAddParam;
 import vip.xiaonuo.exam.domain.exam.TExamEditParam;
 import vip.xiaonuo.exam.domain.exam.TExamIdParam;
 import vip.xiaonuo.exam.domain.exam.TExamPageParam;
+import vip.xiaonuo.exam.vo.TExamVo;
 
 
 import java.util.List;
@@ -37,7 +38,7 @@ public interface TExamService extends IService<TExam> {
      * @author ZSS
      * @date  2025/07/22 10:51
      */
-    Page<TExam> page(TExamPageParam tExamPageParam);
+    Page<TExamVo> page(TExamPageParam tExamPageParam);
 
     /**
      * 添加考试表
@@ -69,7 +70,7 @@ public interface TExamService extends IService<TExam> {
      * @author ZSS
      * @date  2025/07/22 10:51
      */
-    TExam detail(TExamIdParam tExamIdParam);
+    TExamVo detail(TExamIdParam tExamIdParam);
 
     /**
      * 获取考试表详情

+ 5 - 10
snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/service/impl/ExamPaperServiceImpl.java

@@ -2,12 +2,8 @@ package vip.xiaonuo.exam.service.impl;
 
 
 import cn.hutool.core.bean.BeanUtil;
-import cn.hutool.core.map.MapUtil;
-import com.alibaba.fastjson.JSONArray;
-import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
-import com.github.pagehelper.PageHelper;
-import com.github.pagehelper.PageInfo;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import lombok.extern.slf4j.Slf4j;
 import org.modelmapper.ModelMapper;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -15,7 +11,10 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import vip.xiaonuo.auth.core.pojo.SaBaseLoginUser;
 import vip.xiaonuo.exam.api.CourseChapterPaperApi;
-import vip.xiaonuo.exam.domain.*;
+import vip.xiaonuo.exam.domain.CourseChapterPaper;
+import vip.xiaonuo.exam.domain.ExamPaper;
+import vip.xiaonuo.exam.domain.Question;
+import vip.xiaonuo.exam.domain.TextContent;
 import vip.xiaonuo.exam.domain.enums.ExamPaperTypeEnum;
 import vip.xiaonuo.exam.domain.exam.ExamPaperQuestionItemObject;
 import vip.xiaonuo.exam.domain.exam.ExamPaperTitleItemObject;
@@ -31,20 +30,16 @@ import vip.xiaonuo.exam.utility.ModelMapperSingle;
 import vip.xiaonuo.exam.viewmodel.admin.exam.ExamPaperEditRequestVM;
 import vip.xiaonuo.exam.viewmodel.admin.exam.ExamPaperPageRequestVM;
 import vip.xiaonuo.exam.viewmodel.admin.exam.ExamPaperTitleItemVM;
-import vip.xiaonuo.exam.viewmodel.admin.exam.ExamResponseVM;
 import vip.xiaonuo.exam.viewmodel.admin.question.QuestionEditRequestVM;
 import vip.xiaonuo.exam.viewmodel.student.dashboard.PaperFilter;
 import vip.xiaonuo.exam.viewmodel.student.dashboard.PaperInfo;
 import vip.xiaonuo.exam.viewmodel.student.exam.ExamPaperPageVM;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 
 import javax.annotation.Resource;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 
-import static vip.xiaonuo.exam.domain.enums.ExamPaperTypeEnum.Task;
-
 @Slf4j
 @Service
 public class ExamPaperServiceImpl extends BaseServiceImpl<ExamPaper> implements ExamPaperService, CourseChapterPaperApi {

+ 45 - 39
snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/service/impl/QuestionServiceImpl.java

@@ -2,22 +2,29 @@ package vip.xiaonuo.exam.service.impl;
 
 import cn.hutool.core.collection.ListUtil;
 import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.ObjectUtil;
 import com.alibaba.excel.EasyExcel;
-import com.alibaba.excel.EasyExcelFactory;
-import com.alibaba.excel.support.ExcelTypeEnum;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import org.springframework.transaction.interceptor.TransactionAspectSupport;
+import org.modelmapper.ModelMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
 import vip.xiaonuo.auth.core.pojo.SaBaseLoginUser;
 import vip.xiaonuo.dev.api.DevDictApi;
+import vip.xiaonuo.disk.domain.Major;
+import vip.xiaonuo.disk.domain.Semester;
+import vip.xiaonuo.disk.mapper.MajorMapper;
+import vip.xiaonuo.disk.mapper.SemesterMapper;
 import vip.xiaonuo.exam.domain.ExamPaper;
-import vip.xiaonuo.exam.domain.other.KeyValue;
 import vip.xiaonuo.exam.domain.Question;
 import vip.xiaonuo.exam.domain.TextContent;
 import vip.xiaonuo.exam.domain.enums.QuestionStatusEnum;
 import vip.xiaonuo.exam.domain.enums.QuestionTypeEnum;
+import vip.xiaonuo.exam.domain.other.KeyValue;
 import vip.xiaonuo.exam.domain.question.QuestionExcel;
 import vip.xiaonuo.exam.domain.question.QuestionItemObject;
 import vip.xiaonuo.exam.domain.question.QuestionObject;
@@ -25,27 +32,21 @@ import vip.xiaonuo.exam.mapper.QuestionMapper;
 import vip.xiaonuo.exam.service.QuestionService;
 import vip.xiaonuo.exam.service.SubjectService;
 import vip.xiaonuo.exam.service.TextContentService;
-import vip.xiaonuo.exam.utility.*;
+import vip.xiaonuo.exam.utility.DateTimeUtil;
+import vip.xiaonuo.exam.utility.ExamUtil;
+import vip.xiaonuo.exam.utility.JsonUtil;
+import vip.xiaonuo.exam.utility.ModelMapperSingle;
 import vip.xiaonuo.exam.viewmodel.admin.question.QuestionEditItemVM;
 import vip.xiaonuo.exam.viewmodel.admin.question.QuestionEditRequestVM;
 import vip.xiaonuo.exam.viewmodel.admin.question.QuestionPageRequestVM;
-import com.github.pagehelper.PageHelper;
-import com.github.pagehelper.PageInfo;
-import org.modelmapper.ModelMapper;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
+import vip.xiaonuo.exam.vo.QuestionVo;
 
+import javax.annotation.Resource;
 import java.io.File;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
 import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
-import cn.hutool.core.util.NumberUtil;
-
-import javax.annotation.Resource;
 
 import static cn.hutool.core.date.DateTime.now;
 
@@ -60,6 +61,13 @@ public class QuestionServiceImpl extends BaseServiceImpl<Question> implements Qu
     @Resource
     private DevDictApi devDictApi;
 
+    @Resource
+    private  MajorMapper majorMapper;
+    @Resource
+    private SemesterMapper semesterMapper;
+
+
+
     @Autowired
     public QuestionServiceImpl(QuestionMapper questionMapper, TextContentService textContentService, SubjectService subjectService) {
         super(questionMapper);
@@ -69,7 +77,7 @@ public class QuestionServiceImpl extends BaseServiceImpl<Question> implements Qu
     }
 
     @Override
-    public Page<Question> page(QuestionPageRequestVM requestVM) {
+    public Page<QuestionVo> page(QuestionPageRequestVM requestVM) {
         Page<ExamPaper> page = new Page<ExamPaper>(requestVM.getCurrent(), requestVM.getSize());
         page.setSearchCount(true); // 设置计算总记录数
         return questionMapper.page(requestVM,page);
@@ -80,12 +88,6 @@ public class QuestionServiceImpl extends BaseServiceImpl<Question> implements Qu
     @Transactional
     public Question insertFullQuestion(QuestionEditRequestVM model, String userId) {
         Date now = new Date();
-        Integer gradeLevel = null;
-        if(model.getSubjectId() != null){
-            gradeLevel = subjectService.levelBySubjectId(model.getSubjectId());
-        }
-
-
         //题干、解析、选项等 插入
         TextContent infoTextContent = new TextContent();
         infoTextContent.setCreateTime(now);
@@ -93,19 +95,13 @@ public class QuestionServiceImpl extends BaseServiceImpl<Question> implements Qu
         textContentService.insertByFilter(infoTextContent);
 
         Question question = new Question();
-        if(model.getSubjectId() != null){
-            question.setSubjectId(model.getSubjectId());
-        }
-        if(gradeLevel != null){
-            question.setGradeLevel(gradeLevel);
-        }
         question.setCreateTime(now);
         question.setQuestionType(model.getQuestionType());
         question.setStatus(QuestionStatusEnum.OK.getCode());
         question.setCorrectFromVM(model.getCorrect(), model.getCorrectArray());
         int score = 0;
         if(model.getScore() != null && !model.getScore().isEmpty()){
-            score = ExamUtil.scoreFromVM(model.getScore());
+            score = Integer.valueOf(model.getScore());
         }
         question.setScore(score);
         question.setDifficult(model.getDifficult() ==null?0:model.getDifficult());
@@ -113,6 +109,9 @@ public class QuestionServiceImpl extends BaseServiceImpl<Question> implements Qu
         question.setBankType(model.getBankType());
         question.setCreateUser(userId);
         question.setDeleted(false);
+        question.setMajorId(model.getMajorId());
+        question.setCourseId(model.getCourseId());
+        question.setSemesterId(model.getSemesterId());
         questionMapper.insertSelective(question);
         return question;
     }
@@ -120,19 +119,17 @@ public class QuestionServiceImpl extends BaseServiceImpl<Question> implements Qu
     @Override
     @Transactional
     public Question updateFullQuestion(QuestionEditRequestVM model) {
-        Question question = questionMapper.selectByPrimaryKey(model.getId());
-        Integer gradeLevel = null;
-        if(model.getSubjectId() != null){
-            gradeLevel = subjectService.levelBySubjectId(model.getSubjectId());
-            question.setGradeLevel(gradeLevel);
-            question.setSubjectId(model.getSubjectId());
-        }
-        question.setScore(ExamUtil.scoreFromVM(model.getScore()));
+        Question question = questionMapper.detail(model.getId());
+
+        question.setScore(Integer.valueOf(model.getScore()));
         question.setDifficult(model.getDifficult());
         question.setCorrectFromVM(model.getCorrect(), model.getCorrectArray());
         if(model.getBankType() != null){
             question.setBankType(model.getBankType());
         }
+        question.setMajorId(model.getMajorId());
+        question.setCourseId(model.getCourseId());
+        question.setSemesterId(model.getSemesterId());
         questionMapper.updateByPrimaryKeySelective(question);
 
         //题干、解析、选项等 更新
@@ -146,7 +143,7 @@ public class QuestionServiceImpl extends BaseServiceImpl<Question> implements Qu
     @Override
     public QuestionEditRequestVM getQuestionEditRequestVM(Integer questionId) {
         //题目映射
-        Question question = questionMapper.selectByPrimaryKey(questionId);
+        Question question = questionMapper.detail(questionId);
         return getQuestionEditRequestVM(question);
     }
 
@@ -191,6 +188,15 @@ public class QuestionServiceImpl extends BaseServiceImpl<Question> implements Qu
             return questionEditItemVM;
         }).collect(Collectors.toList());
         questionEditRequestVM.setItems(editItems);
+        if(ObjectUtil.isNotEmpty(question.getMajorId())){
+            Major major = majorMapper.selectById(question.getMajorId());
+            questionEditRequestVM.setMajorName(major.getMajorName());
+        }
+        if(ObjectUtil.isNotEmpty(question.getSemesterId())){
+            Semester semester = semesterMapper.selectById(question.getSemesterId());
+            questionEditRequestVM.setSemesterName(semester.getName());
+        }
+
         return questionEditRequestVM;
     }
 

+ 19 - 69
snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/service/impl/TExamServiceImpl.java

@@ -15,21 +15,18 @@ package vip.xiaonuo.exam.service.impl;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollStreamUtil;
 import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSONObject;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-import vip.xiaonuo.common.enums.CommonSortOrderEnum;
 import vip.xiaonuo.common.exception.CommonException;
 import vip.xiaonuo.common.page.CommonPageRequest;
 import vip.xiaonuo.dev.api.DevJobApi;
 import vip.xiaonuo.disk.api.NetDiskApi;
-import vip.xiaonuo.exam.domain.CourseChapterPaper;
 import vip.xiaonuo.exam.domain.ExamPaper;
 import vip.xiaonuo.exam.domain.TExam;
 import vip.xiaonuo.exam.domain.enums.ExamPaperTypeEnum;
@@ -42,9 +39,11 @@ import vip.xiaonuo.exam.mapper.TExamMapper;
 import vip.xiaonuo.exam.service.ExamPaperService;
 import vip.xiaonuo.exam.service.TExamService;
 import vip.xiaonuo.exam.utility.DateTimeUtil;
+import vip.xiaonuo.exam.vo.TExamVo;
 
 import javax.annotation.Resource;
 import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * 考试表Service接口实现类
@@ -68,35 +67,15 @@ public class TExamServiceImpl extends ServiceImpl<TExamMapper, TExam> implements
     @Resource
     private NetDiskApi netDiskApi;
 
+
+    @Resource
+    private TExamMapper tExamMapper;
+
+
     @Override
-    public Page<TExam> page(TExamPageParam tExamPageParam) {
-        QueryWrapper<TExam> queryWrapper = new QueryWrapper<>();
-        if(ObjectUtil.isNotEmpty(tExamPageParam.getExamName())) {
-            queryWrapper.lambda().like(TExam::getExamName, tExamPageParam.getExamName());
-        }
-        if(ObjectUtil.isNotEmpty(tExamPageParam.getExamStatus())) {
-            queryWrapper.lambda().eq(TExam::getExamStatus, tExamPageParam.getExamStatus());
-        }
-        if(ObjectUtil.isNotEmpty(tExamPageParam.getStartTime()) && ObjectUtil.isNotEmpty(tExamPageParam.getEndTime())) {
-            queryWrapper.lambda().between(TExam::getStartTime, tExamPageParam.getStartTime(), tExamPageParam.getEndTime());
-        }
-        if(ObjectUtil.isNotEmpty(tExamPageParam.getPaperId())) {
-            queryWrapper.lambda().eq(TExam::getPaperId, tExamPageParam.getPaperId());
-        }
-        if(ObjectUtil.isNotEmpty(tExamPageParam.getExamType())) {
-            queryWrapper.lambda().eq(TExam::getExamType, tExamPageParam.getExamType());
-        }
-       if(ObjectUtil.isNotEmpty(tExamPageParam.getUserId())){
-           queryWrapper.lambda().eq(TExam::getCreateUser, tExamPageParam.getUserId());
-        }
-        if(ObjectUtil.isAllNotEmpty(tExamPageParam.getSortField(), tExamPageParam.getSortOrder())) {
-            CommonSortOrderEnum.validate(tExamPageParam.getSortOrder());
-            queryWrapper.orderBy(true, tExamPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
-                    StrUtil.toUnderlineCase(tExamPageParam.getSortField()));
-        } else {
-            queryWrapper.lambda().orderByAsc(TExam::getId);
-        }
-        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
+    public Page<TExamVo> page(TExamPageParam tExamPageParam) {
+        Page<TExamVo> page = tExamMapper.queryList(CommonPageRequest.defaultPage(), tExamPageParam);
+        return page;
     }
 
     @Transactional(rollbackFor = Exception.class)
@@ -111,28 +90,16 @@ public class TExamServiceImpl extends ServiceImpl<TExamMapper, TExam> implements
 
         boolean query = false;
         Map<String, Object> map = new HashMap<>();
-        if(tExamAddParam.getChapterId() != null && !tExamAddParam.getChapterId().isEmpty()){
-            map.put("chapterId",tExamAddParam.getChapterId());
-            query = true;
-        }
-        if(tExamAddParam.getGradesId() != null && !tExamAddParam.getGradesId().isEmpty()){
-            map.put("gradesId",tExamAddParam.getGradesId());
-            query = true;
-        }
         if(tExamAddParam.getCourseId() != null && !tExamAddParam.getCourseId().isEmpty()){
             map.put("courseId",tExamAddParam.getCourseId());
             query = true;
         }
-        if(tExamAddParam.getHourId() != null && !tExamAddParam.getHourId().isEmpty()){
-            map.put("hourId",tExamAddParam.getHourId());
-            query = true;
-        }
         if(query){
             JSONObject students = netDiskApi.downList(map);
             if(students != null && students.getIntValue("code") == 200){
                 List<String> studentIds = new ArrayList<String>();
-                if(!students.getJSONArray("data").isEmpty()){
-                    students.getJSONArray("data").forEach(item -> {
+                if(!students.getJSONObject("data").getJSONArray("records").isEmpty()){
+                    students.getJSONObject("data").getJSONArray("records").forEach(item -> {
                         JSONObject student = (JSONObject) item;
                         studentIds.add(student.getString("ACCOUNT"));
                     });
@@ -154,13 +121,6 @@ public class TExamServiceImpl extends ServiceImpl<TExamMapper, TExam> implements
             }
         }
         this.save(tExam);
-        if(tExamAddParam.getChapterId() != null && !tExamAddParam.getChapterId().isEmpty()){
-            CourseChapterPaper cp = new CourseChapterPaper();
-            cp.setChapterId(tExamAddParam.getChapterId());
-            cp.setPaperId(tExamAddParam.getPaperId());
-            cp.setType("0"); // 章节测验
-            courseChapterPaperMapper.add(cp);
-        }
         if(tExamAddParam.getStartTime() != null && tExamAddParam.getEndTime() != null){
             Date currentTime = new Date(System.currentTimeMillis());
             // 开始时间与结束时间不能小于当前时间
@@ -186,18 +146,6 @@ public class TExamServiceImpl extends ServiceImpl<TExamMapper, TExam> implements
         }
 
         TExam tExam = this.queryEntity(tExamEditParam.getId().toString());
-        if(tExamEditParam.getChapterId() != null && !tExamEditParam.getChapterId().isEmpty()){
-            CourseChapterPaper cp = new CourseChapterPaper();
-            cp.setChapterId(tExam.getChapterId());
-            cp.setPaperId(tExam.getPaperId());
-            cp.setType("0"); // 章节测验
-            courseChapterPaperMapper.delete(cp);
-            cp.setChapterId(tExamEditParam.getChapterId());
-            cp.setPaperId(tExamEditParam.getPaperId());
-            courseChapterPaperMapper.add(cp);
-            tExam.setExamType("2"); // 2 章节测验
-        }
-
         if(tExamEditParam.getPaperId() != null && !tExamEditParam.getPaperId().isEmpty()){
             ExamPaper examPaper = examPaperService.selectById(Integer.parseInt(tExamEditParam.getPaperId()));
             if(ExamPaperTypeEnum.TimeLimit.getCode() == examPaper.getPaperType()){
@@ -257,13 +205,15 @@ public class TExamServiceImpl extends ServiceImpl<TExamMapper, TExam> implements
             }
             log.error("任务删除失败,{}",msg);
         }
-        // 执行删除
-        this.removeByIds(CollStreamUtil.toList(tExamIdParamList, TExamIdParam::getId));
+         List<Integer> ids = tExamIdParamList.stream().map(TExamIdParam::getId).collect(Collectors.toList());
+         this.update(new LambdaUpdateWrapper<TExam>()
+                .in(TExam::getId, ids)
+                .set(TExam::getDeleted, 1));
     }
 
     @Override
-    public TExam detail(TExamIdParam tExamIdParam) {
-        return this.queryEntity(tExamIdParam.getId().toString());
+    public TExamVo detail(TExamIdParam tExamIdParam) {
+        return tExamMapper.detail(tExamIdParam.getId().toString());
     }
 
     @Override

+ 63 - 3
snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/viewmodel/admin/question/QuestionEditRequestVM.java

@@ -1,10 +1,9 @@
 package vip.xiaonuo.exam.viewmodel.admin.question;
 
 
-import org.hibernate.validator.constraints.Range;
-
 import javax.validation.Valid;
-import javax.validation.constraints.*;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
 import java.util.List;
 
 
@@ -37,6 +36,67 @@ public class QuestionEditRequestVM {
 
     private String bankType;
 
+    private Integer majorId;
+
+    private String semesterId;
+
+    private String courseId;
+
+    private String semesterName;
+
+    private String majorName;
+
+    private String courseName;
+
+
+    public String getSemesterName() {
+        return semesterName;
+    }
+
+    public void setSemesterName(String semesterName) {
+        this.semesterName = semesterName;
+    }
+
+    public String getMajorName() {
+        return majorName;
+    }
+
+    public void setMajorName(String majorName) {
+        this.majorName = majorName;
+    }
+
+    public String getCourseName() {
+        return courseName;
+    }
+
+    public void setCourseName(String courseName) {
+        this.courseName = courseName;
+    }
+
+    public Integer getMajorId() {
+        return majorId;
+    }
+
+    public void setMajorId(Integer majorId) {
+        this.majorId = majorId;
+    }
+
+    public String getSemesterId() {
+        return semesterId;
+    }
+
+    public void setSemesterId(String semesterId) {
+        this.semesterId = semesterId;
+    }
+
+    public String getCourseId() {
+        return courseId;
+    }
+
+    public void setCourseId(String courseId) {
+        this.courseId = courseId;
+    }
+
     public Integer getId() {
         return id;
     }

+ 31 - 0
snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/viewmodel/admin/question/QuestionPageRequestVM.java

@@ -18,6 +18,37 @@ public class QuestionPageRequestVM extends BasePage {
 
     private String bankType;
 
+    private String majorId;
+
+    private String semesterId;
+
+    private String courseId;
+
+
+    public String getCourseId() {
+        return courseId;
+    }
+
+    public void setCourseId(String courseId) {
+        this.courseId = courseId;
+    }
+
+    public String getMajorId() {
+        return majorId;
+    }
+
+    public void setMajorId(String majorId) {
+        this.majorId = majorId;
+    }
+
+    public String getSemesterId() {
+        return semesterId;
+    }
+
+    public void setSemesterId(String semesterId) {
+        this.semesterId = semesterId;
+    }
+
     public Integer getId() {
         return id;
     }

+ 270 - 0
snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/vo/QuestionVo.java

@@ -0,0 +1,270 @@
+package vip.xiaonuo.exam.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import vip.xiaonuo.exam.domain.enums.QuestionTypeEnum;
+import vip.xiaonuo.exam.utility.ExamUtil;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+public class QuestionVo implements Serializable {
+
+    private static final long serialVersionUID = 8826266720383164363L;
+
+    private Integer id;
+
+    /**
+     * 	1.单选题 2.多选题 3.判断题 4.填空题 5.简答题
+     */
+    private Integer questionType;
+
+    /**
+     * 学科
+     */
+    private Integer subjectId;
+
+    /**
+     * 题目总分(千分制)
+     */
+    private Integer score;
+
+    private String scoreStr;
+
+    /**
+     * 级别
+     */
+    private Integer gradeLevel;
+
+    /**
+     * 题目难度
+     */
+    private Integer difficult;
+
+    /**
+     * 正确答案
+     */
+    private String correct;
+
+    /**
+     * 题目 填空、 题干、解析、答案等信息
+     */
+    private Integer infoTextContentId;
+
+    /**
+     * 题库类型 1练习题目库  2问卷题目库 3 考试题目库
+     */
+    private String bankType;
+
+
+    /**
+     * 创建人
+     */
+    private String createUser;
+
+    /**
+     * 1.正常
+     */
+    private Integer status;
+
+    /**
+     * 创建时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createTime;
+
+    private String createTimeStr;
+
+    private Boolean deleted;
+
+    private String shortTitle;
+
+    private Integer majorId;
+
+    private String semesterId;
+
+    private String courseId;
+
+    private String majorName;
+
+    private String semesterName;
+
+
+    public String getMajorName() {
+        return majorName;
+    }
+
+    public void setMajorName(String majorName) {
+        this.majorName = majorName;
+    }
+
+    public String getSemesterName() {
+        return semesterName;
+    }
+
+    public void setSemesterName(String semesterName) {
+        this.semesterName = semesterName;
+    }
+
+    public Integer getMajorId() {
+        return majorId;
+    }
+
+    public void setMajorId(Integer majorId) {
+        this.majorId = majorId;
+    }
+
+    public String getSemesterId() {
+        return semesterId;
+    }
+
+    public void setSemesterId(String semesterId) {
+        this.semesterId = semesterId;
+    }
+
+    public String getCourseId() {
+        return courseId;
+    }
+
+    public void setCourseId(String courseId) {
+        this.courseId = courseId;
+    }
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Integer getQuestionType() {
+        return questionType;
+    }
+
+    public void setQuestionType(Integer questionType) {
+        this.questionType = questionType;
+    }
+
+    public Integer getSubjectId() {
+        return subjectId;
+    }
+
+    public void setSubjectId(Integer subjectId) {
+        this.subjectId = subjectId;
+    }
+
+    public Integer getScore() {
+        return score;
+    }
+
+    public void setScore(Integer score) {
+        this.score = score;
+    }
+
+    public Integer getGradeLevel() {
+        return gradeLevel;
+    }
+
+    public void setGradeLevel(Integer gradeLevel) {
+        this.gradeLevel = gradeLevel;
+    }
+
+    public Integer getDifficult() {
+        return difficult;
+    }
+
+    public void setDifficult(Integer difficult) {
+        this.difficult = difficult;
+    }
+
+    public String getCorrect() {
+        return correct;
+    }
+
+    public void setCorrect(String correct) {
+        this.correct = correct == null ? null : correct.trim();
+    }
+
+    public Integer getInfoTextContentId() {
+        return infoTextContentId;
+    }
+
+    public void setInfoTextContentId(Integer infoTextContentId) {
+        this.infoTextContentId = infoTextContentId;
+    }
+
+    public String getCreateUser() {
+        return createUser;
+    }
+
+    public void setCreateUser(String createUser) {
+        this.createUser = createUser;
+    }
+
+    public Integer getStatus() {
+        return status;
+    }
+
+    public void setStatus(Integer status) {
+        this.status = status;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    public Boolean getDeleted() {
+        return deleted;
+    }
+
+    public void setDeleted(Boolean deleted) {
+        this.deleted = deleted;
+    }
+
+    public String getShortTitle() {
+        return shortTitle;
+    }
+
+    public void setShortTitle(String shortTitle) {
+        this.shortTitle = shortTitle;
+    }
+
+    public String getCreateTimeStr() {
+        return createTimeStr;
+    }
+
+    public void setCreateTimeStr(String createTimeStr) {
+        this.createTimeStr = createTimeStr;
+    }
+
+    public String getScoreStr() {
+        return scoreStr;
+    }
+
+    public void setScoreStr(String scoreStr) {
+        this.scoreStr = scoreStr;
+    }
+
+    public String getBankType() {
+        return bankType;
+    }
+
+    public void setBankType(String bankType) {
+        this.bankType = bankType;
+    }
+
+    public void setCorrectFromVM(String correct, List<String> correctArray) {
+        int qType = this.getQuestionType();
+        if (qType == QuestionTypeEnum.MultipleChoice.getCode()) {
+            String correctJoin = ExamUtil.contentToString(correctArray);
+            this.setCorrect(correctJoin);
+        } else {
+            this.setCorrect(correct);
+        }
+    }
+}

+ 97 - 0
snowy-plugin/snowy-plugin-exam/snowy-plugin-exam-func/src/main/java/vip/xiaonuo/exam/vo/TExamVo.java

@@ -0,0 +1,97 @@
+package vip.xiaonuo.exam.vo;
+
+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.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+@Getter
+@Setter
+public class TExamVo {
+
+    /** 主键 */
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "主键", position = 1)
+    private Integer id;
+
+    /** 考试标题 */
+    @ApiModelProperty(value = "考试标题", position = 2)
+    private String examName;
+
+    /** 参与考试的学生ID集合 */
+    @ApiModelProperty(value = "参与考试的学生ID集合", position = 3)
+    private String studentIds;
+
+    /** 考试状态 0 未开始 1已开始 2已结束 */
+    @ApiModelProperty(value = "考试状态 0 未开始 1已开始 2已结束", position = 4)
+    private Integer examStatus;
+
+    /** 创建时间 */
+    @ApiModelProperty(value = "创建时间", position = 5)
+    @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createTime;
+
+    /** 创建人ID */
+    @ApiModelProperty(value = "创建人ID", position = 6)
+    @TableField(fill = FieldFill.INSERT)
+    private String createUser;
+
+    /** 更新时间 */
+    @ApiModelProperty(value = "更新时间", position = 7)
+    @TableField(fill = FieldFill.UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updateTime;
+
+    /** 章节ID ,有此则为章节测验 */
+    @ApiModelProperty(value = "章节ID ,有此则为章节测验", position = 8)
+    private String chapterId;
+
+    /** 开始时间 */
+    @ApiModelProperty(value = "开始时间", position = 9)
+    private Date startTime;
+
+    /** 结束时间 */
+    @ApiModelProperty(value = "结束时间", position = 10)
+    private Date endTime;
+
+    /** 试卷ID */
+    @ApiModelProperty(value = "试卷ID", position = 11)
+    private String paperId;
+
+    /** 软删除 */
+    @ApiModelProperty(value = "软删除", position = 12)
+    private Integer deleted;
+
+    @ApiModelProperty(value = "开始任务ID", position = 13)
+    private String startJobId;
+
+    @ApiModelProperty(value = "结束任务ID", position = 14)
+    private String endJobId;
+
+    /** 考试类型 1 考试 2 章节测验 3 调查问卷  */
+    @ApiModelProperty(value = "考试类型", position = 15)
+    private String examType;
+
+    @ApiModelProperty(value = "专业id", position = 15)
+    private Integer majorId;
+
+    @ApiModelProperty(value = "学期id", position = 15)
+    private String semesterId;
+
+    @ApiModelProperty(value = "专业名称", position = 15)
+    private String majorName;
+
+    @ApiModelProperty(value = "学期名称", position = 15)
+    private String semesterName;
+
+    @ApiModelProperty(value = "课程id", position = 15)
+    private String courseId;
+
+}