# 定制眼镜前端对接后端方案与接口文档

## 一、文档目标

本文面向前端开发，按 `软件开发需求功能点.md` 和 `doc/jykj` 下现有方案，整理当前定制眼镜 ERP 后端设计、页面功能、状态口径和接口对接方式。

覆盖模块：

1. Shopify 订单同步与定制参数解析。
2. 订单面板与定制履约进度。
3. 镜框备货/采购。
4. 镜片委外与供应商门户。
5. 组装、质检、成品入库。
6. 生产看板与大屏。
7. 物流下单、扫码发货、物流轨迹、Shopify 发货同步。
8. 客户眼镜档案、客户分析和复购提醒。
9. 红人客户与红人寄样订单。

## 二、通用约定

### 2.1 接口前缀

后台接口统一使用：

```text
/admin/...
```

所有接口走后台登录态、公司权限、菜单权限。

供应商门户不是独立 Open 接口，供应商仍沿用 Admin 登录逻辑，通过菜单权限控制可见页面，通过供应商数据范围过滤控制可见数据。

### 2.2 返回格式

后端统一返回：

```json
{
  "code": 0,
  "msg": "SUCCESS",
  "data": {},
  "rid": "request-id",
  "version": "...",
  "env": "..."
}
```

前端判断成功以 `code === 0` 为准。

### 2.3 通用 CRUD

大多数模型支持通用 CRUD：

```text
GET  /admin/{module}/index
GET  /admin/{module}/detail?id={id}
GET  /admin/{module}/fetch
POST /admin/{module}/add
POST /admin/{module}/edit
POST /admin/{module}/delete
GET  /admin/{module}/export
```

本文只列出前端需要重点关注的模块和专项动作接口。

### 2.4 分页

列表接口通常返回：

```json
{
  "data": [],
  "current_page": 1,
  "per_page": 20,
  "total": 100,
  "last_page": 5
}
```

常用参数：

```text
page
per_page
keyword
sort
order
```

## 三、核心后端模型

### 3.1 订单层

| 模型 | 表 | 说明 |
| --- | --- | --- |
| `SaleOrder` | `sale_order` | 销售订单，Shopify 订单同步后落在这里 |
| `SaleOrderDetail` | `sale_order_detail` | 销售订单明细 |
| `Customer` | `customer` | 客户、红人客户都复用该表 |
| `ThirdShop` | `third_shop` | Shopify 等第三方店铺 |
| `Channel` | `channel` | 销售渠道，关联第三方店铺 |

### 3.2 定制履约编排层

| 模型 | 表 | 说明 |
| --- | --- | --- |
| `CustomOrderItem` | `custom_order_item` | 一副眼镜/一个定制成品履约单元 |
| `CustomItemComponent` | `custom_item_component` | 履约部件，如镜框、左镜片、右镜片 |
| `CustomItemProcess` | `custom_item_process` | 履约工序，如镜片入库、组装、质检、成品入库 |
| `CustomProcessLog` | `custom_process_log` | 状态变更、异常、回退、人工操作日志 |

### 3.3 真实业务单据层

`custom_*` 表只做流程编排，真实业务动作仍复用 ERP 单据：

| 业务 | 表/模型 |
| --- | --- |
| 镜框采购 | `purchase_plan_detail`、`purchase_order`、`purchase_order_detail` |
| 镜片委外 | `entrust` |
| 组装/生产 | `production_receipt`、`production_receipt_process` 或轻量 `custom_item_process` |
| 质检 | `qc_receipt` 或轻量 `custom_item_process` |
| 入库/出库 | `repository_receipt`、`repository_receipt_detail` |
| 库存冻结 | `repository_freeze_log` |
| 快递面单 | `express_task` |
| 物流轨迹 | `express_tracking_log` |

## 四、定制履约主流程

### 4.1 后端流程

```text
Shopify订单同步
  -> 创建 sale_order / sale_order_detail / customer
  -> 解析眼镜定制参数
  -> 生成 custom_order_item
  -> 生成 custom_item_component：frame / lens_left / lens_right
  -> 生成 custom_item_process：lens_stock_in / assemble / qc / stock_in
  -> 订单审核通过
  -> 镜框库存锁定或生成采购计划
  -> 镜片生成委外单
  -> 供应商生产镜片并寄回
  -> 委外接收入库
  -> 部件齐套后启动组装
  -> 组装完成后质检
  -> 质检通过后成品入库
  -> 生成发货计划
  -> 快递下单/打印面单
  -> 扫码发货
  -> 同步 Shopify 状态和快递单号
```

### 4.2 前端页面建议

| 页面 | 主要数据 |
| --- | --- |
| 销售订单列表/订单面板 | 销售订单、定制履约摘要、镜框/镜片/整单状态、异常标识 |
| 销售订单详情 | 履约单元、部件、工序、日志、原始定制参数 |
| 镜框采购页 | 镜框部件、库存状态、采购计划、供应商比价、采购进度 |
| 镜片委外页 | 委外单、供应商、镜片定制参数、预计交期、物流单号 |
| 供应商门户 | 分配给当前供应商的委外单和镜片行 |
| 组装工单页 | 组装工序、部件齐套状态、执行人、开始/完成/异常 |
| 质检工单页 | 质检工序、通过/不通过、返工、异常 |
| 成品入库页 | 成品入库工序、入库动作、发货计划触发 |
| 物流发货页 | 发货计划、快递任务、面单打印、扫码发货、轨迹 |
| 生产看板/大屏 | 生产进度、异常、超期、小组统计 |

## 五、状态枚举

### 5.1 定制履约单元状态：`custom_order_item.status`

| 值 | 前端展示 |
| --- | --- |
| `0` | 待处理 |
| `10` | 准备中 |
| `20` | 组装中 |
| `30` | 质检中 |
| `40` | 已生产入库 |
| `50` | 已交付 |
| `80` | 异常 |
| `90` | 取消 |

### 5.2 部件状态：`custom_item_component.status`

| 值 | 前端展示 |
| --- | --- |
| `0` | 待处理 |
| `10` | 已备齐 |
| `20` | 采购中 |
| `30` | 委外中 |
| `40` | 生产中 |
| `50` | 已完成 |
| `80` | 异常 |
| `90` | 取消 |

### 5.3 工序状态：`custom_item_process.status`

| 值 | 前端展示 |
| --- | --- |
| `0` | 待开始 |
| `10` | 进行中 |
| `20` | 已完成 |
| `80` | 异常 |
| `90` | 取消 |

### 5.4 供应商镜片状态：`custom_item_component.supplier_status`

| 值 | 前端展示 |
| --- | --- |
| `0` | 待接单 |
| `10` | 已接单 |
| `20` | 生产中 |
| `30` | 已生产 |
| `40` | 已打包 |
| `50` | 已寄回 |
| `80` | 异常 |

### 5.5 镜框采购进度：`custom_item_component.supplier_progress_status`

| 值 | 前端展示 |
| --- | --- |
| `0` | 未开始 |
| `10` | 库存已锁定 |
| `20` | 已生成采购计划 |
| `30` | 供应商现货 |
| `40` | 供应商生产中 |
| `80` | 已停产无法采购 |
| `90` | 已采购入库 |

### 5.6 Shopify 定制订单状态

内部由 `CustomOrderStageSyncService` 同步到 Shopify metafield `custom.custom_order_stage`。

| 内部节点 | Shopify 展示 |
| --- | --- |
| 准备中 | `CUSTOM_ORDER_STAGE = 10` 准备中 |
| 组装开始 | `CUSTOM_ORDER_STAGE = 20` 组装中 |
| 质检开始 | `CUSTOM_ORDER_STAGE = 30` 质检中 |
| 成品入库完成 | `CUSTOM_ORDER_STAGE = 40` 已生产入库 |
| 发货完成 | `CUSTOM_ORDER_STAGE = 50` 已发货 |
| 任意异常 | `CUSTOM_ORDER_STAGE = 80` 异常 |

## 六、订单面板与订单详情

### 6.1 销售订单列表

```text
GET /admin/sale-order/index
```

建议筛选：

```text
keyword
channel_id
customer_id
status
delivery_status
audit_status
customer_type=3           # 红人订单筛选
type={订单类型}
```

订单列表为了性能，默认不建议带出完整履约树。前端如需展示订单面板，应优先使用后端已补的轻量统计字段；如果接口暂未带出，可在点击订单后加载详情。

### 6.2 销售订单详情

```text
GET /admin/sale-order/detail?id={sale_order_id}
```

前端重点读取：

```text
custom_order_item_list
custom_order_item_list[].component_list
custom_order_item_list[].process_list
custom_order_item_list[].log_list
```

履约单元结构示例：

```json
{
  "id": 501,
  "industry_type": "optical",
  "sale_order_id": 1001,
  "sale_order_detail_id": 2001,
  "product_id": 3001,
  "item_no": 1,
  "quantity": 1,
  "params_snapshot": {},
  "status": 20,
  "abnormal_status": 0,
  "abnormal_reason": null,
  "component_list": [],
  "process_list": [],
  "log_list": []
}
```

### 6.3 销售订单明细

```text
GET /admin/sale-order-detail/index?order_id={sale_order_id}
GET /admin/sale-order-detail/detail?id={detail_id}
GET /admin/sale-order-detail/fetch?order_id={sale_order_id}
```

销售订单明细可带出当前明细下的 `custom_order_item_list`，适合订单详情页按销售行展示每副眼镜。

## 七、定制基础配置接口

以下均走通用 CRUD。

### 7.1 流程模板：`custom-flow-template`

```text
GET  /admin/custom-flow-template/index
GET  /admin/custom-flow-template/detail?id={id}
GET  /admin/custom-flow-template/fetch
POST /admin/custom-flow-template/add
POST /admin/custom-flow-template/edit
POST /admin/custom-flow-template/delete
```

核心字段：

| 字段 | 说明 |
| --- | --- |
| `industry_type` | 行业类型，眼镜为 `optical` |
| `title` | 模板名称 |
| `product_id` | 绑定产品 ID，可空 |
| `status` | 状态 |

### 7.2 部件模板：`custom-component-template`

```text
GET  /admin/custom-component-template/index
GET  /admin/custom-component-template/detail?id={id}
GET  /admin/custom-component-template/fetch
POST /admin/custom-component-template/add
POST /admin/custom-component-template/edit
POST /admin/custom-component-template/delete
```

核心字段：

| 字段 | 说明 |
| --- | --- |
| `template_id` | 流程模板 ID |
| `component_type` | `frame`、`lens_left`、`lens_right`、`lens_pair` |
| `component_title` | 部件名称 |
| `default_product_id` | 默认产品 |
| `source_type` | `1` 库存、`2` 采购、`3` 委外、`4` 自产 |

### 7.3 工序模板：`custom-process-template`

```text
GET  /admin/custom-process-template/index
GET  /admin/custom-process-template/detail?id={id}
GET  /admin/custom-process-template/fetch
POST /admin/custom-process-template/add
POST /admin/custom-process-template/edit
POST /admin/custom-process-template/delete
```

常用工序类型：

```text
lens_outsource
lens_stock_in
assemble
qc
stock_in
ship
```

### 7.4 参数定义：`custom-param-schema`

```text
GET  /admin/custom-param-schema/index
GET  /admin/custom-param-schema/detail?id={id}
GET  /admin/custom-param-schema/fetch
POST /admin/custom-param-schema/add
POST /admin/custom-param-schema/edit
POST /admin/custom-param-schema/delete
```

用于定义眼镜参数、镜片参数、工序参数的动态字段。

## 八、定制履约数据接口

### 8.1 履约单元：`custom-order-item`

```text
GET  /admin/custom-order-item/index
GET  /admin/custom-order-item/detail?id={id}
GET  /admin/custom-order-item/fetch
POST /admin/custom-order-item/add
POST /admin/custom-order-item/edit
POST /admin/custom-order-item/delete
```

核心字段：

| 字段 | 说明 |
| --- | --- |
| `sale_order_id` | 销售订单 ID |
| `sale_order_detail_id` | 销售明细 ID |
| `customer_id` | 客户 ID |
| `template_id` | 流程模板 |
| `product_id` | 成品产品 |
| `params_snapshot` | 下单定制参数快照 |
| `status` | 履约单元状态 |
| `abnormal_status` | 是否异常 |
| `abnormal_reason` | 异常原因 |
| `owner_admin_id` | 负责人 |

### 8.2 履约部件：`custom-item-component`

