52 lines
2.3 KiB
TypeScript
52 lines
2.3 KiB
TypeScript
const PRODUCT_MODEL_ALLOWED_CHARACTERS = /^[A-Z0-9][A-Z0-9+_.-]*[A-Z0-9]$/
|
||
|
||
/**
|
||
* SPU 唯一允许的自动格式化是转成大写。空格、中文和其它非法字符必须
|
||
* 原样留在输入框里交给校验提示,不能静默删除后把另一个型号写入数据库。
|
||
*/
|
||
export function normalizeSpuProductModel(value: unknown): string {
|
||
return typeof value === 'string'
|
||
? value.replace(/[a-z]/g, character => character.toUpperCase())
|
||
: ''
|
||
}
|
||
|
||
export const SPU_PRODUCT_MODEL_FORMAT_HINT =
|
||
'必须同时包含英文字母和数字,只能使用字母、数字及 +、-、_、.,且不能以符号开头或结尾'
|
||
|
||
export function getSpuProductModelValidationError(value: unknown): string | null {
|
||
const normalized = normalizeSpuProductModel(value)
|
||
|
||
if (!normalized) return '请填写真实 SPU,例如 DF-A3DZ0008'
|
||
if (normalized.length > 100) return 'SPU 不能超过 100 个字符'
|
||
if (normalized !== normalized.trim()) return 'SPU 前后不能包含空格'
|
||
if (!/[A-Z]/.test(normalized) || !/\d/.test(normalized)) {
|
||
return 'SPU 必须同时包含英文字母和数字'
|
||
}
|
||
if (!PRODUCT_MODEL_ALLOWED_CHARACTERS.test(normalized)) {
|
||
return `SPU ${SPU_PRODUCT_MODEL_FORMAT_HINT}`
|
||
}
|
||
|
||
return null
|
||
}
|
||
|
||
/**
|
||
* 这里只拒绝可以明确判定不是 SPU 的值,不假设所有业务线都使用同一套编码。
|
||
* 现有合法型号包含 DF-A3DZ0008、GBPM-SN0204、626DNZ0385-1 等多种格式;
|
||
* 共同边界是包含英文字母和数字,且不能以分隔符开头或结尾。
|
||
*/
|
||
export function isPlausibleSpuProductModel(value: unknown): boolean {
|
||
return getSpuProductModelValidationError(value) === null
|
||
}
|
||
|
||
/**
|
||
* 从文件名中只提取“有明确型号结构”的 SPU;无法确认时必须返回空值,
|
||
* 交给上传人填写,不能再把中文被剔除后的数字尾号冒充为 SPU。
|
||
*/
|
||
export function extractPlausibleSpuFromFileName(filename: string): string {
|
||
const nameWithoutExtension = normalizeSpuProductModel(filename.replace(/\.[^/.]+$/, ''))
|
||
|
||
// 只接受整个文件名(不含扩展名)就是合法 SPU;带说明文字或额外字符时留空,
|
||
// 由上传人确认填写,绝不从文件名中截取一段并冒充用户的 SPU。
|
||
return isPlausibleSpuProductModel(nameWithoutExtension) ? nameWithoutExtension : ''
|
||
}
|