Files
medical-mall/mall_sql/migrations/20260609_fix_delivery_rpc_request_snapshot.sql
2026-06-10 20:20:47 +08:00

129 lines
5.5 KiB
PL/PgSQL

BEGIN;
-- =====================================================================================
-- 20260609_fix_delivery_rpc_request_snapshot.sql
-- Purpose:
-- 修复 delivery RPC 在读取 ec_care_tasks 新链工单时仅返回状态、缺少服务快照的问题。
-- 当 ec_care_tasks 自身缺少 service_name / contact / address_snapshot_json 等字段时,
-- 自动回填 ec_service_requests 中的下单快照,再交由 delivery_build_order_json 输出前端字段。
-- =====================================================================================
CREATE OR REPLACE FUNCTION public.delivery_get_care_order_json(p_order_id TEXT)
RETURNS JSONB
LANGUAGE plpgsql
STABLE
SECURITY DEFINER
SET search_path = public
AS $$
DECLARE
v_user_id UUID := public.delivery_current_user_id();
v_raw JSONB;
v_request JSONB;
v_logs JSONB := '[]'::jsonb;
v_records JSONB := '[]'::jsonb;
v_evidence JSONB := '[]'::jsonb;
v_exception JSONB;
BEGIN
IF NOT public.delivery_table_exists('ec_care_tasks') THEN
RETURN NULL;
END IF;
BEGIN
EXECUTE 'SELECT to_jsonb(t) FROM public.ec_care_tasks t WHERE t.id = $1::uuid AND ($2 IS NULL OR t.assigned_to = $2) LIMIT 1'
INTO v_raw
USING p_order_id, v_user_id;
EXCEPTION WHEN OTHERS THEN
RETURN NULL;
END;
IF v_raw IS NULL THEN
RETURN NULL;
END IF;
BEGIN
IF public.delivery_table_exists('ec_service_requests')
AND COALESCE(v_raw ->> 'request_id', '') <> '' THEN
EXECUTE 'SELECT to_jsonb(r) FROM public.ec_service_requests r WHERE r.id = $1::uuid LIMIT 1'
INTO v_request
USING (v_raw ->> 'request_id');
END IF;
EXCEPTION WHEN OTHERS THEN
v_request := NULL;
END;
IF v_request IS NOT NULL THEN
v_raw := v_raw || jsonb_strip_nulls(
jsonb_build_object(
'service_name',
COALESCE(NULLIF(v_raw ->> 'service_name', ''), NULLIF(v_request ->> 'service_name', '')),
'service_category',
COALESCE(NULLIF(v_raw ->> 'service_category', ''), NULLIF(v_request ->> 'service_category', '')),
'elder_name',
COALESCE(NULLIF(v_raw ->> 'elder_name', ''), NULLIF(v_request ->> 'elder_name', '')),
'elder_phone',
COALESCE(NULLIF(v_raw ->> 'elder_phone', ''), NULLIF(v_request ->> 'elder_phone', '')),
'contact_name',
COALESCE(NULLIF(v_raw ->> 'contact_name', ''), NULLIF(v_request ->> 'contact_name', '')),
'contact_phone',
COALESCE(NULLIF(v_raw ->> 'contact_phone', ''), NULLIF(v_request ->> 'contact_phone', '')),
'remark',
COALESCE(NULLIF(v_raw ->> 'remark', ''), NULLIF(v_request ->> 'remark', '')),
'scheduled_at',
COALESCE(NULLIF(v_raw ->> 'scheduled_at', ''), NULLIF(v_request ->> 'scheduled_at', '')),
'appointment_time',
COALESCE(NULLIF(v_raw ->> 'appointment_time', ''), NULLIF(v_request ->> 'scheduled_at', '')),
'service_snapshot_json',
COALESCE(
NULLIF(v_raw -> 'service_snapshot_json', '{}'::jsonb),
NULLIF(v_request -> 'service_snapshot_json', '{}'::jsonb),
jsonb_build_object(
'category', COALESCE(v_request ->> 'service_category', ''),
'price', 0
)
),
'address_snapshot_json',
COALESCE(
NULLIF(v_raw -> 'address_snapshot_json', '{}'::jsonb),
NULLIF(v_raw -> 'address_snapshot', '{}'::jsonb),
NULLIF(v_request -> 'address_snapshot_json', '{}'::jsonb),
NULLIF(v_request -> 'address_snapshot', '{}'::jsonb)
)
)
);
END IF;
BEGIN
IF public.delivery_table_exists('hc_work_order_events') THEN
EXECUTE 'SELECT COALESCE(jsonb_agg(to_jsonb(e) ORDER BY e.created_at DESC), ''[]''::jsonb) FROM public.hc_work_order_events e WHERE e.task_id = $1::uuid'
INTO v_logs
USING p_order_id;
END IF;
IF public.delivery_table_exists('ec_care_records') THEN
EXECUTE 'SELECT COALESCE(jsonb_agg(to_jsonb(r) ORDER BY r.created_at DESC), ''[]''::jsonb) FROM public.ec_care_records r WHERE r.task_id = $1::uuid'
INTO v_records
USING p_order_id;
END IF;
IF public.delivery_table_exists('hc_evidence_files') THEN
EXECUTE 'SELECT COALESCE(jsonb_agg(to_jsonb(f) ORDER BY f.created_at DESC), ''[]''::jsonb) FROM public.hc_evidence_files f WHERE f.task_id = $1::uuid'
INTO v_evidence
USING p_order_id;
END IF;
IF public.delivery_table_exists('hc_work_order_exceptions') THEN
EXECUTE 'SELECT to_jsonb(x) FROM public.hc_work_order_exceptions x WHERE x.task_id = $1::uuid ORDER BY x.created_at DESC LIMIT 1'
INTO v_exception
USING p_order_id;
END IF;
EXCEPTION WHEN OTHERS THEN
NULL;
END;
RETURN public.delivery_build_order_json(v_raw, v_logs, v_records, v_evidence, v_exception, 'care');
END;
$$;
REVOKE ALL ON FUNCTION public.delivery_get_care_order_json(TEXT) FROM PUBLIC;
REVOKE ALL ON FUNCTION public.delivery_get_care_order_json(TEXT) FROM anon;
GRANT EXECUTE ON FUNCTION public.delivery_get_care_order_json(TEXT) TO authenticated;
COMMIT;