Forráskód Böngészése

Merge branch 'master' of http://47.100.37.243:10191/wutt/manHourHousekeeper

Guo1B0 1 éve
szülő
commit
e2e7c90e58
35 módosított fájl, 1022 hozzáadás és 295 törlés
  1. 6 5
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/Task.java
  2. 3 1
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/TaskLog.java
  3. 2 1
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/vo/TasKVo.java
  4. 53 47
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/TaskServiceImpl.java
  5. 5 5
      fhKeeper/formulahousekeeper/management-crm/src/main/resources/mapper/TaskMapper.xml
  6. 85 123
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectApprovalController.java
  7. 4 4
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectController.java
  8. 44 38
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java
  9. 82 14
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserWithBeisenController.java
  10. 21 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/WxCorpTemplateController.java
  11. 18 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/TimeType.java
  12. 47 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/WxCorpTemplate.java
  13. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/WxCorpTemplateMapper.java
  14. 2 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ProjectApprovalService.java
  15. 2 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ProjectService.java
  16. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ReportService.java
  17. 6 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/WxCorpInfoService.java
  18. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/WxCorpTemplateService.java
  19. 130 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectApprovalServiceImpl.java
  20. 58 11
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java
  21. 128 16
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  22. 90 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/WxCorpInfoServiceImpl.java
  23. 20 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/WxCorpTemplateServiceImpl.java
  24. 11 9
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java
  25. 66 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/BeiSenUtils.java
  26. 4 3
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectMapper.xml
  27. 4 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/TimeTypeMapper.xml
  28. 17 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/WxCorpTemplateMapper.xml
  29. 15 4
      fhKeeper/formulahousekeeper/timesheet/src/views/corpreport/list.vue
  30. 1 1
      fhKeeper/formulahousekeeper/timesheet/src/views/project/list.vue
  31. 17 0
      fhKeeper/formulahousekeeper/timesheet/src/views/projectApproval/projectApproval.vue
  32. 7 0
      fhKeeper/formulahousekeeper/timesheet/src/views/settings/timetype.vue
  33. 32 4
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue
  34. 5 0
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/index.vue
  35. 4 1
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/weekEdit.vue

+ 6 - 5
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/Task.java

@@ -6,6 +6,7 @@ import java.time.LocalDate;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableField;
 import java.io.Serializable;
+import java.util.Date;
 import java.util.List;
 
 import lombok.Data;
