consumer模块完成度95%,优化安卓端界面和小程序测试3

This commit is contained in:
cyh666666
2026-03-13 17:12:00 +08:00
parent b2a6e5a142
commit b5c7947ad8
1741 changed files with 3427 additions and 2036 deletions

View File

@@ -0,0 +1,155 @@
# 基于 Supabase 实现消费者-商家聊天购物闭环方案
> **结论:** 是的,仅依赖 Supabase (配合前端逻辑) 完全可以实现“聊天购物闭环”的核心业务流程。 Supabase 提供的 Authentication身份验证、Database数据库、Realtime实时订阅、Storage存储以及 Edge Functions边缘函数覆盖了即时通讯和订单状态流转所需的所有基础设施。
>
> *注:实际资金的支付(扣款)通常需要对接微信支付/支付宝/Stripe等第三方支付网关但 Supabase 可以完美托管支付前后的数据流、状态流和 Webhook 处理。*
---
## 1. 核心架构概览
在不引入额外后端服务(如 Node.js/Java 服务端)的情况下,架构如下:
* **客户端 (Uni-app / Vue)**: 消费者端消费者 App商家端管理后台。直接通过 `supabase-js` SDK 与 Supabase 交互。
* **身份验证 (Auth)**: 区分消费者Consumer和商家Merchant/Admin。利用 RLS (Row Level Security) 确保数据隔离。
* **实时通讯 (Realtime)**: 监听 `messages``orders` 表的变动,实现毫秒级消息推送和订单状态更新。
* **业务逻辑 (Database + Edge Functions)**: 使用 Postgres 函数处理复杂的原子操作(如创建订单),使用 Edge Functions 处理支付回调。
---
## 2. 数据库设计 (Schema)
为了支持“边聊边买”,我们需要设计能关联聊天与订单的数据结构。
### 2.1 核心表结构
**1. 聊天室表 (`chat_rooms`)**
| 字段 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | uuid | 主键 |
| `consumer_id` | uuid | 关联 `auth.users` (消费者) |
| `merchant_id` | uuid | 关联 `auth.users` (商家) |
| `last_message` | jsonb | 最后一条消息快照(用于列表展示) |
| `updated_at` | timestamp | 排序用 |
**2. 消息表 (`messages`)**
| 字段 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | uuid | 主键 |
| `room_id` | uuid | 外键关联 `chat_rooms` |
| `sender_id` | uuid | 发送者 ID |
| `type` | text | 消息类型: `text`, `image`, `product`, `order`, `system` |
| `payload` | jsonb | 消息内容。如果是 `product`,存商品快照;如果是 `order`,存订单摘要 |
| `is_read` | boolean | 已读状态 |
| `created_at` | timestamp | 发送时间 |
**3. 订单表 (`orders`)**
| 字段 | 类型 | 说明 |
| :--- | :--- | :--- |
| `id` | uuid | 主键 |
| `room_id` | uuid | **关键关联**:该订单属于哪个聊天上下文 |
| `consumer_id` | uuid | 买家 |
| `merchant_id` | uuid | 卖家 |
| `items` | jsonb | 商品列表 |
| `total_amount` | numeric | 总金额 |
| `status` | text | `pending`, `paid`, `shipped`, `completed`, `cancelled` |
| `payment_status`| text | `unpaid`, `success` |
---
## 3. “聊天购物”闭环流程详解
### 场景一:商品咨询与卡片发送
1. **场景**: 消费者在商品详情页点击“联系商家”。
2. **动作**:
* 前端检查 `chat_rooms` 是否存在该(消费者, 商家)的记录,没有则插入(`upsert`)。
* 跳转至聊天页。
* **特色功能**: 自动发送一条 `type: product` 的消息,包含当前浏览的商品卡片 (`payload: { id, title, price, image }`)。
3. **实现 (Supabase)**:
* 直接写入 `messages` 表。
* 商家端通过 `supabase.channel('messages').on(...)` 实时收到商品卡片,知道用户对什么感兴趣。
### 场景二:商家发起收款(创建订单)
1. **场景**: 双方沟通确认购买意向后,商家点击“发起订单”或“直接改价”。
2. **动作**:
* 商家选择商品,填写金额,生成预订单。
*`orders` 表插入一条状态为 `pending` 的记录。
*`messages` 表插入一条 `type: order` 的消息,`payload` 包含 `order_id` 和摘要。
3. **表现**: 消费者在聊天流中看到一个“待支付订单卡片”。
### 场景三:聊天中支付
1. **场景**: 消费者点击聊天气泡中的“立即支付”按钮。
2. **动作**:
* APP 唤起支付(微信/支付宝)。
* 支付成功后,支付平台回调 Supabase Edge Function (或通过前端验证)。
* 更新 `orders``status``paid`
3. **闭环**:
* Supabase 监听到 `orders``status` 变为 `paid`
* **触发器 (Trigger)** 或客户端逻辑自动插入一条 `type: system` 的消息:“订单已支付,等待发货”。
* 商家端聊天界面实时更新订单状态为“已支付”。
---
## 4. 关键技术实现点
### 4.1 RLS (行级安全策略)
必须配置严格的 RLS防止用户偷看他人聊天。
```sql
-- 示例:只能查看属于自己的聊天室
create policy "Users can view their own rooms"
on chat_rooms for select
using (auth.uid() = consumer_id or auth.uid() = merchant_id);
```
### 4.2 实时订阅 (Realtime)
前端代码示例 (Prolog/Vue):
```typescript
// 订阅消息
const messageChannel = supabase
.channel('chat-room-123')
.on(
'postgres_changes',
{ event: 'INSERT', schema: 'public', table: 'messages', filter: `room_id=eq.${roomId}` },
(payload) => {
messages.value.push(payload.new)
scrollToBottom()
}
)
.subscribe()
// 订阅订单状态变更 (实现卡片状态自动刷新)
const orderChannel = supabase
.channel('order-updates')
.on(
'postgres_changes',
{ event: 'UPDATE', schema: 'public', table: 'orders', filter: `room_id=eq.${roomId}` },
(payload) => {
updateOrderCardStatus(payload.new.id, payload.new.status)
}
)
.subscribe()
```
### 4.3 边缘函数 (Edge Functions) 处理 Webhook
由于前端不能直接处理支付回调(不安全),需要使用 Supabase Edge Functions。
* `functions/payment-webhook/index.ts`: 接收微信支付回调,验证签名,然后使用 Service Role Key 更新 `orders` 表。
---
## 5. 总结
完全依赖 Supabase 实现聊天购物闭环是**可行且高效**的方案。
* **开发快**: 免去后端 CRUD 接口开发,直接操作 DB。
* **实时性**: Realtime 功能天然契合聊天场景。
* **成本低**: 无需维护长连接服务器 (WebSocket)。
* **闭环体验**: 订单与消息在同一数据流中,用户体验流畅。
**下一步建议:**
1. 在 Supabase 中创建 `chat_rooms`, `messages`, `orders` 表。
2. 配置 RLS。
3. 开发消息列表 UI支持多类型消息渲染特别是商品卡片和订单卡片

View File

