合并 main 分支并融合订单列表最小化与 SQL 治理

- Auth/权限中间件取 main 演进版(错误细分、token 来源),保留 dev 的用户 cookie 与登出撤销语义
- 后台订单列表:融合 main 的首页免 COUNT 优化与关键词索引路由,保留 dev 的最小化 AdminOrderListItemDTO(结账明细仍由详情接口返回,同步调整对应集成测试)
- 保留 dev 的 token_version 冻结/解冻递增与 main 的状态变化判断及通知
- 前端:保留 dev 登出接口与 main 的 fetchMe silent 参数、SSE 登录跳转;后台订单表按 dev 最小化 DTO 移除号主到手列
This commit is contained in:
yml2213
2026-09-05 11:43:13 +08:00
294 changed files with 30171 additions and 13439 deletions
+28 -2
View File
@@ -10,6 +10,7 @@ import (
"hfb_sys/backend/internal/modules/distribution"
"hfb_sys/backend/internal/modules/notification"
"hfb_sys/backend/internal/modules/rentergrowth"
"hfb_sys/backend/internal/processlog"
"gorm.io/datatypes"
"gorm.io/gorm"
@@ -45,6 +46,10 @@ func (r *Repository) Create(ctx context.Context, renterID uint64, req CreateRequ
if err != nil {
return err
}
accountSource, sourceChannel, err := orderAccountSourceSnapshot(tx, listing.ID)
if err != nil {
return err
}
orderNo, err := newOrderNo()
if err != nil {
return err
@@ -94,6 +99,8 @@ func (r *Repository) Create(ctx context.Context, renterID uint64, req CreateRequ
RenterGrowthLevelName: growthSnapshot.LevelName,
RenterDiscountBps: growthSnapshot.DiscountBps,
AccountSnapshot: snapshot,
AccountSource: accountSource,
SourceChannel: sourceChannel,
Status: orderStatusPendingPayment,
HandoffStatus: handoffStatusNone,
HandoffMode: listingHandoffMode(listing),
@@ -136,6 +143,18 @@ func (r *Repository) Create(ctx context.Context, renterID uint64, req CreateRequ
return r.FindForUser(ctx, renterID, createdID)
}
func orderAccountSourceSnapshot(tx *gorm.DB, listingID uint64) (string, string, error) {
var upload model.ListingUpload
err := tx.Where("listing_id = ?", listingID).Order("id DESC").First(&upload).Error
if err == gorm.ErrRecordNotFound {
return "internal", "", nil
}
if err != nil {
return "", "", err
}
return "external", upload.SourceChannel, nil
}
func listingHandoffMode(listing model.RentalListing) string {
if listing.HandoffMode != "" {
return listing.HandoffMode
@@ -378,8 +397,11 @@ func (r *Repository) Cancel(ctx context.Context, userID uint64, orderID uint64)
return err
}
}
if err := releaseAssetsForRentalIfIdle(tx, &order, listing, account); err != nil {
return err
// 已付款订单取消后需等待客服审核退款,审核通过前继续占用账号。
if beforeStatus == orderStatusPendingPayment {
if err := releaseAssetsForRentalIfIdle(tx, &order, listing, account); err != nil {
return err
}
}
if err := closePendingOrderPayments(tx, order.ID, "order_cancel"); err != nil {
return err
@@ -428,6 +450,7 @@ func (r *Repository) ConfirmReceive(ctx context.Context, userID uint64, orderID
if order.Status != orderStatusPendingHandoff || order.HandoffStatus != handoffStatusPendingRenterConfirm {
return ErrOrderCannotReceive
}
before := orderState(order)
now := time.Now()
if err := tx.Model(&model.HandoffRecord{}).
Where("order_id = ? AND type IN ?", order.ID, []string{"owner_handoff", "platform_handoff"}).
@@ -438,6 +461,9 @@ func (r *Repository) ConfirmReceive(ctx context.Context, userID uint64, orderID
order.HandoffStatus = handoffStatusReceived
order.EstimatedDurationHours = estimateOrderDurationHours(order.AccountSnapshot)
order.RentedAt = &now
if err := appendOrderEvent(tx, order, "handoff", "renter_received_confirmed", processlog.ActorUser, userID, processlog.ActorUser, &order.OwnerID, "租客确认已收号,订单开始租用。", "", nil, before, nil); err != nil {
return err
}
orderID := order.ID
if isPlatformHandoffOrder(order) {
if err := appendManagedAdminNotification(tx, order, "handoff", "租客已确认收号", "代管订单已进入使用中。"); err != nil {