Files
medical-mall/pages/mall/consumer/sql/SUPABASE_CONSUMER_INTEGRATION.md

232 lines
6.4 KiB
Markdown
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.
# Supabase 消费者端集成指南 (Consumer Frontend Integration Guide)
本文档基于 `complete_mall_database.sql` 数据库设计,为消费者端 (Consumer App) 前端开发提供对接指引。
## 1. 核心表结构概览
所有商城相关表均以 `ml_` 开头。
| 功能模块 | 核心表 | 视图 (推荐使用) | 说明 |
| :--- | :--- | :--- | :--- |
| **用户** | `ml_user_profiles`, `ml_user_addresses` | `ml_users_view` | 用户扩展信息、收货地址 |
| **商品** | `ml_products`, `ml_categories`, `ml_product_skus` | `ml_products_detail_view` | 商品、分类、SKU库存 |
| **店铺** | `ml_shops` | - | 店铺基础信息 |
| **购物车** | `ml_shopping_cart` | - | 购物车数据 |
| **订单** | `ml_orders`, `ml_order_items` | `ml_orders_detail_view` | 订单主表及明细 |
| **营销** | `ml_user_coupons`, `ml_coupon_templates` | - | 优惠券 |
| **互动** | `ml_user_favorites`, `ml_product_reviews` | - | 收藏、评价 |
---
## 2. 关键业务场景与查询示例
### 2.1 首页展示
#### 获取一级分类
```typescript
const { data, error } = await supabase
.from('ml_categories')
.select('id, name, icon_url')
.eq('level', 1)
.eq('is_active', true)
.order('sort_order', { ascending: true });
```
#### 获取热销/推荐商品
```typescript
const { data, error } = await supabase
.from('ml_products')
.select('id, name, main_image_url, base_price, sale_count')
.eq('status', 1) // 上架状态
.eq('is_hot', true) // 热销标记
.limit(10);
```
### 2.2 商品详情页
建议优先使用 `ml_products` 表配合关联查询,或者使用视图。
#### 获取商品基础信息
```typescript
const { data, error } = await supabase
.from('ml_products')
.select(`
*,
category:ml_categories(id, name),
brand:ml_brands(id, name),
shop:ml_shops(id, shop_name, shop_logo),
skus:ml_product_skus(*),
specs:ml_product_specs(*)
`)
.eq('id', productId)
.single();
```
*注意:`skus` 和 `specs` 是通过外键关联获取的,确保前端处理好 `1:N` 的关系。*
### 2.3 购物车管理
前端需维护购物车逻辑,数据均存储在 `ml_shopping_cart`
#### 获取我的购物车 (含商品详情)
**重要**:务必使用内联查询 (`!inner` 或关联) 获取商品最新价格和图片。
```typescript
const { data, error } = await supabase
.from('ml_shopping_cart')
.select(`
id,
quantity,
selected,
sku_id,
product:ml_products!inner (
id,
name,
main_image_url,
base_price, -- 基础价格
status, -- 检查是否下架
merchant_id -- 用于店铺分组
),
sku:ml_product_skus (
id,
sku_code,
price, -- SKU价格如果有
specifications,
stock,
image_url
)
`)
.eq('user_id', currentUserId)
.order('created_at', { ascending: false });
```
#### 店铺分组逻辑 (前端处理)
前端获取数据后,应根据 `product.merchant_id` 进行分组,并聚合显示店铺名称 (需另外查询或关联 `ml_shops`)。
### 2.4 收货地址
#### 获取地址列表
```typescript
const { data, error } = await supabase
.from('ml_user_addresses')
.select('*')
.eq('user_id', currentUserId)
.eq('status', 1) // 1: 正常
.order('is_default', { ascending: false }) // 默认地址排最前
.order('updated_at', { ascending: false });
```
### 2.5 订单列表
#### 查询我的订单
```typescript
const { data, error } = await supabase
.from('ml_orders')
.select(`
id,
order_no,
total_amount,
order_status,
created_at,
items:ml_order_items (
id,
product_name,
image_url,
quantity,
price,
specifications
),
shop:ml_shops (
shop_name
)
`)
.eq('user_id', currentUserId)
.order('created_at', { ascending: false });
```
---
## 3. RLS (行级安全) 注意事项
数据库已配置 RLS 策略,前端直接调用 Supabase Client 即可,**无需在查询时手动增加 `user_id` 过滤** (除了显式需要对业务逻辑进行过滤的地方RLS 会自动兜底)。
- **`ml_shopping_cart`**: 用户只能查/改/删自己的购物车记录。
- **`ml_user_addresses`**: 用户只能查/改/删自己的地址。
- **`ml_orders`**: 用户只能查看自己的订单。
- **`ml_products`**: 设置为 `status = 1` 的商品所有人可读。
*确保在 App 启动时正确初始化 Supabase Auth 并处于登录状态。*
## 4. 推荐使用的数据库函数 (RPC)
可以直接通过 ` supabase.rpc('function_name', params)` 调用以下函数:
| 函数名 | 参数 | 描述 |
| :--- | :--- | :--- |
| `calculate_cart_total` | `p_user_id` | 计算当前用户购物车选中商品的总金额 (服务端计算更安全) |
| `get_product_available_stock` | `p_product_id`, `p_sku_id` | 获取特定商品或SKU的实时可用库存 |
| `get_user_default_address` | `p_user_id` | 快速获取用户的默认收货地址 |
### 调用示例
```typescript
// 计算购物车总价
const { data: total, error } = await supabase
.rpc('calculate_cart_total', {
p_user_id: currentUserId
});
```
## 5. 类型定义参考 (TypeScript)
为方便前端开发,以下是核心表对应的推荐接口定义:
```typescript
// 购物车项 (结合了关联查询的结果)
export interface CartItem {
id: string;
quantity: number;
selected: boolean;
product: {
id: string;
name: string;
main_image_url: string;
base_price: number;
merchant_id: string;
};
sku?: {
id: string;
price: number;
specifications: string; // JSON string
stock: number;
};
shop_name?: string; // 前端处理后注入
}
// 订单结构
export interface Order {
id: string;
order_no: string;
total_amount: number;
order_status: number; // 1:待付款 2:待发货 3:待收货 4:已完成 ...
items: Array<{
product_name: string;
image_url: string;
quantity: number;
price: number;
}>;
}
```
## 6. 特殊字段说明
- **Product Images**:
- `main_image_url`: 列表页和购物车主图。
- `image_urls`: JSONB 数组,用于商品详情轮播图。
- **Specifications**:
-`ml_product_skus` 表中 `specifications` 为 JSONB 格式 (例如 `{"color": "红色", "size": "L"}`),前端需解析展示。
- **Money**:
- 数据库使用 `DECIMAL`API 返回为 `number`,建议前端统一处理为两位小数展示。
---
*文档生成日期: 2026-02-02*