day105:Mofang:設定頁面初始化&更新頭像/上傳頭像&設定頁面顯示使用者基本資訊

Poke發表於2020-12-08

目錄

1.設定頁面初始化

2.更新頭像

  1.點選頭像進入更新頭像介面

  2.更新頭像頁面初始化

  3.更新頭像頁面CSS樣式

  4.頭像上傳來源選擇:相簿/相機

  5.呼叫api提供的本地介面從相簿/相機提取圖片

  6.後端提供頭像更新的介面

  7.前端基於axios上傳圖片資料

3.本地更新頭像資訊

  1.頭像上傳成功後-關閉頁面/將頭像資料儲存在前端

  2.setting.js提供avatar_url頭像訪問地址

  3.後端提供展示頭像的檢視方法

  4.設定頁面頭像立即重新整理

  5.前端頁面顯示當前登入使用者的基本資訊

  6.後端提供使用者基本資訊的API介面

1.設定頁面初始化

1.設定頁面setting.html初始化

APP專案中對於使用者的退出登入,一般都在設定中進行。

客戶端新增配置頁面setting.html,程式碼:

day105:Mofang:設定頁面初始化&更新頭像/上傳頭像&設定頁面顯示使用者基本資訊
<!DOCTYPE html>
<html>
<head>
    <title>使用者中心</title>
    <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
    <meta charset="utf-8">
    <link rel="stylesheet" href="../static/css/main.css">
    <script src="../static/js/vue.js"></script>
    <script src="../static/js/axios.js"></script>
    <script src="../static/js/main.js"></script>
    <script src="../static/js/uuid.js"></script>
    <script src="../static/js/settings.js"></script>
</head>
<body>
    <div class="app user setting" id="app">
        <div class="bg">
      <img src="../static/images/form_bg.png">
    </div>
        <!-- 1.設定頁面的返回按鈕 -->
        <img class="back" @click="goto_home" src="../static/images/user_back.png" alt="">
    <div class="form">
      <div class="item avatar">
        <span class="title">頭像</span>
        <span class="goto">&gt;</span>
        <span class="value">
          <img src="../static/images/avatar.png" alt="">
        </span>
      </div>
      <div class="item">
        <span class="title">暱稱</span>
        <span class="goto">&gt;</span>
        <span class="value">iR.Poke</span>
      </div>
      <div class="item">
        <span class="title">手機號</span>
        <span class="goto">&gt;</span>
        <span class="value">134****9284</span>
      </div>
      <div class="item">
        <span class="title">登陸密碼</span>
        <span class="value"></span>
        <span class="goto">&gt;</span>
      </div>
      <div class="item">
        <span class="title">交易密碼</span>
        <span class="value"></span>
        <span class="goto">&gt;</span>
      </div>
      <div class="item">
        <span class="title">地址管理</span>
        <span class="value"></span>
        <span class="goto">&gt;</span>
      </div>
      <div class="item">
        <span class="title">裝置管理</span>
        <span class="value"></span>
        <span class="goto">&gt;</span>
      </div>
      <div class="item logout">
         <!-- 2.設定頁面的切換賬號 --> 
        <img @click="change_account" src="../static/images/change_account.png" alt="">
         <!--3.設定頁面的退出賬號 --> 
        <p @click="logout">退出賬號</p>
      </div>
    </div>
    </div>
    <script>
    apiready = function(){
        init();
        new Vue({
            el:"#app",
            data(){
                return {
                    prev:{name:"",url:"",params:{}},
                    current:{name:"setting",url:"setting.html",params:{}},
                }
            },
            methods:{
        goto_home(){
          // 回到個人中心介面
          this.game.goFrame("user","user.html",this.current);
        },
        change_account(){
          // 切換賬號
          this.game.goFrame("login","login.html", this.current);
        },
        logout(){
          // 退出賬號
          api.actionSheet({
              title: '您確認要退出當前登入嗎?',
              cancelTitle: '取消',
              destructiveTitle: '退出登入'
          }, (ret, err)=>{
              if( ret ){
                  this.game.print(ret);
                   if(ret.buttonIndex==1){
                     this.game.save({"access_token":"","refresh_token":""});
                     this.game.fremove(["access_token","refresh_token"]);
                     this.game.outWin("user");
                   }
              }
          });

        }
            }
        });
    }
    </script>
