Pārlūkot izejas kodu

1.课程中心相关接口
2.课程管理学生相关接口,相关增删改查,导入,模板
3.修复导入功能

honorfire 7 mēneši atpakaļ
vecāks
revīzija
2e9a1e38a4
23 mainītis faili ar 1304 papildinājumiem un 5 dzēšanām
  1. 25 0
      pom.xml
  2. 68 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/controller/CourseChapterController.java
  3. 45 2
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/controller/CourseInfoController.java
  4. 243 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/controller/CourseStudentRelateController.java
  5. 71 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/domain/CourseStudentRelate.java
  6. 34 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/domain/CourseStudentRelateEnum.java
  7. 10 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/CourseInfoMapper.java
  8. 41 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/CourseStudentRelateMapper.java
  9. 3 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/mapping/ClassHourMapper.xml
  10. 86 3
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/mapping/CourseInfoMapper.xml
  11. 52 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/mapping/CourseStudentRelateMapper.xml
  12. 41 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/param/coursestudentrelate/CourseStudentRelateAddParam.java
  13. 44 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/param/coursestudentrelate/CourseStudentRelateEditParam.java
  14. 35 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/param/coursestudentrelate/CourseStudentRelateIdParam.java
  15. 24 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/param/coursestudentrelate/CourseStudentRelateImportParam.java
  16. 49 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/param/coursestudentrelate/CourseStudentRelatePageParam.java
  17. 10 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/CourseInfoService.java
  18. 142 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/CourseStudentRelateService.java
  19. 12 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/impl/CourseInfoServiceImpl.java
  20. 253 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/impl/CourseStudentRelateServiceImpl.java
  21. BIN
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/resources/CourseStudentRelateTemplate.xlsx
  22. 9 0
      snowy-plugin/snowy-plugin-sys/snowy-plugin-sys-func/src/main/java/vip/xiaonuo/sys/modular/user/param/SysUserPageParam.java
  23. 7 0
      snowy-plugin/snowy-plugin-sys/snowy-plugin-sys-func/src/main/java/vip/xiaonuo/sys/modular/user/service/impl/SysUserServiceImpl.java

+ 25 - 0
pom.xml

@@ -545,6 +545,25 @@
                 <groupId>cn.afterturn</groupId>
                 <artifactId>easypoi-spring-boot-starter</artifactId>
                 <version>${easypoi.version}</version>
+                <exclusions>
+                    <!-- 排除旧版POI -->
+                    <exclusion>
+                        <groupId>org.apache.poi</groupId>
+                        <artifactId>poi</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>org.apache.poi</groupId>
+                        <artifactId>poi-ooxml</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>org.apache.poi</groupId>
+                        <artifactId>poi-ooxml-schemas</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>org.apache.poi</groupId>
+                        <artifactId>poi-scratchpad</artifactId>
+                    </exclusion>
+                </exclusions>
             </dependency>
 
             <!-- sm-crypto -->
