Fosi Fossil Service
Small teams. Open source. Built on Fossil.

IaC / SwiftFlow

High-performance WMS with wave picking, smart routing, and real-time inventory visibility.

Public | Owner: IaC | Default branch: trunk | Last update: 2026-10-23 14:37

Artifact 08d5912512f5d271242b6e2e9b3fdedca9629fdd0327d8ef915f3b63784b0dde:


# QL361 (来肯企汇) 逆向接口协议分析与对接技术规范

| 文档版本 | 编写日期 | 目标站点 | 分析工具 / 方式 |
| :--- | :--- | :--- | :--- |
| **v1.0.0** | 2026-10-23 | `https://22beta.ql361.com/` | Web 静态分析、JS 运行时代码逆向 |

---

## 1. 核心网络与网关拓扑

### 1.1 站点入口
- **业务工作台页面**:`https://22beta.ql361.com/desktop.html?v=196647593#/`
- **静态资源基础路径**:`https://22beta.ql361.com/v_22beta/`
- **统一 API 网关地址**:`https://22beta.ql361.com/v_22beta/api.cc`(或分布式直连网关 `https://20-apiserver-prod.ql361.com/api.cc`)
- **统一认证登录页面**:`https://www.ql361.com/account/logon`
- **认证接口**:`POST https://www.ql361.com/account/Auth`

### 1.2 安全与防御层 (WAF)
- **CDN 提供商**:腾讯云 EdgeOne (`Server: TencentEdgeOne`)
- **防御机制**:EdgeOne 具备 Bot 防护与防抓取策略。所有 HTTP 请求必须附带合法的现代浏览器 `User-Agent` 与合规的 `Accept`、`Referer` 头,否则将返回 `HTTP 567 Unknown Status` 阻断。
- **登录验证码**:集成了网易易盾(NetEase Dun)滑动验证码,同时系统也支持手机 App 扫码登录(`GET /account/QRCode` 轮询)。

---

## 2. API 通信协议规范 (api.cc)

QL361 采用基于 RPC 风格的统一网关协议,所有业务调用均路由至 `api.cc`。

### 2.1 请求格式
- **HTTP Method**:`POST`
- **URL 查询参数**:
  $$\text{URL} = \text{base\_url} + \text{?___method=} + \text{MethodName} + \text{&pagetype=erp&from=allinoneclient&platform=pc} + \text{TokenQuery}$$

  | 参数名 | 必填 | 说明 | 示例 |
  | :--- | :--- | :--- | :--- |
  | `___method` | 是 | 后端业务逻辑层 (BLL) 方法名,大小写敏感 | `CC.ERP.BLL.API.MessageServer.GetLoginStatusForDesktop` |
  | `pagetype` | 是 | 页面类型 | 默认 `erp`,报表或消息传 `crmoa` |
  | `from` | 是 | 客户端来源代号 | 固定 `allinoneclient` |
  | `platform` | 是 | 客户端平台 | 固定 `pc` |
  | `s` | 是 | 会话标识 (Session Id) | 从登录态 Cookie 中获取的 `s` 值 |
  | `tok` | 是 | 鉴权令牌 (Token) | 从登录态 Cookie 中获取的 `tok` 值 |

- **HTTP 请求头 (Headers)**:
  ```http
  Host: 22beta.ql361.com
  User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36
  Content-Type: application/json
  Referer: https://22beta.ql361.com/desktop.html?v=196647593
  Cookie: s=<SESSION_ID>; tok=<TOKEN>; acw_tc=<WAF_COOKIE>
  ```

- **请求体 (Body)**:
  标准的 JSON 字符串。
  ```json
  {
    "billid": 100234,
    "begindate": "2026-10-01",
    "enddate": "2026-10-23"
  }
  ```

---

## 3. 响应结构与异常状态码

QL361 网关返回的 JSON 响应具有统一的包裹结构:

### 3.1 正常响应 (Normal)
```json
{
  "type": "normal",
  "data": { ... },
  "msg": "",
  "productVersion": "v_22beta"
}
```

### 3.2 会话过期 / 未登录 (Logoff)
```json
{
  "type": "logoff",
  "msg": "当前账号已在其他地方登录或已退出登录",
  "data": null
}
```
> **处理策略**:SwiftFlow 逆向引擎捕获到 `type == "logoff"` 或 `msg` 包含“已退出登录”时,立即触发告警或重新发起认证流程。

### 3.3 业务异常 (Error)
```json
{
  "type": "error",
  "msg": "未找到指定单据信息",
  "data": null
}
```

---

## 4. 核心 BLL 业务方法清单 (只读抽取)

