Преглед изворни кода

Merge branch 'fu-normal-push' of uskycloud/usky-modules into master

gez пре 2 месеци
родитељ
комит
ed5744805d

+ 60 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/controller/web/PmTimeConfController.java

@@ -0,0 +1,60 @@
+package com.usky.iot.controller.web;
+
+
+import com.usky.common.core.bean.CommonPage;
+import com.usky.iot.domain.PmWorkReport;
+import com.usky.iot.service.PmTimeConfService;
+import com.usky.iot.service.vo.PmSubmitCountResponseVO;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.LocalDate;
+
+/**
+ * <p>
+ * 工作报告提交时间配置表 前端控制器
+ * </p>
+ *
+ * @author fu
+ * @since 2025-01-10
+ */
+@RestController
+@RequestMapping("/pmTimeConf")
+public class PmTimeConfController {
+
+    @Autowired
+    private PmTimeConfService pmTimeConfService;
+
+    /**
+     * 提交统计
+     * @param submitDate 统计日期
+     * @return 统计结果
+     */
+    @GetMapping("/submitCount")
+    public PmSubmitCountResponseVO submitCount(@RequestParam(value = "submitDate", required = false) String submitDate) {
+        if (submitDate == null || submitDate.isEmpty()) {
+            submitDate = LocalDate.now().toString();
+        }
+        return pmTimeConfService.submitCount(submitDate);
+    }
+
+    @GetMapping("/submitPage")
+    public CommonPage<Object> submitPage(@RequestParam(value = "queryType", required = false, defaultValue = "0") Integer queryType,
+                                         @RequestParam(value = "submitDate", required = false) String submitDate,
+                                         @RequestParam(value = "reportId", required = false) Integer reportId,
+                                         @RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
+                                         @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize) {
+        if (StringUtils.isBlank(submitDate)) {
+            submitDate = LocalDate.now().toString();
+        }
+        return pmTimeConfService.submitPage(submitDate, queryType, reportId, pageNum, pageSize);
+    }
+
+}
+

+ 87 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/domain/PmTimeConf.java

@@ -0,0 +1,87 @@
+package com.usky.iot.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.time.LocalTime;
+import java.time.LocalDateTime;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 提交时间配置表
+ * </p>
+ *
+ * @author fu
+ * @since 2025-01-10
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class PmTimeConf implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 时间配置表主键ID
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 开始提交时间
+     */
+    private LocalTime startTime;
+
+    /**
+     * 正常提交时间
+     */
+    private LocalTime onTime;
+
+    /**
+     * 结束提交时间
+     */
+    private LocalTime endTime;
+
+    /**
+     * 配置名称
+     */
+    private String confName;
+
+    /**
+     * 配置类型(PM:工作报告提交时间配置)
+     */
+    private String confType;
+
+    /**
+     * 创建者
+     */
+    private String createBy;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新者
+     */
+    private String updateBy;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+
+    /**
+     * 部门ID
+     */
+    private Long deptId;
+
+    /**
+     * 租户ID
+     */
+    private Integer tenantId;
+
+
+}

+ 16 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/mapper/PmTimeConfMapper.java

@@ -0,0 +1,16 @@
+package com.usky.iot.mapper;
+
+import com.usky.iot.domain.PmTimeConf;
+import com.usky.common.mybatis.core.CrudMapper;
+
+/**
+ * <p>
+ * 工作报告提交时间配置表 Mapper 接口
+ * </p>
+ *
+ * @author fu
+ * @since 2025-01-10
+ */
+public interface PmTimeConfMapper extends CrudMapper<PmTimeConf> {
+
+}

+ 31 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/service/PmTimeConfService.java

@@ -0,0 +1,31 @@
+package com.usky.iot.service;
+
+import com.usky.common.core.bean.CommonPage;
+import com.usky.iot.domain.PmTimeConf;
+import com.usky.common.mybatis.core.CrudService;
+import com.usky.iot.domain.PmWorkReport;
+import com.usky.iot.service.vo.PmSubmitCountResponseVO;
+
+/**
+ * <p>
+ * 工作报告提交时间配置表 服务类
+ * </p>
+ *
+ * @author fu
+ * @since 2025-01-10
+ */
+public interface PmTimeConfService extends CrudService<PmTimeConf> {
+
+    /**
+     * 获取提交统计
+     * @param submitDate
+     * @return
+     */
+    PmSubmitCountResponseVO submitCount(String submitDate);
+
+    /**
+     * 获取提交列表
+     * @return
+     */
+    CommonPage<Object> submitPage(String submitDate, Integer queryType, Integer reportId, Integer pageNum, Integer pageSize);
+}

