'admin-23.04.12:同步master分支v2.4.33版本内容'

This commit is contained in:
lyt 2023-04-12 11:51:49 +08:00
parent 1d11c00f91
commit 999429ce13
24 changed files with 526 additions and 475 deletions

2
.env
View File

@ -8,4 +8,4 @@ VITE_OPEN = false
VITE_OPEN_CDN = false
# public path 配置线上环境路径(打包)、本地通过 http-server 访问时,请置空即可
VITE_PUBLIC_PATH = /vue-next-admin-preview/
VITE_PUBLIC_PATH =

View File

@ -1,6 +1,12 @@
# <a href="https://gitee.com/lyt-top/vue-next-admin" target="_blank">vue-next-admin-template不带国际化 更新日志</a>
🎉🎉🔥 `vue-next-admin-template` 基于 vue-next-admin-v2.4.32 版本) vue3.x 、Typescript、vite、Element plus 等适配手机、平板、pc 的后台开源免费模板库vue2.x 请切换 vue-prev-admin 分支)
🎉🎉🔥 `vue-next-admin-template` 基于 vue-next-admin-v2.4.33 版本) vue3.x 、Typescript、vite、Element plus 等适配手机、平板、pc 的后台开源免费模板库vue2.x 请切换 vue-prev-admin 分支)
## 2.4.33
`2023.04.12`
- 🎉 同步 master 分支 v2.4.33 版本内容,具体查看 [master CHANGELOG.md](https://gitee.com/lyt-top/vue-next-admin/blob/master/CHANGELOG.md)
## 2.4.32

843
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "vue-next-admin-template",
"version": "2.4.32",
"version": "2.4.33",
"description": "vue3 vite next admin template",
"author": "lyt_20201208",
"license": "MIT",
@ -11,13 +11,13 @@
},
"dependencies": {
"@element-plus/icons-vue": "^2.1.0",
"axios": "^1.3.4",
"axios": "^1.3.5",
"echarts": "^5.4.2",
"element-plus": "^2.3.1",
"element-plus": "^2.3.3",
"js-cookie": "^3.0.1",
"mitt": "^3.0.0",
"nprogress": "^0.2.0",
"pinia": "^2.0.33",
"pinia": "^2.0.34",
"qrcodejs2-fixes": "^0.0.2",
"screenfull": "^6.0.2",
"sortablejs": "^1.15.0",
@ -28,22 +28,22 @@
"vue-router": "^4.1.6"
},
"devDependencies": {
"@types/node": "^18.15.10",
"@types/node": "^18.15.11",
"@types/nprogress": "^0.2.0",
"@typescript-eslint/eslint-plugin": "^5.56.0",
"@typescript-eslint/parser": "^5.56.0",
"@typescript-eslint/eslint-plugin": "^5.58.0",
"@typescript-eslint/parser": "^5.58.0",
"@vitejs/plugin-vue": "^4.1.0",
"@vue/compiler-sfc": "^3.2.47",
"eslint": "^8.36.0",
"eslint": "^8.38.0",
"eslint-plugin-vue": "^9.10.0",
"prettier": "^2.8.7",
"sass": "^1.60.0",
"typescript": "^5.0.2",
"sass": "^1.61.0",
"typescript": "^5.0.4",
"vite": "^4.2.1",
"vite-plugin-cdn-import": "^0.3.5",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-vue-setup-extend-plus": "^0.1.0",
"vue-eslint-parser": "^9.1.0"
"vue-eslint-parser": "^9.1.1"
},
"browserslist": [
"> 1%",

View File

@ -23,8 +23,8 @@ import setIntroduction from '/@/utils/setIconfont';
//
const LockScreen = defineAsyncComponent(() => import('/@/layout/lockScreen/index.vue'));
const Setings = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/setings.vue'));
const CloseFull = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/closeFull.vue'));
const Setings = defineAsyncComponent(() => import('/@/layout/navBars/topBar/setings.vue'));
const CloseFull = defineAsyncComponent(() => import('/@/layout/navBars/topBar/closeFull.vue'));
const Upgrade = defineAsyncComponent(() => import('/@/layout/upgrade/index.vue'));
const Sponsors = defineAsyncComponent(() => import('/@/layout/sponsors/index.vue'));

View File

@ -152,4 +152,11 @@ watch(
deep: true,
}
);
// ` -> -> `
watch(
() => routesList.value,
() => {
setFilterRoutes();
}
);
</script>

View File

