Files
medical-mall/mall_sql/migrations/20260601_hss_service_package_pricing_v1.sql

116 lines
4.4 KiB
PL/PgSQL

BEGIN;
CREATE TABLE IF NOT EXISTS public.hss_service_packages (
id TEXT PRIMARY KEY,
service_id TEXT NOT NULL REFERENCES public.hss_service_catalog(id) ON DELETE RESTRICT,
package_name TEXT NOT NULL,
package_desc TEXT NOT NULL DEFAULT '',
duration_minutes INTEGER NOT NULL DEFAULT 0,
duration_text TEXT NOT NULL DEFAULT '',
price NUMERIC(10, 2) NOT NULL DEFAULT 0,
list_price NUMERIC(10, 2) NOT NULL DEFAULT 0,
is_default BOOLEAN NOT NULL DEFAULT false,
sort_no INTEGER NOT NULL DEFAULT 0,
status SMALLINT NOT NULL DEFAULT 1,
effective_at TIMESTAMPTZ,
expires_at TIMESTAMPTZ,
data_source TEXT NOT NULL DEFAULT 'manual',
seed_batch_no TEXT NOT NULL DEFAULT '',
remark TEXT NOT NULL DEFAULT '',
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
deleted_at TIMESTAMPTZ
);
CREATE INDEX IF NOT EXISTS idx_hss_service_packages_service_status_sort
ON public.hss_service_packages(service_id, status, sort_no)
WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_hss_service_packages_effective_window
ON public.hss_service_packages(effective_at, expires_at)
WHERE deleted_at IS NULL;
CREATE OR REPLACE FUNCTION public.tg_hss_service_packages_updated_at()
RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
NEW.updated_at = now();
RETURN NEW;
END;
$$;
DROP TRIGGER IF EXISTS trg_hss_service_packages_updated_at ON public.hss_service_packages;
CREATE TRIGGER trg_hss_service_packages_updated_at
BEFORE UPDATE ON public.hss_service_packages
FOR EACH ROW
EXECUTE FUNCTION public.tg_hss_service_packages_updated_at();
ALTER TABLE public.hss_service_packages ENABLE ROW LEVEL SECURITY;
DROP POLICY IF EXISTS hss_service_packages_public_select_active ON public.hss_service_packages;
CREATE POLICY hss_service_packages_public_select_active
ON public.hss_service_packages
FOR SELECT
USING (
deleted_at IS NULL
AND status = 1
AND (effective_at IS NULL OR effective_at <= now())
AND (expires_at IS NULL OR expires_at > now())
);
ALTER TABLE public.hss_service_orders
ADD COLUMN IF NOT EXISTS service_package_id TEXT REFERENCES public.hss_service_packages(id) ON DELETE SET NULL,
ADD COLUMN IF NOT EXISTS pricing_snapshot_json JSONB NOT NULL DEFAULT '{}'::jsonb,
ADD COLUMN IF NOT EXISTS original_amount NUMERIC(10, 2) NOT NULL DEFAULT 0,
ADD COLUMN IF NOT EXISTS payable_amount NUMERIC(10, 2) NOT NULL DEFAULT 0,
ADD COLUMN IF NOT EXISTS total_amount NUMERIC(10, 2) NOT NULL DEFAULT 0;
CREATE INDEX IF NOT EXISTS idx_hss_service_orders_service_package_id
ON public.hss_service_orders(service_package_id)
WHERE deleted_at IS NULL;
UPDATE public.hss_service_orders
SET
pricing_snapshot_json = CASE
WHEN pricing_snapshot_json = '{}'::jsonb THEN jsonb_build_object(
'service_id', service_id,
'service_name', service_name,
'package_id', NULL,
'package_name', service_name,
'price', COALESCE((service_snapshot_json ->> 'price')::NUMERIC, 0),
'data_source', 'legacy_service_snapshot',
'remark', '历史订单由 service_snapshot_json.price 回填'
)
ELSE pricing_snapshot_json
END,
original_amount = CASE
WHEN original_amount <= 0 THEN COALESCE((service_snapshot_json ->> 'price')::NUMERIC, 0)
ELSE original_amount
END,
payable_amount = CASE
WHEN payable_amount <= 0 THEN COALESCE((service_snapshot_json ->> 'price')::NUMERIC, 0)
ELSE payable_amount
END,
total_amount = CASE
WHEN total_amount <= 0 THEN COALESCE((service_snapshot_json ->> 'price')::NUMERIC, 0)
ELSE total_amount
END,
updated_at = now()
WHERE deleted_at IS NULL
AND (
pricing_snapshot_json = '{}'::jsonb
OR original_amount <= 0
OR payable_amount <= 0
OR total_amount <= 0
);
COMMENT ON TABLE public.hss_service_packages IS '居家服务正式套餐/报价表';
COMMENT ON COLUMN public.hss_service_packages.data_source IS 'manual/dev_seed/prod_import 等数据来源标识';
COMMENT ON COLUMN public.hss_service_packages.seed_batch_no IS '测试种子批次号,便于上线前清理';
COMMENT ON COLUMN public.hss_service_orders.service_package_id IS '下单时冻结的正式套餐 ID';
COMMENT ON COLUMN public.hss_service_orders.pricing_snapshot_json IS '订单创建时冻结的套餐/报价快照';
COMMENT ON COLUMN public.hss_service_orders.payable_amount IS '订单应付金额快照';
COMMENT ON COLUMN public.hss_service_orders.total_amount IS '服务订单总金额快照';
COMMIT;