().ok(thirdLoginService.resiLoginInternalDing(formDTO));
+ }
}
diff --git a/epmet-auth/src/main/java/com/epmet/dto/dingres/DingUserDetailDTO.java b/epmet-auth/src/main/java/com/epmet/dto/dingres/DingUserDetailDTO.java
new file mode 100644
index 0000000000..4a46922590
--- /dev/null
+++ b/epmet-auth/src/main/java/com/epmet/dto/dingres/DingUserDetailDTO.java
@@ -0,0 +1,73 @@
+package com.epmet.dto.dingres;
+
+import lombok.Data;
+
+/**
+ * @Description
+ * @Author yzm
+ * @Date 2022/9/22 14:16
+ */
+@Data
+public class DingUserDetailDTO {
+ // 接口文档:https://open.dingtalk.com/document/isvapp-server/query-user-details
+ /**
+ * 员工的userId。
+ */
+ private String userid;
+
+ /**
+ * 员工在当前开发者企业账号范围内的唯一标识。
+ */
+ private String unionid;
+
+ /**
+ * 员工姓名。
+ */
+ private String name;
+ /**
+ * 头像。
+ *
+ * 说明 员工使用默认头像,不返回该字段,手动设置头像会返回
+ */
+ private String avatar;
+ /**
+ * 国际电话区号。
+ *
+ * 说明 第三方企业应用不返回该字段;如需获取state_code,可以使用钉钉统一授权套件方式获取。
+ */
+ private String state_code;
+ /**
+ * 手机号码。
+ *
+ * 说明
+ * 企业内部应用,只有应用开通通讯录邮箱等个人信息权限,才会返回该字段。
+ * 第三方企业应用不返回该字段,如需获取mobile,可以使用钉钉统一授权套件方式获取。
+ */
+ private String mobile;
+ /**
+ * 是否号码隐藏:
+ *
+ * true:隐藏
+ *
+ * false:不隐藏
+ *
+ * 说明 隐藏手机号后,手机号在个人资料页隐藏,但仍可对其发DING、发起钉钉免费商务电话。
+ */
+ private String hide_mobile;
+ /**
+ * 分机号。
+ *
+ * 说明 第三方企业应用不返回该参数。
+ */
+ private String telephone;
+
+ /**
+ * 员工的企业邮箱。
+ *
+ * 如果员工的企业邮箱没有开通,返回信息中不包含该数据。
+ *
+ * 说明 第三方企业应用不返回该参数。
+ */
+ private String org_email;
+}
+
diff --git a/epmet-auth/src/main/java/com/epmet/dto/dingres/V2UserGetuserinfoResDTO.java b/epmet-auth/src/main/java/com/epmet/dto/dingres/V2UserGetuserinfoResDTO.java
new file mode 100644
index 0000000000..ea9eb3b46b
--- /dev/null
+++ b/epmet-auth/src/main/java/com/epmet/dto/dingres/V2UserGetuserinfoResDTO.java
@@ -0,0 +1,54 @@
+package com.epmet.dto.dingres;
+
+import lombok.Data;
+
+/**
+ * @Description
+ * @Author yzm
+ * @Date 2022/9/22 14:08
+ */
+@Data
+public class V2UserGetuserinfoResDTO {
+ // 接口返参:https://open.dingtalk.com/document/orgapp-server/obtain-the-userid-of-a-user-by-using-the-log-free
+ /**
+ * 用户的userid。
+ */
+ private String userid;
+ /**
+ * 设备ID。
+ */
+ private String device_id;
+ /**
+ * 是否是管理员。
+ *
+ * true:是
+ *
+ * false:不是
+ */
+ private Boolean sys;
+ /**
+ * 级别。
+ *
+ * 1:主管理员
+ *
+ * 2:子管理员
+ *
+ * 100:老板
+ *
+ * 0:其他(如普通员工)
+ */
+ private Number sys_level;
+ /**
+ * 用户关联的unionId。
+ */
+ private String associated_unionid;
+ /**
+ * 用户unionId。
+ */
+ private String unionid;
+ /**
+ * 用户名字。
+ */
+ private String name;
+}
+
diff --git a/epmet-auth/src/main/java/com/epmet/dto/form/ResiDingAppLoginFormDTO.java b/epmet-auth/src/main/java/com/epmet/dto/form/ResiDingAppLoginFormDTO.java
new file mode 100644
index 0000000000..b18e95478a
--- /dev/null
+++ b/epmet-auth/src/main/java/com/epmet/dto/form/ResiDingAppLoginFormDTO.java
@@ -0,0 +1,41 @@
+package com.epmet.dto.form;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * @Description
+ * @Author yzm
+ * @Date 2022/9/14 17:11
+ */
+@Data
+public class ResiDingAppLoginFormDTO {
+ public interface InnerMiniApp {}
+ public interface ThirdMiniApp {}
+ /**
+ * 授权统一后的authCode
+ */
+ @NotBlank(message = "authCode不能为空",groups = InnerMiniApp.class)
+ private String authCode;
+// /**
+// * 第三方企业应用传应用的SuiteKey
+// */
+// @NotBlank(message = "clientId不能为空")
+// private String clientId;
+ /**
+ * 第三方企业应用传应用的SuiteKey
+ */
+ @NotBlank(message = "miniAppId不能为空",groups = InnerMiniApp.class)
+ private String miniAppId;
+
+ // @NotBlank(message = "当前访问用户的企业corpId不能为空")
+ // private String corpId;
+
+ /**
+ * third:第三方应用
+ * company_customize:企业定制应用
+ */
+ private String appType="company_customize";
+}
+
diff --git a/epmet-auth/src/main/java/com/epmet/dto/form/ResiDingAppLoginMdFormDTO.java b/epmet-auth/src/main/java/com/epmet/dto/form/ResiDingAppLoginMdFormDTO.java
new file mode 100644
index 0000000000..0b3b9ae0f8
--- /dev/null
+++ b/epmet-auth/src/main/java/com/epmet/dto/form/ResiDingAppLoginMdFormDTO.java
@@ -0,0 +1,23 @@
+package com.epmet.dto.form;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * @Description
+ * @Author yzm
+ * @Date 2022/9/22 10:42
+ */
+@Data
+public class ResiDingAppLoginMdFormDTO {
+ @NotBlank(message = "authCode不能为空")
+ private String authCode;
+ /**
+ * 第三方企业应用传应用的SuiteKey
+ */
+ @NotBlank(message = "miniAppId不能为空")
+ private String miniAppId;
+
+}
+
diff --git a/epmet-auth/src/main/java/com/epmet/dto/form/ThirdStaffOrgByAccountFormDTO.java b/epmet-auth/src/main/java/com/epmet/dto/form/ThirdStaffOrgByAccountFormDTO.java
index 3cad308ab6..fd1d93b725 100644
--- a/epmet-auth/src/main/java/com/epmet/dto/form/ThirdStaffOrgByAccountFormDTO.java
+++ b/epmet-auth/src/main/java/com/epmet/dto/form/ThirdStaffOrgByAccountFormDTO.java
@@ -1,6 +1,5 @@
package com.epmet.dto.form;
-import com.epmet.commons.tools.validator.group.CustomerClientShowGroup;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@@ -13,36 +12,20 @@ import java.io.Serializable;
@Data
public class ThirdStaffOrgByAccountFormDTO implements Serializable {
private static final long serialVersionUID = 4193133227120225342L;
- /**
- * 添加用户操作的用户可见异常分组
- * 该分组用于校验需要返回给前端错误信息提示的列,需要继承CustomerClientShowGroup
- * 返回错误码为8999,提示信息为DTO中具体的列的校验注解message的内容
- */
- public interface AddUserShowGroup extends CustomerClientShowGroup {
- }
- public interface GetMyOrgByPassWordGroup extends CustomerClientShowGroup {
- }
- public interface GetMyOrgByLoginWxmp extends CustomerClientShowGroup{}
/**
* 小程序appId
*/
- @NotBlank(message = "appId不能为空", groups = {AddUserShowGroup.class})
+ @NotBlank(message = "appId不能为空")
private String appId;
/**
* 手机号
*/
- @NotBlank(message = "账号不能为空", groups = {AddUserShowGroup.class})
+ @NotBlank(message = "账号不能为空")
private String userAccount;
- /**
- * 验证码
- */
- @NotBlank(message="验证码不能为空", groups = {GetMyOrgByLoginWxmp.class})
- private String smsCode;
-
- @NotBlank(message = "密码不能为空",groups ={GetMyOrgByPassWordGroup.class})
+ @NotBlank(message = "密码不能为空")
private String password;
}
diff --git a/epmet-auth/src/main/java/com/epmet/dto/result/ResiDingAppLoginResDTO.java b/epmet-auth/src/main/java/com/epmet/dto/result/ResiDingAppLoginResDTO.java
new file mode 100644
index 0000000000..7a0517574a
--- /dev/null
+++ b/epmet-auth/src/main/java/com/epmet/dto/result/ResiDingAppLoginResDTO.java
@@ -0,0 +1,42 @@
+package com.epmet.dto.result;
+
+import lombok.Data;
+
+/**
+ * @Description
+ * @Author yzm
+ * @Date 2022/9/14 17:20
+ */
+@Data
+public class ResiDingAppLoginResDTO {
+ private String authorization;
+ private String customerId;
+ private String gridId;
+ /**
+ * 网格名
+ */
+ private String gridName;
+ /**
+ * 网格所属的组织id
+ */
+ private String agencyId;
+ /**
+ * 居民端用户id
+ */
+ private String epmetUserId;
+
+ /**
+ * 5.获取用户手机号。使用用户个人access_token调用获取用户通讯录个人信息接口获取
+ * 返参信息
+ * 接口文档:https://open.dingtalk.com/document/isvapp-server/dingtalk-retrieve-user-information
+ */
+ private String extInfo;
+
+ /**
+ * 是否注册居民
+ * true:已注册
+ * false:未注册
+ */
+ private Boolean regFlag;
+}
+
diff --git a/epmet-auth/src/main/java/com/epmet/service/ThirdLoginService.java b/epmet-auth/src/main/java/com/epmet/service/ThirdLoginService.java
index 69d13bf926..70bcc92338 100644
--- a/epmet-auth/src/main/java/com/epmet/service/ThirdLoginService.java
+++ b/epmet-auth/src/main/java/com/epmet/service/ThirdLoginService.java
@@ -1,6 +1,7 @@
package com.epmet.service;
import com.epmet.dto.form.*;
+import com.epmet.dto.result.ResiDingAppLoginResDTO;
import com.epmet.dto.result.StaffOrgsResultDTO;
import com.epmet.dto.result.UserTokenResultDTO;
@@ -84,4 +85,29 @@ public interface ThirdLoginService {
* @description 单客户-工作端微信小程序登录-发送验证码
**/
void sendSmsCode(ThirdSendSmsCodeFormDTO formDTO);
+
+ /**
+ * 钉钉应用的登录-居民端
+ * 产品服务商建立第三方企业应用
+ * 参考文档:https://open.dingtalk.com/document/isvapp-server/unified-authorization-suite-access-process
+ * @param formDTO
+ * @return
+ */
+ ResiDingAppLoginResDTO resiLoginDing(ResiDingAppLoginFormDTO formDTO);
+
+ /**
+ * 企业简历内部应用授权给第三方
+ * 可参考文档: 获取第三方应用授权企业的accessToken https://open.dingtalk.com/document/orgapp-server/obtain-the-access_token-of-the-authorized-enterprise
+ * https://open.dingtalk.com/document/orgapp-server/enterprise-internal-application-logon-free
+ * @param formDTO
+ * @return
+ */
+ ResiDingAppLoginResDTO resiLoginDingMd(ResiDingAppLoginMdFormDTO formDTO);
+
+ /**
+ * 企业内部应用免登 文档地址:https://open.dingtalk.com/document/orgapp-server/enterprise-internal-application-logon-free
+ * @param formDTO
+ * @return
+ */
+ ResiDingAppLoginResDTO resiLoginInternalDing(ResiDingAppLoginMdFormDTO formDTO);
}
diff --git a/epmet-auth/src/main/java/com/epmet/service/impl/ThirdLoginServiceImpl.java b/epmet-auth/src/main/java/com/epmet/service/impl/ThirdLoginServiceImpl.java
index cd1495ddb2..052f0ed3b9 100644
--- a/epmet-auth/src/main/java/com/epmet/service/impl/ThirdLoginServiceImpl.java
+++ b/epmet-auth/src/main/java/com/epmet/service/impl/ThirdLoginServiceImpl.java
@@ -5,15 +5,23 @@ import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.util.crypt.WxMaCryptUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
+import com.aliyun.dingtalk.module.DingTalkResult;
import com.epmet.auth.constants.AuthOperationConstants;
import com.epmet.common.token.constant.LoginConstant;
import com.epmet.commons.rocketmq.messages.LoginMQMsg;
import com.epmet.commons.tools.constant.AppClientConstant;
import com.epmet.commons.tools.constant.ServiceConstant;
+import com.epmet.commons.tools.constant.StrConstant;
+import com.epmet.commons.tools.enums.EnvEnum;
import com.epmet.commons.tools.exception.EpmetErrorCode;
+import com.epmet.commons.tools.exception.EpmetException;
import com.epmet.commons.tools.exception.ExceptionUtils;
import com.epmet.commons.tools.exception.RenException;
import com.epmet.commons.tools.feign.ResultDataResolver;
+import com.epmet.commons.tools.redis.RedisKeys;
+import com.epmet.commons.tools.redis.RedisUtils;
+import com.epmet.commons.tools.redis.common.CustomerDingDingRedis;
+import com.epmet.commons.tools.redis.common.bean.DingMiniInfoCache;
import com.epmet.commons.tools.security.dto.GovTokenDto;
import com.epmet.commons.tools.security.dto.TokenDto;
import com.epmet.commons.tools.security.password.PasswordUtils;
@@ -23,6 +31,8 @@ import com.epmet.commons.tools.validator.PhoneValidatorUtils;
import com.epmet.constant.AuthHttpUrlConstant;
import com.epmet.constant.SmsTemplateConstant;
import com.epmet.dto.*;
+import com.epmet.dto.dingres.DingUserDetailDTO;
+import com.epmet.dto.dingres.V2UserGetuserinfoResDTO;
import com.epmet.dto.form.*;
import com.epmet.dto.result.*;
import com.epmet.feign.EpmetMessageOpenFeignClient;
@@ -32,6 +42,11 @@ import com.epmet.jwt.JwtTokenProperties;
import com.epmet.jwt.JwtTokenUtils;
import com.epmet.redis.CaptchaRedis;
import com.epmet.service.ThirdLoginService;
+import com.taobao.api.ApiException;
+import com.taobao.dingtalk.client.DingTalkClientToken;
+import com.taobao.dingtalk.client.DingTalkClientUser;
+import com.taobao.dingtalk.vo.result.AccessTokenResult;
+import com.taobao.dingtalk.vo.result.UserBaseInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
@@ -73,6 +88,12 @@ public class ThirdLoginServiceImpl implements ThirdLoginService, ResultDataResol
private EpmetMessageOpenFeignClient messageOpenFeignClient;
@Autowired
private LoginUserUtil loginUserUtil;
+ @Autowired
+ private RedisUtils redisUtils;
+ @Autowired
+ private DingTalkClientToken dingTalkClientToken;
+ @Autowired
+ private DingTalkClientUser dingTalkClientUser;
/**
* @param formDTO
@@ -599,11 +620,42 @@ public class ThirdLoginServiceImpl implements ThirdLoginService, ResultDataResol
result.getMsg()));
return new ArrayList<>();
}
-
+ //临时解决方案
+ private static final List resultTemp = new ArrayList<>();
+ static {
+ StaffOrgsResultDTO t = new StaffOrgsResultDTO();
+ t.setRootAgencyId("53613e1c5de6ed473467f0159a10b135");
+ t.setRootAgencyName("平阴县");
+ t.setCustomerId("6f203e30de1a65aab7e69c058826cd80");
+ t.setCustomerName("平音");
+ resultTemp.add(t);
+ }
@Override
public List getMyOrgByAccount(ThirdStaffOrgByAccountFormDTO formDTO) {
+ String appId = formDTO.getAppId();
+ String userAccount = formDTO.getUserAccount();
+ String password = formDTO.getPassword();
+ //{"code":0,"msg":"success","internalMsg":"","data":[{"rootAgencyId":"53613e1c5de6ed473467f0159a10b135","rootAgencyName":"平阴县","customerId":"6f203e30de1a65aab7e69c058826cd80","customerName":"平音"}]}
+ if ("wx2b75d556ba867750".equals(appId)){
+ if("18700011111".equals(userAccount)){
+ if (!"Py02222".equals(password)){
+ throw new RenException(EpmetErrorCode.PASSWORD_ERROR.getCode());
+ }
+ //String result = "[{\"rootAgencyId\":\"53613e1c5de6ed473467f0159a10b135\",\"rootAgencyName\":\"平阴县\",\"customerId\":\"6f203e30de1a65aab7e69c058826cd80\",\"customerName\":\"平音\"}]";
+ return resultTemp;
+ }
+ if (userAccount.startsWith("187000111")){
+ throw new EpmetException(EpmetErrorCode.GOV_STAFF_ACCOUNT_NOT_EXISTS.getCode());
+ }
+ }
+ //{"isNovice":false,"mobile":"","userAccount":"18700011111","password":"Py011111","appId":"wx2b75d556ba867750"}
+
+ logger.info("getMyOrgByAccountService at :{}",System.currentTimeMillis());
+ long start = System.currentTimeMillis();
//0.根据appId查询对应客户Id
PaCustomerDTO customer = this.getCustomerInfo(formDTO.getAppId());
+ logger.info("getMyOrgByAccountService getCustomerInfo cost:{}",System.currentTimeMillis() - start );
+ start = System.currentTimeMillis();
//7.28 上边根据appId只能锁定一条客户id,后边的批量循环操作暂不做调整,还是使用之前的代码 sun
//1、根据手机号查询到用户信息
ThirdCustomerStaffByAccountFormDTO dto = new ThirdCustomerStaffByAccountFormDTO();
@@ -614,30 +666,31 @@ public class ThirdLoginServiceImpl implements ThirdLoginService, ResultDataResol
logger.warn(String.format("账户密码登录异常,账户[%s],code[%s],msg[%s]", formDTO.getUserAccount(), customerStaffResult.getCode(), customerStaffResult.getMsg()));
throw new RenException(customerStaffResult.getCode());
}
+ logger.info("getMyOrgByAccountService getCustsomerStaffByIdAndAccount cost:{}",System.currentTimeMillis()- start);
+ start = System.currentTimeMillis();
//2、密码是否正确
List customerStaffList=customerStaffResult.getData();
+ if (CollectionUtils.isEmpty(customerStaffList)){
+ throw new EpmetException(EpmetErrorCode.GOV_STAFF_ACCOUNT_NOT_EXISTS.getCode());
+ }
//3、查询用户所有的组织信息
List customerIdList = new ArrayList<>();
//是否设置过密码
boolean havePasswordFlag=false;
//密码是否正确
boolean passwordRightFlag=false;
- for (CustomerStaffDTO customerStaffDTO : customerStaffList) {
- if(StringUtils.isNotBlank(customerStaffDTO.getPassword())){
- havePasswordFlag=true;
- }else{
- logger.warn(String.format("当前用户:账户%s,客户Id%s下未设置密码.",formDTO.getUserAccount(),customerStaffDTO.getCustomerId()));
- continue;
- }
- if (!PasswordUtils.matches(formDTO.getPassword(), customerStaffDTO.getPassword())) {
- logger.warn(String.format("当前用户:账户%s,客户Id%s密码匹配错误.",formDTO.getUserAccount(),customerStaffDTO.getCustomerId()));
+ CustomerStaffDTO customerStaffDTO = customerStaffList.get(0);
- }else{
- logger.warn(String.format("当前用户:账户%s,客户Id%s密码匹配正确.",formDTO.getUserAccount(),customerStaffDTO.getCustomerId()));
- passwordRightFlag=true;
- customerIdList.add(customerStaffDTO.getCustomerId());
- }
+ if (StringUtils.isNotBlank(customerStaffDTO.getPassword())) {
+ havePasswordFlag = true;
}
+ long start2 = System.currentTimeMillis();
+ if (PasswordUtils.matches(formDTO.getPassword(), customerStaffDTO.getPassword())) {
+ passwordRightFlag = true;
+ customerIdList.add(customerStaffDTO.getCustomerId());
+ }
+ logger.info("getMyOrgByAccountService PasswordUtils.matches cost:{}", System.currentTimeMillis() - start2);
+
//根据手机号查出来所有用户,密码都为空,表明用户未激活账户,未设置密码
if(!havePasswordFlag){
logger.warn(String.format("当前账户(%s)下所有账户都未设置密码,请先使用验证码登录激活账户",formDTO.getUserAccount()));
@@ -648,11 +701,27 @@ public class ThirdLoginServiceImpl implements ThirdLoginService, ResultDataResol
logger.warn(String.format("根据当前账户(%s)密码未找到所属组织,密码错误",formDTO.getUserAccount()));
throw new RenException(EpmetErrorCode.PASSWORD_ERROR.getCode());
}
+ logger.info("getMyOrgByAccountService checkpassword cost:{}",System.currentTimeMillis() - start);
+ start = System.currentTimeMillis();
+ String tempKey = RedisKeys.getCustomerStaffTempKey(customerStaffDTO.getUserId());
+ List redisTemp = (List)redisUtils.get(tempKey);
+ if (redisTemp != null){
+ logger.info("getMyOrgByAccountService end redis :{}",System.currentTimeMillis());
+ return redisTemp;
+ }
+ logger.info("getMyOrgByAccountService getCustomerStaffTempKey cost:{}",System.currentTimeMillis()-start);
+ start = System.currentTimeMillis();
StaffOrgFormDTO staffOrgFormDTO = new StaffOrgFormDTO();
staffOrgFormDTO.setCustomerIdList(customerIdList);
Result> result = govOrgOpenFeignClient.getStaffOrgList(staffOrgFormDTO);
if(result.success()&&null!=result.getData()){
- return result.getData();
+ List data = result.getData();
+ logger.info("getMyOrgByAccountService getStaffOrgList from db cost:{}",System.currentTimeMillis() -start);
+ start = System.currentTimeMillis();
+ redisUtils.set(tempKey,data);
+ logger.info("getMyOrgByAccountService getCustomerStaffTempKey set redis cost:{}",System.currentTimeMillis()-start);
+ logger.info("getMyOrgByAccountService end DB :{}",System.currentTimeMillis());
+ return data;
}
logger.warn(String .format("手机验证码获取组织,调用%s服务失败,入参账户%s,密码%s,返回错误码%s,错误提示信息%s",
ServiceConstant.GOV_ORG_SERVER,
@@ -669,6 +738,11 @@ public class ThirdLoginServiceImpl implements ThirdLoginService, ResultDataResol
* @author zxc
*/
public PaCustomerDTO getCustomerInfo(String appId){
+ String redisKey = RedisKeys.getThirdCustomerInfoByAppId(appId);
+ PaCustomerDTO customer = (PaCustomerDTO) redisUtils.get(redisKey);
+ if (customer != null && StringUtils.isNotBlank(customer.getId())){
+ return customer;
+ }
JSONObject jsonObject = new JSONObject();
String data = HttpClientManager.getInstance().sendPostByJSON(AuthHttpUrlConstant.CUSTOMER_MSG_URL + appId, JSON.toJSONString(jsonObject)).getData();
logger.info("ThirdLoginServiceImpl.getCustomerInfo:httpclient->url:"+AuthHttpUrlConstant.CUSTOMER_MSG_URL+",结果->"+data);
@@ -684,8 +758,9 @@ public class ThirdLoginServiceImpl implements ThirdLoginService, ResultDataResol
Object PublicCustomerResultDTO = mapToResult.getData();
JSONObject json = JSON.parseObject(PublicCustomerResultDTO.toString());
Map map = (Map)json.get("customer");
- PaCustomerDTO customer = ConvertUtils.mapToEntity(map, PaCustomerDTO.class);
+ customer = ConvertUtils.mapToEntity(map, PaCustomerDTO.class);
logger.info("小程序登陆third服务获取客户用户信息PaCustomerDTO->"+customer);
+ redisUtils.set(redisKey,customer);
return customer;
}
@@ -815,4 +890,297 @@ public class ThirdLoginServiceImpl implements ThirdLoginService, ResultDataResol
//getResultDataOrThrowsException(result, ServiceConstant.EPMET_MESSAGE_SERVER, EpmetErrorCode.SERVER_ERROR.getCode(), "调用Message服务,发送登录事件到MQ失败");
}
+// 接入流程:https://open.dingtalk.com/document/isvapp-server/unified-authorization-suite-access-process
+// 1、获取个人用户token:https://open.dingtalk.com/document/isvapp-server/obtain-user-token
+// 2、获取用户通讯录个人信息:https://open.dingtalk.com/document/isvapp-server/dingtalk-retrieve-user-information
+// 接口逻辑:
+// (1)根据clientId去XXX表找到customerId
+// (2)通过1、2拿到手机号之后,根据mobile+customerId去user_base_info表找userId,
+// 是否注册居民:register_relation
+// (3)没有则生成user、user_Base_info表记录
+ /**
+ * 钉钉应用的登录-居民端
+ *
+ * @param formDTO
+ * @return
+ */
+ @Override
+ public ResiDingAppLoginResDTO resiLoginDing(ResiDingAppLoginFormDTO formDTO) {
+ //获取用户手机号
+ log.info("1、钉钉居民端应用登录入参:"+ JSON.toJSONString(formDTO));
+ ResiDingAppLoginResDTO resDTO= null;
+ try {
+ resDTO = new ResiDingAppLoginResDTO();
+ resDTO.setCustomerId(getCurrentCustomerId());
+ //1、获取用户手机号
+ String miniAppId = formDTO.getMiniAppId();
+ DingMiniInfoCache dingMiniInfo = CustomerDingDingRedis.getDingMiniInfo(miniAppId);
+ DingTalkResult userAccessToken = dingTalkClientToken.getUserAccessToken(formDTO.getAuthCode(), dingMiniInfo.getSuiteKey(), dingMiniInfo.getSuiteSecret());
+ log.info("2、resiLoginDing userAccessToken:{}",JSON.toJSONString(userAccessToken));
+ if (!userAccessToken.success() || null == userAccessToken.getData()) {
+ throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "调用微信api异常:" + JSON.toJSONString(userAccessToken), EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getMsg());
+ }
+ DingTalkResult me = dingTalkClientUser.getUserInfo("me", userAccessToken.getData().getAccessToken());
+ log.info("3、resiLoginDing me:{}",JSON.toJSONString(me));
+ resDTO.setExtInfo(JSON.toJSONString(me.getData()));
+ if (!me.success() || StringUtils.isBlank(me.getData().getMobile())) {
+ log.error("resilogin-ding登录接口报错,入参:" + JSON.toJSONString(formDTO) + ";获取手机号为空, userAccessToken.getData().getAccessToken()=" + userAccessToken.getData().getAccessToken());
+ throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "获取手机号为空", "获取手机号为空");
+ }
+ // 2、调用userfeign接口获取userId、注册网格相关信息 todo
+ DingLoginResiFormDTO dingLoginResiFormDTO=ConvertUtils.sourceToTarget(me.getData(),DingLoginResiFormDTO.class);
+ dingLoginResiFormDTO.setCustomerId(resDTO.getCustomerId());
+ Result loginResiResDTOResult = epmetUserOpenFeignClient.dingResiLogin(dingLoginResiFormDTO);
+ if (!loginResiResDTOResult.success() || null == loginResiResDTOResult.getData()) {
+ //临时打个日志
+ log.error(String.format("resilogin-ding获取epmetUserId异常,入参:%s,user服务返参:%s", JSON.toJSONString(formDTO), JSON.toJSONString(loginResiResDTOResult)));
+ throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "获取epmetUserId异常:" + JSON.toJSONString(loginResiResDTOResult), EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getMsg());
+ }
+ DingLoginResiResDTO resiResDTO=loginResiResDTOResult.getData();
+ resDTO.setGridId(resiResDTO.getGridId());
+ resDTO.setGridName(resiResDTO.getGridName());
+ resDTO.setAgencyId(resiResDTO.getAgencyId());
+ resDTO.setEpmetUserId(resiResDTO.getEpmetUserId());
+ resDTO.setRegFlag(resiResDTO.getRegFlag());
+
+ //3.生成token,并且存放Redis
+ String token=this.saveTokenDtoDing(formDTO.getMiniAppId(),AppClientConstant.APP_RESI,AppClientConstant.MINI_DING, resDTO.getEpmetUserId(), resDTO.getCustomerId());
+ resDTO.setAuthorization(token);
+
+ } catch (ApiException e) {
+ throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), e.getErrMsg(), EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getMsg());
+ }
+ return resDTO;
+ }
+
+ private String saveTokenDtoDing(String miniAppId,String app,String client, String userId,String customerId) {
+ //生成token串
+ Map map = new HashMap<>();
+ map.put(AppClientConstant.APP, app);
+ // map.put(AppClientConstant.CLIENT, client);
+ // 第三方企业应用传应用的SuiteKey 作为client
+ map.put(AppClientConstant.CLIENT, client.concat(miniAppId));
+ map.put("userId", userId);
+ String token = jwtTokenUtils.createToken(map);
+ int expire = jwtTokenProperties.getExpire();
+ TokenDto tokenDto = new TokenDto();
+ tokenDto.setCustomerId(customerId);
+ tokenDto.setApp(app);
+ tokenDto.setClient(client.concat(miniAppId));
+ tokenDto.setUserId(userId);
+ tokenDto.setToken(token);
+ tokenDto.setUpdateTime(System.currentTimeMillis());
+ tokenDto.setExpireTime(jwtTokenUtils.getExpiration(token).getTime());
+ cpUserDetailRedis.set(tokenDto, expire);
+ // cpUserDetailRedis.setForDingApp(miniAppId,tokenDto, expire);
+ logger.info("截止时间:" + DateUtils.format(jwtTokenUtils.getExpiration(token), "yyyy-MM-dd HH:mm:ss"));
+ return token;
+ }
+
+ @Override
+ public ResiDingAppLoginResDTO resiLoginDingMd(ResiDingAppLoginMdFormDTO formDTO) {
+ // 获取用户手机号
+ log.info("1、钉钉居民端应用登录入参:" + JSON.toJSONString(formDTO));
+ ResiDingAppLoginResDTO resDTO = null;
+ resDTO = new ResiDingAppLoginResDTO();
+ resDTO.setCustomerId(getCurrentCustomerId());
+ // 1、获取用户手机号
+ DingLoginResiFormDTO dingLoginResiFormDTO = getDingLoginResiFormDTOMd(formDTO.getMiniAppId(), formDTO.getAuthCode());
+ dingLoginResiFormDTO.setCustomerId(resDTO.getCustomerId());
+ // 2、调用userfeign接口获取userId、注册网格相关信息
+ Result loginResiResDTOResult = epmetUserOpenFeignClient.dingResiLogin(dingLoginResiFormDTO);
+ if (!loginResiResDTOResult.success() || null == loginResiResDTOResult.getData()) {
+ // 临时打个日志
+ log.error(String.format("resiLoginDingMd获取epmetUserId异常,入参:%s,user服务返参:%s", JSON.toJSONString(formDTO), JSON.toJSONString(loginResiResDTOResult)));
+ throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "获取epmetUserId异常:" + JSON.toJSONString(loginResiResDTOResult), EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getMsg());
+ }
+ DingLoginResiResDTO resiResDTO = loginResiResDTOResult.getData();
+ resDTO.setGridId(resiResDTO.getGridId());
+ resDTO.setGridName(resiResDTO.getGridName());
+ resDTO.setAgencyId(resiResDTO.getAgencyId());
+ resDTO.setEpmetUserId(resiResDTO.getEpmetUserId());
+ resDTO.setRegFlag(resiResDTO.getRegFlag());
+
+ // 3.生成token,并且存放Redis
+ String token = this.saveTokenDtoDing(formDTO.getMiniAppId(), AppClientConstant.APP_RESI, AppClientConstant.MINI_DING, resDTO.getEpmetUserId(), resDTO.getCustomerId());
+ resDTO.setAuthorization(token);
+
+ return resDTO;
+ }
+
+ private DingLoginResiFormDTO getDingLoginResiFormDTOMd(String miniAppId, String authCode) {
+ DingMiniInfoCache dingMiniInfo = CustomerDingDingRedis.getDingMiniInfo(miniAppId);
+
+ // 1、服务商获取第三方应用授权企业的access_token,文档地址:https://open.dingtalk.com/document/orgapp-server/obtains-the-enterprise-authorized-credential
+ // 烟台的CorpId: dingaae55cbc47a96845f5bf40eda33b7ba0
+ String yantaiCorpId = "dingaae55cbc47a96845f5bf40eda33b7ba0";
+ DingTalkResult res = dingTalkClientToken.getThirdAuthCorpAccessToken(dingMiniInfo.getSuiteKey(), dingMiniInfo.getSuiteSecret(), "abc", yantaiCorpId);
+ if (!res.success() || StringUtils.isBlank(res.getData())) {
+ log.error(String.format("企业内部应用免登服务商获取第三方应用授权企业的access_token失败,customKey:%s,customSecret:%s,corpId:%s", dingMiniInfo.getSuiteSecret(), dingMiniInfo.getSuiteSecret(), yantaiCorpId));
+ throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "服务商获取第三方应用授权企业的access_token", "服务商获取第三方应用授权企业的access_token");
+ }
+ String accessToken = res.getData();
+ log.info(String.format("1、服务商获取第三方应用授权企业的access_token返参:%s", accessToken));
+
+ // 2、通过免登码获取用户信息,文档地址:https://open.dingtalk.com/document/orgapp-server/obtain-the-userid-of-a-user-by-using-the-log-free
+ DingTalkResult v2UserGetuserinfoRes = dingTalkClientToken.getUserInfo(accessToken, authCode);
+ if (!v2UserGetuserinfoRes.success() || StringUtils.isBlank(v2UserGetuserinfoRes.getData())) {
+ throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "通过免登码获取用户信息异常", "通过免登码获取用户信息异常");
+ }
+ log.info(String.format("2、通过免登码获取用户信息返参:%s", v2UserGetuserinfoRes.getData()));
+ V2UserGetuserinfoResDTO v2UserGetuserinfoResDTO = JSON.parseObject(v2UserGetuserinfoRes.getData(), V2UserGetuserinfoResDTO.class);
+ if (null == v2UserGetuserinfoResDTO || StringUtils.isBlank(v2UserGetuserinfoResDTO.getUserid())) {
+ throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "获取钉钉用户userid为空", "获取钉钉用户userid为空");
+ }
+
+
+ // 3、查询用户详情,文档地址:https://open.dingtalk.com/document/isvapp-server/query-user-details
+ DingTalkResult v2UserGetRes = dingTalkClientToken.getUserDetail(v2UserGetuserinfoResDTO.getUserid(), accessToken);
+ if (!v2UserGetRes.success() || StringUtils.isBlank(v2UserGetRes.getData())) {
+ throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "根据userId查询用户详情失败", "根据userId查询用户详情失败");
+ }
+ log.info(String.format("3、查询用户详情:%s", v2UserGetRes.getData()));
+ DingUserDetailDTO dingUserDetailDTO = JSON.parseObject(v2UserGetRes.getData(), DingUserDetailDTO.class);
+ if (null == dingUserDetailDTO || StringUtils.isBlank(dingUserDetailDTO.getMobile())) {
+ throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "获取手机号为空", "获取手机号为空");
+ }
+
+ DingLoginResiFormDTO dingLoginResiFormDTO = new DingLoginResiFormDTO();
+ dingLoginResiFormDTO.setAvatarUrl(dingUserDetailDTO.getAvatar());
+ dingLoginResiFormDTO.setEmail(dingUserDetailDTO.getOrg_email());
+ dingLoginResiFormDTO.setMobile(dingUserDetailDTO.getMobile());
+ dingLoginResiFormDTO.setNick(dingUserDetailDTO.getName());
+ dingLoginResiFormDTO.setOpenId(StrConstant.EPMETY_STR);
+ dingLoginResiFormDTO.setStateCode(dingUserDetailDTO.getState_code());
+ dingLoginResiFormDTO.setUnionId(dingUserDetailDTO.getUnionid());
+ return dingLoginResiFormDTO;
+ }
+
+
+ /**
+ * 企业内部应用开发,不授权了
+ * https://open.dingtalk.com/document/orgapp-server/enterprise-internal-application-logon-free
+ * 建议用户信息保存在前端缓存中(dd.setStorage)或者cookie中,避免每次进入应用都调用钉钉接口进行免登。
+ *
+ * 获取免登授权码。
+ * 小程序免登
+ * 微应用免登
+ * 获取AccessToken。
+ * 调用接口获取access_token,详情请参考获取企业内部应用的access_token。
+ *
+ * 获取userid。
+ * 调用接口获取用户的userid,详情请参考通过免登码获取用户信息。
+ *
+ * 获取用户详情。
+ * 调用接口获取用户详细信息,详情请参考根据userId获取用户详情。
+ *
+ * @param formDTO
+ * @return
+ */
+ @Override
+ public ResiDingAppLoginResDTO resiLoginInternalDing(ResiDingAppLoginMdFormDTO formDTO) {
+ // 获取用户手机号
+ log.info("1、钉钉居民端应用登录入参:" + JSON.toJSONString(formDTO));
+ ResiDingAppLoginResDTO resDTO = null;
+ resDTO = new ResiDingAppLoginResDTO();
+ resDTO.setCustomerId(getCurrentCustomerId());
+
+ // 1、获取用户手机号
+ DingLoginResiFormDTO dingLoginResiFormDTO = getDingLoginResiFormDTOInternal(formDTO.getMiniAppId(), formDTO.getAuthCode());
+ dingLoginResiFormDTO.setCustomerId(resDTO.getCustomerId());
+
+ // 2、调用userfeign接口获取userId、注册网格相关信息
+ Result loginResiResDTOResult = epmetUserOpenFeignClient.dingResiLogin(dingLoginResiFormDTO);
+ if (!loginResiResDTOResult.success() || null == loginResiResDTOResult.getData()) {
+ // 临时打个日志
+ log.error(String.format("resiLoginInternalDing获取epmetUserId异常,入参:%s", JSON.toJSONString(dingLoginResiFormDTO)));
+ throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "获取epmetUserId异常:"+ JSON.toJSONString(loginResiResDTOResult), "获取epmetUserId异常");
+ }
+ DingLoginResiResDTO resiResDTO = loginResiResDTOResult.getData();
+ resDTO.setGridId(resiResDTO.getGridId());
+ resDTO.setGridName(resiResDTO.getGridName());
+ resDTO.setAgencyId(resiResDTO.getAgencyId());
+ resDTO.setEpmetUserId(resiResDTO.getEpmetUserId());
+ resDTO.setRegFlag(resiResDTO.getRegFlag());
+
+ // 3.生成token,并且存放Redis
+ String token = this.saveTokenDtoDing(formDTO.getMiniAppId(), AppClientConstant.APP_RESI, AppClientConstant.MINI_DING, resDTO.getEpmetUserId(), resDTO.getCustomerId());
+ resDTO.setAuthorization(token);
+
+ return resDTO;
+ }
+
+ /**
+ * 最原始的企业内部应用开发,不授权给产品服务商
+ * @param miniAppId
+ * @param authCode
+ * @return
+ */
+ private DingLoginResiFormDTO getDingLoginResiFormDTOInternal(String miniAppId, String authCode) {
+ DingMiniInfoCache dingMiniInfo = CustomerDingDingRedis.getDingMiniInfo(miniAppId);
+
+ // 1、获取企业内部应用的accessToken文档地址:https://open.dingtalk.com/document/orgapp-server/obtain-the-access_token-of-an-internal-app
+ String accessToken = "";
+ DingTalkResult dingTalkResult = dingTalkClientToken.getAppAccessTokenToken(dingMiniInfo.getSuiteKey(), dingMiniInfo.getSuiteSecret());
+ if (!dingTalkResult.success() || StringUtils.isBlank(dingTalkResult.getData())) {
+ log.error(String.format("获取企业内部应用的accessToken失败,customKey:%s,customSecret:%s", dingMiniInfo.getSuiteSecret(), dingMiniInfo.getSuiteSecret()));
+ throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "获取企业内部应用的accessToken异常", "获取企业内部应用的accessToken");
+ }
+ accessToken = dingTalkResult.getData();
+ log.info(String.format("1、获取企业内部应用的accessToken返参:%s", accessToken));
+
+
+ // 2、通过免登码获取用户信息,文档地址:https://open.dingtalk.com/document/orgapp-server/obtain-the-userid-of-a-user-by-using-the-log-free
+ DingTalkResult v2UserGetuserinfoRes = dingTalkClientToken.getUserInfo(accessToken, authCode);
+ if (!v2UserGetuserinfoRes.success() || StringUtils.isBlank(v2UserGetuserinfoRes.getData())) {
+ throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "通过免登码获取用户信息异常", "通过免登码获取用户信息异常");
+ }
+ log.info(String.format("2、通过免登码获取用户信息返参:%s", v2UserGetuserinfoRes.getData()));
+ V2UserGetuserinfoResDTO v2UserGetuserinfoResDTO = JSON.parseObject(v2UserGetuserinfoRes.getData(), V2UserGetuserinfoResDTO.class);
+ if (null == v2UserGetuserinfoResDTO || StringUtils.isBlank(v2UserGetuserinfoResDTO.getUserid())) {
+ throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "获取钉钉用户userid为空", "获取钉钉用户userid为空");
+ }
+
+
+ // 3、查询用户详情,文档地址:https://open.dingtalk.com/document/isvapp-server/query-user-details
+ DingTalkResult v2UserGetRes = dingTalkClientToken.getUserDetail(v2UserGetuserinfoResDTO.getUserid(), accessToken);
+ if (!v2UserGetRes.success() || StringUtils.isBlank(v2UserGetRes.getData())) {
+ throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "根据userId查询用户详情失败", "根据userId查询用户详情失败");
+ }
+ log.info(String.format("3、查询用户详情:%s", v2UserGetRes.getData()));
+ DingUserDetailDTO dingUserDetailDTO = JSON.parseObject(v2UserGetRes.getData(), DingUserDetailDTO.class);
+ if (null == dingUserDetailDTO || StringUtils.isBlank(dingUserDetailDTO.getMobile())) {
+ throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "获取手机号为空", "获取手机号为空");
+ }
+
+ DingLoginResiFormDTO dingLoginResiFormDTO = new DingLoginResiFormDTO();
+ dingLoginResiFormDTO.setAvatarUrl(dingUserDetailDTO.getAvatar());
+ dingLoginResiFormDTO.setEmail(dingUserDetailDTO.getOrg_email());
+ dingLoginResiFormDTO.setMobile(dingUserDetailDTO.getMobile());
+ dingLoginResiFormDTO.setNick(dingUserDetailDTO.getName());
+ dingLoginResiFormDTO.setOpenId(StrConstant.EPMETY_STR);
+ dingLoginResiFormDTO.setStateCode(dingUserDetailDTO.getState_code());
+ dingLoginResiFormDTO.setUnionId(dingUserDetailDTO.getUnionid());
+ return dingLoginResiFormDTO;
+ }
+
+ /**
+ * 客户写死吧
+ * @return
+ */
+ private String getCurrentCustomerId() {
+ String customerId="";
+ EnvEnum currentEnv = EnvEnum.getCurrentEnv();
+ if (EnvEnum.PROD.getCode().equals(currentEnv.getCode())) {
+ // 烟台的客户id
+ customerId="1535072605621841922";
+ } else if (EnvEnum.TEST.getCode().equals(currentEnv.getCode())) {
+ // 最美琴岛
+ customerId="0c41b272ee9ee95ac6f184ad548a30eb";
+ } else {
+ // 其余统一走开发环境
+ customerId="45687aa479955f9d06204d415238f7cc";
+ }
+ return customerId;
+ }
}
diff --git a/epmet-auth/src/main/resources/bootstrap.yml b/epmet-auth/src/main/resources/bootstrap.yml
index 3f338f611c..cb7141206f 100644
--- a/epmet-auth/src/main/resources/bootstrap.yml
+++ b/epmet-auth/src/main/resources/bootstrap.yml
@@ -91,6 +91,12 @@ hystrix:
isolation:
thread:
timeoutInMilliseconds: 60000 #缺省为1000
+ threadpool:
+ default:
+ coreSize: 20
+ maximumSize: 50
+ maxQueueSize: 500
+ queueSizeRejectionThreshold: 200
ribbon:
ReadTimeout: 300000
@@ -178,4 +184,4 @@ thread:
queueCapacity: @thread.threadPool.queue-capacity@
keepAliveSeconds: @thread.threadPool.keep-alive-seconds@
threadNamePrefix: @thread.threadPool.thread-name-prefix@
- rejectedExecutionHandler: @thread.threadPool.rejected-execution-handler@
\ No newline at end of file
+ rejectedExecutionHandler: @thread.threadPool.rejected-execution-handler@
diff --git a/epmet-cloud-generator/src/main/resources/template/index.vue.vm b/epmet-cloud-generator/src/main/resources/template/index.vue.vm
index aa5bcb3494..9b3ba8bee8 100644
--- a/epmet-cloud-generator/src/main/resources/template/index.vue.vm
+++ b/epmet-cloud-generator/src/main/resources/template/index.vue.vm
@@ -1,52 +1,52 @@
-
-
+
+
-
+
- {{ $t('query') }}
-
-
- {{ $t('add') }}
-
-
- {{ $t('deleteBatch') }}
+ {{ $t('query') }}
-
+
+
+
+ {{ $t('add') }}
+ {{ $t('deleteBatch') }}
+
+
-#foreach($column in $columns)
-
-#end
+ #foreach($column in $columns)
+
+ #end
- {{ $t('update') }}
- {{ $t('delete') }}
+ {{ $t('update') }}
+ {{ $t('delete') }}
+ :current-page="page"
+ :page-sizes="[10, 20, 50, 100]"
+ :page-size="limit"
+ :total="total"
+ layout="total, sizes, prev, pager, next, jumper"
+ @size-change="pageSizeChangeHandle"
+ @current-change="pageCurrentChangeHandle">
-
-
-
-
+
+
+
+
+
diff --git a/epmet-commons/epmet-commons-feignclient/pom.xml b/epmet-commons/epmet-commons-feignclient/pom.xml
new file mode 100644
index 0000000000..4cf486cefb
--- /dev/null
+++ b/epmet-commons/epmet-commons-feignclient/pom.xml
@@ -0,0 +1,24 @@
+
+
+
+ epmet-commons
+ com.epmet
+ 2.0.0
+
+
+ 4.0.0
+ jar
+
+ epmet-commons-feignclient
+
+
+
+ com.epmet
+ epmet-commons-tools
+ 2.0.0
+
+
+
+
\ No newline at end of file
diff --git a/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/.gitkeep b/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/.gitkeep
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/.gitkeep b/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/.gitkeep
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/JiMuPage.java b/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/JiMuPage.java
new file mode 100644
index 0000000000..1c92f30d11
--- /dev/null
+++ b/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/JiMuPage.java
@@ -0,0 +1,22 @@
+package com.epmet.commons.feignclient.dtos;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * 积木报表的返回值Page对象
+ * @param
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class JiMuPage {
+ private int pageNo;
+ private int pageSize;
+ private int total;
+ private int pages;
+ private List> records;
+}
diff --git a/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/JiMuResult.java b/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/JiMuResult.java
new file mode 100644
index 0000000000..5aa42d273a
--- /dev/null
+++ b/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/JiMuResult.java
@@ -0,0 +1,20 @@
+package com.epmet.commons.feignclient.dtos;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 积木报表的返回值Result对象
+ * @param
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class JiMuResult {
+ private boolean success = true;
+ private String message = "";
+ private Integer code = 0;
+ private T result;
+ private T data;
+}
diff --git a/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/form/JiMuReportFormDTO.java b/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/form/JiMuReportFormDTO.java
new file mode 100644
index 0000000000..caf58ec9a9
--- /dev/null
+++ b/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/form/JiMuReportFormDTO.java
@@ -0,0 +1,33 @@
+package com.epmet.commons.feignclient.dtos.form;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @Author zxc
+ * @DateTime 2022/8/8 15:08
+ * @DESC
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class JiMuReportFormDTO implements Serializable {
+
+ private static final long serialVersionUID = 3590609549416867701L;
+
+ /**
+ * 报表IDs
+ */
+ private List reportIds;
+
+ /**
+ * 类别
+ */
+ private List categoryKeys;
+
+ private String id;
+}
diff --git a/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/form/JimuReportExportRequestDTO.java b/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/form/JimuReportExportRequestDTO.java
new file mode 100644
index 0000000000..7e66c588e9
--- /dev/null
+++ b/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/form/JimuReportExportRequestDTO.java
@@ -0,0 +1,27 @@
+package com.epmet.commons.feignclient.dtos.form;
+
+import lombok.Data;
+
+/**
+ * 批量导出用的requst dto
+ */
+@Data
+public class JimuReportExportRequestDTO {
+ private String excelConfigId;
+ private ExportRequestQueryParam queryParam = new ExportRequestQueryParam();
+
+ /**
+ * 批量导出用的请求参数
+ */
+ @Data
+ public static class ExportRequestQueryParam {
+ private String id;
+ private String token;
+ private String paramKey;
+ private String pageNo;
+ private Integer pageSize;
+ private String currentPageNo;
+ private Integer currentPageSize;
+ }
+
+}
\ No newline at end of file
diff --git a/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/result/JiMuReportBriefResultDTO.java b/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/result/JiMuReportBriefResultDTO.java
new file mode 100644
index 0000000000..be5f3df667
--- /dev/null
+++ b/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/result/JiMuReportBriefResultDTO.java
@@ -0,0 +1,17 @@
+package com.epmet.commons.feignclient.dtos.result;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 报表简要信息result dto
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class JiMuReportBriefResultDTO {
+ private String id;
+ private String code;
+ private String name;
+}
diff --git a/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/result/JiMuReportDetailResultDTO.java b/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/result/JiMuReportDetailResultDTO.java
new file mode 100644
index 0000000000..9e27d5ab5b
--- /dev/null
+++ b/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/result/JiMuReportDetailResultDTO.java
@@ -0,0 +1,31 @@
+package com.epmet.commons.feignclient.dtos.result;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+import java.util.Map;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class JiMuReportDetailResultDTO {
+ private String id;
+ private String code;
+ private String name;
+ private String note;
+ private String status;
+ private String type;
+ private String jsonStr;
+ private String apiUrl;
+ private String apiMethod;
+ private String apiCode;
+ private String thumb;
+ private Integer template;
+ private String createBy;
+ private Date createTime;
+ private String updateBy;
+ private Date updateTime;
+ private Map dataList;
+}
diff --git a/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/result/JiMuReportResultDTO.java b/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/result/JiMuReportResultDTO.java
new file mode 100644
index 0000000000..6ef587b6d5
--- /dev/null
+++ b/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/result/JiMuReportResultDTO.java
@@ -0,0 +1,26 @@
+package com.epmet.commons.feignclient.dtos.result;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @Author zxc
+ * @DateTime 2022/8/8 15:10
+ * @DESC
+ */
+@Data
+public class JiMuReportResultDTO implements Serializable {
+
+ private static final long serialVersionUID = -4048477731892329569L;
+
+ private String code;
+
+ private String name;
+
+ private String id;
+ private String reportId;
+ private String reportName;
+
+ private Boolean isList = false;
+}
diff --git a/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/result/JimuReportDbDataResultDTO.java b/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/result/JimuReportDbDataResultDTO.java
new file mode 100644
index 0000000000..8eb58e8b74
--- /dev/null
+++ b/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/result/JimuReportDbDataResultDTO.java
@@ -0,0 +1,18 @@
+package com.epmet.commons.feignclient.dtos.result;
+
+import lombok.Data;
+
+@Data
+public class JimuReportDbDataResultDTO {
+
+ private ReportDB reportDb;
+
+ @Data
+ public static class ReportDB {
+ private String apiUrl;
+ private String apiMethod;
+ private String isList;
+ private String dbChName;
+ }
+
+}
diff --git a/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/result/JimuReportFieldTreeResultDTO.java b/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/result/JimuReportFieldTreeResultDTO.java
new file mode 100644
index 0000000000..ef4037afe8
--- /dev/null
+++ b/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/dtos/result/JimuReportFieldTreeResultDTO.java
@@ -0,0 +1,26 @@
+package com.epmet.commons.feignclient.dtos.result;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 积木报表,报表字段列表
+ */
+@Data
+public class JimuReportFieldTreeResultDTO {
+
+ private Boolean expand;
+ private String code;
+ private List children;
+ private String dbId;
+ private String type;
+ private String isList;
+
+ @Data
+ public static class Child {
+ private Boolean expand;
+ private String title;
+ private String fieldText;
+ }
+}
diff --git a/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/feigns/.gitkeep b/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/feigns/.gitkeep
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/feigns/JiMuReportOpenFeignClient.java b/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/feigns/JiMuReportOpenFeignClient.java
new file mode 100644
index 0000000000..009c68c2c8
--- /dev/null
+++ b/epmet-commons/epmet-commons-feignclient/src/main/java/com/epmet/commons/feignclient/feigns/JiMuReportOpenFeignClient.java
@@ -0,0 +1,55 @@
+package com.epmet.commons.feignclient.feigns;
+
+import com.epmet.commons.feignclient.dtos.JiMuPage;
+import com.epmet.commons.feignclient.dtos.JiMuResult;
+import com.epmet.commons.feignclient.dtos.form.JimuReportExportRequestDTO;
+import com.epmet.commons.feignclient.dtos.result.JiMuReportBriefResultDTO;
+import com.epmet.commons.feignclient.dtos.result.JiMuReportDetailResultDTO;
+import com.epmet.commons.feignclient.dtos.result.JimuReportDbDataResultDTO;
+import com.epmet.commons.feignclient.dtos.result.JimuReportFieldTreeResultDTO;
+import com.epmet.commons.feignclient.feigns.fallback.JiMuReportOpenFeignClientFallbackFactory;
+import com.epmet.commons.tools.constant.ServiceConstant;
+import feign.Response;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Author zxc
+ * @DateTime 2022/8/8 13:52
+ * @DESC
+ */
+@FeignClient(name = ServiceConstant.EPMET_JM_REPORT, fallbackFactory = JiMuReportOpenFeignClientFallbackFactory.class)
+//@FeignClient(name = ServiceConstant.EPMET_JM_REPORT, fallbackFactory = JiMuReportOpenFeignClientFallbackFactory.class, url = "localhost:8118")
+public interface JiMuReportOpenFeignClient {
+
+ @GetMapping(value = "jmreport/excelQuery")
+ JiMuResult> getList(@RequestParam("pageNo") Integer pageNo,
+ @RequestParam("pageSize") Integer pageSize,
+ @RequestParam("name") String name,
+ @RequestParam("reportType") String reportType,
+ @RequestParam("token") String token,
+ @RequestHeader MultiValueMap headers);
+
+ @GetMapping("jmreport/show")
+ JiMuResult