feat(distribution): 分站可下调收号比例且不超过主站上限

让分销站能按自身能力下调收号比例扩大利润,同时把主站回收比例作为硬边界,避免分站把比例加得比主站更高。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
yml2213
2026-09-15 20:35:30 +08:00
co-authored by Cursor
parent 1c86bef765
commit c9d9160ff4
27 changed files with 1159 additions and 106 deletions
@@ -68,6 +68,7 @@ func setupHandlerTestEnv(t *testing.T) *handlerTestEnv {
siteProtected.POST("/sites/:id/withdrawals", h.ApplySiteWithdrawal)
siteProtected.GET("/sites/:id/withdrawals", h.ListSiteWithdrawals)
siteProtected.GET("/sites/:id/analytics", h.GetDashboardAnalytics)
siteProtected.PUT("/sites/:id", h.UpdateSite)
siteProtected.PUT("/sites/:id/branding", h.UpdateSiteBranding)
siteProtected.POST("/sites/:id/sync-accounts", h.SyncSiteAccounts)
siteProtected.GET("/received-listings", h.ListReceivedListings)
@@ -404,6 +405,33 @@ func TestHandler_SiteOperatorEndpoints(t *testing.T) {
t.Fatalf("branding expected 200, got %d: %s", wBrand.Code, wBrand.Body.String())
}
delta := 2.5
wRatio := env.request("PUT", fmt.Sprintf("/api/v1/distribution/sites/%d", siteA.ID), UpdateSiteRequest{ReceiveRatioDelta: &delta}, adminA.ID, nil)
if wRatio.Code != http.StatusOK {
t.Fatalf("receive ratio expected 200, got %d: %s", wRatio.Code, wRatio.Body.String())
}
var ratioResp struct {
Code string `json:"code"`
Data SiteDTO `json:"data"`
}
json.Unmarshal(wRatio.Body.Bytes(), &ratioResp)
if ratioResp.Data.ReceiveRatioDelta != 2.5 {
t.Fatalf("receive_ratio_delta = %v, want 2.5", ratioResp.Data.ReceiveRatioDelta)
}
hackedName := "越权改名"
wHackName := env.request("PUT", fmt.Sprintf("/api/v1/distribution/sites/%d", siteA.ID), UpdateSiteRequest{SiteName: &hackedName}, adminA.ID, nil)
if wHackName.Code != http.StatusOK {
t.Fatalf("operator privileged field expected 200 with ignore, got %d: %s", wHackName.Code, wHackName.Body.String())
}
json.Unmarshal(wHackName.Body.Bytes(), &ratioResp)
if ratioResp.Data.SiteName != siteA.SiteName {
t.Fatalf("operator must not rename site, got %q", ratioResp.Data.SiteName)
}
wCrossRatio := env.request("PUT", fmt.Sprintf("/api/v1/distribution/sites/%d", siteA.ID), UpdateSiteRequest{ReceiveRatioDelta: &delta}, adminB.ID, nil)
if wCrossRatio.Code != http.StatusForbidden {
t.Fatalf("cross-site receive ratio expected 403, got %d: %s", wCrossRatio.Code, wCrossRatio.Body.String())
}
// 6. 同步主站商品货架
opOwner := model.User{Phone: "13800000077", Status: "active"}
env.db.Create(&opOwner)