ソースを参照

完善账号注册功能

Junling Bu 7 年 前
コミット
35d08ff02e

+ 8 - 3
litemall-core/src/main/java/org/linlinjava/litemall/core/notify/NotifyService.java

@@ -44,13 +44,18 @@ public class NotifyService {
      * @param params      通知模版内容里的参数,类似"您的验证码为{1}"中{1}的值
      */
     @Async
-    public void notifySmsTemplate(String phoneNumber, NotifyType notifyType, String[] params) {
+    public boolean notifySmsTemplate(String phoneNumber, NotifyType notifyType, String[] params) {
         if (smsSender == null)
-            return;
+            return false;
 
-        int templateId = Integer.parseInt(getTemplateId(notifyType, smsTemplate));
+        String templateIdStr = getTemplateId(notifyType, smsTemplate);
+        if (templateIdStr == null){
+            return false;
+        }
 
+        int templateId = Integer.parseInt(templateIdStr);
         smsSender.sendWithTemplate(phoneNumber, templateId, params);
+        return true;
     }
 
     /**

+ 6 - 0
litemall-db/src/main/java/org/linlinjava/litemall/db/service/LitemallUserService.java

@@ -97,6 +97,12 @@ public class LitemallUserService {
         return userMapper.selectByExample(example);
     }
 
+    public List<LitemallUser> queryByOpenid(String openid) {
+        LitemallUserExample example = new LitemallUserExample();
+        example.or().andWeixinOpenidEqualTo(openid).andDeletedEqualTo(false);
+        return userMapper.selectByExample(example);
+    }
+
     public void deleteById(Integer id) {
         userMapper.logicalDeleteByPrimaryKey(id);
     }

+ 46 - 12
litemall-wx-api/src/main/java/org/linlinjava/litemall/wx/web/WxAuthController.java

@@ -22,6 +22,7 @@ import org.linlinjava.litemall.wx.service.CaptchaCodeManager;
 import org.linlinjava.litemall.wx.service.UserTokenManager;
 import org.linlinjava.litemall.wx.util.IpUtil;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.StringUtils;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
@@ -150,8 +151,8 @@ public class WxAuthController {
         LitemallUser user = userService.queryByOid(openId);
         if (user == null) {
             user = new LitemallUser();
-            user.setUsername(userInfo.getNickName());  // 其实没有用,因为用户没有真正注册
-            user.setPassword(openId);                  // 其实没有用,因为用户没有真正注册
+            user.setUsername(openId);
+            user.setPassword(openId);
             user.setWeixinOpenid(openId);
             user.setAvatar(userInfo.getAvatarUrl());
             user.setNickname(userInfo.getNickName());
@@ -192,12 +193,25 @@ public class WxAuthController {
     @PostMapping("regCaptcha")
     public Object registerCaptcha(@RequestBody String body) {
         String phoneNumber = JacksonUtil.parseString(body, "mobile");
+        if(StringUtils.isEmpty(phoneNumber)){
+            return ResponseUtil.badArgument();
+        }
+        if(!RegexUtil.isMobileExact(phoneNumber)){
+            return ResponseUtil.badArgumentValue();
+        }
+
         String code = CharUtil.getRandomNum(6);
+        boolean successful = notifyService.notifySmsTemplate(phoneNumber, NotifyType.CAPTCHA, new String[]{code});
+        if(!successful){
+            return ResponseUtil.fail(404, "小程序后台验证码服务不支持");
+        }
 
-        notifyService.notifySmsTemplate(phoneNumber, NotifyType.CAPTCHA, new String[]{code});
+        successful = CaptchaCodeManager.addToCache(phoneNumber, code);
+        if(!successful){
+            return ResponseUtil.fail(404, "验证码未超时1分钟,不能发送");
+        }
 
-        boolean successful = CaptchaCodeManager.addToCache(phoneNumber, code);
-        return successful ? ResponseUtil.ok() : ResponseUtil.badArgument();
+        return ResponseUtil.ok();
     }
 
     /**
@@ -231,9 +245,11 @@ public class WxAuthController {
         String username = JacksonUtil.parseString(body, "username");
         String password = JacksonUtil.parseString(body, "password");
         String mobile = JacksonUtil.parseString(body, "mobile");
+        String captcha = JacksonUtil.parseString(body, "captcha");
         String code = JacksonUtil.parseString(body, "code");
 
-        if (username == null || password == null || mobile == null || code == null) {
+        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password) || StringUtils.isEmpty(mobile)
+            || StringUtils.isEmpty(captcha) || StringUtils.isEmpty(code)) {
             return ResponseUtil.badArgument();
         }
 
@@ -251,20 +267,39 @@ public class WxAuthController {
         }
         //判断验证码是否正确
         String cacheCode = CaptchaCodeManager.getCachedCaptcha(mobile);
-        if (cacheCode == null || cacheCode.isEmpty() || !cacheCode.equals(code))
+        if (cacheCode == null || cacheCode.isEmpty() || !cacheCode.equals(code)) {
             return ResponseUtil.fail(403, "验证码错误");
+        }
 
-        LitemallUser user = new LitemallUser();
+        String openId = null;
+        try {
+            WxMaJscode2SessionResult result = this.wxService.getUserService().getSessionInfo(code);
+            openId = result.getOpenid();
+        } catch (Exception e) {
+            e.printStackTrace();
+            return ResponseUtil.fail(403, "openid 获取失败");
+        }
+        userList = userService.queryByOpenid(openId);
+        if(userList.size() > 1){
+            return ResponseUtil.fail(403, "openid 存在多个");
+        }
+        if(userList.size() == 1){
+          LitemallUser checkUser = userList.get(0);
+          String checkUsername = checkUser.getUsername();
+          String checkPassword = checkUser.getPassword();
+          if(!checkUsername.equals(openId) || !checkPassword.equals(openId)){
+              return ResponseUtil.fail(403, "openid已绑定账号");
+          }
+        }
 
+        LitemallUser user = null;
         BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
         String encodedPassword = encoder.encode(password);
-        user.setPassword(encodedPassword);
-
         user = new LitemallUser();
         user.setUsername(username);
         user.setPassword(encodedPassword);
         user.setMobile(mobile);
-        user.setWeixinOpenid("");
+        user.setWeixinOpenid(openId);
         user.setAvatar("https://yanxuan.nosdn.127.net/80841d741d7fa3073e0ae27bf487339f.jpg?imageView&quality=90&thumbnail=64x64");
         user.setNickname(username);
         user.setGender((byte) 0);
@@ -275,7 +310,6 @@ public class WxAuthController {
         user.setAddTime(LocalDateTime.now());
         userService.add(user);
 
-
         // userInfo
         UserInfo userInfo = new UserInfo();
         userInfo.setNickName(username);

+ 73 - 36
litemall-wx/pages/auth/register/register.js

@@ -1,3 +1,4 @@
+
 var api = require('../../../config/api.js');
 var check = require('../../../utils/check.js');
 
@@ -8,7 +9,7 @@ Page({
     password: '',
     confirmPassword: '',
     mobile: '',
-    code: ''
+    captcha: ''
   },
   onLoad: function (options) {
     // 页面初始化 options为页面跳转所带来的参数
@@ -30,8 +31,27 @@ Page({
     // 页面关闭
 
   },
-  sendCode: function () {
+  sendCaptcha: function () {
     let that = this;
+
+    if (this.data.mobile.length == 0) {
+      wx.showModal({
+        title: '错误信息',
+        content: '手机号不能为空',
+        showCancel: false
+      });
+      return false;
+    }
+
+    if (!check.isValidPhone(this.data.mobile)) {
+      wx.showModal({
+        title: '错误信息',
+        content: '手机号输入不正确',
+        showCancel: false
+      });
+      return false;
+    }
+
     wx.request({
       url: api.AuthRegisterCaptcha,
       data: {
@@ -59,13 +79,52 @@ Page({
       }
     });
   },
+  requestRegister: function (code) {
+    let that = this;
+    wx.request({
+      url: api.AuthRegister,
+      data: {
+        username: that.data.username,
+        password: that.data.password,
+        mobile: that.data.mobile,
+        captcha: that.data.captcha,
+        code: code
+      },
+      method: 'POST',
+      header: {
+        'content-type': 'application/json'
+      },
+      success: function (res) {
+        if (res.data.errno == 0) {
+          app.globalData.hasLogin = true;
+          wx.setStorageSync('userInfo', res.data.data.userInfo);
+          wx.setStorage({
+            key: "token",
+            data: res.data.data.token,
+            success: function () {
+              wx.switchTab({
+                url: '/pages/ucenter/index/index'
+              });
+            }
+          });
+        }
+        else {
+          wx.showModal({
+            title: '错误信息',
+            content: res.data.errmsg,
+            showCancel: false
+          });
+        }
+      }
+    });
+  },
   startRegister: function () {
     var that = this;
 
-    if (this.data.password.length < 3 || this.data.username.length < 3) {
+    if (this.data.password.length < 6 || this.data.username.length < 6) {
       wx.showModal({
         title: '错误信息',
-        content: '用户名和密码不得少于3位',
+        content: '用户名和密码不得少于6位',
         showCancel: false
       });
       return false;
@@ -80,7 +139,7 @@ Page({
       return false;
     }
 
-    if (this.data.mobile.length == 0 || this.data.code.length == 0) {
+    if (this.data.mobile.length == 0 || this.data.captcha.length == 0) {
       wx.showModal({
         title: '错误信息',
         content: '手机号和验证码不能为空',
@@ -98,39 +157,17 @@ Page({
       return false;
     }
     
-    wx.request({
-      url: api.AuthRegister,
-      data: {
-        username: that.data.username,
-        password: that.data.password,
-        mobile: that.data.mobile,
-        code: that.data.code
-      },
-      method: 'POST',
-      header: {
-        'content-type': 'application/json'
-      },
+    wx.login({
       success: function (res) {
-        if (res.data.errno == 0) {
-          app.globalData.hasLogin = true;
-          wx.setStorageSync('userInfo', res.data.data.userInfo);
-          wx.setStorage({
-            key: "token",
-            data: res.data.data.token,
-            success: function () {
-              wx.switchTab({
-                url: '/pages/ucenter/index/index'
-              });
-            }
-          });
-        }
-        else{
+        if (!res.code) {
           wx.showModal({
             title: '错误信息',
-            content: res.data.errmsg,
+            content: '注册失败',
             showCancel: false
           });
         }
+
+        that.requestRegister(res.code);
       }
     });
   },
@@ -158,10 +195,10 @@ Page({
       mobile: e.detail.value
     });
   },
-  bindCodeInput: function (e) {
+  bindCaptchaInput: function (e) {
 
     this.setData({
-      code: e.detail.value
+      captcha: e.detail.value
     });
   },
   clearInput: function (e) {
@@ -186,9 +223,9 @@ Page({
           mobile: ''
         });
         break;        
-      case 'clear-code':
+      case 'clear-captcha':
         this.setData({
-          code: ''
+          captcha: ''
         });
         break;
     }

+ 6 - 6
litemall-wx/pages/auth/register/register.wxml

@@ -21,15 +21,15 @@
     	<image wx:if="{{ mobile.length > 0 }}" id="clear-mobile" class="clear" src="/static/images/clear_input.png" catchtap="clearInput"></image>
     </view>
 		
-    <view class="form-item-code" >
-			<view class="form-item code-item">
-				<input class="code" value="{{code}}" bindinput="bindCodeInput" placeholder="验证码"/>
-				<image class="clear" id="clear-code" wx:if="{{ code.length > 0 }}" src="/static/images/clear_input.png" catchtap="clearInput"></image>
+    <view class="form-item-captcha" >
+			<view class="form-item captcha-item">
+				<input class="captcha" value="{{captcha}}" bindinput="bindCaptchaInput" placeholder="验证码"/>
+				<image class="clear" id="clear-captcha" wx:if="{{ captcha.length > 0 }}" src="/static/images/clear_input.png" catchtap="clearInput"></image>
 			</view>
-			<view class="code-btn" bindtap="sendCode">获取验证码</view>
+			<view class="captcha-btn" bindtap="sendCaptcha">获取验证码</view>
 		</view>
 
-    	<button type="default" class="register-btn" bindtap="startRegister">注册</button>
+    	<button type="primary" class="register-btn" bindtap="startRegister">注册</button>
 
     </view>
 </view>

+ 6 - 5
litemall-wx/pages/auth/register/register.wxss

@@ -14,7 +14,7 @@
     border-bottom: 1px solid #d9d9d9;
 }
 
-.form-item .username, .form-item .password, .form-item .mobile, .form-item .code{
+.form-item .username, .form-item .password, .form-item .mobile, .form-item .captcha{
     position: absolute;
     top: 26rpx;
     left: 0;
@@ -26,23 +26,25 @@
     font-size: 30rpx;
 }
 
-.form-item-code{
+.form-item-captcha{
     margin-top:32rpx;
     height: auto;
     overflow: hidden;
     width: 100%;
 }
 
-.form-item-code .form-item{
+.form-item-captcha .form-item{
     float: left;
     width: 350rpx;
 }
 
-.form-item-code .code-btn{
+.form-item-captcha .captcha-btn{
     float: right;
     padding: 20rpx 40rpx;
     border: 1px solid #d9d9d9;
     border-radius: 10rpx;
+    color: #fff;
+    background: green;
 }
 
 .form-item .clear{
@@ -63,6 +65,5 @@
     color: #fff;
     font-size: 30rpx;
     width: 100%;
-    background: #b4282d;
     border-radius: 6rpx;
 }