@@ -0,0 +1,321 @@
# 消费者端前端数据库文档 (Consumer App DB Schema)
本文档基于现有消费者前端 (`mall/pages/mall/consumer`) 和 Supabase 服务层 (`mall/utils/supabaseService.uts`) 的调用逻辑生成。旨在协助商家端前端开发进行数据库对接。
## 1. 核心业务表 (Core Business Tables)
### 1.1 商品分类表 (`ml_categories`)
用于展示商品的一级/二级分类。
| 字段名 | 类型 | 描述 | 备注 |
| :--- | :--- | :--- | :--- |
| `id` | UUID | 主键 | |
| `name` | Text | 分类名称 | |
| `icon_url` | Text | 图标 URL | 前端可能回退到 Emoji |
| `description` | Text | 描述 | |
| `parent_id` | UUID | 父分类 ID | 用于树形结构 |
| `sort_order` | Integer | 排序权重 | |
| `is_active` | Boolean | 是否启用 | |
### 1.2 品牌表 (`ml_brands`)
商品所属品牌信息。
| 字段名 | 类型 | 描述 | 备注 |
| :--- | :--- | :--- | :--- |
| `id` | UUID | 主键 | |
| `name` | Text | 品牌名称 | |
| `logo_url` | Text | 品牌 Logo URL | |
| `description` | Text | 品牌描述 | |
| `country` | Text | 所属国家 | 可选 |
| `is_active` | Boolean | 是否启用 | |
### 1.3 商家/店铺表 (`ml_shops`)
商家端主要管理的店铺信息实体。
| 字段名 | 类型 | 描述 | 备注 |
| :--- | :--- | :--- | :--- |
| `id` | UUID | 主键 | |
| `merchant_id` | UUID | 关联的商户账号 ID | 对应 auth.users 或 merchants 表 |
| `shop_name` | Text | 店铺名称 | |
| `shop_logo` | Text | 店铺 Logo | |
| `shop_banner` | Text | 店铺背景图 | |
| `description` | Text | 店铺简介 | |
| `contact_name` | Text | 联系人 | |
| `contact_phone` | Text | 联系电话 | |
| `rating_avg` | Numeric | 平均评分 | |
| `total_sales` | Integer | 总销量 | |
| `status` | Integer | 状态 | 1: 正常, 0: 停用 |
---
## 2. 商品系统 (Product System)
### 2.1 商品主表 (`ml_products`)
商家发布的核心商品数据。
| 字段名 | 类型 | 描述 | 备注 |
| :--- | :--- | :--- | :--- |
| `id` | UUID | 主键 | |
| `merchant_id` | UUID | 所属商家 ID | |
| `category_id` | UUID | 所属分类 ID | |
| `brand_id` | UUID | 所属品牌 ID | |
| `name` | Text | 商品名称 | |
| `subtitle` | Text | 副标题 | 简短描述 |
| `description` | Text | 商品详情 | HTML 或 Markdown |
| `main_image_url` | Text | 主图 URL | |
| `image_urls` | JSON/Array | 轮播图列表 | `['url1', 'url2']` |
| `video_urls` | JSON/Array | 视频列表 | |
| `base_price` | Numeric | 基础售价 | 列表页展示价格 |
| `market_price` | Numeric | 市场价/划线价 | |
| `cost_price` | Numeric | 成本价 | 敏感字段,仅商家可见 |
| `total_stock` | Integer | 总库存 | |
| `status` | Integer | 状态 | 1: 上架, 0: 下架, 2: 审核中 |
| `is_hot` | Boolean | 是否热销 | |
| `is_new` | Boolean | 是否新品 | |
| `is_featured` | Boolean | 是否推荐 | |
| `attributes` | JSONB | 商品属性 | `{ "材质": "纯棉", "季节": "夏季" }` |
| `tags` | Text[] | 标签 | |
| `sale_count` | Integer | 销量 | 统计字段 |
### 2.2 商品 SKU 表 (`ml_product_skus`)
商品的多规格定义(如颜色、尺寸)。
| 字段名 | 类型 | 描述 | 备注 |
| :--- | :--- | :--- | :--- |
| `id` | UUID | 主键 | |
| `product_id` | UUID | 关联商品 ID | |
| `sku_code` | Text | SKU 编码 | 商家自定义编码 |
| `specifications` | JSONB | 规格键值对 | `{ "颜色": "红", "尺寸": "L" }` |
| `price` | Numeric | SKU 售价 | 特殊规格价格 |
| `market_price` | Numeric | SKU 市场价 | |
| `stock` | Integer | 当前库存 | |
| `image_url` | Text | 规格对应图片 | 如红色款对应红色的图 |
| `status` | Integer | 状态 | 1: 启用, 0: 禁用 |
### 2.3 商品详情视图 (`ml_products_detail_view`)
**重要**: 消费者端主要通过此视图查询商品,商家在维护数据时应确保这些关联字段能正确生成。
* 该视图通常 `JOIN``ml_shops` (获取 `shop_name`), `ml_brands` (获取 `brand_name`), `ml_categories` (获取 `category_name`)。
* **商家端操作**: 不需要直接操作视图,只需维护上述基础表。
---
## 3. 交易系统 (Transaction System)
### 3.1 购物车 (`ml_shopping_cart`)
| 字段名 | 类型 | 描述 | 备注 |
| :--- | :--- | :--- | :--- |
| `id` | UUID | 主键 | |
| `user_id` | UUID | 用户 ID | |
| `product_id` | UUID | 商品 ID | |
| `sku_id` | UUID | SKU ID | 可空(若商品无多规格) |
| `quantity` | Integer |数量 | |
| `selected` | Boolean | 是否勾选 | 购物车状态 |
| `created_at` | Timestamp | 创建时间 | |
### 3.2 订单主表 (`ml_orders`)
商家端处理订单的核心表。
| 字段名 | 类型 | 描述 | 备注 |
| :--- | :--- | :--- | :--- |
| `id` | UUID | 主键 | |
| `order_no` | VARCHAR | 订单号 | 唯一业务单号 |
| `user_id` | UUID | 用户 ID | |
| `merchant_id` | UUID | 商家 ID | |
| `product_amount` | NUMERIC | 商品金额 | 默认0 |
| `discount_amount` | NUMERIC | 优惠金额 | |
| `shipping_fee` | NUMERIC | 运费 | |
| `total_amount` | NUMERIC | 订单总金额 | |
| `paid_amount` | NUMERIC | 实付金额 | |
| `shipping_address` | JSONB | 收货地址 | |
| `order_status` | INTEGER | 订单状态 | 1:待付款, 2:待发货, 3:待收货, 4:已完成, 5:已取消, 0:退款中, -1:已取消 |
| `payment_status` | INTEGER | 支付状态 | 默认1 |
| `shipping_status` | INTEGER | 发货状态 | 默认1 |
| `paid_at` | TIMESTAMP | 支付时间 | |
| `shipped_at` | TIMESTAMP | 发货时间 | |
| `delivered_at` | TIMESTAMP | 收货时间 | |
| `completed_at` | TIMESTAMP | 完成时间 | |
| `remark` | TEXT | 订单备注 | |
| `merchant_memo` | TEXT | 商家备注 | |
| `cancel_reason` | TEXT | 取消原因 | |
| `created_at` | TIMESTAMP | 创建时间 | 默认now() |
| `updated_at` | TIMESTAMP | 更新时间 | |
| `cid` | INTEGER | 序号 | |
| `payment_method` | VARCHAR | 支付方式 | |
| `payment_time` | TIMESTAMP | 支付时间 | |
| `shipping_company` | VARCHAR | 物流公司 | 商家端发货填写 |
| `tracking_number` | VARCHAR | 物流单号 | 商家端发货填写 |
### 3.3 订单项表 (`ml_order_items`)
| 字段名 | 类型 | 描述 | 备注 |
| :--- | :--- | :--- | :--- |
| `id` | UUID | 主键 | |
| `order_id` | UUID | 订单 ID | |
| `product_id` | UUID | 商品 ID | |
| `sku_id` | UUID | SKU ID | 可空 |
| `product_name` | VARCHAR | 商品名称快照 | |
| `sku_name` | VARCHAR | SKU名称 | 可空 |
| `specifications` | JSONB | 规格信息 | 默认{} |
| `image_url` | TEXT | 商品图片 | 可空 |
| `price` | NUMERIC | 成交单价 | |
| `quantity` | INTEGER | 购买数量 | |
| `total_amount` | NUMERIC | 小计金额 | |
| `created_at` | TIMESTAMP | 创建时间 | |
| `sku_snapshot` | JSONB | SKU快照 | 默认{} |
### 3.4 订单详情视图 (`ml_orders_detail_view`)
订单联合查询视图。
| 字段名 | 类型 | 描述 | 备注 |
| :--- | :--- | :--- | :--- |
| `id` | UUID | 主键 | |
| `order_no` | VARCHAR | 订单号 | |
| `user_id` | UUID | 用户 ID | |
| `merchant_id` | UUID | 商家 ID | |
| `product_amount` | NUMERIC | 商品金额 | |
| `discount_amount` | NUMERIC | 优惠金额 | |
| `shipping_fee` | NUMERIC | 运费 | |
| `total_amount` | NUMERIC | 订单总金额 | |
| `paid_amount` | NUMERIC | 实付金额 | |
| `shipping_address` | JSONB | 收货地址 | |
| `order_status` | INTEGER | 订单状态 | |
| `payment_status` | INTEGER | 支付状态 | |
| `shipping_status` | INTEGER | 发货状态 | |
| `paid_at` | TIMESTAMP | 支付时间 | |
| `shipped_at` | TIMESTAMP | 发货时间 | |
| `delivered_at` | TIMESTAMP | 收货时间 | |
| `completed_at` | TIMESTAMP | 完成时间 | |
| `remark` | TEXT | 订单备注 | |
| `merchant_memo` | TEXT | 商家备注 | |
| `cancel_reason` | TEXT | 取消原因 | |
| `created_at` | TIMESTAMP | 创建时间 | |
| `updated_at` | TIMESTAMP | 更新时间 | |
| `customer_name` | VARCHAR | 客户姓名 | |
| `customer_phone` | TEXT | 客户电话 | |
| `merchant_name` | VARCHAR | 商家名称 | |
| `shop_name` | VARCHAR | 店铺名称 | |
| `order_status_name` | TEXT | 订单状态名称 | |
| `payment_status_name` | TEXT | 支付状态名称 | |
### 3.5 支付订单表 (`pay_order`)
支付网关订单表。
| 字段名 | 类型 | 描述 | 备注 |
| :--- | :--- | :--- | :--- |
| `id` | BIGINT | 主键 | |
| `merchant_id` | BIGINT | 商户ID | |
| `app_id` | BIGINT | 应用ID | |
| `channel_id` | BIGINT | 渠道ID | 可空 |
| `channel_code` | VARCHAR | 渠道编码 | 可空 |
| `merchant_order_id` | VARCHAR | 商户订单号 | |
| `subject` | VARCHAR | 订单标题 | |
| `body` | VARCHAR | 订单描述 | |
| `notify_url` | VARCHAR | 通知地址 | |
| `notify_status` | SMALLINT | 通知状态 | |
| `amount` | BIGINT | 金额 | |
| `channel_fee_rate` | DOUBLE | 渠道费率 | 可空 |
| `channel_fee_amount` | BIGINT | 渠道手续费 | 可空 |
| `status` | SMALLINT | 状态 | |
| `user_ip` | VARCHAR | 用户IP | |
| `expire_time` | TIMESTAMP | 过期时间 | |
| `success_time` | TIMESTAMP | 成功时间 | 可空 |
| `notify_time` | TIMESTAMP | 通知时间 | 可空 |
| `success_extension_id` | BIGINT | 成功扩展ID | 可空 |
| `refund_status` | SMALLINT | 退款状态 | |
| `refund_times` | SMALLINT | 退款次数 | |
| `refund_amount` | BIGINT | 退款金额 | |
| `channel_user_id` | VARCHAR | 渠道用户ID | 可空 |
| `channel_order_no` | VARCHAR | 渠道订单号 | 可空 |
| `creator` | VARCHAR | 创建人 | 可空 |
| `create_time` | TIMESTAMP | 创建时间 | |
| `updater` | VARCHAR | 更新人 | 可空 |
| `update_time` | TIMESTAMP | 更新时间 | |
| `deleted` | SMALLINT | 删除标记 | 默认0 |
| `tenant_id` | BIGINT | 租户ID | 默认0 |
### 3.6 支付订单扩展表 (`pay_order_extension`)
支付订单扩展信息表。
| 字段名 | 类型 | 描述 | 备注 |
| :--- | :--- | :--- | :--- |
| `id` | BIGINT | 主键 | |
| `no` | VARCHAR | 支付流水号 | |
| `order_id` | BIGINT | 支付订单ID | |
| `channel_id` | BIGINT | 渠道ID | |
| `channel_code` | VARCHAR | 渠道编码 | |
| `user_ip` | VARCHAR | 用户IP | |
| `status` | SMALLINT | 状态 | |
| `channel_extras` | VARCHAR | 渠道额外信息 | 可空 |
| `channel_notify_data` | VARCHAR | 渠道通知数据 | 可空 |
| `creator` | VARCHAR | 创建人 | 可空 |
| `create_time` | TIMESTAMP | 创建时间 | |
| `updater` | VARCHAR | 更新人 | 可空 |
| `update_time` | TIMESTAMP | 更新时间 | |
| `deleted` | SMALLINT | 删除标记 | 默认0 |
| `tenant_id` | BIGINT | 租户ID | 默认0 |
### 3.7 库存订单表 (`stock_orders`)
库存相关订单表。
| 字段名 | 类型 | 描述 | 备注 |
| :--- | :--- | :--- | :--- |
| `id` | UUID | 主键 | |
| `simulation_id` | UUID | 模拟ID | 可空 |
| `symbol` | TEXT | 交易标的 | |
| `side` | TEXT | 交易方向 | |
| `qty` | NUMERIC | 数量 | |
| `price` | NUMERIC | 价格 | 可空 |
| `status` | TEXT | 状态 | 默认created |
| `placed_at` | TIMESTAMP | 下单时间 | |
| `executed_at` | TIMESTAMP | 执行时间 | 可空 |
| `fee` | NUMERIC | 手续费 | 默认0 |
---
## 4. 用户相关 (User Relations)
### 4.1 用户地址 (`ml_user_addresses`)
| 字段名 | 类型 | 描述 | 备注 |
| :--- | :--- | :--- | :--- |
| `id` | UUID | 主键 | |
| `user_id` | UUID | 用户 ID | |
| `recipient_name` | Text | 收货人姓名 | |
| `phone` | Text | 手机号 | |
| `province` | Text | 省 | |
| `city` | Text | 市 | |
| `district` | Text | 区 | |
| `detail_address` | Text | 详细地址 | |
| `is_default` | Boolean | 是否默认地址 | |
### 4.2 聊天消息 (`ml_chat_messages`)
用于客服系统。
| 字段名 | 类型 | 描述 | 备注 |
| :--- | :--- | :--- | :--- |
| `id` | UUID | 主键 | |
| `session_id` | UUID | 会话 ID | 可选,或通过收发人聚合 |
| `sender_id` | UUID | 发送者 ID | |
| `receiver_id` | UUID | 接收者 ID | |
| `content` | Text | 消息内容 | |
| `msg_type` | Text | 消息类型 | 'text', 'image', 'product' |
| `is_read` | Boolean | 是否已读 | |
| `created_at` | Timestamp | 发送时间 | |
## 5. 对接建议 (Integration Tips for Merchant Frontend)
1. **商品管理**:
* 在创建商品时,必须先选择 `category_id``merchant_id`
* 如果有 `specifications` (多规格),请同时向 `ml_product_skus` 插入数据。
* 更新库存时,请优先更新 `ml_product_skus` 中的 `stock`,并同步总库存到 `ml_products`.`total_stock`
2. **图片处理**:
* 消费者端支持 `main_image_url` (字符串) 和 `image_urls` (JSON 数组) 两种格式,请确保都正确填充。
3. **状态管理**:
* 上架商品请将 `status` 设为 `1`
* 如需在首页 "推荐/热销" 板块显示,请设置 `is_featured``is_hot``true`
4. **Supabase 安全策略 (RLS)**:
* 请确保商家端账号有权限写入 `ml_products``ml_shops` 表,但只能修改 `merchant_id` 等于自己账号的数据。

View File

@@ -0,0 +1,62 @@
# 功能与页面状态详解
本文档详细记录了 Consumer App 各个功能模块的实现状态与业务逻辑。
> **状态图例**: ✅ 正常 (已对接真实 DB) | 🚧 开发中 | ❌ 未开始
## 🛍️ 核心购物流程
| 功能模块 | 页面路径 | 状态 | 备注 |
| :--- | :--- | :--- | :--- |
| **首页** | `pages/mall/consumer/index.uvue` | ✅ 正常 | 金刚区、Banner、推荐商品流。 |
| **分类** | `pages/mall/consumer/category.uvue` | ✅ 正常 | 一级/二级分类联动,跳转搜索结果。 |
| **商品详情** | `pages/mall/consumer/product-detail.uvue` | ✅ 正常 | SKU 选择、加入购物车、立即购买。 |
| **购物车** | `pages/mall/consumer/cart.uvue` | ✅ 正常 | 数量增减、勾选计算、结算校验。 |
| **结算页** | `pages/mall/consumer/checkout.uvue` | ✅ 正常 | 选择地址、运费计算、创建订单。 |
| **收银台** | `pages/mall/consumer/payment.uvue` | ✅ 正常 | 模拟支付流程,更新订单为“待发货”。 |
## 👤 个人中心 (Profile)
**文件**: `pages/mall/consumer/profile.uvue`
* **资产看板**: 实时加载积分、余额、优惠券数量。
* **订单看板**: 待支付、待发货、待收货、退款/售后(跳转至 `refund.uvue`)。
* **服务矩阵**:
* **地址管理**: `address-list.uvue` (CRUD 正常)
* **我的收藏**: `favorites.uvue` (商品/店铺收藏 正常)
* **浏览足迹**: `footprint.uvue` (按日期分组 正常)
* **在线客服**: 跳转至 `chat.uvue`
* **消息通知**: 跳转至 `messages.uvue`
## 📦 订单管理体系
**列表页**: `pages/mall/consumer/orders.uvue`
* **状态筛选**: 全部 / 待支付 / 待发货 / 待收货 / 已完成。
* **核心操作**:
* **去支付**: 跳转收银台。
* **确认收货**: 变更状态为已完成。
* **申请售后**: 跳转 `apply-refund.uvue` (带入订单信息)。
**详情页**: `pages/mall/consumer/order-detail.uvue`
* **信息展示**: 完整的地址、商品规格、金额明细、时间线。
* **业务状态**: 根据 `order_status` 动态展示可操作按钮。
## 🔄 售后服务体系 (Refunds)
**申请页**: `pages/mall/consumer/apply-refund.uvue`
* **功能**: 支持仅退款/退货退款。
* **逻辑**: 自动获取订单最大可退金额,防止超额申请。
* **提交**: 数据写入 `ml_refunds` 表。
**记录页**: `pages/mall/consumer/refund.uvue`
* **列表**: 展示所有历史售后申请及其当前状态。
* **进度**: 可视化展示审核进度 (目前模拟进度条)。
## 💬 社交与互动
| 功能模块 | 页面路径 | 状态 | 说明 |
| :--- | :--- | :--- | :--- |
| **在线客服** | `pages/mall/consumer/chat.uvue` | ✅ 正常 | 支持文本/表情发送,历史记录持久化。 |
| **消息中心** | `pages/mall/consumer/messages.uvue` | ✅ 正常 | 聚合系统通知订单消息与客服消息。 |
| **商品评价** | `pages/mall/consumer/review.uvue` | ✅ 正常 | 支持星级评分与文本评价。 |

View File

