From 3777ec066316f3c1d3ca36e2cae5b1e05bac4f6e Mon Sep 17 00:00:00 2001
From: zxl <763096477@qq.com>
Date: 星期五, 05 十二月 2025 17:11:39 +0800
Subject: [PATCH] 首页

---
 business/src/main/java/com/ycl/service/impl/IndexHomeServiceImpl.java         |  635 ++++++++++++++++++++++++++++++++++++++++++--
 start/src/main/resources/application-dev.yml                                  |   14 
 business/src/main/java/com/ycl/domain/form/ProjectProgressStatisticsForm.java |    2 
 business/src/main/resources/mapper/ProjectInfoMapper.xml                      |    6 
 business/src/main/java/com/ycl/mapper/ProjectInfoMapper.java                  |    5 
 flowable/src/main/resources/mapper/ProcessCodingMapper.xml                    |    6 
 business/src/main/java/com/ycl/domain/vo/CheckPointVO.java                    |   25 +
 business/src/main/java/com/ycl/service/IndexHomeService.java                  |    3 
 business/src/main/java/com/ycl/service/impl/ProjectProcessServiceImpl.java    |   14 
 business/src/main/java/com/ycl/service/impl/FlowTaskServiceImpl.java          |   24 +
 business/src/main/java/com/ycl/service/ProjectProcessService.java             |    3 
 business/src/main/java/com/ycl/domain/vo/TaskInfoVo.java                      |   26 +
 business/src/main/java/com/ycl/task/FlowableTask.java                         |   21 +
 business/src/main/java/com/ycl/controller/IndexHomeController.java            |   13 
 flowable/src/main/java/com/ycl/domain/entity/ProcessCoding.java               |    3 
 15 files changed, 736 insertions(+), 64 deletions(-)

diff --git a/business/src/main/java/com/ycl/controller/IndexHomeController.java b/business/src/main/java/com/ycl/controller/IndexHomeController.java
index 92ec413..ccb1e4b 100644
--- a/business/src/main/java/com/ycl/controller/IndexHomeController.java
+++ b/business/src/main/java/com/ycl/controller/IndexHomeController.java
@@ -5,9 +5,7 @@
 import com.ycl.domain.form.ProjectProgressStatisticsForm;
 import com.ycl.service.IndexHomeService;
 import lombok.RequiredArgsConstructor;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 /**
  * nongtou-project-java
@@ -44,7 +42,8 @@
      * 椤圭洰杩涘害缁熻
      * @return
      */
-    Result projectTaskStatus(ProjectProgressStatisticsForm form){
+    @PostMapping("/taskStatus")
+    Result projectTaskStatus(@RequestBody ProjectProgressStatisticsForm form){
         return indexHomeService.projectTaskStatus(form);
     }
 
@@ -61,7 +60,13 @@
      * 椤圭洰鎺ㄨ繘鍗$偣
      * @return
      */
+    @GetMapping("/getProjectAdvanceCheckPoint")
     Result projectAdvanceCheckPoint(){
         return indexHomeService.projectAdvanceCheckPoint();
     }
+
+    @GetMapping("/getSelect")
+    Result getProjectSelectList(){
+        return indexHomeService.getProjectSelectList();
+    }
 }
diff --git a/business/src/main/java/com/ycl/domain/form/ProjectProgressStatisticsForm.java b/business/src/main/java/com/ycl/domain/form/ProjectProgressStatisticsForm.java
index 042ae06..a313676 100644
--- a/business/src/main/java/com/ycl/domain/form/ProjectProgressStatisticsForm.java
+++ b/business/src/main/java/com/ycl/domain/form/ProjectProgressStatisticsForm.java
@@ -21,7 +21,7 @@
 @NoArgsConstructor
 public class ProjectProgressStatisticsForm extends AbsForm {
 
-    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM")
     private Date startTime;
 
 
diff --git a/business/src/main/java/com/ycl/domain/vo/CheckPointVO.java b/business/src/main/java/com/ycl/domain/vo/CheckPointVO.java
new file mode 100644
index 0000000..1eea931
--- /dev/null
+++ b/business/src/main/java/com/ycl/domain/vo/CheckPointVO.java
@@ -0,0 +1,25 @@
+package com.ycl.domain.vo;
+
+
+import com.ycl.system.domain.base.AbsVo;
+import lombok.Data;
+import org.flowable.bpmn.model.Task;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * nongtou-project-java
+ *
+ * @author : zxl
+ * @date : 2025-12-02 15:42
+ **/
+@Data
+public class CheckPointVO extends AbsVo {
+    private String projectName;//椤圭洰鍚�
+    private String processDefinitionId;
+    private String processInstanceId;
+    private String processName;
+    private String deployId;//娴佺▼閮ㄧ讲id
+
+}
diff --git a/business/src/main/java/com/ycl/domain/vo/TaskInfoVo.java b/business/src/main/java/com/ycl/domain/vo/TaskInfoVo.java
new file mode 100644
index 0000000..87b5520
--- /dev/null
+++ b/business/src/main/java/com/ycl/domain/vo/TaskInfoVo.java
@@ -0,0 +1,26 @@
+package com.ycl.domain.vo;
+
+
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * nongtou-project-java
+ *
+ * @author : zxl
+ * @date : 2025-12-03 14:35
+ **/
+@Data
+public class TaskInfoVo  {
+    private String id;
+    private String taskName;//浠诲姟鍚�
+    private String taskType;
+    private Date startTime;//寮�濮嬫椂闂�
+    private Date endTime;//鎴嚦鏃堕棿
+    private String totalOverTime;//瓒呮椂鏃堕棿
+    private Long overTimeCount;//瓒呮椂娆℃暟
+    private CheckPointVO checkPointInfo;
+
+    private CustomerTaskVO customerTaskInfo;
+}
diff --git a/business/src/main/java/com/ycl/mapper/ProjectInfoMapper.java b/business/src/main/java/com/ycl/mapper/ProjectInfoMapper.java
index 4d653b8..cabf22c 100644
--- a/business/src/main/java/com/ycl/mapper/ProjectInfoMapper.java
+++ b/business/src/main/java/com/ycl/mapper/ProjectInfoMapper.java
@@ -6,9 +6,10 @@
 import com.ycl.common.annotation.DataScope;
 import com.ycl.common.core.domain.BaseEntity;
 import com.ycl.domain.entity.ProjectInfo;
+import com.ycl.domain.entity.ProjectInvestmentFunding;
 import com.ycl.domain.excel.ProjectExcelTemplate;
 import com.ycl.domain.query.ProjectInfoQuery;
-import com.ycl.domain.vo.ProjectInfoVO;
+import com.ycl.domain.vo.ProjectInvestmentFundingVO;
 import com.ycl.domain.vo.ProjectVO;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
@@ -53,6 +54,6 @@
      * @return
      */
     @DataScope(deptAlias = "d")
-    List<ProjectInfoVO> getProjectInfoAndFunding(BaseEntity params);
+    List<ProjectInvestmentFundingVO> getProjectInfoAndFunding(BaseEntity params);
 
 }
diff --git a/business/src/main/java/com/ycl/service/IndexHomeService.java b/business/src/main/java/com/ycl/service/IndexHomeService.java
index e2d7da3..41d9aba 100644
--- a/business/src/main/java/com/ycl/service/IndexHomeService.java
+++ b/business/src/main/java/com/ycl/service/IndexHomeService.java
@@ -1,7 +1,6 @@
 package com.ycl.service;
 
 
-import com.ycl.common.annotation.DataScope;
 import com.ycl.common.base.Result;
 import com.ycl.domain.form.ProjectProgressStatisticsForm;
 
@@ -40,4 +39,6 @@
      * @return
      */
     Result projectAdvanceCheckPoint();
+
+    Result getProjectSelectList();
 }
diff --git a/business/src/main/java/com/ycl/service/ProjectProcessService.java b/business/src/main/java/com/ycl/service/ProjectProcessService.java
index 9803243..62520f7 100644
--- a/business/src/main/java/com/ycl/service/ProjectProcessService.java
+++ b/business/src/main/java/com/ycl/service/ProjectProcessService.java
@@ -11,6 +11,7 @@
 import com.ycl.domain.vo.CustomerTaskVO;
 import com.ycl.domain.vo.IndexMsgCountVO;
 import com.ycl.system.domain.base.AbsQuery;
+import org.flowable.task.api.history.HistoricTaskInstance;
 
 import java.util.List;
 
@@ -149,6 +150,8 @@
 
     Result getProcessMsg(AbsQuery query);
 
