xiongzhu 4 лет назад
Родитель
Сommit
30d474e21d

+ 6 - 3
src/main/java/com/izouma/nineth/repo/UserRepo.java

@@ -9,6 +9,7 @@ import org.springframework.data.jpa.repository.Query;
 
 import javax.transaction.Transactional;
 import java.util.List;
+import java.util.Optional;
 
 public interface UserRepo extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
     @Transactional
@@ -16,11 +17,13 @@ public interface UserRepo extends JpaRepository<User, Long>, JpaSpecificationExe
     @Query("update User u set u.del = true where u.id = ?1")
     void softDelete(Long id);
 
-    User findByUsernameAndDelFalse(String username);
+    Optional<User> findByUsernameAndDelFalse(String username);
 
     List<User> findAllByAuthoritiesContainsAndDelFalse(Authority authority);
 
-    User findByOpenIdAndDelFalse(String openId);
+    Optional<User> findByOpenIdAndDelFalse(String openId);
 
-    User findByPhoneAndDelFalse(String phone);
+    Optional<User> findByPhoneAndDelFalse(String phone);
+
+    Optional<User> findByIdAndDelFalse(Long userId);
 }

+ 1 - 1
src/main/java/com/izouma/nineth/security/JwtUserDetailsService.java

@@ -15,7 +15,7 @@ public class JwtUserDetailsService implements UserDetailsService {
 
     @Override
     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
-        User user = userRepo.findByUsernameAndDelFalse(username);
+        User user = userRepo.findByUsernameAndDelFalse(username).orElse(null);
 
         if (user == null) {
             throw new UsernameNotFoundException(String.format("No user found with username '%s'.", username));

+ 46 - 5
src/main/java/com/izouma/nineth/service/UserService.java

@@ -83,14 +83,38 @@ public class UserService {
         userRepo.save(user);
     }
 
-    public User loginByPhone(String phone) {
-        return userRepo.findByPhoneAndDelFalse(phone);
+    public User loginByPhone(String phone, String code) {
+        smsService.verify(phone, code);
+        User user = userRepo.findByPhoneAndDelFalse(phone).orElse(null);
+        ;
+        if (user == null) {
+            String name = "9th_" + RandomStringUtils.randomAlphabetic(8);
+            user = create(UserRegister.builder()
+                    .authorities(Collections.singleton(Authority.get(AuthorityName.ROLE_USER)))
+                    .username(name)
+                    .nickname(name)
+                    .avatar(Constants.DEFAULT_AVATAR)
+                    .phone(phone)
+                    .build());
+        }
+        return user;
+    }
+
+    public User loginByPhonePwd(String phone, String password) {
+        User user = userRepo.findByPhoneAndDelFalse(phone).orElseThrow(new BusinessException("账号或密码错误"));
+
+        if (StringUtils.isNoneEmpty(user.getPassword()) &&
+                new BCryptPasswordEncoder().matches(password, user.getPassword())) {
+            throw new BusinessException("账号或密码错误");
+        }
+
+        return user;
     }
 
     public User loginMp(String code) throws WxErrorException {
         WxMpOAuth2AccessToken accessToken = wxMpService.oauth2getAccessToken(code);
         WxMpUser wxMpUser = wxMpService.oauth2getUserInfo(accessToken, null);
-        User user = userRepo.findByOpenIdAndDelFalse(wxMpUser.getOpenId());
+        User user = userRepo.findByOpenIdAndDelFalse(wxMpUser.getOpenId()).orElse(null);
         if (user == null) {
             user = User.builder()
                     .username(UUID.randomUUID().toString())
@@ -114,7 +138,8 @@ public class UserService {
             WxMaJscode2SessionResult result = wxMaService.jsCode2SessionInfo(code);
             String openId = result.getOpenid();
             String sessionKey = result.getSessionKey();
-            User userInfo = userRepo.findByOpenIdAndDelFalse(openId);
+            User userInfo = userRepo.findByOpenIdAndDelFalse(openId).orElse(null);
+            ;
             if (userInfo != null) {
                 return userInfo;
             }
@@ -142,7 +167,8 @@ public class UserService {
 
         // 解密用户信息
         WxMaUserInfo wxUserInfo = wxMaService.getUserService().getUserInfo(sessionKey, encryptedData, iv);
-        User user = userRepo.findByOpenIdAndDelFalse(wxUserInfo.getOpenId());
+        User user = userRepo.findByOpenIdAndDelFalse(wxUserInfo.getOpenId()).orElse(null);
+        ;
 
         String avatarUrl = Constants.DEFAULT_AVATAR;
         try {
@@ -196,4 +222,19 @@ public class UserService {
         }
         return setPassword(userId, password);
     }
+
+    public void bindPhone(Long userId, String phone) {
+        User user = userRepo.findByIdAndDelFalse(userId).orElseThrow(new BusinessException("用户不存在"));
+        if (StringUtils.isNoneEmpty(user.getPhone())) {
+            throw new BusinessException("该账号已绑定手机");
+        }
+        userRepo.findByPhoneAndDelFalse(phone).ifPresent(user1 -> {
+            if (!user1.getId().equals(userId)) {
+                throw new BusinessException("该手机号已绑定其他账号");
+            }
+        });
+
+        user.setPhone(phone);
+        userRepo.save(user);
+    }
 }

+ 11 - 9
src/main/java/com/izouma/nineth/service/sms/AliSmsService.java

@@ -36,7 +36,8 @@ public class AliSmsService implements SmsService {
     public String sendVerify(String phone) {
         smsRecordRepo.findLastByPhoneAndExpiresAtAfterAndExpiredFalse(phone, LocalDateTime.now()).ifPresent(record -> {
             if (record.getCreatedAt().plusMinutes(1L).isAfter(LocalDateTime.now())) {
-                long sec = record.getCreatedAt().plusMinutes(1L).toInstant(ZoneOffset.UTC).getEpochSecond() - LocalDateTime.now().toInstant(ZoneOffset.UTC).getEpochSecond() + 1;
+                long sec = record.getCreatedAt().plusMinutes(1L).toInstant(ZoneOffset.UTC)
+                        .getEpochSecond() - LocalDateTime.now().toInstant(ZoneOffset.UTC).getEpochSecond() + 1;
                 throw new BusinessException("请" + sec + "秒后再试");
             }
         });
@@ -67,12 +68,12 @@ public class AliSmsService implements SmsService {
             smsRecordRepo.expire(phone);
             String sessionId = RandomStringUtils.randomAlphabetic(10);
             smsRecordRepo.save(SmsRecord.builder()
-                                        .sessionId(sessionId)
-                                        .phone(phone)
-                                        .code(code)
-                                        .expiresAt(LocalDateTime.now().plusMinutes(5))
-                                        .expired(false)
-                                        .build());
+                    .sessionId(sessionId)
+                    .phone(phone)
+                    .code(code)
+                    .expiresAt(LocalDateTime.now().plusMinutes(5))
+                    .expired(false)
+                    .build());
             return sessionId;
         } catch (ClientException | JSONException e) {
             e.printStackTrace();
@@ -81,8 +82,9 @@ public class AliSmsService implements SmsService {
     }
 
     @Override
-    public void verify(String phone, String code) throws SmsVerifyException {
-        SmsRecord smsRecord = smsRecordRepo.findLastByPhoneAndExpiresAtAfterAndExpiredFalse(phone, LocalDateTime.now()).orElseThrow(new SmsVerifyException("验证码错误"));
+    public void verify(String phone, String code) {
+        SmsRecord smsRecord = smsRecordRepo.findLastByPhoneAndExpiresAtAfterAndExpiredFalse(phone, LocalDateTime.now())
+                .orElseThrow(new BusinessException("验证码错误"));
         if (!smsRecord.getCode().equalsIgnoreCase(code)) {
             throw new BusinessException("验证码错误");
         }

+ 1 - 1
src/main/java/com/izouma/nineth/service/sms/SmsService.java

@@ -5,7 +5,7 @@ import java.util.function.Supplier;
 public interface SmsService {
     String sendVerify(String phone);
 
-    void verify(String phone, String code) throws SmsVerifyException;
+    void verify(String phone, String code);
 
     class SmsVerifyException extends Exception implements Supplier<SmsVerifyException> {
         public SmsVerifyException(String msg) {

+ 12 - 9
src/main/java/com/izouma/nineth/web/AuthenticationController.java

@@ -7,6 +7,7 @@ import com.izouma.nineth.security.JwtTokenUtil;
 import com.izouma.nineth.security.JwtUser;
 import com.izouma.nineth.security.JwtUserFactory;
 import com.izouma.nineth.service.UserService;
+import com.izouma.nineth.service.sms.SmsService;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -49,15 +50,17 @@ public class AuthenticationController {
     }
 
     @PostMapping("/phoneLogin")
-    @ApiOperation(value = "手机号登录")
-    public String phoneLogin(String phone) {
-        try {
-            User user = userService.loginByPhone(phone);
-            return jwtTokenUtil.generateToken(JwtUserFactory.create(user));
-        } catch (Exception e) {
-            log.error("loginByPhone", e);
-            throw new AuthenticationException("登陆错误", e);
-        }
+    @ApiOperation(value = "手机号验证码登录")
+    public String phoneLogin(String phone, String code) {
+        User user = userService.loginByPhone(phone, code);
+        return jwtTokenUtil.generateToken(JwtUserFactory.create(user));
+    }
+
+    @PostMapping("/phonePwdLogin")
+    @ApiOperation(value = "手机号密码登录")
+    public String phonePwdLogin(String phone, String password) {
+        User user = userService.loginByPhonePwd(phone, password);
+        return jwtTokenUtil.generateToken(JwtUserFactory.create(user));
     }
 
     @PostMapping("/mpLogin")

+ 5 - 0
src/main/java/com/izouma/nineth/web/UserController.java

@@ -127,4 +127,9 @@ public class UserController extends BaseController {
         return jwtTokenUtil.generateToken(JwtUserFactory.create(userRepo.findById(userId)
                 .orElseThrow(new BusinessException("用户不存在"))));
     }
+
+    @PostMapping("/bindPhone")
+    public void bindPhone(@RequestParam String phone) {
+        userService.bindPhone(SecurityUtils.getAuthenticatedUser().getId(), phone);
+    }
 }

+ 0 - 3
src/test/java/com/izouma/nineth/repo/UserRepoTest.java

@@ -30,9 +30,6 @@ public class UserRepoTest {
     @Test
     public void createUser() {
 
-        User user = userRepo.findByUsernameAndDelFalse("root");
-        user.setPassword(new BCryptPasswordEncoder().encode("123456"));
-        userRepo.save(user);
     }
 
     @Test