浏览代码

!1918 修复图标垂直居中、对齐、大小等问题
Merge pull request !1918 from 夜鹰/v2

zuohuaijun 6 月之前
父节点
当前提交
73921146d4

+ 1 - 1
Admin.NET/Admin.NET.Core/Entity/SysLang.cs

@@ -19,7 +19,7 @@ public class SysLang : EntityBase
     public string Name { get; set; }
 
     /// <summary>
-    /// 语言代码(如 zh_CN)
+    /// 语言代码(如 zh-CN)
     /// </summary>
     [SugarColumn(ColumnDescription = "语言代码")]
     public string Code { get; set; }

+ 2 - 2
Admin.NET/Admin.NET.Core/Entity/SysUser.cs

@@ -314,10 +314,10 @@ public partial class SysUser : EntityBaseTenantOrg
     public string? Signature { get; set; }
 
     /// <summary>
-    /// 语言代码(如 zh_CN)
+    /// 语言代码(如 zh-CN)
     /// </summary>
     [SugarColumn(ColumnDescription = "语言代码")]
-    public string LangCode { get; set; } = "zh_CN";
+    public string LangCode { get; set; } = App.GetOptions<LocalizationSettingsOptions>().DefaultCulture;
 
     /// <summary>
     /// 验证超级管理员类型,若账号类型为超级管理员则报错

+ 5 - 5
Admin.NET/Admin.NET.Core/Service/LangText/SysLangTextCacheService.cs

@@ -50,12 +50,12 @@ public class SysLangTextCacheService : IDynamicApiController, ITransient
     /// 适用于:小表(如菜单、字典),可设置较长缓存时间。<br/>
     /// <br/>
     /// 【示例】<br/>
-    /// var content = await _sysLangTextCacheService.GetTranslation("Product", "Name", 123, "en_US");
+    /// var content = await _sysLangTextCacheService.GetTranslation("Product", "Name", 123, "en-US");
     /// </summary>
     /// <param name="entityName">实体名称,如 "Product"</param>
     /// <param name="fieldName">字段名称,如 "Name"</param>
     /// <param name="entityId">实体主键ID</param>
-    /// <param name="langCode">语言编码,如 "zh_CN"</param>
+    /// <param name="langCode">语言编码,如 "zh-CN"</param>
     /// <returns>翻译后的内容(若无则返回 null 或空)</returns>
     [NonAction]
     public async Task<string> GetTranslation(string entityName, string fieldName, long entityId, string langCode)
@@ -166,7 +166,7 @@ public class SysLangTextCacheService : IDynamicApiController, ITransient
     /// 按配置把同一字段的翻译写回到实体列表中。内部会调用批量翻译接口。<br/>
     /// <br/>
     /// 【示例】<br/>
-    /// await _sysLangTextCacheService.TranslateList(products, "Product", "Name", p =&gt; p.Id, (p, val) =&gt; p.Name = val, "zh_CN");
+    /// await _sysLangTextCacheService.TranslateList(products, "Product", "Name", p =&gt; p.Id, (p, val) =&gt; p.Name = val, "zh-CN");
     /// </summary>
     /// <typeparam name="TEntity">实体类型</typeparam>
     /// <param name="list">待翻译的实体列表</param>
@@ -219,13 +219,13 @@ public class SysLangTextCacheService : IDynamicApiController, ITransient
     ///         SetTranslatedValue = (p, val) =&gt; p.Description = val
     ///     }
     /// };
-    /// await _sysLangTextCacheService.TranslateMultiFields(products, fields, "zh_CN");
+    /// await _sysLangTextCacheService.TranslateMultiFields(products, fields, "zh-CN");
     /// </code>
     /// </summary>
     /// <typeparam name="TEntity">要翻译的实体类型,如 Product/Menu/SKU 等</typeparam>
     /// <param name="list">需要翻译的实体对象列表</param>
     /// <param name="fields">需要翻译的字段映射集合,支持多个字段</param>
