Browse Source

组织架构更改显示

Lijy 2 năm trước cách đây
mục cha
commit
bb3c9714d0
24 tập tin đã thay đổi với 563 bổ sung117 xóa
  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. 12 0
      fhKeeper/formulahousekeeper/timesheet/src/permissions.js
  17. 11 5
      fhKeeper/formulahousekeeper/timesheet/src/views/corpreport/list.vue
  18. 102 49
      fhKeeper/formulahousekeeper/timesheet/src/views/project/cost.vue
  19. 1 0
      fhKeeper/formulahousekeeper/timesheet/src/views/project/list.vue
  20. 7 0
      fhKeeper/formulahousekeeper/timesheet/src/views/settings/timetype.vue
  21. 132 1
      fhKeeper/formulahousekeeper/timesheet/src/views/team/index.vue
  22. 2 2
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue
  23. 2 2
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/list.vue
  24. 39 2
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/index.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


+ 12 - 0
fhKeeper/formulahousekeeper/timesheet/src/permissions.js

@@ -51,6 +51,7 @@ const StringUtil = {
         reportPhaseCost: false, // 查看阶段成本 //
         reportTimeDivide: false, // 人员工时分配表 //
         reportTimely: false, // 查看人员填报及时率 //
+        reportAuditRate: false, // 查看日报待审核统计 // 
 
         // 请假模块
         leaveFil : false, // 请假填报 // 
@@ -72,6 +73,12 @@ const StringUtil = {
         costAudit : false, // 费用审核 //
         costAll : false, // 查看全部报销单 //
 
+        // 工时成本统计
+        countAllWorkTime: false, // 查看全公司工时统计 //
+        countAllCost: false, // 查看全公司成本统计 //
+        countResWorkTime: false, // 查看负责部门工时统计 //
+        countResCost: false, // 查看负责部门成本统计 //
+
         // 项目报告审核
         projectReportReview: false, // 审核全员日报 //
 
@@ -137,6 +144,11 @@ const StringUtil = {
         arr[i] == '查看人员工时分配' ? obj.reportTimeDivide = true : ''
         arr[i] == '自定义配置' ? obj.structureCustomConfig = true : ''
         arr[i] == '查看人员填报及时率' ? obj.reportTimely = true : ''
+        arr[i] == '查看日报待审核统计' ? obj.reportAuditRate = true : ''
+        arr[i] == '查看全公司工时统计' ? obj.countAllWorkTime = true : ''
+        arr[i] == '查看负责部门工时统计' ? obj.countResWorkTime = true : ''
+        arr[i] == '查看全公司成本统计' ? obj.countAllCost = true : ''
+        arr[i] == '查看负责部门成本统计' ? obj.countResCost = true : ''
     }
 
     return obj

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

@@ -28,7 +28,7 @@
                 <el-menu-item index="1-8" v-if="permissions.reportOvertime"><p @click="ssl(6)">加班情况统计表</p></el-menu-item>
 
                 <el-menu-item index="1-10" v-if="permissions.reportTimely"><p @click="ssl(9)">员工填报及时率</p></el-menu-item>
-                <el-menu-item index="1-11" v-if="permissions.reportTimely"><p @click="ssl(10)">日报待审核统计</p></el-menu-item>
+                <el-menu-item index="1-11" v-if="permissions.reportAuditRate"><p @click="ssl(10)">日报待审核统计</p></el-menu-item>
               </el-submenu>
             </el-menu>
         </el-col>
@@ -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">
@@ -79,7 +79,7 @@
         </el-select>
           
           <!-- 部门筛选 -->
-          <el-cascader v-if="ins == 9 || (ins == 10 && departmentOrProject == 0)" v-model="departmentIdArray" :options="departmentList" placeholder="请选择部门"
+          <el-cascader v-if="ins == 9 || ins == 8 || ins == 6 || (ins == 10 && departmentOrProject == 0)" v-model="departmentIdArray" :options="departmentList" placeholder="请选择部门"
             :props="{ checkStrictly: false,expandTrigger: 'hover' }" :show-all-levels="false" clearable
             @change="selcts(9)" size="small" style="margin-left:10px"
           ></el-cascader>
@@ -651,7 +651,7 @@ export default {
       departmentList: [],
       departmentIdArray: [],
       selUserList: [],
-      departmentOrProject: 0
+      departmentOrProject: 1
 
     };
   },
@@ -1064,6 +1064,9 @@ export default {
       } else {
         obj.userId = this.userId
       }
+      if(this.departmentIdArray.length != 0){
+        obj.departmentId = this.departmentIdArray[this.departmentIdArray.length - 1]
+      }
       this.http.post('/project/getOvertimeList', obj,
         res => {
             if (res.code == "ok") {
@@ -1220,6 +1223,9 @@ export default {
       if(this.userId){
         parameter.userId = this.userId
       }
+      if(this.departmentIdArray.length != 0){
+        parameter.departmentId = this.departmentIdArray[this.departmentIdArray.length - 1]
+      }
       this.listLoading = true
       this.http.post('/project/getUserWorkingTimeList',parameter,
       res => {

+ 102 - 49
fhKeeper/formulahousekeeper/timesheet/src/views/project/cost.vue

@@ -4,8 +4,8 @@
         <el-col :span="6" >
             <div ><span style="color:#999;">图表Y轴: </span>
             <el-radio-group v-model="yAxisValue" @change="onYAxisChange">
-            <el-radio-button label="0">显示成本</el-radio-button>
-            <el-radio-button label="1">显示工时</el-radio-button>
+            <el-radio-button label="0" v-if="permissions.countAllCost || permissions.countResCost">显示成本</el-radio-button>
+            <el-radio-button label="1" v-if="permissions.countAllWorkTime || permissions.countResWorkTime">显示工时</el-radio-button>
             </el-radio-group></div>
         </el-col>
         <el-col :span="14" style="display: flex;flex-wrap: wrap;">
@@ -149,6 +149,7 @@
                 exportDialog:false,
                 dateRange:[],
                 user: JSON.parse(sessionStorage.getItem("user")),
+                permissions: JSON.parse(sessionStorage.getItem("permissions")),
                 radio: sessionStorage.radio!=null?sessionStorage.radio:'项目',
                 containerHeight: 0,    
                 myChart: null,
@@ -548,12 +549,18 @@
                             if(project.length != 0) {
                                 for(var k in project) {
                                     if(project[k].project == array[i]) {
-                                        dataList.push({
+                                        let item = {
                                             "value": this.yAxisValue==0?project[k].money:project[k].time,
-                                            "cost": project[k].time,
-                                             "money":project[k].money
-                                        })
-                                        totalHours += parseFloat(project[k].time);
+                                        }
+                                        if(this.permissions.countAllCost || this.permissions.countResCost){
+                                            item.money = project[k].money
+                                        }
+                                        if(this.permissions.countAllWorkTime || this.permissions.countResWorkTime){
+                                            item.cost = project[k].time
+                                            totalHours += parseFloat(project[k].time);
+                                        }
+                                        dataList.push(item)
+                                        
                                     } else {
                                         num++;
                                     }
@@ -595,7 +602,10 @@
                     var option = {
                         //总成本
                         title: {
-                            text: '工时成本总计' + totalMoneyCost.toFixed(2) + '元, 时长'+totalHours+'小时',
+                            // text: '工时成本总计' + totalMoneyCost.toFixed(2) + '元, 时长'+totalHours+'小时',
+                            text: '工时成本总计:' + 
+                            ((this.permissions.countAllCost || this.permissions.countResCost) ? '成本' + totalMoneyCost.toFixed(2) + '元,' : '') + 
+                            ((this.permissions.countAllWorkTime || this.permissions.countResWorkTime) ? '时长' + totalHours + '小时' : ''),
                             left:'left',
                         },
                         // 工具箱
@@ -642,13 +652,17 @@
                                 for(var i in params) {
                                     if (params[i].data.value > 0) {
                                         res += "<div style='margin-top:3px;font-size:12px;'><font color='#ddd'>项目名称:" + params[i].seriesName 
-                                            + "</font><br/>工作成本 : " + params[i].data.money
-                                            + "元 <br/>工作时长"+" : " + params[i].data.cost + "小时</br></div>";
+                                            + "</font><br/>" + 
+                                            ((_this.permissions.countAllCost || _this.permissions.countResCost) ? "工作成本 : " + params[i].data.money + "元<br/>" : '') + 
+                                            ((_this.permissions.countAllWorkTime || _this.permissions.countResWorkTime) ? "工作时长 : " + params[i].data.cost + "小时</br>" : '') + "</div>";
                                         totalTime += Number(params[i].data.cost);
                                         totalCost += Number(params[i].data.money);
                                     }
                                 }
-                                res = res +'<br/>'+ params[0].name+ '<br/>总计: ' + totalTime.toFixed(1)+'小时 '+totalCost.toFixed(2) + "元<br/>";
+                                res = res +'<br/>'+ params[0].name+ '<br/>总计: ' + 
+                                ((_this.permissions.countAllWorkTime || _this.permissions.countResWorkTime) ? totalTime.toFixed(1) + '小时 ' : '') + 
+                                ((_this.permissions.countAllCost || _this.permissions.countResCost) ? totalCost.toFixed(2) + "元" : '') + 
+                                "<br/>";
                                 return res;
                             }
                         },
@@ -679,9 +693,9 @@
                     that.jieliu()
                 // },100);
                 // this.jieliu()
-                if(this.radio == '项目分类'){
-                    this.getCategoryList()
-                }
+                // if(this.radio == '项目分类'){
+                //     this.getCategoryList()
+                // }
             },
             getCategoryList(){
                 this.http.post('/project-category/list',{},
@@ -722,13 +736,14 @@
                 if (this.dateRange != null) {
                     param = {startDate:this.user.timeType.fixMonthcost==0?this.dateRange[0]:this.dateRange, 
                     endDate: this.user.timeType.fixMonthcost==0?this.dateRange[1]:this.dateRange};
-                    console.log(param);
+                    // console.log(param);
                 }
                 var url = '';
                 if (this.radio=='项目') {
                     url = this.port.project.listCost;
                 } else if (this.radio=='项目分类') {
                     url = '/project/getTimeCostByCategory';
+                    
                     // param.parentDeptId = this.parentDeptId;
                     // param.userId = this.user.id
                 } else if (this.radio=='部门') {
@@ -760,56 +775,81 @@
                         var totalHours = 0.0;
                         if(this.radio == '项目' || this.radio == '项目分类' || this.radio=='部门') {
                             list = res.data.costList
-                            totalMoneyCost = ((this.radio=='项目')?res.data.totalMoneyCost:res.data.totalCostMoney);
+                            totalMoneyCost = ((this.radio=='项目' || this.radio == '项目分类')?res.data.totalMoneyCost:res.data.totalCostMoney);
+
                             for(var i in list) {
                                 if(this.radio=='项目') {
                                     xList.push(list[i].project);
-                                    yList.push({
+                                    let item = {
                                         "value": this.yAxisValue==0?list[i].costMoney.toFixed(2) || list[i].costMoney:list[i].cost.toFixed(1),
                                         "id": list[i].id || i,
-                                        "cost": list[i].cost,
-                                        "money":list[i].costMoney.toFixed(2)
-                                    });
-                                    totalHours += parseFloat(list[i].cost);
+                                    }
+                                    if(this.permissions.countAllCost || this.permissions.countResCost){
+                                        item.money = list[i].costMoney.toFixed(2)
+                                    }
+                                    if(this.permissions.countAllWorkTime || this.permissions.countResWorkTime){
+                                        item.cost = list[i].cost
+                                        totalHours += parseFloat(list[i].cost);
+                                    }
+                                    yList.push(item);
+                                    
                                 } else if(this.radio == '部门'){
                                     xList.push(list[i].departmentName);
-                                    yList.push({
-                                        "value": this.yAxisValue==0? list[i].costMoney.toFixed(2) || list[i].costMoney: list[i].costTime.toFixed(1),
+                                    let item = {
+                                        "value": this.yAxisValue==0 ? list[i].costMoney.toFixed(2) || list[i].costMoney: list[i].costTime.toFixed(1),
                                         "id": list[i].departmentId,
-                                        "cost": list[i].costTime,
-                                        "hasSubDept": list[i].hasSubDept,
-                                        "money":list[i].costMoney.toFixed(2)
-                                    });
-                                    totalHours += parseFloat(list[i].costTime);
+                                        "hasSubDept": list[i].hasSubDept
+                                    }
+                                    if(this.permissions.countAllCost || this.permissions.countResCost){
+                                        item.money = list[i].costMoney.toFixed(2)
+                                    }
+                                    if(this.permissions.countAllWorkTime || this.permissions.countResWorkTime){
+                                        item.cost = list[i].costTime
+                                        totalHours += parseFloat(list[i].costTime);
+                                    }
+                                    yList.push(item);
+                                    
                                 }else {
                                     xList.push(list[i].categoryName);
-                                    yList.push({
+                                    let item = {
                                         "value": this.yAxisValue==0?list[i].costMoney.toFixed(2) || list[i].costMoney:list[i].cost.toFixed(1),
                                         "id": list[i].id || i,
-                                        "cost": list[i].cost,
-                                        "money":list[i].costMoney.toFixed(2)
-                                    });
-                                    totalHours += parseFloat(list[i].cost);
+                                    }
+                                    if(this.permissions.countAllCost || this.permissions.countResCost){
+                                        item.money = list[i].costMoney.toFixed(2)
+                                    }
+                                    if(this.permissions.countAllWorkTime || this.permissions.countResWorkTime){
+                                        item.cost = list[i].cost
+                                        totalHours += parseFloat(list[i].cost);
+                                    }
+                                    yList.push(item);
                                 }
                             }
                         } else {
                             list = res.data
-                            var totalMoneyCost = 0;
+                            
                             for(var i in list) {
-                                console.log(list[i].name, list[i].costMoney, list[i].cost)
+                                // console.log(list[i].name, list[i].costMoney, list[i].cost)
                                 xList.push(list[i].name);
-                                yList.push({
+                                let item = {
                                     "value": this.yAxisValue==0?list[i].costMoney:list[i].cost,
                                     "id": list[i].id || i,
-                                    "cost": list[i].cost,
-                                    "money":list[i].costMoney.toFixed(2)
-                                });
-                                totalHours += parseFloat(list[i].cost);
-                                totalMoneyCost += parseFloat(list[i].costMoney);
+                                }
+                                if(this.permissions.countAllCost || this.permissions.countResCost){
+                                    item.money = list[i].costMoney.toFixed(2)
+                                    totalMoneyCost += parseFloat(list[i].costMoney);
+                                }
+                                if(this.permissions.countAllWorkTime || this.permissions.countResWorkTime){
+                                    item.cost = list[i].cost
+                                    totalHours += parseFloat(list[i].cost);
+                                }
+                                yList.push(item);
+                                
                             }
                         }
                         totalHours = totalHours.toFixed(1);
                         
+                        
                         var myChart = echarts.init(document.getElementById("container"));
                         myChart.resize({
                             width: this.widthHtval
@@ -820,10 +860,11 @@
                         if(totalMoneyCost) {
                             this.zhishin = totalMoneyCost.toFixed(2)
                         } 
-                        if(this.radio == '项目' || this.radio == '人员' || this.radio=='部门') {
+
+                        if(this.radio == '项目' || this.radio == '人员' || this.radio == '项目分类' || this.radio=='部门') {
                             var option = {
                                 title: {
-                                    text: '工时成本总计' + this.zhishin + '元, 时长'+totalHours+'小时',
+                                    text: '工时成本总计:' + ((this.permissions.countAllCost || this.permissions.countResCost) ? '成本' + this.zhishin + '元,' : '') + ((this.permissions.countAllWorkTime || this.permissions.countResWorkTime) ? '时长' + totalHours + '小时' : ''),
                                     left:'left',
                                 },
                                 // 工具箱
@@ -836,9 +877,13 @@
                                 tooltip:{
                                     trigger:'axis',
                                     formatter: function (params,ticket,callback) {
-                                        var res = params[0].name + "<br/>工作成本"+" : " + params[0].data.money 
-                                        + "元 <br/>工作时长"+" : " + params[0].data.cost + "小时";
-                                        _this.params = params;
+                                        // var res = params[0].name + "<br/>工作成本"+" : " + params[0].data.money 
+                                        // + "元 <br/>工作时长"+" : " + params[0].data.cost + "小时";
+                                        // _this.params = params;
+                                        var res = params[0].name + "<br/>" + 
+                                        ((_this.permissions.countAllCost || _this.permissions.countResCost) ? "工作成本"+" : " + params[0].data.money 
+                                        + "元 <br/>" : '') + 
+                                        ((_this.permissions.countAllWorkTime || _this.permissions.countResWorkTime) ? "工作时长"+" : " + params[0].data.cost + "小时" : '');
                                         return res;
                                     }
                                 },
@@ -864,7 +909,8 @@
                         } else {
                             var option = {
                                 title: {
-                                    text: '工时成本总计' + this.zhishin + '元, 时长'+totalHours+'小时',
+                                    // text: '工时成本总计' + this.zhishin + '元, 时长'+totalHours+'小时',
+                                    text: '工时成本总计:' + ((this.permissions.countAllCost || this.permissions.countResCost) ? '成本' + this.zhishin + '元,' : '') + ((this.permissions.countAllWorkTime || this.permissions.countResWorkTime) ? '时长' + totalHours + '小时' : ''),
                                     left:'left',
                                 },
                                 // 工具箱
@@ -877,8 +923,10 @@
                                 tooltip:{
                                     trigger:'axis',
                                     formatter: function (params,ticket,callback) {
-                                        var res = params[0].name + "<br/>工作成本"+" : " + params[0].data.money 
-                                        + "元 <br/>工作时长"+" : " + params[0].data.cost + "小时";
+                                        var res = params[0].name + "<br/>" + 
+                                        ((_this.permissions.countAllCost || _this.permissions.countResCost) ? "工作成本"+" : " + params[0].data.money 
+                                        + "元 <br/>" : '') + 
+                                        ((_this.permissions.countAllWorkTime || _this.permissions.countResWorkTime) ? "工作时长"+" : " + params[0].data.cost + "小时" : '');
                                         _this.params = params;
                                         return res;
                                     }
@@ -985,6 +1033,11 @@
                 this.containerHeight = window.innerHeight - 130
                 // this.containerHeight = window.innerHeight - 200
             };
+            if(this.permissions.countAllCost || this.permissions.countResCost){
+                this.yAxisValue = '0'
+            }else{
+                this.yAxisValue = '1'
+            }
             if (this.user.timeType.fixMonthcost == 0) {
                 if (this.$route.query.startDate != null) {
                     this.dateRange = [this.$route.query.startDate, this.$route.query.endDate];

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

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

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

@@ -217,6 +217,13 @@
                     <span style="color:#666;margin-left:10px;">(说明:系统管理员为员工代填日报时不受补填时间的限制)</span>
                     <span class="lockworktime"><el-checkbox v-model="timeType.fillAhead" label="可提前填报" /></span>
                 </el-form-item>
+                <el-form-item label="员工填报及时日" prop="timeliness">
+                    <el-select v-model="timeType.timeliness">
+                        <el-option label="当天" :value="0"></el-option>
+                        <el-option label="第二天" :value="1"></el-option>
+                        <el-option label="第三天" :value="2"></el-option>
+                    </el-select>
+                </el-form-item>
                 </el-form>
             </div>
         </el-col>

+ 132 - 1
fhKeeper/formulahousekeeper/timesheet/src/views/team/index.vue

@@ -64,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">
@@ -533,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>
 
@@ -542,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,
@@ -721,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()
             },
@@ -2392,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;

+ 2 - 2
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>
@@ -1321,7 +1321,7 @@
                 fillMembList:[],
                 membListVisible: false,
                 isBatch:0,//是否是批量填报
-                editTitle: ['填写日报','批量填报','批量代填'],
+                editTitle: ['填写日报','批量填报','代填日报'],
                 weekDay : ["周日", "周一", "周二", "周三", "周四", "周五", "周六"],
                 statusStyle:["waiting", "filledReportStyle", "RejectStyle", "waitSubmitStyle"],
                 fillStatusList: [],

+ 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>

+ 39 - 2
fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/index.vue

@@ -66,6 +66,14 @@
                         <van-picker show-toolbar :columns="item.stages" value-key="stagesName" @confirm="choseStage" 
                             @cancel="item.showPickerStage = false;$forceUpdate();" />
                     </van-popup>
+                    <!-- 预算来源 -->
+                    <van-field  readonly  name="basecostId" v-if="user.company.packageProject==1&&reportBasecostList &&reportBasecostList.length>0" 
+                        :value="item.basecostName" label="预算来源" placeholder="请选择预算来源" 
+                    @click="clickPickCostId(index, item)" />
+                    <van-popup v-model="item.showPickerCostId" position="bottom">
+                        <van-picker show-toolbar :columns="reportBasecostList" value-key="name" @confirm="choseCostId" 
+                            @cancel="item.showPickerCostId = false;$forceUpdate();" />
+                    </van-popup>
                     <!-- 审核人 -->
                     <van-field  readonly  name="projectAuditorId" v-if="item.auditUserList != null && item.auditUserList.length > 0" clickable
                         :value="item.projectAuditorName" :label="user.companyId==781?'审核人':'项目审核人'" placeholder="请选择审核人" 
@@ -324,6 +332,7 @@
                 showPickerStage: false,
                 showPickerTaskGroup: false,
                 showPickerSubProject: false,
+                showPickerCostId: false,
                 isDraft:0,
                 showWorkStartTime:false,
                 showWorkEndTime:false,
@@ -389,7 +398,8 @@
                 projectss: [],
                 proads: [],
                 userName: '',
-                flgLg: true
+                flgLg: true,
+                reportBasecostList: []
             };
         },
 
@@ -398,6 +408,18 @@
         },
 
         methods: {
+            // 获取预算来源
+            getReportBasecostList(){
+                this.$axios.post('/project-basecost-setting/getReportBasecostList',{
+                    companyId: this.user.companyId
+                }).then(res => {
+                    if(res.code == 'ok'){
+                        this.reportBasecostList = res.data
+                    }else{
+                        this.$toast.fail('获取失败:'+res.msg);
+                    }
+                }).catch(err => {this.$toast.clear();})
+            },
             //获取项目审核人
             getProjectAuditorList(domainItem) {
                 this.$axios.post("/project-auditor/getList", {projectId: domainItem.projectId})
@@ -997,6 +1019,12 @@
                 item.showPickerSubProject = true;
                 this.$forceUpdate();
             },
+            clickPickCostId(i, item) {
+                if (!this.canEdit) return;
+                this.clickIndex = i;
+                item.showPickerCostId = true;
+                this.$forceUpdate();
+            },
             clickPickTaskGroup(i, item) {
                 if (!this.canEdit) return;
                 this.clickIndex = i;
@@ -1105,6 +1133,12 @@
                 this.$forceUpdate();
 
             },
+            choseCostId(value,index){
+                this.form.domains[this.clickIndex].basecostId = value.id;
+                this.form.domains[this.clickIndex].basecostName = value.name;
+                this.form.domains[this.clickIndex].showPickerCostId = false;
+                this.$forceUpdate();
+            },
 
             getGroupStages(domain, index) {
                 this.$axios.post("/stages/getProjectStagesByGroup", {groupId: domain.groupId})
@@ -1561,15 +1595,18 @@
                 this.isWX = true;
             }
             this.getPeoject() // 获取项目
+            console.log('mounted');
+            this.getReportBasecostList()
             //获取传递过来的日期
             var passDate = this.$route.query.date;
             if (passDate != null) {
                 this.form.createDate = this.$route.query.date;
             }
             
-            this.getProject();
+            // this.getProject();
             this.getReport();
             this.getTimeType();
+            
             //初始化微信js-sdk参数
             if (this.isCorpWX) {
                 this.initWxConfig();