334 lines
9.6 KiB
Vue
334 lines
9.6 KiB
Vue
<route lang="json5">
|
|
{
|
|
style: {
|
|
navigationStyle: 'custom',
|
|
disableScroll: true
|
|
},
|
|
needLogin: false
|
|
}
|
|
</route>
|
|
<template>
|
|
<view class="bg-white">
|
|
<TopNavigation
|
|
:have-back="false"
|
|
v-if="systemInfo && systemInfo?.uniPlatform === 'app'"
|
|
></TopNavigation>
|
|
<swiper
|
|
v-if="systemInfo"
|
|
circular="true"
|
|
:current="index"
|
|
disable-touch="true"
|
|
:style="{
|
|
height: 'calc(100vh - ' + (systemInfo.safeAreaInsets?.top + 48) + 'px)'
|
|
}"
|
|
>
|
|
<swiper-item v-for="item in 4" :key="item">
|
|
<view
|
|
:class="[systemInfo && systemInfo?.uniPlatform === 'app' ? 'pt-5' : 'pt-20']"
|
|
class="pos-relative"
|
|
>
|
|
<view class="text-6 ml-4 mt-2 custom-color-black font-bold">欢迎使用{{ appName }}</view>
|
|
<view class="text-3 ml-4 mt-2 mb-4 custom-color-grey">
|
|
未注册手机号验证号将创建{{ appName }}通行证
|
|
</view>
|
|
<view class="p-5">
|
|
<wd-input
|
|
v-model="phone"
|
|
:maxlength="11"
|
|
clearable
|
|
placeholder="请输入手机号码"
|
|
placeholderClass="text-4 custom-color-grey"
|
|
size="large"
|
|
type="number"
|
|
@change="phoneChange"
|
|
/>
|
|
<wd-input
|
|
v-if="index % 2 === 1"
|
|
v-model="password"
|
|
:maxlength="20"
|
|
class="mt-6"
|
|
clearable
|
|
placeholder="请输入密码"
|
|
placeholderClass="text-4 custom-color-grey"
|
|
show-password
|
|
size="large"
|
|
@change="passwordChange"
|
|
/>
|
|
</view>
|
|
<view v-if="index % 2 === 0" class="p-5">
|
|
<wd-button
|
|
:block="true"
|
|
:disabled="!phonePass"
|
|
:round="false"
|
|
size="large"
|
|
@click="codeLogin(false, $event)"
|
|
>
|
|
获取验证码
|
|
</wd-button>
|
|
</view>
|
|
<view v-else class="p-5">
|
|
<wd-button
|
|
@click="passwordLogin"
|
|
:block="true"
|
|
:disabled="!(passwordPass && phonePass)"
|
|
size="large"
|
|
:round="false"
|
|
>
|
|
登录
|
|
</wd-button>
|
|
</view>
|
|
<view
|
|
class="pt-2 pb-1 pl-5 pr-5 flex flex-items-center flex-justify-center custom-color-grey"
|
|
>
|
|
<view v-if="index % 2 === 0" @click="index = index + 1">密码登录</view>
|
|
<view v-if="index % 2 === 1" @click="index === 3 ? (index = 0) : (index = index + 1)">
|
|
验证码登录
|
|
</view>
|
|
<view v-if="index % 2 === 1" class="mx-4">|</view>
|
|
<view v-if="index % 2 === 1" @click="resetPassword">忘记密码</view>
|
|
</view>
|
|
<view class="pos-fixed bottom-1 pb-safe">
|
|
<view v-if="systemInfo" class="text-center text-3">
|
|
<view>{{ systemInfo?.uniPlatform === 'app' ? '第三方登录方式' : '扫码登录' }}</view>
|
|
<image
|
|
v-if="systemInfo?.uniPlatform === 'app'"
|
|
class="h-10 w-10 mt-2"
|
|
mode="aspectFit"
|
|
src="/static/images/icon_wechat.png"
|
|
></image>
|
|
<image
|
|
v-if="systemInfo?.uniPlatform !== 'app'"
|
|
class="h-10 w-10 mt-2"
|
|
mode="aspectFit"
|
|
src="/static/images/icon_scan_code.png"
|
|
></image>
|
|
</view>
|
|
<view class="flex p-5">
|
|
<view class="pt-0.8">
|
|
<wd-checkbox
|
|
:modelValue="consentAgreement"
|
|
class="flex-shrink-0"
|
|
shape="circle"
|
|
size="larger"
|
|
@click="changeConsentAgreement"
|
|
></wd-checkbox>
|
|
</view>
|
|
<view class="ml-1.5 text-3">
|
|
<text>
|
|
登录后即同意
|
|
<text class="custom-color-blue">《天翼账号认证服务条款》</text>
|
|
和
|
|
<text class="custom-color-blue">《{{ appName }}登录政策》</text>
|
|
、
|
|
<text class="custom-color-blue">《{{ appName }}服务协议》</text>
|
|
、
|
|
<text class="custom-color-blue">《{{ appName }}隐私政策》</text>
|
|
并授权{{ appName }}获取本机号码及{{ appName }}通行证账号信息进行统一管理
|
|
</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</swiper-item>
|
|
</swiper>
|
|
</view>
|
|
<Modal
|
|
ref="agreementModal"
|
|
:title="`欢迎使用${appName}`"
|
|
confirm-text="同意并继续"
|
|
@confirm="confirm"
|
|
>
|
|
<text>
|
|
登录后即同意
|
|
<text class="custom-color-blue">《天翼账号认证服务条款》</text>
|
|
和
|
|
<text class="custom-color-blue">《{{ appName }}登录政策》</text>
|
|
、
|
|
<text class="custom-color-blue">《{{ appName }}服务协议》</text>
|
|
、
|
|
<text class="custom-color-blue">《{{ appName }}隐私政策》</text>
|
|
</text>
|
|
</Modal>
|
|
</template>
|
|
<script lang="ts" setup>
|
|
import { useBasicStore, useUserStore } from '@/store'
|
|
import { passwordRegExp, phoneRegExp } from '@/constants/regular-expressions'
|
|
import {
|
|
getCodeApi,
|
|
passwordLoginApi,
|
|
PasswordLoginRequest,
|
|
UserGetCodeRequest
|
|
} from '@/service/user'
|
|
import { AccountChannel, CodeType, PlatId } from '@/typings'
|
|
import { Result } from '@/constants/result'
|
|
import GetSystemInfoResult = UniNamespace.GetSystemInfoResult
|
|
|
|
const $basic = useBasicStore()
|
|
const $user = useUserStore()
|
|
|
|
const appName = import.meta.env.VITE_APP_TITLE
|
|
|
|
const phone = ref<string>('')
|
|
const password = ref<string>('')
|
|
|
|
const consentAgreement = ref<boolean>(false)
|
|
|
|
const index = ref<number>(0)
|
|
|
|
const systemInfo = ref<GetSystemInfoResult>(null)
|
|
|
|
const phonePass = computed(() => phoneRegExp.test(phone.value))
|
|
|
|
const passwordPass = computed(() => passwordRegExp.test(password.value))
|
|
|
|
const agreementModal = ref(null)
|
|
|
|
const type = ref('code')
|
|
|
|
onMounted(async () => {
|
|
systemInfo.value = await $basic.getSystemInfo()
|
|
})
|
|
|
|
const passwordLogin = async () => {
|
|
if (!phonePass.value || !passwordPass.value) {
|
|
return
|
|
}
|
|
if (!consentAgreement.value) {
|
|
type.value = 'password'
|
|
agreementModal.value.showModal()
|
|
return
|
|
}
|
|
await uni.showLoading({
|
|
title: '登录中',
|
|
mask: true
|
|
})
|
|
try {
|
|
const result = await passwordLoginApi<PasswordLoginRequest>({
|
|
platId: PlatId.app,
|
|
username: phone.value,
|
|
password: password.value,
|
|
deviceInfo: {
|
|
deviceNo: systemInfo.value?.deviceId,
|
|
deviceName: `${systemInfo.value?.deviceBrand} ${systemInfo.value?.deviceModel}`,
|
|
deviceBrand: systemInfo.value?.deviceBrand,
|
|
deviceModel: systemInfo.value?.deviceModel
|
|
}
|
|
})
|
|
uni.hideLoading()
|
|
if (result.errorCode === Result.Success.code) {
|
|
uni.setStorageSync('token', result.data.token)
|
|
$user.getUserInfo()
|
|
await uni.switchTab({
|
|
url: '/pages/home/home'
|
|
})
|
|
await uni.showToast({
|
|
title: '登录成功',
|
|
icon: 'none'
|
|
})
|
|
} else if (result.errorCode === Result.NewDevice.code) {
|
|
await codeLogin(true)
|
|
} else {
|
|
await uni.showToast({
|
|
title: result.errorMsg,
|
|
icon: 'none'
|
|
})
|
|
}
|
|
} catch (err) {
|
|
console.log(err)
|
|
uni.hideLoading()
|
|
await uni.showToast({
|
|
title: '获取验证码失败,请稍后再试',
|
|
icon: 'none'
|
|
})
|
|
}
|
|
}
|
|
|
|
const codeLogin = async (tip: boolean = false) => {
|
|
if (!phonePass.value) {
|
|
return
|
|
}
|
|
if (!consentAgreement.value) {
|
|
type.value = 'code'
|
|
agreementModal.value.showModal()
|
|
return
|
|
}
|
|
await uni.showLoading({
|
|
title: '加载中',
|
|
mask: true
|
|
})
|
|
try {
|
|
const result = await getCodeApi<UserGetCodeRequest>({
|
|
account: phone.value,
|
|
channel: AccountChannel.phone,
|
|
codeType: CodeType.login
|
|
})
|
|
uni.hideLoading()
|
|
if (result.errorCode === Result.Success.code) {
|
|
let url = `/pages/login/code?phone=${phone.value}&type=login`
|
|
if (tip) {
|
|
url = url + `&tip=true`
|
|
}
|
|
await uni.navigateTo({
|
|
url
|
|
})
|
|
} else {
|
|
await uni.showToast({
|
|
title: result.errorMsg,
|
|
icon: 'none'
|
|
})
|
|
}
|
|
} catch (err) {
|
|
console.log(err)
|
|
uni.hideLoading()
|
|
await uni.showToast({
|
|
title: '获取验证码失败,请稍后再试',
|
|
icon: 'none'
|
|
})
|
|
}
|
|
}
|
|
|
|
const resetPassword = () => {
|
|
if (!consentAgreement.value) {
|
|
type.value = 'reset'
|
|
agreementModal.value.showModal()
|
|
return
|
|
}
|
|
let params = ''
|
|
if (phonePass.value) {
|
|
params = `?phone=${phone.value}`
|
|
}
|
|
uni.navigateTo({
|
|
url: `/pages/login/get-code${params}`
|
|
})
|
|
}
|
|
|
|
const confirm = () => {
|
|
consentAgreement.value = true
|
|
if (type.value === 'code') {
|
|
codeLogin()
|
|
} else if (type.value === 'password') {
|
|
passwordLogin()
|
|
} else if (type.value === 'reset') {
|
|
resetPassword()
|
|
}
|
|
}
|
|
|
|
const phoneChange = (value: string) => {
|
|
phone.value = value
|
|
}
|
|
|
|
const passwordChange = (value: string) => {
|
|
password.value = value
|
|
}
|
|
|
|
const changeConsentAgreement = () => {
|
|
consentAgreement.value = !consentAgreement.value
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
page {
|
|
background-color: #ffffff;
|
|
}
|
|
</style>
|