重构: 手续费改为百分比/固定二选一,清理旧 Skin/Order/ShipLog 演示链路
手续费: - 新增 fee_type 字段(rate/fixed),百分比与固定金额二选一,不再叠加 - calculateServiceFee 按 fee_type 分支计算 - 商户创建/更新校验 fee_type,订单落库快照 fee_type - 前端表单改为下拉选择手续费类型,动态显示对应输入框 - 测试拆为 TestFeeRate + TestFeeFixed 清理旧链路: - 删除旧 Skin/Order/ShipLog 模型及 OrderService/SkinService - Dashboard 迁移到 FulfillmentService - 上游 /api/open/v1 改为基于 FulfillmentOrder 实现,接口契约不变 - 推送留痕改用 AuditLog,不再建 ShipLog 表 - 删除前端 Skins/Orders/ShipLogs/Distributors 页面及路由、菜单、API、类型 - 新增迁移 003: 添加 fee_type 列并 DROP 旧表
This commit is contained in:
@@ -14,8 +14,7 @@ import (
|
||||
|
||||
type Handlers struct {
|
||||
Auth *handler.AuthHandler
|
||||
Skin *handler.SkinHandler
|
||||
Order *handler.OrderHandler
|
||||
Dashboard *handler.DashboardHandler
|
||||
User *handler.UserHandler
|
||||
Open *handler.OpenV1Handler
|
||||
SourceOpen *handler.OpenHandler
|
||||
@@ -72,64 +71,52 @@ func Setup(h *Handlers) *gin.Engine {
|
||||
Debug: h.OpenAPIDebug,
|
||||
}))
|
||||
{
|
||||
clientOpen.GET("/products", middleware.RequireAPIScope("products:read"), h.Open.ListProducts)
|
||||
clientOpen.POST("/orders", middleware.RequireAPIScope("orders:write"), h.Open.CreateOrder)
|
||||
clientOpen.GET("/orders/:order_no", middleware.RequireAPIScope("orders:read", "fulfillment:read"), h.Open.QueryOrder)
|
||||
clientOpen.POST("/orders/:order_no/cancel", middleware.RequireAPIScope("orders:write"), h.Open.CancelOrder)
|
||||
clientOpen.POST("/orders/:order_no/ship-notify", middleware.RequireAPIScope("fulfillment:write"), h.Open.ShipNotify)
|
||||
clientOpen.GET("/wallet", middleware.RequireAPIScope("wallet:read"), h.Open.GetWallet)
|
||||
clientOpen.GET("/products", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureProducts), middleware.RequireAPIScope("products:read"), h.Open.ListProducts)
|
||||
clientOpen.POST("/orders", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureOrders), middleware.RequireAPIScope("orders:write"), h.Open.CreateOrder)
|
||||
clientOpen.GET("/orders/:order_no", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureOrders), middleware.RequireAPIScope("orders:read", "fulfillment:read"), h.Open.QueryOrder)
|
||||
clientOpen.POST("/orders/:order_no/cancel", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureOrders), middleware.RequireAPIScope("orders:write"), h.Open.CancelOrder)
|
||||
clientOpen.POST("/orders/:order_no/ship-notify", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureOrders), middleware.RequireAPIScope("fulfillment:write"), h.Open.ShipNotify)
|
||||
clientOpen.GET("/wallet", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureWallet), middleware.RequireAPIScope("wallet:read"), h.Open.GetWallet)
|
||||
}
|
||||
|
||||
auth := api.Group("")
|
||||
auth.Use(middleware.Auth(h.JWT))
|
||||
auth.Use(middleware.Tenant(h.Tenant))
|
||||
{
|
||||
auth.GET("/auth/profile", h.Auth.Profile)
|
||||
auth.GET("/dashboard", h.Order.Dashboard)
|
||||
auth.GET("/auth/profile", h.Auth.Profile)
|
||||
auth.GET("/dashboard", h.Dashboard.Dashboard)
|
||||
|
||||
// 皮肤
|
||||
auth.GET("/skins", h.Skin.List)
|
||||
auth.GET("/skins/:id", h.Skin.Get)
|
||||
auth.POST("/skins", middleware.RequireRole(model.RoleAdmin), h.Skin.Create)
|
||||
auth.PUT("/skins/:id", middleware.RequireRole(model.RoleAdmin), h.Skin.Update)
|
||||
auth.DELETE("/skins/:id", middleware.RequireRole(model.RoleAdmin), h.Skin.Delete)
|
||||
|
||||
// 订单
|
||||
auth.GET("/orders", h.Order.List)
|
||||
auth.POST("/orders", h.Order.Create)
|
||||
auth.PATCH("/orders/:id/status", middleware.RequireRole(model.RoleAdmin), h.Order.UpdateStatus)
|
||||
|
||||
// 新商户后台:不依赖旧皮肤/分销商模型。
|
||||
// 商户后台:商户就是平台下游客户,成员只代表该商户内部员工。
|
||||
merchant := auth.Group("/merchant")
|
||||
{
|
||||
merchant.GET("", h.Merchant.Current)
|
||||
merchant.GET("/products", h.Merchant.ListProducts)
|
||||
merchant.POST("/products", middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.CreateProduct)
|
||||
merchant.PATCH("/products/:id", middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.UpdateProduct)
|
||||
merchant.GET("/orders", h.Merchant.ListOrders)
|
||||
merchant.GET("/wallet", middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator, model.MemberRoleFinance), h.Merchant.GetWallet)
|
||||
merchant.GET("/wallet/ledger", middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleFinance), h.Merchant.ListWalletLedger)
|
||||
merchant.POST("/wallet/adjust", middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleFinance), h.Merchant.AdjustWallet)
|
||||
merchant.GET("/api-clients", middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.ListAPIClients)
|
||||
merchant.POST("/api-clients", middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.CreateAPIClient)
|
||||
merchant.PATCH("/api-clients/:id/status", middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.UpdateAPIClientStatus)
|
||||
merchant.GET("/callbacks", middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.ListCallbacks)
|
||||
merchant.POST("/callbacks", middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.CreateCallback)
|
||||
merchant.PATCH("/callbacks/:id/status", middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.UpdateCallbackStatus)
|
||||
merchant.GET("/products", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureProducts), h.Merchant.ListProducts)
|
||||
merchant.POST("/products", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureProducts), middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.CreateProduct)
|
||||
merchant.PATCH("/products/:id", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureProducts), middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.UpdateProduct)
|
||||
merchant.GET("/orders", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureOrders), h.Merchant.ListOrders)
|
||||
merchant.GET("/wallet", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureWallet), middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator, model.MemberRoleFinance), h.Merchant.GetWallet)
|
||||
merchant.GET("/wallet/ledger", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureWallet), middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleFinance), h.Merchant.ListWalletLedger)
|
||||
merchant.POST("/wallet/adjust", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureWallet), middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleFinance), h.Merchant.AdjustWallet)
|
||||
merchant.GET("/api-clients", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureAPI), middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.ListAPIClients)
|
||||
merchant.POST("/api-clients", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureAPI), middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.CreateAPIClient)
|
||||
merchant.PATCH("/api-clients/:id/status", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureAPI), middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.UpdateAPIClientStatus)
|
||||
merchant.GET("/callbacks", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureCallbacks), middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.ListCallbacks)
|
||||
merchant.POST("/callbacks", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureCallbacks), middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.CreateCallback)
|
||||
merchant.PATCH("/callbacks/:id/status", middleware.RequireMerchantFeature(h.OpenDB, model.MerchantFeatureCallbacks), middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.UpdateCallbackStatus)
|
||||
merchant.GET("/members", middleware.RequireMerchantRole(model.MemberRoleOwner, model.MemberRoleOperator), h.Merchant.ListMembers)
|
||||
merchant.POST("/members", middleware.RequireMerchantRole(model.MemberRoleOwner), h.Merchant.AddCurrentMerchantMember)
|
||||
}
|
||||
|
||||
// 用户 / 分销商 / 发货记录(仅管理员)
|
||||
// 用户 / 发货记录 / 平台商户(仅管理员)
|
||||
admin := auth.Group("")
|
||||
admin.Use(middleware.RequireRole(model.RoleAdmin))
|
||||
{
|
||||
admin.GET("/users", h.User.List)
|
||||
admin.POST("/users", h.User.Create)
|
||||
admin.PATCH("/users/:id/status", h.User.UpdateStatus)
|
||||
admin.GET("/ship-logs", h.Order.ListShipLogs)
|
||||
admin.GET("/platform/merchants", h.Merchant.ListPlatformMerchants)
|
||||
admin.PATCH("/users/:id/status", h.User.UpdateStatus)
|
||||
admin.GET("/platform/merchants", h.Merchant.ListPlatformMerchants)
|
||||
admin.POST("/platform/merchants", h.Merchant.CreateMerchant)
|
||||
admin.PATCH("/platform/merchants/:id", h.Merchant.UpdateMerchantSettings)
|
||||
admin.POST("/platform/merchants/:id/members", h.Merchant.AddPlatformMerchantMember)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,6 @@ func TestSetupDoesNotPanic(t *testing.T) {
|
||||
}
|
||||
tenantSvc := service.NewTenantService(db)
|
||||
authSvc := service.NewAuthService(db, jwt.NewManager("test-jwt"), tenantSvc)
|
||||
skinSvc := service.NewSkinService(db)
|
||||
orderSvc := service.NewOrderService(db)
|
||||
userSvc := service.NewUserService(db, tenantSvc)
|
||||
callbackSvc := service.NewCallbackService(db, codec)
|
||||
fulfillmentSvc := service.NewFulfillmentService(db, callbackSvc)
|
||||
@@ -34,11 +32,10 @@ func TestSetupDoesNotPanic(t *testing.T) {
|
||||
}()
|
||||
_ = Setup(&Handlers{
|
||||
Auth: handler.NewAuthHandler(authSvc),
|
||||
Skin: handler.NewSkinHandler(skinSvc),
|
||||
Order: handler.NewOrderHandler(orderSvc),
|
||||
Dashboard: handler.NewDashboardHandler(fulfillmentSvc),
|
||||
User: handler.NewUserHandler(userSvc),
|
||||
Open: handler.NewOpenV1Handler(merchantSvc, fulfillmentSvc),
|
||||
SourceOpen: handler.NewOpenHandler(orderSvc),
|
||||
SourceOpen: handler.NewOpenHandler(fulfillmentSvc),
|
||||
Merchant: handler.NewMerchantHandler(merchantSvc, fulfillmentSvc, callbackSvc),
|
||||
JWT: jwt.NewManager("test-jwt"),
|
||||
Tenant: tenantSvc,
|
||||
|
||||
Reference in New Issue
Block a user