@@ -130,7 +131,7 @@ public class Task extends Model<Task> {
      * 重复结束 在  ? 日期YYYY-MM-DD之后
      */
     @TableField("repeat_end_date")
-    private LocalDate repeatEndDate;
+    private Date repeatEndDate;
 
     /**
      * 自定义周期: 每 ? 天一次,保存为 x1,x2,x3,x4
@@ -166,25 +167,25 @@ public class Task extends Model<Task> {
      * 创建时间
      */
     @TableField("create_date")
-    private LocalDate createDate;
+    private Date createDate;
 
     /**
      * 截止时间
      */
     @TableField("end_date")
-    private LocalDate endDate;
+    private Date endDate;
 
     /**
      * 开始日期
      */
     @TableField("start_date")
-    private LocalDate startDate;
+    private Date startDate;
 
     /**
      * 完成日期
      */
     @TableField("finish_date")
-    private LocalDate finishDate;
+    private Date finishDate;
 
     /**
      * 是否被删除: 0否,1是

+ 3 - 1
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/TaskLog.java

@@ -6,6 +6,8 @@ import com.baomidou.mybatisplus.annotation.TableId;
 import java.time.LocalDateTime;
 import com.baomidou.mybatisplus.annotation.TableField;
 import java.io.Serializable;
+import java.util.Date;
+
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
@@ -41,7 +43,7 @@ public class TaskLog extends Model<TaskLog> {
      * 修改时间
      */
     @TableField("mod_time")
-    private LocalDateTime modTime;
+    private Date modTime;
 
     /**
      * 修改人

+ 2 - 1
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/vo/TasKVo.java

@@ -28,7 +28,8 @@ public class TasKVo extends Task {
     private String contactsName;
     private String contactsPhone;
 
-    private List taskExecutors;
+
+    private List<String> taskExecutors;
 
 
 }

+ 53 - 47
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/TaskServiceImpl.java

@@ -121,9 +121,9 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
         }
         Task task = new Task();
         BeanUtils.copyProperties(taskDto,task);
-        task.setCreateDate(LocalDate.now());//任务的创建时间
+        task.setCreateDate(new Date());//任务的创建时间
         //根据任务的开始时间与当下时间判断任务的状态
-        if (taskDto.getStartDate()==null||taskDto.getStartDate().isAfter(LocalDate.now())){
+        if (taskDto.getStartDate()==null||taskDto.getStartDate().after(new Date())){
             task.setStatus(0);
         }else {
             task.setStatus(1);
@@ -163,7 +163,6 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
         taskLog.setContent("创建了任务");
         taskLog.setUserId(userId);
         taskLog.setUserName(user.getName());
-        taskLog.setModTime(LocalDateTime.now());
         taskLog.setCompanyId(user.getCompanyId());
         taskLogMapper.insert(taskLog);
 
@@ -181,18 +180,14 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
         List<TaskLog> taskLogList = taskLogMapper.selectList(new LambdaQueryWrapper<TaskLog>().eq(TaskLog::getCompanyId,user.getCompanyId()));
         List<TasKVo> taskVoList =taskMapper.getPageListTask(taskDto);
         for (TasKVo tasKVo : taskVoList) {
-            System.out.println(tasKVo.getStartDate());
-            System.out.println(tasKVo.getEndDate());
-            System.out.println(tasKVo.getCreateDate());
             if (!taskExecutorList.isEmpty()){
                 List<TaskExecutor> collect = taskExecutorList.stream().
                         filter(taskExecutor -> taskExecutor.getTaskId().equals(tasKVo.getId())).
                         filter(taskExecutor -> taskExecutor.getCompanyId().equals(user.getCompanyId()))
                         .collect(Collectors.toList());
                 if (!collect.isEmpty()){
-                    List<String> collect1 = collect.stream().map(TaskExecutor::getExecutorId).collect(Collectors.toList());
-                    ArrayList<String> taskExecutorIds = new ArrayList<>(collect1);
-                    tasKVo.setTaskExecutors(taskExecutorIds);
+                    List<String> collect1 = collect.stream().map(TaskExecutor::getExecutorName).collect(Collectors.toList());
+                    tasKVo.setTaskExecutors(collect1);
                 }
             }
             if (!taskLogList.isEmpty()){
@@ -204,17 +199,6 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
             }
 
         }
-        if (!taskVoList.isEmpty()){
-            taskVoList.forEach(tasKVo -> {
-                if (!tasKVo.getTaskExecutors().isEmpty()){
-                    Integer taskId = tasKVo.getId();
-                    LambdaQueryWrapper<TaskExecutor> lqw = new LambdaQueryWrapper<>();
-                    lqw.eq(TaskExecutor::getTaskId,taskId);
-                    List<TaskExecutor> taskExecutors = taskExecutorMapper.selectList(lqw);
-                    tasKVo.setTaskExecutors(taskExecutors);
-                }
-            });
-        }
         List<TasKVo> taskVoTotalList= taskMapper.getPageListTotalTask(taskDto);
         HttpRespMsg msg = new HttpRespMsg();
         HashMap<String, Object> map = new HashMap<>();
@@ -272,7 +256,6 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
         taskLog.setContent("修改了任务");
         taskLog.setUserId(user.getId());
         taskLog.setUserName(user.getName());
-        taskLog.setModTime(LocalDateTime.now());
         taskLogMapper.insert(taskLog);
 
         return msg;
@@ -414,7 +397,7 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
                 Task task=new Task();
                 task.setCompanyId(companyId);
                 task.setCreaterId(user.getId());
-                task.setCreateDate(LocalDate.now());
+                task.setCreateDate(new Date());
                 for (int i = 0; i < cellNum; i++) {
                     JSONObject item = configObJSONArray.getJSONObject(i);
                     String modelName = item.getString("model");
@@ -518,7 +501,7 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
                             if (cell.getCellTypeEnum() == CellType.NUMERIC){
                                 double numericCellValue = cell.getNumericCellValue();
                                 long daysSince1900 = (long) numericCellValue - 2;
-                                task.setStartDate(LocalDate.of(1900, 1, 1).plusDays(daysSince1900));
+                                task.setStartDate(new Date(daysSince1900));
                             }
                         }
                     }
@@ -527,7 +510,7 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
                             if (cell.getCellTypeEnum() == CellType.NUMERIC){
                                 double numericCellValue = cell.getNumericCellValue();
                                 long daysSince1900 = (long) numericCellValue - 2;
-                                task.setEndDate(LocalDate.of(1900, 1, 1).plusDays(daysSince1900));
+                                task.setEndDate(new Date(daysSince1900));
                             }
                         }
                     }
@@ -687,7 +670,6 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
                         TaskLog taskLog = new TaskLog();
                         taskLog.setTaskId(task.getId());
                         taskLog.setContent("通过文件导入任务");
-                        taskLog.setModTime(LocalDateTime.now());
                         taskLog.setUserName(user.getName());
                         taskLog.setUserId(user.getId());
                         taskLog.setCompanyId(user.getCompanyId());
@@ -721,6 +703,8 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
         User user = userMapper.selectById(request.getHeader("token"));
         SysForm sysForm = sysFormMapper.selectOne(new LambdaQueryWrapper<SysForm>().eq(SysForm::getCompanyId, user.getCompanyId()).eq(SysForm::getCode, "Task").eq(SysForm::getIsCurrent, 1));
         WxCorpInfo wxCorpInfo = wxCorpInfoService.getOne(new LambdaQueryWrapper<WxCorpInfo>().eq(WxCorpInfo::getCompanyId, user.getCompanyId()));
+        List<TaskExecutor> taskExecutorList = taskExecutorMapper.selectList(new LambdaQueryWrapper<TaskExecutor>().eq(TaskExecutor::getCompanyId,user.getCompanyId()));
+        List<TaskLog> taskLogList = taskLogMapper.selectList(new LambdaQueryWrapper<TaskLog>().eq(TaskLog::getCompanyId,user.getCompanyId()));
         String config = sysForm.getConfig();
         JSONObject configOb = JSON.parseObject(config);
         JSONArray configObJSONArray = configOb.getJSONArray("list");
@@ -736,16 +720,20 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
         taskDto.setPageIndex(null).setPageSize(null);//暂时部不分页
         List<TasKVo> taskVoList =taskMapper.getPageListTask(taskDto);
         if (!taskVoList.isEmpty()){
-            taskVoList.forEach(tasKVo -> {
-                if (!tasKVo.getTaskExecutors().isEmpty()){
-                    Integer taskId = tasKVo.getId();
-                    LambdaQueryWrapper<TaskExecutor> lqw = new LambdaQueryWrapper<>();
-                    lqw.eq(TaskExecutor::getTaskId,taskId);
-                    List<TaskExecutor> taskExecutors = taskExecutorMapper.selectList(lqw);
-                    tasKVo.setTaskExecutors(taskExecutors);
+            for (TasKVo tasKVo : taskVoList) {
+                if (!taskExecutorList.isEmpty()){
+                    List<TaskExecutor> collect = taskExecutorList.stream().
+                            filter(taskExecutor -> taskExecutor.getTaskId().equals(tasKVo.getId())).
+                            filter(taskExecutor -> taskExecutor.getCompanyId().equals(user.getCompanyId()))
+                            .collect(Collectors.toList());
+                    if (!collect.isEmpty()){
+                        List<String> collect1 = collect.stream().map(TaskExecutor::getExecutorName).collect(Collectors.toList());
+                        tasKVo.setTaskExecutors(collect1);
+                    }
                 }
-            });
+            }
         }
+
         for (TasKVo tasKVo : taskVoList) {
             List<String> item=new ArrayList<>();
             for (int i = 0; i < configObJSONArray.size(); i++) {
@@ -768,33 +756,51 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
                 if(model.equals("taskName")){
                     value = String.valueOf(aClass.getMethod("getTaskName").invoke(tasKVo)).equals("null")?"":String.valueOf(aClass.getMethod("getTaskName").invoke(tasKVo));
                 }
-                if(model.equals("priority")){
+                else if(model.equals("priority")){
                     value = String.valueOf(aClass.getMethod("getPriority").invoke(tasKVo)).equals("null")?"":String.valueOf(aClass.getMethod("getPriority").invoke(tasKVo));
                 }
-                if(model.equals("executorId")){
+                else if(model.equals("executorId")){
                     StringJoiner stringJoiner = new StringJoiner(",");
-                    List<TaskExecutor> taskExecutors = tasKVo.getTaskExecutors();
+                    List<String> taskExecutors = tasKVo.getTaskExecutors();
                     if (taskExecutors!=null&&!taskExecutors.isEmpty()){
-                        for (TaskExecutor taskExecutor : taskExecutors) {
-                            stringJoiner.add(taskExecutor.getExecutorName());
+                        for (String taskExecutor : taskExecutors) {
+                            stringJoiner.add(taskExecutor);
                         }
                     }
                     value =stringJoiner.length()==0?"":stringJoiner.toString();
                 }
-                if(model.equals("startDate")){
+                else if(model.equals("startDate")){
                     if (tasKVo.getStartDate()!=null){
-                        LocalDate startDate = tasKVo.getStartDate();
-                        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
-                        value=startDate.format(dateTimeFormatter);
+                        Date startDate = tasKVo.getStartDate();
+                        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+                        value=format.format(startDate);
                     }
                 }
-                if(model.equals("endDate")){
+                else if(model.equals("endDate")){
                     if (tasKVo.getEndDate()!=null){
-                        LocalDate endDate = tasKVo.getEndDate();
-                        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
-                        value=endDate.format(dateTimeFormatter);
+                        Date endDate = tasKVo.getEndDate();
+                        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+                        value=format.format(endDate);
                     }
                 }
+                else if(model.equals("customId")){
+                    value = String.valueOf(aClass.getMethod("getCustomName").invoke(tasKVo)).equals("null")?"":String.valueOf(aClass.getMethod("getCustomName").invoke(tasKVo));
+                }
+                else if(model.equals("businessOpportunityId")){
+                    value = String.valueOf(aClass.getMethod("getBusinessName").invoke(tasKVo)).equals("null")?"":String.valueOf(aClass.getMethod("getBusinessName").invoke(tasKVo));
+                }
+                else if(model.equals("orderId")){
+                    value = String.valueOf(aClass.getMethod("getOrderName").invoke(tasKVo)).equals("null")?"":String.valueOf(aClass.getMethod("getOrderName").invoke(tasKVo));
+                }
+                else if(model.equals("clueId")){
+                    value = String.valueOf(aClass.getMethod("getClueName").invoke(tasKVo)).equals("null")?"":String.valueOf(aClass.getMethod("getClueName").invoke(tasKVo));
+                }
+                else if(model.equals("contactsId")){
+                    value = String.valueOf(aClass.getMethod("getContactsName").invoke(tasKVo)).equals("null")?"":String.valueOf(aClass.getMethod("getContactsName").invoke(tasKVo));
+                }
+                else if(model.equals("phone")){
+                    value = String.valueOf(aClass.getMethod("getContactsPhone").invoke(tasKVo)).equals("null")?"":String.valueOf(aClass.getMethod("getContactsPhone").invoke(tasKVo));
+                }
                 item.add(value);
             }
             dataList.add(item);
@@ -816,7 +822,7 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
         taskMapper.update(null,luw);
         TaskLog taskLog = new TaskLog();
         taskLog.setUserId(user.getId()).setTaskId(taskDto.getId()).setUserName(user.getName())
-                .setContent("修改任务状态").setModTime(LocalDateTime.now());
+                .setContent("修改任务状态");
         taskLogMapper.insert(taskLog);
         return msg;
     }

+ 5 - 5
fhKeeper/formulahousekeeper/management-crm/src/main/resources/mapper/TaskMapper.xml

@@ -62,16 +62,16 @@
         <result column="repeat_type" property="repeatType" />
         <result column="repeat_end_never" property="repeatEndNever" />
         <result column="repeat_end_count" property="repeatEndCount" />
-        <result column="repeat_end_date" property="repeatEndDate" jdbcType="DATE" javaType="java.time.LocalDate" />
+        <result column="repeat_end_date" property="repeatEndDate"  />
         <result column="repeat_design_day" property="repeatDesignDay" />
         <result column="repeat_design_sameday" property="repeatDesignSameday" />
         <result column="task_desc" property="taskDesc" />
         <result column="creater_id" property="createrId" />
         <result column="creater_name" property="createrName" />
-        <result column="create_date" property="createDate" jdbcType="DATE" javaType="java.time.LocalDate" />
-        <result column="end_date" property="endDate" jdbcType="DATE" javaType="java.time.LocalDate" />
-        <result column="start_date" property="startDate" jdbcType="DATE" javaType="java.time.LocalDate" />
-        <result column="finish_date" property="finishDate" jdbcType="DATE" javaType="java.time.LocalDate" />
+        <result column="create_date" property="createDate"  />
+        <result column="end_date" property="endDate" />
+        <result column="start_date" property="startDate" />
+        <result column="finish_date" property="finishDate" />
         <result column="is_delete" property="isDelete" />
         <result column="plate1" property="plate1" />
         <result column="plate2" property="plate2" />

+ 85 - 123
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectApprovalController.java

@@ -1,11 +1,16 @@
 package com.management.platform.controller;
 
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.google.gson.JsonObject;
 import com.management.platform.entity.*;
 import com.management.platform.mapper.ProjectMapper;
 import com.management.platform.mapper.UserMapper;
 import com.management.platform.service.*;
+import com.management.platform.service.impl.WxCorpInfoServiceImpl;
 import com.management.platform.util.HttpRespMsg;
 import org.springframework.beans.BeanUtils;
 import org.springframework.transaction.annotation.Transactional;
@@ -21,9 +26,8 @@ import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -57,19 +61,11 @@ public class ProjectApprovalController {
     @Resource
     private ProjectApprovalCheckService projectApprovalCheckService;
     @Resource
-    private ProjectService projectService;
-    @Resource
-    private ProjectBasecostService projectBasecostService;
-    @Resource
-    private ProjectAuditorService projectAuditorService;
-    @Resource
-    private ParticipationService participationService;
-    @Resource
-    private SysFunctionService sysFunctionService;
-    @Resource
     private ProjectApprovalLogService projectApprovalLogService;
     @Resource
-    private ReportService reportService;
+    private WxCorpInfoService wxCorpInfoService;
+    @Resource
+    private WxCorpTemplateService wxCorpTemplateService;
 
     /**
      * 分页获取项目列表
@@ -84,8 +80,9 @@ public class ProjectApprovalController {
 
     @RequestMapping("/editProjectApproval")
     @Transactional(rollbackFor = Exception.class)
-    public HttpRespMsg editProjectApproval(@RequestBody ProjectApproval projectApproval) {
+    public HttpRespMsg editProjectApproval(@RequestBody ProjectApproval projectApproval) throws Exception {
         HttpRespMsg msg=new HttpRespMsg();
+        String[] arr=new String[]{"正常","紧急","重要","重要且紧急","低风险","中风险","高风险"};
         User user = userMapper.selectById(request.getHeader("token"));
         Integer companyId = user.getCompanyId();
         List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getCompanyId, companyId));
@@ -158,6 +155,78 @@ public class ProjectApprovalController {
             }
             if(projectApprovalCheckList.size()>0){
                 projectApprovalCheckService.saveOrUpdateBatch(projectApprovalCheckList);
+                //更新审核人 发送到企业微信完成审核动作
+                String detail = wxCorpInfoService.getTemplateDetail(request, 0);
+                if(detail!=null&&!StringUtils.isEmpty(detail)){
+                    DateTimeFormatter df=DateTimeFormatter.ofPattern("yyyy-MM-dd");
+                    JSONObject resultOb = JSONObject.parseObject(detail);
+                    JSONObject template_content = resultOb.getJSONObject("template_content");
+                    JSONArray controls = template_content.getJSONArray("controls");
+                    Map<String,Object> templateMap=new HashMap<>();
+                    WxCorpTemplate template = wxCorpTemplateService.getById(companyId);
+                    JSONObject requestData=new JSONObject();
+                    requestData.put("template_id",template.getTemplateId());
+                    requestData.put("creator_userid",user.getCorpwxUserid());
+                    //审核模式  0-通过接口指定审批人、抄送人(此时approver、notifyer等参数可用);1-使用此模板在管理后台设置的审批流程(需要保证审批流程中没有“申请人自选”节点),支持条件审批
+                    requestData.put("use_template_approver",1);
+                    JSONObject apply_data=new JSONObject();
+                    JSONArray contents=new JSONArray();
+                    for (int i = 0; i < controls.size(); i++) {
+                        JSONObject item = controls.getJSONObject(i);
+                        JSONObject property = item.getJSONObject("property");
+                        //控件id指定到指定控件
+                        String templateId = property.getString("id");
+                        //控件名称 这里为了统一工时管家格式 限制企业需要用到我们提供的名称(项目编号 项目名称 项目分类 项目类型 项目经理 级别 合同金额 计划开始日期 计划结束日期)
+                        String title = property.getString("title");
+                        //控件类型 在这里统一用Text  Text-文本;Textarea-多行文本;Number-数字;Money-金额;Date-日期/日期+时间;Selector-单选/多选;Contact-成员/部门;Tips-说明文字;File-附件;Table-明细;Attendance-假勤控件;Vacation-请假控件;Location-位置;RelatedApproval-关联审批单;Formula-公式;DateRange-时长;BankAccount-收款账户
+                        String control = property.getString("control");
+                        //是否必填
+                        String require = property.getString("require");
+                        //是否打印
+                        String un_print = property.getString("un_print");
+                        JSONObject content=new JSONObject();
+                        content.put("control",control);
+                        content.put("id",templateId);
+                        JSONObject value=new JSONObject();
+                        switch (title){
+                            case "项目编号":
+                                value.put("text",projectApproval.getProjectCode());
+                                break;
+                            case "项目名称":
+                                value.put("text",projectApproval.getProjectName());
+                                break;
+                            case "项目分类":
+                                value.put("text",projectApproval.getCategoryName());
+                                break;
+                            case "项目类型":
+                                value.put("text",projectApproval.getIsPublic()==0?"正式项目":"非项目");
+                                break;
+                            case "项目经理":
+                                value.put("text",projectApproval.getInchargerName());
+                                break;
+                            case "级别":
+                                value.put("text",arr[projectApproval.getLevel()-1]);
+                                break;
+                            case "合同金额":
+                                value.put("text",projectApproval.getContractAmount());
+                                break;
+                            case "计划开始日期":
+                                value.put("text",df.format(projectApproval.getPlanStartDate()));
+                                break;
+                            case "计划结束日期":
+                                value.put("text",df.format(projectApproval.getPlanEndDate()));
+                                break;
+                        }
+                        content.put("value",value);
+                        contents.add(content);
+                    }
+                    apply_data.put("contents",contents);
+                    requestData.put("apply_data",apply_data);
+                    System.out.println("===============>发送到企业微信的数据"+requestData);
+//                    wxCorpInfoService.applyEvent(request,requestData);
+                }else {
+                    throw  new Exception("企业暂未同步服务商审批模板,推送企业微信审批失败,请联系服务商!");
+                }
             }
         }
         //新增操作记录数据
@@ -220,114 +289,7 @@ public class ProjectApprovalController {
     @RequestMapping("/check")
     @Transactional(rollbackFor = Exception.class)
     public HttpRespMsg check(Integer id,Integer checkType,Integer revokeType){
-        HttpRespMsg msg=new HttpRespMsg();
-        User user = userMapper.selectById(request.getHeader("token"));
-        ProjectApproval projectApproval = projectApprovalService.getById(id);
-        List<ProjectApprovalCheck> projectApprovalChecks = projectApprovalCheckService.list(new LambdaQueryWrapper<ProjectApprovalCheck>().eq(ProjectApprovalCheck::getProjectApprovalId, id));
-        Optional<ProjectApprovalCheck> first = projectApprovalChecks.stream().filter(p -> p.getUserId().equals(user.getId())&&p.getStatus()==0).findFirst();
-//        boolean hasAllPriviledge = sysFunctionService.hasPriviledge(user.getRoleId(), "管理全部立项申请");
-//        boolean hasCheckPriviledge = sysFunctionService.hasPriviledge(user.getRoleId(), "审核立项申请");
-        if(checkType!=3){
-            if(projectApprovalChecks.size()>0){
-                if(!first.isPresent()){
-                    msg.setError("审核人验证失败,请按照审核人顺序审核");
-                    return msg;
-                }
-            }
-        }
-        ProjectApprovalLog projectApprovalLog=new ProjectApprovalLog();
-        switch (checkType){
-            /*审核通过*/
-            case 1:
-                ProjectApprovalCheck projectApprovalCheck = first.get();
-                projectApprovalCheck.setStatus(1);
-                projectApprovalCheckService.updateById(projectApprovalCheck);
-                //检查剩余的数据
-                List<ProjectApprovalCheck> approvalChecks = projectApprovalChecks.stream().filter(p -> !p.getId().equals(first.get().getId())).collect(Collectors.toList());
-                boolean b = approvalChecks.stream().anyMatch(a -> a.getStatus() != 1);
-                if(!b){
-                    projectApproval.setStatus(1);
-                    projectApprovalService.updateById(projectApproval);
-                    //立项审核通过后创建项目数据
-                    Project project=new Project();
-                    BeanUtils.copyProperties(projectApproval,project);
-                    project.setId(null);
-                    project.setCreateDate(LocalDate.now());
-                    List<ProjectApprovalBasecost> projectApprovalBasecostList = projectApprovalBasecostService.list(new LambdaQueryWrapper<ProjectApprovalBasecost>().eq(ProjectApprovalBasecost::getProjectApprovalId, id));
-                    List<ParticipationApproval> participationApprovalList = participationApprovalService.list(new LambdaQueryWrapper<ParticipationApproval>().eq(ParticipationApproval::getProjectApprovalId, id));
-                    List<ProjectApprovalAuditor> projectApprovalAuditorList = projectApprovalAuditorService.list(new LambdaQueryWrapper<ProjectApprovalAuditor>().eq(ProjectApprovalAuditor::getProjectApprovalId, id));
-                    projectService.save(project);
-                    List<ProjectBasecost> projectBasecostList=new ArrayList<>();
-                    List<Participation> participationList=new ArrayList<>();
-                    List<ProjectAuditor> projectAuditorList=new ArrayList<>();
-                    projectApprovalBasecostList.forEach(p->{
-                        ProjectBasecost projectBasecost=new ProjectBasecost();
-                        BeanUtils.copyProperties(p,projectBasecost);
-                        projectBasecost.setId(null);
-                        projectBasecost.setProjectId(project.getId());
-                        projectBasecostList.add(projectBasecost);
-                    });
-                    participationApprovalList.forEach(p->{
-                        Participation participation=new Participation();
-                        BeanUtils.copyProperties(p,participation);
-                        participation.setId(null);
-                        participation.setProjectId(project.getId());
-                        participationList.add(participation);
-                    });
-                    projectApprovalAuditorList.forEach(p->{
-                        ProjectAuditor projectAuditor=new ProjectAuditor();
-                        BeanUtils.copyProperties(p,projectAuditor);
-                        projectAuditor.setId(null);
-                        projectAuditor.setProjectId(project.getId());
-                        projectAuditorList.add(projectAuditor);
-                    });
-                    projectBasecostService.saveBatch(projectBasecostList);
-                    participationService.saveBatch(participationList);
-                    projectAuditorService.saveBatch(projectAuditorList);
-                    //新增操作记录数据
-                    projectApprovalLog.setCreateTime(LocalDateTime.now());
-                    projectApprovalLog.setProjectApprovalId(projectApproval.getId());
-                    //通过
-                    projectApprovalLog.setType(2);
-                    projectApprovalLogService.save(projectApprovalLog);
-                }
-                break;
-            /*驳回*/
-            case 2:
-                projectApproval.setStatus(2);
-                projectApprovalService.updateById(projectApproval);
-                //新增操作记录数据
-                projectApprovalLog.setCreateTime(LocalDateTime.now());
-                projectApprovalLog.setProjectApprovalId(projectApproval.getId());
-                //驳回
-                projectApprovalLog.setType(3);
-                projectApprovalLogService.save(projectApprovalLog);
-                break;
-            /*撤销*/
-            case 3:
-                Project project = projectService.getOne(new LambdaQueryWrapper<Project>().eq(Project::getApproveId,projectApproval.getId()));
-                if(project!=null){
-                    int count = reportService.count(new LambdaQueryWrapper<Report>().eq(Report::getProjectId, project.getId()));
-                    if(count>0){
-                        msg.setError("已存在填报数据无法撤销立项");
-                        return msg;
-                    }
-                    projectAuditorService.remove(new LambdaQueryWrapper<ProjectAuditor>().eq(ProjectAuditor::getProjectId,project.getId()));
-                    projectBasecostService.remove(new LambdaQueryWrapper<ProjectBasecost>().eq(ProjectBasecost::getProjectId,project.getId()));
-                    participationService.remove(new LambdaQueryWrapper<Participation>().eq(Participation::getProjectId,project.getId()));
-                    project.deleteById(project.getId());
-                }
-                projectApproval.setStatus(3);
-                projectApprovalService.updateById(projectApproval);
-                //新增操作记录数据
-                projectApprovalLog.setCreateTime(LocalDateTime.now());
-                projectApprovalLog.setProjectApprovalId(projectApproval.getId());
-                //驳回
-                projectApprovalLog.setType(4);
-                projectApprovalLogService.save(projectApprovalLog);
-                break;
-        }
-        return msg;
+        return projectApprovalService.check(id,checkType,revokeType);
     }
 
     @RequestMapping("/importData")