</body>
</html>
設定頁面setting.html初始化

2.設定頁面的CSS樣式

static/css/main.css,樣式程式碼:

day105:Mofang:設定頁面初始化&更新頭像/上傳頭像&設定頁面顯示使用者基本資訊
.setting .bg img{
  animation: normal;
}
.setting .back{
  top: 4rem;
}
.setting .form {
  top: 9rem;
}
.setting .form .item{
  height: 3.9rem;
  line-height: 3.9rem;
  font-size: 1.25rem;
  text-indent: 0.6rem;
  border-bottom: 1px solid rgba(204,153,102,0.2);
}
.setting .form .avatar{
  height: 6.11rem;
  line-height: 6.11rem;
}
.setting .form .avatar img{
  width: 4.56rem;
  height: 4.56rem;
  vertical-align: middle;
}
.setting .form .item .value,
.setting .form .item .goto{
  float: right;
}
.setting .form .logout{
  margin-top: 3rem;
  text-align: center;
  height: 4rem;
  line-height: 2rem;
}
.setting .form .logout img{
  width: 11rem;
}
設定頁面的CSS樣式

3.使用者介面點選設定按鈕跳轉到設定介面

<!-- 點選設定按鈕去到設定介面 -->
<img class="setting" @click="goto_setting" src="../static/images/setting.png" alt="">
        
<script>
    apiready = function(){
        init();
        new Vue({
            el:"#app",
            data(){
                return {
                    prev:{name:"",url:"",params:{}},
                    current:{name:"user",url:"user.html",params:{}},
                }
            },
            methods:{
                    goto_setting(){
                        this.game.goFrame("setting","setting.html", this.current);
                    }
            }
        });
    }
    </script>
</body>
</html>

2.更新頭像

1.點選頭像進入更新頭像介面

點選頭像進入更新頭像頁面,setting.html,程式碼:

<span class="value">
    <!-- 點選頭像進入到更新頭像介面 -->
    <img @click="update_avatar_frame" src="../static/images/avatar.png" alt="">
</span>
     
<script>

    update_avatar_frame(){
        // 點選頭像,跳到更新頭像的介面:avatar.html
        this.game.goFrame("avatar","avatar.html", this.current,null,{
            type:"push",             //動畫型別(詳見動畫型別常量)
            subType:"from_top",    //動畫子型別(詳見動畫子型別常量)
            duration:300             //動畫過渡時間,預設300毫秒
        })
    }

</script>

2.更新頭像頁面初始化

avatar.html,顯示頁面,程式碼:

day105:Mofang:設定頁面初始化&更新頭像/上傳頭像&設定頁面顯示使用者基本資訊
<!DOCTYPE html>
<html>
<head>
    <title>使用者中心</title>
    <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
    <meta charset="utf-8">
    <link rel="stylesheet" href="../static/css/main.css">
    <script src="../static/js/vue.js"></script>
    <script src="../static/js/axios.js"></script>
    <script src="../static/js/main.js"></script>
    <script src="../static/js/uuid.js"></script>
    <script src="../static/js/settings.js"></script>
