# zssport1 **Repository Path**: llisten1421/zssport1 ## Basic Information - **Project Name**: zssport1 - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-03 - **Last Updated**: 2026-07-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ZSSport ZSSport 是一个基于 ASP.NET Core 的 Web API 项目,使用 SqlSugar 访问 MySQL,使用 Scalar 展示接口文档,项目启动时会根据 `Models` 类库中带 `[SugarTable]` 的实体自动创建数据库表。 本文档面向新加入项目的开发同学,重点说明项目结构、开发约定,以及如何编写一个新接口。 ## 项目结构 ```text ZSSport ├─ ZSSport.slnx # 解决方案文件 ├─ ZSSport # Web API 主项目 │ ├─ Controllers # 接口控制器 │ │ ├─ ApiControllerBase.cs # API 控制器基类,统一路由、鉴权和返回格式 │ │ └─ ExampleController.cs # 示例增删改查接口 │ ├─ Models # 接口请求参数 DTO,不放数据库实体 │ │ └─ ExampleInputs.cs # 示例接口请求参数 │ ├─ Extentions # 项目启动、服务注册、JWT、数据库初始化扩展 │ │ ├─ Extension.ServiceCollection.cs │ │ ├─ Extension.Database.cs │ │ └─ Extension.Jwt.cs │ ├─ appsettings.json # 配置文件,包含数据库连接、JWT、跨域等配置 │ └─ Program.cs # 应用启动入口 ├─ Models # 数据库实体类库 │ └─ ExampleInfo.cs # 示例数据库实体 └─ Shared # 公共类库 ├─ Primitives # 统一响应模型 ├─ Filters # JWT 过滤器等 ├─ Exceptions # 全局异常处理 ├─ Extensions # Serilog、跨域、静态文件等扩展 ├─ Helper # 工具 Helper └─ Util # 通用工具类 ``` ## 运行环境 - .NET 10 - MySQL - SqlSugarCore - Scalar.AspNetCore - Serilog 数据库连接在 `ZSSport/appsettings.json`: ```json { "ConnectionStrings": { "DefaultConnection": "Server=192.168.1.86;Port=3306;Database=zs_sport;Uid=root;Pwd=你的密码;" } } ``` 启动项目后,开发环境会打开 OpenAPI/Scalar 文档: ```text /scalar ``` ## 重要约定 ### 1. Controller 必须继承 ApiControllerBase 所有业务接口 Controller 都放在 `ZSSport/Controllers` 下,并继承: ```csharp public class XxxController : ApiControllerBase ``` `ApiControllerBase` 已经统一配置: ```csharp [Route("api/[controller]/[Action]")] [ApiController] [Authorize] [JwtAuthorizeFilter] ``` 因此接口地址规则是: ```text api/控制器名/方法名 ``` 例如: ```text api/Example/GetList api/Example/Create ``` ### 2. 只使用 GET 和 POST 本项目接口只允许使用: ```csharp [HttpGet] [HttpPost] ``` 查询类接口使用 `GET`,新增、修改、删除使用 `POST`。 ### 3. POST 参数使用 [FromBody] POST 接口统一使用 JSON body: ```csharp public IActionResult Create([FromBody] ExampleCreateInput input) ``` 请求时必须设置: ```http Content-Type: application/json ``` 请求示例: ```json { "name": "测试", "remark": "备注" } ``` ### 4. 请求参数类放到 ZSSport/Models 接口请求参数 DTO 放在 `ZSSport/Models` 下,不要写在 Controller 文件底部。 命名建议: ```text XxxCreateInput XxxUpdateInput XxxDeleteInput XxxQueryInput ``` ### 5. 数据库实体放到 Models 类库 数据库表实体放在根目录的 `Models` 类库中。 只有带 `[SugarTable]` 的类才会被认为是数据库表实体,项目启动时才会参与自动建表。 ```csharp [SugarTable("example_info", "示例信息表")] public class ExampleInfo { [SugarColumn(IsPrimaryKey = true, IsIdentity = true, ColumnDescription = "主键编号")] public int Id { get; set; } } ``` ### 6. 表和字段必须写中文备注 实体类必须写: - XML 中文注释 - `[SugarTable]` 表备注 - `[SugarColumn]` 字段备注 这样接口文档和数据库都能看到清楚说明。 ### 7. 接口必须写中文 XML 注释 Controller、Action、参数类、参数属性都要写中文 XML 注释。 项目已开启 XML 文档生成,注释会进入接口文档。 ## 如何新增一个接口 下面以“商品”接口为例,演示完整开发流程。 ### 第一步:新增数据库实体 在 `Models` 类库中新建: ```text Models/ProductInfo.cs ``` 示例: ```csharp using SqlSugar; namespace Models; /// /// 商品信息 /// [SugarTable("product_info", "商品信息表")] public class ProductInfo { /// /// 主键编号 /// [SugarColumn(IsPrimaryKey = true, IsIdentity = true, ColumnDescription = "主键编号")] public int Id { get; set; } /// /// 商品名称 /// [SugarColumn(Length = 100, IsNullable = false, ColumnDescription = "商品名称")] public string Name { get; set; } = string.Empty; /// /// 商品价格 /// [SugarColumn(ColumnDescription = "商品价格")] public decimal Price { get; set; } /// /// 创建时间 /// [SugarColumn(ColumnDescription = "创建时间")] public DateTime CreateTime { get; set; } = DateTime.Now; } ``` 注意: - 必须有 `[SugarTable]` - 必须有表中文备注 - 每个字段建议都有 `[SugarColumn(ColumnDescription = "...")]` - 主键自增使用 `IsPrimaryKey = true, IsIdentity = true` ### 第二步:新增请求参数 DTO 在 `ZSSport/Models` 下新建: ```text ZSSport/Models/ProductInputs.cs ``` 示例: ```csharp namespace ZSSport.Models; /// /// 新增商品请求参数 /// public class ProductCreateInput { /// /// 商品名称 /// public string Name { get; set; } = string.Empty; /// /// 商品价格 /// public decimal Price { get; set; } } /// /// 修改商品请求参数 /// public class ProductUpdateInput : ProductCreateInput { /// /// 商品编号 /// public int Id { get; set; } } /// /// 删除商品请求参数 /// public class ProductDeleteInput { /// /// 商品编号 /// public int Id { get; set; } } ``` 注意: - DTO 只描述接口请求参数 - DTO 不要加 `[SugarTable]` - DTO 不要放进 `Models` 类库,否则容易和数据库实体混淆 ### 第三步:新增 Controller 在 `ZSSport/Controllers` 下新建: ```text ZSSport/Controllers/ProductController.cs ``` 示例: ```csharp using Models; using SqlSugar; using ZSSport.Models; namespace WebApi.Controllers; /// /// 商品管理 /// public class ProductController : ApiControllerBase { private readonly ISqlSugarClient _db; /// /// 初始化商品管理控制器 /// /// 日志组件 /// 数据库客户端 public ProductController(ILogger logger, ISqlSugarClient db) : base(logger) { _db = db; } /// /// 获取商品列表 /// /// 商品列表 [HttpGet] public IActionResult GetList() { var list = _db.Queryable() .OrderByDescending(item => item.Id) .ToList(); return Success(list); } /// /// 获取商品详情 /// /// 商品编号 /// 商品详情 [HttpGet] public IActionResult Get(int id) { var entity = _db.Queryable() .First(item => item.Id == id); if (entity is null) { return Error("数据不存在。"); } return Success(entity); } /// /// 新增商品 /// /// 新增商品请求参数 /// 操作结果 [HttpPost] public IActionResult Create([FromBody] ProductCreateInput input) { if (string.IsNullOrWhiteSpace(input.Name)) { return Error("商品名称不能为空。"); } var entity = new ProductInfo { Name = input.Name.Trim(), Price = input.Price, CreateTime = DateTime.Now }; _db.Insertable(entity).ExecuteCommand(); return Success("新增成功!"); } /// /// 修改商品 /// /// 修改商品请求参数 /// 操作结果 [HttpPost] public IActionResult Update([FromBody] ProductUpdateInput input) { if (input.Id <= 0) { return Error("商品编号无效。"); } if (string.IsNullOrWhiteSpace(input.Name)) { return Error("商品名称不能为空。"); } var rows = _db.Updateable() .SetColumns(item => item.Name == input.Name.Trim()) .SetColumns(item => item.Price == input.Price) .Where(item => item.Id == input.Id) .ExecuteCommand(); return rows > 0 ? Success("修改成功!") : Error("数据不存在。"); } /// /// 删除商品 /// /// 删除商品请求参数 /// 操作结果 [HttpPost] public IActionResult Delete([FromBody] ProductDeleteInput input) { if (input.Id <= 0) { return Error("商品编号无效。"); } var rows = _db.Deleteable() .Where(item => item.Id == input.Id) .ExecuteCommand(); return rows > 0 ? Success("删除成功!") : Error("数据不存在。"); } } ``` ### 第四步:确认接口地址 根据项目统一路由: ```csharp [Route("api/[controller]/[Action]")] ``` 商品接口地址为: ```text GET api/Product/GetList GET api/Product/Get?id=1 POST api/Product/Create POST api/Product/Update POST api/Product/Delete ``` ### 第五步:启动项目并检查接口文档 运行: ```bash dotnet build dotnet run --project ZSSport ``` 开发环境访问 Scalar 文档: ```text /scalar ``` 如果新增接口、参数说明没有显示: 1. 确认 Controller、Action、DTO、DTO 属性都有 `/// ` 2. 确认项目已重新编译 3. 重启项目 4. 刷新 Scalar 页面 ## 自动建库建表说明 项目启动时会执行: ```csharp app.UseModelsCodeFirst(); ``` 逻辑在: ```text ZSSport/Extentions/Extension.Database.cs ``` 规则: - 从 `DefaultConnection` 读取数据库连接字符串 - 如果数据库不存在,则自动创建 - 扫描 `Models` 类库 - 只有带 `[SugarTable]` 的实体才会自动建表 - 调用 SqlSugar CodeFirst 创建表 注意: - 普通 DTO 不要放到 `Models` 类库 - 不带 `[SugarTable]` 的类不会建表 - 已存在的表不一定会自动同步字段备注,必要时需要手动迁移或重建表 ## 统一返回格式 Controller 继承 `ApiControllerBase` 后,可以直接使用: ```csharp return Success(); return Success(data); return Success("操作成功!"); return Error("错误提示"); ``` 成功响应基础结构: ```json { "success": true, "responseTime": "2026-06-29 15:30:00", "code": 1, "msg": "请求成功!", "data": {} } ``` 失败响应基础结构: ```json { "success": false, "responseTime": "2026-06-29 15:30:00", "code": 0, "msg": "错误提示" } ``` ## 鉴权说明 `ApiControllerBase` 默认带: ```csharp [Authorize] [JwtAuthorizeFilter] ``` 所以业务接口默认需要 JWT。 如果某个接口临时允许匿名访问,可以在 Action 上加: ```csharp [AllowAnonymous] ``` 正式业务接口不要随意加匿名访问。 ## 日志说明 项目使用 Serilog: ```text Shared/Extensions/Extension.Serilog.cs ``` 日志输出到: - 控制台 - 本地日志文件 - MySQL 表 `log_serilogs` 首次启动时会自动创建日志表。 ## 新人开发检查清单 新增接口提交前,请逐项确认: - Controller 放在 `ZSSport/Controllers` - Controller 继承 `ApiControllerBase` - 只使用 `[HttpGet]` 或 `[HttpPost]` - POST 参数使用 `[FromBody]` - 请求 DTO 放在 `ZSSport/Models` - 数据库实体放在 `Models` 类库 - 数据库实体必须有 `[SugarTable]` - 表和字段都有中文备注 - Controller、Action、DTO、DTO 属性都有中文 XML 注释 - 返回值使用 `Success(...)` 或 `Error(...)` - 执行过 `dotnet build` - 在 Scalar 文档中确认接口说明和参数说明正常显示