种植园

一、我的背包

打开背包,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" @click='go_friends'>好友</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=>{// this.game.print(response.data);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>

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: "", // 当前登陆用户Idprev:{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>

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

种植园的参数信息:

商店的商品:1. 种子果树标题价格描述图片使用流程相关状态: 种子期, 成长期, 成熟期, 树桩种子期: 3  x 60 x 60成长期: 6  x 60 x 60成熟期: 12 x 60 x 60树桩 :  -12. 宠物小狗1,小狗2,小狗3,小狗4标题价格描述图片使用流程相关:饱食度: <20%(饥饿) <50%(正常) <100%(饱腹)生命期: -1(永久)保护命中率  : 10%   0-1   <10%3. 狗粮狗粮1,狗粮2,狗粮3标题价格描述图片使用流程相关:饱食度: 20%有效期: 4. 道具化肥,....标题价格描述图片使用流程相关:缩短时间: 1小时

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

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

修改商店中商品购买的货币信息, 模型代码:
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="商品图片")

数据迁移, 终端执行:

python manage.py db migrate -m "add goods column"
python manage.py db upgrade

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

...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);}}
...

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

...go_index(){this.game.goWin("root");},
...

修改main.js代码:

...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 获取});}
...

二、道具购买

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: "", // 当前登陆用户Idgoods_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>

在种植园主页面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/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" @click='go_friends'>好友</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=>{// this.game.print(response.data);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>

服务端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('connect', namespace='/mofang')
# def user_connect():
#     """用户连接"""
#     print('用户%s连接过来了!' % request.sid)
#     # 主动响应数据给客户端
#     socketio.emit('server_response', 'hello', namespace='/mofang')# 断开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中获取当前用户信息user_info = mongo.db.user_info_list.find_one({'sid': request.sid})user = User.query.get(user_info.get('_id'))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中获取商品价格prop = Goods.query.get(data['pid'])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:"""此前没有购买任何道具"""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)

status.py,代码:

    CODE_NO_MONEY = 1014  # 余额不足

message.py,代码:

    money_no_enough = "余额不足!"

魔坊APP项目-19-种植园,我的背包、道具购买相关推荐

  1. 魔坊APP项目-20-种植园,背包显示道具、用户购买道具的时候,判断背包存储是否达到上限、背包解锁

    种植园 一.背包显示道具 在背包中显示道具,会涉及到用户的背包格子的显示以及解锁问题,所以我们需要在服务端准备一个参数信息, 用于保存种植园中用户的业务参数,例如: 格子的初始化数量, 每次解锁背包格 ...

  2. 魔坊APP项目-22-种植园,种植栏的功能实现,客户端根据激活状态和未激活状态分别显示树桩、服务端提供种植植物的相关数据、解锁树桩、植物相关道具使用

    种植园 一.种植栏的功能实现 1. 客户端需要的植物相关参数: 总树桩数量, 当前用户激活树桩数量, 当前种植的树桩数量, 树桩列表状态 2. 客户端根据激活状态和未激活状态分别显示树桩 3. 服务端 ...

  3. 魔坊APP项目-23-种植园,宠物和种植物的状态改变、宠物的状态改动

    种植园 宠物和种植物的状态改变 1. 宠物的状态改动 2. 种植物的状态改动 3. 道具的使用 宠物的状态改动 因为宠物有多个,每个宠物会有不同的初始生命的饥饿时间,所以我们提前在mysql中进行配置 ...

  4. 魔坊APP项目-25-种植园,植物的状态改动、当果树种植以后在celery的异步任务中调整浇水的状态、客户端通过倒计时判断时间,显示浇水道具

    种植园 植物的状态改动 一.当果树种植以后在celery的异步任务中调整浇水的状态 在进行果树种植的时候, 在服务端设置当前果树到等待浇水的redis变量中.通过celery不断进行周期任务的处理, ...

  5. 魔坊APP项目-21-种植园,宠物栏的功能实现、服务端提供显示宠物的api接口、客户端中展示宠物栏和宠物列表以及饱食度、宠物道具的使用

    种植园 一.宠物栏的功能实现 1. 宠物的显示 2. 宠物的使用 3. 宠物的饱食度 4. 宠物的开锁 1.服务端提供显示宠物的api接口 socket.py,代码 ... import math f ...

  6. 魔坊APP项目-16-种植园、websocket协议、服务端基于socket提供服务(基于房间管理分发信息)、种植园页面展示

    种植园 我们需要完成的种植园,是一个互动频繁,并且要求有一定即时性的模块,所以如果继续基于http协议开发,那么需要通过ajax发送大量http请求,同时因为http本身属于单向通讯,所以服务端无法主 ...

  7. 魔坊APP项目-17-种植园,商城页面、服务端提供商品api,解决App打包编译以后的跨域限制、客户端获取商品列表并进行展示,集成Alipayplus模块完成支付

    种植园 一.商城页面 orchard.html,代码: <!DOCTYPE html> <html> <head><title>用户中心</tit ...

  8. 魔坊APP项目-18-种植园,基于支付宝提供的沙箱测试环境开发支付接口、服务端, 处理支付结果的同步通知和异步通知、修复页面底部菜单无法被点击的BUG

    种植园 一.基于支付宝提供的沙箱测试环境开发支付接口 沙箱环境: https://openhome.alipay.com/platform/appDaily.htm?tab=info 开发文档: ht ...

  9. 魔坊APP项目-24-种植园,修复宠物喂食时出现的饱食度没有增加的bug、宠物挂了的bug问题

    种植园 修复宠物喂食时出现的饱食度没有增加的bug 在feed方法中监听是否喂食成功的pet_feed_success通知中, 保存更新后的hp_time. my_orchard.html代码: &l ...