</head>
<body>
    <div class="app frame avatar" id="app">
    <div class="box">
      <p class="title">上傳頭像</p>
      <img class="close" src="../static/images/close_btn1.png" alt="">
      <div class="content">
        <p class="header">!注意事項</p>
        <p class="text">禁止使用有誘導性的內容,二維碼,聯絡方式等違規違法違約的圖片,一經發現,永久封號,
          並保留追究法律責任的權利。</p>
      </div>
      <img @click="update_avatar_confirm" class="btn" src="../static/images/yes.png" alt="">
    </div>
    </div>
    <script>
    apiready = function(){
        init();
        new Vue({
            el:"#app",
            data(){
                return {
                    prev:{name:"",url:"",params:{}},
                    current:{name:"avatar",url:"avatar.html",params:{}},
                }
            },
            methods:{
        update_avatar_confirm(){
          // 確認上傳頭像

        },
        upload_avatar(ret){
          // 頭像上傳處理
          
        }
            }
        });
    }
    </script>
</body>
</html>
更新頭像頁面avatar.html初始化

3.更新頭像頁面CSS樣式

main.css,頁面樣式,程式碼:

day105:Mofang:設定頁面初始化&更新頭像/上傳頭像&設定頁面顯示使用者基本資訊
.avatar.frame{
  background-color: rgba(0,0,0,0.6);
}
.avatar{
  overflow: hidden;
}
.avatar .box{
  width: 28.89rem;
  height: 34.44rem;
  background: url("../images/board_bg1.png") no-repeat 0 0;
  background-size: 100%;
  position: absolute;
  top: 11rem;
  margin: 0 auto;
  left: 0;
  right: 0;
}

.avatar .box .title{
  color: #fff;
  font-size: 2rem;
  text-align: center;
  margin-top: 2.8rem;
}
.avatar .box .close{
  width: 5.22rem;
  height: 5.78rem;
  position: absolute;
  right: 0;
  top: 8rem;
}
.avatar .box .header{
  margin-top: 3.6rem;
  font-size: 1.8rem;
  text-align: center;
  color: #ff3333;
  font-weight: bold;
}
.avatar .box .text{
  width: 16.67rem;
  margin: 1.4rem auto 0;
  font-size: 1.22rem;
  color: #ffffcc;
}
.avatar .box .btn{
  display: block;
  width: 12.22rem;
  height: 4.55rem;
  margin: 1.4rem auto 0;
}
更新頭像頁面CSS樣式

4.頭像上傳來源選擇:相簿/相機

頭像上傳來源選擇,avatar.html,程式碼:

<!-- 1.關閉更新頭像介面: close_frame -->
<img class="close" @click="close_frame" src="../static/images/close_btn1.png" alt="">
<div class="content">
    <p class="header">!注意事項</p>
    <p class="text">禁止使用有誘導性的內容,二維碼,聯絡方式等違規違法違約的圖片,一經發現,永久封號,
        並保留追究法律責任的權利。</p>
</div>
<!-- 2.頭像上傳來源選擇 :相簿/相機 -->
<img @click="update_avatar_confirm" class="btn" src="../static/images/yes.png" alt="">
</div>

    <script>
    
        close_frame(){
          this.game.outFrame("avatar");
        },
            
        update_avatar_confirm(){
          // 確認上傳頭像的方式
          api.actionSheet({
              title: '請選擇上傳頭像的來源',
              cancelTitle: '取消',
              buttons: ['相簿','相機'],
          }, function(ret, err){
              if( ret ){
                   alert( JSON.stringify( ret ) );
              }else{
                   this.game.print( err );
              }
          });

        },
        
    </script>

5.呼叫api提供的本地介面從相簿/相機提取圖片

接下來,呼叫apicloud提供的本地介面從相簿或者相機中提取圖片.

avatar.html程式碼

<!-- 1.關閉更新頭像介面: close_frame -->
<img class="close" @click="close_frame" src="../static/images/close_btn1.png" alt="">
<div class="content">
    <p class="header">!注意事項</p>
    <p class="text">禁止使用有誘導性的內容,二維碼,聯絡方式等違規違法違約的圖片,一經發現,永久封號,
        並保留追究法律責任的權利。</p>
