123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454 |
- package com.huaxia.imes.service;
- import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
- import com.baomidou.mybatisplus.core.metadata.IPage;
- import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
- import com.baomidou.mybatisplus.extension.service.IService;
- import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
- import com.huaxia.comm.domain.imes.MesLine;
- import com.huaxia.imes.mapper.MesLineMapper;
- import com.huaxia.imes.pojo.MesLineBO;
- import com.huaxia.imes.pojo.MesLineVO;
- import com.ruoyi.common.annotation.DataSource;
- import com.ruoyi.common.core.domain.R;
- import com.ruoyi.common.enums.DataSourceType;
- import com.ruoyi.common.utils.SecurityUtils;
- import com.ruoyi.common.utils.StringUtils;
- import lombok.AllArgsConstructor;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- import org.springframework.util.Assert;
- import java.math.BigDecimal;
- import java.math.RoundingMode;
- import java.time.*;
- import java.time.format.DateTimeFormatter;
- import java.time.format.TextStyle;
- import java.time.temporal.TemporalAdjusters;
- import java.util.*;
- /**
- * @author zx
- * @since 2024年10月29日
- */
- @Service
- @Transactional(rollbackFor = Exception.class)
- @Slf4j
- @AllArgsConstructor
- @DataSource(DataSourceType.SLAVE)
- public class MesLineService extends ServiceImpl<MesLineMapper, MesLine> implements IService<MesLine> {
- private MesLineMapper mesLineMapper;
- /**
- * 分页查询
- *
- * @param bo
- * @return
- */
- public IPage<MesLineVO> queryList(MesLineBO bo, int pageNum, int pageSize) {
- int offset = (pageNum - 1) * pageSize;
- Map<String, Object> params = new HashMap<>();
- params.put("boy", bo);
- params.put("offset", offset);
- params.put("pageSize", pageSize);
- // 获取总记录数
- int total = mesLineMapper.countByParams(params);
- //开始分页查询
- List<MesLineVO> records = mesLineMapper.queryListPage(params);
- // 创建并返回 Page 对象
- return new Page<MesLineVO>(pageNum, pageSize, total).setRecords(records);
- }
- /**
- * 新增数据
- *
- * @param boy
- */
- public void add(MesLine boy) {
- //校验数据
- this.check(boy);
- //判断创建时间是否为空
- if (boy.getCreateTime() == null) {
- boy.setCreateTime(new Date());
- } else {
- // 转换为 Instant 进行比较,避免时区问题
- Instant createInstant = boy.getCreateTime().toInstant();
- Instant nowInstant = Instant.now();
- Assert.isTrue(!createInstant.isAfter(nowInstant), "500-创建时间不能大于当前时间");
- }
- //通过产线名称和创建如期去查询产线数据是否存在
- LambdaQueryWrapper<MesLine> wr = new LambdaQueryWrapper<>();
- wr.eq(MesLine::getLineName, boy.getLineName());
- wr.eq(MesLine::getCreateTime, boy.getCreateTime());
- //序列化时间格式 年月日
- String format = boy.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate().toString();
- long aLong = this.count(wr);
- Assert.isTrue(aLong == 0, String.format("500-产线%s-%s已存在", boy.getLineName(), format));
- //获取登录人信息
- boy.setCreateBy(SecurityUtils.getUsername());
- this.save(boy);
- }
- /**
- * 修改数据
- *
- * @param boy
- */
- public void edit(MesLine boy) {
- //检验数据
- this.check(boy);
- //判断一下时间
- Assert.isTrue(boy.getCreateTime() != null, "500-时间不能为空");
- // 转换为 Instant 进行比较,避免时区问题
- Instant createInstant = boy.getCreateTime().toInstant();
- Instant nowInstant = Instant.now();
- Assert.isTrue(!createInstant.isAfter(nowInstant), "500-生产时间不能大于当前时间");
- boy.setUpdateTime(new Date())
- .setUpdateBy(SecurityUtils.getUsername());
- this.updateById(boy);
- }
- /**
- * 新增数据时校验数据
- *
- * @param boy
- */
- private void check(MesLine boy) {
- Assert.isTrue(StringUtils.isNotBlank(boy.getLineName()), "500-产线名称不能为空");
- Assert.isTrue(boy.getCurrentQty() != null && BigDecimal.valueOf(boy.getCurrentQty()).compareTo(BigDecimal.ZERO) > 0, "500-当日产量必须大于0");
- }
- /**
- * 删除数据
- *
- * @param ids
- */
- public void delete(Long[] ids) {
- //遍历id匹配数据
- for (Long id : ids) {
- MesLine mesLine = mesLineMapper.selectById(id);
- Assert.isTrue(mesLine != null, "500-数据不存在");
- mesLineMapper.deleteById(id);
- }
- }
- /**
- * 按天来统计数据
- *
- * @return
- */
- public R<Map<String, Map<String, Map<String, Object>>>> countDay() {
- //获取当前时间
- LocalDate now = LocalDate.now();
- // 计算本周的星期一
- LocalDate mondayOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
- // 计算本周的星期天
- LocalDate sundayOfWeek = now.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
- //获取星期一致星期天的数据
- LambdaQueryWrapper<MesLine> wr = new LambdaQueryWrapper<>();
- wr.between(MesLine::getCreateTime, mondayOfWeek, sundayOfWeek);
- List<MesLine> boy = mesLineMapper.selectList(wr);
- //格式 key:产线名称 value:星期几 key:产量 value:数量
- Map<String, Map<String, Map<String, Object>>> newMap = new LinkedHashMap<>();
- // 初始化Map中的键,并设置默认值为0
- for (DayOfWeek dayOfWeek : DayOfWeek.values()) {
- String dayOfWeekName = dayOfWeek.getDisplayName(TextStyle.FULL, Locale.CHINA);
- if (boy != null && !boy.isEmpty()) {
- for (MesLine mesLine : boy) {
- String lineName = mesLine.getLineName();
- if (StringUtils.isBlank(lineName)) {
- continue;
- }
- Map<String, Map<String, Object>> dayMap = newMap.computeIfAbsent(lineName, k -> new LinkedHashMap<>());
- Map<String, Object> statsMap = dayMap.computeIfAbsent(dayOfWeekName, k -> new HashMap<String, Object>() {{
- put("产量", 0L);
- }});
- }
- }
- }
- //遍历集合
- if (boy != null && !boy.isEmpty()) {
- for (MesLine mesLine : boy) {
- // 获取星期几
- LocalDate date = mesLine.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
- String week = date.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.CHINA);
- Long count = mesLine.getCurrentQty(); // 获取产量
- String lineName = mesLine.getLineName(); // 获取产线名称
- if (StringUtils.isBlank(lineName)) {
- continue;
- }
- //获取内层
- Map<String, Map<String, Object>> dayMap = newMap.get(lineName);
- Map<String, Object> statsMap = dayMap.get(week);
- // 更新内层Map中的产量
- Long totalOutPut = (Long) statsMap.getOrDefault("产量", 0L);
- totalOutPut += count;
- statsMap.put("产量", totalOutPut);
- }
- }
- return R.ok(newMap);
- }
- /**
- * 统计本周 每条产线数据
- *
- * @return
- */
- public R<Map<String, Map<String, Object>>> queryDay() {
- //获取当前时间
- LocalDate now = LocalDate.now();
- //计算本周的星期一
- LocalDate mondayOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
- // 计算本周的星期天
- LocalDate sundayOfWeek = now.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
- //获取星期一致星期天的数据
- LambdaQueryWrapper<MesLine> wr = new LambdaQueryWrapper<>();
- wr.between(MesLine::getCreateTime, mondayOfWeek, sundayOfWeek);
- List<MesLine> boy = mesLineMapper.selectList(wr);
- // 创建一个LinkedHashMap用于存储统计结果
- Map<String, Map<String, Object>> lineSummary = new LinkedHashMap<>();
- // 遍历集合,统计每条产线的数据
- if (boy != null && !boy.isEmpty()) {
- for (MesLine mesLine : boy) {
- try {
- //获取产线名称
- String lineName = mesLine.getLineName();
- LocalDate createTime = mesLine.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
- if (createTime.isAfter(mondayOfWeek.minusDays(1)) && createTime.isBefore(sundayOfWeek.plusDays(1))) {
- Map<String, Object> lineData = lineSummary.computeIfAbsent(lineName, k -> new HashMap<>());
- //累加产量
- Long totalOutput = (Long) lineData.getOrDefault("产量", 0L);
- Long count = mesLine.getCurrentQty();//产量=产量(包含合格数量)+不合格数量
- Long poorQty = mesLine.getPoorQty();//不合格数量
- totalOutput += (count + poorQty);
- lineData.put("产量", totalOutput);
- //累加不合格数量
- Long totalPoorQty = (Long) lineData.getOrDefault("不合格数量", 0L);
- Long currentPoorQty = mesLine.getPoorQty();
- totalPoorQty += currentPoorQty;
- lineData.put("不合格数量", totalPoorQty);
- //计算合格数量
- Long totalQualifiedQty = (Long) lineData.getOrDefault("合格数量", 0L);
- totalQualifiedQty += count;
- lineData.put("合格数量", totalQualifiedQty);
- //更新合格率
- if (totalOutput > 0) {
- double qualificationRate = ((double) totalQualifiedQty / (double) totalOutput) * 100;
- lineData.put("合格率", String.format("%.2f%%", qualificationRate));
- } else {
- lineData.put("合格率", "0.00%");
- }
- }
- } catch (Exception e) {
- log.warn("数据转换异常", e);
- }
- }
- }
- return R.ok(lineSummary);
- }
- /**
- * 获取本月总产量
- *
- * @return
- */
- public R<Map<String, Long>> getMonthTotal() {
- //获取当前时间
- LocalDate now = LocalDate.now();
- //获取本月的开始时间和结束时间
- LocalDate startOfMonth = now.withDayOfMonth(1);
- LocalDate endOfMonth = now.withDayOfMonth(now.lengthOfMonth());
- //按月份查询数据
- LambdaQueryWrapper<MesLine> wr = new LambdaQueryWrapper<>();
- wr.between(MesLine::getCreateTime, startOfMonth, endOfMonth);
- List<MesLine> list = mesLineMapper.selectList(wr);
- // 开始累加本月各产线总产量
- Map<String, Long> totalByLine = new HashMap<>();
- if (list != null && !list.isEmpty()) {
- for (MesLine mesLine : list) {
- String lineName = mesLine.getLineName();
- Long currentQty = mesLine.getCurrentQty();
- if (totalByLine.containsKey(lineName)) {
- totalByLine.put(lineName, totalByLine.get(lineName) + currentQty);
- } else {
- totalByLine.put(lineName, currentQty);
- }
- }
- }
- return R.ok(totalByLine);
- }
- /**
- * 获取合格率 星期1-7
- *
- * @return
- */
- public R< Map<String, Map<String, Map<String, Object>>>> getPassRate() {
- //获取当前日期
- LocalDate now = LocalDate.now();
- //计算本周的星期一
- LocalDate mondayOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
- // 计算本周的星期天
- LocalDate sundayOfWeek = now.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
- //获取星期一致星期天的数据
- LambdaQueryWrapper<MesLine> wr = new LambdaQueryWrapper<>();
- wr.between(MesLine::getCreateTime, mondayOfWeek, sundayOfWeek);
- List<MesLine> boy = mesLineMapper.selectList(wr);
- //存储的数据格式 key:产线名称 value:星期几 key:产量,value:数量
- Map<String, Map<String, Map<String, Object>>> map = new LinkedHashMap<>();
- //初始化每周的数据
- for (DayOfWeek dayOfWeek : DayOfWeek.values()) {
- String dayOfWeekName = dayOfWeek.getDisplayName(TextStyle.FULL, Locale.CHINA);
- if (boy != null && !boy.isEmpty()) {
- for (MesLine mesLine : boy) {
- //获取产线名称
- String lineName = mesLine.getLineName();
- if (StringUtils.isBlank(lineName)) {
- continue;
- }
- Map<String, Map<String, Object>> dayMap = map.computeIfAbsent(lineName, k -> new LinkedHashMap<>());
- dayMap.putIfAbsent(dayOfWeekName, new HashMap<String, Object>() {{
- put("产量", 0L);
- put("不合格数量", 0L);
- put("合格数量", 0L);
- put("合格率", "0.00%");
- }});
- }
- }
- }
- // 遍历集合,统计每条产线的数据
- if (boy != null && !boy.isEmpty()) {
- for (MesLine mesLine : boy) {
- // 获取创建日期
- LocalDate createTime = mesLine.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
- if (createTime.isAfter(mondayOfWeek.minusDays(1)) && createTime.isBefore(sundayOfWeek.plusDays(1))) {
- DayOfWeek dayOfWeek = createTime.getDayOfWeek();
- String dayOfWeekName = dayOfWeek.getDisplayName(TextStyle.FULL, Locale.CHINA);
- String lineName = mesLine.getLineName();
- if (StringUtils.isBlank(lineName)) {
- continue;
- }
- Map<String, Map<String, Object>> dayMap = map.get(lineName);
- Map<String, Object> stats = dayMap.get(dayOfWeekName);
- // 累加总产量
- Long totalOutput = (Long) stats.getOrDefault("产量", 0L);
- Long count = mesLine.getCurrentQty();//产量+不合格数
- Long poorQty = mesLine.getPoorQty();//不合格数量
- totalOutput += (count + poorQty);
- stats.put("产量", totalOutput);
- // 累加不合格数量
- Long totalPoorQty = (Long) stats.getOrDefault("不合格数量", 0L);
- totalPoorQty += mesLine.getPoorQty();
- stats.put("不合格数量", totalPoorQty);
- //计算合格数量
- Long totalQualifiedQty = (Long) stats.getOrDefault("合格数量", 0L);
- totalQualifiedQty += count;
- stats.put("合格数量", totalQualifiedQty);
- // 更新合格率
- if (totalOutput > 0) {
- double qualificationRate = ((double) totalQualifiedQty / (double) totalOutput) * 100;
- stats.put("合格率", String.format(Locale.US, "%.2f%%", qualificationRate));
- } else {
- stats.put("合格率", "0.00%");
- }
- }
- }
- }
- return R.ok(map);
- }
- /**
- * 获取人均产出(按月)
- *
- * @return
- */
- public R<Map<String, Map<String, Map<String, Object>>>> getWorkerQty() {
- //获取当前系统时间
- LocalDate now = LocalDate.now();
- //计算当月的第一天
- LocalDate firstDayOfMonth = now.withDayOfMonth(1);
- //计算当月的最后一天
- LocalDate lastDayOfMonth = now.withDayOfMonth(now.lengthOfMonth());
- //获取当月的数据
- LambdaQueryWrapper<MesLine> wr = new LambdaQueryWrapper<>();
- wr.between(MesLine::getCreateTime, firstDayOfMonth, lastDayOfMonth);
- List<MesLine> boy = mesLineMapper.selectList(wr);
- //创建Map 用于存储统计结果 日期:产线 每日产量 每日工作人数 人均产出
- Map<String, Map<String, Map<String, Object>>> weekMap = new LinkedHashMap<>();
- //初始化 每月1号到当前时间
- LocalDate currentDate = firstDayOfMonth;
- while (currentDate.isBefore(now.plusDays(1))) {
- String dateString = currentDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
- if (boy != null && !boy.isEmpty()) {
- for (MesLine mesLine : boy) {
- String lineName = mesLine.getLineName();
- Map<String, Map<String, Object>> dayStats = weekMap.computeIfAbsent(lineName, k -> new TreeMap<>(Comparator.naturalOrder()));
- dayStats.putIfAbsent(dateString, new HashMap<String, Object>() {{
- put("产量", 0L);
- put("每日工作人数", 0);
- put("人均产出", BigDecimal.ZERO);
- }});
- }
- currentDate = currentDate.plusDays(1);
- }
- }
- //遍历集合 获取某条线产量
- if (boy != null && !boy.isEmpty()) {
- for (MesLine mesLine : boy) {
- //获取产线名称
- String lineName = mesLine.getLineName();
- // 获取创建日期
- LocalDate createTime = mesLine.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
- //序列化日期格式 年月日
- String dateString = createTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
- //初始化数据
- Map<String, Map<String, Object>> dayStats = weekMap.get(lineName);
- Map<String, Object> lineStats = dayStats.get(dateString);
- //累加产量
- Long totalOutPut = (Long) lineStats.getOrDefault("产量", 0L);
- Long count = mesLine.getCurrentQty();//产量
- totalOutPut += count;//产量
- lineStats.put("产量", totalOutPut);
- //累加每条线的投产人员
- Integer workerQty = (Integer) lineStats.getOrDefault("每日工作人数", 0);
- workerQty += mesLine.getWorkerQty();
- lineStats.put("每日工作人数", workerQty);
- }
- // 计算每个产线每天人均产出
- for (Map.Entry<String, Map<String, Map<String, Object>>> entry : weekMap.entrySet()) {
- String lineName = entry.getKey();
- for (Map.Entry<String, Map<String, Object>> lineEntry : entry.getValue().entrySet()) {
- String dateString = lineEntry.getKey();
- Long totalOutput = (Long) lineEntry.getValue().get("产量");
- Integer workerQty = (Integer) lineEntry.getValue().get("每日工作人数");
- //计算平均人均产出
- if (workerQty > 0) {
- BigDecimal averageOutputPerPerson = BigDecimal.valueOf(totalOutput).divide(BigDecimal.valueOf(workerQty), 0, RoundingMode.HALF_UP);
- lineEntry.getValue().put("人均产出", averageOutputPerPerson);
- } else {
- lineEntry.getValue().put("人均产出", BigDecimal.ZERO);
- }
- }
- }
- }
- return R.ok(weekMap);
- }
- }
|