feat(fulfillment): 统一中文内部 SKU 履约路由
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
-- 126_internal_sku_canonical_routing.sql
|
||||
--
|
||||
-- 履约渠道的唯一标准键是规范化后的中文内部 SKU。
|
||||
-- 平台 SKU 只能用于入口映射,不能再成为渠道判定或兜底键。
|
||||
|
||||
CREATE OR REPLACE FUNCTION canonicalize_internal_sku(p_value TEXT)
|
||||
RETURNS TEXT
|
||||
LANGUAGE SQL
|
||||
IMMUTABLE
|
||||
PARALLEL SAFE
|
||||
AS $$
|
||||
SELECT NULLIF(
|
||||
LOWER(
|
||||
REGEXP_REPLACE(
|
||||
BTRIM(NORMALIZE(COALESCE(p_value, ''), NFKC)),
|
||||
'\s+',
|
||||
'',
|
||||
'g'
|
||||
)
|
||||
),
|
||||
''
|
||||
)
|
||||
$$;
|
||||
|
||||
COMMENT ON FUNCTION canonicalize_internal_sku(TEXT) IS
|
||||
'内部 SKU 唯一规范化:NFKC、去全部空白、转小写';
|
||||
|
||||
CREATE OR REPLACE FUNCTION resolve_internal_sku(
|
||||
p_manual_sku_key TEXT,
|
||||
p_sku_name TEXT,
|
||||
p_sku_code TEXT
|
||||
) RETURNS TEXT
|
||||
LANGUAGE SQL
|
||||
IMMUTABLE
|
||||
PARALLEL SAFE
|
||||
AS $$
|
||||
SELECT COALESCE(
|
||||
CASE
|
||||
WHEN canonicalize_internal_sku(p_manual_sku_key) ~ '[一-龥]'
|
||||
THEN canonicalize_internal_sku(p_manual_sku_key)
|
||||
END,
|
||||
CASE
|
||||
WHEN canonicalize_internal_sku(p_sku_name) ~ '[一-龥]'
|
||||
THEN canonicalize_internal_sku(p_sku_name)
|
||||
END
|
||||
)
|
||||
$$;
|
||||
|
||||
COMMENT ON FUNCTION resolve_internal_sku(TEXT, TEXT, TEXT) IS
|
||||
'订单项唯一内部 SKU 解析:只接受规范化后的中文 SKU,平台 SKU 不参与兜底';
|
||||
|
||||
COMMENT ON COLUMN order_items.manual_sku_key IS
|
||||
'原始内部 SKU 匹配键(skuNick -> outSkuSn -> sku_code -> sku_name);渠道判定统一使用 resolve_internal_sku() 的中文规范值';
|
||||
|
||||
CREATE OR REPLACE FUNCTION normalize_internal_sku_channel_key()
|
||||
RETURNS TRIGGER
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
NEW.internal_sku := canonicalize_internal_sku(NEW.internal_sku);
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION normalize_manual_fulfillment_config_key()
|
||||
RETURNS TRIGGER
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
NEW.sku_key := canonicalize_internal_sku(NEW.sku_key);
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION normalize_manual_sku_registry_key()
|
||||
RETURNS TRIGGER
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
NEW.sku_key := canonicalize_internal_sku(NEW.sku_key);
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION normalize_internal_sku_mapping_keys()
|
||||
RETURNS TRIGGER
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
NEW.match_value := canonicalize_internal_sku(NEW.match_value);
|
||||
NEW.internal_sku := canonicalize_internal_sku(NEW.internal_sku);
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$;
|
||||
|
||||
DROP TRIGGER IF EXISTS trg_normalize_internal_sku_channel_key ON internal_sku_channels;
|
||||
CREATE TRIGGER trg_normalize_internal_sku_channel_key
|
||||
BEFORE INSERT OR UPDATE OF internal_sku ON internal_sku_channels
|
||||
FOR EACH ROW EXECUTE FUNCTION normalize_internal_sku_channel_key();
|
||||
|
||||
DROP TRIGGER IF EXISTS trg_normalize_manual_fulfillment_config_key ON manual_fulfillment_configs;
|
||||
CREATE TRIGGER trg_normalize_manual_fulfillment_config_key
|
||||
BEFORE INSERT OR UPDATE OF sku_key ON manual_fulfillment_configs
|
||||
FOR EACH ROW EXECUTE FUNCTION normalize_manual_fulfillment_config_key();
|
||||
|
||||
DROP TRIGGER IF EXISTS trg_normalize_manual_sku_registry_key ON manual_sku_registry;
|
||||
CREATE TRIGGER trg_normalize_manual_sku_registry_key
|
||||
BEFORE INSERT OR UPDATE OF sku_key ON manual_sku_registry
|
||||
FOR EACH ROW EXECUTE FUNCTION normalize_manual_sku_registry_key();
|
||||
|
||||
DROP TRIGGER IF EXISTS trg_normalize_internal_sku_mapping_keys ON internal_sku_mappings;
|
||||
CREATE TRIGGER trg_normalize_internal_sku_mapping_keys
|
||||
BEFORE INSERT OR UPDATE OF match_value, internal_sku ON internal_sku_mappings
|
||||
FOR EACH ROW EXECUTE FUNCTION normalize_internal_sku_mapping_keys();
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_internal_sku_channels_canonical
|
||||
ON internal_sku_channels (canonicalize_internal_sku(internal_sku), priority, channel)
|
||||
WHERE enabled = TRUE;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_manual_fulfillment_configs_canonical_sku
|
||||
ON manual_fulfillment_configs (canonicalize_internal_sku(sku_key))
|
||||
WHERE enabled = TRUE;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_internal_sku_mappings_canonical_match
|
||||
ON internal_sku_mappings (match_type, canonicalize_internal_sku(match_value))
|
||||
WHERE enabled = TRUE;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_product_catalog_canonical_name
|
||||
ON product_catalog (canonicalize_internal_sku(canonical_name))
|
||||
WHERE status = 'active';
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_order_items_pending_internal_sku
|
||||
ON order_items (resolve_internal_sku(manual_sku_key, sku_name, sku_code))
|
||||
WHERE fulfillment_status = 'pending';
|
||||
Reference in New Issue
Block a user