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