seyason 2 tahun lalu
induk
melakukan
f9bf846946
30 mengubah file dengan 508 tambahan dan 335 penghapusan
  1. 158 111
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/DingDingController.java
  2. 34 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/WeiXinCorpController.java
  3. 5 5
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/CompanyDingding.java
  4. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ReportMapper.java
  5. 2 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/CompanyDingdingService.java
  6. 13 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/DingDingService.java
  7. 57 20
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/CompanyDingdingServiceImpl.java
  8. 209 178
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DingDingServiceImpl.java
  9. 5 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  10. 2 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/UserServiceImpl.java
  11. 2 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java
  12. 1 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/ExcelUtil.java
  13. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/application-dev.yml
  14. 6 8
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/application-mld.yml
  15. 3 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/application.yml
  16. 3 3
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/CompanyDingdingMapper.xml
  17. 5 2
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportMapper.xml
  18. TEMPAT SAMPAH
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/upload/人员导入模板.xlsx
  19. TEMPAT SAMPAH
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/upload/员工工时导入模板.xlsx
  20. TEMPAT SAMPAH
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/upload/员工工时统计模板.xlsx
  21. TEMPAT SAMPAH
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/upload/员工项目分摊比例导入模板.xlsx
  22. TEMPAT SAMPAH
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/upload/工时管家使用说明_基础版.docx
  23. TEMPAT SAMPAH
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/upload/工时管家使用说明_建筑工程专业版.docx
  24. TEMPAT SAMPAH
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/upload/工时管家使用说明_项目管理专业版.docx
  25. TEMPAT SAMPAH
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/upload/新增客户导入模板.xlsx
  26. TEMPAT SAMPAH
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/upload/研究中心导入模板.xlsx
  27. TEMPAT SAMPAH
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/upload/资源需求导入模板.xlsx
  28. TEMPAT SAMPAH
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/upload/项目任务导入模板.xlsx
  29. TEMPAT SAMPAH
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/upload/项目导入模板.xlsx
  30. 1 1
      fhKeeper/formulahousekeeper/timesheet_h5/public/index.html

+ 158 - 111
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/DingDingController.java

@@ -16,11 +16,14 @@ import com.management.platform.util.*;
 import com.taobao.api.ApiException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.ZoneOffset;
 import java.time.format.DateTimeFormatter;
 import java.util.List;
 import java.util.Map;
