WechatCpServiceImpl.java 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. package com.ydtech.modules.admin.service.impl;
  2. import cn.dev33.satoken.session.SaSession;
  3. import cn.dev33.satoken.stp.StpUtil;
  4. import cn.hutool.http.HttpUtil;
  5. import com.alibaba.fastjson.JSON;
  6. import com.alibaba.fastjson.JSONObject;
  7. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  8. import com.ydtech.constants.sys.SysPasswordEnum;
  9. import com.ydtech.exception.SystemException;
  10. import com.ydtech.modules.admin.model.SysPassword;
  11. import com.ydtech.modules.admin.model.SysUser;
  12. import com.ydtech.modules.admin.service.*;
  13. import com.ydtech.core.page.HttpResult;
  14. import com.ydtech.modules.admin.model.SysWechatWork;
  15. import com.ydtech.modules.admin.model.vo.WechatCpBindVo;
  16. import com.ydtech.security.utils.PasswordUtils;
  17. import com.ydtech.utils.StringUtils;
  18. import lombok.RequiredArgsConstructor;
  19. import lombok.extern.slf4j.Slf4j;
  20. import me.chanjar.weixin.common.error.WxErrorException;
  21. import org.springframework.beans.factory.annotation.Value;
  22. import org.springframework.data.redis.core.StringRedisTemplate;
  23. import org.springframework.stereotype.Service;
  24. import javax.annotation.Resource;
  25. import java.util.concurrent.TimeUnit;
  26. @Slf4j
  27. @Service
  28. @RequiredArgsConstructor
  29. public class WechatCpServiceImpl implements WechatCpService {
  30. private final SysWechatWorkService sysWechatWorkService;
  31. @Resource
  32. private SysUserService sysUserService;
  33. private final SysPasswordService sysPasswordService;
  34. @Value("${wechat.cp.corp-id}")
  35. private String corpId;
  36. @Value("${wechat.cp.secret}")
  37. private String corpSecret;
  38. @Value("${wechat.cp.agent-id}")
  39. private Integer agentId;
  40. private static final String ACCESS_TOKEN_KEY = "access_token";
  41. private final StringRedisTemplate redisTemplate;
  42. // 获取accessToken
  43. private String fetchAccessToken() {
  44. String accessTokenUrl = String.format("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s", corpId, corpSecret);
  45. String response = HttpUtil.get(accessTokenUrl);
  46. JSONObject jsonObject = JSON.parseObject(response);
  47. return jsonObject.getString("access_token");
  48. }
  49. public String getAccessToken() {
  50. String accessToken = redisTemplate.opsForValue().get(ACCESS_TOKEN_KEY);
  51. if (StringUtils.isEmpty(accessToken)) {
  52. accessToken = fetchAccessToken();
  53. // access_token 有效期为 7200 秒
  54. redisTemplate.opsForValue().set(ACCESS_TOKEN_KEY, accessToken, 7000, TimeUnit.SECONDS);
  55. }
  56. return accessToken;
  57. }
  58. // 通过 accessToken 和 code 获取企业微信用户信息
  59. private JSONObject getUserInfo(String code) {
  60. try {
  61. String userInfoUrl = String.format("https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token=%s&code=%s", getAccessToken(), code);
  62. String userInfoResponse = HttpUtil.get(userInfoUrl);
  63. return JSON.parseObject(userInfoResponse);
  64. } catch (Exception e) {
  65. throw new SystemException("500", e.getMessage());
  66. }
  67. }
  68. // 根据openid获取绑定用户信息
  69. private SysWechatWork getWechatWorkByOpenid(String openid) {
  70. return sysWechatWorkService.getOne(new LambdaQueryWrapper<SysWechatWork>().eq(SysWechatWork::getOpenid, openid));
  71. }
  72. private HttpResult<Object> loginUser(String userId) {
  73. SysUser user = sysUserService.getById(userId);
  74. String token = StpUtil.createLoginSession(userId);
  75. StpUtil.getSessionByLoginId(userId).set(SaSession.USER, user);
  76. return HttpResult.ok(token);
  77. }
  78. private HttpResult<Object> handleNewUserBinding(WechatCpBindVo wechatCpBindVo, String openid) {
  79. String userId = wechatCpBindVo.getUserId();
  80. String password = wechatCpBindVo.getPassword();
  81. // 验证工号是否正确
  82. if (userId.contains("M")) {
  83. throw new SystemException("该用户不是后线人员");
  84. }
  85. // 获取用户和密码信息
  86. SysUser user = sysUserService.getById(userId);
  87. SysUser.verifyUser(user);
  88. SysPassword sysPassword = sysPasswordService.getOne(new LambdaQueryWrapper<SysPassword>().eq(SysPassword::getCode, SysPasswordEnum.GENERAL.getCode()));
  89. // 验证密码
  90. if (!"admin".equals(userId) && PasswordUtils.matches(sysPassword.getSalt(), password, sysPassword.getPassword())) {
  91. log.info("万能密码登录系统");
  92. } else if (!PasswordUtils.matches(user.getSalt(), password, user.getPassword())) {
  93. return HttpResult.error("密码不正确");
  94. }
  95. // 保存绑定关系并返回 token
  96. SysWechatWork newWechatWork = new SysWechatWork();
  97. newWechatWork.setUserId(userId);
  98. newWechatWork.setOpenid(openid);
  99. sysWechatWorkService.save(newWechatWork);
  100. return loginUser(userId);
  101. }
  102. public HttpResult<Object> verifyBind(WechatCpBindVo wechatCpBindVo) {
  103. // 获取企业微信用户信息
  104. JSONObject userInfoJson = getUserInfo(wechatCpBindVo.getCode());
  105. System.out.println(userInfoJson);
  106. // 验证获取用户信息是否成功
  107. if (userInfoJson.containsKey("userid")) {
  108. String openid = userInfoJson.getString("userid");
  109. SysWechatWork wechatWork = getWechatWorkByOpenid(openid);
  110. if (wechatWork != null) {
  111. // 已绑定用户直接返回token
  112. return loginUser(wechatWork.getUserId());
  113. } else {
  114. // 用户信息验证成功,但尚未绑定
  115. return HttpResult.error(null);
  116. }
  117. } else {
  118. // 获取用户信息失败
  119. throw new SystemException("未能获取到企业微信用户信息");
  120. }
  121. }
  122. @Override
  123. public HttpResult<Object> bind(WechatCpBindVo wechatCpBindVo) throws WxErrorException {
  124. // 获取企业微信用户信息
  125. JSONObject userInfoJson = getUserInfo(wechatCpBindVo.getCode());
  126. // 验证获取用户信息是否成功
  127. if (userInfoJson.containsKey("userid")) {
  128. String openid = userInfoJson.getString("userid");
  129. // 处理新的用户绑定
  130. return handleNewUserBinding(wechatCpBindVo, openid);
  131. } else {
  132. // 获取用户信息失败
  133. throw new SystemException("未能获取到企业微信用户信息");
  134. }
  135. }
  136. }