Эх сурвалжийг харах

新增本年 履职任务完成数量统计定时任务

zhulu 1 сар өмнө
parent
commit
d49f3c9053

+ 3 - 0
soc-api/soc-api-system/src/main/java/com/xunmei/system/api/RemoteResumptionTaskService.java

@@ -52,4 +52,7 @@ public interface RemoteResumptionTaskService {
 
     @GetMapping(value = "/api/plan/buildPdf")
     AjaxResult buildPdf();
+
+    @GetMapping(value = "/cockpit/statistic/resumption")
+    R<Boolean> statisticTaskCount();
 }

+ 5 - 0
soc-api/soc-api-system/src/main/java/com/xunmei/system/api/factory/RemoteResumptionTaskFallbackFactory.java

@@ -71,6 +71,11 @@ public class RemoteResumptionTaskFallbackFactory implements FallbackFactory<Remo
                 return AjaxResult.error();
             }
 
+            @Override
+            public R<Boolean> statisticTaskCount() {
+                return R.fail();
+            }
+
 
         };
     }

+ 4 - 4
soc-api/soc-api-system/src/main/java/com/xunmei/system/api/function/RemoteCallHandlerExecutor.java

@@ -20,21 +20,21 @@ public class RemoteCallHandlerExecutor {
             if (handle instanceof AjaxResult) {
                 final AjaxResult ajaxResult = (AjaxResult) handle;
                 if (!ajaxResult.isSuccess()) {
-                    throw new SystemException(ErrorMsgConstants.REMOTE_CALL_ERROR + errorMessage);
+                    throw new SystemException(ErrorMsgConstants.REMOTE_CALL_ERROR + errorMessage +" ajaxResult.isSuccess false");
                 }
             }
             if (handle instanceof R) {
                 final R result = (R) handle;
                 if (!R.isSuccess(result)) {
-                    throw new SystemException(ErrorMsgConstants.REMOTE_CALL_ERROR + errorMessage);
+                    throw new SystemException(ErrorMsgConstants.REMOTE_CALL_ERROR + errorMessage +" R.isSuccess false");
                 }
             }
             if (ObjectUtil.isNull(handle)) {
-                throw new SystemException(ErrorMsgConstants.REMOTE_CALL_ERROR + errorMessage);
+                throw new SystemException(ErrorMsgConstants.REMOTE_CALL_ERROR + errorMessage+" 返回值为空");
             }
             return handle;
         } catch (Exception e) {
-            throw new SystemException(ErrorMsgConstants.REMOTE_CALL_ERROR + errorMessage);
+            throw new SystemException(ErrorMsgConstants.REMOTE_CALL_ERROR + errorMessage+e.getMessage()+e.getStackTrace());
         }
     }
 }

+ 11 - 0
soc-modules/soc-modules-core/src/main/java/com/xunmei/core/board/controller/WebCockpitController.java

@@ -36,6 +36,17 @@ public class WebCockpitController extends BaseController {
     }
 
 
+
+    @GetMapping("/statistic/resumption")
+    public AjaxResult statisticResumptionTaskCount() {
+        try {
+            cockpitService.statisticCurrentYearResumptionTaskCount();
+            return AjaxResult.success("提前统计机构履职任务完成数量成功");
+        } catch (Exception e) {
+            return AjaxResult.error("提前统计机构履职任务完成数量失败"+e.getMessage()+e.getStackTrace());
+        }
+    }
+
     /**
      * 统计近期下级机构安全检查情况
      */

+ 64 - 0
soc-modules/soc-modules-core/src/main/java/com/xunmei/core/board/domain/ResumptionTaskCount.java

@@ -0,0 +1,64 @@
+package com.xunmei.core.board.domain;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.xunmei.common.core.utils.Ymd;
+import com.xunmei.common.core.web.domain.BaseEntity;
+import com.xunmei.core.resumption.domain.AppPlan;
+import com.xunmei.system.api.domain.SysOrg;
+import feign.form.FormData;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Date;
+import java.util.List;
+
+
+/**
+ * 履职
+ */
+@Data
+@AllArgsConstructor
+@Builder
+@TableName("core_resumption_task_count_statistic")
+public class ResumptionTaskCount extends BaseEntity {
+
+    private static Logger log = LoggerFactory.getLogger(ResumptionTaskCount.class);
+
+    /**
+     * 编号
+     */
+    @TableId
+    private Long id;
+
+    /**
+     * 机构
+     */
+    private Long orgId;
+
+    /**
+     * 机构路径
+     */
+    private String orgPath;
+
+    /**
+     * 任务总数
+     */
+    private Integer taskTotal;
+
+
+    /**
+     * 已完成数目
+     */
+    private Integer completedCount;
+
+    public ResumptionTaskCount() {
+    }
+}

