背景
為某化妝品企業(yè)的柜臺推銷員提供與客戶交流的企業(yè)微信小應(yīng)用杈帐,可以分享自己的名片桑阶,與自己的客戶發(fā)起會話并發(fā)送素材庫中的文章和新聞唆樊。同樣可以在文章詳情頁將當前文章分享給微信好友霜运。
引入jssdk并預(yù)設(shè)一些全局變量
<script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<script>
(function(win) {
var ua = navigator.userAgent;
win.isIOS = /iPhone/i.test(ua);
win.isAndroid = /Android/i.test(ua);
win.isWexin = /MicroMessenger/i.test(ua);
win.isWxWork = /wxwork/i.test(ua);
// 企業(yè)微信的userAgent為:wxwork 不是WxWork
})(window);
</script>
第一步:換取code脾歇,使用code換取accessToken和userId
注意要點:
- 注意token驗證 防止一直跳轉(zhuǎn)
- axios請求地址使用https
- 測試時的地址不可以為本地地址,可使用uat
微信開發(fā)文檔API:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html
/**
* 微信網(wǎng)頁授權(quán)
* getAccessToken() 見名知意,用于獲取accessToken
* tools.unparam() 用戶將url的參數(shù)解析為json格式
*/
async function weixinAuth(fn) {
if (getAccessToken() || !window.isWexin || !window.isWxWork) return;
const params = tools.unparam(location.href);
if (params.code && params.state === 'weixinAuthorize') {
const res = await axios.get(`/app/index/auth`, {
params: {
code: params.code,
},
});
if (res.fail) return;
if (res.accessToken) {
setWxInfo(res);
fn && fn();
}
return;
}
delete params.code;
delete params.state;
let redirect_uri = location.href.split('?')[0];
redirect_uri += tools.param(params);
let authParams = {
redirect_uri,
appid: config.appId,
scope: 'snsapi_userinfo',
response_type: 'code',
state: 'weixinAuthorize',
};
authParams = tools.param(authParams);
location.replace(
`https://open.weixin.qq.com/connect/oauth2/authorize${authParams}#wechat_redirect`,
);
}
第二步:初始化微信SDK
思路:
- 將當前url傳給后端拿到配置參數(shù)
- 將拿到的參數(shù)使用wx.config初始化
- 后續(xù)的操作需要在wx.ready中調(diào)用
注意:
- 當前網(wǎng)頁的URL淘捡, 不包含#及其后面部分
- debug為true藕各,在微信中調(diào)試時,會alert結(jié)果
import axios from 'axios';
const JSAPILIST = [
'getCurExternalContact',
'getContext',
'sendChatMessage',
'selectExternalContact',
'openEnterpriseChat',
'onMenuShareTimeline',
'onMenuShareAppMessage',
'previewImage',
'chooseImage',
'uploadImage',
'downloadImage',
'getNetworkType',
'openLocation',
'getLocation',
'hideOptionMenu',
'showOptionMenu',
'hideMenuItems',
'showMenuItems',
'hideAllNonBaseMenuItem',
'showAllNonBaseMenuItem',
'closeWindow',
'scanQRCode',
'previewFile',
];
/**
* 初始化微信SDK
*/
function init(success, fail) {
if (!window.isWexin || !window.isWxWork) {
fail && fail();
return;
}
axios
.get('/app/index/config/corp', {
params: {
url: location.href.split('#')[0], // 當前網(wǎng)頁的URL焦除, 不包含#及其后面部分
},
})
.then(res => {
console.log(res);
if (!res.signature) {
fail && fail();
return;
}
wx.config({
beta: true,
debug: false,
appId: res.corpID,
timestamp: +res.timestamp,
nonceStr: res.nonceStr,
signature: res.signature,
jsApiList: JSAPILIST,
});
wx.ready(function() {
success && success();
});
wx.error(function(res) {
console.log(res, 'error - config');
});
});
}
第三步:注入應(yīng)用的身份與權(quán)限
并不是所有的接口都需要注入應(yīng)用身份激况,例如:getLocation,chooseImage等
但是在企業(yè)微信中拉取聯(lián)系人或者打開會話時需要先注入應(yīng)用膘魄,例如wx.invoke('sendChatMessage', ...)
注意:
1.【初始化微信SDK】和【注入應(yīng)用的身份與權(quán)限】簽名算法完全一樣乌逐,但是jsapi_ticket的獲取方法不一樣
- 調(diào)用wx.agentConfig之前,必須確保先成功調(diào)用wx.config. 注意:從企業(yè)微信3.0.24及以后版本(可通過企業(yè)微信UA判斷版本號)创葡,無須先調(diào)用wx.config浙踢,可直接wx.agentConfig.
**** 在微信開發(fā)者工具中提示wx.agentConfig is not a function 意味著不支持企業(yè)微信接口,需要真機測試 ****
/**
* 注入應(yīng)用的身份與權(quán)限
*/
async function initAgent(success, fail) {
if (!window.isWexin) {
fail && fail();
return;
}
init(
() => {
axios
.get('/app/index/config/app', {
params: {
url: location.href.split('#')[0], // 當前網(wǎng)頁的URL灿渴, 不包含#及其后面部分
},
})
.then(res => {
if (res.fail || !res.signature) {
fail && fail();
return;
}
let configData = {
corpid: res.corpID,
agentid: res.agentId,
timestamp: +res.timestamp,
nonceStr: res.nonceStr,
signature: res.signature,
jsApiList: JSAPILIST,
success: () => {
success && success();
},
fail: function(res) {
console.log(res, 'fail - agentConfig');
if (res.errMsg.indexOf('function not exist') > -1) {
console.log('版本過低請升級', 'error');
}
},
};
wx.agentConfig(configData);
});
},
() => {
fail && fail();
},
);
}
怎么使用
注意:
使用的接口都要在jsApiList中先聲明
/**
* 隱藏右上角菜單
*/
function hideOptionMenu() {
return new Promise(resolve => {
init(() => {
wx.hideOptionMenu();
});
});
}
/**
* 獲取經(jīng)緯度
*/
function getLocation() {
const defOptions = {
city: '上海市',
};
return new Promise(resolve => {
init(
() => {
wx.getLocation({
type: 'gcj02',
success: res => {
let { longitude, latitude } = res;
console.log('getLocation:', res);
resolve(res);
},
fail: () => {
Message({
message:
'獲取位置失敗洛波,請開啟并授權(quán)微信定位呐芥,此次將使用默認的位置',
type: 'error',
onClose() {
resolve(defOptions);
},
});
},
cancel: () => {
resolve(defOptions);
},
});
},
() => {
resolve(defOptions);
},
);
});
}
使用企業(yè)微信中的特定接口
/**
* 打開外部聯(lián)系人
*/
function selectExternalContact() {
return new Promise(resolve => {
initAgent(
() => {
wx.invoke(
'selectExternalContact',
{
filterType: 0, //0表示展示全部外部聯(lián)系人列表,1表示僅展示未曾選擇過的外部聯(lián)系人奋岁。
},
function(res) {
console.log(res, 'selectExternalContact');
if (res.err_msg == 'selectExternalContact:ok') {
resolve(res.userIds);
} else {
resolve([]);
}
},
);
},
() => {
console.log('err');
resolve([]);
},
);
});
}
/**
* 打開會話
* @param {*} userIds
*/
function openChat(userIds) {
let groupName = userIds.length > 1 ? '討論組' : '';
let externalUserIds = userIds.join(';');
return new Promise(resolve => {
initAgent(
() => {
wx.openEnterpriseChat({
// 注意:參與會話的外部聯(lián)系人列表思瘟,格式為userId1;userId2;…,用分號隔開闻伶。
externalUserIds,
// 必填滨攻,會話名稱。單聊時該參數(shù)傳入空字符串""即可蓝翰。
groupName,
success: function(res) {
// 回調(diào)
resolve(res);
},
fail: function(res) {
if (res.errMsg.indexOf('function not exist') > -1) {
alert('版本過低請升級');
}
},
});
},
() => {},
);
});
}