PHP多规格商品算法

wen PHP项目 6

本文目录导读:

PHP多规格商品算法

  1. 核心SKU生成算法
  2. 商品SKU管理类
  3. SKU价格计算
  4. 完整使用示例
  5. 数据库表结构
  6. 前端联动判断算法

我将为您提供一个PHP多规格商品SKU算法实现,包含完整的SKU生成、库存管理和价格计算功能。

核心SKU生成算法

<?php
class SKUGenerator
{
    /**
     * 生成所有SKU组合
     * @param array $specs 规格字典,如 ['颜色' => ['红色','蓝色'], '尺寸' => ['S','M','L']]
     * @return array 所有SKU组合
     */
    public function generateCombinations(array $specs): array
    {
        $result = [[]];
        foreach ($specs as $specName => $specValues) {
            $temp = [];
            foreach ($result as $combination) {
                foreach ($specValues as $value) {
                    $temp[] = array_merge($combination, [$specName => $value]);
                }
            }
            $result = $temp;
        }
        return $result;
    }
    /**
     * 生成SKU编码
     * @param array $combination 规格组合
     * @param string $productId 商品ID
     * @return string
     */
    public function generateSkuCode(array $combination, string $productId = ''): string
    {
        $code = $productId ? $productId . '-' : '';
        foreach ($combination as $specName => $value) {
            $code .= $this->encodeSpec($specName, $value) . '-';
        }
        return rtrim($code, '-');
    }
    private function encodeSpec(string $name, string $value): string
    {
        // 简单的编码,可根据需求调整
        return strtoupper(mb_substr($name, 0, 1)) . strtoupper(mb_substr($value, 0, 2));
    }
}

商品SKU管理类

<?php
class ProductSKUManager
{
    private $productId;
    private $specs;           // 规格字典
    private $skuList = [];    // SKU列表
    public function __construct(string $productId, array $specs)
    {
        $this->productId = $productId;
        $this->specs = $specs;
    }
    /**
     * 初始化所有SKU
     * @param float $defaultPrice 默认价格
     * @param int $defaultStock 默认库存
     */
    public function initSKUs(float $defaultPrice = 0, int $defaultStock = 0): void
    {
        $generator = new SKUGenerator();
        $combinations = $generator->generateCombinations($this->specs);
        foreach ($combinations as $index => $combination) {
            $sku = [
                'sku_code' => $generator->generateSkuCode($combination, $this->productId),
                'specs' => $combination,
                'price' => $defaultPrice,
                'stock' => $defaultStock,
                'image' => '',
                'weight' => 0,
                'status' => 1
            ];
            $this->skuList[] = $sku;
        }
    }
    /**
     * 获取特定规格的SKU
     * @param array $selectedSpecs 选中的规格,如 ['颜色' => '红色', '尺寸' => 'M']
     * @return array|null
     */
    public function findSKU(array $selectedSpecs): ?array
    {
        foreach ($this->skuList as $sku) {
            $match = true;
            foreach ($selectedSpecs as $specName => $value) {
                if (!isset($sku['specs'][$specName]) || $sku['specs'][$specName] !== $value) {
                    $match = false;
                    break;
                }
            }
            if ($match) {
                return $sku;
            }
        }
        return null;
    }
    /**
     * 更新SKU库存
     */
    public function updateStock(array $selectedSpecs, int $quantity): bool
    {
        $sku = $this->findSKU($selectedSpecs);
        if (!$sku) return false;
        // 更新逻辑,这里简化为直接修改
        foreach ($this->skuList as &$item) {
            if ($item['sku_code'] === $sku['sku_code']) {
                $item['stock'] = $quantity;
                return true;
            }
        }
        return false;
    }
    /**
     * 库存扣减
     */
    public function decreaseStock(array $selectedSpecs, int $quantity): bool
    {
        $sku = $this->findSKU($selectedSpecs);
        if (!$sku || $sku['stock'] < $quantity) return false;
        foreach ($this->skuList as &$item) {
            if ($item['sku_code'] === $sku['sku_code']) {
                $item['stock'] -= $quantity;
                return true;
            }
        }
        return false;
    }
    /**
     * 检查规格是否可选(用于前端联动)
     */
    public function isSpecAvailable(array $selectedSpecs, string $specName, string $specValue): bool
    {
        $testSpecs = $selectedSpecs;
        $testSpecs[$specName] = $specValue;
        $sku = $this->findSKU($testSpecs);
        return $sku !== null && $sku['stock'] > 0;
    }
    /**
     * 获取所有SKU
     */
    public function getAllSKUs(): array
    {
        return $this->skuList;
    }
}

SKU价格计算

<?php
class SKUPriceCalculator
{
    /**
     * 计算SKU价格(考虑促销、会员价等)
     * @param array $sku SKU数据
     * @param array $user 用户信息(可选)
     * @return float
     */
    public function calculatePrice(array $sku, array $user = []): float
    {
        $basePrice = $sku['price'];
        // 会员价计算
        if (isset($user['level']) && isset($sku['member_prices'])) {
            $memberPrices = $sku['member_prices'];
            if (isset($memberPrices[$user['level']])) {
                $basePrice = $memberPrices[$user['level']];
            }
        }
        // 促销价格
        if (isset($sku['promotion_price']) && $sku['promotion_price'] > 0) {
            $promotionPrice = $sku['promotion_price'];
            if ($promotionPrice < $basePrice) {
                $basePrice = $promotionPrice;
            }
        }
        // 阶梯价格计算
        if (isset($sku['tier_prices']) && !empty($sku['tier_prices'])) {
            $quantity = $sku['quantity'] ?? 1;
            foreach ($sku['tier_prices'] as $tier) {
                if ($quantity >= $tier['min_quantity']) {
                    $basePrice = $tier['price'];
                    break;
                }
            }
        }
        return round($basePrice, 2);
    }
    /**
     * 批量计算价格
     */
    public function calculateBatchPrices(array $skuList, array $user = []): array
    {
        $result = [];
        foreach ($skuList as $sku) {
            $result[$sku['sku_code']] = $this->calculatePrice($sku, $user);
        }
        return $result;
    }
}

