瀏覽代碼

Merge branch 'server-165' of uskycloud/usky-modules into master

gez 11 月之前
父節點
當前提交
feddcc4184
共有 30 個文件被更改,包括 2449 次插入14 次删除
  1. 5 1
      service-agbox/service-agbox-biz/src/main/java/com/usky/agbox/service/listener/RabbitMQListener.java
  2. 5 1
      service-fire/service-fire-biz/src/main/java/com/usky/fire/controller/web/PatrolInspectionRecordController.java
  3. 2 0
      service-fire/service-fire-biz/src/main/java/com/usky/fire/mapper/PatrolInspectionContentMapper.java
  4. 2 0
      service-fire/service-fire-biz/src/main/java/com/usky/fire/mapper/PatrolInspectionContentOptionMapper.java
  5. 2 0
      service-fire/service-fire-biz/src/main/java/com/usky/fire/mapper/PatrolInspectionRecordOptionMapper.java
  6. 7 2
      service-fire/service-fire-biz/src/main/java/com/usky/fire/service/PatrolInspectionRecordService.java
  7. 21 0
      service-fire/service-fire-biz/src/main/java/com/usky/fire/service/impl/PatrolInspectionPlanSonServiceImpl.java
  8. 239 5
      service-fire/service-fire-biz/src/main/java/com/usky/fire/service/impl/PatrolInspectionRecordServiceImpl.java
  9. 807 0
      service-fire/service-fire-biz/src/main/java/com/usky/fire/service/util/ExcelUtilImage.java
  10. 37 5
      service-fire/service-fire-biz/src/main/java/com/usky/fire/service/vo/PatrolInspectionRecordExportVo.java
  11. 7 0
      service-fire/service-fire-biz/src/main/java/com/usky/fire/service/vo/PlanRecordVo.java
  12. 88 0
      service-iot/service-iot-biz/src/main/java/com/usky/iot/controller/web/PmProjectController.java
  13. 33 0
      service-iot/service-iot-biz/src/main/java/com/usky/iot/controller/web/PmWorkContentController.java
  14. 64 0
      service-iot/service-iot-biz/src/main/java/com/usky/iot/controller/web/PmWorkReportController.java
  15. 113 0
      service-iot/service-iot-biz/src/main/java/com/usky/iot/domain/PmProject.java
  16. 94 0
      service-iot/service-iot-biz/src/main/java/com/usky/iot/domain/PmWorkContent.java
  17. 109 0
      service-iot/service-iot-biz/src/main/java/com/usky/iot/domain/PmWorkReport.java
  18. 18 0
      service-iot/service-iot-biz/src/main/java/com/usky/iot/mapper/PmProjectMapper.java
  19. 18 0
      service-iot/service-iot-biz/src/main/java/com/usky/iot/mapper/PmWorkContentMapper.java
  20. 18 0
      service-iot/service-iot-biz/src/main/java/com/usky/iot/mapper/PmWorkReportMapper.java
  21. 61 0
      service-iot/service-iot-biz/src/main/java/com/usky/iot/service/PmProjectService.java
  22. 23 0
      service-iot/service-iot-biz/src/main/java/com/usky/iot/service/PmWorkContentService.java
  23. 43 0
      service-iot/service-iot-biz/src/main/java/com/usky/iot/service/PmWorkReportService.java
  24. 188 0
      service-iot/service-iot-biz/src/main/java/com/usky/iot/service/impl/PmProjectServiceImpl.java
  25. 32 0
      service-iot/service-iot-biz/src/main/java/com/usky/iot/service/impl/PmWorkContentServiceImpl.java
  26. 313 0
      service-iot/service-iot-biz/src/main/java/com/usky/iot/service/impl/PmWorkReportServiceImpl.java
  27. 29 0
      service-iot/service-iot-biz/src/main/java/com/usky/iot/service/vo/PmProjectWorkTimeVo.java
  28. 26 0
      service-iot/service-iot-biz/src/main/resources/mapper/iot/PmProjectMapper.xml
  29. 22 0
      service-iot/service-iot-biz/src/main/resources/mapper/iot/PmWorkContentMapper.xml
  30. 23 0
      service-iot/service-iot-biz/src/main/resources/mapper/iot/PmWorkReportMapper.xml

+ 5 - 1
service-agbox/service-agbox-biz/src/main/java/com/usky/agbox/service/listener/RabbitMQListener.java

@@ -31,7 +31,11 @@ public class RabbitMQListener {
                 eventVO1.put("eventCode",2);
                 PatrolAgbox.addEvent(eventVO1.toJSONString());
             }else {
-                eventVO.put("eventCode",16);
+                if (eventVO1.get("eventType").equals(33)||eventVO1.get("eventType").equals(34)){
+                    eventVO.put("eventCode",5);
+                }else {
+                    eventVO.put("eventCode",16);
+                }
                 String timeWithT = eventVO1.get("createTime").toString();
                 eventVO.put("deviceId",eventVO1.get("deviceId"));
                 eventVO.put("triggerTime",timeWithT.replace("T", " "));

+ 5 - 1
service-fire/service-fire-biz/src/main/java/com/usky/fire/controller/web/PatrolInspectionRecordController.java

@@ -7,6 +7,7 @@ import com.usky.common.log.annotation.Log;
 import com.usky.common.log.enums.BusinessType;
 import com.usky.fire.domain.PatrolInspectionRecord;
 import com.usky.fire.service.PatrolInspectionRecordService;
+import com.usky.fire.service.util.ExcelUtilImage;
 import com.usky.fire.service.vo.PatrolInspectionRecordExportVo;
 import com.usky.fire.service.vo.PatrolInspectionRecordVo;
 import com.usky.fire.service.vo.RecordStatisticsVo;
@@ -139,7 +140,10 @@ public class PatrolInspectionRecordController {
                                  @RequestParam(value = "startDateTime", required = false) String startDateTime,
                                  @RequestParam(value = "endDateTime", required = false) String endDateTime,
                                  @RequestParam(value = "idList", required = false) String idList) throws IOException {
-        patrolInspectionRecordService.exportImage(response,areaName, siteName, name, planType, startDateTime, endDateTime, idList);
+        List<PatrolInspectionRecordExportVo> list = patrolInspectionRecordService.exportImage(areaName, siteName, name, planType, startDateTime, endDateTime, idList);
+        ExcelUtilImage<PatrolInspectionRecordExportVo> util = new ExcelUtilImage<PatrolInspectionRecordExportVo>(PatrolInspectionRecordExportVo.class);
+        util.exportExcel(response, list, "巡检记录", "巡检记录");
+//        patrolInspectionRecordService.exportImage(response,areaName, siteName, name, planType, startDateTime, endDateTime, idList);
     }
 }
 

+ 2 - 0
service-fire/service-fire-biz/src/main/java/com/usky/fire/mapper/PatrolInspectionContentMapper.java

@@ -2,6 +2,7 @@ package com.usky.fire.mapper;
 
 import com.usky.fire.domain.PatrolInspectionContent;
 import com.usky.common.mybatis.core.CrudMapper;
+import org.springframework.stereotype.Repository;
 
 /**
  * <p>
@@ -11,6 +12,7 @@ import com.usky.common.mybatis.core.CrudMapper;
  * @author JCB
  * @since 2022-07-15
  */
+@Repository
 public interface PatrolInspectionContentMapper extends CrudMapper<PatrolInspectionContent> {
 
 }

+ 2 - 0
service-fire/service-fire-biz/src/main/java/com/usky/fire/mapper/PatrolInspectionContentOptionMapper.java

@@ -2,6 +2,7 @@ package com.usky.fire.mapper;
 
 import com.usky.fire.domain.PatrolInspectionContentOption;
 import com.usky.common.mybatis.core.CrudMapper;
+import org.springframework.stereotype.Repository;
 
 /**
  * <p>
@@ -11,6 +12,7 @@ import com.usky.common.mybatis.core.CrudMapper;
  * @author JCB
  * @since 2022-07-15
  */
+@Repository
 public interface PatrolInspectionContentOptionMapper extends CrudMapper<PatrolInspectionContentOption> {
 
 }

+ 2 - 0
service-fire/service-fire-biz/src/main/java/com/usky/fire/mapper/PatrolInspectionRecordOptionMapper.java

@@ -2,6 +2,7 @@ package com.usky.fire.mapper;
 
 import com.usky.fire.domain.PatrolInspectionRecordOption;
 import com.usky.common.mybatis.core.CrudMapper;
+import org.springframework.stereotype.Repository;
 
 /**
  * <p>
@@ -11,6 +12,7 @@ import com.usky.common.mybatis.core.CrudMapper;
  * @author JCB
  * @since 2022-07-21
  */
+@Repository
 public interface PatrolInspectionRecordOptionMapper extends CrudMapper<PatrolInspectionRecordOption> {
 
 }

+ 7 - 2
service-fire/service-fire-biz/src/main/java/com/usky/fire/service/PatrolInspectionRecordService.java

@@ -43,6 +43,11 @@ public interface PatrolInspectionRecordService extends CrudService<PatrolInspect
     List<PatrolInspectionRecordExportVo> recordLsitExport(String areaName, String siteName, String name,
                                                           Integer planType, String startDateTime,
                                                           String endDateTime,String idList);
-    void exportImage(HttpServletResponse response, String areaName, String siteName, String name, Integer planType,
-                            String startDateTime, String endDateTime, String idList) throws IOException;
+
+    List<PatrolInspectionRecordExportVo> exportImage(String areaName, String siteName, String name,
+                                                     Integer planType, String startDateTime,
+                                                     String endDateTime, String idList);
+
+/*    void exportImage(HttpServletResponse response, String areaName, String siteName, String name, Integer planType,
+                            String startDateTime, String endDateTime, String idList) throws IOException;*/
 }

+ 21 - 0
service-fire/service-fire-biz/src/main/java/com/usky/fire/service/impl/PatrolInspectionPlanSonServiceImpl.java

@@ -73,6 +73,9 @@ public class PatrolInspectionPlanSonServiceImpl extends AbstractCrudService<Patr
     @Autowired
     private PatrolInspectionPersonnelService patrolInspectionPersonnelService;
 
