Pārlūkot izejas kodu

任务提交对比

yusm 3 nedēļas atpakaļ
vecāks
revīzija
b645b17b62

+ 116 - 1
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/TaskController.java

@@ -6,9 +6,13 @@ import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.management.platform.constant.Constant;
+import com.management.platform.demo.BeanDiffUtil;
+import com.management.platform.demo.ListDiffUtil;
 import com.management.platform.entity.*;
 import com.management.platform.entity.bo.QueryTaskChargePage;
+import com.management.platform.entity.vo.ExecutorVo;
 import com.management.platform.entity.vo.SysRichFunction;
+import com.management.platform.entity.vo.TaskAllocateVo;
 import com.management.platform.entity.vo.UserVO;
 import com.management.platform.mapper.*;
 import com.management.platform.service.*;
@@ -21,6 +25,7 @@ import net.sourceforge.tess4j.ITessAPI;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.poi.hssf.usermodel.*;
 import org.assertj.core.util.Lists;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.transaction.annotation.Transactional;
@@ -204,6 +209,11 @@ public class TaskController {
         int isInsert=0;
         boolean shouldResetAuditStatus = false;
         boolean shouldUpdatetaskDailyAllocate = false;
+        ArrayList<ExecutorVo> newExecutorVos = new ArrayList<>();
+        ArrayList<ExecutorVo> oldExecutorVos = new ArrayList<>();
+        ArrayList<TaskAllocateVo> newTaskAllocateVos = new ArrayList<>();
+        ArrayList<TaskAllocateVo> oldTaskAllocateVos = new ArrayList<>();
+        Integer initTaskStatus=null;//修改任务的时候,任务的初始状态
         List<TaskType> typeList = taskTypeMapper.selectList(new QueryWrapper<TaskType>().eq("company_id", user.getCompanyId()));
         TaskType taskType = typeList.stream().filter(t->t.getId()==task.getTaskPlanType()).findAny().orElse(null);
         if (taskType == null){
@@ -236,6 +246,8 @@ public class TaskController {
             } else {
                 task.setTaskStatus(STATUS_FIRST_CHECK);
             }
+        }else {
+            initTaskStatus=task.getTaskStatus();
         }
         ArrayList<TaskDailyAllocate> allocateArrayList = new ArrayList<>();
         if (!StringUtils.isEmpty(executorListStr)) {
@@ -379,6 +391,9 @@ public class TaskController {
         List<String> msgRecepientList = new ArrayList<>();
         List<Task> needReOrderList = new ArrayList<>();
         StringBuilder taskCommentString=new StringBuilder();
+        StringJoiner joiner=new StringJoiner(",");//任务字段变化的记录
+        StringJoiner joinerExecutor=new StringJoiner(",");//执行人字段变化的记录
+        StringJoiner joinerAllocate=new StringJoiner(",");//分配时间字段变化的记录
         //新建的任务需要计算排序
         if (task.getId() == null) {
             isNew = true;
@@ -406,8 +421,50 @@ public class TaskController {
             if (task.getTaskType()!=null&&task.getTaskType() == 1) {
                 needRecalculateProgress = true;
             }
-        } else {
+        }
+        else {
             Task oldTask = taskService.getById(task.getId());
+            List<BeanDiffUtil.FieldDifference> changes = new BeanDiffUtil<Task>(oldTask, task)
+                    .compare("任务类型", Task::getTaskPlanType)
+                    .compare("所属项目", Task::getProjectId)
+                    .compare("研究中心", Task::getCenterId)
+                    .compare("所属任务分组", Task::getGroupId)
+                    .compare("所属任务列表", Task::getStagesId)
+                    .compare("前置任务", Task::getAheadTid)
+                    .compare("计划内容", Task::getName)
+                    .compare("开始时间", Task::getStartDate)
+                    .compare("截止时间", Task::getEndDate)
+                    .compare("优先级", Task::getTaskLevel)
+                    .compare("详细描述", Task::getTaskDesc)
+                    .getDifferences();
+
+            for (BeanDiffUtil.FieldDifference fieldDifference : changes) {
+                joiner.add(fieldDifference.getFieldName());
+            }
+            if (joiner.length() > 0) {
+                joiner.add("发生了变化");
+            }
+            List<TaskExecutor> executorList = JSONArray.parseArray(executorListStr, TaskExecutor.class);
+            for (TaskExecutor executor : executorList) {
+                ExecutorVo executorVo = new ExecutorVo();
+                BeanUtils.copyProperties(executor, executorVo);
+                newExecutorVos.add(executorVo);
+            }
+
+            for (TaskDailyAllocate dailyAllocate : allocateArrayList) {
+                TaskAllocateVo taskAllocateVo = new TaskAllocateVo();
+                BeanUtils.copyProperties(dailyAllocate, taskAllocateVo);
+                newTaskAllocateVos.add(taskAllocateVo);
+            }
+
+            List<TaskDailyAllocate> allocateList = taskDailyAllocateService.list(new QueryWrapper<TaskDailyAllocate>().eq("task_id", task.getId()));
+            for (TaskDailyAllocate dailyAllocate : allocateList) {
+                TaskAllocateVo taskAllocateVo = new TaskAllocateVo();
+                BeanUtils.copyProperties(dailyAllocate, taskAllocateVo);
+                oldTaskAllocateVos.add(taskAllocateVo);
+            }
+
+
             if (taskType.getNeedAudit()) {
                 if (oldTask.getTaskStatus() == STATUS_CANCEL || oldTask.getTaskStatus() == STATUS_FIRST_REJECT || oldTask.getTaskStatus() == STATUS_SECOND_REJECT) {
                     //重新提交
@@ -422,6 +479,53 @@ public class TaskController {
                 taskService.update(sample, new QueryWrapper<Task>().eq("parent_tid", task.getId()));
             }
             List<TaskExecutor> oldExeList = taskExecutorMapper.selectList(new QueryWrapper<TaskExecutor>().eq("task_id", task.getId()));
+            for (TaskExecutor oldExe : oldExeList) {
+                ExecutorVo executorVo = new ExecutorVo();
+                BeanUtils.copyProperties(oldExe, executorVo);
+                oldExecutorVos.add(executorVo);
+            }
+
+            //对比比较执行人是否发生变化
+            if (newExecutorVos.stream().anyMatch(t -> t.getId() == null)) {
+                joinerExecutor.add("执行人发生变化");
+            } else{
+                // 进行比较
+                ListDiffUtil.ListComparisonResult<ExecutorVo> result = ListDiffUtil.compareLists(
+                        oldExecutorVos,
+                        newExecutorVos,
+                        ExecutorVo::getId,
+                        Arrays.asList(
+                                ExecutorVo::getExecutorId,
+                                ExecutorVo::getPlanHours
+                        )
+                );
+                if (!result.getAdded().isEmpty() || !result.getChanged().isEmpty() || !result.getRemoved().isEmpty()) {
+                    joinerExecutor.add("执行人发生变化");
+                }
+            }
+
+            if (newTaskAllocateVos.stream().anyMatch(t -> t.getId() == null)) {
+                joinerAllocate.add("每日分配工时发生变化");
+            }else {
+                // 进行比较
+                ListDiffUtil.ListComparisonResult<TaskAllocateVo> allocateResult = ListDiffUtil.compareLists(
+                        oldTaskAllocateVos,
+                        newTaskAllocateVos,
+                        TaskAllocateVo::getId,
+                        Arrays.asList(
+                                TaskAllocateVo::getUserId,
+                                TaskAllocateVo::getStartTime,
+                                TaskAllocateVo::getEndTime,
+                                TaskAllocateVo::getAllocateDate,
+                                TaskAllocateVo::getWorkHour,
+                                TaskAllocateVo::getOverWorkHour
+                        )
+                );
+                if (!allocateResult.getAdded().isEmpty() || !allocateResult.getChanged().isEmpty() || !allocateResult.getRemoved().isEmpty()) {
+                    joinerAllocate.add("分配每日工时发生变化");
+                }
+            }
+
             CompanyDingding dingding = companyDingdingService.getOne(new LambdaQueryWrapper<CompanyDingding>().eq(CompanyDingding::getCompanyId, user.getCompanyId()));
             //计算需要移除的执行人
             List<Integer> ids = oldExeList.stream().filter(old->!task.getExecutorList().stream().anyMatch(newT->newT.getId()!=null&&newT.getId().equals(old.getId())))
@@ -578,6 +682,17 @@ public class TaskController {
                 taskDailyAllocateService.saveBatch(allocateArrayList);
             }
         } else if (saved&&shouldUpdatetaskDailyAllocate) {
+            if (initTaskStatus==3||initTaskStatus==4){
+                if (joiner.length()>0){
+                    log.info("任务变化内容:"+joiner.toString());
+                }
+                if (joinerExecutor.length()>0){
+                    log.info("执行人变化:"+joinerExecutor.toString());
+                }
+                if (joinerAllocate.length()>0){
+                    log.info("分配每日工时变化:"+joinerAllocate.toString());
+                }
+            }
             if (!allocateArrayList.isEmpty()) {
                 taskDailyAllocateService.remove(new QueryWrapper<TaskDailyAllocate>().eq("task_id",task.getId()));
                 taskDailyAllocateService.saveBatch(allocateArrayList);

+ 42 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/demo/BeanDiffUtil.java

@@ -0,0 +1,42 @@
+package com.management.platform.demo;
+
+
+import lombok.Data;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Function;
+
+public class BeanDiffUtil<T> {
+    
+    private final List<FieldDifference> differences = new ArrayList<>();
+    private final T oldObj;
+    private final T newObj;
+
+    public BeanDiffUtil(T oldObj, T newObj) {
+        this.oldObj = oldObj;
+        this.newObj = newObj;
+    }
+
+    public BeanDiffUtil<T> compare(String fieldName, Function<T, ?> extractor) {
+        Object oldValue = extractor.apply(oldObj);
+        Object newValue = extractor.apply(newObj);
+        
+        if (!Objects.equals(oldValue, newValue)) {
+            differences.add(new FieldDifference(fieldName, oldValue, newValue));
+        }
+        return this;
+    }
+
+    public List<FieldDifference> getDifferences() {
+        return differences;
+    }
+
+    @Data
+    public static class FieldDifference {
+        private final String fieldName;
+        private final Object oldValue;
+        private final Object newValue;
+
+    }
+}

+ 85 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/demo/ListDiffUtil.java

@@ -0,0 +1,85 @@
+package com.management.platform.demo;
+
+import lombok.Data;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+public class ListDiffUtil<T> {
+
+    @Data
+    public static class ListComparisonResult<T> {
+        private final List<T> added;
+        private final List<T> removed;
+        private final List<ElementChange<T>> changed;
+        
+
+    }
+
+    @Data
+    public static class ElementChange<T> {
+        private final T oldElement;
+        private final T newElement;
+        private final List<BeanDiffUtil.FieldDifference> fieldDifferences;
+        
+
+    }
+
+    public static <T> ListComparisonResult<T> compareLists(
+        List<T> oldList, 
+        List<T> newList,
+        Function<T, Object> identityExtractor,
+        List<Function<T, ?>> fieldExtractors) {
+        
+        // 1. 识别新增和删除的元素
+        Map<Object, T> oldMap = oldList.stream()
+            .collect(Collectors.toMap(identityExtractor, e -> e));
+        
+        Map<Object, T> newMap = newList.stream()
+            .collect(Collectors.toMap(identityExtractor, e -> e));
+        
+        List<T> added = newList.stream()
+            .filter(e -> !oldMap.containsKey(identityExtractor.apply(e)))
+            .collect(Collectors.toList());
+        
+        List<T> removed = oldList.stream()
+            .filter(e -> !newMap.containsKey(identityExtractor.apply(e)))
+            .collect(Collectors.toList());
+        
+        // 2. 识别修改的元素
+        List<ElementChange<T>> changed = new ArrayList<>();
+        
+        newList.forEach(newElement -> {
+            Object id = identityExtractor.apply(newElement);
+            if (oldMap.containsKey(id)) {
+                T oldElement = oldMap.get(id);
+                List<BeanDiffUtil.FieldDifference> diffs = compareElements(oldElement, newElement, fieldExtractors);
+                if (!diffs.isEmpty()) {
+                    changed.add(new ElementChange<>(oldElement, newElement, diffs));
+                }
+            }
+        });
+        
+        return new ListComparisonResult<>(added, removed, changed);
+    }
+    
+    private static <T> List<BeanDiffUtil.FieldDifference> compareElements(
+        T oldElement, 
+        T newElement,
+        List<Function<T, ?>> fieldExtractors) {
+        
+        return fieldExtractors.stream()
+            .map(extractor -> {
+                Object oldValue = extractor.apply(oldElement);
+                Object newValue = extractor.apply(newElement);
+                return new BeanDiffUtil.FieldDifference(
+                    extractor.toString(), // 可以用更好的方式获取字段名
+                    oldValue,
+                    newValue
+                );
+            })
+            .filter(diff -> !Objects.equals(diff.getOldValue(), diff.getNewValue()))
+            .collect(Collectors.toList());
+    }
+}

+ 10 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/entity/vo/ExecutorVo.java

@@ -0,0 +1,10 @@
+package com.management.platform.entity.vo;
+
+import lombok.Data;
+
+@Data
+public class ExecutorVo {
+    private Integer id;
+    private String executorId;
+    private String planHours;
+}

+ 24 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/entity/vo/TaskAllocateVo.java

@@ -0,0 +1,24 @@
+package com.management.platform.entity.vo;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDate;
+import java.time.LocalTime;
+
+@Data
+public class TaskAllocateVo {
+
+    private Integer id;
+    private Integer taskId;
+    private String userId;
+    private LocalTime startTime;
+    private LocalTime endTime;
+    private LocalDate allocateDate;
+    private Double workHour;
+    private Double overWorkHour;
+}