完整使用示例

<?php
// 使用示例
class ProductExample
{
    public function demo()
    {
        // 定义商品规格
        $specs = [
            '颜色' => ['红色', '蓝色', '绿色'],
            '尺寸' => ['S', 'M', 'L'],
            '版本' => ['标准版', '豪华版']
        ];
        // 创建SKU管理器
        $manager = new ProductSKUManager('P001', $specs);
        // 初始化所有SKU,默认价格599,库存100
        $manager->initSKUs(599.00, 100);
        // 获取所有SKU数量
        $allSKUs = $manager->getAllSKUs();
        echo "共生成 " . count($allSKUs) . " 个SKU\n"; // 3 × 3 × 2 = 18个
        // 查找特定SKU
        $selected = ['颜色' => '红色', '尺寸' => 'M', '版本' => '标准版'];
        $sku = $manager->findSKU($selected);
        if ($sku) {
            echo "找到SKU: " . $sku['sku_code'] . "\n";
            echo "价格: ¥" . $sku['price'] . "\n";
            echo "库存: " . $sku['stock'] . "\n";
        }
        // 扣减库存
        $manager->decreaseStock($selected, 2);
        echo "扣减后库存: " . $manager->findSKU($selected)['stock'] . "\n";
        // 检查规格是否可选
        $available = $manager->isSpecAvailable(['颜色' => '红色'], '尺寸', 'M');
        echo "红色M码是否可选: " . ($available ? '是' : '否') . "\n";
        // 价格计算
        $calculator = new SKUPriceCalculator();
        $price = $calculator->calculatePrice($sku, ['level' => 'vip']);
        echo "VIP价格: ¥" . $price . "\n";
        // 输出所有SKU
        echo "\n所有SKU列表:\n";
        foreach ($allSKUs as $item) {
            $specStr = [];
            foreach ($item['specs'] as $key => $value) {
                $specStr[] = "$key: $value";
            }
            echo $item['sku_code'] . " | " . implode(", ", $specStr) 
                . " | ¥" . $item['price'] . " | 库存:" . $item['stock'] . "\n";
        }
    }
}
// 运行示例
$example = new ProductExample();
$example->demo();

数据库表结构

-- 商品表
CREATE TABLE products (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,
    description TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
-- 规格表
CREATE TABLE product_specs (
    id INT PRIMARY KEY AUTO_INCREMENT,
    product_id INT NOT NULL,
    spec_name VARCHAR(50) NOT NULL,
    spec_values JSON NOT NULL,
    FOREIGN KEY (product_id) REFERENCES products(id)
) ENGINE=InnoDB;
-- SKU表
CREATE TABLE product_skus (
    id INT PRIMARY KEY AUTO_INCREMENT,
    product_id INT NOT NULL,
    sku_code VARCHAR(100) UNIQUE NOT NULL,
    specs JSON NOT NULL,
    price DECIMAL(10,2) NOT NULL,
    stock INT NOT NULL DEFAULT 0,
    status TINYINT DEFAULT 1,
    image VARCHAR(255),
    weight DECIMAL(10,2) DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (product_id) REFERENCES products(id),
    INDEX idx_sku_code (sku_code)
) ENGINE=InnoDB;
-- SKU促销价格表
CREATE TABLE sku_promotions (
    id INT PRIMARY KEY AUTO_INCREMENT,
    sku_id INT NOT NULL,
    promotion_price DECIMAL(10,2),
    start_time DATETIME,
    end_time DATETIME,
    FOREIGN KEY (sku_id) REFERENCES product_skus(id)
) ENGINE=InnoDB;

前端联动判断算法

<?php
class FrontendSkuHelper
{
    /**
     * 获取可选规格值(前端联动用)
     * @param array $allSKUs 所有SKU
     * @param array $selectedSpecs 已选规格
     * @return array 每项规格的可选值
     */
    public function getAvailableOptions(array $allSKUs, array $selectedSpecs): array
    {
        $availableOptions = [];
        foreach ($selectedSpecs as $specName => $specValue) {
            if (empty($specValue)) continue;
            // 复制当前选择,但排除正在检查的规格
            $tempSpecs = $selectedSpecs;
            unset($tempSpecs[$specName]);
            // 找出该规格的可选值
            $values = [];
            foreach ($allSKUs as $sku) {
                if ($this->matchesSpecs($sku['specs'], $tempSpecs) && $sku['stock'] > 0) {
                    $values[] = $sku['specs'][$specName];
                }
            }
            $availableOptions[$specName] = array_unique($values);
        }
        return $availableOptions;
    }
    private function matchesSpecs(array $skuSpecs, array $requiredSpecs): bool
    {
        foreach ($requiredSpecs as $name => $value) {
            if (!isset($skuSpecs[$name]) || $skuSpecs[$name] !== $value) {
                return false;
            }
        }
        return true;
    }
}

这个算法实现包含了:

  1. 多规格组合生成 - 自动生成所有SKU组合
  2. SKU编码生成 - 统一的SKU编码规则
  3. 库存管理 - 增减库存、库存检查
  4. 价格计算 - 支持基础价、会员价、促销价、阶梯价
  5. 前端联动判断 - 判断哪些规格可选
  6. 数据库表设计 - 完整的数据结构支持

可以根据具体需求调整算法复杂度和功能范围。

抱歉,评论功能暂时关闭!