10. 社交模塊 - 好友邀請,推廣應用


社交模塊

邀請好友 - 推廣應用

主要就是為了實現推廣流程。

業務邏輯流程圖

客戶端提供邀請好友的展示頁面

  1. 用戶個人中心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>
  1. 邀請好友頁面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>

  1. 添加代碼樣式: static/css/main.css,代碼:
.invite_code{
  width: 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/

  1. 安裝二維碼生成模塊
pip install flask-qrcode
  1. 項目入口文件初始化模塊 ,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
  1. 視圖提供生成二維碼圖片 : 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
  1. 開發環境配置文件 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地址
  1. 路由: 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), # 獲取好友列表
]

  1. 獲取好友邀請碼訪問地址:
http://0.0.0.0:5000/users/invite.png?jwt=(access_token值)

客戶端獲取好友邀請碼

  1. 獲取好友邀請碼, 並且長按保存圖片到相冊中 ,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>


  1. 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
		}
	}

掃描識別邀請碼,下載應用軟件

服務端提供對應的接口允許訪問

  1. 視圖提供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 !'

  1. 模板目錄下創建對應的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{
        width: 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 中, 方便視圖調用下載

  1. 注冊視圖路由: ,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

  1. 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>


  1. 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來進行測試。

  1. 編譯APP,則是生成一個獨立的APP,無法進行終端調試,后續如果客戶端代碼更新,需要重新生成APP。
  2. 編譯自定義APPLoader,則是生成一個新的調試加載器工具,可以進行終端調試,可以配置網絡參數。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM