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

!1498 功能优化并修复部分已知bug
Merge pull request !1498 from 喵你个汪/next

zuohuaijun 1 год назад
Родитель
Сommit
6df859fe4a

+ 1 - 1
Admin.NET/Admin.NET.Core/Service/CodeGen/CustomViewEngine.cs

@@ -64,7 +64,7 @@ public class CustomViewEngine : ViewEngineModel
     
     public List<TableUniqueConfigItem> TableUniqueConfigList { get; set; }
 
-    public List<string> PrimaryKeyNames => PrimaryKeyFieldList.Select(u => u.PropertyName).ToList();
+    public List<CodeGenConfig> IgnoreUpdateFieldList => TableField.Where(u => u.WhetherAddUpdate == "N" && u.ColumnKey != "True" && u.WhetherCommon != "Y").ToList();
     
     /// <summary>
     /// 格式化主键查询条件

+ 6 - 5
Admin.NET/Admin.NET.Core/Service/CodeGen/Dto/CodeGenConfig.cs

@@ -184,23 +184,24 @@ public class CodeGenConfig
     public string LowerPropertyNameTrimEndId => LowerPropertyName.TrimEnd("Id");
 
     /// <summary>
-    /// 联表显示字段名称
+    /// 扩展属性名称
     /// </summary>
-    public string FkLinkDisplayPropertyName => EffectType switch
+    public string ExtendedPropertyName => EffectType switch
     {
         "ForeignKey" => $"{LowerPropertyNameTrimEndId}FkDisplayName",
         "ApiTreeSelector" => $"{LowerPropertyNameTrimEndId}DisplayName",
+        "Upload" => $"{LowerPropertyName}Attachment",
         _ => PropertyName
     };
 
     /// <summary>
-    /// 联表显示字段首字母小写名称
+    /// 首字母小写的扩展属性名称
     /// </summary>
-    public string LowerFkLinkDisplayPropertyName
+    public string LowerExtendedPropertyName
     {
         get
         {
-            var displayPropertyName = FkLinkDisplayPropertyName;
+            var displayPropertyName = ExtendedPropertyName;
             if (string.IsNullOrWhiteSpace(displayPropertyName)) return null;
             return displayPropertyName[..1].ToLower() + displayPropertyName[1..];
         }

+ 3 - 3
Admin.NET/Admin.NET.Core/Service/CodeGen/SysCodeGenService.cs

@@ -681,20 +681,20 @@ public class SysCodeGenService : IDynamicApiController, ITransient
     {
         if (input.GenerateType!.Substring(1, 1).Contains('1'))
         {
-            return new() { "index.vue.vm", "editDialog.vue.vm", "api.js.vm" };
+            return new() { "index.vue.vm", "editDialog.vue.vm", "api.ts.vm" };
         }
         if (input.GenerateType.Substring(1, 1).Contains('2'))
         {
             return new() { "Service.cs.vm", "Input.cs.vm", "Output.cs.vm", "Dto.cs.vm" };
         }
-        return new() { "Service.cs.vm", "Input.cs.vm", "Output.cs.vm", "Dto.cs.vm", "index.vue.vm", "editDialog.vue.vm", "api.js.vm" };
+        return new() { "Service.cs.vm", "Input.cs.vm", "Output.cs.vm", "Dto.cs.vm", "index.vue.vm", "editDialog.vue.vm", "api.ts.vm" };
     }
 
     /// <summary>
     /// 获取模板文件路径集合
     /// </summary>
     /// <returns></returns>
-    private static List<string> GetTemplatePathList() => new() { "Service.cs.vm", "Input.cs.vm", "Output.cs.vm", "Dto.cs.vm", "index.vue.vm", "editDialog.vue.vm", "api.js.vm" };
+    private static List<string> GetTemplatePathList() => new() { "Service.cs.vm", "Input.cs.vm", "Output.cs.vm", "Dto.cs.vm", "index.vue.vm", "editDialog.vue.vm", "api.ts.vm" };
 
     /// <summary>
     /// 设置生成文件路径

+ 1 - 1
Admin.NET/Admin.NET.Web.Entry/wwwroot/template/Input.cs.vm

@@ -158,7 +158,7 @@ public class QueryById@(Model.ClassName)Input : Delete@(Model.ClassName)Input
     @:/// </summary>
     @:[ImporterHeader(Name = "@(headerName)")]
     @:[ExporterHeader("@(headerName)", Format = "@", Width = 25, IsBold = true)]
-    @:public string @column.FkLinkDisplayPropertyName { get; set; }
+    @:public string @column.ExtendedPropertyName { get; set; }
     } else {
     @:/// <summary>
     @:/// @column.ColumnComment

+ 3 - 3
Admin.NET/Admin.NET.Web.Entry/wwwroot/template/Output.cs.vm

@@ -21,13 +21,13 @@ public class @(Model.ClassName)Output
     @:/// <summary>
     @:/// @(column.ColumnComment) 描述
     @:/// </summary>
-    @:public string @(column.FkLinkDisplayPropertyName) { get; set; } 
+    @:public string @(column.ExtendedPropertyName) { get; set; } 
     }else if(column.EffectType == "Upload"){
     @:
     @:/// <summary>
-    @:/// @(column.ColumnComment) 件信息
+    @:/// @(column.ColumnComment) 件信息
     @:/// </summary>
-    @:public SysFile @(column.PropertyName)Attachment { get; set; }
+    @:public SysFile @(column.ExtendedPropertyName) { get; set; }
     }
     @:
     }

