FileService.java 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  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.FileUtil;
  8. import cn.hutool.core.io.IoUtil;
  9. import cn.hutool.core.util.IdUtil;
  10. import cn.hutool.poi.excel.ExcelReader;
  11. import cn.hutool.poi.excel.ExcelUtil;
  12. import com.mongodb.client.gridfs.model.GridFSFile;
  13. import com.mongodb.client.result.DeleteResult;
  14. import com.opencsv.CSVReader;
  15. import ieven.server.webapp.domain.IdInput;
  16. import ieven.server.webapp.domain.data.DataMap;
  17. import ieven.server.webapp.domain.data.Fields;
  18. import ieven.server.webapp.domain.model.Model;
  19. import ieven.server.webapp.domain.tenpay.TenpayHeaders;
  20. import ieven.server.webapp.infrastructure.wrapper.Mapped;
  21. import ieven.server.webapp.service.MongoExcelService;
  22. import ieven.server.webapp.util.EncodeDetector;
  23. import ieven.server.webapp.util.FileUtils;
  24. import ieven.server.webapp.util.excel.ExcelXlsReader;
  25. import ieven.server.webapp.util.excel.ExcelXlsxReader;
  26. import ieven.server.webapp.util.excel.PublicStatic;
  27. import info.monitorenter.cpdetector.io.*;
  28. import lombok.extern.slf4j.Slf4j;
  29. import org.apache.commons.csv.CSVFormat;
  30. import org.apache.commons.csv.CSVParser;
  31. import org.apache.commons.csv.CSVRecord;
  32. import org.apache.commons.lang3.StringUtils;
  33. import org.apache.poi.ss.usermodel.Sheet;
  34. import org.bson.types.ObjectId;
  35. import org.springframework.beans.factory.annotation.Autowired;
  36. import org.springframework.beans.factory.annotation.Value;
  37. import org.springframework.context.annotation.Lazy;
  38. import org.springframework.data.domain.Sort;
  39. import org.springframework.data.domain.Sort.Order;
  40. import org.springframework.data.mongodb.core.MongoTemplate;
  41. import org.springframework.data.mongodb.core.query.Criteria;
  42. import org.springframework.data.mongodb.core.query.Query;
  43. import org.springframework.data.mongodb.core.query.Update;
  44. import org.springframework.data.mongodb.gridfs.GridFsOperations;
  45. import org.springframework.data.mongodb.gridfs.GridFsResource;
  46. import org.springframework.data.mongodb.gridfs.GridFsTemplate;
  47. import org.springframework.scheduling.annotation.Async;
  48. import org.springframework.scheduling.annotation.AsyncResult;
  49. import org.springframework.scheduling.annotation.EnableAsync;
  50. import org.springframework.stereotype.Service;
  51. import org.springframework.web.multipart.MultipartFile;
  52. import java.io.*;
  53. import java.nio.charset.Charset;
  54. import java.util.ArrayList;
  55. import java.util.Arrays;
  56. import java.util.HashMap;
  57. import java.util.List;
  58. import java.util.concurrent.*;
  59. import java.util.regex.Pattern;
  60. import java.util.stream.Collectors;
  61. import static cn.hutool.core.util.ArrayUtil.contains;
  62. @Service
  63. @EnableAsync
  64. @Slf4j
  65. public class FileService {
  66. @Value("${spring.data.fileExportPath}")
  67. private String fileUploadPath;
  68. String[] order1 = {"反诈数据-订单明细", "反诈数据-订单明细2", "治安数据-订单明细", "经侦数据-订单明细", "网黑数据-订单明细", "反诈治安-交易明细", "反诈治安-账户透视", "反诈治安-对手透视"};
  69. String[] order2 = {
  70. "五联单-注册信息",
  71. "经侦云-注册信息",
  72. "五联单-登录日志",
  73. "五联单-交易记录",
  74. "五联单-账户明细",
  75. "经侦云-账户明细",
  76. "五联单-转账明细",
  77. "五联单-转账分析",
  78. "五联单-账户透视",
  79. "五联单-对手透视",
  80. "五联单-IP地址分析",
  81. "五联单-收货地址分析"
  82. };
  83. String[] order3 = {"财付通-注册信息", "财付通-订单明细1", "财付通-订单明细2", "财付通-商户注册信息","财付通-商户订单", "财付通-交易明细", "财付通-账户透视", "财付通-对手透视", "财付通-手机明细"};
  84. String[] order4 = {"数据分析-主体信息汇总", "数据分析-账户透视", "数据分析-对手透视", "数据分析-共同关系网络"};
  85. @Autowired
  86. private GridFsTemplate gridFsTemplate;
  87. @Autowired
  88. private MongoTemplate mongoTemplate;
  89. @Autowired
  90. private GridFsOperations fsOperations;
  91. @Autowired
  92. @Lazy
  93. private FileService fileService;
  94. public FileService() {
  95. }
  96. public static String getCharsetName(File file) throws IOException {
  97. String charsetName = "UTF-8";
  98. // 获取 CodepageDetectorProxy 实例
  99. CodepageDetectorProxy detector = CodepageDetectorProxy.getInstance();
  100. // 添加解析器,会使用到添加的后 2 个 ext 里的 jar 包
  101. detector.add(new ParsingDetector(false));
  102. detector.add(JChardetFacade.getInstance());
  103. detector.add(ASCIIDetector.getInstance());
  104. detector.add(UnicodeDetector.getInstance());
  105. Charset charset = detector.detectCodepage(file.toURI().toURL());
  106. if (charset != null) {
  107. charsetName = charset.name();
  108. }
  109. return charsetName;
  110. }
  111. public static void main(String[] args) throws IOException {
  112. File file =
  113. new File(
  114. "C:\\Users\\Administrator\\Desktop\\楼\\支付宝五联单数据格式\\20120303组织卖淫案_OR222713D2400411_注册信息_20210913100124.csv");
  115. String charsetName = getCharsetName(file);
  116. CSVParser csvParser =
  117. CSVFormat.EXCEL.parse(new InputStreamReader(new FileInputStream(file), charsetName));
  118. for (CSVRecord strings : csvParser) {
  119. System.out.println(strings);
  120. }
  121. file = new File("C:\\Users\\Administrator\\Desktop\\楼\\微信支付账单(2).csv");
  122. charsetName = getCharsetName(file);
  123. csvParser =
  124. CSVFormat.EXCEL.parse(new InputStreamReader(new FileInputStream(file), charsetName));
  125. for (CSVRecord strings : csvParser) {
  126. System.out.println(strings);
  127. }
  128. }
  129. public Mapped storeUploaded(
  130. InputStream inputStream, String encoding, String filename, String contentType, String modelId) {
  131. ObjectId objectId;
  132. objectId = this.gridFsTemplate.store(inputStream, filename, contentType);
  133. Query query =
  134. new Query(
  135. Criteria.where("modelId")
  136. .is(modelId)
  137. .and("filename")
  138. .is(filename));
  139. List<LogicalFile> existsFileList = this.mongoTemplate.find(query, LogicalFile.class);
  140. if (existsFileList != null && existsFileList.size() > 0) {
  141. return Mapped.OK();
  142. }
  143. LogicalFile logicalFile = new LogicalFile();
  144. logicalFile.setFilename(filename);
  145. logicalFile.setUploadDate(DateUtil.now());
  146. logicalFile.setModelId(modelId);
  147. logicalFile.setGridId(objectId);
  148. logicalFile.setGenerated(Boolean.FALSE);
  149. logicalFile.setStatus("LOADING");
  150. logicalFile = this.mongoTemplate.insert(logicalFile);
  151. this.readFile(logicalFile, encoding);
  152. return Mapped.OK();
  153. }
  154. @Async
  155. public void readFile(LogicalFile uploaded, String encoding) {
  156. GridFSFile fsFile =
  157. this.fsOperations.findOne(new Query(Criteria.where("_id").is(uploaded.getGridId())));
  158. if (fsFile == null) {
  159. this.modifyStatus(uploaded.getId(), "ERROR");
  160. } else {
  161. GridFsResource resource = this.fsOperations.getResource(fsFile);
  162. String filename = resource.getFilename();
  163. if (StringUtils.isBlank(filename)) {
  164. this.modifyStatus(uploaded.getId(), "ERROR");
  165. } else {
  166. try {
  167. InputStream inputStream = resource.getInputStream();
  168. MongoExcelService mongoExcelService;
  169. if (filename.endsWith(".xlsx")) {
  170. mongoExcelService = new MongoExcelService(this.mongoTemplate, uploaded.getId());
  171. ExcelXlsxReader reader = new ExcelXlsxReader(mongoExcelService);
  172. reader.processStream(inputStream);
  173. mongoExcelService.insertRest();
  174. } else if (filename.endsWith(".xls")) {
  175. mongoExcelService = new MongoExcelService(this.mongoTemplate, uploaded.getId());
  176. ExcelXlsReader reader = new ExcelXlsReader(mongoExcelService);
  177. reader.processStream(inputStream);
  178. mongoExcelService.insertRest();
  179. } else if (filename.endsWith(".csv")) {
  180. mongoExcelService = new MongoExcelService(this.mongoTemplate, uploaded.getId());
  181. log.info("encoding2:{}", encoding);
  182. /*CSVParser csvParser = null;
  183. if (encoding.equalsIgnoreCase("UTF-8")) {
  184. csvParser = CSVFormat.EXCEL.parse(new InputStreamReader(inputStream, "utf-8"));
  185. } else {
  186. csvParser = CSVFormat.EXCEL.parse(new InputStreamReader(inputStream));
  187. }*/
  188. int curRow = 0;
  189. int curRowWxFile = 0;
  190. boolean wxFile = false;
  191. String nickname = ""; // 微信手机账单文件 添加一列 微信昵称 需要单独处理
  192. try (CSVReader reader = new CSVReader(new InputStreamReader(inputStream))) {
  193. List<String[]> lines = reader.readAll();
  194. for (String[] line : lines) {
  195. log.info("record,{}", line);
  196. List<String> strings = Arrays.asList(line);
  197. List<String> strings2 = new ArrayList<>();
  198. strings2.addAll(strings);
  199. /************* 此处内容一下均为处理微信账单表头 ****************/
  200. String join = String.join("", strings);
  201. join = PublicStatic.removeAllSpecial(join);
  202. if (join.equals("微信支付账单明细")) {
  203. wxFile = true;
  204. }
  205. if (wxFile && curRowWxFile < 16) {
  206. if (curRowWxFile == 1) {
  207. String temp = strings.get(0);
  208. if (StringUtils.isNotBlank(temp)) {
  209. nickname = temp.replace("微信昵称:[", "").replace("]", "");
  210. }
  211. }
  212. curRowWxFile++;
  213. continue;
  214. }
  215. if (wxFile && curRowWxFile > 16) {
  216. strings2.add(0, nickname);
  217. curRowWxFile++;
  218. }
  219. if (wxFile && curRowWxFile == 16) {
  220. strings2.add(0, "微信昵称");
  221. curRowWxFile++;
  222. }
  223. /************* 此处内容以上均为处理微信账单表头 ****************/
  224. mongoExcelService.getRows(
  225. 0,
  226. curRow,
  227. strings2.stream()
  228. .map(PublicStatic::removeAllSpecial)
  229. .collect(Collectors.toList())
  230. );
  231. curRow++;
  232. }
  233. } catch (Exception e) {
  234. e.printStackTrace();
  235. }
  236. mongoExcelService.insertRest();
  237. } else if (filename.endsWith(".txt")) {
  238. mongoExcelService = new MongoExcelService(this.mongoTemplate, uploaded.getId());
  239. List<String> lines = new ArrayList<>();
  240. IoUtil.readLines(new InputStreamReader(inputStream, "utf-8"), lines);
  241. int curRow = 0;
  242. boolean processNext = false;
  243. boolean lineAccount = false;
  244. for (String line : lines) {
  245. if (line.equals("注销信息")) {
  246. continue;
  247. }
  248. if (processNext) {
  249. List<String> values = Arrays.asList(line.split("\t"));
  250. if (values.size() > 1) {
  251. mongoExcelService.getRows(
  252. 0,
  253. curRow,
  254. values.stream().map(PublicStatic::removeAllSpecial).collect(Collectors.toList())
  255. );
  256. curRow++;
  257. }
  258. break;
  259. }
  260. /*
  261. * // 定义需要检查的字段
  262. String[] requiredFields = {"账户状态", "账号", "注册姓名", "注册时间", "注册身份证号"};
  263. // 将行拆分为字段数组
  264. String[] fields = line.split("\t");
  265. // 检查每个必要字段是否存在
  266. for (String field : requiredFields) {
  267. if (contains(fields, field) && !lineAccount) {
  268. lineAccount = true;
  269. }
  270. }
  271. * */
  272. if (line.contains("账户状态\t账号\t注册姓名\t注册时间\t注册身份证号\t绑定手机\t绑定状态")) {
  273. // 先存储表头行
  274. mongoExcelService.getRows(
  275. 0,
  276. curRow,
  277. Arrays.stream(line.split("\t"))
  278. .map(PublicStatic::removeAllSpecial)
  279. .collect(Collectors.toList())
  280. );
  281. curRow++;
  282. processNext = true;
  283. }
  284. }
  285. int isMerchant = 0; // 商户注册信息
  286. HashMap<String, String> merchantMap = new HashMap<>();
  287. List<String> headers = TenpayHeaders.getHeaders(11);
  288. for (String line : lines) {
  289. try {
  290. for (String header : headers) {
  291. if (line.contains(header)) {
  292. // Split each line into left and right parts
  293. String[] merchantLine = line.split(":");
  294. String key = merchantLine[0].trim();
  295. String value = merchantLine.length < 2 ? "" : merchantLine[1].trim();
  296. merchantMap.put(key, value);
  297. isMerchant++;
  298. }
  299. }
  300. } catch (ArrayIndexOutOfBoundsException e) {
  301. System.out.println("错误: 行解析失败,行内容可能不正确。");
  302. System.out.println("错误信息: " + e.getMessage());
  303. e.printStackTrace();
  304. } catch (NullPointerException e) {
  305. System.out.println("错误: 空指针异常,可能是headers或line为空。");
  306. System.out.println("错误信息: " + e.getMessage());
  307. e.printStackTrace();
  308. }
  309. }
  310. System.out.println(merchantMap);
  311. /*财付通-商户注册信息 */
  312. if(merchantMap.size() > 8) {
  313. String bankNo = merchantMap.get("绑定银行卡号");
  314. /*
  315. * "商户账号", "商户名", "注册时间", "证件号", "邮箱", "绑定手机", "银行账户名", "绑定银行", "绑定银行卡号", "商户地址"
  316. * */
  317. String[] bankNoArray = bankNo.split(",");
  318. mongoExcelService.getRows(
  319. 0,
  320. 0,
  321. headers
  322. );
  323. for (String no : bankNoArray) {
  324. // 创建每行的数据,包含所有字段,其中bankNo为当前值
  325. List<String> row = new ArrayList<>();
  326. row.add(merchantMap.get("商户账号"));
  327. row.add(merchantMap.get("商户名"));
  328. row.add(merchantMap.get("注册时间"));
  329. row.add(merchantMap.get("证件号"));
  330. row.add(merchantMap.get("邮箱"));
  331. row.add(merchantMap.get("绑定手机"));
  332. row.add(merchantMap.get("银行账户名"));
  333. row.add(merchantMap.get("绑定银行"));
  334. row.add(no);
  335. row.add(merchantMap.get("商户地址"));
  336. // 假设bankNo是第三个字段
  337. // 添加其他字段...
  338. mongoExcelService.getRows(
  339. 0,
  340. 1,
  341. row
  342. );
  343. }
  344. }
  345. mongoExcelService.insertRest();
  346. }
  347. } catch (Exception var11) {
  348. this.modifyStatus(uploaded.getId(), "ERROR");
  349. var11.printStackTrace();
  350. }
  351. this.modifyStatus(uploaded.getId(), "FINISHED");
  352. }
  353. }
  354. }
  355. private void modifyStatus(String id, String status) {
  356. Query query = new Query();
  357. query.addCriteria(Criteria.where("_id").is(id));
  358. Update update = new Update();
  359. update.set("status", status);
  360. this.mongoTemplate.updateFirst(query, update, "logical_file");
  361. }
  362. public Mapped listGroupUploaded(FileListInput fileListInput) {
  363. String modelId = fileListInput.getModelId();
  364. if (modelId == null) {
  365. return Mapped.ERROR("没有选择任何分组");
  366. } else {
  367. Query query =
  368. new Query(Criteria.where("modelId").is(modelId).and("generated").is(Boolean.TRUE));
  369. query.with(Sort.by(Order.desc("uploadDate")));
  370. List<LogicalFile> resultList = this.mongoTemplate.find(query, LogicalFile.class);
  371. // 将文件 按照 反诈 财付通 五联单 进行分类
  372. List<GroupLogincalFile> groupLogincalFiles = new ArrayList<>();
  373. groupLogicalFile("反诈治安数据分析", new String[]{"反诈", "治安", "经侦数据", "网黑"}, resultList, groupLogincalFiles);
  374. groupLogicalFile("支付宝数据分析", new String[]{"五联单", "经侦云"}, resultList, groupLogincalFiles);
  375. groupLogicalFile("财付通数据分析", new String[]{"财付通"}, resultList, groupLogincalFiles);
  376. groupLogicalFile("数据综合分析", new String[]{"数据分析"}, resultList, groupLogincalFiles);
  377. Mapped res = Mapped.OK();
  378. res.put("code", 200);
  379. res.put("result", groupLogincalFiles);
  380. return res;
  381. }
  382. }
  383. public void groupLogicalFile(
  384. String groupName,
  385. String[] group,
  386. List<LogicalFile> logicalFileList,
  387. List<GroupLogincalFile> groupLogincalFiles) {
  388. List<LogicalFile> children = new ArrayList<>();
  389. for (String s : group) {
  390. children.addAll(
  391. logicalFileList.stream()
  392. .filter(t -> t.getFilename().startsWith(s))
  393. .collect(Collectors.toList()));
  394. }
  395. if (children != null && children.size() > 0) {
  396. GroupLogincalFile groupLogincalFile = new GroupLogincalFile();
  397. groupLogincalFile.setGroupName(groupName);
  398. groupLogincalFile.setId(IdUtil.randomUUID());
  399. groupLogincalFile.setChildren(orderGroupLogicalFile(groupName, children));
  400. groupLogincalFiles.add(groupLogincalFile);
  401. }
  402. }
  403. public List<LogicalFile> orderGroupLogicalFile(String groupName, List<LogicalFile> list) {
  404. if (groupName.equals("反诈治安数据分析")) {
  405. return orderGroupLogicalFileChild(order1, list);
  406. }
  407. if (groupName.equals("支付宝数据分析")) {
  408. return orderGroupLogicalFileChild(order2, list);
  409. }
  410. if (groupName.equals("财付通数据分析")) {
  411. return orderGroupLogicalFileChild(order3, list);
  412. }
  413. if (groupName.equals("数据综合分析")) {
  414. return orderGroupLogicalFileChild(order4, list);
  415. }
  416. return null;
  417. }
  418. public List<LogicalFile> orderGroupLogicalFileChild(String[] orders, List<LogicalFile> list) {
  419. List<LogicalFile> child = new ArrayList<>();
  420. for (String s : orders) {
  421. for (LogicalFile logicalFile : list) {
  422. if (logicalFile.getFilename().equals(s)) {
  423. if ("数据分析-共同关系网络".equals(logicalFile.getFilename())) {
  424. logicalFile.setFileType("map");
  425. }
  426. child.add(logicalFile);
  427. break;
  428. }
  429. }
  430. }
  431. return child;
  432. }
  433. public Mapped listUploaded(FileListInput fileListInput) {
  434. String modelId = fileListInput.getModelId();
  435. if (modelId == null) {
  436. return Mapped.ERROR("没有选择任何分组");
  437. } else {
  438. String generated = fileListInput.getGenerated();
  439. String fileName = fileListInput.getFileName();
  440. Future<Long> longFuture = this.fileService.countTotalByModelId(modelId, generated);
  441. Future<String> modelNameFuture = this.fileService.retrieveModelname(modelId);
  442. int page = fileListInput.getPage();
  443. int pageSize = fileListInput.getPageSize();
  444. int skip = (page - 1) * pageSize;
  445. Criteria criteria = Criteria.where("modelId").is(modelId);
  446. if ("true".equals(generated)) {
  447. criteria.and("generated").is(Boolean.TRUE);
  448. } else if ("false".equals(generated)) {
  449. criteria.and("generated").is(Boolean.FALSE);
  450. }
  451. if (fileName != null && !fileName.isEmpty()) {
  452. // 使用正则表达式进行模糊匹配,i 表示不区分大小写
  453. Pattern pattern = Pattern.compile(".*" + Pattern.quote(fileName) + ".*", Pattern.CASE_INSENSITIVE);
  454. criteria.and("filename").regex(pattern);
  455. }
  456. // 创建查询对象并执行查询
  457. Query query = new Query(criteria)
  458. .with(Sort.by(Sort.Direction.DESC, "uploadDate")) // 保留排序逻辑
  459. .skip(skip)
  460. .limit(pageSize);
  461. List<LogicalFile> resultList =
  462. this.mongoTemplate.find(query, LogicalFile.class);
  463. Long total;
  464. try {
  465. total = longFuture.get();
  466. } catch (ExecutionException | InterruptedException var17) {
  467. return Mapped.ERROR("查询出错");
  468. }
  469. String modelName;
  470. try {
  471. modelName = modelNameFuture.get();
  472. } catch (ExecutionException | InterruptedException var17) {
  473. return Mapped.ERROR("查询出错");
  474. }
  475. int i = skip;
  476. for (LogicalFile file : resultList) {
  477. ++i;
  478. file.setCount(i);
  479. file.setModelName(modelName);
  480. }
  481. Mapped res = Mapped.OK();
  482. res.put("code", 200);
  483. res.put("result", resultList);
  484. res.put("total", total);
  485. res.put("page", page);
  486. res.put("pageSize", pageSize);
  487. return res;
  488. }
  489. }
  490. public Mapped deleteById(IdInput idInput) {
  491. String id = idInput.getId();
  492. Query query = new Query(Criteria.where("id").is(id));
  493. LogicalFile file = this.mongoTemplate.findOne(query, LogicalFile.class);
  494. if (file != null && file.getGridId() != null) {
  495. String physicalId = file.getGridId().toHexString();
  496. this.fileService.removePhysicalFile(physicalId);
  497. }
  498. this.fileService.removeDataByFileId(id);
  499. this.fileService.removeFieldsByFileId(id);
  500. DeleteResult result = this.mongoTemplate.remove(query, LogicalFile.class);
  501. return result.getDeletedCount() > 0L ? Mapped.OK() : Mapped.ERROR("删除失败");
  502. }
  503. @Async
  504. Future<Long> countTotalByModelId(String modelId, String generated) {
  505. Criteria criteria = Criteria.where("modelId").is(modelId);
  506. if ("true".equals(generated)) {
  507. criteria.and("generated").is(Boolean.TRUE);
  508. } else if ("false".equals(generated)) {
  509. criteria.and("generated").is(Boolean.FALSE);
  510. }
  511. Long total = this.mongoTemplate.count(new Query(criteria), LogicalFile.class);
  512. return new AsyncResult(total);
  513. }
  514. @Async
  515. public void removePhysicalFile(String id) {
  516. this.fsOperations.delete(new Query(Criteria.where("_id").is(id)));
  517. }
  518. @Async
  519. public void removeLogicalFile(String fileId) {
  520. this.mongoTemplate.remove(new Query(Criteria.where("id").is(fileId)), LogicalFile.class);
  521. }
  522. @Async
  523. public void removeDataByFileId(String fileId) {
  524. this.mongoTemplate.remove(new Query(Criteria.where("fileId").is(fileId)), DataMap.class);
  525. }
  526. @Async
  527. public void removeFieldsByFileId(String fileId) {
  528. this.mongoTemplate.remove(new Query(Criteria.where("fileId").is(fileId)), Fields.class);
  529. }
  530. @Async
  531. Future<String> retrieveModelname(String modelId) {
  532. Query query = new Query(Criteria.where("id").is(modelId));
  533. query.fields().include("modelName");
  534. Model model = this.mongoTemplate.findOne(query, Model.class, "model");
  535. return new AsyncResult(model != null ? model.getModelName() : "");
  536. }
  537. public Mapped uploadFilesAndSave(List<MultipartFile> multipartFiles, String modelId) {
  538. List<String> failNameList = new ArrayList<>();
  539. for (int i = 0; i < multipartFiles.size(); i++) {
  540. MultipartFile multipartFile = multipartFiles.get(i);
  541. String originName = multipartFile.getOriginalFilename();
  542. String suffix = originName.substring(originName.lastIndexOf(".") + 1);
  543. String prefix = originName.substring(0, originName.lastIndexOf("."));
  544. String savedName = prefix + "(" + (i + 1) + ")." + suffix;
  545. String filepath = fileUploadPath + File.separator + modelId + File.separator + savedName;
  546. FileUtils.uploadFile(multipartFile, filepath);
  547. MultipartFile multipartFile1 = FileUtils.getMultipartFile(new File(filepath));
  548. try {
  549. ExecutorService executor = Executors.newSingleThreadExecutor();
  550. Future<Mapped> future = executor.submit(new Callable<Mapped>() {
  551. @Override
  552. public Mapped call() throws Exception {
  553. return uploadSingle(multipartFile1, modelId);
  554. }
  555. });
  556. // 在这里,主线程会等待 future 的结果
  557. Mapped mapped = future.get(); // 这将会阻塞,直到Callable任务完成
  558. if (200 != Integer.valueOf(String.valueOf(mapped.get("code")))) {
  559. failNameList.add(savedName + ":" + String.valueOf(mapped.get("message")));
  560. }
  561. //删除文件
  562. FileUtils.deleteFile(filepath);
  563. } catch (Exception e) {
  564. e.printStackTrace();
  565. }
  566. }
  567. Mapped mapped = Mapped.OK();
  568. mapped.put("failNameList", failNameList);
  569. return mapped;
  570. }
  571. public Mapped uploadSingle(MultipartFile file, String modelId)
  572. throws Exception {
  573. String filename = file.getOriginalFilename();
  574. String extName = FileUtil.extName(filename);
  575. String contentType = file.getContentType();
  576. ByteArrayOutputStream baos = FileUtils.cloneInputStream(file.getInputStream());
  577. if (extName.equalsIgnoreCase("xls") || extName.equalsIgnoreCase("xlsx")) {
  578. ExcelReader reader = ExcelUtil.getReader(new ByteArrayInputStream(baos.toByteArray()));
  579. List<Sheet> sheets = reader.getSheets();
  580. List<String> headers = new ArrayList<>();
  581. for (Sheet sheet : sheets) {
  582. reader.setSheet(sheet);
  583. List<Object> objects = reader.readRow(0);
  584. if (objects.size() > 1) { // 至少大于1
  585. StringBuilder stringBuilder = new StringBuilder();
  586. for (Object object : objects) {
  587. stringBuilder.append(object);
  588. }
  589. headers.add(stringBuilder.toString());
  590. }
  591. }
  592. if (headers.size() > 1) {
  593. // 判断sheet第一行内容是否一致
  594. StringBuilder errorHeaders = new StringBuilder();
  595. String baseHeader = headers.get(0);
  596. for (int i = 0; i < headers.size(); i++) {
  597. //
  598. if (i == 0) {
  599. continue;
  600. }
  601. if (!headers.get(i).equals(baseHeader)) {
  602. errorHeaders.append("sheet").append(i).append("标题列与第一个sheet不一致!");
  603. }
  604. }
  605. if (errorHeaders.length() > 0) {
  606. return Mapped.ERROR(errorHeaders.toString());
  607. }
  608. }
  609. reader.close();
  610. }
  611. String encoding = EncodeDetector.getEncoding(baos.toByteArray());
  612. baos.close();
  613. return this.fileService.storeUploaded(
  614. new ByteArrayInputStream(baos.toByteArray()), encoding, filename, contentType, modelId);
  615. }
  616. }