Files
menchuang/doc/API.md
T
HHY 7554f2e3c7 feat: 整站全量采集与订单写入接口契约补全
- GET 全量扫描 279 个接口并留档(HTTP200=90, 业务成功=76)
- POST 安全探测 24 个只读/计算接口(白名单制, 支付/短信/删除类零触碰)
- 订单写入接口契约经 chunk 源码静态分析补全:
  orders CRUD / 创建订单{contract_id,drawing_data,pic_url} / windoor_default 保存
- 确认付费墙语义 code=10086 及到期/角色权限响应
- doc/API.md 新增整站采集结果章节, 更新订单模块契约表
2026-09-20 07:19:10 -07:00

185 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# API 接口文档
> 本文档记录自研系统的接口规范,并对照目标站已验证接口。目标站基址:`https://zzc-serv.thinkerx.com/api/`(仅作参照)。
> 自研系统基址:`/api/`(FastAPI 挂载)。
> 认证方式:`Authorization: Bearer <JWT>`(HS256,24h);`X-Requested-With: XMLHttpRequest`;`Accept: application/json`。
## 0. 统一响应规范
```json
{ "code": 1, "message": "获取成功", "data": {}, "other_data": "", "other_data2": "" }
```
- `code=1` 成功,其他为失败;`message` 为用户可读文案。
- **`code=10086` 业务付费墙**:模块未购买/已到期,`message` 为"购买后解锁此功能,点击此处去购买";前端跳转商城。自研系统对应"套餐权限校验中间件"。
- 列表分页:`data: { current_page, data: [], total, per_page, last_page, next_page_url, ... }`。
- 业务错误:HTTP 200 + code≠1;认证失败:HTTP 401;参数缺失:HTTP 200 + code=0(message 提示)或 422。
## 1. 认证模块
| 接口名称 | 方式 | URL 路径 | 请求参数 | 响应示例 |
|---|---|---|---|---|
| 手机验证码登录 | POST | `/api/wechat-login-with-phone` | `{phone_number, code, ...}` | `{token, user}`(原站登录入口,JWT iss 即此) |
| 账号密码登录 | POST | `/api/login` | `{phone_number, password}` | `{token, ...}` |
| 验证码登录 | POST | `/api/code-login` | `{phone_number, code}` | `{token, ...}` |
| 发送验证码 | POST | `/api/verification-code-new` | `{phone_number, scene}` | `{code:1}` |
| 图形验证码 | GET | `/api/captcha` | — | 图形/`{code:1,data}` |
| 注册并登录 | POST | `/api/register-and-login` | `{phone_number, password, code}` | `{token, ...}` |
| 忘记密码 | POST | `/api/forget-password` | `{phone_number, code, password}` | `{code:1}` |
| 微信登录 | POST | `/api/wechat-login` | 微信 OAuth code | `{token, ...}` |
## 2. 用户模块
| 接口名称 | 方式 | URL 路径 | 请求参数 | 响应示例(已验证 ✅ 节选) |
|---|---|---|---|---|
| 当前用户信息 | GET | `/api/current-user` | — | ✅ `{"id":3562856,"nickname":"...","phone_number":"...","company_id":1,"money":"0.00","try_expiration_time":"2026-09-23 00:00:00","son_account_type":1,"language":"zh-CN",...}` |
| 子账户列表 | GET | `/api/users?page=1` | `page` | ✅ Laravel 分页,`data.data[]` |
| 邀请用户列表 | GET | `/api/invited_user_list?page=1` | `page` | ✅ 分页 |
| 修改密码 | POST | `/api/current-user/password` | `{old,new}` | ⏳ |
| 绑定微信 | POST | `/api/bind-wechat` | `code` | ⏳ |
| 解绑微信 | POST | `/api/unbind-wechat` | — | ⏳ |
## 3. 样板库模块(已全量采集 ✅)
| 接口名称 | 方式 | URL 路径 | 请求参数 | 响应示例 |
|---|---|---|---|---|
| 窗型分类树 | GET | `/api/default_windoor_catelog` | — | ✅ 树:`[{id:1,name:"推拉门",children:[{id:3,name:"平开"},...]}]` |
| 搜索官方模板 | GET | `/api/search_default_windoor` | `name`(可选,按名称过滤) | ✅ 无分页全量返回:`data.data: [{id,name,pic_url,catelog_id,note,times}]`,共 254 条 |
| 模板绘制详情 | GET | `/api/default_windoor_info/{id}` | 路径 `id` | ✅ `{id,drawing_data(编辑器画布JSON),pic_url,script_bar,script_glass,low/high_width,low/high_height,...}` |
| 用户自存窗型列表 | GET | `/api/windoor/` | `page` | ⏳(需服务端排序参数,待抓包) |
| 用户窗型详情 | GET | `/api/windoor/{id}` | 路径 `id` | ⏳(同 drawing_data 结构) |
| 模板排序 | POST | `/api/windoor_template_sort` | `{ids:[...]}` | ⏳ |
`drawing_data` 结构参见《克隆实施方案.md》§2.2。
## 4. 客户模块
| 接口名称 | 方式 | URL 路径 | 请求参数 | 响应示例 |
|---|---|---|---|---|
| 客户列表 | GET | `/api/customers_list` | — | ✅ `[{id,name,phone,address,note,sort,type,salesmen,discount,balance,level,join_date}]` |
| 客户列表(分页) | GET | `/api/customers` | `page,keywords` | ⏳ |
| 新增/编辑客户 | POST | `/api/customers` | `{name,phone,address,...}` | ⏳ |
| 客户跟进记录 | GET | `/api/customer_records/` | `customer_id` | ⏳ |
| 客户导入 | POST | `/api/customers_excel_in` | Excel 文件 | ⏳ |
## 5. 合同/订单模块
| 接口名称 | 方式 | URL 路径 | 请求参数 | 响应示例 |
|---|---|---|---|---|
| 合同列表 | GET | `/api/contracts` | — | ✅ `{"contracts":{current_page,data:[{id,contract_no:"FG20260818009",customer,area,count,money,status:"意向单",cut_status,sign_status,contract_type,confirmed,discount,oids[],agency_money}]}}` |
| 意向单转合同 | POST | `/api/convert-contract/` | `{contract_id,...}` | ⏳ |
| **订单列表/搜索** | POST | `/api/orders/` | `{page:1, ...筛选条件}` | ✅ 已验证(付费墙):`{"code":"10086","message":"购买后解锁此功能,点击此处去购买","data":""}`;已购账号返回 Laravel 分页订单列表 |
| **创建订单(合同+图纸)** | POST | `/api/orders/` | ✅ 源码确认:`{contract_id, drawing_data(shapeManager序列化), pic_url(缩略图)}` | ⏳ |
| 订单详情 | GET | `/api/orders/{id}` | 路径 `id` | ✅ 路由确认(源码),返回 `data.order` |
| 订单排序 | PUT | `/api/orders/{id}` | `{sort:n}` | ✅ 路由确认(源码) |
| 删除订单 | DELETE | `/api/orders/{id}` | 路径 `id`(支持批量 Promise.allSettled) | ✅ 路由确认(源码) |
| 订单详情(按pid) | POST | `/api/order-by-pid` | `{pid}` | ✅ 已验证(付费墙 code=10086) |
| 订单进度 | POST | `/api/get_order_process` | `{order_id}` | ✅ 已验证 code=1 |
| 订单进度列表 | GET | `/api/get_order_process(_list)` | — | ✅ GET code=1 |
| 订单日志 | GET | `/api/order_up_logs` | `订单id`(缺失时提示"订单id 必须") | ✅ 参数契约确认 |
| 阳光房订单 | POST | `/api/sunny_house_order/` | `{page:1,...}` | ✅ 已验证(付费墙 code=10086) |
| 售后单 | POST | `/api/after_sales_orders/` | `{问题描述...}` | ✅ 已验证(校验"请填写问题描述") |
| 重复订单校验 | POST | `/api/is-repeat-order` | 查询条件 | ✅ 已验证 code=1 |
| 订单状态(管家婆) | POST | `/api/cj-orders-status` | 需参数(当前500) | ⏳ |
| 合同确认 | POST | `/api/up-contract-confirmed/` | `{contract_id}` | ⏳ |
| 电子签名上传 | POST | `/api/update-contract-sign-status` | `{contract_id, sign_picture}` | ⏳ |
| 收款记录 | GET | `/api/contract_receipt_list/` | `contract_id` | ✅ GET code=1 |
| 收款统计 | GET | `/api/contract_receipt_statistics` | — | ✅ GET code=1 |
| 收款统计(按年) | GET | `/api/contract_receipt_statistics_tb` | `年份`(缺失提示"请选择年份") | ✅ 参数契约确认 |
**订单写入流完整契约(自研对齐)**:`画图(shapeManager.serialize) → POST windoor_default 保存模板 或 POST orders/{contract_id, drawing_data, pic_url} 创建订单 → GET orders/{id} 详情回显 → PUT orders/{id} 排序 → DELETE orders/{id} 删除`
## 6. 产品/价格模块
| 接口名称 | 方式 | URL 路径 | 请求参数 | 响应示例 |
|---|---|---|---|---|
| 产品分类树 | GET | `/api/product-catelog` | — | ✅ 树(is_reference、lang、children) |
| 全部产品 | GET | `/api/all-product` | — | ✅ `data:[]`(当前账户为空) |
| 产品详情 | GET | `/api/product/{id}` | 路径 `id` | ⏳ |
| 产品搜索 | GET | `/api/search-product` | `keywords` | ⏳ |
| 团队折扣 | GET | `/api/team-discount` | — | ⏳ |
| 报价单 | GET | `/api/quotations?page=1` | `page` | ✅ 分页(当前账户为空) |
## 7. 仓库/库存模块
| 接口名称 | 方式 | URL 路径 | 请求参数 | 响应示例 |
|---|---|---|---|---|
| 材料库存列表 | GET | `/api/warehouse_list` | 分页参数 | ✅ `[{id,bom_code,name,material:"profile",cost,price,color,pricing_method,length,count,warning,unit,meter_weight,thick,agency_price}]` |
| 库存分类 | GET | `/api/warehouse_catelogs` | — | ⏳ |
| 收款账户 | GET | `/api/receipt_accounts` | — | ✅ `[{id,type,name,number,bank,pic_url,is_default,balance}]` |
| 材料入库 | POST | `/api/product_move_in/` | `{...}` | ⏳ |
| 材料出库 | POST | `/api/product_move_out/` | `{...}` | ⏳ |
| 配件配置 | GET | `/api/materials_config` | — | ⏳ |
## 8. 优化下料/生产模块
| 接口名称 | 方式 | URL 路径 | 请求参数 | 响应示例 |
|---|---|---|---|---|
| 一维优化 | POST | `/api/optimize1d` | `{bars:[], stock:[]}` | ⏳ |
| 切割方案 | GET | `/api/cut_solution(_new)/{contract_id}` | 路径 | ⏳ |
| 合同型材清单 | GET | `/api/contract_bars(_with_stock)` | `contract_id` | ⏳ |
| 更新切割状态 | POST | `/api/up-cut-status` | `{...}` | ⏳ |
| 订单打印模板 | GET | `/api/order_format/` | — | ⏳ |
## 9. 渲染/3D 模块
| 接口名称 | 方式 | URL 路径 | 请求参数 | 响应示例 |
|---|---|---|---|---|
| 渲染信息 | GET | `/api/rendering-info` | — | ⏳ |
| 3D 数据 | POST | `/api/three-d-data` | `{drawing_data}` | ⏳ |
| 按订单取绘图 | GET | `/api/drawing_data_by_oid/{oid}` | 路径 `oid` | ⏳ |
| 照片生成窗型(AI) | POST | `/api/sketch-to-window-info` | 图片 | ⏳ |
## 10. 平台模块
| 接口名称 | 方式 | URL 路径 | 请求参数 | 响应示例 |
|---|---|---|---|---|
| 公告列表 | GET | `/api/announcements` | — | ✅ `[{id,name,desc,pic_url,content(富文本)}]` |
| 商城模块配置 | GET | `/api/company-module-info` | — | ✅ 25 个模块(名称/图标/描述/价格/试用天数) |
| 帮助文档菜单 | GET | `/api/get-showdoc-menu` | — | ✅ showdoc 目录结构 |
| 操作日志 | GET | `/api/operation_logs?page=1` | `page` | ✅ 分页 |
| 业务员列表 | GET | `/api/salesmen` | — | ✅(当前账户为空) |
| 反馈 | POST | `/api/feedback` | `{content}` | ⏳ |
> 标注说明:✅ = 已用只读请求实测并留存样本于 `data/api-samples/`;⏳ = 写入/低频接口未对生产系统探测,自研时按功能语义实现,或抓包后补全。
## 11. 整站全量采集结果(2026-09-20)
原始留档:`data/full-site/`(`get/` 279 个接口响应、`post/` 24 个 POST 响应、`get-manifest.json`、`post-manifest.json`、采集脚本 `sweep_get.py`/`sweep_post.py`)。
### 11.1 GET 扫描(279 个接口)
| 结果 | 数量 | 说明 |
|---|---|---|
| HTTP 200 | 90 | 其中 code=1 业务成功 **76 个** |
| HTTP 405 | 110 | POST/PUT/DELETE-only 接口(已列入 ⏳ 并按语义实现) |
| HTTP 404 | 65 | 需路径参数(如 `{id}` 后缀类) |
| HTTP 500 | 14 | 缺必填参数触发(服务端未做输入校验,自研须避免) |
参数契约(由失败提示反推):`order_up_logs`←订单id;`script/`←系列id;`pay-page`←类型;`contract_receipt_statistics_tb`←年份;`ywy-ykt-user`←手机号;`three-d-data`(POST)←order_id。
### 11.2 POST 安全探测(24 个,白名单制)
- 付费墙确认(code=10086):`orders/`、`sunny_house_order/`、`order-by-pid`、`offer-price(/)`、`product_by_warehouse`、`order_format_by_warehouse`、`ai_product`
- 成功(code=1):`get_order_process`、`is-repeat-order`、`xf_contract_workshop`
- 参数提示:`three-d-data`←必须 order_id;`after_sales_orders/`←问题描述
- 未探测(危险类,永不盲发):支付(wechat_pay*、withdraw)、短信(send-bind-code、verification-code-new)、账号绑定(bind-*、login)、删除/更新类(del_*、void_*、up_*、*_sort)、文件上传(upload*)
### 11.3 源码静态提取的写入契约
| 流程 | 方法+路径 | 请求体 |
|---|---|---|
| 创建订单 | POST `orders/` | `{contract_id, drawing_data, pic_url}` |
| 保存官方模板 | POST `windoor_default` | `{drawing_data: shapeManager.serialize(true), ...}` |
| 修改系列脚本 | PUT `script/{id}` | `{drawing_data: shapeManager.serialize(...)}` |
| 模板排序 | POST `windoor_template_sort` | `{[模板id]: 序号, ...}` |
| 删除订单 | DELETE `orders/{id}` | 路径参数,前端支持批量 |
| 订单排序 | PUT `orders/{id}` | `{sort}` |
### 11.4 权限/付费墙语义(自研须实现)
- 试账户可用模块:样板库、客户、合同、仓库、收款账户、公告、报表统计、帮助文档
- 付费墙模块(code=10086):订单全流程、报价(offer-price)、产品库、订单打印模板、AI 产品
- 到期语义:`pay-page-list` 返回 code=0 "您的账号已经到期,请联系销售人员!";`try_render` 返回 "体验版无法体验实景渲染"
- 角色权限:`contract-stat` 返回 code=210 "该账号没有该权限"