图现AI — 产品与面料体系设计(含 SQL + 前后台)¶
文档定位:改造增量设计。现行表结构以 product/shared/data-model.md 为准;本文描述
applicable_functions、sub_type_fabric_materials等改造提案。
一、改了什么¶
| 改动 | 说明 |
|---|---|
product_sub_types 新增字段 |
applicable_functions JSON — 控制该子类在哪些功能页出现 |
| 新增关联表 | sub_type_fabric_materials — 产品子类 ↔ 面料材质 多对多 |
| 后台编辑子类弹窗 | 新增「适用功能」勾选 +「适用面料」勾选区 |
| 前端获取子类接口 | 加 ?function= 参数,按功能过滤品类 |
| 虚拟影棚流程 | 不出现面料选择环节 |
| 主图/详情图流程 | 选完子类后必须选面料材质 |
二、SQL¶
-- ============================================================
-- 1. 产品大类
-- ============================================================
CREATE TABLE product_categories (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
slug VARCHAR(50) NOT NULL UNIQUE,
icon_url VARCHAR(500) NULL,
description VARCHAR(200) NULL,
sort_order INT NOT NULL DEFAULT 0,
has_composition TINYINT NOT NULL DEFAULT 0 COMMENT '0=否 1=是',
has_scene TINYINT NOT NULL DEFAULT 0 COMMENT '0=否 1=是',
has_model TINYINT NOT NULL DEFAULT 0 COMMENT '0=否 1=是',
status TINYINT NOT NULL DEFAULT 1 COMMENT '0=停用 1=启用',
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
INDEX idx_sort (sort_order),
INDEX idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO product_categories (id, name, slug, sort_order, has_composition, has_scene, has_model) VALUES
(1, '床品套件', 'bedding-set', 1, 1, 1, 1),
(2, '单件', 'single-piece', 2, 1, 1, 1),
(3, '被子被芯', 'quilt', 3, 1, 1, 1),
(4, '枕芯枕头', 'pillow', 4, 1, 1, 1),
(5, '床垫床褥', 'mattress', 5, 1, 1, 1),
(6, '毯类盖毯', 'blanket', 6, 1, 1, 1),
(7, '夏凉用品', 'summer', 7, 1, 1, 1),
(8, '家居布艺', 'fabric-home', 8, 1, 1, 0),
(9, '家居服饰', 'apparel', 9, 1, 1, 1);
-- ============================================================
-- 2. 产品子类(🆕 新增 applicable_functions 字段)
-- ============================================================
CREATE TABLE product_sub_types (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
category_id BIGINT UNSIGNED NOT NULL,
name VARCHAR(100) NOT NULL,
slug VARCHAR(100) NOT NULL UNIQUE,
description VARCHAR(200) NULL,
sort_order INT NOT NULL DEFAULT 0,
has_composition TINYINT NOT NULL DEFAULT 0,
has_scene TINYINT NOT NULL DEFAULT 0,
has_model TINYINT NOT NULL DEFAULT 0,
applicable_functions JSON NULL COMMENT '🆕 适用功能,如["virtual_studio","main_image","detail_image"]',
status TINYINT NOT NULL DEFAULT 1,
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
INDEX idx_category (category_id),
INDEX idx_sort (sort_order),
FOREIGN KEY (category_id) REFERENCES product_categories(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 种子数据:注意 different functions 的品类不同
INSERT INTO product_sub_types (id, category_id, name, slug, sort_order, applicable_functions) VALUES
-- ===== 床品套件 =====
-- 虚拟影棚用(粗粒度)
(1, 1, '四件套', 'four-piece-set', 1, '["virtual_studio","main_image","detail_image"]'),
(2, 1, '三件套', 'three-piece-set', 2, '["virtual_studio"]'),
(3, 1, '六件套+多件套', 'multi-piece-set', 3, '["virtual_studio"]'),
(4, 1, '学生套件', 'student-set', 4, '["virtual_studio"]'),
-- 主图/详情图用(细粒度,按单品分)
(5, 1, '套件', 'set', 5, '["main_image","detail_image"]'),
(6, 1, '被套', 'duvet-cover', 6, '["main_image","detail_image"]'),
(7, 1, '床单', 'bed-sheet', 7, '["main_image","detail_image"]'),
(8, 1, '枕套', 'pillowcase', 8, '["main_image","detail_image"]'),
(9, 1, '床笠', 'fitted-sheet', 9, '["main_image","detail_image"]'),
(10, 1, '床裙', 'bed-skirt', 10,'["main_image","detail_image"]'),
(11, 1, '睡袋', 'sleeping-bag', 11,'["main_image","detail_image"]'),
-- ===== 单件(虚拟影棚用) =====
(12, 2, '床单', 'single-bed-sheet', 1, '["virtual_studio"]'),
(13, 2, '被套', 'single-duvet-cover',2, '["virtual_studio"]'),
(14, 2, '睡袋', 'single-sleeping-bag',3,'["virtual_studio"]'),
(15, 2, '床笠', 'single-fitted-sheet',4,'["virtual_studio"]'),
(16, 2, '枕套', 'single-pillowcase', 5, '["virtual_studio"]'),
(17, 2, '床裙', 'single-bed-skirt', 6, '["virtual_studio"]'),
-- ===== 被子被芯 =====
(18, 3, '春秋被', 'spring-autumn-quilt',1, '["virtual_studio","main_image","detail_image"]'),
(19, 3, '夏被', 'summer-quilt', 2, '["virtual_studio","main_image","detail_image"]'),
(20, 3, '冬被', 'winter-quilt', 3, '["virtual_studio","main_image","detail_image"]'),
(21, 3, '子母被', 'mother-child-quilt',4, '["virtual_studio"]'),
-- ===== 枕芯枕头 =====
(22, 4, '纤维枕', 'fiber-pillow', 1, '["virtual_studio","main_image","detail_image"]'),
(23, 4, '乳胶枕', 'latex-pillow', 2, '["virtual_studio","main_image","detail_image"]'),
(24, 4, '记忆枕', 'memory-pillow', 3, '["virtual_studio","main_image","detail_image"]'),
(25, 4, '保健枕', 'health-pillow', 4, '["virtual_studio","main_image","detail_image"]'),
(26, 4, '功能枕', 'functional-pillow', 5, '["virtual_studio","main_image","detail_image"]'),
(27, 4, '抱枕靠垫芯', 'cushion-core', 6, '["virtual_studio","main_image","detail_image"]'),
(28, 4, '羽绒枕', 'down-pillow', 7, '["virtual_studio","main_image","detail_image"]'),
(29, 4, 'U型枕', 'u-shaped-pillow', 8, '["virtual_studio"]'),
(30, 4, '双人枕', 'double-pillow', 9, '["virtual_studio"]'),
-- ===== 床垫床褥 =====
(31, 5, '乳胶垫', 'latex-mattress', 1, '["virtual_studio"]'),
(32, 5, '记忆棉垫', 'memory-foam-mattress',2,'["virtual_studio"]'),
(33, 5, '棕垫', 'coconut-mattress', 3, '["virtual_studio"]'),
(34, 5, '弹簧垫', 'spring-mattress', 4, '["virtual_studio"]'),
(35, 5, '复合垫', 'hybrid-mattress', 5, '["virtual_studio"]'),
-- 主图/详情图用
(36, 5, '床垫', 'mattress-main', 6, '["main_image","detail_image"]'),
(37, 5, '床褥', 'mattress-pad', 7, '["main_image","detail_image"]'),
-- ===== 毯类盖毯 =====
(38, 6, '纯棉毯', 'cotton-blanket', 1, '["virtual_studio","main_image","detail_image"]'),
(39, 6, '针织毯', 'knitted-blanket', 2, '["virtual_studio","main_image","detail_image"]'),
(40, 6, '珊瑚绒毯', 'coral-fleece-blanket',3,'["virtual_studio","main_image","detail_image"]'),
(41, 6, '法莱绒毯', 'flannel-blanket', 4, '["virtual_studio","main_image","detail_image"]'),
(42, 6, '羊羔绒毯', 'lamb-wool-blanket', 5, '["virtual_studio","main_image","detail_image"]'),
(43, 6, '拉舍尔毯', 'raschel-blanket', 6, '["virtual_studio","main_image","detail_image"]'),
(44, 6, '婴儿毯', 'baby-blanket', 7, '["virtual_studio","main_image","detail_image"]'),
(45, 6, '电热毯', 'electric-blanket', 8, '["virtual_studio"]'),
(46, 6, '地毯', 'carpet', 9, '["virtual_studio"]'),
(47, 6, '地垫', 'floor-mat', 10,'["virtual_studio"]'),
-- ===== 夏凉用品 =====
(48, 7, '竹席', 'bamboo-mat', 1, '["virtual_studio","main_image","detail_image"]'),
(49, 7, '藤席', 'rattan-mat', 2, '["virtual_studio","main_image","detail_image"]'),
(50, 7, '牛皮席', 'leather-mat', 3, '["virtual_studio","main_image","detail_image"]'),
(51, 7, '亚麻席', 'linen-mat', 4, '["virtual_studio","main_image","detail_image"]'),
(52, 7, '乳胶凉席', 'latex-cool-mat', 5, '["virtual_studio","main_image","detail_image"]'),
(53, 7, '冰丝席', 'ice-silk-mat', 6, '["virtual_studio","main_image","detail_image"]'),
(54, 7, '天丝软席', 'tencel-soft-mat', 7, '["virtual_studio","main_image","detail_image"]'),
(55, 7, '蒙古包蚊帐', 'yurt-mosquito-net', 8, '["virtual_studio","main_image","detail_image"]'),
(56, 7, '宫廷蚊帐', 'palace-mosquito-net',9,'["virtual_studio","main_image","detail_image"]'),
(57, 7, '导轨蚊帐', 'rail-mosquito-net', 10,'["virtual_studio","main_image","detail_image"]'),
(58, 7, '免安装蚊帐', 'no-install-net', 11,'["virtual_studio","main_image","detail_image"]'),
(59, 7, '落地式蚊帐', 'floor-net', 12,'["virtual_studio","main_image","detail_image"]'),
-- ===== 家居布艺 =====
(60, 8, '窗帘', 'curtain', 1, '["virtual_studio"]'),
(61, 8, '门帘', 'door-curtain', 2, '["virtual_studio"]'),
(62, 8, '百叶帘', 'blinds', 3, '["virtual_studio"]'),
(63, 8, '卷帘', 'roller-blind', 4, '["virtual_studio"]'),
(64, 8, '靠垫', 'cushion', 5, '["virtual_studio"]'),
(65, 8, '抱枕', 'throw-pillow', 6, '["virtual_studio"]'),
(66, 8, '坐垫', 'seat-cushion', 7, '["virtual_studio"]'),
(67, 8, '蒲团', 'floor-cushion', 8, '["virtual_studio"]'),
(68, 8, '沙发套', 'sofa-cover', 9, '["virtual_studio"]'),
(69, 8, '床头套', 'headboard-cover', 10,'["virtual_studio"]'),
(70, 8, '美容床罩', 'beauty-bed-cover', 11,'["virtual_studio"]'),
(71, 8, '防尘罩', 'dust-cover', 12,'["virtual_studio"]'),
(72, 8, '餐垫', 'placemat', 13,'["virtual_studio"]'),
(73, 8, '桌旗', 'table-runner', 14,'["virtual_studio"]'),
(74, 8, '餐桌布', 'tablecloth', 15,'["virtual_studio"]'),
-- 主图/详情图用
(75, 8, '窗/门帘', 'window-door-fabric',16,'["main_image","detail_image"]'),
(76, 8, '坐具布艺', 'seating-fabric', 17,'["main_image","detail_image"]'),
(77, 8, '防护/遮盖', 'protective-cover', 18,'["main_image","detail_image"]'),
(78, 8, '桌布桌旗', 'table-fabric', 19,'["main_image","detail_image"]'),
-- ===== 家居服饰 =====
(79, 9, '家居服睡衣', 'homewear-pajamas', 1, '["virtual_studio","main_image","detail_image"]'),
(80, 9, '毛巾', 'towel', 2, '["virtual_studio","main_image","detail_image"]'),
(81, 9, '浴巾', 'bath-towel', 3, '["virtual_studio","main_image","detail_image"]'),
(82, 9, '浴袍', 'bathrobe', 4, '["virtual_studio","main_image","detail_image"]'),
(83, 9, '拖鞋', 'slippers', 5, '["virtual_studio","main_image","detail_image"]');
-- ============================================================
-- 3. 面料大类
-- ============================================================
CREATE TABLE fabric_types (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
slug VARCHAR(50) NOT NULL UNIQUE,
sort_order INT NOT NULL DEFAULT 0,
status TINYINT NOT NULL DEFAULT 1,
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO fabric_types (id, name, slug, sort_order) VALUES
(1, '全棉系', 'cotton', 1),
(2, '高支系', 'high-thread-count', 2),
(3, '高端系', 'premium', 3),
(4, '磨毛系', 'brushed', 4),
(5, '绒类系', 'fleece', 5),
(6, '提花系', 'jacquard', 6);
-- ============================================================
-- 4. 面料材质
-- ============================================================
CREATE TABLE fabric_materials (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
fabric_type_id BIGINT UNSIGNED NOT NULL,
name VARCHAR(50) NOT NULL,
slug VARCHAR(50) NOT NULL UNIQUE,
sort_order INT NOT NULL DEFAULT 0,
status TINYINT NOT NULL DEFAULT 1,
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
INDEX idx_fabric_type (fabric_type_id),
FOREIGN KEY (fabric_type_id) REFERENCES fabric_types(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO fabric_materials (id, fabric_type_id, name, slug, sort_order) VALUES
-- 全棉系
(1, 1, '纯棉', 'pure-cotton', 1),
(2, 1, '长绒棉', 'long-staple-cotton', 2),
(3, 1, '针织棉', 'knitted-cotton', 3),
(4, 1, '水洗棉', 'washed-cotton', 4),
(5, 1, '双层纱', 'double-layer-gauze', 5),
-- 高支系
(6, 2, '天丝', 'tencel', 1),
(7, 2, '贡缎', 'sateen', 2),
(8, 2, '天丝棉', 'tencel-cotton', 3),
(9, 2, '莱赛尔', 'lyocell', 4),
(10, 2, '莫代尔', 'modal', 5),
-- 高端系
(11, 3, '蚕丝', 'silk', 1),
(12, 3, '真丝', 'pure-silk', 2),
-- 磨毛系
(13, 4, '普通磨毛', 'regular-brushed', 1),
(14, 4, '水洗棉磨毛', 'washed-cotton-brushed', 2),
-- 绒类系
(15, 5, '牛奶绒', 'milk-velvet', 1),
(16, 5, '珊瑚绒', 'coral-fleece', 2),
(17, 5, '法莱绒', 'flannel', 3),
(18, 5, '羊羔绒', 'lamb-wool', 4),
(19, 5, '兔毛绒', 'rabbit-fur', 5),
(20, 5, '宝宝绒', 'baby-fleece', 6),
-- 提花系
(21, 6, '提花', 'jacquard-weave', 1),
(22, 6, '绣花刺绣', 'embroidery', 2),
(23, 6, '蕾丝花边', 'lace', 3);
-- ============================================================
-- 5. 🆕 产品子类 ↔ 面料材质 关联表
-- ============================================================
CREATE TABLE sub_type_fabric_materials (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
sub_type_id BIGINT UNSIGNED NOT NULL,
fabric_material_id BIGINT UNSIGNED NOT NULL,
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
UNIQUE INDEX uk_sub_fabric (sub_type_id, fabric_material_id),
INDEX idx_sub_type (sub_type_id),
INDEX idx_fabric_material (fabric_material_id),
FOREIGN KEY (sub_type_id) REFERENCES product_sub_types(id) ON DELETE CASCADE,
FOREIGN KEY (fabric_material_id) REFERENCES fabric_materials(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- ===== 床品套件下的主图/详情图品类 =====
-- 套件(id=5): 22种(不含蕾丝花边)
INSERT INTO sub_type_fabric_materials (sub_type_id, fabric_material_id)
SELECT 5, id FROM fabric_materials WHERE id NOT IN (23);
-- 被套(id=6): 23种(含蕾丝花边)
INSERT INTO sub_type_fabric_materials (sub_type_id, fabric_material_id)
SELECT 6, id FROM fabric_materials;
-- 床单(id=7): 23种
INSERT INTO sub_type_fabric_materials (sub_type_id, fabric_material_id)
SELECT 7, id FROM fabric_materials;
-- 枕套(id=8): 23种
INSERT INTO sub_type_fabric_materials (sub_type_id, fabric_material_id)
SELECT 8, id FROM fabric_materials;
-- 床笠(id=9): 22种
INSERT INTO sub_type_fabric_materials (sub_type_id, fabric_material_id)
SELECT 9, id FROM fabric_materials WHERE id NOT IN (23);
-- 床裙(id=10): 22种
INSERT INTO sub_type_fabric_materials (sub_type_id, fabric_material_id)
SELECT 10, id FROM fabric_materials WHERE id NOT IN (23);
-- 睡袋(id=11): 22种
INSERT INTO sub_type_fabric_materials (sub_type_id, fabric_material_id)
SELECT 11, id FROM fabric_materials WHERE id NOT IN (23);
-- 四件套(id=1): 22种(虚拟影棚也可以用面料做说明)
INSERT INTO sub_type_fabric_materials (sub_type_id, fabric_material_id)
SELECT 1, id FROM fabric_materials WHERE id NOT IN (23);
-- ===== 被子被芯(主图/详情图) =====
-- 需要先在 fabric_materials 中补充被子填充材质
INSERT INTO fabric_materials (id, fabric_type_id, name, slug, sort_order) VALUES
(24, 1, '棉花被', 'cotton-quilt', 6),
(25, 1, '大豆被', 'soybean-quilt', 7),
(26, 1, '蚕丝被', 'silk-quilt', 8),
(27, 1, '羽绒被', 'down-quilt', 9),
(28, 1, '羊毛被', 'wool-quilt', 10),
(29, 1, '化纤被', 'chemical-fiber-quilt',11),
(30, 1, '毛巾被', 'towel-quilt', 12);
-- 春秋被(id=18): 6种
INSERT INTO sub_type_fabric_materials (sub_type_id, fabric_material_id) VALUES
(18,24),(18,25),(18,26),(18,27),(18,28),(18,29);
-- 冬被(id=20): 6种
INSERT INTO sub_type_fabric_materials (sub_type_id, fabric_material_id) VALUES
(20,24),(20,25),(20,26),(20,27),(20,28),(20,29);
-- 夏被(id=19): 5种(不含羊毛被)
INSERT INTO sub_type_fabric_materials (sub_type_id, fabric_material_id) VALUES
(19,24),(19,25),(19,26),(19,29),(19,30);
-- ===== 床垫床褥(主图/详情图)=====
-- 需补充填充材质
INSERT INTO fabric_materials (id, fabric_type_id, name, slug, sort_order) VALUES
(31, 1, '夹棉', 'cotton-padded', 13),
(32, 1, '羽绒填充', 'down-filled', 14),
(33, 1, '绒类填充', 'fleece-filled', 15);
-- 床垫(id=36): 乳胶/记忆棉/棕垫/弹簧/复合
-- 床褥(id=37): 夹棉/羽绒/绒类
INSERT INTO sub_type_fabric_materials (sub_type_id, fabric_material_id) VALUES
(37,31),(37,32),(37,33);
-- ===== 家居服饰(主图/详情图)=====
-- 家居服睡衣(id=79): 夏款(真丝/莫代尔/双层纱) + 秋冬(珊瑚绒/法兰绒/羊羔绒)
INSERT INTO sub_type_fabric_materials (sub_type_id, fabric_material_id) VALUES
(79,12),(79,10),(79,5),(79,16),(79,17),(79,18);
-- 浴袍(id=82): 珊瑚绒/法兰绒/羊羔绒/全棉/缎面
INSERT INTO sub_type_fabric_materials (sub_type_id, fabric_material_id) VALUES
(82,16),(82,17),(82,18),(82,1),(82,7);
-- 拖鞋(id=83): 绒类/全棉/浴室
INSERT INTO sub_type_fabric_materials (sub_type_id, fabric_material_id) VALUES
(83,16),(83,1);
三、后台设计¶
编辑子类弹窗(完整结构)¶
┌─ 编辑子类 ──────────────────────────────────────────────┐
│ │
│ 名称: [套件] 所属大类: [床品套件 ▼] │
│ │
│ ── 适用功能 ─────────────────────────────────────────── │
│ ☑ 虚拟影棚 ☑ 主图生成 ☑ 详情图生成 │
│ │
│ ── 适用面料材质 ─────────────────────────────────────── │
│ (仅当勾选了「主图生成」或「详情图生成」时才显示) │
│ │
│ [全选] [全不选] │
│ │
│ ▼ 全棉系 │
│ ☑纯棉 ☑长绒棉 ☑针织棉 ☑水洗棉 ☑双层纱 │
│ ▼ 高支系 │
│ ☑天丝 ☑贡缎 ☑天丝棉 ☑莱赛尔 ☑莫代尔 │
│ ▼ 高端系 │
│ ☑蚕丝 ☑真丝 │
│ ▼ 磨毛系 │
│ ☑普通磨毛 ☑水洗棉磨毛 │
│ ▼ 绒类系 │
│ ☑牛奶绒 ☑珊瑚绒 ☑法莱绒 ☑羊羔绒 ☑兔毛绒 ☑宝宝绒│
│ ▼ 提花系 │
│ ☑提花 ☑绣花刺绣 □蕾丝花边 │
│ │
│ [保存] │
└──────────────────────────────────────────────────────────┘
保存逻辑:
def update_sub_type(sub_type_id, data):
# 1. 更新基本信息 + applicable_functions
sub_type = repo.update(sub_type_id, data)
# 2. 面料关联
repo.execute("DELETE FROM sub_type_fabric_materials WHERE sub_type_id=?", sub_type_id)
if "main_image" in data.applicable_functions or "detail_image" in data.applicable_functions:
if data.fabric_material_ids:
for fm_id in data.fabric_material_ids:
repo.execute("INSERT INTO sub_type_fabric_materials (sub_type_id, fabric_material_id) VALUES (?,?)",
sub_type_id, fm_id)
四、前端设计¶
虚拟影棚(无面料环节)¶
用户选品类:
┌────────────────────────────┐
│ 产品类型 │
│ [床品套件 ▼] [四件套 ▼] │ ← 只显示 applicable_functions 含 "virtual_studio" 的
└────────────────────────────┘
选完直接出构图/场景/模特,没有面料选择。
请求:
GET /api/sub-types?function=virtual_studio&category_id=1
返回: [四件套, 三件套, 六件套+多件套, 学生套件]
主图生成(有面料环节)¶
Step 1 — 选品类:
┌────────────────────────────┐
│ 产品类型 │
│ [床品套件 ▼] [套件 ▼] │ ← 只显示 applicable_functions 含 "main_image" 的
└────────────────────────────┘
Step 2 — 选完「套件」→ 自动出现面料区:
┌────────────────────────────┐
│ 选择面料 │
│ │
│ [全棉 ▼] │
│ [纯棉] [长绒棉] [针织棉] │
│ [水洗棉] [双层纱] │
│ [高支 ▼] │
│ [天丝] [贡缎] [天丝棉] │
│ [莱赛尔] [莫代尔] │
│ [绒类 ▼] │
│ [牛奶绒] [珊瑚绒] [法莱绒] │
│ ... │
│ ● 选中「天丝」 │
└────────────────────────────┘
Step 3 — 选完面料 → 模板自动过滤:
只显示 product_sub_type_ids 含「套件」AND fabric_material_ids 含「天丝」的模板
请求:
GET /api/sub-types?function=main_image&category_id=1
返回: [套件, 被套, 床单, 枕套, 床笠, 床裙, 睡袋]
GET /api/sub-types/5/fabric-materials ← 套件 id=5
返回: {
"全棉系": ["纯棉","长绒棉","针织棉","水洗棉","双层纱"],
"高支系": ["天丝","贡缎","天丝棉","莱赛尔","莫代尔"],
...
}
被子品类的主图生成(面料完全不同)¶
Step 1:
[被子被芯 ▼] [春秋被 ▼]
Step 2 — 面料区变成被子填充材质,不是床品面料:
┌────────────────────────────┐
│ 选择面料 │
│ [棉花被] [大豆被] [蚕丝被] │
│ [羽绒被] [羊毛被] [化纤被] │
│ ● 选中「蚕丝被」 │
└────────────────────────────┘
为什么不同: 因为 sub_type_fabric_materials 里春秋被(id=18)只关联了 24-29 号材质(棉花被/大豆被...),不关联 1-23 号。
五、接口汇总¶
| Method | Path | 说明 |
|---|---|---|
| GET | /api/sub-types?function=virtual_studio&category_id=1 | 虚拟影棚用的子类列表 |
| GET | /api/sub-types?function=main_image&category_id=1 | 主图生成用的子类列表 |
| GET | /api/sub-types/:id/fabric-materials | 该子类关联的面料材质 |
| PUT | /admin/sub-types/:id | 编辑子类(含 applicable_functions + fabric_material_ids) |