Procházet zdrojové kódy

完善SSO单点登录

puhui999 před 2 roky
rodič
revize
e22363d061

+ 10 - 3
src/api/login/index.ts

@@ -76,7 +76,14 @@ export const reqCheckApi = (data) => {
 }
 
 // ========== OAUTH 2.0 相关 ==========
-
+export type scopesType = string[]
+export interface paramsType {
+  responseType: string
+  clientId: string
+  redirectUri: string
+  state: string
+  scopes: scopesType
+}
 export const getAuthorize = (clientId) => {
   return request.get({ url: '/system/oauth2/authorize?clientId=' + clientId })
 }
@@ -87,8 +94,8 @@ export function authorize(
   redirectUri: string,
   state: string,
   autoApprove: boolean,
-  checkedScopes: any,
-  uncheckedScopes: any
+  checkedScopes: scopesType,
+  uncheckedScopes: scopesType
 ) {
   // 构建 scopes
   const scopes = {}

+ 9 - 24
src/views/Login/Login.vue

@@ -9,19 +9,19 @@
       >
         <!-- 左上角的 logo + 系统标题 -->
         <div class="flex items-center relative text-white">
-          <img src="@/assets/imgs/logo.png" alt="" class="w-48px h-48px mr-10px" />
+          <img alt="" class="w-48px h-48px mr-10px" src="@/assets/imgs/logo.png" />
           <span class="text-20px font-bold">{{ underlineToHump(appStore.getTitle) }}</span>
         </div>
         <!-- 左边的背景图 + 欢迎语 -->
         <div class="flex justify-center items-center h-[calc(100%-60px)]">
           <TransitionGroup
             appear
-            tag="div"
             enter-active-class="animate__animated animate__bounceInLeft"
+            tag="div"
           >
-            <img src="@/assets/svgs/login-box-bg.svg" key="1" alt="" class="w-350px" />
-            <div class="text-3xl text-white" key="2">{{ t('login.welcome') }}</div>
-            <div class="mt-5 font-normal text-white text-14px" key="3">
+            <img key="1" alt="" class="w-350px" src="@/assets/svgs/login-box-bg.svg" />
+            <div key="2" class="text-3xl text-white">{{ t('login.welcome') }}</div>
+            <div key="3" class="mt-5 font-normal text-white text-14px">
               {{ t('login.message') }}
             </div>
           </TransitionGroup>
@@ -31,7 +31,7 @@
         <!-- 右上角的主题、语言选择 -->
         <div class="flex justify-between items-center text-white @2xl:justify-end @xl:justify-end">
           <div class="flex items-center @2xl:hidden @xl:hidden">
-            <img src="@/assets/imgs/logo.png" alt="" class="w-48px h-48px mr-10px" />
+            <img alt="" class="w-48px h-48px mr-10px" src="@/assets/imgs/logo.png" />
             <span class="text-20px font-bold">{{ underlineToHump(appStore.getTitle) }}</span>
           </div>
           <div class="flex justify-end items-center space-x-10px">
@@ -52,18 +52,15 @@
             <QrCodeForm class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)" />
             <!-- 注册 -->
             <RegisterForm class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)" />
-            <!-- 三方登录 v-if触发组件初始化 -->
-            <SSOLoginVue
-              v-if="isSSO"
-              class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)"
-            />
+            <!-- 三方登录 -->
+            <SSOLoginVue class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)" />
           </div>
         </Transition>
       </div>
     </div>
   </div>
 </template>
-<script setup lang="ts">
+<script lang="ts" setup>
 import { underlineToHump } from '@/utils'
 
 import { useDesign } from '@/hooks/web/useDesign'
@@ -72,23 +69,11 @@ import { ThemeSwitch } from '@/layout/components/ThemeSwitch'
 import { LocaleDropdown } from '@/layout/components/LocaleDropdown'
 
 import { LoginForm, MobileForm, QrCodeForm, RegisterForm, SSOLoginVue } from './components'
-import { RouteLocationNormalizedLoaded } from 'vue-router'
 
 const { t } = useI18n()
 const appStore = useAppStore()
 const { getPrefixCls } = useDesign()
 const prefixCls = getPrefixCls('login')