-    /// <param name="langCode">语言编码,如 "zh_CN"、"en_US"、"it_IT" 等</param>
+    /// <param name="langCode">语言编码,如 "zh-CN"、"en-US"、"it-IT" 等</param>
     /// <returns>翻译后的实体列表(引用传递,原对象已直接赋值)</returns>
     [NonAction]
     public async Task<List<TEntity>> TranslateMultiFields<TEntity>(

+ 2 - 0
Web/src/components/iconSelector/list.vue

@@ -60,7 +60,9 @@ const onColClick = (v: unknown | string) => {
 		border-radius: 5px;
 		margin-bottom: 10px;
 		height: 30px;
+        width: 30px;
 		i {
+            display: inline-flex;
 			font-size: 20px;
 			color: var(--el-text-color-regular);
 		}

+ 1 - 1
Web/src/components/svgIcon/index.vue

@@ -20,7 +20,7 @@ const props = defineProps({
 	// svg 大小
 	size: {
 		type: Number,
-		default: () => 16,
+		//default: () => 16,
 	},
 	// svg 颜色
 	color: {

+ 2 - 2
Web/src/layout/component/columnsAside.vue

@@ -17,14 +17,14 @@
 					:title="v.meta.title"
 				>
 					<div :class="themeConfig.columnsAsideLayout" v-if="!v.meta.isLink || (v.meta.isLink && v.meta.isIframe)">
-						<SvgIcon :name="v.meta.icon" />
+						<SvgIcon size="16" :name="v.meta.icon" />
 						<div class="columns-vertical-title font12">
 							{{ v.meta.title && v.meta.title.length >= 4 ? v.meta.title.substr(0, themeConfig.columnsAsideLayout === 'columns-vertical' ? 4 : 3) : v.meta.title }}
 						</div>
 					</div>
 					<div :class="themeConfig.columnsAsideLayout" v-else>
 						<a :href="v.meta.isLink" target="_blank">
-							<SvgIcon :name="v.meta.icon" />
+							<SvgIcon size="16" :name="v.meta.icon" />
 							<div class="columns-vertical-title font12">
 								{{ v.meta.title && v.meta.title.length >= 4 ? v.meta.title.substr(0, themeConfig.columnsAsideLayout === 'columns-vertical' ? 4 : 3) : v.meta.title }}
 							</div>

+ 10 - 13
Web/src/layout/navBars/tagsView/tagsView.vue

@@ -18,24 +18,24 @@
 					"
 				>
 					<i class="iconfont icon-webicon318 layout-navbars-tagsview-ul-li-iconfont" v-if="isActive(v)"></i>
-					<SvgIcon :name="v.meta.icon" v-if="!isActive(v) && getThemeConfig.isTagsviewIcon" class="pr5" />
+					<SvgIcon :name="v.meta.icon" v-if="!isActive(v) && getThemeConfig.isTagsviewIcon" :size="14" class="mr5 el-icon" />
 					<span>{{ setTagsViewNameI18n(v) }}</span>
 					<template v-if="isActive(v)">
 						<SvgIcon
 							name="ele-RefreshRight"
-							class="ml5 layout-navbars-tagsview-ul-li-refresh"
+							class="ml5 layout-navbars-tagsview-ul-li-refresh el-icon"
 							@click.stop="refreshCurrentTagsView($route.fullPath)"
 						/>
 						<SvgIcon
 							name="ele-Close"
-							class="layout-navbars-tagsview-ul-li-icon layout-icon-active"
+							class="layout-navbars-tagsview-ul-li-icon layout-icon-active el-icon"
 							v-if="!v.meta.isAffix"
 							@click.stop="closeCurrentTagsView(getThemeConfig.isShareTagsView ? v.path : v.url)"
 						/>
 					</template>
 					<SvgIcon
 						name="ele-Close"
-						class="layout-navbars-tagsview-ul-li-icon layout-icon-three"
+						class="layout-navbars-tagsview-ul-li-icon layout-icon-three el-icon"
 						v-if="!v.meta.isAffix"
 						@click.stop="closeCurrentTagsView(getThemeConfig.isShareTagsView ? v.path : v.url)"
 					/>
@@ -154,8 +154,8 @@ const solveAddTagsView = async (path: string, to?: RouteToFrom) => {
 		(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
+				to?.meta?.isDynamic ? (v.params ? v.params : {}) : v.query ? v.query : {},
+				to?.meta?.isDynamic ? (to?.params ? to?.params : {}) : to?.query ? to?.query : {}
 			)
 	);
 	if (current.length <= 0) {
@@ -642,10 +642,7 @@ watch(
 			&-icon {
 				border-radius: 100%;
 				position: relative;
-				height: 14px;
-				width: 14px;
 				text-align: center;
-				line-height: 14px;
 				right: -5px;
 				&:hover {
 					color: var(--el-color-white);
@@ -692,12 +689,12 @@ watch(
 	.tags-style-five {
 		align-items: flex-end;
 		.tags-style-five-svg {
-			-webkit-mask-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNzAiIGhlaWdodD0iNzAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgZmlsbD0ibm9uZSI+CgogPGc+CiAgPHRpdGxlPkxheWVyIDE8L3RpdGxlPgogIDxwYXRoIHRyYW5zZm9ybT0icm90YXRlKC0wLjEzMzUwNiA1MC4xMTkyIDUwKSIgaWQ9InN2Z18xIiBkPSJtMTAwLjExOTE5LDEwMGMtNTUuMjI4LDAgLTEwMCwtNDQuNzcyIC0xMDAsLTEwMGwwLDEwMGwxMDAsMHoiIG9wYWNpdHk9InVuZGVmaW5lZCIgc3Ryb2tlPSJudWxsIiBmaWxsPSIjRjhFQUU3Ii8+CiAgPHBhdGggZD0ibS0wLjYzNzY2LDcuMzEyMjhjMC4xMTkxOSwwIDAuMjE3MzcsMC4wNTc5NiAwLjQ3Njc2LDAuMTE5MTljMC4yMzIsMC4wNTQ3NyAwLjI3MzI5LDAuMDM0OTEgMC4zNTc1NywwLjExOTE5YzAuMDg0MjgsMC4wODQyOCAwLjM1NzU3LDAgMC40NzY3NiwwbDAuMTE5MTksMGwwLjIzODM4LDAiIGlkPSJzdmdfMiIgc3Ryb2tlPSJudWxsIiBmaWxsPSJub25lIi8+CiAgPHBhdGggZD0ibTI4LjkyMTM0LDY5LjA1MjQ0YzAsMC4xMTkxOSAwLDAuMjM4MzggMCwwLjM1NzU3bDAsMC4xMTkxOWwwLDAuMTE5MTkiIGlkPSJzdmdfMyIgc3Ryb2tlPSJudWxsIiBmaWxsPSJub25lIi8+CiAgPHJlY3QgaWQ9InN2Z180IiBoZWlnaHQ9IjAiIHdpZHRoPSIxLjMxMTA4IiB5PSI2LjgzNTUyIiB4PSItMC4wNDE3MSIgc3Ryb2tlPSJudWxsIiBmaWxsPSJub25lIi8+CiAgPHJlY3QgaWQ9InN2Z181IiBoZWlnaHQ9IjEuNzg3ODQiIHdpZHRoPSIwLjExOTE5IiB5PSI2OC40NTY1IiB4PSIyOC45MjEzNCIgc3Ryb2tlPSJudWxsIiBmaWxsPSJub25lIi8+CiAgPHJlY3QgaWQ9InN2Z182IiBoZWlnaHQ9IjQuODg2NzciIHdpZHRoPSIxOS4wNzAzMiIgeT0iNTEuMjkzMjEiIHg9IjM2LjY2ODY2IiBzdHJva2U9Im51bGwiIGZpbGw9Im5vbmUiLz4KIDwvZz4KPC9zdmc+'),
+			mask-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNzAiIGhlaWdodD0iNzAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgZmlsbD0ibm9uZSI+CgogPGc+CiAgPHRpdGxlPkxheWVyIDE8L3RpdGxlPgogIDxwYXRoIHRyYW5zZm9ybT0icm90YXRlKC0wLjEzMzUwNiA1MC4xMTkyIDUwKSIgaWQ9InN2Z18xIiBkPSJtMTAwLjExOTE5LDEwMGMtNTUuMjI4LDAgLTEwMCwtNDQuNzcyIC0xMDAsLTEwMGwwLDEwMGwxMDAsMHoiIG9wYWNpdHk9InVuZGVmaW5lZCIgc3Ryb2tlPSJudWxsIiBmaWxsPSIjRjhFQUU3Ii8+CiAgPHBhdGggZD0ibS0wLjYzNzY2LDcuMzEyMjhjMC4xMTkxOSwwIDAuMjE3MzcsMC4wNTc5NiAwLjQ3Njc2LDAuMTE5MTljMC4yMzIsMC4wNTQ3NyAwLjI3MzI5LDAuMDM0OTEgMC4zNTc1NywwLjExOTE5YzAuMDg0MjgsMC4wODQyOCAwLjM1NzU3LDAgMC40NzY3NiwwbDAuMTE5MTksMGwwLjIzODM4LDAiIGlkPSJzdmdfMiIgc3Ryb2tlPSJudWxsIiBmaWxsPSJub25lIi8+CiAgPHBhdGggZD0ibTI4LjkyMTM0LDY5LjA1MjQ0YzAsMC4xMTkxOSAwLDAuMjM4MzggMCwwLjM1NzU3bDAsMC4xMTkxOWwwLDAuMTE5MTkiIGlkPSJzdmdfMyIgc3Ryb2tlPSJudWxsIiBmaWxsPSJub25lIi8+CiAgPHJlY3QgaWQ9InN2Z180IiBoZWlnaHQ9IjAiIHdpZHRoPSIxLjMxMTA4IiB5PSI2LjgzNTUyIiB4PSItMC4wNDE3MSIgc3Ryb2tlPSJudWxsIiBmaWxsPSJub25lIi8+CiAgPHJlY3QgaWQ9InN2Z181IiBoZWlnaHQ9IjEuNzg3ODQiIHdpZHRoPSIwLjExOTE5IiB5PSI2OC40NTY1IiB4PSIyOC45MjEzNCIgc3Ryb2tlPSJudWxsIiBmaWxsPSJub25lIi8+CiAgPHJlY3QgaWQ9InN2Z182IiBoZWlnaHQ9IjQuODg2NzciIHdpZHRoPSIxOS4wNzAzMiIgeT0iNTEuMjkzMjEiIHg9IjM2LjY2ODY2IiBzdHJva2U9Im51bGwiIGZpbGw9Im5vbmUiLz4KIDwvZz4KPC9zdmc+'),
 				url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNzAiIGhlaWdodD0iNzAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgZmlsbD0ibm9uZSI+CiA8Zz4KICA8dGl0bGU+TGF5ZXIgMTwvdGl0bGU+CiAgPHBhdGggdHJhbnNmb3JtPSJyb3RhdGUoLTg5Ljc2MjQgNy4zMzAxNCA1NS4xMjUyKSIgc3Ryb2tlPSJudWxsIiBpZD0ic3ZnXzEiIGZpbGw9IiNGOEVBRTciIGQ9Im02Mi41NzQ0OSwxMTcuNTIwODZjLTU1LjIyOCwwIC0xMDAsLTQ0Ljc3MiAtMTAwLC0xMDBsMCwxMDBsMTAwLDB6IiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPgogIDxwYXRoIGQ9Im0tMC42Mzc2Niw3LjMxMjI4YzAuMTE5MTksMCAwLjIxNzM3LDAuMDU3OTYgMC40NzY3NiwwLjExOTE5YzAuMjMyLDAuMDU0NzcgMC4yNzMyOSwwLjAzNDkxIDAuMzU3NTcsMC4xMTkxOWMwLjA4NDI4LDAuMDg0MjggMC4zNTc1NywwIDAuNDc2NzYsMGwwLjExOTE5LDBsMC4yMzgzOCwwIiBpZD0ic3ZnXzIiIHN0cm9rZT0ibnVsbCIgZmlsbD0ibm9uZSIvPgogIDxwYXRoIGQ9Im0yOC45MjEzNCw2OS4wNTI0NGMwLDAuMTE5MTkgMCwwLjIzODM4IDAsMC4zNTc1N2wwLDAuMTE5MTlsMCwwLjExOTE5IiBpZD0ic3ZnXzMiIHN0cm9rZT0ibnVsbCIgZmlsbD0ibm9uZSIvPgogIDxyZWN0IGlkPSJzdmdfNCIgaGVpZ2h0PSIwIiB3aWR0aD0iMS4zMTEwOCIgeT0iNi44MzU1MiIgeD0iLTAuMDQxNzEiIHN0cm9rZT0ibnVsbCIgZmlsbD0ibm9uZSIvPgogIDxyZWN0IGlkPSJzdmdfNSIgaGVpZ2h0PSIxLjc4Nzg0IiB3aWR0aD0iMC4xMTkxOSIgeT0iNjguNDU2NSIgeD0iMjguOTIxMzQiIHN0cm9rZT0ibnVsbCIgZmlsbD0ibm9uZSIvPgogIDxyZWN0IGlkPSJzdmdfNiIgaGVpZ2h0PSI0Ljg4Njc3IiB3aWR0aD0iMTkuMDcwMzIiIHk9IjUxLjI5MzIxIiB4PSIzNi42Njg2NiIgc3Ryb2tlPSJudWxsIiBmaWxsPSJub25lIi8+CiA8L2c+Cjwvc3ZnPg=='),
 				url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><rect rx='8' width='100%' height='100%' fill='%23F8EAE7'/></svg>");
-			-webkit-mask-size: 18px 30px, 20px 30px, calc(100% - 30px) calc(100% + 17px);
-			-webkit-mask-position: right bottom, left bottom, center top;
-			-webkit-mask-repeat: no-repeat;
+			mask-size: 18px 30px, 20px 30px, calc(100% - 30px) calc(100% + 17px);
+			mask-position: right bottom, left bottom, center top;
+			mask-repeat: no-repeat;
 		}
 		.layout-navbars-tagsview-ul-li {
 			padding: 0 5px;

+ 52 - 51
Web/src/layout/navBars/topBar/breadcrumb.vue

@@ -1,19 +1,28 @@
 <template>
-	<div v-if="isShowBreadcrumb" class="layout-navbars-breadcrumb">
-		<SvgIcon class="layout-navbars-breadcrumb-icon" :name="themeConfig.isCollapse ? 'ele-Expand' : 'ele-Fold'" :size="16" @click="onThemeConfigChange" />
-		<el-breadcrumb class="layout-navbars-breadcrumb-hide">
-			<transition-group name="breadcrumb">
-				<el-breadcrumb-item v-for="(v, k) in state.breadcrumbList" :key="v.path">
-					<span v-if="k === state.breadcrumbList.length - 1" class="layout-navbars-breadcrumb-span">
-						<SvgIcon :name="v.meta.icon" class="layout-navbars-breadcrumb-iconfont" v-if="themeConfig.isBreadcrumbIcon" />
-						<div v-if="v.meta.title">{{ v.meta.title }}</div>
-						<div v-else>{{ v.meta.tagsViewName }}</div>
-					</span>
-					<a v-else @click.prevent="onBreadcrumbClick(v)"> <SvgIcon :name="v.meta.icon" class="layout-navbars-breadcrumb-iconfont" v-if="themeConfig.isBreadcrumbIcon" />{{ v.meta.title }} </a>
-				</el-breadcrumb-item>
-			</transition-group>
-		</el-breadcrumb>
-	</div>
+    <div v-if="isShowBreadcrumb" class="bar-box">
+        <SvgIcon :size="16" class="bar-expand-icon" 
+            :name="themeConfig.isCollapse ? 'ele-Expand' : 'ele-Fold'" 
+            @click="onThemeConfigChange" 
+        />
+
+        <el-breadcrumb>
+            <transition-group name="breadcrumb">
+                <el-breadcrumb-item v-for="(v, k) in state.breadcrumbList" :key="v.path">
+                    <div v-if="k === state.breadcrumbList.length - 1" class="bar-breadcrumb-item bar-breadcrumb-item-last">
+                        <SvgIcon v-if="themeConfig.isBreadcrumbIcon" :name="v.meta.icon" />
+                        <span v-if="v.meta.title">{{ v.meta.title }}</span>
+                        <span v-else>{{ v.meta.tagsViewName }}</span>
+                    </div>
+                    <div v-else class="bar-breadcrumb-item">
+                        <a @click.prevent="onBreadcrumbClick(v)"> 
+                            <SvgIcon :name="v.meta.icon" v-if="themeConfig.isBreadcrumbIcon" />
+                            <span>{{ v.meta.title }}</span>
+                        </a>
+                    </div>
+                </el-breadcrumb-item>
+            </transition-group>
+        </el-breadcrumb>
+    </div>
 </template>
 
 <script setup lang="ts" name="layoutBreadcrumb">
@@ -99,42 +108,34 @@ onBeforeRouteUpdate((to) => {
 });
 </script>
 
-<style scoped lang="scss">
-.layout-navbars-breadcrumb {
-	flex: 1;
-	height: inherit;
-	display: flex;
-	align-items: center;
-	.layout-navbars-breadcrumb-icon {
-		cursor: pointer;
-		font-size: 18px;
-		color: var(--next-bg-topBarColor);
-		height: 100%;
-		width: 40px;
-		opacity: 0.8;
-		&:hover {
-			opacity: 1;
-		}
-	}
-	.layout-navbars-breadcrumb-span {
-		display: flex;
-		opacity: 0.7;
-		color: var(--next-bg-topBarColor);
-	}
-	.layout-navbars-breadcrumb-iconfont {
-		font-size: 14px;
-		margin-right: 5px;
-	}
-	:deep(.el-breadcrumb__separator) {
-		opacity: 0.7;
-		color: var(--next-bg-topBarColor);
-	}
-	:deep(.el-breadcrumb__inner a, .el-breadcrumb__inner.is-link) {
-		font-weight: unset !important;
-		color: var(--next-bg-topBarColor);
-		&:hover {
-			color: var(--el-color-primary) !important;
-		}
+<style lang="scss" scoped>
+.bar-box {
+    display: inline-flex;
+    align-items: center;
+    height: 100%;
+}
+
+.bar-expand-icon {
+    cursor: pointer;
+	font-size: 18px;
+	color: var(--next-bg-topBarColor);
+	height: 100%;
+	width: 40px;
+	opacity: 0.8;
+
+	&:hover {
+		opacity: 1;
 	}
 }
+.bar-breadcrumb-item {
+    height: 16px;
+    line-height: 16px;
+	display: flex;
+    align-items: center;
+
+    a { display: inherit; align-items: inherit; font-weight: unset; }
+    i { margin-right: 5px; }
+
+    &-last { opacity: 0.7; }
+}
 </style>

+ 1 - 1
Web/src/layout/navBars/topBar/search.vue

@@ -16,7 +16,7 @@
 						</el-icon>
 					</template>
 					<template #default="{ item }">
-						<div>
+						<div style="display: inline-flex; align-items: center;">
 							<SvgIcon :name="item.meta.icon" class="mr5" />
 							{{ item.meta.title }}
 						</div>

+ 3 - 3
Web/src/layout/navMenu/subItem.vue

@@ -2,7 +2,7 @@
 	<template v-for="val in chils">
 		<el-sub-menu :index="val.path" :key="val.path" v-if="val.children && val.children.length > 0">
 			<template #title>
-				<SvgIcon :name="val.meta.icon" style="font-size: 16px" />
+				<SvgIcon :name="val.meta.icon" class="el-icon" />
 				<span>{{ val.meta.title }}</span>
 			</template>
 			<sub-item :chil="val.children" />
@@ -10,12 +10,12 @@
 		<template v-else>
 			<el-menu-item :index="val.path" :key="val.path">
 				<template v-if="!val.meta.isLink || (val.meta.isLink && val.meta.isIframe)">
-					<SvgIcon :name="val.meta.icon" style="font-size: 16px" />
+					<SvgIcon :name="val.meta.icon" class="el-icon" />
 					<span>{{ val.meta.title }}</span>
 				</template>
 				<template v-else>
 					<a class="w100" @click.prevent="onALinkClick(val)">
-						<SvgIcon :name="val.meta.icon" style="font-size: 16px" />
+						<SvgIcon :name="val.meta.icon" class="el-icon" />
 						{{ val.meta.title }}
 					</a>
 				</template>

+ 2 - 2
Web/src/layout/navMenu/vertical.vue

@@ -10,14 +10,14 @@
 		<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>
-					<SvgIcon :name="val.meta.icon" />
+					<SvgIcon :name="val.meta.icon" class="el-icon" />
 					<span>{{ val.meta.title }}</span>
 				</template>
 				<SubItem :chil="val.children" />
 			</el-sub-menu>
 			<template v-else>
 				<el-menu-item :index="val.path" :key="val.path">
-					<SvgIcon :name="val.meta.icon" />
+					<SvgIcon :name="val.meta.icon" class="el-icon" />
 					<template #title v-if="!val.meta.isLink || (val.meta.isLink && val.meta.isIframe)">
 						<span>{{ val.meta.title }}</span>
 					</template>

+ 29 - 46
Web/src/theme/element.scss

@@ -10,21 +10,13 @@
         font-size: var(--el-font-size-medium);
     }
 }
-// 第三方字体图标大小
-// .el-button:not(.is-circle) i.el-icon,
-// .el-button i.iconfont,
-// .el-button i.fa,
-// .el-button--default i.iconfont,
-// .el-button--default i.fa {
-// 	font-size: 14px !important;
-// 	margin-right: 5px;
-// }
 
-// .el-button--small i.iconfont,
-// .el-button--small i.fa {
-// 	font-size: 12px !important;
-// 	margin-right: 5px;
-// }
+// 按钮使用第三方字体图标正确用法
+// <el-button>
+//     <SvgIcon name="iconfont icon-yunshangchuan_o" class="el-icon" />
+//     <span>笑笑</span>
+// </el-button>
+
 
 /* Input 输入框、InputNumber 计数器
 ------------------------------- */
@@ -113,14 +105,22 @@
 .el-menu {
 	border-right: none !important;
 	width: auto;
+
+    .el-icon {
+        font-size: var(--el-font-size-medium);
+    }
+
+    .el-sub-menu__icon-arrow {
+        margin-top: 0;
+        top: unset;
+    }
 }
 
 .el-menu-item,
 .el-sub-menu__title {
 	color: var(--next-bg-menuBarColor);
-	height: 45px !important;
-	line-height: 45px !important;
-	// margin: 0 0 1px 0;
+	height: 44px !important;
+	line-height: 44px !important;
 }
 
 // 修复点击左侧菜单折叠再展开时,宽度不跟随问题
@@ -142,7 +142,7 @@
 .el-sub-menu .iconfont,
 .el-menu-item .fa,
 .el-sub-menu .fa {
-	@include generalIcon;
+	@include generalIcon(var(--el-font-size-medium), var(--el-menu-icon-width));
 }
 
 // 水平菜单、横向菜单高亮 背景色,鼠标 hover 时,有子级菜单的背景色
@@ -450,11 +450,13 @@
     .el-button [class*=el-icon]+span{
         margin-left: 4px;
     }
+
+    .iconfont {
+        font-size: unset !important;
+    }
 }
 .el-table [class*=el-table__row--level] .el-table__expand-icon {
-    height: 14px;
-    line-height: 14px;
-    width: 14px;
+    vertical-align: middle;
 }
 
 $--el-table-text-color: #fb6d49;
@@ -509,11 +511,6 @@ $--el-table-text-color: #fb6d49;
 	max-height: 274px !important;
 }
 
-/*修复Cascader 级联选择器高度问题 -- Tips: 官方已修复该问题 */
-// .el-cascader-menu__wrap.el-scrollbar__wrap {
-// 	height: 204px !important;
-// }
-
 /*用于界面高度自适应(main.vue),区分 scrollbar__view,防止其它使用 scrollbar 的地方出现滚动条消失*/
 .layout-container-view .el-scrollbar__view {
 	height: 100%;
@@ -547,27 +544,12 @@ $--el-table-text-color: #fb6d49;
 	color: var(--el-color-danger) !important;
 }
 
-// 级联选择-点击文本也生效 -- Tips: 官方已支持,设置 el-cascader 的 checkOnClickNode=true 即可
-// .el-cascader-panel .el-radio {
-// 	width: 100%;
-// 	height: 100%;
-// 	z-index: 10;
-// 	position: absolute;
-// 	top: 0px;
-// 	right: -8px;
-// }
-
-// .el-cascader-panel .el-checkbox {
-// 	width: 100%;
-// 	height: 100%;
-// 	z-index: 10;
-// 	position: absolute;
-// 	top: 0px;
-// 	right: 0px;
-// }
-
 .el-tree {
     --el-tree-node-content-height: 30px;
+
+    .el-tree-node__content {
+        line-height: var(--el-tree-node-content-height);
+    }
 }
 
 // hack列表页
@@ -596,7 +578,8 @@ $--el-table-text-color: #fb6d49;
 			justify-content: space-between;
 
 			.el-card__body {
-				height: 100%;
+                flex: 1;
+				height: 0;
 				display: flex;
 				//padding: 5px 5px 0px 5px;
 				flex-direction: column;

+ 1 - 1
Web/src/theme/iconfont/font_2298093_rnp72ifj3ba.scss

@@ -6,7 +6,7 @@
 
 .iconfont {
 	font-family: 'iconfont' !important;
-	font-size: 16px;
+	font-size: inherit;
 	font-style: normal;
 	-webkit-font-smoothing: antialiased;
 	-moz-osx-font-smoothing: grayscale;

+ 3 - 4
Web/src/theme/mixins/index.scss

@@ -1,11 +1,10 @@
 /* 第三方图标字体间距/大小设置
 ------------------------------- */
-@mixin generalIcon {
-	font-size: 14px !important;
-	display: inline-block;
+@mixin generalIcon($fontSize: 16px, $width: 16px) {
+	font-size: $fontSize; 
 	vertical-align: middle;
 	margin-right: 5px;
-	width: 24px;
+	width: $width;
 	text-align: center;
 	justify-content: center;
 }

+ 1 - 1
Web/src/views/system/job/component/editJobDetail.vue

@@ -40,7 +40,7 @@
 										<div>
 											扫描触发器
 											<el-tooltip raw-content content="此参数只在新增作业时生效<br/>扫描定义在作业上的触发器" placement="top">
-												<SvgIcon name="fa fa-question-circle-o" :size="16" style="vertical-align: middle" />
+												<SvgIcon name="fa fa-question-circle-o" :size="15" style="vertical-align: middle" />
 											</el-tooltip>
 										</div>
 									</template>

+ 1 - 1
Web/src/views/system/job/component/editJobTrigger.vue

@@ -103,7 +103,7 @@
 								<div>
 									重置触发次数
 									<el-tooltip raw-content content="是否在启动时重置最大触发次数等于一次的作业<br/>解决因持久化数据已完成一次触发但启动时不再执行的问题" placement="top">
-										<SvgIcon name="fa fa-question-circle-o" :size="16" style="vertical-align: middle" />
+										<SvgIcon name="fa fa-question-circle-o" :size="15" style="vertical-align: middle" />
 									</el-tooltip>
 								</div>
 							</template>

+ 24 - 3
Web/src/views/system/menu/index.vue

@@ -32,10 +32,12 @@
 		<el-card class="full-table" shadow="hover" style="margin-top: 5px">
 			<el-table :data="state.menuData" v-loading="state.loading" row-key="id"
 				:tree-props="{ children: 'children', hasChildren: 'hasChildren' }" border>
-				<el-table-column label="菜单名称" header-align="center" show-overflow-tooltip>
+				<el-table-column label="菜单名称" header-align="center">
 					<template #default="scope">
-						<SvgIcon :name="scope.row.icon" />
-						<span class="ml10">{{ scope.row.title }}</span>
+                        <div class="menu-icon-box">
+                            <span class="vertical-center"><SvgIcon :name="scope.row.icon" class="el-icon" /></span>
+                            <span class="ml10 vertical-center">{{ scope.row.title }}</span>
+                        </div>
 					</template>
 				</el-table-column>
 				<el-table-column label="类型" width="70" align="center" show-overflow-tooltip>
@@ -184,3 +186,22 @@ const changeStatus = async (row: any) => {
 		});
 };
 </script>
+
+<style lang="scss" scoped>
+.el-table .cell.el-tooltip {
+    display: inline-flex;
+    align-items: center;
+}
+.menu-icon-box {
+    display: inline-block;
+
+    .vertical-center { 
+        display: inline-flex;
+        align-items: center;
+        vertical-align: middle;
+        line-height: 1em;
+        height: 1em;
+    }
+    //.el-icon { vertical-align: middle; }
+}
+</style>

+ 40 - 25
Web/src/views/system/user/component/editUser.vue

@@ -97,36 +97,31 @@
 								<div style="color: #b1b3b8">附属机构</div>
 							</el-divider>
 							<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
-								<el-button icon="ele-Plus" type="primary" plain @click="addExtOrgRow"> 增加附属机构 </el-button>
+								<el-button icon="ele-Plus" type="primary" text plain @click="addExtOrgRow"> 增加附属机构 </el-button>
 								<span style="font-size: 12px; color: gray; padding-left: 5px"> 具有相应组织机构的数据权限 </span>
 							</el-col>
-							<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
+							<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="unique-box">
 								<template v-if="state.ruleForm.extOrgIdList != undefined && state.ruleForm.extOrgIdList.length > 0">
-									<el-row :gutter="35" v-for="(v, k) in state.ruleForm.extOrgIdList" :key="k">
-										<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
-											<el-form-item label="机构" :prop="`extOrgIdList[${k}].orgId`" :rules="[{ required: true, message: `机构不能为空`, trigger: 'blur' }]">
-												<template #label>
-													<el-button icon="ele-Delete" type="danger" circle plain size="small" @click="deleteExtOrgRow(k)" />
-													<span class="ml5">机构</span>
+                                    <div v-for="(v, k) in state.ruleForm.extOrgIdList" :key="k" class="unique-line">
+                                        <el-form-item label="机构" label-width="55" :prop="`extOrgIdList[${k}].orgId`" :rules="[{ required: true, message: `机构不能为空`, trigger: 'blur' }]">
+											<el-cascader :options="props.orgTreeData" :props="cascaderProps" placeholder="机构组织" clearable filterable class="w100" v-model="state.ruleForm.extOrgIdList[k].orgId">
+												<template #default="{ node, data }">
+													<span>{{ data.name }}</span>
+													<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
 												</template>
-												<el-cascader :options="props.orgTreeData" :props="cascaderProps" placeholder="机构组织" clearable filterable class="w100" v-model="state.ruleForm.extOrgIdList[k].orgId">
-													<template #default="{ node, data }">
-														<span>{{ data.name }}</span>
-														<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
-													</template>
-												</el-cascader>
-											</el-form-item>
-										</el-col>
-										<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
-											<el-form-item label="职位" :prop="`extOrgIdList[${k}].posId`" :rules="[{ required: true, message: `职位不能为空`, trigger: 'blur' }]">
-												<el-select v-model="state.ruleForm.extOrgIdList[k].posId" placeholder="职位名称" class="w100">
-													<el-option v-for="d in state.posData" :key="d.id" :label="d.name" :value="d.id" />
-												</el-select>
-											</el-form-item>
-										</el-col>
-									</el-row>
+											</el-cascader>
+										</el-form-item>
+                                        <el-form-item label="职位" label-width="55" :prop="`extOrgIdList[${k}].posId`" :rules="[{ required: true, message: `职位不能为空`, trigger: 'blur' }]">
+											<el-select v-model="state.ruleForm.extOrgIdList[k].posId" placeholder="职位名称" class="w100">
+												<el-option v-for="d in state.posData" :key="d.id" :label="d.name" :value="d.id" />
+											</el-select>
+										</el-form-item>
+                                        <div class="delete-btn">
+                                            <el-button icon="ele-Delete" type="danger" circle plain size="small" @click="deleteExtOrgRow(k)" />
+                                        </div>
+                                    </div>
 								</template>
-								<el-empty :image-size="50" description="空数据" style="padding: 0px;" v-else></el-empty>
+								<el-empty :image-size="50" style="padding: 0px;" v-else></el-empty>
 							</el-col>
 						</el-row>
 					</el-form>
@@ -343,5 +338,25 @@ defineExpose({ openDialog });
 
         --el-transfer-panel-body-height: calc(100% - 40px);
     }
+
+    .unique-box {
+        display: grid;
+        gap: 20px;
+    }
+    .unique-line {
+        display: flex;
+        gap: 20px;
+        
+        .el-form-item {
+            margin-bottom: 0;
+            flex: 1;
+        }
+
+        .delete-btn {
+            align-self: center;
+            width: 24px;
+            margin-left: -10px;
+        }
+    }
 }
 </style>