</div>
<!-- 2.頭像上傳來源選擇 :相簿/相機 -->
<img @click="update_avatar_confirm" class="btn" src="../static/images/yes.png" alt="">
</div>
    <script>
    
        close_frame(){
          this.game.outFrame("avatar");
        },
        update_avatar_confirm(){
          // 確認上傳頭像的方式
          api.actionSheet({
              title: '請選擇上傳頭像的來源',
              cancelTitle: '取消',
              buttons: ['相簿','相機'],
          }, (ret, err)=>{
              if( ret ){
                   var sourceType = ["album","camera"];
                   if(ret.buttonIndex > sourceType.length){
                     // 如果使用者選擇了取消,則關閉當前修改頭像的頁面
                     this.game.outFrame("avatar");
                     return;
                   }
                   // ***使用APIcloud提供的api.getPicture方法從相機/相簿獲取圖片***
                   api.getPicture({
                       sourceType: sourceType[ret.buttonIndex-1],
                       mediaValue: 'pic',
                       destinationType: 'base64',
                       allowEdit: true,
                       preview:true,
                       quality: 50,
                       targetWidth: 100,
                       targetHeight: 100,
                       saveToPhotoAlbum: true,
                   }, (ret, err)=>{
                       if(ret){
                            this.game.print(ret);
                       }else{
                            this.game.print(err);
                       }
                   });

                   alert( JSON.stringify( ret ) );
              }else{
                   this.game.print( err );
              }
          });

        },
        upload_avatar(ret){
          // 頭像上傳處理

        }
            }
        });
    }
    </script>
</body>
</html>

6.後端提供頭像更新的介面

服務端提供頭像更新介面,application/apps/users/views.py,程式碼

import base64, uuid,os
@jsonrpc.method("User.avatar.update")
@jwt_required # 驗證jwt
def update_avatar(avatar):
    """獲取使用者資訊"""
    # 1.接受客戶端上傳的頭像資訊
    ext = avatar[avatar.find("/")+1:avatar.find(";")]  # 資源格式:jpeg/jpg/png....
    b64_avatar = avatar[avatar.find(",")+1:]
    b64_image = base64.b64decode(b64_avatar)
    
    # 2.使用uuid給頭像檔案生成隨機的檔名
    filename = uuid.uuid4()
    
    # 3.拼接頭像檔案在後端儲存的路徑
    static_path = os.path.join( current_app.BASE_DIR,current_app.config["STATIC_DIR"] )
    with open("%s/%s.%s" % (static_path, filename,ext),"wb") as f:
        f.write(b64_image)
    
    # 4.查詢當前使用者是否存在
    current_user_id = get_jwt_identity()
    user = User.query.get(current_user_id)
    if user is None:
        return {
            "errno": status.CODE_NO_USER,
            "errmsg": message.user_not_exists,
        }
    
    # 5.將使用者的頭像資料儲存到mysql資料庫中
    user.avatar = "%s.%s" % (filename,ext)
    db.session.commit()
    return {
        "errno": status.CODE_OK,
        "errmsg": message.avatar_save_success,
        "avatar": "%s.%s" % (filename,ext)
    }

在專案後端全域性配置檔案中新增靜態檔案目錄儲存路徑

application/settings/__init__.py,程式碼:

# 靜態檔案目錄儲存路徑
STATIC_DIR = "application/static"

7.前端基於axios上傳圖片資料

客戶端基於axios上傳圖片資料,avatar.html程式碼

<!-- 1.關閉更新頭像介面: close_frame -->
<img class="close" @click="close_frame" src="../static/images/close_btn1.png" alt="">
<div class="content">
    <p class="header">!注意事項</p>
    <p class="text">禁止使用有誘導性的內容,二維碼,聯絡方式等違規違法違約的圖片,一經發現,永久封號,
        並保留追究法律責任的權利。</p>