+ 16 - 10
Admin.NET/Admin.NET.Web.Entry/wwwroot/template/Service.cs.vm

@@ -70,7 +70,7 @@ public class @(Model.ClassName)Service : IDynamicApiController, ITransient
             foreach (var column in Model.TableField) {
                 @:@(column.PropertyName) = u.@(column.PropertyName),
                 if (column.EffectType == "ForeignKey" || column.EffectType == "ApiTreeSelector") {
-                @:@(column.FkLinkDisplayPropertyName) = @column.GetDisplayColumn(column.LowerPropertyNameTrimEndId),
+                @:@(column.ExtendedPropertyName) = @column.GetDisplayColumn(column.LowerPropertyNameTrimEndId),
                 }
             }
             @:});
@@ -103,7 +103,7 @@ public class @(Model.ClassName)Service : IDynamicApiController, ITransient
     [ApiDescriptionSettings(Name = "Detail"), HttpGet]
     public async Task<@(Model.ClassName)> Detail([FromQuery] QueryById@(Model.ClassName)Input input)
     {
-        return await _@(Model.LowerClassName)Rep.GetFirstAsync(u => @Model.PrimaryKeysFormat(" && ", "u.{0} == input.{0}", false));
+        return await _@(Model.LowerClassName)Rep.GetFirstAsync(u => @Model.PrimaryKeysFormat(" && ", "u.{0} == input.{0}"));
     }
 
     /// <summary>
@@ -132,13 +132,17 @@ public class @(Model.ClassName)Service : IDynamicApiController, ITransient
     public async Task Update(Update@(Model.ClassName)Input input)
     {
         @{
-        var primaryKeyWhere = Model.PrimaryKeysFormat(" && ", "u.{0} != input.{0}", false);
+        var primaryKeyWhere = Model.PrimaryKeysFormat(" && ", "u.{0} != input.{0}");
         foreach (var config in Model.TableUniqueConfigList) {
         @:if (await _@(Model.LowerClassName)Rep.IsAnyAsync(u => @primaryKeyWhere && @config.Format(" && ", "u.{0} != null && u.{0} == input.{0}"))) throw Oops.Oh("@(config.Message)已存在");
         }
         }
         var entity = input.Adapt<@(Model.ClassName)>();
-        await _@(Model.LowerClassName)Rep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
+        await _@(Model.LowerClassName)Rep.AsUpdateable(entity).IgnoreColumns(u => new {
+        @foreach (var column in Model.IgnoreUpdateFieldList) {
+            @:u.@(column.PropertyName),
+        }
+        }).ExecuteCommandAsync();
     }
 
     /// <summary>
@@ -150,7 +154,7 @@ public class @(Model.ClassName)Service : IDynamicApiController, ITransient
     [ApiDescriptionSettings(Name = "Delete"), HttpPost]
     public async Task Delete(Delete@(Model.ClassName)Input input)
     {
-        var entity = await _@(Model.LowerClassName)Rep.GetFirstAsync(u => @Model.PrimaryKeysFormat(" && ", "u.{0} == input.{0}", false)) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
+        var entity = await _@(Model.LowerClassName)Rep.GetFirstAsync(u => @Model.PrimaryKeysFormat(" && ", "u.{0} == input.{0}")) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
         await _@(Model.LowerClassName)Rep.FakeDeleteAsync(entity);   //假删除
         //await _@(Model.LowerClassName)Rep.DeleteAsync(entity);   //真删除
     }
@@ -164,7 +168,9 @@ public class @(Model.ClassName)Service : IDynamicApiController, ITransient
     [ApiDescriptionSettings(Name = "BatchDelete"), HttpPost]
     public async Task<int> BatchDelete([Required(ErrorMessage = "主键列表不能为空")]List<Delete@(Model.ClassName)Input> input)
     {
-        var list = await _@(Model.LowerClassName)Rep.AsQueryable().In(u => new { @Model.PrimaryKeysFormat(", ", "u.{0}", false) }, input).ToListAsync();
+        var exp = Expressionable.Create<@(Model.ClassName)>();
+        foreach (var row in input) exp = exp.Or(it => @Model.PrimaryKeysFormat(" && ", "it.{0} == row.{0}"));
+        var list = await _@(Model.LowerClassName)Rep.AsQueryable().Where(exp.ToExpression()).ToListAsync();
         return await _@(Model.LowerClassName)Rep.FakeDeleteAsync(list);   //假删除
         //return await _@(Model.LowerClassName)Rep.DeleteAsync(list);   //真删除
     }
@@ -179,7 +185,7 @@ public class @(Model.ClassName)Service : IDynamicApiController, ITransient
     @:[ApiDescriptionSettings(Name = "SetStatus"), HttpPost]
     @:public async Task Set@(Model.ClassName)Status(Set@(Model.ClassName)StatusInput input)
     @:{
-        @:await _@(Model.LowerClassName)Rep.AsUpdateable().SetColumns(u => u.Status, input.Status).Where(u => @Model.PrimaryKeysFormat(" && ", "u.{0} == input.{0}", false)).ExecuteCommandAsync();
+        @:await _@(Model.LowerClassName)Rep.AsUpdateable().SetColumns(u => u.Status, input.Status).Where(u => @Model.PrimaryKeysFormat(" && ", "u.{0} == input.{0}")).ExecuteCommandAsync();
     @:}
     }
     @foreach (var column in Model.UploadFieldList) {
@@ -247,7 +253,7 @@ public class @(Model.ClassName)Service : IDynamicApiController, ITransient
         @:{
             foreach (var column in fieldsList) {
             var columnList = column.FkDisplayColumnList.Select(n => $"{{u.{n}}}").ToList();
-            @:if (nameof(Export@(Model.ClassName)Output.@column.FkLinkDisplayPropertyName) == info.Name) return _@(Model.LowerClassName)Rep.Context.Queryable<@(column.FkEntityName)>().Select(u => $"@(string.Join("-", columnList))").Distinct().ToList();
+            @:if (nameof(Export@(Model.ClassName)Output.@column.ExtendedPropertyName) == info.Name) return _@(Model.LowerClassName)Rep.Context.Queryable<@(column.FkEntityName)>().Select(u => $"@(string.Join("-", columnList))").Distinct().ToList();
             }
             @:return null;
         @:});
