mirror of
https://gitee.com/nicefold/seewis-soybean-plus.git
synced 2026-10-14 03:52:28 +08:00
refactor(auth): 移除多租户前端逻辑并修复接口加密密钥
- 删除租户选择组件 tenant-select.vue 及全局头部的引用 - 删除 fetchTenantList 接口调用及登录/注册页的租户列表加载逻辑 - 更新 .env.dev/.env.prod/.env.test 接口加密 RSA 公钥与私钥,与后端 Nacos api-decrypt 配置配对,修复登录 BadBlockException - 登录失败后自动刷新验证码(验证码已消费需重新获取) - pnpm-workspace.yaml 允许 es5-ext 执行构建脚本 - components.d.ts 同步自动生成的图标组件声明 refactor(auth): remove frontend multi-tenant logic and fix API encryption keys - Remove tenant-select component and its usage in global header - Remove fetchTenantList API and tenant list loading in login/register pages - Update RSA public/private keys in .env files to pair with backend Nacos api-decrypt config, fixing login BadBlockException - Refresh captcha after a failed login attempt - Allow es5-ext build scripts in pnpm-workspace.yaml
This commit is contained in:
@@ -21,6 +21,6 @@ VITE_APP_ENCRYPT=Y
|
|||||||
# AES 加密头标识
|
# AES 加密头标识
|
||||||
VITE_HEADER_FLAG=encrypt-key
|
VITE_HEADER_FLAG=encrypt-key
|
||||||
# 接口加密传输 RSA 公钥与后端解密私钥对应 如更换需前后端一同更换
|
# 接口加密传输 RSA 公钥与后端解密私钥对应 如更换需前后端一同更换
|
||||||
VITE_APP_RSA_PUBLIC_KEY='MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=='
|
VITE_APP_RSA_PUBLIC_KEY='MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDvEDuRIOM3oZPWj9Ukoc5pQklR4PFH6/clnjeFqjDLIgDyQvjxhgqAZQA+E9eD6qu6FsXPmK8djcL+nh3cFHz4pX473jDvO3Sve+8yL3VRQ0n2pRgQ2a01MJsy+WwTZCBYWf0VnLRIvANUoWQgy9vz94q7Va44dg7A1/3ICf+xAwIDAQAB'
|
||||||
# 接口响应解密 RSA 私钥与后端加密公钥对应 如更换需前后端一同更换
|
# 接口响应解密 RSA 私钥与后端加密公钥对应 如更换需前后端一同更换
|
||||||
VITE_APP_RSA_PRIVATE_KEY='MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAmc3CuPiGL/LcIIm7zryCEIbl1SPzBkr75E2VMtxegyZ1lYRD+7TZGAPkvIsBcaMs6Nsy0L78n2qh+lIZMpLH8wIDAQABAkEAk82Mhz0tlv6IVCyIcw/s3f0E+WLmtPFyR9/WtV3Y5aaejUkU60JpX4m5xNR2VaqOLTZAYjW8Wy0aXr3zYIhhQQIhAMfqR9oFdYw1J9SsNc+CrhugAvKTi0+BF6VoL6psWhvbAiEAxPPNTmrkmrXwdm/pQQu3UOQmc2vCZ5tiKpW10CgJi8kCIFGkL6utxw93Ncj4exE/gPLvKcT+1Emnoox+O9kRXss5AiAMtYLJDaLEzPrAWcZeeSgSIzbL+ecokmFKSDDcRske6QIgSMkHedwND1olF8vlKsJUGK3BcdtM8w4Xq7BpSBwsloE='
|
VITE_APP_RSA_PRIVATE_KEY='MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAObq7yrxfvyieZtTjAYyrdvi59tYTXxjO5ajmPCRSXBY9M9wQ1tli297JN6mnY53UJMNyOFNSZVi8WSFoIXjpR87FmvChJlzeN/dZdd3SEs48Ee66XKeSePYqxa8oO5GKDsnajgpsOHKXSeeVSIysiIPS2/WsEqk0In9P4w3RsRFAgMBAAECgYBiMEWwce24SPICnRzuScBpvmsudrbEDIH7BOd0a6LZlcnLJwZNJ7mJlshPsHNQb+WgEf135+BBGEhioPtn0yuTdEuKP4kB9UdYUKiayWCoWhJpesv7sAD4RDClV7dhuV+gcd1AXD+YzyRIPbGm0VC2U+4q8/+UPRpVjqskbLVTgQJBAPRpou7g3S8n4XB527kq0D8I3+ZYwMxZhszwhrCDpJU319+ucmpLVwYIzDmZVeID2QQdUaDfIEViFHu95xDrGiUCQQDx3YOKn3yaEctk/ERVn7hDAyAXUbd8/pv2b24/M/l1ZevlsFem8U4Jk5Mu64t3z3YGJoymEjQmbucwT01iKhehAkEAxlnccsRmfFh/KkqauKE4M4++NTAd9zlInpUsmZ+cN8UEGnF2RTEzRKBrLOt1uWCqBB7PGiE6DVTVjr7FAQPrSQJAT5yeY87DcONSk9cFlzmPqV8p/QME5rvYEnHzVBKDlkUKNPyqnWToTvaoh9U4fyNmsfeWbEOprszqhFhWHG3GgQJAK8+ynmyFhaw63+Hx2KU5zR4hVuQso2IzrEurGxCxybV6mR7VBerb4502+EPx3PmOgxQL+niUFhcMWxcvBFP9+A=='
|
||||||
|
|||||||
@@ -18,6 +18,6 @@ VITE_APP_ENCRYPT=Y
|
|||||||
# AES 加密头标识
|
# AES 加密头标识
|
||||||
VITE_HEADER_FLAG=encrypt-key
|
VITE_HEADER_FLAG=encrypt-key
|
||||||
# 接口加密传输 RSA 公钥与后端解密私钥对应 如更换需前后端一同更换
|
# 接口加密传输 RSA 公钥与后端解密私钥对应 如更换需前后端一同更换
|
||||||
VITE_APP_RSA_PUBLIC_KEY='MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=='
|
VITE_APP_RSA_PUBLIC_KEY='MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDvEDuRIOM3oZPWj9Ukoc5pQklR4PFH6/clnjeFqjDLIgDyQvjxhgqAZQA+E9eD6qu6FsXPmK8djcL+nh3cFHz4pX473jDvO3Sve+8yL3VRQ0n2pRgQ2a01MJsy+WwTZCBYWf0VnLRIvANUoWQgy9vz94q7Va44dg7A1/3ICf+xAwIDAQAB'
|
||||||
# 接口响应解密 RSA 私钥与后端加密公钥对应 如更换需前后端一同更换
|
# 接口响应解密 RSA 私钥与后端加密公钥对应 如更换需前后端一同更换
|
||||||
VITE_APP_RSA_PRIVATE_KEY='MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAmc3CuPiGL/LcIIm7zryCEIbl1SPzBkr75E2VMtxegyZ1lYRD+7TZGAPkvIsBcaMs6Nsy0L78n2qh+lIZMpLH8wIDAQABAkEAk82Mhz0tlv6IVCyIcw/s3f0E+WLmtPFyR9/WtV3Y5aaejUkU60JpX4m5xNR2VaqOLTZAYjW8Wy0aXr3zYIhhQQIhAMfqR9oFdYw1J9SsNc+CrhugAvKTi0+BF6VoL6psWhvbAiEAxPPNTmrkmrXwdm/pQQu3UOQmc2vCZ5tiKpW10CgJi8kCIFGkL6utxw93Ncj4exE/gPLvKcT+1Emnoox+O9kRXss5AiAMtYLJDaLEzPrAWcZeeSgSIzbL+ecokmFKSDDcRske6QIgSMkHedwND1olF8vlKsJUGK3BcdtM8w4Xq7BpSBwsloE='
|
VITE_APP_RSA_PRIVATE_KEY='MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAObq7yrxfvyieZtTjAYyrdvi59tYTXxjO5ajmPCRSXBY9M9wQ1tli297JN6mnY53UJMNyOFNSZVi8WSFoIXjpR87FmvChJlzeN/dZdd3SEs48Ee66XKeSePYqxa8oO5GKDsnajgpsOHKXSeeVSIysiIPS2/WsEqk0In9P4w3RsRFAgMBAAECgYBiMEWwce24SPICnRzuScBpvmsudrbEDIH7BOd0a6LZlcnLJwZNJ7mJlshPsHNQb+WgEf135+BBGEhioPtn0yuTdEuKP4kB9UdYUKiayWCoWhJpesv7sAD4RDClV7dhuV+gcd1AXD+YzyRIPbGm0VC2U+4q8/+UPRpVjqskbLVTgQJBAPRpou7g3S8n4XB527kq0D8I3+ZYwMxZhszwhrCDpJU319+ucmpLVwYIzDmZVeID2QQdUaDfIEViFHu95xDrGiUCQQDx3YOKn3yaEctk/ERVn7hDAyAXUbd8/pv2b24/M/l1ZevlsFem8U4Jk5Mu64t3z3YGJoymEjQmbucwT01iKhehAkEAxlnccsRmfFh/KkqauKE4M4++NTAd9zlInpUsmZ+cN8UEGnF2RTEzRKBrLOt1uWCqBB7PGiE6DVTVjr7FAQPrSQJAT5yeY87DcONSk9cFlzmPqV8p/QME5rvYEnHzVBKDlkUKNPyqnWToTvaoh9U4fyNmsfeWbEOprszqhFhWHG3GgQJAK8+ynmyFhaw63+Hx2KU5zR4hVuQso2IzrEurGxCxybV6mR7VBerb4502+EPx3PmOgxQL+niUFhcMWxcvBFP9+A=='
|
||||||
|
|||||||
@@ -18,6 +18,6 @@ VITE_APP_ENCRYPT=Y
|
|||||||
# AES 加密头标识
|
# AES 加密头标识
|
||||||
VITE_HEADER_FLAG=encrypt-key
|
VITE_HEADER_FLAG=encrypt-key
|
||||||
# 接口加密传输 RSA 公钥与后端解密私钥对应 如更换需前后端一同更换
|
# 接口加密传输 RSA 公钥与后端解密私钥对应 如更换需前后端一同更换
|
||||||
VITE_APP_RSA_PUBLIC_KEY='MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=='
|
VITE_APP_RSA_PUBLIC_KEY='MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDvEDuRIOM3oZPWj9Ukoc5pQklR4PFH6/clnjeFqjDLIgDyQvjxhgqAZQA+E9eD6qu6FsXPmK8djcL+nh3cFHz4pX473jDvO3Sve+8yL3VRQ0n2pRgQ2a01MJsy+WwTZCBYWf0VnLRIvANUoWQgy9vz94q7Va44dg7A1/3ICf+xAwIDAQAB'
|
||||||
# 接口响应解密 RSA 私钥与后端加密公钥对应 如更换需前后端一同更换
|
# 接口响应解密 RSA 私钥与后端加密公钥对应 如更换需前后端一同更换
|
||||||
VITE_APP_RSA_PRIVATE_KEY='MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAmc3CuPiGL/LcIIm7zryCEIbl1SPzBkr75E2VMtxegyZ1lYRD+7TZGAPkvIsBcaMs6Nsy0L78n2qh+lIZMpLH8wIDAQABAkEAk82Mhz0tlv6IVCyIcw/s3f0E+WLmtPFyR9/WtV3Y5aaejUkU60JpX4m5xNR2VaqOLTZAYjW8Wy0aXr3zYIhhQQIhAMfqR9oFdYw1J9SsNc+CrhugAvKTi0+BF6VoL6psWhvbAiEAxPPNTmrkmrXwdm/pQQu3UOQmc2vCZ5tiKpW10CgJi8kCIFGkL6utxw93Ncj4exE/gPLvKcT+1Emnoox+O9kRXss5AiAMtYLJDaLEzPrAWcZeeSgSIzbL+ecokmFKSDDcRske6QIgSMkHedwND1olF8vlKsJUGK3BcdtM8w4Xq7BpSBwsloE='
|
VITE_APP_RSA_PRIVATE_KEY='MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAObq7yrxfvyieZtTjAYyrdvi59tYTXxjO5ajmPCRSXBY9M9wQ1tli297JN6mnY53UJMNyOFNSZVi8WSFoIXjpR87FmvChJlzeN/dZdd3SEs48Ee66XKeSePYqxa8oO5GKDsnajgpsOHKXSeeVSIysiIPS2/WsEqk0In9P4w3RsRFAgMBAAECgYBiMEWwce24SPICnRzuScBpvmsudrbEDIH7BOd0a6LZlcnLJwZNJ7mJlshPsHNQb+WgEf135+BBGEhioPtn0yuTdEuKP4kB9UdYUKiayWCoWhJpesv7sAD4RDClV7dhuV+gcd1AXD+YzyRIPbGm0VC2U+4q8/+UPRpVjqskbLVTgQJBAPRpou7g3S8n4XB527kq0D8I3+ZYwMxZhszwhrCDpJU319+ucmpLVwYIzDmZVeID2QQdUaDfIEViFHu95xDrGiUCQQDx3YOKn3yaEctk/ERVn7hDAyAXUbd8/pv2b24/M/l1ZevlsFem8U4Jk5Mu64t3z3YGJoymEjQmbucwT01iKhehAkEAxlnccsRmfFh/KkqauKE4M4++NTAd9zlInpUsmZ+cN8UEGnF2RTEzRKBrLOt1uWCqBB7PGiE6DVTVjr7FAQPrSQJAT5yeY87DcONSk9cFlzmPqV8p/QME5rvYEnHzVBKDlkUKNPyqnWToTvaoh9U4fyNmsfeWbEOprszqhFhWHG3GgQJAK8+ynmyFhaw63+Hx2KU5zR4hVuQso2IzrEurGxCxybV6mR7VBerb4502+EPx3PmOgxQL+niUFhcMWxcvBFP9+A=='
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ packages:
|
|||||||
- 'packages/*'
|
- 'packages/*'
|
||||||
allowBuilds:
|
allowBuilds:
|
||||||
'@parcel/watcher': false
|
'@parcel/watcher': false
|
||||||
|
es5-ext: true
|
||||||
esbuild: false
|
esbuild: false
|
||||||
simple-git-hooks: false
|
simple-git-hooks: false
|
||||||
vue-demi: false
|
vue-demi: false
|
||||||
|
|||||||
@@ -1,103 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { computed, onMounted, ref } from 'vue';
|
|
||||||
import type { SelectOption } from 'naive-ui';
|
|
||||||
import { useLoading } from '@sa/hooks';
|
|
||||||
import { fetchTenantList } from '@/service/api';
|
|
||||||
import { fetchChangeTenant, fetchClearTenant } from '@/service/api/system/tenant';
|
|
||||||
import { useAppStore } from '@/store/modules/app';
|
|
||||||
import { useTabStore } from '@/store/modules/tab';
|
|
||||||
import { useAuthStore } from '@/store/modules/auth';
|
|
||||||
import { useRouterPush } from '@/hooks/common/router';
|
|
||||||
|
|
||||||
defineOptions({ name: 'TenantSelect' });
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
clearable?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
withDefaults(defineProps<Props>(), {
|
|
||||||
clearable: false
|
|
||||||
});
|
|
||||||
|
|
||||||
const appStore = useAppStore();
|
|
||||||
const { userInfo } = useAuthStore();
|
|
||||||
const { clearTabs } = useTabStore();
|
|
||||||
const { toHome } = useRouterPush();
|
|
||||||
|
|
||||||
const tenantId = defineModel<CommonType.IdType>('tenantId', { required: false, default: undefined });
|
|
||||||
const enabled = defineModel<boolean>('enabled', { required: false, default: false });
|
|
||||||
|
|
||||||
const lastSelected = ref<CommonType.IdType>();
|
|
||||||
|
|
||||||
const tenantOption = ref<SelectOption[]>([]);
|
|
||||||
const { loading, startLoading, endLoading } = useLoading();
|
|
||||||
|
|
||||||
const showTenantSelect = computed<boolean>(() => {
|
|
||||||
return userInfo.user?.userId === 1 && enabled.value;
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 关闭当前页面并刷新
|
|
||||||
*
|
|
||||||
* @param msg 提示信息
|
|
||||||
* @param val 租户ID
|
|
||||||
*/
|
|
||||||
async function closeAndRefresh(msg: string, val: CommonType.IdType = '') {
|
|
||||||
lastSelected.value = val;
|
|
||||||
window.$message?.success(msg);
|
|
||||||
clearTabs([], true);
|
|
||||||
toHome();
|
|
||||||
appStore.reloadPage(500);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleChangeTenant(_tenantId: CommonType.IdType) {
|
|
||||||
if (!_tenantId) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (lastSelected.value === _tenantId) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await fetchChangeTenant(_tenantId);
|
|
||||||
closeAndRefresh('切换租户成功', _tenantId);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleClearTenant() {
|
|
||||||
await fetchClearTenant();
|
|
||||||
closeAndRefresh('切换为默认租户');
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleFetchTenantList() {
|
|
||||||
startLoading();
|
|
||||||
const { data, error } = await fetchTenantList();
|
|
||||||
if (error) return;
|
|
||||||
enabled.value = data.tenantEnabled;
|
|
||||||
if (data.tenantEnabled) {
|
|
||||||
tenantOption.value = data.voList.map(tenant => {
|
|
||||||
return {
|
|
||||||
label: tenant.companyName,
|
|
||||||
value: tenant.tenantId
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
endLoading();
|
|
||||||
}
|
|
||||||
onMounted(async () => {
|
|
||||||
if (userInfo.user?.userId !== 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await handleFetchTenantList();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<NSelect
|
|
||||||
v-if="showTenantSelect"
|
|
||||||
v-model:value="tenantId"
|
|
||||||
:clearable="clearable"
|
|
||||||
placeholder="请选择租户"
|
|
||||||
:options="tenantOption"
|
|
||||||
:loading="loading"
|
|
||||||
@update:value="handleChangeTenant"
|
|
||||||
@clear="handleClearTenant"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
|
||||||
import { useFullscreen } from '@vueuse/core';
|
import { useFullscreen } from '@vueuse/core';
|
||||||
import { GLOBAL_HEADER_MENU_ID } from '@/constants/app';
|
import { GLOBAL_HEADER_MENU_ID } from '@/constants/app';
|
||||||
import { useAppStore } from '@/store/modules/app';
|
import { useAppStore } from '@/store/modules/app';
|
||||||
import { useAuthStore } from '@/store/modules/auth';
|
|
||||||
import { useThemeStore } from '@/store/modules/theme';
|
import { useThemeStore } from '@/store/modules/theme';
|
||||||
import GlobalLogo from '../global-logo/index.vue';
|
import GlobalLogo from '../global-logo/index.vue';
|
||||||
import GlobalBreadcrumb from '../global-breadcrumb/index.vue';
|
import GlobalBreadcrumb from '../global-breadcrumb/index.vue';
|
||||||
@@ -28,11 +26,8 @@ interface Props {
|
|||||||
defineProps<Props>();
|
defineProps<Props>();
|
||||||
|
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
const authStore = useAuthStore();
|
|
||||||
const themeStore = useThemeStore();
|
const themeStore = useThemeStore();
|
||||||
const { isFullscreen, toggle } = useFullscreen();
|
const { isFullscreen, toggle } = useFullscreen();
|
||||||
|
|
||||||
const tenantId = ref<CommonType.IdType>(authStore.userInfo?.user?.tenantId || '000000');
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -44,7 +39,6 @@ const tenantId = ref<CommonType.IdType>(authStore.userInfo?.user?.tenantId || '0
|
|||||||
<GlobalBreadcrumb v-if="!appStore.isMobile" class="ml-12px" />
|
<GlobalBreadcrumb v-if="!appStore.isMobile" class="ml-12px" />
|
||||||
</div>
|
</div>
|
||||||
<div class="h-full flex-y-center justify-end">
|
<div class="h-full flex-y-center justify-end">
|
||||||
<TenantSelect v-if="!appStore.isMobile" v-model:value="tenantId" class="mr-12px w-150px" />
|
|
||||||
<GlobalSearch v-if="themeStore.header.globalSearch.visible && !appStore.isMobile" />
|
<GlobalSearch v-if="themeStore.header.globalSearch.visible && !appStore.isMobile" />
|
||||||
<MessageButton />
|
<MessageButton />
|
||||||
<FullScreen v-if="!appStore.isMobile" :full="isFullscreen" @click="toggle" />
|
<FullScreen v-if="!appStore.isMobile" :full="isFullscreen" @click="toggle" />
|
||||||
|
|||||||
@@ -1,13 +1,5 @@
|
|||||||
import { request } from '../request';
|
import { request } from '../request';
|
||||||
|
|
||||||
/** Get tenant list */
|
|
||||||
export function fetchTenantList() {
|
|
||||||
return request<Api.Auth.LoginTenant>({
|
|
||||||
url: '/auth/tenant/list',
|
|
||||||
method: 'get'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get image code */
|
/** Get image code */
|
||||||
export function fetchCaptchaCode() {
|
export function fetchCaptchaCode() {
|
||||||
return request<Api.Auth.CaptchaCode>({
|
return request<Api.Auth.CaptchaCode>({
|
||||||
|
|||||||
Vendored
+12
@@ -51,11 +51,17 @@ declare module 'vue' {
|
|||||||
IconMaterialSymbolsUploadRounded: typeof import('~icons/material-symbols/upload-rounded')['default']
|
IconMaterialSymbolsUploadRounded: typeof import('~icons/material-symbols/upload-rounded')['default']
|
||||||
IconMaterialSymbolsWarningOutlineRounded: typeof import('~icons/material-symbols/warning-outline-rounded')['default']
|
IconMaterialSymbolsWarningOutlineRounded: typeof import('~icons/material-symbols/warning-outline-rounded')['default']
|
||||||
IconMdiArrowDownThin: typeof import('~icons/mdi/arrow-down-thin')['default']
|
IconMdiArrowDownThin: typeof import('~icons/mdi/arrow-down-thin')['default']
|
||||||
|
IconMdiArrowRightThick: typeof import('~icons/mdi/arrow-right-thick')['default']
|
||||||
IconMdiArrowUpThin: typeof import('~icons/mdi/arrow-up-thin')['default']
|
IconMdiArrowUpThin: typeof import('~icons/mdi/arrow-up-thin')['default']
|
||||||
|
IconMdiCheckCircleOutline: typeof import('~icons/mdi/check-circle-outline')['default']
|
||||||
IconMdiDrag: typeof import('~icons/mdi/drag')['default']
|
IconMdiDrag: typeof import('~icons/mdi/drag')['default']
|
||||||
IconMdiGithub: typeof import('~icons/mdi/github')['default']
|
IconMdiGithub: typeof import('~icons/mdi/github')['default']
|
||||||
IconMdiKeyboardEsc: typeof import('~icons/mdi/keyboard-esc')['default']
|
IconMdiKeyboardEsc: typeof import('~icons/mdi/keyboard-esc')['default']
|
||||||
IconMdiKeyboardReturn: typeof import('~icons/mdi/keyboard-return')['default']
|
IconMdiKeyboardReturn: typeof import('~icons/mdi/keyboard-return')['default']
|
||||||
|
IconMdiLoading: typeof import('~icons/mdi/loading')['default']
|
||||||
|
IconMdiRefresh: typeof import('~icons/mdi/refresh')['default']
|
||||||
|
IconMdiShieldAlertOutline: typeof import('~icons/mdi/shield-alert-outline')['default']
|
||||||
|
IconMdiShieldCheckOutline: typeof import('~icons/mdi/shield-check-outline')['default']
|
||||||
IconOcticonPin16: typeof import('~icons/octicon/pin16')['default']
|
IconOcticonPin16: typeof import('~icons/octicon/pin16')['default']
|
||||||
IconOcticonPinSlash16: typeof import('~icons/octicon/pin-slash16')['default']
|
IconOcticonPinSlash16: typeof import('~icons/octicon/pin-slash16')['default']
|
||||||
IconQuillCollapse: typeof import('~icons/quill/collapse')['default']
|
IconQuillCollapse: typeof import('~icons/quill/collapse')['default']
|
||||||
@@ -202,11 +208,17 @@ declare global {
|
|||||||
const IconMaterialSymbolsUploadRounded: typeof import('~icons/material-symbols/upload-rounded')['default']
|
const IconMaterialSymbolsUploadRounded: typeof import('~icons/material-symbols/upload-rounded')['default']
|
||||||
const IconMaterialSymbolsWarningOutlineRounded: typeof import('~icons/material-symbols/warning-outline-rounded')['default']
|
const IconMaterialSymbolsWarningOutlineRounded: typeof import('~icons/material-symbols/warning-outline-rounded')['default']
|
||||||
const IconMdiArrowDownThin: typeof import('~icons/mdi/arrow-down-thin')['default']
|
const IconMdiArrowDownThin: typeof import('~icons/mdi/arrow-down-thin')['default']
|
||||||
|
const IconMdiArrowRightThick: typeof import('~icons/mdi/arrow-right-thick')['default']
|
||||||
const IconMdiArrowUpThin: typeof import('~icons/mdi/arrow-up-thin')['default']
|
const IconMdiArrowUpThin: typeof import('~icons/mdi/arrow-up-thin')['default']
|
||||||
|
const IconMdiCheckCircleOutline: typeof import('~icons/mdi/check-circle-outline')['default']
|
||||||
const IconMdiDrag: typeof import('~icons/mdi/drag')['default']
|
const IconMdiDrag: typeof import('~icons/mdi/drag')['default']
|
||||||
const IconMdiGithub: typeof import('~icons/mdi/github')['default']
|
const IconMdiGithub: typeof import('~icons/mdi/github')['default']
|
||||||
const IconMdiKeyboardEsc: typeof import('~icons/mdi/keyboard-esc')['default']
|
const IconMdiKeyboardEsc: typeof import('~icons/mdi/keyboard-esc')['default']
|
||||||
const IconMdiKeyboardReturn: typeof import('~icons/mdi/keyboard-return')['default']
|
const IconMdiKeyboardReturn: typeof import('~icons/mdi/keyboard-return')['default']
|
||||||
|
const IconMdiLoading: typeof import('~icons/mdi/loading')['default']
|
||||||
|
const IconMdiRefresh: typeof import('~icons/mdi/refresh')['default']
|
||||||
|
const IconMdiShieldAlertOutline: typeof import('~icons/mdi/shield-alert-outline')['default']
|
||||||
|
const IconMdiShieldCheckOutline: typeof import('~icons/mdi/shield-check-outline')['default']
|
||||||
const IconOcticonPin16: typeof import('~icons/octicon/pin16')['default']
|
const IconOcticonPin16: typeof import('~icons/octicon/pin16')['default']
|
||||||
const IconOcticonPinSlash16: typeof import('~icons/octicon/pin-slash16')['default']
|
const IconOcticonPinSlash16: typeof import('~icons/octicon/pin-slash16')['default']
|
||||||
const IconQuillCollapse: typeof import('~icons/quill/collapse')['default']
|
const IconQuillCollapse: typeof import('~icons/quill/collapse')['default']
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { computed, reactive, ref } from 'vue';
|
|||||||
import type { SelectOption } from 'naive-ui';
|
import type { SelectOption } from 'naive-ui';
|
||||||
import { useLoading } from '@sa/hooks';
|
import { useLoading } from '@sa/hooks';
|
||||||
import CryptoJS from 'crypto-js';
|
import CryptoJS from 'crypto-js';
|
||||||
import { fetchCaptchaCode, fetchTenantList } from '@/service/api';
|
import { fetchCaptchaCode } from '@/service/api';
|
||||||
import { fetchSocialAuthBinding } from '@/service/api/system';
|
import { fetchSocialAuthBinding } from '@/service/api/system';
|
||||||
import { useAuthStore } from '@/store/modules/auth';
|
import { useAuthStore } from '@/store/modules/auth';
|
||||||
import { useRouterPush } from '@/hooks/common/router';
|
import { useRouterPush } from '@/hooks/common/router';
|
||||||
@@ -22,7 +22,7 @@ const authStore = useAuthStore();
|
|||||||
const { toggleLoginModule } = useRouterPush();
|
const { toggleLoginModule } = useRouterPush();
|
||||||
const { formRef, validate } = useNaiveForm();
|
const { formRef, validate } = useNaiveForm();
|
||||||
const { loading: codeLoading, startLoading: startCodeLoading, endLoading: endCodeLoading } = useLoading();
|
const { loading: codeLoading, startLoading: startCodeLoading, endLoading: endCodeLoading } = useLoading();
|
||||||
const { loading: tenantLoading, startLoading: startTenantLoading, endLoading: endTenantLoading } = useLoading();
|
const { loading: tenantLoading } = useLoading();
|
||||||
|
|
||||||
const codeUrl = ref<string>();
|
const codeUrl = ref<string>();
|
||||||
const captchaEnabled = ref<boolean>(false);
|
const captchaEnabled = ref<boolean>(false);
|
||||||
@@ -55,24 +55,6 @@ const rules = computed<Record<RuleKey, App.Global.FormRule[]>>(() => {
|
|||||||
return loginRules;
|
return loginRules;
|
||||||
});
|
});
|
||||||
|
|
||||||
async function handleFetchTenantList() {
|
|
||||||
startTenantLoading();
|
|
||||||
const { data, error } = await fetchTenantList();
|
|
||||||
if (error) return;
|
|
||||||
tenantEnabled.value = data.tenantEnabled;
|
|
||||||
if (data.tenantEnabled) {
|
|
||||||
tenantOption.value = data.voList.map(tenant => {
|
|
||||||
return {
|
|
||||||
label: tenant.companyName,
|
|
||||||
value: tenant.tenantId
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
endTenantLoading();
|
|
||||||
}
|
|
||||||
|
|
||||||
handleFetchTenantList();
|
|
||||||
|
|
||||||
async function handleSubmit() {
|
async function handleSubmit() {
|
||||||
await validate();
|
await validate();
|
||||||
// 勾选了需要记住密码设置在 localStorage 中设置记住用户名和密码
|
// 勾选了需要记住密码设置在 localStorage 中设置记住用户名和密码
|
||||||
@@ -86,6 +68,7 @@ async function handleSubmit() {
|
|||||||
try {
|
try {
|
||||||
await authStore.login(model);
|
await authStore.login(model);
|
||||||
} catch {
|
} catch {
|
||||||
|
// 登录失败后验证码已消费,刷新并重置
|
||||||
handleFetchCaptchaCode();
|
handleFetchCaptchaCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { computed, reactive, ref } from 'vue';
|
import { computed, reactive, ref } from 'vue';
|
||||||
import type { SelectOption } from 'naive-ui';
|
import type { SelectOption } from 'naive-ui';
|
||||||
import { useLoading } from '@sa/hooks';
|
import { useLoading } from '@sa/hooks';
|
||||||
import { fetchCaptchaCode, fetchRegister, fetchTenantList } from '@/service/api';
|
import { fetchCaptchaCode, fetchRegister } from '@/service/api';
|
||||||
import { useRouterPush } from '@/hooks/common/router';
|
import { useRouterPush } from '@/hooks/common/router';
|
||||||
import { useFormRules, useNaiveForm } from '@/hooks/common/form';
|
import { useFormRules, useNaiveForm } from '@/hooks/common/form';
|
||||||
import { $t } from '@/locales';
|
import { $t } from '@/locales';
|
||||||
@@ -72,20 +72,6 @@ async function handleSubmit() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleFetchTenantList() {
|
|
||||||
const { data, error } = await fetchTenantList();
|
|
||||||
if (error) return;
|
|
||||||
tenantEnabled.value = data.tenantEnabled;
|
|
||||||
tenantOption.value = data.voList.map(tenant => {
|
|
||||||
return {
|
|
||||||
label: tenant.companyName,
|
|
||||||
value: tenant.tenantId
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
handleFetchTenantList();
|
|
||||||
|
|
||||||
async function handleFetchCaptchaCode() {
|
async function handleFetchCaptchaCode() {
|
||||||
startCodeLoading();
|
startCodeLoading();
|
||||||
const { data, error } = await fetchCaptchaCode();
|
const { data, error } = await fetchCaptchaCode();
|
||||||
|
|||||||
Reference in New Issue
Block a user