mirror of
http://git.pig4cloud.com/pig/pigx.git
synced 2026-11-09 04:49:02 +08:00
♻️ Refactoring code. 支持钉钉、企微登录
This commit is contained in:
1 parent
f6f05b132a
commit
673896ecf7
6 files changed
+191
-26
No files matched your search
+12
@@ -143,6 +143,18 @@ public class SysUser implements Serializable {
|
||||
@Schema(description = "微信openid")
|
||||
private String wxOpenid;
|
||||
|
||||
/**
|
||||
* 企微微信 userid
|
||||
*/
|
||||
@Schema(description = "企微微信 userid")
|
||||
private String wxCpUserid;
|
||||
|
||||
/**
|
||||
* 钉钉 userid
|
||||
*/
|
||||
@Schema(description = "钉钉 userid")
|
||||
private String wxDingUserid;
|
||||
|
||||
/**
|
||||
* 微信小程序openId
|
||||
*/
|
||||
|
||||
@@ -172,4 +172,16 @@ public class UserVO implements Serializable {
|
||||
@Schema(description = "邮箱")
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 企微微信 userid
|
||||
*/
|
||||
@Schema(description = "企微微信 userid")
|
||||
private String wxCpUserid;
|
||||
|
||||
/**
|
||||
* 钉钉 userid
|
||||
*/
|
||||
@Schema(description = "钉钉 userid")
|
||||
private String wxDingUserid;
|
||||
|
||||
}
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
|
||||
package com.pig4cloud.pigx.admin.handler;
|
||||
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.pig4cloud.pigx.admin.api.dto.UserInfo;
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails;
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysUser;
|
||||
import com.pig4cloud.pigx.admin.mapper.SysSocialDetailsMapper;
|
||||
import com.pig4cloud.pigx.admin.service.SysUserService;
|
||||
import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2023-10-14
|
||||
*
|
||||
* 钉钉登录
|
||||
*/
|
||||
@Slf4j
|
||||
@Component("DINGTALK")
|
||||
@AllArgsConstructor
|
||||
public class DingTalkLoginHandler extends AbstractLoginHandler {
|
||||
|
||||
private final SysUserService sysUserService;
|
||||
|
||||
private final SysSocialDetailsMapper sysSocialDetailsMapper;
|
||||
|
||||
/**
|
||||
* QQ登录传入code
|
||||
* <p>
|
||||
* 通过code 调用qq 获取唯一标识
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String identify(String code) {
|
||||
SysSocialDetails condition = new SysSocialDetails();
|
||||
condition.setType(LoginTypeEnum.DINGTALK.getType());
|
||||
SysSocialDetails socialDetails = sysSocialDetailsMapper.selectOne(new QueryWrapper<>(condition));
|
||||
|
||||
String getAccessTokenUrl = "https://api.dingtalk.com/v1.0/oauth2/userAccessToken";
|
||||
String accessTokenResult = HttpUtil.post(getAccessTokenUrl,
|
||||
JSONUtil.createObj()
|
||||
.set("clientId", socialDetails.getAppId())
|
||||
.set("clientSecret", socialDetails.getAppSecret())
|
||||
.set("grantType", "authorization_code")
|
||||
.set("code", code)
|
||||
.toString());
|
||||
log.debug("获取钉钉Token响应报文:{}", accessTokenResult);
|
||||
String accessToken = JSONUtil.parseObj(accessTokenResult).getStr("accessToken");
|
||||
String getUserIdUrl = "https://api.dingtalk.com/v1.0/contact/users/me";
|
||||
|
||||
String userResult = HttpRequest.get(getUserIdUrl)
|
||||
.header("x-acs-dingtalk-access-token", accessToken)
|
||||
.execute()
|
||||
.body();
|
||||
log.debug("获取钉钉UserId响应报文:{}", userResult);
|
||||
// 企微唯一标识
|
||||
return JSONUtil.parseObj(userResult).getStr("openId");
|
||||
}
|
||||
|
||||
/**
|
||||
* openId 获取用户信息
|
||||
* @param openId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public UserInfo info(String openId) {
|
||||
SysUser user = sysUserService.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getWxDingUserid, openId));
|
||||
|
||||
if (user == null) {
|
||||
log.info("钉钉未绑定:{}", openId);
|
||||
return null;
|
||||
}
|
||||
return sysUserService.findUserInfo(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定逻辑
|
||||
* @param user 用户实体
|
||||
* @param identify 渠道返回唯一标识
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Boolean bind(SysUser user, String identify) {
|
||||
user.setWxDingUserid(identify);
|
||||
sysUserService.updateById(user);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+29
-20
@@ -17,50 +17,59 @@
|
||||
|
||||
package com.pig4cloud.pigx.admin.handler;
|
||||
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.pig4cloud.pigx.admin.api.dto.UserInfo;
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails;
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysUser;
|
||||
import com.pig4cloud.pigx.admin.service.ConnectService;
|
||||
import com.pig4cloud.pigx.admin.mapper.SysSocialDetailsMapper;
|
||||
import com.pig4cloud.pigx.admin.service.SysUserService;
|
||||
import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
|
||||
import me.chanjar.weixin.cp.bean.WxCpOauth2UserInfo;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2022/7/19
|
||||
* @date 2023-10-14
|
||||
*
|
||||
* 企业微信免密登录
|
||||
* 企业微信登录
|
||||
*/
|
||||
@Slf4j
|
||||
@Component("WEIXIN_CP")
|
||||
@Component("CP")
|
||||
@AllArgsConstructor
|
||||
public class WxCpLoginHandler extends AbstractLoginHandler {
|
||||
|
||||
private ConnectService connectService;
|
||||
public class WeChatCPLoginHandler extends AbstractLoginHandler {
|
||||
|
||||
private final SysUserService sysUserService;
|
||||
|
||||
private final SysSocialDetailsMapper sysSocialDetailsMapper;
|
||||
|
||||
/**
|
||||
* 微信登录传入code
|
||||
* QQ登录传入code
|
||||
* <p>
|
||||
* 通过code 调用qq 获取唯一标识
|
||||
* @param code
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public String identify(String code) {
|
||||
WxCpService wxCpService = new WxCpServiceImpl();
|
||||
wxCpService.setWxCpConfigStorage(connectService.getCpConfig());
|
||||
SysSocialDetails condition = new SysSocialDetails();
|
||||
condition.setType(LoginTypeEnum.WEIXIN_CP.getType());
|
||||
SysSocialDetails socialDetails = sysSocialDetailsMapper.selectOne(new QueryWrapper<>(condition));
|
||||
|
||||
WxCpOauth2UserInfo userInfo = wxCpService.getOauth2Service().getUserInfo(code);
|
||||
log.info("企业微信返回报文:{}", userInfo);
|
||||
return userInfo.getUserId();
|
||||
String getAccessTokenUrl = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s";
|
||||
|
||||
String accessTokenResult = HttpUtil
|
||||
.get(String.format(getAccessTokenUrl, socialDetails.getAppId(), socialDetails.getAppSecret()));
|
||||
log.debug("获取企业微信Token响应报文:{}", accessTokenResult);
|
||||
String accessToken = JSONUtil.parseObj(accessTokenResult).getStr("access_token");
|
||||
String getUserIdUrl = "https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token=%s&code=%s";
|
||||
String userResult = HttpUtil.get(String.format(getUserIdUrl, accessToken, code));
|
||||
log.debug("获取企业微信UserId响应报文:{}", userResult);
|
||||
// 企微唯一标识
|
||||
return JSONUtil.parseObj(userResult).getStr("userid");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,7 +79,7 @@ public class WxCpLoginHandler extends AbstractLoginHandler {
|
||||
*/
|
||||
@Override
|
||||
public UserInfo info(String openId) {
|
||||
SysUser user = sysUserService.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getWxOpenid, openId));
|
||||
SysUser user = sysUserService.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getWxCpUserid, openId));
|
||||
|
||||
if (user == null) {
|
||||
log.info("企业微信未绑定:{}", openId);
|
||||
@@ -87,7 +96,7 @@ public class WxCpLoginHandler extends AbstractLoginHandler {
|
||||
*/
|
||||
@Override
|
||||
public Boolean bind(SysUser user, String identify) {
|
||||
user.setWxOpenid(identify);
|
||||
user.setWxCpUserid(identify);
|
||||
sysUserService.updateById(user);
|
||||
return true;
|
||||
}
|
||||
+14
-5
@@ -28,6 +28,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.pig4cloud.pigx.admin.api.constant.UserStateEnum;
|
||||
import com.pig4cloud.pigx.admin.api.dto.UserDTO;
|
||||
import com.pig4cloud.pigx.admin.api.dto.UserInfo;
|
||||
import com.pig4cloud.pigx.admin.api.entity.*;
|
||||
@@ -39,7 +40,6 @@ import com.pig4cloud.pigx.admin.mapper.SysUserRoleMapper;
|
||||
import com.pig4cloud.pigx.admin.service.*;
|
||||
import com.pig4cloud.pigx.common.audit.annotation.Audit;
|
||||
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
|
||||
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
|
||||
import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
|
||||
import com.pig4cloud.pigx.common.core.util.MsgUtils;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
@@ -99,8 +99,8 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
public Boolean saveUser(UserDTO userDto) {
|
||||
SysUser sysUser = new SysUser();
|
||||
BeanUtils.copyProperties(userDto, sysUser);
|
||||
sysUser
|
||||
.setDelFlag(StrUtil.isBlank(userDto.getLockFlag()) ? CommonConstants.STATUS_NORMAL : sysUser.getDelFlag());
|
||||
sysUser.setLockFlag(
|
||||
StrUtil.isBlank(userDto.getLockFlag()) ? UserStateEnum.NORMAL.getCode() : UserStateEnum.LOCK.getCode());
|
||||
sysUser.setCreateBy(userDto.getUsername());
|
||||
sysUser.setUpdateBy(userDto.getUsername());
|
||||
sysUser.setPassword(ENCODER.encode(userDto.getPassword()));
|
||||
@@ -438,7 +438,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
SysUser sysUser = baseMapper.selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, username));
|
||||
|
||||
if (Objects.nonNull(sysUser)) {
|
||||
sysUser.setLockFlag(CommonConstants.STATUS_LOCK);
|
||||
sysUser.setLockFlag(UserStateEnum.LOCK.getCode());
|
||||
baseMapper.updateById(sysUser);
|
||||
}
|
||||
return R.ok();
|
||||
@@ -496,6 +496,16 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
.set(SysUser::getQqOpenid, null)
|
||||
.eq(SysUser::getUserId, user.getId());
|
||||
}
|
||||
else if (type.equals("cp")) {
|
||||
wrapper = Wrappers.<SysUser>lambdaUpdate()
|
||||
.set(SysUser::getWxCpUserid, null)
|
||||
.eq(SysUser::getUserId, user.getId());
|
||||
}
|
||||
else if (type.equals("dingding")) {
|
||||
wrapper = Wrappers.<SysUser>lambdaUpdate()
|
||||
.set(SysUser::getWxDingUserid, null)
|
||||
.eq(SysUser::getUserId, user.getId());
|
||||
}
|
||||
if (wrapper == null) {
|
||||
return R.failed("解绑账号类型不存在");
|
||||
}
|
||||
@@ -536,5 +546,4 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
public List<SysUser> listUserIdByDeptIds(List<Long> deptIdList) {
|
||||
return baseMapper.selectList(Wrappers.<SysUser>lambdaQuery().in(SysUser::getDeptId, deptIdList));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -30,6 +30,8 @@
|
||||
<result column="avatar" property="avatar"/>
|
||||
<result column="wx_openid" property="wxOpenid"/>
|
||||
<result column="qq_openid" property="qqOpenid"/>
|
||||
<result column="wx_cp_userid" property="wxCpUserid"/>
|
||||
<result column="wx_ding_userid" property="wxDingUserid"/>
|
||||
<result column="gitee_login" property="giteeOpenId"/>
|
||||
<result column="osc_id" property="oscOpenId"/>
|
||||
<result column="ucreate_time" property="createTime"/>
|
||||
@@ -59,6 +61,8 @@
|
||||
u.avatar,
|
||||
u.wx_openid,
|
||||
u.qq_openid,
|
||||
u.wx_cp_userid,
|
||||
u.wx_ding_userid,
|
||||
u.dept_id,
|
||||
u.del_flag,
|
||||
u.lock_flag,
|
||||
@@ -83,7 +87,9 @@
|
||||
u.avatar,
|
||||
u.wx_openid,
|
||||
u.qq_openid,
|
||||
u.gitee_login,
|
||||
u.gitee_login,
|
||||
u.wx_cp_userid,
|
||||
u.wx_ding_userid,
|
||||
u.osc_id,
|
||||
u.del_flag,
|
||||
u.lock_flag,
|
||||
@@ -128,6 +134,8 @@
|
||||
u.avatar,
|
||||
u.wx_openid,
|
||||
u.qq_openid,
|
||||
u.wx_cp_userid,
|
||||
u.wx_ding_userid,
|
||||
u.dept_id,
|
||||
u.create_by,
|
||||
u.create_time ucreate_time,
|
||||
@@ -172,6 +180,8 @@
|
||||
u.avatar,
|
||||
u.wx_openid,
|
||||
u.qq_openid,
|
||||
u.wx_cp_userid,
|
||||
u.wx_ding_userid,
|
||||
u.dept_id,
|
||||
u.create_by,
|
||||
u.create_time ucreate_time,
|
||||
|
||||
Reference in new issue
Block a user