DeviceDataServiceImpl.java 16 KB

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