@@ -0,0 +1,305 @@
# 多端分包与体积优化方案
## 一、问题分析
### 1.1 当前项目结构问题
当前 `pages.json` 包含了所有端的页面配置:
```
pages/
├── user/ # 公共用户页面
├── main/ # 公共主页面
├── mall/
│ ├── consumer/ # 消费者端 (约 40+ 页面)
│ ├── merchant/ # 商家端 (约 20+ 页面)
│ ├── admin/ # 管理端 (约 50+ 页面)
│ ├── analytics/ # 分析端 (约 15+ 页面)
│ ├── delivery/ # 配送端 (约 15+ 页面)
│ └── service/ # 服务端 (约 5+ 页面)
```
### 1.2 小程序包体积限制
| 平台 | 主包限制 | 分包限制 | 总限制 |
|------|---------|---------|--------|
| 微信小程序 | 2MB | 2MB/个 | 20MB |
| 支付宝小程序 | 2MB | 2MB/个 | 20MB |
| 百度小程序 | 2MB | 2MB/个 | 20MB |
**问题**: 如果所有端的页面都打包进小程序,会严重超出限制!
---
## 二、解决方案
### 方案 A条件编译 + 独立 pages.json推荐
**核心思路**: 使用 uni-app x 的条件编译功能,为不同端编译不同的页面配置。
#### 2.1 创建端专用 pages.json
```
pages/
├── pages-consumer.json # 消费者端页面配置
├── pages-merchant.json # 商家端页面配置
├── pages-admin.json # 管理端页面配置
├── pages-analytics.json # 分析端页面配置
└── pages-delivery.json # 配送端页面配置
```
#### 2.2 pages-consumer.json 示例
```json
{
"pages": [
{
"path": "pages/user/login",
"style": { "navigationBarTitleText": "登录" }
},
{
"path": "pages/main/index",
"style": { "navigationBarTitleText": "首页" }
},
{
"path": "pages/main/category",
"style": { "navigationBarTitleText": "分类" }
},
{
"path": "pages/main/cart",
"style": { "navigationBarTitleText": "购物车" }
},
{
"path": "pages/main/profile",
"style": { "navigationBarTitleText": "我的" }
}
],
"subPackages": [
{
"root": "pages/mall/consumer",
"pages": [
{ "path": "product-detail", "style": { "navigationBarTitleText": "商品详情" } },
{ "path": "checkout", "style": { "navigationBarTitleText": "结算" } },
{ "path": "orders", "style": { "navigationBarTitleText": "订单" } },
{ "path": "payment", "style": { "navigationBarTitleText": "支付" } }
]
}
]
}
```
#### 2.3 编译脚本配置
`package.json` 中添加编译脚本:
```json
{
"scripts": {
"dev:mp-weixin:consumer": "uni -p mp-weixin --pages pages-consumer.json",
"build:mp-weixin:consumer": "uni build -p mp-weixin --pages pages-consumer.json",
"dev:mp-weixin:merchant": "uni -p mp-weixin --pages pages-merchant.json",
"build:mp-weixin:merchant": "uni build -p mp-weixin --pages pages-merchant.json"
}
}
```
---
### 方案 B条件编译页面级别备选
**核心思路**: 在单个 `pages.json` 中使用条件编译注释。
```json
{
"pages": [
// 公共页面
{ "path": "pages/user/login", "style": {} },
// #ifdef PLATFORM_CONSUMER
// 消费者端页面
{ "path": "pages/main/index", "style": {} },
{ "path": "pages/main/cart", "style": {} },
// #endif
// #ifdef PLATFORM_MERCHANT
// 商家端页面
{ "path": "pages/mall/merchant/index", "style": {} },
// #endif
]
}
```
**注意**: 此方案需要自定义平台标识uni-app x 默认不支持。
---
### 方案 C多项目共享核心备选
**核心思路**: 创建多个小程序项目,共享核心代码。
```
mall/
├── core/ # 共享核心代码
│ ├── components/
│ ├── utils/
│ ├── api/
│ └── types/
├── projects/
│ ├── consumer/ # 消费者端项目
│ │ ├── pages/
│ │ ├── pages.json
│ │ └── manifest.json
│ ├── merchant/ # 商家端项目
│ │ ├── pages/
│ │ ├── pages.json
│ │ └── manifest.json
│ └── admin/ # 管理端项目
│ ├── pages/
│ ├── pages.json
│ └── manifest.json
└── shared/ # 共享资源
├── static/
└── uni_modules/
```
---
## 三、推荐方案实施
### 3.1 采用方案 A 的实施步骤
#### 步骤 1创建消费者端专用配置
创建 `pages-consumer.json`,仅包含消费者端需要的页面。
#### 步骤 2修改 manifest.json
```json
{
"mp-weixin": {
"appid": "消费者端小程序AppID",
"optimization": {
"subPackages": true
}
}
}
```
#### 步骤 3配置分包
```json
{
"subPackages": [
{
"root": "pages/mall/consumer",
"pages": [
// 消费者端次级页面
]
}
],
"preloadRule": {
"pages/main/index": {
"network": "all",
"packages": ["pages/mall/consumer"]
}
}
}
```
#### 步骤 4排除其他端代码
`manifest.json` 中配置排除:
```json
{
"mp-weixin": {
"optimization": {
"subPackages": true
},
"exclude": [
"pages/mall/merchant/**",
"pages/mall/admin/**",
"pages/mall/analytics/**",
"pages/mall/delivery/**",
"pages/mall/service/**"
]
}
}
```
---
## 四、体积优化建议
### 4.1 图片资源优化
```
static/
├── images/
│ ├── consumer/ # 消费者端图片
│ ├── merchant/ # 商家端图片
│ └── common/ # 公共图片
```
- 使用 CDN 托管图片
- 小图片使用 base64 内联
- 使用 WebP 格式
### 4.2 组件按需加载
```uts
// 动态导入组件
const ProductDetail = () => import('@/pages/mall/consumer/product-detail.uvue')
```
### 4.3 代码分割
```
utils/
├── consumer/ # 消费者端专用工具
├── merchant/ # 商家端专用工具
├── admin/ # 管理端专用工具
└── common/ # 公共工具
```
---
## 五、各端小程序独立发布
### 5.1 发布矩阵
| 端 | 小程序名称 | AppID | 用途 |
|---|-----------|-------|------|
| 消费者端 | XX商城 | wx_xxx | 消费者购物 |
| 商家端 | XX商家 | wx_xxx | 商家管理 |
| 配送端 | XX配送 | wx_xxx | 配送员接单 |
### 5.2 独立配置
每个端使用独立的:
- `manifest.json` 配置AppID、权限等
- `pages.json` 页面配置
- 图标和启动页
---
## 六、总结
### 推荐方案
**方案 A条件编译 + 独立 pages.json**
### 核心优势
1. **体积可控**: 每个端只编译自己需要的页面
2. **维护简单**: 代码仍在同一仓库,便于共享和同步
3. **发布灵活**: 各端可独立发布和更新
### 实施优先级
1. 创建 `pages-consumer.json`(消费者端)
2. 配置分包和排除规则
3. 测试编译体积
4. 逐步为其他端创建配置
### 预期效果
- 消费者端小程序主包 < 1.5MB
- 分包 < 500KB
- 总体积 < 3MB

View File

@@ -0,0 +1,44 @@
# 测试数据生成指南 (Mock Data Guide)
为了有效测试消费者端前端功能,我们编写了 SQL 脚本来向数据库填充真实的模拟数据。
## 📂 脚本位置
所有脚本均位于 `doc_mall/consumer/sql/` 目录下。
## 🛠 使用说明
### 1. 修复现有数据问题 (优先级最高)
**脚本**: `fix_order_items_data.sql`
* **适用场景**: 如果您的订单列表中,商品显示为空白图片或缺失名称。
* **功能**:
*`ml_product_skus``ml_products` 表自动回填缺失的 `image_url`
* 修正占位符形式的 `product_name`
* 补充缺失的 `specifications` (如:规格参数)。
### 2. 生成新的测试订单
**脚本**: `add_mock_orders_corrected.sql`
* **适用场景**: 为测试用户 (`test@mall.com`) 创建一批全新的订单数据。
* **生成数据包含**:
* 1x **待支付** 订单
* 1x **待发货** 订单 (已支付)
* 1x **待收货** 订单 (已发货)
* 1x **已完成** 订单
* **注意**: 该脚本会随机选取数据库中现有的真实商品,确保数据关联正确无误。
### 3. 生成评价测试数据
**脚本**: `add_mock_reviews_for_test_user.sql`
* **适用场景**: 测试“我的评价”列表或商品详情页的评价展示。
* **功能**: 创建已完成的订单,并自动为其添加一条带图片的 5 星好评。
## 🧪 建议测试流程
1. **运行** `add_mock_orders_corrected.sql`
2. **打开 App** > 个人中心 (Profile) > 我的订单。
3. **验证**:
* 各状态标签页下是否有对应的订单。
* 商品图片和名称是否显示正常。
* 在“待收货”或“已完成”订单上点击**申请售后**,验证是否跳转正确。

View File

@@ -0,0 +1,534 @@
# 消费者端多端适配方案
## 一、项目现状分析
### 1.1 当前技术栈
- **框架**: uni-app x (Vue 3 + UTS)
- **已支持平台**:
- Android App (已验证)
- 微信小程序 (已验证)
- H5 (配置已就绪)
- 其他小程序平台 (支付宝、百度、头条等配置已就绪)
### 1.2 项目结构
```
pages/mall/consumer/ # 消费者端页面
├── doc/ # 文档目录
├── index.uvue # 首页
├── category.uvue # 分类页
├── product-detail.uvue # 商品详情
├── cart.uvue # 购物车
├── checkout.uvue # 结算页
├── orders.uvue # 订单列表
├── profile.uvue # 个人中心
└── ...
```
---
## 二、多端适配方案对比
### 方案一:单项目多端编译(推荐)
**核心思路**: 一套代码,通过条件编译和平台判断,编译到不同平台。
**优点**:
- 代码复用率高,维护成本低
- 统一的技术栈和开发流程
- Bug修复一次全平台生效
- 符合 uni-app x 的设计理念
**缺点**:
- 需要处理各平台差异
- 部分平台特性需要条件编译
- 小程序包体积限制需要注意
**实现方式**:
```uts
// 条件编译示例
// #ifdef MP-WEIXIN
// 微信小程序特有代码
// #endif
// #ifdef APP-ANDROID
// Android App 特有代码
// #endif
// #ifdef H5
// H5 特有代码
// #endif
```
### 方案二:多项目独立开发
**核心思路**: 为每个平台创建独立项目,共享核心业务逻辑。
**优点**:
- 各端可独立优化
- 不受其他平台限制
- 可针对平台特性深度定制
**缺点**:
- 维护成本高,代码重复
- Bug需要多端修复
- 开发周期长
**适用场景**:
- 各端差异极大
- 需要深度定制平台特性
- 有充足的开发资源
### 方案三:核心库 + 平台适配层
**核心思路**: 抽离核心业务逻辑为共享库,各平台实现适配层。
**优点**:
- 核心逻辑统一
- 平台适配灵活
- 便于团队协作
**缺点**:
- 架构复杂度高
- 需要良好的抽象设计
- 初期开发成本较高
---
## 三、推荐方案:单项目多端编译
基于项目现状,**推荐采用方案一**,原因如下:
1. **uni-app x 天然支持多端编译**
2. **当前代码已具备良好的跨端基础**
3. **维护成本最低,开发效率最高**
---
## 四、具体实施步骤
### 4.1 平台配置
#### 4.1.1 微信小程序配置
```json
// manifest.json
{
"mp-weixin": {
"appid": "你的微信小程序AppID",
"setting": {
"urlCheck": false,
"es6": true,
"postcss": true,
"minified": true
},
"usingComponents": true,
"optimization": {
"subPackages": true
}
}
}
```
#### 4.1.2 支付宝小程序配置
```json
// manifest.json
{
"mp-alipay": {
"appid": "你的支付宝小程序AppID",
"usingComponents": true
}
}
```
#### 4.1.3 H5 配置
```json
// manifest.json
{
"h5": {
"title": "商城消费者端",
"router": {
"mode": "history",
"base": "/consumer/"
},
"devServer": {
"port": 8080,
"proxy": {
"/api": {
"target": "https://your-api.com",
"changeOrigin": true
}
}
}
}
}
```
### 4.2 条件编译处理
#### 4.2.1 平台判断工具类
```uts
// utils/platform.uts
// 平台类型
export type PlatformType = 'android' | 'ios' | 'weixin' | 'alipay' | 'h5' | 'unknown'
// 获取当前平台
export function getCurrentPlatform(): PlatformType {
// #ifdef APP-ANDROID
return 'android'
// #endif
// #ifdef APP-IOS
return 'ios'
// #endif
// #ifdef MP-WEIXIN
return 'weixin'
// #endif
// #ifdef MP-ALIPAY
return 'alipay'
// #endif
// #ifdef H5
return 'h5'
// #endif
return 'unknown'
}
// 判断是否为小程序环境
export function isMiniProgram(): boolean {
const platform = getCurrentPlatform()
return platform === 'weixin' || platform === 'alipay'
}
// 判断是否为 App 环境
export function isApp(): boolean {
const platform = getCurrentPlatform()
return platform === 'android' || platform === 'ios'
}
```
#### 4.2.2 API 适配层
```uts
// utils/apiAdapter.uts
import { getCurrentPlatform, isMiniProgram, isApp } from './platform.uts'
// 支付适配
export function requestPayment(orderId: string, amount: number): Promise<any> {
return new Promise((resolve, reject) => {
// #ifdef MP-WEIXIN
// 微信小程序支付
uni.requestPayment({
provider: 'wxpay',
timeStamp: '',
nonceStr: '',
package: '',
signType: 'MD5',
paySign: '',
success: (res) => resolve(res),
fail: (err) => reject(err)
})
// #endif
// #ifdef MP-ALIPAY
// 支付宝小程序支付
my.tradePay({
tradeNO: orderId,
success: (res) => resolve(res),
fail: (err) => reject(err)
})
// #endif
// #ifdef APP-ANDROID || APP-IOS
// App 支付
uni.requestPayment({
provider: 'wxpay', // 或 'alipay'
orderInfo: orderId,
success: (res) => resolve(res),
fail: (err) => reject(err)
})
// #endif
// #ifdef H5
// H5 支付(跳转到支付页面)
window.location.href = `/payment?orderId=${orderId}`
resolve({})
// #endif
})
}
// 登录适配
export function platformLogin(): Promise<any> {
return new Promise((resolve, reject) => {
// #ifdef MP-WEIXIN
// 微信小程序登录
uni.login({
provider: 'weixin',
success: (res) => resolve(res),
fail: (err) => reject(err)
})
// #endif
// #ifdef MP-ALIPAY
// 支付宝小程序登录
my.getAuthCode({
scopes: 'auth_user',
success: (res) => resolve(res),
fail: (err) => reject(err)
})
// #endif
// #ifdef APP-ANDROID || APP-IOS
// App 登录(使用账号密码或第三方登录)
// 跳转到登录页面
uni.navigateTo({ url: '/pages/user/login' })
resolve({})
// #endif
})
}
// 分享适配
export function shareProduct(productId: string, title: string, imageUrl: string): void {
// #ifdef MP-WEIXIN
// 微信小程序分享(通过 onShareAppMessage
// 在页面中定义 onShareAppMessage 即可
// #endif
// #ifdef MP-ALIPAY
// 支付宝小程序分享
// #endif
// #ifdef APP-ANDROID || APP-IOS
// App 分享
uni.share({
provider: 'weixin',
scene: 'WXSceneSession',
type: 0,
title: title,
imageUrl: imageUrl,
success: () => console.log('分享成功'),
fail: (err) => console.error('分享失败', err)
})
// #endif
}
```
### 4.3 样式适配
#### 4.3.1 响应式样式
```css
/* 基础样式 */
.container {
padding: 20rpx;
}
/* 小程序适配 */
/* #ifdef MP-WEIXIN || MP-ALIPAY */
.container {
padding: 30rpx; /* 小程序通常需要更大的间距 */
}
/* #endif */
/* H5 适配 */
/* #ifdef H5 */
.container {
max-width: 750rpx;
margin: 0 auto;
}
/* #endif */
/* 电脑端适配 */
@media screen and (min-width: 1025px) {
.container {
max-width: 1200px;
padding: 40rpx;
}
}
```
#### 4.3.2 安全区域适配
```css
/* 底部安全区域 */
.safe-area-bottom {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
/* 顶部安全区域 */
.safe-area-top {
padding-top: constant(safe-area-inset-top);
padding-top: env(safe-area-inset-top);
}
```
### 4.4 功能差异处理
#### 4.4.1 小程序特有功能
```uts
// 小程序特有功能封装
export function initMiniProgramFeatures(): void {
// #ifdef MP-WEIXIN
// 微信小程序更新检查
const updateManager = uni.getUpdateManager()
updateManager.onUpdateReady(() => {
uni.showModal({
title: '更新提示',
content: '新版本已经准备好,是否重启应用?',
success: (res) => {
if (res.confirm) {
updateManager.applyUpdate()
}
}
})
})
// #endif
}
```
#### 4.4.2 App 特有功能
```uts
// App 特有功能封装
export function initAppFeatures(): void {
// #ifdef APP-ANDROID || APP-IOS
// 检查 App 更新
checkAppUpdate()
// 推送通知初始化
initPushNotification()
// #endif
}
```
---
## 五、小程序分包策略
### 5.1 分包配置
```json
// pages.json
{
"pages": [
{
"path": "pages/main/index",
"style": { "navigationBarTitleText": "首页" }
},
{
"path": "pages/main/category",
"style": { "navigationBarTitleText": "分类" }
},
{
"path": "pages/main/cart",
"style": { "navigationBarTitleText": "购物车" }
},
{
"path": "pages/user/center",
"style": { "navigationBarTitleText": "我的" }
}
],
"subPackages": [
{
"root": "pages/mall/consumer",
"pages": [
{
"path": "product-detail",
"style": { "navigationBarTitleText": "商品详情" }
},
{
"path": "checkout",
"style": { "navigationBarTitleText": "结算" }
},
{
"path": "orders",
"style": { "navigationBarTitleText": "订单" }
},
{
"path": "payment",
"style": { "navigationBarTitleText": "支付" }
}
]
}
],
"preloadRule": {
"pages/main/index": {
"network": "all",
"packages": ["pages/mall/consumer"]
}
}
}
```
### 5.2 分包原则
1. **主包**: 仅包含首页、分类、购物车、个人中心等核心页面
2. **分包**: 包含商品详情、订单、支付等次级页面
3. **预加载**: 在首页预加载分包,提升用户体验
---
## 六、测试策略
### 6.1 测试环境配置
| 平台 | 测试工具 | 测试要点 |
|------|---------|---------|
| Android App | 真机调试 | 性能、兼容性、权限 |
| iOS App | 真机调试 | 性能、兼容性、权限 |
| 微信小程序 | 微信开发者工具 | 功能、样式、API |
| 支付宝小程序 | 支付宝开发者工具 | 功能、样式、API |
| H5 | Chrome DevTools | 响应式、兼容性 |
### 6.2 自动化测试
```typescript
// 测试用例示例
describe('多端适配测试', () => {
it('登录功能各端一致', async () => {
// 测试登录逻辑在各端表现一致
})
it('支付功能各端可用', async () => {
// 测试支付功能在各端可用
})
})
```
---
## 七、发布流程
### 7.1 发布检查清单
- [ ] 条件编译代码正确
- [ ] 各端样式适配完成
- [ ] API 调用正常
- [ ] 支付功能测试通过
- [ ] 分包配置正确
- [ ] 包体积符合要求
### 7.2 发布渠道
| 平台 | 发布渠道 | 审核周期 |
|------|---------|---------|
| Android App | 应用商店 / 自有渠道 | 1-3天 |
| iOS App | App Store | 3-7天 |
| 微信小程序 | 微信审核 | 1-3天 |
| 支付宝小程序 | 支付宝审核 | 1-3天 |
| H5 | 自有服务器 | 即时 |
---
## 八、总结
### 推荐方案
**单项目多端编译**,利用 uni-app x 的跨端能力,通过条件编译处理平台差异。
### 关键点
1. 使用条件编译处理平台差异
2. 封装平台适配层统一 API 调用
3. 合理使用分包控制包体积
4. 建立完善的多端测试流程
### 后续优化
1. 持续优化各端性能
2. 完善自动化测试
3. 建立多端 CI/CD 流程

