({ chunkUpload: jest.fn() }))
+test('成品只填写 SPU 时不能上传,须先填写报告名称', () => {
+ const originalFetch = global.fetch
+ global.fetch = jest.fn()
+ try {
+ render()
+ fireEvent.change(screen.getByLabelText('SPU'), { target: { value: 'SPU-001' } })
+ fireEvent.click(screen.getByRole('button', { name: '创建分享素材' }))
+ expect(screen.getByText('请填写报告名称 / 检测对象')).toBeInTheDocument()
+ expect(global.fetch).not.toHaveBeenCalled()
+ } finally {
+ global.fetch = originalFetch
+ }
+})
+
test.each([['成品', true], ['成品', false], ['原材料', true], ['原材料', false]] as const)('%s上传说明与日期:手动到期时间 %s', async (kind, manualExpiry) => {
const originalFetch = global.fetch
jest.useFakeTimers().setSystemTime(new Date('2026-09-27T12:00:00'))
@@ -12,6 +26,12 @@ test.each([['成品', true], ['成品', false], ['原材料', true], ['原材料
try {
expect(screen.getByLabelText('成品')).toBeChecked()
fireEvent.click(screen.getByLabelText(kind))
+ const reportTitleInput = screen.getByLabelText('报告名称 / 检测对象 *')
+ expect(reportTitleInput).toBeRequired()
+ if (kind === '成品') {
+ expect(reportTitleInput.compareDocumentPosition(screen.getByLabelText('SPU')) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy()
+ }
+ expect(screen.getByText('上传后将作为素材名称显示')).toBeInTheDocument()
fireEvent.change(screen.getByLabelText(/报告名称 \/ 检测对象/), { target: { value: '板材检测报告' } })
fireEvent.change(screen.getByLabelText('品类 *'), { target: { value: '板材' } })
fireEvent.change(screen.getByLabelText('证书编号 *'), { target: { value: 'CMA-001' } })
diff --git a/components/upload/CertificateReportUploader.tsx b/components/upload/CertificateReportUploader.tsx
index c1ec989..bfb4d60 100644
--- a/components/upload/CertificateReportUploader.tsx
+++ b/components/upload/CertificateReportUploader.tsx
@@ -122,6 +122,10 @@ export default function CertificateReportUploader({
const handleSubmit = async () => {
const submittedProductModel = reportKind === CERTIFICATE_REPORT_KIND.RAW ? '' : productModel.trim()
+ if (reportKind === CERTIFICATE_REPORT_KIND.FINISHED && !reportTitle.trim()) {
+ setError('请填写报告名称 / 检测对象')
+ return
+ }
const metadata = validateCertificateReportMetadata({
reportKind,
productModel: submittedProductModel,
@@ -280,6 +284,23 @@ export default function CertificateReportUploader({
+
+
+
setReportTitle(event.target.value)}
+ placeholder="例如:E0级颗粒板检测报告"
+ className={fieldControlClass}
+ required
+ />
+
+ 上传后将作为素材名称显示
+
+
{reportKind === CERTIFICATE_REPORT_KIND.FINISHED && (
@@ -293,24 +314,6 @@ export default function CertificateReportUploader({
/>
)}
-
-
-
-
setReportTitle(event.target.value)}
- placeholder="例如:E0级颗粒板检测报告"
- className={fieldControlClass}
- required={reportKind === CERTIFICATE_REPORT_KIND.RAW}
- />
-
- {reportKind === CERTIFICATE_REPORT_KIND.RAW ? '原材料检测报告必须填写报告名称' : 'SPU 和这个字段至少填写一个'}
-
-
diff --git a/lib/__tests__/certificate-report.test.ts b/lib/__tests__/certificate-report.test.ts
index 377a6fd..19e91c0 100644
--- a/lib/__tests__/certificate-report.test.ts
+++ b/lib/__tests__/certificate-report.test.ts
@@ -41,12 +41,16 @@ describe('检测报告字段规则', () => {
reportTitle: '板材检测报告',
})).toHaveProperty('value.reportKind', '原材料')
expect(getCertificateReportDisplayTitle({
- reportKind: '原材料',
productModel: '旧 SPU',
reportTitle: '板材检测报告',
})).toBe('板材检测报告')
})
+ test('成品有报告名称时优先显示,旧记录缺少名称时显示 SPU', () => {
+ expect(getCertificateReportDisplayTitle({ productModel: 'SPU-001', reportTitle: '成品检测报告' })).toBe('成品检测报告')
+ expect(getCertificateReportDisplayTitle({ productModel: 'SPU-001', reportTitle: null })).toBe('SPU-001')
+ })
+
test('检测日期必须是真实的 YYYY-MM-DD 日期', () => {
expect(parseCertificateDate('2027-02-28')?.toISOString().slice(0, 10)).toBe('2027-02-28')
expect(parseCertificateDate('2027-02-30')).toBeNull()
diff --git a/lib/certificate-report.ts b/lib/certificate-report.ts
index db9945f..c45f9eb 100644
--- a/lib/certificate-report.ts
+++ b/lib/certificate-report.ts
@@ -153,21 +153,15 @@ export function validateCertificateReportMetadata(input: {
export function getCertificateReportDisplayTitle(input: {
productModel?: string | null
reportTitle?: string | null
- reportKind?: string | null
}): string {
const productModel = String(input.productModel || '').trim()
const reportTitle = String(input.reportTitle || '').trim()
- if (input.reportKind === CERTIFICATE_REPORT_KIND.RAW && reportTitle) {
+ if (reportTitle) {
return reportTitle
}
if (productModel) {
return productModel
}
-
- if (reportTitle) {
- return reportTitle
- }
-
return '未命名报告'
}