支付寶小程序開發——登陸失效后的交互處理


前言:

做的第一個支付寶小程序,支付寶會員日搶購的一個卡券類項目。考慮到流量會比較大,授權登陸放到用戶第一次能直接訪問的需要登陸的頁面(或頁面某個操作)進行處理。訪問需要登陸的接口請求返回登陸失效的結果之后進行重新登陸,登陸成功后需要重新回到當前頁面。

需求分析:

1. 登陸邏輯的處理:

用戶首次訪問的入口頁面需要登陸的不止一個,所以登陸邏輯最好是進行統一風封裝復用;

2. 登陸失效的處理:

這個支付寶小程序項目並沒有登陸頁,且小程序外部入口較多,所以登陸失效跳回到入口頁面不僅體驗不好,而且實現起來也比較復雜。

也考慮過接口登陸失效后調用登陸模塊,登陸成功后回調之前的請求  A(params)=>{B(A(params)} ,但我們的接口請求是經過統一封裝的,登陸失效的處理邏輯也是在封裝里邊的,那么回調也是在封裝里邊進行的,並不能同步到頁面的數據進行重新賦值,也就無法重新渲染。當然,你也可以直接將登陸邏輯放到頁面中去,那就是所有需要登陸的接口的處理都要放到頁面中去了,那就比較麻煩了。

最后想到的最佳的解決方案就是登陸失效后重新刷新當前頁面,雖說比不上重新登陸回調之前請求的體驗好,但是實現上就會容易的多了,而且交互上做好登陸相關的提示,體驗也還是挺不錯的了。

需求實現:

1. 登陸封裝:

鑒於項目中已經封裝了網絡請求,且登陸的相關邏輯需要引入網絡請求的相關封裝模塊,也進行了一番探索,最終還是把登陸的邏輯封裝在app.js中:

//app.js
import http from "./api/http"
App({
    ......
    /**
        * 2. 自動登錄業務邏輯  
        */
    login: function() {
        let self = this;
        my.getAuthCode({
            //授權類型,默認 auth_base。支持 auth_base(靜默授權)/ auth_user(主動授權) / auth_zhima(芝麻信用)
            scopes: ['auth_user'],
            success: res => {
                let authCode = res.authCode
                console.log("authCode:", authCode)
                if (authCode) {
                    // 訪問用戶登錄接口獲取usertoken
                    http.userLogin(authCode).then(data => {
                        if (!my.isEmpty(data.userToken)) {
                            my.setStorageSync0("usertoken", data.userToken)
                            if (my.getStorageSync0("currentPageUrl")) {
                   my.reLaunch({   url: my.getStorageSync0(
"currentPageUrl")   });
                 } }
else { console.log("userLoginError:", JSON.stringify(data)) } }) } }, fail: res => { console.warn("getAuthCode:", res) my.confirm({ title: '溫馨提示', content: '登錄授權失敗,您可以嘗試重新授權', confirmButtonText: '重新授權', cancelButtonText: '取消', success: (result) => { if (result.confirm) { self.login() } else { //取消登陸,需要返回上一頁 if (my.getStorageSync0("currentPageUrl") == "/pages/my/my") { //我的頁面(tab頁面需要使用relanch跳轉到首頁) my.reLaunch({ url: '/pages/index/index' }) } else { //針對其他頁面,返回上一頁 my.navigateBack({ delta: 1 }) } } }, }); } }) } ...... });

說明:

  • 代碼中的 my.isEmpty(value)  getStorageSync0(key)  my.setStorageSync0(key,value) 等方法均為針對支付寶小程序的特性自己封裝的公共方法;
  • 頁面初始化接口登陸失效——這種情況可以采用靜默登陸,不提示(用戶看到小程序原生的授權登陸就能明白怎么回事),登陸成功之后重新加載當前頁面進行初始化即可;
  • 用戶主動觸發接口請求登陸失效——如用戶單擊事件調用接口,重新登陸打斷了用戶的操作,如果還想上邊一樣靜默登陸不提示,那么用戶會有點懵的。然而如果在重新授權登陸的過程中給出相關提示,那么用戶重新執行之前的操作就好了,這樣體驗就好的多了。
  • 關於在封裝方法中重載當前頁面——支付寶小程序並沒有提供直接獲取頁面路徑及參數的API,所以這個就只能在需要重載的頁面保存頁面的路徑+參數的完整path了,下邊會詳細說明。
  • 如果用戶取消授權登陸——那么就只有讓用戶返回上一頁了,其中Tab頁需要重載首頁。

2. 頁面登陸及頁面路徑保存:

//main.js 公共方法封裝
......
//將當前頁面路徑及參數保存到緩存中(登陸失效自動登陸后relaunch())
my.getCurrentPageUrlWithArgs=function(options) {
  const pages = getCurrentPages()
  const currentPage = pages[pages.length - 1]
  const url = currentPage.route
  let urlWithArgs = `/${url}?`
  for (let key in options) {
    const value = options[key]
    urlWithArgs += `${key}=${value}&`
  }
  urlWithArgs = urlWithArgs.substring(0, urlWithArgs.length - 1)
  my.setStorage0("currentPageUrl",urlWithArgs)
}
//page.js
import http from "../../api/http" var app = getApp(); Page({ ...... onLoad(e) { my.getCurrentPageUrlWithArgs(e) this.autologin() }, autologin() { //未登陸首次訪問 if (my.isEmpty(my.getStorageSync0("usertoken"))) { app.login() } else { this.getUserInfo() } }, ...... })

說明:

  • 頁面onLoad的時候,調用 my.getCurrentPageUrlWithArgs() 方法保存當前頁面的完整路徑;
  • 關於登陸,如果頁面作為首次登陸的入口,如果登陸過則直接初始化,否則調用登陸方法。

3. 網絡請求封裝:

接口請求新增了 clickRequest 參數,有此參數,則給出相關提示,否則靜默登陸不予提示:

......
const http = (params) => {
    return new Promise((resolve, reject) => {
        my.request({
            ......
            success: function(res) {
                //my.hideLoading()
                if (res.status == 200) {
                    //需要登錄、后端返回登錄失效代碼,需要自動登錄然后重新加載小程序
                    if (!params.noNeedLogin && res.data.s == "302") {
                        my.removeStorageSync({ key: "usertoken" })
                        //根據接口的調用是否是用戶主動調用來確定是否給出提示
                        if (params.clickRequest) {
                            my.toast("登陸失效,重新登陸中...", function() {
                                getApp().login(() => {
                                    my.toast("登陸成功")
                                })
                            })
                        } else {
                            getApp().login()
                        }
                        return;
                    }
                    ......
                } else {
                    errorToast();
                    console.error(res)
                }
            },
            fail: function(e) {
                errorToast();
                reject(e)
            }
        })
    })
}
......

后記:

每新做一個項目,都會盡可能的對現有框架進行提升優化,這樣不僅對當前項目的開發有幫助,也有利於以后其他類似項目的復用。力求精簡代碼,提升效率!有感興趣的小伙伴可以多多留言討論,共同探索前端技術。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM