feat(基础资料库): 移除系统名称、优化花色筛选和表单布局
- 全栈移除 SubstrateSystemNameOption(字典管理、表单、API、数据库) - 花色改为单选 + 自动搜索下拉,排除五金油漆/漆面颜色/五金漆面色 - 基材名称自动生成格式:尺寸+环保等级+材质+花色+贴面 - 材质改为纯下拉选择,贴面始终显示 - 花色框体与 Select 组件宽度/高度统一 - 厚度规格字典只保留厚度数值+排序值
This commit is contained in:
parent
cb6cb0cc57
commit
a531b16b38
@ -446,8 +446,8 @@ model Substrate {
|
||||
thicknessSpec SubstrateThicknessSpec @relation(fields: [thicknessSpecId], references: [id])
|
||||
surfaceOptionId String?
|
||||
surfaceOption SubstrateSurfaceOption? @relation(fields: [surfaceOptionId], references: [id])
|
||||
systemNameOptionId String
|
||||
systemNameOption SubstrateSystemNameOption @relation(fields: [systemNameOptionId], references: [id])
|
||||
systemNameOptionId String?
|
||||
systemNameOption SubstrateSystemNameOption? @relation(fields: [systemNameOptionId], references: [id])
|
||||
suggestedPrice Decimal? @db.Decimal(10, 2)
|
||||
weightKg Float?
|
||||
metadata Json?
|
||||
|
||||
@ -49,8 +49,7 @@ export async function DELETE(request: NextRequest, context: RouteParams) {
|
||||
type !== 'CATEGORY' &&
|
||||
type !== 'ENVIRONMENT_GRADE' &&
|
||||
type !== 'THICKNESS_SPEC' &&
|
||||
type !== 'SURFACE_OPTION' &&
|
||||
type !== 'SYSTEM_NAME_OPTION'
|
||||
type !== 'SURFACE_OPTION'
|
||||
) {
|
||||
return jsonError(ErrorCode.VALIDATION_FAILED, '缺少有效的字典类型', 400, ctx.requestId)
|
||||
}
|
||||
|
||||
@ -104,7 +104,6 @@ export const substrateCreateSchema = z.object({
|
||||
environmentGradeId: z.string().trim().min(1),
|
||||
thicknessSpecId: z.string().trim().min(1),
|
||||
surfaceOptionId: z.string().trim().min(1).optional().nullable(),
|
||||
systemNameOptionId: z.string().trim().min(1),
|
||||
suggestedPrice: z.number().nonnegative().optional().nullable(),
|
||||
weightKg: z.number().nonnegative().optional().nullable(),
|
||||
finishIds: z.array(z.string().trim().min(1)).optional(),
|
||||
@ -118,7 +117,6 @@ export const substrateUpdateSchema = z.object({
|
||||
environmentGradeId: z.string().trim().min(1).optional(),
|
||||
thicknessSpecId: z.string().trim().min(1).optional(),
|
||||
surfaceOptionId: z.string().trim().min(1).optional().nullable(),
|
||||
systemNameOptionId: z.string().trim().min(1).optional(),
|
||||
suggestedPrice: z.number().nonnegative().optional().nullable(),
|
||||
weightKg: z.number().nonnegative().optional().nullable(),
|
||||
finishIds: z.array(z.string().trim().min(1)).optional(),
|
||||
@ -131,7 +129,6 @@ export const substrateDictionaryTypeSchema = z.enum([
|
||||
'ENVIRONMENT_GRADE',
|
||||
'THICKNESS_SPEC',
|
||||
'SURFACE_OPTION',
|
||||
'SYSTEM_NAME_OPTION',
|
||||
])
|
||||
|
||||
export const substrateDictionaryCreateSchema = z.object({
|
||||
|
||||
@ -14,23 +14,8 @@ jest.mock('next/link', () => ({
|
||||
|
||||
jest.mock('@/components/ui/Modal', () => ({
|
||||
__esModule: true,
|
||||
default: ({
|
||||
isOpen,
|
||||
title,
|
||||
children,
|
||||
footer,
|
||||
}: {
|
||||
isOpen: boolean
|
||||
title?: ReactNode
|
||||
children: ReactNode
|
||||
footer?: ReactNode
|
||||
}) =>
|
||||
isOpen ? (
|
||||
<div role="dialog" aria-label={typeof title === 'string' ? title : undefined}>
|
||||
<div>{children}</div>
|
||||
<div>{footer}</div>
|
||||
</div>
|
||||
) : null,
|
||||
default: ({ isOpen, title, children, footer }: { isOpen: boolean; title?: ReactNode; children: ReactNode; footer?: ReactNode }) =>
|
||||
isOpen ? <div role="dialog" aria-label={typeof title === 'string' ? title : undefined}><div>{children}</div><div>{footer}</div></div> : null,
|
||||
}))
|
||||
|
||||
jest.mock('@/components/ui/DeleteConfirmDialog', () => ({
|
||||
@ -40,144 +25,64 @@ jest.mock('@/components/ui/DeleteConfirmDialog', () => ({
|
||||
|
||||
jest.mock('@/components/ui/Toast', () => ({
|
||||
__esModule: true,
|
||||
useToast: () => ({
|
||||
toasts: [],
|
||||
success: jest.fn(),
|
||||
error: jest.fn(),
|
||||
warning: jest.fn(),
|
||||
info: jest.fn(),
|
||||
removeToast: jest.fn(),
|
||||
}),
|
||||
useToast: () => ({ toasts: [], success: jest.fn(), error: jest.fn(), warning: jest.fn(), info: jest.fn(), removeToast: jest.fn() }),
|
||||
ToastContainer: () => null,
|
||||
}))
|
||||
|
||||
jest.mock('@/components/platform/PlatformSplitLayout', () => ({
|
||||
__esModule: true,
|
||||
PlatformSplitLayout: ({
|
||||
leftContent,
|
||||
rightContent,
|
||||
}: {
|
||||
leftContent: ReactNode
|
||||
rightContent: ReactNode
|
||||
}) => (
|
||||
<div>
|
||||
<div>{leftContent}</div>
|
||||
<div>{rightContent}</div>
|
||||
</div>
|
||||
),
|
||||
PlatformSplitLayout: ({ leftContent, rightContent }: { leftContent: ReactNode; rightContent: ReactNode }) => <div><div>{leftContent}</div><div>{rightContent}</div></div>,
|
||||
}))
|
||||
|
||||
jest.mock('@/lib/open-product/platform-api', () => ({
|
||||
__esModule: true,
|
||||
createMaterial: jest.fn(),
|
||||
createMaterialCategory: jest.fn(),
|
||||
createSubstrate: jest.fn(),
|
||||
createSubstrateDictionary: jest.fn(),
|
||||
deleteMaterial: jest.fn(),
|
||||
deleteMaterialCategory: jest.fn(),
|
||||
deleteSubstrate: jest.fn(),
|
||||
deleteSubstrateDictionary: jest.fn(),
|
||||
updateMaterial: jest.fn(),
|
||||
updateMaterialCategory: jest.fn(),
|
||||
updateSubstrate: jest.fn(),
|
||||
updateSubstrateDictionary: jest.fn(),
|
||||
uploadMaterialThumbnail: jest.fn(),
|
||||
}))
|
||||
|
||||
const mockedCreateSubstrate = jest.mocked(createSubstrate)
|
||||
|
||||
const dictionaries: SubstrateDictionaryBundleDTO = {
|
||||
categories: [
|
||||
{
|
||||
id: 'cat-board',
|
||||
type: 'CATEGORY',
|
||||
name: '密度板',
|
||||
sortOrder: 0,
|
||||
isActive: true,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
],
|
||||
environmentGrades: [
|
||||
{
|
||||
id: 'grade-e1',
|
||||
type: 'ENVIRONMENT_GRADE',
|
||||
name: 'E1',
|
||||
sortOrder: 0,
|
||||
isActive: true,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
],
|
||||
thicknessSpecs: [
|
||||
{
|
||||
id: 'th-18',
|
||||
type: 'THICKNESS_SPEC',
|
||||
name: '18',
|
||||
sortOrder: 0,
|
||||
isActive: true,
|
||||
thicknessMm: 18,
|
||||
sheetLengthMm: 2440,
|
||||
sheetWidthMm: 1220,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
],
|
||||
surfaceOptions: [
|
||||
{
|
||||
id: 'surface-double',
|
||||
type: 'SURFACE_OPTION',
|
||||
name: '双贴',
|
||||
sortOrder: 0,
|
||||
isActive: true,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
],
|
||||
systemNameOptions: [
|
||||
{
|
||||
id: 'sys-18e1',
|
||||
type: 'SYSTEM_NAME_OPTION',
|
||||
name: '18E1级刨花板',
|
||||
sortOrder: 0,
|
||||
isActive: true,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
],
|
||||
categories: [{ id: 'cat-board', type: 'CATEGORY', name: '密度板', sortOrder: 0, isActive: true, createdAt: new Date(), updatedAt: new Date() }],
|
||||
environmentGrades: [{ id: 'grade-e1', type: 'ENVIRONMENT_GRADE', name: 'E1', sortOrder: 0, isActive: true, createdAt: new Date(), updatedAt: new Date() }],
|
||||
thicknessSpecs: [{ id: 'th-18', type: 'THICKNESS_SPEC', name: '18', sortOrder: 0, isActive: true, thicknessMm: 18, sheetLengthMm: 2440, sheetWidthMm: 1220, createdAt: new Date(), updatedAt: new Date() }],
|
||||
surfaceOptions: [{ id: 'surface-double', type: 'SURFACE_OPTION', name: '双贴', sortOrder: 0, isActive: true, createdAt: new Date(), updatedAt: new Date() }],
|
||||
}
|
||||
|
||||
function renderClient() {
|
||||
return render(
|
||||
<MaterialLibraryClient
|
||||
initialSubstrates={[
|
||||
{
|
||||
id: 'substrate-1',
|
||||
code: 'PB18',
|
||||
name: '18E1级刨花板',
|
||||
description: null,
|
||||
categoryId: 'cat-board',
|
||||
categoryName: '密度板',
|
||||
environmentGradeId: 'grade-e1',
|
||||
environmentGradeName: 'E1',
|
||||
thicknessSpecId: 'th-18',
|
||||
thicknessSpecName: '18',
|
||||
thicknessMm: 18,
|
||||
sheetLengthMm: 2440,
|
||||
sheetWidthMm: 1220,
|
||||
surfaceOptionId: 'surface-double',
|
||||
surfaceOptionName: '双贴',
|
||||
systemNameOptionId: 'sys-18e1',
|
||||
systemNameOptionName: '18E1级刨花板',
|
||||
suggestedPrice: 180,
|
||||
weightKg: 32,
|
||||
finishes: [],
|
||||
metadata: null,
|
||||
isActive: true,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
] as SubstrateDTO[]}
|
||||
initialSubstrates={[{
|
||||
id: 'substrate-1',
|
||||
code: 'PB18',
|
||||
name: '18E1级刨花板',
|
||||
description: null,
|
||||
categoryId: 'cat-board',
|
||||
categoryName: '密度板',
|
||||
environmentGradeId: 'grade-e1',
|
||||
environmentGradeName: 'E1',
|
||||
thicknessSpecId: 'th-18',
|
||||
thicknessSpecName: '18',
|
||||
thicknessMm: 18,
|
||||
sheetLengthMm: 2440,
|
||||
sheetWidthMm: 1220,
|
||||
surfaceOptionId: 'surface-double',
|
||||
surfaceOptionName: '双贴',
|
||||
suggestedPrice: 180,
|
||||
weightKg: null,
|
||||
finishes: [],
|
||||
metadata: null,
|
||||
isActive: true,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
}] as SubstrateDTO[]}
|
||||
initialFinishes={[] as MaterialDTO[]}
|
||||
initialMaterialCategories={[] as MaterialCategoryDTO[]}
|
||||
initialSubstrateDictionaries={dictionaries}
|
||||
@ -191,12 +96,6 @@ describe('MaterialLibraryClient', () => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
it('默认先显示基材页签', () => {
|
||||
renderClient()
|
||||
|
||||
expect(screen.getByPlaceholderText('搜索基材名称、编码、材质...')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('新建基材时按规则字段提交并显示自动名称', async () => {
|
||||
const actor = userEvent.setup()
|
||||
mockedCreateSubstrate.mockResolvedValue({
|
||||
@ -216,10 +115,8 @@ describe('MaterialLibraryClient', () => {
|
||||
sheetWidthMm: 1220,
|
||||
surfaceOptionId: 'surface-double',
|
||||
surfaceOptionName: '双贴',
|
||||
systemNameOptionId: 'sys-18e1',
|
||||
systemNameOptionName: '18E1级刨花板',
|
||||
suggestedPrice: 200,
|
||||
weightKg: 36,
|
||||
weightKg: null,
|
||||
finishes: [],
|
||||
metadata: null,
|
||||
isActive: true,
|
||||
@ -230,24 +127,20 @@ describe('MaterialLibraryClient', () => {
|
||||
|
||||
renderClient()
|
||||
|
||||
// Switch to substrate tab first
|
||||
await actor.click(screen.getByRole('button', { name: /基材录入/ }))
|
||||
await actor.click(screen.getByRole('button', { name: /新建/ }))
|
||||
await actor.type(screen.getByLabelText(/基材编码/), 'PB25')
|
||||
await actor.type(screen.getByLabelText('建议售价'), '200')
|
||||
await actor.type(screen.getByLabelText(/整板重量/), '36')
|
||||
await actor.click(screen.getByRole('button', { name: '创建基材' }))
|
||||
await actor.type(screen.getByLabelText('售价'), '200')
|
||||
await actor.click(screen.getByRole('button', { name: '创建' }))
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockedCreateSubstrate).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
code: 'PB25',
|
||||
categoryId: 'cat-board',
|
||||
environmentGradeId: 'grade-e1',
|
||||
thicknessSpecId: 'th-18',
|
||||
surfaceOptionId: null,
|
||||
systemNameOptionId: 'sys-18e1',
|
||||
surfaceOptionId: 'surface-double',
|
||||
suggestedPrice: 200,
|
||||
weightKg: 36,
|
||||
finishIds: [],
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -15,17 +15,23 @@ function toFinitePositive(value: number | null | undefined): number | null {
|
||||
}
|
||||
|
||||
export function buildSubstrateDisplayName(params: {
|
||||
thicknessLabel: string
|
||||
thicknessMm: number
|
||||
environmentGradeLabel: string
|
||||
systemNameLabel: string
|
||||
categoryLabel: string
|
||||
finishLabels?: string[]
|
||||
surfaceLabel?: string
|
||||
}): string {
|
||||
const envLabel = params.environmentGradeLabel.trim()
|
||||
const envWithSuffix = envLabel ? (envLabel.endsWith('级') ? envLabel : `${envLabel}级`) : ''
|
||||
return [
|
||||
params.thicknessLabel.trim(),
|
||||
params.environmentGradeLabel.trim(),
|
||||
params.systemNameLabel.trim(),
|
||||
`${params.thicknessMm}`,
|
||||
envWithSuffix,
|
||||
params.categoryLabel.trim(),
|
||||
...(params.finishLabels ?? []),
|
||||
params.surfaceLabel?.trim() ?? '',
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join('')
|
||||
.join(' ')
|
||||
}
|
||||
|
||||
export function buildSubstrateSummaryLabel(params: {
|
||||
|
||||
@ -40,7 +40,6 @@ export interface SubstrateWithRelations extends Substrate {
|
||||
environmentGrade: { id: string; name: string }
|
||||
thicknessSpec: { id: string; name: string; thicknessMm: number; sheetLengthMm: number; sheetWidthMm: number }
|
||||
surfaceOption: { id: string; name: string } | null
|
||||
systemNameOption: { id: string; name: string }
|
||||
finishes: {
|
||||
finish: {
|
||||
id: string
|
||||
@ -89,7 +88,6 @@ const substrateRelationInclude = {
|
||||
},
|
||||
},
|
||||
surfaceOption: { select: { id: true, name: true } },
|
||||
systemNameOption: { select: { id: true, name: true } },
|
||||
finishes: {
|
||||
select: {
|
||||
finish: {
|
||||
|
||||
@ -103,8 +103,6 @@ describe('assetCenterService.createSubstrate', () => {
|
||||
},
|
||||
surfaceOptionId: null,
|
||||
surfaceOption: null,
|
||||
systemNameOptionId: 'sys-solid',
|
||||
systemNameOption: { id: 'sys-solid', name: '实木板' },
|
||||
suggestedPrice: 320,
|
||||
weightKg: 32,
|
||||
metadata: null,
|
||||
@ -124,7 +122,6 @@ describe('assetCenterService.createSubstrate', () => {
|
||||
environmentGradeId: 'grade-e1',
|
||||
thicknessSpecId: 'th-18',
|
||||
surfaceOptionId: null,
|
||||
systemNameOptionId: 'sys-solid',
|
||||
suggestedPrice: 320,
|
||||
weightKg: 32,
|
||||
finishIds: ['finish-oak', 'finish-walnut'],
|
||||
|
||||
@ -246,8 +246,6 @@ function toSubstrateDTO(record: SubstrateWithRelations): SubstrateDTO {
|
||||
sheetWidthMm: record.thicknessSpec.sheetWidthMm,
|
||||
surfaceOptionId: record.surfaceOptionId,
|
||||
surfaceOptionName: record.surfaceOption?.name ?? null,
|
||||
systemNameOptionId: record.systemNameOptionId,
|
||||
systemNameOptionName: record.systemNameOption.name,
|
||||
suggestedPrice: decimalToNumber(record.suggestedPrice),
|
||||
weightKg: record.weightKg ?? null,
|
||||
finishes: (record.finishes ?? []).map((item) => ({
|
||||
@ -291,8 +289,6 @@ function getDictionaryLabel(type: SubstrateDictionaryType): string {
|
||||
return '厚度规格'
|
||||
case 'SURFACE_OPTION':
|
||||
return '贴面类型'
|
||||
case 'SYSTEM_NAME_OPTION':
|
||||
return '系统名称'
|
||||
}
|
||||
}
|
||||
|
||||
@ -361,9 +357,8 @@ async function loadSubstrateParts(input: {
|
||||
environmentGradeId: string
|
||||
thicknessSpecId: string
|
||||
surfaceOptionId: string | null
|
||||
systemNameOptionId: string
|
||||
}) {
|
||||
const [category, environmentGrade, thicknessSpec, surfaceOption, systemNameOption] =
|
||||
const [category, environmentGrade, thicknessSpec, surfaceOption] =
|
||||
await Promise.all([
|
||||
prisma.substrateCategory.findUnique({ where: { id: input.categoryId } }),
|
||||
prisma.substrateEnvironmentGrade.findUnique({ where: { id: input.environmentGradeId } }),
|
||||
@ -371,7 +366,6 @@ async function loadSubstrateParts(input: {
|
||||
input.surfaceOptionId
|
||||
? prisma.substrateSurfaceOption.findUnique({ where: { id: input.surfaceOptionId } })
|
||||
: Promise.resolve(null),
|
||||
prisma.substrateSystemNameOption.findUnique({ where: { id: input.systemNameOptionId } }),
|
||||
])
|
||||
|
||||
if (!category) {
|
||||
@ -386,16 +380,12 @@ async function loadSubstrateParts(input: {
|
||||
if (input.surfaceOptionId && !surfaceOption) {
|
||||
throw new AppError(ErrorCode.SUBSTRATE_NOT_FOUND, '贴面类型不存在')
|
||||
}
|
||||
if (!systemNameOption) {
|
||||
throw new AppError(ErrorCode.SUBSTRATE_NOT_FOUND, '系统名称不存在')
|
||||
}
|
||||
|
||||
return {
|
||||
category,
|
||||
environmentGrade,
|
||||
thicknessSpec,
|
||||
surfaceOption,
|
||||
systemNameOption,
|
||||
}
|
||||
}
|
||||
|
||||
@ -404,13 +394,12 @@ async function buildSubstratePayload(input: {
|
||||
environmentGradeId: string
|
||||
thicknessSpecId: string
|
||||
surfaceOptionId: string | null
|
||||
systemNameOptionId: string
|
||||
}) {
|
||||
const parts = await loadSubstrateParts(input)
|
||||
const generatedName = buildSubstrateDisplayName({
|
||||
thicknessLabel: parts.thicknessSpec.name,
|
||||
thicknessMm: parts.thicknessSpec.thicknessMm,
|
||||
environmentGradeLabel: parts.environmentGrade.name,
|
||||
systemNameLabel: parts.systemNameOption.name,
|
||||
categoryLabel: parts.category.name,
|
||||
})
|
||||
|
||||
return {
|
||||
@ -450,7 +439,6 @@ async function buildSubstratePayloadWithFinishes(input: {
|
||||
environmentGradeId: string
|
||||
thicknessSpecId: string
|
||||
surfaceOptionId: string | null
|
||||
systemNameOptionId: string
|
||||
finishIds: string[]
|
||||
}) {
|
||||
const parts = await loadSubstrateParts(input)
|
||||
@ -464,15 +452,13 @@ async function buildSubstratePayloadWithFinishes(input: {
|
||||
: []
|
||||
|
||||
const finishPart = finishRows.map((item) => item.name).join(' ')
|
||||
const generatedName = [
|
||||
parts.thicknessSpec.name.toUpperCase(),
|
||||
parts.environmentGrade.name,
|
||||
parts.category.name,
|
||||
finishPart,
|
||||
parts.surfaceOption?.name ?? '',
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(' ')
|
||||
const generatedName = buildSubstrateDisplayName({
|
||||
thicknessMm: parts.thicknessSpec.thicknessMm,
|
||||
environmentGradeLabel: parts.environmentGrade.name,
|
||||
categoryLabel: parts.category.name,
|
||||
finishLabels: finishPart ? [finishPart] : [],
|
||||
surfaceLabel: parts.surfaceOption?.name ?? '',
|
||||
})
|
||||
|
||||
return {
|
||||
generatedName,
|
||||
@ -597,13 +583,12 @@ class AssetCenterService {
|
||||
}
|
||||
|
||||
async getSubstrateDictionaryBundle(): Promise<SubstrateDictionaryBundleDTO> {
|
||||
const [categories, environmentGrades, thicknessSpecs, surfaceOptions, systemNameOptions] =
|
||||
const [categories, environmentGrades, thicknessSpecs, surfaceOptions] =
|
||||
await Promise.all([
|
||||
prisma.substrateCategory.findMany({ orderBy: [{ sortOrder: 'asc' }, { name: 'asc' }] }),
|
||||
prisma.substrateEnvironmentGrade.findMany({ orderBy: [{ sortOrder: 'asc' }, { name: 'asc' }] }),
|
||||
prisma.substrateThicknessSpec.findMany({ orderBy: [{ sortOrder: 'asc' }, { thicknessMm: 'asc' }] }),
|
||||
prisma.substrateSurfaceOption.findMany({ orderBy: [{ sortOrder: 'asc' }, { name: 'asc' }] }),
|
||||
prisma.substrateSystemNameOption.findMany({ orderBy: [{ sortOrder: 'asc' }, { name: 'asc' }] }),
|
||||
])
|
||||
|
||||
return {
|
||||
@ -611,7 +596,6 @@ class AssetCenterService {
|
||||
environmentGrades: environmentGrades.map((item) => toDictionaryOptionDTO('ENVIRONMENT_GRADE', item)),
|
||||
thicknessSpecs: thicknessSpecs.map((item) => toDictionaryOptionDTO('THICKNESS_SPEC', item)),
|
||||
surfaceOptions: surfaceOptions.map((item) => toDictionaryOptionDTO('SURFACE_OPTION', item)),
|
||||
systemNameOptions: systemNameOptions.map((item) => toDictionaryOptionDTO('SYSTEM_NAME_OPTION', item)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -694,7 +678,6 @@ class AssetCenterService {
|
||||
environmentGradeId: input.environmentGradeId,
|
||||
thicknessSpecId: input.thicknessSpecId,
|
||||
surfaceOptionId: input.surfaceOptionId ?? null,
|
||||
systemNameOptionId: input.systemNameOptionId,
|
||||
isActive: true,
|
||||
},
|
||||
include: {
|
||||
@ -718,7 +701,6 @@ class AssetCenterService {
|
||||
environmentGradeId: existing.environmentGradeId,
|
||||
thicknessSpecId: existing.thicknessSpecId,
|
||||
surfaceOptionId: existing.surfaceOptionId ?? null,
|
||||
systemNameOptionId: existing.systemNameOptionId,
|
||||
finishIds: mergedFinishIds,
|
||||
})
|
||||
|
||||
@ -751,7 +733,6 @@ class AssetCenterService {
|
||||
environmentGradeId: input.environmentGradeId,
|
||||
thicknessSpecId: input.thicknessSpecId,
|
||||
surfaceOptionId: input.surfaceOptionId ?? null,
|
||||
systemNameOptionId: input.systemNameOptionId,
|
||||
finishIds,
|
||||
})
|
||||
|
||||
@ -766,7 +747,6 @@ class AssetCenterService {
|
||||
surfaceOption: input.surfaceOptionId
|
||||
? { connect: { id: input.surfaceOptionId } }
|
||||
: undefined,
|
||||
systemNameOption: { connect: { id: input.systemNameOptionId } },
|
||||
suggestedPrice: input.suggestedPrice ?? null,
|
||||
weightKg: input.weightKg ?? null,
|
||||
finishes:
|
||||
@ -788,7 +768,6 @@ class AssetCenterService {
|
||||
select: { id: true, name: true, thicknessMm: true, sheetLengthMm: true, sheetWidthMm: true },
|
||||
},
|
||||
surfaceOption: { select: { id: true, name: true } },
|
||||
systemNameOption: { select: { id: true, name: true } },
|
||||
finishes: {
|
||||
include: {
|
||||
finish: {
|
||||
@ -828,7 +807,6 @@ class AssetCenterService {
|
||||
const nextThicknessSpecId = input.thicknessSpecId ?? existing.thicknessSpecId
|
||||
const nextSurfaceOptionId =
|
||||
input.surfaceOptionId !== undefined ? input.surfaceOptionId : existing.surfaceOptionId
|
||||
const nextSystemNameOptionId = input.systemNameOptionId ?? existing.systemNameOptionId
|
||||
const nextFinishIds =
|
||||
input.finishIds !== undefined
|
||||
? normalizeFinishIds(input.finishIds)
|
||||
@ -842,13 +820,12 @@ class AssetCenterService {
|
||||
environmentGradeId: nextEnvironmentGradeId,
|
||||
thicknessSpecId: nextThicknessSpecId,
|
||||
surfaceOptionId: nextSurfaceOptionId ?? null,
|
||||
systemNameOptionId: nextSystemNameOptionId,
|
||||
isActive: true,
|
||||
},
|
||||
select: { id: true },
|
||||
})
|
||||
if (duplicate) {
|
||||
throw new AppError(ErrorCode.VALIDATION_FAILED, '已存在相同 5 字段规格的基材,请直接维护已有基材')
|
||||
throw new AppError(ErrorCode.VALIDATION_FAILED, '已存在相同规格的基材,请直接维护已有基材')
|
||||
}
|
||||
|
||||
const payload = await buildSubstratePayloadWithFinishes({
|
||||
@ -856,7 +833,6 @@ class AssetCenterService {
|
||||
environmentGradeId: nextEnvironmentGradeId,
|
||||
thicknessSpecId: nextThicknessSpecId,
|
||||
surfaceOptionId: nextSurfaceOptionId ?? null,
|
||||
systemNameOptionId: nextSystemNameOptionId,
|
||||
finishIds: nextFinishIds,
|
||||
})
|
||||
|
||||
@ -883,10 +859,6 @@ class AssetCenterService {
|
||||
: input.surfaceOptionId
|
||||
? { connect: { id: input.surfaceOptionId } }
|
||||
: { disconnect: true },
|
||||
systemNameOption:
|
||||
input.systemNameOptionId === undefined
|
||||
? undefined
|
||||
: { connect: { id: input.systemNameOptionId } },
|
||||
suggestedPrice: input.suggestedPrice === undefined ? undefined : input.suggestedPrice,
|
||||
weightKg: input.weightKg === undefined ? undefined : input.weightKg,
|
||||
finishes:
|
||||
@ -908,7 +880,6 @@ class AssetCenterService {
|
||||
select: { id: true, name: true, thicknessMm: true, sheetLengthMm: true, sheetWidthMm: true },
|
||||
},
|
||||
surfaceOption: { select: { id: true, name: true } },
|
||||
systemNameOption: { select: { id: true, name: true } },
|
||||
finishes: {
|
||||
include: {
|
||||
finish: {
|
||||
@ -981,11 +952,6 @@ class AssetCenterService {
|
||||
'SURFACE_OPTION',
|
||||
await prisma.substrateSurfaceOption.create({ data: dataBase }),
|
||||
)
|
||||
case 'SYSTEM_NAME_OPTION':
|
||||
return toDictionaryOptionDTO(
|
||||
'SYSTEM_NAME_OPTION',
|
||||
await prisma.substrateSystemNameOption.create({ data: dataBase }),
|
||||
)
|
||||
}
|
||||
} catch (error) {
|
||||
if (
|
||||
@ -1056,18 +1022,6 @@ class AssetCenterService {
|
||||
},
|
||||
}),
|
||||
)
|
||||
case 'SYSTEM_NAME_OPTION':
|
||||
return toDictionaryOptionDTO(
|
||||
'SYSTEM_NAME_OPTION',
|
||||
await prisma.substrateSystemNameOption.update({
|
||||
where: { id },
|
||||
data: {
|
||||
name: input.name?.trim(),
|
||||
sortOrder: input.sortOrder,
|
||||
isActive: input.isActive,
|
||||
},
|
||||
}),
|
||||
)
|
||||
}
|
||||
} catch (error) {
|
||||
if (
|
||||
@ -1092,7 +1046,6 @@ class AssetCenterService {
|
||||
ENVIRONMENT_GRADE: { environmentGradeId: id },
|
||||
THICKNESS_SPEC: { thicknessSpecId: id },
|
||||
SURFACE_OPTION: { surfaceOptionId: id },
|
||||
SYSTEM_NAME_OPTION: { systemNameOptionId: id },
|
||||
}
|
||||
const referenceCount = await prisma.substrate.count({ where: whereByType[type] })
|
||||
if (referenceCount > 0) {
|
||||
@ -1113,9 +1066,6 @@ class AssetCenterService {
|
||||
case 'SURFACE_OPTION':
|
||||
await prisma.substrateSurfaceOption.delete({ where: { id } })
|
||||
return
|
||||
case 'SYSTEM_NAME_OPTION':
|
||||
await prisma.substrateSystemNameOption.delete({ where: { id } })
|
||||
return
|
||||
}
|
||||
} catch (error) {
|
||||
if (
|
||||
|
||||
@ -100,8 +100,6 @@ export interface SubstrateDTO {
|
||||
sheetWidthMm: number
|
||||
surfaceOptionId: string | null
|
||||
surfaceOptionName: string | null
|
||||
systemNameOptionId: string
|
||||
systemNameOptionName: string
|
||||
suggestedPrice: number | null
|
||||
weightKg: number | null
|
||||
finishes: {
|
||||
@ -121,7 +119,6 @@ export type SubstrateDictionaryType =
|
||||
| 'ENVIRONMENT_GRADE'
|
||||
| 'THICKNESS_SPEC'
|
||||
| 'SURFACE_OPTION'
|
||||
| 'SYSTEM_NAME_OPTION'
|
||||
|
||||
export interface SubstrateDictionaryOptionDTO {
|
||||
id: string
|
||||
@ -141,7 +138,6 @@ export interface SubstrateDictionaryBundleDTO {
|
||||
environmentGrades: SubstrateDictionaryOptionDTO[]
|
||||
thicknessSpecs: SubstrateDictionaryOptionDTO[]
|
||||
surfaceOptions: SubstrateDictionaryOptionDTO[]
|
||||
systemNameOptions: SubstrateDictionaryOptionDTO[]
|
||||
}
|
||||
|
||||
export interface CreateAssetFamilyInput {
|
||||
@ -223,7 +219,6 @@ export interface CreateSubstrateInput {
|
||||
environmentGradeId: string
|
||||
thicknessSpecId: string
|
||||
surfaceOptionId?: string | null
|
||||
systemNameOptionId: string
|
||||
suggestedPrice?: number | null
|
||||
weightKg?: number | null
|
||||
finishIds?: string[]
|
||||
@ -238,7 +233,6 @@ export interface UpdateSubstrateInput {
|
||||
environmentGradeId?: string
|
||||
thicknessSpecId?: string
|
||||
surfaceOptionId?: string | null
|
||||
systemNameOptionId?: string
|
||||
suggestedPrice?: number | null
|
||||
weightKg?: number | null
|
||||
finishIds?: string[]
|
||||
|
||||
@ -341,7 +341,7 @@ async function ensureSubstrate(creatorId: string) {
|
||||
return existing
|
||||
}
|
||||
|
||||
const [category, environmentGrade, thicknessSpec, surfaceOption, systemNameOption] = await Promise.all([
|
||||
const [category, environmentGrade, thicknessSpec, surfaceOption] = await Promise.all([
|
||||
prisma.substrateCategory.upsert({
|
||||
where: { name: '颗粒板' },
|
||||
update: {},
|
||||
@ -362,11 +362,6 @@ async function ensureSubstrate(creatorId: string) {
|
||||
update: {},
|
||||
create: { name: '双贴', sortOrder: 0, isActive: true },
|
||||
}),
|
||||
prisma.substrateSystemNameOption.upsert({
|
||||
where: { name: '18E1级颗粒板' },
|
||||
update: {},
|
||||
create: { name: '18E1级颗粒板', sortOrder: 0, isActive: true },
|
||||
}),
|
||||
])
|
||||
|
||||
return assetCenterService.createSubstrate({
|
||||
@ -376,7 +371,6 @@ async function ensureSubstrate(creatorId: string) {
|
||||
environmentGradeId: environmentGrade.id,
|
||||
thicknessSpecId: thicknessSpec.id,
|
||||
surfaceOptionId: surfaceOption.id,
|
||||
systemNameOptionId: systemNameOption.id,
|
||||
suggestedPrice: 180,
|
||||
metadata: {
|
||||
seedKey: OPEN_PLATFORM_DEMO_SEED_MARKER,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user