微信小程序云端增強(qiáng) SDK接入
【引自第九程序的博客】一、XpmJS 是啥
XpmJS可以鏈接任何云端資源,為小程序、移動應(yīng)用提供云資源通道和后端能力。降低開發(fā)門檻,提升小程序的開發(fā)效率。無需編寫后端代碼,即可實(shí)現(xiàn)用戶登錄、WebSocket 通信、微信支付、云端數(shù)據(jù)表格、文件存儲等功能。雖然 PHP 是最好的編程語言, 但是使用 XpmJS 后, 無需學(xué)習(xí)包括 PHP 在內(nèi)的任何后端語言,用 Javascript 即可搞定一切,NodeJS 也不用!
二、為啥 XpmJS
從代碼結(jié)構(gòu)上看 XpmJS 更優(yōu)雅!因?yàn)槭褂昧?Promise!
XpmJS 封裝了常用后端操作,還提供一個管理后臺,微信支付只要一行代碼就可以實(shí)現(xiàn)!
后端部署在你的云主機(jī)上!你可以完全掌控數(shù)據(jù)。
方法1: 一鍵安裝
推薦使用騰訊云一鍵安裝鏈接 ( 訪問微信接口快, 可以免費(fèi)申請 Https 證書 )
方法2: 安裝腳本
安裝前,先提前申請 Docker Hub 鏡像 申請地址 https://www.daocloud.io/mirror
- # 請采用 Ubuntu 14.04 64位 LTS
- curl -sSL http://tuanduimao.com/xpmjs-server.sh | sh -s yourdomain.com http://<your id>.m.daocloud.io
方法3: 使用 Docker 安裝
- # 安裝 Docker
- curl -sSL https://get.daocloud.io/docker | sh
- # 啟動容器
- docker run -d --name=xpmjs-server \
- -e "HOST=yourdomain.com" \
- -v /host/data:/data \
- -v /host/apps:/apps \
- -v /host/config:/config \
- -p 80:80 -p 443:443 \
- tuanduimao/xpmjs-server:1.0
XpmJS Server 升級
第一步: 下載代碼:
- curl http://xpmjs-1252011659.costj.myqcloud.com/xpmjs-server-1.0.tar.gz
第二步: 解壓并更新:
- tar xvfz xpmjs-server-1.0.tar.gz
- cd 1.0 && docker cp . xpmjs-server:/code
三、XpmJS 咋用
1. 用戶 ( User )
用戶登錄 login()
- var user = app.xpm.require('User');
- user.login().then( function( userInfo ) {
- console.log( '用戶登錄成功', userInfo );
- app.session.set('loginUser', userInfo );
- })
- .catch( function( excp ) {
- console.log('用戶登錄失敗', excp );
- });
用戶退出 logout()
- var user = app.xpm.require('User');
- user.logout().then( function( userInfo ) {
- console.log( '用戶注銷成功', userInfo );
- })
- .catch( function( excp ) {
- console.log('用戶注銷失敗', excp );
- });
讀取資料 get()
來自微信客戶端的用戶信息 ( 非云端數(shù)據(jù) )
- var user = app.xpm.require('User');
- user.get().then( function( userInfo ) {
- console.log( '讀取成功', userInfo );
- })
- .catch( function( excp ) {
- console.log('讀取失敗', excp );
- });
2. 信道( Wss )
使用 Websocket 信道,可以實(shí)現(xiàn)雙向?qū)崟r通信。
打開信道 open()
- var wss = app.xpm.require('Wss');
- wss.open('/wxapp').then(function( res ) {
- console.log( '信道連接成功', res );
- })
- .catch( function( excp ) {
- console.log('信道連接失敗', excp );
- });
在線用戶 liveUsers ()
- var wss = app.xpm.require('Wss');
- wss.liveUsers().then(function( users ) {
- console.log( '讀取在線用戶成功', users );
- })
- .catch( function( excp ) {
- console.log('讀取在線用戶失敗', excp );
- });
用戶信息數(shù)據(jù)結(jié)構(gòu)
字段 | 中文 | 說明 |
---|---|---|
id | 客戶端ID | |
_id | 用戶ID | |
nickName | 微信昵稱 | |
gender | 性別 | |
avatarUrl | 頭像 | |
language | 語言 | |
group | 用戶組 | |
isadmin | 是否是管理員 | 0 非管理員 1 管理員 |
檢查用戶是否在線 isOnline ( xpmjs-server 1.0rc4+ )
- var user = app.xpm.require('User');
- var wss = app.xpm.require('Wss');
- user.login().then( function( userInfo ) {
- return wss.isOnline( userInfo['_id'] )
- }).then function( isOnline ) {
- if ( isOnline ) {
- console.log( '用戶在線');
- } else {
- console.log( '用戶離線');
- }
- })
- .catch( function( excp ) {
- console.log('出錯啦', excp );
- });
監(jiān)聽指令 listen()
小程序僅提供 WebSocket 客戶端 API,所以小程序本身無法實(shí)現(xiàn) WebSocket服務(wù)器。 wss.listen() 方法并非啟動 WebSocket Server, 而是用來接收云端信道轉(zhuǎn)發(fā)的指令。
- var wss = app.xpm.require('Wss');
- wss.listen('payment', function( res, status ){
- // 當(dāng)接收到 payment 指令后運(yùn)行
- if ( status != 'success') return ;
- console.log( res, status );
- });
發(fā)送指令 send()
- var wss = app.xpm.require('Wss');
- wss.liveUsers().then(function( users ) {
- console.log( '讀取在線用戶成功', users );
- // 向第一個用戶發(fā)送 payment 指令
- if ( users.length > 0 ) {
- return wss.send('payment', users[0], users[0]['id'] )
- } else {
- return {code:404, message:'no live user'};
- }
- }).then( function( res ){
- console.log('發(fā)送完畢', res);
- });
- .catch( function( excp ) {
- console.log('出錯了', excp );
- });
綁定事件 bind()
接收并處理 websocket 服務(wù)器事件,有效值 ( open/close/message/error )
- var wss = app.xpm.require('Wss');
- wss.bind('open', function(event) {
- console.log('信道服務(wù)器開啟', event );
- });
- wss.bind('close', function(event) {
- console.log('信道服務(wù)器關(guān)閉', event );
- });
3. 會話 ( Session )
Session 會話分為客戶端和服務(wù)端兩部分,客戶端與服務(wù)端會話ID相同,客戶端保存用戶信息資料,服務(wù)端保存用戶 openid 等敏感信息。與服務(wù)端通信,使用Sesssion ID 鑒權(quán),通過服務(wù)器端驗(yàn)證后,請勿將 Session ID 發(fā)送給第三方。
啟用會話 start()
啟用會話后,會自動創(chuàng)建一個會話ID
- var session = app.xpm.require('session');
- session.start();
會話 ID id()
- var session = app.xpm.require('session');
- var sid = app.id();
- console.log( sid );
客戶端會話數(shù)據(jù)管理 set() & get()
- var session = app.xpm.require('session');
- session.set('hello', 'world');
- console.log( session.get('hello') );
4. 云端表格 ( Table )
可以使用云端表格接口,將數(shù)據(jù)保存在 MySQL 中,可以通過 SQL 查詢數(shù)據(jù)。
創(chuàng)建數(shù)據(jù)表 _schema()
僅管理員帳號擁有創(chuàng)建數(shù)據(jù)表權(quán)限 ( 登錄管理后臺,打開用戶表,將開發(fā)者對應(yīng)帳號記錄的 isadmin 字段數(shù)值設(shè)置為 1 )
- var table = app.xpm.require('Table', 'hello');
- table._schema(
- [
- {name:"name", type:'string', option:{length:80, require:true }, acl:"rwd:r:-" },
- {name:"company", type:'string', option:{length:100}, acl:"w:-:-" }
- ],
- { record:"rwd:rw:-", table:"rwd:-:-", field:'rwd:r:-', user:'admin', group:'member' }
- , true ).then( function( data ) {
- console.log('數(shù)據(jù)表創(chuàng)建成功', data );
- })
- .catch( function( excp ) {
- console.log('數(shù)據(jù)表創(chuàng)建失敗', excp );
- });
字段配置參數(shù)
參數(shù) | 中文 | 說明 |
---|---|---|
name | 字段名稱 | |
type | 字段類型 | string/integer/text/boolean 等 |
option | 字段參數(shù) | index:true 索引 unique:true 唯一索引 length:80 字段長度 |
acl | 字段鑒權(quán) | rw:rw:rw r: 讀取 w: 寫入 -:無 user:group:other |
數(shù)據(jù)增刪改查 get() create() update() remove()
- var table = app.xpm.require('Table', 'hello');
- // 創(chuàng)建
- table.create(
- {name:'張藝謀', company:'中國電影制片廠'}
- ).then(function(data) { // 更新
- return table.update(data['_id'], {name:'馮小剛'});
- }).then(function(data) { // 讀取
- return table.get(data['_id']);
- }).then(function(data) { // 刪除
- return table.remove(data['name'], 'name' );
- }).then(function(resp) {
- console.log( 'remove success', resp );
- }).catch( function( excp ) {
- console.log('出錯了', excp );
- });
數(shù)據(jù)查詢 query()
- var table = app.xpm.require('Table', 'hello');
- table.query()
- .where('name', '=', '馮小剛')
- .orderby('name', 'asc')
- .limit(2) // 僅查詢 2條
- .fetch('name','company').then(function(data) {
- console.log( '查詢結(jié)果', data );
- })
- table.query()
- .where('name', '=', '馮小剛')
- .orderby('name', 'asc')
- .paginate(3, 2) // 分3頁,當(dāng)前顯示第 2頁
- .fetch('name','company').then(function(data) {
- console.log( '查詢結(jié)果', data );
- });
聯(lián)合查詢 join(), leftjoin(), rightjoin() (xpmjs-server 1.0rc4+)
Table 1: User
id | name | title |
---|---|---|
1 | 張三 | 產(chǎn)品經(jīng)理 |
2 | 李四 | 工程師 |
3 | 王五 | 運(yùn)維工程師 |
Table 2: Project
id | name | uid |
---|---|---|
1 | 小程序開發(fā)組 | 1 |
2 | 網(wǎng)頁開發(fā)組 | 3 |
- var table = app.xpm.require('Table', 'Project');
- table.query()
- .join('User', 'User.id', '=', 'Project.uid' ) // leftjoin / rightjoin
- .limit(1)
- .fetch('User.id as userid', 'User.name as username', 'Project.*').then(function(data) {
- console.log( '查詢結(jié)果', data );
- })
返回值
- [
- {
- "id":1,
- "name":"小程序開發(fā)組"
- "userid":1,
- "username":"產(chǎn)品經(jīng)理"
- }
- ]
inWhere 查詢 inWhere()
Table 1: User
id | name | title |
---|---|---|
1 | 張三 | 產(chǎn)品經(jīng)理 |
2 | 李四 | 工程師 |
3 | 王五 | 運(yùn)維工程師 |
Table 2: Project
id | name | users |
---|---|---|
1 | 小程序開發(fā)組 | ["1","2","3"] |
2 | 網(wǎng)頁開發(fā)組 | ["1", "3"] |
- var table = app.xpm.require('Table', 'Project');
- table.query()
- .inWhere('users', 'User', 'id', '*' )
- .limit(1)
- .fetch('User.id as userid', 'User.name as username', 'Project.*').then(function(data) {
- console.log( '查詢結(jié)果', data );
- })
返回值
- [
- {
- "id":1,
- "name":"小程序開發(fā)組"
- "users":[
- {
- "id":1,
- "name":"張三",
- "title":"產(chǎn)品經(jīng)理"
- }
- ...
- ]
- }
- ]
5. 微信支付 ( Pay )
發(fā)起支付 request();
- var pay = app.xpm.require('Pay');
- pay.request({
- total_fee:500, // 單位分
- body:'算命、服務(wù)器開光',
- attach:'HELLO XpmJS.com',
- detail:'{id:888,desp:"算命,抽SSR,贈送服務(wù)器開光"}'
- }).then(function( data ){
- console.log('Request Pay Success', data );
- }).catch( function( excp){
- console.log('Request Pay Failure', excp );
- });
云端事件 before(), success(), fail(), complete() (xpmjs-server 1.0rc4+)
- pay.before('create', { // 創(chuàng)建充值記錄 (統(tǒng)一下單成功后, 發(fā)起支付前, 在云端運(yùn)行 )
- 'table':'income',
- 'data': {
- sn:'{{sn}}',
- order_sn: data.order.sn,
- uid:data.order.uid,
- amount:data.order.sale_price,
- amount_free:0,
- status:'PENDING',
- status_tips:"F請求付款"
- }
- })
- .order({ // 生成訂單 ( 統(tǒng)一下單接口, 僅設(shè)定并不發(fā)送請求 )
- total_fee:data.order.sale_price, // 單位分
- body:data.order.show_name,
- attach:'attach user is ' + mid, // 應(yīng)該是當(dāng)前登錄用戶的 ID
- detail:data
- })
- .success('update', { // 更新充值記錄 ( 支付成功后回調(diào),在云端運(yùn)行 )
- 'table':'income',
- 'data': {
- sn:'{{sn}}',
- status:'DONE',
- status_tips:"income status_tips field"
- },
- 'unique':'sn'
- })
- .success('app', { // 調(diào)用APP 示例 ( 支付成功后回調(diào),在云端運(yùn)行 )
- 'name':'xapp',
- 'api':['ticket','index',{sn:'{{sn}}','status_tips':"{{0.status_tips}}"}],
- 'data': {
- sn:'{{sn}}',
- status:'DONE'
- }
- })
- .success('update', { // 更新訂單狀態(tài) ( 支付成功后回調(diào),在云端運(yùn)行 )
- 'table':'order',
- 'data': {
- _id:oid,
- status:'PENDING'
- }
- })
- .success('create', { // 創(chuàng)建消費(fèi)記錄 ( 支付成功后回調(diào),在云端運(yùn)行 )
- 'table':'payout',
- 'data': {
- sn:'{{sn}}',
- order_sn: data.order.sn,
- uid:data.order.uid,
- amount:data.order.sale_price,
- amount_free:0,
- status:'DONE',
- status_tips:"F請求付款"
- }
- })
- .request().then(function( payResp ) { // 發(fā)起請求
- console.log( payResp );
- })
6. 本地存儲 ( Stor )
- var stor = app.xpm.require('Stor');
- stor.setSync('key','value');
- console.log(stor.getSync('key'));
- stor.setMapSync('map_name', 'key', 'value');
- console.log(stor.getMapSync('map_name','key'));
7. 云端應(yīng)用 ( App ) (xpmjs-server 1.0rc3+)
調(diào)用示例
- var xapp = app.xpm.require('App', 'xapp' ); // xapp 應(yīng)用名稱
- xapp.api( 'ticket', 'available' ) // ticket 控制器 available 方法名
- .post({
- 'train_date':'2017-01-26',
- 'from_station':'BJP',
- 'to_station':'SHH'
- })
- .then( function( resp ) {
- console.log('POST RESP:', resp );
- })
- .catch( function( excp ) {
- console.log('POST EXCP:', excp );
- });
XpmJS 云端應(yīng)用開發(fā)
參考云端應(yīng)用 Demo <火車票余票查詢接口實(shí)現(xiàn)>
https://git.oschina.net/xpmjs/xapp
8. 云端隊(duì)列 ( Que.js ) (xpmjs-server 1.0rc4+)
- var que = app.xpm.require('Que', 'hello');
- que.select('world').push('create', { // 增加數(shù)據(jù)
- table:'payout',
- data: {
- sn:'200193',
- order_sn:'test29993',
- amount:100,
- status:'DONE'
- }
- }).push('update', { // 更新數(shù)據(jù)
- table:'order',
- data: {
- sn:'148457330261256',
- status_tips:'{{0.sn}} {{0.status}}'
- },
- unique:'sn'
- }).push('app', { // 調(diào)用APP 示例
- 'name':'xapp',
- 'api':['ticket','index',{sn:'{{0.sn}}'}],
- 'data': {
- sn:'{{0.sn}} {{1.sn}}',
- status:'DONE'
- }
- }).run().then(function(resp){
- console.log( 'Response', resp );
- })
- .catch(function(excp){
- console.log( 'Error', excp );
- })
9. 文件上傳 Utils.upload & App.upload (xpmjs-server 1.0+)
上傳文件到騰訊云對象存儲
- var qcloud = app.xpm.require('app', 'xqcloud');
- qcloud.api("cos",'upload')
- .upload( tempFilePaths[0] )
- .then(function(data){
- that.setData({
- 'rs.corver':data.access_url,
- 'rs.images':[data.access_url]
- });
- })
- .catch( function(excp){
- console.log('Upload Fail', excp );
- });
10. 常用方法 ( Utils )
請求網(wǎng)址 ( Utils.fetch ) (xpmjs-server 1.0rc3+)
- var utils = app.xpm.require('Utils' );
- utils.fetch( 'http://qcloud.com' ).then( function( resp ) {
- console.log('FETCH RESP:', resp );
- })
- .catch( function( excp ) {
- console.log('FETCH EXCP:', excp );
- });
生成二維碼圖片 ( Utils.qrImageUrl ) (xpmjs-server 1.0+)
返回二維碼圖片地址
- var utils = app.xpm.require('Utils' );
- var url = utils.qrImageUrl('hello world', {size:200});
- console.log( url );
生成小程序頁面二維碼 ( Utils.qrcode ) ( xpmjs-server 1.0 )
- var utils = app.xpm.require('Utils' );
- var url = utils.qrcode('/page/detail?id=1');
- console.log( url );
三、微信小程序 Demo
四、安裝配置
1. 云端配置
【安裝后端程序】
推薦使用騰訊云( 訪問微信接口快, 可以免費(fèi)申請 Https 證書 )
方法1: 使用腳本安裝 ( 目前僅支持 Ubuntu 14.04 64 LTS 操作系統(tǒng) )
創(chuàng)建一臺云服務(wù)器,選擇 Ubuntu 14.04 64 LTS 操作系統(tǒng)。 登錄服務(wù)器運(yùn)行以下腳本。
安裝前,先提前申請 Docker Hub 鏡像 申請地址 https://www.daocloud.io/mirror
- curl -sSL http://tuanduimao.com/xpmjs-server.sh | sh -s yourdomain.com http://<your id>.m.daocloud.io
方法2: 使用 Docker 安裝
- docker run -d --name=xpmjs-server \
- -e "HOST=yourdomain.com" \
- -v /host/data:/data \
- -v /host/apps:/apps \
- -v /host/config:/config \
- -p 80:80 -p 443:443 \
- tuanduimao/xpmjs-server:1.0
【設(shè)置管理員名稱和密碼】
訪問: http://yourdomian.com/setup.php
1、填寫后臺信息
2、填寫管理員信息
【上傳 HTTPS 證書 & 微信支付證書】
訪問:http://yourdomian.com/baas-admin/cert/index 上傳 HTTPS 證書和證書密鑰; 如已申請微信支付,建議盡量上傳支付證書,用于雙向驗(yàn)證證書和密鑰,確保支付安全。
上傳好證書后,登錄服務(wù)器,重啟容器。
- docker restart xpmjs-server
訪問: https://yourdomian.com ( 有 "S", 檢查證書是否生效 )
【設(shè)置小程序配置信息】
訪問: https://yourdomian.com/baas-admin/conf/index ( 有 "S", 填寫小程序和微信支付的信息 )
2. 使用 XpmJS
【下載代碼】
使用 Git Bash , 進(jìn)入小程序項(xiàng)目目錄, 運(yùn)行 git clone 拉去代碼。(也可以 使用 Git 等客戶端 Clone 代碼 )
- git clone https://git.oschina.net/xpmjs/xpmjs.git xpmjs
克隆成功后的目錄結(jié)構(gòu)為:
【編寫配置信息】
編輯 app.js 將域名更換為你的域名。( 必須配置好 Https 證書 )
- App({
- onLaunch: function () {
- var that = this;
- // 創(chuàng)建 xpm 對象
- this.xpm = require('xpmjs/xpm.js').option({
- 'app':1, // 對應(yīng)后臺 APP 配置,支持5個
- 'host':'yourdomian.com',
- 'https':'yourdomian.com',
- 'wss': 'yourdomian.com/ws-server',
- 'table.prefix': 'demo',
- 'user.table':'user'
- });
- // 創(chuàng)建全局對象
- this.wss = this.xpm.require('wss'); // 信道
- this.session = this.xpm.require('session'); // 會話
- this.stor = this.xpm.require('stor'); // 存儲
- },
- xpm:null,
- session:null,
- stor:null,
- wss:null
- })
建議將 xpm、wss、session、stor 設(shè)定為全局變量。