+ 316 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/service/impl/PmTimeConfServiceImpl.java

@@ -0,0 +1,316 @@
+package com.usky.iot.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.usky.common.core.bean.CommonPage;
+import com.usky.common.core.exception.BusinessException;
+import com.usky.common.security.utils.SecurityUtils;
+import com.usky.iot.domain.PmReceive;
+import com.usky.iot.domain.PmTimeConf;
+import com.usky.iot.domain.PmWorkContent;
+import com.usky.iot.domain.PmWorkReport;
+import com.usky.iot.mapper.*;
+import com.usky.iot.service.PmTimeConfService;
+import com.usky.common.mybatis.core.AbstractCrudService;
+import com.usky.iot.service.vo.PmReportReadersVO;
+import com.usky.iot.service.vo.PmSubmitCountResponseVO;
+import com.usky.system.domain.SysUser;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ * 工作报告提交时间配置表 服务实现类
+ * </p>
+ *
+ * @author fu
+ * @since 2025-01-10
+ */
+@Service
+public class PmTimeConfServiceImpl extends AbstractCrudService<PmTimeConfMapper, PmTimeConf> implements PmTimeConfService {
+
+    @Autowired
+    private PmTimeConfMapper pmTimeConfMapper;
+
+    @Autowired
+    private PmWorkReportMapper pmWorkReportMapper;
+
+    @Autowired
+    private SysUserMapper sysUserMapper;
+
+    @Autowired
+    private PmWorkContentMapper pmWorkContentMapper;
+
+    @Autowired
+    private PmReceiveMapper pmReceiveMapper;
+
+    // 统计工作报提交
+    @Override
+    public PmSubmitCountResponseVO submitCount(String submitDate) {
+        Integer tenantId = SecurityUtils.getTenantId();
+        PmSubmitCountResponseVO responseVO = new PmSubmitCountResponseVO();
+        LocalDate countDate = LocalDate.parse(submitDate);
+
+        // 查询时间配置
+        PmTimeConf timeConf = getTimeConf(tenantId);
+        if (timeConf == null) {
+            throw new RuntimeException("未找到工作报提交统计告时间配置,请联系管理员");
+        } else if (countDate.equals(LocalDate.now()) && timeConf.getStartTime().isAfter(LocalTime.now())) {
+            throw new RuntimeException("不可查看未来数据");
+        }
+
+        LocalTime startTime = timeConf.getStartTime();
+        LocalTime onTime = timeConf.getOnTime();
+        LocalTime endTime = timeConf.getEndTime();
+        LocalDateTime startDateTime = LocalDateTime.of(countDate, startTime);
+        LocalDateTime onDateTime = LocalDateTime.of(countDate, onTime);
+        LocalDateTime endDateTime = LocalDateTime.of(countDate, endTime).plusDays(1);
+
+        // 按时提交
+        List<PmWorkReport> pmWorkReports = reportList(tenantId, 0, startDateTime, onDateTime, endDateTime);
+        Integer submitOnTime = pmWorkReports.size();
+
+        // 延迟提交
+        List<PmWorkReport> pmWorkReports2 = reportList(tenantId, 1, startDateTime, onDateTime, endDateTime);
+        Integer submitLate = pmWorkReports2.size();
+
+        Integer suerSum = users(tenantId).size();
+        // 未提交
+        Integer notSubmitted = suerSum - submitOnTime - submitLate;
+
+        responseVO.setSubmitOnTime(submitOnTime);
+        responseVO.setSubmitLate(submitLate);
+        responseVO.setNotSubmitted(notSubmitted);
+        return responseVO;
+    }
+
+    @Override
+    public CommonPage<Object> submitPage(String submitDate, Integer queryType, Integer reportId, Integer pageNum, Integer pageSize) {
+        Integer tenantId = SecurityUtils.getTenantId();
+        Long userId2 = SecurityUtils.getUserId();
+        LocalDate countDate = LocalDate.parse(submitDate);
+
+        List<SysUser> userList = users(tenantId);
+
+        PmTimeConf timeConf = getTimeConf(tenantId);
+        if (timeConf == null) {
+            throw new BusinessException("未找到工作报提交统计告时间配置,请联系管理员");
+        }
+
+        LocalTime startTime = timeConf.getStartTime();
+        LocalTime onTime = timeConf.getOnTime();
+        LocalTime endTime = timeConf.getEndTime();
+        LocalDateTime startDateTime = LocalDateTime.of(countDate, startTime);
+        LocalDateTime onDateTime = LocalDateTime.of(countDate, onTime);
+        LocalDateTime endDateTime = LocalDateTime.of(countDate, endTime).plusDays(1);
+
+        LambdaQueryWrapper<PmWorkReport> reportQuery = Wrappers.lambdaQuery();
+        reportQuery.eq(PmWorkReport::getTenantId, tenantId).eq(PmWorkReport::getReportStatus, 1);
+
+        if (reportId != null && reportId != 0) {
+            reportQuery.eq(PmWorkReport::getId, reportId);
+        } else {
+            switch (queryType) {
+                // 按时提交
+                case 0:
+                    reportQuery.between(PmWorkReport::getSubmitDate, startDateTime, onDateTime);
+                    break;
+                // 延迟提交
+                case 1:
+                    reportQuery.between(PmWorkReport::getSubmitDate, onDateTime, endDateTime);
+                    break;
+                // 未提交
+                case 2:
+                    List<Long> userId = new ArrayList<>();
+                    // 按时提交
+                    List<PmWorkReport> pmWorkReports = reportList(tenantId, 0, startDateTime, onDateTime, endDateTime);
+                    pmWorkReports.forEach(report -> {
+                        userId.add(report.getSubmitterId());
+                    });
+                    // 延迟提交
+                    List<PmWorkReport> pmWorkReports2 = reportList(tenantId, 1, startDateTime, onDateTime, endDateTime);
+                    pmWorkReports2.forEach(report -> {
+                        userId.add(report.getSubmitterId());
+                    });
+                    // 未提交
+                    List<SysUser> unSubmitted = userList.stream().filter(user -> !userId.contains(user.getUserId())).collect(Collectors.toList());
+
+                    int total = unSubmitted.size();
+                    int start = (pageNum - 1) * pageSize;
+                    int end = Math.min(start + pageSize, total);
+
+                    List<SysUser> pageData;
+                    if (start < total) {
+                        pageData = unSubmitted.subList(start, end);
+                    } else {
+                        pageData = Collections.emptyList();
+                    }
+                    return new CommonPage<>(Collections.singletonList(pageData), total, pageSize, pageNum);
+
+                default:
+                    throw new BusinessException("报告统计分页参数错误!");
+            }
+            if (countDate.equals(LocalDate.now()) && timeConf.getStartTime().isAfter(LocalTime.now())) {
+                throw new BusinessException("不可查看未来数据");
+            }
+            reportQuery.eq(PmWorkReport::getReportDate, countDate);
+        }
+
+        List<PmWorkReport> pmWorkReports = pmWorkReportMapper.selectList(reportQuery);
+        if (pmWorkReports.isEmpty()) {
+            return new CommonPage<>();
+        }
+        List<Integer> reportIds = new ArrayList<>();
+        pmWorkReports.forEach(report -> {
+            reportIds.add(report.getId());
+        });
+
+        LambdaQueryWrapper<PmWorkContent> reportContents = Wrappers.lambdaQuery();
+        reportContents.in(PmWorkContent::getReportId, reportIds);
+        List<PmWorkContent> pmWorkContentList = pmWorkContentMapper.selectList(reportContents);
+
+        // 查询已读状态
+        LambdaQueryWrapper<PmReceive> statusQuery = Wrappers.lambdaQuery();
+        statusQuery.select(PmReceive::getReportId, PmReceive::getReadFlag).eq(PmReceive::getReceiverId, userId2);
+        if (reportId != null && reportId != 0) {
+            statusQuery.eq(PmReceive::getReportId, reportId);
+        } else {
+            statusQuery.in(PmReceive::getReportId, reportIds);
+        }
+        List<PmReceive> receiveList2 = pmReceiveMapper.selectList(statusQuery);
+
+        Map<Integer, Integer> reportReadFlags = new HashMap<>();
+        for (PmReceive pmReceive : receiveList2) {
+            Integer reportId2 = pmReceive.getReportId();
+            reportReadFlags.put(reportId2, pmReceive.getReadFlag());
+        }
+
+        List<Long> userIds = new ArrayList<>();
+
+        // 已读未读数量查询
+        List<PmReceive> receives = new ArrayList<>();
+        receives = receives(reportIds);
+        Map<Integer, List<PmReceive>> reportReceivesMap = new HashMap<>();
+        reportReceivesMap = receives.stream().collect(Collectors.groupingBy(PmReceive::getReportId));
+        for (PmWorkReport report : pmWorkReports) {
+            List<PmWorkContent> contents = pmWorkContentList.stream().filter(content -> content.getReportId().equals(report.getId())).collect(Collectors.toList());
+            report.setWorkContents(contents);
+            userIds.add(report.getSubmitterId());
+
+            Integer readFlagValue = reportReadFlags.get(report.getId());
+            report.setReadFlag(readFlagValue);
+
+            // 创建人名字替换
+            if (!userIds.isEmpty()) {
+                List<SysUser> nickNames = nickNames(userIds);
+                Map<Long, String> userNicknameMap = nickNames.stream().collect(Collectors.toMap(SysUser::getUserId, SysUser::getNickName));
+                report.setCreateBy(userNicknameMap.get(report.getSubmitterId()));
+            }
+
+            List<Long> readAlready = new ArrayList<>();
+            List<Long> readNotAlready = new ArrayList<>();
+            int readCount = 0;
+            int unreadCount = 0;
+            if (!reportReceivesMap.isEmpty()) {
+                List<PmReceive> reportReceives = reportReceivesMap.getOrDefault(report.getId(), Collections.emptyList());
+                for (PmReceive pmReceive : reportReceives) {
+                    if (pmReceive.getReadFlag() == 1) {
+                        readCount++;
+                        readAlready.add(pmReceive.getReceiverId());
+                    } else {
+                        unreadCount++;
+                        readNotAlready.add(pmReceive.getReceiverId());
+                    }
+                }
+            }
+
+            PmReportReadersVO readUnreadVO = new PmReportReadersVO(readAlready, readNotAlready, readCount, unreadCount);
+            report.setPmReportReaders(readUnreadVO);
+
+            // 头像
+            for (SysUser sysUser : userList) {
+                if (sysUser.getUserId().equals(report.getSubmitterId())) {
+                    report.setAvatar(sysUser.getAvatar());
+                    break;
+                }
+            }
+        }
+
+        int total = pmWorkReports.size();
+        int start = (pageNum - 1) * pageSize;
+        int end = Math.min(start + pageSize, total);
+
+        List<PmWorkReport> pageData;
+        if (start < total) {
+            pageData = pmWorkReports.subList(start, end);
+        } else {
+            pageData = Collections.emptyList();
+        }
+
+        return new CommonPage<>(Collections.singletonList(pageData), total, pageSize, pageNum);
+    }
+
+    // 查询已读未读
+    private List<PmReceive> receives(List<Integer> reports) {
+        LambdaQueryWrapper<PmReceive> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.select(PmReceive::getReportId, PmReceive::getReadFlag, PmReceive::getReceiverId).in(PmReceive::getReportId, reports);
+        return pmReceiveMapper.selectList(queryWrapper);
+    }
+
+    // 构建查询条件,返回按时提交和延迟提交列表
+    private List<PmWorkReport> reportList(Integer tenantId, Integer queryType, LocalDateTime startDateTime, LocalDateTime onDateTime, LocalDateTime endDateTime) {
+
+        LocalDate countDate = startDateTime.toLocalDate();
+
+        LambdaQueryWrapper<PmWorkReport> reportQuery = new LambdaQueryWrapper<>();
+        reportQuery.eq(PmWorkReport::getTenantId, tenantId)
+                .eq(PmWorkReport::getReportDate, countDate);
+        switch (queryType) {
+            // 按时提交
+            case 0:
+                reportQuery.between(PmWorkReport::getSubmitDate, startDateTime, onDateTime);
+                break;
+            // 延迟提交
+            case 1:
+                reportQuery.between(PmWorkReport::getSubmitDate, onDateTime, endDateTime);
+                break;
+        }
+        return pmWorkReportMapper.selectList(reportQuery);
+    }
+
+    // 获取报告时间配置
+    private PmTimeConf getTimeConf(Integer tenantId) {
+        LambdaQueryWrapper<PmTimeConf> timeConfQuery = new LambdaQueryWrapper<>();
+        timeConfQuery.select(PmTimeConf::getStartTime, PmTimeConf::getOnTime, PmTimeConf::getEndTime)
+                .eq(PmTimeConf::getTenantId, tenantId)
+                .eq(PmTimeConf::getConfType, "PM");
+        return pmTimeConfMapper.selectOne(timeConfQuery);
+    }
+
+    // 查询用户信息
+    private List<SysUser> users(Integer tenantId) {
+        LambdaQueryWrapper<SysUser> userQuery = new LambdaQueryWrapper<>();
+        userQuery.select(SysUser::getUserId, SysUser::getDeptId, SysUser::getUserName, SysUser::getNickName, SysUser::getPhonenumber,
+                        SysUser::getAvatar, SysUser::getSex, SysUser::getAddress, SysUser::getEmail)
+                .eq(SysUser::getTenantId, tenantId)
+                .eq(SysUser::getStatus, 0)
+                .eq(SysUser::getDelFlag, 0)
+                .eq(SysUser::getUserType, "00");
+        return sysUserMapper.selectList(userQuery);
+    }
+
+    // 获取用户昵称
+    private List<SysUser> nickNames(List<Long> userIds) {
+        LambdaQueryWrapper<SysUser> userQuery = new LambdaQueryWrapper<>();
+        userQuery.select(SysUser::getUserId, SysUser::getNickName)
+                .in(SysUser::getUserId, userIds);
+        return sysUserMapper.selectList(userQuery);
+    }
+
+}

