284 lines
12 KiB
SQL
284 lines
12 KiB
SQL
-- =============================================
|
||
-- 配送效率分析 - 配送相关基础表(建表 + 升级,支持重复执行)
|
||
-- 说明:
|
||
-- - 本脚本用于测试阶段,为配送效率分析页面提供必要的表结构。
|
||
-- - 使用 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 唯一(测试阶段允许 NULL,NULL 不冲突)
|
||
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;
|