From 801a31dfbafe6a1e2b8513aa2b14981b02b634f1 Mon Sep 17 00:00:00 2001 From: zuohuaijun Date: Tue, 23 Sep 2025 13:21:02 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=98=8E1=E3=80=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E6=9D=A1=E4=BB=B6=E5=BF=85=E5=A1=AB=E5=8F=82=E6=95=B0=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E7=89=B9=E6=80=A7=20=202=E3=80=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E5=AD=97=E5=85=B8=E5=92=8C=E4=B8=8B=E6=8B=89=E6=A1=86=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=203=E3=80=81=E4=BC=98=E5=8C=96=E8=BF=9C=E7=A8=8B?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Attribute/RequiredIFAttribute.cs | 53 ++++++++++++++++--- Admin.NET/Admin.NET.sln | 4 +- .../Admin.NET.Plugin.ReZero.csproj | 2 +- Web/package.json | 12 ++--- .../components/selector/pulldownSelecter.vue | 23 ++++---- Web/src/components/sysDict/sysDict.vue | 5 ++ .../log/loghttp/component/logDetail.vue | 11 +++- 7 files changed, 83 insertions(+), 27 deletions(-) diff --git a/Admin.NET/Admin.NET.Core/Attribute/RequiredIFAttribute.cs b/Admin.NET/Admin.NET.Core/Attribute/RequiredIFAttribute.cs index 19456711..a71b7076 100644 --- a/Admin.NET/Admin.NET.Core/Attribute/RequiredIFAttribute.cs +++ b/Admin.NET/Admin.NET.Core/Attribute/RequiredIFAttribute.cs @@ -64,11 +64,13 @@ public sealed class RequiredIFAttribute( var instance = validationContext.ObjectInstance; var targetProperty = instance.GetType().GetProperty(PropertyName); + // 判断校验字段内容是否为字典 + var dictAttr = targetProperty?.GetCustomAttribute(); if (targetProperty == null) return new ValidationResult($"找不到属性: {PropertyName}"); var targetValue = targetProperty.GetValue(instance); - if (!ShouldValidate(targetValue)) return ValidationResult.Success; + if (!ShouldValidate(targetValue, dictAttr)) return ValidationResult.Success; return IsEmpty(value) ? new ValidationResult(ErrorMessage ?? $"{validationContext.MemberName}不能为空") : ValidationResult.Success; } @@ -78,7 +80,7 @@ public sealed class RequiredIFAttribute( /// /// 依赖属性的值 /// 是否需要验证 - private bool ShouldValidate(object targetValue) + private bool ShouldValidate(object targetValue, DictAttribute dictAttr) { switch (Comparison) { @@ -94,8 +96,26 @@ public sealed class RequiredIFAttribute( case Operator.LessThanOrEqual: case Operator.Contains: case Operator.NotContains: - if (targetValue is IEnumerable enumerable) return enumerable.Cast().Any(item => CompareValues(item, TargetValue, Comparison)); - return TargetValue == null ? !IsEmpty(targetValue) : CompareValues(targetValue, TargetValue, Comparison); + // 多选字典 + if (dictAttr != null && targetValue is string targetString && targetString.Contains(',')) + { + var values = targetString.Split(',') + .Select(v => v.Trim()) + .Where(v => !string.IsNullOrEmpty(v)) + .ToArray(); + + return values.Any(value => CompareValues(value, TargetValue, Comparison)); + } + // 处理其他集合情况 + else if (targetValue is IEnumerable enumerable && !(targetValue is string)) + { + return enumerable.Cast().Any(item => CompareValues(item, TargetValue, Comparison)); + } + // 单选字典 + else + { + return TargetValue == null ? !IsEmpty(targetValue) : CompareValues(targetValue, TargetValue, Comparison); + } default: return false; @@ -137,9 +157,28 @@ public sealed class RequiredIFAttribute( case Operator.Contains: case Operator.NotContains: - if (targetValue is not IEnumerable enumerable) return false; - bool contains = enumerable.Cast().Any(item => item != null && item.Equals(sourceValue)); - return comparison == Operator.Contains ? contains : !contains; + if (targetValue == null) return false; + if (sourceValue == null) return comparison == Operator.NotContains; + + // 多选字典 + if (targetValue is string targetString) + { + string sourceString = sourceValue.ToString(); + bool stringContains = targetString.Equals(sourceString); + return comparison == Operator.Contains ? stringContains : !stringContains; + } + // 其他集合类型处理 + else if (targetValue is IEnumerable enumerable && !(targetValue is string)) + { + bool contains = enumerable.OfType().Any(item => + item != null && item.Equals(sourceValue)); + return comparison == Operator.Contains ? contains : !contains; + } + else + { + bool valuesEqual = targetValue.Equals(sourceValue); + return comparison == Operator.Contains ? valuesEqual : !valuesEqual; + } default: return false; diff --git a/Admin.NET/Admin.NET.sln b/Admin.NET/Admin.NET.sln index a452e8a4..a7cc8391 100644 --- a/Admin.NET/Admin.NET.sln +++ b/Admin.NET/Admin.NET.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 18 -VisualStudioVersion = 18.0.11012.119 d18.0 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36511.14 d17.14 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Admin.NET.Application", "Admin.NET.Application\Admin.NET.Application.csproj", "{C3F5AEC5-ACEE-4109-94E3-3F981DC18268}" EndProject diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.ReZero/Admin.NET.Plugin.ReZero.csproj b/Admin.NET/Plugins/Admin.NET.Plugin.ReZero/Admin.NET.Plugin.ReZero.csproj index 06846115..099d9176 100644 --- a/Admin.NET/Plugins/Admin.NET.Plugin.ReZero/Admin.NET.Plugin.ReZero.csproj +++ b/Admin.NET/Plugins/Admin.NET.Plugin.ReZero/Admin.NET.Plugin.ReZero.csproj @@ -26,7 +26,7 @@ - + diff --git a/Web/package.json b/Web/package.json index c2c46b78..8de4972e 100644 --- a/Web/package.json +++ b/Web/package.json @@ -2,7 +2,7 @@ "name": "admin.net.pro", "type": "module", "version": "2.4.33", - "lastBuildTime": "2025.09.22", + "lastBuildTime": "2025.09.23", "description": "Admin.NET 站在巨人肩膀上的 .NET 通用权限开发框架", "author": "zuohuaijun", "license": "MIT", @@ -93,8 +93,8 @@ "@types/node": "^22.18.6", "@types/nprogress": "^0.2.3", "@types/sortablejs": "^1.15.8", - "@typescript-eslint/eslint-plugin": "^8.44.0", - "@typescript-eslint/parser": "^8.44.0", + "@typescript-eslint/eslint-plugin": "^8.44.1", + "@typescript-eslint/parser": "^8.44.1", "@vitejs/plugin-vue": "^6.0.1", "@vitejs/plugin-vue-jsx": "^5.1.1", "@vue/compiler-sfc": "^3.5.21", @@ -103,15 +103,15 @@ "colors": "^1.4.0", "dotenv": "^17.2.1", "eslint": "^9.36.0", - "eslint-plugin-vue": "^10.4.0", + "eslint-plugin-vue": "^10.5.0", "globals": "^16.4.0", "less": "^4.4.1", "prettier": "^3.6.2", "rollup-plugin-visualizer": "^6.0.3", - "sass": "^1.93.0", + "sass": "^1.93.1", "terser": "^5.44.0", "typescript": "^5.9.2", - "vite": "^7.1.6", + "vite": "^7.1.7", "vite-auto-i18n-plugin": "^1.1.9", "vite-plugin-cdn-import": "^1.0.1", "vite-plugin-compression2": "^2.2.1", diff --git a/Web/src/components/selector/pulldownSelecter.vue b/Web/src/components/selector/pulldownSelecter.vue index 63948c3e..50caff5c 100644 --- a/Web/src/components/selector/pulldownSelecter.vue +++ b/Web/src/components/selector/pulldownSelecter.vue @@ -1,6 +1,6 @@