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
    }