AchievementServiceImpl.java 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. package com.ruoyi.system.service.impl;
  2. import cn.hutool.core.date.format.FastDateFormat;
  3. import cn.hutool.core.io.resource.ClassPathResource;
  4. import cn.hutool.json.JSONUtil;
  5. import com.alibaba.excel.EasyExcel;
  6. import com.alibaba.excel.ExcelWriter;
  7. import com.alibaba.excel.support.ExcelTypeEnum;
  8. import com.alibaba.excel.util.MapUtils;
  9. import com.alibaba.excel.write.metadata.WriteSheet;
  10. import com.alibaba.excel.write.metadata.fill.FillWrapper;
  11. import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
  12. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  13. import com.ruoyi.common.exception.base.BaseException;
  14. import com.ruoyi.system.domain.*;
  15. import com.ruoyi.system.dto.PrintExcelDTO;
  16. import com.ruoyi.system.dto.TaskResultSortDTO;
  17. import com.ruoyi.system.dto.WaterLevelDTO;
  18. import com.ruoyi.system.mapper.*;
  19. import com.ruoyi.system.paramet.AchievementQuery;
  20. import com.ruoyi.system.paramet.ScattperPlotQuery;
  21. import com.ruoyi.system.paramet.WaterLevelQuery;
  22. import com.ruoyi.system.service.AchievementService;
  23. import com.ruoyi.system.service.SiteService;
  24. import lombok.extern.slf4j.Slf4j;
  25. import org.springframework.beans.factory.annotation.Autowired;
  26. import org.springframework.stereotype.Service;
  27. import reactor.core.publisher.Flux;
  28. import javax.annotation.Resource;
  29. import javax.servlet.http.HttpServletResponse;
  30. import java.io.OutputStream;
  31. import java.math.BigDecimal;
  32. import java.math.RoundingMode;
  33. import java.net.URLEncoder;
  34. import java.nio.charset.StandardCharsets;
  35. import java.text.SimpleDateFormat;
  36. import java.util.*;
  37. /**
  38. * classname: 站点信息
  39. * description 服务实现类
  40. */
  41. @Service
  42. @Slf4j
  43. public class AchievementServiceImpl implements AchievementService {
  44. @Resource
  45. private TaskResultMapper taskResultMapper;
  46. @Resource
  47. private WaterLevelMapper waterLevelMapper;
  48. @Resource
  49. private SiteInfoMapper siteInfoMapper;
  50. @Resource
  51. private BerthingPointMapper berthingPointMapper;
  52. @Resource
  53. private SiteService siteService;
  54. @Autowired
  55. private BerthingPointConfigMapper berthingPointConfigMapper;
  56. @Override
  57. public Page<TaskResult> queryAchievement(AchievementQuery achievementQuery){
  58. if (achievementQuery.getPage() == null || achievementQuery.getSize() == null) {
  59. achievementQuery.setPage(1L);
  60. achievementQuery.setSize(10L);
  61. }
  62. return taskResultMapper.queryAllByLimit(achievementQuery ,new Page(achievementQuery.getPage(),achievementQuery.getSize()));
  63. }
  64. @Override
  65. public TaskResult queryAchievementByTaskid(String taskid){
  66. return taskResultMapper.queryByTaskid(taskid);
  67. }
  68. @Override
  69. public Page<WaterLevelDTO> getWaterLevelList(WaterLevelQuery waterLevelQuery){
  70. if (waterLevelQuery.getType() == null){
  71. waterLevelQuery.setType(1L);
  72. }
  73. if (waterLevelQuery.getPage() == null || waterLevelQuery.getSize() == null) {
  74. waterLevelQuery.setPage(1L);
  75. waterLevelQuery.setSize(10L);
  76. }
  77. return waterLevelMapper.queryAllByTime(waterLevelQuery,new Page(waterLevelQuery.getPage(),waterLevelQuery.getSize()));
  78. }
  79. @Override
  80. public boolean downAchievement(Long resultId, HttpServletResponse response) {
  81. ExcelWriter excelWriter = null;
  82. try {
  83. //查询resultId结果
  84. TaskResult taskResult = taskResultMapper.queryById(resultId);
  85. if (taskResult == null){
  86. throw new BaseException("该结果不存在");
  87. }
  88. if (taskResult.getStatus() != 2){
  89. throw new BaseException("结果未完成,不支持导出");
  90. }
  91. //查询站点信息
  92. SiteInfo siteInfo = siteInfoMapper.queryById(taskResult.getSiteId());
  93. if (siteInfo == null){
  94. throw new BaseException("该站点不存在");
  95. }
  96. //查站点详情
  97. SiteConfig siteConfig = siteService.queryConfig(siteInfo.getSiteId());
  98. if (siteConfig == null){
  99. throw new BaseException("该站点配置不存在");
  100. }
  101. //拿断面数据
  102. BerthingPoint berthingPoint = berthingPointMapper.queryById(taskResult.getBerthingId());
  103. if (berthingPoint == null){
  104. throw new BaseException("断面不存在");
  105. }
  106. //拿停泊点数据
  107. BerthingPointConfig berthingPointConfig = berthingPointConfigMapper.queryById(taskResult.getStopId());
  108. if (berthingPointConfig == null){
  109. throw new BaseException("停泊点配置不存在");
  110. }
  111. OutputStream outputStream = response.getOutputStream();
  112. // 模版文件
  113. ClassPathResource classPathResource = new ClassPathResource("excel/test.xlsx");
  114. String templateFileName = classPathResource.getFile().getPath();
  115. excelWriter = EasyExcel.write(outputStream).withTemplate(templateFileName).excelType(ExcelTypeEnum.XLSX).autoCloseStream(Boolean.FALSE).build();
  116. WriteSheet writeSheet = EasyExcel.writerSheet().build();
  117. //先组装单数据
  118. Map<String, Object> map = MapUtils.newHashMap();
  119. map.put("stieName", siteInfo.getSiteName());
  120. map.put("startTime", taskResult.getStarttime());
  121. map.put("endTime", taskResult.getEndtime());
  122. map.put("flowsum", taskResult.getFlowsum());
  123. map.put("width", taskResult.getWidth());
  124. map.put("waterlevel",taskResult.getWaterlevel());
  125. map.put("acreagesum",taskResult.getAcreagesum());
  126. List<Double> WspeedsList = JSONUtil.parseArray(taskResult.getWspeeds()).toList(Double.class);
  127. double averageWspeed = WspeedsList.stream().mapToDouble(d -> d).average().orElse(Double.NaN);
  128. BigDecimal averageWspeedBigDecimal = new BigDecimal(averageWspeed).setScale(2, BigDecimal.ROUND_HALF_UP);
  129. Double maxWspeed = WspeedsList.stream().max(Double::compareTo).orElse(Double.NaN);
  130. List<Double> waterlevelList = JSONUtil.parseArray(taskResult.getWaterlevels()).toList(Double.class);
  131. double averageWaterlevel = waterlevelList.stream().mapToDouble(d -> d).average().orElse(Double.NaN);
  132. BigDecimal averageWaterlevelBigDecimal = new BigDecimal(averageWaterlevel).setScale(2, BigDecimal.ROUND_HALF_UP);
  133. Double maxWaterlevel = waterlevelList.stream().max(Double::compareTo).orElse(Double.NaN);
  134. map.put("agWaterlevels",averageWaterlevelBigDecimal.toString());
  135. map.put("maxWaterlevels",String.valueOf(maxWaterlevel));
  136. map.put("agWspeeds",averageWspeedBigDecimal.toString());
  137. map.put("maxWspeeds",String.valueOf(maxWspeed));
  138. excelWriter.fill(map, writeSheet);
  139. //拿断面数据
  140. List<PrintExcelDTO> positionsList = JSONUtil.toList(berthingPoint.getPositions(), PrintExcelDTO.class);
  141. //组装列表
  142. List<Map<String, Object>> dataList = new ArrayList<>();
  143. List<Map<String, Object>> pgList = new ArrayList<>();
  144. List<Double> taskX = JSONUtil.toList(taskResult.getPositions(), Double.class);
  145. List<Double> taskY = JSONUtil.toList(taskResult.getElevations(), Double.class);
  146. List<String> pointConfigfactors = JSONUtil.toList(berthingPointConfig.getFactors(), String.class);
  147. List<String> taskWspeeds = JSONUtil.toList(taskResult.getWspeeds(), String.class);
  148. List<String> taskStopwspeeds = JSONUtil.toList(taskResult.getStopwspeeds(), String.class);
  149. List<String> tasKPartwspeeds = JSONUtil.toList(taskResult.getPartwspeeds(), String.class);
  150. List<String> acreages = JSONUtil.toList(taskResult.getAcreages(), String.class);
  151. List<String> taskFlows = JSONUtil.toList(taskResult.getFlows(), String.class);
  152. int pnIndex = 0;
  153. for (int i = 0; i < positionsList.size(); i++) {
  154. Map<String, Object> data = MapUtils.newHashMap();
  155. if (i == 0) {
  156. String str = siteConfig.getLocal() == 0 ? "左水边" : "右水边";
  157. data.put("index", str);
  158. } else if (i == positionsList.size() - 1) {
  159. String str = siteConfig.getLocal() == 1 ? "左水边" : "右水边";
  160. data.put("index", str);
  161. } else {
  162. data.put("index", String.valueOf(i));
  163. }
  164. data.put("x", positionsList.get(i).getX().toString());
  165. data.put("y", positionsList.get(i).getY().toString());
  166. data.put("waterlevel",taskResult.getWaterlevel());
  167. data.put("subWlevel",BigDecimal.valueOf(taskResult.getWaterlevel()).subtract(BigDecimal.valueOf(positionsList.get(i).getY())));
  168. if (pnIndex < taskX.size()) {
  169. if (taskX.get(pnIndex).equals(positionsList.get(i).getX()) && taskY.get(pnIndex).equals(positionsList.get(i).getY())) {
  170. data.put("speed", String.valueOf(pnIndex + 1));
  171. data.put("time", "12:00");
  172. data.put("factors", pointConfigfactors.get(pnIndex));
  173. data.put("wspeeds", taskWspeeds.get(pnIndex));
  174. data.put("stopwspeeds", taskStopwspeeds.get(pnIndex));
  175. pnIndex = pnIndex + 1;
  176. } else {
  177. data.put("speed", "");
  178. data.put("time", "");
  179. data.put("factors", "");
  180. data.put("wspeeds", "");
  181. data.put("stopwspeeds", "");
  182. }
  183. } else {
  184. data.put("speed", "");
  185. data.put("time", "");
  186. data.put("factors", "");
  187. data.put("wspeeds", "");
  188. data.put("stopwspeeds", "");
  189. }
  190. dataList.add(data);
  191. }
  192. pnIndex = 0;
  193. //新循环
  194. for (int i = 0; i < positionsList.size(); i++) {
  195. Map<String, Object> pgData = MapUtils.newHashMap();
  196. if (i < positionsList.size() - 1) {
  197. if (pnIndex < taskX.size()) {
  198. if (taskX.get(pnIndex).equals(positionsList.get(i).getX()) && taskY.get(pnIndex).equals(positionsList.get(i).getY())) {
  199. pgData.put("partwspeeds", tasKPartwspeeds.get(pnIndex));
  200. if (i < 2) {
  201. pgData.put("add", acreages.get(0));//部分
  202. } else {
  203. BigDecimal bd1 = new BigDecimal(acreages.get(i));
  204. BigDecimal bd2 = new BigDecimal(acreages.get(i - 1));
  205. BigDecimal add = bd1.add(bd2);
  206. pgData.put("add", add.toString());
  207. }
  208. pgData.put("flows", taskFlows.get(pnIndex));//部分流量
  209. pnIndex = pnIndex + 1;
  210. } else {
  211. pgData.put("partwspeeds","");
  212. pgData.put("add", "");
  213. pgData.put("flows", "");
  214. }
  215. }
  216. Map<String, Object> temp1 = dataList.get(i);
  217. Map<String, Object> temp2 = dataList.get(i + 1);
  218. // 将字符串转换为BigDecimal
  219. BigDecimal bd1 = new BigDecimal(temp1.get("subWlevel").toString());
  220. BigDecimal bd2 = new BigDecimal(temp2.get("subWlevel").toString());
  221. // 求和
  222. BigDecimal sum = bd1.add(bd2);
  223. // 求平均值
  224. BigDecimal average = sum.divide(new BigDecimal(2), 2, RoundingMode.HALF_UP);
  225. pgData.put("subWlevel", average.toString()); //平均水深
  226. bd1 = new BigDecimal(temp1.get("x").toString());
  227. bd2 = new BigDecimal(temp2.get("x").toString());
  228. BigDecimal subx = bd2.subtract(bd1);
  229. pgData.put("subx", subx.toString()); //间距
  230. pgData.put("acreages", acreages.get(i)); //垂线间
  231. pgList.add(pgData);
  232. }
  233. }
  234. dataList = insertEmptyDataOnEvenRows(dataList);
  235. pgList = insertEmptyDataOnEvenRows(pgList);
  236. excelWriter.fill(new FillWrapper("details", dataList), writeSheet);
  237. excelWriter.fill(new FillWrapper("pg", pgList), writeSheet);
  238. // 设置输出流格式以及文件名:
  239. response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
  240. response.setCharacterEncoding("utf-8");
  241. String fileName = URLEncoder.encode("质检任务", StandardCharsets.UTF_8).replaceAll("\\+", "%20");
  242. response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
  243. return true;
  244. } catch (Exception e) {
  245. log.error("下载失败", e);
  246. throw new BaseException(e.getMessage());
  247. } finally {
  248. if (excelWriter != null) {
  249. excelWriter.close();
  250. }
  251. }
  252. }
  253. @Override
  254. public List<TaskResultSortDTO> getScatterPlot(ScattperPlotQuery scattperPlotQuery){
  255. try {
  256. return taskResultMapper.queryByTimeQuery(scattperPlotQuery);
  257. } catch (Exception e){
  258. log.error("获取数据失败", e);
  259. throw new BaseException("获取数据失败");
  260. }
  261. }
  262. @Override
  263. public void downWaterLevel(Long siteId, Long type, String startTime, String endTime, HttpServletResponse response){
  264. WaterLevelQuery waterLevelQuery = new WaterLevelQuery();
  265. FastDateFormat fdf = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss");
  266. try {
  267. Date startTimedDate = fdf.parse(startTime);
  268. Date endTimedDate = fdf.parse(endTime);
  269. waterLevelQuery.setSiteId(siteId);
  270. waterLevelQuery.setStartTime(startTimedDate);
  271. waterLevelQuery.setEndTime(endTimedDate);
  272. waterLevelQuery.setType(type);
  273. List<WaterLevelDTO> waterLevelList = waterLevelMapper.queryAllByTime(waterLevelQuery, new Page(1, 1000000)).getRecords();
  274. if (!waterLevelList.isEmpty()) {
  275. response.setContentType("application/octet-stream; charset=utf-8");
  276. String today = new SimpleDateFormat("yyyyMMdd").format(new Date());
  277. String fileName = "downWaterLevel_".concat(today);
  278. response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
  279. ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).build();
  280. WriteSheet detailSheet = EasyExcel.writerSheet(0, "水位数据").head(WaterLevelDTO.class).build();
  281. excelWriter.write(waterLevelList, detailSheet);
  282. excelWriter.finish();
  283. }
  284. } catch (Exception e) {
  285. log.error("水位列表下载失败",e);
  286. }
  287. }
  288. @Override
  289. public void downScatterPlot(Long siteId, String startTime, String endTime, HttpServletResponse response){
  290. ScattperPlotQuery scattperPlotQuery = new ScattperPlotQuery();
  291. FastDateFormat fdf = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss");
  292. try {
  293. Date startTimedDate = fdf.parse(startTime);
  294. Date endTimedDate = fdf.parse(endTime);
  295. scattperPlotQuery.setSiteId(siteId);
  296. scattperPlotQuery.setStartTime(startTimedDate);
  297. scattperPlotQuery.setEndTime(endTimedDate);
  298. List<TaskResultSortDTO> taskResultList = taskResultMapper.queryByTimeQuery(scattperPlotQuery);
  299. if (!taskResultList.isEmpty()) {
  300. response.setContentType("application/octet-stream; charset=utf-8");
  301. String today = new SimpleDateFormat("yyyyMMdd").format(new Date());
  302. String fileName = "downScatterPlot_".concat(today);
  303. response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
  304. ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).build();
  305. WriteSheet detailSheet = EasyExcel.writerSheet(0, "测流结果").head(TaskResultSortDTO.class).build();
  306. excelWriter.write(taskResultList, detailSheet);
  307. excelWriter.finish();
  308. }
  309. } catch (Exception e) {
  310. log.error("测流结果下载失败",e);
  311. }
  312. }
  313. public static <T> List<T> insertEmptyDataOnEvenRows(List<T> list) {
  314. List<T> modifiedList = new ArrayList<>(list.size() * 2 - 1); // 预估新列表的大小
  315. for (int i = 0; i < list.size(); i++) {
  316. modifiedList.add(list.get(i)); // 添加原始元素
  317. if (i < list.size() - 1) { // 避免在最后一个元素后插入
  318. modifiedList.add(list.get(i)); // 在每个元素后插入空白数据
  319. }
  320. }
  321. return modifiedList;
  322. }
  323. }