UNPKG

tencent-qqnews-user

Version:

用于在腾讯新闻客户端中进行登录、获取用户信息和提交请求等操作

543 lines (492 loc) 14.7 kB
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;