问题:分站上架商品审核通过后主站能搜到、分站看不到,且没有自动同步。 根因:分站前台/搜索只认 distribution_site_accounts 中 display_status='enabled' 的货架行,而主站前台不按站点过滤。货架行此前只由「号主在该站上架」或站长手动 「一键同步主站商品」写入,审核通过不回写;同时一键同步的失效清理把「非 published+approved」的货架行一律置为 disabled,商品重新在售后也不会恢复。 - 新增 EnsureListingShelvedTx:商品变为 published+approved 时自动铺到所有 display_account_enabled=true 的站点货架(缺行新增、系统下架恢复、人工下架不动), 经 ListingShelfSyncer 接口注入,避免 listing 反向依赖 distribution - 新增 distribution_site_accounts.display_disabled_by(operator/system/空)区分下架 来源;人工上下架各入口写入来源标记 - 一键同步的失效清理收紧为只清理「货源记录已删除」的孤儿行,并支持恢复系统下架行, 结果新增 reenabled_count - 新增迁移 000074 回填存量缺失货架行,部署后无需逐站手动同步 - 修复 CreateSite 显式传 false/0 的配置(不允许自动展示、结算冷却 0 天)被 GORM default 标签忽略而静默回落默认值 - 前端:去掉会跨站串扰的 localStorage 站点码回退,站点探测完成后再挂载应用, 避免分站发布因缺少站点码被记成主站商品;同步弹窗文案与统计项同步更新 - 补充分销货架自动铺货、清理口径、建站零值落库与审核铺货回归测试
80 lines
2.4 KiB
Go
80 lines
2.4 KiB
Go
package listing
|
|
|
|
import (
|
|
"errors"
|
|
"sync"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
"hfb_sys/backend/internal/model"
|
|
)
|
|
|
|
// ListingChatCreator 发布群创建接口(由 chat 模块实现,避免直接依赖)
|
|
type ListingChatCreator interface {
|
|
EnsureListingConversation(tx *gorm.DB, listing model.RentalListing, supportAdminID uint64) (conversationID uint64, err error)
|
|
}
|
|
|
|
// ListingShelfSyncer 商品上架后的分站货架铺货接口(由 distribution 模块实现,避免模块反向依赖)。
|
|
//
|
|
// 所有站点与主站共用同一批已审核商品,因此商品审核通过后必须自动出现在各分站货架,
|
|
// 不能依赖站长手动「一键同步主站商品」。
|
|
type ListingShelfSyncer interface {
|
|
EnsureListingShelvedTx(tx *gorm.DB, listingID, accountID uint64) error
|
|
}
|
|
|
|
type Repository struct {
|
|
db *gorm.DB
|
|
publicZoneCountsMu sync.Mutex
|
|
publicZoneCounts publicZoneCountCache
|
|
chatCreator ListingChatCreator
|
|
shelfSyncer ListingShelfSyncer
|
|
}
|
|
|
|
func NewRepository(db *gorm.DB, chatCreator ListingChatCreator) *Repository {
|
|
return &Repository{
|
|
db: db,
|
|
chatCreator: chatCreator,
|
|
}
|
|
}
|
|
|
|
// SetShelfSyncer 注入货架铺货实现;未注入(如未接入分销模块的环境)时自动铺货为 no-op。
|
|
func (r *Repository) SetShelfSyncer(syncer ListingShelfSyncer) {
|
|
if r == nil {
|
|
return
|
|
}
|
|
r.shelfSyncer = syncer
|
|
}
|
|
|
|
// syncPublishedShelf 只在商品真正对外可售(published + approved)时铺货到各分站货架。
|
|
// 草稿、待审核、已下架商品不需要铺货:分站前台本身就要求 published + approved 才展示。
|
|
func (r *Repository) syncPublishedShelf(tx *gorm.DB, listing *model.RentalListing) error {
|
|
if r == nil || r.shelfSyncer == nil || listing == nil {
|
|
return nil
|
|
}
|
|
if listing.Status != "published" || listing.ReviewStatus != "approved" {
|
|
return nil
|
|
}
|
|
return r.shelfSyncer.EnsureListingShelvedTx(tx, listing.ID, listing.AccountID)
|
|
}
|
|
|
|
type publicZoneCountCache struct {
|
|
Counts map[string]int64
|
|
ExpiresAt time.Time
|
|
}
|
|
|
|
const publicZoneCountCacheTTL = 5 * time.Second
|
|
|
|
func initialPublishState(reviewRequired bool) (string, string, *time.Time) {
|
|
if reviewRequired {
|
|
return "draft", "pending", nil
|
|
}
|
|
now := time.Now()
|
|
return "published", "approved", &now
|
|
}
|
|
|
|
func IsNotFound(err error) bool {
|
|
return errors.Is(err, gorm.ErrRecordNotFound)
|
|
}
|
|
|
|
// roundMoney 使用统一的角精度(0.1元)
|