diff --git a/furniture-3d-system/src/server/services/__tests__/jst-sku-stock-sync.service.test.ts b/furniture-3d-system/src/server/services/__tests__/jst-sku-stock-sync.service.test.ts index 9edc3269..e67c970b 100644 --- a/furniture-3d-system/src/server/services/__tests__/jst-sku-stock-sync.service.test.ts +++ b/furniture-3d-system/src/server/services/__tests__/jst-sku-stock-sync.service.test.ts @@ -262,6 +262,7 @@ describe('syncJstSkuStockProducts', () => { skuItems: expect.arrayContaining([ expect.objectContaining({ barcode: 'BAR001', + model: 'SPU001', skuCode: 'SPJ00001', sourceTable: 'jst_sku', }), @@ -289,6 +290,7 @@ describe('syncJstSkuStockProducts', () => { createMany: { data: expect.arrayContaining([ expect.objectContaining({ + model: 'SPU001', skuCode: 'SPJ00001', specName: '测试存量商品 1200*600*750', barcode: 'BAR001', @@ -302,6 +304,45 @@ describe('syncJstSkuStockProducts', () => { ) }) + it('apply 创建存量商品时用聚水潭 sku_id 兜底缺失的 SKU 编码', async () => { + createConnectionMock( + createSourceRow({ + sku_id: 'bar001', + other_7: '', + }), + ) + + const result = await syncJstSkuStockProducts({ apply: true, batchSize: 1, limit: 1 }) + + expect(result.created).toBe(1) + expect(mockedPrisma.intakeNonIntegratedProduct.create).toHaveBeenCalledWith( + expect.objectContaining({ + data: expect.objectContaining({ + payload: expect.objectContaining({ + skuItems: expect.arrayContaining([ + expect.objectContaining({ + barcode: 'BAR001', + skuCode: 'BAR001', + sourceSkuId: 'BAR001', + }), + ]), + }), + skuItems: { + createMany: { + data: expect.arrayContaining([ + expect.objectContaining({ + barcode: 'BAR001', + skuCode: 'BAR001', + sourceSkuId: 'BAR001', + }), + ]), + }, + }, + }), + }), + ) + }) + it('apply 更新存量商品时 upsert 产品 profile 并刷新结构化 SKU 明细', async () => { createConnectionMock(createSourceRow({ name: '更新后的存量商品 1200*600*750' })) mockedPrisma.intakeNonIntegratedProduct.findUnique.mockResolvedValue({ @@ -340,6 +381,7 @@ describe('syncJstSkuStockProducts', () => { data: expect.arrayContaining([ expect.objectContaining({ barcode: 'BAR001', + model: 'SPU001', skuCode: 'SPJ00001', sourceTable: 'jst_sku', }), diff --git a/furniture-3d-system/src/server/services/jst-sku-stock-sync.service.ts b/furniture-3d-system/src/server/services/jst-sku-stock-sync.service.ts index 549707e8..7238198e 100644 --- a/furniture-3d-system/src/server/services/jst-sku-stock-sync.service.ts +++ b/furniture-3d-system/src/server/services/jst-sku-stock-sync.service.ts @@ -209,7 +209,11 @@ function mergeDefinedSourceFields>( return next } -function buildSourceSkuItem(row: JstSkuSourceRow, sequence: number): NonIntegratedSkuItem { +function buildSourceSkuItem( + row: JstSkuSourceRow, + sequence: number, + sourceSpu: string, +): NonIntegratedSkuItem { const skuId = normalizeSkuId(row.sku_id) const name = normalizeSourceString(row.name) const image = pickSourceImage(row) @@ -225,8 +229,8 @@ function buildSourceSkuItem(row: JstSkuSourceRow, sequence: number): NonIntegrat packageSuffix: '', image, imageName: pickImageName(skuId, image), - model: '', - skuCode: normalizeSourceString(row.other_7), + model: sourceSpu, + skuCode: normalizeSourceString(row.other_7) || skuId, setCount: normalizeSetCount(row.other_8), specName: name, barcode: skuId, @@ -300,7 +304,7 @@ function shouldExcludeStockCategory(category: string) { return category.trim() === EXCLUDED_STOCK_CATEGORY } -function buildSourceSkuItems(rows: JstSkuSourceRow[]) { +function buildSourceSkuItems(rows: JstSkuSourceRow[], sourceSpu: string) { const seenSkuIds = new Set() return rows @@ -311,7 +315,7 @@ function buildSourceSkuItems(rows: JstSkuSourceRow[]) { return row }) .filter((row): row is JstSkuSourceRow => row !== null) - .map((row, index) => buildSourceSkuItem(row, index + 1)) + .map((row, index) => buildSourceSkuItem(row, index + 1, sourceSpu)) } function buildSourceProductPayload( @@ -322,7 +326,7 @@ function buildSourceProductPayload( if (!sourceSpu) return null const skuContentRows = pickSkuContentRows(group.rows) - const skuItems = buildSourceSkuItems(skuContentRows) + const skuItems = buildSourceSkuItems(skuContentRows, sourceSpu) if (skuItems.length === 0) return null const representativeRow = pickRepresentativeSourceRow(group.rows)