# 阶段五:后台能力底座、Worker 基座与运营闭环 状态:已完成第一轮底座实现并通过本地验收(2026-07-28)。 本阶段从核心 SaaS 架构重构进入后台运营能力补齐。目标不是逐字兼容旧 NestJS,而是在当前 ASP.NET Core + EF Core + PostgreSQL 架构下重建后台权限、菜单、审计、交易运营和 Worker 基座,并参考 yudao 的后台能力清单补齐系统底座。 ## 固定 SDK 选型 微信生态统一使用 Senparc: - `Senparc.Weixin` - `Senparc.Weixin.MP` - `Senparc.Weixin.WxOpen` - `Senparc.Weixin.TenPayV3` 已移除并禁止: - `SKIT.FlurlHttpClient.Wechat.*` 其他外部服务: - OSS:`AlibabaCloud.OSS.V2` - 阿里云短信:`AlibabaCloud.SDK.Dysmsapi20170525` - 支付宝:`AlipaySDKNet.Standard` - Worker:`Microsoft.Extensions.Hosting` + `BackgroundService` 业务层仍然只依赖 Application 接口: - `IIdentityProvider` - `IObjectStorageService` - `ISmsProvider` - `IPaymentProvider` - `INotificationProvider` 第三方 SDK namespace 只允许出现在 Infrastructure provider 实现中。 ## 5A:微信 Provider 收敛 `WechatPayProvider` 已切换到 `Senparc.Weixin.TenPayV3`: - JSAPI / H5 下单参数生成走 Senparc TenPayV3。 - JSAPI 前端支付参数使用 Senparc 签名 helper 生成。 - 支付 provider 继续通过 `IPaymentProvider` 暴露,不向 Application 或 API 泄漏 Senparc 类型。 - 架构测试禁止生产代码引用 `SKIT.FlurlHttpClient.Wechat`。 说明:当前 `IPaymentProvider` 的回调入口抽象为 body + headers,不直接暴露 `HttpContext`。Senparc 官方推荐的 `TenPayNotifyHandler(HttpContext)` 回调验签/解密模式后续可以在 Infrastructure 的 HTTP 适配层补强,但不能把 Senparc 类型扩散到业务层。 ## 5B:后台权限、菜单、角色与审计底座 新增后台基础模型: - `BackendPermission` - `BackendMenu` - `TenantBackendRole` - `TenantBackendRolePermission` - `TenantBackendRoleMenu` - `TenantBackendUserRole` - `PlatformBackendRole` - `PlatformBackendRolePermission` - `PlatformBackendRoleMenu` - `PlatformBackendUserRole` 设计边界: - 权限点是稳定字符串 code。 - 菜单只控制后台 UI 展示,不作为唯一 API 鉴权来源。 - 平台角色和租户角色分表。 - 租户角色绑定包含 `TenantId`,平台角色绑定不带租户键。 - 角色、权限、菜单、用户角色绑定写操作落 `AuditLog`。 新增接口: - `GET /api/backoffice/tenant/bootstrap` - `POST /api/backoffice/tenant/roles` - `PUT /api/backoffice/tenant/roles/{roleId}/bindings` - `PUT /api/backoffice/tenant/users/{userId}/roles` - `GET /api/backoffice/platform/bootstrap` - `POST /api/backoffice/platform/roles` - `PUT /api/backoffice/platform/roles/{roleId}/bindings` - `PUT /api/backoffice/platform/users/{userId}/roles` `TenantAdminDirect` 继续作为过渡入口;新增后台能力使用 `backoffice` 模块命名。 ## 5E:交易运营底座 在现有 commerce 模型上补齐租户后台运营服务: - 退款申请。 - 退款状态流转。 - 退款事件记录。 - 对账批次创建。 - 对账 issue 查询与状态流转。 - 退款、对账写操作落审计。 退款状态流转由服务控制,不能任意跳转。支付、回调、退款后续仍统一走 `IPaymentProvider`,初期不默认开启真实自动退款。 新增租户交易运营接口: - `GET /api/tenant-commerce/refunds` - `POST /api/tenant-commerce/refunds` - `POST /api/tenant-commerce/refunds/status` - `GET /api/tenant-commerce/refunds/{refundRequestId}/events` - `GET /api/tenant-commerce/reconciliation/batches` - `POST /api/tenant-commerce/reconciliation/batches` - `GET /api/tenant-commerce/reconciliation/issues` - `POST /api/tenant-commerce/reconciliation/issues/status` ## 5F:Worker 与后台任务基座 新增统一任务模型 `BackgroundJob`: - `JobType` - `TenantId` - `Payload` - `Status` - `RetryCount` - `MaxRetries` - `LockedBy` - `LockExpiresAt` - `RunAfter` - `StartedAt` - `CompletedAt` - `LastError` - `OutputAssetId` - `Result` Worker 基于 `Microsoft.Extensions.Hosting` + `BackgroundService`,暂不引入 Hangfire。后续需要复杂 cron 时再评估 `Quartz.Extensions.Hosting`。 当前任务处理器建立了幂等租户 Scope 入口和状态机骨架,覆盖以下 job type: - `content_export` - `content_import` - `asset_security_scan` - `statistics_aggregation` - `commerce_reconciliation` - `tenant_domain_recheck` 新增租户后台任务接口: - `GET /api/backoffice/tenant/jobs` - `POST /api/backoffice/tenant/jobs` API 只负责创建任务和查询任务;Worker 必须通过 `ITenantExecutionScope` 初始化执行上下文。 ## 阿里云短信 Provider `ISmsProvider` 默认接入租户 Provider 配置: - 未配置短信 provider 时,本地/测试降级为 `noop`。 - 配置 `aliyun_sms` 时,从 `TenantExternalProvider(capability=sms)` 读取公开配置。 - `signName`、`templateCode`、`endpoint`、`regionId` 等公开字段放 `ConfigPublic`。 - `accessKeyId`、`accessKeySecret` 只允许通过 `TenantSecret` 解密获得。 - 发送失败会记录 `SmsVerificationStatus.Failed`,不会留下可验证验证码。 ## 数据库约束补强 阶段五重建 `InitialSchema` 时同步补齐阶段三遗漏的两个 PostgreSQL 硬约束: - `TenantQuestionReference` 只能引用平台主体公共题或当前租户私题。 - `TaxonomyNode` 父节点只能属于平台主体或当前租户。 这类跨表租户不变量不能靠 EF Core FK / check constraint 自动表达,统一放在 `PostgreSqlTenantConstraintSql`,由 migration 调用,并由真实 PostgreSQL 集成测试覆盖。 ## 架构测试 新增或强化禁止项: - 生产代码不得引用 `SKIT.FlurlHttpClient.Wechat`。 - 业务层不得直接引用阿里云 OSS、阿里云短信、Senparc、支付宝 SDK namespace。 - 生产代码不得回流 Supabase provider、Supabase Storage 或旧专用 provider 表模型。 - 普通业务目录继续禁止 `IgnoreQueryFilters`、`FromSql`、`ExecuteSql` 和直接 `NpgsqlCommand`。 ## 验收结果 本阶段本地验收: ```bash dotnet restore TIKU-BACKEND.slnx dotnet build TIKU-BACKEND.slnx --no-restore dotnet test Tiku.UnitTests/Tiku.UnitTests.csproj --no-build dotnet test Tiku.IntegrationTests/Tiku.IntegrationTests.csproj --no-build dotnet ef migrations script --project Tiku.Infrastructure --startup-project Tiku.DbMigrator git diff --check ``` 结果: - build:0 警告,0 错误。 - unit tests:18/18 通过。 - integration tests:264/264 通过。 - migration script:生成成功。 - 空 PostgreSQL 通过 `Tiku.DbMigrator` 建库成功。 - PostgreSQL 验证两个租户约束 trigger 已创建。