feat: add order governance flags and reconciliation

This commit is contained in:
2026-01-16 13:29:59 +08:00
parent 7ead7fc11c
commit e5f40287c3
17 changed files with 1247 additions and 103 deletions

View File

@@ -165,6 +165,10 @@ type SuperOrderListFilter struct {
Type *consts.OrderType `query:"type"`
// Status 订单状态过滤。
Status *consts.OrderStatus `query:"status"`
// IsFlagged 是否标记为问题订单true/false
IsFlagged *bool `query:"is_flagged"`
// IsReconciled 是否已完成对账true/false
IsReconciled *bool `query:"is_reconciled"`
// CreatedAtFrom 创建时间起始RFC3339
CreatedAtFrom *string `query:"created_at_from"`
// CreatedAtTo 创建时间结束RFC3339
@@ -549,6 +553,22 @@ type SuperOrderItem struct {
PaidAt string `json:"paid_at"`
// RefundedAt 退款时间RFC3339
RefundedAt string `json:"refunded_at"`
// IsFlagged 是否标记为问题订单。
IsFlagged bool `json:"is_flagged"`
// FlagReason 问题标记原因。
FlagReason string `json:"flag_reason"`
// FlaggedBy 标记操作者ID。
FlaggedBy int64 `json:"flagged_by"`
// FlaggedAt 标记时间RFC3339
FlaggedAt string `json:"flagged_at"`
// IsReconciled 是否完成对账。
IsReconciled bool `json:"is_reconciled"`
// ReconcileNote 对账说明。
ReconcileNote string `json:"reconcile_note"`
// ReconciledBy 对账操作者ID。
ReconciledBy int64 `json:"reconciled_by"`
// ReconciledAt 对账时间RFC3339
ReconciledAt string `json:"reconciled_at"`
// CreatedAt 创建时间RFC3339
CreatedAt string `json:"created_at"`
// UpdatedAt 更新时间RFC3339
@@ -621,6 +641,20 @@ type SuperOrderRefundForm struct {
IdempotencyKey string `json:"idempotency_key"`
}
type SuperOrderFlagForm struct {
// IsFlagged 是否标记为问题订单。
IsFlagged bool `json:"is_flagged"`
// Reason 标记原因(标记为问题时必填)。
Reason string `json:"reason"`
}
type SuperOrderReconcileForm struct {
// IsReconciled 是否完成对账。
IsReconciled bool `json:"is_reconciled"`
// Note 对账说明(可选)。
Note string `json:"note"`
}
// AdminContentItem for super admin view
type AdminContentItem struct {
// Content 内容摘要信息。

View File

@@ -4,6 +4,7 @@ import (
dto "quyun/v2/app/http/super/v1/dto"
"quyun/v2/app/requests"
"quyun/v2/app/services"
"quyun/v2/database/models"
"github.com/gofiber/fiber/v3"
)
@@ -42,6 +43,42 @@ func (c *orders) Get(ctx fiber.Ctx, id int64) (*dto.SuperOrderDetail, error) {
return services.Super.GetOrder(ctx, id)
}
// Flag order
//
// @Router /super/v1/orders/:id<int>/flag [post]
// @Summary Flag order
// @Description Flag or unflag an order as problematic
// @Tags Order
// @Accept json
// @Produce json
// @Param id path int64 true "Order ID"
// @Param form body dto.SuperOrderFlagForm true "Flag form"
// @Success 200 {string} string "OK"
// @Bind user local key(__ctx_user)
// @Bind id path
// @Bind form body
func (c *orders) Flag(ctx fiber.Ctx, user *models.User, id int64, form *dto.SuperOrderFlagForm) error {
return services.Super.FlagOrder(ctx, user.ID, id, form)
}
// Reconcile order
//
// @Router /super/v1/orders/:id<int>/reconcile [post]
// @Summary Reconcile order
// @Description Mark or unmark order reconciliation status
// @Tags Order
// @Accept json
// @Produce json
// @Param id path int64 true "Order ID"
// @Param form body dto.SuperOrderReconcileForm true "Reconcile form"
// @Success 200 {string} string "OK"
// @Bind user local key(__ctx_user)
// @Bind id path
// @Bind form body
func (c *orders) Reconcile(ctx fiber.Ctx, user *models.User, id int64, form *dto.SuperOrderReconcileForm) error {
return services.Super.ReconcileOrder(ctx, user.ID, id, form)
}
// Refund order
//
// @Router /super/v1/orders/:id<int>/refund [post]

View File

@@ -267,6 +267,20 @@ func (r *Routes) Register(router fiber.Router) {
router.Get("/super/v1/orders/statistics"[len(r.Path()):], DataFunc0(
r.orders.Statistics,
))
r.log.Debugf("Registering route: Post /super/v1/orders/:id<int>/flag -> orders.Flag")
router.Post("/super/v1/orders/:id<int>/flag"[len(r.Path()):], Func3(
r.orders.Flag,
Local[*models.User]("__ctx_user"),
PathParam[int64]("id"),
Body[dto.SuperOrderFlagForm]("form"),
))
r.log.Debugf("Registering route: Post /super/v1/orders/:id<int>/reconcile -> orders.Reconcile")
router.Post("/super/v1/orders/:id<int>/reconcile"[len(r.Path()):], Func3(
r.orders.Reconcile,
Local[*models.User]("__ctx_user"),
PathParam[int64]("id"),
Body[dto.SuperOrderReconcileForm]("form"),
))
r.log.Debugf("Registering route: Post /super/v1/orders/:id<int>/refund -> orders.Refund")
router.Post("/super/v1/orders/:id<int>/refund"[len(r.Path()):], Func2(
r.orders.Refund,