fix: allow packaging variants without real model

This commit is contained in:
WuYongJie 2026-06-04 10:09:33 +08:00
parent 5cb25981ef
commit 01eb1647bc
6 changed files with 20 additions and 6 deletions

View File

@ -15,6 +15,7 @@ import {
regenerateAssetVariantThumbnail,
updateAssetVariant,
} from '@/lib/open-product/platform-api'
import { PACKAGING_PLACEHOLDER_MODEL_URL } from '@/lib/packaging-materials/constants'
jest.mock('next/link', () => ({
__esModule: true,
@ -690,7 +691,7 @@ describe('AssetCenterClient', () => {
width: 1200,
thickness: 60,
},
modelUrl: '',
modelUrl: PACKAGING_PLACEHOLDER_MODEL_URL,
mountPoints: [],
lossFactor: null,
}),

View File

@ -97,6 +97,7 @@ import {
normalizeSkuVersionNo,
} from '@/lib/open-product/asset-coding'
import { calculateEstimatedCost } from '@/lib/open-product/substrate-rules'
import { PACKAGING_PLACEHOLDER_MODEL_URL } from '@/lib/packaging-materials/constants'
import { getLevel1FromFamily } from '@/lib/packaging-materials/catalog'
import { canOperateDesignWorkspace as canOperateDesignWorkspaceForUser } from '@/lib/role-scope'
import { cn } from '@/lib/utils'
@ -3951,7 +3952,7 @@ export default function AssetCenterClient({
versionNo: skuPayload.versionNo,
barcode: skuPayload.barcode,
dimensions,
modelUrl: '',
modelUrl: PACKAGING_PLACEHOLDER_MODEL_URL,
mountPoints: [],
lossFactor: null,
businessData: skuPayload.businessData,

View File

@ -3,6 +3,7 @@ import type {
AssetVariantDTO,
CreateAssetVariantInput,
} from '@/server/services'
export { PACKAGING_PLACEHOLDER_MODEL_URL } from './constants'
import {
LEVEL2_BY_LEVEL1,
PACKAGING_TEMPLATE_MAP,
@ -12,8 +13,7 @@ import {
type Level1CategoryKey,
type PackagingTemplateKey,
} from './catalog'
export const PACKAGING_PLACEHOLDER_MODEL_URL = 'packaging-material://placeholder'
import { PACKAGING_PLACEHOLDER_MODEL_URL } from './constants'
export interface PackagingMaterialDraftInput {
assetFamilyId: string

View File

@ -0,0 +1 @@
export const PACKAGING_PLACEHOLDER_MODEL_URL = 'packaging-material://placeholder'

View File

@ -3,6 +3,7 @@ import {
ORIGINAL_ASSET_VARIANT_CODE_KEY,
ORIGINAL_ASSET_VARIANT_IDENTITY_KEY,
} from '@/lib/open-product/asset-variant-soft-delete'
import { PACKAGING_PLACEHOLDER_MODEL_URL } from '@/lib/packaging-materials/constants'
import { assetCenterService } from '../asset-center.service'
import { assetVariantThumbnailService } from '../asset-variant-thumbnail.service'
import { materialService } from '../material.service'
@ -2667,7 +2668,7 @@ describe('assetCenterService', () => {
substrateId: null,
finishId: null,
dimensions: { length: 1200, width: 1200, thickness: 60 },
modelUrl: '',
modelUrl: PACKAGING_PLACEHOLDER_MODEL_URL,
thumbnailUrl: null,
barcode: 'DBZ-SPJ04N1280V01',
supplierName: 'supplier',
@ -2758,6 +2759,11 @@ describe('assetCenterService', () => {
{ skipThumbnail: true },
)
expect(mockedAssetVariantRepository.createWithRelations).toHaveBeenCalledWith(
expect.objectContaining({
modelUrl: PACKAGING_PLACEHOLDER_MODEL_URL,
}),
)
expect(mockedIntakeNonIntegratedProductRepository.updateAttachmentPayloadByUser).toHaveBeenCalled()
const syncedPayload =
mockedIntakeNonIntegratedProductRepository.updateAttachmentPayloadByUser.mock.calls[0]?.[1] as {

View File

@ -73,6 +73,7 @@ import type { AssetThumbnailRenderAssetType } from '@/lib/asset-thumbnail-auth'
import { toMaterialConfig } from '@/lib/material-config'
import { buildMaterialThumbnailPreviewUrl } from '@/lib/material-thumbnail'
import type { OpenProductMountPoint } from '@/lib/open-product/types'
import { PACKAGING_PLACEHOLDER_MODEL_URL } from '@/lib/packaging-materials/constants'
import { AppError, ErrorCode } from '@/server/core/errors'
import type { AuthUser } from '@/server/core/types'
import {
@ -2975,6 +2976,10 @@ class AssetCenterService {
const code = input.code?.trim().toUpperCase() || await this.generateNextVariantCode(family.assetSeries.code)
const name = input.name.trim()
const modelUrl =
family.type === 'PACKAGING' && !input.modelUrl.trim()
? PACKAGING_PLACEHOLDER_MODEL_URL
: input.modelUrl.trim()
if (!code || !name) {
throw new AppError(ErrorCode.VALIDATION_REQUIRED_FIELD, '规格款编码和名称不能为空')
}
@ -3079,7 +3084,7 @@ class AssetCenterService {
substrate: input.substrateId ? { connect: { id: input.substrateId } } : undefined,
finish: resolvedFinishId ? { connect: { id: resolvedFinishId } } : undefined,
dimensions: resolvedDimensions as Prisma.InputJsonValue,
modelUrl: input.modelUrl.trim(),
modelUrl,
thumbnailUrl: trimOrNull(input.thumbnailUrl),
barcode: commercialFields.barcode,
supplierName: commercialFields.supplierName,