+    @Autowired
+    private PatrolInspectionEventService patrolInspectionEventService;
+
     @Override
     public Map<String, Object> appPlanStatistics(String currentDate) {
         Integer planSonCount = 0;
@@ -246,8 +249,26 @@ public class PatrolInspectionPlanSonServiceImpl extends AbstractCrudService<Patr
         LocalDateTime inspectionDateTime = LocalDateTime.parse(planSonList.get(0).getInspectionDate() +" "+ planSonList.get(0).getStartTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
         LocalDateTime inspectionDateTime1 = LocalDateTime.parse(planSonList.get(0).getInspectionDate() +" "+ planSonList.get(0).getEndTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
         if (inspectionDateTime.isAfter(now)) {
+            PatrolInspectionEvent patrolInspectionEvent = new PatrolInspectionEvent();
+            patrolInspectionEvent.setEventName("早到");
+            patrolInspectionEvent.setEventType(33);
+            patrolInspectionEvent.setEventLevel(1);
+            patrolInspectionEvent.setEventCategory(1);
+            patrolInspectionEvent.setDeviceId(planRecordVo.getDeviceId());
+            patrolInspectionEvent.setCreateBy(SecurityUtils.getUsername());
+            patrolInspectionEvent.setCreateTime(LocalDateTime.now());
+            patrolInspectionEventService.add(patrolInspectionEvent);
             throw new BusinessException("计划未开始,不可巡检");
         } else if (now.isAfter(inspectionDateTime1)){
+            PatrolInspectionEvent patrolInspectionEvent = new PatrolInspectionEvent();
+            patrolInspectionEvent.setEventName("迟到");
+            patrolInspectionEvent.setEventType(34);
+            patrolInspectionEvent.setEventLevel(1);
+            patrolInspectionEvent.setEventCategory(1);
+            patrolInspectionEvent.setDeviceId(planRecordVo.getDeviceId());
+            patrolInspectionEvent.setCreateBy(SecurityUtils.getUsername());
+            patrolInspectionEvent.setCreateTime(LocalDateTime.now());
+            patrolInspectionEventService.add(patrolInspectionEvent);
             throw new BusinessException("巡检时间已过,请联系管理员");
         }
 

+ 239 - 5
service-fire/service-fire-biz/src/main/java/com/usky/fire/service/impl/PatrolInspectionRecordServiceImpl.java

@@ -12,9 +12,7 @@ import com.usky.common.core.exception.BusinessException;
 import com.usky.common.mybatis.core.AbstractCrudService;
 import com.usky.common.security.utils.SecurityUtils;
 import com.usky.fire.domain.*;
-import com.usky.fire.mapper.PatrolInspectionPlanMapper;
-import com.usky.fire.mapper.PatrolInspectionRecordMapper;
-import com.usky.fire.mapper.PatrolInspectionRecordPictureMapper;
+import com.usky.fire.mapper.*;
 import com.usky.fire.service.*;
 import com.usky.fire.service.vo.*;
 import com.usky.system.model.LoginUser;
@@ -35,7 +33,9 @@ import java.net.MalformedURLException;
 import java.net.URL;
 import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * <p>
@@ -75,6 +75,15 @@ public class PatrolInspectionRecordServiceImpl extends AbstractCrudService<Patro
     @Autowired
     private PatrolInspectionRecordPictureMapper orphansInspectionRecordPictureMapper;
 
+    @Autowired
+    private PatrolInspectionRecordOptionMapper patrolInspectionRecordOptionMapper;
+
+    @Autowired
+    private PatrolInspectionContentMapper patrolInspectionContentMapper;
+
+    @Autowired
+    private PatrolInspectionContentOptionMapper patrolInspectionContentOptionMapper;
+
     @Override
     public CommonPage<PatrolInspectionRecord> patrolInspectionRecordLsit(String areaName, String siteName, String name,
                                                                          Integer planType, String startDateTime, String endDateTime,
@@ -165,7 +174,7 @@ public class PatrolInspectionRecordServiceImpl extends AbstractCrudService<Patro
             contentOptionVo.setCreateTime(contentOptionList.get(i).getCreateTime());
             contentOptionVo.setSelectStatus(false);
             for (int j = 0; j < patrolInspectionRecordOptionList.size(); j++) {
-                if(contentOptionList.get(i).getContentId()==patrolInspectionContentList.get(j).getId()){
+                if (contentOptionList.get(i).getContentId() == patrolInspectionContentList.get(j).getId()) {
                     contentOptionVo.setRemarks(patrolInspectionRecordOptionList.get(j).getRemarks());
                 }
                 if (contentOptionList.get(i).getId() == patrolInspectionRecordOptionList.get(j).getContentOptionId()) {
@@ -420,7 +429,91 @@ public class PatrolInspectionRecordServiceImpl extends AbstractCrudService<Patro
     }
 
     @Override
-    public void exportImage(HttpServletResponse response, String areaName, String siteName, String name, Integer planType,
+    public List<PatrolInspectionRecordExportVo> exportImage(String areaName, String siteName, String name,
+                                                            Integer planType, String startDateTime,
+                                                            String endDateTime, String idList) {
+        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        String userType = null;
+        if (loginUser != null && !"".equals(loginUser)) {
+            userType = loginUser.getUserType();
+        }
+        LambdaQueryWrapper<PatrolInspectionRecord> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(PatrolInspectionRecord::getTenantId, SecurityUtils.getTenantId())
+                .like(StringUtils.isNotBlank(areaName), PatrolInspectionRecord::getAreaName, areaName)
+                .like(StringUtils.isNotBlank(siteName), PatrolInspectionRecord::getSiteName, siteName)
+                .like(StringUtils.isNotBlank(name), PatrolInspectionRecord::getName, name)
+                .eq(planType != null && planType != 0, PatrolInspectionRecord::getPlanType, planType)
+                .between(StringUtils.isNotBlank(startDateTime) && StringUtils.isNotBlank(endDateTime), PatrolInspectionRecord::getCreateTime, startDateTime, endDateTime)
+                .eq("00".equals(userType), PatrolInspectionRecord::getCreator, SecurityUtils.getUsername());
+        if (StringUtils.isNotBlank(idList)) {
+            List<Integer> listId = new ArrayList<>();
+            String[] idArray = idList.split(",");
+            for (int i = 0; i < idArray.length; i++) {
+                listId.add(Integer.parseInt(idArray[i]));
+            }
+            queryWrapper.in(PatrolInspectionRecord::getId, listId);
+        }
+        queryWrapper.orderByDesc(PatrolInspectionRecord::getId);
+        List<PatrolInspectionRecord> patrolInspectionRecordList = this.list(queryWrapper);
+        List<PatrolInspectionRecordExportVo> list = new ArrayList<>();
+        for (int i = 0; i < patrolInspectionRecordList.size(); i++) {
+            PatrolInspectionRecordExportVo patrolInspectionRecordExportVo = new PatrolInspectionRecordExportVo();
+            patrolInspectionRecordExportVo.setXh(i + 1);
+            patrolInspectionRecordExportVo.setId(patrolInspectionRecordList.get(i).getId());
+            patrolInspectionRecordExportVo.setSiteNubmber(patrolInspectionRecordList.get(i).getSiteNubmber());
+            patrolInspectionRecordExportVo.setSiteType(patrolInspectionRecordList.get(i).getSiteType());
+            patrolInspectionRecordExportVo.setAreaName(patrolInspectionRecordList.get(i).getAreaName());
+            patrolInspectionRecordExportVo.setSiteName(patrolInspectionRecordList.get(i).getSiteName());
+            patrolInspectionRecordExportVo.setName(patrolInspectionRecordList.get(i).getName());
+            patrolInspectionRecordExportVo.setPhone(patrolInspectionRecordList.get(i).getPhone());
+            patrolInspectionRecordExportVo.setPlanType(patrolInspectionRecordList.get(i).getPlanType());
+            patrolInspectionRecordExportVo.setLongitude(patrolInspectionRecordList.get(i).getLongitude());
+            patrolInspectionRecordExportVo.setLatitude(patrolInspectionRecordList.get(i).getLatitude());
+            patrolInspectionRecordExportVo.setStartDate(patrolInspectionRecordList.get(i).getStartDate().format(df));
+            patrolInspectionRecordExportVo.setEndDate(patrolInspectionRecordList.get(i).getEndDate().format(df));
+            patrolInspectionRecordExportVo.setCreateTime(patrolInspectionRecordList.get(i).getCreateTime().format(df));
+            patrolInspectionRecordExportVo.setRemarks(patrolInspectionRecordList.get(i).getRemarks());
+
+            patrolInspectionRecordExportVo.setContentTitle(getContentTitle(patrolInspectionRecordList.get(i).getId()));
+            patrolInspectionRecordExportVo.setSubmissionMethod(getSubmissionMethod(patrolInspectionRecordList.get(i).getId()));
+            patrolInspectionRecordExportVo.setOptionName(getOptionName(patrolInspectionRecordList.get(i).getId()));
+            patrolInspectionRecordExportVo.setContentRemarks(getRemarks(patrolInspectionRecordList.get(i).getId()));
+            LambdaQueryWrapper<PatrolInspectionRecordPicture> queryWrapperImage = Wrappers.lambdaQuery();//导出图片
+            queryWrapperImage.select(PatrolInspectionRecordPicture::getPictureUrl)
+                    .eq(PatrolInspectionRecordPicture::getRecordId, patrolInspectionRecordList.get(i).getId());
+            List<PatrolInspectionRecordPicture> pictures = orphansInspectionRecordPictureMapper.selectList(queryWrapperImage);
+            if (pictures.size() > 0) {
+                for (int j = 0; j < pictures.size() && j < 5; j++) {
+                    String pictureUrl = pictures.get(j).getPictureUrl();
+                    switch (j) {
+                        case 0:
+                            patrolInspectionRecordExportVo.setImagePath1(pictureUrl);
+                            break;
+                        case 1:
+                            patrolInspectionRecordExportVo.setImagePath2(pictureUrl);
+                            break;
+                        case 2:
+                            patrolInspectionRecordExportVo.setImagePath3(pictureUrl);
+                            break;
+                        case 3:
+                            patrolInspectionRecordExportVo.setImagePath4(pictureUrl);
+                            break;
+                        case 4:
+                            patrolInspectionRecordExportVo.setImagePath5(pictureUrl);
+                            break;
+                        default:
+                            break;
+                    }
+                }
+            }
+            list.add(patrolInspectionRecordExportVo);
+        }
+        return list;
+    }
+
+
+    /*public void exportImage(HttpServletResponse response, String areaName, String siteName, String name, Integer planType,
                             String startDateTime, String endDateTime, String idList) throws IOException {
         DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
         LoginUser loginUser = SecurityUtils.getLoginUser();
@@ -692,12 +785,153 @@ public class PatrolInspectionRecordServiceImpl extends AbstractCrudService<Patro
         workbook.close();
     }
 
+    //处理图片
     public byte[] getImageBytes(String imageUrl) throws IOException {
         URL url = new URL(imageUrl);
         BufferedImage image = ImageIO.read(url);
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         ImageIO.write(image, "jpg", baos);
         return baos.toByteArray();
+    }*/
+
+    /**
+     * 获取内容选项备注
+     *
+     * @param recordId 巡检记录id
+     * @return
+     */
+    public List<String> getRemarks(int recordId) {
+        LambdaQueryWrapper<PatrolInspectionRecordOption> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(PatrolInspectionRecordOption::getRecordId, recordId)
+                .orderByAsc(PatrolInspectionRecordOption::getId);
+        List<PatrolInspectionRecordOption> recordOptions = patrolInspectionRecordOptionMapper.selectList(queryWrapper);
+        List<String> remarksList = new ArrayList<>();
+        for (PatrolInspectionRecordOption recordOption : recordOptions) {
+            if (recordOption.getRemarks() != null) {
+                remarksList.add(recordOption.getRemarks());
+            } else {
+                remarksList.add(""); // 如果Remarks为空,则添加空字符串
+            }
+        }
+        return remarksList;
+    }
+
+    /**
+     * 获取检查项ID
+     *
+     * @param recordId 巡检记录id
+     * @return
+     */
+    public List<Integer> getContentId(int recordId) {
+        LambdaQueryWrapper<PatrolInspectionRecordOption> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.select(PatrolInspectionRecordOption::getContentId)
+                .eq(PatrolInspectionRecordOption::getRecordId, recordId)
+                .orderByAsc(PatrolInspectionRecordOption::getId);
+        List<PatrolInspectionRecordOption> recordOptions = patrolInspectionRecordOptionMapper.selectList(queryWrapper);
+        List<Integer> ContentIdList = new ArrayList<>();
+        for (PatrolInspectionRecordOption recordOption : recordOptions) {
+            ContentIdList.add(recordOption.getContentId());
+        }
+        return ContentIdList;
     }
 
+    /**
+     * 获取内容标题
+     *
+     * @param recordId 巡检记录id
+     * @return
+     */
+    public List<String> getContentTitle(int recordId) {
+        List<Integer> list = getContentId(recordId);
+        LambdaQueryWrapper<PatrolInspectionContent> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.select(PatrolInspectionContent::getContentTitle)
+                .in(PatrolInspectionContent::getId, list)
+                .orderByAsc(PatrolInspectionContent::getId);
+        List<PatrolInspectionContent> contentList = patrolInspectionContentMapper.selectList(queryWrapper);
+        List<String> contentTitle = new ArrayList<>();
+        for (PatrolInspectionContent content : contentList) {
+            contentTitle.add(content.getContentTitle());
+        }
+        return contentTitle;
+    }
+
+    /**
+     * 获取提交方法
+     *
+     * @param recordId 巡检记录id
+     * @return
+     */
+    public List<String> getSubmissionMethod(int recordId) {
+        List<Integer> list = getContentId(recordId);
+        LambdaQueryWrapper<PatrolInspectionContent> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.select(PatrolInspectionContent::getSubmissionMethod)
+                .in(PatrolInspectionContent::getId, list)
+                .orderByAsc(PatrolInspectionContent::getId);
+        List<PatrolInspectionContent> contentList = patrolInspectionContentMapper.selectList(queryWrapper);
+        List<String> contentTitle = new ArrayList<>();
+        for (PatrolInspectionContent content : contentList) {
+            switch (content.getSubmissionMethod()) {
+                case 1:
+                    contentTitle.add("多选");
+                    break;
+                case 2:
+                    contentTitle.add("单选");
+                    break;
+                default:
+                    contentTitle.add("输入框");
+            }
+        }
+        return contentTitle;
+    }
+
+    /**
+     * 获取内容选项ID
+     *
+     * @param recordId 巡检记录id
+     * @return
+     */
+    public List<Integer> getContentOptionId(int recordId) {
+        LambdaQueryWrapper<PatrolInspectionRecordOption> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(PatrolInspectionRecordOption::getRecordId, recordId)
+                .orderByAsc(PatrolInspectionRecordOption::getId);
+        List<PatrolInspectionRecordOption> contentOptionIds = patrolInspectionRecordOptionMapper.selectList(queryWrapper);
+        List<Integer> contentOptionIdList = new ArrayList<>();
+        for (PatrolInspectionRecordOption recordOption : contentOptionIds) {
+            contentOptionIdList.add(recordOption.getContentId());
+        }
+        return contentOptionIdList;
+    }
+
+    /**
+     * 获取选项内容
+     *
+     * @param recordId 巡检记录id
+     * @return
+     */
+    public List<String> getOptionName(int recordId) {
+        List<Integer> list = getContentOptionId(recordId);
+        System.out.println(list);
+        LambdaQueryWrapper<PatrolInspectionRecordOption> queryWrapper1 = Wrappers.lambdaQuery();
+        queryWrapper1.eq(PatrolInspectionRecordOption::getRecordId,recordId)
+                .in(PatrolInspectionRecordOption::getContentId,list)
+                .orderByAsc(PatrolInspectionRecordOption::getId);
+        List<PatrolInspectionRecordOption> list2 = patrolInspectionRecordOptionMapper.selectList(queryWrapper1);
+        List<String> optionNameList = new ArrayList<>();
+        for (int i = 0; i < list2.size(); i++) {
+            if (list2.get(i).getContentOptionId() == null || " ".equals(list2.get(i).getContentOptionId())){
+                optionNameList.add(list2.get(i).getContent());
+            }else {
+                LambdaQueryWrapper<PatrolInspectionContentOption> queryWrapper2 = Wrappers.lambdaQuery();
+                queryWrapper2.select(PatrolInspectionContentOption::getOptionName)
+                        .eq(PatrolInspectionContentOption::getId,list2.get(i).getContentOptionId())
+                        .orderByAsc(PatrolInspectionContentOption::getId);
+                PatrolInspectionContentOption optionName1 = patrolInspectionContentOptionMapper.selectOne(queryWrapper2);
+                optionNameList.add(optionName1.getOptionName());
+            }
+        }
+        return optionNameList;
+    }
+
+
+
 }

+ 807 - 0
service-fire/service-fire-biz/src/main/java/com/usky/fire/service/util/ExcelUtilImage.java

@@ -0,0 +1,807 @@
+package com.usky.fire.service.util;
+
+import com.ruoyi.common.core.annotation.Excel;
+import com.ruoyi.common.core.annotation.Excels;
+import com.ruoyi.common.core.annotation.Excel.ColumnType;
+import com.ruoyi.common.core.annotation.Excel.Type;
+import com.ruoyi.common.core.text.Convert;
+import com.ruoyi.common.core.utils.DateUtils;
+import com.ruoyi.common.core.utils.StringUtils;
+import com.ruoyi.common.core.utils.file.FileTypeUtils;
+import com.ruoyi.common.core.utils.file.ImageUtils;
+import com.ruoyi.common.core.utils.poi.ExcelHandlerAdapter;
+import com.ruoyi.common.core.utils.reflect.ReflectUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.stream.Collectors;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.RegExUtils;
+import org.apache.poi.ss.usermodel.BorderStyle;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.CellType;
+import org.apache.poi.ss.usermodel.ClientAnchor;
+import org.apache.poi.ss.usermodel.DataValidation;
+import org.apache.poi.ss.usermodel.DataValidationConstraint;
+import org.apache.poi.ss.usermodel.DataValidationHelper;
+import org.apache.poi.ss.usermodel.DateUtil;
+import org.apache.poi.ss.usermodel.Drawing;
+import org.apache.poi.ss.usermodel.FillPatternType;
+import org.apache.poi.ss.usermodel.Font;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+import org.apache.poi.ss.usermodel.IndexedColors;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.VerticalAlignment;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.usermodel.WorkbookFactory;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellRangeAddressList;
+import org.apache.poi.util.IOUtils;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
+import org.apache.poi.xssf.usermodel.XSSFDataValidation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @description:TODO
+ * @author: fu
+ * @create: 2024-04-30 12:34
+ */
+public class ExcelUtilImage<T> {
+    private static final Logger log = LoggerFactory.getLogger(ExcelUtilImage.class);
+    public static final String FORMULA_REGEX_STR = "=|-|\\+|@";
+    public static final String[] FORMULA_STR = new String[]{"=", "-", "+", "@"};
+    public static final int sheetSize = 65536;
+    private String sheetName;
+    private Type type;
+    private Workbook wb;
+    private Sheet sheet;
+    private Map<String, CellStyle> styles;
+    private List<T> list;
+    private List<Object[]> fields;
+    private int rownum;
+    private String title;
+    private short maxHeight;
+    private Map<Integer, Double> statistics = new HashMap();
+    private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00");
+    public Class<T> clazz;
+
+    public ExcelUtilImage(Class<T> clazz) {
+        this.clazz = clazz;
+    }
+
+    public void init(List<T> list, String sheetName, String title, Type type) {
+        if (list == null) {
+            list = new ArrayList();
+        }
+
+        this.list = (List) list;
+        this.sheetName = sheetName;
+        this.type = type;
+        this.title = title;
+        this.createExcelField();
+        this.createWorkbook();
+        this.createTitle();
+    }
+
+    public void createTitle() {
+        if (StringUtils.isNotEmpty(this.title)) {
+            Sheet var10000 = this.sheet;
+            int var10001;
+            if (this.rownum == 0) {
+                int var10003 = this.rownum;
+                var10001 = var10003;
+                this.rownum = var10003 + 1;
+            } else {
+                var10001 = 0;
+            }
+
+            Row titleRow = var10000.createRow(var10001);
+            titleRow.setHeightInPoints(30.0F);
+            Cell titleCell = titleRow.createCell(0);
+            titleCell.setCellStyle((CellStyle) this.styles.get("title"));
+            titleCell.setCellValue(this.title);
+            this.sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), titleRow.getRowNum(), this.fields.size() - 1));
+        }
+
+    }
+
+    public List<T> importExcel(InputStream is) throws Exception {
+        return this.importExcel(is, 0);
+    }
+
+    public List<T> importExcel(InputStream is, int titleNum) throws Exception {
+        return this.importExcel("", is, titleNum);
+    }
+
+    public List<T> importExcel(String sheetName, InputStream is, int titleNum) throws Exception {
+        this.type = Type.IMPORT;
+        this.wb = WorkbookFactory.create(is);
+        List<T> list = new ArrayList();
+        Sheet sheet = StringUtils.isNotEmpty(sheetName) ? this.wb.getSheet(sheetName) : this.wb.getSheetAt(0);
+        if (sheet == null) {
+            throw new IOException("文件sheet不存在");
+        } else {
+            int rows = sheet.getLastRowNum();
+            if (rows > 0) {
+                Map<String, Integer> cellMap = new HashMap();
+                Row heard = sheet.getRow(titleNum);
+
+                for (int i = 0; i < heard.getPhysicalNumberOfCells(); ++i) {
+                    Cell cell = heard.getCell(i);
+                    if (StringUtils.isNotNull(cell)) {
+                        String value = this.getCellValue(heard, i).toString();
+                        cellMap.put(value, i);
+                    } else {
+                        cellMap.put(String.valueOf((Object) null), i);
+                    }
+                }
+
+                List<Object[]> fields = this.getFields();
+                Map<Integer, Object[]> fieldsMap = new HashMap();
+                Iterator var24 = fields.iterator();
+
+                while (var24.hasNext()) {
+                    Object[] objects = (Object[]) var24.next();
+                    Excel attr = (Excel) objects[1];
+                    Integer column = (Integer) cellMap.get(attr.name());
+                    if (column != null) {
+                        fieldsMap.put(column, objects);
+                    }
+                }
+
+                for (int i = titleNum + 1; i <= rows; ++i) {
+                    Row row = sheet.getRow(i);
+                    if (!this.isRowEmpty(row)) {
+                        T entity = null;
+                        Iterator var28 = fieldsMap.entrySet().iterator();
+
+                        while (var28.hasNext()) {
+                            Entry<Integer, Object[]> entry = (Entry) var28.next();
+                            Object val = this.getCellValue(row, (Integer) entry.getKey());
+                            entity = entity == null ? this.clazz.newInstance() : entity;
+                            Field field = (Field) ((Object[]) entry.getValue())[0];
+                            Excel attr = (Excel) ((Object[]) entry.getValue())[1];
+                            Class<?> fieldType = field.getType();
+                            String propertyName;
+                            if (String.class == fieldType) {
+                                propertyName = Convert.toStr(val);
+                                if (StringUtils.endsWith(propertyName, ".0")) {
+                                    val = StringUtils.substringBefore(propertyName, ".0");
+                                } else {
+                                    String dateFormat = ((Excel) field.getAnnotation(Excel.class)).dateFormat();
+                                    if (StringUtils.isNotEmpty(dateFormat)) {
+                                        val = this.parseDateToStr(dateFormat, val);
+                                    } else {
+                                        val = Convert.toStr(val);
+                                    }
+                                }
+                            } else if ((Integer.TYPE == fieldType || Integer.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) {
+                                val = Convert.toInt(val);
+                            } else if ((Long.TYPE == fieldType || Long.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) {
+                                val = Convert.toLong(val);
+                            } else if (Double.TYPE != fieldType && Double.class != fieldType) {
+                                if (Float.TYPE != fieldType && Float.class != fieldType) {
+                                    if (BigDecimal.class == fieldType) {
+                                        val = Convert.toBigDecimal(val);
+                                    } else if (Date.class == fieldType) {
+                                        if (val instanceof String) {
+                                            val = DateUtils.parseDate(val);
+                                        } else if (val instanceof Double) {
+                                            val = DateUtil.getJavaDate((Double) val);
+                                        }
+                                    } else if (Boolean.TYPE == fieldType || Boolean.class == fieldType) {
+                                        val = Convert.toBool(val, false);
+                                    }
+                                } else {
+                                    val = Convert.toFloat(val);
+                                }
+                            } else {
+                                val = Convert.toDouble(val);
+                            }
+
+                            if (StringUtils.isNotNull(fieldType)) {
+                                propertyName = field.getName();
+                                if (StringUtils.isNotEmpty(attr.targetAttr())) {
+                                    propertyName = field.getName() + "." + attr.targetAttr();
+                                } else if (StringUtils.isNotEmpty(attr.readConverterExp())) {
+                                    val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator());
+                                } else if (!attr.handler().equals(ExcelHandlerAdapter.class)) {
+                                    val = this.dataFormatHandlerAdapter(val, attr);
+                                }
+
+                                ReflectUtils.invokeSetter(entity, propertyName, val);
+                            }
+                        }
+
+                        list.add(entity);
+                    }
+                }
+            }
+
+            return list;
+        }
+    }
+
+    public void exportExcel(HttpServletResponse response, List<T> list, String sheetName) {
+        this.exportExcel(response, list, sheetName, "");
+    }
+
+    public void exportExcel(HttpServletResponse response, List<T> list, String sheetName, String title) {
+        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+        response.setCharacterEncoding("utf-8");
+        this.init(list, sheetName, title, Type.EXPORT);
+        this.exportExcel(response);
+    }
+
+    public void importTemplateExcel(HttpServletResponse response, String sheetName) {
+        this.importTemplateExcel(response, sheetName, "");
+    }
+
+    public void importTemplateExcel(HttpServletResponse response, String sheetName, String title) {
+        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+        response.setCharacterEncoding("utf-8");
+        this.init((List) null, sheetName, title, Type.IMPORT);
+        this.exportExcel(response);
+    }
+
+    public void exportExcel(HttpServletResponse response) {
+        try {
+            this.writeSheet();
+            this.addSignatureAndDate(this.sheet); // 在写入数据后添加签名和日期
+            this.wb.write(response.getOutputStream());
+        } catch (Exception var6) {
+            log.error("导出Excel异常{}", var6.getMessage());
+        } finally {
+            IOUtils.closeQuietly(this.wb);
+        }
+
+    }
+
+    public void addSignatureAndDate(Sheet sheet) {
+        try {
+            // 获取最后一行的行号
+            int lastRowNum = sheet.getLastRowNum();
+            // 检查是否需要创建新行,如果最后一行不为空,则在其下创建新行
+            int newRowNum = (lastRowNum == 0 || !isRowEmpty(sheet.getRow(lastRowNum))) ? lastRowNum + 2 : lastRowNum;
+            Row signatureAndDateRow = sheet.createRow(newRowNum);
+            Cell signatureCell = signatureAndDateRow.createCell(0);
+            signatureCell.setCellValue("负责人签名:");
+            Cell dateCell = signatureAndDateRow.createCell(4);
+            dateCell.setCellValue("日期:");
+            CellStyle style = this.wb.createCellStyle();
+            Font font = this.wb.createFont();
+            font.setBold(true);
+            style.setFont(font);
+            signatureCell.setCellStyle(style);
+            dateCell.setCellStyle(style);
+
+        } catch (Exception e) {
+            log.error("Error adding signature and date to the Excel sheet.", e);
+        }
+    }
+
+    public void writeSheet() {
+        int sheetNo = Math.max(1, (int) Math.ceil((double) this.list.size() * 1.0D / 65536.0D));
+
+        for (int index = 0; index < sheetNo; ++index) {
+            this.createSheet(sheetNo, index);
+            Row row = this.sheet.createRow(this.rownum);
+            int column = 0;
+            Iterator var5 = this.fields.iterator();
+
+            while (var5.hasNext()) {
+                Object[] os = (Object[]) var5.next();
+                Excel excel = (Excel) os[1];
+                this.createCell(excel, row, column++);
+            }
+
+            if (Type.EXPORT.equals(this.type)) {
+                this.fillExcelData(index, row);
+                this.addStatisticsRow();
+            }
+        }
+
+    }
+
+
+    public void fillExcelData(int index, Row row) {
+        int startNo = index * 65536;
+        int endNo = Math.min(startNo + 65536, this.list.size());
+
+        for (int i = startNo; i < endNo; ++i) {
+            row = this.sheet.createRow(i + 1 + this.rownum - startNo);
+            T vo = this.list.get(i);
+            int column = 0;
+            Iterator var8 = this.fields.iterator();
+
+            while (var8.hasNext()) {
+                Object[] os = (Object[]) var8.next();
+                Field field = (Field) os[0];
+                Excel excel = (Excel) os[1];
+                this.addCell(excel, row, vo, field, column++);
+            }
+        }
+    }
+
+    private Map<String, CellStyle> createStyles(Workbook wb) {
+        Map<String, CellStyle> styles = new HashMap();
+        CellStyle style = wb.createCellStyle();
+        style.setAlignment(HorizontalAlignment.CENTER);
+        style.setVerticalAlignment(VerticalAlignment.CENTER);
+        Font titleFont = wb.createFont();
+        titleFont.setFontName("Arial");
+        titleFont.setFontHeightInPoints((short) 16);
+        titleFont.setBold(true);
+        style.setFont(titleFont);
+        styles.put("title", style);
+        style = wb.createCellStyle();
+        style.setAlignment(HorizontalAlignment.CENTER);
+        style.setVerticalAlignment(VerticalAlignment.CENTER);
+        style.setBorderRight(BorderStyle.THIN);
+        style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
+        style.setBorderLeft(BorderStyle.THIN);
+        style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
+        style.setBorderTop(BorderStyle.THIN);
+        style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
+        style.setBorderBottom(BorderStyle.THIN);
+        style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
+        Font dataFont = wb.createFont();
+        dataFont.setFontName("Arial");
+        dataFont.setFontHeightInPoints((short) 10);
+        style.setFont(dataFont);
+        styles.put("data", style);
+        style = wb.createCellStyle();
+        style.cloneStyleFrom((CellStyle) styles.get("data"));
+        style.setAlignment(HorizontalAlignment.CENTER);
+        style.setVerticalAlignment(VerticalAlignment.CENTER);
+        style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
+        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+        Font headerFont = wb.createFont();
+        headerFont.setFontName("Arial");
+        headerFont.setFontHeightInPoints((short) 10);
+        headerFont.setBold(true);
+        headerFont.setColor(IndexedColors.WHITE.getIndex());
+        style.setFont(headerFont);
+        styles.put("header", style);
+        style = wb.createCellStyle();
+        style.setAlignment(HorizontalAlignment.CENTER);
+        style.setVerticalAlignment(VerticalAlignment.CENTER);
+        Font totalFont = wb.createFont();
+        totalFont.setFontName("Arial");
+        totalFont.setFontHeightInPoints((short) 10);
+        style.setFont(totalFont);
+        styles.put("total", style);
+        style = wb.createCellStyle();
+        style.cloneStyleFrom((CellStyle) styles.get("data"));
+        style.setAlignment(HorizontalAlignment.LEFT);
+        styles.put("data1", style);
+        style = wb.createCellStyle();
+        style.cloneStyleFrom((CellStyle) styles.get("data"));
+        style.setAlignment(HorizontalAlignment.CENTER);
+        styles.put("data2", style);
+        style = wb.createCellStyle();
+        style.cloneStyleFrom((CellStyle) styles.get("data"));
+        style.setAlignment(HorizontalAlignment.RIGHT);
+        styles.put("data3", style);
+        return styles;
+    }
+
+    public Cell createCell(Excel attr, Row row, int column) {
+        Cell cell = row.createCell(column);
+        cell.setCellValue(attr.name());
+        this.setDataValidation(attr, row, column);
+        cell.setCellStyle((CellStyle) this.styles.get("header"));
+        return cell;
+    }
+
+    public void setCellVo(Object value, Excel attr, Cell cell) {
+        if (ColumnType.STRING == attr.cellType()) {
+            String cellValue = Convert.toStr(value);
+            if (StringUtils.startsWithAny(cellValue, FORMULA_STR)) {
+                cellValue = RegExUtils.replaceFirst(cellValue, "=|-|\\+|@", "\t$0");
+            }
+
+            cell.setCellValue(StringUtils.isNull(cellValue) ? attr.defaultValue() : cellValue + attr.suffix());
+        } else if (ColumnType.NUMERIC == attr.cellType()) {
+            if (StringUtils.isNotNull(value)) {
+                cell.setCellValue(StringUtils.contains(Convert.toStr(value), ".") ? Convert.toDouble(value) : (double) Convert.toInt(value));
+            }
+        } else if (ColumnType.IMAGE == attr.cellType()) {
+            ClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1), cell.getRow().getRowNum() + 1);
+            String imagePath = Convert.toStr(value);
+            if (StringUtils.isNotEmpty(imagePath)) {
+                byte[] data = ImageUtils.getImage(imagePath);
+                getDrawingPatriarch(cell.getSheet()).createPicture(anchor, cell.getSheet().getWorkbook().addPicture(data, this.getImageType(data)));
+            }
+        }
+
+    }
+
+    public static Drawing<?> getDrawingPatriarch(Sheet sheet) {
+        if (sheet.getDrawingPatriarch() == null) {
+            sheet.createDrawingPatriarch();
+        }
+
+        return sheet.getDrawingPatriarch();
+    }
+
+    public int getImageType(byte[] value) {
+        String type = FileTypeUtils.getFileExtendName(value);
+        if ("JPG".equalsIgnoreCase(type)) {
+            return 5;
+        } else {
+            return "PNG".equalsIgnoreCase(type) ? 6 : 5;
+        }
+    }
+
+    public void setDataValidation(Excel attr, Row row, int column) {
+        if (attr.name().indexOf("注:") >= 0) {
+            this.sheet.setColumnWidth(column, 6000);
+        } else {
+            this.sheet.setColumnWidth(column, (int) ((attr.width() + 0.72D) * 256.0D));
+        }
+
+        if (StringUtils.isNotEmpty(attr.prompt()) || attr.combo().length > 0) {
+            this.setPromptOrValidation(this.sheet, attr.combo(), attr.prompt(), 1, 100, column, column);
+        }
+
+    }
+
+    public Cell addCell(Excel attr, Row row, T vo, Field field, int column) {
+        Cell cell = null;
+
+        try {
+            row.setHeight(this.maxHeight);
+            if (attr.isExport()) {
+                cell = row.createCell(column);
+                int align = attr.align().value();
+                cell.setCellStyle((CellStyle)this.styles.get("data" + (align >= 1 && align <= 3 ? align : "")));
+                Object value = this.getTargetValue(vo, field, attr);
+                String dateFormat = attr.dateFormat();
+                String readConverterExp = attr.readConverterExp();
+                String separator = attr.separator();
+                if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value)) {
+                    cell.setCellValue(this.parseDateToStr(dateFormat, value));
+                } else if (StringUtils.isNotEmpty(readConverterExp) && StringUtils.isNotNull(value)) {
+                    cell.setCellValue(convertByExp(Convert.toStr(value), readConverterExp, separator));
+                } else if (value instanceof BigDecimal && -1 != attr.scale()) {
+                    cell.setCellValue(((BigDecimal)value).setScale(attr.scale(), attr.roundingMode()).toString());
+                } else if (!attr.handler().equals(ExcelHandlerAdapter.class)) {
+                    cell.setCellValue(this.dataFormatHandlerAdapter(value, attr));
+                } else {
+                    this.setCellVo(value, attr, cell);
+                }
+
+                this.addStatisticsData(column, Convert.toStr(value), attr);
+            }
+        } catch (Exception var12) {
+            log.error("导出Excel失败{}", var12);
+        }
+
+        return cell;
+    }
+
+    public void setPromptOrValidation(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, int firstCol, int endCol) {
+        DataValidationHelper helper = sheet.getDataValidationHelper();
+        DataValidationConstraint constraint = textlist.length > 0 ? helper.createExplicitListConstraint(textlist) : helper.createCustomConstraint("DD1");
+        CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);
+        DataValidation dataValidation = helper.createValidation(constraint, regions);
+        if (StringUtils.isNotEmpty(promptContent)) {
+            dataValidation.createPromptBox("", promptContent);
+            dataValidation.setShowPromptBox(true);
+        }
+
+        if (dataValidation instanceof XSSFDataValidation) {
+            dataValidation.setSuppressDropDownArrow(true);
+            dataValidation.setShowErrorBox(true);
+        } else {
+            dataValidation.setSuppressDropDownArrow(false);
+        }
+
+        sheet.addValidationData(dataValidation);
+    }
+
+    public static String convertByExp(String propertyValue, String converterExp, String separator) {
+        StringBuilder propertyString = new StringBuilder();
+        String[] convertSource = converterExp.split(",");
+        String[] var5 = convertSource;
+        int var6 = convertSource.length;
+
+        for (int var7 = 0; var7 < var6; ++var7) {
+            String item = var5[var7];
+            String[] itemArray = item.split("=");
+            if (StringUtils.containsAny(separator, propertyValue)) {
+                String[] var10 = propertyValue.split(separator);
+                int var11 = var10.length;
+
+                for (int var12 = 0; var12 < var11; ++var12) {
+                    String value = var10[var12];
+                    if (itemArray[0].equals(value)) {
+                        propertyString.append(itemArray[1] + separator);
+                        break;
+                    }
+                }
+            } else if (itemArray[0].equals(propertyValue)) {
+                return itemArray[1];
+            }
+        }
+
+        return StringUtils.stripEnd(propertyString.toString(), separator);
+    }
+
+    public static String reverseByExp(String propertyValue, String converterExp, String separator) {
+        StringBuilder propertyString = new StringBuilder();
+        String[] convertSource = converterExp.split(",");
+        String[] var5 = convertSource;
+        int var6 = convertSource.length;
+
+        for (int var7 = 0; var7 < var6; ++var7) {
+            String item = var5[var7];
+            String[] itemArray = item.split("=");
+            if (StringUtils.containsAny(separator, propertyValue)) {
+                String[] var10 = propertyValue.split(separator);
+                int var11 = var10.length;
+
+                for (int var12 = 0; var12 < var11; ++var12) {
+                    String value = var10[var12];
+                    if (itemArray[1].equals(value)) {
+                        propertyString.append(itemArray[0] + separator);
+                        break;
+                    }
+                }
+            } else if (itemArray[1].equals(propertyValue)) {
+                return itemArray[0];
+            }
+        }
+
+        return StringUtils.stripEnd(propertyString.toString(), separator);
+    }
+
+    public String dataFormatHandlerAdapter(Object value, Excel excel) {
+        try {
+            Object instance = excel.handler().newInstance();
+            Method formatMethod = excel.handler().getMethod("format", Object.class, String[].class);
+            value = formatMethod.invoke(instance, value, excel.args());
+        } catch (Exception var5) {
+            log.error("不能格式化数据 " + excel.handler(), var5.getMessage());
+        }
+
+        return Convert.toStr(value);
+    }
+
+    private void addStatisticsData(Integer index, String text, Excel entity) {
+        if (entity != null && entity.isStatistics()) {
+            Double temp = 0.0D;
+            if (!this.statistics.containsKey(index)) {
+                this.statistics.put(index, temp);
+            }
+
+            try {
+                temp = Double.valueOf(text);
+            } catch (NumberFormatException var6) {
+            }
+
+            this.statistics.put(index, (Double) this.statistics.get(index) + temp);
+        }
+
+    }
+
+    public void addStatisticsRow() {
+        if (this.statistics.size() > 0) {
+            Row row = this.sheet.createRow(this.sheet.getLastRowNum() + 1);
+            Set<Integer> keys = this.statistics.keySet();
+            Cell cell = row.createCell(0);
+            cell.setCellStyle((CellStyle) this.styles.get("total"));
+            cell.setCellValue("合计");
+            Iterator var4 = keys.iterator();
+            while (var4.hasNext()) {
+                Integer key = (Integer) var4.next();
+                cell = row.createCell(key);
+                cell.setCellStyle((CellStyle) this.styles.get("total"));
+                cell.setCellValue(DOUBLE_FORMAT.format(this.statistics.get(key)));
+            }
+
+            this.statistics.clear();
+        }
+
+    }
+
+    private Object getTargetValue(T vo, Field field, Excel excel) throws Exception {
+        Object o = field.get(vo);
+        if (StringUtils.isNotEmpty(excel.targetAttr())) {
+            String target = excel.targetAttr();
+            if (target.contains(".")) {
+                String[] targets = target.split("[.]");
+                String[] var7 = targets;
+                int var8 = targets.length;
+
+                for (int var9 = 0; var9 < var8; ++var9) {
+                    String name = var7[var9];
+                    o = this.getValue(o, name);
+                }
+            } else {
+                o = this.getValue(o, target);
+            }
+        }
+
+        return o;
+    }
+
+    private Object getValue(Object o, String name) throws Exception {
+        if (StringUtils.isNotNull(o) && StringUtils.isNotEmpty(name)) {
+            Class<?> clazz = o.getClass();
+            Field field = clazz.getDeclaredField(name);
+            field.setAccessible(true);
+            o = field.get(o);
+        }
+
+        return o;
+    }
+
+    private void createExcelField() {
+        this.fields = this.getFields();
+        this.fields = (List) this.fields.stream().sorted(Comparator.comparing((objects) -> {
+            return ((Excel) objects[1]).sort();
+        })).collect(Collectors.toList());
+        this.maxHeight = this.getRowHeight();
+    }
+
+    public List<Object[]> getFields() {
+        List<Object[]> fields = new ArrayList();
+        List<Field> tempFields = new ArrayList();
+        tempFields.addAll(Arrays.asList(this.clazz.getSuperclass().getDeclaredFields()));
+        tempFields.addAll(Arrays.asList(this.clazz.getDeclaredFields()));
+        Iterator var3 = tempFields.iterator();
+
+        while (true) {
+            Field field;
+            do {
+                if (!var3.hasNext()) {
+                    return fields;
+                }
+
+                field = (Field) var3.next();
+                if (field.isAnnotationPresent(Excel.class)) {
+                    Excel attr = (Excel) field.getAnnotation(Excel.class);
+                    if (attr != null && (attr.type() == Type.ALL || attr.type() == this.type)) {
+                        field.setAccessible(true);
+                        fields.add(new Object[]{field, attr});
+                    }
+                }
+            } while (!field.isAnnotationPresent(Excels.class));
+
+            Excels attrs = (Excels) field.getAnnotation(Excels.class);
+            Excel[] excels = attrs.value();
+            Excel[] var7 = excels;
+            int var8 = excels.length;
+
+            for (int var9 = 0; var9 < var8; ++var9) {
+                Excel attr = var7[var9];
+                if (attr != null && (attr.type() == Type.ALL || attr.type() == this.type)) {
+                    field.setAccessible(true);
+                    fields.add(new Object[]{field, attr});
+                }
+            }
+        }
+    }
+
+    public short getRowHeight() {
+        double maxHeight = 0.0D;
+
+        Excel excel;
+        for (Iterator var3 = this.fields.iterator(); var3.hasNext(); maxHeight = Math.max(maxHeight, excel.height())) {
+            Object[] os = (Object[]) var3.next();
+            excel = (Excel) os[1];
+        }
+
+        return (short) ((int) (maxHeight * 20.0D));
+    }
+
+    public void createWorkbook() {
+        this.wb = new SXSSFWorkbook(500);
+        this.sheet = this.wb.createSheet();
+        this.wb.setSheetName(0, this.sheetName);
+        this.styles = this.createStyles(this.wb);
+    }
+
+    public void createSheet(int sheetNo, int index) {
+        if (sheetNo > 1 && index > 0) {
+            this.sheet = this.wb.createSheet();
+            this.createTitle();
+            this.wb.setSheetName(index, this.sheetName + index);
+        }
+
+    }
+
+    public Object getCellValue(Row row, int column) {
+        if (row == null) {
+            return row;
+        } else {
+            Object val = "";
+
+            try {
+                Cell cell = row.getCell(column);
+                if (StringUtils.isNotNull(cell)) {
+                    if (cell.getCellType() != CellType.NUMERIC && cell.getCellType() != CellType.FORMULA) {
+                        if (cell.getCellType() == CellType.STRING) {
+                            val = cell.getStringCellValue();
+                        } else if (cell.getCellType() == CellType.BOOLEAN) {
+                            val = cell.getBooleanCellValue();
+                        } else if (cell.getCellType() == CellType.ERROR) {
+                            val = cell.getErrorCellValue();
+                        }
+                    } else {
+                        val = cell.getNumericCellValue();
+                        if (DateUtil.isCellDateFormatted(cell)) {
+                            val = DateUtil.getJavaDate((Double) val);
+                        } else if ((Double) val % 1.0D != 0.0D) {
+                            val = new BigDecimal(val.toString());
+                        } else {
+                            val = (new DecimalFormat("0")).format(val);
+                        }
+                    }
+                }
+
+                return val;
+            } catch (Exception var5) {
+                return val;
+            }
+        }
+    }
+
+    private boolean isRowEmpty(Row row) {
+        if (row == null) {
+            return true;
+        } else {
+            for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); ++i) {
+                Cell cell = row.getCell(i);
+                if (cell != null && cell.getCellType() != CellType.BLANK) {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+    }
+
+    public String parseDateToStr(String dateFormat, Object val) {
+        if (val == null) {
+            return "";
+        } else {
+            String str;
+            if (val instanceof Date) {
+                str = DateUtils.parseDateToStr(dateFormat, (Date) val);
+            } else if (val instanceof LocalDateTime) {
+                str = DateUtils.parseDateToStr(dateFormat, DateUtils.toDate((LocalDateTime) val));
+            } else if (val instanceof LocalDate) {
+                str = DateUtils.parseDateToStr(dateFormat, DateUtils.toDate((LocalDate) val));
+            } else {
+                str = val.toString();
+            }
+
+            return str;
+        }
+    }
+}
+

