fix: 修复 OpenAPI 路径参数 path 标签缺失导致启动 panic 的问题
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 4m17s

- 为 enterprise_card_authorization_dto.go 中的 DTO 添加 path 标签
- 为 customer_account_dto.go 中的 DTO 添加 path 标签并重构结构
- 为 enterprise_dto.go 中的 DTO 添加 path 标签并重构结构
- 更新 handler 和 service 层使用正确的请求体类型
This commit is contained in:
2026-01-21 18:42:29 +08:00
parent 8677a54370
commit 23be0a7d3e
9 changed files with 69 additions and 16 deletions

View File

@@ -54,7 +54,7 @@ func (h *CustomerAccountHandler) Update(c *fiber.Ctx) error {
return errors.New(errors.CodeInvalidParam, "无效的账号ID") return errors.New(errors.CodeInvalidParam, "无效的账号ID")
} }
var req model.UpdateCustomerAccountReq var req model.UpdateCustomerAccountRequest
if err := c.BodyParser(&req); err != nil { if err := c.BodyParser(&req); err != nil {
return errors.New(errors.CodeInvalidParam, "请求参数解析失败") return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
} }
@@ -74,7 +74,7 @@ func (h *CustomerAccountHandler) UpdatePassword(c *fiber.Ctx) error {
return errors.New(errors.CodeInvalidParam, "无效的账号ID") return errors.New(errors.CodeInvalidParam, "无效的账号ID")
} }
var req model.UpdateCustomerAccountPasswordReq var req model.UpdateCustomerAccountPasswordRequest
if err := c.BodyParser(&req); err != nil { if err := c.BodyParser(&req); err != nil {
return errors.New(errors.CodeInvalidParam, "请求参数解析失败") return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
} }
@@ -93,7 +93,7 @@ func (h *CustomerAccountHandler) UpdateStatus(c *fiber.Ctx) error {
return errors.New(errors.CodeInvalidParam, "无效的账号ID") return errors.New(errors.CodeInvalidParam, "无效的账号ID")
} }
var req model.UpdateCustomerAccountStatusReq var req model.UpdateCustomerAccountStatusRequest
if err := c.BodyParser(&req); err != nil { if err := c.BodyParser(&req); err != nil {
return errors.New(errors.CodeInvalidParam, "请求参数解析失败") return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
} }

View File

@@ -54,7 +54,7 @@ func (h *EnterpriseHandler) Update(c *fiber.Ctx) error {
return errors.New(errors.CodeInvalidParam, "无效的企业ID") return errors.New(errors.CodeInvalidParam, "无效的企业ID")
} }
var req model.UpdateEnterpriseReq var req model.UpdateEnterpriseBody
if err := c.BodyParser(&req); err != nil { if err := c.BodyParser(&req); err != nil {
return errors.New(errors.CodeInvalidParam, "请求参数解析失败") return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
} }
@@ -74,7 +74,7 @@ func (h *EnterpriseHandler) UpdateStatus(c *fiber.Ctx) error {
return errors.New(errors.CodeInvalidParam, "无效的企业ID") return errors.New(errors.CodeInvalidParam, "无效的企业ID")
} }
var req model.UpdateEnterpriseStatusReq var req model.UpdateEnterpriseStatusBody
if err := c.BodyParser(&req); err != nil { if err := c.BodyParser(&req); err != nil {
return errors.New(errors.CodeInvalidParam, "请求参数解析失败") return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
} }
@@ -93,7 +93,7 @@ func (h *EnterpriseHandler) UpdatePassword(c *fiber.Ctx) error {
return errors.New(errors.CodeInvalidParam, "无效的企业ID") return errors.New(errors.CodeInvalidParam, "无效的企业ID")
} }
var req model.UpdateEnterprisePasswordReq var req model.UpdateEnterprisePasswordBody
if err := c.BodyParser(&req); err != nil { if err := c.BodyParser(&req); err != nil {
return errors.New(errors.CodeInvalidParam, "请求参数解析失败") return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
} }

View File

