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;