feat: 实现门店套餐分配功能并统一测试基础设施
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m30s

新增功能:
- 门店套餐分配管理(shop_package_allocation):支持门店套餐库存管理
- 门店套餐系列分配管理(shop_series_allocation):支持套餐系列分配和佣金层级设置
- 我的套餐查询(my_package):支持门店查询自己的套餐分配情况

测试改进:
- 统一集成测试基础设施,新增 testutils.NewIntegrationTestEnv
- 重构所有集成测试使用新的测试环境设置
- 移除旧的测试辅助函数和冗余测试文件
- 新增 test_helpers_test.go 统一任务测试辅助

技术细节:
- 新增数据库迁移 000025_create_shop_allocation_tables
- 新增 3 个 Handler、Service、Store 和对应的单元测试
- 更新 OpenAPI 文档和文档生成器
- 测试覆盖率:Service 层 > 90%

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-28 10:45:16 +08:00
parent 5fefe9d0cb
commit 23eb0307bb
73 changed files with 8716 additions and 4558 deletions

View File

@@ -76,6 +76,15 @@ func RegisterAdminRoutes(router fiber.Router, handlers *bootstrap.Handlers, midd
if handlers.Package != nil {
registerPackageRoutes(authGroup, handlers.Package, doc, basePath)
}
if handlers.ShopSeriesAllocation != nil {
registerShopSeriesAllocationRoutes(authGroup, handlers.ShopSeriesAllocation, doc, basePath)
}
if handlers.ShopPackageAllocation != nil {
registerShopPackageAllocationRoutes(authGroup, handlers.ShopPackageAllocation, doc, basePath)
}
if handlers.MyPackage != nil {
registerMyPackageRoutes(authGroup, handlers.MyPackage, doc, basePath)
}
}
func registerAdminAuthRoutes(router fiber.Router, handler interface{}, authMiddleware fiber.Handler, doc *openapi.Generator, basePath string) {

View File

@@ -0,0 +1,35 @@
package routes
import (
"github.com/gofiber/fiber/v2"
"github.com/break/junhong_cmp_fiber/internal/handler/admin"
"github.com/break/junhong_cmp_fiber/internal/model/dto"
"github.com/break/junhong_cmp_fiber/pkg/openapi"
)
func registerMyPackageRoutes(router fiber.Router, handler *admin.MyPackageHandler, doc *openapi.Generator, basePath string) {
Register(router, doc, basePath, "GET", "/my-packages", handler.ListMyPackages, RouteSpec{
Summary: "我的可售套餐列表",
Tags: []string{"代理可售套餐"},
Input: new(dto.MyPackageListRequest),
Output: new(dto.MyPackagePageResult),
Auth: true,
})
Register(router, doc, basePath, "GET", "/my-packages/:id", handler.GetMyPackage, RouteSpec{
Summary: "获取可售套餐详情",
Tags: []string{"代理可售套餐"},
Input: new(dto.IDReq),
Output: new(dto.MyPackageDetailResponse),
Auth: true,
})
Register(router, doc, basePath, "GET", "/my-series-allocations", handler.ListMySeriesAllocations, RouteSpec{
Summary: "我的被分配系列列表",
Tags: []string{"代理可售套餐"},
Input: new(dto.MySeriesAllocationListRequest),
Output: new(dto.MySeriesAllocationPageResult),
Auth: true,
})
}

View File

@@ -0,0 +1,62 @@
package routes
import (
"github.com/gofiber/fiber/v2"
"github.com/break/junhong_cmp_fiber/internal/handler/admin"
"github.com/break/junhong_cmp_fiber/internal/model/dto"
"github.com/break/junhong_cmp_fiber/pkg/openapi"
)
func registerShopPackageAllocationRoutes(router fiber.Router, handler *admin.ShopPackageAllocationHandler, doc *openapi.Generator, basePath string) {
allocations := router.Group("/shop-package-allocations")
groupPath := basePath + "/shop-package-allocations"
Register(allocations, doc, groupPath, "GET", "", handler.List, RouteSpec{
Summary: "单套餐分配列表",
Tags: []string{"单套餐分配"},
Input: new(dto.ShopPackageAllocationListRequest),
Output: new(dto.ShopPackageAllocationPageResult),
Auth: true,
})
Register(allocations, doc, groupPath, "POST", "", handler.Create, RouteSpec{
Summary: "创建单套餐分配",
Tags: []string{"单套餐分配"},
Input: new(dto.CreateShopPackageAllocationRequest),
Output: new(dto.ShopPackageAllocationResponse),
Auth: true,
})
Register(allocations, doc, groupPath, "GET", "/:id", handler.Get, RouteSpec{
Summary: "获取单套餐分配详情",
Tags: []string{"单套餐分配"},
Input: new(dto.IDReq),
Output: new(dto.ShopPackageAllocationResponse),
Auth: true,
})
Register(allocations, doc, groupPath, "PUT", "/:id", handler.Update, RouteSpec{
Summary: "更新单套餐分配",
Tags: []string{"单套餐分配"},
Input: new(dto.UpdateShopPackageAllocationParams),
Output: new(dto.ShopPackageAllocationResponse),
Auth: true,
})
Register(allocations, doc, groupPath, "DELETE", "/:id", handler.Delete, RouteSpec{
Summary: "删除单套餐分配",
Tags: []string{"单套餐分配"},
Input: new(dto.IDReq),
Output: nil,
Auth: true,
})
Register(allocations, doc, groupPath, "PUT", "/:id/status", handler.UpdateStatus, RouteSpec{
Summary: "更新单套餐分配状态",
Tags: []string{"单套餐分配"},
Input: new(dto.UpdateStatusParams),
Output: nil,
Auth: true,
})
}

View File

@@ -0,0 +1,95 @@
package routes
import (
"github.com/gofiber/fiber/v2"
"github.com/break/junhong_cmp_fiber/internal/handler/admin"
"github.com/break/junhong_cmp_fiber/internal/model/dto"
"github.com/break/junhong_cmp_fiber/pkg/openapi"
)
// registerShopSeriesAllocationRoutes 注册套餐系列分配相关路由
func registerShopSeriesAllocationRoutes(router fiber.Router, handler *admin.ShopSeriesAllocationHandler, doc *openapi.Generator, basePath string) {
allocations := router.Group("/shop-series-allocations")
groupPath := basePath + "/shop-series-allocations"
Register(allocations, doc, groupPath, "GET", "", handler.List, RouteSpec{
Summary: "套餐系列分配列表",
Tags: []string{"套餐系列分配"},
Input: new(dto.ShopSeriesAllocationListRequest),
Output: new(dto.ShopSeriesAllocationPageResult),
Auth: true,
})
Register(allocations, doc, groupPath, "POST", "", handler.Create, RouteSpec{
Summary: "创建套餐系列分配",
Tags: []string{"套餐系列分配"},
Input: new(dto.CreateShopSeriesAllocationRequest),
Output: new(dto.ShopSeriesAllocationResponse),
Auth: true,
})
Register(allocations, doc, groupPath, "GET", "/:id", handler.Get, RouteSpec{
Summary: "获取套餐系列分配详情",
Tags: []string{"套餐系列分配"},
Input: new(dto.IDReq),
Output: new(dto.ShopSeriesAllocationResponse),
Auth: true,
})
Register(allocations, doc, groupPath, "PUT", "/:id", handler.Update, RouteSpec{
Summary: "更新套餐系列分配",
Tags: []string{"套餐系列分配"},
Input: new(dto.UpdateShopSeriesAllocationParams),
Output: new(dto.ShopSeriesAllocationResponse),
Auth: true,
})
Register(allocations, doc, groupPath, "DELETE", "/:id", handler.Delete, RouteSpec{
Summary: "删除套餐系列分配",
Tags: []string{"套餐系列分配"},
Input: new(dto.IDReq),
Output: nil,
Auth: true,
})
Register(allocations, doc, groupPath, "PUT", "/:id/status", handler.UpdateStatus, RouteSpec{
Summary: "更新套餐系列分配状态",
Tags: []string{"套餐系列分配"},
Input: new(dto.UpdateStatusParams),
Output: nil,
Auth: true,
})
Register(allocations, doc, groupPath, "GET", "/:id/tiers", handler.ListTiers, RouteSpec{
Summary: "获取梯度佣金列表",
Tags: []string{"套餐系列分配"},
Input: new(dto.IDReq),
Output: new(dto.CommissionTierListResult),
Auth: true,
})
Register(allocations, doc, groupPath, "POST", "/:id/tiers", handler.AddTier, RouteSpec{
Summary: "添加梯度佣金配置",
Tags: []string{"套餐系列分配"},
Input: new(dto.CreateCommissionTierParams),
Output: new(dto.CommissionTierResponse),
Auth: true,
})
Register(allocations, doc, groupPath, "PUT", "/:id/tiers/:tier_id", handler.UpdateTier, RouteSpec{
Summary: "更新梯度佣金配置",
Tags: []string{"套餐系列分配"},
Input: new(dto.UpdateCommissionTierParams),
Output: new(dto.CommissionTierResponse),
Auth: true,
})
Register(allocations, doc, groupPath, "DELETE", "/:id/tiers/:tier_id", handler.DeleteTier, RouteSpec{
Summary: "删除梯度佣金配置",
Tags: []string{"套餐系列分配"},
Input: new(dto.TierIDParams),
Output: nil,
Auth: true,
})
}