+ 37 - 5
service-fire/service-fire-biz/src/main/java/com/usky/fire/service/vo/PatrolInspectionRecordExportVo.java

@@ -8,6 +8,7 @@ import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
 
 import java.io.Serializable;
+import java.util.List;
 
 /**
  * <p>
@@ -143,29 +144,60 @@ public class PatrolInspectionRecordExportVo implements Serializable {
      */
     private String creator;
 
+    /**
+     * 巡检备注
+     */
+    @Excel(name = "巡检备注")
+    private String remarks;
+
+    /**
+     * 内容标题
+     */
+    @Excel(name = "内容标题")
+    private List<String> contentTitle;
+
+    /**
+     * 提交方式
+     */
+    @Excel(name = "提交方式")
+    private List<String> submissionMethod;
+
+    /**
+     * 选项内容
+     */
+    @Excel(name = "选项内容")
+    private List<String> optionName;
+
+    /**
+     * 内容备注
+     */
+    @Excel(name = "内容备注")
+    private List<String> contentRemarks;
+
     /**
      * 图片数据
      */
-    @Excel(name = "巡检照片1")
+    @Excel(name = "巡检照片1", cellType = Excel.ColumnType.IMAGE)
     private String imagePath1;
     /**
      * 图片数据
      */
-    @Excel(name = "巡检照片2")
+    @Excel(name = "巡检照片2", cellType = Excel.ColumnType.IMAGE)
     private String imagePath2;
     /**
      * 图片数据
      */
