Commit 2dc5a72e authored by tyyin lan's avatar tyyin lan

feat: 谷歌登录

parent 69ef3c03
......@@ -26,6 +26,7 @@ export default [
ConversationMessageItemInfo: 'readonly',
MittEvents: 'readonly',
I18n: 'readonly',
google: 'readonly',
},
parser: vueParser,
parserOptions: {
......
import { request } from '@/utils/request'
export function fetchLogin<T>(payload: {
loginChannel: 'MEMBER_PLATFOMR_SMS' | 'MEMBER_PLATFOMR_EMAIL' | 'MEMBER_PLATFOMR_PW'
loginChannel: 'MEMBER_PLATFOMR_SMS' | 'MEMBER_PLATFOMR_EMAIL' | 'MEMBER_PLATFOMR_PW' | 'MEMBER_PLATFOMR_GOOGLE'
account: string
password?: string
authCode?: string
......@@ -38,3 +38,7 @@ export function fetchUserPasswordUpdate<T>(authCode: string, password: string) {
params: { authCode, password },
})
}
export function fetchGoogleClientId<T>() {
return request.post<T>('/googleConfigRest/getClientId.json')
}
......@@ -134,6 +134,7 @@ common_module:
export_successfully: 'Export successfully'
export_failed: 'Export failed'
copy_link: 'Copy link'
or: 'or'
dialogue_module:
continue_question_message: 'You can keep asking questions'
......
......@@ -133,6 +133,7 @@ common_module:
export_successfully: '导出成功'
export_failed: '导出失败'
copy_link: '复制链接'
or: '或'
dialogue_module:
continue_question_message: '你可以继续提问'
......
......@@ -133,6 +133,7 @@ common_module:
export_successfully: '導出成功'
export_failed: '導出失敗'
copy_link: '複製鏈接'
or: '或'
dialogue_module:
continue_question_message: '你可以繼續提問'
......
......@@ -53,6 +53,10 @@ export const useUserStore = defineStore('user-store', {
this.token = ''
this.userInfo = createDefaultUserInfoFactory()
if (window.google) {
window.google.accounts.id.disableAutoSelect()
}
ss.remove(UserStoreStorageKeyEnum.isLogin)
ss.remove(UserStoreStorageKeyEnum.token)
ss.remove(UserStoreStorageKeyEnum.userInfo)
......
......@@ -5,27 +5,29 @@ import { Mail, Lock, Iphone, Down, User } from '@icon-park/vue-next'
import isMobilePhone from 'validator/es/lib/isMobilePhone'
import isEmail from 'validator/es/lib/isEmail'
import { ss } from '@/utils/storage'
import { fetchEmailCode, fetchLogin, fetchSMSCode } from '@/apis/user'
import { fetchEmailCode, fetchLogin, fetchSMSCode, fetchGoogleClientId } from '@/apis/user'
import SparkMD5 from 'spark-md5'
import { useUserStore } from '@/store/modules/user'
import type { UserInfo } from '@/store/types/user'
import { useRouter, useRoute } from 'vue-router'
import { useI18n } from 'vue-i18n'
import LanguageSetting from '@/components/language-setting/language-setting.vue'
import { useSystemLanguageStore } from '@/store/modules/system-language'
enum StorageKeyEnum {
smsCountdownTime = 'SMS_COUNTDOWN_TIME',
emailCountdownTime = 'MAIL_COUNTDOWN_TIME',
}
type LoginMethod = 'password' | 'sms' | 'email'
type LoginMethod = 'password' | 'sms' | 'email' | 'google'
interface LoginPayload {
loginChannel: 'MEMBER_PLATFOMR_SMS' | 'MEMBER_PLATFOMR_EMAIL' | 'MEMBER_PLATFOMR_PW'
loginChannel: 'MEMBER_PLATFOMR_SMS' | 'MEMBER_PLATFOMR_EMAIL' | 'MEMBER_PLATFOMR_PW' | 'MEMBER_PLATFOMR_GOOGLE'
account: string
password?: string
authCode?: string
}
const userStore = useUserStore()
const systemLanguageStore = useSystemLanguageStore()
const router = useRouter()
const route = useRoute()
const { t } = useI18n()
......@@ -34,6 +36,7 @@ const passwordLoginFormRef = useTemplateRef<FormInst>('passwordLoginFormRef')
const smsLoginFormRef = useTemplateRef<FormInst>('smsLoginFormRef')
const emailLoginFormRef = useTemplateRef<FormInst>('emailLoginFormRef')
const countdownRef = useTemplateRef<CountdownInst>('countdownRef')
const googleLoginBtnRef = useTemplateRef<HTMLDivElement>('googleLoginBtnRef')
const currentLoginMethod = ref<LoginMethod>('sms')
const showCardReserveAnimation = ref(false)
......@@ -52,6 +55,9 @@ const emailLoginForm = ref({
email: '',
code: '',
})
const googleLoginForm = ref({
credential: '',
})
const passwordLoginFormRules = shallowReadonly<FormRules>({
account: { required: true, message: t('login_module.please_enter_your_account_number'), trigger: 'blur' },
......@@ -90,6 +96,12 @@ const emailLoginFormRules = shallowReadonly<FormRules>({
code: { required: true, message: t('login_module.please_enter_the_verification_code') },
})
const currentPhoneNumberArea = ref<'+86' | '+852'>('+852')
const countdownActive = ref(true)
const isShowCountdown = ref(false)
const countdownDuration = ref<number>(60000)
const phoneNumberAreaOptions = computed(() => {
return [
{
......@@ -102,11 +114,6 @@ const phoneNumberAreaOptions = computed(() => {
},
]
})
const currentPhoneNumberArea = ref<'+86' | '+852'>('+852')
const countdownActive = ref(true)
const isShowCountdown = ref(false)
const countdownDuration = ref<number>(60000)
watchEffect(() => {
let timeStringDraft = ''
......@@ -135,6 +142,21 @@ watchEffect(() => {
}
})
/* created */
;(function () {
if (!window.google) {
const script = document.createElement('script')
script.src = `https://accounts.google.com/gsi/client?hl=${systemLanguageStore.currentLanguage}` // 加载客户端库
script.async = true
script.onload = () => {
getGoogleLoginClientId().then((clientId) => {
clientId && initializeGoogleSignIn(clientId)
})
}
document.head.appendChild(script)
}
})()
function onlyAllowNumber(value: string) {
return !value || /^\d+$/.test(value)
}
......@@ -218,6 +240,17 @@ function handleLoginSubmit(method: LoginMethod) {
})
}
break
case 'google':
{
payload = {
loginChannel: 'MEMBER_PLATFOMR_GOOGLE',
account: '',
authCode: googleLoginForm.value.credential,
}
resolve(true)
}
break
}
}).then(() => {
loginBtnLoading.value = true
......@@ -301,6 +334,41 @@ function handleEmailCodeGain() {
},
)
}
function initializeGoogleSignIn(clientId: string) {
window.google.accounts.id.initialize({
client_id: encodeURIComponent(clientId),
auto_select: false,
callback: (res: { credential: string; clientId: string }) => {
googleLoginForm.value.credential = res.credential
handleLoginSubmit('google')
},
})
if (googleLoginBtnRef.value) {
window.google.accounts.id.renderButton(googleLoginBtnRef.value, {
size: 'medium',
text: 'signin_with',
logo_alignment: 'left',
locale: systemLanguageStore.currentLanguage,
})
}
// window.google.accounts.id.prompt((notification: any) => {
// if (notification.isNotDisplayed() || notification.isSkippedMoment()) {
// console.log('💥💥💥💥💥💥登录失败💥💥💥💥💥💥')
// }
// })
}
function getGoogleLoginClientId() {
return fetchGoogleClientId<string>().then((res) => {
if (res.code !== 0) return ''
return res.data
})
}
</script>
<template>
......@@ -313,7 +381,7 @@ function handleEmailCodeGain() {
<LanguageSetting arrow-direction="bottom" btn-bg-color="#f4f5f5" />
</div>
<div class="absolute right-[14%] top-1/2 h-[458px] w-[390px] -translate-y-1/2">
<div class="absolute right-[14%] top-1/2 w-[390px] -translate-y-1/2">
<div
class="h-full w-full rounded-[10px] bg-[#fff] px-[29px] shadow-2xl"
:class="{ 'animate-card-reverse': showCardReserveAnimation }"
......@@ -532,8 +600,8 @@ function handleEmailCodeGain() {
</n-form>
</div>
<div class="absolute bottom-[22px] left-0 w-full">
<div class="mb-[32px]">
<div class="w-full pb-[34px]">
<div class="h-[134px]">
<div class="mb-[12px] text-center text-[12px] text-[#999999]">
{{ t('login_module.other_login_methods') }}
</div>
......@@ -562,6 +630,12 @@ function handleEmailCodeGain() {
<Lock theme="outline" size="17" fill="#666666" :stroke-width="3" />
</button>
</div>
<div class="py-[10px] text-center text-[12px] text-[#999999]">{{ t('common_module.or') }}</div>
<div class="flex-center flex">
<div ref="googleLoginBtnRef"></div>
</div>
</div>
<!-- <div class="text-center">
......
......@@ -6,6 +6,8 @@ declare interface Window {
ctWarning: (message: string, title?: string, cancelText?: string, confirmText?: string) => Promise<boolean | Error>
}
$notification: import('naive-ui').NotificationProviderInst
google: any
}
declare namespace JSX {
......
......@@ -133,6 +133,7 @@ declare namespace I18n {
export_successfully: string
export_failed: string
copy_link: string
or: string
dialogue_module: {
continue_question_message: string
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment