UserService.java 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. package com.izouma.jiashanxia.service;
  2. import cn.binarywang.wx.miniapp.api.WxMaService;
  3. import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
  4. import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
  5. import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
  6. import cn.hutool.core.util.ObjectUtil;
  7. import com.izouma.jiashanxia.config.Constants;
  8. import com.izouma.jiashanxia.domain.User;
  9. import com.izouma.jiashanxia.dto.PageQuery;
  10. import com.izouma.jiashanxia.dto.UserRegister;
  11. import com.izouma.jiashanxia.exception.BusinessException;
  12. import com.izouma.jiashanxia.repo.UserRepo;
  13. import com.izouma.jiashanxia.security.Authority;
  14. import com.izouma.jiashanxia.security.JwtTokenUtil;
  15. import com.izouma.jiashanxia.security.JwtUserFactory;
  16. import com.izouma.jiashanxia.service.sms.SmsService;
  17. import com.izouma.jiashanxia.service.storage.StorageService;
  18. import com.izouma.jiashanxia.utils.JpaUtils;
  19. import com.izouma.jiashanxia.utils.SecurityUtils;
  20. import lombok.AllArgsConstructor;
  21. import lombok.extern.slf4j.Slf4j;
  22. import me.chanjar.weixin.common.error.WxErrorException;
  23. import me.chanjar.weixin.mp.api.WxMpService;
  24. import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
  25. import me.chanjar.weixin.mp.bean.result.WxMpUser;
  26. import org.apache.commons.lang3.RandomStringUtils;
  27. import org.apache.commons.lang3.StringUtils;
  28. import org.springframework.beans.BeanUtils;
  29. import org.springframework.data.domain.Page;
  30. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  31. import org.springframework.stereotype.Service;
  32. import java.lang.reflect.InvocationTargetException;
  33. import java.math.BigDecimal;
  34. import java.text.SimpleDateFormat;
  35. import java.util.*;
  36. @Service
  37. @Slf4j
  38. @AllArgsConstructor
  39. public class UserService {
  40. private UserRepo userRepo;
  41. private WxMaService wxMaService;
  42. private WxMpService wxMpService;
  43. private SmsService smsService;
  44. private StorageService storageService;
  45. private JwtTokenUtil jwtTokenUtil;
  46. private CaptchaService captchaService;
  47. public Page<User> all(PageQuery pageQuery) {
  48. return userRepo.findAll(JpaUtils.toSpecification(pageQuery, User.class), JpaUtils.toPageRequest(pageQuery));
  49. }
  50. public User create(UserRegister userRegister) {
  51. User user = new User();
  52. BeanUtils.copyProperties(userRegister, user);
  53. if (StringUtils.isNotBlank(userRegister.getPassword())) {
  54. user.setPassword(new BCryptPasswordEncoder().encode(userRegister.getPassword()));
  55. }
  56. return userRepo.save(user);
  57. }
  58. public User loginByPhone(String phone) {
  59. return userRepo.findByPhone(phone);
  60. }
  61. public User loginMp(String code) throws WxErrorException {
  62. WxMpOAuth2AccessToken accessToken = wxMpService.oauth2getAccessToken(code);
  63. WxMpUser wxMpUser = wxMpService.oauth2getUserInfo(accessToken, null);
  64. User user = userRepo.findByOpenId(wxMpUser.getOpenId());
  65. if (user == null) {
  66. user = User.builder()
  67. .username(UUID.randomUUID().toString())
  68. .nickname(wxMpUser.getNickname())
  69. .avatar(wxMpUser.getHeadImgUrl())
  70. .sex(wxMpUser.getSexDesc())
  71. .country(wxMpUser.getCountry())
  72. .province(wxMpUser.getProvince())
  73. .city(wxMpUser.getCity())
  74. .openId(wxMpUser.getOpenId())
  75. .language(wxMpUser.getLanguage())
  76. .authorities(Collections.singleton(Authority.builder().name("ROLE_USER").build()))
  77. .build();
  78. userRepo.save(user);
  79. }
  80. return user;
  81. }
  82. public User loginMa(String code, Long parent) {
  83. try {
  84. WxMaJscode2SessionResult result = wxMaService.jsCode2SessionInfo(code);
  85. String openId = result.getOpenid();
  86. String sessionKey = result.getSessionKey();
  87. User userInfo = userRepo.findByOpenId(openId);
  88. if (userInfo != null) {
  89. // 上级不为空 && 用户上级为空
  90. if (ObjectUtil.isNotEmpty(parent) && ObjectUtil.isNull(userInfo.getParent())) {
  91. userInfo.setParent(parent);
  92. userRepo.save(userInfo);
  93. }
  94. userInfo.setSessionKey(sessionKey);
  95. return userInfo;
  96. }
  97. userInfo = User.builder()
  98. .username(UUID.randomUUID().toString())
  99. .nickname("用户" + RandomStringUtils.randomAlphabetic(6))
  100. .openId(openId)
  101. .avatar(Constants.DEFAULT_AVATAR)
  102. .authorities(Collections.singleton(Authority.builder().name("ROLE_USER").build()))
  103. .parent(parent)
  104. .amount(BigDecimal.ZERO)
  105. .teamFounder(false)
  106. .sessionKey(sessionKey)
  107. .build();
  108. userInfo = userRepo.save(userInfo);
  109. return userInfo;
  110. } catch (WxErrorException e) {
  111. e.printStackTrace();
  112. }
  113. throw new BusinessException("登录失败");
  114. }
  115. public User getMaUserInfo(String sessionKey, String rawData, String signature,
  116. String encryptedData, String iv) {
  117. // 用户信息校验
  118. if (!wxMaService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
  119. throw new BusinessException("获取用户信息失败");
  120. }
  121. // 解密用户信息
  122. WxMaUserInfo wxUserInfo = wxMaService.getUserService().getUserInfo(sessionKey, encryptedData, iv);
  123. User user = userRepo.findByOpenId(wxUserInfo.getOpenId());
  124. String avatarUrl = Constants.DEFAULT_AVATAR;
  125. try {
  126. String path = "image/avatar/" +
  127. new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()) +
  128. RandomStringUtils.randomAlphabetic(8) +
  129. ".jpg";
  130. avatarUrl = storageService.uploadFromUrl(wxUserInfo.getAvatarUrl(), path);
  131. } catch (Exception e) {
  132. log.error("获取头像失败", e);
  133. }
  134. if (user == null) {
  135. user = User.builder()
  136. .username(UUID.randomUUID().toString())
  137. .nickname(wxUserInfo.getNickName())
  138. .openId(wxUserInfo.getOpenId())
  139. .avatar(avatarUrl)
  140. .sex(wxUserInfo.getGender())
  141. .country(wxUserInfo.getCountry())
  142. .province(wxUserInfo.getProvince())
  143. .city(wxUserInfo.getCity())
  144. .authorities(Collections.singleton(Authority.builder().name("ROLE_USER").build()))
  145. .amount(BigDecimal.ZERO)
  146. .teamFounder(false)
  147. .wxAuthorized(true)
  148. .build();
  149. user = userRepo.save(user);
  150. } else {
  151. user.setAvatar(avatarUrl);
  152. user.setNickname(wxUserInfo.getNickName());
  153. user.setSex(wxUserInfo.getGender());
  154. user.setCountry(wxUserInfo.getCountry());
  155. user.setProvince(wxUserInfo.getProvince());
  156. user.setCity(wxUserInfo.getCity());
  157. user.setWxAuthorized(true);
  158. user = userRepo.save(user);
  159. }
  160. return user;
  161. }
  162. public User getMaPhone(String sessionKey, String encryptedData, String iv) {
  163. // 解密用户信息
  164. WxMaPhoneNumberInfo phoneNoInfo = wxMaService.getUserService().getPhoneNoInfo(sessionKey, encryptedData, iv);
  165. User user = userRepo.findById(SecurityUtils.getAuthenticatedUser().getId())
  166. .orElseThrow(new BusinessException("用户不存在"));
  167. user.setPhone(phoneNoInfo.getPhoneNumber());
  168. return userRepo.save(user);
  169. }
  170. public String setPassword(Long userId, String password) {
  171. User user = userRepo.findById(userId).orElseThrow(new BusinessException("用户不存在"));
  172. user.setPassword(new BCryptPasswordEncoder().encode(password));
  173. user = userRepo.save(user);
  174. return jwtTokenUtil.generateToken(JwtUserFactory.create(user));
  175. }
  176. public String setPassword(Long userId, String key, String code, String password) {
  177. if (!captchaService.verify(key, code)) {
  178. throw new BusinessException("验证码错误");
  179. }
  180. return setPassword(userId, password);
  181. }
  182. public void updateUserInfo(Map<String, Object> data) {
  183. User user = userRepo.findById(SecurityUtils.getAuthenticatedUser().getId())
  184. .orElseThrow(new BusinessException("用户不存在"));
  185. try {
  186. org.apache.commons.beanutils.BeanUtils.populate(user, data);
  187. } catch (IllegalAccessException | InvocationTargetException e) {
  188. log.error("updateUserInfo", e);
  189. }
  190. userRepo.save(user);
  191. }
  192. }