</div>
<!-- 2.頭像上傳來源選擇 :相簿/相機 -->
<img @click="update_avatar_confirm" class="btn" src="../static/images/yes.png" alt="">
</div>
    <script>
    
        close_frame(){
          this.game.outFrame("avatar");
        },
        update_avatar_confirm(){
          api.actionSheet({
              title: '請選擇上傳頭像的來源',
              cancelTitle: '取消',
              buttons: ['相簿','相機'],
          }, (ret, err)=>{
              if( ret ){
                   var sourceType = ["album","camera"];
                   if(ret.buttonIndex > sourceType.length){
                     this.game.outFrame("avatar");
                     return;
                   }
                   api.getPicture({
                      ...
                   }, (ret, err)=>{
                       if(ret){
                               // 1.獲取本地圖片成功後,開始上傳圖片
                            this.upload_avatar(ret);
                       }else{
                            this.game.print(err);
                       }
                   });

              }else{
                   this.game.print( err );
              }
          });

        },
        // 頭像上傳處理
        upload_avatar(ret){
          
          var token = this.game.get("access_token") || this.game.fget("access_token");
          if(!token){
            this.game.goFrame("login","login.html", this.current);
            return ;
          }
          // 2.前端基於axios上傳頭像
          this.axios.post("",{
                        "jsonrpc": "2.0",
                        "id": this.uuid(),
                        "method": "User.avatar.update",
                        "params": {
                            "avatar": ret.base64Data,
                        }
                    },{
            headers:{
              Authorization: "jwt " + token,
            }
          }).then(response=>{
            if(parseInt(response.data.result.errno)==1000){
              this.game.print(response);
            }else{
              this.game.print(response.data.result);
            }
          }).catch(error=>{
            // 網路等異常
            this.game.print(error);
          })
        }
            }
        });
    }
    </script>
</body>
</html>

3.本地更新頭像資訊

1.頭像上傳成功後-關閉頁面/將頭像資料儲存在前端

關閉avatar.html頁面,展示底下的setting.html,並將頭像儲存在前端

客戶端的avatar.html程式碼:

upload_avatar(ret){
    // 頭像上傳處理
    var token = this.game.get("access_token") || this.game.fget("access_token");
    if(!token){
        this.game.goFrame("login","login.html", this.current);
        return ;
    }
    this.axios.post("",{
        "jsonrpc": "2.0",
        "id": this.uuid(),
        "method": "User.avatar.update",
        "params": {
            "avatar": ret.base64Data,
        }
    },{
        headers:{
            Authorization: "jwt " + token,
        }
    }).then(response=>{
        // 當後端儲存頭像資料成功後
        if(parseInt(response.data.result.errno)==1000){
            // 1.將頭像儲存在前端
            this.game.fsave({"avatar": response.data.result.avatar});
            // 2.跳轉到設定頁面
            this.game.goFrame("setting","setting.html", this.current);
        }else{
            this.game.print(">>>> fail");
            this.game.print(response.data);
        }
    }).catch(error=>{
        // 網路等異常
        this.game.print(error);
    })
}
}
});
}

2.setting.js提供avatar_url頭像訪問地址

客戶端的配置檔案static/js/settings.js新增配置項avatar_url提供頭像訪問地址,程式碼;

function init(){
  if(Game){
    var game = new Game("../mp3/bg1.mp3");
    Vue.prototype.game = game;
  }
  if(axios){
    // 初始化axios
    axios.defaults.baseURL = "http://192.168.20.251:5000/api" // 服務端api介面閘道器地址
    axios.defaults.timeout = 2500; // 請求超時時間
    axios.defaults.withCredentials = false; // 跨域請求資源的情況下,忽略cookie的傳送
    Vue.prototype.axios = axios;
    Vue.prototype.uuid  = UUID.generate;
  }
  // 介面相關的配置項
  Vue.prototype.settings = {
    captcha_app_id: "2071340228",  // 騰訊防水牆驗證碼應用ID
    avatar_url: "http://192.168.20.251:5000/users/avatar", // ***頭像前端訪問地址***
  }
}

3.後端提供展示頭像的檢視方法

