系统各配置优化
This commit is contained in:
parent
0e890d96c5
commit
dbc9d8b458
2
.env
2
.env
|
@ -2,7 +2,7 @@
|
|||
VITE_PORT = 3100
|
||||
|
||||
# 网站标题
|
||||
VITE_GLOB_APP_TITLE = JeecgBoot 企业级低代码平台
|
||||
VITE_GLOB_APP_TITLE = 哈尔滨师范大学评阅人员管理系统
|
||||
|
||||
# 简称,用于配置文件名字 不要出现空格、数字开头等特殊字符
|
||||
VITE_GLOB_APP_SHORT_NAME = JeecgBootAdmin
|
||||
|
|
|
@ -157,7 +157,7 @@
|
|||
</style>
|
||||
<div class="app-loading">
|
||||
<div class="app-loading-wrap">
|
||||
<img src="/resource/img/logo.png" class="app-loading-logo" alt="Logo" />
|
||||
<!--<img src="/logo.png" class="app-loading-logo" alt="Logo" />-->
|
||||
<div class="app-loading-dots">
|
||||
<span class="dot dot-spin"><i></i><i></i><i></i><i></i></span>
|
||||
</div>
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
Binary file not shown.
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 5.3 KiB |
|
@ -4,89 +4,93 @@
|
|||
-->
|
||||
<template>
|
||||
<div class="anticon" :class="getAppLogoClass" @click="goHome">
|
||||
<img src="../../../assets/images/logo.png" />
|
||||
<div class="ml-2 truncate md:opacity-100" :class="getTitleClass" v-show="showTitle">
|
||||
{{ title }}
|
||||
<img style="width: 100%;" src="../../../assets/images/logo-red.png" />
|
||||
<div style="display: flex;" class="ml-2 truncate md:opacity-100" :class="getTitleClass" v-show="showTitle">
|
||||
<!-- {{ title }} -->
|
||||
<!-- <span>英语四六级综合管理平台</span> -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { computed, unref } from 'vue';
|
||||
import { useGlobSetting } from '/@/hooks/setting';
|
||||
import { useGo } from '/@/hooks/web/usePage';
|
||||
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { PageEnum } from '/@/enums/pageEnum';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
import { computed, unref } from 'vue';
|
||||
import { useGlobSetting } from '/@/hooks/setting';
|
||||
import { useGo } from '/@/hooks/web/usePage';
|
||||
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { PageEnum } from '/@/enums/pageEnum';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
|
||||
const props = defineProps({
|
||||
/**
|
||||
* The theme of the current parent component
|
||||
*/
|
||||
theme: { type: String, validator: (v: string) => ['light', 'dark'].includes(v) },
|
||||
/**
|
||||
* Whether to show title
|
||||
*/
|
||||
showTitle: { type: Boolean, default: true },
|
||||
/**
|
||||
* The title is also displayed when the menu is collapsed
|
||||
*/
|
||||
alwaysShowTitle: { type: Boolean },
|
||||
});
|
||||
const props = defineProps({
|
||||
/**
|
||||
* The theme of the current parent component
|
||||
*/
|
||||
theme: { type: String, validator: (v: string) => ['light', 'dark'].includes(v) },
|
||||
/**
|
||||
* Whether to show title
|
||||
*/
|
||||
showTitle: { type: Boolean, default: true },
|
||||
/**
|
||||
* The title is also displayed when the menu is collapsed
|
||||
*/
|
||||
alwaysShowTitle: { type: Boolean },
|
||||
});
|
||||
|
||||
const { prefixCls } = useDesign('app-logo');
|
||||
const { getCollapsedShowTitle } = useMenuSetting();
|
||||
const userStore = useUserStore();
|
||||
const { title } = useGlobSetting();
|
||||
const go = useGo();
|
||||
const { prefixCls } = useDesign('app-logo');
|
||||
const { getCollapsedShowTitle } = useMenuSetting();
|
||||
const userStore = useUserStore();
|
||||
const { title } = useGlobSetting();
|
||||
const go = useGo();
|
||||
|
||||
const getAppLogoClass = computed(() => [prefixCls, props.theme, { 'collapsed-show-title': unref(getCollapsedShowTitle) }]);
|
||||
const getAppLogoClass = computed(() => [prefixCls, props.theme, { 'collapsed-show-title': unref(getCollapsedShowTitle) }]);
|
||||
|
||||
const getTitleClass = computed(() => [
|
||||
`${prefixCls}__title`,
|
||||
{
|
||||
'xs:opacity-0': !props.alwaysShowTitle,
|
||||
},
|
||||
]);
|
||||
const getTitleClass = computed(() => [
|
||||
`${prefixCls}__title`,
|
||||
{
|
||||
'xs:opacity-0': !props.alwaysShowTitle,
|
||||
},
|
||||
]);
|
||||
|
||||
function goHome() {
|
||||
go(userStore.getUserInfo.homePath || PageEnum.BASE_HOME);
|
||||
}
|
||||
function goHome() {
|
||||
go(userStore.getUserInfo.homePath || PageEnum.BASE_HOME);
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
@prefix-cls: ~'@{namespace}-app-logo';
|
||||
@prefix-cls: ~'@{namespace}-app-logo';
|
||||
|
||||
.@{prefix-cls} {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 7px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
//左侧菜单模式和左侧菜单混合模式加渐变背景色
|
||||
&.jeecg-layout-mix-sider-logo,&.jeecg-layout-menu-logo{
|
||||
background:@sider-logo-bg-color;
|
||||
}
|
||||
// &.light {
|
||||
// border-bottom: 1px solid @border-color-base;
|
||||
// }
|
||||
.@{prefix-cls} {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 7px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
&.collapsed-show-title {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
&.light &__title {
|
||||
color: @primary-color;
|
||||
}
|
||||
|
||||
&.dark &__title {
|
||||
color: @white;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
transition: all 0.5s;
|
||||
line-height: normal;
|
||||
}
|
||||
//左侧菜单模式和左侧菜单混合模式加渐变背景色
|
||||
&.jeecg-layout-mix-sider-logo,
|
||||
&.jeecg-layout-menu-logo {
|
||||
background: @sider-logo-bg-color;
|
||||
}
|
||||
|
||||
// &.light {
|
||||
// border-bottom: 1px solid @border-color-base;
|
||||
// }
|
||||
|
||||
&.collapsed-show-title {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
&.light &__title {
|
||||
color: @primary-color;
|
||||
}
|
||||
|
||||
&.dark &__title {
|
||||
color: @white;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
transition: all 0.5s;
|
||||
line-height: normal;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,6 +1,20 @@
|
|||
<template>
|
||||
<div class="scrollbar">
|
||||
<div ref="wrap" :class="[wrapClass, 'scrollbar__wrap', native ? '' : 'scrollbar__wrap--hidden-default']" :style="style" @scroll="handleScroll">
|
||||
<div ref="wrap" :class="[wrapClass, 'scrollbar__wrap', native ? '' : 'scrollbar__wrap--hidden-default']"
|
||||
:style="style" @scroll="handleScroll">
|
||||
<div style="display: flex; justify-content: center; align-items: center">
|
||||
<span style="
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
transition: all 0.5s;
|
||||
line-height: normal;
|
||||
padding: 5px;
|
||||
">
|
||||
评阅人员管理系统
|
||||
</span>
|
||||
|
||||
</div>
|
||||
|
||||
<component :is="tag" ref="resize" :class="['scrollbar__view', viewClass]" :style="viewStyle">
|
||||
<slot></slot>
|
||||
</component>
|
||||
|
@ -12,182 +26,182 @@
|
|||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { addResizeListener, removeResizeListener } from '/@/utils/event';
|
||||
import componentSetting from '/@/settings/componentSetting';
|
||||
const { scrollbar } = componentSetting;
|
||||
import { toObject } from './util';
|
||||
import { defineComponent, ref, onMounted, onBeforeUnmount, nextTick, provide, computed, unref } from 'vue';
|
||||
import Bar from './bar';
|
||||
import { addResizeListener, removeResizeListener } from '/@/utils/event';
|
||||
import componentSetting from '/@/settings/componentSetting';
|
||||
const { scrollbar } = componentSetting;
|
||||
import { toObject } from './util';
|
||||
import { defineComponent, ref, onMounted, onBeforeUnmount, nextTick, provide, computed, unref } from 'vue';
|
||||
import Bar from './bar';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Scrollbar',
|
||||
// inheritAttrs: false,
|
||||
components: { Bar },
|
||||
props: {
|
||||
native: {
|
||||
type: Boolean,
|
||||
default: scrollbar?.native ?? false,
|
||||
},
|
||||
wrapStyle: {
|
||||
type: [String, Array],
|
||||
default: '',
|
||||
},
|
||||
wrapClass: {
|
||||
type: [String, Array],
|
||||
default: '',
|
||||
},
|
||||
viewClass: {
|
||||
type: [String, Array],
|
||||
default: '',
|
||||
},
|
||||
viewStyle: {
|
||||
type: [String, Array],
|
||||
default: '',
|
||||
},
|
||||
noresize: Boolean, // 如果 container 尺寸不会发生变化,最好设置它可以优化性能
|
||||
tag: {
|
||||
type: String,
|
||||
default: 'div',
|
||||
},
|
||||
export default defineComponent({
|
||||
name: 'Scrollbar',
|
||||
// inheritAttrs: false,
|
||||
components: { Bar },
|
||||
props: {
|
||||
native: {
|
||||
type: Boolean,
|
||||
default: scrollbar?.native ?? false,
|
||||
},
|
||||
setup(props) {
|
||||
const sizeWidth = ref('0');
|
||||
const sizeHeight = ref('0');
|
||||
const moveX = ref(0);
|
||||
const moveY = ref(0);
|
||||
const wrap = ref();
|
||||
const resize = ref();
|
||||
|
||||
provide('scroll-bar-wrap', wrap);
|
||||
|
||||
const style = computed(() => {
|
||||
if (Array.isArray(props.wrapStyle)) {
|
||||
return toObject(props.wrapStyle);
|
||||
}
|
||||
return props.wrapStyle;
|
||||
});
|
||||
|
||||
const handleScroll = () => {
|
||||
if (!props.native) {
|
||||
moveY.value = (unref(wrap).scrollTop * 100) / unref(wrap).clientHeight;
|
||||
moveX.value = (unref(wrap).scrollLeft * 100) / unref(wrap).clientWidth;
|
||||
}
|
||||
};
|
||||
|
||||
const update = () => {
|
||||
if (!unref(wrap)) return;
|
||||
|
||||
const heightPercentage = (unref(wrap).clientHeight * 100) / unref(wrap).scrollHeight;
|
||||
const widthPercentage = (unref(wrap).clientWidth * 100) / unref(wrap).scrollWidth;
|
||||
|
||||
sizeHeight.value = heightPercentage < 100 ? heightPercentage + '%' : '';
|
||||
sizeWidth.value = widthPercentage < 100 ? widthPercentage + '%' : '';
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
if (props.native) return;
|
||||
nextTick(update);
|
||||
if (!props.noresize) {
|
||||
addResizeListener(unref(resize), update);
|
||||
addResizeListener(unref(wrap), update);
|
||||
addEventListener('resize', update);
|
||||
}
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (props.native) return;
|
||||
if (!props.noresize) {
|
||||
removeResizeListener(unref(resize), update);
|
||||
removeResizeListener(unref(wrap), update);
|
||||
removeEventListener('resize', update);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
moveX,
|
||||
moveY,
|
||||
sizeWidth,
|
||||
sizeHeight,
|
||||
style,
|
||||
wrap,
|
||||
resize,
|
||||
update,
|
||||
handleScroll,
|
||||
};
|
||||
wrapStyle: {
|
||||
type: [String, Array],
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
wrapClass: {
|
||||
type: [String, Array],
|
||||
default: '',
|
||||
},
|
||||
viewClass: {
|
||||
type: [String, Array],
|
||||
default: '',
|
||||
},
|
||||
viewStyle: {
|
||||
type: [String, Array],
|
||||
default: '',
|
||||
},
|
||||
noresize: Boolean, // 如果 container 尺寸不会发生变化,最好设置它可以优化性能
|
||||
tag: {
|
||||
type: String,
|
||||
default: 'div',
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const sizeWidth = ref('0');
|
||||
const sizeHeight = ref('0');
|
||||
const moveX = ref(0);
|
||||
const moveY = ref(0);
|
||||
const wrap = ref();
|
||||
const resize = ref();
|
||||
|
||||
provide('scroll-bar-wrap', wrap);
|
||||
|
||||
const style = computed(() => {
|
||||
if (Array.isArray(props.wrapStyle)) {
|
||||
return toObject(props.wrapStyle);
|
||||
}
|
||||
return props.wrapStyle;
|
||||
});
|
||||
|
||||
const handleScroll = () => {
|
||||
if (!props.native) {
|
||||
moveY.value = (unref(wrap).scrollTop * 100) / unref(wrap).clientHeight;
|
||||
moveX.value = (unref(wrap).scrollLeft * 100) / unref(wrap).clientWidth;
|
||||
}
|
||||
};
|
||||
|
||||
const update = () => {
|
||||
if (!unref(wrap)) return;
|
||||
|
||||
const heightPercentage = (unref(wrap).clientHeight * 100) / unref(wrap).scrollHeight;
|
||||
const widthPercentage = (unref(wrap).clientWidth * 100) / unref(wrap).scrollWidth;
|
||||
|
||||
sizeHeight.value = heightPercentage < 100 ? heightPercentage + '%' : '';
|
||||
sizeWidth.value = widthPercentage < 100 ? widthPercentage + '%' : '';
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
if (props.native) return;
|
||||
nextTick(update);
|
||||
if (!props.noresize) {
|
||||
addResizeListener(unref(resize), update);
|
||||
addResizeListener(unref(wrap), update);
|
||||
addEventListener('resize', update);
|
||||
}
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (props.native) return;
|
||||
if (!props.noresize) {
|
||||
removeResizeListener(unref(resize), update);
|
||||
removeResizeListener(unref(wrap), update);
|
||||
removeEventListener('resize', update);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
moveX,
|
||||
moveY,
|
||||
sizeWidth,
|
||||
sizeHeight,
|
||||
style,
|
||||
wrap,
|
||||
resize,
|
||||
update,
|
||||
handleScroll,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="less">
|
||||
.scrollbar {
|
||||
position: relative;
|
||||
.scrollbar {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
&__wrap {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
overflow: auto;
|
||||
|
||||
&__wrap {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
&--hidden-default {
|
||||
scrollbar-width: none;
|
||||
|
||||
&--hidden-default {
|
||||
scrollbar-width: none;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
width: 0;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__thumb {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
cursor: pointer;
|
||||
background-color: rgba(144, 147, 153, 0.3);
|
||||
border-radius: inherit;
|
||||
transition: 0.3s background-color;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(144, 147, 153, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
&__bar {
|
||||
position: absolute;
|
||||
right: 2px;
|
||||
bottom: 2px;
|
||||
z-index: 1;
|
||||
border-radius: 4px;
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 80ms ease;
|
||||
transition: opacity 80ms ease;
|
||||
|
||||
&.is-vertical {
|
||||
top: 2px;
|
||||
width: 6px;
|
||||
|
||||
& > div {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-horizontal {
|
||||
left: 2px;
|
||||
height: 6px;
|
||||
|
||||
& > div {
|
||||
height: 100%;
|
||||
}
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
width: 0;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.scrollbar:active > .scrollbar__bar,
|
||||
.scrollbar:focus > .scrollbar__bar,
|
||||
.scrollbar:hover > .scrollbar__bar {
|
||||
opacity: 1;
|
||||
transition: opacity 340ms ease-out;
|
||||
&__thumb {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
cursor: pointer;
|
||||
background-color: rgba(144, 147, 153, 0.3);
|
||||
border-radius: inherit;
|
||||
transition: 0.3s background-color;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(144, 147, 153, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
&__bar {
|
||||
position: absolute;
|
||||
right: 2px;
|
||||
bottom: 2px;
|
||||
z-index: 1;
|
||||
border-radius: 4px;
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 80ms ease;
|
||||
transition: opacity 80ms ease;
|
||||
|
||||
&.is-vertical {
|
||||
top: 2px;
|
||||
width: 6px;
|
||||
|
||||
&>div {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-horizontal {
|
||||
left: 2px;
|
||||
height: 6px;
|
||||
|
||||
&>div {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.scrollbar:active>.scrollbar__bar,
|
||||
.scrollbar:focus>.scrollbar__bar,
|
||||
.scrollbar:hover>.scrollbar__bar {
|
||||
opacity: 1;
|
||||
transition: opacity 340ms ease-out;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -11,12 +11,8 @@
|
|||
|
||||
<template #overlay>
|
||||
<Menu @click="handleMenuClick">
|
||||
<MenuItem key="doc" :text="t('layout.header.dropdownItemDoc')" icon="ion:document-text-outline" v-if="getShowDoc" />
|
||||
<MenuDivider v-if="getShowDoc" />
|
||||
<MenuItem key="account" :text="t('layout.header.dropdownItemSwitchAccount')" icon="ant-design:setting-outlined" />
|
||||
<MenuItem key="password" :text="t('layout.header.dropdownItemSwitchPassword')" icon="ant-design:edit-outlined" />
|
||||
<MenuItem key="depart" :text="t('layout.header.dropdownItemSwitchDepart')" icon="ant-design:cluster-outlined" />
|
||||
<MenuItem key="cache" :text="t('layout.header.dropdownItemRefreshCache')" icon="ion:sync-outline" />
|
||||
<MenuItem key="password" :text="t('layout.header.dropdownItemSwitchPassword')"
|
||||
icon="ant-design:edit-outlined" />
|
||||
<!-- <MenuItem
|
||||
v-if="getUseLockPage"
|
||||
key="lock"
|
||||
|
@ -32,220 +28,221 @@
|
|||
<UpdatePassword v-if="passwordVisible" ref="updatePasswordRef" />
|
||||
</template>
|
||||
<script lang="ts">
|
||||
// components
|
||||
import { Dropdown, Menu } from 'ant-design-vue';
|
||||
// components
|
||||
import { Dropdown, Menu } from 'ant-design-vue';
|
||||
|
||||
import { defineComponent, computed, ref } from 'vue';
|
||||
import { defineComponent, computed, ref } from 'vue';
|
||||
|
||||
import { SITE_URL } from '/@/settings/siteSetting';
|
||||
import { SITE_URL } from '/@/settings/siteSetting';
|
||||
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useMessage } from '/src/hooks/web/useMessage';
|
||||
import { useGo } from '/@/hooks/web/usePage';
|
||||
import headerImg from '/@/assets/images/header.jpg';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { openWindow } from '/@/utils';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { useMessage } from '/src/hooks/web/useMessage';
|
||||
import { useGo } from '/@/hooks/web/usePage';
|
||||
import headerImg from '/@/assets/images/header.jpg';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { openWindow } from '/@/utils';
|
||||
|
||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
|
||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
|
||||
|
||||
import { refreshCache, queryAllDictItems } from '/@/views/system/dict/dict.api';
|
||||
import { DB_DICT_DATA_KEY } from '/src/enums/cacheEnum';
|
||||
import { removeAuthCache, setAuthCache } from '/src/utils/auth';
|
||||
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
|
||||
import { getRefPromise } from '/@/utils/index';
|
||||
import { refreshCache, queryAllDictItems } from '/@/views/system/dict/dict.api';
|
||||
import { DB_DICT_DATA_KEY } from '/src/enums/cacheEnum';
|
||||
import { removeAuthCache, setAuthCache } from '/src/utils/auth';
|
||||
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
|
||||
import { getRefPromise } from '/@/utils/index';
|
||||
|
||||
type MenuEvent = 'logout' | 'doc' | 'lock' | 'cache' | 'depart';
|
||||
const { createMessage } = useMessage();
|
||||
export default defineComponent({
|
||||
name: 'UserDropdown',
|
||||
components: {
|
||||
Dropdown,
|
||||
Menu,
|
||||
MenuItem: createAsyncComponent(() => import('./DropMenuItem.vue')),
|
||||
MenuDivider: Menu.Divider,
|
||||
LockAction: createAsyncComponent(() => import('../lock/LockModal.vue')),
|
||||
DepartSelect: createAsyncComponent(() => import('./DepartSelect.vue')),
|
||||
UpdatePassword: createAsyncComponent(() => import('./UpdatePassword.vue')),
|
||||
},
|
||||
props: {
|
||||
theme: propTypes.oneOf(['dark', 'light']),
|
||||
},
|
||||
setup() {
|
||||
const { prefixCls } = useDesign('header-user-dropdown');
|
||||
const { t } = useI18n();
|
||||
const { getShowDoc, getUseLockPage } = useHeaderSetting();
|
||||
const userStore = useUserStore();
|
||||
const go = useGo();
|
||||
const passwordVisible = ref(false);
|
||||
const lockActionVisible = ref(false);
|
||||
const lockActionRef = ref(null);
|
||||
type MenuEvent = 'logout' | 'doc' | 'lock' | 'cache' | 'depart';
|
||||
const { createMessage } = useMessage();
|
||||
export default defineComponent({
|
||||
name: 'UserDropdown',
|
||||
components: {
|
||||
Dropdown,
|
||||
Menu,
|
||||
MenuItem: createAsyncComponent(() => import('./DropMenuItem.vue')),
|
||||
MenuDivider: Menu.Divider,
|
||||
LockAction: createAsyncComponent(() => import('../lock/LockModal.vue')),
|
||||
DepartSelect: createAsyncComponent(() => import('./DepartSelect.vue')),
|
||||
UpdatePassword: createAsyncComponent(() => import('./UpdatePassword.vue')),
|
||||
},
|
||||
props: {
|
||||
theme: propTypes.oneOf(['dark', 'light']),
|
||||
},
|
||||
setup() {
|
||||
const { prefixCls } = useDesign('header-user-dropdown');
|
||||
const { t } = useI18n();
|
||||
const { getShowDoc, getUseLockPage } = useHeaderSetting();
|
||||
const userStore = useUserStore();
|
||||
const go = useGo();
|
||||
const passwordVisible = ref(false);
|
||||
const lockActionVisible = ref(false);
|
||||
const lockActionRef = ref(null);
|
||||
|
||||
const getUserInfo = computed(() => {
|
||||
const { realname = '', avatar, desc } = userStore.getUserInfo || {};
|
||||
return { realname, avatar: avatar || headerImg, desc };
|
||||
});
|
||||
const getUserInfo = computed(() => {
|
||||
const { realname = '', avatar, desc } = userStore.getUserInfo || {};
|
||||
return { realname, avatar: avatar || headerImg, desc };
|
||||
});
|
||||
|
||||
const getAvatarUrl = computed(() => {
|
||||
let { avatar } = getUserInfo.value;
|
||||
if (avatar == headerImg) {
|
||||
return avatar;
|
||||
} else {
|
||||
return getFileAccessHttpUrl(avatar);
|
||||
}
|
||||
});
|
||||
|
||||
const [register, { openModal }] = useModal();
|
||||
/**
|
||||
* 多部门弹窗逻辑
|
||||
*/
|
||||
const loginSelectRef = ref();
|
||||
// update-begin--author:liaozhiyang---date:20230901---for:【QQYUN-6333】空路由问题—首次访问资源太大
|
||||
async function handleLock() {
|
||||
await getRefPromise(lockActionRef);
|
||||
openModal(true);
|
||||
}
|
||||
// update-end--author:liaozhiyang---date:20230901---for:【QQYUN-6333】空路由问题—首次访问资源太大
|
||||
// login out
|
||||
function handleLoginOut() {
|
||||
userStore.confirmLoginOut();
|
||||
const getAvatarUrl = computed(() => {
|
||||
let { avatar } = getUserInfo.value;
|
||||
if (avatar == headerImg) {
|
||||
return avatar;
|
||||
} else {
|
||||
return getFileAccessHttpUrl(avatar);
|
||||
}
|
||||
});
|
||||
|
||||
// open doc
|
||||
function openDoc() {
|
||||
openWindow(SITE_URL);
|
||||
}
|
||||
const [register, { openModal }] = useModal();
|
||||
/**
|
||||
* 多部门弹窗逻辑
|
||||
*/
|
||||
const loginSelectRef = ref();
|
||||
// update-begin--author:liaozhiyang---date:20230901---for:【QQYUN-6333】空路由问题—首次访问资源太大
|
||||
async function handleLock() {
|
||||
await getRefPromise(lockActionRef);
|
||||
openModal(true);
|
||||
}
|
||||
// update-end--author:liaozhiyang---date:20230901---for:【QQYUN-6333】空路由问题—首次访问资源太大
|
||||
// login out
|
||||
function handleLoginOut() {
|
||||
userStore.confirmLoginOut();
|
||||
}
|
||||
|
||||
// 清除缓存
|
||||
async function clearCache() {
|
||||
const result = await refreshCache();
|
||||
if (result.success) {
|
||||
const res = await queryAllDictItems();
|
||||
removeAuthCache(DB_DICT_DATA_KEY);
|
||||
setAuthCache(DB_DICT_DATA_KEY, res.result);
|
||||
// update-begin--author:liaozhiyang---date:20240124---for:【QQYUN-7970】国际化
|
||||
createMessage.success(t('layout.header.refreshCacheComplete'));
|
||||
// update-end--author:liaozhiyang---date:20240124---for:【QQYUN-7970】国际化
|
||||
} else {
|
||||
// update-begin--author:liaozhiyang---date:20240124---for:【QQYUN-7970】国际化
|
||||
createMessage.error(t('layout.header.refreshCacheFailure'));
|
||||
// update-end--author:liaozhiyang---date:20240124---for:【QQYUN-7970】国际化
|
||||
}
|
||||
}
|
||||
// 切换部门
|
||||
function updateCurrentDepart() {
|
||||
loginSelectRef.value.show();
|
||||
}
|
||||
// 修改密码
|
||||
const updatePasswordRef = ref();
|
||||
// update-begin--author:liaozhiyang---date:20230901---for:【QQYUN-6333】空路由问题—首次访问资源太大
|
||||
async function updatePassword() {
|
||||
passwordVisible.value = true;
|
||||
await getRefPromise(updatePasswordRef);
|
||||
updatePasswordRef.value.show(userStore.getUserInfo.username);
|
||||
}
|
||||
// update-end--author:liaozhiyang---date:20230901---for:【QQYUN-6333】空路由问题—首次访问资源太大
|
||||
function handleMenuClick(e: { key: MenuEvent }) {
|
||||
switch (e.key) {
|
||||
case 'logout':
|
||||
handleLoginOut();
|
||||
break;
|
||||
case 'doc':
|
||||
openDoc();
|
||||
break;
|
||||
case 'lock':
|
||||
handleLock();
|
||||
break;
|
||||
case 'cache':
|
||||
clearCache();
|
||||
break;
|
||||
case 'depart':
|
||||
updateCurrentDepart();
|
||||
break;
|
||||
case 'password':
|
||||
updatePassword();
|
||||
break;
|
||||
case 'account':
|
||||
//update-begin---author:wangshuai ---date:20221125 for:进入用户设置页面------------
|
||||
go(`/system/usersetting`);
|
||||
//update-end---author:wangshuai ---date:20221125 for:进入用户设置页面--------------
|
||||
break;
|
||||
}
|
||||
}
|
||||
// open doc
|
||||
function openDoc() {
|
||||
openWindow(SITE_URL);
|
||||
}
|
||||
|
||||
return {
|
||||
prefixCls,
|
||||
t,
|
||||
getUserInfo,
|
||||
getAvatarUrl,
|
||||
handleMenuClick,
|
||||
getShowDoc,
|
||||
register,
|
||||
getUseLockPage,
|
||||
loginSelectRef,
|
||||
updatePasswordRef,
|
||||
passwordVisible,
|
||||
lockActionVisible,
|
||||
};
|
||||
},
|
||||
});
|
||||
// 清除缓存
|
||||
async function clearCache() {
|
||||
const result = await refreshCache();
|
||||
if (result.success) {
|
||||
const res = await queryAllDictItems();
|
||||
removeAuthCache(DB_DICT_DATA_KEY);
|
||||
setAuthCache(DB_DICT_DATA_KEY, res.result);
|
||||
// update-begin--author:liaozhiyang---date:20240124---for:【QQYUN-7970】国际化
|
||||
createMessage.success(t('layout.header.refreshCacheComplete'));
|
||||
// update-end--author:liaozhiyang---date:20240124---for:【QQYUN-7970】国际化
|
||||
} else {
|
||||
// update-begin--author:liaozhiyang---date:20240124---for:【QQYUN-7970】国际化
|
||||
createMessage.error(t('layout.header.refreshCacheFailure'));
|
||||
// update-end--author:liaozhiyang---date:20240124---for:【QQYUN-7970】国际化
|
||||
}
|
||||
}
|
||||
// 切换部门
|
||||
function updateCurrentDepart() {
|
||||
loginSelectRef.value.show();
|
||||
}
|
||||
// 修改密码
|
||||
const updatePasswordRef = ref();
|
||||
// update-begin--author:liaozhiyang---date:20230901---for:【QQYUN-6333】空路由问题—首次访问资源太大
|
||||
async function updatePassword() {
|
||||
passwordVisible.value = true;
|
||||
await getRefPromise(updatePasswordRef);
|
||||
updatePasswordRef.value.show(userStore.getUserInfo.username);
|
||||
}
|
||||
// update-end--author:liaozhiyang---date:20230901---for:【QQYUN-6333】空路由问题—首次访问资源太大
|
||||
function handleMenuClick(e: { key: MenuEvent }) {
|
||||
switch (e.key) {
|
||||
case 'logout':
|
||||
handleLoginOut();
|
||||
break;
|
||||
case 'doc':
|
||||
openDoc();
|
||||
break;
|
||||
case 'lock':
|
||||
handleLock();
|
||||
break;
|
||||
case 'cache':
|
||||
clearCache();
|
||||
break;
|
||||
case 'depart':
|
||||
updateCurrentDepart();
|
||||
break;
|
||||
case 'password':
|
||||
updatePassword();
|
||||
break;
|
||||
case 'account':
|
||||
//update-begin---author:wangshuai ---date:20221125 for:进入用户设置页面------------
|
||||
go(`/system/usersetting`);
|
||||
//update-end---author:wangshuai ---date:20221125 for:进入用户设置页面--------------
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
prefixCls,
|
||||
t,
|
||||
getUserInfo,
|
||||
getAvatarUrl,
|
||||
handleMenuClick,
|
||||
getShowDoc,
|
||||
register,
|
||||
getUseLockPage,
|
||||
loginSelectRef,
|
||||
updatePasswordRef,
|
||||
passwordVisible,
|
||||
lockActionVisible,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="less">
|
||||
@prefix-cls: ~'@{namespace}-header-user-dropdown';
|
||||
@prefix-cls: ~'@{namespace}-header-user-dropdown';
|
||||
|
||||
.@{prefix-cls} {
|
||||
height: @header-height;
|
||||
padding: 0 0 0 10px;
|
||||
padding-right: 10px;
|
||||
overflow: hidden;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
.@{prefix-cls} {
|
||||
height: @header-height;
|
||||
padding: 0 0 0 10px;
|
||||
padding-right: 10px;
|
||||
overflow: hidden;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
img {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
&__header {
|
||||
border-radius: 50%;
|
||||
}
|
||||
&__header {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
&__name {
|
||||
font-size: 14px;
|
||||
}
|
||||
&__name {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&--dark {
|
||||
&:hover {
|
||||
background-color: @header-dark-bg-hover-color;
|
||||
}
|
||||
}
|
||||
|
||||
&--light {
|
||||
&:hover {
|
||||
background-color: @header-light-bg-hover-color;
|
||||
}
|
||||
|
||||
.@{prefix-cls}__name {
|
||||
color: @text-color-base;
|
||||
}
|
||||
|
||||
.@{prefix-cls}__desc {
|
||||
color: @header-light-desc-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-dropdown-overlay {
|
||||
// update-begin--author:liaozhiyang---date:20231226---for:【QQYUN-7512】顶部账号划过首次弹出时位置会变更一下
|
||||
width: 160px;
|
||||
// update-end--author:liaozhiyang---date:20231226---for:【QQYUN-7512】顶部账号划过首次弹出时位置会变更一下
|
||||
.ant-dropdown-menu-item {
|
||||
min-width: 160px;
|
||||
}
|
||||
&--dark {
|
||||
&:hover {
|
||||
background-color: @header-dark-bg-hover-color;
|
||||
}
|
||||
}
|
||||
|
||||
&--light {
|
||||
&:hover {
|
||||
background-color: @header-light-bg-hover-color;
|
||||
}
|
||||
|
||||
.@{prefix-cls}__name {
|
||||
color: @text-color-base;
|
||||
}
|
||||
|
||||
.@{prefix-cls}__desc {
|
||||
color: @header-light-desc-color;
|
||||
}
|
||||
}
|
||||
|
||||
&-dropdown-overlay {
|
||||
// update-begin--author:liaozhiyang---date:20231226---for:【QQYUN-7512】顶部账号划过首次弹出时位置会变更一下
|
||||
width: 160px;
|
||||
|
||||
// update-end--author:liaozhiyang---date:20231226---for:【QQYUN-7512】顶部账号划过首次弹出时位置会变更一下
|
||||
.ant-dropdown-menu-item {
|
||||
min-width: 160px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -3,15 +3,11 @@
|
|||
<!-- left start -->
|
||||
<div :class="`${prefixCls}-left`">
|
||||
<!-- logo -->
|
||||
<AppLogo v-if="getShowHeaderLogo || getIsMobile" :class="`${prefixCls}-logo`" :theme="getHeaderTheme" :style="getLogoWidth" />
|
||||
<LayoutTrigger
|
||||
v-if="(getShowContent && getShowHeaderTrigger && !getSplit && !getIsMixSidebar) || getIsMobile"
|
||||
:theme="getHeaderTheme"
|
||||
:sider="false"
|
||||
/>
|
||||
<AppLogo v-if="getShowHeaderLogo || getIsMobile" :class="`${prefixCls}-logo`" :theme="getHeaderTheme"
|
||||
:style="getLogoWidth" />
|
||||
<LayoutTrigger v-if="(getShowContent && getShowHeaderTrigger && !getSplit && !getIsMixSidebar) || getIsMobile"
|
||||
:theme="getHeaderTheme" :sider="false" />
|
||||
<LayoutBreadcrumb v-if="getShowContent && getShowBread" :theme="getHeaderTheme" />
|
||||
<!-- 欢迎语 -->
|
||||
<span v-if="getShowContent && getShowBreadTitle && !getIsMobile" :class="[prefixCls, `${prefixCls}--${getHeaderTheme}`,'headerIntroductionClass']"> {{t('layout.header.welcomeIn')}} {{ title }} </span>
|
||||
</div>
|
||||
<!-- left end -->
|
||||
|
||||
|
@ -23,236 +19,228 @@
|
|||
|
||||
<!-- action -->
|
||||
<div :class="`${prefixCls}-action`">
|
||||
<AppSearch :class="`${prefixCls}-action__item `" v-if="getShowSearch" />
|
||||
|
||||
<ErrorAction v-if="getUseErrorHandle" :class="`${prefixCls}-action__item error-action`" />
|
||||
|
||||
<Notify v-if="getShowNotice" :class="`${prefixCls}-action__item notify-item`" />
|
||||
|
||||
<FullScreen v-if="getShowFullScreen" :class="`${prefixCls}-action__item fullscreen-item`" />
|
||||
|
||||
<LockScreen v-if="getUseLockPage" />
|
||||
|
||||
<AppLocalePicker v-if="getShowLocalePicker" :reload="true" :showText="false" :class="`${prefixCls}-action__item`" />
|
||||
|
||||
<UserDropDown :theme="getHeaderTheme" />
|
||||
|
||||
<SettingDrawer v-if="getShowSetting" :class="`${prefixCls}-action__item`" />
|
||||
<!-- ai助手 -->
|
||||
<Aide></Aide>
|
||||
</div>
|
||||
|
||||
</Header>
|
||||
<LoginSelect ref="loginSelectRef" @success="loginSelectOk"></LoginSelect>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, unref, computed, ref, onMounted, toRaw } from 'vue';
|
||||
import { useGlobSetting } from '/@/hooks/setting';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { defineComponent, unref, computed, ref, onMounted, toRaw } from 'vue';
|
||||
import { useGlobSetting } from '/@/hooks/setting';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
|
||||
import { Layout } from 'ant-design-vue';
|
||||
import { AppLogo } from '/@/components/Application';
|
||||
import LayoutMenu from '../menu/index.vue';
|
||||
import LayoutTrigger from '../trigger/index.vue';
|
||||
import { Layout } from 'ant-design-vue';
|
||||
import { AppLogo } from '/@/components/Application';
|
||||
import LayoutMenu from '../menu/index.vue';
|
||||
import LayoutTrigger from '../trigger/index.vue';
|
||||
|
||||
import { AppSearch } from '/@/components/Application';
|
||||
import { AppSearch } from '/@/components/Application';
|
||||
|
||||
import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
|
||||
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
||||
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
||||
import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
|
||||
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
|
||||
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
||||
|
||||
import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
|
||||
import { SettingButtonPositionEnum } from '/@/enums/appEnum';
|
||||
import { AppLocalePicker } from '/@/components/Application';
|
||||
import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
|
||||
import { SettingButtonPositionEnum } from '/@/enums/appEnum';
|
||||
import { AppLocalePicker } from '/@/components/Application';
|
||||
|
||||
import { UserDropDown, LayoutBreadcrumb, FullScreen, Notify, ErrorAction, LockScreen } from './components';
|
||||
import { useAppInject } from '/@/hooks/web/useAppInject';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { UserDropDown, LayoutBreadcrumb, FullScreen, Notify, ErrorAction, LockScreen } from './components';
|
||||
import { useAppInject } from '/@/hooks/web/useAppInject';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
|
||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
|
||||
import { useLocale } from '/@/locales/useLocale';
|
||||
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
|
||||
import { useLocale } from '/@/locales/useLocale';
|
||||
|
||||
import LoginSelect from '/@/views/sys/login/LoginSelect.vue';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import Aide from "@/views/dashboard/ai/components/aide/index.vue"
|
||||
const { t } = useI18n();
|
||||
import LoginSelect from '/@/views/sys/login/LoginSelect.vue';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import Aide from "@/views/dashboard/ai/components/aide/index.vue"
|
||||
const { t } = useI18n();
|
||||
|
||||
export default defineComponent({
|
||||
name: 'LayoutHeader',
|
||||
components: {
|
||||
Header: Layout.Header,
|
||||
AppLogo,
|
||||
LayoutTrigger,
|
||||
LayoutBreadcrumb,
|
||||
LayoutMenu,
|
||||
UserDropDown,
|
||||
AppLocalePicker,
|
||||
FullScreen,
|
||||
Notify,
|
||||
AppSearch,
|
||||
ErrorAction,
|
||||
LockScreen,
|
||||
LoginSelect,
|
||||
SettingDrawer: createAsyncComponent(() => import('/@/layouts/default/setting/index.vue'), {
|
||||
loading: true,
|
||||
}),
|
||||
Aide
|
||||
},
|
||||
props: {
|
||||
fixed: propTypes.bool,
|
||||
},
|
||||
setup(props) {
|
||||
const { prefixCls } = useDesign('layout-header');
|
||||
const userStore = useUserStore();
|
||||
const { getShowTopMenu, getShowHeaderTrigger, getSplit, getIsMixMode, getMenuWidth, getIsMixSidebar } = useMenuSetting();
|
||||
const { getUseErrorHandle, getShowSettingButton, getSettingButtonPosition } = useRootSetting();
|
||||
const { title } = useGlobSetting();
|
||||
export default defineComponent({
|
||||
name: 'LayoutHeader',
|
||||
components: {
|
||||
Header: Layout.Header,
|
||||
AppLogo,
|
||||
LayoutTrigger,
|
||||
LayoutBreadcrumb,
|
||||
LayoutMenu,
|
||||
UserDropDown,
|
||||
AppLocalePicker,
|
||||
FullScreen,
|
||||
Notify,
|
||||
AppSearch,
|
||||
ErrorAction,
|
||||
LockScreen,
|
||||
LoginSelect,
|
||||
SettingDrawer: createAsyncComponent(() => import('/@/layouts/default/setting/index.vue'), {
|
||||
loading: true,
|
||||
}),
|
||||
Aide
|
||||
},
|
||||
props: {
|
||||
fixed: propTypes.bool,
|
||||
},
|
||||
setup(props) {
|
||||
const { prefixCls } = useDesign('layout-header');
|
||||
const userStore = useUserStore();
|
||||
const { getShowTopMenu, getShowHeaderTrigger, getSplit, getIsMixMode, getMenuWidth, getIsMixSidebar } = useMenuSetting();
|
||||
const { getUseErrorHandle, getShowSettingButton, getSettingButtonPosition } = useRootSetting();
|
||||
const { title } = useGlobSetting();
|
||||
|
||||
const {
|
||||
getHeaderTheme,
|
||||
getShowFullScreen,
|
||||
getShowNotice,
|
||||
getShowContent,
|
||||
getShowBread,
|
||||
getShowHeaderLogo,
|
||||
getShowHeader,
|
||||
getShowSearch,
|
||||
getUseLockPage,
|
||||
getShowBreadTitle,
|
||||
} = useHeaderSetting();
|
||||
const {
|
||||
getHeaderTheme,
|
||||
getShowFullScreen,
|
||||
getShowNotice,
|
||||
getShowContent,
|
||||
getShowBread,
|
||||
getShowHeaderLogo,
|
||||
getShowHeader,
|
||||
getShowSearch,
|
||||
getUseLockPage,
|
||||
getShowBreadTitle,
|
||||
} = useHeaderSetting();
|
||||
|
||||
const { getShowLocalePicker } = useLocale();
|
||||
const { getShowLocalePicker } = useLocale();
|
||||
|
||||
const { getIsMobile } = useAppInject();
|
||||
const { getIsMobile } = useAppInject();
|
||||
|
||||
const getHeaderClass = computed(() => {
|
||||
const theme = unref(getHeaderTheme);
|
||||
return [
|
||||
prefixCls,
|
||||
{
|
||||
[`${prefixCls}--fixed`]: props.fixed,
|
||||
[`${prefixCls}--mobile`]: unref(getIsMobile),
|
||||
[`${prefixCls}--${theme}`]: theme,
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
const getShowSetting = computed(() => {
|
||||
if (!unref(getShowSettingButton)) {
|
||||
return false;
|
||||
}
|
||||
const settingButtonPosition = unref(getSettingButtonPosition);
|
||||
|
||||
if (settingButtonPosition === SettingButtonPositionEnum.AUTO) {
|
||||
return unref(getShowHeader);
|
||||
}
|
||||
return settingButtonPosition === SettingButtonPositionEnum.HEADER;
|
||||
});
|
||||
|
||||
const getLogoWidth = computed(() => {
|
||||
if (!unref(getIsMixMode) || unref(getIsMobile)) {
|
||||
return {};
|
||||
}
|
||||
const width = unref(getMenuWidth) < 180 ? 180 : unref(getMenuWidth);
|
||||
return { width: `${width}px` };
|
||||
});
|
||||
|
||||
const getSplitType = computed(() => {
|
||||
return unref(getSplit) ? MenuSplitTyeEnum.TOP : MenuSplitTyeEnum.NONE;
|
||||
});
|
||||
|
||||
const getMenuMode = computed(() => {
|
||||
return unref(getSplit) ? MenuModeEnum.HORIZONTAL : null;
|
||||
});
|
||||
|
||||
/**
|
||||
* 首页多租户部门弹窗逻辑
|
||||
*/
|
||||
const loginSelectRef = ref();
|
||||
|
||||
function showLoginSelect() {
|
||||
//update-begin---author:liusq Date:20220101 for:判断登录进来是否需要弹窗选择租户----
|
||||
//判断是否是登陆进来
|
||||
const loginInfo = toRaw(userStore.getLoginInfo) || {};
|
||||
if (!!loginInfo.isLogin) {
|
||||
loginSelectRef.value.show(loginInfo);
|
||||
}
|
||||
//update-end---author:liusq Date:20220101 for:判断登录进来是否需要弹窗选择租户----
|
||||
}
|
||||
|
||||
function loginSelectOk() {
|
||||
console.log('成功。。。。。');
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
showLoginSelect();
|
||||
});
|
||||
|
||||
return {
|
||||
const getHeaderClass = computed(() => {
|
||||
const theme = unref(getHeaderTheme);
|
||||
return [
|
||||
prefixCls,
|
||||
getHeaderClass,
|
||||
getShowHeaderLogo,
|
||||
getHeaderTheme,
|
||||
getShowHeaderTrigger,
|
||||
getIsMobile,
|
||||
getShowBreadTitle,
|
||||
getShowBread,
|
||||
getShowContent,
|
||||
getSplitType,
|
||||
getSplit,
|
||||
getMenuMode,
|
||||
getShowTopMenu,
|
||||
getShowLocalePicker,
|
||||
getShowFullScreen,
|
||||
getShowNotice,
|
||||
getUseErrorHandle,
|
||||
getLogoWidth,
|
||||
getIsMixSidebar,
|
||||
getShowSettingButton,
|
||||
getShowSetting,
|
||||
getShowSearch,
|
||||
getUseLockPage,
|
||||
loginSelectOk,
|
||||
loginSelectRef,
|
||||
title,
|
||||
t
|
||||
};
|
||||
},
|
||||
});
|
||||
{
|
||||
[`${prefixCls}--fixed`]: props.fixed,
|
||||
[`${prefixCls}--mobile`]: unref(getIsMobile),
|
||||
[`${prefixCls}--${theme}`]: theme,
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
const getShowSetting = computed(() => {
|
||||
if (!unref(getShowSettingButton)) {
|
||||
return false;
|
||||
}
|
||||
const settingButtonPosition = unref(getSettingButtonPosition);
|
||||
|
||||
if (settingButtonPosition === SettingButtonPositionEnum.AUTO) {
|
||||
return unref(getShowHeader);
|
||||
}
|
||||
return settingButtonPosition === SettingButtonPositionEnum.HEADER;
|
||||
});
|
||||
|
||||
const getLogoWidth = computed(() => {
|
||||
if (!unref(getIsMixMode) || unref(getIsMobile)) {
|
||||
return {};
|
||||
}
|
||||
const width = unref(getMenuWidth) < 180 ? 180 : unref(getMenuWidth);
|
||||
return { width: `${width}px` };
|
||||
});
|
||||
|
||||
const getSplitType = computed(() => {
|
||||
return unref(getSplit) ? MenuSplitTyeEnum.TOP : MenuSplitTyeEnum.NONE;
|
||||
});
|
||||
|
||||
const getMenuMode = computed(() => {
|
||||
return unref(getSplit) ? MenuModeEnum.HORIZONTAL : null;
|
||||
});
|
||||
|
||||
/**
|
||||
* 首页多租户部门弹窗逻辑
|
||||
*/
|
||||
const loginSelectRef = ref();
|
||||
|
||||
function showLoginSelect() {
|
||||
//update-begin---author:liusq Date:20220101 for:判断登录进来是否需要弹窗选择租户----
|
||||
//判断是否是登陆进来
|
||||
const loginInfo = toRaw(userStore.getLoginInfo) || {};
|
||||
if (!!loginInfo.isLogin) {
|
||||
loginSelectRef.value.show(loginInfo);
|
||||
}
|
||||
//update-end---author:liusq Date:20220101 for:判断登录进来是否需要弹窗选择租户----
|
||||
}
|
||||
|
||||
function loginSelectOk() {
|
||||
console.log('成功。。。。。');
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
showLoginSelect();
|
||||
});
|
||||
|
||||
return {
|
||||
prefixCls,
|
||||
getHeaderClass,
|
||||
getShowHeaderLogo,
|
||||
getHeaderTheme,
|
||||
getShowHeaderTrigger,
|
||||
getIsMobile,
|
||||
getShowBreadTitle,
|
||||
getShowBread,
|
||||
getShowContent,
|
||||
getSplitType,
|
||||
getSplit,
|
||||
getMenuMode,
|
||||
getShowTopMenu,
|
||||
getShowLocalePicker,
|
||||
getShowFullScreen,
|
||||
getShowNotice,
|
||||
getUseErrorHandle,
|
||||
getLogoWidth,
|
||||
getIsMixSidebar,
|
||||
getShowSettingButton,
|
||||
getShowSetting,
|
||||
getShowSearch,
|
||||
getUseLockPage,
|
||||
loginSelectOk,
|
||||
loginSelectRef,
|
||||
title,
|
||||
t
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="less">
|
||||
@import './index.less';
|
||||
//update-begin---author:scott ---date:2022-09-30 for:默认隐藏顶部菜单面包屑-----------
|
||||
//顶部欢迎语展示样式
|
||||
@prefix-cls: ~'@{namespace}-layout-header';
|
||||
|
||||
.ant-layout .@{prefix-cls} {
|
||||
display: flex;
|
||||
padding: 0 8px;
|
||||
height: 48px;
|
||||
align-items: center;
|
||||
|
||||
@import './index.less';
|
||||
//update-begin---author:scott ---date:2022-09-30 for:默认隐藏顶部菜单面包屑-----------
|
||||
//顶部欢迎语展示样式
|
||||
@prefix-cls: ~'@{namespace}-layout-header';
|
||||
|
||||
.ant-layout .@{prefix-cls} {
|
||||
display: flex;
|
||||
padding: 0 8px;
|
||||
height: 48px;
|
||||
align-items: center;
|
||||
|
||||
.headerIntroductionClass {
|
||||
margin-right: 4px;
|
||||
margin-bottom: 2px;
|
||||
border-bottom: 0px;
|
||||
border-left: 0px;
|
||||
}
|
||||
|
||||
&--light {
|
||||
.headerIntroductionClass {
|
||||
margin-right: 4px;
|
||||
margin-bottom: 2px;
|
||||
border-bottom: 0px;
|
||||
border-left: 0px;
|
||||
color: @breadcrumb-item-normal-color;
|
||||
}
|
||||
|
||||
&--light {
|
||||
.headerIntroductionClass {
|
||||
color: @breadcrumb-item-normal-color;
|
||||
}
|
||||
}
|
||||
|
||||
&--dark {
|
||||
.headerIntroductionClass {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
&--dark {
|
||||
.headerIntroductionClass {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
.anticon, .truncate {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
.anticon,
|
||||
.truncate {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
//update-end---author:scott ---date::2022-09-30 for:默认隐藏顶部菜单面包屑--------------
|
||||
}
|
||||
|
||||
//update-end---author:scott ---date::2022-09-30 for:默认隐藏顶部菜单面包屑--------------
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -65,13 +65,13 @@ const setting: ProjectConfig = {
|
|||
// 头部配置
|
||||
headerSetting: {
|
||||
// 背景色
|
||||
bgColor: HEADER_PRESET_BG_COLOR_LIST[0],
|
||||
bgColor: HEADER_PRESET_BG_COLOR_LIST[5],
|
||||
// 固定头部
|
||||
fixed: true,
|
||||
// 是否显示顶部
|
||||
show: true,
|
||||
// 主题
|
||||
theme: ThemeEnum.LIGHT,
|
||||
theme: ThemeEnum.DARK,
|
||||
// 开启锁屏功能
|
||||
useLockPage: true,
|
||||
// 显示全屏按钮
|
||||
|
@ -87,7 +87,7 @@ const setting: ProjectConfig = {
|
|||
// 菜单配置
|
||||
menuSetting: {
|
||||
// 背景色
|
||||
bgColor: SIDE_BAR_BG_COLOR_LIST[0],
|
||||
bgColor: SIDE_BAR_BG_COLOR_LIST[3],
|
||||
// 是否固定住左侧菜单
|
||||
fixed: true,
|
||||
// 菜单折叠
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
<template>
|
||||
<div>
|
||||
<h1>学生信息</h1>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
|
@ -1,5 +1,8 @@
|
|||
<template>
|
||||
<IndexDef v-if="indexStyle === 0"></IndexDef>
|
||||
<div class="mod-home">
|
||||
<h3>欢迎使用评阅人员管理系统</h3>
|
||||
</div>
|
||||
<!--<IndexDef v-if="indexStyle === 0"></IndexDef>
|
||||
<IndexChart v-if="indexStyle === 1"></IndexChart>
|
||||
<IndexBdc v-if="indexStyle == 2"></IndexBdc>
|
||||
<IndexTask v-if="indexStyle == 3"></IndexTask>
|
||||
|
@ -11,14 +14,20 @@
|
|||
<a-radio :value="2">业务统计</a-radio>
|
||||
<a-radio :value="3">我的任务</a-radio>
|
||||
</a-radio-group>
|
||||
</div>
|
||||
</div>-->
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import IndexDef from './homePage/IndexDef.vue';
|
||||
import IndexChart from './homePage/IndexChart.vue';
|
||||
import IndexBdc from './homePage/IndexBdc.vue';
|
||||
import IndexTask from './homePage/IndexTask.vue';
|
||||
//import { ref } from 'vue';
|
||||
//import IndexDef from './homePage/IndexDef.vue';
|
||||
//import IndexChart from './homePage/IndexChart.vue';
|
||||
//import IndexBdc from './homePage/IndexBdc.vue';
|
||||
//import IndexTask from './homePage/IndexTask.vue';
|
||||
|
||||
const indexStyle = ref(0);
|
||||
//const indexStyle = ref(0);
|
||||
</script>
|
||||
<style>
|
||||
.mod-home {
|
||||
line-height: 2.5;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,29 +1,30 @@
|
|||
<template>
|
||||
<LoginFormTitle v-show="getShow" class="enter-x" />
|
||||
<Form class="p-4 enter-x" :model="formData" :rules="getFormRules" ref="formRef" v-show="getShow" @keypress.enter="handleLogin">
|
||||
<Form class="p-4 enter-x" :model="formData" :rules="getFormRules" ref="formRef" v-show="getShow"
|
||||
@keypress.enter="handleLogin">
|
||||
<FormItem name="account" class="enter-x">
|
||||
<Input size="large" v-model:value="formData.account" :placeholder="t('sys.login.userName')" class="fix-auto-fill" />
|
||||
<Input size="large" v-model:value="formData.account" :placeholder="t('sys.login.userName')"
|
||||
class="fix-auto-fill" />
|
||||
</FormItem>
|
||||
<FormItem name="password" class="enter-x">
|
||||
<InputPassword size="large" visibilityToggle v-model:value="formData.password" :placeholder="t('sys.login.password')" />
|
||||
<InputPassword size="large" visibilityToggle v-model:value="formData.password"
|
||||
:placeholder="t('sys.login.password')" />
|
||||
</FormItem>
|
||||
|
||||
<!--验证码-->
|
||||
<ARow class="enter-x">
|
||||
<ACol :span="12">
|
||||
<FormItem name="inputCode" class="enter-x">
|
||||
<Input size="large" v-model:value="formData.inputCode" :placeholder="t('sys.login.inputCode')" style="min-width: 100px" />
|
||||
<Input size="large" v-model:value="formData.inputCode" :placeholder="t('sys.login.inputCode')"
|
||||
style="min-width: 100px" />
|
||||
</FormItem>
|
||||
</ACol>
|
||||
<ACol :span="8">
|
||||
<FormItem :style="{ 'text-align': 'right', 'margin-left': '20px' }" class="enter-x">
|
||||
<img
|
||||
v-if="randCodeData.requestCodeSuccess"
|
||||
style="margin-top: 2px; max-width: initial"
|
||||
:src="randCodeData.randCodeImage"
|
||||
@click="handleChangeCheckCode"
|
||||
/>
|
||||
<img v-else style="margin-top: 2px; max-width: initial" src="../../../assets/images/checkcode.png" @click="handleChangeCheckCode" />
|
||||
<img v-if="randCodeData.requestCodeSuccess" style="margin-top: 2px; max-width: initial"
|
||||
:src="randCodeData.randCodeImage" @click="handleChangeCheckCode" />
|
||||
<img v-else style="margin-top: 2px; max-width: initial" src="../../../assets/images/checkcode.png"
|
||||
@click="handleChangeCheckCode" />
|
||||
</FormItem>
|
||||
</ACol>
|
||||
</ARow>
|
||||
|
@ -76,121 +77,128 @@
|
|||
<Divider class="enter-x">{{ t('sys.login.otherSignIn') }}</Divider>
|
||||
|
||||
<div class="flex justify-evenly enter-x" :class="`${prefixCls}-sign-in-way`">
|
||||
<a @click="onThirdLogin('github')" title="github"><GithubFilled /></a>
|
||||
<a @click="onThirdLogin('wechat_enterprise')" title="企业微信"> <icon-font class="item-icon" type="icon-qiyeweixin3" /></a>
|
||||
<a @click="onThirdLogin('dingtalk')" title="钉钉"><DingtalkCircleFilled /></a>
|
||||
<a @click="onThirdLogin('wechat_open')" title="微信"><WechatFilled /></a>
|
||||
<a @click="onThirdLogin('github')" title="github">
|
||||
<GithubFilled />
|
||||
</a>
|
||||
<a @click="onThirdLogin('wechat_enterprise')" title="企业微信"> <icon-font class="item-icon"
|
||||
type="icon-qiyeweixin3" /></a>
|
||||
<a @click="onThirdLogin('dingtalk')" title="钉钉">
|
||||
<DingtalkCircleFilled />
|
||||
</a>
|
||||
<a @click="onThirdLogin('wechat_open')" title="微信">
|
||||
<WechatFilled />
|
||||
</a>
|
||||
</div>
|
||||
</Form>
|
||||
<!-- 第三方登录相关弹框 -->
|
||||
<ThirdModal ref="thirdModalRef"></ThirdModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref, toRaw, unref, computed, onMounted } from 'vue';
|
||||
import { reactive, ref, toRaw, unref, computed, onMounted } from 'vue';
|
||||
|
||||
import { Checkbox, Form, Input, Row, Col, Button, Divider } from 'ant-design-vue';
|
||||
import { GithubFilled, WechatFilled, DingtalkCircleFilled, createFromIconfontCN } from '@ant-design/icons-vue';
|
||||
import LoginFormTitle from './LoginFormTitle.vue';
|
||||
import ThirdModal from './ThirdModal.vue';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { Checkbox, Form, Input, Row, Col, Button, Divider } from 'ant-design-vue';
|
||||
import { GithubFilled, WechatFilled, DingtalkCircleFilled, createFromIconfontCN } from '@ant-design/icons-vue';
|
||||
import LoginFormTitle from './LoginFormTitle.vue';
|
||||
import ThirdModal from './ThirdModal.vue';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
import { LoginStateEnum, useLoginState, useFormRules, useFormValid } from './useLogin';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { getCodeInfo } from '/@/api/sys/user';
|
||||
//import { onKeyStroke } from '@vueuse/core';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
import { LoginStateEnum, useLoginState, useFormRules, useFormValid } from './useLogin';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { getCodeInfo } from '/@/api/sys/user';
|
||||
//import { onKeyStroke } from '@vueuse/core';
|
||||
|
||||
const ACol = Col;
|
||||
const ARow = Row;
|
||||
const FormItem = Form.Item;
|
||||
const InputPassword = Input.Password;
|
||||
const IconFont = createFromIconfontCN({
|
||||
scriptUrl: '//at.alicdn.com/t/font_2316098_umqusozousr.js',
|
||||
});
|
||||
const { t } = useI18n();
|
||||
const { notification, createErrorModal } = useMessage();
|
||||
const { prefixCls } = useDesign('login');
|
||||
const userStore = useUserStore();
|
||||
const ACol = Col;
|
||||
const ARow = Row;
|
||||
const FormItem = Form.Item;
|
||||
const InputPassword = Input.Password;
|
||||
const IconFont = createFromIconfontCN({
|
||||
scriptUrl: '//at.alicdn.com/t/font_2316098_umqusozousr.js',
|
||||
});
|
||||
const { t } = useI18n();
|
||||
const { notification, createErrorModal } = useMessage();
|
||||
const { prefixCls } = useDesign('login');
|
||||
const userStore = useUserStore();
|
||||
|
||||
const { setLoginState, getLoginState } = useLoginState();
|
||||
const { getFormRules } = useFormRules();
|
||||
const { setLoginState, getLoginState } = useLoginState();
|
||||
const { getFormRules } = useFormRules();
|
||||
|
||||
const formRef = ref();
|
||||
const thirdModalRef = ref();
|
||||
const loading = ref(false);
|
||||
const rememberMe = ref(false);
|
||||
const formRef = ref();
|
||||
const thirdModalRef = ref();
|
||||
const loading = ref(false);
|
||||
const rememberMe = ref(false);
|
||||
|
||||
const formData = reactive({
|
||||
account: 'admin',
|
||||
password: '123456',
|
||||
inputCode: '',
|
||||
});
|
||||
const randCodeData = reactive({
|
||||
randCodeImage: '',
|
||||
requestCodeSuccess: false,
|
||||
checkKey: null,
|
||||
});
|
||||
const formData = reactive({
|
||||
account: 'admin',
|
||||
password: '123456',
|
||||
inputCode: '',
|
||||
});
|
||||
const randCodeData = reactive({
|
||||
randCodeImage: '',
|
||||
requestCodeSuccess: false,
|
||||
checkKey: null,
|
||||
});
|
||||
|
||||
const { validForm } = useFormValid(formRef);
|
||||
const { validForm } = useFormValid(formRef);
|
||||
|
||||
//onKeyStroke('Enter', handleLogin);
|
||||
//onKeyStroke('Enter', handleLogin);
|
||||
|
||||
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.LOGIN);
|
||||
const getShow = computed(() => unref(getLoginState) === LoginStateEnum.LOGIN);
|
||||
|
||||
async function handleLogin() {
|
||||
const data = await validForm();
|
||||
if (!data) return;
|
||||
try {
|
||||
loading.value = true;
|
||||
const { userInfo } = await userStore.login(
|
||||
toRaw({
|
||||
password: data.password,
|
||||
username: data.account,
|
||||
captcha: data.inputCode,
|
||||
checkKey: randCodeData.checkKey,
|
||||
mode: 'none', //不要默认的错误提示
|
||||
})
|
||||
);
|
||||
if (userInfo) {
|
||||
notification.success({
|
||||
message: t('sys.login.loginSuccessTitle'),
|
||||
description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.realname}`,
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
notification.error({
|
||||
message: t('sys.api.errorTip'),
|
||||
description: error.message || t('sys.api.networkExceptionMsg'),
|
||||
async function handleLogin() {
|
||||
const data = await validForm();
|
||||
if (!data) return;
|
||||
try {
|
||||
loading.value = true;
|
||||
const { userInfo } = await userStore.login(
|
||||
toRaw({
|
||||
password: data.password,
|
||||
username: data.account,
|
||||
captcha: data.inputCode,
|
||||
checkKey: randCodeData.checkKey,
|
||||
mode: 'none', //不要默认的错误提示
|
||||
})
|
||||
);
|
||||
if (userInfo) {
|
||||
notification.success({
|
||||
message: t('sys.login.loginSuccessTitle'),
|
||||
description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.realname}`,
|
||||
duration: 3,
|
||||
});
|
||||
loading.value = false;
|
||||
|
||||
//update-begin-author:taoyan date:2022-5-3 for: issues/41 登录页面,当输入验证码错误时,验证码图片要刷新一下,而不是保持旧的验证码图片不变
|
||||
handleChangeCheckCode();
|
||||
//update-end-author:taoyan date:2022-5-3 for: issues/41 登录页面,当输入验证码错误时,验证码图片要刷新一下,而不是保持旧的验证码图片不变
|
||||
}
|
||||
}
|
||||
function handleChangeCheckCode() {
|
||||
formData.inputCode = '';
|
||||
//TODO 兼容mock和接口,暂时这样处理
|
||||
randCodeData.checkKey = 1629428467008; //new Date().getTime();
|
||||
getCodeInfo(randCodeData.checkKey).then((res) => {
|
||||
randCodeData.randCodeImage = res;
|
||||
randCodeData.requestCodeSuccess = true;
|
||||
} catch (error) {
|
||||
notification.error({
|
||||
message: t('sys.api.errorTip'),
|
||||
description: error.message || t('sys.api.networkExceptionMsg'),
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
loading.value = false;
|
||||
|
||||
/**
|
||||
* 第三方登录
|
||||
* @param type
|
||||
*/
|
||||
function onThirdLogin(type) {
|
||||
thirdModalRef.value.onThirdLogin(type);
|
||||
}
|
||||
//初始化验证码
|
||||
onMounted(() => {
|
||||
//update-begin-author:taoyan date:2022-5-3 for: issues/41 登录页面,当输入验证码错误时,验证码图片要刷新一下,而不是保持旧的验证码图片不变
|
||||
handleChangeCheckCode();
|
||||
//update-end-author:taoyan date:2022-5-3 for: issues/41 登录页面,当输入验证码错误时,验证码图片要刷新一下,而不是保持旧的验证码图片不变
|
||||
}
|
||||
}
|
||||
function handleChangeCheckCode() {
|
||||
formData.inputCode = '';
|
||||
//TODO 兼容mock和接口,暂时这样处理
|
||||
randCodeData.checkKey = 1629428467008; //new Date().getTime();
|
||||
getCodeInfo(randCodeData.checkKey).then((res) => {
|
||||
randCodeData.randCodeImage = res;
|
||||
randCodeData.requestCodeSuccess = true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 第三方登录
|
||||
* @param type
|
||||
*/
|
||||
function onThirdLogin(type) {
|
||||
thirdModalRef.value.onThirdLogin(type);
|
||||
}
|
||||
//初始化验证码
|
||||
onMounted(() => {
|
||||
handleChangeCheckCode();
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -1,218 +1,221 @@
|
|||
<template>
|
||||
<div class="app-loading">
|
||||
<div class="app-loading-wrap">
|
||||
<img src="/resource/img/logo.png" class="app-loading-logo" alt="Logo">
|
||||
<div class="app-loading-dots">
|
||||
<span class="dot dot-spin"><i></i><i></i><i></i><i></i></span>
|
||||
</div>
|
||||
<div class="app-loading-title">JeecgBoot 企业级低代码平台</div>
|
||||
</div>
|
||||
<div class="app-loading">
|
||||
<div class="app-loading-wrap">
|
||||
<!--<img src="/resource/img/logo.png" class="app-loading-logo" alt="Logo">-->
|
||||
<div class="app-loading-dots">
|
||||
<span class="dot dot-spin"><i></i><i></i><i></i><i></i></span>
|
||||
</div>
|
||||
<div class="app-loading-title">哈尔滨师范大学</div>
|
||||
<div class="app-loading-title">评阅人员管理系统</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
/**
|
||||
* 地址中携带token,跳转至此页面进行登录操作
|
||||
*/
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
|
||||
export default {
|
||||
name: "TokenLogin",
|
||||
setup(){
|
||||
const route = useRoute();
|
||||
let router = useRouter();
|
||||
const {createMessage, notification} = useMessage()
|
||||
const {t} = useI18n();
|
||||
const routeQuery:any = route.query;
|
||||
if(!routeQuery){
|
||||
createMessage.warning('参数无效')
|
||||
}
|
||||
|
||||
const token = routeQuery['loginToken'];
|
||||
if(!token){
|
||||
createMessage.warning('token无效')
|
||||
}
|
||||
const userStore = useUserStore();
|
||||
userStore.ThirdLogin({ token, thirdType:'email', goHome: false }).then(res => {
|
||||
console.log("res====>doThirdLogin",res)
|
||||
if(res && res.userInfo){
|
||||
requestSuccess(res)
|
||||
}else{
|
||||
requestFailed(res)
|
||||
}
|
||||
});
|
||||
/**
|
||||
* 地址中携带token,跳转至此页面进行登录操作
|
||||
*/
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
|
||||
function requestFailed (err) {
|
||||
export default {
|
||||
name: "TokenLogin",
|
||||
setup() {
|
||||
const route = useRoute();
|
||||
let router = useRouter();
|
||||
const { createMessage, notification } = useMessage()
|
||||
const { t } = useI18n();
|
||||
const routeQuery: any = route.query;
|
||||
if (!routeQuery) {
|
||||
createMessage.warning('参数无效')
|
||||
}
|
||||
|
||||
const token = routeQuery['loginToken'];
|
||||
if (!token) {
|
||||
createMessage.warning('token无效')
|
||||
}
|
||||
const userStore = useUserStore();
|
||||
userStore.ThirdLogin({ token, thirdType: 'email', goHome: false }).then(res => {
|
||||
console.log("res====>doThirdLogin", res)
|
||||
if (res && res.userInfo) {
|
||||
requestSuccess(res)
|
||||
} else {
|
||||
requestFailed(res)
|
||||
}
|
||||
});
|
||||
|
||||
function requestFailed(err) {
|
||||
notification.error({
|
||||
message: '登录失败',
|
||||
description: ((err.response || {}).data || {}).message || err.message || "请求出现错误,请稍后再试",
|
||||
duration: 4,
|
||||
});
|
||||
}
|
||||
|
||||
function requestSuccess(res) {
|
||||
let info = routeQuery.info;
|
||||
if (info) {
|
||||
let query = JSON.parse(info);
|
||||
|
||||
//update-begin-author:taoyan date:2023-4-27 for: QQYUN-4882【简流】节点消息通知 邮箱 点击办理跳到了应用首页
|
||||
let path = '';
|
||||
if (query.isLowApp === 1) {
|
||||
path = '/myapps/personalOffice/myTodo'
|
||||
} else {
|
||||
let taskId = query.taskId;
|
||||
path = '/task/handle/' + taskId
|
||||
}
|
||||
//update-end-author:taoyan date:2023-4-27 for: QQYUN-4882【简流】节点消息通知 邮箱 点击办理跳到了应用首页
|
||||
|
||||
router.replace({ path, query });
|
||||
notification.success({
|
||||
message: t('sys.login.loginSuccessTitle'),
|
||||
description: `${t('sys.login.loginSuccessDesc')}: ${res.userInfo.realname}`,
|
||||
duration: 3,
|
||||
});
|
||||
} else {
|
||||
notification.error({
|
||||
message: '登录失败',
|
||||
description: ((err.response || {}).data || {}).message || err.message || "请求出现错误,请稍后再试",
|
||||
message: '参数失效',
|
||||
description: "页面跳转参数丢失,请查看日志",
|
||||
duration: 4,
|
||||
});
|
||||
}
|
||||
|
||||
function requestSuccess(res){
|
||||
let info = routeQuery.info;
|
||||
if(info){
|
||||
let query = JSON.parse(info);
|
||||
|
||||
//update-begin-author:taoyan date:2023-4-27 for: QQYUN-4882【简流】节点消息通知 邮箱 点击办理跳到了应用首页
|
||||
let path = '';
|
||||
if(query.isLowApp === 1){
|
||||
path = '/myapps/personalOffice/myTodo'
|
||||
}else{
|
||||
let taskId = query.taskId;
|
||||
path = '/task/handle/' + taskId
|
||||
}
|
||||
//update-end-author:taoyan date:2023-4-27 for: QQYUN-4882【简流】节点消息通知 邮箱 点击办理跳到了应用首页
|
||||
|
||||
router.replace({ path, query });
|
||||
notification.success({
|
||||
message: t('sys.login.loginSuccessTitle'),
|
||||
description: `${t('sys.login.loginSuccessDesc')}: ${res.userInfo.realname}`,
|
||||
duration: 3,
|
||||
});
|
||||
}else{
|
||||
notification.error({
|
||||
message: '参数失效',
|
||||
description: "页面跳转参数丢失,请查看日志",
|
||||
duration: 4,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
html[data-theme='dark'] .app-loading {
|
||||
background-color: #2c344a;
|
||||
}
|
||||
|
||||
html[data-theme='dark'] .app-loading {
|
||||
background-color: #2c344a;
|
||||
}
|
||||
html[data-theme='dark'] .app-loading .app-loading-title {
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
|
||||
html[data-theme='dark'] .app-loading .app-loading-title {
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
.app-loading {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
background-color: #f4f7f9;
|
||||
}
|
||||
|
||||
.app-loading {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
background-color: #f4f7f9;
|
||||
}
|
||||
.app-loading .app-loading-wrap {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
display: flex;
|
||||
-webkit-transform: translate3d(-50%, -50%, 0);
|
||||
transform: translate3d(-50%, -50%, 0);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.app-loading .app-loading-wrap {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
display: flex;
|
||||
-webkit-transform: translate3d(-50%, -50%, 0);
|
||||
transform: translate3d(-50%, -50%, 0);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
.app-loading .dots {
|
||||
display: flex;
|
||||
padding: 98px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.app-loading .dots {
|
||||
display: flex;
|
||||
padding: 98px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.app-loading .app-loading-title {
|
||||
display: flex;
|
||||
margin-top: 30px;
|
||||
font-size: 30px;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.app-loading .app-loading-title {
|
||||
display: flex;
|
||||
margin-top: 30px;
|
||||
font-size: 30px;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.app-loading .app-loading-logo {
|
||||
display: block;
|
||||
width: 90px;
|
||||
margin: 0 auto;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.app-loading .app-loading-logo {
|
||||
display: block;
|
||||
width: 90px;
|
||||
margin: 0 auto;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.dot {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin-top: 30px;
|
||||
font-size: 32px;
|
||||
transform: rotate(45deg);
|
||||
box-sizing: border-box;
|
||||
animation: antRotate 1.2s infinite linear;
|
||||
}
|
||||
|
||||
.dot {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin-top: 30px;
|
||||
font-size: 32px;
|
||||
transform: rotate(45deg);
|
||||
box-sizing: border-box;
|
||||
animation: antRotate 1.2s infinite linear;
|
||||
}
|
||||
.dot i {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: #0065cc;
|
||||
border-radius: 100%;
|
||||
opacity: 0.3;
|
||||
transform: scale(0.75);
|
||||
animation: antSpinMove 1s infinite linear alternate;
|
||||
transform-origin: 50% 50%;
|
||||
}
|
||||
|
||||
.dot i {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: #0065cc;
|
||||
border-radius: 100%;
|
||||
opacity: 0.3;
|
||||
transform: scale(0.75);
|
||||
animation: antSpinMove 1s infinite linear alternate;
|
||||
transform-origin: 50% 50%;
|
||||
}
|
||||
.dot i:nth-child(1) {
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.dot i:nth-child(1) {
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.dot i:nth-child(2) {
|
||||
top: 0;
|
||||
right: 0;
|
||||
-webkit-animation-delay: 0.4s;
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
|
||||
.dot i:nth-child(2) {
|
||||
top: 0;
|
||||
right: 0;
|
||||
-webkit-animation-delay: 0.4s;
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
.dot i:nth-child(3) {
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
-webkit-animation-delay: 0.8s;
|
||||
animation-delay: 0.8s;
|
||||
}
|
||||
|
||||
.dot i:nth-child(3) {
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
-webkit-animation-delay: 0.8s;
|
||||
animation-delay: 0.8s;
|
||||
}
|
||||
.dot i:nth-child(4) {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
-webkit-animation-delay: 1.2s;
|
||||
animation-delay: 1.2s;
|
||||
}
|
||||
|
||||
.dot i:nth-child(4) {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
-webkit-animation-delay: 1.2s;
|
||||
animation-delay: 1.2s;
|
||||
}
|
||||
@keyframes antRotate {
|
||||
to {
|
||||
-webkit-transform: rotate(405deg);
|
||||
transform: rotate(405deg);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes antRotate {
|
||||
to {
|
||||
-webkit-transform: rotate(405deg);
|
||||
transform: rotate(405deg);
|
||||
}
|
||||
}
|
||||
@keyframes antSpinMove {
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes antSpinMove {
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@keyframes antRotate {
|
||||
to {
|
||||
-webkit-transform: rotate(405deg);
|
||||
transform: rotate(405deg);
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes antRotate {
|
||||
to {
|
||||
-webkit-transform: rotate(405deg);
|
||||
transform: rotate(405deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes antSpinMove {
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes antSpinMove {
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,86 +1,65 @@
|
|||
<template>
|
||||
<div :class="prefixCls" class="login-background-img">
|
||||
<AppLocalePicker class="absolute top-4 right-4 enter-x xl:text-gray-600" :showText="false"/>
|
||||
<AppLocalePicker class="absolute top-4 right-4 enter-x xl:text-gray-600" :showText="false" />
|
||||
<AppDarkModeToggle class="absolute top-3 right-7 enter-x" />
|
||||
<div class="aui-logo" v-if="!getIsMobile">
|
||||
<div>
|
||||
<h3>
|
||||
<img :src="logoImg" alt="jeecg" />
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="aui-phone-logo">
|
||||
<img :src="logoImg" alt="jeecg" />
|
||||
</div>
|
||||
<div v-show="type === 'login'">
|
||||
<div class="aui-content">
|
||||
<div class="aui-container">
|
||||
<div class="aui-form">
|
||||
<div class="aui-image">
|
||||
<div class="aui-image-text">
|
||||
<img :src="adTextImg" />
|
||||
<div>
|
||||
<span class="introduce-text1">哈尔滨师范大学</span>
|
||||
<br>
|
||||
<span class="introduce-text">评阅人员管理系统</span>
|
||||
<br>
|
||||
<br>
|
||||
<!--<span class="introduce-text" style="font-size: 18px;">深入分析 多维展示</span>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="aui-formBox">
|
||||
<div class="aui-formWell">
|
||||
<div class="aui-flex aui-form-nav investment_title">
|
||||
<div class="aui-flex-box" :class="activeIndex === 'accountLogin' ? 'activeNav on' : ''" @click="loginClick('accountLogin')"
|
||||
>{{ t('sys.login.signInFormTitle') }}
|
||||
</div>
|
||||
<div class="aui-flex-box" :class="activeIndex === 'phoneLogin' ? 'activeNav on' : ''" @click="loginClick('phoneLogin')"
|
||||
>{{ t('sys.login.mobileSignInFormTitle') }}
|
||||
<div class="aui-flex-box" :class="activeIndex === 'accountLogin' ? 'activeNav on' : ''"
|
||||
@click="loginClick('accountLogin')">{{ t('sys.login.signInFormTitle') }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="aui-form-box" style="height: 180px">
|
||||
<a-form ref="loginRef" :model="formData" v-if="activeIndex === 'accountLogin'" @keyup.enter.native="loginHandleClick">
|
||||
<div class="aui-form-box" style="height: 140px">
|
||||
<a-form ref="loginRef" :model="formData" v-if="activeIndex === 'accountLogin'"
|
||||
@keyup.enter.native="loginHandleClick">
|
||||
<div class="aui-account">
|
||||
<div class="aui-inputClear">
|
||||
<i class="icon icon-code"></i>
|
||||
<a-form-item>
|
||||
<a-input class="fix-auto-fill" :placeholder="t('sys.login.userName')" v-model:value="formData.username" />
|
||||
<a-input class="fix-auto-fill" :placeholder="t('sys.login.userName')"
|
||||
v-model:value="formData.username" />
|
||||
</a-form-item>
|
||||
</div>
|
||||
<div class="aui-inputClear">
|
||||
<i class="icon icon-password"></i>
|
||||
<a-form-item>
|
||||
<a-input class="fix-auto-fill" type="password" :placeholder="t('sys.login.password')" v-model:value="formData.password" />
|
||||
<a-input class="fix-auto-fill" type="password" :placeholder="t('sys.login.password')"
|
||||
v-model:value="formData.password" />
|
||||
</a-form-item>
|
||||
</div>
|
||||
<div class="aui-inputClear">
|
||||
<i class="icon icon-code"></i>
|
||||
<a-form-item>
|
||||
<a-input class="fix-auto-fill" type="text" :placeholder="t('sys.login.inputCode')" v-model:value="formData.inputCode" />
|
||||
</a-form-item>
|
||||
<div class="aui-code">
|
||||
<img v-if="randCodeData.requestCodeSuccess" :src="randCodeData.randCodeImage" @click="handleChangeCheckCode" />
|
||||
<img v-else style="margin-top: 2px; max-width: initial" :src="codeImg" @click="handleChangeCheckCode" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="aui-flex">
|
||||
<div class="aui-flex-box">
|
||||
<div class="aui-choice">
|
||||
<a-input class="fix-auto-fill" type="checkbox" v-model:value="rememberMe" />
|
||||
<span style="margin-left: 5px">{{ t('sys.login.rememberMe') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="aui-forget">
|
||||
<a @click="forgetHandelClick"> {{ t('sys.login.forgetPassword') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-form>
|
||||
<a-form v-else ref="phoneFormRef" :model="phoneFormData" @keyup.enter.native="loginHandleClick">
|
||||
<div class="aui-account phone">
|
||||
<div class="aui-inputClear phoneClear">
|
||||
<a-input class="fix-auto-fill" :placeholder="t('sys.login.mobile')" v-model:value="phoneFormData.mobile" />
|
||||
<a-input class="fix-auto-fill" :placeholder="t('sys.login.mobile')"
|
||||
v-model:value="phoneFormData.mobile" />
|
||||
</div>
|
||||
<div class="aui-inputClear">
|
||||
<a-input class="fix-auto-fill" :maxlength="6" :placeholder="t('sys.login.smsCode')" v-model:value="phoneFormData.smscode" />
|
||||
<a-input class="fix-auto-fill" :maxlength="6" :placeholder="t('sys.login.smsCode')"
|
||||
v-model:value="phoneFormData.smscode" />
|
||||
<div v-if="showInterval" class="aui-code" @click="getLoginCode">
|
||||
<a>{{ t('component.countdown.normalText') }}</a>
|
||||
</div>
|
||||
<div v-else class="aui-code">
|
||||
<span class="aui-get-code code-shape">{{ t('component.countdown.sendText', [unref(timeRuning)]) }}</span>
|
||||
<span class="aui-get-code code-shape">{{ t('component.countdown.sendText',
|
||||
[unref(timeRuning)]) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -92,42 +71,11 @@
|
|||
{{ t('sys.login.loginButton') }}</a-button>
|
||||
</div>
|
||||
<div class="aui-flex">
|
||||
<a class="aui-linek-code aui-flex-box" @click="codeHandleClick">{{ t('sys.login.qrSignInFormTitle') }}</a>
|
||||
</div>
|
||||
<div class="aui-flex">
|
||||
<a class="aui-linek-code aui-flex-box" @click="registerHandleClick">{{ t('sys.login.registerButton') }}</a>
|
||||
<a class="aui-linek-code aui-flex-box" @click="registerHandleClick">{{ t('sys.login.registerButton')
|
||||
}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a-form @keyup.enter.native="loginHandleClick">
|
||||
<div class="aui-flex aui-third-text">
|
||||
<div class="aui-flex-box aui-third-border">
|
||||
<span>{{ t('sys.login.otherSignIn') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="aui-flex" :class="`${prefixCls}-sign-in-way`">
|
||||
<div class="aui-flex-box">
|
||||
<div class="aui-third-login">
|
||||
<a title="github" @click="onThirdLogin('github')"><GithubFilled /></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="aui-flex-box">
|
||||
<div class="aui-third-login">
|
||||
<a title="企业微信" @click="onThirdLogin('wechat_enterprise')"><icon-font class="item-icon" type="icon-qiyeweixin3" /></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="aui-flex-box">
|
||||
<div class="aui-third-login">
|
||||
<a title="钉钉" @click="onThirdLogin('dingtalk')"><DingtalkCircleFilled /></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="aui-flex-box">
|
||||
<div class="aui-third-login">
|
||||
<a title="微信" @click="onThirdLogin('wechat_open')"><WechatFilled /></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -147,331 +95,310 @@
|
|||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup name="login-mini">
|
||||
import { getCaptcha, getCodeInfo } from '/@/api/sys/user';
|
||||
import { computed, onMounted, reactive, ref, toRaw, unref } from 'vue';
|
||||
import codeImg from '/@/assets/images/checkcode.png';
|
||||
import { Rule } from '/@/components/Form';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { SmsEnum } from '/@/views/sys/login/useLogin';
|
||||
import ThirdModal from '/@/views/sys/login/ThirdModal.vue';
|
||||
import MiniForgotpad from './MiniForgotpad.vue';
|
||||
import MiniRegister from './MiniRegister.vue';
|
||||
import MiniCodelogin from './MiniCodelogin.vue';
|
||||
import logoImg from '/@/assets/loginmini/icon/jeecg_logo.png';
|
||||
import adTextImg from '/@/assets/loginmini/icon/jeecg_ad_text.png';
|
||||
import { AppLocalePicker, AppDarkModeToggle } from '/@/components/Application';
|
||||
import { useLocaleStore } from '/@/store/modules/locale';
|
||||
import { useDesign } from "/@/hooks/web/useDesign";
|
||||
import { useAppInject } from "/@/hooks/web/useAppInject";
|
||||
import { GithubFilled, WechatFilled, DingtalkCircleFilled, createFromIconfontCN } from '@ant-design/icons-vue';
|
||||
import { getCaptcha, getCodeInfo } from '/@/api/sys/user';
|
||||
import { onMounted, reactive, ref, toRaw, unref } from 'vue';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { SmsEnum } from '/@/views/sys/login/useLogin';
|
||||
import ThirdModal from '/@/views/sys/login/ThirdModal.vue';
|
||||
import MiniForgotpad from './MiniForgotpad.vue';
|
||||
import MiniRegister from './MiniRegister.vue';
|
||||
import MiniCodelogin from './MiniCodelogin.vue';
|
||||
import adTextImg from '/@/assets/loginmini/icon/jeecg_ad_text.png';
|
||||
import { AppLocalePicker, AppDarkModeToggle } from '/@/components/Application';
|
||||
import { useLocaleStore } from '/@/store/modules/locale';
|
||||
import { useDesign } from "/@/hooks/web/useDesign";
|
||||
import { useAppInject } from "/@/hooks/web/useAppInject";
|
||||
|
||||
const IconFont = createFromIconfontCN({
|
||||
scriptUrl: '//at.alicdn.com/t/font_2316098_umqusozousr.js',
|
||||
});
|
||||
const { prefixCls } = useDesign('mini-login');
|
||||
const { notification, createMessage } = useMessage();
|
||||
const userStore = useUserStore();
|
||||
const { t } = useI18n();
|
||||
const localeStore = useLocaleStore();
|
||||
const showLocale = localeStore.getShowPicker;
|
||||
const randCodeData = reactive<any>({
|
||||
randCodeImage: '',
|
||||
requestCodeSuccess: false,
|
||||
checkKey: null,
|
||||
});
|
||||
const rememberMe = ref<string>('0');
|
||||
//手机号登录还是账号登录
|
||||
const activeIndex = ref<string>('accountLogin');
|
||||
const type = ref<string>('login');
|
||||
//账号登录表单字段
|
||||
const formData = reactive<any>({
|
||||
inputCode: '',
|
||||
username: 'admin',
|
||||
password: '123456',
|
||||
});
|
||||
//手机登录表单字段
|
||||
const phoneFormData = reactive<any>({
|
||||
mobile: '',
|
||||
smscode: '',
|
||||
});
|
||||
const loginRef = ref();
|
||||
//第三方登录弹窗
|
||||
const thirdModalRef = ref();
|
||||
//扫码登录
|
||||
const codeRef = ref();
|
||||
//是否显示获取验证码
|
||||
const showInterval = ref<boolean>(true);
|
||||
//60s
|
||||
const timeRuning = ref<number>(60);
|
||||
//定时器
|
||||
const timer = ref<any>(null);
|
||||
//忘记密码
|
||||
const forgotRef = ref();
|
||||
//注册
|
||||
const registerRef = ref();
|
||||
const loginLoading = ref<boolean>(false);
|
||||
const { getIsMobile } = useAppInject();
|
||||
const { prefixCls } = useDesign('mini-login');
|
||||
const { notification, createMessage } = useMessage();
|
||||
const userStore = useUserStore();
|
||||
const { t } = useI18n();
|
||||
const localeStore = useLocaleStore();
|
||||
const randCodeData = reactive<any>({
|
||||
randCodeImage: '',
|
||||
requestCodeSuccess: false,
|
||||
checkKey: null,
|
||||
});
|
||||
//手机号登录还是账号登录
|
||||
const activeIndex = ref<string>('accountLogin');
|
||||
const type = ref<string>('login');
|
||||
//账号登录表单字段
|
||||
const formData = reactive<any>({
|
||||
inputCode: '',
|
||||
username: 'admin',
|
||||
password: '123456',
|
||||
});
|
||||
//手机登录表单字段
|
||||
const phoneFormData = reactive<any>({
|
||||
mobile: '',
|
||||
smscode: '',
|
||||
});
|
||||
const loginRef = ref();
|
||||
//第三方登录弹窗
|
||||
const thirdModalRef = ref();
|
||||
//扫码登录
|
||||
const codeRef = ref();
|
||||
//是否显示获取验证码
|
||||
const showInterval = ref<boolean>(true);
|
||||
//60s
|
||||
const timeRuning = ref<number>(60);
|
||||
//定时器
|
||||
const timer = ref<any>(null);
|
||||
//忘记密码
|
||||
const forgotRef = ref();
|
||||
//注册
|
||||
const registerRef = ref();
|
||||
const loginLoading = ref<boolean>(false);
|
||||
const { getIsMobile } = useAppInject();
|
||||
|
||||
defineProps({
|
||||
sessionTimeout: {
|
||||
type: Boolean,
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取验证码
|
||||
*/
|
||||
function handleChangeCheckCode() {
|
||||
formData.inputCode = '';
|
||||
|
||||
randCodeData.checkKey = 1629428467008;
|
||||
getCodeInfo(randCodeData.checkKey).then((res) => {
|
||||
randCodeData.randCodeImage = res;
|
||||
randCodeData.requestCodeSuccess = true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取验证码
|
||||
*/
|
||||
function handleChangeCheckCode() {
|
||||
formData.inputCode = '';
|
||||
/**
|
||||
* 切换登录方式
|
||||
*/
|
||||
function loginClick(type) {
|
||||
activeIndex.value = type;
|
||||
}
|
||||
|
||||
randCodeData.checkKey = 1629428467008;
|
||||
getCodeInfo(randCodeData.checkKey).then((res) => {
|
||||
randCodeData.randCodeImage = res;
|
||||
randCodeData.requestCodeSuccess = true;
|
||||
});
|
||||
/**
|
||||
* 账号或者手机登录
|
||||
*/
|
||||
async function loginHandleClick() {
|
||||
if (unref(activeIndex) === 'accountLogin') {
|
||||
accountLogin();
|
||||
} else {
|
||||
//手机号登录
|
||||
phoneLogin();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换登录方式
|
||||
*/
|
||||
function loginClick(type) {
|
||||
activeIndex.value = type;
|
||||
async function accountLogin() {
|
||||
if (!formData.username) {
|
||||
createMessage.warn(t('sys.login.accountPlaceholder'));
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 账号或者手机登录
|
||||
*/
|
||||
async function loginHandleClick() {
|
||||
if (unref(activeIndex) === 'accountLogin') {
|
||||
accountLogin();
|
||||
} else {
|
||||
//手机号登录
|
||||
phoneLogin();
|
||||
}
|
||||
if (!formData.password) {
|
||||
createMessage.warn(t('sys.login.passwordPlaceholder'));
|
||||
return;
|
||||
}
|
||||
|
||||
async function accountLogin() {
|
||||
if (!formData.username) {
|
||||
createMessage.warn(t('sys.login.accountPlaceholder'));
|
||||
return;
|
||||
}
|
||||
if (!formData.password) {
|
||||
createMessage.warn(t('sys.login.passwordPlaceholder'));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
loginLoading.value = true;
|
||||
const { userInfo } = await userStore.login(
|
||||
toRaw({
|
||||
password: formData.password,
|
||||
username: formData.username,
|
||||
captcha: formData.inputCode,
|
||||
checkKey: randCodeData.checkKey,
|
||||
mode: 'none', //不要默认的错误提示
|
||||
})
|
||||
);
|
||||
if (userInfo) {
|
||||
notification.success({
|
||||
message: t('sys.login.loginSuccessTitle'),
|
||||
description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.realname}`,
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
notification.error({
|
||||
message: t('sys.api.errorTip'),
|
||||
description: error.message || t('sys.login.networkExceptionMsg'),
|
||||
duration: 3,
|
||||
});
|
||||
handleChangeCheckCode();
|
||||
} finally {
|
||||
loginLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 手机号登录
|
||||
*/
|
||||
async function phoneLogin() {
|
||||
if (!phoneFormData.mobile) {
|
||||
createMessage.warn(t('sys.login.mobilePlaceholder'));
|
||||
return;
|
||||
}
|
||||
if (!phoneFormData.smscode) {
|
||||
createMessage.warn(t('sys.login.smsPlaceholder'));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
loginLoading.value = true;
|
||||
const { userInfo }: any = await userStore.phoneLogin({
|
||||
mobile: phoneFormData.mobile,
|
||||
captcha: phoneFormData.smscode,
|
||||
try {
|
||||
loginLoading.value = true;
|
||||
const { userInfo } = await userStore.login(
|
||||
toRaw({
|
||||
password: formData.password,
|
||||
username: formData.username,
|
||||
captcha: formData.inputCode,
|
||||
checkKey: randCodeData.checkKey,
|
||||
mode: 'none', //不要默认的错误提示
|
||||
});
|
||||
if (userInfo) {
|
||||
notification.success({
|
||||
message: t('sys.login.loginSuccessTitle'),
|
||||
description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.realname}`,
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
notification.error({
|
||||
message: t('sys.api.errorTip'),
|
||||
description: error.message || t('sys.login.networkExceptionMsg'),
|
||||
})
|
||||
);
|
||||
if (userInfo) {
|
||||
notification.success({
|
||||
message: t('sys.login.loginSuccessTitle'),
|
||||
description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.realname}`,
|
||||
duration: 3,
|
||||
});
|
||||
} finally {
|
||||
loginLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取手机验证码
|
||||
*/
|
||||
async function getLoginCode() {
|
||||
if (!phoneFormData.mobile) {
|
||||
createMessage.warn(t('sys.login.mobilePlaceholder'));
|
||||
return;
|
||||
}
|
||||
const result = await getCaptcha({ mobile: phoneFormData.mobile, smsmode: SmsEnum.FORGET_PASSWORD });
|
||||
if (result) {
|
||||
const TIME_COUNT = 60;
|
||||
if (!unref(timer)) {
|
||||
timeRuning.value = TIME_COUNT;
|
||||
showInterval.value = false;
|
||||
timer.value = setInterval(() => {
|
||||
if (unref(timeRuning) > 0 && unref(timeRuning) <= TIME_COUNT) {
|
||||
timeRuning.value = timeRuning.value - 1;
|
||||
} else {
|
||||
showInterval.value = true;
|
||||
clearInterval(unref(timer));
|
||||
timer.value = null;
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 第三方登录
|
||||
* @param type
|
||||
*/
|
||||
function onThirdLogin(type) {
|
||||
thirdModalRef.value.onThirdLogin(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 忘记密码
|
||||
*/
|
||||
function forgetHandelClick() {
|
||||
type.value = 'forgot';
|
||||
setTimeout(() => {
|
||||
forgotRef.value.initForm();
|
||||
}, 300);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回登录页面
|
||||
*/
|
||||
function goBack() {
|
||||
activeIndex.value = 'accountLogin';
|
||||
type.value = 'login';
|
||||
}
|
||||
|
||||
/**
|
||||
* 忘记密码/注册账号回调事件
|
||||
* @param value
|
||||
*/
|
||||
function handleSuccess(value) {
|
||||
Object.assign(formData, value);
|
||||
Object.assign(phoneFormData, { mobile: "", smscode: "" });
|
||||
type.value = 'login';
|
||||
activeIndex.value = 'accountLogin';
|
||||
} catch (error) {
|
||||
notification.error({
|
||||
message: t('sys.api.errorTip'),
|
||||
description: error.message || t('sys.login.networkExceptionMsg'),
|
||||
duration: 3,
|
||||
});
|
||||
handleChangeCheckCode();
|
||||
} finally {
|
||||
loginLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册
|
||||
*/
|
||||
function registerHandleClick() {
|
||||
type.value = 'register';
|
||||
setTimeout(() => {
|
||||
registerRef.value.initForm();
|
||||
}, 300);
|
||||
/**
|
||||
* 手机号登录
|
||||
*/
|
||||
async function phoneLogin() {
|
||||
if (!phoneFormData.mobile) {
|
||||
createMessage.warn(t('sys.login.mobilePlaceholder'));
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册
|
||||
*/
|
||||
function codeHandleClick() {
|
||||
type.value = 'codeLogin';
|
||||
setTimeout(() => {
|
||||
codeRef.value.initFrom();
|
||||
}, 300);
|
||||
if (!phoneFormData.smscode) {
|
||||
createMessage.warn(t('sys.login.smsPlaceholder'));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
loginLoading.value = true;
|
||||
const { userInfo }: any = await userStore.phoneLogin({
|
||||
mobile: phoneFormData.mobile,
|
||||
captcha: phoneFormData.smscode,
|
||||
mode: 'none', //不要默认的错误提示
|
||||
});
|
||||
if (userInfo) {
|
||||
notification.success({
|
||||
message: t('sys.login.loginSuccessTitle'),
|
||||
description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.realname}`,
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
notification.error({
|
||||
message: t('sys.api.errorTip'),
|
||||
description: error.message || t('sys.login.networkExceptionMsg'),
|
||||
duration: 3,
|
||||
});
|
||||
} finally {
|
||||
loginLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
//加载验证码
|
||||
handleChangeCheckCode();
|
||||
});
|
||||
/**
|
||||
* 获取手机验证码
|
||||
*/
|
||||
async function getLoginCode() {
|
||||
if (!phoneFormData.mobile) {
|
||||
createMessage.warn(t('sys.login.mobilePlaceholder'));
|
||||
return;
|
||||
}
|
||||
const result = await getCaptcha({ mobile: phoneFormData.mobile, smsmode: SmsEnum.FORGET_PASSWORD });
|
||||
if (result) {
|
||||
const TIME_COUNT = 60;
|
||||
if (!unref(timer)) {
|
||||
timeRuning.value = TIME_COUNT;
|
||||
showInterval.value = false;
|
||||
timer.value = setInterval(() => {
|
||||
if (unref(timeRuning) > 0 && unref(timeRuning) <= TIME_COUNT) {
|
||||
timeRuning.value = timeRuning.value - 1;
|
||||
} else {
|
||||
showInterval.value = true;
|
||||
clearInterval(unref(timer));
|
||||
timer.value = null;
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 返回登录页面
|
||||
*/
|
||||
function goBack() {
|
||||
activeIndex.value = 'accountLogin';
|
||||
type.value = 'login';
|
||||
}
|
||||
|
||||
/**
|
||||
* 忘记密码/注册账号回调事件
|
||||
* @param value
|
||||
*/
|
||||
function handleSuccess(value) {
|
||||
Object.assign(formData, value);
|
||||
Object.assign(phoneFormData, { mobile: "", smscode: "" });
|
||||
type.value = 'login';
|
||||
activeIndex.value = 'accountLogin';
|
||||
handleChangeCheckCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册
|
||||
*/
|
||||
function registerHandleClick() {
|
||||
type.value = 'register';
|
||||
setTimeout(() => {
|
||||
registerRef.value.initForm();
|
||||
}, 300);
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
//加载验证码
|
||||
handleChangeCheckCode();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@import '/@/assets/loginmini/style/home.less';
|
||||
@import '/@/assets/loginmini/style/base.less';
|
||||
@import '/@/assets/loginmini/style/home.less';
|
||||
@import '/@/assets/loginmini/style/base.less';
|
||||
|
||||
:deep(.ant-input:focus) {
|
||||
box-shadow: none;
|
||||
}
|
||||
.aui-get-code {
|
||||
float: right;
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
background: #ffffff;
|
||||
color: #1573e9;
|
||||
border-radius: 100px;
|
||||
padding: 5px 16px;
|
||||
margin: 7px;
|
||||
border: 1px solid #1573e9;
|
||||
top: 12px;
|
||||
}
|
||||
// 介绍文字
|
||||
.introduce-text1 {
|
||||
font-size: 30px;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.aui-get-code:hover {
|
||||
color: #1573e9;
|
||||
}
|
||||
.introduce-text {
|
||||
font-size: 40px;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.code-shape {
|
||||
border-color: #dadada !important;
|
||||
color: #aaa !important;
|
||||
}
|
||||
:deep(.ant-input:focus) {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
:deep(.jeecg-dark-switch){
|
||||
position:absolute;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.aui-link-login{
|
||||
height: 42px;
|
||||
padding: 10px 15px;
|
||||
font-size: 14px;
|
||||
border-radius: 8px;
|
||||
margin-top: 15px;
|
||||
margin-bottom: 8px;
|
||||
flex: 1;
|
||||
color: #fff;
|
||||
}
|
||||
.aui-phone-logo{
|
||||
position: absolute;
|
||||
margin-left: 10px;
|
||||
width: 60px;
|
||||
top:2px;
|
||||
z-index: 4;
|
||||
}
|
||||
.top-3{
|
||||
top: 0.45rem;
|
||||
}
|
||||
.aui-get-code {
|
||||
float: right;
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
background: #ffffff;
|
||||
color: #1573e9;
|
||||
border-radius: 100px;
|
||||
padding: 5px 16px;
|
||||
margin: 7px;
|
||||
border: 1px solid #1573e9;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
.aui-get-code:hover {
|
||||
color: #1573e9;
|
||||
}
|
||||
|
||||
.code-shape {
|
||||
border-color: #dadada !important;
|
||||
color: #aaa !important;
|
||||
}
|
||||
|
||||
:deep(.jeecg-dark-switch) {
|
||||
position: absolute;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.aui-link-login {
|
||||
height: 42px;
|
||||
padding: 10px 15px;
|
||||
font-size: 14px;
|
||||
border-radius: 8px;
|
||||
margin-top: 15px;
|
||||
margin-bottom: 8px;
|
||||
flex: 1;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.aui-phone-logo {
|
||||
position: absolute;
|
||||
margin-left: 10px;
|
||||
width: 60px;
|
||||
top: 2px;
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.top-3 {
|
||||
top: 0.45rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="less">
|
||||
|
@ -486,9 +413,11 @@ html[data-theme='dark'] {
|
|||
&::before {
|
||||
background-image: url(/@/assets/svg/login-bg-dark.svg);
|
||||
}
|
||||
.aui-inputClear{
|
||||
|
||||
.aui-inputClear {
|
||||
background-color: #232a3b !important;
|
||||
}
|
||||
|
||||
.ant-input,
|
||||
.ant-input-password {
|
||||
background-color: #232a3b !important;
|
||||
|
@ -505,30 +434,39 @@ html[data-theme='dark'] {
|
|||
.app-iconify {
|
||||
color: #fff !important;
|
||||
}
|
||||
.aui-inputClear input,.aui-input-line input,.aui-choice{
|
||||
|
||||
.aui-inputClear input,
|
||||
.aui-input-line input,
|
||||
.aui-choice {
|
||||
color: #c9d1d9 !important;
|
||||
}
|
||||
|
||||
.aui-formBox{
|
||||
.aui-formBox {
|
||||
background-color: @dark-bg !important;
|
||||
}
|
||||
.aui-third-text span{
|
||||
|
||||
.aui-third-text span {
|
||||
background-color: @dark-bg !important;
|
||||
}
|
||||
.aui-form-nav .aui-flex-box{
|
||||
|
||||
.aui-form-nav .aui-flex-box {
|
||||
color: #c9d1d9 !important;
|
||||
}
|
||||
|
||||
.aui-formButton .aui-linek-code{
|
||||
background: @dark-bg !important;
|
||||
.aui-formButton .aui-linek-code {
|
||||
background: @dark-bg !important;
|
||||
color: white !important;
|
||||
}
|
||||
.aui-code-line{
|
||||
|
||||
.aui-code-line {
|
||||
border-left: none !important;
|
||||
}
|
||||
.ant-checkbox-inner,.aui-success h3{
|
||||
|
||||
.ant-checkbox-inner,
|
||||
.aui-success h3 {
|
||||
border-color: #c9d1d9;
|
||||
}
|
||||
|
||||
//update-begin---author:wangshuai ---date:20230828 for:【QQYUN-6363】这个样式代码有问题,不在里面,导致表达式有问题------------
|
||||
&-sign-in-way {
|
||||
.anticon {
|
||||
|
@ -541,6 +479,7 @@ html[data-theme='dark'] {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
//update-end---author:wangshuai ---date:20230828 for:【QQYUN-6363】这个样式代码有问题,不在里面,导致表达式有问题------------
|
||||
}
|
||||
|
||||
|
@ -549,12 +488,13 @@ html[data-theme='dark'] {
|
|||
-webkit-text-fill-color: #c9d1d9 !important;
|
||||
box-shadow: inherit !important;
|
||||
}
|
||||
|
||||
|
||||
.ant-divider-inner-text {
|
||||
font-size: 12px !important;
|
||||
color: @text-color-secondary !important;
|
||||
}
|
||||
.aui-third-login a{
|
||||
|
||||
.aui-third-login a {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue