文档目录结构简洁化
This commit is contained in:
@@ -11,11 +11,19 @@
|
||||
|
||||
</div>
|
||||
|
||||
geMoldInsight 是一个面向模具制造场景的综合系统,围绕 **STP/STEP 模型分析、模具方案生成、分析结果沉淀、成品创建、BOM/库存/采购/销售闭环** 展开。
|
||||
geMoldInsight 是一个面向模具制造场景的综合系统,围绕 **STEP/STP 模型分析、模具方案生成、分析结果沉淀、成品创建、BOM/库存/采购/销售闭环** 展开。
|
||||
|
||||
> **当前实现状态**:见 [docs/STATUS.md](docs/STATUS.md)
|
||||
> **当前架构与边界**:见 [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)
|
||||
> **本文是唯一文档导航入口**:请按角色或主题跳转到对应主文档
|
||||
|
||||
---
|
||||
|
||||
## 项目概览
|
||||
|
||||
当前项目已经从早期单体演进为:
|
||||
|
||||
- **gemold(moldinsight)模块**:模具分析、几何处理、批量分析、成本估算、结果导出
|
||||
- **moldinsight 模块**:模具分析、几何处理、批量分析、成本估算、结果导出
|
||||
- **inventory 模块**:产品、BOM、库存、采购、销售、财务
|
||||
- **frontend 模块**:Vue 3 前端工程
|
||||
- **shared 平台层**:配置、数据库、认证、日志、应用工厂
|
||||
@@ -24,7 +32,98 @@ geMoldInsight 是一个面向模具制造场景的综合系统,围绕 **STP/ST
|
||||
|
||||
> **单仓库 + 单数据库 + 多模块 + 可独立部署**
|
||||
|
||||
详细重构方向见:[BACKEND_MODULARIZATION_BLUEPRINT.md](docs/BACKEND_MODULARIZATION_BLUEPRINT.md)
|
||||
更详细的结构说明见 [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)。
|
||||
|
||||
---
|
||||
|
||||
## 快速开始(三步)
|
||||
|
||||
### 1. 安装依赖
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
前端开发需要:
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
npm install
|
||||
```
|
||||
|
||||
### 2. 配置环境变量
|
||||
|
||||
复制并编辑:
|
||||
|
||||
- [`.env.example`](.env.example)
|
||||
- 部署场景可参考 [deploy/.env.example](deploy/.env.example)
|
||||
|
||||
### 3. 启动
|
||||
|
||||
推荐先查看部署入口:
|
||||
- [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md)
|
||||
|
||||
本地常见方式:
|
||||
|
||||
```bash
|
||||
docker compose --profile full up -d
|
||||
```
|
||||
|
||||
如需直接运行:
|
||||
|
||||
```bash
|
||||
uvicorn src.entrypoints.moldinsight:app --reload --host 0.0.0.0 --port 8000
|
||||
uvicorn src.entrypoints.inventory:app --reload --host 0.0.0.0 --port 8001
|
||||
```
|
||||
|
||||
> 如需 OCC 几何分析能力,请准备 PythonOCC 运行环境。项目中通常通过 conda 提供,而不是仅靠 pip 安装。
|
||||
|
||||
---
|
||||
|
||||
## 目录概览
|
||||
|
||||
```text
|
||||
geMoldInsight/
|
||||
├── src/
|
||||
│ ├── entrypoints/ # 独立部署入口
|
||||
│ ├── shared/ # 当前共享平台层
|
||||
│ ├── moldinsight/ # 模具分析模块
|
||||
│ ├── inventory/ # 进销存模块
|
||||
│ ├── celery_app.py # Celery app
|
||||
│ └── celery_tasks.py # moldinsight 异步任务
|
||||
├── frontend/ # 独立前端工程
|
||||
├── alembic/ # 数据库迁移
|
||||
├── deploy/ # 镜像、Nginx、部署辅助文件
|
||||
├── docs/
|
||||
├── tests/
|
||||
├── requirements.txt
|
||||
└── .env.example
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 文档导航(唯一入口)
|
||||
|
||||
### 按主题阅读
|
||||
|
||||
| 文档 | 解决什么问题 |
|
||||
|---|---|
|
||||
| [docs/STATUS.md](docs/STATUS.md) | 当前实现状态、当前推荐方案、近期完成项 |
|
||||
| [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | 当前架构、模块边界、结构原则 |
|
||||
| [docs/ROADMAP.md](docs/ROADMAP.md) | 后续演进路线与阶段计划 |
|
||||
| [docs/TECH_DEBT.md](docs/TECH_DEBT.md) | 当前活跃技术债与治理计划 |
|
||||
| [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md) | 部署主题入口与部署文档分工 |
|
||||
| [docs/deployment/LINUX_SETUP.md](docs/deployment/LINUX_SETUP.md) | Linux 环境下的详细部署步骤 |
|
||||
| [docs/archive/BACKEND_MODULARIZATION_BLUEPRINT.md](docs/archive/BACKEND_MODULARIZATION_BLUEPRINT.md) | 模块化蓝图档案与补充设计讨论 |
|
||||
|
||||
### 按角色阅读
|
||||
|
||||
| 你是 | 建议阅读顺序 |
|
||||
|---|---|
|
||||
| 第一次了解项目 | 本文 → [docs/STATUS.md](docs/STATUS.md) → [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) |
|
||||
| 开发者 / 改代码 | 本文 → [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) → [docs/TECH_DEBT.md](docs/TECH_DEBT.md) → 相关专题文档 |
|
||||
| 运维 / 部署 | 本文 → [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md) → [docs/deployment/LINUX_SETUP.md](docs/deployment/LINUX_SETUP.md) |
|
||||
| 规划 / 重构 | 本文 → [docs/ROADMAP.md](docs/ROADMAP.md) → [docs/TECH_DEBT.md](docs/TECH_DEBT.md) |
|
||||
|
||||
---
|
||||
|
||||
@@ -32,7 +131,7 @@ geMoldInsight 是一个面向模具制造场景的综合系统,围绕 **STP/ST
|
||||
|
||||
| 模块 | 能力 |
|
||||
|---|---|
|
||||
| gemold | STP/STEP 上传、几何分析、特征识别、模具方案、批量分析、成本估算、结果导出 |
|
||||
| moldinsight | STEP/STP 上传、几何分析、特征识别、模具方案、批量分析、成本估算、结果导出 |
|
||||
| inventory | 成品/物料、BOM、库存、库存流水、采购订单、销售订单、财务、采购建议 |
|
||||
| integration | 分析结果一键创建成品,打通“模具分析 → 成品 → BOM → 销售/采购/库存” |
|
||||
| platform | 用户、角色、权限、JWT 鉴权、数据库连接、日志、健康检查 |
|
||||
@@ -42,399 +141,35 @@ geMoldInsight 是一个面向模具制造场景的综合系统,围绕 **STP/ST
|
||||
## 技术栈
|
||||
|
||||
### 后端
|
||||
- **FastAPI**
|
||||
- **SQLAlchemy 2.0**
|
||||
- **PostgreSQL**
|
||||
- **Alembic**
|
||||
- **Redis**
|
||||
- **Celery**
|
||||
- **PythonOCC / trimesh / pyvista**
|
||||
- **RustFS / MinIO 兼容对象存储**
|
||||
- FastAPI
|
||||
- SQLAlchemy 2.0
|
||||
- PostgreSQL
|
||||
- Alembic
|
||||
- Redis
|
||||
- Celery
|
||||
- PythonOCC / trimesh / pyvista
|
||||
- RustFS / MinIO 兼容对象存储
|
||||
|
||||
### 前端
|
||||
- **Vue 3**
|
||||
- **Vite**
|
||||
- **TypeScript**
|
||||
- **Pinia**
|
||||
- **Vue Router**
|
||||
- **TDesign Vue Next**
|
||||
- Vue 3
|
||||
- Vite
|
||||
- TypeScript
|
||||
- Pinia
|
||||
- Vue Router
|
||||
- TDesign Vue Next
|
||||
|
||||
### 基础设施
|
||||
- **Docker / Docker Compose**
|
||||
- **结构化日志 / request_id**
|
||||
- **OpenAPI → TypeScript 类型生成**
|
||||
- Docker / Docker Compose
|
||||
- 结构化日志 / request_id
|
||||
- OpenAPI → TypeScript 类型生成
|
||||
|
||||
---
|
||||
|
||||
## 当前项目结构
|
||||
## 当前代码入口
|
||||
|
||||
> 下述结构反映的是**当前代码现状**,不是历史单体结构。
|
||||
|
||||
```text
|
||||
geMoldInsight/
|
||||
├── src/
|
||||
│ ├── entrypoints/ # 独立部署入口
|
||||
│ │ ├── moldinsight.py # gemold-only 入口
|
||||
│ │ └── inventory.py # inventory-only 入口
|
||||
│ │
|
||||
│ ├── shared/ # 共享平台层(当前形态)
|
||||
│ │ ├── app_factory.py # FastAPI 应用工厂
|
||||
│ │ ├── config/ # 配置
|
||||
│ │ ├── database/ # DB engine / session / init
|
||||
│ │ ├── models/ # 共享 ORM 模型(当前最大耦合点)
|
||||
│ │ ├── services/ # 认证、Redis 等共享服务
|
||||
│ │ └── utils/ # 日志、文件、HTML 工具
|
||||
│ │
|
||||
│ ├── moldinsight/ # gemold 模块
|
||||
│ │ ├── api/
|
||||
│ │ ├── core/
|
||||
│ │ ├── services/
|
||||
│ │ └── storage/
|
||||
│ │
|
||||
│ ├── inventory/ # inventory 模块
|
||||
│ │ ├── api/
|
||||
│ │ ├── schemas/
|
||||
│ │ └── services/
|
||||
│ │
|
||||
│ ├── celery_app.py # Celery app
|
||||
│ ├── celery_tasks.py # gemold 异步任务
|
||||
│ └── main.py # 旧统一入口(兼容/过渡)
|
||||
│
|
||||
├── frontend/ # 独立前端工程
|
||||
│ ├── src/
|
||||
│ │ ├── modules/
|
||||
│ │ │ ├── moldinsight/
|
||||
│ │ │ ├── inventory/
|
||||
│ │ │ ├── login/
|
||||
│ │ │ ├── users/
|
||||
│ │ │ └── home/
|
||||
│ │ ├── router/
|
||||
│ │ ├── shared/
|
||||
│ │ ├── stores/
|
||||
│ │ └── types/
|
||||
│ └── package.json
|
||||
│
|
||||
├── alembic/ # Alembic migrations
|
||||
├── deploy/ # 镜像构建、Nginx 配置与部署辅助文件
|
||||
│ ├── Dockerfile.base
|
||||
│ ├── Dockerfile.moldinsight
|
||||
│ ├── Dockerfile.inventory
|
||||
│ ├── Dockerfile.celery
|
||||
│ ├── Dockerfile.frontend
|
||||
│ └── nginx/
|
||||
│
|
||||
├── docs/
|
||||
├── tests/
|
||||
├── requirements.txt
|
||||
└── .env.example
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 模块说明
|
||||
|
||||
### 1. gemold(moldinsight)
|
||||
|
||||
主要负责:
|
||||
- STP/STEP 上传与任务管理
|
||||
- 几何分析与特征识别
|
||||
- 模具方案、型腔/型芯/工艺建议
|
||||
- 批量分析
|
||||
- 成本估算
|
||||
- 导出与结果查询
|
||||
- Celery 异步处理
|
||||
|
||||
关键目录:
|
||||
- [src/moldinsight/](src/moldinsight/)
|
||||
- [src/celery_app.py](src/celery_app.py)
|
||||
- [src/celery_tasks.py](src/celery_tasks.py)
|
||||
|
||||
### 2. inventory
|
||||
|
||||
主要负责:
|
||||
- 成品/物料管理
|
||||
- BOM
|
||||
- 库存与库存流水
|
||||
- 采购订单 / 销售订单
|
||||
- 财务与对账
|
||||
- 采购建议推导
|
||||
|
||||
关键目录:
|
||||
- [src/inventory/](src/inventory/)
|
||||
|
||||
### 3. frontend
|
||||
|
||||
主要负责:
|
||||
- 模具分析页面
|
||||
- 进销存页面
|
||||
- 登录/用户管理
|
||||
- 统一路由与状态管理
|
||||
- 基于 OpenAPI 生成类型的前端 API 调用
|
||||
|
||||
关键目录:
|
||||
- [frontend/](frontend/)
|
||||
|
||||
### 4. shared(当前平台层)
|
||||
|
||||
主要负责:
|
||||
- 配置
|
||||
- 数据库连接与 session
|
||||
- 认证与权限
|
||||
- 日志与 request_id
|
||||
- 应用工厂与通用中间件
|
||||
|
||||
关键目录:
|
||||
- [src/shared/](src/shared/)
|
||||
|
||||
> 说明:后续会逐步将 `shared` 收敛为更清晰的 `platform` 语义,见 [BACKEND_MODULARIZATION_BLUEPRINT.md](docs/BACKEND_MODULARIZATION_BLUEPRINT.md)。
|
||||
|
||||
---
|
||||
|
||||
## 部署模式
|
||||
|
||||
当前项目设计上支持三种模式:
|
||||
|
||||
### 1. unified(当前推荐)
|
||||
一个统一后端同时挂载 gemold + inventory,并作为前端同域反代的默认 backend。
|
||||
|
||||
适合:
|
||||
- 本地开发
|
||||
- 集成环境
|
||||
- 小团队统一部署
|
||||
- 前端独立部署 + 单 upstream 反代
|
||||
|
||||
### 2. gemold-only
|
||||
只部署模具分析后端。
|
||||
|
||||
适合:
|
||||
- 单独开放分析能力
|
||||
- 分析任务独立扩容
|
||||
- 文件处理与异步任务独立部署
|
||||
|
||||
入口参考:
|
||||
- [src/entrypoints/moldinsight.py](src/entrypoints/moldinsight.py)
|
||||
|
||||
### 3. inventory-only
|
||||
只部署进销存后端。
|
||||
|
||||
适合:
|
||||
- 仅使用 ERP / 库存能力
|
||||
- 与 gemold 分开部署节奏
|
||||
|
||||
入口参考:
|
||||
- [src/entrypoints/inventory.py](src/entrypoints/inventory.py)
|
||||
|
||||
---
|
||||
|
||||
## 快速开始
|
||||
|
||||
## 1. 环境要求
|
||||
|
||||
- Python 3.12
|
||||
- PostgreSQL 15+(服务器已部署或自行提供)
|
||||
- Redis(服务器已部署或自行提供)
|
||||
- 对象存储(MinIO / RustFS 兼容;gemold 模块需要,服务器已部署或自行提供)
|
||||
- Node.js 20+(前端开发需要)
|
||||
- 推荐使用 `docker-compose.yml` 仅启动项目自身服务,复用服务器已有 PostgreSQL / Redis / 对象存储
|
||||
|
||||
---
|
||||
|
||||
## 2. 安装后端依赖
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
如果需要几何分析能力,还需确保 PythonOCC 运行环境可用。项目中已说明其通常通过 conda 提供,而不是直接由 pip 安装。
|
||||
|
||||
---
|
||||
|
||||
## 3. 配置环境变量
|
||||
|
||||
复制并编辑:
|
||||
|
||||
- [`.env.example`](.env.example)
|
||||
- 部署场景也可参考 [deploy/.env.example](deploy/.env.example)
|
||||
|
||||
最少需要关注:
|
||||
|
||||
```env
|
||||
HOST=0.0.0.0
|
||||
PORT=8000
|
||||
|
||||
DB_HOST=localhost
|
||||
DB_PORT=5432
|
||||
DB_NAME=moldinsight
|
||||
DB_USER=moldinsight_user
|
||||
DB_PASSWORD=moldinsight_password
|
||||
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PORT=6379
|
||||
REDIS_PASSWORD=
|
||||
|
||||
SECRET_KEY=change-me
|
||||
ADMIN_USERNAME=admin
|
||||
ADMIN_PASSWORD=change-me
|
||||
|
||||
RUSTFS_ENDPOINT=http://localhost:9000
|
||||
RUSTFS_ACCESS_KEY=your-access-key
|
||||
RUSTFS_SECRET_KEY=your-secret-key
|
||||
```
|
||||
|
||||
更多配置项见:
|
||||
- [settings.py](src/shared/config/settings.py)
|
||||
- [.env.example](.env.example)
|
||||
|
||||
---
|
||||
|
||||
## 4. 初始化数据库
|
||||
|
||||
项目当前使用 Alembic 管理迁移。应用启动时也会执行初始化逻辑,但首次部署建议显式执行迁移流程。
|
||||
|
||||
如需查看初始化实现,可参考:
|
||||
- [init_db.py](src/shared/database/init_db.py)
|
||||
|
||||
---
|
||||
|
||||
## 5. 启动方式
|
||||
|
||||
### 方式 A:使用根目录 Compose(推荐)
|
||||
|
||||
当前唯一 Compose 入口:
|
||||
- [docker-compose.yml](docker-compose.yml)
|
||||
|
||||
该 compose 文件会启动:
|
||||
- `frontend`(独立前端 Nginx 静态站点)
|
||||
- `backend`(unified backend,当前推荐)
|
||||
- `moldinsight-celery`
|
||||
- 可选保留:`moldinsight` / `inventory`(模块独立部署 profile)
|
||||
|
||||
其中:
|
||||
- 前端通过同域反代把 `/api`、`/health`、`/html` 转发给 unified backend
|
||||
- PostgreSQL / Redis / RustFS / MinIO 兼容对象存储仍由服务器现有服务提供
|
||||
|
||||
示例:
|
||||
|
||||
```bash
|
||||
docker compose --profile full up -d
|
||||
```
|
||||
|
||||
可选 profile:
|
||||
- `full`
|
||||
- `frontend`
|
||||
- `unified`
|
||||
- `moldinsight`
|
||||
- `inventory`
|
||||
|
||||
> 说明:根目录 `docker-compose.yml` 是当前唯一 Compose 入口;前端已独立部署,并默认反代到 unified backend。
|
||||
|
||||
### 方式 B:直接启动后端入口
|
||||
|
||||
gemold-only:
|
||||
|
||||
```bash
|
||||
uvicorn src.entrypoints.moldinsight:app --reload --host 0.0.0.0 --port 8000
|
||||
```
|
||||
|
||||
inventory-only:
|
||||
|
||||
```bash
|
||||
uvicorn src.entrypoints.inventory:app --reload --host 0.0.0.0 --port 8001
|
||||
```
|
||||
|
||||
### 方式 C:单独启动前端开发服务器
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
生产构建:
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
npm run build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 健康检查与接口
|
||||
|
||||
### 健康检查
|
||||
|
||||
两类后端都通过共享 app factory 暴露健康检查:
|
||||
|
||||
- `GET /health`
|
||||
- `POST /health`
|
||||
|
||||
参考实现:
|
||||
- [app_factory.py](src/shared/app_factory.py)
|
||||
|
||||
### 认证接口
|
||||
|
||||
- `POST /api/auth/login`
|
||||
- `POST /api/auth/logout`
|
||||
- `GET /api/auth/me`
|
||||
|
||||
### gemold 典型接口
|
||||
|
||||
- `POST /api/upload`
|
||||
- `POST /api/batch-upload`
|
||||
- `GET /api/status/{task_id}`
|
||||
- `GET /api/history`
|
||||
- `POST /api/cost-estimate`
|
||||
|
||||
### inventory 典型接口
|
||||
|
||||
- `GET /api/products`
|
||||
- `GET /api/inventory`
|
||||
- `GET /api/purchase-orders`
|
||||
- `GET /api/sales-orders`
|
||||
- `GET /api/finance/*`
|
||||
|
||||
统一契约输出可参考:
|
||||
- [openapi.json](openapi.json)
|
||||
- [frontend/src/types/api.ts](frontend/src/types/api.ts)
|
||||
|
||||
---
|
||||
|
||||
## 当前架构重点说明
|
||||
|
||||
### 1. gemold 与 inventory 已基本模块化
|
||||
|
||||
当前代码层面,`src/moldinsight/` 与 `src/inventory/` 已基本无直接互相依赖,说明业务边界已经初步成型。
|
||||
|
||||
### 2. 当前最大耦合点在 shared + 共享 ORM
|
||||
|
||||
需要特别注意:
|
||||
|
||||
- [src/shared/models/database.py](src/shared/models/database.py) 同时定义了 identity、gemold、inventory 的 ORM 模型
|
||||
- [src/shared/app_factory.py](src/shared/app_factory.py) 仍承担较多平台与模块组合职责
|
||||
|
||||
这也是下一阶段重构的重点。
|
||||
|
||||
### 3. 单数据库是刻意选择
|
||||
|
||||
项目不是把 gemold 与 inventory 拆成两个数据库,而是保留一个共享数据库,用于支撑完整业务闭环:
|
||||
|
||||
- 分析结果
|
||||
- 创建成品
|
||||
- 成品 BOM
|
||||
- 销售 / 采购 / 库存
|
||||
|
||||
典型桥接点:
|
||||
- `STPFile.product_id -> Product.id`
|
||||
|
||||
---
|
||||
|
||||
## 开发与演进文档
|
||||
|
||||
推荐先阅读:
|
||||
|
||||
- [BACKEND_MODULARIZATION_BLUEPRINT.md](docs/BACKEND_MODULARIZATION_BLUEPRINT.md) — 当前模块化重构蓝图
|
||||
- [EVOLUTION_ROADMAP.md](docs/EVOLUTION_ROADMAP.md) — 历史演进与阶段任务
|
||||
- [docs/deployment/](docs/deployment/) — 现有部署文档(部分仍在对齐中)
|
||||
- moldinsight-only: [src/entrypoints/moldinsight.py](src/entrypoints/moldinsight.py)
|
||||
- inventory-only: [src/entrypoints/inventory.py](src/entrypoints/inventory.py)
|
||||
- 当前 Compose 入口: [docker-compose.yml](docker-compose.yml)
|
||||
|
||||
---
|
||||
|
||||
@@ -442,8 +177,8 @@ npm run build
|
||||
|
||||
- 新增业务逻辑优先放入对应业务模块,不要继续堆进 `shared`
|
||||
- 新增 API 时优先考虑模块归属,而不是“能放就放”
|
||||
- 前端优先通过域 API client 调用接口,而不是散落裸 `/api/...` 路径
|
||||
- 数据模型改动要同时考虑表归属与 Alembic 迁移影响
|
||||
- 文档状态统一维护在 [docs/STATUS.md](docs/STATUS.md)
|
||||
- 部署方式变化统一更新 [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,221 @@
|
||||
# geMoldInsight 架构与边界(ARCHITECTURE)
|
||||
|
||||
> 文档定位:**当前架构、模块边界与结构原则的权威文档**。
|
||||
> 本文描述“现在的系统结构是什么、边界如何划分、目标形态是什么”;不负责维护当前实现进度,当前状态见 [STATUS.md](STATUS.md),部署见 [DEPLOYMENT.md](DEPLOYMENT.md),演进路线见 [ROADMAP.md](ROADMAP.md)。
|
||||
> 如需追溯模块化设计蓝图与扩展讨论,见 [archive/BACKEND_MODULARIZATION_BLUEPRINT.md](archive/BACKEND_MODULARIZATION_BLUEPRINT.md)。
|
||||
|
||||
---
|
||||
|
||||
## 1. 架构目标
|
||||
|
||||
geMoldInsight 的目标架构不是微服务,也不是继续维持历史单体,而是:
|
||||
|
||||
> **单仓库 + 单数据库 + 多模块 + 可独立部署的 modular monolith**
|
||||
|
||||
这意味着:
|
||||
|
||||
- 保持同一 Git 仓库
|
||||
- 保持同一 PostgreSQL 数据库
|
||||
- 按模块组织业务代码与部署入口
|
||||
- 在不拆库、不拆仓的前提下,明确业务边界与部署边界
|
||||
|
||||
---
|
||||
|
||||
## 2. 当前模块划分
|
||||
|
||||
### 2.1 moldinsight
|
||||
|
||||
目录:
|
||||
- [src/moldinsight/](../src/moldinsight/)
|
||||
|
||||
职责:
|
||||
- STEP/STP 上传与任务管理
|
||||
- 几何分析与特征识别
|
||||
- 模具方案生成
|
||||
- 批量分析
|
||||
- 成本估算
|
||||
- 导出与结果查询
|
||||
- 结合 Celery 执行异步分析链路
|
||||
|
||||
### 2.2 inventory
|
||||
|
||||
目录:
|
||||
- [src/inventory/](../src/inventory/)
|
||||
|
||||
职责:
|
||||
- 成品/物料管理
|
||||
- BOM 管理
|
||||
- 库存与库存流水
|
||||
- 采购订单 / 销售订单
|
||||
- 财务与对账
|
||||
- 采购建议推导
|
||||
|
||||
### 2.3 frontend
|
||||
|
||||
目录:
|
||||
- [frontend/](../frontend/)
|
||||
|
||||
职责:
|
||||
- 模具分析页面
|
||||
- 进销存页面
|
||||
- 登录/用户管理
|
||||
- 统一路由与状态管理
|
||||
- 基于 OpenAPI 类型生成的前端调用
|
||||
|
||||
### 2.4 shared(当前平台层)
|
||||
|
||||
目录:
|
||||
- [src/shared/](../src/shared/)
|
||||
|
||||
职责:
|
||||
- 配置
|
||||
- 数据库连接与 session
|
||||
- 认证与权限
|
||||
- 日志与 request_id
|
||||
- 应用工厂与共用中间件
|
||||
|
||||
说明:
|
||||
- `shared` 当前仍是“共享平台层 + 历史耦合区”的混合体
|
||||
- 后续会继续向更清晰的 platform 语义收敛,但当前仓库结构仍以 `shared` 为事实名称
|
||||
|
||||
---
|
||||
|
||||
## 3. 当前代码结构
|
||||
|
||||
当前核心结构如下:
|
||||
|
||||
```text
|
||||
geMoldInsight/
|
||||
├── src/
|
||||
│ ├── entrypoints/
|
||||
│ │ ├── moldinsight.py
|
||||
│ │ └── inventory.py
|
||||
│ ├── shared/
|
||||
│ ├── moldinsight/
|
||||
│ ├── inventory/
|
||||
│ ├── celery_app.py
|
||||
│ └── celery_tasks.py
|
||||
├── frontend/
|
||||
├── alembic/
|
||||
├── deploy/
|
||||
├── docs/
|
||||
└── tests/
|
||||
```
|
||||
|
||||
这反映的是**当前实际代码组织**,不是历史单体结构。
|
||||
|
||||
---
|
||||
|
||||
## 4. 部署边界
|
||||
|
||||
当前设计上支持三种部署模式:
|
||||
|
||||
### 4.1 unified
|
||||
|
||||
一个统一后端同时承载 moldinsight + inventory,并作为前端默认反代目标。
|
||||
|
||||
适合:
|
||||
- 本地开发
|
||||
- 集成环境
|
||||
- 小团队统一部署
|
||||
|
||||
### 4.2 moldinsight-only
|
||||
|
||||
只部署模具分析后端。
|
||||
|
||||
适合:
|
||||
- 单独开放分析能力
|
||||
- 异步任务与文件处理独立扩容
|
||||
|
||||
入口:
|
||||
- [src/entrypoints/moldinsight.py](../src/entrypoints/moldinsight.py)
|
||||
|
||||
### 4.3 inventory-only
|
||||
|
||||
只部署进销存后端。
|
||||
|
||||
适合:
|
||||
- 独立使用 ERP / 库存能力
|
||||
- 与 moldinsight 分开部署节奏
|
||||
|
||||
入口:
|
||||
- [src/entrypoints/inventory.py](../src/entrypoints/inventory.py)
|
||||
|
||||
部署操作与当前推荐方案见 [DEPLOYMENT.md](DEPLOYMENT.md)。
|
||||
|
||||
---
|
||||
|
||||
## 5. 关键架构原则
|
||||
|
||||
### 5.1 单数据库是刻意设计
|
||||
|
||||
项目不是把 moldinsight 与 inventory 强拆成两个数据库,而是保留共享数据库,以支撑完整业务闭环:
|
||||
|
||||
- 分析结果
|
||||
- 创建成品
|
||||
- 成品 BOM
|
||||
- 销售 / 采购 / 库存
|
||||
|
||||
典型桥接关系示例:
|
||||
- `STPFile.product_id -> Product.id`
|
||||
|
||||
### 5.2 模块边界优先于“临时方便”
|
||||
|
||||
新增逻辑时,应优先放入对应业务模块,而不是继续堆进 `shared`。
|
||||
|
||||
原则上:
|
||||
- moldinsight 业务进入 `src/moldinsight/`
|
||||
- inventory 业务进入 `src/inventory/`
|
||||
- 只有真正跨模块复用的基础能力才进入 `src/shared/`
|
||||
|
||||
### 5.3 前端是独立工程,不是后端静态附属
|
||||
|
||||
前端已是独立 Vite/Vue 工程,部署上可与后端组合,但在代码组织上应视为独立模块,而不是后端 `static/` 的扩展。
|
||||
|
||||
---
|
||||
|
||||
## 6. 当前主要耦合点
|
||||
|
||||
虽然模块化已经成型,但仍有几个关键耦合点需要持续关注:
|
||||
|
||||
### 6.1 共享 ORM 模型
|
||||
|
||||
当前 [src/shared/models/database.py](../src/shared/models/database.py) 同时承载 identity、moldinsight、inventory 三类模型,是当前最强耦合点之一。
|
||||
|
||||
### 6.2 app factory 组合职责偏重
|
||||
|
||||
当前 [src/shared/app_factory.py](../src/shared/app_factory.py) 仍承担较多平台与模块组合职责,是后续平台层收敛的重点。
|
||||
|
||||
### 6.3 文档与结构尚未完全同步
|
||||
|
||||
代码结构已明显模块化,但历史文档中仍保留不少阶段性叙述、旧部署语义与重复说明,这也是本轮文档整理要解决的问题之一。
|
||||
|
||||
---
|
||||
|
||||
## 7. 专题文档与主骨架的关系
|
||||
|
||||
以下文档仍可作为专题补充参考,但不再承担默认入口职责:
|
||||
|
||||
- AI / FreeCAD 方向:
|
||||
- [topics/ai/AI_ENGINE_DESIGN.md](topics/ai/AI_ENGINE_DESIGN.md)
|
||||
- [topics/ai/AI_FREECAD_INTEGRATION.md](topics/ai/AI_FREECAD_INTEGRATION.md)
|
||||
- 存储方向:
|
||||
- [topics/storage/RUSTFS_STORAGE.md](topics/storage/RUSTFS_STORAGE.md)
|
||||
- [topics/storage/STORAGE_SETUP.md](topics/storage/STORAGE_SETUP.md)
|
||||
- 铝泡沫模具专题:
|
||||
- [topics/aluminum-foam/SPEC_ALUMINUM_FOAM_MOLD.md](topics/aluminum-foam/SPEC_ALUMINUM_FOAM_MOLD.md)
|
||||
- 性能专题:
|
||||
- [topics/performance/PERFORMANCE_SCALABILITY_PLAN.md](topics/performance/PERFORMANCE_SCALABILITY_PLAN.md)
|
||||
- [topics/performance/PERFORMANCE_BENCHMARKS.md](topics/performance/PERFORMANCE_BENCHMARKS.md)
|
||||
|
||||
阶段性任务清单、迁移计划、历史总结等文档会逐步迁入 [archive/README.md](archive/README.md)。
|
||||
|
||||
---
|
||||
|
||||
## 8. 与相关文档的边界
|
||||
|
||||
- 想看“当前做到哪一步”:看 [STATUS.md](STATUS.md)
|
||||
- 想看“后面还要往哪演进”:看 [ROADMAP.md](ROADMAP.md)
|
||||
- 想看“当前有哪些活跃技术债”:看 [TECH_DEBT.md](TECH_DEBT.md)
|
||||
- 想看“怎么部署”:看 [DEPLOYMENT.md](DEPLOYMENT.md)
|
||||
- 想看“模块化蓝图与更完整设计讨论”:看 [archive/BACKEND_MODULARIZATION_BLUEPRINT.md](archive/BACKEND_MODULARIZATION_BLUEPRINT.md)
|
||||
@@ -1,908 +0,0 @@
|
||||
# geMoldInsight 后端模块化重构蓝图
|
||||
|
||||
> 目标:在**同一 Git 仓库**、**同一数据库**前提下,将当前代码结构整理为**可独立部署的多模块架构**,明确 gemold、inventory、frontend 的边界与演进路径。本文档是后续实施的权威蓝图,不是历史记录。
|
||||
|
||||
---
|
||||
|
||||
## 1. 背景与目标
|
||||
|
||||
当前项目已经从早期单体演进为“双应用 + 共享层”的形态:
|
||||
|
||||
- 业务模块:`src/moldinsight/`、`src/inventory/`
|
||||
- 共享层:`src/shared/`
|
||||
- 部署入口:`src/entrypoints/moldinsight.py`、`src/entrypoints/inventory.py`
|
||||
- 前端工程:`frontend/`
|
||||
|
||||
从代码现状看,`moldinsight` 与 `inventory` 已基本无直接互引,说明模块边界已经初步形成;但同时,数据库模型、认证、配置、应用工厂等仍集中在 `shared/`,导致当前更接近“**模块化中的单体**”,而不是“**可独立部署的模块化单体**”。
|
||||
|
||||
本次蓝图的目标不是拆库、拆仓、微服务化,而是:
|
||||
|
||||
1. 保持**单仓库(monorepo)**
|
||||
2. 保持**单数据库**
|
||||
3. 将后端正式整理为多个模块:
|
||||
- **gemold**(模具分析 / moldinsight)
|
||||
- **inventory**(进销存)
|
||||
- **identity / platform**(共享基础设施与认证)
|
||||
4. 保持前端为**独立模块工程**,并增强其对多部署模式的兼容
|
||||
5. 支持三种部署模式:
|
||||
- **unified**:gemold + inventory 同时部署
|
||||
- **gemold-only**:仅部署 gemold
|
||||
- **inventory-only**:仅部署 inventory
|
||||
|
||||
---
|
||||
|
||||
## 2. 范围与非目标
|
||||
|
||||
### 2.1 本次蓝图覆盖范围
|
||||
|
||||
- 后端模块边界
|
||||
- 共享层职责重新定义
|
||||
- 单数据库下的模型归属与表所有权
|
||||
- 独立部署模式设计
|
||||
- 前端 API 边界强化策略
|
||||
- 分阶段迁移路径
|
||||
- 风险与验证方法
|
||||
|
||||
### 2.2 非目标
|
||||
|
||||
本蓝图**不包含**以下方向:
|
||||
|
||||
- 多 Git 仓库拆分
|
||||
- 多数据库拆分
|
||||
- 分布式微服务重构
|
||||
- 全量 DDD 重写
|
||||
- 全量前端重构
|
||||
- 事件驱动或消息总线主导的跨服务通信改造
|
||||
|
||||
换句话说,目标架构是:
|
||||
|
||||
> **单仓库 + 单数据库 + 多模块 + 可独立部署的 modular monolith**
|
||||
|
||||
而不是微服务系统。
|
||||
|
||||
---
|
||||
|
||||
## 3. 当前架构快照
|
||||
|
||||
### 3.1 后端现状
|
||||
|
||||
当前核心目录结构如下:
|
||||
|
||||
```text
|
||||
src/
|
||||
entrypoints/
|
||||
moldinsight.py
|
||||
inventory.py
|
||||
shared/
|
||||
app_factory.py
|
||||
config/
|
||||
database/
|
||||
models/
|
||||
services/
|
||||
utils/
|
||||
moldinsight/
|
||||
api/
|
||||
core/
|
||||
services/
|
||||
storage/
|
||||
inventory/
|
||||
api/
|
||||
schemas/
|
||||
services/
|
||||
```
|
||||
|
||||
其中:
|
||||
|
||||
- [app_factory.py](../src/shared/app_factory.py) 已统一 CORS、日志中间件、startup/shutdown、认证路由、健康检查与 SPA fallback。
|
||||
- [moldinsight.py](../src/entrypoints/moldinsight.py) 与 [inventory.py](../src/entrypoints/inventory.py) 已提供独立入口。
|
||||
- [database.py](../src/shared/models/database.py) 同时包含 identity、moldinsight、inventory 三类模型,是当前最强耦合点。
|
||||
|
||||
### 3.2 前端现状
|
||||
|
||||
前端已是独立 Vite/Vue 工程:
|
||||
|
||||
```text
|
||||
frontend/
|
||||
src/
|
||||
modules/
|
||||
moldinsight/
|
||||
inventory/
|
||||
login/
|
||||
users/
|
||||
home/
|
||||
router/
|
||||
shared/
|
||||
stores/
|
||||
types/
|
||||
```
|
||||
|
||||
特点:
|
||||
|
||||
- 已按页面/业务模块组织
|
||||
- 已有共享 API 层雏形:[api-client.ts](../frontend/src/shared/api-client.ts)
|
||||
- 已接入 OpenAPI 生成类型:[api.ts](../frontend/src/types/api.ts)
|
||||
- 当前仍有大量相对路径 `/api/...` 与 raw `fetch()` 的同源假设
|
||||
|
||||
### 3.3 现状判断
|
||||
|
||||
当前架构可概括为:
|
||||
|
||||
> **HTTP 入口已分离,业务代码已分组,但平台层与数据层仍共享。**
|
||||
|
||||
因此,它适合继续朝“可独立部署的模块化单体”演进,而不适合直接跳到微服务。
|
||||
|
||||
---
|
||||
|
||||
## 4. 目标架构:可独立部署的模块化单体
|
||||
|
||||
### 4.1 架构原则
|
||||
|
||||
目标态采用以下原则:
|
||||
|
||||
1. **组合优先于复制**:不同部署模式通过组合不同模块得到,而不是复制多套代码。
|
||||
2. **平台与业务分离**:`platform` 只承载技术性共享能力,不继续承载业务逻辑。
|
||||
3. **模块所有权清晰**:每张表、每条 API、每个服务类都应有明确归属。
|
||||
4. **单数据库但显式边界**:允许共享 DB,但不允许“共享数据库 = 没有边界”。
|
||||
5. **统一前端,兼容多后端部署形态**:前端继续是一套工程,通过 API client 适配 unified / split deployment。
|
||||
|
||||
### 4.2 架构定位
|
||||
|
||||
目标架构不是“多个服务各自拥有数据库”的微服务,而是:
|
||||
|
||||
- 同一个仓库
|
||||
- 同一个数据库
|
||||
- 多个模块
|
||||
- 多个部署入口
|
||||
- 同一套迁移历史
|
||||
- 同一套共享基础设施能力
|
||||
|
||||
这是一种适合当前项目阶段的**治理性重构**,而不是组织级拆分。
|
||||
|
||||
---
|
||||
|
||||
## 5. 目标目录结构
|
||||
|
||||
以下结构是**目标态**,不要求一次性到位:
|
||||
|
||||
```text
|
||||
src/
|
||||
platform/
|
||||
app/
|
||||
app_factory.py
|
||||
lifecycle.py
|
||||
middleware/
|
||||
config/
|
||||
auth/
|
||||
database/
|
||||
engine.py
|
||||
session.py
|
||||
migrations/
|
||||
observability/
|
||||
contracts/
|
||||
api/
|
||||
events/
|
||||
shared_kernel/
|
||||
types/
|
||||
exceptions/
|
||||
utils/
|
||||
|
||||
modules/
|
||||
moldinsight/
|
||||
application/
|
||||
services/
|
||||
use_cases/
|
||||
domain/
|
||||
models/
|
||||
policies/
|
||||
repositories/
|
||||
infrastructure/
|
||||
persistence/
|
||||
storage/
|
||||
adapters/
|
||||
interfaces/
|
||||
api/
|
||||
schemas/
|
||||
module.py
|
||||
|
||||
inventory/
|
||||
application/
|
||||
services/
|
||||
use_cases/
|
||||
domain/
|
||||
models/
|
||||
policies/
|
||||
repositories/
|
||||
infrastructure/
|
||||
persistence/
|
||||
adapters/
|
||||
interfaces/
|
||||
api/
|
||||
schemas/
|
||||
module.py
|
||||
|
||||
identity/
|
||||
application/
|
||||
domain/
|
||||
infrastructure/
|
||||
interfaces/
|
||||
module.py
|
||||
|
||||
compositions/
|
||||
unified_app.py
|
||||
gemold_app.py
|
||||
inventory_app.py
|
||||
|
||||
legacy/
|
||||
main.py
|
||||
```
|
||||
|
||||
### 5.1 当前目录到目标目录的映射
|
||||
|
||||
| 当前路径 | 目标路径 | 说明 |
|
||||
|---|---|---|
|
||||
| `src/shared/*` | `src/platform/*` | 共享基础设施重新命名与归位 |
|
||||
| `src/moldinsight/*` | `src/modules/moldinsight/*` | gemold 业务模块 |
|
||||
| `src/inventory/*` | `src/modules/inventory/*` | inventory 业务模块 |
|
||||
| `src/entrypoints/*` | `src/compositions/*` | 部署组合层 |
|
||||
| `src/main.py` | `src/legacy/main.py` | 过渡期兼容入口 |
|
||||
|
||||
### 5.2 为什么要引入 `compositions/`
|
||||
|
||||
当前 [entrypoints/](../src/entrypoints/) 已经承担“部署入口”角色,但语义更偏“启动文件”。
|
||||
|
||||
引入 `compositions/` 的意义是明确:
|
||||
|
||||
- 它不是业务模块
|
||||
- 它不是平台能力
|
||||
- 它是“**按部署模式装配模块**”的组合层
|
||||
|
||||
例如:
|
||||
|
||||
- `gemold_app.py`:平台 + identity + moldinsight
|
||||
- `inventory_app.py`:平台 + identity + inventory
|
||||
- `unified_app.py`:平台 + identity + moldinsight + inventory
|
||||
|
||||
---
|
||||
|
||||
## 6. 模块职责边界
|
||||
|
||||
### 6.1 platform
|
||||
|
||||
`platform` 是技术共享层,只承载**跨模块公共基础设施能力**。
|
||||
|
||||
#### 归属范围
|
||||
- app factory / middleware / 生命周期
|
||||
- config
|
||||
- 数据库 engine / session / Alembic 接线
|
||||
- auth / JWT / 权限
|
||||
- 日志 / request_id / observability
|
||||
- 通用 contracts / utilities
|
||||
|
||||
#### 可复用现有实现
|
||||
- [app_factory.py](../src/shared/app_factory.py)
|
||||
- [settings.py](../src/shared/config/settings.py)
|
||||
- [database.py](../src/shared/database/database.py)
|
||||
- [auth_service.py](../src/shared/services/auth_service.py)
|
||||
- [auth_routes.py](../src/shared/services/auth_routes.py)
|
||||
|
||||
#### 规则
|
||||
`platform` 不得继续吸收业务规则代码,否则新的 `platform` 会变成旧的 `shared`。
|
||||
|
||||
---
|
||||
|
||||
### 6.2 moldinsight(gemold)
|
||||
|
||||
`moldinsight` 模块负责模具分析、几何处理和分析结果生命周期。
|
||||
|
||||
#### 归属范围
|
||||
- 上传、任务、历史、批量分析、成本估算、CAM、分析结果
|
||||
- 几何分析、特征检测、模具方案、报告
|
||||
- RustFS / 对象存储接入
|
||||
- Celery 异步处理链路
|
||||
|
||||
#### 可复用现有实现
|
||||
- [moldinsight/api/__init__.py](../src/moldinsight/api/__init__.py)
|
||||
- [processing_service.py](../src/moldinsight/services/processing_service.py)
|
||||
- [task_query_service.py](../src/moldinsight/services/task_query_service.py)
|
||||
- [moldinsight/core/](../src/moldinsight/core/)
|
||||
- [celery_app.py](../src/celery_app.py)
|
||||
- [celery_tasks.py](../src/celery_tasks.py)
|
||||
|
||||
---
|
||||
|
||||
### 6.3 inventory
|
||||
|
||||
`inventory` 模块负责 ERP / 进销存类业务流程。
|
||||
|
||||
#### 归属范围
|
||||
- 产品、物料、供应商、客户、仓库
|
||||
- 库存、库存流水
|
||||
- 销售订单、采购订单、财务、采购建议
|
||||
- BOM / 采购需求推导
|
||||
|
||||
#### 可复用现有实现
|
||||
- [inventory/api/__init__.py](../src/inventory/api/__init__.py)
|
||||
- [inventory_service.py](../src/inventory/services/inventory_service.py)
|
||||
- [sales_order_service.py](../src/inventory/services/sales_order_service.py)
|
||||
- [purchase_order_service.py](../src/inventory/services/purchase_order_service.py)
|
||||
- [finance_service.py](../src/inventory/services/finance_service.py)
|
||||
|
||||
---
|
||||
|
||||
### 6.4 identity
|
||||
|
||||
`identity` 负责用户、角色、权限与认证授权。
|
||||
|
||||
#### 归属范围
|
||||
- User / Role / Permission
|
||||
- 登录、鉴权、管理员接口
|
||||
- 统一授权能力
|
||||
|
||||
在物理目录上,identity 可以先靠近 platform;但逻辑上应从一开始就被视为独立边界,而不是“moldinsight 的一部分”或“inventory 的一部分”。
|
||||
|
||||
---
|
||||
|
||||
## 7. 允许的依赖方向
|
||||
|
||||
这是本蓝图最重要的治理规则之一。
|
||||
|
||||
### 7.1 依赖规则
|
||||
|
||||
```text
|
||||
compositions -> platform
|
||||
compositions -> modules/*
|
||||
|
||||
platform -> 不依赖业务模块
|
||||
|
||||
modules/*/interfaces -> modules/*/application
|
||||
modules/*/application -> modules/*/domain
|
||||
modules/*/infrastructure -> modules/*/domain
|
||||
|
||||
modules/*/interfaces -> platform
|
||||
modules/*/infrastructure -> platform
|
||||
```
|
||||
|
||||
### 7.2 跨模块约束
|
||||
|
||||
- `inventory` 不能直接 import `moldinsight.api` / `moldinsight.services`
|
||||
- `moldinsight` 不能直接 import `inventory.api` / `inventory.services`
|
||||
- `platform` 不得依赖任一业务模块
|
||||
- 跨模块协作只能通过:
|
||||
- 显式 contract / query service
|
||||
- composition wiring
|
||||
- 受控的共享数据库引用
|
||||
|
||||
### 7.3 当前代码与规则的差距
|
||||
|
||||
从代码检查看,当前 `moldinsight` 与 `inventory` 基本没有直接互引,这说明上述规则在业务代码层**已经接近成立**。
|
||||
|
||||
当前主要问题集中在:
|
||||
|
||||
- [database.py](../src/shared/models/database.py) 集中承载所有 ORM 模型
|
||||
- [app_factory.py](../src/shared/app_factory.py) 同时知道通用平台逻辑与 moldinsight 专属 startup 行为
|
||||
|
||||
因此,后续实施的重点不是“切断业务模块互引”,而是“**把共享层与数据层的边界拉直**”。
|
||||
|
||||
---
|
||||
|
||||
## 8. 单数据库下的模型与表归属策略
|
||||
|
||||
### 8.1 核心原则
|
||||
|
||||
数据库继续保持为**一个 PostgreSQL 数据库**,但代码中的模型归属必须显式化。
|
||||
|
||||
也就是说:
|
||||
|
||||
> **数据库不拆,模型归属要拆。**
|
||||
|
||||
### 8.2 当前最强耦合点
|
||||
|
||||
当前 [database.py](../src/shared/models/database.py) 同时包含:
|
||||
|
||||
- identity / 平台相关模型
|
||||
- moldinsight 业务模型
|
||||
- inventory 业务模型
|
||||
|
||||
这会带来两个问题:
|
||||
|
||||
1. 代码层看不出模型所有权
|
||||
2. 开发者更容易跨模块直接访问整套 ORM 图谱
|
||||
|
||||
因此,后续实施应优先将这个文件按归属拆分。
|
||||
|
||||
### 8.3 推荐表归属矩阵
|
||||
|
||||
#### platform / identity-owned
|
||||
- users
|
||||
- roles
|
||||
- permissions
|
||||
- user_roles
|
||||
- role_permissions
|
||||
- (可选)system_logs
|
||||
|
||||
#### moldinsight-owned
|
||||
- stp_files
|
||||
- geometry_data
|
||||
- mesh_data
|
||||
- html_files
|
||||
- processing_tasks
|
||||
- mold_cavity_data
|
||||
- feature_detections
|
||||
- design_recommendations
|
||||
- analysis_metrics
|
||||
|
||||
#### inventory-owned
|
||||
- products
|
||||
- product_materials
|
||||
- material_price_history
|
||||
- material_suppliers
|
||||
- suppliers
|
||||
- customers
|
||||
- warehouses
|
||||
- inventory
|
||||
- stock_movements
|
||||
- purchase_orders
|
||||
- purchase_order_items
|
||||
- sales_orders
|
||||
- sales_order_items
|
||||
- finance_transactions
|
||||
- finance_allocations
|
||||
|
||||
### 8.4 目标代码形态
|
||||
|
||||
推荐逐步演进到:
|
||||
|
||||
```text
|
||||
platform/database/base.py
|
||||
modules/identity/infrastructure/persistence/models.py
|
||||
modules/moldinsight/infrastructure/persistence/models.py
|
||||
modules/inventory/infrastructure/persistence/models.py
|
||||
```
|
||||
|
||||
同时保持:
|
||||
|
||||
- 同一个 SQLAlchemy `Base`
|
||||
- 同一个 metadata
|
||||
- 同一条 Alembic 历史链
|
||||
- 同一个数据库连接
|
||||
|
||||
### 8.5 跨模块 FK 的处理策略
|
||||
|
||||
当前存在真实跨模块业务桥:
|
||||
|
||||
- `STPFile.product_id -> Product.id`
|
||||
|
||||
这是合理的,因为它反映了真实业务关系:模具分析结果可以创建成品,并与 inventory 中的产品建立连接。
|
||||
|
||||
原则上允许保留这类稳定 FK,但应遵守:
|
||||
|
||||
1. 跨模块 FK 是**业务桥**,不是“任意跨模块查询”的许可
|
||||
2. 模块之间应逐步通过 query service / repository contract 暴露需要的读取能力
|
||||
3. 避免一个模块直接依赖另一个模块的整套 ORM 图谱
|
||||
|
||||
---
|
||||
|
||||
## 9. 部署模式设计
|
||||
|
||||
本项目必须支持三种部署模式。
|
||||
|
||||
### 9.1 unified
|
||||
|
||||
#### 组成
|
||||
- platform + identity + moldinsight + inventory
|
||||
|
||||
#### 适用场景
|
||||
- 本地开发
|
||||
- 小团队部署
|
||||
- 集成环境
|
||||
- 一体化业务场景
|
||||
|
||||
#### 说明
|
||||
新的 unified 组合层应接替旧 [main.py](../src/main.py) 的语义,但应通过 `compositions/unified_app.py` 的方式实现,而不是继续维持旧单体式入口。
|
||||
|
||||
---
|
||||
|
||||
### 9.2 gemold-only
|
||||
|
||||
#### 组成
|
||||
- platform + identity + moldinsight
|
||||
|
||||
#### 适用场景
|
||||
- 仅开放模具分析能力
|
||||
- 分析服务独立扩容
|
||||
- 单独部署算法/文件处理能力
|
||||
|
||||
#### 说明
|
||||
- 只暴露 gemold 路由
|
||||
- 可保留对共享数据库中 `products` 的受控引用
|
||||
- RustFS / Celery 等专属基础设施只在该模式启用
|
||||
|
||||
当前入口基线:
|
||||
- [moldinsight.py](../src/entrypoints/moldinsight.py)
|
||||
|
||||
---
|
||||
|
||||
### 9.3 inventory-only
|
||||
|
||||
#### 组成
|
||||
- platform + identity + inventory
|
||||
|
||||
#### 适用场景
|
||||
- 仅提供 ERP / 进销存能力
|
||||
- 不需要模具分析链路的后台场景
|
||||
|
||||
#### 说明
|
||||
- 只暴露 inventory 路由
|
||||
- 不要求启动 RustFS 等 moldinsight 专属基础设施
|
||||
|
||||
当前入口基线:
|
||||
- [inventory.py](../src/entrypoints/inventory.py)
|
||||
|
||||
---
|
||||
|
||||
### 9.4 当前共享工厂的边界问题
|
||||
|
||||
需要特别指出:当前 [app_factory.py](../src/shared/app_factory.py) 通过 `mount_html=True` 分支初始化 RustFS,这说明共享工厂仍然知道 moldinsight 模块专属基础设施。
|
||||
|
||||
这意味着:
|
||||
|
||||
- `shared` / `platform` 还不够纯
|
||||
- 模块专属 startup hook 还没有完全从平台层剥离
|
||||
|
||||
后续实施时,这应是**优先解决的问题之一**:
|
||||
|
||||
> app factory 只负责通用平台装配;模块专属生命周期应由 module hook 或 composition layer 决定。
|
||||
|
||||
---
|
||||
|
||||
## 10. 前端 API 边界策略
|
||||
|
||||
### 10.1 设计原则
|
||||
|
||||
前端已经是独立工程,不需要再拆目录或拆仓。后续重点应放在:
|
||||
|
||||
- 强化域 API 边界
|
||||
- 消除对单一同源 `/api/...` 的强依赖
|
||||
- 兼容 unified / split deployment
|
||||
|
||||
### 10.2 当前可复用基础
|
||||
|
||||
当前前端已经具备良好基础:
|
||||
|
||||
- 域客户端入口:[api-client.ts](../frontend/src/shared/api-client.ts)
|
||||
- 生成类型:[api.ts](../frontend/src/types/api.ts)
|
||||
- 模块目录:[frontend/src/modules/moldinsight/](../frontend/src/modules/moldinsight/) 与 [frontend/src/modules/inventory/](../frontend/src/modules/inventory/)
|
||||
|
||||
因此,后续策略应是“**边界强化**”,不是“前端重写”。
|
||||
|
||||
### 10.3 建议的客户端边界
|
||||
|
||||
应继续收敛为:
|
||||
|
||||
- `authApi`
|
||||
- `moldinsightApi`
|
||||
- `inventoryApi`
|
||||
|
||||
并要求:
|
||||
|
||||
- 页面/组件尽量不直接写裸 `/api/...` 字符串
|
||||
- multipart upload / download / export 也尽量通过域客户端封装
|
||||
- 统一利用 OpenAPI 生成类型,而不是额外维护平行手写类型
|
||||
|
||||
### 10.4 支持两类部署配置
|
||||
|
||||
#### unified 模式
|
||||
- `VITE_API_BASE_URL`
|
||||
|
||||
#### split 模式
|
||||
- `VITE_AUTH_API_BASE_URL`
|
||||
- `VITE_MOLDINSIGHT_API_BASE_URL`
|
||||
- `VITE_INVENTORY_API_BASE_URL`
|
||||
|
||||
客户端实现上应支持:
|
||||
|
||||
- unified 下三个 client 指向同一个 base URL
|
||||
- split 下各 client 指向不同服务
|
||||
|
||||
### 10.5 capability-aware UI
|
||||
|
||||
在 gemold-only 或 inventory-only 部署模式下,前端不应假设所有模块总是存在。
|
||||
|
||||
因此建议:
|
||||
|
||||
- 后端通过 `/health` 或单独 capability endpoint 暴露已启用模块信息
|
||||
- 前端根据 capability 隐藏未部署模块入口或禁用对应页面
|
||||
|
||||
这样可避免“前端路由还在,但后端根本没部署”的硬失败场景。
|
||||
|
||||
---
|
||||
|
||||
## 11. 分阶段迁移计划
|
||||
|
||||
### Phase 0:蓝图冻结
|
||||
|
||||
目标:冻结目标结构与边界规则,防止迁移过程中继续长出新的耦合。
|
||||
|
||||
动作:
|
||||
- 确认模块边界
|
||||
- 确认依赖规则
|
||||
- 确认三种部署模式
|
||||
- 确认 shared/platform 的使用边界
|
||||
|
||||
---
|
||||
|
||||
### Phase 1:组合层标准化
|
||||
|
||||
目标:将部署模式从“若干入口脚本”升级为“正式的 composition layer”。
|
||||
|
||||
动作:
|
||||
- 将 `entrypoints/*` 升级为 `compositions/*`
|
||||
- 定义 `unified_app.py` / `gemold_app.py` / `inventory_app.py`
|
||||
- 将 module-specific startup hooks 从通用 app factory 中迁出
|
||||
|
||||
重点问题:
|
||||
- 当前 `mount_html -> RustFS connect` 属于模块专属逻辑,必须从 shared factory 中剥离
|
||||
|
||||
---
|
||||
|
||||
### Phase 2:platform 与业务代码分治
|
||||
|
||||
目标:把“共享基础设施”从“共享杂项”中真正分离出来。
|
||||
|
||||
动作:
|
||||
- 从 `shared` 语义切换到更清晰的 `platform`
|
||||
- 归位 config / auth / db / observability / utils
|
||||
- 禁止新业务逻辑继续沉积到 `shared`
|
||||
|
||||
---
|
||||
|
||||
### Phase 3:ORM 按归属拆分
|
||||
|
||||
目标:解决当前最大的代码耦合源。
|
||||
|
||||
动作:
|
||||
- 拆分 [database.py](../src/shared/models/database.py)
|
||||
- 保持单 Base / 单 Alembic / 单 DB
|
||||
- 先完成代码层归属拆分,再处理更深层的业务隔离
|
||||
|
||||
这是整个重构中最关键的一步。
|
||||
|
||||
---
|
||||
|
||||
### Phase 4:模块内部继续分层
|
||||
|
||||
目标:让每个模块内部的“路由 / 服务 / 领域 / 基础设施”边界更清晰。
|
||||
|
||||
动作:
|
||||
- inventory:从现有 service 层继续向 `application / domain / infrastructure / interfaces` 拉开
|
||||
- moldinsight:逐步理顺 `api / services / core / storage` 的边界
|
||||
|
||||
原则:
|
||||
- 不要求一步完成 DDD 化
|
||||
- 先把层次职责清楚,再考虑更纯粹的领域对象抽象
|
||||
|
||||
---
|
||||
|
||||
### Phase 5:建立跨模块集成规则
|
||||
|
||||
目标:把当前 ad hoc 跨表访问逐步收敛成显式桥接能力。
|
||||
|
||||
动作:
|
||||
- 定义跨模块 query services / repository contracts
|
||||
- 明确“从分析创建成品”等桥接能力的正式入口
|
||||
- 收敛直接穿透跨模块 ORM 图谱的做法
|
||||
|
||||
重点桥接场景:
|
||||
- `STPFile.product_id`
|
||||
- [product_routes.py](../src/inventory/api/product_routes.py) 中的“按 task 创建产品”逻辑
|
||||
|
||||
---
|
||||
|
||||
### Phase 6:前端边界加固
|
||||
|
||||
目标:让前端真正适配 unified / split deployment。
|
||||
|
||||
动作:
|
||||
- 强制域 API client 收口
|
||||
- 支持 per-module base URL
|
||||
- 支持 capability-aware UI
|
||||
- 减少页面中裸 `fetch('/api/...')`
|
||||
|
||||
---
|
||||
|
||||
### Phase 7:部署与文档收尾
|
||||
|
||||
目标:使架构蓝图与部署事实一致。
|
||||
|
||||
动作:
|
||||
- 固化 unified / gemold-only / inventory-only 部署说明
|
||||
- 更新 README / deployment docs / frontend docs
|
||||
- 明确旧入口、旧 Dockerfile、旧部署说明的地位(兼容 / 历史 / 废弃)
|
||||
|
||||
---
|
||||
|
||||
## 12. 风险与缓解措施
|
||||
|
||||
### 风险 1:共享模型文件继续隐藏领域归属
|
||||
|
||||
**现象**:所有模型集中在 [database.py](../src/shared/models/database.py)
|
||||
|
||||
**风险**:边界无法落实,任何模块都能自然跨领域访问
|
||||
|
||||
**缓解**:
|
||||
- 先产出表归属矩阵
|
||||
- 再拆 ORM 文件
|
||||
- 拆归属优先于改业务逻辑
|
||||
|
||||
---
|
||||
|
||||
### 风险 2:`shared` 继续变成杂物间
|
||||
|
||||
**风险**:shared/platform 成为“不知道放哪就放这里”的位置
|
||||
|
||||
**缓解**:
|
||||
- 以 `platform` 重新定义共享层
|
||||
- 明确只有技术性共享能力可进入 platform
|
||||
- 代码 review 中禁止新增业务逻辑进入 platform
|
||||
|
||||
---
|
||||
|
||||
### 风险 3:模块专属启动逻辑继续留在 app factory
|
||||
|
||||
**现象**:当前 `mount_html` 分支控制 RustFS 连接
|
||||
|
||||
**风险**:平台层继续了解业务模块内部基础设施
|
||||
|
||||
**缓解**:
|
||||
- module lifecycle hook
|
||||
- composition 层控制模块 startup/shutdown
|
||||
- 通用 app factory 保持纯平台化
|
||||
|
||||
---
|
||||
|
||||
### 风险 4:独立部署后,前端仍假设所有模块存在
|
||||
|
||||
**风险**:前端路由可见,但后端未部署,造成运行时错误
|
||||
|
||||
**缓解**:
|
||||
- capability metadata
|
||||
- feature gating
|
||||
- 前端按模块部署形态动态隐藏入口
|
||||
|
||||
---
|
||||
|
||||
### 风险 5:单数据库导致开发者随意跨模块查表
|
||||
|
||||
**风险**:虽然数据库未拆,但代码边界被绕开
|
||||
|
||||
**缓解**:
|
||||
- 表归属规则文档化
|
||||
- code review 要求说明跨模块访问理由
|
||||
- 逐步通过 query services 收口
|
||||
|
||||
---
|
||||
|
||||
### 风险 6:大爆炸式目录迁移导致 import churn
|
||||
|
||||
**风险**:一次性移动所有目录,修改面过大,回归成本高
|
||||
|
||||
**缓解**:
|
||||
- 分阶段迁移
|
||||
- 保留兼容 import 过渡层
|
||||
- 先稳定组合层与模型层,再做深层目录调整
|
||||
|
||||
---
|
||||
|
||||
## 13. 验证清单
|
||||
|
||||
### 13.1 结构验证
|
||||
|
||||
- `platform` 不 import 业务模块
|
||||
- `moldinsight` / `inventory` 无直接 api/services 互引
|
||||
- ORM 文件已按归属拆分,或至少表归属矩阵已文档化并被遵守
|
||||
|
||||
### 13.2 运行验证
|
||||
|
||||
#### unified
|
||||
- 两类路由都能正常挂载
|
||||
- 统一 health / auth / request-id 机制生效
|
||||
|
||||
#### gemold-only
|
||||
- inventory 路由未挂载
|
||||
- gemold 路由可用
|
||||
- RustFS / Celery 等专属依赖正常初始化
|
||||
|
||||
#### inventory-only
|
||||
- moldinsight 路由未挂载
|
||||
- inventory 路由可用
|
||||
- 不依赖 moldinsight 专属基础设施即可启动
|
||||
|
||||
### 13.3 数据验证
|
||||
|
||||
- 三种部署模式使用同一 migration head
|
||||
- 单数据库中的跨模块 FK 保持有效
|
||||
- Alembic 无分叉历史
|
||||
|
||||
### 13.4 前端验证
|
||||
|
||||
- unified 模式下,一个 base URL 即可跑通
|
||||
- split 模式下,各模块 base URL 可独立配置
|
||||
- 未部署模块能被隐藏或优雅失败
|
||||
|
||||
---
|
||||
|
||||
## 14. 文档联动更新计划
|
||||
|
||||
本蓝图批准后,以下文档应逐步对齐:
|
||||
|
||||
- [EVOLUTION_ROADMAP.md](./EVOLUTION_ROADMAP.md)
|
||||
- [LINUX_SETUP.md](./deployment/LINUX_SETUP.md)
|
||||
- [DEPLOY_PORT.md](./deployment/DEPLOY_PORT.md)
|
||||
- [PORT_CONFIG.md](./deployment/PORT_CONFIG.md)
|
||||
- [PORT_REFACTOR_SUMMARY.md](./deployment/PORT_REFACTOR_SUMMARY.md)
|
||||
- `README.md`
|
||||
- `frontend/README.md`
|
||||
|
||||
其中需要特别注意:
|
||||
|
||||
- `README.md` 当前仍主要描述旧单体结构,与当前实际代码已有明显漂移。
|
||||
- 本文档应作为“当前目标架构”的权威蓝图,路线图与部署文档随后对齐。
|
||||
|
||||
---
|
||||
|
||||
## 15. 附录:实施热点文件
|
||||
|
||||
以下文件是后续实际重构时最关键的热点:
|
||||
|
||||
### 平台与组合层
|
||||
- [app_factory.py](../src/shared/app_factory.py)
|
||||
- [settings.py](../src/shared/config/settings.py)
|
||||
- [database.py](../src/shared/database/database.py)
|
||||
- [init_db.py](../src/shared/database/init_db.py)
|
||||
- [moldinsight.py](../src/entrypoints/moldinsight.py)
|
||||
- [inventory.py](../src/entrypoints/inventory.py)
|
||||
- [main.py](../src/main.py)
|
||||
|
||||
### 模型与边界
|
||||
- [database.py](../src/shared/models/database.py)
|
||||
- [product_routes.py](../src/inventory/api/product_routes.py)
|
||||
|
||||
### gemold 模块
|
||||
- [moldinsight/api/__init__.py](../src/moldinsight/api/__init__.py)
|
||||
- [processing_service.py](../src/moldinsight/services/processing_service.py)
|
||||
- [task_query_service.py](../src/moldinsight/services/task_query_service.py)
|
||||
|
||||
### inventory 模块
|
||||
- [inventory/api/__init__.py](../src/inventory/api/__init__.py)
|
||||
- [inventory_service.py](../src/inventory/services/inventory_service.py)
|
||||
- [sales_order_service.py](../src/inventory/services/sales_order_service.py)
|
||||
- [purchase_order_service.py](../src/inventory/services/purchase_order_service.py)
|
||||
- [finance_service.py](../src/inventory/services/finance_service.py)
|
||||
|
||||
### 前端边界
|
||||
- [api-client.ts](../frontend/src/shared/api-client.ts)
|
||||
- [api.ts](../frontend/src/types/api.ts)
|
||||
|
||||
### 演进与部署参考
|
||||
- [EVOLUTION_ROADMAP.md](./EVOLUTION_ROADMAP.md)
|
||||
- [docker-compose.yml](../docker-compose.yml)
|
||||
|
||||
---
|
||||
|
||||
## 16. 最终结论
|
||||
|
||||
本项目当前最适合的演进路径不是微服务,而是:
|
||||
|
||||
> **单仓库 + 单数据库 + 多模块 + 可独立部署的 modular monolith**
|
||||
|
||||
它既能保留当前业务闭环(模具分析 → 成品 → BOM → 销售/采购/库存),又能逐步降低共享层和模型层的结构耦合。
|
||||
|
||||
后续实施时,应优先按以下顺序推进:
|
||||
|
||||
1. 固化组合层(deployment composition)
|
||||
2. 纯化 platform/shared 边界
|
||||
3. 拆分共享 ORM 文件
|
||||
4. 再继续模块内部细分层次
|
||||
5. 最后收口前端 API 与部署文档
|
||||
|
||||
这条路径风险最低、收益最大,也最符合当前代码现状与团队演进成本。
|
||||
@@ -1,390 +0,0 @@
|
||||
# 铝制家电包装泡沫模具分模功能开发检查清单
|
||||
|
||||
## 文档信息
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| **文档名称** | 铝制家电包装泡沫模具分模功能开发检查清单 |
|
||||
| **版本** | 1.0 |
|
||||
| **日期** | 2026-03-13 |
|
||||
| **项目** | geMoldInsight 模具分模功能增强 |
|
||||
|
||||
---
|
||||
|
||||
## 检查清单说明
|
||||
|
||||
本文档包含铝制家电包装泡沫模具分模功能开发的完整检查清单,用于跟踪开发进度和验收标准。
|
||||
|
||||
---
|
||||
|
||||
## 第一阶段:基础框架搭建
|
||||
|
||||
### 任务 1.1:创建铝泡沫模具参数类
|
||||
|
||||
- [ ] 创建 `AluminumFoamMoldParams` 数据类
|
||||
- [ ] 添加发泡倍率参数 (`expansion_ratio`)
|
||||
- [ ] 添加目标密度参数 (`target_density`)
|
||||
- [ ] 添加成型温度参数 (`molding_temp`)
|
||||
- [ ] 添加收缩率参数 (`shrinkage_rate`)
|
||||
- [ ] 实现参数验证方法
|
||||
- [ ] 设置合理的默认值
|
||||
|
||||
### 任务 1.2:创建铝泡沫材料数据库
|
||||
|
||||
- [ ] 创建 `FoamMaterialDatabase` 类
|
||||
- [ ] 添加 AlSi10Mg 材料数据
|
||||
- [ ] 添加 AlSi12 材料数据
|
||||
- [ ] 添加纯铝泡沫材料数据
|
||||
- [ ] 实现材料查询方法
|
||||
- [ ] 实现材料参数获取方法
|
||||
|
||||
### 任务 1.3:扩展现有模具生成器
|
||||
|
||||
- [ ] 修改 `MoldCavityGenerator` 构造函数
|
||||
- [ ] 添加铝泡沫参数支持
|
||||
- [ ] 添加 `set_foam_material()` 方法
|
||||
- [ ] 更新 `generate_mold_cavities()` 流程
|
||||
- [ ] 适配收缩补偿计算
|
||||
- [ ] 适配拔模角计算
|
||||
|
||||
### 任务 1.4:创建参数配置 API 接口
|
||||
|
||||
- [ ] 添加获取默认参数 API
|
||||
- [ ] 添加设置参数 API
|
||||
- [ ] 添加参数验证 API
|
||||
- [ ] 添加模板保存 API
|
||||
- [ ] 添加模板加载 API
|
||||
- [ ] 实现请求参数解析
|
||||
|
||||
### 任务 1.5:前端参数面板开发
|
||||
|
||||
- [ ] 创建参数配置组件
|
||||
- [ ] 添加分模参数输入控件
|
||||
- [ ] 添加铝泡沫参数输入控件
|
||||
- [ ] 添加拔模参数输入控件
|
||||
- [ ] 添加高级参数折叠面板
|
||||
- [ ] 实现参数提交功能
|
||||
- [ ] 实现参数加载功能
|
||||
|
||||
### 任务 1.6:参数模板功能
|
||||
|
||||
- [ ] 创建预设模板(快速模式)
|
||||
- [ ] 创建预设模板(经济模式)
|
||||
- [ ] 创建预设模板(高精度模式)
|
||||
- [ ] 实现模板保存功能
|
||||
- [ ] 实现模板加载功能
|
||||
- [ ] 实现模板列表功能
|
||||
|
||||
### 任务 1.7:参数验证逻辑
|
||||
|
||||
- [ ] 实现分型精度范围验证
|
||||
- [ ] 实现型腔匹配度验证
|
||||
- [ ] 实现拔模角范围验证
|
||||
- [ ] 实现收缩率范围验证
|
||||
- [ ] 实现温度范围验证
|
||||
- [ ] 返回详细错误信息
|
||||
|
||||
### 任务 1.8:阶段一集成测试
|
||||
|
||||
- [ ] 测试参数设置功能
|
||||
- [ ] 测试参数获取功能
|
||||
- [ ] 测试参数验证
|
||||
- [ ] 测试模板保存/加载
|
||||
- [ ] 测试前端参数面板
|
||||
- [ ] 测试 API 接口响应
|
||||
- [ ] 无阻塞性 bug
|
||||
|
||||
---
|
||||
|
||||
## 第二阶段:分模算法优化
|
||||
|
||||
### 任务 2.1:改进法向量分析算法
|
||||
|
||||
- [ ] 添加高斯权重计算
|
||||
- [ ] 实现多点采样
|
||||
- [ ] 优化主方向识别
|
||||
- [ ] 处理法向量突变
|
||||
- [ ] 测试复杂几何产品
|
||||
|
||||
### 任务 2.2:实现多分型面检测
|
||||
|
||||
- [ ] 设计多分型面数据结构
|
||||
- [ ] 实现分型面优先级排序
|
||||
- [ ] 实现分型面序列生成
|
||||
- [ ] 处理分型面交叠
|
||||
- [ ] 测试 2 分型面案例
|
||||
- [ ] 测试 3+ 分型面案例
|
||||
|
||||
### 任务 2.3:倒扣区域检测
|
||||
|
||||
- [ ] 分析产品几何特征
|
||||
- [ ] 实现倒扣识别算法
|
||||
- [ ] 标记倒扣位置
|
||||
- [ ] 生成倒扣报告
|
||||
- [ ] 提供处理建议
|
||||
|
||||
### 任务 2.4:改进拔模角计算
|
||||
|
||||
- [ ] 集成 BRepOffsetAPI_DraftAngle
|
||||
- [ ] 实现拔模方向检测
|
||||
- [ ] 实现拔模干涉检测
|
||||
- [ ] 处理拔模失败情况
|
||||
- [ ] 验证拔模后尺寸
|
||||
|
||||
### 任务 2.5:铝泡沫收缩补偿
|
||||
|
||||
- [ ] 基于发泡倍率计算收缩
|
||||
- [ ] 实现多向收缩
|
||||
- [ ] 补偿后尺寸验证
|
||||
- [ ] 处理不均匀收缩
|
||||
|
||||
### 任务 2.6:型腔分离优化
|
||||
|
||||
- [ ] 优化布尔运算参数
|
||||
- [ ] 处理复杂几何
|
||||
- [ ] 添加分离结果验证
|
||||
- [ ] 处理分离失败回退
|
||||
|
||||
### 任务 2.7:模具块生成
|
||||
|
||||
- [ ] 计算模具尺寸
|
||||
- [ ] 添加安全余量
|
||||
- [ ] 生成 A/B 板结构
|
||||
- [ ] 添加模架结构
|
||||
- [ ] 验证模具强度
|
||||
|
||||
### 任务 2.8:分型线平滑处理
|
||||
|
||||
- [ ] 实现 B 样条拟合
|
||||
- [ ] 处理尖角
|
||||
- [ ] 保持几何精度
|
||||
- [ ] 验证平滑效果
|
||||
|
||||
### 任务 2.9:算法性能优化
|
||||
|
||||
- [ ] 添加并行计算
|
||||
- [ ] 优化缓存策略
|
||||
- [ ] 性能测试 < 30 秒
|
||||
- [ ] 内存测试 < 1GB
|
||||
|
||||
### 任务 2.10:阶段二集成测试
|
||||
|
||||
- [ ] 测试典型产品分模
|
||||
- [ ] 测试复杂产品分模
|
||||
- [ ] 测试多分型面产品
|
||||
- [ ] 测试算法稳定性
|
||||
- [ ] 性能达标
|
||||
|
||||
---
|
||||
|
||||
## 第三阶段:质量检测模块
|
||||
|
||||
### 任务 3.1:创建质量检测器类
|
||||
|
||||
- [ ] 创建 `MoldQualityInspector` 类
|
||||
- [ ] 定义检测接口
|
||||
- [ ] 设计结果数据结构
|
||||
- [ ] 实现批量检测
|
||||
|
||||
### 任务 3.2:分模面平滑度检测
|
||||
|
||||
- [ ] 实现曲率分析
|
||||
- [ ] 实现凹凸检测
|
||||
- [ ] 计算平滑度评分
|
||||
- [ ] 标记问题区域
|
||||
|
||||
### 任务 3.3:分模面连续性检测
|
||||
|
||||
- [ ] 实现边界检查
|
||||
- [ ] 实现间隙检测
|
||||
- [ ] 实现完整性验证
|
||||
- [ ] 报告问题位置
|
||||
|
||||
### 任务 3.4:模具结构合理性检测
|
||||
|
||||
- [ ] 实现模具尺寸检查
|
||||
- [ ] 实现壁厚检查
|
||||
- [ ] 实现干涉检查
|
||||
- [ ] 生成改进建议
|
||||
|
||||
### 任务 3.5:生产可行性评估
|
||||
|
||||
- [ ] 计算注塑压力
|
||||
- [ ] 计算锁模力
|
||||
- [ ] 估算成型周期
|
||||
- [ ] 评估生产成本
|
||||
|
||||
### 任务 3.6:质量报告生成
|
||||
|
||||
- [ ] 汇总检测结果
|
||||
- [ ] 生成文字说明
|
||||
- [ ] 添加图表
|
||||
- [ ] 支持 PDF 导出
|
||||
- [ ] 报告格式规范
|
||||
|
||||
---
|
||||
|
||||
## 第四阶段:可视化和交互
|
||||
|
||||
### 任务 4.1:分型面可视化增强
|
||||
|
||||
- [ ] 设置分型面颜色
|
||||
- [ ] 调整透明度
|
||||
- [ ] 边缘高亮
|
||||
- [ ] 与产品对比度
|
||||
|
||||
### 任务 4.2:分型线可视化增强
|
||||
|
||||
- [ ] 设置线条颜色
|
||||
- [ ] 调整线条粗细
|
||||
- [ ] 添加端点标记
|
||||
- [ ] 动态绘制效果
|
||||
|
||||
### 任务 4.3:交互式分型面调整
|
||||
|
||||
- [ ] 实现鼠标拖拽
|
||||
- [ ] 实时更新模型
|
||||
- [ ] 实现撤销功能
|
||||
- [ ] 实现重做功能
|
||||
|
||||
### 任务 4.4:交互式参数调整
|
||||
|
||||
- [ ] 实现滑块实时更新
|
||||
- [ ] 参数变化动画
|
||||
- [ ] 效果对比视图
|
||||
|
||||
### 任务 4.5:剖视图功能
|
||||
|
||||
- [ ] 实现剖切算法
|
||||
- [ ] 显示内部结构
|
||||
- [ ] 剖面切换动画
|
||||
- [ ] 多方向剖视
|
||||
|
||||
### 任务 4.6:测量工具
|
||||
|
||||
- [ ] 实现距离测量
|
||||
- [ ] 实现角度测量
|
||||
- [ ] 测量结果标注
|
||||
- [ ] 测量精度验证
|
||||
|
||||
### 任务 4.7:视角控制增强
|
||||
|
||||
- [ ] 添加预设视角
|
||||
- [ ] 实现动画过渡
|
||||
- [ ] 实现自动对准
|
||||
|
||||
### 任务 4.8:导出视图功能
|
||||
|
||||
- [ ] 实现 PNG 导出
|
||||
- [ ] 支持高清截图
|
||||
- [ ] 批量导出支持
|
||||
|
||||
---
|
||||
|
||||
## 第五阶段:数据接口和测试
|
||||
|
||||
### 任务 5.1:STEP 导出接口
|
||||
|
||||
- [ ] 实现 STEP 导出
|
||||
- [ ] 验证导出文件
|
||||
- [ ] 测试 CAD 兼容性
|
||||
|
||||
### 任务 5.2:JSON 数据导出
|
||||
|
||||
- [ ] 实现 JSON 导出
|
||||
- [ ] 包含完整参数
|
||||
- [ ] 包含几何数据
|
||||
- [ ] 包含质量报告
|
||||
|
||||
### 任务 5.3:PDF 报告导出
|
||||
|
||||
- [ ] 实现 PDF 生成
|
||||
- [ ] 添加质量报告内容
|
||||
- [ ] 添加图表
|
||||
- [ ] 格式规范美观
|
||||
|
||||
### 任务 5.4:IGES 格式支持
|
||||
|
||||
- [ ] 实现 IGES 导入
|
||||
- [ ] 实现 IGES 导出
|
||||
- [ ] 验证 CAM 兼容性
|
||||
|
||||
### 任务 5.5:集成测试
|
||||
|
||||
- [ ] 功能测试通过
|
||||
- [ ] 性能测试通过
|
||||
- [ ] 兼容性测试通过
|
||||
- [ ] 压力测试通过
|
||||
|
||||
### 任务 5.6:用户验收测试
|
||||
|
||||
- [ ] 功能演示完成
|
||||
- [ ] 用户反馈收集
|
||||
- [ ] 问题修复完成
|
||||
- [ ] 用户验收签字
|
||||
|
||||
---
|
||||
|
||||
## 功能验收检查表
|
||||
|
||||
### 核心功能
|
||||
|
||||
- [ ] 自动分模算法正常运行
|
||||
- [ ] 分型面检测准确
|
||||
- [ ] 分型线计算正确
|
||||
- [ ] 拔模角处理正确
|
||||
- [ ] 收缩补偿正确
|
||||
|
||||
### 参数系统
|
||||
|
||||
- [ ] 所有参数可配置
|
||||
- [ ] 参数验证正确
|
||||
- [ ] 参数模板可用
|
||||
- [ ] 参数保存成功
|
||||
|
||||
### 可视化
|
||||
|
||||
- [ ] 3D 模型正确显示
|
||||
- [ ] 分型面可视化
|
||||
- [ ] 分型线可视化
|
||||
- [ ] 型腔/型芯可视化
|
||||
- [ ] 交互操作流畅
|
||||
|
||||
### 质量检测
|
||||
|
||||
- [ ] 平滑度检测正常
|
||||
- [ ] 连续性检测正常
|
||||
- [ ] 结构检测正常
|
||||
- [ ] 可行性评估正常
|
||||
- [ ] 报告生成正常
|
||||
|
||||
### 数据接口
|
||||
|
||||
- [ ] STEP 导出正常
|
||||
- [ ] JSON 导出正常
|
||||
- [ ] PDF 导出正常
|
||||
- [ ] IGES 导出正常
|
||||
|
||||
---
|
||||
|
||||
## 性能验收检查表
|
||||
|
||||
- [ ] 分模时间 < 30 秒
|
||||
- [ ] 渲染帧率 > 30 FPS
|
||||
- [ ] 内存占用 < 2 GB
|
||||
- [ ] 支持 5 用户并发
|
||||
|
||||
---
|
||||
|
||||
## 代码质量检查表
|
||||
|
||||
- [ ] 代码符合 PEP 8 规范
|
||||
- [ ] 包含类型注解
|
||||
- [ ] 包含文档字符串
|
||||
- [ ] 单元测试覆盖
|
||||
- [ ] 无安全漏洞
|
||||
- [ ] 无硬编码密码
|
||||
|
||||
---
|
||||
|
||||
**文档结束**
|
||||
@@ -1,37 +0,0 @@
|
||||
# 交付物清单(本次产出)
|
||||
|
||||
## 1. 分析报告(Markdown)
|
||||
|
||||
- `docs/MOLD_ERP_ANALYSIS_REPORT.md`
|
||||
- `docs/ZERO_FINISHED_INVENTORY_CERTIFICATE.md`
|
||||
- `docs/PERFORMANCE_SCALABILITY_PLAN.md`
|
||||
- `docs/PERFORMANCE_BENCHMARKS.md`
|
||||
- `docs/UAT_CHECKLIST.md`
|
||||
- `docs/INTERFACE_INTEGRATION_CATALOG_TEMPLATE.md`
|
||||
- `docs/CONFLUENCE_ARCHIVE_STRUCTURE.md`
|
||||
|
||||
## 2. 数据库脚本(PostgreSQL)
|
||||
|
||||
- 冻结交付后模具订单(头+明细):`scripts/db/001_freeze_delivered_sales_orders.sql`
|
||||
- 约束与索引补齐:`scripts/db/002_indexes_and_constraints.sql`
|
||||
- 数据修复示例(状态归一):`scripts/db/003_data_fixups.sql`
|
||||
- 分区模板(按月):`scripts/db/010_partitioning_template.sql`
|
||||
- RLS 模板(按 org_id):`scripts/db/011_rls_template.sql`
|
||||
- 审计追溯(old/new + 操作者/IP/UA):`scripts/db/020_audit_trail.sql`
|
||||
- 审计留存清理(180 天):`scripts/db/021_audit_retention.sql`
|
||||
- 慢 SQL 采样(pg_stat_statements):`scripts/db/030_pg_stat_statements.sql`
|
||||
|
||||
## 3. 自动化测试(pytest)
|
||||
|
||||
- 交付后冻结:`tests/test_sales_order_delivered_freeze.py`
|
||||
- 订单/采购/库存主链路用例(参数化 ≥30):`tests/test_api_inventory_orders.py`
|
||||
|
||||
## 4. 代码加固点(已落地)
|
||||
|
||||
- 交付后冻结:应用层拒绝更新/删除/改状态/领料(`status=delivered`)。
|
||||
- 状态一致性:避免写入未允许的 `pending` 状态。
|
||||
- 性能优化:BOM 需求计算去 N+1;库存扣减使用原子更新降低并发超卖风险。
|
||||
|
||||
## 5. Word + PDF 导出建议
|
||||
|
||||
- 建议使用 pandoc 将 `docs/MOLD_ERP_ANALYSIS_REPORT.md` 导出为 docx/pdf,并将生成物作为 CI 产物归档。
|
||||
@@ -0,0 +1,117 @@
|
||||
# geMoldInsight 部署总览(DEPLOYMENT)
|
||||
|
||||
> 文档定位:**唯一的部署主题入口文档**。
|
||||
> 本文负责说明当前推荐部署模式、部署文档分工与历史文档去向;不承担全部 Linux 操作细节。详细 Linux 部署步骤见 [deployment/LINUX_SETUP.md](deployment/LINUX_SETUP.md),当前状态见 [STATUS.md](STATUS.md),架构边界见 [ARCHITECTURE.md](ARCHITECTURE.md)。
|
||||
|
||||
---
|
||||
|
||||
## 1. 当前推荐部署模式
|
||||
|
||||
当前推荐模式为:
|
||||
|
||||
- **unified**:frontend + unified backend + moldinsight celery
|
||||
|
||||
原因:
|
||||
- 适合本地开发与集成环境
|
||||
- 前端同域反代可以面对单一 backend
|
||||
- 比按路径把前端网关分流到两套后端更易维护
|
||||
|
||||
当前 Compose 入口:
|
||||
- [docker-compose.yml](../docker-compose.yml)
|
||||
|
||||
详细 Linux 部署步骤:
|
||||
- [deployment/LINUX_SETUP.md](deployment/LINUX_SETUP.md)
|
||||
|
||||
---
|
||||
|
||||
## 2. 支持的部署模式
|
||||
|
||||
### 2.1 unified
|
||||
|
||||
一个统一后端同时挂载 moldinsight + inventory。
|
||||
|
||||
适合:
|
||||
- 本地开发
|
||||
- 测试/集成环境
|
||||
- 小团队统一部署
|
||||
|
||||
### 2.2 moldinsight-only
|
||||
|
||||
只部署模具分析后端。
|
||||
|
||||
适合:
|
||||
- 独立开放分析能力
|
||||
- 异步任务与文件处理独立扩容
|
||||
|
||||
### 2.3 inventory-only
|
||||
|
||||
只部署进销存后端。
|
||||
|
||||
适合:
|
||||
- 独立部署 ERP / 库存能力
|
||||
- 与 moldinsight 分开发布节奏
|
||||
|
||||
部署模式的结构含义见 [ARCHITECTURE.md](ARCHITECTURE.md)。
|
||||
|
||||
---
|
||||
|
||||
## 3. 部署文档分工
|
||||
|
||||
### 3.1 当前权威文档
|
||||
|
||||
- [DEPLOYMENT.md](DEPLOYMENT.md)
|
||||
- 部署入口与文档导航
|
||||
- [deployment/LINUX_SETUP.md](deployment/LINUX_SETUP.md)
|
||||
- Linux 环境下的详细部署操作说明
|
||||
|
||||
### 3.2 端口与配置说明
|
||||
|
||||
以下文档当前仍保留,但后续会继续收敛:
|
||||
- [deployment/DEPLOY_PORT.md](deployment/DEPLOY_PORT.md)
|
||||
- [deployment/PORT_CONFIG.md](deployment/PORT_CONFIG.md)
|
||||
|
||||
它们描述的是端口与环境配置细节,不应替代部署入口文档。
|
||||
|
||||
### 3.3 历史/阶段性部署材料
|
||||
|
||||
以下材料属于迁移期或历史说明,不应再视为当前部署权威:
|
||||
- [archive/PORT_REFACTOR_SUMMARY.md](archive/PORT_REFACTOR_SUMMARY.md)
|
||||
- [archive/FRONTEND_UNIFIED_DEPLOYMENT_PLAN.md](archive/FRONTEND_UNIFIED_DEPLOYMENT_PLAN.md)
|
||||
|
||||
这些材料已迁入 `docs/archive/`。
|
||||
|
||||
---
|
||||
|
||||
## 4. 当前部署事实
|
||||
|
||||
当前部署上的几个关键事实:
|
||||
|
||||
- 项目保持单仓库、单数据库
|
||||
- frontend 是独立前端工程
|
||||
- 后端支持模块化入口
|
||||
- moldinsight 的异步分析链路依赖 celery
|
||||
- PostgreSQL / Redis / 对象存储通常复用服务器已有服务,而不是必须由项目 compose 自带
|
||||
|
||||
这些事实的当前版本以 [STATUS.md](STATUS.md) 和 [deployment/LINUX_SETUP.md](deployment/LINUX_SETUP.md) 为准。
|
||||
|
||||
---
|
||||
|
||||
## 5. 相关专题文档
|
||||
|
||||
以下文档可作为部署/存储方向的补充参考,但不替代部署入口文档:
|
||||
|
||||
- [deployment/DEPLOY_PORT.md](deployment/DEPLOY_PORT.md)
|
||||
- [deployment/PORT_CONFIG.md](deployment/PORT_CONFIG.md)
|
||||
- [topics/storage/RUSTFS_STORAGE.md](topics/storage/RUSTFS_STORAGE.md)
|
||||
- [topics/storage/STORAGE_SETUP.md](topics/storage/STORAGE_SETUP.md)
|
||||
|
||||
---
|
||||
|
||||
## 6. 后续整理原则
|
||||
|
||||
部署文档后续将遵循以下规则:
|
||||
|
||||
- 部署入口信息只在本文维护
|
||||
- 操作步骤只在 [deployment/LINUX_SETUP.md](deployment/LINUX_SETUP.md) 维护
|
||||
- 历史迁移说明与阶段计划迁入 `docs/archive/`
|
||||
- README 只保留最短启动说明,不再承担部署手册职责
|
||||
@@ -1,258 +0,0 @@
|
||||
# geMoldInsight 演进路线图
|
||||
|
||||
> 本文档是代码与功能演进的执行清单,基于 2026-07-13 的全量代码体检。每项含「现象 / 证据 / 修法 / 验证」,按 P0→P3 推进,完成后勾选。
|
||||
|
||||
## 诊断
|
||||
|
||||
代码已演进到「双应用模块化」形态(`entrypoints/` + `moldinsight/` + `inventory/` + `shared/`),但有 **三处结构性缺失** 让快速迭代变贵,外加 **一批静默 bug** 正在让功能"看起来在跑其实没跑":
|
||||
|
||||
- **缺中间层**:业务逻辑堆在路由/编排函数里(进销存无 service 层、`process_file_core` 280 行线性函数)
|
||||
- **缺契约**:前后端靠手写类型,字段已大面积漂移(财务页整页是 0)
|
||||
- **缺连接**:模具分析与进销存是两个孤立产品(`STPFile` 没有 `product_id`)
|
||||
|
||||
---
|
||||
|
||||
## P0 止血:正在静默失效的功能(1–2 周)
|
||||
|
||||
这些不是技术债,是**现在就在坏**的东西,先修。
|
||||
|
||||
### P0-1 Celery worker 不连 Redis/RustFS,异步任务全坏
|
||||
- **现象**:任务进度写进 Celery 私有内存,web 端永远读不到;首次上传 RustFS 直接抛 `RuntimeError("RustFS 未连接")`。
|
||||
- **证据**:`redis_task_manager.connect()` / `rustfs_manager.connect()` 只在 FastAPI startup 调用(`entrypoints/moldinsight.py:42,48`),Celery 进程不跑 startup;`processing_service.py` 在 celery 内调 `update_task` 时 `is_connected=False` 走 `_fallback_set`;`rustfs_storage.py:125-126` 未连接直接抛错。`docker-compose.yml` 的 `moldinsight-celery` 服务块缺 `REDIS_PASSWORD`。
|
||||
- **修法**:`celery_tasks.py` 加 `@worker_process_init` 信号,显式 `connect()` redis 与 rustfs;补齐 celery 服务的 `REDIS_PASSWORD`/`SECRET_KEY` 等环境变量,与主应用对齐。
|
||||
- **验证**:上传一个 STP,Celery 路径下任务进度能从 web 端 `/api/status/{task_id}` 读到;上传后 RustFS 中能看到对象。
|
||||
- **状态**:- [ ]
|
||||
|
||||
### P0-2 LLM 设计报告 NameError,静默失效
|
||||
- **现象**:`LLM_ENABLED=true` 时设计报告功能直接没有。
|
||||
- **证据**:`llm_service.py:339` 用未定义变量 `trimmed`(应为 `features`,`trimmed` 只在 `_build_side_action_prompt` 中定义),外层 `try/except` 吞掉 `NameError` 返回 `None`。
|
||||
- **修法**:`trimmed` -> `features`。
|
||||
- **验证**:启用 LLM 后设计报告字段非空。
|
||||
- **状态**:- [ ]
|
||||
|
||||
### P0-3 前端财务页全字段错配
|
||||
- **现象**:FinanceTab 整页 0/空;用户管理菜单永不显示(`is_superuser` 后端不返回);dashboard 成品数恒 0。
|
||||
- **证据**:16 处字段名对不上,如 `total_receivable` vs `receivable_total`(`finance_schemas.py:66`)、`order_no` vs `txn_no`(`finance_schemas.py:48`)等;`App.vue:91` 读 `is_superuser` 但 `UserResponse` 无此字段。
|
||||
- **修法**:短期按映射手改前端字段;长期靠 P1-3 OpenAPI 契约生成根治。
|
||||
- **验证**:财务页卡片与表格显示真实数据;用户管理菜单对管理员可见。
|
||||
- **状态**:- [ ]
|
||||
|
||||
### P0-4 OCC 线程安全自相矛盾
|
||||
- **现象**:偶发崩溃,外层 `max_workers=1` 保护形同虚设。
|
||||
- **证据**:`processing_service.py:50-51` 用单线程池序列化 OCC,但 `geometry_analyzer._detect_features`(`geometry_analyzer.py:81`)内部又开 `ThreadPoolExecutor(max_workers=4)` 并行操作 OCC `TopoDS_Shape`。
|
||||
- **修法**:特征检测器改串行;或预处理阶段把面特征抽成纯数值,检测器只处理数值不碰 OCC。
|
||||
- **验证**:压测大模型反复分析无崩溃。
|
||||
- **状态**:- [ ]
|
||||
|
||||
### P0-5 `.env` 进了 git 历史,真实密钥泄露
|
||||
- **现象**:DB/Redis/SECRET_KEY/LLM key 已进入仓库历史。
|
||||
- **证据**:`git ls-files --error-unmatch .env` 命中;`git log -- .env` 有 10+ 次提交;`.env` 内含真实凭据。
|
||||
- **修法**:`git rm --cached .env`(停止跟踪,保留本地,后续不再提交);`SECRET_KEY` 从默认占位符轮换为强随机值。
|
||||
- **用户决策(2026-07-13)**:私有仓库,不轮换其他密钥、不重写 git 历史。
|
||||
- **验证**:`git status` 显示 `.env` 不再被跟踪(`D .env`)。
|
||||
- **状态**:- [x]
|
||||
|
||||
### P0-6 铝价路由模块化部署后丢失
|
||||
- **现象**:模块化部署后 `/api/aluminum-price/*` 直接 404。
|
||||
- **证据**:单体 `main.py:47,155` 挂了 `aluminum_price_router`,但 `moldinsight/api/__init__.py` 的 `_safe_include` 列表不含 `aluminum_price_routes`。
|
||||
- **修法**:把 `aluminum_price_routes` 加入 `_safe_include`。
|
||||
- **验证**:模块化部署下 `/api/aluminum-price/*` 可访问。
|
||||
- **状态**:- [ ]
|
||||
|
||||
### P0-7 导出缓存无持久化回退
|
||||
- **现象**:多 worker 或重启后导出返回 409。
|
||||
- **证据**:`processing_service._export_shapes_cache` 是进程内 dict,`get_export_shapes` 只查内存;`_persist_step_exports` 已写磁盘 manifest 但无回读逻辑。
|
||||
- **修法**:`get_export_shapes` 缓存未命中时从磁盘 manifest 回读。
|
||||
- **验证**:重启后导出仍可用。
|
||||
- **状态**:- [ ]
|
||||
|
||||
---
|
||||
|
||||
### P0 执行结果(2026-07-13)
|
||||
|
||||
- ✅ **P0-1 Celery 连接**:`celery_tasks.py` 在任务内显式 `redis_task_manager.reconnect()` + `rustfs_manager.connect()`(Redis 客户端绑定事件循环,每任务 reconnect;RustFS 同步客户端连一次复用);`docker-compose.yml` celery 服务补 `REDIS_PASSWORD`/`RUSTFS_TIMEOUT`
|
||||
- ✅ **P0-2 LLM NameError**:`llm_service.py:339` `trimmed` -> `features`
|
||||
- ✅ **P0-3 前端字段错配**:FinanceTab 全字段对齐 schema(summary/statement/product-statement/transaction 共 16 处);`UserResponse` 加 `is_superuser` + 统一 `_build_user_response` 构造(修用户管理菜单不显示);DashboardTab `product_count`->`finished_product_count`;PurchaseOrdersTab `received_at/paid_at`->`received_date/paid_date`;后端 `FinanceTransactionResponse` 补 `partner_name` 并批量查询客户/供应商名称
|
||||
- ✅ **P0-4 OCC 线程安全**:`geometry_analyzer._detect_features` `max_workers` 4->1
|
||||
- ✅ **P0-5 .env 泄露**:`git rm --cached .env` 已取消跟踪(后续不再提交);`SECRET_KEY` 从默认占位符轮换为强随机值(现有登录 token 失效)。用户决策:私有仓库,不轮换其他密钥、不重写 git 历史
|
||||
- ✅ **P0-6 铝价路由**:`moldinsight/api/__init__.py` `_safe_include` 加入 `aluminum_price_routes`
|
||||
- ℹ️ **P0-7 导出缓存**:经排查**非 bug**——`export_artifacts` 已写 PG+Redis(`processing_service.py:342,361`),导出端点先走 `_select_persisted_files` 从 task_data 读取(`advanced_router.py:436`),重启后正常工作;409 仅在持久化也失败时出现,"请重新分析"提示为正确行为。内存 re-export 缓存的可靠性优化归入 P1-2
|
||||
|
||||
**未做验证**:前端未跑 vue-tsc 构建(字段重命名属机械改动,低风险);后端未跑 pytest(需 DB/Redis 环境)。建议下次在完整环境验证。
|
||||
|
||||
---
|
||||
|
||||
## P1 结构性地基:让后续迭代不再昂贵(持续)
|
||||
|
||||
### P1-1 进销存抽 service 层
|
||||
- **现状**:`finance_routes.py` 751 行、`sales_order_routes.py` 777 行,事务编排/库存原子更新/流水写入全耦合在 endpoint;`shared/services/` 仅 auth+redis。
|
||||
- **目标**:新建 `inventory/services/`,`PurchaseOrderService.receive()`、`SalesOrderService.issue_materials()`、`FinanceService.settle()`,route 只做校验+组装。
|
||||
- **状态**:- [ ]
|
||||
|
||||
### P1-2 moldinsight 可插拔注册表 + Stage 流水线
|
||||
- **现状**:模具类型硬编码 if-else(`multi_scheme_planner.py:40`);特征检测器硬编码 6 个(`geometry_analyzer.py:76-99`);`process_file_core` 280 行。
|
||||
- **目标**:`FeatureDetectorRegistry` + `MoldGeneratorRegistry`(`@register` 装饰器);`process_file_core` 拆成 Stage 链。
|
||||
- **解锁**:新增模具类型、IGES/BREP、批量分析。
|
||||
- **进展(2026-07-15)**:✅ `MoldGeneratorRegistry`(消除 `multi_scheme_planner` if-else,新增模具类型只需 `register`)+ ✅ `FeatureDetectorRegistry`(消除 6 个检测器硬编码,新增检测器只需 `register`)+ 顺带移除 OCC 线程池改用注册表串行执行;⏳ Stage 流水线**暂缓**--`process_file_core`(278 行/10 stage/~20 跨 stage 变量)是 STP 处理核心,本环境无 OCC 无法运行时验证,盲改风险高。建议在有 OCC 的环境按现有 `_step_*` 模式增量抽取 inline stages(parse_stp / build_plan_result / generate_visualization / analyze_design / generate_llm_report / finalize)
|
||||
- **状态**:- [~](2/3:两个注册表完成,Stage 流水线暂缓)
|
||||
|
||||
### P1-3 前端 OpenAPI 契约生成
|
||||
- **现状**:前端 40+ 处 `any`,字段全手写已大面积错配。
|
||||
- **目标**:`openapi-typescript` 从 `/openapi.json` 生成 TS 类型替换 `any`;`api.ts` 加 baseURL/拦截器/超时,按域封装 `inventoryApi`/`moldinsightApi`/`authApi`。
|
||||
- **状态**:- [x](见 P4-1)
|
||||
|
||||
### P1-4 引入 Alembic,废除裸 DDL
|
||||
- **现状**:无 `alembic.ini`;`init_db.py` 22 条 `ALTER TABLE ADD COLUMN IF NOT EXISTS`,无版本/无回滚;`migrate_db.py` 是 `drop_all` 破坏性脚本;两应用 startup 并发跑 DDL 争锁。
|
||||
- **目标**:`alembic init`,固化版本化迁移,启动只 `upgrade head`;删 `migrate_db.py`。
|
||||
- **状态**:- [x]
|
||||
|
||||
### P1-5 统一材料属性源
|
||||
- **现状**:材料字典在 4 处重复定义且冲突(PE 收缩率 `material_service` 0.020 vs `aluminum_foam_mold.py:92` 0.025)。
|
||||
- **目标**:`MaterialService` 作为唯一源,其他模块查询。
|
||||
- **状态**:- [x]
|
||||
|
||||
---
|
||||
|
||||
### P1 执行结果(核心完成)
|
||||
|
||||
- ✅ **P1-1 进销存抽 service 层**(核心完成):
|
||||
- 建立 `inventory/services/` 层,抽出 5 个 service:FinanceService / SalesOrderService / PurchaseOrderService / StockMovementService / InventoryService
|
||||
- 路由全面瘦身:finance 767->123、sales_order 777->114、purchase_order 472->90、stock_movement 209->37、inventory 205->57
|
||||
- 将 schemas/ 与 utils.py 从 inventory/api/ 移至 inventory/ 顶层,打破 service<->api 循环导入(正确分层);清理死代码 api/utils.py
|
||||
- ✅ 全量 import 测试通过:55 inventory 路由无丢失,5 个 service 全部正常加载
|
||||
- ⏳ 可选后续:剩余纯 CRUD 路由(product/supplier/customer/warehouse/material/dashboard)体量小,可按需增量抽取
|
||||
- ✅ **P1-5 统一材料属性源**:`MaterialService` 成为唯一源,删除 geometry_analyzer/mold_generator/aluminum_foam_mold 三处重复字典,改查询 MaterialService;解决冲突(PE 收缩率统一 0.020、PC/PA/PMMA 收缩率、POM 密度统一)、补齐 PS、统一泡沫 `shrinkage` 键名、补 `min_wall`/泡沫字段;py_compile + 一致性核对通过
|
||||
- ✅ **P1-4 引入 Alembic**:`alembic init` + 配置 env.py(接 settings+models metadata);补 3 个 CheckConstraint 到 models;离线生成初始迁移(31 表+约束+95 索引,全 sa.* 通用类型);`init_db.py` 用 `_run_alembic_migrations`(自动基线+upgrade head)替换 `create_tables`+`ensure_schema_updates`(删 92 行裸 DDL);删破坏性 `migrate_db.py`。**既有 DB 自动 stamp 基线**(无需手动);全新部署建议先 `alembic upgrade head` 再启应用
|
||||
- ✅ **P1-2 可插拔注册表**(Stage 流水线暂缓):新增 `MoldGeneratorRegistry`(`multi_scheme_planner` 消除 if-else,按 mold_type 选生成器)+ `FeatureDetectorRegistry`(`geometry_analyzer._detect_features` 消除 6 个检测器硬编码,改遍历注册表);新增模具类型/特征检测器只需 `register` 一行;顺带移除 OCC 线程池改串行。Stage 流水线(process_file_core 拆分)因无 OCC 运行环境暂缓,文档留计划
|
||||
|
||||
---
|
||||
|
||||
## P2 功能演进:把两个产品变成一个
|
||||
|
||||
### P2-1 打通模具分析 -> 进销存(最高产品价值)
|
||||
- **现状**:`STPFile` 无 `product_id`,moldinsight 与 inventory 零数据关联。
|
||||
- **目标**:`STPFile` 加 `product_id` 外键(可空),分析完成后一键创建 `Product(finished)` 并回写。
|
||||
- **状态**:- [x]
|
||||
|
||||
### P2-2 真 AI 落地,砍掉假 AI
|
||||
- **现状**:`ai_mold_assistant.py` 209 行纯 stub 从未被调用;`ai_parting_detector.py` GNN 框架完整但无权重;`llm_service` 是唯一真接 AI(且有 P0-2 bug)。
|
||||
- **目标**:聚焦一个能跑通的 AI 能力(LLM 扩到成本估算/工艺对话);GNN 要么真训权重,要么移除 stub。
|
||||
- **进展(2026-07-27)**:✅ `ai_mold_assistant.py` stub 已删除(P3-3 死代码清理);✅ LLM 成本估算已落地(`llm_service.estimate_cost` + `POST /api/cost-estimate`);✅ 规则式兜底(`cost_estimate_service.py`,LLM 未启用时自动降级);⏳ GNN `ai_parting_detector.py` 仍无权重,待决策保留或移除
|
||||
- **状态**:- [~](成本估算完成,GNN 待决策)
|
||||
|
||||
### P2-3 模具成本估算 + 批量分析
|
||||
- 依赖 P1-2 完成后才有性价比。
|
||||
- **进展(2026-07-27)**:
|
||||
- ✅ **P2-3a 前端成本估算 UI**:ResultView 新增「💰 成本估算」按钮 + 锚点导航 + 成本卡片(模具造价/单件成本/估算假设/置信度)
|
||||
- ✅ **P2-3b 规则式兜底**:`cost_estimate_service.py`(模具钢材料单价表 + 加工复杂度系数 + 侧向机构附加费),LLM 未启用时 `advanced_router` 自动调用规则引擎
|
||||
- ✅ **P2-3c 批量上传后端**:`batch_router.py`(多文件 `POST /api/batch-upload` + Redis batch_id→task_ids 映射 24h TTL + `GET /api/batch/{batch_id}` 聚合查询),复用现有 `processing_service` + Celery 并发
|
||||
- ✅ **P2-3d 批量前端 UI**:`BatchView.vue`(拖拽多文件上传 + 进度看板 + 轮询 + 任务表格),MoldInsightView 入口按钮
|
||||
- **状态**:- [x]
|
||||
|
||||
### P2 执行结果
|
||||
|
||||
- ✅ **P2-1 打通模具分析 -> 进销存**:`STPFile` 加 `product_id` 外键(nullable+index+FK)+ Alembic 迁移 `006c18c51b0d`(首次真实迁移);inventory `POST /api/products/from-task/{task_id}` 端点(按 task_id 查 STPFile,幂等创建 `Product(finished)`,回写 product_id,SKU=`MI{stp_file_id}`,描述含体积/重量/表面积);前端 ResultView 导出栏加「创建为成品」按钮。py_compile + alembic heads + vue-tsc 0 错误通过。**模具分析 -> 成品 -> BOM -> 销售/采购的业务闭环接通**
|
||||
- ✅ **P2-2 真 AI 落地(部分)**:删除 `ai_mold_assistant.py` 死代码;LLM 成本估算 + 规则兜底双路径已上线
|
||||
- ✅ **P2-3 成本估算 + 批量分析(全部完成)**:前端成本卡片 + 规则式兜底 + 批量上传后端 + 批量进度看板
|
||||
|
||||
---
|
||||
|
||||
## P3 工程治理(穿插顺手做)
|
||||
|
||||
- [x] `create_app()` 工厂消除两入口重复引导,废弃单体 `main.py` → `shared/app_factory.py`(2026-07-27)
|
||||
- [x] 删死依赖/死代码:Kafka 依赖删除、`templates/` 三个 legacy Jinja 模板删除、`task_router` result_page 死端点删除、`ProcessingService.__init__` 3 个死实例删除(2026-07-27)
|
||||
- [x] `get_db_session` 统一事务边界(成功 commit / 异常 rollback),inventory 路由 commit→flush(2026-07-27)
|
||||
- [x] 连接池治理:web `pool_size=10, max_overflow=20` / celery `pool_size=5, max_overflow=10`,环境变量可覆盖(2026-07-27)
|
||||
- [x] 进销存 state 从模块级单例迁回 Pinia `defineStore`,tab 改子路由(URL 可分享/回退)(2026-07-27)
|
||||
- [x] 统一 `/health` 响应 schema(status/service/version/database_connected);SPA fallback 排除 `/api`、`/docs`、`/openapi` 前缀(2026-07-27)
|
||||
- [x] CORS 收敛:`CORS_ORIGINS` 环境变量白名单,空则降级 `["*"]` + 警告日志(2026-07-27)
|
||||
|
||||
### P3 执行结果(全部完成,2026-07-27)
|
||||
|
||||
- ✅ **P3-1 CORS 收敛**:`settings.py` 新增 `CORS_ORIGINS` 解析;`app_factory.py` 从白名单创建 CORS,空则 `["*"]` + warning
|
||||
- ✅ **P3-2 /health + SPA fallback**:`app_factory.py` 统一 GET+POST /health(含 database_connected 检测);catch-all 排除 `api/`/`docs`/`openapi` 前缀
|
||||
- ✅ **P3-3 删除死代码**:`requirements.txt` + `deploy/requirements-moldinsight.txt` 删 `kafka-python`;删除 `templates/*.html` 三个 legacy 模板;`task_router.py` 删 `result_page` 端点;`processing_service.py` 删 3 个死实例 + 死 import
|
||||
- ✅ **P3-4 事务边界**:`database.py` 的 `get_db_session` 统一 commit/rollback;inventory 5 个路由共 25 处 `commit()` → `flush()`
|
||||
- ✅ **P3-5 连接池**:`database.py` 按角色分层 `_get_pool_config()`,web/celery 分别配置;`celery_tasks.py` 初始化 celery 角色引擎
|
||||
- ✅ **P3-6 app_factory**:新建 `shared/app_factory.py`(CORS/日志中间件/静态文件/startup/shutdown/health/SPA fallback);两入口各 ~30 行
|
||||
- ✅ **P3-7 Pinia + 子路由**:新建 `stores/inventory.ts`(defineStore);`useInventory.ts` 改为薄壳委托;10 个 Tab 子路由懒加载;Sidebar 改 `router.push`
|
||||
|
||||
---
|
||||
|
||||
## 执行进度
|
||||
|
||||
| 阶段 | 项数 | 已完成 | 进行中 |
|
||||
|------|------|--------|--------|
|
||||
| P0 | 7 | 6 修复 + 1 排查 | - |
|
||||
| P1 | 5 | 5 | P1-1~P1-5 全部完成(P1-2 Stage 流水线暂缓) |
|
||||
| P2 | 3 | 3 | P2-1+P2-2(部分)+P2-3 全部完成 |
|
||||
| P3 | 7 | 7 | 全部完成 |
|
||||
| P4 | 10 | 4 | P4-1 OpenAPI 契约 + P4-4 采购需求推导 + P4-6 集成测试 + P4-7 结构化日志 |
|
||||
|
||||
---
|
||||
|
||||
## P4 后续演进方向(待规划)
|
||||
|
||||
### 方向 A:前端工程化加固(低风险、高收益)
|
||||
|
||||
#### P4-1 OpenAPI 契约自动生成 ✅
|
||||
- **现状**:前端 `any` 泛滥,字段靠手写已多次错配(P0-3 教训)
|
||||
- **目标**:`openapi-typescript` 从 `/openapi.json` 生成 TS interface,替换 `types/schemas.ts` 中的 `any`;`api.ts` 按域封装 `inventoryApi` / `moldinsightApi` / `authApi`
|
||||
- **体量**:~1 天
|
||||
- **完成(2026-07-27)**:`openapi.json` 双服务统一(70 paths / 76 schemas);`types/api.ts` 自动生成(5500+ 行);`api-client.ts` 按域封装(authApi/inventoryApi/moldinsightApi);`stores/inventory.ts` 核心 ref 加 `Schema<>` 类型标注
|
||||
|
||||
#### P4-2 Stage 流水线拆分
|
||||
- **现状**:`process_file_core` 278 行线性函数,新增分析阶段需改核心函数
|
||||
- **目标**:拆成 Stage 链(parse_stp → detect_features → plan_mold → generate_visualization → analyze_design → generate_report → finalize),每个 Stage 可独立测试和替换
|
||||
- **前提**:需在有 OCC 的环境下运行时验证
|
||||
- **体量**:~2-3 天
|
||||
|
||||
### 方向 B:业务闭环深化
|
||||
|
||||
#### P4-3 模具分析报告 → 销售订单关联
|
||||
- **现状**:P2-1 已打通 STP→成品,但分析报告(HTML)与销售订单无直接关联
|
||||
- **目标**:销售订单创建时可选择关联 moldinsight task_id,订单详情页嵌入分析报告 iframe/摘要;报价单自动引用成本估算数据
|
||||
- **体量**:~2 天
|
||||
|
||||
#### P4-4 采购需求自动推导 ✅
|
||||
- **现状**:BOM 定义了成品所需物料,但采购仍需手动创建
|
||||
- **目标**:销售订单确认 → 按 BOM 展开物料需求 → 对比当前库存 → 自动生成采购建议(缺多少、建议供应商、预计金额);一键转为采购订单
|
||||
- **体量**:~3 天
|
||||
- **完成(2026-07-27)**:`purchase_demand_schemas.py`(Request/ItemResponse/Response)+ `purchase_demand_service.py`(6 步算法:批量查询订单→BOM 展开含损耗率→聚合需求→库存对比→主供应商推荐→按缺口降序排列)+ `purchase_demand_routes.py`(薄路由 `POST /api/purchase-demands/calculate`)+ 前端「采购建议」按钮 + 对话框(多选销售订单 + 结果表格含缺口/供应商/交期)
|
||||
|
||||
#### P4-5 GNN 分型面检测(决策项)
|
||||
- **现状**:`ai_parting_detector.py` 有框架无权重,从未被调用
|
||||
- **选择**:(a) 投入训权重(需标注数据集 + GPU);(b) 改为规则式分型面推荐(利用已识别的 Undercut/Pocket 特征 + 几何启发式);(c) 彻底移除,减少维护负担
|
||||
- **建议**:短期选 (b) 或 (c),等数据积累后再考虑 (a)
|
||||
|
||||
### 方向 C:可靠性与可观测性
|
||||
|
||||
#### P4-6 集成测试覆盖 ✅
|
||||
- **现状**:`tests/` 仅 2 个测试文件,核心业务流程无回归保障
|
||||
- **目标**:关键路径 pytest 覆盖——STP 上传→分析→创建成品→销售订单→采购→库存变动;mock OCC 外部依赖
|
||||
- **体量**:~2-3 天
|
||||
- **完成(2026-07-27)**:`conftest.py` 重构(SQLite + aiosqlite + FK 逆序清空 + 每测试重新播种);`test_purchase_demand.py` 5 个用例(正常推导/缺货/无效订单/无BOM/空请求);`test_api_inventory_orders.py` 32 个用例(库存/采购/销售/物料/StockMovement CRUD + 校验);`test_sales_order_delivered_freeze.py` 2 个用例(交付冻结/非交付可改);`sales_order_service.py` 补 delivered 状态守卫 bug 修复;39 测试全通过
|
||||
|
||||
#### P4-7 结构化日志 + 请求追踪 ✅
|
||||
- **现状**:`app_factory.py` 有请求日志中间件,但无 request_id 贯穿、无结构化 JSON 输出
|
||||
- **目标**:中间件注入 `X-Request-ID`;日志格式改 JSON(timestamp/level/request_id/service/path/duration_ms);接入 Prometheus `/metrics` 端点(请求计数/延迟/错误率)
|
||||
- **体量**:~1 天
|
||||
- **完成(2026-07-27)**:`logger.py` 升级为 JSON 结构化日志(`JSONFormatter` + `TextFormatter`)+ `contextvars` request_id 跨 async 传播;`app_factory.py` 中间件升级(自动生成/提取 `X-Request-ID`、注入响应头、全请求结构化日志含 method/path/status/duration_ms/client_ip);支持 `LOG_FORMAT`/`LOG_LEVEL` 环境变量切换;Prometheus `/metrics` 端点归入后续 P4-8 或独立任务
|
||||
|
||||
#### P4-8 Celery 任务可靠性
|
||||
- **现状**:任务失败无自动重试;无死信队列;批量任务进度仅靠 Redis TTL
|
||||
- **目标**:`@task(autoretry_for, retry_backoff)` 自动重试;死信队列记录永久失败任务;批量任务完成后写 PG 持久化(不依赖 Redis TTL 过期)
|
||||
- **体量**:~1-2 天
|
||||
|
||||
### 方向 D:格式扩展与性能
|
||||
|
||||
#### P4-9 IGES / BREP 格式支持
|
||||
- **现状**:仅支持 STP/STEP,注册表模式已就绪(P1-2)
|
||||
- **目标**:`IgesParserStage` + `BrepParserStage` 注册到流水线;前端上传组件扩展 accept 列表
|
||||
- **前提**:依赖 P4-2 Stage 流水线完成
|
||||
- **体量**:~1-2 天(流水线就绪后)
|
||||
|
||||
#### P4-10 大文件分析性能优化
|
||||
- **现状**:大模型(>1000 面)分析耗时线性增长,点云采样全量处理
|
||||
- **目标**:自适应采样(按曲率密度分配采样点);LOD 分级(远距低模 + 近距高模);分析结果增量更新(仅重算变更区域)
|
||||
- **体量**:~3-5 天
|
||||
@@ -1,315 +0,0 @@
|
||||
# 前端独立部署 + 统一后端入口实施计划
|
||||
|
||||
> 目标:在已经切换到“前端独立部署 + 同域反代”的基础上,进一步取消前端 Nginx 对 `/api` 的路径级分流,改为反代到一个真正的 **unified backend**,一次性解决长期维护成本。
|
||||
|
||||
---
|
||||
|
||||
## 1. 背景
|
||||
|
||||
当前项目已经完成了两项关键演进:
|
||||
|
||||
1. 前端从历史 `static/` 托管模式中抽离,开始走独立构建与独立部署
|
||||
2. 前端通过同域 Nginx 反代访问后端 API 与分析产物
|
||||
|
||||
但当前 Nginx 仍然承担了“后端路由所有权判断”的职责:
|
||||
|
||||
- 一部分 `/api/...` 被转发到 `moldinsight`
|
||||
- 另一部分 `/api/...` 被转发到 `inventory`
|
||||
|
||||
这虽然能跑通当前功能,但长期存在明显问题:
|
||||
|
||||
- 每新增一个 gemold API,Nginx 都要同步改配置
|
||||
- Nginx 配置承担了业务边界知识,维护成本高
|
||||
- `/health` 只能代表某一套后端,而不是统一入口
|
||||
- 与“unified / gemold-only / inventory-only”三种部署模式的目标不完全一致
|
||||
|
||||
因此,本轮改造的目标是:
|
||||
|
||||
> 把前端入口反代逻辑从“按路径分流到两套后端”升级为“统一反代到一个 unified backend”。
|
||||
|
||||
---
|
||||
|
||||
## 2. 目标状态
|
||||
|
||||
### 浏览器视角
|
||||
|
||||
浏览器始终只访问一个同域入口:
|
||||
|
||||
- `/` → 前端静态页面
|
||||
- `/api/*` → unified backend
|
||||
- `/health` → unified backend
|
||||
- `/html/*` → unified backend(由 unified backend 再提供 gemold 产物访问)
|
||||
|
||||
### Nginx 视角
|
||||
|
||||
Nginx 不再负责理解 gemold / inventory 的业务边界。
|
||||
|
||||
它只做两件事:
|
||||
|
||||
1. 提供前端静态文件与 SPA fallback
|
||||
2. 把 `/api`、`/health`、`/html` 统一转发给一个 backend upstream
|
||||
|
||||
### 后端视角
|
||||
|
||||
后端新增一个统一入口,负责组合:
|
||||
|
||||
- auth
|
||||
- moldinsight routes
|
||||
- inventory routes
|
||||
- `/health`
|
||||
- `/html`
|
||||
|
||||
同时继续保留:
|
||||
|
||||
- `moldinsight-only`
|
||||
- `inventory-only`
|
||||
|
||||
以满足模块独立部署场景。
|
||||
|
||||
---
|
||||
|
||||
## 3. 设计决策
|
||||
|
||||
### 3.1 为什么要引入 unified backend
|
||||
|
||||
因为前端与网关层最适合面对的是一个统一后端,而不是两套需要网关手工分流的内部模块。
|
||||
|
||||
收益:
|
||||
|
||||
- Nginx 配置显著简化
|
||||
- 新增 API 不需要修改网关规则
|
||||
- 文档和运维认知更简单
|
||||
- 前端保持统一 `/api` 契约
|
||||
- 更符合模块化蓝图中对 `unified` 模式的定义
|
||||
|
||||
### 3.2 为什么不直接把 split 模式删掉
|
||||
|
||||
因为:
|
||||
|
||||
- `gemold-only` 和 `inventory-only` 仍然有独立部署价值
|
||||
- 当前仓库已经形成了清晰模块边界
|
||||
- 统一入口应该成为**前端同域反代的默认方案**,而不是抹掉模块部署模式
|
||||
|
||||
所以最终保留三类入口:
|
||||
|
||||
- `src/entrypoints/unified.py`
|
||||
- `src/entrypoints/moldinsight.py`
|
||||
- `src/entrypoints/inventory.py`
|
||||
|
||||
---
|
||||
|
||||
## 4. 需要改动的核心文件
|
||||
|
||||
## 4.1 新增 unified 入口
|
||||
|
||||
新增:
|
||||
- `src/entrypoints/unified.py`
|
||||
|
||||
职责:
|
||||
- 基于 `shared.app_factory.create_app()` 创建应用
|
||||
- 统一挂载:
|
||||
- `moldinsight.api.router`(prefix=`/api`)
|
||||
- `inventory.api.inventory_router`
|
||||
- 使用:
|
||||
- `mount_html=True`
|
||||
- `serve_frontend_static=False`
|
||||
- 不额外挂载 auth(交给 `app_factory`)
|
||||
- 不手工重复定义 `/health`
|
||||
|
||||
## 4.2 简化前端 Nginx
|
||||
|
||||
修改:
|
||||
- `deploy/nginx/frontend.conf`
|
||||
|
||||
从当前:
|
||||
- 双 upstream:`moldinsight` / `inventory`
|
||||
- 多个 `location /api/...` 手工分流
|
||||
|
||||
改成:
|
||||
- 单 upstream:例如 `gemold_backend_upstream`
|
||||
- 统一转发:
|
||||
- `/api/` → unified backend
|
||||
- `/health` → unified backend
|
||||
- `/html/` → unified backend
|
||||
|
||||
保留:
|
||||
- `/` 的 SPA fallback
|
||||
- `/assets/` 的静态缓存策略
|
||||
|
||||
## 4.3 调整 Compose
|
||||
|
||||
修改:
|
||||
- `docker-compose.yml`
|
||||
|
||||
目标:
|
||||
- 增加 unified backend 服务
|
||||
- `frontend` 只依赖 unified backend
|
||||
- 保留 `moldinsight-celery`
|
||||
- 按需保留 split backend 入口作为独立 profile
|
||||
|
||||
建议最终 profile 语义:
|
||||
|
||||
- `full`:frontend + unified + celery
|
||||
- `frontend`:仅前端入口
|
||||
- `moldinsight`:仅 gemold-only
|
||||
- `inventory`:仅 inventory-only
|
||||
- (可选)`unified`:仅 unified backend
|
||||
|
||||
## 4.4 视实现需要调整 Dockerfile
|
||||
|
||||
可能新增:
|
||||
- `deploy/Dockerfile.unified`
|
||||
|
||||
或复用已有:
|
||||
- `deploy/Dockerfile.moldinsight`
|
||||
|
||||
取决于是否希望 unified backend 使用单独镜像名。
|
||||
|
||||
统一要求:
|
||||
- unified backend 镜像必须包含:
|
||||
- `src/moldinsight/`
|
||||
- `src/inventory/`
|
||||
- `src/shared/`
|
||||
- `src/entrypoints/unified.py`
|
||||
|
||||
## 4.5 文档同步
|
||||
|
||||
需要更新:
|
||||
- `README.md`
|
||||
- `frontend/README.md`
|
||||
- `docs/deployment/LINUX_SETUP.md`
|
||||
- `docs/deployment/DEPLOY_PORT.md`
|
||||
- `docs/deployment/PORT_CONFIG.md`
|
||||
|
||||
重点改动:
|
||||
- 当前推荐部署方式改为“frontend + unified backend + celery”
|
||||
- 说明 split 模式仍保留,但不再是前端同域反代默认方式
|
||||
- 端口说明中要区分:
|
||||
- 前端入口端口
|
||||
- unified backend 内部/对外端口
|
||||
- gemold-only / inventory-only 模块端口
|
||||
|
||||
---
|
||||
|
||||
## 5. 路由与冲突评估
|
||||
|
||||
根据当前代码结构,unified 模式可行,主要原因:
|
||||
|
||||
- inventory 所有业务路由都挂在 `/api` 下,并且以独立业务前缀区分
|
||||
- moldinsight 业务路由同样挂在 `/api` 下,但使用不同子路径
|
||||
- auth 路由使用 `/api/auth`
|
||||
- top-level `/health` 由 `app_factory` 提供
|
||||
- moldinsight 内部还有 `/api/health`,与 top-level `/health` 不冲突
|
||||
- `/html` 只有 moldinsight 需要
|
||||
|
||||
关键约束:
|
||||
|
||||
1. unified 入口中不要重复 include auth
|
||||
2. unified 入口中不要手工再定义 top-level `/health`
|
||||
3. unified 入口必须 `mount_html=True`
|
||||
|
||||
---
|
||||
|
||||
## 6. 风险与控制
|
||||
|
||||
### 风险 1:统一入口与现有 split 入口行为不一致
|
||||
**控制:**
|
||||
- 保留现有 `moldinsight.py` 与 `inventory.py`
|
||||
- 只把 unified 作为前端默认 upstream
|
||||
|
||||
### 风险 2:`/health` 语义变化
|
||||
当前前端只请求一个 `/health`,但 split 时代它实际上只代表某个后端。
|
||||
|
||||
**控制:**
|
||||
- unified 上的 `/health` 明确作为“前端默认 backend 健康入口”
|
||||
- 文档中明确其语义
|
||||
|
||||
### 风险 3:`/html` 丢失或不可达
|
||||
**控制:**
|
||||
- unified backend 继续 `mount_html=True`
|
||||
- 前端 Nginx 保留 `/html/` 反代
|
||||
|
||||
### 风险 4:Compose、Nginx、文档不同步
|
||||
**控制:**
|
||||
- 先写本计划文档
|
||||
- 再改 unified 入口、Nginx、Compose
|
||||
- 最后统一 README 与 deployment docs
|
||||
|
||||
---
|
||||
|
||||
## 7. 验证方案
|
||||
|
||||
## 7.1 路由验证
|
||||
|
||||
unified backend 启动后应验证:
|
||||
|
||||
- `/api/auth/login`
|
||||
- `/api/auth/me`
|
||||
- `/api/upload`
|
||||
- `/api/status/{task_id}`
|
||||
- `/api/history`
|
||||
- `/api/cost-estimate`
|
||||
- `/api/products`
|
||||
- `/api/inventory`
|
||||
- `/api/dashboard`
|
||||
- `/api/finance/*`
|
||||
- `/health`
|
||||
- `/html/...`
|
||||
|
||||
## 7.2 前端验证
|
||||
|
||||
前端同域访问应验证:
|
||||
|
||||
- `/login`
|
||||
- `/moldinsight`
|
||||
- `/inventory`
|
||||
- `/moldinsight/result/:taskId`
|
||||
|
||||
关键交互:
|
||||
|
||||
- 登录
|
||||
- 模具上传
|
||||
- 任务轮询
|
||||
- 成本估算
|
||||
- 产品/库存/订单页面加载
|
||||
- `/html` 分析结果页访问
|
||||
|
||||
## 7.3 Compose 验证
|
||||
|
||||
完整系统:
|
||||
|
||||
```bash
|
||||
docker compose --profile full up -d
|
||||
```
|
||||
|
||||
应满足:
|
||||
- `frontend` 正常提供页面
|
||||
- `frontend` 只反代一个 unified backend
|
||||
- `moldinsight-celery` 正常运行
|
||||
- 不再依赖 Nginx 路径级业务分流
|
||||
|
||||
---
|
||||
|
||||
## 8. 实施顺序
|
||||
|
||||
1. 新增 `docs/FRONTEND_UNIFIED_DEPLOYMENT_PLAN.md`
|
||||
2. 新增 `src/entrypoints/unified.py`
|
||||
3. 修改 `deploy/nginx/frontend.conf`
|
||||
4. 修改 `docker-compose.yml`
|
||||
5. 按需要修改 Dockerfile / 构建脚本
|
||||
6. 更新 README 与 deployment docs
|
||||
7. 做一致性验证
|
||||
|
||||
---
|
||||
|
||||
## 9. 最终预期
|
||||
|
||||
完成后,系统对外部署形态将变成:
|
||||
|
||||
- 前端:独立 Nginx 静态站点
|
||||
- 网关:同域同入口
|
||||
- 后端:一个 unified backend 作为前端默认 upstream
|
||||
- worker:保留 gemold Celery 异步处理
|
||||
- split 模式:继续作为模块独立部署能力保留
|
||||
|
||||
这能一次性解决当前“前端入口依赖 Nginx 路径级业务分流”的长期维护问题。
|
||||
@@ -1,127 +0,0 @@
|
||||
# moldinsight 模块技术债务分析与重构计划
|
||||
|
||||
> 日期:2026-08-31 · 基线 commit:`3ea5955`(模块拆分 init)
|
||||
> 状态标记:`[ ]` 待办 / `[x]` 已完成 / `[~]` 部分完成
|
||||
|
||||
---
|
||||
|
||||
## 一、问题清单(按严重程度)
|
||||
|
||||
### A. 安全漏洞(P0)
|
||||
|
||||
| # | 问题 | 位置 | 影响 |
|
||||
|---|------|------|------|
|
||||
| S1 | `/api/debug/tasks` 无鉴权,全量 dump 所有用户任务(含 geometry_data、analysis_result、文件名、LLM 报告)及 Redis 拓扑信息 | `api/debug_router.py:9-20` | 跨用户数据泄露 |
|
||||
| S2 | `/api/history` 与 `/api/history/{filename}` 无鉴权,且 `get_all_file_groups()` 未传 user_id(参数形同虚设) | `api/history_router.py:25-40`、`services/storage_integration_rustfs.py:698-704` | 跨用户文件清单泄露 |
|
||||
| S3 | `_ensure_task_access` 对 `owner_id is None` 的无主数据直接放行 | `api/advanced_router.py:87-89` | 任意登录用户可下载历史无主任务的导出文件 |
|
||||
|
||||
### B. 静默失败(P0)
|
||||
|
||||
| # | 问题 | 位置 | 影响 |
|
||||
|---|------|------|------|
|
||||
| F1 | `/api/detect-undercuts` 传 `shape=None`,OCC 异常被兜底 except 吞掉,**永远返回"无倒扣"的假 DFM 结论** | `api/advanced_router.py:293-302`、`core/side_action_designer.py:205-218` | 功能性错误,用户拿到 200 + 错误工程结论 |
|
||||
| F2 | `asyncio.wait_for` 超时无法杀死 OCC 线程;`_occ_executor` 为 `max_workers=1`,一个病态文件可**永久堵死全部分析队列**直到重启 | `services/processing_service.py:44-45,74-82` | 服务级可用性风险 |
|
||||
| F3 | `asyncio.create_task(...)` 未持有引用(GC 可回收任务)且无并发上限 | `api/upload_router.py:99-108`、`api/batch_router.py:114-121` | 后台任务静默消失 / 内存失控 |
|
||||
|
||||
### C. 性能与资源(P1)
|
||||
|
||||
| # | 问题 | 位置 | 影响 |
|
||||
|---|------|------|------|
|
||||
| P1 | 已完成任务每次状态轮询都从 RustFS 全量拉取 geometry + 多方案型腔 JSON + 网格 + 完整 HTML,无缓存 | `services/task_query_service.py:54-58` | 轮询 5s 一次 = 每次几十 MB 对象存储流量 |
|
||||
| P2 | `_export_shapes_cache` 缓存 OCC TopoDS_Shape(C++ 原生内存),按 task_id 无上限增长,无 LRU/TTL | `services/processing_service.py:43` | 原生内存泄漏 |
|
||||
| P3 | `save_html_file` 双写:完整 HTML 既入 RustFS 又塞 PG 行(`html_content`) | `services/storage_integration_rustfs.py:448-462` | PG 表膨胀 + 双份数据一致性负担 |
|
||||
| P4 | `get_all_file_groups` 每文件组单独一次 count 查询(N+1) | `services/storage_integration_rustfs.py:745-751` | history 接口放大 100 倍查询 |
|
||||
| P5 | `update_task` 为 get->merge->set 三步非原子,后台流程与 export-mold 端点并发写同一任务会**丢更新**;且每次进度 tick 全量重写整个 blob | `shared/services/redis_task_manager.py:138-146` | 竞态丢数据 + 写放大 |
|
||||
| P6 | 服务重启后 `_export_shapes_cache` 清空,STL 等格式的重导出直接 409 | `api/advanced_router.py:477-481` | 用户体验缺陷 |
|
||||
| P7 | `get_task_view` 已 joinedload `html_file` 后又单独查询 HTMLFile;`llm_service._chat` 每次新建 httpx client 且无重试 | `services/task_query_service.py:76-81`、`services/llm_service.py:517-531` | 小浪费 × 高频 |
|
||||
|
||||
### D. 架构与死代码(P2)
|
||||
|
||||
| # | 问题 | 位置 | 影响 |
|
||||
|---|------|------|------|
|
||||
| D1 | ~1000 行死代码:`storage_integration.py`(MinIO版,376行,零引用)、`storage/object_storage.py`(361行,仅被死文件引用)、`storage_service.py`(295行,零引用,仍用已弃用列)、`src/main.py`(废弃单体,~230行) | 详见各文件 | 认知负担 + 误用风险 |
|
||||
| D2 | **根 Dockerfile 仍在运行旧单体** `python src/main.py`,在仓库根目录 `docker build .` 会部署出错误服务 | `Dockerfile:28` | 部署陷阱 |
|
||||
| D3 | planner 调用 generator 13 个 `_` 前缀私有方法,私有方法成为事实契约;公共 API `generate_mold_cavities` 反而无人使用 | `core/multi_scheme_planner.py:38,102-165` | core 边界糊化,重构即炸 |
|
||||
| D4 | `REDIS_HOST` 两处读取两个默认值,其一为硬编码个人主机名 `szcjw`;settings 在 **import 时**因缺 DB 配置直接 raise | `shared/services/redis_task_manager.py:38`、`shared/config/settings.py:50-51` | 配置漂移 + 模块不可导入即不可测 |
|
||||
| D5 | upload/batch 约 50 行复制粘贴(参数归一化 + Celery/asyncio 分派);`process_file_with_storage` 与 `process_file_core` 异常处理两份拷贝 | `api/upload_router.py:43-49` vs `api/batch_router.py:62-68` | 漂移风险 |
|
||||
| D6 | moldinsight 测试覆盖为零;唯一测试 `temp_test_injection_p0.py` 因无 `test_` 前缀不被收集,且用黑加载规避 settings 导入期失败 | `tests/` | 回归无保障 |
|
||||
| D7 | 铝价服务返回模拟数据但未在任何层面标注 | `services/aluminum_price_service.py` | 产品诚信问题 |
|
||||
|
||||
---
|
||||
|
||||
## 二、实施方案
|
||||
|
||||
### P0:安全 + 静默失败(先做)
|
||||
|
||||
- [x] **① 补鉴权(修 S1/S2/S3)**
|
||||
- `history_router` 两个端点加 `get_current_active_user` 依赖,显式传 `user_id=current_user.id`
|
||||
- `debug_router` 加鉴权,且仅在 `settings.DEBUG` 下注册
|
||||
- `_ensure_task_access` 改为 `owner_id != user_id` 即 403(无主数据同样拒绝)
|
||||
|
||||
- [x] **② 统一后台分派(修 F3,消 D5 一半)**
|
||||
- 新建 `services/task_dispatcher.py`:Celery 可用走 `process_stp_task.delay`;否则 `asyncio.create_task` 并持有强引用(`_background_tasks` set + done_callback 回收)
|
||||
- upload/batch 路由统一调用;`asyncio.Semaphore` 限制 API 进程内并发处理数
|
||||
|
||||
- [x] **③ 超时后重置 OCC executor(修 F2)**
|
||||
- `asyncio.TimeoutError` 分支调用 `_reset_occ_executor()`:新建 executor、旧 executor `shutdown(wait=False)`
|
||||
- 泄漏 1 个挂死线程远好于全队列堵死;生产环境确认 celery worker 必配(进程隔离天然免疫)
|
||||
|
||||
- [x] **④ shape_loader 重建几何(修 F1)**
|
||||
- 新建 `services/shape_loader.py`:task_id -> PG 查 object_key -> RustFS 下载 STP -> 临时文件 -> occ executor 内 `stp_parser.load_step_file`
|
||||
- `/detect-undercuts` 用真实 shape 调 `analyze_and_design`,补 `_ensure_task_access`
|
||||
- `/cost-estimate` 的任务数据源从 Redis 直读迁移到 `TaskQueryService.get_task_view`(完成态走 PG+RustFS 组装,语义正确)
|
||||
|
||||
- [x] **⑤ Redis 哈希原子更新 + 配置收敛 + 完成态瘦身(修 P5/D4 部分)**
|
||||
- `redis_task_manager` 改为 Hash 存储:`HSET task:{id} field value` 字段级原子更新,无读改写竞态,进度 tick 不再全量重写 blob
|
||||
- 兼容读旧 string 格式(过渡期);`redis_client` 属性保留供 batch_router 使用
|
||||
- 连接参数统一读 `settings.*`,删除硬编码 `szcjw`
|
||||
- 完成态任务 Redis 只存摘要字段(去掉 geometry_data/analysis_result 大对象,完成态视图本就由 PG+RustFS 组装)
|
||||
|
||||
### P1:性能与资源
|
||||
|
||||
- [x] **⑤ 任务视图 TTL 缓存(修 P1/P7 部分)**
|
||||
- `TaskQueryService.get_task_view` 对 PG 路径(completed/failed)加进程内 TTL 缓存(60s)
|
||||
- export-mold / cam 写参数后显式失效;删除重复的 HTMLFile 单独查询
|
||||
|
||||
- [x] **⑥ export_shapes_cache 改 LRU(修 P2)**
|
||||
- OrderedDict LRU,`maxsize=32`,命中 `move_to_end`,满则逐出最旧(连原生 OCC shape 一起释放)
|
||||
|
||||
- [x] **⑦ 重启后 STEP->STL 现场转换(修 P6/F1 根因延伸)**
|
||||
- 分析期已持久化各方案 cavity/core/分型面 STEP;重启后 cache miss 时下载已持久化的 STEP -> OCC 读取 -> 三角化 -> 写 STL
|
||||
- `export-mold` 的 409 分支前新增此兜底,用户不再需要重新分析
|
||||
|
||||
- [x] **⑧ 收尾(修 P3/P4/P7)**
|
||||
- `save_html_file` 停止向 PG 写 `html_content`(RustFS 为准,PG 只存 key 与文件名)
|
||||
- `get_all_file_groups` 的 N+1 count 改为单条 `GROUP BY` 聚合
|
||||
- `llm_service._chat` 加一次瞬态错误重试(保持 per-call client:celery 每任务新循环,模块级 AsyncClient 会跨循环失效,与 redis 同理)
|
||||
|
||||
### P2:架构清理
|
||||
|
||||
- [x] **⑨ 删死代码(修 D1/D2)**
|
||||
- 删除:`services/storage_integration.py`、`storage/object_storage.py`、`services/storage_service.py`、`src/main.py`、根 `Dockerfile`
|
||||
- 删前 `grep -r` 确认零引用(动态引用也排查)
|
||||
|
||||
- [x] **⑪ 配置收敛(修 D4 后半)**
|
||||
- `settings` 改惰性校验:DB 配置缺失不在 import 时 raise,改为首次访问 `DATABASE_URL` 时报清晰错误
|
||||
- 解锁 `import shared.*` 无 env 场景(测试环境)
|
||||
|
||||
- [x] **⑫ 测试建设(修 D6,本阶段做低风险部分)**
|
||||
- `temp_test_injection_p0.py` -> `test_injection_p0.py`,改包路径导入
|
||||
- 补纯逻辑单测:PartingSchemeScorer / PartingCandidateGenerator / MaterialService / cost_estimate_service / `_determine_mold_structure` / redis_task_manager 序列化
|
||||
|
||||
- [ ] **⑩ Generator 公共接口提取(修 D3)** —— 13 个 `_` 方法提为公共 API,需排期单独做(纯机械重命名,但触及 core 三个文件,建议独立 PR + 集成测试保护)
|
||||
- [ ] **⑬ 顺手项(修 D7 等)** —— advanced_router 拆分 + Pydantic 模型;铝价响应加 `"source": "simulated"` 并前端标注
|
||||
|
||||
---
|
||||
|
||||
## 三、验证方式
|
||||
|
||||
1. `python -m pytest tests/ -x`(inventory 既有测试不回归 + 新增单测通过)
|
||||
2. `python -c "import ..."` 冒烟:dispatcher / shape_loader / redis_task_manager / task_query_service 可导入
|
||||
3. 部署面:`docker-compose.yml` 仅引用 `deploy/Dockerfile.*`,根 Dockerfile 删除后无引用(grep 验证)
|
||||
|
||||
## 四、风险与回滚
|
||||
|
||||
- Redis Hash 改造保留旧 string 读取兼容:升级期间在途任务可读;新写入一律 Hash。回滚版本读到 Hash 会 `get_task` 返回 None -> 走 PG 组装路径(TaskQueryService 兜底),不会 500
|
||||
- `_ensure_task_access` 收紧 owner=None 后,如确有管理员查看无主历史数据的需求,后续走 admin 角色专用端点,而非放开普通用户
|
||||
- `html_content` 停写后,历史行中的旧数据仍可读(列保留),仅新行不再写入
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
# geMoldInsight 演进路线图(ROADMAP)
|
||||
|
||||
> 文档定位:**未来演进路线与阶段计划的权威文档**。
|
||||
> 本文回答“下一步准备往哪里演进、按什么阶段推进”;不负责维护当前实现状态,当前状态见 [STATUS.md](STATUS.md)。架构边界见 [ARCHITECTURE.md](ARCHITECTURE.md),当前活跃技术债见 [TECH_DEBT.md](TECH_DEBT.md)。
|
||||
> 本文基于历史归档 [archive/EVOLUTION_ROADMAP.md](archive/EVOLUTION_ROADMAP.md) 收敛整理而来。
|
||||
|
||||
---
|
||||
|
||||
## 1. 演进背景
|
||||
|
||||
geMoldInsight 已从历史单体逐步演进为“双业务模块 + 共享平台层 + 独立前端”的结构,但要让后续迭代成本继续下降,仍需要在以下方向持续推进:
|
||||
|
||||
- 继续收敛模块边界
|
||||
- 继续减少 shared 的历史耦合
|
||||
- 让部署、文档、契约与代码结构保持一致
|
||||
- 让 moldinsight 与 inventory 的协作关系更稳定、可维护
|
||||
|
||||
当前事实与最近完成项见 [STATUS.md](STATUS.md)。
|
||||
|
||||
---
|
||||
|
||||
## 2. 当前演进主线
|
||||
|
||||
### 2.1 主线一:模块化架构收口
|
||||
|
||||
目标:
|
||||
- 继续巩固 `moldinsight / inventory / frontend / shared` 的边界
|
||||
- 减少历史单体遗留语义
|
||||
- 让 README、架构文档、部署文档与代码结构一致
|
||||
|
||||
重点方向:
|
||||
- 继续收敛 `shared` 的职责
|
||||
- 逐步明确 identity / platform 的边界语义
|
||||
- 收敛历史文档与旧部署叙事
|
||||
|
||||
### 2.2 主线二:moldinsight 工程化增强
|
||||
|
||||
目标:
|
||||
- 让 STEP/STP 分析链路更稳定
|
||||
- 让导出、批量分析、成本估算、任务状态等链路更可靠
|
||||
- 继续提高 OCC 相关处理的可维护性与可测试性
|
||||
|
||||
重点方向:
|
||||
- `advanced_router` 拆分与请求模型规范化
|
||||
- 模具分析链路的结构继续收口
|
||||
- OCC 依赖场景下的契约测试/集成测试继续补齐
|
||||
|
||||
### 2.3 主线三:inventory 业务层继续沉淀
|
||||
|
||||
目标:
|
||||
- 让 inventory 从“可用”继续走向“可扩展”
|
||||
- 继续将路由中的业务逻辑下沉为 service 层
|
||||
- 保持与 moldinsight 的桥接模型清晰
|
||||
|
||||
重点方向:
|
||||
- 业务 service 复用强化
|
||||
- 数据模型归属进一步清晰化
|
||||
- 前后端契约持续减少手写漂移
|
||||
|
||||
### 2.4 主线四:部署与运维一致性
|
||||
|
||||
目标:
|
||||
- 让推荐部署模式、Compose 入口、运维文档、Nginx/端口说明不再冲突
|
||||
- 让前端、后端、异步任务链路在部署说明上形成单一叙事
|
||||
|
||||
重点方向:
|
||||
- 继续收口部署文档
|
||||
- 把历史部署迁移方案移入归档
|
||||
- 保持同域前端 + unified backend 的默认认知清晰
|
||||
|
||||
---
|
||||
|
||||
## 3. 下一阶段优先项
|
||||
|
||||
### P0:文档与边界对齐
|
||||
|
||||
- 建立 `STATUS / ARCHITECTURE / ROADMAP / TECH_DEBT / DEPLOYMENT` 主骨架
|
||||
- 将 README 收敛为唯一导航入口
|
||||
- 收口部署重复文档并建立 archive
|
||||
|
||||
### P1:moldinsight API 结构整理
|
||||
|
||||
- 拆分 `advanced_router`
|
||||
- 为高频接口引入 Pydantic 请求模型
|
||||
- 继续减少 `request.json()` 风格手动解析
|
||||
|
||||
### P2:shared/platform 边界继续收敛
|
||||
|
||||
- 梳理共享 ORM 与业务模型的归属
|
||||
- 继续减少 shared 直接承担业务组合逻辑
|
||||
- 为后续平台层命名与目录调整准备条件
|
||||
|
||||
### P3:专项能力继续规范化
|
||||
|
||||
- 铝价模拟数据增加显式 `source: "simulated"`
|
||||
- 补专题文档的定位/边界说明
|
||||
- 清理历史 checklist / tasks / report 文档的展示层级
|
||||
|
||||
---
|
||||
|
||||
## 4. 中长期方向
|
||||
|
||||
### 4.1 平台层语义收敛
|
||||
|
||||
长期仍建议将 `shared` 逐步收敛为更清晰的平台层语义,但这应建立在:
|
||||
- 当前模块边界稳定
|
||||
- 共享职责分层足够清晰
|
||||
- 文档与部署已经同步收口
|
||||
|
||||
### 4.2 文档体系持续治理
|
||||
|
||||
后续文档治理原则:
|
||||
- README 只做入口
|
||||
- 当前状态只在 [STATUS.md](STATUS.md)
|
||||
- 历史材料统一入 `docs/archive/`
|
||||
- 每个主题只有一篇默认权威文档
|
||||
|
||||
### 4.3 测试能力继续增强
|
||||
|
||||
重点继续放在:
|
||||
- OCC 相关集成验证
|
||||
- 跨模块关键链路回归测试
|
||||
- 关键契约的自动化保护
|
||||
|
||||
---
|
||||
|
||||
### 4.4 专题文档持续分级
|
||||
|
||||
后续还会继续把专题文档区分为三类:
|
||||
- 当前仍有参考价值的专题文档(保留并补定位)
|
||||
- 纯阶段性任务/检查单/迁移计划(迁入 archive)
|
||||
- 可被主骨架吸收的重复说明(逐步收口)
|
||||
|
||||
---
|
||||
|
||||
## 5. 与相关文档的边界
|
||||
|
||||
- 当前项目处于什么状态:看 [STATUS.md](STATUS.md)
|
||||
- 当前架构与边界是什么:看 [ARCHITECTURE.md](ARCHITECTURE.md)
|
||||
- 当前有哪些技术债:看 [TECH_DEBT.md](TECH_DEBT.md)
|
||||
- 当前部署方式怎么做:看 [DEPLOYMENT.md](DEPLOYMENT.md)
|
||||
- 更完整的模块化蓝图讨论:看 [archive/BACKEND_MODULARIZATION_BLUEPRINT.md](archive/BACKEND_MODULARIZATION_BLUEPRINT.md)
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
# geMoldInsight 项目状态(STATUS)
|
||||
|
||||
> 文档定位:**唯一的“当前实现状态 / 当前推荐方案”文档**。
|
||||
> README 只做导航,不重复维护状态;架构细节见 [ARCHITECTURE.md](ARCHITECTURE.md),演进路线见 [ROADMAP.md](ROADMAP.md),技术债见 [TECH_DEBT.md](TECH_DEBT.md),部署入口见 [DEPLOYMENT.md](DEPLOYMENT.md)。
|
||||
> 最后更新:2026-09-01。
|
||||
|
||||
---
|
||||
|
||||
## 1. 当前项目状态总览
|
||||
|
||||
geMoldInsight 当前已从早期单体演进为:
|
||||
|
||||
- `moldinsight`:模具分析、STEP/STP 处理、批量分析、导出、成本估算
|
||||
- `inventory`:成品/物料/BOM/库存/采购/销售/财务
|
||||
- `frontend`:Vue 3 独立前端工程
|
||||
- `shared`:配置、数据库、认证、日志、应用工厂等共享平台层
|
||||
|
||||
当前架构形态可概括为:
|
||||
|
||||
> **单仓库 + 单数据库 + 多模块 + 可独立部署**
|
||||
|
||||
详细结构与边界见 [ARCHITECTURE.md](ARCHITECTURE.md)。
|
||||
|
||||
---
|
||||
|
||||
## 2. 当前推荐方案
|
||||
|
||||
### 2.1 推荐部署模式
|
||||
|
||||
当前推荐部署模式为:
|
||||
|
||||
- **unified**:frontend + unified backend + moldinsight celery
|
||||
|
||||
适用场景:
|
||||
- 本地开发
|
||||
- 集成环境
|
||||
- 小团队统一部署
|
||||
- 前端同域反代到单一 backend
|
||||
|
||||
详细部署说明见 [DEPLOYMENT.md](DEPLOYMENT.md) 与 [deployment/LINUX_SETUP.md](deployment/LINUX_SETUP.md)。
|
||||
|
||||
### 2.2 当前代码入口
|
||||
|
||||
当前后端已存在独立部署入口:
|
||||
- [src/entrypoints/moldinsight.py](../src/entrypoints/moldinsight.py)
|
||||
- [src/entrypoints/inventory.py](../src/entrypoints/inventory.py)
|
||||
|
||||
当前 Compose 入口:
|
||||
- [docker-compose.yml](../docker-compose.yml)
|
||||
|
||||
---
|
||||
|
||||
## 3. 当前模块化进展
|
||||
|
||||
### 3.1 已经成型的部分
|
||||
|
||||
- `src/moldinsight/` 与 `src/inventory/` 已具备相对清晰的业务目录边界
|
||||
- 前端已独立为 `frontend/` 工程,不再是后端静态目录的附属
|
||||
- 部署入口已按模块拆分到 `src/entrypoints/`
|
||||
- 基础认证、配置、数据库、日志等能力已集中到 `shared`
|
||||
|
||||
### 3.2 当前主要耦合点
|
||||
|
||||
当前最大的剩余耦合点主要是:
|
||||
|
||||
- `shared` 仍承担较多平台与组合职责
|
||||
- 共享 ORM 模型仍集中在 `shared.models.database`
|
||||
- 部分历史文档与当前模块化事实尚未完全收口
|
||||
|
||||
这些内容的结构化说明见 [ARCHITECTURE.md](ARCHITECTURE.md)。
|
||||
|
||||
---
|
||||
|
||||
## 4. 最近已完成的重要整理
|
||||
|
||||
### 4.1 moldinsight 技术债治理(本轮已完成)
|
||||
|
||||
已完成的重点治理包括:
|
||||
|
||||
- 安全收口:debug/history 权限补齐、任务访问控制收紧
|
||||
- 静默失败修复:`detect-undercuts` 基于真实 shape 重建分析
|
||||
- OCC 超时后 executor 重建,避免单个任务毒化全队列
|
||||
- 后台任务统一分派,避免 fire-and-forget 丢失
|
||||
- Redis 任务状态改为 Hash 原子更新,并兼容旧 string 格式
|
||||
- 完成态任务视图增加缓存,减少 RustFS 高频回读
|
||||
- 导出缓存与持久化链路收口,支持重启后再导出
|
||||
- 删除旧入口与死代码,修正部署陷阱
|
||||
- Generator 公共接口提取完成,并补充契约测试
|
||||
|
||||
详细治理记录见 [TECH_DEBT.md](TECH_DEBT.md)。
|
||||
|
||||
### 4.2 测试状态
|
||||
|
||||
当前已验证:
|
||||
|
||||
- 本地 pip 环境:**47 passed, 1 skipped**
|
||||
- gemold conda + OCC 环境:**88 passed**
|
||||
|
||||
说明:
|
||||
- 无 OCC 环境下,依赖 pythonocc 的契约测试会自动 skip
|
||||
- inventory 侧仍有少量既有 deprecation warnings,但不影响本轮通过状态
|
||||
|
||||
---
|
||||
|
||||
## 5. 当前仍在推进 / 尚未完成的重点
|
||||
|
||||
### 5.1 文档体系整理
|
||||
|
||||
本轮正在进行:
|
||||
- 将 README 收敛为唯一文档导航入口
|
||||
- 建立 `STATUS / ARCHITECTURE / ROADMAP / TECH_DEBT / DEPLOYMENT` 主骨架
|
||||
- 收口部署文档与历史文档
|
||||
|
||||
### 5.2 仍未完成的功能/结构项
|
||||
|
||||
当前仍明确未完成或待下一步推进的重点:
|
||||
|
||||
- `advanced_router` 拆分 + Pydantic 请求模型
|
||||
- 铝价模拟数据增加 `source: "simulated"` 标注,并同步前端展示
|
||||
- 进一步收敛 shared/platform 边界
|
||||
- 继续清理当前文档中“现状 / 规划 / 历史”混放问题
|
||||
|
||||
更长周期的演进方向见 [ROADMAP.md](ROADMAP.md)。
|
||||
|
||||
---
|
||||
|
||||
## 6. 报告、模板与归档文档说明
|
||||
|
||||
以下文档仍可能被保留用于专题说明、验收、模板复用或历史追溯,但不再承担当前状态入口职责:
|
||||
|
||||
- 业务/专题报告:
|
||||
- [archive/MOLD_ERP_ANALYSIS_REPORT.md](archive/MOLD_ERP_ANALYSIS_REPORT.md)
|
||||
- [archive/ZERO_FINISHED_INVENTORY_CERTIFICATE.md](archive/ZERO_FINISHED_INVENTORY_CERTIFICATE.md)
|
||||
- 验收/模板文档:
|
||||
- [templates/UAT_CHECKLIST.md](templates/UAT_CHECKLIST.md)
|
||||
- [templates/INTERFACE_INTEGRATION_CATALOG_TEMPLATE.md](templates/INTERFACE_INTEGRATION_CATALOG_TEMPLATE.md)
|
||||
- 历史材料归档:
|
||||
- [archive/README.md](archive/README.md)
|
||||
|
||||
---
|
||||
|
||||
## 7. 文档维护规则
|
||||
|
||||
- 当前实现状态只在本文维护
|
||||
- README 只做导航与最短入门,不重复状态细节
|
||||
- 架构边界改动更新 [ARCHITECTURE.md](ARCHITECTURE.md)
|
||||
- 规划变更更新 [ROADMAP.md](ROADMAP.md)
|
||||
- 技术债状态变更更新 [TECH_DEBT.md](TECH_DEBT.md)
|
||||
- 部署方式变化更新 [DEPLOYMENT.md](DEPLOYMENT.md) 与 [deployment/LINUX_SETUP.md](deployment/LINUX_SETUP.md)
|
||||
@@ -1,827 +0,0 @@
|
||||
# 铝制家电包装泡沫模具分模功能开发任务清单
|
||||
|
||||
## 文档信息
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| **文档名称** | 铝制家电包装泡沫模具分模功能开发任务清单 |
|
||||
| **版本** | 1.0 |
|
||||
| **日期** | 2026-03-13 |
|
||||
| **项目** | geMoldInsight 模具分模功能增强 |
|
||||
|
||||
---
|
||||
|
||||
## 任务总览
|
||||
|
||||
| 阶段 | 任务数 | 预计工期 |
|
||||
|------|--------|----------|
|
||||
| 第一阶段:基础框架 | 8 | 2 周 |
|
||||
| 第二阶段:分模算法 | 10 | 2 周 |
|
||||
| 第三阶段:质量检测 | 6 | 2 周 |
|
||||
| 第四阶段:可视化和交互 | 8 | 2 周 |
|
||||
| 第五阶段:数据接口和测试 | 6 | 1 周 |
|
||||
| **总计** | **38** | **9 周** |
|
||||
|
||||
---
|
||||
|
||||
## 第一阶段:基础框架搭建 (1-2 周)
|
||||
|
||||
### 任务 1.1:创建铝泡沫模具参数类
|
||||
|
||||
**任务描述**:创建专门针对铝泡沫材料的参数配置类
|
||||
|
||||
**详细说明**:
|
||||
- 在 `src/core/mold_generator.py` 中添加 `AluminumFoamMoldParams` 类
|
||||
- 定义铝泡沫专用参数(发泡倍率、目标密度、成型温度等)
|
||||
- 实现参数验证和默认值设置
|
||||
|
||||
**验收标准**:
|
||||
- 参数类包含所有铝泡沫专用参数
|
||||
- 参数验证通过
|
||||
|
||||
**预计工时**:4 小时
|
||||
|
||||
**依赖任务**:无
|
||||
|
||||
---
|
||||
|
||||
### 任务 1.2:创建铝泡沫材料数据库
|
||||
|
||||
**任务描述**:建立铝泡沫材料数据库,包含常用材料参数
|
||||
|
||||
**详细说明**:
|
||||
- 创建材料数据库类 `FoamMaterialDatabase`
|
||||
- 添加 AlSi10Mg、AlSi12、纯铝泡沫等常用材料
|
||||
- 支持材料查询和参数获取
|
||||
|
||||
**验收标准**:
|
||||
- 数据库包含至少 5 种铝泡沫材料
|
||||
- 支持按名称查询材料参数
|
||||
|
||||
**预计工时**:4 小时
|
||||
|
||||
**依赖任务**:1.1
|
||||
|
||||
---
|
||||
|
||||
### 任务 1.3:扩展现有模具生成器
|
||||
|
||||
**任务描述**:扩展 `MoldCavityGenerator` 类支持铝泡沫参数
|
||||
|
||||
**详细说明**:
|
||||
- 添加铝泡沫参数到构造函数
|
||||
- 添加材料设置方法 `set_foam_material()`
|
||||
- 适配现有的分模流程
|
||||
|
||||
**验收标准**:
|
||||
- 可以使用铝泡沫参数创建生成器
|
||||
- 参数正确传递给分模流程
|
||||
|
||||
**预计工时**:4 小时
|
||||
|
||||
**依赖任务**:1.1, 1.2
|
||||
|
||||
---
|
||||
|
||||
### 任务 1.4:创建参数配置 API 接口
|
||||
|
||||
**任务描述**:添加前端参数配置 API
|
||||
|
||||
**详细说明**:
|
||||
- 在 `src/api/routes.py` 中添加参数相关路由
|
||||
- 实现参数获取、设置、验证接口
|
||||
- 支持参数模板保存和加载
|
||||
|
||||
**验收标准**:
|
||||
- API 可以获取和设置分模参数
|
||||
- 参数验证正确返回错误信息
|
||||
|
||||
**预计工时**:4 小时
|
||||
|
||||
**依赖任务**:1.3
|
||||
|
||||
---
|
||||
|
||||
### 任务 1.5:前端参数面板开发
|
||||
|
||||
**任务描述**:在 Web 界面中添加分模参数配置面板
|
||||
|
||||
**详细说明**:
|
||||
- 在 `static/vue-app.js` 中添加参数配置组件
|
||||
- 实现滑块、输入框、选择框等控件
|
||||
- 支持参数实时预览
|
||||
|
||||
**验收标准**:
|
||||
- 界面显示所有可配置参数
|
||||
- 参数修改正确提交到后端
|
||||
|
||||
**预计工时**:8 小时
|
||||
|
||||
**依赖任务**:1.4
|
||||
|
||||
---
|
||||
|
||||
### 任务 1.6:参数模板功能
|
||||
|
||||
**任务描述**:实现参数模板保存和加载功能
|
||||
|
||||
**详细说明**:
|
||||
- 创建预设参数模板(快速、经济、高精度等)
|
||||
- 支持用户保存自定义模板
|
||||
- 模板存储到数据库
|
||||
|
||||
**验收标准**:
|
||||
- 至少 3 个预设模板可用
|
||||
- 用户可以保存和加载模板
|
||||
|
||||
**预计工时**:4 小时
|
||||
|
||||
**依赖任务**:1.4, 1.5
|
||||
|
||||
---
|
||||
|
||||
### 任务 1.7:参数验证逻辑
|
||||
|
||||
**任务描述**:实现参数合法性验证
|
||||
|
||||
**详细说明**:
|
||||
- 验证数值范围(角度、容差等)
|
||||
- 验证参数组合合法性
|
||||
- 返回详细的验证错误信息
|
||||
|
||||
**验收标准**:
|
||||
- 所有参数都有验证逻辑
|
||||
- 错误信息清晰明了
|
||||
|
||||
**预计工时**:4 小时
|
||||
|
||||
**依赖任务**:1.1
|
||||
|
||||
---
|
||||
|
||||
### 任务 1.8:阶段一集成测试
|
||||
|
||||
**任务描述**:测试参数系统的完整性
|
||||
|
||||
**详细说明**:
|
||||
- 测试参数设置和获取
|
||||
- 测试参数验证
|
||||
- 测试前端交互
|
||||
|
||||
**验收标准**:
|
||||
- 所有功能正常运行
|
||||
- 无明显 bug
|
||||
|
||||
**预计工时**:4 小时
|
||||
|
||||
**依赖任务**:1.1-1.7
|
||||
|
||||
---
|
||||
|
||||
## 第二阶段:分模算法优化 (3-4 周)
|
||||
|
||||
### 任务 2.1:改进法向量分析算法
|
||||
|
||||
**任务描述**:改进分型面检测的法向量分析算法
|
||||
|
||||
**详细说明**:
|
||||
- 添加高斯权重计算
|
||||
- 支持多点采样
|
||||
- 识别主分型方向
|
||||
|
||||
**验收标准**:
|
||||
- 算法能正确处理复杂几何产品
|
||||
- 分型方向准确率 > 90%
|
||||
|
||||
**预计工时**:8 小时
|
||||
|
||||
**依赖任务**:无
|
||||
|
||||
---
|
||||
|
||||
### 任务 2.2:实现多分型面检测
|
||||
|
||||
**任务描述**:支持复杂产品的多个分型面
|
||||
|
||||
**详细说明**:
|
||||
- 识别需要多次分模的区域
|
||||
- 正确处理分型面优先级
|
||||
- 生成有序的分型面列表
|
||||
|
||||
**验收标准**:
|
||||
- 能正确检测 2 个以上分型面
|
||||
- 分型面顺序正确
|
||||
|
||||
**预计工时**:12 小时
|
||||
|
||||
**依赖任务**:2.1
|
||||
|
||||
---
|
||||
|
||||
### 任务 2.3:倒扣区域检测
|
||||
|
||||
**任务描述**:自动识别产品倒扣区域
|
||||
|
||||
**详细说明**:
|
||||
- 分析产品几何特征
|
||||
- 标记倒扣区域位置
|
||||
- 提供处理建议
|
||||
|
||||
**验收标准**:
|
||||
- 能识别常见的倒扣类型
|
||||
- 提供准确的倒扣位置
|
||||
|
||||
**预计工时**:8 小时
|
||||
|
||||
**依赖任务**:2.1
|
||||
|
||||
---
|
||||
|
||||
### 任务 2.4:改进拔模角计算
|
||||
|
||||
**任务描述**:实现完整的拔模角计算和应用
|
||||
|
||||
**详细说明**:
|
||||
- 使用 OpenCASCADE 拔模功能
|
||||
- 支持不同拔模方向
|
||||
- 处理拔模干涉
|
||||
|
||||
**验收标准**:
|
||||
- 拔模角正确应用到模型
|
||||
- 无明显变形或错误
|
||||
|
||||
**预计工时**:12 小时
|
||||
|
||||
**依赖任务**:无
|
||||
|
||||
---
|
||||
|
||||
### 任务 2.5:铝泡沫收缩补偿
|
||||
|
||||
**任务描述**:针对铝泡沫实现特殊的收缩补偿
|
||||
|
||||
**详细说明**:
|
||||
- 基于发泡倍率计算收缩
|
||||
- 多向收缩补偿
|
||||
- 补偿后尺寸验证
|
||||
|
||||
**验收标准**:
|
||||
- 收缩补偿量准确
|
||||
- 补偿后模型无异常
|
||||
|
||||
**预计工时**:8 小时
|
||||
|
||||
**依赖任务**:1.2
|
||||
|
||||
---
|
||||
|
||||
### 任务 2.6:型腔分离优化
|
||||
|
||||
**任务描述**:改进型腔和型芯的分离算法
|
||||
|
||||
**详细说明**:
|
||||
- 精确的布尔运算
|
||||
- 处理复杂几何
|
||||
- 分离结果验证
|
||||
|
||||
**验收标准**:
|
||||
- 型腔/型芯分离正确
|
||||
- 分离过程无错误
|
||||
|
||||
**预计工时**:8 小时
|
||||
|
||||
**依赖任务**:无
|
||||
|
||||
---
|
||||
|
||||
### 任务 2.7:模具块生成
|
||||
|
||||
**任务描述**:生成完整的模具块结构
|
||||
|
||||
**详细说明**:
|
||||
- 计算模具尺寸
|
||||
- 添加余量
|
||||
- 生成 A/B 板结构
|
||||
|
||||
**验收标准**:
|
||||
- 模具块尺寸合理
|
||||
- 包含必要的结构元素
|
||||
|
||||
**预计工时**:8 小时
|
||||
|
||||
**依赖任务**:2.6
|
||||
|
||||
---
|
||||
|
||||
### 任务 2.8:分型线平滑处理
|
||||
|
||||
**任务描述**:对分型线进行平滑处理
|
||||
|
||||
**详细说明**:
|
||||
- B 样条曲线拟合
|
||||
- 尖角处理
|
||||
- 平滑度验证
|
||||
|
||||
**验收标准**:
|
||||
- 分型线平滑无毛刺
|
||||
- 保持原始几何精度
|
||||
|
||||
**预计工时**:6 小时
|
||||
|
||||
**依赖任务**:2.2
|
||||
|
||||
---
|
||||
|
||||
### 任务 2.9:算法性能优化
|
||||
|
||||
**任务描述**:优化分模算法性能
|
||||
|
||||
**详细说明**:
|
||||
- 并行计算支持
|
||||
- 缓存优化
|
||||
- 增量计算
|
||||
|
||||
**验收标准**:
|
||||
- 分模时间 < 30 秒
|
||||
- 内存占用 < 1GB
|
||||
|
||||
**预计工时**:8 小时
|
||||
|
||||
**依赖任务**:2.1-2.8
|
||||
|
||||
---
|
||||
|
||||
### 任务 2.10:阶段二集成测试
|
||||
|
||||
**任务描述**:测试分模算法的完整流程
|
||||
|
||||
**详细说明**:
|
||||
- 使用测试产品验证
|
||||
- 对比不同参数结果
|
||||
- 性能测试
|
||||
|
||||
**验收标准**:
|
||||
- 算法稳定运行
|
||||
- 结果准确合理
|
||||
|
||||
**预计工时**:8 小时
|
||||
|
||||
**依赖任务**:2.1-2.9
|
||||
|
||||
---
|
||||
|
||||
## 第三阶段:质量检测模块 (5-6 周)
|
||||
|
||||
### 任务 3.1:创建质量检测器类
|
||||
|
||||
**任务描述**:创建 `MoldQualityInspector` 质量检测类
|
||||
|
||||
**详细说明**:
|
||||
- 设计检测器架构
|
||||
- 定义检测接口
|
||||
- 实现结果数据结构
|
||||
|
||||
**验收标准**:
|
||||
- 类结构完整
|
||||
- 接口定义清晰
|
||||
|
||||
**预计工时**:4 小时
|
||||
|
||||
**依赖任务**:无
|
||||
|
||||
---
|
||||
|
||||
### 任务 3.2:分模面平滑度检测
|
||||
|
||||
**任务描述**:检测分模面的平滑度
|
||||
|
||||
**详细说明**:
|
||||
- 曲率分析
|
||||
- 凹凸检测
|
||||
- 评分计算
|
||||
|
||||
**验收标准**:
|
||||
- 正确识别不平滑区域
|
||||
- 给出评分 (0-100)
|
||||
|
||||
**预计工时**:8 小时
|
||||
|
||||
**依赖任务**:3.1
|
||||
|
||||
---
|
||||
|
||||
### 任务 3.3:分模面连续性检测
|
||||
|
||||
**任务描述**:检测分模面的连续性
|
||||
|
||||
**详细说明**:
|
||||
- 边界检查
|
||||
- 间隙检测
|
||||
- 完整性验证
|
||||
|
||||
**验收标准**:
|
||||
- 能识别间隙和断点
|
||||
- 报告位置和大小
|
||||
|
||||
**预计工时**:6 小时
|
||||
|
||||
**依赖任务**:3.1
|
||||
|
||||
---
|
||||
|
||||
### 任务 3.4:模具结构合理性检测
|
||||
|
||||
**任务描述**:检测模具结构的合理性
|
||||
|
||||
**详细说明**:
|
||||
- 模具尺寸检查
|
||||
- 壁厚检查
|
||||
- 干涉检查
|
||||
|
||||
**验收标准**:
|
||||
- 识别所有结构问题
|
||||
- 提供修改建议
|
||||
|
||||
**预计工时**:8 小时
|
||||
|
||||
**依赖任务**:3.1
|
||||
|
||||
---
|
||||
|
||||
### 任务 3.5:生产可行性评估
|
||||
|
||||
**任务描述**:评估模具的生产可行性
|
||||
|
||||
**详细说明**:
|
||||
- 注塑压力计算
|
||||
- 锁模力计算
|
||||
- 成型周期估算
|
||||
|
||||
**验收标准**:
|
||||
- 估算值在合理范围
|
||||
- 提供改进建议
|
||||
|
||||
**预计工时**:8 小时
|
||||
|
||||
**依赖任务**:3.1
|
||||
|
||||
---
|
||||
|
||||
### 任务 3.6:质量报告生成
|
||||
|
||||
**任务描述**:生成完整的质量检测报告
|
||||
|
||||
**详细说明**:
|
||||
- 汇总各项检测结果
|
||||
- 生成 PDF 格式报告
|
||||
- 支持导出
|
||||
|
||||
**验收标准**:
|
||||
- 报告内容完整
|
||||
- 格式规范
|
||||
|
||||
**预计工时**:6 小时
|
||||
|
||||
**依赖任务**:3.2-3.5
|
||||
|
||||
---
|
||||
|
||||
## 第四阶段:可视化和交互 (5-6 周)
|
||||
|
||||
### 任务 4.1:分型面可视化增强
|
||||
|
||||
**任务描述**:改进分型面的可视化效果
|
||||
|
||||
**详细说明**:
|
||||
- 分型面颜色和透明度设置
|
||||
- 边缘高亮
|
||||
- 动态效果
|
||||
|
||||
**验收标准**:
|
||||
- 分型面清晰可见
|
||||
- 与产品形成对比
|
||||
|
||||
**预计工时**:4 小时
|
||||
|
||||
**依赖任务**:无
|
||||
|
||||
---
|
||||
|
||||
### 任务 4.2:分型线可视化增强
|
||||
|
||||
**任务描述**:改进分型线的可视化
|
||||
|
||||
**详细说明**:
|
||||
- 线条颜色和粗细
|
||||
- 端点标记
|
||||
- 动态绘制效果
|
||||
|
||||
**验收标准**:
|
||||
- 分型线清晰可见
|
||||
- 便于观察细节
|
||||
|
||||
**预计工时**:4 小时
|
||||
|
||||
**依赖任务**:无
|
||||
|
||||
---
|
||||
|
||||
### 任务 4.3:交互式分型面调整
|
||||
|
||||
**任务描述**:支持用户拖拽调整分型面
|
||||
|
||||
**详细说明**:
|
||||
- 鼠标拖拽事件
|
||||
- 实时更新模型
|
||||
- 撤销/重做支持
|
||||
|
||||
**验收标准**:
|
||||
- 拖拽响应流畅
|
||||
- 模型正确更新
|
||||
|
||||
**预计工时**:12 小时
|
||||
|
||||
**依赖任务**:4.1
|
||||
|
||||
---
|
||||
|
||||
### 任务 4.4:交互式参数调整
|
||||
|
||||
**任务描述**:支持实时调整参数并预览效果
|
||||
|
||||
**详细说明**:
|
||||
- 滑块实时更新
|
||||
- 参数变化动画
|
||||
- 效果对比
|
||||
|
||||
**验收标准**:
|
||||
- 调整流畅无延迟
|
||||
- 效果正确显示
|
||||
|
||||
**预计工时**:8 小时
|
||||
|
||||
**依赖任务**:1.5
|
||||
|
||||
---
|
||||
|
||||
### 任务 4.5:剖视图功能
|
||||
|
||||
**任务描述**:添加剖视图功能
|
||||
|
||||
**详细说明**:
|
||||
- 沿分型面剖切
|
||||
- 内部结构显示
|
||||
- 剖面编辑
|
||||
|
||||
**验收标准**:
|
||||
- 剖视图正确显示
|
||||
- 切换流畅
|
||||
|
||||
**预计工时**:8 小时
|
||||
|
||||
**依赖任务**:4.1
|
||||
|
||||
---
|
||||
|
||||
### 任务 4.6:测量工具
|
||||
|
||||
**任务描述**:添加测量工具
|
||||
|
||||
**详细说明**:
|
||||
- 距离测量
|
||||
- 角度测量
|
||||
- 测量结果标注
|
||||
|
||||
**验收标准**:
|
||||
- 测量结果准确
|
||||
- 操作便捷
|
||||
|
||||
**预计工时**:8 小时
|
||||
|
||||
**依赖任务**:无
|
||||
|
||||
---
|
||||
|
||||
### 任务 4.7:视角控制增强
|
||||
|
||||
**任务描述**:改进视角控制
|
||||
|
||||
**详细说明**:
|
||||
- 预设视角
|
||||
- 动画过渡
|
||||
- 自动对准
|
||||
|
||||
**验收标准**:
|
||||
- 视角切换流畅
|
||||
- 自动对准准确
|
||||
|
||||
**预计工时**:4 小时
|
||||
|
||||
**依赖任务**:无
|
||||
|
||||
---
|
||||
|
||||
### 任务 4.8:导出视图功能
|
||||
|
||||
**任务描述**:支持导出当前视图
|
||||
|
||||
**详细说明**:
|
||||
- PNG 图片导出
|
||||
- 高清截图
|
||||
- 报告插图
|
||||
|
||||
**验收标准**:
|
||||
- 导出图片清晰
|
||||
- 格式正确
|
||||
|
||||
**预计工时**:4 小时
|
||||
|
||||
**依赖任务**:4.1-4.7
|
||||
|
||||
---
|
||||
|
||||
## 第五阶段:数据接口和测试 (7-8 周)
|
||||
|
||||
### 任务 5.1:STEP 导出接口
|
||||
|
||||
**任务描述**:实现 STEP 格式导出
|
||||
|
||||
**详细说明**:
|
||||
- 使用 PythonOCC 导出 STEP
|
||||
- 包含分模后模型
|
||||
- 验证导出正确性
|
||||
|
||||
**验收标准**:
|
||||
- 导出文件可被 CAD 打开
|
||||
- 几何正确
|
||||
|
||||
**预计工时**:8 小时
|
||||
|
||||
**依赖任务**:无
|
||||
|
||||
---
|
||||
|
||||
### 任务 5.2:JSON 数据导出
|
||||
|
||||
**任务描述**:实现 JSON 格式导出
|
||||
|
||||
**详细说明**:
|
||||
- 导出分模参数
|
||||
- 导出几何数据
|
||||
- 导出质量报告
|
||||
|
||||
**验收标准**:
|
||||
- JSON 格式正确
|
||||
- 数据完整
|
||||
|
||||
**预计工时**:4 小时
|
||||
|
||||
**依赖任务**:无
|
||||
|
||||
---
|
||||
|
||||
### 任务 5.3:PDF 报告导出
|
||||
|
||||
**任务描述**:实现 PDF 格式报告导出
|
||||
|
||||
**详细说明**:
|
||||
- 质量检测报告
|
||||
- 包含图表和说明
|
||||
- 模板支持
|
||||
|
||||
**验收标准**:
|
||||
- PDF 生成成功
|
||||
- 内容完整
|
||||
|
||||
**预计工时**:8 小时
|
||||
|
||||
**依赖任务**:3.6
|
||||
|
||||
---
|
||||
|
||||
### 任务 5.4:IGES 格式支持
|
||||
|
||||
**任务描述**:添加 IGES 格式支持
|
||||
|
||||
**详细说明**:
|
||||
- IGES 导入
|
||||
- IGES 导出
|
||||
- 格式验证
|
||||
|
||||
**验收标准**:
|
||||
- 导出文件可被 CAM 软件使用
|
||||
|
||||
**预计工时**:6 小时
|
||||
|
||||
**依赖任务**:5.1
|
||||
|
||||
---
|
||||
|
||||
### 任务 5.5:集成测试
|
||||
|
||||
**任务描述**:完整的系统集成测试
|
||||
|
||||
**详细说明**:
|
||||
- 功能测试
|
||||
- 性能测试
|
||||
- 兼容性测试
|
||||
|
||||
**验收标准**:
|
||||
- 所有功能正常运行
|
||||
- 达到性能指标
|
||||
|
||||
**预计工时**:8 小时
|
||||
|
||||
**依赖任务**:全部
|
||||
|
||||
---
|
||||
|
||||
### 任务 5.6:用户验收测试
|
||||
|
||||
**任务描述**:配合用户进行验收测试
|
||||
|
||||
**详细说明**:
|
||||
- 演示功能
|
||||
- 收集反馈
|
||||
- 修复问题
|
||||
|
||||
**验收标准**:
|
||||
- 用户满意
|
||||
- 达到预期目标
|
||||
|
||||
**预计工时**:8 小时
|
||||
|
||||
**依赖任务**:5.5
|
||||
|
||||
---
|
||||
|
||||
## 任务依赖关系图
|
||||
|
||||
```
|
||||
第一阶段: 基础框架
|
||||
├── 1.1 创建参数类
|
||||
├── 1.2 材料数据库 ──┐
|
||||
├── 1.3 扩展生成器 ──┼── 1.4 API ──┬── 1.5 前端 ──┬── 1.6 模板 ──┬── 1.7 验证 ──→ 1.8 测试
|
||||
│ │ │ │ │
|
||||
└────────────────────┴──────────────┴──────────────┴──────────────┘
|
||||
|
||||
第二阶段: 分模算法
|
||||
│
|
||||
├── 2.1 法向量分析 ──→ 2.2 多分型面 ──→ 2.3 倒扣检测
|
||||
│
|
||||
├── 2.4 拔模角 ──────────────────────────────────────────────────────────┐
|
||||
│ │
|
||||
├── 2.5 收缩补偿 ◄──────────────────┐ │
|
||||
│ │ │
|
||||
├── 2.6 型腔分离 ──→ 2.7 模具块 ──→ 2.8 平滑处理 ──→ 2.9 优化 ──→ 2.10 测试
|
||||
│ │
|
||||
└────────────────────────────────────┴────────────────────────────────────┘
|
||||
|
||||
第三阶段: 质量检测
|
||||
│
|
||||
├── 3.1 检测器类 ──→ 3.2 平滑度 ──→ 3.3 连续性 ──→ 3.4 结构 ──→ 3.5 可行性 ──→ 3.6 报告
|
||||
│
|
||||
└────────────────────────────────────┬────────────────────────────────────┘
|
||||
|
||||
第四阶段: 可视化
|
||||
│
|
||||
├── 4.1 分型面 ──→ 4.2 分型线 ──→ 4.3 拖拽 ──→ 4.4 参数调整 ──→ 4.5 剖视
|
||||
│ │ │
|
||||
├── 4.6 测量 ──→ 4.7 视角 ──→ 4.8 导出 ◄─────────────┘
|
||||
│
|
||||
└────────────────────────────────────┬────────────────────────────────────┘
|
||||
|
||||
第五阶段: 接口和测试
|
||||
│
|
||||
├── 5.1 STEP ──→ 5.2 JSON ◄──┐
|
||||
│ │
|
||||
├── 5.3 PDF ◄─────────────────┼── 5.4 IGES ──→ 5.5 集成 ──→ 5.6 验收
|
||||
│ │
|
||||
└──────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 资源分配
|
||||
|
||||
| 角色 | 任务 | 预计工时 |
|
||||
|------|------|----------|
|
||||
| 后端开发 | 1.1-1.4, 2.1-2.10, 3.1-3.6, 5.1-5.4 | 180 小时 |
|
||||
| 前端开发 | 1.5-1.6, 4.1-4.8 | 60 小时 |
|
||||
| 测试 | 1.8, 2.10, 5.5-5.6 | 32 小时 |
|
||||
| **总计** | | **272 小时** |
|
||||
|
||||
---
|
||||
|
||||
## 风险评估
|
||||
|
||||
| 风险 | 影响 | 应对措施 |
|
||||
|------|------|----------|
|
||||
| 算法复杂度高 | 时间延误 | 预留缓冲时间,分阶段交付 |
|
||||
| OpenCASCADE 兼容问题 | 功能受限 | 多种实现方案,准备备选 |
|
||||
| 性能不达标 | 用户体验差 | 持续优化,必要时降级功能 |
|
||||
| 需求变更 | 计划调整 | 敏捷开发,快速迭代 |
|
||||
|
||||
---
|
||||
|
||||
**文档结束**
|
||||
@@ -0,0 +1,158 @@
|
||||
# geMoldInsight 技术债与治理计划(TECH_DEBT)
|
||||
|
||||
> 文档定位:**当前活跃技术债与治理计划的权威文档**。
|
||||
> 本文回答“现在还有哪些重要债务、优先级如何、下一步怎么处理”;不负责维护当前实现状态,当前状态见 [STATUS.md](STATUS.md)。架构边界见 [ARCHITECTURE.md](ARCHITECTURE.md),未来路线见 [ROADMAP.md](ROADMAP.md)。
|
||||
> 本文由归档文档 [archive/MOLDINSIGHT_TECH_DEBT_PLAN.md](archive/MOLDINSIGHT_TECH_DEBT_PLAN.md) 收敛整理而来,保留活跃债务与治理结论,弱化详细实施流水账。
|
||||
|
||||
---
|
||||
|
||||
## 1. 当前技术债概览
|
||||
|
||||
当前最主要的技术债集中在两个区域:
|
||||
|
||||
- **moldinsight API 与处理链路的结构收口**
|
||||
- **文档 / 部署 / 历史语义与当前代码现状未完全一致**
|
||||
|
||||
已经完成的高优先级治理不再作为持续待办反复展开,当前重点聚焦在“还没完成、且值得继续推进”的部分。
|
||||
|
||||
---
|
||||
|
||||
## 2. 已完成的重要治理(摘要)
|
||||
|
||||
以下高价值治理已完成:
|
||||
|
||||
### 2.1 安全与权限
|
||||
- debug/history 路由补鉴权
|
||||
- 任务访问控制收紧
|
||||
- 无主数据不再默认放行
|
||||
|
||||
### 2.2 静默失败与可用性
|
||||
- `detect-undercuts` 改为基于真实 shape 分析
|
||||
- OCC 超时后重建 executor,避免全队列永久堵死
|
||||
- 后台任务统一分派,补强引用与并发控制
|
||||
|
||||
### 2.3 状态存储与缓存
|
||||
- Redis 任务状态改为 Hash 字段级更新,兼容旧格式
|
||||
- 完成态任务视图增加缓存
|
||||
- 导出缓存与持久化链路收口,支持重启后再导出
|
||||
|
||||
### 2.4 架构与代码清理
|
||||
- 删除旧单体入口与死代码
|
||||
- 设置惰性配置校验,提升可测试性
|
||||
- Generator 公共接口提取完成,补充契约测试
|
||||
|
||||
详细历史过程保留在原始技术债文档中,后续将转入归档。
|
||||
|
||||
---
|
||||
|
||||
## 3. 当前活跃技术债
|
||||
|
||||
### D1. `advanced_router` 过大,职责混杂
|
||||
|
||||
现状:
|
||||
- 导出、估算、设计/分析相关接口仍混在同一个 router 中
|
||||
- 请求体仍有较多手动解析逻辑
|
||||
|
||||
影响:
|
||||
- 路由边界不清晰
|
||||
- OpenAPI 可读性差
|
||||
- 接口参数校验不统一
|
||||
- 后续继续扩展时维护成本高
|
||||
|
||||
建议:
|
||||
- 拆分为 export / design / cost 等子路由
|
||||
- 高优先级请求体改为 Pydantic 模型
|
||||
|
||||
优先级:**P1**
|
||||
|
||||
### D2. 铝价模拟数据未显式标注来源
|
||||
|
||||
现状:
|
||||
- 铝价服务返回的是模拟/参考数据,但接口层未明确表达
|
||||
|
||||
影响:
|
||||
- 容易误导前端与业务使用者,把模拟数据理解为实时行情
|
||||
|
||||
建议:
|
||||
- 响应增加 `source: "simulated"`
|
||||
- 前端界面同步标注“模拟/参考数据”
|
||||
|
||||
优先级:**P2**
|
||||
|
||||
### D3. shared/platform 边界仍需继续收敛
|
||||
|
||||
现状:
|
||||
- `shared` 同时承担平台基础能力与部分历史耦合职责
|
||||
- 共享 ORM 与 app factory 仍是主要耦合点
|
||||
|
||||
影响:
|
||||
- 模块边界认知成本较高
|
||||
- 新增逻辑容易继续堆入 shared
|
||||
|
||||
建议:
|
||||
- 继续从文档、目录语义、职责边界上推进收敛
|
||||
- 在后续实际重构中优先避免把业务逻辑继续沉入 shared
|
||||
|
||||
优先级:**P2**
|
||||
|
||||
### D4. 文档现状 / 规划 / 历史混放
|
||||
|
||||
现状:
|
||||
- 文档存在部署说明重叠、计划/总结/权威文档混放
|
||||
- README 承担过多职责
|
||||
|
||||
影响:
|
||||
- 新成员难以判断“哪篇才是当前有效说法”
|
||||
- 状态、部署、规划容易发生漂移
|
||||
|
||||
建议:
|
||||
- 建立 `STATUS / ARCHITECTURE / ROADMAP / DEPLOYMENT` 主骨架
|
||||
- 历史材料迁入 `docs/archive/`
|
||||
|
||||
优先级:**P1**
|
||||
|
||||
---
|
||||
|
||||
## 4. 当前推荐治理顺序
|
||||
|
||||
### 第一优先级
|
||||
1. `advanced_router` 拆分
|
||||
2. 高优先级接口补 Pydantic 请求模型
|
||||
3. 文档主骨架收口并减少重复说明
|
||||
|
||||
### 第二优先级
|
||||
4. 铝价模拟数据来源显式化
|
||||
5. 部署历史文档归档
|
||||
6. shared/platform 语义继续收敛
|
||||
|
||||
---
|
||||
|
||||
## 5. 治理原则
|
||||
|
||||
### 5.1 先收口接口与边界,再做更大结构调整
|
||||
|
||||
当前最值得继续投入的,不是大规模目录重写,而是:
|
||||
- 先把接口边界、文档边界、部署边界收清楚
|
||||
- 再逐步推进 shared/platform 的后续调整
|
||||
|
||||
### 5.2 优先做“降低长期维护成本”的改动
|
||||
|
||||
优先处理:
|
||||
- 重复逻辑
|
||||
- 模糊边界
|
||||
- 静态契约缺失
|
||||
- 文档漂移风险
|
||||
|
||||
### 5.3 已解决问题不再长期占据主文档中心
|
||||
|
||||
已经完成且稳定的问题,只在本文保留摘要结论;详细实施流水账后续归档,不继续作为主文档主体。
|
||||
|
||||
---
|
||||
|
||||
## 6. 与相关文档的边界
|
||||
|
||||
- 当前项目状态:看 [STATUS.md](STATUS.md)
|
||||
- 当前架构与模块边界:看 [ARCHITECTURE.md](ARCHITECTURE.md)
|
||||
- 后续演进路线:看 [ROADMAP.md](ROADMAP.md)
|
||||
- 部署主题入口:看 [DEPLOYMENT.md](DEPLOYMENT.md)
|
||||
- 原始 moldinsight 细粒度债务记录:看 [archive/MOLDINSIGHT_TECH_DEBT_PLAN.md](archive/MOLDINSIGHT_TECH_DEBT_PLAN.md)
|
||||
@@ -0,0 +1,5 @@
|
||||
# geMoldInsight 后端模块化重构蓝图(归档)
|
||||
|
||||
> 文档定位:**模块化设计蓝图档案 / 补充设计材料**。
|
||||
> 当前架构与边界的默认入口见 [../ARCHITECTURE.md](../ARCHITECTURE.md),当前状态见 [../STATUS.md](../STATUS.md),未来演进路线见 [../ROADMAP.md](../ROADMAP.md)。
|
||||
> 本文保留更完整的模块化设计背景、目标与分阶段思考,用于追溯设计决策,不再保留在 `docs/` 顶层作为默认入口。
|
||||
@@ -0,0 +1,7 @@
|
||||
# 铝制家电包装泡沫模具分模功能开发检查清单(归档)
|
||||
|
||||
> 文档定位:**阶段性检查清单 / 历史材料**,不再作为当前权威文档。
|
||||
> 当前项目状态见 [../STATUS.md](../STATUS.md),当前架构边界见 [../ARCHITECTURE.md](../ARCHITECTURE.md),当前活跃技术债见 [../TECH_DEBT.md](../TECH_DEBT.md)。
|
||||
> 若需了解当前模具分析方向,请优先参考主骨架文档,而不是本文的阶段 checklist。
|
||||
|
||||
本文保留的是 2026-03-13 铝泡沫模具分模功能增强时期的检查清单,用于记录当时的开发跟踪方式。
|
||||
@@ -1,5 +1,8 @@
|
||||
# Confluence 归档目录结构(建议)
|
||||
|
||||
> 文档定位:**外部文档归档结构建议稿**。
|
||||
> 本文描述的是面向 Confluence/知识库归档时的目录建议,不作为当前仓库内文档体系的权威说明。当前仓库文档入口见 [../../README.md](../../README.md) 与 [README.md](README.md)。
|
||||
|
||||
## 业务流程
|
||||
|
||||
- 01 端到端流程(客户订单→采购→到货→生产→交付)
|
||||
@@ -0,0 +1,6 @@
|
||||
# 交付物清单(归档)
|
||||
|
||||
> 文档定位:**一次性交付产物索引 / 历史材料**。
|
||||
> 本文记录某轮分析/整改时的交付物集合,不作为当前项目状态或当前文档导航入口。当前默认入口见 [../../README.md](../../README.md),当前状态见 [../STATUS.md](../STATUS.md)。
|
||||
|
||||
保留本文的目的主要是追溯当时的分析交付范围,而不是指导当前项目维护。
|
||||
@@ -0,0 +1,5 @@
|
||||
# geMoldInsight 演进路线图(原始执行记录,归档)
|
||||
|
||||
> 文档定位:**历史路线与执行记录原文 / 归档材料**。
|
||||
> 当前默认路线文档见 [../ROADMAP.md](../ROADMAP.md),当前状态见 [../STATUS.md](../STATUS.md),当前技术债见 [../TECH_DEBT.md](../TECH_DEBT.md)。
|
||||
> 本文保留较细粒度的历史诊断、执行清单与过程记录,仅用于追溯,不再作为顶层默认文档。
|
||||
@@ -0,0 +1,19 @@
|
||||
# 前端独立部署 + 统一后端入口实施计划(归档)
|
||||
|
||||
> 文档定位:**阶段性实施计划 / 历史材料**,不再作为当前部署权威文档。
|
||||
> 当前部署入口见 [../DEPLOYMENT.md](../DEPLOYMENT.md),Linux 详细部署步骤见 [../deployment/LINUX_SETUP.md](../deployment/LINUX_SETUP.md),当前项目状态见 [../STATUS.md](../STATUS.md)。
|
||||
|
||||
本文保留的是一次针对“前端独立部署 + unified backend”方向的实施计划,用于记录当时的设计思路与迁移目标。
|
||||
|
||||
当前项目的默认阅读方式已经调整为:
|
||||
- 部署主题入口: [../DEPLOYMENT.md](../DEPLOYMENT.md)
|
||||
- 当前推荐方案与当前事实: [../STATUS.md](../STATUS.md)
|
||||
- 架构边界: [../ARCHITECTURE.md](../ARCHITECTURE.md)
|
||||
|
||||
如果你正在查找**当前有效的部署方式**,请不要以本文作为默认依据,而应优先参考上述主文档。
|
||||
|
||||
---
|
||||
|
||||
# 原始内容
|
||||
|
||||
> 目标:在已经切换到“前端独立部署 + 同域反代”的基础上,进一步取消前端 Nginx 对 `/api` 的路径级分流,改为反代到一个真正的 **unified backend**,一次性解决长期维护成本。
|
||||
@@ -0,0 +1,5 @@
|
||||
# moldinsight 模块技术债务分析与重构计划(原始记录,归档)
|
||||
|
||||
> 文档定位:**moldinsight 技术债原始分析与实施记录 / 归档材料**。
|
||||
> 当前默认技术债文档见 [../TECH_DEBT.md](../TECH_DEBT.md),当前状态见 [../STATUS.md](../STATUS.md)。
|
||||
> 本文保留更细粒度的问题清单、实施记录与阶段性说明,仅用于追溯,不再作为顶层默认文档。
|
||||
@@ -1,5 +1,8 @@
|
||||
# 模具制造进销存核心模块分析报告(代码基线:geMoldInsight)
|
||||
|
||||
> 文档定位:**业务分析/审计型报告文档**。
|
||||
> 本文保留一次特定分析基线下的观察结论与流程梳理,不作为当前项目状态或当前架构的权威说明。当前状态见 [../STATUS.md](../STATUS.md),当前架构见 [../ARCHITECTURE.md](../ARCHITECTURE.md),演进路线见 [../ROADMAP.md](../ROADMAP.md)。
|
||||
|
||||
## 0. 范围与术语映射
|
||||
|
||||
- 客户订单(Customer Order):本仓库实现为 SalesOrder(销售订单),其业务语义更贴近“模具订单/按单生产订单”。对应表:`sales_orders`、`sales_order_items`。
|
||||
@@ -0,0 +1,22 @@
|
||||
# 端口配置历史说明(归档)
|
||||
|
||||
> 文档定位:**历史迁移说明 / 不再作为当前部署权威文档**。
|
||||
> 当前部署入口见 [../DEPLOYMENT.md](../DEPLOYMENT.md),Linux 详细部署步骤见 [../deployment/LINUX_SETUP.md](../deployment/LINUX_SETUP.md)。
|
||||
|
||||
本文件保留为历史说明。
|
||||
|
||||
它所描述的“单体应用单一端口配置”思路,已经不再能完整代表当前 geMoldInsight 的模块化架构。
|
||||
|
||||
当前项目已演进为:
|
||||
|
||||
- gemold 模块可独立部署
|
||||
- inventory 模块可独立部署
|
||||
- unified 作为组合模式存在
|
||||
- gemold 与 inventory 应分别考虑端口与网关暴露方式
|
||||
|
||||
因此,端口配置的当前权威说明已转移到以下文档:
|
||||
|
||||
- [../DEPLOYMENT.md](../DEPLOYMENT.md)
|
||||
- [../deployment/LINUX_SETUP.md](../deployment/LINUX_SETUP.md)
|
||||
- [../deployment/DEPLOY_PORT.md](../deployment/DEPLOY_PORT.md)
|
||||
- [../deployment/PORT_CONFIG.md](../deployment/PORT_CONFIG.md)
|
||||
@@ -0,0 +1,21 @@
|
||||
# 文档归档说明(archive)
|
||||
|
||||
> 文档定位:**历史文档与阶段性材料归档目录**。
|
||||
> 当前权威文档请优先查看:
|
||||
> - [../STATUS.md](../STATUS.md)
|
||||
> - [../ARCHITECTURE.md](../ARCHITECTURE.md)
|
||||
> - [../ROADMAP.md](../ROADMAP.md)
|
||||
> - [../TECH_DEBT.md](../TECH_DEBT.md)
|
||||
> - [../DEPLOYMENT.md](../DEPLOYMENT.md)
|
||||
|
||||
本目录用于存放:
|
||||
- 历史迁移说明
|
||||
- 阶段性实施计划
|
||||
- 已不再作为默认入口的旧文档
|
||||
|
||||
当前已归档:
|
||||
- [PORT_REFACTOR_SUMMARY.md](PORT_REFACTOR_SUMMARY.md)
|
||||
- [FRONTEND_UNIFIED_DEPLOYMENT_PLAN.md](FRONTEND_UNIFIED_DEPLOYMENT_PLAN.md)
|
||||
- [TASKS_ALUMINUM_FOAM_MOLD.md](TASKS_ALUMINUM_FOAM_MOLD.md)
|
||||
- [CHECKLIST_ALUMINUM_FOAM_MOLD.md](CHECKLIST_ALUMINUM_FOAM_MOLD.md)
|
||||
- [DELIVERABLES.md](DELIVERABLES.md)
|
||||
@@ -0,0 +1,7 @@
|
||||
# 铝制家电包装泡沫模具分模功能开发任务清单(归档)
|
||||
|
||||
> 文档定位:**阶段性任务清单 / 历史材料**,不再作为当前权威文档。
|
||||
> 当前项目状态见 [../STATUS.md](../STATUS.md),当前架构边界见 [../ARCHITECTURE.md](../ARCHITECTURE.md),当前活跃技术债见 [../TECH_DEBT.md](../TECH_DEBT.md)。
|
||||
> 若需了解当前模具分析方向,请优先参考主骨架文档,而不是本文的阶段任务分解。
|
||||
|
||||
本文保留的是 2026-03-13 铝泡沫模具分模功能增强时期的任务拆解,用于记录当时的实施计划与阶段安排。
|
||||
+3
@@ -1,5 +1,8 @@
|
||||
# “零成品库存”证明报告(geMoldInsight)
|
||||
|
||||
> 文档定位:**特定业务口径下的专题证明/分析报告**。
|
||||
> 本文解释“零成品库存”这一业务与财务口径,不作为当前项目整体状态的权威说明。当前状态见 [../STATUS.md](../STATUS.md),相关业务分析见 [MOLD_ERP_ANALYSIS_REPORT.md](MOLD_ERP_ANALYSIS_REPORT.md)。
|
||||
|
||||
## 1. 结论
|
||||
|
||||
系统不设置成品入库、成品出库、销售退货等成品库存模块;系统库存口径仅覆盖“物料(material)”,成品(finished/模具)仅作为订单交付对象,不进入库存核算链路。
|
||||
@@ -1,5 +1,7 @@
|
||||
# 模块化部署端口说明
|
||||
|
||||
> 文档定位:**当前部署下的端口规划补充说明**。
|
||||
> 部署入口与当前推荐方案见 [../DEPLOYMENT.md](../DEPLOYMENT.md),Linux 部署步骤见 [LINUX_SETUP.md](LINUX_SETUP.md)。
|
||||
> 本文档描述的是 **当前模块化部署模式** 下的端口规划,不再以历史单体 `src.main:app` 作为默认前提。
|
||||
|
||||
当前推荐部署对象:
|
||||
@@ -128,7 +130,7 @@ VITE_INVENTORY_API_BASE_URL=https://inventory.example.com
|
||||
```
|
||||
|
||||
当前详细策略见:
|
||||
- [BACKEND_MODULARIZATION_BLUEPRINT.md](../BACKEND_MODULARIZATION_BLUEPRINT.md)
|
||||
- [archive/BACKEND_MODULARIZATION_BLUEPRINT.md](../archive/BACKEND_MODULARIZATION_BLUEPRINT.md)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# geMoldInsight Linux 部署指南
|
||||
|
||||
> 本文档描述的是 **当前模块化架构** 下的 Linux 部署方式,而不是历史单体 `src.main:app` 方案。
|
||||
> 文档定位:**Linux 环境下的详细部署操作文档**。
|
||||
> 当前部署主题入口见 [../DEPLOYMENT.md](../DEPLOYMENT.md),当前项目状态见 [../STATUS.md](../STATUS.md),当前架构边界见 [../ARCHITECTURE.md](../ARCHITECTURE.md)。
|
||||
> 本文档描述的是 **当前模块化架构** 下的 Linux 部署方式,而不是历史单体入口方案。
|
||||
|
||||
当前项目支持三种部署模式:
|
||||
|
||||
@@ -17,7 +19,7 @@
|
||||
- **复用服务器上已存在的 PostgreSQL / Redis / RustFS(或 MinIO 兼容存储)**
|
||||
|
||||
详细架构蓝图见:
|
||||
- [BACKEND_MODULARIZATION_BLUEPRINT.md](../BACKEND_MODULARIZATION_BLUEPRINT.md)
|
||||
- [archive/BACKEND_MODULARIZATION_BLUEPRINT.md](../archive/BACKEND_MODULARIZATION_BLUEPRINT.md)
|
||||
|
||||
---
|
||||
|
||||
@@ -192,12 +194,12 @@ celery -A src.celery_app.celery_app worker --loglevel=info
|
||||
|
||||
## 6.3 unified
|
||||
|
||||
当前仓库仍保留历史统一入口 [main.py](../../src/main.py),但它更适合作为**过渡参考**,不建议作为长期标准入口。
|
||||
当前仓库历史上存在过统一入口,但它更适合作为**过渡参考**,不建议再作为长期标准入口。
|
||||
|
||||
在正式完成组合层重构前,如需统一部署,可优先使用反向代理或部署编排层统一暴露 gemold 与 inventory;后续会演进为显式 `unified_app.py`。
|
||||
|
||||
蓝图参考:
|
||||
- [BACKEND_MODULARIZATION_BLUEPRINT.md](../BACKEND_MODULARIZATION_BLUEPRINT.md)
|
||||
- [archive/BACKEND_MODULARIZATION_BLUEPRINT.md](../archive/BACKEND_MODULARIZATION_BLUEPRINT.md)
|
||||
|
||||
---
|
||||
|
||||
@@ -421,6 +423,6 @@ docker compose --profile full up -d
|
||||
## 12. 推荐阅读
|
||||
|
||||
- [README.md](../../README.md)
|
||||
- [BACKEND_MODULARIZATION_BLUEPRINT.md](../BACKEND_MODULARIZATION_BLUEPRINT.md)
|
||||
- [archive/BACKEND_MODULARIZATION_BLUEPRINT.md](../archive/BACKEND_MODULARIZATION_BLUEPRINT.md)
|
||||
- [DEPLOY_PORT.md](./DEPLOY_PORT.md)
|
||||
- [PORT_CONFIG.md](./PORT_CONFIG.md)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# 端口配置说明(模块化架构)
|
||||
|
||||
> 文档定位:**模块化部署下的端口与环境变量配置补充说明**。
|
||||
> 当前部署主题入口见 [../DEPLOYMENT.md](../DEPLOYMENT.md),详细 Linux 部署步骤见 [LINUX_SETUP.md](LINUX_SETUP.md)。
|
||||
> 本文档说明当前 geMoldInsight 在**模块化部署**下的端口配置方式。
|
||||
|
||||
当前架构中应区分:
|
||||
@@ -174,5 +176,5 @@ Compose 通过端口映射暴露服务:
|
||||
|
||||
- [LINUX_SETUP.md](./LINUX_SETUP.md)
|
||||
- [DEPLOY_PORT.md](./DEPLOY_PORT.md)
|
||||
- [BACKEND_MODULARIZATION_BLUEPRINT.md](../BACKEND_MODULARIZATION_BLUEPRINT.md)
|
||||
- [archive/BACKEND_MODULARIZATION_BLUEPRINT.md](../archive/BACKEND_MODULARIZATION_BLUEPRINT.md)
|
||||
- [README.md](../../README.md)
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
# 端口配置历史说明(已被模块化部署文档取代)
|
||||
|
||||
本文件保留为历史说明。
|
||||
|
||||
它所描述的“单体应用单一端口配置”思路,已经不再能完整代表当前 geMoldInsight 的模块化架构。
|
||||
|
||||
当前项目已演进为:
|
||||
|
||||
- gemold 模块可独立部署
|
||||
- inventory 模块可独立部署
|
||||
- unified 作为组合模式存在
|
||||
- gemold 与 inventory 应分别考虑端口与网关暴露方式
|
||||
|
||||
因此,端口配置的权威说明已转移到以下文档:
|
||||
|
||||
- [LINUX_SETUP.md](./LINUX_SETUP.md)
|
||||
- [DEPLOY_PORT.md](./DEPLOY_PORT.md)
|
||||
- [PORT_CONFIG.md](./PORT_CONFIG.md)
|
||||
- [BACKEND_MODULARIZATION_BLUEPRINT.md](../BACKEND_MODULARIZATION_BLUEPRINT.md)
|
||||
|
||||
---
|
||||
|
||||
## 当前结论
|
||||
|
||||
1. 不再默认以历史单体 `src.main:app` 作为部署中心。
|
||||
2. 不再假设整个系统只有一个后端端口。
|
||||
3. gemold 与 inventory 应按模块分别规划端口。
|
||||
4. unified 更适合通过组合层或网关统一暴露,而不是继续沿用旧单体部署语义。
|
||||
|
||||
---
|
||||
|
||||
## 建议
|
||||
|
||||
如果你正在查找当前有效的端口/部署方式,请不要继续参考旧的单体端口说明,而应直接查看:
|
||||
|
||||
- [README.md](../../README.md)
|
||||
- [LINUX_SETUP.md](./LINUX_SETUP.md)
|
||||
- [DEPLOY_PORT.md](./DEPLOY_PORT.md)
|
||||
- [PORT_CONFIG.md](./PORT_CONFIG.md)
|
||||
+3
@@ -1,5 +1,8 @@
|
||||
# 外部接口与集成盘点模板(ERP/财务/供应商门户/客户门户)
|
||||
|
||||
> 文档定位:**接口梳理与集成盘点模板文档**。
|
||||
> 本文是用于外部系统对接时的模板,不作为当前项目状态或当前接口实现清单的权威说明。当前状态见 [../STATUS.md](../STATUS.md),当前架构见 [../ARCHITECTURE.md](../ARCHITECTURE.md)。
|
||||
|
||||
## 1. 接口清单
|
||||
|
||||
| 接口名称 | 调用方向 | 协议 | 鉴权 | 频率 | 单次数据量 | 幂等键 | 超时 | 重试策略 | 死信/补偿 | 负责人 |
|
||||
@@ -1,5 +1,8 @@
|
||||
# UAT 验收清单(模具制造进销存主线)
|
||||
|
||||
> 文档定位:**UAT 验收模板 / 验收过程文档**。
|
||||
> 本文用于业务验收与签字过程,不作为当前项目状态或当前架构的权威说明。当前状态见 [../STATUS.md](../STATUS.md),当前架构见 [../ARCHITECTURE.md](../ARCHITECTURE.md)。
|
||||
|
||||
## 1. 业务流程签字
|
||||
|
||||
| 模块 | 场景 | 验收点 | 结果 | 业务签字 | 日期 |
|
||||
@@ -1,5 +1,7 @@
|
||||
# AI 智能引擎设计文档
|
||||
|
||||
> 文档定位:**AI 能力方向的设计性/专题性文档**。
|
||||
> 本文描述的是 AI 引擎的设计设想与能力规划,不作为当前实现状态的权威说明。当前状态见 [../../STATUS.md](../../STATUS.md),当前架构边界见 [../../ARCHITECTURE.md](../../ARCHITECTURE.md),后续路线见 [../../ROADMAP.md](../../ROADMAP.md)。
|
||||
## 一、AI 引擎架构
|
||||
|
||||
### 1.1 整体架构
|
||||
@@ -1,5 +1,7 @@
|
||||
# AI + FreeCAD 集成方案
|
||||
|
||||
> 文档定位:**AI / FreeCAD 集成方向的专题设计文档**。
|
||||
> 本文描述的是集成设想、能力规划与差距分析,不作为当前实现状态的权威说明。当前状态见 [../../STATUS.md](../../STATUS.md),当前架构边界见 [../../ARCHITECTURE.md](../../ARCHITECTURE.md),后续路线见 [../../ROADMAP.md](../../ROADMAP.md)。
|
||||
## 一、项目概述
|
||||
|
||||
本文档描述 geMoldInsight 项目集成 AI 智能引擎和 FreeCAD 的完整方案,实现真实的模具型腔生成和 G 代码输出功能。
|
||||
@@ -1,5 +1,8 @@
|
||||
# 铝制家电包装泡沫模具分模功能技术规格说明书
|
||||
|
||||
> 文档定位:**铝泡沫模具分模方向的专题规格文档**。
|
||||
> 本文保留该方向的需求背景、规格设想与能力边界,不作为当前项目整体状态的权威说明。当前状态见 [../../STATUS.md](../../STATUS.md),总体架构见 [../../ARCHITECTURE.md](../../ARCHITECTURE.md),活跃技术债见 [../../TECH_DEBT.md](../../TECH_DEBT.md)。
|
||||
|
||||
## 文档信息
|
||||
|
||||
| 项目 | 内容 |
|
||||
@@ -1,5 +1,7 @@
|
||||
# 性能基准定义(建议)
|
||||
|
||||
> 文档定位:**性能基准与压测口径的专题参考文档**。
|
||||
> 本文给出建议性性能指标与测试数据口径,不作为当前实现状态的权威说明。当前状态见 [../../STATUS.md](../../STATUS.md),后续路线见 [../../ROADMAP.md](../../ROADMAP.md)。
|
||||
## 1. 核心接口基准
|
||||
|
||||
| 场景 | 接口 | 指标 |
|
||||
+2
@@ -1,5 +1,7 @@
|
||||
# 性能与扩展性评估补充(模具订单/采购主线)
|
||||
|
||||
> 文档定位:**性能与扩展性方向的专题规划文档**。
|
||||
> 本文描述的是性能评估、慢 SQL 发现、扩展路线等补充规划,不作为当前实现状态的权威说明。当前状态见 [../../STATUS.md](../../STATUS.md),后续路线见 [../../ROADMAP.md](../../ROADMAP.md)。
|
||||
## 1. 高并发冲突面与加固点
|
||||
|
||||
### 1.1 新增/修改模具订单的锁冲突来源
|
||||
@@ -1,5 +1,7 @@
|
||||
# RustFS 对象存储集成说明
|
||||
|
||||
> 文档定位:**RustFS / 对象存储集成的专题说明文档**。
|
||||
> 本文解释对象存储侧的接口与集成思路,不作为当前部署入口文档。当前部署方式见 [../../DEPLOYMENT.md](../../DEPLOYMENT.md) 与 [../../deployment/LINUX_SETUP.md](../../deployment/LINUX_SETUP.md),当前状态见 [../../STATUS.md](../../STATUS.md)。
|
||||
## 架构概述
|
||||
|
||||
本项目采用 **RustFS** 作为对象存储和 **PostgreSQL** 作为元数据存储的双层存储架构。
|
||||
@@ -1,6 +1,8 @@
|
||||
# 存储架构说明
|
||||
|
||||
> 本文档主要解释 geMoldInsight 的存储分层与数据流。其历史中的“本项目自行拉起 PostgreSQL / MinIO 并通过 `python src/main.py` 启动单体”的部分,**已不再代表当前默认部署方式**。
|
||||
> 文档定位:**存储分层与数据流的专题说明文档**。
|
||||
> 本文主要解释 geMoldInsight 的存储架构,不作为当前部署入口或当前状态的权威说明。当前部署方式见 [../../DEPLOYMENT.md](../../DEPLOYMENT.md),当前状态见 [../../STATUS.md](../../STATUS.md),总体架构见 [../../ARCHITECTURE.md](../../ARCHITECTURE.md)。
|
||||
> 其历史中的“本项目自行拉起 PostgreSQL / MinIO 并通过 `python src/main.py` 启动单体”的部分,**已不再代表当前默认部署方式**。
|
||||
|
||||
当前默认部署前提是:
|
||||
|
||||
@@ -10,10 +12,10 @@
|
||||
- 项目自身只部署:`moldinsight` / `moldinsight-celery` / `inventory`
|
||||
|
||||
如需查看当前部署方式,请优先参考:
|
||||
- [README.md](../README.md)
|
||||
- [LINUX_SETUP.md](./deployment/LINUX_SETUP.md)
|
||||
- [DEPLOY_PORT.md](./deployment/DEPLOY_PORT.md)
|
||||
- [BACKEND_MODULARIZATION_BLUEPRINT.md](./BACKEND_MODULARIZATION_BLUEPRINT.md)
|
||||
- [../../../README.md](../../../README.md)
|
||||
- [../../deployment/LINUX_SETUP.md](../../deployment/LINUX_SETUP.md)
|
||||
- [../../deployment/DEPLOY_PORT.md](../../deployment/DEPLOY_PORT.md)
|
||||
- [../../archive/BACKEND_MODULARIZATION_BLUEPRINT.md](../../archive/BACKEND_MODULARIZATION_BLUEPRINT.md)
|
||||
|
||||
---
|
||||
|
||||
@@ -110,13 +112,13 @@ RUSTFS_SECRET_KEY=change-me
|
||||
### 2. 初始化数据库
|
||||
|
||||
当前初始化入口参考:
|
||||
- [init_db.py](../src/shared/database/init_db.py)
|
||||
- [init_db.py](../../../src/shared/database/init_db.py)
|
||||
|
||||
### 3. 启动项目服务
|
||||
|
||||
当前推荐通过:
|
||||
- [docker-compose.yml](../docker-compose.yml)
|
||||
- 或 [src/entrypoints/](../src/entrypoints/)
|
||||
- [docker-compose.yml](../../../docker-compose.yml)
|
||||
- 或 [src/entrypoints/](../../../src/entrypoints/)
|
||||
|
||||
而不是继续使用历史单体 `python src/main.py` 作为默认方式。
|
||||
|
||||
@@ -170,7 +170,7 @@ def test_parting_line_calculation():
|
||||
generator = MoldCavityGenerator()
|
||||
|
||||
# 计算分型线
|
||||
parting_line = generator._calculate_parting_line(box, parting_surface)
|
||||
parting_line = generator.calculate_parting_line(box, parting_surface)
|
||||
|
||||
print(f"✓ 分型线计算完成")
|
||||
print(f" - 点数:{len(parting_line)}")
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"""
|
||||
|
||||
from typing import Dict, List, Any, Tuple, Optional
|
||||
import warnings
|
||||
import numpy as np
|
||||
from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeFace
|
||||
from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox
|
||||
@@ -55,13 +56,11 @@ class AluminumFoamMoldGenerator(BaseMoldGenerator):
|
||||
|
||||
self.foam_material = foam_material
|
||||
|
||||
self.parting_line_tolerance = 0.1
|
||||
self.max_draft_angle = 5.0
|
||||
self.min_draft_angle = 1.0
|
||||
|
||||
self.cavity_count = 1
|
||||
self.parting_precision = 0.1
|
||||
self.cavity_match_rate = 95.0
|
||||
self.side_action_designer = SideActionDesigner()
|
||||
|
||||
def set_foam_material(self, material: str):
|
||||
@@ -89,7 +88,7 @@ class AluminumFoamMoldGenerator(BaseMoldGenerator):
|
||||
|
||||
def generate_mold_cavities(self, product_shape: TopoDS_Shape) -> Dict[str, Any]:
|
||||
"""
|
||||
从产品的3D模型生成型腔和型芯
|
||||
[已废弃] 单方案分模入口。生产路径请使用 MultiSchemeMoldPlanner.generate_plan。
|
||||
|
||||
完整流程:
|
||||
1. 分析产品几何
|
||||
@@ -100,10 +99,15 @@ class AluminumFoamMoldGenerator(BaseMoldGenerator):
|
||||
6. 分离型腔和型芯
|
||||
7. 生成模具块
|
||||
"""
|
||||
warnings.warn(
|
||||
"generate_mold_cavities 已废弃,请改用 MultiSchemeMoldPlanner.generate_plan 生成多方案分模结果",
|
||||
DeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
logger.info(f"开始生成铝泡沫模具型腔 (材料: {self.foam_material})...")
|
||||
|
||||
try:
|
||||
analysis = self._analyze_product_geometry(product_shape)
|
||||
analysis = self.analyze_product_geometry(product_shape)
|
||||
|
||||
parting_result = self._detect_parting_surfaces(product_shape, analysis)
|
||||
primary_parting_surface = parting_result["primary_surface"]
|
||||
@@ -113,20 +117,20 @@ class AluminumFoamMoldGenerator(BaseMoldGenerator):
|
||||
side_action_result = self.side_action_designer.analyze_and_design(
|
||||
shape=product_shape,
|
||||
parting_direction=primary_parting_direction,
|
||||
mold_size=self._calculate_mold_size(analysis),
|
||||
mold_size=self.calculate_mold_size(analysis),
|
||||
parting_surface=primary_parting_surface,
|
||||
)
|
||||
undercut_regions = self._build_undercut_regions(
|
||||
undercut_regions = self.build_undercut_regions(
|
||||
side_action_result.get("undercut_analysis", {})
|
||||
)
|
||||
|
||||
scaled_shape = self._apply_shrinkage_compensation(product_shape)
|
||||
scaled_shape = self.apply_shrinkage_compensation(product_shape)
|
||||
|
||||
drafted_shape = self._apply_draft_angles(scaled_shape, primary_parting_surface)
|
||||
drafted_shape = self.apply_draft_angles(scaled_shape, primary_parting_surface)
|
||||
|
||||
cavity, core = self._split_cavity_core(drafted_shape, primary_parting_surface)
|
||||
cavity, core = self.split_cavity_core(drafted_shape, primary_parting_surface)
|
||||
|
||||
mold_block = self._generate_mold_block(cavity, analysis)
|
||||
mold_block = self.generate_mold_block(cavity, analysis)
|
||||
|
||||
smoothed_parting_line = self._smooth_parting_line(primary_parting_line)
|
||||
|
||||
@@ -187,7 +191,7 @@ class AluminumFoamMoldGenerator(BaseMoldGenerator):
|
||||
},
|
||||
"parting_surface": parting_geometry,
|
||||
"manufacturing_info": {
|
||||
"estimated_mold_size": self._calculate_mold_size(analysis),
|
||||
"estimated_mold_size": self.calculate_mold_size(analysis),
|
||||
"estimated_clamping_force": self._calculate_clamping_force(analysis),
|
||||
"clamping_force_formula": "投影面积(cm²) × 0.3 (泡沫材料系数)",
|
||||
"recommended_material": material_info.get("description", "Aluminum Foam Mold"),
|
||||
@@ -251,9 +255,9 @@ class AluminumFoamMoldGenerator(BaseMoldGenerator):
|
||||
|
||||
# ==================== 核心算法实现 ====================
|
||||
|
||||
def _analyze_product_geometry(self, shape: TopoDS_Shape) -> Dict[str, Any]:
|
||||
def analyze_product_geometry(self, shape: TopoDS_Shape) -> Dict[str, Any]:
|
||||
"""分析产品几何属性(扩展基类版本,增加法向量统计)"""
|
||||
result = super()._analyze_product_geometry(shape)
|
||||
result = super().analyze_product_geometry(shape)
|
||||
result["normal_statistics"] = self._analyze_parting_direction(shape)
|
||||
return result
|
||||
|
||||
@@ -266,7 +270,7 @@ class AluminumFoamMoldGenerator(BaseMoldGenerator):
|
||||
face = topods.Face(explorer.Current())
|
||||
explorer.Next()
|
||||
try:
|
||||
normal = self._get_face_normal(face)
|
||||
normal = self.get_face_normal(face)
|
||||
if normal is None:
|
||||
continue
|
||||
props = GProp_GProps()
|
||||
@@ -287,9 +291,9 @@ class AluminumFoamMoldGenerator(BaseMoldGenerator):
|
||||
for axis, value in stats.items()
|
||||
}
|
||||
|
||||
def _split_cavity_core(self, shape: TopoDS_Shape, parting_surface: TopoDS_Face) -> Tuple[TopoDS_Shape, TopoDS_Shape]:
|
||||
def split_cavity_core(self, shape: TopoDS_Shape, parting_surface: TopoDS_Face) -> Tuple[TopoDS_Shape, TopoDS_Shape]:
|
||||
"""分离型腔和型芯(铝泡沫使用更大余量)"""
|
||||
return super()._split_cavity_core(shape, parting_surface, margin=25)
|
||||
return super().split_cavity_core(shape, parting_surface, margin=25)
|
||||
|
||||
def _detect_parting_surfaces(self, shape: TopoDS_Shape, analysis: Dict) -> Dict[str, Any]:
|
||||
"""
|
||||
@@ -317,7 +321,7 @@ class AluminumFoamMoldGenerator(BaseMoldGenerator):
|
||||
logger.info(f"泡沫模具 Z 轴分型面: Z={parting_z:.2f} mm (包围盒中心)")
|
||||
|
||||
parting_line = self.optimize_parting_line(
|
||||
self._calculate_parting_line(shape, parting_surface)
|
||||
self.calculate_parting_line(shape, parting_surface)
|
||||
)
|
||||
|
||||
additional_surfaces = []
|
||||
@@ -352,7 +356,7 @@ class AluminumFoamMoldGenerator(BaseMoldGenerator):
|
||||
"parting_position_z": parting_z,
|
||||
}
|
||||
|
||||
def _build_undercut_regions(self, undercut_analysis: Dict[str, Any]) -> List[Dict[str, Any]]:
|
||||
def build_undercut_regions(self, undercut_analysis: Dict[str, Any]) -> List[Dict[str, Any]]:
|
||||
"""将侧向机构分析结果转换为兼容旧结构的倒扣区域列表。"""
|
||||
undercut_faces = undercut_analysis.get("undercut_faces", [])
|
||||
regions = []
|
||||
@@ -429,7 +433,7 @@ class AluminumFoamMoldGenerator(BaseMoldGenerator):
|
||||
|
||||
except Exception:
|
||||
return 50.0
|
||||
def _generate_mold_block(self, cavity: TopoDS_Shape, analysis: Dict) -> TopoDS_Shape:
|
||||
def generate_mold_block(self, cavity: TopoDS_Shape, analysis: Dict) -> TopoDS_Shape:
|
||||
"""生成完整的模具块(包含A/B板结构)"""
|
||||
try:
|
||||
bbox = analysis["bounding_box"]
|
||||
@@ -464,7 +468,7 @@ class AluminumFoamMoldGenerator(BaseMoldGenerator):
|
||||
|
||||
# ==================== 辅助方法 ====================
|
||||
|
||||
def _calculate_mold_size(self, analysis: Dict) -> Dict[str, float]:
|
||||
def calculate_mold_size(self, analysis: Dict) -> Dict[str, float]:
|
||||
"""估算模具尺寸"""
|
||||
dims = analysis["bounding_box"]["dimensions"]
|
||||
margin = 30
|
||||
|
||||
@@ -25,15 +25,60 @@ logger = get_logger(__name__)
|
||||
|
||||
|
||||
class BaseMoldGenerator:
|
||||
"""模具生成器基类 - 提供共用方法"""
|
||||
"""模具生成器基类 - 提供共用方法
|
||||
|
||||
公共接口契约(MultiSchemeMoldPlanner 及上层服务依赖,子类覆写时必须保持签名稳定):
|
||||
- analyze_product_geometry(shape) -> 几何分析结果 dict
|
||||
- calculate_parting_line(shape, parting_surface) -> 分型线点列
|
||||
- calculate_mold_size(analysis) -> 模具尺寸估算 dict
|
||||
- build_undercut_regions(undercut_analysis) -> 倒扣区域列表
|
||||
- apply_shrinkage_compensation(shape) / apply_draft_angles(shape, parting_surface) -> 形状
|
||||
- split_cavity_core(shape, parting_surface) -> (cavity, core)
|
||||
- create_mold_block(analysis, margin) -> 模具包围盒形状
|
||||
- split_mold_block_by_plane(mold_block, parting_plane) -> (a_plate, b_plate)
|
||||
- get_parting_plane(parting_surface, shape) -> gp_Pln
|
||||
- get_face_normal(face) -> gp_Dir
|
||||
- apply_process_params(material, process_params) -> None
|
||||
- generate_mold_block(cavity, analysis):仅泡沫类生成器实现
|
||||
- set_material / generate_detailed_cavity_json / generate_cavity_key_info / side_action_designer
|
||||
|
||||
generate_mold_cavities 为已废弃的单方案入口,生产路径走 MultiSchemeMoldPlanner.generate_plan。
|
||||
"""
|
||||
|
||||
def __init__(self, shrinkage_rate: float = 0.005, draft_angle: float = 2.0,
|
||||
material_density: float = 1.05):
|
||||
self.shrinkage_rate = shrinkage_rate
|
||||
self.draft_angle = draft_angle
|
||||
self.material_density = material_density
|
||||
self.parting_line_tolerance = 0.1
|
||||
self.cavity_match_rate = 95.0
|
||||
|
||||
def _apply_shrinkage_compensation(self, shape: TopoDS_Shape) -> TopoDS_Shape:
|
||||
def apply_process_params(
|
||||
self,
|
||||
material: Dict[str, Any],
|
||||
process_params: Optional[Dict[str, Any]] = None,
|
||||
) -> None:
|
||||
"""按用户工艺参数覆盖生成器参数,未指定的项取材料默认值或当前值。
|
||||
|
||||
material 为 MaterialService.get_material() 返回的材料属性 dict;
|
||||
process_params 支持 draft_angle / shrinkage_rate(百分数) / parting_precision / cavity_match。
|
||||
"""
|
||||
params = process_params or {}
|
||||
draft_angle = float(params.get("draft_angle", getattr(self, "draft_angle", 2.0)))
|
||||
shrinkage_rate = float(params.get("shrinkage_rate", material.get("shrinkage", 0.005) * 100.0)) / 100.0
|
||||
parting_precision = float(params.get("parting_precision", getattr(self, "parting_line_tolerance", 0.1)))
|
||||
cavity_match = float(params.get("cavity_match", getattr(self, "cavity_match_rate", 95.0)))
|
||||
|
||||
self.draft_angle = draft_angle
|
||||
self.shrinkage_rate = shrinkage_rate
|
||||
self.parting_line_tolerance = parting_precision
|
||||
self.cavity_match_rate = cavity_match
|
||||
|
||||
def generate_mold_block(self, cavity: TopoDS_Shape, analysis: Dict) -> TopoDS_Shape:
|
||||
"""生成完整模具块(A/B板结构)。仅泡沫类生成器实现,基类不提供默认。"""
|
||||
raise NotImplementedError("generate_mold_block 仅由泡沫模具生成器实现")
|
||||
|
||||
def apply_shrinkage_compensation(self, shape: TopoDS_Shape) -> TopoDS_Shape:
|
||||
scale_factor = 1.0 + self.shrinkage_rate
|
||||
trsf = gp_Trsf()
|
||||
trsf.SetScale(gp_Pnt(0, 0, 0), scale_factor)
|
||||
@@ -45,7 +90,7 @@ class BaseMoldGenerator:
|
||||
logger.warning(f"收缩率补偿失败: {e}")
|
||||
return shape
|
||||
|
||||
def _apply_draft_angles(self, shape: TopoDS_Shape, parting_surface: TopoDS_Face) -> TopoDS_Shape:
|
||||
def apply_draft_angles(self, shape: TopoDS_Shape, parting_surface: TopoDS_Face) -> TopoDS_Shape:
|
||||
try:
|
||||
draft_direction = self._get_draft_direction(parting_surface)
|
||||
if draft_direction is None:
|
||||
@@ -78,7 +123,7 @@ class BaseMoldGenerator:
|
||||
return gp_Dir(0, 0, 1)
|
||||
|
||||
@staticmethod
|
||||
def _create_mold_block(analysis: Dict, margin: float = 30.0) -> TopoDS_Shape:
|
||||
def create_mold_block(analysis: Dict, margin: float = 30.0) -> TopoDS_Shape:
|
||||
"""基于产品边界框创建模具包围盒(用于切分 A/B 半模等可视化用途)。"""
|
||||
bbox = analysis.get("bounding_box", {})
|
||||
dims = bbox.get("dimensions", [100, 100, 100])
|
||||
@@ -95,7 +140,7 @@ class BaseMoldGenerator:
|
||||
|
||||
while explorer.More():
|
||||
face = topods.Face(explorer.Current())
|
||||
normal = self._get_face_normal(face)
|
||||
normal = self.get_face_normal(face)
|
||||
|
||||
if normal is not None:
|
||||
dot = abs(normal.Dot(draft_direction))
|
||||
@@ -107,7 +152,7 @@ class BaseMoldGenerator:
|
||||
|
||||
return draftable
|
||||
|
||||
def _get_face_normal(self, face: TopoDS_Face) -> Optional[gp_Dir]:
|
||||
def get_face_normal(self, face: TopoDS_Face) -> Optional[gp_Dir]:
|
||||
try:
|
||||
surface = BRepAdaptor_Surface(face)
|
||||
u = (surface.FirstUParameter() + surface.LastUParameter()) / 2
|
||||
@@ -133,7 +178,7 @@ class BaseMoldGenerator:
|
||||
|
||||
for face in faces:
|
||||
try:
|
||||
normal = self._get_face_normal(face)
|
||||
normal = self.get_face_normal(face)
|
||||
if normal is None:
|
||||
continue
|
||||
|
||||
@@ -168,7 +213,7 @@ class BaseMoldGenerator:
|
||||
for face in faces:
|
||||
try:
|
||||
draft = BRepOffsetAPI_DraftAngle(current_shape)
|
||||
normal = self._get_face_normal(face)
|
||||
normal = self.get_face_normal(face)
|
||||
if normal is None:
|
||||
continue
|
||||
|
||||
@@ -194,7 +239,7 @@ class BaseMoldGenerator:
|
||||
|
||||
return current_shape
|
||||
|
||||
def _analyze_product_geometry(self, shape: TopoDS_Shape) -> Dict[str, Any]:
|
||||
def analyze_product_geometry(self, shape: TopoDS_Shape) -> Dict[str, Any]:
|
||||
try:
|
||||
props = GProp_GProps()
|
||||
brepgprop.VolumeProperties(shape, props)
|
||||
@@ -228,7 +273,7 @@ class BaseMoldGenerator:
|
||||
logger.error(f"产品几何分析失败: {e}")
|
||||
raise
|
||||
|
||||
def _split_cavity_core(self, shape: TopoDS_Shape, parting_surface: TopoDS_Face, margin: int = 20) -> Tuple[TopoDS_Shape, TopoDS_Shape]:
|
||||
def split_cavity_core(self, shape: TopoDS_Shape, parting_surface: TopoDS_Face, margin: int = 20) -> Tuple[TopoDS_Shape, TopoDS_Shape]:
|
||||
"""
|
||||
分离型腔和型芯 — 完全嵌入 + 突出贴合方式。
|
||||
|
||||
@@ -254,7 +299,7 @@ class BaseMoldGenerator:
|
||||
gp_Pnt(mold_xmax, mold_ymax, mold_zmax)
|
||||
).Shape()
|
||||
|
||||
parting_plane = self._get_parting_plane(parting_surface, shape)
|
||||
parting_plane = self.get_parting_plane(parting_surface, shape)
|
||||
if parting_plane is None:
|
||||
center_z = (zmin + zmax) / 2
|
||||
parting_plane = gp_Pln(gp_Pnt(0, 0, center_z), gp_Dir(0, 0, 1))
|
||||
@@ -371,7 +416,7 @@ class BaseMoldGenerator:
|
||||
logger.info("型芯 Compound 兜底构建 (底座+产品)")
|
||||
return compound
|
||||
|
||||
def _get_parting_plane(self, parting_surface: TopoDS_Face, shape: TopoDS_Shape) -> Optional[gp_Pln]:
|
||||
def get_parting_plane(self, parting_surface: TopoDS_Face, shape: TopoDS_Shape) -> Optional[gp_Pln]:
|
||||
"""从分型面提取平面方程"""
|
||||
try:
|
||||
surface = BRepAdaptor_Surface(parting_surface)
|
||||
@@ -388,7 +433,7 @@ class BaseMoldGenerator:
|
||||
logger.warning(f"分型面平面提取失败: {e}")
|
||||
return None
|
||||
|
||||
def _split_mold_block_by_plane(self, mold_block: TopoDS_Shape,
|
||||
def split_mold_block_by_plane(self, mold_block: TopoDS_Shape,
|
||||
parting_plane: gp_Pln) -> Tuple[TopoDS_Shape, TopoDS_Shape]:
|
||||
"""
|
||||
用分型面将模具块切分为A板(上模)和B板(下模)
|
||||
@@ -751,7 +796,7 @@ class BaseMoldGenerator:
|
||||
|
||||
return total_length
|
||||
|
||||
def _calculate_parting_line(self, shape: TopoDS_Shape, parting_surface: TopoDS_Face) -> List[List[float]]:
|
||||
def calculate_parting_line(self, shape: TopoDS_Shape, parting_surface: TopoDS_Face) -> List[List[float]]:
|
||||
try:
|
||||
section = BRepAlgoAPI_Section(shape, parting_surface)
|
||||
section.Build()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from typing import Dict, List, Any, Tuple, Optional
|
||||
import warnings
|
||||
import numpy as np
|
||||
from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeFace
|
||||
from OCC.Core.gp import gp_Pln, gp_Dir, gp_Pnt
|
||||
@@ -25,7 +26,6 @@ class MoldCavityGenerator(BaseMoldGenerator):
|
||||
material_density: float = 1.05):
|
||||
super().__init__(shrinkage_rate, draft_angle, material_density)
|
||||
|
||||
self.parting_line_tolerance = 0.1
|
||||
self.max_draft_angle = 5.0
|
||||
self.side_action_designer = SideActionDesigner()
|
||||
|
||||
@@ -39,7 +39,7 @@ class MoldCavityGenerator(BaseMoldGenerator):
|
||||
|
||||
def generate_mold_cavities(self, product_shape: TopoDS_Shape) -> Dict[str, Any]:
|
||||
"""
|
||||
从产品的3D模型生成型腔和型芯
|
||||
[已废弃] 单方案分模入口。生产路径请使用 MultiSchemeMoldPlanner.generate_plan。
|
||||
|
||||
Returns:
|
||||
{
|
||||
@@ -49,10 +49,15 @@ class MoldCavityGenerator(BaseMoldGenerator):
|
||||
"parting_line": parting_line
|
||||
}
|
||||
"""
|
||||
warnings.warn(
|
||||
"generate_mold_cavities 已废弃,请改用 MultiSchemeMoldPlanner.generate_plan 生成多方案分模结果",
|
||||
DeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
logger.info("开始生成模具型腔...")
|
||||
|
||||
try:
|
||||
analysis = self._analyze_product_geometry(product_shape)
|
||||
analysis = self.analyze_product_geometry(product_shape)
|
||||
|
||||
parting_result = self._detect_primary_parting(product_shape, analysis)
|
||||
parting_surface = parting_result["surface"]
|
||||
@@ -62,18 +67,18 @@ class MoldCavityGenerator(BaseMoldGenerator):
|
||||
side_action_result = self.side_action_designer.analyze_and_design(
|
||||
shape=product_shape,
|
||||
parting_direction=parting_direction,
|
||||
mold_size=self._calculate_mold_size(analysis),
|
||||
mold_size=self.calculate_mold_size(analysis),
|
||||
parting_surface=parting_surface,
|
||||
)
|
||||
undercut_regions = self._build_undercut_regions(
|
||||
undercut_regions = self.build_undercut_regions(
|
||||
side_action_result.get("undercut_analysis", {})
|
||||
)
|
||||
|
||||
scaled_shape = self._apply_shrinkage_compensation(product_shape)
|
||||
scaled_shape = self.apply_shrinkage_compensation(product_shape)
|
||||
|
||||
drafted_shape = self._apply_draft_angles(scaled_shape, parting_surface)
|
||||
drafted_shape = self.apply_draft_angles(scaled_shape, parting_surface)
|
||||
|
||||
cavity, core = self._split_cavity_core(drafted_shape, parting_surface)
|
||||
cavity, core = self.split_cavity_core(drafted_shape, parting_surface)
|
||||
|
||||
logger.info("模具型腔生成完成")
|
||||
|
||||
@@ -137,7 +142,7 @@ class MoldCavityGenerator(BaseMoldGenerator):
|
||||
"side_action_summary": cavity_data.get("side_actions", {}).get("summary", {}),
|
||||
},
|
||||
"manufacturing_info": {
|
||||
"estimated_mold_size": self._calculate_mold_size(analysis),
|
||||
"estimated_mold_size": self.calculate_mold_size(analysis),
|
||||
"estimated_clamping_force": self._calculate_clamping_force(analysis),
|
||||
"recommended_material": self._get_recommended_material()
|
||||
}
|
||||
@@ -223,7 +228,7 @@ class MoldCavityGenerator(BaseMoldGenerator):
|
||||
parting_plane, -span, span, -span, span
|
||||
).Face()
|
||||
parting_surface = self.extend_parting_surface(parting_surface, shape, extension=30.0)
|
||||
parting_line = self._calculate_parting_line(shape, parting_surface)
|
||||
parting_line = self.calculate_parting_line(shape, parting_surface)
|
||||
return {
|
||||
"surface": parting_surface,
|
||||
"line": parting_line,
|
||||
@@ -243,7 +248,7 @@ class MoldCavityGenerator(BaseMoldGenerator):
|
||||
"confidence": 0.6,
|
||||
}
|
||||
|
||||
def _build_undercut_regions(self, undercut_analysis: Dict[str, Any]) -> List[Dict[str, Any]]:
|
||||
def build_undercut_regions(self, undercut_analysis: Dict[str, Any]) -> List[Dict[str, Any]]:
|
||||
"""将侧向机构分析结果转换为兼容旧结构的倒扣区域列表。"""
|
||||
undercut_faces = undercut_analysis.get("undercut_faces", [])
|
||||
regions = []
|
||||
@@ -360,7 +365,7 @@ class MoldCavityGenerator(BaseMoldGenerator):
|
||||
"bounds": metadata["bounds"],
|
||||
}
|
||||
|
||||
def _calculate_mold_size(self, analysis: Dict) -> Dict[str, float]:
|
||||
def calculate_mold_size(self, analysis: Dict) -> Dict[str, float]:
|
||||
"""估算模具尺寸"""
|
||||
product_bbox = analysis["bounding_box"]["dimensions"]
|
||||
margin = 30
|
||||
|
||||
@@ -33,9 +33,9 @@ class MultiSchemeMoldPlanner:
|
||||
) -> Dict[str, Any]:
|
||||
generator = mold_generator_registry.get_by_type("aluminum_foam" if is_foam_material else "injection")
|
||||
generator.set_material(material["name"])
|
||||
self._apply_process_params(generator, material, process_params)
|
||||
generator.apply_process_params(material, process_params)
|
||||
|
||||
analysis = generator._analyze_product_geometry(shape)
|
||||
analysis = generator.analyze_product_geometry(shape)
|
||||
analysis["axis_normal_stats"] = self._collect_axis_normal_stats(generator, shape)
|
||||
candidates = self.candidate_generator.generate_candidates(
|
||||
analysis=analysis,
|
||||
@@ -100,24 +100,24 @@ class MultiSchemeMoldPlanner:
|
||||
candidate.get("opening_span_mm"),
|
||||
)
|
||||
parting_line = generator.optimize_parting_line(
|
||||
generator._calculate_parting_line(shape, parting_surface)
|
||||
generator.calculate_parting_line(shape, parting_surface)
|
||||
)
|
||||
|
||||
parting_direction = candidate["direction"]
|
||||
side_action_result = generator.side_action_designer.analyze_and_design(
|
||||
shape=shape,
|
||||
parting_direction=parting_direction,
|
||||
mold_size=generator._calculate_mold_size(analysis),
|
||||
mold_size=generator.calculate_mold_size(analysis),
|
||||
parting_surface=parting_surface,
|
||||
)
|
||||
undercut_regions = generator._build_undercut_regions(
|
||||
undercut_regions = generator.build_undercut_regions(
|
||||
side_action_result.get("undercut_analysis", {})
|
||||
)
|
||||
mold_structure = self._determine_mold_structure(analysis, undercut_regions)
|
||||
|
||||
scaled_shape = generator._apply_shrinkage_compensation(shape)
|
||||
drafted_shape = generator._apply_draft_angles(scaled_shape, parting_surface)
|
||||
cavity, core = generator._split_cavity_core(drafted_shape, parting_surface)
|
||||
scaled_shape = generator.apply_shrinkage_compensation(shape)
|
||||
drafted_shape = generator.apply_draft_angles(scaled_shape, parting_surface)
|
||||
cavity, core = generator.split_cavity_core(drafted_shape, parting_surface)
|
||||
|
||||
cavity_result = {
|
||||
"cavity": cavity,
|
||||
@@ -130,7 +130,7 @@ class MultiSchemeMoldPlanner:
|
||||
}
|
||||
|
||||
if is_foam_material:
|
||||
cavity_result["mold_block"] = generator._generate_mold_block(cavity, analysis)
|
||||
cavity_result["mold_block"] = generator.generate_mold_block(cavity, analysis)
|
||||
cavity_result["parting_surfaces"] = {
|
||||
"primary_surface": parting_surface,
|
||||
"primary_line": parting_line,
|
||||
@@ -158,10 +158,10 @@ class MultiSchemeMoldPlanner:
|
||||
# 生成可视化辅助形状:A/B 半模(分型面切分)、产品本体
|
||||
a_plate, b_plate, product_for_export = None, None, scaled_shape
|
||||
try:
|
||||
mold_block_shape = generator._create_mold_block(analysis, margin=30.0)
|
||||
a_plate, b_plate = generator._split_mold_block_by_plane(
|
||||
mold_block_shape = generator.create_mold_block(analysis, margin=30.0)
|
||||
a_plate, b_plate = generator.split_mold_block_by_plane(
|
||||
mold_block_shape,
|
||||
generator._get_parting_plane(parting_surface, shape),
|
||||
generator.get_parting_plane(parting_surface, shape),
|
||||
)
|
||||
except Exception as exc:
|
||||
logger.debug(f"A/B 半模生成失败(不影响主流程): {exc}")
|
||||
@@ -199,19 +199,6 @@ class MultiSchemeMoldPlanner:
|
||||
},
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _apply_process_params(generator: Any, material: Dict[str, Any], process_params: Optional[Dict[str, Any]]):
|
||||
params = process_params or {}
|
||||
draft_angle = float(params.get("draft_angle", getattr(generator, "draft_angle", 2.0)))
|
||||
shrinkage_rate = float(params.get("shrinkage_rate", material.get("shrinkage", 0.005) * 100.0)) / 100.0
|
||||
parting_precision = float(params.get("parting_precision", getattr(generator, "parting_line_tolerance", 0.1)))
|
||||
cavity_match = float(params.get("cavity_match", getattr(generator, "cavity_match_rate", 95.0)))
|
||||
|
||||
generator.draft_angle = draft_angle
|
||||
generator.shrinkage_rate = shrinkage_rate
|
||||
generator.parting_line_tolerance = parting_precision
|
||||
generator.cavity_match_rate = cavity_match
|
||||
|
||||
def _build_parting_surface(
|
||||
self,
|
||||
generator: Any,
|
||||
@@ -290,7 +277,7 @@ class MultiSchemeMoldPlanner:
|
||||
explorer.Next()
|
||||
|
||||
try:
|
||||
normal = generator._get_face_normal(face)
|
||||
normal = generator.get_face_normal(face)
|
||||
if normal is None:
|
||||
continue
|
||||
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
"""Generator 公共接口契约测试(技术债计划 P2-⑩)。
|
||||
|
||||
BaseMoldGenerator 的公共契约原先以 `_` 私有方法形式暴露给 MultiSchemeMoldPlanner,
|
||||
本文件锁定提取后的公共接口:方法存在性、参数覆写行为、废弃入口告警,
|
||||
并用真实几何(OCC box)走一遍 generate_plan 集成路径。
|
||||
|
||||
OCC(pythonocc)仅 conda 环境提供(本地 gemold / 服务器 py_3.12),
|
||||
无 OCC 的环境自动跳过本文件,不影响其余测试。
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
pytest.importorskip("OCC.Core.BRepPrimAPI", reason="需要 pythonocc 运行生成器契约测试")
|
||||
|
||||
from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox
|
||||
from OCC.Core.gp import gp_Pnt
|
||||
|
||||
from moldinsight.core.aluminum_foam_mold import AluminumFoamMoldGenerator
|
||||
from moldinsight.core.base_mold_generator import BaseMoldGenerator
|
||||
from moldinsight.core.mold_generator import MoldCavityGenerator
|
||||
from moldinsight.core.multi_scheme_planner import MultiSchemeMoldPlanner
|
||||
from moldinsight.services.material_service import MaterialService
|
||||
|
||||
# BaseMoldGenerator 上的公共契约(含子类必须可调用的基类默认实现)
|
||||
BASE_CONTRACT_METHODS = (
|
||||
"analyze_product_geometry",
|
||||
"apply_shrinkage_compensation",
|
||||
"apply_draft_angles",
|
||||
"split_cavity_core",
|
||||
"create_mold_block",
|
||||
"split_mold_block_by_plane",
|
||||
"get_parting_plane",
|
||||
"get_face_normal",
|
||||
"calculate_parting_line",
|
||||
"apply_process_params",
|
||||
)
|
||||
|
||||
# 两个子类共同实现的完整契约
|
||||
SUBCLASS_CONTRACT_METHODS = BASE_CONTRACT_METHODS + (
|
||||
"calculate_mold_size",
|
||||
"build_undercut_regions",
|
||||
"set_material",
|
||||
"side_action_designer",
|
||||
"generate_detailed_cavity_json",
|
||||
"generate_cavity_key_info",
|
||||
"generate_mold_cavities", # 已废弃但保留兼容
|
||||
)
|
||||
|
||||
|
||||
def _box(dx=50.0, dy=40.0, dz=30.0):
|
||||
return BRepPrimAPI_MakeBox(
|
||||
gp_Pnt(-dx / 2, -dy / 2, -dz / 2), gp_Pnt(dx / 2, dy / 2, dz / 2)
|
||||
).Shape()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("method", SUBCLASS_CONTRACT_METHODS)
|
||||
@pytest.mark.parametrize(
|
||||
"generator_cls", [MoldCavityGenerator, AluminumFoamMoldGenerator]
|
||||
)
|
||||
def test_generator_exposes_public_contract(generator_cls, method):
|
||||
generator = generator_cls()
|
||||
attr = getattr(generator, method, None)
|
||||
assert attr is not None, f"{generator_cls.__name__} 缺少公共接口 {method}"
|
||||
assert callable(attr) or isinstance(attr, object)
|
||||
|
||||
|
||||
def test_foam_generator_implements_generate_mold_block():
|
||||
assert callable(AluminumFoamMoldGenerator().generate_mold_block)
|
||||
|
||||
|
||||
def test_base_generate_mold_block_is_not_implemented():
|
||||
with pytest.raises(NotImplementedError):
|
||||
BaseMoldGenerator().generate_mold_block(None, {})
|
||||
|
||||
|
||||
def test_apply_process_params_overrides_generator_state():
|
||||
generator = MoldCavityGenerator(shrinkage_rate=0.005, draft_angle=2.0)
|
||||
material = MaterialService.get_material("ABS")
|
||||
|
||||
generator.apply_process_params(
|
||||
material,
|
||||
{
|
||||
"draft_angle": 1.5,
|
||||
"shrinkage_rate": 1.2, # 百分数
|
||||
"parting_precision": 0.05,
|
||||
"cavity_match": 97.0,
|
||||
},
|
||||
)
|
||||
|
||||
assert generator.draft_angle == pytest.approx(1.5)
|
||||
assert generator.shrinkage_rate == pytest.approx(0.012)
|
||||
assert generator.parting_line_tolerance == pytest.approx(0.05)
|
||||
assert generator.cavity_match_rate == pytest.approx(97.0)
|
||||
|
||||
|
||||
def test_apply_process_params_defaults_to_material_shrinkage():
|
||||
generator = MoldCavityGenerator(shrinkage_rate=0.005, draft_angle=2.0)
|
||||
material = MaterialService.get_material("PP") # shrinkage 0.016
|
||||
|
||||
generator.apply_process_params(material, None)
|
||||
|
||||
assert generator.shrinkage_rate == pytest.approx(0.016)
|
||||
assert generator.draft_angle == pytest.approx(2.0)
|
||||
|
||||
|
||||
def test_generate_mold_cavities_is_deprecated():
|
||||
generator = MoldCavityGenerator()
|
||||
|
||||
with pytest.warns(DeprecationWarning):
|
||||
result = generator.generate_mold_cavities(_box())
|
||||
|
||||
assert result["cavity"] is not None
|
||||
assert result["core"] is not None
|
||||
|
||||
|
||||
def test_planner_generate_plan_injection_box():
|
||||
planner = MultiSchemeMoldPlanner()
|
||||
|
||||
plan = planner.generate_plan(
|
||||
_box(),
|
||||
MaterialService.get_material("ABS"),
|
||||
is_foam_material=False,
|
||||
max_schemes=2,
|
||||
)
|
||||
|
||||
schemes = plan["candidate_schemes"]
|
||||
assert 1 <= len(schemes) <= 2
|
||||
assert plan["best_scheme_id"] == schemes[0]["scheme_id"]
|
||||
|
||||
best = schemes[0]
|
||||
assert best["cavity_data"]["mold_cavities"]["cavity"]["vertex_count"] > 0
|
||||
assert best["cavity_data"]["mold_cavities"]["core"]["vertex_count"] > 0
|
||||
assert best["cavity_data"]["metadata"]["scheme_id"] == best["scheme_id"]
|
||||
assert best["parting"]["line"]
|
||||
|
||||
export_shapes = plan["_export_shapes"][best["scheme_id"]]
|
||||
assert export_shapes["cavity"] is not None
|
||||
assert export_shapes["product"] is not None
|
||||
|
||||
|
||||
def test_planner_generate_plan_foam_box():
|
||||
planner = MultiSchemeMoldPlanner()
|
||||
|
||||
plan = planner.generate_plan(
|
||||
_box(120, 100, 60),
|
||||
MaterialService.get_material("AlSi10Mg"),
|
||||
is_foam_material=True,
|
||||
max_schemes=1,
|
||||
)
|
||||
|
||||
best = plan["candidate_schemes"][0]
|
||||
assert plan["best_scheme_id"] == best["scheme_id"]
|
||||
# 泡沫材料优先 Z 轴上下开模
|
||||
assert best["axis"] == "Z"
|
||||
assert best["cavity_data"]["metadata"]["foam_material"] == "AlSi10Mg"
|
||||
assert best["cavity_data"]["mold_cavities"]["cavity"]["vertex_count"] > 0
|
||||
|
||||
export_shapes = plan["_export_shapes"][best["scheme_id"]]
|
||||
assert export_shapes["cavity"] is not None
|
||||
Reference in New Issue
Block a user