feat: add scheduled automatic task matching

This commit is contained in:
richjohnrambo
2026-10-13 15:21:08 +08:00
parent 2a3c411c9b
commit 45ef10b2af
4 changed files with 192 additions and 26 deletions
+33 -1
View File
@@ -77,6 +77,8 @@ type Order struct {
Status string `json:"status"`
StatusText string `json:"status_text"`
Message string `json:"message"`
ScheduledMatchAt string `json:"scheduled_match_at,omitempty"`
DispatchDelay int `json:"dispatch_delay_seconds,omitempty"`
DeadlineAt string `json:"deadline_at"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
@@ -235,14 +237,39 @@ func (s *Service) Claim(ctx context.Context, tenantID, memberID, hallID int64) (
}
now := s.now().UTC()
row, err := s.repository.ClaimTask(ctx, store.ClaimTaskInput{TenantID: tenantID, MemberID: memberID,
HallID: hallID, MinimumAmount: policy.MinimumAmount, DeadlineAt: now.Add(policy.Deadline), OrderNo: newNumber("TO", now)})
HallID: hallID, MinimumAmount: policy.MinimumAmount, AutoDelay: policy.AutoDelay,
DeadlineAt: now.Add(policy.Deadline), OrderNo: newNumber("TO", now)})
if err != nil {
return nil, err
}
result := orderFromStore(*row, false)
s.scheduleAutoMatch(tenantID, memberID, row.ID, row.RuleSnapshot, policy)
return &result, nil
}
func (s *Service) scheduleAutoMatch(tenantID, memberID, orderID int64, raw json.RawMessage, policy taskPolicy) {
var snapshot map[string]any
if json.Unmarshal(raw, &snapshot) != nil || snapshot["dispatch_mode"] != "auto" {
return
}
matchAt, err := time.Parse(time.RFC3339, fmt.Sprint(snapshot["scheduled_match_at"]))
if err != nil {
return
}
delay := time.Until(matchAt)
if delay < 0 {
delay = 0
}
go func() {
timer := time.NewTimer(delay)
defer timer.Stop()
<-timer.C
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
_ = s.repository.AutoMatchTaskOrder(ctx, tenantID, memberID, orderID, policy.AutoDelay, policy.AutoMinAmount, policy.AutoMaxAmount)
}()
}
func (s *Service) Orders(ctx context.Context, tenantID, memberID int64, page, pageSize int, status string) (*OrderPage, error) {
if page == 0 {
page = 1
@@ -368,6 +395,11 @@ func orderFromStore(row store.TaskOrder, detail bool) Order {
UnitPriceAmount: row.UnitPriceAmount, TotalAmount: row.TotalAmount, CommissionAmount: row.CommissionAmount,
Currency: row.Currency, Status: status, StatusText: orderStatusText(row.OrderStatus), Message: row.Message,
DeadlineAt: row.DeadlineAt, CreatedAt: row.CreatedAt, UpdatedAt: row.UpdatedAt}
var snapshot map[string]any
if json.Unmarshal(row.RuleSnapshot, &snapshot) == nil {
result.ScheduledMatchAt, _ = snapshot["scheduled_match_at"].(string)
result.DispatchDelay = intValue(snapshot["dispatch_delay_seconds"])
}
if !detail {
return result
}