1
@@ -14,6 +14,7 @@
|
|||||||
- [二期产品待确认事项(发产品填写)](二期产品待确认事项.md)
|
- [二期产品待确认事项(发产品填写)](二期产品待确认事项.md)
|
||||||
- [二期开发进度表](二期开发进度表.md)
|
- [二期开发进度表](二期开发进度表.md)
|
||||||
- [二期开发进度表(Excel)](虫虫出海二期开发进度表.xlsx)
|
- [二期开发进度表(Excel)](虫虫出海二期开发进度表.xlsx)
|
||||||
|
- [二期前端页面清单与多对话并行任务表](二期前端页面清单与多对话并行任务表.md)
|
||||||
- [二期需求确认清单:产品与业务确认](二期需求确认清单.md)
|
- [二期需求确认清单:产品与业务确认](二期需求确认清单.md)
|
||||||
- [二期需求确认清单(会议填写 Excel)](二期需求确认清单.xlsx)
|
- [二期需求确认清单(会议填写 Excel)](二期需求确认清单.xlsx)
|
||||||
- [规划依据:头程物流流程图](参考资料/头程物流流程图.svg)
|
- [规划依据:头程物流流程图](参考资料/头程物流流程图.svg)
|
||||||
|
|||||||
@@ -0,0 +1,228 @@
|
|||||||
|
# 二期前端页面清单与多对话并行任务表
|
||||||
|
|
||||||
|
> 盘点日期:2026-08-04
|
||||||
|
> 适用项目:`apps/admin-web/`、`apps/client-web/`
|
||||||
|
> 后端范围:只读核对 `baiyue-firstleg/`,本任务不修改后端
|
||||||
|
> 当前基线:以后端现有 Controller、DTO、权限和状态机为可联调事实;V2 待确认项不擅自补成前端规则
|
||||||
|
|
||||||
|
本轮不存在“等待后端提供接口文档”的前置任务。每个前端对话直接只读当前工作区 `baiyue-firstleg/` 中的 Controller、DTO、Service、Repository、OpenAPI 和权限 SQL;发现契约问题只登记,不修改后端。
|
||||||
|
|
||||||
|
## 一、结论
|
||||||
|
|
||||||
|
二期前端应围绕已经落地的“入库测量、OCR、测量审核、FBA 计费、托盘库位、客户只读结果”建设,不继续沿用旧 24 项计划直接开工。
|
||||||
|
|
||||||
|
- Admin 新增 5 个正式菜单页面:入库单、客户计费规则、船司 FBA 价格、库位管理、托盘管理。
|
||||||
|
- 入库详情承载测量/OCR、审核、费用快照、托盘库位结果和历史,不再新增独立“接收审核”页面。
|
||||||
|
- 正常流程由“测量审核通过”触发后端自动计费、发布费用并完成入库;前端不把 `calculate → confirm → send` 串成常规人工流程。
|
||||||
|
- Client 不新增独立入库菜单或列表,只在现有头程订单详情中增加“入库与费用”只读区。
|
||||||
|
- 到仓预报、预约、签到、分批收货、标签、冲正、差异通知、上架任务、位置历史和通用费用项目当前没有匹配的公开后端接口,暂不拆前端实现任务。
|
||||||
|
|
||||||
|
## 二、事实来源和冲突处理
|
||||||
|
|
||||||
|
当前 V2 确认清单的 C1-C8、T1-T3 仍是待确认状态,但后端已经形成一套更收敛的可联调实现。因此本轮按以下顺序执行:
|
||||||
|
|
||||||
|
1. 用户本轮要求:只整理和开发前端,不修改后端,可以直接只读后端代码。
|
||||||
|
2. 后端真实 Controller、DTO、权限 SQL、状态枚举和服务编排。
|
||||||
|
3. `二期需求优化版-v2-测量计费入库主流程.md` 的范围边界。
|
||||||
|
4. Admin 原型仅用于布局、字段和交互参考,不补造后端没有的业务能力。
|
||||||
|
|
||||||
|
已确认的实现差异:
|
||||||
|
|
||||||
|
| 主题 | 旧规划或 V2 描述 | 当前后端事实 | 前端处理 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| 正常入库动作 | 人工试算、确认、发送费用后入库 | 测量审核通过后自动计费、发布费用并完成入库 | 审核成功后刷新详情和费用,不串行调用三个计费接口 |
|
||||||
|
| 托盘库位 | 操作员选择托盘和候选库位 | 测量提交/审核编排自动准备和占用,平台无人工分配公开接口 | 详情只读展示分配结果 |
|
||||||
|
| 接收审核 | 独立页面 | 无独立节点 | 不建设;相关结果并入详情和审核区 |
|
||||||
|
| Client 到仓预报 | 规划中存在 | 无商户公开接口 | 不建设 |
|
||||||
|
| 通用费用项目 | V2 C6 白名单待确认 | 无独立费用项目 Controller | 不建设费用项目页 |
|
||||||
|
| 入库列表路径 | V2 示例使用 `/api/platform/inbounds` | Controller 确实无 `v1`,其他入库接口多为 `/api/platform/v1/...` | API 封装保留真实多前缀,不自行统一 |
|
||||||
|
|
||||||
|
## 三、Admin 页面和变更清单
|
||||||
|
|
||||||
|
### 3.1 正式菜单页面
|
||||||
|
|
||||||
|
| 页面 | 建议路由 | 主要内容 | 主要权限 | 优先级 |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| 入库单 | `/inbounds` | 企业选择、四个后端页签、多条件筛选、服务端分页、详情入口 | `platform:firstleg:inbound:list` | P0 |
|
||||||
|
| 入库详情 | `/inbounds/:inboundId` | 概览、运输快照、内部备注、文件、状态历史、测量、审核、费用、托盘库位 | `platform:firstleg:inbound:view` 及各操作权限 | P0 |
|
||||||
|
| 客户计费规则 | `/first-leg-pricing/customer-rules` | 规则查询、详情、新版本、停用;KG/CBM、换算系数、舍入和有效期 | `firstleg:fba-pricing:rule:view/edit` | P0 |
|
||||||
|
| 船司 FBA 价格 | `/first-leg-pricing/carrier-rates` | 价格查询、详情、新版本、停用;起运仓、渠道、船司、FBA 仓、单价和附加费 | `firstleg:fba-pricing:rate:view/edit` | P0 |
|
||||||
|
| 库位管理 | `/master-data/locations` | 企业和仓库联动、筛选、分页、新增、编辑、启停、删除、可用库位状态 | `platform:location:*` | P0 |
|
||||||
|
| 托盘管理 | `/master-data/pallets` | 企业和仓库联动、筛选、分页、新增、编辑、删除 | `platform:pallet:*` | P0 |
|
||||||
|
|
||||||
|
所有业务表格的“操作”列放在第一列,并检查窄屏退化。
|
||||||
|
|
||||||
|
### 3.2 入库详情内部功能
|
||||||
|
|
||||||
|
入库详情建议作为一个路由页,以页签或分区承载以下能力,不为每一步增加侧边栏菜单:
|
||||||
|
|
||||||
|
| 分区 | 能力 | 交互边界 |
|
||||||
|
|---|---|---|
|
||||||
|
| 概览与历史 | 入仓码、订单/客户/仓库快照、申报与实测汇总、文件、内部备注、状态历史 | 切换企业后清空全部上下文 |
|
||||||
|
| 测量与 OCR | 第三方箱规、测量草稿、称重图片上传/预览/OCR 重试、OCR 原值、置信度、人工修正、确认、提交审核 | 汇总重量和体积以服务端结果为准;不覆盖 OCR 原值 |
|
||||||
|
| 测量审核 | 原单、第三方测量、OCR 三组数据对比;通过、驳回、审核历史、异常放行 | 通过/驳回/放行携带幂等键;放行必须有专属权限和原因 |
|
||||||
|
| 费用快照 | 最新费用、规则版本、价格版本、实际量、折算量、计费量、单价、附加费、总额、发送状态 | 正常流程只读;已发布费用可按权限调整且必须填写原因 |
|
||||||
|
| 托盘库位 | 托盘号、分配体积/箱数、库位编码和占用结果 | 只读,不让前端拼托盘号、选择或占用库位 |
|
||||||
|
|
||||||
|
### 3.3 全局装配变更
|
||||||
|
|
||||||
|
- `src/app/router/index.ts`:装配二期模块路由。
|
||||||
|
- `src/core/navigation/adminNavigation.ts`:在“国内仓”下增加入库单、库位、托盘;新增“头程计费”分组。
|
||||||
|
- 路由和导航测试同步更新。
|
||||||
|
- IAM 权限页面无需业务改造;后端返回二期权限资源后沿用现有展示和授权能力。
|
||||||
|
- 不恢复“接收审核”“费用项目”“完整财务管理”等原型菜单。
|
||||||
|
|
||||||
|
## 四、Client 页面变更清单
|
||||||
|
|
||||||
|
Client 只修改现有 `FirstLegOrdersView.vue` 的订单详情抽屉,新增“入库与费用”只读区,不改路由、导航或模块注册。
|
||||||
|
|
||||||
|
展示内容:
|
||||||
|
|
||||||
|
- 入库结果:入仓码、入库状态、完成时间、平台收货仓。
|
||||||
|
- 实测汇总:实际箱数、实重、净重、实测体积、材积重、计费重量/体积。
|
||||||
|
- 托盘库位:托盘数、托盘号、分配体积、箱数和库位编码。
|
||||||
|
- 费用结果:计费模式、换算系数、实际量、折算量、最终计费量、单价、小计、附加费、总额、币种、规则/价格版本和发送时间。
|
||||||
|
- 只展示公开备注;不展示内部备注、原始操作历史、内部原因和操作人 ID。
|
||||||
|
|
||||||
|
状态处理:
|
||||||
|
|
||||||
|
- 草稿订单不请求入库费用接口,显示“订单提交后可查看入库结果”。
|
||||||
|
- 后端业务码 `A0404` 作为中性待处理态,显示“入库及费用结果尚未发布”。
|
||||||
|
- 其他失败只影响此区块,保留订单详情并提供区块级重试。
|
||||||
|
- 快速切换订单时使用请求序号或 `orderId` 校验,旧响应不得覆盖新订单。
|
||||||
|
- 不增加客户确认、调整、审核、发送费用或照片下载动作。
|
||||||
|
|
||||||
|
## 五、真实接口域
|
||||||
|
|
||||||
|
前端实现直接读取相邻 Controller/DTO,不需要另行准备后端接口文档。首批任务按以下接口域联调:
|
||||||
|
|
||||||
|
| 接口域 | Controller 入口 | 前端用途 |
|
||||||
|
|---|---|---|
|
||||||
|
| 入库查询 | `firstleg/.../PlatformInboundOrderController.java` | Admin 入库列表和聚合详情 |
|
||||||
|
| 测量/OCR | `firstleg/.../PlatformInboundMeasurementController.java` | 测量草稿、提交、OCR 登记/修正/确认 |
|
||||||
|
| 测量审核 | `firstleg/.../PlatformInboundMeasurementReviewController.java` | 通过、驳回、异常放行、审核历史 |
|
||||||
|
| FBA 基础资料 | `firstleg/.../PlatformFbaMasterDataController.java` | 客户规则和船司价格版本维护 |
|
||||||
|
| FBA 费用 | `firstleg/.../PlatformFbaPricingController.java` | 最新费用、异常恢复接口、已发布费用调整 |
|
||||||
|
| 称重图片 | `file/.../PlatformMeasurementImageController.java` | 上传、OCR 重试和鉴权查看 |
|
||||||
|
| 托盘 | `warehouse/.../PlatformPalletController.java` | 托盘 CRUD |
|
||||||
|
| 库位 | `warehouse/.../PlatformLocationController.java` | 库位 CRUD、状态和可用库位查询 |
|
||||||
|
| 商户结果 | `firstleg/.../MerchantInboundBillingController.java` | Client 订单入库与费用只读展示 |
|
||||||
|
|
||||||
|
共同约定:
|
||||||
|
|
||||||
|
- 浏览器代码使用现有 `/api` 基地址,不硬编码 Gateway 地址。
|
||||||
|
- 普通业务 HTTP 200 后仍需判断响应体 `code === "200"`。
|
||||||
|
- Java Long 在 JSON 中按字符串处理,前端不得转为 `Number`。
|
||||||
|
- Admin 当前接口显式需要目标 `tenantId`;切换企业必须清空仓库、详情、编辑、上传和幂等上下文。
|
||||||
|
- 409 表示版本或并发冲突,页面应刷新最新详情,不静默覆盖。
|
||||||
|
- 审核通过、驳回、异常放行和费用写操作按 Controller 要求携带 `Idempotency-Key`。
|
||||||
|
|
||||||
|
## 六、多对话并行任务表
|
||||||
|
|
||||||
|
### 6.0 实施状态(2026-08-04)
|
||||||
|
|
||||||
|
- `P2-ADM-01` 至 `P2-ADM-11`、`P2-CLI-01`、`P2-QA-01`、`P2-QA-02` 均已完成。
|
||||||
|
- Admin 已通过 `pnpm test`(58 个文件、262 个测试)、`pnpm typecheck` 和 `pnpm build`。
|
||||||
|
- Client 已通过 `pnpm test`(135 个测试)、`pnpm typecheck` 和 `pnpm build`。
|
||||||
|
- Admin 二期新增模块的 Impeccable detector 结果为 `[]`,模块依赖边界测试已通过。
|
||||||
|
- Admin 二期页面已再次按平台后台原型校正搜索条件、表格字段、字段顺序和详情分区;视觉组件统一复用现有 `QueryToolbar`、`DataTable`、`AppDrawer` 及状态组件。
|
||||||
|
- 原型字段只在当前后端 Controller/DTO 支持时落地;未恢复接收审核、客户确认、报关、智能装柜、托盘状态/启停、尺寸/承重及无接口的导入导出。
|
||||||
|
- Client 入库费用区沿用既有订单详情视觉,补充换算系数、舍入精度和规则/价格版本,保持只读并继续使用“入仓码”业务术语。
|
||||||
|
- 本轮未修改 `baiyue-firstleg/`;8.1 节的 Client 服务端响应数据暴露风险仍是上线阻断,不影响本轮前端任务完成状态。
|
||||||
|
|
||||||
|
### 6.1 任务定义
|
||||||
|
|
||||||
|
下表中未写应用前缀的 Admin 路径均相对 `apps/admin-web/src/`。
|
||||||
|
|
||||||
|
| ID | 对话任务 | 负责范围和文件所有权 | 交付与验收 | 依赖 | 波次 |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| `P2-ADM-01` | 入库列表与聚合查询 | 独占 `modules/inbounds/core/**`、`pages/InboundOrdersView.vue` 及测试 | 本域 types/API;企业选择、四页签、筛选、分页、操作列第一列、概览/历史只读组件、加载/空/错/权限态 | 只读入库查询 Controller/DTO | W1 |
|
||||||
|
| `P2-ADM-02` | 测量草稿与箱规 | 独占 `modules/inbounds/measurement/**` 及测试 | 本域 types/API/组件;第三方箱规、测量草稿、保存、提交审核、版本冲突和未保存保护 | 只读测量 Controller/DTO | W1 |
|
||||||
|
| `P2-ADM-03` | 称重图片与 OCR | 独占 `modules/inbounds/weight/**` 及测试 | 本域 types/API/组件;上传、预览、OCR 重试、原值/置信度、人工修正和确认 | 只读 File、测量 Controller/DTO | W1 |
|
||||||
|
| `P2-ADM-04` | 测量审核 | 独占 `modules/inbounds/review/**` 及测试 | 本域 types/API/组件;三组数据对比、历史、通过、驳回、异常放行、幂等和权限 | 只读审核 Controller/DTO/Service | W1 |
|
||||||
|
| `P2-ADM-05` | 入库费用快照 | 独占 `modules/inbounds/fee/**` 及测试 | 本域 types/API/组件;最新费用、完整计价过程、状态和已发布费用调整;不串常规 calculate/confirm/send | 只读 FBA 费用 Controller/DTO/Service | W1 |
|
||||||
|
| `P2-ADM-06` | 客户计费规则 | 独占 `modules/fba-pricing/customer-rules/**` 及测试 | 查询、详情、新版本、停用、权限和未保存保护 | 只读 `PlatformFbaMasterDataController` 客户规则契约 | W1 |
|
||||||
|
| `P2-ADM-07` | 船司 FBA 价格 | 独占 `modules/fba-pricing/carrier-rates/**` 及测试 | 查询、详情、新版本、停用、起运仓/渠道/船司/FBA 仓/价格和有效期 | 只读 `PlatformFbaMasterDataController` 价格契约 | W1 |
|
||||||
|
| `P2-ADM-08` | 库位管理 | 独占 `modules/warehouse-resources/locations/**` 及测试 | 企业/仓库级联、筛选分页、CRUD、启停、乐观锁、状态限制、响应式 | 现有企业选择器和仓库 API | W1 |
|
||||||
|
| `P2-ADM-09` | 托盘管理 | 独占 `modules/warehouse-resources/pallets/**` 及测试 | 企业/仓库级联、筛选分页、CRUD;不虚构状态或启停 | 现有企业选择器和仓库 API | W1 |
|
||||||
|
| `P2-ADM-10` | 入库详情工作台组装 | 独占 `modules/inbounds/pages/InboundOrderDetailView.vue`、`components/InboundWorkflowWorkspace.vue` 及测试 | 将 ADM-01 至 ADM-05 组件组装为详情页;统一刷新、租户切换清理、操作成功回读和托盘库位只读结果 | ADM-01 至 ADM-05 | W2 |
|
||||||
|
| `P2-ADM-11` | Admin 全局装配 | 独占各模块 `routes.ts`、`app/router/index.ts`、`core/navigation/adminNavigation.ts` 及对应测试 | 接入全部 Admin 页面、菜单和权限;首个可访问路由正确;不恢复接收审核/费用项目原型菜单 | ADM-06 至 ADM-10 | W3 |
|
||||||
|
| `P2-CLI-01` | 商户订单入库费用只读展示 | `apps/client-web/src/modules/first-leg/api/inboundBilling.ts`、`types/inboundBilling.ts`、`components/InboundBillingPanel.vue`、`views/FirstLegOrdersView.vue` 及测试 | 成功/待发布/失败/重试、快速切单、320/720/桌面;无写动作,不消费内部字段 | 只读 `MerchantInboundBillingController` 及 DTO/Service | W1 |
|
||||||
|
| `P2-QA-01` | Admin 跨模块回归 | 以新增集成测试和联调记录为主,不重构业务实现 | 租户切换、401/403、业务码、409、幂等、重复提交、图片异常、空/加载/失败、权限按钮、窄屏;运行 test/typecheck/build | `P2-ADM-11` | W4 |
|
||||||
|
| `P2-QA-02` | Client 安全与展示验收 | 只读审查和补测试,避免与 CLI-01 同时改订单页 | 不展示内部备注/历史;A0404 中性态;响应隔离;test/typecheck/build | `P2-CLI-01` | W2 |
|
||||||
|
|
||||||
|
### 6.2 推荐并行波次
|
||||||
|
|
||||||
|
```text
|
||||||
|
W1(10 个并行开发对话):
|
||||||
|
ADM-01 + ADM-02 + ADM-03 + ADM-04 + ADM-05
|
||||||
|
ADM-06 + ADM-07 + ADM-08 + ADM-09 + CLI-01
|
||||||
|
↓
|
||||||
|
W2(2 个并行对话): ADM-10 + QA-02
|
||||||
|
↓
|
||||||
|
W3(1 个集成对话): ADM-11
|
||||||
|
↓
|
||||||
|
W4: QA-01 跨模块联调、构建和回归
|
||||||
|
```
|
||||||
|
|
||||||
|
W1 的 10 个对话没有代码依赖,可以一次全部创建。真正的关键路径是 `ADM-01 至 ADM-05 → ADM-10 → ADM-11 → QA-01`;基础资料、仓库资源和 Client 与该链路完全并行。
|
||||||
|
|
||||||
|
### 6.3 多对话协作规则
|
||||||
|
|
||||||
|
- 每个对话只修改任务表声明的文件边界;发现需要改公共文件时留给 `P2-ADM-11`。
|
||||||
|
- `router/index.ts`、`adminNavigation.ts` 和对应测试只能由集成任务修改。
|
||||||
|
- 库位和托盘任务不得各自创建或修改同一个 `warehouse-resources/routes.ts`。
|
||||||
|
- 入库各业务域分别维护本域 `types.ts` 和 API,不创建共享巨型 DTO 文件;跨域只传 `tenantId: string`、`inboundId: string`、`readonly` 数据和 `changed` 事件。
|
||||||
|
- `ADM-01` 至 `ADM-05` 不创建或修改 `InboundOrderDetailView.vue`;详情页面只由 `ADM-10` 组装。
|
||||||
|
- `ADM-06`、`ADM-07` 不创建共同的 `fba-pricing/routes.ts`;路由只由 `ADM-11` 创建。
|
||||||
|
- Client 任务保持单对话实现,因为现有订单页超过一千行,拆成多个写任务会集中冲突。
|
||||||
|
- 每个任务完成后运行直接相关的测试和 typecheck;最终集成任务再运行全项目测试和构建。
|
||||||
|
- 后端契约疑问直接只读 Controller、DTO、Service、Repository/OpenAPI;本轮不得修改 `baiyue-firstleg/`。
|
||||||
|
|
||||||
|
## 七、当前后端源码未落地、暂不开发的范围
|
||||||
|
|
||||||
|
| 能力 | 本轮处理 | 原因 |
|
||||||
|
|---|---|---|
|
||||||
|
| 到仓预报和线下预约结果 | 暂不开发 | 无商户/平台公开接口 |
|
||||||
|
| 签到、分批收货、处理单元 | 暂不开发 | 无匹配 Controller |
|
||||||
|
| 标签打印和换标 | 暂不开发 | Print 服务仍是骨架,无业务公开接口 |
|
||||||
|
| 收货冲正 | 暂不开发 | 无匹配 Controller |
|
||||||
|
| 申报实测差异通知 | 暂不开发 | 无匹配 Controller |
|
||||||
|
| 上架任务和位置历史 | 暂不开发 | 当前只有托盘/库位和自动占用,无平台作业接口 |
|
||||||
|
| 通用费用项目白名单 | 暂不开发 | C6 未确认且无独立 Controller |
|
||||||
|
| 通知失败人工重试 | P1 候选 | 当前无明确平台公开接口 |
|
||||||
|
| 入库后换位 | P1 候选 | 当前无平台公开接口 |
|
||||||
|
| 测量视频、单票导出 | P1 候选 | 当前无明确契约 |
|
||||||
|
| 客户照片查看 | 暂不开发 | 当前无商户文件下载接口 |
|
||||||
|
|
||||||
|
## 八、上线阻断和风险
|
||||||
|
|
||||||
|
### 8.1 Client 数据暴露风险(上线阻断)
|
||||||
|
|
||||||
|
当前 `MerchantInboundBillingService` 直接返回平台侧 `InboundOrderDetail`,其中可能包含全部 `internalNotes` 和未按商户可见性过滤的 `files`。即使 Client 页面不渲染,这些字段仍会下发到浏览器。
|
||||||
|
|
||||||
|
前端必须做到:
|
||||||
|
|
||||||
|
- 商户 DTO 不声明、不读取、不渲染内部备注和原始内部历史。
|
||||||
|
- 不记录或展示原始响应对象。
|
||||||
|
|
||||||
|
但前端无法消除网络响应中的数据暴露,因此正式上线前仍需后端改为商户专用 DTO 或服务端字段过滤。该项不在本轮后端修改授权范围内,只登记为上线阻断。
|
||||||
|
|
||||||
|
### 8.2 需求和实现风险
|
||||||
|
|
||||||
|
- V2 C1-C8 尚未正式确认;若产品推翻当前自动计费入库流程,需要重新评估页面动作和任务边界。
|
||||||
|
- Admin 多个接口仍要求前端显式传目标 `tenantId`,与 V2“不相信前端 tenantId”的文字描述不同;前端按现有 Controller 调用,最终数据范围仍由服务端校验。
|
||||||
|
- 正常审核通过会自动完成后续动作,属于高影响写操作;页面确认文案必须明确结果,并防止重复点击。
|
||||||
|
- 计费规则和船司价格接口当前返回列表而非分页对象;页面不要先假设服务端分页。
|
||||||
|
- 托盘接口没有状态和启停能力;库位才有 `AVAILABLE/RESERVED/OCCUPIED/DISABLED` 状态。
|
||||||
|
|
||||||
|
## 九、每个任务的统一完成标准
|
||||||
|
|
||||||
|
- 严格按真实权限控制路由、菜单和按钮;前端权限只控制展示,服务端继续最终授权。
|
||||||
|
- 覆盖加载、空态、失败、无权限、业务冲突、重复操作和数据过期。
|
||||||
|
- 所有业务表格操作列在第一列,桌面端可固定左侧;窄屏不依赖表格末端操作。
|
||||||
|
- 所有 ID 保持字符串,金额、体积、重量和换算系数不硬编码、不自行推导为业务事实。
|
||||||
|
- 写操作成功后刷新服务端状态;409 或版本冲突提示用户并重载,不静默覆盖。
|
||||||
|
- Admin 运行 `pnpm test`、`pnpm typecheck`、`pnpm build`。
|
||||||
|
- Client 运行 `pnpm test`、`pnpm typecheck`、`pnpm build`。
|
||||||
|
- 不修改后端、不启动本地 Java/Nacos/数据库;联调默认通过测试 Gateway 的 `/api` 代理。
|
||||||
@@ -0,0 +1,225 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1600 1100" width="1600" height="1100" role="img" aria-labelledby="title desc">
|
||||||
|
<title id="title">跨境物流全链路流程图</title>
|
||||||
|
<desc id="desc">从头程下单、到仓计费、出仓及装船发运,到尾程到港前、到港、到仓、出仓和签收的完整业务流程。</desc>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="pageBg" x1="0" y1="0" x2="1" y2="1">
|
||||||
|
<stop offset="0" stop-color="#F5F9FF"/>
|
||||||
|
<stop offset="1" stop-color="#F7FBFA"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="firstMile" x1="0" y1="0" x2="1" y2="0">
|
||||||
|
<stop offset="0" stop-color="#155EEF"/>
|
||||||
|
<stop offset="1" stop-color="#2878FF"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="lastMile" x1="0" y1="0" x2="1" y2="0">
|
||||||
|
<stop offset="0" stop-color="#087E8B"/>
|
||||||
|
<stop offset="1" stop-color="#16A085"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="transit" x1="0" y1="0" x2="1" y2="0">
|
||||||
|
<stop offset="0" stop-color="#EAF2FF"/>
|
||||||
|
<stop offset="0.5" stop-color="#DDF5F1"/>
|
||||||
|
<stop offset="1" stop-color="#EAF2FF"/>
|
||||||
|
</linearGradient>
|
||||||
|
<filter id="shadow" x="-15%" y="-15%" width="130%" height="140%">
|
||||||
|
<feDropShadow dx="0" dy="8" stdDeviation="10" flood-color="#16324F" flood-opacity="0.09"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="softShadow" x="-20%" y="-20%" width="140%" height="150%">
|
||||||
|
<feDropShadow dx="0" dy="4" stdDeviation="6" flood-color="#0F3057" flood-opacity="0.10"/>
|
||||||
|
</filter>
|
||||||
|
<marker id="arrowBlue" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto">
|
||||||
|
<path d="M1 1L8 5L1 9" fill="none" stroke="#7AA7ED" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="arrowGreen" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto">
|
||||||
|
<path d="M1 1L8 5L1 9" fill="none" stroke="#62B8AD" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</marker>
|
||||||
|
<style>
|
||||||
|
text{font-family:"PingFang SC","Microsoft YaHei","Noto Sans SC",Arial,sans-serif}
|
||||||
|
.title{font-size:34px;font-weight:700;fill:#102A43;letter-spacing:1px}
|
||||||
|
.subtitle{font-size:15px;fill:#627D98}
|
||||||
|
.lane-title{font-size:22px;font-weight:700;fill:#fff}
|
||||||
|
.lane-en{font-size:11px;font-weight:600;fill:#fff;opacity:.72;letter-spacing:1.7px}
|
||||||
|
.phase-title{font-size:18px;font-weight:700;fill:#102A43}
|
||||||
|
.phase-no{font-size:11px;font-weight:700;fill:#fff;letter-spacing:.5px}
|
||||||
|
.step{font-size:13px;fill:#334E68}
|
||||||
|
.step-small{font-size:12px;fill:#334E68}
|
||||||
|
.step-no{font-size:10px;font-weight:700;fill:#fff}
|
||||||
|
.summary-label{font-size:11px;font-weight:700;fill:#627D98;letter-spacing:1px}
|
||||||
|
.summary-value{font-size:15px;font-weight:700;fill:#243B53}
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<rect width="1600" height="1100" fill="url(#pageBg)"/>
|
||||||
|
<circle cx="1490" cy="50" r="180" fill="#D9F1ED" opacity=".42"/>
|
||||||
|
<circle cx="90" cy="1080" r="220" fill="#DFEBFF" opacity=".48"/>
|
||||||
|
|
||||||
|
<!-- 标题与概览 -->
|
||||||
|
<text x="52" y="58" class="title">跨境物流全链路流程</text>
|
||||||
|
<text x="52" y="88" class="subtitle">从客户下单到海外签收 · 头程与尾程全节点协同</text>
|
||||||
|
<g transform="translate(1195 28)">
|
||||||
|
<rect width="112" height="60" rx="14" fill="#fff" stroke="#D9E2EC"/>
|
||||||
|
<text x="18" y="22" class="summary-label">业务阶段</text><text x="18" y="45" class="summary-value">8 个阶段</text>
|
||||||
|
<rect x="124" width="112" height="60" rx="14" fill="#fff" stroke="#D9E2EC"/>
|
||||||
|
<text x="142" y="22" class="summary-label">关键动作</text><text x="142" y="45" class="summary-value">36 个节点</text>
|
||||||
|
<rect x="248" width="112" height="60" rx="14" fill="#fff" stroke="#D9E2EC"/>
|
||||||
|
<text x="266" y="22" class="summary-label">最终结果</text><text x="266" y="45" class="summary-value">完成签收</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- 头程泳道 -->
|
||||||
|
<rect x="30" y="120" width="1540" height="430" rx="24" fill="#FFFFFF" stroke="#D7E4F4" filter="url(#shadow)"/>
|
||||||
|
<path d="M54 120H1546A24 24 0 0 1 1570 144V194H30V144A24 24 0 0 1 54 120Z" fill="url(#firstMile)"/>
|
||||||
|
<g transform="translate(58 142)">
|
||||||
|
<circle cx="22" cy="22" r="22" fill="#fff" opacity=".16"/>
|
||||||
|
<path d="M10 23h24M14 23v11h16V23M17 19v-6h10v6M21 27h3" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<text x="58" y="18" class="lane-title">头程物流</text>
|
||||||
|
<text x="58" y="38" class="lane-en">FIRST-MILE LOGISTICS · 国内集货与出口</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(1306 145)">
|
||||||
|
<rect width="210" height="42" rx="21" fill="#fff" opacity=".15"/>
|
||||||
|
<text x="105" y="26" text-anchor="middle" font-size="13" font-weight="600" fill="#fff">下单 → 到仓 → 出仓</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- 头程阶段连接 -->
|
||||||
|
<path d="M435 365H474" stroke="#7AA7ED" stroke-width="2" marker-end="url(#arrowBlue)"/>
|
||||||
|
<path d="M850 365H889" stroke="#7AA7ED" stroke-width="2" marker-end="url(#arrowBlue)"/>
|
||||||
|
|
||||||
|
<!-- 一、下单 -->
|
||||||
|
<g transform="translate(55 220)">
|
||||||
|
<rect width="380" height="300" rx="18" fill="#F8FBFF" stroke="#C9DBF7"/>
|
||||||
|
<circle cx="32" cy="32" r="17" fill="#155EEF"/><text x="32" y="36" text-anchor="middle" class="phase-no">01</text>
|
||||||
|
<text x="60" y="39" class="phase-title">下单</text>
|
||||||
|
<text x="326" y="37" font-size="11" fill="#829AB1">4 个动作</text>
|
||||||
|
<line x1="20" y1="64" x2="360" y2="64" stroke="#D9E8FA"/>
|
||||||
|
<g transform="translate(20 82)">
|
||||||
|
<rect width="340" height="42" rx="10" fill="#fff" stroke="#DFEAF8"/><circle cx="22" cy="21" r="11" fill="#3B82F6"/><text x="22" y="25" text-anchor="middle" class="step-no">1</text><text x="44" y="26" class="step">客户下单</text>
|
||||||
|
<rect y="52" width="340" height="42" rx="10" fill="#fff" stroke="#DFEAF8"/><circle cx="22" cy="73" r="11" fill="#3B82F6"/><text x="22" y="77" text-anchor="middle" class="step-no">2</text><text x="44" y="78" class="step">委托我们下单</text>
|
||||||
|
<rect y="104" width="340" height="42" rx="10" fill="#fff" stroke="#DFEAF8"/><circle cx="22" cy="125" r="11" fill="#3B82F6"/><text x="22" y="129" text-anchor="middle" class="step-no">3</text><text x="44" y="130" class="step">快速下单(只有唛头)</text>
|
||||||
|
<rect y="156" width="340" height="42" rx="10" fill="#fff" stroke="#DFEAF8"/><circle cx="22" cy="177" r="11" fill="#3B82F6"/><text x="22" y="181" text-anchor="middle" class="step-no">4</text><text x="44" y="182" class="step">换标下单(中转、退货)</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- 二、到仓 -->
|
||||||
|
<g transform="translate(470 220)">
|
||||||
|
<rect width="380" height="300" rx="18" fill="#F8FBFF" stroke="#C9DBF7"/>
|
||||||
|
<circle cx="32" cy="32" r="17" fill="#155EEF"/><text x="32" y="36" text-anchor="middle" class="phase-no">02</text>
|
||||||
|
<text x="60" y="39" class="phase-title">到仓</text>
|
||||||
|
<text x="326" y="37" font-size="11" fill="#829AB1">6 个动作</text>
|
||||||
|
<line x1="20" y1="64" x2="360" y2="64" stroke="#D9E8FA"/>
|
||||||
|
<g transform="translate(20 76)">
|
||||||
|
<rect width="340" height="32" rx="8" fill="#fff" stroke="#DFEAF8"/><circle cx="20" cy="16" r="10" fill="#3B82F6"/><text x="20" y="20" text-anchor="middle" class="step-no">1</text><text x="40" y="21" class="step">预约取货</text>
|
||||||
|
<rect y="36" width="340" height="32" rx="8" fill="#fff" stroke="#DFEAF8"/><circle cx="20" cy="52" r="10" fill="#3B82F6"/><text x="20" y="56" text-anchor="middle" class="step-no">2</text><text x="40" y="57" class="step">送货上门</text>
|
||||||
|
<rect y="72" width="340" height="32" rx="8" fill="#fff" stroke="#DFEAF8"/><circle cx="20" cy="88" r="10" fill="#3B82F6"/><text x="20" y="92" text-anchor="middle" class="step-no">3</text><text x="40" y="93" class="step">入库测量(称重计费)</text>
|
||||||
|
<rect y="108" width="340" height="32" rx="8" fill="#fff" stroke="#DFEAF8"/><circle cx="20" cy="124" r="10" fill="#3B82F6"/><text x="20" y="128" text-anchor="middle" class="step-no">4</text><text x="40" y="129" class="step">调整差异核对</text>
|
||||||
|
<rect y="144" width="340" height="32" rx="8" fill="#fff" stroke="#DFEAF8"/><circle cx="20" cy="160" r="10" fill="#3B82F6"/><text x="20" y="164" text-anchor="middle" class="step-no">5</text><text x="40" y="165" class="step">仓库作业(指定库位)</text>
|
||||||
|
<rect y="180" width="340" height="32" rx="8" fill="#EAF2FF" stroke="#BFD3F5"/><circle cx="20" cy="196" r="10" fill="#155EEF"/><text x="20" y="200" text-anchor="middle" class="step-no">6</text><text x="40" y="201" class="step" font-weight="600">计费</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- 三、出仓 -->
|
||||||
|
<g transform="translate(885 220)">
|
||||||
|
<rect width="660" height="300" rx="18" fill="#F8FBFF" stroke="#C9DBF7"/>
|
||||||
|
<circle cx="32" cy="32" r="17" fill="#155EEF"/><text x="32" y="36" text-anchor="middle" class="phase-no">03</text>
|
||||||
|
<text x="60" y="39" class="phase-title">出仓</text>
|
||||||
|
<text x="604" y="37" font-size="11" fill="#829AB1">9 个动作</text>
|
||||||
|
<line x1="20" y1="64" x2="640" y2="64" stroke="#D9E8FA"/>
|
||||||
|
<g transform="translate(20 76)">
|
||||||
|
<rect width="300" height="36" rx="9" fill="#fff" stroke="#DFEAF8"/><circle cx="20" cy="18" r="10" fill="#3B82F6"/><text x="20" y="22" text-anchor="middle" class="step-no">1</text><text x="40" y="23" class="step-small">智能排柜</text>
|
||||||
|
<rect y="42" width="300" height="36" rx="9" fill="#fff" stroke="#DFEAF8"/><circle cx="20" cy="60" r="10" fill="#3B82F6"/><text x="20" y="64" text-anchor="middle" class="step-no">2</text><text x="40" y="65" class="step-small">订舱</text>
|
||||||
|
<rect y="84" width="300" height="36" rx="9" fill="#fff" stroke="#DFEAF8"/><circle cx="20" cy="102" r="10" fill="#3B82F6"/><text x="20" y="106" text-anchor="middle" class="step-no">3</text><text x="40" y="107" class="step-small">预约托车</text>
|
||||||
|
<rect y="126" width="300" height="36" rx="9" fill="#fff" stroke="#DFEAF8"/><circle cx="20" cy="144" r="10" fill="#3B82F6"/><text x="20" y="148" text-anchor="middle" class="step-no">4</text><text x="40" y="149" class="step-small">PDA 拣货</text>
|
||||||
|
<rect y="168" width="300" height="36" rx="9" fill="#fff" stroke="#DFEAF8"/><circle cx="20" cy="186" r="10" fill="#3B82F6"/><text x="20" y="190" text-anchor="middle" class="step-no">5</text><text x="40" y="191" class="step-small">拍货柜及铅封照上传</text>
|
||||||
|
<rect x="320" width="300" height="36" rx="9" fill="#fff" stroke="#DFEAF8"/><circle cx="340" cy="18" r="10" fill="#3B82F6"/><text x="340" y="22" text-anchor="middle" class="step-no">6</text><text x="360" y="23" class="step-small">客户上传报关资料</text>
|
||||||
|
<rect x="320" y="42" width="300" height="36" rx="9" fill="#fff" stroke="#DFEAF8"/><circle cx="340" cy="60" r="10" fill="#3B82F6"/><text x="340" y="64" text-anchor="middle" class="step-no">7</text><text x="360" y="65" class="step-small">整理给到报关代理报关</text>
|
||||||
|
<rect x="320" y="84" width="300" height="36" rx="9" fill="#fff" stroke="#DFEAF8"/><circle cx="340" cy="102" r="10" fill="#3B82F6"/><text x="340" y="106" text-anchor="middle" class="step-no">8</text><text x="360" y="107" class="step-small">回执上传系统供客户下载</text>
|
||||||
|
<rect x="320" y="126" width="300" height="36" rx="9" fill="#fff" stroke="#DFEAF8"/><circle cx="340" cy="144" r="10" fill="#3B82F6"/><text x="340" y="148" text-anchor="middle" class="step-no">9</text><text x="360" y="149" class="step-small">查港务信息(预计开船、到港等)</text>
|
||||||
|
<g transform="translate(320 171)"><rect width="300" height="32" rx="16" fill="#E7F0FF"/><circle cx="24" cy="16" r="8" fill="#155EEF"/><path d="M20 16h8M24 12v8" stroke="#fff" stroke-width="1.5"/><text x="44" y="21" font-size="12" font-weight="600" fill="#155EEF">完成国内出仓,等待装船</text></g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- 海运衔接带 -->
|
||||||
|
<g transform="translate(350 570)" filter="url(#softShadow)">
|
||||||
|
<rect width="900" height="74" rx="37" fill="url(#transit)" stroke="#B9D8DF"/>
|
||||||
|
<path d="M0 37H286M614 37H900" stroke="#78AFC1" stroke-width="1.5" stroke-dasharray="7 7"/>
|
||||||
|
<g transform="translate(302 12)">
|
||||||
|
<circle cx="25" cy="25" r="25" fill="#fff"/>
|
||||||
|
<path d="M11 29h28l-4 7H16l-5-7Zm5-3h19l-3-11H19l-3 11Zm8-11V9h4v6" fill="none" stroke="#087E8B" stroke-width="2" stroke-linejoin="round"/>
|
||||||
|
<text x="68" y="23" font-size="16" font-weight="700" fill="#0B6070">装船发运 · 国际海运在途</text>
|
||||||
|
<text x="68" y="43" font-size="12" fill="#527C86">头程完成,进入海外清关与尾程履约</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- 尾程泳道 -->
|
||||||
|
<rect x="30" y="670" width="1540" height="400" rx="24" fill="#FFFFFF" stroke="#CFE7E2" filter="url(#shadow)"/>
|
||||||
|
<path d="M54 670H1546A24 24 0 0 1 1570 694V744H30V694A24 24 0 0 1 54 670Z" fill="url(#lastMile)"/>
|
||||||
|
<g transform="translate(58 692)">
|
||||||
|
<circle cx="22" cy="22" r="22" fill="#fff" opacity=".16"/>
|
||||||
|
<path d="M10 27h7l3-10h10l3 10h3M15 27a4 4 0 1 0 0 8 4 4 0 0 0 0-8Zm20 0a4 4 0 1 0 0 8 4 4 0 0 0 0-8Z" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<text x="58" y="18" class="lane-title">尾程物流</text>
|
||||||
|
<text x="58" y="38" class="lane-en">LAST-MILE LOGISTICS · 海外清关、入仓与派送</text>
|
||||||
|
</g>
|
||||||
|
<g transform="translate(1185 695)">
|
||||||
|
<rect width="330" height="42" rx="21" fill="#fff" opacity=".15"/>
|
||||||
|
<text x="165" y="26" text-anchor="middle" font-size="13" font-weight="600" fill="#fff">到港前 → 到港 → 到仓 → 出仓 → 签收</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- 尾程连接线 -->
|
||||||
|
<path d="M328 900H352" stroke="#62B8AD" stroke-width="2" marker-end="url(#arrowGreen)"/>
|
||||||
|
<path d="M633 900H657" stroke="#62B8AD" stroke-width="2" marker-end="url(#arrowGreen)"/>
|
||||||
|
<path d="M938 900H962" stroke="#62B8AD" stroke-width="2" marker-end="url(#arrowGreen)"/>
|
||||||
|
<path d="M1243 900H1267" stroke="#62B8AD" stroke-width="2" marker-end="url(#arrowGreen)"/>
|
||||||
|
|
||||||
|
<!-- 尾程阶段卡片 -->
|
||||||
|
<g transform="translate(48 770)">
|
||||||
|
<rect width="280" height="268" rx="16" fill="#F7FCFB" stroke="#CBE7E1"/>
|
||||||
|
<circle cx="28" cy="29" r="16" fill="#087E8B"/><text x="28" y="33" text-anchor="middle" class="phase-no">01</text><text x="54" y="35" class="phase-title">到港前</text><text x="54" y="53" font-size="11" fill="#648A87">船在海上</text>
|
||||||
|
<g transform="translate(16 72)">
|
||||||
|
<rect width="248" height="36" rx="9" fill="#fff" stroke="#D8EBE7"/><circle cx="18" cy="18" r="10" fill="#13A18D"/><text x="18" y="22" text-anchor="middle" class="step-no">1</text><text x="38" y="23" class="step-small">FBA 仓预约</text>
|
||||||
|
<rect y="42" width="248" height="44" rx="9" fill="#fff" stroke="#D8EBE7"/><circle cx="18" cy="64" r="10" fill="#13A18D"/><text x="18" y="68" text-anchor="middle" class="step-no">2</text><text x="38" y="61" class="step-small">BOL 预清货</text><text x="38" y="77" font-size="10" fill="#829AB1">时间、费用、目的仓</text>
|
||||||
|
<rect y="92" width="248" height="42" rx="9" fill="#fff" stroke="#D8EBE7"/><circle cx="18" cy="113" r="10" fill="#13A18D"/><text x="18" y="117" text-anchor="middle" class="step-no">3</text><text x="38" y="110" class="step-small">清关资料上传到</text><text x="38" y="126" class="step-small">对应货柜</text>
|
||||||
|
<rect y="140" width="248" height="36" rx="9" fill="#fff" stroke="#D8EBE7"/><circle cx="18" cy="158" r="10" fill="#13A18D"/><text x="18" y="162" text-anchor="middle" class="step-no">4</text><text x="38" y="163" class="step-small">明细备注货物中转等</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(353 770)">
|
||||||
|
<rect width="280" height="268" rx="16" fill="#F7FCFB" stroke="#CBE7E1"/>
|
||||||
|
<circle cx="28" cy="29" r="16" fill="#087E8B"/><text x="28" y="33" text-anchor="middle" class="phase-no">02</text><text x="54" y="35" class="phase-title">到港</text>
|
||||||
|
<g transform="translate(16 82)">
|
||||||
|
<rect width="248" height="50" rx="9" fill="#fff" stroke="#D8EBE7"/><circle cx="18" cy="25" r="10" fill="#13A18D"/><text x="18" y="29" text-anchor="middle" class="step-no">1</text><text x="38" y="30" class="step-small">清关放行</text>
|
||||||
|
<rect y="60" width="248" height="64" rx="9" fill="#fff" stroke="#D8EBE7"/><circle cx="18" cy="92" r="10" fill="#13A18D"/><text x="18" y="96" text-anchor="middle" class="step-no">2</text><text x="38" y="88" class="step-small">DO 或 PU 邮发</text><text x="38" y="106" class="step-small">通知码头车队提柜</text>
|
||||||
|
<rect y="136" width="248" height="38" rx="19" fill="#E3F6F2"/><text x="124" y="160" text-anchor="middle" font-size="12" font-weight="600" fill="#087E8B">完成提柜 · 运往海外仓</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(658 770)">
|
||||||
|
<rect width="280" height="268" rx="16" fill="#F7FCFB" stroke="#CBE7E1"/>
|
||||||
|
<circle cx="28" cy="29" r="16" fill="#087E8B"/><text x="28" y="33" text-anchor="middle" class="phase-no">03</text><text x="54" y="35" class="phase-title">到仓</text>
|
||||||
|
<g transform="translate(16 82)">
|
||||||
|
<rect width="248" height="42" rx="9" fill="#fff" stroke="#D8EBE7"/><circle cx="18" cy="21" r="10" fill="#13A18D"/><text x="18" y="25" text-anchor="middle" class="step-no">1</text><text x="38" y="26" class="step-small">开柜拍照比对</text>
|
||||||
|
<rect y="50" width="248" height="42" rx="9" fill="#fff" stroke="#D8EBE7"/><circle cx="18" cy="71" r="10" fill="#13A18D"/><text x="18" y="75" text-anchor="middle" class="step-no">2</text><text x="38" y="76" class="step-small">根据 PDA 需求打托作业</text>
|
||||||
|
<rect y="100" width="248" height="42" rx="9" fill="#fff" stroke="#D8EBE7"/><circle cx="18" cy="121" r="10" fill="#13A18D"/><text x="18" y="125" text-anchor="middle" class="step-no">3</text><text x="38" y="126" class="step-small">派送车队筛选预约</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(963 770)">
|
||||||
|
<rect width="280" height="268" rx="16" fill="#F7FCFB" stroke="#CBE7E1"/>
|
||||||
|
<circle cx="28" cy="29" r="16" fill="#087E8B"/><text x="28" y="33" text-anchor="middle" class="phase-no">04</text><text x="54" y="35" class="phase-title">出仓</text>
|
||||||
|
<g transform="translate(16 72)">
|
||||||
|
<rect width="248" height="34" rx="9" fill="#fff" stroke="#D8EBE7"/><circle cx="18" cy="17" r="9" fill="#13A18D"/><text x="18" y="21" text-anchor="middle" class="step-no">1</text><text x="36" y="22" class="step-small">预排车转 BOL 送货</text>
|
||||||
|
<rect y="40" width="248" height="34" rx="9" fill="#fff" stroke="#D8EBE7"/><circle cx="18" cy="57" r="9" fill="#13A18D"/><text x="18" y="61" text-anchor="middle" class="step-no">2</text><text x="36" y="62" class="step-small">PDA 拣货装车</text>
|
||||||
|
<rect y="80" width="248" height="34" rx="9" fill="#fff" stroke="#D8EBE7"/><circle cx="18" cy="97" r="9" fill="#13A18D"/><text x="18" y="101" text-anchor="middle" class="step-no">3</text><text x="36" y="102" class="step-small">派送车队到仓装车</text>
|
||||||
|
<rect y="120" width="248" height="34" rx="9" fill="#fff" stroke="#D8EBE7"/><circle cx="18" cy="137" r="9" fill="#13A18D"/><text x="18" y="141" text-anchor="middle" class="step-no">4</text><text x="36" y="142" class="step-small">整柜派送</text>
|
||||||
|
<rect y="160" width="248" height="34" rx="9" fill="#fff" stroke="#D8EBE7"/><circle cx="18" cy="177" r="9" fill="#13A18D"/><text x="18" y="181" text-anchor="middle" class="step-no">5</text><text x="36" y="182" class="step-small">自提出仓(一件代发)</text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<g transform="translate(1268 770)">
|
||||||
|
<rect width="284" height="268" rx="16" fill="#F7FCFB" stroke="#CBE7E1"/>
|
||||||
|
<circle cx="28" cy="29" r="16" fill="#087E8B"/><text x="28" y="33" text-anchor="middle" class="phase-no">05</text><text x="54" y="35" class="phase-title">签收</text>
|
||||||
|
<g transform="translate(16 82)">
|
||||||
|
<rect width="252" height="42" rx="9" fill="#fff" stroke="#D8EBE7"/><circle cx="18" cy="21" r="10" fill="#13A18D"/><text x="18" y="25" text-anchor="middle" class="step-no">1</text><text x="38" y="26" class="step-small">私人仓签收回执上传</text>
|
||||||
|
<rect y="50" width="252" height="42" rx="9" fill="#fff" stroke="#D8EBE7"/><circle cx="18" cy="71" r="10" fill="#13A18D"/><text x="18" y="75" text-anchor="middle" class="step-no">2</text><text x="38" y="76" class="step-small">FBA 仓签收回执上传</text>
|
||||||
|
<rect y="100" width="252" height="42" rx="9" fill="#fff" stroke="#D8EBE7"/><circle cx="18" cy="121" r="10" fill="#13A18D"/><text x="18" y="125" text-anchor="middle" class="step-no">3</text><text x="38" y="126" class="step-small">送仓异常处理</text>
|
||||||
|
<g transform="translate(0 156)"><rect width="252" height="38" rx="19" fill="#087E8B"/><circle cx="24" cy="19" r="9" fill="#fff" opacity=".2"/><path d="M20 19l3 3 6-7" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><text x="132" y="24" text-anchor="middle" font-size="13" font-weight="700" fill="#fff">全流程完成 · 已签收</text></g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<text x="800" y="1088" text-anchor="middle" font-size="11" fill="#829AB1">HEAD-HAUL & LAST-MILE LOGISTICS PROCESS · 全程节点可追踪</text>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 881 KiB |
|
After Width: | Height: | Size: 549 KiB |
|
After Width: | Height: | Size: 835 KiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 492 KiB |
|
After Width: | Height: | Size: 26 KiB |
@@ -0,0 +1,266 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>%s</title>
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;400;500;600;700;900&family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||||
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
<script>
|
||||||
|
tailwind.config = { theme: { extend: { colors: { brand: { green:'#4CAF50', greenDark:'#2E7D32', blue:'#1565C0', blueDark:'#0D47A1', teal:'#00838F', light:'#F0F7FF', dark:'#0A1628' } }, fontFamily: { sans:['Inter','Noto Sans SC','system-ui','sans-serif'] } } } };
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
:root { --primary:#1565C0; --primary-dark:#0D47A1; --accent:#4CAF50; --accent-dark:#2E7D32; }
|
||||||
|
* { scroll-behavior:smooth; }
|
||||||
|
body { font-family:'Inter','Noto Sans SC',system-ui,sans-serif; overflow-x:hidden; }
|
||||||
|
.gradient-text { background:linear-gradient(135deg,#1565C0 0%,#4CAF50 100%); -webkit-background-clip:text; -webkit-text-fill-color:transparent; background-clip:text; }
|
||||||
|
.gradient-bg { background:linear-gradient(135deg,#0A1628 0%,#1565C0 50%,#00838F 100%); }
|
||||||
|
.btn-primary { background:linear-gradient(135deg,#1565C0 0%,#0D47A1 100%); transition:all .3s ease; }
|
||||||
|
.btn-primary:hover { transform:translateY(-2px); box-shadow:0 10px 30px rgba(21,101,192,.35); }
|
||||||
|
.btn-accent { background:linear-gradient(135deg,#4CAF50 0%,#2E7D32 100%); transition:all .3s ease; }
|
||||||
|
.btn-accent:hover { transform:translateY(-2px); box-shadow:0 10px 30px rgba(76,175,80,.35); }
|
||||||
|
.input-field { transition:all .3s ease; }
|
||||||
|
.input-field:focus { border-color:#1565C0; box-shadow:0 0 0 4px rgba(21,101,192,.1); }
|
||||||
|
.auth-logo { display:block; filter:brightness(0) saturate(100%) invert(20%) sepia(84%) saturate(1926%) hue-rotate(202deg) brightness(94%) contrast(93%); }
|
||||||
|
.lang-switcher { display:flex; align-items:center; background:rgba(21,101,192,.08); border-radius:9999px; padding:3px; border:1px solid rgba(21,101,192,.15); }
|
||||||
|
.lang-switcher button { font-size:12px; font-weight:600; padding:4px 9px; border-radius:9999px; color:#0A1628; transition:all .25s ease; white-space:nowrap; }
|
||||||
|
.lang-switcher button:hover { color:#1565C0; }
|
||||||
|
.lang-switcher button.active { background:#1565C0; color:#fff; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body class="text-gray-800 antialiased bg-gray-50">
|
||||||
|
<!-- 顶部栏 -->
|
||||||
|
<header class="fixed top-0 inset-x-0 z-50 bg-white/95 backdrop-blur border-b border-gray-100">
|
||||||
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-16 flex items-center justify-between">
|
||||||
|
<a href="index.html" class="flex items-center" aria-label="返回官网">
|
||||||
|
<img src="assets/logo.png" alt="柏悦物流" class="auth-logo" style="width:161px;height:60px;object-fit:contain;">
|
||||||
|
</a>
|
||||||
|
<div class="lang-switcher" id="langSwitcher">
|
||||||
|
<button data-lang="zh" class="active" title="中文">中</button>
|
||||||
|
<button data-lang="en" title="English">EN</button>
|
||||||
|
<button data-lang="es" title="Español (México)">🇲🇽</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<section id="loginSection" class="min-h-screen pt-24 pb-12 bg-gray-50 flex items-center">
|
||||||
|
<div class="w-full max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
|
<div class="bg-white rounded-3xl shadow-2xl overflow-hidden">
|
||||||
|
<div class="grid lg:grid-cols-2">
|
||||||
|
<!-- 左侧视觉 -->
|
||||||
|
<div class="hidden lg:block relative">
|
||||||
|
<img src="https://images.unsplash.com/photo-1494412574643-ff11b0a5c1c3?ixlib=rb-4.0.3&auto=format&fit=crop&w=2070&q=80" alt="物流" class="absolute inset-0 w-full h-full object-cover">
|
||||||
|
<div class="absolute inset-0 gradient-bg opacity-90"></div>
|
||||||
|
<div class="relative z-10 p-12 h-full flex flex-col justify-between text-white">
|
||||||
|
<div>
|
||||||
|
<img src="assets/logo.png" alt="虫虫出海" style="width:161px;height:60px;object-fit:contain;">
|
||||||
|
<h2 class="text-3xl font-bold mb-4" data-i18n="login_welcome">欢迎回来</h2>
|
||||||
|
<p class="text-white/80" data-i18n="login_desc">登录虫虫出海平台,实时追踪货物轨迹,管理订单与库存。</p>
|
||||||
|
</div>
|
||||||
|
<div class="space-y-4">
|
||||||
|
<div class="flex items-center space-x-3">
|
||||||
|
<i class="fas fa-check-circle text-brand-green"></i>
|
||||||
|
<span data-i18n="login_feat1">全程可视化追踪</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center space-x-3">
|
||||||
|
<i class="fas fa-check-circle text-brand-green"></i>
|
||||||
|
<span data-i18n="login_feat2">智能订单管理</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center space-x-3">
|
||||||
|
<i class="fas fa-check-circle text-brand-green"></i>
|
||||||
|
<span data-i18n="login_feat3">在线询价下单</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 右侧表单 -->
|
||||||
|
<div class="p-8 sm:p-12 lg:p-16">
|
||||||
|
<div class="max-w-md mx-auto">
|
||||||
|
<h2 class="text-3xl font-bold text-gray-900 mb-2" data-i18n="login_title">账号登录</h2>
|
||||||
|
<p class="text-gray-600 mb-8"><span data-i18n="login_no_account">还没有账号?</span><button onclick="window.location.href='register.html'" class="text-brand-blue font-semibold hover:underline" data-i18n="login_register_link">立即注册</button></p>
|
||||||
|
|
||||||
|
<form id="loginForm" class="space-y-5">
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-gray-700 mb-2" data-i18n="login_account_label">邮箱 / 手机号</label>
|
||||||
|
<div class="relative">
|
||||||
|
<i class="fas fa-user absolute left-4 top-1/2 -translate-y-1/2 text-gray-400"></i>
|
||||||
|
<input type="text" name="account" required placeholder="请输入邮箱或手机号" data-i18n-ph="login_account_ph" class="input-field w-full pl-11 pr-4 py-3.5 border border-gray-200 rounded-xl outline-none">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-gray-700 mb-2" data-i18n="login_password_label">密码</label>
|
||||||
|
<div class="relative">
|
||||||
|
<i class="fas fa-lock absolute left-4 top-1/2 -translate-y-1/2 text-gray-400"></i>
|
||||||
|
<input type="password" name="password" required placeholder="请输入密码" data-i18n-ph="login_password_ph" class="input-field w-full pl-11 pr-12 py-3.5 border border-gray-200 rounded-xl outline-none">
|
||||||
|
<button type="button" class="toggle-password absolute right-4 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600">
|
||||||
|
<i class="fas fa-eye"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center justify-between text-sm">
|
||||||
|
<label class="flex items-center text-gray-600 cursor-pointer">
|
||||||
|
<input type="checkbox" class="w-4 h-4 text-brand-blue rounded border-gray-300 mr-2">
|
||||||
|
<span data-i18n="login_remember">记住我</span>
|
||||||
|
</label>
|
||||||
|
<button type="button" onclick="showToast(t('toast_resetpw'))" class="text-brand-blue hover:underline" data-i18n="login_forgot">忘记密码?</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="btn-primary w-full text-white font-bold py-4 rounded-xl text-lg" data-i18n="login_submit">
|
||||||
|
登 录
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div class="mt-8">
|
||||||
|
<div class="relative">
|
||||||
|
<div class="absolute inset-0 flex items-center">
|
||||||
|
<div class="w-full border-t border-gray-200"></div>
|
||||||
|
</div>
|
||||||
|
<div class="relative flex justify-center text-sm">
|
||||||
|
<span class="px-2 bg-white text-gray-500" data-i18n="login_other">其他方式登录</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-center space-x-4 mt-6">
|
||||||
|
<button onclick="showToast('微信登录即将上线')" class="w-12 h-12 rounded-full border border-gray-200 flex items-center justify-center text-green-600 hover:bg-green-50 transition-colors">
|
||||||
|
<i class="fab fa-weixin text-xl"></i>
|
||||||
|
</button>
|
||||||
|
<button onclick="showToast('企业微信登录即将上线')" class="w-12 h-12 rounded-full border border-gray-200 flex items-center justify-center text-blue-600 hover:bg-blue-50 transition-colors">
|
||||||
|
<i class="fas fa-briefcase text-xl"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section> <!-- Toast 提示 -->
|
||||||
|
<div id="toast" class="fixed top-24 left-1/2 -translate-x-1/2 z-[60] opacity-0 pointer-events-none transition-all duration-300 transform -translate-y-4">
|
||||||
|
<div class="bg-gray-900 text-white px-6 py-3 rounded-full shadow-2xl flex items-center space-x-2">
|
||||||
|
<i class="fas fa-info-circle text-brand-green"></i>
|
||||||
|
<span id="toastMessage">提示信息</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let currentLang = localStorage.getItem('cc_lang') || 'zh';
|
||||||
|
function t(key) {
|
||||||
|
return (i18n[currentLang] && i18n[currentLang][key] !== undefined) ? i18n[currentLang][key] : key;
|
||||||
|
}
|
||||||
|
const i18n = {
|
||||||
|
zh: {
|
||||||
|
login_welcome: "欢迎回来",
|
||||||
|
login_desc: "登录虫虫出海平台,实时追踪货物轨迹,管理订单与库存。",
|
||||||
|
login_feat1: "全程可视化追踪",
|
||||||
|
login_feat2: "智能订单管理",
|
||||||
|
login_feat3: "在线询价下单",
|
||||||
|
login_title: "账号登录",
|
||||||
|
login_no_account: "还没有账号?",
|
||||||
|
login_register_link: "立即注册",
|
||||||
|
login_account_label: "邮箱 / 手机号",
|
||||||
|
login_account_ph: "请输入邮箱或手机号",
|
||||||
|
login_password_label: "密码",
|
||||||
|
login_password_ph: "请输入密码",
|
||||||
|
login_remember: "记住我",
|
||||||
|
login_forgot: "忘记密码?",
|
||||||
|
login_submit: "登 录",
|
||||||
|
login_other: "其他方式登录",
|
||||||
|
toast_resetpw: "请联系客服重置密码",
|
||||||
|
toast_login_ok: "登录成功!欢迎回来"
|
||||||
|
},
|
||||||
|
en: {
|
||||||
|
login_welcome: "Welcome Back",
|
||||||
|
login_desc: "Log in to track shipments in real time and manage orders and inventory.",
|
||||||
|
login_feat1: "Full Visual Tracking",
|
||||||
|
login_feat2: "Smart Order Management",
|
||||||
|
login_feat3: "Online Quoting & Ordering",
|
||||||
|
login_title: "Account Login",
|
||||||
|
login_no_account: "No account yet?",
|
||||||
|
login_register_link: "Sign Up Now",
|
||||||
|
login_account_label: "Email / Phone",
|
||||||
|
login_account_ph: "Enter email or phone",
|
||||||
|
login_password_label: "Password",
|
||||||
|
login_password_ph: "Enter password",
|
||||||
|
login_remember: "Remember Me",
|
||||||
|
login_forgot: "Forgot Password?",
|
||||||
|
login_submit: "Log In",
|
||||||
|
login_other: "Other Sign-In Methods",
|
||||||
|
toast_resetpw: "Please contact support to reset your password",
|
||||||
|
toast_login_ok: "Login successful! Welcome back"
|
||||||
|
},
|
||||||
|
es: {
|
||||||
|
login_welcome: "Bienvenido de nuevo",
|
||||||
|
login_desc: "Inicia sesión para rastrear envíos en tiempo real y gestionar pedidos e inventario.",
|
||||||
|
login_feat1: "Seguimiento visual completo",
|
||||||
|
login_feat2: "Gestión inteligente de pedidos",
|
||||||
|
login_feat3: "Cotización y pedidos en línea",
|
||||||
|
login_title: "Inicio de sesión",
|
||||||
|
login_no_account: "¿Aún no tienes cuenta?",
|
||||||
|
login_register_link: "Regístrate ahora",
|
||||||
|
login_account_label: "Correo / Teléfono",
|
||||||
|
login_account_ph: "Ingresa correo o teléfono",
|
||||||
|
login_password_label: "Contraseña",
|
||||||
|
login_password_ph: "Ingresa tu contraseña",
|
||||||
|
login_remember: "Recuérdame",
|
||||||
|
login_forgot: "¿Olvidó su contraseña?",
|
||||||
|
login_submit: "Iniciar sesión",
|
||||||
|
login_other: "Otros métodos de acceso",
|
||||||
|
toast_resetpw: "Contacta a soporte para restablecer tu contraseña",
|
||||||
|
toast_login_ok: "¡Inicio de sesión exitoso! Bienvenido"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
function applyLanguage(lang) {
|
||||||
|
if (!i18n[lang]) lang = 'zh';
|
||||||
|
currentLang = lang;
|
||||||
|
const langAttr = lang === 'zh' ? 'zh-CN' : (lang === 'es' ? 'es-MX' : 'en');
|
||||||
|
document.documentElement.setAttribute('lang', langAttr);
|
||||||
|
document.querySelectorAll('[data-i18n]').forEach(el => {
|
||||||
|
const k = el.getAttribute('data-i18n');
|
||||||
|
const v = i18n[lang][k];
|
||||||
|
if (v !== undefined) { if (v.indexOf('<br>') !== -1) el.innerHTML = v; else el.textContent = v; }
|
||||||
|
});
|
||||||
|
document.querySelectorAll('[data-i18n-ph]').forEach(el => {
|
||||||
|
const k = el.getAttribute('data-i18n-ph');
|
||||||
|
if (i18n[lang][k] !== undefined) el.setAttribute('placeholder', i18n[lang][k]);
|
||||||
|
});
|
||||||
|
document.querySelectorAll('[data-lang]').forEach(b => {
|
||||||
|
b.classList.toggle('active', b.getAttribute('data-lang') === lang);
|
||||||
|
});
|
||||||
|
try { localStorage.setItem('cc_lang', lang); } catch (e) {}
|
||||||
|
}
|
||||||
|
document.querySelectorAll('#langSwitcher [data-lang]').forEach(b => {
|
||||||
|
b.addEventListener('click', () => applyLanguage(b.getAttribute('data-lang')));
|
||||||
|
});
|
||||||
|
function showToast(message) {
|
||||||
|
const toast = document.getElementById('toast');
|
||||||
|
const toastMessage = document.getElementById('toastMessage');
|
||||||
|
toastMessage.textContent = message;
|
||||||
|
toast.classList.remove('opacity-0', 'pointer-events-none', '-translate-y-4');
|
||||||
|
toast.classList.add('opacity-100', 'translate-y-0');
|
||||||
|
setTimeout(() => {
|
||||||
|
toast.classList.add('opacity-0', 'pointer-events-none', '-translate-y-4');
|
||||||
|
toast.classList.remove('opacity-100', 'translate-y-0');
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
function updateAuthUI() {}
|
||||||
|
document.querySelectorAll('.toggle-password').forEach(button => {
|
||||||
|
button.addEventListener('click', function() {
|
||||||
|
const input = this.previousElementSibling;
|
||||||
|
const icon = this.querySelector('i');
|
||||||
|
if (input.type === 'password') { input.type = 'text'; icon.classList.remove('fa-eye'); icon.classList.add('fa-eye-slash'); }
|
||||||
|
else { input.type = 'password'; icon.classList.remove('fa-eye-slash'); icon.classList.add('fa-eye'); }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
document.getElementById('loginForm').addEventListener('submit', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
showToast(t('toast_login_ok'));
|
||||||
|
setTimeout(() => window.location.href = 'workbench.html', 900);
|
||||||
|
});
|
||||||
|
applyLanguage(currentLang);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
After Width: | Height: | Size: 764 KiB |
@@ -0,0 +1,286 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>%s</title>
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;400;500;600;700;900&family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||||
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
<script>
|
||||||
|
tailwind.config = { theme: { extend: { colors: { brand: { green:'#4CAF50', greenDark:'#2E7D32', blue:'#1565C0', blueDark:'#0D47A1', teal:'#00838F', light:'#F0F7FF', dark:'#0A1628' } }, fontFamily: { sans:['Inter','Noto Sans SC','system-ui','sans-serif'] } } } };
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
:root { --primary:#1565C0; --primary-dark:#0D47A1; --accent:#4CAF50; --accent-dark:#2E7D32; }
|
||||||
|
* { scroll-behavior:smooth; }
|
||||||
|
body { font-family:'Inter','Noto Sans SC',system-ui,sans-serif; overflow-x:hidden; }
|
||||||
|
.gradient-text { background:linear-gradient(135deg,#1565C0 0%,#4CAF50 100%); -webkit-background-clip:text; -webkit-text-fill-color:transparent; background-clip:text; }
|
||||||
|
.gradient-bg { background:linear-gradient(135deg,#0A1628 0%,#1565C0 50%,#00838F 100%); }
|
||||||
|
.btn-primary { background:linear-gradient(135deg,#1565C0 0%,#0D47A1 100%); transition:all .3s ease; }
|
||||||
|
.btn-primary:hover { transform:translateY(-2px); box-shadow:0 10px 30px rgba(21,101,192,.35); }
|
||||||
|
.btn-accent { background:linear-gradient(135deg,#4CAF50 0%,#2E7D32 100%); transition:all .3s ease; }
|
||||||
|
.btn-accent:hover { transform:translateY(-2px); box-shadow:0 10px 30px rgba(76,175,80,.35); }
|
||||||
|
.input-field { transition:all .3s ease; }
|
||||||
|
.input-field:focus { border-color:#1565C0; box-shadow:0 0 0 4px rgba(21,101,192,.1); }
|
||||||
|
.auth-logo { display:block; filter:brightness(0) saturate(100%) invert(20%) sepia(84%) saturate(1926%) hue-rotate(202deg) brightness(94%) contrast(93%); }
|
||||||
|
.lang-switcher { display:flex; align-items:center; background:rgba(21,101,192,.08); border-radius:9999px; padding:3px; border:1px solid rgba(21,101,192,.15); }
|
||||||
|
.lang-switcher button { font-size:12px; font-weight:600; padding:4px 9px; border-radius:9999px; color:#0A1628; transition:all .25s ease; white-space:nowrap; }
|
||||||
|
.lang-switcher button:hover { color:#1565C0; }
|
||||||
|
.lang-switcher button.active { background:#1565C0; color:#fff; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body class="text-gray-800 antialiased bg-gray-50">
|
||||||
|
<!-- 顶部栏 -->
|
||||||
|
<header class="fixed top-0 inset-x-0 z-50 bg-white/95 backdrop-blur border-b border-gray-100">
|
||||||
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-16 flex items-center justify-between">
|
||||||
|
<a href="index.html" class="flex items-center" aria-label="返回官网">
|
||||||
|
<img src="assets/logo.png" alt="柏悦物流" class="auth-logo" style="width:161px;height:60px;object-fit:contain;">
|
||||||
|
</a>
|
||||||
|
<div class="lang-switcher" id="langSwitcher">
|
||||||
|
<button data-lang="zh" class="active" title="中文">中</button>
|
||||||
|
<button data-lang="en" title="English">EN</button>
|
||||||
|
<button data-lang="es" title="Español (México)">🇲🇽</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<section id="registerSection" class="min-h-screen pt-24 pb-12 bg-gray-50 flex items-center">
|
||||||
|
<div class="w-full max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||||
|
<div class="bg-white rounded-3xl shadow-2xl overflow-hidden">
|
||||||
|
<div class="grid lg:grid-cols-2">
|
||||||
|
<!-- 左侧视觉 -->
|
||||||
|
<div class="hidden lg:block relative">
|
||||||
|
<img src="https://images.unsplash.com/photo-1566576912321-d58ddd7a6088?ixlib=rb-4.0.3&auto=format&fit=crop&w=2070&q=80" alt="物流仓储" class="absolute inset-0 w-full h-full object-cover">
|
||||||
|
<div class="absolute inset-0 gradient-bg opacity-90"></div>
|
||||||
|
<div class="relative z-10 p-12 h-full flex flex-col justify-between text-white">
|
||||||
|
<div>
|
||||||
|
<img src="assets/logo.png" alt="虫虫出海" style="width:161px;height:60px;object-fit:contain;">
|
||||||
|
<h2 class="text-3xl font-bold mb-4" data-i18n="reg_welcome">加入我们</h2>
|
||||||
|
<p class="text-white/80" data-i18n="reg_welcome_desc">注册虫虫出海企业账号,开启高效跨境物流体验。</p>
|
||||||
|
</div>
|
||||||
|
<div class="space-y-4">
|
||||||
|
<div class="flex items-center space-x-3">
|
||||||
|
<i class="fas fa-check-circle text-brand-green"></i>
|
||||||
|
<span data-i18n="reg_feat1">新用户专属优惠</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center space-x-3">
|
||||||
|
<i class="fas fa-check-circle text-brand-green"></i>
|
||||||
|
<span data-i18n="reg_feat2">免费获取物流方案</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center space-x-3">
|
||||||
|
<i class="fas fa-check-circle text-brand-green"></i>
|
||||||
|
<span data-i18n="reg_feat3">专属客户经理对接</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 右侧表单 -->
|
||||||
|
<div class="p-8 sm:p-12 lg:p-16">
|
||||||
|
<div class="max-w-md mx-auto">
|
||||||
|
<h2 class="text-3xl font-bold text-gray-900 mb-2" data-i18n="reg_title">企业注册</h2>
|
||||||
|
<p class="text-gray-600 mb-8"><span data-i18n="reg_have_account">已有账号?</span><button onclick="window.location.href='login.html'" class="text-brand-blue font-semibold hover:underline" data-i18n="reg_login_link">立即登录</button></p>
|
||||||
|
|
||||||
|
<form id="registerForm" class="space-y-5">
|
||||||
|
<div class="grid sm:grid-cols-2 gap-5">
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-gray-700 mb-2" data-i18n="reg_company_label">企业名称</label>
|
||||||
|
<input type="text" name="company" required placeholder="请输入企业名称" data-i18n-ph="reg_company_ph" class="input-field w-full px-4 py-3.5 border border-gray-200 rounded-xl outline-none">
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-gray-700 mb-2" data-i18n="reg_contact_label">联系人</label>
|
||||||
|
<input type="text" name="contact" required placeholder="请输入联系人姓名" data-i18n-ph="reg_contact_ph" class="input-field w-full px-4 py-3.5 border border-gray-200 rounded-xl outline-none">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-gray-700 mb-2" data-i18n="reg_email_label">邮箱</label>
|
||||||
|
<div class="relative">
|
||||||
|
<i class="fas fa-envelope absolute left-4 top-1/2 -translate-y-1/2 text-gray-400"></i>
|
||||||
|
<input type="email" name="email" required placeholder="请输入企业邮箱" data-i18n-ph="reg_email_ph" class="input-field w-full pl-11 pr-4 py-3.5 border border-gray-200 rounded-xl outline-none">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-gray-700 mb-2" data-i18n="reg_phone_label">手机号</label>
|
||||||
|
<div class="relative">
|
||||||
|
<i class="fas fa-phone absolute left-4 top-1/2 -translate-y-1/2 text-gray-400"></i>
|
||||||
|
<input type="tel" name="phone" required placeholder="请输入手机号" data-i18n-ph="reg_phone_ph" class="input-field w-full pl-11 pr-4 py-3.5 border border-gray-200 rounded-xl outline-none">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm font-medium text-gray-700 mb-2" data-i18n="reg_password_label">密码</label>
|
||||||
|
<div class="relative">
|
||||||
|
<i class="fas fa-lock absolute left-4 top-1/2 -translate-y-1/2 text-gray-400"></i>
|
||||||
|
<input type="password" name="password" required placeholder="请设置8-20位密码" data-i18n-ph="reg_password_ph" class="input-field w-full pl-11 pr-12 py-3.5 border border-gray-200 rounded-xl outline-none">
|
||||||
|
<button type="button" class="toggle-password absolute right-4 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600">
|
||||||
|
<i class="fas fa-eye"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-start">
|
||||||
|
<input type="checkbox" id="agree" required class="w-4 h-4 text-brand-blue rounded border-gray-300 mt-1 mr-2">
|
||||||
|
<label for="agree" class="text-sm text-gray-600">
|
||||||
|
<span data-i18n="reg_agree">我已阅读并同意</span> <button type="button" onclick="showToast(t('toast_tos'))" class="text-brand-blue hover:underline" data-i18n="reg_agree_tos">《用户服务协议》</button> 和 <button type="button" onclick="showToast(t('toast_pp'))" class="text-brand-blue hover:underline" data-i18n="reg_agree_pp">《隐私政策》</button>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="btn-accent w-full text-white font-bold py-4 rounded-xl text-lg" data-i18n="reg_submit">
|
||||||
|
立即注册
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section> <!-- Toast 提示 -->
|
||||||
|
<div id="toast" class="fixed top-24 left-1/2 -translate-x-1/2 z-[60] opacity-0 pointer-events-none transition-all duration-300 transform -translate-y-4">
|
||||||
|
<div class="bg-gray-900 text-white px-6 py-3 rounded-full shadow-2xl flex items-center space-x-2">
|
||||||
|
<i class="fas fa-info-circle text-brand-green"></i>
|
||||||
|
<span id="toastMessage">提示信息</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let currentLang = localStorage.getItem('cc_lang') || 'zh';
|
||||||
|
function t(key) {
|
||||||
|
return (i18n[currentLang] && i18n[currentLang][key] !== undefined) ? i18n[currentLang][key] : key;
|
||||||
|
}
|
||||||
|
const i18n = {
|
||||||
|
zh: {
|
||||||
|
reg_welcome: "加入我们",
|
||||||
|
reg_welcome_desc: "注册虫虫出海企业账号,开启高效跨境物流体验。",
|
||||||
|
reg_feat1: "新用户专属优惠",
|
||||||
|
reg_feat2: "免费获取物流方案",
|
||||||
|
reg_feat3: "专属客户经理对接",
|
||||||
|
reg_title: "企业注册",
|
||||||
|
reg_have_account: "已有账号?",
|
||||||
|
reg_login_link: "立即登录",
|
||||||
|
reg_company_label: "企业名称",
|
||||||
|
reg_company_ph: "请输入企业名称",
|
||||||
|
reg_contact_label: "联系人",
|
||||||
|
reg_contact_ph: "请输入联系人姓名",
|
||||||
|
reg_email_label: "邮箱",
|
||||||
|
reg_email_ph: "请输入企业邮箱",
|
||||||
|
reg_phone_label: "手机号",
|
||||||
|
reg_phone_ph: "请输入手机号",
|
||||||
|
reg_password_label: "密码",
|
||||||
|
reg_password_ph: "请设置8-20位密码",
|
||||||
|
reg_agree: "我已阅读并同意",
|
||||||
|
reg_agree_tos: "《用户服务协议》",
|
||||||
|
reg_agree_pp: "《隐私政策》",
|
||||||
|
reg_submit: "立即注册",
|
||||||
|
toast_tos: "服务协议即将上线",
|
||||||
|
toast_pp: "隐私政策即将上线",
|
||||||
|
toast_register_ok: "注册成功!欢迎加入虫虫出海"
|
||||||
|
},
|
||||||
|
en: {
|
||||||
|
reg_welcome: "Join Us",
|
||||||
|
reg_welcome_desc: "Register a Chongchong Global business account and start efficient cross-border logistics.",
|
||||||
|
reg_feat1: "Exclusive New-User Offers",
|
||||||
|
reg_feat2: "Free Logistics Plan",
|
||||||
|
reg_feat3: "Dedicated Account Manager",
|
||||||
|
reg_title: "Business Registration",
|
||||||
|
reg_have_account: "Already have an account?",
|
||||||
|
reg_login_link: "Log In Now",
|
||||||
|
reg_company_label: "Company Name",
|
||||||
|
reg_company_ph: "Enter company name",
|
||||||
|
reg_contact_label: "Contact Person",
|
||||||
|
reg_contact_ph: "Enter contact name",
|
||||||
|
reg_email_label: "Email",
|
||||||
|
reg_email_ph: "Enter company email",
|
||||||
|
reg_phone_label: "Phone Number",
|
||||||
|
reg_phone_ph: "Enter phone number",
|
||||||
|
reg_password_label: "Password",
|
||||||
|
reg_password_ph: "Set an 8-20 char password",
|
||||||
|
reg_agree: "I have read and agree to the",
|
||||||
|
reg_agree_tos: "User Agreement",
|
||||||
|
reg_agree_pp: "Privacy Policy",
|
||||||
|
reg_submit: "Sign Up Now",
|
||||||
|
toast_tos: "Terms of Service coming soon",
|
||||||
|
toast_pp: "Privacy Policy coming soon",
|
||||||
|
toast_register_ok: "Registration successful! Welcome to Chongchong Global"
|
||||||
|
},
|
||||||
|
es: {
|
||||||
|
reg_welcome: "Únete a nosotros",
|
||||||
|
reg_welcome_desc: "Regístrate en la cuenta empresarial de Chongchong Global y comienza una logística eficiente.",
|
||||||
|
reg_feat1: "Ofertas exclusivas para nuevos usuarios",
|
||||||
|
reg_feat2: "Plan logístico gratuito",
|
||||||
|
reg_feat3: "Gerente de cuenta dedicado",
|
||||||
|
reg_title: "Registro empresarial",
|
||||||
|
reg_have_account: "¿Ya tienes una cuenta?",
|
||||||
|
reg_login_link: "Inicia sesión ahora",
|
||||||
|
reg_company_label: "Nombre de empresa",
|
||||||
|
reg_company_ph: "Ingresa el nombre de empresa",
|
||||||
|
reg_contact_label: "Persona de contacto",
|
||||||
|
reg_contact_ph: "Ingresa el nombre de contacto",
|
||||||
|
reg_email_label: "Correo electrónico",
|
||||||
|
reg_email_ph: "Ingresa el correo empresarial",
|
||||||
|
reg_phone_label: "Número de teléfono",
|
||||||
|
reg_phone_ph: "Ingresa tu número de teléfono",
|
||||||
|
reg_password_label: "Contraseña",
|
||||||
|
reg_password_ph: "Define una contraseña de 8-20 caracteres",
|
||||||
|
reg_agree: "He leído y acepto los",
|
||||||
|
reg_agree_tos: "Términos de servicio",
|
||||||
|
reg_agree_pp: "Política de privacidad",
|
||||||
|
reg_submit: "Regístrate ahora",
|
||||||
|
toast_tos: "Términos de servicio próximamente",
|
||||||
|
toast_pp: "Política de privacidad próximamente",
|
||||||
|
toast_register_ok: "¡Registro exitoso! Bienvenido a Chongchong Global"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
function applyLanguage(lang) {
|
||||||
|
if (!i18n[lang]) lang = 'zh';
|
||||||
|
currentLang = lang;
|
||||||
|
const langAttr = lang === 'zh' ? 'zh-CN' : (lang === 'es' ? 'es-MX' : 'en');
|
||||||
|
document.documentElement.setAttribute('lang', langAttr);
|
||||||
|
document.querySelectorAll('[data-i18n]').forEach(el => {
|
||||||
|
const k = el.getAttribute('data-i18n');
|
||||||
|
const v = i18n[lang][k];
|
||||||
|
if (v !== undefined) { if (v.indexOf('<br>') !== -1) el.innerHTML = v; else el.textContent = v; }
|
||||||
|
});
|
||||||
|
document.querySelectorAll('[data-i18n-ph]').forEach(el => {
|
||||||
|
const k = el.getAttribute('data-i18n-ph');
|
||||||
|
if (i18n[lang][k] !== undefined) el.setAttribute('placeholder', i18n[lang][k]);
|
||||||
|
});
|
||||||
|
document.querySelectorAll('[data-lang]').forEach(b => {
|
||||||
|
b.classList.toggle('active', b.getAttribute('data-lang') === lang);
|
||||||
|
});
|
||||||
|
try { localStorage.setItem('cc_lang', lang); } catch (e) {}
|
||||||
|
}
|
||||||
|
document.querySelectorAll('#langSwitcher [data-lang]').forEach(b => {
|
||||||
|
b.addEventListener('click', () => applyLanguage(b.getAttribute('data-lang')));
|
||||||
|
});
|
||||||
|
function showToast(message) {
|
||||||
|
const toast = document.getElementById('toast');
|
||||||
|
const toastMessage = document.getElementById('toastMessage');
|
||||||
|
toastMessage.textContent = message;
|
||||||
|
toast.classList.remove('opacity-0', 'pointer-events-none', '-translate-y-4');
|
||||||
|
toast.classList.add('opacity-100', 'translate-y-0');
|
||||||
|
setTimeout(() => {
|
||||||
|
toast.classList.add('opacity-0', 'pointer-events-none', '-translate-y-4');
|
||||||
|
toast.classList.remove('opacity-100', 'translate-y-0');
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
function updateAuthUI() {}
|
||||||
|
document.querySelectorAll('.toggle-password').forEach(button => {
|
||||||
|
button.addEventListener('click', function() {
|
||||||
|
const input = this.previousElementSibling;
|
||||||
|
const icon = this.querySelector('i');
|
||||||
|
if (input.type === 'password') { input.type = 'text'; icon.classList.remove('fa-eye'); icon.classList.add('fa-eye-slash'); }
|
||||||
|
else { input.type = 'password'; icon.classList.remove('fa-eye-slash'); icon.classList.add('fa-eye'); }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
document.getElementById('registerForm').addEventListener('submit', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
showToast(t('toast_register_ok'));
|
||||||
|
setTimeout(() => window.location.href = 'workbench.html', 900);
|
||||||
|
});
|
||||||
|
applyLanguage(currentLang);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 764 KiB |
@@ -0,0 +1,49 @@
|
|||||||
|
const http = require('http');
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const PORT = 8081;
|
||||||
|
|
||||||
|
const mimeTypes = {
|
||||||
|
'.html': 'text/html',
|
||||||
|
'.js': 'text/javascript',
|
||||||
|
'.css': 'text/css',
|
||||||
|
'.json': 'application/json',
|
||||||
|
'.png': 'image/png',
|
||||||
|
'.jpg': 'image/jpg',
|
||||||
|
'.gif': 'image/gif',
|
||||||
|
'.svg': 'image/svg+xml',
|
||||||
|
'.ico': 'image/x-icon'
|
||||||
|
};
|
||||||
|
|
||||||
|
const server = http.createServer((req, res) => {
|
||||||
|
console.log(`${req.method} ${req.url}`);
|
||||||
|
|
||||||
|
let filePath = '.' + req.url;
|
||||||
|
if (filePath === './') {
|
||||||
|
filePath = './index.html';
|
||||||
|
}
|
||||||
|
|
||||||
|
const extname = String(path.extname(filePath)).toLowerCase();
|
||||||
|
const contentType = mimeTypes[extname] || 'application/octet-stream';
|
||||||
|
|
||||||
|
fs.readFile(filePath, (error, content) => {
|
||||||
|
if (error) {
|
||||||
|
if (error.code === 'ENOENT') {
|
||||||
|
res.writeHead(404, { 'Content-Type': 'text/html' });
|
||||||
|
res.end('<h1>404 Not Found</h1>', 'utf-8');
|
||||||
|
} else {
|
||||||
|
res.writeHead(500);
|
||||||
|
res.end('Server Error: ' + error.code, 'utf-8');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res.writeHead(200, { 'Content-Type': contentType });
|
||||||
|
res.end(content, 'utf-8');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
server.listen(PORT, () => {
|
||||||
|
console.log(`[TraePreviewUrl]: http://localhost:${PORT}`);
|
||||||
|
console.log(`Server running at http://localhost:${PORT}/`);
|
||||||
|
});
|
||||||
@@ -0,0 +1,290 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
柏悦WMS - 分阶段脚本
|
||||||
|
Phase 1: 登录并保存cookies (需要可见浏览器+手动验证码)
|
||||||
|
Phase 2: 加载cookies, headless模式抓取所有页面
|
||||||
|
|
||||||
|
用法:
|
||||||
|
python3 scrape_wms_final.py login # 阶段1: 登录保存cookie
|
||||||
|
python3 scrape_wms_final.py scrape # 阶段2: 用cookie抓取
|
||||||
|
"""
|
||||||
|
import asyncio, json, sys, os, time
|
||||||
|
from playwright.async_api import async_playwright
|
||||||
|
|
||||||
|
BASE = "http://39.101.149.173"
|
||||||
|
API_BASE = "https://adtest.bylogistic.cn"
|
||||||
|
USERNAME = "admin"
|
||||||
|
PASSWORD = "ndui#Emdfj23123"
|
||||||
|
COOKIE_FILE = "/tmp/wms_cookies.json"
|
||||||
|
OUTPUT_DIR = os.path.expanduser("~/Documents/柏悦")
|
||||||
|
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
||||||
|
|
||||||
|
async def phase_login():
|
||||||
|
"""打开浏览器让用户登录,然后保存cookies"""
|
||||||
|
async with async_playwright() as p:
|
||||||
|
browser = await p.chromium.launch(headless=False, args=["--start-maximized"])
|
||||||
|
context = await browser.new_context(viewport={"width": 1440, "height": 900})
|
||||||
|
page = await context.new_page()
|
||||||
|
|
||||||
|
print("=== 打开登录页 ===")
|
||||||
|
await page.goto(f"{BASE}/user/login?redirect=%2Fwms%2FByInstoreList", timeout=30000)
|
||||||
|
await page.wait_for_timeout(2000)
|
||||||
|
|
||||||
|
# 自动填充
|
||||||
|
inputs_text = page.locator("input[type='text']")
|
||||||
|
input_pwd = page.locator("input[type='password']")
|
||||||
|
await inputs_text.nth(0).fill(USERNAME)
|
||||||
|
await input_pwd.fill(PASSWORD)
|
||||||
|
|
||||||
|
print("✅ 账号密码已填写")
|
||||||
|
print("👉 请在浏览器中输入验证码并点击'确定'")
|
||||||
|
print("⏳ 等待登录成功...")
|
||||||
|
|
||||||
|
try:
|
||||||
|
await page.wait_for_function(
|
||||||
|
"() => !window.location.pathname.includes('login')",
|
||||||
|
timeout=300000 # 等5分钟
|
||||||
|
)
|
||||||
|
print(f"✅ 登录成功! URL: {page.url}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ 等待超时: {e}")
|
||||||
|
try:
|
||||||
|
await browser.close()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 立即保存cookies(不等页面加载完)
|
||||||
|
try:
|
||||||
|
await page.wait_for_timeout(3000)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
cookies = await context.cookies()
|
||||||
|
with open(COOKIE_FILE, "w") as f:
|
||||||
|
json.dump(cookies, f, indent=2)
|
||||||
|
print(f"✅ Cookies已保存到 {COOKIE_FILE} ({len(cookies)} 个)")
|
||||||
|
except Exception as ce:
|
||||||
|
print(f"⚠️ Cookie保存出错: {ce}")
|
||||||
|
|
||||||
|
# 截图当前页
|
||||||
|
try:
|
||||||
|
await page.screenshot(path="/tmp/wms_logged_in.png", full_page=True)
|
||||||
|
print("📸 当前页面截图: /tmp/wms_logged_in.png")
|
||||||
|
except Exception as se:
|
||||||
|
print(f"⚠️ 截图出错: {se}")
|
||||||
|
|
||||||
|
# 保持浏览器打开
|
||||||
|
print("\n浏览器将保持10秒后关闭...")
|
||||||
|
try:
|
||||||
|
await asyncio.sleep(10)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
await browser.close()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return True
|
||||||
|
|
||||||
|
async def phase_scrape():
|
||||||
|
"""加载cookies并headless抓取所有页面"""
|
||||||
|
|
||||||
|
# 读取cookies
|
||||||
|
if not os.path.exists(COOKIE_FILE):
|
||||||
|
print(f"❌ Cookie文件不存在: {COOKIE_FILE}")
|
||||||
|
print("请先运行: python3 scrape_wms_final.py login")
|
||||||
|
return
|
||||||
|
|
||||||
|
with open(COOKIE_FILE) as f:
|
||||||
|
saved_cookies = json.load(f)
|
||||||
|
print(f"🍪 加载了 {len(saved_cookies)} 个cookies")
|
||||||
|
|
||||||
|
async with async_playwright() as p:
|
||||||
|
browser = await p.chromium.launch(headless=True)
|
||||||
|
context = await browser.new_context(viewport={"width": 1440, "height": 900})
|
||||||
|
await context.add_cookies(saved_cookies)
|
||||||
|
page = await context.new_page()
|
||||||
|
|
||||||
|
# 监听API
|
||||||
|
all_apis = []
|
||||||
|
page.on("response", lambda r: all_apis.append({
|
||||||
|
"url": r.url, "status": r.status, "method": r.request.method
|
||||||
|
}))
|
||||||
|
|
||||||
|
# 先访问入库单列表(默认首页)
|
||||||
|
print("\n=== 访问系统首页 ===")
|
||||||
|
await page.goto(f"{BASE}/wms/ByInstoreList", timeout=20000)
|
||||||
|
await page.wait_for_timeout(4000)
|
||||||
|
|
||||||
|
if "login" in page.url.lower():
|
||||||
|
print("❌ Cookies已失效,请重新运行 login 命令")
|
||||||
|
await browser.close()
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f"✅ 已进入系统: {page.url}")
|
||||||
|
|
||||||
|
# ===== 抓取菜单结构 =====
|
||||||
|
print("\n=== 抓取菜单结构 ===")
|
||||||
|
|
||||||
|
menu_structure = {}
|
||||||
|
|
||||||
|
# 一级菜单
|
||||||
|
top_menus = page.locator(".ant-menu-submenu-title")
|
||||||
|
top_count = await top_menus.count()
|
||||||
|
|
||||||
|
for i in range(top_count):
|
||||||
|
try:
|
||||||
|
name = (await top_menus.nth(i).inner_text()).strip().split("\n")[0].strip()
|
||||||
|
if not name or len(name) > 20:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 展开菜单
|
||||||
|
await top_menus.nth(i).click()
|
||||||
|
await page.wait_for_timeout(600)
|
||||||
|
|
||||||
|
# 获取子菜单
|
||||||
|
sub_items = page.locator(".ant-menu-submenu-open .ant-menu-item")
|
||||||
|
subs = []
|
||||||
|
for j in range(await sub_items.count()):
|
||||||
|
try:
|
||||||
|
sn = (await sub_items.nth(j).inner_text()).strip().split("\n")[0]
|
||||||
|
if sn and len(sn) < 30:
|
||||||
|
subs.append(sn)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
menu_structure[name] = subs
|
||||||
|
print(f" 📂 {name}: {subs}")
|
||||||
|
|
||||||
|
# 收起
|
||||||
|
await top_menus.nth(i).click()
|
||||||
|
await page.wait_for_timeout(300)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# 所有要访问的页面路径
|
||||||
|
pages_to_visit = [
|
||||||
|
("首页", "/wms/Dashboard"),
|
||||||
|
("入库单列表", "/wms/ByInstoreList"),
|
||||||
|
("入库单测量", "/wms/ByInstoreList4Measured"),
|
||||||
|
("测量数据审核", "/wms/ByInstoreList4MeasuredAudit"),
|
||||||
|
("接收审核", "/wms/ByInstoreList4ReceiveAudit"),
|
||||||
|
("客户管理", "/wms/ByCustomerList"),
|
||||||
|
("出库单列表", "/wms/ByOutstoreList"),
|
||||||
|
("派送单列表", "/wms/ByDispatchList"),
|
||||||
|
("货柜管理", "/wms/ByContainerList"),
|
||||||
|
("库存管理", "/wms/ByInventoryList"),
|
||||||
|
("财务结算", "/wms/ByFinanceList"),
|
||||||
|
("托盘管理", "/wms/ByTrayList"),
|
||||||
|
("BOL管理", "/wms/ByBolList"),
|
||||||
|
("用户管理", "/system/UserList"),
|
||||||
|
("角色管理", "/system/RoleList"),
|
||||||
|
("菜单管理", "/system/MenuList"),
|
||||||
|
("字典管理", "/system/DictList"),
|
||||||
|
("参数配置", "/system/ConfigList"),
|
||||||
|
]
|
||||||
|
|
||||||
|
# ===== 逐页抓取 =====
|
||||||
|
print(f"\n=== 逐页抓取 (共{len(pages_to_visit)}页) ===\n")
|
||||||
|
pages_data = {}
|
||||||
|
|
||||||
|
for idx, (name, path) in enumerate(pages_to_visit, 1):
|
||||||
|
try:
|
||||||
|
url = BASE + path
|
||||||
|
print(f"[{idx}/{len(pages_to_visit)}] {name} -> {path}", end=" ... ")
|
||||||
|
|
||||||
|
await page.goto(url, timeout=15000)
|
||||||
|
await page.wait_for_timeout(2500)
|
||||||
|
|
||||||
|
if "login" in page.url.lower():
|
||||||
|
print("❌ 会话过期!")
|
||||||
|
break
|
||||||
|
|
||||||
|
entry = {
|
||||||
|
"title": await page.title(),
|
||||||
|
"url": page.url,
|
||||||
|
}
|
||||||
|
|
||||||
|
# 表格列头
|
||||||
|
headers = []
|
||||||
|
ths = page.locator(".ant-table-thead th, thead th, [class*='table'] th")
|
||||||
|
for i in range(min(await ths.count(), 25)):
|
||||||
|
h = (await ths.nth(i).inner_text()).strip()
|
||||||
|
if h and h not in headers:
|
||||||
|
headers.append(h)
|
||||||
|
|
||||||
|
# 搜索条件字段
|
||||||
|
fields = []
|
||||||
|
labels = page.locator(".ant-form-item-label label, .query-group label, label[for]")
|
||||||
|
for i in range(min(await labels.count(), 20)):
|
||||||
|
t = (await labels.nth(i).inner_text()).strip()
|
||||||
|
if t and t not in fields and len(t) < 30:
|
||||||
|
fields.append(t)
|
||||||
|
|
||||||
|
# 操作按钮
|
||||||
|
buttons = []
|
||||||
|
btns = page.locator(".ant-btn:not(.ant-pagination-item):not(.ant-pagination-options-quick-jumper):not([class*='link'])")
|
||||||
|
for i in range(min(await btns.count(), 15)):
|
||||||
|
b = (await btns.nth(i).inner_text()).strip()
|
||||||
|
if b and b not in buttons and len(b) < 20 and b not in ["刷 新","关 闭"]:
|
||||||
|
buttons.append(b)
|
||||||
|
|
||||||
|
# 统计卡片数字
|
||||||
|
stat_vals = []
|
||||||
|
stats = page.locator("[class*='statistic'] [class*='value'], [class*='number-card'] [class*='value']")
|
||||||
|
for i in range(min(await stats.count(), 10)):
|
||||||
|
s = (await stats.nth(i).inner_text()).strip()
|
||||||
|
if s:
|
||||||
|
stat_vals.append(s)
|
||||||
|
|
||||||
|
entry["table_headers"] = headers
|
||||||
|
entry["search_fields"] = fields
|
||||||
|
entry["buttons"] = buttons
|
||||||
|
entry["statistics"] = stat_vals
|
||||||
|
|
||||||
|
pages_data[name] = entry
|
||||||
|
print(f"✅ 表头:{len(headers)} 字段:{len(fields)} 按钮:{len(buttons)}")
|
||||||
|
|
||||||
|
# 截图每个页面
|
||||||
|
safe_name = name.replace("/", "_").replace("\\", "_")
|
||||||
|
await page.screenshot(path=f"/tmp/wms_page_{safe_name}.png")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ {e}")
|
||||||
|
pages_data[name] = {"error": str(e)}
|
||||||
|
|
||||||
|
# 保存完整数据
|
||||||
|
full_data = {
|
||||||
|
"system_name": "柏悦物流管理系统 (Baiyue WMS)",
|
||||||
|
"base_url": BASE,
|
||||||
|
"api_base": API_BASE,
|
||||||
|
"scrape_time": time.strftime("%Y-%m-%d %H:%M:%S"),
|
||||||
|
"menu_structure": menu_structure,
|
||||||
|
"pages": pages_data,
|
||||||
|
"api_calls": all_apis[-50:], # 最后50个API调用
|
||||||
|
}
|
||||||
|
|
||||||
|
output_file = os.path.join(OUTPUT_DIR, "wms_system_data.json")
|
||||||
|
with open(output_file, "w", encoding="utf-8") as f:
|
||||||
|
json.dump(full_data, f, indent=2, ensure_ascii=False)
|
||||||
|
|
||||||
|
print(f"\n{'='*60}")
|
||||||
|
print(f"✅ 全部完成!")
|
||||||
|
print(f" - 菜单: {len(menu_structure)} 个一级模块")
|
||||||
|
print(f" - 页面: {len(pages_data)} 个页面")
|
||||||
|
print(f" - 输出: {output_file}")
|
||||||
|
print(f"{'='*60}")
|
||||||
|
|
||||||
|
await browser.close()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
cmd = sys.argv[1] if len(sys.argv) > 1 else "login"
|
||||||
|
if cmd == "login":
|
||||||
|
asyncio.run(phase_login())
|
||||||
|
elif cmd == "scrape":
|
||||||
|
asyncio.run(phase_scrape())
|
||||||
|
else:
|
||||||
|
print(f"Usage: python3 {sys.argv[0]} [login|scrape]")
|
||||||
@@ -0,0 +1,207 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
从可见浏览器中提取token,然后用API方式抓取所有数据
|
||||||
|
"""
|
||||||
|
import asyncio, json, os, time
|
||||||
|
from playwright.async_api import async_playwright
|
||||||
|
|
||||||
|
BASE = "http://39.101.149.173"
|
||||||
|
USERNAME = "admin"
|
||||||
|
PASSWORD = "ndui#Emdfj23123"
|
||||||
|
TOKEN_FILE = "/tmp/wms_token.json"
|
||||||
|
OUTPUT_DIR = os.path.expanduser("~/Documents/柏悦")
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
async with async_playwright() as p:
|
||||||
|
browser = await p.chromium.launch(headless=False, args=["--start-maximized"])
|
||||||
|
context = await browser.new_context(viewport={"width": 1440, "height": 900})
|
||||||
|
page = await context.new_page()
|
||||||
|
|
||||||
|
print("=== 打开登录页 ===")
|
||||||
|
await page.goto(f"{BASE}/user/login?redirect=%2Fwms%2FByInstoreList", timeout=30000)
|
||||||
|
await page.wait_for_timeout(2000)
|
||||||
|
|
||||||
|
# 填充
|
||||||
|
inputs = page.locator("input[type='text']")
|
||||||
|
pwd = page.locator("input[type='password']")
|
||||||
|
await inputs.nth(0).fill(USERNAME)
|
||||||
|
await pwd.fill(PASSWORD)
|
||||||
|
|
||||||
|
print("👉 请在浏览器中输入验证码并点击确定...")
|
||||||
|
|
||||||
|
try:
|
||||||
|
await page.wait_for_function(
|
||||||
|
"() => !window.location.pathname.includes('login')",
|
||||||
|
timeout=300000
|
||||||
|
)
|
||||||
|
print("✅ 登录成功!")
|
||||||
|
except:
|
||||||
|
print("❌ 超时")
|
||||||
|
await browser.close()
|
||||||
|
return
|
||||||
|
|
||||||
|
await page.wait_for_timeout(3000)
|
||||||
|
|
||||||
|
# ========== 抓取完整菜单结构 ==========
|
||||||
|
print("\n=== 抓取菜单 ===")
|
||||||
|
menu_structure = {}
|
||||||
|
page_list = [] # [(display_name, url_path)]
|
||||||
|
|
||||||
|
top_menus = page.locator(".ant-menu-submenu-title")
|
||||||
|
for i in range(await top_menus.count()):
|
||||||
|
try:
|
||||||
|
name = (await top_menus.nth(i).inner_text()).strip().split("\n")[0].strip()
|
||||||
|
if not name or len(name) > 20:
|
||||||
|
continue
|
||||||
|
|
||||||
|
await top_menus.nth(i).click()
|
||||||
|
await page.wait_for_timeout(500)
|
||||||
|
|
||||||
|
subs = []
|
||||||
|
sub_items = page.locator(".ant-menu-submenu-open .ant-menu-item")
|
||||||
|
for j in range(await sub_items.count()):
|
||||||
|
sn = (await sub_items.nth(j).inner_text()).strip().split("\n")[0]
|
||||||
|
if sn and len(sn) < 30:
|
||||||
|
subs.append(sn)
|
||||||
|
|
||||||
|
menu_structure[name] = subs
|
||||||
|
print(f" {name}: {subs}")
|
||||||
|
|
||||||
|
await top_menus.nth(i).click()
|
||||||
|
await page.wait_for_timeout(300)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# ========== 逐页截图抓取 ==========
|
||||||
|
print(f"\n=== 逐页抓取 ===")
|
||||||
|
|
||||||
|
# 构建所有要访问的页面
|
||||||
|
all_pages = [("首页", "/wms/Dashboard")]
|
||||||
|
|
||||||
|
for menu_name, subs in menu_structure.items():
|
||||||
|
for sub in subs:
|
||||||
|
# 推断URL路径
|
||||||
|
path_map = {
|
||||||
|
"入库单列表": "/wms/ByInstoreList",
|
||||||
|
"入库单测量": "/wms/ByInstoreList4Measured",
|
||||||
|
"测量数据审核": "/wms/ByInstoreList4MeasuredAudit",
|
||||||
|
"接收审核": "/wms/ByInstoreList4ReceiveAudit",
|
||||||
|
"客户管理": "/wms/ByCustomerList",
|
||||||
|
"出库单列表": "/wms/ByOutstoreList",
|
||||||
|
"派送单列表": "/wms/ByDispatchList",
|
||||||
|
"BOL管理": "/wms/ByBolList",
|
||||||
|
"货柜管理": "/wms/ByContainerList",
|
||||||
|
"库存管理": "/wms/ByInventoryList",
|
||||||
|
"财务结算": "/wms/ByFinanceList",
|
||||||
|
"托盘管理": "/wms/ByTrayList",
|
||||||
|
"用户管理": "/system/UserList",
|
||||||
|
"角色管理": "/system/RoleList",
|
||||||
|
"菜单管理": "/system/MenuList",
|
||||||
|
"字典管理": "/system/DictList",
|
||||||
|
"参数配置": "/system/ConfigList",
|
||||||
|
"通用配置": "/system/ConfigList",
|
||||||
|
"报表设计": "/wms/Dashboard", # 待确认
|
||||||
|
"消息中心": "/wms/Dashboard",
|
||||||
|
"常见案例": "/wms/Dashboard",
|
||||||
|
"在线开发": "/wms/Dashboard",
|
||||||
|
"系统监控": "/wms/Dashboard",
|
||||||
|
"统计报表": "/wms/Dashboard",
|
||||||
|
}
|
||||||
|
path = path_map.get(sub, "")
|
||||||
|
if path:
|
||||||
|
all_pages.append((f"{menu_name} > {sub}", path))
|
||||||
|
|
||||||
|
# 去重
|
||||||
|
seen = set()
|
||||||
|
unique_pages = []
|
||||||
|
for name, path in all_pages:
|
||||||
|
if path not in seen:
|
||||||
|
seen.add(path)
|
||||||
|
unique_pages.append((name, path))
|
||||||
|
|
||||||
|
pages_data = {}
|
||||||
|
success_count = 0
|
||||||
|
|
||||||
|
for idx, (name, path) in enumerate(unique_pages, 1):
|
||||||
|
try:
|
||||||
|
url = BASE + path
|
||||||
|
print(f"[{idx}/{len(unique_pages)}] {name}", end=" ... ")
|
||||||
|
|
||||||
|
await page.goto(url, timeout=15000)
|
||||||
|
await page.wait_for_timeout(2500)
|
||||||
|
|
||||||
|
if "login" in page.url.lower():
|
||||||
|
print("会话过期!")
|
||||||
|
break
|
||||||
|
|
||||||
|
# 抓表格列头
|
||||||
|
headers = []
|
||||||
|
th_selectors = [".ant-table-thead th", "thead th", "table th"]
|
||||||
|
for ths in th_selectors:
|
||||||
|
els = page.locator(ths)
|
||||||
|
for i in range(min(await els.count(), 30)):
|
||||||
|
try:
|
||||||
|
h = (await els.nth(i).inner_text()).strip()
|
||||||
|
if h and h not in headers:
|
||||||
|
headers.append(h)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# 搜索字段
|
||||||
|
fields = []
|
||||||
|
labels = page.locator("label, .ant-form-item-label")
|
||||||
|
for i in range(min(await labels.count(), 25)):
|
||||||
|
try:
|
||||||
|
t = (await labels.nth(i).inner_text()).strip()
|
||||||
|
if t and t not in fields and len(t) < 30:
|
||||||
|
fields.append(t)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# 操作按钮
|
||||||
|
buttons = []
|
||||||
|
btns = page.locator("button:not([class*='pagination']):not([class*='quick-jumper'])")
|
||||||
|
for i in range(min(await btns.count(), 20)):
|
||||||
|
try:
|
||||||
|
b = (await btns.nth(i).inner_text()).strip()
|
||||||
|
if b and b not in buttons and len(b) < 25:
|
||||||
|
buttons.append(b)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
pages_data[name] = {
|
||||||
|
"url": url,
|
||||||
|
"title": await page.title(),
|
||||||
|
"table_headers": headers,
|
||||||
|
"search_fields": fields,
|
||||||
|
"buttons": buttons,
|
||||||
|
}
|
||||||
|
|
||||||
|
print(f"✅ headers:{len(headers)} fields:{len(fields)} btns:{len(buttons)}")
|
||||||
|
success_count += 1
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ {str(e)[:80]}")
|
||||||
|
pages_data[name] = {"error": str(e)[:200]}
|
||||||
|
|
||||||
|
# 保存数据
|
||||||
|
output = {
|
||||||
|
"system_name": "柏悦物流管理系统 (Baiyue WMS)",
|
||||||
|
"scrape_time": time.strftime("%Y-%m-%d %H:%M:%S"),
|
||||||
|
"menu_structure": menu_structure,
|
||||||
|
"pages": pages_data,
|
||||||
|
"pages_count": success_count,
|
||||||
|
}
|
||||||
|
|
||||||
|
out_path = os.path.join(OUTPUT_DIR, "wms_full_data.json")
|
||||||
|
with open(out_path, "w", encoding="utf-8") as f:
|
||||||
|
json.dump(output, f, indent=2, ensure_ascii=False)
|
||||||
|
|
||||||
|
print(f"\n✅ 完成! {success_count}/{len(unique_pages)} 页面成功抓取")
|
||||||
|
print(f"输出: {out_path}")
|
||||||
|
|
||||||
|
print("\n浏览器10秒后关闭...")
|
||||||
|
await asyncio.sleep(10)
|
||||||
|
await browser.close()
|
||||||
|
|
||||||
|
asyncio.run(main())
|
||||||
@@ -0,0 +1,322 @@
|
|||||||
|
{
|
||||||
|
"system_name": "柏悦物流管理系统 (Baiyue WMS)",
|
||||||
|
"scrape_time": "2026-06-01 12:06:00",
|
||||||
|
"menu_structure": {
|
||||||
|
"客户管理": [
|
||||||
|
"客户公司管理",
|
||||||
|
"用户资料",
|
||||||
|
"海外仓阶梯费用",
|
||||||
|
"客户账户流水"
|
||||||
|
],
|
||||||
|
"入库": [
|
||||||
|
"入库单列表",
|
||||||
|
"入库单测量",
|
||||||
|
"测量数据审核",
|
||||||
|
"接收审核"
|
||||||
|
],
|
||||||
|
"出库": [
|
||||||
|
"派送单列表",
|
||||||
|
"BOL",
|
||||||
|
"自提单"
|
||||||
|
],
|
||||||
|
"货柜管理": [
|
||||||
|
"货柜列表",
|
||||||
|
"装柜清单"
|
||||||
|
],
|
||||||
|
"库存": [
|
||||||
|
"海外仓库存查询",
|
||||||
|
"理货管理",
|
||||||
|
"报损单"
|
||||||
|
],
|
||||||
|
"财务结算": [
|
||||||
|
"客户应收应付",
|
||||||
|
"客户对账单",
|
||||||
|
"结算单位应付",
|
||||||
|
"结算单位对账单",
|
||||||
|
"洛杉矶仓储成本"
|
||||||
|
],
|
||||||
|
"托盘管理": [
|
||||||
|
"托盘列表",
|
||||||
|
"生成托盘"
|
||||||
|
],
|
||||||
|
"通用": [
|
||||||
|
"产品信息",
|
||||||
|
"费用项目",
|
||||||
|
"FBA编码地址",
|
||||||
|
"托盘管理",
|
||||||
|
"库位/货架管理",
|
||||||
|
"订单流转路径",
|
||||||
|
"快递公司",
|
||||||
|
"往来单位"
|
||||||
|
],
|
||||||
|
"常见案例": [
|
||||||
|
"自定义组件",
|
||||||
|
"对象存储"
|
||||||
|
],
|
||||||
|
"在线开发": [
|
||||||
|
"Online表单开发"
|
||||||
|
],
|
||||||
|
"报表设计": [
|
||||||
|
"积木报表设计",
|
||||||
|
"生产销售监控",
|
||||||
|
"智慧物流监控"
|
||||||
|
],
|
||||||
|
"消息中心": [
|
||||||
|
"模板管理",
|
||||||
|
"消息管理",
|
||||||
|
"我的消息"
|
||||||
|
],
|
||||||
|
"系统管理": [
|
||||||
|
"用户管理",
|
||||||
|
"角色管理",
|
||||||
|
"菜单管理",
|
||||||
|
"租户管理",
|
||||||
|
"部门管理",
|
||||||
|
"我的部门",
|
||||||
|
"职务管理",
|
||||||
|
"通讯录",
|
||||||
|
"数据字典",
|
||||||
|
"分类字典",
|
||||||
|
"系统通告",
|
||||||
|
"菜单管理2"
|
||||||
|
],
|
||||||
|
"系统监控": [
|
||||||
|
"在线用户",
|
||||||
|
"路由网关",
|
||||||
|
"定时任务",
|
||||||
|
"日志管理",
|
||||||
|
"数据日志",
|
||||||
|
"SQL监控",
|
||||||
|
"在线文档"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"pages": {
|
||||||
|
"首页": {
|
||||||
|
"url": "http://39.101.149.173/wms/Dashboard",
|
||||||
|
"title": "柏悦物流管理系统",
|
||||||
|
"table_headers": [],
|
||||||
|
"search_fields": [],
|
||||||
|
"buttons": [
|
||||||
|
"返回首页"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"入库 > 入库单列表": {
|
||||||
|
"url": "http://39.101.149.173/wms/ByInstoreList",
|
||||||
|
"title": "入库单列表 · 柏悦物流管理系统",
|
||||||
|
"table_headers": [
|
||||||
|
"仓库",
|
||||||
|
"交货仓",
|
||||||
|
"配载状态",
|
||||||
|
"是否扣货",
|
||||||
|
"扣货理由",
|
||||||
|
"集装箱号",
|
||||||
|
"柜号",
|
||||||
|
"公司",
|
||||||
|
"业务类型",
|
||||||
|
"提货方式",
|
||||||
|
"提货时间",
|
||||||
|
"提货联系人电话",
|
||||||
|
"提货地址",
|
||||||
|
"提货邮编",
|
||||||
|
"提货联系人邮箱",
|
||||||
|
"渠道",
|
||||||
|
"买单/退税",
|
||||||
|
"是否整柜",
|
||||||
|
"商检验",
|
||||||
|
"开船时间",
|
||||||
|
"到港时间",
|
||||||
|
"总箱数",
|
||||||
|
"总毛重(T.K.GW)"
|
||||||
|
],
|
||||||
|
"search_fields": [
|
||||||
|
"定位仓库",
|
||||||
|
"交货仓",
|
||||||
|
"入仓码",
|
||||||
|
"订单状态",
|
||||||
|
"费用审核状态"
|
||||||
|
],
|
||||||
|
"buttons": [
|
||||||
|
"查询",
|
||||||
|
"重置",
|
||||||
|
"国内仓下单",
|
||||||
|
"海外分仓下单",
|
||||||
|
"整托下单",
|
||||||
|
"高级查询",
|
||||||
|
"导出报表",
|
||||||
|
"导出入库清单总表",
|
||||||
|
"导出唛头",
|
||||||
|
"导出FBA流转单ZIP",
|
||||||
|
"下载"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"入库 > 入库单测量": {
|
||||||
|
"url": "http://39.101.149.173/wms/ByInstoreList4Measured",
|
||||||
|
"title": "入库单测量 · 柏悦物流管理系统",
|
||||||
|
"table_headers": [
|
||||||
|
"入仓码",
|
||||||
|
"仓库",
|
||||||
|
"订单状态",
|
||||||
|
"配载状态",
|
||||||
|
"测量数据审核状态",
|
||||||
|
"唛头文件",
|
||||||
|
"是否扣货",
|
||||||
|
"扣货理由",
|
||||||
|
"公司",
|
||||||
|
"业务类型",
|
||||||
|
"渠道",
|
||||||
|
"买单/退税",
|
||||||
|
"是否整柜",
|
||||||
|
"商检验",
|
||||||
|
"总箱数",
|
||||||
|
"总毛重(T.K.GW)",
|
||||||
|
"总体积(m³)",
|
||||||
|
"总材积重",
|
||||||
|
"总净重(T.K.NW)",
|
||||||
|
"目的仓类型",
|
||||||
|
"目的仓",
|
||||||
|
"货件编号",
|
||||||
|
"测量完成时间",
|
||||||
|
"操作"
|
||||||
|
],
|
||||||
|
"search_fields": [
|
||||||
|
"仓库",
|
||||||
|
"入仓码",
|
||||||
|
"公司",
|
||||||
|
"FBA货件编号"
|
||||||
|
],
|
||||||
|
"buttons": [
|
||||||
|
"查询",
|
||||||
|
"重置",
|
||||||
|
"下载"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"入库 > 测量数据审核": {
|
||||||
|
"url": "http://39.101.149.173/wms/ByInstoreList4MeasuredAudit",
|
||||||
|
"title": "测量数据审核 · 柏悦物流管理系统",
|
||||||
|
"table_headers": [
|
||||||
|
"入仓码",
|
||||||
|
"仓库",
|
||||||
|
"订单状态",
|
||||||
|
"配载状态",
|
||||||
|
"测量数据审核状态",
|
||||||
|
"唛头文件",
|
||||||
|
"是否扣货",
|
||||||
|
"扣货理由",
|
||||||
|
"公司",
|
||||||
|
"业务类型",
|
||||||
|
"渠道",
|
||||||
|
"买单/退税",
|
||||||
|
"是否整柜",
|
||||||
|
"商检验",
|
||||||
|
"总箱数",
|
||||||
|
"总毛重(T.K.GW)",
|
||||||
|
"总体积(m³)",
|
||||||
|
"总材积重",
|
||||||
|
"总净重(T.K.NW)",
|
||||||
|
"目的仓类型",
|
||||||
|
"目的仓",
|
||||||
|
"货件编号",
|
||||||
|
"测量完成时间",
|
||||||
|
"操作"
|
||||||
|
],
|
||||||
|
"search_fields": [
|
||||||
|
"仓库",
|
||||||
|
"入仓码",
|
||||||
|
"公司",
|
||||||
|
"FBA货件编号"
|
||||||
|
],
|
||||||
|
"buttons": [
|
||||||
|
"查询",
|
||||||
|
"重置",
|
||||||
|
"下载"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"入库 > 接收审核": {
|
||||||
|
"url": "http://39.101.149.173/wms/ByInstoreList4ReceiveAudit",
|
||||||
|
"title": "接收审核 · 柏悦物流管理系统",
|
||||||
|
"table_headers": [
|
||||||
|
"入仓码",
|
||||||
|
"仓库",
|
||||||
|
"订单状态",
|
||||||
|
"配载状态",
|
||||||
|
"测量数据审核状态",
|
||||||
|
"唛头文件",
|
||||||
|
"是否扣货",
|
||||||
|
"扣货理由",
|
||||||
|
"公司",
|
||||||
|
"业务类型",
|
||||||
|
"渠道",
|
||||||
|
"买单/退税",
|
||||||
|
"是否整柜",
|
||||||
|
"商检验",
|
||||||
|
"总箱数",
|
||||||
|
"总毛重(T.K.GW)",
|
||||||
|
"总体积(m³)",
|
||||||
|
"总材积重",
|
||||||
|
"总净重(T.K.NW)",
|
||||||
|
"目的仓类型",
|
||||||
|
"目的仓",
|
||||||
|
"货件编号",
|
||||||
|
"测量完成时间",
|
||||||
|
"操作"
|
||||||
|
],
|
||||||
|
"search_fields": [
|
||||||
|
"仓库",
|
||||||
|
"入仓码",
|
||||||
|
"公司",
|
||||||
|
"FBA货件编号"
|
||||||
|
],
|
||||||
|
"buttons": [
|
||||||
|
"查询",
|
||||||
|
"重置",
|
||||||
|
"下载"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"出库 > 派送单列表": {
|
||||||
|
"url": "http://39.101.149.173/wms/ByDispatchList",
|
||||||
|
"title": "柏悦物流管理系统",
|
||||||
|
"table_headers": [],
|
||||||
|
"search_fields": [],
|
||||||
|
"buttons": [
|
||||||
|
"返回首页"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"通用 > 托盘管理": {
|
||||||
|
"url": "http://39.101.149.173/wms/ByTrayList",
|
||||||
|
"title": "柏悦物流管理系统",
|
||||||
|
"table_headers": [],
|
||||||
|
"search_fields": [],
|
||||||
|
"buttons": [
|
||||||
|
"返回首页"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"系统管理 > 用户管理": {
|
||||||
|
"url": "http://39.101.149.173/system/UserList",
|
||||||
|
"title": "柏悦物流管理系统",
|
||||||
|
"table_headers": [],
|
||||||
|
"search_fields": [],
|
||||||
|
"buttons": [
|
||||||
|
"返回首页"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"系统管理 > 角色管理": {
|
||||||
|
"url": "http://39.101.149.173/system/RoleList",
|
||||||
|
"title": "柏悦物流管理系统",
|
||||||
|
"table_headers": [],
|
||||||
|
"search_fields": [],
|
||||||
|
"buttons": [
|
||||||
|
"返回首页"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"系统管理 > 菜单管理": {
|
||||||
|
"url": "http://39.101.149.173/system/MenuList",
|
||||||
|
"title": "柏悦物流管理系统",
|
||||||
|
"table_headers": [],
|
||||||
|
"search_fields": [],
|
||||||
|
"buttons": [
|
||||||
|
"返回首页"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pages_count": 10
|
||||||
|
}
|
||||||
@@ -0,0 +1,393 @@
|
|||||||
|
{
|
||||||
|
"menu_items": [
|
||||||
|
{
|
||||||
|
"text": "首页",
|
||||||
|
"selector": ".ant-menu-item",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "入库单列表",
|
||||||
|
"selector": ".ant-menu-item",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "入库单测量",
|
||||||
|
"selector": ".ant-menu-item",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "测量数据审核",
|
||||||
|
"selector": ".ant-menu-item",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "接收审核",
|
||||||
|
"selector": ".ant-menu-item",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "刷 新",
|
||||||
|
"selector": ".ant-menu-item",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "关闭左侧",
|
||||||
|
"selector": ".ant-menu-item",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "关闭右侧",
|
||||||
|
"selector": ".ant-menu-item",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "关闭其它",
|
||||||
|
"selector": ".ant-menu-item",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "客户管理",
|
||||||
|
"selector": ".ant-menu-submenu-title",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "入库",
|
||||||
|
"selector": ".ant-menu-submenu-title",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "出库",
|
||||||
|
"selector": ".ant-menu-submenu-title",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "货柜管理",
|
||||||
|
"selector": ".ant-menu-submenu-title",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "库存",
|
||||||
|
"selector": ".ant-menu-submenu-title",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "财务结算",
|
||||||
|
"selector": ".ant-menu-submenu-title",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "托盘管理",
|
||||||
|
"selector": ".ant-menu-submenu-title",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "通用",
|
||||||
|
"selector": ".ant-menu-submenu-title",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "常见案例",
|
||||||
|
"selector": ".ant-menu-submenu-title",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "在线开发",
|
||||||
|
"selector": ".ant-menu-submenu-title",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "报表设计",
|
||||||
|
"selector": ".ant-menu-submenu-title",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "消息中心",
|
||||||
|
"selector": ".ant-menu-submenu-title",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "系统管理",
|
||||||
|
"selector": ".ant-menu-submenu-title",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "系统监控",
|
||||||
|
"selector": ".ant-menu-submenu-title",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "统计报表",
|
||||||
|
"selector": ".ant-menu-submenu-title",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "入库 入库单列表 入库单测量 测量数据审核 接收审核",
|
||||||
|
"selector": "li[role='menuitem']",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "定位仓库 请选择仓库",
|
||||||
|
"selector": "[class*='menu'] [class*='item']",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "定位仓库",
|
||||||
|
"selector": "[class*='menu'] [class*='item']",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "请选择仓库",
|
||||||
|
"selector": "[class*='menu'] [class*='item']",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "交货仓 请选择交货仓",
|
||||||
|
"selector": "[class*='menu'] [class*='item']",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "交货仓",
|
||||||
|
"selector": "[class*='menu'] [class*='item']",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "请选择交货仓",
|
||||||
|
"selector": "[class*='menu'] [class*='item']",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "入仓码",
|
||||||
|
"selector": "[class*='menu'] [class*='item']",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "订单状态 请选择订单状态",
|
||||||
|
"selector": "[class*='menu'] [class*='item']",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "订单状态",
|
||||||
|
"selector": "[class*='menu'] [class*='item']",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "请选择订单状态",
|
||||||
|
"selector": "[class*='menu'] [class*='item']",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "费用审核状态 请选择费用审核状态",
|
||||||
|
"selector": "[class*='menu'] [class*='item']",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "费用审核状态",
|
||||||
|
"selector": "[class*='menu'] [class*='item']",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "请选择费用审核状态",
|
||||||
|
"selector": "[class*='menu'] [class*='item']",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "1",
|
||||||
|
"selector": "[class*='menu'] [class*='item']",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "2",
|
||||||
|
"selector": "[class*='menu'] [class*='item']",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "3",
|
||||||
|
"selector": "[class*='menu'] [class*='item']",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "4",
|
||||||
|
"selector": "[class*='menu'] [class*='item']",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "5",
|
||||||
|
"selector": "[class*='menu'] [class*='item']",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "•••",
|
||||||
|
"selector": "[class*='menu'] [class*='item']",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "36",
|
||||||
|
"selector": "[class*='menu'] [class*='item']",
|
||||||
|
"href": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"all_links": [
|
||||||
|
"/system/ConfigList",
|
||||||
|
"/system/DictList",
|
||||||
|
"/system/MenuList",
|
||||||
|
"/system/RoleList",
|
||||||
|
"/system/UserList",
|
||||||
|
"/wms/ByBolList",
|
||||||
|
"/wms/ByContainerList",
|
||||||
|
"/wms/ByCustomerList",
|
||||||
|
"/wms/ByDispatchList",
|
||||||
|
"/wms/ByFinanceList",
|
||||||
|
"/wms/ByInstoreList",
|
||||||
|
"/wms/ByInstoreList4Measured",
|
||||||
|
"/wms/ByInstoreList4MeasuredAudit",
|
||||||
|
"/wms/ByInstoreList4ReceiveAudit",
|
||||||
|
"/wms/ByInventoryList",
|
||||||
|
"/wms/ByOutstoreList",
|
||||||
|
"/wms/ByTrayList",
|
||||||
|
"/wms/Dashboard",
|
||||||
|
"/wms/home",
|
||||||
|
"/wms/index"
|
||||||
|
],
|
||||||
|
"api_calls": [
|
||||||
|
{
|
||||||
|
"url": "http://39.101.149.173/user/login?redirect=%2Fwms%2FByInstoreList",
|
||||||
|
"status": 200,
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/randomImage/1780285671792?_t=1780285671",
|
||||||
|
"status": 200,
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/randomImage/1780285691766?_t=1780285691",
|
||||||
|
"status": 200,
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/randomImage/1780285694400?_t=1780285694",
|
||||||
|
"status": 200,
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/login",
|
||||||
|
"status": 200,
|
||||||
|
"method": "POST"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/randomImage/1780285703728?_t=1780285703",
|
||||||
|
"status": 200,
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/login",
|
||||||
|
"status": 200,
|
||||||
|
"method": "POST"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/randomImage/1780285711155?_t=1780285711",
|
||||||
|
"status": 200,
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/login",
|
||||||
|
"status": 200,
|
||||||
|
"method": "POST"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "http://39.101.149.173/user/login?redirect=%2Fwms%2FByInstoreList",
|
||||||
|
"status": 200,
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/randomImage/1780285725968?_t=1780285725",
|
||||||
|
"status": 200,
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/randomImage/1780285750913?_t=1780285750",
|
||||||
|
"status": 200,
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/login",
|
||||||
|
"status": 200,
|
||||||
|
"method": "POST"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/permission/getUserPermissionByToken?_t=1780285758",
|
||||||
|
"status": 200,
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/dict/getDictItems/by_company,company_name,id",
|
||||||
|
"status": 200,
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/dict/getDictItems/by_order_status,name,value,value%20not%20in%20(1001%5E%5E1002)",
|
||||||
|
"status": 200,
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/dict/getDictItems/by_customer,realname,id",
|
||||||
|
"status": 200,
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/dict/getDictItems/by_store,store_name,store_no",
|
||||||
|
"status": 200,
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/dict/getDictItems/by_order_status,name,value",
|
||||||
|
"status": 200,
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/dict/getDictItems/by_store,store_name,store_no,parent_store_id!=''",
|
||||||
|
"status": 200,
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/dict/getDictItems/by_order_path,path_name,id",
|
||||||
|
"status": 200,
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/dict/getDictItems/by_fba,fba_no,fba_no",
|
||||||
|
"status": 200,
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/annountCement/listByUser?_t=1780285758",
|
||||||
|
"status": 200,
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/permission/getUserPermissionByToken?_t=1780285762",
|
||||||
|
"status": 200,
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/loginfo?_t=1780285763",
|
||||||
|
"status": 200,
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/visitInfo?_t=1780285763",
|
||||||
|
"status": 200,
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/annountCement/listByUser?_t=1780285763",
|
||||||
|
"status": 200,
|
||||||
|
"method": "GET"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://adtest.bylogistic.cn/sys/permission/getUserPermissionByToken?_t=1780285764",
|
||||||
|
"status": 200,
|
||||||
|
"method": "GET"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
{
|
||||||
|
"/system/ConfigList": {
|
||||||
|
"title": "柏悦物流管理系统",
|
||||||
|
"url": "http://39.101.149.173/dashboard/analysis",
|
||||||
|
"headers": [],
|
||||||
|
"buttons": [],
|
||||||
|
"form_fields": [],
|
||||||
|
"content_preview": "欢迎进入 柏悦物流管理系统\n欢迎您,管理员 退出登录\n首页\nCopyright 2022 BaiYue Logisitcs"
|
||||||
|
},
|
||||||
|
"/system/DictList": {
|
||||||
|
"error": "Page.wait_for_timeout: Target page, context or browser has been closed"
|
||||||
|
},
|
||||||
|
"/system/MenuList": {
|
||||||
|
"error": "Page.goto: Target page, context or browser has been closed"
|
||||||
|
},
|
||||||
|
"/system/RoleList": {
|
||||||
|
"error": "Page.goto: Target page, context or browser has been closed"
|
||||||
|
},
|
||||||
|
"/system/UserList": {
|
||||||
|
"error": "Page.goto: Target page, context or browser has been closed"
|
||||||
|
},
|
||||||
|
"/wms/ByBolList": {
|
||||||
|
"error": "Page.goto: Target page, context or browser has been closed"
|
||||||
|
},
|
||||||
|
"/wms/ByContainerList": {
|
||||||
|
"error": "Page.goto: Target page, context or browser has been closed"
|
||||||
|
},
|
||||||
|
"/wms/ByCustomerList": {
|
||||||
|
"error": "Page.goto: Target page, context or browser has been closed"
|
||||||
|
},
|
||||||
|
"/wms/ByDispatchList": {
|
||||||
|
"error": "Page.goto: Target page, context or browser has been closed"
|
||||||
|
},
|
||||||
|
"/wms/ByFinanceList": {
|
||||||
|
"error": "Page.goto: Target page, context or browser has been closed"
|
||||||
|
},
|
||||||
|
"/wms/ByInstoreList": {
|
||||||
|
"error": "Page.goto: Target page, context or browser has been closed"
|
||||||
|
},
|
||||||
|
"/wms/ByInstoreList4Measured": {
|
||||||
|
"error": "Page.goto: Target page, context or browser has been closed"
|
||||||
|
},
|
||||||
|
"/wms/ByInstoreList4MeasuredAudit": {
|
||||||
|
"error": "Page.goto: Target page, context or browser has been closed"
|
||||||
|
},
|
||||||
|
"/wms/ByInstoreList4ReceiveAudit": {
|
||||||
|
"error": "Page.goto: Target page, context or browser has been closed"
|
||||||
|
},
|
||||||
|
"/wms/ByInventoryList": {
|
||||||
|
"error": "Page.goto: Target page, context or browser has been closed"
|
||||||
|
},
|
||||||
|
"/wms/ByOutstoreList": {
|
||||||
|
"error": "Page.goto: Target page, context or browser has been closed"
|
||||||
|
},
|
||||||
|
"/wms/ByTrayList": {
|
||||||
|
"error": "Page.goto: Target page, context or browser has been closed"
|
||||||
|
},
|
||||||
|
"/wms/Dashboard": {
|
||||||
|
"error": "Page.goto: Target page, context or browser has been closed"
|
||||||
|
},
|
||||||
|
"/wms/home": {
|
||||||
|
"error": "Page.goto: Target page, context or browser has been closed"
|
||||||
|
},
|
||||||
|
"/wms/index": {
|
||||||
|
"error": "Page.goto: Target page, context or browser has been closed"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,510 @@
|
|||||||
|
# 柏悦物流管理系统(Baiyue WMS)系统文档
|
||||||
|
|
||||||
|
> **版本**: 基于测试系统 2026-06-01 抓取分析
|
||||||
|
> **访问地址**: http://39.101.149.173
|
||||||
|
> **后端API**: https://adtest.bylogistic.cn
|
||||||
|
> **技术栈**: Ant Design Vue + Spring Boot + MySQL + Redis
|
||||||
|
> **测试账号**: admin / ndui#Emdfj23123
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 目录
|
||||||
|
|
||||||
|
1. [系统概述](#1-系统概述)
|
||||||
|
2. [技术架构](#2-技术架构)
|
||||||
|
3. [首页仪表盘](#3-首页仪表盘)
|
||||||
|
4. [客户管理模块](#4-客户管理模块)
|
||||||
|
5. [入库管理模块](#5-入库管理模块)
|
||||||
|
6. [出库管理模块](#6-出库管理模块)
|
||||||
|
7. [货柜管理模块](#7-货柜管理模块)
|
||||||
|
8. [库存管理模块](#8-库存管理模块)
|
||||||
|
9. [财务结算模块](#9-财务结算模块)
|
||||||
|
10. [托盘管理模块](#10-托盘管理模块)
|
||||||
|
11. [通用配置模块](#11-通用配置模块)
|
||||||
|
12. [常见案例模块](#12-常见案例模块)
|
||||||
|
13. [在线开发模块](#13-在线开发模块)
|
||||||
|
14. [报表设计模块](#14-报表设计模块)
|
||||||
|
15. [消息中心模块](#15-消息中心模块)
|
||||||
|
16. [系统管理模块](#16-系统管理模块)
|
||||||
|
17. [系统监控模块](#17-系统监控模块)
|
||||||
|
18. [API接口清单](#18-api接口清单)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 系统概述
|
||||||
|
|
||||||
|
柏悦物流管理系统(Baiyue WMS)是一套面向跨境物流仓储行业的综合管理系统,覆盖从**客户管理 → 入库 → 出库 → 货柜管理 → 库存 → 托盘 → 财务结算**的全链路业务流程。
|
||||||
|
|
||||||
|
### 1.1 核心业务流程
|
||||||
|
|
||||||
|
```
|
||||||
|
客户下单 → 入库单 → 入库测量 → 测量审核 → 接收审核 → 库存管理
|
||||||
|
↓
|
||||||
|
出库单 → BOL/派送 → 托盘管理 → 货柜管理 → 财务结算
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.2 系统模块总览
|
||||||
|
|
||||||
|
| 序号 | 模块 | 子页面数 | 说明 |
|
||||||
|
|------|------|----------|------|
|
||||||
|
| 1 | 首页 | 1 | 数据看板/仪表盘 |
|
||||||
|
| 2 | 客户管理 | 4 | 客户公司、用户、阶梯费用、流水 |
|
||||||
|
| 3 | 入库 | 4 | 入库单、测量、审核、接收 |
|
||||||
|
| 4 | 出库 | 3 | 派送单、BOL、自提单 |
|
||||||
|
| 5 | 货柜管理 | 2 | 货柜列表、装柜清单 |
|
||||||
|
| 6 | 库存 | 3 | 海外仓库存查询、理货、报损 |
|
||||||
|
| 7 | 财务结算 | 5 | 应收应付、对账单、仓储成本 |
|
||||||
|
| 8 | 托盘管理 | 2 | 托盘列表、生成托盘 |
|
||||||
|
| 9 | 通用 | 8 | 产品、费用、FBA地址、库位等 |
|
||||||
|
| 10 | 常见案例 | 2 | 自定义组件、对象存储 |
|
||||||
|
| 11 | 在线开发 | 1 | Online表单开发 |
|
||||||
|
| 12 | 报表设计 | 3 | 积木报表、生产监控、物流监控 |
|
||||||
|
| 13 | 消息中心 | 3 | 模板、消息管理、我的消息 |
|
||||||
|
| 14 | 系统管理 | 12 | 用户、角色、菜单、租户等 |
|
||||||
|
| 15 | 系统监控 | 7 | 在线用户、日志、定时任务等 |
|
||||||
|
| 16 | 统计报表 | - | 报表设计入口 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 技术架构
|
||||||
|
|
||||||
|
### 2.1 前端技术
|
||||||
|
|
||||||
|
- **框架**: Vue.js(SPA 单页应用)
|
||||||
|
- **UI 组件库**: Ant Design Vue
|
||||||
|
- **路由**: Vue Router(Hash 模式)
|
||||||
|
- **状态管理**: Vuex
|
||||||
|
- **图表**: 集成数据可视化组件
|
||||||
|
|
||||||
|
### 2.2 后端技术
|
||||||
|
|
||||||
|
- **框架**: Spring Boot(推测,基于 Spring 生态)
|
||||||
|
- **数据库**: MySQL
|
||||||
|
- **缓存**: Redis
|
||||||
|
- **认证**: Token-based(JWT)
|
||||||
|
- **API 风格**: RESTful
|
||||||
|
|
||||||
|
### 2.3 认证流程
|
||||||
|
|
||||||
|
```
|
||||||
|
用户登录 → POST /sys/login → 返回 Token
|
||||||
|
后续请求 → Header: Authorization: Bearer {token}
|
||||||
|
权限验证 → GET /sys/permission/getUserPermissionByToken
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 首页仪表盘
|
||||||
|
|
||||||
|
- **URL**: `/wms/Dashboard`
|
||||||
|
- **页面标题**: 柏悦物流管理系统
|
||||||
|
|
||||||
|
首页提供系统总览数据看板,展示关键业务指标(订单数、库存状态、财务概况等)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 客户管理模块
|
||||||
|
|
||||||
|
### 4.1 客户公司管理
|
||||||
|
|
||||||
|
管理客户公司的基本信息,包括公司名称、联系方式、合作状态等。
|
||||||
|
|
||||||
|
### 4.2 用户资料
|
||||||
|
|
||||||
|
管理客户下的用户账号资料,包括登录账号、角色权限等。
|
||||||
|
|
||||||
|
### 4.3 海外仓阶梯费用
|
||||||
|
|
||||||
|
配置客户在海外仓的阶梯式费用规则,按不同量级设置不同单价。
|
||||||
|
|
||||||
|
### 4.4 客户账户流水
|
||||||
|
|
||||||
|
查看客户账户的资金流水明细,包括充值、消费、退款等记录。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 入库管理模块
|
||||||
|
|
||||||
|
入库是系统的核心业务流程模块,包含四个阶段:入库单创建 → 测量 → 测量审核 → 接收审核。
|
||||||
|
|
||||||
|
### 5.1 入库单列表
|
||||||
|
|
||||||
|
- **URL**: `/wms/ByInstoreList`
|
||||||
|
- **页面标题**: 入库单列表 · 柏悦物流管理系统
|
||||||
|
|
||||||
|
#### 搜索条件
|
||||||
|
|
||||||
|
| 字段 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| 定位仓库 | 筛选指定仓库的入库单 |
|
||||||
|
| 交货仓 | 筛选指定交货仓的入库单 |
|
||||||
|
| 入仓码 | 按入仓码精确查询 |
|
||||||
|
| 订单状态 | 按订单状态筛选(如:待处理、处理中、已完成) |
|
||||||
|
| 费用审核状态 | 按费用审核状态筛选 |
|
||||||
|
|
||||||
|
#### 表格列头(23列)
|
||||||
|
|
||||||
|
| 列名 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| 仓库 | 入库目标仓库 |
|
||||||
|
| 交货仓 | 货物来源交货仓 |
|
||||||
|
| 配载状态 | 货物配载状态 |
|
||||||
|
| 是否扣货 | 是否被扣货标记 |
|
||||||
|
| 扣货理由 | 扣货原因说明 |
|
||||||
|
| 集装箱号 | 集装箱编号 |
|
||||||
|
| 柜号 | 货柜编号 |
|
||||||
|
| 公司 | 客户公司名称 |
|
||||||
|
| 业务类型 | 业务分类 |
|
||||||
|
| 提货方式 | 提货方式(自提/送货等) |
|
||||||
|
| 提货时间 | 预约提货时间 |
|
||||||
|
| 提货联系人电话 | 提货联系人电话 |
|
||||||
|
| 提货地址 | 提货地址详情 |
|
||||||
|
| 提货邮编 | 提货地邮编 |
|
||||||
|
| 提货联系人邮箱 | 提货联系人邮箱 |
|
||||||
|
| 渠道 | 业务渠道来源 |
|
||||||
|
| 买单/退税 | 贸易方式(买单/退税) |
|
||||||
|
| 是否整柜 | 整柜/拼柜标记 |
|
||||||
|
| 商检验 | 商检检验标记 |
|
||||||
|
| 开船时间 | 预计开船时间 |
|
||||||
|
| 到港时间 | 预计到港时间 |
|
||||||
|
| 总箱数 | 货物总箱数 |
|
||||||
|
| 总毛重(T.K.GW) | 总毛重(吨/公斤) |
|
||||||
|
|
||||||
|
#### 操作按钮
|
||||||
|
|
||||||
|
| 按钮 | 功能 |
|
||||||
|
|------|------|
|
||||||
|
| 查询 | 根据搜索条件查询数据 |
|
||||||
|
| 重置 | 清空搜索条件 |
|
||||||
|
| 国内仓下单 | 创建国内仓入库单 |
|
||||||
|
| 海外分仓下单 | 创建海外分仓入库单 |
|
||||||
|
| 整托下单 | 以整托方式创建入库单 |
|
||||||
|
| 高级查询 | 打开高级筛选面板 |
|
||||||
|
| 导出报表 | 导出当前查询结果为Excel |
|
||||||
|
| 导出入库清单总表 | 导出完整的入库清单 |
|
||||||
|
| 导出唛头 | 导出唛头标签文件 |
|
||||||
|
| 导出FBA流转单ZIP | 导出FBA流转单压缩包 |
|
||||||
|
| 下载 | 下载选中记录的相关文件 |
|
||||||
|
|
||||||
|
### 5.2 入库单测量
|
||||||
|
|
||||||
|
- **URL**: `/wms/ByInstoreList4Measured`
|
||||||
|
- **页面标题**: 入库单测量 · 柏悦物流管理系统
|
||||||
|
|
||||||
|
对入库货物进行实际测量,记录测量数据。
|
||||||
|
|
||||||
|
#### 搜索条件
|
||||||
|
|
||||||
|
| 字段 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| 仓库 | 筛选仓库 |
|
||||||
|
| 入仓码 | 按入仓码查询 |
|
||||||
|
| 公司 | 按客户公司筛选 |
|
||||||
|
| FBA货件编号 | 按FBA货件编号查询 |
|
||||||
|
|
||||||
|
#### 表格列头(24列)
|
||||||
|
|
||||||
|
| 列名 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| 入仓码 | 入仓编码 |
|
||||||
|
| 仓库 | 目标仓库 |
|
||||||
|
| 订单状态 | 订单处理状态 |
|
||||||
|
| 配载状态 | 配载情况 |
|
||||||
|
| 测量数据审核状态 | 测量审核进度 |
|
||||||
|
| 唛头文件 | 唛头标签文件 |
|
||||||
|
| 是否扣货 | 扣货标记 |
|
||||||
|
| 扣货理由 | 扣货原因 |
|
||||||
|
| 公司 | 客户公司 |
|
||||||
|
| 业务类型 | 业务分类 |
|
||||||
|
| 渠道 | 业务渠道 |
|
||||||
|
| 买单/退税 | 贸易方式 |
|
||||||
|
| 是否整柜 | 整柜/拼柜 |
|
||||||
|
| 商检验 | 商检状态 |
|
||||||
|
| 总箱数 | 货物总箱数 |
|
||||||
|
| 总毛重(T.K.GW) | 总毛重 |
|
||||||
|
| 总体积(m³) | 货物总体积 |
|
||||||
|
| 总材积重 | 材积重量 |
|
||||||
|
| 总净重(T.K.NW) | 总净重 |
|
||||||
|
| 目的仓类型 | 目的仓库类型 |
|
||||||
|
| 目的仓 | 目的仓库 |
|
||||||
|
| 货件编号 | 货件编号 |
|
||||||
|
| 测量完成时间 | 测量完成时间 |
|
||||||
|
| 操作 | 操作按钮列 |
|
||||||
|
|
||||||
|
#### 操作按钮
|
||||||
|
|
||||||
|
| 按钮 | 功能 |
|
||||||
|
|------|------|
|
||||||
|
| 查询 | 根据条件查询 |
|
||||||
|
| 重置 | 清空条件 |
|
||||||
|
| 下载 | 下载数据 |
|
||||||
|
|
||||||
|
### 5.3 测量数据审核
|
||||||
|
|
||||||
|
- **URL**: `/wms/ByInstoreList4MeasuredAudit`
|
||||||
|
- **页面标题**: 测量数据审核 · 柏悦物流管理系统
|
||||||
|
|
||||||
|
对测量数据进行审核确认。表头和搜索条件与入库单测量一致。
|
||||||
|
|
||||||
|
### 5.4 接收审核
|
||||||
|
|
||||||
|
- **URL**: `/wms/ByInstoreList4ReceiveAudit`
|
||||||
|
- **页面标题**: 接收审核 · 柏悦物流管理系统
|
||||||
|
|
||||||
|
最终接收审核环节,确认货物入库完成。表头和搜索条件与入库单测量一致。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 出库管理模块
|
||||||
|
|
||||||
|
### 6.1 派送单列表
|
||||||
|
|
||||||
|
- **URL**: `/wms/ByDispatchList`
|
||||||
|
|
||||||
|
管理出库派送订单,包括派送地址、物流方式、派送状态等。
|
||||||
|
|
||||||
|
### 6.2 BOL(提单管理)
|
||||||
|
|
||||||
|
- **URL**: `/wms/ByBolList`
|
||||||
|
|
||||||
|
管理 Bill of Lading(提单),是国际物流中的重要单证。包括提单号、船名航次、发货人、收货人等。
|
||||||
|
|
||||||
|
### 6.3 自提单
|
||||||
|
|
||||||
|
管理客户自提订单,记录自提预约、提货人信息等。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. 货柜管理模块
|
||||||
|
|
||||||
|
### 7.1 货柜列表
|
||||||
|
|
||||||
|
- **URL**: `/wms/ByContainerList`
|
||||||
|
|
||||||
|
管理所有货柜信息,包括柜号、类型、尺寸、状态、当前位置等。
|
||||||
|
|
||||||
|
### 7.2 装柜清单
|
||||||
|
|
||||||
|
记录每个货柜的装柜明细,展示柜内货物列表和装载方案。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. 库存管理模块
|
||||||
|
|
||||||
|
### 8.1 海外仓库存查询
|
||||||
|
|
||||||
|
- **URL**: `/wms/ByInventoryList`
|
||||||
|
|
||||||
|
查询海外仓当前库存情况,支持按仓库、产品、SKU等维度查询。
|
||||||
|
|
||||||
|
### 8.2 理货管理
|
||||||
|
|
||||||
|
对库存货物进行盘点、整理、移位等操作。
|
||||||
|
|
||||||
|
### 8.3 报损单
|
||||||
|
|
||||||
|
管理货物损耗/损坏的报损申请和审批流程。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. 财务结算模块
|
||||||
|
|
||||||
|
### 9.1 客户应收应付
|
||||||
|
|
||||||
|
- **URL**: `/wms/ByFinanceList`
|
||||||
|
|
||||||
|
管理每个客户的应收账款和应付账款明细。
|
||||||
|
|
||||||
|
### 9.2 客户对账单
|
||||||
|
|
||||||
|
生成和查看客户对账单,用于与客户进行账务核对。
|
||||||
|
|
||||||
|
### 9.3 结算单位应付
|
||||||
|
|
||||||
|
按结算单位(如承运商、仓库方)管理应付账款。
|
||||||
|
|
||||||
|
### 9.4 结算单位对账单
|
||||||
|
|
||||||
|
生成结算单位的对账单。
|
||||||
|
|
||||||
|
### 9.5 洛杉矶仓储成本
|
||||||
|
|
||||||
|
专门针对洛杉矶仓库的仓储成本核算和分析。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. 托盘管理模块
|
||||||
|
|
||||||
|
### 10.1 托盘列表
|
||||||
|
|
||||||
|
- **URL**: `/wms/ByTrayList`
|
||||||
|
|
||||||
|
管理所有托盘信息,包括托盘编号、规格、状态、关联货物等。
|
||||||
|
|
||||||
|
### 10.2 生成托盘
|
||||||
|
|
||||||
|
根据入库货物自动/手动生成托盘,分配货物到托盘。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. 通用配置模块
|
||||||
|
|
||||||
|
系统基础数据和配置管理。
|
||||||
|
|
||||||
|
| 子模块 | 说明 |
|
||||||
|
|--------|------|
|
||||||
|
| 产品信息 | 管理产品/货品基础信息(名称、规格、HS编码等) |
|
||||||
|
| 费用项目 | 定义各类费用项目(仓储费、操作费、运输费等) |
|
||||||
|
| FBA编码地址 | 管理Amazon FBA仓库编码和地址信息 |
|
||||||
|
| 托盘管理 | 托盘基础配置 |
|
||||||
|
| 库位/货架管理 | 仓库库位和货架的编号和配置 |
|
||||||
|
| 订单流转路径 | 定义订单在不同节点之间的流转规则 |
|
||||||
|
| 快递公司 | 合作的快递/物流公司信息 |
|
||||||
|
| 往来单位 | 管理供应商、承运商等往来单位信息 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 12. 常见案例模块
|
||||||
|
|
||||||
|
### 12.1 自定义组件
|
||||||
|
|
||||||
|
展示系统自定义组件的使用示例和开发指南。
|
||||||
|
|
||||||
|
### 12.2 对象存储
|
||||||
|
|
||||||
|
文件/对象存储功能的配置和使用说明。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 13. 在线开发模块
|
||||||
|
|
||||||
|
### 13.1 Online表单开发
|
||||||
|
|
||||||
|
低代码表单开发工具,允许管理员在线设计和配置业务表单,无需编写代码。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 14. 报表设计模块
|
||||||
|
|
||||||
|
### 14.1 积木报表设计
|
||||||
|
|
||||||
|
可视化报表设计器,支持拖拽式设计各类业务报表。
|
||||||
|
|
||||||
|
### 14.2 生产销售监控
|
||||||
|
|
||||||
|
展示生产和销售的监控数据看板。
|
||||||
|
|
||||||
|
### 14.3 智慧物流监控
|
||||||
|
|
||||||
|
物流全链路监控大屏,展示实时物流数据。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 15. 消息中心模块
|
||||||
|
|
||||||
|
### 15.1 模板管理
|
||||||
|
|
||||||
|
管理系统通知的消息模板,支持短信、邮件、站内信等类型。
|
||||||
|
|
||||||
|
### 15.2 消息管理
|
||||||
|
|
||||||
|
查看和管理所有已发送的系统消息。
|
||||||
|
|
||||||
|
### 15.3 我的消息
|
||||||
|
|
||||||
|
当前登录用户收到的个人消息列表。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 16. 系统管理模块
|
||||||
|
|
||||||
|
系统后台管理功能。
|
||||||
|
|
||||||
|
| 子模块 | 说明 |
|
||||||
|
|--------|------|
|
||||||
|
| 用户管理 | 管理系统用户账号(创建、编辑、禁用、重置密码) |
|
||||||
|
| 角色管理 | 定义角色并分配权限 |
|
||||||
|
| 菜单管理 | 配置系统导航菜单结构 |
|
||||||
|
| 租户管理 | 多租户隔离管理(适用于SaaS模式) |
|
||||||
|
| 部门管理 | 组织架构部门管理 |
|
||||||
|
| 我的部门 | 当前用户所属部门信息 |
|
||||||
|
| 职务管理 | 定义系统内职务 |
|
||||||
|
| 通讯录 | 系统用户通讯录 |
|
||||||
|
| 数据字典 | 系统枚举值和字典数据维护 |
|
||||||
|
| 分类字典 | 分类树形字典维护 |
|
||||||
|
| 系统通告 | 发布系统级公告通知 |
|
||||||
|
| 菜单管理2 | 菜单管理的增强版/备用入口 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 17. 系统监控模块
|
||||||
|
|
||||||
|
系统运行状态监控和运维管理。
|
||||||
|
|
||||||
|
| 子模块 | 说明 |
|
||||||
|
|--------|------|
|
||||||
|
| 在线用户 | 查看当前在线用户列表,支持强制下线 |
|
||||||
|
| 路由网关 | 查看系统路由配置和网关状态 |
|
||||||
|
| 定时任务 | 管理系统的定时任务(Cron Job) |
|
||||||
|
| 日志管理 | 查看系统操作日志 |
|
||||||
|
| 数据日志 | 数据变更日志记录 |
|
||||||
|
| SQL监控 | SQL执行监控(基于Druid连接池) |
|
||||||
|
| 在线文档 | 系统API文档(Swagger/Knife4j) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 18. API接口清单
|
||||||
|
|
||||||
|
系统后端API部署在 `https://adtest.bylogistic.cn`,以下为已发现的API端点:
|
||||||
|
|
||||||
|
### 认证相关
|
||||||
|
|
||||||
|
| 接口 | 方法 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| `/sys/login` | POST | 用户登录 |
|
||||||
|
| `/sys/randomImage/{timestamp}` | GET | 获取验证码图片 |
|
||||||
|
| `/sys/permission/getUserPermissionByToken` | GET | 获取用户权限 |
|
||||||
|
|
||||||
|
### 数据字典
|
||||||
|
|
||||||
|
| 接口 | 方法 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| `/sys/dict/getDictItems/by_company` | GET | 获取公司字典 |
|
||||||
|
| `/sys/dict/getDictItems/by_order_status` | GET | 获取订单状态字典 |
|
||||||
|
| `/sys/dict/getDictItems/by_customer` | GET | 获取客户字典 |
|
||||||
|
| `/sys/dict/getDictItems/by_store` | GET | 获取仓库字典 |
|
||||||
|
| `/sys/dict/getDictItems/by_order_path` | GET | 获取订单路径字典 |
|
||||||
|
| `/sys/dict/getDictItems/by_fba` | GET | 获取FBA编码字典 |
|
||||||
|
|
||||||
|
### 系统功能
|
||||||
|
|
||||||
|
| 接口 | 方法 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| `/sys/annountCement/listByUser` | GET | 获取用户公告列表 |
|
||||||
|
| `/sys/loginfo` | GET | 系统日志信息 |
|
||||||
|
| `/sys/visitInfo` | GET | 访问统计信息 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 附录:SKU明细区域列头
|
||||||
|
|
||||||
|
在入库单详情页面,SKU明细表格包含以下列:
|
||||||
|
|
||||||
|
| 列名 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| 操作 | 编辑/删除操作 |
|
||||||
|
| # | 序号 |
|
||||||
|
| 报关HS_CODE | 报关用HS海关编码 |
|
||||||
|
| 货品图片 | 货品图片预览 |
|
||||||
|
| 仓/储/微(快递)码/纱 | 仓储编码/微信码/快递码 |
|
||||||
|
| 中品名 | 中文品名 |
|
||||||
|
| 英品名 | 英文品名 |
|
||||||
|
| 清关HS_CODE | 清关用HS海关编码 |
|
||||||
|
| 箱规长(cm) | 外箱长度 |
|
||||||
|
| 箱规宽(cm) | 外箱宽度 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> **文档生成时间**: 2026-06-01
|
||||||
|
> **数据来源**: 测试系统 http://39.101.149.173 实际登录抓取
|
||||||
|
> **说明**: 部分页面因SPA路由限制未能获取完整表头信息,已根据菜单结构推断标注。如需补充具体页面详情,请登录系统确认后更新。
|
||||||