Browse Source

登录

remotes/origin/HEAD
wally 5 years ago
parent
commit
49fabf7daf
  1. 14
      App.vue
  2. 4
      config/api/user.js
  3. 1
      config/config.default.js
  4. 19
      config/config.user.js
  5. 9
      main.js
  6. 4
      pages/sign/sign.vue
  7. 90
      plugins/request/index.js
  8. 10
      store/index.js
  9. 39
      store/modules/user/actions.js
  10. 5
      store/modules/user/index.js
  11. 39
      store/modules/user/mutations.js
  12. 6
      store/modules/user/state.js
  13. 31
      utils/ui.js
  14. 110
      utils/user.js

14
App.vue

@ -1,13 +1,13 @@
<script> <script>
import { mapActions } from 'vuex';
export default { export default {
onLaunch: function() { async onLaunch() {
console.log('App Launch'); await this.login();
},
onShow: function() {
console.log('App Show');
}, },
onHide: function() {
console.log('App Hide'); methods: {
...mapActions('user', ['login']),
}, },
}; };
</script> </script>

4
config/api/user.js

@ -0,0 +1,4 @@
const proxyUrl = '/tall/v1.0';
// 登录api
export const SIGN_IN = `${proxyUrl}/users/signin`;

1
config/config.default.js

@ -0,0 +1 @@
export const ERR_CODE = 200;

19
config/config.user.js

@ -0,0 +1,19 @@
/*
* Copyright (c) 2020.
* author: wally
* email: 18603454788@163.com
*/
// 用户登录client
export const SIGN_IN_CLIENTS = { mp: 0, h5: 1, android: 2, ios: 3 };
// 用户登录类型
export const SIGN_IN_TYPES = {
mp: 0,
phone: 1,
email: 2,
username: 3,
wx: 4,
wx_web: 5,
wb: 6,
};

9
main.js

