Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Failing after 8h37m36s
- M2 批量换绑表头改为“平台登录账号”,只认手机号,细分格式、不存在、多匹配、非平台、已禁用失败原因 - M3 后台订单列表与详情返回 C 端在线购买的交易流水号、支付渠道、商户名称,详情新增全部支付单 payments - M16 预警规则不再返回 real_data_mb,预警列表/详情新增 threshold_mb,导出末列追加“阈值流量(MB)” - M23 设备导入 IMEI 必填,空 IMEI 行记为失败 - OpenSpec Change fix-august-iteration-follow-up-gaps:13/18,导入任务、导出任务的 Worker 端到端验证与前端/运营通知待部署后完成
161 lines
4.6 KiB
Go
161 lines
4.6 KiB
Go
package admin
|
||
|
||
import (
|
||
"strconv"
|
||
|
||
"github.com/go-playground/validator/v10"
|
||
"github.com/gofiber/fiber/v2"
|
||
|
||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||
"github.com/break/junhong_cmp_fiber/internal/model/dto"
|
||
orderService "github.com/break/junhong_cmp_fiber/internal/service/order"
|
||
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
||
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
||
"github.com/break/junhong_cmp_fiber/pkg/middleware"
|
||
"github.com/break/junhong_cmp_fiber/pkg/response"
|
||
"github.com/break/junhong_cmp_fiber/pkg/utils"
|
||
)
|
||
|
||
// OrderHandler 后台订单处理器
|
||
type OrderHandler struct {
|
||
service *orderService.Service
|
||
validator *validator.Validate
|
||
}
|
||
|
||
// NewOrderHandler 创建后台订单处理器
|
||
func NewOrderHandler(service *orderService.Service, validator *validator.Validate) *OrderHandler {
|
||
return &OrderHandler{service: service, validator: validator}
|
||
}
|
||
|
||
// Create 创建后台订单
|
||
// POST /api/admin/orders
|
||
func (h *OrderHandler) Create(c *fiber.Ctx) error {
|
||
var req dto.CreateAdminOrderRequest
|
||
if err := c.BodyParser(&req); err != nil {
|
||
return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
|
||
}
|
||
|
||
// 验证请求参数(payment_method 必须为 wallet 或 offline)
|
||
if err := h.validator.Struct(&req); err != nil {
|
||
return errors.New(errors.CodeInvalidParam)
|
||
}
|
||
|
||
ctx := c.UserContext()
|
||
userType := middleware.GetUserTypeFromContext(ctx)
|
||
shopID := middleware.GetShopIDFromContext(ctx)
|
||
|
||
// 线下支付仅限平台用户
|
||
if req.PaymentMethod == model.PaymentMethodOffline {
|
||
if userType != constants.UserTypeSuperAdmin && userType != constants.UserTypePlatform {
|
||
return errors.New(errors.CodeForbidden, "只有平台可以使用线下支付")
|
||
}
|
||
} else if req.PaymentMethod == model.PaymentMethodWallet {
|
||
if userType != constants.UserTypeAgent && userType != constants.UserTypePlatform && userType != constants.UserTypeSuperAdmin {
|
||
return errors.New(errors.CodeForbidden, "无权创建订单")
|
||
}
|
||
} else {
|
||
// 防御性分支:DTO 验证已限制,此处兜底
|
||
return errors.New(errors.CodeInvalidParam, "后台仅支持钱包支付和线下支付")
|
||
}
|
||
|
||
buyerType := ""
|
||
buyerID := uint(0)
|
||
if userType == constants.UserTypeAgent {
|
||
buyerType = model.BuyerTypeAgent
|
||
buyerID = shopID
|
||
}
|
||
|
||
order, err := h.service.CreateAdminOrder(ctx, &req, buyerType, buyerID)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
return response.Success(c, order)
|
||
}
|
||
|
||
func (h *OrderHandler) Get(c *fiber.Ctx) error {
|
||
id, err := strconv.ParseUint(c.Params("id"), 10, 64)
|
||
if err != nil {
|
||
return errors.New(errors.CodeInvalidParam, "无效的订单ID")
|
||
}
|
||
|
||
order, err := h.service.GetDetail(c.UserContext(), uint(id))
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
return response.Success(c, order)
|
||
}
|
||
|
||
func (h *OrderHandler) List(c *fiber.Ctx) error {
|
||
var req dto.OrderListRequest
|
||
if err := c.QueryParser(&req); err != nil {
|
||
return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
|
||
}
|
||
startTime, endTime, err := utils.ParseTimeRange(req.StartTime, req.EndTime)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
ctx := c.UserContext()
|
||
userType := middleware.GetUserTypeFromContext(ctx)
|
||
shopID := middleware.GetShopIDFromContext(ctx)
|
||
|
||
var buyerType string
|
||
var buyerID uint
|
||
|
||
if userType == constants.UserTypeAgent {
|
||
buyerType = model.BuyerTypeAgent
|
||
buyerID = shopID
|
||
} else {
|
||
buyerType = ""
|
||
buyerID = 0
|
||
}
|
||
|
||
orders, err := h.service.List(ctx, &req, startTime, endTime, buyerType, buyerID)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
return response.Success(c, orders)
|
||
}
|
||
|
||
func (h *OrderHandler) Cancel(c *fiber.Ctx) error {
|
||
id, err := strconv.ParseUint(c.Params("id"), 10, 64)
|
||
if err != nil {
|
||
return errors.New(errors.CodeInvalidParam, "无效的订单ID")
|
||
}
|
||
|
||
ctx := c.UserContext()
|
||
userType := middleware.GetUserTypeFromContext(ctx)
|
||
shopID := middleware.GetShopIDFromContext(ctx)
|
||
|
||
if userType != constants.UserTypeAgent {
|
||
return errors.New(errors.CodeForbidden, "只有代理账号可以取消订单")
|
||
}
|
||
|
||
if err := h.service.Cancel(ctx, uint(id), model.BuyerTypeAgent, shopID); err != nil {
|
||
return err
|
||
}
|
||
|
||
return response.Success(c, nil)
|
||
}
|
||
|
||
// PurchaseCheck 代购订单预检接口
|
||
// 路由: POST /api/admin/orders/purchase-check
|
||
// 参数: order_type(订单类型), resource_id(资源ID), package_ids(套餐ID列表)
|
||
// 响应: 套餐总价、强充要求、实际支付金额等预检结果
|
||
func (h *OrderHandler) PurchaseCheck(c *fiber.Ctx) error {
|
||
var req dto.PurchaseCheckRequest
|
||
if err := c.BodyParser(&req); err != nil {
|
||
return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
|
||
}
|
||
|
||
result, err := h.service.GetPurchaseCheck(c.UserContext(), &req)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
return response.Success(c, result)
|
||
}
|