Merge remote-tracking branch 'origin/main' into multi-tenant

This commit is contained in:
TsMask
2024-06-27 20:19:46 +08:00
114 changed files with 4066 additions and 1781 deletions

View File

@@ -8,8 +8,16 @@ import {
} from 'antdv-pro-layout';
import RightContent from './components/RightContent.vue';
import Tabs from './components/Tabs.vue';
import GlobalMask from '@/components/GlobalMask/index.vue';
import { scriptUrl } from '@/assets/js/icon_font_8d5l8fzk5b87iudi';
import { computed, reactive, watch, onMounted, onUnmounted } from 'vue';
import {
computed,
reactive,
watch,
onMounted,
onUnmounted,
nextTick,
} from 'vue';
import useLayoutStore from '@/store/modules/layout';
import useRouterStore from '@/store/modules/router';
import useTabsStore from '@/store/modules/tabs';
@@ -21,6 +29,7 @@ const { proConfig, waterMarkContent } = useLayoutStore();
import useI18n from '@/hooks/useI18n';
import { getServerTime } from '@/api';
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
import { parseDateToStr } from '@/utils/date-utils';
import { parseUrlPath } from '@/plugins/file-static-url';
const { t, currentLocale } = useI18n();
@@ -159,8 +168,27 @@ function fnLocale(m: MenuDataItem) {
return title;
}
/**检查系统名称是否超出范围进行滚动 */
function fnCheckAppNameOverflow() {
const container: HTMLDivElement | null = document.querySelector('.app-name');
if (!container) return;
const text: HTMLDivElement | null = container.querySelector('.marquee');
if (!text) return;
if (text.offsetWidth > container.offsetWidth) {
text.classList.add('app-name_scrollable');
} else {
text.classList.remove('app-name_scrollable');
}
}
watch(
() => appStore.appName,
() => nextTick(fnCheckAppNameOverflow)
);
//
onMounted(() => {
fnCheckAppNameOverflow();
fnGetServerTime();
useAlarmStore().fnGetActiveAlarmInfo();
});
@@ -224,10 +252,10 @@ onUnmounted(() => {
v-model:selectedKeys="layoutState.selectedKeys"
v-model:openKeys="layoutState.openKeys"
:menu-data="menuData"
:breadcrumb="{ routes: breadcrumb } as any"
:breadcrumb="{ routes: breadcrumb }"
v-bind="proConfig"
:iconfont-url="scriptUrl"
:locale="(fnLocale as any)"
:iconfont-url="scriptUrl"
:locale="fnLocale"
>
<!--插槽-菜单头-->
<template #menuHeaderRender>
@@ -244,8 +272,10 @@ onUnmounted(() => {
:alt="appStore.appName"
:title="appStore.appName"
/>
<h1 class="title" :title="appStore.appName">
{{ appStore.appName }}
<h1 class="app-name" :title="appStore.appName">
<span class="marquee app-name_scrollable">
{{ appStore.appName }}
</span>
</h1>
</template>
<template v-if="appStore.logoType === 'brand'">
@@ -298,9 +328,6 @@ onUnmounted(() => {
</transition>
</RouterView>
<!-- 锁屏遮罩 -->
<LockScreen />
<!--插槽-内容底部-->
<template #footerRender="{ width }">
<footer class="footer">
@@ -327,6 +354,9 @@ onUnmounted(() => {
</footer>
</template>
</ProLayout>
<!-- 全局遮罩 -->
<GlobalMask />
</WaterMark>
</template>
@@ -347,11 +377,27 @@ onUnmounted(() => {
margin-right: 16px;
}
.title {
.app-name {
overflow: hidden;
text-overflow: ellipsis;
// text-overflow: ellipsis;
white-space: nowrap;
width: 130px;
width: 148px;
&_scrollable {
// padding-left: 100%;
display: inline-block;
animation: scrollable-animation linear 6s infinite both;
}
@keyframes scrollable-animation {
0% {
transform: translate3d(0, 0, 0);
}
100% {
transform: translate3d(-100%, 0, 0);
}
}
}
.footer {

View File

@@ -1,22 +1,23 @@
<script setup lang="ts">
import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface';
import Modal from 'ant-design-vue/lib/modal/Modal';
import { useRouter } from 'vue-router';
import { useRoute, useRouter } from 'vue-router';
import { useFullscreen } from '@vueuse/core';
import useI18n from '@/hooks/useI18n';
import useAppStore from '@/store/modules/app';
import useUserStore from '@/store/modules/user';
import useAlarmStore from '@/store/modules/alarm';
import useLockedStore from '@/store/modules/locked';
import useMaskStore from '@/store/modules/mask';
import { hasPermissions } from '@/plugins/auth-user';
import { dbClear } from '@/utils/cache-db-utils';
import { CACHE_DB_TABLE_DND } from '@/constants/cache-keys-constants';
import { ref } from 'vue';
const { isFullscreen, toggle } = useFullscreen();
const { t, changeLocale, optionsLocale } = useI18n();
const lockedStore = useLockedStore();
const maskStore = useMaskStore();
const userStore = useUserStore();
const appStore = useAppStore();
const route = useRoute();
const router = useRouter();
/**头像展开项点击 */
@@ -37,15 +38,24 @@ function fnClick({ key }: MenuInfo) {
}
}
/**锁屏确认 */
const lockConfirm = ref<boolean>(false);
/**锁屏密码 */
const lockPasswd = ref<string>('');
/**锁屏按钮提示 */
function fnClickLock() {
Modal.confirm({
title: t('common.tipTitle'),
content: t('loayouts.rightContent.lockTip'),
onOk() {
lockedStore.fnLock('lock');
},
});
lockConfirm.value = true;
lockPasswd.value = '';
maskStore.lockPasswd = '';
}
/**锁屏确认跳转锁屏页面 */
function fnClickLockToPage() {
lockConfirm.value = false;
maskStore.lockPasswd = lockPasswd.value;
maskStore.handleMaskType('lock');
router.push({ name: 'LockScreen', query: { redirect: route.path } });
}
/**告警数按钮提示跳转 */
@@ -89,13 +99,40 @@ function fnChangeLocale(e: any) {
</template>
</a-button>
<a-tooltip placement="bottom" v-if="false">
<!-- 锁屏操作 -->
<a-tooltip placement="bottom">
<template #title>{{ t('loayouts.rightContent.lock') }}</template>
<a-button type="text" style="color: inherit" @click="fnClickLock">
<a-button type="text" style="color: inherit" @click="fnClickLock()">
<template #icon>
<LockOutlined />
</template>
</a-button>
<ProModal
:drag="true"
:width="400"
:minHeight="200"
:mask-closable="false"
v-model:visible="lockConfirm"
:title="t('loayouts.rightContent.lockTip')"
@ok="fnClickLockToPage()"
>
<a-space>
{{ t('loayouts.rightContent.lockPasswd') }}
<a-input-password
v-model:value="lockPasswd"
:placeholder="t('common.inputPlease')"
>
<template #prefix>
<a-tooltip
:title="t('loayouts.rightContent.lockPasswdTip')"
placement="topLeft"
>
<UnlockOutlined />
</a-tooltip>
</template>
</a-input-password>
</a-space>
</ProModal>
</a-tooltip>
<a-tooltip placement="bottom">