Authored by QC-L

添加基础登录逻辑 review by 黄敬囿

import { LoginService } from './loginService.js'
const login = new LoginService().yohoApi();
export const loginAction = (callBack) => {
return wx.login({
success(res) {
if (res.code) {
login.checkLogin(res.code).then((data) => {
// 获取 srd_session
const loginData = data;
handleLoginData(loginData);
callBack(null, data);
}).catch((error) => {
callBack(error);
});
}
},
fail(error) {
callBack(error);
}
})
};
const handleLoginData = (loginData) => {
// 上报接口返回的结果,线上debug用
// 缓存 srd_session
setStorageWithValueForKey('srd_session', loginData.srd_session);
// 缓存 openid
setStorageWithValueForKey('openid', loginData.openid);
// 如果 unionid 不存在(未使用过任何有货微信产品的全新用户),调用getUnionID函数,再次获取unionID
if (loginData.unionid) {
// 对于已经授权过的用户,拿到unionid之后获取一次userinfo更新个人信息
setStorageWithValueForKey('unionid', loginData.unionid);
}
}
/**
* 判断微信用户是否绑定
* @param srd_session
* @param result
* @returns {Promise.}
*/
export const decodeUnionId = (srd_session, result) => {
let res = result.detail;
// 存储 userInfo
if (res && res.userInfo) {
setStorageWithValueForKey('userInfo', res.userInfo);
} else {
return;
}
const nickName = res.userInfo.nickName;
const avatarUrl = res.userInfo.avatarUrl;
if (!srd_session) return;
return login.getUnionID(srd_session, res.encryptedData, res.iv).then((data) => {
let union_id;
// 本地保存 union_id
if (data.union_id) {
setStorageWithValueForKey('union_id', data.union_id);
union_id = data.union_id;
} else {
union_id = wx.getStorageSync('union_id');
}
if (!union_id) {
throw new Error('union_id is null');
}
// 网络上传头像,union_id,昵称
login.sendWeChatUserDataWithUnionId(data.union_id, nickName, avatarUrl).catch(error => {});
return {
union_id: union_id,
userInfo: res.userInfo
};
});
};
/**
* 判断微信用户是否绑定
* @param unionID
* @param userInfo
* @returns {Promise.}
*/
export const wechatUserIsBind = (union_id, userInfo) => {
return login.wechatUserIsBind(union_id, userInfo.nickName).then(data => {
if (!isStringEmpty(data.is_bind) && data.is_bind === "Y") {
const newUserInfo = {
is_bind: data.is_bind,
mobile: data.mobile,
session_key: data.session_key,
uid: data.uid,
ssouid: data.ssouid
};
const assignUserInfo = Object.assign(newUserInfo, userInfo);
setStorageWithValueForKey('userInfo', assignUserInfo);
return Promise.resolve({
code: 10003,
data: userInfo,
message: '微信用户已绑定手机号'
});
} else {
return Promise.resolve({
code: 10004,
message: '微信用户未绑定手机号'
});
}
});
}
const setStorageWithValueForKey = (key, value) => {
const globalData = getGlobalData();
wx.setStorage({
key: key,
data: value,
})
globalData[key] = value;
}
const getStorageWithValueForKey = (key) => {
wx.getStorage({
key: key,
success: function(res) {
},
})
}
const getGlobalData = () => {
const app = getApp();
let globalData;
if (app && app.globalData) {
// 原生小程序的 globalData 获取方式
globalData = app && app.globalData;
} else {
// Taro 下 globalData 获取方式
globalData = app && app.props && app.props.globalData;
}
return globalData;
}
const isStringEmpty = (str) => {
if (str === undefined || str === null || str === '') {
return true
} else {
return false
}
}
\ No newline at end of file
... ...
import BaseService from '../services/baseService.js';
const WECHAT_SMALLPROGRAM_ONLOGIN = 'wechat.smallProgram.onLogin';
const WECHAT_SMALLPROGRAM_DECODEUSERINFO = 'wechat.smallProgram.decodeUserInfo';
const WECHAT_ADDUNIONUPDUSER = 'app.wechat.addUnionUpdUser';
const WECHAT_PASSPORT_SIGNINBYOPENID = 'app.passport.signinByOpenID';
const WechatPath = '/wechat';
export class LoginService extends BaseService {
async checkLogin(code) {
return await this.GET({
method: WECHAT_SMALLPROGRAM_ONLOGIN,
jsCode: code,
miniapp_type: '0' // 暂时为 0
}, {
path: WechatPath
}).then((data) => {
return data;
}).catch((error) => {
throw error;
})
}
async getUnionID(srdSession, encryptedData, iv) {
return await this.GET({
method: WECHAT_SMALLPROGRAM_DECODEUSERINFO,
srdSession,
encryptedData,
iv
}, {
path: WechatPath
}).then((data) => {
return data;
}).catch((error) => {
throw error;
});
}
async sendWeChatUserDataWithUnionId(unionId, nickname, avatarUrl) {
if (!unionId || !nickname || !avatarUrl || avatarUrl === "images/mine_default_head.png") throw new Error('请检查 unionId 或用户信息是否有误');
return await this.GET({
method: WECHAT_ADDUNIONUPDUSER,
unionId,
headIco: avatarUrl,
nickname
}).then(data => {
return data;
}).catch(error => {
throw error;
})
}
async wechatUserIsBind(unionId, nickname) {
return await this.GET({
method: WECHAT_PASSPORT_SIGNINBYOPENID,
openId: unionId,
nickname
}).then(data => {
return data
}).catch(error => {
throw error;
});
}
}
\ No newline at end of file
... ...
... ... @@ -4,7 +4,7 @@ import trimObject from './utils/trimObject.js'
import queryString from './utils/query-string/query-string.js'
const crypto = require('./utils/cryptojs/cryptojs.js');
import MD5 from './utils/md5/md5.js'
import udid from './utils/udid.js'
const request = (methods = 'GET') => {
return async (options = {}) => {
... ... @@ -46,7 +46,7 @@ const handleParam = (params) => {
let globalData = getGlobalData();
getUid(params);
getUdid(params);
const session_key = globalData && globalData.sessionKey ? globalData.sessionKey : '';
const session_key = globalData && globalData.userInfo && globalData.userInfo.session_key ? globalData.userInfo.session_key : '';
const publicParams = _publicParams();
let newParams = {
...params,
... ... @@ -59,16 +59,7 @@ const handleParam = (params) => {
}
const getUdid = (params) => {
const globalData = getGlobalData();
if (params && !params.hasOwnProperty('udid')) {
let udid = globalData.udid ? globalData.udid : "";
if (udid.length === 0) {
udid = getYHStorageSync('udid', 'request');
}
if (udid.length !== 0) {
params.udid = udid;
}
}
params.udid = udid.get();
}
const getUid = (params) => {
... ... @@ -130,6 +121,7 @@ const handleHeader = (options, newParams) => {
const session_key = newParams.session_key ? newParams.session_key : '';
let header = {
'x-yoho-verify': resultString,
'Cookie': 'JSESSIONID=' + session_key,
'Cookies': 'JSESSIONID=' + session_key,
}
return header;
... ... @@ -159,7 +151,7 @@ const sendRequest = (resolve, reject, options) => {
const statusCode = res.statusCode;
const errMsg = res.errMsg;
const data = res.data;
if (data && data.code == 200 && data.data) {
if (data && (data.code == 200 || data.code == 301) && data.data) {
resolve(data.data);
} else {
const code = res.statusCode;
... ...
import uuid from './uuid';
export default {
get() {
let udid = wx.getStorageSync('udid');
if (udid) {
return udid;
}
udid = uuid().replace(/-/g, '');
wx.setStorageSync('udid', udid);
return udid;
}
};
\ No newline at end of file
... ...
// github: https://github.com/kelektiv/node-uuid
// update: https://wzrd.in/standalone/uuid%2Fv4@latest
!function(r){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=r();else if("function"==typeof define&&define.amd)define([],r);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.uuidv4=r()}}(function(){return function r(e,n,t){function o(f,u){if(!n[f]){if(!e[f]){var a="function"==typeof require&&require;if(!u&&a)return a(f,!0);if(i)return i(f,!0);var d=new Error("Cannot find module '"+f+"'");throw d.code="MODULE_NOT_FOUND",d}var p=n[f]={exports:{}};e[f][0].call(p.exports,function(r){var n=e[f][1][r];return o(n?n:r)},p,p.exports,r,e,n,t)}return n[f].exports}for(var i="function"==typeof require&&require,f=0;f<t.length;f++)o(t[f]);return o}({1:[function(r,e,n){function t(r,e){var n=e||0,t=o;return t[r[n++]]+t[r[n++]]+t[r[n++]]+t[r[n++]]+"-"+t[r[n++]]+t[r[n++]]+"-"+t[r[n++]]+t[r[n++]]+"-"+t[r[n++]]+t[r[n++]]+"-"+t[r[n++]]+t[r[n++]]+t[r[n++]]+t[r[n++]]+t[r[n++]]+t[r[n++]]}for(var o=[],i=0;i<256;++i)o[i]=(i+256).toString(16).substr(1);e.exports=t},{}],2:[function(r,e,n){var t="undefined"!=typeof crypto&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&msCrypto.getRandomValues.bind(msCrypto);if(t){var o=new Uint8Array(16);e.exports=function(){return t(o),o}}else{var i=new Array(16);e.exports=function(){for(var r,e=0;e<16;e++)0===(3&e)&&(r=4294967296*Math.random()),i[e]=r>>>((3&e)<<3)&255;return i}}},{}],3:[function(r,e,n){function t(r,e,n){var t=e&&n||0;"string"==typeof r&&(e="binary"===r?new Array(16):null,r=null),r=r||{};var f=r.random||(r.rng||o)();if(f[6]=15&f[6]|64,f[8]=63&f[8]|128,e)for(var u=0;u<16;++u)e[t+u]=f[u];return e||i(f)}var o=r("./lib/rng"),i=r("./lib/bytesToUuid");e.exports=t},{"./lib/bytesToUuid":1,"./lib/rng":2}]},{},[3])(3)});
\ No newline at end of file
... ...
... ... @@ -6,6 +6,7 @@ import searchImg from '../../static/images/search.png';
import {common as commonModel} from '../../models';
import './index.scss';
import { connect } from '@tarojs/redux';
import { loginAction, decodeUnionId, wechatUserIsBind } from '../../libs/login/login.js'
@connect(({ filterMenu }) => ({
... ... @@ -116,6 +117,18 @@ export default class Index extends Component {
})
}
login(e) {
loginAction((error, loginData) => {
if (error) return;
decodeUnionId(loginData.srd_session, e).then(data => {
console.log(data);
wechatUserIsBind(data.union_id, data.userInfo).then(message => {
console.log(message);
});
});
})
}
render() {
let {tabs, productList} = this.state;
let {filterMenu} = this.props;
... ... @@ -133,6 +146,7 @@ export default class Index extends Component {
<View className="header-nav">
<Text className="page-label">飞碟好物</Text>
<Text onClick={this.gotoNative}>跳转原生页面</Text>
<Button openType="getUserInfo" onGetUserInfo={this.login}>登录</Button>
<Navigator url="/pages/search/index" className="search" hover-class="none"><Image className="search-btn" src={searchImg}></Image></Navigator>
</View>
... ...