408249787 3 settimane fa
parent
commit
94050e4aa8

+ 11 - 10
pages/index/home.uvue

@@ -68,6 +68,10 @@ const icons = {
 const selected = ref<string>('physics')
 function handlePage(val: any) {
 	if (val.code === 'user') {
+		if (user.token === 'Basic ZW5kOmVuZA==') {
+			router.push({ path: '/pages/user/login' })
+			return
+		}
 		router.push({ path: '/pages/user/info' })
 		return
 	}
@@ -130,7 +134,7 @@ const handleBind = async () => {
 		success: async (res) => {
 			await bindWechatOpenId({ code: res.code })
 			uni.showToast({
-				title: '授权成功,请重新登录'
+				title: '授权成功'
 			})
 			await user.get()
 		}
@@ -198,8 +202,7 @@ async function handleExchange() {
 		<cl-popup v-model="visible" :size="400" :show-header="false" direction="center">
 			<view class="flex flex-col items-center justify-center gap-4 py-7 bg-slate-50">
 				<cl-text class="text-center " color="#09ba07" :size="30"> ——专属服务内容—— </cl-text>
-				<image src="https://oss.xiaoxiongcode.com/static/home/qr.png" show-menu-by-longpress
-					class="w-32 h-32" />
+				<image src="https://oss.xiaoxiongcode.com/static/home/qr.png" show-menu-by-longpress class="w-32 h-32" />
 				<view class="text-center "> <cl-text class="text-center" color="#999" :size="14"> 长按识别二维码 </cl-text>
 					<cl-text class="text-center" color="#999" :size="14"> 添加微信,享专业老师服务 </cl-text>
 				</view>
@@ -209,11 +212,11 @@ async function handleExchange() {
 			<view class="flex flex-col items-center justify-center gap-4 py-7 bg-slate-50">
 				<cl-text class="text-center " color="#09ba07" :size="30"> ——会员福利—— </cl-text>
 				<image src="https://oss.xiaoxiongcode.com/static/home/coding.png" class="w-32 h-32" />
-				<view class="text-center " v-if="userInfo?.memberLevel !== 'default'">
+				<view class="text-center " v-if="userInfo && userInfo?.memberLevel !== 'default'">
 					<cl-text class="text-center" color="#999" :size="14">账号:小程序登录手机账号 </cl-text>
 					<cl-text class="text-center" color="#999" :size="14"> 密码:初始密码为123456 </cl-text>
-					<cl-text class="text-center" v-if="userInfo && !userInfo.roleCodes?.includes('show_time')"
-						color="#999" :size="14">少儿编程网址: www.xiaoxiongcode.com </cl-text>
+					<cl-text class="text-center" v-if="userInfo && !userInfo.roleCodes?.includes('show_time')" color="#999"
+						:size="14">少儿编程网址: www.xiaoxiongcode.com </cl-text>
 					<cl-text class="text-center" v-else color="#999" :size="14">少儿编程网址: ************* </cl-text>
 					<cl-button type="primary" size="small" @tap="copyUrl"> 复制网址 </cl-button>
 				</view>
@@ -226,8 +229,7 @@ async function handleExchange() {
 			<view class="flex flex-col items-center justify-center gap-4 py-7 bg-slate-50">
 				<cl-text class="text-center " color="#333" :size="25"> ——激活会员—— </cl-text>
 
-				<input
-					class="w-[200px] h-[40px] bg-[#F5F5F5] border-[1px] border-[#333] border-solid rounded-[20px] px-[10px]"
+				<input class="w-[200px] h-[40px] bg-[#F5F5F5] border-[1px] border-[#333] border-solid rounded-[20px] px-[10px]"
 					v-model="code" placeholder="请输入兑换码"></input>
 
 				<cl-button class="mt-4" size="large" type="primary" block @tap="handleExchange"> 兑换 </cl-button>
@@ -240,8 +242,7 @@ async function handleExchange() {
 			}
 		}">
 			<view class="w-[360px]  relative">
-				<image src="https://oss.xiaoxiongcode.com/static/home/6171.png" mode="widthFix"
-					class="w-[360px]  relative ">
+				<image src="https://oss.xiaoxiongcode.com/static/home/6171.png" mode="widthFix" class="w-[360px]  relative ">
 				</image>
 				<view class=" wz-1  ">
 					您当前未绑定微信,是否绑定微信?

+ 6 - 0
pages/test/index.uvue

@@ -47,6 +47,12 @@ onMounted(async () => {
 const cardsScrollView = ref<any>(null)
 
 function handleDetail(item: SubjectCourseTestResult) {
+  if (user.token === 'Basic ZW5kOmVuZA==') {
+    router.push({
+      path: "/pages/user/login",
+    });
+    return
+  }
   if (item?.lockFlag) return
   router.push({
     path: "/pages/catalog/web-view",

+ 26 - 7
pages/user/components/password.uvue

@@ -1,15 +1,34 @@
 <template>
 	<view class="flex flex-col w-[80vw]">
-		<view class="mb-3 flex flex-row ">
-			<cl-input class="" :pt="{ className: '!h-[40px] !rounded-xxl !px-4 !w-[80vw]' }" v-model="form.username"
-				placeholder="请输入手机号"></cl-input>
-		</view>
-
-		<view class="relative flex flex-row items-center mb-5">
+		<cl-form-item prop="username" required :pt="{
+			className: '!mb-4'
+		}" :rules="[
+			{
+				required: true,
+				message: '用户名不能为空'
+			}
+		] as ClFormRule[]
+			">
+			<cl-input clearable class="" :pt="{ className: '!h-[40px] !rounded-xxl !px-4 !w-[80vw]' }" v-model="form.username"
+				placeholder="请输入用户名"></cl-input>
+		</cl-form-item>
+		<cl-form-item prop="password" required :pt="{
+			className: '!mb-4'
+		}" :rules="[
+			{
+				required: true,
+				message: '密码不能为空'
+			}, {
+				min: 6,
+				max: 12,
+				message: '密码长度必须在6到16位之间'
+			}
+		] as ClFormRule[]
+			">
 			<cl-input :pt="{ className: '!h-[40px] !rounded-xxl !px-4 !w-[80vw]' }" clearable v-model="form.password" password
 				placeholder="请输入密码">
 			</cl-input>
-		</view>
+		</cl-form-item>
 
 
 	</view>

+ 79 - 0
pages/user/components/register.uvue

@@ -0,0 +1,79 @@
+<template>
+	<view class=" w-[80vw]">
+		<cl-form-item prop="username" required :pt="{
+			className: '!mb-4'
+		}" :rules="[
+			{
+				required: true,
+				message: '用户名不能为空'
+			}
+		] as ClFormRule[]
+			">
+			<cl-input clearable class="" :pt="{ className: '!h-[40px] !rounded-xxl !px-4 !w-[80vw]' }" v-model="form.username"
+				placeholder="请输入用户名(必填)"></cl-input>
+		</cl-form-item>
+		<cl-form-item prop="password" required :pt="{
+			className: '!mb-4'
+		}" :rules="[
+			{
+				required: true,
+				message: '密码不能为空'
+			}, {
+				min: 6,
+				max: 12,
+				message: '密码长度必须在6到16位之间'
+			}
+		] as ClFormRule[]
+			">
+			<cl-input :pt="{ className: '!h-[40px] !rounded-xxl !px-4 !w-[80vw]' }" clearable v-model="form.password" password
+				placeholder="请输入密码(必填)">
+			</cl-input>
+		</cl-form-item>
+		<cl-form-item prop="confirmPassword" required :pt="{
+			className: '!mb-4'
+		}" :rules="[
+			{
+				required: true,
+				message: '确认密码不能为空'
+			}, {
+				validator: (val: string) => val === form.password,
+				message: '两次密码输入不一致'
+			}
+		] as ClFormRule[]
+			">
+			<cl-input :pt="{ className: '!h-[40px] !rounded-xxl !px-4 !w-[80vw]' }" clearable v-model="form.confirmPassword"
+				password placeholder="请确认密码(必填)">
+			</cl-input>
+		</cl-form-item>
+		<cl-form-item :pt="{
+			className: '!mb-4'
+		}" prop="realName">
+			<cl-input clearable :pt="{ className: '!h-[40px] !rounded-xxl !px-4 !w-[80vw]' }" v-model="form.realName"
+				placeholder="请输入姓名"></cl-input>
+		</cl-form-item>
+		<cl-form-item :pt="{
+			className: '!mb-4'
+		}" prop="phone">
+			<cl-input clearable :pt="{ className: '!h-[40px] !rounded-xxl !px-4 !w-[80vw]' }" v-model="form.phone"
+				placeholder="请输入手机号"></cl-input>
+		</cl-form-item>
+	</view>
+</template>
+
+<script setup lang="ts">
+import { type PropType } from "vue";
+import type { LoginForm } from "./types";
+import { useRefs, } from "@/.cool";
+
+const props = defineProps({
+	form: {
+		type: Object as PropType<LoginForm>,
+		default: () => ({})
+	}
+});
+
+const emit = defineEmits(["success"]);
+
+const refs = useRefs();
+
+</script>

+ 3 - 0
pages/user/components/types.ts

@@ -6,4 +6,7 @@ export type LoginForm = {
 	scope: string;
 	code: string;
 	loginType: number;
+	confirmPassword?: string;
+	realName?: string;
+	phone?: string;
 };

+ 103 - 56
pages/user/login.uvue

@@ -4,40 +4,46 @@
 		<!-- <cl-image src="https://oss.xiaoxiongcode.com/static/home/1.jpg" mode="heightFix" class="w-full h-full object-cover"
 			height="100%" width="100%" /> -->
 		<view class="content">
-			<view class="title">
-				<cl-image src="https://oss.xiaoxiongcode.com/static/home/logo.png" width="120px" height="120px"
-					mode="heightFix" />
 
-				<cl-text :size="20" color="#666">
-					少儿物理启蒙
-				</cl-text>
-			</view>
 			<view class="group">
+				<view class="title">
+					<cl-image src="https://oss.xiaoxiongcode.com/static/home/logo.png" width="120px" height="120px"
+						mode="heightFix" />
+
+					<cl-text :size="20" color="#666">
+						少儿物理启蒙
+					</cl-text>
+				</view>
 				<view class="w-[80vw]">
 					<!-- <cl-tabs v-model="val" :list="list" fill :form="formData" @change="tabsChange"></cl-tabs> -->
-					<cl-form v-model="formData" :pt="{ className: 'mt-1' }">
+					<cl-form v-model="formData" ref="formRef" :pt="{ className: 'mt-1' }">
 						<view v-if="val === 'quickly_login'">
 							<phone :form="formData" />
 						</view>
 						<view v-else-if="val === 'password'">
 							<password :form="formData" />
 						</view>
+						<view v-else-if="val === 'register'">
+							<register :form="formData" />
+						</view>
 
 						<view class="flex flex-row items-center justify-center mb-5">
-							<cl-button v-if="val === 'weixin'"
-								:pt="{ className: '!h-[45px] !rounded-full w-[200px] mx-auto' }" type="success"
-								@tap="toWechatLogin">
+							<cl-button v-if="val === 'weixin'" :pt="{ className: '!h-[45px] !rounded-full w-[200px] mx-auto' }"
+								type="success" @tap="toWechatLogin">
 								<view class="flex flex-row items-center justify-center">
-									<cl-image src="https://oss.xiaoxiongcode.com/static/个人中心/微信.png" mode="heightFix"
-										height="20px" width="auto"></cl-image>
+									<cl-image src="https://oss.xiaoxiongcode.com/static/个人中心/微信.png" mode="heightFix" height="20px"
+										width="auto"></cl-image>
 									<view class="ml-2">
 										微信快捷登录
 									</view>
 								</view>
 							</cl-button>
+							<cl-button v-else-if="val === 'register'" :disabled="!agree || !agree2"
+								:pt="{ className: '!h-[45px] !rounded-full w-[200px] mx-auto' }" :loading="loading" @tap="toRegister">
+								注册并登录
+							</cl-button>
 							<cl-button v-else :disabled="!agree || !agree2"
-								:pt="{ className: '!h-[45px] !rounded-full w-[200px] mx-auto' }" :loading="loading"
-								@tap="toLogin">
+								:pt="{ className: '!h-[45px] !rounded-full w-[200px] mx-auto' }" :loading="loading" @tap="toLogin">
 								登录
 							</cl-button>
 						</view>
@@ -75,10 +81,10 @@
 					</view>
 				</view>
 				<view v-if="val !== 'quickly_login'">
-					<cl-button type="info" :pt="{ className: '!h-[40px] !rounded-full w-[40px] mx-auto !p-1' }"
-						:loading="loading" @tap="tabsChange('quickly_login')">
-						<cl-image src="https://oss.xiaoxiongcode.com/static/home/phone.svg" mode="heightFix"
-							height="20px" width="auto"></cl-image>
+					<cl-button type="info" :pt="{ className: '!h-[40px] !rounded-full w-[40px] mx-auto !p-1' }" :loading="loading"
+						@tap="tabsChange('quickly_login')">
+						<cl-image src="https://oss.xiaoxiongcode.com/static/home/phone.svg" mode="heightFix" height="20px"
+							width="auto"></cl-image>
 					</cl-button>
 					<view class="mt-1">
 						<cl-text :size="14" color="#666">
@@ -87,10 +93,10 @@
 					</view>
 				</view>
 				<view v-if="val !== 'password'">
-					<cl-button type="info" :pt="{ className: '!h-[40px] !rounded-full w-[40px] mx-auto !p-1' }"
-						:loading="loading" @tap="tabsChange('password')">
-						<cl-image src="https://oss.xiaoxiongcode.com/static/home/password.svg" mode="heightFix"
-							height="20px" width="auto"></cl-image>
+					<cl-button type="info" :pt="{ className: '!h-[40px] !rounded-full w-[40px] mx-auto !p-1' }" :loading="loading"
+						@tap="tabsChange('password')">
+						<cl-image src="https://oss.xiaoxiongcode.com/static/home/password.svg" mode="heightFix" height="20px"
+							width="auto"></cl-image>
 					</cl-button>
 					<view class="mt-1">
 						<cl-text :size="14" color="#666">
@@ -99,6 +105,12 @@
 					</view>
 				</view>
 			</view>
+			<view v-if="val !== 'register'"
+				class="absolute bottom-12 w-full flex flex-row  gap-4 items-center justify-center">
+				<cl-text :size="14" color="primary" @tap="tabsChange('register')">
+					注册账号
+				</cl-text>
+			</view>
 		</view>
 		<cl-action-sheet ref="actionSheetRef">
 			<template #prepend>
@@ -115,14 +127,13 @@
 			}
 		}">
 			<view class="w-[330px]  relative">
-				<image src="https://oss.xiaoxiongcode.com/static/home/6172.png" mode="widthFix"
-					class="w-[330px]  relative ">
+				<image src="https://oss.xiaoxiongcode.com/static/home/6172.png" mode="widthFix" class="w-[330px]  relative ">
 				</image>
 				<view class=" wz-1  ">
 					当前微信账号,<br />尚未绑定,<br />无法快捷登录
 				</view>
 				<view class="wz-2  " @tap="handleClosePopup">
-					手机登录
+					立即登录
 				</view>
 			</view>
 		</cl-popup>
@@ -134,19 +145,21 @@ import Back from '@/components/back.uvue'
 import type { LoginForm } from "./components/types";
 import phone from './components/phone.uvue';
 import password from './components/password.uvue';
+import register from './components/register.uvue';
 import { ref } from 'vue'
 import type { ClTabsItem } from "@/uni_modules/cool-ui";
 import { encryptPassword, user, router } from '@/.cool';
-import { loginApi, wechatLogin, quicklyRegister } from "@/services/user";
+import { loginApi, wechatLogin, quicklyRegister, selfRegister } from "@/services/user";
 import type { ClActionSheetOptions } from "@/uni_modules/cool-ui";
+import { type ClFormRule, useForm } from "@/uni_modules/cool-ui";
 
 const actionSheetRef = ref<ClActionSheetComponentPublicInstance | null>(null);
 const visible = ref(false)
-
+const { formRef, validate, clearValidate } = useForm();
 const val = ref('weixin')
 const agree = ref(false)
 const agree2 = ref(false)
-const list: ClTabsItem[] = [
+const list = [
 	{
 		label: '验证码登录',
 		value: 'quickly_login'
@@ -159,6 +172,10 @@ const list: ClTabsItem[] = [
 		label: '微信登录',
 		value: 'weixin'
 	},
+	{
+		label: '注册账号',
+		value: 'register'
+	}
 ]
 const formData = ref<LoginForm>({
 	username: '',
@@ -184,34 +201,64 @@ function tabsChange(type: string) {
 		formData.value.code = ''
 	}
 }
+async function toRegister() {
+	validate(async (valid, errors) => {
+		if (valid) {
+			try {
+				await selfRegister(formData.value)
+				uni.showToast({
+					title: '注册成功',
+					icon: 'success'
+				})
+				handleSelect(formData.value.username)
+			} catch (error) {
+				uni.showToast({
+					title: '注册失败',
+					icon: 'none'
+				})
+			}
+		} else {
+			// 验证不通过,可以提示错误信息 errors
+			console.log(formData.value, 2);
+		}
+	});
+}
 function toLogin() {
-	// loading.value = true
-	console.log(formData.value);
-	loginApi({
-		...formData.value,
-		password: formData.value.password && encryptPassword(formData.value.password),
-	}).then(res => {
-		user.setToken(res)
-		uni.showToast({
-			title: '登录成功',
-			icon: 'success'
-		})
-		router.home();
-	}).catch(err => {
-		if (err.message == '手机号不存在' && val.value === 'quickly_login') {
-			quicklyRegister({
-				username: formData.value.username,
-				password: 'ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413',
+	loading.value = true
+	validate((valid, errors) => {
+		if (valid) {
+			console.log(formData.value);
+			loginApi({
+				...formData.value,
+				password: formData.value.password && encryptPassword(formData.value.password),
 			}).then(res => {
-				handleSelect(formData.value.username)
+				user.setToken(res)
+				uni.showToast({
+					title: '登录成功',
+					icon: 'success'
+				})
+				router.home();
+			}).catch(err => {
+				if (err.message == '手机号不存在' && val.value === 'quickly_login') {
+					quicklyRegister({
+						username: formData.value.username,
+						password: 'ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413',
+					}).then(res => {
+						handleSelect(formData.value.username)
+					})
+				} else {
+					uni.showToast({
+						title: err.message,
+						icon: 'none'
+					})
+				}
 			})
 		} else {
-			uni.showToast({
-				title: err.message,
-				icon: 'none'
-			})
+			// 验证不通过,可以提示错误信息 errors
+			loading.value = false
+			console.log(formData.value, 2);
 		}
-	})
+	});
 }
 function handleClosePopup() {
 	visible.value = false
@@ -297,17 +344,17 @@ function toPrivacy() {
 
 
 .title {
-	position: absolute;
-	top: 10%;
 	//设置字间距
 	letter-spacing: 0.1em;
+	margin-bottom: 20px;
 	@apply flex flex-col w-full items-center justify-center;
 }
 
 .group {
-	@apply absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-white px-4 py-2 pb-10 rounded-xl;
+	@apply absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 px-4 py-2 pb-10 rounded-xl;
 	display: flex;
+	height: 80%;
 	align-items: center;
-	flex-direction: row;
+	flex-direction: column;
 }
 </style>

+ 3 - 0
services/user.ts

@@ -81,4 +81,7 @@ export function wechatPayCancel(parameter: any) {
 }
 export function quicklyRegister(params) {
   return usePost(`/upms/users/register/quickly`, params) as Promise<any>
+}
+export function selfRegister(params) {
+  return usePost(`/upms/users/register/self`, params) as Promise<any>
 }