Yi 框架
📖 简介
Yi Framework(意框架)是一个基于 .NET 8 + ABP.vNext + SqlSugar 的 DDD 领域驱动设计后端开源框架。
核心理念
- 简单易用:面向用户的快速开发框架,新人友好
- 源码开放:框架以源码形式提供,不打包,方便二开和学习
- 模块化设计:基于 ABP.vNext 模块化架构,按需引用
- 开箱即用:内置权限管理、多租户、CRUD 等常用功能
技术栈
后端
- .NET 8.0
- ABP.vNext(动态 API、模块化、依赖注入)
- SqlSugar(ORM)
- JWT 鉴权
- Serilog 日志
- Mapster 对象映射
前端
- Vue 3.2
- Vben Admin(企业级中后台前端解决方案)
🚀 快速开始
环境要求
- .NET SDK 8.0 或更高版本
- Visual Studio 2022 或 VS Code
- Node.js 20.10+(前端开发需要)
- 数据库:SQLite(默认)/ MySQL / SQL Server / PostgreSQL / Oracle
第一步:克隆项目
git clone https://gitee.com/ccnetcore/Yi.git
cd Yi
第二步:配置数据库
编辑 Yi.Abp.Net8/src/Yi.Abp.Web/appsettings.json:
{
"DbConnOptions": {
"Url": "server=localhost;port=3306;database=yi_db;uid=root;pwd=123456;CharSet=utf8mb4;",
"DbType": "Mysql",
"EnabledCodeFirst": true, // 是否通过代码优先创建数据库表结构
"EnabledDbSeed": true, // 是否启用数据库种子数据(初始化数据)
"EnabledSqlLog": true, // 是否启用SQL日志记录
"EnabledSaasMultiTenancy": false, // 是否启用多租户
"EnabledConcurrencyException": false // 是否启用并发异常处理
}
}
支持的数据库类型:
Sqlite(默认,无需配置)MysqlSqlserverPostgreSQLOracle
第三步:启动后端
- 使用 Visual Studio 打开
Yi.Abp.Net8/Yi.Abp.sln - 设置启动项目为
Yi.Abp.Web - 按
F5启动项目
启动成功后,浏览器会自动打开 Swagger 文档:http://localhost:19001/swagger
默认管理员账号:admin / 123456
💡 提示:
- 首次启动会自动创建数据库表(CodeFirst)
- 会自动初始化种子数据(用户、角色等)
- 接口会自动分组,点击右上角的分组名称查看不同模块的接口
第四步:启动前端(可选)
cd Yi.Vben5.Vue3
pnpm install
pnpm dev:antd
前端地址:http://localhost:18000
📁 项目结构
Yi/
├── Yi.Abp.Net8/ # 后端项目
│ ├── framework/ # 框架核心代码(基础设施)
│ │ ├── Yi.Framework.SqlSugarCore/ # SqlSugar ORM 封装
│ │ ├── Yi.Framework.Ddd.Application/ # DDD 应用层基类
│ │ └── ...
│ ├── module/ # 业务模块目录(所有业务代码都在这里)
│ │ ├── rbac/ # 权限管理模块(内置)
│ │ ├── tenant-management/# 租户管理模块(内置)
│ │ ├── antis-erp/ # 示例业务模块
│ │ └── your-module/ # 你的业务模块(在这里创建)
│ └── src/ # 框架启动项目
│ └── Yi.Abp.Web/ # Web 层(启动项目,仅配置)
├── Yi.Vben5.Vue3/ # 前端项目
└── Yi.Doc.Md/ # 框架文档
模块结构(每个业务模块都包含以下分层)
your-module/
├── YourModule.Domain.Shared/ # 领域共享层(枚举、常量)
├── YourModule.Domain/ # 领域层(实体、领域服务)
├── YourModule.Application.Contracts/ # 应用抽象层(接口、DTO)
├── YourModule.Application/ # 应用层(服务实现)
└── YourModule.SqlSugarCore/ # 基础设施层(数据库上下文)
分层架构(DDD)
┌─────────────────────────────────┐
│ Web 层(Yi.Abp.Web) │ ← 启动项目、中间件配置
├─────────────────────────────────┤
│ 应用层(Application) │ ← 业务逻辑、服务实现
├─────────────────────────────────┤
│ 应用抽象层(Application.Contracts)│ ← 接口定义、DTO
├─────────────────────────────────┤
│ 领域层(Domain) │ ← 实体、领域服务
├─────────────────────────────────┤
│ 领域共享层(Domain.Shared) │ ← 枚举、常量、共享 DTO
├─────────────────────────────────┤
│ 基础设施层(SqlSugarCore) │ ← ORM、仓储实现
└─────────────────────────────────┘
💡 重要:
- 所有业务代码都应该放在
module目录下创建自己的模块src目录只用于框架启动配置,不存放业务代码- 每个模块都是独立的,可以按需引用
🎯 核心功能
1. 动态 API
框架基于 ABP.vNext,自动将应用服务转换为 RESTful API,无需手写 Controller。
示例:
// 在 Application 层创建服务
public class NewsService : YiCrudAppService<...> { }
// 自动生成 API:
// GET /api/app/news - 查询列表
// GET /api/app/news/{id} - 查询详情
// POST /api/app/news - 创建
// PUT /api/app/news/{id} - 更新
// DELETE /api/app/news/{id} - 删除
2. CRUD 快速开发
继承 YiCrudAppService 即可自动获得完整的增删改查功能。
3. 权限管理(RBAC)
内置完整的权限管理系统:
- 用户管理
- 角色管理
- 菜单管理
- 部门管理
- 岗位管理
- 字典管理
- 操作日志
- 登录日志
4. 多租户支持
支持 SaaS 多租户架构,可配置是否启用。
5. 模块化架构
采用 ABP.vNext 模块化设计,功能模块化,按需引用。
💻 开发指南
创建自己的业务模块
重要:所有业务代码都应该在 module 目录下创建自己的模块,而不是放在 src 目录。
步骤一:创建模块目录结构
在 Yi.Abp.Net8/module/ 目录下创建你的模块文件夹,例如:your-module/
模块应包含以下项目(参考 antis-erp 模块):
YourModule.Domain.Shared- 领域共享层YourModule.Domain- 领域层YourModule.Application.Contracts- 应用抽象层YourModule.Application- 应用层YourModule.SqlSugarCore- 基础设施层
步骤二:创建模块文件
每个项目都需要一个 Module 类,例如:
YourModuleDomainSharedModule.csYourModuleDomainModule.csYourModuleApplicationContractsModule.csYourModuleApplicationModule.csYourModuleSqlSugarCoreModule.cs
步骤三:注册模块依赖
在 Yi.Abp.Web/YiAbpWebModule.cs 中注册你的模块:
[DependsOn(
typeof(YourModuleApplicationModule), // 添加你的应用模块
// ... 其他依赖
)]
public class YiAbpWebModule : AbpModule
{
// 注册动态 API
PreConfigure<AbpAspNetCoreMvcOptions>(options =>
{
options.ConventionalControllers.Create(
typeof(YourModuleApplicationModule).Assembly,
options => options.RemoteServiceName = "你的模块名称"
);
});
}
创建一个完整的 CRUD 功能
以创建"新闻管理"功能为例(在 your-module 模块中):
1. 创建实体(Domain 层)
在 YourModule.Domain/Entities/ 创建:
using SqlSugar;
using Volo.Abp.Auditing;
using Volo.Abp.Domain.Entities;
using Yi.Framework.Core.Data;
namespace YourModule.Domain.Entities
{
[SugarTable("News")]
public class NewsAggregateRoot : AggregateRoot<Guid>, ISoftDelete, IAuditedObject, IOrderNum, IState
{
[SugarColumn(IsPrimaryKey = true)]
public override Guid Id { get; protected set; }
public bool IsDeleted { get; set; }
public DateTime CreationTime { get; set; } = DateTime.Now;
public Guid? CreatorId { get; set; }
public Guid? LastModifierId { get; set; }
public DateTime? LastModificationTime { get; set; }
public int OrderNum { get; set; } = 0;
public bool State { get; set; } = true;
[SugarColumn(ColumnName = "Title")]
public string Title { get; set; } = string.Empty;
[SugarColumn(ColumnName = "Content", ColumnDataType = "text")]
public string Content { get; set; } = string.Empty;
}
}
2. 创建 DTO(Application.Contracts 层)
在 YourModule.Application.Contracts/Dtos/News/ 创建:
// NewsGetOutputDto.cs - 详情输出 DTO
using Volo.Abp.Application.Dtos;
namespace YourModule.Application.Contracts.Dtos.News
{
public class NewsGetOutputDto : EntityDto<Guid>
{
public string Title { get; set; }
public string Content { get; set; }
public DateTime CreationTime { get; set; }
}
}
// NewsGetListOutputDto.cs - 列表输出 DTO
public class NewsGetListOutputDto : EntityDto<Guid>
{
public string Title { get; set; }
public DateTime CreationTime { get; set; }
}
// NewsGetListInputVo.cs - 查询参数
using Yi.Framework.Ddd.Application.Contracts;
public class NewsGetListInputVo : PagedAllResultRequestDto
{
public string? Title { get; set; }
}
// NewsCreateInputVo.cs - 创建输入
namespace YourModule.Application.Contracts.Dtos.News
{
public class NewsCreateInputVo
{
public string Title { get; set; }
public string Content { get; set; }
}
}
// NewsUpdateInputVo.cs - 更新输入
public class NewsUpdateInputVo
{
public string Title { get; set; }
public string Content { get; set; }
}
3. 创建服务接口(Application.Contracts 层)
在 YourModule.Application.Contracts/IServices/ 创建:
using Yi.Framework.Ddd.Application.Contracts;
using YourModule.Application.Contracts.Dtos.News;
namespace YourModule.Application.Contracts.IServices
{
public interface INewsService : IYiCrudAppService<
NewsGetOutputDto,
NewsGetListOutputDto,
Guid,
NewsGetListInputVo,
NewsCreateInputVo,
NewsUpdateInputVo>
{
}
}
4. 实现服务(Application 层)
在 YourModule.Application/Services/ 创建:
using SqlSugar;
using Volo.Abp.Application.Dtos;
using Yi.Framework.Ddd.Application;
using Yi.Framework.SqlSugarCore.Abstractions;
using YourModule.Application.Contracts.Dtos.News;
using YourModule.Application.Contracts.IServices;
using YourModule.Domain.Entities;
namespace YourModule.Application.Services
{
public class NewsService : YiCrudAppService<
NewsAggregateRoot,
NewsGetOutputDto,
NewsGetListOutputDto,
Guid,
NewsGetListInputVo,
NewsCreateInputVo,
NewsUpdateInputVo>,
INewsService
{
private ISqlSugarRepository<NewsAggregateRoot, Guid> _repository;
public NewsService(ISqlSugarRepository<NewsAggregateRoot, Guid> repository)
: base(repository)
{
_repository = repository;
}
// 自定义查询逻辑(可选)
public override async Task<PagedResultDto<NewsGetListOutputDto>> GetListAsync(NewsGetListInputVo input)
{
RefAsync<int> total = 0;
var entities = await _repository._DbQueryable
.WhereIF(!string.IsNullOrEmpty(input.Title), x => x.Title.Contains(input.Title!))
.OrderByDescending(x => x.CreationTime)
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
return new PagedResultDto<NewsGetListOutputDto>(
total,
await MapToGetListOutputDtosAsync(entities)
);
}
}
}
5. 注册模块和动态 API
在 Yi.Abp.Web/YiAbpWebModule.cs 中:
// 1. 添加模块依赖
[DependsOn(
typeof(YourModuleApplicationModule), // 添加你的模块
// ... 其他依赖
)]
// 2. 注册动态 API
PreConfigure<AbpAspNetCoreMvcOptions>(options =>
{
options.ConventionalControllers.Create(
typeof(YourModuleApplicationModule).Assembly,
options => options.RemoteServiceName = "你的模块名称"
);
});
6. 完成!
启动项目后,自动生成以下 API:
GET /api/app/news- 分页查询GET /api/app/news/{id}- 查询详情POST /api/app/news- 创建PUT /api/app/news/{id}- 更新DELETE /api/app/news/{id}- 删除
数据库表会在首次启动时自动创建(CodeFirst)。
⚙️ 配置说明
数据库配置
{
"DbConnOptions": {
"Url": "数据库连接字符串",
"DbType": "Mysql", // 数据库类型
"EnabledCodeFirst": true, // 是否自动创建表
"EnabledDbSeed": true, // 是否初始化种子数据
"EnabledSqlLog": true, // 是否记录SQL日志
"EnabledSaasMultiTenancy": false, // 是否启用多租户
"EnabledConcurrencyException": false // 是否启用乐观锁
}
}
JWT 配置
{
"JwtOptions": {
"Issuer": "https://ccnetcore.com",
"Audience": "https://ccnetcore.com",
"SecurityKey": "你的密钥",
"ExpiresMinuteTime": 86400 // Token 过期时间(分钟)
}
}
Redis 配置(可选)
{
"Redis": {
"IsEnabled": false,
"Configuration": "127.0.0.1:6379,password=123,defaultDatabase=13",
"JobDb": 13
}
}
权限管理配置
{
"RbacOptions": {
"AdminPassword": "123456", // 默认管理员密码
"EnableCaptcha": false, // 是否启用验证码
"EnableRegister": false, // 是否允许注册
"EnableDataBaseBackup": false // 是否启用数据库备份
}
}
📚 更多文档
🎁 内置模块
- ✅ RBAC 权限管理系统 - 完整的用户权限管理
- ✅ 租户管理模块 - 多租户支持
- ✅ 审计日志模块 - 操作日志记录
- ✅ 设置管理模块 - 系统配置管理
🌟 特性
- ✅ 开箱即用:默认 SQLite,无需配置即可运行
- ✅ CodeFirst:自动创建数据库表结构
- ✅ 种子数据:自动初始化基础数据
- ✅ 动态 API:无需手写 Controller
- ✅ CRUD 基类:快速开发增删改查
- ✅ 权限控制:内置完整的权限管理
- ✅ 多租户:支持 SaaS 架构
- ✅ 模块化:功能模块化,按需引用
- ✅ 源码开放:框架源码直接提供,方便学习和二开
🔧 常见问题
Q: 如何切换数据库?
A: 修改 appsettings.json 中的 DbConnOptions 配置,设置 DbType 和 Url。
Q: 如何禁用 CodeFirst 自动建表?
A: 设置 EnabledCodeFirst: false,然后手动执行 SQL 脚本创建表。
Q: 如何添加新的业务模块?
A: 所有业务代码都应该在 module 目录下创建自己的模块。参考 antis-erp 模块的结构,创建包含 Domain.Shared、Domain、Application.Contracts、Application、SqlSugarCore 五个项目的模块,然后在 YiAbpWebModule.cs 中注册模块依赖和动态 API。
Q: 如何自定义 API 路由?
A: 在服务方法上使用 [Route("your-route")] 特性。
Q: 如何启用多租户?
A: 设置 EnabledSaasMultiTenancy: true,并在 Swagger 中使用 __tenant 参数指定租户。
📞 联系我们
- 官网:ccnetcore.com
- 演示地址:data.ccnetcore.com:2000(账号:admin / 密码:123456)
- QQ 群:981136525(官方五群)
- 微信:添加
chengzilaoge520(备注:拉群)
📄 许可证
本项目采用 MIT 许可证。
🙏 致谢
感谢以下开源项目: