ソースを参照

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

ggooalice 2 年 前
コミット
27d7fe04dc
20 ファイル変更404 行追加71 行削除
  1. 2 2
      fhKeeper/formulahousekeeper/management-platform/pom.xml
  2. 15 7
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java
  3. 152 28
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/WeiXinCorpController.java
  4. 14 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/WxCorpInfoController.java
  5. 7 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/WxCorpInfo.java
  6. 38 4
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  7. 6 3
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportMapper.xml
  8. 2 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/WxCorpInfoMapper.xml
  9. 9 0
      fhKeeper/formulahousekeeper/ops-platform/src/main/java/com/management/platform/entity/VcompanyCustomerContact.java
  10. 10 10
      fhKeeper/formulahousekeeper/timesheet/config/index.js
  11. BIN
      fhKeeper/formulahousekeeper/timesheet/src/assets/image/047_S.jpg
  12. BIN
      fhKeeper/formulahousekeeper/timesheet/src/assets/image/Step1.jpg
  13. BIN
      fhKeeper/formulahousekeeper/timesheet/src/assets/image/Step2.jpg
  14. BIN
      fhKeeper/formulahousekeeper/timesheet/src/assets/image/Step3.jpg
  15. BIN
      fhKeeper/formulahousekeeper/timesheet/src/assets/image/userHead.jpg
  16. 3 3
      fhKeeper/formulahousekeeper/timesheet/src/views/corpreport/list.vue
  17. 1 0
      fhKeeper/formulahousekeeper/timesheet/src/views/project/list.vue
  18. 142 9
      fhKeeper/formulahousekeeper/timesheet/src/views/team/index.vue
  19. 1 1
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue
  20. 2 2
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/list.vue

+ 2 - 2
fhKeeper/formulahousekeeper/management-platform/pom.xml

@@ -10,8 +10,8 @@
     <modelVersion>4.0.0</modelVersion>
 
     <groupId>com.hssx.parent</groupId>
-    <artifactId>management-platform</artifactId>
-    <version>1.0-SNAPSHOT</version>
+    <artifactId>timesheet</artifactId>
+    <version>3.4.0</version>
 
     <dependencies>
         <dependency>

+ 15 - 7
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java

@@ -274,7 +274,7 @@ public class ReportController {
                         return msg;
                     }
                 } else {
-                    //批量填报
+                    //批量填报(含代填)
                     String[] dateArr = createDate[i].split("@");
                     for (String curDate : dateArr) {
                         if (curP.getStatus() == 2) {
@@ -374,7 +374,7 @@ public class ReportController {
         }
 
         SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
-        //判断当前操作的人员,是不是系统管理员
+        //判断当前操作的人员,是否有代填权限
         List<SysRichFunction> functionList = sysFunctionMapper.getRoleFunctions(user.getRoleId(), "代填日报");
         if (functionList.size() == 0) {
             //非系统管理员,检查填报时间
@@ -439,12 +439,21 @@ public class ReportController {
             for (int i = 0; i < id.length; i++) {
                 if (createDate[i].contains("@")) {
                     DateTimeFormatter mdFormatter = DateTimeFormatter.ofPattern("MM-dd");
-                    //这是批量填报的情况,日期有范围
+                    //这是批量填报的情况(含代填),日期有范围
                     String[] dateArray = createDate[i].split("@");
                     String startDate = dateArray[0];
                     String endDate = dateArray[1];
                     //检查该时间范围是否已经有填写过的日报了,代填日报不需要检查
-                    List<Report> oldReportList = reportService.list(new QueryWrapper<Report>().between("create_date", startDate, endDate).eq("creator_id", token));
+                    List<Report> oldReportList = null;
+                    if (targetUserList == null) {
+                        //非代填的情况
+                        oldReportList = reportService.list(new QueryWrapper<Report>().between("create_date", startDate, endDate).eq("creator_id", token));
+                    } else {
+                        //代填的情况
+                        List<String> checkUserId = targetUserList.stream().map(User::getId).collect(Collectors.toList());
+                        oldReportList = reportService.list(new QueryWrapper<Report>().select("id, create_date").between("create_date", startDate, endDate).in("creator_id", checkUserId));
+                    }
+
                     if (oldReportList.size() > 0) {
                         List<LocalDate> collect = oldReportList.stream().map(Report::getCreateDate).collect(Collectors.toList());
                         StringBuilder sb = new StringBuilder();
@@ -458,8 +467,6 @@ public class ReportController {
                         return msg;
                     }
 
-//                    LocalDate localStartDate = LocalDate.parse(startDate, ddtf);
-//                    LocalDate localEndDate = LocalDate.parse(endDate, ddtf);
                     List<LocalDate> workDaysListInRange = WorkDayCalculateUtils.getWorkDaysListInRange(startDate, endDate);
                     if (workDaysListInRange.size() == 0) {
                         HttpRespMsg msg = new HttpRespMsg();
@@ -523,10 +530,10 @@ public class ReportController {
 
                             //项目专业的进展
                             fillReportProgress(report, professionProgress[i]);
-                            System.out.println("======添加Report==========");
                             reportList.add(report);
                         } else {
                             //批量代填报的
+                            System.out.println("======跨日期批量代填=========");
                             for (User subsUser : targetUserList) {
                                 Report report = new Report()
                                         .setId(id[i] == -1 ? null : id[i])
@@ -572,6 +579,7 @@ public class ReportController {
                                 if (progress != null && progress[i] != null) {
                                     report.setProgress(progress[i]);
                                 }
+                                hourCost = subsUser.getCost();
                                 //计算工时和成本
                                 if (report.getMultiWorktime() == 0) {
                                     fillReportHours(report, hourCost, workingTime==null?null:workingTime[i], timeType==null?null:timeType[i], startTime==null?null:startTime[i], endTime==null?null:endTime[i],  sdf, comTimeType, excludeTimeList);

+ 152 - 28
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/WeiXinCorpController.java

@@ -184,25 +184,17 @@ public class WeiXinCorpController {
 
     //获取企业通讯录的accessToken
     private String getCorpConcactAccessToken(WxCorpInfo corpInfo) throws Exception {
-        if (corpInfo.getExpireTime().isBefore(LocalDateTime.now())) {
-            String url = GET_CORP_TOKEN.replace("ID", corpInfo.getCorpid()).replace("SECRET", concactSecret);
-//            HttpHeaders headers = new HttpHeaders();
-//            headers.setContentType(MediaType.APPLICATION_JSON);
-//            JSONObject reqParam = new JSONObject();
-//            reqParam.put("auth_corpid",  corpInfo.getCorpid());
-//            reqParam.put("permanent_code",  corpInfo.getPermanentCode());
-////            HttpEntity<String> requestEntity = new HttpEntity<String>(reqParam.toJSONString(), headers);
-            ResponseEntity<String> responseEntity = this.restTemplate.exchange(url,
-                    HttpMethod.GET, null, String.class);
-            if (responseEntity.getStatusCode() == HttpStatus.OK) {
-                String resp = responseEntity.getBody();
-                JSONObject json = JSONObject.parseObject(resp);
-                if (json.getIntValue("errcode") == 0) {
-                    String access_token = json.getString("access_token");
-                    corpInfo.setAccessToken(access_token);
-                } else {
-                    throw new Exception(json.toJSONString());
-                }
+        String url = GET_CORP_TOKEN.replace("ID", corpInfo.getCorpid()).replace("SECRET", corpInfo.getContactSecret());
+        ResponseEntity<String> responseEntity = this.restTemplate.exchange(url,
+                HttpMethod.GET, null, String.class);
+        if (responseEntity.getStatusCode() == HttpStatus.OK) {
+            String resp = responseEntity.getBody();
+            JSONObject json = JSONObject.parseObject(resp);
+            if (json.getIntValue("errcode") == 0) {
+                String access_token = json.getString("access_token");
+                corpInfo.setAccessToken(access_token);
+            } else {
+                throw new Exception(json.toJSONString());
             }
         }
         return corpInfo.getAccessToken();
@@ -975,9 +967,12 @@ public class WeiXinCorpController {
 
     @RequestMapping("/getCorpMembs")
     public HttpRespMsg getCorpMembs(String corpId) {
-
         WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectById(corpId);
-
+        if (wxCorpInfo.getContactSecret() == null) {
+            HttpRespMsg msg = new HttpRespMsg();
+            msg.setError("请先设置企业通讯录同步Secret");
+            return msg;
+        }
         Company company = companyMapper.selectById(wxCorpInfo.getCompanyId());
         String curCorpAccessToken = null;
         try {
@@ -1009,41 +1004,170 @@ public class WeiXinCorpController {
 
             //检查用户是否已经存在
             if (userMapper.selectCount(new QueryWrapper<User>().eq("corpwx_userid", curUserid)) == 0) {
-                userMapper.insert(user);
+                //检查姓名,该公司下面这个员工的姓名是否已经存在
+                List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId).eq("name", user.getName()));
+                if (userList.size() == 0) {
+                    //姓名也没有存在,就插入,检查人员是否已经超过上限
+                    userMapper.insert(user);
+                } else {
+                    //姓名已经存在,更新wxcorpid
+                    List<User> updateUser = new ArrayList<User>();
+                    userList.forEach(u-> {
+                        if (u.getCorpwxUserid() == null) {
+                            u.setCorpwxUserid(user.getCorpwxUserid());
+                            updateUser.add(u);
+                        }
+                    });
+                    if (updateUser.size() > 0) {
+                        userService.updateBatchById(updateUser);
+                    }
+                }
             }
         }
 
         //获取部门
-        JSONObject deptObj = getAllDepartments(curCorpAccessToken);
+        JSONObject deptObj = getDepartments(curCorpAccessToken);
         JSONArray deptObjJSONArray = deptObj.getJSONArray("department");
 
+        List<Department> sysDeptList = new ArrayList<>();
         for (int i=0;i<deptObjJSONArray.size(); i++) {
             int deptId = deptObjJSONArray.getJSONObject(i).getIntValue("id");
+            Department department = new Department();
+            department.setDepartmentName(deptObjJSONArray.getJSONObject(i).getString("name"));
+            department.setCompanyId(companyId);
+            //检查是否已经有了
+            Department oldDept = departmentMapper.selectOne(new QueryWrapper<Department>().eq("company_id", companyId).eq("department_name", department.getDepartmentName()).last("limit 1"));
+            if (oldDept == null) {
+                if (deptId != 1) {
+                    //忽略根,根是公司名称
+                    departmentMapper.insert(department);
+                }
+            } else {
+                department = oldDept;
+            }
 
+            sysDeptList.add(department);
+            deptObjJSONArray.getJSONObject(i).put("sys_dept_id", department.getDepartmentId());
+            Integer departmentId = department.getDepartmentId();
             JSONArray userList = getDeptUserSimple(curCorpAccessToken, deptId);
             for (int m=0;m<userList.size(); m++) {
                 JSONObject userJson = userList.getJSONObject(m);
                 String curUserid = userJson.getString("userid");
-                System.out.println("userid="+curUserid+", name=" + userJson.getString("name")+", mobile="+userJson.getString("mobile"));
+                log.info("userid="+curUserid+", name=" + userJson.getString("name")+", mobile="+userJson.getString("mobile"));
                 //不存在的人员, 进行插入
                 User user = new User();
 
                 user.setId(SnowFlake.nextId()+"")
-                        .setRoleId(defaultRole.getId())//默认普通员工
-                        .setRoleName(defaultRole.getRolename())
+                        .setRole(0)//默认普通员工
                         .setCompanyId(companyId)
-                        .setDepartmentId(0)
+                        .setDepartmentId(departmentId)
                         .setName(userJson.getString("name"))
                         .setCorpwxUserid(curUserid)
                         .setColor(ColorUtil.randomColor());
 
                 //检查用户是否已经存在
                 if (userMapper.selectCount(new QueryWrapper<User>().eq("corpwx_userid", curUserid)) == 0) {
-                    userMapper.insert(user);
+                    //检查姓名,该公司下面这个员工的姓名是否已经存在
+                    List<User> userList2 = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId).eq("name", user.getName()));
+                    if (userList2.size() == 0) {
+                        //姓名也没有存在,就插入,检查人员是否已经超过上限
+                        userMapper.insert(user);
+                    } else {
+                        //姓名已经存在,更新wxcorpid
+                        List<User> updateUser = new ArrayList<User>();
+                        userList2.forEach(u-> {
+                            if (u.getCorpwxUserid() == null) {
+                                u.setCorpwxUserid(user.getCorpwxUserid());
+                                updateUser.add(u);
+                            }
+                        });
+                        if (updateUser.size() > 0) {
+                            userService.updateBatchById(updateUser);
+                        }
+                    }
+                } else {
+//                    //更新信息
+//                    User oldUser = userMapper.selectList(new QueryWrapper<User>().eq("corpwx_userid", curUserid).eq("company_id", companyId).orderByDesc("create_time")).get(0);
+//                    oldUser.setName(userJson.getString("name"));
+//                    oldUser.setDepartmentId(departmentId);
+//                    userMapper.updateById(oldUser);
                 }
             }
         }
 
+        //再来更新部门的层级关系
+        List<Department> needUpdateDepts = new ArrayList<>();
+        for (int i=0;i<deptObjJSONArray.size(); i++) {
+            JSONObject deptJson = deptObjJSONArray.getJSONObject(i);
+            int pid = deptJson.getInteger("parentid");
+            if (pid != 1) {
+                //根部门Id = 1
+                Integer sysDeptId = deptJson.getInteger("sys_dept_id");
+                Department department = sysDeptList.stream().filter(d -> d.getDepartmentId().equals(sysDeptId)).findFirst().get();
+                //从deptjson数组中寻找parent item
+                for (int m=0;m<deptObjJSONArray.size(); m++) {
+                    JSONObject item = deptObjJSONArray.getJSONObject(m);
+                    if (item.getInteger("id").equals(pid)) {
+                        department.setSuperiorId(item.getInteger("sys_dept_id"));
+                        break;
+                    }
+                }
+                needUpdateDepts.add(department);
+            }
+        }
+        if (needUpdateDepts.size() > 0) {
+            departmentService.updateBatchById(needUpdateDepts);
+        }
+
+//        //获取部门
+//        JSONObject deptObj = getAllDepartments(curCorpAccessToken);
+//        JSONArray deptObjJSONArray = deptObj.getJSONArray("department");
+//
+//        for (int i=0;i<deptObjJSONArray.size(); i++) {
+//            int deptId = deptObjJSONArray.getJSONObject(i).getIntValue("id");
+//
+//            JSONArray userList = getDeptUserSimple(curCorpAccessToken, deptId);
+//            for (int m=0;m<userList.size(); m++) {
+//                JSONObject userJson = userList.getJSONObject(m);
+//                System.out.println(userJson);
+//                String curUserid = userJson.getString("userid");
+//                System.out.println("userid="+curUserid+", name=" + userJson.getString("name")+", mobile="+userJson.getString("mobile"));
+//                //不存在的人员, 进行插入
+//                User user = new User();
+//
+//                user.setId(SnowFlake.nextId()+"")
+//                        .setRoleId(defaultRole.getId())//默认普通员工
+//                        .setRoleName(defaultRole.getRolename())
+//                        .setCompanyId(companyId)
+//                        .setDepartmentId(0)
+//                        .setName(userJson.getString("name"))
+//                        .setCorpwxUserid(curUserid)
+//                        .setColor(ColorUtil.randomColor());
+//
+//                //检查用户是否已经存在
+//                if (userMapper.selectCount(new QueryWrapper<User>().eq("corpwx_userid", curUserid)) == 0) {
+//                    //检查姓名,该公司下面这个员工的姓名是否已经存在
+//                    List<User> userList2 = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId).eq("name", user.getName()));
+//                    if (userList2.size() == 0) {
+//                        //姓名也没有存在,就插入,检查人员是否已经超过上限
+//                        userMapper.insert(user);
+//                    } else {
+//                        //姓名已经存在,更新wxcorpid
+//                        List<User> updateUser = new ArrayList<User>();
+//                        userList2.forEach(u-> {
+//                            if (u.getCorpwxUserid() == null) {
+//                                u.setCorpwxUserid(user.getCorpwxUserid());
+//                                updateUser.add(u);
+//                            }
+//                        });
+//                        if (updateUser.size() > 0) {
+//                            userService.updateBatchById(updateUser);
+//                        }
+//                    }
+//                }
+//            }
+//        }
+
         return new HttpRespMsg();
     }
 

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

@@ -39,6 +39,20 @@ public class WxCorpInfoController {
         return msg;
     }
 
+    @RequestMapping("/saveContactSecret")
+    public HttpRespMsg saveContactSecret(WxCorpInfo info) {
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.data = wxCorpInfoService.updateById(info);
+        return msg;
+    }
+
+    @RequestMapping("/get")
+    public HttpRespMsg get(Integer companyId) {
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.data = wxCorpInfoService.getOne(new QueryWrapper<WxCorpInfo>().eq("company_id", companyId));
+        return msg;
+    }
+
     @RequestMapping("/testSendTemplateMsg")
     public HttpRespMsg testSendTemplateMsg(String userId) {
         User user = userMapper.selectById(userId);

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

@@ -15,7 +15,7 @@ import lombok.experimental.Accessors;
  * </p>
  *
  * @author Seyason
- * @since 2021-09-05
+ * @since 2022-06-28
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -81,6 +81,12 @@ public class WxCorpInfo extends Model<WxCorpInfo> {
     @TableField("agentid")
     private Integer agentid;
 
+    /**
+     * 通讯录ApiSecret
+     */
+    @TableField("contact_secret")
+    private String contactSecret;
+
 
     @Override
     protected Serializable pkVal() {

+ 38 - 4
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -766,11 +766,27 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         return httpRespMsg;
     }
 
+    //保存撤销的操作
+    private void saveCancelLog(String reportIds, User operator) {
+        List<Integer> ids = ListUtil.convertIntegerIdsArrayToList(reportIds);
+        List<Report> reportList = reportMapper.selectList(new QueryWrapper<Report>().in("id", ids));
+        Report report = reportList.get(0);
+        ReportLog log = new ReportLog();
+        log.setCreatorId(report.getCreatorId());
+        log.setCreateDate(report.getCreateDate());
+        log.setOperatorId(operator.getId());
+        log.setMsg(operator.getName()+"撤销了日报");
+        log.setCompanyId(report.getCompanyId());
+        log.setReportIds(reportIds);
+        reportLogMapper.insert(log);
+    }
+
     //保存提交日报的记录
     private void saveFillReportLog(List<Report> reportList) {
         Report r = reportList.get(0);
         List<ReportLog> addLogList = new ArrayList<>();
-        if (r.getState() == 0) {
+        //待审核或者直接通过的(代填时state可能是直接通过)
+        if (r.getState() == 0 || r.getState() == 1) {
             Integer companyId = r.getCompanyId();
             List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId));
             //提交待审核
@@ -783,11 +799,20 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 if (!oldLog.isPresent()) {
                     log.setOperatorId(report.getFillUserid()==null?report.getCreatorId():report.getFillUserid());
                     Optional<User> first = userList.stream().filter(u -> u.getId().equals(log.getCreatorId())).findFirst();
-                    String username = "";
+                    String reportOwner = "";
                     if (first.isPresent()) {
-                        username = first.get().getName();
+                        reportOwner = first.get().getName();
                     }
-                    log.setMsg(username+"提交了日报");
+                    String msg = null;
+                    if (report.getFillUserid()==null) {
+                        //自己填写自己的
+                        msg = reportOwner+"提交了日报";
+                    } else {
+                        //代填的
+                        first = userList.stream().filter(u -> u.getId().equals(log.getOperatorId())).findFirst();
+                        msg = first.get().getName()+"为" + reportOwner+"代填了日报";
+                    }
+                    log.setMsg(msg);
                     log.setCompanyId(companyId);
                     log.setReportIds(report.getId()+"");
                     addLogList.add(log);
@@ -805,6 +830,8 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         Report r = reportList.get(0);
         List<ReportLog> addLogList = new ArrayList<>();
         Integer companyId = r.getCompanyId();
+//        List<Integer> projectIds = reportList.stream().map(Report::getProjectId).collect(Collectors.toList());
+//        List<Project> projectList = projectMapper.selectList(new QueryWrapper<Project>().select("id, project_name").in("id", projectIds));
         //操作审核通过
         for (Report report : reportList) {
             ReportLog log = new ReportLog();
@@ -927,6 +954,9 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         }
         if (reportMapper.delete(queryWrapper) == 0) {
             httpRespMsg.setError("操作失败");
+        } else {
+            //删除日报的日志
+            reportLogMapper.delete(new QueryWrapper<ReportLog>().eq("creator_id", userId).eq("create_date", date));
         }
         return httpRespMsg;
     }
@@ -1009,6 +1039,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 map2.put("state", list2.get(0).get("state"));
                 map2.put("auditDeptName", list2.get(0).get("auditDeptName"));
                 map2.put("isDeptAudit", list2.get(0).get("isDeptAudit"));
+                map2.put("deptAuditorName", list2.get(0).get("deptAuditorName"));
                 //增加填报人所属部门
                 map2.put("departmentName", list2.get(0).get("departmentName"));
             }
@@ -1986,6 +2017,9 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         }
         if (cnt == 0) {
             msg.setError("只有待审核状态的报告才能撤回");
+        } else {
+            //记录撤销操作
+            saveCancelLog(reportIds, user);
         }
         return msg;
     }

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

@@ -243,13 +243,14 @@
         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,
         department.department_name as auditDeptName, a.is_dept_audit as isDeptAudit, a.project_audit_state as projectAuditState,task_group.name as groupName,a.group_id as groupId, a.custom_data as customData
-        ,u.name as projectAuditorName, a.project_auditor_id as projectAuditorId, a.overtime_hours as overtimeHours, a.custom_text as customText
+        ,u.name as projectAuditorName, a.project_auditor_id as projectAuditorId, a.overtime_hours as overtimeHours, a.custom_text as customText, dept_manager.name as deptAuditorName
         FROM report AS a
         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
         left join department on department.department_id = a.audit_deptid
+        left join user dept_manager on dept_manager.id = a.audit_dept_managerid
         left join task_group on task_group.id = a.group_id
         left join user u on u.id = a.project_auditor_id
         WHERE 1=1
@@ -272,7 +273,7 @@
         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,
         department.department_name as auditDeptName, a.is_dept_audit as isDeptAudit, a.project_audit_state as projectAuditState,task_group.name as groupName,a.group_id as groupId, a.custom_data as customData
-        ,u.name as projectAuditorName, a.project_auditor_id as projectAuditorId, a.overtime_hours as overtimeHours, a.custom_text as customText
+        ,u.name as projectAuditorName, a.project_auditor_id as projectAuditorId, a.overtime_hours as overtimeHours, a.custom_text as customText, dept_manager.name as deptAuditorName
         FROM report AS a
         left join user on user.id = a.creator_id
         JOIN project AS b ON a.project_id=b.id
@@ -280,6 +281,7 @@
         left join task on task.id = a.task_id
         left join report_extra_degree on report_extra_degree.id = a.degree_id
         left join department on department.department_id = a.audit_deptid
+        left join user dept_manager on dept_manager.id = a.audit_dept_managerid
         left join department dept on dept.department_id = a.dept_id
         left join task_group on task_group.id = a.group_id
         left join user u on u.id = a.project_auditor_id
@@ -349,13 +351,14 @@
         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,
         department.department_name as auditDeptName, a.is_dept_audit as isDeptAudit, a.project_audit_state as projectAuditState,task_group.name as groupName,a.group_id as groupId, a.custom_data as customData
-        ,u.name as projectAuditorName, a.project_auditor_id as projectAuditorId, a.overtime_hours as overtimeHours, a.custom_text as customText
+        ,u.name as projectAuditorName, a.project_auditor_id as projectAuditorId, a.overtime_hours as overtimeHours, a.custom_text as customText, dept_manager.name as deptAuditorName
         FROM report AS a
         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
         left join department on department.department_id = a.audit_deptid
+        left join user dept_manager on dept_manager.id = a.audit_dept_managerid
         left join task_group on task_group.id = a.group_id
         left join user u on u.id = a.project_auditor_id
         WHERE 1=1

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

@@ -17,11 +17,12 @@
         <result column="auth_username" property="authUsername" />
         <result column="company_id" property="companyId" />
         <result column="agentid" property="agentid" />
+        <result column="contact_secret" property="contactSecret" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        corpid, corp_name, corp_full_name, corp_scale, corp_industry, corp_sub_industry, location, access_token, expire_time, permanent_code, auth_username, company_id, agentid
+        corpid, corp_name, corp_full_name, corp_scale, corp_industry, corp_sub_industry, location, access_token, expire_time, permanent_code, auth_username, company_id, agentid, contact_secret
     </sql>
 
 </mapper>

+ 9 - 0
fhKeeper/formulahousekeeper/ops-platform/src/main/java/com/management/platform/entity/VcompanyCustomerContact.java

@@ -4,9 +4,12 @@ import com.baomidou.mybatisplus.extension.activerecord.Model;
 import java.time.LocalDateTime;
 import com.baomidou.mybatisplus.annotation.TableField;
 import java.io.Serializable;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
+import org.springframework.format.annotation.DateTimeFormat;
 
 /**
  * <p>
@@ -45,6 +48,8 @@ public class VcompanyCustomerContact extends Model<VcompanyCustomerContact> {
      * 会员到期时间
      */
     @TableField("expiration_date")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
     private LocalDateTime expirationDate;
 
     /**
@@ -78,12 +83,16 @@ public class VcompanyCustomerContact extends Model<VcompanyCustomerContact> {
     private String feedback;
 
     @TableField("indate")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
     private LocalDateTime indate;
 
     /**
      * 创建时间
      */
     @TableField("c_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
     private LocalDateTime cTime;
 
     @TableField("wx_corpid")

+ 10 - 10
fhKeeper/formulahousekeeper/timesheet/config/index.js

@@ -2,17 +2,17 @@ var path = require('path')
 
 //  var ip = '127.0.0.1'
 // var ip = '47.100.37.243'
-var ip = '192.168.2.7'
+// var ip = '192.168.2.7'
 
-// var os = require('os'), ip = '', ifaces = os.networkInterfaces() // 获取本机ip
-// for (var i in ifaces) {
-//     for (var j in ifaces[i]) {
-//         var val = ifaces[i][j]
-//         if (val.family === 'IPv4' && val.address !== '127.0.0.1') {
-//             ip = val.address
-//         }
-//     }
-// }
+var os = require('os'), ip = '', ifaces = os.networkInterfaces() // 获取本机ip
+for (var i in ifaces) {
+    for (var j in ifaces[i]) {
+        var val = ifaces[i][j]
+        if (val.family === 'IPv4' && val.address !== '127.0.0.1') {
+            ip = val.address
+        }
+    }
+}
 
 module.exports = {
   build: {

BIN
fhKeeper/formulahousekeeper/timesheet/src/assets/image/047_S.jpg


BIN
fhKeeper/formulahousekeeper/timesheet/src/assets/image/Step1.jpg


BIN
fhKeeper/formulahousekeeper/timesheet/src/assets/image/Step2.jpg


BIN
fhKeeper/formulahousekeeper/timesheet/src/assets/image/Step3.jpg


BIN
fhKeeper/formulahousekeeper/timesheet/src/assets/image/userHead.jpg


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

@@ -67,8 +67,8 @@
 
         <!-- 按部门/项目筛选 -->
         <el-select v-if="ins == 10" v-model="departmentOrProject" placeholder="请选择" size="small" @change="selcts(10)" style="margin-left:10px;width:120px">
-          <el-option label="按部门筛选" :value="0"></el-option>
-          <el-option label="按项目筛选" :value="1"></el-option>
+          <el-option label="查看项目审核人" :value="1"></el-option>
+          <el-option label="查看部门审核人" :value="0"></el-option>
         </el-select>
         <!-- 项目筛选 -->
         <el-select v-if="(ins != 4 && ins != 8 && ins != 9 && ins != 10) || (ins == 10 && departmentOrProject == 1)" v-model="proJuctId" placeholder="请选择项目" clearable filterable size="small" @change="selcts()" style="margin-left:10px">
@@ -651,7 +651,7 @@ export default {
       departmentList: [],
       departmentIdArray: [],
       selUserList: [],
-      departmentOrProject: 0
+      departmentOrProject: 1
 
     };
   },

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

@@ -2484,6 +2484,7 @@ a {
                                 type: "success"
                             });
                             this.getList();
+                            this.addFormVisible = false;
                         } else {
                             this.$message({
                                 message: res.msg,

+ 142 - 9
fhKeeper/formulahousekeeper/timesheet/src/views/team/index.vue

@@ -1,6 +1,6 @@
 <template>
     <section>
-        <el-col :span="4" class="left" :style="'height:'+ (tableHeight + 113) + 'px'">
+        <el-col :span="4" class="left" :style="'height:'+ (tableHeight + 113) + 'px;'">
             <div class="department">
                 <span><i class="iconfont firerock-iconzuzhijiegou" style="font-size:10px;" ></i>&nbsp;部门</span>
                 <div v-on:click="createDepartment(-1)">
@@ -13,14 +13,16 @@
                 <!-- <el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick" accordion></el-tree> -->
                 <el-tree :data="data" :props="defaultProps" node-key="id" :expand-on-click-node="false" accordion @node-click="handleNodeClick" :default-expanded-keys="jDarr" @node-expand="jieDian" @node-collapse="shutDown" @current-change="chufa">
                     <span class="custom-tree-node" slot-scope="{ node }" @mouseleave= mouseleave(data,$event) @mouseover= mouseover(data,$event)>
-                        <span style="width: 100%;line-height: 36px; display: inline-block;">{{ node.label }}</span>
+
+                        <span style="width: 130px;overflow:hidden;text-overflow:ellipsis;line-height: 36px; display: inline-block;">{{ node.label }}</span>
+
                         <span v-if="node.label != '全部人员'" class="node none">
-                        <el-button type="text" size="mini" @click="createDepartment(-2)" >
-                            <i class="el-icon-circle-plus-outline"></i> <!-- 新增 -->
-                        </el-button>
-                        <el-button type="text" size="mini" @click="deleteDep(null)">
-                            <i class="el-icon-delete"></i> <!-- 删除 -->
-                        </el-button>
+                            <el-button type="text" size="mini" @click="createDepartment(-2)" >
+                                <i class="el-icon-circle-plus-outline"></i> <!-- 新增 -->
+                            </el-button>
+                            <el-button type="text" size="mini" @click="deleteDep(null)">
+                                <i class="el-icon-delete"></i> <!-- 删除 -->
+                            </el-button>
                         </span>
                     </span> 
                 </el-tree>
@@ -62,7 +64,10 @@
                     </el-form-item>
                     
                     <el-form-item style="float:right;" v-if="user.dingdingUserid == null && permissions.structureImport">
-                            <el-link type="primary" :underline="false" @click="importUserC">批量导入</el-link>
+                        <el-link type="primary" :underline="false" @click="importUserC">批量导入</el-link>
+                    </el-form-item>
+                    <el-form-item style="float:right;" v-if="user.corpwxUserid != null && permissions.structureImport">
+                        <el-link type="primary" :underline="false" @click="syncWithCorpWx">同步企微通讯录</el-link>
                     </el-form-item>
 
                     <!-- <el-form-item style="float:right;" v-if="user.dingdingUserid == null && permissions.structureImport">
@@ -531,6 +536,24 @@
             </el-upload>
             </p>
         </el-dialog>
+        <el-dialog title="同步企业微信通讯录" v-if="showSyncCWDialog" :visible.sync="showSyncCWDialog" customClass="customWidth" width="500px">
+            <p>填写企业微信通讯录Secret 
+                <el-popover placement="top" width="1200" trigger="hover">
+                    <div class="imgFlex">
+                        <div><img src="../../assets/image/Step1.jpg" style="width: 380px"/> <p><b>第一步:进入管理后台</b></p> </div>
+                        <div class="imgBor"> <p></p> <img src="../../assets/image/Step2.jpg" style="width: 380px"/> <p><b>第二步:进入通讯录同步</b></p></div>
+                        <div><img src="../../assets/image/Step3.jpg" style="width: 380px"/> <p><b>第三步:查看Secret</b></p></div>
+                    </div>
+                    <i class="el-icon-question" slot="reference" />
+                </el-popover>
+            </p>
+            <p>
+            <el-input v-model="contactSecret" style="width:380px;"/><el-button @click="saveContactSecret" >保存</el-button>
+            </p>
+            <p style="display: flex;justify-content: center;padding-bottom:1em;">
+                <el-button type="primary" :underline="false" :loading="importingData" :disabled="!canSync" @click="startCorpWxImport">开始同步</el-button>
+            </p>
+        </el-dialog>
     </section>
 </template>
 
@@ -540,6 +563,10 @@
     export default {
         data() {
             return {
+                canSync: false,
+                corpid:null,
+                contactSecret:null,
+                showSyncCWDialog: false,
                 permissions: JSON.parse(sessionStorage.getItem("permissions")),
                 handleSelectionZzjgshow: false,
                 handljues: false,
@@ -719,6 +746,93 @@
             that = this;
         },
         methods: {
+            saveContactSecret() {
+                if (!this.contactSecret) {
+                    this.$message({
+                            message: '请输入通讯录secret',
+                            type: 'error'
+                        })
+                    return;
+                }
+                this.http.post('/wx-corp-info/saveContactSecret',{
+                    corpid: this.corpid,
+                    contactSecret:this.contactSecret
+                },res => {
+                    if(res.code == 'ok'){
+                        this.$message({
+                            message: '保存成功',
+                            type: 'success'
+                        })
+                        this.canSync = true;
+                    }else {
+                        this.$message({
+                            message: res.msg,
+                            type: 'error'
+                        })
+                    }
+                },err => {
+                    this.tableLoading = false
+                    this.$message({
+                        message: err,
+                        type: 'error'
+                    })
+                })
+            },
+            startCorpWxImport() {
+                this.importingData = true;
+                this.http.post('/wxcorp/getCorpMembs',{
+                    corpId: this.corpid
+                },res => {
+                    this.importingData = false;
+                    if(res.code == 'ok'){
+                        this.showSyncCWDialog = false;
+                        this.$message({
+                                message: '同步完成',
+                                type: "success"
+                            });
+                        this.getDepartment();
+                        this.getUser();
+                        this.getUsers();
+                    }else {
+                        this.$message({
+                            message: res.msg,
+                            type: 'error'
+                        })
+                    }
+                },err => {
+                    this.tableLoading = false
+                    this.$message({
+                        message: err,
+                        type: 'error'
+                    })
+                })
+            },
+            //从企业微信同步通讯录
+            syncWithCorpWx() {
+                this.showSyncCWDialog = true;
+                this.http.post('/wx-corp-info/get',{
+                    companyId: this.user.companyId
+                },res => {
+                    if(res.code == 'ok'){
+                        this.contactSecret = res.data.contactSecret;
+                        if (this.contactSecret) {
+                            this.canSync = true;
+                        }
+                        this.corpid = res.data.corpid;
+                    }else {
+                        this.$message({
+                            message: res.msg,
+                            type: 'error'
+                        })
+                    }
+                },err => {
+                    this.tableLoading = false
+                    this.$message({
+                        message: err,
+                        type: 'error'
+                    })
+                })
+            },
             test(){
                 this.getCustomConfigList()
             },
@@ -2390,6 +2504,25 @@
 </script>
 
 <style lang="scss" scoped>
+.imgFlex {
+    display: flex;
+    align-items: center;
+}
+.imgFlex p {
+    width: 100%;
+    text-align: center;
+}
+.imgFlex div {
+    padding: 10px;
+    display: flex;
+    align-content: space-between;
+    flex-wrap: wrap;
+    height: 600px;
+}
+.imgBor {
+    border-right: 1px solid #666;
+    border-left: 1px solid #666;
+}
     .custom-tree-node {
         flex: 1;
         display: flex;

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

@@ -115,7 +115,7 @@
                                     <!-- <span :style="parseFloat(item1.reportTime)>parseFloat(item1.calculateTime)+0.5?'color:red':''">{{item1.reportTime}}h</span> -->
                                     <span >{{item1.reportTime}}</span>h
                                 </span>
-                                <span class="approvalProcessBox">
+                                <span class="approvalProcessBox" v-if="user.timeType.showFillauditTime == 1">
                                     <i class="iconfont firerock-iconliucheng1"></i>
                                     <span class="approvalProcessClick" @click="getApprovalProcess(item1)">审批流程</span>
                                 </span>

+ 2 - 2
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/list.vue

@@ -72,7 +72,7 @@
                                                     </span>
                                                 </span>
                                                 <span v-else-if="item.isDeptAudit==1">
-                                                    {{('待'+item.auditDeptName+'审核')}}
+                                                    {{('待'+item.auditDeptName+('('+item.deptAuditorName+')')+'审核')}}
                                                 </span>
                                                  ]
                                 </span>
@@ -148,7 +148,7 @@
             </el-table-column>
             <el-table-column prop="state" label="状态" sortable>
                 <template slot-scope="scope">
-                    <span v-if="scope.row.state == 0" style="color:#DAA520;">{{scope.row.isDeptAudit==0?'待项目审核人审核':('待'+scope.row.auditDeptName+'审核')}}</span>
+                    <span v-if="scope.row.state == 0" style="color:#DAA520;">{{scope.row.isDeptAudit==0?'待项目审核人审核':('待'+scope.row.auditDeptName+('('+scope.row.deptAuditorName+')')+'审核')}}</span>
                     <span v-else-if="scope.row.state == 1" style="color:#32CD32;">已通过</span>
                     <span v-else-if="scope.row.state == 2" style="color:#FF0000;">已驳回</span>
                 </template>