From 7a6351a1fa5fc6e67b55c475bcd253d6d3e5d68f Mon Sep 17 00:00:00 2001
From: liu <2021943741@qq.com>
Date: 星期二, 29 九月 2026 13:48:31 +0800
Subject: [PATCH] feat(wxcp): 新增企业微信模块页面与扫码登录入口

---
 src/views/_core/authentication/login.vue |  161 ++++++++++++++++++++++++++++-------------------------
 1 files changed, 86 insertions(+), 75 deletions(-)

diff --git a/src/views/_core/authentication/login.vue b/src/views/_core/authentication/login.vue
index 9df6483..0d0f566 100644
--- a/src/views/_core/authentication/login.vue
+++ b/src/views/_core/authentication/login.vue
@@ -1,15 +1,15 @@
 <script lang="ts" setup>
-import type { VbenFormSchema } from '../../../packages/effects/common-ui/src';
+import type { VbenFormSchema } from '@vben/common-ui';
 
 import type { AuthApi } from '#/api/core/auth';
 
 import { computed, onMounted, ref } from 'vue';
-import { useRoute } from 'vue-router';
 
-import { AuthenticationLogin, Verification, z } from '../../../packages/effects/common-ui/src';
-import { isCaptchaEnable, isTenantEnable } from '../../../packages/effects/hooks/src';
-import { $t } from '../../../packages/locales/src';
-import { useAccessStore } from '../../../packages/stores/src';
+import { AuthenticationLogin, VbenButton, Verification, z } from '@vben/common-ui';
+import { isCaptchaEnable, isTenantEnable } from '@vben/hooks';
+import { SvgWeChatIcon } from '@vben/icons';
+import { $t } from '@vben/locales';
+import { useAccessStore } from '@vben/stores';
 
 import {
   checkCaptcha,
@@ -22,7 +22,6 @@
 
 defineOptions({ name: 'Login' });
 
-const { query } = useRoute();
 const authStore = useAuthStore();
 const accessStore = useAccessStore();
 const tenantEnable = isTenantEnable();
@@ -33,35 +32,15 @@
 
 const captchaType = 'blockPuzzle'; // 楠岃瘉鐮佺被鍨嬶細'blockPuzzle' | 'clickWord'
 
-/** 鑾峰彇绉熸埛鍒楄〃锛屽苟榛樿閫変腑 */
+/** 鑾峰彇绉熸埛鍒楄〃 */
 const tenantList = ref<AuthApi.TenantResult[]>([]); // 绉熸埛鍒楄〃
 async function fetchTenantList() {
   if (!tenantEnable) {
     return;
   }
   try {
-    // 鑾峰彇绉熸埛鍒楄〃銆佸煙鍚嶅搴旂鎴�
-    const websiteTenantPromise = getTenantByWebsite(window.location.hostname);
+    // 鑾峰彇绉熸埛鍒楄〃
     tenantList.value = await getTenantSimpleList();
-
-    // 閫変腑绉熸埛锛氬煙鍚� > store 涓殑绉熸埛 > 棣栦釜绉熸埛
-    let tenantId: null | number = null;
-    const websiteTenant = await websiteTenantPromise;
-    if (websiteTenant?.id) {
-      tenantId = websiteTenant.id;
-    }
-    // 濡傛灉娌℃湁浠庡煙鍚嶈幏鍙栧埌绉熸埛锛屽皾璇曚粠 store 涓幏鍙�
-    if (!tenantId && accessStore.tenantId) {
-      tenantId = accessStore.tenantId;
-    }
-    // 濡傛灉杩樻槸娌℃湁绉熸埛锛屼娇鐢ㄥ垪琛ㄤ腑鐨勭涓�涓�
-    if (!tenantId && tenantList.value?.[0]?.id) {
-      tenantId = tenantList.value[0].id;
-    }
-
-    // 璁剧疆閫変腑鐨勭鎴风紪鍙�
-    accessStore.setTenantId(tenantId);
-    loginRef.value.getFormApi().setFieldValue('tenantId', tenantId?.toString());
   } catch (error) {
     console.error('鑾峰彇绉熸埛鍒楄〃澶辫触:', error);
   }
@@ -90,57 +69,63 @@
   }
 }
 
-/** 澶勭悊绗笁鏂圭櫥褰� */
-const redirect = query?.redirect;
-async function handleThirdLogin(type: number) {
-  if (type <= 0) {
-    return;
-  }
-  try {
-    // 璁$畻 redirectUri
-    // tricky: type銆乺edirect 闇�瑕佸厛 encode 涓�娆★紝鍚﹀垯閽夐拤鍥炶皟浼氫涪澶便�傞厤鍚� social-login.vue#getUrlValue() 浣跨敤
-    const redirectUri = `${
-      location.origin
-    }/auth/social-login?${encodeURIComponent(
-      `type=${type}&redirect=${redirect || '/'}`,
-    )}`;
-
-    // 杩涜璺宠浆
-    window.location.href = await socialAuthRedirect(type, redirectUri);
-  } catch (error) {
-    console.error('绗笁鏂圭櫥褰曞鐞嗗け璐�:', error);
-  }
-}
-
 /** 缁勪欢鎸傝浇鏃惰幏鍙栫鎴蜂俊鎭� */
 onMounted(() => {
   fetchTenantList();
 });
 