View File

@@ -0,0 +1,85 @@
# 多端用户注册与身份识别实现指南 (Multi-Terminal Registration Guide)
本档说明了如何在当前的 Supabase 架构下实现“消费者端”、“商家端”及“管理端”的统一注册逻辑并确保用户身份Role在入库时能够自动、准确地被识别。
## 1. 核心架构原理
系统采用 **“前端声明意图 + 后端自动触发”** 的模式:
1. **前端 App**:在调用接口注册时,通过 `raw_user_meta_data` 声明用户的目标角色(如 `consumer``merchant`)。
2. **Supabase Auth**:接收并存储这些元数据。
3. **数据库触发器 (Trigger)**:在 `auth.users` 产生新记录的一瞬间,由数据库自动读取元数据,并将用户信息连带其正确的角色属性同步到业务表 `ak_users` 中。
---
## 2. 前端实现步骤 (代码参考)
在各端 App 的注册逻辑中,需在调用 `signUp` 接口时传递 `options.data`
### 消费者端 (Consumer App)
`pages/user/register.uvue` 中:
```typescript
const options = new UTSJSONObject()
const metaData = new UTSJSONObject()
metaData.set('user_role', 'consumer') // 核心:声明为消费者
options.set('data', metaData)
const result = await supa.signUp(email, password, options)
```
### 商家端 (Merchant App)
在商家端的注册页面中,只需修改 `user_role` 的值:
```typescript
metaData.set('user_role', 'merchant') // 核心:声明为商家
```
---
## 3. 数据库实现步骤 (SQL 设置)
为了让数据库能够“看碟下菜”,必须在 Supabase SQL Editor 中运行以下脚本,安装/更新智能触发器:
```sql
-- 1. 创建或更新处理函数
CREATE OR REPLACE FUNCTION public.handle_new_user()
RETURNS trigger AS $$
BEGIN
-- 向业务表插入数据,并智能识别角色
INSERT INTO public.ak_users (id, auth_id, email, role, nickname, status)
VALUES (
NEW.id,
NEW.id, -- 统一使用 Auth ID
NEW.email,
-- 核心逻辑:读取 metadata 中的 user_role如果没有传则默认为 'consumer'
COALESCE(NEW.raw_user_meta_data->>'user_role', 'consumer'),
-- 默认昵称取邮箱前缀
split_part(NEW.email, '@', 1),
1 -- 默认激活状态
);
RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
-- 2. 绑定触发器
DROP TRIGGER IF EXISTS on_auth_user_created ON auth.users;
CREATE TRIGGER on_auth_user_created
AFTER INSERT ON auth.users
FOR EACH ROW EXECUTE FUNCTION public.handle_new_user();
```
---
## 4. 三端互不干扰的优势
* **全自动入库**:一旦 SQL 触发器设置完成,前端不再需要手动调用 `ensureUserProfile``insert` 接口,减少了网络请求和前端报错几率。
* **物理隔离与 RLS 安全**:通过 `ak_users` 表的 RLS 策略(`auth.uid() = id`),确保即使用户通过 API 尝试修改他人数据,也会被数据库直接拦截。
* **统一维护**:所有端的注册逻辑在数据库层面是统一的,未来若需增加新角色(如 `admin_manager`),只需修改触发器逻辑即可,无需大规模重构代码。
---
## 5. 开发建议
* **强制校验**:在生产环境下,可以在触发器内增加校验逻辑,防止普通用户通过伪造元数据获得 `admin` 角色。
* **日志排查**:如果新用户注册后 `ak_users` 表没有数据,请检查 Supabase 控制台的 `Database -> Logs`,查看触发器执行是否有报错(通常是唯一索引冲突导致)。
---
*最后更新时间2026-03-10*

View File