+    List<HistoricTaskInstance> distinctHisTask(List<HistoricTaskInstance> hisTaskList);
+
     /**
      * 鑾峰彇棣栭〉瀹圭己浠诲姟
      *
diff --git a/business/src/main/java/com/ycl/service/impl/FlowTaskServiceImpl.java b/business/src/main/java/com/ycl/service/impl/FlowTaskServiceImpl.java
index c39400e..9514a39 100644
--- a/business/src/main/java/com/ycl/service/impl/FlowTaskServiceImpl.java
+++ b/business/src/main/java/com/ycl/service/impl/FlowTaskServiceImpl.java
@@ -175,6 +175,7 @@
             }
         }
         taskService.addComment(taskId, task.getProcessInstanceId(), FlowComment.SUBMIT.getType(), "瀹屾垚鎻愪氦");
+        //鍒ゆ柇鏄惁鏄娲句换鍔�
         if (DelegationState.PENDING.equals(task.getDelegationState())) {
             taskService.resolveTask(taskId, newV);
         } else {
@@ -1513,7 +1514,7 @@
 
     /**
      * 娴佺▼鑺傜偣琛ㄥ崟
-     *
+     * 鐐瑰嚮鍔炵悊杩涘叆
      * @param taskId 娴佺▼浠诲姟缂栧彿
      * @return
      */
