FileService.java 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. package ieven.server.webapp.domain.file;
  2. import com.mongodb.client.gridfs.model.GridFSFile;
  3. import com.mongodb.client.result.DeleteResult;
  4. import ieven.server.webapp.domain.IdInput;
  5. import ieven.server.webapp.domain.data.DataMap;
  6. import ieven.server.webapp.domain.model.Model;
  7. import ieven.server.webapp.infrastructure.wrapper.Mapped;
  8. import ieven.server.webapp.service.impl.MongoExcelServiceImpl;
  9. import ieven.server.webapp.util.excel.ExcelXlsReader;
  10. import ieven.server.webapp.util.excel.ExcelXlsxReader;
  11. import ieven.server.webapp.util.excel.PublicStatic;
  12. import lombok.extern.slf4j.Slf4j;
  13. import org.apache.commons.csv.CSVFormat;
  14. import org.apache.commons.csv.CSVParser;
  15. import org.apache.commons.csv.CSVRecord;
  16. import org.apache.commons.lang3.StringUtils;
  17. import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
  18. import org.bson.types.ObjectId;
  19. import org.springframework.beans.factory.annotation.Autowired;
  20. import org.springframework.beans.factory.annotation.Qualifier;
  21. import org.springframework.context.annotation.Lazy;
  22. import org.springframework.data.domain.Sort;
  23. import org.springframework.data.mongodb.core.MongoTemplate;
  24. import org.springframework.data.mongodb.core.query.Criteria;
  25. import org.springframework.data.mongodb.core.query.Query;
  26. import org.springframework.data.mongodb.core.query.Update;
  27. import org.springframework.data.mongodb.gridfs.GridFsOperations;
  28. import org.springframework.data.mongodb.gridfs.GridFsResource;
  29. import org.springframework.data.mongodb.gridfs.GridFsTemplate;
  30. import org.springframework.scheduling.annotation.Async;
  31. import org.springframework.scheduling.annotation.AsyncResult;
  32. import org.springframework.scheduling.annotation.EnableAsync;
  33. import org.springframework.stereotype.Service;
  34. import org.springframework.web.multipart.MultipartFile;
  35. import org.xml.sax.SAXException;
  36. import java.io.IOException;
  37. import java.io.InputStream;
  38. import java.io.InputStreamReader;
  39. import java.text.SimpleDateFormat;
  40. import java.util.Date;
  41. import java.util.List;
  42. import java.util.concurrent.ExecutionException;
  43. import java.util.concurrent.Future;
  44. import java.util.concurrent.ThreadPoolExecutor;
  45. import java.util.stream.Collectors;
  46. @Slf4j
  47. @Service
  48. @EnableAsync
  49. public class FileService {
  50. @Autowired
  51. private GridFsTemplate gridFsTemplate;
  52. @Autowired
  53. private MongoTemplate mongoTemplate;
  54. @Autowired
  55. private GridFsOperations fsOperations;
  56. @Autowired
  57. @Lazy
  58. private FileService fileService;
  59. public Mapped storeUploaded(MultipartFile file, String modelId) {
  60. String filename = file.getOriginalFilename();
  61. String contentType = file.getContentType();
  62. //直接上传到mongo
  63. ObjectId objectId = null;
  64. try {
  65. objectId = gridFsTemplate.store(file.getInputStream(), filename, contentType);
  66. } catch (IOException e) {
  67. log.info("转储文件失败");
  68. e.printStackTrace();
  69. return Mapped.ERROR("转储文件失败");
  70. }
  71. LogicalFile logicalFile = new LogicalFile();
  72. logicalFile.setFilename(filename);
  73. logicalFile.setUploadDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
  74. logicalFile.setModelId(modelId);
  75. logicalFile.setGridId(objectId);
  76. logicalFile.setGenerated(Boolean.FALSE);
  77. logicalFile.setStatus(FileStatus.STATUS_LOADING);
  78. //使用主键自动生成id
  79. logicalFile = mongoTemplate.insert(logicalFile);
  80. //异步读取数据并存储到mongo
  81. fileService.readFile(logicalFile);
  82. // fileService.readFileWhileStoreDataAsync(objectId);
  83. return Mapped.OK();
  84. }
  85. @Async
  86. public void readFile(LogicalFile uploaded) {
  87. GridFSFile fsFile = fsOperations.findOne(new Query(Criteria.where("_id").is(uploaded.getGridId())));
  88. if (fsFile == null) {
  89. //解析失败
  90. modifyStatus(uploaded.getId(), FileStatus.STATUS_ERROR);
  91. return;
  92. }
  93. GridFsResource resource = fsOperations.getResource(fsFile);
  94. String filename = resource.getFilename();
  95. if (StringUtils.isBlank(filename)) {
  96. //解析失败
  97. modifyStatus(uploaded.getId(), FileStatus.STATUS_ERROR);
  98. return;
  99. }
  100. try {
  101. InputStream inputStream = resource.getInputStream();
  102. if (filename.endsWith(".xlsx")) {
  103. MongoExcelServiceImpl mongoExcelService = new MongoExcelServiceImpl(mongoTemplate, uploaded.getId());
  104. ExcelXlsxReader reader = new ExcelXlsxReader(mongoExcelService);
  105. reader.processStream(inputStream);
  106. mongoExcelService.insertRest();
  107. } else if (filename.endsWith(".xls")) {
  108. MongoExcelServiceImpl mongoExcelService = new MongoExcelServiceImpl(mongoTemplate, uploaded.getId());
  109. ExcelXlsReader reader = new ExcelXlsReader(mongoExcelService);
  110. reader.processStream(inputStream);
  111. mongoExcelService.insertRest();
  112. } else if (filename.endsWith(".csv")) {
  113. MongoExcelServiceImpl mongoExcelService = new MongoExcelServiceImpl(mongoTemplate, uploaded.getId());
  114. CSVParser csvParser = CSVFormat.EXCEL.parse(new InputStreamReader(inputStream, "gbk"));
  115. int curRow = 0;
  116. for (CSVRecord record : csvParser) {
  117. mongoExcelService.getRows(0, curRow, record.stream().map(PublicStatic::removeAllSpecial).collect(Collectors.toList()));
  118. curRow++;
  119. }
  120. mongoExcelService.insertRest();
  121. }
  122. } catch (IOException | OpenXML4JException | SAXException e) {
  123. //解析失败
  124. modifyStatus(uploaded.getId(), FileStatus.STATUS_ERROR);
  125. e.printStackTrace();
  126. }
  127. //解析成功
  128. modifyStatus(uploaded.getId(), FileStatus.STATUS_FINISHED);
  129. }
  130. private void modifyStatus(String id, String status) {
  131. Query query = new Query();
  132. query.addCriteria(Criteria.where("_id").is(id));
  133. Update update = new Update();
  134. update.set("status", status);
  135. mongoTemplate.updateFirst(query, update, "logical_file");
  136. }
  137. public Mapped listUploaded(FileListInput fileListInput) {
  138. String modelId = fileListInput.getModelId();
  139. if (modelId == null) {
  140. return Mapped.ERROR("没有选择任何分组");
  141. }
  142. Future<Long> longFuture = fileService.countTotalByModelId(modelId);
  143. Future<String> modelNameFuture = fileService.retrieveModelname(modelId);
  144. int page = fileListInput.getPage();
  145. int pageSize = fileListInput.getPageSize();
  146. int skip = (page - 1) * pageSize;
  147. Query query = new Query(Criteria.where("modelId").is(modelId));
  148. query.with(Sort.by(
  149. Sort.Order.desc("uploadDate")
  150. ));
  151. List<LogicalFile> resultList = mongoTemplate.find(
  152. query.skip(skip).limit(pageSize),
  153. LogicalFile.class);
  154. Long total = null;
  155. String modelName = "";
  156. try {
  157. total = longFuture.get();
  158. modelName = modelNameFuture.get();
  159. } catch (InterruptedException | ExecutionException e) {
  160. return Mapped.ERROR("查询出错");
  161. }
  162. int i = 0;
  163. for (LogicalFile file : resultList) {
  164. file.setModelName(modelName);
  165. file.setCount(++i);
  166. }
  167. Mapped res = Mapped.OK();
  168. res.put("code", 200);
  169. res.put("result", resultList);
  170. res.put("total", total);
  171. res.put("currentPage", page);
  172. res.put("pageSize", pageSize);
  173. return res;
  174. }
  175. public Mapped deleteById(IdInput idInput) {
  176. String id = idInput.getId();
  177. Query query = new Query(Criteria.where("id").is(id));
  178. LogicalFile file = mongoTemplate.findOne(query, LogicalFile.class);
  179. //删除物理文件
  180. if (file != null && file.getGridId() != null) {
  181. String physicalId = file.getGridId().toHexString();
  182. fileService.removePhysicalFile(physicalId);
  183. }
  184. //删除数据
  185. fileService.removeDataByFileId(id);
  186. DeleteResult result = mongoTemplate.remove(query, LogicalFile.class);
  187. if (result.getDeletedCount() > 0) {
  188. return Mapped.OK();
  189. } else {
  190. return Mapped.ERROR("删除失败");
  191. }
  192. }
  193. @Async
  194. Future<Long> countTotalByModelId(String modelId) {
  195. Long total = mongoTemplate.count(new Query(Criteria.where("modelId").is(modelId)), LogicalFile.class);
  196. return new AsyncResult<>(total);
  197. }
  198. @Async
  199. void removePhysicalFile(String id) {
  200. fsOperations.delete(new Query(Criteria.where("_id").is(id)));
  201. }
  202. @Async
  203. void removeDataByFileId(String fileId) {
  204. mongoTemplate.remove(new Query(Criteria.where("fileId").is(fileId)), DataMap.class);
  205. }
  206. @Async
  207. Future<String> retrieveModelname(String modelId) {
  208. Query query = new Query(Criteria.where("id").is(modelId));
  209. query.fields().include("modelName");
  210. Model model = mongoTemplate.findOne(query, Model.class, "model");
  211. return new AsyncResult<>(model != null ? model.getModelName() : "");
  212. }
  213. }