@@ -277,12 +283,12 @@ public class @(Model.ClassName)Service : IDynamicApiController, ITransient
                 @:{
                     foreach (var column in Model.ImportFieldList.Where(u => u.EffectType == "ForeignKey" || u.EffectType == "ApiTreeSelector")) {
                     @:// 链接 @(column.ColumnComment)
-                    @:var @(column.LowerPropertyName)LabelList = pageItems.Where(x => x.@column.FkLinkDisplayPropertyName != null).Select(x => x.@column.FkLinkDisplayPropertyName).Distinct().ToList();
+                    @:var @(column.LowerPropertyName)LabelList = pageItems.Where(x => x.@column.ExtendedPropertyName != null).Select(x => x.@column.ExtendedPropertyName).Distinct().ToList();
                     @:if (@(column.LowerPropertyName)LabelList.Any()) {
                         var columnList = column.FkDisplayColumnList.Select(n => $"{{u.{n}}}").ToList();
                         @:var @(column.LowerPropertyName)LinkMap = _@(Model.LowerClassName)Rep.Context.Queryable<@(column.FkEntityName)>().Where(u => @(column.LowerPropertyName)LabelList.Contains($"@(string.Join("-", columnList))")).ToList().ToDictionary(u => $"@(string.Join("-", columnList))", u => u.@(column.FkLinkColumnName));
                         @:pageItems.ForEach(e => {
-                            @:e.@(column.PropertyName) = @(column.LowerPropertyName)LinkMap?.GetValueOrDefault(e.@column.FkLinkDisplayPropertyName);
+                            @:e.@(column.PropertyName) = @(column.LowerPropertyName)LinkMap?.GetValueOrDefault(e.@column.ExtendedPropertyName);
                             @:if (e.@(column.PropertyName) == null) e.Error = "@(column.ColumnComment)链接失败";
                         @:});
                     @:}

+ 0 - 0
Admin.NET/Admin.NET.Web.Entry/wwwroot/template/Api.js.vm → Admin.NET/Admin.NET.Web.Entry/wwwroot/template/api.ts.vm


+ 2 - 2
Admin.NET/Admin.NET.Web.Entry/wwwroot/template/editDialog.vue.vm

@@ -44,7 +44,7 @@
 						</el-form-item>
 					</el-col>
 					}else if(column.EffectType == "DictSelector" || column.EffectType == "EnumSelector"){
-					@:<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20" @(Model.IsStatus(column) ? $"v-if='!ruleForm.{Model.ToLowerFirstLetter(Model.PrimaryKeyNames.First())}'" : "")>
+					@:<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20" @(Model.IsStatus(column) ? $"v-if='!ruleForm.{Model.PrimaryKeyFieldList.First().LowerPropertyName}'" : "")>
 						@:<el-form-item label="@column.ColumnComment" prop="@(column.LowerPropertyName)">
 							if (Model.IsStatus(column)) {
 							@:<el-switch v-model="ruleForm.@column.LowerPropertyName" :active-value="1" :inactive-value="2" size="small" />
@@ -219,7 +219,7 @@
 		ruleFormRef.value.validate(async (isValid: boolean, fields?: any) => {
 			if (isValid) {
 				let values = ruleForm.value;
-				await @(Model.LowerClassName)Api[ruleForm.value.@(Model.ToLowerFirstLetter(Model.PrimaryKeyNames.First())) ? 'update' : 'add'](values);
+				await @(Model.LowerClassName)Api[ruleForm.value.@(Model.PrimaryKeyFieldList.First().LowerPropertyName) ? 'update' : 'add'](values);
 				closeDialog();
 			} else {
 				ElMessage({

+ 3 - 5
Admin.NET/Admin.NET.Web.Entry/wwwroot/template/index.vue.vm

@@ -99,7 +99,7 @@
       </el-form>
     </el-card>
     <el-card class="full-table" shadow="hover" style="margin-top: 5px">
-      <el-table :data="tableData" @@selection-change="(val: any[]) => { selectData = val; }" style="width: 100%" v-loading="loading" tooltip-effect="light" row-key="@Model.ToLowerFirstLetter(Model.PrimaryKeyNames.First())" @@sort-change="sortChange" border>
+      <el-table :data="tableData" @@selection-change="(val: any[]) => { selectData = val; }" style="width: 100%" v-loading="loading" tooltip-effect="light" row-key="@Model.PrimaryKeyFieldList.First().LowerPropertyName" @@sort-change="sortChange" border>
         <el-table-column type="selection" width="40" align="center" v-auth="'@(Model.LowerClassName):batchDelete'" />
         <el-table-column type="index" label="序号" width="55" align="center"/>
         @foreach (var column in Model.TableField.Where(u => u.WhetherTable == "Y")){
@@ -118,7 +118,7 @@
             @:fit="scale-down"
             @:preview-teleported />
             }else if(column.EffectType == "ForeignKey" || column.EffectType == "ApiTreeSelector"){
-            @:<span>{{scope.row.@(column.LowerFkLinkDisplayPropertyName)}}</span>
+            @:<span>{{scope.row.@(column.LowerExtendedPropertyName)}}</span>
             }else if(column.EffectType == "Switch"){
             @:<el-tag v-if="scope.row.@(column.LowerPropertyName)"> 是 </el-tag>
             @:<el-tag type="danger" v-else> 否 </el-tag>
@@ -328,9 +328,7 @@
       cancelButtonText: "取消",
       type: "warning",
     }).then(async () => {
-      @foreach (var column in @Model.TableField.Where(u => u.ColumnKey == "True")) {
-      @:const count = await @(Model.LowerClassName)Api.batchDelete({ @(column.LowerPropertyName)List: selectData.value.map(u => { @(Model.PrimaryKeysFormat(", ", "u.{0}", true)) }) });
-      }
+      const count = await @(Model.LowerClassName)Api.batchDelete(selectData.value.map(u => ({ @(Model.PrimaryKeysFormat(", ", "{0}: u.{0}", true)) }) )).then(res => res.data.result);
       handleQuery();
       ElMessage.success(`成功批量删除${count}条记录`);
     }).catch(() => {});