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

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

Lijy 2 éve
szülő
commit
79e786a5cd

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

@@ -547,12 +547,12 @@ public class ProjectController {
         return projectService.getDegreeCost(startDate, endDate, projectId, request);
     }
 
-    @RequestMapping("exportData")
+    @RequestMapping("/exportData")
     public HttpRespMsg exportData() {
         return projectService.exportData(request);
     }
 
-    @RequestMapping("exportGroupData")
+    @RequestMapping("/exportGroupData")
     public HttpRespMsg exportGroupData() {
         return projectService.exportGroupData(request);
     }

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

@@ -327,6 +327,10 @@ public class WeiXinCorpController {
             org.json.JSONObject jsonObject = XML.toJSONObject(sMsg);
             log.info("json=="+jsonObject.toString());
             jsonObject = jsonObject.getJSONObject("xml");
+            if(jsonObject.has("Event") && ("open_approval_change".equals(jsonObject.getString("Event")))){
+                //审批状态回调通知
+                System.out.println("审批状态回调通知!");
+            }
             if (jsonObject.has("AuthCode")) {
                 //企业授权通知
                 String authCode = jsonObject.getString("AuthCode");

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

@@ -2,10 +2,12 @@ package com.management.platform.service;
 
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.management.platform.entity.LeaveSheet;
 import com.management.platform.entity.WxCorpInfo;
 import com.management.platform.util.HttpRespMsg;
 
 import java.time.LocalDateTime;
+import java.util.List;
 
 /**
  * <p>
@@ -28,4 +30,6 @@ public interface WxCorpInfoService extends IService<WxCorpInfo> {
     public HttpRespMsg getUserCheckInDayData(int companyId, String userId, LocalDateTime startDateTime, LocalDateTime endDateTime, boolean showLog);
 
     HttpRespMsg syncMembByCardTime(WxCorpInfo wxCorpInfo);
+
+    public List<LeaveSheet> WxLeaveNumber(String startTime,String endTime,List<WxCorpInfo> wxCorpInfos) throws Exception;
 }

+ 273 - 84
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/WxCorpInfoServiceImpl.java

@@ -25,9 +25,13 @@ import org.springframework.web.client.RestTemplate;
 import javax.annotation.Resource;
 import java.io.File;
 import java.io.FileOutputStream;
+import java.lang.reflect.Array;
+import java.text.SimpleDateFormat;
 import java.time.*;
 import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -78,27 +82,27 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
     public void sendWXCorpMsg(WxCorpInfo corpInfo, String corpUserid, String msg) {
         try {
             if (isDev) return;
-            log.info("发送企业微信消息==="+corpUserid);
-            System.out.println("发送企业微信消息==="+corpUserid);
+            log.info("发送企业微信消息===" + corpUserid);
+            System.out.println("发送企业微信消息===" + corpUserid);
             String accessToken = getCorpAccessToken(corpInfo);
             String url = URL_SEND_WXCORP_MSG.replaceAll("ACCESS_TOKEN", accessToken);
             HttpHeaders headers = new HttpHeaders();
             headers.setContentType(MediaType.APPLICATION_JSON);
             JSONObject reqParam = new JSONObject();
-            reqParam.put("touser",  corpUserid);
-            reqParam.put("msgtype",  "text");
-            reqParam.put("agentid",  corpInfo.getAgentid());
+            reqParam.put("touser", corpUserid);
+            reqParam.put("msgtype", "text");
+            reqParam.put("agentid", corpInfo.getAgentid());
             JSONObject contentJson = new JSONObject();
             contentJson.put("content", msg);
-            reqParam.put("text",  contentJson);
+            reqParam.put("text", contentJson);
 
             HttpEntity<String> requestEntity = new HttpEntity<String>(reqParam.toJSONString(), headers);
             ResponseEntity<String> responseEntity = this.restTemplate.exchange(url,
                     HttpMethod.POST, requestEntity, String.class);
             if (responseEntity.getStatusCode() == HttpStatus.OK) {
                 String resp = responseEntity.getBody();
-                log.info("发送企业微信消息返回结果=="+resp);
-                System.out.println("发送企业微信消息返回结果=="+resp);
+                log.info("发送企业微信消息返回结果==" + resp);
+                System.out.println("发送企业微信消息返回结果==" + resp);
                 JSONObject json = JSONObject.parseObject(resp);
                 if (json.getIntValue("errcode") == 0) {
                     //发送成功
@@ -107,8 +111,8 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                     throw new Exception(json.toJSONString());
                 }
             } else {
-                log.error("发送失败:"+responseEntity.getStatusCode()+", "+responseEntity.getBody());
-                System.err.println("发送失败:"+responseEntity.getStatusCode()+", "+responseEntity.getBody());
+                log.error("发送失败:" + responseEntity.getStatusCode() + ", " + responseEntity.getBody());
+                System.err.println("发送失败:" + responseEntity.getStatusCode() + ", " + responseEntity.getBody());
             }
 
         } catch (Exception e) {
@@ -121,27 +125,27 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
     public void sendWXCorpTemplateMsg(WxCorpInfo corpInfo, String corpUserid, JSONObject msg) {
         try {
             if (isDev) return;
-            log.info("发送企业微信模板消息==="+corpUserid);
-            System.out.println("发送企业微信模板消息==="+corpUserid);
+            log.info("发送企业微信模板消息===" + corpUserid);
+            System.out.println("发送企业微信模板消息===" + corpUserid);
             String accessToken = getCorpAccessToken(corpInfo);
             String url = URL_SEND_WXCORP_MSG.replaceAll("ACCESS_TOKEN", accessToken);
             HttpHeaders headers = new HttpHeaders();
             headers.setContentType(MediaType.APPLICATION_JSON);
             JSONObject reqParam = new JSONObject();
-            reqParam.put("touser",  corpUserid);
+            reqParam.put("touser", corpUserid);
             reqParam.put("toparty", "");
-            reqParam.put("totag",  "");
-            reqParam.put("msgtype",  "template_msg");
-            reqParam.put("agentid",  corpInfo.getAgentid());
-            reqParam.put("template_msg",msg);
+            reqParam.put("totag", "");
+            reqParam.put("msgtype", "template_msg");
+            reqParam.put("agentid", corpInfo.getAgentid());
+            reqParam.put("template_msg", msg);
 
             HttpEntity<String> requestEntity = new HttpEntity<String>(reqParam.toJSONString(), headers);
             ResponseEntity<String> responseEntity = this.restTemplate.exchange(url,
                     HttpMethod.POST, requestEntity, String.class);
             if (responseEntity.getStatusCode() == HttpStatus.OK) {
                 String resp = responseEntity.getBody();
-                log.info("发送企业微信模板消息返回结果=="+resp);
-                System.out.println("发送企业微信模板消息返回结果=="+resp);
+                log.info("发送企业微信模板消息返回结果==" + resp);
+                System.out.println("发送企业微信模板消息返回结果==" + resp);
                 JSONObject json = JSONObject.parseObject(resp);
                 if (json.getIntValue("errcode") == 0) {
                     //发送成功
@@ -150,8 +154,8 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                     throw new Exception(json.toJSONString());
                 }
             } else {
-                log.error("发送失败:"+responseEntity.getStatusCode()+", "+responseEntity.getBody());
-                System.err.println("发送失败:"+responseEntity.getStatusCode()+", "+responseEntity.getBody());
+                log.error("发送失败:" + responseEntity.getStatusCode() + ", " + responseEntity.getBody());
+                System.err.println("发送失败:" + responseEntity.getStatusCode() + ", " + responseEntity.getBody());
             }
 
         } catch (Exception e) {
@@ -166,18 +170,18 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
             String corpAccessToken = getCorpAccessToken(corpInfo);
             String url = URL_GET_MEDIA.replaceAll("ACCESS_TOKEN", corpAccessToken).replaceAll("MEDIA_ID", mediaId);
             HttpHeaders headers = new HttpHeaders();
-            ResponseEntity<byte[]> entity = restTemplate.exchange(url, HttpMethod.GET,new HttpEntity<>(headers), byte[].class);
+            ResponseEntity<byte[]> entity = restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(headers), byte[].class);
             byte[] body = entity.getBody();
             HttpHeaders respHeader = entity.getHeaders();
-            System.out.println("================开始处理文件==========body size="+body.length);
+            System.out.println("================开始处理文件==========body size=" + body.length);
             System.out.println(respHeader.getContentType());
             System.out.println(respHeader.getContentLength());
             System.out.println(respHeader.getContentDisposition().getName());
             ContentDisposition contentDisposition = respHeader.getContentDisposition();
-            System.out.println("文件名=="+contentDisposition.getFilename());
+            System.out.println("文件名==" + contentDisposition.getFilename());
             //写入文件
-            String fileName = mediaId+".jpg";
-            FileOutputStream fileOutputStream = new FileOutputStream(new File(path+fileName));
+            String fileName = mediaId + ".jpg";
+            FileOutputStream fileOutputStream = new FileOutputStream(new File(path + fileName));
             fileOutputStream.write(body);
             fileOutputStream.close();
         } catch (Exception e) {
@@ -192,17 +196,17 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
         try {
             String url = "http://worktime.ttkuaiban.com/upload/bc4df504fa724e6cab69872e2c1cfb35.png";
             HttpHeaders headers = new HttpHeaders();
-            ResponseEntity<byte[]> entity = restTemplate.exchange(url, HttpMethod.GET,new HttpEntity<>(headers), byte[].class);
+            ResponseEntity<byte[]> entity = restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(headers), byte[].class);
             byte[] body = entity.getBody();
             HttpHeaders respHeader = entity.getHeaders();
             System.out.println(respHeader.getContentType());
             System.out.println(respHeader.getContentLength());
             System.out.println(respHeader.getContentDisposition().getName());
             ContentDisposition contentDisposition = respHeader.getContentDisposition();
-            System.out.println("文件名=="+contentDisposition.getFilename());
+            System.out.println("文件名==" + contentDisposition.getFilename());
             //写入文件
             String fileName = "downloadFile.jpg";
-            FileOutputStream fileOutputStream = new FileOutputStream(new File(path+fileName));
+            FileOutputStream fileOutputStream = new FileOutputStream(new File(path + fileName));
             fileOutputStream.write(body);
             fileOutputStream.close();
 
@@ -214,7 +218,6 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
     }
 
 
-
     //获取第三方应用临时凭证
     private String getSuiteAccessToken() {
         if (WeiXinCorpController.SUITE_ACCESS_TOKEN == null || WeiXinCorpController.suiteTokenExpireTime < System.currentTimeMillis()) {
@@ -222,11 +225,11 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
             HttpHeaders headers = new HttpHeaders();
             headers.setContentType(MediaType.APPLICATION_JSON);
             JSONObject reqParam = new JSONObject();
-            reqParam.put("suite_id",  suitId);
+            reqParam.put("suite_id", suitId);
             reqParam.put("suite_secret", suitSecret);
             SysConfig param = sysConfigMapper.selectOne(new QueryWrapper<SysConfig>().eq("param_key", "wx_suite_ticket"));
             if (param != null) {
-                reqParam.put("suite_ticket",param.getParamValue());
+                reqParam.put("suite_ticket", param.getParamValue());
             }
 
             HttpEntity<String> requestEntity = new HttpEntity<String>(reqParam.toJSONString(), headers);
@@ -238,7 +241,7 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                 JSONObject obj = JSONObject.parseObject(resp);
                 if (obj.getIntValue("errcode") == 0) {
                     WeiXinCorpController.SUITE_ACCESS_TOKEN = obj.getString("suite_access_token");
-                    WeiXinCorpController.suiteTokenExpireTime = System.currentTimeMillis() + obj.getIntValue("expires_in")*1000;
+                    WeiXinCorpController.suiteTokenExpireTime = System.currentTimeMillis() + obj.getIntValue("expires_in") * 1000;
                 }
             }
         }
@@ -252,8 +255,8 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
             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());
+            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.POST, requestEntity, String.class);
@@ -289,7 +292,7 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
             long startTime = startDateTime.toEpochSecond(ZoneOffset.of("+8"));
             endDateTime = endDateTime.withHour(0).withMinute(0).withSecond(0).withNano(0);
             long endTime = endDateTime.toEpochSecond(ZoneOffset.of("+8"));
-            System.out.println("startTime="+startTime+",endTime="+endTime);
+            System.out.println("startTime=" + startTime + ",endTime=" + endTime);
 
             int batchCount = 1;
             int batchSize = 100;
@@ -298,20 +301,20 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
             if (userId == null) {
                 //获取企业下的全部员工
                 List<User> users = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId).isNotNull("corpwx_userid").eq("is_active", 1));
-                System.out.println("获取考勤记录users size=="+users.size());
+                System.out.println("获取考勤记录users size==" + users.size());
                 corpwxUserIds = users.stream().map(User::getCorpwxUserid).collect(Collectors.toList());
                 totalLength = corpwxUserIds.size();
-                batchCount = totalLength/batchSize+(totalLength%batchSize==0?0:1);
+                batchCount = totalLength / batchSize + (totalLength % batchSize == 0 ? 0 : 1);
             } else {
                 //指定获取员工
                 User user = userMapper.selectById(userId);
                 corpwxUserIds.add(user.getCorpwxUserid());
-                System.out.println("获取corpwxuserid=="+user.getCorpwxUserid()+"的考勤记录");
+                System.out.println("获取corpwxuserid==" + user.getCorpwxUserid() + "的考勤记录");
             }
             //按批调用
-            for (int i=0;i<batchCount; i++) {
-                int fromIndex = i*batchSize;
-                int toIndex = (i+1) * batchSize;
+            for (int i = 0; i < batchCount; i++) {
+                int fromIndex = i * batchSize;
+                int toIndex = (i + 1) * batchSize;
                 if (toIndex > totalLength) toIndex = totalLength;
                 Object[] objects = corpwxUserIds.subList(fromIndex, toIndex).toArray(new String[0]);
                 reqOnceCardTime(corpInfo, startTime, endTime, objects, showLog);
@@ -328,7 +331,7 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
         HttpRespMsg msg = new HttpRespMsg();
         List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", wxCorpInfo.getCompanyId()).likeRight("name", "woy9Tk"));
         List<String> corpwxUserIds = userList.stream().map(User::getCorpwxUserid).collect(Collectors.toList());
-        System.out.println("新拉取到的无姓名用户WXCorp_userid size="+corpwxUserIds.size());
+        System.out.println("新拉取到的无姓名用户WXCorp_userid size=" + corpwxUserIds.size());
         if (corpwxUserIds.size() == 0) {
             msg.data = "无新成员更新";
             return msg;
@@ -344,22 +347,22 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
             long startTime = startDateTime.toEpochSecond(ZoneOffset.of("+8"));
             endDateTime = endDateTime.withHour(0).withMinute(0).withSecond(0).withNano(0);
             long endTime = endDateTime.toEpochSecond(ZoneOffset.of("+8"));
-            System.out.println("startTime="+startTime+",endTime="+endTime);
+            System.out.println("startTime=" + startTime + ",endTime=" + endTime);
 
             int totalLength = corpwxUserIds.size();
             int batchSize = 100;
-            int batchCount = totalLength/batchSize+(totalLength%batchSize==0?0:1);
+            int batchCount = totalLength / batchSize + (totalLength % batchSize == 0 ? 0 : 1);
 
             //按批调用
-            for (int i=0;i<batchCount; i++) {
-                int fromIndex = i*batchSize;
-                int toIndex = (i+1) * batchSize;
+            for (int i = 0; i < batchCount; i++) {
+                int fromIndex = i * batchSize;
+                int toIndex = (i + 1) * batchSize;
                 if (toIndex > totalLength) toIndex = totalLength;
                 Object[] objects = corpwxUserIds.subList(fromIndex, toIndex).toArray(new String[0]);
                 reqOnceCardTime(wxCorpInfo, startTime, endTime, objects, false);
             }
             //查询日报中的人员姓名,更新用户表
-            System.out.println(""+corpwxUserIds.size());
+            System.out.println("" + corpwxUserIds.size());
             List<UserCorpwxTime> cardTimeList = userCorpwxTimeMapper.selectList(
                     new QueryWrapper<UserCorpwxTime>().select("distinct corpwx_userid, name").eq("company_id", wxCorpInfo.getCompanyId()).in("corpwx_userid", corpwxUserIds));
             List<User> updateUserList = new ArrayList<>();
@@ -369,9 +372,9 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                     user.setCorpwxUserid(userCorpwxTime.getCorpwxUserid());
                     updateUserList.add(user);
                     userMapper.updateById(user);
-                    System.out.println("更新用户:"+user.getName());
+                    System.out.println("更新用户:" + user.getName());
                 } else {
-                    System.out.println("查询日报无更新:"+userCorpwxTime.getCorpwxUserid()+", "+userCorpwxTime.getName());
+                    System.out.println("查询日报无更新:" + userCorpwxTime.getCorpwxUserid() + ", " + userCorpwxTime.getName());
                 }
             }
 
@@ -386,7 +389,7 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
             if (updateUserList.size() == 0) {
                 msg.data = "处理完毕。当前无新人员需要关联企业微信身份";
             } else {
-                msg.data = "处理完毕。本次自动关联了:"+updateUserList.size()+"位人员:"+updateUserList.stream().map(User::getName).collect(Collectors.joining(","));
+                msg.data = "处理完毕。本次自动关联了:" + updateUserList.size() + "位人员:" + updateUserList.stream().map(User::getName).collect(Collectors.joining(","));
             }
 
         } catch (Exception exception) {
@@ -401,22 +404,22 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
         String url = GET_CHECKIN_DAYDATA.replace("ACCESS_TOKEN", getCorpAccessToken(corpInfo));
         HttpHeaders headers = new HttpHeaders();
         headers.setContentType(MediaType.APPLICATION_JSON);
-        System.out.println(""+objects.toString());
+        System.out.println("" + objects.toString());
         JSONObject reqParam = new JSONObject();
         reqParam.put("starttime", startTime);
-        reqParam.put("endtime",  endTime);
-        reqParam.put("useridlist",  objects);
+        reqParam.put("endtime", endTime);
+        reqParam.put("useridlist", objects);
         HttpEntity<String> requestEntity = new HttpEntity<String>(reqParam.toJSONString(), headers);
         ResponseEntity<String> responseEntity = this.restTemplate.exchange(url,
                 HttpMethod.POST, requestEntity, String.class);
 
         if (responseEntity.getStatusCode() == HttpStatus.OK) {
             String resp = responseEntity.getBody();
-            if (showLog)System.out.println(resp);
+            if (showLog) System.out.println(resp);
             JSONObject json = JSONObject.parseObject(resp);
             if (json.getIntValue("errcode") == 0) {
                 JSONArray datas = json.getJSONArray("datas");
-                for (int i=0;i<datas.size(); i++) {
+                for (int i = 0; i < datas.size(); i++) {
                     JSONObject jsonObject = datas.getJSONObject(i);
                     JSONObject base_info = jsonObject.getJSONObject("base_info");
                     String curUserid = base_info.getString("acctid");
@@ -424,10 +427,10 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                     Long time = base_info.getLong("date");
                     JSONArray workRules = base_info.getJSONObject("rule_info").getJSONArray("checkintime");
                     //获取上下午的考勤打卡规则
-                    String baseMorningStart = workRules.size()<=1?"09:00":DateTimeUtil.getTimeFromSeconds(workRules.getJSONObject(0).getIntValue("work_sec"));
-                    String baseMorningEnd = workRules.size()<=1?"12:00":DateTimeUtil.getTimeFromSeconds(workRules.getJSONObject(0).getIntValue("off_work_sec"));
-                    String baseAfternoonStart = workRules.size()<=1?"13:00":DateTimeUtil.getTimeFromSeconds(workRules.getJSONObject(1).getIntValue("work_sec"));
-                    String baseAfternoonEnd = workRules.size()<=1?"18:00":DateTimeUtil.getTimeFromSeconds(workRules.getJSONObject(1).getIntValue("off_work_sec"));
+                    String baseMorningStart = workRules.size() <= 1 ? "09:00" : DateTimeUtil.getTimeFromSeconds(workRules.getJSONObject(0).getIntValue("work_sec"));
+                    String baseMorningEnd = workRules.size() <= 1 ? "12:00" : DateTimeUtil.getTimeFromSeconds(workRules.getJSONObject(0).getIntValue("off_work_sec"));
+                    String baseAfternoonStart = workRules.size() <= 1 ? "13:00" : DateTimeUtil.getTimeFromSeconds(workRules.getJSONObject(1).getIntValue("work_sec"));
+                    String baseAfternoonEnd = workRules.size() <= 1 ? "18:00" : DateTimeUtil.getTimeFromSeconds(workRules.getJSONObject(1).getIntValue("off_work_sec"));
                     if (workRules.size() == 0) {
                         baseMorningStart = "09:00";
                         baseMorningEnd = "12:00";
@@ -448,7 +451,7 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                     if (workRules.size() <= 1) {
                         restTime = 1.0;//一个小时午休
                     } else {
-                        restTime = 1.0*(workRules.getJSONObject(1).getIntValue("work_sec") - workRules.getJSONObject(0).getIntValue("off_work_sec"))/3600;
+                        restTime = 1.0 * (workRules.getJSONObject(1).getIntValue("work_sec") - workRules.getJSONObject(0).getIntValue("off_work_sec")) / 3600;
                     }
 
                     LocalDate localDate = LocalDateTime.ofInstant(Instant.ofEpochSecond(time), ZoneId.systemDefault()).toLocalDate();
@@ -477,11 +480,11 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                     //开始时间和结束时间一样,说明下班没有打卡,需要提取请假的最晚时间作为下班打卡时间
                     String lastestOffworkTime = null;
                     boolean needRecaculate = false;
-                    for (int t=0;t<holidayItems.size(); t++) {
+                    for (int t = 0; t < holidayItems.size(); t++) {
                         JSONObject holiday = holidayItems.getJSONObject(t);
                         JSONObject spTitle = holiday.getJSONObject("sp_title");
                         JSONArray data = spTitle.getJSONArray("data");
-                        for (int m=0;m<data.size(); m++) {
+                        for (int m = 0; m < data.size(); m++) {
                             String leaveText = data.getJSONObject(m).getString("text");
                             if (leaveText.startsWith("请假")) {
                                 //获取对应位置的请假时间段
@@ -493,11 +496,11 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                                 }
 
                                 //获取到请假的开始时间和结束时间
-                                String leaveEnd = isOldFormat?s[3]:s[4];
+                                String leaveEnd = isOldFormat ? s[3] : s[4];
                                 String leaveStart = s[1];
                                 //请假开始的日期和结束的日期
                                 String dateStart = localDate.getYear() + "/" + s[0];
-                                String dateEnd =  localDate.getYear() + "/" +(isOldFormat?s[2]:s[3]);
+                                String dateEnd = localDate.getYear() + "/" + (isOldFormat ? s[2] : s[3]);
                                 LocalDate sDate = LocalDate.parse(dateStart, mdFormat);
                                 LocalDate eDate = LocalDate.parse(dateEnd, mdFormat);
                                 if (sDate.isEqual(eDate)) {
@@ -510,7 +513,7 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                                             leaveStart = "14:00";
                                             leaveEnd = baseAfternoonEnd;//请假的下班打卡时间,算上午结束的时间
                                         }
-                                    } else if (leaveEnd.equals("上午")){
+                                    } else if (leaveEnd.equals("上午")) {
                                         //上午请假
                                         leaveEnd = baseMorningEnd;
                                         leaveStart = baseMorningStart;
@@ -519,10 +522,11 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                                     if ("00:00".equals(leaveStart)) {
                                         leaveStart = baseMorningStart;
                                     }
-                                    System.out.println("leaveStart=="+leaveStart+", leaveEnd="+leaveEnd);
+                                    System.out.println("leaveStart==" + leaveStart + ", leaveEnd=" + leaveEnd);
                                 } else {
-                                    if (showLog)System.out.println("跨天请假@@@@");
-                                    if (showLog)System.out.println("当天=="+localDate+", sDate=" + sDate+", 比较="+(localDate.isEqual(sDate)));
+                                    if (showLog) System.out.println("跨天请假@@@@");
+                                    if (showLog)
+                                        System.out.println("当天==" + localDate + ", sDate=" + sDate + ", 比较=" + (localDate.isEqual(sDate)));
                                     //跨天请假
                                     if (localDate.isEqual(sDate)) {
                                         //当前日期第一天,需判断上下午半天请假的情况
@@ -537,7 +541,7 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                                         //当前日期就是最后一天,需判断上下午半天请假的情况
                                         if (leaveEnd.equals("下午")) {
                                             leaveEnd = baseAfternoonEnd;//请假到最后一天的下午,就算是全天
-                                        } else if (leaveEnd.equals("上午")){
+                                        } else if (leaveEnd.equals("上午")) {
                                             //上午请假
                                             leaveEnd = baseMorningEnd;
                                         }
@@ -547,7 +551,7 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                                         //中间日期就是全天
                                         leaveStart = baseMorningStart;
                                         leaveEnd = baseAfternoonEnd;
-                                        if (showLog)System.out.println("===中间天请假===");
+                                        if (showLog) System.out.println("===中间天请假===");
                                     }
                                 }
 
@@ -568,7 +572,7 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                                 if (s.length < 5) {
                                     isOldFormat = true;
                                 }
-                                String outEnd = isOldFormat?s[3]:s[4];
+                                String outEnd = isOldFormat ? s[3] : s[4];
                                 String outStart = s[1];
                                 //获取外出的最早的开始时间和最晚的结束时间最为当天考勤的最早和最晚时间
                                 if (ct.getStartTime().equals("00:00") || ct.getStartTime().compareTo(outStart) > 0) {
@@ -586,7 +590,7 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                     double timeDelta = 0;
                     //时间有变化,需要重新计算
                     if (needRecaculate) {
-                        System.out.println(""+ct.getStartTime()+"--"+ct.getEndTime());
+                        System.out.println("" + ct.getStartTime() + "--" + ct.getEndTime());
                         timeDelta = DateTimeUtil.getHoursFromSeconds(DateTimeUtil.getSecondsFromTime(ct.getEndTime()) - DateTimeUtil.getSecondsFromTime(ct.getStartTime()));
                         //超过下午上班的开始时间,需要减去午休的时间
                         if (ct.getEndTime().compareTo(baseAfternoonStart) >= 0) {
@@ -598,11 +602,11 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                         timeDelta = ct.getCardTime();
                     }
 
-                    if (showLog)System.out.println("上下班间隔时长为=="+timeDelta);
+                    if (showLog) System.out.println("上下班间隔时长为==" + timeDelta);
                     ct.setName(name);
                     //解析请假和外出的情况
                     JSONArray sp_items = jsonObject.getJSONArray("sp_items");
-                    for (int j=0;j<sp_items.size(); j++) {
+                    for (int j = 0; j < sp_items.size(); j++) {
                         JSONObject spItem = sp_items.getJSONObject(j);
                         switch (spItem.getInteger("type")) {
                             case 1://请假
@@ -630,11 +634,11 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                     }
 
                     //获取请假的最早和最晚时间
-                    for (int t=0;t<holidayItems.size(); t++) {
+                    for (int t = 0; t < holidayItems.size(); t++) {
                         JSONObject holiday = holidayItems.getJSONObject(t);
                         JSONObject spTitle = holiday.getJSONObject("sp_title");
                         JSONArray data = spTitle.getJSONArray("data");
-                        for (int m=0;m<data.size(); m++) {
+                        for (int m = 0; m < data.size(); m++) {
                             String leaveText = data.getJSONObject(m).getString("text");
                             if (leaveText.startsWith("请假")) {
                                 //获取对应位置的请假时间段
@@ -646,19 +650,20 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                                 }
                                 //获取到请假的开始时间和结束时间
                                 String leaveStart = s[1];
-                                String leaveEnd = isOldFormat?s[3]:s[4];
+                                String leaveEnd = isOldFormat ? s[3] : s[4];
 
                                 //检查请假时间段是否在打卡的时间范围内
                                 if ("上午".equals(leaveEnd) || "下午".equals(leaveEnd)) {
                                     //半天或者全天请假, 上面已经处理过结束时间为请假之前的时间了,此处不需要再处理了
                                     if (ct.getAskLeaveTime() >= 12) {
-                                        if (showLog)System.out.println("====半天或者全天请假 =转化为8小时制下的时间="+(ct.getAskLeaveTime()/24*8.0));
+                                        if (showLog)
+                                            System.out.println("====半天或者全天请假 =转化为8小时制下的时间=" + (ct.getAskLeaveTime() / 24 * 8.0));
                                         //12小时以上的,是请假半天或者全天的。 防止1天有2次上下午分开的请假,导致计算两次的错误
-                                        ct.setAskLeaveTime(ct.getAskLeaveTime()/24*8.0);//转换成一天8小时工作制
+                                        ct.setAskLeaveTime(ct.getAskLeaveTime() / 24 * 8.0);//转换成一天8小时工作制
                                     }
                                 } else if (ct.getStartTime().compareTo(leaveStart) <= 0 && ct.getEndTime().compareTo(leaveEnd) >= 0) {
                                     String hourLeaveTime = leaveText.replaceAll("请假", "").replaceAll("小时", "");
-                                    if (showLog)System.out.println("请假时长=" + hourLeaveTime);
+                                    if (showLog) System.out.println("请假时长=" + hourLeaveTime);
 //                                        ct.setCardTime(ct.getCardTime() - Double.parseDouble(hourLeaveTime));
                                 }
                             }
@@ -671,7 +676,7 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                     if (ct.getAskLeaveTime() > 8.0) {
                         ct.setAskLeaveTime(8.0);//超过8小时都以8小时计算
                     }
-                    if (showLog)System.out.println("校正后请假时长="+ct.getAskLeaveTime());
+                    if (showLog) System.out.println("校正后请假时长=" + ct.getAskLeaveTime());
                     //如果有出差的,但是没有打卡,则用出差的时间作为timeDelta
                     if (timeDelta < 8.0 && ct.getOutdoorTime() > 0) {
                         timeDelta += ct.getOutdoorTime();
@@ -687,7 +692,7 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                         ct.setStartTime(baseMorningStart);
                         ct.setEndTime(baseAfternoonEnd);
                     }
-                    if (showLog)System.out.println("工作时长=="+workHours);
+                    if (showLog) System.out.println("工作时长==" + workHours);
                     ct.setWorkHours(DateTimeUtil.getHoursFromDouble(workHours));
 //                        if (regular_work_sec < standard_work_sec) {
 //                            ct.setWorkHours(DateTimeUtil.getHoursFromDouble(ct.getCardTime() + ct.getOutdoorTime()));
@@ -733,4 +738,188 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
             return d;
         }
     }
+
+    //查询某时间段的微信请假审批单号及详情
+    @Override
+    public List<LeaveSheet> WxLeaveNumber(String startTime,String endTime,List<WxCorpInfo> wxCorpInfos) throws Exception {
+        //存储更新失败的公司名称
+        List<String> fail = new ArrayList<>();
+        String url = "https://qyapi.weixin.qq.com/cgi-bin/oa/getapprovalinfo?access_token=ACCESS_TOKEN";
+        String detailUrl = "https://qyapi.weixin.qq.com/cgi-bin/oa/getapprovaldetail?access_token=ACCESS_TOKEN";
+        HttpHeaders headers = new HttpHeaders();
+        RestTemplate restTemplate = new RestTemplate();
+        ArrayList<LeaveSheet> result = new ArrayList<>();
+        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
+        headers.setContentType(type);
+        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
+        for (WxCorpInfo wxCorpInfo : wxCorpInfos) {
+            //获取更新Access_token查询审批号
+            String accessToken = getCorpAccessToken(wxCorpInfo);
+            url = url.replace("ACCESS_TOKEN", accessToken);
+            ArrayList<HashMap> list = new ArrayList<>();
+            HashMap<String, String> record_type = new HashMap<>();
+            HashMap<String, String> sp_status = new HashMap<>();
+            list.add(record_type);
+            list.add(sp_status);
+            record_type.put("key", "record_type");
+            record_type.put("value", "1");
+            sp_status.put("key", "sp_status");
+            sp_status.put("value", "2");
+            JSONObject requestMap = new JSONObject();
+            requestMap.put("starttime", startTime);
+            requestMap.put("endtime", endTime);
+            requestMap.put("cursor", 0);
+            requestMap.put("size", 100);
+            requestMap.put("filters", list);
+            HttpEntity<JSONObject> entity = new HttpEntity<>(requestMap, headers);
+            ResponseEntity<String> ResponseEntity = restTemplate.postForEntity(url, entity, String.class);
+            if (ResponseEntity.getStatusCode() == HttpStatus.OK) {
+                String resp = ResponseEntity.getBody();
+                JSONObject json = JSONObject.parseObject(resp);
+                Object[] sp_no_lists = json.getJSONArray("sp_no_list").toArray();
+                //查询每个审批号审批详情
+                for (int i = 0; i < sp_no_lists.length; i++) {
+                    detailUrl = detailUrl.replace("ACCESS_TOKEN", accessToken);
+                    JSONObject detailMap = new JSONObject();
+                    detailMap.put("sp_no", sp_no_lists[i]);
+                    HttpEntity<JSONObject> detailEntity = new HttpEntity<>(detailMap, headers);
+                    ResponseEntity<String> detailResponseEntity = restTemplate.postForEntity(detailUrl, detailEntity, String.class);
+                    if(ResponseEntity.getStatusCode() == HttpStatus.OK){
+                        //封装请假单数据
+                        String detailResp = detailResponseEntity.getBody();
+                        JSONObject detailJson = JSONObject.parseObject(detailResp);
+                        String info = detailJson.getString("info");
+                        JSONObject infoJson = JSONObject.parseObject(info);
+                        //审批申请提交时间,Unix时间戳
+                        LocalDateTime applyTime = LocalDateTime.ofEpochSecond(Long.parseLong(infoJson.getString("apply_time")), 0, ZoneOffset.ofHours(8));
+                        //申请人姓名
+                        String applyer = infoJson.getString("applyer");
+                        String userId = JSONObject.parseObject(applyer).getString("userid");
+                        User user = userMapper.selectOne(new QueryWrapper<User>().eq("corpwx_userid", userId));
+                        if(user == null){
+                            System.out.println("申请人WxId查询不到");
+                            continue;
+                        }
+                        String name = user.getName();
+                        //审批人姓名
+                        Object[] sp_record = infoJson.getJSONArray("sp_record").toArray();
+                        Object[] details = JSONObject.parseObject(sp_record[0].toString()).getJSONArray("details").toArray();
+                        String approver = JSONObject.parseObject(details[0].toString()).getString("approver");
+                        String approverUserId = JSONObject.parseObject(approver).getString("userid");
+                        User approverUser = userMapper.selectOne(new QueryWrapper<User>().eq("corpwx_userid", approverUserId));
+                        if(approverUser == null){
+                            System.out.println("审批人WxId为空");
+                            continue;
+                        }
+                        String approverName = approverUser.getName();
+                        //请假类型
+                        String apply_data = infoJson.getString("apply_data");
+                        Object[] contents = JSONObject.parseObject(apply_data).getJSONArray("contents").toArray();
+                        String value = JSONObject.parseObject(contents[0].toString()).getString("value");
+                        String remarkValue = JSONObject.parseObject(contents[1].toString()).getString("value");
+                        String remark = JSONObject.parseObject(remarkValue).getString("text");
+                        String vacation = JSONObject.parseObject(value).getString("vacation");
+                        String selector = JSONObject.parseObject(vacation).getString("selector");
+                        Object[] options = JSONObject.parseObject(selector).getJSONArray("options").toArray();
+                        Object[] values = JSONObject.parseObject(options[0].toString()).getJSONArray("value").toArray();
+                        String text = JSONObject.parseObject(values[0].toString()).getString("text");
+                        Integer leave_type = 0;
+                        switch (text){
+                            case "事假":
+                                leave_type = 0;
+                                break;
+                            case "病假":
+                                leave_type = 1;
+                                break;
+                            case "年假":
+                                leave_type = 2;
+                                break;
+                            case "产假":
+                                leave_type = 3;
+                                break;
+                            case "婚假":
+                                leave_type = 4;
+                                break;
+                            case "丧假":
+                                leave_type = 5;
+                                break;
+                            case "调休假":
+                                leave_type = 6;
+                                break;
+                            case "陪产假":
+                                leave_type = 7;
+                                break;
+                            case "其他":
+                                leave_type = 8;
+                                break;
+                        }
+                        //请假开始时间
+                        String attendance = JSONObject.parseObject(vacation).getString("attendance");
+                        String date_range = JSONObject.parseObject(attendance).getString("date_range");
+                        String startDate = JSONObject.parseObject(date_range).getString("new_begin");
+                        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
+                        long startDateTemp = Long.valueOf(startDate);
+                        String startDateString = sdf.format(new Date(startDateTemp * 1000L));
+                        DateTimeFormatter startfmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+                        LocalDate sDate = LocalDate.parse(startDateString, startfmt);
+                        //请假结束时间
+                        String endDate = JSONObject.parseObject(date_range).getString("new_end");
+                        long endDatetemp = Long.valueOf(endDate);
+                        String endDateString = sdf.format(new Date(endDatetemp * 1000L));
+                        DateTimeFormatter endfmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+                        LocalDate eDate = LocalDate.parse(endDateString, endfmt);
+                        //请假时长
+                        String timeHours = JSONObject.parseObject(date_range).getString("new_duration");
+                        String leaveType = JSONObject.parseObject(date_range).getString("type");
+                        LeaveSheet leaveSheet = new LeaveSheet();
+                        leaveSheet.setIsFinalAudit(1);
+                        leaveSheet.setIndate(applyTime);
+                        leaveSheet.setOwnerName(name);
+                        leaveSheet.setOwnerId(user.getId());
+                        leaveSheet.setCompanyId(user.getCompanyId());
+                        leaveSheet.setTel(user.getPhone()==null?"":user.getPhone());
+                        //审批人信息
+                        leaveSheet.setAuditorName(approverName);
+                        leaveSheet.setAuditorId(approverUser.getId());
+                        //请假日期
+                        leaveSheet.setStartDate(sDate);
+                        leaveSheet.setEndDate(eDate);
+                        //请假类型
+                        leaveSheet.setLeaveType(leave_type);
+                        leaveSheet.setStatus(0);
+                        //请假说明
+                        leaveSheet.setRemark(remark==null?"":remark);
+                        //请假时长和天数
+                        float time = Integer.parseInt(timeHours);
+                        if("hour".equals(leaveType)){
+                            leaveSheet.setTimeType(1);
+                            leaveSheet.setTimeHours(time/3600);
+                        }else{
+                            leaveSheet.setTimeType(0);
+                            leaveSheet.setTimeDays(time/3600/24);
+                        }
+                        result.add(leaveSheet);
+                        for (LeaveSheet sheet : result) {
+                            System.out.println(sheet);
+                        }
+                    }else{
+                        System.out.println(sp_no_lists[i]+"审批单详情查询失败");
+                    }
+                }
+            }else{
+                fail.add(wxCorpInfo.getCorpFullName());
+                System.out.println(wxCorpInfo.getCorpFullName()+"审批单查询失败");
+            }
+        }
+        if (fail.size() == 0){
+            System.out.println("全部同步成功");
+        }else{
+            System.out.print("同步失败的公司有:");
+            for (String s : fail) {
+                System.out.print(s+",");
+                System.out.println();
+            }
+        }
+        return result;
+    }
 }

+ 20 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java

@@ -3,6 +3,7 @@ package com.management.platform.task;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.injector.methods.SelectById;
 import com.management.platform.entity.*;
 import com.management.platform.mapper.*;
 import com.management.platform.service.CompanyDingdingService;
@@ -18,10 +19,15 @@ import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
 import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
 import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 import org.springframework.util.StringUtils;
+import org.springframework.web.client.RestTemplate;
 
 import javax.annotation.Resource;
 import java.security.SecureRandom;
@@ -85,6 +91,8 @@ public class TimingTask {
     @Value(value = "${upload.path}")
     private String path;
 
+    @Resource
+    private LeaveSheetMapper leaveSheetMapper;
     @Resource
     private ProjectMapper projectMapper;
     @Resource
@@ -178,7 +186,18 @@ public class TimingTask {
         }
     }
 
-
+    //每天1:00 同步昨天的微信请假信息
+    @Scheduled(cron = "0 0 1 ? * *")
+    private void synWxLeave() throws Exception {
+        if (isDev) return;
+        String startTime = Long.toString(System.currentTimeMillis()/1000L-86400);
+        String endTime = Long.toString(System.currentTimeMillis()/1000L);
+        List<WxCorpInfo> wxCorpInfos = wxCorpInfoMapper.selectList(null);
+        List<LeaveSheet> leaveSheets = wxCorpInfoService.WxLeaveNumber(startTime,endTime, wxCorpInfos);
+        for (LeaveSheet leaveSheet : leaveSheets) {
+            leaveSheetMapper.insert(leaveSheet);
+        }
+    }
 
     //每天7点同步前2天的企业微信考勤考勤打卡记录
     @Scheduled(cron = "0 0 7 ? * *")