feat: 验证码流程
parent
236a33c8ac
commit
1f3d5cfb04
|
|
@ -27,11 +27,34 @@
|
||||||
src="https://api.static.ycymedu.com/images/logo.png"
|
src="https://api.static.ycymedu.com/images/logo.png"
|
||||||
mode="aspectFit"
|
mode="aspectFit"
|
||||||
></image>
|
></image>
|
||||||
<view
|
<button
|
||||||
class="px-[32rpx] py-[16rpx] bg-[#3370FF] rounded-[40rpx] text-white text-[32rpx] font-medium flex items-center justify-center"
|
class="w-[493rpx]! mb-[40rpx] h-[88rpx]! rounded-[44rpx] text-[32rpx] text-white flex items-center justify-center"
|
||||||
@click="handleLogin"
|
:class="checked.length > 0 ? 'bg-[#1580FF]' : 'bg-[#BFBFBF]'"
|
||||||
|
@click.stop="handleClick"
|
||||||
|
open-type="getPhoneNumber"
|
||||||
|
@getphonenumber="getPhoneNumber"
|
||||||
|
:disabled="checked.length === 0"
|
||||||
>
|
>
|
||||||
立即登录
|
一键登录
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<view class="flex items-center flex-nowrap">
|
||||||
|
<CheckboxGroup v-model="checked" class="check-class mr-[10rpx]">
|
||||||
|
<Checkbox name="1" cell shape="button" class="custom-checkbox"></Checkbox>
|
||||||
|
</CheckboxGroup>
|
||||||
|
|
||||||
|
<view class="flex items-center">
|
||||||
|
<text class="text-[24rpx] whitespace-nowrap">
|
||||||
|
已阅读并同意
|
||||||
|
<text class="text-[#1580FF]" @click.stop="handleClickUserAgreement">
|
||||||
|
<text>《用户协议》</text>
|
||||||
|
</text>
|
||||||
|
和
|
||||||
|
<text class="text-[#1580FF]" @click.stop="handleClickPrivacyPolicy">
|
||||||
|
<text>《隐私条款》</text>
|
||||||
|
</text>
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<LoginMask v-model:show="show" @auth-ready="handleAuthReady" />
|
<LoginMask v-model:show="show" @auth-ready="handleAuthReady" />
|
||||||
|
|
@ -41,11 +64,54 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import LoginMask from './components/LoginMask.vue'
|
import LoginMask from './components/LoginMask.vue'
|
||||||
import Navbar from './components/navbar/Navbar.vue'
|
import Navbar from './components/navbar/Navbar.vue'
|
||||||
|
import { useUserStore } from '@/store/user'
|
||||||
|
import {
|
||||||
|
getSessionKey,
|
||||||
|
getVolunteerInitialization,
|
||||||
|
getWxUserInfo,
|
||||||
|
setWxInfo,
|
||||||
|
} from '@/service/index/api'
|
||||||
|
import { City } from '@/types/app-type'
|
||||||
|
import Checkbox from './components/check-group/Checkbox.vue'
|
||||||
|
import CheckboxGroup from './components/check-group/CheckboxGroup.vue'
|
||||||
|
import { useLogin } from '@/login-sub/hooks/useUserInfo'
|
||||||
|
|
||||||
const show = ref(false)
|
const show = ref(false)
|
||||||
|
|
||||||
const handleLogin = () => {
|
const checked = ref([]) // 是否同意条款
|
||||||
show.value = true
|
const getPhoneInfo = ref(null)
|
||||||
|
|
||||||
|
const getPhoneNumber = async (e: any) => {
|
||||||
|
if (e.detail.errMsg == 'getPhoneNumber:ok') {
|
||||||
|
const detail = e.detail
|
||||||
|
let _getPhoneInfo = {
|
||||||
|
iv: detail.iv,
|
||||||
|
encryptedData: detail.encryptedData,
|
||||||
|
code: detail.code,
|
||||||
|
}
|
||||||
|
getPhoneInfo.value = _getPhoneInfo
|
||||||
|
await getUserInfo(detail.code)
|
||||||
|
} else if (e.detail.errMsg == 'getPhoneNumber:fail not login') {
|
||||||
|
uni.showToast({
|
||||||
|
title: '请先登录',
|
||||||
|
icon: 'none',
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: '获取手机号失败',
|
||||||
|
icon: 'none',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleClick = () => {
|
||||||
|
if (!checked.value) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '您需先同意《服务条款》和《隐私条款》',
|
||||||
|
icon: 'none',
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 授权完成之后返回到上一个目录去
|
// 授权完成之后返回到上一个目录去
|
||||||
|
|
@ -56,4 +122,113 @@ const handleAuthReady = () => {
|
||||||
const handleClickLeft = () => {
|
const handleClickLeft = () => {
|
||||||
uni.navigateBack()
|
uni.navigateBack()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleClickUserAgreement = () => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/login-sub/userAgreement',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleClickPrivacyPolicy = () => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/login-sub/privacyPolicy',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
const getUserInfo = async (_code: string) => {
|
||||||
|
let userInfo = (await useLogin()) as { code: string; errMsg: string }
|
||||||
|
|
||||||
|
if (userInfo.errMsg == 'login:ok') {
|
||||||
|
const resp = await getSessionKey({ JsCode: userInfo.code })
|
||||||
|
if (resp.code == 200) {
|
||||||
|
const result = resp.result as { accessToken: string; openId: string }
|
||||||
|
userStore.setUserToken(result.accessToken)
|
||||||
|
userStore.setUserOpenId(result.openId)
|
||||||
|
|
||||||
|
setWxInfo({ code: _code, openId: result.openId })
|
||||||
|
|
||||||
|
// 根据微信的信息获取用户信息
|
||||||
|
getWxUserInfo().then((resp) => {
|
||||||
|
const infoData = resp.result as unknown as {
|
||||||
|
userExtend: { provinceCode: string; init: boolean }
|
||||||
|
zyBatches: any[]
|
||||||
|
batchDataUrl: string
|
||||||
|
batchName: string
|
||||||
|
avatar: string
|
||||||
|
nickName: string
|
||||||
|
mobile: string
|
||||||
|
sex: number
|
||||||
|
}
|
||||||
|
userStore.setEstimatedAchievement(infoData.userExtend)
|
||||||
|
userStore.setZyBatches(infoData.zyBatches)
|
||||||
|
userStore.setBatchDataUrl(infoData.batchDataUrl)
|
||||||
|
userStore.setBatchName(infoData.batchName)
|
||||||
|
userStore.setUserAvatar(infoData.avatar)
|
||||||
|
userStore.setUserNickName(infoData.nickName)
|
||||||
|
userStore.setUserBaseInfo({ mobile: infoData.mobile, sex: infoData.sex })
|
||||||
|
|
||||||
|
if (resp.code === 200) {
|
||||||
|
// 根据用户信息中的城市设置对应城市的分数等信息
|
||||||
|
getVolunteerInitialization()
|
||||||
|
.then((res) => {
|
||||||
|
let list = res.result as any[]
|
||||||
|
let code = infoData.userExtend ? infoData.userExtend.provinceCode : ''
|
||||||
|
let addressItem: City
|
||||||
|
if (code !== '') {
|
||||||
|
for (let i = 0; i < list.length; i++) {
|
||||||
|
if (list[i].code == code) {
|
||||||
|
addressItem = list[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
userStore.setUserCity(addressItem)
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
// 个人信息初始化
|
||||||
|
if (infoData.userExtend && !infoData.userExtend.init) {
|
||||||
|
uni.navigateTo({ url: '/login-sub/inviteCode' })
|
||||||
|
} else {
|
||||||
|
uni.switchTab({
|
||||||
|
url: '/pages/home/index/index',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: '您需先授权',
|
||||||
|
icon: 'none',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
:deep(.custom-checkbox) {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
.checkbox__icon {
|
||||||
|
border-radius: 50%;
|
||||||
|
height: 32rpx;
|
||||||
|
width: 32rpx;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-box {
|
||||||
|
width: 32rpx;
|
||||||
|
height: 32rpx;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.checkbox-active) {
|
||||||
|
border-color: #fff !important;
|
||||||
|
background-color: #fff !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,226 @@
|
||||||
|
<route lang="json5" type="page">
|
||||||
|
{
|
||||||
|
style: {
|
||||||
|
navigationBarTitleText: '基本信息',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="flex flex-col bg-[#f8f8f8] h-screen">
|
||||||
|
<view class="flex-1 pb-safe">
|
||||||
|
<view class="mx-[32rpx] mt-[24rpx] bg-[#fff] rounded-[20rpx]">
|
||||||
|
<form>
|
||||||
|
<view
|
||||||
|
class="flex items-center justify-between h-[100rpx] mx-[24rpx] border-b-[2rpx] border-b-solid border-[#F3F3F3]"
|
||||||
|
>
|
||||||
|
<view class="flex items-center">
|
||||||
|
<view class="text-[28rpx] text-[#000] font-[500]">姓名</view>
|
||||||
|
<view class="text-[#FF5151] font-[500] leading-[1] h-[18rpx] ml-[8rpx]">*</view>
|
||||||
|
</view>
|
||||||
|
<view>
|
||||||
|
<input
|
||||||
|
v-model="formData.name"
|
||||||
|
placeholder="请输入姓名"
|
||||||
|
confirm-type="done"
|
||||||
|
placeholder-style="color:#BABABA;font-size:28rpx;"
|
||||||
|
class="text-start w-[140rpx]"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view
|
||||||
|
class="flex items-center justify-between h-[100rpx] mx-[24rpx] border-b-[2rpx] border-b-solid border-[#F3F3F3]"
|
||||||
|
>
|
||||||
|
<view class="flex items-center">
|
||||||
|
<view class="text-[28rpx] text-[#000] font-[500]">性别</view>
|
||||||
|
<view class="text-[#FF5151] font-[500] leading-[1] h-[18rpx] ml-[8rpx]">*</view>
|
||||||
|
</view>
|
||||||
|
<view>
|
||||||
|
<RadioGroup v-model="formData.gender" class="custom-radio-group">
|
||||||
|
<Radio :name="1" class="custom-radio">男</Radio>
|
||||||
|
<Radio :name="2" class="custom-radio">女</Radio>
|
||||||
|
</RadioGroup>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view
|
||||||
|
class="flex items-center justify-between h-[100rpx] mx-[24rpx] border-b-[2rpx] border-b-solid border-[#F3F3F3]"
|
||||||
|
>
|
||||||
|
<view class="flex items-center">
|
||||||
|
<view class="text-[28rpx] text-[#000] font-[500]">手机号</view>
|
||||||
|
<view class="text-[#FF5151] font-[500] leading-[1] h-[18rpx] ml-[8rpx]">*</view>
|
||||||
|
</view>
|
||||||
|
<view class="text-[#333] text-[28rpx]">{{ userStore.userInfo.mobile }}</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="flex items-center justify-between h-[100rpx] mx-[24rpx]">
|
||||||
|
<view class="flex items-center">
|
||||||
|
<view class="text-[28rpx] text-[#000] font-[500]">就读学校</view>
|
||||||
|
</view>
|
||||||
|
<view class="">
|
||||||
|
<input
|
||||||
|
v-model="formData.school"
|
||||||
|
placeholder="请输入您的就读学校"
|
||||||
|
confirm-type="done"
|
||||||
|
placeholder-style="color:#BABABA;font-size:28rpx;"
|
||||||
|
class="text-start w-[252rpx]"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</form>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="p-[24rpx] bg-[#fff] mx-[32rpx] mt-[24rpx] rounded-[20rpx]">
|
||||||
|
<input
|
||||||
|
v-model="formData.invitedCode"
|
||||||
|
placeholder="邀请码"
|
||||||
|
confirm-type="done"
|
||||||
|
:maxlength="4"
|
||||||
|
placeholder-style="color:#999;font-size:28rpx;"
|
||||||
|
class="text-center h-[86rpx] bg-[#F5F5F5] rounded-[16rpx]"
|
||||||
|
@input="handleInviteCode"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<view class="text-[#666] text-[24rpx] text-center mt-[10rpx]">
|
||||||
|
输入邀请码,获取免费AI报告解读
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="w-[560rpx]! h-[88rpx]! rounded-[44rpx] font-500 text-[32rpx] text-white! flex items-center justify-center mt-[80rpx]"
|
||||||
|
:class="'bg-[#1580FF]!'"
|
||||||
|
@click="handleSubmit"
|
||||||
|
>
|
||||||
|
提交
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import Radio from './components/radio-group/Radio.vue'
|
||||||
|
import RadioGroup from './components/radio-group/RadioGroup.vue'
|
||||||
|
import { useUserStore } from '@/store'
|
||||||
|
import { savePerfectInfo, verifyInviteCode } from '@/service/index/api'
|
||||||
|
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
const formData = ref({
|
||||||
|
name: userStore.userInfo.nickname,
|
||||||
|
gender: userStore.userInfo.sex || 1,
|
||||||
|
school: userStore.userInfo.estimatedAchievement.schoolName,
|
||||||
|
invitedCode: userStore.userInfo.estimatedAchievement.vipCode,
|
||||||
|
})
|
||||||
|
|
||||||
|
const invitedCodeFlag = ref(false)
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
if (!formData.value.name) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '请输入昵称',
|
||||||
|
icon: 'error',
|
||||||
|
mask: true,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
savePerfectInfo({
|
||||||
|
nickName: formData.value.name,
|
||||||
|
schoolName: formData.value.school,
|
||||||
|
sex: formData.value.gender,
|
||||||
|
inviteCode: formData.value.invitedCode,
|
||||||
|
}).then((resp) => {
|
||||||
|
if (resp.code === 200) {
|
||||||
|
uni.switchTab({
|
||||||
|
url: '/pages/home/index/index',
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: resp.message,
|
||||||
|
icon: 'error',
|
||||||
|
mask: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleInviteCode = () => {
|
||||||
|
if (formData.value.invitedCode.length === 4) {
|
||||||
|
verifyInviteCode({ code: formData.value.invitedCode }).then((resp) => {
|
||||||
|
if (resp.code === 200) {
|
||||||
|
invitedCodeFlag.value = resp.result as boolean
|
||||||
|
userStore.setEstimatedAchievement({ init: true })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
invitedCodeFlag.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const handleLogout = () => {
|
||||||
|
userStore.clearUserInfo()
|
||||||
|
uni.switchTab({
|
||||||
|
url: '/pages/home/index/index',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const instance = getCurrentInstance()
|
||||||
|
onUnload(() => {
|
||||||
|
console.log(
|
||||||
|
' userStore.userInfo.estimatedAchievement.init',
|
||||||
|
userStore.userInfo.estimatedAchievement.init,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!userStore.userInfo.estimatedAchievement.init) {
|
||||||
|
handleLogout()
|
||||||
|
}
|
||||||
|
}, instance)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
:deep(.custom-radio-group) {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 20rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.custom-radio) {
|
||||||
|
width: 108rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 32rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border: 2rpx solid #ccc;
|
||||||
|
color: #999;
|
||||||
|
|
||||||
|
.radio-wrapper {
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-label {
|
||||||
|
margin-left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-label--active {
|
||||||
|
background-color: rgba(21, 128, 255, 0.1) !important;
|
||||||
|
border-color: #1580ff !important;
|
||||||
|
border: 2rpx solid #1580ff;
|
||||||
|
border-radius: 32rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,215 @@
|
||||||
|
<route lang="json5" type="page">
|
||||||
|
{
|
||||||
|
style: {
|
||||||
|
navigationBarTitleText: '基本信息',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</route>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="flex flex-col bg-[#f8f8f8] h-screen">
|
||||||
|
<view class="flex-1 pb-safe">
|
||||||
|
<view class="mx-[32rpx] mt-[24rpx] bg-[#fff] rounded-[20rpx]">
|
||||||
|
<form>
|
||||||
|
<view
|
||||||
|
class="flex items-center justify-between h-[100rpx] mx-[24rpx] border-b-[2rpx] border-b-solid border-[#F3F3F3]"
|
||||||
|
>
|
||||||
|
<view class="flex items-center">
|
||||||
|
<view class="text-[28rpx] text-[#000] font-[500]">姓名</view>
|
||||||
|
<view class="text-[#FF5151] font-[500] leading-[1] h-[18rpx] ml-[8rpx]">*</view>
|
||||||
|
</view>
|
||||||
|
<view>
|
||||||
|
<input
|
||||||
|
v-model="formData.name"
|
||||||
|
placeholder="请输入姓名"
|
||||||
|
confirm-type="done"
|
||||||
|
placeholder-style="color:#BABABA;font-size:28rpx;"
|
||||||
|
class="text-start w-[140rpx]"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view
|
||||||
|
class="flex items-center justify-between h-[100rpx] mx-[24rpx] border-b-[2rpx] border-b-solid border-[#F3F3F3]"
|
||||||
|
>
|
||||||
|
<view class="flex items-center">
|
||||||
|
<view class="text-[28rpx] text-[#000] font-[500]">性别</view>
|
||||||
|
<view class="text-[#FF5151] font-[500] leading-[1] h-[18rpx] ml-[8rpx]">*</view>
|
||||||
|
</view>
|
||||||
|
<view>
|
||||||
|
<RadioGroup v-model="formData.gender" class="custom-radio-group">
|
||||||
|
<Radio :name="1" class="custom-radio">男</Radio>
|
||||||
|
<Radio :name="2" class="custom-radio">女</Radio>
|
||||||
|
</RadioGroup>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view
|
||||||
|
class="flex items-center justify-between h-[100rpx] mx-[24rpx] border-b-[2rpx] border-b-solid border-[#F3F3F3]"
|
||||||
|
>
|
||||||
|
<view class="flex items-center">
|
||||||
|
<view class="text-[28rpx] text-[#000] font-[500]">手机号</view>
|
||||||
|
<view class="text-[#FF5151] font-[500] leading-[1] h-[18rpx] ml-[8rpx]">*</view>
|
||||||
|
</view>
|
||||||
|
<view class="text-[#333] text-[28rpx]">{{ userStore.userInfo.mobile }}</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view
|
||||||
|
class="flex items-center justify-between h-[100rpx] mx-[24rpx] border-b-[2rpx] border-b-solid border-[#F3F3F3]"
|
||||||
|
>
|
||||||
|
<view class="flex items-center">
|
||||||
|
<view class="text-[28rpx] text-[#000] font-[500]">就读学校</view>
|
||||||
|
</view>
|
||||||
|
<view class="">
|
||||||
|
<input
|
||||||
|
v-model="formData.school"
|
||||||
|
placeholder="请输入您的就读学校"
|
||||||
|
confirm-type="done"
|
||||||
|
placeholder-style="color:#BABABA;font-size:28rpx;"
|
||||||
|
class="text-start w-[252rpx]"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="flex items-center justify-between h-[100rpx] mx-[24rpx]">
|
||||||
|
<view class="flex items-center">
|
||||||
|
<view class="text-[28rpx] text-[#000] font-[500]">邀请码</view>
|
||||||
|
</view>
|
||||||
|
<view class="">
|
||||||
|
<input
|
||||||
|
v-model="formData.invitedCode"
|
||||||
|
placeholder="请输入您的邀请码"
|
||||||
|
confirm-type="done"
|
||||||
|
:maxlength="4"
|
||||||
|
placeholder-style="color:#BABABA;font-size:28rpx;"
|
||||||
|
class="text-start w-[252rpx]"
|
||||||
|
@input="handleInviteCode"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</form>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="w-[560rpx]! h-[88rpx]! rounded-[44rpx] font-500 text-[32rpx] text-white! flex items-center justify-center mt-[80rpx]"
|
||||||
|
:class="'bg-[#1580FF]!'"
|
||||||
|
@click="handleSubmit"
|
||||||
|
>
|
||||||
|
提交
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import Radio from '@/pages-sub/components/radio-group/Radio.vue'
|
||||||
|
import RadioGroup from '@/pages-sub/components/radio-group/RadioGroup.vue'
|
||||||
|
import { useUserStore } from '@/store'
|
||||||
|
import { savePerfectInfo, verifyInviteCode } from '@/service/index/api'
|
||||||
|
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
const formData = ref({
|
||||||
|
name: userStore.userInfo.nickname,
|
||||||
|
gender: userStore.userInfo.sex || 1,
|
||||||
|
school: userStore.userInfo.estimatedAchievement.schoolName,
|
||||||
|
invitedCode: userStore.userInfo.estimatedAchievement.vipCode,
|
||||||
|
})
|
||||||
|
|
||||||
|
const invitedCodeFlag = ref(false)
|
||||||
|
|
||||||
|
const handleSubmit = () => {
|
||||||
|
if (!formData.value.name) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '请输入昵称',
|
||||||
|
icon: 'error',
|
||||||
|
mask: true,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
savePerfectInfo({
|
||||||
|
nickName: formData.value.name,
|
||||||
|
schoolName: formData.value.school,
|
||||||
|
sex: formData.value.gender,
|
||||||
|
inviteCode: formData.value.invitedCode,
|
||||||
|
}).then((resp) => {
|
||||||
|
if (resp.code === 200) {
|
||||||
|
userStore.setUserNickName(formData.value.name)
|
||||||
|
userStore.setUserBaseInfo({ sex: formData.value.gender })
|
||||||
|
userStore.setEstimatedAchievement({
|
||||||
|
schoolName: formData.value.school,
|
||||||
|
vipCode: formData.value.invitedCode,
|
||||||
|
})
|
||||||
|
uni.navigateBack()
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: resp.message,
|
||||||
|
icon: 'error',
|
||||||
|
mask: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleInviteCode = () => {
|
||||||
|
if (formData.value.invitedCode.length === 4) {
|
||||||
|
verifyInviteCode({ code: formData.value.invitedCode }).then((resp) => {
|
||||||
|
if (resp.code === 200) {
|
||||||
|
invitedCodeFlag.value = resp.result as boolean
|
||||||
|
userStore.setEstimatedAchievement({ init: true })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
invitedCodeFlag.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
:deep(.custom-radio-group) {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 20rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.custom-radio) {
|
||||||
|
width: 108rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 32rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border: 2rpx solid #ccc;
|
||||||
|
color: #999;
|
||||||
|
|
||||||
|
.radio-wrapper {
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio {
|
||||||
|
border-radius: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-label {
|
||||||
|
margin-left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-label--active {
|
||||||
|
background-color: rgba(21, 128, 255, 0.1) !important;
|
||||||
|
border-color: #1580ff !important;
|
||||||
|
border: 2rpx solid #1580ff;
|
||||||
|
border-radius: 32rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -287,6 +287,13 @@
|
||||||
"navigationBarTitleText": "设置"
|
"navigationBarTitleText": "设置"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "ucenter/setting/userInfo",
|
||||||
|
"type": "page",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "基本信息"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "ucenter/star/myStar",
|
"path": "ucenter/star/myStar",
|
||||||
"type": "page",
|
"type": "page",
|
||||||
|
|
@ -320,6 +327,13 @@
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "inviteCode",
|
||||||
|
"type": "page",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "基本信息"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "privacyPolicy",
|
"path": "privacyPolicy",
|
||||||
"type": "page"
|
"type": "page"
|
||||||
|
|
|
||||||
|
|
@ -182,10 +182,16 @@ const toSetting = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const goLogin = () => {
|
const goLogin = () => {
|
||||||
|
console.log('hhh')
|
||||||
|
|
||||||
if (!userStore.userInfo.openid) {
|
if (!userStore.userInfo.openid) {
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: '/login-sub/index',
|
url: '/login-sub/index',
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages-sub/ucenter/setting/userInfo',
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -219,6 +219,9 @@ export const savePerfectInfo = (params: {
|
||||||
score?: number
|
score?: number
|
||||||
sp?: number
|
sp?: number
|
||||||
year?: number
|
year?: number
|
||||||
|
sex?: number
|
||||||
|
nickName?: string
|
||||||
|
inviteCode?: string
|
||||||
}) => {
|
}) => {
|
||||||
return http.post('/api/weChatUserEx/perfectInfo', params)
|
return http.post('/api/weChatUserEx/perfectInfo', params)
|
||||||
}
|
}
|
||||||
|
|
@ -470,3 +473,7 @@ export const sendMessage = (params: { conversation_id: string; user: string; que
|
||||||
export const getAssistant = () => {
|
export const getAssistant = () => {
|
||||||
return http.get('/api/weChatUserEx/areaExtend', {})
|
return http.get('/api/weChatUserEx/areaExtend', {})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const verifyInviteCode = ({ code }: { code: string }) => {
|
||||||
|
return http.post('/api/weChatUserEx/verifyInviteCode', { code })
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ import { ref } from 'vue'
|
||||||
const initState = {
|
const initState = {
|
||||||
nickname: '',
|
nickname: '',
|
||||||
avatar: '',
|
avatar: '',
|
||||||
|
mobile: '',
|
||||||
|
sex: 0,
|
||||||
city: {
|
city: {
|
||||||
allscore: 0,
|
allscore: 0,
|
||||||
code: '0',
|
code: '0',
|
||||||
|
|
@ -97,6 +99,13 @@ export const useUserStore = defineStore(
|
||||||
userInfo.value.avatar = val
|
userInfo.value.avatar = val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const setUserBaseInfo = ({ mobile, sex }: { mobile?: string; sex: number }) => {
|
||||||
|
userInfo.value.sex = sex
|
||||||
|
if (mobile) {
|
||||||
|
userInfo.value.mobile = mobile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 清除预估成绩
|
// 清除预估成绩
|
||||||
const clearUserEstimatedAchievement = () => {
|
const clearUserEstimatedAchievement = () => {
|
||||||
userInfo.value.estimatedAchievement = Object.assign(userInfo.value.estimatedAchievement, {
|
userInfo.value.estimatedAchievement = Object.assign(userInfo.value.estimatedAchievement, {
|
||||||
|
|
@ -221,6 +230,7 @@ export const useUserStore = defineStore(
|
||||||
setIsVIP,
|
setIsVIP,
|
||||||
setVipCode,
|
setVipCode,
|
||||||
setIsShowAi,
|
setIsShowAi,
|
||||||
|
setUserBaseInfo,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,8 @@ export type ExtraUserInfo = {
|
||||||
batchName: string
|
batchName: string
|
||||||
wishList: any[]
|
wishList: any[]
|
||||||
isShowAi: boolean
|
isShowAi: boolean
|
||||||
|
mobile: string
|
||||||
|
sex: number
|
||||||
} & IUserInfo
|
} & IUserInfo
|
||||||
|
|
||||||
export type News = {
|
export type News = {
|
||||||
|
|
|
||||||
|
|
@ -33,10 +33,12 @@ interface NavigateToOptions {
|
||||||
"/pages-sub/ucenter/evaluate/evaluateList" |
|
"/pages-sub/ucenter/evaluate/evaluateList" |
|
||||||
"/pages-sub/ucenter/setting/about" |
|
"/pages-sub/ucenter/setting/about" |
|
||||||
"/pages-sub/ucenter/setting/index" |
|
"/pages-sub/ucenter/setting/index" |
|
||||||
|
"/pages-sub/ucenter/setting/userInfo" |
|
||||||
"/pages-sub/ucenter/star/myStar" |
|
"/pages-sub/ucenter/star/myStar" |
|
||||||
"/pages-sub/ucenter/vip/openVip" |
|
"/pages-sub/ucenter/vip/openVip" |
|
||||||
"/pages-sub/ucenter/wishList/wishList" |
|
"/pages-sub/ucenter/wishList/wishList" |
|
||||||
"/login-sub/index" |
|
"/login-sub/index" |
|
||||||
|
"/login-sub/inviteCode" |
|
||||||
"/login-sub/privacyPolicy" |
|
"/login-sub/privacyPolicy" |
|
||||||
"/login-sub/userAgreement" |
|
"/login-sub/userAgreement" |
|
||||||
"/pages-evaluation-sub/aiAutoFill/index" |
|
"/pages-evaluation-sub/aiAutoFill/index" |
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue