removed all "paid" features - no more stars, gifts, or grams
This commit is contained in:
parent
d4451d753c
commit
21d8e91756
165 changed files with 318 additions and 40948 deletions
|
|
@ -182,125 +182,6 @@ DO UPDATE SET reaction_count = user_top_reactions.reaction_count + 1, reaction_d
|
|||
}, nil
|
||||
}
|
||||
|
||||
// AddChannelMessagePaidReaction 为一条广播频道消息增投付费 reaction 星数(累计),返回聚合
|
||||
// 状态供 rpc 投影与扇出。扣费在 rpc 层经 Stars 账本 Debit 完成,本方法只负责累计与聚合。
|
||||
func (s *ChannelStore) AddChannelMessagePaidReaction(ctx context.Context, req domain.SendChannelPaidReactionRequest) (domain.ChannelMessagePaidReactionResult, error) {
|
||||
if req.UserID == 0 || req.ChannelID == 0 || req.MessageID <= 0 || req.MessageID > domain.MaxMessageBoxID {
|
||||
return domain.ChannelMessagePaidReactionResult{}, domain.ErrChannelInvalid
|
||||
}
|
||||
if req.Stars <= 0 || req.Stars > domain.MaxPaidReactionStarsPerRequest {
|
||||
return domain.ChannelMessagePaidReactionResult{}, domain.ErrChannelInvalid
|
||||
}
|
||||
if req.Date <= 0 {
|
||||
req.Date = nowUnix()
|
||||
}
|
||||
beginner, ok := s.db.(txBeginner)
|
||||
if !ok {
|
||||
return domain.ChannelMessagePaidReactionResult{}, fmt.Errorf("add channel paid reaction: db does not support transactions")
|
||||
}
|
||||
tx, err := beginner.Begin(ctx)
|
||||
if err != nil {
|
||||
return domain.ChannelMessagePaidReactionResult{}, fmt.Errorf("begin add channel paid reaction: %w", err)
|
||||
}
|
||||
committed := false
|
||||
defer func() {
|
||||
if !committed {
|
||||
_ = tx.Rollback(ctx)
|
||||
}
|
||||
}()
|
||||
channel, member, err := s.getChannelForMember(ctx, tx, req.UserID, req.ChannelID)
|
||||
if err != nil {
|
||||
return domain.ChannelMessagePaidReactionResult{}, err
|
||||
}
|
||||
// 付费 reaction 仅用于广播频道帖子(官方语义)。
|
||||
if !channel.Broadcast || channel.Megagroup {
|
||||
return domain.ChannelMessagePaidReactionResult{}, domain.ErrReactionInvalid
|
||||
}
|
||||
msg, err := s.getChannelMessage(ctx, tx, req.ChannelID, req.MessageID)
|
||||
if err != nil {
|
||||
return domain.ChannelMessagePaidReactionResult{}, err
|
||||
}
|
||||
if msg.Deleted || msg.Action != nil || msg.ID <= member.AvailableMinID {
|
||||
return domain.ChannelMessagePaidReactionResult{}, domain.ErrMessageIDInvalid
|
||||
}
|
||||
if _, err := tx.Exec(ctx, `
|
||||
INSERT INTO channel_message_paid_reactions (channel_id, message_id, reactor_user_id, stars, anonymous, reaction_date)
|
||||
VALUES ($1,$2,$3,$4,$5,$6)
|
||||
ON CONFLICT (channel_id, message_id, reactor_user_id)
|
||||
DO UPDATE SET stars = channel_message_paid_reactions.stars + EXCLUDED.stars,
|
||||
anonymous = EXCLUDED.anonymous,
|
||||
reaction_date = EXCLUDED.reaction_date`,
|
||||
req.ChannelID, req.MessageID, req.UserID, req.Stars, req.Anonymous, req.Date); err != nil {
|
||||
return domain.ChannelMessagePaidReactionResult{}, fmt.Errorf("upsert channel paid reaction: %w", err)
|
||||
}
|
||||
if err := tx.Commit(ctx); err != nil {
|
||||
return domain.ChannelMessagePaidReactionResult{}, fmt.Errorf("commit add channel paid reaction: %w", err)
|
||||
}
|
||||
committed = true
|
||||
messages := []domain.ChannelMessage{msg}
|
||||
if err := s.populateChannelMessagesReactions(ctx, s.db, req.UserID, []domain.Channel{channel}, messages); err != nil {
|
||||
return domain.ChannelMessagePaidReactionResult{}, err
|
||||
}
|
||||
msg = messages[0]
|
||||
paid, err := s.aggregateChannelPaidReactions(ctx, req.ChannelID, req.MessageID, req.UserID)
|
||||
if err != nil {
|
||||
return domain.ChannelMessagePaidReactionResult{}, err
|
||||
}
|
||||
recipients, err := s.ListActiveChannelMemberIDs(ctx, req.UserID, req.ChannelID, domain.MaxChannelRealtimeFanout)
|
||||
if err != nil || len(recipients) == 0 {
|
||||
recipients = []int64{req.UserID}
|
||||
}
|
||||
return domain.ChannelMessagePaidReactionResult{
|
||||
Channel: channel,
|
||||
Message: msg,
|
||||
Paid: paid,
|
||||
Recipients: recipients,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// aggregateChannelPaidReactions 汇总一条消息的付费 reaction:总星数 + viewer 自身 + top reactors。
|
||||
func (s *ChannelStore) aggregateChannelPaidReactions(ctx context.Context, channelID int64, messageID int, viewerUserID int64) (domain.ChannelMessagePaidReactions, error) {
|
||||
rows, err := s.db.Query(ctx, `
|
||||
SELECT reactor_user_id, stars, anonymous
|
||||
FROM channel_message_paid_reactions
|
||||
WHERE channel_id = $1 AND message_id = $2
|
||||
ORDER BY stars DESC, reactor_user_id ASC`, channelID, messageID)
|
||||
if err != nil {
|
||||
return domain.ChannelMessagePaidReactions{}, fmt.Errorf("aggregate channel paid reactions: %w", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
var out domain.ChannelMessagePaidReactions
|
||||
var myReactor domain.PaidReactor
|
||||
myInTop := false
|
||||
for rows.Next() {
|
||||
var r domain.PaidReactor
|
||||
if err := rows.Scan(&r.UserID, &r.Stars, &r.Anonymous); err != nil {
|
||||
return domain.ChannelMessagePaidReactions{}, err
|
||||
}
|
||||
out.TotalStars += r.Stars
|
||||
r.My = r.UserID == viewerUserID
|
||||
if r.My {
|
||||
out.MyStars = r.Stars
|
||||
out.MyAnonymous = r.Anonymous
|
||||
myReactor = r
|
||||
}
|
||||
if len(out.TopReactors) < domain.MaxPaidReactionTopReactors {
|
||||
out.TopReactors = append(out.TopReactors, r)
|
||||
if r.My {
|
||||
myInTop = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return domain.ChannelMessagePaidReactions{}, err
|
||||
}
|
||||
// viewer 自身始终出现在 top reactors(官方:你的条目总在列表里,带 My 标志)。
|
||||
if out.MyStars > 0 && !myInTop {
|
||||
out.TopReactors = append(out.TopReactors, myReactor)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (s *ChannelStore) DeleteChannelParticipantReaction(ctx context.Context, req domain.DeleteChannelParticipantReactionRequest) (domain.ChannelMessageReactionsResult, error) {
|
||||
if req.UserID == 0 || req.ChannelID == 0 || req.MessageID <= 0 || req.MessageID > domain.MaxMessageBoxID || req.ParticipantUserID == 0 {
|
||||
return domain.ChannelMessageReactionsResult{}, domain.ErrChannelInvalid
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue