30 账户安全功能页面(各种账号绑定操作)

30 账户安全功能页面

一 修改账号与安全页面

ps:原有的账号与安全选项只是修改密码,现在可以绑定其他的第三方手机号修改密码等等。

效果图:

image-20200525181030464

代码:

<template>
	<view>
		<uni-list-item :title="item.name" 
		v-for="(item,index) in list"
		:key="index">
			<view class="flex align-center text-right text-light-muted" 
			slot="right">
				{{item.data}}
			</view>
		</uni-list-item>
	</view>
</template>

<script>
	import uniListItem from '@/components/uni-ui/uni-list-item/uni-list-item.vue';
	export default {
		components: {
			uniListItem
		},
		data() {
			return {
				list:[
					{ 
						name:"手机号",
						data:"未绑定",
					},
					{ 
						name:"登录密码",
						data:"未设置"
					},
					{ 
						name:"邮箱绑定",
						data:"未绑定"
					},
					{ 
						name:"微信账号",
						data:"未绑定",
					},
					{
						name:"微博账号",
						data:"未绑定",
					},
					{
						name:"QQ账号",
						data:"未绑定",
					}
				]
			}
		},
		methods: {
			
		}
	}
</script>

<style>

</style>

二 绑定手机

效果图:

image-20200525181241931

思路:

1 修改手机号这种操作一定是已经登录过token了,所以重新封装request.js使得可以动态获得token

2 然后绑定手机的业务逻辑而已了

3 然后修改state的user信息,然后重新存储一下user信息。

code: 重装request.js(关注验证token部分)

import $C from '@/common/config.js'
import $store from '@/store/index.js'
export default {
	common:{
		method:'GET',
		header:{
			"content-type":"application/json"
		},
		data:{}
	},
	
	request(options = {}){
		
		options.url = $C.webUrl + options.url
		options.method = options.method || this.common.method
		options.header = options.header || this.common.header
		
		// 验证权限token 写到了这里!!!!!!!
		if (options.token) {
			options.header.token = $store.state.token
			if (!options.header.token){
				return uni.showToast({
					title:'非法token,请重新登录',
					icon:'none'
				});
			}
		}
		
		// 该有的参数传入进去,返回了一个promise对象可以直接.then使用了就。
		// ps:之前不写成promise对象是因为,之前没有使用success,fail回掉函数,uniapp自动封装为promise对象。
		// 现在使用了success、fail 所以要自己定制一个promise对象
		return new Promise((resolve,reject)=>{
			uni.request({
				// 类似于python的** 打散
				...options,
				success: (result) => {
					// console.log('####',result)
					// 返回原始数据
					if (options.native){
						return resolve(result)
					}
					// 服务器传来非200 状态码
					if (result.statusCode !== 200){
						uni.showToast({
							title:result.data.msg || '请求失败',
							icon:'none'
						})
						return reject(result.data)
					}
					// 正常返回 服务器返回正常数据,直接取到了服务器传来的data
					resolve(result.data.data)
				},
				// 请求发送失败
				fail:(error) => {
					uni.showToast({
						title:error.errMsg || '请求失败',
						icon:'none'
					})
					return reject()
				}
				
			})
		})
	},
	
	
	get(url, data={}, options={}){
		options.url = url
		options.data = data
		options.method = 'GET'
		return this.request(options)
	},
	
	post(url, data={}, options={}){
		options.url = url
		options.data = data
		options.method = 'POST'
		return this.request(options)
	},
	
}

// ---------------正确的返回方式 success的result--------------
// {
// 	"data": {
// 		"msg": "获取成功",
// 		"data": {
// 			"list": [{
// 				"id": 1,
// 				"classname": "关注"
// 			}, {
// 				"id": 2,
// 				"classname": "推荐"
// 			}, {
// 				"id": 3,
// 				"classname": "体育"
// 			}, {
// 				"id": 4,
// 				"classname": "热点"
// 			}, {
// 				"id": 5,
// 				"classname": "财经"
// 			}, {
// 				"id": 6,
// 				"classname": "娱乐"
// 			}]
// 		}
// 	},
// 	"statusCode": 200,
// 	"header": {
// 		"X-Android-Sent-Millis": "1587476693145",
// 		"Content-Type": "application/json; charset=utf-8",
// 		"_": "HTTP/1.1 200 OK",
// 		"X-Powered-By": "PHP/7.2.13",
// 		"X-Android-Selected-Protocol": "http/1.1",
// 		"Date": "Tue, 21 Apr 2020 13:44:49 GMT",
// 		"Server": "nginx",
// 		"Transfer-Encoding": "chunked",
// 		"X-Android-Response-Source": "NETWORK 200",
// 		"Connection": "keep-alive",
// 		"X-Android-Received-Millis": "1587476693348"
// 	},
// 	"errMsg": "request:ok"
// }


// -------------错误的返回方式 success的result---------------
// {
// 	"data": {
// 		"msg": "服务器异常",
// 		"errorCode": "999"
// 	},
// 	"statusCode": 500,
// 	"header": {
// 		"X-Android-Sent-Millis": "1587476568046",
// 		"Content-Type": "application/json; charset=utf-8",
// 		"_": "HTTP/1.1 500 Internal Server Error",
// 		"X-Powered-By": "PHP/7.2.13",
// 		"X-Android-Selected-Protocol": "http/1.1",
// 		"Date": "Tue, 21 Apr 2020 13:42:44 GMT",
// 		"Server": "nginx",
// 		"Transfer-Encoding": "chunked",
// 		"X-Android-Response-Source": "NETWORK 500",
// 		"Connection": "keep-alive",
// 		"X-Android-Received-Millis": "1587476568104"
// 	},
// 	"errMsg": "request:ok"
// }