+ 4 - 4
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectController.java

@@ -1470,14 +1470,14 @@ public class ProjectController {
 
     //依斯倍定制 分组耗用进度表
     @RequestMapping("/groupExpendProcessList")
-    public HttpRespMsg groupExpendProcessList(String startDate,String endDate,Integer pageIndex,Integer pageSize){
-        return projectService.groupExpendProcessList(startDate,endDate,pageIndex,pageSize);
+    public HttpRespMsg groupExpendProcessList(String startDate,String endDate,Integer projectId,Integer pageIndex,Integer pageSize){
+        return projectService.groupExpendProcessList(startDate,endDate,projectId,pageIndex,pageSize);
     }
 
     //依斯倍定制 导出分组耗用进度表
     @RequestMapping("/exportGroupExpendProcessList")
-    public HttpRespMsg exportGroupExpendProcessList(String startDate,String endDate){
-        return projectService.exportGroupExpendProcessList(startDate,endDate);
+    public HttpRespMsg exportGroupExpendProcessList(String startDate,String endDate,Integer projectId){
+        return projectService.exportGroupExpendProcessList(startDate,endDate,projectId);
     }
 
     //依斯倍定制 项目耗用进度表

+ 44 - 38
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java

@@ -899,18 +899,7 @@ public class ReportController {
                             if (comTimeType.getReportAuditType() == 3) {
                                 report.setAuditorSetting(auditorSettingList.get(i));
                             }
-                            if (auditWorkflowList.size() == 0) {
-                                //没有自定义审核流,默认的直接是项目负责人审核
-                                report.setIsDeptAudit(0);
-                                report.setIsFinalAudit(1);
-                            } else {
-                                //取第一个审核节点
-                                AuditWorkflowTimeSetting firstNode = auditWorkflowList.get(0);
-                                report.setIsFinalAudit(auditWorkflowList.size() > 1?0:1);
-                                report.setIsDeptAudit(firstNode.getIsDeptAudit());
-                                report.setAuditDeptid(firstNode.getAuditDeptId());
-                                report.setAuditDeptManagerid(firstNode.getAuditDeptId() != null?allDeptList.stream().filter(d->d.getDepartmentId().equals(firstNode.getAuditDeptId())).findFirst().get().getManagerId(): null);
-                            }
+                            setReportWorkflowAuditor(auditWorkflowList, allDeptList, report,comTimeType);
                             if (taskId != null && taskId[i] != null && taskId[i] != 0) {
                                 report.setTaskId(taskId[i]);
                             }
@@ -966,18 +955,7 @@ public class ReportController {
                                 if (comTimeType.getReportAuditType() == 3) {
                                     report.setAuditorSetting(auditorSettingList.get(i));
                                 }
-                                if (auditWorkflowList.size() == 0) {
-                                    //没有自定义审核流,默认的直接是项目负责人审核
-                                    report.setIsDeptAudit(0);
-                                    report.setIsFinalAudit(1);
-                                } else {
-                                    //取第一个审核节点
-                                    AuditWorkflowTimeSetting firstNode = auditWorkflowList.get(0);
-                                    report.setIsFinalAudit(auditWorkflowList.size() > 1?0:1);
-                                    report.setIsDeptAudit(firstNode.getIsDeptAudit());
-                                    report.setAuditDeptid(firstNode.getAuditDeptId());
-                                    report.setAuditDeptManagerid(firstNode.getAuditDeptId() != null?allDeptList.stream().filter(d->d.getDepartmentId().equals(firstNode.getAuditDeptId())).findFirst().get().getManagerId(): null);
-                                }
+                                setReportWorkflowAuditor(auditWorkflowList, allDeptList, report,comTimeType);
                                 if (taskId != null && taskId[i] != null && taskId[i] != 0) {
                                     report.setTaskId(taskId[i]);
                                 }
@@ -995,7 +973,6 @@ public class ReportController {
                                 } else {
                                     fillReportHours(report, hourCost, workingTime==null?null:workingTime[i], timeType==null?null:timeType[i], null, null, sdf, comTimeType, excludeTimeList);
                                 }
-
                                 fillReportProgress(report, professionProgress[i]);
                                 reportList.add(report);
                             }
@@ -1035,18 +1012,7 @@ public class ReportController {
                         if (comTimeType.getReportAuditType() == 3) {
                             report.setAuditorSetting(auditorSettingList.get(i));
                         }
-                        if (auditWorkflowList.size() == 0) {
-                            //没有自定义审核流,默认的直接是项目负责人审核
-                            report.setIsDeptAudit(0);
-                            report.setIsFinalAudit(1);
-                        } else {
-                            //取第一个审核节点
-                            AuditWorkflowTimeSetting firstNode = auditWorkflowList.get(0);
-                            report.setIsFinalAudit(auditWorkflowList.size() > 1?0:1);
-                            report.setIsDeptAudit(firstNode.getIsDeptAudit());
-                            report.setAuditDeptid(firstNode.getAuditDeptId());
-                            report.setAuditDeptManagerid(firstNode.getAuditDeptId() != null?allDeptList.stream().filter(d->d.getDepartmentId().equals(firstNode.getAuditDeptId())).findFirst().get().getManagerId(): null);
-                        }
+                        setReportWorkflowAuditor(auditWorkflowList, allDeptList, report,comTimeType);
                         if (taskId != null && taskId[i] != null && taskId[i] != 0) {
                             report.setTaskId(taskId[i]);
                         }
@@ -1821,6 +1787,40 @@ public class ReportController {
         }
     }
 
+    private void setReportWorkflowAuditor(List<AuditWorkflowTimeSetting> auditWorkflowList, List<Department> allDeptList, Report report, TimeType comTimeType) {
+        if (auditWorkflowList.size() == 0) {
+            //没有自定义审核流,默认的直接是项目负责人审核
+            report.setIsDeptAudit(0);
+            report.setIsFinalAudit(1);
+        } else {
+            //取第一个审核节点
+            AuditWorkflowTimeSetting firstNode = auditWorkflowList.get(0);
+            report.setIsFinalAudit(auditWorkflowList.size() > 1?0:1);
+            report.setIsDeptAudit(firstNode.getIsDeptAudit());
+            report.setAuditDeptid(firstNode.getAuditDeptId());
+            if (firstNode.getIsDeptAudit() == 1) {
+                Department curDept = allDeptList.stream()
+                        .filter(ad->ad.getDepartmentId().equals(firstNode.getAuditDeptId())).findFirst().get();
+                String curDeptManagerId = curDept.getManagerId();
+                //启用了本部门负责人的日报由上级部门主要负责人审核
+                if (comTimeType.getReportAuditFlowEnableSuperDeptAduit() == 1 && curDeptManagerId.equals(report.getCreatorId())) {
+                    //当前提交的人是这个部门的主要负责人,那么要取该部门的上一级部门的主要负责人来审核
+                    Integer parentDeptId = curDept.getSuperiorId();
+                    if (parentDeptId == null) {
+                        //没有上级部门,直接取当前部门的负责人
+                        report.setAuditDeptManagerid(curDeptManagerId);
+                    } else {
+//                        report.setAuditDeptid(parentDeptId);
+                        report.setAuditDeptManagerid(allDeptList.stream()
+                                .filter(ad->ad.getDepartmentId().equals(parentDeptId)).findFirst().get().getManagerId());
+                    }
+                } else {
+                    report.setAuditDeptManagerid(curDeptManagerId);
+                }
+            }
+        }
+    }
+
     /**
      * 删除报告
      * id 要删除的报告的id
@@ -1932,7 +1932,13 @@ public class ReportController {
 
     @RequestMapping("/batchApproveReport")
     public HttpRespMsg batchApproveReport(@RequestParam String ids, Integer isDepartment, HttpServletRequest request,String evaluate) {
-        return reportService.batchApproveReport(ids, isDepartment, request,evaluate);
+        HttpRespMsg msg = new HttpRespMsg();
+        try {
+            msg = reportService.batchApproveReport(ids, isDepartment, request,evaluate);
+        } catch (Exception e) {
+            msg.setError("批量审核失败:"+e.getMessage());
+        }
+        return msg;
     }
 
     @RequestMapping("/batchApproveByDate")

+ 82 - 14
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserWithBeisenController.java

@@ -68,13 +68,9 @@ public class UserWithBeisenController {
             httpRespMsg.setError("北森基础数据配置未完成,请联系服务商完成配置");
             return httpRespMsg;
         }
-//        if(companyId==5978){
-//            beisenConfig.setAppKey("70FD83474FB946E5A6A122BB2989E8D9");
-//            beisenConfig.setAppSecret("F494856D0BCC49D18C63429D4F2CB42EDE9480D5C075449E9C97E7AEA5C7D9E1");
-//        }
         List<UserWithBeisen> allBeisenList = userWithBeisenService.list(new LambdaQueryWrapper<UserWithBeisen>().eq(UserWithBeisen::getCompanyId, companyId));
         List<UserWithBeisen> userWithBeisenList=new ArrayList<>();
-        List<JSONArray> byTimeWindow = BeiSenUtils.getByTimeWindow("",startTime,stopTime,beisenConfig.getAppKey(),beisenConfig.getAppSecret());
+        List<JSONArray> byTimeWindow = BeiSenUtils.getByTimeWindow("",startTime,stopTime,companyId,beisenConfig.getAppKey(),beisenConfig.getAppSecret());
         for (JSONArray array : byTimeWindow) {
             for (int i = 0; i < array.size(); i++) {
                 UserWithBeisen userWithBeisen=new UserWithBeisen();
@@ -140,14 +136,16 @@ public class UserWithBeisenController {
             return msg;
         }
         //todo 获取到指定日期的考勤数据
-        JSONArray attendanceStatistics = BeiSenUtils.getAttendanceStatistics(startDate, endDate, beisenConfig.getAppKey(), beisenConfig.getAppSecret(), 1, 100);
+        JSONArray attendanceStatistics=new JSONArray();
         //todo 获取到指定日期的加班数据
         List<LocalDate> workDaysListInRange = WorkDayCalculateUtils.getWorkDaysListInRange(startDate, endDate, 1);
         JSONArray allOverTimeList=new JSONArray();
         List<UserFvTime> userFvTimeList=new ArrayList<>();
         for (LocalDate localDate : workDaysListInRange) {
+            JSONArray statisticList = BeiSenUtils.getAttendanceStatistics(df.format(localDate), df.format(localDate), beisenConfig.getAppKey(), beisenConfig.getAppSecret(), 1, 100);
             JSONArray overTimeList = BeiSenUtils.getOverTimeList(df.format(localDate), beisenConfig.getAppKey(), beisenConfig.getAppSecret(), 1, 100);
             allOverTimeList.addAll(overTimeList);
+            attendanceStatistics.addAll(statisticList);
         }
         for (LocalDate localDate : workDaysListInRange) {
             Stream<JSONObject> swipingCardsStream = attendanceStatistics.stream().map(item -> (JSONObject) item);
@@ -174,14 +172,16 @@ public class UserWithBeisenController {
                     Double workTime=8.0;
                     Stream<JSONObject> overTimeStream = allOverTimeList.stream().map(elment -> (JSONObject) elment);
                     Optional<UserWithBeisen> beisen = userWithBeisenList.stream().filter(u -> u.getJobNumber() != null && u.getJobNumber().equals(first.get().getJobNumber())).findFirst();
-                    List<JSONObject> overTimeList = overTimeStream.filter(a -> a.getString("StaffId").equals(beisen.get().getUserId())
-                            && a.getIntValue("ApproveStatus") == 2).collect(Collectors.toList());
-                    if(overTimeList.size()>0){
-                        double actualOverTimeDuration = overTimeList.stream().mapToDouble(i -> i.getDouble("ActualOverTimeDuration")).sum();
-                        if(workDay){
-                            workTime= workTime+actualOverTimeDuration;
-                        }else {
-                            workTime= actualOverTimeDuration;
+                    if(beisen.isPresent()){
+                        List<JSONObject> overTimeList = overTimeStream.filter(a -> a.getString("StaffId").equals(beisen.get().getUserId())
+                                && a.getIntValue("ApproveStatus") == 2).collect(Collectors.toList());
+                        if(overTimeList.size()>0){
+                            double actualOverTimeDuration = overTimeList.stream().mapToDouble(i -> i.getDouble("ActualOverTimeDuration")).sum();
+                            if(workDay){
+                                workTime= workTime+actualOverTimeDuration;
+                            }else {
+                                workTime= actualOverTimeDuration;
+                            }
                         }
                     }
                     UserFvTime userFvTime=new UserFvTime();
@@ -207,5 +207,73 @@ public class UserWithBeisenController {
         return msg;
     }
 
+
+    @RequestMapping("/getAttendanceStatisticWithUser")
+    public HttpRespMsg getAttendanceStatisticWithUser(String createDate){
+        HttpRespMsg msg=new HttpRespMsg();
+        DateTimeFormatter df=DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        DateTimeFormatter df1=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        DateTimeFormatter df2=DateTimeFormatter.ofPattern("HH:mm");
+        User user = userMapper.selectById(request.getHeader("token"));
+        Integer companyId = user.getCompanyId();
+        TimeType timeType = timeTypeMapper.selectById(companyId);
+        List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getCompanyId, companyId));
+        List<UserWithBeisen> userWithBeisenList = userWithBeisenService.list(new LambdaQueryWrapper<UserWithBeisen>().eq(UserWithBeisen::getCompanyId, companyId));
+        BeisenConfig beisenConfig = beisenConfigMapper.selectById(companyId);
+        if(beisenConfig==null){
+            msg.setError("北森基础数据配置未完成,请联系服务商完成配置");
+            return msg;
+        }
+        //todo 获取到指定日期的考勤数据
+        //todo 获取到指定日期的加班数据
+        Optional<UserWithBeisen> withBeisen = userWithBeisenList.stream().filter(u ->u.getJobNumber()!=null&& u.getJobNumber().equals(user.getJobNumber())).findFirst();
+        if(!withBeisen.isPresent()){
+            msg.setError("当前员工在北森系统中不存在,请完成录入员工信息");
+            return msg;
+        }
+        JSONObject item = BeiSenUtils.getAttendanceStatisticWithUser(createDate,withBeisen.get().getUserId(), beisenConfig.getAppKey(), beisenConfig.getAppSecret());
+        JSONArray allOverTimeList = BeiSenUtils.getScheduledOverTimeRangeList(createDate,createDate,withBeisen.get().getUserId(), beisenConfig.getAppKey(), beisenConfig.getAppSecret());
+        //获取当前数据下的人员工号对应到工时管家
+        String cardNumber = item.getString("staffId");
+        Optional<User> first = userList.stream().filter(f -> f.getJobNumber().equals(cardNumber)).findFirst();
+        //todo: 获取早晚打卡时间
+        String firstCard = item.getString("firstCard");
+        String lastCard = item.getString("lastCard");
+        //获取最晚下班时间
+        if(first.isPresent()){
+            boolean workDay = WorkDayCalculateUtils.isWorkDay(LocalDate.parse(createDate,df));
+            //todo:针对景昱 工作日默认以8小时工作制度加上加班时长 非工作日以加班时长为准
+            Double workTime=8.0;
+            Stream<JSONObject> overTimeStream = allOverTimeList.stream().map(elment -> (JSONObject) elment);
+            Optional<UserWithBeisen> beisen = userWithBeisenList.stream().filter(u -> u.getJobNumber() != null && u.getJobNumber().equals(first.get().getJobNumber())).findFirst();
+            if(beisen.isPresent()){
+                List<JSONObject> overTimeList = overTimeStream.filter(a -> a.getString("StaffId").equals(beisen.get().getUserId())
+                        && a.getIntValue("ApproveStatus") == 2).collect(Collectors.toList());
+                if(overTimeList.size()>0){
+                    double actualOverTimeDuration = overTimeList.stream().mapToDouble(i -> i.getDouble("ActualOverTimeDuration")).sum();
+                    if(workDay){
+                        workTime= workTime+actualOverTimeDuration;
+                    }else {
+                        workTime= actualOverTimeDuration;
+                    }
+                }
+            }
+            UserFvTime userFvTime=new UserFvTime();
+            userFvTime.setWorkDate(LocalDate.parse(createDate,df));
+            userFvTime.setStartTime(!StringUtils.isEmpty(firstCard)?firstCard:"08:30");
+            userFvTime.setEndTime(!StringUtils.isEmpty(lastCard)?lastCard:"17:30");
+            userFvTime.setUserId(first.get().getId());
+            userFvTime.setCompanyId(companyId);
+            userFvTime.setWorkHours(workTime.floatValue());
+            UserFvTime one = userFvTimeService.getOne(new LambdaQueryWrapper<UserFvTime>().eq(UserFvTime::getCompanyId, companyId).eq(UserFvTime::getUserId, first.get().getId()).eq(UserFvTime::getWorkDate, LocalDate.parse(createDate,df)));
+            if(one!=null){
+                userFvTime.setId(one.getId());
+            }
+            userFvTimeService.saveOrUpdate(userFvTime);
+            msg.setData(userFvTime);
+        }
+        return msg;
+    }
+
 }
 

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/WxCorpTemplateController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-03-25
+ */
+@RestController
+@RequestMapping("/wx-corp-template")
+public class WxCorpTemplateController {
+
+}
+

+ 18 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/TimeType.java

@@ -17,7 +17,7 @@ import lombok.experimental.Accessors;
  * </p>
  *
  * @author Seyason
- * @since 2024-03-23
+ * @since 2024-03-26
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -530,6 +530,12 @@ public class TimeType extends Model<TimeType> {
     @TableField("custom_degree_multiple")
     private Boolean customDegreeMultiple;
 
+    /**
+     * 任务分组是否必填
+     */
+    @TableField("task_group_required")
+    private Integer taskGroupRequired;
+
     /**
      * 任务是否必填 0-否 1-是
      */
@@ -548,6 +554,17 @@ public class TimeType extends Model<TimeType> {
     @TableField("hide_task")
     private Integer hideTask;
 
+    /**
+     * 项目隐藏子项目功能按钮
+     */
+    @TableField("hide_subproject")
+    private Integer hideSubproject;
+
+    /**
+     * 开启日报审批流的本部门负责人由上级部门负责人审核
+     */
+    @TableField("report_audit_flow_enable_super_dept_aduit")
+    private Integer reportAuditFlowEnableSuperDeptAduit;
 
     @TableField(exist = false)
     private List<User> userList;
@@ -556,7 +573,6 @@ public class TimeType extends Model<TimeType> {
     @TableField(exist = false)
     private Integer saasSyncContact;
 
-
     @Override
     protected Serializable pkVal() {
         return this.companyId;

+ 47 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/WxCorpTemplate.java

@@ -0,0 +1,47 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-03-25
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class WxCorpTemplate extends Model<WxCorpTemplate> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId("company_id")
+    private Integer companyId;
+
+    /**
+     * 审批模板id
+     */
+    @TableField("template_id")
+    private String templateId;
+
+    /**
+     * 0-立项审批
+     */
+    @TableField("type")
+    private Integer type;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.companyId;
+    }
+
+}

+ 16 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/WxCorpTemplateMapper.java

@@ -0,0 +1,16 @@
+package com.management.platform.mapper;
+
+import com.management.platform.entity.WxCorpTemplate;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-03-25
+ */
+public interface WxCorpTemplateMapper extends BaseMapper<WxCorpTemplate> {
+
+}

+ 2 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ProjectApprovalService.java

@@ -23,4 +23,6 @@ public interface ProjectApprovalService extends IService<ProjectApproval> {
     HttpRespMsg importData(MultipartFile multipartFile);
 
     HttpRespMsg exportData(String keyword, Integer searchField, String statuses, Integer category, Integer viewId);
+
+    HttpRespMsg check(Integer id, Integer checkType, Integer revokeType);
 }

+ 2 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ProjectService.java

@@ -279,9 +279,9 @@ public interface ProjectService extends IService<Project> {
 
     HttpRespMsg exportUserProjectProcessList(Integer deptId, String userId, Integer projectId);
 
-    HttpRespMsg groupExpendProcessList(String startDate, String endDate,Integer pageIndex,Integer pageSize);
+    HttpRespMsg groupExpendProcessList(String startDate, String endDate,Integer projectId,Integer pageIndex,Integer pageSize);
 
-    HttpRespMsg exportGroupExpendProcessList(String startDate, String endDate);
+    HttpRespMsg exportGroupExpendProcessList(String startDate, String endDate,Integer projectId);
 
     HttpRespMsg projectExpendProcessList(String startDate,String endDate,Integer projectId, Integer categoryId, String userId, Integer pageIndex, Integer pageSize);
 

+ 1 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ReportService.java

@@ -51,7 +51,7 @@ public interface ReportService extends IService<Report> {
 
     HttpRespMsg getMembList(String date, HttpServletRequest request);
 
-    HttpRespMsg batchApproveReport(String ids, Integer isDepartment, HttpServletRequest request,String evaluate);
+    HttpRespMsg batchApproveReport(String ids, Integer isDepartment, HttpServletRequest request,String evaluate) throws Exception;
     HttpRespMsg batchDenyReport(String ids, Integer isDepartment, String reason, HttpServletRequest request);
 
     HttpRespMsg cancelReport(String userId, String reportIds, HttpServletRequest request);

+ 6 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/WxCorpInfoService.java

@@ -76,4 +76,10 @@ public interface WxCorpInfoService extends IService<WxCorpInfo> {
     List<Map<String, String>> getActiveInfoByUser(HttpServletRequest request) throws Exception;
 
     HttpRespMsg batchTransferLicense(HttpServletRequest request,String handoverId, String takeoverId) throws Exception;
+
+    public void copyTemplate(HttpServletRequest request,Integer templateType) throws Exception;
+
+    public String getTemplateDetail(HttpServletRequest request,Integer templateType) throws Exception;
+
+    public void applyEvent(HttpServletRequest request,JSONObject data) throws Exception;
 }

+ 16 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/WxCorpTemplateService.java

@@ -0,0 +1,16 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.WxCorpTemplate;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-03-25
+ */
+public interface WxCorpTemplateService extends IService<WxCorpTemplate> {
+
+}

+ 130 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectApprovalServiceImpl.java

@@ -16,6 +16,7 @@ import org.apache.poi.xssf.usermodel.XSSFCell;
 import org.apache.poi.xssf.usermodel.XSSFRow;
 import org.apache.poi.xssf.usermodel.XSSFSheet;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
@@ -29,6 +30,7 @@ import javax.servlet.http.HttpServletRequest;
 import java.io.*;
 import java.text.SimpleDateFormat;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.stream.Collectors;
@@ -69,11 +71,27 @@ public class ProjectApprovalServiceImpl extends ServiceImpl<ProjectApprovalMappe
     @Resource
     private ProjectApprovalAuditorMapper projectApprovalAuditorMapper;
     @Resource
+    private ProjectApprovalBasecostService projectApprovalBasecostService;
+    @Resource
     private ProjectApprovalAuditorService projectApprovalAuditorService;
     @Resource
     private ProjectMapper projectMapper;
     @Resource
     private ExcelExportService excelExportService;
+    @Resource
+    private ProjectService projectService;
+    @Resource
+    private ProjectApprovalService projectApprovalService;
+    @Resource
+    private ProjectBasecostService projectBasecostService;
+    @Resource
+    private ProjectAuditorService projectAuditorService;
+    @Resource
+    private ParticipationService participationService;
+    @Resource
+    private ProjectApprovalLogService projectApprovalLogService;
+    @Resource
+    private ReportService reportService;
     @Value(value = "${upload.path}")
     private String path;
 
@@ -654,4 +672,116 @@ public class ProjectApprovalServiceImpl extends ServiceImpl<ProjectApprovalMappe
         }
         return msg;
     }
+
+    @Override
+    public HttpRespMsg check(Integer id, Integer checkType, Integer revokeType) {
+        HttpRespMsg msg=new HttpRespMsg();
+        User user = userMapper.selectById(request.getHeader("token"));
+        ProjectApproval projectApproval = getById(id);
+        List<ProjectApprovalCheck> projectApprovalChecks = projectApprovalCheckService.list(new LambdaQueryWrapper<ProjectApprovalCheck>().eq(ProjectApprovalCheck::getProjectApprovalId, id));
+        Optional<ProjectApprovalCheck> first = projectApprovalChecks.stream().filter(p -> p.getUserId().equals(user.getId())&&p.getStatus()==0).findFirst();
+//        boolean hasAllPriviledge = sysFunctionService.hasPriviledge(user.getRoleId(), "管理全部立项申请");
+//        boolean hasCheckPriviledge = sysFunctionService.hasPriviledge(user.getRoleId(), "审核立项申请");
+        if(checkType!=3){
+            if(projectApprovalChecks.size()>0){
+                if(!first.isPresent()){
+                    msg.setError("审核人验证失败,请按照审核人顺序审核");
+                    return msg;
+                }
+            }
+        }
+        ProjectApprovalLog projectApprovalLog=new ProjectApprovalLog();
+        switch (checkType){
+            /*审核通过*/
+            case 1:
+                ProjectApprovalCheck projectApprovalCheck = first.get();
+                projectApprovalCheck.setStatus(1);
+                projectApprovalCheckService.updateById(projectApprovalCheck);
+                //检查剩余的数据
+                List<ProjectApprovalCheck> approvalChecks = projectApprovalChecks.stream().filter(p -> !p.getId().equals(first.get().getId())).collect(Collectors.toList());
+                boolean b = approvalChecks.stream().anyMatch(a -> a.getStatus() != 1);
+                if(!b){
+                    projectApproval.setStatus(1);
+                    updateById(projectApproval);
+                    //立项审核通过后创建项目数据
+                    Project project=new Project();
+                    BeanUtils.copyProperties(projectApproval,project);
+                    project.setId(null);
+                    project.setCreateDate(LocalDate.now());
+                    List<ProjectApprovalBasecost> projectApprovalBasecostList = projectApprovalBasecostService.list(new LambdaQueryWrapper<ProjectApprovalBasecost>().eq(ProjectApprovalBasecost::getProjectApprovalId, id));
+                    List<ParticipationApproval> participationApprovalList = participationApprovalService.list(new LambdaQueryWrapper<ParticipationApproval>().eq(ParticipationApproval::getProjectApprovalId, id));
+                    List<ProjectApprovalAuditor> projectApprovalAuditorList = projectApprovalAuditorService.list(new LambdaQueryWrapper<ProjectApprovalAuditor>().eq(ProjectApprovalAuditor::getProjectApprovalId, id));
+                    projectService.save(project);
+                    List<ProjectBasecost> projectBasecostList=new ArrayList<>();
+                    List<Participation> participationList=new ArrayList<>();
+                    List<ProjectAuditor> projectAuditorList=new ArrayList<>();
+                    projectApprovalBasecostList.forEach(p->{
+                        ProjectBasecost projectBasecost=new ProjectBasecost();
+                        BeanUtils.copyProperties(p,projectBasecost);
+                        projectBasecost.setId(null);
+                        projectBasecost.setProjectId(project.getId());
+                        projectBasecostList.add(projectBasecost);
+                    });
+                    participationApprovalList.forEach(p->{
+                        Participation participation=new Participation();
+                        BeanUtils.copyProperties(p,participation);
+                        participation.setId(null);
+                        participation.setProjectId(project.getId());
+                        participationList.add(participation);
+                    });
+                    projectApprovalAuditorList.forEach(p->{
+                        ProjectAuditor projectAuditor=new ProjectAuditor();
+                        BeanUtils.copyProperties(p,projectAuditor);
+                        projectAuditor.setId(null);
+                        projectAuditor.setProjectId(project.getId());
+                        projectAuditorList.add(projectAuditor);
+                    });
+                    projectBasecostService.saveBatch(projectBasecostList);
+                    participationService.saveBatch(participationList);
+                    projectAuditorService.saveBatch(projectAuditorList);
+                    //新增操作记录数据
+                    projectApprovalLog.setCreateTime(LocalDateTime.now());
+                    projectApprovalLog.setProjectApprovalId(projectApproval.getId());
+                    //通过
+                    projectApprovalLog.setType(2);
+                    projectApprovalLogService.save(projectApprovalLog);
+                }
+                break;
+            /*驳回*/
+            case 2:
+                projectApproval.setStatus(2);
+                projectApprovalService.updateById(projectApproval);
+                //新增操作记录数据
+                projectApprovalLog.setCreateTime(LocalDateTime.now());
+                projectApprovalLog.setProjectApprovalId(projectApproval.getId());
+                //驳回
+                projectApprovalLog.setType(3);
+                projectApprovalLogService.save(projectApprovalLog);
+                break;
+            /*撤销*/
+            case 3:
+                Project project = projectService.getOne(new LambdaQueryWrapper<Project>().eq(Project::getApproveId,projectApproval.getId()));
+                if(project!=null){
+                    int count = reportService.count(new LambdaQueryWrapper<Report>().eq(Report::getProjectId, project.getId()));
+                    if(count>0){
+                        msg.setError("已存在填报数据无法撤销立项");
+                        return msg;
+                    }
+                    projectAuditorService.remove(new LambdaQueryWrapper<ProjectAuditor>().eq(ProjectAuditor::getProjectId,project.getId()));
+                    projectBasecostService.remove(new LambdaQueryWrapper<ProjectBasecost>().eq(ProjectBasecost::getProjectId,project.getId()));
+                    participationService.remove(new LambdaQueryWrapper<Participation>().eq(Participation::getProjectId,project.getId()));
+                    project.deleteById(project.getId());
+                }
+                projectApproval.setStatus(3);
+                projectApprovalService.updateById(projectApproval);
+                //新增操作记录数据
+                projectApprovalLog.setCreateTime(LocalDateTime.now());
+                projectApprovalLog.setProjectApprovalId(projectApproval.getId());
+                //驳回
+                projectApprovalLog.setType(4);
+                projectApprovalLogService.save(projectApprovalLog);
+                break;
+        }
+        return msg;
+    }
 }

+ 58 - 11
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java

@@ -1664,6 +1664,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             List<Integer> deptIds=null;
             List<Department> departmentList = departmentMapper.selectList(new QueryWrapper<Department>().eq("manager_id", targetUser.getId()).eq("company_id", companyId));
             List<Department> allDepartmentList = departmentMapper.selectList(new QueryWrapper<Department>().eq("company_id", targetUser.getCompanyId()));
+            Department[] deptArray = allDepartmentList.toArray(new Department[0]);
             List<DepartmentOtherManager> departmentOtherManagerList = departmentOtherManagerMapper.selectList(new QueryWrapper<DepartmentOtherManager>().eq("other_manager_id", targetUser.getId()));
             List<SysRichFunction> functionAllList = sysFunctionMapper.getRoleFunctions(targetUser.getRoleId(), "查看全公司");
             List<SysRichFunction> functionDpartList = sysFunctionMapper.getRoleFunctions(targetUser.getRoleId(), "查看负责部门");
@@ -1888,16 +1889,27 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                                 membRowData.add("");
 
                             }
+                            Department dept = null;
+                            Department targetDept = new Department();
+                            if (membMap.get("deptId") != null) {
+                                targetDept.setDepartmentId(Integer.valueOf(membMap.get("deptId").toString()));
+                                int index = Arrays.binarySearch(deptArray, targetDept, Comparator.comparing(Department::getDepartmentId));
+                                if (index >= 0) {
+                                    dept = deptArray[index];
+                                }
+                            }
                             if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
                                 membRowData.add((String)("$userName="+membMap.get("corpwxUserId")+"$"));
                                 if(membMap.get("departmentName").equals("未分配")){
                                     membRowData.add("未分配");
                                 }else {
-                                    membRowData.add((String)("$departmentName="+membMap.get("corpwxDeptId")+"$"));
+                                    membRowData.add(departmentService.exportWxDepartment(dept,allDepartmentList));
+//                                    membRowData.add((String)("$departmentName="+membMap.get("corpwxDeptId")+"$"));
                                 }
                             }else {
                                 membRowData.add((String)membMap.get("name"));
-                                membRowData.add((String)membMap.get("departmentName"));
+                                membRowData.add(departmentService.getSupDepartment(dept,allDepartmentList));
+//                                membRowData.add((String)membMap.get("departmentName"));
                             }
                             String creatorId = (String)membMap.get("creatorId");
                             User us = userList.stream().filter(u->u.getId().equals(creatorId)).findFirst().get();
@@ -7871,6 +7883,8 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             double workTimeDouble = Double.parseDouble(map.get("workingTime").toString()) + leaveSum;
             BigDecimal workTimeBig = new BigDecimal(workTimeDouble);
             map.put("workingTime",workTimeBig.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
+            double overtimeHours = Double.parseDouble(map.get("overtimeHours").toString());
+            map.put("overtimeHours",overtimeHours + "h");
         }
         list.forEach(li->{
             double isPublic = (double) li.get("isPublic");
@@ -8025,8 +8039,11 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             }
         }
         List<Map<String, Object>> list = projectMapper.getUserWorkingTimeList(userId, user.getCompanyId(), startDate, endDate, projectId,null,null,null,deptIds);
-        //String[] string={"人员","部门","工号","普通项目工时","公共项目工时","请假时长","总工时","公共项目工时占比"};
-        String[] string={MessageUtils.message("entry.personnel"),MessageUtils.message("excel.department"),MessageUtils.message("entry.No"),MessageUtils.message("entry.GenProHours"),MessageUtils.message("entry.PubProHours"),MessageUtils.message("leave.duration"),MessageUtils.message("entry.totalManHours"),MessageUtils.message("entry.PubProHoursProp")};
+        //String[] string={"人员","部门","工号","普通项目工时","公共项目工时","请假时长","加班时长",总工时","公共项目工时占比"};
+        String[] string={MessageUtils.message("entry.personnel"),MessageUtils.message("excel.department"),
+                MessageUtils.message("entry.No"),MessageUtils.message("entry.GenProHours"),
+                MessageUtils.message("entry.PubProHours"),MessageUtils.message("leave.duration"),MessageUtils.message("excel.workOvertime"),
+                MessageUtils.message("entry.totalManHours"),MessageUtils.message("entry.PubProHoursProp")};
         List<List<String>> dataList=new ArrayList<>();
         dataList.add(Arrays.asList(string));
         Integer companyId = user.getCompanyId();
@@ -8057,6 +8074,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             subList.add(String.valueOf(item.get("unPublic")));
             subList.add(String.valueOf(item.get("isPublic")));
             subList.add(String.valueOf(item.get("leaveSum")));
+            subList.add(String.valueOf(item.get("overtimeHours")));
             subList.add(String.valueOf(item.get("workingTime")));
             subList.add(String.valueOf(item.get("proportion")));
             dataList.add(subList);
@@ -12719,7 +12737,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
     }
 
     @Override
-    public HttpRespMsg groupExpendProcessList(String startDate, String endDate,Integer pageIndex,Integer pageSize) {
+    public HttpRespMsg groupExpendProcessList(String startDate, String endDate,Integer projectId,Integer pageIndex,Integer pageSize) {
         HttpRespMsg msg=new HttpRespMsg();
         User user = userMapper.selectById(request.getHeader("token"));
         NumberFormat percentFormat = NumberFormat.getPercentInstance();
@@ -12759,7 +12777,11 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             pageIndex=-1;
             pageSize=-1;
         }
-        IPage<Project> projectIPage = projectMapper.selectPage(new Page<>(pageIndex, pageSize), new LambdaQueryWrapper<Project>().in(Project::getId, projectIds).eq(Project::getCompanyId, companyId));
+        LambdaQueryWrapper<Project> queryWrapper = new LambdaQueryWrapper<Project>().in(Project::getId, projectIds).eq(Project::getCompanyId, companyId);
+        if(projectId!=null){
+            queryWrapper.eq(Project::getId,projectId);
+        }
+        IPage<Project> projectIPage = projectMapper.selectPage(new Page<>(pageIndex, pageSize),queryWrapper);
         List<Project> projectList = projectIPage.getRecords();
         //是否具有查看全部数据的权限
         //针对依斯呗 指定部门
@@ -12834,8 +12856,13 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                                     item.put("realCost",new BigDecimal(mapList.stream().mapToDouble(m-> Double.valueOf(String.valueOf(m.get("realCost")))).sum()).setScale(2,RoundingMode.HALF_UP));
                                     item.put("overHour",new BigDecimal(mapList.stream().mapToDouble(m-> Double.valueOf(String.valueOf(m.get("overHour")))).sum()).setScale(2,RoundingMode.HALF_UP));
                                     item.put("normalHour",new BigDecimal(mapList.stream().mapToDouble(m-> Double.valueOf(String.valueOf(m.get("normalHour")))).sum()).setScale(2,RoundingMode.HALF_UP));
+                                    item.put("afterSetPlanHour",mapList.get(0).get("afterSetPlanHour"));
+                                    double afterSetPlanHour = Double.valueOf(String.valueOf(mapList.get(0).get("afterSetPlanHour"))).doubleValue();
                                     double realHour = mapList.stream().mapToDouble(m -> Double.valueOf(String.valueOf(m.get("realHour")))).sum();
                                     double planHour =  Double.valueOf(String.valueOf( mapList.get(0).get("planHour"))).doubleValue();
+                                    if(afterSetPlanHour>0){
+                                        planHour=planHour-afterSetPlanHour;
+                                    }
                                     item.put("process",percentFormat.format(realHour/planHour));
                                 }else {
                                     item.put("planHour",0);
@@ -12843,6 +12870,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                                     item.put("realCost",0);
                                     item.put("overHour",0);
                                     item.put("normalHour",0);
+                                    item.put("afterSetPlanHour",0);
                                     item.put("process","0.00%");
                                 }
                             }else {
@@ -12851,6 +12879,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                                 item.put("realCost",0);
                                 item.put("overHour",0);
                                 item.put("normalHour",0);
+                                item.put("afterSetPlanHour",0);
                                 item.put("process","0.00%");
                             }
                             itemList.add(item);
@@ -12881,8 +12910,13 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                                     item.put("realCost",new BigDecimal(mapList.stream().mapToDouble(m-> Double.valueOf(String.valueOf(m.get("realCost")))).sum()).setScale(2,RoundingMode.HALF_UP));
                                     item.put("overHour",new BigDecimal(mapList.stream().mapToDouble(m-> Double.valueOf(String.valueOf(m.get("overHour")))).sum()).setScale(2,RoundingMode.HALF_UP));
                                     item.put("normalHour",new BigDecimal(mapList.stream().mapToDouble(m-> Double.valueOf(String.valueOf(m.get("normalHour")))).sum()).setScale(2,RoundingMode.HALF_UP));
+                                    item.put("afterSetPlanHour",mapList.get(0).get("afterSetPlanHour"));
+                                    double afterSetPlanHour = Double.valueOf(String.valueOf(mapList.get(0).get("afterSetPlanHour"))).doubleValue();
                                     double realHour = mapList.stream().mapToDouble(m -> Double.valueOf(String.valueOf(m.get("realHour")))).sum();
                                     double planHour =  Double.valueOf(String.valueOf( mapList.get(0).get("planHour"))).doubleValue();
+                                    if(afterSetPlanHour>0){
+                                        planHour=planHour-afterSetPlanHour;
+                                    }
                                     item.put("process",percentFormat.format(realHour/planHour));
                                 }else {
                                     item.put("planHour",0);
@@ -12890,6 +12924,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                                     item.put("realCost",0);
                                     item.put("overHour",0);
                                     item.put("normalHour",0);
+                                    item.put("afterSetPlanHour",0);
                                     item.put("process","0.00%");
                                 }
                             }else {
@@ -12898,6 +12933,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                                 item.put("realCost",0);
                                 item.put("overHour",0);
                                 item.put("normalHour",0);
+                                item.put("afterSetPlanHour",0);
                                 item.put("process","0.00%");
                             }
                             itemList.add(item);
