From ee7ac8df8bce38add1f75baf876b49de94b9e00a Mon Sep 17 00:00:00 2001
From: liu <2021943741@qq.com>
Date: 星期五, 16 十月 2026 17:58:33 +0800
Subject: [PATCH] feat(mes): 赋码管理绑定托盘支持未录入批次的袋码

---
 src/views/_core/authentication/login.vue |  179 +++++++++++++++++++++--------------------------------------
 1 files changed, 65 insertions(+), 114 deletions(-)

diff --git a/src/views/_core/authentication/login.vue b/src/views/_core/authentication/login.vue
index 9df6483..92c9711 100644
--- a/src/views/_core/authentication/login.vue
+++ b/src/views/_core/authentication/login.vue
@@ -1,31 +1,25 @@
 <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 { computed, 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, Verification, z } from '@vben/common-ui';
+import { isCaptchaEnable } from '@vben/hooks';
+import { $t } from '@vben/locales';
 
-import {
-  checkCaptcha,
-  getCaptcha,
-  getTenantByWebsite,
-  getTenantSimpleList,
-  socialAuthRedirect,
-} from '#/api/core/auth';
+import { checkCaptcha, getCaptcha } from '#/api/core/auth';
 import { useAuthStore } from '#/store';
+import { selectTerminal, terminalType } from '#/mobile/terminal';
+import { errorText } from '#/mobile/api';
+import { useRoute } from 'vue-router';
 
 defineOptions({ name: 'Login' });
 
-const { query } = useRoute();
 const authStore = useAuthStore();
-const accessStore = useAccessStore();
-const tenantEnable = isTenantEnable();
+const route = useRoute();
+const loginError = ref(route.query.loadError ? '鑿滃崟鍔犺浇澶辫触锛岃閲嶆柊鐧诲綍鍚庨噸璇曘��' : '');
 const captchaEnable = isCaptchaEnable();
 
 const loginRef = ref();
@@ -33,117 +27,37 @@
 
 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);
-  }
-}
-
 /** 澶勭悊鐧诲綍 */
-async function handleLogin(values: any) {
-  // 濡傛灉寮�鍚獙璇佺爜锛屽垯鍏堥獙璇侀獙璇佺爜
+async function handleLogin(values: AuthApi.LoginParams) {
   if (captchaEnable) {
     verifyRef.value.show();
     return;
   }
-  // 鏃犻獙璇佺爜锛岀洿鎺ョ櫥褰�
-  await authStore.authLogin('username', values);
+  loginError.value = '';
+  try { await authStore.authLogin('username', values); }
+  catch (e) { loginError.value = errorText(e); }
 }
 
 /** 楠岃瘉鐮侀�氳繃锛屾墽琛岀櫥褰� */
-async function handleVerifySuccess({ captchaVerification }: any) {
-  try {
-    await authStore.authLogin('username', {
-      ...(await loginRef.value.getFormApi().getValues()),
-      captchaVerification,
-    });
-  } catch (error) {
-    console.error('Error in handleLogin:', error);
-  }
+async function handleVerifySuccess({
+  captchaVerification,
+}: {
+  captchaVerification: string;
+}) {
+  loginError.value = '';
+  try { await authStore.authLogin('username', {
+    ...(await loginRef.value.getFormApi().getValues()),
+    captchaVerification,
+  }); } catch (e) { loginError.value = errorText(e); }
 }
-
-/** 澶勭悊绗笁鏂圭櫥褰� */
-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();
-});
 
 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: 'VbenInput',
       componentProps: {
+        'aria-label': $t('authentication.username'),
+        autocomplete: 'username',
         placeholder: $t('authentication.usernameTip'),
       },
       fieldName: 'username',
@@ -156,6 +70,8 @@
     {
       component: 'VbenInputPassword',
       componentProps: {
+        'aria-label': $t('authentication.password'),
+        autocomplete: 'current-password',
         placeholder: $t('authentication.passwordTip'),
       },
       fieldName: 'password',
@@ -171,13 +87,37 @@
 
 <template>
   <div>
+    <fieldset class="terminal-selector">
+      <legend>閫夋嫨浣跨敤绔�</legend>
+      <div class="terminal-options">
+        <label :class="{ selected: terminalType === 'mobile' }">
+          <input type="radio" name="terminal" value="mobile" :checked="terminalType === 'mobile'" :disabled="authStore.loginLoading" @change="selectTerminal('mobile')" />
+          <span>绉诲姩绔�</span>
+        </label>
+        <label :class="{ selected: terminalType === 'pc' }">
+          <input type="radio" name="terminal" value="pc" :checked="terminalType === 'pc'" :disabled="authStore.loginLoading" @change="selectTerminal('pc')" />
+          <span>PC 绔�</span>
+        </label>
+      </div>
+      <p>宸叉寜灞忓箷澶у皬閫夋嫨锛屽彲鎵嬪姩鍒囨崲</p>
+    </fieldset>
     <AuthenticationLogin
       ref="loginRef"
       :form-schema="formSchema"
       :loading="authStore.loginLoading"
+      :show-field-labels="terminalType === 'mobile'"
+      :submit-button-text="terminalType === 'mobile' ? '鐧诲綍绉诲姩绔�' : '鐧诲綍 PC 绔�'"
+      title="娆㈣繋鍥炴潵"
+      :sub-title="terminalType === 'mobile' ? '浣跨敤宸叉湁璐﹀彿鐧诲綍鐜板満浣滀笟' : '鐧诲綍绉嶆涓氭暟瀛楀寲骞冲彴锛屽紑鍚櫤鎱х妞�'"
+      :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"
     />
+    <p v-if="loginError" class="login-error" role="alert">{{loginError}}</p>
     <Verification
       ref="verifyRef"
       v-if="captchaEnable"
@@ -190,3 +130,14 @@
     />
   </div>
 </template>
+
+<style scoped>
+.terminal-selector { border: 0; margin: 0 0 24px; padding: 0; }
+.login-error { padding:12px;color:#b91c1c;background:#fef2f2;border-radius:8px; }
+.terminal-selector legend { font-size: 16px; margin-bottom: 8px; }
+.terminal-options { display: flex; gap: 12px; }
+.terminal-options label { display:flex;align-items:center;justify-content:center;gap:8px;flex:1;min-height:52px;border:1px solid #64748b;border-radius:8px;cursor:pointer; }
+.terminal-options label.selected { border-color:#0369a1;color:#0369a1;background:#f0f9ff; }
+.terminal-options label:focus-within { outline:2px solid #0369a1;outline-offset:2px; }
+.terminal-selector p { margin-top:8px;color:#475569;font-size:14px; }
+</style>

--
Gitblit v1.9.3