```text
GET  /admin/custom-item-component/index
GET  /admin/custom-item-component/detail?id={id}
GET  /admin/custom-item-component/fetch
POST /admin/custom-item-component/add
POST /admin/custom-item-component/edit
POST /admin/custom-item-component/delete
```

核心字段：

| 字段 | 说明 |
| --- | --- |
| `custom_order_item_id` | 履约单元 ID |
| `component_type` | 部件类型 |
| `product_id` | 产品 ID |
| `supplier_id` | 供应商 ID |
| `source_type` | 来源 |
| `status` | 部件状态 |
| `expected_finish_time` | 预计完成时间 |
| `actual_finish_time` | 实际完成时间 |
| `purchase_plan_detail_id` | 采购计划明细 |
| `purchase_order_detail_id` | 采购明细 |
| `entrust_id` | 委外单 |
| `repository_freeze_log_id` | 库存冻结 |
| `tracking_num` | 供应商/物流单号 |
| `params_snapshot` | 部件参数快照 |
| `supplier_status` | 供应商侧镜片状态 |
| `supplier_scan_code` | 供应商扫码码 |
| `supplier_progress_status` | 镜框采购进度 |
| `supplier_eta_time` | 供应商预计入库时间 |

### 8.3 履约工序：`custom-item-process`

通用 CRUD：

```text
GET  /admin/custom-item-process/index
GET  /admin/custom-item-process/detail?id={id}
GET  /admin/custom-item-process/fetch
POST /admin/custom-item-process/add
POST /admin/custom-item-process/edit
POST /admin/custom-item-process/delete
```

专项动作接口：

```text
GET  /admin/custom-item-process/workOrderList
GET  /admin/custom-item-process/assembleDetail?id={process_id}
GET  /admin/custom-item-process/qcDetail?id={process_id}
POST /admin/custom-item-process/assign
POST /admin/custom-item-process/start
POST /admin/custom-item-process/finish
POST /admin/custom-item-process/rollback
POST /admin/custom-item-process/abnormal
POST /admin/custom-item-process/assembleFinish
POST /admin/custom-item-process/qcPass
POST /admin/custom-item-process/qcReject
POST /admin/custom-item-process/stockInFinish
```

常用参数：

| 接口 | 参数 |
| --- | --- |
| `assign` | `id` 或 `process_id`，`main_admin_id` |
| `start` | `id` 或 `process_id`，`remark` 可选 |
| `finish` | `id` 或 `process_id` |
| `rollback` | `id` 或 `process_id`，`target_process_type`，`reason` |
| `abnormal` | `id` 或 `process_id`，`reason`，`mark_item_abnormal` |
| `qcReject` | `id` 或 `process_id`，`reject_type`，`reason`，`rollback_process_type` |

说明：

- `assembleFinish` 等价于完成组装工序。
- `qcPass` 会完成质检工序。
- `qcReject` 可回退到组装或标记异常。
- `stockInFinish` 完成成品入库后，会尝试生成可发货计划。

### 8.4 履约日志：`custom-process-log`

```text
GET  /admin/custom-process-log/index
GET  /admin/custom-process-log/detail?id={id}
GET  /admin/custom-process-log/fetch
```

前端通常只读日志，不建议直接新增/编辑日志。

## 九、镜片委外与供应商门户

### 9.1 后台委外单

委外单仍使用现有 `entrust` 模块。

专项接口：

```text
POST /admin/entrust/ship
POST /admin/entrust/receiveStockIn
POST /admin/entrust/receiveStockInAndTriggerAssemble
POST /admin/entrust/triggerAssemble
POST /admin/entrust/triggerQc
POST /admin/entrust/generateMaterialReceipt
POST /admin/entrust/generateQcReceipt
```

前端场景：

| 场景 | 接口 |
| --- | --- |
| 供应商发货 | `POST /admin/entrust/ship` |
| 委外镜片接收入库 | `POST /admin/entrust/receiveStockIn` |
| 入库后立即触发组装 | `POST /admin/entrust/receiveStockInAndTriggerAssemble` |
| 手动触发组装检查 | `POST /admin/entrust/triggerAssemble` |
| 手动触发质检 | `POST /admin/entrust/triggerQc` |

### 9.2 供应商门户接口

