fix(distribution): 修复收号站订单详情权限、专属支付通道路由、大盘统计与仲裁积分隔离
- 修复 FindOrder 在收号站模式(two_party_distributor_receive / three_party)下的 403 权限判定,放行参与方站点成员并精准计算收益 - 串联 distribution_site_payment_channels 至 payment.Start 核心支付发起流程,分销订单优先使用绑定的专属商户通道 - 修复数据大盘 GetDashboardAnalytics 趋势中 ReceivedCount 恒为 0 的问题,并对齐今日订单与 GMV 统计 - 修复 dispute/arbitration.go 仲裁完成时向分销租客发放成长积分的泄漏风险 - 提现管理新增 distribution_site_name/distribution_site_code 字段并在后台列表与详情弹窗中区分展示分销站 - GetPublicSiteInfo 增加 X-Distribution-Site-Code 请求头兜底支持
This commit is contained in:
@@ -27,34 +27,36 @@ type WithdrawalDTO struct {
|
||||
|
||||
// 管理员端详细 DTO
|
||||
type WithdrawalDetailDTO struct {
|
||||
ID uint64 `json:"id"`
|
||||
WithdrawNo string `json:"withdraw_no"`
|
||||
UserID uint64 `json:"user_id"`
|
||||
DistributionSiteID uint64 `json:"distribution_site_id"`
|
||||
UserNickname string `json:"user_nickname"`
|
||||
UserPhone string `json:"user_phone"`
|
||||
AmountCent int64 `json:"amount_cent"`
|
||||
FeeCent int64 `json:"fee_cent"`
|
||||
ActualAmountCent int64 `json:"actual_amount_cent"`
|
||||
PaymentAccountID *uint64 `json:"payment_account_id"`
|
||||
AccountType string `json:"account_type"`
|
||||
AccountName string `json:"account_name"`
|
||||
AccountNo string `json:"account_no"` // 管理员可见完整账号
|
||||
BankName string `json:"bank_name"`
|
||||
BankBranch string `json:"bank_branch"`
|
||||
CertificateURLs []string `json:"certificate_urls"` // 收款二维码图片
|
||||
Status string `json:"status"`
|
||||
ReviewedBy *uint64 `json:"reviewed_by"`
|
||||
ReviewedByName string `json:"reviewed_by_name"`
|
||||
ReviewedAt *time.Time `json:"reviewed_at"`
|
||||
ReviewRemark string `json:"review_remark"`
|
||||
PaidBy *uint64 `json:"paid_by"`
|
||||
PaidByName string `json:"paid_by_name"`
|
||||
PaidAt *time.Time `json:"paid_at"`
|
||||
PaymentProofURL string `json:"payment_proof_url"`
|
||||
PaymentRemark string `json:"payment_remark"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
ID uint64 `json:"id"`
|
||||
WithdrawNo string `json:"withdraw_no"`
|
||||
UserID uint64 `json:"user_id"`
|
||||
DistributionSiteID uint64 `json:"distribution_site_id"`
|
||||
DistributionSiteName string `json:"distribution_site_name"`
|
||||
DistributionSiteCode string `json:"distribution_site_code"`
|
||||
UserNickname string `json:"user_nickname"`
|
||||
UserPhone string `json:"user_phone"`
|
||||
AmountCent int64 `json:"amount_cent"`
|
||||
FeeCent int64 `json:"fee_cent"`
|
||||
ActualAmountCent int64 `json:"actual_amount_cent"`
|
||||
PaymentAccountID *uint64 `json:"payment_account_id"`
|
||||
AccountType string `json:"account_type"`
|
||||
AccountName string `json:"account_name"`
|
||||
AccountNo string `json:"account_no"` // 管理员可见完整账号
|
||||
BankName string `json:"bank_name"`
|
||||
BankBranch string `json:"bank_branch"`
|
||||
CertificateURLs []string `json:"certificate_urls"` // 收款二维码图片
|
||||
Status string `json:"status"`
|
||||
ReviewedBy *uint64 `json:"reviewed_by"`
|
||||
ReviewedByName string `json:"reviewed_by_name"`
|
||||
ReviewedAt *time.Time `json:"reviewed_at"`
|
||||
ReviewRemark string `json:"review_remark"`
|
||||
PaidBy *uint64 `json:"paid_by"`
|
||||
PaidByName string `json:"paid_by_name"`
|
||||
PaidAt *time.Time `json:"paid_at"`
|
||||
PaymentProofURL string `json:"payment_proof_url"`
|
||||
PaymentRemark string `json:"payment_remark"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
type CreateWithdrawalRequest struct {
|
||||
|
||||
@@ -75,12 +75,23 @@ func (r *Repository) toDetailDTO(ctx context.Context, w model.WithdrawalRequest)
|
||||
}
|
||||
}
|
||||
|
||||
var siteName, siteCode string
|
||||
if w.DistributionSiteID > 0 {
|
||||
var site model.DistributionSite
|
||||
if err := db.Select("site_name, site_code").First(&site, w.DistributionSiteID).Error; err == nil {
|
||||
siteName = site.SiteName
|
||||
siteCode = site.SiteCode
|
||||
}
|
||||
}
|
||||
|
||||
return &WithdrawalDetailDTO{
|
||||
ID: w.ID,
|
||||
WithdrawNo: w.WithdrawNo,
|
||||
UserID: w.UserID,
|
||||
DistributionSiteID: w.DistributionSiteID,
|
||||
UserNickname: user.Nickname,
|
||||
ID: w.ID,
|
||||
WithdrawNo: w.WithdrawNo,
|
||||
UserID: w.UserID,
|
||||
DistributionSiteID: w.DistributionSiteID,
|
||||
DistributionSiteName: siteName,
|
||||
DistributionSiteCode: siteCode,
|
||||
UserNickname: user.Nickname,
|
||||
UserPhone: user.Phone,
|
||||
AmountCent: w.AmountCent,
|
||||
FeeCent: w.FeeCent,
|
||||
|
||||
@@ -168,3 +168,33 @@ func TestWithdrawalCreateRollsBackWhenBalanceIsInsufficient(t *testing.T) {
|
||||
}
|
||||
f.assertBalance(t, 100_000, 0)
|
||||
}
|
||||
|
||||
func TestWithdrawalDetailIncludesDistributionSiteInfo(t *testing.T) {
|
||||
f := newWithdrawalFixture(t)
|
||||
if err := f.db.AutoMigrate(&model.DistributionSite{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
site := model.DistributionSite{SiteCode: "sub_site", SiteName: "分销子站", Domain: "sub.example.com", Status: "active"}
|
||||
if err := f.db.Create(&site).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
wReq := model.WithdrawalRequest{
|
||||
WithdrawNo: "WD2026TESTSITE",
|
||||
UserID: f.userID,
|
||||
DistributionSiteID: site.ID,
|
||||
AmountCent: 5000,
|
||||
ActualAmountCent: 5000,
|
||||
Status: "pending",
|
||||
}
|
||||
if err := f.db.Create(&wReq).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
detail, err := f.repo.AdminFindByID(context.Background(), wReq.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("AdminFindByID failed: %v", err)
|
||||
}
|
||||
if detail.DistributionSiteID != site.ID || detail.DistributionSiteName != "分销子站" || detail.DistributionSiteCode != "sub_site" {
|
||||
t.Fatalf("unexpected detail site info: %+v", detail)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user