-    @Excel(name = "巡检照片3")
+    @Excel(name = "巡检照片3", cellType = Excel.ColumnType.IMAGE)
     private String imagePath3;
     /**
      * 图片数据
      */
-    @Excel(name = "巡检照片4")
+    @Excel(name = "巡检照片4", cellType = Excel.ColumnType.IMAGE)
     private String imagePath4;
     /**
      * 图片数据
      */
-    @Excel(name = "巡检照片5")
+    @Excel(name = "巡检照片5", cellType = Excel.ColumnType.IMAGE)
     private String imagePath5;
+
 }

+ 7 - 0
service-fire/service-fire-biz/src/main/java/com/usky/fire/service/vo/PlanRecordVo.java

@@ -1,6 +1,7 @@
 package com.usky.fire.service.vo;
 
 import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.usky.fire.domain.PatrolInspectionRecordOption;
 import com.usky.fire.domain.PatrolInspectionRecordPicture;
@@ -143,4 +144,10 @@ public class PlanRecordVo implements Serializable {
      */
     private List<PatrolInspectionRecordOption> recordOptionList;
 
+    /**
+     * 设备ID
+     */
+    @TableField(exist = false)
+    private String deviceId;
+
 }

+ 88 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/controller/web/PmProjectController.java

@@ -0,0 +1,88 @@
+package com.usky.iot.controller.web;
+
+
+import com.usky.common.core.bean.ApiResult;
+import com.usky.common.core.bean.CommonPage;
+import com.usky.common.security.utils.SecurityUtils;
+import com.usky.iot.domain.PmProject;
+import com.usky.iot.service.PmProjectService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * 项目表 前端控制器
+ * </p>
+ *
+ * @author fu
+ * @since 2024-05-20
+ */
+@RestController
+@RequestMapping("/pmProject")
+public class PmProjectController {
+    @Autowired
+    private PmProjectService pmProjectService;
+
+    /**
+     * 查询项目名(下拉框)
+     *
+     * @return
+     */
+    @GetMapping("/projects")
+    public ApiResult<List<PmProject>> queryProjectName() {
+        return ApiResult.success(pmProjectService.queryProject());
+    }
+
+    /**
+     * 分页
+     * @param projectName
+     * @param projectType
+     * @param projectStatus
+     * @param projectAscription
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @GetMapping("/page")
+    public ApiResult<CommonPage<PmProject>> pageList(@RequestParam(value = "projectName", required = false, defaultValue = "") String projectName,
+                                                     @RequestParam(value = "projectType", required = false, defaultValue = "0") Integer projectType,
+                                                     @RequestParam(value = "projectStatus", required = false, defaultValue = "0") Integer projectStatus,
+                                                     @RequestParam(value = "projectAscription", required = false, defaultValue = "0") Integer projectAscription,
+                                                     @RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
+                                                     @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize) {
+        return ApiResult.success(pmProjectService.projectList(projectName, projectType, projectStatus, projectAscription, pageNum, pageSize));
+    }
+
+    /**
+     * 统计
+     * @return
+     */
+    @GetMapping("/counting")
+    public ApiResult<Map<String, Integer>> count() {
+        return ApiResult.success(pmProjectService.sum());
+    }
+
+    /**
+     * 新增项目
+     * @param pmProject
+     */
+    @PostMapping("/add")
+    public void add(@RequestBody PmProject pmProject){
+        pmProjectService.addProject(pmProject);
+    }
+
+    /**
+     * 删除
+     * @param projectId 项目id
+     */
+    @GetMapping("/del")
+    public void del(@RequestParam Integer projectId){
+        pmProjectService.delProject(projectId);
+    }
+
+
+}
+