供应商用户使用 Admin 登录态，只能访问分配给自己的委外单。

```text
GET  /admin/supplier-entrust/index
GET  /admin/supplier-entrust/detail?id={entrust_id}
GET  /admin/supplier-entrust/componentList?entrust_id={entrust_id}
POST /admin/supplier-entrust/updateTracking
POST /admin/supplier-entrust/component/updateStatus
POST /admin/supplier-entrust/component/scanUpdate
GET  /admin/supplier-entrust/export
```

列表筛选：

| 参数 | 说明 |
| --- | --- |
| `status` | 委外单状态 |
| `supplier_status` | 镜片供应商侧状态 |
| `keyword` | 委外单号/物流单号 |
| `page` / `per_page` | 分页 |

`updateTracking` 请求：

```json
{
  "entrust_id": 1001,
  "tracking_num": "YT123456789",
  "shipped_time": "2026-07-23 10:00:00"
}
```

`component/updateStatus` 请求：

```json
{
  "component_id": 501,
  "supplier_status": 30,
  "tracking_num": "YT123456789"
}
```

`component/scanUpdate` 请求：

```json
{
  "scan_code": "CIC20260723000001",
  "target_status": 30,
  "tracking_num": "YT123456789"
}
```

供应商页面返回字段已做白名单，前端不要依赖销售单号、销售价、客户联系方式等敏感字段。

## 十、镜框采购与供应商比价

### 10.1 采购计划生成

镜框部件如果库存不足，可生成采购计划：

```text
POST /admin/purchase-plan-detail/generateByCustomComponent
```

请求：

```json
{
  "custom_item_component_id": 501
}
```

说明：

- 仅支持 `component_type = frame`。
- 如果库存可用，后端会优先锁定库存。
- 库存不足时会生成采购计划并回写部件采购关联字段。

### 10.2 供应商比价

```text
GET /admin/purchase-order/supplierCompare?product_id={product_id}
```

返回字段：

| 字段 | 说明 |
| --- | --- |
| `supplier_id` | 供应商 ID |
| `supplier_title` | 供应商名称 |
| `current_price` | 当前报价 |
| `currency` | 币种 |
| `moq` | 起订量 |
| `history_min_price` | 历史最低价 |
| `history_avg_price` | 历史平均价 |
| `last_purchase_price` | 最近采购价 |
| `last_purchase_time` | 最近采购时间 |
| `recommend_score` | 推荐分 |

### 10.3 采购价格走势

```text
GET /admin/purchase-order/trend?product_id={product_id}
GET /admin/purchase-order/trend?product_id={product_id}&supplier_id={supplier_id}
```

用于采购分析折线图。

### 10.4 更新采购供应商进度

```text
POST /admin/purchase-order/updateSupplierProgress
```

请求：

```json
{
  "component_id": 501,
  "supplier_progress_status": 40,
  "supplier_eta_time": "2026-07-30 18:00:00",
  "abnormal_reason": ""
}
```

也可通过采购明细更新：

```json
{
  "purchase_order_detail_id": 9001,
  "supplier_progress_status": 30,
  "supplier_eta_time": "2026-07-28 18:00:00"
}
```

## 十一、组装、质检、成品入库

### 11.1 工单列表

```text
GET /admin/custom-item-process/workOrderList
```

常用筛选：

```text
process_type=assemble
process_type=qc
status=0|10|20|80
sale_order_id
customer_id
custom_item_status
only_mine=1
```

### 11.2 组装详情

```text
GET /admin/custom-item-process/assembleDetail?id={process_id}
```

返回包含：

```text
customOrderItemInfo.orderInfo
customOrderItemInfo.orderDetailInfo
customOrderItemInfo.productInfo
customOrderItemInfo.componentList
customOrderItemInfo.processList
logList
```

### 11.3 质检详情

```text
GET /admin/custom-item-process/qcDetail?id={process_id}
```

前端操作：

```text
POST /admin/custom-item-process/qcPass
POST /admin/custom-item-process/qcReject
```

`qcReject` 示例：

```json
{
  "id": 701,
  "reject_type": "rework",
  "rollback_process_type": "assemble",
  "reason": "镜片装配偏位"
}
```

### 11.4 成品入库

