Просмотр исходного кода

😁前端与官方仓库同步升级v2.4.32

zuohuaijun 3 лет назад
Родитель
Сommit
e9f407e6dc

+ 3 - 0
Web/.env

@@ -4,5 +4,8 @@ VITE_PORT = 8888
 # open 运行 npm run dev 时自动打开浏览器
 VITE_OPEN = false
 
+# 打包是否开启 cdn(源文件 utils/build.ts),可自行修改
+VITE_OPEN_CDN = false
+
 # public path 配置线上环境路径(打包)、本地通过 http-server 访问时,请置空即可
 VITE_PUBLIC_PATH =

+ 14 - 0
Web/CHANGELOG.md

@@ -2,6 +2,20 @@
 
 🎉🎉🔥 `vue-next-admin` 基于 vue3.x 、Typescript、vite、Element plus 等,适配手机、平板、pc 的后台开源免费模板库(vue2.x 请切换 vue-prev-admin 分支)
 
+## 2.4.32
+
+💔💔💔 图片不显示问题(README.md、演示中使用的图片,[vue-next-admin-images](https://gitee.com/lyt-top/vue-next-admin-images)),通过网站 [https://www.hd-r.cn/](https://www.hd-r.cn/) 转在线链接,如若侵权请联系作者 qq:1105290566
+
+`2023.03.26`
+
+- 🌟 更新 依赖更新最新版本
+- 🐞 修复 [关于开发环境 sourceMap 的问题](https://gitee.com/lyt-top/vue-next-admin/issues/I6DNDQ),感谢[@XiaoSongJiang](https://gitee.com/XiaoSongJiang)
+- 🐞 修复 打包提示 `[@vue/compiler-sfc] ::v-deep usage as a combinator has been deprecated. Use :deep(<inner-selector>) instead.`,不能使用 `:deep {}`,而应使用 `:deep() {}`
+- 🎨 合并 [feat: 一级菜单重定向为空,分栏模式下,点击一次菜单时现在会切换子菜单列表,而不是打开空白页](https://gitee.com/lyt-top/vue-next-admin/commit/a91f84e3a1a86d8d303a5b46171622913d9d0737),感谢[@写意](https://gitee.com/xjj_0906)
+- 🎯 优化 经典布局分割菜单只有一项子级时,收起左侧导航菜单
+- 🎯 优化 watch 监听范围
+- 🎯 优化 打包:分包(manualChunks)、gzip 压缩、cdn 加速 `默认关闭 .env 中开启`(可查看文章[vue-next-admin vue3 + vite 打包 gzip 压缩、cdn 加速](https://blog.csdn.net/qq_34450741/article/details/129766676))
+
 ## 2.4.31
 
 `2023.03.10`

+ 10 - 3
Web/README.md

@@ -1,5 +1,5 @@
 <div align="center">
-	<img src="https://img-blog.csdnimg.cn/9efd5420327a46b7bd6d93524a97229d.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbHl0LXRvcA==,size_14,color_FFFFFF,t_70,g_se,x_16">
+	<img src="https://i.hd-r.cn/6ce52e5724fae609444b5b48bdc4accb.png">
 	<p align="center">
 		<a href="https://v3.vuejs.org/" target="_blank">
 			<img src="https://img.shields.io/badge/vue.js-vue3.x-green" alt="vue">
@@ -91,6 +91,7 @@ cnpm run build
 
 #### 💒 集成后端
 
+- <a target="_blank" href="https://gitee.com/zuohuaijun/Admin.NET">@zuohuaijun Admin.NET</a>
 - <a target="_blank" href="https://github.com/PandaGoAdmin/PandaX">@熊猫 PandaGoAdmin</a>
 - <a target="_blank" href="https://toscode.gitee.com/GionConnection/gopro_free">@甜蜜蜜 GoPro 平台</a>
 - <a target="_blank" href="https://gitee.com/GionConnection/niupi-free">@甜蜜蜜 NiuPi 平台</a>
@@ -111,7 +112,6 @@ cnpm run build
 - <a href="https://github.com/vuejs/pinia" target="_blank">pinia</a>
 - <a href="https://github.com/apache/echarts" target="_blank">echarts</a>
 - <a href="https://github.com/axios/axios" target="_blank">axios</a>
-- <a href="https://github.com/zenorocha/clipboard.js" target="_blank">clipboard</a>
 - <a href="https://github.com/inorganik/countUp.js" target="_blank">countUp</a>
 - <a href="https://github.com/developit/mitt" target="_blank">mitt</a>
 - <a href="https://github.com/rstacruz/nprogress" target="_blank">nprogress</a>
@@ -122,12 +122,19 @@ cnpm run build
 - <a href="https://github.com/vitejs/vite" target="_blank">vite</a>
 - <a href="https://github.com/wangeditor-team/wangEditor" target="_blank">wangeditor</a>
 - <a href="https://github.com/fengyuanchen/cropperjs" target="_blank">cropperjs</a>
-- <a href="https://github.com/davidshimjs/qrcodejs" target="_blank">qrcodejs</a>
 - <a href="https://github.com/crabbly/Print.js" target="_blank">print-js</a>
 - <a href="https://github.com/jbaysolutions/vue-grid-layout" target="_blank">vue-grid-layout</a>
 - <a href="https://github.com/antoniandre/splitpanes" target="_blank">splitpanes</a>
 - <a href="https://github.com/jsplumb/jsplumb" target="_blank">jsplumb</a>
 - <a href="https://github.com/hxj9102/table2excel" target="_blank">js-table2excel</a>
+- <a href="https://github.com/mmf-fe/vite-plugin-cdn-import" target="_blank">vite-plugin-cdn-import</a>
+- <a href="https://github.com/js-cookie/js-cookie" target="_blank">js-cookie</a>
+- <a href="https://github.com/davidshimjs/qrcodejs" target="_blank">qrcodejs2-fixes</a>
+- <a href="https://github.com/ljharb/qs" target="_blank">qs</a>
+- <a href="https://github.com/JamieCurnow/vue-clipboard3" target="_blank">vue-clipboard3</a>
+- <a href="https://github.com/intlify/vue-i18n-next" target="_blank">vue-i18n</a>
+- <a href="https://github.com/vbenjs/vite-plugin-compression" target="_blank">vite-plugin-compression</a>
+- <a href="https://github.com/chenxch/vite-plugin-vue-setup-extend-plus" target="_blank">vite-plugin-vue-setup-extend-plus</a>
 
 #### 💕 特别感谢
 

+ 19 - 16
Web/package.json

@@ -1,6 +1,6 @@
 {
 	"name": "vue-next-admin",
-	"version": "2.4.31",
+	"version": "2.4.32",
 	"description": "vue3 vite next admin template",
 	"author": "lyt_20201208",
 	"license": "MIT",
@@ -16,12 +16,12 @@
 		"@wangeditor/editor-for-vue": "^5.1.12",
 		"animate.css": "^4.1.1",
 		"axios": "^1.3.4",
-		"countup.js": "^2.5.0",
+		"countup.js": "^2.6.0",
 		"cropperjs": "^1.5.13",
-		"echarts": "^5.4.1",
+		"echarts": "^5.4.2",
 		"echarts-gl": "^2.0.9",
 		"echarts-wordcloud": "^2.1.0",
-		"element-plus": "^2.2.36",
+		"element-plus": "^2.3.1",
 		"js-cookie": "^3.0.1",
 		"js-table2excel": "^1.0.3",
 		"jsplumb": "^2.15.6",
@@ -39,6 +39,7 @@
 		"vform3-builds": "^3.0.8",
 		"vue": "^3.2.47",
 		"vue-clipboard3": "^2.0.0",
+		"vue-demi": "^0.13.11",
 		"vue-grid-layout": "^3.0.0-beta1",
 		"vue-i18n": "^9.2.2",
 		"vue-json-pretty": "^2.2.3",
@@ -49,20 +50,22 @@
 	},
 	"devDependencies": {
 		"@types/lodash-es": "^4.17.7",
-		"@types/node": "^18.15.0",
+		"@types/node": "^18.15.10",
 		"@types/nprogress": "^0.2.0",
-		"@types/sortablejs": "^1.15.0",
-		"@typescript-eslint/eslint-plugin": "^5.54.1",
-		"@typescript-eslint/parser": "^5.54.1",
-		"@vitejs/plugin-vue": "^4.0.0",
+		"@types/sortablejs": "^1.15.1",
+		"@typescript-eslint/eslint-plugin": "^5.56.0",
+		"@typescript-eslint/parser": "^5.56.0",
+		"@vitejs/plugin-vue": "^4.1.0",
 		"@vue/compiler-sfc": "^3.2.47",
-		"eslint": "^8.35.0",
-		"eslint-plugin-vue": "^9.9.0",
-		"prettier": "^2.8.4",
-		"sass": "^1.58.3",
-		"typescript": "^4.9.5",
-		"vite": "^4.1.4",
-		"vite-plugin-vue-setup-extend": "^0.4.0",
+		"eslint": "^8.36.0",
+		"eslint-plugin-vue": "^9.10.0",
+		"prettier": "^2.8.7",
+		"sass": "^1.60.0",
+		"typescript": "^5.0.2",
+		"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"
 	},
 	"browserslist": [

Разница между файлами не показана из-за своего большого размера
+ 346 - 478
Web/pnpm-lock.yaml


+ 9 - 15
Web/src/layout/component/aside.vue

@@ -12,7 +12,6 @@
 <script setup lang="ts" name="layoutAside">
 import { defineAsyncComponent, reactive, computed, watch, onBeforeMount, ref } from 'vue';
 import { storeToRefs } from 'pinia';
-import pinia from '/@/stores/index';
 import { useRoutesList } from '/@/stores/routesList';
 import { useThemeConfig } from '/@/stores/themeConfig';
 import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
@@ -56,8 +55,8 @@ const setCollapseStyle = computed(() => {
 			return [asideBrColor, 'layout-aside-mobile', 'layout-aside-mobile-close'];
 		}
 	} else {
-		if (layout === 'columns') {
-			// 分栏布局,菜单收起时宽度给 1px
+		if (layout === 'columns' || layout === 'classic') {
+			// 分栏布局、经典布局,菜单收起时宽度给 1px,防止切换动画消失
 			if (isCollapse) return [asideBrColor, 'layout-aside-pc-1'];
 			else return [asideBrColor, 'layout-aside-pc-220'];
 		} else {
@@ -123,6 +122,8 @@ onBeforeMount(() => {
 	mittBus.on('setSendClassicChildren', (res: MittMenu) => {
 		let { layout, isClassicSplitMenu } = themeConfig.value;
 		if (layout === 'classic' && isClassicSplitMenu) {
+			// 经典布局分割菜单只要一项子级时,收起左侧导航菜单
+			res.children.length <= 1 ? (themeConfig.value.isCollapse = true) : (themeConfig.value.isCollapse = false);
 			state.menuList = [];
 			state.menuList = res.children;
 		}
@@ -138,21 +139,14 @@ onBeforeMount(() => {
 	});
 });
 // 监听 themeConfig 配置文件的变化,更新菜单 el-scrollbar 的高度
-watch(themeConfig.value, (val) => {
-	if (val.isShowLogoChange !== val.isShowLogo) {
-		if (layoutAsideScrollbarRef.value) layoutAsideScrollbarRef.value.update();
-	}
-});
-// 监听 pinia 值的变化,动态赋值给菜单中
 watch(
-	pinia.state,
-	(val) => {
-		let { layout, isClassicSplitMenu } = val.themeConfig.themeConfig;
+	() => [themeConfig.value.isShowLogoChange, themeConfig.value.isShowLogo, themeConfig.value.layout, themeConfig.value.isClassicSplitMenu],
+	([isShowLogoChange, isShowLogo, layout, isClassicSplitMenu]) => {
+		if (isShowLogoChange !== isShowLogo) {
+			if (layoutAsideScrollbarRef.value) layoutAsideScrollbarRef.value.update();
+		}
 		if (layout === 'classic' && isClassicSplitMenu) return false;
 		setFilterRoutes();
-	},
-	{
-		deep: true,
 	}
 );
 </script>

+ 10 - 3
Web/src/layout/component/columnsAside.vue

@@ -19,14 +19,22 @@
 					<div :class="themeConfig.columnsAsideLayout" v-if="!v.meta.isLink || (v.meta.isLink && v.meta.isIframe)">
 						<SvgIcon :name="v.meta.icon" />
 						<div class="columns-vertical-title font12">
-							{{ $t(v.meta.title) && $t(v.meta.title).length >= 4 ? $t(v.meta.title).substr(0, themeConfig.columnsAsideLayout === 'columns-vertical' ? 4 : 3) : $t(v.meta.title) }}
+							{{
+								$t(v.meta.title) && $t(v.meta.title).length >= 4
+									? $t(v.meta.title).substr(0, themeConfig.columnsAsideLayout === 'columns-vertical' ? 4 : 3)
+									: $t(v.meta.title)
+							}}
 						</div>
 					</div>
 					<div :class="themeConfig.columnsAsideLayout" v-else>
 						<a :href="v.meta.isLink" target="_blank">
 							<SvgIcon :name="v.meta.icon" />
 							<div class="columns-vertical-title font12">
-								{{ $t(v.meta.title) && $t(v.meta.title).length >= 4 ? $t(v.meta.title).substr(0, themeConfig.columnsAsideLayout === 'columns-vertical' ? 4 : 3) : $t(v.meta.title) }}
+								{{
+									$t(v.meta.title) && $t(v.meta.title).length >= 4
+										? $t(v.meta.title).substr(0, themeConfig.columnsAsideLayout === 'columns-vertical' ? 4 : 3)
+										: $t(v.meta.title)
+								}}
 							</div>
 						</a>
 					</div>
@@ -44,7 +52,6 @@ import { storeToRefs } from 'pinia';
 import { useRoutesList } from '/@/stores/routesList';
 import { useThemeConfig } from '/@/stores/themeConfig';
 import mittBus from '/@/utils/mitt';
-import logoMini from '/@/assets/logo-mini.svg';
 
 // 定义变量内容
 const columnsAsideOffsetTopRefs = ref<RefType>([]);

+ 7 - 2
Web/src/layout/lockScreen/index.vue

@@ -32,7 +32,12 @@
 						</div>
 						<div class="layout-lock-screen-login-box-name">Administrator</div>
 						<div class="layout-lock-screen-login-box-value">
-							<el-input placeholder="请输入密码" ref="layoutLockScreenInputRef" v-model="state.lockScreenPassword" @keyup.enter.native.stop="onLockScreenSubmit()">
+							<el-input
+								placeholder="请输入密码"
+								ref="layoutLockScreenInputRef"
+								v-model="state.lockScreenPassword"
+								@keyup.enter.native.stop="onLockScreenSubmit()"
+							>
 								<template #append>
 									<el-button @click="onLockScreenSubmit">
 										<el-icon class="el-input__icon">
@@ -208,7 +213,7 @@ onUnmounted(() => {
 }
 .layout-lock-screen-img {
 	@extend .layout-lock-screen-fixed;
-	background-image: url('https://img-blog.csdnimg.cn/afa9c317667f47d5bea34b85af45979e.png#pic_center');
+	background-image: url('https://i.hd-r.cn/e4a19d84364f185266666765ac21a5db.jpg');
 	background-size: 100% 100%;
 	z-index: 9999991;
 }

+ 5 - 3
Web/src/layout/main/classic.vue

@@ -58,11 +58,13 @@ watch(
 		initScrollBarHeight();
 	}
 );
-// 监听 themeConfig 配置文件的变化,更新菜单 el-scrollbar 的高度
+// 监听 themeConfig  isTagsview 配置文件的变化,更新菜单 el-scrollbar 的高度
 watch(
-	themeConfig,
+	() => themeConfig.value.isTagsview,
 	() => {
-		updateScrollbar();
+		nextTick(() => {
+			updateScrollbar();
+		});
 	},
 	{
 		deep: true,

+ 5 - 3
Web/src/layout/main/columns.vue

@@ -43,7 +43,7 @@ const initScrollBarHeight = () => {
 		setTimeout(() => {
 			updateScrollbar();
 			layoutScrollbarRef.value.wrapRef.scrollTop = 0;
-			if (layoutMainRef.value != undefined) layoutMainRef.value.layoutMainScrollbarRef.wrapRef.scrollTop = 0;
+			layoutMainRef.value!.layoutMainScrollbarRef.wrapRef.scrollTop = 0;
 		}, 500);
 	});
 };
@@ -60,9 +60,11 @@ watch(
 );
 // 监听 themeConfig 配置文件的变化,更新菜单 el-scrollbar 的高度
 watch(
-	themeConfig,
+	() => [themeConfig.value.isTagsview, themeConfig.value.isFixedHeader],
 	() => {
-		updateScrollbar();
+		nextTick(() => {
+			updateScrollbar();
+		});
 	},
 	{
 		deep: true,

+ 4 - 2
Web/src/layout/main/defaults.vue

@@ -60,9 +60,11 @@ watch(
 );
 // 监听 themeConfig 配置文件的变化,更新菜单 el-scrollbar 的高度
 watch(
-	themeConfig,
+	() => [themeConfig.value.isTagsview, themeConfig.value.isFixedHeader],
 	() => {
-		updateScrollbar();
+		nextTick(() => {
+			updateScrollbar();
+		});
 	},
 	{
 		deep: true,

+ 4 - 2
Web/src/layout/main/transverse.vue

@@ -47,9 +47,11 @@ watch(
 );
 // 监听 themeConfig 配置文件的变化,更新菜单 el-scrollbar 的高度
 watch(
-	themeConfig,
+	() => themeConfig.value.isTagsview,
 	() => {
-		updateScrollbar();
+		nextTick(() => {
+			updateScrollbar();
+		});
 	},
 	{
 		deep: true,

+ 15 - 6
Web/src/layout/navBars/tagsView/tagsView.vue

@@ -21,7 +21,11 @@
 					<SvgIcon :name="v.meta.icon" v-if="!isActive(v) && getThemeConfig.isTagsviewIcon" class="pr5" />
 					<span>{{ setTagsViewNameI18n(v) }}</span>
 					<template v-if="isActive(v)">
-						<SvgIcon name="ele-RefreshRight" class="ml5 layout-navbars-tagsview-ul-li-refresh" @click.stop="refreshCurrentTagsView($route.fullPath)" />
+						<SvgIcon
+							name="ele-RefreshRight"
+							class="ml5 layout-navbars-tagsview-ul-li-refresh"
+							@click.stop="refreshCurrentTagsView($route.fullPath)"
+						/>
 						<SvgIcon
 							name="ele-Close"
 							class="layout-navbars-tagsview-ul-li-icon layout-icon-active"
@@ -48,7 +52,6 @@ import { useRoute, useRouter, onBeforeRouteUpdate } from 'vue-router';
 import Sortable from 'sortablejs';
 import { ElMessage } from 'element-plus';
 import { storeToRefs } from 'pinia';
-import pinia from '/@/stores/index';
 import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
 import { useThemeConfig } from '/@/stores/themeConfig';
 import { useKeepALiveNames } from '/@/stores/keepAliveNames';
@@ -150,7 +153,10 @@ const solveAddTagsView = async (path: string, to?: RouteToFrom) => {
 	let current = state.tagsViewList.filter(
 		(v: RouteItem) =>
 			v.path === isDynamicPath &&
-			isObjectValueEqual(to?.meta?.isDynamic ? (v.params ? v.params : null) : v.query ? v.query : null, to?.meta?.isDynamic ? (to?.params ? to?.params : null) : to?.query ? to?.query : null)
+			isObjectValueEqual(
+				to?.meta?.isDynamic ? (v.params ? v.params : null) : v.query ? v.query : null,
+				to?.meta?.isDynamic ? (to?.params ? to?.params : null) : to?.query ? to?.query : null
+			)
 	);
 	if (current.length <= 0) {
 		// 防止:Avoid app logic that relies on enumerating keys on a component instance. The keys will be empty in production mode to avoid performance overhead.
@@ -171,7 +177,10 @@ const singleAddTagsView = (path: string, to?: RouteToFrom) => {
 	state.tagsViewList.forEach((v) => {
 		if (
 			v.path === isDynamicPath &&
-			!isObjectValueEqual(to?.meta?.isDynamic ? (v.params ? v.params : null) : v.query ? v.query : null, to?.meta?.isDynamic ? (to?.params ? to?.params : null) : to?.query ? to?.query : null)
+			!isObjectValueEqual(
+				to?.meta?.isDynamic ? (v.params ? v.params : null) : v.query ? v.query : null,
+				to?.meta?.isDynamic ? (to?.params ? to?.params : null) : to?.query ? to?.query : null
+			)
 		) {
 			to?.meta?.isDynamic ? (v.params = to.params) : (v.query = to?.query);
 			v.url = setTagsViewHighlight(v);
@@ -576,9 +585,9 @@ onBeforeRouteUpdate(async (to) => {
 });
 // 监听路由的变化,动态赋值给 tagsView
 watch(
-	pinia.state,
+	() => tagsViewRoutes.value,
 	(val) => {
-		if (val.tagsViewRoutes.tagsViewRoutes.length === state.tagsViewRoutesList.length) return false;
+		if (val.length === state.tagsViewRoutesList.length) return false;
 		getTagsViewRoutes();
 	},
 	{

+ 11 - 4
Web/src/layout/navMenu/vertical.vue

@@ -1,5 +1,12 @@
 <template>
-	<el-menu router :default-active="state.defaultActive" background-color="transparent" :collapse="state.isCollapse" :unique-opened="getThemeConfig.isUniqueOpened" :collapse-transition="false">
+	<el-menu
+		router
+		:default-active="state.defaultActive"
+		background-color="transparent"
+		:collapse="state.isCollapse"
+		:unique-opened="getThemeConfig.isUniqueOpened"
+		:collapse-transition="false"
+	>
 		<template v-for="val in menuLists">
 			<el-sub-menu :index="val.path" v-if="val.children && val.children.length > 0" :key="val.path">
 				<template #title>
@@ -84,9 +91,9 @@ onBeforeRouteUpdate((to) => {
 });
 // 设置菜单的收起/展开
 watch(
-	themeConfig.value,
-	() => {
-		document.body.clientWidth <= 1000 ? (state.isCollapse = false) : (state.isCollapse = themeConfig.value.isCollapse);
+	() => themeConfig.value.isCollapse,
+	(isCollapse) => {
+		document.body.clientWidth <= 1000 ? (state.isCollapse = false) : (state.isCollapse = isCollapse);
 	},
 	{
 		immediate: true,

+ 3 - 2
Web/src/stores/userInfo.ts

@@ -54,6 +54,7 @@ export const useUserInfo = defineStore('userInfo', {
 							authBtnList: d.buttons,
 							time: new Date().getTime(),
 						};
+						Session.set('userInfo', userInfos);
 
 						// 读取用户配置
 						const configRes: any = await getAPI(SysAuthApi).apiSysAuthUserConfigGet();
@@ -62,14 +63,14 @@ export const useUserInfo = defineStore('userInfo', {
 						const configData = configRes.data.result;
 						const storesThemeConfig = useThemeConfig();
 
-						// storesThemeConfig.themeConfig.watermarkText = d.account;
+						// 是否设置水印
 						storesThemeConfig.themeConfig.isWatermark = configData.watermarkEnabled;
 						if (storesThemeConfig.themeConfig.isWatermark) Watermark.set(storesThemeConfig.themeConfig.watermarkText);
 						else Watermark.del();
 
 						Local.remove('themeConfig');
 						Local.set('themeConfig', storesThemeConfig.themeConfig);
-
+						
 						resolve(userInfos);
 					});
 			});

+ 2 - 0
Web/src/theme/app.scss

@@ -146,6 +146,8 @@ body,
 	.layout-aside-pc-1 {
 		width: 1px !important;
 		transition: width 0.3s ease;
+		position: relative;
+		left: -1px;
 	}
 	// 手机端左侧导航样式
 	.layout-aside-mobile {

+ 8 - 4
Web/src/theme/media/layout.scss

@@ -7,6 +7,10 @@
 	.el-message-box {
 		width: 80% !important;
 	}
+	// 锁屏页
+	.layout-lock-screen-date-top {
+		display: none;
+	}
 }
 
 /* 页面宽度小于768px
@@ -52,8 +56,8 @@
 			color: #666666;
 		}
 	}
-	// pagination 分页中的工具栏
-	//.table-footer-tool {
-	//	display: none !important;
-	//}
+	// // pagination 分页中的工具栏
+	// .table-footer-tool {
+	// 	display: none !important;
+	// }
 }

+ 125 - 0
Web/src/utils/build.ts

@@ -0,0 +1,125 @@
+import importToCDN from 'vite-plugin-cdn-import';
+
+/**
+ * 打包相关
+ * 注意 prodUrl:使用的是 jsdelivr 还是 unpkg。它们的 path 可能不一致
+ * 文章链接:https://blog.csdn.net/qq_34450741/article/details/129766676,使用的是 jsdelivr
+ * @description importToCDN https://github.com/mmf-fe/vite-plugin-cdn-import
+ * @description cdn 在线引入的 cdn 地址配置。path:https://www.jsdelivr.com/ || https://unpkg.com/
+ * @description external 打包时,过滤包导入。参考:https://rollupjs.org/configuration-options/#external
+ */
+export const buildConfig = {
+	cdn() {
+		return importToCDN({
+			prodUrl: 'https://unpkg.com/{name}@{version}/{path}',
+			modules: [
+				// autoComplete('vue'),
+				// autoComplete('axios'),
+				{
+					name: 'vue',
+					var: 'Vue',
+					path: 'dist/vue.global.js',
+				},
+				{
+					name: 'vue-demi',
+					var: 'VueDemi',
+					path: 'lib/index.iife.js',
+				},
+				{
+					name: 'vue-router',
+					var: 'VueRouter',
+					path: 'dist/vue-router.global.js',
+				},
+				{
+					name: 'element-plus',
+					var: 'ElementPlus',
+					path: 'dist/index.full.js',
+				},
+				// {
+				// 	name: '@element-plus/icons-vue',
+				// 	var: 'ElementPlusIconsVue',
+				// 	path: 'dist/index.iife.min.js',
+				// },
+				// {
+				// 	name: 'echarts',
+				// 	var: 'echarts',
+				// 	path: 'dist/echarts.min.js',
+				// },
+				// {
+				// 	name: 'echarts-gl',
+				// 	var: 'echarts-gl',
+				// 	path: 'dist/echarts-gl.min.js',
+				// },
+				// {
+				// 	name: 'echarts-wordcloud',
+				// 	var: 'echarts-wordcloud',
+				// 	path: 'dist/echarts-wordcloud.min.js',
+				// },
+				// {
+				// 	name: 'vue-i18n',
+				// 	var: 'VueI18n',
+				// 	path: 'dist/vue-i18n.global.min.js',
+				// },
+				// {
+				// 	name: 'jsplumb',
+				// 	var: 'jsPlumb',
+				// 	path: 'dist/js/jsplumb.min.js',
+				// },
+				// {
+				// 	name: 'cropperjs',
+				// 	var: 'Cropper',
+				// 	path: 'dist/cropper.min.js',
+				// },
+				// {
+				// 	name: 'sortablejs',
+				// 	var: 'Sortable',
+				// 	path: 'Sortable.min.js',
+				// },
+				// {
+				// 	name: 'qrcodejs2-fixes',
+				// 	var: 'QRCode',
+				// 	path: 'qrcode.min.js',
+				// },
+				// {
+				// 	name: 'print-js',
+				// 	var: 'printJS',
+				// 	path: 'dist/print.min.js',
+				// },
+				// {
+				// 	name: '@wangeditor/editor',
+				// 	var: 'wangEditor',
+				// 	path: 'dist/index.min.js',
+				// },
+				// {
+				// 	name: '@wangeditor/editor-for-vue',
+				// 	var: 'WangEditorForVue',
+				// 	path: 'dist/index.min.js',
+				// },
+				// {
+				// 	name: 'vue-grid-layout',
+				// 	var: 'VueGridLayout',
+				// 	path: 'https://cdn.jsdelivr.net/npm/vue-grid-layout@3.0.0-beta1/dist/vue-grid-layout.umd.min.js',
+				// },
+			],
+		});
+	},
+	external: [
+		'vue',
+		// 'axios',
+		'vue-router',
+		'element-plus',
+		// '@element-plus/icons-vue',
+		// 'echarts',
+		// 'echarts-gl',
+		// 'echarts-wordcloud',
+		// 'vue-i18n',
+		// 'jsplumb',
+		// 'cropperjs',
+		// 'sortablejs',
+		// 'qrcodejs2-fixes',
+		// 'print-js',
+		// '@wangeditor/editor',
+		// '@wangeditor/editor-for-vue',
+		// 'vue-grid-layout',
+	],
+};

+ 1 - 3
Web/src/views/error/401.vue

@@ -13,9 +13,7 @@
 					</div>
 				</div>
 				<div class="right">
-					<img
-						src="https://img-blog.csdnimg.cn/3333f265772a4fa89287993500ecbf96.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbHl0LXRvcA==,size_16,color_FFFFFF,t_70,g_se,x_16"
-					/>
+					<img src="https://i.hd-r.cn/2cf0d2e192660eec23eb9d0655753e7d.png" />
 				</div>
 			</div>
 		</div>

+ 1 - 3
Web/src/views/error/404.vue

@@ -13,9 +13,7 @@
 					</div>
 				</div>
 				<div class="right">
-					<img
-						src="https://img-blog.csdnimg.cn/9eb1d85a417f4ed1ba7107f149ce3da1.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbHl0LXRvcA==,size_16,color_FFFFFF,t_70,g_se,x_16"
-					/>
+					<img src="https://i.hd-r.cn/1a0d90a6c1e8b0184c7299dda713effd.png" />
 				</div>
 			</div>
 		</div>

+ 3 - 0
Web/src/views/pages/filtering/index.vue

@@ -226,6 +226,9 @@ const onHandleCurrentChange = (val: number) => {
 			flex-wrap: wrap;
 			align-content: flex-start;
 			margin: 0 -5px;
+			.el-row {
+				width: 101%;
+			}
 			.flex-warp-item {
 				padding: 5px;
 				width: 100%;

+ 7 - 2
Web/src/views/pages/tableRules/index.vue

@@ -2,7 +2,7 @@
 	<div class="layout-pd">
 		<el-card shadow="hover" header="表单表格验证">
 			<el-form ref="tableRulesRef" :model="state.tableData" size="default">
-				<el-table :data="state.tableData.data" border class="module-table-uncollected">
+				<el-table ref="tableRef" :data="state.tableData.data" border class="module-table-uncollected" max-height="200">
 					<el-table-column
 						v-for="(item, index) in state.tableData.header"
 						:key="index"
@@ -55,12 +55,13 @@
 </template>
 
 <script setup lang="ts" name="pagesTableRules">
-import { reactive, ref } from 'vue';
+import { reactive, ref, nextTick } from 'vue';
 import { ElMessage } from 'element-plus';
 import type { FormInstance } from 'element-plus';
 
 // 定义变量内容
 const tableRulesRef = ref<FormInstance>();
+const tableRef = ref();
 const state = reactive<TableRulesState>({
 	tableData: {
 		data: [],
@@ -103,5 +104,9 @@ const onAddRow = () => {
 		a7: '',
 		a8: '',
 	});
+	tableRef.value.doLayout();
+	nextTick(() => {
+		tableRef.value.setScrollTop(1000000);
+	});
 };
 </script>

+ 1 - 1
Web/src/views/pages/workflow/component/drawer/node.vue

@@ -222,7 +222,7 @@ defineExpose({
 
 <style scoped lang="scss">
 .workflow-drawer-node {
-	:deep {
+	:deep() {
 		.el-tabs {
 			box-shadow: unset;
 			border: unset;

+ 3 - 5
Web/src/views/visualizing/demo2.vue

@@ -235,8 +235,6 @@ import 'echarts-gl';
 import { formatDate } from '/@/utils/formatTime';
 import { NextLoading } from '/@/utils/loading';
 import { dropdownList, skyList, dBtnList, earth3DBtnList, chartData4List } from './mock/demo2';
-import worldImg from './images/world.jpg';
-import bathymetryImg from './images/bathymetry.jpg';
 
 // 定义变量内容
 const rightChartData1 = ref();
@@ -694,8 +692,8 @@ const init3DEarth = (globeRadius: any) => {
 	const myChart = echarts.init(el);
 	const option = {
 		globe: {
-			baseTexture: worldImg,
-			heightTexture: bathymetryImg,
+			baseTexture: 'https://i.hd-r.cn/4d572a171eb475da0c2e731d15b63aea.jpg',
+			heightTexture: 'https://i.hd-r.cn/52356e8d906c84c5e23390f829dec7a3.jpg',
 			shading: 'realistic',
 			light: {
 				ambient: {
@@ -790,7 +788,7 @@ onUnmounted(() => {
 	height: 100%;
 	width: 100%;
 	overflow: hidden;
-	background: url(https://img-blog.csdnimg.cn/6267533849444025811bf0840f9366e3.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbHl0LXRvcA==,size_20,color_FFFFFF,t_70,g_se,x_16);
+	background: url(https://i.hd-r.cn/b1040178e4a2265fe87ffbb9bda839a4.jpg);
 	background-size: 100% 100%;
 	display: flex;
 	flex-direction: column;

BIN
Web/src/views/visualizing/images/bathymetry.jpg


BIN
Web/src/views/visualizing/images/world.jpg


+ 14 - 11
Web/vite.config.ts

@@ -1,7 +1,9 @@
 import vue from '@vitejs/plugin-vue';
 import { resolve } from 'path';
 import { defineConfig, loadEnv, ConfigEnv } from 'vite';
-import vueSetupExtend from 'vite-plugin-vue-setup-extend';
+import vueSetupExtend from 'vite-plugin-vue-setup-extend-plus';
+import viteCompression from 'vite-plugin-compression';
+import { buildConfig } from './src/utils/build';
 
 const pathResolve = (dir: string) => {
 	return resolve(__dirname, '.', dir);
@@ -15,12 +17,13 @@ const alias: Record<string, string> = {
 const viteConfig = defineConfig((mode: ConfigEnv) => {
 	const env = loadEnv(mode.mode, process.cwd());
 	return {
-		plugins: [vue(), vueSetupExtend()],
+		plugins: [vue(), vueSetupExtend(), viteCompression(), JSON.parse(env.VITE_OPEN_CDN) ? buildConfig.cdn() : null],
 		root: process.cwd(),
 		resolve: { alias },
-		base: mode.command === 'serve' ? './' : env.VITE_PUBLIC_PATH,		
+		base: mode.command === 'serve' ? './' : env.VITE_PUBLIC_PATH,
 		optimizeDeps: {
 			include: ['element-plus/lib/locale/lang/zh-cn', 'element-plus/lib/locale/lang/en', 'element-plus/lib/locale/lang/zh-tw'],
+			exclude: ['vue-demi'],
 		},
 		server: {
 			host: '0.0.0.0',
@@ -41,16 +44,16 @@ const viteConfig = defineConfig((mode: ConfigEnv) => {
 			chunkSizeWarningLimit: 1500,
 			rollupOptions: {
 				output: {
-					entryFileNames: `assets/[name].[hash].js`,
-					chunkFileNames: `assets/[name].[hash].js`,
-					assetFileNames: `assets/[name].[hash].[ext]`,
-					compact: true,
-					manualChunks: {
-						vue: ['vue', 'vue-router', 'pinia'],
-						echarts: ['echarts'],
-						monacoEditor: ['monaco-editor'],
+					chunkFileNames: 'assets/js/[name]-[hash].js',
+					entryFileNames: 'assets/js/[name]-[hash].js',
+					assetFileNames: 'assets/[ext]/[name]-[hash].[ext]',
+					manualChunks(id) {
+						if (id.includes('node_modules')) {
+							return id.toString().match(/\/node_modules\/(?!.pnpm)(?<moduleName>[^\/]*)\//)?.groups.moduleName ?? 'vender';
+						}
 					},
 				},
+				...(JSON.parse(env.VITE_OPEN_CDN) ? {external:  buildConfig.external} : {}),
 			},
 		},
 		css: { preprocessorOptions: { css: { charset: false } } },

Некоторые файлы не были показаны из-за большого количества измененных файлов