+ 33 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/controller/web/PmWorkContentController.java

@@ -0,0 +1,33 @@
+package com.usky.iot.controller.web;
+
+
+import com.usky.common.core.bean.ApiResult;
+import com.usky.iot.domain.PmWorkContent;
+import com.usky.iot.service.PmWorkContentService;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.DayOfWeek;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * <p>
+ * 工作内容表 前端控制器
+ * </p>
+ *
+ * @author fu
+ * @since 2024-05-20
+ */
+@RestController
+@RequestMapping("/pmWorkContent")
+public class PmWorkContentController {
+
+}
+

+ 64 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/controller/web/PmWorkReportController.java

@@ -0,0 +1,64 @@
+package com.usky.iot.controller.web;
+
+
+import com.usky.common.core.bean.ApiResult;
+import com.usky.iot.domain.PmWorkReport;
+import com.usky.iot.service.PmWorkReportService;
+import com.usky.iot.service.vo.PmProjectWorkTimeVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.DayOfWeek;
+import java.time.LocalDate;
+import java.time.temporal.TemporalAdjusters;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * 工作报告表 前端控制器
+ * </p>
+ *
+ * @author fu
+ * @since 2024-05-20
+ */
+@RestController
+@RequestMapping("/pmWorkReport")
+public class PmWorkReportController {
+    @Autowired
+    private PmWorkReportService pmWorkReportService;
+
+    /**
+     * 周工作报告查询
+     * @param startDate 开始时间
+     * @param endDate 结束时间
+     * @param id 报告id
+     * @return
+     */
+    @GetMapping("/week")
+    public ApiResult<List<PmWorkReport>> weekWork(@RequestParam(required = false) String startDate,
+                                                  @RequestParam(required = false) String endDate,
+                                                  @RequestParam(required = false, defaultValue = "0") Integer id) {
+
+        return ApiResult.success(pmWorkReportService.weekWork(startDate, endDate, id));
+    }
+
+    /**
+     * 添加工作报告
+     *
+     * @param
+     */
+    @PostMapping("/add")
+    public void add(@RequestBody PmWorkReport pmWorkReport) {
+        pmWorkReportService.addReport(pmWorkReport);
+    }
+
+    /**
+     * 统计工时
+     * @return
+     */
+    @GetMapping("/workTimeTotal")
+    public ApiResult<List<Map<String, Object>>> weekWork(){
+        return ApiResult.success(pmWorkReportService.countTime());
+    }
+}

