diff --git a/base-webapp/pom.xml b/base-webapp/pom.xml
index 79bd4cf9..15a885ff 100644
--- a/base-webapp/pom.xml
+++ b/base-webapp/pom.xml
@@ -28,11 +28,11 @@
-
-
-
-
-
+
+ com.hzya.frame
+ fw-dd
+ ${revision}
+
diff --git a/fw-dd/pom.xml b/fw-dd/pom.xml
new file mode 100644
index 00000000..ebf7aeec
--- /dev/null
+++ b/fw-dd/pom.xml
@@ -0,0 +1,48 @@
+
+
+
+ kangarooDataCenterV3
+ com.hzya.frame
+ ${revision}
+
+ 4.0.0
+ fw-dd
+ jar
+ ${revision}
+
+
+
+ com.hzya.frame
+ base-service
+ ${revision}
+
+
+ mysql
+ mysql-connector-java
+ ${mysql-connector-java}
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ none
+ execute
+ true
+
+
+
+
+ repackage
+
+
+
+
+
+
+
diff --git a/fw-dd/src/main/java/com/hzya/frame/dd/IDDInterfaceService.java b/fw-dd/src/main/java/com/hzya/frame/dd/IDDInterfaceService.java
new file mode 100644
index 00000000..604f8a6f
--- /dev/null
+++ b/fw-dd/src/main/java/com/hzya/frame/dd/IDDInterfaceService.java
@@ -0,0 +1,31 @@
+package com.hzya.frame.dd;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.dynamic.datasource.annotation.DSTransactional;
+import com.hzya.frame.web.entity.JsonResultEntity;
+import org.springframework.stereotype.Service;
+
+/***
+ * 对接钉钉相关功能接口实现类,用于内部应用调用,返回指定格式数据
+ * @content:
+ * @author 👻👻👻👻👻👻👻👻 gjh
+ * @date 2023-08-29 9:38
+ * @param
+ * @return
+ **/
+
+public interface IDDInterfaceService {
+
+ /***
+ * 推送钉钉方法
+ * @content:
+ * @author 👻👻👻👻👻👻👻👻 gjh
+ * @date 2023-08-29 9:46
+ * @param
+ * @return void
+ **/
+ String senddd(JSONObject requestJson);
+
+
+}
diff --git a/fw-dd/src/main/java/com/hzya/frame/dd/impl/DdInterfaceServiceImpl.java b/fw-dd/src/main/java/com/hzya/frame/dd/impl/DdInterfaceServiceImpl.java
new file mode 100644
index 00000000..2d4e8775
--- /dev/null
+++ b/fw-dd/src/main/java/com/hzya/frame/dd/impl/DdInterfaceServiceImpl.java
@@ -0,0 +1,165 @@
+package com.hzya.frame.dd.impl;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.hzya.frame.dd.IDDInterfaceService;
+import com.hzya.frame.web.exception.BaseSystemException;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+import org.springframework.util.ObjectUtils;
+
+
+/**
+ * @author 👻👻👻👻👻👻👻👻👻👻 gjh
+ * @version 1.0
+ * @content
+ * @date 2023-08-29 9:48
+ */
+@Service(value = "ddInterfaceService")
+public class DdInterfaceServiceImpl implements IDDInterfaceService {
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+ //TODO 此处参数暂时使用变量使用!后续应该使用应用参数动态设置
+
+ private final String appSecret = "DuRw6EEEvhGXfr6Q8wN_x4025qKjrffIGCXF9KeCKKIID-LVSsR6_8KWMei6sug1";
+ private final String appKey = "dingxewtjaserj292ggu";
+ //TODO 此处参数暂时使用变量使用!后续应该使用应用参数动态设置
+
+ @Override
+ public String senddd(JSONObject requestJson) {
+ JSONObject jsonStrObj = requestJson.getJSONObject("jsonStr");
+
+ if(ObjectUtils.isEmpty(jsonStrObj)){
+ throw new BaseSystemException("请传入jsonStr参数");
+ }
+ String code = jsonStrObj.getString("code");
+ if(StringUtils.isEmpty(code)){
+ throw new BaseSystemException("请传入接口编号参数:code");
+ }
+ String url = getDdUrlByType(code);
+ String accessTokenCode = "0001";
+ //如果请求的是token接口,不需要拼接access_token参数
+ String result = null;
+ //如果是单据接口,需要增加access_token参数,在此处定义变量赋值
+ String access_token = getToken();
+ if(accessTokenCode.equalsIgnoreCase(code)){
+ url+= "?appkey="+appKey+"&appsecret="+appSecret;
+ result = HttpUtil.get(url);
+ JSONObject jsonObject = analysisDDResult(result);
+ access_token = jsonObject.getString("access_token");
+ }else{
+ url+= "?access_token="+access_token;
+ JSONObject data = jsonStrObj.getJSONObject("data");
+ if("0004".equals(code) || "0003".equals(code)|| "0005".equals(code)){
+ logger.info("调用钉钉请求前参数:{}",data.toString());
+ if("0003".equals(code)){
+ String formInstanceId = data.getString("formInstanceId");
+ //如果表单ID不等于空走编辑动作
+ if(StrUtil.isNotEmpty(formInstanceId)){
+ result = HttpRequest.put(url).header("x-acs-dingtalk-access-token",access_token).body(data.toString()).execute().body();
+ }else{
+ result = HttpRequest.post(url).header("x-acs-dingtalk-access-token",access_token).body(data.toString()).execute().body();
+ }
+ }
+
+ logger.info("调用钉钉返回参数:{}",result);
+ }else{
+ result = HttpRequest.post(url).header("access_token",access_token).body(data.toJSONString()).execute().body();
+ }
+
+ }
+ return result;
+ }
+
+
+
+ /*****
+ * 暂时写个固定获取token方法
+ * @content:
+ * @author 👻👻👻👻👻👻👻👻 gjh
+ * @date 2023-08-29 14:52
+ * @param
+ * @return java.lang.String
+ **/
+ private String getToken(){
+ String url = getDdUrlByType("0001");
+ url+= "?appkey="+appKey+"&appsecret="+appSecret;
+ String result = HttpUtil.get(url);
+ JSONObject jsonObject = analysisDDResult(result);
+ String access_token = jsonObject.getString("access_token");
+ return access_token;
+ }
+ /****
+ * 解析钉钉接口返回的数据,转换成json对象
+ * @content:
+ * @author 👻👻👻👻👻👻👻👻 gjh
+ * @date 2023-08-29 11:55
+ * @param
+ * @return com.alibaba.fastjson.JSONObject
+ **/
+ private JSONObject analysisDDResult(String result){
+ //解析result
+ JSONObject jsonObject = JSON.parseObject(result);
+ //定义钉钉返回成功的标记
+ String okCode = "0";
+ //钉钉返回的接口成功标记
+ String errorCode = jsonObject.getString("errcode");
+ //钉钉接口返回的提示信息
+ String errmsg = jsonObject.getString("errmsg");
+ //钉钉Result
+ String ddResult = jsonObject.getString("result");
+ //如果返回值是0,则表示调用成功了
+ if(okCode.equalsIgnoreCase(errorCode)){
+ return jsonObject;
+ }else{
+ throw new BaseSystemException("调用钉钉接口失败!错误代码:"+errorCode+"错误信息:"+errmsg);
+ }
+ }
+
+
+ /*****
+ * 把所有做过的钉钉接口在此处做备注,通过给外部系统的编号获取
+ * @content:
+ * @author 👻👻👻👻👻👻👻👻 gjh
+ * @date 2023-08-29 9:54
+ * @param
+ * @return java.lang.String
+ **/
+ private String getDdUrlByType(String code){
+ StringBuffer urlBuffer = null;
+ if("0003".equals(code)|| "0004".equals(code)|| "0005".equals(code)){
+ urlBuffer = new StringBuffer("https://api.dingtalk.com");
+ }else{
+ urlBuffer = new StringBuffer("https://oapi.dingtalk.com");
+ }
+ switch (code){
+ case "0001":
+ //获取钉钉tokenURL
+ urlBuffer.append("/gettoken") ;
+ break;
+ //通知审批通过URL
+ case "0002":
+ urlBuffer.append("/topapi/attendance/approve/finish") ;
+ break;
+ //销售合同URL,无流程表单统一Url
+ case "0003":
+ urlBuffer.append("/v1.0/yida/forms/instances") ;
+ break;
+ case "0004":
+ urlBuffer.append("/v1.0/yida/forms/instances/search") ;
+ break;
+ case "0005":
+ urlBuffer.append("/v1.0/yida/forms/instances") ;
+// urlBuffer.append("/v1.0/yida/processes/instances/start") ;
+ break;
+ default:
+ throw new BaseSystemException("获取钉钉URL错误!请确认URL编号");
+ }
+ return urlBuffer.toString();
+ }
+
+}
diff --git a/fw-dd/src/main/java/com/hzya/frame/dingtalk/enums/OrgEventEnum.java b/fw-dd/src/main/java/com/hzya/frame/dingtalk/enums/OrgEventEnum.java
new file mode 100644
index 00000000..f01431f0
--- /dev/null
+++ b/fw-dd/src/main/java/com/hzya/frame/dingtalk/enums/OrgEventEnum.java
@@ -0,0 +1,48 @@
+package com.hzya.frame.dingtalk.enums;
+
+/**
+ * @Description 通讯录事件类型
+ * @Author xiangerlin
+ * @Date 2024/8/27 15:58
+ **/
+public enum OrgEventEnum {
+ USER_ADD_ORG("user_add_org","通讯录用户新增"),
+ USER_MODIFY_ORG("user_modify_org","通讯录用户更改"),
+ USER_LEAVE_ORG("user_leave_org","通讯录用户离职"),
+ USER_ACTIVE_ORG("user_active_org","加入企业后用户激活"),
+ ORG_DEPT_CREATE("org_dept_create","通讯录企业部门创建"),
+ ORG_DEPT_MODIFY("org_dept_modify","通讯录企业部门更改"),
+ ORG_DEPT_REMOVE("org_dept_remove","通讯录企业部门删除"),
+ ;
+
+
+ private String code;
+ private String explain;
+
+ OrgEventEnum(String code, String explain) {
+ this.code = code;
+ this.explain = explain;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public String getExplain() {
+ return explain;
+ }
+
+ /**
+ * 根据code获取事件类型
+ * @param code
+ * @return
+ */
+ public static OrgEventEnum getByCode(String code){
+ for (OrgEventEnum org : OrgEventEnum.values()) {
+ if (org.getCode().equals(code)){
+ return org;
+ }
+ }
+ return null;
+ }
+}
diff --git a/fw-dd/src/main/java/com/hzya/frame/dingtalk/service/IDingTalkExtService.java b/fw-dd/src/main/java/com/hzya/frame/dingtalk/service/IDingTalkExtService.java
new file mode 100644
index 00000000..ffbba432
--- /dev/null
+++ b/fw-dd/src/main/java/com/hzya/frame/dingtalk/service/IDingTalkExtService.java
@@ -0,0 +1,32 @@
+package com.hzya.frame.dingtalk.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.hzya.frame.sysnew.application.entity.SysApplicationEntity;
+import com.hzya.frame.sysnew.application.entity.SysExtensionApiEntity;
+
+/**
+ * @Description 钉钉集成扩展类
+ * @Author xiangerlin
+ * @Date 2024/8/28 14:25
+ **/
+public interface IDingTalkExtService {
+
+ /**
+ * 调用这个方法初始化钉钉参数
+ * @param entity
+ * @return
+ */
+ SysExtensionApiEntity init(SysExtensionApiEntity entity);
+
+ /**
+ * 查询配置在应用上的钉钉参数
+ * @param sysApplication
+ * @return
+ */
+ JSONObject getDingTalkConfig(SysApplicationEntity sysApplication);
+
+ /**
+ * 清空配置缓存
+ */
+ void clearDingTalkConfigCatch();
+}
diff --git a/fw-dd/src/main/java/com/hzya/frame/dingtalk/service/IDingTalkService.java b/fw-dd/src/main/java/com/hzya/frame/dingtalk/service/IDingTalkService.java
new file mode 100644
index 00000000..be742955
--- /dev/null
+++ b/fw-dd/src/main/java/com/hzya/frame/dingtalk/service/IDingTalkService.java
@@ -0,0 +1,66 @@
+package com.hzya.frame.dingtalk.service;
+
+import com.dingtalk.api.request.OapiV2UserListRequest;
+import com.dingtalk.api.response.OapiV2DepartmentGetResponse;
+import com.dingtalk.api.response.OapiV2DepartmentListsubResponse;
+import com.dingtalk.api.response.OapiV2UserGetResponse;
+import com.dingtalk.api.response.OapiV2UserListResponse;
+
+import java.util.List;
+
+/**
+ * @Description 钉钉service
+ * @Author xiangerlin
+ * @Date 2024/8/27 16:17
+ **/
+public interface IDingTalkService {
+
+ /**
+ * 根据userid获取用户详情
+ * @param userId 钉钉userid
+ * @param appKey
+ * @param appSecret
+ * @return
+ */
+ OapiV2UserGetResponse.UserGetResponse getUserById(String userId, String appKey, String appSecret);
+
+ /**
+ * 根据userid获取用户详情
+ * @param userId
+ * @return
+ */
+ OapiV2UserGetResponse.UserGetResponse getUserById(String userId);
+
+ /**
+ * 获取部门用户列表
+ * @param req 请求参数
+ * @param appKey
+ * @param appSecret
+ * @return
+ */
+ OapiV2UserListResponse.PageResult getUserListByDeptId(OapiV2UserListRequest req, String appKey, String appSecret);
+ /**
+ * 根据部门id获取部门详情
+ * @param deptId 钉钉部门id
+ * @param appKey
+ * @param appSecret
+ * @return
+ */
+ OapiV2DepartmentGetResponse.DeptGetResponse getDeptById(Long deptId, String appKey, String appSecret);
+
+ /**
+ * 根据部门id获取部门详情
+ * @param deptId
+ * @return
+ */
+ OapiV2DepartmentGetResponse.DeptGetResponse getDeptById(Long deptId);
+
+ /**
+ * 获取部门列表,此接口只会返回下一级部门信息
+ * @param deptId 部门id,如果不传则查询一级部门
+ * @param appKey
+ * @param appSecret
+ * @return
+ */
+ List getDeptList(Long deptId, String appKey, String appSecret);
+}
diff --git a/fw-dd/src/main/java/com/hzya/frame/dingtalk/service/impl/DingTalkExtServiceImpl.java b/fw-dd/src/main/java/com/hzya/frame/dingtalk/service/impl/DingTalkExtServiceImpl.java
new file mode 100644
index 00000000..dd0267f8
--- /dev/null
+++ b/fw-dd/src/main/java/com/hzya/frame/dingtalk/service/impl/DingTalkExtServiceImpl.java
@@ -0,0 +1,100 @@
+package com.hzya.frame.dingtalk.service.impl;
+
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.hzya.frame.dingtalk.service.IDingTalkExtService;
+import com.hzya.frame.dingtalk.util.DingTalkAccessToken;
+import com.hzya.frame.sysnew.application.api.entity.SysApplicationApiEntity;
+import com.hzya.frame.sysnew.application.apiPara.dao.ISysApplicationApiParaDao;
+import com.hzya.frame.sysnew.application.apiPara.entity.SysApplicationApiParaEntity;
+import com.hzya.frame.sysnew.application.apiPara.service.ISysApplicationApiParaService;
+import com.hzya.frame.sysnew.application.entity.SysApplicationEntity;
+import com.hzya.frame.sysnew.application.entity.SysExtensionApiEntity;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * @Description 钉钉集成扩展类
+ * @Author xiangerlin
+ * @Date 2024/8/28 14:25
+ **/
+@Service(value = "dingTalkExtService")
+public class DingTalkExtServiceImpl implements IDingTalkExtService {
+
+
+ @Resource
+ private ISysApplicationApiParaDao sysApplicationApiParaDao;
+ private final ConcurrentHashMap dingTalkMap = new ConcurrentHashMap<>();
+ /**
+ * 调用这个方法初始化钉钉参数
+ *
+ * @param entity
+ * @return
+ */
+ @Override
+ public SysExtensionApiEntity init(SysExtensionApiEntity entity) {
+ Map headers = entity.getHeaders();
+ if (null == headers){
+ headers = new HashMap<>();
+ }
+ SysApplicationEntity receiveApp = entity.getReceiveApp();
+ //查询应用上配置的参数
+ JSONObject dingTalkConfig = getDingTalkConfig(receiveApp);
+ //给token赋值
+ entity.setQuerys("access_token="+DingTalkAccessToken.getAccessToken(dingTalkConfig.getString("appKey"),dingTalkConfig.getString("appSecret")));
+ return entity;
+ }
+
+ /**
+ * 查询配置在应用上的钉钉参数
+ *
+ * @param sysApplication
+ * @return
+ */
+ @Override
+ public JSONObject getDingTalkConfig(SysApplicationEntity sysApplication) {
+ if (null != sysApplication && StrUtil.isNotEmpty(sysApplication.getId()) && null != sysApplication.getAppId()){
+ JSONObject jsonObject = new JSONObject();
+ String key = sysApplication.getAppId()+"dingTalk";
+ if (null != dingTalkMap.get(key)){
+ return dingTalkMap.get(key);
+ }else {
+ //查询应用上配置的参数
+ SysApplicationApiParaEntity paraEntity = new SysApplicationApiParaEntity();
+ paraEntity.setAppId(sysApplication.getId());
+ List paraList = sysApplicationApiParaDao.query(paraEntity);
+ if (CollectionUtils.isNotEmpty(paraList)) {
+ List appKeyList = paraList.stream().filter(p -> p.getInterfaceKey().equals("appKey")).collect(Collectors.toList());
+ if (CollectionUtils.isNotEmpty(appKeyList)) {
+ jsonObject.put("appKey", appKeyList.get(0).getInterfaceValue());
+ }
+ List appSecretList = paraList.stream().filter(p -> p.getInterfaceKey().equals("appSecret")).collect(Collectors.toList());
+ if (CollectionUtils.isNotEmpty(appSecretList)) {
+ jsonObject.put("appSecret", appSecretList.get(0).getInterfaceValue());
+ }
+ dingTalkMap.put(key,jsonObject);
+ return dingTalkMap.get(key);
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 清空配置缓存
+ */
+ @Override
+ public void clearDingTalkConfigCatch() {
+ dingTalkMap.clear();
+ }
+}
diff --git a/fw-dd/src/main/java/com/hzya/frame/dingtalk/service/impl/DingTalkServiceImpl.java b/fw-dd/src/main/java/com/hzya/frame/dingtalk/service/impl/DingTalkServiceImpl.java
new file mode 100644
index 00000000..89b4bd3e
--- /dev/null
+++ b/fw-dd/src/main/java/com/hzya/frame/dingtalk/service/impl/DingTalkServiceImpl.java
@@ -0,0 +1,164 @@
+package com.hzya.frame.dingtalk.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.dingtalk.api.DefaultDingTalkClient;
+import com.dingtalk.api.DingTalkClient;
+import com.dingtalk.api.request.OapiV2DepartmentGetRequest;
+import com.dingtalk.api.request.OapiV2DepartmentListsubRequest;
+import com.dingtalk.api.request.OapiV2UserGetRequest;
+import com.dingtalk.api.request.OapiV2UserListRequest;
+import com.dingtalk.api.response.OapiV2DepartmentGetResponse;
+import com.dingtalk.api.response.OapiV2DepartmentListsubResponse;
+import com.dingtalk.api.response.OapiV2UserGetResponse;
+import com.dingtalk.api.response.OapiV2UserListResponse;
+import com.hzya.frame.dingtalk.service.IDingTalkService;
+import com.hzya.frame.dingtalk.util.DingTalkAccessToken;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @Description 钉钉service
+ * @Author xiangerlin
+ * @Date 2024/8/27 16:17
+ **/
+@Service
+public class DingTalkServiceImpl implements IDingTalkService {
+ Logger logger = LoggerFactory.getLogger(getClass());
+ @Value("${dingtalk.appKey:}")
+ private String dAppKey;
+ @Value("${dingtalk.appSecret:}")
+ private String dAppSecret;
+
+
+ /**
+ * 根据userid获取用户详情
+ *
+ * @param userId 钉钉userid
+ * @param appKey
+ * @param appSecret
+ * @return
+ */
+ @Override
+ public OapiV2UserGetResponse.UserGetResponse getUserById(String userId, String appKey, String appSecret) {
+ DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
+ OapiV2UserGetRequest req = new OapiV2UserGetRequest();
+ req.setUserid(userId);
+ req.setLanguage("zh_CN");
+ try {
+ OapiV2UserGetResponse rsp = client.execute(req, DingTalkAccessToken.getAccessToken(appKey,appSecret));
+ if (rsp.isSuccess()){
+ OapiV2UserGetResponse.UserGetResponse result = rsp.getResult();
+ String s = JSONObject.toJSONString(result);
+ logger.info("人员详情信息:{}",s);
+ return result;
+ }
+ }catch (Exception e){
+ logger.error("根据部门id获取钉钉用户详情出错:{}",e);
+ }
+ return null;
+ }
+
+ /**
+ * 根据userid获取用户详情
+ *
+ * @param userId
+ * @return
+ */
+ @Override
+ public OapiV2UserGetResponse.UserGetResponse getUserById(String userId) {
+ return getUserById(userId,dAppKey,dAppSecret);
+ }
+
+ /**
+ * 获取部门用户列表
+ *
+ * @param req 请求参数
+ * @param appKey
+ * @param appSecret
+ * @return
+ */
+ @Override
+ public OapiV2UserListResponse.PageResult getUserListByDeptId(OapiV2UserListRequest req, String appKey, String appSecret) {
+ try {
+ DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/list");
+ req.setSize(100L);//每页最大只能查100条
+ req.setOrderField("modify_desc");
+ req.setContainAccessLimit(false);
+ req.setLanguage("zh_CN");
+ OapiV2UserListResponse rsp = client.execute(req, DingTalkAccessToken.getAccessToken(appKey,appSecret));
+ OapiV2UserListResponse.PageResult result = rsp.getResult();
+ return result;
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * 根据部门id获取部门详情
+ *
+ * @param deptId 钉钉部门id
+ * @param appKey
+ * @param appSecret
+ * @return
+ */
+ @Override
+ public OapiV2DepartmentGetResponse.DeptGetResponse getDeptById(Long deptId, String appKey, String appSecret) {
+ DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/get");
+ OapiV2DepartmentGetRequest req = new OapiV2DepartmentGetRequest();
+ req.setDeptId(deptId);
+ req.setLanguage("zh_CN");
+ try {
+ OapiV2DepartmentGetResponse rsp = client.execute(req, DingTalkAccessToken.getAccessToken(appKey,appSecret));
+ if (rsp.isSuccess()){
+ OapiV2DepartmentGetResponse.DeptGetResponse result = rsp.getResult();
+ String s = JSONObject.toJSONString(result);
+ logger.info("部门详情信息:{}",s);
+ return result;
+ }
+ }catch(Exception e){
+ logger.error("根据部门id获取钉钉部门出错:{}",e);
+ }
+ return null;
+ }
+
+ /**
+ * 根据部门id获取部门详情
+ *
+ * @param deptId
+ * @return
+ */
+ @Override
+ public OapiV2DepartmentGetResponse.DeptGetResponse getDeptById(Long deptId) {
+ return getDeptById(deptId,dAppKey,dAppSecret);
+ }
+
+ /**
+ * 获取部门列表,此接口只会返回下一级部门信息
+ * @param deptId 部门id,如果不传则查询一级部门
+ * @param appKey
+ * @param appSecret
+ * @return
+ */
+ @Override
+ public List getDeptList(Long deptId,String appKey,String appSecret) {
+ try {
+ DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
+ OapiV2DepartmentListsubRequest req = new OapiV2DepartmentListsubRequest();
+ req.setDeptId(deptId);
+ req.setLanguage("zh_CN");
+ OapiV2DepartmentListsubResponse rsp = client.execute(req, DingTalkAccessToken.getAccessToken(appKey,appSecret));
+ if (rsp.isSuccess()){
+ List result = rsp.getResult();
+ return result;
+ }
+ }catch (Exception e){
+ logger.error("获取部门列表接口出错:{}",e);
+ }
+ return null;
+ }
+}
diff --git a/fw-dd/src/main/java/com/hzya/frame/dingtalk/util/DingTalkAccessToken.java b/fw-dd/src/main/java/com/hzya/frame/dingtalk/util/DingTalkAccessToken.java
new file mode 100644
index 00000000..eb951180
--- /dev/null
+++ b/fw-dd/src/main/java/com/hzya/frame/dingtalk/util/DingTalkAccessToken.java
@@ -0,0 +1,103 @@
+package com.hzya.frame.dingtalk.util;
+
+import cn.hutool.core.util.StrUtil;
+import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenResponse;
+import com.aliyun.tea.TeaException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+
+import java.time.Instant;
+
+/**
+ * @Description 钉钉获取accessToken
+ * @Author xiangerlin
+ * @Date 2024/8/27 14:05
+ **/
+public class DingTalkAccessToken {
+ static Logger logger = LoggerFactory.getLogger(DingTalkAccessToken.class);
+ //token
+ private static String accessToken;
+ //过期时间
+ private static Instant expireTime;
+ private static final Long CACHE_EXPIRY_TIME = 7000L; // 缓存有效时间(秒)
+ //应用key
+ private static String appKey;
+ //应用密钥
+ private static String appSecret;
+ @Value("${dingtalk.appKey:}")
+ public static void setAppKey(String appKey) {
+ DingTalkAccessToken.appKey = appKey;
+ }
+ @Value("${dingtalk.appSecret:}")
+ public static void setAppSecret(String appSecret) {
+ DingTalkAccessToken.appSecret = appSecret;
+ }
+
+ /**
+ * 获取token
+ * @return
+ */
+ public static String getAccessToken(){
+ return getAccessToken(appKey,appSecret);
+ }
+ /**
+ * 获取accessToken
+ *
+ * @param appKey
+ * @param appSecret
+ * @return
+ */
+ public static String getAccessToken(String appKey,String appSecret) {
+ //判断是否过期 如果没过期直接返回
+ if (null != accessToken && expireTime != null && Instant.now().isBefore(expireTime)) {
+ return accessToken;
+ }
+ //获取新的accessToken
+ accessToken = fetchNewAccessToken(appKey,appSecret);
+ //过期时间设置成当前事件+7000s,预留200s的时间
+ expireTime = Instant.now().plusSeconds(CACHE_EXPIRY_TIME);
+ return accessToken;
+ }
+
+ /**
+ * 获取新的accessToken
+ *
+ * @return
+ */
+ private static String fetchNewAccessToken(String appKey,String appSecret) {
+ try {
+ //查询应用上配置的钉钉信息
+ if (StrUtil.isNotEmpty(appKey) && StrUtil.isNotEmpty(appSecret)) {
+ //查询应用上的信息
+ com.aliyun.dingtalkoauth2_1_0.Client client = DingTalkAccessToken.createClient();
+ com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest getAccessTokenRequest = new com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest()
+ .setAppKey(appKey)
+ .setAppSecret(appSecret);
+ GetAccessTokenResponse accessToken = client.getAccessToken(getAccessTokenRequest);
+ String accessToken1 = accessToken.getBody().getAccessToken();
+ return accessToken1;
+ }
+ } catch (Exception _err) {
+ TeaException err = new TeaException(_err.getMessage(), _err);
+ if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
+ // err 中含有 code 和 message 属性,可帮助开发定位问题
+ }
+ logger.error("获取钉钉token出错:{}", _err);
+ }
+ return null;
+ }
+
+ /**
+ * 使用 Token 初始化账号Client
+ *
+ * @return Client
+ * @throws Exception
+ */
+ private static com.aliyun.dingtalkoauth2_1_0.Client createClient() throws Exception {
+ com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
+ config.protocol = "https";
+ config.regionId = "central";
+ return new com.aliyun.dingtalkoauth2_1_0.Client(config);
+ }
+}
diff --git a/fw-dd/src/main/webapp/WEB-INF/web.xml b/fw-dd/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000..d80081d1
--- /dev/null
+++ b/fw-dd/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,6 @@
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index fc53bd54..cb600e9d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,7 +9,7 @@
base-core
-
+ fw-dd