```text
POST /admin/custom-item-process/stockInFinish
```

说明：

- 成品入库成功后，`custom_order_item.status` 推进到 `40`。
- 后端会尝试生成发货计划。
- Shopify 定制订单状态会同步为“已生产入库”。

## 十二、物流发货

### 12.1 快递任务

创建快递任务：

```text
POST /admin/custom-logistics/createExpressTask
```

请求：

```json
{
  "delivery_plan_id": 456,
  "service": "yuntu",
  "express_com": "运输方式代码",
  "rec_name": "收件人",
  "rec_mobile": "电话",
  "rec_country": "US",
  "rec_state": "CA",
  "rec_city": "Los Angeles",
  "rec_address": "address",
  "rec_zip": "90001",
  "weight": 1.2,
  "l": 10,
  "w": 8,
  "h": 4
}
```

快递渠道下单：

```text
POST /admin/custom-logistics/placeExpressOrder
```

请求：

```json
{
  "express_task_id": 123,
  "service": "yuntu",
  "express_com": "运输方式代码"
}
```

### 12.2 面单打印

标记面单已打印：

```text
POST /admin/custom-logistics/printLabel
```

请求：

```json
{
  "ids": [123, 124]
}
```

如需要合并 PDF 面单，仍可复用：

```text
POST /admin/express-task/printLabel
```

### 12.3 扫码发货

```text
POST /admin/custom-logistics/scanShip
```

请求：

```json
{
  "barcode": "YT1907911202000015"
}
```

响应：

```json
{
  "express_task_id": 123,
  "delivery_plan_id": 456,
  "sale_order_id": 789,
  "tracking_no": "YT1907911202000015",
  "delivery_status": 5,
  "already_shipped": false,
  "shopify_sync_status": "queued"
}
```

说明：

- 条码优先匹配 `express_task.task_id`，其次匹配 `order_id`、发货计划编码、发货计划快递单号。
- 扫码发货会自动备货、生成并审核销售出库单。
- 扫码接口幂等，已发货重复扫描不会重复扣库存。
- Shopify 发货同步异步执行，失败后可手动重试。

### 12.4 物流轨迹

```text
GET  /admin/custom-logistics/tracking?id={express_task_id}
POST /admin/custom-logistics/syncTracking
```

`syncTracking` 请求：

```json
{
  "express_task_id": 123
}
```

### 12.5 Shopify 发货同步重试

```text
POST /admin/custom-logistics/syncShopifyShipment
```

请求：

```json
{
  "express_task_id": 123,
  "force": true
}
```

## 十三、生产看板与大屏

### 13.1 通用筛选参数

```text
start_date
end_date
time=today|week|month
owner_admin_id
main_admin_id
organization_id
status
process_type
only_abnormal=1
only_overdue=1
channel_id
```

### 13.2 后台生产看板接口

```text
GET /admin/dashboard/customProductionOverview
GET /admin/dashboard/customProductionStage
GET /admin/dashboard/customProductionComponent
GET /admin/dashboard/customProductionProcess
GET /admin/dashboard/customProductionWarning
GET /admin/dashboard/customProductionOrderList
GET /admin/dashboard/customProductionTrend
GET /admin/dashboard/customProductionGroup
```

页面建议：

| 区域 | 接口 |
| --- | --- |
| 顶部指标卡 | `customProductionOverview` |
| 阶段分布图 | `customProductionStage` |
| 部件进度图 | `customProductionComponent` |
| 工序进度图 | `customProductionProcess` |
| 超期/异常列表 | `customProductionWarning` |
| 订单明细表 | `customProductionOrderList` |
| 近 7 天趋势 | `customProductionTrend` |
| 车间/小组统计 | `customProductionGroup` |

### 13.3 大屏接口

```text
GET /admin/dashboard/customProductionScreen
GET /admin/dashboard/customProductionScreenTrend
GET /admin/dashboard/customProductionScreenGroup
GET /admin/dashboard/customProductionScreenWarning
```

大屏建议：

- 30 秒自动刷新。
- 使用后台登录态。
- 不展示敏感客户字段和销售价格。
- 支持按 `organization_id` 切换车间/小组。

## 十四、客户眼镜档案与复购提醒

### 14.1 处方档案

