zoukankan      html  css  js  c++  java
  • day115:MoFang:种植园我的背包&种植园道具购买

    目录

    1.我的背包

    2.道具购买

    1.我的背包

    1.在种植园点击背包按钮打开我的背包

    在种植园打开背包,orchard.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>
        <script src="../static/js/socket.io.js"></script>
    </head>
    <body>
        <div class="app orchard" id="app">
        <img class="music" :class="music_play?'music2':''" @click="music_play=!music_play" src="../static/images/player.png">
        <div class="orchard-bg">
                <img src="../static/images/bg2.png">
                <img class="board_bg2" src="../static/images/board_bg2.png">
            </div>
        <img class="back" @click="go_index" src="../static/images/user_back.png" alt="">
        <div class="header">
                <div class="info" @click="go_home">
                    <div class="avatar">
                        <img class="avatar_bf" src="../static/images/avatar_bf.png" alt="">
                        <img class="user_avatar" src="../static/images/avatar.png" alt="">
                        <img class="avatar_border" src="../static/images/avatar_border.png" alt="">
                    </div>
                    <p class="user_name">好听的昵称</p>
                </div>
                <div class="wallet">
                    <div class="balance" @click="user_recharge">
                        <p class="title"><img src="../static/images/money.png" alt="">钱包</p>
                        <p class="num">{{money}}</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="menu-list">
            <div class="menu">
              <img src="../static/images/menu1.png" alt="">
              排行榜
            </div>
            <div class="menu">
              <img src="../static/images/menu2.png" alt="">
              签到有礼
            </div>
            <div class="menu" @click="go_orchard_shop">
              <img src="../static/images/menu3.png" alt="">
              道具商城
            </div>
            <div class="menu">
              <img src="../static/images/menu4.png" alt="">
              邮件中心
            </div>
          </div>
            </div>
        <div class="footer" >
          <ul class="menu-list">
            <li class="menu">新手</li>
            <li class="menu" @click="go_my_package">背包</li>
            <li class="menu-center" @click="go_orchard_shop">商店</li>
            <li class="menu">消息</li>
            <li class="menu">好友</li>
          </ul>
        </div>
        </div>
        <script>
        apiready = function(){
            init();
            new Vue({
                el:"#app",
                data(){
                    return {
              music_play:true,
              namespace: '/mofang_orchard',
              token:"",
                        money:"",
              socket: null,
                        recharge_list: ['10','20','50','100','200','500','1000'],
              timeout: 0,
                        prev:{name:"",url:"",params:{}},
                        current:{name:"orchard",url:"orchard.html",params:{}},
                    }
                },
          created(){
            this.game.goFrame("orchard","my_orchard.html", this.current,{
                x: 0,
                y: 180,
                w: 'auto',
                h: 410,
            },null);
            this.checkout();
                    this.money = this.game.fget("money")
          },
                methods:{
                    user_recharge(){
                        // 发起充值请求
                        api.actionSheet({
                            title: '余额充值',
                            cancelTitle: '取消',
                            buttons: this.recharge_list
                        }, (ret, err)=>{
                            if( ret ){
                                         if(ret.buttonIndex <= this.recharge_list.length){
                                                 // 充值金额
                                                 money = this.recharge_list[ret.buttonIndex-1];
                                                 // 调用支付宝充值
                                                 this.create_recharge(money);
                                         }
                            }else{
    
                            }
                        });
    
                    },
                    create_recharge(money){
                        // 获取历史信息记录
                        var token = this.game.get("access_token") || this.game.fget("access_token");
                        this.game.checkout(this, token, (new_access_token)=>{
                            this.axios.post("",{
                                "jsonrpc": "2.0",
                                "id": this.uuid(),
                                "method": "Recharge.create",
                                "params": {
                                    "money": money,
                                }
                            },{
                                headers:{
                                    Authorization: "jwt " + token,
                                }
                            }).then(response=>{
                                if(parseInt(response.data.result.errno)==1000){
                                    // 前往支付宝
                                    var aliPayPlus = api.require('aliPayPlus');
                                    aliPayPlus.payOrder({
                                         orderInfo: response.data.result.order_string,
                                         sandbox: response.data.result.sandbox, // 将来APP上线需要修改成false
                                     }, (ret, err)=>{
                                          pay_result = {
                                                9000:"支付成功",
                              8000:"正在处理中",
                              4000:"订单支付失败",
                              5000:"重复请求",
                              6001:"取消支付",
                              6002:"网络连接出错",
                                                6004:"支付结果未知",
                                            }
                                        api.alert({
                                            title: '支付结果',
                                            msg: pay_result[ret.code],
                                            buttons: ['确定']
                                        });
                                            // 通知服务端, 修改充值结果
                                            this.return_recharge(response.data.result.order_number,token);
                                    });
                                }else{
                                        this.game.print(response.data);
                                }
                            }).catch(error=>{
                                // 网络等异常
                                this.game.print(error);
                            });
                        })
                    },
                    return_recharge(out_trade_number,token){
                        this.axios.post("",{
                            "jsonrpc": "2.0",
                            "id": this.uuid(),
                            "method": "Recharge.return",
                            "params": {
                                "out_trade_number": out_trade_number,
                            }
                        },{
                            headers:{
                                Authorization: "jwt " + token,
                            }
                        }).then(response=>{
                            if(parseInt(response.data.result.errno)==1000){
                                this.money = response.data.result.money.toFixed(2);
                            }
                        })
                    },
            checkout(){
              var token = this.game.get("access_token") || this.game.fget("access_token");
              this.game.checkout(this,token,(new_access_token)=>{
                this.connect();
              });
            },
            connect(){
              // socket连接
              this.socket = io.connect(this.settings.socket_server + this.namespace, {transports: ['websocket']});
              this.socket.on('connect', ()=>{
                  this.game.print("开始连接服务端");
              });
            },
            go_index(){
              this.game.outWin("orchard");
            },
            go_friends(){
              this.game.goFrame("friends","friends.html",this.current);
              this.game.goFrame("friend_list","friend_list.html",this.current,{
                  x: 0,
                  y: 190,
                  w: 'auto',
                  h: 'auto',
              },null,true);
            },
            go_home(){
              this.game.goWin("user","user.html", this.current);
            },
                    go_orchard_shop(){
                        // 种植园商店
                        this.game.goFrame("orchard_shop","shop.html", this.current,null,{
                  type:"push",
                  subType:"from_top",
                  duration:300
              });
                    },
                    go_my_package(){
                        // 我的背包
                        this.game.goFrame("package","package.html", this.current,null,{
                  type:"push",
                  subType:"from_top",
                  duration:300
              });
                    },
                }
            });
        }
        </script>
    </body>
    </html>
    在种植园点击背包按钮打开我的背包

    2.我的背包页面初始化

    package.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 frame avatar add_friend package" id="app">
        <div class="box">
          <p class="title">我的背包</p>
          <img class="close" @click="close_frame" src="../static/images/close_btn1.png" alt="">
          <div class="prop_list">
            <div class="item">
              <img src="../static/images/fruit_tree.png" alt="">
              <span>10</span>
            </div>
            <div class="item">
              <img src="../static/images/prop1.png" alt="">
              <span>10</span>
            </div>
            <div class="item"></div>
            <div class="item"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
            <div class="item lock"></div>
          </div>
        </div>
        </div>
        <script>
        apiready = function(){
            init();
            new Vue({
                el:"#app",
                data(){
                    return {
                        user_id: "", // 当前登陆用户Id
                        prev:{name:"",url:"",params:{}},
                        current:{name:"package",url:"package.html",params:{}},
                    }
                },
    
                created(){
                    this.user_id = this.game.get("id") || this.game.fget("id");
                },
                methods:{
            close_frame(){
              this.game.outFrame("package");
            },
                }
            });
        }
        </script>
    </body>
    </html>
    我的背包页面初始化:package.html

    3.我的背包页面CSS样式

    main.css,代码:

    .package .prop_list{
      position: absolute;
      left: 4.2rem;
      top: 10rem;
      width: 21rem;
      height: 39.8rem;
      overflow: scroll;
    }
    
    .package .prop_list .item{
      background: #a63600;
      border: 3px solid #ff9900;
      width: 4rem;
      height: 4rem;
      margin: .2rem;
      float: left;
      border-radius: 5px;
      position: relative;
    }
    
    .package .prop_list .item img{
      position: absolute;
      margin: auto;
      width: 3rem;
      height: 3rem;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
    }
    .package .prop_list .item span{
      font-size: 1.5rem;
      color: #fff;
      position: absolute;
      bottom: 0;
      right: 0;
    }
    .package .prop_list .lock:after{
      display: block;
      content:"x";
      font-size: 4rem;
      color: #ff9900;
      text-align: center;
      line-height: 100%;
      height: 4rem;
      width: 4rem;
    }
    我的背包页面CSS样式

    4.种植园道具的配置参数

    经过了充值以后, 用户就可以有对应的余额进行购买商品, 而对于商品中的果树, 道具等使用用户信息, 我们可以理解为 配置参数, 这些配置参数与以往的dev.py里面填写的项目配置信息不也一样, 这些参数是业务相关的, 在运营过程中随时可能发生变化, 而dev.py中的配置信息, 则在项目上线以后基本不会发生变化.

    所以需要在实现商品购买以后, 还需要把参数保存到数据库中.

    为参数信息设计表结构,orchard/models.py代码:

    class Setting(BaseModel):
        """参数信息"""
        __tablename__ = "mf_orchard_setting"
        title=db.Column(db.String(255), comment="提示文本")
        value=db.Column(db.String(255), comment="数值")

    5.商品既可以用果子购买也可以用余额购买

    修改商店中商品购买的货币信息, 模型代码:

    orchard/models.py, 代码:

    from application.utils.models import BaseModel,db
    class Goods(BaseModel):
        """商品基本信息"""
        __tablename__ = "mf_goods"
        remark = db.Column(db.String(255), comment="商品描述")
        price = db.Column(db.Numeric(7,2), comment="商品价格[余额]")
        credit = db.Column(db.Integer,     comment="商品价格[果子]")
        image = db.Column(db.String(255),  comment="商品图片")

    6.修复socket的会话ID持续刷新的问题

    修复用户在进入种植园页面和返回首页时, socket的回话ID持续刷新的问题.此处我们需要在窗口切换的时候, 不能关闭窗口和刷新页面.因此修改代码如下.

    1.index.html

    index.html,修改go_orchard方法的代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <title>首页</title>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
      <meta name="format-detection" content="telephone=no,email=no,date=no,address=no">
      <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" id="app">
        <img class="music" :class="music_play?'music2':''" @click="music_play=!music_play" src="../static/images/player.png">
        <div class="bg">
          <img src="../static/images/bg0.jpg">
        </div>
        <ul>
          <li><img class="module1" @click="go_orchard" src="../static/images/image1.png"></li>
          <li><img class="module2" @click="go_home" src="../static/images/image2.png"></li>
          <li><img class="module3" src="../static/images/image3.png"></li>
          <li><img class="module4" src="../static/images/image4.png"></li>
        </ul>
      </div>
      <script>
        apiready = function(){
        init();
            new Vue({
                el:"#app",
                data(){
                    return {
              music_play:true,  // 默认播放背景音乐
                        prev:{name:"",url:"",params:{}}, // 上一页状态
                        current:{name:"index",url:"index.html","params":{}}, // 下一页状态
                    }
                },
          watch:{
            music_play(){
              if(this.music_play){
                this.game.play_music("../static/mp3/bg1.mp3");
              }else{
                this.game.stop_music();
              }
            }
          },
          created(){
            this.app_listener();
            this.check_user_login();
          },
                methods:{
            app_listener(){
              // 使用appintenr监听并使用appParam接收URLScheme的参数
              // 收集操作保存起来,并跳转到注册页面.
              // 注册frame中, 用户注册成功以后,记录邀请信息.
              api.addEventListener({
                  name:'appintent' // 当前事件监听必须是唯一的,整个APP中只能编写一次,否则冲突导致监听无效
              },(ret,err)=>{
                  var appParam = ret.appParam;
                  this.game.print(typeof appParam); // {"uid":"15"}
                  // 保存URLScheme参数到本地
                  this.game.fsave(appParam);
                  // 跳转到注册页面
                  this.game.goWin("user","register.html", this.current);
              });
            },
            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");
                }
              });
            },
            go_home(){
              if(this.game.get("access_token") || this.game.fget("access_token")){
                this.game.goWin("user","user.html", this.current);
              }else{
                this.game.goWin("user","login.html", this.current);
              }
            },
            go_orchard(){
              if(this.game.get("access_token") || this.game.fget("access_token")){
                this.game.goWin("orchard","orchard.html", this.current,reload=false);
              }else{
                this.game.goWin("user","login.html", this.current);
              }
            }
                }
            })
        }
        </script>
    </body>
    </html>
    index.html修改go_orchard方法

    2.orchard.html

    修改orchard.html的go_index方法代码:

    <!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>
        <script src="../static/js/socket.io.js"></script>
    </head>
    <body>
        <div class="app orchard" id="app">
        <img class="music" :class="music_play?'music2':''" @click="music_play=!music_play" src="../static/images/player.png">
        <div class="orchard-bg">
                <img src="../static/images/bg2.png">
                <img class="board_bg2" src="../static/images/board_bg2.png">
            </div>
        <img class="back" @click="go_index" src="../static/images/user_back.png" alt="">
        <div class="header">
                <div class="info" @click="go_home">
                    <div class="avatar">
                        <img class="avatar_bf" src="../static/images/avatar_bf.png" alt="">
                        <img class="user_avatar" src="../static/images/avatar.png" alt="">
                        <img class="avatar_border" src="../static/images/avatar_border.png" alt="">
                    </div>
                    <p class="user_name">好听的昵称</p>
                </div>
                <div class="wallet">
                    <div class="balance" @click="user_recharge">
                        <p class="title"><img src="../static/images/money.png" alt="">钱包</p>
                        <p class="num">{{money}}</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="menu-list">
            <div class="menu">
              <img src="../static/images/menu1.png" alt="">
              排行榜
            </div>
            <div class="menu">
              <img src="../static/images/menu2.png" alt="">
              签到有礼
            </div>
            <div class="menu" @click="go_orchard_shop">
              <img src="../static/images/menu3.png" alt="">
              道具商城
            </div>
            <div class="menu">
              <img src="../static/images/menu4.png" alt="">
              邮件中心
            </div>
          </div>
            </div>
        <div class="footer" >
          <ul class="menu-list">
            <li class="menu">新手</li>
            <li class="menu" @click="go_my_package">背包</li>
            <li class="menu-center" @click="go_orchard_shop">商店</li>
            <li class="menu">消息</li>
            <li class="menu">好友</li>
          </ul>
        </div>
        </div>
        <script>
        apiready = function(){
            init();
            new Vue({
                el:"#app",
                data(){
                    return {
              music_play:true,
              namespace: '/mofang',
              token:"",
                        money:"",
              socket: null,
                        recharge_list: ['10','20','50','100','200','500','1000'],
              timeout: 0,
                        prev:{name:"",url:"",params:{}},
                        current:{name:"orchard",url:"orchard.html",params:{}},
                    }
                },
          created(){
            this.game.goFrame("orchard","my_orchard.html", this.current,{
                x: 0,
                y: 180,
                w: 'auto',
                h: 410,
            },null);
            this.checkout();
                    this.money = this.game.fget("money")
          },
                methods:{
                    user_recharge(){
                        // 发起充值请求
                        api.actionSheet({
                            title: '余额充值',
                            cancelTitle: '取消',
                            buttons: this.recharge_list
                        }, (ret, err)=>{
                            if( ret ){
                                         if(ret.buttonIndex <= this.recharge_list.length){
                                                 // 充值金额
                                                 money = this.recharge_list[ret.buttonIndex-1];
                                                 // 调用支付宝充值
                                                 this.create_recharge(money);
                                         }
                            }else{
    
                            }
                        });
    
                    },
                    create_recharge(money){
                        // 获取历史信息记录
                        var token = this.game.get("access_token") || this.game.fget("access_token");
                        this.game.checkout(this, token, (new_access_token)=>{
                            this.axios.post("",{
                                "jsonrpc": "2.0",
                                "id": this.uuid(),
                                "method": "Recharge.create",
                                "params": {
                                    "money": money,
                                }
                            },{
                                headers:{
                                    Authorization: "jwt " + token,
                                }
                            }).then(response=>{
                                if(parseInt(response.data.result.errno)==1000){
                                    // 前往支付宝
                                    var aliPayPlus = api.require('aliPayPlus');
                                    aliPayPlus.payOrder({
                                         orderInfo: response.data.result.order_string,
                                         sandbox: response.data.result.sandbox, // 将来APP上线需要修改成false
                                     }, (ret, err)=>{
                                          pay_result = {
                                                9000:"支付成功",
                              8000:"正在处理中",
                              4000:"订单支付失败",
                              5000:"重复请求",
                              6001:"取消支付",
                              6002:"网络连接出错",
                                                6004:"支付结果未知",
                                            }
                                        api.alert({
                                            title: '支付结果',
                                            msg: pay_result[ret.code],
                                            buttons: ['确定']
                                        });
                                            // 通知服务端, 修改充值结果
                                            this.return_recharge(response.data.result.order_number,token);
                                    });
                                }else{
                                        this.game.print(response.data);
                                }
                            }).catch(error=>{
                                // 网络等异常
                                this.game.print(error);
                            });
                        })
                    },
                    return_recharge(out_trade_number,token){
                        this.axios.post("",{
                            "jsonrpc": "2.0",
                            "id": this.uuid(),
                            "method": "Recharge.return",
                            "params": {
                                "out_trade_number": out_trade_number,
                            }
                        },{
                            headers:{
                                Authorization: "jwt " + token,
                            }
                        }).then(response=>{
                            if(parseInt(response.data.result.errno)==1000){
                                this.money = response.data.result.money.toFixed(2);
                            }
                        })
                    },
            checkout(){
              var token = this.game.get("access_token") || this.game.fget("access_token");
              this.game.checkout(this,token,(new_access_token)=>{
                this.connect();
              });
            },
            connect(){
              // socket连接
              this.socket = io.connect(this.settings.socket_server + this.namespace, {transports: ['websocket']});
              this.socket.on('connect', ()=>{
                  this.game.print("开始连接服务端");
              });
            },
            go_index(){
              this.game.goWin("root");
            },
            go_friends(){
              this.game.goFrame("friends","friends.html",this.current);
              this.game.goFrame("friend_list","friend_list.html",this.current,{
                  x: 0,
                  y: 190,
                  w: 'auto',
                  h: 'auto',
              },null,true);
            },
            go_home(){
              this.game.goWin("user","user.html", this.current);
            },
                    go_orchard_shop(){
                        // 种植园商店
                        this.game.goFrame("orchard_shop","shop.html", this.current,null,{
                  type:"push",
                  subType:"from_top",
                  duration:300
              });
                    },
                    go_my_package(){
                        // 我的背包
                        this.game.goFrame("package","package.html", this.current,null,{
                  type:"push",
                  subType:"from_top",
                  duration:300
              });
                    },
                }
            });
        }
        </script>
    </body>
    </html>
    orchard.html修改go_index方法

    3.main.js

    main.js中修改goWin方法,增加reload参数

    goWin(name,url,pageParam,reload=true){
        // 新建窗口
        api.openWin({
            name: name,            // 自定义窗口名称
            bounces: false,        // 窗口是否上下拉动
            reload: reload,          // 如果页面已经在之前被打开了,是否要重新加载当前窗口中的页面
            useWKWebView:true,
            historyGestureEnabled:true,
            url: url,              // 窗口创建时展示的html页面的本地路径[相对于当前代码所在文件的路径]
            animation:{            // 打开新建窗口时的过渡动画效果
                type: "push",                //动画类型(详见动画类型常量)
                subType: "from_right",       //动画子类型(详见动画子类型常量)
                duration:300                //动画过渡时间,默认300毫秒
            },
            pageParam: pageParam   // 传递给下一个窗口使用的参数.将来可以在新窗口中通过 api.pageParam.name 获取
        });
    }

    2.道具购买

    1.在商城点击商品触发购买buy_prop方法

    shop.html中发起购买通知, 获取购买的道具ID和数量,代码:

    <!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 add_friend shop" id="app">
        <div class="box">
          <p class="title">商店</p>
          <img class="close" @click="close_frame" src="../static/images/close_btn1.png" alt="">
          <div class="friends_list shop_list">
            <div class="item" @click="buy_prop(goods.id)" v-for="goods in goods_list">
              <div class="avatar shop_item">
                <img :src="settings.static_url+goods.image" alt="">
              </div>
              <div class="info">
                <p class="username">{{goods.name}}</p>
                <p class="time">{{goods.remark}}</p>
              </div>
              <div class="status">{{goods.price}}</div>
            </div>
          </div>
        </div>
        </div>
        <script>
        apiready = function(){
            init();
            new Vue({
                el:"#app",
                data(){
                    return {
                        user_id: "", // 当前登陆用户Id
              goods_list:[], // 商品列表
              page: 1,
              limit: 10,
              is_send_ajax:false,
                        prev:{name:"",url:"",params:{}},
                        current:{name:"orchard",url:"shop.html",params:{}},
                    }
                },
                created(){
                    this.user_id = this.game.get("id") || this.game.fget("id");
            this.get_goods_list();
                },
                methods:{
            close_frame(){
              this.game.outFrame("orchard_shop");
            },
            get_goods_list(){
                        if(this.is_send_ajax){
                            return ;
                        }
                        // 通过请求获取当前用户的好友列表
                        var token = this.game.get("access_token") || this.game.fget("access_token");
                        this.game.checkout(this, token, (new_access_token)=>{
                            this.is_send_ajax = true;
                            this.axios.post("",{
                                "jsonrpc": "2.0",
                                "id": this.uuid(),
                                "method": "Orchard.goods.list",
                                "params": {
                                    "page": this.page,
                    "limit": this.limit,
                                }
                            },{
                                headers:{
                                    Authorization: "jwt " + token,
                                }
                            }).then(response=>{
                                if(parseInt(response.data.result.errno)==1000){
                                    if(this.page+1 == response.data.result.pages){
                                        this.is_send_ajax = true;
                                    }else{
                                        this.is_send_ajax = false;
                                        this.page+=1;
                                    }
                                    if(this.page>1){
                                        api.refreshHeaderLoadDone();
                                    }
                                    this.goods_list = response.data.result.goods_list.concat(this.goods_list);
                                }else if(parseInt(response.data.result.errno) == 1008){
                                    this.friends = [];
                                }else{
                                        this.game.print(response.data);
                                }
                            }).catch(error=>{
                                // 网络等异常
                                this.game.print(error);
                            });
                        })
                    },
                    buy_prop(prop_id){
                        // 购买商品道具
                        // 让用户选择购买的数量
                        api.prompt({
                                text: 1,
                                title:"请输入购买数量",
                                type: "number",
                            buttons: ['确定', '取消']
                        }, (ret, err)=>{
                                if(ret.buttonIndex == 1){
                                    // 通过通知告知socket进行商品购买
                                    api.sendEvent({
                                            name: 'buy_prop',
                                            extra: {
                                                "pid": prop_id,
                                                "num": ret.text
                                            }
                                    });
                                }
                        });
                    }
                }
            });
        }
        </script>
    </body>
    </html>
    shop.html发起购买通知请求

    2.种植园主页面监听商城页面购买道具的方法

    在种植园主页面orchard.html中通过监听获取购买道具的通知, 并通过socket发起请求服务端进行购买, 代码:

    <!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/jAs/axios.js"></script>
        <script src="../static/js/main.js"></script>
        <script src="../static/js/uuid.js"></script>
        <script src="../static/js/settings.js"></script>
        <script src="../static/js/socket.io.js"></script>
    </head>
    <body>
        <div class="app orchard" id="app">
        <img class="music" :class="music_play?'music2':''" @click="music_play=!music_play" src="../static/images/player.png">
        <div class="orchard-bg">
                <img src="../static/images/bg2.png">
                <img class="board_bg2" src="../static/images/board_bg2.png">
            </div>
        <img class="back" @click="go_index" src="../static/images/user_back.png" alt="">
        <div class="header">
                <div class="info" @click="go_home">
                    <div class="avatar">
                        <img class="avatar_bf" src="../static/images/avatar_bf.png" alt="">
                        <img class="user_avatar" src="../static/images/avatar.png" alt="">
                        <img class="avatar_border" src="../static/images/avatar_border.png" alt="">
                    </div>
                    <p class="user_name">好听的昵称</p>
                </div>
                <div class="wallet">
                    <div class="balance" @click="user_recharge">
                        <p class="title"><img src="../static/images/money.png" alt="">钱包</p>
                        <p class="num">{{money}}</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="menu-list">
            <div class="menu">
              <img src="../static/images/menu1.png" alt="">
              排行榜
            </div>
            <div class="menu">
              <img src="../static/images/menu2.png" alt="">
              签到有礼
            </div>
            <div class="menu" @click="go_orchard_shop">
              <img src="../static/images/menu3.png" alt="">
              道具商城
            </div>
            <div class="menu">
              <img src="../static/images/menu4.png" alt="">
              邮件中心
            </div>
          </div>
            </div>
        <div class="footer" >
          <ul class="menu-list">
            <li class="menu">新手</li>
            <li class="menu" @click="go_my_package">背包</li>
            <li class="menu-center" @click="go_orchard_shop">商店</li>
            <li class="menu">消息</li>
            <li class="menu">好友</li>
          </ul>
        </div>
        </div>
        <script>
        apiready = function(){
            init();
            new Vue({
                el:"#app",
                data(){
                    return {
              music_play:true,
              namespace: '/mofang',
              token:"",
                        money:"",
              socket: null,
                        recharge_list: ['10','20','50','100','200','500','1000'],
              timeout: 0,
                        prev:{name:"",url:"",params:{}},
                        current:{name:"orchard",url:"orchard.html",params:{}},
                    }
                },
          created(){
            this.game.goFrame("orchard","my_orchard.html", this.current,{
                x: 0,
                y: 180,
                w: 'auto',
                h: 410,
            },null);
            this.checkout();
                    this.money = this.game.fget("money");
                    this.buy_prop();
          },
                methods:{
                    user_recharge(){
                        // 发起充值请求
                        api.actionSheet({
                            title: '余额充值',
                            cancelTitle: '取消',
                            buttons: this.recharge_list
                        }, (ret, err)=>{
                            if( ret ){
                                         if(ret.buttonIndex <= this.recharge_list.length){
                                                 // 充值金额
                                                 money = this.recharge_list[ret.buttonIndex-1];
                                                 // 调用支付宝充值
                                                 this.create_recharge(money);
                                         }
                            }else{
    
                            }
                        });
    
                    },
                    create_recharge(money){
                        // 获取历史信息记录
                        var token = this.game.get("access_token") || this.game.fget("access_token");
                        this.game.checkout(this, token, (new_access_token)=>{
                            this.axios.post("",{
                                "jsonrpc": "2.0",
                                "id": this.uuid(),
                                "method": "Recharge.create",
                                "params": {
                                    "money": money,
                                }
                            },{
                                headers:{
                                    Authorization: "jwt " + token,
                                }
                            }).then(response=>{
                                if(parseInt(response.data.result.errno)==1000){
                                    // 前往支付宝
                                    var aliPayPlus = api.require('aliPayPlus');
                                    aliPayPlus.payOrder({
                                         orderInfo: response.data.result.order_string,
                                         sandbox: response.data.result.sandbox, // 将来APP上线需要修改成false
                                     }, (ret, err)=>{
                                          pay_result = {
                                                9000:"支付成功",
                              8000:"正在处理中",
                              4000:"订单支付失败",
                              5000:"重复请求",
                              6001:"取消支付",
                              6002:"网络连接出错",
                                                6004:"支付结果未知",
                                            }
                                        api.alert({
                                            title: '支付结果',
                                            msg: pay_result[ret.code],
                                            buttons: ['确定']
                                        });
                                            // 通知服务端, 修改充值结果
                                            this.return_recharge(response.data.result.order_number,token);
                                    });
                                }else{
                                        this.game.print(response.data);
                                }
                            }).catch(error=>{
                                // 网络等异常
                                this.game.print(error);
                            });
                        })
                    },
                    return_recharge(out_trade_number,token){
                        this.axios.post("",{
                            "jsonrpc": "2.0",
                            "id": this.uuid(),
                            "method": "Recharge.return",
                            "params": {
                                "out_trade_number": out_trade_number,
                            }
                        },{
                            headers:{
                                Authorization: "jwt " + token,
                            }
                        }).then(response=>{
                            if(parseInt(response.data.result.errno)==1000){
                                this.money = response.data.result.money.toFixed(2);
                            }
                        })
                    },
            checkout(){
              var token = this.game.get("access_token") || this.game.fget("access_token");
              this.game.checkout(this,token,(new_access_token)=>{
                this.connect();
              });
            },
            connect(){
              // socket连接
              this.socket = io.connect(this.settings.socket_server + this.namespace, {transports: ['websocket']});
              this.socket.on('connect', ()=>{
                  this.game.print("开始连接服务端");
                                var id = this.game.fget("id");
                                this.socket.emit("login",{"uid":id});
              });
            },
            go_index(){
              this.game.goWin("root");
            },
            go_friends(){
              this.game.goFrame("friends","friends.html",this.current);
              this.game.goFrame("friend_list","friend_list.html",this.current,{
                  x: 0,
                  y: 190,
                  w: 'auto',
                  h: 'auto',
              },null,true);
            },
            go_home(){
              this.game.goWin("user","user.html", this.current);
            },
                    go_orchard_shop(){
                        // 种植园商店
                        this.game.goFrame("orchard_shop","shop.html", this.current,null,{
                  type:"push",
                  subType:"from_top",
                  duration:300
              });
                    },
                    go_my_package(){
                        // 我的背包
                        this.game.goFrame("package","package.html", this.current,null,{
                  type:"push",
                  subType:"from_top",
                  duration:300
              });
                    },
                    buy_prop(){
                        api.addEventListener({
                                name: 'buy_prop'
                        }, (ret, err)=>{
                                if( ret ){
                                    // 用户购买道具
                                    this.socket.emit("user_buy_prop",ret.value);
                                }
                        });
                    },
                }
            });
        }
        </script>
    </body>
    </html>
    orchard.html监听shop.html页面buy_prop方法

    3.服务端socket监听购买道具事件

    服务端socket监听购买道具事件, orchard/socket.py, 代码:

    from application import socketio
    from flask import request
    from application.apps.users.models import User
    from flask_socketio import join_room, leave_room
    from application import mongo
    from .models import Goods
    from status import APIStatus as status
    from message import ErrorMessage as errmsg
    
    
    # 断开socket通信
    @socketio.on("disconnect", namespace="/mofang")
    def user_disconnect():
        print("用户%s退出了种植园" % request.sid )
    
    @socketio.on("login", namespace="/mofang")
    def user_login(data):
        # 分配房间
        room = data["uid"]
        join_room(room)
        # 保存当前用户和sid的绑定关系
        # 判断当前用户是否在mongo中有记录
        query = {
            "_id": data["uid"]
        }
        ret = mongo.db.user_info_list.find_one(query)
        if ret:
            mongo.db.user_info_list.update_one(query,{"$set":{"sid": request.sid}})
        else:
            mongo.db.user_info_list.insert_one({
            "_id": data["uid"],
            "sid": request.sid,
        })
        socketio.emit("login_response", {"errno":status.CODE_OK,"errmsg":errmsg.ok}, namespace="/mofang", room=room)
    

    @socketio.on(
    "user_buy_prop", namespace="/mofang") def user_buy_prop(data): """用户购买道具""" room = request.sid # 从mongo中获取当前用户信息 # 1.获取当前sid对应的mongo存储的字典:包括_id,sid,prop_list user_info = mongo.db.user_info_list.find_one({"sid":request.sid}) # 2.根据mongo存储的字典get取键获取当前用户id user = User.query.get(user_info.get("_id")) # 3.判断当前用户是否存在 if user is None: socketio.emit("user_buy_prop_response", {"errno":status.CODE_NO_USER,"errmsg":errmsg.user_not_exists}, namespace="/mofang", room=room) return # 从mysql中获取商品价格 # 4.通过商品id查询出当前商品model对象 prop = Goods.query.get(data["pid"]) # 5.判断用户余额是否充足 if float(user.money) < float(prop.price) * int(data["num"]): socketio.emit("user_buy_prop_response", {"errno":status.CODE_NO_MONEY,"errmsg":errmsg.money_no_enough}, namespace="/mofang", room=room) return # 从mongo中获取用户列表信息,提取购买的商品数量进行累加和余额 query = {"sid": request.sid} if user_info.get("prop_list") is None: # 别忘了,user_info是mongo字典 """此前没有购买任何道具""" message = {"$set":{"prop_list":{"prop_%s" % prop.id:int(data["num"])}}} mongo.db.user_info_list.update_one(query,message) else: """此前有购买了道具""" prop_list = user_info.get("prop_list") # 道具列表 if ("prop_%s" % prop.id) in prop_list: """如果再次同一款道具""" prop_list[("prop_%s" % prop.id)] = prop_list[("prop_%s" % prop.id)] + int(data["num"]) else: """此前没有购买过这种道具""" prop_list[("prop_%s" % prop.id)] = int(data["num"]) mongo.db.user_info_list.update_one(query, {"$set":{"prop_list":prop_list}}) socketio.emit("user_buy_prop_response", {"errno":status.CODE_OK,"errmsg":errmsg.ok}, namespace="/mofang", room=room)

    4.种植园道具购买流程图

  • 相关阅读:
    游吟诗人阿严
    学霸女
    sql group by 分组后查询最新的一条数据
    腐朽
    我喜欢不说话的山川
    redis启动
    php 时间轴,数据统计(最近7天的数据)
    php options 请求跨域
    mac关机声音
    JVM-内存模型
  • 原文地址:https://www.cnblogs.com/libolun/p/14213537.html
Copyright © 2011-2022 走看看