服務端提供展示頭像的檢視方法地址

application/apps/users/urls.py,程式碼:

from . import views
from application.utils import path
urlpatterns = [
    path("/avatar", views.avatar),
]

確認總路由設定了訪問藍圖的url字首,application/urls.py,程式碼:

from application.utils import include
urlpatterns = [
    include("","home.urls"),
    include("/users","users.urls"),
    include("/marsh","marsh.urls"),
]

檢視中, 顯示圖片時驗證使用者身份.,application/apps/users/views.py程式碼:

from flask import make_response,request
@jwt_required # 驗證jwt
def avatar():
    """獲取頭像資訊"""
    
    # 1.獲取前端儲存頭像的sign引數
    avatar = request.args.get("sign")
    
    # 2.獲取頭像檔案格式:jpg/jpeg/png
    ext  = avatar[avatar.find(".")+1:]
    
    # 3.獲取頭像檔案的檔名
    filename = avatar[:avatar.find(".")]
    
    # 4.後端檔案儲存的路徑
    static_path = os.path.join(current_app.BASE_DIR, current_app.config["STATIC_DIR"])
    
    # 5.讀取後端檔案資料
    with open("%s/%s.%s" % (static_path,filename,ext), "rb") as f:
        content = f.read() #  此時content儲存的是二進位制檔案
    response = make_response(content) # 
    response.headers["Content-Type"] = "image/%s" % ext
    return response

4.設定頁面頭像立即重新整理

完成了上面步驟程式碼以後, 我們現在能在客戶端修改使用者頭像了,但是在關閉avatar.html頁面以後, setting.html頁面中的頭像並沒有及時發生變化,.所以我們在avatar.html頁面更新了頭像以後, 我們借住apicloud提供的自定義事件和事件監聽介面,來實現,通知setting.html頁面,使用者頭銜已經發生改變了.

文件: https://docs.apicloud.com/Client-API/api#72

當前功能,我們需要根據文件瞭解關於sendEventaddEventListener的使用.

// a頁面可以通過sendEvent發起一個自定義事件
api.sendEvent({
    name: 'myEvent', # 自定義事件名稱
    extra: {
        key1: 'value1',  # 事件傳參
        key2: 'value2'
    }
});

// b頁面可以通過addEventListener進行監聽是否有對應名稱的自定義事件進行傳送了,一旦監聽到,則自動執行回撥函式:
api.addEventListener({
    name: 'myEvent' # 監聽指定名稱的事件
}, function(ret, err) {   # ret接收指定名稱的事件引數
    alert(JSON.stringify(ret.value));
});

// c頁面也可以通過addEventListener進行監聽是否有對應名稱的自定義事件進行傳送了,一旦監聽到,則自動執行回撥函式:
api.addEventListener({
    name: 'myEvent'
}, function(ret, err) {
    alert(JSON.stringify(ret.value));
});

// b.c 頁面都將收到 myEvent 事件

1.avatar.html傳送自定義事件

接下來,我們就可以在avatar.html頁面中,傳送一個自定義事件,告知其他頁面,當前使用者的頭像發生了改變.

avatar.html程式碼

        upload_avatar(ret){
          // 頭像上傳處理
          var token = this.game.get("access_token") || this.game.fget("access_token");
          if(!token){
            this.game.goFrame("login","login.html", this.current);
            return ;
          }
          this.axios.post("",{
                        "jsonrpc": "2.0",
                        "id": this.uuid(),
                        "method": "User.avatar.update",
                        "params": {
                            "avatar": ret.base64Data,
                        }
                    },{
            headers:{
              Authorization: "jwt " + token,
            }
          }).then(response=>{
            if(parseInt(response.data.result.errno)==1000){
              this.game.fsave({"avatar": response.data.result.avatar});
                            // ***傳送自定義事件***
                            api.sendEvent({
                                name: 'change_avatar',
                                extra: {
                                        "avatar": response.data.result.avatar
                                    }
                            });
              this.game.outFrame("avatar");
                    }else{
                            this.game.print(">>>> fail");
              this.game.print(response.data);
            }
          }).catch(error=>{
            // 網路等異常
            this.game.print(error);
          })
        }
            }
        });
    }

