Explorar o código

feat: google登陆完成

chenpeng hai 2 semanas
pai
achega
87cdda808a

+ 96 - 0
components/common/googleLogin/index.vue

@@ -0,0 +1,96 @@
+<script setup>
+const emit = defineEmits(['success', 'error'])
+const loading = ref(false)
+const clientID = '482169597782-nic3d8bo67o0gmq93cmgao7050ets16n.apps.googleusercontent.com'
+onMounted(() => {
+  const script = document.createElement('script')
+  script.src = 'https://accounts.google.com/gsi/client'
+  script.async = true
+  script.defer = true
+  document.head.appendChild(script)
+})
+
+/**
+ * 初始化 Google Auth
+ */
+function initializeGoogleAuth(resolve, reject) {
+  return window.google.accounts.oauth2.initTokenClient({
+    client_id: clientID,
+    scope: 'email profile',
+    callback: async (response) => {
+      try {
+        // 获取用户基本信息
+        const userInfo = await fetchUserInfo(response.access_token)
+        const res = {
+          token: response.access_token,
+          userInfo,
+        }
+        resolve(res)
+      }
+      catch (error) {
+        reject(error)
+      }
+    },
+    error_callback: (error) => {
+      reject(error)
+    },
+  })
+}
+
+/**
+ * 获取用户详细信息
+ */
+async function fetchUserInfo(accessToken) {
+  const res = await fetch('https://www.googleapis.com/oauth2/v3/userinfo', {
+    headers: {
+      Authorization: `Bearer ${accessToken}`,
+    },
+  })
+  if (!res.ok)
+    throw new Error('获取用户信息失败')
+  return await res.json()
+}
+
+// 触发登录
+function handleGoogleLogin() {
+  return new Promise((resolve, reject) => {
+    if (!window.google) {
+      const t = setTimeout(() => {
+        clearTimeout(t)
+        ElMessage.error('当前环境不支持 Google 登录,请使用其他方式登录')
+        reject(new Error('Google SDK not loaded'))
+      }, 1000)
+      return
+    }
+    const client = initializeGoogleAuth(resolve, reject)
+    client.requestAccessToken()
+  })
+}
+
+async function onGoogleLogin() {
+  try {
+    loading.value = true
+    const result = await handleGoogleLogin()
+    loading.value = false
+    console.log('result------登陆成功', result)
+    emit('success', result)
+  }
+  catch (error) {
+    loading.value = false
+    emit('error', error)
+  }
+}
+</script>
+
+<template>
+  <button id="google-login-button" class="b-rd-200px w-100% bg-#fff text-#333 b-1px b-solid b-#D8D8D8 h-48px lh-48px hover:b-#9B6CFF disabled:hover:b-#D8D8D8 cursor-pointer mb-24px text-14px fw-500" :disabled="loading" @click="onGoogleLogin">
+    <span v-if="loading">登录中...</span>
+    <div v-else class="flex justify-center items-center">
+      <img src="@/assets/images/google_logo.png" alt="" class="w-24px h-24px mr-10px">
+      Continue with Google
+    </div>
+  </button>
+</template>
+
+<style scoped>
+</style>

+ 1 - 5
components/common/login/comp/choice.vue

@@ -12,15 +12,11 @@ const { onSelectEmail } = useLogin()
     <div class="text-14px text-#1A1A1A lh-22px mb-20px">
       Use your Email or another service to continue with EJET Spark!
     </div>
-    <div class="b-rd-200px bg-#fff text-#333 b-1px b-solid b-#D8D8D8 h-48px lh-48px hover:b-#9B6CFF flex justify-center items-center cursor-pointer mb-24px text-14px fw-500">
-      <img src="@/assets/images/google_logo.png" alt="" class="w-24px h-24px mr-10px">
-      Continue with Google
-    </div>
+    <common-google-login class="mb-24px" />
     <div class="b-rd-200px bg-#fff b-1px text-#333 b-solid b-#D8D8D8 h-48px lh-48px hover:b-#9B6CFF flex justify-center items-center cursor-pointer text-14px fw-500" @click="onSelectEmail">
       <img src="@/assets/images/mail_logo.png" class="w-24px h-24px mr-10px" alt="">
       Continue with Email
     </div>
-
     <div class="mt-40px lh-22px text-14px text-#767676">
       By continuing, you agree to EJET Spark’s <span class="text-#1A1A1A underline cursor-pointer fw-500">Terms of Use⁠.</span> Read our
       <span class="text-#1A1A1A underline cursor-pointer fw-500">Privacy Policy⁠.</span>

+ 11 - 11
stores/modules/common.ts

@@ -11,17 +11,17 @@ export const useCommonStore = defineStore(
     const isCompletedInfo = ref<boolean>(true) // 是否提交过的信息
     const loginType = ref<string>('choice')
     const downloadCatalog = ref<any>(null)
-    const accountList = ref([
-      {
-        name: 'EJET Spark 12',
-        email: '185@163.com',
-        id: '1',
-      },
-      {
-        name: 'EJET Spark 34',
-        email: '18525917172@gmail.com',
-        id: '2',
-      },
+    const accountList = ref<any>([
+      // {
+      //   name: 'EJET Spark 12',
+      //   email: '185@163.com',
+      //   id: '1',
+      // },
+      // {
+      //   name: 'EJET Spark 34',
+      //   email: '18525917172@gmail.com',
+      //   id: '2',
+      // },
     ])
     // const userStore = useUserStore()