فهرست منبع

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

yusm 2 روز پیش
والد
کامیت
07228f37c8
21فایلهای تغییر یافته به همراه821 افزوده شده و 521 حذف شده
  1. 7 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/OvertimeAllowanceController.java
  2. 69 45
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java
  3. 33 6
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserCorpwxTimeController.java
  4. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/WxCorpInfoController.java
  5. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/OvertimeAllowance.java
  6. 6 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/TimeType.java
  7. 1 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ReportService.java
  8. 463 205
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  9. 37 35
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/WxCorpInfoServiceImpl.java
  10. 2 2
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/OvertimeAllowanceMapper.xml
  11. 6 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportMapper.xml
  12. 2 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/TimeTypeMapper.xml
  13. 9 3
      fhKeeper/formulahousekeeper/octopus/src/views/customer/list.vue
  14. 0 3
      fhKeeper/formulahousekeeper/timesheet/src/i18n/en.json
  15. 0 3
      fhKeeper/formulahousekeeper/timesheet/src/i18n/zh.json
  16. 14 7
      fhKeeper/formulahousekeeper/timesheet/src/views/corpreport/list.vue
  17. 1 1
      fhKeeper/formulahousekeeper/timesheet/src/views/project/gantt.vue
  18. 0 80
      fhKeeper/formulahousekeeper/timesheet/src/views/project/project_gantt.vue
  19. 3 3
      fhKeeper/formulahousekeeper/timesheet/src/views/settings/timetype.vue
  20. 109 82
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue
  21. 57 41
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/index.vue

+ 7 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/OvertimeAllowanceController.java