2.setting.html監聽自定義事件

setting.html頁面中,監聽自定義事件,這個監聽過程是不需要重新整理頁面的.

methods:{
    change_avatar(){
        // 監聽自定義事件
        api.addEventListener({
            name: 'change_avatar'
        }, (ret, err)=>{
            if( ret ){
                var token = this.game.get("access_token") || this.game.fget("access_token");
                this.avatar = `${this.settings.avatar_url}?sign=${ret.value.avatar}&token=${token}`;
            }
        });
    },
        

5.前端頁面顯示當前登入使用者的基本資訊

setting.html頁面提供當前登陸使用者的基本資訊,程式碼:

      </div>
      <div class="item">
        <span class="title">暱稱</span>
        <span class="goto">&gt;</span>
        <span class="value">{{nickname}}</span>
      </div>
      <div class="item">
        <span class="title">手機號</span>
        <span class="goto">&gt;</span>
        <span class="value">{{mobile}}</span>
      </div>


    <script>
    apiready = function(){
        init();
        new Vue({
            el:"#app",
            data(){
                return {
                    nickname: "", // 暱稱
                    mobile: "",  // 手機號
                    avatar: "../static/images/avatar.png",
                    prev:{name:"",url:"",params:{}},
                    current:{name:"setting",url:"setting.html",params:{}},
                }
            },
            created(){
                this.get_user_info(); // 觸發獲取使用者資訊方法
                this.change_avatar();
            },
            methods:{
                 // 獲取當前使用者登入基本資訊
                get_user_info(){
                    var token = this.game.get("access_token") || this.game.fget("access_token");
                     // 獲取當前登陸使用者基本資訊
                     this.axios.post("",{
                         "jsonrpc": "2.0",
                         "id": this.uuid(),
                         "method": "User.info",
                         "params": {}
                     },{
             headers:{
               Authorization: "jwt " + token,
             }
           }).then(response=>{
                          var res = response.data.result;
                          if(parseInt(res.errno) === 1000){
                                this.nickname = res.nickname;
                              // avatar從前端獲取傳到:src上
                                this.avatar = `${this.settings.avatar_url}?sign=${res.avatar}&token=${token}`;
                                this.mobile = res.mobile;
                            }
                     })
                },
            
    </script>
</body>
</html>

6.後端提供使用者基本資訊的API介面

服務端提供使用者基本資訊APi介面,application/apps/users/views.py,程式碼:

from .marshmallow import UserInfoSchema
@jsonrpc.method("User.info")
@jwt_required # 驗證jwt
def info():
    """獲取使用者資訊"""
    current_user_id = get_jwt_identity() # 根據token反解出當前使用者id
    
    # 判斷當前使用者是否存在
    user = User.query.get(current_user_id)
    if user is None:
        return {
            "errno": status.CODE_NO_USER,
            "errmsg": message.user_not_exists,
        }
    uis = UserInfoSchema()
    data = uis.dump(user) # 將使用者資訊序列化傳遞給前端
    return {
        "errno": status.CODE_OK,
        "errmsg": message.ok,
        **data
    }

marshmallow.py,程式碼:

from marshmallow import post_dump
class UserInfoSchema(SQLAlchemyAutoSchema):
    id = auto_field()
    mobile = auto_field()
    nickname = auto_field()
    avatar = auto_field()

    class Meta:
        model = User
        include_fk = True
        include_relationships = True
        fields = ["id","mobile","nickname","avatar"]
        sql_session = db.session

    @post_dump()
    def mobile_format(self, data, **kwargs):
        data["mobile"] = data["mobile"][:3]+"****"+data["mobile"][-4:]
        return data

 

相關文章