@@ -560,6 +579,12 @@
                 <artifactId>easyexcel</artifactId>
                 <version>${easyexcel.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.poi</groupId>
+                <artifactId>poi</artifactId>
+                <version>4.1.2</version>
+            </dependency>
+
 
             <!-- sa-token-core -->
             <dependency>

+ 68 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/controller/CourseChapterController.java

@@ -20,6 +20,7 @@ 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.apache.commons.lang3.StringUtils;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -74,6 +75,7 @@ public class CourseChapterController {
     @GetMapping("/disk/chapter/page")
     public CommonResult<Page<Map<String,Object>>> page(ChapterPageParam chapterPageParam, HttpServletRequest req) {
         Map param =new HashMap();
+        if(StringUtils.isEmpty(req.getParameter("courseId")))return CommonResult.error("课程id不能为空");
         param.put("courseId", req.getParameter("courseId"));
         param.put("name", req.getParameter("name"));
         //查回章节信息
@@ -139,6 +141,7 @@ public class CourseChapterController {
     @GetMapping("/disk/chapter/allList")
     public CommonResult<List<Map<String,Object>>> allList(ChapterPageParam chapterPageParam, HttpServletRequest req) {
         Map param =new HashMap();
+        if(StringUtils.isEmpty(req.getParameter("courseId")))return CommonResult.error("课程id不能为空");
         param.put("courseId", req.getParameter("courseId"));
         param.put("name", req.getParameter("name"));
         List<Map<String,Object>> chapterList=chapterService.queryAllList(param);
@@ -257,4 +260,69 @@ public class CourseChapterController {
         return CommonResult.data(result);
     }
 
+    /**
+     * 课程章中心-全量列表(学生端)
+     *
+     * @author pans
+     * @date  2025/07/02 15:34
+     */
+    @ApiOperationSupport(order = 1)
+    @ApiOperation("课程章中心-全量列表(学生端)")
+    @SaCheckPermission("/disk/coursecentry/coursechapterList")
+    @GetMapping("/disk/coursecentry/coursechapterList")
+    public CommonResult<List<Map<String,Object>>> coursechapterList(ChapterPageParam chapterPageParam, HttpServletRequest req) {
+        Map param =new HashMap();
+        if(StringUtils.isEmpty(req.getParameter("courseId")))return CommonResult.error("课程id不能为空");
+        param.put("courseId", req.getParameter("courseId"));
+        param.put("name", req.getParameter("name"));
+        List<Map<String,Object>> chapterList=chapterService.queryAllList(param);
+        //挂上所有章节的课时信息
+        //先取出所有章节id
+        List<String> chapterIdList=  chapterList.stream().map(map -> (String) map.get("id")).collect(Collectors.toList());
+        param.clear();
+        param.put("chapterIdList", chapterIdList);
+        //只查出资源审核通过的课时
+        param.put("verifyPass", "1");
+        List<Map<String,Object>> classHourList =classHourService.queryAllList(param);
+        // 1. 准备结果:为每个章节添加classHours字段
+        for (Map<String, Object> chapter : chapterList) {
+            if (chapter == null || chapter.get("id") == null) continue;
+
+            String chapterId = chapter.get("id").toString();
+            List<Map<String, Object>> chapterClassHours = new ArrayList<>();
+
+            // 2. 倒序遍历课程列表(关键点!)
+            for (int i = classHourList.size() - 1; i >= 0; i--) {
+                Map<String, Object> classHour = classHourList.get(i);
+                if (classHour == null || classHour.get("chapterId") == null) continue;
+
+                // 3. 匹配当前章节
+                if (chapterId.equals(classHour.get("chapterId").toString())) {
+                    chapterClassHours.add(classHour);  // 添加到章节
+                    classHourList.remove(i);          // 从原列表删除(安全操作)
+                }
+            }
+
+            chapter.put("classHours", chapterClassHours);
+        }
+//        //按chapterId分组课程
+//        Map<String, List<Map<String, Object>>> classHourByChapter = classHourList.stream()
+//                .filter(Objects::nonNull)
+//                .filter(classHour -> classHour.get("chapterId") != null)
+//                .collect(Collectors.groupingBy(
+//                        classHour -> classHour.get("chapterId").toString()
+//                ));
+//
+//        //为每个章节添加对应的课程列表
+//        chapterList.stream()
+//                .filter(Objects::nonNull)
+//                .filter(chapter -> chapter.get("id") != null)
+//                .forEach(chapter -> {
+//                    String chapterId = chapter.get("id").toString();
+//                    chapter.put("classHours",
+//                            classHourByChapter.getOrDefault(chapterId, Collections.emptyList()));
+//                });
+        return CommonResult.data(chapterList);
+    }
+
 }

+ 45 - 2
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/controller/CourseInfoController.java

@@ -25,6 +25,7 @@ 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.auth.core.util.StpLoginUserUtil;
 import vip.xiaonuo.common.annotation.CommonLog;
 import vip.xiaonuo.common.pojo.CommonResult;
 import vip.xiaonuo.common.pojo.CommonValidList;
@@ -77,8 +78,6 @@ public class CourseInfoController {
         param.put("courseType", req.getParameter("courseType"));
         //排序类型,0最新,1热门
         param.put("sortflag", req.getParameter("sortflag"));
-        //格式类型,待定
-        param.put("suffixType", req.getParameter("suffixType"));
 
         Page<Map<String,Object>> list=courseInfoService.queryList(param);
         return CommonResult.data(list);
@@ -218,4 +217,48 @@ public class CourseInfoController {
         return CommonResult.data(result);
     }
 
+    /**
+     * 课程中心-分页列表(学生端)
+     *
+     * @author honorfire
+     * @date  2025/06/20 15:00
+     */
+    @ApiOperationSupport(order = 1)
+    @ApiOperation("课程中心-分页列表(学生端)")
+    @SaCheckPermission("/disk/coursecentry/page")
+    @GetMapping("/disk/coursecentry/page")
+    public CommonResult<Page<Map<String,Object>>> coursecentryPage(CourseInfoPageParam courseInfoPageParam, HttpServletRequest req) {
+        Map param =new HashMap(6);
+        //查询学生自己的课程
+        param.put("userId", StpLoginUserUtil.getLoginUser().getId());
+        param.put("courseName", req.getParameter("courseName"));
+        param.put("collegeId", req.getParameter("collegeId"));
+        param.put("majorId", req.getParameter("majorId"));
+        param.put("courseType", req.getParameter("courseType"));
+        //排序类型,0最新,1热门
+        param.put("sortflag", req.getParameter("sortflag"));
+
+
+        Page<Map<String,Object>> list=courseInfoService.queryCoursecentryPage(param);
+        return CommonResult.data(list);
+    }
+
+
+    /**
+     * 课程中心-详情(学生端)
+     *
+     * @author honorfire
+     * @date  2025/06/20 15:00
+     */
+    @ApiOperationSupport(order = 5)
+    @ApiOperation("课程中心-详情(学生端)")
+    @SaCheckPermission("/disk/coursecentry/detail")
+    @GetMapping("/disk/coursecentry/detail")
+    public CommonResult<Map<String,Object>> coursecentryDetail(@Valid CourseInfoIdParam courseInfoIdParam, HttpServletRequest req) {
+        Map param =new HashMap();
+        param.put("courseId", req.getParameter("courseId"));
+        Map<String,Object> result=courseInfoService.coursecentryDetail(param);
+        return CommonResult.data(result);
+    }
+
 }

+ 243 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/controller/CourseStudentRelateController.java

@@ -0,0 +1,243 @@
+/*
+ * 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 cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollStreamUtil;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONObject;
+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 io.swagger.annotations.ApiParam;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.http.MediaType;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import vip.xiaonuo.common.annotation.CommonLog;
+import vip.xiaonuo.common.pojo.CommonResult;
+import vip.xiaonuo.common.pojo.CommonValidList;
+import vip.xiaonuo.disk.domain.CourseStudentRelate;
+import vip.xiaonuo.disk.domain.ResourceRecordUserRelate;
+import vip.xiaonuo.disk.param.coursestudentrelate.CourseStudentRelateAddParam;
+import vip.xiaonuo.disk.param.coursestudentrelate.CourseStudentRelateEditParam;
+import vip.xiaonuo.disk.param.coursestudentrelate.CourseStudentRelateIdParam;
+import vip.xiaonuo.disk.param.coursestudentrelate.CourseStudentRelatePageParam;
+import vip.xiaonuo.disk.service.CourseStudentRelateService;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import javax.validation.constraints.NotEmpty;
+import java.io.IOException;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 课程学生关联表控制器
+ *
+ * @author honorfire
+ * @date  2025/07/12 11:04
+ */
+@Api(tags = "课程学生关联表控制器")
+@ApiSupport(author = "SNOWY_TEAM", order = 1)
+@RestController
+@Validated
+public class CourseStudentRelateController {
+
+    @Resource
+    private CourseStudentRelateService courseStudentRelateService;
+
+    /**
+     * 获取课程学生关联表分页
+     *
+     * @author honorfire
+     * @date  2025/07/12 11:04
+     */
+    @ApiOperationSupport(order = 1)
+    @ApiOperation("获取课程学生关联表分页")
+    @SaCheckPermission("/disk/coursestudentrelate/page")
+    @GetMapping("/disk/coursestudentrelate/page")
+    public CommonResult<Page<Map<String,Object>>> page(CourseStudentRelatePageParam courseStudentRelatePageParam, HttpServletRequest req) {
+        Map param =new HashMap();
+        param.put("queryInfo", req.getParameter("queryInfo"));
+        param.put("gender", req.getParameter("gender"));
+        param.put("userStatus", req.getParameter("userStatus"));
+        param.put("latestLoginStartTime", req.getParameter("latestLoginStartTime"));
+        param.put("latestLoginEndTime", req.getParameter("latestLoginEndTime"));
+        Page<Map<String,Object>> page=courseStudentRelateService.queryList(param);
+        List<Map<String,Object>> list=page.getRecords();
+        //根据获取所有b端登录用户的方法得到的获取所有在线用户id,然后比对这些用户是否在其中,在则为在线,不在为离线
+        //0离线1在线
+        List<String> userIdList = StpUtil.searchSessionId("", 0, Integer.MAX_VALUE, true)
+                .stream()
+                .map(sessionId -> StrUtil.split(sessionId, StrUtil.COLON).get(3))
+                .collect(Collectors.toList());
+        for(Map oneUser : list)
+        {
+            if(userIdList.contains(oneUser.get("userId")))
+            {
+                oneUser.put("isLogin","1");
+                oneUser.put("isLoginName","在线");
+            }else
+            {
+                oneUser.put("isLogin","0");
+                oneUser.put("isLoginName","离线");
+            }
+        }
+        return CommonResult.data(page);
+    }
+
+    /**
+     * 添加课程学生关联表
+     *
+     * @author honorfire
+     * @date  2025/07/12 11:04
+     */
+    @ApiOperationSupport(order = 2)
+    @ApiOperation("添加课程学生关联表")
+    @CommonLog("添加课程学生关联表")
+    @SaCheckPermission("/disk/coursestudentrelate/add")
+    @PostMapping("/disk/coursestudentrelate/add")
+    public CommonResult<String> add(@RequestBody @Valid CourseStudentRelateAddParam courseStudentRelateAddParam) {
+        Map param=new HashMap();
+        List<CourseStudentRelate> willAddList=new ArrayList<>();
+        //先排查该课程要新关联的学生id中,是否已有某学生关联,存在的话进行剔除
+        String[] userIds = courseStudentRelateAddParam.getUserIds().split(",");
+        List<String> willUserIdList= Arrays.asList(userIds);
+        param.put("courseId", courseStudentRelateAddParam.getCourseId());
+        List<CourseStudentRelate> alreadyRelateList=courseStudentRelateService.listWrapper(param);
+        List<String> alreadyRelateIdList=CollStreamUtil.toList(alreadyRelateList, CourseStudentRelate::getUserId);
+        for(String willUserId:willUserIdList)
+        {
+            if(alreadyRelateIdList.contains(willUserId))
+            {
+                willUserIdList.remove(willUserId);
+            }
+        }
+        if(willUserIdList.size()>0)
+        {
+            for(String willUserId:willUserIdList)
+            {
+                CourseStudentRelate courseStudentRelate = BeanUtil.toBean(courseStudentRelateAddParam, CourseStudentRelate.class);
+                courseStudentRelate.setUserId(willUserId);
+                willAddList.add(courseStudentRelate);
+            }
+        }
+
+        courseStudentRelateService.addBatch(willAddList);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 编辑课程学生关联表
+     *
+     * @author honorfire
+     * @date  2025/07/12 11:04
+     */
+    @ApiOperationSupport(order = 3)
+    @ApiOperation("编辑课程学生关联表")
+    @CommonLog("编辑课程学生关联表")
+    @SaCheckPermission("/disk/coursestudentrelate/edit")
+    @PostMapping("/disk/coursestudentrelate/edit")
+    public CommonResult<String> edit(@RequestBody @Valid CourseStudentRelateEditParam courseStudentRelateEditParam) {
+        CourseStudentRelate courseStudentRelate = BeanUtil.toBean(courseStudentRelateEditParam, CourseStudentRelate.class);
+        courseStudentRelateService.editOne(courseStudentRelate);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 删除课程学生关联表
+     *
+     * @author honorfire
+     * @date  2025/07/12 11:04
+     */
+    @ApiOperationSupport(order = 4)
+    @ApiOperation("删除课程学生关联表")
+    @CommonLog("删除课程学生关联表")
+    @SaCheckPermission("/disk/coursestudentrelate/delete")
+    @PostMapping("/disk/coursestudentrelate/delete")
+    public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
+                                                   CommonValidList<CourseStudentRelateIdParam> courseStudentRelateIdParamList) {
+        courseStudentRelateService.delete(courseStudentRelateIdParamList);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 课程学生关联-详情
+     *
+     * @author honorfire
+     * @date  2025/07/12 11:04
+     */
+    @ApiOperationSupport(order = 5)
+    @ApiOperation("课程学生关联-详情")
+    @SaCheckPermission("/disk/coursestudentrelate/detail")
+    @GetMapping("/disk/coursestudentrelate/detail")
+    public CommonResult<Map<String,Object>> detail(@Valid CourseStudentRelateIdParam courseStudentRelateIdParam, HttpServletRequest req) {
+        Map param =new HashMap();
+        param.put("id", req.getParameter("id"));
+        Map<String,Object> oneUser=courseStudentRelateService.queryInfo(param);
+        List<String> userIdList = StpUtil.searchSessionId("", 0, Integer.MAX_VALUE, true)
+                .stream()
+                .map(sessionId -> StrUtil.split(sessionId, StrUtil.COLON).get(3))
+                .collect(Collectors.toList());
+        if(userIdList.contains(oneUser.get("userId")))
+        {
+            oneUser.put("isLogin","1");
+            oneUser.put("isLoginName","在线");
+        }else
+        {
+            oneUser.put("isLogin","0");
+            oneUser.put("isLoginName","离线");
+        }
+        return CommonResult.data(oneUser);
+    }
+
+    /**
+     * 课程学生关联-导入
+     *
+     * @author xuyuxiang
+     * @date 2022/4/24 20:00
+     */
+    @ApiOperationSupport(order = 16)
+    @ApiOperation("用户导入")
+    @CommonLog("用户导入")
+    @PostMapping("/disk/coursestudentrelate/import")
+    public CommonResult<JSONObject> importInfo(@RequestPart("file") @ApiParam(value="文件", required = true) MultipartFile file,@RequestParam("courseId") String courseId) {
+        if(StringUtils.isEmpty(courseId))return CommonResult.error("课程id不能为空");
+
+        return CommonResult.data(courseStudentRelateService.importInfo(file,courseId));
+    }
+
+    /**
+     * 课程学生关联-下载导入模板
+     *
+     */
+    @ApiOperationSupport(order = 15)
+    @ApiOperation("课程学生关联-下载导入模板")
+    @CommonLog("课程学生关联-下载导入模板")
+    @GetMapping(value = "/disk/coursestudentrelate/downloadImportlate", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
+    public void downloadImportUserTemplate(HttpServletResponse response) throws IOException {
+        courseStudentRelateService.downloadImportTemplate(response);
+    }
+
+
+
+}

+ 71 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/domain/CourseStudentRelate.java

@@ -0,0 +1,71 @@
+/*
+ * 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.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 课程学生关联表实体
+ *
+ * @author honorfire
+ * @date  2025/07/12 11:04
+ **/
+@Getter
+@Setter
+@TableName("COURSE_STUDENT_RELATE")
+public class CourseStudentRelate {
+
+    /** ID */
+    @TableId
+    @ApiModelProperty(value = "ID", position = 1)
+    private String id;
+
+    /** 人员id */
+    @ApiModelProperty(value = "人员id", position = 2)
+    private String userId;
+
+    /** 课程id */
+    @ApiModelProperty(value = "课程id", position = 3)
+    private String courseId;
+
+    /** 删除标记(NOT_DELETE-未删除) */
+    @ApiModelProperty(value = "删除标记(NOT_DELETE-未删除)", position = 4)
+    @TableLogic
+    @TableField(fill = FieldFill.INSERT)
+    private String deleteFlag;
+
+    /** 记录更新时间 */
+    @ApiModelProperty(value = "记录更新时间", position = 5)
+    @TableField(fill = FieldFill.UPDATE)
+    private Date updateTime;
+
+    /** 记录创建时间 */
+    @ApiModelProperty(value = "记录创建时间", position = 6)
+    @TableField(fill = FieldFill.INSERT)
+    private Date createTime;
+
+    /** 记录创建人 */
+    @ApiModelProperty(value = "记录创建人", position = 7)
+    @TableField(fill = FieldFill.INSERT)
+    private String createUser;
+
+    /** 记录更新人 */
+    @ApiModelProperty(value = "记录更新人", position = 8)
+    @TableField(fill = FieldFill.UPDATE)
+    private String updateUser;
+}

+ 34 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/domain/CourseStudentRelateEnum.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.domain;
+
+import lombok.Getter;
+
+/**
+ * 课程学生关联表枚举
+ *
+ * @author honorfire
+ * @date  2025/07/12 11:04
+ **/
+@Getter
+public enum CourseStudentRelateEnum {
+
+    /** 测试 */
+    TEST("TEST");
+
+    private final String value;
+
+    CourseStudentRelateEnum(String value) {
+        this.value = value;
+    }
+}

+ 10 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/CourseInfoMapper.java

@@ -32,8 +32,18 @@ public interface CourseInfoMapper extends BaseMapper<CourseInfo> {
      */
     Page<Map<String,Object>> queryList(@Param("param") Map param, @Param("page") Page<Object> page);
 
+    /**
+     *  课程中心-分页列表(学生端)
+     */
+    Page<Map<String,Object>> queryCoursecentryPage(@Param("param") Map param, @Param("page") Page<Object> page);
+
     /**
      * 课程信息-详情
      */
     Map<String,Object> queryInfo(Map param);
+
+    /**
+     * 课程中心-详情(学生端)
+     */
+    Map<String,Object> coursecentryDetail(Map param);
 }

+ 41 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/CourseStudentRelateMapper.java

@@ -0,0 +1,41 @@
+/*
+ * 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 com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Param;
+import vip.xiaonuo.disk.domain.CourseStudentRelate;
+
+import java.util.Map;
+
+/**
+ * 课程学生关联表Mapper接口
+ *
+ * @author honorfire
+ * @date  2025/07/12 11:04
+ **/
+public interface CourseStudentRelateMapper extends BaseMapper<CourseStudentRelate> {
+
+    /**
+     * 课程学生关联-详情
+     */
+    Map<String,Object> queryInfo(Map param);
+
+
+    /**
+     * 课程学生关联-分页列表
+     */
+    Page<Map<String,Object>> queryList(@Param("param") Map param, @Param("page") Page<Object> page);
+
+}

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

@@ -120,6 +120,9 @@
         LEFT JOIN RESOURCE_FILE rf ON ru.FILE_ID= rf.FILE_ID
         LEFT JOIN SYS_USER su ON rr.CREATE_USER =su.ID AND su.DELETE_FLAG ='NOT_DELETE'
         where cc.DELETE_FLAG ='NOT_DELETE'
+        <if test=" param.verifyPass == 1">
+            AND rr.VERIFY_STATUS ='2'
+        </if>
         <if test="chapterId !=null and chapterId != ''">
             and cc.chapter_id=#{chapterId}
         </if>

+ 86 - 3
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/mapping/CourseInfoMapper.xml

@@ -7,7 +7,7 @@
         ci.COURSE_ID as courseId,
         IFNULL(ci.COURSE_NAME,'') as courseName,
         IFNULL(ci.COURSE_TYPE,'') as courseType,
-        IFNULL(( SELECT dd1.DICT_LABEL FROM (SELECT d1.DICT_LABEL,d1.DICT_VALUE  FROM  DEV_DICT d1 WHERE PARENT_ID = (SELECT d2.ID  FROM  DEV_DICT d2 WHERE d2.DICT_VALUE='COURSE_TYPE') )dd1 WHERE dd1.DICT_VALUE = TRIM(ci.COURSE_TYPE) ),'') AS isCreaterName,
+        IFNULL(( SELECT dd1.DICT_LABEL FROM (SELECT d1.DICT_LABEL,d1.DICT_VALUE  FROM  DEV_DICT d1 WHERE PARENT_ID = (SELECT d2.ID  FROM  DEV_DICT d2 WHERE d2.DICT_VALUE='COURSE_TYPE') )dd1 WHERE dd1.DICT_VALUE = TRIM(ci.COURSE_TYPE) ),'') AS courseTypeName,
         IFNULL(ci.COURSE_DESC,'') as courseDesc,
         IFNULL(ci.TEACHER_ID,'') as teacherId,
         IFNULL(su.NAME,'') AS teacherIdName,
@@ -60,7 +60,6 @@
                 order by ci.VIEW_COUNT desc
             </if>
         </if>
-        order by ci.COLLEGE_ID desc
     </select>
 
     <select id="queryInfo" parameterType="java.util.Map" resultType="java.util.Map">
@@ -68,7 +67,7 @@
         ci.COURSE_ID as courseId,
         IFNULL(ci.COURSE_NAME,'') as courseName,
         IFNULL(ci.COURSE_TYPE,'') as courseType,
-        IFNULL(( SELECT dd1.DICT_LABEL FROM (SELECT d1.DICT_LABEL,d1.DICT_VALUE  FROM  DEV_DICT d1 WHERE PARENT_ID = (SELECT d2.ID  FROM  DEV_DICT d2 WHERE d2.DICT_VALUE='COURSE_TYPE') )dd1 WHERE dd1.DICT_VALUE = TRIM(ci.COURSE_TYPE) ),'') AS isCreaterName,
+        IFNULL(( SELECT dd1.DICT_LABEL FROM (SELECT d1.DICT_LABEL,d1.DICT_VALUE  FROM  DEV_DICT d1 WHERE PARENT_ID = (SELECT d2.ID  FROM  DEV_DICT d2 WHERE d2.DICT_VALUE='COURSE_TYPE') )dd1 WHERE dd1.DICT_VALUE = TRIM(ci.COURSE_TYPE) ),'') AS courseTypeName,
         IFNULL(ci.COURSE_DESC,'') as courseDesc,
         IFNULL(ci.TEACHER_ID,'') as teacherId,
         IFNULL(su.NAME,'') AS teacherIdName,
@@ -102,4 +101,88 @@
             and ci.COURSE_ID=#{courseId}
         </if>
     </select>
+    <select id="queryCoursecentryPage" resultType="java.util.Map">
+        select
+            ci.COURSE_ID as courseId,
+            IFNULL(ci.COURSE_NAME,'') as courseName,
+            IFNULL(ci.COURSE_TYPE,'') as courseType,
+            IFNULL(( SELECT dd1.DICT_LABEL FROM (SELECT d1.DICT_LABEL,d1.DICT_VALUE  FROM  DEV_DICT d1 WHERE PARENT_ID = (SELECT d2.ID  FROM  DEV_DICT d2 WHERE d2.DICT_VALUE='COURSE_TYPE') )dd1 WHERE dd1.DICT_VALUE = TRIM(ci.COURSE_TYPE) ),'') AS courseTypeName,
+            IFNULL(ci.TEACHER_ID,'') as teacherId,
+            IFNULL(su.NAME,'') AS teacherIdName,
+            IFNULL(ci.MAJOR_ID,'') AS majorId,
+            IFNULL(ma.major_name,'') AS majorIdName,
+            IFNULL(ci.PUBLISH_TIME,'') as publishTime,
+            IFNULL(ci.COVER_IMAGE_ID,'') as coverImageId,
+            IFNULL (CAST(df.DOWNLOAD_PATH AS VARCHAR),'') AS coverImagePath,
+            IFNULL(ci.TIME_LIMIT_TYPE,'') as timeLimitType,
+            IFNULL(ci.START_TIME,'') as startTime,
+            IFNULL(ci.END_TIME,'') as endTime
+        FROM COURSE_INFO ci
+        LEFT JOIN COURSE_STUDENT_RELATE csr ON ci.COURSE_ID = CSR.COURSE_ID AND CSR.DELETE_FLAG ='NOT_DELETE'
+        LEFT JOIN DEV_FILE df ON ci.COVER_IMAGE_ID =df.ID AND df.DELETE_FLAG ='NOT_DELETE'
+        LEFT JOIN college co ON ci.COLLEGE_ID=co.ID AND co.DELETE_FLAG ='NOT_DELETE'
+        LEFT JOIN college co2 ON ci.COLLEGE_TWO_ID=co2.id AND co2.DELETE_FLAG ='NOT_DELETE'
+        LEFT JOIN college co3 ON ci.COLLEGE_THREE_ID=co3.id AND co3.DELETE_FLAG ='NOT_DELETE'
+        LEFT JOIN major ma ON ci.MAJOR_ID=ma.id AND ma.DELETE_FLAG ='NOT_DELETE'
+        LEFT JOIN SYS_USER su ON su.ID=ci.TEACHER_ID AND su.DELETE_FLAG ='NOT_DELETE'
+        WHERE ci.DELETE_FLAG ='NOT_DELETE'
+        <if test="param.userId !=null and param.userId != ''">
+            and csr.USER_ID=#{param.userId}
+        </if>
+        <if test="param.collegeId !=null and param.collegeId != ''">
+            and ci.COLLEGE_ID=#{param.courseId}
+        </if>
+        <if test="param.collegeTwoId!=null and param.collegeTwoId != ''">
+            and ci.COLLEGE_TWO_ID=#{param.collegeTwoId}
+        </if>
+        <if test="param.collegeThreeId!=null and param.collegeThreeId != ''">
+            and ci.COLLEGE_THREE_ID=#{param.collegeThreeId}
+        </if>
+        <if test="param.majorId !=null and param.majorId != ''">
+            and ci.MAJOR_ID=#{param.majorId}
+        </if>
+        <if test="param.courseType !=null and param.courseType != ''">
+            and ci.COURSE_TYPE=#{param.courseType}
+        </if>
+        <if test="param.courseName !=null and param.courseName != ''">
+            and ci.COURSE_NAME=#{param.courseName}
+        </if>
+        <if test="param.sortflag !=null and param.sortflag != ''">
+            <if test=" param.sortflag == 0">
+                order by ci.CREATE_TIME desc
+            </if>
+            <if test=" param.sortflag == 1">
+                order by ci.VIEW_COUNT desc
+            </if>
+        </if>
+    </select>
+    <select id="coursecentryDetail" resultType="java.util.Map">
+        select
+            ci.COURSE_ID as courseId,
+            IFNULL(ci.COURSE_NAME,'') as courseName,
+            IFNULL(ci.COURSE_TYPE,'') as courseType,
+            IFNULL(( SELECT dd1.DICT_LABEL FROM (SELECT d1.DICT_LABEL,d1.DICT_VALUE  FROM  DEV_DICT d1 WHERE PARENT_ID = (SELECT d2.ID  FROM  DEV_DICT d2 WHERE d2.DICT_VALUE='COURSE_TYPE') )dd1 WHERE dd1.DICT_VALUE = TRIM(ci.COURSE_TYPE) ),'') AS courseTypeName,
+            IFNULL(ci.TEACHER_ID,'') as teacherId,
+            IFNULL(su.NAME,'') AS teacherIdName,
+            IFNULL(ci.MAJOR_ID,'') AS majorId,
+            IFNULL(ma.major_name,'') AS majorIdName,
+            IFNULL(ci.PUBLISH_TIME,'') as publishTime,
+            IFNULL(ci.COVER_IMAGE_ID,'') as coverImageId,
+            IFNULL (CAST(df.DOWNLOAD_PATH AS VARCHAR),'') AS coverImagePath,
+            IFNULL(ci.TIME_LIMIT_TYPE,'') as timeLimitType,
+            IFNULL(ci.START_TIME,'') as startTime,
+            IFNULL(ci.END_TIME,'') as endTime
+        FROM COURSE_INFO ci
+        LEFT JOIN COURSE_STUDENT_RELATE csr ON ci.COURSE_ID = CSR.COURSE_ID AND CSR.DELETE_FLAG ='NOT_DELETE'
+        LEFT JOIN DEV_FILE df ON ci.COVER_IMAGE_ID =df.ID AND df.DELETE_FLAG ='NOT_DELETE'
+        LEFT JOIN college co ON ci.COLLEGE_ID=co.ID AND co.DELETE_FLAG ='NOT_DELETE'
+        LEFT JOIN college co2 ON ci.COLLEGE_TWO_ID=co2.id AND co2.DELETE_FLAG ='NOT_DELETE'
+        LEFT JOIN college co3 ON ci.COLLEGE_THREE_ID=co3.id AND co3.DELETE_FLAG ='NOT_DELETE'
+        LEFT JOIN major ma ON ci.MAJOR_ID=ma.id AND ma.DELETE_FLAG ='NOT_DELETE'
+        LEFT JOIN SYS_USER su ON su.ID=ci.TEACHER_ID AND su.DELETE_FLAG ='NOT_DELETE'
+        WHERE ci.DELETE_FLAG ='NOT_DELETE'
+        <if test="courseId !=null and courseId != ''">
+            and ci.COURSE_ID=#{courseId}
+        </if>
+    </select>
 </mapper>

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

@@ -0,0 +1,52 @@
+<?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.mapper.CourseStudentRelateMapper">
+
+    <select id="queryList" resultType="java.util.Map">
+        SELECT
+            csr.ID AS relateId,
+            IFNULL (csr.COURSE_ID,'') AS courseId,
+            IFNULL (csr.USER_ID,'') AS userId,
+            IFNULL (su.ACCOUNT,'') AS account,
+            IFNULL (su.NAME,'') AS userIdName,
+            IFNULL (su.GENDER,'未知') AS gender,
+            IFNULL (su.USER_STATUS,'') AS userStatus,
+            IFNULL(( SELECT dd1.DICT_LABEL FROM (SELECT d1.DICT_LABEL,d1.DICT_VALUE  FROM  DEV_DICT d1 WHERE PARENT_ID = (SELECT d2.ID  FROM  DEV_DICT d2 WHERE d2.DICT_VALUE='COMMON_STATUS') )dd1 WHERE dd1.DICT_VALUE = TRIM(su.USER_STATUS) ),'') AS userStatusName,
+            IFNULL (su.PHONE,'') AS phone,
+            IFNULL (su.LATEST_LOGIN_TIME,'') AS latestLoginTime
+        FROM COURSE_STUDENT_RELATE csr
+        LEFT JOIN SYS_USER su ON csr.USER_ID =su.ID
+        WHERE csr.DELETE_FLAG ='NOT_DELETE'
+        AND su.DELETE_FLAG ='NOT_DELETE'
+        <if test="param.queryInfo !=null and param.gender != ''">
+            and (su.NAME like CONCAT('%',#{param.queryInfo}, '%') or su.ACCOUNT like CONCAT('%',#{param.queryInfo}, '%') or su.PHONE like CONCAT('%',#{param.queryInfo}, '%'))
+        </if>
+        <if test="param.gender !=null and param.gender != ''">
+            and su.GENDER=#{param.gender}
+        </if>
+        <if test="param.userStatus !=null and param.userStatus != ''">
+            and su.USER_STATUS=#{param.userStatus}
+        </if>
+        <if test="param.latestLoginStartTime !=null and param.latestLoginStartTime != ''">
+            and su.LATEST_LOGIN_TIME &gt;=#{param.latestLoginStartTime}
+        </if>
+        <if test="param.latestLoginEndTime !=null and param.latestLoginEndTime != ''">
+            and su.LATEST_LOGIN_TIME &lt;=#{param.latestLoginEndTime}
+        </if>
+    </select>
+    <select id="queryInfo" resultType="java.util.Map">
+        SELECT
+            csr.ID AS relateId,
+            IFNULL (csr.COURSE_ID,'') AS courseId,
+            IFNULL (csr.USER_ID,'') AS userId,
+            IFNULL (su.ACCOUNT,'') AS account,
+            IFNULL (su.NAME,'') AS userIdName,
+            IFNULL (su.GENDER,'未知') AS gender,
+            IFNULL (su.USER_STATUS,'') AS userStatus,
+            IFNULL(( SELECT dd1.DICT_LABEL FROM (SELECT d1.DICT_LABEL,d1.DICT_VALUE  FROM  DEV_DICT d1 WHERE PARENT_ID = (SELECT d2.ID  FROM  DEV_DICT d2 WHERE d2.DICT_VALUE='COMMON_STATUS') )dd1 WHERE dd1.DICT_VALUE = TRIM(su.USER_STATUS) ),'') AS userStatusName,
+            IFNULL (su.PHONE,'') AS phone,
+            IFNULL (su.LATEST_LOGIN_TIME,'') AS latestLoginTime
+        FROM COURSE_STUDENT_RELATE csr
+        LEFT JOIN SYS_USER su ON csr.USER_ID =su.ID
+    </select>
+</mapper>

+ 41 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/param/coursestudentrelate/CourseStudentRelateAddParam.java

@@ -0,0 +1,41 @@
+/*
+ * 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.coursestudentrelate;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * 课程学生关联表添加参数
+ *
+ * @author honorfire
+ * @date  2025/07/12 11:04
+ **/
+@Getter
+@Setter
+public class CourseStudentRelateAddParam {
+
+    /** 人员id */
+    @ApiModelProperty(value = "人员id", position = 2)
+    @NotBlank(message = "人员id组不能为空")
+    private String userIds;
+
+    /** 课程id */
+    @ApiModelProperty(value = "课程id", position = 3)
+    @NotBlank(message = "课程id不能为空")
+    private String courseId;
+
+}

+ 44 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/param/coursestudentrelate/CourseStudentRelateEditParam.java

@@ -0,0 +1,44 @@
+/*
+ * 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.coursestudentrelate;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * 课程学生关联表编辑参数
+ *
+ * @author honorfire
+ * @date  2025/07/12 11:04
+ **/
+@Getter
+@Setter
+public class CourseStudentRelateEditParam {
+
+    /** ID */
+    @ApiModelProperty(value = "ID", required = true, position = 1)
+    @NotBlank(message = "id不能为空")
+    private String id;
+
+    /** 人员id */
+    @ApiModelProperty(value = "人员id", position = 2)
+    private String userId;
+
+    /** 课程id */
+    @ApiModelProperty(value = "课程id", position = 3)
+    private String courseId;
+
+}

+ 35 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/param/coursestudentrelate/CourseStudentRelateIdParam.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.coursestudentrelate;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * 课程学生关联表Id参数
+ *
+ * @author honorfire
+ * @date  2025/07/12 11:04
+ **/
+@Getter
+@Setter
+public class CourseStudentRelateIdParam {
+
+    /** ID */
+    @ApiModelProperty(value = "ID", required = true)
+    @NotBlank(message = "id不能为空")
+    private String id;
+}

+ 24 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/param/coursestudentrelate/CourseStudentRelateImportParam.java

@@ -0,0 +1,24 @@
+package vip.xiaonuo.disk.param.coursestudentrelate;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class CourseStudentRelateImportParam {
+
+    /** 人员账号 */
+    @ApiModelProperty(value = "人员账号", position = 2)
+    private String acount;
+
+    /** 人员姓名 */
+    @ApiModelProperty(value = "人员姓名", position = 2)
+    private String userName;
+
+    /** 课程id */
+    @ApiModelProperty(value = "课程id", position = 3)
+    private String courseId;
+
+
+}

+ 49 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/param/coursestudentrelate/CourseStudentRelatePageParam.java

@@ -0,0 +1,49 @@
+/*
+ * 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.coursestudentrelate;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 课程学生关联表查询参数
+ *
+ * @author honorfire
+ * @date  2025/07/12 11:04
+ **/
+@Getter
+@Setter
+public class CourseStudentRelatePageParam {
+
+    /** 当前页 */
+    @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;
+
+}

+ 10 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/CourseInfoService.java

@@ -101,6 +101,11 @@ public interface CourseInfoService extends IService<CourseInfo> {
      */
     Page<Map<String,Object>> queryList(Map param);
 
+    /**
+     *  课程中心-分页列表(学生端)
+     */
+    Page<Map<String,Object>> queryCoursecentryPage(Map param);
+
     /**
      *  课程信息-全量列表
      */
@@ -110,4 +115,9 @@ public interface CourseInfoService extends IService<CourseInfo> {
      *  课程信息-详情
      */
     Map<String,Object> queryInfo(Map param);
+
+    /**
+     *  课程中心-详情(学生端)
+     */
+    Map<String,Object> coursecentryDetail(Map param);
 }

+ 142 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/CourseStudentRelateService.java

@@ -0,0 +1,142 @@
+/*
+ * 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 cn.hutool.json.JSONObject;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.springframework.web.multipart.MultipartFile;
+import vip.xiaonuo.disk.domain.CourseAuditRecord;
+import vip.xiaonuo.disk.domain.CourseStudentRelate;
+import vip.xiaonuo.disk.param.coursestudentrelate.CourseStudentRelateAddParam;
+import vip.xiaonuo.disk.param.coursestudentrelate.CourseStudentRelateEditParam;
+import vip.xiaonuo.disk.param.coursestudentrelate.CourseStudentRelateIdParam;
+import vip.xiaonuo.disk.param.coursestudentrelate.CourseStudentRelatePageParam;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 课程学生关联表Service接口
+ *
+ * @author honorfire
+ * @date  2025/07/12 11:04
+ **/
+public interface CourseStudentRelateService extends IService<CourseStudentRelate> {
+
+    /**
+     * 获取课程学生关联表分页
+     *
+     * @author honorfire
+     * @date  2025/07/12 11:04
+     */
+    Page<CourseStudentRelate> page(CourseStudentRelatePageParam courseStudentRelatePageParam);
+
+    /**
+     * 获取课程学生关联-封装方法
+     *
+     * @author honorfire
+     * @date  2025/07/12 11:04
+     */
+    List<CourseStudentRelate> listWrapper(Map param);
+
+    /**
+     * 添加课程学生关联表
+     *
+     * @author honorfire
+     * @date  2025/07/12 11:04
+     */
+    void add(CourseStudentRelateAddParam courseStudentRelateAddParam);
+
+    /**
+     * 课程学生关联-添加
+     *
+     * @author honorfire
+     * @date  2025/06/20 14:58
+     */
+    CourseStudentRelate addOne(CourseStudentRelate courseStudentRelate);
+
+    /**
+     * 课程学生关联-批量添加
+     *
+     * @author honorfire
+     * @date  2025/06/20 14:58
+     */
+    void addBatch(List<CourseStudentRelate> courseStudentRelateList);
+
+    /**
+     * 编辑课程学生关联表
+     *
+     * @author honorfire
+     * @date  2025/07/12 11:04
+     */
+    void edit(CourseStudentRelateEditParam courseStudentRelateEditParam);
+
+    /**
+     * 课程学生关联-编辑
+     *
+     * @author honorfire
+     * @date  2025/06/20 14:58
+     */
+    CourseStudentRelate editOne(CourseStudentRelate courseStudentRelate);
+
+    /**
+     * 删除课程学生关联表
+     *
+     * @author honorfire
+     * @date  2025/07/12 11:04
+     */
+    void delete(List<CourseStudentRelateIdParam> courseStudentRelateIdParamList);
+
+    /**
+     * 获取课程学生关联表详情
+     *
+     * @author honorfire
+     * @date  2025/07/12 11:04
+     */
+    CourseStudentRelate detail(CourseStudentRelateIdParam courseStudentRelateIdParam);
+
+    /**
+     * 获取课程学生关联表详情
+     *
+     * @author honorfire
+     * @date  2025/07/12 11:04
+     **/
+    CourseStudentRelate queryEntity(String id);
+
+    /**
+     *  课程学生关联-分页列表
+     */
+    Page<Map<String,Object>> queryList(Map param);
+
+    /**
+     *  课程学生关联-详情
+     */
+    Map<String,Object> queryInfo(Map param);
+
+
+    /**
+     * 课程学生关联-导入
+     **/
+    JSONObject importInfo(MultipartFile file,String courseId);
+
+    /**
+     * 课程学生关联-下载导入模板
+     *
+     * @author xuyuxiang
+     * @date 2022/8/8 13:16
+     **/
+    void downloadImportTemplate(HttpServletResponse response) throws IOException;
+}

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

@@ -117,6 +117,12 @@ public class CourseInfoServiceImpl extends ServiceImpl<CourseInfoMapper, CourseI
         return courseInfoMapper.queryList(param,CommonPageRequest.defaultPage());
     }
 
+    @Override
+    public Page<Map<String,Object>> queryCoursecentryPage(Map param)
+    {
+        return courseInfoMapper.queryCoursecentryPage(param,CommonPageRequest.defaultPage());
+    }
+
     /**
      *  课程信息-全量列表
      */
@@ -134,6 +140,12 @@ public class CourseInfoServiceImpl extends ServiceImpl<CourseInfoMapper, CourseI
         return courseInfoMapper.queryInfo(param);
     }
 
+    @Override
+    public Map<String,Object> coursecentryDetail(Map param)
+    {
+        return courseInfoMapper.coursecentryDetail(param);
+    }
+
 
 
 }

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

@@ -0,0 +1,253 @@
+/*
+ * 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.afterturn.easypoi.cache.manager.POICacheManager;
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollStreamUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.alibaba.excel.EasyExcel;
+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.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+import vip.xiaonuo.common.enums.CommonSortOrderEnum;
+import vip.xiaonuo.common.exception.CommonException;
+import vip.xiaonuo.common.page.CommonPageRequest;
+import vip.xiaonuo.common.util.CommonDownloadUtil;
+import vip.xiaonuo.common.util.CommonResponseUtil;
+import vip.xiaonuo.disk.domain.CourseStudentRelate;
+import vip.xiaonuo.disk.domain.ResourceRecordUserRelate;
+import vip.xiaonuo.disk.mapper.CourseStudentRelateMapper;
+import vip.xiaonuo.disk.param.coursestudentrelate.*;
+import vip.xiaonuo.disk.service.CourseStudentRelateService;
+import vip.xiaonuo.sys.modular.user.entity.SysUser;
+import vip.xiaonuo.sys.modular.user.param.SysUserImportParam;
+import vip.xiaonuo.sys.modular.user.param.SysUserPageParam;
+import vip.xiaonuo.sys.modular.user.service.SysUserService;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 课程学生关联表Service接口实现类
+ *
+ * @author honorfire
+ * @date  2025/07/12 11:04
+ **/
+@Service
+public class CourseStudentRelateServiceImpl extends ServiceImpl<CourseStudentRelateMapper, CourseStudentRelate> implements CourseStudentRelateService {
+
+    @Resource
+    private CourseStudentRelateMapper courseStudentRelateMapper;
+    @Resource
+    private SysUserService sysUserService;
+
+    @Override
+    public Page<CourseStudentRelate> page(CourseStudentRelatePageParam courseStudentRelatePageParam) {
+        QueryWrapper<CourseStudentRelate> queryWrapper = new QueryWrapper<>();
+        if(ObjectUtil.isAllNotEmpty(courseStudentRelatePageParam.getSortField(), courseStudentRelatePageParam.getSortOrder())) {
+            CommonSortOrderEnum.validate(courseStudentRelatePageParam.getSortOrder());
+            queryWrapper.orderBy(true, courseStudentRelatePageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
+                    StrUtil.toUnderlineCase(courseStudentRelatePageParam.getSortField()));
+        } else {
+            queryWrapper.lambda().orderByAsc(CourseStudentRelate::getId);
+        }
+        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
+    }
+
+    @Override
+    public List<CourseStudentRelate> listWrapper(Map param) {
+        QueryWrapper<CourseStudentRelate> queryWrapper = new QueryWrapper<>();
+        if (ObjectUtil.isNotEmpty(param.get("userId"))) {
+            queryWrapper.lambda().eq(CourseStudentRelate::getUserId, param.get("userId"));
+        }
+        if (ObjectUtil.isNotEmpty(param.get("courseId"))) {
+            queryWrapper.lambda().eq(CourseStudentRelate::getCourseId, param.get("courseId"));
+        }
+        return this.list(queryWrapper);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void add(CourseStudentRelateAddParam courseStudentRelateAddParam) {
+        CourseStudentRelate courseStudentRelate = BeanUtil.toBean(courseStudentRelateAddParam, CourseStudentRelate.class);
+        this.save(courseStudentRelate);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public CourseStudentRelate addOne(CourseStudentRelate courseStudentRelate) {
+        this.save(courseStudentRelate);
+        return courseStudentRelate;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void addBatch(List<CourseStudentRelate> courseStudentRelateList)
+    {
+        this.saveBatch(courseStudentRelateList);
+    }
+
+
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void edit(CourseStudentRelateEditParam courseStudentRelateEditParam) {
+        CourseStudentRelate courseStudentRelate = this.queryEntity(courseStudentRelateEditParam.getId());
+        BeanUtil.copyProperties(courseStudentRelateEditParam, courseStudentRelate);
+        this.updateById(courseStudentRelate);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public CourseStudentRelate editOne(CourseStudentRelate courseStudentRelate) {
+        this.updateById(courseStudentRelate);
+        return courseStudentRelate;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void delete(List<CourseStudentRelateIdParam> courseStudentRelateIdParamList) {
+        // 执行删除
+        this.removeByIds(CollStreamUtil.toList(courseStudentRelateIdParamList, CourseStudentRelateIdParam::getId));
+    }
+
+    @Override
+    public CourseStudentRelate detail(CourseStudentRelateIdParam courseStudentRelateIdParam) {
+        return this.queryEntity(courseStudentRelateIdParam.getId());
+    }
+
+    @Override
+    public CourseStudentRelate queryEntity(String id) {
+        CourseStudentRelate courseStudentRelate = this.getById(id);
+        if(ObjectUtil.isEmpty(courseStudentRelate)) {
+            throw new CommonException("课程学生关联表不存在,id值为:{}", id);
+        }
+        return courseStudentRelate;
+    }
+
+    @Override
+    public Page<Map<String,Object>> queryList(Map param)
+    {
+        return courseStudentRelateMapper.queryList(param,CommonPageRequest.defaultPage());
+    }
+
+    @Override
+    public Map<String,Object> queryInfo(Map param)
+    {
+        return courseStudentRelateMapper.queryInfo(param);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public JSONObject importInfo(MultipartFile file,String courseId) {
+        try {
+            int successCount = 0;
+            int errorCount = 0;
+            JSONArray errorDetail = JSONUtil.createArray();
+            // 创建临时文件
+            File tempFile = FileUtil.writeBytes(file.getBytes(), FileUtil.file(FileUtil.getTmpDir() +
+                    FileUtil.FILE_SEPARATOR + "CourseStudentRelateImportTemplate.xlsx"));
+            // 读取excel
+            List<CourseStudentRelateImportParam> relateImportParamList =  EasyExcel.read(tempFile).head(CourseStudentRelateImportParam.class).sheet()
+                    .headRowNumber(2).doReadSync();
+            QueryWrapper<CourseStudentRelate> queryWrapper = new QueryWrapper<>();
+            queryWrapper.lambda().eq(CourseStudentRelate::getCourseId, courseId);
+            List<CourseStudentRelate> allRelateList = this.list(queryWrapper);
+            for (int i = 0; i < relateImportParamList.size(); i++) {
+                JSONObject jsonObject = this.doImport(allRelateList, relateImportParamList.get(i), i,courseId);
+                if(jsonObject.getBool("success")) {
+                    successCount += 1;
+                } else {
+                    errorCount += 1;
+                    errorDetail.add(jsonObject);
+                }
+            }
+            return JSONUtil.createObj()
+                    .set("totalCount", relateImportParamList.size())
+                    .set("successCount", successCount)
+                    .set("errorCount", errorCount)
+                    .set("errorDetail", errorDetail);
+        } catch (Exception e) {
+            log.error(">>> 用户导入失败:", e);
+            throw new CommonException("用户导入失败");
+        }
+    }
+
+    /**
+     * 执行导入
+     **/
+    public JSONObject doImport(List<CourseStudentRelate> allRelateList, CourseStudentRelateImportParam courseStudentRelateImportParam, int i,String courseId) {
+        if(StringUtils.isEmpty(courseStudentRelateImportParam.getAcount()) || StringUtils.isEmpty(courseStudentRelateImportParam.getUserName()))
+        {
+            return JSONUtil.createObj().set("success", false)
+                    .set("index", i + 1)
+                    .set("message", "账号及姓名不能为空");
+        }
+        //用账号及姓名,查询人员信息
+        SysUserPageParam sysUserPageParam=new SysUserPageParam();
+        sysUserPageParam.setAccount(courseStudentRelateImportParam.getAcount());
+        sysUserPageParam.setName(courseStudentRelateImportParam.getUserName());
+        List<SysUser> sysUserList = sysUserService.queryAllList(sysUserPageParam);
+        if(sysUserList.size()==0)
+        {
+            return JSONUtil.createObj().set("success", false)
+                    .set("index", i + 1)
+                    .set("message", "账号或姓名在系统人员中不存在");
+        }
+        SysUser sysUser = sysUserList.get(0);
+        //查看该课程已关联的学生中有没有这个学生
+        List<String> relateUserIdList=CollStreamUtil.toList(allRelateList, CourseStudentRelate::getUserId);
+        if(relateUserIdList.contains(sysUser.getId()))
+        {
+            return JSONUtil.createObj().set("success", false)
+                    .set("index", i + 1)
+                    .set("message", "该学生已关联该课程");
+        }
+        CourseStudentRelate courseStudentRelate=new CourseStudentRelate();
+        courseStudentRelate.setUserId(sysUser.getId());
+        courseStudentRelate.setCourseId(courseId);
+        this.addOne(courseStudentRelate);
+
+        return JSONUtil.createObj().set("success", true);
+    }
+
+
+    @Override
+    public void downloadImportTemplate(HttpServletResponse response) throws IOException {
+        try {
+            InputStream inputStream = POICacheManager.getFile("CourseStudentRelateTemplate.xlsx");
+            byte[] bytes = IoUtil.readBytes(inputStream);
+            CommonDownloadUtil.download("课程关联学员导入模板.xlsx", bytes, response);
+        } catch (Exception e) {
+            log.error(">>> 下载用户导入模板失败:", e);
+            CommonResponseUtil.renderError(response, "下载用户导入模板失败");
+        }
+    }
+
+}

BIN
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/resources/CourseStudentRelateTemplate.xlsx


+ 9 - 0
snowy-plugin/snowy-plugin-sys/snowy-plugin-sys-func/src/main/java/vip/xiaonuo/sys/modular/user/param/SysUserPageParam.java

@@ -57,4 +57,13 @@ public class SysUserPageParam {
     /** 是否是资源库特殊账号,0否1是 */
     @ApiModelProperty(value = "是否是资源库特殊账号,0否1是")
     private String isResourceaccount;
+
+    /** 账号 */
+    @ApiModelProperty(value = "账号")
+    private String account;
+
+    /** 姓名 */
+    @ApiModelProperty(value = "姓名")
+    private String name;
+
 }

+ 7 - 0
snowy-plugin/snowy-plugin-sys/snowy-plugin-sys-func/src/main/java/vip/xiaonuo/sys/modular/user/service/impl/SysUserServiceImpl.java

@@ -294,6 +294,12 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
         if (ObjectUtil.isNotEmpty(sysUserPageParam.getUserStatus())) {
             queryWrapper.lambda().eq(SysUser::getUserStatus, sysUserPageParam.getUserStatus());
         }
+        if (ObjectUtil.isNotEmpty(sysUserPageParam.getAccount())) {
+            queryWrapper.lambda().eq(SysUser::getAccount, sysUserPageParam.getAccount());
+        }
+        if (ObjectUtil.isNotEmpty(sysUserPageParam.getName())) {
+            queryWrapper.lambda().like(SysUser::getName, sysUserPageParam.getName());
+        }
 
         queryWrapper.lambda().orderByAsc(SysUser::getSortCode);
         List<SysUser> jsonList =  this.list(queryWrapper);
@@ -1115,6 +1121,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
             // 读取excel
             List<SysUserImportParam> sysUserImportParamList =  EasyExcel.read(tempFile).head(SysUserImportParam.class).sheet()
                     .headRowNumber(2).doReadSync();
+//            List<SysUserImportParam> sysUserImportParamList =EasyExcel.read(tempFile).head(SysUserImportParam.class).autoCloseStream(false).sheet().doReadSync();
             List<SysUser> allUserList = this.list();
             for (int i = 0; i < sysUserImportParamList.size(); i++) {
                 JSONObject jsonObject = this.doImport(allUserList, sysUserImportParamList.get(i), i);