'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 VITE_OPEN_CDN = false
# public path 配置线上环境路径(打包)、本地通过 http-server 访问时,请置空即可 # 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> # <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 ## 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", "name": "vue-next-admin-template",
"version": "2.4.32", "version": "2.4.33",
"description": "vue3 vite next admin template", "description": "vue3 vite next admin template",
"author": "lyt_20201208", "author": "lyt_20201208",
"license": "MIT", "license": "MIT",
@ -11,13 +11,13 @@
}, },
"dependencies": { "dependencies": {
"@element-plus/icons-vue": "^2.1.0", "@element-plus/icons-vue": "^2.1.0",
"axios": "^1.3.4", "axios": "^1.3.5",
"echarts": "^5.4.2", "echarts": "^5.4.2",
"element-plus": "^2.3.1", "element-plus": "^2.3.3",
"js-cookie": "^3.0.1", "js-cookie": "^3.0.1",
"mitt": "^3.0.0", "mitt": "^3.0.0",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"pinia": "^2.0.33", "pinia": "^2.0.34",
"qrcodejs2-fixes": "^0.0.2", "qrcodejs2-fixes": "^0.0.2",
"screenfull": "^6.0.2", "screenfull": "^6.0.2",
"sortablejs": "^1.15.0", "sortablejs": "^1.15.0",
@ -28,22 +28,22 @@
"vue-router": "^4.1.6" "vue-router": "^4.1.6"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^18.15.10", "@types/node": "^18.15.11",
"@types/nprogress": "^0.2.0", "@types/nprogress": "^0.2.0",
"@typescript-eslint/eslint-plugin": "^5.56.0", "@typescript-eslint/eslint-plugin": "^5.58.0",
"@typescript-eslint/parser": "^5.56.0", "@typescript-eslint/parser": "^5.58.0",
"@vitejs/plugin-vue": "^4.1.0", "@vitejs/plugin-vue": "^4.1.0",
"@vue/compiler-sfc": "^3.2.47", "@vue/compiler-sfc": "^3.2.47",
"eslint": "^8.36.0", "eslint": "^8.38.0",
"eslint-plugin-vue": "^9.10.0", "eslint-plugin-vue": "^9.10.0",
"prettier": "^2.8.7", "prettier": "^2.8.7",
"sass": "^1.60.0", "sass": "^1.61.0",
"typescript": "^5.0.2", "typescript": "^5.0.4",
"vite": "^4.2.1", "vite": "^4.2.1",
"vite-plugin-cdn-import": "^0.3.5", "vite-plugin-cdn-import": "^0.3.5",
"vite-plugin-compression": "^0.5.1", "vite-plugin-compression": "^0.5.1",
"vite-plugin-vue-setup-extend-plus": "^0.1.0", "vite-plugin-vue-setup-extend-plus": "^0.1.0",
"vue-eslint-parser": "^9.1.0" "vue-eslint-parser": "^9.1.1"
}, },
"browserslist": [ "browserslist": [
"> 1%", "> 1%",

View File

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

View File

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

View File

@ -126,15 +126,19 @@ const onColumnsAsideDown = (k: number) => {
setColumnsAsideMove(k); 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 = () => { const setFilterRoutes = () => {
state.columnsAsideList = filterRoutesFun(routesList.value); state.columnsAsideList = filterRoutesFun(routesList.value);
const resData: MittMenu = setSendChildren(route.path); const resData: MittMenu = setMenuAutoCollaps(route.path);
if (Object.keys(resData).length <= 0) return false;
onColumnsAsideDown(resData.item?.k); 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 // 500 aside.vue setSendColumnsChildren
setTimeout(() => { setTimeout(() => {
mittBus.emit('setSendColumnsChildren', resData); mittBus.emit('setSendColumnsChildren', resData);
@ -191,8 +195,9 @@ onUnmounted(() => {
}); });
// //
onBeforeRouteUpdate((to) => { onBeforeRouteUpdate((to) => {
const resData = setMenuAutoCollaps(to.path);
setColumnsMenuHighlight(to.path); setColumnsMenuHighlight(to.path);
mittBus.emit('setSendColumnsChildren', setSendChildren(to.path)); mittBus.emit('setSendColumnsChildren', resData);
}); });
// //
watch( watch(

View File

@ -11,7 +11,7 @@ import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig'; 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')); 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'; import mittBus from '/@/utils/mitt';
// //
const Breadcrumb = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/breadcrumb.vue')); const Breadcrumb = defineAsyncComponent(() => import('/@/layout/navBars/topBar/breadcrumb.vue'));
const User = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/user.vue')); const User = defineAsyncComponent(() => import('/@/layout/navBars/topBar/user.vue'));
const Logo = defineAsyncComponent(() => import('/@/layout/logo/index.vue')); const Logo = defineAsyncComponent(() => import('/@/layout/logo/index.vue'));
const Horizontal = defineAsyncComponent(() => import('/@/layout/navMenu/horizontal.vue')); const Horizontal = defineAsyncComponent(() => import('/@/layout/navMenu/horizontal.vue'));

View File

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

View File

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

View File

@ -32,7 +32,7 @@ export async function initFrontEndControlRoutes() {
// 添加动态路由 // 添加动态路由
await setAddRoute(); await setAddRoute();
// 设置递归过滤有权限的路由到 pinia routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组 // 设置递归过滤有权限的路由到 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(设置布局切换,重置主题样式)` * `initSetLayoutChange(设置布局切换,重置主题样式)`
*/ */
// 布局切换:可选值"<defaults|classic|transverse|columns>",默认 defaults // 布局切换:可选值"<defaults|classic|transverse|columns>",默认 defaults

View File

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

View File

@ -188,6 +188,18 @@
color: var(--next-bg-topBarColor); 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 标签页 /* Tabs 标签页
------------------------------- */ ------------------------------- */

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

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

View File

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

View File

@ -68,7 +68,6 @@
/* Advanced Options */ /* Advanced Options */
"skipLibCheck": true /* Skip type checking of declaration files. */, "skipLibCheck": true /* Skip type checking of declaration files. */,
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, "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 "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 "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]', assetFileNames: 'assets/[ext]/[name]-[hash].[ext]',
manualChunks(id) { manualChunks(id) {
if (id.includes('node_modules')) { 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 } } }, css: { preprocessorOptions: { css: { charset: false } } },