@@ -0,0 +1,119 @@
# 电商平台生产环境上线准备清单 (Production Readiness Checklist)
本指南旨在指导开发者在将“消费者端”和“商家端”推向实际生产环境时,所需准备的各项核心服务申请、资质认定及技术对接点。
---
## 1. 身份认证与登录系统 (Identity & Login)
为了提供丝滑的登录体验,需申请以下第三方服务:
### A. 微信登录 (WeChat Login)
* **主体要求**:必须是企业或个体工商户(个人主体无法开通部分权限)。
* **准备工作**
* 在 [微信开放平台](https://open.weixin.qq.com/) 注册账号并完成 **开发者资质认证** (300元/年)。
* 创建一个“移动应用”获取 `AppID``AppSecret`
* 在 [Supabase 控制台](https://supabase.com/dashboard/project/_/auth/providers) 启用 **WeChat Provider** 并填入上述秘钥。
* **注意**:如果是微信小程序环境,需在 [微信公众平台](https://mp.weixin.qq.com/) 另外申请小程序账号。
### B. 手机短信验证码 (SMS Authentication)
* **推荐方案**:阿里云短信、腾讯云短信 或 Twilio。
* **准备工作**
* **签名申请**如“【XX商城】”需提交营业执照审核。
* **模板申请**:如“验证码${code}您正在进行登录操作5分钟内有效。”
* **Supabase 对接**:在 Auth -> Providers -> Phone 开启,并配置短信服务商提供的 API 秘钥。
---
## 2. 支付与结算系统 (Payments & Settlement)
支付是电商的命脉,涉及非常严格的合规性审核。
### A. 消费者端:支付方式与钱包提醒
* **资质准备**
* **微信支付**:在 [微信支付商户平台](https://pay.weixin.qq.com/) 申请“商户号”,需关联上述微信 AppID。
* **支付宝**:在 [支付宝开放平台](https://open.alipay.com/) 申请“APP支付”或“小程序支付”能力。
* **钱包逻辑实现**
* **余额系统**:在数据库中建立 `user_wallets` 表,记录 `balance`(余额)和 `points`(积分)。
* **支付拦截器**用户下单时需通过后端逻辑Edge Functions校验余额是否足够不足时弹出“余额不足请充值”或“引导去微信支付”。
* **变动提醒**:每当发生消费或退款,需通过 **微信模板消息****App 推送** 发送钱包变动实时通知。
### B. 商家端:收款账号与提现
* **资金流控制**:生产环境下,资金通常先进入平台大账户(二清合规性建议)。
* **提现准备**
* **实名认证**:商家入驻时必须上传 **身份证**、**营业执照**、**开户许可证**。
* **打款接口**:需要申请“微信支付-企业付款到零钱”或“支付宝-单笔转账到账户”能力。
* **手续费逻辑**:需确定平台抽成比例(佣金),在商家点击提现时自动计算并扣除。
---
## 3. 服务器与合规性 (Infrastructure & Compliance)
* **域名备案**:在中国境内运营,必须完成 **ICP 备案**
* **HTTPS 证书**:所有生产接口必须使用 SSL 证书(不能使用 HTTP
* **隐私政策与用户协议**:必须在 App 登录页面显著位置提供,且符合 GDPR 或国内网络安全法规定。
* **CDN 存储**:商品图片和视频应存放在对象存储(如 Supabase Storage + 自定义 CDN 域名),以保证加载速度。
---
## 4. 商家入驻所需材料模板
建议在商家端后台提供以下材料的上传入口:
1. **负责人身份证正反面**
2. **统一社会信用代码证**
3. **银行结算账户信息(开户行、支行名称、账号、持卡人姓名)**
4. **行业特许经营许可**(如卖食品需要《食品经营许可证》)。
---
## 5. 技术架构建议 (Production Stack)
* **数据库保护**:开启 Supabase 的 **RLS (行级安全策略)**,防止数据越权读取。
* **日志记录**:接入 **Sentry****阿里云日志服务**,记录生产环境中的所有前端报错(尤其是支付环节)。
* **压力测试**:上线前需进行接口压力测试,确保在促销活动期间数据库连接数不会爆满。
---
## 6. 无真机调试指南 (iOS & 鸿蒙调试方案)
针对您目前没有 iOS 和鸿蒙HarmonyOS Next实机的情况请务必执行以下**模拟调试流程**,以确保上线后 90% 以上的兼容性。
### A. iOS (苹果) 远程与模拟调试
1. **微信开发者工具“模拟器” (最简便)**:
* 在工具底部左侧选择 `iPhone 13/14 Pro`
* **重点检查**: 底部 Tabbar 是否被 iPhone 的 Home Indicator (底部黑条) 遮挡。如果是,请在 CSS 中使用 `padding-bottom: constant(safe-area-inset-bottom); padding-bottom: env(safe-area-inset-bottom);`
2. **Chrome 浏览器 iOS 仿真 (针对 H5 端)**:
* 将项目运行为 H5开启 Chrome Console (F12)。
* 选择 `iPhone` 设备仿真,手动测试 `v-if` 在不同屏幕高度下的布局抖动。
3. **免费云真机调试 (推荐)**:
* **腾讯云 WeTest / 阿里云移动测试**: 注册后通常有免费试用额度(如 30-60 分钟)。
* **操作**: 上传打包好的 APK (Android) 或在微信内测环境下选择 iOS 云真机,远程控制真机屏幕进行滑屏测试。
### B. 鸿蒙 (HarmonyOS Next) 深度兼容
由于鸿蒙系统现在进入了“纯血”阶段,与 Android 差异变大:
1. **华为开发者联盟“云调试” (官方推荐)**:
* **访问**: [华为远程真机调试](https://developer.huawei.com/consumer/cn/service/jsservicestu/appdebug.html)。
* **步骤**:
1. 注册并完成实名认证。
2. 选择“远程真机”。
3. 申请免费使用的 **Mate 60 / Pura 70 (HarmonyOS Next 预览版)**
* **调试重点**: 鸿蒙系统对 Webview 的内核限制较多,务必通过云真机测试“结算页”和“支付弹窗”是否能正常拉起。
2. **DevEco Studio 远程模拟器**:
* 安装华为官开发的 IDE `DevEco Studio`
* 使用内置的 `Device Manager` 启动 `Remote Emulator`。这比本地模拟器对电脑配置要求低,且渲染效果最接近真机。
### C. 关键代码兼容性“避坑”建议 (无真机必做)
* **日期处理**: 严禁使用 `new Date("2024-03-10")`,在 iOS 上会返回 `Invalid Date`。**必须**统一替换为 `new Date("2024/03/10")``new Date(2024, 2, 10)`
* **图片显示**: iOS 微信小程序对 WebP 格式支持有限,生产环境生产建议优先使用 **JPG/PNG** 或确保 CDN 开启了自适应转换。
* **输入框**: iOS 下 `input``focus` 自动拉起键盘可能会造成页面整体上移或错位,务必通过云真机确认“下单备注”等输入区域。
---
## 7. 微信小程序上线必改项 (Final Checklist)
1. **正式 AppID**: 修改 `manifest.json` 中的 `mp-weixin.appid` 为正式 ID。
2. **域名白名单**: 在微信后台添加 Supabase API 域名、图片 CDN 域名、物流查询域名。
3. **用户隐私政策**: 获取头像、位置等接口前,必须在微信后台配置隐私协议,且在 App 内部提供可见入口。
4. **打包优化**: 检查 `unpackage/dist/build/mp-weixin` 的大小,如超过 2MB必须启用“分包加载”。
---
*生成日期2026-03-10*

View File

@@ -0,0 +1,62 @@
# 商城消费者端 (Consumer) 开发文档
本文档包含了商城消费者前端模块的详细开发指南和状态说明。
## 📂 项目结构
消费者端模块位于 `pages/mall/consumer/` 目录下,基于 UniApp x (UTS/UVUE) 开发。
### 核心页面清单
| 页面文件 | 描述 | 当前状态 |
|-----------|-------------|--------|
| `index.uvue` | 首页 (商城门面) | ✅ 正常 |
| `category.uvue` | 商品分类浏览 | ✅ 正常 |
| `cart.uvue` | 购物车 | ✅ 正常 |
| `profile.uvue` | 个人中心 (用户主页) | ✅ 正常 |
| `orders.uvue` | 订单列表管理 | ✅ 正常 |
| `order-detail.uvue` | 订单详情页 | ✅ 正常 |
| `apply-refund.uvue` | 申请售后 (退款/退货) | ✅ 正常 |
| `refund.uvue` | 售后记录列表 | ✅ 正常 |
| `chat.uvue` | 在线客服 | ✅ 正常 |
| `messages.uvue` | 消息通知中心 | ✅ 正常 |
### 关键功能实现
1. **用户个人中心**:
* 可视化展示用户状态(积分、余额)。
* 订单状态快捷入口(待支付、待发货、待收货等)。
* **我的服务**: 优惠券、地址、收藏夹。
* **新功能**: 已集成“评价”入口(跳转至待评价订单)和“退款/售后”入口(跳转至售后记录页)。
2. **订单管理**:
* 多状态标签页切换(全部、待支付、待收货、已完成)。
* **操作**: 支付、取消、提醒发货、确认收货、评价、**申请售后**。
*`supabaseService` 后端服务实时交互。
3. **售后系统**:
* 独立页面 `apply-refund.uvue`:支持仅退款/退货退款,关联原订单金额。
* 售后列表 `refund.uvue`:查看历史退款记录及进度。
4. **客服与消息**:
* 在线客服 `chat.uvue`:支持文本/表情发送,消息持久化存储。
* 消息中心 `messages.uvue`:聚合系统通知与客服消息。
## 🛠 技术栈
* **框架**: UniApp x (Vue 3 + UTS)
* **后端**: Supabase (PostgreSQL)
* **语言**: UTS (TypeScript 方言)
* **样式**: SCSS / UVUE Styles
## 🚀 快速开始
1. **环境准备**: 确保已安装 HBuilderX 并配置好 UniApp x 插件。
2. **数据库**: 运行 `doc_mall/consumer/sql/` 下的 SQL 脚本初始测试数据。
3. **运行**: 在 HBuilderX 中打开项目,运行到 Web 浏览器或 App 模拟器。
## 📚 文档索引
* [功能与页面状态详解](./FEATURES_&_PAGES.md)
* [Supabase 集成与数据库架构](./SUPABASE_INTEGRATION.md)
* [测试数据生成指南](./MOCK_DATA_GUIDE.md)

View File

@@ -0,0 +1,235 @@
# 智能推荐系统文档
## 一、系统概述
智能推荐系统基于用户行为数据,为用户提供个性化的商品推荐。系统综合分析用户的搜索历史、浏览历史,结合全站热销商品数据,生成智能推荐列表。
## 二、推荐逻辑架构
```
┌─────────────────────────────────────────────────────────────┐
│ 智能推荐系统 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 用户搜索历史 │ │ 用户浏览历史 │ │ 全站热销商品 │ │
│ │ (权重高) │ │ (权重中) │ │ (权重低) │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 关键词匹配 │ │ 分类匹配 │ │ 销量排序 │ │
│ │ 相关商品 │ │ 相似商品 │ │ 热门商品 │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ └────────────────┼────────────────┘ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ 去重 & 合并结果 │ │
│ └──────────┬──────────┘ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ 返回推荐商品列表 │ │
│ └─────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
```
## 三、权重分配策略
### 3.1 数据源权重
| 数据源 | 权重 | 说明 |
|--------|------|------|
| 用户搜索历史 | 50% | 用户主动搜索的关键词最能反映购买意向 |
| 用户浏览历史 | 30% | 用户浏览过的商品分类反映兴趣偏好 |
| 热销商品 | 20% | 全站热销商品作为兜底和补充 |
### 3.2 推荐优先级
```
优先级 1: 用户搜索历史匹配的商品最多占推荐列表的50%
优先级 2: 用户浏览过的分类下的商品最多占推荐列表的30%
优先级 3: 全站热销商品(填充剩余位置)
```
## 四、核心算法详解
### 4.1 智能推荐主流程
```typescript
async getSmartRecommendations(limit: number): Promise<Product[]> {
const products: Product[] = []
const addedIds = new Set<string>() // 用于去重
// 步骤1: 根据用户搜索历史推荐(权重最高)
const searchHistory = await getUserSearchHistory(5)
if (searchHistory.length > 0) {
const keywordProducts = await searchProductsByKeywords(searchHistory, limit)
// 添加到结果列表,去重
}
// 步骤2: 根据用户浏览历史推荐(权重中)
if (products.length < limit) {
const browseCategories = await getUserBrowseCategories(3)
if (browseCategories.length > 0) {
const categoryProducts = await getProductsByCategories(browseCategories, limit - products.length)
// 添加到结果列表,去重
}
}
// 步骤3: 补充热销商品(权重低)
if (products.length < limit) {
const hotProducts = await getHotProducts(limit - products.length + 5)
// 添加到结果列表,去重
}
return products.slice(0, limit)
}
```
### 4.2 搜索历史匹配算法
```typescript
// 根据用户搜索关键词匹配商品
async searchProductsByKeywords(keywords: string[], limit: number): Promise<Product[]> {
// 1. 获取商品数据
// 2. 遍历商品,检查名称和描述是否包含关键词
// 3. 匹配成功的商品加入推荐列表
for (product in products) {
for (keyword in keywords) {
if (product.name.contains(keyword) || product.description.contains(keyword)) {
matched = true
break
}
}
}
}
```
### 4.3 浏览历史分类匹配算法
```typescript
// 根据用户浏览过的商品分类推荐
async getProductsByCategories(categoryIds: string[], limit: number): Promise<Product[]> {
// 1. 获取用户浏览过的商品分类ID列表
// 2. 查询这些分类下的商品
// 3. 按销量排序返回
}
```
## 五、热搜词系统
### 5.1 热搜词计算
```typescript
async getHotKeywords(limit: number): Promise<string[]> {
// 1. 获取最近100条搜索记录
// 2. 统计每个关键词的出现频率
// 3. 按频率降序排序
// 4. 返回前N个高频关键词
}
```
### 5.2 热搜词展示规则
| 排名 | 样式 | 说明 |
|------|------|------|
| 1-3名 | 红色背景 | 热度最高,突出显示 |
| 4-10名 | 灰色背景 | 普通热度 |
## 六、用户行为记录
### 6.1 搜索行为记录
```typescript
// 在用户执行搜索时调用
async recordSearch(keyword: string, resultCount: number): Promise<void> {
// 记录字段:
// - user_id: 用户ID可选支持匿名
// - keyword: 搜索关键词
// - result_count: 搜索结果数量
// - created_at: 搜索时间
}
```
### 6.2 浏览行为记录
```typescript
// 在用户查看商品详情时调用
async recordBrowse(productId: string, duration: number): Promise<void> {
// 记录字段:
// - user_id: 用户ID
// - product_id: 商品ID
// - browse_duration: 浏览时长(秒)
// - created_at/updated_at: 时间戳
}
```
## 七、数据表结构
### 7.1 搜索历史表 (ml_search_history)
| 字段 | 类型 | 说明 |
|------|------|------|
| id | UUID | 主键 |
| user_id | UUID | 用户ID可空 |
| keyword | VARCHAR(200) | 搜索关键词 |
| result_count | INTEGER | 搜索结果数量 |
| created_at | TIMESTAMP | 搜索时间 |
### 7.2 浏览历史表 (ml_browse_history)
| 字段 | 类型 | 说明 |
|------|------|------|
| id | UUID | 主键 |
| user_id | UUID | 用户ID |
| product_id | UUID | 商品ID |
| browse_duration | INTEGER | 浏览时长(秒) |
| created_at | TIMESTAMP | 首次浏览时间 |
| updated_at | TIMESTAMP | 最近浏览时间 |
## 八、API接口列表
| API | 方法 | 说明 |
|-----|------|------|
| getSmartRecommendations | GET | 获取智能推荐商品 |
| getHotKeywords | GET | 获取热搜词列表 |
| getUserSearchHistory | GET | 获取用户搜索历史 |
| getUserBrowseCategories | GET | 获取用户浏览分类 |
| recordSearch | POST | 记录搜索行为 |
| recordBrowse | POST | 记录浏览行为 |
## 九、性能优化建议
### 9.1 缓存策略
- 热搜词列表缓存5分钟减少数据库查询
- 用户搜索历史缓存10分钟
- 推荐结果缓存3分钟
### 9.2 数据量控制
- 搜索历史每个用户最多保留100条
- 浏览历史每个用户最多保留50条
- 热搜词统计只统计最近30天的数据
## 十、扩展方向
### 10.1 短期优化
1. **时间衰减因子**:近期行为权重更高
2. **购买行为加权**:已购买商品的相关商品权重提升
3. **收藏行为加权**:收藏商品的相关商品权重提升
### 10.2 长期规划
1. **协同过滤**:基于相似用户的行为推荐
2. **商品相似度**:基于商品属性计算相似度
3. **机器学习**:使用推荐算法模型
---
*文档版本1.0*
*最后更新2024年*

View File

@@ -0,0 +1,121 @@
# Supabase 集成与数据库架构 (Consumer App)
本文档详细描述了消费者端 (Consumer App) 涉及的所有数据库集成点、核心表结构以及 `supabaseService.uts` 提供的 API 服务。
> **更新时间**: 2026-02-03
> **状态**: 已完成核心业务闭环 (订单、支付、售后、客服、足迹等)
## 🗄️ 核心数据架构
消费者端业务依赖以下核心数据库表:
### 1. 交易与订单 (Orders & Transactions)
| 表名 | 描述 | 关键字段 |
| :--- | :--- | :--- |
| `ml_orders` | 订单主表 | `id`, `user_id`, `merchant_id`, `order_status` (1:待付, 2:待发, 3:待收, 4:完成, 5:取消), `total_amount` |
| `ml_order_items` | 订单商品明细 | `order_id`, `product_id`, `image_url` (快照), `specifications` (快照) |
| `ml_refunds` | **[新增]** 售后/退款申请 | `order_id`, `reason_category`, `refund_amount`, `status` (0:待审, 1:同意, 2:拒绝), `refund_type` (1:仅退款, 2:退货退款) |
### 2. 互动与消息 (Interaction & Communication)
| 表名 | 描述 | 关键字段 |
| :--- | :--- | :--- |
| `ml_chat_messages` | **[新增]** 客服聊天记录 | `session_id`, `sender_id`, `receiver_id`, `content`, `msg_type`, `is_from_user` |
| `ml_notifications` | 消息通知 | `type` (system/order/promotion), `title`, `is_read` |
| `ml_product_reviews` | 商品评价 | `order_id`, `product_id`, `rating`, `content`, `images` |
### 3. 用户行为 (User Behavior)
| 表名 | 描述 | 关键字段 |
| :--- | :--- | :--- |
| `ml_browsing_history` | 足迹/浏览记录 | `user_id`, `product_id`, `view_time` |
| `ml_favorites` | 收藏夹 | `user_id`, `target_id`, `type` (1:商品, 2:店铺) |
| `ml_user_addresses` | 收货地址 | `user_id`, `receiver_name`, `phone`, `province`... |
---
## 🔌 API 服务层 (`utils/supabaseService.uts`)
所有后端交互通过单例 `supabaseService` 进行,主要模块如下:
### 1. 售后/退款服务 (Refunds)
> **状态**: ✅ 已集成 (apply-refund.uvue)
```typescript
// 创建退款/售后申请
async createRefund(data: {
order_id: string,
refund_type: number,
refund_amount: number,
reason_category: string,
description: string,
images: string[]
}): Promise<boolean>
```
### 2. 在线客服/消息服务 (Chat & Messages)
> **状态**: ✅ 已集成 (chat.uvue, messages.uvue)
```typescript
// 获取当前用户的聊天记录
async getUserChatMessages(): Promise<ChatMessage[]>
// 发送聊天消息 (持久化到 ml_chat_messages)
async sendChatMessage(content: string, type: string = 'text'): Promise<boolean>
// (测试用) 模拟客服自动回复
async simulateServiceReply(content: string): Promise<boolean>
```
### 3. 订单与支付 (Orders & Payment)
> **状态**: ✅ 已集成 (checkout.uvue, payment.uvue, orders.uvue)
```typescript
// 创建订单 (由购物车或直接购买触发)
async createOrder(orderData: any): Promise<string | null>
// 获取订单详情 (包含商品明细)
async getOrderDetail(orderId: string): Promise<any | null>
// 支付订单 (模拟支付,更新订单状态 1->2记录支付时间)
async payOrder(orderId: string, paymentMethod: string, amount: number): Promise<boolean>
// 确认收货 (3->4)
async confirmReceipt(orderId: string): Promise<Result>
```
### 4. 商品与搜索 (Products)
> **状态**: ✅ 已集成 (search.uvue, product-detail.uvue)
```typescript
// 搜索商品 (支持关键词、分类、价格排序、销量排序)
async searchProducts(keyword: string, page: number, pageSize: number, sort: string, asc: boolean): Promise<PaginatedResponse<Product>>
// 获取足迹
async getFootprints(): Promise<any[]>
```
---
## 📊 页面集成状态一览表
| 页面模块 | 文件路径 | 数据源状态 | 说明 |
| :--- | :--- | :--- | :--- |
| **首页** | `pages/mall/consumer/index.uvue` | ✅ Real DB | 金刚区、推荐商品已接入 |
| **搜索** | `pages/mall/consumer/search.uvue` | ✅ Real DB | 关键词搜索、排序、分页正常 |
| **购物车** | `pages/mall/consumer/cart.uvue` | ✅ Real DB | 加减购、结算校验正常 |
| **结算台** | `pages/mall/consumer/checkout.uvue` | ✅ Real DB | 地址选择、订单创建正常 |
| **收银台** | `pages/mall/consumer/payment.uvue` | ✅ Real DB | 读取待付金额,更新支付状态 |
| **订单列表** | `pages/mall/consumer/orders.uvue` | ✅ Real DB | 状态筛选 (全部/待付/待收/退款) 正常 |
| **订单详情** | `pages/mall/consumer/order-detail.uvue` | ✅ Real DB | 地址、商品、金额展示正常 |
| **申请售后** | `pages/mall/consumer/apply-refund.uvue` | ✅ Real DB | **[本次完成]** 关联订单金额,提交至 `ml_refunds` |
| **在线客服** | `pages/mall/consumer/chat.uvue` | ✅ Real DB | **[本次完成]** 消息收发持久化,支持历史记录 |
| **消息中心** | `pages/mall/consumer/messages.uvue` | ✅ Real DB | 能够统计未读客服消息数 |
| **我的评价** | `pages/mall/consumer/review.uvue` | ✅ Real DB | 提交评价至 `ml_product_reviews` |
## 🛠️ 下一步维护建议
1. **异常处理**: 目前部分接口在网络异常时仅打印 `console.error`,建议增加全局统一的 Toasts 提示。
2. **图片上传**: 目前退款和评价中的图片上传依赖 Mock 或简单路径,需对接真实的 OSS/Supabase Storage 文件上传。
3. **实时消息**: 目前 `chat.uvue` 使用 polling (轮询) 或手动刷新Supabase 支持 Realtime Subscription后续可升级为 WebSocket 实时推送。

View File

@@ -0,0 +1,386 @@
# 多人协作多端开发方案
## 一、问题分析
### 1.1 当前协作场景
```
团队成员分工:
├── 开发者A → 消费者端 (consumer)
├── 开发者B → 商家端 (merchant)
├── 开发者C → 管理端 (admin)
├── 开发者D → 分析端 (analytics)
└── 开发者E → 配送端 (delivery)
```
### 1.2 潜在冲突问题
如果每个人都在 `manifest.json``pages.json` 中修改配置:
- ❌ Git 合并冲突频繁
- ❌ 互相覆盖配置
- ❌ 影响其他端的编译
---
## 二、推荐方案:端专用配置文件
### 2.1 核心思路
**不修改公共配置文件,而是创建端专用的配置文件**
```
mall/
├── pages.json # 主配置(保持不变,供 App 端使用)
├── manifest.json # 主配置(保持不变)
├── config/ # 端专用配置目录
│ ├── consumer/ # 消费者端配置
│ │ ├── pages.json # 消费者端页面配置
│ │ └── manifest.json # 消费者端小程序配置
│ │
│ ├── merchant/ # 商家端配置
│ │ ├── pages.json
│ │ └── manifest.json
│ │
│ ├── admin/ # 管理端配置
│ │ ├── pages.json
│ │ └── manifest.json
│ │
│ ├── analytics/ # 分析端配置
│ │ ├── pages.json
│ │ └── manifest.json
│ │
│ └── delivery/ # 配送端配置
│ ├── pages.json
│ └── manifest.json
└── scripts/ # 构建脚本
├── build-consumer.sh # 消费者端构建脚本
├── build-merchant.sh # 商家端构建脚本
└── ...
```
### 2.2 优势
| 优势 | 说明 |
|------|------|
| ✅ 无冲突 | 每个开发者只修改自己端的配置文件 |
| ✅ 独立发布 | 各端可独立编译和发布 |
| ✅ 代码共享 | 页面代码仍在同一仓库,便于共享 |
| ✅ 向后兼容 | 主配置文件保持不变,不影响 App 端 |
---
## 三、具体实施
### 3.1 创建端专用配置目录
```bash
# 创建配置目录结构
mkdir -p config/consumer
mkdir -p config/merchant
mkdir -p config/admin
mkdir -p config/analytics
mkdir -p config/delivery
```
### 3.2 消费者端配置示例
#### config/consumer/pages.json
```json
{
"pages": [
{
"path": "pages/user/login",
"style": { "navigationBarTitleText": "登录" }
},
{
"path": "pages/main/index",
"style": { "navigationBarTitleText": "首页", "navigationStyle": "custom" }
},
{
"path": "pages/main/category",
"style": { "navigationBarTitleText": "分类", "navigationStyle": "custom" }
},
{
"path": "pages/main/cart",
"style": { "navigationBarTitleText": "购物车", "navigationStyle": "custom" }
},
{
"path": "pages/main/profile",
"style": { "navigationBarTitleText": "我的", "navigationStyle": "custom" }
}
],
"subPackages": [
{
"root": "pages/mall/consumer",
"pages": [
{ "path": "product-detail", "style": { "navigationBarTitleText": "商品详情" } },
{ "path": "shop-detail", "style": { "navigationBarTitleText": "店铺详情" } },
{ "path": "search", "style": { "navigationBarTitleText": "搜索" } },
{ "path": "checkout", "style": { "navigationBarTitleText": "结算" } },
{ "path": "payment", "style": { "navigationBarTitleText": "支付" } },
{ "path": "orders", "style": { "navigationBarTitleText": "订单" } },
{ "path": "order-detail", "style": { "navigationBarTitleText": "订单详情" } },
{ "path": "favorites", "style": { "navigationBarTitleText": "收藏" } },
{ "path": "coupons", "style": { "navigationBarTitleText": "优惠券" } },
{ "path": "address-list", "style": { "navigationBarTitleText": "地址管理" } },
{ "path": "address-edit", "style": { "navigationBarTitleText": "编辑地址" } },
{ "path": "chat", "style": { "navigationBarTitleText": "客服" } },
{ "path": "points/index", "style": { "navigationBarTitleText": "积分" } },
{ "path": "member/index", "style": { "navigationBarTitleText": "会员" } },
{ "path": "wallet", "style": { "navigationBarTitleText": "钱包" } },
{ "path": "settings", "style": { "navigationBarTitleText": "设置" } }
]
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "商城",
"navigationBarBackgroundColor": "#ffffff",
"backgroundColor": "#f5f5f5"
},
"tabBar": {
"color": "#999999",
"selectedColor": "#ff5000",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"list": [
{ "pagePath": "pages/main/index", "text": "首页", "iconPath": "static/tabbar/home.png", "selectedIconPath": "static/tabbar/home-active.png" },
{ "pagePath": "pages/main/category", "text": "分类", "iconPath": "static/tabbar/category.png", "selectedIconPath": "static/tabbar/category-active.png" },
{ "pagePath": "pages/main/cart", "text": "购物车", "iconPath": "static/tabbar/cart.png", "selectedIconPath": "static/tabbar/cart-active.png" },
{ "pagePath": "pages/main/profile", "text": "我的", "iconPath": "static/tabbar/profile.png", "selectedIconPath": "static/tabbar/profile-active.png" }
]
}
}
```
#### config/consumer/manifest.json
```json
{
"name": "商城消费者端",
"appid": "__UNI__CONSUMER",
"description": "商城消费者端小程序",
"versionName": "1.0.0",
"versionCode": "100",
"mp-weixin": {
"appid": "wx_consumer_appid",
"setting": {
"urlCheck": false,
"es6": true,
"postcss": true,
"minified": true
},
"usingComponents": true,
"optimization": {
"subPackages": true
}
}
}
```
### 3.3 构建脚本
#### scripts/build-consumer.sh
```bash
#!/bin/bash
# 消费者端小程序构建脚本
# 复制消费者端配置到根目录
cp config/consumer/pages.json pages.json
cp config/consumer/manifest.json manifest.json
# 执行编译
uni build -p mp-weixin
# 编译完成后恢复原配置(可选)
# git checkout pages.json manifest.json
echo "消费者端小程序构建完成!"
```
#### scripts/dev-consumer.sh
```bash
#!/bin/bash
# 消费者端开发脚本
# 复制消费者端配置到根目录
cp config/consumer/pages.json pages.json
cp config/consumer/manifest.json manifest.json
# 启动开发服务器
uni -p mp-weixin
echo "消费者端开发环境已启动!"
```
---
## 四、Git 协作策略
### 4.1 .gitignore 配置
```gitignore
# 编译产物
unpackage/
# 临时配置文件(可选)
# 如果不想提交临时替换的配置,可以忽略
# pages.json
# manifest.json
```
### 4.2 分支策略
```
main # 主分支(稳定版本)
├── develop # 开发分支
│ ├── feature/consumer # 消费者端功能分支
│ ├── feature/merchant # 商家端功能分支
│ ├── feature/admin # 管理端功能分支
│ └── ...
└── release/consumer # 消费者端发布分支
```
### 4.3 提交规范
```
feat(consumer): 添加会员功能
fix(merchant): 修复订单列表bug
docs(admin): 更新管理端文档
style(analytics): 优化分析端样式
```
---
## 五、HBuilderX 配置(推荐)
### 5.1 创建多个运行配置
在 HBuilderX 中,可以为每个端创建独立的运行配置:
**运行 → 运行到小程序模拟器 → 消费者端微信小程序**
配置文件:`.hbuilderx/launch.json`
```json
{
"version": "0.0.1",
"configurations": [
{
"name": "消费者端-微信小程序",
"type": "uni-app",
"platform": "mp-weixin",
"args": {
"pages": "config/consumer/pages.json",
"manifest": "config/consumer/manifest.json"
}
},
{
"name": "商家端-微信小程序",
"type": "uni-app",
"platform": "mp-weixin",
"args": {
"pages": "config/merchant/pages.json",
"manifest": "config/merchant/manifest.json"
}
}
]
}
```
---
## 六、团队协作流程
### 6.1 开发流程
```
1. 拉取最新代码
git pull origin develop
2. 创建功能分支
git checkout -b feature/consumer/member-function
3. 开发(只修改消费者端相关文件)
- 修改 pages/mall/consumer/*.uvue
- 修改 config/consumer/pages.json如需添加新页面
4. 提交代码
git add .
git commit -m "feat(consumer): 添加会员功能"
5. 推送并创建 PR
git push origin feature/consumer/member-function
```
### 6.2 编译发布流程
```
1. 切换到发布分支
git checkout release/consumer
2. 执行构建脚本
./scripts/build-consumer.sh
3. 上传小程序代码
微信开发者工具 → 上传
4. 提交审核
微信公众平台 → 提交审核
```
---
## 七、注意事项
### 7.1 共享代码修改
如果修改了共享代码(如 `utils/``components/``types/`),需要:
1. 通知相关开发者
2. 确保不影响其他端
3. 在 PR 中详细说明
### 7.2 配置文件同步
如果主 `pages.json` 有公共页面更新,需要同步到各端的配置文件:
```bash
# 同步公共页面配置
./scripts/sync-common-pages.sh
```
### 7.3 冲突处理
如果发生配置冲突:
1. 优先保留各端专用配置
2. 合并公共配置
3. 团队沟通确认
---
## 八、总结
### 推荐方案
**端专用配置文件 + 构建脚本**
### 核心优势
| 优势 | 说明 |
|------|------|
| ✅ 无冲突 | 每个开发者只修改自己端的配置 |
| ✅ 体积可控 | 每个端只编译自己需要的页面 |
| ✅ 独立发布 | 各端可独立发布小程序 |
| ✅ 代码共享 | 页面代码仍在同一仓库 |
### 目录结构
```
config/
├── consumer/ # 消费者端配置开发者A维护
├── merchant/ # 商家端配置开发者B维护
├── admin/ # 管理端配置开发者C维护
├── analytics/ # 分析端配置开发者D维护
└── delivery/ # 配送端配置开发者E维护
```

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,216 @@
# 微信小程序审核优化方案
## 一、问题分析
### 1.1 审核未通过项
| 问题 | 说明 | 限制 |
|------|------|------|
| 主包尺寸 | 主包体积超过限制 | ≤ 2MB |
| 组件按需注入 | 未启用组件按需注入 | 需要配置 |
| 图片音频资源 | 静态资源过大 | 建议使用 CDN |
---
## 二、优化方案
### 2.1 主包尺寸优化
#### 当前问题
主包包含了太多页面,需要进一步分包。
#### 解决方案:进一步分包
修改 `config/consumer/pages.json`
```json
{
"pages": [
// 只保留最核心的页面在主包
{ "path": "pages/user/login" },
{ "path": "pages/main/index" }
],
"subPackages": [
{
"root": "pagesub/user",
"pages": [
{ "path": "register" },
{ "path": "forgot-password" },
{ "path": "profile" },
{ "path": "center" }
]
},
{
"root": "pagesub/main",
"pages": [
{ "path": "category" },
{ "path": "cart" },
{ "path": "profile" }
]
},
{
"root": "pages/mall/consumer",
"pages": [
// 消费者端所有页面
]
}
]
}
```
### 2.2 启用组件按需注入
修改 `config/consumer/pages.json`,添加:
```json
{
"easycom": {
"autoscan": true,
"custom": {
"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
}
},
"optimization": {
"subPackages": true
}
}
```
修改 `config/consumer/manifest.json`
```json
{
"mp-weixin": {
"appid": "",
"setting": {
"urlCheck": false,
"es6": true,
"postcss": true,
"minified": true,
"enhance": true
},
"usingComponents": true,
"optimization": {
"subPackages": true
},
"lazyCodeLoading": "requiredComponents"
}
}
```
### 2.3 图片资源优化
#### 方案 A使用 CDN 托管图片
1.`static/` 目录下的图片上传到 CDN
2. 代码中使用 CDN 链接
```javascript
// 修改前
<image src="/static/images/default-product.png" />
// 修改后
<image src="https://cdn.your-domain.com/images/default-product.png" />
```
#### 方案 B压缩图片
使用工具压缩图片:
- TinyPNG: https://tinypng.com/
- 智图: https://zhitu.isux.us/
#### 方案 C使用 WebP 格式
微信小程序支持 WebP 格式,体积更小。
---
## 三、具体修改
### 3.1 修改 manifest.json
```json
{
"mp-weixin": {
"appid": "",
"setting": {
"urlCheck": false,
"es6": true,
"postcss": true,
"minified": true,
"enhance": true
},
"usingComponents": true,
"optimization": {
"subPackages": true
},
"lazyCodeLoading": "requiredComponents"
}
}
```
### 3.2 修改 pages.json
添加优化配置:
```json
{
"optimization": {
"subPackages": true
}
}
```
---
## 四、优化检查清单
### 4.1 主包优化
- [ ] 只保留登录页和首页在主包
- [ ] 其他页面移到分包
- [ ] 检查主包体积 < 2MB
### 4.2 组件优化
- [ ] 启用 `lazyCodeLoading`
- [ ] 启用 `enhance`
- [ ] 检查组件按需加载
### 4.3 资源优化
- [ ] 图片使用 CDN
- [ ] 压缩图片
- [ ] 移除未使用的资源
---
## 五、快速修复
### 5.1 修改 manifest.json启用组件按需注入
`mp-weixin` 配置中添加:
```json
"lazyCodeLoading": "requiredComponents"
```
### 5.2 图片优化
1. 删除未使用的图片
2. 压缩现有图片
3. 考虑使用 CDN
---
## 六、预期效果
| 优化项 | 优化前 | 优化后 |
|--------|--------|--------|
| 主包体积 | 可能 > 2MB | < 1.5MB |
| 组件加载 | 全量加载 | 按需加载 |
| 图片资源 | 本地存储 | CDN 托管 |
---
## 七、注意事项
1. 分包后页面路径会变化,需要更新跳转逻辑
2. CDN 图片需要确保域名已备案
3. 测试分包后功能是否正常

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,296 @@
# 商城推销模式功能需求文档
## 一、功能概述
本文档描述商城消费者端的推销模式功能,**该功能为商家级别功能**,即:
- **商家可自主开启/关闭**自己店铺的推销模式
- 只有**开启了推销模式的商家**,其店铺订单才会显示"分享免单"按钮
- **会员等级系统**为全局功能,适用于所有商家
- **经销点返利系统**为商家级别功能,由商家自行配置
### 1.1 核心变更说明
| 功能模块 | 作用范围 | 说明 |
|---------|---------|------|
| 分享免单系统 | 商家级别 | 商家开启后,其订单才显示分享免单入口 |
| 会员等级系统 | 全局 | 所有用户统一等级体系 |
| 经销点返利系统 | 商家级别 | 商家自行创建和管理经销点 |
| 用户余额系统 | 商家级别 | 每个商家有独立的用户余额池 |
---
## 二、商家推销模式配置
### 2.1 商家推销设置表 ml_merchant_promotion_config
| 字段名 | 类型 | 说明 |
|--------|------|------|
| id | UUID | 主键 |
| merchant_id | UUID | 商家ID关联ml_shops.merchant_id |
| promotion_enabled | BOOLEAN | 是否开启推销模式默认false |
| share_free_enabled | BOOLEAN | 是否开启分享免单默认false |
| distribution_enabled | BOOLEAN | 是否开启经销点返利默认false |
| required_count | INT | 分享免单所需购买数默认4 |
| reward_type | VARCHAR(20) | 奖励类型product_price-商品价格fixed-固定金额 |
| fixed_reward_amount | DECIMAL(10,2) | 固定奖励金额reward_type=fixed时使用 |
| created_at | TIMESTAMPTZ | 创建时间 |
| updated_at | TIMESTAMPTZ | 更新时间 |
### 2.2 商家用户余额表 ml_merchant_user_balance
> 每个商家的用户余额独立计算,用户在不同商家有不同余额
| 字段名 | 类型 | 说明 |
|--------|------|------|
| id | UUID | 主键 |
| merchant_id | UUID | 商家ID |
| user_id | UUID | 用户ID |
| balance | DECIMAL(10,2) | 当前余额 |
| frozen_balance | DECIMAL(10,2) | 冻结余额 |
| total_earned | DECIMAL(10,2) | 累计获得 |
| total_withdrawn | DECIMAL(10,2) | 累计提现 |
| updated_at | TIMESTAMPTZ | 更新时间 |
| UNIQUE(merchant_id, user_id) | | 联合唯一约束 |
---
## 三、分享免单系统
### 3.1 功能描述
用户购买商品后,可分享商品链接给其他用户(二级用户)。当二级用户通过分享链接购买该商品累计达到指定数量时,原用户可获得免单奖励。
**重要变更:**
- 只有开启了分享免单功能的商家,其订单才显示分享免单入口
- 分享免单所需购买数由商家自行设置默认4人
- 奖励金额可以是商品价格或固定金额
### 3.2 业务流程
```
商家开启推销模式 → 用户购买商品 → 订单详情显示"分享免单"按钮
用户点击创建分享记录
分享给好友B/C/D
好友通过分享码购买
累计购买数量达标
用户获得免单奖励
奖励存入该商家下的用户余额
```
### 3.3 数据库设计
#### 3.3.1 分享记录表 ml_share_records
| 字段名 | 类型 | 说明 |
|--------|------|------|
| id | UUID | 主键 |
| merchant_id | UUID | 商家ID新增 |
| user_id | UUID | 分享用户ID |
| product_id | UUID | 商品ID |
| order_id | UUID | 关联订单ID |
| share_code | VARCHAR(20) | 分享码(唯一) |
| required_count | INT | 需要的购买数量 |
| current_count | INT | 当前已购买数量 |
| status | INT | 状态0-进行中1-已完成2-已失效 |
| reward_amount | DECIMAL(10,2) | 奖励金额 |
| created_at | TIMESTAMPTZ | 创建时间 |
| completed_at | TIMESTAMPTZ | 完成时间 |
#### 3.3.2 二级购买记录表 ml_secondary_purchases
| 字段名 | 类型 | 说明 |
|--------|------|------|
| id | UUID | 主键 |
| share_record_id | UUID | 关联分享记录ID |
| buyer_id | UUID | 购买用户ID |
| order_id | UUID | 订单ID |
| quantity | INT | 购买数量 |
| created_at | TIMESTAMPTZ | 创建时间 |
#### 3.3.3 免单奖励记录表 ml_free_order_rewards
| 字段名 | 类型 | 说明 |
|--------|------|------|
| id | UUID | 主键 |
| merchant_id | UUID | 商家ID新增 |
| user_id | UUID | 获得奖励的用户ID |
| share_record_id | UUID | 关联分享记录ID |
| amount | DECIMAL(10,2) | 奖励金额 |
| status | INT | 状态0-待处理1-已发放2-已清零 |
| cleared_at | TIMESTAMPTZ | 清零时间 |
| cleared_by | UUID | 清零操作人 |
| created_at | TIMESTAMPTZ | 创建时间 |
### 3.4 前端逻辑变更
#### 3.4.1 订单列表页/订单详情页
```typescript
// 判断是否显示分享免单按钮
async function checkShareFreeEnabled(merchantId: string): Promise<boolean> {
const config = await supabaseService.getMerchantPromotionConfig(merchantId)
return config?.promotion_enabled && config?.share_free_enabled
}
// 在订单卡片中
<view v-if="order.status >= 2 && order.status <= 4 && isShareFreeEnabled(order.merchant_id)"
class="share-free-row" @click="shareForFree(order)">
<text>🎁 </text>
</view>
```
#### 3.4.2 我的余额页
- 需要按商家分组显示余额
- 或显示总余额,点击查看各商家余额明细
---
## 四、会员等级系统
### 4.1 功能描述
会员等级系统为**全局功能**,用户等级在所有商家通用。用户可通过累计消费金额自动升级,或由商家手动设置等级。
### 4.2 等级设置(全局配置)
| 等级 | 名称 | 升级条件 | 折扣 |
|------|------|---------|------|
| 0 | 普通会员 | 注册即可 | 无折扣 |
| 1 | 铜牌会员 | 累计消费500元 | 98折 |
| 2 | 银牌会员 | 累计消费2000元 | 95折 |
| 3 | 金牌会员 | 累计消费5000元 | 92折 |
| 4 | 钻石会员 | 累计消费10000元 | 88折 |
| 5 | VIP会员 | 商家手动设置 | 85折 |
### 4.3 数据库设计
保持原有设计不变,会员等级为全局配置。
---
## 五、经销点返利系统
### 5.1 功能描述
商家可创建多个经销点,每个经销点有独立的推广码。经销点通过推广码产生的订单可获得返利。
**重要变更:**
- 经销点返利为商家级别功能
- 商家需先开启经销点功能才能使用
### 5.2 数据库设计
#### 5.2.1 经销点表 ml_distribution_points
| 字段名 | 类型 | 说明 |
|--------|------|------|
| id | UUID | 主键 |
| merchant_id | UUID | 商家ID新增 |
| name | VARCHAR(100) | 经销点名称 |
| contact_name | VARCHAR(50) | 联系人 |
| contact_phone | VARCHAR(20) | 联系电话 |
| invite_code | VARCHAR(20) | 邀请码(唯一) |
| owner_id | UUID | 负责人用户ID |
| status | INT | 状态0-禁用1-启用 |
| total_orders | INT | 累计订单数 |
| total_rebate | DECIMAL(10,2) | 累计返利 |
| balance | DECIMAL(10,2) | 可提现余额 |
| created_at | TIMESTAMPTZ | 创建时间 |
---
## 六、余额变动记录表
### 6.1 ml_balance_records按商家区分
| 字段名 | 类型 | 说明 |
|--------|------|------|
| id | UUID | 主键 |
| merchant_id | UUID | 商家ID新增 |
| user_id | UUID | 用户ID |
| type | VARCHAR(50) | 类型 |
| amount | DECIMAL(10,2) | 变动金额 |
| balance_before | DECIMAL(10,2) | 变动前余额 |
| balance_after | DECIMAL(10,2) | 变动后余额 |
| related_id | UUID | 关联ID |
| description | VARCHAR(200) | 描述 |
| operator_id | UUID | 操作人 |
| created_at | TIMESTAMPTZ | 创建时间 |
---
## 七、API 接口变更
### 7.1 新增接口
| 接口 | 方法 | 说明 |
|------|------|------|
| /api/merchant/promotion-config | GET | 获取商家推销配置 |
| /api/merchant/user-balance | GET | 获取用户在某商家的余额 |
| /api/merchant/user-balance-list | GET | 获取用户所有商家余额列表 |
### 7.2 修改接口
| 接口 | 变更说明 |
|------|---------|
| /api/share/create | 新增merchant_id参数 |
| /api/share/my-records | 按merchant_id筛选 |
| /api/balance/info | 新增merchant_id参数 |
---
## 八、前端页面变更
### 8.1 消费者端
| 页面 | 变更说明 |
|------|---------|
| 订单列表/详情 | 根据商家配置显示分享免单按钮 |
| 我的余额 | 按商家分组显示余额,或显示余额列表 |
| 我的分享 | 按商家筛选分享记录 |
### 8.2 商家端(新增)
| 页面 | 说明 |
|------|------|
| 推销模式设置 | 开启/关闭分享免单、经销点功能 |
| 用户余额管理 | 查看用户余额、清零操作 |
| 经销点管理 | 创建、编辑经销点 |
---
## 九、开发优先级
### 第一阶段
1. 商家推销配置表SQL
2. 修改用户余额表结构(按商家区分)
3. 修改分享记录表结构添加merchant_id
4. 前端:根据商家配置显示分享免单按钮
### 第二阶段
1. 商家端推销模式设置页面
2. 用户余额按商家分组显示
3. 经销点返利系统
---
## 十、SQL变更清单
需要执行以下SQL变更
1. **新增商家推销配置表** `ml_merchant_promotion_config`
2. **修改用户余额表** 添加merchant_id字段改为联合唯一约束
3. **修改分享记录表** 添加merchant_id字段
4. **修改余额记录表** 添加merchant_id字段
5. **修改免单奖励表** 添加merchant_id字段
6. **修改经销点表** 添加merchant_id字段
详细SQL语句见`promotion_system_tables_v2.sql`

View File

@@ -0,0 +1,629 @@
# 商城消费者端 - 积分与评价功能完善需求文档
## 一、项目概述
### 1.1 项目背景
本项目为商城消费者端应用,当前积分和评价功能已有基础实现,但存在部分功能缺失和体验优化空间。本文档旨在明确积分和评价功能的完善需求。
### 1.2 当前实现状态
| 功能模块 | 当前状态 | 说明 |
|---------|---------|------|
| 消费者端积分页面 | ✅ 已完成 | 显示积分余额、积分明细列表 |
| 积分兑换商城 | ❌ 未实现 | 点击"积分兑换"提示"开发中" |
| 消费者端商品评价 | ✅ 已完成 | 支持评分、文字、图片、匿名评价 |
| 消费者端店铺评价 | ✅ 已完成 | 支持描述/物流/服务三维评分 |
| 商家端评价管理 | ✅ 已完成 | 支持查看、筛选、回复评价 |
---
## 二、积分功能完善需求
### 2.1 功能架构图
```
┌─────────────────────────────────────────────────────────────┐
│ 积分系统架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 积分获取 │ │ 积分使用 │ │ 积分管理 │ │
│ ├─────────────┤ ├─────────────┤ ├─────────────┤ │
│ │ • 注册赠送 │ │ • 积分兑换 │ │ • 积分查询 │ │
│ │ • 每日签到 │ │ • 订单抵扣 │ │ • 明细记录 │ │
│ │ • 购物奖励 │ │ • 积分抽奖 │ │ • 过期处理 │ │
│ │ • 评价奖励 │ │ │ │ • 积分规则 │ │
│ │ • 邀请好友 │ │ │ │ │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
```
### 2.2 前端功能需求
#### 2.2.1 积分首页优化
**页面路径**: `pages/mall/consumer/points/index.uvue`
**需求描述**:
1. **积分概览卡片**
- 显示当前可用积分
- 显示即将过期积分30天内
- 显示历史累计积分
- 积分趋势图表近7天/30天
2. **快捷入口**
- 签到入口(带签到状态提示)
- 积分兑换入口
- 积分规则说明
3. **积分明细列表**
- 支持按类型筛选(获取/消费/过期)
- 支持按时间范围筛选
- 下拉刷新、上拉加载更多
#### 2.2.2 每日签到功能(新增)
**页面路径**: `pages/mall/consumer/points/signin.uvue`
**需求描述**:
1. **签到日历**
- 显示当月签到记录
- 连续签到天数统计
- 签到奖励预览
2. **签到奖励规则**
- 每日签到:+5积分
- 连续签到7天额外+20积分
- 连续签到30天额外+100积分
3. **签到弹窗**
- 签到成功动画
- 显示获得积分
- 连续签到进度提示
#### 2.2.3 积分兑换商城(新增)
**页面路径**: `pages/mall/consumer/points/exchange.uvue`
**需求描述**:
1. **兑换商品列表**
- 优惠券兑换
- 实物商品兑换
- 虚拟商品兑换(会员权益等)
2. **商品详情**
- 商品图片、名称、描述
- 兑换所需积分
- 库存状态
- 兑换记录
3. **兑换流程**
- 积分不足提示
- 确认兑换弹窗
- 兑换成功/失败反馈
- 物流跟踪(实物商品)
#### 2.2.4 积分规则页面(新增)
**页面路径**: `pages/mall/consumer/points/rules.uvue`
**需求描述**:
- 积分获取规则说明
- 积分使用规则说明
- 积分有效期说明
- 常见问题FAQ
### 2.3 后端API需求
#### 2.3.1 新增API接口
| 接口名称 | 请求方法 | 接口路径 | 说明 |
|---------|---------|---------|------|
| 签到 | POST | `/api/points/signin` | 用户每日签到 |
| 获取签到记录 | GET | `/api/points/signin-records` | 获取月度签到记录 |
| 获取兑换商品列表 | GET | `/api/points/exchange-products` | 获取可兑换商品 |
| 积分兑换 | POST | `/api/points/exchange` | 兑换商品 |
| 获取兑换记录 | GET | `/api/points/exchange-records` | 获取兑换历史 |
| 积分过期提醒 | GET | `/api/points/expiring` | 获取即将过期积分 |
#### 2.3.2 接口详细设计
**签到接口**
```typescript
// 请求
POST /api/points/signin
Response: {
success: boolean
points: number // 本次获得积分
continuous_days: number // 连续签到天数
bonus_points: number // 额外奖励积分
total_points: number // 当前总积分
}
```
**积分兑换接口**
```typescript
// 请求
POST /api/points/exchange
Body: {
product_id: string // 兑换商品ID
quantity: number // 兑换数量
address_id?: string // 收货地址(实物商品)
}
Response: {
success: boolean
exchange_id: string // 兑换记录ID
points_used: number // 消耗积分
remaining_points: number // 剩余积分
}
```
### 2.4 数据库设计
#### 2.4.1 现有表结构
**用户积分表 (ml_user_points)**
```sql
CREATE TABLE IF NOT EXISTS ml_user_points (
user_id UUID NOT NULL PRIMARY KEY REFERENCES auth.users(id),
points INT DEFAULT 0 NOT NULL, -- 当前可用积分
total_earned INT DEFAULT 0, -- 历史累计获得积分
total_used INT DEFAULT 0, -- 历史累计使用积分
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- 添加索引
CREATE INDEX idx_user_points_user_id ON ml_user_points(user_id);
```
**积分记录表 (ml_point_records)**
```sql
CREATE TABLE IF NOT EXISTS ml_point_records (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
user_id UUID NOT NULL REFERENCES auth.users(id),
points INT NOT NULL, -- 变动积分 (正/负)
balance INT NOT NULL, -- 变动后余额
type VARCHAR(50) NOT NULL, -- 类型
reference_id UUID, -- 关联ID订单ID/兑换ID等
description TEXT,
expires_at TIMESTAMPTZ, -- 过期时间
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- 添加索引
CREATE INDEX idx_point_records_user_id ON ml_point_records(user_id);
CREATE INDEX idx_point_records_type ON ml_point_records(type);
CREATE INDEX idx_point_records_created_at ON ml_point_records(created_at);
```
#### 2.4.2 新增表结构
**签到记录表 (ml_signin_records)**
```sql
CREATE TABLE IF NOT EXISTS ml_signin_records (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
user_id UUID NOT NULL REFERENCES auth.users(id),
signin_date DATE NOT NULL, -- 签到日期
points_earned INT DEFAULT 0, -- 获得积分
bonus_points INT DEFAULT 0, -- 奖励积分
continuous_days INT DEFAULT 1, -- 当次连续签到天数
created_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(user_id, signin_date) -- 每用户每天只能签到一次
);
-- 添加索引
CREATE INDEX idx_signin_records_user_id ON ml_signin_records(user_id);
CREATE INDEX idx_signin_records_date ON ml_signin_records(signin_date);
```
**积分兑换商品表 (ml_point_products)**
```sql
CREATE TABLE IF NOT EXISTS ml_point_products (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
name VARCHAR(200) NOT NULL, -- 商品名称
description TEXT, -- 商品描述
image_url VARCHAR(500), -- 商品图片
product_type VARCHAR(50) NOT NULL, -- 类型: coupon/physical/virtual
points_required INT NOT NULL, -- 所需积分
original_price DECIMAL(10,2), -- 原价(展示用)
stock INT DEFAULT 0, -- 库存
status INT DEFAULT 1, -- 状态: 0=下架, 1=上架
sort_order INT DEFAULT 0, -- 排序
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
```
**积分兑换记录表 (ml_point_exchanges)**
```sql
CREATE TABLE IF NOT EXISTS ml_point_exchanges (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
user_id UUID NOT NULL REFERENCES auth.users(id),
product_id UUID NOT NULL REFERENCES ml_point_products(id),
quantity INT DEFAULT 1, -- 兑换数量
points_used INT NOT NULL, -- 消耗积分
status INT DEFAULT 0, -- 状态: 0=待处理, 1=已发货, 2=已完成, 3=已取消
tracking_no VARCHAR(100), -- 物流单号
address_id UUID, -- 收货地址
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
```
**积分规则配置表 (ml_point_rules)**
```sql
CREATE TABLE IF NOT EXISTS ml_point_rules (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
rule_type VARCHAR(50) NOT NULL, -- 规则类型
rule_name VARCHAR(100) NOT NULL, -- 规则名称
points INT NOT NULL, -- 积分值
description TEXT, -- 规则说明
config JSONB, -- 扩展配置
status INT DEFAULT 1, -- 状态
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- 初始化规则数据
INSERT INTO ml_point_rules (rule_type, rule_name, points, description) VALUES
('register', '注册赠送', 100, '新用户注册赠送积分'),
('signin_daily', '每日签到', 5, '每日签到获得积分'),
('signin_continuous_7', '连续签到7天奖励', 20, '连续签到7天额外奖励'),
('signin_continuous_30', '连续签到30天奖励', 100, '连续签到30天额外奖励'),
('shopping', '购物奖励', 1, '每消费1元获得1积分'),
('review', '评价奖励', 10, '完成商品评价获得积分'),
('review_with_image', '带图评价奖励', 20, '带图评价额外奖励');
```
---
## 三、评价功能完善需求
### 3.1 功能架构图
```
┌─────────────────────────────────────────────────────────────┐
│ 评价系统架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 评价提交 │ │ 评价展示 │ │ 评价管理 │ │
│ ├─────────────┤ ├─────────────┤ ├─────────────┤ │
│ │ • 商品评价 │ │ • 商品详情 │ │ • 商家回复 │ │
│ │ • 店铺评价 │ │ • 评价列表 │ │ • 评价统计 │ │
│ │ • 配送评价 │ │ • 评分统计 │ │ • 违规处理 │ │
│ │ • 追加评价 │ │ • 筛选排序 │ │ • 评价审核 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
```
### 3.2 前端功能需求
#### 3.2.1 评价页面优化
**页面路径**: `pages/mall/consumer/review.uvue`
**需求描述**:
1. **评价表单优化**
- 支持视频上传限1个30秒内
- 支持图片拖拽排序
- 添加评价标签选择(质量好/物流快/服务好等)
- 添加商品满意度维度(质量/包装/性价比)
2. **追加评价功能**
- 订单完成后7天内可追加评价
- 追加评价入口(订单详情页)
- 追加评价表单
3. **评价预览**
- 提交前预览评价效果
- 匿名评价预览效果
#### 3.2.2 商品评价列表(新增)
**页面路径**: `pages/mall/consumer/product-reviews.uvue`
**需求描述**:
1. **评价统计概览**
- 好评率百分比
- 评分分布图1-5星
- 标签云(高频评价关键词)
2. **评价列表**
- 支持按评分筛选
- 支持按时间/点赞数排序
- 支持只看有图/有视频评价
- 评价点赞功能
- 评价举报功能
3. **评价详情**
- 点击评价查看详情
- 查看商家回复
- 查看追加评价
#### 3.2.3 我的评价页面(新增)
**页面路径**: `pages/mall/consumer/my-reviews.uvue`
**需求描述**:
1. **评价列表**
- 显示已评价商品
- 显示待评价商品
- 显示可追加评价商品
2. **评价操作**
- 编辑评价24小时内
- 删除评价
- 追加评价
#### 3.2.4 配送员评价(完善)
**页面路径**: `pages/mall/delivery/ratings.uvue`
**需求描述**:
- 对接真实API当前使用Mock数据
- 配送员评分统计
- 配送评价列表
### 3.3 后端API需求
#### 3.3.1 新增API接口
| 接口名称 | 请求方法 | 接口路径 | 说明 |
|---------|---------|---------|------|
| 获取商品评价列表 | GET | `/api/reviews/product/:productId` | 分页获取商品评价 |
| 获取评价统计 | GET | `/api/reviews/stats/:productId` | 获取商品评分统计 |
| 追加评价 | POST | `/api/reviews/append` | 追加评价内容 |
| 评价点赞 | POST | `/api/reviews/like/:id` | 点赞评价 |
| 获取我的评价 | GET | `/api/reviews/my` | 获取用户评价列表 |
| 编辑评价 | PUT | `/api/reviews/:id` | 编辑评价24小时内 |
| 删除评价 | DELETE | `/api/reviews/:id` | 删除评价 |
| 评价举报 | POST | `/api/reviews/report/:id` | 举报违规评价 |
#### 3.3.2 接口详细设计
**获取商品评价列表**
```typescript
GET /api/reviews/product/:productId?page=1&limit=10&rating=5&has_image=true
Response: {
total: number
page: number
limit: number
data: [{
id: string
user_name: string
user_avatar: string
rating: number
content: string
images: string[]
videos: string[]
tags: string[]
like_count: number
is_liked: boolean
reply: {
content: string
created_at: string
}
append_content?: {
content: string
created_at: string
}
created_at: string
}]
}
```
**获取评价统计**
```typescript
GET /api/reviews/stats/:productId
Response: {
total_count: number
avg_rating: number
good_rate: number // 好评率
rating_distribution: { // 评分分布
1: number
2: number
3: number
4: number
5: number
}
tags: [{ // 高频标签
name: string
count: number
}]
}
```
### 3.4 数据库设计
#### 3.4.1 现有表结构优化
**商品评价表 (ml_product_reviews)**
```sql
-- 添加新字段
ALTER TABLE ml_product_reviews ADD COLUMN IF NOT EXISTS videos JSONB DEFAULT '[]';
ALTER TABLE ml_product_reviews ADD COLUMN IF NOT EXISTS tags JSONB DEFAULT '[]';
ALTER TABLE ml_product_reviews ADD COLUMN IF NOT EXISTS like_count INT DEFAULT 0;
ALTER TABLE ml_product_reviews ADD COLUMN IF NOT EXISTS is_edited BOOLEAN DEFAULT false;
ALTER TABLE ml_product_reviews ADD COLUMN IF NOT EXISTS append_content TEXT;
ALTER TABLE ml_product_reviews ADD COLUMN IF NOT EXISTS append_at TIMESTAMPTZ;
ALTER TABLE ml_product_reviews ADD COLUMN IF NOT EXISTS append_images JSONB DEFAULT '[]';
```
#### 3.4.2 新增表结构
**评价点赞表 (ml_review_likes)**
```sql
CREATE TABLE IF NOT EXISTS ml_review_likes (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
review_id UUID NOT NULL REFERENCES ml_product_reviews(id),
user_id UUID NOT NULL REFERENCES auth.users(id),
created_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(review_id, user_id) -- 每用户对每条评价只能点赞一次
);
CREATE INDEX idx_review_likes_review_id ON ml_review_likes(review_id);
```
**评价举报表 (ml_review_reports)**
```sql
CREATE TABLE IF NOT EXISTS ml_review_reports (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
review_id UUID NOT NULL REFERENCES ml_product_reviews(id),
user_id UUID NOT NULL REFERENCES auth.users(id),
reason VARCHAR(200) NOT NULL, -- 举报原因
description TEXT, -- 详细说明
status INT DEFAULT 0, -- 状态: 0=待处理, 1=已处理, 2=已驳回
handle_result TEXT, -- 处理结果
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
```
**配送员评价表 (ml_delivery_ratings)**
```sql
CREATE TABLE IF NOT EXISTS ml_delivery_ratings (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
order_id UUID NOT NULL REFERENCES ml_orders(id),
delivery_user_id UUID NOT NULL, -- 配送员ID
user_id UUID NOT NULL REFERENCES auth.users(id),
rating INT CHECK (rating >= 1 AND rating <= 5),
content TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(order_id) -- 每订单只能评价一次
);
```
---
## 四、开发优先级
### 4.1 第一阶段(高优先级)
| 序号 | 功能 | 模块 | 预估工时 |
|-----|------|------|---------|
| 1 | 每日签到功能 | 积分 | 2天 |
| 2 | 积分兑换商城 | 积分 | 3天 |
| 3 | 商品评价列表展示 | 评价 | 2天 |
| 4 | 我的评价页面 | 评价 | 1天 |
### 4.2 第二阶段(中优先级)
| 序号 | 功能 | 模块 | 预估工时 |
|-----|------|------|---------|
| 1 | 积分规则配置 | 积分 | 1天 |
| 2 | 追加评价功能 | 评价 | 1天 |
| 3 | 评价点赞功能 | 评价 | 0.5天 |
| 4 | 配送员评价对接 | 评价 | 1天 |
### 4.3 第三阶段(低优先级)
| 序号 | 功能 | 模块 | 预估工时 |
|-----|------|------|---------|
| 1 | 积分过期提醒 | 积分 | 0.5天 |
| 2 | 评价视频上传 | 评价 | 1天 |
| 3 | 评价举报功能 | 评价 | 0.5天 |
| 4 | 管理端完善 | 综合 | 2天 |
---
## 五、技术要点
### 5.1 积分系统技术要点
1. **积分并发安全**
- 使用数据库事务保证积分变动原子性
- 添加乐观锁防止超扣
2. **积分过期处理**
- 定时任务每日检查过期积分
- 过期前7天推送提醒通知
3. **签到防刷**
- 限制每日只能签到一次
- 记录签到IP检测异常行为
### 5.2 评价系统技术要点
1. **评价数据统计**
- 使用触发器自动更新商品评分统计
- 缓存热门商品评价数据
2. **图片/视频处理**
- 图片压缩后上传
- 视频转码处理
- CDN加速访问
3. **敏感词过滤**
- 评价内容敏感词检测
- 自动替换或人工审核
---
## 六、测试要点
### 6.1 积分功能测试
- [ ] 签到功能:每日签到、连续签到奖励
- [ ] 积分兑换:积分不足、库存不足、兑换成功
- [ ] 积分过期:自动过期、过期提醒
- [ ] 并发测试:同时兑换、同时签到
### 6.2 评价功能测试
- [ ] 评价提交:文字、图片、视频、匿名
- [ ] 评价展示:列表、筛选、排序
- [ ] 评价操作:编辑、删除、追加、点赞
- [ ] 边界测试:空内容、超长内容、敏感词
---
## 七、附录
### 7.1 相关文件路径
```
pages/
├── mall/
│ └── consumer/
│ ├── points/
│ │ ├── index.uvue # 积分首页(已有)
│ │ ├── signin.uvue # 签到页面(新增)
│ │ ├── exchange.uvue # 兑换商城(新增)
│ │ └── rules.uvue # 积分规则(新增)
│ ├── review.uvue # 评价页面(已有)
│ ├── product-reviews.uvue # 商品评价列表(新增)
│ └── my-reviews.uvue # 我的评价(新增)
└── user/
└── login.uvue # 登录页面
utils/
└── supabaseService.uts # API服务
types/
└── mall-types.uts # 类型定义
doc_mall/
└── consumer/
└── sql/
├── 01_wallet_and_points.sql
└── add_reviews_tables.sql
```
### 7.2 参考文档
- [Supabase 官方文档](https://supabase.com/docs)
- [uni-app x 开发文档](https://doc.dcloud.net.cn/uni-app-x/)
- [UTS 语法指南](https://doc.dcloud.net.cn/uni-app-x/uts/)
---
**文档版本**: v1.0
**创建日期**: 2026-03-05
**最后更新**: 2026-03-05