README.md 16.8 KB

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 2022VS 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(默认,无需配置)
  • Mysql
  • Sqlserver
  • PostgreSQL
  • Oracle

第三步:启动后端

  1. 使用 Visual Studio 打开 Yi.Abp.Net8/Yi.Abp.sln
  2. 设置启动项目为 Yi.Abp.Web
  3. 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.cs
  • YourModuleDomainModule.cs
  • YourModuleApplicationContractsModule.cs
  • YourModuleApplicationModule.cs
  • YourModuleSqlSugarCoreModule.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 配置,设置 DbTypeUrl

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 许可证。


🙏 致谢

感谢以下开源项目:


**⭐ 如果这个项目对你有帮助,请给个 Star ⭐** Made with ❤️ by [Yi Framework Team](https://ccnetcore.com)