day108:MoFang:首頁檢測用戶是否登錄&在項目中使用MongoDB&用戶頁面更新用戶資訊&交易密碼介面實現

目錄

1.首頁頁面也要檢測用戶是否登錄

2.在flask中使用MongoDB

3.用戶頁面更新用戶資訊

4.交易密碼介面/密碼修改介面/昵稱修改介面初始化

5.交易密碼實現

1.首頁頁面也要檢測用戶是否登錄

1.在index.html中添加check_user_login方法

在index.html頁面中調用checkout函數,如果回調函數傳來1005狀態碼,則刪除對應token,讓用戶重新進行登錄

html/index.html,程式碼;

created(){
    this.check_user_login();
},
    methods:{
        // 首頁檢測用戶是否登錄
        check_user_login(){
            let token = this.game.get("access_token") || this.game.fget("access_token");
            this.game.checkout(this, token, (new_access_token)=>{
                if(new_access_token.errno == 1005){
                    this.game.save({"access_token":""});
                    this.game.fremove("access_token");
                }
            });
        },

2.修改main.js中checkout函數

當檢查用戶登錄狀態時,如果用戶點擊取消登錄,則返回1005狀態碼.

class Game{
    // 驗證用戶token是否存在或者是否失效的功能
    checkout(vm, token, callback){
        vm.axios.post("",{
            "jsonrpc": "2.0",
            "id": vm.uuid(),
            "method": "User.check",
            "params": {}
        },{
            headers:{
                Authorization: "jwt " + token,
            }
        }).then(response=>{
            if(parseInt(response.data.result.errno) === 1005){
                api.actionSheet({
                    title: '本次登陸超時,是否更新登陸狀態?',
                    cancelTitle: '取消登陸',
                    destructiveTitle: '更新登陸狀態',
                }, (ret, err)=>{
                    if( ret.buttonIndex == 1 ){ 
                                this.get_acccess_by_refresh(vm, callback);
                    }else{
                                // ********
                              callback({"errno":1005,"errmsg":"登陸超時!"});
                        }
                });
            }else if (parseInt(response.data.result.errno) === 1000){
                callback(token);
            }
            return false;
        }).catch(error=>{
            this.print(error);
        });

    }
    get_acccess_by_refresh(vm, callback){
        var token = this.get("refresh_token") || this.fget("refresh_token");
        if( !token ){
            return false;
        }
        vm.axios.post("",{
            "jsonrpc": "2.0",
            "id": vm.uuid(),
            "method": "User.refresh",
            "params": {}
        },{
            headers:{
                Authorization: "jwt " + token,
            }
        }).then(response=>{
            if(response.data.result.errno===1000){
                this.save({"access_token": response.data.result.access_token});
                callback(response.data.result.access_token);
            }
        })
    }

2.在flask中使用MongoDB

1.安裝

pip install Flask-PyMongo

2.初始化和配置

application/__init__.py,程式碼:

from flask_pymongo import PyMongo

# mongoDB
mongo = PyMongo()

def init_app(config_path):
    """全局初始化"""
   
    # 資料庫初始化
    db.init_app(app)
    app.db = db
    redis.init_app(app)
    mongo.init_app(app) # 初始化mongo
 

`application/settings/dev.py`,程式碼:

from . import InitConfig
class Config(InitConfig):
    """項目開發環境下的配置"""

    # mongoDB配置資訊
    MONGO_URI = "mongodb://127.0.0.1:27017/mofang"

3.在用戶修改個人資訊[頭像]時, 更新歷史記錄到mongodb

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

import base64, uuid,os
from application import mongo
from datetime import datetime
@jsonrpc.method("User.avatar.update")
@jwt_required # 驗證jwt
def update_avatar(avatar):
    """獲取用戶資訊"""
    # 1. 接受客戶端上傳的頭像資訊
    ext = avatar[avatar.find("/")+1:avatar.find(";")]  # 資源格式
    b64_avatar = avatar[avatar.find(",")+1:]
    b64_image = base64.b64decode(b64_avatar)
    filename = uuid.uuid4()
    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)
        
    # 2.判斷用戶是否存在
    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,
        }
    # 3.將用戶頭像存到mysql資料庫中
    user.avatar = "%s.%s" % (filename,ext)
    db.session.commit()
    # ***4.添加修改記錄到MongoDB***!
    document = {
        "user_id": user.id,
        "user_name": user.name,
        "user_nikcname": user.nickname,
        "updated_time": datetime.now().timestamp(), # 修改時間
        "avatar": avatar, # 圖片內容
        "type": "avatar",    # 本次操作的類型
    }
    mongo.db.user_info_history.insert_one(document)

    return {
        "errno": status.CODE_OK,
        "errmsg": message.avatar_save_success,
        "avatar": "%s.%s" % (filename,ext)
    }

