All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 7m25s
80 lines
2.5 KiB
Go
80 lines
2.5 KiB
Go
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
|
||
}
|
||
|