+// ========== 浼佷笟寰俊鐧诲綍 ==========
+
+/** 浼佷笟寰俊鐨勭ぞ浜ょ被鍨嬶紝瀵瑰簲鍚庣 SocialTypeEnum.WECHAT_ENTERPRISE */
+const WXCP_SOCIAL_TYPE = 30;
+
+const wxcpLoading = ref(false);
+
+/**
+ * 浼佷笟寰俊鎵爜鐧诲綍
+ *
+ * 娴佺▼锛氬彇鎺堟潈鍦板潃 -> 鏁撮〉璺宠浆鍒颁紒涓氬井淇℃壂鐮侀〉 -> 鎵爜鍚庝紒涓氬井淇″甫 code/state
+ * 鍥炶烦鍒� social-login 椤甸潰 -> 璇ラ〉闈㈣皟鐢� /system/auth/social-login 鎹㈠彇浠ょ墝
+ */
+async function handleWxcpLogin() {
+  try {
+    wxcpLoading.value = true;
+    // 娉ㄦ剰锛歵ype 闇�瑕佸厛 encode 涓�娆★紝閰嶅悎 social-login 椤甸潰鐨� getUrlValue() 浣跨敤锛�
+    // 鍚﹀垯浼佷笟寰俊鍥炶烦鍚� type 鍙傛暟浼氳鍚炴帀锛屽鑷存棤娉曡瘑鍒ぞ浜ょ被鍨�
+    const redirectUri = `${location.origin}/auth/social-login?${encodeURIComponent(
+      `type=${WXCP_SOCIAL_TYPE}`,
+    )}`;
+    window.location.href = await socialAuthRedirect(
+      WXCP_SOCIAL_TYPE,
+      redirectUri,
+    );
+  } catch (error) {
+    console.error('浼佷笟寰俊鐧诲綍澶辫触:', error);
+    wxcpLoading.value = false;
+  }
+}
+
 const formSchema = computed((): VbenFormSchema[] => {
   return [
-    {
-      component: 'VbenSelect',
-      componentProps: {
-        options: tenantList.value.map((item) => ({
-          label: item.name,
-          value: item.id.toString(),
-        })),
-        placeholder: $t('authentication.tenantTip'),
-      },
-      fieldName: 'tenantId',
-      label: $t('authentication.tenant'),
-      rules: z.string().min(1, { message: $t('authentication.tenantTip') }),
-      dependencies: {
-        triggerFields: ['tenantId'],
-        if: tenantEnable,
-        trigger(values) {
-          if (values.tenantId) {
-            accessStore.setTenantId(Number(values.tenantId));
-          }
-        },
-      },
-    },
+    // {
+    //   component: 'VbenSelect',
+    //   componentProps: {
+    //     options: tenantList.value.map((item) => ({
+    //       label: item.name,
+    //       value: item.id.toString(),
+    //     })),
+    //     placeholder: $t('authentication.tenantTip'),
+    //   },
+    //   fieldName: 'tenantId',
+    //   label: $t('authentication.tenant'),
+    //   dependencies: {
+    //     triggerFields: ['tenantId'],
+    //     if: tenantEnable,
+    //     trigger(values) {
+    //       accessStore.setTenantId(values.tenantId ? Number(values.tenantId) : null);
+    //     },
+    //   },
+    // },
     {
       component: 'VbenInput',
       componentProps: {
@@ -175,9 +160,35 @@
       ref="loginRef"
       :form-schema="formSchema"
       :loading="authStore.loginLoading"
+      :show-code-login="false"
+      :show-qrcode-login="false"
+      :show-third-party-login="false"
+      :show-register="false"
+      :show-forget-password="false"
+      :show-doc-link="false"
       @submit="handleLogin"
-      @third-login="handleThirdLogin"
-    />
+    >
+      <template #third-party-login>
+        <div class="mt-4">
+          <div class="mb-4 flex items-center justify-between">
+            <span class="w-[35%] border-b border-input dark:border-gray-600"></span>
+            <span class="text-center text-xs text-muted-foreground">
+              鍏朵粬鐧诲綍鏂瑰紡
+            </span>
+            <span class="w-[35%] border-b border-input dark:border-gray-600"></span>
+          </div>
+          <VbenButton
+            class="w-full"
+            variant="outline"
+            :loading="wxcpLoading"
+            @click="handleWxcpLogin"
+          >
+            <SvgWeChatIcon class="mr-2 size-5" />
+            浼佷笟寰俊鐧诲綍
+          </VbenButton>
+        </div>
+      </template>
+    </AuthenticationLogin>
     <Verification
       ref="verifyRef"
       v-if="captchaEnable"

--
Gitblit v1.9.3