@@ -49,6 +49,7 @@ type WithdrawalRequestPageResult struct {
// ApproveWithdrawalReq 审批通过提现申请请求 // ApproveWithdrawalReq 审批通过提现申请请求
type ApproveWithdrawalReq struct { type ApproveWithdrawalReq struct {
ID uint `json:"-" params:"id" path:"id" validate:"required" description:"提现申请ID"`
PaymentType string `json:"payment_type" validate:"required,oneof=manual" required:"true" description:"放款类型目前只支持manual人工打款"` PaymentType string `json:"payment_type" validate:"required,oneof=manual" required:"true" description:"放款类型目前只支持manual人工打款"`
Amount *int64 `json:"amount" validate:"omitempty,min=1" minimum:"1" description:"修正后的提现金额(分),不填则使用原金额"` Amount *int64 `json:"amount" validate:"omitempty,min=1" minimum:"1" description:"修正后的提现金额(分),不填则使用原金额"`
WithdrawalMethod *string `json:"withdrawal_method" validate:"omitempty,oneof=alipay wechat bank" description:"修正后的收款类型 (alipay:支付宝, wechat:微信, bank:银行卡)"` WithdrawalMethod *string `json:"withdrawal_method" validate:"omitempty,oneof=alipay wechat bank" description:"修正后的收款类型 (alipay:支付宝, wechat:微信, bank:银行卡)"`
@@ -59,6 +60,7 @@ type ApproveWithdrawalReq struct {
// RejectWithdrawalReq 拒绝提现申请请求 // RejectWithdrawalReq 拒绝提现申请请求
type RejectWithdrawalReq struct { type RejectWithdrawalReq struct {
ID uint `json:"-" params:"id" path:"id" validate:"required" description:"提现申请ID"`
Remark string `json:"remark" validate:"required,max=500" required:"true" maxLength:"500" description:"拒绝原因(必填)"` Remark string `json:"remark" validate:"required,max=500" required:"true" maxLength:"500" description:"拒绝原因(必填)"`
} }

View File

@@ -40,15 +40,33 @@ type CreateCustomerAccountReq struct {
ShopID uint `json:"shop_id" validate:"required" required:"true" description:"店铺ID"` ShopID uint `json:"shop_id" validate:"required" required:"true" description:"店铺ID"`
} }
type UpdateCustomerAccountReq struct { type UpdateCustomerAccountRequest struct {
Username *string `json:"username" validate:"omitempty,min=2,max=50" minimum:"2" maximum:"50" description:"用户名"` Username *string `json:"username" validate:"omitempty,min=2,max=50" minimum:"2" maximum:"50" description:"用户名"`
Phone *string `json:"phone" validate:"omitempty,len=11" description:"手机号"` Phone *string `json:"phone" validate:"omitempty,len=11" description:"手机号"`
} }
type UpdateCustomerAccountPasswordReq struct { // UpdateCustomerAccountReq 更新客户账号请求(用于文档生成,包含路径参数)
type UpdateCustomerAccountReq struct {
IDReq
UpdateCustomerAccountRequest
}
type UpdateCustomerAccountPasswordRequest struct {
Password string `json:"password" validate:"required,min=6,max=20" required:"true" minimum:"6" maximum:"20" description:"新密码"` Password string `json:"password" validate:"required,min=6,max=20" required:"true" minimum:"6" maximum:"20" description:"新密码"`
} }
type UpdateCustomerAccountStatusReq struct { // UpdateCustomerAccountPasswordReq 修改客户账号密码请求(用于文档生成,包含路径参数)
type UpdateCustomerAccountPasswordReq struct {
IDReq
UpdateCustomerAccountPasswordRequest
}
type UpdateCustomerAccountStatusRequest struct {
Status int `json:"status" validate:"required,oneof=0 1" required:"true" enum:"0,1" description:"状态0=禁用, 1=启用)"` Status int `json:"status" validate:"required,oneof=0 1" required:"true" enum:"0,1" description:"状态0=禁用, 1=启用)"`
} }
// UpdateCustomerAccountStatusReq 修改客户账号状态请求(用于文档生成,包含路径参数)
type UpdateCustomerAccountStatusReq struct {
IDReq
UpdateCustomerAccountStatusRequest
}

View File

@@ -1,6 +1,7 @@
package model package model
type AllocateCardsPreviewReq struct { type AllocateCardsPreviewReq struct {
ID uint `json:"-" params:"id" path:"id" validate:"required" required:"true" description:"企业ID"`
ICCIDs []string `json:"iccids" validate:"required,min=1,max=1000,dive,required" required:"true" description:"需要授权的 ICCID 列表最多1000个"` ICCIDs []string `json:"iccids" validate:"required,min=1,max=1000,dive,required" required:"true" description:"需要授权的 ICCID 列表最多1000个"`
} }
@@ -46,6 +47,7 @@ type AllocateCardsPreviewResp struct {
} }
type AllocateCardsReq struct { type AllocateCardsReq struct {
ID uint `json:"-" params:"id" path:"id" validate:"required" required:"true" description:"企业ID"`
ICCIDs []string `json:"iccids" validate:"required,min=1,max=1000,dive,required" required:"true" description:"需要授权的 ICCID 列表"` ICCIDs []string `json:"iccids" validate:"required,min=1,max=1000,dive,required" required:"true" description:"需要授权的 ICCID 列表"`
ConfirmDeviceBundles bool `json:"confirm_device_bundles" description:"确认整体授权设备下所有卡"` ConfirmDeviceBundles bool `json:"confirm_device_bundles" description:"确认整体授权设备下所有卡"`
} }
@@ -65,6 +67,7 @@ type AllocateCardsResp struct {
} }
type RecallCardsReq struct { type RecallCardsReq struct {
ID uint `json:"-" params:"id" path:"id" validate:"required" required:"true" description:"企业ID"`
ICCIDs []string `json:"iccids" validate:"required,min=1,max=1000,dive,required" required:"true" description:"需要回收授权的 ICCID 列表"` ICCIDs []string `json:"iccids" validate:"required,min=1,max=1000,dive,required" required:"true" description:"需要回收授权的 ICCID 列表"`
} }
@@ -83,6 +86,7 @@ type RecallCardsResp struct {
} }
type EnterpriseCardListReq struct { type EnterpriseCardListReq struct {
ID uint `json:"-" params:"id" path:"id" validate:"required" required:"true" description:"企业ID"`
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码"` Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码"`
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量"` PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量"`
Status *int `json:"status" query:"status" description:"卡状态"` Status *int `json:"status" query:"status" description:"卡状态"`
@@ -113,3 +117,15 @@ type EnterpriseCardPageResult struct {
Page int `json:"page" description:"当前页码"` Page int `json:"page" description:"当前页码"`
Size int `json:"size" description:"每页数量"` Size int `json:"size" description:"每页数量"`
} }
// SuspendCardReq 停机卡请求
type SuspendCardReq struct {
ID uint `json:"-" params:"id" path:"id" validate:"required" required:"true" description:"企业ID"`
CardID uint `json:"-" params:"card_id" path:"card_id" validate:"required" required:"true" description:"卡ID"`
}
// ResumeCardReq 复机卡请求
type ResumeCardReq struct {
ID uint `json:"-" params:"id" path:"id" validate:"required" required:"true" description:"企业ID"`
CardID uint `json:"-" params:"card_id" path:"card_id" validate:"required" required:"true" description:"卡ID"`
}

View File

@@ -16,7 +16,7 @@ type CreateEnterpriseReq struct {
Address string `json:"address" validate:"max=255" maximum:"255" description:"详细地址"` Address string `json:"address" validate:"max=255" maximum:"255" description:"详细地址"`
} }
type UpdateEnterpriseReq struct { type UpdateEnterpriseBody struct {
OwnerShopID *uint `json:"owner_shop_id" description:"归属店铺ID"` OwnerShopID *uint `json:"owner_shop_id" description:"归属店铺ID"`
EnterpriseName *string `json:"enterprise_name" validate:"omitempty,max=100" maximum:"100" description:"企业名称"` EnterpriseName *string `json:"enterprise_name" validate:"omitempty,max=100" maximum:"100" description:"企业名称"`
EnterpriseCode *string `json:"enterprise_code" validate:"omitempty,max=50" maximum:"50" description:"企业编号"` EnterpriseCode *string `json:"enterprise_code" validate:"omitempty,max=50" maximum:"50" description:"企业编号"`
@@ -30,6 +30,11 @@ type UpdateEnterpriseReq struct {
Address *string `json:"address" validate:"omitempty,max=255" maximum:"255" description:"详细地址"` Address *string `json:"address" validate:"omitempty,max=255" maximum:"255" description:"详细地址"`
} }
type UpdateEnterpriseReq struct {
IDReq
UpdateEnterpriseBody
}
type EnterpriseListReq struct { type EnterpriseListReq struct {
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码默认1"` Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码默认1"`
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量默认20最大100"` PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量默认20最大100"`
@@ -67,14 +72,24 @@ type EnterprisePageResult struct {
Size int `json:"size" description:"每页数量"` Size int `json:"size" description:"每页数量"`
} }
type UpdateEnterpriseStatusReq struct { type UpdateEnterpriseStatusBody struct {
Status int `json:"status" validate:"required,oneof=0 1" required:"true" enum:"0,1" description:"状态0=禁用, 1=启用)"` Status int `json:"status" validate:"required,oneof=0 1" required:"true" enum:"0,1" description:"状态0=禁用, 1=启用)"`
} }
type UpdateEnterprisePasswordReq struct { type UpdateEnterpriseStatusReq struct {
IDReq
UpdateEnterpriseStatusBody
}
type UpdateEnterprisePasswordBody struct {
Password string `json:"password" validate:"required,min=6,max=20" required:"true" minimum:"6" maximum:"20" description:"新密码"` Password string `json:"password" validate:"required,min=6,max=20" required:"true" minimum:"6" maximum:"20" description:"新密码"`
} }
type UpdateEnterprisePasswordReq struct {
IDReq
UpdateEnterprisePasswordBody
}
type CreateEnterpriseResp struct { type CreateEnterpriseResp struct {
Enterprise EnterpriseItem `json:"enterprise" description:"企业信息"` Enterprise EnterpriseItem `json:"enterprise" description:"企业信息"`
AccountID uint `json:"account_id" description:"账号ID"` AccountID uint `json:"account_id" description:"账号ID"`
@@ -84,7 +99,7 @@ type CreateEnterpriseResp struct {
type CreateEnterpriseRequest = CreateEnterpriseReq type CreateEnterpriseRequest = CreateEnterpriseReq
// UpdateEnterpriseRequest 更新企业请求(兼容旧接口) // UpdateEnterpriseRequest 更新企业请求(兼容旧接口)
type UpdateEnterpriseRequest = UpdateEnterpriseReq type UpdateEnterpriseRequest = UpdateEnterpriseBody
// EnterpriseResponse 企业响应(兼容旧接口) // EnterpriseResponse 企业响应(兼容旧接口)
type EnterpriseResponse = EnterpriseItem type EnterpriseResponse = EnterpriseItem

View File

@@ -42,6 +42,7 @@ type ShopCommissionSummaryPageResult struct {
// ShopWithdrawalRequestListReq 代理商提现记录查询请求 // ShopWithdrawalRequestListReq 代理商提现记录查询请求
type ShopWithdrawalRequestListReq struct { type ShopWithdrawalRequestListReq struct {
ShopID uint `json:"-" params:"shop_id" path:"shop_id" validate:"required" description:"店铺ID"`
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码默认1"` Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码默认1"`
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量默认20最大100"` PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量默认20最大100"`
WithdrawalNo string `json:"withdrawal_no" query:"withdrawal_no" validate:"omitempty,max=50" maxLength:"50" description:"提现单号(精确查询)"` WithdrawalNo string `json:"withdrawal_no" query:"withdrawal_no" validate:"omitempty,max=50" maxLength:"50" description:"提现单号(精确查询)"`
@@ -92,6 +93,7 @@ type ShopWithdrawalRequestPageResult struct {
// ShopCommissionRecordListReq 代理商佣金明细查询请求 // ShopCommissionRecordListReq 代理商佣金明细查询请求
type ShopCommissionRecordListReq struct { type ShopCommissionRecordListReq struct {
ShopID uint `json:"-" params:"shop_id" path:"shop_id" validate:"required" description:"店铺ID"`
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码默认1"` Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码默认1"`
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量默认20最大100"` PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量默认20最大100"`
CommissionType string `json:"commission_type" query:"commission_type" validate:"omitempty,oneof=one_time long_term" description:"佣金类型 (one_time:一次性, long_term:长期)"` CommissionType string `json:"commission_type" query:"commission_type" validate:"omitempty,oneof=one_time long_term" description:"佣金类型 (one_time:一次性, long_term:长期)"`

View File

@@ -47,7 +47,7 @@ func registerEnterpriseCardRoutes(router fiber.Router, handler *admin.Enterprise
Register(enterprises, doc, groupPath, "POST", "/:id/cards/:card_id/suspend", handler.SuspendCard, RouteSpec{ Register(enterprises, doc, groupPath, "POST", "/:id/cards/:card_id/suspend", handler.SuspendCard, RouteSpec{
Summary: "停机卡", Summary: "停机卡",
Tags: []string{"企业卡授权"}, Tags: []string{"企业卡授权"},
Input: nil, Input: new(model.SuspendCardReq),
Output: nil, Output: nil,
Auth: true, Auth: true,
}) })
@@ -55,7 +55,7 @@ func registerEnterpriseCardRoutes(router fiber.Router, handler *admin.Enterprise
Register(enterprises, doc, groupPath, "POST", "/:id/cards/:card_id/resume", handler.ResumeCard, RouteSpec{ Register(enterprises, doc, groupPath, "POST", "/:id/cards/:card_id/resume", handler.ResumeCard, RouteSpec{
Summary: "复机卡", Summary: "复机卡",
Tags: []string{"企业卡授权"}, Tags: []string{"企业卡授权"},
Input: nil, Input: new(model.ResumeCardReq),
Output: nil, Output: nil,
Auth: true, Auth: true,
}) })

View File

@@ -196,7 +196,7 @@ func (s *Service) Create(ctx context.Context, req *model.CreateCustomerAccountRe
}, nil }, nil
} }
func (s *Service) Update(ctx context.Context, id uint, req *model.UpdateCustomerAccountReq) (*model.CustomerAccountItem, error) { func (s *Service) Update(ctx context.Context, id uint, req *model.UpdateCustomerAccountRequest) (*model.CustomerAccountItem, error) {
currentUserID := middleware.GetUserIDFromContext(ctx) currentUserID := middleware.GetUserIDFromContext(ctx)
if currentUserID == 0 { if currentUserID == 0 {
return nil, errors.New(errors.CodeUnauthorized, "未授权访问") return nil, errors.New(errors.CodeUnauthorized, "未授权访问")