| 业务领域 | 核心方法名 (`___method`) | 业务用途 | 实测状态 |
| :--- | :--- | :--- | :--- |
| **会话状态** | `CC.ERP.BLL.API.MessageServer.GetLoginStatusForDesktop` | 检查当前 Session 是否有效 | 已验证通过 |
| **基础仓库** | `cc.erp.bll.bas.baseinfomanager.getforautocomplete` | 获取全部仓库列表 (`bastype: "store"`) | 已验证通过 |
| **销售订单列表** | `cc.erp.bll.bill.billbllmanager.getdatalist` | 分页拉取销售订单 (`billtype: 604`) | 已验证通过 |
| **订单商品行明细** | `cc.erp.bll.bill.billbllmanager.getfulldata` | 查询指定订单全量明细与商品条码/规格/库位 | 已验证通过 |
| **待拣货销售清单** | `cc.erp.bll.report.reportmanager.getdatalist` | 待拣货专用报表视图 (`billtype: 2352`) | 已验证通过 |
| **待发货出库清单** | `CC.ERP.BLL.Bill.Core.Delivery.DeliveryHandOverService.QueryCanHandOverBillList` | 交接发货出库单据 | 已验证通过 |

---

## 5. 销售订单与商品明细数据协议 (实测样本)

### 5.1 订单列表拉取 (`cc.erp.bll.bill.billbllmanager.getdatalist`)
- **请求负载**:
  ```json
  {
    "reportparam": {
      "orders": "",
      "parid": 0,
      "pagetype": "erp",
      "displaytype": "tree",
      "pagerow": 100,
      "pagenumber": 0
    },
    "conditionparam": {
      "begindate": "2024-01-01",
      "enddate": "2026-12-31",
      "billtype": 604,
      "status": 20
    }
  }
  ```
- **核心字段映射**:
  - `billid`: 订单数字 ID (如 `1898938789`)
  - `billcode`: 业务单据号 (如 `XSDD-20260922-001`)
  - `dfullname`: 客户名称 (如 `山西省忻州市巷往烘焙`)
  - `contactor`: 联系人
  - `phone`: 电话
  - `soutfullname`: 发货仓库名称 (如 `门店`)
  - `soutid`: 仓库 ID (如 `793208`)
  - `qty`: 订单总件数 (如 `22.0`)
  - `totalmoney`: 订单总金额
  - `status`: 订单状态 (`20` = 待发货/待拣货, `22` = 发货完成, `30` = 交易完成, `19` = 已取消)

### 5.2 订单全量商品明细 (`cc.erp.bll.bill.billbllmanager.getfulldata`)
- **请求负载**:
  ```json
  {
    "billid": 1898938789,
    "billtype": 604
  }
  ```
- **响应结构**:`data.header` (单头汇总) + `data.body0.datasource` (商品行明细列表)
- **商品行字段提取**:
  - `gcode`: 商品编码/SKU (如 `c001057`)
  - `gfullname`: 商品名称 (如 `乙夫-蔬香紫薯味吐司400g`)
  - `barcode`: 69码/EAN13商品条码 (如 `6971979070155`)
  - `spec`: 规格 (如 `400g*20袋`)
  - `mqty` / `mufullname`: 大单位件数 (如 `2.0 件`)
  - `qty` / `bufullname`: 基本单位散件数 (如 `40.0 盒`)
  - `gpcode`: 原系统货位 (如 `默认货位(门店)`)
  - `sacode`: 原系统库区 (如 `默认库区`)

---

## 6. 拣货单生成转换逻辑 (SwiftFlow WMS 核心)

从 QL361 销售订单向 SwiftFlow 拣货任务的转换流程如下:

```
[QL361 销售订单: billtype 604]
            │
            ▼ (只读抽取: getfulldata)
{ 订单商品行明细: SKU, 条码, 件数, 散数 }
            │
            ├───────────────────────────────────────────┐
            ▼                                           ▼
   【按单拣货 Single Order】                   【波次汇总拣货 Wave Picking】
   - 单任务 1:1 对应源单                       - 多单合并、相同 SKU 累加数量
   - SwiftFlow 推荐最优 S 型库位动线           - 匹配四级库位 (区-排-架-位) 推荐最短动线
   - PDA 扫条码逐行核销                        - 拣货完成后推入播种墙 (Seed Wall) 进行二次分播
            │                                           │
            ▼                                           ▼
   【拣货完成待复核】                          【播种复核分箱完成】
```

---

## 5. SwiftFlow 在 Gleam 中的实现架构

- **模块位置**:[`shared/ql361api`](file:///Users/pluto/MyProject/NMProject/fosi.dev/SwiftFlow/shared/ql361api)
- **底层驱动**:`gleam_httpc` + `gleam_json`
- **设计模式**:只读数据适配器模式(Read-Only Adapter Pattern)。所有抓取到的数据经过清洗与类型转换后,投递给 `backend/` 业务核心。

Clone

You can clone this repository with the following command:

fossil clone https://fosi.dev/IaC/SwiftFlow

Contribute

The best way to contribute is through e-mail. See the project documentation for more details.