+ 113 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/domain/PmProject.java

@@ -0,0 +1,113 @@
+package com.usky.iot.domain;
+
+import java.math.BigDecimal;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.time.LocalDateTime;
+import java.io.Serializable;
+
+import lombok.*;
+
+/**
+ * <p>
+ * 项目表
+ * </p>
+ *
+ * @author fu
+ * @since 2024-05-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class PmProject implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 项目表主键ID
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 项目名称
+     */
+    private String projectName;
+
+    /**
+     * 项目开始时间
+     */
+    private LocalDateTime startTime;
+
+    /**
+     * 项目结束时间
+     */
+    private LocalDateTime endTime;
+
+    /**
+     * 项目描述
+     */
+    private String projectDescribe;
+
+    /**
+     * 项目类型(1:人力外包,2:项目研发,3:采购项目,4:过标项目,5:集成项目,6:其他)
+     */
+    private Integer projectType;
+
+    /**
+     * 项目状态(1:未开始;2;进行中;3:已完成;4:已暂停;5:已作废)
+     */
+    private Integer projectStatus;
+
+    /**
+     * 负责人
+     */
+    private Long projectHead;
+
+    /**
+     * 项目成员
+     */
+    private String projectMember;
+
+    /**
+     * 项目工作量(计划人/天)
+     */
+    private BigDecimal projectWorkload;
+
+    /**
+     * 创建者
+     */
+    private String createBy;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新者
+     */
+    private String updateBy;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+
+    /**
+     * 部门ID
+     */
+    private Long deptId;
+
+    /**
+     * 租户ID
+     */
+    private Integer tenantId;
+
+    /**
+     * 删除标识(默认0,已删除1)
+     */
+    private Integer delFlag;
+
+
+
+}

+ 94 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/domain/PmWorkContent.java

@@ -0,0 +1,94 @@
+package com.usky.iot.domain;
+
+import java.math.BigDecimal;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.time.LocalDateTime;
+import java.io.Serializable;
+import java.util.List;
+
+import lombok.*;
+import org.springframework.data.annotation.Transient;
+
+/**
+ * <p>
+ * 工作内容表
+ * </p>
+ *
+ * @author fu
+ * @since 2024-05-20
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class PmWorkContent implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 工作内容表主键ID
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 工作报告表主键ID
+     */
+    private Integer reportId;
+
+    /**
+     * 项目ID
+     */
+    private Integer projectId;
+
+    /**
+     * 项目名称
+     */
+    private String projectName;
+
+    /**
+     * 提交人ID
+     */
+    private Long submitterId;
+
+    /**
+     * 工作内容
+     */
+    private String workContent;
+
+    /**
+     * 工时
+     */
+    private BigDecimal workTime;
+
+    /**
+     * 创建者
+     */
+    private String createBy;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新者
+     */
+    private String updateBy;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+
+    /**
+     * 部门ID
+     */
+    private Long deptId;
+
+    /**
+     * 租户ID
+     */
+    private Integer tenantId;
+
+}

+ 109 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/domain/PmWorkReport.java

@@ -0,0 +1,109 @@
+package com.usky.iot.domain;
+
+import java.math.BigDecimal;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+import lombok.*;
+import org.springframework.data.annotation.Transient;
+
+/**
+ * <p>
+ * 工作报告表
+ * </p>
+ *
+ * @author fu
+ * @since 2024-05-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class PmWorkReport implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 工作报告表主键ID
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 提交人ID
+     */
+    private Long submitterId;
+
+    /**
+     * 报告时间
+     */
+    private LocalDate reportDate;
+
+    /**
+     * 提交时间
+     */
+    private LocalDateTime submitDate;
+
+    /**
+     * 总工时
+     */
+    private BigDecimal totalHours;
+
+    /**
+     * 抄送人
+     */
+    private String ccTo;
+
+    /**
+     * 工作协调
+     */
+    private String coordinateWork;
+
+    /**
+     * 明日计划
+     */
+    private String tomorrowPlan;
+
+    /**
+     * 创建者
+     */
+    private String createBy;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新者
+     */
+    private String updateBy;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+
+    /**
+     * 部门ID
+     */
+    private Long deptId;
+
+    /**
+     * 租户ID
+     */
+    private Integer tenantId;
+
+    /**
+     * 工作报告对应内容
+     */
+    @Transient
+    private List<PmWorkContent> workContents;
+
+
+}

+ 18 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/mapper/PmProjectMapper.java

@@ -0,0 +1,18 @@
+package com.usky.iot.mapper;
+
+import com.usky.iot.domain.PmProject;
+import com.usky.common.mybatis.core.CrudMapper;
+import org.springframework.stereotype.Repository;
+
+/**
+ * <p>
+ * 项目表 Mapper 接口
+ * </p>
+ *
+ * @author fu
+ * @since 2024-05-20
+ */
+@Repository
+public interface PmProjectMapper extends CrudMapper<PmProject> {
+
+}

+ 18 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/mapper/PmWorkContentMapper.java

@@ -0,0 +1,18 @@
+package com.usky.iot.mapper;
+
+import com.usky.iot.domain.PmWorkContent;
+import com.usky.common.mybatis.core.CrudMapper;
+import org.springframework.stereotype.Repository;
+
+/**
+ * <p>
+ * 工作内容表 Mapper 接口
+ * </p>
+ *
+ * @author fu
+ * @since 2024-05-20
+ */
+@Repository
+public interface PmWorkContentMapper extends CrudMapper<PmWorkContent> {
+
+}

+ 18 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/mapper/PmWorkReportMapper.java

@@ -0,0 +1,18 @@
+package com.usky.iot.mapper;
+
+import com.usky.iot.domain.PmWorkReport;
+import com.usky.common.mybatis.core.CrudMapper;
+import org.springframework.stereotype.Repository;
+
+/**
+ * <p>
+ * 工作报告表 Mapper 接口
+ * </p>
+ *
+ * @author fu
+ * @since 2024-05-20
+ */
+@Repository
+public interface PmWorkReportMapper extends CrudMapper<PmWorkReport> {
+
+}

+ 61 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/service/PmProjectService.java

@@ -0,0 +1,61 @@
+package com.usky.iot.service;
+
+import com.usky.common.core.bean.CommonPage;
+import com.usky.iot.domain.PmProject;
+import com.usky.common.mybatis.core.CrudService;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * 项目表 服务类
+ * </p>
+ *
+ * @author fu
+ * @since 2024-05-20
+ */
+public interface PmProjectService extends CrudService<PmProject> {
+
+     /**
+      * 新增、编辑项目
+      * @param project
+      */
+     void addProject(PmProject project);
+
+     /**
+      * 删除
+      * @param projectId 项目id
+      */
+     void delProject(Integer projectId);
+
+
+     List<PmProject> queryProject();
+
+     /**
+      * 分页
+      *
+      * @param projectName       项目名
+      * @param projectType       类型
+      * @param projectStatus     状态
+      * @param projectAscription 项目归属类型
+      * @param pageNum           页码
+      * @param pageSize          页大小
+      * @return
+      */
+     CommonPage<PmProject> projectList(String projectName, Integer projectType, Integer projectStatus, Integer projectAscription, Integer pageNum, Integer pageSize);
+
+     /**
+      * 查询项目名
+      *
+      * @param projectIds
+      * @return
+      */
+     List<PmProject> projectName(List<Integer> projectIds);
+
+     /**
+      * 所有、我负责、我参与项目数量统计
+      * @return
+      */
+     Map<String, Integer> sum();
+}

+ 23 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/service/PmWorkContentService.java

@@ -0,0 +1,23 @@
+package com.usky.iot.service;
+
+import com.usky.iot.domain.PmWorkContent;
+import com.usky.common.mybatis.core.CrudService;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * <p>
+ * 工作内容表 服务类
+ * </p>
+ *
+ * @author fu
+ * @since 2024-05-20
+ */
+public interface PmWorkContentService extends CrudService<PmWorkContent> {
+
+    void deleteContent(Integer reportId);
+
+
+}

+ 43 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/service/PmWorkReportService.java

@@ -0,0 +1,43 @@
+package com.usky.iot.service;
+
+import com.usky.iot.domain.PmWorkContent;
+import com.usky.iot.domain.PmWorkReport;
+import com.usky.common.mybatis.core.CrudService;
+import com.usky.iot.service.vo.PmProjectWorkTimeVo;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * 工作报告表 服务类
+ * </p>
+ *
+ * @author fu
+ * @since 2024-05-20
+ */
+public interface PmWorkReportService extends CrudService<PmWorkReport> {
+
+    /**
+     * 获取时间内工作报告
+     * @param startDate 开始时间
+     * @param endDate 结束时间
+     * @param reportId 报告id
+     * @return
+     */
+    List<PmWorkReport> weekWork(String startDate, String endDate, Integer reportId);
+
+    /**
+     * 新增、编辑工作报告
+     * @param pmWorkReport 工作报告
+     */
+    void addReport(PmWorkReport pmWorkReport);
+
+    /**
+     * 工时计算
+     * @return
+     */
+    List<Map<String, Object>> countTime();
+}

+ 188 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/service/impl/PmProjectServiceImpl.java

