diff --git a/tduck-api/src/main/java/com/tduck/cloud/api/web/controller/CommonController.java b/tduck-api/src/main/java/com/tduck/cloud/api/web/controller/CommonController.java new file mode 100644 index 0000000..216fd4e --- /dev/null +++ b/tduck-api/src/main/java/com/tduck/cloud/api/web/controller/CommonController.java @@ -0,0 +1,27 @@ +package com.tduck.cloud.api.web.controller; + +import com.tduck.cloud.common.util.AsyncProcessUtils; +import com.tduck.cloud.common.util.Result; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author : smalljop + * @description : 通用 + * @create : 2021/06/08 15:32 + **/ +@RestController +@RequestMapping("/common/") +public class CommonController { + + + /** + * 获取异步处理进度 + */ + @GetMapping("/process") + public Result getProcess(@RequestParam String key) { + return Result.success(AsyncProcessUtils.getProcess(key)); + } +} diff --git a/tduck-api/src/main/java/com/tduck/cloud/api/web/controller/ProjectController.java b/tduck-api/src/main/java/com/tduck/cloud/api/web/controller/ProjectController.java index 1ce3508..0c1678e 100644 --- a/tduck-api/src/main/java/com/tduck/cloud/api/web/controller/ProjectController.java +++ b/tduck-api/src/main/java/com/tduck/cloud/api/web/controller/ProjectController.java @@ -22,9 +22,10 @@ import java.util.List; * @description : * @create : 2020-11-24 10:13 **/ -@RequiredArgsConstructor + @RestController @RequestMapping("/project/") +@RequiredArgsConstructor public class ProjectController { private final ProjectThemeService projectThemeService; diff --git a/tduck-api/src/main/java/com/tduck/cloud/api/web/controller/UserProjectResultController.java b/tduck-api/src/main/java/com/tduck/cloud/api/web/controller/UserProjectResultController.java index 47c3554..ec01880 100644 --- a/tduck-api/src/main/java/com/tduck/cloud/api/web/controller/UserProjectResultController.java +++ b/tduck-api/src/main/java/com/tduck/cloud/api/web/controller/UserProjectResultController.java @@ -42,10 +42,11 @@ import static com.tduck.cloud.project.constant.ProjectRedisKeyConstants.PROJECT_ * @description : 项目 * @create : 2020-11-18 18:17 **/ -@RequiredArgsConstructor + +@Slf4j @RestController +@RequiredArgsConstructor @RequestMapping("/user/project/result") -@Slf4j public class UserProjectResultController { private final UserProjectService projectService; @@ -131,10 +132,10 @@ public class UserProjectResultController { * @param request * @return */ - @Login +// @Login @GetMapping("/download/file") - public void downloadProjectResultFile(QueryProjectResultRequest request) { - projectResultService.downloadProjectResultFile(request); + public Result downloadProjectResultFile(QueryProjectResultRequest request) { + return projectResultService.downloadProjectResultFile(request); } @@ -144,8 +145,8 @@ public class UserProjectResultController { * @param request * @return */ - @GetMapping("/page") @Login + @GetMapping("/page") public Result queryProjectResults(QueryProjectResultRequest request) { return Result.success(projectResultService.listByQueryConditions(request)); } diff --git a/tduck-common/src/main/java/com/tduck/cloud/common/util/AsyncProcessUtils.java b/tduck-common/src/main/java/com/tduck/cloud/common/util/AsyncProcessUtils.java new file mode 100644 index 0000000..8cd1e6d --- /dev/null +++ b/tduck-common/src/main/java/com/tduck/cloud/common/util/AsyncProcessUtils.java @@ -0,0 +1,74 @@ +package com.tduck.cloud.common.util; + +import cn.hutool.cache.CacheUtil; +import cn.hutool.cache.impl.TimedCache; +import cn.hutool.core.util.StrUtil; +import lombok.AllArgsConstructor; +import lombok.experimental.UtilityClass; + +/** + * @author : smalljop + * @description : 异步处理进度 像导出文件等异步耗时操作 + * @create : 2021/06/08 15:35 + **/ +@UtilityClass +public class AsyncProcessUtils { + + /** + * 最大完成率 + */ + private final int MAX_PROCESS_RATE = 100; + /** + * 处理中任务 5h过期 + * timeout – 过期时长,单位:毫秒 + */ + TimedCache processMap = CacheUtil.newTimedCache(5 * 60 * 60 * 1000); + + + static { + //启动定时任务,每5分钟检查一次过期 + processMap.schedulePrune(5 * 60 * 1000); + } + + /** + * 设置进度 + * + * @param key + * @param rate + */ + public void setProcess(String key, int rate) { + processMap.put(key, new Process(rate * 100, StrUtil.EMPTY)); + } + + /** + * 设置进度 + * + * @param key + */ + public void setProcess(String key, String url) { + processMap.put(key, new Process(MAX_PROCESS_RATE, url)); + } + + /** + * 设置进度 + * + * @param key + */ + public Process getProcess(String key) { + return processMap.get(key); + } + + + @AllArgsConstructor + public class Process { + /** + * 完成进度 + */ + public int rate; + /** + * 下载地址 + */ + public String url; + } + +} diff --git a/tduck-project/pom.xml b/tduck-project/pom.xml index fc50f4e..84da641 100644 --- a/tduck-project/pom.xml +++ b/tduck-project/pom.xml @@ -19,5 +19,10 @@ tduck-common 0.0.1-SNAPSHOT + + com.tduck + tduck-storage + 0.0.1-SNAPSHOT + \ No newline at end of file diff --git a/tduck-project/src/main/java/com/tduck/cloud/project/entity/struct/PaginationExpandStruct.java b/tduck-project/src/main/java/com/tduck/cloud/project/entity/struct/PaginationExpandStruct.java index 3811801..ba2ee56 100644 --- a/tduck-project/src/main/java/com/tduck/cloud/project/entity/struct/PaginationExpandStruct.java +++ b/tduck-project/src/main/java/com/tduck/cloud/project/entity/struct/PaginationExpandStruct.java @@ -3,7 +3,7 @@ package com.tduck.cloud.project.entity.struct; import lombok.Data; /** - * @author : wangqing + * @author : smalljop * @description : 分页组件属性 * @create : 2021/05/19 10:29 **/ diff --git a/tduck-project/src/main/java/com/tduck/cloud/project/entity/struct/UploadResultStruct.java b/tduck-project/src/main/java/com/tduck/cloud/project/entity/struct/UploadResultStruct.java index da25d2e..58e1905 100644 --- a/tduck-project/src/main/java/com/tduck/cloud/project/entity/struct/UploadResultStruct.java +++ b/tduck-project/src/main/java/com/tduck/cloud/project/entity/struct/UploadResultStruct.java @@ -5,7 +5,7 @@ import lombok.Data; import java.util.List; /** - * @author : wangqing + * @author : smalljop * @description : 上传收集结果 * @create : 2021/06/07 16:37 **/ diff --git a/tduck-project/src/main/java/com/tduck/cloud/project/request/QueryProjectItemRequest.java b/tduck-project/src/main/java/com/tduck/cloud/project/request/QueryProjectItemRequest.java index e28c4b3..8dd2fcc 100644 --- a/tduck-project/src/main/java/com/tduck/cloud/project/request/QueryProjectItemRequest.java +++ b/tduck-project/src/main/java/com/tduck/cloud/project/request/QueryProjectItemRequest.java @@ -5,7 +5,7 @@ import lombok.Data; import javax.validation.constraints.NotBlank; /** - * @author : wangqing + * @author : smalljop * @description : 查询项目问题 * @create : 2021/06/03 14:45 **/ diff --git a/tduck-project/src/main/java/com/tduck/cloud/project/service/impl/UserProjectResultServiceImpl.java b/tduck-project/src/main/java/com/tduck/cloud/project/service/impl/UserProjectResultServiceImpl.java index d9f3c80..b7a1737 100644 --- a/tduck-project/src/main/java/com/tduck/cloud/project/service/impl/UserProjectResultServiceImpl.java +++ b/tduck-project/src/main/java/com/tduck/cloud/project/service/impl/UserProjectResultServiceImpl.java @@ -3,8 +3,8 @@ package com.tduck.cloud.project.service.impl; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.io.FileUtil; import cn.hutool.core.map.MapUtil; -import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.StrUtil; +import cn.hutool.core.thread.ThreadUtil; +import cn.hutool.core.util.*; import cn.hutool.http.HttpUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -14,6 +14,7 @@ import com.tduck.cloud.common.constant.CommonConstants; import com.tduck.cloud.common.entity.BaseEntity; import com.tduck.cloud.common.exception.BaseException; import com.tduck.cloud.common.util.AddressUtils; +import com.tduck.cloud.common.util.AsyncProcessUtils; import com.tduck.cloud.common.util.RedisUtils; import com.tduck.cloud.common.util.Result; import com.tduck.cloud.project.entity.UserProjectItemEntity; @@ -25,11 +26,14 @@ import com.tduck.cloud.project.request.QueryProjectResultRequest; import com.tduck.cloud.project.service.UserProjectItemService; import com.tduck.cloud.project.service.UserProjectResultService; import com.tduck.cloud.project.vo.ExportProjectResultVO; +import com.tduck.cloud.storage.cloud.OssStorageFactory; +import com.tduck.cloud.storage.util.StorageUtils; import lombok.RequiredArgsConstructor; import org.springframework.boot.system.ApplicationHome; import org.springframework.stereotype.Service; import java.io.File; +import java.io.FileInputStream; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -51,7 +55,6 @@ public class UserProjectResultServiceImpl extends ServiceImpl userProjectItemEntityList = userProjectItemService.list(Wrappers.lambdaQuery() .eq(UserProjectItemEntity::getProjectKey, request.getProjectKey()) .eq(UserProjectItemEntity::getType, ProjectItemTypeEnum.UPLOAD)); - String filed = "filed"; + String filed = "field"; // 临时下载文件位置 ApplicationHome home = new ApplicationHome(getClass()); File path = home.getSource(); - StringBuffer downloadPath = new StringBuffer(path.getParentFile().toString()).append(request.getProjectKey()).append(File.separator); + String uuid = IdUtil.fastSimpleUUID(); + StringBuffer downloadPath = new StringBuffer(path.getParentFile().toString()).append(File.separator).append(uuid).append(File.separator); + System.out.println(downloadPath); //结果 List resultEntityList = this.list(Wrappers.lambdaQuery() .eq(UserProjectResultEntity::getProjectKey, request.getProjectKey()) .le(ObjectUtil.isNotNull(request.getEndDateTime()), UserProjectResultEntity::getCreateTime, request.getEndDateTime()) .ge(ObjectUtil.isNotNull(request.getBeginDateTime()), UserProjectResultEntity::getCreateTime, request.getBeginDateTime()) .orderByDesc(BaseEntity::getCreateTime)); - resultEntityList.forEach(result -> { - userProjectItemEntityList.forEach(item -> { - StringBuffer tempDownloadPath = downloadPath.append(item.getFormItemId()); - UploadResultStruct uploadResult = MapUtil.get(result.getProcessData(), filed + item.getFormItemId(), UploadResultStruct.class); - if (CollectionUtil.isNotEmpty(uploadResult.getFiles())) { - uploadResult.getFiles().forEach(ufile -> { - File downFile = FileUtil.file(tempDownloadPath.append(File.separator) - .append(result.getId()).append(File.separator).append(ufile.getFileName()).toString()); - HttpUtil.downloadFile(ufile.getUrl(), downFile); + if (CollectionUtil.isEmpty(resultEntityList) || CollectionUtil.isEmpty(userProjectItemEntityList)) { + return Result.failed("暂无收集附件,无法下载"); + } + + ThreadUtil.execAsync(() -> { + try { + resultEntityList.forEach(result -> { + int index = 0; + userProjectItemEntityList.forEach(item -> { + StringBuffer tempDownloadPath = new StringBuffer(downloadPath).append(item.getFormItemId()); + UploadResultStruct uploadResult = MapUtil.get(result.getProcessData(), filed + item.getFormItemId(), UploadResultStruct.class); + if (ObjectUtil.isNotNull(uploadResult) && CollectionUtil.isNotEmpty(uploadResult.getFiles())) { + uploadResult.getFiles().forEach(uFile -> { + if (StrUtil.isNotBlank(uFile.getUrl())) { + File downFile = FileUtil.file(new StringBuffer(tempDownloadPath).append(File.separator) + .append(result.getId()).append(CharUtil.DASHED).append(uFile.getFileName()).toString()); + HttpUtil.downloadFile(uFile.getUrl(), downFile); + } + }); + } }); - } - }); + AsyncProcessUtils.setProcess(uuid, ++index / resultEntityList.size() + 1); + }); + // 压缩上传oss + File zip = ZipUtil.zip(downloadPath.toString()); + String downloadUrl = OssStorageFactory.build().upload(new FileInputStream(zip), StorageUtils.generateFileName("download", ".zip")); + AsyncProcessUtils.setProcess(uuid, downloadUrl); + //删除临时文件 + FileUtil.del(zip); + FileUtil.del(downloadPath.toString()); + } catch (Exception e) { + log.error("download file", e); + } }); - return null; + return Result.success(uuid); } } \ No newline at end of file diff --git a/tduck-storage/src/main/java/com/tduck/cloud/storage/entity/SysOssEntity.java b/tduck-storage/src/main/java/com/tduck/cloud/storage/entity/SysOssEntity.java deleted file mode 100644 index cda576f..0000000 --- a/tduck-storage/src/main/java/com/tduck/cloud/storage/entity/SysOssEntity.java +++ /dev/null @@ -1,67 +0,0 @@ -//package com.tduck.cloud.storage.entity; -// -//import com.baomidou.mybatisplus.annotation.FieldFill; -//import com.baomidou.mybatisplus.annotation.TableField; -//import com.baomidou.mybatisplus.annotation.TableId; -//import com.baomidou.mybatisplus.annotation.TableName; -//import com.tduck.cloud.storage.entity.enums.OssTypeEnum; -//import com.smalljop.business.platform.common.entity.BaseEntity; -//import lombok.AllArgsConstructor; -//import lombok.Builder; -//import lombok.Data; -//import lombok.NoArgsConstructor; -// -///** -// * @author smalljop -// * @email 250543222@qq.com -// * @date 20190124 16:17:32 -// */ -//@Data -//@TableName("sys_oss") -//@NoArgsConstructor -//@AllArgsConstructor -//@Builder -//public class SysOssEntity extends BaseEntity { -// /** -// * -// */ -// @TableId -// private Long id; -// /** -// * 旧文件名 -// */ -// private String oldFileName; -// -// /** -// * 文件名 -// */ -// private String fileName; -// -// -// private OssTypeEnum ossType; -// /** -// * 文件类型 -// */ -// private String fileType; -// -// /** -// * 文件存储key -// */ -// private String path; -// -// /** -// * 地址 -// */ -// private String url; -// /** -// * 文件大小 -// */ -// private Long fileSize; -// -// /** -// * 创建者ID -// **/ -// @TableField(fill = FieldFill.INSERT) -// private Long createUserId; -// -//} diff --git a/tduck-storage/src/main/java/com/tduck/cloud/storage/mapper/SysFileMapper.java b/tduck-storage/src/main/java/com/tduck/cloud/storage/mapper/SysFileMapper.java deleted file mode 100644 index 2caee10..0000000 --- a/tduck-storage/src/main/java/com/tduck/cloud/storage/mapper/SysFileMapper.java +++ /dev/null @@ -1,15 +0,0 @@ -//package com.tduck.cloud.storage.mapper; -// -//import com.baomidou.mybatisplus.core.mapper.BaseMapper; -//import com.tduck.cloud.storage.entity.SysOssEntity; -//import org.apache.ibatis.annotations.Mapper; -// -///** -// * @author smalljop -// * @email 250543222@qq.com -// * @date 20190124 16:17:32 -// */ -//@Mapper -//public interface SysFileMapper extends BaseMapper { -// -//}