# 自营网店（shop）

自营网店插件面向自有渠道在线销售：插件后台负责商品、营销、会员与履约，买家通过独立前台完成浏览、加购、结算、支付、收货与售后前流程。

- 商家后台：`/app/shop/`（插件 `shop` 已安装并启用后出现在左侧导航）
- 买家前台：`/app/shop/store.html?seller={卖家用户ID}`
- 买家前台不依赖插件中间件，平台会员登录后即可下单，方便把店铺链接分享给其他会员
- 支付参数与云商城、会员升级共用后台「设置 → 支付」

## 一、能力概览

### 买家前台（PC / 手机）

| 模块 | 说明 |
| --- | --- |
| 店铺首页 | 渐隐幻灯片（自动轮播 + 指示点）、公告条、服务标签、物流说明、分类入口、热销 / 新品商品网格 |
| 商品 | 实物 / 虚拟商品、主图与轮播图、规格 SKU、库存与销量、图文详情；列表封面可点开 3D 环绕大图，左右切换 |
| 分类 | 分类封面与筛选、关键词搜索、默认 / 销量 / 价格排序、分页 |
| 购物车 | 勾选结算、数量加减、删除、清空、角标同步 |
| 地址簿 | 新增、编辑、删除、设为默认；按「卖家 + 买家」隔离 |
| 优惠券 | 可用券筛选、最低消费、每人限领、固定金额 / 折扣券 |
| 结算 | 地址、优惠券、支付方式、备注；服务端重算金额、满减、运费与包邮门槛 |
| 支付 | 微信支付 V3 Native 扫码、支付宝电脑网站支付；二维码本地生成，支付结果轮询 + 服务端查单兜底 |
| 订单 | 状态筛选、详情、取消、去支付、物流时间轴、确认收货 |
| 虚拟商品 | 支付成功后自动完成订单，并把卡密 / 下载地址写入物流时间轴 |

移动端在 `≤720px` 切换为底部 5 个 Tab（首页 / 分类 / 购物车 / 订单 / 我的），顶部横向导航隐藏。

### 商家后台

- 商品管理：实物 / 虚拟类型、主图、轮播图、虚拟发货内容、价格、库存、上下架
- 分类管理：分类封面、排序、启停
- 规格库存：SKU 价格与库存
- 订单列表：状态筛选、搜索、置为已付款、发货（物流公司 + 运单号）、完成
- 店铺设置：店铺名称、Logo、运费、包邮门槛、支付方式、主题、店铺状态、首页幻灯片、首页公告、服务标签、物流说明
- 店铺装修：3 套风格预览，PC 1024×780 / 手机 680×1024
- 概览页「店铺前台」按钮直接打开买家前台

首页幻灯片在店铺设置中按行填写，也可直接点「上传组图」批量上传图片后自动追加：

```text
图片地址|标题|副标题|跳转链接
```

上传后的每一行只包含图片地址，可继续补齐标题、副标题与跳转链接；点击预览缩略图可打开 3D 大图。

未配置幻灯片时，自动取销量最高的 3 个商品主图作为幻灯片。

## 二、图片、3D 大图与可视化编辑器

### 商品图片

- 商品管理列表首列展示主图与最多 2 张轮播图缩略图，点击任意缩略图打开 3D 环绕大图
- 3D 大图支持左右按钮、键盘 ← / →、圆点跳转、点击侧边图片环绕切换，Esc 或点击遮罩关闭
- 买家前台商品列表点击封面、商品详情点击主图，同样打开 3D 环绕大图
- 商品主图与轮播图均在编辑弹窗内直接上传，图片写入 `app/uploads/shop/{用户ID}/`，单张上限 8MB，支持 JPG / PNG / GIF / WEBP
- 轮播图支持一次选择多张、预览移除、点击预览打开 3D 大图，也可继续手工填写图片地址

### 本地化编辑器插件

店铺设置新增「编辑器插件管理」，内置 3 个本地编辑器，资源位于 `app/shop/editors/`，不依赖 CDN：

| 引擎 | 名称 | 说明 |
| --- | --- | --- |
| `quill` | Quill 富文本 | 标题、加粗、列表、引用、链接与正文配图上传 |
| `pell` | Pell 极简 | 体积最小，基础格式，打开速度快 |
| `suneditor` | SunEditor 中文 | 中文工具栏，支持颜色、对齐等排版 |

- 每个编辑器可单独启用 / 停用，至少保留一个
- 点击卡片切换当前使用的编辑器，商品详情的「内容」字段会按当前编辑器加载
- 编辑器加载失败时自动回退纯文本编辑并给出提示，不影响保存
- 编辑器内部配图走 `shop/upload`，与商品图片共用上传目录

## 三、订单与履约流程

订单统一写入平台订单总线 `p_platform_orders` / `p_platform_order_items`：

- `user_id`：卖家（店铺所有者）
- `buyer_user_id`：买家
- `source`：`shop`
- `source_order_id`：`SHOP...`，与订单号 `NO...` 同时保留

### 实物商品

1. 买家下单，订单 `pending`，扣减库存与销量
2. 支付成功 → `paid` / `pay_status=paid`，写支付流水与时间轴
3. 商家在订单列表点「发货」，填写物流公司、运单号 → `shipped`
4. 买家在订单详情或「查看物流」查看时间轴
5. 买家确认收货 → `completed`
6. 未支付订单可取消，库存、销量与优惠券使用量回滚

