CREATE TABLE material_types ( id BIGINT NOT NULL AUTO_INCREMENT, organization_id BIGINT NOT NULL, code VARCHAR(50) NOT NULL, name VARCHAR(100) NOT NULL, status VARCHAR(20) NOT NULL DEFAULT 'active', PRIMARY KEY (id), UNIQUE KEY uk_material_types_org_code (organization_id, code), CONSTRAINT fk_material_types_org FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE RESTRICT ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE material_categories ( id BIGINT NOT NULL AUTO_INCREMENT, organization_id BIGINT NOT NULL, code VARCHAR(50) NOT NULL, name VARCHAR(100) NOT NULL, parent_id BIGINT NULL, status VARCHAR(20) NOT NULL DEFAULT 'active', PRIMARY KEY (id), UNIQUE KEY uk_material_categories_org_code (organization_id, code), CONSTRAINT fk_material_categories_org FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE RESTRICT, CONSTRAINT fk_material_categories_parent FOREIGN KEY (parent_id) REFERENCES material_categories(id) ON DELETE RESTRICT ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE units ( id BIGINT NOT NULL AUTO_INCREMENT, organization_id BIGINT NOT NULL, code VARCHAR(50) NOT NULL, name VARCHAR(100) NOT NULL, precision_scale TINYINT NOT NULL DEFAULT 0, status VARCHAR(20) NOT NULL DEFAULT 'active', PRIMARY KEY (id), UNIQUE KEY uk_units_org_code (organization_id, code), CONSTRAINT fk_units_org FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE RESTRICT ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE code_rules ( id BIGINT NOT NULL AUTO_INCREMENT, organization_id BIGINT NOT NULL, category_id BIGINT NOT NULL, prefix VARCHAR(30) NOT NULL, sequence_length TINYINT NOT NULL, next_sequence BIGINT NOT NULL DEFAULT 1, status VARCHAR(20) NOT NULL DEFAULT 'active', PRIMARY KEY (id), UNIQUE KEY uk_code_rules_org_category (organization_id, category_id), CONSTRAINT fk_code_rules_org FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE RESTRICT, CONSTRAINT fk_code_rules_category FOREIGN KEY (category_id) REFERENCES material_categories(id) ON DELETE RESTRICT ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE material_unit_conversions ( id BIGINT NOT NULL AUTO_INCREMENT, organization_id BIGINT NOT NULL, material_id BIGINT NOT NULL, from_unit_id BIGINT NOT NULL, to_unit_id BIGINT NOT NULL, conversion_rate DECIMAL(20,6) NOT NULL, effective_from DATE NOT NULL, effective_to DATE NULL, PRIMARY KEY (id), KEY idx_material_unit_conversions_material (organization_id, material_id), CONSTRAINT fk_material_unit_conversions_org FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE RESTRICT, CONSTRAINT fk_material_unit_conversions_material FOREIGN KEY (material_id) REFERENCES materials(id) ON DELETE RESTRICT, CONSTRAINT fk_material_unit_conversions_from_unit FOREIGN KEY (from_unit_id) REFERENCES units(id) ON DELETE RESTRICT, CONSTRAINT fk_material_unit_conversions_to_unit FOREIGN KEY (to_unit_id) REFERENCES units(id) ON DELETE RESTRICT ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ALTER TABLE materials ADD COLUMN organization_id BIGINT NOT NULL DEFAULT 1 AFTER id, ADD COLUMN material_type_id BIGINT NULL AFTER category, ADD COLUMN category_id BIGINT NULL AFTER material_type_id, ADD COLUMN base_unit_id BIGINT NULL AFTER unit, ADD COLUMN status VARCHAR(20) NOT NULL DEFAULT 'active' AFTER base_unit_id, ADD COLUMN version INT NOT NULL DEFAULT 1 AFTER status, ADD COLUMN manufacturer_model VARCHAR(200) NULL AFTER spec, ADD CONSTRAINT fk_materials_org FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE RESTRICT, ADD CONSTRAINT fk_materials_type FOREIGN KEY (material_type_id) REFERENCES material_types(id) ON DELETE RESTRICT, ADD CONSTRAINT fk_materials_category FOREIGN KEY (category_id) REFERENCES material_categories(id) ON DELETE RESTRICT, ADD CONSTRAINT fk_materials_base_unit FOREIGN KEY (base_unit_id) REFERENCES units(id) ON DELETE RESTRICT; ALTER TABLE materials DROP INDEX material_code; ALTER TABLE materials ADD UNIQUE KEY uk_materials_org_code (organization_id, material_code); INSERT INTO material_types (organization_id, code, name) VALUES (1, 'raw_material', '原材料'), (1, 'semi_finished', '半成品'), (1, 'finished_good', '成品'), (1, 'consumable', '耗材'), (1, 'service', '服务'); INSERT INTO material_categories (organization_id, code, name) VALUES (1, 'A01', '标准件'), (1, 'A02', '成品件'), (1, 'A03', '简易加工件'), (1, 'A04', '精密加工件'), (1, 'A05', '钣金件'), (1, 'A06', '塑胶件'), (1, 'A07', '其他'), (1, 'B01', '成品件'), (1, 'B02', '简易加工件'), (1, 'B03', 'PCB硬板'), (1, 'B04', 'FPC软板'), (1, 'B05', '线束'), (1, 'B06', '组装组件'), (1, 'B07', '其他'), (1, 'C01', '连接耗材'), (1, 'C02', '密封耗材'), (1, 'C03', '其他'), (1, 'D01', '自研程序固件'), (1, 'D02', '外购软件授权'), (1, 'D03', '授权介质'), (1, 'D04', '其他'), (1, 'E01', '成品'), (1, 'E02', '半成品'), (1, 'F01', '资料文档'), (1, 'F02', '标识标牌'), (1, 'F03', '包装物料'), (1, 'F04', '随机工具配件'), (1, 'F05', '其他'); INSERT INTO units (organization_id, code, name) SELECT 1, unit, unit FROM materials WHERE unit IS NOT NULL AND unit <> '' GROUP BY unit; UPDATE materials m LEFT JOIN material_categories c ON c.organization_id = m.organization_id AND c.code = m.category LEFT JOIN units u ON u.organization_id = m.organization_id AND u.code = m.unit SET m.category_id = c.id, m.base_unit_id = u.id;