mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-22 23:31:52 +08:00
完善手机密码登录和Vuex状态管理
This commit is contained in:
parent
671b5d343e
commit
93352b5386
@ -1,22 +1,31 @@
|
||||
<script>
|
||||
export default {
|
||||
onLaunch: function() {
|
||||
console.log('App Launch')
|
||||
},
|
||||
onShow: function() {
|
||||
console.log('App Show')
|
||||
},
|
||||
onHide: function() {
|
||||
console.log('App Hide')
|
||||
}
|
||||
}
|
||||
export default {
|
||||
onLaunch: function () {
|
||||
console.log('App Launch')
|
||||
// #ifdef H5
|
||||
//在页面加载时读取sessionStorage里的状态信息
|
||||
if (sessionStorage.getItem('store')) {
|
||||
this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem('store'))))
|
||||
}
|
||||
//在页面刷新时将vuex里的信息保存到sessionStorage里
|
||||
window.addEventListener('beforeunload', () => {
|
||||
sessionStorage.setItem('store', JSON.stringify(this.$store.state))
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
onShow: function () {
|
||||
console.log('App Show')
|
||||
},
|
||||
onHide: function () {
|
||||
console.log('App Hide')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
/* 引入uView基础样式 */
|
||||
@import "@/uni_modules/uview-ui/index.scss";
|
||||
|
||||
/*每个页面公共scss */
|
||||
@import "app.scss";
|
||||
/* 引入uView基础样式 */
|
||||
@import '@/uni_modules/uview-ui/index.scss';
|
||||
|
||||
/*每个页面公共scss */
|
||||
@import 'app.scss';
|
||||
</style>
|
||||
|
@ -2,12 +2,15 @@ const { http } = uni.$u
|
||||
|
||||
/* login */
|
||||
//使用手机 + 密码登录
|
||||
export const passwordLogin = params => http.post('/app-api/member/user/login', params)
|
||||
export const passwordLogin = params => http.post('/app-api/member/login', params)
|
||||
//发送手机验证码
|
||||
export const sendSmsCode = params => http.post('/app-api/member/send-sms-code', params)
|
||||
//使用手机 + 验证码登录
|
||||
export const smsLogin = params => http.post('/app-api/member/sms-login', params)
|
||||
|
||||
//获取用户信息
|
||||
export const getUserInfo = params => http.get('/app-api/member/user/get', params)
|
||||
|
||||
/* index */
|
||||
// 获取滚动图数据
|
||||
export const getBannerData = params => http.get('/app-api/index', params)
|
||||
|
@ -1,3 +1,8 @@
|
||||
module.exports = {
|
||||
baseUrl: 'http://192.168.3.199:8086'
|
||||
//后端接口地址
|
||||
baseUrl: 'http://127.0.0.1:48080',
|
||||
header: {
|
||||
//租户ID
|
||||
'tenant-id': 1
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
}
|
||||
data() {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,16 @@
|
||||
import Vue from 'vue'
|
||||
import App from './App'
|
||||
|
||||
// 引入全局uView
|
||||
import uView from '@/uni_modules/uview-ui'
|
||||
|
||||
// vuex
|
||||
import store from './store'
|
||||
|
||||
Vue.config.productionTip = false
|
||||
Vue.prototype.$store = store
|
||||
|
||||
// 引入全局uView
|
||||
import uView from '@/uni_modules/uview-ui'
|
||||
|
||||
|
||||
App.mpType = 'app'
|
||||
Vue.use(uView)
|
||||
|
@ -4,7 +4,7 @@
|
||||
<u-empty mode="car" width="500rpx" height="500rpx" icon="/static/images/empty/cart.png"></u-empty>
|
||||
</view>
|
||||
|
||||
<view class="login-tips-box">
|
||||
<view v-if="!hasLogin" class="login-tips-box">
|
||||
<view class="login-tips">
|
||||
<navigator url="/pages/login/login" open-type="navigate" hover-class="none">
|
||||
<text class="login-link">登录</text>
|
||||
@ -23,7 +23,12 @@ export default {
|
||||
}
|
||||
},
|
||||
onLoad() {},
|
||||
methods: {}
|
||||
methods: {},
|
||||
computed: {
|
||||
hasLogin() {
|
||||
return this.$store.getters.hasLogin
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -53,15 +53,13 @@ import { passwordLogin, sendSmsCode, smsLogin } from '../../common/api'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
//租户ID
|
||||
agent: 1,
|
||||
currentModeIndex: 0,
|
||||
loginModeList: ['密码登录', '验证码登录'],
|
||||
inputType: 'password',
|
||||
codeDisabled: false,
|
||||
codeTips: '',
|
||||
formData: {
|
||||
mobile: '15601691234',
|
||||
mobile: '',
|
||||
password: '',
|
||||
code: ''
|
||||
},
|
||||
@ -131,17 +129,17 @@ export default {
|
||||
})
|
||||
|
||||
//scene:1登陆获取验证码场景
|
||||
sendSmsCode({ agent: 1, mobile: mobile, scene: 1 })
|
||||
sendSmsCode({ mobile: mobile, scene: 1 })
|
||||
.then(res => {
|
||||
//console.log(res)
|
||||
uni.hideLoading()
|
||||
if (res.data.code === 0) {
|
||||
if (res.code === 0) {
|
||||
// 这里此提示会被this.start()方法中的提示覆盖
|
||||
uni.$u.toast('验证码已发送')
|
||||
// 通知验证码组件内部开始倒计时
|
||||
this.$refs.uCode.start()
|
||||
} else {
|
||||
uni.$u.toast(res.data.msg)
|
||||
uni.$u.toast(res.msg)
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
@ -153,26 +151,30 @@ export default {
|
||||
},
|
||||
handleSubmit() {
|
||||
this.$refs.form.validate().then(res => {
|
||||
uni.$u.toast('登录')
|
||||
if (this.currentModeIndex === 0) {
|
||||
passwordLogin({ agent: 1, mobile: this.formData.mobile, password: this.formData.password })
|
||||
.then(res => {
|
||||
if (res.data.code === 0) {
|
||||
uni.$u.toast('登录成功')
|
||||
// TODO 登录成功,保存toke
|
||||
} else {
|
||||
uni.$u.toast(res.data.msg)
|
||||
// TODO 登录失败
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
uni.$u.toast('服务器接口请求异常')
|
||||
})
|
||||
this.handleLoginPromise(passwordLogin({ mobile: this.formData.mobile, password: this.formData.password }))
|
||||
} else if (this.currentModeIndex === 1) {
|
||||
smsLogin({ agent: 1, mobile: this.formData.mobile, code: this.formData.code })
|
||||
this.handleLoginPromise(smsLogin({ mobile: this.formData.mobile, code: this.formData.code }))
|
||||
}
|
||||
})
|
||||
},
|
||||
handleLoginPromise(promise) {
|
||||
promise
|
||||
.then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$store.commit('setToken', res.data)
|
||||
uni.$u.toast('登录成功')
|
||||
setTimeout(() => {
|
||||
this.navigateBack()
|
||||
}, 1000)
|
||||
} else {
|
||||
uni.$u.toast(res.msg)
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
uni.$u.toast('接口请求失败')
|
||||
})
|
||||
},
|
||||
navigateBack() {
|
||||
uni.navigateBack()
|
||||
}
|
||||
@ -200,8 +202,6 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.lk-group {
|
||||
height: 40rpx;
|
||||
margin-top: 40rpx;
|
||||
|
@ -2,8 +2,8 @@
|
||||
<view class="container">
|
||||
<view class="user-header">
|
||||
<view class="user-info" @click="loginOrJump('/pages/profile/profile')">
|
||||
<u-avatar size="80" :src="avatar"></u-avatar>
|
||||
<text class="nick-name">{{ nickName }}</text>
|
||||
<u-avatar size="80" :src="userInfo.avatar"></u-avatar>
|
||||
<text class="nick-name">{{ hasLogin ? userInfo.nickname || '游客' : '点击登录' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@ -19,8 +19,8 @@
|
||||
</view>
|
||||
|
||||
<view class="order-status-box">
|
||||
<u-grid :border="false" :col="orderStatusList.length"
|
||||
><u-grid-item v-for="(item, index) in orderStatusList" :key="index">
|
||||
<u-grid :border="false" :col="orderStatusList.length">
|
||||
<u-grid-item v-for="(item, index) in orderStatusList" :key="index">
|
||||
<u-icon :name="item.icon" :size="32"></u-icon>
|
||||
<text class="grid-title">{{ item.title }}</text>
|
||||
</u-grid-item>
|
||||
@ -45,13 +45,12 @@
|
||||
<u-cell class="fun-item" :border="false" icon="gift" title="分销中心" isLink></u-cell>
|
||||
<u-cell class="fun-item" :border="false" icon="tags" title="领券中心" isLink></u-cell>
|
||||
<u-cell class="fun-item" :border="false" icon="coupon" title="我的优惠券" isLink></u-cell>
|
||||
<u-cell class="fun-item" :border="false" icon="map" title="收货地址" @click="loginOrJump('/pages/address/list')" isLink></u-cell>
|
||||
<u-cell class="fun-item" :border="false" icon="map" title="收货地址" @click="loginOrJump('/pages/address/list')" isLink></u-cell>
|
||||
</u-cell-group>
|
||||
|
||||
<view class="logout-btn">
|
||||
<u-button type="error" color="#ea322b" text="确定"></u-button>
|
||||
<view v-if="hasLogin" class="logout-btn">
|
||||
<u-button type="error" color="#ea322b" text="退出登录" @click="logout"></u-button>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@ -59,8 +58,6 @@
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
avatar: '',
|
||||
nickName: '点击登录',
|
||||
orderStatusList: [
|
||||
{ icon: 'rmb-circle', title: '待支付' },
|
||||
{ icon: 'car', title: '代发货' },
|
||||
@ -76,13 +73,34 @@ export default {
|
||||
},
|
||||
onLoad() {},
|
||||
methods: {
|
||||
loginOrJump(pageUrl){
|
||||
// TODO 判断是否已经登录逻辑
|
||||
if (!uni.getStorageSync('token')) {
|
||||
loginOrJump(pageUrl) {
|
||||
if (!this.hasLogin) {
|
||||
uni.$u.route('/pages/login/login')
|
||||
} else {
|
||||
uni.$u.route(pageUrl)
|
||||
}
|
||||
},
|
||||
logout() {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '您确定要退出登录吗',
|
||||
success: res => {
|
||||
if (res.confirm) {
|
||||
console.log('用户点击确定')
|
||||
this.$store.commit('logout')
|
||||
} else if (res.cancel) {
|
||||
console.log('用户点击取消')
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
userInfo() {
|
||||
return this.$store.state.userInfo
|
||||
},
|
||||
hasLogin() {
|
||||
return this.$store.getters.hasLogin
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +1,64 @@
|
||||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
import { getUserInfo } from '@/common/api'
|
||||
|
||||
Vue.use(Vuex) // vue的插件机制
|
||||
|
||||
// Vuex.Store 构造器选项
|
||||
const store = new Vuex.Store({
|
||||
// 为了不和页面或组件的data中的造成混淆,state中的变量前面建议加上$符号
|
||||
state: {
|
||||
// 用户信息
|
||||
$userInfo: {
|
||||
id: ''
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
|
||||
},
|
||||
actions: {
|
||||
|
||||
},
|
||||
getters:{
|
||||
|
||||
state: {
|
||||
openExamine: false, // 是否开启审核状态。用于小程序、App 等审核时,关闭部分功能。TODO 芋艿:暂时没找到刷新的地方
|
||||
token: uni.getStorageSync('token'), // 用户身份 Token
|
||||
userInfo: {}, // 用户基本信息
|
||||
timerIdent: false // 全局 1s 定时器,只在全局开启一个,所有需要定时执行的任务监听该值即可,无需额外开启 TODO 芋艿:需要看看
|
||||
},
|
||||
getters: {
|
||||
hasLogin(state) {
|
||||
return !!state.token
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
// 更新 state 的通用方法
|
||||
setStateAttr(state, param) {
|
||||
if (param instanceof Array) {
|
||||
for (let item of param) {
|
||||
state[item.key] = item.val
|
||||
}
|
||||
} else {
|
||||
state[param.key] = param.val
|
||||
}
|
||||
},
|
||||
// 更新token
|
||||
setToken(state, data) {
|
||||
// 设置 Token
|
||||
const { token } = data
|
||||
state.token = token
|
||||
uni.setStorageSync('token', token)
|
||||
|
||||
// 加载用户信息
|
||||
this.dispatch('obtainUserInfo')
|
||||
},
|
||||
// 退出登录
|
||||
logout(state) {
|
||||
// 清空 Token
|
||||
state.token = ''
|
||||
uni.removeStorageSync('token')
|
||||
// 清空用户信息 TODO 芋艿:这里 setTimeout 的原因是,上面可能还有一些 request 请求。后续得优化下
|
||||
setTimeout(() => {
|
||||
state.userInfo = {}
|
||||
}, 1100)
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
// 获得用户基本信息
|
||||
async obtainUserInfo({ state, commit }) {
|
||||
const res = await getUserInfo()
|
||||
commit('setStateAttr', {
|
||||
key: 'userInfo',
|
||||
val: res.data
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default store
|
||||
|
@ -4,6 +4,7 @@ import config from '@/common/config'
|
||||
uni.$u.http.setConfig((defaultConfig) => {
|
||||
/* defaultConfig 为默认全局配置 */
|
||||
defaultConfig.baseURL = config.baseUrl /* 根域名 */
|
||||
defaultConfig.header = config.header
|
||||
return defaultConfig
|
||||
})
|
||||
|
||||
|
@ -2,13 +2,21 @@
|
||||
* 请求拦截
|
||||
* @param {Object} http
|
||||
*/
|
||||
module.exports = (vm) => {
|
||||
uni.$u.http.interceptors.request.use((config) => { // 可使用async await 做异步操作
|
||||
// 初始化请求拦截器时,会执行此方法,此时data为undefined,赋予默认{}
|
||||
config.data = config.data || {}
|
||||
// 可以在此通过vm引用vuex中的变量,具体值在vm.$store.state中
|
||||
// console.log(vm.$store.state);
|
||||
return config
|
||||
}, (config) => // 可使用async await 做异步操作
|
||||
Promise.reject(config))
|
||||
module.exports = vm => {
|
||||
uni.$u.http.interceptors.request.use(
|
||||
config => {
|
||||
// 可使用async await 做异步操作
|
||||
// 初始化请求拦截器时,会执行此方法,此时data为undefined,赋予默认{}
|
||||
config.data = config.data || {}
|
||||
// 可以在此通过vm引用vuex中的变量,具体值在vm.$store.state中
|
||||
// console.log(vm.$store.state)
|
||||
if (vm.$store.getters.hasLogin) {
|
||||
config.header.authorization = 'Bearer ' + vm.$store.state.token
|
||||
}
|
||||
return config
|
||||
},
|
||||
(
|
||||
config // 可使用async await 做异步操作
|
||||
) => Promise.reject(config)
|
||||
)
|
||||
}
|
||||
|
@ -2,16 +2,16 @@
|
||||
* 响应拦截
|
||||
* @param {Object} http
|
||||
*/
|
||||
module.exports = (vm) => {
|
||||
uni.$u.http.interceptors.response.use((res) => {
|
||||
/* 对响应成功做点什么 可使用async await 做异步操作*/
|
||||
const data = res.data
|
||||
/*
|
||||
可以根据业务情况做相应的处理
|
||||
*/
|
||||
return res
|
||||
}, (err) => {
|
||||
/* 对响应错误做点什么 (statusCode !== 200)*/
|
||||
return Promise.reject(err)
|
||||
})
|
||||
}
|
||||
module.exports = vm => {
|
||||
uni.$u.http.interceptors.response.use(
|
||||
res => {
|
||||
//对响应成功做点什么 可使用async await 做异步操作
|
||||
//可以根据业务情况做相应的处理
|
||||
return res.data
|
||||
},
|
||||
err => {
|
||||
//对响应错误做点什么 (statusCode !== 200)
|
||||
return Promise.reject(err)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user