3.用戶頁面更新用戶資訊

1.將nickname和avatar改為動態的

2.並且在user.html中添加之前已經寫過的change_avatar函數和get_user_info函數

<!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" id="app">
        <div class="bg">
      <img src="../static/images/bg0.jpg">
    </div>
        <img class="back" @click="goto_index" src="../static/images/user_back.png" alt="">
        <img class="setting" @click="goto_setting" src="../static/images/setting.png" alt="">
        <div class="header">
            <div class="info">
                <div class="avatar">
                    <img class="avatar_bf" src="../static/images/avatar_bf.png" alt="">
                    <img class="user_avatar" :src="avatar" alt="">
                    <img class="avatar_border" src="../static/images/avatar_border.png" alt="">
                </div>
                <p class="user_name">{{nickname}}</p>
            </div>
            <div class="wallet">
                <div class="balance">
                    <p class="title"><img src="../static/images/money.png" alt="">錢包</p>
                    <p class="num">99,999.00</p>
                </div>
                <div class="balance">
                    <p class="title"><img src="../static/images/integral.png" alt="">果子</p>
                    <p class="num">99,999.00</p>
                </div>
            </div>
            <div class="invite">
                <img class="invite_btn" src="../static/images/invite.png" alt="">
            </div>
        </div>
        <div class="menu">
                <div class="item">
                    <span class="title">我的主頁</span>
                    <span class="value">查看</span>
                </div>
                <div class="item">
                    <span class="title">任務列表</span>
                    <span class="value">75%</span>
                </div>
                <div class="item">
                    <span class="title">收益明細</span>
                    <span class="value">查看</span>
                </div>
                <div class="item">
                    <span class="title">實名認證</span>
                    <span class="value">未認證</span>
                </div>
                <div class="item">
                    <span class="title">問題回饋</span>
                    <span class="value">去回饋</span>
                </div>
            </ul>
        </div>
    </div>
    <script>
    apiready = function(){
        init();
        new Vue({
            el:"#app",
            data(){
                return {
                    nickname:"",
                    avatar:"",
                    prev:{name:"",url:"",params:{}},
                    current:{name:"user",url:"user.html",params:{}},
                }
            },
            created(){
                this.get_user_info();
                this.change_avatar();
            },
            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}`;
                                }
                        });
                    },
                    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;
                                this.game.print(res);
                              if(parseInt(res.errno) === 1000){
                                    this.nickname = res.nickname;
                                    this.avatar = `${this.settings.avatar_url}?sign=${res.avatar}&token=${token}`;
                                }
                         })
                    },
                  goto_index(){
            // 返回首頁
            this.game.outWin("user");
          },
                    goto_setting(){
                        // 進入設置
                        this.game.goFrame("setting","setting.html", this.current);
                    }
            }
        });
    }
    </script>
</body>
</html>

用戶頁面更新用戶資訊

解決頭像圓角問題

解決頭像圓角問題,可以通過css修改樣式. main.css,程式碼:

.user .info .user_avatar{
  position: absolute;
  z-index: 1;
  width: 4.56rem;
  height: 4.56rem;
  margin: auto;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  border-radius: 1rem;
}

4.交易密碼介面/密碼修改介面/昵稱修改介面初始化

1.配置頁面點擊交易/密碼修改/昵稱,進入到相應介面

配置頁面中點擊交易密碼/密碼修改/昵稱,進入相應頁面。html/setting.html,程式碼:

<!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>
        <img class="back" @click="goto_home" src="../static/images/user_back.png" alt="">
    <div class="form">
      <div class="item avatar" @click="update_avatar_frame">
        <span class="title">頭像</span>
        <span class="goto">&gt;</span>
        <span class="value">
          <img :src="avatar" alt="">
        </span>
      </div>
      <div class="item" @click="update_nickname_frame">
        <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>
      <div class="item" @click="update_password_frame">
        <span class="title">登陸密碼</span>
        <span class="value"></span>
        <span class="goto">&gt;</span>
      </div>
      <div class="item" @click="update_transaction_password_frame">
        <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">
        <img @click="change_account" src="../static/images/change_account.png" alt="">
        <p @click="logout">退出帳號</p>
      </div>
    </div>
    </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;
                            this.game.print(res);
                          if(parseInt(res.errno) === 1000){
                                this.nickname = res.nickname;
                                this.avatar = `${this.settings.avatar_url}?sign=${res.avatar}&token=${token}`;
                                this.mobile = res.mobile;
                            }
                     })
                },
                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}`;
                        }
                    });
                },
        goto_home(){
          // this.game.outFrame("setting");
          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);  // 取消為2
                   if(ret.buttonIndex==1){
                     this.game.save({"access_token":"","refresh_token":""});
                     this.game.fremove(["access_token","refresh_token"]);
                     this.game.outWin("user");
                   }
              }
          });
        },
                update_avatar_frame(){
                    // 顯示修改頭像的頁面frame
                    this.game.goFrame("avatar","avatar.html", this.current,null,{
                        type:"push",             //動畫類型(詳見動畫類型常量)
                        subType:"from_top",    //動畫子類型(詳見動畫子類型常量)
                        duration:300             //動畫過渡時間,默認300毫秒
                });
                },
                update_transaction_password_frame(){
                    this.game.goFrame("transaction_password","transaction_password.html", this.current,null,{
                        type:"push",
                        subType:"from_top",
                        duration:300
                    });
                },
                update_password_frame(){
                    this.game.goFrame("password","password.html", this.current,null,{
                        type:"push",
                        subType:"from_top",
                        duration:300
                    });
                },
                update_nickname_frame(){
                    this.game.goFrame("password","password.html", this.current,null,{
                        type:"push",
                        subType:"from_top",
                        duration:300
                    });
                }
            }
        });
    }
    </script>
