150 lines
3.5 KiB
Go

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{}
}