import type { _SkuSpec, SkuItem } from '../../../types/components/sku' /** * 生成SKU树,用于规格选择和禁用状态管理 */ export function generateSkuTree(specs: _SkuSpec[], skus: SkuItem[]) { // 创建规格值映射 const specValueMap = new Map>() specs.forEach(spec => { specValueMap.set(spec.name, new Set()) }) // 收集所有有效的规格值 skus.forEach(sku => { Object.entries(sku.specs).forEach(([specName, specValue]) => { specValueMap.get(specName)?.add(specValue) }) }) // 更新规格值的禁用状态 const updatedSpecs = specs.map(spec => { const availableValues = specValueMap.get(spec.name) || new Set() return { ...spec, values: spec.values.map(value => ({ ...value, disabled: !availableValues.has(value.name) })) } }) return updatedSpecs } /** * 根据选中的规格计算可用的规格值 */ export function getAvailableSpecValues( selectedSpecs: Record, specs: _SkuSpec[], skus: SkuItem[] ) { const availableValues = new Map>() // 初始化所有规格值 specs.forEach(spec => { spec.values.forEach(value => { if (!availableValues.has(spec.name)) { availableValues.set(spec.name, new Set()) } availableValues.get(spec.name)?.add(value.name) }) }) // 过滤不可用的规格值 skus.forEach(sku => { // 检查这个SKU是否与当前选中的规格匹配 const isMatch = Object.keys(selectedSpecs).every(specName => { return sku.specs[specName] === selectedSpecs[specName] }) if (isMatch && sku.stock > 0 && !sku.disabled) { // 这个SKU可用,将其规格值标记为可用 Object.entries(sku.specs).forEach(([specName, specValue]) => { if (!selectedSpecs[specName]) { availableValues.get(specName)?.add(specValue) } }) } }) // 更新规格的禁用状态 return specs.map(spec => { const availableSet = availableValues.get(spec.name) || new Set() return { ...spec, values: spec.values.map(value => ({ ...value, disabled: !availableSet.has(value.name) })) } }) } /** * 验证SKU数据 */ export function validateSkuData(specs: _SkuSpec[], skus: SkuItem[]) { const errors: string[] = [] // 检查规格是否为空 if (!specs.length) { errors.push('规格列表不能为空') } // 检查SKU是否为空 if (!skus.length) { errors.push('SKU列表不能为空') } // 检查规格名称是否重复 const specNames = specs.map(spec => spec.name) const uniqueSpecNames = new Set(specNames) if (uniqueSpecNames.size !== specNames.length) { errors.push('规格名称不能重复') } // 检查每个规格的值是否重复 specs.forEach(spec => { const valueNames = spec.values.map(value => value.name) const uniqueValueNames = new Set(valueNames) if (uniqueValueNames.size !== valueNames.length) { errors.push(`规格"${spec.name}"的值不能重复`) } }) // 检查SKU规格组合是否完整 const expectedSpecCount = specs.length skus.forEach((sku, index) => { const specCount = Object.keys(sku.specs).length if (specCount !== expectedSpecCount) { errors.push(`SKU ${index + 1} 的规格数量不完整`) } }) // 检查SKU规格值是否有效 skus.forEach((sku, index) => { Object.entries(sku.specs).forEach(([specName, specValue]) => { const spec = specs.find(s => s.name === specName) if (!spec) { errors.push(`SKU ${index + 1} 包含不存在的规格"${specName}"`) } else if (!spec.values.some(v => v.name === specValue)) { errors.push(`SKU ${index + 1} 包含无效的规格值"${specValue}"`) } }) }) return errors } /** * 根据规格值查找SKU */ export function findSkuBySpecs( specs: Record, skus: SkuItem[] ): SkuItem | undefined { return skus.find(sku => { return Object.keys(specs).every(key => { return sku.specs[key] === specs[key] }) }) } /** * 获取默认选中的规格 */ export function getDefaultSelectedSpecs(skus: SkuItem[]) { const selectedSpecs: Record = {} // 找到第一个有库存的SKU const availableSku = skus.find(sku => sku.stock > 0 && !sku.disabled) if (availableSku) { return { ...availableSku.specs } } return selectedSpecs } /** * 检查规格组合是否完整 */ export function isSpecsComplete( selectedSpecs: Record, specs: _SkuSpec[] ) { return specs.every(spec => selectedSpecs[spec.name]) }