AbstractReportService.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. package com.huaxu.service;
  2. import cn.hutool.core.collection.CollectionUtil;
  3. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  4. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  5. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  6. import com.huaxu.common.StringUtils;
  7. import com.huaxu.dto.*;
  8. import com.huaxu.entity.DayReportEntity;
  9. import com.huaxu.util.UserUtil;
  10. import org.springframework.beans.factory.annotation.Autowired;
  11. import java.math.BigDecimal;
  12. import java.math.RoundingMode;
  13. import java.util.*;
  14. import java.util.stream.Collectors;
  15. /**
  16. * 报表业务处理
  17. * @author lihui
  18. * @date 2020-3-26
  19. */
  20. public abstract class AbstractReportService<M extends BaseMapper<T>, T> extends ServiceImpl {
  21. @Autowired
  22. protected SceneService sceneService;
  23. @Autowired
  24. protected DeviceService deviceService;
  25. @Autowired
  26. protected DeviceParmService deviceParmService;
  27. /**
  28. * 报表数据处理
  29. * @param queryDto
  30. * @param devices
  31. * @param reportPage
  32. */
  33. public void reportDataHandle(ReportQueryDto queryDto, List<DeviceDto> devices, Page<ReportDto> reportPage, boolean isPipe){
  34. // 组装查询参数
  35. ReportDto reportDto = getQueryReportDto(queryDto, devices, isPipe);
  36. // 设置报表标题
  37. Map<String, Integer> mapsTitle = new LinkedHashMap<>();
  38. Map<String, ReportAttributeDto> mapsAttributeTitle = new LinkedHashMap<>();
  39. // 获取标题
  40. List<ReportTitleDto> reportTitleDtos = getReportTitle(reportDto, mapsTitle, mapsAttributeTitle);
  41. // 固定参数项
  42. List<ReportDto> reportList = findReport(reportDto);
  43. // 如果为空,把自定义表头返回回去
  44. if (CollectionUtil.isEmpty(reportPage.getRecords())){
  45. List<ReportDto> reportDtos = new ArrayList<>();
  46. ReportDto reportDto1 = new ReportDto();
  47. reportDto1.setReportTitle(reportTitleDtos);
  48. reportDtos.add(reportDto1);
  49. reportPage.setRecords(reportDtos);
  50. return;
  51. }
  52. int total = 0;
  53. // 单个属性值
  54. for (ReportDto item : reportPage.getRecords()) {
  55. item.setCollectDate(formateCollectDate(queryDto, item));
  56. item.setDeviceIds(devices);
  57. if (total == 0){
  58. item.setReportTitle(reportTitleDtos);
  59. }
  60. // 固定参数项
  61. calcUsage(item, reportList);
  62. Integer parentSceneId = item.getParentSceneId();
  63. item.setParentSceneId(null);
  64. //动态参数项
  65. List<ReportAttributeDto> reportAttributeDtos = this.findAttributeList(item);
  66. item.setParentSceneId(parentSceneId);
  67. Map<String, ReportAttributeDto> mapData = new LinkedHashMap<>();
  68. for (ReportAttributeDto itemData : reportAttributeDtos) {
  69. if (!mapData.containsKey(itemData.getDeviceParmId().toString())){
  70. mapData.put(itemData.getDeviceParmId().toString(), itemData);
  71. }
  72. }
  73. // 获取统计维度的值
  74. item.setDataMapValues(getStatisticalDimensionsValue(mapsTitle, mapData, mapsAttributeTitle));
  75. total ++;
  76. }
  77. }
  78. /**
  79. * 查询场景下的所有设备信息
  80. * @param ids 场景ID
  81. * @return
  82. */
  83. public List<DeviceDto> findDevices(Long[] ids){
  84. List<DeviceDto> devices = new ArrayList<>();
  85. DeviceDto deviceDto = new DeviceDto();
  86. for (Long id : ids) {
  87. deviceDto.setSceneIds(sceneService.findByParentIdsLike(id));
  88. if (deviceDto.getSceneIds().size() > 0){
  89. devices.addAll(deviceService.selectList(deviceDto));
  90. }
  91. }
  92. return devices;
  93. }
  94. /**
  95. * ids转换场景集合对象
  96. * @param ids 场景ID
  97. * @return
  98. */
  99. public List<DeviceDto> devicesToList(Long[] ids){
  100. List<DeviceDto> devices = new ArrayList<>();
  101. for (Long id : ids) {
  102. DeviceDto deviceDto = new DeviceDto();
  103. deviceDto.setId(id);
  104. devices.add(deviceDto);
  105. }
  106. return devices;
  107. }
  108. /**
  109. * 1000汇算
  110. * @param value
  111. * @return
  112. */
  113. public double doubleRoundValue(double value){
  114. return (double) Math.round(value * 1000) / 1000;
  115. }
  116. /**
  117. * @Author lihui
  118. * @Description 单位除以一万,保留3位小数
  119. * @Date 14:18 2021/4/28
  120. * @Param [value]
  121. * @return double
  122. **/
  123. public double doubleDivideValue(double value){
  124. return new BigDecimal(value).divide(BigDecimal.valueOf(10000), 3, RoundingMode.HALF_UP).doubleValue();
  125. }
  126. /**
  127. * 组装参数
  128. * @param queryDto
  129. * @param devices
  130. * @return
  131. */
  132. public ReportDto getQueryReportDto(ReportQueryDto queryDto, List<DeviceDto> devices, boolean isPipe){
  133. ReportDto reportDto = new ReportDto();
  134. reportDto.setYear(queryDto.getYear());
  135. reportDto.setMonth(queryDto.getMonth());
  136. reportDto.setDay(queryDto.getDay());
  137. if (isPipe){
  138. /*Integer[] parmType = null;
  139. if (queryDto.getType() == 1) {
  140. parmType = new Integer[]{13};
  141. } else if (queryDto.getType() == 2){
  142. parmType = new Integer[]{14};
  143. } else if (queryDto.getType() == 3){
  144. parmType = new Integer[]{7, 9, 11};
  145. }
  146. reportDto.setParmType(Arrays.asList(parmType));*/
  147. reportDto.setDeviceIds(devices);
  148. } else {
  149. reportDto.setDeviceIds(devices);
  150. reportDto.setParentSceneIds(queryDto.getIds());
  151. }
  152. reportDto.setUserId(UserUtil.getCurrentUser().getId());
  153. reportDto.setStartTime(queryDto.getStartTime());
  154. reportDto.setEndTime(queryDto.getEndTime());
  155. return reportDto;
  156. }
  157. //根据设备ID查询报表测点信息
  158. protected ReportPageQueryDto getReportPageQuery(ReportQueryDto queryDto, List<DeviceDto> devices, boolean isPipe){
  159. ReportPageQueryDto dto = new ReportPageQueryDto();
  160. dto.setYear(queryDto.getYear());
  161. dto.setMonth(queryDto.getMonth());
  162. dto.setDay(queryDto.getDay());
  163. dto.setTenantId(UserUtil.getCurrentUser().getTenantId());
  164. dto.setDeviceIds(devices);
  165. // 管网和其他有点不一样
  166. if (isPipe){
  167. /* Integer[] parmType = null;
  168. if (queryDto.getType() == 1) {
  169. parmType = new Integer[]{13};
  170. } else if (queryDto.getType() == 2){
  171. parmType = new Integer[]{14};
  172. } else if (queryDto.getType() == 3){
  173. parmType = new Integer[]{7, 9, 11};
  174. }
  175. dto.setTypeIds(Arrays.asList(parmType));*/
  176. dto.setType(queryDto.getType());
  177. } else {
  178. // 管网不需要场景
  179. dto.setParentSceneIds(queryDto.getIds());
  180. }
  181. dto.setStartTime(queryDto.getStartTime());
  182. dto.setEndTime(queryDto.getEndTime());
  183. return dto;
  184. }
  185. /**
  186. * 获取报表标题
  187. * @param reportDto
  188. * @param mapsTitle
  189. * @param mapsAttributeTitle
  190. * @return
  191. */
  192. public List<ReportTitleDto> getReportTitle(ReportDto reportDto, Map<String, Integer> mapsTitle,
  193. Map<String, ReportAttributeDto> mapsAttributeTitle){
  194. // 设置标题
  195. Map<String, ReportTitleDto> deviceChildrenMap = new HashMap<>();
  196. List<ReportAttributeDto> reportAttributeDtos2 = deviceParmService.findAttributeNameList(reportDto);
  197. int numCount = 0;
  198. for (ReportAttributeDto reportAttributeDto : reportAttributeDtos2) {
  199. // 判断开关是否开启
  200. if (reportAttributeDto.isShowOnOff()){
  201. setReportTitle(reportAttributeDto, deviceChildrenMap);
  202. mapsAttributeTitle.put(reportAttributeDto.getDeviceParmId().toString(),reportAttributeDto);
  203. }
  204. }
  205. // 转换list返回
  206. List<ReportTitleDto> resultList = deviceChildrenMap.values().stream().collect(Collectors.toList());
  207. for (ReportTitleDto reportTitleDto : resultList) {
  208. List<ReportTitleDto.DeviceChildren> childrenList = reportTitleDto.getDeviceChildren();
  209. for (ReportTitleDto.DeviceChildren children : childrenList) {
  210. mapsTitle.put(children.getParamId(), numCount++);
  211. }
  212. }
  213. return resultList;
  214. }
  215. /**
  216. * 获取统计维度的值
  217. * @param mapsTitle
  218. * @param mapData
  219. * @param mapsAttributeTitle
  220. * @return
  221. */
  222. public List<Map<String, Object>> getStatisticalDimensionsValue( Map<String, Integer> mapsTitle, Map<String, ReportAttributeDto> mapData,
  223. Map<String, ReportAttributeDto> mapsAttributeTitle){
  224. // 判断是否有需要展示的字段
  225. boolean haveShowTitle = false;
  226. List<Map<String, Object>> dataMapValues = new ArrayList<>();
  227. for (String key : mapsTitle.keySet()) {
  228. ReportAttributeDto reportAttributeDto = mapsAttributeTitle.get(key);
  229. // 过滤掉没有开启开关的
  230. if (reportAttributeDto == null || !reportAttributeDto.isShowOnOff()) {
  231. continue;
  232. }
  233. Map<String, Object> map = new LinkedHashMap<>();
  234. map.put("attributeName", mapData.get(key) == null ? key : mapData.get(key).getAttributeName());
  235. if (reportAttributeDto.isShowMaxValue()) {
  236. map.put("maxValue" + mapsTitle.get(key), mapData.get(key) == null || mapData.get(key).getMaxValue() == null ?
  237. "-" : doubleRoundValue(mapData.get(key).getMaxValue()));
  238. haveShowTitle = true;
  239. }
  240. if (reportAttributeDto.isShowMinValue()) {
  241. map.put("minValue" + mapsTitle.get(key), mapData.get(key) == null || mapData.get(key).getMinValue() == null ?
  242. "-" : doubleRoundValue(mapData.get(key).getMinValue()));
  243. haveShowTitle = true;
  244. }
  245. if (reportAttributeDto.isShowSumValue()) {
  246. map.put("sumValue" + mapsTitle.get(key), mapData.get(key) == null || mapData.get(key).getSumValue() == null ?
  247. "-" : doubleRoundValue(mapData.get(key).getSumValue()));
  248. haveShowTitle = true;
  249. }
  250. if (reportAttributeDto.isShowLatestValue()) {
  251. map.put("latestValue" + mapsTitle.get(key), mapData.get(key) == null || mapData.get(key).getLatestValue() == null ?
  252. "-" : doubleRoundValue(mapData.get(key).getLatestValue()));
  253. haveShowTitle = true;
  254. }
  255. if (reportAttributeDto.isShowAvgValue()) {
  256. map.put("avgValue" + mapsTitle.get(key), mapData.get(key) == null || mapData.get(key).getAvgValue() == null ?
  257. "-" : doubleRoundValue(mapData.get(key).getAvgValue()));
  258. haveShowTitle = true;
  259. }
  260. if (!haveShowTitle){
  261. continue;
  262. }
  263. haveShowTitle = false;
  264. dataMapValues.add(map);
  265. }
  266. return dataMapValues;
  267. }
  268. /**
  269. * 设置报表标题
  270. * @param v
  271. * @param deviceChildrenMap
  272. */
  273. private void setReportTitle(ReportAttributeDto v, Map<String, ReportTitleDto> deviceChildrenMap){
  274. String classify = StringUtils.isEmpty(v.getClassify()) ? v.getAttributeName() + v.getDeviceParmId() + "isNull" : v.getClassify();
  275. ReportTitleDto reportTitleDto = deviceChildrenMap.get(classify);
  276. if (reportTitleDto == null) {
  277. reportTitleDto = new ReportTitleDto();
  278. reportTitleDto.setClassify(classify);
  279. }
  280. List<ReportTitleDto.DeviceChildren> deviceChildrenList = reportTitleDto.getDeviceChildren();
  281. if (CollectionUtil.isEmpty(deviceChildrenList)){
  282. deviceChildrenList = new ArrayList<>();
  283. }
  284. String unit = StringUtils.isEmpty(v.getUnit()) ? "" : "("+v.getUnit()+")";
  285. ReportTitleDto.DeviceChildren deviceChildren = new ReportTitleDto.DeviceChildren();
  286. deviceChildren.setName(v.getAttributeName() + unit);
  287. deviceChildren.setParamId(v.getDeviceParmId().toString());
  288. // 检查是否有设置维度
  289. List<ReportTitleDto.StatisticalDimension> statisticalDimensions = new ArrayList<>();
  290. if (v.isShowMaxValue()){
  291. statisticalDimensions.add(getStatisticalDimension("showMaxValue", "最大值"));
  292. }
  293. if (v.isShowMinValue()){
  294. statisticalDimensions.add(getStatisticalDimension("showMinValue", "最小值"));
  295. }
  296. if (v.isShowSumValue()){
  297. statisticalDimensions.add(getStatisticalDimension("showSumValue", "合计值"));
  298. }
  299. if (v.isShowLatestValue()){
  300. statisticalDimensions.add(getStatisticalDimension("showLatestValue", "最新值"));
  301. }
  302. if (v.isShowAvgValue()){
  303. statisticalDimensions.add(getStatisticalDimension("showAvgValue", "平均值"));
  304. }
  305. // 有设置维度,添加相关信息
  306. if (v.isShowMaxValue() || v.isShowMinValue() || v.isShowSumValue() || v.isShowLatestValue()
  307. || v.isShowAvgValue()){
  308. deviceChildren.setDimensionList(statisticalDimensions);
  309. deviceChildrenList.add(deviceChildren);
  310. reportTitleDto.setDeviceChildren(deviceChildrenList);
  311. deviceChildrenMap.put(classify, reportTitleDto);
  312. }
  313. }
  314. /**
  315. * 获取统计维度
  316. * @param key
  317. * @param name
  318. * @return
  319. */
  320. private ReportTitleDto.StatisticalDimension getStatisticalDimension(String key, String name){
  321. ReportTitleDto.StatisticalDimension statisticalDimension = new ReportTitleDto.StatisticalDimension();
  322. statisticalDimension.setDimensionKey(key);
  323. statisticalDimension.setDimensionName(name);
  324. return statisticalDimension;
  325. }
  326. /**
  327. * @Author lihui
  328. * @Description 格式化日期
  329. * @Date 16:38 2021/4/15
  330. * @Param [queryDto, item]
  331. * @return java.lang.String
  332. **/
  333. private String formateCollectDate(ReportQueryDto queryDto, ReportDto item){
  334. // 0日 1月 2年
  335. if (queryDto.getReportType() == 0) {
  336. return item.getYear() + "-" + String.format("%02d", item.getMonth()) + "-" + String.format("%02d", item.getDay()) + " " + String.format("%02d", item.getHour()) + ":00:00";
  337. }
  338. if (queryDto.getReportType() == 1 || queryDto.getReportType() == 3) {
  339. return item.getYear() + "-" + String.format("%02d", item.getMonth()) + "-" + String.format("%02d", item.getDay());
  340. }
  341. if (queryDto.getReportType() == 2) {
  342. return item.getYear() + "-" + String.format("%02d", item.getMonth());
  343. }
  344. return null;
  345. }
  346. /**
  347. * 查询报表
  348. * @param reportDto
  349. * @return
  350. */
  351. abstract List<ReportDto> findReport(ReportDto reportDto);
  352. /**
  353. * 计算值
  354. * @param item
  355. * @param reportDtos
  356. */
  357. abstract void calcUsage(ReportDto item, List<ReportDto> reportDtos);
  358. /**
  359. * 查询属性
  360. * @param item
  361. * @return
  362. */
  363. abstract List<ReportAttributeDto> findAttributeList(ReportDto item);
  364. }