feat: user buy media
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
||||
|
||||
"backend/database/models/qvyun/public/model"
|
||||
"backend/database/models/qvyun/public/table"
|
||||
"backend/pkg/errorx"
|
||||
"backend/pkg/media_store"
|
||||
"backend/pkg/path"
|
||||
"backend/pkg/pg"
|
||||
@@ -314,3 +315,94 @@ func (svc *Service) GetM3U8(ctx context.Context, tenantId int64, types pg.MediaT
|
||||
func (svc *Service) GetSegmentPath(ctx context.Context, t pg.MediaType, hash string, segment int64) string {
|
||||
return filepath.Join(svc.storageConfig.Path, hash, t.String(), fmt.Sprintf("%d.ts", segment))
|
||||
}
|
||||
|
||||
func (svc *Service) Checkout(ctx context.Context, tenantId, userId, mediaId int64) error {
|
||||
log := svc.log.WithField("method", "Checkout")
|
||||
|
||||
bought, err := svc.HasUserBought(ctx, tenantId, userId, mediaId)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "check user bought")
|
||||
}
|
||||
|
||||
if bought {
|
||||
return nil
|
||||
}
|
||||
|
||||
media, err := svc.GetMediaByID(ctx, tenantId, userId, mediaId)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "get media")
|
||||
}
|
||||
|
||||
userBalance, err := svc.GetUserBalance(ctx, tenantId, userId)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "get user balance")
|
||||
}
|
||||
|
||||
if userBalance < media.Price {
|
||||
return errorx.UserBalanceNotEnough
|
||||
}
|
||||
|
||||
tx, err := svc.db.Begin()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "begin transaction")
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
tbl := table.UserMedias
|
||||
stmt := tbl.
|
||||
INSERT(tbl.TenantID, tbl.UserID, tbl.MediaID, tbl.Price).
|
||||
VALUES(Int(tenantId), Int(userId), Int(mediaId), Int(media.Price))
|
||||
log.Debug(stmt.DebugSql())
|
||||
|
||||
if _, err := stmt.ExecContext(ctx, tx); err != nil {
|
||||
return errors.Wrap(err, "insert user media")
|
||||
}
|
||||
|
||||
// update user balance
|
||||
tblUserTenants := table.UsersTenants
|
||||
stmtUserTenants := tblUserTenants.
|
||||
UPDATE().
|
||||
SET(
|
||||
tblUserTenants.Balance.SET(
|
||||
tblUserTenants.Balance.SUB(Int(media.Price)),
|
||||
),
|
||||
).
|
||||
WHERE(
|
||||
tblUserTenants.TenantID.EQ(Int(tenantId)).AND(
|
||||
tblUserTenants.UserID.EQ(Int(userId)),
|
||||
),
|
||||
)
|
||||
log.Debug(stmtUserTenants.DebugSql())
|
||||
|
||||
if _, err := stmtUserTenants.ExecContext(ctx, tx); err != nil {
|
||||
return errors.Wrap(err, "update user balance")
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
return errors.Wrap(err, "commit transaction")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetUserBalance
|
||||
func (svc *Service) GetUserBalance(ctx context.Context, tenantId, userId int64) (int64, error) {
|
||||
log := svc.log.WithField("method", "GetUserBalance")
|
||||
|
||||
tbl := table.UsersTenants
|
||||
stmt := tbl.SELECT(tbl.Balance.AS("balance")).WHERE(
|
||||
tbl.TenantID.EQ(Int(tenantId)).AND(
|
||||
tbl.UserID.EQ(Int(userId)),
|
||||
),
|
||||
)
|
||||
log.Debug(stmt.DebugSql())
|
||||
|
||||
var result struct {
|
||||
Balance int64
|
||||
}
|
||||
if err := stmt.QueryContext(ctx, svc.db, &result); err != nil {
|
||||
return 0, errors.Wrap(err, "query user balance")
|
||||
}
|
||||
|
||||
return result.Balance, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user