DeviceDataServiceImpl.java 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. package com.xy.service;
  2. import cn.hutool.core.bean.BeanUtil;
  3. import cn.hutool.core.util.StrUtil;
  4. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  5. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  6. import com.baomidou.mybatisplus.core.metadata.IPage;
  7. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  8. import com.xy.collections.list.JArrayList;
  9. import com.xy.collections.map.JConcurrentHashMap;
  10. import com.xy.collections.map.JHashMap;
  11. import com.xy.collections.map.JMap;
  12. import com.xy.device.EnumDeviceDataType;
  13. import com.xy.dto.DeviceDataDto;
  14. import com.xy.dto.DeviceInfoDto;
  15. import com.xy.entity.DeviceData;
  16. import com.xy.entity.SysDictRedis;
  17. import com.xy.mapper.DeviceDataMapper;
  18. import com.xy.utils.*;
  19. import io.swagger.annotations.Api;
  20. import io.swagger.annotations.ApiOperation;
  21. import lombok.AllArgsConstructor;
  22. import lombok.SneakyThrows;
  23. import org.springframework.context.annotation.Lazy;
  24. import org.springframework.stereotype.Service;
  25. import org.springframework.web.bind.annotation.PostMapping;
  26. import org.springframework.web.bind.annotation.RequestBody;
  27. import javax.validation.Valid;
  28. import java.math.BigDecimal;
  29. import java.time.LocalDateTime;
  30. import java.util.ArrayList;
  31. import java.util.List;
  32. import java.util.Map;
  33. import java.util.stream.Collectors;
  34. import static com.xy.utils.Beans.copy;
  35. import static com.xy.utils.PlusBeans.toIPage;
  36. import static com.xy.utils.PlusBeans.toPageBean;
  37. /**
  38. * <p>
  39. * 设备统计数据 服务实现类
  40. * </p>
  41. *
  42. * @author lijin
  43. * @since 2023-01-11
  44. */
  45. @Service
  46. @AllArgsConstructor(onConstructor_ = @Lazy)
  47. @Api(tags = "设备统计数据")
  48. public class DeviceDataServiceImpl extends ServiceImpl<DeviceDataMapper, DeviceData> implements DeviceDataService {
  49. private final DeviceInfoServiceImpl deviceInfoService;
  50. @PostMapping("sumPage")
  51. @ApiOperation("设备销售统计")
  52. public R<PageBean<DeviceDataDto.SumPageVo>> sumPage(@RequestBody @Valid DeviceDataDto.SumPageDto dto) {
  53. PageBean pageBean = dto.getPage();
  54. String salesCount = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getSalesCount));
  55. String salesMoney = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getSalesMoney));
  56. String goodsCount = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getGoodsCount));
  57. String refundMoney = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getRefundMoney));
  58. String refundCount = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getRefundCount));
  59. String riskCount = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getRiskCount));
  60. String zeroCount = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getZeroCount));
  61. String deviceId = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getDeviceId));
  62. LambdaQueryWrapper<DeviceData> lqw = new QueryWrapper<DeviceData>()
  63. .select(String.format("%s,sum(%s) %s,sum(%s) %s,sum(%s) %s,sum(%s) %s,sum(%s) %s,sum(%s) %s,sum(%s) %s"
  64. , deviceId, salesCount, salesCount, salesMoney, salesMoney, goodsCount, goodsCount
  65. , refundMoney, refundMoney, refundCount, refundCount, riskCount, riskCount, zeroCount, zeroCount
  66. ))
  67. .orderByAsc("asc".equals(dto.getOrderBy()), dto.getOrderByKey())
  68. .orderByDesc("desc".equals(dto.getOrderBy()), dto.getOrderByKey())
  69. .lambda()
  70. .eq(Emptys.check(dto.getMercId()), DeviceData::getMercId, dto.getMercId())
  71. .eq(DeviceData::getType, dto.getType())
  72. .ge(Emptys.check(dto.getBeginDate()), DeviceData::getDateValue, dto.getBeginDate())
  73. .le(Emptys.check(dto.getEndDate()), DeviceData::getDateValue, dto.getEndDate())
  74. .groupBy(DeviceData::getDeviceId);
  75. IPage<DeviceData> ipage = page(toIPage(pageBean), lqw);
  76. if (Emptys.check(ipage.getRecords())) {
  77. List<Long> deviceIdList = ipage.getRecords().stream().map(DeviceData::getDeviceId).collect(Collectors.toList());
  78. Map<Long, String> deviceMap = deviceInfoService.getDeviceNameList(new DeviceInfoDto.DeviceIdDto().setDeviceId(deviceIdList)).getData();
  79. PageBean<DeviceDataDto.SumPageVo> sumPageVoPageBean = toPageBean(DeviceDataDto.SumPageVo.class, ipage);
  80. sumPageVoPageBean.getRecords().forEach(i -> {
  81. i.setDeviceName(deviceMap.get(i.getDeviceId()));
  82. });
  83. return R.ok(sumPageVoPageBean);
  84. }
  85. return R.ok();
  86. }
  87. @PostMapping("sumCount")
  88. @ApiOperation("设备销售统计总计")
  89. public R<DeviceDataDto.SumCountVo> sumCount(@RequestBody @Valid DeviceDataDto.SumCountDto dto) {
  90. String salesCount = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getSalesCount));
  91. String salesMoney = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getSalesMoney));
  92. String goodsCount = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getGoodsCount));
  93. String refundMoney = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getRefundMoney));
  94. String refundCount = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getRefundCount));
  95. String riskCount = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getRiskCount));
  96. String zeroCount = StringTools.humpToLine(LambdaUtils.getProperty(DeviceData::getZeroCount));
  97. //查询总数
  98. LambdaQueryWrapper<DeviceData> lqw = new QueryWrapper<DeviceData>()
  99. .select(String.format("sum(%s) %s,sum(%s) %s,sum(%s) %s,sum(%s) %s,sum(%s) %s,sum(%s) %s,sum(%s) %s"
  100. , salesCount, salesCount, salesMoney, salesMoney, goodsCount, goodsCount
  101. , refundMoney, refundMoney, refundCount, refundCount, riskCount, riskCount, zeroCount, zeroCount
  102. ))
  103. .lambda()
  104. .eq(Emptys.check(dto.getMercId()), DeviceData::getMercId, dto.getMercId())
  105. .eq(DeviceData::getType, dto.getType())
  106. .ge(Emptys.check(dto.getBeginDate()), DeviceData::getDateValue, dto.getBeginDate())
  107. .le(Emptys.check(dto.getEndDate()), DeviceData::getDateValue, dto.getEndDate());
  108. return R.ok(copy(DeviceDataDto.SumCountVo.class, getOne(lqw)));
  109. }
  110. @PostMapping("obj")
  111. @ApiOperation("对象查询")
  112. public R<DeviceDataDto.Vo> obj(@RequestBody DeviceDataDto.Vo vo) {
  113. LambdaQueryWrapper<DeviceData> lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(vo, DeviceData.class).build();
  114. List<DeviceData> list = list(lambdaQueryWrapper);
  115. if (Emptys.check(list)) {
  116. return R.ok(copy(DeviceDataDto.Vo.class, list).get(0));
  117. }
  118. return R.ok();
  119. }
  120. @PostMapping("page")
  121. @ApiOperation("分页查询")
  122. public R<PageBean<DeviceDataDto.Vo>> page(@RequestBody DeviceDataDto.Page page) {
  123. PageBean pageBean = page.getPage();
  124. LambdaQueryWrapper<DeviceData> lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(page, DeviceData.class)
  125. .ge(DeviceData::getCreateTime, page.getBeginCreateTime())
  126. .le(DeviceData::getCreateTime, page.getEndCreateTime())
  127. .build()
  128. .orderByDesc(!Emptys.check(pageBean.getOrders()), DeviceData::getCreateTime);
  129. IPage<DeviceData> iPage = page(toIPage(pageBean), lambdaQueryWrapper);
  130. return R.ok(toPageBean(DeviceDataDto.Vo.class, iPage));
  131. }
  132. @ApiOperation("添加/累加")
  133. @PostMapping("saveOrAccum")
  134. public R saveOrAccum(@RequestBody DeviceDataDto.SaveOrAccum saveOrAccum) {
  135. return new SaveOrAccum().saveOrAccum(saveOrAccum, this);
  136. }
  137. /**
  138. * 集合查询
  139. *
  140. * @param dto
  141. * @return
  142. */
  143. public List<DeviceDataDto.Vo> list(DeviceDataDto.ListDTO dto) {
  144. LambdaQueryWrapper<DeviceData> lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(dto, DeviceData.class).build();
  145. List<DeviceData> list = list(lambdaQueryWrapper);
  146. return copy(DeviceDataDto.Vo.class, list);
  147. }
  148. /**
  149. * 指定查询商户某设备某天数据
  150. *
  151. * @param deviceId
  152. * @param mercId
  153. * @param dateValue
  154. * @return
  155. */
  156. public DeviceDataDto.Vo getByDay(Long deviceId, Long mercId, String dateValue) {
  157. return getOneData(EnumDeviceDataType.DAY.getCode(), deviceId, mercId, dateValue);
  158. }
  159. /**
  160. * 指定查询商户所有设备某天数据
  161. *
  162. * @param mercId
  163. * @param dateValue
  164. * @return
  165. */
  166. public List<DeviceDataDto.Vo> getMercDataOneDay(Long mercId, String dateValue) {
  167. return getMercListData(EnumDeviceDataType.DAY.getCode(), mercId, dateValue);
  168. }
  169. /**
  170. * 指定查询商户所有设备某月数据
  171. *
  172. * @param mercId
  173. * @param dateValue
  174. * @return
  175. */
  176. public List<DeviceDataDto.Vo> getMercDataOneMonth(Long mercId, String dateValue) {
  177. return getMercListData(EnumDeviceDataType.MONTH.getCode(), mercId, dateValue);
  178. }
  179. /**
  180. * 指定查询商户某设备某月数据
  181. *
  182. * @param deviceId
  183. * @param mercId
  184. * @param dateValue
  185. * @return
  186. */
  187. public DeviceDataDto.Vo getByMonth(Long deviceId, Long mercId, String dateValue) {
  188. return getOneData(EnumDeviceDataType.MONTH.getCode(), deviceId, mercId, dateValue);
  189. }
  190. /**
  191. * 指定查询商户某设备某年数据
  192. *
  193. * @param deviceId
  194. * @param mercId
  195. * @param dateValue
  196. * @return
  197. */
  198. public DeviceDataDto.Vo getByYear(Long deviceId, Long mercId, String dateValue) {
  199. return getOneData(EnumDeviceDataType.YEAR.getCode(), deviceId, mercId, dateValue);
  200. }
  201. /**
  202. * 指定查询商户某设备某年、月、日数据
  203. *
  204. * @param type
  205. * @param deviceId
  206. * @param mercId
  207. * @param dateValue
  208. * @return
  209. */
  210. public DeviceDataDto.Vo getOneData(String type, Long deviceId, Long mercId, String dateValue) {
  211. LambdaQueryWrapper<DeviceData> lambdaQueryWrapper = new LambdaQueryWrapper<>();
  212. lambdaQueryWrapper.eq(DeviceData::getType, type);
  213. lambdaQueryWrapper.eq(DeviceData::getDeviceId, deviceId);
  214. lambdaQueryWrapper.eq(DeviceData::getMercId, mercId);
  215. lambdaQueryWrapper.eq(DeviceData::getDateValue, Integer.valueOf(dateValue));
  216. DeviceData data = getOne(lambdaQueryWrapper);
  217. return copy(DeviceDataDto.Vo.class, data);
  218. }
  219. /**
  220. * 指定查询商户所有设备某年、月、日数据
  221. *
  222. * @param type
  223. * @param mercId
  224. * @param dateValue
  225. * @return
  226. */
  227. public List<DeviceDataDto.Vo> getMercListData(String type, Long mercId, String dateValue) {
  228. LambdaQueryWrapper<DeviceData> lambdaQueryWrapper = new LambdaQueryWrapper<>();
  229. lambdaQueryWrapper.eq(DeviceData::getType, type);
  230. lambdaQueryWrapper.eq(DeviceData::getMercId, mercId);
  231. lambdaQueryWrapper.eq(DeviceData::getDateValue, Integer.valueOf(dateValue));
  232. List<DeviceData> list = list(lambdaQueryWrapper);
  233. return BeanUtil.copyToList(list, DeviceDataDto.Vo.class);
  234. }
  235. /**
  236. * 日范围内每天数据
  237. *
  238. * @param deviceId
  239. * @param startDateValue
  240. * @param endDateValue
  241. * @return
  242. */
  243. public List<DeviceDataDto.Vo> getListByDay(Long deviceId, Integer startDateValue, Integer endDateValue) {
  244. return getListData(EnumDeviceDataType.DAY.getCode(), deviceId, startDateValue, endDateValue);
  245. }
  246. /**
  247. * 日期范围查询
  248. *
  249. * @param type
  250. * @param deviceId
  251. * @param startDateValue
  252. * @param endDateValue
  253. * @return
  254. */
  255. public List<DeviceDataDto.Vo> getListData(String type, Long deviceId, Integer startDateValue, Integer endDateValue) {
  256. LambdaQueryWrapper<DeviceData> lambdaQueryWrapper = new LambdaQueryWrapper<>();
  257. lambdaQueryWrapper.eq(DeviceData::getType, type);
  258. lambdaQueryWrapper.eq(DeviceData::getDeviceId, deviceId);
  259. lambdaQueryWrapper.between(DeviceData::getDateValue, startDateValue, endDateValue);
  260. lambdaQueryWrapper.orderBy(true, true, DeviceData::getDateValue);
  261. List<DeviceData> list = list(lambdaQueryWrapper);
  262. return copy(DeviceDataDto.Vo.class, list);
  263. }
  264. @Override
  265. public R<List<DeviceDataDto.Vo>> getMercDataOneDay(DeviceDataDto.CountByDay dto) {
  266. return R.ok(this.getMercDataOneDay(dto.getMercId(), dto.getDateValue()));
  267. }
  268. @Override
  269. public R<List<DeviceDataDto.Vo>> getMercDataOneMonth(DeviceDataDto.CountByMonth dto) {
  270. return R.ok(this.getMercDataOneMonth(dto.getMercId(), dto.getDateValue()));
  271. }
  272. @ApiOperation("图表数据")
  273. @Override
  274. public R<List<DeviceDataDto.DayChartVo>> dayChart(@RequestBody @Valid DeviceDataDto.DayChartDto dto) {
  275. List<DeviceDataDto.DayChartVo> dayChartVos = baseMapper.dayChart(dto.getMercId(), dto.getBeginInt(), dto.getEndDateInt(), dto.getType());
  276. Map<Integer, DeviceDataDto.DayChartVo> voMap = dayChartVos.stream().collect(Collectors.toMap(DeviceDataDto.DayChartVo::getTime, i -> i));
  277. List<String> dayList = DataTime.getBetweenDates(dto.getBeginDate().toString(), dto.getEndDate().toString(), true);
  278. List<Integer> dayList2 = dayList.stream().map(i -> Integer.valueOf(StrUtil.replace(i, "-", ""))).collect(Collectors.toList());
  279. List<DeviceDataDto.DayChartVo> list = new ArrayList<>();
  280. dayList2.forEach(
  281. i -> {
  282. Integer num = 0;
  283. Integer totalMoney = 0;
  284. BigDecimal totalMoneyYuan = new BigDecimal(0);
  285. DeviceDataDto.DayChartVo dayChartVo = voMap.get(i);
  286. if (Emptys.check(dayChartVo)) {
  287. num = dayChartVo.getNum();
  288. totalMoney = dayChartVo.getTotalMoney();
  289. totalMoneyYuan = dayChartVo.getTotalMoneyYuan();
  290. }
  291. list.add(new DeviceDataDto.DayChartVo()
  292. .setTime(i)
  293. .setNum(num)
  294. .setTotalMoney(totalMoney)
  295. .setTotalMoneyYuan(totalMoneyYuan)
  296. );
  297. }
  298. );
  299. return R.ok(list);
  300. }
  301. @Override
  302. @ApiOperation("商户日期维度查询")
  303. public R<PageBean<DeviceDataDto.Vo>> pageByMercAndDate(DeviceDataDto.PageByMercAndDate pageByMercAndDate) {
  304. PageBean pageBean = pageByMercAndDate.getPage();
  305. LambdaQueryWrapper<DeviceData> lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(pageByMercAndDate, DeviceData.class)
  306. .in(DeviceData::getDeviceId)
  307. .ge(DeviceData::getDateValue, pageByMercAndDate.getBeginDateValue())
  308. .le(DeviceData::getDateValue, pageByMercAndDate.getEndDateValue())
  309. .build()
  310. .orderByDesc(DeviceData::getCreateTime);
  311. IPage<DeviceData> iPage = page(toIPage(pageBean), lambdaQueryWrapper);
  312. return R.ok(toPageBean(DeviceDataDto.Vo.class, iPage));
  313. }
  314. @Override
  315. @ApiOperation("商户日期维度统计查询")
  316. public R<Long> pageByMercAndDateCount(DeviceDataDto.PageByMercAndDate pageByMercAndDate) {
  317. LambdaQueryWrapper<DeviceData> lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(pageByMercAndDate, DeviceData.class)
  318. .in(DeviceData::getDeviceId)
  319. .ge(DeviceData::getDateValue, pageByMercAndDate.getBeginDateValue())
  320. .le(DeviceData::getDateValue, pageByMercAndDate.getEndDateValue())
  321. .build()
  322. .orderByDesc(DeviceData::getCreateTime);
  323. long count = count(lambdaQueryWrapper);
  324. return R.ok(count);
  325. }
  326. public static class SaveOrAccum {
  327. public R saveOrAccum(DeviceDataDto.SaveOrAccum saveOrAccum, DeviceDataServiceImpl deviceDataService) {
  328. return new LockUtils()
  329. .name("saveOrAccum.deviceId")
  330. .prefix("data_save_accum_")
  331. .build(SaveOrAccum.class)
  332. .exec(saveOrAccum, deviceDataService);
  333. }
  334. @SneakyThrows
  335. public R exec(DeviceDataDto.SaveOrAccum saveOrAccum, DeviceDataServiceImpl deviceDataService) {
  336. LocalDateTime now = LocalDateTime.now();
  337. String yyyyMMdd = DataTime.toString(now, "yyyyMMdd");
  338. //获取字典
  339. Map<String, SysDictRedis> map = SysDictUtils.get(EnumDeviceDataType.Code.CODE.getCode());
  340. JMap<String, Integer> jMap = new JHashMap<>(map.size());
  341. map.forEach((type, sysDictRedis) -> {
  342. Integer dateValue = Integer.valueOf(yyyyMMdd.substring(0, Integer.valueOf(sysDictRedis.getValue())));
  343. jMap.put(type, dateValue);
  344. });
  345. //查询已存在数据
  346. List<DeviceData> list = deviceDataService.list(new LambdaQueryWrapper<DeviceData>()
  347. .eq(DeviceData::getDeviceId, saveOrAccum.getDeviceId())
  348. .in(DeviceData::getDateValue, jMap.toList().value())
  349. );
  350. JMap<String, DeviceData> typeMaps = new JArrayList<>(list).toMap(DeviceData::getType).cover();
  351. //新增或修改的多线程桶map集合
  352. JMap<String, DeviceData> dbMaps = new JConcurrentHashMap<>(map.size());
  353. //封装新增或修改对象
  354. jMap.forEach((type, dateValue) -> {
  355. DeviceData deviceData = typeMaps.get(type);
  356. //添加
  357. if (deviceData == null) {
  358. DeviceData saveOrUpdateInfo = copy(DeviceData.class, saveOrAccum)
  359. .setCreateTime(now)
  360. .setUpdateTime(now)
  361. .setType(type)
  362. .setDateValue(dateValue);
  363. dbMaps.put(type, saveOrUpdateInfo);
  364. return;
  365. }
  366. //累加
  367. DeviceData updateDeviceData = new DeviceData().setId(deviceData.getId()).setUpdateTime(now)
  368. .setSalesMoney(saveOrAccum.getSalesMoney() != null ? saveOrAccum.getSalesMoney() + deviceData.getSalesMoney() : null)
  369. .setSalesCount(saveOrAccum.getSalesCount() != null ? saveOrAccum.getSalesCount() + deviceData.getSalesCount() : null)
  370. .setGoodsCount(saveOrAccum.getGoodsCount() != null ? saveOrAccum.getGoodsCount() + deviceData.getGoodsCount() : null)
  371. .setRefundMoney(saveOrAccum.getRefundMoney() != null ? saveOrAccum.getRefundMoney() + deviceData.getRefundMoney() : null)
  372. .setRefundCount(saveOrAccum.getRefundCount() != null ? saveOrAccum.getRefundCount() + deviceData.getRefundCount() : null)
  373. .setZeroCount(saveOrAccum.getZeroCount() != null ? saveOrAccum.getZeroCount() + deviceData.getZeroCount() : null)
  374. .setDeviceFaultCount(saveOrAccum.getDeviceFaultCount() != null ? saveOrAccum.getDeviceFaultCount() + deviceData.getDeviceFaultCount() : null);
  375. dbMaps.put(type, updateDeviceData);
  376. });
  377. deviceDataService.saveOrUpdateBatch(dbMaps.toList().value());
  378. return R.ok();
  379. }
  380. }
  381. }