UserService.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  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.EmployeeDTO;
  10. import com.izouma.jiashanxia.dto.PageQuery;
  11. import com.izouma.jiashanxia.dto.UserRegister;
  12. import com.izouma.jiashanxia.enums.AuthorityName;
  13. import com.izouma.jiashanxia.exception.BusinessException;
  14. import com.izouma.jiashanxia.repo.UserRepo;
  15. import com.izouma.jiashanxia.security.Authority;
  16. import com.izouma.jiashanxia.security.JwtTokenUtil;
  17. import com.izouma.jiashanxia.security.JwtUserFactory;
  18. import com.izouma.jiashanxia.service.sms.SmsService;
  19. import com.izouma.jiashanxia.service.storage.StorageService;
  20. import com.izouma.jiashanxia.utils.JpaUtils;
  21. import com.izouma.jiashanxia.utils.SecurityUtils;
  22. import lombok.AllArgsConstructor;
  23. import lombok.extern.slf4j.Slf4j;
  24. import me.chanjar.weixin.common.error.WxErrorException;
  25. import me.chanjar.weixin.mp.api.WxMpService;
  26. import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
  27. import me.chanjar.weixin.mp.bean.result.WxMpUser;
  28. import org.apache.commons.lang3.RandomStringUtils;
  29. import org.apache.commons.lang3.StringUtils;
  30. import org.springframework.beans.BeanUtils;
  31. import org.springframework.data.domain.Page;
  32. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  33. import org.springframework.stereotype.Service;
  34. import javax.persistence.criteria.Predicate;
  35. import java.lang.reflect.InvocationTargetException;
  36. import java.math.BigDecimal;
  37. import java.text.SimpleDateFormat;
  38. import java.util.*;
  39. import java.util.stream.Collectors;
  40. @Service
  41. @Slf4j
  42. @AllArgsConstructor
  43. public class UserService {
  44. private UserRepo userRepo;
  45. private WxMaService wxMaService;
  46. private WxMpService wxMpService;
  47. private SmsService smsService;
  48. private StorageService storageService;
  49. private JwtTokenUtil jwtTokenUtil;
  50. private CaptchaService captchaService;
  51. public Page<User> all(PageQuery pageQuery) {
  52. return userRepo.findAll(JpaUtils.toSpecification(pageQuery, User.class), JpaUtils.toPageRequest(pageQuery));
  53. }
  54. public User create(UserRegister userRegister) {
  55. User user = new User();
  56. BeanUtils.copyProperties(userRegister, user);
  57. if (StringUtils.isNotBlank(userRegister.getPassword())) {
  58. user.setPassword(new BCryptPasswordEncoder().encode(userRegister.getPassword()));
  59. }
  60. return userRepo.save(user);
  61. }
  62. public User loginByPhone(String phone) {
  63. return userRepo.findByPhone(phone);
  64. }
  65. public User loginMp(String code) throws WxErrorException {
  66. WxMpOAuth2AccessToken accessToken = wxMpService.oauth2getAccessToken(code);
  67. WxMpUser wxMpUser = wxMpService.oauth2getUserInfo(accessToken, null);
  68. User user = userRepo.findByOpenId(wxMpUser.getOpenId());
  69. if (user == null) {
  70. user = User.builder()
  71. .username(UUID.randomUUID().toString())
  72. .nickname(wxMpUser.getNickname())
  73. .avatar(wxMpUser.getHeadImgUrl())
  74. .sex(wxMpUser.getSexDesc())
  75. .country(wxMpUser.getCountry())
  76. .province(wxMpUser.getProvince())
  77. .city(wxMpUser.getCity())
  78. .openId(wxMpUser.getOpenId())
  79. .language(wxMpUser.getLanguage())
  80. .authorities(Collections.singleton(Authority.builder().name("ROLE_USER").build()))
  81. .build();
  82. userRepo.save(user);
  83. }
  84. return user;
  85. }
  86. public User loginMa(String code, Long parent) {
  87. try {
  88. WxMaJscode2SessionResult result = wxMaService.jsCode2SessionInfo(code);
  89. String openId = result.getOpenid();
  90. String sessionKey = result.getSessionKey();
  91. User userInfo = userRepo.findByOpenId(openId);
  92. if (userInfo != null) {
  93. // 上级不为空 && 用户上级为空
  94. if (ObjectUtil.isNotEmpty(parent) && ObjectUtil.isNull(userInfo.getParent())) {
  95. userInfo.setParent(parent);
  96. userRepo.save(userInfo);
  97. }
  98. userInfo.setSessionKey(sessionKey);
  99. return userInfo;
  100. }
  101. userInfo = User.builder()
  102. .username(UUID.randomUUID().toString())
  103. .nickname("用户" + RandomStringUtils.randomAlphabetic(6))
  104. .openId(openId)
  105. .avatar(Constants.DEFAULT_AVATAR)
  106. .authorities(Collections.singleton(Authority.builder().name("ROLE_USER").build()))
  107. .parent(parent)
  108. .amount(BigDecimal.ZERO)
  109. .teamFounder(false)
  110. .sessionKey(sessionKey)
  111. .build();
  112. userInfo = userRepo.save(userInfo);
  113. return userInfo;
  114. } catch (WxErrorException e) {
  115. e.printStackTrace();
  116. }
  117. throw new BusinessException("登录失败");
  118. }
  119. public User getMaUserInfo(String sessionKey, String rawData, String signature,
  120. String encryptedData, String iv) {
  121. // 用户信息校验
  122. if (!wxMaService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
  123. throw new BusinessException("获取用户信息失败");
  124. }
  125. // 解密用户信息
  126. WxMaUserInfo wxUserInfo = wxMaService.getUserService().getUserInfo(sessionKey, encryptedData, iv);
  127. User user = userRepo.findByOpenId(wxUserInfo.getOpenId());
  128. String avatarUrl = Constants.DEFAULT_AVATAR;
  129. try {
  130. String path = "image/avatar/" +
  131. new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()) +
  132. RandomStringUtils.randomAlphabetic(8) +
  133. ".jpg";
  134. avatarUrl = storageService.uploadFromUrl(wxUserInfo.getAvatarUrl(), path);
  135. } catch (Exception e) {
  136. log.error("获取头像失败", e);
  137. }
  138. if (user == null) {
  139. user = User.builder()
  140. .username(UUID.randomUUID().toString())
  141. .nickname(wxUserInfo.getNickName())
  142. .openId(wxUserInfo.getOpenId())
  143. .avatar(avatarUrl)
  144. .sex(wxUserInfo.getGender())
  145. .country(wxUserInfo.getCountry())
  146. .province(wxUserInfo.getProvince())
  147. .city(wxUserInfo.getCity())
  148. .authorities(Collections.singleton(Authority.builder().name("ROLE_USER").build()))
  149. .amount(BigDecimal.ZERO)
  150. .teamFounder(false)
  151. .wxAuthorized(true)
  152. .build();
  153. user = userRepo.save(user);
  154. } else {
  155. user.setAvatar(avatarUrl);
  156. user.setNickname(wxUserInfo.getNickName());
  157. user.setSex(wxUserInfo.getGender());
  158. user.setCountry(wxUserInfo.getCountry());
  159. user.setProvince(wxUserInfo.getProvince());
  160. user.setCity(wxUserInfo.getCity());
  161. user.setWxAuthorized(true);
  162. user = userRepo.save(user);
  163. }
  164. return user;
  165. }
  166. public User getMaPhone(String sessionKey, String encryptedData, String iv) {
  167. // 解密用户信息
  168. WxMaPhoneNumberInfo phoneNoInfo = wxMaService.getUserService().getPhoneNoInfo(sessionKey, encryptedData, iv);
  169. User user = userRepo.findById(SecurityUtils.getAuthenticatedUser().getId())
  170. .orElseThrow(new BusinessException("用户不存在"));
  171. user.setPhone(phoneNoInfo.getPhoneNumber());
  172. return userRepo.save(user);
  173. }
  174. public String setPassword(Long userId, String password) {
  175. User user = userRepo.findById(userId).orElseThrow(new BusinessException("用户不存在"));
  176. user.setPassword(new BCryptPasswordEncoder().encode(password));
  177. user = userRepo.save(user);
  178. return jwtTokenUtil.generateToken(JwtUserFactory.create(user));
  179. }
  180. public String setPassword(Long userId, String key, String code, String password) {
  181. if (!captchaService.verify(key, code)) {
  182. throw new BusinessException("验证码错误");
  183. }
  184. return setPassword(userId, password);
  185. }
  186. public void updateUserInfo(Map<String, Object> data) {
  187. User user = userRepo.findById(SecurityUtils.getAuthenticatedUser().getId())
  188. .orElseThrow(new BusinessException("用户不存在"));
  189. try {
  190. org.apache.commons.beanutils.BeanUtils.populate(user, data);
  191. } catch (IllegalAccessException | InvocationTargetException e) {
  192. log.error("updateUserInfo", e);
  193. }
  194. userRepo.save(user);
  195. }
  196. /*
  197. 我的推广
  198. */
  199. public List<User> myPromotion(Long userId) {
  200. User user = userRepo.findById(userId).orElseThrow(new BusinessException("无用户"));
  201. List<User> users = new ArrayList<>();
  202. // 如果是企业创始人,查出下级所有推广
  203. if (user.getTeamFounder()) {
  204. List<User> employees = userRepo.findAllByCompanyId(user.getCompanyId());
  205. List<Long> collect = employees.stream().map(User::getId).collect(Collectors.toList());
  206. users.addAll(userRepo.findAllByParentIn(collect));
  207. }
  208. users.addAll(userRepo.findAllByParent(userId));
  209. return users;
  210. }
  211. /*
  212. 我的推广
  213. */
  214. public Page<User> myPromotion(PageQuery pageQuery, Long userId) {
  215. User user = userRepo.findById(userId).orElseThrow(new BusinessException("无用户"));
  216. return userRepo.findAll(((root, criteriaQuery, criteriaBuilder) -> {
  217. List<Predicate> and = JpaUtils.toPredicates(pageQuery, User.class, root, criteriaQuery, criteriaBuilder);
  218. if (user.getTeamFounder()) {
  219. List<User> employees = userRepo.findAllByCompanyId(user.getCompanyId());
  220. List<Long> collect = employees.stream().map(User::getId).collect(Collectors.toList());
  221. and.add(root.get("parent").in(collect));
  222. } else {
  223. and.add(criteriaBuilder.equal(root.get("parent"), userId));
  224. }
  225. return criteriaBuilder.and(and.toArray(new Predicate[0]));
  226. }), JpaUtils.toPageRequest(pageQuery));
  227. }
  228. /*
  229. 我的员工
  230. */
  231. public Page<User> myEmployee(PageQuery pageQuery, User user) {
  232. // User user = userRepo.findById(id).orElseThrow(new BusinessException("无用户"));
  233. Set<Authority> authorities = user.getAuthorities();
  234. // 管理员返回所有
  235. if (authorities.contains(Authority.get(AuthorityName.ROLE_ADMIN))) {
  236. return userRepo.findAll(((root, criteriaQuery, criteriaBuilder) -> {
  237. List<Predicate> and = JpaUtils.toPredicates(pageQuery, User.class, root, criteriaQuery, criteriaBuilder);
  238. and.add(root.get("companyId").isNotNull());
  239. return criteriaBuilder.and(and.toArray(new Predicate[0]));
  240. }), JpaUtils.toPageRequest(pageQuery));
  241. }
  242. if (ObjectUtil.isNull(user.getCompanyId())) {
  243. throw new BusinessException("无企业");
  244. }
  245. // 返回企业员工
  246. return userRepo.findAll(((root, criteriaQuery, criteriaBuilder) -> {
  247. List<Predicate> and = JpaUtils.toPredicates(pageQuery, User.class, root, criteriaQuery, criteriaBuilder);
  248. and.add(criteriaBuilder.equal(root.get("companyId"), user.getCompanyId()));
  249. return criteriaBuilder.and(and.toArray(new Predicate[0]));
  250. }), JpaUtils.toPageRequest(pageQuery));
  251. }
  252. }