Просмотр исходного кода

导入日报审核模块修改

seyason 3 лет назад
Родитель
Сommit
d78b7f982f
24 измененных файлов с 866 добавлено и 577 удалено
  1. 18 13
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java
  2. 36 18
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserCorpwxTimeController.java
  3. 13 3
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ReportMapper.java
  4. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/UserCorpwxTimeMapper.java
  5. 10 6
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ReportService.java
  6. 0 89
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DepartmentServiceImpl.java
  7. 53 39
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DingDingServiceImpl.java
  8. 359 260
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  9. 5 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/UserServiceImpl.java
  10. 140 45
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/WxCorpInfoServiceImpl.java
  11. 74 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java
  12. 4 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/DateTimeUtil.java
  13. 16 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/WorkDayCalculateUtils.java
  14. 1 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/application.yml
  15. 62 6
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportMapper.xml
  16. 0 3
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/UserCorpwxTimeMapper.xml
  17. 7 2
      fhKeeper/formulahousekeeper/timesheet/src/main.js
  18. 5 5
      fhKeeper/formulahousekeeper/timesheet/src/views/corpreport/list.vue
  19. 3 25
      fhKeeper/formulahousekeeper/timesheet/src/views/project/projectInside.vue
  20. 1 1
      fhKeeper/formulahousekeeper/timesheet/src/views/task/list.vue
  21. 11 22
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue
  22. 9 7
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/list_department.vue
  23. 24 20
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/list_import.vue
  24. 14 9
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/review/department_list.vue

+ 18 - 13
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java