### 虚拟商品

1. 下单与支付流程同上，虚拟商品无需收货地址
2. 支付成功且订单全部为虚拟商品时，自动置为 `completed`
3. 商品 `virtual_content` 写入物流时间轴，买家在订单详情即可看到卡密 / 下载地址

### 状态说明

| 状态 | 前台展示 | 可执行操作 |
| --- | --- | --- |
| `pending` | 待付款 | 去支付、取消订单 |
| `paid` / `packed` | 待发货 | 等待卖家发货 |
| `shipped` | 待收货 | 查看物流、确认收货 |
| `completed` | 已完成 | 查看详情 / 物流 |
| `cancelled` | 已取消 | 查看详情 |

## 四、支付配置

后台「设置 → 支付」填写微信支付与支付宝参数后，前台结算页自动出现对应渠道：

| 渠道 | 模式 | 必填参数 |
| --- | --- | --- |
| 微信支付 | Native 扫码 | `enabled`、`app_id`、`mch_id`、`api_v3_key`（32 位）、`serial_no`、商户 API 私钥；可选 `notify_url` |
| 支付宝 | 电脑网站支付 | `enabled`、`app_id`、RSA2 应用私钥、支付宝公钥；可选 `notify_url` |

回调地址：

```text
微信：https://www.example.com/api/index.php?r=pay/store/wechat
支付宝异步：https://www.example.com/api/index.php?r=pay/store/alipay
支付宝同步：https://www.example.com/api/index.php?r=pay/store/alipay/return
```

- 后台「站点设置 → 站点访问地址」必须为正式 HTTPS 域名，回调与同步跳转据此生成
- 未配置或未启用支付时，结算页提示「在线支付暂未启用」，订单仍会创建为待付款，可联系卖家付款
- 支付成功为幂等操作，重复回调不会重复记账或重复发货

## 五、数据表

| 表 | 用途 |
| --- | --- |
| `p_shop_settings` | 店铺设置（幻灯片、公告、服务标签、物流说明、运费、包邮门槛、编辑器与编辑器插件） |
| `p_shop_categories` | 分类与封面 |
| `p_shop_products` | 商品（`type` 实物 / 虚拟、`gallery` 轮播图 JSON、`virtual_content` 发货内容） |
| `p_shop_skus` | 规格与库存 |
| `p_shop_coupons` | 优惠券 |
| `p_shop_promotions` / `p_shop_freebies` / `p_shop_lottery` | 满减、限时免费、抽奖 |
| `p_shop_addresses` | 买家地址簿（按卖家 + 买家隔离） |
| `p_shop_cart` | 购物车（`seller_id + buyer_id + product_id + sku_id` 唯一） |
| `p_shop_payments` | 网店支付流水 |
| `p_shop_logistics` | 订单物流时间轴 |
| `p_platform_orders` / `p_platform_order_items` | 平台订单总线（`source=shop`） |

新增表与列由 `OOO\Services\SchemaMigrator` 幂等补齐，执行：

```bash
php api/bin/migrate.php
```

## 六、部署清单

```text
api/routes.php
api/src/Platform/OrderBus.php
api/src/Services/SchemaMigrator.php
api/src/Services/Payment/GatewayPaymentService.php
api/src/Services/Payment/MembershipPaymentService.php
api/src/Services/Cloud/PaymentService.php
api/src/Services/Payment/ShopStorePaymentService.php
api/src/Services/ShopStore/ShopStoreService.php
api/src/Http/Controllers/ShopStoreController.php
api/src/Http/Controllers/ShopStorePayController.php
api/plugins/shop/src/Controller.php
api/plugins/shop/routes.php
api/plugins/shop/manifest.json
app/shop/index.html
app/shop/store.html
app/shop/editors/
app/css/shop-store.css
app/js/shop-store.js
app/js/module-shop.js
admin/pay-guide.html
```

部署后：

1. 执行 `php api/bin/migrate.php`
2. 清理缓存（`api/data/cache/*` 或后台「清理缓存」）
3. 在后台「店铺设置」配置幻灯片、公告、服务标签、物流说明与运费
4. 打开 `/app/shop/store.html?seller={卖家ID}` 验证 PC 与手机版
5. 支付参数启用后，用最小金额完成一笔真实支付，验证回调、发货与确认收货

## 七、常见问题

- **前台 404 / 店铺未开通**：确认 `p_shop_settings.status='on'`，且链接中的 `seller` 为卖家用户 ID
- **结算没有支付渠道**：检查后台支付参数是否完整并启用；未配置时前台会明确提示
- **支付成功订单仍待付款**：查看 `p_shop_payments` 是否有 `pending` 记录；前台会轮询 `store/pay-status`，服务端会主动查单
- **虚拟商品没有自动完成**：确认商品 `type='virtual'`；混合订单需全部商品为虚拟才会自动完成
- **手机版看不到底部 Tab**：确认页面宽度 ≤720px，且 `app/css/shop-store.css` 已更新
- **商品图片上传失败**：确认 `app/uploads/shop/` 可写，图片不超过 8MB 且为 JPG / PNG / GIF / WEBP
- **编辑器显示为纯文本**：确认 `app/shop/editors/` 下资源已上传；也可在「店铺设置 → 编辑器插件管理」切换到其他编辑器
