package remark import ( "fmt" "strconv" "strings" ) // OrderRemark 结构化订单备注信息 type OrderRemark struct { ActivityID int64 IssueID int64 Count int64 ItemCardID int64 Slots []SlotInfo Coupons []CouponInfo } // SlotInfo 格位信息 (SlotIndex:Count) type SlotInfo struct { SlotIndex int64 // 从 0 开始的真实索引 Count int64 } // CouponInfo 优惠券信息 (CouponID:AppliedAmount) type CouponInfo struct { UserCouponID int64 AppliedAmount int64 } // Parse 解析备注字符串 func Parse(remark string) *OrderRemark { r := &OrderRemark{ Count: 1, // 默认为 1 } if remark == "" { return r } parts := strings.Split(remark, "|") for _, p := range parts { if strings.HasPrefix(p, "lottery:activity:") { r.ActivityID = parseInt64(p[17:]) } else if strings.HasPrefix(p, "activity:") { r.ActivityID = parseInt64(p[9:]) } else if strings.HasPrefix(p, "matching_game:issue:") { r.IssueID = parseInt64(p[20:]) } else if strings.HasPrefix(p, "issue:") { r.IssueID = parseInt64(p[6:]) } else if strings.HasPrefix(p, "count:") { n := parseInt64(p[6:]) if n > 0 { r.Count = n } } else if strings.HasPrefix(p, "itemcard:") { r.ItemCardID = parseInt64(p[9:]) } else if strings.HasPrefix(p, "slot:") { // 处理单个 slot:X r.Slots = append(r.Slots, SlotInfo{SlotIndex: parseInt64(p[5:]), Count: 1}) } else if strings.HasPrefix(p, "slots:") { // 处理多个 slots:X:Y,X:Y r.Slots = append(r.Slots, parseSlots(p[6:])...) } else if strings.HasPrefix(p, "c:") { // 处理优惠券 c:ID:AMT r.Coupons = append(r.Coupons, parseCoupon(p[2:])) } } return r } // String 将结构化数据转为 Remark 字符串 func (r *OrderRemark) String() string { var parts []string if r.ActivityID > 0 { parts = append(parts, fmt.Sprintf("lottery:activity:%d", r.ActivityID)) } if r.IssueID > 0 { parts = append(parts, fmt.Sprintf("issue:%d", r.IssueID)) } if r.Count > 0 { parts = append(parts, fmt.Sprintf("count:%d", r.Count)) } if r.ItemCardID > 0 { parts = append(parts, fmt.Sprintf("itemcard:%d", r.ItemCardID)) } if len(r.Slots) > 0 { var slotStrs []string for _, s := range r.Slots { slotStrs = append(slotStrs, fmt.Sprintf("%d:%d", s.SlotIndex, s.Count)) } parts = append(parts, "slots:"+strings.Join(slotStrs, ",")) } for _, c := range r.Coupons { parts = append(parts, fmt.Sprintf("c:%d:%d", c.UserCouponID, c.AppliedAmount)) } return strings.Join(parts, "|") } // GetTotalSlotsCount 获取总格位数量 func (r *OrderRemark) GetTotalSlotsCount() int64 { var total int64 for _, s := range r.Slots { total += s.Count } return total } // GetSlotAtIndex 根据抽奖序号获取对应的格位索引 func (r *OrderRemark) GetSlotAtIndex(drawIndex int64) int64 { var current int64 for _, s := range r.Slots { if drawIndex < current+s.Count { return s.SlotIndex } current += s.Count } return -1 } func parseInt64(s string) int64 { n, _ := strconv.ParseInt(s, 10, 64) return n } func parseSlots(s string) []SlotInfo { var slots []SlotInfo pairs := strings.Split(s, ",") for _, p := range pairs { kv := strings.Split(p, ":") if len(kv) == 2 { slots = append(slots, SlotInfo{ SlotIndex: parseInt64(kv[0]), Count: parseInt64(kv[1]), }) } } return slots } func parseCoupon(s string) CouponInfo { kv := strings.Split(s, ":") if len(kv) == 2 { return CouponInfo{ UserCouponID: parseInt64(kv[0]), AppliedAmount: parseInt64(kv[1]), } } return CouponInfo{} }