@@ -0,0 +1,188 @@
+package com.usky.iot.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+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.PmProject;
+import com.usky.iot.domain.PmWorkContent;
+import com.usky.iot.domain.PmWorkReport;
+import com.usky.iot.mapper.PmProjectMapper;
+import com.usky.iot.mapper.PmWorkContentMapper;
+import com.usky.iot.service.PmProjectService;
+import com.usky.common.mybatis.core.AbstractCrudService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * 项目表 服务实现类
+ * </p>
+ *
+ * @author fu
+ * @since 2024-05-20
+ */
+@Service
+public class PmProjectServiceImpl extends AbstractCrudService<PmProjectMapper, PmProject> implements PmProjectService {
+
+    @Autowired
+    private PmWorkContentMapper pmWorkContentMapper;
+
+    @Override
+    public void addProject(PmProject project) {
+        if (project.getProjectWorkload() == null){
+            if (project.getId() == null) {
+                project.setCreateBy(SecurityUtils.getUsername());
+                project.setCreateTime(LocalDateTime.now());
+                project.setTenantId(SecurityUtils.getTenantId());
+                project.setDeptId(SecurityUtils.getLoginUser().getSysUser().getDeptId());
+                this.save(project);
+            } else {
+                project.setUpdateBy(SecurityUtils.getUsername());
+                project.setUpdateTime(LocalDateTime.now());
+                this.updateById(project);
+            }
+        }else {
+            if (project.getProjectWorkload().scale() > 2) {
+                throw new BusinessException("计划人/天小数位超出长度请重新输入");
+            } else if (project.getProjectWorkload().precision() - project.getProjectWorkload().scale() > 4) {
+                throw new BusinessException("计划人/天整数位超出长度请重新输入");
+            }
+        }
+    }
+
+    @Override
+    public void delProject(Integer projectId) {
+        LambdaQueryWrapper<PmWorkContent> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(PmWorkContent::getProjectId, projectId);
+        List<PmWorkContent> pmWorkContent = pmWorkContentMapper.selectList(queryWrapper);
+        if (pmWorkContent.size() != 0) {
+            throw new BusinessException("该项目下存在日报,无法删除!");
+        } else {
+            LambdaQueryWrapper<PmProject> query = Wrappers.lambdaQuery();
+            query.eq(PmProject::getId, projectId);
+            PmProject project = baseMapper.selectOne(query);
+            project.setDelFlag(1);
+            project.setUpdateBy(SecurityUtils.getUsername());
+            project.setUpdateTime(LocalDateTime.now());
+            baseMapper.updateById(project);
+        }
+    }
+
+    /**
+     * 添加工作报告下拉框
+     * 查询当前租户所有项目
+     *
+     * @return 只返回项目id和名称
+     */
+    @Override
+    public List<PmProject> queryProject() {
+        LambdaQueryWrapper<PmProject> wrapper = Wrappers.lambdaQuery();
+        wrapper.select(PmProject::getId, PmProject::getProjectName)
+                .eq(PmProject::getTenantId, SecurityUtils.getTenantId())
+                .eq(PmProject::getDelFlag, 0)
+                .and(qw -> qw
+                        .eq(PmProject::getProjectHead, SecurityUtils.getUserId())
+                        .or()
+                        .apply("FIND_IN_SET('" + SecurityUtils.getUserId() + "', project_member) > 0")
+                )
+                .in(PmProject::getProjectStatus, 1, 2, 3);
+        List<PmProject> list = this.list(wrapper);
+        return list;
+    }
+
+    /**
+     * 分页
+     *
+     * @param projectName       项目名
+     * @param projectType       类型
+     * @param projectStatus     状态
+     * @param projectAscription 项目归属类型
+     * @param pageNum           页码
+     * @param pageSize          页大小
+     * @return
+     */
+    @Override
+    public CommonPage<PmProject> projectList(String projectName, Integer projectType, Integer projectStatus, Integer projectAscription, Integer pageNum, Integer pageSize) {
+        IPage<PmProject> page = new Page<>(pageNum, pageSize);
+        LambdaQueryWrapper<PmProject> lambdaQuery = Wrappers.lambdaQuery();
+        lambdaQuery.eq(PmProject::getTenantId, SecurityUtils.getTenantId())
+                .eq(PmProject::getDelFlag, 0)
+                .orderByDesc(PmProject::getCreateTime);
+        if (projectAscription == 1) {
+            lambdaQuery.eq(PmProject::getProjectHead, SecurityUtils.getUserId());
+        }
+        if (projectAscription == 2) {
+            lambdaQuery.apply("FIND_IN_SET('" + SecurityUtils.getUserId() + "', project_member) > 0");
+        }
+        if (!projectName.isEmpty()) {
+            lambdaQuery.like(PmProject::getProjectName, projectName);
+        }
+        if (projectType != 0) {
+            lambdaQuery.eq(PmProject::getProjectType, projectType);
+        }
+        if (projectStatus != 0) {
+            lambdaQuery.eq(PmProject::getProjectStatus, projectStatus);
+        }
+        page = this.page(page, lambdaQuery);
+        if (page.getRecords() == null || page.getRecords().isEmpty()) {
+            return new CommonPage<>(Collections.emptyList(), 0, pageSize, pageNum);
+        }
+        return new CommonPage<>(page.getRecords(), page.getTotal(), pageSize, pageNum);
+    }
+
+    /**
+     * 查询项目名
+     *
+     * @param projectIds
+     * @return
+     */
+    @Override
+    public List<PmProject> projectName(List<Integer> projectIds) {
+        LambdaQueryWrapper<PmProject> wrapper = Wrappers.lambdaQuery();
+        wrapper.select(PmProject::getId, PmProject::getProjectName)
+                .in(PmProject::getId, projectIds);
+        return this.list(wrapper);
+    }
+
+    /**
+     * 统计
+     *
+     * @return
+     */
+    @Override
+    public Map<String, Integer> sum() {
+        LambdaQueryWrapper<PmProject> lambdaQuery = Wrappers.lambdaQuery();
+        lambdaQuery.eq(PmProject::getTenantId, SecurityUtils.getTenantId())
+                .eq(PmProject::getDelFlag, 0);
+        Integer all = this.count(lambdaQuery);
+
+        LambdaQueryWrapper<PmProject> lambdaQuery1 = Wrappers.lambdaQuery();
+        lambdaQuery1.eq(PmProject::getTenantId, SecurityUtils.getTenantId())
+                .eq(PmProject::getDelFlag, 0)
+                .eq(PmProject::getProjectHead, SecurityUtils.getUserId());
+        Integer head = this.count(lambdaQuery1);
+
+        LambdaQueryWrapper<PmProject> lambdaQuery2 = Wrappers.lambdaQuery();
+        lambdaQuery2.eq(PmProject::getTenantId, SecurityUtils.getTenantId())
+                .eq(PmProject::getDelFlag, 0)
+                .apply("FIND_IN_SET('" + SecurityUtils.getUserId() + "', project_member) > 0");
+        Integer join = this.count(lambdaQuery2);
+
+        Map<String, Integer> sumMap = new HashMap<>();
+        sumMap.put("allProject", all);
+        sumMap.put("headProject", head);
+        sumMap.put("joinProject", join);
+        return sumMap;
+    }
+
+}

+ 32 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/service/impl/PmWorkContentServiceImpl.java

@@ -0,0 +1,32 @@
+package com.usky.iot.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.usky.iot.domain.PmWorkContent;
+import com.usky.iot.mapper.PmWorkContentMapper;
+import com.usky.iot.service.PmWorkContentService;
+import com.usky.common.mybatis.core.AbstractCrudService;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * <p>
+ * 工作内容表 服务实现类
+ * </p>
+ *
+ * @author fu
+ * @since 2024-05-20
+ */
+@Service
+public class PmWorkContentServiceImpl extends AbstractCrudService<PmWorkContentMapper, PmWorkContent> implements PmWorkContentService {
+
+    @Override
+    public void deleteContent(Integer reportId) {
+        LambdaQueryWrapper<PmWorkContent> deleteWrapper = Wrappers.lambdaQuery();
+        deleteWrapper.eq(PmWorkContent::getReportId,reportId);
+        baseMapper.delete(deleteWrapper);
+    }
+}

+ 313 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/service/impl/PmWorkReportServiceImpl.java

