tencent-qqnews-user
Version:
用于在腾讯新闻客户端中进行登录、获取用户信息和提交请求等操作
543 lines (492 loc) • 14.7 kB
JavaScript
import {cookie, getScript, os, callbackRandom, jsonp} from './modules/common';
let getUserBB = {
timer: null
};
const User = {
cache: {},
__readyList: [],
// 新闻客户端内的回调,确保 window.TencentNews 全局变量一定存在
// iOS客户端提供的 JS API 由客户端注入。页面无需引入或主动加载这些JS文件,客户端会在合适的时机将 JS API 注入到页面中供页面使用
// iOS客户端里,由于页面执行 客户端注入js 和 页面js 的顺序无法保证,需要在使用 window.TencentNews 对象前,确保客户端提供的 JS API已经处于ready状态
// Android客户端需要先加载jsapi才能使用 window.TencentNews 这个全局变量
__isReady: false,
ready(){
if( typeof window==='undefined' ){
return Promise.reject(new Error('window is undefined'));
}
if( this.__isReady ){
return Promise.resolve(window.TencentNews);
}
if( window.TencentNews ){
this.__isReady = true;
return Promise.resolve(window.TencentNews);
}
return new Promise((resolve)=>{
if( os.android ){
getScript('//mat1.gtimg.com/www/js/newsapp/jsapi/news.js?_tsid=1', ()=>{
this.__isReady = true;
resolve(window.TencentNews);
});
}else{
document.addEventListener('TencentNewsJSInjectionComplete', () => {
this.__isReady = true;
resolve(window.TencentNews);
});
}
});
},
async login(logintype='qqorweixin', callback=()=>{}){
if(os.qqnews){
const myNews = await this.ready();
return new Promise((resolve, reject)=>{
if( myNews.showNativeLoginWithType ){
window['userLoginCallBack'] = (res)=>{
setTimeout(()=>{
callback(res);
resolve(res);
// delete window['userLoginCallBack'];
}, 600);
};
if( !os.android ){
// ios登录
myNews.showNativeLoginWithType(logintype, window.userLoginCallBack, '');
}else{
// 安卓登录
myNews.showNativeLoginWithType(logintype, 'userLoginCallBack', '');
}
}else{
reject(new Error('TencentNews has no function showNativeLoginWithType'));
}
});
} else if(os.weixin) {
window.location.href = (window.location.protocol==='https:' ? 'https:' : 'http:') + '//api.prize.qq.com/wxlogin/login/wx9bf1f2b2b6610eb0/newsapp';
} else {
// http://platform.server.com/ptlogin/handbook6.html
// low_login=1表示弱登录
// 弱登录使用的cookie名称是luin和lskey,有别于常规的cookie名称uin和skey
let url = 'http://ui.ptlogin2.qq.com/cgi-bin/login?v=1';
let params = {
style: 9,
appid: 1006102,
daid: 0,
low_login: 1,
pt_no_onekey: 1,
s_url: encodeURIComponent(window.location.href)
};
let s = '';
for(let key in params) {
s += `&${key}=${params[key]}`;
}
url += s;
window.location.href = url;
}
},
async logout(){
const myNews = await this.ready();
if( myNews.clearMainAccount ){
this.clearCache('user');
myNews.clearMainAccount();
}
},
async changeLogin(logintype='qqorweixin', callback=()=>{}){
const myNews = await this.ready();
return new Promise((resolve, reject)=>{
if( myNews.changeMainAccount ){
window['changeMainAccountBack']=(res)=>{
this.clearCache('user');
callback(res);
resolve(res);
// delete window['changeMainAccountBack'];
};
if( !os.android ){
// ios登录
myNews.changeMainAccount(window.changeMainAccountBack, logintype, '');
}else{
// 安卓登录
myNews.changeMainAccount('changeMainAccountBack', logintype, '');
}
}else{
reject(new Error('TencentNews has no function changeMainAccount'));
}
});
},
// 获取用户信息
async getUserInfo(callback=()=>{}){
let result = {
logintype: ''
};
if( this.cache['user'] ){
callback(this.cache['user']);
return false;
}
if( os.qqnews ){
await this.ready();
window['userInfoCallBack']=(res)=>{
res = JSON.parse(res);
clearTimeout(getUserBB.timer);
getUserBB.timer = null;
if( res.primary ){
// ios
if( res.primary==='qq' ){
// this.getQQUserInfo(callback);
if (window.TencentNews.getQQUserInfo) {
window['getUserDataQQCallback'] = (qqres) => {
// nick 昵称 | head_url:头像 | openid
// result = JSON.parse( result );
let _result = JSON.parse(qqres),
openid = '';
if (_result.uin) {
openid = _result.uin.substring(1).replace(/\b(0+)/gi, '');
} else if (_result.openid) {
openid = _result.openid;
}
if (openid) {
result = {
logintype: 'qq',
nickname: _result.nick,
avatar: _result.head_url,
openid: openid,
connected: !!_result.openid
};
}
this.cache['user'] = result;
callback(result);
this.readyListCallBack(result);
};
window.TencentNews.getQQUserInfo(window.getUserDataQQCallback);
} else {
throw new Error('TencentNews have no getQQUserInfo function');
}
}else if( res.primary==='weixin' ){
// this.getWeixinUserInfo(callback);
if (window.TencentNews.getWeixinUserInfo) {
window['getUserDataWeixinCallback'] = (weixinres) => {
// nick 昵称 | head_url:头像 | openid
// result = JSON.parse( result );
let _result = JSON.parse(weixinres);
result = {
logintype: 'weixin',
nickname: _result.nick,
avatar: _result.head_url,
openid: _result.openid
};
this.cache['user'] = result;
callback(result);
this.readyListCallBack(result);
};
window.TencentNews.getWeixinUserInfo(window.getUserDataWeixinCallback);
} else {
throw new Error('TencentNews have no getWeixinUserInfo function');
}
}
}else if( res.accountType ){
// android
if( res.accountType=='qq' && res.qqUserInfo && (res.qqUserInfo.openid || res.qqUserInfo.qqNumber) ){
// 新版返回openid,不再是QQ号; 旧版依然返回qqNumber
let openid = res.qqUserInfo.openid ? res.qqUserInfo.openid : res.qqUserInfo.qqNumber,
connected = res.qqUserInfo.openid ? true : false;
result = {
logintype: 'qq',
nickname: res.qqUserInfo.nick,
avatar: res.qqUserInfo.head_url,
openid: openid,
connected: connected // 是否是QQ互联的登录方式
};
}else if(res.accountType=='wx' && res.wxUserInfo && res.wxUserInfo.openid){
result = {
logintype: 'weixin',
nickname: res.wxUserInfo.nick,
avatar: res.wxUserInfo.head_url,
openid: res.wxUserInfo.openid
};
}
this.cache['user'] = result;
callback(result);
this.readyListCallBack(result);
}else{
this.cache['user'] = result;
callback(result);
this.readyListCallBack(result);
}
};
if(getUserBB.timer){
this.__readyList.push(callback);
return false;
}
getUserBB.timer = setTimeout(function(){
if( !os.android ){
window.TencentNews.getUserInfo(window.userInfoCallBack);
}else{
window.TencentNews.getUserInfo('userInfoCallBack');
}
}, 300);
} else if (os.qq) {
if (getUserBB.timer) {
this.__readyList.push(callback);
return false;
}
getUserBB.timer = 1;
const getUserInfoInQQ = () => {
window.mqq.data.getUserInfo((userinfo) => {
if (userinfo) {
if (userinfo.code===0) {
const uin = userinfo.data.uin || userinfo.uin;
result = {
logintype: 'qq',
nickname: userinfo.data.nick || userinfo.nick,
avatar: `https://q.qlogo.cn/g?b=qq&nk=${uin}&s=100`,
openid: uin.replace(/[a-z]/g, '').replace(/\b(0+)/gi, '')
};
} else if (userinfo.uin) {
const uin = userinfo.uin.replace(/[a-z]/g, '').replace(/\b(0+)/gi, '');
result = {
logintype: 'qq',
nickname: userinfo.nick,
avatar: `https://q.qlogo.cn/g?b=qq&nk=${uin}&s=100`,
openid: uin
};
}
}
getUserBB.timer = null;
this.cache['user'] = result;
callback(result);
this.readyListCallBack(result);
})
}
if (window.mqq) {
getUserInfoInQQ();
} else {
getScript('https://open.mobile.qq.com/sdk/qqapi.js?_bid=152', () => {
getUserInfoInQQ();
})
}
} else if(os.weixin){
let userinfo = cookie.getCookie('prize_wx_user_info', 1);
if (userinfo) {
let user = JSON.parse(userinfo); // 存储的为json string,需要转换
/*
user结构:
{
"nickname":"%E7%8E%8BMax%28%2Aint64%29%F0%9F%8D%81", // 需要decodeURIComponent编译
"headimgurl":"http://wx.qlogo.cn/mmopen/TFA8syOnicFsNYb0t24cxriadGvrDOO6LicKzicrBRq6JXutRZSWnu3N4sPRIcc6NYJB1vxTNJAZHMAUibTqHC5hicslreXkvE85Qg/0"
}
*/
if (!user.headimgurl || user.headimgurl === '/0') {
user.headimgurl = '//mat1.gtimg.com/news/qqnews/newolduser/img/defaults_avatar.jpg';
}
result = {
logintype: 'weixin',
nickname: decodeURIComponent(user.nickname),
avatar: user.headimgurl,
openid: cookie.getCookie('prize_wx_openid_newsapp')
};
}
this.cache['user'] = result;
callback(result);
} else {
const qq_openid = cookie.getCookie('qq_openid');
const qq_access_token = cookie.getCookie('qq_access_token');
if (!qq_openid || !qq_access_token) {
callback(result);
return false;
}
if (getUserBB.timer) {
this.__readyList.push(callback);
return false;
}
getUserBB.timer = 1;
jsonp('https://pacaio.match.qq.com/qq/userInfo', {
_: Math.random()
}).then((userinfo) => {
if (userinfo && userinfo.ret===0) {
result = {
logintype: 'qq',
nickname: userinfo.nickname,
avatar: userinfo.figureurl_qq || userinfo.figureurl_qq_2 || userinfo.figureurl_qq_1 || userinfo.figureurl_2,
openid: qq_openid
};
}
getUserBB.timer = null;
this.cache['user'] = result;
callback(result);
this.readyListCallBack(result);
}).catch((error) => {
console.error(error);
});
}
},
readyListCallBack (options) {
while (this.__readyList.length) {
this.__readyList.pop()(options);
}
},
// 清除缓存
clearCache (type) {
delete this.cache[type];
},
getQQUserInfo(callback=()=>{}){
if( window.TencentNews.getQQUserInfo ){
window['getUserDataQQCallback'] = (result)=>{
// nick 昵称 | head_url:头像 | openid
// result = JSON.parse( result );
let _result = JSON.parse( result ),
res = {logintype: ''},
openid = '';
if(_result.uin){
openid = _result.uin.substring(1).replace(/\b(0+)/gi, '');
}else if(_result.openid){
openid = _result.openid;
}
if(openid){
res = {
logintype: 'qq',
nickname: _result.nick,
avatar: _result.head_url,
openid: openid
};
}
this.cache['user'] = res;
callback( res );
delete window['getUserDataQQCallback'];
};
window.TencentNews.getQQUserInfo(window.getUserDataQQCallback);
}else{
throw new Error('TencentNews have no getQQUserInfo function');
}
},
getWeixinUserInfo(callback=()=>{}){
if( window.TencentNews.getWeixinUserInfo ){
window['getUserDataWeixinCallback'] = (result)=>{
// nick 昵称 | head_url:头像 | openid
// result = JSON.parse( result );
let _result = JSON.parse( result ),
res = {
logintype: 'weixin',
nickname: _result.nick,
avatar: _result.head_url,
openid: _result.openid
};
this.cache['user'] = res;
callback( res );
delete window['getUserDataWeixinCallback'];
};
window.TencentNews.getWeixinUserInfo(window.getUserDataWeixinCallback);
}else{
throw new Error('TencentNews have no getWeixinUserInfo function');
}
},
// 所有post方法获取数据成功后都会执行的方法
postSuccess(){
},
// 所有post方法获取数据失败时都活执行的方法
postError(){
},
// 提交数据
post(argv, params){
let url = '',
data = {a:'1'},
success = function(){},
error = function(){},
complete = function(){};
if( typeof argv==='object' && argv.url ){
url = argv.url;
}else if( typeof argv==='string' ){
url = argv;
if(typeof params==='object'){
argv = params;
}
}
if(!url){
return Promise.reject(new TypeError('url must be needed'));
}
if( typeof argv==='object' ){
if( typeof argv['data']==='object' ){
data = argv['data'];
}
if( typeof argv['success']==='function' ){
success = argv['success'];
}
if( typeof argv['error']==='function' ){
error = argv['error'];
}
if( typeof argv['complete']==='function' ){
complete = argv['complete'];
}
}
if( os.qqnews ){
return this.newsPost({url, data, success, error, complete});
}else{
return this.fetch({url, data, success, error, complete});
}
},
/**
* 新闻客户端内的请求
*/
async newsPost({
url='',
data={},
success=()=>{},
error=()=>{},
complete=()=>{}
}){
await this.ready();
let postCallBack = callbackRandom();
let errorCallback = callbackRandom();
return new Promise((resolve, reject)=>{
window[errorCallback] = (err)=>{
let _error = err || new Error('url: '+url+' post error');
error( _error, url );
reject( _error, url );
complete( _error, url );
this.postError( _error, url );
// delete window[errorCallback];
// delete window[postCallBack];
};
window[postCallBack] = (result, cc)=>{
if( !os.android ){
if( !result ){
window[errorCallback]();
return false;
}else{
result = cc;
}
}
success( JSON.parse(result) );
resolve( JSON.parse(result) );
complete( null, url, JSON.parse(result) );
this.postSuccess( null, url, JSON.parse(result) );
// delete window[postCallBack];
// delete window[errorCallback];
};
if( !os.android ){
window.TencentNews.post && window.TencentNews.post(url, data, window[postCallBack], {'loginType':'qqorweixin'}, {});
}else{
window.TencentNews.postData && window.TencentNews.postData(url, JSON.stringify(data), postCallBack, errorCallback);
}
});
},
/**
* 网页端的请求
*/
fetch ({
url='',
data={},
success=()=>{},
error=()=>{},
complete=()=>{}
}) {
return new Promise((resolve, reject) => {
jsonp(url, data).then((data) => {
success(data);
complete(null, data);
this.postSuccess( null, url, data );
resolve(data);
}).catch(err => {
error(err, url);
this.postError(err, url);
reject(err, url);
});
});
}
};
export default User;