FileService.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. //
  2. // Source code recreated from a .class file by IntelliJ IDEA
  3. // (powered by FernFlower decompiler)
  4. //
  5. package ieven.server.webapp.domain.file;
  6. import cn.hutool.core.date.DateUtil;
  7. import cn.hutool.core.io.IoUtil;
  8. import cn.hutool.core.util.IdUtil;
  9. import com.mongodb.client.gridfs.model.GridFSFile;
  10. import com.mongodb.client.result.DeleteResult;
  11. import ieven.server.webapp.domain.IdInput;
  12. import ieven.server.webapp.domain.data.DataMap;
  13. import ieven.server.webapp.domain.data.Fields;
  14. import ieven.server.webapp.domain.model.Model;
  15. import ieven.server.webapp.infrastructure.wrapper.Mapped;
  16. import ieven.server.webapp.service.MongoExcelService;
  17. import ieven.server.webapp.util.excel.ExcelXlsReader;
  18. import ieven.server.webapp.util.excel.ExcelXlsxReader;
  19. import ieven.server.webapp.util.excel.PublicStatic;
  20. import org.apache.commons.csv.CSVFormat;
  21. import org.apache.commons.csv.CSVParser;
  22. import org.apache.commons.csv.CSVRecord;
  23. import org.apache.commons.lang3.StringUtils;
  24. import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
  25. import org.bson.types.ObjectId;
  26. import org.springframework.beans.factory.annotation.Autowired;
  27. import org.springframework.context.annotation.Lazy;
  28. import org.springframework.data.domain.Sort;
  29. import org.springframework.data.domain.Sort.Order;
  30. import org.springframework.data.mongodb.core.MongoTemplate;
  31. import org.springframework.data.mongodb.core.query.Criteria;
  32. import org.springframework.data.mongodb.core.query.Query;
  33. import org.springframework.data.mongodb.core.query.Update;
  34. import org.springframework.data.mongodb.gridfs.GridFsOperations;
  35. import org.springframework.data.mongodb.gridfs.GridFsResource;
  36. import org.springframework.data.mongodb.gridfs.GridFsTemplate;
  37. import org.springframework.scheduling.annotation.Async;
  38. import org.springframework.scheduling.annotation.AsyncResult;
  39. import org.springframework.scheduling.annotation.EnableAsync;
  40. import org.springframework.stereotype.Service;
  41. import org.xml.sax.SAXException;
  42. import java.io.IOException;
  43. import java.io.InputStream;
  44. import java.io.InputStreamReader;
  45. import java.util.ArrayList;
  46. import java.util.Arrays;
  47. import java.util.List;
  48. import java.util.concurrent.ExecutionException;
  49. import java.util.concurrent.Future;
  50. import java.util.stream.Collectors;
  51. @Service
  52. @EnableAsync
  53. public class FileService {
  54. @Autowired private GridFsTemplate gridFsTemplate;
  55. @Autowired private MongoTemplate mongoTemplate;
  56. @Autowired private GridFsOperations fsOperations;
  57. @Autowired @Lazy private FileService fileService;
  58. public FileService() {}
  59. public Mapped storeUploaded(
  60. InputStream inputStream, String filename, String contentType, String modelId) {
  61. ObjectId objectId;
  62. objectId = this.gridFsTemplate.store(inputStream, filename, contentType);
  63. LogicalFile logicalFile = new LogicalFile();
  64. logicalFile.setFilename(filename);
  65. logicalFile.setUploadDate(DateUtil.now());
  66. logicalFile.setModelId(modelId);
  67. logicalFile.setGridId(objectId);
  68. logicalFile.setGenerated(Boolean.FALSE);
  69. logicalFile.setStatus("LOADING");
  70. logicalFile = this.mongoTemplate.insert(logicalFile);
  71. this.readFile(logicalFile);
  72. return Mapped.OK();
  73. }
  74. @Async
  75. public void readFile(LogicalFile uploaded) {
  76. GridFSFile fsFile =
  77. this.fsOperations.findOne(new Query(Criteria.where("_id").is(uploaded.getGridId())));
  78. if (fsFile == null) {
  79. this.modifyStatus(uploaded.getId(), "ERROR");
  80. } else {
  81. GridFsResource resource = this.fsOperations.getResource(fsFile);
  82. String filename = resource.getFilename();
  83. if (StringUtils.isBlank(filename)) {
  84. this.modifyStatus(uploaded.getId(), "ERROR");
  85. } else {
  86. try {
  87. InputStream inputStream = resource.getInputStream();
  88. MongoExcelService mongoExcelService;
  89. if (filename.endsWith(".xlsx")) {
  90. mongoExcelService = new MongoExcelService(this.mongoTemplate, uploaded.getId());
  91. ExcelXlsxReader reader = new ExcelXlsxReader(mongoExcelService);
  92. reader.processStream(inputStream);
  93. mongoExcelService.insertRest();
  94. } else if (filename.endsWith(".xls")) {
  95. mongoExcelService = new MongoExcelService(this.mongoTemplate, uploaded.getId());
  96. ExcelXlsReader reader = new ExcelXlsReader(mongoExcelService);
  97. reader.processStream(inputStream);
  98. mongoExcelService.insertRest();
  99. } else if (filename.endsWith(".csv")) {
  100. mongoExcelService = new MongoExcelService(this.mongoTemplate, uploaded.getId());
  101. CSVParser csvParser = CSVFormat.EXCEL.parse(new InputStreamReader(inputStream, "gbk"));
  102. int curRow = 0;
  103. int curRowWxFile = 0;
  104. boolean wxFile = false;
  105. String nickname = ""; // 微信手机账单文件 添加一列 微信昵称 需要单独处理
  106. for (CSVRecord record : csvParser) {
  107. List<String> strings = record.toList();
  108. /************* 此处内容一下均为处理微信账单表头 ****************/
  109. if (strings.size() == 1 && strings.get(0).equals("微信支付账单明细")) {
  110. wxFile = true;
  111. }
  112. if (wxFile && curRowWxFile < 16) {
  113. if (curRowWxFile == 1) {
  114. String temp = strings.get(0);
  115. if (StringUtils.isNotBlank(temp)) {
  116. nickname = temp.replace("微信昵称:[", "").replace("]", "");
  117. }
  118. }
  119. curRowWxFile++;
  120. continue;
  121. }
  122. if (wxFile && curRowWxFile == 16) {
  123. strings.add(0, "微信昵称");
  124. curRowWxFile++;
  125. }
  126. if (wxFile && curRowWxFile > 16) {
  127. strings.add(0, nickname);
  128. curRowWxFile++;
  129. }
  130. /************* 此处内容以上均为处理微信账单表头 ****************/
  131. mongoExcelService.getRows(
  132. 0,
  133. curRow,
  134. strings.stream()
  135. .map(PublicStatic::removeAllSpecial)
  136. .collect(Collectors.toList()));
  137. curRow++;
  138. }
  139. mongoExcelService.insertRest();
  140. } else if (filename.endsWith(".txt")) {
  141. mongoExcelService = new MongoExcelService(this.mongoTemplate, uploaded.getId());
  142. List<String> lines = new ArrayList<>();
  143. IoUtil.readLines(new InputStreamReader(inputStream, "utf-8"), lines);
  144. int curRow = 0;
  145. for (String string : lines) {
  146. if (string.equals("注销信息")) {
  147. break;
  148. }
  149. List<String> values = Arrays.asList(string.split("\t"));
  150. if (values.size() <= 1) {
  151. continue;
  152. }
  153. mongoExcelService.getRows(
  154. 0,
  155. curRow,
  156. values.stream().map(PublicStatic::removeAllSpecial).collect(Collectors.toList()));
  157. curRow++;
  158. }
  159. mongoExcelService.insertRest();
  160. }
  161. } catch (OpenXML4JException | SAXException | IOException var11) {
  162. this.modifyStatus(uploaded.getId(), "ERROR");
  163. var11.printStackTrace();
  164. }
  165. this.modifyStatus(uploaded.getId(), "FINISHED");
  166. }
  167. }
  168. }
  169. private void modifyStatus(String id, String status) {
  170. Query query = new Query();
  171. query.addCriteria(Criteria.where("_id").is(id));
  172. Update update = new Update();
  173. update.set("status", status);
  174. this.mongoTemplate.updateFirst(query, update, "logical_file");
  175. }
  176. public Mapped listGroupUploaded(FileListInput fileListInput) {
  177. String modelId = fileListInput.getModelId();
  178. if (modelId == null) {
  179. return Mapped.ERROR("没有选择任何分组");
  180. } else {
  181. Query query =
  182. new Query(Criteria.where("modelId").is(modelId).and("generated").is(Boolean.TRUE));
  183. query.with(Sort.by(Order.desc("uploadDate")));
  184. List<LogicalFile> resultList = this.mongoTemplate.find(query, LogicalFile.class);
  185. // 将文件 按照 反诈 财付通 五联单 进行分类
  186. List<GroupLogincalFile> groupLogincalFiles = new ArrayList<>();
  187. groupLogicalFile("反诈治安数据分析", new String[] {"反诈", "治安"}, resultList, groupLogincalFiles);
  188. groupLogicalFile("支付宝数据分析", new String[] {"五联单"}, resultList, groupLogincalFiles);
  189. groupLogicalFile("财付通数据分析", new String[] {"财付通"}, resultList, groupLogincalFiles);
  190. Mapped res = Mapped.OK();
  191. res.put("code", 200);
  192. res.put("result", groupLogincalFiles);
  193. return res;
  194. }
  195. }
  196. public void groupLogicalFile(
  197. String groupName,
  198. String[] group,
  199. List<LogicalFile> logicalFileList,
  200. List<GroupLogincalFile> groupLogincalFiles) {
  201. List<LogicalFile> children = new ArrayList<>();
  202. for (String s : group) {
  203. children.addAll(
  204. logicalFileList.stream()
  205. .filter(t -> t.getFilename().startsWith(s))
  206. .collect(Collectors.toList()));
  207. }
  208. if (children != null && children.size() > 0) {
  209. GroupLogincalFile groupLogincalFile = new GroupLogincalFile();
  210. groupLogincalFile.setGroupName(groupName);
  211. groupLogincalFile.setId(IdUtil.randomUUID());
  212. groupLogincalFile.setChildren(orderGroupLogicalFile(groupName, children));
  213. groupLogincalFiles.add(groupLogincalFile);
  214. }
  215. }
  216. String[] order1 = {"反诈数据-订单明细", "治安数据-订单明细", "反诈治安-交易明细", "反诈治安-账户透视", "反诈治安-对手透视"};
  217. String[] order2 = {
  218. "五联单-注册信息",
  219. "五联单-登录日志",
  220. "五联单-交易记录",
  221. "五联单-账户明细",
  222. "五联单-转账明细",
  223. "五联单-转账分析",
  224. "五联单-账户透视",
  225. "五联单-对手透视",
  226. "五联单-IP地址分析",
  227. "五联单-收货地址分析"
  228. };
  229. String[] order3 = {"财付通-开户信息", "财付通-订单明细", "财付通-交易明细", "财付通-账户透视", "财付通-对手透视", "财付通-手机明细"};
  230. public List<LogicalFile> orderGroupLogicalFile(String groupName, List<LogicalFile> list) {
  231. if (groupName.equals("反诈治安数据分析")) {
  232. return orderGroupLogicalFileChild(order1, list);
  233. }
  234. if (groupName.equals("支付宝数据分析")) {
  235. return orderGroupLogicalFileChild(order2, list);
  236. }
  237. if (groupName.equals("财付通数据分析")) {
  238. return orderGroupLogicalFileChild(order3, list);
  239. }
  240. return null;
  241. }
  242. public List<LogicalFile> orderGroupLogicalFileChild(String[] orders, List<LogicalFile> list) {
  243. List<LogicalFile> child = new ArrayList<>();
  244. for (String s : orders) {
  245. for (LogicalFile logicalFile : list) {
  246. if (logicalFile.getFilename().equals(s)) {
  247. child.add(logicalFile);
  248. break;
  249. }
  250. }
  251. }
  252. return child;
  253. }
  254. public Mapped listUploaded(FileListInput fileListInput) {
  255. String modelId = fileListInput.getModelId();
  256. if (modelId == null) {
  257. return Mapped.ERROR("没有选择任何分组");
  258. } else {
  259. String generated = fileListInput.getGenerated();
  260. Future<Long> longFuture = this.fileService.countTotalByModelId(modelId, generated);
  261. Future<String> modelNameFuture = this.fileService.retrieveModelname(modelId);
  262. int page = fileListInput.getPage();
  263. int pageSize = fileListInput.getPageSize();
  264. int skip = (page - 1) * pageSize;
  265. Criteria criteria = Criteria.where("modelId").is(modelId);
  266. if ("true".equals(generated)) {
  267. criteria.and("generated").is(Boolean.TRUE);
  268. } else if ("false".equals(generated)) {
  269. criteria.and("generated").is(Boolean.FALSE);
  270. }
  271. Query query = new Query(criteria);
  272. query.with(Sort.by(Order.desc("uploadDate")));
  273. List<LogicalFile> resultList =
  274. this.mongoTemplate.find(query.skip(skip).limit(pageSize), LogicalFile.class);
  275. Long total;
  276. try {
  277. total = longFuture.get();
  278. } catch (ExecutionException | InterruptedException var17) {
  279. return Mapped.ERROR("查询出错");
  280. }
  281. String modelName;
  282. try {
  283. modelName = modelNameFuture.get();
  284. } catch (ExecutionException | InterruptedException var17) {
  285. return Mapped.ERROR("查询出错");
  286. }
  287. int i = skip;
  288. for (LogicalFile file : resultList) {
  289. ++i;
  290. file.setCount(i);
  291. file.setModelName(modelName);
  292. }
  293. Mapped res = Mapped.OK();
  294. res.put("code", 200);
  295. res.put("result", resultList);
  296. res.put("total", total);
  297. res.put("page", page);
  298. res.put("pageSize", pageSize);
  299. return res;
  300. }
  301. }
  302. public Mapped deleteById(IdInput idInput) {
  303. String id = idInput.getId();
  304. Query query = new Query(Criteria.where("id").is(id));
  305. LogicalFile file = this.mongoTemplate.findOne(query, LogicalFile.class);
  306. if (file != null && file.getGridId() != null) {
  307. String physicalId = file.getGridId().toHexString();
  308. this.fileService.removePhysicalFile(physicalId);
  309. }
  310. this.fileService.removeDataByFileId(id);
  311. this.fileService.removeFieldsByFileId(id);
  312. DeleteResult result = this.mongoTemplate.remove(query, LogicalFile.class);
  313. return result.getDeletedCount() > 0L ? Mapped.OK() : Mapped.ERROR("删除失败");
  314. }
  315. @Async
  316. Future<Long> countTotalByModelId(String modelId, String generated) {
  317. Criteria criteria = Criteria.where("modelId").is(modelId);
  318. if ("true".equals(generated)) {
  319. criteria.and("generated").is(Boolean.TRUE);
  320. } else if ("false".equals(generated)) {
  321. criteria.and("generated").is(Boolean.FALSE);
  322. }
  323. Long total = this.mongoTemplate.count(new Query(criteria), LogicalFile.class);
  324. return new AsyncResult(total);
  325. }
  326. @Async
  327. public void removePhysicalFile(String id) {
  328. this.fsOperations.delete(new Query(Criteria.where("_id").is(id)));
  329. }
  330. @Async
  331. public void removeLogicalFile(String fileId) {
  332. this.mongoTemplate.remove(new Query(Criteria.where("id").is(fileId)), LogicalFile.class);
  333. }
  334. @Async
  335. public void removeDataByFileId(String fileId) {
  336. this.mongoTemplate.remove(new Query(Criteria.where("fileId").is(fileId)), DataMap.class);
  337. }
  338. @Async
  339. public void removeFieldsByFileId(String fileId) {
  340. this.mongoTemplate.remove(new Query(Criteria.where("fileId").is(fileId)), Fields.class);
  341. }
  342. @Async
  343. Future<String> retrieveModelname(String modelId) {
  344. Query query = new Query(Criteria.where("id").is(modelId));
  345. query.fields().include("modelName");
  346. Model model = this.mongoTemplate.findOne(query, Model.class, "model");
  347. return new AsyncResult(model != null ? model.getModelName() : "");
  348. }
  349. }