diff --git a/apps/admin/src/views/goods/components/GoodsConfigDialog.vue b/apps/admin/src/views/goods/components/GoodsConfigDialog.vue
index ece36eb..cce5263 100644
--- a/apps/admin/src/views/goods/components/GoodsConfigDialog.vue
+++ b/apps/admin/src/views/goods/components/GoodsConfigDialog.vue
@@ -52,6 +52,17 @@ watch(() => props.visible, (v) => {
if (v) checkedIds.value = [...props.defaultCheckedIds]
})
+// 合并同名候选搜索(本地过滤同分类链接)
+const mergeKeyword = ref('')
+watch(() => props.visible, (v) => {
+ if (v) mergeKeyword.value = ''
+})
+const filteredSiblings = computed(() => {
+ const kw = mergeKeyword.value.trim()
+ if (!kw) return props.siblings
+ return props.siblings.filter((s) => (s.goodName ?? '').includes(kw))
+})
+
function onCascaderChange(val: any) {
form.value.categoryId = val.length ? val[val.length - 1] : ''
}
@@ -126,11 +137,19 @@ async function handleSubmit() {
+
-
+
{{ s.goodName }} · ¥{{ s.goodPrice }}
+
没有匹配的链接
@@ -149,5 +168,6 @@ async function handleSubmit() {
.config-og-name { font-weight: 600; font-size: 14px; }
.config-og-meta { color: #909399; font-size: 12px; margin-top: 2px; }
.config-merge-box { width: 100%; }
+.config-merge-empty { font-size: 12px; color: #909399; padding: 4px 0; }
.config-merge-box .el-checkbox-group { display: flex; flex-direction: column; align-items: flex-start; max-height: 200px; overflow-y: auto; }
diff --git a/apps/admin/src/views/goods/components/GoodsEditDialog.vue b/apps/admin/src/views/goods/components/GoodsEditDialog.vue
index 4136a37..a07ed7b 100644
--- a/apps/admin/src/views/goods/components/GoodsEditDialog.vue
+++ b/apps/admin/src/views/goods/components/GoodsEditDialog.vue
@@ -155,6 +155,15 @@ const memberPriceSaving = ref('')
/** 族原始详情(含 priceMatrix) */
const familyDetailRaw = ref(null)
+// ─── 族级并集视图:尺码表/包装规格(族物化并集)+ SKU(价格矩阵 = 各链接动态合并) ───
+const familySizeRows = computed(() => familyDetailRaw.value?.sizeChart?.rows ?? [])
+const familySizeColumns = computed(() => familyDetailRaw.value?.sizeChart?.columns ?? [])
+const familyPackageRows = computed(() => familyDetailRaw.value?.packageSpecs?.rows ?? [])
+const familySkuRows = computed(() => {
+ const rows = (familyDetailRaw.value?.priceMatrix?.rows ?? []) as any[]
+ return rows.map((r) => ({ ...r, sourceCount: Array.isArray(r.sources) ? r.sources.length : 0 }))
+})
+
function toggleMemberExpand(key: string) {
const next = new Set(expandedMemberKeys.value)
if (next.has(key)) next.delete(key)
@@ -683,6 +692,58 @@ async function handleDeleteGood() {
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ row.dimensionsCm ? `${row.dimensionsCm.length}×${row.dimensionsCm.width}×${row.dimensionsCm.height}` : '-' }}
+
+
+
+
+
+
+
+
+
+ {{ row.logistics || '-' }}
+
+
+ {{ row.craft || '-' }}
+
+
+ {{ row.craft?.includes('双面印花') ? '双面印花' : row.craft?.includes('单面印花') ? '单面印花' : '-' }}
+
+
+
+
+ {{ row.price }}
+
+
+ {{ row.sourceCount || 1 }}
+
+
+
+ {{ row.manual ? '人工价' : '推导价' }}
+
+
+
+
+
@@ -818,6 +879,8 @@ async function handleDeleteGood() {
}
.member-detail-tabs :deep(.el-tabs__header) { margin-bottom: 8px; }
.edit-family-loading { color: var(--el-text-color-placeholder); font-size: 12px; padding: 4px 0; }
+.family-detail-tabs { margin-top: 10px; }
+.family-detail-tabs :deep(.el-tabs__header) { margin-bottom: 8px; }
.detail-tabs { margin-top: 12px; padding-top: 4px; border-top: 1px solid #ebeef5; }
.select-inline { display: flex; align-items: center; gap: 6px; width: 100%; }