This commit is contained in:
zhangyahui
2025-11-05 11:59:34 +08:00
parent 618e82bc95
commit cdc5e5406b

View File

@@ -1,53 +1,76 @@
<template> <template>
<div class="Container"> <div class="Container">
<!-- 谷歌登录 -->
<div class="g_id_signin" id="g_id_signin"></div> <div class="g_id_signin" id="g_id_signin"></div>
<!-- <div class="icon"> <!-- <div class="icon" @click="toGmailLogin"> -->
<img :src="google" class="google-icon" /> <div class="icon">
<span>{{ text }}</span> <img src="@/assets/images/loginPage/gmailIcon.svg" alt="" />
</div> --> <span>{{ $props.text }}</span>
</div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script>
import { reactive, onMounted, onBeforeUnmount } from 'vue' import { defineComponent, ref, reactive, watch, onMounted, onBeforeUnmount, toRefs } from 'vue'
import { google } from '@/assets/base64'
// 定义 props export default defineComponent({
defineProps({ name: 'login',
emits: ['googelLogin'],
props: {
text: { text: {
type: String, type: String,
default: 'Sign in with Google' default: 'Sign in with Google'
} }
}) },
setup(props, { emit }) {
function decodeJWT(token) {
let base64Url = token.split('.')[1]
let base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/')
let jsonPayload = decodeURIComponent(
atob(base64)
.split('')
.map(function (c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
})
.join('')
)
return JSON.parse(jsonPayload)
}
const handleCredentialResponse = async (response) => {
// 获取回调响应的凭证数据 然后拿这个凭证给后台后台jwt进行解析获取登录信息
console.log('Encoded JWT ID token: ' + response.credential)
const responsePayload = decodeJWT(response.credential)
console.log('Decoded JWT ID token fields:')
console.log(' Full Name: ' + responsePayload.name)
console.log(' Given Name: ' + responsePayload.given_name)
console.log(' Family Name: ' + responsePayload.family_name)
console.log(' Unique ID: ' + responsePayload.sub)
console.log(' Profile image URL: ' + responsePayload.picture)
console.log(' Email: ' + responsePayload.email)
// 定义 emits let code = response.credential
const emit = defineEmits<{
(e: 'googelLogin', code: string): void
}>()
// 处理 Google 登录回调
const handleCredentialResponse = async (response: { credential: string }) => {
const code = response.credential
emit('googelLogin', code) emit('googelLogin', code)
window.isAddGmail = false window.isAddGmail = false
} }
let data = reactive({
// 配置数据
const data = reactive({
// scriptSrc:'https://apis.google.com/js/platform.js', // scriptSrc:'https://apis.google.com/js/platform.js',
scriptSrc: 'https://accounts.google.com/gsi/client', scriptSrc: 'https://accounts.google.com/gsi/client',
script: null script: null
}) })
console.log(import.meta.env.VITE_USER_NODE_ENV)
// 根据环境设置 Google Client ID let GOOGLE_CLIENT_ID =
const GOOGLE_CLIENT_ID = '216037134725-7q8vqp0ohtmohlosltkfg7bd2v29rm5a.apps.googleusercontent.com' '216037134725-7q8vqp0ohtmohlosltkfg7bd2v29rm5a.apps.googleusercontent.com'
// if(import.meta.env.VITE_USER_NODE_ENV == 'development'){
// 创建 Gmail 登录 // GOOGLE_CLIENT_ID = '157095842121-kdd1fdf8m8nudvj9sprstb2k2prnf9e4.apps.googleusercontent.com'
const createGmailLogin = async () => { // }else{
const existingScript = document.querySelector(`script[src="${data.scriptSrc}"]`) // GOOGLE_CLIENT_ID = '29310152396-nnsd3h533fld665oguu8ovrt1nukmt46.apps.googleusercontent.com'
// }
// 使用谷歌登录的api
const createGmailLogin = async () => {
var existingScript = document.querySelector(`script[src="${data.scriptSrc}"]`)
if (!window.isAddGmail) { if (!window.isAddGmail) {
if (!existingScript) { if (!existingScript) {
window.isAddGmail = true window.isAddGmail = true
await new Promise<void>((resolve) => { await new Promise((resolve, reject) => {
const script = document.createElement('script') const script = document.createElement('script')
script.onload = () => { script.onload = () => {
resolve() resolve()
@@ -56,18 +79,16 @@ const createGmailLogin = async () => {
script.src = data.scriptSrc script.src = data.scriptSrc
}) })
} }
// 初始化Google登录禁用One Tap自动提示 window.google.accounts.id.initialize({
const initConfig: Parameters<typeof window.google.accounts.id.initialize>[0] = { // 主要就是填写client_id
client_id: GOOGLE_CLIENT_ID, client_id: GOOGLE_CLIENT_ID,
auto_select: false, // 禁用自动选择避免显示One Tap提示 auto_select: false,
callback: handleCredentialResponse, callback: handleCredentialResponse,
context: 'signin', // 设置为signin模式避免显示个性化One Tap提示 // context:"signin",
ux_mode: 'popup', ux_mode: 'popup',
itp_support: true, itp_support: true
cancel_on_tap_outside: true // 点击外部时取消One Tap提示 })
} console.log(document.querySelector('.Container #g_id_signin'))
window.google.accounts.id.initialize(initConfig as any)
console.log('创建谷歌登录按钮:', document.querySelector('.Container #g_id_signin'))
window.google.accounts.id.renderButton(document.querySelector('.Container #g_id_signin'), { window.google.accounts.id.renderButton(document.querySelector('.Container #g_id_signin'), {
type: 'standard', //icon为只有一个icon type: 'standard', //icon为只有一个icon
shape: 'circle', shape: 'circle',
@@ -76,35 +97,30 @@ const createGmailLogin = async () => {
logo_alignment: 'center' logo_alignment: 'center'
}) })
} }
} }
onBeforeUnmount(() => {
onBeforeUnmount(() => { var existingScript = document.querySelector(`script[src="${data.scriptSrc}"]`)
const existingScript = document.querySelector(`script[src="${data.scriptSrc}"]`)
if (existingScript) { if (existingScript) {
existingScript.remove() existingScript.remove()
window.isAddGmail = false window.isAddGmail = false
} }
}) })
onMounted(() => {
onMounted(() => {
createGmailLogin() createGmailLogin()
})
return {}
}
}) })
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
.Container { .Container {
width: 100%; position: relative;
height: 10.6rem; border-radius: 4rem;
padding: 1.6rem; overflow: hidden;
border: 0.2rem solid #fff; background: transparent;
border-radius: 7rem; @media (max-width: 768px) {
font-size: 3.83rem; border-radius: 2.5rem;
cursor: pointer; }
display: flex;
align-items: center;
justify-content: center;
column-gap: 3.1rem;
margin-bottom: 1.67rem;
:deep(.nsm7Bb-HzV7m-LgbsSe-bN97Pc-sM5MNb) { :deep(.nsm7Bb-HzV7m-LgbsSe-bN97Pc-sM5MNb) {
justify-content: center; justify-content: center;
.nsm7Bb-HzV7m-LgbsSe-Bz112c { .nsm7Bb-HzV7m-LgbsSe-Bz112c {
@@ -113,10 +129,15 @@ onMounted(() => {
} }
:deep(.nsm7Bb-HzV7m-LgbsSe.JGcpL-RbRzK) { :deep(.nsm7Bb-HzV7m-LgbsSe.JGcpL-RbRzK) {
width: 100%; width: 100%;
height: 10.6rem;
} }
// :deep(.S9gUrf-YoZ4jf){
// *{
// width: 100%;
// height: 100%;
// }
// }
.icon { .icon {
// width: 40px;
width: auto; width: auto;
display: flex; display: flex;
align-items: center; align-items: center;
@@ -128,31 +149,53 @@ onMounted(() => {
position: relative; position: relative;
background: transparent; background: transparent;
pointer-events: none; pointer-events: none;
column-gap: 3.1rem; background-color: #f9fafa;
@media (max-width: 768px) {
border-radius: 2.5rem;
padding: 0.32rem 1.7rem;
}
&:hover {
background: #f8faff;
}
img {
width: 3.8rem;
height: 3.8rem;
@media (max-width: 768px) {
width: 2.7rem;
height: 2.7rem;
}
}
span {
font-size: 1.4rem;
margin-left: 1.4rem;
@media (max-width: 768px) {
font-size: 1.2rem;
margin-left: 1rem;
}
}
} }
.g_id_signin { .g_id_signin {
position: absolute; position: absolute;
width: 100%; width: 100%;
height: 100%; height: 100%;
// overflow: hidden;
top: 0; top: 0;
left: 0; left: 0;
// opacity: 0; // opacity: 0;
.S9gUrf-YoZ4jf {
}
:deep(.S9gUrf-YoZ4jf) { :deep(.S9gUrf-YoZ4jf) {
&,
& > div {
width: 100%; width: 100%;
height: 100%; height: 100%;
}
iframe { iframe {
zoom: 3; zoom: 3;
} }
} }
} }
} &:hover {
.icon {
.google-icon { background: #f8faff;
width: 4.8rem; }
height: 4.8rem; }
} }
</style> </style>