fix(server/reward): TG bot 回复区分已领取/未加入两态 + 按 Telegram language_code 中英双语
ci-pangolin / Cleartext Scan — Android 禁明文 (pull_request) Successful in 24s
ci-pangolin / Portable SQL — 可移植性 (mysql/sqlite) (pull_request) Successful in 23s
ci-pangolin / Lint — shellcheck (pull_request) Successful in 6s
ci-pangolin / OpenAPI Sync Check (pull_request) Successful in 36s
ci-pangolin / Flutter — analyze + test (pull_request) Successful in 34s
ci-pangolin / Codegen Drift — token 生成物未漂移 (pull_request) Successful in 3s
ci-pangolin / DS-flow — 原型/跨端同源/代码色单源闸 (pull_request) Successful in 3s
ci-pangolin / Go — build + test (pull_request) Failing after 11s
ci-pangolin / E2E Smoke — L4 进程级端到端 (pull_request) Failing after 10s
ci-pangolin / Redline Scan — 脱敏 (UI 文案) (pull_request) Failing after 10m52s
ci-pangolin / Go — integration (mysql/redis testcontainers) (pull_request) Failing after 4m33s
ci-pangolin / Golden — 视觉回归 (全量:components/auth/desktop/tablet) (pull_request) Failing after 19s
ci-pangolin / Cleartext Scan — Android 禁明文 (pull_request) Successful in 24s
ci-pangolin / Portable SQL — 可移植性 (mysql/sqlite) (pull_request) Successful in 23s
ci-pangolin / Lint — shellcheck (pull_request) Successful in 6s
ci-pangolin / OpenAPI Sync Check (pull_request) Successful in 36s
ci-pangolin / Flutter — analyze + test (pull_request) Successful in 34s
ci-pangolin / Codegen Drift — token 生成物未漂移 (pull_request) Successful in 3s
ci-pangolin / DS-flow — 原型/跨端同源/代码色单源闸 (pull_request) Successful in 3s
ci-pangolin / Go — build + test (pull_request) Failing after 11s
ci-pangolin / E2E Smoke — L4 进程级端到端 (pull_request) Failing after 10s
ci-pangolin / Redline Scan — 脱敏 (UI 文案) (pull_request) Failing after 10m52s
ci-pangolin / Go — integration (mysql/redis testcontainers) (pull_request) Failing after 4m33s
ci-pangolin / Golden — 视觉回归 (全量:components/auth/desktop/tablet) (pull_request) Failing after 19s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P9G7E3wmAYL9KeYCVZVsqu
This commit is contained in:
@@ -91,32 +91,44 @@ func (s *Service) ConsumeTelegramToken(ctx context.Context, token string) (int64
|
||||
return id, ok, nil
|
||||
}
|
||||
|
||||
// ClaimResult 是 ClaimTelegram 的结果三态,供上层(handler)按态回不同文案。
|
||||
type ClaimResult int
|
||||
|
||||
const (
|
||||
ClaimGranted ClaimResult = iota // 发放成功
|
||||
ClaimAlready // 已领取过(本账户或该 telegram_id)
|
||||
ClaimNotMember // 不在频道
|
||||
)
|
||||
|
||||
// ClaimTelegram: 真是频道成员则一次性发 TgDays 天(source='task'),唯一守卫防重复领取
|
||||
// (同 userID 或同 telegramID 只能成功一次)。
|
||||
func (s *Service) ClaimTelegram(ctx context.Context, userID int64, telegramID string) (bool, error) {
|
||||
func (s *Service) ClaimTelegram(ctx context.Context, userID int64, telegramID string) (ClaimResult, error) {
|
||||
member, err := s.checker.IsMember(ctx, s.tg.channel, telegramID)
|
||||
if err != nil || !member {
|
||||
return false, err
|
||||
if err != nil {
|
||||
return ClaimNotMember, err
|
||||
}
|
||||
if !member {
|
||||
return ClaimNotMember, nil
|
||||
}
|
||||
tx, err := s.db.BeginTx(ctx, &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
return ClaimNotMember, err
|
||||
}
|
||||
defer func() { _ = tx.Rollback() }()
|
||||
now := s.now()
|
||||
if err := s.st.InsertClaimTx(ctx, tx, userID, "telegram_join", telegramID, s.cfg.TgDays, now); err != nil {
|
||||
if err == ErrClaimExists {
|
||||
return false, nil // 已领过(本账户 or 该 tgid)
|
||||
return ClaimAlready, nil // 已领过(本账户 or 该 tgid)
|
||||
}
|
||||
return false, err
|
||||
return ClaimNotMember, err
|
||||
}
|
||||
if _, _, err := s.g.GrantRewardTx(ctx, tx, userID, s.cfg.TgDays, "task", "task_telegram_join", "tg:"+telegramID); err != nil {
|
||||
return false, err
|
||||
return ClaimNotMember, err
|
||||
}
|
||||
if err := tx.Commit(); err != nil {
|
||||
return false, err
|
||||
return ClaimNotMember, err
|
||||
}
|
||||
return true, nil
|
||||
return ClaimGranted, nil
|
||||
}
|
||||
|
||||
// apiChecker 是 ChatMemberChecker 的默认生产实现:打 Telegram getChatMember。
|
||||
|
||||
Reference in New Issue
Block a user