From 7981c8b76ea5708bfb75b59fcd65252e72ed72f3 Mon Sep 17 00:00:00 2001
From: liu <2021943741@qq.com>
Date: 星期二, 20 十月 2026 14:09:55 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_江苏商贸供销社' into dev_江苏商贸供销社

---
 src/views/_core/authentication/login.vue |  129 ++++++++++++++++++++++++++++++++++--------
 1 files changed, 103 insertions(+), 26 deletions(-)

diff --git a/src/views/_core/authentication/login.vue b/src/views/_core/authentication/login.vue
index e63e399..90d4140 100644
--- a/src/views/_core/authentication/login.vue
+++ b/src/views/_core/authentication/login.vue
@@ -1,20 +1,22 @@
 <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 { 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,
   getCaptcha,
   getTenantByWebsite,
   getTenantSimpleList,
+  socialAuthRedirect,
 } from '#/api/core/auth';
 import { useAuthStore } from '#/store';
 
@@ -72,32 +74,51 @@
   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 鍙傛暟浼氳鍚炴帀锛屽鑷存棤娉曡瘑鍒ぞ浜ょ被鍨�
+    // 鍥炶皟鍦板潃蹇呴』甯� hash 鍓嶇紑锛氱敓浜х敤 hash 璺敱锛圴ITE_ROUTER_HISTORY=hash锛夛紝
+    // 灏戜簡 # 浼佷笟寰俊鍥炶烦鍚� vue-router 浼氳В鏋愬埌 /锛岃惤鍒扮櫥褰曢〉鑰屼笉鏄� social-login 椤甸潰
+    const hashPrefix =
+      import.meta.env.VITE_ROUTER_HISTORY === 'hash' ? '/#' : '';
+    const redirectUri = `${location.origin}${hashPrefix}/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'),
-    //   dependencies: {
-    //     triggerFields: ['tenantId'],
-    //     if: tenantEnable,
-    //     trigger(values) {
-    //       accessStore.setTenantId(values.tenantId ? Number(values.tenantId) : null);
-    //     },
-    //   },
-    // },
     {
       component: 'VbenInput',
       componentProps: {
+        autocomplete: 'username',
         placeholder: $t('authentication.usernameTip'),
       },
+      hideLabel: false,
+      labelWidth: 44,
       fieldName: 'username',
       label: $t('authentication.username'),
       rules: z
@@ -108,8 +129,11 @@
     {
       component: 'VbenInputPassword',
       componentProps: {
+        autocomplete: 'current-password',
         placeholder: $t('authentication.passwordTip'),
       },
+      hideLabel: false,
+      labelWidth: 44,
       fieldName: 'password',
       label: $t('authentication.password'),
       rules: z
@@ -122,7 +146,7 @@
 </script>
 
 <template>
-  <div>
+  <div class="academic-login-wrapper">
     <AuthenticationLogin
       ref="loginRef"
       :form-schema="formSchema"
@@ -133,8 +157,39 @@
       :show-register="false"
       :show-forget-password="false"
       :show-doc-link="false"
+      class="academic-login-form"
       @submit="handleLogin"
-    />
+    >
+      <!-- 鑷畾涔夋爣棰橈細瑕嗙洊娆㈣繋璇� -->
+      <template #title>
+        <div class="academic-title-area">
+          <h2 class="academic-title">璐﹀彿鐧诲綍</h2>
+          <p class="academic-subtitle">娆㈣繋鍥炴潵锛岃浣跨敤鎮ㄧ殑璐﹀彿鐧诲綍</p>
+        </div>
+      </template>
+
+      <!-- 绗笁鏂圭櫥褰� -->
+      <template #third-party-login>
+        <div class="academic-third-party">
+          <div class="academic-divider">
+            <span class="academic-divider-line"></span>
+            <span class="academic-divider-text">鍏朵粬鐧诲綍鏂瑰紡</span>
+            <span class="academic-divider-line"></span>
+          </div>
+          <VbenButton
+            class="academic-wxcp-btn"
+            variant="outline"
+            :loading="wxcpLoading"
+            @click="handleWxcpLogin"
+          >
+            <SvgWeChatIcon class="mr-2 size-4" />
+            浼佷笟寰俊鐧诲綍
+          </VbenButton>
+        </div>
+      </template>
+    </AuthenticationLogin>
+
+    <!-- 楠岃瘉鐮侊紙婊戝潡鎷煎浘锛夛紝captchaEnable 鏃跺惎鐢� -->
     <Verification
       ref="verifyRef"
       v-if="captchaEnable"
@@ -147,3 +202,25 @@
     />
   </div>
 </template>
+
+<style scoped>
+.academic-login-wrapper { width: 100%; }
+.academic-title-area { margin-bottom: 28px; }
+.academic-title { margin: 0 0 10px; color: #18365a; font-size: 26px; font-weight: 750; line-height: 1.4; }
+.academic-subtitle { margin: 0; color: #5c7187; font-size: 13px; line-height: 1.7; }
+:deep(.academic-login-form label) { color: #294d70; font-size: 13px; font-weight: 600; }
+:deep(.academic-login-form input:not([type=checkbox])) { min-height: 46px; border-radius: 6px; border-color: #d6e1ec; background: #f8fbfe; color: #18365a; font-size: 14px; }
+:deep(.academic-login-form input::placeholder) { color: #5c7187; }
+:deep(.academic-login-form input:focus-visible) { border-color: #3476b5; outline-color: #3476b5; background: #fff; }
+:deep(.academic-login-form button[aria-label=login]) { height: 46px; border: 0; border-radius: 6px; color: #fff; background: #b7242d; font-size: 15px; font-weight: 650; letter-spacing: .16em; box-shadow: 0 4px 12px rgb(150 30 40 / 12%); }
+:deep(.academic-login-form button[aria-label=login]:hover) { background: #9f1d27; }
+:deep(.academic-login-form button[aria-label=login]:disabled) { opacity: .65; cursor: wait; }
+:deep(.academic-login-form .vben-link) { color: #28659d; }
+.academic-third-party { margin-top: 24px; }
+.academic-divider { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
+.academic-divider-line { height: 1px; flex: 1; background: #e4ecf3; }
+.academic-divider-text { color: #5c7187; font-size: 12px; white-space: nowrap; }
+.academic-wxcp-btn { width: 100%; height: 44px; border: 1px solid #d8e4ee; border-radius: 6px; color: #315777; background: #fff; font-size: 13px; }
+.academic-wxcp-btn:hover { border-color: #8cb5d5; background: #f3f8fc; }
+:deep(button:focus-visible) { outline: 2px solid #2c70b2; outline-offset: 3px; }
+</style>

--
Gitblit v1.9.3