feat: 客户端接口数据模型基础准备

- 新增资产状态、订单来源、操作人类型、实名链接类型常量
- 8个模型新增字段(asset_status/generation/source/retail_price等)
- 数据库迁移000082:7张表15+字段,含存量retail_price回填
- BUG-1修复:代理零售价渠道隔离,cost_price分配锁定
- BUG-2修复:一次性佣金仅客户端订单触发
- BUG-4修复:充值回调Store操作纳入事务
- 新增资产手动停用接口(PATCH /iot-cards/:id/deactivate、/devices/:id/deactivate)
- Carrier管理新增实名链接配置
- 后台订单generation写时快照
- BatchUpdatePricing支持retail_price调价目标
- 清理全部H5旧接口和个人客户旧登录方法
This commit is contained in:
2026-03-19 10:56:50 +08:00
parent 817d0d6e04
commit ec86dbf463
70 changed files with 1438 additions and 1188 deletions

View File

@@ -59,6 +59,9 @@ func RegisterAdminRoutes(router fiber.Router, handlers *bootstrap.Handlers, midd
if handlers.Device != nil {
registerDeviceRoutes(authGroup, handlers.Device, handlers.DeviceImport, doc, basePath)
}
if handlers.AssetLifecycle != nil {
registerAssetLifecycleRoutes(authGroup, handlers.AssetLifecycle, doc, basePath)
}
if handlers.AssetAllocationRecord != nil {
registerAssetAllocationRecordRoutes(authGroup, handlers.AssetAllocationRecord, doc, basePath)
}

View File

@@ -0,0 +1,28 @@
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"
)
// registerAssetLifecycleRoutes 注册资产手动停用路由
func registerAssetLifecycleRoutes(router fiber.Router, handler *admin.AssetLifecycleHandler, doc *openapi.Generator, basePath string) {
Register(router, doc, basePath, "PATCH", "/iot-cards/:id/deactivate", handler.DeactivateIotCard, RouteSpec{
Summary: "手动停用IoT卡",
Tags: []string{"IoT卡管理"},
Input: new(dto.IDReq),
Output: nil,
Auth: true,
})
Register(router, doc, basePath, "PATCH", "/devices/:id/deactivate", handler.DeactivateDevice, RouteSpec{
Summary: "手动停用设备",
Tags: []string{"设备管理"},
Input: new(dto.IDReq),
Output: nil,
Auth: true,
})
}

View File

@@ -1,27 +0,0 @@
package routes
import (
"github.com/gofiber/fiber/v2"
"github.com/break/junhong_cmp_fiber/internal/bootstrap"
"github.com/break/junhong_cmp_fiber/pkg/openapi"
)
// RegisterH5Routes 注册H5相关路由
func RegisterH5Routes(router fiber.Router, handlers *bootstrap.Handlers, middlewares *bootstrap.Middlewares, doc *openapi.Generator, basePath string) {
// 认证路由已迁移到 /api/auth参见 RegisterAuthRoutes
authGroup := router.Group("", middlewares.H5Auth)
if handlers.H5Order != nil {
registerH5OrderRoutes(authGroup, handlers.H5Order, doc, basePath)
}
if handlers.H5Recharge != nil {
registerH5RechargeRoutes(authGroup, handlers.H5Recharge, doc, basePath)
}
if handlers.EnterpriseDeviceH5 != nil {
registerH5EnterpriseDeviceRoutes(authGroup, handlers.EnterpriseDeviceH5, doc, basePath)
}
if handlers.H5PackageUsage != nil {
registerH5PackageUsageRoutes(authGroup, handlers.H5PackageUsage, doc, basePath)
}
}

View File

@@ -1,31 +0,0 @@
package routes
import (
"github.com/gofiber/fiber/v2"
"github.com/break/junhong_cmp_fiber/internal/handler/h5"
"github.com/break/junhong_cmp_fiber/internal/model/dto"
"github.com/break/junhong_cmp_fiber/pkg/openapi"
)
func registerH5EnterpriseDeviceRoutes(router fiber.Router, handler *h5.EnterpriseDeviceHandler, doc *openapi.Generator, basePath string) {
devices := router.Group("/devices")
groupPath := basePath + "/devices"
Register(devices, doc, groupPath, "GET", "", handler.ListDevices, RouteSpec{
Summary: "企业设备列表H5",
Tags: []string{"H5-企业设备"},
Input: new(dto.H5EnterpriseDeviceListReq),
Output: new(dto.EnterpriseDeviceListResp),
Auth: true,
})
Register(devices, doc, groupPath, "GET", "/:device_id", handler.GetDeviceDetail, RouteSpec{
Summary: "获取设备详情H5",
Tags: []string{"H5-企业设备"},
Input: new(dto.DeviceDetailReq),
Output: new(dto.EnterpriseDeviceDetailResp),
Auth: true,
})
}

