Browse Source

完成注册登录

sslyg 3 years ago
parent
commit
78ca50ce97
13 changed files with 336 additions and 69 deletions
  1. 10 9
      App.vue
  2. 60 0
      http.js
  3. 10 2
      main.js
  4. 12 1
      pages/home/home.vue
  5. 3 3
      pages/register/step1.vue
  6. 11 5
      pages/register/step2.vue
  7. 84 10
      pages/register/step3.vue
  8. 22 5
      pages/user/login.vue
  9. 41 24
      pages/user/setting.vue
  10. 16 10
      pages/user/user-center.vue
  11. 12 0
      store/index.js
  12. 33 0
      store/modules/user.js
  13. 22 0
      verified.js

+ 10 - 9
App.vue

@@ -5,24 +5,25 @@
 		},
 		onShow: function() {
 			console.log('App Show')
+			this.$store.commit("user/save", uni.getStorageSync("userinfo"))
 		},
 		onHide: function() {
 			console.log('App Hide')
-		}
+		},
 	}
 </script>
 
 <style>
-	page{
+	page {
 		background: #F8F8F8;
 	}
+
 	/*每个页面公共css */
-	::-webkit-scrollbar {  
-	    display: none;  
-	    width: 0 !important;  
-	    height: 0 !important;  
-	    -webkit-appearance: none;  
-	    background: transparent;  
+	::-webkit-scrollbar {
+		display: none;
+		width: 0 !important;
+		height: 0 !important;
+		-webkit-appearance: none;
+		background: transparent;
 	}
-
 </style>

+ 60 - 0
http.js

@@ -0,0 +1,60 @@
+import store from './store'
+
+const baseUrl = "http://192.168.1.101:8000/api";
+
+function initPramas() {
+	arguments[0].url = baseUrl + arguments[0].url;
+	// console.log(typeof arguments[0].fail)
+	if (typeof arguments[0].fail === "undefined") {
+		arguments[0].fail = (res) => {
+			console.log(res)
+			uni.showToast({
+				title: res.data.msg,
+				icon: "none"
+			})
+			console.log(res.data.code)
+		}
+	}
+	const success = arguments[0].success
+	arguments[0].success = (res) => {
+		console.log(res)
+		if (res.data.code === 0) {
+			uni.showToast({
+				title: res.data.msg,
+				icon: "none"
+			})
+			arguments[0].fail(res)
+		}
+		if (res.data.code === 1) {
+			success(res)
+		}
+		if (res.data.code === 401) {
+			uni.navigateTo({
+				url: "/pages/user/login"
+			})
+		}
+
+	}
+	if (typeof arguments[0].header === "undefined") {
+		arguments[0].header = {}
+	}
+
+	if (store.state.user.token) {
+		arguments[0].header["HTTP_TOKEN"] = store.state.user.token;
+	}
+	return arguments[0];
+}
+export default {
+	get: function() {
+		let obj = initPramas(arguments[0]);
+		obj.method = "GET";
+		uni.request(obj);
+	},
+	post: function() {
+		let obj = initPramas(arguments[0]);
+		obj.method = "POST";
+		obj.header["Content-type"] = "application/x-www-form-urlencoded"
+		console.log(obj);
+		uni.request(obj);
+	}
+}

+ 10 - 2
main.js

@@ -1,11 +1,19 @@
 import Vue from 'vue'
 import App from './App'
+import http from 'http.js'
+import verified from 'verified.js'
+import store from './store'
 
-Vue.config.productionTip = false
+Vue.prototype.$http = http
+Vue.prototype.$verified = verified
+Vue.prototype.$store = store
 
+Vue.config.productionTip = false
 App.mpType = 'app'
 
 const app = new Vue({
-    ...App
+	...App,
+	store
 })
 app.$mount()
+

+ 12 - 1
pages/home/home.vue

@@ -67,7 +67,18 @@
 		},
 		components: {},
 		onLoad() {
-
+			console.log(this.$http)
+		},
+		onShow() {
+			this.$http.get({
+				url: "/demo/test",
+				data: {
+					category: 'test'
+				},
+				success: (res) => {
+
+				}
+			})
 		},
 		onNavigationBarButtonTap(e) {
 			// console.log(e)

+ 3 - 3
pages/register/step1.vue

@@ -3,13 +3,13 @@
 		<view class="step1-from">
 			<view class="title">填写邀请码</view>
 			<view class="input-item" style="margin-top: 180upx;">
-				<input type="text" placeholder="请输入邀请码">
+				<input type="text" placeholder="请输入邀请码" v-model="invite_code">
 				<view class="scan">
 					<image src="../../static/images/scan.png" mode="scaleToFill" style="width: 46upx;height: 45upx;"></image>
 				</view>
 			</view>
 			<view class="button-item" style="margin-top: 220upx;">
-				<navigator url="/pages/register/step2" open-type="navigate">
+				<navigator :url="'/pages/register/step2?invite_code='+invite_code" open-type="navigate">
 					<button class="next">下一步</button>
 				</navigator>
 			</view>
@@ -22,7 +22,7 @@
 	export default {
 		data() {
 			return {
-
+				invite_code:""
 			}
 		},
 		methods: {

+ 11 - 5
pages/register/step2.vue

@@ -3,17 +3,17 @@
 		<view class="step2-from">
 			<view class="title">请选择角色</view>
 			<view class="role-list">
-				<view class="role-item" @tap="user_type=1" :class="{'selected':user_type===1}">
+				<view class="role-item" @tap="user_type=1" :class="{'selected':user_type===3}">
 					<image src="../../static/images/woman.png" mode="scaleToFill" style="width: 144upx;height: 144upx;"></image>
 					<view class="text"><text>网店店主</text></view>
 				</view>
 				<view class="role-item" @tap="user_type=2" :class="{'selected':user_type===2}">
 					<image src="../../static/images/man.png" mode="scaleToFill" style="width: 144upx;height: 144upx;"></image>
-					<view class="text"><text>供厂家</text></view>
+					<view class="text"><text>供厂家</text></view>
 				</view>
 			</view>
 			<view class="button-item" style="margin-top: 80upx;">
-				<navigator url="/pages/register/step3" open-type="navigate">
+				<navigator :url="'/pages/register/step3?user_type='+user_type+'&invite_code='+invite_code" open-type="navigate">
 					<button class="next">下一步</button>
 				</navigator>
 			</view>
@@ -26,11 +26,15 @@
 	export default {
 		data() {
 			return {
-				user_type: 1
+				user_type: 3,
+				invite_code: "",
 			}
 		},
 		methods: {
 
+		},
+		onLoad: function(option) {
+			this.invite_code = option.invite_code;
 		}
 	}
 </script>
@@ -86,10 +90,12 @@
 			margin: 50upx;
 			text-align: center;
 			position: relative;
-			.text{
+
+			.text {
 				font-size: 30upx;
 				color: #666666;
 			}
+
 			&.selected::after {
 				background-image: url(../../static/images/icon71.png);
 				content: "";

+ 84 - 10
pages/register/step3.vue

@@ -1,28 +1,28 @@
 <template>
 	<view class="step3">
-		<view class="login-from">
+		<view class="login-form">
 			<view class="title">填写资料</view>
 			<view class="input-item">
 				<label for="">
 					<text>中国(+86)</text>
 				</label>
-				<input type="number" placeholder="请输入手机号">
+				<input type="number" placeholder="请输入手机号" v-model="form.mobile">
 			</view>
 			<view class="input-item">
 				<label for="">
 					<text>验证码</text>
 				</label>
-				<input type="number" placeholder="" maxlength="6">
-				<button class="send-vcode">获取验证码</button>
+				<input type="number" placeholder="" maxlength="6" v-model="form.code">
+				<button class="send-vcode" @tap="sendSms()" :disabled="!sendable">{{sendable?'获取验证码':countdown+'秒'}}</button>
 			</view>
 			<view class="input-item">
 				<label for="">
 					<text>密码</text>
 				</label>
-				<input type="password" placeholder="请输入密码">
+				<input type="password" placeholder="请输入密码" v-model="form.password">
 			</view>
 			<view class="button-item" style="margin-top: 80upx;">
-				<button class="confirm">注册</button>
+				<button class="confirm" @tap="register()">注册</button>
 			</view>
 			<view class="agreement">
 				<view>
@@ -41,14 +41,87 @@
 </template>
 
 <script>
+	let timeInterval = null;
+	const time = 120
 	export default {
 		data() {
 			return {
-
+				sendable: true,
+				countdown: time,
+				form: {
+					username: "",
+					mobile: "",
+					code: "",
+					password: "",
+					user_type: 3,
+					invite_code: "",
+				}
 			}
 		},
 		methods: {
+			register() {
+				if (this.$verified.mobile(this.form.mobile) &&
+					this.$verified.required(this.form.code, "请输入手机验证码") &&
+					this.$verified.required(this.form.password, "请输入密码")) {
+					this.form.username = this.form.mobile;
+					this.$http.post({
+						url: "/user/register",
+						data: this.form,
+						success(res) {
+							uni.showToast({
+								title: res.data.msg,
+								icon: "none",
+								success: () => {
+									setTimeout(() => {
+										uni.navigateBack({
+											delta: 999,
+											animationType:'none'
+										})
+										uni.navigateTo({
+											url: '/pages/user/login'
+										})
+									}, 1500)
+								}
+							})
+						}
+					})
+
+				}
+			},
+			sendSms() {
+				if (this.sendable && this.$verified.mobile(this.form.mobile)) {
+					this.sendable = false;
+
+					this.$http.get({
+						url: '/sms/send',
+						data: {
+							mobile: this.form.mobile,
+							event: "register"
+						},
+						success: (res) => {
+							uni.showToast({
+								title: res.data.msg,
+								icon: "none"
+							})
+							timeInterval = setInterval(() => {
+								if (this.countdown-- === 0) {
+									clearInterval(timeInterval)
+									this.countdown = time;
+									this.sendable = true;
+								}
+							}, 1000)
+						},
+						fail: () => {
+							this.sendable = true;
+						}
+					})
+				}
+			},
 
+		},
+		onLoad: function(option) {
+			this.form.invite_code = option.invite_code;
+			this.form.user_type = option.user_type;
 		}
 	}
 </script>
@@ -61,7 +134,7 @@
 		overflow: hidden;
 	}
 
-	.login-from {
+	.login-form {
 		margin: auto;
 		width: 600upx;
 		height: 700upx;
@@ -101,6 +174,7 @@
 		position: relative;
 		margin-bottom: 30upx;
 		border-bottom: 2upx solid $primary-color;
+		align-items: center;
 
 		label {
 			width: 158upx;
@@ -110,7 +184,7 @@
 
 		input {
 			flex-grow: 1;
-			padding: 5upx;
+			padding: 10upx 5upx;
 			font-size: 30upx;
 		}
 	}
@@ -138,7 +212,7 @@
 		width: 160upx;
 		line-height: normal;
 		right: 0upx;
-		top: -5upx;
+		top: 10upx;
 	}
 
 	.agreement {

+ 22 - 5
pages/user/login.vue

@@ -8,13 +8,13 @@
 				<label for="">
 					<image src="../../static/images/login/phone.png" style="width: 30upx;height: 40upx;" mode=""></image>
 				</label>
-				<input type="text" placeholder="请输入账号">
+				<input type="text" placeholder="请输入账号" v-model="account">
 			</view>
 			<view class="input-item" style="margin-bottom: 20upx;">
 				<label for="">
 					<image src="../../static/images/login/lock.png" style="width: 30upx;height: 40upx;" mode=""></image>
 				</label>
-				<input type="text" placeholder="请输入密码">
+				<input type="password" placeholder="请输入密码" v-model="password">
 			</view>
 			<view class="forget">
 				<navigator url="/pages/user/find-pass" open-type="navigate" style="display: inline;">
@@ -22,7 +22,7 @@
 				</navigator>
 			</view>
 			<view class="button-item">
-				<button class="login-btn">登录</button>
+				<button class="login-btn" @tap="login()">登录</button>
 			</view>
 			<view class="button-item">
 				<navigator url="/pages/register/step1" open-type="navigate">
@@ -49,11 +49,28 @@
 	export default {
 		data() {
 			return {
-
+				account: '',
+				password: ''
 			}
 		},
 		methods: {
-
+			login() {
+				if (this.$verified.account(this.account) &&
+					this.$verified.required(this.password, "请输入密码")) {
+					this.$http.post({
+						url: "/user/login",
+						data: {
+							account: this.account,
+							password: this.password
+						},
+						success: (res) => {
+							console.log(this.$store)
+							this.$store.dispatch("user/save", res.data.data.userinfo)
+							uni.navigateBack();
+						}
+					})
+				}
+			}
 		}
 	}
 </script>

+ 41 - 24
pages/user/setting.vue

@@ -26,7 +26,7 @@
 				<view class="option">未绑定</view>
 			</view>
 		</view>
-		
+
 		<view class="block b3">
 			<view class="row">
 				<view class="label">修改手机号 <text class="info">18111897865</text></view>
@@ -38,18 +38,16 @@
 				<view class="option"></view>
 			</view>
 		</view>
-		
+
 		<view class="block b4">
 			<view class="row">
 				<view class="label">清除缓存 <text class="info">18.20MB</text></view>
 				<view class="option"><button class="clear-cache-btn" type="default">清除缓存</button></view>
 			</view>
 		</view>
-		
+
 		<view class="logout-block">
-			<navigator url="/pages/user/login" open-type="navigate">
-				<button class="logout-btn" type="default">退出登录</button>
-			</navigator>
+			<button class="logout-btn" type="default" @tap="logout()">退出登录</button>
 		</view>
 	</view>
 </template>
@@ -62,18 +60,28 @@
 			}
 		},
 		methods: {
-
+			logout() {				
+				uni.navigateBack({
+					delta: 999,
+					animationType:'none'
+				})
+				uni.navigateTo({
+					url: '/pages/user/login'
+				})
+				this.$store.dispatch("user/logout")
+			}
 		}
 	}
 </script>
 
 <style lang="scss" scoped>
-	.setting{
+	.setting {
 		overflow: hidden;
 		position: relative;
-		
+
 	}
-	.header-bg{
+
+	.header-bg {
 		background-color: $primary-color;
 		height: 120upx;
 		position: absolute;
@@ -81,45 +89,52 @@
 		width: 100%;
 		z-index: 1;
 	}
-	.portrait{
-		justify-content: center!important;
-		margin-top:20upx;
-		.image{
+
+	.portrait {
+		justify-content: center !important;
+		margin-top: 20upx;
+
+		.image {
 			width: 168upx;
 			height: 168upx;
 			border: 10upx solid $primary-color;
 			border-radius: 100upx;
 		}
 	}
-	
-	.block{
+
+	.block {
 		border-radius: 20upx;
 		background-color: white;
 		margin: 20upx;
 		position: relative;
 		overflow: hidden;
 		z-index: 2;
-		.row{
+
+		.row {
 			display: flex;
 			justify-content: space-between;
 			padding: 20upx 40upx;
 			align-items: center;
 			font-size: 28upx;
-			.info{
+
+			.info {
 				color: #999999;
 				font-size: 24upx;
 				display: inline-block;
 				margin-left: 20upx;
 			}
-			.option{
+
+			.option {
 				color: #999999;
 			}
 		}
 	}
-	.logout-block{
+
+	.logout-block {
 		margin: 20upx;
 	}
-	.clear-cache-btn{
+
+	.clear-cache-btn {
 		line-height: normal;
 		padding: 4upx 20upx;
 		background: white;
@@ -128,14 +143,16 @@
 		border-radius: 50upx;
 		color: $primary-color;
 	}
-	.logout-btn{
+
+	.logout-btn {
 		background: $primary-color;
 		color: white;
 		font-size: 30upx;
 		line-height: 80upx;
 	}
-	.line{
+
+	.line {
 		border: 2upx solid #EEEEEE;
-		transform: scale(0.9,0.5);
+		transform: scale(0.9, 0.5);
 	}
 </style>

+ 16 - 10
pages/user/user-center.vue

@@ -5,7 +5,7 @@
 				<image class="image" src="../../static/images/login/logo.png" mode="scaleToFill"></image>
 			</view>
 			<view>
-				<view class="nickname">未设置昵称</view>
+				<view class="nickname">{{nickname}}</view>				
 				<view>
 					<text v-show="user_type===1" class="wddz">网店店主</text>
 					<text v-show="user_type===2" class="zgcj">直供厂家</text>
@@ -71,18 +71,18 @@
 			<view class="menu">
 				<view>
 					<navigator url="/pages/user/problem" open-type="navigate">
-					<view class="icon">
-						<image class="image" src="../../static/images/menu/b3.png" mode=""></image>
-					</view>
-					<view class="name">常见问题</view>
+						<view class="icon">
+							<image class="image" src="../../static/images/menu/b3.png" mode=""></image>
+						</view>
+						<view class="name">常见问题</view>
 					</navigator>
 				</view>
 				<view>
 					<navigator url="/pages/user/kefu" open-type="navigate">
-					<view class="icon">
-						<image class="image" src="../../static/images/menu/b4.png" mode=""></image>
-					</view>
-					<view class="name">联系客服</view>
+						<view class="icon">
+							<image class="image" src="../../static/images/menu/b4.png" mode=""></image>
+						</view>
+						<view class="name">联系客服</view>
 					</navigator>
 				</view>
 				<view>
@@ -105,15 +105,21 @@
 </template>
 
 <script>
+	import {
+		mapState
+	} from 'vuex'
+
 	export default {
 		data() {
 			return {
-				nickname: '',
 				balance: '',
 				deposit: '',
 				user_type: 1,
 			};
 		},
+		computed: mapState({
+			nickname: state => state.user.nickname
+		}),
 		onNavigationBarButtonTap(e) {
 			// console.log(e)
 			switch (e.index) {

+ 12 - 0
store/index.js

@@ -0,0 +1,12 @@
+import Vue from 'vue'
+import Vuex from 'vuex'
+import user from './modules/user'
+
+Vue.use(Vuex)
+
+export default new Vuex.Store({
+	modules: {
+		user
+	},
+	strict: true
+})

+ 33 - 0
store/modules/user.js

@@ -0,0 +1,33 @@
+const defaults = {
+	nickname: "未设置昵称"
+}
+const state = JSON.parse(JSON.stringify(defaults));
+
+const getters = {
+	// token: (state) => state.token
+
+}
+const mutations = {
+	save(state, payload) {
+		Object.assign(state, payload)
+	}
+}
+const actions = {
+	save(context, payload) {
+		uni.setStorageSync("userinfo", payload)
+		context.commit('save', payload)
+	},
+	logout(context) {
+		uni.removeStorageSync("userinfo")
+		context.commit('save', defaults)
+	}
+}
+
+
+export default {
+	namespaced: true,
+	state,
+	getters,
+	actions,
+	mutations
+}

+ 22 - 0
verified.js

@@ -0,0 +1,22 @@
+export default {
+	required(str, msg) {
+		return str.length > 0 || tips(msg)
+	},
+	mobile(str) {
+		return /^1\d{10}$/.test(str) || tips("请输入正确的手机号")
+	},
+	account(str) {
+		return /^1\d{10}$/.test(str) || tips("请输入正确的手机号")
+	},
+	password(str) {
+		return /^[0-9a-z<>?:"|{},./;'/[]]{6,20}$/i.test(str) || tips("密码必须为6至20位数字与字母的组合")
+	}
+}
+
+function tips(msg) {
+	uni.showToast({
+		title: msg,
+		icon: "none"
+	})
+	return false;
+}