feat(distribution): 分站品牌装修可配置首页入口并上传图片
分站可单独配置回收、合作反馈和客服二维码,未配置时继承主站;Logo、图标和轮播支持直接上传。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"hfb_sys/backend/internal/middleware"
|
||||
"hfb_sys/backend/internal/sitecode"
|
||||
"hfb_sys/backend/pkg/response"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -82,7 +83,7 @@ func (h *Handler) HomeAnnouncements(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (h *Handler) HomeConfig(c *gin.Context) {
|
||||
config, err := h.service.HomeConfig(c.Request.Context())
|
||||
config, err := h.service.HomeConfig(c.Request.Context(), sitecode.FromRequest(c))
|
||||
if err != nil {
|
||||
writeConfigError(c, err)
|
||||
return
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package systemconfig
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestParseHomeEntryOverrideInheritsWhenEmpty(t *testing.T) {
|
||||
if _, ok := parseAWRecycleOverride(" "); ok {
|
||||
t.Fatal("空配置应继承主站")
|
||||
}
|
||||
if _, ok := parseCooperationFeedbackOverride(""); ok {
|
||||
t.Fatal("空配置应继承主站")
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseHomeEntryOverrideUsesSiteJSON(t *testing.T) {
|
||||
aw, ok := parseAWRecycleOverride(`{"title":"分站回收","subtitle":"看图","image_url":"/aw.png","enabled":true}`)
|
||||
if !ok || aw.Title != "分站回收" || aw.ImageURL != "/aw.png" {
|
||||
t.Fatalf("回收覆盖 = %+v ok=%v", aw, ok)
|
||||
}
|
||||
coop, ok := parseCooperationFeedbackOverride(`{"title":"分站合作","subtitle":"联系","image_url":"/coop.png","enabled":false}`)
|
||||
if !ok || coop.Title != "分站合作" || coop.Enabled {
|
||||
t.Fatalf("合作覆盖 = %+v ok=%v", coop, ok)
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,9 @@ package systemconfig
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"hfb_sys/backend/internal/model"
|
||||
)
|
||||
|
||||
func (s *Service) HomeAnnouncements(ctx context.Context) (*HomeAnnouncementsDTO, error) {
|
||||
@@ -16,7 +19,7 @@ func (s *Service) HomeAnnouncements(ctx context.Context) (*HomeAnnouncementsDTO,
|
||||
return &HomeAnnouncementsDTO{Items: items}, nil
|
||||
}
|
||||
|
||||
func (s *Service) HomeConfig(ctx context.Context) (*HomeConfigDTO, error) {
|
||||
func (s *Service) HomeConfig(ctx context.Context, siteCode string) (*HomeConfigDTO, error) {
|
||||
if s.repo == nil {
|
||||
return nil, ErrDependencyUnavailable
|
||||
}
|
||||
@@ -40,13 +43,61 @@ func (s *Service) HomeConfig(ctx context.Context) (*HomeConfigDTO, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &HomeConfigDTO{
|
||||
config := &HomeConfigDTO{
|
||||
Announcements: announcements,
|
||||
Banners: banners,
|
||||
PublishOptions: publishOptions,
|
||||
AWRecycle: awRecycle,
|
||||
CooperationFeedback: cooperationFeedback,
|
||||
}, nil
|
||||
}
|
||||
s.applySiteHomeOverrides(ctx, siteCode, config)
|
||||
return config, nil
|
||||
}
|
||||
|
||||
// applySiteHomeOverrides 用分站自己的首页入口覆盖主站配置。字段为空表示继续继承主站。
|
||||
func (s *Service) applySiteHomeOverrides(ctx context.Context, siteCode string, config *HomeConfigDTO) {
|
||||
siteCode = strings.TrimSpace(siteCode)
|
||||
if s == nil || s.repo == nil || s.repo.db == nil || config == nil || siteCode == "" {
|
||||
return
|
||||
}
|
||||
var site model.DistributionSite
|
||||
err := s.repo.db.WithContext(ctx).
|
||||
Select("aw_recycle_json", "cooperation_feedback_json").
|
||||
Where("site_code = ? AND status = ?", siteCode, "active").
|
||||
First(&site).Error
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if item, ok := parseAWRecycleOverride(site.AWRecycleJSON); ok {
|
||||
config.AWRecycle = item
|
||||
}
|
||||
if item, ok := parseCooperationFeedbackOverride(site.CooperationFeedbackJSON); ok {
|
||||
config.CooperationFeedback = item
|
||||
}
|
||||
}
|
||||
|
||||
func parseAWRecycleOverride(raw string) (AWRecycleConfig, bool) {
|
||||
raw = strings.TrimSpace(raw)
|
||||
if raw == "" {
|
||||
return AWRecycleConfig{}, false
|
||||
}
|
||||
var item AWRecycleConfig
|
||||
if err := json.Unmarshal([]byte(raw), &item); err != nil {
|
||||
return AWRecycleConfig{}, false
|
||||
}
|
||||
return normalizeAWRecycle(item), true
|
||||
}
|
||||
|
||||
func parseCooperationFeedbackOverride(raw string) (CooperationFeedbackConfig, bool) {
|
||||
raw = strings.TrimSpace(raw)
|
||||
if raw == "" {
|
||||
return CooperationFeedbackConfig{}, false
|
||||
}
|
||||
var item CooperationFeedbackConfig
|
||||
if err := json.Unmarshal([]byte(raw), &item); err != nil {
|
||||
return CooperationFeedbackConfig{}, false
|
||||
}
|
||||
return normalizeCooperationFeedback(item), true
|
||||
}
|
||||
|
||||
func (s *Service) homeAnnouncements(ctx context.Context) ([]string, error) {
|
||||
|
||||
Reference in New Issue
Block a user