View File

@@ -1,23 +0,0 @@
package routes
import (
"github.com/gofiber/fiber/v2"
"github.com/break/junhong_cmp_fiber/internal/handler/h5"
"github.com/break/junhong_cmp_fiber/internal/model/dto"
"github.com/break/junhong_cmp_fiber/pkg/openapi"
)
// registerH5PackageUsageRoutes 注册 H5 端套餐使用情况路由
func registerH5PackageUsageRoutes(router fiber.Router, handler *h5.PackageUsageHandler, doc *openapi.Generator, basePath string) {
packages := router.Group("/packages")
groupPath := basePath + "/packages"
Register(packages, doc, groupPath, "GET", "/my-usage", handler.GetMyUsage, RouteSpec{
Summary: "获取我的套餐使用情况",
Tags: []string{"H5-套餐"},
Input: nil,
Output: new(dto.PackageUsageCustomerViewResponse),
Auth: true,
})
}

View File

@@ -5,7 +5,6 @@ import (
"github.com/break/junhong_cmp_fiber/internal/handler/admin"
"github.com/break/junhong_cmp_fiber/internal/handler/callback"
"github.com/break/junhong_cmp_fiber/internal/handler/h5"
"github.com/break/junhong_cmp_fiber/internal/model/dto"
"github.com/break/junhong_cmp_fiber/pkg/openapi"
)
@@ -53,57 +52,6 @@ func registerAdminOrderRoutes(router fiber.Router, handler *admin.OrderHandler,
})
}
// registerH5OrderRoutes 注册H5订单路由
func registerH5OrderRoutes(router fiber.Router, handler *h5.OrderHandler, doc *openapi.Generator, basePath string) {
Register(router, doc, basePath, "POST", "/orders", handler.Create, RouteSpec{
Summary: "创建订单",
Tags: []string{"H5 订单"},
Input: new(dto.CreateOrderRequest),
Output: new(dto.OrderResponse),
Auth: true,
})
Register(router, doc, basePath, "GET", "/orders", handler.List, RouteSpec{
Summary: "获取订单列表",
Tags: []string{"H5 订单"},
Input: new(dto.OrderListRequest),
Output: new(dto.OrderListResponse),
Auth: true,
})
Register(router, doc, basePath, "GET", "/orders/:id", handler.Get, RouteSpec{
Summary: "获取订单详情",
Tags: []string{"H5 订单"},
Input: new(dto.GetOrderRequest),
Output: new(dto.OrderResponse),
Auth: true,
})
Register(router, doc, basePath, "POST", "/orders/:id/wallet-pay", handler.WalletPay, RouteSpec{
Summary: "钱包支付",
Tags: []string{"H5 订单"},
Input: new(dto.CancelOrderRequest),
Output: nil,
Auth: true,
})
Register(router, doc, basePath, "POST", "/orders/:id/wechat-pay/jsapi", handler.WechatPayJSAPI, RouteSpec{
Summary: "微信 JSAPI 支付",
Tags: []string{"H5 订单"},
Input: new(dto.WechatPayJSAPIParams),
Output: new(dto.WechatPayJSAPIResponse),
Auth: true,
})
Register(router, doc, basePath, "POST", "/orders/:id/wechat-pay/h5", handler.WechatPayH5, RouteSpec{
Summary: "微信 H5 支付",
Tags: []string{"H5 订单"},
Input: new(dto.WechatPayH5Params),
Output: new(dto.WechatPayH5Response),
Auth: true,
})
}
// registerPaymentCallbackRoutes 注册支付回调路由
func registerPaymentCallbackRoutes(router fiber.Router, handler *callback.PaymentHandler, doc *openapi.Generator, basePath string) {
Register(router, doc, basePath, "POST", "/wechat-pay", handler.WechatPayCallback, RouteSpec{

View File

@@ -6,60 +6,16 @@ import (
"github.com/break/junhong_cmp_fiber/internal/bootstrap"
apphandler "github.com/break/junhong_cmp_fiber/internal/handler/app"
"github.com/break/junhong_cmp_fiber/internal/middleware"
"github.com/break/junhong_cmp_fiber/internal/model/dto"
"github.com/break/junhong_cmp_fiber/pkg/openapi"
)
// RegisterPersonalCustomerRoutes 注册个人客户路由
// 路由挂载在 /api/c/v1 下
func RegisterPersonalCustomerRoutes(router fiber.Router, doc *openapi.Generator, basePath string, handlers *bootstrap.Handlers, personalAuthMiddleware *middleware.PersonalAuthMiddleware) {
// 公开路由(不需要认证)
publicGroup := router.Group("")
// 发送验证码
Register(publicGroup, doc, basePath, "POST", "/login/send-code", handlers.PersonalCustomer.SendCode, RouteSpec{
Summary: "发送验证码",
Description: "向指定手机号发送登录验证码",
Tags: []string{"个人客户 - 认证"},
Auth: false,
Input: &apphandler.SendCodeRequest{},
Output: nil,
})
// 登录
Register(publicGroup, doc, basePath, "POST", "/login", handlers.PersonalCustomer.Login, RouteSpec{
Summary: "手机号登录",
Description: "使用手机号和验证码登录",
Tags: []string{"个人客户 - 认证"},
Auth: false,
Input: &apphandler.LoginRequest{},
Output: &apphandler.LoginResponse{},
})
// 微信 OAuth 登录(公开)
Register(publicGroup, doc, basePath, "POST", "/wechat/auth", handlers.PersonalCustomer.WechatOAuthLogin, RouteSpec{
Summary: "微信授权登录",
Description: "使用微信授权码登录,自动创建或关联用户",
Tags: []string{"个人客户 - 认证"},
Auth: false,
Input: &dto.WechatOAuthRequest{},
Output: &dto.WechatOAuthResponse{},
})
// 需要认证的路由
authGroup := router.Group("")
authGroup.Use(personalAuthMiddleware.Authenticate())
// 绑定微信
Register(authGroup, doc, basePath, "POST", "/bind-wechat", handlers.PersonalCustomer.BindWechat, RouteSpec{
Summary: "绑定微信",
Description: "绑定微信账号到当前个人客户",
Tags: []string{"个人客户 - 账户"},
Auth: true,
Input: &dto.WechatOAuthRequest{},
Output: nil,
})
// 获取个人资料
Register(authGroup, doc, basePath, "GET", "/profile", handlers.PersonalCustomer.GetProfile, RouteSpec{
Summary: "获取个人资料",

View File

@@ -1,44 +1 @@
package routes
import (
"github.com/gofiber/fiber/v2"
"github.com/break/junhong_cmp_fiber/internal/handler/h5"
"github.com/break/junhong_cmp_fiber/internal/model/dto"
"github.com/break/junhong_cmp_fiber/pkg/openapi"
)
// registerH5RechargeRoutes 注册H5充值路由
func registerH5RechargeRoutes(router fiber.Router, handler *h5.RechargeHandler, doc *openapi.Generator, basePath string) {
Register(router, doc, basePath, "POST", "/wallets/recharge", handler.Create, RouteSpec{
Summary: "创建充值订单",
Tags: []string{"H5 充值"},
Input: new(dto.CreateRechargeRequest),
Output: new(dto.RechargeResponse),
Auth: true,
})
Register(router, doc, basePath, "GET", "/wallets/recharge-check", handler.RechargeCheck, RouteSpec{
Summary: "充值预检",
Tags: []string{"H5 充值"},
Input: new(dto.RechargeCheckRequest),
Output: new(dto.RechargeCheckResponse),
Auth: true,
})
Register(router, doc, basePath, "GET", "/wallets/recharges", handler.List, RouteSpec{
Summary: "获取充值订单列表",
Tags: []string{"H5 充值"},
Input: new(dto.RechargeListRequest),
Output: new(dto.RechargeListResponse),
Auth: true,
})
Register(router, doc, basePath, "GET", "/wallets/recharges/:id", handler.Get, RouteSpec{
Summary: "获取充值订单详情",
Tags: []string{"H5 充值"},
Input: new(dto.GetRechargeRequest),
Output: new(dto.RechargeResponse),
Auth: true,
})
}

View File

@@ -28,15 +28,11 @@ func RegisterRoutesWithDoc(app *fiber.App, handlers *bootstrap.Handlers, middlew
adminGroup := app.Group("/api/admin")
RegisterAdminRoutes(adminGroup, handlers, middlewares, doc, "/api/admin")
// 4. H5 域 (挂载在 /api/h5)
h5Group := app.Group("/api/h5")
RegisterH5Routes(h5Group, handlers, middlewares, doc, "/api/h5")
// 5. 个人客户路由 (挂载在 /api/c/v1)
// 4. 个人客户路由 (挂载在 /api/c/v1)
personalGroup := app.Group("/api/c/v1")
RegisterPersonalCustomerRoutes(personalGroup, doc, "/api/c/v1", handlers, middlewares.PersonalAuth)
// 6. 支付回调路由 (挂载在 /api/callback无需认证)
// 5. 支付回调路由 (挂载在 /api/callback无需认证)
if handlers.PaymentCallback != nil {
callbackGroup := app.Group("/api/callback")
registerPaymentCallbackRoutes(callbackGroup, handlers.PaymentCallback, doc, "/api/callback")