```text
GET  /admin/optical-prescription/index?customer_id={customer_id}
GET  /admin/optical-prescription/detail?id={id}
POST /admin/optical-prescription/add
POST /admin/optical-prescription/edit
POST /admin/optical-prescription/delete
```

### 14.2 客户分析

实际路由使用驼峰：

```text
GET  /admin/customer/opticalAnalysis?id={customer_id}
POST /admin/customer/refreshOpticalAnalysis
```

`opticalAnalysis` 返回：

```json
{
  "profile": {},
  "latest_prescription": {},
  "prescription_history": [],
  "order_history": [],
  "suggestions": [],
  "customer": {}
}
```

### 14.3 客户列表筛选

```text
GET /admin/customer/index?repurchase_due=1
GET /admin/customer/index?repurchase_overdue=1
GET /admin/customer/index?prescription_changed=1
```

前端建议展示：

```text
最近眼镜订单时间
预计复购日期
复购状态
最新处方时间
处方变化等级
```

## 十五、红人客户与寄样订单

### 15.1 红人客户

红人是 `Customer` 的一种类型，不新增红人主表。

```text
GET  /admin/customer/index?type=3
GET  /admin/customer/detail?id={customer_id}
POST /admin/customer/add
POST /admin/customer/edit
POST /admin/customer/delete
```

创建/编辑时重点字段：

```text
type = 3
website                 # 红人主页地址，去重优先使用该字段
owner_admin_id
source
level
trade
admin_remark
```

说明：

- 红人主页去重采用简单规范化比对，不单独依赖 hash 字段。
- 红人客户不允许导出客户列表。
- 红人负责人可看完整信息，其他人按权限和数据范围展示。

### 15.2 红人寄样订单

红人订单复用销售订单，沿用 `sale_order.type` 表示寄样订单类型。

```text
GET  /admin/sale-order/index?customer_type=3&type={红人寄样订单类型}
GET  /admin/sale-order/detail?id={sale_order_id}
POST /admin/sale-order/add
POST /admin/sale-order/edit
POST /admin/sale-order/audit
POST /admin/sale-order/delete
```

创建寄样订单建议：

```json
{
  "customer_id": 1001,
  "type": "红人寄样订单类型",
  "amount": 0,
  "real_amount": 0,
  "detail_list": []
}
```

## 十六、前端页面优先级建议

### 第一阶段：跑通业务闭环

1. 订单详情履约树。
2. 订单面板状态展示。
3. 供应商镜片门户。
4. 组装工单、质检工单。
5. 物流扫码发货。

### 第二阶段：运营效率

1. 镜框采购比价。
2. 采购进度反馈到订单面板。
3. 生产看板。
4. 客户眼镜档案和复购提醒。

### 第三阶段：展示和管理增强

1. 数据大屏。
2. 红人管理和红人订单。
3. 物流轨迹详情。
4. Shopify 状态同步失败重试页面。

## 十七、前端实现注意事项

1. 订单详情页不要一次性在列表加载全部履约树，避免列表变慢。
2. 所有状态都以数值字段为准，展示文案前端可维护枚举。
3. 供应商门户不要展示销售单号、销售价格、客户联系方式、Shopify line item id。
4. 扫码枪按普通输入框处理，扫码后调用接口即可。
5. 扫码发货、扫码改镜片状态都需要处理重复扫码的成功返回。
6. 工序回退和异常必须展示 `custom_process_log`，否则运营无法追溯。
7. Shopify 同步失败不代表内部流程失败，应在页面显示“待重试/同步失败”，允许人工重试。
8. 大屏接口仍是 Admin 接口，需要登录态，不应做 Open 页面直连。

## 十八、参考文档

- `doc/jykj/软件开发需求功能点.md`
- `doc/jykj/泛用定制销售生产前端接口字段说明.md`
- `doc/jykj/生产管理委外入库工单组装质检入库实施方案.md`
- `doc/jykj/供应商采购与镜片供应门户实现方案.md`
- `doc/jykj/生产数据看板与大屏实施方案.md`
- `doc/jykj/物流快递下单扫码发货状态同步实施方案.md`
- `doc/jykj/客户分析与复购提醒实现方案.md`
- `doc/jykj/红人客户与寄样订单实现方案.md`
