mirror of
https://codeup.aliyun.com/64f7d6b8ce01efaafef1e678/coal/coal.git
synced 2026-01-25 07:46:40 +08:00
网盘
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package cn.lihongjie.coal.aop;
|
||||
|
||||
import cn.lihongjie.coal.annotation.SysLog;
|
||||
import cn.lihongjie.coal.base.dto.CommonDto;
|
||||
import cn.lihongjie.coal.base.entity.CommonEntity;
|
||||
import cn.lihongjie.coal.common.RequestUtils;
|
||||
import cn.lihongjie.coal.ip.IpQueryService;
|
||||
import cn.lihongjie.coal.session.SessionService;
|
||||
@@ -137,20 +139,34 @@ public class ControllerAop {
|
||||
SysLog sysLog, Method method, Object[] args, HttpServletRequest request) {
|
||||
String message = sysLog.message();
|
||||
if (StringUtils.isEmpty(sysLog.message())) {
|
||||
message = "(id?:'') + ' ' + (name?:'') + ' ' + (code?:'')";
|
||||
if (args != null
|
||||
&& args.length == 1
|
||||
&& args[0] != null
|
||||
&& (args[0] instanceof CommonDto || args[0] instanceof CommonEntity)) {
|
||||
|
||||
message = "(id?:'') + ' ' + (name?:'') + ' ' + (code?:'')";
|
||||
} else {
|
||||
|
||||
message = "";
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
MethodBasedEvaluationContext context =
|
||||
new MethodBasedEvaluationContext(
|
||||
ArrayUtils.isEmpty(args) ? null : args[0],
|
||||
method,
|
||||
args,
|
||||
new DefaultParameterNameDiscoverer());
|
||||
context.setVariable("request", request);
|
||||
Object value = parser.parseExpression(message).getValue(context);
|
||||
return value + "";
|
||||
if (StringUtils.isNotBlank(message)) {
|
||||
|
||||
MethodBasedEvaluationContext context =
|
||||
new MethodBasedEvaluationContext(
|
||||
ArrayUtils.isEmpty(args) ? null : args[0],
|
||||
method,
|
||||
args,
|
||||
new DefaultParameterNameDiscoverer());
|
||||
context.setVariable("request", request);
|
||||
Object value = parser.parseExpression(message).getValue(context);
|
||||
return value + "";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("解析日志表达式失败: {}", sysLog.message(), e);
|
||||
return "";
|
||||
|
||||
@@ -11,6 +11,7 @@ import cn.lihongjie.coal.dictionary.entity.DictionaryItemEntity;
|
||||
import cn.lihongjie.coal.file.entity.FileEntity;
|
||||
import cn.lihongjie.coal.meter.entity.MeterEntity;
|
||||
import cn.lihongjie.coal.meterLog.entity.MeterLogEntity;
|
||||
import cn.lihongjie.coal.netDisk.entity.NetDiskEntity;
|
||||
import cn.lihongjie.coal.noteBook.entity.NoteBookEntity;
|
||||
import cn.lihongjie.coal.noteBookChapter.entity.NoteBookChapterEntity;
|
||||
import cn.lihongjie.coal.organization.entity.OrganizationEntity;
|
||||
@@ -52,7 +53,14 @@ public interface CommonMapper {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
default Long toLong(String s) {
|
||||
try {
|
||||
|
||||
return Long.valueOf(s);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
default UserEntity createUser(String id) {
|
||||
|
||||
if (StringUtils.isEmpty(id)) {
|
||||
@@ -244,6 +252,17 @@ public interface CommonMapper {
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
default NetDiskEntity createNetDiskEntity(String id) {
|
||||
|
||||
if (StringUtils.isEmpty(id)) {
|
||||
|
||||
return null;
|
||||
}
|
||||
var e = new NetDiskEntity();
|
||||
e.setId(id);
|
||||
return e;
|
||||
}
|
||||
default NoteBookEntity createNoteBook(String id) {
|
||||
|
||||
if (StringUtils.isEmpty(id)) {
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
package cn.lihongjie.coal.netDisk.controller;
|
||||
|
||||
import cn.lihongjie.coal.annotation.OrgScope;
|
||||
import cn.lihongjie.coal.annotation.SysLog;
|
||||
import cn.lihongjie.coal.base.dto.IdRequest;
|
||||
import cn.lihongjie.coal.netDisk.dto.*;
|
||||
import cn.lihongjie.coal.netDisk.service.NetDiskService;
|
||||
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/netDisk")
|
||||
@SysLog(module = "网盘")
|
||||
@Slf4j
|
||||
@OrgScope
|
||||
public class NetDiskController {
|
||||
@Autowired private NetDiskService service;
|
||||
|
||||
|
||||
|
||||
@PostMapping("/getById")
|
||||
public NetDiskDto getById(@RequestBody IdRequest request) {
|
||||
return this.service.getById(request.getId());
|
||||
}
|
||||
|
||||
@PostMapping("/ls")
|
||||
@SysLog(action = "ls", message = "id")
|
||||
public List<NetDiskDto> ls(@RequestBody IdRequest request) {
|
||||
return this.service.ls(request);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/createDir")
|
||||
@SysLog(action = "createDir", message = "name")
|
||||
public NetDiskDto createDir (@RequestBody CreateDirDto request) {
|
||||
return this.service.createDir(request);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/batchCreateDir")
|
||||
@SysLog(action = "createDir", message = "names.join(',')")
|
||||
public List<NetDiskDto> batchCreateDir (@RequestBody BatchCreateDirDto request) {
|
||||
return this.service.batchCreateDir(request);
|
||||
}
|
||||
|
||||
@PostMapping("/preCreateFile")
|
||||
@SysLog(action = "preCreateFile", message = "name")
|
||||
|
||||
public PreCreateFileDto preCreateFile (@RequestBody CreateFileDto request) {
|
||||
return this.service.preCreateFile(request);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/createFileSlice")
|
||||
public NetDiskDto createFileSlice (
|
||||
@RequestParam("parent") String parent,
|
||||
@RequestParam("size") Long size,
|
||||
@RequestParam("sha256") String sha256,
|
||||
@RequestParam("mineType") String mineType,
|
||||
@RequestParam("multipartFile") MultipartFile multipartFile,
|
||||
@RequestParam("ossKey") String ossKey,
|
||||
@RequestParam("name") String name,
|
||||
@RequestParam("code") String code,
|
||||
@RequestParam("remarks") String remarks,
|
||||
@RequestParam("sortKey") String sortKey
|
||||
|
||||
|
||||
|
||||
) {
|
||||
CreateFileDto request = new CreateFileDto();
|
||||
request.setParent(parent);
|
||||
request.setSize(size);
|
||||
request.setSha256(sha256);
|
||||
request.setMineType(mineType);
|
||||
request.setMultipartFile(multipartFile);
|
||||
request.setOssKey(ossKey);
|
||||
request.setName(name);
|
||||
request.setCode(code);
|
||||
request.setRemarks(remarks);
|
||||
try{
|
||||
|
||||
request.setSortKey(Integer.valueOf(sortKey));
|
||||
}catch (Exception e){
|
||||
|
||||
}
|
||||
|
||||
return this.service.createFileSlice(request);
|
||||
}
|
||||
|
||||
@PostMapping("/createFile")
|
||||
public NetDiskDto createFile (
|
||||
@RequestParam("parent") String parent,
|
||||
@RequestParam("size") Long size,
|
||||
@RequestParam("sha256") String sha256,
|
||||
@RequestParam("mineType") String mineType,
|
||||
@RequestParam("multipartFile") MultipartFile multipartFile,
|
||||
@RequestParam("ossKey") String ossKey,
|
||||
@RequestParam("name") String name,
|
||||
@RequestParam("code") String code,
|
||||
@RequestParam("remarks") String remarks,
|
||||
@RequestParam("sortKey") String sortKey
|
||||
|
||||
|
||||
|
||||
) {
|
||||
CreateFileDto request = new CreateFileDto();
|
||||
request.setParent(parent);
|
||||
request.setSize(size);
|
||||
request.setSha256(sha256);
|
||||
request.setMineType(mineType);
|
||||
request.setMultipartFile(multipartFile);
|
||||
request.setOssKey(ossKey);
|
||||
request.setName(name);
|
||||
request.setCode(code);
|
||||
request.setRemarks(remarks);
|
||||
try{
|
||||
|
||||
request.setSortKey(Integer.valueOf(sortKey));
|
||||
}catch (Exception e){
|
||||
|
||||
}
|
||||
|
||||
return this.service.createFile(request);
|
||||
}
|
||||
|
||||
@PostMapping("/move")
|
||||
@SysLog(action = "move", message = "srcId + ' -> ' + targetId")
|
||||
|
||||
public NetDiskDto move(@RequestBody MoveDto request) {
|
||||
return this.service.move(request);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/copy")
|
||||
@SysLog(action = "copy", message = "srcId + ' -> ' + targetId")
|
||||
public NetDiskDto copy (@RequestBody CopyDto request) {
|
||||
return this.service.copy(request);
|
||||
}
|
||||
|
||||
@PostMapping("/remove")
|
||||
@SysLog(action = "remove", message = "id")
|
||||
public Object remove (@RequestBody IdRequest request) {
|
||||
this.service.remove(request);
|
||||
return null;
|
||||
}
|
||||
|
||||
@PostMapping("/downloadDir")
|
||||
@SysLog(action = "downloadDir", message = "id")
|
||||
public void remove (@RequestBody IdRequest request, HttpServletResponse response) {
|
||||
|
||||
this.service.downloadDir(request, response);
|
||||
}
|
||||
|
||||
@GetMapping("/downloadFile")
|
||||
|
||||
public ResponseEntity<Object> downloadFile(@RequestParam("id") String id, @RequestParam(value = "attachment", defaultValue = "false") Boolean attachment) {
|
||||
|
||||
|
||||
return ResponseEntity.status(HttpStatus.TEMPORARY_REDIRECT).header("Location", this.service.downloadFile(id, attachment)).body(null);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package cn.lihongjie.coal.netDisk.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Data
|
||||
public class BatchCreateDirDto {
|
||||
|
||||
private String parent;
|
||||
|
||||
|
||||
private List<String> names;
|
||||
|
||||
}
|
||||
14
src/main/java/cn/lihongjie/coal/netDisk/dto/CopyDto.java
Normal file
14
src/main/java/cn/lihongjie/coal/netDisk/dto/CopyDto.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package cn.lihongjie.coal.netDisk.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class CopyDto {
|
||||
|
||||
private String srcId;
|
||||
private String newName;
|
||||
private String targetId;
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package cn.lihongjie.coal.netDisk.dto;
|
||||
|
||||
import cn.lihongjie.coal.base.dto.OrgCommonDto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class CreateDirDto extends OrgCommonDto {
|
||||
|
||||
private String parent;
|
||||
|
||||
|
||||
public CreateDirDto(String parent, String name) {
|
||||
super();
|
||||
this.parent = parent;
|
||||
setName(name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package cn.lihongjie.coal.netDisk.dto;
|
||||
|
||||
import cn.lihongjie.coal.base.dto.OrgCommonDto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import org.hibernate.annotations.Comment;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Data
|
||||
public class CreateFileDto extends OrgCommonDto {
|
||||
|
||||
|
||||
private String parent;
|
||||
|
||||
|
||||
@Comment("文件/文件夹 大小, 单位 byte")
|
||||
private Long size;
|
||||
|
||||
|
||||
@Comment("文件 sha256 值, 文件夹没有")
|
||||
private String sha256;
|
||||
|
||||
|
||||
@Comment("文件 mime 类型, 文件夹没有")
|
||||
private String mineType;
|
||||
|
||||
|
||||
private MultipartFile multipartFile;
|
||||
|
||||
|
||||
private String ossKey;
|
||||
|
||||
|
||||
@Comment("分片序号")
|
||||
private Long sliceIndex;
|
||||
|
||||
|
||||
@Comment("分片 sha256 值")
|
||||
private String sliceSha256;
|
||||
|
||||
|
||||
@Comment("分片文件大小")
|
||||
private String sliceSize;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package cn.lihongjie.coal.netDisk.dto;
|
||||
|
||||
import cn.lihongjie.coal.base.dto.OrgCommonDto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class CreateNetDiskDto extends OrgCommonDto {}
|
||||
16
src/main/java/cn/lihongjie/coal/netDisk/dto/MoveDto.java
Normal file
16
src/main/java/cn/lihongjie/coal/netDisk/dto/MoveDto.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package cn.lihongjie.coal.netDisk.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Data
|
||||
public class MoveDto {
|
||||
|
||||
private String srcId;
|
||||
private String newName;
|
||||
private String targetId;
|
||||
|
||||
|
||||
|
||||
}
|
||||
42
src/main/java/cn/lihongjie/coal/netDisk/dto/NetDiskDto.java
Normal file
42
src/main/java/cn/lihongjie/coal/netDisk/dto/NetDiskDto.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package cn.lihongjie.coal.netDisk.dto;
|
||||
|
||||
import cn.lihongjie.coal.base.dto.OrgCommonDto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import org.hibernate.annotations.Comment;
|
||||
import org.hibernate.annotations.Formula;
|
||||
|
||||
@Data
|
||||
public class NetDiskDto extends OrgCommonDto {
|
||||
|
||||
|
||||
|
||||
@Comment("条目类型, 文件夹/目录")
|
||||
private String entryType;
|
||||
|
||||
@Formula(
|
||||
"(select i.name\n"
|
||||
+ "from t_dictionary d,\n"
|
||||
+ " t_dictionary_item i\n"
|
||||
+ "where d.id = i.dictionary_id\n"
|
||||
+ " and d.code = 'netDisk.entryType'\n"
|
||||
+ " and i.code = entry_type)")
|
||||
private String entryTypeName;
|
||||
|
||||
|
||||
|
||||
|
||||
@Comment("文件/文件夹 大小, 单位 byte")
|
||||
private Long size;
|
||||
|
||||
private Long sizeHumanReadable;
|
||||
|
||||
|
||||
@Comment("文件 sha256 值, 文件夹没有")
|
||||
private String sha256;
|
||||
|
||||
|
||||
@Comment("文件 mime 类型, 文件夹没有")
|
||||
private String mineType;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package cn.lihongjie.coal.netDisk.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import org.hibernate.annotations.Comment;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Data
|
||||
public class PreCreateFileDto {
|
||||
|
||||
@Comment("如果这个存在, 就意味着文件已经上传过, 可以直接创建")
|
||||
private String ossKey;
|
||||
|
||||
@Comment("分片明细")
|
||||
private List<NetDiskDto> slices = new ArrayList<>();
|
||||
|
||||
@Comment("分片大小")
|
||||
private Long sliceSize;
|
||||
|
||||
|
||||
}
|
||||
14
src/main/java/cn/lihongjie/coal/netDisk/dto/RenameDto.java
Normal file
14
src/main/java/cn/lihongjie/coal/netDisk/dto/RenameDto.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package cn.lihongjie.coal.netDisk.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Data public class RenameDto {
|
||||
|
||||
private String id;
|
||||
|
||||
private String name;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package cn.lihongjie.coal.netDisk.dto;
|
||||
|
||||
import cn.lihongjie.coal.base.dto.OrgCommonDto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class UpdateNetDiskDto extends OrgCommonDto {}
|
||||
@@ -0,0 +1,81 @@
|
||||
package cn.lihongjie.coal.netDisk.entity;
|
||||
|
||||
import cn.lihongjie.coal.base.entity.OrgCommonEntity;
|
||||
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.OneToMany;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import org.hibernate.annotations.Comment;
|
||||
import org.hibernate.annotations.Formula;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Entity
|
||||
public class NetDiskEntity extends OrgCommonEntity {
|
||||
|
||||
@ManyToOne
|
||||
private NetDiskEntity parent;
|
||||
|
||||
@Comment("条目类型, 文件夹/目录/分片文件")
|
||||
private String entryType;
|
||||
|
||||
@Formula(
|
||||
"(select i.name\n"
|
||||
+ "from t_dictionary d,\n"
|
||||
+ " t_dictionary_item i\n"
|
||||
+ "where d.id = i.dictionary_id\n"
|
||||
+ " and d.code = 'netDisk.entryType'\n"
|
||||
+ " and i.code = entry_type)")
|
||||
private String entryTypeName;
|
||||
|
||||
|
||||
|
||||
@OneToMany(mappedBy = "parent", cascade = {CascadeType.REMOVE})
|
||||
private List<NetDiskEntity> children;
|
||||
|
||||
@Comment("文件/文件夹 大小, 单位 byte")
|
||||
private Long size;
|
||||
|
||||
|
||||
@Formula("(pg_size_pretty(size))")
|
||||
private Long sizeHumanReadable;
|
||||
|
||||
|
||||
@Comment("文件 sha256 值, 文件夹没有")
|
||||
private String sha256;
|
||||
|
||||
|
||||
@Comment("文件 mime 类型, 文件夹没有")
|
||||
private String mineType;
|
||||
|
||||
|
||||
private String ossKey;
|
||||
|
||||
|
||||
@Comment("分片序号")
|
||||
private Long sliceIndex;
|
||||
|
||||
|
||||
@Comment("分片 sha256 值")
|
||||
private String sliceSha256;
|
||||
|
||||
|
||||
@Comment("分片文件大小")
|
||||
private Long sliceSize;
|
||||
|
||||
|
||||
@Comment("分片上传任务ID")
|
||||
private String sliceTaskId;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package cn.lihongjie.coal.netDisk.mapper;
|
||||
|
||||
import cn.lihongjie.coal.base.mapper.BaseMapper;
|
||||
import cn.lihongjie.coal.base.mapper.CommonMapper;
|
||||
import cn.lihongjie.coal.netDisk.dto.*;
|
||||
import cn.lihongjie.coal.netDisk.entity.NetDiskEntity;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.Named;
|
||||
import org.mapstruct.control.DeepClone;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper(
|
||||
componentModel = org.mapstruct.MappingConstants.ComponentModel.SPRING,
|
||||
uses = {CommonMapper.class},
|
||||
mappingControl = DeepClone.class)
|
||||
public interface NetDiskMapper
|
||||
extends BaseMapper<NetDiskEntity, NetDiskDto, CreateNetDiskDto, UpdateNetDiskDto> {
|
||||
NetDiskEntity toEntity(CreateDirDto request);
|
||||
|
||||
@Mappings({
|
||||
@org.mapstruct.Mapping(target = "id", ignore = true),
|
||||
@Mapping(target = "parent", ignore = true, qualifiedByName = "copyChildren"),
|
||||
@Mapping(source = "children", target = "children", ignore = false, qualifiedByName = "copyChildren" )
|
||||
})
|
||||
@Named("copyChildren")
|
||||
NetDiskEntity copyChildren(NetDiskEntity src);
|
||||
|
||||
NetDiskEntity toEntity(CreateFileDto request);
|
||||
|
||||
List<NetDiskDto> toDto(List<NetDiskEntity> children);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package cn.lihongjie.coal.netDisk.repository;
|
||||
|
||||
import cn.lihongjie.coal.base.dao.BaseRepository;
|
||||
import cn.lihongjie.coal.netDisk.entity.NetDiskEntity;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface NetDiskRepository extends BaseRepository<NetDiskEntity> {
|
||||
NetDiskEntity findBySha256(String sha256);
|
||||
|
||||
List<NetDiskEntity> findAllBySha256(String sha256);
|
||||
|
||||
long countByNameAndParentNull(String name);
|
||||
|
||||
boolean existsByOssKey(String ossKey);
|
||||
|
||||
NetDiskEntity findByParentNull();
|
||||
|
||||
List<NetDiskEntity> findALlByParentNullAndOrganizationId(String organizationId);
|
||||
|
||||
long countByParentNullAndOrganizationIdAndName(String organizationId, String name);
|
||||
}
|
||||
@@ -0,0 +1,744 @@
|
||||
package cn.lihongjie.coal.netDisk.service;
|
||||
|
||||
import cn.lihongjie.coal.base.dto.CommonQuery;
|
||||
import cn.lihongjie.coal.base.dto.IdRequest;
|
||||
import cn.lihongjie.coal.base.service.BaseService;
|
||||
import cn.lihongjie.coal.common.Ctx;
|
||||
import cn.lihongjie.coal.exception.BizException;
|
||||
import cn.lihongjie.coal.netDisk.dto.*;
|
||||
import cn.lihongjie.coal.netDisk.entity.NetDiskEntity;
|
||||
import cn.lihongjie.coal.netDisk.mapper.NetDiskMapper;
|
||||
import cn.lihongjie.coal.netDisk.repository.NetDiskRepository;
|
||||
import cn.lihongjie.coal.spring.config.AliyunProperty;
|
||||
|
||||
import com.aliyun.oss.HttpMethod;
|
||||
import com.aliyun.oss.OSSClient;
|
||||
import com.aliyun.oss.model.*;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import lombok.Cleanup;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StopWatch;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@Transactional
|
||||
public class NetDiskService extends BaseService<NetDiskEntity, NetDiskRepository> {
|
||||
public static final int DEFAULT_SLICE_SIZE = 10 * 1024 * 1024;
|
||||
@Autowired ObjectMapper objectMapper;
|
||||
@Autowired OSSClient ossClient;
|
||||
@Autowired AliyunProperty aliyunProperty;
|
||||
@Autowired private NetDiskRepository repository;
|
||||
@Autowired private NetDiskMapper mapper;
|
||||
@Autowired private ConversionService conversionService;
|
||||
|
||||
private static void checkEntry(CreateFileDto request, List<NetDiskEntity> allSlice) {
|
||||
if (allSlice.isEmpty() && request.getSliceIndex() != 0) {
|
||||
throw new BizException("第一个分片的index必须是0");
|
||||
}
|
||||
|
||||
if (request.getSliceIndex() != allSlice.size()) {
|
||||
throw new BizException("分片index必须是连续的");
|
||||
}
|
||||
}
|
||||
|
||||
private static NetDiskEntity findExistEntry(
|
||||
CreateFileDto request, List<NetDiskEntity> allSlice, NetDiskEntity existEntry) {
|
||||
for (NetDiskEntity entity : allSlice) {
|
||||
|
||||
if (entity.getSliceIndex().equals(request.getSliceIndex())) {
|
||||
|
||||
if (StringUtils.equals(entity.getSliceSha256(), request.getSliceSha256())) {
|
||||
log.info("分片 {} 已经存在, 不用上传", request.getName() + "-" + request.getSliceIndex());
|
||||
existEntry = entity;
|
||||
break;
|
||||
} else {
|
||||
throw new BizException("分片已经存在, 但是sha256不一致, 请检查");
|
||||
}
|
||||
}
|
||||
}
|
||||
return existEntry;
|
||||
}
|
||||
|
||||
private static String getOssKey(String sha256) {
|
||||
return "netDisk"
|
||||
+ "/"
|
||||
+ sha256.substring(0, 2)
|
||||
+ "/"
|
||||
+ sha256.substring(2, 4)
|
||||
+ "/"
|
||||
+ sha256.substring(4);
|
||||
}
|
||||
|
||||
public List<NetDiskDto> ls(IdRequest request) {
|
||||
|
||||
handlerRootDir(request);
|
||||
|
||||
if (StringUtils.isEmpty(request.getId())) {
|
||||
return this.mapper.toDto(
|
||||
repository.findALlByParentNullAndOrganizationId(
|
||||
Ctx.currentUser().getOrganizationId()));
|
||||
}
|
||||
|
||||
NetDiskEntity entity = get(request.getId());
|
||||
|
||||
return this.mapper.toDto(entity.getChildren());
|
||||
}
|
||||
|
||||
public List<NetDiskDto> batchCreateDir(BatchCreateDirDto request) {
|
||||
|
||||
request.getNames().forEach(x -> validateDirName(x));
|
||||
|
||||
ArrayList<NetDiskDto> ans = new ArrayList<>();
|
||||
for (Object o : request.getNames()) {
|
||||
String name = (String) o;
|
||||
NetDiskDto dto = createDir(new CreateDirDto(request.getParent(), name));
|
||||
ans.add(dto);
|
||||
}
|
||||
|
||||
return ans;
|
||||
}
|
||||
|
||||
private void handlerRootDir(IdRequest request) {
|
||||
if (StringUtils.equals(request.getId(), "/")) {
|
||||
|
||||
List<NetDiskEntity> rootDir =
|
||||
this.repository.findAll(
|
||||
new Specification<NetDiskEntity>() {
|
||||
@Override
|
||||
public Predicate toPredicate(
|
||||
Root<NetDiskEntity> root,
|
||||
CriteriaQuery<?> query,
|
||||
CriteriaBuilder criteriaBuilder) {
|
||||
|
||||
return criteriaBuilder.and(
|
||||
criteriaBuilder.isNull(root.get("parent")),
|
||||
criteriaBuilder.equal(
|
||||
root.get("organizationId"),
|
||||
Ctx.currentUser().getOrganizationId()),
|
||||
criteriaBuilder.equal(root.get("entryType"), "0"),
|
||||
criteriaBuilder.equal(root.get("name"), "/"));
|
||||
}
|
||||
});
|
||||
|
||||
if (rootDir.isEmpty()) {
|
||||
NetDiskEntity entity = new NetDiskEntity();
|
||||
entity.setEntryType("0");
|
||||
entity.setName("/");
|
||||
entity.setOrganizationId(Ctx.currentUser().getOrganizationId());
|
||||
save(entity);
|
||||
|
||||
request.setId(entity.getId());
|
||||
} else {
|
||||
request.setId(rootDir.get(0).getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public NetDiskDto createDir(CreateDirDto request) {
|
||||
|
||||
validateDirName(request.getName());
|
||||
|
||||
checkParentWithEntryName(request.getParent(), request.getName());
|
||||
|
||||
NetDiskEntity entity = this.mapper.toEntity(request);
|
||||
entity.setEntryType("0");
|
||||
entity.setSize(0L);
|
||||
save(entity);
|
||||
return this.mapper.toDto(entity);
|
||||
}
|
||||
|
||||
private void checkParentWithEntryName(String parent, String name) {
|
||||
|
||||
if (StringUtils.isEmpty(parent)) {
|
||||
|
||||
long count =
|
||||
repository.countByParentNullAndOrganizationIdAndName(
|
||||
Ctx.currentUser().getOrganizationId(), name);
|
||||
|
||||
if (count > 0) {
|
||||
throw new BizException("根目录已经存在同名文件/文件夹");
|
||||
}
|
||||
} else {
|
||||
|
||||
NetDiskEntity disk = get(parent);
|
||||
|
||||
if (disk.getChildren().stream().anyMatch(x -> x.getName().equals(name))) {
|
||||
throw new BizException("目录已经存在同名文件/文件夹");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void validateDirName(String name) {
|
||||
|
||||
if (StringUtils.isEmpty(name) || StringUtils.isBlank(name)) {
|
||||
throw new BizException("文件夹名字不能为空");
|
||||
}
|
||||
|
||||
if (name.length() > 255) {
|
||||
throw new BizException("文件夹名字不能超过255个字符");
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public NetDiskDto createFile(CreateFileDto request) {
|
||||
|
||||
validateFileName(request.getName());
|
||||
checkParentWithEntryName(request.getParent(), request.getName());
|
||||
|
||||
if (StringUtils.isNotBlank(request.getOssKey())) {
|
||||
|
||||
if (!repository.existsByOssKey(request.getOssKey())) {
|
||||
throw new BizException("OSSKey 不存在");
|
||||
}
|
||||
} else {
|
||||
|
||||
try {
|
||||
|
||||
String ossKey = getOssKey(request.getSha256());
|
||||
|
||||
PutObjectResult objectResult =
|
||||
ossClient.putObject(
|
||||
aliyunProperty.getOSS().getBucketName(),
|
||||
ossKey,
|
||||
request.getMultipartFile().getInputStream());
|
||||
request.setOssKey(ossKey);
|
||||
log.info("上传文件 {} 到 OSS {}", request.getName(), objectResult.getResponse());
|
||||
|
||||
} catch (Exception e) {
|
||||
log.warn("上传文件失败", e);
|
||||
throw new BizException("上传文件失败 " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
NetDiskEntity entity = this.mapper.toEntity(request);
|
||||
entity.setEntryType("1");
|
||||
entity.setSize(request.getSize());
|
||||
save(entity);
|
||||
|
||||
if (entity.getParent() != null) {
|
||||
|
||||
updateDirSize(entity.getParent().getId());
|
||||
}
|
||||
|
||||
return this.mapper.toDto(entity);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public NetDiskDto createFileSlice(CreateFileDto request) {
|
||||
|
||||
validateFileName(request.getName());
|
||||
checkParentWithEntryName(request.getParent(), request.getName());
|
||||
NetDiskEntity existEntry = null;
|
||||
String ossKey = getOssKey(request.getSha256());
|
||||
|
||||
@Cleanup InputStream inputStream = request.getMultipartFile().getInputStream();
|
||||
|
||||
try {
|
||||
|
||||
List<NetDiskEntity> allSlice = findSlice(request.getSha256());
|
||||
|
||||
// 如果分片已经存在, 就不用上传了
|
||||
|
||||
existEntry = findExistEntry(request, allSlice, existEntry);
|
||||
|
||||
checkEntry(request, allSlice);
|
||||
|
||||
if (existEntry == null) {
|
||||
|
||||
UploadPartResult uploadPartResult =
|
||||
doUploadPart(request, ossKey, allSlice, inputStream);
|
||||
|
||||
existEntry = saveEntry(request, ossKey, allSlice, uploadPartResult);
|
||||
log.info("上传文件 {} 到 OSS {}", request.getName(), uploadPartResult.getResponse());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.warn("上传文件失败", e);
|
||||
throw new BizException("上传文件失败 " + e.getMessage());
|
||||
}
|
||||
|
||||
List<NetDiskEntity> slice = findSlice(request.getSha256());
|
||||
|
||||
long totalSize = slice.stream().mapToLong(NetDiskEntity::getSliceSize).sum();
|
||||
|
||||
if (totalSize == request.getSize()) {
|
||||
log.info("文件 {} 已经上传完成, 开始合并", request.getName());
|
||||
|
||||
CompleteMultipartUploadResult completeMultipartUploadResult =
|
||||
doCompleteSliceUpload(slice, ossKey);
|
||||
|
||||
log.info("合并完成 {}", completeMultipartUploadResult.getResponse());
|
||||
|
||||
// 生成新的文件信息
|
||||
|
||||
NetDiskEntity netDiskEntity = buildNewEntry(slice, ossKey);
|
||||
|
||||
// 删除分片信息
|
||||
|
||||
this.repository.deleteAll(slice);
|
||||
|
||||
if (netDiskEntity.getParent() != null) {
|
||||
|
||||
updateDirSize(netDiskEntity.getParent().getId());
|
||||
}
|
||||
|
||||
} else {
|
||||
log.info(
|
||||
"文件 {} 还没有上传完成, 已经上传 {} 个分片, 分片总大小 {} , 文件总大小 {} ",
|
||||
request.getName(),
|
||||
slice.size(),
|
||||
totalSize,
|
||||
request.getSize());
|
||||
}
|
||||
|
||||
return this.mapper.toDto(existEntry);
|
||||
}
|
||||
|
||||
private NetDiskEntity buildNewEntry(List<NetDiskEntity> slice, String ossKey) {
|
||||
NetDiskEntity completeFile = mapper.copy(slice.get(0));
|
||||
|
||||
completeFile.setEntryType("1");
|
||||
completeFile.setOssKey(ossKey);
|
||||
completeFile.setSliceSize(null);
|
||||
completeFile.setSliceIndex(null);
|
||||
completeFile.setSliceSha256(null);
|
||||
|
||||
this.repository.save(completeFile);
|
||||
return completeFile;
|
||||
}
|
||||
|
||||
private CompleteMultipartUploadResult doCompleteSliceUpload(
|
||||
List<NetDiskEntity> slice, String ossKey) {
|
||||
List<PartETag> partETags =
|
||||
slice.stream()
|
||||
.map(
|
||||
x -> {
|
||||
try {
|
||||
return objectMapper.readValue(
|
||||
x.getRemarks(), PartETag.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
CompleteMultipartUploadRequest completeMultipartUploadRequest =
|
||||
new CompleteMultipartUploadRequest(
|
||||
aliyunProperty.getOSS().getBucketName(),
|
||||
ossKey,
|
||||
slice.get(0).getSliceTaskId(),
|
||||
partETags);
|
||||
CompleteMultipartUploadResult completeMultipartUploadResult =
|
||||
ossClient.completeMultipartUpload(completeMultipartUploadRequest);
|
||||
return completeMultipartUploadResult;
|
||||
}
|
||||
|
||||
private NetDiskEntity saveEntry(
|
||||
CreateFileDto request,
|
||||
String ossKey,
|
||||
List<NetDiskEntity> allSlice,
|
||||
UploadPartResult uploadPartResult)
|
||||
throws JsonProcessingException {
|
||||
NetDiskEntity existEntry;
|
||||
existEntry = this.mapper.toEntity(request);
|
||||
existEntry.setEntryType("2");
|
||||
existEntry.setSliceTaskId(getUploadId(request, ossKey, allSlice));
|
||||
existEntry.setRemarks(objectMapper.writeValueAsString(uploadPartResult.getPartETag()));
|
||||
save(existEntry);
|
||||
return existEntry;
|
||||
}
|
||||
|
||||
private UploadPartResult doUploadPart(
|
||||
CreateFileDto request,
|
||||
String ossKey,
|
||||
List<NetDiskEntity> allSlice,
|
||||
InputStream inputStream) {
|
||||
UploadPartRequest uploadPartRequest = new UploadPartRequest();
|
||||
uploadPartRequest.setBucketName(aliyunProperty.getOSS().getBucketName());
|
||||
uploadPartRequest.setKey(ossKey);
|
||||
uploadPartRequest.setUploadId(getUploadId(request, ossKey, allSlice));
|
||||
uploadPartRequest.setPartNumber(Math.toIntExact(request.getSliceIndex()) + 1);
|
||||
uploadPartRequest.setInputStream(inputStream);
|
||||
UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
|
||||
return uploadPartResult;
|
||||
}
|
||||
|
||||
private String getUploadId(CreateFileDto request, String ossKey, List<NetDiskEntity> allSlice) {
|
||||
String uploadId;
|
||||
if (request.getSliceIndex() == 0) {
|
||||
|
||||
uploadId = initPartTask(ossKey);
|
||||
|
||||
log.info("初始化分片上传 {}", uploadId);
|
||||
} else {
|
||||
|
||||
uploadId = allSlice.get(0).getSliceTaskId();
|
||||
}
|
||||
return uploadId;
|
||||
}
|
||||
|
||||
private String initPartTask(String ossKey) {
|
||||
String uploadId;
|
||||
InitiateMultipartUploadRequest multipartUploadRequest =
|
||||
new InitiateMultipartUploadRequest(aliyunProperty.getOSS().getBucketName(), ossKey);
|
||||
|
||||
InitiateMultipartUploadResult multipartUpload =
|
||||
ossClient.initiateMultipartUpload(multipartUploadRequest);
|
||||
uploadId = multipartUpload.getUploadId();
|
||||
return uploadId;
|
||||
}
|
||||
|
||||
private void validateFileName(String name) {
|
||||
|
||||
if (StringUtils.isEmpty(name) || StringUtils.isBlank(name)) {
|
||||
throw new BizException("文件名字不能为空");
|
||||
}
|
||||
|
||||
if (name.length() > 255) {
|
||||
throw new BizException("文件名字不能超过255个字符");
|
||||
}
|
||||
}
|
||||
|
||||
public NetDiskDto rename(RenameDto request) {
|
||||
|
||||
NetDiskEntity netDiskEntity = get(request.getId());
|
||||
|
||||
if (netDiskEntity.getParent().getChildren().stream()
|
||||
.anyMatch(x -> x.getName().equals(request.getName()))) {
|
||||
throw new BizException("目录已经存在同名文件/文件夹");
|
||||
}
|
||||
|
||||
netDiskEntity.setName(request.getName());
|
||||
|
||||
save(netDiskEntity);
|
||||
|
||||
return this.mapper.toDto(netDiskEntity);
|
||||
}
|
||||
|
||||
public void remove(IdRequest request) {
|
||||
|
||||
this.repository.findAllById(request.getIds()).forEach(this::remove);
|
||||
}
|
||||
|
||||
private void remove(NetDiskEntity netDiskEntity) {
|
||||
|
||||
this.repository.delete(netDiskEntity);
|
||||
|
||||
if (netDiskEntity.getParent() != null) {
|
||||
|
||||
updateDirSize(netDiskEntity.getParent().getId());
|
||||
}
|
||||
}
|
||||
|
||||
public NetDiskDto move(MoveDto request) {
|
||||
|
||||
NetDiskEntity src = get(request.getSrcId());
|
||||
NetDiskEntity target = get(request.getTargetId());
|
||||
if (StringUtils.isNotEmpty(request.getNewName())) {
|
||||
src.setName(request.getNewName());
|
||||
}
|
||||
|
||||
if (src.getParent().getId().equals(target.getId())) {
|
||||
throw new BizException("不能移动到自己的子目录");
|
||||
}
|
||||
|
||||
if (!target.getEntryType().equals("0")) {
|
||||
throw new BizException("只能移动到目录");
|
||||
}
|
||||
|
||||
if (target.getChildren().stream().filter(x -> x.getName().equals(src.getName())).count()
|
||||
> 0) {
|
||||
throw new BizException("目标目录已经存在同名文件/文件夹");
|
||||
}
|
||||
|
||||
src.setParent(target);
|
||||
|
||||
this.save(src);
|
||||
|
||||
if (src.getParent() != null) {
|
||||
|
||||
updateDirSize(src.getParent().getId());
|
||||
}
|
||||
|
||||
if (target.getParent() != null) {
|
||||
|
||||
updateDirSize(target.getParent().getId());
|
||||
}
|
||||
|
||||
return this.mapper.toDto(src);
|
||||
}
|
||||
|
||||
public NetDiskDto copy(CopyDto request) {
|
||||
|
||||
NetDiskEntity srcEntity = get(request.getSrcId());
|
||||
|
||||
NetDiskEntity src = this.mapper.copyChildren(srcEntity);
|
||||
|
||||
NetDiskEntity target = get(request.getTargetId());
|
||||
if (StringUtils.isNotEmpty(request.getNewName())) {
|
||||
src.setName(request.getNewName());
|
||||
}
|
||||
|
||||
if (src.getParent().getId().equals(target.getId())) {
|
||||
throw new BizException("不能复制到自己的子目录");
|
||||
}
|
||||
|
||||
if (!target.getEntryType().equals("0")) {
|
||||
throw new BizException("只能复制到目录");
|
||||
}
|
||||
|
||||
if (target.getChildren().stream().filter(x -> x.getName().equals(src.getName())).count()
|
||||
> 0) {
|
||||
throw new BizException("目标目录已经存在同名文件/文件夹");
|
||||
}
|
||||
|
||||
src.setParent(target);
|
||||
|
||||
this.save(src);
|
||||
|
||||
if (src.getParent() != null) {
|
||||
|
||||
updateDirSize(src.getParent().getId());
|
||||
}
|
||||
|
||||
return this.mapper.toDto(src);
|
||||
}
|
||||
|
||||
public String downloadFile(String id, boolean attachment) {
|
||||
|
||||
String bucketName = aliyunProperty.getOSS().getBucketName();
|
||||
NetDiskEntity disk = get(id);
|
||||
|
||||
if (!disk.getEntryType().equals("1")) {
|
||||
throw new BizException("只能下载文件");
|
||||
}
|
||||
|
||||
String ossKey = disk.getOssKey();
|
||||
Date addedMinutes =
|
||||
DateUtils.addMinutes(
|
||||
new Date(),
|
||||
Math.toIntExact(
|
||||
ObjectUtils.defaultIfNull(
|
||||
aliyunProperty.getOSS().getPreSignedUrlExpire(), 30L)));
|
||||
GeneratePresignedUrlRequest request =
|
||||
new GeneratePresignedUrlRequest(bucketName, ossKey, HttpMethod.GET);
|
||||
request.setExpiration(addedMinutes);
|
||||
|
||||
ResponseHeaderOverrides responseHeaders = new ResponseHeaderOverrides();
|
||||
responseHeaders.setContentType(disk.getMineType());
|
||||
if (attachment) {
|
||||
responseHeaders.setContentDisposition(
|
||||
"attachment;filename="
|
||||
+ URLEncoder.encode(disk.getName(), StandardCharsets.UTF_8));
|
||||
|
||||
} else {
|
||||
responseHeaders.setContentDisposition(
|
||||
"inline;filename=" + URLEncoder.encode(disk.getName(), StandardCharsets.UTF_8));
|
||||
}
|
||||
request.setResponseHeaders(responseHeaders);
|
||||
|
||||
URL url = ossClient.generatePresignedUrl(request);
|
||||
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public void downloadDir(IdRequest id, HttpServletResponse response) {
|
||||
|
||||
NetDiskEntity dir = get(id.getId());
|
||||
|
||||
if (!dir.getEntryType().equals("0")) {
|
||||
throw new BizException("只能下载目录");
|
||||
}
|
||||
|
||||
StopWatch stopWatch = new StopWatch("下载文件夹 " + dir.getName() + " " + dir.getId());
|
||||
// 设置响应类型为ZIP
|
||||
response.setContentType("application/zip");
|
||||
|
||||
// 设置响应头,指定ZIP文件名
|
||||
String zipName = URLEncoder.encode(dir.getName() + ".zip", StandardCharsets.UTF_8);
|
||||
response.setHeader("Content-Disposition", "attachment; filename=" + zipName);
|
||||
|
||||
@Cleanup("close")
|
||||
ZipArchiveOutputStream zipArchiveOutputStream =
|
||||
new ZipArchiveOutputStream(response.getOutputStream());
|
||||
|
||||
zipDir(dir, zipArchiveOutputStream, dir, stopWatch);
|
||||
|
||||
log.info(stopWatch.prettyPrint());
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private void zipDir(
|
||||
NetDiskEntity dir,
|
||||
ZipArchiveOutputStream zipArchiveOutputStream,
|
||||
NetDiskEntity root,
|
||||
StopWatch stopWatch) {
|
||||
|
||||
if (dir.getEntryType().equals("0")) {
|
||||
|
||||
stopWatch.start("创建目录 " + dir.getName() + " " + dir.getId());
|
||||
zipArchiveOutputStream.putArchiveEntry(new ZipArchiveEntry(getFullName(root, dir)));
|
||||
|
||||
zipArchiveOutputStream.closeArchiveEntry();
|
||||
|
||||
stopWatch.stop();
|
||||
} else {
|
||||
|
||||
zipArchiveOutputStream.putArchiveEntry(new ZipArchiveEntry(getFullName(root, dir)));
|
||||
|
||||
stopWatch.start("下载文件 " + dir.getName() + " " + dir.getId());
|
||||
OSSObject ossObject =
|
||||
ossClient.getObject(aliyunProperty.getOSS().getBucketName(), dir.getOssKey());
|
||||
|
||||
IOUtils.copy(ossObject.getObjectContent(), zipArchiveOutputStream);
|
||||
|
||||
stopWatch.stop();
|
||||
zipArchiveOutputStream.closeArchiveEntry();
|
||||
|
||||
for (NetDiskEntity child : dir.getChildren()) {
|
||||
|
||||
zipDir(child, zipArchiveOutputStream, root, stopWatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getFullName(NetDiskEntity root, NetDiskEntity entry) {
|
||||
|
||||
if (root == entry) {
|
||||
return entry.getName() + "/";
|
||||
}
|
||||
|
||||
LinkedList<String> parts = new LinkedList<>();
|
||||
boolean isDir = entry.getEntryType().equals("0");
|
||||
|
||||
while (entry != root) {
|
||||
parts.addFirst(entry.getName());
|
||||
entry = entry.getParent();
|
||||
}
|
||||
|
||||
return StringUtils.join(parts, "/") + (isDir ? "/" : "");
|
||||
}
|
||||
|
||||
public NetDiskDto create(CreateNetDiskDto request) {
|
||||
NetDiskEntity entity = mapper.toEntity(request);
|
||||
|
||||
this.repository.save(entity);
|
||||
return getById(entity.getId());
|
||||
}
|
||||
|
||||
public NetDiskDto update(UpdateNetDiskDto request) {
|
||||
NetDiskEntity entity = this.repository.get(request.getId());
|
||||
this.mapper.updateEntity(entity, request);
|
||||
|
||||
this.repository.save(entity);
|
||||
|
||||
return getById(entity.getId());
|
||||
}
|
||||
|
||||
public void delete(IdRequest request) {
|
||||
this.repository.deleteAllById(request.getIds());
|
||||
}
|
||||
|
||||
public NetDiskDto getById(String id) {
|
||||
NetDiskEntity entity = repository.get(id);
|
||||
|
||||
return mapper.toDto(entity);
|
||||
}
|
||||
|
||||
public Page<NetDiskDto> list(CommonQuery query) {
|
||||
Page<NetDiskEntity> page =
|
||||
repository.findAll(
|
||||
query.specification(conversionService),
|
||||
PageRequest.of(
|
||||
query.getPageNo(),
|
||||
query.getPageSize(),
|
||||
Sort.by(query.getOrders())));
|
||||
|
||||
return page.map(this.mapper::toDto);
|
||||
}
|
||||
|
||||
public PreCreateFileDto preCreateFile(CreateFileDto request) {
|
||||
|
||||
PreCreateFileDto dto = new PreCreateFileDto();
|
||||
validateFileName(request.getName());
|
||||
|
||||
checkParentWithEntryName(request.getParent(), request.getName());
|
||||
|
||||
List<NetDiskEntity> sha256 = repository.findAllBySha256(request.getSha256());
|
||||
|
||||
String ossKey = sha256.stream().findAny().map(NetDiskEntity::getOssKey).orElse(null);
|
||||
|
||||
dto.setOssKey(ossKey);
|
||||
|
||||
dto.setSliceSize((long) DEFAULT_SLICE_SIZE);
|
||||
|
||||
if (request.getSize() > DEFAULT_SLICE_SIZE) {
|
||||
|
||||
if (StringUtils.isEmpty(ossKey)) {
|
||||
|
||||
// 查找分片记录
|
||||
List<NetDiskEntity> slice = findSlice(request.getSha256());
|
||||
|
||||
dto.setSlices(this.mapper.toDto(slice));
|
||||
}
|
||||
}
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
private List<NetDiskEntity> findSlice(String sha256) {
|
||||
return repository.findAll(
|
||||
(root, query, criteriaBuilder) -> {
|
||||
return criteriaBuilder.and(
|
||||
criteriaBuilder.equal(root.get("sha256"), sha256),
|
||||
criteriaBuilder.equal(root.get("entryType"), "2"));
|
||||
},
|
||||
Sort.by(Sort.Direction.ASC, "sliceIndex"));
|
||||
}
|
||||
|
||||
public void updateDirSize(String id) {
|
||||
NetDiskEntity entity = get(id);
|
||||
entity.setSize(entity.getChildren().stream().mapToLong(NetDiskEntity::getSize).sum());
|
||||
save(entity);
|
||||
|
||||
while (entity.getParent() != null) {
|
||||
entity = entity.getParent();
|
||||
entity.setSize(entity.getChildren().stream().mapToLong(NetDiskEntity::getSize).sum());
|
||||
save(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,8 @@ public class AliyunProperty {
|
||||
|
||||
private List<OSSRegion> regions;
|
||||
|
||||
private Long preSignedUrlExpire;
|
||||
|
||||
private String ak;
|
||||
|
||||
private String sk;
|
||||
|
||||
@@ -5,6 +5,7 @@ import cn.lihongjie.coal.base.dto.R;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.server.ServerHttpRequest;
|
||||
import org.springframework.http.server.ServerHttpResponse;
|
||||
@@ -48,6 +49,10 @@ public class RResponseBodyAdvice implements ResponseBodyAdvice<Object> {
|
||||
return body;
|
||||
}
|
||||
|
||||
if (body instanceof ResponseEntity<?>) {
|
||||
return body;
|
||||
}
|
||||
|
||||
if (body instanceof Page<?> p) {
|
||||
R<? extends List<?>> r = R.success(p.getContent());
|
||||
r.setPageNo(p.getNumber());
|
||||
|
||||
@@ -1675,6 +1675,24 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"code": "netDisk.entryType",
|
||||
"name": "网盘文件类型",
|
||||
"item": [
|
||||
{
|
||||
"code": "0",
|
||||
"name": "文件夹"
|
||||
},
|
||||
{
|
||||
"code": "1",
|
||||
"name": "文件"
|
||||
},
|
||||
{
|
||||
"code": "2",
|
||||
"name": "文件分片"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"code": "notebook.contentType",
|
||||
"name": "章节内容类型",
|
||||
|
||||
Reference in New Issue
Block a user