BusinessServiceImpl.java 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. package com.ruoyi.business.service.impl;
  2. import com.ruoyi.business.domain.*;
  3. import com.ruoyi.business.mapper.*;
  4. import com.ruoyi.business.req.AssayReq;
  5. import com.ruoyi.business.req.DeviceReq;
  6. import com.ruoyi.business.res.*;
  7. import com.ruoyi.business.service.IBusinessService;
  8. import com.ruoyi.common.NumberUtils;
  9. import com.ruoyi.common.utils.DateUtils;
  10. import com.ruoyi.common.utils.StringUtils;
  11. import lombok.extern.slf4j.Slf4j;
  12. import org.springframework.beans.factory.annotation.Autowired;
  13. import org.springframework.stereotype.Service;
  14. import org.springframework.util.CollectionUtils;
  15. import java.util.*;
  16. import java.util.concurrent.atomic.AtomicInteger;
  17. import java.util.stream.Collectors;
  18. import static com.ruoyi.common.constant.Constants.INT_2;
  19. import static com.ruoyi.common.constant.Constants.INT_4;
  20. @Slf4j
  21. @Service
  22. public class BusinessServiceImpl implements IBusinessService {
  23. @Autowired
  24. private BizDeviceMapper bizDeviceMapper;
  25. @Autowired
  26. private BizWaterWorkMapper bizWaterWorkMapper;
  27. @Autowired
  28. private ZAssayMapper zAssayMapper;
  29. @Autowired
  30. private ZAssayResultMapper zAssayResultMapper;
  31. @Autowired
  32. private ZQualityValueMapper zQualityValueMapper;
  33. /**
  34. * 2024年10月25日09:46:36 新增逻辑:type可以不传。
  35. * @param type
  36. * @return
  37. */
  38. @Override
  39. public HomeCountsRes homeCountsInfo(String type) {//type 1:化验室,2:连续检测
  40. HomeCountsRes build = HomeCountsRes.builder().build();
  41. //处理各个维度的统计信息
  42. //获取所有的正在使用的设备列表 大概几十个,所以直接取所有数据,下面再过滤
  43. //2024年10月25日09:51:12 type可以不传,直接查询对应的数据
  44. List<BizDevice> totalList = this.bizDeviceMapper.selectBizDeviceList(BizDevice.builder().deviceStatus("0").type(type).build());
  45. //一定有设备 并且mybatis返回的默认是空集合new出来的而不是null,所以这里不用判断
  46. // List<BizDevice> totalList = bizDevices.stream().filter(bizDevice -> String.valueOf(type).equals(bizDevice.getType())).collect(Collectors.toList());
  47. if (!CollectionUtils.isEmpty(totalList)) {
  48. build.setDeviceTotals((long) totalList.size());
  49. //化验中
  50. build.setOnDeviceCounts(totalList.stream().filter(bizDevice -> "2".equals(bizDevice.getAssayStatus())).count());
  51. //待机
  52. build.setStandbyDeviceCounts(totalList.stream().filter(bizDevice -> "0".equals(bizDevice.getAssayStatus())).count());
  53. //离线
  54. build.setOffDeviceCounts(totalList.stream().filter(bizDevice -> "1".equals(bizDevice.getAssayStatus())).count());
  55. }
  56. //统计今日的化验数据
  57. //先获取今日的所有的化验的质控样数据 再编写通用方法,判断是否合格,再获取合格的数量
  58. List<ZAssayResult> zAssayResults = this.zAssayResultMapper.selectZAssayResultList(ZAssayResult.builder().resultDate(DateUtils.getDate()).assayType("3").build());
  59. // List<ZAssayResult> zAssayResults = this.zAssayResultMapper.selectZAssayResultList(ZAssayResult.builder().resultDate("2024-08-13").assayType("3").build());
  60. if(!CollectionUtils.isEmpty(zAssayResults)){
  61. int checkTotals = zAssayResults.size();
  62. build.setAssayTotals(checkTotals);
  63. int passCheckTotals = this.getPassedCounts(zAssayResults);
  64. build.setPassAssayTotals(passCheckTotals);
  65. build.setPassAssayRates(NumberUtils.getDoublePercentAndNLength(INT_4, (double)passCheckTotals / (double)checkTotals, INT_2));//整数除以整数还是整数,所以这里要强转成小数
  66. }
  67. return build;
  68. }
  69. @Override
  70. public List<DeviceRes> devicePageList(DeviceReq deviceReq) {
  71. //处理一下化验日期,如果没有,默认是今天
  72. String assayDate = deviceReq.getAssayDate();
  73. if(StringUtils.isBlank(assayDate)){
  74. assayDate = DateUtils.getDate();
  75. // assayDate = "2024-08-13";
  76. }
  77. //先获取设备列表 直接写SQL了,不使用copy
  78. List<DeviceRes> list =this.bizDeviceMapper.devicePageList(deviceReq);
  79. //额外处理其他数据
  80. if(!CollectionUtils.isEmpty(list)){
  81. for (DeviceRes deviceRes : list) {
  82. this.addDeviceExtra(deviceRes, assayDate, deviceRes.getDeviceNo());
  83. }
  84. }
  85. return list;
  86. }
  87. @Override
  88. public List<AssayDetailRes> assayPageListByDeviceNoAndDate(AssayReq assayReq) {
  89. //通过设备编号和日期获取质控样的化验记录的明细化验时间和化验编号
  90. //2024年10月28日14:51:33 化验室设备还是连续监测设备是分开的,不可以同时出现
  91. if(StringUtils.isBlank(assayReq.getType()))
  92. throw new RuntimeException("请输入一种设备类型");
  93. String nowDate = DateUtils.getDate();
  94. if(StringUtils.isBlank(assayReq.getTimeBegin()))
  95. assayReq.setTimeBegin(nowDate);
  96. if(StringUtils.isBlank(assayReq.getTimeEnd()))
  97. assayReq.setTimeEnd(nowDate);
  98. List<AssayDetailRes> list = this.zAssayMapper.assayPageListByDeviceNoAndDate(assayReq);
  99. if(!CollectionUtils.isEmpty(list)){
  100. for (AssayDetailRes assayDetailRes : list) {
  101. String assayNo = assayDetailRes.getAssayNo();
  102. if(StringUtils.isNotBlank(assayNo)){
  103. this.addAssayExtra(assayNo, assayDetailRes);
  104. }
  105. }
  106. }
  107. return list;
  108. }
  109. @Override
  110. public List<AssayQualityDetailRes> assayCountListByDates(AssayReq assayReq) {
  111. //2024年10月21日10:56:31 只获取质控样的数据
  112. //2024年10月22日16:22:53 因为数据的原因,这里只获取化验室的数据 即biz_device表type=1
  113. // List<ZAssayResult> zAssayResults = this.zAssayResultMapper.selectZAssayResultList(ZAssayResult.builder().assayType("3").deviceNo(assayReq.getDeviceNo()).timeBegin(assayReq.getTimeBegin()).timeEnd(assayReq.getTimeEnd()).assayType("3").build());
  114. List<ZAssayResult> zAssayResults = this.zAssayResultMapper.assayCountListByDates(assayReq);
  115. if(CollectionUtils.isEmpty(zAssayResults)){
  116. return Collections.emptyList();
  117. }
  118. //有数据 处理统计信息
  119. return this.getCountInfoByAssayResults(zAssayResults);
  120. }
  121. @Override
  122. public Map<String, Map<String, List<ContinuousAssayResultRes>>> continuousAssayCountByDates(AssayReq assayReq) {
  123. //返回的最终对象
  124. Map<String, Map<String, List<ContinuousAssayResultRes>>> resultMap = new LinkedHashMap<>();
  125. //通过筛选条件获取最基本的数据列表
  126. List<ContinuousAssayBasic> list = this.zAssayResultMapper.continuousAssayCountByDates(assayReq);
  127. AtomicInteger totalCount = new AtomicInteger();//合计次数
  128. if(!CollectionUtils.isEmpty(list)){
  129. //有数据 再分组,再分别统计信息
  130. Map<String, List<ContinuousAssayBasic>> itemNameMap = list.stream().collect(Collectors.groupingBy(ContinuousAssayBasic::getItemName));
  131. itemNameMap.forEach((k, v) -> {
  132. //内存的map
  133. HashMap<String, List<ContinuousAssayResultRes>> innerMap = new HashMap<>();
  134. //还需要再根据化验指标再分一次组
  135. Map<String, List<ContinuousAssayBasic>> assayNameMap = v.stream().collect(Collectors.groupingBy(ContinuousAssayBasic::getAssayName));
  136. assayNameMap.forEach((assayName, assayBasicList) -> {
  137. List<ContinuousAssayResultRes> innerList = new ArrayList<>(assayBasicList.size());
  138. ContinuousAssayResultRes continuousAssayResultRes = new ContinuousAssayResultRes();
  139. //处理统计信息
  140. int assayCounts = assayBasicList.size();//实际检测数量
  141. totalCount.addAndGet(assayCounts);
  142. //调用通用的获取合格数量的方法
  143. List<ZAssayResult> zAssayResults = new ArrayList<>();
  144. for (ContinuousAssayBasic continuousAssayBasic : assayBasicList) {
  145. ZAssayResult zAssayResult = new ZAssayResult();
  146. zAssayResult.setAssayItem(continuousAssayBasic.getAssayName());
  147. zAssayResult.setDeviceNo(continuousAssayBasic.getDeviceNo());
  148. zAssayResult.setResultConcentration(continuousAssayBasic.getResultConcentration());
  149. zAssayResults.add(zAssayResult);
  150. }
  151. int passedCounts = this.getPassedCounts(zAssayResults);
  152. //封装到对象
  153. continuousAssayResultRes.setAssayName(assayName);
  154. continuousAssayResultRes.setAssayCounts(assayCounts);
  155. assayBasicList.stream().map(ContinuousAssayBasic::getResultConcentration).min(Double::compareTo).ifPresent(continuousAssayResultRes::setMinVal);
  156. assayBasicList.stream().map(ContinuousAssayBasic::getResultConcentration).max(Double::compareTo).ifPresent(continuousAssayResultRes::setMaxVal);
  157. double passedRates = (double) passedCounts / (double) assayCounts;
  158. continuousAssayResultRes.setPassedRates(NumberUtils.getDoublePercentAndNLength(INT_4, passedRates, INT_2));
  159. continuousAssayResultRes.setRatesDeviation(NumberUtils.getDoublePercentAndNLength(INT_4, passedRates - continuousAssayResultRes.getBxDouble(), INT_2));
  160. innerList.add(continuousAssayResultRes);
  161. innerMap.put(assayName, innerList);
  162. });
  163. resultMap.put(k, innerMap);
  164. });
  165. //2024年10月10日10:10:10 把 合计的结果也返回
  166. HashMap<String, List<ContinuousAssayResultRes>> extraMap = new HashMap<>();
  167. List<ContinuousAssayResultRes> extraList = new ArrayList<>();
  168. ContinuousAssayResultRes continuousAssayResultRes = new ContinuousAssayResultRes();
  169. continuousAssayResultRes.setAssayCounts(totalCount.get());
  170. //2024年10月10日19:16:39 因为有默认值,所以需要把他们清空
  171. continuousAssayResultRes.setBx(null);
  172. continuousAssayResultRes.setRatesDeviation(null);
  173. extraList.add(continuousAssayResultRes);
  174. extraMap.put("合计", extraList);
  175. resultMap.put("total", extraMap);
  176. //2024年10月21日14:14:53 最下面额外再添加新的维度的统计数据
  177. HashMap<String, List<ContinuousAssayResultRes>> calculateMap = new HashMap<>();
  178. List<ContinuousAssayResultRes> calculateList = new ArrayList<>();
  179. //2024年10月21日14:43:43 额外统计的指标汇总信息
  180. Map<String, List<ContinuousAssayBasic>> collect = list.stream().collect(Collectors.groupingBy(ContinuousAssayBasic::getAssayName));
  181. collect.forEach((key, value) -> {
  182. ContinuousAssayResultRes continuousAssayResultResCalculate = new ContinuousAssayResultRes();
  183. continuousAssayResultResCalculate.setAssayName(key);
  184. continuousAssayResultResCalculate.setAssayCounts(value.size());
  185. continuousAssayResultResCalculate.setBx(null);
  186. calculateList.add(continuousAssayResultResCalculate);
  187. });
  188. calculateMap.put("额外统计", calculateList);
  189. resultMap.put("calculate", calculateMap);
  190. }
  191. return resultMap;
  192. }
  193. @Override
  194. public Map<String, ContinuousAssayResultResNew> continuousAssayCountByDatesNew(AssayReq assayReq) {
  195. //返回的最终对象
  196. Map<String, ContinuousAssayResultResNew> resultMap = new LinkedHashMap<>();
  197. //通过筛选条件获取最基本的数据列表
  198. List<ContinuousAssayBasic> list = this.zAssayResultMapper.continuousAssayCountByDates(assayReq);
  199. Map<String, List<ContinuousAssayBasic>> map = list.stream().collect(Collectors.groupingBy(ContinuousAssayBasic::getAssayName));
  200. map.forEach((key, value) -> {
  201. //获取同检测指标的的质控样的统计数据
  202. List<ZAssayResult> zAssayResults = this.zAssayResultMapper.selectZAssayResultList(ZAssayResult.builder().assayType("3").assayItem(value.get(0).getAssayItem()).deviceNo(assayReq.getDeviceNo()).timeBegin(assayReq.getTimeBegin()).timeEnd(assayReq.getTimeEnd()).build());
  203. int zkCounts = zAssayResults.size();
  204. int passedCounts = this.getPassedCounts(zAssayResults);
  205. double val = (double) passedCounts / zkCounts;//质控样合格率
  206. //组装对应的数据
  207. ContinuousAssayResultResNew continuousAssayResultResNew = new ContinuousAssayResultResNew();
  208. continuousAssayResultResNew.setAssayName(key);
  209. continuousAssayResultResNew.setAssayCounts(value.size());
  210. continuousAssayResultResNew.setZkCounts(zkCounts);
  211. continuousAssayResultResNew.setPassedRates(NumberUtils.getDoublePercentAndNLength(INT_4, val, INT_2));
  212. double ratesDeviation = val - continuousAssayResultResNew.getBxDouble();
  213. double ratesDeviationNumber = ratesDeviation > 0 ? 0D : Math.abs(ratesDeviation);
  214. continuousAssayResultResNew.setRatesDeviation(NumberUtils.getDoublePercentAndNLength(INT_4, ratesDeviationNumber, INT_2));
  215. continuousAssayResultResNew.setRatesDeviationNumber(ratesDeviationNumber);
  216. resultMap.put(key, continuousAssayResultResNew);
  217. });
  218. return resultMap;
  219. }
  220. private List<AssayQualityDetailRes> getCountInfoByAssayResults(List<ZAssayResult> zAssayResults) {
  221. List<AssayQualityDetailRes> result = new ArrayList<>();
  222. if(!CollectionUtils.isEmpty(zAssayResults)){
  223. //先按照水厂进行分组
  224. Map<String, List<ZAssayResult>> map = zAssayResults.stream().collect(Collectors.groupingBy(ZAssayResult::getDeviceNo));
  225. map.forEach((deviceNo, value) -> {
  226. AssayQualityDetailRes assayQualityDetailRes = new AssayQualityDetailRes();
  227. log.info("水厂的编号为{}", deviceNo);
  228. //获取水厂的名称
  229. //先查询化验室,再获取水厂信息
  230. List<BizDevice> bizDevices = this.bizDeviceMapper.selectBizDeviceList(BizDevice.builder().deviceNo(deviceNo).build());
  231. if(!CollectionUtils.isEmpty(bizDevices)){
  232. //水厂
  233. /*log.info("化验对应的设备id为{}", bizDevices.get(0).getDeviceWorks());
  234. List<BizWaterWork> bizWaterWorks = this.bizWaterWorkMapper.selectBizWaterWorkList(BizWaterWork.builder().worksId(bizDevices.get(0).getDeviceWorks()).build());
  235. if(!CollectionUtils.isEmpty(bizWaterWorks)){
  236. assayQualityDetailRes.setWorksName(bizWaterWorks.get(0).getWorksName());
  237. }*/
  238. Long deviceWorks = bizDevices.get(0).getDeviceWorks();
  239. if(Objects.isNull(deviceWorks)){
  240. log.error("通过化验结果的化验设备编号查询设备记录时,没有查询到设备记录,导致无法获取水厂信息");
  241. }else{
  242. BizWaterWork bizWaterWork = this.bizWaterWorkMapper.selectBizWaterWorkByWorksId(deviceWorks);
  243. if(!Objects.isNull(bizWaterWork)){
  244. assayQualityDetailRes.setWorksName(bizWaterWork.getWorksName());
  245. }
  246. }
  247. }
  248. //处理统计信息
  249. //处理总的合格率
  250. int totalDeviationRateCounts = 0;
  251. int totalpassedDeviationRateCounts = 0;
  252. //高COD
  253. List<ZAssayResult> highCodList = value.stream().filter(zAssayResult -> "1".equals(zAssayResult.getAssayItem())).collect(Collectors.toList());
  254. Double highCodDeviationRate = null;//后续有个总的合格率,这里用null默认,后面计算分别做判断
  255. if(!CollectionUtils.isEmpty(highCodList)){
  256. int highCodArrayCounts = highCodList.size();
  257. assayQualityDetailRes.setHighCodArrayCounts(highCodArrayCounts);
  258. int highCodPassedCounts = this.getPassedCounts(highCodList);
  259. assayQualityDetailRes.setHighCodPassedCounts(highCodPassedCounts);
  260. highCodDeviationRate = (double) highCodPassedCounts / (double) highCodArrayCounts;
  261. totalDeviationRateCounts += highCodArrayCounts;
  262. totalpassedDeviationRateCounts += highCodPassedCounts;
  263. assayQualityDetailRes.setHighCodDeviationRate(NumberUtils.getDoublePercentAndNLength(INT_4, highCodDeviationRate, INT_2));
  264. }
  265. //低COD
  266. List<ZAssayResult> lowCodList = value.stream().filter(zAssayResult -> "2".equals(zAssayResult.getAssayItem())).collect(Collectors.toList());
  267. Double lowCodDeviationRate = null;//后续有个总的合格率,这里用null默认,后面计算分别做判断
  268. if(!CollectionUtils.isEmpty(lowCodList)){
  269. int lowCodArrayCounts = lowCodList.size();
  270. assayQualityDetailRes.setLowCodArrayCounts(lowCodArrayCounts);
  271. int lowCodPassedCounts = this.getPassedCounts(lowCodList);
  272. assayQualityDetailRes.setLowCodPassedCounts(lowCodPassedCounts);
  273. lowCodDeviationRate = (double) lowCodPassedCounts / (double) lowCodArrayCounts;
  274. totalDeviationRateCounts += lowCodArrayCounts;
  275. totalpassedDeviationRateCounts += lowCodPassedCounts;
  276. assayQualityDetailRes.setLowCodDeviationRate(NumberUtils.getDoublePercentAndNLength(INT_4, lowCodDeviationRate, INT_2));
  277. }
  278. //氨氮
  279. List<ZAssayResult> anDanList = value.stream().filter(zAssayResult -> "3".equals(zAssayResult.getAssayItem())).collect(Collectors.toList());
  280. Double anDanDeviationRate = null;//后续有个总的合格率,这里用null默认,后面计算分别做判断
  281. if(!CollectionUtils.isEmpty(anDanList)){
  282. int anDanArrayCounts = anDanList.size();
  283. assayQualityDetailRes.setAnDanArrayCounts(anDanArrayCounts);
  284. int anDanPassedCounts = this.getPassedCounts(anDanList);
  285. assayQualityDetailRes.setAnDanPassedCounts(anDanPassedCounts);
  286. anDanDeviationRate = (double) anDanPassedCounts / (double) anDanArrayCounts;
  287. totalDeviationRateCounts += anDanArrayCounts;
  288. totalpassedDeviationRateCounts += anDanPassedCounts;
  289. assayQualityDetailRes.setAnDanDeviationRate(NumberUtils.getDoublePercentAndNLength(INT_4, anDanDeviationRate, INT_2));
  290. }
  291. //总氮
  292. List<ZAssayResult> tnList = value.stream().filter(zAssayResult -> "4".equals(zAssayResult.getAssayItem())).collect(Collectors.toList());
  293. Double tnDeviationRate = null;//后续有个总的合格率,这里用null默认,后面计算分别做判断
  294. if(!CollectionUtils.isEmpty(tnList)){
  295. int tnArrayCounts = tnList.size();
  296. assayQualityDetailRes.setTnArrayCounts(tnArrayCounts);
  297. int tnPassedCounts = this.getPassedCounts(tnList);
  298. assayQualityDetailRes.setTnPassedCounts(tnPassedCounts);
  299. tnDeviationRate = (double) tnPassedCounts / (double) tnArrayCounts;
  300. totalDeviationRateCounts += tnArrayCounts;
  301. totalpassedDeviationRateCounts += tnPassedCounts;
  302. assayQualityDetailRes.setTnDeviationRate(NumberUtils.getDoublePercentAndNLength(INT_4, tnDeviationRate, INT_2));
  303. }
  304. //总磷
  305. List<ZAssayResult> tpList = value.stream().filter(zAssayResult -> "5".equals(zAssayResult.getAssayItem())).collect(Collectors.toList());
  306. Double tpDeviationRate = null;//后续有个总的合格率,这里用null默认,后面计算分别做判断
  307. if(!CollectionUtils.isEmpty(tpList)){
  308. int tpArrayCounts = tpList.size();
  309. assayQualityDetailRes.setTpArrayCounts(tpArrayCounts);
  310. int tpPassedCounts = this.getPassedCounts(tpList);
  311. assayQualityDetailRes.setTpPassedCounts(tpPassedCounts);
  312. tpDeviationRate = (double) tpPassedCounts / (double) tpArrayCounts;
  313. totalDeviationRateCounts += tpArrayCounts;
  314. totalpassedDeviationRateCounts += tpPassedCounts;
  315. assayQualityDetailRes.setTpDeviationRate(NumberUtils.getDoublePercentAndNLength(INT_4, tpDeviationRate, INT_2));
  316. }
  317. //正磷酸盐
  318. List<ZAssayResult> zlsyList = value.stream().filter(zAssayResult -> "6".equals(zAssayResult.getAssayItem())).collect(Collectors.toList());
  319. Double zlsyDeviationRate = null;//后续有个总的合格率,这里用null默认,后面计算分别做判断
  320. if(!CollectionUtils.isEmpty(zlsyList)){
  321. int zlsyArrayCounts = zlsyList.size();
  322. assayQualityDetailRes.setZlsyArrayCounts(zlsyArrayCounts);
  323. int zlsyPassedCounts = this.getPassedCounts(zlsyList);
  324. assayQualityDetailRes.setZlsyPassedCounts(zlsyPassedCounts);
  325. zlsyDeviationRate = (double) zlsyPassedCounts / (double) zlsyArrayCounts;
  326. totalDeviationRateCounts += zlsyArrayCounts;
  327. totalpassedDeviationRateCounts += zlsyPassedCounts;
  328. assayQualityDetailRes.setZlsyDeviationRate(NumberUtils.getDoublePercentAndNLength(INT_4, zlsyDeviationRate, INT_2));
  329. }
  330. //亚硝酸盐氮
  331. List<ZAssayResult> yxsydList = value.stream().filter(zAssayResult -> "7".equals(zAssayResult.getAssayItem())).collect(Collectors.toList());
  332. Double yxsydDeviationRate = null;//后续有个总的合格率,这里用null默认,后面计算分别做判断
  333. if(!CollectionUtils.isEmpty(yxsydList)){
  334. int yxsydArrayCounts = yxsydList.size();
  335. assayQualityDetailRes.setYxsyArrayCounts(yxsydArrayCounts);
  336. int ysxydPassedCounts = this.getPassedCounts(yxsydList);
  337. assayQualityDetailRes.setYxsyPassedCounts(ysxydPassedCounts);
  338. yxsydDeviationRate = (double) ysxydPassedCounts / (double) yxsydArrayCounts;
  339. totalDeviationRateCounts += yxsydArrayCounts;
  340. totalpassedDeviationRateCounts += ysxydPassedCounts;
  341. assayQualityDetailRes.setYxsyDeviationRate(NumberUtils.getDoublePercentAndNLength(INT_4, yxsydDeviationRate, INT_2));
  342. }
  343. //硝酸盐氮
  344. List<ZAssayResult> xsydList = value.stream().filter(zAssayResult -> "8".equals(zAssayResult.getAssayItem())).collect(Collectors.toList());
  345. Double xsydDeviationRate = null;//后续有个总的合格率,这里用null默认,后面计算分别做判断
  346. if(!CollectionUtils.isEmpty(xsydList)){
  347. int xsydArrayCounts = xsydList.size();
  348. assayQualityDetailRes.setXsydArrayCounts(xsydArrayCounts);
  349. int xsydPassedCounts = this.getPassedCounts(xsydList);
  350. assayQualityDetailRes.setXsydPassedCounts(xsydPassedCounts);
  351. xsydDeviationRate = (double) xsydPassedCounts / (double) xsydArrayCounts;
  352. totalDeviationRateCounts += xsydArrayCounts;
  353. totalpassedDeviationRateCounts += xsydPassedCounts;
  354. assayQualityDetailRes.setXsydDeviationRate(NumberUtils.getDoublePercentAndNLength(INT_4, xsydDeviationRate, INT_2));
  355. }
  356. assayQualityDetailRes.setTotalDeviationRate(NumberUtils.getDoublePercentAndNLength(INT_4, (double)totalpassedDeviationRateCounts / (double)totalDeviationRateCounts, INT_2));
  357. result.add(assayQualityDetailRes);
  358. });
  359. }
  360. return result;
  361. }
  362. private void addAssayExtra(String assayNo, AssayDetailRes assayDetailRes) {
  363. //分别处理化验设备的名称、水厂的名字字段(没有通过SQL关联查询,数据量大会很慢。。。)
  364. //化验室
  365. List<BizDevice> bizDevices = this.bizDeviceMapper.selectBizDeviceList(BizDevice.builder().deviceNo(assayDetailRes.getDeviceNo()).build());
  366. //水厂
  367. /*List<BizWaterWork> bizWaterWorks = this.bizWaterWorkMapper.selectBizWaterWorkList(BizWaterWork.builder().worksId(assayDetailRes.getDeviceWorks()).build());
  368. if(!CollectionUtils.isEmpty(bizWaterWorks)){
  369. assayDetailRes.setWorksName(bizWaterWorks.get(0).getWorksName());
  370. }*/
  371. if(CollectionUtils.isEmpty(bizDevices)){
  372. log.error("通过化验明细的设备号查询设备时,没有查询到对应的设备信息");
  373. }else{
  374. BizDevice bizDevice = bizDevices.get(0);
  375. assayDetailRes.setDeviceName(bizDevice.getDeviceName());
  376. assayDetailRes.setDeviceWorks(bizDevice.getDeviceWorks());
  377. Long deviceWorks = bizDevice.getDeviceWorks();
  378. if(Objects.isNull(deviceWorks)){
  379. log.error("通过化验结果的化验设备编号查询设备记录时,没有查询到设备记录id,导致无法获取水厂信息");
  380. }else{
  381. BizWaterWork bizWaterWork = this.bizWaterWorkMapper.selectBizWaterWorkByWorksId(deviceWorks);
  382. if(!Objects.isNull(bizWaterWork)){
  383. assayDetailRes.setWorksName(bizWaterWork.getWorksName());
  384. }
  385. }
  386. }
  387. //通过化验编号查询所有的化验明细,然后根据类型计算对应的
  388. List<ZAssayResult> zAssayResults = this.zAssayResultMapper.selectZAssayResultList(ZAssayResult.builder().assayNo(assayNo).assayType("3").build());
  389. calculateRate(assayDetailRes, zAssayResults);
  390. }
  391. private void calculateRate(AssayDetailRes assayDetailRes, List<ZAssayResult> zAssayResults) {
  392. if(!CollectionUtils.isEmpty(zAssayResults)){
  393. //高COD
  394. Optional<ZAssayResult> highCodOptional = zAssayResults.stream().filter(zAssayResult -> "1".equals(zAssayResult.getAssayItem())).findFirst();
  395. if(highCodOptional.isPresent()){
  396. ZAssayResult zAssayResult = highCodOptional.get();
  397. Double resultConcentration = NumberUtils.getDoubleNLength(INT_2, NumberUtils.getDoubleNLength(INT_2, zAssayResult.getResultConcentration()));
  398. if(!Objects.isNull(resultConcentration)){
  399. assayDetailRes.setHighCodResultConcentration(resultConcentration);
  400. Double highCodStandardVal = assayDetailRes.getHighCodStandardVal();
  401. Double val = (resultConcentration - highCodStandardVal) / highCodStandardVal;
  402. assayDetailRes.setHighCodDeviationRate(NumberUtils.getDoublePercentAndNLength(INT_4, val, INT_2));
  403. assayDetailRes.setHighCodDeviationRateNumber(NumberUtils.getDoubleNLength(INT_2, val));
  404. }
  405. }
  406. //低COD
  407. Optional<ZAssayResult> lowCodOptional = zAssayResults.stream().filter(zAssayResult -> "2".equals(zAssayResult.getAssayItem())).findFirst();
  408. if(lowCodOptional.isPresent()){
  409. ZAssayResult zAssayResult = lowCodOptional.get();
  410. Double resultConcentration = NumberUtils.getDoubleNLength(INT_2, zAssayResult.getResultConcentration());
  411. if(!Objects.isNull(resultConcentration)){
  412. assayDetailRes.setLowCodResultConcentration(resultConcentration);
  413. Double lowCodStandardVal = assayDetailRes.getLowCodStandardVal();
  414. Double val = (resultConcentration - lowCodStandardVal) / lowCodStandardVal;
  415. assayDetailRes.setLowCodDeviationRate(NumberUtils.getDoublePercentAndNLength(INT_4, val, INT_2));
  416. assayDetailRes.setLowCodDeviationRateNumber(NumberUtils.getDoubleNLength(INT_2, val));
  417. }
  418. }
  419. //氨氮
  420. Optional<ZAssayResult> andanOptional = zAssayResults.stream().filter(zAssayResult -> "3".equals(zAssayResult.getAssayItem())).findFirst();
  421. if(andanOptional.isPresent()){
  422. ZAssayResult zAssayResult = andanOptional.get();
  423. Double resultConcentration = NumberUtils.getDoubleNLength(INT_2, zAssayResult.getResultConcentration());
  424. if(!Objects.isNull(resultConcentration)){
  425. assayDetailRes.setAnDanResultConcentration(resultConcentration);
  426. Double anDanStandardVal = assayDetailRes.getAnDanStandardVal();
  427. Double val = (resultConcentration - anDanStandardVal) / anDanStandardVal;
  428. assayDetailRes.setAnDanDeviationRate(NumberUtils.getDoublePercentAndNLength(INT_4, val, INT_2));
  429. assayDetailRes.setAnDanDeviationRateNumber(NumberUtils.getDoubleNLength(INT_2, val));
  430. }
  431. }
  432. //总氮
  433. Optional<ZAssayResult> tnOptional = zAssayResults.stream().filter(zAssayResult -> "4".equals(zAssayResult.getAssayItem())).findFirst();
  434. if(tnOptional.isPresent()){
  435. ZAssayResult zAssayResult = tnOptional.get();
  436. Double resultConcentration = NumberUtils.getDoubleNLength(INT_2, zAssayResult.getResultConcentration());
  437. if(!Objects.isNull(resultConcentration)){
  438. assayDetailRes.setTnResultConcentration(resultConcentration);
  439. Double tnStandardVal = assayDetailRes.getTnStandardVal();
  440. Double val = (resultConcentration - tnStandardVal) / tnStandardVal;
  441. assayDetailRes.setTnDeviationRate(NumberUtils.getDoublePercentAndNLength(INT_4, val, INT_2));
  442. assayDetailRes.setTnDeviationRateNumber(NumberUtils.getDoubleNLength(INT_2, val));
  443. }
  444. }
  445. //总磷
  446. Optional<ZAssayResult> tpOptional = zAssayResults.stream().filter(zAssayResult -> "5".equals(zAssayResult.getAssayItem())).findFirst();
  447. if(tpOptional.isPresent()){
  448. ZAssayResult zAssayResult = tpOptional.get();
  449. Double resultConcentration = NumberUtils.getDoubleNLength(INT_2, zAssayResult.getResultConcentration());
  450. if(!Objects.isNull(resultConcentration)){
  451. assayDetailRes.setTpResultConcentration(resultConcentration);
  452. Double tpStandardVal = assayDetailRes.getTpStandardVal();
  453. Double val = (resultConcentration - tpStandardVal) / tpStandardVal;
  454. assayDetailRes.setTpDeviationRate(NumberUtils.getDoublePercentAndNLength(INT_4, val, INT_2));
  455. assayDetailRes.setTpDeviationRateNumber(NumberUtils.getDoubleNLength(INT_2, val));
  456. }
  457. }
  458. //正磷酸盐
  459. Optional<ZAssayResult> zlsyOptional = zAssayResults.stream().filter(zAssayResult -> "6".equals(zAssayResult.getAssayItem())).findFirst();
  460. if(zlsyOptional.isPresent()){
  461. ZAssayResult zAssayResult = zlsyOptional.get();
  462. Double resultConcentration = NumberUtils.getDoubleNLength(INT_2, zAssayResult.getResultConcentration());
  463. if(!Objects.isNull(resultConcentration)){
  464. assayDetailRes.setZlsyResultConcentration(resultConcentration);
  465. Double zlsyStandardVal = assayDetailRes.getZlsyStandardVal();
  466. Double val = (resultConcentration - zlsyStandardVal) / zlsyStandardVal;
  467. assayDetailRes.setZlsyDeviationRate(NumberUtils.getDoublePercentAndNLength(INT_4, val, INT_2));
  468. assayDetailRes.setZlsyDeviationRateNumber(NumberUtils.getDoubleNLength(INT_2, val));
  469. }
  470. }
  471. //亚硝酸盐氮
  472. Optional<ZAssayResult> yxsydOptional = zAssayResults.stream().filter(zAssayResult -> "7".equals(zAssayResult.getAssayItem())).findFirst();
  473. if(yxsydOptional.isPresent()){
  474. ZAssayResult zAssayResult = yxsydOptional.get();
  475. Double resultConcentration = NumberUtils.getDoubleNLength(INT_2, zAssayResult.getResultConcentration());
  476. if(!Objects.isNull(resultConcentration)){
  477. assayDetailRes.setYxsyResultConcentration(resultConcentration);
  478. Double yxsyStandardVal = assayDetailRes.getYxsyStandardVal();
  479. Double val = (resultConcentration - yxsyStandardVal) / yxsyStandardVal;
  480. assayDetailRes.setYxsyDeviationRate(NumberUtils.getDoublePercentAndNLength(INT_4, val, INT_2));
  481. assayDetailRes.setYxsyDeviationRateNumber(NumberUtils.getDoubleNLength(INT_2, val));
  482. }
  483. }
  484. //硝酸盐氮
  485. Optional<ZAssayResult> xsydOptional = zAssayResults.stream().filter(zAssayResult -> "8".equals(zAssayResult.getAssayItem())).findFirst();
  486. if(xsydOptional.isPresent()){
  487. ZAssayResult zAssayResult = xsydOptional.get();
  488. Double resultConcentration = NumberUtils.getDoubleNLength(INT_2, zAssayResult.getResultConcentration());
  489. if(!Objects.isNull(resultConcentration)){
  490. assayDetailRes.setXsydResultConcentration(resultConcentration);
  491. Double xsydStandardVal = assayDetailRes.getXsydStandardVal();
  492. Double val = (resultConcentration - xsydStandardVal) / xsydStandardVal;
  493. assayDetailRes.setXsydDeviationRate(NumberUtils.getDoublePercentAndNLength(INT_4, val, INT_2));
  494. assayDetailRes.setXsydDeviationRateNumber(NumberUtils.getDoubleNLength(INT_2, val));
  495. }
  496. }
  497. }
  498. }
  499. /**
  500. * 额外处理其他的字段 聚合,查询其他表,计算等
  501. *
  502. * @param deviceRes
  503. * @param assayDate
  504. * @param deviceNo
  505. */
  506. private void addDeviceExtra(DeviceRes deviceRes, String assayDate, String deviceNo) {
  507. //查询最近的一条化验记录明细 及 化验统计(结果)
  508. List<ZAssayResult> zAssayResults = this.zAssayResultMapper.selectZAssayResultList(ZAssayResult.builder().resultDate(assayDate).assayType("3").deviceNo(deviceNo).build());
  509. if(!CollectionUtils.isEmpty(zAssayResults)){
  510. int checkTotals = zAssayResults.size();
  511. int passCheckTotals = this.getPassedCounts(zAssayResults);
  512. deviceRes.setAssayTotals(passCheckTotals);
  513. deviceRes.setPassAssayRates(NumberUtils.getDoublePercentAndNLength(INT_4, (double)passCheckTotals / (double)checkTotals, INT_2));//整数除以整数还是整数,所以这里要强转成小数
  514. //获取最新的一条化验明细数据
  515. ZAssayResult zAssayResult = zAssayResults.get(0);
  516. //根据化验类型处理不同的数据
  517. String assayStatus = deviceRes.getAssayStatus();
  518. if("1".equals(assayStatus)){//离线
  519. deviceRes.setLastAssayTime(zAssayResult.getUpdateTime());
  520. }else if("2".equals(assayStatus)){//化验中
  521. deviceRes.setBeginAssayTime(zAssayResult.getUpdateTime());
  522. }
  523. deviceRes.setCurrentTemperature(zAssayResult.getResultWendu());
  524. // deviceRes.setCurrentHumidity(NumberUtils.getDoublePercentAndNLength(INT_4, zAssayResult.getResultShidu(), INT_2));
  525. //2024年10月14日16:55:06 原本就已经乘以100了,如果有值直接拼接%即可
  526. Double resultShidu = zAssayResult.getResultShidu();
  527. if(!Objects.isNull(resultShidu)){
  528. deviceRes.setCurrentHumidity(NumberUtils.getDoubleNLength(INT_2, resultShidu) + "%");
  529. }
  530. //获取最新的一条化验记录 处理化验进度的展示: 因为历史数据有总步进为0的,这种的默认进度就是0处理 只有化验中的才显示进度
  531. String assayNo = zAssayResult.getAssayNo();
  532. if("2".equals(deviceRes.getAssayStatus()) && StringUtils.isNotBlank(assayNo)){
  533. ZAssay zAssay = this.zAssayMapper.selectUniqueRecordByAssayNo(assayNo);
  534. if(!Objects.isNull(zAssay)){
  535. String stepNow = zAssay.getStepNow();
  536. String stepTotal = zAssay.getStepTotal();
  537. if(StringUtils.isBlank(stepNow) || StringUtils.isBlank(stepTotal) || "0".equals(stepNow) || "0".equals(stepTotal)){
  538. deviceRes.setAssayProgress(null);
  539. }else{
  540. deviceRes.setAssayProgress(NumberUtils.getDoublePercentAndNLength(INT_4, Double.parseDouble(stepNow)/Double.parseDouble(stepTotal), INT_2));
  541. }
  542. }
  543. }
  544. //todo 废液量暂时无法计算
  545. }
  546. //因为有重复数据,需要去重
  547. deviceRes.setAssayCounts(this.zAssayMapper.getDistinctCountsByDeviceNoAndDate(assayDate, deviceNo));
  548. }
  549. //判断每个质控样的数是否各个,然后获取汇总的数量
  550. private int getPassedCounts(List<ZAssayResult> zAssayResults) {
  551. boolean passed = false;
  552. int count = 0;
  553. for (ZAssayResult zAssayResult : zAssayResults) {
  554. passed = this.isPassed(zAssayResult);
  555. if (passed) {
  556. count++;//通过 数量加一
  557. }
  558. }
  559. return count;
  560. }
  561. //获取每个质控样的数据是否是合格的
  562. private boolean isPassed(ZAssayResult zAssayResult) {
  563. boolean isPassed = true;//默认是合格的,防止一些极端场景:没有配置范围 范围配置时间过期等等情况
  564. String deviceNo = zAssayResult.getDeviceNo();
  565. if(StringUtils.isBlank(deviceNo))
  566. return isPassed;//无法关联数据,默认合格
  567. //需要通过化验明细里的设备ID找到水厂ID,配置的表需要该参数
  568. List<BizDevice> bizDevices = this.bizDeviceMapper.selectBizDeviceList(BizDevice.builder().deviceNo(deviceNo).build());
  569. if(CollectionUtils.isEmpty(bizDevices)){
  570. return isPassed;//无法查询到水厂,默认合格
  571. }
  572. Date nowDate = DateUtils.getNowDate();
  573. // Date nowDate = DateUtils.parseDate("2024-08-13");
  574. Double resultConcentration = zAssayResult.getResultConcentration();//化验的真实值
  575. //去查询配置的标准值的范围(数据不确认,有可能是多个,获取最后一条数据):
  576. List<ZQualityValue> list = this.zQualityValueMapper.selectZQualityValueList(ZQualityValue.builder().beginTime(nowDate).endTime(nowDate).deviceWorks(bizDevices.get(0).getDeviceWorks()).assayItem(zAssayResult.getAssayItem()).build());
  577. //理论上是只有一个的
  578. if(!CollectionUtils.isEmpty(list)){
  579. ZQualityValue zQualityValue = list.get(0);//获取最新的一条,防止有多条数据的情况
  580. Double lowValue = zQualityValue.getLowValue();
  581. Double highValue = zQualityValue.getHighValue();
  582. if(!Objects.isNull(resultConcentration) && !Objects.isNull(lowValue) && !Objects.isNull(highValue)){
  583. isPassed = resultConcentration >= lowValue && resultConcentration <= highValue;
  584. }
  585. }
  586. return isPassed;
  587. }
  588. public static void main(String[] args) {
  589. List list = new ArrayList<>();
  590. list.add(1);
  591. list.add(1);
  592. System.out.println(list.stream().count());
  593. System.out.println(DateUtils.getDate());
  594. }
  595. }