150 lines
3.5 KiB
Go
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{}
|
|
}
|