目录
社交模块
邀请好友 - 推广应用
主要就是为了实现推广流程。
业务逻辑流程图
客户端提供邀请好友的展示页面
- 用户个人中心
user.html
, 实现点击"邀请好友"打开邀请好友invite.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/uuid.js"></script>
<script src="../static/js/v-avatar-2.0.3.min.js"></script>
<script src="../static/js/main.js"></script>
</head>
<body>
<div class="app user" id="app">
<div class="bg">
<img src="../static/images/bg0.jpg">
</div>
<img class="back" @click="back" src="../static/images/user_back.png" alt="">
<img class="setting" @click="goto_settings" 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="user_data.avatar" alt=""> -->
<div class="user_avatar">
<v-avatar v-if="user_data.avatar" :src="user_data.avatar" :size="56" :rounded="true"></v-avatar>
<v-avatar v-else-if="user_data.nickname" :username="user_data.nickname" :size="56" :rounded="true"></v-avatar>
<v-avatar v-else :username="user_data.id" :size="56" :rounded="true"></v-avatar>
</div>
<img class="avatar_border" src="../static/images/avatar_border.png" alt="">
</div>
<p class="user_name">{{user_data.nickname}}</p>
</div>
<div class="wallet">
<div class="balance">
<p class="title"><img src="../static/images/money.png" alt="">钱包</p>
<p class="num">{{game.money_format(user_data.money)}}</p>
</div>
<div class="balance">
<p class="title"><img src="../static/images/integral.png" alt="">果子</p>
<p class="num">{{game.money_format(user_data.credit)}}</p>
<!-- <p class="num">99,999.00</p> -->
<!-- <p class="num">1,999,999.00</p> -->
</div>
</div>
<div class="invite" @click="open_invite_page">
<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" @click="open_friend_list">
<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>
<div class="item">
<span class="title">问题反馈</span>
<span class="value">去反馈</span>
</div>
</ul>
</div>
</div>
<script>
apiready = function(){
var game = new Game("../static/mp3/bg1.mp3");
Vue.prototype.game = game;
new Vue({
el:"#app",
data(){
return {
user_data: {},
}
},
created(){
let token = this.game.getfs("access_token") || this.game.getdata("access_token");
this.user_data = this.game.get_user_by_token(token);
this.game.print(this.user_data);
this.listen();
},
methods:{
listen(){
// 监听头像发生变化的通知
this.listen_update_avatar();
// 监听昵称发生变化的通知
this.listen_update_nickname();
},
listen_update_avatar(){
// 监听头像更新的通知
api.addEventListener({
name: 'update_avatar_success',
}, (ret, err)=>{
this.get_user_data();
});
},
listen_update_nickname(){
//监听昵称更新的通知
api.addEventListener({
name: 'update_nickname_success'
}, (ret, err)=>{
this.get_user_data();
});
},
get_user_data(){
let token = this.game.getfs("access_token") || this.game.getdata("access_token");
this.user_data = this.game.get_user_by_token(token);
this.game.print(this.user_data);
},
back(){
// 返回首页
this.game.closeWin();
},
goto_settings(){
// 打开配置页面
this.game.openFrame("settings","settings.html");
},
open_friend_list(){
// 打开好友列表
this.game.openFrame("friends","friends.html");
this.game.openFrame("friend_list","friend_list.html",null,{
x: 0, // 左上角x轴坐标
y: 194, // 左上角y轴坐标
w: 'auto', // 当前帧页面的宽度, auto表示满屏
h: 'auto' // 当前帧页面的高度, auto表示满屏
});
},
open_invite_page(){
// 邀请好友页面
this.game.openFrame("invite","invite.html",null,null,{
type: "push", //动画类型(详见动画类型常量)
subType: "from_top", //动画子类型(详见动画子类型常量)
duration: 300 //动画过渡时间,默认300毫秒
});
}
}
});
}
</script>
</body>
</html>
- 邀请好友页面
html/invite.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/uuid.js"></script>
<script src="../static/js/main.js"></script>
</head>
<body>
<div class="app frame avatar" id="app">
<div class="box">
<p class="title">邀请好友</p>
<img class="close" @click="back" src="../static/images/close_btn1.png" alt="">
<div class="content">
<img class="invite_code" src="../static/images/code.jpg" alt="">
</div>
<p class="invite_tips">长按保存图片到相册</p>
</div>
</div>
<script>
apiready = function(){
var game = new Game("../static/mp3/bg1.mp3");
// 在 #app 标签下渲染一个按钮组件
Vue.prototype.game = game;
new Vue({
el:"#app",
data(){
return {
}
},
methods:{
back(){
this.game.closeFrame();
},
}
});
}
</script>
</body>
</html>
- 添加代码样式:
static/css/main.css
,代码:
.invite_code{
14rem;
height: 14rem;
position: absolute;
left: 7rem;
top: 11rem;
}
.invite_tips{
position: absolute;
left: 7rem;
top: 26.4rem;
text-align: center;
color: #fff;
font-size: 1.5rem;
}
代码逻辑编写
服务端提供基于二维码生成邀请码的接口
flask-qrcode, 文档: https://marcoagner.github.io/Flask-QRcode/
- 安装二维码生成模块
pip install flask-qrcode
- 项目入口文件初始化模块 ,
application/__init__.py
,代码:
import os
from flask import Flask
from flask_script import Manager
from flask_sqlalchemy import SQLAlchemy
from flask_redis import FlaskRedis
from flask_session import Session
from flask_jsonrpc import JSONRPC
from faker import Faker
from celery import Celery
from flask_jwt_extended import JWTManager
from flask_admin import Admin
from flask_babelex import Babel
from xpinyin import Pinyin
from flask_qrcode import QRcode
from application.utils.config import init_config
from application.utils.logger import Log
from application.utils.commands import load_commands
from application.utils.bluerprint import register_blueprint, path, include, api_rpc
from application.utils import message, code
from application.utils.unittest import BasicTestCase
from application.utils.OssStore import OssStore
# 终端脚本工具初始化
manager = Manager()
# SQLAlchemy初始化
db = SQLAlchemy()
# redis数据库初始化
# - 1.默认缓存数据库对象,配置前缀为REDIS
redis_cache = FlaskRedis(config_prefix='REDIS')
# - 2.验证相关数据库对象,配置前缀为CHECK
redis_check = FlaskRedis(config_prefix='CHECK')
# - 3.验证相关数据库对象,配置前缀为SESSION
redis_session = FlaskRedis(config_prefix='SESSION')
# session储存配置初始化
session_store = Session()
# 自定义日志初始化
logger = Log()
# 初始化jsonrpc模块
jsonrpc = JSONRPC()
# 初始化随机生成数据模块faker
faker = Faker(locale='zh-CN') # 指定中文
# 初始化异步celery
celery = Celery()
# jwt认证模块初始化
jwt = JWTManager()
# 阿里云对象存储oss初始化
oss = OssStore()
# admin后台站点初始化
admin = Admin()
# 国际化和本地化的初始化
babel = Babel()
# 文字转拼音初始化
pinyin = Pinyin()
# 二维码生成模块初始化
qrcode = QRcode()
# 全局初始化
def init_app(config_path):
"""全局初始化 - 需要传入加载开发或生产环境配置路径"""
# 创建app应用对象
app = Flask(__name__)
# 当前项目根目录
app.BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# 开发或生产环境加载配置
init_config(app, config_path)
# SQLAlchemy加载配置
db.init_app(app)
# redis加载配置
redis_cache.init_app(app)
redis_check.init_app(app)
redis_session.init_app(app)
"""一定先加载默认配置,再传入APP加载session对象"""
# session保存数据到redis时启用的链接对象
app.config["SESSION_REDIS"] = redis_session
# session存储对象加载配置
session_store.init_app(app)
# 为日志对象加载配置
log = logger.init_app(app)
app.log = log
# json-rpc加载配置
jsonrpc.init_app(app)
# rpc访问路径入口(只有唯一一个访问路径入口),默认/api
jsonrpc.service_url = app.config.get('JSON_SERVER_URL', '/api')
jsonrpc.enable_web_browsable_api = app.config.get("ENABLE_WEB_BROWSABLE_API",False)
app.jsonrpc = jsonrpc
# 自动注册蓝图
register_blueprint(app)
# 加载celery配置
celery.main = app.name
celery.app = app
# 更新配置
celery.conf.update(app.config)
# 自动注册任务
celery.autodiscover_tasks(app.config.get('INSTALL_BLUEPRINT'))
# jwt认证加载配置
jwt.init_app(app)
# faker作为app成员属性
app.faker = faker
# 注册模型,创建表
with app.app_context():
db.create_all()
# 阿里云存储对象加载配置
oss.init_app(app)
# admin后台站点加载配置
admin.name = app.config.get('FLASK_ADMIN_NAME') # 站点名称
admin.template_mode = app.config.get('FLASK_TEMPLATE_MODE') # 使用的模板
admin.init_app(app)
# 国际化和本地化加载配置
babel.init_app(app)
# 二维码模块加载配置
qrcode.init_app(app)
# 终端脚本工具加载配置
manager.app = app
# 自动注册自定义命令
load_commands(manager)
return manager
- 视图提供生成二维码图片 :
users/views.py
,代码:
from flask_jwt_extended import jwt_required
from flask import make_response, current_app, request
from application import qrcode
# 引入装饰器
from application.utils import decorator
# 基于二维码模块生成邀请码
@jwt_required()
@decorator.get_user_object
def invite_code(user):
'''
基于二维码模块生成邀请码
:param user: 装饰器通过token获取的用户模型对象
:return:
'''
# 获取用户头像,如果没有设置头像,则默认为项目配置中的默认头像
if user.avatar:
avatar = user.avatar
else:
avatar = current_app.config.get('DEFAULT_INVITE_LOGO')
# 服务端访问地址,从配置文件中提取
# 判断是否为开发环境
if current_app.config.get('DEBUG'):
SERVER_URL = 'DEV_SERVER_URL'
else:
SERVER_URL = 'SERVER_URL'
# 获取服务端访问地址,如果没有就用请求地址
# print(request.host_url[:-1]) # http://0.0.0.0:5000
server_url = current_app.config.get(SERVER_URL, request.host_url[:-1])
# 编写邀请码中携带的地址
invite_url = server_url + '/users/invite?type=invite&uid=%s'%user.id
# 生成二维码图片数据
# qrcode基于mode=raw生成的图片数据格式是 BytesIO, flask返回图片需要bytes类型数据
# 所以需要把BytesIO通过getvalue方法转成bytes
image = qrcode.qrcode(invite_url, mode='raw', box_size=16, icon_img=avatar)
image = image.getvalue()
response = make_response(image)
# 设置响应头类型
response.headers['Content-Type'] = 'image/png'
return response
- 开发环境配置文件
application/settings/dev.py
,配置代码:
"""邀请二维码"""
# 默认LOGO
DEFAULT_INVITE_LOGO = "https://mofang32.oss-cn-beijing.aliyuncs.com/680cda4f-2868-4abf-95b0-6eb5240bfd39.jpeg"
# 服务端的访问地址
SERVER_URL = "http://www.mofang.com:5000"
DEV_SERVER_URL = "http://192.168.19.46:5000" # 开发环境使用主机IP地址
- 路由:
user/urls.py
,代码:
from application import path, api_rpc
# 引入当前蓝图应用视图 , 引入rpc视图
from . import views, api
# 蓝图路径与函数映射列表
urlpatterns = [
path('invite.png', views.invite_code), # 生成邀请码,推广应用
]
# rpc方法与函数映射列表[rpc接口列表]
apipatterns = [
api_rpc('check_mobile', api.check_mobile),
api_rpc('register', api.register),
api_rpc('login', api.login),
api_rpc('refresh', api.refresh_token), # 刷新access_token值
api_rpc('update_avatar', api.update_avatar), # 更新头像
api_rpc('update_nickname', api.update_nickname), # 更新昵称
api_rpc('update_mobile', api.update_mobile), # 更新手机号
api_rpc('update_password', api.update_password), # 更新登录密码
api_rpc('update_pay_password', api.update_pay_password), # 更新交易密码
api_rpc('get_apply_friend_history', api.get_apply_friend_history), # 获取好友申请列表
api_rpc('search_user_info', api.search_user_info), # 搜索用户信息
api_rpc('apply_friend', api.apply_friend), # 添加用户好友申请记录
api_rpc('add_friend', api.add_friend), # 添加用户好友关系记录
api_rpc('cancel_apply_friend', api.cancel_apply_friend), # 用户取消自己申请的好友记录
api_rpc('get_friend_list', api.get_friend_list), # 获取好友列表
]
- 获取好友邀请码访问地址:
http://0.0.0.0:5000/users/invite.png?jwt=(access_token值)
客户端获取好友邀请码
- 获取好友邀请码, 并且长按保存图片到相册中 ,
html/invite.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/uuid.js"></script>
<script src="../static/js/main.js"></script>
</head>
<body>
<div class="app frame avatar" id="app">
<div class="box">
<p class="title">邀请好友</p>
<img class="close" @click="back" src="../static/images/close_btn1.png" alt="">
<div class="content">
<img class="invite_code" :src="invite_code" alt="">
</div>
<p class="invite_tips">长按保存图片到相册</p>
</div>
</div>
<script>
apiready = function(){
var game = new Game("../static/mp3/bg1.mp3");
// 在 #app 标签下渲染一个按钮组件
Vue.prototype.game = game;
new Vue({
el:"#app",
data(){
return {
invite_code: '', // 好友邀请码图片地址
}
},
created(){
this.get_invite_code(); // 获取好友邀请码地址
this.listen(); // 监听事件
},
methods:{
// 监听事件
listen(){
// 监听长按事件
this.listen_long_press();
},
// 监听长按邀请码事件
listen_long_press(){
api.addEventListener({
name: 'longpress' // 监听系统长按页面事件
}, (ret, err)=>{
// 保存图片或视频到本地相册
api.saveMediaToAlbum({
path: this.invite_code
}, (ret, err)=>{
if (ret && ret.status) {
this.game.tips('保存二维码成功!')
} else {
this.game.tips('保存二维码失败!')
}
});
});
},
back(){
this.game.closeFrame();
},
// 获取好友邀请码地址
get_invite_code(){
let self = this
self.game.check_user_login(self, () => {
let token = self.game.getdata('access_token') || self.game.getfs('access_token')
// 拼接好友邀请码地址
self.invite_code = self.game.config.HTTP_SERVER + 'users/invite.png?jwt=' + token
})
},
}
});
}
</script>
</body>
</html>
- 在
static/js/main.js
中新增HTTP_SERVER(网关地址)配置项,代码:
// 初始化配置
init_config(){
// 客户端项目的全局配置
this.config = {
// 服务端API地址
// API_SERVER:"http://192.168.189.138:5000/api",
API_SERVER:"http://192.168.19.46:5000/api",
// http服务端网关地址
HTTP_SERVER: 'http://192.168.19.46:5000/',
SMS_TIME_OUT: 60 , // 短信发送冷却时间/秒
CAPTCHA_APP_ID: "2028945858", // 防水墙验证码应用ID
}
}
扫描识别邀请码,下载应用软件
服务端提供对应的接口允许访问
- 视图提供
users/views.py
:
from flask import make_response, current_app, request, render_template
# 根据二维码识别进入的唤醒/下载APP视图
def invite():
'''根据二维码识别进入的唤醒/下载APP视图'''
# 提取二维码中隐藏链接的参数信息
uid = request.args.get('uid') # 用户ID
user_type = request.args.get('type') # 用途来源
# 识别用户信息
user = services.get_user_by_id(id = uid)
# todo 用户邀请好友的奖励方法,将来方便进行奖励处理
# services.apply_user(user)
# 识别用户当前使用的访问代理(使用什么软件扫描的二维码)
user_agent = request.headers.get('User-Agent').lower()
if 'micromessenger' in user_agent:
client_agent = 'weixin' # 使用微信扫描的
elif 'alipayclient' in user_agent:
client_agent = 'alipay' # 使用支付宝扫描的
else:
client_agent = 'others' # 使用其他软件扫描的
# 判断用途来源
if user_type == 'invite':
'''邀请好友的'''
data = {
'uid': uid,
'user_tpye': user_type,
'client_agent': client_agent
}
# 返回模板界面
return render_template('users/invite.html', **data)
return 'hello world !'
- 模板目录下创建对应的html模板文件,
application/templates/users/invite.html
, 代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta >
<title>Title</title>
<style>
body{
background-color: #000;
}
img{
100%;
}
a{
color: #fff;
}
</style>
</head>
<body>
{% if client_agent == "weixin" %}
<img src="/static/openbrowser.png" alt="">
{% else %}
<div id="content"></div>
<script>
// 尝试通过打开客户端已经安装的魔方APP
var iframe = document.createElement("iframe");
iframe.src = "mofang://?uid={{ uid }}&user_type={{user_type}}"; // app的私有协议,在用户已经安装了app以后,可以自动唤醒APP
iframe.hidden=true; // iframe.style.display="none";
document.body.appendChild(iframe);
// 如果等待了3秒以后,还没有切换APP
setTimeout(function() {
if (!document.hidden) {
// 在3秒内如果页面出去了。说明这个时候document.hidden是true,这段代码就不执行了。
// 就算是再切回来也是不执行的。
// 如果你进了这个函数,没离开。。那就会在3秒后跳进这里
alert('你还没安装魔方APP,赶紧下载吧,你的好友朋友都在等哦~');
// 自动下载
var iframe = document.createElement("iframe");
iframe.src = "/static/app/mofang.apk"; // app所在的下载地址
iframe.hidden=true;
document.body.appendChild(iframe);
// 让用户自己手动点击下载链接
u = navigator.userAgent;
let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端
let isiOS = !!u.match(/(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
var content = document.querySelector("#content");
if (isiOS) {
// 去下载ios版本的魔方APP
content.innerHTML = `<a href="/static/app/mofang.ipa">点击链接下载魔方APP</a>`;
}
if (isAndroid){
// 去下载安卓版本的魔方APP
content.innerHTML = `<a href="/static/app/mofang.apk">点击链接下载魔方APP</a>`;
}
}
}, 3000);
</script>
{% endif %}
</body>
</html>
(1) 把素材中的openbrowser.png
图片放到静态文件中application/static/image
(2) 把客户端编译过的APP下载包, 放置到静态文件 application/static/app
中, 方便视图调用下载
- 注册视图路由: ,
users.urls
,代码:
from application import path, api_rpc
# 引入当前蓝图应用视图 , 引入rpc视图
from . import views, api
# 蓝图路径与函数映射列表
urlpatterns = [
path('invite.png', views.invite_code), # 生成邀请码,推广应用
path('invite', views.invite), # 唤醒或下载APP软件
]
# rpc方法与函数映射列表[rpc接口列表]
apipatterns = [
api_rpc('check_mobile', api.check_mobile),
api_rpc('register', api.register),
api_rpc('login', api.login),
api_rpc('refresh', api.refresh_token), # 刷新access_token值
api_rpc('update_avatar', api.update_avatar), # 更新头像
api_rpc('update_nickname', api.update_nickname), # 更新昵称
api_rpc('update_mobile', api.update_mobile), # 更新手机号
api_rpc('update_password', api.update_password), # 更新登录密码
api_rpc('update_pay_password', api.update_pay_password), # 更新交易密码
api_rpc('get_apply_friend_history', api.get_apply_friend_history), # 获取好友申请列表
api_rpc('search_user_info', api.search_user_info), # 搜索用户信息
api_rpc('apply_friend', api.apply_friend), # 添加用户好友申请记录
api_rpc('add_friend', api.add_friend), # 添加用户好友关系记录
api_rpc('cancel_apply_friend', api.cancel_apply_friend), # 用户取消自己申请的好友记录
api_rpc('get_friend_list', api.get_friend_list), # 获取好友列表
]
客户端
App配置私有协议, 允许第三方应用通过私有协议唤醒魔方APP
- 在
config.xml
中配置添加<preference name="urlScheme" value="mofang" />
<widget id="A6177994729952" version="0.0.1">
<name>mofangapp</name>
<description>
Example For APICloud.
</description>
<author email="developer@apicloud.com" href="http://www.apicloud.com">
Developer
</author>
<content src="html/index.html" />
<access origin="*" />
<preference name="pageBounce" value="false"/>
<preference name="appBackground" value="rgba(0,0,0,0.0)"/>
<preference name="windowBackground" value="rgba(0,0,0,0.0)"/>
<preference name="frameBackgroundColor" value="rgba(0,0,0,0.0)"/>
<preference name="hScrollBarEnabled" value="false"/>
<preference name="vScrollBarEnabled" value="false"/>
<preference name="autoLaunch" value="true"/>
<preference name="fullScreen" value="false"/>
<preference name="autoUpdate" value="true" />
<preference name="smartUpdate" value="false" />
<preference name="debug" value="true"/>
<preference name="statusBarAppearance" value="true"/>
<!-- 配置app私有协议, 可通过协议唤醒魔方APP软件 -->
<preference name="urlScheme" value="mofang" />
<permission name="readPhoneState" />
<permission name="camera" />
<permission name="record" />
<permission name="location" />
<permission name="fileSystem" />
<permission name="internet" />
<permission name="bootCompleted" />
<permission name="hardware" />
</widget>
- APP默认首页
index.html
中监听是否来自第三方应用的唤醒.并接收唤醒时附带的参数信息.
html/index.html
,代码:
<!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/uuid.js"></script>
<script src="../static/js/main.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" src="../static/images/image1.png"></li>
<li><img class="module2" src="../static/images/image2.png" @click='to_user'></li>
<li><img class="module3" src="../static/images/image3.png"></li>
<li><img class="module4" src="../static/images/image4.png" @click='to_login'></li>
</ul>
</div>
<script>
apiready = function(){
var game = new Game("../static/mp3/bg1.mp3");
Vue.prototype.game = game;
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.listen(); // 监听事件
},
methods:{
// 监听事件
listen(){
// 监听外部访问,唤醒app
this.listen_invite();
},
// 监听外部访问,唤醒app
listen_invite(){
// 使用系统方法appintenr监听并使用appParam接收URLScheme的路由参数
// 收集操作保存起来,并跳转到登陆页面.
api.addEventListener({
name: 'appintent' // 系统方法
}, (ret, err)=>{
// 获取路由参数,保存到本地
let appParam = ret.appParam;
// this.game.print(appParam,1); //{"uid":xxx,"user_type":xxx};
this.game.setfs(appParam)
// 如果是其他用户邀请注册!
if(appParam.user_type == 'invite'){
// 跳转到登陆页面
this.game.openWin('login', 'login.html')
}
});
},
// 点击签到跳转登陆页面
to_login(){
this.game.openWin('login','login.html')
},
// 点击跳转到个人中心页面
to_user(){
// 判断用户是否登陆
this.game.check_user_login(this,() => {
this.game.openWin('user', 'user.html')
});
},
}
})
}
</script>
</body>
</html>
编译生成apk安装包
接下来的开发,我们不能再依赖官方提供的AppLoader进行功能测试了,所以我们使用由APICloud编辑器提供的本地编译, 编译自定义APPLoader来进行测试。
- 编译APP,则是生成一个独立的APP,无法进行终端调试,后续如果客户端代码更新,需要重新生成APP。
- 编译自定义APPLoader,则是生成一个新的调试加载器工具,可以进行终端调试,可以配置网络参数。