Files
menchuang/doc/克隆实施方案.md
T
HHY b70a904255 feat: v2.0 DXF 截面学习+多腔体型材挤出落地
- 下载源站 49 个真实型材截面 DXF 用于学习(临时, 已按约定删除)
- 自研 DXF 解析器: 提取截面外轮廓/闭合腔体/实体统计
- 学习结论: 外框深46-62宽74-130(3-6腔), 玻璃扇深80-90宽65-72(4-10腔),
  中梃深79-84宽~100(3-7腔), 纱扇薄壁19-38, 转角立柱146x150(5腔)等
- 3D 型材升级: 多腔体截面挤出(外框3腔/扇2腔, 玻璃槽深20%, 壁厚比例修正)
- 学习结论沉淀至方案文档§3.3, DXF 素材已全部删除
2026-09-21 03:02:05 -07:00

17 KiB
Raw Blame History

门窗 Saunders 云平台(windoorcraft.com 同功能系统)克隆实施方案

版本:v0.1 | 日期:2026-09-20 | 编制:HHY 目标站:https://www.windoorcraft.com/home (代号 zzc,出品方 thinkerx.com) 本文档基于对目标站的只读接口采集(用户自有账户)与前端结构分析编写,所有代码实现均为自研原创。


1. 目标产品画像

windoorcraft.com 是一套面向门窗行业的 SaaS 工具集,核心价值链:

画窗(拖拽布置分格) → 自动算料报价 → 客户确认(合同/订单) → 生产(优化下料/打印) → 财务(收付款) → 库存

已探明的子系统:

子系统 说明 证据(路由/接口)
2D 画窗编辑器 拖拽布置外框、中梃、扇、玻璃、横竖撑,参数化尺寸 /draw、drawing_data、shapeManager
报价引擎 自动报价 + 手动报价,型材/玻璃/五金附件计价 /manual-quote、automatic_quote、base_price、offer-price
订单/合同 意向单→合同→订单流转,电子签名确认 /orders、contracts、convert-contract/、up-contract-confirmed/
客户管理 CRM 客户档案、业务员、客户分级 /customers_list、salesmen、ywy-*
生产管理 订单进度、车间派工、条码打印 get_order_process、printer、order_format
优化下料 一维型材优化切割(BIN 问题) optimize1d、cut_solution、contract_bars
库存/仓库 型材/玻璃/配件库存、出入库 warehouse_list、product_move_in/、materials_config
3D/渲染 BabylonJS 3D 展示、DXF 出图、AI 炫图 /threed、renderV2、sketch-to-window-info
样板库 254 套官方窗型模板(6 大分类) search_default_windoor、default_windoor_info/{id}
商城/会员 软件订阅购买、试用、邀请返利 /purchase、company-module-info、invited_user_list
多端生态 微信小程序/公众号/APP、Apple/Google 登录 wechat-login-with-phone、wx/getwxurllink、apple_login
多语言 中/英/韩/俄/越 5 语言包 lang-en-us 等独立 chunk
子账户/权限 主子账户、业务员/经销商角色 son_user_update、up_son_user_permission、dls-*

2. 已采集数据资产(本次交付)

全部存于 data/ 目录:

