¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.shlanbao.qms.service.impl; |
| | | |
| | | import cn.hutool.core.date.DateUtil; |
| | | import cn.shlanbao.qms.domain.LbBatch; |
| | | import cn.shlanbao.qms.domain.LbSensorResult; |
| | | import cn.shlanbao.qms.domain.LbTestResult; |
| | | import cn.shlanbao.qms.domain.bo.LbBatchBo; |
| | | import cn.shlanbao.qms.domain.vo.LbBatchVo; |
| | | import cn.shlanbao.qms.domain.vo.LbSensorResultVo; |
| | | import cn.shlanbao.qms.domain.vo.LbTestResultVo; |
| | | import cn.shlanbao.qms.mapper.LbBatchMapper; |
| | | import cn.shlanbao.qms.mapper.LbSensorResultMapper; |
| | | import cn.shlanbao.qms.mapper.LbTestResultMapper; |
| | | import cn.shlanbao.qms.service.ILbQualityService; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.dromara.common.core.utils.StringUtils; |
| | | import org.dromara.common.mybatis.core.page.PageQuery; |
| | | import org.dromara.common.mybatis.core.page.TableDataInfo; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.util.CollectionUtils; |
| | | |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @RequiredArgsConstructor |
| | | @Service |
| | | public class LbQualityServiceImpl implements ILbQualityService { |
| | | private final LbBatchMapper batchMapper; |
| | | private final LbSensorResultMapper sensorResultMapper; |
| | | private final LbTestResultMapper testResultMapper; |
| | | |
| | | @Override |
| | | public Map<String, Object> queryQualityHealth() { |
| | | Map<String, Object> result = new HashMap<>(2); |
| | | |
| | | // è·åå½å年份 |
| | | int currentYear = DateUtil.year(DateUtil.date()); |
| | | |
| | | // æå»ºæ¥è¯¢æ¡ä»¶ï¼æ¥è¯¢å½åå¹´ä»½çæ°æ® |
| | | QueryWrapper<LbSensorResult> queryWrapper = new QueryWrapper<>(); |
| | | queryWrapper.likeRight("batch_code", String.valueOf(currentYear)); |
| | | |
| | | // æ¥è¯¢æ°æ® |
| | | List<LbSensorResultVo> sensorResultList = sensorResultMapper.selectVoList(queryWrapper); |
| | | |
| | | if (CollectionUtils.isEmpty(sensorResultList)) { |
| | | result.put("xAxis", Collections.emptyList()); |
| | | result.put("yAxis", Collections.emptyList()); |
| | | return result; |
| | | } |
| | | |
| | | // æå¹´æåç»ï¼batch_codeå6ä½ï¼ |
| | | Map<String, List<LbSensorResultVo>> monthlyGroup = sensorResultList.stream() |
| | | .filter(vo -> vo != null && StringUtils.isNotBlank(vo.getBatchCode())) |
| | | .collect(Collectors.groupingBy(vo -> vo.getBatchCode().substring(0, 6))); |
| | | |
| | | // åå¤xè½´åyè½´æ°æ® |
| | | List<String> xAxis = new ArrayList<>(); |
| | | List<Map<String, Object>> yAxis = new ArrayList<>(); |
| | | |
| | | // å¤çæ¯ä¸ªæçæ°æ® |
| | | monthlyGroup.entrySet().stream() |
| | | .sorted(Map.Entry.comparingByKey()) |
| | | .forEach(entry -> { |
| | | String monthKey = entry.getKey(); |
| | | List<LbSensorResultVo> monthlyData = entry.getValue(); |
| | | |
| | | if (CollectionUtils.isEmpty(monthlyData)) { |
| | | return; |
| | | } |
| | | |
| | | // æ·»å xè½´æ°æ® |
| | | xAxis.add(monthKey.substring(4, 6) + "æ"); |
| | | |
| | | // 计ç®åæ ¼ç |
| | | long passCount = monthlyData.stream() |
| | | .filter(vo -> "OK".equalsIgnoreCase(vo.getJudgeResult())) |
| | | .count(); |
| | | |
| | | double passRate = (double) passCount / monthlyData.size(); |
| | | |
| | | // æ·»å yè½´æ°æ® |
| | | Map<String, Object> monthData = new HashMap<>(1); |
| | | monthData.put("value", String.format("%.1f", (passRate * 10))); |
| | | yAxis.add(monthData); |
| | | }); |
| | | |
| | | result.put("xAxis", xAxis); |
| | | result.put("yAxis", yAxis); |
| | | |
| | | return result; |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public TableDataInfo<LbBatchVo> queryBatchList(LbBatchBo bo, PageQuery pageQuery) { |
| | | LambdaQueryWrapper<LbBatch> lqw = buildQueryWrapper(bo); |
| | | Page<LbBatchVo> result = batchMapper.selectVoPage(pageQuery.build(), lqw); |
| | | |
| | | List<LbBatchVo> records = result.getRecords(); |
| | | if (records.isEmpty()) { |
| | | return TableDataInfo.build(result); |
| | | } |
| | | |
| | | List<String> batchCodes = records.stream() |
| | | .map(LbBatchVo::getBatchCode) |
| | | .collect(Collectors.toList()); |
| | | |
| | | LambdaQueryWrapper<LbSensorResult> sensorResultWrapper = new LambdaQueryWrapper<>(); |
| | | sensorResultWrapper.in(LbSensorResult::getBatchCode, batchCodes); |
| | | |
| | | List<LbSensorResultVo> sensorResultVoList = sensorResultMapper.selectVoList(sensorResultWrapper); |
| | | |
| | | // 䏿¬¡æ§ç»è®¡OKåæ»æ° |
| | | Map<String, BatchStats> statsMap = sensorResultVoList.stream() |
| | | .collect(Collectors.groupingBy( |
| | | LbSensorResultVo::getBatchCode, |
| | | Collectors.collectingAndThen( |
| | | Collectors.toList(), |
| | | list -> { |
| | | long okCount = list.stream() |
| | | .filter(vo -> "OK".equals(vo.getJudgeResult())) |
| | | .count(); |
| | | return new BatchStats(okCount, list.size()); |
| | | } |
| | | ) |
| | | )); |
| | | |
| | | // æ¹é设置ç»è®¡ç»æ |
| | | records.forEach(item -> { |
| | | BatchStats stats = statsMap.get(item.getBatchCode()); |
| | | if (stats != null) { |
| | | item.setOkNum(stats.okCount); |
| | | item.setNgNum(stats.totalCount - stats.okCount); |
| | | } else { |
| | | // å¦ææ²¡æç¸å
³æ£æµç»æï¼è®¾ç½®ä¸º0 |
| | | item.setOkNum(0L); |
| | | item.setNgNum(item.getNum()); |
| | | } |
| | | }); |
| | | |
| | | return TableDataInfo.build(result); |
| | | } |
| | | |
| | | @Override |
| | | public Map<String, Object> queryPwbatchList() { |
| | | Map<String, Object> res = new HashMap<>(2); |
| | | // åå¤xè½´åyè½´æ°æ® |
| | | List<String> xAxis = new ArrayList<>(); |
| | | List<Object> yAxis = new ArrayList<>(); |
| | | |
| | | LambdaQueryWrapper<LbBatch> dateQuery = Wrappers.lambdaQuery(); |
| | | dateQuery.select(LbBatch::getBatchTime) |
| | | .groupBy(LbBatch::getBatchTime) |
| | | .orderByDesc(LbBatch::getBatchTime) // ä¿æååºæ¥è¯¢æè¿7天 |
| | | .last("LIMIT 30"); |
| | | |
| | | List<LbBatchVo> dateVos = batchMapper.selectVoList(dateQuery); |
| | | |
| | | // ä» Vo å¯¹è±¡ä¸æå batchTime |
| | | List<Date> recentDates = dateVos.stream() |
| | | .map(LbBatchVo::getBatchTime) |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toList()); |
| | | |
| | | LambdaQueryWrapper<LbBatch> lqw = Wrappers.lambdaQuery(); |
| | | lqw.in(LbBatch::getBatchTime, recentDates) |
| | | .orderByAsc(LbBatch::getBatchTime); // è¿éæ¹ä¸ºæ£åºï¼ç¡®ä¿æ°æ®ææ¥æé¡ºåº |
| | | |
| | | List<LbBatchVo> records = batchMapper.selectVoList(lqw); |
| | | |
| | | List<String> batchCodes = records.stream() |
| | | .map(LbBatchVo::getBatchCode) |
| | | .collect(Collectors.toList()); |
| | | |
| | | LambdaQueryWrapper<LbSensorResult> sensorResultWrapper = new LambdaQueryWrapper<>(); |
| | | sensorResultWrapper.in(LbSensorResult::getBatchCode, batchCodes); |
| | | |
| | | List<LbSensorResultVo> sensorResultVoList = sensorResultMapper.selectVoList(sensorResultWrapper); |
| | | |
| | | // è®¡ç®æ¯ä¸ªæ¥æçOKæ¯ä¾ |
| | | Map<Date, Double> dateOkRatioMap = sensorResultVoList.stream() |
| | | .collect(Collectors.groupingBy( |
| | | result -> { |
| | | String batchCode = result.getBatchCode(); |
| | | return records.stream() |
| | | .filter(record -> record.getBatchCode().equals(batchCode)) |
| | | .findFirst() |
| | | .map(LbBatchVo::getBatchTime) |
| | | .orElse(null); |
| | | }, |
| | | Collectors.collectingAndThen( |
| | | Collectors.toList(), |
| | | list -> { |
| | | long okCount = list.stream() |
| | | .filter(result -> "ok".equalsIgnoreCase(result.getJudgeResult())) |
| | | .count(); |
| | | return list.size() > 0 ? (double) okCount / list.size() : 0.0; |
| | | } |
| | | ) |
| | | )) |
| | | .entrySet().stream() |
| | | .filter(entry -> entry.getKey() != null) |
| | | .sorted(Map.Entry.<Date, Double>comparingByKey()) // æ¹ä¸ºæ£åºæåº |
| | | .collect(Collectors.toMap( |
| | | Map.Entry::getKey, |
| | | Map.Entry::getValue, |
| | | (e1, e2) -> e1, |
| | | LinkedHashMap::new |
| | | )); |
| | | |
| | | // è¿æ»¤æyAxiså°äº80çæ°æ® |
| | | dateOkRatioMap.entrySet().stream() |
| | | .filter(entry -> { |
| | | double ratio = entry.getValue() * 100; // 转æ¢ä¸ºç¾åæ¯ |
| | | return ratio >= 80; // åªä¿ç大äºçäº80çæ°æ® |
| | | }) |
| | | .forEach(entry -> { |
| | | Date date = entry.getKey(); |
| | | double ratio = entry.getValue() * 100; // 转æ¢ä¸ºç¾åæ¯ |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); |
| | | xAxis.add(sdf.format(date)); |
| | | yAxis.add(String.format("%.1f", ratio)); |
| | | }); |
| | | |
| | | res.put("xAxis", xAxis); |
| | | res.put("yAxis", yAxis); |
| | | |
| | | return res; |
| | | } |
| | | |
| | | @Override |
| | | public Map<String, Object> queryNgrankList() { |
| | | Map<String, Object> res = new HashMap<>(2); |
| | | LambdaQueryWrapper<LbTestResult> lqwGroup = Wrappers.lambdaQuery(); |
| | | lqwGroup.select(LbTestResult::getBatchCode) |
| | | .groupBy(LbTestResult::getBatchCode) |
| | | .orderByDesc(LbTestResult::getBatchCode) |
| | | .last("LIMIT 30"); |
| | | |
| | | List<LbTestResultVo> groupResultVos = testResultMapper.selectVoList(lqwGroup); |
| | | List<String> batchCodeList = groupResultVos.stream() |
| | | .map(LbTestResultVo::getBatchCode) |
| | | .collect(Collectors.toList()); |
| | | LambdaQueryWrapper<LbTestResult> lqw = Wrappers.lambdaQuery(); |
| | | lqw.in(LbTestResult::getBatchCode, batchCodeList); |
| | | lqw.eq(LbTestResult::getTestResult, "NG"); |
| | | List<LbTestResultVo> testResultVos = testResultMapper.selectVoList(lqw); |
| | | // 1. ætestItemåç»å¹¶ç»è®¡æ°éï¼æ¯è¡è®¡ä¸º1ï¼ |
| | | Map<String, Long> countByTestItem = testResultVos.stream() |
| | | .filter(result -> "NG".equalsIgnoreCase(result.getTestResult())) |
| | | .collect(Collectors.groupingBy( |
| | | LbTestResultVo::getTestItem, |
| | | Collectors.counting() |
| | | )); |
| | | |
| | | // 2. ææ°ééåºæåºå¹¶åå5大 |
| | | List<Map.Entry<String, Long>> top5Entries = countByTestItem.entrySet().stream() |
| | | .sorted(Map.Entry.<String, Long>comparingByValue().reversed()) |
| | | .limit(5) |
| | | .collect(Collectors.toList()); |
| | | |
| | | // 3. çæxAxisåyAxisæ°ç» |
| | | String[] xAxis = top5Entries.stream() |
| | | .map(Map.Entry::getKey) |
| | | .toArray(String[]::new); |
| | | |
| | | Long[] yAxis = top5Entries.stream() |
| | | .map(Map.Entry::getValue) |
| | | .toArray(Long[]::new); |
| | | |
| | | res.put("xAxis", xAxis); |
| | | res.put("yAxis", yAxis); |
| | | return res; |
| | | } |
| | | |
| | | // å
é¨ç»è®¡ç±» |
| | | private static class BatchStats { |
| | | long okCount; |
| | | long totalCount; |
| | | |
| | | BatchStats(long okCount, long totalCount) { |
| | | this.okCount = okCount; |
| | | this.totalCount = totalCount; |
| | | } |
| | | } |
| | | |
| | | |
| | | private LambdaQueryWrapper<LbBatch> buildQueryWrapper(LbBatchBo bo) { |
| | | Map<String, Object> params = bo.getParams(); |
| | | LambdaQueryWrapper<LbBatch> lqw = Wrappers.lambdaQuery(); |
| | | lqw.eq(StringUtils.isNotBlank(bo.getBatchCode()), LbBatch::getBatchCode, bo.getBatchCode()); |
| | | lqw.eq(StringUtils.isNotBlank(bo.getProdModel()), LbBatch::getProdModel, bo.getProdModel()); |
| | | lqw.eq(StringUtils.isNotBlank(bo.getDeviceCode()), LbBatch::getDeviceCode, bo.getDeviceCode()); |
| | | lqw.eq(bo.getUserId() != null, LbBatch::getUserId, bo.getUserId()); |
| | | lqw.eq(bo.getNum() != null, LbBatch::getNum, bo.getNum()); |
| | | lqw.orderByDesc(LbBatch::getBatchCode); |
| | | if (params != null && params.containsKey("startTime") && params.containsKey("endTime")) { |
| | | lqw.between(LbBatch::getBatchTime, params.get("startTime"), params.get("endTime")); |
| | | } |
| | | return lqw; |
| | | } |
| | | |
| | | } |