@@ -12932,8 +12968,13 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                                     item.put("realCost",new BigDecimal(mapList.stream().mapToDouble(m-> Double.valueOf(String.valueOf(m.get("realCost")))).sum()).setScale(2,RoundingMode.HALF_UP));
                                     item.put("overHour",new BigDecimal(mapList.stream().mapToDouble(m-> Double.valueOf(String.valueOf(m.get("overHour")))).sum()).setScale(2,RoundingMode.HALF_UP));
                                     item.put("normalHour",new BigDecimal(mapList.stream().mapToDouble(m-> Double.valueOf(String.valueOf(m.get("normalHour")))).sum()).setScale(2,RoundingMode.HALF_UP));
+                                    item.put("afterSetPlanHour",mapList.get(0).get("afterSetPlanHour"));
+                                    double afterSetPlanHour = Double.valueOf(String.valueOf(mapList.get(0).get("afterSetPlanHour"))).doubleValue();
                                     double realHour = mapList.stream().mapToDouble(m -> Double.valueOf(String.valueOf(m.get("realHour")))).sum();
                                     double planHour =  Double.valueOf(String.valueOf( mapList.get(0).get("planHour"))).doubleValue();
+                                    if(afterSetPlanHour>0){
+                                        planHour=planHour-afterSetPlanHour;
+                                    }
                                     item.put("process",percentFormat.format(realHour/planHour));
                                 }else {
                                     item.put("planHour",0);
@@ -12941,6 +12982,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                                     item.put("realCost",0);
                                     item.put("overHour",0);
                                     item.put("normalHour",0);
+                                    item.put("afterSetPlanHour",0);
                                     item.put("process","0.00%");
                                 }
                             }else {
@@ -12949,6 +12991,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
                                 item.put("realCost",0);
                                 item.put("overHour",0);
                                 item.put("normalHour",0);
+                                item.put("afterSetPlanHour",0);
                                 item.put("process","0.00%");
                             }
                             itemList.add(item);
