完善手机密码登录和Vuex状态管理

This commit is contained in:
sfmind 2022-04-20 03:08:59 +08:00
parent 671b5d343e
commit 93352b5386
12 changed files with 187 additions and 100 deletions

View File

@ -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'))))
}
//vuexsessionStorage
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>

View File

@ -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)

View File

@ -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
}
}

View File

@ -1,7 +1,5 @@
export default {
data() {
return {
}
}
data() {
return {}
}
}

View File

@ -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)

View File

@ -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>

View File

@ -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;

View File

@ -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
}
}
}

View File

@ -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

View File

@ -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
})

View File

@ -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)
)
}

View File

@ -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)
}
)
}