refactor(sitecode): 统一各模块分销站点编码解析为公共包

- 新增 internal/sitecode 包:FromRequest 头优先解析、FromQueryThenHeader
  探测接口专用、ExtractHost/IsLocalHost 提取 Host 域名
- 替换 auth/order/listing/chat/notification/withdrawal/wallet/distribution
  八模块 17 处各自内联的解析逻辑,统一优先级与 TrimSpace 行为
- 修复 notification 漏 TrimSpace、探测接口会话头压过显式 query、
  GetPublicSiteInfo 把 localhost Host 当站点域名查库等不一致
- 顺手清理 auth 中无引用的 extractHost 死代码
- gofmt 修复 withdrawal/presenter、chat/file/payment 测试四个历史遗留格式问题
This commit is contained in:
yml2213
2026-09-17 14:54:38 +08:00
parent 69774458b0
commit 8dc21d2757
16 changed files with 236 additions and 119 deletions
+7 -20
View File
@@ -2,10 +2,10 @@ package auth
import (
"errors"
"net"
"net/http"
"strings"
"hfb_sys/backend/internal/sitecode"
"hfb_sys/backend/pkg/response"
"github.com/gin-gonic/gin"
@@ -86,20 +86,18 @@ func (h *Handler) SendSMS(c *gin.Context) {
return
}
siteCode := strings.TrimSpace(firstNonEmpty(
c.GetHeader("X-Distribution-Site-Code"),
c.Query("distribution_site_code"),
c.Query("site_code"),
req.SiteCode,
))
siteCode := sitecode.FromRequest(c)
if siteCode == "" {
siteCode = strings.TrimSpace(req.SiteCode)
}
domain := strings.TrimSpace(firstNonEmpty(
c.GetHeader("X-Distribution-Domain"),
c.Query("distribution_domain"),
c.Query("domain"),
))
if siteCode == "" && domain == "" {
host := extractHost(c.Request.Host)
if host != "" && host != "localhost" && host != "127.0.0.1" && host != "::1" {
host := sitecode.ExtractHost(c.Request.Host)
if host != "" && !sitecode.IsLocalHost(host) {
domain = host
}
}
@@ -120,17 +118,6 @@ func firstNonEmpty(items ...string) string {
return ""
}
func extractHost(rawHost string) string {
rawHost = strings.TrimSpace(rawHost)
if rawHost == "" {
return ""
}
if host, _, err := net.SplitHostPort(rawHost); err == nil {
return strings.Trim(host, "[]")
}
return strings.Trim(rawHost, "[]")
}
// Login 短信验证码登录
// @Summary 短信验证码登录
// @Description 使用手机号和验证码登录
@@ -1,25 +1,14 @@
package chat
import (
"strings"
"hfb_sys/backend/internal/sitecode"
"hfb_sys/backend/pkg/response"
"github.com/gin-gonic/gin"
)
func parseSiteCode(c *gin.Context) string {
for _, val := range []string{
c.Query("distribution_site_code"),
c.Query("site_code"),
c.GetHeader("X-Distribution-Site-Code"),
c.GetHeader("X-Site-Code"),
} {
if trimmed := strings.TrimSpace(val); trimmed != "" {
return trimmed
}
}
return ""
return sitecode.FromRequest(c)
}
func (h *Handler) list(c *gin.Context, principal Principal) {
@@ -238,4 +238,3 @@ func TestCollectPaddleOCRJSONLTextSupportsPPOCRv6(t *testing.T) {
t.Fatalf("candidates = %v, want 火爆出租-778群 as first candidate", candidates)
}
}
@@ -7,6 +7,7 @@ import (
"strings"
"hfb_sys/backend/internal/middleware"
"hfb_sys/backend/internal/sitecode"
"hfb_sys/backend/pkg/response"
"github.com/gin-gonic/gin"
@@ -355,20 +356,13 @@ func (h *Handler) ListPublicSiteListings(c *gin.Context) {
}
func (h *Handler) GetPublicSiteInfo(c *gin.Context) {
code := strings.TrimSpace(c.Query("code"))
if code == "" {
code = strings.TrimSpace(c.Query("site_code"))
}
if code == "" {
code = strings.TrimSpace(c.GetHeader("X-Distribution-Site-Code"))
}
code := sitecode.FromQueryThenHeader(c)
domain := strings.TrimSpace(c.Query("domain"))
if code == "" && domain == "" {
host := c.Request.Host
if colon := strings.Index(host, ":"); colon != -1 {
host = host[:colon]
host := sitecode.ExtractHost(c.Request.Host)
if host != "" && !sitecode.IsLocalHost(host) {
domain = host
}
domain = host
}
info, err := h.service.GetPublicSiteInfo(c.Request.Context(), code, domain)
if err != nil {
@@ -382,14 +376,11 @@ func (h *Handler) GetPublicSiteInfo(c *gin.Context) {
// 仅当域名属于系统中正常运行(active)的分销站点时返回 200,其余情况返回 404,
// 防止任意外部未授权域名解析到该服务器刷爆 Let's Encrypt 证书申请配额。
func (h *Handler) CheckDomain(c *gin.Context) {
domain := strings.ToLower(strings.TrimSpace(c.Query("domain")))
domain := sitecode.ExtractHost(c.Query("domain"))
if domain == "" {
c.String(http.StatusBadRequest, "domain required")
return
}
if colon := strings.Index(domain, ":"); colon != -1 {
domain = domain[:colon]
}
info, err := h.service.GetPublicSiteInfo(c.Request.Context(), "", domain)
if err != nil || info == nil || info.Status != "active" {
@@ -91,4 +91,3 @@ func TestNormalizeSceneListingScreenshotAndOperatingExpense(t *testing.T) {
t.Fatalf("normalize operating_expense scene = %q, want operating-expense", got)
}
}
@@ -5,6 +5,7 @@ import (
"strings"
"hfb_sys/backend/internal/middleware"
"hfb_sys/backend/internal/sitecode"
"hfb_sys/backend/pkg/response"
"github.com/gin-gonic/gin"
@@ -119,7 +120,7 @@ func parsePublicListQuery(c *gin.Context) PublicListQuery {
MinSecretKD: parseOptionalFloat(c.Query("min_secret_kd")),
MaxSecretKD: parseOptionalFloat(c.Query("max_secret_kd")),
ResourceRanges: parseResourceRanges(c),
DistributionSiteCode: strings.TrimSpace(firstNonEmpty(c.GetHeader("X-Distribution-Site-Code"), c.Query("distribution_site_code"), c.Query("site_code"))),
DistributionSiteCode: sitecode.FromRequest(c),
}
if query.PageSize > 50 {
query.PageSize = 50
@@ -3,9 +3,9 @@ package listing
import (
"net/http"
"strconv"
"strings"
filemodule "hfb_sys/backend/internal/modules/file"
"hfb_sys/backend/internal/sitecode"
"hfb_sys/backend/pkg/response"
"github.com/gin-gonic/gin"
@@ -25,7 +25,7 @@ func (h *Handler) FindPublic(c *gin.Context) {
if !ok {
return
}
siteCode := strings.TrimSpace(firstNonEmpty(c.GetHeader("X-Distribution-Site-Code"), c.Query("distribution_site_code"), c.Query("site_code")))
siteCode := sitecode.FromRequest(c)
item, err := h.service.FindPublic(c.Request.Context(), id, siteCode)
if err != nil {
writeListingError(c, err)
@@ -1,6 +1,7 @@
package listing
import (
"hfb_sys/backend/internal/sitecode"
"hfb_sys/backend/pkg/response"
"strings"
@@ -18,7 +19,7 @@ func (h *Handler) Create(c *gin.Context) {
response.BadRequest(c, listingBindErrorMessage(err))
return
}
siteCode := strings.TrimSpace(c.GetHeader("X-Distribution-Site-Code"))
siteCode := sitecode.FromRequest(c)
item, err := h.service.Create(c.Request.Context(), ownerID, req, siteCode)
if err != nil {
writeListingError(c, err)
@@ -42,7 +43,7 @@ func (h *Handler) Update(c *gin.Context) {
response.BadRequest(c, listingBindErrorMessage(err))
return
}
item, err := h.service.Update(c.Request.Context(), ownerID, id, req, strings.TrimSpace(c.GetHeader("X-Distribution-Site-Code")))
item, err := h.service.Update(c.Request.Context(), ownerID, id, req, sitecode.FromRequest(c))
if err != nil {
writeListingError(c, err)
return
@@ -103,7 +104,7 @@ func (h *Handler) ListMine(c *gin.Context) {
response.Unauthorized(c, "缺少用户上下文")
return
}
siteCode := strings.TrimSpace(c.GetHeader("X-Distribution-Site-Code"))
siteCode := sitecode.FromRequest(c)
items, err := h.service.ListMine(c.Request.Context(), ownerID, siteCode)
if err != nil {
writeListingError(c, err)
@@ -5,6 +5,7 @@ import (
"strconv"
"hfb_sys/backend/internal/middleware"
"hfb_sys/backend/internal/sitecode"
"hfb_sys/backend/pkg/response"
"github.com/gin-gonic/gin"
@@ -99,17 +100,7 @@ func (h *Handler) MarkRead(c *gin.Context) {
}
func parseSiteCode(c *gin.Context) string {
siteCode := c.Query("distribution_site_code")
if siteCode == "" {
siteCode = c.Query("site_code")
}
if siteCode == "" {
siteCode = c.GetHeader("X-Distribution-Site-Code")
}
if siteCode == "" {
siteCode = c.GetHeader("X-Site-Code")
}
return siteCode
return sitecode.FromRequest(c)
}
func currentUserID(c *gin.Context) (uint64, bool) {
@@ -3,6 +3,7 @@ package order
import (
"strings"
"hfb_sys/backend/internal/sitecode"
"hfb_sys/backend/pkg/response"
"github.com/gin-gonic/gin"
@@ -20,7 +21,7 @@ func (h *Handler) Create(c *gin.Context) {
return
}
if strings.TrimSpace(req.DistributionSiteCode) == "" {
req.DistributionSiteCode = strings.TrimSpace(c.GetHeader("X-Distribution-Site-Code"))
req.DistributionSiteCode = sitecode.FromRequest(c)
}
item, err := h.service.Create(c.Request.Context(), userID, req)
if err != nil {
@@ -37,7 +38,7 @@ func (h *Handler) List(c *gin.Context) {
return
}
page, pageSize := parsePagination(c)
siteCode := strings.TrimSpace(firstNonEmpty(c.GetHeader("X-Distribution-Site-Code"), c.Query("distribution_site_code"), c.Query("site_code")))
siteCode := sitecode.FromRequest(c)
items, err := h.service.ListForUser(c.Request.Context(), userID, page, pageSize, siteCode)
if err != nil {
writeOrderError(c, err)
@@ -53,7 +54,7 @@ func (h *Handler) ListSellerHandoffs(c *gin.Context) {
return
}
page, pageSize := parsePagination(c)
siteCode := strings.TrimSpace(firstNonEmpty(c.GetHeader("X-Distribution-Site-Code"), c.Query("distribution_site_code"), c.Query("site_code")))
siteCode := sitecode.FromRequest(c)
items, err := h.service.ListSellerHandoffs(c.Request.Context(), userID, SellerHandoffQuery{
Page: page,
PageSize: pageSize,
@@ -77,7 +78,7 @@ func (h *Handler) Detail(c *gin.Context) {
if !ok {
return
}
siteCode := strings.TrimSpace(firstNonEmpty(c.GetHeader("X-Distribution-Site-Code"), c.Query("distribution_site_code"), c.Query("site_code")))
siteCode := sitecode.FromRequest(c)
item, err := h.service.FindForUser(c.Request.Context(), userID, id, siteCode)
if err != nil {
writeOrderError(c, err)
@@ -927,4 +927,3 @@ func TestStartPaymentRoutesToDistributionSitePaymentChannel(t *testing.T) {
t.Fatalf("Order B expected MerchantID=%s, got %s", defaultConfig.MerchantID, savedB.MerchantID)
}
}
+2 -12
View File
@@ -3,9 +3,9 @@ package wallet
import (
"errors"
"strconv"
"strings"
"hfb_sys/backend/internal/middleware"
"hfb_sys/backend/internal/sitecode"
"hfb_sys/backend/pkg/response"
"github.com/gin-gonic/gin"
@@ -20,17 +20,7 @@ func NewHandler(service *Service) *Handler {
}
func parseSiteCode(c *gin.Context) string {
for _, val := range []string{
c.Query("distribution_site_code"),
c.Query("site_code"),
c.GetHeader("X-Distribution-Site-Code"),
c.GetHeader("X-Site-Code"),
} {
if trimmed := strings.TrimSpace(val); trimmed != "" {
return trimmed
}
}
return ""
return sitecode.FromRequest(c)
}
func (h *Handler) Balance(c *gin.Context) {
+2 -12
View File
@@ -2,8 +2,8 @@ package withdrawal
import (
"strconv"
"strings"
"hfb_sys/backend/internal/sitecode"
"hfb_sys/backend/pkg/response"
"github.com/gin-gonic/gin"
@@ -18,17 +18,7 @@ func NewHandler(service *Service) *Handler {
}
func parseSiteCode(c *gin.Context) string {
for _, val := range []string{
c.Query("distribution_site_code"),
c.Query("site_code"),
c.GetHeader("X-Distribution-Site-Code"),
c.GetHeader("X-Site-Code"),
} {
if trimmed := strings.TrimSpace(val); trimmed != "" {
return trimmed
}
}
return ""
return sitecode.FromRequest(c)
}
// ========== 用户端接口 ==========
@@ -95,29 +95,29 @@ func (r *Repository) toDetailDTO(ctx context.Context, w model.WithdrawalRequest)
DistributionSiteName: siteName,
DistributionSiteCode: siteCode,
UserNickname: user.Nickname,
UserPhone: user.Phone,
AmountCent: w.AmountCent,
FeeCent: w.FeeCent,
ActualAmountCent: w.ActualAmountCent,
PaymentAccountID: w.PaymentAccountID,
AccountType: w.AccountType,
AccountName: w.AccountName,
AccountNo: fullAccountNo,
BankName: w.BankName,
BankBranch: w.BankBranch,
CertificateURLs: certificateURLs,
Status: w.Status,
ReviewedBy: w.ReviewedBy,
ReviewedByName: reviewedByName,
ReviewedAt: w.ReviewedAt,
ReviewRemark: w.ReviewRemark,
PaidBy: w.PaidBy,
PaidByName: paidByName,
PaidAt: w.PaidAt,
PaymentProofURL: w.PaymentProofURL,
PaymentRemark: w.PaymentRemark,
CreatedAt: w.CreatedAt,
UpdatedAt: w.UpdatedAt,
UserPhone: user.Phone,
AmountCent: w.AmountCent,
FeeCent: w.FeeCent,
ActualAmountCent: w.ActualAmountCent,
PaymentAccountID: w.PaymentAccountID,
AccountType: w.AccountType,
AccountName: w.AccountName,
AccountNo: fullAccountNo,
BankName: w.BankName,
BankBranch: w.BankBranch,
CertificateURLs: certificateURLs,
Status: w.Status,
ReviewedBy: w.ReviewedBy,
ReviewedByName: reviewedByName,
ReviewedAt: w.ReviewedAt,
ReviewRemark: w.ReviewRemark,
PaidBy: w.PaidBy,
PaidByName: paidByName,
PaidAt: w.PaidAt,
PaymentProofURL: w.PaymentProofURL,
PaymentRemark: w.PaymentRemark,
CreatedAt: w.CreatedAt,
UpdatedAt: w.UpdatedAt,
}, nil
}