Files
medical-mall/pages/mall/analytics/test/01_create_delivery_tables.sql
2026-01-30 16:17:13 +08:00

284 lines
12 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- =============================================
-- 配送效率分析 - 配送相关基础表(建表 + 升级,支持重复执行)
-- 说明:
-- - 本脚本用于测试阶段,为配送效率分析页面提供必要的表结构。
-- - 使用 CREATE TABLE IF NOT EXISTS + DO 块判断列/约束是否存在,实现可重复执行。
-- - 外键:
-- - driver_id -> ml_delivery_drivers(id) 必须存在。
-- - user_id -> ak_users(id) 仅在 ak_users 表存在时才会创建外键(避免执行报错)。
-- =============================================
-- 1) 创建基础表(若不存在)
CREATE TABLE IF NOT EXISTS public.ml_delivery_drivers (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
real_name TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS public.ml_delivery_tasks (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- 2) 补齐字段(若不存在)
DO $$
BEGIN
-- =========================
-- ml_delivery_drivers
-- =========================
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema='public' AND table_name='ml_delivery_drivers' AND column_name='user_id'
) THEN
ALTER TABLE public.ml_delivery_drivers ADD COLUMN user_id UUID;
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema='public' AND table_name='ml_delivery_drivers' AND column_name='work_status'
) THEN
ALTER TABLE public.ml_delivery_drivers ADD COLUMN work_status INTEGER DEFAULT 1;
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema='public' AND table_name='ml_delivery_drivers' AND column_name='rating_avg'
) THEN
ALTER TABLE public.ml_delivery_drivers ADD COLUMN rating_avg NUMERIC(3,2) DEFAULT 0;
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema='public' AND table_name='ml_delivery_drivers' AND column_name='rating_count'
) THEN
ALTER TABLE public.ml_delivery_drivers ADD COLUMN rating_count INTEGER DEFAULT 0;
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema='public' AND table_name='ml_delivery_drivers' AND column_name='updated_at'
) THEN
ALTER TABLE public.ml_delivery_drivers ADD COLUMN updated_at TIMESTAMPTZ DEFAULT NOW();
END IF;
-- =========================
-- ml_delivery_tasks
-- =========================
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema='public' AND table_name='ml_delivery_tasks' AND column_name='order_id'
) THEN
ALTER TABLE public.ml_delivery_tasks ADD COLUMN order_id UUID;
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema='public' AND table_name='ml_delivery_tasks' AND column_name='driver_id'
) THEN
ALTER TABLE public.ml_delivery_tasks ADD COLUMN driver_id UUID;
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema='public' AND table_name='ml_delivery_tasks' AND column_name='status'
) THEN
ALTER TABLE public.ml_delivery_tasks ADD COLUMN status INTEGER DEFAULT 1;
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema='public' AND table_name='ml_delivery_tasks' AND column_name='assigned_at'
) THEN
ALTER TABLE public.ml_delivery_tasks ADD COLUMN assigned_at TIMESTAMPTZ;
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema='public' AND table_name='ml_delivery_tasks' AND column_name='delivered_at'
) THEN
ALTER TABLE public.ml_delivery_tasks ADD COLUMN delivered_at TIMESTAMPTZ;
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema='public' AND table_name='ml_delivery_tasks' AND column_name='delivery_fee'
) THEN
ALTER TABLE public.ml_delivery_tasks ADD COLUMN delivery_fee NUMERIC(10,2) DEFAULT 0;
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema='public' AND table_name='ml_delivery_tasks' AND column_name='updated_at'
) THEN
ALTER TABLE public.ml_delivery_tasks ADD COLUMN updated_at TIMESTAMPTZ DEFAULT NOW();
END IF;
END;
$$;
-- 3) 添加表/字段中文注释
COMMENT ON TABLE public.ml_delivery_drivers IS '配送员表';
COMMENT ON COLUMN public.ml_delivery_drivers.id IS '配送员ID';
COMMENT ON COLUMN public.ml_delivery_drivers.user_id IS '关联用户ID可选若存在 ak_users 表则可建立外键)';
COMMENT ON COLUMN public.ml_delivery_drivers.real_name IS '真实姓名';
COMMENT ON COLUMN public.ml_delivery_drivers.work_status IS '工作状态1在线 2忙碌 3离线';
COMMENT ON COLUMN public.ml_delivery_drivers.rating_avg IS '平均评分0-5';
COMMENT ON COLUMN public.ml_delivery_drivers.rating_count IS '评分次数';
COMMENT ON COLUMN public.ml_delivery_drivers.created_at IS '创建时间';
COMMENT ON COLUMN public.ml_delivery_drivers.updated_at IS '更新时间';
COMMENT ON TABLE public.ml_delivery_tasks IS '配送任务表(接单->送达)';
COMMENT ON COLUMN public.ml_delivery_tasks.id IS '任务ID';
COMMENT ON COLUMN public.ml_delivery_tasks.order_id IS '订单ID测试阶段可空正式可做 UNIQUE + 外键)';
COMMENT ON COLUMN public.ml_delivery_tasks.driver_id IS '配送员ID';
COMMENT ON COLUMN public.ml_delivery_tasks.status IS '状态1待接 2已接 3取货 4配送中 5已送达 6配送失败';
COMMENT ON COLUMN public.ml_delivery_tasks.assigned_at IS '接单时间';
COMMENT ON COLUMN public.ml_delivery_tasks.delivered_at IS '送达时间';
COMMENT ON COLUMN public.ml_delivery_tasks.delivery_fee IS '配送费';
COMMENT ON COLUMN public.ml_delivery_tasks.created_at IS '创建时间';
COMMENT ON COLUMN public.ml_delivery_tasks.updated_at IS '更新时间';
-- 4) 添加约束(幂等)
DO $$
BEGIN
-- drivers: real_name 唯一
IF NOT EXISTS (
SELECT 1 FROM pg_constraint c
JOIN pg_class t ON t.oid = c.conrelid
JOIN pg_namespace n ON n.oid = t.relnamespace
WHERE c.contype='u' AND n.nspname='public' AND t.relname='ml_delivery_drivers' AND c.conname='ml_delivery_drivers_real_name_key'
) THEN
ALTER TABLE public.ml_delivery_drivers
ADD CONSTRAINT ml_delivery_drivers_real_name_key UNIQUE (real_name);
END IF;
-- drivers: work_status 枚举
IF NOT EXISTS (
SELECT 1 FROM pg_constraint c
JOIN pg_class t ON t.oid = c.conrelid
JOIN pg_namespace n ON n.oid = t.relnamespace
WHERE c.contype='c' AND n.nspname='public' AND t.relname='ml_delivery_drivers' AND c.conname='chk_ml_delivery_drivers_work_status'
) THEN
ALTER TABLE public.ml_delivery_drivers
ADD CONSTRAINT chk_ml_delivery_drivers_work_status CHECK (work_status IN (1,2,3));
END IF;
-- drivers: rating_avg 范围
IF NOT EXISTS (
SELECT 1 FROM pg_constraint c
JOIN pg_class t ON t.oid = c.conrelid
JOIN pg_namespace n ON n.oid = t.relnamespace
WHERE c.contype='c' AND n.nspname='public' AND t.relname='ml_delivery_drivers' AND c.conname='chk_ml_delivery_drivers_rating_avg'
) THEN
ALTER TABLE public.ml_delivery_drivers
ADD CONSTRAINT chk_ml_delivery_drivers_rating_avg CHECK (rating_avg >= 0 AND rating_avg <= 5);
END IF;
-- drivers: rating_count 非负
IF NOT EXISTS (
SELECT 1 FROM pg_constraint c
JOIN pg_class t ON t.oid = c.conrelid
JOIN pg_namespace n ON n.oid = t.relnamespace
WHERE c.contype='c' AND n.nspname='public' AND t.relname='ml_delivery_drivers' AND c.conname='chk_ml_delivery_drivers_rating_count'
) THEN
ALTER TABLE public.ml_delivery_drivers
ADD CONSTRAINT chk_ml_delivery_drivers_rating_count CHECK (rating_count >= 0);
END IF;
-- tasks: status 枚举
IF NOT EXISTS (
SELECT 1 FROM pg_constraint c
JOIN pg_class t ON t.oid = c.conrelid
JOIN pg_namespace n ON n.oid = t.relnamespace
WHERE c.contype='c' AND n.nspname='public' AND t.relname='ml_delivery_tasks' AND c.conname='chk_ml_delivery_tasks_status'
) THEN
ALTER TABLE public.ml_delivery_tasks
ADD CONSTRAINT chk_ml_delivery_tasks_status CHECK (status IN (1,2,3,4,5,6));
END IF;
-- tasks: delivery_fee 非负
IF NOT EXISTS (
SELECT 1 FROM pg_constraint c
JOIN pg_class t ON t.oid = c.conrelid
JOIN pg_namespace n ON n.oid = t.relnamespace
WHERE c.contype='c' AND n.nspname='public' AND t.relname='ml_delivery_tasks' AND c.conname='chk_ml_delivery_tasks_delivery_fee'
) THEN
ALTER TABLE public.ml_delivery_tasks
ADD CONSTRAINT chk_ml_delivery_tasks_delivery_fee CHECK (delivery_fee >= 0);
END IF;
-- tasks: 时间逻辑 delivered_at >= assigned_at
IF NOT EXISTS (
SELECT 1 FROM pg_constraint c
JOIN pg_class t ON t.oid = c.conrelid
JOIN pg_namespace n ON n.oid = t.relnamespace
WHERE c.contype='c' AND n.nspname='public' AND t.relname='ml_delivery_tasks' AND c.conname='chk_ml_delivery_tasks_time_logic'
) THEN
ALTER TABLE public.ml_delivery_tasks
ADD CONSTRAINT chk_ml_delivery_tasks_time_logic CHECK (
delivered_at IS NULL OR assigned_at IS NULL OR delivered_at >= assigned_at
);
END IF;
-- tasks: driver_id 外键
IF NOT EXISTS (
SELECT 1 FROM pg_constraint c
JOIN pg_class t ON t.oid = c.conrelid
JOIN pg_namespace n ON n.oid = t.relnamespace
WHERE c.contype='f' AND n.nspname='public' AND t.relname='ml_delivery_tasks' AND c.conname='ml_delivery_tasks_driver_id_fkey'
) THEN
ALTER TABLE public.ml_delivery_tasks
ADD CONSTRAINT ml_delivery_tasks_driver_id_fkey FOREIGN KEY (driver_id)
REFERENCES public.ml_delivery_drivers(id) ON DELETE SET NULL;
END IF;
-- drivers: user_id 外键(仅当 ak_users 表存在时才创建)
IF EXISTS (
SELECT 1 FROM information_schema.tables
WHERE table_schema='public' AND table_name='ak_users'
) THEN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint c
JOIN pg_class t ON t.oid = c.conrelid
JOIN pg_namespace n ON n.oid = t.relnamespace
WHERE c.contype='f' AND n.nspname='public' AND t.relname='ml_delivery_drivers' AND c.conname='ml_delivery_drivers_user_id_fkey'
) THEN
ALTER TABLE public.ml_delivery_drivers
ADD CONSTRAINT ml_delivery_drivers_user_id_fkey FOREIGN KEY (user_id)
REFERENCES public.ak_users(id) ON DELETE SET NULL;
END IF;
END IF;
-- drivers: user_id 唯一(如果你不用 user_id可以后续删除该约束
IF NOT EXISTS (
SELECT 1 FROM pg_constraint c
JOIN pg_class t ON t.oid = c.conrelid
JOIN pg_namespace n ON n.oid = t.relnamespace
WHERE c.contype='u' AND n.nspname='public' AND t.relname='ml_delivery_drivers' AND c.conname='ml_delivery_drivers_user_id_key'
) THEN
ALTER TABLE public.ml_delivery_drivers
ADD CONSTRAINT ml_delivery_drivers_user_id_key UNIQUE (user_id);
END IF;
-- tasks: order_id 唯一(测试阶段允许 NULLNULL 不冲突)
IF NOT EXISTS (
SELECT 1 FROM pg_constraint c
JOIN pg_class t ON t.oid = c.conrelid
JOIN pg_namespace n ON n.oid = t.relnamespace
WHERE c.contype='u' AND n.nspname='public' AND t.relname='ml_delivery_tasks' AND c.conname='ml_delivery_tasks_order_id_key'
) THEN
ALTER TABLE public.ml_delivery_tasks
ADD CONSTRAINT ml_delivery_tasks_order_id_key UNIQUE (order_id);
END IF;
END;
$$;
-- 5) 索引(幂等)
CREATE INDEX IF NOT EXISTS idx_ml_delivery_drivers_work_status ON public.ml_delivery_drivers(work_status);
CREATE INDEX IF NOT EXISTS idx_ml_delivery_tasks_status ON public.ml_delivery_tasks(status);
CREATE INDEX IF NOT EXISTS idx_ml_delivery_tasks_assigned_at ON public.ml_delivery_tasks(assigned_at);
CREATE INDEX IF NOT EXISTS idx_ml_delivery_tasks_driver_id ON public.ml_delivery_tasks(driver_id);
-- 完成
SELECT 'delivery tables ensured' AS message;