Przeglądaj źródła

feat: 后端代码生成支持数据导入

喵你个旺呀 1 rok temu
rodzic
commit
fc4e0d7801

+ 3 - 0
Admin.NET/Admin.NET.Application/GlobalUsings.cs

@@ -6,6 +6,7 @@
 
 global using Admin.NET.Core;
 global using Furion;
+global using Furion.DatabaseAccessor;
 global using Furion.DependencyInjection;
 global using Furion.DynamicApiController;
 global using Furion.FriendlyException;
@@ -13,6 +14,8 @@ global using Mapster;
 global using Microsoft.AspNetCore.Authorization;
 global using Microsoft.AspNetCore.Mvc;
 global using Microsoft.Extensions.DependencyInjection;
+global using Magicodes.ExporterAndImporter.Core;
+global using Magicodes.ExporterAndImporter.Excel;
 global using SqlSugar;
 global using System;
 global using System.Collections.Generic;

+ 8 - 1
Admin.NET/Admin.NET.Core/Entity/SysCodeGenConfig.cs

@@ -157,7 +157,14 @@ public partial class SysCodeGenConfig : EntityBase
     [SugarColumn(ColumnDescription = "增改", Length = 8)]
     [MaxLength(8)]
     public string? WhetherAddUpdate { get; set; }
-
+    
+    /// <summary>
+    /// 导入
+    /// </summary>
+    [SugarColumn(ColumnDescription = "导入", Length = 8)]
+    [MaxLength(8)]
+    public string? WhetherImport { get; set; }
+    
     /// <summary>
     /// 主键
     /// </summary>

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

@@ -137,7 +137,12 @@ public class CodeGenConfig
     /// 增改
     /// </summary>
     public string WhetherAddUpdate { get; set; }
-
+    
+    /// <summary>
+    /// 导入
+    /// </summary>
+    public string WhetherImport { get; set; }
+    
     /// <summary>
     /// 主外键
     /// </summary>

+ 1 - 0
Admin.NET/Admin.NET.Core/Service/CodeGen/SysCodeGenConfigService.cs

@@ -118,6 +118,7 @@ public class SysCodeGenConfigService : IDynamicApiController, ITransient
             // 生成代码时,主键并不是必要输入项,故一定要排除主键字段
             codeGenConfig.WhetherRequired = (tableColumn.IsNullable || tableColumn.IsPrimarykey) ? YesNoEnum.N.ToString() : YesNoEnum.Y.ToString();
             codeGenConfig.QueryWhether = YesOrNo;
+            codeGenConfig.WhetherImport = YesOrNo;
             codeGenConfig.WhetherAddUpdate = YesOrNo;
             codeGenConfig.WhetherTable = YesOrNo;
 

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

@@ -119,3 +119,33 @@ public class QueryById@(@Model.ClassName)Input : Delete@(@Model.ClassName)Input
 {
 
 }
+
+@if (Model.TableField.Any(x => x.WhetherImport == "Y")) {
+@:/// <summary>
+@:/// @(@Model.BusName)数据导入实体
+@:/// </summary>
+@:[ExcelImporter(SheetIndex = 1, IsOnlyErrorRows = true)]
+@:public class Import@(@Model.ClassName)Input : BaseImportInput
+@:{
+  foreach (var column in Model.TableField.Where(x => x.WhetherImport == "Y")){
+    if (@column.WhetherAddUpdate == "Y") {
+    @:/// <summary>
+    @:/// @column.ColumnComment
+    @:/// </summary>
+      if (@column.WhetherRequired == "Y" || @column.NetType.TrimEnd('?').EndsWith("Enum")){
+    @:[ImporterHeader(Name = "*@(@column.ColumnComment)")]
+    @:[ExporterHeader("*@(@column.ColumnComment)", Format = "@", Width = 25, IsBold = true)]
+      } else {
+    @:[ImporterHeader(Name = "@(@column.ColumnComment)")]
+    @:[ExporterHeader("@(@column.ColumnComment)", Format = "@", Width = 25, IsBold = true)]
+      }
+      if (@column.NetType.TrimEnd('?').EndsWith("Enum") || @column.NetType.EndsWith("int") || @column.NetType.EndsWith("float") || @column.NetType.EndsWith("long")){
+    @:public @column.NetType? @column.PropertyName { get; set; }
+      } else {
+    @:public @column.NetType @column.PropertyName { get; set; }
+      }
+    @:
+    }
+  }
+@:}
+}

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

@@ -40,7 +40,6 @@ if(column.EffectType == "fk")
     @:
 }
     }
