(wepy)小程序注册
2018年11月29日服务器端
1.添加路由
1 2 |
$api->post('weapp/users', 'UsersController@weappStore') ->name('api.weapp.users.store'); |
2.编写控制器(这里有验证码)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
public function weappStore(WeappAuthorizationRequest $request) { $code = $request->code; $miniProgram = \EasyWeChat::miniProgram(); #开始小程序 $data = $miniProgram->auth->session($code); if (isset($data['errcode'])) { return $this->response->errorUnauthorized('code 不正确'); } $user = User::where('weapp_openid', $data['openid'])->first(); $attributes['weixin_session_key'] = $data['session_key']; if (!$user) { // 找不到 openid 对应的用户要求用户提交 if (!$request->username) { return $this->response->errorForbidden('用户不存在'); } $username = $request->username; filter_var($username, FILTER_VALIDATE_EMAIL) ? $credentials['email'] = $username : $credentials['phone'] = $username; $credentials['password'] = $request->password; if (!Auth::guard('api')->once($credentials)) { return $this->response->errorUnauthorized('用户名或密码错误'); } $user = Auth::guard('api')->getUser(); $attributes['weapp_openid'] = $data['openid']; } $user->update($attributes); $token = Auth::guard('api')->fromUser($user); return $this->respondWithToken($token)->setStatusCode(201); } |
小程序客户端
1创建注册页面
1 2 |
cd ~/Code/larabbs-weapp touch src/pages/auth/register.wpy |
打开src/app.wpy
开始编辑
1 2 3 4 5 6 7 8 9 10 11 12 |
. . . pages: [ . . . 'pages/auth/register' ], . . . |
编辑注册页面src/pages/auth/register.wpy
(这里调用了验证码接口)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 |
<style lang="less"> .register-wrap { margin-top: 50px; } .error-message { color: #E64340; } </style> <template> <view class="page"> <view class="page__bd register-wrap"> <form bindsubmit="submit"> <view class="weui-toptips weui-toptips_warn" wx:if="{{ errorMessage }}">{{ errorMessage }}</view> <view class="weui-cells__title">Larabbs 手机注册</view> <!-- 手机号 --> <view class="weui-cells__title {{ errors.phone ? 'weui-cell_warn' : ''}}">手机号</view> <view class="weui-cells weui-cells_after-title"> <view class="weui-cell weui-cell_input {{ errors.phone ? 'weui-cell_warn' : ''}}"> <view class="weui-cell__bd"> <input disabled="{{ phoneDisabled }}" class="weui-input" type="number" placeholder="请输入手机号" @input="bindPhoneInput"/> </view> <view class="weui-cell__ft"> <icon wx:if="{{ errors.phone }}" type="warn" size="23" color="#E64340"></icon> <view class="weui-vcode-btn" @tap="tapCaptchaCode">获取验证码</view> </view> </view> </view> <view wx:if="{{ errors.phone }}" class="weui-cells__tips error-message">{{errors.phone[0]}}</view> <!-- 短信验证码 --> <view class="weui-cells__title {{ errors.verification_code ? 'weui-cell_warn' : ''}}">短信验证码</view> <view class="weui-cells weui-cells_after-title"> <view class="weui-cell weui-cell_input {{ errors.verification_code ? 'weui-cell_warn' : ''}}"> <view class="weui-cell__bd"> <input class="weui-input" placeholder="请输入短信验证码" name="verification_code"/> </view> <view class="weui-cell__ft"> <icon wx:if="{{ errors.verification_code }}" type="warn" size="23" color="#E64340"></icon> </view> </view> </view> <view wx:if="{{ errors.verification_code }}" class="weui-cells__tips error-message"> {{errors.verification_code[0]}} </view> <!-- 姓名 --> <view class="weui-cells__title {{ errors.name ? 'weui-cell_warn' : ''}}">姓名</view> <view class="weui-cells weui-cells_after-title"> <view class="weui-cell weui-cell_input {{ errors.name ? 'weui-cell_warn' : ''}}"> <view class="weui-cell__bd"> <input class="weui-input" placeholder="请输入姓名" name="name"/> </view> <view class="weui-cell__ft"> <icon wx:if="{{ errors.name }}" type="warn" size="23" color="#E64340"></icon> </view> </view> </view> <view wx:if="{{ errors.name }}" class="weui-cells__tips error-message">{{errors.name[0]}}</view> <!-- 密码 --> <view class="weui-cells__title {{ errors.password ? 'weui-cell_warn' : ''}}">密码</view> <view class="weui-cells weui-cells_after-title"> <view class="weui-cell weui-cell_input {{ errors.password ? 'weui-cell_warn' : ''}}"> <view class="weui-cell__bd"> <input class="weui-input" placeholder="请输入密码" name="password" type="password"/> </view> <view class="weui-cell__ft"> <icon wx:if="{{ errors.password }}" type="warn" size="23" color="#E64340"></icon> </view> </view> </view> <view wx:if="{{ errors.password }}" class="weui-cells__tips error-message">{{ errors.password[0] }}</view> <view class="weui-btn-area"> <button class="weui-btn" type="primary" formType="submit">注册</button> </view> </form> <!-- 验证码输入模态框 --> <modal class="modal" hidden="{{ captchaModalHidden }}" no-cancel bindconfirm="sendVerificationCode"> <view wx:if="{{ errors.captchaValue }}" class="weui-cells__tips error-message">{{ errors.captchaValue[0] }} </view> <view class="weui-cell weui-cell_input weui-cell_vcode"> <view class="weui-cell__bd"> <input class="weui-input" placeholder="图片验证码" @input="bindCaptchaCodeInput"/> </view> <view class="weui-cell__ft"> <image class="weui-vcode-img" @tap="tapCaptchaCode" src="{{ captcha.imageContent }}" style="width: 100px"></image> </view> </view> </modal> </view> </view> </template> <script> import wepy from 'wepy' import api from '@/utils/api' export default class Login extends wepy.page { config = { navigationBarTitleText: '注册' } data = { // 手机号 phone: null, // 手机号 input 是否 disabled phoneDisabled: false, // 图片验证码 modal 是否显示 captchaModalHidden: true, // 用户输入的验证码 captchaValue: null, // 图片验证码 key 及过期时间 captcha: {}, // 表单错误 errors: {}, // 手机验证码以及过期时间 verificationCode: {} } // 重置注册流程,初始化 data 数据 resetRegister() { this.captchaModalHidden = true this.phoneDisabled = false this.captcha = {} this.verificationCode = {} this.errors = {} } // 表单提交 async submit (e) { this.errors = {} // 检查验证码是否已发送 if (!this.verificationCode.key) { wepy.showToast({ title: '请发送验证码', icon: 'none', duration: 2000 }) return false } // 检查验证码是否过期 if (new Date().getTime() > this.verificationCode.expiredAt) { wepy.showToast({ title: '验证码已过期', icon: 'none', duration: 2000 }) this.resetRegister() return false } try { let formData = e.detail.value formData.verification_key = this.verificationCode.key let loginData = await wepy.login() // 参数中增加code,用于获取 openid 绑定当前用户 formData.code = loginData.code let registerResponse = await api.request({ url: 'weapp/users', method: 'POST', data: formData }) // 验证码错误 if (registerResponse.statusCode === 401) { this.errors.verification_code = ['验证码错误'] this.$apply() } // 表单错误 if (registerResponse.statusCode === 422) { this.errors = registerResponse.data.errors this.$apply() } // 注册成功,记录token if (registerResponse.statusCode === 201) { wepy.setStorageSync('access_token', registerResponse.data.meta.access_token) wepy.setStorageSync('access_token_expired_at', new Date().getTime() + registerResponse.data.meta.expires_in * 1000) // 设置用户信息 wepy.setStorageSync('user', registerResponse.data) wepy.showToast({ title: '注册成功', icon: 'success' }) // 跳转到我的页面 setTimeout(function() { wepy.switchTab({ url: '/pages/user' }) }, 2000) } } catch (err) { console.log(err) wepy.showModal({ title: '提示', content: '服务器错误,请联系管理员' }) } } // 获取图片验证码 async getCaptchaCode() { this.errors.phone = null // 判断手机号是否正确 if (!(/^1[34578]\d{9}$/.test(this.phone))) { this.errors.phone = ['请输入正确的手机号'] this.$apply() return false } try { // 调用发送验证码接口,参数为手机号 let captchaResponse = await api.request({ url: 'captchas', method: 'POST', data: { phone: this.phone } }) // 表单错误 if (captchaResponse.statusCode === 422) { this.errors = captchaResponse.data.errors this.$apply() } // 记录 key 和过期时间,打开 modal if (captchaResponse.statusCode === 201) { this.captcha = { key: captchaResponse.data.captcha_key, imageContent: captchaResponse.data.captcha_image_content, expiredAt: Date.parse(captchaResponse.data.expired_at) } // 关闭modal this.captchaModalHidden = false this.$apply() } } catch (err) { console.log(err) wepy.showModal({ title: '提示', content: '服务器错误,请联系管理员' }) } } methods = { // 绑定手机输入 bindPhoneInput (e) { this.phone = e.detail.value }, // 绑定验证码输入 bindCaptchaCodeInput (e) { this.captchaValue = e.detail.value }, // 响应获取图片验证码按钮点击事件 async tapCaptchaCode() { this.getCaptchaCode() }, // 发送短信验证码 async sendVerificationCode() { if (!this.captchaValue) { this.errors.captchaValue = ['请输入图片验证码'] return false } // 检查验证码是否过期,重置流程 if (new Date().getTime() > this.captcha.expiredAt) { wepy.showToast({ title: '验证码已过期', icon: 'none', duration: 2000 }) this.resetRegister() return false } try { let codeResponse = await api.request({ url: 'verificationCodes', method: 'POST', data: { captcha_key: this.captcha.key, captcha_code: this.captchaValue } }) // 验证码错误提示 if (codeResponse.statusCode === 401) { this.errors.captchaValue = ['图片验证码错误'] this.$apply() await this.getCaptchaCode() return false } // 记录 key 和 过期时间 if (codeResponse.statusCode === 201) { this.verificationCode = { key: codeResponse.data.key, expiredAt: Date.parse(codeResponse.data.expired_at) } // 关闭modal this.captchaModalHidden = true // 手机输入框 disabled this.phoneDisabled = true // 清空报错信息 this.errors = {} this.$apply() } } catch (err) { console.log(err) wepy.showModal({ title: '提示', content: '服务器错误,请联系管理员' }) } } } } </script> |