274 lines
12 KiB
PL/PgSQL
274 lines
12 KiB
PL/PgSQL
BEGIN;
|
|
|
|
ALTER TABLE public.ml_user_addresses
|
|
ADD COLUMN IF NOT EXISTS latitude DOUBLE PRECISION,
|
|
ADD COLUMN IF NOT EXISTS longitude DOUBLE PRECISION,
|
|
ADD COLUMN IF NOT EXISTS coordinate_type TEXT NOT NULL DEFAULT 'gcj02';
|
|
|
|
CREATE TABLE IF NOT EXISTS public.hss_service_orders (
|
|
id TEXT PRIMARY KEY,
|
|
order_no TEXT NOT NULL UNIQUE,
|
|
user_id UUID NOT NULL,
|
|
service_id TEXT NOT NULL,
|
|
service_name TEXT NOT NULL,
|
|
service_snapshot_json JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
service_address_id UUID,
|
|
address_snapshot_json JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
recipient_name TEXT NOT NULL DEFAULT '',
|
|
recipient_phone TEXT NOT NULL DEFAULT '',
|
|
contact_name TEXT NOT NULL DEFAULT '',
|
|
contact_phone TEXT NOT NULL DEFAULT '',
|
|
appointment_time TIMESTAMPTZ,
|
|
remark TEXT NOT NULL DEFAULT '',
|
|
status TEXT NOT NULL DEFAULT 'created',
|
|
current_assignment_id TEXT NOT NULL DEFAULT '',
|
|
current_staff_id UUID,
|
|
accepted_at TIMESTAMPTZ,
|
|
departed_at TIMESTAMPTZ,
|
|
arrived_at TIMESTAMPTZ,
|
|
service_started_at TIMESTAMPTZ,
|
|
completed_at TIMESTAMPTZ,
|
|
pending_acceptance_at TIMESTAMPTZ,
|
|
accepted_by_user_at TIMESTAMPTZ,
|
|
reviewed_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
deleted_at TIMESTAMPTZ,
|
|
deleted_by UUID,
|
|
CONSTRAINT chk_hss_service_orders_status CHECK (
|
|
status IN (
|
|
'created', 'paid', 'assigned', 'accepted', 'rejected', 'departed', 'arrived',
|
|
'in_service', 'completed', 'pending_acceptance', 'accepted_by_user',
|
|
'reviewed', 'settled', 'cancelled', 'exception'
|
|
)
|
|
)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS public.hss_service_assignments (
|
|
id TEXT PRIMARY KEY,
|
|
order_id TEXT NOT NULL REFERENCES public.hss_service_orders(id) ON DELETE CASCADE,
|
|
staff_id UUID NOT NULL REFERENCES public.ml_delivery_staff(id) ON DELETE RESTRICT,
|
|
station_id UUID REFERENCES public.ml_delivery_stations(id) ON DELETE SET NULL,
|
|
status TEXT NOT NULL DEFAULT 'assigned',
|
|
assigned_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
accepted_at TIMESTAMPTZ,
|
|
rejected_at TIMESTAMPTZ,
|
|
reject_reason TEXT NOT NULL DEFAULT '',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
CONSTRAINT chk_hss_service_assignments_status CHECK (
|
|
status IN ('assigned', 'accepted', 'rejected', 'departed', 'arrived', 'in_service', 'pending_acceptance', 'completed', 'cancelled', 'exception')
|
|
)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS public.hss_service_execution_records (
|
|
id TEXT PRIMARY KEY,
|
|
order_id TEXT NOT NULL REFERENCES public.hss_service_orders(id) ON DELETE CASCADE,
|
|
assignment_id TEXT NOT NULL REFERENCES public.hss_service_assignments(id) ON DELETE CASCADE,
|
|
checkin_time TIMESTAMPTZ,
|
|
checkin_latitude DOUBLE PRECISION,
|
|
checkin_longitude DOUBLE PRECISION,
|
|
checkin_address TEXT NOT NULL DEFAULT '',
|
|
service_started_at TIMESTAMPTZ,
|
|
service_finished_at TIMESTAMPTZ,
|
|
actual_duration_minutes INTEGER NOT NULL DEFAULT 0,
|
|
service_items_json JSONB NOT NULL DEFAULT '[]'::jsonb,
|
|
summary TEXT NOT NULL DEFAULT '',
|
|
remark TEXT NOT NULL DEFAULT '',
|
|
track_points_json JSONB NOT NULL DEFAULT '[]'::jsonb,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS public.hss_service_evidence_files (
|
|
id TEXT PRIMARY KEY,
|
|
order_id TEXT NOT NULL REFERENCES public.hss_service_orders(id) ON DELETE CASCADE,
|
|
execution_record_id TEXT REFERENCES public.hss_service_execution_records(id) ON DELETE CASCADE,
|
|
phase TEXT NOT NULL DEFAULT 'service',
|
|
file_type TEXT NOT NULL DEFAULT 'image',
|
|
storage_path TEXT NOT NULL DEFAULT '',
|
|
file_url TEXT NOT NULL DEFAULT '',
|
|
latitude DOUBLE PRECISION,
|
|
longitude DOUBLE PRECISION,
|
|
captured_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS public.hss_service_order_status_logs (
|
|
id TEXT PRIMARY KEY,
|
|
order_id TEXT NOT NULL REFERENCES public.hss_service_orders(id) ON DELETE CASCADE,
|
|
from_status TEXT NOT NULL DEFAULT '',
|
|
to_status TEXT NOT NULL,
|
|
operator_id UUID,
|
|
operator_role TEXT NOT NULL DEFAULT '',
|
|
remark TEXT NOT NULL DEFAULT '',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS public.hss_service_reviews (
|
|
id TEXT PRIMARY KEY,
|
|
order_id TEXT NOT NULL REFERENCES public.hss_service_orders(id) ON DELETE CASCADE,
|
|
user_id UUID NOT NULL,
|
|
rating INTEGER NOT NULL DEFAULT 5,
|
|
tags_json JSONB NOT NULL DEFAULT '[]'::jsonb,
|
|
content TEXT NOT NULL DEFAULT '',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_hss_service_orders_user_status
|
|
ON public.hss_service_orders(user_id, status)
|
|
WHERE deleted_at IS NULL;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_hss_service_orders_staff_status
|
|
ON public.hss_service_orders(current_staff_id, status)
|
|
WHERE deleted_at IS NULL;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_hss_service_assignments_staff_status
|
|
ON public.hss_service_assignments(staff_id, status);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_hss_service_execution_records_order
|
|
ON public.hss_service_execution_records(order_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_hss_service_evidence_files_order
|
|
ON public.hss_service_evidence_files(order_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_hss_service_logs_order_created
|
|
ON public.hss_service_order_status_logs(order_id, created_at DESC);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_hss_service_reviews_order
|
|
ON public.hss_service_reviews(order_id);
|
|
|
|
CREATE OR REPLACE FUNCTION public.tg_hss_set_updated_at()
|
|
RETURNS trigger
|
|
LANGUAGE plpgsql
|
|
AS $$
|
|
BEGIN
|
|
NEW.updated_at = now();
|
|
RETURN NEW;
|
|
END;
|
|
$$;
|
|
|
|
DROP TRIGGER IF EXISTS trg_hss_service_orders_updated_at ON public.hss_service_orders;
|
|
CREATE TRIGGER trg_hss_service_orders_updated_at
|
|
BEFORE UPDATE ON public.hss_service_orders
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION public.tg_hss_set_updated_at();
|
|
|
|
DROP TRIGGER IF EXISTS trg_hss_service_assignments_updated_at ON public.hss_service_assignments;
|
|
CREATE TRIGGER trg_hss_service_assignments_updated_at
|
|
BEFORE UPDATE ON public.hss_service_assignments
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION public.tg_hss_set_updated_at();
|
|
|
|
DROP TRIGGER IF EXISTS trg_hss_service_execution_records_updated_at ON public.hss_service_execution_records;
|
|
CREATE TRIGGER trg_hss_service_execution_records_updated_at
|
|
BEFORE UPDATE ON public.hss_service_execution_records
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION public.tg_hss_set_updated_at();
|
|
|
|
ALTER TABLE public.hss_service_orders ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE public.hss_service_assignments ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE public.hss_service_execution_records ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE public.hss_service_evidence_files ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE public.hss_service_order_status_logs ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE public.hss_service_reviews ENABLE ROW LEVEL SECURITY;
|
|
|
|
DROP POLICY IF EXISTS hss_service_orders_user_select ON public.hss_service_orders;
|
|
CREATE POLICY hss_service_orders_user_select
|
|
ON public.hss_service_orders
|
|
FOR SELECT
|
|
TO authenticated
|
|
USING (
|
|
deleted_at IS NULL AND (
|
|
user_id IN (SELECT id FROM public.ak_users WHERE auth_id = auth.uid())
|
|
OR current_staff_id IN (SELECT id FROM public.ml_delivery_staff WHERE uid IN (SELECT id FROM public.ak_users WHERE auth_id = auth.uid()) AND deleted_at IS NULL)
|
|
)
|
|
);
|
|
|
|
DROP POLICY IF EXISTS hss_service_orders_user_insert ON public.hss_service_orders;
|
|
CREATE POLICY hss_service_orders_user_insert
|
|
ON public.hss_service_orders
|
|
FOR INSERT
|
|
TO authenticated
|
|
WITH CHECK (user_id IN (SELECT id FROM public.ak_users WHERE auth_id = auth.uid()));
|
|
|
|
DROP POLICY IF EXISTS hss_service_orders_user_update ON public.hss_service_orders;
|
|
CREATE POLICY hss_service_orders_user_update
|
|
ON public.hss_service_orders
|
|
FOR UPDATE
|
|
TO authenticated
|
|
USING (
|
|
deleted_at IS NULL AND (
|
|
user_id IN (SELECT id FROM public.ak_users WHERE auth_id = auth.uid())
|
|
OR current_staff_id IN (SELECT id FROM public.ml_delivery_staff WHERE uid IN (SELECT id FROM public.ak_users WHERE auth_id = auth.uid()) AND deleted_at IS NULL)
|
|
)
|
|
)
|
|
WITH CHECK (
|
|
deleted_at IS NULL AND (
|
|
user_id IN (SELECT id FROM public.ak_users WHERE auth_id = auth.uid())
|
|
OR current_staff_id IN (SELECT id FROM public.ml_delivery_staff WHERE uid IN (SELECT id FROM public.ak_users WHERE auth_id = auth.uid()) AND deleted_at IS NULL)
|
|
)
|
|
);
|
|
|
|
DROP POLICY IF EXISTS hss_service_assignments_staff_select ON public.hss_service_assignments;
|
|
CREATE POLICY hss_service_assignments_staff_select
|
|
ON public.hss_service_assignments
|
|
FOR SELECT
|
|
TO authenticated
|
|
USING (staff_id IN (SELECT id FROM public.ml_delivery_staff WHERE uid IN (SELECT id FROM public.ak_users WHERE auth_id = auth.uid()) AND deleted_at IS NULL));
|
|
|
|
DROP POLICY IF EXISTS hss_service_assignments_staff_update ON public.hss_service_assignments;
|
|
CREATE POLICY hss_service_assignments_staff_update
|
|
ON public.hss_service_assignments
|
|
FOR UPDATE
|
|
TO authenticated
|
|
USING (staff_id IN (SELECT id FROM public.ml_delivery_staff WHERE uid IN (SELECT id FROM public.ak_users WHERE auth_id = auth.uid()) AND deleted_at IS NULL))
|
|
WITH CHECK (staff_id IN (SELECT id FROM public.ml_delivery_staff WHERE uid IN (SELECT id FROM public.ak_users WHERE auth_id = auth.uid()) AND deleted_at IS NULL));
|
|
|
|
DROP POLICY IF EXISTS hss_service_assignments_staff_insert ON public.hss_service_assignments;
|
|
CREATE POLICY hss_service_assignments_staff_insert
|
|
ON public.hss_service_assignments
|
|
FOR INSERT
|
|
TO authenticated
|
|
WITH CHECK (staff_id IN (SELECT id FROM public.ml_delivery_staff WHERE uid IN (SELECT id FROM public.ak_users WHERE auth_id = auth.uid()) AND deleted_at IS NULL));
|
|
|
|
DROP POLICY IF EXISTS hss_service_execution_records_order_access ON public.hss_service_execution_records;
|
|
CREATE POLICY hss_service_execution_records_order_access
|
|
ON public.hss_service_execution_records
|
|
FOR ALL
|
|
TO authenticated
|
|
USING (order_id IN (SELECT id FROM public.hss_service_orders WHERE deleted_at IS NULL))
|
|
WITH CHECK (order_id IN (SELECT id FROM public.hss_service_orders WHERE deleted_at IS NULL));
|
|
|
|
DROP POLICY IF EXISTS hss_service_evidence_files_order_access ON public.hss_service_evidence_files;
|
|
CREATE POLICY hss_service_evidence_files_order_access
|
|
ON public.hss_service_evidence_files
|
|
FOR ALL
|
|
TO authenticated
|
|
USING (order_id IN (SELECT id FROM public.hss_service_orders WHERE deleted_at IS NULL))
|
|
WITH CHECK (order_id IN (SELECT id FROM public.hss_service_orders WHERE deleted_at IS NULL));
|
|
|
|
DROP POLICY IF EXISTS hss_service_order_status_logs_order_access ON public.hss_service_order_status_logs;
|
|
CREATE POLICY hss_service_order_status_logs_order_access
|
|
ON public.hss_service_order_status_logs
|
|
FOR ALL
|
|
TO authenticated
|
|
USING (order_id IN (SELECT id FROM public.hss_service_orders WHERE deleted_at IS NULL))
|
|
WITH CHECK (order_id IN (SELECT id FROM public.hss_service_orders WHERE deleted_at IS NULL));
|
|
|
|
DROP POLICY IF EXISTS hss_service_reviews_order_access ON public.hss_service_reviews;
|
|
CREATE POLICY hss_service_reviews_order_access
|
|
ON public.hss_service_reviews
|
|
FOR ALL
|
|
TO authenticated
|
|
USING (order_id IN (SELECT id FROM public.hss_service_orders WHERE deleted_at IS NULL))
|
|
WITH CHECK (order_id IN (SELECT id FROM public.hss_service_orders WHERE deleted_at IS NULL));
|
|
|
|
COMMENT ON TABLE public.hss_service_orders IS '居家上门服务订单主表';
|
|
COMMENT ON TABLE public.hss_service_assignments IS '居家上门服务派单表';
|
|
COMMENT ON TABLE public.hss_service_execution_records IS '居家上门服务执行记录表';
|
|
COMMENT ON TABLE public.hss_service_evidence_files IS '居家上门服务证据文件表';
|
|
COMMENT ON TABLE public.hss_service_order_status_logs IS '居家上门服务状态日志表';
|
|
COMMENT ON TABLE public.hss_service_reviews IS '居家上门服务评价表';
|
|
|
|
COMMIT; |