Files
medical-mall/docs/sql/07_business_workflows.md

7.7 KiB
Raw Blame History

07 典型业务流程:落表路径与关键字段

本节用“业务步骤 → 涉及表 → 关键字段/约束/触发器”的方式,把核心链路讲清楚,方便新同事快速理解数据如何流动。


1. 商品发布与上架流程(商家侧)

1.1 创建 SPU商品主表

  • 写入表ml_products
  • 关键字段
    • merchant_id:商家用户(关联 ak_users.id
    • category_id/brand_id
    • base_price
    • status:初始可为草稿(3)或上架(1)
    • cid/slug:对外访问

示例(简化):

insert into public.ml_products(
  merchant_id, category_id, product_code, name, base_price, status
)
values (
  '...merchant_uuid...'::uuid,
  '...category_uuid...'::uuid,
  'P20260001',
  '苹果手机',
  4999.00,
  3
)
returning id, cid;

1.2 定义规格项(可选)

  • 写入表ml_product_specs
  • 关键字段spec_namespec_values JSONB

示例:

insert into public.ml_product_specs(product_id, spec_name, spec_values)
values
('...product_uuid...'::uuid, '颜色', '["黑","白"]'::jsonb),
('...product_uuid...'::uuid, '容量', '["128G","256G"]'::jsonb);

1.3 创建 SKU库存与具体价格

  • 写入表ml_product_skus
  • 关键字段specifications JSONBpricestockstatus
  • 数据库规则
    • SKU 变更会触发 update_product_stock(),自动汇总刷新 ml_products.total_stock/available_stock

示例:

insert into public.ml_product_skus(product_id, sku_code, specifications, price, stock)
values
(
  '...product_uuid...'::uuid,
  'SKU-001',
  '{"颜色":"黑","容量":"128G"}'::jsonb,
  4999.00,
  10
);

-- 插入 SKU 后,触发器会把商品 total_stock/available_stock 更新为 10

1.4 上架商品

  • 更新表ml_products
  • 关键字段status = 1published_at(若使用)

示例:

update public.ml_products
set status = 1, published_at = now()
where id = '...product_uuid...'::uuid;

2. 浏览与收藏(用户侧)

2.1 浏览记录

  • 写入表ml_browse_history
  • 约束UNIQUE(user_id, product_id)
  • 含义:倾向记录“最后一次浏览”而不是“浏览流水”。

典型写法:

  • 插入失败后转更新upsert
insert into public.ml_browse_history(user_id, product_id, browse_duration)
values ('...user_uuid...'::uuid, '...product_uuid...'::uuid, 20)
on conflict (user_id, product_id)
do update set browse_duration = excluded.browse_duration, updated_at = now();

2.2 收藏

  • 写入表ml_user_favorites
  • 约束UNIQUE(user_id, target_type, target_id)
insert into public.ml_user_favorites(user_id, target_type, target_id)
values ('...user_uuid...'::uuid, 1, '...product_uuid...'::uuid)
on conflict do nothing;

3. 加购与结算(用户侧)

3.1 加入购物车

  • 写入表ml_shopping_cart
  • 约束UNIQUE(user_id, product_id, sku_id)

常见做法:重复加购时做累加:

insert into public.ml_shopping_cart(user_id, product_id, sku_id, quantity, selected)
values ('...user_uuid...'::uuid, '...product_uuid...'::uuid, '...sku_uuid...'::uuid, 1, true)
on conflict (user_id, product_id, sku_id)
do update set quantity = public.ml_shopping_cart.quantity + 1, updated_at = now();

3.2 计算购物车金额

  • 读取函数public.calculate_cart_total(p_user_id)
select public.calculate_cart_total('...user_uuid...'::uuid);

4. 下单(创建订单 + 明细快照)

4.1 订单号生成

  • 函数public.generate_order_no()(基于 ml_order_seq
select public.generate_order_no();

4.2 创建订单主表(地址快照)

  • 写入表ml_orders
  • 关键字段
    • shipping_address JSONB:下单时把地址“快照化”写进订单
    • order_status/payment_status/shipping_status

示例(简化):

insert into public.ml_orders(
  order_no, user_id, merchant_id,
  product_amount, discount_amount, shipping_fee, total_amount,
  shipping_address,
  order_status, payment_status, shipping_status
)
values (
  public.generate_order_no(),
  '...user_uuid...'::uuid,
  '...merchant_uuid...'::uuid,
  4999.00, 0.00, 10.00, 5009.00,
  '{"receiver":"张三","phone":"138...","province":"广东","city":"深圳","district":"南山","detail":"xxx"}'::jsonb,
  1, 1, 1
)
returning id;

4.3 创建订单明细(商品快照)

  • 写入表ml_order_items
  • 关键点:把 product_name/sku_name/specifications/image_url/price 等写入明细,防止商品后改影响历史。
insert into public.ml_order_items(
  order_id, product_id, sku_id,
  product_name, sku_name, specifications, image_url,
  price, quantity, total_amount
)
values (
  '...order_uuid...'::uuid,
  '...product_uuid...'::uuid,
  '...sku_uuid...'::uuid,
  '苹果手机',
  '黑/128G',
  '{"颜色":"黑","容量":"128G"}'::jsonb,
  'https://.../1.png',
  4999.00,
  1,
  4999.00
);

注意:当前可见 SQL 未体现“扣库存/冻结库存”动作,通常需要在同一事务中由应用层或额外 DB 函数完成(详见 08_data_consistency_boundaries.md)。


5. 支付、发货、完成(状态流转)

5.1 支付完成

  • 更新表ml_orders
  • 预期order_status: 1 -> 2,并写 paid_amount/payment_status
  • 数据库副作用complete 脚本):触发器 handle_order_status_change() 自动写 paid_at
update public.ml_orders
set order_status = 2,
    payment_status = 2,
    paid_amount = total_amount
where id = '...order_uuid...'::uuid;

5.2 发货

update public.ml_orders
set order_status = 3,
    shipping_status = 2
where id = '...order_uuid...'::uuid;

-- complete 脚本的触发器会在 2->3 时写 shipped_at

5.3 收货完成

update public.ml_orders
set order_status = 4,
    shipping_status = 4
where id = '...order_uuid...'::uuid;

-- complete 脚本触发器在 3->4 时写 delivered_at/completed_at并累计商品 sale_count

6. 评价

  • 写入表ml_product_reviews
  • 约束设计:强绑定 order_idorder_item_id,保证评价来自真实订单。
insert into public.ml_product_reviews(
  order_id, order_item_id, user_id, product_id, merchant_id,
  rating, content, images
)
values (
  '...order_uuid...'::uuid,
  '...order_item_uuid...'::uuid,
  '...user_uuid...'::uuid,
  '...product_uuid...'::uuid,
  '...merchant_uuid...'::uuid,
  5,
  '很好用',
  '["https://.../a.png"]'::jsonb
);

7. 优惠券:发放与使用

7.1 领券

  • 写入表ml_user_coupons
  • 券码:可使用 generate_coupon_code() 生成
insert into public.ml_user_coupons(user_id, template_id, coupon_code, status, expire_at)
values (
  '...user_uuid...'::uuid,
  '...template_uuid...'::uuid,
  public.generate_coupon_code(),
  1,
  now() + interval '30 days'
);

7.2 用券归因

update public.ml_user_coupons
set status = 2,
    used_at = now(),
    order_id = '...order_uuid...'::uuid
where id = '...user_coupon_uuid...'::uuid
  and status = 1;

8. 订阅:开通/续费/到期

8.1 创建套餐

  • ml_subscription_plans
insert into public.ml_subscription_plans(plan_code, name, price, billing_period)
values ('PRO_MONTH', '专业版(月付)', 99.00, 'monthly');

8.2 用户订阅

  • ml_user_subscriptions
insert into public.ml_user_subscriptions(user_id, plan_id, status, start_date, next_billing_date)
values (
  '...user_uuid...'::uuid,
  '...plan_uuid...'::uuid,
  'trial',
  now(),
  now() + interval '30 days'
);

说明:订阅模块脚本未与 ml_orders 建立外键关联,支付/对账链路通常在应用层或另一个交易子系统实现。