</body>
</html>

配置頁面點擊不同項進入不同頁面

2.交易頁面初始化

<!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 update_password" id="app">
    <div class="box">
      <p class="title">交易密碼</p>
      <img class="close" @click="close_frame" src="../static/images/close_btn1.png" alt="">
      <div class="content">
                <input class="password" type="text" v-model="password" placeholder="交易密碼....">
                <input class="password password2" type="text" v-model="password2" placeholder="確認交易密碼....">
      </div>
      <img @click="update_password_commit" class="btn" src="../static/images/yes.png" alt="">
    </div>
    </div>
    <script>
    apiready = function(){
        init();
        new Vue({
            el:"#app",
            data(){
                return {
                    password:"",
                    password2:"",
                    prev:{name:"",url:"",params:{}},
                    current:{name:"transaction_password",url:"transaction_password.html",params:{}},
                }
            },
            methods:{
        close_frame(){
          this.game.outFrame("transaction_password");
        },
        update_password_commit(){
          // 提交用戶密碼

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

交易頁面transaction_password.html初始化

交易介面CSS樣式

.update_nickname .nickname,
.update_password .password
{
  margin: 8rem 4.4rem 4rem;
  width: 19.50rem;
  height: 4rem;
  line-height: 4rem;
  background-color: #cc9966;
  outline: none;
  border: 1px solid #330000;
  text-align: center;
  font-size: 1.5rem;
  color: #ffffcc;
}
.update_password .password{
  margin-top: 5.6rem;
  margin-bottom: 0.4rem;
}
.update_password .password2{
  margin-top: 0.4rem;
}

交易介面CSS樣式

3.密碼修改介面初始化

<!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 update_password" id="app">
    <div class="box">
      <p class="title">修改密碼</p>
      <img class="close" @click="close_frame" src="../static/images/close_btn1.png" alt="">
      <div class="content">
                <input class="password" type="text" v-model="password" placeholder="原密碼....">
                <input class="password password2" type="text" v-model="password2" placeholder="新密碼....">
      </div>
      <img @click="update_password_commit" class="btn" src="../static/images/yes.png" alt="">
    </div>
    </div>
    <script>
    apiready = function(){
        init();
        new Vue({
            el:"#app",
            data(){
                return {
                    password:"",
                    password2:"",
                    prev:{name:"",url:"",params:{}},
                    current:{name:"password",url:"password.html",params:{}},
                }
            },
            methods:{
        close_frame(){
          this.game.outFrame("password");
        },
        update_password_commit(){
          // 提交用戶密碼

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

密碼修改介面password.html

4.昵稱修改介面初始化

<!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 update_nickname" id="app">
    <div class="box">
      <p class="title">修改昵稱</p>
      <img class="close" @click="close_frame" src="../static/images/close_btn1.png" alt="">
      <div class="content">
                <input class="nickname" type="text" v-model="nickname" placeholder="輸入昵稱....">
      </div>
      <img @click="update_nickname_commit" class="btn" src="../static/images/yes.png" alt="">
    </div>
    </div>
    <script>
    apiready = function(){
        init();
        new Vue({
            el:"#app",
            data(){
                return {
                    nickname:"",
                    prev:{name:"",url:"",params:{}},
                    current:{name:"nickname",url:"nickname.html",params:{}},
                }
            },
            methods:{
        close_frame(){
          this.game.outFrame("nickname");
        },
        update_nickname_commit(){
          // 提交用戶昵稱

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

昵稱修改介面nickname.html初始化

5.交易密碼實現

1.模型中新增交易密碼欄位

模型中,新增一個交易密碼的欄位.users.models程式碼:

from werkzeug.security import generate_password_hash, check_password_hash
from application.utils.models import BaseModel,db
class User(BaseModel):
    """用戶基本資訊"""

    
    # 新增一個交易密碼的欄位
    _transaction_password = db.Column(db.String(255), comment="交易密碼")
    

    @property
    def transaction_password(self):
        return self._transaction_password

    @transaction_password.setter
    def transaction_password(self, rawpwd):
        """密碼加密"""
        self._transaction_password = generate_password_hash(rawpwd)

    def check_transaction_password(self, rawpwd):
        """驗證密碼"""
        return check_password_hash(self.transaction_password, rawpwd)

數據遷移,命令:

python manage.py db migrate -m "add user tansaction password"
python manage.py db upgrade

2.編寫交易密碼後端介面

視圖中編寫交易密碼修改的介面,users.views.,程式碼

@jsonrpc.method("User.transaction.password")
@jwt_required # 驗證jwt
def transaction_password(password1, password2,old_password=None):
    """
    交易密碼的初始化和修改
    1. 剛註冊的用戶,沒有交易密碼,所以此處填寫的是新密碼
    2. 已經有了交易密碼的用戶,修改舊的交易密碼
    """
    # 1.判斷兩次輸入密碼是否一致
    if password1 != password2:
        return {
            "errno": status.CODE_TRANSACTION_PASSWORD_ERROR,
            "errmsg": message.transaction_password_not_match
        }
    # 2.判斷用戶是否存在
    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,
        }

    # 3.如果之前有存在交易密碼,則需要驗證舊密碼
    if user.transaction_password: # 去資料庫查看用戶是否有舊的交易密碼
        """修改"""
        # 驗證舊密碼
        ret = user.check_transaction_password(old_password)
        if ret == False: # 如果驗證舊密碼失敗
            return {
                "errno": status.CODE_PASSWORD_ERROR,
                "errmsg": message.transaction_password_error
            }

    """設置交易密碼"""
    user.transaction_password = password1
    db.session.commit()
    return {
        "errno": status.CODE_OK,
        "errmsg": message.ok
    }

3.客戶端提交交易密碼變更後端用戶資訊

<!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 update_password" id="app">
    <div class="box">
      <p class="title">交易密碼</p>
      <img class="close" @click="close_frame" src="../static/images/close_btn1.png" alt="">
      <div class="content" v-if="is_set_password">
                <input class="password" type="password" v-model="old_password" placeholder="舊交易密碼....">
                <input class="password password2" type="password" v-model="password1" placeholder="新交易密碼....">
                <input class="password password2" type="password" v-model="password2" placeholder="確認新交易密碼....">
      </div>
      <div class="content" v-else>
        <input class="password" type="password" v-model="password1" placeholder="交易密碼....">
        <input class="password password2" type="password" v-model="password2" placeholder="確認交易密碼....">
      </div>
      <img @click="update_password_commit" class="btn" src="../static/images/yes.png" alt="">
    </div>
    </div>
    <script>
    apiready = function(){
        init();
        new Vue({
            el:"#app",
            data(){
                return {
          is_set_password: true,
          old_password: "", // 舊交易密碼
                    password1:"",      // 新交易密碼
                    password2:"",     // 確認新交易密碼
                    prev:{name:"",url:"",params:{}},
                    current:{name:"transaction_password",url:"transaction_password.html",params:{}},
                }
            },
      created(){
          if( this.game.fget("is_set_transaction_password") === "false"){
            this.is_set_password = false;
          }
      },
            methods:{
        close_frame(){
          this.game.outFrame("transaction_password");
        },
        update_password_commit(){
          // 1.提交用戶新密碼
          params = {
            password1: this.password1,
            password2: this.password2,
          }
          // 2.如果不是第一次設置密碼,需要將舊密碼也提交到後端  
          if(this.is_set_password){
            params.old_password = this.old_password;
          }
          // 3.向交易密碼後端介面發送請求
          var token = this.game.get("access_token") || this.game.fget("access_token");
          this.axios.post("",{
           "jsonrpc": "2.0",
           "id": this.uuid(),
           "method": "User.transaction.password",
           "params": params
         },{
            headers:{
              Authorization: "jwt " + token,
            }
          }).then(response=>{
            var res = response.data.result;
            if(parseInt(res.errno) === 1000){
              this.game.fsave({"is_set_transaction_password":true});
              this.game.outFrame("transaction_password");
            }else{
              api.alert({
                  title: '錯誤!',
                  msg: res.errmsg,
              }, function(ret, err){
                  
              });

              this.game.print(res.errno);
            }
          }).catch(error=>{
            this.game.print(error);
          });
        }
            }
        });
    }
    </script>
</body>
</html>

4.把交易密碼更變歷史記錄到Mongodb中

@jsonrpc.method("User.transaction.password")
@jwt_required # 驗證jwt
def transaction_password(password1, password2,old_password=None):
    """
    交易密碼的初始化和修改
    1. 剛註冊的用戶,沒有交易密碼,所以此處填寫的是新密碼
    2. 已經有了交易密碼的用戶,修改舊的交易密碼
    """

    if password1 != password2:
        return {
            "errno": status.CODE_TRANSACTION_PASSWORD_ERROR,
            "errmsg": message.transaction_password_not_match
        }

    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,
        }

    # 1.如果之前有存在交易密碼,則需要驗證舊密碼
    if user.transaction_password:
        """修改"""
        # 驗證舊密碼
        ret = user.check_transaction_password(old_password)
        if ret == False:
            return {
                "errno": status.CODE_PASSWORD_ERROR,
                "errmsg": message.transaction_password_error
            }

    """設置交易密碼"""
    user.transaction_password = password1
    db.session.commit()

    # ***2.添加交易密碼的修改記錄,為了保證安全,僅僅記錄舊密碼!***
    if old_password:
        document = {
            "user_id": user.id,
            "user_name": user.name,
            "user_nikcname": user.nickname,
            "updated_time": datetime.now().timestamp(),        # 修改時間
            "transaction_password": old_password, # 變更內容
            "type": "transaction_password",    # 本次操作的類型
        }
        mongo.db.user_info_history.insert_one(document)

    return {
        "errno": status.CODE_OK,
        "errmsg": message.ok
    }