@@ -12965,11 +13008,11 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
     }
 
     @Override
-    public HttpRespMsg exportGroupExpendProcessList(String startDate, String endDate) {
+    public HttpRespMsg exportGroupExpendProcessList(String startDate, String endDate,Integer projectId) {
         HttpRespMsg httpRespMsg=new HttpRespMsg();
         NumberFormat percentFormat = NumberFormat.getPercentInstance();
         percentFormat.setMaximumFractionDigits(2);
-        HttpRespMsg resultMsg = groupExpendProcessList(startDate,endDate,null,null);
+        HttpRespMsg resultMsg = groupExpendProcessList(startDate,endDate,projectId,null,null);
         Map<String, Object> msgData = (Map<String, Object>) resultMsg.getData();
         List<Map<String, Object>> mapList = (List<Map<String, Object>>) msgData.get("record");
         Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
@@ -13097,8 +13140,8 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
         List<String> projectIdList = mapList.stream().map(m -> String.valueOf(m.get("projectId"))).distinct().collect(Collectors.toList());
         //根据每个项目合并项目列表
         Integer projectNum=rowNum;
-        for (String projectId : projectIdList) {
-            List<Map<String, Object>> maps = listMapGroupList.get(projectId);
+        for (String pid : projectIdList) {
+            List<Map<String, Object>> maps = listMapGroupList.get(pid);
             if(maps.size()>1){
                 sheet.addMergedRegion(new CellRangeAddress(projectNum,projectNum+maps.size()-1,0,0));
             }
@@ -13116,7 +13159,11 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
         }
         for (Map<String, Object> map : mapList) {
             list.add(String.valueOf(map.get("projectName")));
-            list.add(String.valueOf(map.get("corpwxDeptId")));
+            if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
+                list.add("$departmentName="+map.get("corpwxDeptId")+"$");
+            }else {
+                list.add(String.valueOf(map.get("department_name")));
+            }
             list.add(String.valueOf(map.get("groupName")));
             list.add(String.valueOf(map.get("planHour")));
             list.add(String.valueOf(map.get("normalHour")));

+ 128 - 16
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -2346,7 +2346,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                     updateBatchById(updateReportList);
                 }
             } else {
-                //之前的流程逻辑,综合了一层项目审核,或者一层任务分组审核。 可叠加部门审批流
+                //之前的流程逻辑,综合了一层项目审核,或者一层任务分组审核。 可叠加部门审批流(部门审批时,本部门的负责人是否由上级部门负责人审核,可配置)
                 List<AuditWorkflowTimeSetting> settings = auditWorkflowTimeSettingMapper.selectList(
                         new QueryWrapper<AuditWorkflowTimeSetting>().eq("dept_id", auditTargetUser.getDepartmentId())
                                 .orderByAsc("seq"));
@@ -2383,9 +2383,26 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                                     AuditWorkflowTimeSetting nextNode = settings.get(m + 1);
                                     upR.setIsDeptAudit(nextNode.getIsDeptAudit());
                                     if (upR.getIsDeptAudit() == 1) {
+                                        //下一个节点是部门审核
                                         upR.setAuditDeptid(nextNode.getAuditDeptId());
-                                        upR.setAuditDeptManagerid(allDepts.stream()
-                                                .filter(ad->ad.getDepartmentId().equals(nextNode.getAuditDeptId())).findFirst().get().getManagerId());
+                                        Department curDept = allDepts.stream()
+                                                .filter(ad->ad.getDepartmentId().equals(nextNode.getAuditDeptId())).findFirst().get();
+                                        String curDeptManagerId = curDept.getManagerId();
+                                        //启用了本部门负责人的日报由上级部门主要负责人审核
+                                        if (timeType.getReportAuditFlowEnableSuperDeptAduit() == 1 && curDeptManagerId.equals(item.getCreatorId())) {
+                                            //当前提交的人是这个部门的主要负责人,那么要取该部门的上一级部门的主要负责人来审核
+                                            Integer parentDeptId = curDept.getSuperiorId();
+                                            if (parentDeptId == null) {
+                                                //没有上级部门,直接取当前部门的负责人
+                                                upR.setAuditDeptManagerid(curDeptManagerId);
+                                            } else {
+//                                                upR.setAuditDeptid(parentDeptId);
+                                                upR.setAuditDeptManagerid(allDepts.stream()
+                                                        .filter(ad->ad.getDepartmentId().equals(parentDeptId)).findFirst().get().getManagerId());
+                                            }
+                                        } else {
+                                            upR.setAuditDeptManagerid(curDeptManagerId);
+                                        }
                                     }
                                     upR.setIsFinalAudit(nextNode.getIsFinal());
                                     break;
@@ -2417,8 +2434,27 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                                             upR.setIsDeptAudit(nextNode.getIsDeptAudit());
                                             if (upR.getIsDeptAudit() == 1) {
                                                 upR.setAuditDeptid(nextNode.getAuditDeptId());
-                                                upR.setAuditDeptManagerid(allDepts.stream()
-                                                        .filter(ad->ad.getDepartmentId().equals(nextNode.getAuditDeptId())).findFirst().get().getManagerId());
+                                                Department curDept = allDepts.stream()
+                                                        .filter(ad->ad.getDepartmentId().equals(nextNode.getAuditDeptId())).findFirst().get();
+                                                String curDeptManagerId = curDept.getManagerId();
+                                                //启用了本部门负责人的日报由上级部门主要负责人审核
+                                                if (timeType.getReportAuditFlowEnableSuperDeptAduit() == 1 && curDeptManagerId.equals(item.getCreatorId())) {
+                                                    //当前提交的人是这个部门的主要负责人,那么要取该部门的上一级部门的主要负责人来审核
+                                                    Integer parentDeptId = curDept.getSuperiorId();
+                                                    if (parentDeptId == null) {
+                                                        //没有上级部门,直接取当前部门的负责人
+                                                        upR.setAuditDeptManagerid(curDeptManagerId);
+                                                    } else {
+//                                                        upR.setAuditDeptid(parentDeptId);
+                                                        upR.setAuditDeptManagerid(allDepts.stream()
+                                                                .filter(ad->ad.getDepartmentId().equals(parentDeptId)).findFirst().get().getManagerId());
+                                                    }
+                                                } else {
+                                                    upR.setAuditDeptManagerid(curDeptManagerId);
+                                                }
+
+//                                                upR.setAuditDeptManagerid(allDepts.stream()
+//                                                        .filter(ad->ad.getDepartmentId().equals(nextNode.getAuditDeptId())).findFirst().get().getManagerId());
                                             }
                                             upR.setIsFinalAudit(nextNode.getIsFinal());
                                             break;
@@ -2447,8 +2483,27 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                                                 upR.setIsDeptAudit(nextNode.getIsDeptAudit());
                                                 if (upR.getIsDeptAudit() == 1) {
                                                     upR.setAuditDeptid(nextNode.getAuditDeptId());
-                                                    upR.setAuditDeptManagerid(allDepts.stream()
-                                                            .filter(ad->ad.getDepartmentId().equals(nextNode.getAuditDeptId())).findFirst().get().getManagerId());
+                                                    Department curDept = allDepts.stream()
+                                                            .filter(ad->ad.getDepartmentId().equals(nextNode.getAuditDeptId())).findFirst().get();
+                                                    String curDeptManagerId = curDept.getManagerId();
+                                                    //启用了本部门负责人的日报由上级部门主要负责人审核
+                                                    if (timeType.getReportAuditFlowEnableSuperDeptAduit() == 1 && curDeptManagerId.equals(item.getCreatorId())) {
+                                                        //当前提交的人是这个部门的主要负责人,那么要取该部门的上一级部门的主要负责人来审核
+                                                        Integer parentDeptId = curDept.getSuperiorId();
+                                                        if (parentDeptId == null) {
+                                                            //没有上级部门,直接取当前部门的负责人
+                                                            upR.setAuditDeptManagerid(curDeptManagerId);
+                                                        } else {
+//                                                            upR.setAuditDeptid(parentDeptId);
+                                                            upR.setAuditDeptManagerid(allDepts.stream()
+                                                                    .filter(ad->ad.getDepartmentId().equals(parentDeptId)).findFirst().get().getManagerId());
+                                                        }
+                                                    } else {
+                                                        upR.setAuditDeptManagerid(curDeptManagerId);
+                                                    }
+
+//                                                    upR.setAuditDeptManagerid(allDepts.stream()
+//                                                            .filter(ad->ad.getDepartmentId().equals(nextNode.getAuditDeptId())).findFirst().get().getManagerId());
                                                 }
                                                 upR.setIsFinalAudit(nextNode.getIsFinal());
                                                 break;
@@ -3136,7 +3191,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     }
 
     @Override
-    public HttpRespMsg batchApproveReport(String reportIds, Integer isDepartment, HttpServletRequest request,String evaluate) {
+    public HttpRespMsg batchApproveReport(String reportIds, Integer isDepartment, HttpServletRequest request,String evaluate) throws Exception {
         String token = request.getHeader("Token");
         User user = userMapper.selectById(token);
         Company company = companyMapper.selectById(user.getCompanyId());
@@ -3559,12 +3614,26 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                                                 Optional<Department> first = allDepts.stream()
                                                         .filter(ad -> ad.getDepartmentId().equals(nextNode.getAuditDeptId())).findFirst();
                                                 if (!first.isPresent()) {
-
                                                     System.out.println(item.getId()+"下个节点找不到: "+nextNode.getAuditDeptId()+", "+nextNode.getAuditDeptName());
-
+                                                    throw new Exception("找不到部门");
+                                                }
+                                                Department curDept = first.get();
+                                                String curDeptManagerId = curDept.getManagerId();
+                                                //启用了本部门负责人的日报由上级部门主要负责人审核
+                                                if (timeType.getReportAuditFlowEnableSuperDeptAduit() == 1 && curDeptManagerId.equals(creatorId)) {
+                                                    //当前提交的人是这个部门的主要负责人,那么要取该部门的上一级部门的主要负责人来审核
+                                                    Integer parentDeptId = curDept.getSuperiorId();
+                                                    if (parentDeptId == null) {
+                                                        //没有上级部门,直接取当前部门的负责人
+                                                        curReport.setAuditDeptManagerid(curDeptManagerId);
+                                                    } else {
+//                                                        curReport.setAuditDeptid(parentDeptId);
+                                                        curReport.setAuditDeptManagerid(allDepts.stream()
+                                                                .filter(ad->ad.getDepartmentId().equals(parentDeptId)).findFirst().get().getManagerId());
+                                                    }
+                                                } else {
+                                                    curReport.setAuditDeptManagerid(curDeptManagerId);
                                                 }
-                                                String managerId = first.get().getManagerId();
-                                                curReport.setAuditDeptManagerid(managerId);
                                             }
                                             curReport.setIsFinalAudit(nextNode.getIsFinal());
                                             break;
@@ -3594,8 +3663,24 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                                                 curReport.setIsDeptAudit(nextNode.getIsDeptAudit());
                                                 if (curReport.getIsDeptAudit() == 1) {
                                                     curReport.setAuditDeptid(nextNode.getAuditDeptId());
-                                                    curReport.setAuditDeptManagerid(allDepts.stream()
-                                                            .filter(ad->ad.getDepartmentId().equals(nextNode.getAuditDeptId())).findFirst().get().getManagerId());
+                                                    Department curDept = allDepts.stream()
+                                                            .filter(ad->ad.getDepartmentId().equals(nextNode.getAuditDeptId())).findFirst().get();
+                                                    String curDeptManagerId = curDept.getManagerId();
+                                                    //启用了本部门负责人的日报由上级部门主要负责人审核
+                                                    if (timeType.getReportAuditFlowEnableSuperDeptAduit() == 1 && curDeptManagerId.equals(creatorId)) {
+                                                        //当前提交的人是这个部门的主要负责人,那么要取该部门的上一级部门的主要负责人来审核
+                                                        Integer parentDeptId = curDept.getSuperiorId();
+                                                        if (parentDeptId == null) {
+                                                            //没有上级部门,直接取当前部门的负责人
+                                                            curReport.setAuditDeptManagerid(curDeptManagerId);
+                                                        } else {
+//                                                            curReport.setAuditDeptid(parentDeptId);
+                                                            curReport.setAuditDeptManagerid(allDepts.stream()
+                                                                    .filter(ad->ad.getDepartmentId().equals(parentDeptId)).findFirst().get().getManagerId());
+                                                        }
+                                                    } else {
+                                                        curReport.setAuditDeptManagerid(curDeptManagerId);
+                                                    }
                                                 }
                                                 curReport.setIsFinalAudit(nextNode.getIsFinal());
                                                 upR = curReport;
@@ -3639,8 +3724,24 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                                                         upR.setIsDeptAudit(nextNode.getIsDeptAudit());
                                                         if (upR.getIsDeptAudit() == 1) {
                                                             upR.setAuditDeptid(nextNode.getAuditDeptId());
-                                                            upR.setAuditDeptManagerid(allDepts.stream()
-                                                                    .filter(ad->ad.getDepartmentId().equals(nextNode.getAuditDeptId())).findFirst().get().getManagerId());
+                                                            Department curDept = allDepts.stream()
+                                                                    .filter(ad->ad.getDepartmentId().equals(nextNode.getAuditDeptId())).findFirst().get();
+                                                            String curDeptManagerId = curDept.getManagerId();
+                                                            //启用了本部门负责人的日报由上级部门主要负责人审核
+                                                            if (timeType.getReportAuditFlowEnableSuperDeptAduit() == 1 && curDeptManagerId.equals(creatorId)) {
+                                                                //当前提交的人是这个部门的主要负责人,那么要取该部门的上一级部门的主要负责人来审核
+                                                                Integer parentDeptId = curDept.getSuperiorId();
+                                                                if (parentDeptId == null) {
+                                                                    //没有上级部门,直接取当前部门的负责人
+                                                                    curReport.setAuditDeptManagerid(curDeptManagerId);
+                                                                } else {
+//                                                                    curReport.setAuditDeptid(parentDeptId);
+                                                                    curReport.setAuditDeptManagerid(allDepts.stream()
+                                                                            .filter(ad->ad.getDepartmentId().equals(parentDeptId)).findFirst().get().getManagerId());
+                                                                }
+                                                            } else {
+                                                                curReport.setAuditDeptManagerid(curDeptManagerId);
+                                                            }
                                                         }
                                                         upR.setIsFinalAudit(nextNode.getIsFinal());
                                                         break;
@@ -4235,6 +4336,8 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         User user = userMapper.selectById(token);
         Integer companyId = user.getCompanyId();
         Company company = companyMapper.selectById(companyId);
+        List<UserFvTime> userFvTimeList = userFvTimeMapper.selectList(new LambdaQueryWrapper<UserFvTime>().between(UserFvTime::getWorkDate, startDate, endDate));
+        DateTimeFormatter df=DateTimeFormatter.ofPattern("yyyy-MM-dd");
         //String[] weekDayCHN = {"周一","周二","周三","周四","周五","周六","周日"};
         String[] weekDayCHN = {MessageUtils.message("week.Monday"),MessageUtils.message("week.Tuesday"),MessageUtils.message("week.Wednesday"),MessageUtils.message("week.Thursday"),MessageUtils.message("week.Friday"),MessageUtils.message("week.Saturday"),MessageUtils.message("week.Sunday")};
         HttpRespMsg msg = new HttpRespMsg();
@@ -4293,6 +4396,15 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             String date = new SimpleDateFormat("yyyy-MM-dd").format((Date)data.get("createDate"));
             map.put("workingTime", data.get("workingTime"));
             map.put("createDate", date);
+            //针对景昱 5978 校验填报工时是否超过考勤
+            if(user.getCompanyId().equals(5978)){
+                Optional<UserFvTime> first = userFvTimeList.stream().filter(u -> u.getWorkDate().isEqual(LocalDate.parse(date, df)) && u.getUserId().equals(id)).findFirst();
+                if(first.isPresent()){
+                    if(Double.valueOf(String.valueOf(data.get("workingTime")))>first.get().getWorkHours()){
+                        map.put("isOver",1);
+                    }
+                }
+            }
             if (id.equals(lastUserId)) {
                 //同一个用户的数据
                 lastUserData.worktimeList.add(map);

+ 90 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/WxCorpInfoServiceImpl.java

@@ -9,6 +9,7 @@ import com.management.platform.entity.*;
 import com.management.platform.mapper.*;
 import com.management.platform.service.TimeTypeService;
 import com.management.platform.service.WxCorpInfoService;
+import com.management.platform.service.WxCorpTemplateService;
 import com.management.platform.task.SFTPAsyncUploader;
 import com.management.platform.util.*;
 import lombok.extern.slf4j.Slf4j;
@@ -78,6 +79,15 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
     //获取日程
     public static final String ADD_SCHEDULE = " https://qyapi.weixin.qq.com/cgi-bin/oa/schedule/add?access_token=ACCESS_TOKEN";
 
+    //复制审批模板到企业
+    public static final String COPY_TEMPLATE = "https://qyapi.weixin.qq.com/cgi-bin/oa/approval/copytemplate?access_token=ACCESS_TOKEN";
+
+    //获取企业审批模板详情
+    public static final String GET_TEMPLATE_DETAIL = "https://qyapi.weixin.qq.com/cgi-bin/oa/gettemplatedetail?access_token=ACCESS_TOKEN";
+
+    //提交审批至企业微信
+    public static final String APPLY_EVENT = "https://qyapi.weixin.qq.com/cgi-bin/oa/applyevent?access_token=ACCESS_TOKEN";
+
 
     public static final int TEXT_CARD_MSG_BUSTRIP_WAITING_AUDIT = 0;//出差待审核
     public static final int TEXT_CARD_MSG_BUSTRIP_AGREE = 1;//出差审核通过
@@ -144,6 +154,8 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
     ContactSyncLogMapper contactSyncLogMapper;
     @Resource
     TaskMapper taskMapper;
+    @Resource
+    WxCorpTemplateService wxCorpTemplateService;
 
 
     //获取服务商provider_access_token
@@ -2337,4 +2349,82 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
         return msg;
     }
 
+    /**
+     * 企业微信审批模板 复制更新到企业
+     *
+     * */
+    @Override
+    public void copyTemplate(HttpServletRequest request,Integer templateType) throws Exception {
+        User user = userMapper.selectById(request.getHeader("token"));
+        WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", user.getCompanyId()));
+        String url=GET_TEMPLATE_DETAIL.replace("ACCESS_TOKEN",getCorpAccessToken(wxCorpInfo));
+        HttpHeaders headers = new HttpHeaders();
+        RestTemplate restTemplate = new RestTemplate();
+        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
+        headers.setContentType(type);
+        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
+        JSONObject requestMap = new JSONObject();
+        requestMap.put("template_id","1bc0b9fc084369083b6abb970d658f3a_75187226");
+        HttpEntity<JSONObject> entity = new HttpEntity<>(requestMap, headers);
+        ResponseEntity<String> ResponseEntity = restTemplate.postForEntity(url, entity, String.class);
+        if (ResponseEntity.getStatusCode() == HttpStatus.OK) {
+            String resp = ResponseEntity.getBody();
+            JSONObject respJson = JSONObject.parseObject(resp);
+            WxCorpTemplate wxCorpTemplate =new WxCorpTemplate();
+            wxCorpTemplate.setCompanyId(wxCorpInfo.getCompanyId())
+                          .setTemplateId(respJson.getString("template_id"))
+                          .setType(templateType);
+            wxCorpTemplateService.saveOrUpdate(wxCorpTemplate);
+            System.out.println(resp);
+        }
+    }
+
+    /**
+     * 获取企业审批模板详情
+     * */
+    @Override
+    public String getTemplateDetail(HttpServletRequest request,Integer templateType) throws Exception {
+        User user = userMapper.selectById(request.getHeader("token"));
+        WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", user.getCompanyId()));
+        WxCorpTemplate template = wxCorpTemplateService.getById(wxCorpInfo.getCompanyId());
+        if(template==null){
+            copyTemplate(request,templateType);
+            template = wxCorpTemplateService.getById(wxCorpInfo.getCompanyId());
+        }
+        String url=COPY_TEMPLATE.replace("ACCESS_TOKEN",getCorpAccessToken(wxCorpInfo));
+        HttpHeaders headers = new HttpHeaders();
+        RestTemplate restTemplate = new RestTemplate();
+        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
+        headers.setContentType(type);
+        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
+        JSONObject requestMap = new JSONObject();
+        requestMap.put("template_id",template.getTemplateId());
+        HttpEntity<JSONObject> entity = new HttpEntity<>(requestMap, headers);
+        ResponseEntity<String> ResponseEntity = restTemplate.postForEntity(url, entity, String.class);
+        if (ResponseEntity.getStatusCode() == HttpStatus.OK) {
+            String resp = ResponseEntity.getBody();
+            return resp;
+        }
+        return null;
+    }
+
+    /**
+     * 提交审批到企业微信
+     * */
+    @Override
+    public void applyEvent(HttpServletRequest request,JSONObject data) throws Exception {
+        User user = userMapper.selectById(request.getHeader("token"));
+        WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", user.getCompanyId()));
+        String url=APPLY_EVENT.replace("ACCESS_TOKEN",getCorpAccessToken(wxCorpInfo));
+        HttpHeaders headers = new HttpHeaders();
+        RestTemplate restTemplate = new RestTemplate();
+        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
+        headers.setContentType(type);
+        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
+        HttpEntity<JSONObject> entity = new HttpEntity<>(data, headers);
+        ResponseEntity<String> ResponseEntity = restTemplate.postForEntity(url, entity, String.class);
+        if (ResponseEntity.getStatusCode() == HttpStatus.OK) {
+            String resp = ResponseEntity.getBody();
+        }
+    }
 }

+ 20 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/WxCorpTemplateServiceImpl.java

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.WxCorpTemplate;
+import com.management.platform.mapper.WxCorpTemplateMapper;
+import com.management.platform.service.WxCorpTemplateService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-03-25
+ */
+@Service
+public class WxCorpTemplateServiceImpl extends ServiceImpl<WxCorpTemplateMapper, WxCorpTemplate> implements WxCorpTemplateService {
+
+}

+ 11 - 9
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java

@@ -2009,7 +2009,7 @@ public class TimingTask {
         List<BeisenConfig> beisenConfigs = beisenConfigMapper.selectList(null);
         for (BeisenConfig beisenConfig : beisenConfigs) {
             if(beisenConfig!=null){
-                List<JSONArray> byTimeWindow = BeiSenUtils.getByTimeWindow("",time,time,beisenConfig.getAppKey(),beisenConfig.getAppSecret());
+                List<JSONArray> byTimeWindow = BeiSenUtils.getByTimeWindow("",time,time,beisenConfig.getCompanyId(),beisenConfig.getAppKey(),beisenConfig.getAppSecret());
                 for (JSONArray array : byTimeWindow) {
                     for (int i = 0; i < array.size(); i++) {
                         UserWithBeisen userWithBeisen=new UserWithBeisen();
@@ -2089,14 +2089,16 @@ public class TimingTask {
                     Double workTime=8.0;
                     Stream<JSONObject> overTimeStream = allOverTimeList.stream().map(elment -> (JSONObject) elment);
                     Optional<UserWithBeisen> beisen = userWithBeisenList.stream().filter(u -> u.getJobNumber() != null && u.getJobNumber().equals(first.get().getJobNumber())).findFirst();
-                    List<JSONObject> overTimeList = overTimeStream.filter(a -> a.getString("StaffId").equals(beisen.get().getUserId())
-                            && a.getIntValue("ApproveStatus") == 2).collect(Collectors.toList());
-                    if(overTimeList.size()>0){
-                        double actualOverTimeDuration = overTimeList.stream().mapToDouble(i -> i.getDouble("ActualOverTimeDuration")).sum();
-                        if(workDay){
-                            workTime= workTime+actualOverTimeDuration;
-                        }else {
-                            workTime= actualOverTimeDuration;
+                    if(beisen.isPresent()){
+                        List<JSONObject> overTimeList = overTimeStream.filter(a -> a.getString("StaffId").equals(beisen.get().getUserId())
+                                && a.getIntValue("ApproveStatus") == 2).collect(Collectors.toList());
+                        if(overTimeList.size()>0){
+                            double actualOverTimeDuration = overTimeList.stream().mapToDouble(i -> i.getDouble("ActualOverTimeDuration")).sum();
+                            if(workDay){
+                                workTime= workTime+actualOverTimeDuration;
+                            }else {
+                                workTime= actualOverTimeDuration;
+                            }
                         }
                     }
                     UserFvTime userFvTime=new UserFvTime();

+ 66 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/BeiSenUtils.java

@@ -83,7 +83,7 @@ public class BeiSenUtils {
     /**
      * 获取人员数据
      * */
-    public static List<JSONArray> getByTimeWindow(String scrollId,String startTime,String stopTime,String appkey,String appSecret){
+    public static List<JSONArray> getByTimeWindow(String scrollId,String startTime,String stopTime,Integer companyId,String appkey,String appSecret){
         List<JSONArray> resultList=new ArrayList<>();
         String url = "https://openapi.italent.cn/TenantBaseExternal/api/v5/Employee/GetByTimeWindow";
         HttpHeaders headers = new HttpHeaders();
@@ -97,6 +97,15 @@ public class BeiSenUtils {
         requestMap.put("timeWindowQueryType",1);
         requestMap.put("startTime",startTime+"T00:00:00");
         requestMap.put("stopTime",stopTime+"T23:59:59");
+        List<String> columns=new ArrayList<>();
+        columns.add("JobNumber");
+        columns.add("MobilePhone");
+        columns.add("Name");
+        columns.add("StaffID");
+        columns.add("UserID");
+        if(companyId!=null && companyId==5789){
+            requestMap.put("columns",columns);
+        }
         System.out.println("--------headers请求头数据-------"+headers);
         if(!StringUtils.isEmpty(scrollId)){
             requestMap.put("scrollId",scrollId);
@@ -111,7 +120,7 @@ public class BeiSenUtils {
                 resultList.add(respJson.getJSONArray("data"));
                 String nextScrollId = respJson.getString("scrollId");
                 if(!StringUtils.isEmpty(nextScrollId)&&respJson.getJSONArray("data").size()>0){
-                    List<JSONArray> byTimeWindow = getByTimeWindow(nextScrollId,startTime,stopTime,appkey,appSecret);
+                    List<JSONArray> byTimeWindow = getByTimeWindow(nextScrollId,startTime,stopTime,companyId,appkey,appSecret);
                     resultList.addAll(byTimeWindow);
                 }
             }
@@ -242,4 +251,59 @@ public class BeiSenUtils {
         return lastJSONArray;
     }
 
+
+    /**
+     * 获取指定人员指定日期考勤数据
+     * */
+    public static JSONObject getAttendanceStatisticWithUser(String date,String userId,String appkey,String appSecret){
+        String url = "https://openapi.italent.cn/AttendanceOpen/api/v1/AttendanceStatistics/GetAttendanceStatistics";
+        HttpHeaders headers = new HttpHeaders();
+        RestTemplate restTemplate = new RestTemplate();
+        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
+        headers.setContentType(type);
+        String accessToken = getToken(appkey,appSecret);
+        System.out.println("--------Bearer TOKEN--------"+accessToken);
+        headers.add("Authorization","Bearer "+accessToken);
+        JSONObject requestMap = new JSONObject();
+        requestMap.put("date",date);
+        requestMap.put("staffId",userId);
+        System.out.println("--------headers请求头数据-------"+headers);
+        System.out.println("--------requestMap请求参数-------"+requestMap);
+        HttpEntity<JSONObject> entity = new HttpEntity<>(requestMap, headers);
+        ResponseEntity<String> ResponseEntity = restTemplate.postForEntity(url, entity, String.class);
+        String resp= ResponseEntity.getBody();
+        JSONObject respJson = JSONObject.parseObject(resp);
+        JSONObject data = respJson.getJSONObject("data");
+        return data;
+    }
+
+
+    /**
+     * 获取指定人员指定日期加班数据
+     * */
+    public static JSONArray getScheduledOverTimeRangeList(String startDate,String endDate,String userId,String appkey,String appSecret){
+        String url = "https://openapi.italent.cn/AttendanceOpen/api/v1/AttendanceOvertime/GetScheduledOverTimeRangeList";
+        HttpHeaders headers = new HttpHeaders();
+        RestTemplate restTemplate = new RestTemplate();
+        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
+        headers.setContentType(type);
+        String accessToken = getToken(appkey,appSecret);
+        System.out.println("--------Bearer TOKEN--------"+accessToken);
+        headers.add("Authorization","Bearer "+accessToken);
+        JSONObject requestMap = new JSONObject();
+        requestMap.put("startDate",startDate);
+        List<String> staffIds=new ArrayList<>();
+        staffIds.add(userId);
+        requestMap.put("stopDate",endDate);
+        requestMap.put("staffIds",staffIds);
+        System.out.println("--------headers请求头数据-------"+headers);
+        System.out.println("--------requestMap请求参数-------"+requestMap);
+        HttpEntity<JSONObject> entity = new HttpEntity<>(requestMap, headers);
+        ResponseEntity<String> ResponseEntity = restTemplate.postForEntity(url, entity, String.class);
+        String resp= ResponseEntity.getBody();
+        JSONObject respJson = JSONObject.parseObject(resp);
+        JSONArray data = respJson.getJSONArray("data");
+        return data;
+    }
+
 }

+ 4 - 3
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectMapper.xml

@@ -818,7 +818,8 @@
         user.department_id As deptId,
         ifnull(SUM(if(project.is_public=0,report.working_time,null)),0) as unPublic,
         ifnull(SUM(if(project.is_public=1,report.working_time,null)),0) as isPublic,
-        ifnull(SUM(report.`working_time`),0) AS workingTime
+        ifnull(SUM(report.`working_time`),0) AS workingTime,
+        ifnull(SUM(report.`overtime_hours`),0) AS overtimeHours
         FROM report LEFT JOIN user ON user.id = report.`creator_id`
         left join project on project.id = report.project_id
         WHERE
@@ -1896,7 +1897,7 @@
     <select id="groupExpendProcessList" resultType="java.util.Map">
         SELECT p.project_name AS projectName,p.id AS projectId,tg.id AS groupId,d.department_name,d.department_id AS deptId,d.corpwx_deptid AS corpwxDeptId,tg.name AS groupName,
         IFNULL(r.realHour,0) AS realHour,IFNULL(r.realCost,0) AS realCost,IFNULL(r.normalHour,0) as normalHour,IFNULL(r.overHour,0) as overHour,
-        IFNULL(tg.man_day*8,0) AS planHour
+        IFNULL(tg.man_day*8,0) AS planHour,IFNULL((SELECT SUM(change_man_day*8) FROM `group_budget_review` WHERE group_id=tg.`id` AND `status`=1),0) AS afterSetPlanHour
         FROM task_executor te
         LEFT JOIN task t ON t.id=te.task_id
         LEFT JOIN user u ON te.executor_id=u.id
@@ -1905,7 +1906,7 @@
         LEFT JOIN department d ON d.department_id=u.department_id
         LEFT JOIN (
         SELECT SUM(working_time) AS realHour,SUM(cost) AS realCost,(SUM(working_time)-SUM(overtime_hours)) AS normalHour,SUM(overtime_hours) AS overHour,group_id,dept_id
-        FROM report  WHERE create_date BETWEEN #{startDate} AND #{endDate} AND state=1 AND project_id IS NOT NULL AND company_id=#{companyId} GROUP BY group_id,dept_id) r ON r.group_id=tg.`id` and r.dept_id=u.department_id
+        FROM report  WHERE state=1 <if test="startDate!=null and startDate!='' and endDate!=null and endDate!=''"> AND create_date BETWEEN #{startDate} AND #{endDate} </if>AND project_id IS NOT NULL AND company_id=#{companyId} GROUP BY group_id,dept_id) r ON r.group_id=tg.`id` and r.dept_id=u.department_id
         WHERE u.company_id=#{companyId}
         AND tg.name IN ('生产部电气','生产部车间','工程部现场安装施工','工程部配合调试','研发部工艺设计','研发部结构设计','研发部BIM设计','研发部电气设计','研发部工艺调试验收','研发部电气调试验收')
         <if test="userId!=null and userId!=''">

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 4 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/TimeTypeMapper.xml


+ 17 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/WxCorpTemplateMapper.xml

@@ -0,0 +1,17 @@
+<?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.management.platform.mapper.WxCorpTemplateMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.WxCorpTemplate">
+        <id column="company_id" property="companyId" />
+        <result column="template_id" property="templateId" />
+        <result column="type" property="type" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        company_id, template_id, type
+    </sql>
+
+</mapper>

+ 15 - 4
fhKeeper/formulahousekeeper/timesheet/src/views/corpreport/list.vue

@@ -630,6 +630,8 @@
               </el-table-column>
               <el-table-column prop="leaveSum" :label="$t('qing-jia-gong-shi')" min-width="160" align="right">
               </el-table-column>
+              <el-table-column prop="overtimeHours" :label="$t('jia-ban-shi-chang')" min-width="160" align="right">
+              </el-table-column>
               <el-table-column prop="workingTime" :label="$t('other.totalworkinghours')" min-width="160" align="right">
                 <template slot-scope="scope">
                   <span>{{scope.row.workingTime == null? 0 + 'h' : scope.row.workingTime.toFixed(1) + 'h'}}</span>
@@ -1142,6 +1144,7 @@
               <el-table-column align="center" prop="groupName" label="任务分组" min-width="150"></el-table-column>
               <el-table-column align="center" prop="planHour" label="计划工时(财务)" width="120"></el-table-column>
               <el-table-column align="center" label="实际工时成本">
+                <el-table-column align="center" prop="afterSetPlanHour" label="增补工时(h)" width="120"></el-table-column>
                 <el-table-column align="center" prop="normalHour" label="正常工时(h)" width="100"></el-table-column>
                 <el-table-column align="center" prop="overHour" label="加班工时(h)" width="100"></el-table-column>
                 <el-table-column align="center" prop="realHour" label="合计工时(h)" width="100"></el-table-column>
@@ -1502,7 +1505,7 @@ export default {
   data() {
     return {
       screeningCondition: { // 筛选条件的判断
-        project: [4, 8, 9, 10, 11, 14, 15, 17, 19, 20, 21, 22, 24], // 项目筛选条件 (不等于)
+        project: [4, 8, 9, 10, 11, 14, 15, 17, 19, 20, 21, 22], // 项目筛选条件 (不等于)
         months: [14, 15], // 月份筛选条件 (等于)
         monthRange: [19], // 月份区间筛选条件 (等于)
         staff: [6, 8, 9, 19, 11, 14, 18, 23, 25, 26], // 人员筛选条件 (等于)
@@ -2077,7 +2080,9 @@ export default {
             },
             getList(e) {
               let noUserList = [16, 17, 18, 19, 20, 21, 22, 24, 25, 26,27]
-              if(this.ins == 15) {
+              if(this.ins == 24) {
+                this.rangeDatas = []
+              } else if(this.ins == 15) {
                 this.rangeDatas = null
               } else if(!e){
                 this.rangeDatas = this.getCurrentRangeTime()
@@ -2333,6 +2338,7 @@ export default {
         } else if(this.ins == 24) {
           fName = '分组耗用进度表' + '.xlsx'
           url = "/project/exportGroupExpendProcessList"
+          this.proJuctId ? parameter.projectId = this.proJuctId : ''
           sl.startDate = this.rangeDatas[0]
           sl.endDate = this.rangeDatas[1]
         } else if(this.ins == 25) {
@@ -3873,11 +3879,16 @@ export default {
     // 分组耗用进度表
     async getConsumptionSchedule() {
       let parameter = {
-        startDate: this.rangeDatas[0],
-        endDate: this.rangeDatas[1],
+        // startDate: this.rangeDatas[0],
+        // endDate: this.rangeDatas[1],
         pageIndex: this.page,
         pageSize: this.size,
       }
+      if( this.rangeDatas &&  this.rangeDatas.length > 0) {
+        parameter.startDate = this.rangeDatas[0]
+        parameter.endDate = this.rangeDatas[1]
+      }
+      this.proJuctId ? parameter.projectId = this.proJuctId : ''
       this.listLoading = true
       let { data } = await this.postData('/project/groupExpendProcessList', {
         ...parameter

+ 1 - 1
fhKeeper/formulahousekeeper/timesheet/src/views/project/list.vue

@@ -402,7 +402,7 @@
             </el-table-column>
             <el-table-column :label="$t('operation')" :width="showColumnWidth" align="left" fixed="right" v-if="showColumnWidth != '0' || permissions.projectManagement">
                 <template slot-scope="scope">
-                    <el-button v-if="(permissions.projectManagement || user.id==scope.row.creatorId) && user.timeType.mainProjectState != '1'" size="mini"  @click="subProject(scope.row)">{{ $t('lable.subproject') }}</el-button>
+                    <el-button v-if="(permissions.projectManagement || user.id==scope.row.creatorId) && user.timeType.mainProjectState != '1' && !user.timeType.hideSubproject" size="mini"  @click="subProject(scope.row)">{{ $t('lable.subproject') }}</el-button>
                     <el-button size="mini" v-if="permissions.projectParticipator || permissions.projectManagement || user.id==scope.row.inchargerId || user.id==scope.row.creatorId" type="primary" @click="handleAdd(scope.$index, scope.row)">{{ $t('bian-ji') }}</el-button>
                     <!-- <el-button v-if="permissions.projectManagement || user.id==scope.row.creatorId" size="mini"  @click="deletePro(scope.$index, scope.row)">删除</el-button> -->
                     <el-dropdown class="customdropdown" split-button size="mini" @click="finishPro(scope.row)" v-if="(permissions.projectManagement || user.id==scope.row.creatorId || user.id==scope.row.inchargerId) && scope.row.status == 1" placement="bottom-start">

+ 17 - 0
fhKeeper/formulahousekeeper/timesheet/src/views/projectApproval/projectApproval.vue

@@ -169,6 +169,23 @@
                                     </el-select>
                                     <selectCat v-if="user.userNameNeedTranslate == '1'" :size="'medium'" :tile="true" :widthStr="'800'" :disabled="!(permissions.projectManagement|| user.id == addForm.inchargerId || user.id == addForm.creatorId)" :subjectId="addForm.auditUserIds" :subject="participator" :clearable="false" :distinction="'10'"  :multiSelect="user.timeType.reportAuditType != 6" @selectCal="selectCal"></selectCat>
                                 </el-form-item>
+                                <!--专业项目协作版本功能 -->
+                                <el-form-item :label="$t('ji-bie')" :class="title == $t('newproject') && user.companyId == 936 ? 'wpgCssClass' : ''" v-if="user.company.packageProject==1 && (user.company.nonProjectSimple == 0 || (user.company.nonProjectSimple == 1 && addForm.isPublic == 0))">
+                                    <el-select v-model="addForm.level"  :placeholder="$t('defaultText.pleaseChoose')" style="width:32%;" v-if="user.timeType.projectLevelState == 1" :disabled="canOnlyModParticipator || isShowProjectName">
+                                        <el-option v-for="item in levelList" :key="item.id" :label="item.projectLevelName" :value="item.id"></el-option>
+                                    </el-select>
+                                    <el-select v-model="addForm.level"  :placeholder="this.$t('defaultText.pleaseChoose')" style="width:32%;" :disabled="canOnlyModParticipator" v-else>
+                                        <el-option v-for="item in importanceList" :key="item.id" :label="item.label" :value="item.id"></el-option>
+                                    </el-select>
+                                </el-form-item>
+                                <!-- 增加合同金额字段 -->
+                                <el-form-item  :label="$t('contractamount')" v-if="user.company.packageProject==1 && (user.company.nonProjectSimple == 0 || (user.company.nonProjectSimple == 1 && addForm.isPublic == 0))">
+                                    <el-input id="contractAmount" v-model="addForm.contractAmount" :disabled="canOnlyModParticipator" style="width:32%;" @input="contractAmountChange(addForm.contractAmount)" :placeholder="$t('zheng-shu')" clearable  @keyup.native="restrictNumber('contractAmount')"></el-input><span style="margin-left:10px;position:absolute;">{{ $t('yuan') }}</span>
+                                    <template v-if="title == $t('modifytheproject') && contractAmountReasonShow">
+                                        <span style="margin-left:63px;margin-right:10px;">{{ $t('modifythereason') }}</span>
+                                        <el-input v-model="addForm.changeContractReason" style="width:33%" clearable :placeholder="$t('contractamountasd')"></el-input>
+                                    </template>
+                                </el-form-item>
                                 <el-form-item :label="$t('ommencementDate')" prop="planStartDate"  v-if="(user.company.nonProjectSimple == 0 || (user.company.nonProjectSimple == 1 && addForm.isPublic == 0))">
                                     <el-date-picker v-model="addForm.planStartDate" :disabled="canOnlyModParticipator"
                                     :editable="false" style="width:32%;" 

+ 7 - 0
fhKeeper/formulahousekeeper/timesheet/src/views/settings/timetype.vue

@@ -415,6 +415,11 @@
             <el-switch style="margin:0px 0 10px 81px;" v-model="timeType.taskRequired" active-color="#20a0ff"></el-switch>
             <span style="margin:0px 0 10px 10px;color:#999;">{{ $t('parametermandatory') }}</span>
         </div>
+        <div class="yanjiu">
+            <span style="margin:0px 0 10px 10px;color:#666;">任务分组</span>
+            <el-switch style="margin-left:108px;" v-model="timeType.taskGroupRequired" active-color="#20a0ff"></el-switch>
+            <span style="margin:0px 0 10px 10px;color:#999;">{{ $t('parametermandatory') }}</span>
+        </div>
         <div class="yanjiu">
             <span style="margin-left:10px;color:#666;">{{user.companyId==781?$t('other.specificcontentandresults'):$t('other.workMatters')}}</span>
             <el-switch :style="user.companyId==781?'margin-left:66px;':'margin-left:108px;'" v-model="timeType.workContentState" active-color="#20a0ff" > </el-switch>
@@ -1336,6 +1341,7 @@
                         param.hideStages = param.hideStages ? 1 : 0
                         param.hideTask = param.hideTask ? 1 : 0
                         param.taskRequired = param.taskRequired ? 1 : 0
+                        param.taskGroupRequired = param.taskGroupRequired ? 1 : 0
 
                         var oneseet = 0
                         var twoset = 0
@@ -1405,6 +1411,7 @@
                             this.timeType.hideStages = this.timeType.hideStages? true: false;
                             this.timeType.hideTask = this.timeType.hideTask? true: false;
                             this.timeType.taskRequired = this.timeType.taskRequired? true: false;
+                            this.timeType.taskGroupRequired = this.timeType.taskGroupRequired? true: false;
                             // this.timeType.alertNonWorkday = this.timeType.alertNonWorkday ? true : false
 
                             if(this.timeType.alertNonWorkday) {

+ 32 - 4
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

@@ -274,7 +274,7 @@
                                                     <span style="margin-left:10px;">工作内容:{{ item2.extraField3? item2.extraField3Name:''}}</span></p>
                                                     <!--任务分组和阶段 -->
                                                     <p v-if="item2.groupId != 0">
-                                                        {{$t('other.taskGroup')}}:{{item2.groupName}} 
+                                                        {{$t('other.taskGroup')}}:{{item2.groupName}}
                                                         <span v-if="item2.stage != null && item2.stage != '-' && user.companyId != yuzhongCompId && user.timeType.enableNewWeeklyfill != 1" style="margin-left:10px;">{{$t('other.inputStage')}}:{{item2.stage}}</span>
                                                     </p>
                                                     <p v-if="user.timeType.customDegreeActive==1 && ((item2.degree_id != null && item2.degree_id != -1) || item2.multiDegrId)">{{user.timeType.customDegreeName}}:{{item2.degreeName}}</p>
@@ -1379,12 +1379,20 @@
                 </el-input>
                 <selectCat v-if="user.userNameNeedTranslate == '1'" :filterable="true"  :searchBoxTop="'1'" :size="'small'" :subject="usersList" :subjectId="usersListId" :distinction="'12'" :clearable="true" @selectCal="selectCal"></selectCat>
             </div>
-            <el-link
+            <div style="float: right; vertical-align: middle;height:32px">
+              <el-link 
+              v-if="user.companyId==5978"
+              type="primary"
+              @click="changeReminder()"
+              >{{'变更提醒'}}</el-link
+              >
+              <el-link
               type="primary"
-              style="float: right; vertical-align: middle;height:32px"
               @click="exportMembWorkHours()"
               >{{$t('export.exportData')}}</el-link
-            >
+             >
+            </div>
+            
           </div>
 
           <el-table ref="hasworkTbl"
@@ -4461,6 +4469,10 @@
                 if(!domain.groupId){
                     domain.projectAuditorId = ''
                     domain.stages = []
+                    if(this.user.companyId == '3092') { // 针对 公司id为3092的公司清空任务分组时一起清空任务和服务
+                        domain.taskId = ''
+                        domain.sapServiceId = ''
+                    }
                     if(this.user.timeType.reportAuditType >= 1){
                         domain.auditUserList = []
                     }
@@ -6034,6 +6046,7 @@
             },
             // 按周填报里内容的填写点击确定
             setWeekProItemData() {
+                
                 //专业版模式下,任务分组和阶段必填
                 if (this.user.company.packageProject == 1 && this.user.companyId === 3917) {
                     if (!this.zhoBao.groupId || !this.zhoBao.stage) {
@@ -6044,6 +6057,14 @@
                         return;
                     }
                 }
+                // 检查任务分组
+                if(this.user.timeType.taskGroupRequired == 1 && !this.zhoBao.groupId){
+                    this.$message({
+                        message: '任务分组必填,请检查',
+                        type: "error"
+                    });
+                    return
+                }
                 //检查子项目是否必填
                 if (this.user.timeType.subProMustFill == 1 && this.zhoBao.subProjectList && this.zhoBao.subProjectList.length > 0 && !this.zhoBao.subProjectId) {
                     this.$message({
@@ -7719,6 +7740,13 @@
                             if (this.user.companyId == this.yisibeiCompId) {
                                 formData.append('sapServiceId', this.workForm.domains[i].sapServiceId);
                             }
+                            if(this.user.timeType.taskGroupRequired == 1 && !this.workForm.domains[i].groupId) {
+                                this.$message({
+                                    message: this.$t('defaultText.pleaseset') + "["+this.workForm.domains[i].projectName+"]"+this.$t('message.Projectgroupleader'),
+                                    type: "error"
+                                });
+                                return
+                            }
                         }
                         this.submitingReport = true;
                         this.http.uploadFile( this.port.report.editPort, formData,

+ 5 - 0
fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/index.vue

@@ -2470,6 +2470,11 @@ export default {
                 if (this.user.companyId == 3092) {
                     formData.append('sapServiceId', this.form.domains[i].sapServiceId);
                 }
+
+                if(this.user.timeType.taskGroupRequired == 1 && !this.form.domains[i].groupId) {
+                    this.$toast.fail("请选择[" + this.form.domains[i].projectName + "]项目的任务分组");
+                    return;
+                }
             }
             if (!this.flgLg) {
                 return

+ 4 - 1
fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/weekEdit.vue

@@ -2143,7 +2143,10 @@
                             formData.append("auditorSettingArray", JSON.stringify(audItem).replace(/,/g,"@"));
                         }
 
-
+                        if(this.user.timeType.taskGroupRequired == 1 && !this.form[formIndex].domains[i].groupId){
+                            this.$toast.fail('请指定' + this.weekArr[formIndex] + '的任务分组')
+                            return
+                        }
 
 
                         if (this.user.timeType.customDegreeActive == 1) {