新功能: withdrawal_log 接口加 summary 字段 + admin 禁直接扣减 commission
接口侧: - /v1/public/user/withdrawal_log 响应新增 summary 字段, 包含: - commission_balance (当前余额) - locked_by_pending (待审批占用) - available_to_withdraw (可提现) - total_historical_amount (已通过提现总额) - total_refunded_amount (退款回扣总额) - total_income_amount (收入总额) - 前端可据此自洽展示账目对账, 用户能在一个接口里看清整笔账 代码守护: - updateUserBasicInfoLogic 拒绝任何 change<0 的 commission 修改 - 扣减必须走 approveWithdrawal 写 type=334 日志 - 防止未来 admin 误操作再次造成 user.commission 与 system_logs 失衡 时间戳修复: - queryWithdrawalLogLogic 和 queryCommissionReturnLogLogic 的时间戳 从 UnixMilli 改回 Unix (秒级), 符合项目"后端统一秒级"约定 测试: - 补 buildSummary 的 4 个 mock 查询期望 - 加 summary 字段值正确性断言
This commit is contained in:
@@ -40,6 +40,23 @@ func TestQueryWithdrawalLog_WithWithdrawalBizType(t *testing.T) {
|
||||
}).AddRow(
|
||||
int64(1001), userID, int64(3000), "bank withdrawal", usermodel.WithdrawalStatusPending, "", uint8(3), "acct-001", "", createdAt, updatedAt,
|
||||
))
|
||||
// buildSummary 触发的 4 个聚合查询
|
||||
mock.ExpectQuery("SELECT COALESCE(commission, 0) FROM `user`").
|
||||
WithArgs(userID).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"commission"}).AddRow(int64(5000)))
|
||||
mock.ExpectQuery("SELECT COALESCE(SUM(amount), 0) FROM `withdrawals`").
|
||||
WithArgs(userID, usermodel.WithdrawalStatusPending).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"sum"}).AddRow(int64(3000)))
|
||||
mock.ExpectQuery("SELECT COALESCE(SUM(amount), 0) FROM `withdrawals`").
|
||||
WithArgs(userID, usermodel.WithdrawalStatusApproved).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"sum"}).AddRow(int64(0)))
|
||||
mock.ExpectQuery("FROM system_logs").
|
||||
WithArgs(
|
||||
logmodel.CommissionTypePurchase, logmodel.CommissionTypeRenewal,
|
||||
logmodel.CommissionTypeRefund, logmodel.CommissionTypeWithdrawReject, logmodel.CommissionTypeWithdrawCancel,
|
||||
logmodel.TypeCommission.Uint8(), userID,
|
||||
).
|
||||
WillReturnRows(sqlmock.NewRows([]string{"income", "refund"}).AddRow(int64(8000), int64(0)))
|
||||
|
||||
logic := newTestQueryWithdrawalLogLogic(t, db, userID)
|
||||
resp, err := logic.QueryWithdrawalLog(&types.QueryWithdrawalLogListRequest{
|
||||
@@ -57,9 +74,16 @@ func TestQueryWithdrawalLog_WithWithdrawalBizType(t *testing.T) {
|
||||
if got.BizType != withdrawalLogBizTypeWithdrawal {
|
||||
t.Fatalf("BizType = %q, want %q", got.BizType, withdrawalLogBizTypeWithdrawal)
|
||||
}
|
||||
if got.Id != 1001 || got.UserId != userID || got.Amount != 3000 || got.CreatedAt != createdAt.UnixMilli() || got.UpdatedAt != updatedAt.UnixMilli() {
|
||||
if got.Id != 1001 || got.UserId != userID || got.Amount != 3000 || got.CreatedAt != createdAt.Unix() || got.UpdatedAt != updatedAt.Unix() {
|
||||
t.Fatalf("withdrawal item = %+v", got)
|
||||
}
|
||||
if resp.Summary == nil {
|
||||
t.Fatalf("expected summary, got nil")
|
||||
}
|
||||
if resp.Summary.CommissionBalance != 5000 || resp.Summary.LockedByPending != 3000 ||
|
||||
resp.Summary.AvailableToWithdraw != 2000 || resp.Summary.TotalIncomeAmount != 8000 {
|
||||
t.Fatalf("summary = %+v, want balance=5000 locked=3000 avail=2000 income=8000", resp.Summary)
|
||||
}
|
||||
assertQueryWithdrawalLogExpectations(t, mock)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user