diff --git a/Infrastructure/Controllers/BaseController.cs b/Infrastructure/Controllers/BaseController.cs
index 9a88f4e..d84a7d3 100644
--- a/Infrastructure/Controllers/BaseController.cs
+++ b/Infrastructure/Controllers/BaseController.cs
@@ -15,6 +15,7 @@ namespace Infrastructure.Controllers
///
/// web层通用数据处理
///
+ //[ApiController]
public class BaseController : ControllerBase
{
public static string TIME_FORMAT_FULL = "yyyy-MM-dd HH:mm:ss";
diff --git a/Infrastructure/ModelBinder/CommaSeparatedArrayModelBinder.cs b/Infrastructure/ModelBinder/CommaSeparatedArrayModelBinder.cs
new file mode 100644
index 0000000..735b054
--- /dev/null
+++ b/Infrastructure/ModelBinder/CommaSeparatedArrayModelBinder.cs
@@ -0,0 +1,51 @@
+using Microsoft.AspNetCore.Mvc.ModelBinding;
+using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace ZR.Infrastructure.ModelBinder
+{
+ public class CommaSeparatedArrayModelBinder : IModelBinder
+ {
+ public Task BindModelAsync(ModelBindingContext bindingContext)
+ {
+ var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
+ if (valueProviderResult == ValueProviderResult.None)
+ {
+ return Task.CompletedTask;
+ }
+
+ var value = valueProviderResult.FirstValue;
+ if (string.IsNullOrEmpty(value))
+ {
+ return Task.CompletedTask;
+ }
+
+ try
+ {
+ var array = value.Split(',').Select(x => (T)Convert.ChangeType(x, typeof(T))).ToArray();
+ bindingContext.Result = ModelBindingResult.Success(array);
+ }
+ catch
+ {
+ bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, "Invalid value format");
+ }
+
+ return Task.CompletedTask;
+ }
+ }
+
+ public class CommaSeparatedArrayModelBinderProvider : IModelBinderProvider
+ {
+ public IModelBinder? GetBinder(ModelBinderProviderContext context)
+ {
+ if (context.Metadata.ModelType == typeof(T[]))
+ {
+ return new BinderTypeModelBinder(typeof(CommaSeparatedArrayModelBinder));
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/ZR.Admin.WebApi/GlobalUsing.cs b/ZR.Admin.WebApi/GlobalUsing.cs
index 89190fa..8d76ef1 100644
--- a/ZR.Admin.WebApi/GlobalUsing.cs
+++ b/ZR.Admin.WebApi/GlobalUsing.cs
@@ -8,4 +8,5 @@ global using Mapster;
global using Infrastructure.Extensions;
global using Infrastructure.Controllers;
global using ZR.ServiceCore.Middleware;
-global using ZR.ServiceCore.Services;
\ No newline at end of file
+global using ZR.ServiceCore.Services;
+global using ZR.Infrastructure.ModelBinder;
\ No newline at end of file
diff --git a/ZR.Admin.WebApi/Program.cs b/ZR.Admin.WebApi/Program.cs
index 5df3ff0..9eca8fa 100644
--- a/ZR.Admin.WebApi/Program.cs
+++ b/ZR.Admin.WebApi/Program.cs
@@ -16,7 +16,12 @@ var builder = WebApplication.CreateBuilder(args);
builder.Host.UseNLog();
// Add services to the container.
-builder.Services.AddControllers();
+builder.Services.AddControllers(options =>
+{
+ options.ModelBinderProviders.Insert(0, new CommaSeparatedArrayModelBinderProvider());
+ options.ModelBinderProviders.Insert(0, new CommaSeparatedArrayModelBinderProvider());
+ options.ModelBinderProviders.Insert(0, new CommaSeparatedArrayModelBinderProvider());
+});
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
@@ -37,7 +42,8 @@ builder.Services.AddIPRate(builder.Configuration);
builder.Services.AddHttpContextAccessor();
//绑定整个对象到Model上
builder.Services.Configure(builder.Configuration);
-
+builder.Configuration.AddJsonFile("codeGen.json");
+builder.Configuration.AddJsonFile("iprate.json");
//jwt 认证
builder.Services.AddJwt();
//配置文件
diff --git a/ZR.Admin.WebApi/appsettings.json b/ZR.Admin.WebApi/appsettings.json
index f91383c..2e52bf4 100644
--- a/ZR.Admin.WebApi/appsettings.json
+++ b/ZR.Admin.WebApi/appsettings.json
@@ -67,26 +67,6 @@
"AppID": "",
"AppSecret": ""
},
- //代码生成配置
- "gen": {
- //是否显示移动端代码生成
- "showApp": false,
- //自动去除表前缀
- "autoPre": true,
- "author": "admin",
- "tablePrefix": "sys_", //"表前缀(生成类名不会包含表前缀,多个用逗号分隔)",
- "vuePath": "", //前端代码存储路径eg:D:\Work\ZRAdmin-Vue3
- "csharpTypeArr": {
- "string": [ "varchar", "nvarchar", "text", "longtext" ],
- "int": [ "int", "integer", "smallint", "int4", "int8", "int2" ],
- "long": [ "bigint", "number" ],
- "float": [ "numeric", "real", "float" ],
- "decimal": [ "money", "decimal", "smallmoney" ],
- "dateTime": [ "date", "datetime", "datetime2", "smalldatetime", "timestamp" ],
- "byte": [ "tinyint" ],
- "bool": [ "bit" ]
- }
- },
//邮箱配置信息
"MailOptions": {
//发件人名称
@@ -107,36 +87,20 @@
"Cache": "127.0.0.1:6379,defaultDatabase=0,poolsize=50,ssl=false,writeBuffer=10240,prefix=cache:",
"Session": "127.0.0.1:6379,defaultDatabase=0,poolsize=50,ssl=false,writeBuffer=10240,prefix=session:"
},
- //接口请求限制
- "IpRateLimiting": {
- "EnableEndpointRateLimiting": true,
- "StackBlockedRequests": false,
- "RealIpHeader": "X-Real-IP",
- "ClientIdHeader": "X-ClientId",
- "HttpStatusCode": 429,
- "EndpointWhitelist": [ "post:/system/dict/data/types", "*:/msghub/negotiate", "*:/LogOut", "*:/common/uploadfile", "*:/VerifyScan" ],
- "QuotaExceededResponse": {
- "Content": "{{\"code\":429,\"msg\":\"访问过于频繁,请稍后重试\"}}",
- "ContentType": "application/json",
- "StatusCode": 429
- },
- //通用规则,api规则,结尾一定要带*
- "GeneralRules": [
- {
- "Endpoint": "*:/captchaImage",
- //时间段,格式:{数字}{单位};可使用单位:s, m, h, d
- "Period": "3s",
- "Limit": 5
- },
- {
- "Endpoint": "((post)|(put)):*",
- "Period": "3s",
- "Limit": 1
- }
- ]
- },
//验证码配置
"CaptchaOptions": {
"IgnoreCase": true // 比较时是否忽略大小写
+ },
+ //代码生成配置
+ "CodeGen": {
+ //是否显示移动端代码生成
+ "showApp": false,
+ //自动去除表前缀
+ "autoPre": true,
+ //默认生成业务模块名
+ "moduleName": "business",
+ "author": "admin",
+ "tablePrefix": "sys_", //"表前缀(生成类名不会包含表前缀,多个用逗号分隔)",
+ "vuePath": "" //前端代码存储路径eg:D:\Work\ZRAdmin-Vue3
}
}
diff --git a/ZR.Admin.WebApi/iprate.json b/ZR.Admin.WebApi/iprate.json
new file mode 100644
index 0000000..7269065
--- /dev/null
+++ b/ZR.Admin.WebApi/iprate.json
@@ -0,0 +1,30 @@
+{
+ //接口请求限制
+ "IpRateLimiting": {
+ "EnableEndpointRateLimiting": true,
+ "StackBlockedRequests": false,
+ "RealIpHeader": "X-Real-IP",
+ "ClientIdHeader": "X-ClientId",
+ "HttpStatusCode": 429,
+ "EndpointWhitelist": [ "post:/system/dict/data/types", "*:/msghub/negotiate", "*:/LogOut", "*:/common/uploadfile", "*:/VerifyScan" ],
+ "QuotaExceededResponse": {
+ "Content": "{{\"code\":429,\"msg\":\"访问过于频繁,请稍后重试\"}}",
+ "ContentType": "application/json",
+ "StatusCode": 429
+ },
+ //通用规则,api规则,结尾一定要带*
+ "GeneralRules": [
+ {
+ "Endpoint": "*:/captchaImage",
+ //时间段,格式:{数字}{单位};可使用单位:s, m, h, d
+ "Period": "3s",
+ "Limit": 5
+ },
+ {
+ "Endpoint": "((post)|(put)):*",
+ "Period": "3s",
+ "Limit": 1
+ }
+ ]
+ }
+}
diff --git a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/TplControllers.txt b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/TplControllers.txt
index 2536570..496bf89 100644
--- a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/TplControllers.txt
+++ b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/TplControllers.txt
@@ -113,14 +113,11 @@ $if(replaceDto.ShowBtnDelete || replaceDto.ShowBtnMultiDel)
[HttpDelete("{ids}")]
[ActionPermissionFilter(Permission = "${replaceDto.PermissionPrefix}:delete")]
[Log(Title = "${genTable.FunctionName}", BusinessType = BusinessType.DELETE)]
- public IActionResult Delete${replaceDto.ModelTypeName}(string ids)
+ public IActionResult Delete${replaceDto.ModelTypeName}([ModelBinder(typeof(CommaSeparatedArrayModelBinder<${replaceDto.PKType}>))] ${replaceDto.PKType}[] ids)
{
- long[] idsArr = Tools.SpitLongArrary(ids);
- if (idsArr.Length <= 0) { return ToResponse(ApiResult.Error($"删除失败Id 不能为空")); }
+ if (ids.Length <= 0) { return ToResponse(ApiResult.Error($"删除失败Id 不能为空")); }
- var response = _${replaceDto.ModelTypeName}Service.Delete(idsArr$if(replaceDto.enableLog), "删除${genTable.FunctionName}"$end);
-
- return ToResponse(response);
+ return ToResponse(_${replaceDto.ModelTypeName}Service.Delete(ids$if(replaceDto.enableLog), "删除${genTable.FunctionName}"$end));
}
$end
diff --git a/ZR.CodeGenerator/Model/ImportCodeGenTableDto.cs b/ZR.CodeGenerator/Model/ImportCodeGenTableDto.cs
new file mode 100644
index 0000000..ac395f3
--- /dev/null
+++ b/ZR.CodeGenerator/Model/ImportCodeGenTableDto.cs
@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+
+namespace ZR.CodeGenerator.Model
+{
+ public class ImportCodeGenTableDto
+ {
+ public string DbName { get; set; }
+ public List Tables { get; set; }
+ }
+
+ public class CodeGenTables
+ {
+ public string Name { get; set; }
+ public string Description { get; set; }
+ }
+}
diff --git a/ZR.CodeGenerator/Model/InitTableDto.cs b/ZR.CodeGenerator/Model/InitTableDto.cs
new file mode 100644
index 0000000..a1bf45a
--- /dev/null
+++ b/ZR.CodeGenerator/Model/InitTableDto.cs
@@ -0,0 +1,13 @@
+using Infrastructure.Model;
+
+namespace ZR.CodeGenerator.Model
+{
+ public class InitTableDto
+ {
+ public string DbName { get; set; }
+ public string UserName { get; set; }
+ public string TableName { get; set; }
+ public string Desc { get; set; }
+ public CodeGen CodeGen { get; set; }
+ }
+}