# “一客一价” (客户专属单品折扣) 改造设计方案

## 1. 背景与业务痛点
* **当前系统瓶颈**：目前系统仅支持“全局统一折扣”或“商品级统一折扣”。也就是说，如果给商品 A 设置了 8 折，那么所有 VIP 卡客户买商品 A 都是 8 折。
* **新业务需求**：为了精细化管理客户（尤其是 B2B 批发客户或核心大客户），需要实现**客户维度与商品维度的交叉定价**。例如：核心客户张三由于拿货量大，商品 A 给他 7.5 折；而普通客户李四拿货少，商品 A 只能给他 9 折；同时，张三买商品 B 可能利润薄，这件只给 95 折。
* **业务目标**：打造千人千面的私有价格体系（一客一价），增强熟客黏性。

---

## 2. 数据库设计 (Database Schema)

由于需求属于“多对多”（多客户对应多商品，各有独立折扣价），必须引入一张新的映射关联表。

### 新增关联表：`ml_user_product_discounts`
我们需要在 Supabase 中创建这张记录专属折扣的桥接表。

```sql
CREATE TABLE ml_user_product_discounts (
    id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
    user_id UUID NOT NULL,          -- 关联：客户(买家) ID
    product_id UUID NOT NULL,       -- 关联：商品 ID
    discount_rate NUMERIC NOT NULL, -- 该客户买该商品的专属折扣率 (例如 0.75)
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    UNIQUE(user_id, product_id)     -- 核心约束：保证同个客户对同个商品只有一条有效规则
);

-- 出于性能考虑，建议在 `user_id` 和 `product_id` 上添加索引，方便检索某个用户购物车里商品的价格。
CREATE INDEX idx_user_discount_user ON ml_user_product_discounts(user_id);
```

*(附注：该表的数据由**商家端**维护分配，**买家端**在此表面前仅为“只读查询”角色。)*

---

## 3. 商家端 (Merchant App) 功能拆解

系统需要提供给商家的管理入口从“发商品时”转移到“管客户时”。

### 3.1 【客户分析/管理】入口
* 若当前缺少直接管理消费者的模块，需先建设一个简单的【客户列表页】，加载已在平台注册/下单过的用户。
* 点击具体用户，进入【客户详情管理页】。

### 3.2 专属商品折扣分配功能
* **功能入口**：在【客户详情页】底部增加按钮或标签卡——「配置专属折扣商品」。
* **交互流程**：
  1. 商家调出平台的全量商品列表面板（可能带有搜索与分类）。
  2. 商家勾选指定的若干个商品，将它们加入到此客户的“专属打折清单”中。
  3. 出现在专属清单中的每一个商品，商家可通过步进器或输入框单独设置对于该客户的**专属折扣率**。
  4. 提交保存后，数据 `UPSERT` 存入 `ml_user_product_discounts` 表。
  5. 商家也可以随时将某个商品从该客户的专属清单中踢出（删除记录）。

### 3.3 系统融合建议
* 如果商家发现给每个特定商品设价格太累，仍可以保留“商品通用VIP折扣”作为保底。

---

## 4. 消费者端 (Consumer App) 核心计价降级逻辑 (重要!)

在价格体系变得复杂后，**消费者渲染的价格、加入购物车的价格、结算付款时的价格**，这三端必须遵循绝对严格的“逐层降级（Fallback）”查询机制。

**价格优先级链条设定如下（权重由高到低）：**

* **👑 T0 级别（最高）：一客一价** 
  - 前端去查当前商品是否在 `ml_user_product_discounts` 里有当前用户的专属记录。如果有，以此为准。（如：张三专属 75 折）
* **🥇 T1 级别：单品通用 VIP 折扣**
  - 如果 T0 没有，接着查 `ml_products` 中该商品的 `is_vip_discount` 是否为 true 且配置了 `vip_discount_rate`。如果有，以此为准。（如：全民VIP买此衣服 8 折）
* **🥈 T2 级别：全站全局 VIP 折扣**
  - 如果 T1 也没有，接着查询该用户绑定等级的全局默认折扣（如：白银会员全场 95 折，如果在历史版本中还在生效的话）。
* **🥉 T3 级别（底线）：原价销售**
  - 兜底机制，以原先的 `base_price`（销售商品原价）售卖。

### 4.1 查询性能优化 (购物车与订单结算)
**防止 N+1 查询问题**：当用户在购物车勾选了 20 个不同商品进行结算时，**绝对不能**在后端使用循环去数据库查 20 次个人折扣表！
* **正确做法**：将购物车里所有商品的 `product_id` 组装成一个数组。执行一次 `SELECT * FROM ml_user_product_discounts WHERE user_id = 'xxx' AND product_id IN (id1, id2, id3...);` 构建一个映射字典（Map/Hash），然后在内存在结算链中匹配。

---

## 5. 项目分期与落地计划

为了控制风险保障业务不中断，建议采取“两周敏捷迭代”策略。

* **Phase 1 (第一期)：打通通道与数据库**
  * 在 Supabase `ml_user_product_discounts` 建表与打入测试数据。
  * 改写买家端商品详情与结算页的逻辑，先完成**后端价格过滤模型**。这一步让消费者能准确以多级降级的形式算清最后的价格。
* **Phase 2 (第二期)：商家端可视化管理体系**
  * 开发并上线商家的【客户管理页】。
  * 根据客户维度拉取列表，并制作批量打折与分配商品的界面。
  * 上线后通知业务方进行试发价。