@@ -33,11 +36,16 @@ import java.util.stream.Collectors;
 public class DingDingController {
 
     private final Logger bizLogger = LoggerFactory.getLogger(getClass());
-    String token = "cf776d62c5fb3508b5d8c2cbb9f3df0c";
+
     String aesKey = "ktmbamhymjsf60ndwp6n81mnu92847oynsgj9e0zr9v";
+    String token = "cf776d62c5fb3508b5d8c2cbb9f3df0c";
+
     String suiteKey = "suitejwoq9dw4bxv4stdb";
     String suiteSecret = "o-TWFLkFe8YbJsa_025JOj_JEWydP5GR3eigt1Yn1rtx5dTcryTJiSA6KEih3Bi4";
 
+    @Value("${configEnv.isPrivateDeploy}")
+    private boolean isPrivateDeploy;
+
     @Resource
     private DingDingService dingDingService;
     static ExecutorService executorService = Executors.newCachedThreadPool();
@@ -56,14 +64,15 @@ public class DingDingController {
             @RequestParam(value = "signature") String signature,
             @RequestParam(value = "timestamp") String timestamp,
             @RequestParam(value = "nonce") String nonce,
-            @RequestBody(required = false) JSONObject body
+            @RequestBody(required = false) JSONObject body,
+            @RequestParam(value = "innerAppKey", required = false) String innerAppKey
     ) {
-        System.out.println("接收到ding call back");
+        System.out.println("接收到ding call back"+(isPrivateDeploy?", innerAppKey="+innerAppKey:""));
         if (body == null) {
             System.out.println("Body为NULL !!!!!,直接返回success");
             DingCallbackCrypto callbackCrypto = null;
             try {
-                callbackCrypto = new DingCallbackCrypto(token, aesKey, suiteKey);
+                callbackCrypto = new DingCallbackCrypto(token, aesKey, isPrivateDeploy?innerAppKey:suiteKey);
                 Map<String, String> successMap = callbackCrypto.getEncryptedMap("success");
                 LocalDateTime now = LocalDateTime.now();
                 DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
@@ -83,7 +92,7 @@ public class DingDingController {
             //      此时OWNER_KEY为应用的APP_KEY(企业内部应用)或SUITE_KEY(三方应用)。
             // 2、调用订阅事件接口订阅的事件为企业级事件推送,
             //      此时OWNER_KEY为:企业的CORP_ID(企业内部应用)或SUITE_KEY(三方应用)
-            DingCallbackCrypto callbackCrypto = new DingCallbackCrypto(token, aesKey, suiteKey);
+            DingCallbackCrypto callbackCrypto = new DingCallbackCrypto(token, aesKey, isPrivateDeploy?innerAppKey:suiteKey);
             String encryptMsg = body.getString("encrypt");
             String decryptMsg = callbackCrypto.getDecryptMsg(signature, timestamp, nonce, encryptMsg);
 
@@ -99,126 +108,137 @@ public class DingDingController {
             } else if ("user_add_org".equals(eventType)) {
                 // 处理通讯录用户增加事件
                 bizLogger.info("发生了:" + eventType + "事件");
+                String corpId = eventJson.getString("CorpId");
+                JSONArray userIdArray = eventJson.getJSONArray("UserId");
+                dingDingService.userAddOrg(corpId, userIdArray);
             } else {
-                // 添加其他已注册的
                 bizLogger.info("发生了:" + eventType + "事件");
-                //推送suit ticket事件
-                /**
-                 * {
-                 *   "SuiteKey": "xxxxxx",
-                 *   "EventType": "suite_ticket ",
-                 *   "TimeStamp": 123456,
-                 *   "SuiteTicket": "xxxxxx"
-                 * }
-                 */
-                if ("suite_ticket".equals(eventType)) {
-                    System.out.println("==推送SuiteTicket===");
-                    dingDingService.updateSuiteTicket(eventJson.getString("SuiteTicket"));
-                } else if ("tmp_auth_code".equals(eventType)) {
-                    //企业授权开通应用
+                if ("user_leave_org".equals(eventType)) {
+                    String corpId = eventJson.getString("CorpId");
+                    JSONArray userIdArray = eventJson.getJSONArray("UserId");
+                    Long timeStamp = eventJson.getLong("TimeStamp");
+                    LocalDateTime time = LocalDateTime.ofEpochSecond(timeStamp/1000,0, ZoneOffset.ofHours(8));
+                    dingDingService.userLeaveOrg(corpId, userIdArray, time.toLocalDate());
+                } else {
+                    // 添加其他已注册的
+                    //推送suit ticket事件
                     /**
                      * {
-                     *    "TimeStamp":1553709079062,
-                     *    "AuthCode": "xxxxxx",
-                     *    "AuthCorpId":"xxxxxx",
-                     *    "EventType":"tmp_auth_code",
-                     *    "SuiteKey":"xxxxxx"
-                     *  }
+                     *   "SuiteKey": "xxxxxx",
+                     *   "EventType": "suite_ticket ",
+                     *   "TimeStamp": 123456,
+                     *   "SuiteTicket": "xxxxxx"
+                     * }
                      */
-                    System.out.println("==企业授权开通应用===");
+                    if ("suite_ticket".equals(eventType)) {
+                        System.out.println("==推送SuiteTicket===");
+                        dingDingService.updateSuiteTicket(eventJson.getString("SuiteTicket"));
+                    } else if ("tmp_auth_code".equals(eventType)) {
+                        //企业授权开通应用
+                        /**
+                         * {
+                         *    "TimeStamp":1553709079062,
+                         *    "AuthCode": "xxxxxx",
+                         *    "AuthCorpId":"xxxxxx",
+                         *    "EventType":"tmp_auth_code",
+                         *    "SuiteKey":"xxxxxx"
+                         *  }
+                         */
+                        System.out.println("==企业授权开通应用===");
 
-                } else if ("SYNC_HTTP_PUSH_HIGH".equals(eventType)) {
-                    /**
-                     * {"EventType":"SYNC_HTTP_PUSH_HIGH",
-                     * "bizData":[{"gmt_create":1624757980000,"biz_type":2,"open_cursor":0,
-                     * "subscribe_id":"16822005_0","id":15275,"gmt_modified":1624757980000,
-                     * "biz_id":"16822005",
-                     * "biz_data":"{\"syncAction\":\"suite_ticket\",
-                     * \"suiteTicket\":\"IaIbq7a9S36R2uAbUh02VNlWoMB2LkorhyFCFhdpSWxJPZhIsIEhxIoIS7HQRn0zxMGh57gGd56RRh2Ntmcuzq\",
-                     * \"syncSeq\":\"AE815E12E6908BDEE8CA8D33A9\"}","corp_id":"ding169917db7f1ee5f435c2f4657eb6378f","status":0}]}
-                     */
-                    JSONArray bizData = eventJson.getJSONArray("bizData");
-                    if (bizData.size() > 0) {
-                        //优先处理suite_ticket推送
-                        for (int i=0;i<bizData.size(); i++) {
-                            JSONObject bizItem = bizData.getJSONObject(i);
-                            int bizType = bizItem.getInteger("biz_type");
-                            if (bizType == 2) {
-                                //SuteTicket推送事件
-                                JSONObject biz_data = JSONObject.parseObject(bizItem.getString("biz_data"));
-                                String syncAction = biz_data.getString("syncAction");
-                                if ("suite_ticket".equals(syncAction)) {
-                                    System.out.println("==Push 推送事件 suite_ticket===");
-                                    dingDingService.updateSuiteTicket(biz_data.getString("suiteTicket"));
+                    } else if ("SYNC_HTTP_PUSH_HIGH".equals(eventType)) {
+                        /**
+                         * {"EventType":"SYNC_HTTP_PUSH_HIGH",
+                         * "bizData":[{"gmt_create":1624757980000,"biz_type":2,"open_cursor":0,
+                         * "subscribe_id":"16822005_0","id":15275,"gmt_modified":1624757980000,
+                         * "biz_id":"16822005",
+                         * "biz_data":"{\"syncAction\":\"suite_ticket\",
+                         * \"suiteTicket\":\"IaIbq7a9S36R2uAbUh02VNlWoMB2LkorhyFCFhdpSWxJPZhIsIEhxIoIS7HQRn0zxMGh57gGd56RRh2Ntmcuzq\",
+                         * \"syncSeq\":\"AE815E12E6908BDEE8CA8D33A9\"}","corp_id":"ding169917db7f1ee5f435c2f4657eb6378f","status":0}]}
+                         */
+                        JSONArray bizData = eventJson.getJSONArray("bizData");
+                        if (bizData.size() > 0) {
+                            //优先处理suite_ticket推送
+                            for (int i=0;i<bizData.size(); i++) {
+                                JSONObject bizItem = bizData.getJSONObject(i);
+                                int bizType = bizItem.getInteger("biz_type");
+                                if (bizType == 2) {
+                                    //SuteTicket推送事件
+                                    JSONObject biz_data = JSONObject.parseObject(bizItem.getString("biz_data"));
+                                    String syncAction = biz_data.getString("syncAction");
+                                    if ("suite_ticket".equals(syncAction)) {
+                                        System.out.println("==Push 推送事件 suite_ticket===");
+                                        dingDingService.updateSuiteTicket(biz_data.getString("suiteTicket"));
+                                    }
                                 }
                             }
-                        }
-                        //再处理其他的情况
-                        for (int i=0;i<bizData.size(); i++) {
-                            JSONObject bizItem = bizData.getJSONObject(i);
-                            int bizType = bizItem.getInteger("biz_type");
-                            if (bizType == 4) {
-                                //企业授权变更,包含授权、解除授权、授权变更。
-                                JSONObject biz_data = JSONObject.parseObject(bizItem.getString("biz_data"));
-                                System.out.println("授权变更数据===@@");
-                                System.out.println(biz_data);
-                                String syncAction = biz_data.getString("syncAction");
-                                if ("org_suite_auth".equals(syncAction) || "org_suite_change".equals(syncAction)) {
-                                    //开通授权应用
-                                    JSONObject authCorpInfo = biz_data.getJSONObject("auth_corp_info");
-                                    String corp_name = authCorpInfo.getString("corp_name");
-                                    boolean isAuthenticated = authCorpInfo.getBooleanValue("is_authenticated");
-                                    Long agentId = null;
-                                    if ("org_suite_auth".equals(syncAction)) {
-                                        System.out.println("==Push 推送事件 开通授权应用===" + corp_name);
-                                        //此处在授权开通时强制赋值
-                                        isAuthenticated = true;
-                                        JSONObject authInfo = biz_data.getJSONObject("auth_info");
-
-                                        if (authInfo != null) {
-                                            JSONArray agents = authInfo.getJSONArray("agent");
-                                            for (int j=0;j<agents.size(); j++) {
-                                                JSONObject item = agents.getJSONObject(j);
-                                                if (item.getString("agent_name").equals("工时管家")) {
-                                                    agentId = item.getLong("agentid");
+                            //再处理其他的情况
+                            for (int i=0;i<bizData.size(); i++) {
+                                JSONObject bizItem = bizData.getJSONObject(i);
+                                int bizType = bizItem.getInteger("biz_type");
+                                if (bizType == 4) {
+                                    //企业授权变更,包含授权、解除授权、授权变更。
+                                    JSONObject biz_data = JSONObject.parseObject(bizItem.getString("biz_data"));
+                                    System.out.println("授权变更数据===@@");
+                                    System.out.println(biz_data);
+                                    String syncAction = biz_data.getString("syncAction");
+                                    if ("org_suite_auth".equals(syncAction) || "org_suite_change".equals(syncAction)) {
+                                        //开通授权应用
+                                        JSONObject authCorpInfo = biz_data.getJSONObject("auth_corp_info");
+                                        String corp_name = authCorpInfo.getString("corp_name");
+                                        boolean isAuthenticated = authCorpInfo.getBooleanValue("is_authenticated");
+                                        Long agentId = null;
+                                        if ("org_suite_auth".equals(syncAction)) {
+                                            System.out.println("==Push 推送事件 开通授权应用===" + corp_name);
+                                            //此处在授权开通时强制赋值
+                                            isAuthenticated = true;
+                                            JSONObject authInfo = biz_data.getJSONObject("auth_info");
+
+                                            if (authInfo != null) {
+                                                JSONArray agents = authInfo.getJSONArray("agent");
+                                                for (int j=0;j<agents.size(); j++) {
+                                                    JSONObject item = agents.getJSONObject(j);
+                                                    if (item.getString("agent_name").equals("工时管家")) {
+                                                        agentId = item.getLong("agentid");
+                                                    }
                                                 }
                                             }
+                                        } else {
+                                            System.out.println("==Push 推送事件 授权变更==="+ corp_name+"=="+(isAuthenticated?"启用":"停用"));
+                                        }
+                                        if (isAuthenticated) {
+                                            String corpid = authCorpInfo.getString("corpid");
+                                            String authUserId = biz_data.getJSONObject("auth_user_info").getString("userId");
+                                            try {
+                                                dingDingService.corpAuth(corpid, corp_name, authUserId, agentId);
+                                            } catch (ApiException e) {
+                                                e.printStackTrace();
+                                                System.out.println(e.getMessage());
+                                            }
+                                        } else {
+                                            System.out.println("===未授权启用===");
                                         }
+
                                     } else {
-                                        System.out.println("==Push 推送事件 授权变更==="+ corp_name+"=="+(isAuthenticated?"启用":"停用"));
+                                        System.out.println("==Push 推送授权类型 ==="+syncAction);
+
                                     }
-                                    if (isAuthenticated) {
-                                        String corpid = authCorpInfo.getString("corpid");
-                                        String authUserId = biz_data.getJSONObject("auth_user_info").getString("userId");
+                                } else if (bizType == 7) {
+                                    JSONObject biz_data = JSONObject.parseObject(bizItem.getString("biz_data"));
+                                    String syncAction = biz_data.getString("syncAction");
+                                    if ("org_micro_app_scope_update".equals(syncAction)) {
+                                        //授权范围变更,我们尝试重新获取组织结构
+                                        String corpid = bizItem.getString("corp_id");
+                                        System.out.println("==Push 推送事件 使用范围变更=调用syncCorpMembs, corpid==="+corpid);
                                         try {
-                                            dingDingService.corpAuth(corpid, corp_name, authUserId, agentId);
+                                            dingDingService.syncCorpMembs(corpid);
                                         } catch (ApiException e) {
                                             e.printStackTrace();
-                                            System.out.println(e.getMessage());
                                         }
-                                    } else {
-                                        System.out.println("===未授权启用===");
+                                    } else if ("org_micro_app_restore".equals(syncAction)) {
+                                        String corpid = bizItem.getString("corp_id");
+                                        System.out.println("==Push 推送事件 app 工时管家恢复启用, corpid==="+corpid);
                                     }
-
-                                } else {
-                                    System.out.println("==Push 推送授权类型 ==="+syncAction);
-
-                                }
-                            } else if (bizType == 7) {
-                                JSONObject biz_data = JSONObject.parseObject(bizItem.getString("biz_data"));
-                                String syncAction = biz_data.getString("syncAction");
-                                if ("org_micro_app_scope_update".equals(syncAction)) {
-                                    //授权范围变更,我们尝试重新获取组织结构
-                                    String corpid = bizItem.getString("corp_id");
-                                    System.out.println("==Push 推送事件 使用范围变更=调用syncCorpMembs, corpid==="+corpid);
-                                    try {
-                                        dingDingService.syncCorpMembs(corpid);
-                                    } catch (ApiException e) {
-                                        e.printStackTrace();
-                                    }
-                                } else if ("org_micro_app_restore".equals(syncAction)) {
-                                    String corpid = bizItem.getString("corp_id");
-                                    System.out.println("==Push 推送事件 app 工时管家恢复启用, corpid==="+corpid);
                                 }
                             }
                         }
@@ -313,7 +333,7 @@ public class DingDingController {
 
     @RequestMapping("/syncUserWorkData")
     public HttpRespMsg syncUserWorkData(Integer companyId, String startDate, String endDate) {
-        CompanyDingding dingding = companyDingdingMapper.selectOne(new QueryWrapper<CompanyDingding>().eq("company_id", companyId).isNotNull("custom_appkey"));
+        CompanyDingding dingding = companyDingdingMapper.selectOne(new QueryWrapper<CompanyDingding>().eq("company_id", companyId).isNotNull("inner_appkey"));
         HttpRespMsg msg = new HttpRespMsg();
         if (startDate.compareTo(endDate) > 0) {
             msg.setError("开始日期不能晚于结束日期");
@@ -322,7 +342,7 @@ public class DingDingController {
 
         if (companyId != null) {
             if (dingding == null) {
-                msg.setError("该公司没有设置customAppkey和customAppSecrt");
+                msg.setError("该公司没有设置innerAppkey和innerAppSecrt");
                 return msg;
             } else {
                 long t1 = System.currentTimeMillis();
@@ -335,10 +355,10 @@ public class DingDingController {
             List<Integer> compIds = timeTypeList.stream().map(TimeType::getCompanyId).collect(Collectors.toList());
             //企业内部应用才有权限调用
             List<CompanyDingding> dingdingList = companyDingdingMapper.selectList(new QueryWrapper<CompanyDingding>().in("company_id", compIds)
-                    .isNotNull("custom_appkey"));
+                    .isNotNull("inner_appkey"));
             System.out.println("==========获取钉钉内部应用的数量是:"+dingdingList.size());
             if (dingdingList.size() == 0) {
-                msg.setError("没有设置customAppkey和customAppSecrt的数据");
+                msg.setError("没有设置innerAppkey和innerAppSecrt的数据");
                 return msg;
             } else {
                 long t1 = System.currentTimeMillis();
@@ -375,4 +395,31 @@ public class DingDingController {
         companyDingdingService.sendBusinessTripSettingMsg(companyId, dingding.getAgentId(), "040534176023851922");
         return new HttpRespMsg();
     }
+
+    /**
+     * 初始化内部应用的系统数据
+     * @return
+     */
+    @RequestMapping("/initSystem")
+    public HttpRespMsg initSystem(String corpid) {
+        try {
+            return dingDingService.initSystem(corpid);
+        } catch (ApiException e) {
+            e.printStackTrace();
+            String errMsg = e.getErrMsg();
+            HttpRespMsg msg = new HttpRespMsg();
+            msg.setError(errMsg);
+            return msg;
+        }
+    }
+
+    @RequestMapping("/removeCompInfo")
+    public HttpRespMsg removeCompInfo(String corpid) {
+        return dingDingService.removeCompInfo(corpid);
+    }
+
+    @RequestMapping("/initSuperManager")
+    public HttpRespMsg initSuperManager(String corpid, String name) {
+        return dingDingService.initSuperManager(corpid, name);
+    }
 }

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

@@ -55,10 +55,17 @@ public class WeiXinCorpController {
     public static final String GET_CHECKINDATA = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckindata?access_token=ACCESS_TOKEN";
 
     public static final String GET_CHECKINOPTION = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckinoption?access_token=ACCESS_TOKEN";
+
+    public static final String GET_CORP_TOKEN = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRET";
+
     @Value("${suitId}")
     private String suitId;
     @Value("${suitSecret}")
     private String suitSecret;
+
+    //自己公司的企业微信通讯录secret
+    private String concactSecret="irf7s8fy16wLhWGb8IxvGL2Nkm0sTB6dludpe_3VP6k";
+
     @Value("${token}")
     private String token;
     @Value("${encodingAesKey}")
@@ -175,6 +182,32 @@ public class WeiXinCorpController {
         return msg;
     }
 
+    //获取企业通讯录的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());
+                }
+            }
+        }
+        return corpInfo.getAccessToken();
+    }
+
     //获取企业AccessToken
     private String getCorpAccessToken(WxCorpInfo corpInfo) throws Exception {
         if (corpInfo.getExpireTime().isBefore(LocalDateTime.now())) {
@@ -931,7 +964,7 @@ public class WeiXinCorpController {
         Company company = companyMapper.selectById(wxCorpInfo.getCompanyId());
         String curCorpAccessToken = null;
         try {
-            curCorpAccessToken = getCorpAccessToken(wxCorpInfo);
+            curCorpAccessToken = getCorpConcactAccessToken(wxCorpInfo);
         } catch (Exception exception) {
             exception.printStackTrace();
         }

+ 5 - 5
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/CompanyDingding.java

@@ -15,7 +15,7 @@ import lombok.experimental.Accessors;
  * </p>
  *
  * @author Seyason
- * @since 2022-04-29
+ * @since 2022-06-16
  */
 @Data
 @EqualsAndHashCode(callSuper = false)
@@ -63,14 +63,14 @@ public class CompanyDingding extends Model<CompanyDingding> {
     /**
      * 企业内部应用appkey
      */
-    @TableField("custom_appkey")
-    private String customAppkey;
+    @TableField("inner_appkey")
+    private String innerAppkey;
 
     /**
      * 企业内部应用appsecret
      */
-    @TableField("custom_appsecret")
-    private String customAppsecret;
+    @TableField("inner_appsecret")
+    private String innerAppsecret;
 
     /**
      * 企业内部应用token

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

@@ -55,7 +55,7 @@ public interface ReportMapper extends BaseMapper<Report> {
                                                  @Param("isEngeering") Integer isEngeering,
                                                  @Param("startDate") String startDate,
                                                  @Param("endDate") String endDate,
-                                                 @Param("targetUserId") String targetUserId
+                                                 @Param("targetUserId") List<String> targetUserId
                                                  );
 
     //获取本人负责的专业的相关的日报

+ 2 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/CompanyDingdingService.java

@@ -32,4 +32,6 @@ public interface CompanyDingdingService extends IService<CompanyDingding> {
     public void sendFinishMileStoneMsg(CompanyDingding dingding, String useridList, String taskName, Integer projectId, String project, String finishDate);
 
     public void sendOAMsg(CompanyDingding dingding, String useridList, HashMap map);
+
+    public void sendInnerLinkMsg(CompanyDingding dingding, String useridList, String title, String alertMsg);
 }

+ 13 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/DingDingService.java

@@ -1,10 +1,15 @@
 package com.management.platform.service;
 
+import com.alibaba.fastjson.JSONArray;
 import com.management.platform.entity.CompanyDingding;
 import com.management.platform.util.HttpRespMsg;
 import com.taobao.api.ApiException;
 
+import java.time.LocalDate;
+
 public interface DingDingService {
+    public HttpRespMsg initSystem(String corpid) throws ApiException;
+
     public void corpAuth(String corpid, String corpName, String authUserId, Long agentId) throws ApiException;
 
     public String syncCorpMembs(String corpid) throws ApiException;
@@ -35,4 +40,12 @@ public interface DingDingService {
 //    public HttpRespMsg getLeaveTypeList(String leaveCode, Integer companyId, Integer departmentId, String userId, Integer pageIndex);
 
     public HttpRespMsg syncLeaveQuotaData(Integer companyId);
+
+    HttpRespMsg removeCompInfo(String corpid);
+
+    HttpRespMsg initSuperManager(String corpid, String name);
+
+    void userLeaveOrg(String corpId, JSONArray userIdArray, LocalDate leaveDate);
+
+    void userAddOrg(String corpId, JSONArray userIdArray);
 }

+ 57 - 20
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/CompanyDingdingServiceImpl.java

@@ -60,31 +60,39 @@ public class CompanyDingdingServiceImpl extends ServiceImpl<CompanyDingdingMappe
     private SysConfigMapper sysConfigMapper;
     @Value("${dingding.appId}")
     private long appId;//钉钉第三方应用的appId
+    @Value("${configEnv.isPrivateDeploy}")
+    private boolean isPrivateDeploy;//是否是私有化部署,企业内部应用
+
 
     @Override
     public void sendFillReportAlertMsg(Integer companyId, Long agentId, String msg, String useridList) {
-        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/sendbytemplate");
-        OapiMessageCorpconversationSendbytemplateRequest req = new OapiMessageCorpconversationSendbytemplateRequest();
-        System.out.println("发送AlertMsg=="+msg+", agentId="+agentId);
-        CompanyDingding dingding = getOne(new QueryWrapper<CompanyDingding>().eq("company_id", companyId));
-        req.setAgentId(agentId);
+        if (isPrivateDeploy) {
+
+
+        } else {
+            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/sendbytemplate");
+            OapiMessageCorpconversationSendbytemplateRequest req = new OapiMessageCorpconversationSendbytemplateRequest();
+            System.out.println("发送AlertMsg=="+msg+", agentId="+agentId);
+            CompanyDingding dingding = getOne(new QueryWrapper<CompanyDingding>().eq("company_id", companyId));
+            req.setAgentId(agentId);
 //        req.setDeptIdList("421897262");
-        req.setUseridList(useridList);
-        req.setTemplateId(TEMPLATE_ALERT_REPORT);
-        JSONObject json = new JSONObject();
-        json.put("APPID", ""+appId);
-        json.put("CORPID", dingding.getCorpid());
-        json.put("msg", msg);
-        req.setData(json.toJSONString());
-        OapiMessageCorpconversationSendbytemplateResponse rsp = null;
-        try {
-            rsp = client.execute(req, getCorpAccessToken(dingding));
-        } catch (ApiException e) {
-            e.printStackTrace();
-        } catch (Exception exception) {
-            exception.printStackTrace();
+            req.setUseridList(useridList);
+            req.setTemplateId(TEMPLATE_ALERT_REPORT);
+            JSONObject json = new JSONObject();
+            json.put("APPID", ""+appId);
+            json.put("CORPID", dingding.getCorpid());
+            json.put("msg", msg);
+            req.setData(json.toJSONString());
+            OapiMessageCorpconversationSendbytemplateResponse rsp = null;
+            try {
+                rsp = client.execute(req, getCorpAccessToken(dingding));
+            } catch (ApiException e) {
+                e.printStackTrace();
+            } catch (Exception exception) {
+                exception.printStackTrace();
+            }
+            System.out.println(rsp.getBody());
         }
-        System.out.println(rsp.getBody());
     }
 
     @Override
@@ -247,6 +255,8 @@ public class CompanyDingdingServiceImpl extends ServiceImpl<CompanyDingdingMappe
         System.out.println(rsp.getBody());
     }
 
+
+
     @Override
     public void sendOAMsg(CompanyDingding dingding, String useridList, HashMap map) {
         DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
@@ -310,6 +320,33 @@ public class CompanyDingdingServiceImpl extends ServiceImpl<CompanyDingdingMappe
         System.out.println(rsp.getBody());
     }
 
+    @Override
+    public void sendInnerLinkMsg(CompanyDingding dingding, String useridList, String title, String alertMsg) {
+        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
+        OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();
+        request.setAgentId(dingding.getAgentId());
+        request.setUseridList(useridList);
+        request.setToAllUser(false);
+
+        OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
+
+        msg.setMsgtype("link");
+        msg.setLink(new OapiMessageCorpconversationAsyncsendV2Request.Link());
+        msg.getLink().setTitle(title);
+        msg.getLink().setText(alertMsg);
+        msg.getLink().setMessageUrl("dingtalk://dingtalkclient/action/openapp?corpid="+dingding.getCorpid()
+                +"&container_type=work_platform&app_id=0_"+dingding.getAgentId()+"&redirect_type=jump&redirect_url=");
+        request.setMsg(msg);
+
+        OapiMessageCorpconversationAsyncsendV2Response rsp = null;
+        try {
+            rsp = client.execute(request, getCorpAccessToken(dingding));
+        } catch (Exception exception) {
+            exception.printStackTrace();
+        }
+        System.out.println(rsp.getBody());
+    }
+
     private String getDDSuiteAccessToken() throws ApiException {
         if (DingDingServiceImpl.SUITE_ACCESS_TOKEN == null || DingDingServiceImpl.suiteTokenExpireTime < System.currentTimeMillis()) {
             DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/service/get_suite_token");

+ 209 - 178
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/DingDingServiceImpl.java

@@ -125,9 +125,58 @@ public class DingDingServiceImpl implements DingDingService {
     private boolean isPrivateDeploy;//企业内部应用,私有化部署的情况
     @Value("${dingding.appId}")
     private long appId;//钉钉第三方应用的appId
+
     @Value("${configEnv.isDev}")
     private boolean isDev;//是否是本地开发环境
 
+    @Override
+    public synchronized HttpRespMsg initSystem(String corpid) throws ApiException {
+        System.out.println("========接收到initSystem请求===corpid="+corpid);
+        HttpRespMsg msg = new HttpRespMsg();
+        if (!isPrivateDeploy) {
+            msg.setError("请配置isPrivateDeploy: true");
+        } else {
+            //查找公司对应的记录是否已经添加
+            CompanyDingding dingding = companyDingdingMapper.selectById(corpid);
+            if (dingding == null) {
+                msg.setError("请在company_dingding表中增加corpid:" + corpid);
+            } else if (dingding.getCompanyId() != null) {
+                msg.setError("companyId已存在,如需重新初始化请先重置company_dingding中该条数据的companyId为null");
+            } else {
+
+                Company company = new Company().setCompanyName(dingding.getCorpName())
+                        .setExpirationDate(LocalDateTime.now().plusDays(15));
+                company.setPackageProject(1);
+                company.setPackageExpense(1);
+                company.setPackageCustomer(1);
+                company.setPackageOa(1);
+                companyMapper.insert(company);
+                dingding.setCompanyId(company.getId());
+                companyDingdingMapper.updateById(dingding);
+                //生成工作时长
+                TimeType timeType = new TimeType();
+                timeType.setCompanyId(company.getId());
+                timeTypeMapper.insert(timeType);
+
+                SysRole smanager = sysRoleService.generateDefaultRoles(company.getId());
+
+                //生成项目的成本基线默认条目
+                String[] array = Constant.DEFAULT_BASE_COST_ITEMS;
+                for (String baseItem : array) {
+                    ProjectBasecostSetting setting = new ProjectBasecostSetting();
+                    setting.setName(baseItem);
+                    setting.setCompanyId(company.getId());
+                    projectBasecostSettingMapper.insert(setting);
+                }
+
+                //获取企业内部应用accessToken
+                String innerCorpToken = getInnerCorpToken(dingding);
+                getAuthedDeptsAndUsers(dingding, innerCorpToken);
+            }
+        }
+        return msg;
+    }
+
     @Override
     @Async
     public void corpAuth(String corpid, String corpName, String authUserId, Long agentId) throws ApiException {
@@ -237,40 +286,41 @@ public class DingDingServiceImpl implements DingDingService {
             System.out.println("corpid不存在=="+corpid);
             return "调用失败:corpid不存在==";
         }
-        if (dingding.getExpireTime().isBefore(LocalDateTime.now())) {
-            SysConfig config = sysConfigMapper.selectOne(new QueryWrapper<SysConfig>().eq("param_key", "dingding_suite_ticket"));
-            OapiServiceGetCorpTokenResponse result = getAuthCorpAccessToken(corpid, config.getParamValue());
-            if (result != null) {
-                if (result.getErrcode() == 0L) {
-                    //返回成功
-                    dingding.setAccessToken(result.getAccessToken());
-                    LocalDateTime time = LocalDateTime.now();
-                    time = time.plusSeconds(result.getExpiresIn());//设置token过期时间
-                    dingding.setExpireTime(time);
-                    companyDingdingMapper.updateById(dingding);
+        if (isPrivateDeploy) {
+            //私有化部署,取innerToken
+            accessToken = getInnerCorpToken(dingding);
+        } else {
+            if (dingding.getExpireTime().isBefore(LocalDateTime.now())) {
+                SysConfig config = sysConfigMapper.selectOne(new QueryWrapper<SysConfig>().eq("param_key", "dingding_suite_ticket"));
+                OapiServiceGetCorpTokenResponse result = getAuthCorpAccessToken(corpid, config.getParamValue());
+                if (result != null) {
+                    if (result.getErrcode() == 0L) {
+                        //返回成功
+                        dingding.setAccessToken(result.getAccessToken());
+                        LocalDateTime time = LocalDateTime.now();
+                        time = time.plusSeconds(result.getExpiresIn());//设置token过期时间
+                        dingding.setExpireTime(time);
+                        companyDingdingMapper.updateById(dingding);
 
-                    accessToken = dingding.getAccessToken();
-                } else {
-                    System.out.println(result.getBody());
+                        accessToken = dingding.getAccessToken();
+                    } else {
+                        System.out.println(result.getBody());
+                    }
                 }
+            } else {
+                accessToken = dingding.getAccessToken();
             }
-        } else {
-            accessToken = dingding.getAccessToken();
         }
+
         if (accessToken == null) {
             System.out.println("获取第三方企业accessToke失败");
             return "调用失败";
         } else {
             System.out.println("syncCorpMembs 开始获取部门, accessToken="+accessToken);
-
             //获取授权的部门
             getAuthedDeptsAndUsers(dingding, accessToken);
             return "调用成功";
         }
-
-
-//        String rest = getDepartmentList(dingding.getCompanyId(), corpid, accessToken, 1L, null);
-
     }
 
     private void getAuthedDeptsAndUsers(CompanyDingding dingding, String accessToken) {
@@ -381,12 +431,14 @@ public class DingDingServiceImpl implements DingDingService {
      */
     private String getInnerCorpToken(CompanyDingding dingding) throws ApiException {
         if (dingding.getInnerToken() == null || LocalDateTime.now().isAfter(dingding.getInnerExpireTime())) {
-            DefaultDingTalkClient client= new DefaultDingTalkClient("https://oapi.dingtalk.com/service/get_corp_token");
-            OapiServiceGetCorpTokenRequest req= new OapiServiceGetCorpTokenRequest();
-            req.setAuthCorpid(dingding.getCorpid());
-            OapiServiceGetCorpTokenResponse response= client.execute(req,dingding.getCustomAppkey(),dingding.getCustomAppsecret(),"anything");
+            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
+            OapiGettokenRequest request = new OapiGettokenRequest();
+            request.setAppkey(dingding.getInnerAppkey());
+            request.setAppsecret(dingding.getInnerAppsecret());
+            request.setHttpMethod("GET");
+            OapiGettokenResponse response = client.execute(request);
             if (!response.isSuccess()) {
-                System.err.println("获取企业内部token:"+response.getErrorCode()+":"+response.getErrmsg());
+                System.err.println("获取企业内部token失败:"+response.getErrorCode()+":"+response.getErrmsg());
             }
             dingding.setInnerToken(response.getAccessToken());
             dingding.setInnerExpireTime(LocalDateTime.now().plusSeconds(response.getExpiresIn()));
@@ -430,10 +482,18 @@ public class DingDingServiceImpl implements DingDingService {
         OapiV2UserGetuserinfoRequest req = new OapiV2UserGetuserinfoRequest();
         req.setCode(code);
         //获取有效的accessToken
-        String accessToken = getValidCorpAccessToken(corpid);
+
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         OapiV2UserGetuserinfoResponse rsp = null;
         try {
+            String accessToken = null;
+            if (isPrivateDeploy) {
+                CompanyDingding companyDingding = companyDingdingMapper.selectById(corpid);
+                accessToken = getInnerCorpToken(companyDingding);
+            } else {
+                accessToken = getValidCorpAccessToken(corpid);
+            }
+
             rsp = client.execute(req, accessToken);
             System.out.println(rsp.getBody());
             JSONObject json = JSONObject.parseObject(rsp.getBody());
@@ -752,6 +812,54 @@ public class DingDingServiceImpl implements DingDingService {
         }
     }
 
+    private void getAddUserDetail(CompanyDingding dingding, String dingdingUserid, String access_token) throws ApiException {
+        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
+        OapiV2UserGetRequest req = new OapiV2UserGetRequest();
+        req.setUserid(dingdingUserid);
+        req.setLanguage("zh_CN");
+        OapiV2UserGetResponse rsp = client.execute(req, access_token);
+//        System.out.println(rsp.getBody());
+        JSONObject resp = JSONObject.parseObject(rsp.getBody());
+        if (resp.getInteger("errcode") == 0) {
+            JSONObject userJson = resp.getJSONObject("result");
+            User user = new User();
+            SysRole defaultRole = sysRoleMapper.selectOne(
+                    new QueryWrapper<SysRole>().eq("company_id", dingding.getCompanyId()).eq("is_default", 1));
+
+            user.setId(SnowFlake.nextId() + "")
+                    .setRoleId(defaultRole.getId())
+                    .setRoleName(defaultRole.getRolename())
+                    .setCompanyId(dingding.getCompanyId())
+                    .setName(userJson.getString("name"))
+                    .setDingdingUserid(dingdingUserid)
+                    .setDingdingUnionid(userJson.getString("unionid"))
+                    .setColor(ColorUtil.randomColor());
+            JSONArray dingdingDeptIds = userJson.getJSONArray("dept_id_list");
+            if (dingdingDeptIds.size() > 0) {
+                //取最后一个部门,一般是最末级部门
+                Integer dpId = dingdingDeptIds.getInteger(dingdingDeptIds.size()-1);
+                DepartmentDingding departmentDingding = departmentDingdingMapper.selectOne(new QueryWrapper<DepartmentDingding>().eq("corpid", dingding.getCorpid())
+                        .eq("dd_deptid", dpId));
+                if (departmentDingding != null) {
+                    Integer departmentId = departmentDingding.getSysDeptid();
+                    if (departmentId != null) {
+                        user.setDepartmentId(departmentDingding.getSysDeptid());
+                        user.setDepartmentCascade(convertDepartmentIdToCascade(departmentId));
+                    }
+                }
+            }
+            //检查用户是否已经存在
+            synchronized (userLock) {
+                List<User> oldList = userMapper.selectList(new QueryWrapper<User>().eq("dingding_userid", dingdingUserid).eq("company_id", dingding.getCompanyId()));
+                if (oldList.size() == 0) {
+                    System.out.println("监听变化,主动新增钉钉用户==" + user.getName());
+                    userMapper.insert(user);
+                }
+            }
+        }
+    }
+
+
     //获取人员详情
     private void getUserDetail(int roleId, String roleName, Integer companyId, Integer departmentId, String dingdingUserid, String access_token) throws ApiException {
         DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
@@ -1364,51 +1472,6 @@ public class DingDingServiceImpl implements DingDingService {
         }
     }
 
-//    public HttpRespMsg getLeaveTypeList(String leaveCode, Integer companyId, Integer departmentId, String userId, Integer pageIndex) {
-//        CompanyDingding dingding = companyDingdingMapper.selectOne(new QueryWrapper<CompanyDingding>().eq("company_id", companyId));
-//        HttpRespMsg msg = new HttpRespMsg();
-//        HashMap resultMap = new HashMap();
-//        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/attendance/vacation/type/list");
-//        OapiAttendanceVacationTypeListRequest req = new OapiAttendanceVacationTypeListRequest();
-//        List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId).eq("role_name", "超级管理员"));
-////        String oaManagerDid = "2221645448842951";
-//        String oaManagerDid = userList.get(0).getDingdingUserid();
-//        if (leaveCode == null) {
-//            req.setOpUserid(oaManagerDid);
-//            req.setVacationSource("all");
-//            OapiAttendanceVacationTypeListResponse rsp = null;
-//            try {
-//                rsp = client.execute(req, getInnerCorpToken(dingding));
-//                System.out.println(rsp.getBody());
-//                JSONObject json = JSONObject.parseObject(rsp.getBody());
-//                JSONArray result = json.getJSONArray("result");
-//                List<LeaveTypeVO> typeList = new ArrayList<>();
-//                LeaveTypeVO defaultType = null;
-//                for (int i=0;i<result.size(); i++) {
-//                    JSONObject obj = result.getJSONObject(i);
-//                    LeaveTypeVO vo = new LeaveTypeVO();
-//                    vo.leaveCode = obj.getString("leave_code");
-//                    vo.leaveName = obj.getString("leave_name");
-//                    if (vo.leaveName.equals("调休")) {
-//                        defaultType = vo;
-//                    }
-//                    typeList.add(vo);
-//                }
-//                resultMap.put("leaveTypeList", typeList);
-//                if (defaultType == null) defaultType = typeList.get(0);
-//                leaveCode = defaultType.leaveCode;
-//                resultMap.put("defaultLeaveType", defaultType);
-//                System.out.println("本次请求的LeaveCode: "+leaveCode);
-//                reqQuotaList(companyId, dingding, leaveCode, oaManagerDid, departmentId, userId, pageIndex, resultMap);
-//            } catch (ApiException e) {
-//                e.printStackTrace();
-//            }
-//        } else {
-//            reqQuotaList(companyId, dingding, leaveCode, oaManagerDid, departmentId, userId, pageIndex, resultMap);
-//        }
-//        msg.data = resultMap;
-//        return msg;
-//    }
 
     @Override
     public HttpRespMsg syncLeaveQuotaData(Integer companyId) {
@@ -1424,6 +1487,8 @@ public class DingDingServiceImpl implements DingDingService {
         OapiAttendanceVacationTypeListResponse rsp = null;
         try {
             rsp = client.execute(req, getInnerCorpToken(dingding));
+            System.out.println(rsp.getBody());
+            System.out.println(rsp.getErrcode()+":"+rsp.getErrmsg());
             JSONObject json = JSONObject.parseObject(rsp.getBody());
             JSONArray result = json.getJSONArray("result");
             List<LeaveType> typeList = new ArrayList<>();
@@ -1464,6 +1529,78 @@ public class DingDingServiceImpl implements DingDingService {
         return new HttpRespMsg();
     }
 
+    @Override
+    public HttpRespMsg removeCompInfo(String corpid) {
+        HttpRespMsg msg = new HttpRespMsg();
+        CompanyDingding dingding = companyDingdingMapper.selectById(corpid);
+        Integer companyId = dingding.getCompanyId();
+        departmentMapper.delete(new QueryWrapper<Department>().eq("company_id", companyId));
+        departmentDingdingMapper.delete(new QueryWrapper<DepartmentDingding>().eq("corpid", corpid));
+        userMapper.delete(new QueryWrapper<User>().eq("company_id", companyId));
+        sysRoleMapper.delete(new QueryWrapper<SysRole>().eq("company_id", companyId));
+        //sysRoleFunction和sysRoleModule表会级联删除
+        projectBasecostSettingMapper.delete(new QueryWrapper<ProjectBasecostSetting>().eq("company_id", companyId));
+        companyMapper.deleteById(companyId);
+        return msg;
+    }
+
+    @Override
+    public HttpRespMsg initSuperManager(String corpid, String name) {
+        HttpRespMsg msg = new HttpRespMsg();
+        CompanyDingding dingding = companyDingdingMapper.selectById(corpid);
+        Integer companyId = dingding.getCompanyId();
+        User user = userMapper.selectOne(new QueryWrapper<User>().eq("name", name).eq("company_id", companyId));
+        if (user == null) {
+            msg.setError("该用户不存在: " + name);
+        } else {
+            SysRole role = sysRoleMapper.selectOne(new QueryWrapper<SysRole>().eq("company_id", companyId).eq("rolename", "超级管理员"));
+            user.setPhone(user.getName());
+            user.setPassword(MD5Util.getPassword("000000"));
+            user.setRoleId(role.getId());
+            user.setRoleName(role.getRolename());
+            userMapper.updateById(user);
+        }
+        return msg;
+    }
+
+    @Override
+    public void userLeaveOrg(String corpId, JSONArray userIdArray, LocalDate leaveDate) {
+        //员工离职,对其标记为离职状态
+        CompanyDingding companyDingding = companyDingdingMapper.selectById(corpId);
+        for (int i=0;i<userIdArray.size(); i++) {
+            String userdingId = userIdArray.getString(i);
+            User user = userMapper.selectOne(new QueryWrapper<User>().eq("company_id", companyDingding.getCompanyId()).eq("dingding_userid", userdingId));
+            if (user != null) {
+                user.setIsActive(0);
+                user.setInactiveDate(leaveDate);
+                userMapper.updateById(user);
+            }
+        }
+    }
+
+    @Override
+    public void userAddOrg(String corpId, JSONArray userIdArray) {
+        //添加了员工,检测是否在我们已经授权的范围内
+        CompanyDingding companyDingding = companyDingdingMapper.selectById(corpId);
+        for (int i=0;i<userIdArray.size(); i++) {
+            String userdingId = userIdArray.getString(i);
+            User user = userMapper.selectOne(new QueryWrapper<User>().eq("company_id", companyDingding.getCompanyId()).eq("dingding_userid", userdingId));
+            if (user == null) {
+                //添加人员
+                try {
+                    String corpAccessToken = getInnerCorpToken(companyDingding);
+                    getAddUserDetail(companyDingding, userdingId, corpAccessToken);
+                } catch (ApiException e) {
+                    e.printStackTrace();
+                }
+            } else {
+                //已存在,更新状态
+                user.setIsActive(1);
+                userMapper.updateById(user);
+            }
+        }
+    }
+
 
     //同步公司全部人员的假期余额
     private void syncQuotaList(String leaveCode,String oaManagerDid, CompanyDingding dingding, List<User> userList, long offset) {
@@ -1537,112 +1674,6 @@ public class DingDingServiceImpl implements DingDingService {
             }
         }
     }
-//
-//    private void reqQuotaList(Integer companyId, CompanyDingding dingding,
-//                                             String leaveCode, String oaManagerDid, Integer departmentId, String userId, Integer pageIndex, HashMap resultMap) {
-//        //再调用查看假期余额的接口
-//        long pageSize = 50L;
-//        DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/attendance/vacation/quota/list");
-//        OapiAttendanceVacationQuotaListRequest quoataReq = new OapiAttendanceVacationQuotaListRequest();
-//        quoataReq.setLeaveCode(leaveCode);
-//        quoataReq.setOpUserid(oaManagerDid);
-//        List<User> userList = null;
-//        String userIds = null;
-//        if (StringUtils.isEmpty(userId)) {
-//            int total = 0;
-//            if (departmentId == null) {
-//                //全部员工,包括离职的
-//                QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
-//                queryWrapper.select("distinct dingding_userid, name").eq("company_id", companyId);
-//                userList = userMapper.selectList(queryWrapper);
-//                total = userList.size();
-//            } else {
-//                //指定部门
-//                Department dept = departmentMapper.selectById(departmentId);
-//                List<Department> allDept = departmentMapper.selectList(new QueryWrapper<Department>().eq("company_id", companyId));
-//                List<Department> allSubDepts = getSubDeptList(allDept, dept);
-//                userList = userMapper.selectList(
-//                        new QueryWrapper<User>().select("distinct dingding_userid, name")
-//                                .in("department_id", allSubDepts.stream().map(Department::getDepartmentId).collect(Collectors.toList())));
-//                total = userList.size();
-//            }
-//            String collect = userList.stream().map(User::getDingdingUserid).collect(Collectors.joining(","));
-//            userIds = collect;
-//            resultMap.put("total", total);
-//        } else {
-//            userList = new ArrayList<>();
-//            userList = userMapper.selectList(new QueryWrapper<User>().in("id", ListUtil.convertLongIdsArrayToList(userId)));
-//            userIds = userList.stream().map(User::getDingdingUserid).collect(Collectors.joining(","));
-//            resultMap.put("total", userList.size());
-//        }
-//
-//        System.out.println("请求的size="+userList.size());
-//        System.out.println("长度=="+userIds.length());
-//        List<LeaveQuotaNum> quotaNumList = new ArrayList<>();
-//        for (User user : userList) {
-//            LeaveQuotaNum quotaNum = new LeaveQuotaNum();
-//            quotaNum.userDingdingId = user.getDingdingUserid();
-//            quotaNum.name = user.getName();
-//            quotaNum.leaveCode = leaveCode;
-//            quotaNumList.add(quotaNum);
-//        }
-//
-//        if (quotaNumList.size() == 0) {
-//            //无员工数据了
-//            return;
-//        }
-//        quoataReq.setUserids(userIds);
-//        quoataReq.setOffset(0L);
-//        quoataReq.setSize(pageSize);
-//        OapiAttendanceVacationQuotaListResponse quotaListResponse = null;
-//        try {
-//            quotaListResponse = client.execute(quoataReq, getInnerCorpToken(dingding));
-//        } catch (ApiException e) {
-//            e.printStackTrace();
-//        }
-//        System.out.println(quotaListResponse.getBody()+":"+quotaListResponse.getErrmsg());
-//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-//        JSONObject json = JSONObject.parseObject(quotaListResponse.getBody());
-//        DecimalFormat df = new DecimalFormat("#0.0");
-//        if (json.getInteger("errcode") == 0) {
-//            JSONObject result = json.getJSONObject("result");
-//            JSONArray leaveQuotas = result.getJSONArray("leave_quotas");
-//            if (leaveQuotas != null) {
-//                for (int i=0;i<leaveQuotas.size(); i++) {
-//                    JSONObject jsonObject = leaveQuotas.getJSONObject(i);
-//                    String userDDid = jsonObject.getString("userid");
-//                    for (LeaveQuotaNum quotaNum : quotaNumList) {
-//                        if (quotaNum.userDingdingId.equals(userDDid)) {
-//                            Date startDate = new Date(jsonObject.getLongValue("start_time"));
-//                            quotaNum.startTime = sdf.format(startDate);
-//                            Date endDate = new Date(jsonObject.getLongValue("end_time"));
-//                            quotaNum.endTime = sdf.format(endDate);
-//                            Integer quota_num_per_hour = jsonObject.getInteger("quota_num_per_hour");
-//                            if (quota_num_per_hour != null) {
-//                                //按小时为单位的情况
-//                                quotaNum.quotaInHours = df.format(quota_num_per_hour*1.0/100);
-//                                Integer used_num_per_hour = jsonObject.getInteger("used_num_per_hour");
-//                                quotaNum.usedInHours = df.format(used_num_per_hour*1.0/100);
-//                                //计算剩余
-//                                quotaNum.leftInHours = df.format((quota_num_per_hour - used_num_per_hour)*1.0/100);
-//                            } else {
-//                                //按天单位的情况
-//                                Integer quota_num_per_day = jsonObject.getInteger("quota_num_per_day");
-//                                quotaNum.quotaInDays = df.format(quota_num_per_day*1.0/100);
-//                                Integer used_num_per_day = jsonObject.getInteger("used_num_per_day");
-//                                quotaNum.usedInDays = df.format(used_num_per_day*1.0/100);
-//                                //计算剩余
-//                                quotaNum.leftInDays = df.format((quota_num_per_day - used_num_per_day)*1.0/100);
-//                            }
-//                            System.out.println(quotaNum.name+" 假期额度="+quotaNum.quotaInDays);
-//                            break;
-//                        }
-//                    }
-//                }
-//                resultMap.put("records", quotaNumList);
-//            }
-//        }
-//    }
 
     public void activateSuite(String authCorpid, String tmpAuthCode) throws ApiException {
         DingTalkClient client= new DefaultDingTalkClient("https://oapi.dingtalk.com/service/activate_suite?suite_access_token=" + getDDSuiteAccessToken());

+ 5 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -859,7 +859,11 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             if (functionList.size() == 0) {//没有全员审核的权限
                 leaderId = curUser.getId();
             }
-            List<Map<String, Object>> auditReportList = reportMapper.getAuditReportList(date, companyId, departmentId, projectId, leaderId, isEngeering, startDate, endDate, userId);
+            List<String> targetUids = null;
+            if (!StringUtils.isEmpty(userId)) {
+                targetUids = ListUtil.convertLongIdsArrayToList(userId);
+            }
+            List<Map<String, Object>> auditReportList = reportMapper.getAuditReportList(date, companyId, departmentId, projectId, leaderId, isEngeering, startDate, endDate, targetUids);
             //抽取姓名,进行分组
             List<Map<String, Object>> nameList = new ArrayList<Map<String, Object>>();
             Map<String, Object> lastName = null;

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

@@ -1282,9 +1282,11 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
             //返回生成的文件地址/upload文件夹下
             httpRespMsg.data = "/upload/" + fileUrlSuffix;
         } catch (NullPointerException e) {
+            e.printStackTrace();
             httpRespMsg.setError("验证失败或缺少数据");
             return httpRespMsg;
         } catch (IOException e) {
+            e.printStackTrace();
             httpRespMsg.setError("文件生成错误");
             return httpRespMsg;
         }

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

@@ -145,7 +145,7 @@ public class TimingTask {
         List<Integer> compIds = timeTypeList.stream().map(TimeType::getCompanyId).collect(Collectors.toList());
         //企业内部应用才有权限调用
         List<CompanyDingding> dingdingList = companyDingdingService.list(new QueryWrapper<CompanyDingding>().in("company_id", compIds)
-                .isNotNull("custom_appkey"));
+                .isNotNull("inner_appkey"));
         System.out.println("==========获取钉钉内部应用的数量是:"+dingdingList.size());
         if (dingdingList.size() > 0) {
             DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
@@ -268,7 +268,7 @@ public class TimingTask {
         List<Integer> companyIds = timeTypes.stream().map(TimeType::getCompanyId).collect(Collectors.toList());
         List<CompanyDingding> dingdingList = companyDingdingService.list(
                 new QueryWrapper<CompanyDingding>().in("company_id", companyIds)
-                    .isNotNull("custom_appkey"));
+                    .isNotNull("inner_appkey"));
         //每分钟5000条,待后续处理
         for (CompanyDingding dingding : dingdingList) {
             List<BusinessTrip> businessTrips = businessTripMapper.selectList(new QueryWrapper<BusinessTrip>().eq("company_id", dingding.getCompanyId())

+ 1 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/ExcelUtil.java

@@ -9,6 +9,7 @@ import java.io.File;
 import java.io.FileOutputStream;
 import java.io.OutputStream;
 import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
 import java.util.List;
 
 public class ExcelUtil {

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

@@ -13,7 +13,7 @@ spring:
       max-request-size: 100MB
   datasource:
     driver-class-name: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://127.0.0.1:3306/man_dev?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&rewriteBatchedStatements=true
+    url: jdbc:mysql://127.0.0.1:3306/man_dev?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&&useSSL=false
     username: root
     password: HuoshiDB@2022
     hikari:

+ 6 - 8
fhKeeper/formulahousekeeper/management-platform/src/main/resources/application-mld.yml

@@ -1,4 +1,3 @@
-# 重庆美莱德服务器配置
 server:
   port: 10010
   tomcat:
@@ -14,9 +13,9 @@ spring:
       max-request-size: 100MB
   datasource:
     driver-class-name: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://10.1.10.33:3306/man_mld?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&rewriteBatchedStatements=true
+    url: jdbc:mysql://127.0.0.1:3306/man_private?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&&useSSL=false
     username: root
-    password: Mld2022@#
+    password: HuoshiDB@2022
     hikari:
       maximum-pool-size: 10
       minimum-idle: 3
@@ -26,7 +25,7 @@ spring:
     # redis
     redis:
       host: 127.0.0.1
-      port: 6379
+      port: 6479
       timeout: 3
       # password:
       pool:
@@ -84,9 +83,6 @@ upload:
   path: /www/staticproject/timesheet/upload/
 
 
-
-
-
 ##actuator健康检查配置
 management:
   security:
@@ -103,4 +99,6 @@ management:
       enabled: false
 
 configEnv:
-  isDev: false
+  isDev: true
+  # 是否是私有化部署,企业内部应用
+  isPrivateDeploy: true

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

@@ -14,7 +14,7 @@ spring:
       location: C:/upload/
   datasource:
     driver-class-name: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://47.101.180.183:3306/man_dev?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&rewriteBatchedStatements=true
+    url: jdbc:mysql://47.101.180.183:3306/man_dev?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&useSSL=false
     username: root
     password: HuoshiDB@2022
     hikari:
@@ -122,6 +122,8 @@ referer:
     - mobworktime.ttkuaiban.com
     - worktime.ttkuaiban.com
     - app71020.eapps.dingtalkcloud.com
+    - mldmobworktime.ttkuaiban.com
+    - mldworktime.ttkuaiban.com
 excludeUrls: /wxcorp/*,/wxcorp/*/*,/dingding/*,/error,/testClient,/corpWXAuth,/wx-corp-info/*,/clean/*,/innerRoles/*
 
 #企业微信相关参数

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

@@ -12,15 +12,15 @@
         <result column="access_token" property="accessToken" />
         <result column="expire_time" property="expireTime" />
         <result column="agent_id" property="agentId" />
-        <result column="custom_appkey" property="customAppkey" />
-        <result column="custom_appsecret" property="customAppsecret" />
+        <result column="inner_appkey" property="innerAppkey" />
+        <result column="inner_appsecret" property="innerAppsecret" />
         <result column="inner_token" property="innerToken" />
         <result column="inner_expire_time" property="innerExpireTime" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        corpid, corp_name, auth_user_id, indate, company_id, access_token, expire_time, agent_id, custom_appkey, custom_appsecret, inner_token, inner_expire_time
+        corpid, corp_name, auth_user_id, indate, company_id, access_token, expire_time, agent_id, inner_appkey, inner_appsecret, inner_token, inner_expire_time
     </sql>
 
 </mapper>

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

@@ -288,8 +288,11 @@
         <if test="date != null and date != ''">
             AND a.create_date=#{date}
         </if>
-        <if test="targetUserId != null and targetUserId != ''">
-            AND a.creator_id=#{targetUserId}
+        <if test="targetUserId != null">
+            AND a.creator_id in
+            <foreach collection="targetUserId" item="tid" separator="," open="(" close=")" index="index">
+            #{tid}
+            </foreach>
         </if>
         <if test="startDate != null and startDate != '' and endDate != null and endDate != ''">
             AND a.create_date between #{startDate} and #{endDate}

TEMPAT SAMPAH
fhKeeper/formulahousekeeper/management-platform/src/main/resources/upload/人员导入模板.xlsx


TEMPAT SAMPAH
fhKeeper/formulahousekeeper/management-platform/src/main/resources/upload/员工工时导入模板.xlsx


TEMPAT SAMPAH
fhKeeper/formulahousekeeper/management-platform/src/main/resources/upload/员工工时统计模板.xlsx


TEMPAT SAMPAH
fhKeeper/formulahousekeeper/management-platform/src/main/resources/upload/员工项目分摊比例导入模板.xlsx


TEMPAT SAMPAH
fhKeeper/formulahousekeeper/management-platform/src/main/resources/upload/工时管家使用说明_基础版.docx


TEMPAT SAMPAH
fhKeeper/formulahousekeeper/management-platform/src/main/resources/upload/工时管家使用说明_建筑工程专业版.docx


TEMPAT SAMPAH
fhKeeper/formulahousekeeper/management-platform/src/main/resources/upload/工时管家使用说明_项目管理专业版.docx


TEMPAT SAMPAH
fhKeeper/formulahousekeeper/management-platform/src/main/resources/upload/新增客户导入模板.xlsx


TEMPAT SAMPAH
fhKeeper/formulahousekeeper/management-platform/src/main/resources/upload/研究中心导入模板.xlsx


TEMPAT SAMPAH
fhKeeper/formulahousekeeper/management-platform/src/main/resources/upload/资源需求导入模板.xlsx


TEMPAT SAMPAH
fhKeeper/formulahousekeeper/management-platform/src/main/resources/upload/项目任务导入模板.xlsx


TEMPAT SAMPAH
fhKeeper/formulahousekeeper/management-platform/src/main/resources/upload/项目导入模板.xlsx


+ 1 - 1
fhKeeper/formulahousekeeper/timesheet_h5/public/index.html

@@ -44,7 +44,7 @@
             if(urls.indexOf('mobworktime.ttkuaiban') != '-1') {
                 location.href = 'https://worktime.ttkuaiban.com';
             } else {
-                location.href = 'http://183.66.166.222:9097/';
+                location.href = 'http://mldworktime.ttkuaiban.com:9097/';
             }
         }
     </script>