跳转至

图现AI — 产品与面料体系设计(含 SQL + 前后台)

文档定位:改造增量设计。现行表结构以 product/shared/data-model.md 为准;本文描述 applicable_functionssub_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)