@ -126,15 +126,19 @@ const onColumnsAsideDown = (k: number) => {
setColumnsAsideMove(k);
});
};
//
// https://gitee.com/lyt-top/vue-next-admin/issues/I6UW2I
const setMenuAutoCollaps = (path: string) => {
const resData: MittMenu = setSendChildren(path);
// https://gitee.com/lyt-top/vue-next-admin/issues/I6HW7H
resData.children.length <= 1 ? (themeConfig.value.isCollapse = true) : (themeConfig.value.isCollapse = false);
return resData;
};
// //
const setFilterRoutes = () => {
state.columnsAsideList = filterRoutesFun(routesList.value);
const resData: MittMenu = setSendChildren(route.path);
if (Object.keys(resData).length <= 0) return false;
const resData: MittMenu = setMenuAutoCollaps(route.path);
onColumnsAsideDown(resData.item?.k);
//
// https://gitee.com/lyt-top/vue-next-admin/issues/I6HW7H
resData.children.length <= 1 ? (themeConfig.value.isCollapse = true) : (themeConfig.value.isCollapse = false);
// 500 aside.vue setSendColumnsChildren
setTimeout(() => {
mittBus.emit('setSendColumnsChildren', resData);
@ -191,8 +195,9 @@ onUnmounted(() => {
});
//
onBeforeRouteUpdate((to) => {
const resData = setMenuAutoCollaps(to.path);
setColumnsMenuHighlight(to.path);
mittBus.emit('setSendColumnsChildren', setSendChildren(to.path));
mittBus.emit('setSendColumnsChildren', resData);
});
//
watch(

View File

@ -11,7 +11,7 @@ import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig';
//
const BreadcrumbIndex = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/index.vue'));
const BreadcrumbIndex = defineAsyncComponent(() => import('/@/layout/navBars/topBar/index.vue'));
const TagsView = defineAsyncComponent(() => import('/@/layout/navBars/tagsView/tagsView.vue'));
//

View File

@ -16,8 +16,8 @@ import { useThemeConfig } from '/@/stores/themeConfig';
import mittBus from '/@/utils/mitt';
//
const Breadcrumb = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/breadcrumb.vue'));
const User = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/user.vue'));
const Breadcrumb = defineAsyncComponent(() => import('/@/layout/navBars/topBar/breadcrumb.vue'));
const User = defineAsyncComponent(() => import('/@/layout/navBars/topBar/user.vue'));
const Logo = defineAsyncComponent(() => import('/@/layout/logo/index.vue'));
const Horizontal = defineAsyncComponent(() => import('/@/layout/navMenu/horizontal.vue'));

View File

@ -20,20 +20,25 @@
<div class="layout-navbars-breadcrumb-user-icon" @click="onLayoutSetingClick">
<i class="icon-skin iconfont" title="布局配置"></i>
</div>
<div class="layout-navbars-breadcrumb-user-icon">
<el-popover placement="bottom" trigger="click" transition="el-zoom-in-top" :width="300" :persistent="false">
<template #reference>
<el-badge :is-dot="true">
<el-icon title="消息">
<ele-Bell />
</el-icon>
</el-badge>
</template>
<template #default>
<UserNews />
</template>
</el-popover>
<div class="layout-navbars-breadcrumb-user-icon" ref="userNewsBadgeRef" v-click-outside="onUserNewsClick">
<el-badge :is-dot="true">
<el-icon title="消息">
<ele-Bell />
</el-icon>
</el-badge>
</div>
<el-popover
ref="userNewsRef"
:virtual-ref="userNewsBadgeRef"
placement="bottom"
trigger="click"
transition="el-zoom-in-top"
virtual-triggering
:width="300"
:persistent="false"
>
<UserNews />
</el-popover>
<div class="layout-navbars-breadcrumb-user-icon mr10" @click="onScreenfullClick">
<i
class="iconfont"
@ -64,9 +69,9 @@
</template>
<script setup lang="ts" name="layoutBreadcrumbUser">
import { defineAsyncComponent, ref, computed, reactive, onMounted } from 'vue';
import { defineAsyncComponent, ref, unref, computed, reactive, onMounted } from 'vue';
import { useRouter } from 'vue-router';
import { ElMessageBox, ElMessage } from 'element-plus';
import { ElMessageBox, ElMessage, ClickOutside as vClickOutside } from 'element-plus';
import screenfull from 'screenfull';
import { storeToRefs } from 'pinia';
import { useUserInfo } from '/@/stores/userInfo';
@ -75,10 +80,12 @@ import mittBus from '/@/utils/mitt';
import { Session, Local } from '/@/utils/storage';
//
const UserNews = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/userNews.vue'));
const Search = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/search.vue'));
const UserNews = defineAsyncComponent(() => import('/@/layout/navBars/topBar/userNews.vue'));
const Search = defineAsyncComponent(() => import('/@/layout/navBars/topBar/search.vue'));
//
const userNewsRef = ref();
const userNewsBadgeRef = ref();
const router = useRouter();
const stores = useUserInfo();
const storesThemeConfig = useThemeConfig();
@ -111,6 +118,10 @@ const onScreenfullClick = () => {
else state.isScreenfull = false;
});
};
//
const onUserNewsClick = () => {
unref(userNewsRef).popperRef?.delayHide?.();
};
// icon
const onLayoutSetingClick = () => {
mittBus.emit('openSetingsDrawer');
@ -169,7 +180,7 @@ const onComponentSizeChange = (size: string) => {
};
// /i18n
const initI18nOrSize = (value: string, attr: string) => {
state[attr] = Local.get('themeConfig')[value];
(<any>state)[attr] = Local.get('themeConfig')[value];
};
//
onMounted(() => {

View File

@ -53,7 +53,7 @@ export async function initBackEndControlRoutes() {
// 添加动态路由
await setAddRoute();
// 设置路由到 pinia routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
await setFilterMenuAndCacheTagsViewRoutes();
setFilterMenuAndCacheTagsViewRoutes();
}
/**

View File

@ -32,7 +32,7 @@ export async function initFrontEndControlRoutes() {
// 添加动态路由
await setAddRoute();
// 设置递归过滤有权限的路由到 pinia routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
await setFilterMenuAndCacheTagsViewRoutes();
setFilterMenuAndCacheTagsViewRoutes();
}
/**

View File

@ -121,7 +121,7 @@ export const useThemeConfig = defineStore('themeConfig', {
/**
*
* /@/layout/navBars/breadcrumb/setings.vue
* /@/layout/navBars/topBar/setings.vue
* `initSetLayoutChange(设置布局切换,重置主题样式)`
*/
// 布局切换:可选值"<defaults|classic|transverse|columns>",默认 defaults

View File

@ -22,7 +22,7 @@ export const useUserInfo = defineStore('userInfo', {
if (Session.get('userInfo')) {
this.userInfos = Session.get('userInfo');
} else {
const userInfos: any = await this.getApiUserInfo();
const userInfos = <UserInfos>await this.getApiUserInfo();
this.userInfos = userInfos;
}
},

View File

@ -188,6 +188,18 @@
color: var(--next-bg-topBarColor);
}
}
// 菜单收起时图标不居中问题
.el-menu--collapse {
.el-menu-item .iconfont,
.el-sub-menu .iconfont,
.el-menu-item .fa,
.el-sub-menu .fa {
margin-right: 0 !important;
}
.el-sub-menu__title {
padding-right: 0 !important;
}
}
/* Tabs 标签页
------------------------------- */

19
src/types/pinia.d.ts vendored
View File

@ -3,15 +3,16 @@
*/
// 用户信息
declare interface UserInfosState<T = any> {
userInfos: {
authBtnList: string[];
photo: string;
roles: string[];
time: number;
userName: string;
[key: string]: T;
};
declare interface UserInfos<T = any> {
authBtnList: string[];
photo: string;
roles: string[];
time: number;
userName: string;
[key: string]: T;
}
declare interface UserInfosState {
userInfos: UserInfos;
}
// 路由缓存列表

View File

@ -325,5 +325,6 @@ declare type TableDemoState = {
};
search: TableSearchType[];
param: EmptyObjectType;
printName: string;
};
};

View File

@ -68,7 +68,6 @@
/* Advanced Options */
"skipLibCheck": true /* Skip type checking of declaration files. */,
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */,
"suppressImplicitAnyIndexErrors": true
},
"include": ["src/**/*.ts", "src/**/*.vue", "src/**/*.tsx", "src/**/*.d.ts"], // **Represents any directory, and * represents any file. Indicates that all files in the src directory will be compiled
"exclude": ["node_modules", "dist"] // Indicates the file directory that does not need to be compiled

View File

@ -47,11 +47,11 @@ const viteConfig = defineConfig((mode: ConfigEnv) => {
assetFileNames: 'assets/[ext]/[name]-[hash].[ext]',
manualChunks(id) {
if (id.includes('node_modules')) {
return id.toString().split('node_modules/')[1].split('/')[0].toString();
return id.toString().match(/\/node_modules\/(?!.pnpm)(?<moduleName>[^\/]*)\//)?.groups!.moduleName ?? 'vender';
}
},
},
external: JSON.parse(env.VITE_OPEN_CDN) ? buildConfig.external : [],
...(JSON.parse(env.VITE_OPEN_CDN) ? { external: buildConfig.external } : {}),
},
},
css: { preprocessorOptions: { css: { charset: false } } },