2026-07-02 10:53:44 +08:00

142 lines
4.6 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 mysql
import (
"context"
"strings"
"hyapp/pkg/appcode"
"hyapp/pkg/xerr"
"hyapp/services/wallet-service/internal/domain/ledger"
)
// ListRechargeBills 查询 wallet-service 的充值账单投影,后台不能直接读写业务库内部语义。
func (r *Repository) ListRechargeBills(ctx context.Context, query ledger.ListRechargeBillsQuery) ([]ledger.RechargeBill, int64, error) {
if r == nil || r.db == nil {
return nil, 0, xerr.New(xerr.Unavailable, "mysql repository is not configured")
}
ctx = contextWithCommandApp(ctx, query.AppCode)
query = normalizeRechargeBillsQuery(query)
query.AppCode = appcode.FromContext(ctx)
where, args := rechargeBillsWhereSQL(query)
total, err := r.countRechargeBillRows(ctx, where, args...)
if err != nil {
return nil, 0, err
}
// 充值事实仍以 wallet_recharge_records 为主表external_recharge_orders 只补 H5 三方订单的实付金额展示,使用 wallet_transaction_id 索引命中,避免列表查询回扫订单表。
rows, err := r.db.QueryContext(ctx, `
SELECT rr.app_code, rr.transaction_id, wt.command_id, wt.biz_type, wt.status, wt.external_ref,
rr.user_id, rr.seller_user_id, rr.seller_region_id, rr.target_region_id,
rr.policy_id, rr.policy_version, rr.currency_code,
rr.coin_amount, rr.usd_minor_amount, rr.exchange_coin_amount, rr.exchange_usd_minor_amount,
COALESCE(eo.provider_amount_minor, 0), rr.created_at_ms
FROM wallet_recharge_records rr
JOIN wallet_transactions wt ON wt.app_code = rr.app_code AND wt.transaction_id = rr.transaction_id
LEFT JOIN external_recharge_orders eo ON eo.app_code = rr.app_code AND eo.wallet_transaction_id = rr.transaction_id
`+where+`
ORDER BY rr.created_at_ms DESC, rr.transaction_id DESC
LIMIT ? OFFSET ?`,
append(args, query.PageSize, resourceOffset(query.Page, query.PageSize))...,
)
if err != nil {
return nil, 0, err
}
defer rows.Close()
items := make([]ledger.RechargeBill, 0, query.PageSize)
for rows.Next() {
var item ledger.RechargeBill
if err := rows.Scan(
&item.AppCode,
&item.TransactionID,
&item.CommandID,
&item.RechargeType,
&item.Status,
&item.ExternalRef,
&item.UserID,
&item.SellerUserID,
&item.SellerRegionID,
&item.TargetRegionID,
&item.PolicyID,
&item.PolicyVersion,
&item.CurrencyCode,
&item.CoinAmount,
&item.USDMinorAmount,
&item.ExchangeCoinAmount,
&item.ExchangeUSDMinorAmount,
&item.ProviderAmountMinor,
&item.CreatedAtMS,
); err != nil {
return nil, 0, err
}
items = append(items, item)
}
if err := rows.Err(); err != nil {
return nil, 0, err
}
return items, total, nil
}
func (r *Repository) countRechargeBillRows(ctx context.Context, where string, args ...any) (int64, error) {
var total int64
err := r.db.QueryRowContext(ctx, `
SELECT COUNT(*)
FROM wallet_recharge_records rr
JOIN wallet_transactions wt ON wt.app_code = rr.app_code AND wt.transaction_id = rr.transaction_id
`+where,
args...,
).Scan(&total)
return total, err
}
func normalizeRechargeBillsQuery(query ledger.ListRechargeBillsQuery) ledger.ListRechargeBillsQuery {
query.AppCode = appcode.Normalize(query.AppCode)
query.RechargeType = strings.ToLower(strings.TrimSpace(query.RechargeType))
query.Status = strings.ToLower(strings.TrimSpace(query.Status))
query.Keyword = strings.TrimSpace(query.Keyword)
query.Page, query.PageSize = normalizePage(query.Page, query.PageSize)
if query.EndAtMS > 0 && query.StartAtMS > query.EndAtMS {
query.StartAtMS, query.EndAtMS = query.EndAtMS, query.StartAtMS
}
return query
}
func rechargeBillsWhereSQL(query ledger.ListRechargeBillsQuery) (string, []any) {
where := `WHERE rr.app_code = ?`
args := []any{query.AppCode}
if query.UserID > 0 {
where += ` AND rr.user_id = ?`
args = append(args, query.UserID)
}
if query.SellerUserID > 0 {
where += ` AND rr.seller_user_id = ?`
args = append(args, query.SellerUserID)
}
if query.RegionID > 0 {
where += ` AND rr.target_region_id = ?`
args = append(args, query.RegionID)
}
if query.RechargeType != "" {
where += ` AND wt.biz_type = ?`
args = append(args, query.RechargeType)
}
if query.Status != "" {
where += ` AND wt.status = ?`
args = append(args, query.Status)
}
if query.StartAtMS > 0 {
where += ` AND rr.created_at_ms >= ?`
args = append(args, query.StartAtMS)
}
if query.EndAtMS > 0 {
where += ` AND rr.created_at_ms < ?`
args = append(args, query.EndAtMS)
}
if query.Keyword != "" {
like := "%" + query.Keyword + "%"
where += ` AND (rr.transaction_id LIKE ? OR wt.command_id LIKE ? OR wt.external_ref LIKE ? OR rr.policy_version LIKE ?)`
args = append(args, like, like, like, like)
}
return where, args
}