Bläddra i källkod

1.与前端联调,修复资源管理以及资源中心的一些bug,以及应前端需要增加一些字段
2.修改专业相关bug
3.迁移上传,编辑,删除,预览等接口,并且加入返回文件id,上传状态等,进行测试

honorfire 8 månader sedan
förälder
incheckning
7fe39bdd8f
21 ändrade filer med 715 tillägg och 40 borttagningar
  1. 6 1
      snowy-modules/snowy-web-app/src/main/java/vip/xiaonuo/web/core/config/GlobalConfigure.java
  2. 3 3
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/component/ResourceFileDealComp.java
  3. 25 3
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/controller/CourseAuditRecordController.java
  4. 222 5
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/controller/ResourceFileController.java
  5. 6 2
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/domain/ResourceUserFile.java
  6. 2 2
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/dto/courseauditrecord/CourseAuditRecordEditParam.java
  7. 15 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/dto/file/EachOtherExchangeDTO.java
  8. 2 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/dto/file/UploadFileDTO.java
  9. 5 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/CourseAuditRecordMapper.java
  10. 40 3
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/mapping/CourseAuditRecordMapper.xml
  11. 2 2
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/mapping/MajorMapper.xml
  12. 1 1
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/mapping/ResourceUserFileMapper.xml
  13. 5 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/CourseAuditRecordService.java
  14. 21 2
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/ResourceFileService.java
  15. 9 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/ResourceUserfileService.java
  16. 6 0
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/impl/CourseAuditRecordServiceImpl.java
  17. 261 13
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/impl/ResourceFileServiceImpl.java
  18. 75 1
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/impl/ResourceUserfileServiceImpl.java
  19. 1 1
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/util/QiwenFileUtil.java
  20. 3 1
      snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/vo/file/UploadFileVo.java
  21. 5 0
      snowy-server/snowy-gateway-app/src/main/java/vip/xiaonuo/gateway/config/GatewayConfigure.java

+ 6 - 1
snowy-modules/snowy-web-app/src/main/java/vip/xiaonuo/web/core/config/GlobalConfigure.java

@@ -175,7 +175,12 @@ public class GlobalConfigure implements WebMvcConfigurer {
             "/easyTrans/proxy/**",
             /* 文件预览 */
             "/filetransfer/preview",
-            "/filetransfer/downloadfile"
+            "/filetransfer/downloadfile",
+
+            /* 资源中心 */
+            "/disk/resourcecentre/page",
+            "/disk/resourcecentre/detail",
+            "/disk/courseauditrecord/addViewCount"
     };
 
     /**

+ 3 - 3
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/component/ResourceFileDealComp.java

@@ -94,7 +94,7 @@ public class ResourceFileDealComp {
             LambdaQueryWrapper<ResourceUserFile> lambdaQueryWrapper = new LambdaQueryWrapper<>();
             lambdaQueryWrapper.eq(ResourceUserFile::getFilePath, parentFilePath)
                     .eq(ResourceUserFile::getFileName, fileName)
-                    .eq(ResourceUserFile::getDeleteFlag, 0)
+                    .eq(ResourceUserFile::getDeleteFlag, "NOT_DELETE")
                     .eq(ResourceUserFile::getIsDir, 1)
                     .eq(ResourceUserFile::getUserId, sessionUserId);
             List<ResourceUserFile> userFileList = resourceUserFileMapper.selectList(lambdaQueryWrapper);
@@ -129,7 +129,7 @@ public class ResourceFileDealComp {
         int isDir = userFile.getIsDir();
         LambdaQueryWrapper<ResourceUserFile> lambdaQueryWrapper = new LambdaQueryWrapper<>();
         lambdaQueryWrapper.eq(ResourceUserFile::getFilePath, savefilePath)
-                .eq(ResourceUserFile::getDeleteFlag, 0)
+                .eq(ResourceUserFile::getDeleteFlag, "NOT_DELETE")
                 .eq(ResourceUserFile::getUserId, userId)
                 .eq(ResourceUserFile::getFileName, fileName)
                 .eq(ResourceUserFile::getIsDir, isDir);
@@ -147,7 +147,7 @@ public class ResourceFileDealComp {
             i++;
             LambdaQueryWrapper<ResourceUserFile> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
             lambdaQueryWrapper1.eq(ResourceUserFile::getFilePath, savefilePath)
-                    .eq(ResourceUserFile::getDeleteFlag, 0)
+                    .eq(ResourceUserFile::getDeleteFlag, "NOT_DELETE")
                     .eq(ResourceUserFile::getUserId, userId)
                     .eq(ResourceUserFile::getFileName, fileName + "(" + i + ")")
                     .eq(ResourceUserFile::getIsDir, isDir);

+ 25 - 3
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/controller/CourseAuditRecordController.java

@@ -59,6 +59,7 @@ import java.util.*;
 @Validated
 public class CourseAuditRecordController {
 
+
     @Resource
     private CourseAuditRecordService courseAuditRecordService;
 
@@ -145,7 +146,7 @@ public class CourseAuditRecordController {
         param.put("majorId", req.getParameter("majorId"));
         param.put("courseType", req.getParameter("courseType"));
         param.put("suffix", req.getParameter("suffix"));
-        Page<Map<String,Object>> list=courseAuditRecordService.queryList(param);
+        Page<Map<String,Object>> list=courseAuditRecordService.queryResourceCentreList(param);
         return CommonResult.data(list);
     }
 
@@ -168,7 +169,7 @@ public class CourseAuditRecordController {
         List<CourseAuditRecord> courseAuditRecordList = new ArrayList<>();
         for (String userFileId : userFileIdList) {
             CourseAuditRecord courseAuditRecord = BeanUtil.toBean(courseAuditRecordAddParam, CourseAuditRecord.class);
-        //2025.6.27废弃,改用userfile表,直接有相关信息
+            //2025.6.27废弃,改用userfile表,直接有相关信息
 //            ResourceUserFile resourceUserFile =resourceUserfileService.queryEntity(userFileId);
 //            courseAuditRecord.setFileName(resourceUserFile.getFileName());
             courseAuditRecord.setUserfileId(userFileId);
@@ -192,6 +193,7 @@ public class CourseAuditRecordController {
     @SaCheckPermission("/disk/courseauditrecord/edit")
     @PostMapping("/disk/courseauditrecord/edit")
     public CommonResult<String> edit(@RequestBody @Valid CourseAuditRecordEditParam courseAuditRecordEditParam) {
+        if(StringUtils.isEmpty(courseAuditRecordEditParam.getId()))return CommonResult.error("id不能为空");
         CourseAuditRecord courseAuditRecord = BeanUtil.toBean(courseAuditRecordEditParam, CourseAuditRecord.class);
         if(StringUtils.isNotEmpty(courseAuditRecordEditParam.getKeywordValue()))courseAuditRecord.setKeywordPinyin(StringUtils.deleteWhitespace(pinyinUtils.toPinyin(courseAuditRecordEditParam.getKeywordValue(),false)));
         courseAuditRecordService.editOne(courseAuditRecord);
@@ -210,6 +212,7 @@ public class CourseAuditRecordController {
     @SaCheckPermission("/disk/courseauditrecord/updateStatus")
     @PostMapping("/disk/courseauditrecord/updateStatus")
     public CommonResult<String> updateStatus(@RequestBody @Valid CourseAuditRecordEditParam courseAuditRecordEditParam) {
+        if(StringUtils.isEmpty(courseAuditRecordEditParam.getIds()))return CommonResult.error("id组不能为空");
         if(StringUtils.isEmpty(courseAuditRecordEditParam.getVerifyStatus()))return CommonResult.error("审核状态不能为空");
         //校验
         //0未发布,1待审核,2已发布,3未通过,4已删除
@@ -288,7 +291,7 @@ public class CourseAuditRecordController {
     @SaCheckPermission("/disk/courseauditrecord/delete")
     @PostMapping("/disk/courseauditrecord/delete")
     public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
-                                                   CommonValidList<CourseAuditRecordIdParam> courseAuditRecordIdParamList) {
+                                               CommonValidList<CourseAuditRecordIdParam> courseAuditRecordIdParamList) {
         courseAuditRecordService.delete(courseAuditRecordIdParamList);
         return CommonResult.ok();
     }
@@ -326,4 +329,23 @@ public class CourseAuditRecordController {
         Map<String,Object> result=courseAuditRecordService.queryInfo(param);
         return CommonResult.data(result);
     }
+
+    /**
+     * 资源管理-查询最近一次信息
+     *
+     * @author honorfire
+     * @date  2025/06/20 14:58
+     */
+    @ApiOperationSupport(order = 5)
+    @ApiOperation("资源管理-查询最近一次信息")
+    @SaCheckPermission("/disk/courseauditrecord/recentlyRecord")
+    @GetMapping("/disk/courseauditrecord/recentlyRecord")
+    public CommonResult<Map<String,Object>> recentlyRecord(CourseAuditRecordIdParam courseAuditRecordIdParam, HttpServletRequest req) {
+        Map param =new HashMap();
+        String userId = StpLoginUserUtil.getLoginUser().getId();
+        param.put("userId", userId);
+        Map<String,Object> result=courseAuditRecordService.queryRecentlyRecord(param);
+        return CommonResult.data(result);
+    }
+
 }

+ 222 - 5
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/controller/ResourceFileController.java

@@ -1,23 +1,48 @@
 package vip.xiaonuo.disk.controller;
 
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.qiwenshare.common.anno.MyLog;
 import com.qiwenshare.common.result.RestResult;
+import com.qiwenshare.common.util.MimeUtils;
+import com.qiwenshare.ufop.factory.UFOPFactory;
+import com.qiwenshare.ufop.operation.download.Downloader;
+import com.qiwenshare.ufop.operation.download.domain.DownloadFile;
+import com.qiwenshare.ufop.operation.download.domain.Range;
+import com.qiwenshare.ufop.util.UFOPUtils;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.ResponseBody;
-import org.springframework.web.bind.annotation.RestController;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.web.bind.annotation.*;
 import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
+import vip.xiaonuo.disk.domain.FileBean;
+import vip.xiaonuo.disk.domain.ResourceFile;
+import vip.xiaonuo.disk.domain.ResourceUserFile;
+import vip.xiaonuo.disk.domain.UserFile;
+import vip.xiaonuo.disk.dto.file.*;
+import vip.xiaonuo.disk.io.QiwenFile;
 import vip.xiaonuo.disk.domain.StorageBean;
 import vip.xiaonuo.disk.dto.file.UploadFileDTO;
 import vip.xiaonuo.disk.service.IStorageReService;
 import vip.xiaonuo.disk.service.ResourceFileService;
+import vip.xiaonuo.disk.service.ResourceUserfileService;
 import vip.xiaonuo.disk.vo.file.UploadFileVo;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.stream.Collectors;
 
 @Slf4j
 @Tag(name = "filetransfer", description = "该接口为文件传输接口,主要用来做文件的上传、下载和预览,用于在线教育单拆")