+ 3 - 0
soc-modules/soc-modules-core/src/main/java/com/xunmei/core/board/mapper/CockpitMapper.java

@@ -1,6 +1,7 @@
 package com.xunmei.core.board.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.xunmei.core.board.domain.ResumptionTaskCount;
 import com.xunmei.core.board.dto.web.OrgMapDto;
 import com.xunmei.core.board.dto.web.WebGA38InfoDto;
 import com.xunmei.core.board.dto.web.WebSyntheticQuestionDto;
@@ -14,6 +15,8 @@ import java.util.Map;
 public interface CockpitMapper extends BaseMapper {
     List<TaskStatisticVo> resumption(@Param("startDate") Date start,@Param("endDate") Date end,@Param("orgPath") String orgPath);
 
+    ResumptionTaskStatisticVo statisticOneOrgResumptionTask(@Param("startDate") Date startDate, @Param("endDate") Date endDate, @Param("orgId") Long orgId);
+
     List<WebSafetyCheckVo> safetyCheck(@Param("startDate") Date start,@Param("endDate") Date end,@Param("orgPath") String orgPath);
 
     List<TaskStatisticVo> edu(@Param("startDate") Date start,@Param("endDate") Date end,@Param("orgPath") String orgPath);

+ 18 - 0
soc-modules/soc-modules-core/src/main/java/com/xunmei/core/board/mapper/ResumptionTaskCountMapper.java

@@ -0,0 +1,18 @@
+package com.xunmei.core.board.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.xunmei.core.board.domain.ResumptionTaskCount;
+import org.apache.ibatis.annotations.Delete;
+
+/**
+ * @Description: 类描述
+ * @Author: LuZhu
+ * @CreateDate: 2025/9/19 14:38
+ */
+public interface ResumptionTaskCountMapper extends BaseMapper<ResumptionTaskCount> {
+    /**
+     * 强制清空整张表(绕过 MyBatis-Plus 全表删除保护)
+     */
+    @Delete("DELETE FROM core_resumption_task_count_statistic WHERE org_id is not null")
+    void deleteAll();
+}

+ 2 - 0
soc-modules/soc-modules-core/src/main/java/com/xunmei/core/board/service/CockpitService.java

@@ -11,6 +11,8 @@ public interface CockpitService {
      */
     List<TaskStatisticVo> resumption(TaskStatisticDto dto);
 
+    void statisticCurrentYearResumptionTaskCount();
+
     /**
      * 统计近期下级机构安全检查情况
      */

+ 12 - 0
soc-modules/soc-modules-core/src/main/java/com/xunmei/core/board/service/ResumptionTaskCountService.java

@@ -0,0 +1,12 @@
+package com.xunmei.core.board.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.xunmei.core.board.domain.ResumptionTaskCount;
+
+/**
+ * @Description: 类描述
+ * @Author: LuZhu
+ * @CreateDate: 2025/9/19 14:39
+ */
+public interface ResumptionTaskCountService extends IService<ResumptionTaskCount> {
+}

+ 133 - 4
soc-modules/soc-modules-core/src/main/java/com/xunmei/core/board/service/impl/CockpitServiceImpl.java

@@ -2,32 +2,42 @@ package com.xunmei.core.board.service.impl;
 
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.xunmei.common.core.constant.SecurityConstants;
 import com.xunmei.common.core.domain.DateRange;
+import com.xunmei.common.core.domain.R;
 import com.xunmei.common.core.enums.CycleCommonEnum;
 import com.xunmei.common.core.enums.OrgTypeEnum;
 import com.xunmei.common.core.exception.ServiceException;
 import com.xunmei.common.core.utils.DateUtils;
+import com.xunmei.common.core.utils.IDHelper;
 import com.xunmei.common.core.utils.NumberUtils;
 import com.xunmei.common.core.utils.StringUtils;
+import com.xunmei.core.board.domain.ResumptionTaskCount;
 import com.xunmei.core.board.dto.web.OrgMapDto;
 import com.xunmei.core.board.dto.web.TaskStatisticDto;
 import com.xunmei.core.board.dto.web.WebSyntheticQuestionDto;
 import com.xunmei.core.board.enums.PeriodEnum;
 import com.xunmei.core.board.mapper.CockpitMapper;
+import com.xunmei.core.board.mapper.ResumptionTaskCountMapper;
 import com.xunmei.core.board.service.CockpitService;
+import com.xunmei.core.board.service.ResumptionTaskCountService;
 import com.xunmei.core.board.vo.web.*;
 import com.xunmei.system.api.RemoteDictDataService;
 import com.xunmei.system.api.RemoteOrgService;
 import com.xunmei.system.api.domain.SysDictData;
 import com.xunmei.system.api.domain.SysOrg;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.http.annotation.Obsolete;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import java.util.*;
 import java.util.stream.Collectors;
-
+@Slf4j
 @Service
 public class CockpitServiceImpl implements CockpitService {
     @Resource
@@ -39,15 +49,134 @@ public class CockpitServiceImpl implements CockpitService {
     @Resource
     RemoteDictDataService remoteDictDataService;
 
+    @Resource
+    ResumptionTaskCountMapper resumptionTaskCountMapper;
+
+    @Resource
+    ResumptionTaskCountService resumptionTaskCountService;
+
+
+
     @Override
     public List<TaskStatisticVo> resumption(TaskStatisticDto dto) {
+        List<TaskStatisticVo> list;
         Date date = getStartDate(dto.getPeriod());
         SysOrg org = getOrgThrowIfNull(dto.getOrgId());
         String orgPath = org.getPath();
-        List<TaskStatisticVo> list = cockpitMapper.resumption(date, DateUtil.endOfDay(new Date()), orgPath);
-//        return taskStatistic(list, org, Arrays.asList(OrgTypeEnum.LIHANG_ZIZHU_YINGHANG.getCode(), OrgTypeEnum.YINGYE_WANGDIAN.getCode()));
+
+        // 判断是否为本年查询
+        if (PeriodEnum.ThisYear.getCode().equals(dto.getPeriod())) {
+            list= handleThisYearCase(org.getPath());
+        } else {
+            list = cockpitMapper.resumption(date, DateUtil.endOfDay(new Date()), orgPath);
+        }
         return taskStatistic(list, org, Arrays.asList(OrgTypeEnum.YINGYE_WANGDIAN.getCode()));
     }
+    /**
+     * 处理“本年”特殊逻辑
+     */
+    private List<TaskStatisticVo> handleThisYearCase(String orgPath)
+    {
+        // 1. 从统计表获取历史数据(年初到昨天)
+        List<TaskStatisticVo> list = resumptionTaskCountService.list().stream().map(this::convertToVo).collect(Collectors.toList());
+
+        // 2. 实时查询今日数据
+        List<TaskStatisticVo> toDayTaskStatistic = cockpitMapper.resumption(DateUtil.beginOfDay(new Date()), DateUtil.endOfDay(new Date()), orgPath);
+
+        // 3. 统计表数据为空 直接返回 实时查询的今日数据
+        if(CollectionUtils.isEmpty(list))
+        {
+            return toDayTaskStatistic;
+        }
+
+        // 4. 合并:按 orgId 聚合,任务数和完成数相加
+        Map<Long, TaskStatisticVo> map = new HashMap<>(list.size());
+        for (TaskStatisticVo task : list) {
+            map.put(task.getOrgId(),task);
+        }
+
+        toDayTaskStatistic.stream().forEach(x->{
+            TaskStatisticVo existing = map.get(x.getOrgId());
+            if (existing != null) {
+                existing.setTaskTotal(existing.getTaskTotal() + x.getTaskTotal());
+                existing.setCompletedCount(existing.getCompletedCount() + x.getCompletedCount());
+            } else {
+                map.put(x.getOrgId(), x);
+            }
+        });
+
+        return new ArrayList<>(map.values());
+    }
+
+    /**
+     * VO 转换:Entity -> VO
+     */
+    private TaskStatisticVo convertToVo(ResumptionTaskCount x) {
+        TaskStatisticVo vo = new TaskStatisticVo();
+        vo.setOrgId(x.getOrgId());
+        vo.setOrgPath(x.getOrgPath());
+        vo.setTaskTotal(x.getTaskTotal());
+        vo.setCompletedCount(x.getCompletedCount());
+        return vo;
+    }
+
+    /**
+     * VO 转换:VO -> Entity
+     */
+    private ResumptionTaskCount convertToEntity(ResumptionTaskStatisticVo vo,SysOrg org) {
+        ResumptionTaskCount entity = new ResumptionTaskCount();
+        entity.setId(IDHelper.id());
+        entity.setOrgId(org.getId());
+        entity.setOrgPath(org.getPath());
+        entity.setTaskTotal(vo.getTaskTotal());
+        entity.setCreateTime(new Date());
+        entity.setCompletedCount(ObjectUtil.isNull(vo.getCompletedCount()) ? 0: vo.getCompletedCount());
+        return entity;
+    }
+
+    /**
+     * 由于履职任务数据量较大,为提高查询速度,定时提前统计机构任务数据
+     * 统计每个机构本年内的履职任务总数量和已完成数量
+     * 统计范围:年初到当前时间的前一天
+     */
+    @Async
+    @Override
+    @Transactional
+    public void statisticCurrentYearResumptionTaskCount() {
+        try {
+            log.info("开始:统计本年履职任务数量和已完成数量");
+            Date startDate = getStartDate(PeriodEnum.ThisYear.getCode());
+            Date endDate = DateUtil.offsetDay(DateUtil.endOfDay(new Date()), -1);
+
+            //开年第一天不统计
+            if(endDate.before(startDate))
+            {
+                //删除前一年的结果
+                resumptionTaskCountMapper.deleteAll();
+                return;
+            }
+
+            final R<List<SysOrg>> allOrgResult = remoteOrgService.getAllOrg(SecurityConstants.INNER);
+            if (allOrgResult == null || allOrgResult.getData() == null || allOrgResult.getData().isEmpty()) {
+                return;
+            }
+            List<SysOrg> allOrg = allOrgResult.getData();
+            List<ResumptionTaskCount> taskCountList =new ArrayList<>();
+            for (SysOrg org : allOrg) {
+                ResumptionTaskStatisticVo taskStatisticVo = cockpitMapper.statisticOneOrgResumptionTask(startDate, endDate, org.getId());
+                if(taskStatisticVo!=null && taskStatisticVo.getTaskTotal()!=null &&  taskStatisticVo.getTaskTotal()>0)
+                {
+                    taskCountList.add(convertToEntity(taskStatisticVo,org));
+                }
+            }
+            //先删除,再插入
+            resumptionTaskCountMapper.deleteAll();
+            resumptionTaskCountService.saveBatch(taskCountList);
+            log.info("结束:统计本年履职任务数量和已完成数量");
+        } catch (Exception ex) {
+            log.error("提前统计本年履职任务数量和已完成数量失败:{},{}",ex.getMessage(),ex.getStackTrace());
+        }
+    }
 
     @Override
     public List<WebSafetyCheckVo> safetyCheck(TaskStatisticDto dto) {
@@ -259,7 +388,7 @@ public class CockpitServiceImpl implements CockpitService {
     /**
      * 本月来访
      *
-     * @param orgPath
+     * @param orgId
      * @return
      */
     @Override

+ 18 - 0
soc-modules/soc-modules-core/src/main/java/com/xunmei/core/board/service/impl/ResumptionTaskCountServiceImpl.java

@@ -0,0 +1,18 @@
+package com.xunmei.core.board.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.xunmei.core.board.domain.ResumptionTaskCount;
+import com.xunmei.core.board.mapper.ResumptionTaskCountMapper;
+import com.xunmei.core.board.service.ResumptionTaskCountService;
+import org.springframework.stereotype.Service;
+
+/**
+ * @ClassName ResumptionTaskCountServiceImpl
+ * @Description: 类描述
+ * @Author: LuZhu
+ * @CreateDate: 2025/9/19 16:23
+ */
+@Service
+public class ResumptionTaskCountServiceImpl extends ServiceImpl<ResumptionTaskCountMapper, ResumptionTaskCount> implements ResumptionTaskCountService {
+
+}

+ 28 - 0
soc-modules/soc-modules-core/src/main/java/com/xunmei/core/board/vo/web/ResumptionTaskStatisticVo.java

@@ -0,0 +1,28 @@
+package com.xunmei.core.board.vo.web;
+
+import lombok.Data;
+
+/**
+ * @ClassName ResumptionTaskStatiscVo
+ * @Description: 类描述
+ * @Author: LuZhu
+ * @CreateDate: 2025/9/22 14:57
+ */
+@Data
+public class ResumptionTaskStatisticVo {
+    /**
+     *
+     */
+    private Long orgId;
+
+    private String orgPath;
+    /**
+     * 任务总数
+     */
+    private Integer taskTotal;
+
+    /**
+     * 完成数量
+     */
+    private Integer completedCount;
+}