Files
medical-mall/pages/mall/delivery/doc/old(弃用)/db/db-data-generation.md
2026-03-17 11:06:26 +08:00

9.6 KiB
Raw Blame History

测试数据生成与验证记录

本文档记录了在本项目中为配送端页面生成并验证测试数据库数据的全过程,包含关键表结构要点、执行的幂等 SQL、遇到的问题及解决办法以及前端验证步骤便于回溯和复现。


概述

  • 目标:让配送端页面 pages/mall/delivery/index.uvue 能读取真实 DB 中的配送任务(ml_delivery_tasks)并在附近订单 / 当前任务中展示;为此需要在 DB 中创建或复用 ak_usersml_delivery_driversml_ordersml_delivery_tasks 的测试数据。
  • 环境Supabase(Postgres)。建议在 Supabase SQL Editor 中以 Role = postgres 执行 SQL 以避免 RLS/触发器引起的权限问题。

关键表与约束摘要

  • public.ak_users:项目用户表,id 为主键,auth_id 对应 auth.users.id
  • public.ml_delivery_drivers:配送员表,重要列:iduser_id (引用 ak_users.idUNIQUE NOT NULL)、real_nameid_card。注意:此表没有 phone 列(以前曾误以为存在)。
  • public.ml_orders:订单表,重要列:idorder_no(UNIQUE NOT NULL)、user_idmerchant_idshipping_address (JSONB NOT NULL)、order_status
  • public.ml_delivery_tasks:配送任务表,重要列:idorder_id (UNIQUE NOT NULL引用 ml_orders.id)、driver_id (引用 ml_delivery_drivers.id)、pickup_address/delivery_address (JSONB)、status (CHECK in (1..6))。注意:联系人信息应内嵌到地址 JSON 中(没有单独 pickup_contact 字段)。

我执行的主要步骤(已实现的幂等脚本)

  1. 查找或创建 ak_users(按 auth_id 唯一):避免重复插入,若已存在则复用其 id
  2. 查找或创建 ml_delivery_drivers(以 ak_users.iduser_id):注意去掉对不存在列的引用(例如 phone)。
  3. 插入两个测试订单(使用唯一 order_no 标识,若已存在则跳过),shipping_address 使用 JSONB 格式且包含 contact/phone/province/city/detail 等字段。
  4. 为每个订单创建对应的 ml_delivery_tasks:一个保持 status = 1(可接单,driver_id = NULL),另一个设置 status = 4 并分配上步骤创建或找到的 driver_id

下面是我实际使用的幂等 SQL已去除不存在列并兼容 schema。在 Supabase SQL Editor 中以 Role = postgres 运行整段脚本即可。

-- 替换 auth_id 为你的 auth.users.id示例值可替换
WITH
found_user AS (
  SELECT id FROM public.ak_users WHERE auth_id = 'dae9f45b-3955-43ae-992f-a3e24beaa520'
),
ins_user AS (
  INSERT INTO public.ak_users (id, auth_id, email, username, created_at)
  SELECT uuid_generate_v4(), 'dae9f45b-3955-43ae-992f-a3e24beaa520', 'test+delivery@example.com', 'test_delivery_user', NOW()
  WHERE NOT EXISTS (SELECT 1 FROM found_user)
  RETURNING id
),
user_id AS (
  SELECT id FROM ins_user
  UNION ALL
  SELECT id FROM found_user
  LIMIT 1
),

found_driver AS (
  SELECT id, user_id FROM public.ml_delivery_drivers WHERE user_id = (SELECT id FROM user_id) LIMIT 1
),
ins_driver AS (
  INSERT INTO public.ml_delivery_drivers (id, user_id, real_name, id_card, created_at)
  SELECT uuid_generate_v4(), (SELECT id FROM user_id), '张师傅', 'ID-TEST-0001', NOW()
  WHERE NOT EXISTS (SELECT 1 FROM found_driver)
  RETURNING id, user_id
),
driver_row AS (
  SELECT id, user_id FROM ins_driver
  UNION ALL
  SELECT id, user_id FROM found_driver
  LIMIT 1
),

ins_order_1 AS (
  INSERT INTO public.ml_orders (
    order_no, user_id, merchant_id,
    product_amount, shipping_fee, total_amount,
    shipping_address, created_at, updated_at
  )
  SELECT
    'TEST-DELIV-20260202-001',
    (SELECT id FROM user_id),
    (SELECT id FROM user_id),
    88.00, 12.00, 100.00,
    ('{"contact":"李小明","phone":"13800000002","province":"上海市","city":"上海市","district":"浦东新区","street":"测试路100号","detail":"5楼502室","lat":31.2000,"lng":121.5000}')::jsonb,
    NOW(), NOW()
  WHERE NOT EXISTS (SELECT 1 FROM public.ml_orders WHERE order_no = 'TEST-DELIV-20260202-001')
  RETURNING id, order_no, order_status
),
sel_order_1 AS (
  SELECT id, order_no FROM ins_order_1
  UNION ALL
  SELECT id, order_no FROM public.ml_orders WHERE order_no = 'TEST-DELIV-20260202-001'
  LIMIT 1
),

ins_task_1 AS (
  INSERT INTO public.ml_delivery_tasks (
    order_id, pickup_address, delivery_address, delivery_fee, status, created_at, updated_at
  )
  SELECT
    (SELECT id FROM sel_order_1),
    ('{"contact":"商家小二","phone":"13900000002","street":"商家路1號","city":"上海市","detail":"商家门店A"}')::jsonb,
    ('{"contact":"李小明","phone":"13800000002","street":"测试路100号","city":"上海市","detail":"5楼502室"}')::jsonb,
    12.00,
    1,
    NOW(), NOW()
  WHERE NOT EXISTS (
    SELECT 1 FROM public.ml_delivery_tasks dt WHERE dt.order_id = (SELECT id FROM sel_order_1)
  )
  RETURNING id, order_id, status, driver_id
),

