From 0c329669a92d3a4650771a959f48ae8476bba73b Mon Sep 17 00:00:00 2001
From: MSuMshk <2039814060@qq.com>
Date: Wed, 3 Dec 2025 19:01:53 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E5=95=86=E6=88=B7=E7=B1=BB=E7=9B=AE?=
=?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93=E5=8C=96=E5=B9=B6=E5=A2=9E=E5=8A=A0?=
=?UTF-8?q?=E6=9D=83=E9=99=90=E7=A7=8D=E5=AD=90?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Document/12_BusinessTodo.md | 4 +-
.../MerchantCategoriesController.cs | 74 +++++++++
.../Controllers/MerchantsController.cs | 145 +++++++++++++++++-
.../appsettings.Development.json | 2 +-
.../appsettings.Production.json | 2 +-
.../appsettings.Seed.Development.json | 14 +-
.../Commands/AddMerchantDocumentCommand.cs | 18 +++
.../Commands/CreateMerchantCategoryCommand.cs | 13 ++
.../Commands/CreateMerchantContractCommand.cs | 16 ++
.../Commands/DeleteMerchantCategoryCommand.cs | 9 ++
.../ReorderMerchantCategoriesCommand.cs | 18 +++
.../Commands/ReviewMerchantCommand.cs | 13 ++
.../Commands/ReviewMerchantDocumentCommand.cs | 14 ++
.../UpdateMerchantContractStatusCommand.cs | 17 ++
.../App/Merchants/Dto/MerchantAuditLogDto.cs | 27 ++++
.../App/Merchants/Dto/MerchantCategoryDto.cs | 34 ++++
.../App/Merchants/Dto/MerchantContractDto.cs | 33 ++++
.../App/Merchants/Dto/MerchantDetailDto.cs | 24 +++
.../App/Merchants/Dto/MerchantDocumentDto.cs | 33 ++++
.../AddMerchantDocumentCommandHandler.cs | 76 +++++++++
.../CreateMerchantCategoryCommandHandler.cs | 49 ++++++
.../CreateMerchantContractCommandHandler.cs | 78 ++++++++++
.../DeleteMerchantCategoryCommandHandler.cs | 33 ++++
.../GetMerchantAuditLogsQueryHandler.cs | 35 +++++
.../GetMerchantCategoriesQueryHandler.cs | 34 ++++
.../GetMerchantContractsQueryHandler.cs | 32 ++++
.../Handlers/GetMerchantDetailQueryHandler.cs | 38 +++++
.../GetMerchantDocumentsQueryHandler.cs | 32 ++++
.../ListMerchantCategoriesQueryHandler.cs | 27 ++++
...ReorderMerchantCategoriesCommandHandler.cs | 42 +++++
.../Handlers/ReviewMerchantCommandHandler.cs | 74 +++++++++
.../ReviewMerchantDocumentCommandHandler.cs | 69 +++++++++
...ateMerchantContractStatusCommandHandler.cs | 76 +++++++++
.../App/Merchants/MerchantMapping.cs | 84 ++++++++++
.../Queries/GetMerchantAuditLogsQuery.cs | 13 ++
.../Queries/GetMerchantCategoriesQuery.cs | 9 ++
.../Queries/GetMerchantContractsQuery.cs | 10 ++
.../Queries/GetMerchantDetailQuery.cs | 9 ++
.../Queries/GetMerchantDocumentsQuery.cs | 10 ++
.../Queries/ListMerchantCategoriesQuery.cs | 10 ++
.../Merchants/Entities/MerchantAuditLog.cs | 40 +++++
.../Merchants/Entities/MerchantCategory.cs | 24 +++
.../Merchants/Enums/MerchantAuditAction.cs | 37 +++++
.../IMerchantCategoryRepository.cs | 47 ++++++
.../Repositories/IMerchantRepository.cs | 14 ++
.../AppServiceCollectionExtensions.cs | 1 +
.../App/Persistence/TakeoutAppDbContext.cs | 25 +++
.../EfMerchantCategoryRepository.cs | 68 ++++++++
.../App/Repositories/EfMerchantRepository.cs | 46 ++++++
49 files changed, 1646 insertions(+), 6 deletions(-)
create mode 100644 src/Api/TakeoutSaaS.AdminApi/Controllers/MerchantCategoriesController.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Commands/AddMerchantDocumentCommand.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Commands/CreateMerchantCategoryCommand.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Commands/CreateMerchantContractCommand.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Commands/DeleteMerchantCategoryCommand.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Commands/ReorderMerchantCategoriesCommand.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Commands/ReviewMerchantCommand.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Commands/ReviewMerchantDocumentCommand.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Commands/UpdateMerchantContractStatusCommand.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Dto/MerchantAuditLogDto.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Dto/MerchantCategoryDto.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Dto/MerchantContractDto.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Dto/MerchantDetailDto.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Dto/MerchantDocumentDto.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Handlers/AddMerchantDocumentCommandHandler.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Handlers/CreateMerchantCategoryCommandHandler.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Handlers/CreateMerchantContractCommandHandler.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Handlers/DeleteMerchantCategoryCommandHandler.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Handlers/GetMerchantAuditLogsQueryHandler.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Handlers/GetMerchantCategoriesQueryHandler.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Handlers/GetMerchantContractsQueryHandler.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Handlers/GetMerchantDetailQueryHandler.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Handlers/GetMerchantDocumentsQueryHandler.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Handlers/ListMerchantCategoriesQueryHandler.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Handlers/ReorderMerchantCategoriesCommandHandler.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Handlers/ReviewMerchantCommandHandler.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Handlers/ReviewMerchantDocumentCommandHandler.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Handlers/UpdateMerchantContractStatusCommandHandler.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/MerchantMapping.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Queries/GetMerchantAuditLogsQuery.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Queries/GetMerchantCategoriesQuery.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Queries/GetMerchantContractsQuery.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Queries/GetMerchantDetailQuery.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Queries/GetMerchantDocumentsQuery.cs
create mode 100644 src/Application/TakeoutSaaS.Application/App/Merchants/Queries/ListMerchantCategoriesQuery.cs
create mode 100644 src/Domain/TakeoutSaaS.Domain/Merchants/Entities/MerchantAuditLog.cs
create mode 100644 src/Domain/TakeoutSaaS.Domain/Merchants/Entities/MerchantCategory.cs
create mode 100644 src/Domain/TakeoutSaaS.Domain/Merchants/Enums/MerchantAuditAction.cs
create mode 100644 src/Domain/TakeoutSaaS.Domain/Merchants/Repositories/IMerchantCategoryRepository.cs
create mode 100644 src/Infrastructure/TakeoutSaaS.Infrastructure/App/Repositories/EfMerchantCategoryRepository.cs
diff --git a/Document/12_BusinessTodo.md b/Document/12_BusinessTodo.md
index ca1a132..5eaadc5 100644
--- a/Document/12_BusinessTodo.md
+++ b/Document/12_BusinessTodo.md
@@ -6,8 +6,8 @@
## Phase 1(当前阶段):租户/商家入驻、门店与菜品、扫码堂食、基础下单支付、预购自提、第三方配送骨架
- [x] 管理端租户 API:注册、实名认证、套餐订阅/续费/升降配、审核流,Swagger ≥6 个端点,含审核日志。
- 已交付:`src/Api/TakeoutSaaS.AdminApi/Controllers/TenantsController.cs` 暴露注册、详情、实名提交、审核、订阅创建/升降配、审核日志 8 个端点;对应命令/查询位于 `src/Application/TakeoutSaaS.Application/App/Tenants`,仓储实现 `EfTenantRepository`,并写入 `TenantAuditLog` 记录。Swagger 自动收录上述接口,满足 Phase1 租户管理要求。
-- [ ] 商家入驻 API:证照上传、合同管理、类目选择,驱动待审/审核/驳回/通过状态机,文件持久在 COS。
- - 当前:`MerchantsController` 只暴露基础 CRUD(`src/Api/TakeoutSaaS.AdminApi/Controllers/MerchantsController.cs:21-88`),缺少证照/合同上传、COS 存储与状态机端点。
+- [x] 商家入驻 API:证照上传、合同管理、类目选择,驱动待审/审核/驳回/通过状态机,文件持久在 COS。
+ - 已交付:`src/Api/TakeoutSaaS.AdminApi/Controllers/MerchantsController.cs` 新增证照上传/审核、合同创建与状态更新、商户审核、审核日志、类目列表等 8 个端点;应用层新增 `AddMerchantDocumentCommand`、`CreateMerchantContractCommand`、`ReviewMerchantCommand` 等 Handler;`MerchantDocument/Contract/Audit` DTO 完整返回详情,文件 URL 仍通过 `/api/admin/v1/files/upload` 上 COS。仓储实现扩展 `EfMerchantRepository` 支持文档/合同/AuditLog 持久化,`TakeoutAppDbContext` 新增 `merchant_audit_logs` 表实现状态机追踪。
- [ ] RBAC 模板:平台管理员、租户管理员、店长、店员四角色模板;API 可复制并允许租户自定义扩展。
- 当前:`RolesController`/`PermissionsController` 已提供角色与权限 CRUD(`src/Api/TakeoutSaaS.AdminApi/Controllers/RolesController.cs:16-88`、`.../PermissionsController.cs:16-63`),但没有“模板复制”或按租户批量初始化的接口。
- [ ] 配额与套餐:TenantPackage CRUD、订阅/续费/配额校验(门店/账号/短信/配送单量),超额返回 409 并记录 TenantQuotaUsage。
diff --git a/src/Api/TakeoutSaaS.AdminApi/Controllers/MerchantCategoriesController.cs b/src/Api/TakeoutSaaS.AdminApi/Controllers/MerchantCategoriesController.cs
new file mode 100644
index 0000000..72684f0
--- /dev/null
+++ b/src/Api/TakeoutSaaS.AdminApi/Controllers/MerchantCategoriesController.cs
@@ -0,0 +1,74 @@
+using System.Collections.Generic;
+using MediatR;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using TakeoutSaaS.Application.App.Merchants.Commands;
+using TakeoutSaaS.Application.App.Merchants.Dto;
+using TakeoutSaaS.Application.App.Merchants.Queries;
+using TakeoutSaaS.Module.Authorization.Attributes;
+using TakeoutSaaS.Shared.Abstractions.Constants;
+using TakeoutSaaS.Shared.Abstractions.Results;
+using TakeoutSaaS.Shared.Web.Api;
+
+namespace TakeoutSaaS.AdminApi.Controllers;
+
+///
+/// 商户类目管理。
+///
+[ApiVersion("1.0")]
+[Authorize]
+[Route("api/admin/v{version:apiVersion}/merchant-categories")]
+public sealed class MerchantCategoriesController(IMediator mediator) : BaseApiController
+{
+ ///
+ /// 列出所有类目。
+ ///
+ [HttpGet]
+ [PermissionAuthorize("merchant_category:read")]
+ [ProducesResponseType(typeof(ApiResponse>), StatusCodes.Status200OK)]
+ public async Task>> List(CancellationToken cancellationToken)
+ {
+ var result = await mediator.Send(new ListMerchantCategoriesQuery(), cancellationToken);
+ return ApiResponse>.Ok(result);
+ }
+
+ ///
+ /// 新增类目。
+ ///
+ [HttpPost]
+ [PermissionAuthorize("merchant_category:create")]
+ [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)]
+ public async Task> Create([FromBody] CreateMerchantCategoryCommand command, CancellationToken cancellationToken)
+ {
+ var result = await mediator.Send(command, cancellationToken);
+ return ApiResponse.Ok(result);
+ }
+
+ ///
+ /// 删除类目。
+ ///
+ [HttpDelete("{categoryId:long}")]
+ [PermissionAuthorize("merchant_category:delete")]
+ [ProducesResponseType(typeof(ApiResponse