fix(distribution): 修复分站搜不到已审核商品并实现审核通过自动铺货

问题:分站上架商品审核通过后主站能搜到、分站看不到,且没有自动同步。

根因:分站前台/搜索只认 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 站点码回退,站点探测完成后再挂载应用,
  避免分站发布因缺少站点码被记成主站商品;同步弹窗文案与统计项同步更新
- 补充分销货架自动铺货、清理口径、建站零值落库与审核铺货回归测试
This commit is contained in:
yml2213
2026-09-30 21:11:09 +08:00
parent 7833e90eee
commit 766c923a6a
21 changed files with 716 additions and 47 deletions
@@ -311,6 +311,7 @@ export interface SyncSiteAccountsResult {
synced_count: number
skipped_count: number
updated_count?: number
reenabled_count?: number
disabled_stale_count?: number
total_active: number
}
@@ -490,8 +490,9 @@ async function handleSyncAccounts(row: DistributionSite) {
syncingSiteId.value = row.id
try {
const res = await syncDistributionSiteAccounts(row.id)
const reenabled = res.reenabled_count ? `,恢复展示 ${res.reenabled_count} 个` : ''
ElMessage.success(
`同步成功!为【${row.site_name}】新增本站上传货 ${res.synced_count} 个,已存在 ${res.skipped_count} 个(本次候选 ${res.total_active} 个)`
`同步成功!为【${row.site_name}】新增货架商品 ${res.synced_count} 个,已存在 ${res.skipped_count} 个${reenabled}(本次候选 ${res.total_active} 个)`
)
} catch (err) {
ElMessage.error(readError(err, '同步商品失败'))
+12 -4
View File
@@ -19,9 +19,6 @@ const pinia = createPinia()
app.use(pinia).use(router)
// 初始化分销站点租户配置(如 ?site=xxx 或独立域名访问)
useDistributionSiteStore(pinia).initSite()
window.addEventListener('auth-storage-changed', () => {
useSessionStore(pinia).syncFromStorage()
useAdminSessionStore(pinia).syncFromStorage()
@@ -34,4 +31,15 @@ window.addEventListener('storage', event => {
}
})
router.isReady().then(() => app.mount('#app'))
// 初始化分销站点租户配置(如 ?site=xxx 或独立域名访问)。
// 必须在挂载前完成:独立域名下的站点码由 /distribution/site-info 探测后写入 sessionStorage,
// 若在探测完成前渲染,分站页面的请求(包括发布商品)会缺少站点码而被当成主站发布。
async function bootstrap() {
await useDistributionSiteStore(pinia)
.initSite()
.catch(() => undefined)
await router.isReady()
app.mount('#app')
}
void bootstrap()
+4 -5
View File
@@ -37,7 +37,10 @@ export interface DistributionSiteInfo {
* 1. 环境变量 VITE_DISTRIBUTION_SITE_CODE(针对独立分销前台开发端口,如 5191)
* 2. 当前标签页 sessionStorage 中的 hfb_site_code(避免跨 Tab 污染主站)
* 3. 本地二级域名(如 test_1.localhost:5189)
* 4. 生产环境或独立域名绑定的 localStorage 缓存
*
* 注意:独立域名下的站点编码只来自 sessionStorage,由 initSite() 通过
* /distribution/site-info?domain= 探测后写入。历史上曾读取 localStorage 缓存,
* 会让同一浏览器访问主站时串到分站站点码(把主站发布记到分站/反之),因此已移除。
*/
export function getEffectiveSiteCode(): string {
if (typeof window === 'undefined') return ''
@@ -52,10 +55,6 @@ export function getEffectiveSiteCode(): string {
return hostname.replace(/\.localhost$/, '')
}
if (hostname !== 'localhost' && hostname !== '127.0.0.1') {
return localStorage.getItem('hfb_site_code') || ''
}
return ''
}