最新文章

  1. poj-1384 Piggy-Bank
  2. sql server 2008 r2 没有维护计划_坚果R2发布,骁龙865+1亿像素+90Hz,4499元起
  3. Android --- 夜神模拟器中没有图片怎么办?夜神模拟器中怎么导入图片?
  4. 逻辑漏洞——验证机制问题
  5. ConcurrentHashMap--自用,非教学
  6. 服务器被黑 追寻ip_我的服务器被打死,源IP暴露怎么办补救
  7. python读取txt文件存储数组_python : 将txt文件中的数据读为numpy数组或列表
  8. 数据库字段与属性的关系是什么?
  9. qml 定义函数_QML类型系统
  10. LVDS屏的俩种接口:JEIDAVESA
  11. 如何更好的理解用户反馈? | 上
  12. oracle学习资料大全
  13. 第一篇:手把手教你移植任天堂,没有声音、无需外置SD卡、可使用独立按键也可使用外置手柄,本人使用的芯片为ESP32,移植到STM32均可使用。(本篇主要介绍nes_main.h这个文件)
  14. c++基础(上) 听课流水账
  15. 递归(recurse)与迭代(iteration)
  16. Win10 卸载了某软件,右键还有该软件,如何删除呢?
  17. 如何做一个炫酷的墨水屏电子钟?
  18. 电力电子相关论文英文单词积累
  19. WinRAR 压缩文件的时候排除指定的目录文件夹
  20. 在Docker安装Calibre-web搭建网上书城

热门文章

  1. Linux 7 (RedHatCentOS)静默安装 Oracle11.2.0.4
  2. php base64数据与图片的转换
  3. jvm优化_Java中JVM,JIR,JRE和JDK之间的区别
  4. 多个USB转串口设备区分方法
  5. 什么是营销漏斗模型?如何创建一个营销漏斗策略
  6. Ubuntu系统---安装“搜狗拼音法”导致桌面打不开
  7. popen和system函数的区别 以及 popen打开的FILE指针能否用close替代fclose关闭
  8. gis可达性分析步骤_消息速递 | 学院2017级城市管理本科班GIS课程作业成果汇报顺利进行...
  9. Html未加载完成时实现动态加载效果
  10. Peak prominences(峰日珥)