ins_order_2 AS (
  INSERT INTO public.ml_orders (
    order_no, user_id, merchant_id,
    product_amount, shipping_fee, total_amount,
    shipping_address, created_at, updated_at
  )
  SELECT
    'TEST-DELIV-20260202-002',
    (SELECT id FROM user_id),
    (SELECT id FROM user_id),
    59.00, 8.00, 67.00,
    ('{"contact":"王小红","phone":"13800000003","province":"上海市","city":"上海市","district":"闵行区","street":"示例街20号","detail":"2幢101室","lat":31.1000,"lng":121.4000}')::jsonb,
    NOW(), NOW()
  WHERE NOT EXISTS (SELECT 1 FROM public.ml_orders WHERE order_no = 'TEST-DELIV-20260202-002')
  RETURNING id, order_no, order_status
),
sel_order_2 AS (
  SELECT id, order_no FROM ins_order_2
  UNION ALL
  SELECT id, order_no FROM public.ml_orders WHERE order_no = 'TEST-DELIV-20260202-002'
  LIMIT 1
),

ins_task_2 AS (
  INSERT INTO public.ml_delivery_tasks (
    order_id, driver_id, pickup_address, delivery_address,
    delivery_fee, status, assigned_at, picked_at, created_at, updated_at
  )
  SELECT
    (SELECT id FROM sel_order_2),
    (SELECT id FROM driver_row),
    ('{"contact":"商家B","phone":"13900000003","street":"商家街2號","city":"上海市","detail":"商家门店B"}')::jsonb,
    ('{"contact":"王小红","phone":"13800000003","street":"示例街20号","city":"上海市","detail":"2幢101室"}')::jsonb,
    8.00,
    4,
    NOW(), NOW(), NOW(), NOW()
  WHERE NOT EXISTS (
    SELECT 1 FROM public.ml_delivery_tasks dt WHERE dt.order_id = (SELECT id FROM sel_order_2)
  )
  RETURNING id, order_id, status, driver_id
)

SELECT
  (SELECT id FROM user_id) AS ak_user_id,
  (SELECT id FROM driver_row) AS delivery_driver_id,
  (SELECT id FROM sel_order_1) AS order1_id,
  (SELECT order_no FROM sel_order_1) AS order1_no,
  (SELECT id FROM sel_order_2) AS order2_id,
  (SELECT order_no FROM sel_order_2) AS order2_no,
  (SELECT id FROM ins_task_1) AS task1_id,
  (SELECT id FROM ins_task_2) AS task2_id;

常见错误与处理

  • 错误:列不存在(例如 address / phone / pickup_contact)。处理:核对 complete_mall_database.sql 中的表结构,确认应使用 shipping_address、并将联系人内嵌到 JSON 中。
  • 错误:插入触发 FK 或 NOT NULL 违规23503 / 23502。处理按顺序插入依赖表或使用已存在的 FK 值(例如先查找 ak_users 再插入 driver
  • 错误唯一约束冲突23505例如 ml_delivery_tasks.order_id 唯一)。处理:脚本使用 WHERE NOT EXISTSORDER_NO 检查以避免重复插入。
  • 无行返回UPDATE/SELECT 返回 “Success. No rows returned”可能因为复制 id 时包含不可见字符,或 WHERE 条件不匹配。建议先用 SELECTorder_no 查找 task再用 UPDATE ... FROM public.ml_orders WHERE order_no = '...' RETURNING ... 更新并检查返回值。

前端验证(我在 pages/mall/delivery/index.uvue 已加入日志)

  1. 刷新配送端页面(或重新打开),观察控制台日志:

    • loadDriverInfo 日志:应输出 driverInfo,例如打印 loadDriverInfo: try user_id=... res=...
    • loadCurrentTask 日志:输出查询结果 loadCurrentTask: driverId=... res=...,若 driver 有未完成任务status < 5currentTask 会被设置。
    • loadAvailableOrders 日志:输出 loadAvailableOrders: query result=...,用于验证 status = 1driver_id IS NULL 的任务是否列出。
  2. 若需要把某条 ml_delivery_tasksstatus 改为 4分配给司机可运行

UPDATE public.ml_delivery_tasks dt
SET status = 4,
    driver_id = '<DRIVER_ID>',
    assigned_at = NOW(),
    updated_at = NOW()
FROM public.ml_orders o
WHERE dt.order_id = o.id
  AND o.order_no = 'TEST-DELIV-20260202-001'
RETURNING dt.id, dt.order_id, dt.status, dt.driver_id, dt.assigned_at, dt.updated_at;

执行后刷新前端并贴回 loadCurrentTask / loadAvailableOrders 的日志,以便确认页面行为。


附:运行建议与注意事项

  • 优先在 Supabase SQL Editor 中以 Role = postgres 执行插入与更新脚本,能避免 RLS 导致的“无行返回”。
  • 若需要创建 ml_order_items,需先确保 ml_products 存在或用最小 mock 产品插入,否则会触发 FK 约束错误。为减少依赖,我先仅创建 ml_ordersml_delivery_tasks
  • 保持 order_no 的唯一性(测试用的 order_no 推荐加时间戳或前缀 TEST-)。

如需我把脚本扩展为同时创建 ml_products / ml_order_items(以便测试完整订单页),或希望我直接在 repo 中加入一个可执行的 SQL 脚本文件,请回复我想要的范围,我来补充。


作者:自动化助手(配合用户执行并记录) 日期2026-02-02