目录结构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 MyCompanyName.MyProjectName.Api ├── Domain │ └── Module │ └── ModuleEntity.cs ├── Repositories │ └── Module │ └── ModuleRepository.cs ├── Contracts │ └── Services │ └── Module │ ├── Input │ │ ├── ModuleAddInput.cs │ │ ├── ModuleUpdateInput.cs │ │ └── ModuleGetPageInput.cs │ └── Output │ ├── ModuleGetOutput.cs │ └── ModuleGetPageOutput.cs └── Services └── Module └── ModuleService.cs
1. 新建模块实体类 路径 : Domain/Module/ModuleEntity.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 using ZhonTai.Admin.Core.Entities;using FreeSql.DataAnnotations;namespace MyCompanyName.MyProjectName.Api.Domain.Module ;[Table(Name = ApiConsts.AreaName + "_module" ) ] [Index("idx_{tablename}_01" , nameof(TenantId) + "," + nameof(Name), true) ] public partial class ModuleEntity : EntityTenant { [Column(StringLength = 50) ] public string Name { get ; set ; } }
约定说明
约定项
说明
实体类命名
以Entity 结尾,如 ModuleEntity
表名命名
下划线命名法,前缀为项目前缀
索引命名
以idx 开头
多租户支持
继承EntityTenant 后自动按 TenantId 筛选数据
2. 新建模块仓储接口 路径 : Domain/Module/IModuleRepository.cs
1 2 3 4 5 6 7 8 9 10 using ZhonTai.Admin.Core.Repositories;namespace MyCompanyName.MyProjectName.Api.Domain.Module ;public interface IModuleRepository : IRepositoryBase <ModuleEntity >{ }
3. 新建模块仓储实现 路径 : Repositories/Module/ModuleRepository.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 using MyCompanyName.MyProjectName.Api.Core.Repositories;using MyCompanyName.MyProjectName.Api.Domain.Module;using ZhonTai.Admin.Core.Db.Transaction;namespace MyCompanyName.MyProjectName.Api.Repositories.Module ;public class ModuleRepository : AppRepositoryBase <ModuleEntity >, IModuleRepository { public ModuleRepository (UnitOfWorkManagerCloud uowm ) : base (uowm ) { } }
说明
模块仓储需继承 App 项目基础仓储 AppRepositoryBase,使用当前项目主库操作模块表。
4. 新建输入输出 Dto 4.1 添加输入 Dto 路径 : Contracts/Services/Module/Input/ModuleAddInput.cs
1 2 3 4 5 6 7 8 9 10 11 12 namespace MyCompanyName.MyProjectName.Api.Contracts.Services.Module.Input ;public class ModuleAddInput { public string Name { get ; set ; } }
4.2 修改输入 Dto 路径 : Contracts/Services/Module/Input/ModuleUpdateInput.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 using System.ComponentModel.DataAnnotations;using ZhonTai.Admin.Core.Validators;namespace MyCompanyName.MyProjectName.Api.Contracts.Services.Module.Input ;public partial class ModuleUpdateInput : ModuleAddInput { [Required ] [ValidateRequired("请选择模块" ) ] public long Id { get ; set ; } }
4.3 分页查询输入 Dto 路径 : Contracts/Services/Module/Input/ModuleGetPageInput.cs
1 2 3 4 5 6 7 8 9 10 11 12 namespace MyCompanyName.MyProjectName.Api.Contracts.Services.Module.Input ;public partial class ModuleGetPageInput { public string Name { get ; set ; } }
4.4 单条查询输出 Dto 路径 : Contracts/Services/Module/Output/ModuleGetOutput.cs
1 2 3 4 5 6 7 8 9 10 using MyCompanyName.MyProjectName.Api.Contracts.Services.Module.Input;namespace MyCompanyName.MyProjectName.Api.Contracts.Services.Module.Output ;public class ModuleGetOutput : ModuleUpdateInput { }
4.5 分页查询输出 Dto 路径 : Contracts/Services/Module/Output/ModuleGetPageOutput.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 namespace MyCompanyName.MyProjectName.Api.Contracts.Services.Module.Output ;public class ModuleGetPageOutput { public long Id { get ; set ; } public string Name { get ; set ; } }
5. 新建模块服务 路径 : Services/Module/ModuleService.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 using System.Threading.Tasks;using ZhonTai.Admin.Core.Dto;using ZhonTai.Admin.Services;using MyCompanyName.MyProjectName.Api.Domain.Module;using MyCompanyName.MyProjectName.Api.Services.Module.Input;using MyCompanyName.MyProjectName.Api.Services.Module.Output;using MyCompanyName.MyProjectName.Api.Core.Consts;using ZhonTai;using ZhonTai.DynamicApi;using ZhonTai.DynamicApi.Attributes;using Microsoft.AspNetCore.Mvc;using Mapster;namespace MyCompanyName.MyProjectName.Api.Services.Module ;[DynamicApi(Area = ApiConsts.AreaName) ] public class ModuleService : BaseService , IDynamicApi { private readonly IModuleRepository _moduleRepository; public ModuleService (IModuleRepository moduleRepository ) { _moduleRepository = moduleRepository; } public async Task<ModuleGetOutput> GetAsync (long id ) { var result = await _moduleRepository.GetAsync<ModuleGetOutput>(id); return result; } [HttpPost ] public async Task<PageOutput<ModuleGetPageOutput>> GetPageAsync(PageInput<ModuleGetPageInput> input) { var key = input.Filter?.Name; var list = await _moduleRepository.Select .WhereIf(key.NotNull(), a => a.Name.Contains(key)) .Count(out var total) .OrderByDescending(true , c => c.Id) .Page(input.CurrentPage, input.PageSize) .ToListAsync<ModuleGetPageOutput>(); return new PageOutput<ModuleGetPageOutput> { List = list, Total = total }; } public async Task<long > AddAsync (ModuleAddInput input ) { var entity = input.Adapt<ModuleEntity>(); await _moduleRepository.InsertAsync(entity); return entity.Id; } public async Task UpdateAsync (ModuleUpdateInput input ) { var entity = await _moduleRepository.GetAsync(input.Id); if (entity?.Id == null ) { throw ResultOutput.Exception("模块不存在" ); } input.Adapt(entity); await _moduleRepository.UpdateAsync(entity); } public async Task DeleteAsync (long id ) { await _moduleRepository.DeleteAsync(m => m.Id == id); } public async Task SoftDeleteAsync (long id ) { await _moduleRepository.SoftDeleteAsync(id); } public async Task BatchSoftDeleteAsync (long [] ids ) { await _moduleRepository.SoftDeleteAsync(ids); } }
动态接口生成
在 ModuleService 上增加 [DynamicApi(Area = ApiConsts.AreaName)] 特性,并继承 IDynamicApi 接口。
6. 接口权限说明 6.1 需要登录 1 2 3 4 5 6 [Login ] public async Task<ModuleGetOutput> GetAsync (long id ){ var result = await _moduleRepository.GetAsync<ModuleGetOutput>(id); return result; }
6.2 允许匿名访问 1 2 3 4 5 6 [AllowAnonymous ] public async Task<ModuleGetOutput> GetAsync (long id ){ var result = await _moduleRepository.GetAsync<ModuleGetOutput>(id); return result; }
6.3 授权接口
注意 : 授权接口需删除 [Login] 和 [AllowAnonymous] 标记。
命名替换参考
占位符
替换为
示例
MyCompanyName
公司名
ZhonTai
MyProjectName
项目名
Admin
Module
业务模块名
User, Role, Product
#中台 |
#中台/新建接口项目 #中台/.NET模板 #中台/分布式微服务 #仓储模式 #API接口