-// =======SSO======
-const isSSO = ref(false)
-const router = useRouter()
-// 监听当前路由
-watch(
-  () => router.currentRoute.value,
-  (route: RouteLocationNormalizedLoaded) => {
-    if (route.name === 'SSOLogin') isSSO.value = true
-  },
-  { immediate: true }
-)
 </script>
 
 <style lang="scss" scoped>

+ 0 - 1
src/views/Login/components/LoginForm.vue

@@ -279,7 +279,6 @@ const doSocialLogin = async (type: number) => {
 watch(
   () => currentRoute.value,
   (route: RouteLocationNormalizedLoaded) => {
-    if (route.name === 'SSOLogin') setLoginState(LoginStateEnum.SSO)
     redirect.value = route?.query?.redirect as string
   },
   {

+ 24 - 14
src/views/Login/components/SSOLogin.vue

@@ -1,6 +1,7 @@
 <template>
   <!-- 表单 -->
-  <div class="form-cont">
+  <div v-show="getShow" class="form-cont">
+    <!--    <LoginFormTitle style="width: 100%" />-->
     <el-tabs class="form" style="float: none" value="uname">
       <el-tab-pane :label="'三方授权(' + client.name + ')'" name="uname" />
     </el-tabs>
@@ -12,8 +13,8 @@
           <el-checkbox-group v-model="loginForm.scopes">
             <el-checkbox
               v-for="scope in params.scopes"
-              :label="scope"
               :key="scope"
+              :label="scope"
               style="display: block; margin-bottom: -10px"
               >{{ formatScope(scope) }}
             </el-checkbox>
@@ -24,8 +25,8 @@
           <el-button
             :loading="loading"
             size="small"
-            type="primary"
             style="width: 60%"
+            type="primary"
             @click.prevent="handleAuthorize(true)"
           >
             <span v-if="!loading">同意授权</span>
@@ -40,19 +41,15 @@
   </div>
 </template>
 <script lang="ts" name="SSOLogin" setup>
-import { authorize, getAuthorize } from '@/api/login'
+// import LoginFormTitle from './LoginFormTitle.vue' // TODO 艿艿你看看要不要这个表头
+import { authorize, getAuthorize, paramsType, scopesType } from '@/api/login'
+import { LoginStateEnum, useLoginState } from './useLogin'
+import type { RouteLocationNormalizedLoaded } from 'vue-router'
 
 const { t } = useI18n()
 const ssoForm = ref() // 表单Ref
-
-type scopesType = string[]
-interface paramsType {
-  responseType: string
-  clientId: string
-  redirectUri: string
-  state: string
-  scopes: scopesType
-}
+const { getLoginState, setLoginState } = useLoginState()
+const getShow = computed(() => unref(getLoginState) === LoginStateEnum.SSO)
 const loginForm = reactive<{ scopes: scopesType }>({
   scopes: [] // 已选中的 scope 数组
 })
@@ -116,6 +113,7 @@ const doAuthorize = (autoApprove, checkedScopes, uncheckedScopes) => {
 const formatScope = (scope) => {
   // 格式化 scope 授权范围,方便用户理解。
   // 这里仅仅是一个 demo,可以考虑录入到字典数据中,例如说字典类型 "system_oauth2_scope",它的每个 scope 都是一条字典数据。
+  // TODO 这个之做了中文部分
   return t(`login.sso.${scope}`)
 }
 const route = useRoute()
@@ -146,7 +144,6 @@ const init = () => {
 
   // 获取授权页的基本信息
   getAuthorize(params.clientId).then((res) => {
-    console.log(res)
     client.value = res.client
     // 解析 scope
     let scopes
@@ -173,5 +170,18 @@ const init = () => {
     }
   })
 }
+// =======SSO======
+const { currentRoute } = useRouter()
+// 监听当前路由
+watch(
+  () => currentRoute.value,
+  (route: RouteLocationNormalizedLoaded) => {
+    if (route.name === 'SSOLogin') {
+      setLoginState(LoginStateEnum.SSO)
+      init()
+    }
+  },
+  { immediate: true }
+)
 init()
 </script>