commit
c0cb8fba35
14
pom.xml
14
pom.xml
@ -98,8 +98,18 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>co.elastic.clients</groupId>
|
||||||
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
|
<artifactId>elasticsearch-java</artifactId>
|
||||||
|
<version>8.1.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>jakarta.json</groupId>
|
||||||
|
<artifactId>jakarta.json-api</artifactId>
|
||||||
|
<version>2.0.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package com.qiwenshare.file.api;
|
//package com.qiwenshare.file.api;
|
||||||
|
//
|
||||||
import com.qiwenshare.file.config.es.FileSearch;
|
//import com.qiwenshare.file.config.es.FileSearch;
|
||||||
import org.springframework.context.annotation.Lazy;
|
//import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
|
//import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
|
||||||
|
//
|
||||||
@Lazy
|
//@Lazy
|
||||||
public interface IElasticSearchService extends ElasticsearchRepository<FileSearch,Long> {
|
//public interface IElasticSearchService extends ElasticsearchRepository<FileSearch,Long> {
|
||||||
|
//
|
||||||
}
|
//}
|
@ -1,6 +1,7 @@
|
|||||||
package com.qiwenshare.file.api;
|
package com.qiwenshare.file.api;
|
||||||
|
|
||||||
import com.qiwenshare.file.domain.FileBean;
|
import com.qiwenshare.file.domain.FileBean;
|
||||||
|
import com.qiwenshare.file.domain.UserFile;
|
||||||
import com.qiwenshare.file.dto.file.DownloadFileDTO;
|
import com.qiwenshare.file.dto.file.DownloadFileDTO;
|
||||||
import com.qiwenshare.file.dto.file.PreviewDTO;
|
import com.qiwenshare.file.dto.file.PreviewDTO;
|
||||||
import com.qiwenshare.file.dto.file.UploadFileDTO;
|
import com.qiwenshare.file.dto.file.UploadFileDTO;
|
||||||
@ -8,6 +9,7 @@ import com.qiwenshare.file.vo.file.UploadFileVo;
|
|||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public interface IFiletransferService {
|
public interface IFiletransferService {
|
||||||
|
|
||||||
@ -16,6 +18,7 @@ public interface IFiletransferService {
|
|||||||
void uploadFile(HttpServletRequest request, UploadFileDTO UploadFileDto, Long userId);
|
void uploadFile(HttpServletRequest request, UploadFileDTO UploadFileDto, Long userId);
|
||||||
|
|
||||||
void downloadFile(HttpServletResponse httpServletResponse, DownloadFileDTO downloadFileDTO);
|
void downloadFile(HttpServletResponse httpServletResponse, DownloadFileDTO downloadFileDTO);
|
||||||
|
void downloadUserFileList(HttpServletResponse httpServletResponse, String filePath, String fileName, List<UserFile> userFileList);
|
||||||
void previewFile(HttpServletResponse httpServletResponse, PreviewDTO previewDTO);
|
void previewFile(HttpServletResponse httpServletResponse, PreviewDTO previewDTO);
|
||||||
void previewPictureFile(HttpServletResponse httpServletResponse, PreviewDTO previewDTO);
|
void previewPictureFile(HttpServletResponse httpServletResponse, PreviewDTO previewDTO);
|
||||||
void deleteFile(FileBean fileBean);
|
void deleteFile(FileBean fileBean);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.qiwenshare.file.component;
|
package com.qiwenshare.file.component;
|
||||||
|
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import co.elastic.clients.elasticsearch.ElasticsearchClient;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.qiwenshare.common.constant.FileConstant;
|
import com.qiwenshare.common.constant.FileConstant;
|
||||||
@ -60,9 +61,11 @@ public class FileDealComp {
|
|||||||
@Resource
|
@Resource
|
||||||
UFOPFactory ufopFactory;
|
UFOPFactory ufopFactory;
|
||||||
|
|
||||||
|
// @Autowired
|
||||||
|
// @Lazy
|
||||||
|
// private IElasticSearchService elasticSearchService;
|
||||||
@Autowired
|
@Autowired
|
||||||
@Lazy
|
private ElasticsearchClient elasticsearchClient;
|
||||||
private IElasticSearchService elasticSearchService;
|
|
||||||
|
|
||||||
public static Executor exec = Executors.newFixedThreadPool(10);
|
public static Executor exec = Executors.newFixedThreadPool(10);
|
||||||
|
|
||||||
@ -292,7 +295,7 @@ public class FileDealComp {
|
|||||||
// fileSearch.setContent(content);
|
// fileSearch.setContent(content);
|
||||||
//
|
//
|
||||||
// }
|
// }
|
||||||
elasticSearchService.save(fileSearch);
|
elasticsearchClient.index(i -> i.index("filesearch").id(String.valueOf(fileSearch.getUserFileId())).document(fileSearch));
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.debug("ES更新操作失败,请检查配置");
|
log.debug("ES更新操作失败,请检查配置");
|
||||||
@ -303,7 +306,9 @@ public class FileDealComp {
|
|||||||
public void deleteESByUserFileId(Long userFileId) {
|
public void deleteESByUserFileId(Long userFileId) {
|
||||||
exec.execute(()->{
|
exec.execute(()->{
|
||||||
try {
|
try {
|
||||||
elasticSearchService.deleteById(userFileId);
|
elasticsearchClient.delete(d -> d
|
||||||
|
.index("filesearch")
|
||||||
|
.id(String.valueOf(userFileId)));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.debug("ES删除操作失败,请检查配置");
|
log.debug("ES删除操作失败,请检查配置");
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.qiwenshare.file.config.es;
|
||||||
|
|
||||||
|
import co.elastic.clients.elasticsearch.ElasticsearchClient;
|
||||||
|
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
|
||||||
|
import co.elastic.clients.transport.ElasticsearchTransport;
|
||||||
|
import co.elastic.clients.transport.rest_client.RestClientTransport;
|
||||||
|
import org.apache.http.HttpHost;
|
||||||
|
import org.elasticsearch.client.RestClient;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class ElasticSearchConfig {
|
||||||
|
|
||||||
|
//注入IOC容器
|
||||||
|
@Bean
|
||||||
|
public ElasticsearchClient elasticsearchClient(){
|
||||||
|
RestClient client = RestClient.builder(new HttpHost("localhost", 9200,"http")).build();
|
||||||
|
ElasticsearchTransport transport = new RestClientTransport(client,new JacksonJsonpMapper());
|
||||||
|
return new ElasticsearchClient(transport);
|
||||||
|
}
|
||||||
|
}
|
@ -1,51 +1,26 @@
|
|||||||
package com.qiwenshare.file.config.es;
|
package com.qiwenshare.file.config.es;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.springframework.data.annotation.Id;
|
|
||||||
import org.springframework.data.elasticsearch.annotations.Document;
|
|
||||||
import org.springframework.data.elasticsearch.annotations.Field;
|
|
||||||
import org.springframework.data.elasticsearch.annotations.FieldType;
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@Document(indexName = "filesearch")
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
public class FileSearch {
|
public class FileSearch {
|
||||||
@Id
|
private String indexName;
|
||||||
private Long userFileId;
|
private Long userFileId;
|
||||||
@Field(type = FieldType.Long)
|
|
||||||
private Long fileId;
|
private Long fileId;
|
||||||
@Field(type = FieldType.Text)
|
|
||||||
private String fileName;
|
private String fileName;
|
||||||
@Field(type = FieldType.Text)
|
|
||||||
private String content;
|
private String content;
|
||||||
@Field(type = FieldType.Keyword)
|
|
||||||
private String timeStampName;
|
|
||||||
@Field(type = FieldType.Keyword)
|
|
||||||
private String fileUrl;
|
private String fileUrl;
|
||||||
@Field(type = FieldType.Long)
|
|
||||||
private Long fileSize;
|
private Long fileSize;
|
||||||
@Field(type = FieldType.Integer)
|
|
||||||
@Deprecated
|
|
||||||
private Integer isOSS;
|
|
||||||
@Field(type = FieldType.Integer)
|
|
||||||
private Integer storageType;
|
private Integer storageType;
|
||||||
@Field(type = FieldType.Integer)
|
|
||||||
private Integer pointCount;
|
|
||||||
@Field(type = FieldType.Keyword)
|
|
||||||
private String identifier;
|
private String identifier;
|
||||||
@Field(type = FieldType.Long)
|
|
||||||
private Long userId;
|
private Long userId;
|
||||||
@Field(type = FieldType.Keyword)
|
|
||||||
private String filePath;
|
private String filePath;
|
||||||
@Field(type = FieldType.Keyword)
|
|
||||||
private String extendName;
|
private String extendName;
|
||||||
@Field(type = FieldType.Integer)
|
|
||||||
private Integer isDir;
|
private Integer isDir;
|
||||||
@Field(type = FieldType.Keyword)
|
|
||||||
private String uploadTime;
|
private String uploadTime;
|
||||||
@Field(type = FieldType.Integer)
|
|
||||||
private Integer deleteFlag;
|
private Integer deleteFlag;
|
||||||
@Field(type = FieldType.Keyword)
|
|
||||||
private String deleteTime;
|
private String deleteTime;
|
||||||
@Field(type = FieldType.Keyword)
|
|
||||||
private String deleteBatchNum;
|
private String deleteBatchNum;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
package com.qiwenshare.file.controller;
|
package com.qiwenshare.file.controller;
|
||||||
|
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import co.elastic.clients.elasticsearch.ElasticsearchClient;
|
||||||
|
import co.elastic.clients.elasticsearch._types.SortOrder;
|
||||||
|
import co.elastic.clients.elasticsearch.core.SearchResponse;
|
||||||
|
import co.elastic.clients.elasticsearch.core.search.HighlighterEncoder;
|
||||||
|
import co.elastic.clients.elasticsearch.core.search.Hit;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
@ -19,6 +25,7 @@ import com.qiwenshare.file.domain.UserFile;
|
|||||||
import com.qiwenshare.file.dto.file.*;
|
import com.qiwenshare.file.dto.file.*;
|
||||||
import com.qiwenshare.file.util.TreeNode;
|
import com.qiwenshare.file.util.TreeNode;
|
||||||
import com.qiwenshare.file.vo.file.FileListVo;
|
import com.qiwenshare.file.vo.file.FileListVo;
|
||||||
|
import com.qiwenshare.file.vo.file.SearchFileVO;
|
||||||
import com.qiwenshare.ufop.constant.UFOPConstant;
|
import com.qiwenshare.ufop.constant.UFOPConstant;
|
||||||
import com.qiwenshare.ufop.factory.UFOPFactory;
|
import com.qiwenshare.ufop.factory.UFOPFactory;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@ -26,18 +33,9 @@ import io.swagger.v3.oas.annotations.Parameter;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.codec.digest.DigestUtils;
|
import org.apache.commons.codec.digest.DigestUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
import org.elasticsearch.index.query.DisMaxQueryBuilder;
|
|
||||||
import org.elasticsearch.index.query.QueryBuilder;
|
|
||||||
import org.elasticsearch.index.query.QueryBuilders;
|
|
||||||
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.PageRequest;
|
|
||||||
import org.springframework.data.domain.Sort;
|
|
||||||
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
|
|
||||||
import org.springframework.data.elasticsearch.core.SearchHits;
|
|
||||||
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
|
|
||||||
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
@ -59,12 +57,12 @@ public class FileController {
|
|||||||
@Resource
|
@Resource
|
||||||
IUserFileService userFileService;
|
IUserFileService userFileService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ElasticsearchRestTemplate elasticsearchRestTemplate;
|
|
||||||
@Resource
|
@Resource
|
||||||
FileDealComp fileDealComp;
|
FileDealComp fileDealComp;
|
||||||
@Resource
|
@Resource
|
||||||
UFOPFactory ufopFactory;
|
UFOPFactory ufopFactory;
|
||||||
|
@Autowired
|
||||||
|
private ElasticsearchClient elasticsearchClient;
|
||||||
|
|
||||||
public static final String CURRENT_MODULE = "文件接口";
|
public static final String CURRENT_MODULE = "文件接口";
|
||||||
|
|
||||||
@ -100,59 +98,56 @@ public class FileController {
|
|||||||
@GetMapping(value = "/search")
|
@GetMapping(value = "/search")
|
||||||
@MyLog(operation = "文件搜索", module = CURRENT_MODULE)
|
@MyLog(operation = "文件搜索", module = CURRENT_MODULE)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public RestResult<SearchHits<FileSearch>> searchFile(SearchFileDTO searchFileDTO) {
|
public RestResult<List<SearchFileVO>> searchFile(SearchFileDTO searchFileDTO) {
|
||||||
JwtUser sessionUserBean = SessionUtil.getSession();
|
JwtUser sessionUserBean = SessionUtil.getSession();
|
||||||
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
|
|
||||||
HighlightBuilder.Field allHighLight = new HighlightBuilder.Field("*").preTags("<span class='keyword'>")
|
|
||||||
.postTags("</span>");
|
|
||||||
|
|
||||||
queryBuilder.withHighlightFields(allHighLight);
|
|
||||||
|
|
||||||
//设置分页
|
|
||||||
int currentPage = (int)searchFileDTO.getCurrentPage() - 1;
|
int currentPage = (int)searchFileDTO.getCurrentPage() - 1;
|
||||||
int pageCount = (int)(searchFileDTO.getPageCount() == 0 ? 10 : searchFileDTO.getPageCount());
|
int pageCount = (int)(searchFileDTO.getPageCount() == 0 ? 10 : searchFileDTO.getPageCount());
|
||||||
String order = searchFileDTO.getOrder();
|
|
||||||
Sort.Direction direction = null;
|
SearchResponse<FileSearch> search = null;
|
||||||
if (searchFileDTO.getDirection() == null) {
|
try {
|
||||||
direction = Sort.Direction.DESC;
|
search = elasticsearchClient.search(s -> s
|
||||||
} else if ("asc".equals(searchFileDTO.getDirection())) {
|
.index("filesearch")
|
||||||
direction = Sort.Direction.ASC;
|
.query(_1 -> _1
|
||||||
} else if ("desc".equals(searchFileDTO.getDirection())) {
|
.bool(_2 -> _2
|
||||||
direction = Sort.Direction.DESC;
|
.must(_3 -> _3
|
||||||
} else {
|
.bool(_4 -> _4
|
||||||
direction = Sort.Direction.DESC;
|
.should(_5 -> _5
|
||||||
|
.match(_6 -> _6
|
||||||
|
.field("fileName")
|
||||||
|
.query(searchFileDTO.getFileName())))
|
||||||
|
.should(_5 -> _5
|
||||||
|
.wildcard(_6 -> _6
|
||||||
|
.field("fileName")
|
||||||
|
.wildcard("*" + searchFileDTO.getFileName() + "*")))))
|
||||||
|
.must(_3 -> _3
|
||||||
|
.term(_4 -> _4
|
||||||
|
.field("userId")
|
||||||
|
.value(sessionUserBean.getUserId())))
|
||||||
|
))
|
||||||
|
.from(currentPage)
|
||||||
|
.size(pageCount)
|
||||||
|
.highlight(h -> h
|
||||||
|
.fields("fileName", f -> f.type("plain")
|
||||||
|
.preTags("<span class='keyword'>").postTags("</span>"))
|
||||||
|
.encoder(HighlighterEncoder.Html))
|
||||||
|
,
|
||||||
|
FileSearch.class);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
if (order == null) {
|
|
||||||
queryBuilder.withPageable(PageRequest.of(currentPage, pageCount));
|
List<SearchFileVO> searchFileVOList = new ArrayList<>();
|
||||||
} else {
|
for (Hit<FileSearch> hit : search.hits().hits()) {
|
||||||
queryBuilder.withPageable(PageRequest.of(currentPage, pageCount, Sort.by(direction, order)));
|
SearchFileVO searchFileVO = new SearchFileVO();
|
||||||
|
BeanUtil.copyProperties(hit.source(), searchFileVO);
|
||||||
|
searchFileVO.setHighLight(hit.highlight());
|
||||||
|
searchFileVOList.add(searchFileVO);
|
||||||
}
|
}
|
||||||
DisMaxQueryBuilder disMaxQueryBuilder = QueryBuilders.disMaxQuery();
|
return RestResult.success().data(searchFileVOList);
|
||||||
|
|
||||||
QueryBuilder q1 = QueryBuilders.boolQuery()
|
|
||||||
.must(QueryBuilders.multiMatchQuery(searchFileDTO.getFileName(), "fileName", "content"))
|
|
||||||
.must(QueryBuilders.termQuery("userId", sessionUserBean.getUserId())).boost(1f); //分词
|
|
||||||
|
|
||||||
QueryBuilder q2 = QueryBuilders.boolQuery()
|
|
||||||
.must(QueryBuilders.wildcardQuery("fileName", "*" + searchFileDTO.getFileName() + "*"))
|
|
||||||
.must(QueryBuilders.wildcardQuery("content", "*" + searchFileDTO.getFileName() + "*"))
|
|
||||||
.must(QueryBuilders.termQuery("userId", sessionUserBean.getUserId())).boost(2f); //模糊匹配
|
|
||||||
|
|
||||||
disMaxQueryBuilder.add(q1);
|
|
||||||
disMaxQueryBuilder.add(q2);
|
|
||||||
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
|
|
||||||
.withQuery(disMaxQueryBuilder).withHighlightFields(allHighLight).build();
|
|
||||||
//
|
|
||||||
// queryBuilder.withQuery(QueryBuilders.boolQuery()
|
|
||||||
//// .must(QueryBuilders.matchQuery("fileName", searchFileDTO.getFileName()))
|
|
||||||
// .must(QueryBuilders.multiMatchQuery(searchFileDTO.getFileName(),"fileName", "content"))
|
|
||||||
// .must(QueryBuilders.termQuery("userId", sessionUserBean.getUserId()))
|
|
||||||
// ).withQuery(QueryBuilders.wildcardQuery("fileName", "*" + searchFileDTO.getFileName() + "*"));
|
|
||||||
SearchHits<FileSearch> search = elasticsearchRestTemplate.search(searchQuery, FileSearch.class);
|
|
||||||
|
|
||||||
return RestResult.success().data(search);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Operation(summary = "文件重命名", description = "文件重命名", tags = {"file"})
|
@Operation(summary = "文件重命名", description = "文件重命名", tags = {"file"})
|
||||||
@RequestMapping(value = "/renamefile", method = RequestMethod.POST)
|
@RequestMapping(value = "/renamefile", method = RequestMethod.POST)
|
||||||
@MyLog(operation = "文件重命名", module = CURRENT_MODULE)
|
@MyLog(operation = "文件重命名", module = CURRENT_MODULE)
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
package com.qiwenshare.file.controller;
|
package com.qiwenshare.file.controller;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.qiwenshare.common.anno.MyLog;
|
import com.qiwenshare.common.anno.MyLog;
|
||||||
import com.qiwenshare.common.result.RestResult;
|
import com.qiwenshare.common.result.RestResult;
|
||||||
|
import com.qiwenshare.common.util.DateUtil;
|
||||||
import com.qiwenshare.common.util.MimeUtils;
|
import com.qiwenshare.common.util.MimeUtils;
|
||||||
import com.qiwenshare.common.util.security.JwtUser;
|
import com.qiwenshare.common.util.security.JwtUser;
|
||||||
import com.qiwenshare.common.util.security.SessionUtil;
|
import com.qiwenshare.common.util.security.SessionUtil;
|
||||||
import com.qiwenshare.file.api.*;
|
import com.qiwenshare.file.api.*;
|
||||||
import com.qiwenshare.file.component.FileDealComp;
|
import com.qiwenshare.file.component.FileDealComp;
|
||||||
import com.qiwenshare.file.domain.FileBean;
|
import com.qiwenshare.file.domain.FileBean;
|
||||||
import com.qiwenshare.file.domain.Image;
|
|
||||||
import com.qiwenshare.file.domain.StorageBean;
|
import com.qiwenshare.file.domain.StorageBean;
|
||||||
import com.qiwenshare.file.domain.UserFile;
|
import com.qiwenshare.file.domain.UserFile;
|
||||||
|
import com.qiwenshare.file.dto.file.BatchDeleteFileDTO;
|
||||||
import com.qiwenshare.file.dto.file.DownloadFileDTO;
|
import com.qiwenshare.file.dto.file.DownloadFileDTO;
|
||||||
import com.qiwenshare.file.dto.file.PreviewDTO;
|
import com.qiwenshare.file.dto.file.PreviewDTO;
|
||||||
import com.qiwenshare.file.dto.file.UploadFileDTO;
|
import com.qiwenshare.file.dto.file.UploadFileDTO;
|
||||||
@ -25,17 +26,14 @@ import com.qiwenshare.ufop.util.UFOPUtils;
|
|||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import javax.servlet.http.Cookie;
|
import javax.servlet.http.Cookie;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
@ -147,6 +145,25 @@ public class FiletransferController {
|
|||||||
filetransferService.downloadFile(httpServletResponse, downloadFileDTO);
|
filetransferService.downloadFile(httpServletResponse, downloadFileDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "批量下载文件", description = "批量下载文件", tags = {"filetransfer"})
|
||||||
|
@RequestMapping(value = "/batchdeletefile", method = RequestMethod.POST)
|
||||||
|
@MyLog(operation = "批量删除文件", module = CURRENT_MODULE)
|
||||||
|
@ResponseBody
|
||||||
|
public RestResult<String> batchDownloadFile(HttpServletResponse httpServletResponse, @RequestBody BatchDeleteFileDTO batchDeleteFileDto) {
|
||||||
|
|
||||||
|
List<UserFile> userFiles = JSON.parseArray(batchDeleteFileDto.getFiles(), UserFile.class);
|
||||||
|
if (userFiles == null || userFiles.isEmpty()) {
|
||||||
|
return RestResult.fail().message("文件列表为空!");
|
||||||
|
}
|
||||||
|
UserFile userFile = userFileService.getById(userFiles.get(0).getUserFileId());
|
||||||
|
httpServletResponse.setContentType("application/force-download");// 设置强制下载不打开
|
||||||
|
String fileName = DateUtil.getCurrentTime();
|
||||||
|
httpServletResponse.addHeader("Content-Disposition", "attachment;fileName=" + fileName);// 设置文件名
|
||||||
|
filetransferService.downloadUserFileList(httpServletResponse, userFile.getFilePath(), fileName, userFiles);
|
||||||
|
|
||||||
|
return RestResult.success().message("批量下载文件成功");
|
||||||
|
}
|
||||||
|
|
||||||
@Operation(summary="预览文件", description="用于文件预览", tags = {"filetransfer"})
|
@Operation(summary="预览文件", description="用于文件预览", tags = {"filetransfer"})
|
||||||
@GetMapping("/preview")
|
@GetMapping("/preview")
|
||||||
public void preview(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, PreviewDTO previewDTO) throws IOException {
|
public void preview(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, PreviewDTO previewDTO) throws IOException {
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
package com.qiwenshare.file.controller;
|
package com.qiwenshare.file.controller;
|
||||||
|
|
||||||
import com.qiwenshare.file.api.IElasticSearchService;
|
import co.elastic.clients.elasticsearch.ElasticsearchClient;
|
||||||
import com.qiwenshare.file.component.FileDealComp;
|
import com.qiwenshare.file.component.FileDealComp;
|
||||||
import com.qiwenshare.file.domain.UserFile;
|
import com.qiwenshare.file.domain.UserFile;
|
||||||
import com.qiwenshare.file.service.UserFileService;
|
import com.qiwenshare.file.service.UserFileService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Lazy;
|
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
|
|
||||||
@ -19,18 +18,17 @@ public class TaskController {
|
|||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
UserFileService userFileService;
|
UserFileService userFileService;
|
||||||
@Autowired
|
|
||||||
@Lazy
|
|
||||||
private IElasticSearchService elasticSearchService;
|
|
||||||
@Resource
|
@Resource
|
||||||
FileDealComp fileDealComp;
|
FileDealComp fileDealComp;
|
||||||
|
@Autowired
|
||||||
|
private ElasticsearchClient elasticsearchClient;
|
||||||
|
|
||||||
|
|
||||||
@Scheduled(fixedRate = 1000 * 60 * 60 * 24)
|
@Scheduled(fixedRate = 1000 * 60 * 60 * 24)
|
||||||
public void updateElasticSearch() {
|
public void updateElasticSearch() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
elasticSearchService.deleteAll();
|
elasticsearchClient.delete(d -> d.index("filesearch"));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.debug("删除ES失败:" + e);
|
log.debug("删除ES失败:" + e);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.qiwenshare.file.dto.file;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(name = "批量下载文件DTO",required = true)
|
||||||
|
public class BatchDownloadFileDTO {
|
||||||
|
@Schema(description="文件集合", required = true)
|
||||||
|
private String files;
|
||||||
|
|
||||||
|
}
|
@ -11,8 +11,4 @@ public class SearchFileDTO {
|
|||||||
private long currentPage;
|
private long currentPage;
|
||||||
@Schema(description="每页数量", required=true)
|
@Schema(description="每页数量", required=true)
|
||||||
private long pageCount;
|
private long pageCount;
|
||||||
@Schema(description="排序字段(可排序字段:fileName, fileSize, extendName, uploadTime)", required=false)
|
|
||||||
private String order;
|
|
||||||
@Schema(description="方向(升序:asc, 降序:desc)", required=false)
|
|
||||||
private String direction;
|
|
||||||
}
|
}
|
||||||
|
@ -290,92 +290,97 @@ public class FiletransferService implements IFiletransferService {
|
|||||||
.eq(UserFile::getDeleteFlag, 0);
|
.eq(UserFile::getDeleteFlag, 0);
|
||||||
List<UserFile> userFileList = userFileMapper.selectList(lambdaQueryWrapper);
|
List<UserFile> userFileList = userFileMapper.selectList(lambdaQueryWrapper);
|
||||||
|
|
||||||
String staticPath = UFOPUtils.getStaticPath();
|
downloadUserFileList(httpServletResponse, userFile.getFilePath(), userFile.getFileName(), userFileList);
|
||||||
String tempPath = staticPath + "temp" + File.separator;
|
}
|
||||||
File tempDirFile = new File(tempPath);
|
}
|
||||||
if (!tempDirFile.exists()) {
|
|
||||||
tempDirFile.mkdirs();
|
|
||||||
}
|
|
||||||
|
|
||||||
FileOutputStream f = null;
|
@Override
|
||||||
|
public void downloadUserFileList(HttpServletResponse httpServletResponse, String filePath, String fileName, List<UserFile> userFileList) {
|
||||||
|
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 (UserFile userFile1 : userFileList) {
|
||||||
|
FileBean fileBean = fileMapper.selectById(userFile1.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());
|
||||||
|
downloadFile.setFileSize(fileBean.getFileSize());
|
||||||
|
InputStream inputStream = downloader.getInputStream(downloadFile);
|
||||||
|
BufferedInputStream bis = new BufferedInputStream(inputStream);
|
||||||
|
try {
|
||||||
|
zos.putNextEntry(new ZipEntry(userFile1.getFilePath().replace(filePath, "/") + userFile1.getFileName() + "." + userFile1.getExtendName()));
|
||||||
|
|
||||||
|
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 {
|
||||||
|
try {
|
||||||
|
bis.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
out.flush();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("压缩过程中出现异常:"+ e);
|
||||||
|
} finally {
|
||||||
try {
|
try {
|
||||||
f = new FileOutputStream(tempPath + userFile.getFileName() + ".zip");
|
out.close();
|
||||||
} catch (FileNotFoundException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
CheckedOutputStream csum = new CheckedOutputStream(f, new Adler32());
|
}
|
||||||
ZipOutputStream zos = new ZipOutputStream(csum);
|
String zipPath = "";
|
||||||
BufferedOutputStream out = new BufferedOutputStream(zos);
|
try {
|
||||||
|
Downloader downloader = ufopFactory.getDownloader(StorageTypeEnum.LOCAL.getCode());
|
||||||
try {
|
DownloadFile downloadFile = new DownloadFile();
|
||||||
for (UserFile userFile1 : userFileList) {
|
downloadFile.setFileUrl("temp" + File.separator + fileName + ".zip");
|
||||||
FileBean fileBean = fileMapper.selectById(userFile1.getFileId());
|
File tempFile = new File(UFOPUtils.getStaticPath() + downloadFile.getFileUrl());
|
||||||
Downloader downloader = ufopFactory.getDownloader(fileBean.getStorageType());
|
httpServletResponse.setContentLengthLong(tempFile.length());
|
||||||
if (downloader == null) {
|
downloader.download(httpServletResponse, downloadFile);
|
||||||
log.error("下载失败,文件存储类型不支持下载,storageType:{}", fileBean.getStorageType());
|
zipPath = UFOPUtils.getStaticPath() + "temp" + File.separator + fileName + ".zip";
|
||||||
throw new UploadException("下载失败");
|
} catch (Exception e) {
|
||||||
}
|
//org.apache.catalina.connector.ClientAbortException: java.io.IOException: Connection reset by peer
|
||||||
DownloadFile downloadFile = new DownloadFile();
|
if (e.getMessage().contains("ClientAbortException")) {
|
||||||
downloadFile.setFileUrl(fileBean.getFileUrl());
|
//该异常忽略不做处理
|
||||||
downloadFile.setFileSize(fileBean.getFileSize());
|
} else {
|
||||||
InputStream inputStream = downloader.getInputStream(downloadFile);
|
log.error("下传zip文件出现异常:{}", e.getMessage());
|
||||||
BufferedInputStream bis = new BufferedInputStream(inputStream);
|
|
||||||
try {
|
|
||||||
zos.putNextEntry(new ZipEntry(userFile1.getFilePath().replace(userFile.getFilePath(), "/") + userFile1.getFileName() + "." + userFile1.getExtendName()));
|
|
||||||
|
|
||||||
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 {
|
|
||||||
try {
|
|
||||||
bis.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
out.flush();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("压缩过程中出现异常:"+ e);
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
out.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
String zipPath = "";
|
|
||||||
try {
|
|
||||||
Downloader downloader = ufopFactory.getDownloader(StorageTypeEnum.LOCAL.getCode());
|
|
||||||
DownloadFile downloadFile = new DownloadFile();
|
|
||||||
downloadFile.setFileUrl("temp" + File.separator + userFile.getFileName() + ".zip");
|
|
||||||
File tempFile = new File(UFOPUtils.getStaticPath() + downloadFile.getFileUrl());
|
|
||||||
httpServletResponse.setContentLengthLong(tempFile.length());
|
|
||||||
downloader.download(httpServletResponse, downloadFile);
|
|
||||||
zipPath = UFOPUtils.getStaticPath() + "temp" + File.separator + userFile.getFileName() + ".zip";
|
|
||||||
} catch (Exception e) {
|
|
||||||
//org.apache.catalina.connector.ClientAbortException: java.io.IOException: Connection reset by peer
|
|
||||||
if (e.getMessage().contains("ClientAbortException")) {
|
|
||||||
//该异常忽略不做处理
|
|
||||||
} else {
|
|
||||||
log.error("下传zip文件出现异常:{}", e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
File file = new File(zipPath);
|
File file = new File(zipPath);
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
file.delete();
|
file.delete();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
24
src/main/java/com/qiwenshare/file/vo/file/SearchFileVO.java
Normal file
24
src/main/java/com/qiwenshare/file/vo/file/SearchFileVO.java
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package com.qiwenshare.file.vo.file;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author MAC
|
||||||
|
* @version 1.0
|
||||||
|
* @description: TODO
|
||||||
|
* @date 2022/4/10 11:04
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SearchFileVO {
|
||||||
|
private Long userFileId;
|
||||||
|
private String fileName;
|
||||||
|
private String filePath;
|
||||||
|
private String extendName;
|
||||||
|
private Long fileSize;
|
||||||
|
private String fileUrl;
|
||||||
|
private Map<String, List<String>> highLight;
|
||||||
|
private Integer isDir;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user