@@ -1627,7 +1628,9 @@
 
     @Override
     public AjaxResult detail(String processInsId, String taskId) {
+        //鏌ヨ杩愯鏃舵祦绋嬪疄渚嬶紙鍚祦绋嬪彉閲忥級
         ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().includeProcessVariables().processInstanceId(processInsId).singleResult();
+        log.info("鎵撳嵃杩愯鏃�:{}",processInstance);
         // 娴佺▼鍙橀噺
         Map<String, Object> parameters = new HashMap<>();
         if (Objects.isNull(processInstance)) {
@@ -1637,7 +1640,7 @@
             if (Objects.isNull(historicProcessInstance)) {
                 throw new RuntimeException("娴佺▼涓嶅瓨鍦�");
             }
-
+            //娴佺▼鏈粨鏉� 鏌ヨ娴佺▼宸插畬鎴愮殑缁撶偣浠诲姟
             List<HistoricTaskInstance> hisTasks = historyService.createHistoricTaskInstanceQuery()
                     .taskId(taskId)
                     .finished()
@@ -1648,7 +1651,9 @@
             if (CollectionUtils.isNotEmpty(hisTasks) && Objects.isNull(hisTasks.get(0))) {
                 throw new RuntimeException("璇ヤ换鍔′笉瀛樺湪");
             }
+            //鑾峰緱鏈�鏂扮殑浠诲姟鑺傜偣
             HistoricTaskInstance hisTask = hisTasks.get(0);
+            //鑾峰緱鍙傛暟
             parameters = historicProcessInstance.getProcessVariables();
             List<FormDetailVO> beforeNodes = this.getBeforeNodeForm(parameters,
                     hisTask.getFormKey(),
@@ -1657,12 +1662,14 @@
                     hisTask.getTaskDefinitionKey(),
                     Boolean.TRUE, Boolean.TRUE);
             List<FormDetailVO> dataList = new ArrayList<>(2);
+            // 鎸夋墽琛屾祦ID鍒嗙粍鍓嶇疆鑺傜偣
             Map<String, List<FormDetailVO>> map = new HashMap<>(2);
             beforeNodes.stream().forEach(node -> {
                 if (node.getCurrent()) {
                     node.setTaskId(taskId);
                     dataList.add(node);
                 } else {
+                    //鍓嶇疆鑺傜偣锛氭煡璇㈠搴旂殑鏈�鏂板巻鍙蹭换鍔�
                     List<HistoricTaskInstance> beforeTasks = historyService.createHistoricTaskInstanceQuery()
                             .processInstanceId(hisTask.getProcessInstanceId())
                             .finished()
@@ -1670,6 +1677,7 @@
                             .orderByTaskCreateTime()
                             .desc()
                             .list();
+
                     if (CollectionUtils.isNotEmpty(beforeTasks) && Objects.nonNull(beforeTasks.get(0))) {
                         node.setTaskId(beforeTasks.get(0).getId());
                         List<FormDetailVO> l = map.get(beforeTasks.get(0));
@@ -1689,7 +1697,9 @@
             }
             List<DoFormDetailVO> vos = dataList.stream().map(node -> {
                 if (node.getCurrent()) {
+                    // 璋冪敤鏃ュ織鏈嶅姟锛屾煡璇㈣浠诲姟鏄惁澶勪簬鎸傝捣鐘舵�侊紙浼犲叆浠诲姟ID鍜屾祦绋嬪疄渚婭D锛�
                     if (processLogService.taskIsHangup(taskId, hisTask.getProcessInstanceId())) {
+                        //鑻ユ寕璧凤紝缁欒妭鐐硅缃�滄寕璧封�濈姸鎬侊紙鍓嶇浼氬睍绀烘寕璧锋爣璇嗭級
                         node.setTaskStatus(TaskStatusEnum.HANGUP);
                     }
                 }
@@ -1812,16 +1822,19 @@
 
         // 杩欓噷鍙渶瑕佹煡鑷韩浠ュ強涓婁竴涓妭鐐�(濡傛灉骞惰鐨勬湁澶氫釜)鐨勮〃鍗曟暟鎹�
         List<FormDetailVO> beforeNodes = taskCommonService.getBeforeNodeDefInfo(processDefId, processDefKey, sysFormService, Boolean.TRUE);
+        // 闈炲綋鍓嶈妭鐐� 鎴� 闇�瑕佸綋鍓嶈妭鐐规暟鎹�
         List<String> beforeNodeDefIds = beforeNodes.stream().filter(item -> !item.getCurrent() || currentNeedData).map(FormDetailVO::getBeforeNodeDefId).collect(Collectors.toList());
 
         // 澶勭悊姣忎釜琛ㄥ崟鐨勬暟鎹�
         for (FormDetailVO formDetailVO : beforeNodes) {
+            // 璺宠繃鈥滃綋鍓嶈妭鐐逛笖涓嶉渶瑕佸叾鏁版嵁鈥濈殑鍦烘櫙 骞朵笖 currentNeedData涓嶉渶瑕佸綋鍓嶈妭鐐规暟鎹殑鎯呭喌
             if (formDetailVO.getCurrent() && !currentNeedData) {
                 // 褰撳墠鑺傜偣鐨勮〃鍗曚篃瑕佸鐞唅p闂
                 continue;  // 璺宠繃褰撳墠鑺傜偣锛屽洜涓哄綋鍓嶈妭鐐瑰湪鑾峰彇鍓嶇疆鑺傜偣鏃跺凡缁忚缃繃浜�(浣嗚〃鍗曟暟鎹病鏈夌粰)
             }
 
             Map<String, Object> newP = new HashMap<>();
+            // 瀛樺偍褰撳墠鑺傜偣鐨勮〃鍗曟暟鎹�
             if (CollectionUtils.isNotEmpty(beforeNodeDefIds)) {
                 for (String key : parameters.keySet()) {
                     // 杩囨护鎷垮埌鐩爣琛ㄥ崟鏁版嵁锛屽皢鐩爣琛ㄥ崟鏁版嵁鏀惧埌鏂癿ap涓�
@@ -1834,7 +1847,7 @@
                     }
                 }
             }
-
+            //鑾峰緱鍓嶇疆鑺傜偣瀹氫箟id锛屽嵆浠诲姟key
             Object form = newP.get(formDetailVO.getBeforeNodeDefId() + "&" + ProcessConstants.TASK_FORM_KEY);
             if (Objects.nonNull(form)) {
                 JSONObject formJson = JSONObject.parseObject(JSON.toJSONString(form));
@@ -1853,11 +1866,12 @@
                             options.put("uploadURL", String.format("http://%s:10076/common/upload", this.targetIp));
                         }
                     }
-
+                    // 鏇存柊琛ㄥ崟缁撴瀯锛堝凡澶勭悊绂佺敤鍜屼笂浼犲湴鍧�锛�
                     formJson.put(ProcessConstants.WIDGET_LIST, oldFields);
                     newP.put(ProcessConstants.TASK_FORM_KEY, formJson);
+                    // 鍒犻櫎鍘熷鐨勨�滆妭鐐笽D&TASK_FORM_KEY鈥濋敭锛堥伩鍏嶅啑浣欙級
                     newP.remove(formDetailVO.getBeforeNodeDefId() + "&" + ProcessConstants.TASK_FORM_KEY);
-                    // 澶勭悊宸茬粡涓婁紶鐨勬枃浠剁殑ip鍦板潃
+                    // 宸蹭笂浼犳枃浠剁殑璁块棶IP鍦板潃锛堝墠绔瑙�/涓嬭浇鏃舵寚鍚戞纭湴鍧�锛�
                     for (String s : newP.keySet()) {
                         if (ProcessConstants.TASK_FORM_KEY.equals(s)) {
                             continue;
diff --git a/business/src/main/java/com/ycl/service/impl/IndexHomeServiceImpl.java b/business/src/main/java/com/ycl/service/impl/IndexHomeServiceImpl.java
index 938bb41..d348364 100644
--- a/business/src/main/java/com/ycl/service/impl/IndexHomeServiceImpl.java
+++ b/business/src/main/java/com/ycl/service/impl/IndexHomeServiceImpl.java
@@ -7,24 +7,48 @@
 import com.ycl.common.base.Result;
 import com.ycl.common.constant.ProcessOverTimeConstants;
 import com.ycl.common.core.domain.BaseEntity;
-import com.ycl.common.enums.business.CodingRulerCodeTypeEnum;
-import com.ycl.common.enums.business.CodingRulerStatusEnum;
-import com.ycl.common.enums.business.ProjectCategoryEnum;
-import com.ycl.common.enums.business.ProjectStatusEnum;
+import com.ycl.common.core.domain.entity.SysDept;
+import com.ycl.common.core.domain.entity.SysRole;
+import com.ycl.common.core.domain.entity.SysUser;
+import com.ycl.common.enums.business.*;
 import com.ycl.common.utils.SecurityUtils;
+import com.ycl.domain.entity.ProcessCoding;
+import com.ycl.domain.entity.ProcessLog;
 import com.ycl.domain.entity.ProjectInfo;
+import com.ycl.domain.entity.ProjectProcess;
 import com.ycl.domain.form.ProjectProgressStatisticsForm;
-import com.ycl.domain.vo.ProjectInfoVO;
-import com.ycl.domain.vo.ProjectVO;
+import com.ycl.domain.vo.*;
+import com.ycl.factory.FlowServiceFactory;
+import com.ycl.mapper.ProcessCodingMapper;
+import com.ycl.mapper.ProcessLogMapper;
 import com.ycl.mapper.ProjectInfoMapper;
+import com.ycl.mapper.ProjectProcessMapper;
 import com.ycl.service.IndexHomeService;
-import com.ycl.service.ProjectInfoService;
 import com.ycl.service.ProjectProcessService;
 import com.ycl.system.mapper.SysDeptMapper;
+import com.ycl.system.service.ISysDeptService;
+import com.ycl.system.service.ISysRoleService;
+import com.ycl.system.service.ISysUserService;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.flowable.bpmn.model.BpmnModel;
+import org.flowable.bpmn.model.Process;
+import org.flowable.bpmn.model.UserTask;
+import org.flowable.engine.history.HistoricProcessInstance;
+import org.flowable.engine.runtime.ProcessInstance;
+import org.flowable.identitylink.api.IdentityLink;
+import org.flowable.identitylink.api.IdentityLinkInfo;
+import org.flowable.identitylink.api.IdentityLinkType;
+import org.flowable.task.api.Task;
+import org.flowable.task.api.history.HistoricTaskInstance;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
+import java.text.DecimalFormat;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.time.temporal.TemporalAdjusters;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -37,33 +61,27 @@
  **/
 @Service
 @RequiredArgsConstructor
-public class IndexHomeServiceImpl implements IndexHomeService {
+@Slf4j
+public class IndexHomeServiceImpl extends FlowServiceFactory implements IndexHomeService {
 
     private final SysDeptMapper sysDeptMapper;
     private final ProjectInfoMapper projectInfoMapper;
+
+    private final ProjectProcessService projectProcessService;
+
+    private final ProcessLogMapper processLogMapper;
+
+    private final ProcessCodingMapper processCodingMapper;
+
+    private final ISysUserService sysUserService;
+
+    private final ISysDeptService sysDeptService;
+
+    private final ISysRoleService sysRoleService;
     @Override
     public Result projectCodingStatusCount() {
         //鏉冮檺鎺у埗
-        Long userId = SecurityUtils.getUserId();
-        List<ProjectInfo> list;
-        if (SecurityUtils.isAdmin(userId)){
-            //鏌ヨ鍏ㄩ儴
-            list = new LambdaQueryChainWrapper<>(projectInfoMapper)
-                    .eq(ProjectInfo::getDeleted, Boolean.FALSE)
-                    .eq(ProjectInfo::getUsedStatus, 2) //瀹℃牳閫氳繃
-                    .list();
-        }else{
-            String ancestors = sysDeptMapper.selectAncestors(userId);
-            String[] ancestorArr = ancestors.split(",");
-            List<String> ancestorList = Arrays.stream(ancestorArr).collect(Collectors.toList());
-            ancestorList.add(SecurityUtils.getDeptId() + "");
-            //鑾峰緱鏈崟浣嶄互鍙婂叾瀛愬崟浣峝eptId;
-            list = new LambdaQueryChainWrapper<>(projectInfoMapper)
-                    .eq(ProjectInfo::getDeleted, Boolean.FALSE)
-                    .eq(ProjectInfo::getUsedStatus, 2) //瀹℃牳閫氳繃
-                    .in(ProjectInfo::getProjectOwnerUnit, ancestorList)
-                    .list();
-        }
+        List<ProjectInfo> loginUserOwnProjectInfo = getLoginUserOwnProjectInfo();
 
 
 
@@ -73,13 +91,13 @@
         map.put(ProcessOverTimeConstants.YELLOW,0);
         map.put(ProcessOverTimeConstants.RED,0);
         map.put("total",0);
-        if (CollectionUtils.isEmpty(list)) {
+        if (CollectionUtils.isEmpty(loginUserOwnProjectInfo)) {
 
             //杩斿洖榛樿鍊�
             return Result.ok().data(map);
         }
 
-        Map<String, List<ProjectInfo>> collect = list.stream()
+        Map<String, List<ProjectInfo>> collect = loginUserOwnProjectInfo.stream()
                 .filter(project -> project.getCoding() != null) // 杩囨护coding涓簄ull鐨勬儏鍐�
                 .collect(Collectors.groupingBy(ProjectInfo::getCoding));
 
@@ -93,7 +111,7 @@
             map.put(ProcessOverTimeConstants.RED, collect.get(ProcessOverTimeConstants.RED).size());
         }
 
-        map.put("total", list.size());
+        map.put("total", loginUserOwnProjectInfo.size());
         return Result.ok().data(map);
     }
 
@@ -115,29 +133,566 @@
                 finish+=1;
             }
         }
-        Map<String,Integer> map = new HashMap<>();
-        map.put(ProjectCategoryEnum.RESERVE.getCode(),reserve);
-        map.put(ProjectCategoryEnum.PREVIOUS.getCode(),previous);
-        map.put(ProjectCategoryEnum.IMPLEMENT.getCode(),implement);
-        map.put(ProjectCategoryEnum.FINISH.getCode(),finish);
+
+
+        Map<String,Object> map = new HashMap<>();
+        Integer[] yData = new Integer[]{
+                projectVOS.size(),
+                reserve,
+                previous,
+                implement,
+                finish
+        };
+        String[] xData = new String[]{
+          "鍦ㄥ簱", "鍌ㄥ","鍓嶆湡","瀹炴柦","绔e伐"
+        };
+        map.put("xData",xData);
+        map.put("yData",yData);
         return Result.ok().data(map);
+    }
+
+    public List<ProjectInfo> getLoginUserOwnProjectInfo(){
+        //鏉冮檺鎺у埗
+        Long userId = SecurityUtils.getUserId();
+        List<ProjectInfo> list;
+        if (SecurityUtils.isAdmin(userId)){
+            //鏌ヨ鍏ㄩ儴
+            list = new LambdaQueryChainWrapper<>(projectInfoMapper)
+                    .eq(ProjectInfo::getDeleted, Boolean.FALSE)
+                    .eq(ProjectInfo::getUsedStatus, 2)//瀹℃牳閫氳繃
+                    .orderBy(true, true, ProjectInfo::getId)
+                    .list();
+        }else{
+            String ancestors = sysDeptMapper.selectAncestors(userId);
+            String[] ancestorArr = ancestors.split(",");
+            List<String> ancestorList = Arrays.stream(ancestorArr).collect(Collectors.toList());
+            ancestorList.add(SecurityUtils.getDeptId() + "");
+            //鑾峰緱鏈崟浣嶄互鍙婂叾瀛愬崟浣峝eptId;
+            list = new LambdaQueryChainWrapper<>(projectInfoMapper)
+                    .eq(ProjectInfo::getDeleted, Boolean.FALSE)
+                    .eq(ProjectInfo::getUsedStatus, 2) //瀹℃牳閫氳繃
+                    .in(ProjectInfo::getProjectOwnerUnit, ancestorList)
+                    .orderBy(true, true, ProjectInfo::getId)
+                    .list();
+        }
+        return list;
     }
 
     @Override
     public Result projectTaskStatus(ProjectProgressStatisticsForm form) {
-        return null;
+        //鑾峰緱鏄」鐩�
+        List<ProjectInfo> loginUserOwnProjectInfo = getLoginUserOwnProjectInfo();
+
+
+        if (CollectionUtils.isEmpty(loginUserOwnProjectInfo)) {
+            return Result.ok().data(loginUserOwnProjectInfo);
+        }
+        Map<String, String> projectMap = loginUserOwnProjectInfo.stream()
+                .collect(Collectors.toMap(
+                        projectInfo -> String.valueOf(projectInfo.getId()),          // key: 椤圭洰ID
+                        ProjectInfo::getProjectName,          // value: 椤圭洰瀵硅薄鏈韩
+                        (existing, replacement) -> existing  // 澶勭悊閲嶅ID鐨勫啿绐佺瓥鐣ワ紙淇濈暀鍘熸湁鍊硷級
+                ));
+
+
+
+        //鑾峰緱椤圭洰ids
+        List<Long> ids = loginUserOwnProjectInfo.stream().map(ProjectInfo::getId).collect(Collectors.toList());
+
+
+        //鏇村叿椤圭洰ids鑾峰緱鎵�鏈夊搴旀祦绋嬩俊鎭� ProjectProcess  娴佺▼瀹氫箟ID processDefId;娴佺▼瀹炰緥id processInsId;
+        List<ProjectProcess> projectProcessList = new LambdaQueryChainWrapper<>(projectProcessService.getBaseMapper())
+                .eq(ProjectProcess::getDeleted, Boolean.FALSE)
+                .in(ProjectProcess::getProjectId, ids).list();
+
+        Date statisticsTime = form.getStartTime();
+        if (statisticsTime == null) {
+            statisticsTime = new Date(); // 濡傛灉鏈紶鍏ユ椂闂达紝榛樿浣跨敤褰撳墠鏃堕棿
+        }
+        LocalDate statisticsLocalDate = statisticsTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+        LocalDate firstDayOfMonth = statisticsLocalDate.with(TemporalAdjusters.firstDayOfMonth());
+        LocalDate lastDayOfMonth = statisticsLocalDate.with(TemporalAdjusters.lastDayOfMonth());
+
+        Date monthStart = Date.from(firstDayOfMonth.atStartOfDay(ZoneId.systemDefault()).toInstant());
+        Date monthEnd = Date.from(lastDayOfMonth.atTime(23, 59, 59).atZone(ZoneId.systemDefault()).toInstant());
+
+        // 瀛樺偍姣忎釜娴佺▼瀹炰緥鐨勭粺璁$粨鏋�
+        List<Map<String, Object>> processStatisticsList = new ArrayList<>();
+
+        // 鑾峰緱娴佺▼鏃ュ織琛ㄤ腑 浠诲姟淇℃伅 鎸夋祦绋嬪疄鍒梚d鍒嗙粍
+        Map<String, List<ProcessLog>> groupMap = new LambdaQueryChainWrapper<>(processLogMapper)
+                .eq(ProcessLog::getDeleted, Boolean.FALSE)
+                .in(ProcessLog::getProjectId, ids).list()
+                .stream().collect(Collectors.groupingBy(ProcessLog::getProcessInsId));
+
+
+        for (ProjectProcess projectProcess : projectProcessList) {
+
+            String processInstanceId = projectProcess.getProcessInsId();
+            if (processInstanceId == null) {
+                continue;
+            }
+
+            // 鍗曚釜娴佺▼鐨勭粺璁$粨鏋�
+            Map<String, Object> processResult = new HashMap<>();
+            processResult.put("id",projectProcess.getProjectId());
+            processResult.put("projectName", projectMap.get(projectProcess.getProjectId()));
+
+            int completedCount = 0;      // 宸插畬鎴愪换鍔℃暟
+            int inProgressCount = 0;     // 杩涜涓换鍔℃暟
+            int notStartedCount = 0;     // 鏈紑濮嬩换鍔℃暟
+
+            try {
+                // 1. 鑾峰彇璇ユ祦绋嬪疄渚嬬殑鎵�鏈夊凡瀹屾垚浠诲姟
+                List<HistoricTaskInstance> completedTasks = historyService.createHistoricTaskInstanceQuery()
+                        .processInstanceId(processInstanceId)
+                        .finished()
+                        .list();
+                // 鍘婚噸鍘嗗彶淇℃伅 鎺掗櫎鐩稿悓鐨勪换鍔ey淇濈暀鏈�鏂扮殑浠诲姟
+                completedTasks = projectProcessService.distinctHisTask(completedTasks);
+                // 闇�瑕佹帓闄ゅ凡瀹屾垚浠诲姟涓椹冲洖鐨勪换鍔℃暟
+                List<ProcessLog> taskLogs = groupMap.get(projectProcess.getProcessInsId());
+                if ("144".equals(projectProcess.getProjectId())) {
+                    for (ProcessLog processLog : taskLogs) {
+                        System.out.println("鎵撳嵃淇℃伅");
+                        System.out.println(processLog.toString());
+                    }
+                }
+                if (!CollectionUtils.isEmpty(taskLogs)) {
+                    //鎺掗櫎鎺夋墍鏈夎椹冲洖鐨勪换鍔�
+                    // 鑾峰彇鎵�鏈夎椹冲洖浠诲姟鐨処D鍒楄〃
+                    List<String> rejectedTaskIds = taskLogs.stream()
+                            .filter(log -> {
+                                // 鍒ゆ柇鏄惁涓洪┏鍥炵被鍨嬬殑鏃ュ織锛堟牴鎹綘鐨勬灇涓惧�艰皟鏁达級
+                                return ProcessLogEventTypeEnum.REJECT.equals(log.getEventType());
+                            })
+                            .map(ProcessLog::getTaskId) // 鍋囪鏃ュ織涓湁taskId瀛楁鍏宠仈浠诲姟
+                            .filter(Objects::nonNull)   // 杩囨护鎺塶ull鐨則askId
+                            .collect(Collectors.toList());
+
+                    // 鎺掗櫎琚┏鍥炵殑浠诲姟锛岀敓鎴愭柊鐨勫凡瀹屾垚浠诲姟闆嗗悎
+
+                    // 灏嗚繃婊ゅ悗鐨勯泦鍚堣祴鍊肩粰鍘熷彉閲�
+                    completedTasks = completedTasks.stream()
+                            .filter(task -> !rejectedTaskIds.contains(task.getId())) //淇濈暀涓嶅寘鍚┏鍥炵殑taskId
+                            .collect(Collectors.toList());
+                }
+
+
+                // 鏈湀鏈�鍚庝竴澶╁畬鎴愮殑 灞炰簬宸插畬鎴� after 涔嬪悗 before 涔嬪墠
+                for (HistoricTaskInstance task : completedTasks) {
+                    Date completionTime = task.getEndTime();
+                    if (completionTime != null &&
+                            completionTime.before(monthEnd)) {
+                        completedCount++;
+                    }
+                }
+                // 鑾峰緱涓婁竴姝ユ湭瑕嗙洊鍒版煡璇㈡潯浠剁殑鍏冪礌 瀹屾垚鏃堕棿鏄湪鏈湀涔嬪悗
+                List<HistoricTaskInstance> excessCompletedTasks  = completedTasks.stream().filter(
+                        task -> { Date endTime = task.getEndTime();
+                           return endTime != null && endTime.after(monthEnd);
+                }).collect(Collectors.toList());
+
+                // 寰幆瀹屾垚鏃堕棿鏄湪鏈湀涔嬪悗鐨�
+                for (HistoricTaskInstance task : excessCompletedTasks) {
+                    Date createTime = task.getCreateTime();
+                    Date endTime = task.getEndTime();
+
+                    // 鏈湀鍒涘缓锛屽畬鎴愬湪鏈湀涔嬪悗 灞炰簬杩涜涓�
+                    if (createTime != null && endTime != null) {
+                        if (createTime.before(monthEnd) && createTime.after(monthStart) && endTime.after(monthEnd)) {
+                            inProgressCount++;
+                        }
+                    }
+
+
+                }
+                // 2. 鑾峰彇璇ユ祦绋嬪疄渚嬬殑鎵�鏈夎繘琛屼腑浠诲姟
+                List<Task> activeTasks = taskService.createTaskQuery()
+                        .processInstanceId(processInstanceId)
+                        .active()
+                        .list();
+                for (Task task : activeTasks) {
+                    Date createTime = task.getCreateTime();
+                    // 杩涜涓殑浠诲姟 鍒ゆ柇鍒涘缓鏃堕棿鏄惁鍦ㄤ笅涓湀涔嬪墠 濡傛灉鏄湰鏈堝垯鍔�1
+                    if (createTime != null && createTime.before(monthEnd)) {
+                        inProgressCount++;
+                    }
+
+                }
+
+
+
+
+                // 5. 缁熻鏈紑濮嬩换鍔★紙鑾峰彇娴佺▼瀹氫箟鐨勬�讳换鍔℃暟 - 宸茬粺璁$殑浠诲姟鏁帮級
+                ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
+                        .processInstanceId(processInstanceId)
+                        .singleResult();
+
+                if (processInstance != null) {
+                    BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
+                    Process mainProcess = bpmnModel.getMainProcess();
+                    List<UserTask> userTasks = mainProcess.findFlowElementsOfType(UserTask.class);
+                    int totalUserTaskCount = userTasks.size();
+
+                    // 鏈紑濮嬩换鍔℃暟 = 鎬讳换鍔℃暟 - 宸插畬鎴� - 杩涜涓�
+                    notStartedCount = totalUserTaskCount - completedCount - inProgressCount;
+
+                    // 纭繚鏈紑濮嬩换鍔℃暟涓嶄负璐熸暟
+                    if (notStartedCount < 0) {
+                        notStartedCount = 0;
+                    }
+                }
+            } catch (Exception e) {
+                // 寮傚父澶勭悊
+                notStartedCount = 0;
+            }
+
+            // 璁剧疆褰撳墠娴佺▼鐨勭粺璁$粨鏋�
+            int totalTasks = completedCount + inProgressCount + notStartedCount;
+
+            double completedPercent = totalTasks == 0 ? 0 : (completedCount * 100.0 / totalTasks);
+            double inProgressPercent = totalTasks == 0 ? 0 : (inProgressCount * 100.0 / totalTasks);
+            double notStartedPercent = totalTasks == 0 ? 0 : (notStartedCount * 100.0 / totalTasks);
+            //鍥涜垗浜斿叆
+            completedPercent = Math.round(completedPercent * 10) / 10.0;
+            inProgressPercent = Math.round(inProgressPercent * 10) / 10.0;
+            notStartedPercent = Math.round(notStartedPercent * 10) / 10.0;
+            //淇濈暀涓�浣�
+            DecimalFormat df = new DecimalFormat("#.#");
+
+            // 鏍煎紡鍖栫粨鏋滐紙鍙�夛細淇濈暀涓哄瓧绗︿覆鎴栬浆鎹负Double锛�
+            String completedFormatted = df.format(completedPercent);
+            String inProgressFormatted = df.format(inProgressPercent);
+            String notStartedFormatted = df.format(notStartedPercent);
+
+            processResult.put("completed", completedFormatted);
+            processResult.put("co", completedCount);
+            processResult.put("co2", inProgressCount);
+            processResult.put("co3", notStartedCount);
+            processResult.put("inProgress", inProgressFormatted);
+            processResult.put("notStarted", notStartedFormatted);
+            processResult.put("totalTasks",totalTasks) ;
+
+            // 娣诲姞鍒扮粨鏋滃垪琛�
+            processStatisticsList.add(processResult);
+        }
+
+        return Result.ok().data(processStatisticsList);
     }
 
     @Override
-    @DataScope(deptAlias = "d")
     public Result projectFundingStatus( ) {
+        List<ProjectInvestmentFundingVO> projectInfoAndFunding = projectInfoMapper.getProjectInfoAndFunding(new BaseEntity());
+        //鎺掗櫎绌烘暟鎹�
+        projectInfoAndFunding = projectInfoAndFunding.stream().filter(Objects::nonNull).collect(Collectors.toList());
 
-        List<ProjectInfoVO> projectInfoAndFunding = projectInfoMapper.getProjectInfoAndFunding(new BaseEntity());
         return Result.ok().data(projectInfoAndFunding);
     }
 
     @Override
     public Result projectAdvanceCheckPoint() {
-        return null;
+        List<ProjectInfo> loginUserOwnProjectInfo = getLoginUserOwnProjectInfo();
+        if (CollectionUtils.isEmpty(loginUserOwnProjectInfo)) {
+            return Result.ok().data(loginUserOwnProjectInfo);
+        }
+        //鑾峰緱椤圭洰ids
+        List<Long> ids = loginUserOwnProjectInfo.stream().map(ProjectInfo::getId).collect(Collectors.toList());
+        List<ProjectProcess> projectProcessList = new LambdaQueryChainWrapper<>(projectProcessService.getBaseMapper())
+                .eq(ProjectProcess::getDeleted, Boolean.FALSE)
+                .in(ProjectProcess::getProjectId, ids).list();
+
+        //娴佺▼瀹炰緥id闆嗗悎
+        List<String> targetProcessInsIds = projectProcessList.stream()
+                .map(ProjectProcess::getProcessInsId)
+                .distinct()
+                .filter(defId -> defId != null && !defId.trim().isEmpty())
+                .collect(Collectors.toList());
+        //缁勮椤圭洰娴佺▼淇℃伅 椤圭洰id涓簁ey
+        Map<String,CheckPointVO> map = new HashMap<>();
+        for (ProjectInfo projectInfo : loginUserOwnProjectInfo){
+            CheckPointVO checkPointVO = new CheckPointVO();
+            checkPointVO.setId(projectInfo.getId());
+            checkPointVO.setProjectName(projectInfo.getProjectName());
+            map.put(String.valueOf(projectInfo.getId()),checkPointVO);
+        }
+        //缁勮娴佺▼淇℃伅
+        for (ProjectProcess projectProcess : projectProcessList) {
+
+            CheckPointVO checkPointVO = map.get(projectProcess.getProjectId());
+            checkPointVO.setProcessDefinitionId(projectProcess.getProcessDefId());
+            checkPointVO.setProcessInstanceId(projectProcess.getProcessInsId());
+
+            //鑾峰緱娴佺▼閮ㄧ讲id
+            ProcessInstance process = runtimeService.createProcessInstanceQuery()
+                    .processInstanceId(projectProcess.getProcessInsId()).singleResult();
+            if (Objects.nonNull(process)) {
+                checkPointVO.setDeployId(process.getDeploymentId()); // 杩愯涓祦绋嬬洿鎺ュ彇閮ㄧ讲ID
+                checkPointVO.setProcessName(process.getProcessDefinitionName());
+            } else {
+                // 2. 杩愯涓祦绋嬩笉瀛樺湪锛堝凡缁撴潫锛夛紝鏌ュ巻鍙叉祦绋嬪疄渚�
+                HistoricProcessInstance hisProcess = historyService.createHistoricProcessInstanceQuery()
+                        .processInstanceId(projectProcess.getProcessInsId()).singleResult();
+                // 鍘嗗彶娴佺▼鍙栭儴缃睮D
+                checkPointVO.setDeployId(hisProcess.getDeploymentId());
+                checkPointVO.setProcessName(hisProcess.getProcessDefinitionName());
+            }
+            map.put(projectProcess.getProjectId(),checkPointVO);
+        }
+        // 杞崲涓簂ist鍚庢寜 娴佺▼瀹炰緥id鍒嗙粍
+        List<CheckPointVO> checkPointList = map.values().stream()
+                .collect(Collectors.toList());
+        // 鑾峰緱缁勮濂界殑 娴佺▼map 閿负娴佺▼瀹炰緥id锛�
+        Map<String, CheckPointVO> processInfoMap = checkPointList.stream()
+                .filter(Objects::nonNull) // 閬垮厤null鍏冪礌瀵艰嚧寮傚父锛堝彲閫夛紝鎸夐渶淇濈暀锛�
+                .filter(vo -> vo.getProcessInstanceId() != null) // 杩囨护娴佺▼瀹氫箟ID涓簄ull鐨勬棤鏁堟暟鎹�
+                .collect(Collectors.toMap(
+                        CheckPointVO::getProcessInstanceId, // key锛氭祦绋嬪畾涔塈D锛堟浛鎹负浣犵殑瀹為檯鏂规硶鍚嶏級
+                        vo -> vo, // value锛氬師濮婥heckPointVO瀵硅薄
+                        (oldVal, newVal) -> newVal // 鍐茬獊绛栫暐锛氬瓨鍦ㄩ噸澶岻D鏃朵繚鐣欏悗鑰咃紙鎸夐渶璋冩暣锛�
+                ));
+
+
+        List<Task> allRunningTasks  = taskService.createTaskQuery().active().list();
+        List<Task> targetRunningTasks = allRunningTasks.stream()
+                // 鍏抽敭鍖归厤锛氫换鍔$殑娴佺▼瀹氫箟ID 瀛樺湪浜� projectProcessList 鐨勬祦绋嬪畾涔塈D鍒楄〃涓�
+                .filter(task -> targetProcessInsIds.contains(task.getProcessInstanceId()))
+                .collect(Collectors.toList());
+
+
+        List<TaskInfoVo> list = new ArrayList<>();
+        // 鎸夋祦绋嬪疄渚媔d鍒嗙粍
+        if (!CollectionUtils.isEmpty(targetRunningTasks)){
+
+            //鏌ヨ鍒版墍鏈�
+            List<String> taskIds = targetRunningTasks.stream().map(Task::getId).collect(Collectors.toList());
+            // 浠诲姟杩愯鏃朵笉鍦� list涓紝鍙兘浠诲姟娌℃湁璁剧疆瓒呮椂鏃堕棿
+            List<ProcessCoding> processCodingList = new LambdaQueryChainWrapper<>(processCodingMapper)
+                    .eq(ProcessCoding::getDeleted, Boolean.FALSE)
+                    .in(ProcessCoding::getTaskId, taskIds)
+                    .list();
+            //鎸塼askId杞崲涓簃ap鏂归潰涓嬮潰鑾峰彇
+            if (!CollectionUtils.isEmpty(processCodingList)){
+                Map<String, ProcessCoding> processCodingMap = processCodingList.stream()
+                        .filter(Objects::nonNull) // 閬垮厤null鍏冪礌瀵艰嚧NPE锛堝彲閫変繚鐣欙級
+                        .filter(vo -> vo.getTaskId() != null) // 杩囨护taskId涓簄ull鐨勬棤鏁堟暟鎹�
+                        .collect(Collectors.toMap(
+                                ProcessCoding::getTaskId, // key锛氫粛涓簍askId
+                                vo -> vo, // value锛氬師濮婸rocessCoding瀵硅薄
+                                // 鍐茬獊绛栫暐锛氭瘮杈冨垱寤烘椂闂达紝淇濈暀鏇存柊鐨勯偅涓�
+                                (oldVal, newVal) -> {
+                                    // 鑾峰彇涓よ�呭垱寤烘椂闂达紙鏍规嵁瀹為檯鏂规硶鍚嶈皟鏁达紝濡俫etGmtCreate()
+                                    Date oldCreateTime = oldVal.getGmtCreate();
+                                    Date newCreateTime = newVal.getGmtCreate();
+
+                                    // 澶勭悊鍒涘缓鏃堕棿涓簄ull鐨勬儏鍐碉紙浼樺厛绾э細鏈夋椂闂�>鏃犳椂闂达紝閮芥棤鍒欎繚鐣欏悗鑰咃級
+                                    if (oldCreateTime == null) return newVal;
+                                    if (newCreateTime == null) return oldVal;
+
+                                    // 姣旇緝鏃堕棿鎴筹紝杩斿洖鏇村ぇ鐨勶紙鏇存柊鐨勶級瀵硅薄
+                                    return newCreateTime.getTime() > oldCreateTime.getTime() ? newVal : oldVal;
+                                }
+                        ));
+
+                for (Task task : targetRunningTasks) {
+
+                    TaskInfoVo taskVo = new TaskInfoVo();
+
+                    taskVo.setId(task.getId());
+                    taskVo.setTaskName(task.getName());
+                    taskVo.setStartTime(task.getCreateTime());
+                    taskVo.setEndTime(task.getDueDate());
+//                    taskVo.setTaskType();
+
+                    List<Long> handlerIds = new ArrayList<>(2);
+                    List<String> handlerNames = new ArrayList<>(2);
+                    List<Long> handlerUnitIds = new ArrayList<>(2);
+                    List<String> handlerUnitNames = new ArrayList<>(2);
+                    List<String> promoterNames = new ArrayList<>(2);
+                    List<String> promoterUnitNames = new ArrayList<>(2);
+                    CustomerTaskVO customerTaskVO = new CustomerTaskVO();
+                    customerTaskVO.setHandlerId(handlerIds);
+                    customerTaskVO.setHandlerName(handlerNames);
+                    customerTaskVO.setHandlerUnitId(handlerUnitIds);
+                    customerTaskVO.setHandlerUnitName(handlerUnitNames);
+                    customerTaskVO.setPromoterName(promoterNames);
+                    customerTaskVO.setPromoterUnitName(promoterUnitNames);
+
+                    // 娴佺▼澶勭悊浜轰俊鎭�
+                    List<IdentityLink> identityLinksForTask = taskService.getIdentityLinksForTask(task.getId());
+                    for (IdentityLinkInfo identityLink : identityLinksForTask) {
+                        // 缁戝畾鐨勬槸鐢ㄦ埛锛屾煡鍑虹敤鎴峰鍚嶃�侀儴闂�
+                        if (StringUtils.isNotBlank(identityLink.getUserId())) {
+                            // 澶勭悊鍙橀噺琛ㄨ揪寮忥紝杩愯涓殑浠诲姟鏃犻渶鍐嶅鐞嗚〃杈惧紡浜嗭紝flowable宸茬粡鑷姩鏍规嵁鍙橀噺璁剧疆浜�
+                            customerTaskVO.setHandlerType(HandlerTypeEnum.USER);
+                            SysUser sysUser = sysUserService.selectUserById(Long.parseLong(identityLink.getUserId()));
+                            if (Objects.nonNull(sysUser)) {
+                                customerTaskVO.getHandlerId().add(sysUser.getUserId());
+                                customerTaskVO.getHandlerName().add(this.getUserShowName(sysUser));
+                                if (Objects.nonNull(sysUser.getDept())) {
+                                    customerTaskVO.getHandlerUnitId().add(sysUser.getDept().getDeptId());
+                                    customerTaskVO.getHandlerUnitName().add(sysUser.getDept().getDeptName());
+                                    customerTaskVO.getPromoterName().add(this.getUserShowName(sysUser));
+                                    String[] str = sysUser.getDept().getAncestors().split(",");
+                                    if (str.length >= 4){
+                                        customerTaskVO.getPromoterUnitName().add(sysUser.getDept().getParentName() +"-"+sysUser.getDept().getDeptName());
+                                    }else {
+                                        customerTaskVO.getPromoterUnitName().add(sysUser.getDept().getDeptName());
+                                    }
+
+                                }
+                            }
+                            // 缁戝畾鐨勬槸瑙掕壊鎴栬�呴儴闂�
+                        } else if (StringUtils.isNotBlank(identityLink.getGroupId())) {
+                            if (identityLink.getGroupId().startsWith("dept")) {   // 閮ㄩ棬鐨刬d鏄姞浜嗗墠缂�鐨勫锛歞ept:1
+                                customerTaskVO.setHandlerType(HandlerTypeEnum.DEPT);
+                                String[] split = identityLink.getGroupId().split(":");
+                                if (split.length > 1) {
+                                    // 閮ㄩ棬
+                                    SysDept dept = sysDeptService.selectDeptById(Long.parseLong(split[1]));
+                                    if (Objects.nonNull(dept)) {
+                                        customerTaskVO.getHandlerUnitId().add(dept.getDeptId());
+                                        customerTaskVO.getHandlerUnitName().add(dept.getDeptName());
+                                        customerTaskVO.getPromoterName().add(this.getDeptLeaderShowName(dept));
+                                        customerTaskVO.getPromoterUnitName().add(this.setDeptNameWithParentName(dept));
+                                    }
+                                }
+                            } else {
+                                customerTaskVO.setHandlerType(HandlerTypeEnum.ROLE);
+                                SysRole role = sysRoleService.selectRoleById(Long.parseLong(identityLink.getGroupId()));
+                                if (Objects.nonNull(role)) {
+                                    customerTaskVO.getHandlerUnitId().add(Long.parseLong(identityLink.getGroupId()));
+                                    customerTaskVO.getHandlerUnitName().add(role.getRoleName());
+                                }
+                            }
+                        }
+                        this.distinctVo(customerTaskVO);
+                    }
+                    taskVo.setCustomerTaskInfo(customerTaskVO);
+
+                    //缁勮浠诲姟淇℃伅
+                    CheckPointVO checkPointVO = processInfoMap.get(task.getProcessInstanceId());
+                    if (checkPointVO != null) {
+                       taskVo.setCheckPointInfo(checkPointVO);
+                    }
+                    //瓒呮椂鏃堕棿鍜屾鏁板湪 processCodingList涓�  杩欓噷闇�瑕佹洿鍏穞askId鏉ヨ幏寰楀搴斾俊鎭�
+                    ProcessCoding processCoding = processCodingMap.get(task.getId());
+                    //璁剧疆瓒呮椂淇℃伅
+                    if (processCoding != null) {
+
+                        String overTimeTotalStr = processCoding.getOverTimeTotal();
+                        long overTimeTotal = 0L;
+                        if (StringUtils.isNotBlank(overTimeTotalStr)) {
+                            try {
+                                overTimeTotal = Long.parseLong(overTimeTotalStr.trim());
+                            } catch (NumberFormatException e) {
+
+                            }
+                        }
+                        String overTimeDesc = convertHoursToDayHourStr(overTimeTotal);
+                        taskVo.setTotalOverTime(overTimeDesc);
+
+                        // 2. 鎻愬彇绾㈢爜闃堝�� 濡傦細 0-22 澶�-灏忔椂 骞惰浆鎹负灏忔椂
+                        String redTimeStr = processCoding.getRedTime();
+                        Long redTimeSec = getTime(redTimeStr);
+                        Double redTimeHour = null;
+                        if (redTimeSec != null && redTimeSec > 0) {
+                            redTimeHour = redTimeSec / 3600.0;
+                        }
+                        long overTimeCount = 0L;
+                        // 鍒ゆ柇瓒呮椂娆℃暟
+                        if (overTimeTotal > 0 && redTimeHour != null && redTimeHour > 0) {
+                            overTimeCount = (long) (overTimeTotal / redTimeHour);
+                        }
+
+
+                        taskVo.setOverTimeCount(overTimeCount);
+                    }else {
+                        //涓簄ull 璇存槑鏈厤缃秴鏃舵椂闂� 榛樿鏈秴鏃�
+                        taskVo.setOverTimeCount(0L);
+                        taskVo.setTotalOverTime("0灏忔椂");
+                    }
+                    list.add(taskVo);
+                }
+
+            }
+
+
+        }
+
+        return Result.ok().data(list);
+    }
+    private String convertHoursToDayHourStr(long totalHours) {
+        if (totalHours < 0) {
+            return "0灏忔椂"; // 闃插尽鎬у鐞嗚礋鏁板満鏅�
+        }
+        long days = totalHours / 24; // 璁$畻澶╂暟
+        long hours = totalHours % 24; // 璁$畻鍓╀綑灏忔椂鏁�
+
+        StringBuilder sb = new StringBuilder();
+        if (days > 0) {
+            sb.append(days).append("澶�");
+        }
+        // 灏忔椂鏁版棤璁烘槸鍚︿负0锛岄兘灞曠ず锛堜篃鍙牴鎹笟鍔¤皟鏁达細濡�0灏忔椂鏃朵笉灞曠ず锛�
+        if (hours > 0 || days == 0) {
+            sb.append(hours).append("灏忔椂");
+        }
+        return sb.toString();
+    }
+    // 瀵归儴闂ㄨ礋璐d汉闆嗗悎淇℃伅杩涜鍘婚噸
+    private void distinctVo(CustomerTaskVO vo) {
+        vo.setHandlerId(vo.getHandlerId().stream().distinct().collect(Collectors.toList()));
+        vo.setHandlerName(vo.getHandlerName().stream().distinct().collect(Collectors.toList()));
+        vo.setHandlerUnitId(vo.getHandlerUnitId().stream().distinct().collect(Collectors.toList()));
+        vo.setHandlerUnitName(vo.getHandlerUnitName().stream().distinct().collect(Collectors.toList()));
+    }
+    //鎷兼帴鐢ㄦ埛鏄电О浠ュ強鐢佃瘽
+    private String getUserShowName(SysUser user) {
+        return user.getNickName() + (StringUtils.isNotBlank(user.getPhonenumber()) ? "(" + user.getPhonenumber() + ")" : "");
+    }
+    //鎷兼帴閮ㄩ棬璐熻矗浜轰互鍙婄數璇�
+    private String getDeptLeaderShowName(SysDept dept) {
+        return dept.getLeader() + (StringUtils.isNotBlank(dept.getPhone()) ? "(" + dept.getPhone() + ")" : "");
+    }
+    //鎷兼帴涓婄骇閮ㄩ棬浠ュ強鏈儴闂ㄥ悕绉�
+    private String setDeptNameWithParentName(SysDept dept) {
+        String[] str = dept.getAncestors().split(",");
+        if (str.length >= 4){
+            return dept.getParentName() + "  /  " + dept.getDeptName();
+        }else {
+            return dept.getDeptName();
+        }
+    }
+    private Long getTime(String timeStr) {
+        Long time = null;
+        if (StringUtils.isNotBlank(timeStr)) {
+            String[] timeArr = timeStr.split("-");
+            // 瑙f瀽澶╂暟鍜屽皬鏃舵暟
+            int days = Integer.parseInt(timeArr[0]);
+            int hours = 0;
+            if (timeArr.length > 1) {
+                hours = Integer.parseInt(timeArr[1]);
+            }
+            time = (days * 24L + hours) * 3600L;
+//            //鍒�-绉�
+//            time= (days * 60L) + hours;
+        }
+        return time;
+    }
+
+    @Override
+    public Result getProjectSelectList() {
+        List<ProjectInfo> loginUserOwnProjectInfo = getLoginUserOwnProjectInfo();
+        if (CollectionUtils.isEmpty(loginUserOwnProjectInfo)) {
+            return Result.ok().data(loginUserOwnProjectInfo);
+        }
+        Map<String, String> projectMap = loginUserOwnProjectInfo.stream()
+                .collect(Collectors.toMap(
+                        projectInfo -> String.valueOf(projectInfo.getId()),          // key: 椤圭洰ID
+                        ProjectInfo::getProjectName,          // value: 椤圭洰瀵硅薄鏈韩
+                        (existing, replacement) -> existing,  // 澶勭悊閲嶅ID鐨勫啿绐佺瓥鐣ワ紙淇濈暀鍘熸湁鍊硷級
+                        LinkedHashMap::new
+                ));
+        return Result.ok().data(projectMap);
     }
 }
diff --git a/business/src/main/java/com/ycl/service/impl/ProjectProcessServiceImpl.java b/business/src/main/java/com/ycl/service/impl/ProjectProcessServiceImpl.java
index 4ac381a..84aa178 100644
--- a/business/src/main/java/com/ycl/service/impl/ProjectProcessServiceImpl.java
+++ b/business/src/main/java/com/ycl/service/impl/ProjectProcessServiceImpl.java
@@ -8,7 +8,6 @@
 import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
 import com.ycl.common.constant.ProcessConstants;
 import com.ycl.common.constant.ProcessOverTimeConstants;
-import com.ycl.common.core.domain.AjaxResult;
 import com.ycl.common.core.domain.entity.SysDept;
 import com.ycl.common.core.domain.entity.SysDictData;
 import com.ycl.common.core.domain.entity.SysRole;
@@ -199,6 +198,7 @@
     public Result startProcess(ProjectProcessForm form) {
         Long unitId = null;
         if (ProjectProcessTypeEnum.PROJECT.equals(form.getProjectType())) {
+            //鑾峰緱椤圭洰淇℃伅
             ProjectInfo project = new LambdaQueryChainWrapper<>(projectInfoMapper)
                     .eq(ProjectInfo::getId, form.getProjectId())
                     .one();
@@ -207,6 +207,7 @@
             }
             unitId = project.getProjectOwnerUnit();
         } else if (ProjectProcessTypeEnum.ENGINEERING.equals(form.getProjectType())) {
+            //鑾峰緱宸ョ▼淇℃伅
             ProjectEngineering projectEngineering = new LambdaQueryChainWrapper<>(projectEngineeringMapper)
                     .eq(ProjectEngineering::getId, form.getProjectId())
                     .one();
@@ -219,7 +220,9 @@
         if (Objects.isNull(dept)) {
             throw new RuntimeException("涓氫富鍗曚綅涓嶅瓨鍦�");
         }
+        //鍚姩娴佺▼
         String processInsId = this.startPro(form.getProjectId(), form.getProcessDefId(), dept.getDeptId());
+        //鎻掑叆椤圭洰娴佺▼淇℃伅琛�
         ProjectProcess entity = new ProjectProcess();
         entity.setProjectId(form.getProjectId());
         entity.setProcessDefId(form.getProcessDefId());
@@ -242,7 +245,7 @@
 
 
         ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefId)
-                .latestVersion().singleResult();
+                .latestVersion().singleResult();// 鏌ヨ鏈�鏂扮増鏈殑娴佺▼瀹氫箟 娴佺▼瀹氫箟瀵硅薄
         if (Objects.nonNull(processDefinition) && processDefinition.isSuspended()) {
             throw new RuntimeException("璇ユ祦绋嬪凡琚寕璧�,璇峰厛婵�娲绘祦绋�");
         }
@@ -254,6 +257,7 @@
         // 灏嗚椤圭洰鐨勭敵璇蜂汉锛堜笟涓绘柟锛変綔涓烘祦绋嬩腑鏌愪簺鐜妭鐨勫鐞嗕汉
         variables.put(ProcessConstants.DATA_LAUNCH, "dept:" + createBy);
         variables.put("a", 1);
+        //灏嗗弬鏁版斁鍏lowable娴佺▼寮曟搸骞跺惎鍔ㄦ祦绋�
         ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefId, projectId + "", variables);
         return processInstance.getId();
     }
@@ -736,6 +740,7 @@
         if (Objects.isNull(task)) {
             throw new RuntimeException("鏈湪杩愯浠诲姟涓壘鍒拌浠诲姟锛屾棤娉曟墽琛岃浆鍔炴搷浣�");
         }
+        //閫氳繃IdentityLink锛堣韩浠介摼鎺ワ級鑾峰彇浠诲姟鐨勫師澶勭悊浜� / 缁勶紝鍒嗕袱绉嶆儏鍐垫竻鐞嗭細
         List<IdentityLink> identityLinksForTask = taskService.getIdentityLinksForTask(task.getId());
         // 杞姙涔嬪墠鐨勫鐞嗕汉
         List<String> beforeHandlerIds = new ArrayList<>(2);
@@ -1057,7 +1062,7 @@
      * @param result
      */
     public void getTodoTaskList(String projectId, String processInsId, String taskName, int pageSize, int pageNum, Result result) {
-
+        //TODO 鐪嬬湅濡備綍鑾峰緱浜哄憳淇℃伅鐨�
         TaskQuery taskQuery = taskService.createTaskQuery()
                 .active()
                 .processInstanceId(processInsId)
@@ -1720,7 +1725,8 @@
      * @param hisTaskList
      * @return
      */
-    private List<HistoricTaskInstance> distinctHisTask(List<HistoricTaskInstance> hisTaskList) {
+    @Override
+    public List<HistoricTaskInstance> distinctHisTask(List<HistoricTaskInstance> hisTaskList) {
         Map<String, HistoricTaskInstance> uniqueTasks = new HashMap<>();
         for (HistoricTaskInstance task : hisTaskList) {
             String taskDefinitionKey = task.getTaskDefinitionKey();
diff --git a/business/src/main/java/com/ycl/task/FlowableTask.java b/business/src/main/java/com/ycl/task/FlowableTask.java
index f130f86..dd90247 100644
--- a/business/src/main/java/com/ycl/task/FlowableTask.java
+++ b/business/src/main/java/com/ycl/task/FlowableTask.java
@@ -26,6 +26,7 @@
 import org.springframework.stereotype.Component;
 import org.springframework.util.CollectionUtils;
 
+import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.function.Function;
 import java.util.stream.Collectors;
@@ -123,9 +124,28 @@
 
                 String status = GREEN; // 榛樿鐘舵�佷负缁胯壊
                 String overtimeStatus = NORMAL;
+                Long overtimeDurationSec = null; // 瓒呮椂鏃堕暱锛堢锛屽師濮嬪�硷級
+                Double overtimeDurationHour = null; // 瓒呮椂鏃堕暱锛堝皬鏃讹紝杞崲鍚庯級
                 if (redTime != null && redTime != 0 && durationTime >= redTime) {
                     status = RED; // 濡傛灉瓒呰繃绾㈣壊鏃堕棿闃堝�硷紝鍒欒〃鏄庤浠诲姟瓒呮椂
                     overtimeStatus = OVERTIME;
+                    overtimeDurationSec = durationTime - redTime;
+                    // 2. 杞崲涓哄皬鏃讹紙淇濈暀1浣嶅皬鏁帮紝閬垮厤灏忔暟杩囧锛�
+                    overtimeDurationHour = Math.round((overtimeDurationSec / 3600.0) * 10) / 10.0;
+
+                    // 鏃堕棿鏍煎紡鍖栵紙Java鏍囧噯API锛屾棤渚濊禆锛�
+                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                    String formattedStartTime = sdf.format(startTime);
+                    String formattedNow = sdf.format(now);
+                    // 杞崲绾㈢爜闃堝�间负灏忔椂锛堝彲閫夛紝鏃ュ織鏇存槗璇伙級
+                    Double redTimeHour = Math.round((redTime / 3600.0) * 10) / 10.0;
+                    Double durationTimeHour = Math.round((durationTime / 3600.0) * 10) / 10.0;
+
+                    // 鎵撳嵃瓒呮椂鏃堕暱锛堝皬鏃跺崟浣嶏級
+                    log.info("浠诲姟瓒呮椂棰勮锛氫换鍔D[{}]锛屾祦绋嬪疄渚婭D[{}]锛岃鏃惰捣鐐筟{}]锛屽綋鍓嶆椂闂碵{}]锛岀孩鐮侀槇鍊糩{}灏忔椂]锛屽疄闄呮湁鏁堣�楁椂[{}灏忔椂]锛岃秴鏃舵椂闀縖{}灏忔椂]",
+                            taskId, task.getProcessInstanceId(),
+                            formattedStartTime, formattedNow,
+                            redTimeHour, durationTimeHour, overtimeDurationHour);
                 }
 //                else if (yellowTime != null && yellowTime != 0 && durationTime >= yellowTime) {
 //                    status = YELLOW; // 鍚﹀垯锛屽鏋滆秴杩囬粍鑹叉椂闂撮槇鍊硷紝鍒欑姸鎬佷负榛勮壊
@@ -141,6 +161,7 @@
 //                    overtimeStatus = WILLOVERTIME; // 濡傛灉涓存湡(鍥哄畾瓒呮椂鍓�12灏忔椂涓轰复鏈�)
 //                }
                 map.get(status).add(task.getProcessInstanceId());
+                processCoding.setOverTimeTotal(String.valueOf(overtimeDurationHour));
                 processCoding.setStatus(status);
                 processCoding.setOvertimeStatus(overtimeStatus);
                 processCoding.setStartTaskTime(task.getCreateTime());
diff --git a/business/src/main/resources/mapper/ProjectInfoMapper.xml b/business/src/main/resources/mapper/ProjectInfoMapper.xml
index 6a87a4b..3220832 100644
--- a/business/src/main/resources/mapper/ProjectInfoMapper.xml
+++ b/business/src/main/resources/mapper/ProjectInfoMapper.xml
@@ -250,10 +250,10 @@
 
     </select>
 
-    <select id="getProjectInfoAndFunding" parameterType="com.ycl.common.core.domain.BaseEntity" resultMap="resultMap">
-        SELECT TPI.*,TPIF.total_investment,TPIF.principal,TPIF.government_investment_total,
+    <select id="getProjectInfoAndFunding" parameterType="com.ycl.common.core.domain.BaseEntity" resultType="com.ycl.domain.vo.ProjectInvestmentFundingVO">
+        SELECT TPIF.project_id,TPIF.total_investment,TPIF.principal,TPIF.government_investment_total,
                TPIF.central_investment_total,TPIF.provincial_investment_total,TPIF.city_investment_total,TPIF.county_investment_total,
-               TPIF.other_investment_total
+               TPIF.other_investment_total,TPIF.enterprise_self_raised_total,TPIF.foreign_investment_total,TPIF.bank_loan,TPIF.domestic_loan_total
         FROM t_project_info TPI
         LEFT JOIN t_project_investment_funding TPIF ON TPI.id = TPIF.project_id and TPIF.deleted = 0
         LEFT JOIN sys_dept d ON TPI.project_owner_unit = d.dept_id
diff --git a/flowable/src/main/java/com/ycl/domain/entity/ProcessCoding.java b/flowable/src/main/java/com/ycl/domain/entity/ProcessCoding.java
index 11ecc79..095b8eb 100644
--- a/flowable/src/main/java/com/ycl/domain/entity/ProcessCoding.java
+++ b/flowable/src/main/java/com/ycl/domain/entity/ProcessCoding.java
@@ -57,4 +57,7 @@
 
     @TableField("start_task_time")
     private Date startTaskTime;
+
+    @TableField("overtime_total")
+    private String overTimeTotal;
 }
diff --git a/flowable/src/main/resources/mapper/ProcessCodingMapper.xml b/flowable/src/main/resources/mapper/ProcessCodingMapper.xml
index eebbdf5..1205492 100644
--- a/flowable/src/main/resources/mapper/ProcessCodingMapper.xml
+++ b/flowable/src/main/resources/mapper/ProcessCodingMapper.xml
@@ -97,6 +97,12 @@
                     when id=#{item.id} then #{item.startTaskTime}
                 </foreach>
             </trim>
+            <trim prefix="overtime_total =case" suffix="end"><!-- 鏈�鍚庝竴涓瓧娈典笉鍔犻�楀彿锛岄伩鍏峴uffixOverrides鏃犳硶绉婚櫎 -->
+                <foreach collection="list" item="item">
+                    <!-- 鏈秴鏃跺垯璁句负null锛屽凡瓒呮椂鍒欏瓨鍏ュ皬鏃舵暟锛堜繚鐣�1浣嶅皬鏁帮級 -->
+                    when id=#{item.id} then #{item.overTimeTotal}
+                </foreach>
+            </trim>
         </trim>
         where id in
         <foreach collection="list" index="index" item="item" separator="," open="(" close=")">
diff --git a/start/src/main/resources/application-dev.yml b/start/src/main/resources/application-dev.yml
index e3f1c76..7d744aa 100644
--- a/start/src/main/resources/application-dev.yml
+++ b/start/src/main/resources/application-dev.yml
@@ -19,13 +19,14 @@
     # redis 閰嶇疆
     redis:
         # 鍦板潃
-        host: 42.193.1.25
+        host: 127.0.0.1
         # 绔彛锛岄粯璁や负6379
         port: 6379
         # 鏁版嵁搴撶储寮�
         database: 2
         # 瀵嗙爜
-        password: ycl2018
+#        password: ycl2018
+        password:
         # 杩炴帴瓒呮椂鏃堕棿
         timeout: 10s
         lettuce:
@@ -45,9 +46,13 @@
             # 涓诲簱鏁版嵁婧�
             master:
 #                url: jdbc:mysql://42.193.1.25:3306/project_management?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true
-                url: jdbc:mysql://42.193.1.25:3306/project_management_test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowMultiQueries=true
+#                url: jdbc:mysql://42.193.1.25:3306/project_management_test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowMultiQueries=true
+                url: jdbc:mysql://127.0.0.1:3306/project_management?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowMultiQueries=true
+
                 username: root
-                password: 321$YcYl@1970!
+#                password: 321$YcYl@1970!
+                password: 123456
+
             # 浠庡簱鏁版嵁婧�
             slave:
                 # 浠庢暟鎹簮寮�鍏�/榛樿鍏抽棴
@@ -117,3 +122,4 @@
 
 # 鐢ㄤ簬鏇挎崲鍔ㄦ�佽〃鍗曠殑鏂囦欢涓婁紶ip锛堟洿鎹㈡湇鍔″櫒ip娌¤皟鏁达級
 targetIp: 119.6.246.90
+

--
Gitblit v1.8.0