diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysUser.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysUser.java index 175d58880..edc0bdd9b 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysUser.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysUser.java @@ -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 */ diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/UserVO.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/UserVO.java index b356bdb27..1451d83a8 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/UserVO.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/UserVO.java @@ -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; + } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/DingTalkLoginHandler.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/DingTalkLoginHandler.java new file mode 100644 index 000000000..5a0cb243f --- /dev/null +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/DingTalkLoginHandler.java @@ -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 + *

+ * 通过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.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; + } + +} diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/WxCpLoginHandler.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/WeChatCPLoginHandler.java similarity index 56% rename from pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/WxCpLoginHandler.java rename to pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/WeChatCPLoginHandler.java index bd27156a9..16bc5e114 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/WxCpLoginHandler.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/handler/WeChatCPLoginHandler.java @@ -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 *

* 通过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.query().lambda().eq(SysUser::getWxOpenid, openId)); + SysUser user = sysUserService.getOne(Wrappers.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; } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysUserServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysUserServiceImpl.java index f5e686830..9942a8955 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysUserServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysUserServiceImpl.java @@ -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 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 impl SysUser sysUser = baseMapper.selectOne(Wrappers.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 impl .set(SysUser::getQqOpenid, null) .eq(SysUser::getUserId, user.getId()); } + else if (type.equals("cp")) { + wrapper = Wrappers.lambdaUpdate() + .set(SysUser::getWxCpUserid, null) + .eq(SysUser::getUserId, user.getId()); + } + else if (type.equals("dingding")) { + wrapper = Wrappers.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 impl public List listUserIdByDeptIds(List deptIdList) { return baseMapper.selectList(Wrappers.lambdaQuery().in(SysUser::getDeptId, deptIdList)); } - } diff --git a/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysUserMapper.xml b/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysUserMapper.xml index fe98b08ca..340044d10 100644 --- a/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysUserMapper.xml +++ b/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysUserMapper.xml @@ -30,6 +30,8 @@ + + @@ -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,