@ -2,19 +2,20 @@ import Vue from 'vue';
import moment from 'moment'; import moment from 'moment';
import { http } from 'plugins/request/index'; import { http } from 'plugins/request/index';
import App from './App'; import App from './App';
// import store from './store'; import store from './store';
Vue.config.productionTip = false; Vue.config.productionTip = false;
Vue.prototype.$http = http; Vue.prototype.$http = http;
Vue.prototype.$moment = moment; Vue.prototype.$moment = moment;
moment.locale('zh-cn');
Vue.prototype.goHome = () => { Vue.prototype.goHome = () => {
uni.reLaunch({ uni.reLaunch({
url: '/pages/index/index', url: '/pages/index/index',
}); });
}; };
moment.locale('zh-cn');
/** /**
* 打开某个页面 * 打开某个页面
* @param {string} path 页面完成路径 * @param {string} path 页面完成路径
@ -28,7 +29,7 @@ Vue.prototype.openPage = function(path, query = '') {
App.mpType = 'app'; App.mpType = 'app';
const app = new Vue({ const app = new Vue({
// store, store,
...App, ...App,
}); });
app.$mount(); app.$mount();

4
pages/sign/sign.vue

@ -59,8 +59,8 @@ export default {
} }
} catch (error) { } catch (error) {
console.log('error: ', error); console.log('error: ', error);
if (error.data) { if (error.msg) {
uni.showToast({ title: error.data.msg || '打卡失败', icon: 'none' }); uni.showToast({ title: error.msg || '打卡失败', icon: 'none' });
} }
} }
}, },

90
plugins/request/index.js

@ -9,85 +9,97 @@ const test = new Request();
*/ */
export const getToken = () => uni.getStorageSync('token'); export const getToken = () => uni.getStorageSync('token');
test.setConfig((config) => { /* 设置全局配置 */ test.setConfig(config => {
/* 设置全局配置 */
config.baseUrl = BASE_URL; config.baseUrl = BASE_URL;
config.header = { config.header = {
...config.header, ...config.header,
} };
return config return config;
}) });
test.interceptor.request((config, cancel) => { /* 请求之前拦截器 */ test.interceptor.request((config, cancel) => {
/* 请求之前拦截器 */
config.header = { config.header = {
...config.header, ...config.header,
} };
/* /*
if (!token) { // 如果token不存在,调用cancel 会取消本次请求,但是该函数的catch() 仍会执行 if (!token) { // 如果token不存在,调用cancel 会取消本次请求,但是该函数的catch() 仍会执行
cancel('token 不存在') // 接收一个参数,会传给catch((err) => {}) err.errMsg === 'token 不存在' cancel('token 不存在') // 接收一个参数,会传给catch((err) => {}) err.errMsg === 'token 不存在'
} }
*/ */
return config return config;
}) });
/** /**
* 自定义验证器如果返回true 则进入响应拦截器的响应成功函数(resolve)否则进入响应拦截器的响应错误函数(reject) * 自定义验证器如果返回true 则进入响应拦截器的响应成功函数(resolve)否则进入响应拦截器的响应错误函数(reject)
* @param { Number } statusCode - 请求响应体statusCode只读 * @param { Number } statusCode - 请求响应体statusCode只读
* @return { Boolean } 如果为true, resolve, 否则 reject * @return { Boolean } 如果为true, resolve, 否则 reject
*/ */
test.validateStatus = (statusCode) => { test.validateStatus = statusCode => {
return statusCode === ERR_CODE return statusCode === ERR_CODE;
} };
test.interceptor.response((response) => { /* 请求之后拦截器 */ test.interceptor.response(
return response response => {
}, (response) => { // 请求错误做点什么 /* 请求之后拦截器 */
return response return response;
}) },
response => {
// 请求错误做点什么
return response;
},
);
const http = new Request() const http = new Request();
http.setConfig((config) => { // 设置全局配置 http.setConfig(config => {
// 设置全局配置
config.baseUrl = BASE_URL; // 根域名不同 config.baseUrl = BASE_URL; // 根域名不同
config.header = { config.header = {
...config.header, ...config.header,
}; };
return config return config;
}) });
/** /**
* 自定义验证器如果返回true 则进入响应拦截器的响应成功函数(resolve)否则进入响应拦截器的响应错误函数(reject) * 自定义验证器如果返回true 则进入响应拦截器的响应成功函数(resolve)否则进入响应拦截器的响应错误函数(reject)
* @param { Number } statusCode - 请求响应体statusCode只读 * @param { Number } statusCode - 请求响应体statusCode只读
* @return { Boolean } 如果为true, resolve, 否则 reject * @return { Boolean } 如果为true, resolve, 否则 reject
*/ */
http.validateStatus = (statusCode) => { http.validateStatus = statusCode => {
return statusCode === ERR_CODE return statusCode === ERR_CODE;
} };
http.interceptor.request((config, cancel) => { /* 请求之前拦截器 */ http.interceptor.request((config, cancel) => {
/* 请求之前拦截器 */
const token = getToken() ? { Authorization: `Bearer ${getToken()}` } : {}; const token = getToken() ? { Authorization: `Bearer ${getToken()}` } : {};
config.header = { config.header = {
...config.header, ...config.header,
...token, ...token,
} };
/* /*
if (!token) { // 如果token不存在,调用cancel 会取消本次请求,但是该函数的catch() 仍会执行 if (!token) { // 如果token不存在,调用cancel 会取消本次请求,但是该函数的catch() 仍会执行
cancel('token 不存在') // 接收一个参数,会传给catch((err) => {}) err.errMsg === 'token 不存在' cancel('token 不存在') // 接收一个参数,会传给catch((err) => {}) err.errMsg === 'token 不存在'
} }
*/ */
return config return config;
}) });
http.interceptor.response((response) => { /* 请求之后拦截器 */ http.interceptor.response(
if (response.data.code !== ERR_CODE) { // 服务端返回的状态码不等于200,则reject() response => {
return Promise.reject(response) /* 请求之后拦截器 */
} if (response.data.code !== ERR_CODE) {
return response // 服务端返回的状态码不等于200,则reject()
}, (response) => { // 请求错误做点什么 return Promise.reject(response.data);
return response }
}) return response;
},
response => {
// 请求错误做点什么
return response;
},
);
export { export { http, test };
http,
test
}

10
store/index.js

@ -0,0 +1,10 @@
import Vue from 'vue';
import Vuex from 'vuex';
import user from './modules/user/index';
Vue.use(Vuex);
const store = new Vuex.Store({
modules: { user },
});
export default store;

39
store/modules/user/actions.js

@ -0,0 +1,39 @@
import { showModal } from 'utils/ui';
import { mpLogin, signIn } from 'utils/user';
const actions = {
// 登录
login({ commit }) {
return new Promise((resolve, reject) => {
// #ifdef MP-WEIXIN
mpLogin()
.then(params => signIn(params))
.then(data => {
commit('setToken', data.token);
commit('setUser', data);
resolve(data);
})
.catch(err => {
showModal(err.msg || '登录失败');
reject(err);
});
// #endif
});
},
/**
* signIn 提交登录信息
* @param {any} commit
* @param {string} params 登录提交的参数
*/
signIn({ commit }, params) {
return signIn(params)
.then(data => {
commit('setToken', data.token);
commit('setUser', data);
})
.catch(err => showModal(err));
},
};
export default actions;