+ 11 - 2
service-iot/service-iot-biz/src/main/java/com/usky/iot/service/impl/PmWorkReportServiceImpl.java

@@ -358,6 +358,7 @@ public class PmWorkReportServiceImpl extends AbstractCrudService<PmWorkReportMap
                 rp.setId(rid);
                 rp.setSubmitterId(pmWorkReport.getSubmitterId());
                 rp.setCcTo(ccTo);
+                rp.setSubmitDate(LocalDateTime.now());
                 rp.setCoordinateWork(pmWorkReport.getCoordinateWork());
                 rp.setTomorrowPlan(pmWorkReport.getTomorrowPlan());
                 rp.setCreateBy(pmWorkReport.getCreateBy());
@@ -535,8 +536,16 @@ public class PmWorkReportServiceImpl extends AbstractCrudService<PmWorkReportMap
                 throw new BusinessException("周数错误!请重新选择");
             }
 
-            LocalDate firstMonday = currentYear.atDay(1).with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));
-            LocalDate startOfWeek = firstMonday.plusWeeks(dateNum - 1);
+            int yearValue = currentYear.getValue();
+            LocalDate firstDayOfYear = LocalDate.of(yearValue, 1, 1);
+            LocalDate firstMondayOfYear = firstDayOfYear.with(TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY));
+
+            DayOfWeek dayOfWeek = firstDayOfYear.getDayOfWeek();
+            if (dayOfWeek != DayOfWeek.MONDAY){
+                dateNum -= 1;
+            }
+
+            LocalDate startOfWeek = firstMondayOfYear.plusWeeks(dateNum - 1);
             LocalDate endOfWeek = startOfWeek.plusWeeks(1).minusDays(1);
             LocalDateTime startTimeOfWeek = startOfWeek.atStartOfDay();
             LocalDateTime endTimeOfWeek = endOfWeek.atTime(23, 59, 59);

