owpengram-server/internal/domain/star_gift.go

115 lines
4.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package domain
import (
"encoding/base64"
"errors"
"strconv"
)
// Star giftpayments.sendStarsForm + inputInvoiceStarGift领域模型。目录是从已 seed 的
// animated_emoji 合成的静态集合StarGiftpeer 收到的礼物实例落 peer_star_giftsSavedStarGift
// 与 Stars 账本配合:发礼 Debit、转换回 Stars 时 Credit。
// StarGift 是一个可购买礼物目录项(合成、非用户持有)。
type StarGift struct {
ID int64
Stars int64 // 购买价Stars
ConvertStars int64 // 收礼人可转换回的 Starsv1 = Stars全额
Title string // 可选标题
Sticker Document // 礼物贴纸快照tg 投影必须是带 sticker 属性的有效 Document否则客户端丢弃
}
// SavedStarGift 是一条已收到的礼物实例peer_star_gifts 一行)。
type SavedStarGift struct {
ID int64
Owner Peer // 收礼 peeruser/channel
FromUserID int64 // 送礼人(匿名也保留真实值供账本,下发时按 NameHidden 决定是否暴露)
GiftID int64 // → StarGift.ID
MsgID int // 用户礼物的私聊 msg_id频道礼物不进历史固定为 0
SavedID int64 // 频道礼物 inputSavedStarGiftChat.saved_id用户礼物为 0
Date int // 收到时刻 Unix 秒
NameHidden bool // 送礼人请求隐藏姓名
Unsaved bool // 未展示在个人资料saveStarGift 切换)
Converted bool // 已转换回 Stars终态从列表排除
ConvertStars int64 // 转换可退回的 Stars
Message string // 附言(可选)
}
// SavedStarGiftRef 是 payments.getSavedStarGift/saveStarGift/convertStarGift 的协议中立引用。
// 用户礼物使用 inputSavedStarGiftUser.msg_id频道礼物使用 inputSavedStarGiftChat.peer + saved_id。
type SavedStarGiftRef struct {
Owner Peer
MsgID int
SavedID int64
}
// Valid reports whether the reference has the identity required by its owner kind.
func (r SavedStarGiftRef) Valid() bool {
switch r.Owner.Type {
case PeerTypeUser:
return r.Owner.ID != 0 && r.MsgID > 0
case PeerTypeChannel:
return r.Owner.ID != 0 && r.SavedID > 0
default:
return false
}
}
// SavedStarGiftPage 是一页已收到礼物 + keyset 分页游标。
type SavedStarGiftPage struct {
Gifts []SavedStarGift
NextOffset string // 空 = 无更多页(末页必须省略,客户端据此停止翻页)
Count int // 总数(未转换、按 excludeUnsaved 过滤后)
}
// Star gift 边界常量。
const (
// MaxSavedStarGiftsLimit 是 getSavedStarGifts 单页上限。
MaxSavedStarGiftsLimit = 100
// MaxStarGiftMessageRunes 限制附言长度(对齐 stargifts_message_length_max 量级)。
MaxStarGiftMessageRunes = 255
// MaxStarGiftsOffsetBytes 是 keyset 游标字符串长度上限。
MaxStarGiftsOffsetBytes = 64
)
// Star gift 哨兵错误rpc 层 errors.Is 映射为 tgerr
var (
// ErrStarGiftInvalid 表示礼物 id 不在目录里。
ErrStarGiftInvalid = errors.New("stargift: invalid gift id")
// ErrStarGiftNotFound 表示找不到该已收到礼物实例。
ErrStarGiftNotFound = errors.New("stargift: saved gift not found")
// ErrStarGiftAlreadyConverted 表示礼物已转换回 Stars不可重复转换
ErrStarGiftAlreadyConverted = errors.New("stargift: already converted")
)
// StarGiftCatalogHash 由目录的 (gift_id, stars) 折叠出稳定 hash供 getStarGifts NotModified。
func StarGiftCatalogHash(catalog []StarGift) int {
var h uint64
for _, g := range catalog {
h ^= uint64(g.ID)
h = h*0x4f25 + uint64(g.ID)
h = h*0x4f25 + uint64(g.Stars)
}
return int(h & 0x7fffffff)
}
// EncodeStarGiftCursor / DecodeStarGiftCursor 是 saved gifts keyset 游标(最后一条实例 id
func EncodeStarGiftCursor(id int64) string {
return base64.RawURLEncoding.EncodeToString([]byte(strconv.FormatInt(id, 10)))
}
// DecodeStarGiftCursor 反解游标;无法解析(含空串)返回 ok=false调用方从首页开始
func DecodeStarGiftCursor(s string) (int64, bool) {
if s == "" {
return 0, false
}
raw, err := base64.RawURLEncoding.DecodeString(s)
if err != nil {
return 0, false
}
id, err := strconv.ParseInt(string(raw), 10, 64)
if err != nil || id <= 0 {
return 0, false
}
return id, true
}