5
store/modules/user/index.js

@ -0,0 +1,5 @@
import state from './state';
import mutations from './mutations';
import actions from './actions.js';
export default { namespaced: true, state, actions, mutations };

39
store/modules/user/mutations.js

@ -0,0 +1,39 @@
const mutations = {
/**
* 设置存储token
* @param {object} state
* @param {string} token
*/
setToken(state, token) {
if (!token) return;
state.token = token;
uni.setStorageSync('token', token);
},
/**
* 设置user数据
* @param {object} state
* @param {object} user
*/
setUser(state, user) {
if (!user) return;
state.user = { ...user };
uni.setStorageSync('user', JSON.stringify(user));
},
/**
* 更新手机号
* @param {*} state
* @param {object} option
* @param {string} option.type 修改的数据的key
* @param {any} option.value 新数据的值
*/
updateUser(state, { type, value }) {
const { user } = state;
user[type] = value;
state.user = { ...user };
uni.setStorageSync('user', JSON.stringify(user));
},
};
export default mutations;

6
store/modules/user/state.js

@ -0,0 +1,6 @@
const state = {
token: '',
user: null,
};
export default state;

31
utils/ui.js

@ -0,0 +1,31 @@
/**
* 显示模态框
* @param {string} msg
* @param {boolean} showCancel
* @param {string} confirmText
*/
export const showModal = (msg, showCancel = false, confirmText = '知道了') =>
uni.showModal({
title: '提示',
content: msg,
showCancel,
confirmText,
confirmColor: '#1890ff',
});
/**
* 显示toast
* @param {string} msg
*/
export const showToast = msg =>
uni.showToast({
title: msg,
icon: 'none',
duration: 3000,
});
// 显示加载动画
export const showLoading = (msg = '努力加载中...') => uni.showLoading({ title: msg });
// 隐藏加载动画
export const hideLoading = () => uni.hideLoading();

110
utils/user.js

@ -0,0 +1,110 @@
import { SIGN_IN } from 'api/user';
import { ERR_CODE } from 'config/config.default';
import { http as axios } from 'plugins/request/index';
import { SIGN_IN_CLIENTS, SIGN_IN_TYPES } from 'config/config.user';
/**
* 保存token
* @param {string} token 服务端返回的token数据
*/
export const setToken = token => {
uni.setStorageSync('anyringToken', token);
};
/**
* 获取token
* @return {string} 本地保存的token
*/
export const getToken = () => uni.getStorageSync('anyringToken');
/**
* 提交登录信息
* @param {object} params 提交的参数
*/
export const signIn = params => {
return new Promise((resolve, reject) => {
axios
.post(SIGN_IN, params)
.then(res => {
const { success, code, data, msg } = res.data;
if (success && code === ERR_CODE) {
if (!data || !data.token) {
reject('服务端返回数据不正确');
} else {
resolve(data);
}
} else {
reject(`登录请求失败 ${msg}`);
}
})
.catch(err => {
reject(err);
});
});
};
// 微信登录
export const wxLogin = () => {
return new Promise((resolve, reject) => {
uni.login({
provider: 'weixin',
success(response) {
if (response.code) {
const params = {
client: SIGN_IN_CLIENTS['mp'],
type: SIGN_IN_TYPES['mp'],
data: { identifier: response.code },
redirect: 'https://test.tall.wiki/gateway/health/initMsg',
};
resolve(params);
} else {
reject(response.errMsg);
}
},
fail() {
console.log('fail');
reject('微信登录失败');
},
});
});
};
// 微信登录
export const wxWorkLogin = () => {
return new Promise((resolve, reject) => {
wx.qy.login({
provider: 'weixin',
success(response) {
if (response.code) {
const params = {
client: SIGN_IN_CLIENTS['mp'],
type: SIGN_IN_TYPES['mp'],
data: { identifier: response.code },
redirect: 'https://test.tall.wiki/gateway/health/initMsg',
};
resolve(params);
} else {
reject(response.errMsg);
}
},
fail() {
console.log('fail');
reject('微信登录失败');
},
});
});
};
// 小程序登录
export const mpLogin = () => {
try {
const res = uni.getSystemInfoSync();
if (res.environment === 'wxwork') {
return wxWorkLogin();
} else {
return wxLogin();
}
} catch (err) {
console.log('err: ', err);
}
};
Loading…
Cancel
Save