@@ -28,6 +53,14 @@ public class ResourceFileController {
     @Resource
     private ResourceFileService resourceFileService;
 
+    @Resource
+    private ResourceUserfileService resourceUserFileService;
+
+    public static Executor executor = Executors.newFixedThreadPool(20);
+
+    @Resource
+    UFOPFactory ufopFactory;
+
 
 
     @Resource
@@ -65,14 +98,198 @@ public class ResourceFileController {
     @ResponseBody
     public RestResult<UploadFileVo> uploadFile(HttpServletRequest request, UploadFileDTO uploadFileDto) {
         String userId = StpLoginUserUtil.getLoginUser().getId();
+
         boolean isCheckSuccess = storageReService.checkStorage(userId, uploadFileDto.getTotalSize());
         if (!isCheckSuccess) {
             return RestResult.fail().message("存储空间不足");
         }
         resourceFileService.uploadFile(request, uploadFileDto, userId);
 
-        UploadFileVo uploadFileVo = new UploadFileVo();
+        UploadFileVo uploadFileVo =resourceFileService.uploadFile(request, uploadFileDto, userId);
+
+
+        return RestResult.success().data(uploadFileVo);
+
+    }
+
+    @Operation(summary = "下载文件", description = "下载文件接口", tags = {"filetransfer"})
+    @MyLog(operation = "下载文件", module = CURRENT_MODULE)
+    @RequestMapping(value = "/downloadfile", method = RequestMethod.GET)
+    public void downloadFile(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, DownloadFileDTO downloadFileDTO) {
+//        Cookie[] cookieArr = httpServletRequest.getCookies();
+        httpServletResponse.setContentType("application/force-download");// 设置强制下载不打开
+        ResourceUserFile resourceUserFile = resourceUserFileService.queryEntity(downloadFileDTO.getUserFileId());
+        String fileName = "";
+        if (resourceUserFile.getIsDir() == 1) {
+            fileName = resourceUserFile.getFileName() + ".zip";
+        } else {
+            fileName = resourceUserFile.getFileName() + "." + resourceUserFile.getExtendName();
+
+        }
+        try {
+            fileName = new String(fileName.getBytes("utf-8"), "ISO-8859-1");
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+
+        httpServletResponse.addHeader("Content-Disposition", "attachment;fileName=" + fileName);// 设置文件名
+
+        resourceFileService.downloadFile(httpServletResponse, downloadFileDTO);
+
+    }
+
+
+    @Operation(summary = "批量下载文件", description = "批量下载文件", tags = {"filetransfer"})
+    @RequestMapping(value = "/batchDownloadFile", method = RequestMethod.GET)
+    @MyLog(operation = "批量下载文件", module = CURRENT_MODULE)
+    @ResponseBody
+    public void batchDownloadFile(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BatchDownloadFileDTO batchDownloadFileDTO) {
+
+        String files = batchDownloadFileDTO.getUserFileIds();
+        String[] userFileIdStrs = files.split(",");
+        List<String> userFileIds = new ArrayList<>();
+        for(String userFileId : userFileIdStrs) {
+            ResourceUserFile resourceUserFile = resourceUserFileService.getById(userFileId);
+            if (resourceUserFile.getIsDir() == 0) {
+                userFileIds.add(userFileId);
+            } else {
+                QiwenFile qiwenFile = new QiwenFile(resourceUserFile.getFilePath(), resourceUserFile.getFileName(), true);
+                List<ResourceUserFile> userFileList = resourceUserFileService.selectUserFileByLikeRightFilePath(qiwenFile.getPath(), resourceUserFile.getUserId());
+                List<String> userFileIds1 = userFileList.stream().map(ResourceUserFile::getUserFileId).collect(Collectors.toList());
+                userFileIds.add(resourceUserFile.getUserFileId());
+                userFileIds.addAll(userFileIds1);
+            }
+
+        }
+        ResourceUserFile userFile = resourceUserFileService.getById(userFileIdStrs[0]);
+        httpServletResponse.setContentType("application/force-download");// 设置强制下载不打开
+        Date date = new Date();
+        String fileName = String.valueOf(date.getTime());
+        httpServletResponse.addHeader("Content-Disposition", "attachment;fileName=" + fileName + ".zip");// 设置文件名
+    }
+
+    @Operation(summary="预览文件", description="用于文件预览", tags = {"filetransfer"})
+    @GetMapping("/preview")
+    public void preview(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,  PreviewDTO previewDTO) throws IOException {
+
+        if (previewDTO.getPlatform() != null && previewDTO.getPlatform() == 2) {
+            resourceFileService.previewPictureFile(httpServletResponse, previewDTO);
+            return ;
+        }
+
+        ResourceUserFile resourceUserFile = resourceUserFileService.getById(previewDTO.getUserFileId());
+
+
+        String fileName = resourceUserFile.getFileName() + "." + resourceUserFile.getExtendName();
+        try {
+            fileName = new String(fileName.getBytes("utf-8"), "ISO-8859-1");
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+
+        httpServletResponse.addHeader("Content-Disposition", "fileName=" + fileName);// 设置文件名
+        String mime = MimeUtils.getMime(resourceUserFile.getExtendName());
+        httpServletResponse.setHeader("Content-Type", mime);
+        if (UFOPUtils.isImageFile(resourceUserFile.getExtendName())) {
+            httpServletResponse.setHeader("cache-control", "public");
+        }
+
+        ResourceFile resourceFile = resourceFileService.getById(resourceUserFile.getFileId());
+        if (UFOPUtils.isVideoFile(resourceUserFile.getExtendName()) || "mp3".equalsIgnoreCase(resourceUserFile.getExtendName()) || "flac".equalsIgnoreCase(resourceUserFile.getExtendName())) {
+            //获取从那个字节开始读取文件
+            String rangeString = httpServletRequest.getHeader("Range");
+            int start = 0;
+            if (StringUtils.isNotBlank(rangeString)) {
+                start = Integer.parseInt(rangeString.substring(rangeString.indexOf("=") + 1, rangeString.indexOf("-")));
+            }
+
+            Downloader downloader = ufopFactory.getDownloader(resourceFile.getStorageType());
+            DownloadFile downloadFile = new DownloadFile();
+            downloadFile.setFileUrl(resourceFile.getFileUrl());
+            Range range = new Range();
+            range.setStart(start);
+
+            if (start + 1024 * 1024 * 1 >= resourceFile.getFileSize().intValue()) {
+                range.setLength(resourceFile.getFileSize().intValue() - start);
+            } else {
+                range.setLength(1024 * 1024 * 1);
+            }
+            downloadFile.setRange(range);
+            InputStream inputStream = downloader.getInputStream(downloadFile);
+
+            OutputStream outputStream = httpServletResponse.getOutputStream();
+            try {
+
+                //返回码需要为206,代表只处理了部分请求,响应了部分数据
+
+                httpServletResponse.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
+                // 每次请求只返回1MB的视频流
+
+                httpServletResponse.setHeader("Accept-Ranges", "bytes");
+                //设置此次相应返回的数据范围
+                httpServletResponse.setHeader("Content-Range", "bytes " + start + "-" + (resourceFile.getFileSize() - 1) + "/" + resourceFile.getFileSize());
+                IOUtils.copy(inputStream, outputStream);
+
+
+            } finally {
+                IOUtils.closeQuietly(inputStream);
+                IOUtils.closeQuietly(outputStream);
+                if (downloadFile.getOssClient() != null) {
+                    downloadFile.getOssClient().shutdown();
+                }
+            }
+
+
+        } else {
+            resourceFileService.previewFile(httpServletResponse, previewDTO);
+
+        }
+
+    }
+
+    @Operation(summary = "批量删除文件", description = "批量删除文件", tags = {"file"})
+    @RequestMapping(value = "/batchdeletefile", method = RequestMethod.POST)
+    @MyLog(operation = "批量删除文件", module = CURRENT_MODULE)
+    @ResponseBody
+    public RestResult<String> deleteImageByIds(HttpServletRequest httpServletRequest,@RequestBody BatchDeleteFileDTO batchDeleteFileDto) {
+        String userFileIds = batchDeleteFileDto.getUserFileIds();
+        String[] userFileIdList = userFileIds.split(",");
+        resourceUserFileService.update(new UpdateWrapper<ResourceUserFile>().lambda().set(ResourceUserFile::getDeleteFlag, 1).in(ResourceUserFile::getUserFileId, Arrays.asList(userFileIdList)));
+        for (String userFileId : userFileIdList) {
+            executor.execute(()->{
+                resourceUserFileService.deleteResourceUserFile(userFileId, StpLoginUserUtil.getLoginUser().getId());
+            });
+            ResourceUserFile resourceUserFile = resourceUserFileService.getById(userFileId);
+
+
+        }
+
+        return RestResult.success().message("批量删除文件成功");
+    }
+
+    @Operation(summary = "删除文件", description = "可以删除文件或者目录", tags = {"file"})
+    @RequestMapping(value = "/deletefile", method = RequestMethod.POST)
+    @MyLog(operation = "删除文件", module = CURRENT_MODULE)
+    @ResponseBody
+    public RestResult deleteFile(HttpServletRequest httpServletRequest,@RequestBody DeleteFileDTO deleteFileDto) {
+
+//        JwtUser sessionUserBean =  SessionUtil.getSession();
+        String userId = StpLoginUserUtil.getLoginUser().getId();
+        resourceUserFileService.deleteResourceUserFile(deleteFileDto.getUserFileId(), userId);
+        ResourceUserFile resourceUserFile = resourceUserFileService.getById(deleteFileDto.getUserFileId());
+
+        return RestResult.success();
+
+    }
+
+    @Operation(summary = "资源库与素材库拉取文件", description = "真正的上传文件接口", tags = {"filetransfer"})
+    @RequestMapping(value = "/eachOtherExchange", method = RequestMethod.POST)
+    @MyLog(operation = "资源库与素材库拉取文件", module = CURRENT_MODULE)
+    @ResponseBody
+    public RestResult<UploadFileVo> eachOtherExchange(HttpServletRequest request, EachOtherExchangeDTO uploadFileDto) {
+        String userId = StpLoginUserUtil.getLoginUser().getId();
 
+        UploadFileVo uploadFileVo =resourceFileService.eachOtherExchange(request, uploadFileDto, userId);
 
         return RestResult.success().data(uploadFileVo);
 

+ 6 - 2
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/domain/ResourceUserFile.java

@@ -57,7 +57,7 @@ public class ResourceUserFile {
     @ApiModelProperty(value = "DELETE_FLAG", position = 5)
     @TableLogic
     @TableField(fill = FieldFill.INSERT)
-    private Integer deleteFlag;
+    private String deleteFlag;
 
     /** DELETE_TIME */
     @ApiModelProperty(value = "DELETE_TIME", position = 6)
@@ -107,6 +107,10 @@ public class ResourceUserFile {
     @ApiModelProperty(value = "IS_COLLET", position = 16)
     private String isCollet;
 
+    /** FUNC_TYPE */
+    @ApiModelProperty(value = "FUNC_TYPE", position = 16)
+    private String funcType;
+
 
     public ResourceUserFile() {};
     public ResourceUserFile(QiwenFile qiwenFile, String userId, String fileId) {
@@ -126,7 +130,7 @@ public class ResourceUserFile {
         this.setUploadTime(currentTime);
         this.setCreateUserId(userId);
         this.setCreateTime(currentTime);
-        this.deleteFlag = 0;
+        this.deleteFlag = "NOT_DELETE";
     }
 
     public boolean isFile() {

+ 2 - 2
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/dto/courseauditrecord/CourseAuditRecordEditParam.java

@@ -33,12 +33,12 @@ public class CourseAuditRecordEditParam {
 
     /** 主键ID */
     @ApiModelProperty(value = "主键ID", required = true, position = 1)
-    @NotBlank(message = "id不能为空")
+//    @NotBlank(message = "id不能为空")
     private String id;
 
     /** 主键ID组 */
     @ApiModelProperty(value = "主键ID组", required = true, position = 1)
-    @NotBlank(message = "id组不能为空")
+//    @NotBlank(message = "id组不能为空")
     private String ids;
 
     /** 用户附件ID(RESOURCE_USERFILE的id) */

+ 15 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/dto/file/EachOtherExchangeDTO.java

@@ -0,0 +1,15 @@
+package vip.xiaonuo.disk.dto.file;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Data
+@Schema(name = "互相拉取文件DTO",required = true)
+public class EachOtherExchangeDTO {
+
+    @Schema(description = "文件附件id")
+    private String userfileId;
+    @Schema(description = "功能标识,0资源库1课程素材库")
+    private String funcType;
+
+}

+ 2 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/dto/file/UploadFileDTO.java

@@ -35,5 +35,7 @@ public class UploadFileDTO {
     private long currentChunkSize;
     @Schema(description = "md5码")
     private String identifier;
+    @Schema(description = "功能标识,0资源库1课程素材库")
+    private String funcType;
 
 }

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

@@ -41,4 +41,9 @@ public interface CourseAuditRecordMapper extends BaseMapper<CourseAuditRecord> {
      * 课程审核-详情
      */
     Map<String,Object> queryInfo(Map param);
+
+    /**
+     * 课程审核-查询最近一次信息
+     */
+    Map<String,Object> queryRecentlyRecord(Map param);
 }

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

@@ -19,6 +19,7 @@
             IFNULL (t1.COLLEGE_THREE_ID,'') AS collegeThreeId,
             IFNULL (t43.NAME,'') AS collegeThreeIdName,
             CONCAT(t1.COLLEGE_ID,',',t1.COLLEGE_TWO_ID,',',t1.COLLEGE_THREE_ID) AS collegeAllId,
+            CONCAT(t4.NAME,',',t42.NAME,',',t43.NAME) AS collegeAllIdName,
             IFNULL (t1.MAJOR_ID,'') AS majorId,
             IFNULL (t5.major_name,'') AS majorIdName,
             IFNULL (t1.COURSE_TYPE,'') AS courseType,
@@ -26,7 +27,7 @@
             IFNULL (t1.COURSE_ID,'') as courseId,
             IFNULL (t3.COURSE_NAME,'') AS courseIdName
         FROM COURSE_AUDIT_RECORD t1
-        LEFT JOIN RESOURCE_USERFILE t2 ON t2.USER_FILE_ID = t1.USERFILE_ID AND t2.DELETE_FLAG ='0'
+        LEFT JOIN RESOURCE_USERFILE t2 ON t2.USER_FILE_ID = t1.USERFILE_ID AND t2.DELETE_FLAG ='NOT_DELETE'
         LEFT JOIN RESOURCE_FILE rf ON t2.FILE_ID= rf.FILE_ID
         LEFT JOIN COURSE_INFO t3 ON t1.COURSE_ID =t3.COURSE_ID AND t3.DELETE_FLAG ='NOT_DELETE'
         LEFT JOIN college t4 ON t1.COLLEGE_ID=t4.id AND t4.DELETE_FLAG ='NOT_DELETE'
@@ -79,15 +80,17 @@
         IFNULL (t1.COLLEGE_ID,'') AS collegeId,
         IFNULL (t4.NAME,'') AS collegeIdName,
         t1.VIEW_COUNT as viewCount,
+        IFNULL (t7.NAME,'') AS resourceCreaterUserName,
         IFNULL (CAST(t6.DOWNLOAD_PATH AS VARCHAR),'') AS coverImagePath
         FROM COURSE_AUDIT_RECORD t1
-        LEFT JOIN RESOURCE_USERFILE t2 ON t2.USER_FILE_ID = t1.USERFILE_ID AND t2.DELETE_FLAG ='0'
+        LEFT JOIN RESOURCE_USERFILE t2 ON t2.USER_FILE_ID = t1.USERFILE_ID AND t2.DELETE_FLAG ='NOT_DELETE'
         LEFT JOIN COURSE_INFO t3 ON t1.COURSE_ID =t3.COURSE_ID AND t3.DELETE_FLAG ='NOT_DELETE'
         LEFT JOIN college t4 ON t1.COLLEGE_ID=t4.id AND t4.DELETE_FLAG ='NOT_DELETE'
         LEFT JOIN major t5 ON t1.MAJOR_ID=t5.id AND t5.DELETE_FLAG ='NOT_DELETE'
         LEFT JOIN college t42 ON t1.COLLEGE_TWO_ID=t42.id AND t42.DELETE_FLAG ='NOT_DELETE'
         LEFT JOIN college t43 ON t1.COLLEGE_THREE_ID=t43.id AND t43.DELETE_FLAG ='NOT_DELETE'
         LEFT JOIN DEV_FILE t6 ON t1.COVER_IMAGE=t6.ID AND t6.DELETE_FLAG ='NOT_DELETE'
+        LEFT JOIN SYS_USER t7 ON t1.CREATE_USER =t7.ID AND t7.DELETE_FLAG ='NOT_DELETE'
         WHERE t1.DELETE_FLAG ='NOT_DELETE'
         <if test="param.verifyStatus!=null and param.verifyStatus != ''">
             and t1.VERIFY_STATUS=#{param.verifyStatus}
@@ -140,6 +143,8 @@
             t1.ID as id,
             t1.USERFILE_ID AS fileId,
             t2.FILE_NAME AS fileName,
+            rf.FILE_URL AS fileUrl,
+            rf.FILE_SIZE AS fileSize,
             t2.CREATE_TIME as uploadTime,
             t2.EXTEND_NAME AS suffix,
             IFNULL (t1.VERIFY_STATUS,'') as verifyStatus,
@@ -152,6 +157,7 @@
             IFNULL (t1.COLLEGE_THREE_ID,'') AS collegeThreeId,
             IFNULL (t43.NAME,'') AS collegeThreeIdName,
             CONCAT(t1.COLLEGE_ID,',',t1.COLLEGE_TWO_ID,',',t1.COLLEGE_THREE_ID) AS collegeAllId,
+            CONCAT(t4.NAME,',',t42.NAME,',',t43.NAME) AS collegeAllIdName,
             IFNULL (t1.MAJOR_ID,'') AS majorId,
             IFNULL (t5.major_name,'') AS majorIdName,
             IFNULL (t1.COURSE_TYPE,'') AS courseType,
@@ -159,19 +165,50 @@
             IFNULL (t1.COURSE_ID,'') as courseId,
             IFNULL (t3.COURSE_NAME,'') AS courseIdName,
             IFNULL (t1.RESOURCE_DESC,'') AS resourceDesc,
+            IFNULL (t7.NAME,'') AS resourceCreaterUserName,
             IFNULL (t1.COVER_IMAGE,'') AS coverImage,
             IFNULL (CAST(t6.DOWNLOAD_PATH AS VARCHAR),'') AS coverImagePath
         FROM COURSE_AUDIT_RECORD t1
-        LEFT JOIN RESOURCE_USERFILE t2 ON t2.USER_FILE_ID = t1.USERFILE_ID AND t2.DELETE_FLAG ='0'
+        LEFT JOIN RESOURCE_USERFILE t2 ON t2.USER_FILE_ID = t1.USERFILE_ID AND t2.DELETE_FLAG ='NOT_DELETE'
+        LEFT JOIN RESOURCE_FILE rf ON t2.FILE_ID= rf.FILE_ID
         LEFT JOIN COURSE_INFO t3 ON t1.COURSE_ID =t3.COURSE_ID AND t3.DELETE_FLAG ='NOT_DELETE'
         LEFT JOIN college t4 ON t1.COLLEGE_ID=t4.id AND t4.DELETE_FLAG ='NOT_DELETE'
         LEFT JOIN major t5 ON t1.MAJOR_ID=t5.id AND t5.DELETE_FLAG ='NOT_DELETE'
         LEFT JOIN college t42 ON t1.COLLEGE_TWO_ID=t42.id AND t42.DELETE_FLAG ='NOT_DELETE'
         LEFT JOIN college t43 ON t1.COLLEGE_THREE_ID=t43.id AND t43.DELETE_FLAG ='NOT_DELETE'
         LEFT JOIN DEV_FILE t6 ON t1.COVER_IMAGE=t6.ID AND t6.DELETE_FLAG ='NOT_DELETE'
+        LEFT JOIN SYS_USER t7 ON t1.CREATE_USER =t7.ID AND t7.DELETE_FLAG ='NOT_DELETE'
         WHERE t1.DELETE_FLAG ='NOT_DELETE'
         <if test="id!=null and id != ''">
             and t1.ID =#{id}
         </if>
     </select>
+
+    <select id="queryRecentlyRecord" resultType="java.util.Map">
+        SELECT
+            t1.ID as id,
+            IFNULL (t1.COLLEGE_ID,'') AS collegeId,
+            IFNULL (t4.NAME,'') AS collegeIdName,
+            IFNULL (t1.COLLEGE_TWO_ID,'') AS collegeTwoId,
+            IFNULL (t42.NAME,'') AS collegeTwoIdName,
+            IFNULL (t1.COLLEGE_THREE_ID,'') AS collegeThreeId,
+            IFNULL (t43.NAME,'') AS collegeThreeIdName,
+            CONCAT(t1.COLLEGE_ID,',',t1.COLLEGE_TWO_ID,',',t1.COLLEGE_THREE_ID) AS collegeAllId,
+            CONCAT(t4.NAME,',',t42.NAME,',',t43.NAME) AS collegeAllIdName,
+            IFNULL (t1.MAJOR_ID,'') AS majorId,
+            IFNULL (t5.major_name,'') AS majorIdName,
+            IFNULL (t1.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(t1.COURSE_TYPE) ),'') AS courseTypeName
+        FROM COURSE_AUDIT_RECORD t1
+        LEFT JOIN college t4 ON t1.COLLEGE_ID=t4.id AND t4.DELETE_FLAG ='NOT_DELETE'
+        LEFT JOIN major t5 ON t1.MAJOR_ID=t5.id AND t5.DELETE_FLAG ='NOT_DELETE'
+        LEFT JOIN college t42 ON t1.COLLEGE_TWO_ID=t42.id AND t42.DELETE_FLAG ='NOT_DELETE'
+        LEFT JOIN college t43 ON t1.COLLEGE_THREE_ID=t43.id AND t43.DELETE_FLAG ='NOT_DELETE'
+        WHERE t1.DELETE_FLAG ='NOT_DELETE'
+        <if test="userId!=null and userId != ''">
+            and t1.CREATE_USER =#{userId}
+        </if>
+        ORDER BY t1.ID desc
+        limit 1
+    </select>
 </mapper>

+ 2 - 2
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/mapping/MajorMapper.xml

@@ -7,7 +7,7 @@
             a.major_name majorName,
             a.major_code majorCode,
             a.college_id collegeId,
-            b.college_name collegeName,
+            b.name collegeName,
             a.create_time createTime,
             a.create_user createUser
         FROM
@@ -28,7 +28,7 @@
             a.major_name majorName,
             a.major_code majorCode,
             a.college_id collegeId,
-            b.college_name collegeName,
+            b.name collegeName,
             a.create_time createTime,
             a.create_user createUser
         FROM

+ 1 - 1
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/mapper/mapping/ResourceUserFileMapper.xml

@@ -10,7 +10,7 @@
 
     <select id="selectStorageSizeByUserId" resultType="java.lang.Long" parameterType="java.lang.String">
         SELECT SUM(FILE_SIZE) FROM RESOURCE_USERFILE
-                                       LEFT JOIN RESOURCE_FILE ON file.FILE_ID = userfile.FILE_ID
+                                       LEFT JOIN RESOURCE_FILE ON RESOURCE_FILE.FILE_ID = RESOURCE_USERFILE.FILE_ID
         WHERE RESOURCE_USERFILE.USER_ID = #{userId}
     </select>
 

+ 5 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/CourseAuditRecordService.java

@@ -134,4 +134,9 @@ public interface CourseAuditRecordService extends IService<CourseAuditRecord> {
      */
     Map<String,Object> queryInfo(Map param);
 
+    /**
+     *  课程审核-查询最近一次信息
+     */
+    Map<String,Object> queryRecentlyRecord(Map param);
+
 }

+ 21 - 2
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/ResourceFileService.java

@@ -1,15 +1,34 @@
 package vip.xiaonuo.disk.service;
 
+import com.baomidou.mybatisplus.extension.service.IService;
+import vip.xiaonuo.disk.domain.FileBean;
+import vip.xiaonuo.disk.domain.ResourceFile;
+import vip.xiaonuo.disk.dto.file.DownloadFileDTO;
+import vip.xiaonuo.disk.dto.file.EachOtherExchangeDTO;
+import vip.xiaonuo.disk.dto.file.PreviewDTO;
 import vip.xiaonuo.disk.dto.file.UploadFileDTO;
 import vip.xiaonuo.disk.vo.file.UploadFileVo;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
 
-public interface ResourceFileService {
+public interface ResourceFileService extends IService<ResourceFile> {
 
     UploadFileVo uploadFileSpeed(HttpServletRequest request,String userId,UploadFileDTO uploadFileDTO);
 
-    void uploadFile(HttpServletRequest request, UploadFileDTO UploadFileDto, String userId);
+    UploadFileVo uploadFile(HttpServletRequest request, UploadFileDTO UploadFileDto, String userId);
+
+    void downloadFile(HttpServletResponse httpServletResponse, DownloadFileDTO downloadFileDTO);
+
+    void downloadUserFileList(HttpServletResponse httpServletResponse, String filePath, String fileName, List<String> userFileIds);
+
+    void previewPictureFile(HttpServletResponse httpServletResponse, PreviewDTO previewDTO);
+
+    void previewFile(HttpServletResponse httpServletResponse, PreviewDTO previewDTO);
+
+    UploadFileVo eachOtherExchange(HttpServletRequest request, EachOtherExchangeDTO UploadFileDto, String userId);
+
 
     Long selectStorageSizeByUserId(String userId);
 }

+ 9 - 0
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/ResourceUserfileService.java

@@ -14,12 +14,16 @@ package vip.xiaonuo.disk.service;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
+import org.apache.ibatis.annotations.Param;
 import vip.xiaonuo.disk.domain.ResourceUserFile;
+import vip.xiaonuo.disk.domain.UserFile;
+import vip.xiaonuo.disk.dto.file.PreviewDTO;
 import vip.xiaonuo.disk.dto.resourceuserfile.ResourceUserFileAddParam;
 import vip.xiaonuo.disk.dto.resourceuserfile.ResourceUserFileEditParam;
 import vip.xiaonuo.disk.dto.resourceuserfile.ResourceUserFileIdParam;
 import vip.xiaonuo.disk.dto.resourceuserfile.ResourceUserFilePageParam;
 
+import javax.servlet.http.HttpServletResponse;
 import java.util.List;
 
 /**
@@ -78,4 +82,9 @@ public interface ResourceUserfileService extends IService<ResourceUserFile> {
      **/
     ResourceUserFile queryEntity(String id);
 
+    List<ResourceUserFile> selectUserFileByLikeRightFilePath(@Param("filePath") String filePath, @Param("userId") String userId);
+
+    void deleteResourceUserFile(String userFileId, String sessionUserId);
+
+
 }

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

@@ -171,4 +171,10 @@ public class CourseAuditRecordServiceImpl extends ServiceImpl<CourseAuditRecordM
         return courseAuditRecordMapper.queryInfo(param);
     }
 
+    @Override
+    public Map<String,Object> queryRecentlyRecord(Map param)
+    {
+        return courseAuditRecordMapper.queryRecentlyRecord(param);
+    }
+
 }

+ 261 - 13
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/impl/ResourceFileServiceImpl.java

@@ -1,23 +1,39 @@
 package vip.xiaonuo.disk.service.impl;
 
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson2.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qiwenshare.common.constant.FileConstant;
+import com.qiwenshare.common.result.RestResult;
 import com.qiwenshare.common.util.DateUtil;
+import com.qiwenshare.common.util.MimeUtils;
 import com.qiwenshare.ufop.constant.UploadFileStatusEnum;
+import com.qiwenshare.ufop.exception.operation.DownloadException;
 import com.qiwenshare.ufop.exception.operation.UploadException;
 import com.qiwenshare.ufop.factory.UFOPFactory;
+import com.qiwenshare.ufop.operation.download.Downloader;
+import com.qiwenshare.ufop.operation.download.domain.DownloadFile;
+import com.qiwenshare.ufop.operation.preview.Previewer;
+import com.qiwenshare.ufop.operation.preview.domain.PreviewFile;
 import com.qiwenshare.ufop.operation.upload.Uploader;
 import com.qiwenshare.ufop.operation.upload.domain.UploadFile;
 import com.qiwenshare.ufop.operation.upload.domain.UploadFileResult;
 import com.qiwenshare.ufop.util.UFOPUtils;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import vip.xiaonuo.disk.component.ResourceFileDealComp;
 import vip.xiaonuo.disk.domain.*;
+import vip.xiaonuo.disk.dto.file.DownloadFileDTO;
+import vip.xiaonuo.disk.dto.file.EachOtherExchangeDTO;
+import vip.xiaonuo.disk.dto.file.PreviewDTO;
 import vip.xiaonuo.disk.dto.file.UploadFileDTO;
 import vip.xiaonuo.disk.io.QiwenFile;
 import vip.xiaonuo.disk.mapper.*;
@@ -27,24 +43,31 @@ import vip.xiaonuo.disk.vo.file.UploadFileVo;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import java.awt.image.BufferedImage;
+import java.io.*;
+import java.util.*;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
+import java.util.stream.Collectors;
+import java.util.zip.Adler32;
+import java.util.zip.CheckedOutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
 
 @Slf4j
 @Service
 @Transactional(rollbackFor=Exception.class)
-public class ResourceFileServiceImpl implements ResourceFileService {
+public class ResourceFileServiceImpl extends ServiceImpl<ResourceFileMapper, ResourceFile> implements ResourceFileService {
 
     @Resource
     ResourceFileMapper resourceFileMapper;
 
     @Resource
     ResourceUserFileMapper resourceUserFileMapper;
-
     @Resource
     UFOPFactory ufopFactory;
     @Resource
@@ -55,6 +78,10 @@ public class ResourceFileServiceImpl implements ResourceFileService {
     UploadTaskMapper uploadTaskMapper;
     @Resource
     ImageMapper imageMapper;
+    @Resource
+    PictureFileMapper pictureFileMapper;
+
+
 
     @Resource
     OperationLogUtil operationLogUtil;
@@ -69,7 +96,11 @@ public class ResourceFileServiceImpl implements ResourceFileService {
     @Override
     public UploadFileVo uploadFileSpeed(HttpServletRequest request,String userId,UploadFileDTO uploadFileDTO) {
         UploadFileVo uploadFileVo = new UploadFileVo();
+        String funcType="0";
+        if(StringUtils.isNotEmpty(uploadFileDTO.getFuncType()))funcType=uploadFileDTO.getFuncType();
+
         Map<String, Object> param = new HashMap<>();
+        //看看该md5批次号有没有对应存在的文件
         param.put("identifier", uploadFileDTO.getIdentifier());
         List<ResourceFile> list = resourceFileMapper.selectByMap(param);
 
@@ -82,30 +113,35 @@ public class ResourceFileServiceImpl implements ResourceFileService {
             qiwenFile = new QiwenFile(filePath, uploadFileDTO.getFilename(), false);
         }
 
+        //如果有这个文件,取第一个重新绑定一下该用户即可
         if (list != null && !list.isEmpty()) {
             ResourceFile file = list.get(0);
             ResourceUserFile resourceUserFile = new ResourceUserFile(qiwenFile, userId, file.getFileId());
 
             try {
                 resourceUserFile.setIsCollet("0");
+                resourceUserFile.setFuncType(funcType);
                 resourceUserFileMapper.insert(resourceUserFile);
+                uploadFileVo.setUploadStatus("1");
             } catch (Exception e) {
                 log.warn("极速上传文件冲突重命名处理: {}", JSON.toJSONString(resourceUserFile));
 
             }
 
-//            if (relativePath.contains("/")) {
-//                QiwenFile finalQiwenFile = qiwenFile;
-//                exec.execute(()->{
-//                    resourceFileDealComp.restoreParentFilePath(finalQiwenFile, userId);
-//                });
-//
-//            }
+            //此处
+            if (relativePath.contains("/")) {
+                QiwenFile finalQiwenFile = qiwenFile;
+                exec.execute(()->{
+                    resourceFileDealComp.restoreParentFilePath(finalQiwenFile, userId);
+                });
+
+            }
             uploadFileVo.setSkipUpload(true);
+            uploadFileVo.setUserFileId(resourceUserFile.getUserFileId());
 
         } else {
             uploadFileVo.setSkipUpload(false);
-
+            uploadFileVo.setUploadStatus("0");
             List<Integer> uploaded = uploadTaskDetailMapper.selectUploadedChunkNumList(uploadFileDTO.getIdentifier());
             if (uploaded != null && !uploaded.isEmpty()) {
                 uploadFileVo.setUploaded(uploaded);
@@ -134,8 +170,10 @@ public class ResourceFileServiceImpl implements ResourceFileService {
     }
 
     @Override
-    public void uploadFile(HttpServletRequest request, UploadFileDTO uploadFileDto, String userId) {
-
+    public UploadFileVo uploadFile(HttpServletRequest request, UploadFileDTO uploadFileDto, String userId) {
+        UploadFileVo uploadFileVo = new UploadFileVo();
+        String funcType="0";
+        if(StringUtils.isNotEmpty(uploadFileDto.getFuncType()))funcType=uploadFileDto.getFuncType();
         UploadFile uploadFile = new UploadFile();
         uploadFile.setChunkNumber(uploadFileDto.getChunkNumber());
         uploadFile.setChunkSize(uploadFileDto.getChunkSize());
@@ -181,6 +219,7 @@ public class ResourceFileServiceImpl implements ResourceFileService {
 
                 try {
                     resourceUserFile.setIsCollet("0");
+                    resourceUserFile.setFuncType(funcType);
                     resourceUserFileMapper.insert(resourceUserFile);
 
                 } catch (Exception e) {
@@ -199,7 +238,8 @@ public class ResourceFileServiceImpl implements ResourceFileService {
                         resourceUserFileMapper.insert(resourceUserFile);
                     }
                 }
-
+                uploadFileVo.setUserFileId(resourceUserFile.getUserFileId());
+                uploadFileVo.setUploadStatus("1");
 
                 if (relativePath.contains("/")) {
                     QiwenFile finalQiwenFile = qiwenFile;
@@ -244,6 +284,7 @@ public class ResourceFileServiceImpl implements ResourceFileService {
                 uploadTaskDetail.setTotalSize((int)uploadFileDto.getTotalSize());
                 uploadTaskDetail.setIdentifier(uploadFileDto.getIdentifier());
                 uploadTaskDetailMapper.insert(uploadTaskDetail);
+                uploadFileVo.setUploadStatus("0");
 
             } else if (UploadFileStatusEnum.FAIL.equals(uploadFileResult.getStatus())) {
                 LambdaQueryWrapper<UploadTaskDetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
@@ -254,11 +295,218 @@ public class ResourceFileServiceImpl implements ResourceFileService {
                 lambdaUpdateWrapper.set(UploadTask::getUploadStatus, UploadFileStatusEnum.FAIL.getCode())
                         .eq(UploadTask::getIdentifier, uploadFileDto.getIdentifier());
                 uploadTaskMapper.update(null, lambdaUpdateWrapper);
+                uploadFileVo.setUploadStatus("2");
+            }
+        }
+        uploadFileVo.setSkipUpload(false);
+        return uploadFileVo;
+    }
+
+
+    @Override
+    public void downloadFile(HttpServletResponse httpServletResponse, DownloadFileDTO downloadFileDTO) {
+        ResourceUserFile resourceUserFile = resourceUserFileMapper.selectById(downloadFileDTO.getUserFileId());
+
+        if (resourceUserFile.isFile()) {
+
+            ResourceFile fileBean = resourceFileMapper.selectById(resourceUserFile.getFileId());
+            Downloader downloader = ufopFactory.getDownloader(fileBean.getStorageType());
+            if (downloader == null) {
+                log.error("下载失败,文件存储类型不支持下载,storageType:{}", fileBean.getStorageType());
+                throw new DownloadException("下载失败");
+            }
+            DownloadFile downloadFile = new DownloadFile();
+
+            downloadFile.setFileUrl(fileBean.getFileUrl());
+            httpServletResponse.setContentLengthLong(fileBean.getFileSize());
+            downloader.download(httpServletResponse, downloadFile);
+        } else {
+
+            QiwenFile qiwenFile = new QiwenFile(resourceUserFile.getFilePath(), resourceUserFile.getFileName(), true);
+            List<ResourceUserFile> userFileList = resourceUserFileMapper.selectUserFileByLikeRightFilePath(qiwenFile.getPath() , resourceUserFile.getUserId());
+            List<String> userFileIds = userFileList.stream().map(ResourceUserFile::getUserFileId).collect(Collectors.toList());
+
+            downloadUserFileList(httpServletResponse, resourceUserFile.getFilePath(), resourceUserFile.getFileName(), userFileIds);
+        }
+    }
+
+    @Override
+    public void downloadUserFileList(HttpServletResponse httpServletResponse, String filePath, String fileName, List<String> userFileIds) {
+        String staticPath = UFOPUtils.getStaticPath();
+        String tempPath = staticPath + "temp" + File.separator;
+        File tempDirFile = new File(tempPath);
+        if (!tempDirFile.exists()) {
+            tempDirFile.mkdirs();
+        }
+
+        FileOutputStream f = null;
+        try {
+            f = new FileOutputStream(tempPath + fileName + ".zip");
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        }
+        CheckedOutputStream csum = new CheckedOutputStream(f, new Adler32());
+        ZipOutputStream zos = new ZipOutputStream(csum);
+        BufferedOutputStream out = new BufferedOutputStream(zos);
+
+        try {
+            for (String userFileId : userFileIds) {
+                ResourceUserFile resourceUserFile1 = resourceUserFileMapper.selectById(userFileId);
+                if (resourceUserFile1.isFile()) {
+                    ResourceFile fileBean = resourceFileMapper.selectById(resourceUserFile1.getFileId());
+                    Downloader downloader = ufopFactory.getDownloader(fileBean.getStorageType());
+                    if (downloader == null) {
+                        log.error("下载失败,文件存储类型不支持下载,storageType:{}", fileBean.getStorageType());
+                        throw new UploadException("下载失败");
+                    }
+                    DownloadFile downloadFile = new DownloadFile();
+                    downloadFile.setFileUrl(fileBean.getFileUrl());
+                    InputStream inputStream = downloader.getInputStream(downloadFile);
+                    BufferedInputStream bis = new BufferedInputStream(inputStream);
+                    try {
+                        QiwenFile qiwenFile = new QiwenFile(StrUtil.removePrefix(resourceUserFile1.getFilePath(), filePath), resourceUserFile1.getFileName() + "." + resourceUserFile1.getExtendName(), false);
+                        zos.putNextEntry(new ZipEntry(qiwenFile.getPath()));
+
+                        byte[] buffer = new byte[1024];
+                        int i = bis.read(buffer);
+                        while (i != -1) {
+                            out.write(buffer, 0, i);
+                            i = bis.read(buffer);
+                        }
+                    } catch (IOException e) {
+                        log.error("" + e);
+                        e.printStackTrace();
+                    } finally {
+                        IOUtils.closeQuietly(bis);
+                        try {
+                            out.flush();
+                        } catch (IOException e) {
+                            e.printStackTrace();
+                        }
+                    }
+                } else {
+                    QiwenFile qiwenFile = new QiwenFile(StrUtil.removePrefix(resourceUserFile1.getFilePath(), filePath), resourceUserFile1.getFileName(), true);
+                    // 空文件夹的处理
+                    zos.putNextEntry(new ZipEntry(qiwenFile.getPath() + QiwenFile.separator));
+                    // 没有文件,不需要文件的copy
+                    zos.closeEntry();
+                }
+            }
+
+        } catch (Exception e) {
+            log.error("压缩过程中出现异常:" + e);
+        } finally {
+            try {
+                out.close();
+            } catch (IOException e) {
+                e.printStackTrace();
             }
         }
+    }
+
+    @Override
+    public void previewPictureFile(HttpServletResponse httpServletResponse, PreviewDTO previewDTO) {
+        byte[] bytesUrl = Base64.getDecoder().decode(previewDTO.getUrl());
+        PictureFile pictureFile = new PictureFile();
+        pictureFile.setFileUrl(new String(bytesUrl));
+        pictureFile = pictureFileMapper.selectOne(new QueryWrapper<>(pictureFile));
+        Previewer previewer = ufopFactory.getPreviewer(pictureFile.getStorageType());
+        if (previewer == null) {
+            log.error("预览失败,文件存储类型不支持预览,storageType:{}", pictureFile.getStorageType());
+            throw new UploadException("预览失败");
+        }
+        PreviewFile previewFile = new PreviewFile();
+        previewFile.setFileUrl(pictureFile.getFileUrl());
+//        previewFile.setFileSize(pictureFile.getFileSize());
+        try {
+
+            String mime= MimeUtils.getMime(pictureFile.getExtendName());
+            httpServletResponse.setHeader("Content-Type", mime);
+
+            String fileName = pictureFile.getFileName() + "." + pictureFile.getExtendName();
+            try {
+                fileName = new String(fileName.getBytes("utf-8"), "ISO-8859-1");
+            } catch (UnsupportedEncodingException e) {
+                e.printStackTrace();
+            }
+
+            httpServletResponse.addHeader("Content-Disposition", "fileName=" + fileName);// 设置文件名
+
+            previewer.imageOriginalPreview(httpServletResponse, previewFile);
+        } catch (Exception e){
+            //org.apache.catalina.connector.ClientAbortException: java.io.IOException: 你的主机中的软件中止了一个已建立的连接。
+            if (e.getMessage().contains("ClientAbortException")) {
+                //该异常忽略不做处理
+            } else {
+                log.error("预览文件出现异常:{}", e.getMessage());
+            }
 
+        }
     }
 
+    @Override
+    public void previewFile(HttpServletResponse httpServletResponse, PreviewDTO previewDTO) {
+        ResourceUserFile resourceUserFile = resourceUserFileMapper.selectById(previewDTO.getUserFileId());
+        ResourceFile resourceFile = resourceFileMapper.selectById(resourceUserFile.getFileId());
+        Previewer previewer = ufopFactory.getPreviewer(resourceFile.getStorageType());
+        if (previewer == null) {
+            log.error("预览失败,文件存储类型不支持预览,storageType:{}", resourceFile.getStorageType());
+            throw new UploadException("预览失败");
+        }
+        PreviewFile previewFile = new PreviewFile();
+        previewFile.setFileUrl(resourceFile.getFileUrl());
+        try {
+            if ("true".equals(previewDTO.getIsMin())) {
+                previewer.imageThumbnailPreview(httpServletResponse, previewFile);
+            } else {
+                previewer.imageOriginalPreview(httpServletResponse, previewFile);
+            }
+        } catch (Exception e){
+            //org.apache.catalina.connector.ClientAbortException: java.io.IOException: 你的主机中的软件中止了一个已建立的连接。
+            if (e.getMessage().contains("ClientAbortException")) {
+                //该异常忽略不做处理
+            } else {
+                log.error("预览文件出现异常:{}", e.getMessage());
+            }
+
+        }
+
+    }
+
+    @Override
+    public UploadFileVo eachOtherExchange(HttpServletRequest request, EachOtherExchangeDTO UploadFileDto, String userId) {
+        UploadFileVo uploadFileVo = new UploadFileVo();
+        ResourceUserFile oldResourceUserFile = resourceUserFileMapper.selectById(UploadFileDto.getUserfileId());
+        QiwenFile qiwenFile = null;
+        qiwenFile = new QiwenFile(oldResourceUserFile.getFilePath(), oldResourceUserFile.getFileName(), false);
+        ResourceUserFile resourceUserFile = new ResourceUserFile(qiwenFile, userId, oldResourceUserFile.getFileId());
+
+        try {
+            resourceUserFile.setIsCollet("0");
+            resourceUserFile.setFuncType(UploadFileDto.getFuncType());
+            resourceUserFileMapper.insert(resourceUserFile);
+            uploadFileVo.setUploadStatus("1");
+        } catch (Exception e) {
+            log.warn("极速上传文件冲突重命名处理: {}", JSON.toJSONString(resourceUserFile));
+
+        }
+
+        //此处
+        if (oldResourceUserFile.getFilePath().contains("/")) {
+            QiwenFile finalQiwenFile = qiwenFile;
+            exec.execute(() -> {
+                resourceFileDealComp.restoreParentFilePath(finalQiwenFile, userId);
+            });
+
+        }
+        uploadFileVo.setSkipUpload(true);
+        uploadFileVo.setUserFileId(resourceUserFile.getUserFileId());
+
+        return uploadFileVo;
+    }
+
+
+
     @Override
     public Long selectStorageSizeByUserId(String userId) {
         return resourceUserFileMapper.selectStorageSizeByUserId(userId);

+ 75 - 1
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/service/impl/ResourceUserfileServiceImpl.java

@@ -15,24 +15,45 @@ 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.RandomUtil;
 import cn.hutool.core.util.StrUtil;
 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 com.qiwenshare.common.constant.FileConstant;
+import com.qiwenshare.common.util.DateUtil;
+import com.qiwenshare.common.util.MimeUtils;
+import com.qiwenshare.ufop.exception.operation.UploadException;
+import com.qiwenshare.ufop.operation.preview.Previewer;
+import com.qiwenshare.ufop.operation.preview.domain.PreviewFile;
+import org.apache.commons.collections4.CollectionUtils;
 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.PictureFile;
 import vip.xiaonuo.disk.domain.ResourceUserFile;
+import vip.xiaonuo.disk.domain.UserFile;
+import vip.xiaonuo.disk.dto.file.PreviewDTO;
 import vip.xiaonuo.disk.dto.resourceuserfile.ResourceUserFileAddParam;
 import vip.xiaonuo.disk.dto.resourceuserfile.ResourceUserFileEditParam;
 import vip.xiaonuo.disk.dto.resourceuserfile.ResourceUserFileIdParam;
 import vip.xiaonuo.disk.dto.resourceuserfile.ResourceUserFilePageParam;
+import vip.xiaonuo.disk.io.QiwenFile;
 import vip.xiaonuo.disk.mapper.ResourceUserFileMapper;
 import vip.xiaonuo.disk.service.ResourceUserfileService;
 
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import java.io.UnsupportedEncodingException;
+import java.util.Base64;
 import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.stream.Collectors;
 
 /**
  * RESOURCE_USERFILEService接口实现类
@@ -43,6 +64,9 @@ import java.util.List;
 @Service
 public class ResourceUserfileServiceImpl extends ServiceImpl<ResourceUserFileMapper, ResourceUserFile> implements ResourceUserfileService {
 
+    @Resource
+    private ResourceUserFileMapper resourceUserFileMapper;
+    public static Executor executor = Executors.newFixedThreadPool(20);
 
     @Override
     public Page<ResourceUserFile> page(ResourceUserFilePageParam ResourceUserFilePageParam) {
@@ -86,11 +110,61 @@ public class ResourceUserfileServiceImpl extends ServiceImpl<ResourceUserFileMap
 
     @Override
     public ResourceUserFile queryEntity(String id) {
-        ResourceUserFile ResourceUserFile = this.getById(id);
+        ResourceUserFile ResourceUserFile = resourceUserFileMapper.selectById(id);
         if(ObjectUtil.isEmpty(ResourceUserFile)) {
             throw new CommonException("RESOURCE_USERFILE不存在,id值为:{}", id);
         }
         return ResourceUserFile;
     }
 
+    @Override
+    public List<ResourceUserFile> selectUserFileByLikeRightFilePath(String filePath, String userId) {
+        return resourceUserFileMapper.selectUserFileByLikeRightFilePath(filePath, userId);
+    }
+
+    @Override
+    public void deleteResourceUserFile(String userFileId, String sessionUserId) {
+        ResourceUserFile resourceUserFile = resourceUserFileMapper.selectById(userFileId);
+        String uuid = UUID.randomUUID().toString();
+        if (resourceUserFile.getIsDir() == 1) {
+            LambdaUpdateWrapper<ResourceUserFile> resourceUserFileLambdaUpdateWrapper = new LambdaUpdateWrapper<ResourceUserFile>();
+            resourceUserFileLambdaUpdateWrapper.set(ResourceUserFile::getDeleteFlag, RandomUtil.randomInt(FileConstant.deleteFileRandomSize))
+                    .set(ResourceUserFile::getDeleteBatchNum, uuid)
+                    .set(ResourceUserFile::getDeleteTime, DateUtil.getCurrentTime())
+                    .eq(ResourceUserFile::getUserFileId, userFileId);
+            resourceUserFileMapper.update(null, resourceUserFileLambdaUpdateWrapper);
+
+            String filePath = new QiwenFile(resourceUserFile.getFilePath(), resourceUserFile.getFileName(), true).getPath();
+            updateFileDeleteStateByFilePath(filePath, uuid, sessionUserId);
+
+        } else {
+            LambdaUpdateWrapper<ResourceUserFile> resourceUserFileLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+            resourceUserFileLambdaUpdateWrapper.set(ResourceUserFile::getDeleteFlag, RandomUtil.randomInt(1, FileConstant.deleteFileRandomSize))
+                    .set(ResourceUserFile::getDeleteTime, DateUtil.getCurrentTime())
+                    .set(ResourceUserFile::getDeleteBatchNum, uuid)
+                    .eq(ResourceUserFile::getUserFileId, userFileId);
+            resourceUserFileMapper.update(null, resourceUserFileLambdaUpdateWrapper);
+        }
+
+    }
+
+    private void updateFileDeleteStateByFilePath(String filePath, String deleteBatchNum, String userId) {
+        executor.execute(() -> {
+            List<ResourceUserFile> fileList = resourceUserFileMapper.selectUserFileByLikeRightFilePath(filePath, userId);
+            List<String> userFileIds = fileList.stream().map(ResourceUserFile::getUserFileId).collect(Collectors.toList());
+
+            //标记删除标志
+            if (CollectionUtils.isNotEmpty(userFileIds)) {
+                LambdaUpdateWrapper<ResourceUserFile> resourceUserFileLambdaUpdateWrapper1 = new LambdaUpdateWrapper<>();
+                resourceUserFileLambdaUpdateWrapper1.set(ResourceUserFile::getDeleteFlag, RandomUtil.randomInt(FileConstant.deleteFileRandomSize))
+                        .set(ResourceUserFile::getDeleteTime, DateUtil.getCurrentTime())
+                        .set(ResourceUserFile::getDeleteBatchNum, deleteBatchNum)
+                        .in(ResourceUserFile::getUserFileId, userFileIds)
+                        .eq(ResourceUserFile::getDeleteFlag, "NOT_DELETE");
+                resourceUserFileMapper.update(null, resourceUserFileLambdaUpdateWrapper1);
+            }
+        });
+    }
+
+
 }

+ 1 - 1
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/util/QiwenFileUtil.java

@@ -40,7 +40,7 @@ public class QiwenFileUtil {
         userFile.setUploadTime(DateUtil.getCurrentTime());
         userFile.setCreateUserId(userId);
         userFile.setCreateTime(DateUtil.getCurrentTime());
-        userFile.setDeleteFlag(0);
+        userFile.setDeleteFlag("NOT_DELETE");
         userFile.setDeleteBatchNum(null);
         return userFile;
     }

+ 3 - 1
snowy-plugin/snowy-plugin-disk/snowy-plugin-disk-func/src/main/java/vip/xiaonuo/disk/vo/file/UploadFileVo.java

@@ -17,8 +17,10 @@ public class UploadFileVo {
     private boolean needMerge;
     @Schema(description = "已经上传的分片", example = "[1,2,3]")
     private List<Integer> uploaded;
-    @Schema(description = "文件用户关联id", example = "true")
+    @Schema(description = "文件用户关联id", example = "1939949820907716608")
     private String userFileId;
+    @Schema(description = "上传状态", example = "0上传中1上传成功2上传失败")
+    private String uploadStatus;
 
 
 

+ 5 - 0
snowy-server/snowy-gateway-app/src/main/java/vip/xiaonuo/gateway/config/GatewayConfigure.java

@@ -137,6 +137,11 @@ public class GatewayConfigure {
 
             "/api/tenapp/ten/storage/tenSelector",
 
+            /* 资源中心 */
+            "/api/webapp/disk/resourcecentre/page",
+            "/api/webapp/disk/resourcecentre/detail",
+            "/api/webapp/disk/courseauditrecord/addViewCount"
+
 
     };