@@ -115,7 +115,7 @@ public class OvertimeAllowanceController {
         boolean noRecords = false;
         if (departmentId != null) {
             // 部门以及子部门
-            List<Department> allDepts = departmentService.list(new QueryWrapper<Department>().eq("company_id", departmentId));
+            List<Department> allDepts = departmentService.list(new QueryWrapper<Department>().eq("company_id", companyId));
             List<Integer> deptIds = departmentService.getDeptIncludeSubDeptIds(departmentId, allDepts);
             if (deptIds.size() > 0) {
                 List<User> deptUsers = userMapper.selectList(new QueryWrapper<User>().in("department_id", deptIds));
@@ -273,7 +273,7 @@ public class OvertimeAllowanceController {
         boolean noRecords = false;
         List<String> corpwxUserids = null;
         if (departmentId != null) {
-            List<Department> allDepts = departmentService.list(new QueryWrapper<Department>().eq("company_id", departmentId));
+            List<Department> allDepts = departmentService.list(new QueryWrapper<Department>().eq("company_id", companyId));
             List<Integer> deptIds = departmentService.getDeptIncludeSubDeptIds(departmentId, allDepts);
             if (deptIds.size() > 0) {
                 List<User> deptUsers = userMapper.selectList(new QueryWrapper<User>().in("department_id", deptIds));
@@ -730,6 +730,11 @@ public class OvertimeAllowanceController {
                             crossMidnightStr = "否";
                             comment = "全天加班";
                             break;
+                        case 5:
+                            typeStr = "白班";
+                            crossMidnightStr = "是";
+                            comment = "加班过凌晨4点,餐补 50 元";
+                            break;
                         default:
                             comment = String.valueOf(allowance.getType());
                     }

+ 69 - 45
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java

@@ -1281,7 +1281,12 @@ public class ReportController {
                             if (comTimeType.getReportAuditType() == 3) {
                                 report.setAuditorSetting(auditorSettingList.get(i));
                             }
-                            setReportWorkflowAuditor(auditWorkflowList, allDeptList, report,comTimeType);
+                            String errorMsg = setReportWorkflowAuditor(auditWorkflowList, allDeptList, report,comTimeType);
+                            if (errorMsg != null) {
+                                HttpRespMsg msg = new HttpRespMsg();
+                                msg.setError(errorMsg);
+                                return msg;
+                            }
                             if (taskId != null && taskId[i] != null && taskId[i] != 0) {
                                 report.setTaskId(taskId[i]);
                             }
@@ -1341,7 +1346,12 @@ public class ReportController {
                                 if (comTimeType.getReportAuditType() == 3) {
                                     report.setAuditorSetting(auditorSettingList.get(i));
                                 }
-                                setReportWorkflowAuditor(auditWorkflowList, allDeptList, report,comTimeType);
+                                String errorMsg = setReportWorkflowAuditor(auditWorkflowList, allDeptList, report,comTimeType);
+                                if (errorMsg != null) {
+                                    HttpRespMsg msg = new HttpRespMsg();
+                                    msg.setError(errorMsg);
+                                    return msg;
+                                }
                                 if (taskId != null && taskId[i] != null && taskId[i] != 0) {
                                     report.setTaskId(taskId[i]);
                                 }
@@ -1401,7 +1411,12 @@ public class ReportController {
                         if (comTimeType.getReportAuditType() == 3) {
                             report.setAuditorSetting(auditorSettingList.get(i));
                         }
-                        setReportWorkflowAuditor(auditWorkflowList, allDeptList, report,comTimeType);
+                        String errorMsg = setReportWorkflowAuditor(auditWorkflowList, allDeptList, report,comTimeType);
+                        if (errorMsg != null) {
+                            HttpRespMsg msg = new HttpRespMsg();
+                            msg.setError(errorMsg);
+                            return msg;
+                        }
                         if (taskId != null && taskId[i] != null && taskId[i] != 0) {
                             report.setTaskId(taskId[i]);
                         }
@@ -1472,7 +1487,12 @@ public class ReportController {
                             } else {
                                 //并非并行审核模式下的代填,需要设置审核状态
                                 report.setState(0);
-                                setReportWorkflowAuditor(auditWorkflowList, allDeptList, report,comTimeType);
+                                String errorMsg = setReportWorkflowAuditor(auditWorkflowList, allDeptList, report,comTimeType);
+                                if (errorMsg != null) {
+                                    HttpRespMsg msg = new HttpRespMsg();
+                                    msg.setError(errorMsg);
+                                    return msg;
+                                }
                             }
                             if (taskId != null && taskId[i] != null && taskId[i] != 0) {
                                 report.setTaskId(taskId[i]);
@@ -1566,15 +1586,16 @@ public class ReportController {
                             double overTimeSum = reportList.stream().filter(rl -> rl.getCreateDate().equals(report.getCreateDate()) && rl.getCreatorId().equals(report.getCreatorId())).mapToDouble(Report::getOvertimeHours).sum();
                             UserCorpwxTime userCorpwxTime = userCorpwxTimeMapper.selectOne(new QueryWrapper<UserCorpwxTime>().ne("ot_status", 0).eq("corpwx_userid", curReporter.getCorpwxUserid()).eq("create_date", report.getCreateDate()));
                             if(overTimeSum > 0){
+                                double allowMoreThan = (company.getId() == Constant.XI_HE_CHAO_DAO_COMPANY_ID || company.getId() == Constant.XI_HE_CHAO_DAO_JIA_XING_COMPANY_ID) ? 2.001 : 0.001;//允许超过打卡中的加班时长的范围
                                 if (company.getPackageOvertime() == 1) {//启用了加班管理模块,去校验加班申请的时长
                                     Overtime overtime = overtimeMapper.selectOne(new QueryWrapper<Overtime>().select("sum(duration) as duration").eq("user_id", curReporter.getId()).eq("date", report.getCreateDate()).ne("status", -1).ne("status", 3).ne("status", 4));
                                     if (overtime == null) {
-                                        httpRespMsg.setError("请先补填加班申请单");
+                                        httpRespMsg.setError("尚无审核通过的加班单");
                                         return httpRespMsg;
                                     } else {
                                         double applyOvertime = 1.0*overtime.getDuration()/3600;//转化为小时
-                                        if (overTimeSum - applyOvertime > 0.001) {
-                                            httpRespMsg.setError("填报加班时长不得超过加班申请时长("+applyOvertime+"h)");
+                                        if (overTimeSum - applyOvertime > allowMoreThan) {
+                                            httpRespMsg.setError("填报加班时长不得超过加班申请时长("+applyOvertime+"h)" + (allowMoreThan > 0.001? "+2h" : ""));
                                             return httpRespMsg;
                                         }
                                     }
@@ -1582,9 +1603,11 @@ public class ReportController {
                                     if (userCorpwxTime == null || userCorpwxTime.getOtTime() == 0) {
                                         httpRespMsg.setError("未同步到企微加班时长,请先补填加班申请");
                                         return httpRespMsg;
-                                    } else if (overTimeSum - userCorpwxTime.getOtTime() > 0.001) {
-                                        httpRespMsg.setError("填报加班时长("+overTimeSum+"h)不得超过考勤加班时长("+userCorpwxTime.getOtTime()+"h)");
-                                        return httpRespMsg;
+                                    } else {
+                                        if (overTimeSum - userCorpwxTime.getOtTime() > allowMoreThan) {
+                                            httpRespMsg.setError("填报加班时长("+overTimeSum+"h)不得超过考勤加班时长("+userCorpwxTime.getOtTime()+"h)" + (allowMoreThan > 0.001? "+2h" : ""));
+                                            return httpRespMsg;
+                                        }
                                     }
                                 }
                             }
@@ -1874,38 +1897,28 @@ public class ReportController {
                     }
                 }
                 //针对羲合超导-合肥,校验加班时长不得超过加班申请单的时长。同理,只要加班申请单有记录就校验。不然不校验。
-                if (Constant.XI_HE_CHAO_DAO_COMPANY_ID == company.getId()) {
-                    //查找当前的填报的加班时长和数据库中的加班时长
-                    if (overtime > 0) {
-                        //存在加班时长的情况下,才去校验
-                        Overtime sumOverTimeApply = overtimeMapper.selectOne(new QueryWrapper<Overtime>().select("sum(duration) duration").eq("date", cDate).eq("user_id", creatorId));
-                        if (sumOverTimeApply != null) {
-                            if (sumOverTimeApply.getDuration() != null) {
-                                if (sumOverTimeApply.getDuration() < overtime*3600) {
-                                    HttpRespMsg httpRespMsg = new HttpRespMsg();
-                                    httpRespMsg.setError("合计加班时长"+overtime+"h不得超过加班申请单的时长"+sumOverTimeApply.getDuration()/3600+"h");
-                                    return httpRespMsg;
-                                } else {
-                                    //去查找数据库中已经填报的加班时长
-                                    Report oldReportSum = reportMapper.selectOne(new QueryWrapper<Report>().select("sum(overtime_hours) as overTime").eq("create_date", cDate).eq("creator_id", creatorId).gt("overtime_hours", 0));
-                                    if (oldReportSum != null) {
-                                        if (oldReportSum.getOvertimeHours() != null) {
-                                            if ((oldReportSum.getOvertimeHours() + overtime) * 3600 > sumOverTimeApply.getDuration()) {
-                                                HttpRespMsg httpRespMsg = new HttpRespMsg();
-                                                httpRespMsg.setError("合计加班时长"+(oldReportSum.getOvertimeHours() + overtime)+"h不得超过加班申请单的时长"+sumOverTimeApply.getDuration()/3600+"h");
-                                                return httpRespMsg;
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                        } else {
-                            HttpRespMsg httpRespMsg = new HttpRespMsg();
-                            httpRespMsg.setError(cDate.toString()+"的加班申请单不存在,无法填报加班日报");
-                            return httpRespMsg;
-                        }
-                    }
-                }
+//                if (Constant.XI_HE_CHAO_DAO_COMPANY_ID == company.getId()) {
+//                    //查找当前的填报的加班时长和数据库中的加班时长
+//                    if (overtime > 0) {
+//                        //存在加班时长的情况下,才去校验
+//                        Overtime sumOverTimeApply = overtimeMapper.selectOne(new QueryWrapper<Overtime>().select("sum(duration) duration").eq("date", cDate).eq("user_id", creatorId));
+//                        if (sumOverTimeApply != null) {
+//                            if (sumOverTimeApply.getDuration() != null) {
+//                                if (sumOverTimeApply.getDuration() < overtime*3600) {
+//                                    HttpRespMsg httpRespMsg = new HttpRespMsg();
+//                                    httpRespMsg.setError("合计加班时长"+overtime+"h不得超过加班申请单的时长"+sumOverTimeApply.getDuration()/3600+"h");
+//                                    return httpRespMsg;
+//                                } else {
+//
+//                                }
+//                            }
+//                        } else {
+//                            HttpRespMsg httpRespMsg = new HttpRespMsg();
+//                            httpRespMsg.setError(cDate.toString()+"的加班申请单不存在,无法填报加班日报");
+//                            return httpRespMsg;
+//                        }
+//                    }
+//                }
 
                 //HardCode:对于正北两家公司,校验填报工时不得少于考勤时长。(代填的不校验)
                 if ((SysConstant.ZhengBeiCompIds.contains(company.getId())) && (report.getFillUserid() == null || creatorId.equals(report.getFillUserid()))) {
@@ -2457,6 +2470,12 @@ public class ReportController {
             for (Report report : reportList) {
                 Optional<Project> first = projectList.stream().filter(pl -> pl.getId().equals(report.getProjectId())).findFirst();
                 if (first.isPresent()) {
+                    LocalDate planStartDate = first.get().getPlanStartDate();
+                    if (planStartDate != null && planStartDate.isAfter(report.getCreateDate())) {
+                        HttpRespMsg msg = new HttpRespMsg();
+                        msg.setError("项目["+first.get().getProjectName()+"]于"+dateTimeFormatter.format(planStartDate)+"开始,不得提前填报");
+                        return msg;
+                    }
                     LocalDate planEndDate = first.get().getPlanEndDate();
                     if (planEndDate != null && planEndDate.isBefore(report.getCreateDate())) {
                         HttpRespMsg msg = new HttpRespMsg();
@@ -2513,9 +2532,8 @@ public class ReportController {
             if (companySetAutoApprove) {
                 List<String> reportIds = reportList.stream().map(Report::getId).map(String::valueOf).collect(Collectors.toList());
                 //直接修改状态为审核通过
-//            reportMapper.update(new Report().setState(1), new LambdaQueryWrapper<Report>().in(Report::getId, reportIds));
                 String rIds = reportIds.stream().collect(Collectors.joining(","));
-                approveReport(rIds, 0, request, null);
+                reportService.autoApproveReport(rIds);
             } else if (company.getId() == 862 || company.getId() == 3344 || company.getId() == 936 || comTimeType.getAutoProjectApprove()) {
                 //项目审核人是提交人的情况,直接审核
                 List<String> reportIds = new ArrayList<>();
@@ -2790,7 +2808,8 @@ public class ReportController {
         }
     }
 
-    private void setReportWorkflowAuditor(List<AuditWorkflowTimeSetting> auditWorkflowList, List<Department> allDeptList, Report report, TimeType comTimeType) {
+    private String setReportWorkflowAuditor(List<AuditWorkflowTimeSetting> auditWorkflowList, List<Department> allDeptList, Report report, TimeType comTimeType) {
+        String errorMsg = null;
         //增加没有开通审批流的判断
         if (comTimeType.getReportWorkflow() == 0 || comTimeType.getReportAuditType() > 1 || auditWorkflowList.size() == 0) {
             //没有自定义审核流,默认的直接是项目负责人审核
@@ -2824,8 +2843,13 @@ public class ReportController {
                 } else {
                     report.setAuditDeptManagerid(curDeptManagerId);
                 }
+                if (report.getAuditDeptManagerid() == null) {
+                    //没有设置好审核人
+                    errorMsg = "员工所在部门尚未设置主要负责人";
+                }
             }
         }
+         return errorMsg;
     }
 
     /**

+ 33 - 6
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserCorpwxTimeController.java

@@ -1774,7 +1774,12 @@ public class UserCorpwxTimeController {
             // 处理第二个sheet:人员分配
             Sheet staffSheet = workbook.getSheetAt(1);
             System.out.println("正在处理第二个Sheet: " + staffSheet.getSheetName() + " (人员分配)");
-            List<Map<String, Object>> staffAllocationResult = processStaffAllocationSheet(year, staffSheet, companyId, allUserList);
+            HttpRespMsg staffAllocationMsg = processStaffAllocationSheet(year, staffSheet, companyId, allUserList);
+            if (staffAllocationMsg.code.equals("error")) {
+                //解析返回错误了,需要中断直接返回。
+                return staffAllocationMsg;
+            }
+            List<Map<String, Object>> staffAllocationResult = (List<Map<String, Object>>)staffAllocationMsg.data;
             //检查系统中是否存在表格中员工没有参与的项目
             List<Project> projectList = projectMapper.selectList(new QueryWrapper<Project>().eq("company_id", companyId));
             List<Participation> participationList = participationMapper.selectList(new QueryWrapper<Participation>().in("project_id", projectList.stream().map(Project::getId).collect(Collectors.toList())));
@@ -2153,12 +2158,13 @@ public class UserCorpwxTimeController {
      * 前面7列是合并的多行数据,形成人员-项目的一对多关系,项目和月份又是一对多的关系
      * 返回员工-项目-可填月份的数据集合
      */
-    private List<Map<String, Object>> processStaffAllocationSheet(Integer startYear,Sheet staffSheet, Integer companyId, List<User> allUserList) {
+    private HttpRespMsg processStaffAllocationSheet(Integer startYear,Sheet staffSheet, Integer companyId, List<User> allUserList) {
+        HttpRespMsg msg = new HttpRespMsg();
         List<Map<String, Object>> result = new ArrayList<>();
         
         if (staffSheet.getLastRowNum() == 0) {
-            System.out.println("人员分配sheet中没有数据");
-            return result;
+            msg.setError("人员分配sheet中没有数据");
+            return msg;
         }
         
         // 解析表头,获取月份信息(从第12列开始)
@@ -2167,6 +2173,17 @@ public class UserCorpwxTimeController {
         LocalDate now = LocalDate.now();
         int startYearColIndex = -1;
         if (headerRow != null) {
+            String[] headerColumnFixed = new String[]{"序号", "姓名", "账号", "全职/兼职", "工种", "个人项目研发最晚结束时间", "入职时间"};
+            for (int colIndex = 0; colIndex < headerColumnFixed.length; colIndex++) {
+                Cell cell = headerRow.getCell(colIndex);
+                if (cell != null) {
+                    String cellValue = cell.getStringCellValue().trim();
+                    if (!cellValue.equals(headerColumnFixed[colIndex])) {
+                        msg.setError("人员分配表头不正确 ,第"+(colIndex+1)+"列应为["+headerColumnFixed[colIndex]+"]");
+                        return msg;
+                    }
+                }
+            }
             for (int colIndex = 11; colIndex < 11 + 24; colIndex++) { // 第12列开始(索引11)
                 Cell cell = headerRow.getCell(colIndex);
                 if (cell != null) {
@@ -2183,7 +2200,10 @@ public class UserCorpwxTimeController {
         }
         
         System.out.println("找到月份列: " + monthColumns);
-        if (monthColumns.size() == 0) return result;
+        if (monthColumns.size() == 0) {
+            msg.setError("找不到月份列");
+            return msg;
+        }
         // 收集所有员工姓名用于批量查询
         List<String> userNameList = new ArrayList<>();
         for (int rowIndex = 1; rowIndex <= staffSheet.getLastRowNum(); rowIndex++) {
@@ -2353,6 +2373,8 @@ public class UserCorpwxTimeController {
             } catch (Exception e) {
                 System.out.println("处理第" + (rowIndex + 1) + "行人员分配数据时出错: " + e.getMessage());
                 e.printStackTrace();
+                msg.setError("处理第" + (rowIndex + 1) + "行人员分配数据时出错: " + e.getMessage());
+                return msg;
             }
         }
         
@@ -2367,13 +2389,18 @@ public class UserCorpwxTimeController {
         // 打印未找到的用户
         if (!missingUser.isEmpty()) {
             System.out.println("未找到的用户:");
+            String strbuilder = "";
             for (User user : missingUser) {
                 System.out.println("姓名: " + user.getName() + ", 工号: " + user.getJobNumber());
+                strbuilder += "姓名: " + user.getName() + ", 工号: " + user.getJobNumber() + "\n";
             }
+            msg.setError("未找到的用户:" + strbuilder);
+            return msg;
         }
         
         System.out.println("处理完成,共生成 " + result.size() + " 条员工-项目-月份分配记录");
-        return result;
+        msg.setData(result);
+        return msg;
     }
     
     /**

+ 1 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/WxCorpInfoController.java

@@ -198,7 +198,7 @@ public class WxCorpInfoController {
             queryWrapper.eq("creator_id", userId);
         }
         List<Report> reportList = reportMapper.selectList(queryWrapper);
-        int time = reportList.size() / 100 + 1;
+        int time = reportList.size() / 1000 + 1;
         wxCorpInfoService.handleUserAllowanceByReport(reportList);
         msg.msg = "刷新餐补任务进行中...,请稍后检查报表, 大约需要" + time + "分钟";
         return msg;

+ 1 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/OvertimeAllowance.java

@@ -84,7 +84,7 @@ public class OvertimeAllowance extends Model<OvertimeAllowance> {
     private Integer companyId;
 
     /**
-     * 0-白班加班3.0小时, 1- 白班加班超过12点,2-小夜班,3-大夜班,4-非工作日加班,全天加班
+     * 0-白班加班3.0小时, 1- 白班加班超过12点,2-小夜班,3-大夜班,4-非工作日加班,全天加班, 跨天并且是第二天凌晨4点以后下班,补贴50
      */
     @TableField("type")
     private Integer type;

+ 6 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/TimeType.java

@@ -3,6 +3,7 @@ package com.management.platform.entity;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.sun.org.apache.xpath.internal.operations.Bool;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
@@ -727,6 +728,11 @@ public class TimeType extends Model<TimeType> {
     @TableField("is_project_closure")
     private Integer isProjectClosure;
 
+    /**
+     * 工时录入是否为正常工时
+     */
+    @TableField("time_input_normal")
+    private Boolean timeInputNormal;
 
 
     @TableField(exist = false)

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

@@ -51,6 +51,7 @@ public interface ReportService extends IService<Report> {
                                HttpServletRequest request);
 
     HttpRespMsg approveReport(String reportIds, Integer isDepartment, HttpServletRequest request,String evaluate);
+    HttpRespMsg autoApproveReport(String reportIds);
 
     HttpRespMsg denyReport(String date, String reportIds, String reason, Integer isDepartment, HttpServletRequest request);
 

+ 463 - 205
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -1585,7 +1585,11 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 if (wxCorpInfo != null) {
                     List<String> auditorCorpwxUserids = new ArrayList<>();
                     for (Report report : reportList) {
-                        String corpwxUserid = userMapper.selectById((report.getIsDeptAudit() == null || report.getIsDeptAudit() == 0)?report.getProjectAuditorId():report.getAuditDeptManagerid()).getCorpwxUserid();
+                        User auditor = userMapper.selectById((report.getIsDeptAudit() == null || report.getIsDeptAudit() == 0)?report.getProjectAuditorId():report.getAuditDeptManagerid());
+                        if (auditor == null) {
+                            System.err.println("审核人尚未设置,report.getIsDeptAudit()="+report.getIsDeptAudit()+", report.getProjectAuditorId()="+report.getProjectAuditorId() + ", report.getAuditDeptManagerid()="+report.getAuditDeptManagerid() + ", deptId=" + report.getDeptId());
+                        }
+                        String corpwxUserid = auditor.getCorpwxUserid();
                         //推送到企业微信
                         JSONObject json=new JSONObject();
                         JSONArray dataJson=new JSONArray();
@@ -3754,6 +3758,56 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         return httpRespMsg;
     }
 
+    @Override
+    public HttpRespMsg autoApproveReport(String reportIds) {
+        //默认按照项目日报审核人的模式进行审核
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        User userCompany = userMapper.selectById(token);
+        Integer companyId = userCompany.getCompanyId();
+        Company company = companyMapper.selectById(companyId);
+        final List<Integer> ids = ListUtil.convertIntegerIdsArrayToList(reportIds);
+        Report oneReport = reportMapper.selectById(ids.get(0));
+        reportMapper.update(new Report().setState(1).setProjectAuditState(1).setProjectAuditTime(LocalDateTime.now()),
+                new QueryWrapper<Report>().in("id", ids));
+
+        List<Report> reportList = reportMapper.selectList(new QueryWrapper<Report>().in("id", ids));
+        List<Integer> collect = reportList.stream().map(rl -> rl.getProjectId()).distinct().collect(Collectors.toList());
+        List<Project> projectList = projectMapper.selectList(new QueryWrapper<Project>().in("id", collect));
+        List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId));
+        String pNames = projectList.stream().map(Project::getProjectName).collect(Collectors.joining(", ", "[", "]"));
+        //按项目拆分,每个项目审核一次
+        for (Project project : projectList) {
+            Report curReport = reportList.stream().filter(one->one.getProjectId().equals(project.getId())).findFirst().get();
+            User auditor = userList.stream().filter(u->u.getId().equals(curReport.getProjectAuditorId())).findFirst().orElse(null);
+            if (auditor != null) {
+                ReportAuditLog log = new ReportAuditLog();
+                log.setAuditChannel(0);
+                log.setCompanyId(company.getId());
+                log.setResult(MessageUtils.message("profession.approved"));
+                log.setUserId(auditor.getId());
+                log.setUserName(auditor.getName());
+                log.setProjectName(pNames);
+                if (pNames.length() > 2000) {
+                    log.setProjectName(pNames.substring(0, 2000));
+                }
+                reportAuditLogMapper.insert(log);
+                //员工的日期
+                ReportAlogMembdate membdate = new ReportAlogMembdate();
+                membdate.setRlogId(log.getId());
+                membdate.setState(1);//通过
+                membdate.setCreateDate(oneReport.getCreateDate());
+                membdate.setUserId(oneReport.getCreatorId());
+                membdate.setUserName(userMapper.selectById(oneReport.getCreatorId()).getName());
+                reportAlogMembdateMapper.insert(membdate);
+
+                //日报的审核过程记录
+                saveApproveReportLog(company.getId(), reportList, auditor.getId(), auditor.getName());
+            }
+        }
+        return httpRespMsg;
+    }
+
 
     private String getTokenOfYiWei(){
         String url = "http://183.194.0.98:3202/api/web-server/controlCenter/token";
@@ -10032,53 +10086,56 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         HttpRespMsg msg = new HttpRespMsg();
         String userId = request.getHeader("TOKEN");
         User user = userMapper.selectById(userId);
-        //根据targetDate获取本周的日期
-        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
-        LocalDate date = LocalDate.parse(targetDate, dtf);
-        LocalDate firstDayOfWeek = date.with(DayOfWeek.MONDAY);
-        //需要填报的最后一天
-        LocalDate lastDayOfWeek = date.with(DayOfWeek.SUNDAY);
-//        int days = sunday.lengthOfMonth() - sunday.getDayOfMonth();
-//        if (days <= 3) {
-//            //周日距离月底相差天数在3天以内,比如周日是10.28,则10.29,10.30和10.31也算在本周内
-//            lastDayOfWeek = sunday.plusDays(days);
-//        }
-        //如果上周只有2天以内工作日,需要并到这周来
-//        LocalDate lastSunday = firstDayOfWeek.minusDays(1);
-//        LocalDate lastSaturday = lastSunday.with(DayOfWeek.SATURDAY);
-
-//        if (WorkDayCalculateUtils.isWorkDay(lastSunday) && WorkDayCalculateUtils.isWorkDay(lastSaturday)) {
-//            //合并上周的工作日的情况:上周周末两天是工作日,并且只有2天以内工作日,需要并到这周来
-//            LocalDate lastMonday = lastSunday.with(DayOfWeek.MONDAY);
-//            boolean hasMoreWorkDays = false;
-//            while (lastMonday.isBefore(lastSaturday)) {
-//                if (WorkDayCalculateUtils.isWorkDay(lastMonday)) {
-//                    hasMoreWorkDays = true;
-//                    break;
-//                }
-//                lastMonday = lastMonday.plusDays(1);
-//            }
-//            if (!hasMoreWorkDays) {
-//                firstDayOfWeek = lastSaturday;
-//            }
-//        } else {
-//            //剔除被合并到上周的情况,如果本周一周二周三中有工作日,但是是上个月的月末,会被合并到上周去,本周要去掉
-//            boolean hasFirstDayOfMonth = false;
-//            LocalDate checkDate = firstDayOfWeek;
-//            int beforeDays = 0;
-//            while (!checkDate.isAfter(lastDayOfWeek)) {
-//                if (checkDate.getDayOfMonth() == 1) {
-//                    hasFirstDayOfMonth = true;
-//                    break;
-//                } else {
-//                    beforeDays++;
-//                }
-//                checkDate = checkDate.plusDays(1);
-//            }
-//            if (hasFirstDayOfMonth && beforeDays <= 3) {
-//                firstDayOfWeek = checkDate;
-//            }
-//        }
+        TimeType timeType = timeTypeMapper.selectById(user.getCompanyId());
+        if (timeType.getEnableNewWeeklyfill() == 1) {
+            //根据targetDate获取本周的日期
+            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+            LocalDate date = LocalDate.parse(targetDate, dtf);
+            LocalDate firstDayOfWeek = date.with(DayOfWeek.MONDAY);
+            LocalDate sunday = date.with(DayOfWeek.SUNDAY);
+            //需要填报的最后一天
+            LocalDate lastDayOfWeek = sunday;
+            int days = sunday.lengthOfMonth() - sunday.getDayOfMonth();
+            if (days <= 3) {
+                //周日距离月底相差天数在3天以内,比如周日是10.28,则10.29,10.30和10.31也算在本周内
+                lastDayOfWeek = sunday.plusDays(days);
+            }
+            //如果上周只有2天以内工作日,需要并到这周来
+            LocalDate lastSunday = firstDayOfWeek.minusDays(1);
+            LocalDate lastSaturday = lastSunday.with(DayOfWeek.SATURDAY);
+
+            if (WorkDayCalculateUtils.isWorkDay(lastSunday) && WorkDayCalculateUtils.isWorkDay(lastSaturday)) {
+                //合并上周的工作日的情况:上周周末两天是工作日,并且只有2天以内工作日,需要并到这周来
+                LocalDate lastMonday = lastSunday.with(DayOfWeek.MONDAY);
+                boolean hasMoreWorkDays = false;
+                while (lastMonday.isBefore(lastSaturday)) {
+                    if (WorkDayCalculateUtils.isWorkDay(lastMonday)) {
+                        hasMoreWorkDays = true;
+                        break;
+                    }
+                    lastMonday = lastMonday.plusDays(1);
+                }
+                if (!hasMoreWorkDays) {
+                    firstDayOfWeek = lastSaturday;
+                }
+            } else {
+                //剔除被合并到上周的情况,如果本周一周二周三中有工作日,但是是上个月的月末,会被合并到上周去,本周要去掉
+                boolean hasFirstDayOfMonth = false;
+                LocalDate checkDate = firstDayOfWeek;
+                int beforeDays = 0;
+                while (!checkDate.isAfter(lastDayOfWeek)) {
+                    if (checkDate.getDayOfMonth() == 1) {
+                        hasFirstDayOfMonth = true;
+                        break;
+                    } else {
+                        beforeDays++;
+                    }
+                    checkDate = checkDate.plusDays(1);
+                }
+                if (hasFirstDayOfMonth && beforeDays <= 3) {
+                    firstDayOfWeek = checkDate;
+                }
+            }
 
 //        if (WorkDayCalculateUtils.isWorkDay(firstDayOfWeek) && firstDayOfWeek.getDayOfMonth() >= 30) {
 //            firstDayOfWeek = firstDayOfWeek.plusDays(1);
@@ -10086,96 +10143,297 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
 //                firstDayOfWeek = firstDayOfWeek.plusDays(1);
 //            }
 //        }
-        //死代码 2025-01-27 周一 合并到1-26号那一周
-//        LocalDate specialDate = LocalDate.of(2025, 1, 27);
-//        if(lastDayOfWeek.plusDays(1).isEqual(specialDate)){
-//            lastDayOfWeek = specialDate;
-//        }
+            //死代码 2025-01-27 周一 合并到1-26号那一周
+            LocalDate specialDate = LocalDate.of(2025, 1, 27);
+            if(lastDayOfWeek.plusDays(1).isEqual(specialDate)){
+                lastDayOfWeek = specialDate;
+            }
 
 
 
-        //再按照当前用户的入职离职日期进行过滤
-        LocalDate entryDate = user.getInductionDate();
-        LocalDate leaveDate = user.getInactiveDate();
-        boolean needFill = true;
-        if (entryDate != null && entryDate.isAfter(firstDayOfWeek)) {
-            if (lastDayOfWeek.isBefore(entryDate)) {
-                //最后一天也在入职日期之前,不需要填报
-                needFill = false;
-            } else {
-                firstDayOfWeek = entryDate;
-            }
-        }
-        if (user.getIsActive()==0 && leaveDate != null && leaveDate.isBefore(lastDayOfWeek)) {
-            lastDayOfWeek = leaveDate;
-        }
-        Map<String, Object> reportMap = new HashMap<>();
-        if (needFill) {
-            String summary = null;
-            String attachment = null;
-            String startDate = firstDayOfWeek.format(dtf);
-            String endDate = lastDayOfWeek.format(dtf);
-            TimeType timeType = timeTypeMapper.selectById(user.getCompanyId());
-            //获取日报详情
-            List<Report> reportList = reportMapper.selectList(new QueryWrapper<Report>().eq("creator_id", userId).between("create_date", startDate, endDate).orderByAsc("create_date"));
-            //已填日报设置审核人姓名
-            if (reportList.size() > 0) {
-                Integer batchId = reportList.get(0).getBatchId();
-                if (batchId != null) {
-                    //获取周总结
-                    ReportBatch batch = reportBatchMapper.selectById(batchId);
-                    //老数据可能出现batchId错误的情况,已经被删掉了,就不处理了。
-                    if (batch != null) {
-                        summary = batch.getSummary();
-                        attachment = batch.getAttachment();
-                    }
-                }
-                List<String> collect = reportList.stream().map(Report::getProjectAuditorId).distinct().collect(Collectors.toList());
-                if (collect.size() > 0) {
-                    List<User> auditorUserList = userMapper.selectList(new QueryWrapper<User>().in("id", collect));
-                    reportList.forEach(r->{
-                        if (r.getProjectAuditorId() != null) {
-                            Optional<User> first = auditorUserList.stream().filter(au -> au.getId().equals(r.getProjectAuditorId())).findFirst();
-                            if (first.isPresent()) {
-                                r.setProjectAuditorName(first.get().getName());
+            //再按照当前用户的入职离职日期进行过滤
+            LocalDate entryDate = user.getInductionDate();
+            LocalDate leaveDate = user.getInactiveDate();
+            boolean needFill = true;
+            if (entryDate != null && entryDate.isAfter(firstDayOfWeek)) {
+                if (lastDayOfWeek.isBefore(entryDate)) {
+                    //最后一天也在入职日期之前,不需要填报
+                    needFill = false;
+                } else {
+                    firstDayOfWeek = entryDate;
+                }
+            }
+            if (user.getIsActive()==0 && leaveDate != null && leaveDate.isBefore(lastDayOfWeek)) {
+                lastDayOfWeek = leaveDate;
+            }
+            Map<String, Object> reportMap = new HashMap<>();
+            if (needFill) {
+                String summary = null;
+                String attachment = null;
+                String startDate = firstDayOfWeek.format(dtf);
+                String endDate = lastDayOfWeek.format(dtf);
+                //获取日报详情
+                List<Report> reportList = reportMapper.selectList(new QueryWrapper<Report>().eq("creator_id", userId).between("create_date", startDate, endDate).orderByAsc("create_date"));
+                //已填日报设置审核人姓名
+                if (reportList.size() > 0) {
+                    Integer batchId = reportList.get(0).getBatchId();
+                    if (batchId != null) {
+                        //获取周总结
+                        ReportBatch batch = reportBatchMapper.selectById(batchId);
+                        //老数据可能出现batchId错误的情况,已经被删掉了,就不处理了。
+                        if (batch != null) {
+                            summary = batch.getSummary();
+                            attachment = batch.getAttachment();
+                        }
+                    }
+                    List<String> collect = reportList.stream().map(Report::getProjectAuditorId).distinct().collect(Collectors.toList());
+                    if (collect.size() > 0) {
+                        List<User> auditorUserList = userMapper.selectList(new QueryWrapper<User>().in("id", collect));
+                        reportList.forEach(r->{
+                            if (r.getProjectAuditorId() != null) {
+                                Optional<User> first = auditorUserList.stream().filter(au -> au.getId().equals(r.getProjectAuditorId())).findFirst();
+                                if (first.isPresent()) {
+                                    r.setProjectAuditorName(first.get().getName());
+                                }
                             }
-                        }
-                    });
+                        });
+                    }
                 }
-            }
 
 
-            List<Integer> collect = reportList.stream().map(Report::getProjectId).collect(Collectors.toList());
-            final List<ReportExtraDegree> degreeList = reportExtraDegreeMapper.selectList(new QueryWrapper<ReportExtraDegree>().eq("company_id", user.getCompanyId()));
+                List<Integer> collect = reportList.stream().map(Report::getProjectId).collect(Collectors.toList());
+                final List<ReportExtraDegree> degreeList = reportExtraDegreeMapper.selectList(new QueryWrapper<ReportExtraDegree>().eq("company_id", user.getCompanyId()));
 
-            //加载这段时间内已填报过的项目
-            List<Project> projectList = new ArrayList<>();
-            if (collect.size() > 0) {
-                projectList = projectMapper.selectList(new QueryWrapper<Project>().in("id", collect));
-                final List<Project> finalProjectList = projectList;
-                //获取项目的任务分组列表
-
-
-                QueryWrapper<TaskGroup> taskGroupQueryWrapper = new QueryWrapper<TaskGroup>().in("project_id", collect);
-                if (timeType.getReportAuditType() == 1) {//分组负责人审核模式,需要按参与的任务分组显示
+                //加载这段时间内已填报过的项目
+                List<Project> projectList = new ArrayList<>();
+                if (collect.size() > 0) {
+                    projectList = projectMapper.selectList(new QueryWrapper<Project>().in("id", collect));
+                    final List<Project> finalProjectList = projectList;
+                    //获取项目的任务分组列表
                     //需要是他参与的任务分组
                     List<GroupParticipator> groupParticipatorList = groupParticipatorMapper.selectList(new QueryWrapper<GroupParticipator>().eq("user_id", userId));
                     List<Integer> joinGroupList = groupParticipatorList.stream().map(GroupParticipator::getGroupId).collect(Collectors.toList());
                     if (joinGroupList.size() > 0) {
-                        taskGroupQueryWrapper.in("id", joinGroupList);
-                    } else {
-                        taskGroupQueryWrapper.eq("id", -1);//没有分组
+                        List<TaskGroup> taskGroups = taskGroupMapper.selectList(new QueryWrapper<TaskGroup>().in("project_id", collect).in("id", joinGroupList));
+                        //获取负责人的用户集合
+                        List<String> inchargerIds = taskGroups.stream().map(TaskGroup::getInchargerId).collect(Collectors.toList());
+                        if (inchargerIds.size() == 0) {
+                            inchargerIds.add("-1");
+                        }
+                        List<User> userList = userMapper.selectList(new QueryWrapper<User>().in("id", inchargerIds));
+                        reportList.forEach(r->{
+                            r.setTaskGroups(taskGroups.stream().filter(tg->tg.getProjectId().equals(r.getProjectId())).collect(Collectors.toList()));
+                            for (TaskGroup gp : r.getTaskGroups()) {
+                                if (!StringUtils.isEmpty(gp.getInchargerId()) ) {
+                                    if (gp.getInchargerId().equals(userId)) {
+                                        //自己担任任务分组的负责人,自己的审核人是项目经理
+                                        gp.setInchargerId(projectMapper.selectById(r.getProjectId()).getInchargerId());
+                                        //如果自己就是项目经理,审核人变成自己的部门负责人
+                                        if (gp.getInchargerId().equals(userId)) {
+                                            Integer dpId = user.getDepartmentId();
+                                            if (dpId != null && dpId > 0) {
+                                                Department department = departmentMapper.selectById(dpId);
+                                                if (department != null) {
+                                                    gp.setInchargerId(department.getManagerId());
+                                                }
+                                            }
+                                        }
+                                        //不存在的话,加上项目经理
+                                        if (!userList.stream().anyMatch(u->u.getId().equals(gp.getInchargerId()))) {
+                                            userList.add(userMapper.selectById(gp.getInchargerId()));
+                                        }
+                                    }
+                                    Optional<User> first = userList.stream().filter(u -> u.getId().equals(gp.getInchargerId())).findFirst();
+                                    if (first.isPresent()) {
+                                        gp.setInchargerName(first.get().getName());
+                                    }
+                                }
+                            }
+                            //设置项目名称
+                            Optional<Project> optional = finalProjectList.stream().filter(p->p.getId().equals(r.getProjectId())).findFirst();
+                            if (optional.isPresent()) {
+                                r.setProjectName(optional.get().getProjectName());
+                            }
+                            //设置自定义维度
+                            if (timeType.getCustomDegreeActive() == 1) {
+                                if (timeType.getCustomDegreeWithPro() == 1) {
+                                    String associateDegrees = optional.get().getAssociateDegrees();
+                                    List<HashMap> degreeMapList = new ArrayList<>();
+                                    if (associateDegrees != null) {
+                                        String[] split = associateDegrees.split("\\,");
+                                        for (int i=0;i<split.length; i++) {
+                                            HashMap map = new HashMap();
+                                            if (!StringUtils.isEmpty(split[i])) {
+                                                Integer id = Integer.parseInt(split[i]);
+                                                map.put("id", id);
+                                                map.put("name", degreeList.stream().filter(d->d.getId().equals(id)).findFirst().get().getName());
+                                                degreeMapList.add(map);
+                                            }
+                                        }
+                                    }
+                                    r.setDegreeList(degreeMapList);
+                                } else {
+                                    //把degreeList改成HashMap结构
+                                    List<HashMap> mapDegreeList = new ArrayList<>();
+                                    for (ReportExtraDegree degree : degreeList) {
+                                        HashMap map = new HashMap();
+                                        map.put("id", degree.getId());
+                                        map.put("name", degree.getName());
+                                        mapDegreeList.add(map);
+                                    }
+                                    r.setDegreeList(mapDegreeList);
+                                }
+                            }
+                        });
+                    }
+                }
+
+                reportMap.put("projectList", projectList);
+                //计算日期,进行返回
+                List<HashMap> dateList = new ArrayList<>();
+                LocalDate today = LocalDate.now();
+                LocalDate itemDate = firstDayOfWeek;
+                while(true) {
+                    if (WorkDayCalculateUtils.isWorkDay(itemDate)) {
+                        HashMap item = new HashMap();
+                        item.put("date", itemDate.format(dtf));
+                        //计算显示的周几
+                        item.put("weekDayTxt", DateTimeUtil.getWeekDayTxt(itemDate.getDayOfWeek().getValue()));
+                        //不可提前填报
+                        if (timeType.getFillAhead() == 0 && itemDate.isAfter(today)) {
+                            item.put("canFill", 0);
+                        } else {
+                            item.put("canFill", 1);
+                        }
+                        //放入当天对应的日报
+                        final LocalDate finalItemDate = itemDate;
+                        List<Report> dateReportList = reportList.stream().filter(r -> r.getCreateDate().isEqual(finalItemDate)).collect(Collectors.toList());
+                        item.put("reportList", dateReportList);
+                        double sum = dateReportList.stream().mapToDouble(Report::getWorkingTime).sum();
+                        item.put("filledTime", sum);
+                        dateList.add(item);
+                    }
+                    //往后推一天
+                    itemDate = itemDate.plusDays(1);
+                    //超过最后一天了,跳出循环
+                    if (itemDate.isAfter(lastDayOfWeek)) {
+                        break;
                     }
                 }
-                List<TaskGroup> taskGroups = taskGroupMapper.selectList(taskGroupQueryWrapper);
-                //获取负责人的用户集合
-                List<String> inchargerIds = taskGroups.stream().map(TaskGroup::getInchargerId).collect(Collectors.toList());
-                if (inchargerIds.size() == 0) {
-                    inchargerIds.add("-1");
+                //241226 当日期为 25-01-27 周一 时,去掉列表
+                if(firstDayOfWeek.isEqual(specialDate)){
+                    dateList = new ArrayList<>();
                 }
-                List<User> userList = userMapper.selectList(new QueryWrapper<User>().in("id", inchargerIds));
-                reportList.forEach(r->{
-                    r.setTaskGroups(taskGroups.stream().filter(tg->tg.getProjectId().equals(r.getProjectId())).collect(Collectors.toList()));
+                reportMap.put("dateList", dateList);
+                //查询考勤请假状态
+                WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", user.getCompanyId()));
+                if (wxCorpInfo != null && dateList.size() > 0) {
+                    List<UserCorpwxTime> userCorpwxTimeList = userCorpwxTimeMapper.selectList(new QueryWrapper<UserCorpwxTime>().eq("corpwx_userid", user.getCorpwxUserid()).in("create_date", dateList.stream().map(r -> (String) r.get("date")).collect(Collectors.toList())));
+                    for (HashMap item : dateList) {
+                        String curDate = (String) item.get("date");
+                        UserCorpwxTime userCorpwxTime = userCorpwxTimeList.stream().filter(r -> r.getCreateDate().isEqual(LocalDate.parse(curDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")))).findFirst().orElse(null);
+                        if (userCorpwxTime != null) {
+                            item.put("time", userCorpwxTime);
+                        }
+                    }
+                }
+                reportMap.put("summary", summary);
+                reportMap.put("weeklyAttachment", attachment);
+            } else {
+                reportMap.put("dateList", new ArrayList());
+            }
+
+            msg.data = reportMap;
+            return msg;
+        } else {
+            //根据targetDate获取本周的日期
+            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+            LocalDate date = LocalDate.parse(targetDate, dtf);
+            LocalDate firstDayOfWeek = date.with(DayOfWeek.MONDAY);
+            //需要填报的最后一天
+            LocalDate lastDayOfWeek = date.with(DayOfWeek.SUNDAY);
+
+            //再按照当前用户的入职离职日期进行过滤
+            LocalDate entryDate = user.getInductionDate();
+            LocalDate leaveDate = user.getInactiveDate();
+            boolean needFill = true;
+            if (entryDate != null && entryDate.isAfter(firstDayOfWeek)) {
+                if (lastDayOfWeek.isBefore(entryDate)) {
+                    //最后一天也在入职日期之前,不需要填报
+                    needFill = false;
+                } else {
+                    firstDayOfWeek = entryDate;
+                }
+            }
+            if (user.getIsActive()==0 && leaveDate != null && leaveDate.isBefore(lastDayOfWeek)) {
+                lastDayOfWeek = leaveDate;
+            }
+            Map<String, Object> reportMap = new HashMap<>();
+            if (needFill) {
+                String summary = null;
+                String attachment = null;
+                String startDate = firstDayOfWeek.format(dtf);
+                String endDate = lastDayOfWeek.format(dtf);
+                //获取日报详情
+                List<Report> reportList = reportMapper.selectList(new QueryWrapper<Report>().eq("creator_id", userId).between("create_date", startDate, endDate).orderByAsc("create_date"));
+                //已填日报设置审核人姓名
+                if (reportList.size() > 0) {
+                    Integer batchId = reportList.get(0).getBatchId();
+                    if (batchId != null) {
+                        //获取周总结
+                        ReportBatch batch = reportBatchMapper.selectById(batchId);
+                        //老数据可能出现batchId错误的情况,已经被删掉了,就不处理了。
+                        if (batch != null) {
+                            summary = batch.getSummary();
+                            attachment = batch.getAttachment();
+                        }
+                    }
+                    List<String> collect = reportList.stream().map(Report::getProjectAuditorId).distinct().collect(Collectors.toList());
+                    if (collect.size() > 0) {
+                        List<User> auditorUserList = userMapper.selectList(new QueryWrapper<User>().in("id", collect));
+                        reportList.forEach(r->{
+                            if (r.getProjectAuditorId() != null) {
+                                Optional<User> first = auditorUserList.stream().filter(au -> au.getId().equals(r.getProjectAuditorId())).findFirst();
+                                if (first.isPresent()) {
+                                    r.setProjectAuditorName(first.get().getName());
+                                }
+                            }
+                        });
+                    }
+                }
+
+
+                List<Integer> collect = reportList.stream().map(Report::getProjectId).collect(Collectors.toList());
+                final List<ReportExtraDegree> degreeList = reportExtraDegreeMapper.selectList(new QueryWrapper<ReportExtraDegree>().eq("company_id", user.getCompanyId()));
+
+                //加载这段时间内已填报过的项目
+                List<Project> projectList = new ArrayList<>();
+                if (collect.size() > 0) {
+                    projectList = projectMapper.selectList(new QueryWrapper<Project>().in("id", collect));
+                    final List<Project> finalProjectList = projectList;
+                    //获取项目的任务分组列表
+
+
+                    QueryWrapper<TaskGroup> taskGroupQueryWrapper = new QueryWrapper<TaskGroup>().in("project_id", collect);
+                    if (timeType.getReportAuditType() == 1) {//分组负责人审核模式,需要按参与的任务分组显示
+                        //需要是他参与的任务分组
+                        List<GroupParticipator> groupParticipatorList = groupParticipatorMapper.selectList(new QueryWrapper<GroupParticipator>().eq("user_id", userId));
+                        List<Integer> joinGroupList = groupParticipatorList.stream().map(GroupParticipator::getGroupId).collect(Collectors.toList());
+                        if (joinGroupList.size() > 0) {
+                            taskGroupQueryWrapper.in("id", joinGroupList);
+                        } else {
+                            taskGroupQueryWrapper.eq("id", -1);//没有分组
+                        }
+                    }
+                    List<TaskGroup> taskGroups = taskGroupMapper.selectList(taskGroupQueryWrapper);
+                    //获取负责人的用户集合
+                    List<String> inchargerIds = taskGroups.stream().map(TaskGroup::getInchargerId).collect(Collectors.toList());
+                    if (inchargerIds.size() == 0) {
+                        inchargerIds.add("-1");
+                    }
+                    List<User> userList = userMapper.selectList(new QueryWrapper<User>().in("id", inchargerIds));
+                    reportList.forEach(r->{
+                        r.setTaskGroups(taskGroups.stream().filter(tg->tg.getProjectId().equals(r.getProjectId())).collect(Collectors.toList()));
 //                    for (TaskGroup gp : r.getTaskGroups()) {
 //                        if (!StringUtils.isEmpty(gp.getInchargerId()) ) {
 //                            if (gp.getInchargerId().equals(userId)) {
@@ -10202,96 +10460,96 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
 //                            }
 //                        }
 //                    }
-                    //设置项目名称
-                    Optional<Project> optional = finalProjectList.stream().filter(p->p.getId().equals(r.getProjectId())).findFirst();
-                    if (optional.isPresent()) {
-                        r.setProjectName(optional.get().getProjectName());
-                    }
-                    //设置自定义维度
-                    if (timeType.getCustomDegreeActive() == 1) {
-                        if (timeType.getCustomDegreeWithPro() == 1) {
-                            String associateDegrees = optional.get().getAssociateDegrees();
-                            List<HashMap> degreeMapList = new ArrayList<>();
-                            if (associateDegrees != null) {
-                                String[] split = associateDegrees.split("\\,");
-                                for (int i=0;i<split.length; i++) {
-                                    HashMap map = new HashMap();
-                                    if (!StringUtils.isEmpty(split[i])) {
-                                        Integer id = Integer.parseInt(split[i]);
-                                        map.put("id", id);
-                                        map.put("name", degreeList.stream().filter(d->d.getId().equals(id)).findFirst().get().getName());
-                                        degreeMapList.add(map);
+                        //设置项目名称
+                        Optional<Project> optional = finalProjectList.stream().filter(p->p.getId().equals(r.getProjectId())).findFirst();
+                        if (optional.isPresent()) {
+                            r.setProjectName(optional.get().getProjectName());
+                        }
+                        //设置自定义维度
+                        if (timeType.getCustomDegreeActive() == 1) {
+                            if (timeType.getCustomDegreeWithPro() == 1) {
+                                String associateDegrees = optional.get().getAssociateDegrees();
+                                List<HashMap> degreeMapList = new ArrayList<>();
+                                if (associateDegrees != null) {
+                                    String[] split = associateDegrees.split("\\,");
+                                    for (int i=0;i<split.length; i++) {
+                                        HashMap map = new HashMap();
+                                        if (!StringUtils.isEmpty(split[i])) {
+                                            Integer id = Integer.parseInt(split[i]);
+                                            map.put("id", id);
+                                            map.put("name", degreeList.stream().filter(d->d.getId().equals(id)).findFirst().get().getName());
+                                            degreeMapList.add(map);
+                                        }
                                     }
                                 }
+                                r.setDegreeList(degreeMapList);
+                            } else {
+                                //把degreeList改成HashMap结构
+                                List<HashMap> mapDegreeList = new ArrayList<>();
+                                for (ReportExtraDegree degree : degreeList) {
+                                    HashMap map = new HashMap();
+                                    map.put("id", degree.getId());
+                                    map.put("name", degree.getName());
+                                    mapDegreeList.add(map);
+                                }
+                                r.setDegreeList(mapDegreeList);
                             }
-                            r.setDegreeList(degreeMapList);
-                        } else {
-                            //把degreeList改成HashMap结构
-                            List<HashMap> mapDegreeList = new ArrayList<>();
-                            for (ReportExtraDegree degree : degreeList) {
-                                HashMap map = new HashMap();
-                                map.put("id", degree.getId());
-                                map.put("name", degree.getName());
-                                mapDegreeList.add(map);
-                            }
-                            r.setDegreeList(mapDegreeList);
                         }
-                    }
-                });
-            }
-
-            reportMap.put("projectList", projectList);
-            //计算日期,进行返回
-            List<HashMap> dateList = new ArrayList<>();
-            LocalDate today = LocalDate.now();
-            LocalDate itemDate = firstDayOfWeek;
-            while(true) {
-                HashMap item = new HashMap();
-                item.put("date", itemDate.format(dtf));
-                //计算显示的周几
-                item.put("weekDayTxt", DateTimeUtil.getWeekDayTxt(itemDate.getDayOfWeek().getValue()));
-                //不可提前填报
-                if (timeType.getFillAhead() == 0 && itemDate.isAfter(today)) {
-                    item.put("canFill", 0);
-                } else {
-                    item.put("canFill", 1);
+                    });
                 }
-                //放入当天对应的日报
-                final LocalDate finalItemDate = itemDate;
-                List<Report> dateReportList = reportList.stream().filter(r -> r.getCreateDate().isEqual(finalItemDate)).collect(Collectors.toList());
-                item.put("reportList", dateReportList);
-                double sum = dateReportList.stream().mapToDouble(Report::getWorkingTime).sum();
-                item.put("filledTime", sum);
-                dateList.add(item);
-                //往后推一天
-                itemDate = itemDate.plusDays(1);
-                //超过最后一天了,跳出循环
-                if (itemDate.isAfter(lastDayOfWeek)) {
-                    break;
+
+                reportMap.put("projectList", projectList);
+                //计算日期,进行返回
+                List<HashMap> dateList = new ArrayList<>();
+                LocalDate today = LocalDate.now();
+                LocalDate itemDate = firstDayOfWeek;
+                while(true) {
+                    HashMap item = new HashMap();
+                    item.put("date", itemDate.format(dtf));
+                    //计算显示的周几
+                    item.put("weekDayTxt", DateTimeUtil.getWeekDayTxt(itemDate.getDayOfWeek().getValue()));
+                    //不可提前填报
+                    if (timeType.getFillAhead() == 0 && itemDate.isAfter(today)) {
+                        item.put("canFill", 0);
+                    } else {
+                        item.put("canFill", 1);
+                    }
+                    //放入当天对应的日报
+                    final LocalDate finalItemDate = itemDate;
+                    List<Report> dateReportList = reportList.stream().filter(r -> r.getCreateDate().isEqual(finalItemDate)).collect(Collectors.toList());
+                    item.put("reportList", dateReportList);
+                    double sum = dateReportList.stream().mapToDouble(Report::getWorkingTime).sum();
+                    item.put("filledTime", sum);
+                    dateList.add(item);
+                    //往后推一天
+                    itemDate = itemDate.plusDays(1);
+                    //超过最后一天了,跳出循环
+                    if (itemDate.isAfter(lastDayOfWeek)) {
+                        break;
+                    }
                 }
-            }
-            reportMap.put("dateList", dateList);
-            //查询考勤请假状态
-            WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", user.getCompanyId()));
-            if (wxCorpInfo != null && dateList.size() > 0) {
-                List<UserCorpwxTime> userCorpwxTimeList = userCorpwxTimeMapper.selectList(new QueryWrapper<UserCorpwxTime>().eq("corpwx_userid", user.getCorpwxUserid()).in("create_date", dateList.stream().map(r -> (String) r.get("date")).collect(Collectors.toList())));
-                for (HashMap item : dateList) {
-                    String curDate = (String) item.get("date");
-                    UserCorpwxTime userCorpwxTime = userCorpwxTimeList.stream().filter(r -> r.getCreateDate().isEqual(LocalDate.parse(curDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")))).findFirst().orElse(null);
-                    if (userCorpwxTime != null) {
-                        item.put("time", userCorpwxTime);
+                reportMap.put("dateList", dateList);
+                //查询考勤请假状态
+                WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", user.getCompanyId()));
+                if (wxCorpInfo != null && dateList.size() > 0) {
+                    List<UserCorpwxTime> userCorpwxTimeList = userCorpwxTimeMapper.selectList(new QueryWrapper<UserCorpwxTime>().eq("corpwx_userid", user.getCorpwxUserid()).in("create_date", dateList.stream().map(r -> (String) r.get("date")).collect(Collectors.toList())));
+                    for (HashMap item : dateList) {
+                        String curDate = (String) item.get("date");
+                        UserCorpwxTime userCorpwxTime = userCorpwxTimeList.stream().filter(r -> r.getCreateDate().isEqual(LocalDate.parse(curDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")))).findFirst().orElse(null);
+                        if (userCorpwxTime != null) {
+                            item.put("time", userCorpwxTime);
+                        }
                     }
                 }
+                reportMap.put("summary", summary);
+                reportMap.put("weeklyAttachment", attachment);
+            } else {
+                reportMap.put("dateList", new ArrayList());
             }
-            reportMap.put("summary", summary);
-            reportMap.put("weeklyAttachment", attachment);
-        } else {
-            reportMap.put("dateList", new ArrayList());
-        }
-
 
-        msg.data = reportMap;
-        return msg;
+            msg.data = reportMap;
+            return msg;
+        }
     }
 
     @Override
@@ -14551,7 +14809,6 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             
             // 生成Excel文件导出
             String fileName = "日报列表_" + startDate + "至" + endDate + "_" + System.currentTimeMillis();
-            System.out.println("到处日报文件==>" + fileName);
             return excelExportService.exportGeneralExcelByTitleAndList(wxCorpInfo, dingding, fileName, dataList, path);
             
         } catch (Exception e) {
@@ -14992,6 +15249,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             titles.add("是否为异常申报");
             titles.add("日报汇报日期");
             titles.add("填写人");
+            titles.add("填报时间");
             titles.add("当日考勤记录");
             titles.add("当日加班申请");
 
@@ -15031,7 +15289,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 } else {
                     item.add((String) map.get("userName"));
                 }
-
+                item.add((String) map.get("createTime"));
                 //考勤
                 item.add(map.get("cardRecord") != null ? (String) map.get("cardRecord") : "");
 

+ 37 - 35
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/WxCorpInfoServiceImpl.java

@@ -1206,10 +1206,6 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                             userCorpwxTimeMapper.insert(userCorpwxTime);
                         }
                     }
-                    //处理曦合超导的加班补贴
-                    if (corpInfo.getCompanyId() == Constant.XI_HE_CHAO_DAO_COMPANY_ID || corpInfo.getCompanyId() == Constant.XI_HE_CHAO_DAO_JIA_XING_COMPANY_ID || corpInfo.getCompanyId() == 8128) {
-//                        handleAllowance(userCorpwxTime, baseMorningStart, baseMorningEnd, baseAfternoonStart, baseAfternoonEnd, restTime);
-                    }
                 }
             }
         }
@@ -1219,23 +1215,37 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
     public void handleUserAllowanceByReport(List<Report> reportList) {
         //从reportList中按照createDate和creatorId进行分组,去重,得到一个新的reportList, 里面的createDate和creatorId组合都是唯一的
         List<Report> distinctReportList = new ArrayList<>();
+        List<String> distinctUserIds = new ArrayList<>();
+
         for (Report report : reportList) {
             if (!distinctReportList.stream().anyMatch(r -> r.getCreatorId().equals(report.getCreatorId()) && r.getCreateDate().equals(report.getCreateDate()))) {
                 distinctReportList.add(report);
+                if (!distinctUserIds.contains(report.getCreatorId())) {
+                    distinctUserIds.add(report.getCreatorId());
+                }
             }
         }
+        LocalDate minDate = distinctReportList.stream().min(Comparator.comparing(Report::getCreateDate)).get().getCreateDate();
+        LocalDate maxDate = distinctReportList.stream().max(Comparator.comparing(Report::getCreateDate)).get().getCreateDate();
+
+        List<Report> sumReportList = reportMapper.selectList(new QueryWrapper<Report>()
+                .select("creator_id,create_date, sum(overtime_hours) as overtime_hours")
+                .in("creator_id", distinctUserIds).between("create_date", minDate, maxDate).ne("state", 2).groupBy("creator_id,create_date"));//驳回的不算
+        List<User> userList = userMapper.selectList(new QueryWrapper<User>().in("id", distinctUserIds));
+        List<String> corpwxUserIds = userList.stream().map(User::getCorpwxUserid).collect(Collectors.toList());
+        List<UserCorpwxTime> userCorpwxTimes = userCorpwxTimeMapper.selectList(new QueryWrapper<UserCorpwxTime>().in("corpwx_userid", corpwxUserIds).between("create_date", minDate, maxDate));
         for (Report item : distinctReportList) {
             String userId = item.getCreatorId();
             LocalDate date = item.getCreateDate();
             //查询日报的合计加班时长
-            Report report = reportMapper.selectOne(new QueryWrapper<Report>().select("sum(overtime_hours) as overtime_hours").eq("creator_id", userId).eq("create_date", date));
-            double reportOvertime = report == null ? 0 : report.getOvertimeHours();
-            User user = userMapper.selectById(userId);
-            UserCorpwxTime userCorpwxTime = userCorpwxTimeMapper.selectOne(new QueryWrapper<UserCorpwxTime>().eq("corpwx_userid", user.getCorpwxUserid()).eq("create_date", date));
+            double reportOvertime = sumReportList.stream().filter(r -> r.getCreatorId().equals(userId) && r.getCreateDate().equals(date)).findFirst().map(Report::getOvertimeHours).orElse(0.0);
+            User user = userList.stream().filter(u -> u.getId().equals(userId)).findFirst().orElse(null);
+            UserCorpwxTime userCorpwxTime = userCorpwxTimes.stream().filter(u -> u.getCorpwxUserid().equals(user.getCorpwxUserid()) && u.getCreateDate().equals(date)).findFirst().orElse(null);
             if (userCorpwxTime != null) {
                 handleAllowance(userCorpwxTime, "08:00", "12:00", "13:00", "17:00", 1.0, reportOvertime);
             }
         }
+
     }
 
     private void handleAllowance(UserCorpwxTime userCorpwxTime, String baseMorningStart, String baseMorningEnd, String baseAfternoonStart, String baseAfternoonEnd, double restTime, double reportOvertime) {
@@ -1244,25 +1254,27 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
         allowance.setCompanyId(userCorpwxTime.getCompanyId());
         allowance.setCorpwxUserid(userCorpwxTime.getCorpwxUserid());
         allowance.setDate(userCorpwxTime.getCreateDate());
+        allowance.setOvertimeDuration(reportOvertime);
         DateTimeFormatter df = DateTimeFormatter.ofPattern("yyy-MM-dd HH:mm");
         DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
         DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm");
         LocalDateTime startTime = LocalDateTime.parse(dateTimeFormatter.format(userCorpwxTime.getCreateDate()) + " " + userCorpwxTime.getStartTime(), df);
         String endTimeStr = userCorpwxTime.getEndTime();
         boolean isNextDay = endTimeStr.startsWith("次日") || endTimeStr.compareTo(userCorpwxTime.getStartTime()) < 0;
-        LocalDateTime endTime = LocalDateTime.parse(dateTimeFormatter.format(userCorpwxTime.getCreateDate()) + " " + userCorpwxTime.getEndTime(), df);
+        LocalDateTime endTime = LocalDateTime.parse(dateTimeFormatter.format(userCorpwxTime.getCreateDate()) + " " + userCorpwxTime.getEndTime().replace("次日", ""), df);
         if (isNextDay) {
-            endTime = endTime.plusDays(1);
-        }
-        if (startTime.toLocalTime().isBefore(LocalTime.parse(baseMorningStart,timeFormatter))) {
-            //上班时间校准为正常上班开始时间
-            startTime.withHour(Integer.parseInt(baseMorningStart.split(":")[0])).withMinute(Integer.parseInt(baseMorningStart.split(":")[1])).withSecond(0).withNano(0);
+            endTime = LocalDateTime.parse(dateTimeFormatter.format(userCorpwxTime.getCreateDate().plusDays(1)) + " " + userCorpwxTime.getEndTime().replace("次日", ""), df);
+        } else {
+            endTime = LocalDateTime.parse(dateTimeFormatter.format(userCorpwxTime.getCreateDate()) + " " + userCorpwxTime.getEndTime(), df);
         }
+//        if (startTime.toLocalTime().isBefore(LocalTime.parse(baseMorningStart,timeFormatter))) {
+//            //上班时间校准为正常上班开始时间
+//            startTime.withHour(Integer.parseInt(baseMorningStart.split(":")[0])).withMinute(Integer.parseInt(baseMorningStart.split(":")[1])).withSecond(0).withNano(0);
+//        }
         allowance.setStartTime(startTime);
         allowance.setEndTime(endTime);
         String startTimeTxt = userCorpwxTime.getStartTime();
         String endTimeTxt = userCorpwxTime.getEndTime();
-        //判断是否是加班
         BigDecimal bigDecimal = new BigDecimal(Duration.between(startTime,endTime).toMinutes());
         bigDecimal = bigDecimal.divide(BigDecimal.valueOf(60),1,BigDecimal.ROUND_HALF_UP);//按小时为单位
         double standWorkHours = 8.0;
@@ -1289,19 +1301,21 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                     //当天加班,补贴20
                     if (endTime.toLocalDate().compareTo(startTime.toLocalDate()) == 0) {
                         allowance.setType(0);
-                        allowance.setOvertimeDuration(reportOvertime);
                         allowance.setAllowance(20);
                     } else {
                         //跨天,加班超过凌晨了,补贴30
-                        allowance.setType(1);
-                        allowance.setOvertimeDuration(reportOvertime);
-                        allowance.setAllowance(30);
+                        //跨天并且是第二天凌晨4点以后下班,补贴50
+                        if (endTimeTxt.compareTo("04:00") >= 0) {
+                            allowance.setType(5);
+                            allowance.setAllowance(50);
+                        } else {
+                            allowance.setType(1);
+                            allowance.setAllowance(30);
+                        }
                     }
                 } else {
                     //不足3小时
-//                        System.out.println("工作日加班不足3小时:"+(time - standWorkHours));
                     allowance.setType(-1);
-                    allowance.setOvertimeDuration(reportOvertime);
                     allowance.setAllowance(0);
                 }
             } else if (startTimeTxt.compareTo("16:00") >= 0) {
@@ -1309,12 +1323,10 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                 if (time >= 12.0) {
                     //大夜班,超过12小时了
                     allowance.setType(3);
-                    allowance.setOvertimeDuration(reportOvertime);
                     allowance.setAllowance(50);
                 } else if (time >= standWorkHours && endTime.toLocalDate().isAfter(startTime.toLocalDate())) {//工作超过凌晨了
                     //小夜班,补贴30
                     allowance.setType(2);
-                    allowance.setOvertimeDuration(reportOvertime);
                     allowance.setAllowance(30);
                 }
             }
@@ -1325,12 +1337,10 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                 if (startTimeTxt.compareTo(baseMorningEnd) < 0) {
                     if (endTime.toLocalDate().isEqual(startTime.toLocalDate())) {
                         allowance.setType(4);
-                        allowance.setOvertimeDuration(reportOvertime);
                         allowance.setAllowance(20);
                     } else {
                         //加班超过凌晨了
                         allowance.setType(1);
-                        allowance.setOvertimeDuration(reportOvertime);
                         allowance.setAllowance(30);
                     }
                 } else if (startTimeTxt.compareTo("16:00") >= 0) {
@@ -1338,19 +1348,16 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                     if (time >= 12.0) {
                         //大夜班,超过12小时了
                         allowance.setType(3);
-                        allowance.setOvertimeDuration(reportOvertime);
                         allowance.setAllowance(50);
                     } else if (time >= standWorkHours){
                         //跨天,加班超过凌晨了,补贴30
                         allowance.setType(2);
-                        allowance.setOvertimeDuration(reportOvertime);
                         allowance.setAllowance(30);
                     }
                 }
             } else if (reportOvertime >= 3.0) {
                 //加班工作时长超过3小时,补20元
                 allowance.setType(0);
-                allowance.setOvertimeDuration(reportOvertime);
                 allowance.setAllowance(20);
             }
         }
@@ -1865,9 +1872,10 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                         double timeDelta = 0;
                         //时间有变化,需要重新计算
                         if (needRecaculate) {
+//                            DateTimeUtil.calculateWorkHours(ct.getStartTime(), ct.getEndTime());
                             timeDelta = DateTimeUtil.getHoursFromSeconds(DateTimeUtil.getSecondsFromTime(ct.getEndTime()) - DateTimeUtil.getSecondsFromTime(ct.getStartTime()));
                             //超过下午上班的开始时间,需要减去午休的时间
-                            if (ct.getEndTime().compareTo(baseAfternoonStart) >= 0) {
+                            if (ct.getStartTime().compareTo(baseMorningEnd) <= 0 && ct.getEndTime().compareTo(baseAfternoonStart) >= 0) {
                                 //重新计算打卡工时时,需要减去中间午休时间
                                 timeDelta -= restTime;
                             }
@@ -2160,17 +2168,11 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                                 if (showLog) System.out.println("更新考勤记录"+curUserid+", "+localDate);
                                 userCorpwxTimeMapper.updateById(ct);
                             }
-                            if (corpInfo.getCompanyId() == Constant.XI_HE_CHAO_DAO_COMPANY_ID || corpInfo.getCompanyId() == Constant.XI_HE_CHAO_DAO_JIA_XING_COMPANY_ID || corpInfo.getCompanyId() == 8128) {
-//                                handleAllowance(item, baseMorningStart, baseMorningEnd, baseAfternoonStart, baseAfternoonEnd, restTime);
-                            }
                         }
                     } else {
                         if (hasTimeRecord) {
                             if (showLog) System.out.println("插入考勤记录"+curUserid+", "+localDate);
                             userCorpwxTimeMapper.insert(ct);
-                            if (corpInfo.getCompanyId() == Constant.XI_HE_CHAO_DAO_COMPANY_ID || corpInfo.getCompanyId() == Constant.XI_HE_CHAO_DAO_JIA_XING_COMPANY_ID || corpInfo.getCompanyId() == 8128) {
-//                                handleAllowance(ct, baseMorningStart, baseMorningEnd, baseAfternoonStart, baseAfternoonEnd, restTime);
-                            }
 
                         } else {
                             //调用打卡详情去获取,弥补外出打卡且时间不在自动同步范围内的情况; 仅对工作日有效

+ 2 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/OvertimeAllowanceMapper.xml

@@ -80,8 +80,8 @@
             SUM(work_hours)         AS work_hours,
             SUM(overtime_duration)  AS overtime_duration,
             SUM(allowance)          AS allowance,
-        -- 夜班补贴:type = 1、2、3
-        SUM(CASE WHEN type IN (1,2,3) THEN allowance ELSE 0 END) AS night_allowance,
+        -- 夜班补贴:type = 1、2、3、5
+        SUM(CASE WHEN type IN (1,2,3, 5) THEN allowance ELSE 0 END) AS night_allowance,
         -- 餐补:其他所有情况
         SUM(CASE WHEN type NOT IN (1,2,3) THEN allowance ELSE 0 END) AS meal_allowance
         FROM overtime_allowance

+ 6 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportMapper.xml

@@ -1965,6 +1965,12 @@
         FROM report r
         INNER JOIN user u ON r.creator_id = u.id
         WHERE r.company_id = #{companyId}
+        <if test="state != null">
+            AND r.state = #{state}
+        </if>
+        <if test="state == null">
+            AND (r.state = 0 or r.state = 1 or r.state = 2)
+        </if>
         <if test="startDate != null and startDate != ''">
             AND r.create_date &gt;= #{startDate}
         </if>

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 2 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/TimeTypeMapper.xml


+ 9 - 3
fhKeeper/formulahousekeeper/octopus/src/views/customer/list.vue

@@ -257,7 +257,13 @@
                     <el-form-item><el-checkbox v-model="dialogData.projectManDay">是否开启项目人天字段</el-checkbox></el-form-item>
                     <el-form-item><el-checkbox v-model="dialogData.projectCustom">是否开启项目自定义表单</el-checkbox></el-form-item>
                     <el-form-item><el-checkbox v-model="dialogData.easyExpense">是否开启简易费用报销</el-checkbox></el-form-item>
-                    <el-form-item><el-checkbox v-model="dialogData.enableNewWeeklyfill">是否启用新的按周填报模式</el-checkbox></el-form-item>
+                    <el-form-item>按周填报模式
+                        <el-select v-model="dialogData.enableNewWeeklyfill" size="small">
+                            <el-option :value="0" label="0-旧版"></el-option>
+                            <el-option :value="1" label="1-新版(物奇)"></el-option>
+                            <el-option :value="2" label="2-新版通用"></el-option>
+                        </el-select>
+                    </el-form-item>
                     <el-form-item><el-checkbox v-model="dialogData.hideSubproject">是否去除子项目</el-checkbox></el-form-item>
                     <el-form-item><el-checkbox v-model="dialogData.userWithMultiDept">是否开启人员设置可填报部门</el-checkbox></el-form-item>
                     <el-form-item><el-checkbox v-model="dialogData.importReportAuditNormal">导入的日报正常审批</el-checkbox></el-form-item>
@@ -515,7 +521,7 @@ import App from '../../App.vue';
                             this.$set(this.dialogData,'projectManDay',res.data.projectManDay ? true : false)
                             this.$set(this.dialogData,'projectCustom',res.data.projectCustom ? true : false)
                             this.$set(this.dialogData,'easyExpense',res.data.easyExpense ? true : false)
-                            this.$set(this.dialogData,'enableNewWeeklyfill',res.data.enableNewWeeklyfill ? true : false)
+                            this.$set(this.dialogData,'enableNewWeeklyfill',res.data.enableNewWeeklyfill)
                             this.$set(this.dialogData,'hideSubproject',res.data.hideSubproject ? true : false)
                             this.$set(this.dialogData,'userWithMultiDept',res.data.userWithMultiDept ? true : false)
                             this.$set(this.dialogData,'taskFileCharge',res.data.taskFileCharge ? true : false) 
@@ -867,7 +873,7 @@ import App from '../../App.vue';
                     projectManDay: this.dialogData.projectManDay ? 1 : 0,
                     projectCustom: this.dialogData.projectCustom ? 1 : 0,
                     easyExpense: this.dialogData.easyExpense ? 1 : 0,
-                    enableNewWeeklyfill: this.dialogData.enableNewWeeklyfill ? 1 : 0,
+                    enableNewWeeklyfill: this.dialogData.enableNewWeeklyfill,
                     hideSubproject:this.dialogData.hideSubproject ? 1: 0, 
                     userWithMultiDept:this.dialogData.userWithMultiDept ? 1: 0, 
                     taskFileCharge:this.dialogData.taskFileCharge ? 1: 0, 

+ 0 - 3
fhKeeper/formulahousekeeper/timesheet/src/i18n/en.json

@@ -1458,8 +1458,6 @@
   "twolayer": "2 layer",
   "an-ren-yuan-cha-kan": "According to personnel needs",
   "an-xiang-mu-cha-kan": "View by project",
-  "zi-yuan-xu-qiu": "resource requirements",
-  "zi-yuan-xu-qiu-dao-ru-mo-ban": "Import a template for resource requirements",
   "dao-ru-xu-qiu": "Import demand",
   "dao-chu-xu-qiu": "Export demand",
   "jin-qi-ri-huo-yue-ren-yuan": "Active staff for seven days",
@@ -1472,7 +1470,6 @@
   "chu-cha": "evection",
   "xuan-xiang-1": "Option 1",
   "xuan-xiang-2": "Option 2",
-  "zi-yuan-xu-qiu-dao-chu": "Exporting Resource Requirements",
   "bumenchanyuqingkuang": "Project information of the departments involved",
   "can-yu-de-xiang-mu-de-shu-liang": "number of projects involved",
   "can-yu-ren-ci": "Number of participants",

+ 0 - 3
fhKeeper/formulahousekeeper/timesheet/src/i18n/zh.json

@@ -1464,8 +1464,6 @@
   "threelayer": "3层",
   "an-ren-yuan-cha-kan": "按人员查看",
   "an-xiang-mu-cha-kan": "按项目查看",
-  "zi-yuan-xu-qiu": "资源需求",
-  "zi-yuan-xu-qiu-dao-ru-mo-ban": "资源需求导入模板",
   "dao-ru-xu-qiu": "导入需求",
   "dao-chu-xu-qiu": "导出需求",
   "jin-qi-ri-huo-yue-ren-yuan": "近七日活跃人员",
@@ -1477,7 +1475,6 @@
   "bu-men-jin-du": "部门进度",
   "xuan-xiang-1": "选项1",
   "xuan-xiang-2": "选项2",
-  "zi-yuan-xu-qiu-dao-chu": "资源需求导出",
   "chu-cha": "出差",
   "bumenchanyuqingkuang": "部门参与项目情况表",
   "can-yu-de-xiang-mu-de-shu-liang": "参与的项目的数量",

+ 14 - 7
fhKeeper/formulahousekeeper/timesheet/src/views/corpreport/list.vue

@@ -2211,6 +2211,8 @@
                             ? "白班"
                             : scope.row.type == 4
                             ? "白班"
+                            : scope.row.type == 5
+                            ? "白班"
                             : "-"
                         }}
                       </template>
@@ -5493,6 +5495,8 @@
                         ? "白班"
                         : scope.row.type == 4
                         ? "白班"
+                        : scope.row.type == 5
+                        ? "白班"
                         : "-"
                     }}
                   </template>
@@ -5507,7 +5511,8 @@
                     {{
                       scope.row.type == 1 ||
                       scope.row.type == 2 ||
-                      scope.row.type == 3
+                      scope.row.type == 3 || 
+                      scope.row.type == 5 //白班,跨天到第二天凌晨4点以后
                         ? "是"
                         : "否"
                     }}
@@ -5567,6 +5572,8 @@
                         ? "大夜班,补贴 50 元"
                         : scope.row.type == 4
                         ? "全天加班"
+                        : scope.row.type == 5
+                        ? "加班过凌晨4点,餐补 50 元"
                         : "-"
                     }}
                   </template>
@@ -8753,11 +8760,7 @@ export default {
       } else if (this.ins == 5) {
         this.getProjectStages();
       } else if (this.ins == 6) {
-        if (
-          this.user.companyId == 8555 ||
-          this.user.companyId == 5792 ||
-          this.user.companyId == 10
-        ) {
+        if (this.user.companyId == 8555 || this.user.companyId == 5792) {
           this.getMealAllowance(false);
         } else {
           this.overTime();
@@ -8853,7 +8856,11 @@ export default {
         this.getAbnormalWorkHours();
       }
       if (this.ins == 36) {
-        this.getMealAllowance();
+        if (this.allowanceTabActive === "detail") {
+          this.getMealAllowance();
+        } else {
+          this.getMealAllowanceSummary();
+        }
       }
       if (this.ins == 37) {
         this.getDailyWorkHours();

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

@@ -178,7 +178,7 @@ export default {
         month_full: [this.$t('yiYue'), this.$t('erYue'), this.$t('sanYue'), this.$t('siYue'), this.$t('thisTWuyue'), this.$t('liuYue'), this.$t('qiYue'), this.$t('baYue'), this.$t('jiuYue'), this.$t('shiYue'), this.$t('shiYiYue'), this.$t('shiErYue')],
         month_short: [this.$t('1Yue'), this.$t('2Yue'), this.$t('3Yue'), this.$t('4Yue'), this.$t('5Yue'), this.$t('6Yue'), this.$t('7Yue'), this.$t('8Yue'), this.$t('9Yue'), this.$t('10Yue'), this.$t('11Yue'), this.$t('12Yue')],
         day_full: [this.$t('xingQiRi'), this.$t('xingQiYi'), this.$t('xingQiEr'), this.$t('xingQiSan'), this.$t('xingQiSi'), this.$t('xingQiWu'), this.$t('xingQiLiu')],
-        day_short: [this.$t('ri'), "一", "二", "三", "四", "五", "六"]
+        day_short: ['日', "一", "二", "三", "四", "五", "六"]
       },
       labels: {
         dhx_cal_today_button: this.$t('jinTian'),

+ 0 - 80
fhKeeper/formulahousekeeper/timesheet/src/views/project/project_gantt.vue

@@ -6,9 +6,7 @@
           <el-radio-group v-model="radio1" @change="selChange()" size="small">
             <el-radio-button :label="$t('an-ren-yuan-cha-kan')" value="renyuan"></el-radio-button>
             <el-radio-button :label="$t('an-xiang-mu-cha-kan')" value="xiangmu"></el-radio-button>
-            <el-radio-button :label="$t('zi-yuan-xu-qiu')" value="demand"></el-radio-button>
           </el-radio-group>
-          <!-- <el-checkbox v-if="radio1 != $t('zi-yuan-xu-qiu') && user.companyId == 876" v-model="justWaitForMe" style="margin-left: 14px;" @change="selChange()">待我审核</el-checkbox> -->
         </div>
       </div>
       <!-- 时间段筛选  -->
@@ -62,18 +60,6 @@
           </el-select>
           <selectCat v-if="!reqpar1 && user.userNameNeedTranslate == '1'" style="margin-left:9px;" :size="'small'" :widthStr="'153'" :subject="screenList" :subjectId="valuex" :distinction="'1'" @selectCal="selectCal"></selectCat>
       </div>
-      <!-- 资源需求导入/导出 -->
-      <div class="head_files" v-if="!isDataLoaded">
-        <div style="margin-left:10px;float:left;">
-          <el-link type="primary" :underline="false" :href="'./upload/'+$t('zi-yuan-xu-qiu-dao-ru-mo-ban')+'.xlsx'" download="资源需求导入模板.xlsx">{{ $t('Downloadthetemplate') }}</el-link>
-        </div>
-        <el-upload ref="upload" style="margin-left:10px;float:left;" action="#" :limit="1" :http-request="importProject" :show-file-list="false">
-          <el-link type="primary" :underline="false" >{{ $t('dao-ru-xu-qiu') }}</el-link>
-        </el-upload>
-        <div style="margin-left:10px;float:left;">
-        <el-link type="primary" :underline="false" @click="exportProjectData" download="资源需求导出.xlsx">{{ $t('dao-chu-xu-qiu') }}</el-link>
-        </div>
-      </div>
     </div>
 
     <gantt v-if="isDataLoaded && user.userNameNeedTranslate != 1" ref="ganttTable1" class="left-container" :tasks="tasks" 
@@ -269,72 +255,6 @@ export default {
         
         this.getList()
       },
-      // 资源需求导出
-      exportProjectData() {
-        let parameter = {}
-        if(this.valuex){
-          parameter.projectId = this.valuex
-        }
-        if(this.valuex2){
-          parameter.groupName = this.valuex2
-        }
-                this.http.post('/project-requirement/exportData',parameter,
-                res => {
-                    if (res.code == "ok") {
-                        let filePath = res.data;
-                        const a = document.createElement('a'); // 创建a标签
-                        a.setAttribute('download', this.$t('zi-yuan-xu-qiu-dao-chu')+'.xlsx');// download属性
-                        a.setAttribute('href', filePath);// href链接
-                        a.click(); //自执行点击事件
-                        a.remove();
-                    } 
-                },
-                error => {
-                    this.$message({
-                        message: error,
-                        type: "error"
-                    });
-                    }
-                );
-            },
-      // 资源需求导入
-      importProject(item) {
-                //首先判断文件类型
-                let str = item.file.name.split(".");
-                let format = str[str.length - 1];
-                if (format != "xls" && format != "xlsx") {
-                    this.$message({
-                        message: this.$t('other.PleaseselecttheXLSorXLSXfile'),
-                        type: "error"
-                    });
-                } else {
-                    let formData = new FormData();
-                    formData.append("multipartFile", item.file);
-                    this.http.uploadFile('/project-requirement/importData', formData,
-                    res => {
-                        this.$refs.upload.clearFiles();
-                        if (res.code == "ok") {
-                            this.$message({
-                                message: this.$t('other.importSuccess'),
-                                type: "success"
-                            });
-                            this.getDemandList();
-                        } else {
-                            this.$message({
-                                message: res.msg,
-                                type: "error"
-                            });
-                        }
-                    },
-                    error => {
-                        this.$refs.upload.clearFiles();
-                        this.$message({
-                            message: error,
-                            type: "error"
-                        });
-                    });
-                }
-            },
       // 人员/项目切换
       selChange(){
         this.valuex = null

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

@@ -779,7 +779,7 @@
               }}<el-input-number
                 v-model="timeType.reportAutoApproveDays"
                 style="width: 150px; margin: 0 10px"
-                min="1"
+                min="0"
               ></el-input-number
               >{{ $t("dyas") }}
             </el-form-item>
@@ -3850,9 +3850,9 @@ export default {
               ? this.timeType.customDataMaxValue
               : 100;
             this.timeType.reportAutoApproveDays = this.timeType
-              .reportAutoApproveDays
+              .reportAutoApproveDays != null
               ? this.timeType.reportAutoApproveDays
-              : 1;
+              : 0;
             this.timeType.stopReport = this.timeType.stopReport ? true : false;
             this.timeType.notAllowedOnNonWorkday = this.timeType
               .notAllowedOnNonWorkday

+ 109 - 82
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

@@ -389,8 +389,8 @@
         </el-dialog>
 
         <!-- 填写日报的dialog -->
-        <el-dialog :title="isSubstitude?$t('textLink.helpToFillIn'):editTitle[isBatch]" :visible.sync="dialogVisible" width="60%" :close-on-click-modal="false" @closed="guanbi()" :top="'5.5vh'" custom-class="editReportDialog" ref="editReportDialog">
-            <div style="height: 65vh;overflow: auto;">
+        <el-dialog :title="isSubstitude?$t('textLink.helpToFillIn'):editTitle[isBatch]" :visible.sync="dialogVisible" width="60%" :close-on-click-modal="false" @closed="guanbi()" :top="'5.2vh'" custom-class="editReportDialog" ref="editReportDialog">
+            <div style="height: 70vh;overflow: auto;">
                 <div style="margin:0 120px 10px 120px;position:relative;" v-if="user.company.enableAi && this.workForm.domains.filter(item=>!item.canEdit).length == 0 && !isSubstitude && !isBatch">
                     <div style="display:flex;align-items:flex-start;gap:10px;">
                         <el-input v-model="userInputMsg" type="textarea" :rows="2" placeholder="样例:今天/昨天/本周三... [A项目], 3小时,做了产品的需求分析;[B项目],5小时,进行技术文档编写。(按Ctrl+Enter快速提交) 当前免费体验" clearable 
@@ -399,7 +399,7 @@
                     </div>
                     <div style="margin-top:5px;"><el-tag size="mini" :key="word.value" effect="plain" v-for="word in quickWords" @click="fillWord(word)">{{ word }}</el-tag></div>
                 </div>
-                <el-form ref="workForm" :model="workForm" :rules="workRules" label-width="120px">
+                <el-form ref="workForm" :model="workForm" :rules="workRules" label-width="120px" >
                     <el-form-item :label="$t('screening.selectPeople')" v-if="isSubstitude">
                         <el-input v-if="user.userNameNeedTranslate != 1" @focus="showChooseMembTree" v-model="workForm.userNames"
                         :placeholder="$t('defaultText.pleaseSelectAsubstitute')" style="width:200px;"></el-input>
@@ -513,12 +513,19 @@
                     <!--加班申请时长-->
                     <el-form-item label="已通过加班申请" v-if="workForm.overtime"><span style="color:#FFA500;">{{ workForm.overtime.toFixed(1) }} h</span></el-form-item>
                     <!-- 000000 -->
-                    <div v-for="(domain, index) in workForm.domains" :key="domain.id" :style="index>0?'padding-top:25px;':''" >
+                    <div v-for="(domain, index) in workForm.domains" :key="domain.id" class="time_box" >
+                        <div class="time_title">
+                            <i class="el-icon-plus"></i> <span>项目&nbsp;{{index+1}}</span>
+                            <el-link v-if="(index >= 1 || workForm.domains.length > 1)&&domain.canEdit"  :underline="false" @click="delDomain(index)" style="position:absolute;right:15px;"
+                                :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)">
+                                <i class="el-icon-close" style="font-size:18px;"></i>
+                            </el-link>
+                        </div>
                         <div v-if="reportTimeType.multiWorktime==0">
-                        <!-- <template v-if="user.companyId == 10">
+                        <template v-if="user.timeType.timeInputNormal">
                             <el-form-item v-if="!(permissions.reportHideWorkingHours && workForm.domains[index].state == 1)" label="正常工时" :prop="'domains.' + index + '.'+timeFields[reportTimeType.type]"
                                 :rules="{ required: true, message: '请选择正常工作时长', trigger: 'blur' }">
-                                <el-select v-model="domain.totalWorkingTime" style="width:200px;"
+                                <el-select v-model="domain.normalWorkingTime" style="width:200px;"
                                 v-if="reportTimeType.type == 1"
                                 :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)"
                                 placeholder="请选择正常工作时长"
@@ -526,16 +533,15 @@
                                 default-first-option
                                 @change="seleChn(0,domain)">
                                 <el-option v-for="item in timeRange" :key="item" :value="item.toFixed(1)">{{item.toFixed(1)}}</el-option>
-                                </el-select>
-                                <span v-if="reportTimeType.type == 1">小时</span>
+                                </el-select>&nbsp;小时
                                 <div class="overtime" v-if="user.timeType.fillOvertime || (isWeekend && user.timeType.lockWorktime != 1)">
-                                    <el-checkbox :disabled="!domain.canEdit" v-model="domain.isOvertime">额外加班工时</el-checkbox>
-                                    <el-input :disabled="!domain.canEdit || domain.isOvertime==null || domain.isOvertime==0 || !domain.isOvertime" v-model="domain.overtimeHours" @blur="triggerCalculateOT(index)" @input="domain.overtimeHours=domain.overtimeHours.replace(/[^\d.]/g,'')" style="width: 100px;"></el-input><span style="margin-left:5px">{{$t('time.hour')}}</span>
+                                    <el-checkbox :disabled="!domain.canEdit" v-model="domain.isOvertime" @change="seleChn(0,domain)">额外加班工时</el-checkbox>
+                                    <el-input :disabled="!domain.canEdit || domain.isOvertime==null || domain.isOvertime==0 || !domain.isOvertime" v-model="domain.overtimeHours" @blur="(user.timeType.timeInputNormal?seleChn(0, domain):null);triggerCalculateOT(index)" @input="domain.overtimeHours=domain.overtimeHours.replace(/[^\d.]/g,'')" style="width: 100px;"></el-input><span style="margin-left:5px">{{$t('time.hour')}}</span>
                                 </div>
-                                ,&nbsp;&nbsp;总工时:{{ parseFloat(domain.totalWorkingTime||0) + parseFloat(domain.overtimeHours || 0)}} 小时
+                                ,&nbsp;&nbsp;合计:{{ domain.workingTime }} 小时
                             </el-form-item>
                         </template>
-                        <template v-else> -->
+                        <template v-else>
                             <el-form-item v-if="reportTimeType.type != 3 && !(permissions.reportHideWorkingHours && workForm.domains[index].state == 1)" :label="reportTimeType.type ==2?$t('screening.workHours'):$t('screening.workTime')" :prop="'domains.' + index + '.'+timeFields[reportTimeType.type]"
                                 :rules="{ required: true, message: $t('defaultText.pleaseSelectWorkingHours'), trigger: 'blur' }">
                                 <el-select v-model="domain.timeType" style="width:200px;"
@@ -598,8 +604,7 @@
                                     <el-input :disabled="!domain.canEdit || domain.isOvertime==null || domain.isOvertime==0 || !domain.isOvertime" v-model="domain.overtimeHours" @blur="triggerCalculateOT(index)" @input="domain.overtimeHours=domain.overtimeHours.replace(/[^\d.]/g,'')" style="width: 100px;"></el-input><span style="margin-left:5px">{{$t('time.hour')}}</span>
                                 </div>
                             </el-form-item>
-
-                        <!-- </template> -->
+                        </template>
                         
                         <el-form-item :label="$t('tianBaoBuMen')" v-if="user.timeType.userWithMultiDept == 1 && userReportDeptList.length > 0"
                             :prop="'domains.' + index + '.reportTargetDeptId'"
@@ -657,10 +662,6 @@
                                 @click="getProjectRemainingTime(workForm.domains[index])"></el-button>
                             </template>
                             
-                            <el-link v-if="(index >= 1 || workForm.domains.length > 1)&&domain.canEdit" type="primary" :underline="false" @click="delDomain(index)" style="float:right;margin-right:15%;"
-                                :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)">
-                                <i class="fa fa-trash" style="color: red;;font-size:18px;"></i>
-                            </el-link>
                             <!-- <el-link type="primary" v-if="canEdit"
                                 :underline="false" style="margin-left:10px;" @click="copyProject(index)">复制</el-link> -->
                             <!--针对柘中,显示项目对应的工程分类-->
@@ -1091,24 +1092,17 @@
                             </div>
                             <el-link size="small" @click="addNewWorktime(index, domain)" style="margin-left:15px;margin-top:5px;margin-bottom:5px;">{{$t('other.AddWorkTime')}}</el-link>
                         </div>
-
-                        <!--照片的显示 -->
-                        <!-- <p v-if="domain.pics != null && domain.pics.length > 0" style="text-align:center;"> 
-                            <el-image v-for="(pic, index) in domain.pics" :key="index"
-                                style="width: 100px; height: 100px; margin-right:10px;"
-                                :src="pic" 
-                                :preview-src-list="domain.pics">
-                            </el-image>
-                        </p>
-                        <el-divider v-if="workForm.domains.length>1" style="margin-bottom:10px;"></el-divider> -->
-
                     </div>
                     <span id="workFormsItemBottom"></span>
                     <template v-if="yonghuUser.type != 3">
-                        <el-link v-if="showAddMore" type="primary" :underline="false" @click="addDomain(reportTimeType.type)" style="margin-left:40px;">{{$t('other.addMore')}}</el-link>
+                        <div v-if="showAddMore" style="text-align: center;">
+                            <el-button type="primary" plain :underline="false" @click="addDomain(reportTimeType.type)" style="width: 300px;margin-top:10px;">+ 添加更多项目</el-button>
+                        </div>
                     </template>
                     <template v-if="yonghuUser.type == 3">
-                        <el-link v-if="canEdit" type="primary" :underline="false" @click="addDomain(reportTimeType.type)" style="margin-left:40px;">{{$t('other.addMore')}}</el-link>
+                        <div v-if="canEdit" style="text-align: center;">
+                            <el-button type="primary" plain :underline="false" @click="addDomain(reportTimeType.type)" style="width: 300px;margin-top:10px;">+ 添加更多项目</el-button>
+                        </div>
                     </template>
                 </el-form>
             </div>
@@ -4666,6 +4660,12 @@
                     this.seleChn(0)
                 }
             },
+            calculateWorkingTime(domain) {
+                if (domain != null && this.user.timeType.timeInputNormal) {
+                    //需要计算合计工时
+                    domain.workingTime = parseFloat(domain.normalWorkingTime||0) + (domain.isOvertime?parseFloat(domain.overtimeHours||0):0.0);
+                }
+            },
             seleChn(e,domain) {
                 if(e == 1) {
                     for(var i in this.workForm.domains) {
@@ -4676,6 +4676,9 @@
                         }
                     }
                 }
+                if (this.user.timeType.timeInputNormal) {
+                    this.calculateWorkingTime(domain);
+                }
                 var quanbu = 0 
                 var spl = this.workForm.domains
                 var zhi = ''
@@ -4686,65 +4689,67 @@
                 }
                 this.jsTime = quanbu
                 this.totalReportHours = quanbu
-                let worktime = this.jsTime
-                
-                // 自动计算加班时长
-                if(this.isBatch != 0){
-                    worktime = this.jsTime / this.jsDay
-                }
-                if(this.user.timeType.fillOvertime && domain){
-                    let isover = false
-                    let alltime = 0
-                    let allover = 0     //此处alltime同上面的worktime
-                    for(let d in spl){
-                        if(spl[d].isOvertime){
-                            isover = true
-                            allover += spl[d].overtimeHours*1
-                        }
-                        alltime += spl[d].workingTime*1
-                    }
-                    if(domain.overtimeHours){
-                        allover = allover - domain.overtimeHours
-                    }
-                    if(worktime*1 > this.user.timeType.allday){
-                        if(isover){
-                            if(alltime > (allover + this.user.timeType.allday)){
-                                    this.$set(domain,'isOvertime',true)
-                                    this.$set(domain,'overtimeHours',worktime - this.user.timeType.allday - allover)
-                            }else{
-                                this.$set(domain,'isOvertime',false)
-                                this.$set(domain,'overtimeHours',null)
-                                if(alltime < (allover + this.user.timeType.allday)){
-                                    let overtime = allover + this.user.timeType.allday - alltime
-                                    for(let pi in spl){
-                                        if(spl[pi].overtimeHours){
-                                            if((overtime - spl[pi].overtimeHours*1) > 0){
-                                                overtime = overtime - spl[pi].overtimeHours*1
-                                                this.$set(spl[pi],'isOvertime',false)
-                                                this.$set(spl[pi],'overtimeHours',null)
-                                            }else if((overtime - spl[pi].overtimeHours*1) < 0){
-                                                this.$set(spl[pi],'overtimeHours',spl[pi].overtimeHours*1 - overtime)
-                                                break
-                                            }else{
-                                                this.$set(spl[pi],'isOvertime',false)
-                                                this.$set(spl[pi],'overtimeHours',null)
-                                                break
+                if (!this.user.timeType.timeInputNormal) {
+                    let worktime = this.jsTime
+                    // 自动计算加班时长
+                    if(this.isBatch != 0){
+                        worktime = this.jsTime / this.jsDay
+                    }
+                    if(this.user.timeType.fillOvertime && domain){
+                        let isover = false
+                        let alltime = 0
+                        let allover = 0     //此处alltime同上面的worktime
+                        for(let d in spl){
+                            if(spl[d].isOvertime){
+                                isover = true
+                                allover += spl[d].overtimeHours*1
+                            }
+                            alltime += spl[d].workingTime*1
+                        }
+                        if(domain.overtimeHours){
+                            allover = allover - domain.overtimeHours
+                        }
+                        if(worktime*1 > this.user.timeType.allday){
+                            if(isover){
+                                if(alltime > (allover + this.user.timeType.allday)){
+                                        this.$set(domain,'isOvertime',true)
+                                        this.$set(domain,'overtimeHours',worktime - this.user.timeType.allday - allover)
+                                }else{
+                                    this.$set(domain,'isOvertime',false)
+                                    this.$set(domain,'overtimeHours',null)
+                                    if(alltime < (allover + this.user.timeType.allday)){
+                                        let overtime = allover + this.user.timeType.allday - alltime
+                                        for(let pi in spl){
+                                            if(spl[pi].overtimeHours){
+                                                if((overtime - spl[pi].overtimeHours*1) > 0){
+                                                    overtime = overtime - spl[pi].overtimeHours*1
+                                                    this.$set(spl[pi],'isOvertime',false)
+                                                    this.$set(spl[pi],'overtimeHours',null)
+                                                }else if((overtime - spl[pi].overtimeHours*1) < 0){
+                                                    this.$set(spl[pi],'overtimeHours',spl[pi].overtimeHours*1 - overtime)
+                                                    break
+                                                }else{
+                                                    this.$set(spl[pi],'isOvertime',false)
+                                                    this.$set(spl[pi],'overtimeHours',null)
+                                                    break
+                                                }
                                             }
                                         }
                                     }
                                 }
+                            }else{
+                                this.$set(domain,'isOvertime',true)
+                                this.$set(domain,'overtimeHours',worktime - this.user.timeType.allday)
                             }
                         }else{
-                            this.$set(domain,'isOvertime',true)
-                            this.$set(domain,'overtimeHours',worktime - this.user.timeType.allday)
-                        }
-                    }else{
-                        for(let di in spl){
-                            this.$set(spl[di],'isOvertime',false)
-                            this.$set(spl[di],'overtimeHours',null)
+                            for(let di in spl){
+                                this.$set(spl[di],'isOvertime',false)
+                                this.$set(spl[di],'overtimeHours',null)
+                            }
                         }
                     }
                 }
+                
             },
             iptChang() {
                 var sl = this.workForm.domains
@@ -7489,13 +7494,16 @@
                                     serviceList: list.report[i].serviceList,
                                     sapServiceId: list.report[i].sapServiceId,
                                     reportTargetDeptId: list.report[i].deptId,
-                                    auditWorkflow: list.report[i].auditWorkflow
+                                    auditWorkflow: list.report[i].auditWorkflow,
                                 }
                                 if (this.user.timeType.reportAuditType != 1 && this.user.timeType.reportAuditType != 2 && this.user.timeType.reportAuditType != 9) {
                                     //分组负责人审核的情况下,前端不需要显示,无需设置
                                     copyData.projectAuditorId = list.report[i].projectAuditorId;
                                     copyData.projectAuditorName = list.report[i].projectAuditorName;
                                 }
+                                if (this.user.timeType.timeInputNormal) {
+                                    copyData.normalWorkingTime = copyData.workingTime - copyData.overtimeHours;
+                                }
                                 
                                 if (this.allConstructionStages.length > 0) {
                                     copyData.engineeringCategory = this.fillProjectList.filter(p=>p.id == copyData.projectId)[0].plate1;
@@ -7588,6 +7596,9 @@
                             if(res.data.timeType.type == 3) {
                                 copyWorkForm.totalDuration = res.data.timeType.allday
                             }
+                            if (this.user.timeType.timeInputNormal) {
+                                copyWorkForm.domains[0].normalWorkingTime = copyWorkForm.domains[0].workingTime;
+                            }
                             this.workForm = copyWorkForm
                             // businessTrips 有数据的情况下
                             const businessTrips = res.data.businessTrips || []
@@ -11032,4 +11043,20 @@
         opacity: 1;
         box-shadow: 0 6px 20px 0 rgba(102, 126, 234, 0.6);
     }
+    .time_box {
+        margin-right:15px;
+    }
+    .time_title {
+        margin: 0px;
+        background: #f3f3f3;
+        margin-bottom:15px;
+        font-size:13px;
+        padding:0 0 0 39px;
+        display: flex;
+        align-items: center;
+        height: 30px;
+        box-sizing: border-box;
+        position: relative;
+        border-radius: 4px;
+    }
 </style>

+ 57 - 41
fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/index.vue

@@ -179,12 +179,9 @@
                             @cancel="item.showPickerTaskGroup = false; $forceUpdate();" />
                     </van-popup> -->
 
-                    <van-popup v-model="item.showPickerTaskGroup" position="bottom" :style="{ height: '80vh' }" @click-overlay="item.showPickerTaskGroup = false;$forceUpdate();">
-                        <div class="groupingSelection">
-                            <div v-for="(taskItem, taskIndex) in item.taskGroups" :key="taskIndex" class="groupingSelectionItem" @click="choseTaskGroup(taskItem, taskIndex)">
-                                {{ taskItem.name }}
-                            </div>
-                        </div>
+                    <van-popup v-model="item.showPickerTaskGroup" position="bottom">
+                        <van-picker show-toolbar :columns="item.taskGroups" value-key="name" @confirm="choseTaskGroup"
+                            @cancel="item.showPickerTaskGroup = false; $forceUpdate();" />
                     </van-popup>
 
                     <!--工作职责-->
@@ -444,10 +441,19 @@
                     </van-popup>
                     <!-- 全天上下午模式 -->
                     <div v-if="reportTimeType.multiWorktime == 0 && (!hideWorkingHours || (hideWorkingHours && item.canEdit)) ">
-                        <van-field v-if="reportTimeType.type < 2" readonly clickable :disabled="!item.canEdit"
+                        <template v-if="user.timeType.timeInputNormal">
+                            <van-field readonly clickable :disabled="!item.canEdit"
+                            :value="reportTimeType.type == 0 ? item.label : (parseFloat(item.normalWorkingTime).toFixed(1) + 'h')"
+                            label="正常工时" placeholder="请选择正常工时(小时)" @click="clickTimePicker(index, item)"
+                            :rules="[{ required: true, message: '请选择正常工时' }]" />
+                        </template>
+                        <template v-else>
+                            <van-field v-if="reportTimeType.type < 2" readonly clickable :disabled="!item.canEdit"
                             :value="reportTimeType.type == 0 ? item.label : (parseFloat(item.workingTime).toFixed(1) + 'h')"
                             label="工作时长" placeholder="请选择工作时长(小时)" @click="clickTimePicker(index, item)"
                             :rules="[{ required: true, message: '请选择工作时长' }]" />
+                        </template>
+                        
                         <van-popup v-model="showPickerTime" position="bottom">
                             <van-picker show-toolbar :columns="timeType" value-key="label" @confirm="choseTimePick"
                                 @cancel="showPickerTime = false" />
@@ -556,10 +562,10 @@
                         v-if="((user.timeType.fillOvertime || (isWeekend && user.timeType.lockWorktime != 1)) || (isCorpWX && canEdit)) && (!hideWorkingHours || (hideWorkingHours && item.canEdit))">
                         <div class="overTimeClas"
                             v-if="user.timeType.fillOvertime || (isWeekend && user.timeType.lockWorktime != 1)">
-                            <van-checkbox :disabled="!item.canEdit" v-model="item.isOvertime"
-                                style="width: 4.3rem;">含加班</van-checkbox>
+                            <van-checkbox :disabled="!item.canEdit" v-model="item.isOvertime" @change="calculateWorkingTime(item)"
+                                style="width: 4.3rem;">{{user.timeType.timeInputNormal?'额外加班':'含加班'}}</van-checkbox>
                             <van-field v-model="item.overtimeHours" type="number"
-                                :disabled="!item.canEdit || item.isOvertime == null || item.isOvertime == 0 || !item.isOvertime"
+                                :disabled="!item.canEdit || item.isOvertime == null || item.isOvertime == 0 || !item.isOvertime" @blur="calculateWorkingTime(item)"
                                 placeholder="请输入加班时长" style="width: 5.2rem" @input="$forceUpdate()"></van-field>
                             <span :class="item.canEdit ? 'overListTime' : 'overListTime hoveOver'">小时</span>
                         </div>
@@ -1683,24 +1689,12 @@ export default {
                 if (this.reportTimeType.multiWorktime == 1) {
                     for (let m in domains[i].worktimeList) {
                         if (domains[i].worktimeList[m].startTime && domains[i].worktimeList[m].endTime) {
-                            // hours += this.getHour(domains[i].worktimeList[m].startTime, domains[i].worktimeList[m].endTime)
                             timeArr.push({ startTime: domains[i].worktimeList[m].startTime, endTime: domains[i].worktimeList[m].endTime })
                         }
                     }
                 } else {
                     if (this.user.timeType.type == 2) {
                         if (domains[i].startTime && domains[i].endTime) {
-                            // let selectionTime = this.getHour(domains[i].startTime, domains[i].endTime)
-                            // let subtractedData = 0
-                            // let arr = JSON.parse(JSON.stringify(this.vacationTime))
-                            // arr.unshift({s: domains[i].startTime, e: domains[i].endTime})
-                            // for(var j in arr) {
-                            //     subtractedData += +this.timeOverlap(j, arr)
-                            // }
-                            // console.log(selectionTime, subtractedData)
-                            // hours += +selectionTime - +subtractedData
-                            // console.log(hours)
-                            // arrNum.push(+selectionTime - +subtractedData)
                             timeArr.push({ startTime: domains[i].startTime, endTime: domains[i].endTime })
                         }
                     } else {
@@ -1709,8 +1703,6 @@ export default {
                 }
             }
 
-            // this.totalReportHours = hours.toFixed(2)
-            console.log('timeArr', timeArr)
             if (this.reportTimeType.multiWorktime == 1 || this.user.timeType.type == 2) {
                 const { timeCanOverlap } = this.reportTimeType // timeCanOverlap 为零时校验不允许重叠
                 if(timeCanOverlap == 0) {
@@ -1762,6 +1754,12 @@ export default {
 
             return options;
         },
+        calculateWorkingTime(domain) {
+            if (this.user.timeType.timeInputNormal) {
+                domain.workingTime = parseFloat(domain.normalWorkingTime||0) + (domain.isOvertime?parseFloat(domain.overtimeHours||0):0);
+                this.setTotalReportHours();
+            }
+        },
         choseTimePick(value, index) {
             if (value == null || value == undefined) {
                 return
@@ -1774,27 +1772,35 @@ export default {
                 this.showPickerTime = false;
             } else if (this.reportTimeType.type == 1) {
                 // console.log('this.reportTimeType.type=='+value,this.form.domains);
-                this.form.domains[this.clickTimeIndex].workingTime = value;
+                if (this.user.timeType.timeInputNormal) {
+                    this.form.domains[this.clickTimeIndex].normalWorkingTime = value;
+                    this.calculateWorkingTime(this.form.domains[this.clickTimeIndex]);
+                } else {
+                    this.form.domains[this.clickTimeIndex].workingTime = value;
+                }
+                
                 this.form.domains[this.clickTimeIndex].label = value.toFixed(1) + '小时';
                 this.showPickerHours = false;
 
-                let allhour = 0
-                for (let i in this.form.domains) {
-                    if (this.isWeekend) {
-                        this.form.domains[i].isOvertime = true
-                        this.form.domains[i].overtimeHours = this.form.domains[i].workingTime
-                    } else {
-                        this.form.domains[i].isOvertime = false
-                        delete this.form.domains[i].overtimeHours
+                
+                if (!this.user.timeType.timeInputNormal) {
+                    let allhour = 0
+                    for (let i in this.form.domains) {
+                        if (this.isWeekend) {
+                            this.form.domains[i].isOvertime = true
+                            this.form.domains[i].overtimeHours = this.form.domains[i].workingTime
+                        } else {
+                            this.form.domains[i].isOvertime = false
+                            delete this.form.domains[i].overtimeHours
+                        }
+                        allhour += this.form.domains[i].workingTime * 1
                     }
-                    allhour += this.form.domains[i].workingTime * 1
-                }
-                if (allhour > this.user.timeType.allday && !this.isWeekend) {
-                    this.form.domains[this.clickTimeIndex].isOvertime = true
-                    this.form.domains[this.clickTimeIndex].overtimeHours = allhour - this.user.timeType.allday
-                }
+                    if (allhour > this.user.timeType.allday && !this.isWeekend) {
+                        this.form.domains[this.clickTimeIndex].isOvertime = true
+                        this.form.domains[this.clickTimeIndex].overtimeHours = allhour - this.user.timeType.allday
+                    }
+                } 
             }
-
             this.setTotalReportHours()
         },
         clickTimePicker(i, item) {
@@ -2256,6 +2262,10 @@ export default {
                                     copyData.projectAuditorId = list[i].projectAuditorId;
                                     copyData.projectAuditorName = list[i].projectAuditorName;
                                 }
+                                if (this.user.timeType.timeInputNormal) {
+                                    copyData.normalWorkingTime = copyData.workingTime - copyData.overtimeHours;
+                                }
+                                
                                 array.push(copyData);
                                 if (list[i].state >= 2) {
                                     this.canEdit = true;
@@ -2365,8 +2375,10 @@ export default {
                                 this.form.domains[0].basecostId = this.report.timeBasecostList[0].id;
                                 this.form.domains[0].basecostName = this.report.timeBasecostList[0].name;
                             }
+                            if (this.user.timeType.timeInputNormal) {
+                                this.form.domains[0].normalWorkingTime = this.form.domains[0].workingTime;
+                            }
                             this.canEdit = true;
-
                             this.setTotalReportHours()
                         }
                     } else {
@@ -2844,6 +2856,10 @@ export default {
                 canEdit: true,
                 constructionStages: [],
             }
+            if (this.user.timeType.timeInputNormal) {
+                //设置正常工时
+                item.normalWorkingTime = item.workingTime;
+            }
             if (this.isWeekend && this.user.timeType.lockWorktime != 1) {
                 this.$set(item, 'isOvertime', true)
                 if (this.reportTimeType.type == 3) {