Compare commits
10 Commits
c06773499d
...
de7aefd0ff
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de7aefd0ff | ||
|
|
657849a5f7 | ||
|
|
935fd7a997 | ||
|
|
220b98da8f | ||
|
|
61ecc5dc98 | ||
|
|
2f508d7b52 | ||
|
|
e962798f46 | ||
|
|
b998772451 | ||
|
|
ed6142f00d | ||
|
|
f8cd408fc5 |
@@ -2,28 +2,32 @@
|
||||
|
||||
> 目的:明确 Admin/User/Mini 三个 API 的职责边界,避免跨端耦合。开发新接口或改动现有控制器时请对照自检,确保租户、安全、DTO、路由符合约定。
|
||||
|
||||
> 说明:仓库已拆分为 `TakeoutSaaS.AdminApi`(管理后台)与 `TakeoutSaaS.TenantApi`(UserApi/MiniApi)。本文档只对边界与自检项作约束,控制器清单仅对 AdminApi 维护,其余端以各自仓库代码为准。
|
||||
|
||||
## 1. AdminApi(管理后台)
|
||||
- **面向对象**:运营、客服、商户管理员。
|
||||
- **职责**:租户/门店/商品/订单/支付/配送/字典/权限/RBAC/审计/任务调度等后台管理与洞察。
|
||||
- **鉴权**:JWT + RBAC(`[Authorize]` + `PermissionAuthorize`),租户头不再强制(单租户操作以路由 `tenantId` 为准)。
|
||||
- **归属仓库**:`TakeoutSaaS.AdminApi`
|
||||
- **面向对象**:平台运营、客服、内部管理。
|
||||
- **职责**:商户/门店/商品/订单/支付/配送/字典/权限/RBAC/审计/系统参数等后台管理与洞察。
|
||||
- **鉴权**:JWT + RBAC(`[Authorize]` + `PermissionAuthorize`);**不强制租户头**,AdminApi 默认不做租户隔离(内部工具允许跨租户查询)。如需限定租户,请在路由/参数中显式指定 `tenantId` 并在应用层校验。
|
||||
- **路由前缀**:`api/admin/v{version}/...`。
|
||||
- **DTO/约束**:仅管理字段,禁止返回 C 端敏感信息;long -> string;严禁实体直接返回。
|
||||
- **现有控制器**:`AuthController`、`DeliveriesController`、`DictionaryController`、`FilesController`、`MerchantsController`、`OrdersController`、`PaymentsController`、`PermissionsController`、`RolesController`、`StoresController`、`SystemParametersController`、`TenantPackagesController`、`TenantsController`、`TenantBillingsController`、`TenantAnnouncementsController`、`TenantNotificationsController`、`UserPermissionsController`、`HealthController`。
|
||||
- **现有控制器(以仓库代码为准)**:`AuthController`、`CacheMetricsController`、`DeliveriesController`、`DictionaryController`、`DictionaryGroupsController`、`DictionaryItemsController`、`DictionaryLabelOverridesController`、`FilesController`、`HealthController`、`InventoryController`、`MenusController`、`MerchantCategoriesController`、`MerchantsController`、`OrdersController`、`PaymentsController`、`PermissionsController`、`ProductsController`、`RoleTemplatesController`、`StoreAuditsController`、`StorePickupController`、`StoreQualificationsController`、`StoreShiftsController`、`StoreStaffsController`、`StoreTableAreasController`、`StoreTablesController`、`StoresController`、`SystemParametersController`、`UsersController`。
|
||||
- **自检清单**:
|
||||
1. 是否需要权限/租户过滤?未加则补 `[Authorize]` + 租户解析。
|
||||
1. 是否需要权限校验?未加则补 `[Authorize]` + `PermissionAuthorize`(内部只读工具也至少需要 `[Authorize]`,避免误暴露)。
|
||||
2. 是否调用了应用层 CQRS,而非在 Controller 写业务?
|
||||
3. DTO 是否按管理口径,未暴露用户端字段?
|
||||
4. 是否使用参数化/AsNoTracking/投影,避免 N+1?
|
||||
5. 路由和 Swagger 示例是否含租户/权限说明?
|
||||
- **自检记录**:RolesController 新增模板列表/详情/复制/初始化端点,均已套用 `[Authorize]` + `PermissionAuthorize`、仅调用 CQRS/DTO,依赖租户头隔离。TenantPackagesController 与 TenantsController(配额校验) 均使用权限码、DTO 映射,配额校验要求携带租户头防越权。新增租户账单/公告/通知控制器,全部采用 CQRS、权限校验与租户参数,列表分页、未暴露实体。
|
||||
5. 路由和 Swagger 示例是否明确权限含义(AdminApi 不要求租户头)?
|
||||
- **自检记录**:已移除租户侧控制器(如 `TenantsController`、`TenantPackagesController`、`TenantBillingsController` 等)。`UsersController` 仅管理平台管理员账号(`Portal=Admin` 且 `TenantId=null`),不做租户侧兼容/兜底。
|
||||
|
||||
## 2. UserApi(C 端用户)
|
||||
- **归属仓库**:`TakeoutSaaS.TenantApi`
|
||||
- **面向对象**:App/H5 普通用户。
|
||||
- **职责**:菜单浏览、下单、支付、评价、地址、售后、订单查询、支付/配送回调(验证签名)等用户闭环。
|
||||
- **鉴权**:用户 JWT,租户隔离;幂等接口需校验。
|
||||
- **路由前缀**:`api/user/v{version}/...`。
|
||||
- **DTO/约束**:仅用户侧可见字段,屏蔽后台配置字段;long -> string。
|
||||
- **现有控制器**:当前仅 `HealthController`(业务接口待补)。
|
||||
- **现有控制器**:以 `TakeoutSaaS.TenantApi` 仓库为准(此处不维护清单,避免与代码偏差)。
|
||||
- **自检清单**:
|
||||
1. 是否暴露给用户的纯前台功能?后台配置请放 AdminApi。
|
||||
2. 是否做租户隔离、用户鉴权、签名/幂等校验?
|
||||
@@ -32,12 +36,13 @@
|
||||
5. 回调路由是否验证签名/防重放?
|
||||
|
||||
## 3. MiniApi(小程序端)
|
||||
- **归属仓库**:`TakeoutSaaS.TenantApi`
|
||||
- **面向对象**:微信/小程序前端。
|
||||
- **职责**:小程序登录/刷新、当前用户档案、订阅消息、直传凭证、小程序场景特定的下单/浏览等。
|
||||
- **鉴权**:小程序登录态/Token,租户隔离;必要时区分渠道。
|
||||
- **路由前缀**:`api/mini/v{version}/...`。
|
||||
- **DTO/约束**:遵循小程序接口规范,错误码与前端对齐;long -> string。
|
||||
- **现有控制器**:`AuthController`、`MeController`、`FilesController`、`HealthController`。
|
||||
- **现有控制器**:以 `TakeoutSaaS.TenantApi` 仓库为准(此处不维护清单,避免与代码偏差)。
|
||||
- **自检清单**:
|
||||
1. 是否为小程序特有流程(code2session、订阅消息、直传等)?通用用户接口放 UserApi。
|
||||
2. 是否完成租户/鉴权校验,区分渠道标识?
|
||||
@@ -47,7 +52,7 @@
|
||||
|
||||
## 4. 共通约束
|
||||
- **分层**:Controller 仅做路由/DTO 转换,业务放 Application 层 Handler。
|
||||
- **租户**:所有写/读需租户过滤;严禁跨租户访问。
|
||||
- **租户**:TenantApi 必须强制租户隔离;AdminApi 作为内部平台工具默认允许跨租户查询,但必须受 RBAC 与审计约束。
|
||||
- **日志/观测**:TraceId/SpanId 已贯通;/metrics、/healthz 按服务暴露。
|
||||
- **命名**:输入 `XxxRequest`、输出 `XxxDto`;文件名与类名一致;布尔属性加 `Is/Has`。
|
||||
- **发布前检查**:运行 `dotnet build`,必要时补 Swagger 示例、单元测试(核心逻辑 100% 覆盖,服务 ≥70%)。
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
- **AdminApi** 通过 `git submodule` 引入:
|
||||
- `TakeoutSaaS.BuildingBlocks` → `TakeoutSaaS.BuildingBlocks/`
|
||||
- `TakeoutSaaS.Docs` → `TakeoutSaaS.Docs/`
|
||||
- `TakeoutSaaS.Gateway` → `src/Gateway/TakeoutSaaS.ApiGateway/`(网关独立仓库,暂以子模块形式挂回)
|
||||
- **TenantApi** 通过 `git submodule` 引入:
|
||||
- `TakeoutSaaS.BuildingBlocks` → `TakeoutSaaS.BuildingBlocks/`
|
||||
- `TakeoutSaaS.Docs` → `TakeoutSaaS.Docs/`
|
||||
- **Gateway** 保持独立仓库:不以子模块形式挂回 AdminApi/TenantApi(避免耦合与引用链)。
|
||||
|
||||
## 3. 克隆与初始化
|
||||
|
||||
@@ -30,6 +30,9 @@ git clone --recurse-submodules -b dev git@github.com:msumshk/TakeoutSaaS.AdminAp
|
||||
|
||||
# TenantApi
|
||||
git clone --recurse-submodules -b dev git@github.com:msumshk/TakeoutSaaS.TenantApi.git
|
||||
|
||||
# Gateway
|
||||
git clone -b dev git@github.com:msumshk/TakeoutSaaS.Gateway.git
|
||||
```
|
||||
|
||||
### 3.2 已有仓库补齐子模块
|
||||
@@ -62,16 +65,15 @@ git submodule update --remote --merge
|
||||
## 5. 常用运行入口
|
||||
|
||||
```bash
|
||||
# AdminApi
|
||||
# AdminApi(在 TakeoutSaaS.AdminApi 仓库根目录)
|
||||
dotnet run --project src/Api/TakeoutSaaS.AdminApi/TakeoutSaaS.AdminApi.csproj
|
||||
|
||||
# TenantApi - MiniApi
|
||||
# TenantApi - MiniApi(在 TakeoutSaaS.TenantApi 仓库根目录)
|
||||
dotnet run --project src/Api/TakeoutSaaS.MiniApi/TakeoutSaaS.MiniApi.csproj
|
||||
|
||||
# TenantApi - UserApi
|
||||
# TenantApi - UserApi(在 TakeoutSaaS.TenantApi 仓库根目录)
|
||||
dotnet run --project src/Api/TakeoutSaaS.UserApi/TakeoutSaaS.UserApi.csproj
|
||||
|
||||
# Gateway(独立仓库)
|
||||
# Gateway(在 TakeoutSaaS.Gateway 仓库根目录)
|
||||
dotnet run --project TakeoutSaaS.ApiGateway.csproj
|
||||
```
|
||||
|
||||
|
||||
@@ -11,53 +11,7 @@
|
||||
"tags": [
|
||||
"Auth"
|
||||
],
|
||||
"summary": "登录获取 Token",
|
||||
"requestBody": {
|
||||
"description": "登录请求。",
|
||||
"content": {
|
||||
"application/json-patch+json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/AdminLoginRequest"
|
||||
}
|
||||
},
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/AdminLoginRequest"
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/AdminLoginRequest"
|
||||
}
|
||||
},
|
||||
"application/*+json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/AdminLoginRequest"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/TokenResponseApiResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/admin/v1/auth/login/simple": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Auth"
|
||||
],
|
||||
"summary": "免租户号登录(仅账号+密码)。",
|
||||
"description": "用于前端简化登录,无需额外传递租户号。",
|
||||
"summary": "账号名+手机号登录获取 Token",
|
||||
"requestBody": {
|
||||
"description": "登录请求。",
|
||||
"content": {
|
||||
@@ -8829,16 +8783,22 @@
|
||||
},
|
||||
"AdminLoginRequest": {
|
||||
"required": [
|
||||
"account",
|
||||
"accountName",
|
||||
"phone",
|
||||
"password"
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"account": {
|
||||
"accountName": {
|
||||
"maxLength": 64,
|
||||
"minLength": 1,
|
||||
"type": "string"
|
||||
},
|
||||
"phone": {
|
||||
"maxLength": 32,
|
||||
"minLength": 1,
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"maxLength": 128,
|
||||
"minLength": 1,
|
||||
@@ -19251,4 +19211,4 @@
|
||||
"description": "用户权限洞察接口。"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
376
Roadmap/01-功能清单.md
Normal file
376
Roadmap/01-功能清单.md
Normal file
@@ -0,0 +1,376 @@
|
||||
# TakeoutSaaS 功能清单
|
||||
|
||||
> 最后更新:2026-02-02
|
||||
|
||||
本文档列出整个 SaaS 外卖系统的所有功能模块,包括平台端、租户端、C端(小程序/App)。
|
||||
|
||||
---
|
||||
|
||||
## 一、平台管理端 (AdminApi + AdminUI)
|
||||
|
||||
平台运营方使用,管理所有租户、商户、系统配置等。
|
||||
|
||||
### 1. 身份认证与授权
|
||||
|
||||
| 功能 | 后端 | 前端 | 说明 |
|
||||
|------|:----:|:----:|------|
|
||||
| 平台用户登录 | ✅ | ✅ | 账号密码登录 |
|
||||
| JWT Token 刷新 | ✅ | ✅ | 无感刷新 |
|
||||
| 密码重置 | ✅ | ✅ | 通过重置链接 |
|
||||
| 用户信息获取 | ✅ | ✅ | 当前登录用户 |
|
||||
| 动态菜单加载 | ✅ | ✅ | 基于权限过滤 |
|
||||
|
||||
### 2. 用户管理
|
||||
|
||||
| 功能 | 后端 | 前端 | 说明 |
|
||||
|------|:----:|:----:|------|
|
||||
| 用户列表查询 | ✅ | ✅ | 分页、筛选 |
|
||||
| 用户详情 | ✅ | ✅ | 查看用户信息 |
|
||||
| 创建用户 | ✅ | ✅ | 新增平台用户 |
|
||||
| 编辑用户 | ✅ | ✅ | 修改用户信息 |
|
||||
| 删除/恢复用户 | ✅ | ✅ | 软删除 |
|
||||
| 用户状态变更 | ✅ | ✅ | 启用/禁用/解锁 |
|
||||
| 重置用户密码 | ✅ | ✅ | 生成重置链接 |
|
||||
| 批量操作 | ✅ | ✅ | 批量启用/禁用/删除/导出 |
|
||||
| 用户权限查询 | ✅ | ✅ | 查看用户权限列表 |
|
||||
|
||||
### 3. 角色权限管理
|
||||
|
||||
| 功能 | 后端 | 前端 | 说明 |
|
||||
|------|:----:|:----:|------|
|
||||
| 平台角色列表 | ✅ | ✅ | 分页查询 |
|
||||
| 创建角色 | ✅ | ✅ | 新增角色 |
|
||||
| 编辑角色 | ✅ | ✅ | 修改角色信息 |
|
||||
| 删除角色 | ✅ | ✅ | 删除角色 |
|
||||
| 角色权限配置 | ✅ | ✅ | 分配权限 |
|
||||
| 克隆角色 | ✅ | ✅ | 复制角色及权限 |
|
||||
| 权限树查询 | ✅ | ✅ | 按门户类型 |
|
||||
| 菜单管理 | ✅ | ✅ | 菜单CRUD |
|
||||
| 角色模板 | ✅ | ✅ | 预设角色模板 |
|
||||
|
||||
### 4. 租户管理
|
||||
|
||||
| 功能 | 后端 | 前端 | 说明 |
|
||||
|------|:----:|:----:|------|
|
||||
| 租户列表 | ✅ | ✅ | 分页、筛选 |
|
||||
| 创建租户 | ✅ | ✅ | 新增租户 |
|
||||
| 编辑租户 | ✅ | ✅ | 修改租户信息 |
|
||||
| 租户详情 | ✅ | ✅ | 查看租户详情 |
|
||||
| 租户审核 | ✅ | ✅ | 审核租户申请 |
|
||||
| 租户角色管理 | ✅ | ✅ | 管理租户内角色 |
|
||||
| 租户菜单配置 | ✅ | ✅ | 配置租户可用菜单 |
|
||||
| 租户冻结/解冻 | ✅ | ✅ | 冻结租户 |
|
||||
| 重置租户管理员 | ✅ | ✅ | 重置管理员密码 |
|
||||
| 租户模拟登录 | ✅ | ✅ | 模拟租户登录 |
|
||||
|
||||
### 5. 租户套餐
|
||||
|
||||
| 功能 | 后端 | 前端 | 说明 |
|
||||
|------|:----:|:----:|------|
|
||||
| 套餐列表 | ✅ | ✅ | 分页查询 |
|
||||
| 创建套餐 | ✅ | ✅ | 定义套餐内容 |
|
||||
| 编辑套餐 | ✅ | ✅ | 修改套餐 |
|
||||
| 套餐详情 | ✅ | ✅ | 查看套餐配置 |
|
||||
| 套餐发布/下架 | ✅ | ✅ | 控制套餐可见性 |
|
||||
| 功能策略配置 | ✅ | ✅ | JSON配置功能开关 |
|
||||
| 套餐配额配置 | ✅ | ✅ | 配额限制 |
|
||||
|
||||
### 6. 租户订阅管理
|
||||
|
||||
| 功能 | 后端 | 前端 | 说明 |
|
||||
|------|:----:|:----:|------|
|
||||
| 订阅列表 | ✅ | ✅ | 分页、多条件筛选 |
|
||||
| 订阅详情 | ✅ | ✅ | 查看订阅详情 |
|
||||
| 更新订阅 | ✅ | ✅ | 修改订阅信息 |
|
||||
| 延期订阅 | ✅ | ✅ | 延长订阅期限 |
|
||||
| 变更套餐 | ✅ | ✅ | 升级/降级套餐 |
|
||||
| 更新订阅状态 | ✅ | ✅ | 状态变更 |
|
||||
| 批量延期 | ✅ | ✅ | 批量操作 |
|
||||
| 到期提醒 | ✅ | ✅ | 批量提醒 |
|
||||
|
||||
### 7. 账单管理
|
||||
|
||||
| 功能 | 后端 | 前端 | 说明 |
|
||||
|------|:----:|:----:|------|
|
||||
| 账单列表 | ✅ | ✅ | 分页、多条件筛选 |
|
||||
| 账单详情 | ✅ | ✅ | 查看账单详情 |
|
||||
| 创建账单 | ✅ | ✅ | 手动创建账单 |
|
||||
| 确认收款 | ✅ | ✅ | 一键确认收款 |
|
||||
| 账单导出 | ✅ | ✅ | 导出账单 |
|
||||
| 账单统计 | ✅ | ✅ | 统计页面 |
|
||||
|
||||
### 8. 配额套餐
|
||||
|
||||
| 功能 | 后端 | 前端 | 说明 |
|
||||
|------|:----:|:----:|------|
|
||||
| 配额套餐列表 | ✅ | ✅ | 套餐管理 |
|
||||
| 配额套餐CRUD | ✅ | ✅ | 增删改查 |
|
||||
| 租户配额使用 | ✅ | ✅ | 使用情况 |
|
||||
| 购买配额 | ✅ | ✅ | 配额购买 |
|
||||
| 配额告警配置 | ✅ | ✅ | 告警设置 |
|
||||
|
||||
### 9. 商户管理
|
||||
|
||||
| 功能 | 后端 | 前端 | 说明 |
|
||||
|------|:----:|:----:|------|
|
||||
| 商户列表 | ✅ | ✅ | 分页、筛选 |
|
||||
| 创建商户 | ✅ | ✅ | 新增商户 |
|
||||
| 编辑商户 | ✅ | ✅ | 修改商户信息 |
|
||||
| 商户详情 | ✅ | ✅ | 查看商户详情 |
|
||||
| 商户审核 | ✅ | ✅ | 审核流程(认领/审批/驳回/撤销) |
|
||||
| 商户文档管理 | ✅ | ✅ | 上传/审核资质文档 |
|
||||
| 商户合同管理 | ✅ | ✅ | 合同CRUD |
|
||||
| 审计历史 | ✅ | ✅ | 操作记录 |
|
||||
| 变更历史 | ✅ | ✅ | 字段变更记录 |
|
||||
| 导出PDF | ✅ | ✅ | 商户资料导出 |
|
||||
| 商户分类 | ✅ | ✅ | 分类管理 |
|
||||
| 商户员工 | ✅ | ✅ | 员工管理 |
|
||||
|
||||
### 10. 门店管理
|
||||
|
||||
| 功能 | 后端 | 前端 | 说明 |
|
||||
|------|:----:|:----:|------|
|
||||
| 门店列表 | ✅ | ✅ | 分页、筛选 |
|
||||
| 创建门店 | ✅ | ✅ | 新增门店 |
|
||||
| 编辑门店 | ✅ | ✅ | 修改门店信息 |
|
||||
| 门店详情 | ✅ | ✅ | 查看门店详情 |
|
||||
| 门店审核 | ✅ | ✅ | 提交审核 |
|
||||
| 营业状态切换 | ✅ | ✅ | 开业/歇业 |
|
||||
| 门店资质管理 | ✅ | ✅ | 资质CRUD、完整性检查 |
|
||||
| 营业时间管理 | ✅ | ✅ | 营业时间CRUD、批量更新 |
|
||||
| 配送区域管理 | ✅ | ✅ | 配送区域CRUD、覆盖检查 |
|
||||
| 门店费用配置 | ✅ | ✅ | 配送费、包装费等 |
|
||||
| 节假日管理 | ✅ | ✅ | 特殊营业时间 |
|
||||
| 门店员工管理 | ✅ | ✅ | 员工CRUD |
|
||||
| 桌台区域管理 | ✅ | ✅ | 堂食桌台 |
|
||||
| 班次管理 | ✅ | ✅ | 员工排班 |
|
||||
| 自提配置 | ✅ | ✅ | 自提点设置 |
|
||||
| 门店审计日志 | ✅ | ✅ | 操作记录 |
|
||||
|
||||
### 11. 商品管理
|
||||
|
||||
| 功能 | 后端 | 前端 | 说明 |
|
||||
|------|:----:|:----:|------|
|
||||
| 商品列表 | ✅ | ✅ | 分页、筛选 |
|
||||
| 创建商品 | ✅ | ✅ | 新增商品 |
|
||||
| 编辑商品 | ✅ | ✅ | 修改商品信息 |
|
||||
| 商品详情 | ✅ | ✅ | 查看商品详情 |
|
||||
| 商品上下架 | ✅ | ✅ | 发布/下架 |
|
||||
| SKU管理 | ✅ | ✅ | 规格管理 |
|
||||
| 商品属性 | ✅ | ✅ | 属性管理 |
|
||||
| 加料管理 | ✅ | ✅ | 加料选项 |
|
||||
| 商品媒体 | ✅ | ✅ | 图片/视频 |
|
||||
| 定价规则 | ✅ | ✅ | 价格策略 |
|
||||
| 商品分类 | ✅ | ✅ | 分类管理 |
|
||||
|
||||
### 12. 订单管理
|
||||
|
||||
| 功能 | 后端 | 前端 | 说明 |
|
||||
|------|:----:|:----:|------|
|
||||
| 订单列表 | ✅ | ✅ | 分页、筛选 |
|
||||
| 订单详情 | ✅ | ✅ | 查看订单详情 |
|
||||
| 创建订单 | ✅ | ✅ | 后台创建 |
|
||||
| 编辑订单 | ✅ | ✅ | 修改订单 |
|
||||
| 删除订单 | ✅ | ✅ | 删除订单 |
|
||||
| 订单状态流转 | ⚠️ | ⚠️ | 基础完成,待完善状态机 |
|
||||
|
||||
### 13. 配送管理
|
||||
|
||||
| 功能 | 后端 | 前端 | 说明 |
|
||||
|------|:----:|:----:|------|
|
||||
| 配送单列表 | ✅ | ✅ | 分页查询 |
|
||||
| 配送单详情 | ✅ | ✅ | 查看详情 |
|
||||
| 创建配送单 | ✅ | ✅ | 创建配送 |
|
||||
| 更新配送单 | ✅ | ✅ | 更新状态 |
|
||||
| 删除配送单 | ✅ | ✅ | 删除配送 |
|
||||
|
||||
### 14. 支付管理
|
||||
|
||||
| 功能 | 后端 | 前端 | 说明 |
|
||||
|------|:----:|:----:|------|
|
||||
| 支付记录列表 | ✅ | ✅ | 分页查询 |
|
||||
| 支付详情 | ✅ | ✅ | 查看详情 |
|
||||
| 创建支付记录 | ✅ | ✅ | 创建记录 |
|
||||
| 更新支付记录 | ✅ | ✅ | 更新状态 |
|
||||
| 删除支付记录 | ✅ | ✅ | 删除记录 |
|
||||
|
||||
### 15. 库存管理
|
||||
|
||||
| 功能 | 后端 | 前端 | 说明 |
|
||||
|------|:----:|:----:|------|
|
||||
| 库存列表 | ✅ | ✅ | 查询库存 |
|
||||
| 库存锁定 | ✅ | ✅ | 下单锁定 |
|
||||
| 库存扣减 | ✅ | ✅ | 支付扣减 |
|
||||
| 库存调整 | ✅ | ✅ | 手动调整 |
|
||||
| 库存释放 | ✅ | ✅ | 取消释放 |
|
||||
| 库存批次 | ✅ | ✅ | 批次管理 |
|
||||
|
||||
### 16. 字典与参数
|
||||
|
||||
| 功能 | 后端 | 前端 | 说明 |
|
||||
|------|:----:|:----:|------|
|
||||
| 字典分组管理 | ✅ | ✅ | 分组CRUD |
|
||||
| 字典条目管理 | ✅ | ✅ | 条目CRUD |
|
||||
| 批量获取字典 | ✅ | ✅ | 带缓存 |
|
||||
| 标签覆盖 | ✅ | ✅ | 多语言/租户定制 |
|
||||
| 系统参数 | ✅ | ✅ | 系统配置 |
|
||||
| 缓存指标 | ✅ | ✅ | 缓存监控 |
|
||||
|
||||
### 17. 文件管理
|
||||
|
||||
| 功能 | 后端 | 前端 | 说明 |
|
||||
|------|:----:|:----:|------|
|
||||
| 文件上传 | ✅ | ✅ | 图片/文档上传 |
|
||||
| 文件分类 | ✅ | ✅ | 按类型分类 |
|
||||
|
||||
### 18. 营销活动
|
||||
|
||||
| 功能 | 后端 | 前端 | 说明 |
|
||||
|------|:----:|:----:|------|
|
||||
| 活动管理 | ⚠️ | ✅ | 前端页面有,后端待验证 |
|
||||
| 渠道管理 | ⚠️ | ✅ | 前端页面有,后端待验证 |
|
||||
| 邀请管理 | ⚠️ | ✅ | 前端页面有,后端待验证 |
|
||||
|
||||
### 19. 财务结算
|
||||
|
||||
| 功能 | 后端 | 前端 | 说明 |
|
||||
|------|:----:|:----:|------|
|
||||
| 佣金管理 | ⚠️ | ✅ | 前端页面有,后端待验证 |
|
||||
| 发票管理 | ⚠️ | ✅ | 前端页面有,后端待验证 |
|
||||
| 对账管理 | ⚠️ | ✅ | 前端页面有,后端待验证 |
|
||||
| 收入统计 | ⚠️ | ✅ | 前端页面有,后端待验证 |
|
||||
|
||||
### 20. 内容管理
|
||||
|
||||
| 功能 | 后端 | 前端 | 说明 |
|
||||
|------|:----:|:----:|------|
|
||||
| Banner管理 | ⚠️ | ✅ | 前端页面有,后端待验证 |
|
||||
| 公告管理 | ✅ | ✅ | 租户公告 |
|
||||
| 推送通知 | ⚠️ | ✅ | 前端页面有,后端待验证 |
|
||||
| 版本管理 | ⚠️ | ✅ | 前端页面有,后端待验证 |
|
||||
|
||||
### 21. 风控管理
|
||||
|
||||
| 功能 | 后端 | 前端 | 说明 |
|
||||
|------|:----:|:----:|------|
|
||||
| 黑名单管理 | ⚠️ | ✅ | 前端页面有,后端待验证 |
|
||||
| 风控规则 | ⚠️ | ✅ | 前端页面有,后端待验证 |
|
||||
| 敏感词过滤 | ⚠️ | ✅ | 前端页面有,后端待验证 |
|
||||
|
||||
### 22. 客服工单
|
||||
|
||||
| 功能 | 后端 | 前端 | 说明 |
|
||||
|------|:----:|:----:|------|
|
||||
| FAQ管理 | ⚠️ | ✅ | 前端页面有,后端待验证 |
|
||||
| 用户反馈 | ⚠️ | ✅ | 前端页面有,后端待验证 |
|
||||
| 工单系统 | ⚠️ | ✅ | 前端页面有,后端待验证 |
|
||||
|
||||
### 23. 数据统计
|
||||
|
||||
| 功能 | 后端 | 前端 | 说明 |
|
||||
|------|:----:|:----:|------|
|
||||
| 概览Dashboard | ⚠️ | ✅ | 前端页面有,后端待验证 |
|
||||
| 平台监控 | ⚠️ | ✅ | 前端页面有,后端待验证 |
|
||||
| 操作日志 | ✅ | ✅ | 操作记录 |
|
||||
| 资质告警 | ⚠️ | ✅ | 前端页面有,后端待验证 |
|
||||
|
||||
### 24. 系统配置
|
||||
|
||||
| 功能 | 后端 | 前端 | 说明 |
|
||||
|------|:----:|:----:|------|
|
||||
| 邮件配置 | ⚠️ | ✅ | 前端页面有,后端待验证 |
|
||||
| 短信配置 | ⚠️ | ✅ | 前端页面有,后端待验证 |
|
||||
| 支付渠道配置 | ⚠️ | ✅ | 前端页面有,后端待验证 |
|
||||
| 存储配置 | ⚠️ | ✅ | 前端页面有,后端待验证 |
|
||||
| 用户中心 | ✅ | ✅ | 个人设置 |
|
||||
|
||||
---
|
||||
|
||||
## 二、租户管理端 (TenantApi + TenantUI)
|
||||
|
||||
商户/租户使用,管理自己的门店、商品、订单等。
|
||||
|
||||
| 功能模块 | 后端 | 前端 | 说明 |
|
||||
|----------|:----:|:----:|------|
|
||||
| 租户登录认证 | ❌ | ❌ | 租户用户登录 |
|
||||
| 门店管理 | ❌ | ❌ | 管理自己的门店 |
|
||||
| 商品管理 | ❌ | ❌ | 管理自己的商品 |
|
||||
| 订单管理 | ❌ | ❌ | 处理订单 |
|
||||
| 员工管理 | ❌ | ❌ | 管理门店员工 |
|
||||
| 营业设置 | ❌ | ❌ | 营业时间、配送等 |
|
||||
| 营销工具 | ❌ | ❌ | 优惠券、活动 |
|
||||
| 数据报表 | ❌ | ❌ | 经营数据 |
|
||||
| 财务管理 | ❌ | ❌ | 收入、提现 |
|
||||
| 消息通知 | ❌ | ❌ | 订单提醒等 |
|
||||
|
||||
---
|
||||
|
||||
## 三、C端应用 (小程序/App)
|
||||
|
||||
消费者使用,浏览、下单、支付等。
|
||||
|
||||
| 功能模块 | 后端 | 前端 | 说明 |
|
||||
|----------|:----:|:----:|------|
|
||||
| 用户注册/登录 | ❌ | ❌ | 手机号/微信登录 |
|
||||
| 首页推荐 | ❌ | ❌ | 门店/商品推荐 |
|
||||
| 门店列表 | ❌ | ❌ | 附近门店 |
|
||||
| 门店详情 | ❌ | ❌ | 门店信息、菜单 |
|
||||
| 商品详情 | ❌ | ❌ | 商品规格、加料 |
|
||||
| 购物车 | ❌ | ❌ | 购物车管理 |
|
||||
| 下单支付 | ❌ | ❌ | 订单创建、支付 |
|
||||
| 订单列表 | ❌ | ❌ | 我的订单 |
|
||||
| 订单详情 | ❌ | ❌ | 订单状态、配送 |
|
||||
| 配送追踪 | ❌ | ❌ | 骑手位置 |
|
||||
| 评价系统 | ❌ | ❌ | 订单评价 |
|
||||
| 优惠券 | ❌ | ❌ | 领券、用券 |
|
||||
| 收货地址 | ❌ | ❌ | 地址管理 |
|
||||
| 个人中心 | ❌ | ❌ | 用户信息 |
|
||||
| 消息中心 | ❌ | ❌ | 通知消息 |
|
||||
| 客服入口 | ❌ | ❌ | 在线客服 |
|
||||
|
||||
---
|
||||
|
||||
## 状态说明
|
||||
|
||||
- ✅ 已完成 - 功能已开发完成,可正常使用
|
||||
- ⚠️ 待验证 - 前端页面存在,后端API需验证
|
||||
- ❌ 未开始 - 功能尚未开发
|
||||
|
||||
---
|
||||
|
||||
## 统计
|
||||
|
||||
| 端 | 总功能数 | 已完成 | 待验证 | 未开始 |
|
||||
|----|:--------:|:------:|:------:|:------:|
|
||||
| 平台管理端 | ~120 | ~95 | ~20 | ~5 |
|
||||
| 租户管理端 | ~10 | 0 | 0 | 10 |
|
||||
| C端应用 | ~16 | 0 | 0 | 16 |
|
||||
|
||||
---
|
||||
|
||||
## Domain 层已实现模块
|
||||
|
||||
- Analytics (数据分析)
|
||||
- Billings (账单)
|
||||
- Common (通用)
|
||||
- Coupons (优惠券)
|
||||
- CustomerService (客服)
|
||||
- Deliveries (配送)
|
||||
- Dictionary (字典)
|
||||
- Distribution (分发)
|
||||
- Engagement (互动)
|
||||
- GroupBuying (团购)
|
||||
- Identity (身份)
|
||||
- Inventory (库存)
|
||||
- Membership (会员)
|
||||
- Merchants (商户)
|
||||
- Navigation (导航)
|
||||
- Ordering (订购)
|
||||
- Orders (订单)
|
||||
- Payments (支付)
|
||||
- Products (产品)
|
||||
- Queues (队列)
|
||||
- Reservations (预订)
|
||||
- Stores (门店)
|
||||
- SystemParameters (系统参数)
|
||||
- Tenants (租户)
|
||||
292
Roadmap/02-开发里程碑.md
Normal file
292
Roadmap/02-开发里程碑.md
Normal file
@@ -0,0 +1,292 @@
|
||||
# TakeoutSaaS 开发里程碑
|
||||
|
||||
> 最后更新:2026-02-02
|
||||
|
||||
本文档定义整个 SaaS 外卖系统的开发里程碑,按优先级和依赖关系排序。
|
||||
|
||||
---
|
||||
|
||||
## 里程碑概览
|
||||
|
||||
```
|
||||
M1 平台核心基础 ─────────────────────────────────────── ✅ 已完成
|
||||
│
|
||||
M2 租户订阅计费 ─────────────────────────────────────── ✅ 已完成
|
||||
│
|
||||
M3 前后端联调验证 ───────────────────────────────────── 🔄 进行中
|
||||
│
|
||||
M4 订单交易闭环 ─────────────────────────────────────── ⏳ 待开始
|
||||
│
|
||||
M5 租户管理端 ───────────────────────────────────────── ⏳ 待开始
|
||||
│
|
||||
M6 C端小程序 ────────────────────────────────────────── ⏳ 待开始
|
||||
│
|
||||
M7 营销与运营 ───────────────────────────────────────── ⏳ 待开始
|
||||
│
|
||||
M8 财务结算 ─────────────────────────────────────────── ⏳ 待开始
|
||||
│
|
||||
M9 数据与风控 ───────────────────────────────────────── ⏳ 待开始
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## M1: 平台核心基础 ✅ 已完成
|
||||
|
||||
**目标**:搭建平台管理端基础框架,实现核心管理功能。
|
||||
|
||||
### 完成内容
|
||||
|
||||
| 模块 | 功能 | 后端 | 前端 |
|
||||
|------|------|:----:|:----:|
|
||||
| 身份认证 | 登录、Token刷新、密码重置 | ✅ | ✅ |
|
||||
| 用户管理 | CRUD、批量操作、权限分配 | ✅ | ✅ |
|
||||
| 角色权限 | 角色CRUD、权限配置、菜单管理 | ✅ | ✅ |
|
||||
| 租户管理 | 租户CRUD、审核、角色模板 | ✅ | ✅ |
|
||||
| 租户套餐 | 套餐CRUD、功能策略 | ✅ | ✅ |
|
||||
| 商户管理 | 完整审核流程、文档、合同 | ✅ | ✅ |
|
||||
| 门店管理 | 资质、营业时间、配送区域、费用 | ✅ | ✅ |
|
||||
| 商品管理 | SKU、属性、加料、媒体、定价 | ✅ | ✅ |
|
||||
| 订单管理 | 基础CRUD | ✅ | ✅ |
|
||||
| 库存管理 | 锁定、扣减、调整、释放 | ✅ | ✅ |
|
||||
| 字典参数 | 字典CRUD、系统参数 | ✅ | ✅ |
|
||||
| 文件管理 | 文件上传 | ✅ | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## M2: 租户订阅计费 ✅ 已完成
|
||||
|
||||
**目标**:实现 SaaS 变现核心,租户可订阅套餐、支付、续费。
|
||||
|
||||
### 完成内容
|
||||
|
||||
| 功能 | 后端 | 前端 | 说明 |
|
||||
|------|:----:|:----:|------|
|
||||
| 订阅列表 | ✅ | ✅ | 分页、多条件筛选 |
|
||||
| 订阅详情 | ✅ | ✅ | 查看订阅详情 |
|
||||
| 更新订阅 | ✅ | ✅ | 修改订阅信息 |
|
||||
| 延期订阅 | ✅ | ✅ | 延长订阅期限 |
|
||||
| 变更套餐 | ✅ | ✅ | 升级/降级套餐 |
|
||||
| 更新订阅状态 | ✅ | ✅ | 状态变更 |
|
||||
| 批量延期 | ✅ | ✅ | 批量操作 |
|
||||
| 到期提醒 | ✅ | ✅ | 批量提醒 |
|
||||
| 账单列表 | ✅ | ✅ | 分页、筛选 |
|
||||
| 账单详情 | ✅ | ✅ | 查看详情 |
|
||||
| 确认收款 | ✅ | ✅ | 一键确认 |
|
||||
| 账单统计 | ✅ | ✅ | 统计页面 |
|
||||
| 配额套餐 | ✅ | ✅ | 配额管理 |
|
||||
| 配额购买 | ✅ | ✅ | 购买配额 |
|
||||
| 配额告警 | ✅ | ✅ | 告警配置 |
|
||||
|
||||
---
|
||||
|
||||
## M3: 前后端联调验证 🔄 进行中
|
||||
|
||||
**目标**:验证前端页面与后端API的对接情况,补齐缺失的API。
|
||||
|
||||
### 待验证模块
|
||||
|
||||
以下模块前端页面已存在,需验证后端API是否完整:
|
||||
|
||||
| 模块 | 前端 | 后端 | 状态 |
|
||||
|------|:----:|:----:|:----:|
|
||||
| 营销活动 | ✅ | ⚠️ | 待验证 |
|
||||
| 财务结算 | ✅ | ⚠️ | 待验证 |
|
||||
| 内容管理 | ✅ | ⚠️ | 待验证 |
|
||||
| 风控管理 | ✅ | ⚠️ | 待验证 |
|
||||
| 客服工单 | ✅ | ⚠️ | 待验证 |
|
||||
| 数据统计 | ✅ | ⚠️ | 待验证 |
|
||||
| 系统配置 | ✅ | ⚠️ | 待验证 |
|
||||
|
||||
### 验证步骤
|
||||
|
||||
1. 逐个检查前端页面调用的API
|
||||
2. 确认后端Controller是否存在
|
||||
3. 补齐缺失的API
|
||||
4. 联调测试
|
||||
|
||||
---
|
||||
|
||||
## M4: 订单交易闭环 ⏳ 待开始
|
||||
|
||||
**目标**:完善订单全生命周期,实现完整交易流程。
|
||||
|
||||
**依赖**:M3 完成
|
||||
|
||||
### 功能清单
|
||||
|
||||
| 功能 | 优先级 | 说明 |
|
||||
|------|:------:|------|
|
||||
| 订单状态机 | P0 | 完整状态流转 |
|
||||
| 订单支付 | P0 | 支付状态处理 |
|
||||
| 订单取消 | P0 | 取消流程 |
|
||||
| 退款处理 | P0 | 退款流程 |
|
||||
| 配送分配 | P1 | 骑手分配 |
|
||||
| 配送追踪 | P1 | 配送状态 |
|
||||
| 订单完成 | P1 | 完成确认 |
|
||||
| 订单评价 | P2 | 评价入口 |
|
||||
| 订单打印 | P2 | 小票打印 |
|
||||
|
||||
### 订单状态流转
|
||||
|
||||
```
|
||||
待支付 → 已支付 → 商家接单 → 制作中 → 待配送 → 配送中 → 已完成
|
||||
↓ ↓ ↓ ↓ ↓ ↓
|
||||
已取消 已退款 已取消 已取消 已取消 配送异常
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## M5: 租户管理端 ⏳ 待开始
|
||||
|
||||
**目标**:为商户/租户提供独立管理后台。
|
||||
|
||||
**依赖**:M4 完成
|
||||
|
||||
### 功能清单
|
||||
|
||||
| 模块 | 功能 |
|
||||
|------|------|
|
||||
| 认证 | 租户用户登录、权限控制 |
|
||||
| 门店 | 管理自己的门店 |
|
||||
| 商品 | 管理自己的商品 |
|
||||
| 订单 | 接单、处理订单 |
|
||||
| 员工 | 管理门店员工 |
|
||||
| 设置 | 营业时间、配送设置 |
|
||||
| 报表 | 经营数据统计 |
|
||||
| 财务 | 收入、提现 |
|
||||
|
||||
### 技术方案
|
||||
|
||||
- **后端**:TenantApi(新项目,复用 Domain/Infrastructure)
|
||||
- **前端**:TenantUI(新项目,复用组件库)
|
||||
- **认证**:独立 JWT,租户隔离
|
||||
|
||||
---
|
||||
|
||||
## M6: C端小程序 ⏳ 待开始
|
||||
|
||||
**目标**:消费者端小程序,实现浏览、下单、支付。
|
||||
|
||||
**依赖**:M5 完成
|
||||
|
||||
### 功能清单
|
||||
|
||||
| 模块 | 功能 |
|
||||
|------|------|
|
||||
| 认证 | 微信登录、手机号绑定 |
|
||||
| 首页 | 门店推荐、搜索 |
|
||||
| 门店 | 门店列表、详情、菜单 |
|
||||
| 商品 | 商品详情、规格选择 |
|
||||
| 购物车 | 购物车管理 |
|
||||
| 订单 | 下单、支付、订单列表 |
|
||||
| 配送 | 配送追踪 |
|
||||
| 用户 | 地址管理、个人中心 |
|
||||
| 优惠 | 优惠券、活动 |
|
||||
|
||||
### 技术方案
|
||||
|
||||
- **框架**:uni-app / Taro
|
||||
- **后端**:CustomerApi(新项目)
|
||||
- **支付**:微信支付
|
||||
|
||||
---
|
||||
|
||||
## M7: 营销与运营 ⏳ 待开始
|
||||
|
||||
**目标**:营销工具,提升订单转化。
|
||||
|
||||
**依赖**:M6 完成
|
||||
|
||||
### 功能清单
|
||||
|
||||
| 功能 | 说明 |
|
||||
|------|------|
|
||||
| 优惠券 | 创建、发放、核销 |
|
||||
| 满减活动 | 满减规则配置 |
|
||||
| 限时折扣 | 折扣活动 |
|
||||
| 新人专享 | 新用户优惠 |
|
||||
| 邀请有礼 | 邀请奖励 |
|
||||
| Banner管理 | 轮播图配置 |
|
||||
| 推送通知 | 消息推送 |
|
||||
|
||||
---
|
||||
|
||||
## M8: 财务结算 ⏳ 待开始
|
||||
|
||||
**目标**:商户结算、平台财务管理。
|
||||
|
||||
**依赖**:M6 完成
|
||||
|
||||
### 功能清单
|
||||
|
||||
| 功能 | 说明 |
|
||||
|------|------|
|
||||
| 佣金规则 | 佣金比例配置 |
|
||||
| 结算周期 | 结算频率配置 |
|
||||
| 结算单 | 结算单生成、审核 |
|
||||
| 提现管理 | 提现申请、审核 |
|
||||
| 发票管理 | 发票申请 |
|
||||
| 财务报表 | 收支统计 |
|
||||
|
||||
---
|
||||
|
||||
## M9: 数据与风控 ⏳ 待开始
|
||||
|
||||
**目标**:数据分析、风险控制。
|
||||
|
||||
**依赖**:M7、M8 完成
|
||||
|
||||
### 功能清单
|
||||
|
||||
| 功能 | 说明 |
|
||||
|------|------|
|
||||
| Dashboard | 核心指标看板 |
|
||||
| 订单统计 | 订单数据分析 |
|
||||
| 销售统计 | 销售额分析 |
|
||||
| 用户统计 | 用户增长分析 |
|
||||
| 黑名单 | 用户/设备黑名单 |
|
||||
| 风控规则 | 风险规则配置 |
|
||||
| 敏感词 | 敏感词过滤 |
|
||||
|
||||
---
|
||||
|
||||
## 里程碑时间线(预估)
|
||||
|
||||
```
|
||||
2026-02
|
||||
├── M3: 前后端联调验证 (1周)
|
||||
|
||||
2026-02 ~ 2026-03
|
||||
├── M4: 订单交易闭环 (3周)
|
||||
|
||||
2026-03 ~ 2026-04
|
||||
├── M5: 租户管理端 (4周)
|
||||
|
||||
2026-04 ~ 2026-05
|
||||
├── M6: C端小程序 (6周)
|
||||
|
||||
2026-06
|
||||
├── M7: 营销与运营 (3周)
|
||||
├── M8: 财务结算 (3周)
|
||||
|
||||
2026-07
|
||||
├── M9: 数据与风控 (2周)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 状态说明
|
||||
|
||||
- ✅ 已完成
|
||||
- 🔄 进行中
|
||||
- ⏳ 待开始
|
||||
- ❌ 已取消
|
||||
|
||||
---
|
||||
|
||||
## 变更记录
|
||||
|
||||
| 日期 | 变更内容 |
|
||||
|------|----------|
|
||||
| 2026-02-02 | 更新文档,M1/M2已完成,新增M3联调验证阶段 |
|
||||
| 2026-02-02 | 初始版本,定义 M1-M8 里程碑 |
|
||||
@@ -13,3 +13,7 @@ dsn = "postgres://dictionary_user:DictionaryUser112233@120.53.222.17:5432/takeou
|
||||
[[sources]]
|
||||
id = "takeout_hangfire"
|
||||
dsn = "postgres://hangfire_user:HangFire112233@120.53.222.17:5432/takeout_hangfire_db"
|
||||
|
||||
[[sources]]
|
||||
id = "takeout_logs"
|
||||
dsn = "postgres://logs_user:Logs112233@120.53.222.17:5432/takeout_logs_db"
|
||||
|
||||
@@ -19,6 +19,15 @@ if [ "${NO_CACHE:-0}" = "1" ]; then
|
||||
docker_build_args+=(--no-cache)
|
||||
fi
|
||||
|
||||
# 3. 代理配置(用于 docker build 阶段访问 nuget.org)
|
||||
proxy_host="172.18.0.1"
|
||||
proxy_port="7890"
|
||||
if [ "${USE_PROXY:-1}" = "1" ]; then
|
||||
docker_build_args+=(--build-arg "HTTP_PROXY=http://${proxy_host}:${proxy_port}")
|
||||
docker_build_args+=(--build-arg "HTTPS_PROXY=http://${proxy_host}:${proxy_port}")
|
||||
echo "已启用代理:http://${proxy_host}:${proxy_port}"
|
||||
fi
|
||||
|
||||
# 2. 先构建镜像(减少停机时间;同时避免每次都删除镜像导致缓存失效)
|
||||
echo "开始构建镜像:${image_name} (Configuration=${build_configuration})"
|
||||
docker build -f "${dockerfile_path}" -t "${image_name}" --build-arg "BUILD_CONFIGURATION=${build_configuration}" "${docker_build_args[@]}" "${repo_root}"
|
||||
@@ -40,7 +49,7 @@ if [ -n "${docker_network}" ]; then
|
||||
fi
|
||||
|
||||
echo "运行新容器:${container_name} (端口映射 7801:7801,环境 Development,网络 ${docker_network})"
|
||||
docker run -d --name "${container_name}" "${run_args[@]}" -e ASPNETCORE_ENVIRONMENT=Development -p 7801:7801 "${image_name}"
|
||||
docker run -d --name "${container_name}" "${run_args[@]}" --restart=always -e ASPNETCORE_ENVIRONMENT=Development -p 7801:7801 "${image_name}"
|
||||
echo "完成。镜像:${image_name},容器:${container_name}。Swagger 访问:http://localhost:7801/swagger"
|
||||
# 6. 交互式终端下暂停,方便查看输出
|
||||
if [ -t 0 ]; then
|
||||
|
||||
@@ -5,7 +5,6 @@ set -euo pipefail
|
||||
trap 'echo "发生错误:${BASH_COMMAND}" >&2' ERR
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
repo_root="$(cd "${script_dir}/.." && pwd)"
|
||||
|
||||
container_name="${CONTAINER_NAME:-takeout.api.admin}"
|
||||
docker_network="${DOCKER_NETWORK:-web_apps}"
|
||||
@@ -16,11 +15,35 @@ nuget_volume="${NUGET_VOLUME:-takeout-nuget}"
|
||||
project_path="${PROJECT_PATH:-src/Api/TakeoutSaaS.AdminApi/TakeoutSaaS.AdminApi.csproj}"
|
||||
environment="${ASPNETCORE_ENVIRONMENT:-Development}"
|
||||
|
||||
repo_root="${REPO_ROOT:-}"
|
||||
if [ -z "${repo_root}" ]; then
|
||||
candidate_dir="${script_dir}"
|
||||
for _ in 0 1 2 3 4 5; do
|
||||
if [ -f "${candidate_dir}/${project_path}" ]; then
|
||||
repo_root="${candidate_dir}"
|
||||
break
|
||||
fi
|
||||
|
||||
if [ -f "${candidate_dir}/AdminApi/${project_path}" ]; then
|
||||
repo_root="${candidate_dir}/AdminApi"
|
||||
break
|
||||
fi
|
||||
|
||||
candidate_dir="$(cd "${candidate_dir}/.." && pwd)"
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -z "${repo_root}" ] || [ ! -f "${repo_root}/${project_path}" ]; then
|
||||
echo "未找到 AdminApi 仓库根目录(缺少 ${project_path}),请设置 REPO_ROOT 或在包含 AdminApi 目录的父级目录中运行该脚本。" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "工作目录:${repo_root}"
|
||||
echo "使用 SDK 镜像:${sdk_image}"
|
||||
echo "容器:${container_name} 端口:${host_port}:${container_port} 网络:${docker_network}"
|
||||
echo "项目:${project_path} 环境:${environment}"
|
||||
|
||||
# Ensure network exists (so it can talk to other services like postgres/redis on the same network).
|
||||
# 1. (空行后) 确保 network 存在(用于连接同网络内的 postgres/redis 等依赖)
|
||||
if [ -n "${docker_network}" ]; then
|
||||
if ! docker network inspect "${docker_network}" >/dev/null 2>&1; then
|
||||
echo "Docker network 不存在,正在创建:${docker_network}"
|
||||
@@ -28,13 +51,13 @@ if [ -n "${docker_network}" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# Persist NuGet cache across container restarts to speed up restore/build.
|
||||
# 2. (空行后) 持久化 NuGet 缓存,加速 restore/build
|
||||
if ! docker volume inspect "${nuget_volume}" >/dev/null 2>&1; then
|
||||
echo "NuGet volume 不存在,正在创建:${nuget_volume}"
|
||||
docker volume create "${nuget_volume}" >/dev/null
|
||||
fi
|
||||
|
||||
# Replace existing container (if any).
|
||||
# 3. (空行后) 替换旧容器(如存在)
|
||||
if docker ps -a --format '{{.Names}}' | grep -qx "${container_name}"; then
|
||||
echo "发现旧容器,正在移除:${container_name}"
|
||||
docker rm -f "${container_name}" >/dev/null
|
||||
@@ -45,9 +68,24 @@ if [ -n "${docker_network}" ]; then
|
||||
run_args+=(--network "${docker_network}")
|
||||
fi
|
||||
|
||||
# 4. 代理配置(用于 dotnet restore 访问 nuget.org)
|
||||
proxy_host="172.18.0.1"
|
||||
proxy_port="7890"
|
||||
proxy_env_args=()
|
||||
if [ "${USE_PROXY:-1}" = "1" ]; then
|
||||
proxy_env_args+=(-e "HTTP_PROXY=http://${proxy_host}:${proxy_port}")
|
||||
proxy_env_args+=(-e "HTTPS_PROXY=http://${proxy_host}:${proxy_port}")
|
||||
proxy_env_args+=(-e "http_proxy=http://${proxy_host}:${proxy_port}")
|
||||
proxy_env_args+=(-e "https_proxy=http://${proxy_host}:${proxy_port}")
|
||||
proxy_env_args+=(-e "NO_PROXY=localhost,127.0.0.1,::1")
|
||||
proxy_env_args+=(-e "no_proxy=localhost,127.0.0.1,::1")
|
||||
echo "已启用代理:http://${proxy_host}:${proxy_port}"
|
||||
fi
|
||||
|
||||
echo "启动 dotnet watch(后台运行)..."
|
||||
docker run -d --name "${container_name}" \
|
||||
"${run_args[@]}" \
|
||||
--restart=always \
|
||||
-p "${host_port}:${container_port}" \
|
||||
-v "${repo_root}":/src \
|
||||
-w /src \
|
||||
@@ -55,9 +93,10 @@ docker run -d --name "${container_name}" \
|
||||
-e ASPNETCORE_ENVIRONMENT="${environment}" \
|
||||
-e ASPNETCORE_URLS="http://+:${container_port}" \
|
||||
-e DOTNET_USE_POLLING_FILE_WATCHER=1 \
|
||||
-e DOTNET_WATCH_SUPPRESS_LAUNCH_BROWSER=1 \
|
||||
"${proxy_env_args[@]}" \
|
||||
"${sdk_image}" \
|
||||
dotnet watch --project "${project_path}" run
|
||||
dotnet watch --project "${project_path}" run --no-launch-profile
|
||||
|
||||
echo "已启动。查看日志:docker logs -f ${container_name}"
|
||||
echo "Swagger:http://localhost:${host_port}/swagger"
|
||||
|
||||
echo "Swagger:http://localhost:${host_port}/api/docs (兼容入口 /swagger)"
|
||||
|
||||
@@ -18,7 +18,8 @@ environment="${ASPNETCORE_ENVIRONMENT:-Development}"
|
||||
repo_root=""
|
||||
candidate_dir="${script_dir}"
|
||||
for _ in 0 1 2 3 4 5; do
|
||||
if [ -f "${candidate_dir}/${project_path}" ] || [ -f "${candidate_dir}/TakeoutSaaS.sln" ]; then
|
||||
# 必须同时满足:项目文件存在 且 sln 文件存在
|
||||
if [ -f "${candidate_dir}/${project_path}" ] && [ -f "${candidate_dir}/TakeoutSaaS.sln" ]; then
|
||||
repo_root="${candidate_dir}"
|
||||
break
|
||||
fi
|
||||
@@ -27,7 +28,7 @@ for _ in 0 1 2 3 4 5; do
|
||||
done
|
||||
|
||||
if [ -z "${repo_root}" ]; then
|
||||
echo "未找到仓库根目录(缺少 ${project_path} 或 TakeoutSaaS.sln),请在 TenantApi 仓库中运行该脚本。" >&2
|
||||
echo "未找到仓库根目录(需要同时存在 ${project_path} 和 TakeoutSaaS.sln),请在 TenantApi 仓库中运行该脚本。" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -61,9 +62,24 @@ if [ -n "${docker_network}" ]; then
|
||||
run_args+=(--network "${docker_network}")
|
||||
fi
|
||||
|
||||
# 4. 代理配置(用于 dotnet restore 访问 nuget.org)
|
||||
proxy_host="172.18.0.1"
|
||||
proxy_port="7890"
|
||||
proxy_env_args=()
|
||||
if [ "${USE_PROXY:-1}" = "1" ]; then
|
||||
proxy_env_args+=(-e "HTTP_PROXY=http://${proxy_host}:${proxy_port}")
|
||||
proxy_env_args+=(-e "HTTPS_PROXY=http://${proxy_host}:${proxy_port}")
|
||||
proxy_env_args+=(-e "http_proxy=http://${proxy_host}:${proxy_port}")
|
||||
proxy_env_args+=(-e "https_proxy=http://${proxy_host}:${proxy_port}")
|
||||
proxy_env_args+=(-e "NO_PROXY=localhost,127.0.0.1,::1")
|
||||
proxy_env_args+=(-e "no_proxy=localhost,127.0.0.1,::1")
|
||||
echo "已启用代理:http://${proxy_host}:${proxy_port}"
|
||||
fi
|
||||
|
||||
echo "启动 dotnet watch(后台运行)..."
|
||||
docker run -d --name "${container_name}" \
|
||||
"${run_args[@]}" \
|
||||
--restart=always \
|
||||
-p "${host_port}:${container_port}" \
|
||||
-v "${repo_root}":/src \
|
||||
-w /src \
|
||||
@@ -72,8 +88,9 @@ docker run -d --name "${container_name}" \
|
||||
-e ASPNETCORE_URLS="http://+:${container_port}" \
|
||||
-e DOTNET_USE_POLLING_FILE_WATCHER=1 \
|
||||
-e DOTNET_WATCH_SUPPRESS_LAUNCH_BROWSER=1 \
|
||||
"${proxy_env_args[@]}" \
|
||||
"${sdk_image}" \
|
||||
dotnet watch --project "${project_path}" run
|
||||
dotnet watch --project "${project_path}" run --no-launch-profile
|
||||
|
||||
echo "已启动。查看日志:docker logs -f ${container_name}"
|
||||
echo "Swagger:http://localhost:${host_port}/api/docs (兼容入口 /swagger)"
|
||||
|
||||
@@ -101,7 +101,7 @@ docker run -d --name $containerName @runArgs `
|
||||
-e "DOTNET_USE_POLLING_FILE_WATCHER=1" `
|
||||
-e "DOTNET_WATCH_SUPPRESS_LAUNCH_BROWSER=1" `
|
||||
$sdkImage `
|
||||
dotnet watch --project $projectPath run
|
||||
dotnet watch --project $projectPath run --no-launch-profile
|
||||
|
||||
Write-Host "已启动。查看日志:docker logs -f $containerName"
|
||||
Write-Host "Swagger:http://localhost:$hostPort/api/docs (兼容入口 /swagger)"
|
||||
|
||||
Reference in New Issue
Block a user