2026-03-10 20:47:24 -07:00

80 lines
2.5 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 apple
import (
"context"
"crypto/sha256"
"encoding/hex"
"fmt"
"github.com/perfect-panel/server/pkg/cache"
"github.com/redis/go-redis/v9"
"gorm.io/gorm"
)
type Model interface {
Insert(ctx context.Context, data *Transaction, tx ...*gorm.DB) error
FindByOriginalId(ctx context.Context, originalId string) (*Transaction, error)
FindByUserAndProduct(ctx context.Context, userId int64, productId string) (*Transaction, error)
FindLatestByUserId(ctx context.Context, userId int64) (*Transaction, error)
}
type defaultModel struct {
cache.CachedConn
table string
}
type customModel struct {
*defaultModel
}
func NewModel(db *gorm.DB, c *redis.Client) Model {
return &customModel{
defaultModel: &defaultModel{
CachedConn: cache.NewConn(db, c),
table: "`apple_iap_transactions`",
},
}
}
func (m *defaultModel) jwsKey(jws string) string {
sum := sha256.Sum256([]byte(jws))
return fmt.Sprintf("cache:iap:jws:%s", hex.EncodeToString(sum[:]))
}
func (m *customModel) Insert(ctx context.Context, data *Transaction, tx ...*gorm.DB) error {
return m.ExecCtx(ctx, func(conn *gorm.DB) error {
if len(tx) > 0 {
conn = tx[0]
}
return conn.Model(&Transaction{}).Create(data).Error
}, m.jwsKey(data.JWSHash))
}
func (m *customModel) FindByOriginalId(ctx context.Context, originalId string) (*Transaction, error) {
var data Transaction
key := fmt.Sprintf("cache:iap:original:%s", originalId)
err := m.QueryCtx(ctx, &data, key, func(conn *gorm.DB, v interface{}) error {
return conn.Model(&Transaction{}).Where("original_transaction_id = ?", originalId).First(&data).Error
})
return &data, err
}
func (m *customModel) FindByUserAndProduct(ctx context.Context, userId int64, productId string) (*Transaction, error) {
var data Transaction
err := m.QueryNoCacheCtx(ctx, &data, func(conn *gorm.DB, v interface{}) error {
return conn.Model(&Transaction{}).Where("user_id = ? AND product_id = ?", userId, productId).Order("purchase_at DESC").First(&data).Error
})
return &data, err
}
// FindLatestByUserId 查找指定用户最近的一条交易记录
// 用于获取已知的 originalTransactionId以便查询 Apple 交易历史
func (m *customModel) FindLatestByUserId(ctx context.Context, userId int64) (*Transaction, error) {
var data Transaction
err := m.QueryNoCacheCtx(ctx, &data, func(conn *gorm.DB, v interface{}) error {
return conn.Model(&Transaction{}).Where("user_id = ?", userId).Order("purchase_at DESC").First(&data).Error
})
return &data, err
}