SkuSpec
服务类封装了商品规格相关的所有查询操作,基于 fa_shop_goods_sku_spec
和 fa_shop_spec
表结构设计。
CREATE TABLE `fa_shop_goods_sku_spec` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`goods_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '商品ID',
`goods_sku_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'SKU ID',
`spec_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '规格ID',
`spec_value_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '规格值ID',
`createtime` bigint(20) DEFAULT NULL COMMENT '添加时间',
`updatetime` bigint(20) DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `fa_shop_spec` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL DEFAULT '' COMMENT '名称',
`type` tinyint(4) NOT NULL DEFAULT '1' COMMENT '规格类型、 1:基础规格 2:定制规格',
`createtime` bigint(20) DEFAULT NULL COMMENT '添加时间',
`updatetime` bigint(20) DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品规格表';
用途: 获取多个SKU的规格属性字符串,用于订单显示
参数:
$sku_ids
(array): SKU ID数组返回:
array
: [sku_id => 'spec_name:spec_value,spec_name:spec_value']
格式示例:
use app\common\Service\SkuSpec;
$sku_ids = [1, 2, 3];
$attrs = SkuSpec::getSkuAttrs($sku_ids);
// 返回结果示例:
// [
// 1 => '颜色:红色,尺寸:L',
// 2 => '颜色:蓝色,尺寸:M',
// 3 => '' // 单规格商品返回空字符串
// ]
用途: 获取商品的规格分组信息
参数:
$goods_id
(int): 商品ID返回:
array
: 规格分组数据示例:
$specs = SkuSpec::getGoodsSkuSpec(1);
// 返回结果示例:
// [
// ['id' => 1, 'goods_id' => 1, 'spec_id' => 1], // 颜色规格
// ['id' => 2, 'goods_id' => 1, 'spec_id' => 2] // 尺寸规格
// ]
用途: 获取商品的完整规格组合详情
参数:
$goods_id
(int): 商品ID返回:
array
: 规格组合详情示例:
$combinations = SkuSpec::getGoodsSpecCombinations(1);
// 返回结果示例:
// [
// ['goods_id' => 1, 'spec_id' => 1, 'spec_value_id' => 1, 'spec_name' => '颜色', 'spec_value' => '红色'],
// ['goods_id' => 1, 'spec_id' => 1, 'spec_value_id' => 2, 'spec_name' => '颜色', 'spec_value' => '蓝色'],
// ['goods_id' => 1, 'spec_id' => 2, 'spec_value_id' => 3, 'spec_name' => '尺寸', 'spec_value' => 'L'],
// ['goods_id' => 1, 'spec_id' => 2, 'spec_value_id' => 4, 'spec_name' => '尺寸', 'spec_value' => 'M']
// ]
用途: 批量获取多个商品的规格统计信息
参数:
$goods_ids
(array): 商品ID数组返回:
array
: 按商品ID分组的规格信息示例:
$specs = SkuSpec::getMultiGoodsSpecs([1, 2, 3]);
// 返回结果示例:
// [
// 1 => [
// ['goods_id' => 1, 'spec_id' => 1, 'spec_name' => '颜色', 'spec_count' => 2],
// ['goods_id' => 1, 'spec_id' => 2, 'spec_name' => '尺寸', 'spec_count' => 2]
// ],
// 2 => [
// ['goods_id' => 2, 'spec_id' => 1, 'spec_name' => '颜色', 'spec_count' => 3]
// ]
// ]
用途: 根据规格值ID组合查找对应的SKU ID
参数:
$goods_id
(int): 商品ID$spec_value_ids
(array): 规格值ID数组返回:
int|null
: SKU ID 或 null示例:
$sku_id = SkuSpec::findSkuBySpecValues(1, [1, 3]); // 红色 + L尺寸
// 返回结果:
// 5 (对应的SKU ID) 或 null (未找到匹配的SKU)
用途: 获取规格的完整映射关系,包含图片等扩展信息
参数:
$spec_ids
(array): 规格ID数组返回:
array
: 规格映射数据示例:
$map = SkuSpec::getSpecNameValueMap([1, 2]);
// 返回结果示例:
// [
// 1 => [ // 颜色规格
// 1 => ['spec_name' => '颜色', 'spec_value' => '红色', 'image' => 'red.jpg', 'desc' => ''],
// 2 => ['spec_name' => '颜色', 'spec_value' => '蓝色', 'image' => 'blue.jpg', 'desc' => '']
// ],
// 2 => [ // 尺寸规格
// 3 => ['spec_name' => '尺寸', 'spec_value' => 'L', 'image' => '', 'desc' => ''],
// 4 => ['spec_name' => '尺寸', 'spec_value' => 'M', 'image' => '', 'desc' => '']
// ]
// ]
用途: 快速判断商品是否有规格
参数:
$goods_id
(int): 商品ID返回:
bool
: true=多规格,false=单规格示例:
$isMulti = SkuSpec::isMultiSpec(1);
// 返回: true 或 false
用途: 获取商品有多少种规格类型
参数:
$goods_id
(int): 商品ID返回:
int
: 规格类型数量示例:
$count = SkuSpec::getSpecCount(1);
// 返回: 2 (表示有颜色和尺寸两种规格)
// 复杂的多表JOIN查询
$skuAttrCollection = Db::name('shop_goods_sku_spec')
->alias('gss')
->field('gss.goods_sku_id, GROUP_CONCAT(sp.name,":",sv.value ORDER BY sp.id asc) as sku_attr')
->join('shop_spec sp', 'sp.id = gss.spec_id', 'LEFT')
->join('shop_spec_value sv', 'sv.id = gss.spec_value_id', 'LEFT')
->join('shop_goods_sku sku', 'sku.id = gss.goods_sku_id', 'LEFT')
->where('gss.goods_sku_id', 'in', $sku_ids)
->group('gss.goods_sku_id')
->select();
// 简洁的服务调用
$skuAttrData = \app\common\Service\SkuSpec::getSkuAttrs($sku_ids);
// 获取商品的所有规格组合
$specs = SkuSpec::getGoodsSpecCombinations($goods_id);
// 按规格分组显示
$groupedSpecs = [];
foreach ($specs as $spec) {
$groupedSpecs[$spec['spec_name']][] = $spec;
}
// 批量获取订单中所有SKU的规格属性
$sku_ids = array_column($orderGoods, 'goods_sku_id');
$skuAttrs = SkuSpec::getSkuAttrs($sku_ids);
// 在订单列表中显示规格信息
foreach ($orderGoods as &$item) {
$item['spec_attr'] = $skuAttrs[$item['goods_sku_id']] ?? '';
}
// 用户选择规格后,查找对应的SKU
$selectedSpecs = [1, 3]; // 红色 + L尺寸
$sku_id = SkuSpec::findSkuBySpecValues($goods_id, $selectedSpecs);
if ($sku_id) {
// 找到对应SKU,可以加入购物车
echo "SKU ID: " . $sku_id;
} else {
// 规格组合不存在
echo "该规格组合不存在";
}
// 批量获取多个商品的规格信息
$goods_ids = [1, 2, 3, 4, 5];
$multiSpecs = SkuSpec::getMultiGoodsSpecs($goods_ids);
// 标记哪些商品是多规格
foreach ($goodsList as &$goods) {
$goods['is_multi_spec'] = isset($multiSpecs[$goods['id']]);
$goods['spec_count'] = count($multiSpecs[$goods['id']] ?? []);
}
goods_sku_id
字段在所有相关表中保持一致