@@ -601,8 +601,8 @@ public class ReportController {
      * reportIds 报告id
      */
     @RequestMapping("/approve")
-    public HttpRespMsg approveReport(@RequestParam String id, @RequestParam String reportIds,HttpServletRequest request) {
-        return reportService.approveReport(id, reportIds, request);
+    public HttpRespMsg approveReport(@RequestParam String reportIds, Integer isDepartment, HttpServletRequest request) {
+        return reportService.approveReport(reportIds,isDepartment, request);
     }
 
 
@@ -612,8 +612,8 @@ public class ReportController {
      * date 日期 格式yyyy-mm-dd
      */
     @RequestMapping("/deny")
-    public HttpRespMsg denyReport(@RequestParam String id, @RequestParam String date, @RequestParam String reportIds, String reason, HttpServletRequest request) {
-        return reportService.denyReport(id, date,reportIds, reason, request);
+    public HttpRespMsg denyReport(@RequestParam String date, @RequestParam String reportIds, String reason, Integer isDepartment, HttpServletRequest request) {
+        return reportService.denyReport(date,reportIds, reason, isDepartment, request);
     }
 
     /**
@@ -638,13 +638,13 @@ public class ReportController {
     }
 
     @RequestMapping("/batchApproveReport")
-    public HttpRespMsg batchApproveReport(@RequestParam String ids, HttpServletRequest request) {
-        return reportService.batchApproveReport(ids, request);
+    public HttpRespMsg batchApproveReport(@RequestParam String ids, Integer isDepartment, HttpServletRequest request) {
+        return reportService.batchApproveReport(ids, isDepartment, request);
     }
 
     @RequestMapping("/batchDenyReport")
-    public HttpRespMsg batchDenyReport(@RequestParam String ids, HttpServletRequest request) {
-        return reportService.batchDenyReport(ids, request);
+    public HttpRespMsg batchDenyReport(@RequestParam String ids, Integer isDepartment, HttpServletRequest request) {
+        return reportService.batchDenyReport(ids, isDepartment, request);
     }
 
     @RequestMapping("/getUserDailyWorkTime")
@@ -679,17 +679,22 @@ public class ReportController {
 
     @RequestMapping("/listImportByState")
     public HttpRespMsg listDeptImportByState(
-                                      Integer departmentId,
                                       Integer projectId,
-                                      String date,
+                                      String startDate,
+                                      String endDate,
+                                      Integer departmentId,
                                       HttpServletRequest request) {
-        int state = -1;//待部门上级审核
         String token = request.getHeader("TOKEN");
         User user = userService.getById(token);
 
-        return reportService.listDeptImportByState(state, user.getId(),
+        return reportService.listDeptImportByState(user.getId(),
                 projectId,
-                date,request);
+                startDate, endDate, departmentId, request);
+    }
+
+    @RequestMapping("/getlastWeekFillTime")
+    public HttpRespMsg getlastWeekFillTime(String userId) {
+        return reportService.getlastWeekFillTime(userId);
     }
 }
 

+ 36 - 18
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserCorpwxTimeController.java

@@ -4,15 +4,14 @@ package com.management.platform.controller;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.management.platform.entity.Participation;
-import com.management.platform.entity.Project;
-import com.management.platform.entity.Report;
-import com.management.platform.entity.User;
+import com.management.platform.entity.*;
 import com.management.platform.mapper.*;
 import com.management.platform.service.ReportService;
 import com.management.platform.util.ExcelUtil;
 import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.WorkDayCalculateUtils;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.format.annotation.DateTimeFormat;
 import org.springframework.web.bind.annotation.RequestMapping;
 
 import org.springframework.web.bind.annotation.RestController;
@@ -64,16 +63,37 @@ public class UserCorpwxTimeController {
         String token = request.getHeader("TOKEN");
         User user = userMapper.selectById(token);
         List<Map> list = new ArrayList<Map>();
-        int excludeWeekend = 1;//排除周末两天
+        int onlyWorkDays = 1;//只要工作日
         if (user.getRole() == 1 || user.getRole() == 2) {
             //管理员查看全部人员的
-            list = userCorpwxTimeMapper.getUserDataList(user.getCompanyId(), startDate, endDate, null, excludeWeekend);
+            list = userCorpwxTimeMapper.getUserDataList(user.getCompanyId(), startDate, endDate, null);
         } else {
             Integer manageDeptId = user.getManageDeptId();
             if (manageDeptId != null && manageDeptId != 0) {
-                list = userCorpwxTimeMapper.getUserDataList(user.getCompanyId(), startDate, endDate, manageDeptId, excludeWeekend);
+                //一个人可能担任多个部门负责人
+                List<Department> departments = departmentMapper.selectList(new QueryWrapper<Department>().eq("manager_id", user.getId()));
+                if (departments.size() == 1) {
+                    list = userCorpwxTimeMapper.getUserDataList(user.getCompanyId(), startDate, endDate, manageDeptId);
+                } else {
+                    for (Department d:departments) {
+                        list.addAll(userCorpwxTimeMapper.getUserDataList(user.getCompanyId(), startDate, endDate, d.getDepartmentId()));
+                    }
+                }
             }
         }
+
+        //工作日处理,排除常规周末和法定节假日
+        if (onlyWorkDays == 1) {
+            DateTimeFormatter dtf =  DateTimeFormatter.ofPattern("yyyy/MM/dd");
+            list = list.stream().filter(time->{
+                String date = (String)time.get("createDate");
+                if (WorkDayCalculateUtils.isWorkDay(LocalDate.parse(date, dtf))) {
+                    return true;
+                } else {
+                    return false;
+                }
+            }).collect(Collectors.toList());
+        }
         HashMap item = new HashMap();
         item.put("list", list);
         if (list.size() > 0) {
@@ -159,9 +179,6 @@ public class UserCorpwxTimeController {
         String token = request.getHeader("TOKEN");
         User user = userMapper.selectById(token);
         Integer manageDeptId = user.getManageDeptId();
-        if (manageDeptId != null && manageDeptId != 0) {
-
-        }
 
         HttpRespMsg ret = getMyDeptMembsData(startDate, endDate);
         HashMap map = (HashMap)ret.data;
@@ -176,10 +193,10 @@ public class UserCorpwxTimeController {
         titles.add("员工姓名");
         titles.add("上班时间");
         titles.add("下班时间");
-        titles.add("打卡时长");
-        titles.add("请假时长");
-        titles.add("补卡/外出时长");
-        titles.add("工作时长");
+//        titles.add("打卡时长");
+//        titles.add("请假时长");
+//        titles.add("补卡/外出时长");
+        titles.add("实际工作时长");
         //添加项目名称作为列名
         for (String p : projects) {
             titles.add(p);
@@ -194,9 +211,9 @@ public class UserCorpwxTimeController {
             dataList.add((String)dataItem.get("username"));
             dataList.add((String)dataItem.get("startTime"));
             dataList.add((String)dataItem.get("endTime"));
-            dataList.add(""+(Double)dataItem.get("cardTime"));
-            dataList.add(""+(Double)dataItem.get("askLeaveTime"));
-            dataList.add(""+(Double)dataItem.get("outdoorTime"));
+//            dataList.add(""+(Double)dataItem.get("cardTime"));
+//            dataList.add(""+(Double)dataItem.get("askLeaveTime"));
+//            dataList.add(""+(Double)dataItem.get("outdoorTime"));
             dataList.add(""+(Double)dataItem.get("workHours"));
             for (String p : projects) {
                 dataList.add("");
@@ -205,7 +222,8 @@ public class UserCorpwxTimeController {
         }
         String fileName = companyMapper.selectById(user.getCompanyId()).getCompanyName();
         if (manageDeptId != null && manageDeptId != 0) {
-            String departmentName = departmentMapper.selectById(manageDeptId).getDepartmentName();
+            List<Department> allDeptList = departmentMapper.selectList(new QueryWrapper<Department>().eq("manager_id", user.getId()));
+            String departmentName = allDeptList.stream().map(Department::getDepartmentName).collect(Collectors.joining("+"));
             fileName = departmentName;
         }
         fileName += "_人员工时统计模板"+startDate+"至"+endDate;

+ 13 - 3
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ReportMapper.java

@@ -31,6 +31,12 @@ public interface ReportMapper extends BaseMapper<Report> {
     //获取项目经理所管理的人员的报告
     List<Map<String, Object>> getInchargeReportByDate(@Param("date") String date, @Param("id") String id, @Param("state") Integer state);
 
+    //获取待日报审核的列表
+    List<Map<String, Object>> getAuditReportList(@Param("date") String date, @Param("companyId") Integer companyId,
+                                                 @Param("departmentId") Integer departmentId,
+                                                 @Param("projectId") Integer projectId,
+                                                 @Param("inchargerId") String inchargerId,
+                                                 @Param("isEngeering") Integer isEngeering);
     //获取本人负责的专业的相关的日报
     List<Map<String, Object>> getProfessionInchargeReportByDate(@Param("date") String date,
                                                                 @Param("id") String id,
@@ -69,7 +75,11 @@ public interface ReportMapper extends BaseMapper<Report> {
 
     List<Report> selectSimpleTime(Integer companyId, String startDate, String endDate);
 
-    List<Map<String, Object>> getDetailImportByState(@Param("state") Integer state,
-                                               @Param("companyId") Integer companyId,
-                                               @Param("leaderId") String leaderId);
+    List<Map<String, Object>> getDeptImportAuditList(@Param("companyId") Integer companyId,
+                                               @Param("leaderId") String leaderId,
+                                                     @Param("startDate") String startDate,
+                                                     @Param("endDate") String endDate,
+                                                     @Param("departmentIdList") List<Integer> departmentIdList,
+                                                     @Param("projectId") Integer projectId
+                                                     );
 }

+ 1 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/UserCorpwxTimeMapper.java

@@ -16,5 +16,5 @@ import java.util.Map;
  */
 public interface UserCorpwxTimeMapper extends BaseMapper<UserCorpwxTime> {
 
-    public List<Map> getUserDataList(Integer companyId, String startDate, String endDate, Integer deptId, Integer excludeWeekend);
+    public List<Map> getUserDataList(Integer companyId, String startDate, String endDate, Integer deptId);
 }

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

@@ -35,9 +35,9 @@ public interface ReportService extends IService<Report> {
                                Integer projectId,
                                String date,HttpServletRequest request);
 
-    HttpRespMsg approveReport(String id, String reportIds, HttpServletRequest request);
+    HttpRespMsg approveReport(String reportIds, Integer isDepartment, HttpServletRequest request);
 
-    HttpRespMsg denyReport(String id, String date, String reportIds, String reason, HttpServletRequest request);
+    HttpRespMsg denyReport(String date, String reportIds, String reason, Integer isDepartment, HttpServletRequest request);
 
     HttpRespMsg singleApproveReport(Integer id, HttpServletRequest request);
 
@@ -45,8 +45,8 @@ public interface ReportService extends IService<Report> {
 
     HttpRespMsg getMembList(String date, Integer manageDeptId, HttpServletRequest request);
 
-    HttpRespMsg batchApproveReport(String ids, HttpServletRequest request);
-    HttpRespMsg batchDenyReport(String ids, HttpServletRequest request);
+    HttpRespMsg batchApproveReport(String ids, Integer isDepartment, HttpServletRequest request);
+    HttpRespMsg batchDenyReport(String ids, Integer isDepartment, HttpServletRequest request);
 
     HttpRespMsg cancelReport(String userId, String reportIds, HttpServletRequest request);
 
@@ -64,7 +64,11 @@ public interface ReportService extends IService<Report> {
 
     HttpRespMsg saveProjectTime(Integer companyId, List<Report> reportList, JSONArray userReportArray);
 
-    HttpRespMsg listDeptImportByState(Integer state, String leaderId,
+    HttpRespMsg listDeptImportByState(String leaderId,
                                Integer projectId,
-                               String date,HttpServletRequest request);
+                               String startDate,
+                               String endDate,
+                                      Integer deprarmtentId, HttpServletRequest request);
+
+    HttpRespMsg getlastWeekFillTime(String userId);
 }

+ 0 - 89
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DepartmentServiceImpl.java

@@ -222,95 +222,6 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
                 fillSubDepartmentList(departmentList, rootDeptVO);
             });
 
-
-//            Stack<DepartmentVO>
-//                    //主栈 存放顺序依赖下半段
-//                    stack1 = new Stack<>(),
-//                    //副栈 存放主栈中依赖被切开后的上半段
-//                    stack2 = new Stack<>();
-//            //遍历一次 把其中无父级的部门PO取出来转换成部门VO放入主栈中 并将其从原始部门数据中移除
-//            for (int i = 0; i < departmentList.size(); i++) {
-//                Department department = departmentList.get(i);
-//                if (department.getSuperiorId() == null) {
-//                    stack1.push(formatDepartmentToVO(department));
-//                    departmentList.remove(i--);
-//                }
-//            }
-            //在原始部门数据移除之前无限循环 将列表里的元素全部按照顺序放进主栈和副栈当中
-//            while (departmentList.size() > 0) {
-//                //用来判断主栈最上方那个部门是 false-本来就在的 还是 true-刚被加入进去的
-//                Boolean isPushed = false;
-//                //偷看顶部元素
-//                DepartmentVO temp = stack1.peek();
-//                //遍历一次原始数据列表
-//                for (int i = 0; i < departmentList.size(); i++) {
-//                    //如果列表中有任何主栈顶部门的子部门
-//                    Department department = departmentList.get(i);
-//                    if (department.getSuperiorId().equals(temp.getId())) {
-//                        //设定主栈最上方的部门是刚放进去的 本次循环中不要向外排
-//                        isPushed = true;
-//                        //那就转换成部门VO放入主栈
-//                        stack1.push(formatDepartmentToVO(department));
-//                        //从列表中移除部门
-//                        departmentList.remove(i--);
-//                    }
-//                }
-//                //如果主栈最上方部门不是刚被加进去的而是一开始循环遍历时的那个
-//                if (!isPushed) {
-//                    //也就是说这个最上方部门并没有子部门 所以排出来扔进副栈
-//                    stack2.push(stack1.pop());
-//                }
-//            }
-//            //开始从主栈中向外排
-//            while (!stack1.isEmpty()) {
-//                //取得栈顶部门及其父部门id
-//                DepartmentVO first = stack1.pop();
-//                Integer superiorId = first.getParentId();
-//                //如果没有父部门id 那就直接放进最终列表当中
-//                if (superiorId != null) {
-//                    List<DepartmentVO> targetList = new ArrayList<>();
-//                    //有父部门的话 那么下方很可能也是相同的父部门 所以要把类似的它们存入最终栈中
-//                    targetList.add(first);
-//                    //把副栈中所有相同父部门的部门存入最终栈
-//                    while (!stack2.isEmpty() &&
-//                            stack2.peek().getParentId() != null &&
-//                            stack2.peek().getParentId().equals(superiorId)) {
-//                        targetList.add(stack2.pop());
-//                    }
-//                    //把主栈中所有相同父部门的部门存入最终栈
-//                    while (stack1.peek().getParentId() != null && stack1.peek().getParentId().equals(superiorId)) {
-//                        targetList.add(stack1.pop());
-//                    }
-//                    //把这些部门装入父部门 也就是当前主栈栈顶的那个部门的children中
-//                    stack1.peek().setChildren(targetList);
-//                } else {
-//                    list.add(first);
-//                }
-//            }
-//            //这个时候主栈已经清空了 副栈中元素加入主栈中再来一次
-//            while (!stack2.isEmpty()) {
-//                stack1.push(stack2.pop());
-//            }
-//            //主栈再来一次 这次不用考虑副栈了
-//            while (!stack1.isEmpty()) {
-//                //取得栈顶部门及其父部门id
-//                DepartmentVO first = stack1.pop();
-//                Integer superiorId = first.getParentId();
-//                //如果没有父部门id 那就直接放进最终列表当中
-//                if (superiorId != null) {
-//                    List<DepartmentVO> targetList = new ArrayList<>();
-//                    //有父部门的话 那么下方很可能也是相同的父部门 所以要把类似的它们存入最终栈中
-//                    targetList.add(first);
-//                    //首先把主栈中所有相同父部门的部门存入最终栈
-//                    while (stack1.peek().getParentId() != null && stack1.peek().getParentId().equals(superiorId)) {
-//                        targetList.add(stack1.pop());
-//                    }
-//                    //把这些部门装入父部门 也就是当前主栈栈顶的那个部门的children中
-//                    stack1.peek().setChildren(targetList);
-//                } else {
-//                    list.add(first);
-//                }
-//            }
             //返回数据
             httpRespMsg.data = list;
         } catch (NullPointerException e) {

+ 53 - 39
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DingDingServiceImpl.java

@@ -30,7 +30,6 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
-import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.ZoneOffset;
 import java.util.ArrayList;
@@ -54,6 +53,8 @@ public class DingDingServiceImpl implements DingDingService {
     public static String PRE_AUTH_CODE = null;
     public static long expireTime = 0L;
 
+    private Object deptLock = new Object();
+    private Object userLock = new Object();
 
     @Resource
     private SysConfigMapper sysConfigMapper;
@@ -516,7 +517,7 @@ public class DingDingServiceImpl implements DingDingService {
             OapiV2DepartmentGetRequest req = new OapiV2DepartmentGetRequest();
             req.setDeptId(deptId);
             OapiV2DepartmentGetResponse rsp = client.execute(req, accessToken);
-            System.out.println(rsp.getBody());
+//            System.out.println(rsp.getBody());
             JSONObject json = JSONObject.parseObject(rsp.getBody());
             if (json.getInteger("errcode") == 0) {
                 JSONObject dept = json.getJSONObject("result");
@@ -531,20 +532,30 @@ public class DingDingServiceImpl implements DingDingService {
                 //检查,根部门是公司名称,不需要创建部门
                 if (departmentDingding.getDdDeptid() != 1) {
                     department.setDepartmentName(dept.getString("name"));
-                    //检查该部门是否已经创建
-                    List<Department> existDept = departmentMapper.selectList(new QueryWrapper<Department>().eq("company_id", companyId).eq("department_name", dept.getString("name")));
-                    if (existDept.size() > 0) {
-                        department = existDept.get(0);
-                    } else {
-                        departmentMapper.insert(department);
-                        departmentDingding.setSysDeptid(department.getDepartmentId());
-                        departmentDingdingMapper.insert(departmentDingding);
+                    synchronized (deptLock) {
+                        int cnt = departmentDingdingMapper.selectCount(new QueryWrapper<DepartmentDingding>()
+                                .eq("corpid", corpid)
+                                .eq("dd_deptid", departmentDingding.getDdDeptid()));
+                        //检查该部门是否已经创建,但是重名的可能是多个父部门下的同名子部门,所以不能用
+                        if (cnt > 0) {
+                            List<DepartmentDingding> departmentDingdings = departmentDingdingMapper.selectList(new QueryWrapper<DepartmentDingding>()
+                                    .eq("corpid", corpid)
+                                    .eq("dd_deptid", departmentDingding.getDdDeptid()));
+                            DepartmentDingding ddd = departmentDingdings.get(0);
+                            Integer sysDeptid = ddd.getSysDeptid();
+                            department = departmentMapper.selectById(sysDeptid);
+                        } else {
+                            departmentMapper.insert(department);
+                            departmentDingding.setSysDeptid(department.getDepartmentId());
+                            departmentDingdingMapper.insert(departmentDingding);
+                        }
                     }
                 }
 
-
                 //获取该部门下的人员, 如果是根部门,不会创建,人员的部门id会使用数据库默认的0
                 getDeptUserIdList(companyId, deptId, department.getDepartmentId(), accessToken);
+                //获取子部门
+                getDepartmentList(companyId, corpid, accessToken, departmentDingding.getDdDeptid(), department.getDepartmentId());
             }
 
         } catch (ApiException e) {
@@ -553,13 +564,13 @@ public class DingDingServiceImpl implements DingDingService {
     }
 
     //获取该部门下的人员和子部门列表,递归下一级子部门
-    public String getDepartmentList(Integer companyId, String corpid, String access_token, long parentDeptId, Integer parentSysDeptId) throws ApiException {
+    public  String getDepartmentList(Integer companyId, String corpid, String access_token, long parentDeptId, Integer parentSysDeptId) throws ApiException {
         DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
         OapiV2DepartmentListsubRequest req = new OapiV2DepartmentListsubRequest();
         req.setDeptId(parentDeptId);
         req.setLanguage("zh_CN");
         OapiV2DepartmentListsubResponse rsp = client.execute(req, access_token);
-        System.out.println("获取部门返回:"+rsp.getBody());
+//        System.out.println("获取部门返回:"+rsp.getBody());
         JSONObject json = JSONObject.parseObject(rsp.getBody());
         if (json.getInteger("errcode") == 0) {
             //正确返回的情况
@@ -575,16 +586,18 @@ public class DingDingServiceImpl implements DingDingService {
                 department.setDepartmentName(dept.getString("name"));
                 department.setCompanyId(companyId);
                 department.setSuperiorId(parentSysDeptId);
-                //检查部门是否重复
-                Integer count = department.selectCount(new QueryWrapper<Department>().eq("company_id", companyId).eq("department_name", department.getDepartmentName()));
-                if (count == 0) {
-                    departmentMapper.insert(department);
-                    departmentDingding.setSysDeptid(department.getDepartmentId());
-                    departmentDingdingMapper.insert(departmentDingding);
-                }
 
-                //获取该部门下的人员
-//                getDeptUserList(companyId, departmentDingding.getDdDeptid(), department.getDepartmentId(), access_token, 0L);
+                synchronized (deptLock) {
+                    //检查该部门是否已经创建,以钉钉deptid为唯一身份, 加上同步锁,防止递归请求的子部门和一级请求是同一个部门
+                    int cnt = departmentDingdingMapper.selectCount(new QueryWrapper<DepartmentDingding>()
+                            .eq("corpid", corpid)
+                            .eq("dd_deptid", departmentDingding.getDdDeptid()));
+                    if (cnt == 0) {
+                        departmentMapper.insert(department);
+                        departmentDingding.setSysDeptid(department.getDepartmentId());
+                        departmentDingdingMapper.insert(departmentDingding);
+                    }
+                }
                 //获取子部门的数据
                 getDepartmentList(companyId, corpid, access_token, departmentDingding.getDdDeptid(), department.getDepartmentId());
             }
@@ -602,7 +615,7 @@ public class DingDingServiceImpl implements DingDingService {
         OapiUserListidRequest req = new OapiUserListidRequest();
         req.setDeptId(ddDeptId);
         OapiUserListidResponse rsp = client.execute(req, access_token);
-        System.out.println("获取人员返回:"+rsp.getBody());
+//        System.out.println("获取人员返回:"+rsp.getBody());
         JSONObject resp = JSONObject.parseObject(rsp.getBody());
         if (resp.getInteger("errcode") == 0) {
             JSONArray jsonArray = resp.getJSONObject("result").getJSONArray("userid_list");
@@ -620,7 +633,7 @@ public class DingDingServiceImpl implements DingDingService {
         req.setUserid(dingdingUserid);
         req.setLanguage("zh_CN");
         OapiV2UserGetResponse rsp = client.execute(req, access_token);
-        System.out.println(rsp.getBody());
+//        System.out.println(rsp.getBody());
         JSONObject resp = JSONObject.parseObject(rsp.getBody());
         if (resp.getInteger("errcode") == 0) {
             JSONObject userJson = resp.getJSONObject("result");
@@ -646,23 +659,24 @@ public class DingDingServiceImpl implements DingDingService {
                 user.setDepartmentCascade(convertDepartmentIdToCascade(departmentId));
             }
             //检查用户是否已经存在
-            User oldUser = userMapper.selectOne(new QueryWrapper<User>().eq("dingding_userid", dingdingUserid).eq("company_id", companyId));
-            if (oldUser == null) {
-                userMapper.insert(user);
-            } else {
-                System.out.println("该人员已存在:dingdingUserid==" + dingdingUserid);
-                //可能需要更新姓名
-                if (oldUser.getName() == null) {
-                    oldUser.setName(userJson.getString("name"));
-                    oldUser.setDingdingUnionid(userJson.getString("unionid"));
-                    userMapper.updateById(oldUser);
-                    System.out.println("更新用户姓名==" + oldUser.getName());
-                }
-                //已有人员不做改动
+            synchronized (userLock) {
+                User oldUser = userMapper.selectOne(new QueryWrapper<User>().eq("dingding_userid", dingdingUserid).eq("company_id", companyId));
+                if (oldUser == null) {
+                    userMapper.insert(user);
+                } else {
+//                    System.out.println("该人员已存在:dingdingUserid==" + dingdingUserid);
+                    //可能需要更新姓名
+                    if (oldUser.getName() == null) {
+                        oldUser.setName(userJson.getString("name"));
+                        oldUser.setDingdingUnionid(userJson.getString("unionid"));
+                        userMapper.updateById(oldUser);
+                        System.out.println("更新用户姓名==" + oldUser.getName());
+                    }
+                    //已有人员不做改动
 //                User oldUser = userMapper.selectList(new QueryWrapper<User>().eq("dingding_userid", dingdingUserid).eq("company_id", companyId).orderByDesc("create_time")).get(0);
 //                oldUser.setName(userJson.getString("name"));
 //                oldUser.setDepartmentId(departmentId);
-                //不修改人员角色
+                    //不修改人员角色
 //                if (oldUser.getRole() == Constant.ROLE_EMPLOYEE) {
 //                    oldUser.setRole(user.getRole());
 //                }
@@ -670,8 +684,8 @@ public class DingDingServiceImpl implements DingDingService {
 //                    oldUser.setDepartmentCascade(convertDepartmentIdToCascade(departmentId));
 //                }
 //                userMapper.updateById(oldUser);
+                }
             }
-
         }
     }
 

+ 359 - 260
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -44,6 +44,7 @@ import java.sql.Timestamp;
 import java.text.DecimalFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
+import java.time.DayOfWeek;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
@@ -445,10 +446,12 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                         String[] split = associateDegrees.split("\\,");
                         for (int i=0;i<split.length; i++) {
                             HashMap map = new HashMap();
-                            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);
+                            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);
@@ -648,7 +651,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                                       String date,HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         try {
-            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
             User curUser = userMapper.selectById(request.getHeader("Token"));
             Integer companyId = curUser.getCompanyId();
             Integer isEngeering = companyMapper.selectById(companyId).getPackageEngineering();
@@ -656,47 +659,34 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             if (curUser.getRole() == 0) {//普通员工
                 leaderId = curUser.getId();
             }
-            //根据权限,管理员查看全部人员的,各个项目负责人只看自己负责的项目参与人员的日报
-            List<Map<String, Object>> nameList = reportMapper.getDetailByState(state, companyId, leaderId, isEngeering);
-            //按部门过滤
-            if (departmentId != null) {
-                nameList = nameList.stream().filter(map->((Long)map.get("departmentId")) == departmentId.longValue()).collect(Collectors.toList());
-            }
-            //按日期过滤
-            if (!StringUtils.isEmpty(date)) {
-                nameList = nameList.stream().filter(map->{
-                    return (sdf.format((java.sql.Date)map.get("date"))).equals(date);
-                }).collect(Collectors.toList());
+            List<Map<String, Object>> auditReportList = reportMapper.getAuditReportList(date, companyId, departmentId, projectId, leaderId, isEngeering);
+            //抽取姓名,进行分组
+            List<Map<String, Object>> nameList = new ArrayList<Map<String, Object>>();
+            Map<String, Object> lastName = null;
+            //某个用户某天下的各个项目日报列表
+            List<Map<String, Object>> userDailyReportList = null;
+            for (Map a : auditReportList) {
+                String createDate = (String)a.get("date");
+                String name = (String)a.get("name");
+
+                if (lastName == null || !(lastName.get("name").equals(name) && lastName.get("dateStr").equals(createDate))) {
+                    lastName = new HashMap<String, Object>();
+                    lastName.put("dateStr", createDate);
+                    lastName.put("name", name);
+                    nameList.add(lastName);
+                    userDailyReportList = new ArrayList<>();
+                    lastName.put("data", userDailyReportList);
+                }
+                //每组日报数据都加上去
+                userDailyReportList.add(a);
             }
-            nameList.forEach(n->{
-                n.put("dateStr",sdf.format((java.sql.Date)n.get("date")));
-            });
 
-            List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId));
             List<Profession> professions = professionMapper.selectList(new QueryWrapper<Profession>().eq("company_id", curUser.getCompanyId()));
             for (int index=0;index<nameList.size(); index++) {
                 Map<String, Object> map2 = nameList.get(index);
-                java.sql.Date createDate = (java.sql.Date)map2.get("date");
-                List<Map<String, Object>> list2 = null;
-                if (leaderId == null) {
-                    //管理员,直接获取每个人的报告
-                    list2 = reportMapper.getReportByDate(createDate.toString(), (String)map2.get("id"));
-                } else {
-                    //获取相关项目的报告
-                    List<Map<String, Object>> inchargeReportList= reportMapper.getInchargeReportByDate(createDate.toString(), leaderId, state);
-                    list2 =
-                            inchargeReportList.stream().filter(i->i.get("creatorId").equals(map2.get("id"))).collect(Collectors.toList());
-                }
-                //按项目过滤
-                if (projectId != null) {
-                    list2 = list2.stream().filter(report->(((Integer)report.get("projectId")).equals(projectId))).collect(Collectors.toList());
-                }
-                if (list2.size() == 0) {
-                    //被项目过滤掉了,没有数据。
-                    nameList.remove(index);
-                    index--;
-                } else {
-                    //项目专业进度
+                List<Map<String, Object>> list2 = (List)map2.get("data");
+                //项目专业进度
+                if (isEngeering == 1) {
                     for (Map<String, Object> map : list2) {
                         //获取当前项目的工程专业进度
                         List<ReportProfessionProgress> progressList = reportProfessionProgressService.list(new QueryWrapper<ReportProfessionProgress>().eq("report_id", (int)map.get("id")));
@@ -705,19 +695,20 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                         });
                         map.put("professionProgressList", progressList);
                     }
-                    map2.put("data", list2);
-                    double reportTime = 0;
-                    BigDecimal total = new BigDecimal(0);
-                    for (Map<String, Object> m : list2) {
-                        double t = (double) m.get("time");
-                        reportTime += t;
-                        total = total.add((BigDecimal)m.get("cost"));
-                    }
-                    DecimalFormat df = new DecimalFormat("0.00");
-                    map2.put("reportTime", df.format(reportTime));
-                    map2.put("cost", total);
-                    map2.put("state", list2.get(0).get("state"));
                 }
+
+                double reportTime = 0;
+                BigDecimal total = new BigDecimal(0);
+                //计算每日汇总的工时成本
+                for (Map<String, Object> m : list2) {
+                    double t = (double) m.get("time");
+                    reportTime += t;
+                    total = total.add((BigDecimal)m.get("cost"));
+                }
+                DecimalFormat df = new DecimalFormat("0.00");
+                map2.put("reportTime", df.format(reportTime));
+                map2.put("cost", total);
+                map2.put("state", list2.get(0).get("state"));
             }
 
             //设置照片显示
@@ -753,7 +744,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
 
     //审核通过某天某人的某报告
     @Override
-    public HttpRespMsg approveReport(String id, String reportIds, HttpServletRequest request) {
+    public HttpRespMsg approveReport(String reportIds, Integer isDepartment, HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         try {
             User user = userMapper.selectById(request.getHeader("Token"));
@@ -761,55 +752,72 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             final List<Long> ids = ListUtil.convertIdsArrayToList(reportIds);
             if (company.getPackageEngineering() == 1) {
                 //检查是否有专业进度待审核
-                List<ReportProfessionProgress> list = reportProfessionProgressService.list(new QueryWrapper<ReportProfessionProgress>().eq("report_id", ids.get(0)).eq("audit_state", 0));
-                if (list.size() > 0) {
-                    //专业待审核的状态,进行专业审核
-                    List<Report> reportList = reportMapper.selectList(new QueryWrapper<Report>().in("id", ids));
-                    List<Integer> projectIds = reportList.stream().map(Report::getProjectId).collect(Collectors.toList());
-
-                    List<ProjectProfession> myProfessionList = projectProfessionMapper.selectList(new QueryWrapper<ProjectProfession>().eq("incharger_id", user.getId()).in("project_id", projectIds));
-                    if (myProfessionList.size() == 0) {
-                        httpRespMsg.setError("只有专业负责人才能进行专业审核");
+                List<ReportProfessionProgress> list = reportProfessionProgressService.list(new QueryWrapper<ReportProfessionProgress>().in("report_id", ids).eq("audit_state", 0));
+                if (isDepartment != null) {
+                    //进行的是部门审核, 需要专业审核都通过才能进行部门审核
+                    if (list.size() > 0) {
+                        httpRespMsg.setError("只有专业审核全部通过才能进行操作");
+                        return httpRespMsg;
                     } else {
-                        List<Integer> collect = myProfessionList.stream().map(ProjectProfession::getProfessionId).collect(Collectors.toList());
-
-                        ReportProfessionProgress item = new ReportProfessionProgress();
-                        item.setAuditState(1);
-                        reportProfessionProgressService.update(item, new QueryWrapper<ReportProfessionProgress>().in("report_id", ids).in("profession_id", collect));
-
-                        //全部的专业都审核通过的情况下,更新部门待审核状态
-                        int count = reportProfessionProgressService.count(new QueryWrapper<ReportProfessionProgress>().in("report_id", ids).ne("audit_state", 1));
-                        if (count == 0) {
-                            Report report = new Report();
-                            report.setDepartmentAuditState(0);
+                        Report report = reportMapper.selectById(ids.get(0));
+                        //部门待审核,部门审核通过
+                        if (report.getDepartmentAuditState() == 0) {
+                            report = new Report();
+                            report.setDepartmentAuditState(1);
                             reportMapper.update(report, new QueryWrapper<Report>().in("id", ids));
                         }
                     }
                 } else {
-                    Report report = reportMapper.selectById(ids.get(0));
-                    //部门待审核,部门审核通过
-                    if (report.getDepartmentAuditState() == 0) {
-                        report = new Report();
-                        report.setDepartmentAuditState(1);
-                        reportMapper.update(report, new QueryWrapper<Report>().in("id", ids));
+                    //专业审核或者项目审核
+                    if (list.size() > 0) {
+                        //专业待审核的状态,进行专业审核
+                        List<Report> reportList = reportMapper.selectList(new QueryWrapper<Report>().in("id", ids));
+                        List<Integer> projectIds = reportList.stream().map(Report::getProjectId).collect(Collectors.toList());
+
+                        List<ProjectProfession> myProfessionList = projectProfessionMapper.selectList(new QueryWrapper<ProjectProfession>().eq("incharger_id", user.getId()).in("project_id", projectIds));
+                        if (myProfessionList.size() == 0) {
+                            httpRespMsg.setError("只有专业负责人才能进行专业审核");
+                        } else {
+                            List<Integer> collect = myProfessionList.stream().map(ProjectProfession::getProfessionId).collect(Collectors.toList());
+
+                            ReportProfessionProgress item = new ReportProfessionProgress();
+                            item.setAuditState(1);
+                            reportProfessionProgressService.update(item, new QueryWrapper<ReportProfessionProgress>().in("report_id", ids).in("profession_id", collect));
+
+                            //全部的专业都审核通过的情况下,更新部门待审核状态
+                            int count = reportProfessionProgressService.count(new QueryWrapper<ReportProfessionProgress>().in("report_id", ids).ne("audit_state", 1));
+                            if (count == 0) {
+                                Report report = new Report();
+                                report.setDepartmentAuditState(0);
+                                reportMapper.update(report, new QueryWrapper<Report>().in("id", ids));
+                            }
+                        }
                     } else {
-                        //最终进行项目经理审核
-                        reportMapper.update(new Report().setState(1),
-                                new QueryWrapper<Report>().in("id", ids));
-                        List<Report> finalReportList = reportMapper.selectList(new QueryWrapper<Report>().in("id", ids));
-                        List<ReportProfessionProgress> professionProgressList = reportProfessionProgressService.list(new QueryWrapper<ReportProfessionProgress>().in("report_id", ids));
-
-                        //审核通过时,才会更新到个人的专业进度上去
-                        professionProgressList.forEach(pro->{
-                            PpMembs memb = new PpMembs();
-                            memb.setProgress(pro.getProgress());
-                            Report report1 = finalReportList.stream().filter(f -> f.getId().equals(pro.getReportId())).findFirst().get();
-                            Integer projectId = report1.getProjectId();
-                            //更新个人在项目中的专业进度
-                            ppMembsMapper.update(memb, new QueryWrapper<PpMembs>().eq("project_id", projectId)
-                                    .eq("memb_id", report1.getCreatorId()).eq("profession_id", pro.getProfessionId()));
-                        });
-                        notifyLeaders(finalReportList);
+                        Report report = reportMapper.selectById(ids.get(0));
+                        //部门待审核,部门审核通过
+                        if (report.getDepartmentAuditState() == 0) {
+                            report = new Report();
+                            report.setDepartmentAuditState(1);
+                            reportMapper.update(report, new QueryWrapper<Report>().in("id", ids));
+                        } else {
+                            //最终进行项目经理审核
+                            reportMapper.update(new Report().setState(1),
+                                    new QueryWrapper<Report>().in("id", ids));
+                            List<Report> finalReportList = reportMapper.selectList(new QueryWrapper<Report>().in("id", ids));
+                            List<ReportProfessionProgress> professionProgressList = reportProfessionProgressService.list(new QueryWrapper<ReportProfessionProgress>().in("report_id", ids));
+
+                            //审核通过时,才会更新到个人的专业进度上去
+                            professionProgressList.forEach(pro->{
+                                PpMembs memb = new PpMembs();
+                                memb.setProgress(pro.getProgress());
+                                Report report1 = finalReportList.stream().filter(f -> f.getId().equals(pro.getReportId())).findFirst().get();
+                                Integer projectId = report1.getProjectId();
+                                //更新个人在项目中的专业进度
+                                ppMembsMapper.update(memb, new QueryWrapper<PpMembs>().eq("project_id", projectId)
+                                        .eq("memb_id", report1.getCreatorId()).eq("profession_id", pro.getProfessionId()));
+                            });
+                            notifyLeaders(finalReportList);
+                        }
                     }
                 }
             } else {
@@ -940,7 +948,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
 
     //审核未通过 以及 撤销审核某天某人
     @Override
-    public HttpRespMsg denyReport(String id, String date, String reportIds, String reason, HttpServletRequest request) {
+    public HttpRespMsg denyReport(String date, String reportIds, String reason, Integer isDepartment, HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         try {
             User user = userMapper.selectById(request.getHeader("Token"));
@@ -952,32 +960,47 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             Report oneReport = reportMapper.selectById(ids.get(0));
             if (company.getPackageEngineering() == 1) {
                 //检查是否有专业进度待审核
-                List<ReportProfessionProgress> list = reportProfessionProgressService.list(new QueryWrapper<ReportProfessionProgress>().eq("report_id", ids.get(0)).eq("audit_state", 0));
-
-                if (list.size() > 0) {
-                    //只能是自己负责的专业
-                    List<Report> reportList = reportMapper.selectList(new QueryWrapper<Report>().in("id", ids));
-                    List<Integer> projectIds = reportList.stream().map(Report::getProjectId).collect(Collectors.toList());
-
-                    List<ProjectProfession> myProfessionList = projectProfessionMapper.selectList(new QueryWrapper<ProjectProfession>().eq("incharger_id", user.getId()).in("project_id", projectIds));
-                    if (myProfessionList.size() == 0) {
-                        httpRespMsg.setError("只有专业负责人才能进行专业审核");
+                List<ReportProfessionProgress> list = reportProfessionProgressService.list(new QueryWrapper<ReportProfessionProgress>().in("report_id", ids).eq("audit_state", 0));
+                if (isDepartment != null) {
+                    if (list.size() > 0) {
+                        httpRespMsg.setError("只有专业审核全部通过才可操作");
+                        return httpRespMsg;
                     } else {
-                        List<Integer> collect = myProfessionList.stream().map(ProjectProfession::getProfessionId).collect(Collectors.toList());
-                        //专业待审核的状态,进行专业审核驳回
-                        ReportProfessionProgress item = new ReportProfessionProgress();
-                        item.setAuditState(2);
-                        reportProfessionProgressService.update(item, new QueryWrapper<ReportProfessionProgress>().in("report_id", ids).in("profession_id", collect));
+                        Report report = reportMapper.selectById(ids.get(0));
+                        //部门待审核,部门审核驳回
+                        if (report.getDepartmentAuditState() == 0) {
+                            report = new Report();
+                            report.setDepartmentAuditState(2);
+                            reportMapper.update(report, new QueryWrapper<Report>().in("id", ids));
+                        }
                     }
                 } else {
-                    Report report = reportMapper.selectById(ids.get(0));
-                    //部门待审核,部门审核驳回
-                    if (report.getDepartmentAuditState() == 0) {
-                        report = new Report();
-                        report.setDepartmentAuditState(2);
-                        reportMapper.update(report, new QueryWrapper<Report>().in("id", ids));
+                    if (list.size() > 0) {
+                        //只能是自己负责的专业
+                        List<Report> reportList = reportMapper.selectList(new QueryWrapper<Report>().in("id", ids));
+                        List<Integer> projectIds = reportList.stream().map(Report::getProjectId).collect(Collectors.toList());
+
+                        List<ProjectProfession> myProfessionList = projectProfessionMapper.selectList(new QueryWrapper<ProjectProfession>().eq("incharger_id", user.getId()).in("project_id", projectIds));
+                        if (myProfessionList.size() == 0) {
+                            httpRespMsg.setError("只有专业负责人才能进行专业审核");
+                        } else {
+                            List<Integer> collect = myProfessionList.stream().map(ProjectProfession::getProfessionId).collect(Collectors.toList());
+                            //专业待审核的状态,进行专业审核驳回
+                            ReportProfessionProgress item = new ReportProfessionProgress();
+                            item.setAuditState(2);
+                            reportProfessionProgressService.update(item, new QueryWrapper<ReportProfessionProgress>().in("report_id", ids).in("profession_id", collect));
+                        }
+                    } else {
+                        Report report = reportMapper.selectById(ids.get(0));
+                        //部门待审核,部门审核驳回
+                        if (report.getDepartmentAuditState() == 0) {
+                            report = new Report();
+                            report.setDepartmentAuditState(2);
+                            reportMapper.update(report, new QueryWrapper<Report>().in("id", ids));
+                        }
                     }
                 }
+
             }
             //直接进行项目经理审核驳回
             reportMapper.update(new Report().setState(2)
@@ -994,7 +1017,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 fillUserId = oneReport.getFillUserid();
             } else {
                 str = "您"+date+"填写的日报中"+pNames+"项目被领导驳回。原因:" + reason;
-                fillUserId = id;
+                fillUserId = oneReport.getCreatorId();
             }
 
             informationMapper.insert(new Information().setType(0).setContent(date).setUserId(fillUserId).setMsg(str));
@@ -1079,15 +1102,25 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
 
     @Override
     public HttpRespMsg getMembList(String date, Integer manageDeptId, HttpServletRequest request) {
-        Integer companyId = userMapper.selectById(request.getHeader("Token")).getCompanyId();
+        String token = request.getHeader("Token");
+        Integer companyId = userMapper.selectById(token).getCompanyId();
         //获取当日已填写的人员报告
         List<Map<String, Object>> reportNameByDate = reportMapper.getReportNameByDate(date, companyId, null);
 
         HttpRespMsg departmentList = departmentService.getDepartmentList(request);
         List<DepartmentVO> list = (List<DepartmentVO>) departmentList.data;
         if (manageDeptId != null && manageDeptId > 0) {
-            //指定查看某个部门下的
-            list = getSpecifiedDept(list, manageDeptId);
+            //指定查看某个部门下的,一个人可能负责多个部门
+            List<Department> allMDeptList = departmentMapper.selectList(new QueryWrapper<Department>().eq("manager_id", token));
+            if (allMDeptList.size() == 1) {
+                list = getSpecifiedDept(list, manageDeptId);
+            } else {
+                ArrayList realMDeptList = new ArrayList<>();
+                for (Department d : allMDeptList) {
+                    realMDeptList.addAll(getSpecifiedDept(list, d.getDepartmentId()));
+                }
+                list = realMDeptList;
+            }
         } else {
             //加上未分配的部门
             DepartmentVO unAssignedDept = new DepartmentVO();
@@ -1120,52 +1153,68 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     }
 
     @Override
-    public HttpRespMsg batchApproveReport(String reportIds, HttpServletRequest request) {
+    public HttpRespMsg batchApproveReport(String reportIds, Integer isDepartment, HttpServletRequest request) {
         User user = userMapper.selectById(request.getHeader("Token"));
         Company company = companyMapper.selectById(user.getCompanyId());
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         final List<Long> ids = ListUtil.convertIdsArrayToList(reportIds);
         if (company.getPackageEngineering() == 1) {
             //检查是否有专业进度待审核
-            List<ReportProfessionProgress> list = reportProfessionProgressService.list(new QueryWrapper<ReportProfessionProgress>().eq("report_id", ids.get(0)).eq("audit_state", 0));
-            if (list.size() > 0) {
-                //专业待审核的状态,进行专业审核
-                List<Report> reportList = reportMapper.selectList(new QueryWrapper<Report>().in("id", ids));
-                List<Integer> projectIds = reportList.stream().map(Report::getProjectId).collect(Collectors.toList());
-
-                List<ProjectProfession> myProfessionList = projectProfessionMapper.selectList(new QueryWrapper<ProjectProfession>().eq("incharger_id", user.getId()).in("project_id", projectIds));
-                if (myProfessionList.size() == 0) {
-                    httpRespMsg.setError("只能专业负责人才能进行专业审核");
+            List<ReportProfessionProgress> list = reportProfessionProgressService.list(new QueryWrapper<ReportProfessionProgress>().in("report_id", ids).eq("audit_state", 0));
+            if (isDepartment != null) {
+                if (list.size() > 0) {
+                    httpRespMsg.setError("只有专业审核全部通过才能操作");
+                    return httpRespMsg;
                 } else {
-                    List<Integer> collect = myProfessionList.stream().map(ProjectProfession::getProfessionId).collect(Collectors.toList());
-
-                    ReportProfessionProgress item = new ReportProfessionProgress();
-                    item.setAuditState(1);
-                    reportProfessionProgressService.update(item, new QueryWrapper<ReportProfessionProgress>().in("report_id", ids).in("profession_id", collect));
-
-                    //全部的专业都审核通过的情况下,更新部门待审核状态
-                    int count = reportProfessionProgressService.count(new QueryWrapper<ReportProfessionProgress>().in("report_id", ids).ne("audit_state", 1));
-                    if (count == 0) {
-                        Report report = new Report();
-                        report.setDepartmentAuditState(0);
+                    Report report = reportMapper.selectById(ids.get(0));
+                    //部门待审核,部门审核通过
+                    if (report.getDepartmentAuditState() == 0) {
+                        report = new Report();
+                        report.setDepartmentAuditState(1);
                         reportMapper.update(report, new QueryWrapper<Report>().in("id", ids));
                     }
                 }
             } else {
-                Report report = reportMapper.selectById(ids.get(0));
-                //部门待审核,部门审核通过
-                if (report.getDepartmentAuditState() == 0) {
-                    report = new Report();
-                    report.setDepartmentAuditState(1);
-                    reportMapper.update(report, new QueryWrapper<Report>().in("id", ids));
+                if (list.size() > 0) {
+                    //专业待审核的状态,进行专业审核
+                    List<Report> reportList = reportMapper.selectList(new QueryWrapper<Report>().in("id", ids));
+                    List<Integer> projectIds = reportList.stream().map(Report::getProjectId).collect(Collectors.toList());
+
+                    List<ProjectProfession> myProfessionList = projectProfessionMapper.selectList(new QueryWrapper<ProjectProfession>().eq("incharger_id", user.getId()).in("project_id", projectIds));
+                    if (myProfessionList.size() == 0) {
+                        httpRespMsg.setError("只能专业负责人才能进行专业审核");
+                    } else {
+                        List<Integer> collect = myProfessionList.stream().map(ProjectProfession::getProfessionId).collect(Collectors.toList());
+
+                        ReportProfessionProgress item = new ReportProfessionProgress();
+                        item.setAuditState(1);
+                        reportProfessionProgressService.update(item, new QueryWrapper<ReportProfessionProgress>().in("report_id", ids).in("profession_id", collect));
+
+                        //全部的专业都审核通过的情况下,更新部门待审核状态
+                        int count = reportProfessionProgressService.count(new QueryWrapper<ReportProfessionProgress>().in("report_id", ids).ne("audit_state", 1));
+                        if (count == 0) {
+                            Report report = new Report();
+                            report.setDepartmentAuditState(0);
+                            reportMapper.update(report, new QueryWrapper<Report>().in("id", ids));
+                        }
+                    }
                 } else {
-                    //直接进行项目经理审核
-                    reportMapper.update(new Report().setState(1),
-                            new QueryWrapper<Report>().in("id", ids));
-                    List<Report> finalReportList = reportMapper.selectList(new QueryWrapper<Report>().in("id", ids));
-                    notifyLeaders(finalReportList);
+                    Report report = reportMapper.selectById(ids.get(0));
+                    //部门待审核,部门审核通过
+                    if (report.getDepartmentAuditState() == 0) {
+                        report = new Report();
+                        report.setDepartmentAuditState(1);
+                        reportMapper.update(report, new QueryWrapper<Report>().in("id", ids));
+                    } else {
+                        //直接进行项目经理审核
+                        reportMapper.update(new Report().setState(1),
+                                new QueryWrapper<Report>().in("id", ids));
+                        List<Report> finalReportList = reportMapper.selectList(new QueryWrapper<Report>().in("id", ids));
+                        notifyLeaders(finalReportList);
+                    }
                 }
             }
+
         } else {
             //直接进行项目经理审核
             reportMapper.update(new Report().setState(1),
@@ -1176,38 +1225,52 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
 
 
     @Override
-    public HttpRespMsg batchDenyReport(String reportIds, HttpServletRequest request) {
+    public HttpRespMsg batchDenyReport(String reportIds, Integer isDepartment, HttpServletRequest request) {
         User user = userMapper.selectById(request.getHeader("Token"));
         Company company = companyMapper.selectById(user.getCompanyId());
         final List<Long> ids = ListUtil.convertIdsArrayToList(reportIds);
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         if (company.getPackageEngineering() == 1) {
             //检查是否有专业进度待审核
-            List<ReportProfessionProgress> list = reportProfessionProgressService.list(new QueryWrapper<ReportProfessionProgress>().eq("report_id", ids.get(0)).eq("audit_state", 0));
-
-            if (list.size() > 0) {
-                //只能是自己负责的专业
-                List<Report> reportList = reportMapper.selectList(new QueryWrapper<Report>().in("id", ids));
-                List<Integer> projectIds = reportList.stream().map(Report::getProjectId).collect(Collectors.toList());
-
-                List<ProjectProfession> myProfessionList = projectProfessionMapper.selectList(new QueryWrapper<ProjectProfession>().eq("incharger_id", user.getId()).in("project_id", projectIds));
-                if (myProfessionList.size() == 0) {
-                    httpRespMsg.setError("只能专业负责人才能进行专业审核");
+            List<ReportProfessionProgress> list = reportProfessionProgressService.list(new QueryWrapper<ReportProfessionProgress>().in("report_id", ids).eq("audit_state", 0));
+            if (isDepartment != null) {
+                if (list.size() > 0) {
+                    httpRespMsg.setError("只有专业审核全部通过才能操作");
+                    return httpRespMsg;
                 } else {
-                    List<Integer> collect = myProfessionList.stream().map(ProjectProfession::getProfessionId).collect(Collectors.toList());
-                    //专业待审核的状态,进行专业审核驳回
-                    ReportProfessionProgress item = new ReportProfessionProgress();
-                    item.setAuditState(2);
-                    reportProfessionProgressService.update(item, new QueryWrapper<ReportProfessionProgress>().in("report_id", ids).in("profession_id", collect));
+                    Report report = reportMapper.selectById(ids.get(0));
+                    //部门待审核,部门审核通过
+                    if (report.getDepartmentAuditState() == 0) {
+                        report = new Report();
+                        report.setDepartmentAuditState(1);
+                        reportMapper.update(report, new QueryWrapper<Report>().in("id", ids));
+                    }
                 }
-
             } else {
-                Report report = reportMapper.selectById(ids.get(0));
-                //部门待审核,部门审核驳回
-                if (report.getDepartmentAuditState() == 0) {
-                    report = new Report();
-                    report.setDepartmentAuditState(2);
-                    reportMapper.update(report, new QueryWrapper<Report>().in("id", ids));
+                if (list.size() > 0) {
+                    //只能是自己负责的专业
+                    List<Report> reportList = reportMapper.selectList(new QueryWrapper<Report>().in("id", ids));
+                    List<Integer> projectIds = reportList.stream().map(Report::getProjectId).collect(Collectors.toList());
+
+                    List<ProjectProfession> myProfessionList = projectProfessionMapper.selectList(new QueryWrapper<ProjectProfession>().eq("incharger_id", user.getId()).in("project_id", projectIds));
+                    if (myProfessionList.size() == 0) {
+                        httpRespMsg.setError("只能专业负责人才能进行专业审核");
+                    } else {
+                        List<Integer> collect = myProfessionList.stream().map(ProjectProfession::getProfessionId).collect(Collectors.toList());
+                        //专业待审核的状态,进行专业审核驳回
+                        ReportProfessionProgress item = new ReportProfessionProgress();
+                        item.setAuditState(2);
+                        reportProfessionProgressService.update(item, new QueryWrapper<ReportProfessionProgress>().in("report_id", ids).in("profession_id", collect));
+                    }
+
+                } else {
+                    Report report = reportMapper.selectById(ids.get(0));
+                    //部门待审核,部门审核驳回
+                    if (report.getDepartmentAuditState() == 0) {
+                        report = new Report();
+                        report.setDepartmentAuditState(2);
+                        reportMapper.update(report, new QueryWrapper<Report>().in("id", ids));
+                    }
                 }
             }
         }
@@ -1615,7 +1678,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             List<String> projectList = new ArrayList<>();
             List<Project> allProjectList = projectMapper.selectList(new QueryWrapper<Project>().eq("company_id", companyId));
             List<Report> reportList = new ArrayList<>();
-            int projectNameStartIndex = (withCheckIn==null?2:9);
+            int projectNameStartIndex = (withCheckIn==null?2:6);
 
             for (int rowIndex = 0; rowIndex <= rowNum; rowIndex++) {
                 Row row = sheet.getRow(rowIndex);
@@ -2021,97 +2084,108 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     }
 
     @Override
-    public HttpRespMsg listDeptImportByState(Integer state, String leaderId, Integer projectId, String date, HttpServletRequest request) {
+    public HttpRespMsg listDeptImportByState(String leaderId, Integer projectId, String startDate, String endDate, Integer departmentId, HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         try {
-            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
             User curUser = userMapper.selectById(request.getHeader("Token"));
             Integer companyId = curUser.getCompanyId();
-
+            Integer isEngeering = companyMapper.selectById(companyId).getPackageEngineering();
             //根据权限,日报审核员只看自己负责的人员的日报
-            List<Map<String, Object>> nameList = reportMapper.getDetailImportByState(state, companyId, leaderId);
-            System.out.println("数据size=="+nameList.size());
-            //按日期过滤
-            if (!StringUtils.isEmpty(date)) {
-                nameList = nameList.stream().filter(map->{
-                    return (sdf.format((java.sql.Date)map.get("date"))).equals(date);
-                }).collect(Collectors.toList());
+            List<Integer> filterDeptIds = null;
+            if (departmentId != null) {
+                filterDeptIds = new ArrayList<>();
+                Department dept = departmentMapper.selectById(departmentId);
+                List<Department> allDepts = departmentMapper.selectList(new QueryWrapper<Department>().eq("company_id", companyId));
+                List<Department> subDepts = getSubDepts(dept, allDepts);
+                filterDeptIds.add(departmentId);
+                filterDeptIds.addAll(subDepts.stream().map(Department::getDepartmentId).collect(Collectors.toList()));
             }
-            nameList.forEach(n->{
-                n.put("dateStr",sdf.format((java.sql.Date)n.get("date")));
-            });
+            List<Map<String, Object>> auditReportList = reportMapper.getDeptImportAuditList(companyId, leaderId, startDate, endDate, filterDeptIds, projectId);
+//            //抽取姓名,进行分组
+//            List<Map<String, Object>> nameList = new ArrayList<Map<String, Object>>();
+//            Map<String, Object> lastName = null;
+//            //某个用户某天下的各个项目日报列表
+//            List<Map<String, Object>> userDailyReportList = null;
+//            for (Map a : auditReportList) {
+//                String createDate = (String)a.get("date");
+//                String name = (String)a.get("name");
+//
+//                if (lastName == null || !(lastName.get("name").equals(name) && lastName.get("dateStr").equals(createDate))) {
+//                    lastName = new HashMap<String, Object>();
+//                    lastName.put("dateStr", createDate);
+//                    lastName.put("name", name);
+//                    nameList.add(lastName);
+//                    userDailyReportList = new ArrayList<>();
+//                    lastName.put("data", userDailyReportList);
+//                }
+//                //每组日报数据都加上去
+//                userDailyReportList.add(a);
+//            }
 
-            List<Profession> professions = professionMapper.selectList(new QueryWrapper<Profession>().eq("company_id", curUser.getCompanyId()));
-            for (int index=0;index<nameList.size(); index++) {
-                Map<String, Object> map2 = nameList.get(index);
-                java.sql.Date createDate = (java.sql.Date)map2.get("date");
-                List<Map<String, Object>> list2 = null;
-//                if (leaderId == null) {
-//                    //按部门导入的,直接获取每个人的报告
-                    list2 = reportMapper.getReportByDate(createDate.toString(), (String)map2.get("id"));
-//                } else {
-                    //获取相关项目的报告
-//                    List<Map<String, Object>> inchargeReportList= reportMapper.getInchargeReportByDate(createDate.toString(), leaderId, state);
-//                    list2 =
-//                            inchargeReportList.stream().filter(i->i.get("creatorId").equals(map2.get("id"))).collect(Collectors.toList());
+
+//            List<Profession> professions = professionMapper.selectList(new QueryWrapper<Profession>().eq("company_id", curUser.getCompanyId()));
+//            for (int index=0;index<nameList.size(); index++) {
+//                Map<String, Object> map2 = nameList.get(index);
+//                List<Map<String, Object>> list2 = (List)map2.get("data");
+//                //项目专业进度
+//                if (isEngeering == 1) {
+//                    for (Map<String, Object> map : list2) {
+//                        //获取当前项目的工程专业进度
+//                        List<ReportProfessionProgress> progressList = reportProfessionProgressService.list(new QueryWrapper<ReportProfessionProgress>().eq("report_id", (int)map.get("id")));
+//                        progressList.stream().forEach(p->{
+//                            p.setProfessionName(professions.stream().filter(m->m.getId().equals(p.getProfessionId())).findFirst().get().getName());
+//                        });
+//                        map.put("professionProgressList", progressList);
+//                    }
 //                }
-                //按项目过滤
-                if (projectId != null) {
-                    list2 = list2.stream().filter(report->(((Integer)report.get("projectId")).equals(projectId))).collect(Collectors.toList());
-                }
-                if (list2.size() == 0) {
-                    //被项目过滤掉了,没有数据。
-                    nameList.remove(index);
-                    index--;
-                } else {
-                    //项目专业进度
-                    for (Map<String, Object> map : list2) {
-                        //获取当前项目的工程专业进度
-                        List<ReportProfessionProgress> progressList = reportProfessionProgressService.list(new QueryWrapper<ReportProfessionProgress>().eq("report_id", (int)map.get("id")));
-                        progressList.stream().forEach(p->{
-                            p.setProfessionName(professions.stream().filter(m->m.getId().equals(p.getProfessionId())).findFirst().get().getName());
-                        });
-                        map.put("professionProgressList", progressList);
-                    }
-                    map2.put("data", list2);
-                    double reportTime = 0;
-                    BigDecimal total = new BigDecimal(0);
-                    for (Map<String, Object> m : list2) {
-                        double t = (double) m.get("time");
-                        reportTime += t;
-                        total = total.add((BigDecimal)m.get("cost"));
-                    }
-                    DecimalFormat df = new DecimalFormat("0.00");
-                    map2.put("reportTime", df.format(reportTime));
-                    map2.put("cost", total);
-                    map2.put("state", list2.get(0).get("state"));
-                }
-            }
+//
+//                double reportTime = 0;
+//                BigDecimal total = new BigDecimal(0);
+//                //计算每日汇总的工时成本
+//                for (Map<String, Object> m : list2) {
+//                    double t = (double) m.get("time");
+//                    reportTime += t;
+//                    total = total.add((BigDecimal)m.get("cost"));
+//                }
+//                DecimalFormat df = new DecimalFormat("0.00");
+//                map2.put("reportTime", df.format(reportTime));
+//                map2.put("cost", total);
+//                map2.put("state", list2.get(0).get("state"));
+//            }
 
-            //设置照片显示
-            for (Map map : nameList) {
-                List<Map<String, Object>> reportList = (List<Map<String, Object>>)map.get("data");
-                for (Map<String, Object> report : reportList) {
-                    String picStr = (String)report.get("picStr");
-                    if (picStr != null) {
-                        JSONArray array = JSONArray.parseArray(picStr.replaceAll("@", ","));
-                        List<String> picList = new ArrayList<>();
-                        for (int i=0;i<array.size(); i++) {
-                            String string = array.getString(i);
-                            string = "/upload/" + string + ".jpg";
-                            picList.add(string);
-                        }
-                        report.put("pics", picList);
-                    }
-                    if (((Integer)report.get("multiWorktime")) == 1) {
-                        //设置多个工时情况下的报告列表
-                        String timeStr = (String)report.get("content");
-                        report.put("worktimeList", JSONArray.parse(timeStr));
-                    }
-                }
+            //设置照片和项目工时成本显示
+//            for (Map map : nameList) {
+//                List<Map<String, Object>> reportList = (List<Map<String, Object>>)map.get("data");
+//                StringBuilder sb = new StringBuilder();
+//                for (int t=0;t<reportList.size(); t++) {
+//                    Map<String, Object> report = reportList.get(t);
+//                    String picStr = (String)report.get("picStr");
+//                    if (picStr != null) {
+//                        JSONArray array = JSONArray.parseArray(picStr.replaceAll("@", ","));
+//                        List<String> picList = new ArrayList<>();
+//                        for (int i=0;i<array.size(); i++) {
+//                            String string = array.getString(i);
+//                            string = "/upload/" + string + ".jpg";
+//                            picList.add(string);
+//                        }
+//                        report.put("pics", picList);
+//                    }
+//                    if (((Integer)report.get("multiWorktime")) == 1) {
+//                        //设置多个工时情况下的报告列表
+//                        String timeStr = (String)report.get("content");
+//                        report.put("worktimeList", JSONArray.parse(timeStr));
+//                    }
+//                    //抽取项目,工时和成本
+//                    sb.append(report.get("project")+"("+report.get("time")+"h/"+report.get("cost")+"元)");
+//                    if (t < reportList.size() -1) {
+//                        sb.append(" | ");
+//                    }
+//                }
+//                map.put("allProjectTime", sb.toString());
+//            }
 
-            }
-            httpRespMsg.data = nameList;
+            httpRespMsg.data = auditReportList;
         } catch (NullPointerException e) {
             httpRespMsg.setError("验证失败");
             return httpRespMsg;
@@ -2119,4 +2193,29 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         return httpRespMsg;
     }
 
+    @Override
+    public HttpRespMsg getlastWeekFillTime(String userId) {
+        HttpRespMsg msg = new HttpRespMsg();
+        LocalDate now = LocalDate.now();
+        //取上周
+        LocalDate lastWeek = now.minusWeeks(1);
+
+        int weekDay = lastWeek.getDayOfWeek().getValue();
+        LocalDate monday = lastWeek.minusDays(weekDay-1);
+        LocalDate sunday = monday.plusDays(6);
+        List<Report> reportList = reportMapper.selectList(new QueryWrapper<Report>().eq("creator_id", userId).between("create_date", monday, sunday));
+        List<Integer> pids = reportList.stream().map(Report::getProjectId).distinct().collect(Collectors.toList());
+        List<Project> projectList = projectMapper.selectList(new QueryWrapper<Project>().in("id", pids));
+        String collect = projectList.stream().map(Project::getProjectName).collect(Collectors.joining(","));
+        //计算总工时
+        double sum = reportList.stream().mapToDouble(Report::getWorkingTime).sum();
+        double waiting = reportList.stream().filter(r -> r.getState() == 0).mapToDouble(Report::getWorkingTime).sum();
+        double reject = reportList.stream().filter(r -> r.getState() == 2).mapToDouble(Report::getWorkingTime).sum();
+        double pass = reportList.stream().filter(r -> r.getState() == 1).mapToDouble(Report::getWorkingTime).sum();
+        String str = "您上周共参与了" + projectList.size()+"个项目,总工时为" + sum+"小时。其中审核通过"+pass
+                    +"小时, 待审核"+waiting+"小时,驳回"+reject+"小时。";
+        msg.data = str;
+        return msg;
+    }
+
 }

+ 5 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/UserServiceImpl.java

@@ -334,6 +334,11 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
         if (userMapper.selectList(new QueryWrapper<User>().eq("phone", phone)).size() > 0) {
             httpRespMsg.setError("该电话号码已注册");
         } else {
+            //检查公司名称是否已经存在
+            if (companyMapper.selectCount(new QueryWrapper<Company>().eq("company_name", companyName)) > 0) {
+                httpRespMsg.setError("该公司已注册,请联系管理员为您添加账号");
+                return httpRespMsg;
+            }
             //首先生成一个新公司,增加会员的试用一个月
             Company company = new Company().setCompanyName(companyName)
                     .setExpirationDate(LocalDateTime.now().plusMonths(1));

+ 140 - 45
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/WxCorpInfoServiceImpl.java

@@ -27,6 +27,7 @@ import javax.annotation.Resource;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.time.*;
+import java.time.format.DateTimeFormatter;
 import java.util.List;
 
 import static org.mockito.ArgumentMatchers.startsWith;
@@ -240,6 +241,7 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
             HttpHeaders headers = new HttpHeaders();
             headers.setContentType(MediaType.APPLICATION_JSON);
             JSONObject reqParam = new JSONObject();
+
             startDateTime = startDateTime.withHour(0).withMinute(0).withSecond(0).withNano(0);
             System.out.println(startDateTime.toString());
             long startTime = startDateTime.toEpochSecond(ZoneOffset.of("+8"));
@@ -250,13 +252,15 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
             reqParam.put("starttime", startTime);
             reqParam.put("endtime",  endTime);
 
-
+            DateTimeFormatter mdFormat = DateTimeFormatter.ofPattern("yyyy/M/d");
             if (userId == null) {
                 //获取企业下的全部员工
                 List<User> users = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId).isNotNull("corpwx_userid").eq("is_active", 1));
                 System.out.println("获取考勤记录users size=="+users.size());
                 Object[] objects = users.stream().map(User::getCorpwxUserid).toArray();
-                System.out.println(objects);
+                for (Object obj : objects) {
+                    System.out.println((String)obj);
+                }
                 reqParam.put("useridlist",  objects);
             } else {
                 //指定获取员工
@@ -300,49 +304,122 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
 
                         ct.setStartTime(DateTimeUtil.getTimeFromSeconds(sTime));
                         ct.setEndTime(DateTimeUtil.getTimeFromSeconds(eTime));
+                        //直接设置打卡时长,以企业微信的为准,不考虑漏打卡的情况
+                        ct.setCardTime(DateTimeUtil.getHoursFromSeconds(regular_work_sec));
 
                         JSONArray holidayItems = jsonObject.getJSONArray("holiday_infos");
-                        if (eTime == sTime) {
-                            //开始时间和结束时间一样,说明下班没有打卡,需要提取请假的最晚时间作为下班打卡时间
-                            String lastestOffworkTime = null;
-                            for (int t=0;t<holidayItems.size(); t++) {
-                                JSONObject holiday = holidayItems.getJSONObject(t);
-                                JSONObject spTitle = holiday.getJSONObject("sp_title");
-                                JSONArray data = spTitle.getJSONArray("data");
-                                for (int m=0;m<data.size(); m++) {
-                                    String leaveText = data.getJSONObject(m).getString("text");
-                                    if (leaveText.startsWith("请假")) {
-                                        //获取对应位置的请假时间段
-                                        String string = holiday.getJSONObject("sp_description").getJSONArray("data").getJSONObject(m).getString("text");
-                                        String[] s = string.split(" ");
-                                        //获取到请假的开始时间和结束时间
-                                        String leaveEnd = s[4];
+//                        if (eTime == sTime) {
+                        //开始时间和结束时间一样,说明下班没有打卡,需要提取请假的最晚时间作为下班打卡时间
+                        String lastestOffworkTime = null;
+                        boolean needRecaculate = false;
+                        for (int t=0;t<holidayItems.size(); t++) {
+                            JSONObject holiday = holidayItems.getJSONObject(t);
+                            JSONObject spTitle = holiday.getJSONObject("sp_title");
+                            JSONArray data = spTitle.getJSONArray("data");
+                            for (int m=0;m<data.size(); m++) {
+                                String leaveText = data.getJSONObject(m).getString("text");
+                                if (leaveText.startsWith("请假")) {
+                                    //获取对应位置的请假时间段
+                                    String string = holiday.getJSONObject("sp_description").getJSONArray("data").getJSONObject(m).getString("text");
+                                    String[] s = string.split(" ");
+                                    //获取到请假的开始时间和结束时间
+                                    String leaveEnd = s[4];
+                                    String leaveStart = s[1];
+                                    //请假开始的日期和结束的日期
+                                    String dateStart = localDate.getYear() + "/" + s[0];
+                                    String dateEnd =  localDate.getYear() + "/" +s[3];
+                                    LocalDate sDate = LocalDate.parse(dateStart, mdFormat);
+                                    LocalDate eDate = LocalDate.parse(dateEnd, mdFormat);
+                                    if (sDate.isEqual(eDate)) {
+                                        //请假在一天内
                                         if (leaveEnd.equals("下午")) {
-                                            leaveEnd = "13:00";//请假的下班打卡时间,算上午结束的时间
+                                            if (leaveStart.equals("上午")) {
+                                                leaveEnd = "18:00";//上午和下午都请假,算全天
+                                                leaveStart = "09:00";
+                                            } else {
+                                                leaveStart = "14:00";
+                                                leaveEnd = "18:00";//请假的下班打卡时间,算上午结束的时间
+                                            }
+                                        } else if (leaveEnd.equals("上午")){
+                                            //上午请假
+                                            leaveEnd = "14:00";
+                                            leaveStart = "09:00";
                                         }
-                                        if (lastestOffworkTime == null || leaveEnd.compareTo(lastestOffworkTime) > 0) {
-                                            lastestOffworkTime = leaveEnd;
+                                    } else {
+                                        System.out.println("跨天请假@@@@");
+                                        System.out.println("当天=="+localDate+", sDate=" + sDate+", 比较="+(localDate.isEqual(sDate)));
+                                        //跨天请假
+                                        if (localDate.isEqual(sDate)) {
+                                            //当前日期就是最后一天,需判断上下午半天请假的情况
+                                            if (leaveStart.equals("上午")) {
+                                                leaveEnd = "18:00";//上午开始请假的算全天
+                                                leaveStart = "09:00";
+                                            } else {
+                                                leaveStart = "14:00";
+                                                leaveEnd = "18:00";//下午开始请假的,算半天
+                                            }
+                                        } else if (localDate.isEqual(eDate)) {
+                                            //当前日期就是最后一天,需判断上下午半天请假的情况
+                                            if (leaveEnd.equals("下午")) {
+                                                leaveEnd = "18:00";//请假到最后一天的下午,就算是全天
+                                                leaveStart = "09:00";
+                                            } else if (leaveEnd.equals("上午")){
+                                                //上午请假
+                                                leaveEnd = "14:00";
+                                                leaveStart = "09:00";
+                                            }
+                                        } else {
+                                            //中间日期就是全天
+                                            leaveEnd = "00:00";
+                                            leaveStart = "00:00";
+                                            System.out.println("===中间天请假===");
                                         }
                                     }
+
+                                    //获取外出的最早的开始时间和最晚的结束时间最为当天考勤的最早和最晚时间
+                                    if (ct.getStartTime().equals("00:00") || ct.getStartTime().compareTo(leaveStart) > 0) {
+                                        ct.setStartTime(leaveStart);
+                                        needRecaculate = true;
+                                    }
+                                    if (ct.getEndTime().compareTo(leaveEnd) < 0) {
+                                        ct.setEndTime(leaveEnd);
+                                        needRecaculate = true;
+                                    }
+                                } else if (leaveText.startsWith("外出")) {
+                                    String string = holiday.getJSONObject("sp_description").getJSONArray("data").getJSONObject(m).getString("text");
+                                    String[] s = string.split(" ");
+                                    //获取到外出的开始时间和结束时间
+                                    String outEnd = s[4];
+                                    String outStart = s[1];
+
+                                    //获取外出的最早的开始时间和最晚的结束时间最为当天考勤的最早和最晚时间
+                                    if (ct.getStartTime().equals("00:00") || ct.getStartTime().compareTo(outStart) > 0) {
+                                        ct.setStartTime(outStart);
+                                        needRecaculate = true;
+                                    }
+                                    if (ct.getEndTime().compareTo(outEnd) < 0) {
+                                        ct.setEndTime(outEnd);
+                                        needRecaculate = true;
+                                    }
                                 }
                             }
-                            if (lastestOffworkTime != null) {
-                                ct.setEndTime(lastestOffworkTime);
-                                //重新计算打卡时长
-
-                                regular_work_sec = DateTimeUtil.getSecondsFromTime(lastestOffworkTime) - sTime;
-                                if (lastestOffworkTime.compareTo("13:00") > 0) {
-                                    //下午请假的,减掉午休的一小时
-                                    regular_work_sec -= 3600;
-                                }
+                        }
+                        double timeDelta = 0;
+                        //时间有变化,需要重新计算
+                        if (needRecaculate) {
+                            timeDelta = DateTimeUtil.getHoursFromSeconds(DateTimeUtil.getSecondsFromTime(ct.getEndTime()) - DateTimeUtil.getSecondsFromTime(ct.getStartTime()));
+                            if (ct.getEndTime().compareTo("13:30") >= 0) {
+                                //重新计算打卡工时时,需要减去中间午休时间
+                                timeDelta -= 1.0;
                             }
+                        } else {
+                            timeDelta = ct.getCardTime();
                         }
-                        //打卡时间先要四舍五入
-                        double hoursFromSeconds = DateTimeUtil.getHoursFromSeconds(regular_work_sec);
-                        System.out.println("打卡间隔时长为=="+hoursFromSeconds);
-                        double hoursFromDouble = DateTimeUtil.getHoursFromDouble(hoursFromSeconds);
-                        System.out.println("四舍五入后cardTime时间=="+hoursFromDouble);
-                        ct.setCardTime(hoursFromDouble);
+
+                        System.out.println("上下班间隔时长为=="+timeDelta);
+//                        double hoursFromDouble = DateTimeUtil.getHoursFromDouble(hoursFromSeconds);
+//                        System.out.println("四舍五入后cardTime时间=="+hoursFromDouble);
+//                        ct.setCardTime(hoursFromSeconds);
 
                         ct.setName(name);
                         //解析请假和外出的情况
@@ -365,11 +442,15 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                                     if (outdoorTime == null) {
                                         outdoorTime = 0.0;
                                     }
-                                    ct.setOutdoorTime(outdoorTime + DateTimeUtil.getHoursFromSeconds(spItem.getInteger("duration")));
+                                    double otTime = DateTimeUtil.getHoursFromSeconds(spItem.getInteger("duration"));
+                                    if (otTime > 8.0) {
+                                        otTime = 8.0;
+                                    }
+                                    ct.setOutdoorTime(outdoorTime + otTime);
                                     break;
                             }
                         }
-                        //获取假期详情
+
                         //获取请假的最早和最晚时间
                         for (int t=0;t<holidayItems.size(); t++) {
                             JSONObject holiday = holidayItems.getJSONObject(t);
@@ -387,22 +468,36 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
 
                                     //检查请假时间段是否在打卡的时间范围内
                                     if ("上午".equals(leaveEnd) || "下午".equals(leaveEnd)) {
-                                        //上下午请假, 上面已经处理过结束时间为请假之前的时间了,此处不需要再处理了
-                                        System.out.println("====请假 = " + leaveEnd);
+                                        //半天或者全天请假, 上面已经处理过结束时间为请假之前的时间了,此处不需要再处理了
+                                        System.out.println("====半天或者全天请假 =转化为8小时制下的时间="+(ct.getAskLeaveTime()/24*8.0));
+                                        ct.setAskLeaveTime(ct.getAskLeaveTime()/24*8.0);//转换成一天8小时工作制
                                     } else if (ct.getStartTime().compareTo(leaveStart) <= 0 && ct.getEndTime().compareTo(leaveEnd) >= 0) {
                                         String hourLeaveTime = leaveText.replaceAll("请假", "").replaceAll("小时", "");
                                         System.out.println("请假时长=" + hourLeaveTime);
-                                        ct.setCardTime(ct.getCardTime() - Double.parseDouble(hourLeaveTime));
+//                                        ct.setCardTime(ct.getCardTime() - Double.parseDouble(hourLeaveTime));
                                     }
                                 }
                             }
-
                         }
-                        if (regular_work_sec < standard_work_sec) {
-                            ct.setWorkHours(ct.getCardTime() + ct.getOutdoorTime());
-                        } else {
-                            ct.setWorkHours(ct.getCardTime());
+                        //校正请假时长
+                        if (ct.getAskLeaveTime() != null && ct.getAskLeaveTime() == 24.0) {
+                            ct.setAskLeaveTime(8.0);//24小时为一天,修正为8小时
+                        }
+                        //如果有出差的,但是没有打卡,则用出差的时间作为timeDelta
+                        if (timeDelta < 8.0 && ct.getOutdoorTime() > 0) {
+                            timeDelta += ct.getOutdoorTime();
+                        }
+                        double workHours = timeDelta - ct.getAskLeaveTime();
+                        if (workHours < 0) {
+                            workHours = 0;
                         }
+                        System.out.println("工作时长=="+workHours);
+                        ct.setWorkHours(DateTimeUtil.getHoursFromDouble(workHours));
+//                        if (regular_work_sec < standard_work_sec) {
+//                            ct.setWorkHours(DateTimeUtil.getHoursFromDouble(ct.getCardTime() + ct.getOutdoorTime()));
+//                        } else {
+//                            ct.setWorkHours(DateTimeUtil.getHoursFromDouble(ct.getCardTime()));
+//                        }
 
                         UserCorpwxTime item = userCorpwxTimeMapper.selectOne(new QueryWrapper<UserCorpwxTime>().eq("corpwx_userid", curUserid)
                                             .eq("create_date", localDate));

+ 74 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java

@@ -28,6 +28,7 @@ import org.springframework.stereotype.Component;
 import javax.annotation.Resource;
 import java.time.LocalDateTime;
 import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * Author: 吴涛涛
@@ -94,7 +95,49 @@ public class TimingTask {
                     pushProjectNotify((String)u.get("wxOpenid"), p.getProjectName(), days, p.getPlanEndDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
                 }
             });
+        }
+    }
+
+    //每天7点同步昨天的企业微信考勤考勤打卡记录
+    @Scheduled(cron = "0 0 7 ? * *")
+    private void synCorpWXCardTime() {
+        LocalDateTime yestoday = LocalDateTime.now().minusDays(1);
+        yestoday = yestoday.withHour(0).withMinute(0).withSecond(0).withNano(0);
+
+        List<TimeType> typeList = timeTypeMapper.selectList(new QueryWrapper<TimeType>().eq("sync_corpwx_time", 1));
+        for (TimeType type : typeList) {
+            Integer companyId = type.getCompanyId();
+            wxCorpInfoService.getUserCheckInDayData(companyId, null, yestoday, yestoday);
+        }
+    }
 
+    //发送上周填写的工时统计
+    @Scheduled(cron = "0 0 8 ? * *")
+    private void lastWeekFillTimeAlert() {
+        //每日检查是否是周一,提醒上周工时汇总
+        LocalDate curDay = LocalDate.now();
+        if (curDay.getDayOfWeek().getValue() == 1) {
+            List<User> allUser = userMapper.selectList(new QueryWrapper<User>().isNotNull("wx_openid"));
+            for (User u : allUser) {
+                //取上周
+                LocalDate lastWeek = curDay.minusWeeks(1);
+
+                int weekDay = lastWeek.getDayOfWeek().getValue();
+                LocalDate monday = lastWeek.minusDays(weekDay-1);
+                LocalDate sunday = monday.plusDays(6);
+                List<Report> reportList = reportMapper.selectList(new QueryWrapper<Report>().eq("creator_id", u.getId()).between("create_date", monday, sunday));
+                List<Integer> pids = reportList.stream().map(Report::getProjectId).distinct().collect(Collectors.toList());
+                List<Project> projectList = projectMapper.selectList(new QueryWrapper<Project>().in("id", pids));
+                String collect = projectList.stream().map(Project::getProjectName).collect(Collectors.joining(","));
+                //计算总工时
+                double sum = reportList.stream().mapToDouble(Report::getWorkingTime).sum();
+                double waiting = reportList.stream().filter(r -> r.getState() == 0).mapToDouble(Report::getWorkingTime).sum();
+                double reject = reportList.stream().filter(r -> r.getState() == 2).mapToDouble(Report::getWorkingTime).sum();
+                double pass = reportList.stream().filter(r -> r.getState() == 1).mapToDouble(Report::getWorkingTime).sum();
+                String str = "您上周共参与了" + projectList.size()+"个项目,总工时为" + sum+"小时。其中审核通过"+pass
+                        +"小时, 待审核"+waiting+"小时,驳回"+reject+"小时。";
+                pushLastWeekReportFill(u, str);
+            }
         }
     }
 
@@ -190,4 +233,35 @@ public class TimingTask {
         }
 
     }
+
+
+    //推送上周填写的日报工时情况
+    public void pushLastWeekReportFill(User user, String alertMsg) {
+        //1,配置
+        WxMpInMemoryConfigStorage wxStorage = new WxMpInMemoryConfigStorage();
+        wxStorage.setAppId(appId);
+        wxStorage.setSecret(appSecret);
+        WxMpService wxMpService = new WxMpServiceImpl();
+        wxMpService.setWxMpConfigStorage(wxStorage);
+
+        //2,推送消息
+        WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
+                .toUser(user.getWxOpenid())//要推送的用户openid
+                .templateId(TEMPLATE_REPORT_FILL)//模版id
+                .url("http://mobworktime.ttkuaiban.com/")//点击模版消息要访问的网址
+                .build();
+        //3,如果是正式版发送模版消息,这里需要配置你的信息
+        templateMessage.addData(new WxMpTemplateData("first", alertMsg, "#FF00FF"));
+        templateMessage.addData(new WxMpTemplateData("keyword1", user.getName(), "#000000"));
+        templateMessage.addData(new WxMpTemplateData("keyword2", user.getDepartmentName(), "#000000"));
+        templateMessage.addData(new WxMpTemplateData("remark", "-", "#000000"));
+        //                templateMessage.addData(new WxMpTemplateData(name2, value2, color2));
+        try {
+            wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
+        } catch (Exception e) {
+            System.out.println("推送失败:" + e.getMessage());
+            e.printStackTrace();
+        }
+
+    }
 }

+ 4 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/DateTimeUtil.java

@@ -60,7 +60,9 @@ public class DateTimeUtil {
 
     public static void main(String[] args) {
 
-        System.out.println(getHoursFromDouble(3.5)
-        );
+        DateTimeFormatter mdFormat = DateTimeFormatter.ofPattern("yyyy/M/d");
+        LocalDate parse = LocalDate.parse("2022/1/29", mdFormat);
+        LocalDate parse2 = LocalDate.parse("2022/1/29", mdFormat);
+        System.out.println(parse.isEqual(parse2));
     }
 }

+ 16 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/WorkDayCalculateUtils.java

@@ -72,7 +72,22 @@ public class WorkDayCalculateUtils {
                 "2022-09-20","2022-09-21",//中秋节
                 "2022-10-01", "2022-10-02","2022-10-03","2022-10-04","2022-10-05","2022-10-06","2022-10-07",//国庆节
         });
-        YEAR_DEFINE.put("map2022", map2022);
+        YEAR_DEFINE.put("2022", map2022);
+
+//        HashMap<String, String[]> map2023 = new HashMap<>();
+//        //除了周末的特殊工作日
+//        map2023.put(KEY_SPECIAL_WORK_DAYS, new String[]{"2022-01-29","2022-01-30","2022-04-02","2022-04-24","2022-05-07","2022-10-08","2022-10-09",});
+//        //除了周末的特殊休息日,例如国庆中秋春节
+//        map2023.put(KEY_SPECIAL_REST_DAYS, new String[]{
+//                "2022-01-03",//元旦
+//                "2022-01-31", "2022-02-01", "2022-02-02", "2022-02-03", "2022-02-04",//春节
+//                "2022-04-04","2022-04-05",//清明节
+//                "2022-05-02","2022-05-03","2022-05-04",//劳动节
+//                "2022-06-03",//端午节
+//                "2022-09-20","2022-09-21",//中秋节
+//                "2022-10-01", "2022-10-02","2022-10-03","2022-10-04","2022-10-05","2022-10-06","2022-10-07",//国庆节
+//        });
+//        YEAR_DEFINE.put("2023", map2023);
 
     }
 

+ 1 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/application.yml

@@ -94,6 +94,7 @@ wx:
   template_report_pass: dbMuR2v7lxXLwRaorIWQ4T6ilvn0vzqmDDkD_3ZsaXc
   template_project_deadline: kY2Qzec64uOANNXA0yn-PV09ZnNjCeGXwWjTaVmQiLU
   template_report_reject: TICiRkvCpF4NCbkPOjefXTpz7jXgpt0SZGkNjCMIt3M
+  template_report_week: lhwkaW9BKwCvMtCuoAxLw4lZoGgMaucL0Ap0Vz-5KOY
 ##actuator健康检查配置
 management:
   security:

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

@@ -113,6 +113,40 @@
         ORDER BY a.creator_id ASC
     </select>
 
+    <!--新版获取待审核的列表,一次性获取全部 -->
+    <select id="getAuditReportList" resultType="java.util.Map">
+        SELECT a.id, user.id as userId, user.name, DATE_FORMAT(a.create_date, '%Y-%m-%d') as date, a.project_id as projectId, b.project_name AS project, a.working_time AS time, a.content, a.state, a.time_type as timeType,
+        a.cost, a.report_time_type as reportTimeType, a.start_time as startTime,
+        a.end_time as endTime, b.incharger_id as inchargerId,
+        a.creator_id as creatorId, d.name as subProjectName,a.task_id as taskId, task.name as taskName, a.is_overtime as isOvertime,a.progress as progress,
+        a.department_audit_state as departmentAuditState, a.stage, a.pic_str as picStr, multi_worktime as multiWorktime
+        , reject_reason as rejectReason, reject_username as rejectUsername, reject_userid as rejectUserid, degree_id as degree_id,report_extra_degree.name as degreeName
+        FROM report AS a
+        left join user on user.id = a.creator_id
+        JOIN project AS b ON a.project_id=b.id
+        left join sub_project as d on d.id = a.sub_project_id
+        left join task on task.id = a.task_id
+        left join report_extra_degree on report_extra_degree.id = a.degree_id
+        WHERE a.company_id = #{companyId}
+        and a.state = 0
+        <if test="date != null and date != ''">
+            AND a.create_date=#{date}
+        </if>
+        <if test="departmentId != null">
+            AND user.department_id=#{departmentId}
+        </if>
+        <if test="projectId != null">
+            AND a.project_id=#{projectId}
+        </if>
+        <if test="inchargerId != null">
+            AND b.incharger_id = #{inchargerId}
+        </if>
+        <if test="isEngeering == 1">
+            AND a.department_audit_state = 1
+        </if>
+        ORDER BY a.create_date desc, a.creator_id asc
+    </select>
+
     <!--根据专业负责人id,日期获取相关项目的全部报告信息-->
     <select id="getProfessionInchargeReportByDate" resultType="java.util.Map">
         SELECT a.id, a.project_id as projectId, b.project_name AS project, a.working_time AS time, a.content, a.state, a.time_type as timeType,
@@ -246,15 +280,37 @@
     </select>
 
     <!--导入工时待审核列表-->
-    <select id="getDetailImportByState" resultType="java.util.Map">
-        SELECT DISTINCT b.id, b.name, cast(b.department_id as SIGNED) as departmentId,a.create_date AS date
+    <select id="getDeptImportAuditList" resultType="java.util.Map">
+        SELECT a.id, user.id as userId, user.name, DATE_FORMAT(a.create_date, '%Y-%m-%d') as date, a.project_id as projectId, b.project_name AS project, a.working_time AS time, a.content, a.state, a.time_type as timeType,
+        a.cost, a.report_time_type as reportTimeType, a.start_time as startTime,
+        a.end_time as endTime, b.incharger_id as inchargerId,
+        a.creator_id as creatorId, d.name as subProjectName,a.task_id as taskId, task.name as taskName, a.is_overtime as isOvertime,a.progress as progress,
+        a.department_audit_state as departmentAuditState, a.stage, a.pic_str as picStr, multi_worktime as multiWorktime
+        , reject_reason as rejectReason, reject_username as rejectUsername, reject_userid as rejectUserid, degree_id as degree_id,report_extra_degree.name as degreeName
         FROM report AS a
-        JOIN user AS b ON a.creator_id=b.id
-        WHERE a.state = #{state} AND b.company_id=#{companyId}
+        left join user on user.id = a.creator_id
+        JOIN project AS b ON a.project_id=b.id
+        left join sub_project as d on d.id = a.sub_project_id
+        left join task on task.id = a.task_id
+        left join report_extra_degree on report_extra_degree.id = a.degree_id
+        WHERE a.company_id = #{companyId}
+        and a.state = -1
         <if test="leaderId != null">
-            AND b.department_id in (select department_id from department where report_audit_userid = #{leaderId})
+            AND user.department_id in (select department_id from department where report_audit_userid = #{leaderId})
         </if>
-        ORDER BY a.create_date DESC
+        <if test="startDate != null and startDate != '' and endDate != null and endDate != ''">
+            AND a.create_date between #{startDate} and #{endDate}
+        </if>
+        <if test="departmentIdList != null">
+            AND user.department_id in
+            <foreach collection="departmentIdList" open="(" close=")" separator="," item="deptId">
+                #{deptId}
+            </foreach>
+        </if>
+        <if test="projectId != null">
+            AND a.project_id= #{projectId}
+        </if>
+        ORDER BY a.create_date desc, a.creator_id asc
     </select>
 
     <select id="getRealProjectTime" resultType="java.util.Map">

+ 0 - 3
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/UserCorpwxTimeMapper.xml

@@ -34,9 +34,6 @@
         <if test="deptId != null">
             AND user.`department_id` = #{deptId}
         </if>
-        <if test="excludeWeekend == 1">
-            AND a.week_day &lt; 6
-        </if>
         ORDER BY a.create_date ASC
     </select>
 

+ 7 - 2
fhKeeper/formulahousekeeper/timesheet/src/main.js

@@ -113,15 +113,15 @@ router.beforeEach((to, from, next) => {
                         //没有开启导入日报审核,则不需要
                         filterRouter = filterRouter.filter(r=>{return r.name != '导入日报审核'});
                     }
-
+                    
                     if (user.role == 1 || user.role == 2) {
-                        console.log(filterRouter, 12345, '看看')
                         getRoutes = filterRouter;
                     } else {
                         var modules = userModules.filter(u=>u.role == user.role)[0].modules;
                         if ((user.role == 0 || user.role == 5) && user.leader) {
                             // if (user.role == 5 && user.leader) {
                             modules.push(2, "项目报告审核");
+                            
                         }
                         if (user.role == 6 && user.timeType.needDeptAudit == 1) {
                             //公司领导可以进行导入日报的审核
@@ -131,6 +131,11 @@ router.beforeEach((to, from, next) => {
                             return modules.filter(m=>m == r.name).length > 0;
                         });
                     }
+                    //同步企业微信考勤打卡的情况下,根据深圳赛元微电子的要求,屏蔽项目报告审核模块
+                    if (user.timeType.syncCorpwxTime == 1) {
+                        getRoutes = getRoutes.filter(r=>{return r.name != '项目报告审核'});
+                    }
+                    
                     
                     global.antRouter = fixedRouter.concat(getRoutes);
                     router.addRoutes(fixedRouter.concat(getRoutes));

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

@@ -149,7 +149,7 @@
                 </el-table-column>
                 <el-table-column  label="总费用"  width="100" align="right">
                   <template slot-scope="scope">
-                        {{scope.row.feeMan+scope.row.feeNormal+scope.row.feeTravel+scope.row.feeOutsourcing}}
+                        {{(scope.row.feeMan+scope.row.feeNormal+scope.row.feeTravel+scope.row.feeOutsourcing).toFixed(2)}}
                     </template>
                 </el-table-column>
             </el-table>
@@ -188,12 +188,12 @@
                 </el-table-column>
                 <el-table-column  label="总费用"  width="100" align="right">
                   <template slot-scope="scope">
-                        {{scope.row.feeMan+scope.row.feeNormal+scope.row.feeTravel+scope.row.feeOutsourcing}}
+                        {{(scope.row.feeMan+scope.row.feeNormal+scope.row.feeTravel+scope.row.feeOutsourcing).toFixed(2)}}
                     </template>
                 </el-table-column>
                 <el-table-column  label="利润"  width="100" align="right">
                   <template slot-scope="scope">
-                        {{(scope.row.contractAmount==null?0:scope.row.contractAmount) - (scope.row.feeMan+scope.row.feeNormal+scope.row.feeTravel+scope.row.feeOutsourcing)}}
+                        {{((scope.row.contractAmount==null?0:scope.row.contractAmount) - (scope.row.feeMan+scope.row.feeNormal+scope.row.feeTravel+scope.row.feeOutsourcing)).toFixed(2)}}
                     </template>
                 </el-table-column>
                 <el-table-column  label="利润率"  width="100" align="right">
@@ -239,12 +239,12 @@
                 </el-table-column>
                 <el-table-column  label="总费用"  width="100" align="right">
                   <template slot-scope="scope">
-                        {{scope.row.feeMan+scope.row.feeNormal+scope.row.feeTravel+scope.row.feeOutsourcing}}
+                        {{(scope.row.feeMan+scope.row.feeNormal+scope.row.feeTravel+scope.row.feeOutsourcing).toFixed(2)}}
                     </template>
                 </el-table-column>
                 <el-table-column  label="利润"  width="100" align="right">
                   <template slot-scope="scope">
-                        {{(scope.row.contractAmount==null?0:scope.row.contractAmount) - (scope.row.feeMan+scope.row.feeNormal+scope.row.feeTravel+scope.row.feeOutsourcing)}}
+                        {{((scope.row.contractAmount==null?0:scope.row.contractAmount) - (scope.row.feeMan+scope.row.feeNormal+scope.row.feeTravel+scope.row.feeOutsourcing)).toFixed(2)}}
                     </template>
                 </el-table-column>
                 <el-table-column  label="利润率"  width="100" align="right">

+ 3 - 25
fhKeeper/formulahousekeeper/timesheet/src/views/project/projectInside.vue

@@ -291,7 +291,7 @@
                         <el-radio-group v-model="radio">
                             <el-radio :label="0" class="rala1">状态正常</el-radio>
                             <el-radio :label="1" class="rala2">存在风险</el-radio>
-                            <el-radio :label="2" class="rala3">进展期</el-radio>
+                            <el-radio :label="2" class="rala3">进展期</el-radio>
                         </el-radio-group>
 
                         <el-input
@@ -321,29 +321,7 @@
 
                     </div>
 
-                    <!-- 任务进展列表 -->
-                    <!-- <div class="ddl" v-if="ProgressList.length > 0">
-                        <div class="elCard" v-for="item in ProgressList" :key="item.id" style="margin-bottom: 10px; height:" >
-                            <i class="el-icon-success" style="color: #43d14f;" v-if="item.status == 0"></i>
-                            <i class="el-icon-success" style="color: #fd7624;" v-else-if="item.status == 1"></i>
-                            <i class="el-icon-success" style="color: #fd4d47;" v-else></i>
-                            <span v-if="item.status == 0">状态正常</span>
-                            <span v-else-if="item.status == 1">状态正常</span>
-                            <span v-else>进展预期</span>
-
-                            <el-dropdown trigger="click" style="float:right;cursor:pointer; float: right;">
-                                    <i class="el-icon-more" ></i>
-                                    <el-dropdown-menu slot="dropdown">
-
-                                        <el-dropdown-item divided>
-                                            <span @click="deleteTaskProgress(item.id)"><i class="el-icon-delete"></i>删除列表</span></el-dropdown-item>
-                                    </el-dropdown-menu>
-                            </el-dropdown>
-                            <div class="elCard_qu">屈经理更新于{{item.indate | relativeTime}}</div>
-                            <p style="padding-left: 20px;">{{item.content}}</p>
-                            <div class="examine"><el-button type="text" @click="innerVisibless = true" style="color: #8F87A3;">查看历史记录</el-button></div>
-                        </div>
-                    </div> -->
+                    
 
                     <div class="ddl" v-if="recentProgressInfo != null && recentProgressInfo.id != null">
                         <div class="elCard" style="margin-bottom: 10px; height:" >
@@ -393,7 +371,7 @@
                                         <div>
                                             <span v-if="activity.status == 0" style="color: #43D14F">状态正常</span>
                                             <span v-if="activity.status == 1" style="color: #FD7624">存在风险</span>
-                                            <span v-if="activity.status == 2" style="color: red">进展期</span>
+                                            <span v-if="activity.status == 2" style="color: red">进展期</span>
                                             <span style="display: inline-block; float: right; color: #8C8C8C">{{activity.indate | relativeTime}}</span>
                                         </div>
                                         <p style="color: #8C8C8C">{{activity.content}}</p>

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

@@ -298,7 +298,7 @@
                                         <div>
                                             <span v-if="activity.status == 0" style="color: #43D14F">状态正常</span>
                                             <span v-if="activity.status == 1" style="color: #FD7624">存在风险</span>
-                                            <span v-if="activity.status == 2" style="color: red">进展期</span>
+                                            <span v-if="activity.status == 2" style="color: red">进展期</span>
                                             <span style="display: inline-block; float: right; color: #8C8C8C">{{activity.indate | relativeTime}}</span>
                                         </div>
                                         <p style="color: #8C8C8C">{{activity.content}}</p>

+ 11 - 22
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

@@ -582,10 +582,12 @@
         </el-dialog>
 
         <!-- 批量日报审核 -->
-        <el-dialog title="批量日报审核" :visible.sync="approveDialogVisible" width="500px" >
+        <el-dialog title="批量项目报告审核" :visible.sync="approveDialogVisible" width="500px" >
+            
             <el-checkbox v-model="isAllSelect" label="全选" style="margin-left:24px;" @change="selectAll" v-if="reportNames.length > 0"></el-checkbox>
             <el-tree ref="approveTree" node-key="id" :data="reportNames" show-checkbox="true" @check-change="handleCheckChange" >
             </el-tree>
+            <div style="margin-left:30px;color:#999;" v-if="user.company.packageEngineering==1">仅能看到自己负责的待项目审核的日报填写人员</div>
             <span slot="footer" class="dialog-footer">
                 <el-button @click="approveDialogVisible = false">取消</el-button>
                 <el-button type="primary" @click="submitBatchApprove" :disabled="batchShowData.length == 0">审核通过</el-button>
@@ -758,22 +760,7 @@
                 <el-table-column prop="username" label="员工姓名"  ></el-table-column>
                 <el-table-column prop="startTime" label="上班时间"  ></el-table-column>
                 <el-table-column prop="endTime" label="下班时间" ></el-table-column>
-                <el-table-column prop="cardTime" label="打卡时长" align="right">
-                    <template slot-scope="scope">
-                        {{scope.row.cardTime.toFixed(1)}}h
-                    </template>
-                </el-table-column>
-                <el-table-column prop="askLeaveTime" label="请假时长"  align="right">
-                    <template slot-scope="scope">
-                        {{scope.row.askLeaveTime.toFixed(1)}}h
-                    </template>
-                </el-table-column>
-                <el-table-column prop="outdoorTime" label="补卡/外出时长"  align="right">
-                    <template slot-scope="scope">
-                        {{scope.row.outdoorTime.toFixed(1)}}h
-                    </template>
-                </el-table-column>
-                <el-table-column prop="workHours" label="工作时长"  align="right">
+                <el-table-column prop="workHours" label="实际工作时长"  align="right">
                     <template slot-scope="scope">
                         {{scope.row.workHours.toFixed(1)}}h
                     </template>
@@ -1859,7 +1846,9 @@
                     var hasUnChecked =false;
                     var id = '';
                     for (var j=0;j<report.data.length; j++) {
-                        if (report.data[j].state == 0) {
+                        if (report.data[j].state == 0 
+                            && (this.user.company.packageEngineering==0 || (this.user.company.packageEngineering==1 && report.data[j].departmentAuditState == 1))
+                            && (this.user.role == 1 || this.user.role == 2 || report.data[j].inchargerId == this.user.id)) {
                             hasUnChecked = true;
                             id += report.data[j].id+',';
                         }
@@ -2004,13 +1993,13 @@
                     if (res.code == "ok") {
                         var list = res.data , list1 = JSON.parse(JSON.stringify(res.data));
                         // let noAllData = JSON.parse(JSON.stringify(res.data));
-                        if (this.user.role > 0) {
-                            list.splice(0,0,{
+                        // if (this.user.role > 0) {
+                            
+                        // }
+                        list.splice(0,0,{
                                 id: -1,
                                 label: '全部人员',
                             })
-                        }
-                       
                         this.membCount = 0;
                         //设置员工到部门下面
                         this.setUserToDept(list);

+ 9 - 7
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/list_department.vue

@@ -27,19 +27,21 @@
                     <el-timeline>
                         <el-timeline-item v-for="(item,index) in props.row.data" :key="index">
                             <el-card shadow="never">
-                                <p>项目:<b>{{item.project}}<span v-if="item.subProjectName != null"> / {{item.subProjectName}}</span></b></p>
+                                <p>项目:<b>{{item.project}}<span v-if="item.subProjectName != null"> / {{item.subProjectName}}</span>
+                                <span v-if="user.company.packageEngineering == 1" style="color:#DAA520;">{{item.departmentAuditState==-1?'待专业审核':'待部门审核'}}</span>
+                                </b></p>
                                 <p v-if="user.company.packageEngineering == 1">
                                     专业进度:
                                     <span style="margin-right:10px;" v-for="progressItem in item.professionProgressList" :key="progressItem.id">
                                         {{progressItem.professionName}}({{progressItem.progress}}%)
                                         <el-tooltip v-if="progressItem.auditState == 0"  content="待审核" effect="light" placement="top">
-                                        <i class="iconfont firerock-icondaibandengdaishenhe"></i>
+                                        <i class="iconfont firerock-icondaibandengdaishenhe" style="color:#DAA520;"></i>
                                         </el-tooltip>
                                         <el-tooltip v-if="progressItem.auditState == 1" content="已通过" effect="light" placement="top">
-                                        <i  class="iconfont firerock-iconshenhetongguo" ></i>
+                                        <i  class="iconfont firerock-iconshenhetongguo" style="color:#32CD32;"></i>
                                         </el-tooltip>
                                         <el-tooltip v-if="progressItem.auditState == 2" content="不通过" effect="light" placement="top">
-                                        <i  class="iconfont firerock-iconshenhebohui"></i>
+                                        <i  class="iconfont firerock-iconshenhebohui" style="color:#red;"></i>
                                         </el-tooltip>
                                         </span>
                                 </p>
@@ -169,7 +171,7 @@
                 if (ids.length > 0) {
                     ids = ids.substring(0, ids.length-1);
                 }
-                this.http.post(isPass?'/report/batchApproveReport':'/report/batchDenyReport', {ids: ids},
+                this.http.post(isPass?'/report/batchApproveReport':'/report/batchDenyReport', {ids: ids, isDepartment:1},
                 res => {
                     this.listLoading = false;
                     if (res.code == "ok") {
@@ -241,7 +243,7 @@
                     ids +=(element.id+',');
                 });
 
-                this.http.post(this.port.report.approve, {id: id ,reportIds: ids},
+                this.http.post(this.port.report.approve, {id: id ,reportIds: ids, isDepartment:1},
                 res => {
                     this.logining = false;
                     if (res.code == "ok") {
@@ -316,7 +318,7 @@
                 data.forEach(element => {
                     ids +=(element.id+',');
                 });
-                this.http.post( this.port.report.deny, {id: id , date: time, reportIds: ids},
+                this.http.post( this.port.report.deny, {id: id , date: time, reportIds: ids, isDepartment: 1},
                 res => {
                     this.logining = false;
                     if (res.code == "ok") {

+ 24 - 20
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/list_import.vue

@@ -95,13 +95,19 @@
             </el-table-column> -->
             
             <el-table-column prop="name" label="姓名" sortable width="120"></el-table-column>
-            <el-table-column prop="dateStr" label="日期" sortable width="150">
+            <el-table-column prop="date" label="日期" sortable width="150">
             </el-table-column>
-            <el-table-column prop="reportTime" label="工作时长(h)" width="150">
+            <el-table-column prop="project" label="项目" >
             </el-table-column>
-            <el-table-column prop="allProjectTime" label="项目工时成本" >
+            <el-table-column prop="time" label="工作时长(h)"  align="right">
+                <template slot-scope="scope">
+                    <span>{{scope.row.time.toFixed(1)}}</span>
+                    
+                </template>
+            </el-table-column>
+            <el-table-column prop="cost" label="成本(元)"   align="right">
             </el-table-column>
-            <el-table-column prop="state" label="状态" sortable width="150px">
+            <el-table-column prop="state" label="状态" width="150">
                 <template slot-scope="scope">
                     <span v-if="scope.row.state == -1" style="color:#DAA520;">待审核</span>
                     <span v-else-if="scope.row.state == 1" style="color:#32CD32;">已通过</span>
@@ -111,8 +117,8 @@
             <el-table-column label="操作" width="220">
                 <template slot-scope="scope">
                     <el-button v-if="scope.row.state == -1" type="primary" :loading="logining" size="small" @click="approve(scope.row.id,scope.row.date, scope.row)">通过</el-button>
-                    <el-button v-if="scope.row.state == -1" type="danger" :loading="logining" size="small" @click="showDenyDialog(scope.row.id,0,scope.row.dateStr, scope.row)">驳回</el-button>
-                    <el-button v-if="scope.row.state == 1" type="danger" :loading="logining" size="small" @click="showDenyDialog(scope.row.id,1,scope.row.dateStr, scope.row)">撤销</el-button>
+                    <el-button v-if="scope.row.state == -1" type="danger" :loading="logining" size="small" @click="showDenyDialog(scope.row.id,0,scope.row.date, scope.row)">驳回</el-button>
+                    <el-button v-if="scope.row.state == 1" type="danger" :loading="logining" size="small" @click="showDenyDialog(scope.row.id,1,scope.row.date, scope.row)">撤销</el-button>
                 </template>
             </el-table-column>
         </el-table>
@@ -205,10 +211,11 @@
                 var ids = '';
                 for (var i=0;i<this.multipleSelection.length; i++) {
                     var line = this.multipleSelection[i];
-                    var array = line.data;
-                    for (var m=0;m<array.length; m++) {
-                        ids += array[m].id+',';
-                    }
+                    // var array = line.data;
+                    // for (var m=0;m<array.length; m++) {
+                    //     ids += array[m].id+',';
+                    // }
+                    ids += line.id + ',';
                 }
                 if (ids.length > 0) {
                     ids = ids.substring(0, ids.length-1);
@@ -294,11 +301,11 @@
                 console.log(item);
                 this.logining = true;
                 
-                var ids = '';
-                var data = item.data;
-                data.forEach(element => {
-                    ids +=(element.id+',');
-                });
+                var ids = item.id;
+                // var data = item.data;
+                // data.forEach(element => {
+                //     ids +=(element.id+',');
+                // });
 
                 this.http.post(this.port.report.approve, {id: id ,reportIds: ids},
                 res => {
@@ -365,11 +372,8 @@
             },
             showDenyDialog(id,i, date, item) {
                 this.denyReasonDialog = true;
-                var ids = '';
-                var data = item.data;
-                data.forEach(element => {
-                    ids +=(element.id+',');
-                });
+                var ids = item.id;
+                
                 this.denyForm = {id: id ,i:i, date: date, reportIds: ids, reason:null};
             },
 

+ 14 - 9
fhKeeper/formulahousekeeper/timesheet_h5/src/views/review/department_list.vue

@@ -14,7 +14,10 @@
                         <!-- <span>系统智能统计:{{item.calculateTime}}h</span> -->
                     </div>
                     <div v-for="(item1,index1) in item.data" :key="index1" class="one_report_data">
-                        <div class="project_title">项目:{{item1.project}}</div>
+                        <div class="project_title">项目:{{item1.project}}
+                        <span v-if="user.company.packageEngineering == 1" 
+                            style="color:#DAA520;">{{item1.departmentAuditState==-1?'待专业审核':'待部门审核'}}</span>
+                        </div>
                         <div class="project_title" v-if="user.company.packageEngineering == 1">
                             专业进度:
                             <span style="margin-right:10px;" v-for="progressItem in item1.professionProgressList" :key="progressItem.id">{{progressItem.professionName}}({{progressItem.progress}}%) 
@@ -49,7 +52,7 @@
                     </div>
                     <div class="form_btn" slot="footer">
                         <van-button size="small" type="info" @click="approve(item.id, item)">通过</van-button>
-                        <van-button size="small" type="danger" @click="deny(item.id,1, item)">驳回</van-button>
+                        <van-button size="small" type="danger" @click="deny(item.id,item)">驳回</van-button>
                     </div>
                     <van-popup v-model="imgShow" position="bottom" closeable >
                         <van-swipe class="my-swipe"  indicator-color="white">
@@ -153,20 +156,22 @@
                         ids +=(element.id+',');
                     }
                 });
-                this.$axios.post("/report/approve", {id: id , date: this.nowTime, reportIds: ids})
+                var that = this;
+                this.$axios.post("/report/approve", {id: id , date: this.nowTime, reportIds: ids, isDepartment: 1})
                 .then(res => {
                     if(res.code == "ok") {
                         toast.clear();
                         this.$toast.success('审核成功');
-                        this.getReport();
+                        
+                        that.getReport();
                     } else {
                         toast.clear();
-                        this.$toast.fail('审核失败');
+                        this.$toast.fail(res.msg);
                     }
                 }).catch(err=> {toast.clear();});
             },
 
-            deny(id,i, item) {
+            deny(id, item) {
                 const toast = this.$toast.loading({
                     forbidClick: true,
                     duration: 0
@@ -178,15 +183,15 @@
                         ids +=(element.id+',');
                     }
                 });
-                this.$axios.post("/report/deny", {id: id , date: this.nowTime, reportIds: ids})
+                this.$axios.post("/report/deny", {id: id , date: this.nowTime, reportIds: ids, isDepartment: 1})
                 .then(res => {
                     if(res.code == "ok") {
                         toast.clear();
-                        this.$toast.success(i==0?'驳回成功':'撤销成功');
+                        this.$toast.success('驳回成功');
                         this.getReport();
                     } else {
                         toast.clear();
-                        this.$toast.fail(i==0?'驳回失败':'撤销失败');
+                        this.$toast.fail(res.msg);
                     }
                 }).catch(err=> {toast.clear();});
             }