- 
 
 @foreach (var column in Model.TableField){
 if (@column.EffectType == "ApiTreeSelect"){
@@ -62,3 +61,15 @@ if (@column.EffectType == "ApiTreeSelect"){
     @:*/
 }
 }
+
+@if (Model.TableField.Any(x => x.WhetherImport == "Y")) {
+@:/// <summary>
+@:/// @(@Model.BusName)数据导入模板实体
+@:/// </summary>
+@:public class Export@(@Model.ClassName)Output : Import@(@Model.ClassName)Input
+@:{
+@:    [ImporterHeader(IsIgnore = true)]
+@:    [ExporterHeader(IsIgnore = true)]
+@:    public virtual string Error { get; set; }
+@:}
+}

+ 55 - 0
Admin.NET/Admin.NET.Web.Entry/wwwroot/template/Service.cs.vm

@@ -241,4 +241,59 @@ if(@column.EffectType == "ApiTreeSelect" && !definedObjects.ContainsKey("@(@colu
 }
 }
 
+@if (Model.TableField.Any(x => x.WhetherImport == "Y")) {
+    @:/// <summary>
+    @:/// 下载@(@Model.BusName)数据导入模板
+    @:/// </summary>
+    @:/// <returns></returns>
+    @:[DisplayName("下载@(@Model.BusName)数据导入模板")]
+    @:[HttpGet("ImportData"), NonUnify]
+    @:public IActionResult DownloadTemplate()
+    @:{
+    @:    return ExcelHelper.ExportTemplate(new List<Export@(@Model.ClassName)Output>{}, "@(@Model.BusName)导入模板");
+    @:}
+@:
+    @:/// <summary>
+    @:/// 导入@(@Model.BusName)记录 📃
+    @:/// </summary>
+    @:/// <returns></returns>
+    @:[DisplayName("导入@(@Model.BusName)记录")]
+    @:[HttpPost("ImportData"), NonUnify, UnitOfWork]
+    @:public IActionResult ImportData([Required] IFormFile file)
+    @:{
+        @:lock (this)
+        @:{
+            @:var stream = ExcelHelper.ImportData<Import@(@Model.ClassName)Input, @(@Model.ClassName)>(file, (list, markerErrorAction) =>
+            @:{
+                @:_sysMenuRep.Context.Utilities.PageEach(list, 2048, pageItems =>
+                @:{
+                    @:var rows = pageItems.Adapt<List<@(@Model.ClassName)>>();
+                    @:var storageable = _sysMenuRep.Context.Storageable(rows)
+    foreach (var column in Model.TableField.Where(x => x.WhetherImport == "Y")){
+        if (@column.WhetherRequired == "Y") {
+            if(@column.NetType?.TrimEnd('?') == "string"){
+                        @:.SplitError(it => string.IsNullOrWhiteSpace(it.Item.@(@column.PropertyName)), "@(@column.ColumnComment)不能为空")
+            } else if(@column.EffectType == "EnumSelector"){
+                        @:.SplitError(it => (int)it.Item.@(@column.PropertyName) == 0, "@(@column.ColumnComment)不能为空")
+            } else if(@column.NetType.EndsWith('?') == true){
+                        @:.SplitError(it => it.Item.@(@column.PropertyName) == null, "@(@column.ColumnComment)不能为空")
+            }
+        }
+        if (@column.NetType?.TrimEnd('?') == "string") {
+                        @:.SplitError(it => it.Item.@(@column.PropertyName)?.Length > @column.ColumnLength, "@(@column.ColumnComment)长度不能超过@(@column.ColumnLength)个字符")
+        }
+    }
+                        @:.ToStorage();
+
+                    @:storageable.BulkCopy();
+                    @:storageable.BulkUpdate();
+                    
+                    @:markerErrorAction.Invoke(storageable, pageItems, rows);
+                @:});
+            @:});
+@:
+            @:return stream;
+        @:}
+    @:}
+@:}
 }

+ 6 - 1
Web/src/views/system/codeGen/component/genConfigDialog.vue

@@ -51,6 +51,11 @@
 						<el-checkbox v-model="scope.row.whetherAddUpdate" :disabled="judgeColumns(scope.row)" />
 					</template>
 				</el-table-column>
+				<el-table-column prop="whetherImport" label="导入" width="80" align="center" show-overflow-tooltip>
+					<template #default="scope">
+						<el-checkbox v-model="scope.row.whetherImport" :disabled="judgeColumns(scope.row)" />
+					</template>
+				</el-table-column>
 				<el-table-column prop="whetherRequired" label="必填" width="80" align="center" show-overflow-tooltip>
 					<template #default="scope">
 						<el-checkbox v-model="scope.row.whetherRequired" :disabled="judgeColumns(scope.row)" />
@@ -175,7 +180,7 @@ const handleQuery = async (row: any) => {
 	state.loading = true;
 	var res = await getAPI(SysCodeGenConfigApi).apiSysCodeGenConfigListGet(undefined, row.id);
 	var data = res.data.result ?? [];
-	let lstWhetherColumn = ['whetherTable', 'whetherAddUpdate', 'whetherRequired', 'whetherSortable']; //列表显示的checkbox
+	let lstWhetherColumn = ['whetherTable', 'whetherAddUpdate', 'whetherImport', 'whetherRequired', 'whetherSortable']; //列表显示的checkbox
 	data.forEach((item: any) => {
 		for (const key in item) {
 			if (item[key] === 'Y') {