code: 更新index.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
	state:{
		loginStatus:false,
		token:false,
		user:{
	// 		"id": 400,
	// 		"username": "17621868045",
	// 		"userpic": null,
	// 		"password": false,
	// 		"phone": "17621868045",
	// 		"email": null,
	// 		"status": 1,
	// 		"create_time": 1587717384,
	// 		"logintype": "phone",
	// 		"token": "3e80c968d8b5610b9fda2341fd0ba43b39c59a40",
	// 		"userinfo": {
	// 			"id": 390,
	// 			"user_id": 400,
	// 			"age": 0,
	// 			"sex": 2,
	// 			"qg": 0,
	// 			"job": null,
	// 			"path": null,
	// 			"birthday": null
	// 		}
		}

	},
	mutations:{
		// 登录
		login(state,user){
			// 更改state中的变量要在这里更改。
			state.loginStatus = true
			state.user = user
			// 登录成功记录一下token
			state.token = state.user.token
			// 永久存储
			uni.setStorageSync('user',JSON.stringify(user));
		},
		
		// 初始化用户登录状态
		initUser(state){
			let user = uni.getStorageSync('user');
			if (user){
				state.user = JSON.parse(user)
				state.loginStatus = true
				// 初始化用户信息记录一下token。
				state.token = state.user.token
			}
		},
		
		// 退出登录
		logout(state){
			state.loginStatus = false
			state.user = {}
			state.token = false
			uni.removeStorageSync('user')
			
		},
		
		// 修改用户信息
		editUserInfo(state,{key,value}){
			// console.log(key,value)
			state.user[key] = value
			uni.setStorageSync('user',JSON.stringify(state.user))
			
		}
		
	}
})

code: user-phone.vue

<template>
	<view>
		<view class="px-4">
			<!-- 手机号 -->
			<view class="flex align-center border-bottom" style="margin-top:100rpx">
				<view class="flex align-center justify-center font-weight-bold  font-md">
					+86
				</view>
				<input class="font-md p-3" type="text"
				value="" placeholder="手机号" 
				v-model="phone"/>
				<!-- <view class="flex align-center justify-center font-weight-bold bg-main">
					+86
				</view> -->
			</view>
			
			<!-- 验证码 -->
			<!-- align-stretch直接保证了各个元素高度的统一,就不只是剧中对齐了 -->
			<view class="flex align-center border-bottom ">
				<input class="flex-1 font-md p-3" type="text"
				value="" placeholder="请输入验证码" 
				v-model="code"/>
				<view class="text-white rounded flex font-md p-1 align-center justify-center bg-main " style="width: 180rpx;"
				@click="getCode"
				:class="codeTime>0 ?'bg-main-disabled':'bg-main'">
					{{codeTime>0 ? codeTime: '获取验证码'}}
				</view>
			</view>
		</view>
		
		<!-- 登录按钮 -->
		<view class="px-3 " style="padding-top:60rpx">
			<button class=" text-white" style="border-radius: 50rpx;border: 0;" type="primary"
			:disabled="disabled"
			:class="disabled?'bg-main-disabled':'bg-main'"
			@click="submit"
			:loading="loading">设置</button>
			<!-- 这个loading bool一旦为true 会显示旋转加载状态并且不可点击 -->
		</view>
		
	</view>
</template>

<script>
	export default {
		data() {
			return {
				phone:"",
				code:"",
				codeTime:0,
				loading:false
			}
		},
		computed:{
			disabled(){
				if (this.phone===""||this.code===""){
					return true
				}
				return false
			}
		},
		methods: {
			// 获取验证码
			getCode(){
				// 防止重复获取
				if (this.codeTime>0){
					return;
				}
				// 验证手机号
				if (!this.validate()) return;
				// 请求数据
				this.$H.post('/user/sendcode',{
					phone:this.phone
				},{
					// 这样原生数据就会传输过来
					native:true
				}).then(res=>{
					// console.log(res)
					uni.showToast({
						title:res.data.msg,
						icon:'none'
					})
				}).catch(err=>{
					// console.log(err)
				})
				
				// 倒计时
				this.codeTime = 5
				// 箭头函数可以直接拿到外面的this的内容
				let timer = setInterval(()=>{
					if (this.codeTime >= 1){
						this.codeTime--
					} else{
						clearInterval(timer)
					}
				},1000)
				
			},
		
			// 表单验证
			validate(){
				//手机号正则 只是针对验证码的手机号字段,其他并未做兼容。
				var mPattern = /^1[34578]\d{9}$/; 
				if (!mPattern.test(this.phone)) {
					uni.showToast({
						title: '手机号格式不正确',
						icon: 'none'
					});
					return false
				}
				// ...更多验证
				return true
			},
			
			submit(){
				this.loading = '设置中...'

				// 表单验证
				if(!this.status){
					if (!this.validate()) return;
				}
				
					
				this.$H.post('/user/bindphone',{
					phone:this.phone,
					code:this.code
				},{
					token:true
				}).then(res=>{
					// console.log(res)
					this.$store.commit('editUserInfo',{
						key:'phone',
						value:this.phone
					})
					
					uni.navigateBack({
						delta:1
					});
					 
					uni.showToast({
						title:'绑定成功',
						icon:'none'
					})
					this.loading = false

				}).catch(err=>{
					this.loading = false
				})
				
			}
				
					
				
		}
	}
</script>

<style>

</style>

posted @ 2020-05-25 18:14  张明岩  阅读(555)  评论(0编辑  收藏  举报