@@ -0,0 +1,313 @@
+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.exception.BusinessException;
+import com.usky.common.security.utils.SecurityUtils;
+import com.usky.iot.domain.PmProject;
+import com.usky.iot.domain.PmWorkContent;
+import com.usky.iot.domain.PmWorkReport;
+import com.usky.iot.mapper.PmProjectMapper;
+import com.usky.iot.mapper.PmWorkContentMapper;
+import com.usky.iot.mapper.PmWorkReportMapper;
+import com.usky.iot.service.PmProjectService;
+import com.usky.iot.service.PmWorkContentService;
+import com.usky.iot.service.PmWorkReportService;
+import com.usky.common.mybatis.core.AbstractCrudService;
+import com.usky.iot.service.vo.PmProjectWorkTimeVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.DayOfWeek;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.temporal.TemporalAdjusters;
+import java.util.*;
+
+
+/**
+ * <p>
+ * 工作报告表 服务实现类
+ * </p>
+ *
+ * @author fu
+ * @since 2024-05-20
+ */
+@Service
+public class PmWorkReportServiceImpl extends AbstractCrudService<PmWorkReportMapper, PmWorkReport> implements PmWorkReportService {
+
+    @Autowired
+    private PmWorkContentMapper pmWorkContentMapper;
+
+    @Autowired
+    private PmWorkReportMapper pmWorkReportMapper;
+
+    @Autowired
+    private PmProjectService pmProjectService;
+
+    @Autowired
+    private PmWorkContentService pmWorkContentService;
+
+    /**
+     * 获取时间内工作报告
+     *
+     * @param startDate 开始时间
+     * @param endDate   结束时间
+     * @param reportId  报告id
+     * @return
+     */
+    @Override
+    public List<PmWorkReport> weekWork(String startDate, String endDate, Integer reportId) {
+        LocalDate startDate1 = null;
+        LocalDate endDate1 = null;
+        if (startDate == null && endDate == null) {
+            startDate1 = LocalDate.now().with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
+            endDate1 = LocalDate.now().with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
+        } else {
+            startDate1 = LocalDate.parse(startDate);
+            endDate1 = LocalDate.parse(endDate);
+        }
+        //固定返回七条数据,没有内容也要设置时间给前端渲染
+        List<LocalDate> dates = new ArrayList<>();
+        while (!startDate1.isAfter(endDate1)) {
+            dates.add(startDate1);
+            startDate1 = startDate1.plusDays(1);
+        }
+        LambdaQueryWrapper<PmWorkReport> queryWrapperR = Wrappers.lambdaQuery();
+        queryWrapperR.select(PmWorkReport::getId, PmWorkReport::getReportDate, PmWorkReport::getSubmitDate, PmWorkReport::getTomorrowPlan, PmWorkReport::getCoordinateWork, PmWorkReport::getCcTo)
+                .eq(PmWorkReport::getSubmitterId, SecurityUtils.getUserId())
+                .between(PmWorkReport::getReportDate, startDate, endDate)
+                .orderByAsc(PmWorkReport::getReportDate)
+                .apply(reportId != 0, "id = " + reportId);
+        List<PmWorkReport> reports = this.list(queryWrapperR);
+        if (reports.isEmpty()) {
+            List<PmWorkReport> reports1 = new ArrayList<>();
+            for (int f = 0; f < dates.size(); f++) {
+                List<PmWorkContent> content = new ArrayList<>();
+                PmWorkReport report1 = new PmWorkReport();
+                report1.setReportDate(dates.get(f));
+                report1.setWorkContents(content);
+                reports1.add(report1);
+            }
+            return reports1;
+        }
+        List<Integer> ids = new ArrayList<>();
+        for (PmWorkReport pwr : reports) {
+            ids.add(pwr.getId());
+        }
+        LambdaQueryWrapper<PmWorkContent> queryWrapperC = Wrappers.lambdaQuery();
+        queryWrapperC.select(PmWorkContent::getId, PmWorkContent::getWorkContent, PmWorkContent::getWorkTime, PmWorkContent::getProjectId, PmWorkContent::getProjectName, PmWorkContent::getReportId)
+                .in(PmWorkContent::getReportId, ids)
+                .orderByDesc(PmWorkContent::getWorkTime);
+        List<PmWorkContent> contents = pmWorkContentMapper.selectList(queryWrapperC);
+        int a, b;
+        for (int i = 0; i < reports.size(); i++) {
+            a = reports.get(i).getId();
+            List<PmWorkContent> contentList = new ArrayList<>();
+            for (int j = 0; j < contents.size(); j++) {
+                b = contents.get(j).getReportId();
+                if (b == a) {
+                    contentList.add(contents.get(j));
+                }
+            }
+            reports.get(i).setWorkContents(contentList);
+        }
+        if (reports.size() == 7 || reportId != 0) {
+            return reports;
+        }
+        List<PmWorkReport> reportList = new ArrayList<>();
+        for (int d = 0; d < dates.size(); d++) {
+            boolean matchFound = false;
+            for (int c = 0; c < reports.size(); c++) {
+                if (dates.get(d).isEqual(reports.get(c).getReportDate())) {
+                    reportList.add(reports.get(c));
+                    matchFound = true;
+                    break;
+                }
+            }
+            if (!matchFound) {
+                PmWorkReport newReport = new PmWorkReport();
+                List<PmWorkContent> newContent = new ArrayList<>();
+                newReport.setReportDate(dates.get(d));
+                newReport.setWorkContents(newContent);
+                reportList.add(newReport);
+            }
+        }
+        return reportList;
+    }
+
+    /**
+     * 新增、编辑工作报告
+     */
+    @Override
+    public void addReport(PmWorkReport pmWorkReport) {
+        BigDecimal totalWorkTime = BigDecimal.ZERO; //计算总工时
+        int size = pmWorkReport.getWorkContents().size();
+        for (int p = 0; p < size; p++) {
+            for (int q = p + 1; q < size; q++) {
+                if (pmWorkReport.getWorkContents().get(p).getProjectId() == pmWorkReport.getWorkContents().get(q).getProjectId()) {
+                    throw new BusinessException("存在重复项目,请检查!");
+                }
+            }
+        }
+        for (PmWorkContent a : pmWorkReport.getWorkContents()) {
+            totalWorkTime = totalWorkTime.add(a.getWorkTime());
+        }
+        //判断总工时是否超过24h
+        BigDecimal noeDay = BigDecimal.valueOf(24);
+        int compareResult = totalWorkTime.compareTo(noeDay);
+        if (compareResult >= 0) {
+            throw new BusinessException("一天24小时都不够你用,请检查当日总工时!");
+        } else if (totalWorkTime == null || totalWorkTime.equals(BigDecimal.ZERO) || totalWorkTime.compareTo(BigDecimal.ZERO) < 0) {
+            throw new BusinessException("工时不能为空!");
+        }
+        //判断是否携带reportId,不写带则为新增报告,携带则为编辑(更新)项目
+        if (pmWorkReport.getId() == null) {
+            PmWorkReport newReport = new PmWorkReport();
+            newReport.setReportDate(pmWorkReport.getReportDate());
+            newReport.setSubmitterId(SecurityUtils.getUserId());
+            newReport.setSubmitDate(LocalDateTime.now());
+            newReport.setCcTo(pmWorkReport.getCcTo());
+            newReport.setCoordinateWork(pmWorkReport.getCoordinateWork());
+            newReport.setTomorrowPlan(pmWorkReport.getTomorrowPlan());
+            newReport.setCreateBy(SecurityUtils.getUsername());
+            newReport.setCreateTime(LocalDateTime.now());
+            newReport.setDeptId(SecurityUtils.getLoginUser().getSysUser().getDeptId());
+            newReport.setTenantId(SecurityUtils.getTenantId());
+            newReport.setTotalHours(totalWorkTime);
+            pmWorkReportMapper.insert(newReport);
+            //获取报告中所有项目id
+            List<Integer> projectIds = new ArrayList<>();
+            for (PmWorkContent b1 : pmWorkReport.getWorkContents()) {
+                projectIds.add(b1.getProjectId());
+            }
+            //查出所有项目id对应项目名
+            List<PmProject> project = pmProjectService.projectName(projectIds);
+            //将项目名重新赋值
+            for (PmWorkContent b : pmWorkReport.getWorkContents()) {
+                for (int c = 0; c < project.size(); c++) {
+                    if (b.getProjectId() == project.get(c).getId()) {
+                        b.setProjectName(project.get(c).getProjectName());
+                    }
+                }
+                PmWorkContent newContent = new PmWorkContent();
+                newContent.setReportId(newReport.getId());
+                newContent.setProjectId(b.getProjectId());
+                projectIds.add(b.getReportId());
+                newContent.setProjectName(b.getProjectName());
+                newContent.setSubmitterId(SecurityUtils.getUserId());
+                newContent.setWorkContent(b.getWorkContent());
+                newContent.setWorkTime(b.getWorkTime());
+                newContent.setCreateBy(SecurityUtils.getUsername());
+                newContent.setCreateTime(LocalDateTime.now());
+                newContent.setDeptId(SecurityUtils.getLoginUser().getSysUser().getDeptId());
+                newContent.setTenantId(SecurityUtils.getTenantId());
+                pmWorkContentMapper.insert(newContent);
+            }
+        } else {
+            PmWorkReport rp = new PmWorkReport();
+            rp.setId(pmWorkReport.getId());
+            rp.setReportDate(pmWorkReport.getReportDate());
+            rp.setSubmitterId(pmWorkReport.getSubmitterId());
+            rp.setSubmitDate(LocalDateTime.now());
+            rp.setCcTo(pmWorkReport.getCcTo());
+            rp.setCoordinateWork(pmWorkReport.getCoordinateWork());
+            rp.setTomorrowPlan(pmWorkReport.getTomorrowPlan());
+            rp.setCreateBy(pmWorkReport.getCreateBy());
+            rp.setCreateTime(pmWorkReport.getCreateTime());
+            rp.setUpdateBy(SecurityUtils.getUsername());
+            rp.setUpdateTime(LocalDateTime.now());
+            rp.setDeptId(pmWorkReport.getDeptId());
+            rp.setTenantId(pmWorkReport.getTenantId());
+            rp.setUpdateBy(SecurityUtils.getUsername());
+            rp.setUpdateTime(LocalDateTime.now());
+            pmWorkReportMapper.updateById(rp);
+
+            LambdaQueryWrapper<PmWorkContent> queryWrapper = Wrappers.lambdaQuery();
+            queryWrapper.select(PmWorkContent::getReportId, PmWorkContent::getSubmitterId, PmWorkContent::getCreateBy, PmWorkContent::getCreateTime, PmWorkContent::getDeptId, PmWorkContent::getTenantId)
+                    .eq(PmWorkContent::getReportId, pmWorkReport.getId())
+                    .last("LIMIT 1");
+            PmWorkContent f = pmWorkContentMapper.selectOne(queryWrapper);
+            pmWorkContentService.deleteContent(pmWorkReport.getId());
+            List<PmWorkContent> contents = pmWorkReport.getWorkContents();
+            for (PmWorkContent e : contents) {
+                e.setReportId(f.getReportId());
+                e.setUpdateBy(SecurityUtils.getUsername());
+                e.setUpdateTime(LocalDateTime.now());
+                e.setSubmitterId(f.getSubmitterId());
+                e.setCreateTime(f.getCreateTime());
+                e.setCreateBy(f.getCreateBy());
+                e.setDeptId(f.getDeptId());
+                e.setTenantId(f.getTenantId());
+                pmWorkContentMapper.insert(e);
+            }
+        }
+    }
+
+    @Override
+    public List<Map<String, Object>> countTime() {
+        int scale = 2;
+        RoundingMode roundingMode = RoundingMode.HALF_UP;
+        List<Map<String, Object>> returnList = new ArrayList<>();
+        Map<String, Object> weekTotalMap = new HashMap<>();
+        Map<String, Object> monthTotalMap = new HashMap<>();
+        Map<String, Object> weekMap = new HashMap<>();
+        Map<String, Object> monthMap = new HashMap<>();
+        List<PmProjectWorkTimeVo> returnListW = new ArrayList<>();
+        List<PmProjectWorkTimeVo> returnListM = new ArrayList<>();
+        LocalDate today = LocalDate.now();
+        LocalDate startOfWeek = today.with(TemporalAdjusters.previousOrSame(java.time.DayOfWeek.MONDAY));
+        LocalDate endOfWeek = today.with(TemporalAdjusters.nextOrSame(java.time.DayOfWeek.SUNDAY));
+        LocalDate startOfMonth = today.withDayOfMonth(1);
+        LocalDate endOfMonth = today.withDayOfMonth(today.lengthOfMonth());
+        BigDecimal weekTotal = BigDecimal.ZERO;
+        LambdaQueryWrapper<PmWorkContent> wrapperW = Wrappers.lambdaQuery();
+        wrapperW.eq(PmWorkContent::getSubmitterId,SecurityUtils.getUserId())
+                .between(PmWorkContent::getCreateTime,startOfWeek,endOfWeek);
+        List<PmWorkContent> week = pmWorkContentMapper.selectList(wrapperW);
+        if (week.isEmpty()){
+            weekTotalMap.put("WeekWorkTimeTotal",0);
+            weekMap.put("WeeklyData",week);
+        }
+        for (int i = 0; i < week.size(); i++) {
+            weekTotal = weekTotal.add(week.get(i).getWorkTime());
+        }
+        BigDecimal monthTotal = BigDecimal.ZERO;
+        LambdaQueryWrapper<PmWorkContent> wrapperM = Wrappers.lambdaQuery();
+        wrapperM.eq(PmWorkContent::getSubmitterId,SecurityUtils.getUserId())
+                .between(PmWorkContent::getCreateTime,startOfMonth,endOfMonth);
+        List<PmWorkContent> month = pmWorkContentMapper.selectList(wrapperW);
+        if (month.isEmpty()){
+            monthTotalMap.put("MonthWorkTimeTotal",0);
+            monthMap.put("MonthlyData",month);
+        }
+        for (int j = 0; j < month.size(); j++) {
+            monthTotal = monthTotal.add(month.get(j).getWorkTime());
+        }
+        for (int a = 0; a < week.size(); a++) {
+            PmProjectWorkTimeVo workTimeVo = new PmProjectWorkTimeVo();
+            workTimeVo.setProjectName(week.get(a).getProjectName());
+            workTimeVo.setWorkTime(week.get(a).getWorkTime());
+            workTimeVo.setPercentage(week.get(a).getWorkTime().divide(weekTotal, scale, roundingMode));
+            returnListW.add(workTimeVo);
+        }
+        for (int b = 0; b < month.size(); b++) {
+            PmProjectWorkTimeVo workTimeVo = new PmProjectWorkTimeVo();
+            workTimeVo.setProjectName(month.get(b).getProjectName());
+            workTimeVo.setWorkTime(month.get(b).getWorkTime());
+            workTimeVo.setPercentage(month.get(b).getWorkTime().divide(weekTotal, scale, roundingMode));
+            returnListM.add(workTimeVo);
+        }
+        weekTotalMap.put("WeekWorkTimeTotal",weekTotal);
+        monthTotalMap.put("MonthWorkTimeTotal",monthTotal);
+        weekMap.put("WeeklyData",returnListW);
+        monthMap.put("MonthlyData",returnListM);
+        returnList.add(weekTotalMap);
+        returnList.add(monthTotalMap);
+        returnList.add(weekMap);
+        returnList.add(monthMap);
+        return returnList;
+    }
+}

+ 29 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/service/vo/PmProjectWorkTimeVo.java

@@ -0,0 +1,29 @@
+package com.usky.iot.service.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @description:TODO
+ * @author: fu
+ * @create: 2024-05-30 16:40
+ */
+@Data
+public class PmProjectWorkTimeVo {
+    /**
+     * 项目名
+     */
+    private String projectName;
+
+    /**
+     * 项目工时
+     */
+    private BigDecimal workTime;
+
+    /**
+     * 项目工时占比
+     */
+    private BigDecimal percentage;
+}
+

+ 26 - 0
service-iot/service-iot-biz/src/main/resources/mapper/iot/PmProjectMapper.xml

@@ -0,0 +1,26 @@
+<?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.PmProjectMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.usky.iot.domain.PmProject">
+        <id column="id" property="id" />
+        <result column="project_name" property="projectName" />
+        <result column="start_time" property="startTime" />
+        <result column="end_time" property="endTime" />
+        <result column="project_describe" property="projectDescribe" />
+        <result column="project_type" property="projectType" />
+        <result column="project_status" property="projectStatus" />
+        <result column="project_head" property="projectHead" />
+        <result column="project_member" property="projectMember" />
+        <result column="project_workload" property="projectWorkload" />
+        <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" />
+        <result column="del_flag" property="delFlag" />
+    </resultMap>
+
+</mapper>

+ 22 - 0
service-iot/service-iot-biz/src/main/resources/mapper/iot/PmWorkContentMapper.xml

@@ -0,0 +1,22 @@
+<?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.PmWorkContentMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.usky.iot.domain.PmWorkContent">
+        <id column="id" property="id" />
+        <result column="report_id" property="reportId" />
+        <result column="project_id" property="projectId" />
+        <result column="project_name" property="projectName" />
+        <result column="submitter_id" property="submitterId" />
+        <result column="work_content" property="workContent" />
+        <result column="work_time" property="workTime" />
+        <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>

+ 23 - 0
service-iot/service-iot-biz/src/main/resources/mapper/iot/PmWorkReportMapper.xml

@@ -0,0 +1,23 @@
+<?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.PmWorkReportMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.usky.iot.domain.PmWorkReport">
+        <id column="id" property="id" />
+        <result column="submitter_id" property="submitterId" />
+        <result column="report_date" property="reportDate" />
+        <result column="submit_date" property="submitDate" />
+        <result column="total_hours" property="totalHours" />
+        <result column="cc_to" property="ccTo" />
+        <result column="coordinate_work" property="coordinateWork" />
+        <result column="tomorrow_plan" property="tomorrowPlan" />
+        <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>