+ 50 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/service/vo/PmSubmitCountResponseVO.java

@@ -0,0 +1,50 @@
+package com.usky.iot.service.vo;
+
+/**
+ *
+ * @author fyc
+ * @email yuchuan.fu@chinausky.com
+ * @date 2025/1/10
+ */
+public class PmSubmitCountResponseVO {
+
+    /**
+     * 按时提交
+     **/
+    private Integer submitOnTime;
+
+    /**
+     * 迟交
+     **/
+    private Integer submitLate;
+
+    /**
+     * 未提交
+     **/
+    private Integer notSubmitted;
+
+    public Integer getSubmitOnTime() {
+        return submitOnTime;
+    }
+
+    public void setSubmitOnTime(Integer submitOnTime) {
+        this.submitOnTime = submitOnTime;
+    }
+
+    public Integer getSubmitLate() {
+        return submitLate;
+    }
+
+    public void setSubmitLate(Integer submitLate) {
+        this.submitLate = submitLate;
+    }
+
+    public Integer getNotSubmitted() {
+        return notSubmitted;
+    }
+
+    public void setNotSubmitted(Integer notSubmitted) {
+        this.notSubmitted = notSubmitted;
+    }
+
+}

+ 19 - 0
service-iot/service-iot-biz/src/main/resources/mapper/iot/PmTimeConfMapper.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.usky.iot.mapper.PmTimeConfMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.usky.iot.domain.PmTimeConf">
+        <id column="id" property="id" />
+        <result column="start_time" property="startTime" />
+        <result column="on_time" property="onTime" />
+        <result column="end_time" property="endTime" />
+        <result column="create_by" property="createBy" />
+        <result column="create_time" property="createTime" />
+        <result column="update_by" property="updateBy" />
+        <result column="update_time" property="updateTime" />
+        <result column="dept_id" property="deptId" />
+        <result column="tenant_id" property="tenantId" />
+    </resultMap>
+
+</mapper>