文件 内容 规模
api-endpoint-inventory.txt 从前端提取的全部接口名清单 ≈300 条
api-samples/*.json 16 个核心接口的真实响应样本 —
api-samples/windoor-templates-clean.json 样板库全量清单(含分类名映射) 254 条
windoor-drawings/{id}.json 每套模板的完整绘制数据 drawing_data 254 个文件 / 5.4MB
full-site/get/ + get-manifest.json 整站 GET 扫描:279 个接口逐一探测留档(200→90,业务成功 76) 全量
full-site/post/ + post-manifest.json POST 安全探测:24 个只读/计算语义接口(付费墙/参数契约确认) 全量
full-site/sweep_get.py / sweep_post.py 可复用的限速采集脚本(白名单制,危险接口永不触碰) —

订单模块受目标站付费墙保护(code=10086),列表/详情数据无法以试用水印账户获取;但订单写入接口的完整请求契约已通过源码静态分析拿到:创建订单 POST orders/{contract_id, drawing_data, pic_url}、详情 GET orders/{id}、排序 PUT orders/{id}、删除 DELETE orders/{id}。自研实现不依赖对方付费墙数据。

2.1 样板库统计

分类 数量
平开 99
转角窗 54
推拉 35
复古门 31
肯德基门 27
中式门窗 8
合计 254

说明:search_default_windoor 接口无分页(前端仅传 name 关键字参数),一次返回全量;经验证 page 参数被忽略、三页内容完全一致,故 254 条即官方样板库全量,本次已 100% 采集成功(254/254)。

2.2 drawing_data 数据模型(拖拽编辑器核心,已破解)

default_windoor_info/{id} 返回的 drawing_data 是编辑器画布的完整序列化状态,直接喂给 canvas.shapeManager.openFile()。结构:

drawing_data
├── s                 全局设置 { cs: 外框默认料宽60, cjs: 100 }
├── cp                预设参数
├── sm[]              形状集合(多形状 = 转角窗/连体窗)
│   └── 每个形状:
│       ├── cm   颜色映射 { g: 玻璃填充色, bn: 边框色, hd: 高光, ben: }
│       ├── dm   尺寸标注 { dims: [{at, ds, eidx, midx, name, type: line|mullion}] }
│       ├── fm   外框模型 { ew: [左,上,右,下]料宽, vs: 顶点, ejw, pew, ast }
│       ├── mm   中梃模型 { sp: [分割线 {line:{pt,norm}, alignType, equalSplit,
│       │                  kw(竖撑), ws(窗撑), reinforced, polyId}] }
│       ├── sashes[]      扇:开向 openToward、开启状态 opened、带转框 withTurningFrame
│       ├── bars / bds    格条(防盗格/装饰格)
│       ├── gg / gcs      玻璃配置
│       ├── ut / tcs      推拉窗轨道(emptyTrackAppended)
│       ├── rt / ep       圆弧半径(复古门弧顶)
│       └── polygon       多边形轮廓(非矩形窗)
├── epi / sbf / wlc   编辑器状态(点吸附/选中框/墙线)
├── wall              附墙信息
└── scale             缩放比例

关键结论:编辑器 = "多边形外框 + 中梃分割线树 + 区域→扇/玻璃分配" 的三层模型。分割线(sp)带单位向量 norm 与对齐策略,渲染时递归切割多边形得到玻璃区域。这就是拖拽布置搭建的实现基础。

3. 目标技术架构(自研实现)

3.1 技术选型

结合本仓库已有的 Python 骨架(pyproject.toml,Python ≥3.14):

层 选型 说明
后端 FastAPI + SQLAlchemy 2.0 + MySQL 8 异步、类型安全(符合类型安全原则)、自带 OpenAPI 文档
前端 Vue 3 + TypeScript + Element Plus + Pinia 与原站 Vue 系心智一致;画布层自研
画布引擎 原生 Canvas 2D + 自研 shapeManager(复刻数据模型 §2.2) 备选 Konva.js 减少底层工作量
3D Three.js + DXF 导出库 原站用 BabylonJS,功能等效替换
缓存/队列 Redis + Celery(优化下料、渲染走异步任务) optimize1d 计算密集
文件存储 阿里云 OSS / MinIO(自托管备选) 原站用阿里云 OSS + 华为云 OBS
认证 JWT (HS256, 24h) + 手机验证码 + 微信 OAuth 对齐原站鉴权方式

3.2 模块划分(严格分层)

src/huamenchuang/
├── main.py                 # FastAPI 入口、前端静态挂载
├── core/                   # 配置、安全(JWT)、依赖注入、统一响应封装
│   ├── config.py  security.py  response.py   # {code,message,data} envelope
├── models/                 # SQLAlchemy ORM(见 §4 领域模型)
├── schemas/                # Pydantic 请求/响应模型
├── repositories/           # 数据访问层
├── services/               # 业务逻辑层
│   ├── auth_service.py     customer_service.py  contract_service.py
│   ├── order_service.py    product_service.py   warehouse_service.py
│   ├── quote_service.py    optimize_service.py  template_service.py
├── api/                    # Controller 路由层(按模块拆分 router)
└── utils/                  # 一维优化算法、公式引擎、单位换算

frontend/
├── src/
│   ├── api/                # axios 封装 + 接口定义
│   ├── stores/             # Pinia
│   ├── views/              # 与原站 42 条路由对应的页面
│   └── components/canvas/  # shapeManager / Frame / Mullion / Sash / Glass / Dimension
└── dist -> 后端静态挂载    # 构建产物挂载(符合前后端规范)

3.3 源站 3D 建模技术探索结论(2026-09-21)

源站 3D 采用 BabylonJS + DXF 型材截面挤出:按产品系存放截面 CAD 文件(外框 frame / 玻璃扇 glassleaf / 中梃 mullion / 纱扇 screenleaf / 固定压线 / 折叠扇 / 转角立柱 / 导轨 / 装饰条 / 水槽等),运行时解析截面沿框架路径挤出成体(ExtrudeShape),sashOpen 参数驱动扇开合,配 _lod2 低模与轨道相机。

对 49 个真实截面 DXF 的解析归纳(事实尺寸,单位 mm):

型材 深度 面宽 腔体数
外框 frame 46-62 74-130 3-6
玻璃扇 glassleaf 80-90 65-72 4-10
固定玻璃压线 glass 22-27 89-130 1-3
中梃 mullion 79-84 ~100 3-7
纱扇 screenleaf 38-90 19-38 1-3
折叠扇 foldleaf 65 67 3
转角立柱 corner 146×150 — 5
装饰格条 decbar 15×15 — 实心

设计结论:真实铝型材为多腔体挤出(隔热腔+加强腔+排水腔,壁厚≈深度 1/30);已按此将自研 3D 型材升级为多腔体截面挤出(外框 3 腔/扇 2 腔/玻璃槽深≈20% 深度),并保留纱扇、压线、转角立柱等型材族的扩展位。

3.4 拖拽布置编辑器(核心难点)复刻方案 —— v2 已实现

原站设计思路(逆向自 drawing_data 序列化结构,经 254 套样本验证):

  1. 三层模型:Frame 形状 = 基底多边形(polygon.polygon) + 分割树(mm.sp[]) + 扇子形状(sm[])
  2. 分割树(关键发现):polygon.polygon 不是最终窗格,而是基底多边形;mm.sp[] 按序记录每次分割——line{pt,norm} 定位分割线、polyId{idx,pos} 指向作用区域与插入位。编辑器打开文件时重放分割树得到最终窗格。同一中梃可能被记录为多条共线分段(随区域生长拆分)
  3. 扇模型:子形状 Sash/DoubleSash,sashes[] 描述子扇(od 开向角、wtf 转框、openToward 内开/外开),经 polyId 挂到窗格;bd 边界在序列化中常退化,运行时重算
  4. 序列化即状态:drawing_data 直接喂给 shapeManager.openFile() 恢复整个画布

自研实现(frontend/src/components/WindoorCanvas.vue,约 700 行,Canvas2D):

能力 实现
真实网格渲染 replayShape() 分割树重放(两次交叉点法切多边形,退化/非凸跳过),254 套样板全部还原真实分格(平开 4-7 格、推拉亮子结构、转角窗多体)
中梃绘制 每条 sp 按其作用区域 bbox 裁剪为分段双线;共线分段自然重叠无害
扇样式推断 有效bd → polyId 映射区域(双扇对半) → 帧bbox按扇数竖向均分 三级解析;开向三角/内开空心/门标注
尺寸参数化 W/H 输入框 + 拖拽外框右缘/下缘/右下角手柄;全部几何(含 sp 点位)按比例缩放,料宽不变
加中梃 +竖梃/+横梃 → 点击玻璃区域 → 追加 sp(polyId.idx=被点窗格)→ 重放
改中梃 点击选中(蓝色高亮)→ 拖动(line.pt 更新→重放,30mm 边距钳制)→ Del/按钮删除(移除 sp→重放)
撤销/自动报价 JSON 快照栈;变化后 600ms 防抖调 offer-price 实时显示总价
服务端算料 Python 侧同语义 replay_shape:玻璃面积=重放窗格面积和,中梃长度=作用区域投影(精确到实际跨度)

数据兼容性:编辑仅增删改 sp 与几何点,不改变 drawing_data 的字段结构——保存后仍是标准 shapeManager 格式。

4. 领域模型(依据真实响应样本归纳)

实体 关键字段(来自采集样本)
users id, nickname, phone_number, wechat_id, union_id, apple_id, company_id, money, bounty, try_expiration_time, son_account_type, language, is_lose
companies id, name, 参数集(find/update_company_param_value)
customers id, name, phone, address, note, sort, type, salesmen, discount, balance, level, join_date
contracts id, contract_no(如 FG20260818009), customer_id, area, count, money, status(意向单…), cut_status, sign_status, sign_picture_url, contract_type, confirmed, discount, agency_money, oids[]
orders (POST 接口,结构待浏览器抓包补全) order_no, contract_id, products[], process
windoor_templates id, name, pic_url, catelog_id, note, times, low/high_width/height, drawing_data
default_windoor_catelogs 树:推拉门{平开,推拉,复古门,肯德基门,中式门窗,转角窗}
product_catelogs 树,is_reference, lang
warehouses(材料) bom_code, name, material(profile/glass/...), cost, price, color, pricing_method, length, count, warning, unit, meter_weight, thick, agency_price
receipt_accounts type, name, number, bank, pic_url, is_default, balance
announcements name, desc, pic_url, content(富文本)
company_modules name, type, icon, description, price, try_days, label, info
operation_logs / invited_users 分页日志/邀请返利

接口响应统一 envelope:{code: 1=成功, message, data, other_data, other_data2};分页为 Laravel 风格 current_page/data[]/total/per_page。自研系统沿用此规范以保持前端迁移成本最低。

5. 接口清单(详见 doc/API.md)

按模块归组(GET 已验证 ✅ / POST 待抓包 ⏳):

  • 认证:login wechat-login wechat-login-with-phone code-login register-and-login verification-code-new captcha forget-password
  • 用户:current-user✅ users✅ current-user/password current-user/phone son_user_update/ up_son_user_permission
  • 客户:customers_list✅ customers customer_record(s) customers_excel_in
  • 合同/订单:contracts✅ convert-contract/ orders/(POST)⏳ order-by-pid get_order_process up_order_no/ contract_receipt*
  • 样板库:search_default_windoor✅ default_windoor_catelog✅ default_windoor_info/{id}✅ default_windoor/ windoor/(用户自存窗型) windoor_template_sort
  • 产品:product-catelog✅ all-product✅ product/ search-product dls-price-config team-discount
  • 仓库:warehouse_list✅ warehouse_info receipt_accounts✅ product_move_in//out/ materials_config
  • 下料:optimize1d cut_solution(_new) contract_bars(_with_stock) up-cut-status
  • 渲染/3D:rendering-info three-d-data(POST)⏳ drawing_data_by_oid/ sketch-to-window-info
  • 财务:contract_receipt_list✅样 contract_receipt_statistics(_tb) withdraw-money pay-order-list
  • 平台:announcements✅ company-module-info✅ get-showdoc-menu✅ feedback ip_to_region

⏳ 项:写入类接口(POST/PUT)为避免对生产系统产生副作用未做探测,需要在自研时按功能自行定义,或后续用浏览器 DevTools Network 面板在实际操作时抓包补全。

6. 里程碑计划

里程碑 内容 验收
M1 基础框架 FastAPI 骨架/统一响应/JWT 认证/Vue3 骨架/部署脚本 登录+用户中心跑通
M2 业务 CRUD 客户/合同/订单/产品/仓库 + Excel 导入导出 + 权限 全部 ✅ 接口对等实现
M3 样板库+画图编辑器 拖拽布置、中梃分割、扇/玻璃指定、尺寸标注 加载全部 254 个采集样本渲染一致
M4 报价+算料 价格脚本引擎、自动报价、手动报价 与原站同窗型报价误差为 0
M5 生产+下料+打印 订单进度、optimize1d、打印模板 优化利用率 ≥ 原站
M6 生态 微信登录/支付、商城、邀请返利、多语言 对齐原站

7. 风险与合规

  1. 只仿功能,不搬代码/素材:功能逻辑与数据模型不受版权保护,但对方源码、图标、宣传图文受保护。本项目全部自研,采集数据仅作开发参照;官方样板库图片存于对方 OSS(webcc-pro.oss-cn-hangzhou...),上线前需替换为自绘素材或取得授权。
  2. 采集凭据时效:本次使用的 Bearer token 有效期至 2026-09-21 06:05;账户试用期至 2026-09-23。后续采集需重新登录获取 token。
  3. 生产 API 礼貌访问:所有采集均为只读且 0.3s 限速;不触碰写入接口、不触发异常路径(其报错响应会暴露框架堆栈,属对方运维问题,勿利用)。
  4. 待补全项:订单/报价写入接口的请求体结构(需浏览器抓包);价格脚本语言文法(需实际配置产品后观察)。

8. 下一步(按优先级)

  1. M1 搭建 FastAPI + Vue3 骨架,落统一响应与 JWT
  2. 导入采集数据:windoor_templates、default_windoor_catelogs 建表入库(数据已就绪)
  3. 画布 shapeManager 原型:先实现"读取 254 个样本→静态渲染",再补交互
  4. 用户在真实环境抓包补全 ⏳ 接口后,更新 doc/API.md