docs: 完善技术文档

新增文档:
- api/API接口文档模板.md
- api/PLM-API接口文档-V2.md
- api/产品服务API文档-V2.md
- architecture/BOM服务技术文档.md
- architecture/PLM技术文档摘要.md
- development/M1-S4开发手册.md
- development/PLM开发手册.md
- development/PLM开发文档.md
- operations/系统部署指南.md
- operations/部署检查清单.md

提交人: creator
提交时间: 2026-04-03
This commit is contained in:
2026-04-03 20:31:01 +08:00
parent 2893a318f5
commit d98c8a05cd
8 changed files with 4995 additions and 0 deletions

View File

@@ -0,0 +1,290 @@
# API 接口文档模板
> **版本**V1.0
> **创建时间**2026-03-31
> **创建人**:笔杆子
> **状态**:模板
---
## 一、API 设计规范
### 1.1 RESTful API 规范
```
基础URL: https://api.plm.example.com/v1
HTTP方法
- GET 查询资源
- POST 创建资源
- PUT 更新资源(全量)
- PATCH 更新资源(部分)
- DELETE 删除资源
```
### 1.2 响应格式
**成功响应:**
```json
{
"code": 0,
"message": "success",
"data": {
// 业务数据
}
}
```
**错误响应:**
```json
{
"code": 40001,
"message": "参数错误",
"errors": [
{
"field": "name",
"message": "名称不能为空"
}
]
}
```
### 1.3 分页格式
```json
{
"code": 0,
"message": "success",
"data": {
"items": [],
"total": 100,
"page": 1,
"page_size": 20,
"total_pages": 5
}
}
```
---
## 二、认证接口
### 2.1 用户登录
**请求:**
```
POST /auth/login
Content-Type: application/json
{
"username": "admin",
"password": "password123"
}
```
**响应:**
```json
{
"code": 0,
"message": "success",
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "eyJhbGciOiJIUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600
}
}
```
### 2.2 刷新Token
**请求:**
```
POST /auth/refresh
Authorization: Bearer {refresh_token}
```
**响应:**
```json
{
"code": 0,
"message": "success",
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"expires_in": 3600
}
}
```
---
## 三、用户管理接口
### 3.1 获取用户列表
**请求:**
```
GET /users?page=1&page_size=20&status=active
Authorization: Bearer {access_token}
```
**响应:**
```json
{
"code": 0,
"message": "success",
"data": {
"items": [
{
"id": 1,
"username": "admin",
"email": "admin@example.com",
"role": "admin",
"status": "active",
"created_at": "2026-03-31T10:00:00Z",
"updated_at": "2026-03-31T10:00:00Z"
}
],
"total": 1,
"page": 1,
"page_size": 20
}
}
```
### 3.2 创建用户
**请求:**
```
POST /users
Authorization: Bearer {access_token}
Content-Type: application/json
{
"username": "newuser",
"email": "newuser@example.com",
"password": "password123",
"role": "engineer"
}
```
**响应:**
```json
{
"code": 0,
"message": "success",
"data": {
"id": 2,
"username": "newuser",
"email": "newuser@example.com",
"role": "engineer",
"status": "active",
"created_at": "2026-03-31T10:00:00Z"
}
}
```
---
## 四、产品管理接口
### 4.1 获取产品列表
**请求:**
```
GET /products?page=1&page_size=20&category_id=1
Authorization: Bearer {access_token}
```
### 4.2 创建产品
**请求:**
```
POST /products
Authorization: Bearer {access_token}
Content-Type: application/json
{
"code": "P001",
"name": "产品名称",
"description": "产品描述",
"category_id": 1,
"status": "draft"
}
```
---
## 五、BOM管理接口
### 5.1 获取BOM列表
**请求:**
```
GET /boms?product_id=1
Authorization: Bearer {access_token}
```
### 5.2 创建BOM
**请求:**
```
POST /boms
Authorization: Bearer {access_token}
Content-Type: application/json
{
"product_id": 1,
"version": "1.0",
"items": [
{
"material_code": "M001",
"quantity": 10,
"unit": "pcs"
}
]
}
```
---
## 六、错误码定义
| 错误码 | 说明 |
|--------|------|
| 0 | 成功 |
| 40001 | 参数错误 |
| 40002 | 资源不存在 |
| 40003 | 资源已存在 |
| 40101 | 未授权 |
| 40102 | Token过期 |
| 40301 | 权限不足 |
| 50001 | 服务器内部错误 |
---
## 七、API 版本管理
- v1: 当前版本
- v2: 开发中
版本通过URL路径控制`/api/v1/...`
---
_创建时间2026-03-31 18:06_
_维护人笔杆子 (creator)_

View File

@@ -0,0 +1,742 @@
# PLM 系统 API 接口文档
> **版本**V2.0
> **创建时间**2026-03-31
> **创建人**:笔杆子 (creator)
> **状态**:已发布
> **基础URL**`https://api.plm.example.com/v1`
---
## 一、概述
### 1.1 API 设计规范
| 规范 | 说明 |
|------|------|
| 协议 | HTTPS |
| 数据格式 | JSON |
| 字符编码 | UTF-8 |
| 认证方式 | Bearer Token (JWT) |
| 版本控制 | URL路径 `/v1/` |
### 1.2 HTTP 方法
| 方法 | 用途 |
|------|------|
| GET | 查询资源 |
| POST | 创建资源 |
| PUT | 全量更新 |
| PATCH | 部分更新 |
| DELETE | 删除资源 |
---
## 二、通用响应格式
### 2.1 成功响应
```json
{
"code": 0,
"message": "success",
"data": { },
"timestamp": "2026-03-31T12:00:00Z"
}
```
### 2.2 错误响应
```json
{
"code": 40001,
"message": "参数错误",
"errors": [
{
"field": "name",
"message": "名称不能为空"
}
],
"timestamp": "2026-03-31T12:00:00Z"
}
```
### 2.3 分页响应
```json
{
"code": 0,
"message": "success",
"data": {
"items": [],
"pagination": {
"total": 100,
"page": 1,
"page_size": 20,
"total_pages": 5
}
}
}
```
---
## 三、认证接口 (Auth)
### 3.1 用户登录
**POST** `/auth/login`
**请求体:**
```json
{
"username": "admin",
"password": "Admin@123456"
}
```
**响应:**
```json
{
"code": 0,
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "eyJhbGciOiJIUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600
}
}
```
### 3.2 刷新Token
**POST** `/auth/refresh`
**Header**
```
Authorization: Bearer {refresh_token}
```
**响应:**
```json
{
"code": 0,
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"expires_in": 3600
}
}
```
### 3.3 用户登出
**POST** `/auth/logout`
**Header**
```
Authorization: Bearer {access_token}
```
**响应:**
```json
{
"code": 0,
"message": "登出成功"
}
```
### 3.4 修改密码
**PUT** `/auth/password`
**请求体:**
```json
{
"old_password": "Admin@123456",
"new_password": "NewPass@123"
}
```
---
## 四、用户管理接口 (Users)
### 4.1 获取用户列表
**GET** `/users`
**查询参数:**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| page | int | 否 | 页码默认1 |
| page_size | int | 否 | 每页数量默认20 |
| status | string | 否 | 状态筛选 |
| role | string | 否 | 角色筛选 |
| keyword | string | 否 | 关键词搜索 |
**响应:**
```json
{
"code": 0,
"data": {
"items": [
{
"id": 1,
"username": "admin",
"email": "admin@example.com",
"phone": "13800138000",
"role": "admin",
"status": "active",
"department_id": 1,
"created_at": "2026-03-01T10:00:00Z",
"updated_at": "2026-03-31T10:00:00Z"
}
],
"pagination": {
"total": 1,
"page": 1,
"page_size": 20
}
}
}
```
### 4.2 获取用户详情
**GET** `/users/{user_id}`
### 4.3 创建用户
**POST** `/users`
**请求体:**
```json
{
"username": "newuser",
"email": "newuser@example.com",
"phone": "13800138001",
"password": "User@123456",
"role": "engineer",
"department_id": 2
}
```
### 4.4 更新用户
**PUT** `/users/{user_id}`
### 4.5 删除用户
**DELETE** `/users/{user_id}`
### 4.6 修改用户状态
**PATCH** `/users/{user_id}/status`
**请求体:**
```json
{
"status": "inactive"
}
```
---
## 五、产品管理接口 (Products)
### 5.1 获取产品列表
**GET** `/products`
**查询参数:**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| page | int | 否 | 页码 |
| page_size | int | 否 | 每页数量 |
| category_id | int | 否 | 分类ID |
| status | string | 否 | 状态 |
| keyword | string | 否 | 关键词 |
### 5.2 获取产品详情
**GET** `/products/{product_id}`
**响应:**
```json
{
"code": 0,
"data": {
"id": 1,
"code": "P001",
"name": "产品名称",
"description": "产品描述",
"category": {
"id": 1,
"name": "分类名称"
},
"status": "released",
"version": "1.0.0",
"ai_analysis_status": "completed",
"ai_recommendation": "建议内容",
"created_at": "2026-03-01T10:00:00Z",
"updated_at": "2026-03-31T10:00:00Z"
}
}
```
### 5.3 创建产品
**POST** `/products`
**请求体:**
```json
{
"code": "P001",
"name": "产品名称",
"description": "产品描述",
"category_id": 1,
"status": "draft"
}
```
### 5.4 更新产品
**PUT** `/products/{product_id}`
### 5.5 删除产品
**DELETE** `/products/{product_id}`
### 5.6 产品版本管理
**GET** `/products/{product_id}/versions`
**POST** `/products/{product_id}/versions`
### 5.7 AI智能分类
**POST** `/products/{product_id}/ai-classify`
**响应:**
```json
{
"code": 0,
"data": {
"suggested_category": {
"id": 5,
"name": "建议分类",
"confidence": 0.92
},
"similar_products": [
{
"id": 10,
"name": "相似产品",
"similarity": 0.85
}
]
}
}
```
---
## 六、BOM管理接口 (BOMs)
### 6.1 获取BOM列表
**GET** `/boms`
### 6.2 获取BOM详情
**GET** `/boms/{bom_id}`
**响应:**
```json
{
"code": 0,
"data": {
"id": 1,
"product_id": 1,
"version": "1.0",
"status": "released",
"items": [
{
"id": 1,
"material_code": "M001",
"material_name": "物料名称",
"quantity": 10,
"unit": "pcs",
"level": 1
}
],
"ai_recommendation": "优化建议"
}
}
```
### 6.3 创建BOM
**POST** `/boms`
**请求体:**
```json
{
"product_id": 1,
"version": "1.0",
"items": [
{
"material_code": "M001",
"quantity": 10,
"unit": "pcs"
}
]
}
```
### 6.4 BOM展开
**GET** `/boms/{bom_id}/expand`
**查询参数:**
| 参数 | 类型 | 说明 |
|------|------|------|
| level | int | 展开层级,-1为全部展开 |
### 6.5 BOM对比
**POST** `/boms/compare`
**请求体:**
```json
{
"bom_id_1": 1,
"bom_id_2": 2
}
```
### 6.6 AI优化建议
**POST** `/boms/{bom_id}/ai-optimize`
**响应:**
```json
{
"code": 0,
"data": {
"optimizations": [
{
"type": "material_substitution",
"original": "M001",
"suggested": "M002",
"reason": "成本降低15%",
"confidence": 0.88
}
],
"similar_boms": [
{
"id": 5,
"product_name": "相似产品BOM",
"similarity": 0.82
}
]
}
}
```
---
## 七、文档管理接口 (Documents)
### 7.1 获取文档列表
**GET** `/documents`
### 7.2 上传文档
**POST** `/documents/upload`
**请求体:** multipart/form-data
| 字段 | 类型 | 说明 |
|------|------|------|
| file | file | 文件 |
| product_id | int | 关联产品ID |
| category | string | 文档分类 |
### 7.3 下载文档
**GET** `/documents/{doc_id}/download`
### 7.4 文档版本历史
**GET** `/documents/{doc_id}/versions`
### 7.5 AI智能标签
**POST** `/documents/{doc_id}/ai-tag`
**响应:**
```json
{
"code": 0,
"data": {
"tags": ["技术文档", "设计规范", "API"],
"summary": "文档摘要内容..."
}
}
```
---
## 八、变更管理接口 (Changes)
### 8.1 获取变更列表
**GET** `/changes`
### 8.2 创建变更申请 (ECR)
**POST** `/changes`
**请求体:**
```json
{
"type": "design_change",
"title": "变更标题",
"description": "变更描述",
"reason": "变更原因",
"product_ids": [1, 2],
"attachments": []
}
```
### 8.3 变更审批
**POST** `/changes/{change_id}/approve`
**请求体:**
```json
{
"action": "approve",
"comment": "审批意见"
}
```
### 8.4 AI风险预测
**POST** `/changes/{change_id}/ai-risk`
**响应:**
```json
{
"code": 0,
"data": {
"risk_level": "medium",
"risk_score": 0.65,
"affected_items": [
{
"type": "bom",
"id": 1,
"impact": "物料M001数量需调整"
}
],
"recommendations": [
"建议同步更新工艺路线",
"需通知采购部门"
]
}
}
```
---
## 九、搜索接口 (Search)
### 9.1 全局搜索
**GET** `/search`
**查询参数:**
| 参数 | 类型 | 说明 |
|------|------|------|
| q | string | 搜索关键词 |
| type | string | 资源类型 |
| page | int | 页码 |
### 9.2 AI智能搜索
**POST** `/search/ai`
**请求体:**
```json
{
"query": "查找所有使用物料M001的产品",
"context": {}
}
```
**响应:**
```json
{
"code": 0,
"data": {
"sql": "SELECT * FROM products WHERE id IN (SELECT product_id FROM boms WHERE material_code = 'M001')",
"results": [...],
"explanation": "已为您查找所有BOM中包含物料M001的产品"
}
}
```
---
## 十、工作流接口 (Workflows)
### 10.1 获取工作流定义列表
**GET** `/workflows/definitions`
### 10.2 启动工作流实例
**POST** `/workflows/instances`
**请求体:**
```json
{
"definition_id": "approval_flow",
"business_key": "ECR-001",
"variables": {
"approver": "manager"
}
}
```
### 10.3 获取工作流实例详情
**GET** `/workflows/instances/{instance_id}`
### 10.4 完成任务
**POST** `/workflows/tasks/{task_id}/complete`
---
## 十一、错误码定义
### 11.1 通用错误码
| 错误码 | 说明 |
|--------|------|
| 0 | 成功 |
| 40001 | 参数错误 |
| 40002 | 资源不存在 |
| 40003 | 资源已存在 |
| 40004 | 操作不允许 |
### 11.2 认证错误码
| 错误码 | 说明 |
|--------|------|
| 40101 | 未授权 |
| 40102 | Token过期 |
| 40103 | Token无效 |
| 40104 | 密码错误 |
### 11.3 权限错误码
| 错误码 | 说明 |
|--------|------|
| 40301 | 权限不足 |
| 40302 | 账户被禁用 |
### 11.4 服务端错误码
| 错误码 | 说明 |
|--------|------|
| 50001 | 服务器内部错误 |
| 50002 | 数据库错误 |
| 50003 | 第三方服务错误 |
---
## 十二、API调用示例
### 12.1 cURL示例
```bash
# 登录获取Token
curl -X POST https://api.plm.example.com/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"Admin@123456"}'
# 获取产品列表
curl -X GET https://api.plm.example.com/v1/products \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
# 创建产品
curl -X POST https://api.plm.example.com/v1/products \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{"code":"P001","name":"产品名称"}'
```
### 12.2 Python示例
```python
import requests
BASE_URL = "https://api.plm.example.com/v1"
# 登录
response = requests.post(f"{BASE_URL}/auth/login", json={
"username": "admin",
"password": "Admin@123456"
})
token = response.json()["data"]["access_token"]
# 获取产品列表
headers = {"Authorization": f"Bearer {token}"}
response = requests.get(f"{BASE_URL}/products", headers=headers)
products = response.json()["data"]["items"]
```
---
## 十三、附录
### 13.1 状态枚举
**用户状态:**
- `active` - 激活
- `inactive` - 未激活
- `suspended` - 已停用
- `pending` - 待审核
**产品状态:**
- `draft` - 草稿
- `released` - 发布
- `frozen` - 冻结
- `obsolete` - 退役
**BOM状态**
- `draft` - 草稿
- `frozen` - 冻结
- `released` - 发布
**变更状态:**
- `draft` - 草稿
- `submitted` - 已提交
- `approved` - 已批准
- `rejected` - 已拒绝
- `implemented` - 已执行
### 13.2 版本历史
| 版本 | 日期 | 变更内容 |
|------|------|----------|
| V2.0 | 2026-03-31 | 新增AI接口、完善业务接口 |
| V1.0 | 2026-03-31 | 初始版本 |
---
_创建时间2026-03-31 20:15_
_维护人笔杆子 (creator)_

View File

@@ -0,0 +1,873 @@
# 产品服务 API 接口文档
> **版本**V2.0
> **创建时间**2026-03-31
> **创建人**:笔杆子 (creator)
> **状态**:已发布
> **微服务**plm-product-service
> **基础URL**`https://api.plm.example.com/v1`
---
## 一、服务概述
### 1.1 服务定位
产品服务负责管理产品全生命周期数据是PLM系统的核心基础服务。
**核心职责:**
- 产品信息管理CRUD
- 产品版本控制
- 产品分类管理
- 产品状态管理
- AI智能分类与推荐
### 1.2 服务端口
| 协议 | 端口 |
|------|------|
| HTTP | 8002 |
| gRPC | 50052 |
---
## 二、数据模型
### 2.1 产品主表 (products)
| 字段 | 类型 | 说明 |
|------|------|------|
| id | INTEGER | 主键 |
| code | VARCHAR(50) | 产品编码(唯一) |
| name | VARCHAR(200) | 产品名称 |
| description | TEXT | 产品描述 |
| category_id | INTEGER | 分类ID |
| type | VARCHAR(50) | 产品类型 |
| status | VARCHAR(20) | 状态 |
| unit | VARCHAR(20) | 计量单位 |
| weight | DECIMAL(10,2) | 重量 |
| specifications | JSONB | 规格参数 |
| custom_attributes | JSONB | 自定义属性 |
| ai_analysis_status | VARCHAR(20) | AI分析状态 |
| ai_recommendation | TEXT | AI推荐内容 |
| ai_confidence_score | FLOAT | AI置信度 |
| embedding_vector | VECTOR(1536) | 向量嵌入 |
| created_by | INTEGER | 创建人 |
| created_at | TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | 更新时间 |
### 2.2 产品版本表 (product_versions)
| 字段 | 类型 | 说明 |
|------|------|------|
| id | INTEGER | 主键 |
| product_id | INTEGER | 产品ID |
| version | VARCHAR(20) | 版本号 |
| change_log | TEXT | 变更日志 |
| status | VARCHAR(20) | 状态 |
| ai_change_analysis | TEXT | AI变更分析 |
| released_at | TIMESTAMP | 发布时间 |
| released_by | INTEGER | 发布人 |
### 2.3 产品分类表 (product_categories)
| 字段 | 类型 | 说明 |
|------|------|------|
| id | INTEGER | 主键 |
| parent_id | INTEGER | 父分类ID |
| code | VARCHAR(50) | 分类编码 |
| name | VARCHAR(100) | 分类名称 |
| level | INTEGER | 层级 |
| path | VARCHAR(500) | 路径 |
| ai_classification_rules | JSONB | AI分类规则 |
| created_at | TIMESTAMP | 创建时间 |
---
## 三、产品管理接口
### 3.1 获取产品列表
```
GET /api/v1/products
```
**请求头:**
```
Authorization: Bearer {access_token}
```
**查询参数:**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| page | int | 否 | 页码默认1 |
| page_size | int | 否 | 每页数量默认20最大100 |
| keyword | string | 否 | 搜索关键词(编码/名称) |
| category_id | int | 否 | 分类ID |
| status | string | 否 | 状态筛选 |
| type | string | 否 | 类型筛选 |
| sort_by | string | 否 | 排序字段created_at/updated_at/name |
| sort_order | string | 否 | 排序方向asc/desc |
**响应示例:**
```json
{
"code": 0,
"message": "success",
"data": {
"items": [
{
"id": 1,
"code": "P001",
"name": "智能电机A型",
"description": "高效节能智能电机",
"category": {
"id": 5,
"name": "电机类"
},
"type": "standard",
"status": "released",
"unit": "台",
"version": "2.0",
"ai_analysis_status": "completed",
"created_at": "2026-03-01T10:00:00Z",
"updated_at": "2026-03-31T10:00:00Z"
}
],
"pagination": {
"total": 150,
"page": 1,
"page_size": 20,
"total_pages": 8
}
},
"timestamp": "2026-03-31T12:00:00Z"
}
```
### 3.2 获取产品详情
```
GET /api/v1/products/{product_id}
```
**路径参数:**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| product_id | int | 是 | 产品ID |
**响应示例:**
```json
{
"code": 0,
"message": "success",
"data": {
"id": 1,
"code": "P001",
"name": "智能电机A型",
"description": "高效节能智能电机功率范围1-100kW",
"category": {
"id": 5,
"name": "电机类",
"path": "设备/动力设备/电机类"
},
"type": "standard",
"status": "released",
"unit": "台",
"weight": 150.5,
"specifications": {
"power": "50kW",
"voltage": "380V",
"speed": "1500rpm"
},
"custom_attributes": {
"brand": "自主品牌",
"warranty": "2年"
},
"version": "2.0",
"versions": [
{
"version": "1.0",
"status": "obsolete",
"released_at": "2026-01-01T00:00:00Z"
},
{
"version": "2.0",
"status": "released",
"released_at": "2026-03-01T00:00:00Z"
}
],
"ai_analysis_status": "completed",
"ai_recommendation": "建议分类电机类置信度92%。相似产品智能电机B型、高效电机C型",
"ai_confidence_score": 0.92,
"created_by": {
"id": 1,
"name": "admin"
},
"created_at": "2026-03-01T10:00:00Z",
"updated_at": "2026-03-31T10:00:00Z"
}
}
```
### 3.3 创建产品
```
POST /api/v1/products
```
**请求体:**
```json
{
"code": "P002",
"name": "智能电机B型",
"description": "新型高效智能电机",
"category_id": 5,
"type": "standard",
"unit": "台",
"weight": 120.0,
"specifications": {
"power": "30kW",
"voltage": "380V",
"speed": "3000rpm"
},
"custom_attributes": {
"brand": "自主品牌",
"warranty": "3年"
}
}
```
**响应示例:**
```json
{
"code": 0,
"message": "success",
"data": {
"id": 2,
"code": "P002",
"name": "智能电机B型",
"status": "draft",
"ai_analysis_status": "pending",
"created_at": "2026-03-31T12:00:00Z"
}
}
```
### 3.4 更新产品
```
PUT /api/v1/products/{product_id}
```
**请求体:**
```json
{
"name": "智能电机B型升级版",
"description": "升级版高效智能电机",
"weight": 125.0
}
```
### 3.5 删除产品
```
DELETE /api/v1/products/{product_id}
```
**响应示例:**
```json
{
"code": 0,
"message": "删除成功"
}
```
### 3.6 批量导入产品
```
POST /api/v1/products/import
```
**请求体:** multipart/form-data
| 字段 | 类型 | 说明 |
|------|------|------|
| file | file | Excel文件.xlsx |
| update_existing | boolean | 是否更新已存在产品 |
**响应示例:**
```json
{
"code": 0,
"data": {
"total": 100,
"success": 95,
"failed": 5,
"errors": [
{
"row": 10,
"code": "P010",
"error": "编码已存在"
}
]
}
}
```
### 3.7 批量导出产品
```
GET /api/v1/products/export
```
**查询参数:**
| 参数 | 类型 | 说明 |
|------|------|------|
| ids | string | 产品ID列表逗号分隔 |
| category_id | int | 按分类导出 |
| status | string | 按状态导出 |
| format | string | 格式xlsx/csv |
---
## 四、产品版本接口
### 4.1 获取产品版本列表
```
GET /api/v1/products/{product_id}/versions
```
**响应示例:**
```json
{
"code": 0,
"data": {
"items": [
{
"id": 1,
"version": "1.0",
"change_log": "初始版本",
"status": "obsolete",
"released_at": "2026-01-01T00:00:00Z",
"released_by": {
"id": 1,
"name": "admin"
}
},
{
"id": 2,
"version": "2.0",
"change_log": "性能优化功率提升20%",
"status": "released",
"ai_change_analysis": "主要变更功率参数从40kW提升到50kW预计影响下游BOM中相关组件选型",
"released_at": "2026-03-01T00:00:00Z"
}
]
}
}
```
### 4.2 创建新版本
```
POST /api/v1/products/{product_id}/versions
```
**请求体:**
```json
{
"version": "3.0",
"change_log": "增加智能监控功能",
"specifications": {
"power": "55kW",
"voltage": "380V",
"speed": "1500rpm",
"monitoring": "IoT智能监控"
}
}
```
### 4.3 发布版本
```
POST /api/v1/products/{product_id}/versions/{version_id}/release
```
### 4.4 版本对比
```
GET /api/v1/products/{product_id}/versions/compare
```
**查询参数:**
| 参数 | 类型 | 说明 |
|------|------|------|
| version1 | string | 版本1 |
| version2 | string | 版本2 |
---
## 五、产品分类接口
### 5.1 获取分类树
```
GET /api/v1/products/categories/tree
```
**响应示例:**
```json
{
"code": 0,
"data": {
"id": 0,
"name": "全部",
"children": [
{
"id": 1,
"name": "设备",
"children": [
{
"id": 3,
"name": "动力设备",
"children": [
{
"id": 5,
"name": "电机类",
"children": []
}
]
}
]
}
]
}
}
```
### 5.2 获取分类详情
```
GET /api/v1/products/categories/{category_id}
```
### 5.3 创建分类
```
POST /api/v1/products/categories
```
**请求体:**
```json
{
"parent_id": 5,
"code": "MOTOR-AC",
"name": "交流电机"
}
```
### 5.4 更新分类
```
PUT /api/v1/products/categories/{category_id}
```
### 5.5 删除分类
```
DELETE /api/v1/products/categories/{category_id}
```
---
## 六、产品状态接口
### 6.1 获取状态列表
```
GET /api/v1/products/statuses
```
**响应示例:**
```json
{
"code": 0,
"data": [
{
"code": "draft",
"name": "草稿",
"description": "新建产品,未发布"
},
{
"code": "released",
"name": "已发布",
"description": "已正式发布"
},
{
"code": "frozen",
"name": "已冻结",
"description": "暂停使用"
},
{
"code": "obsolete",
"name": "已废弃",
"description": "不再使用"
}
]
}
```
### 6.2 变更状态
```
PATCH /api/v1/products/{product_id}/status
```
**请求体:**
```json
{
"status": "released",
"reason": "产品已通过测试,正式发布"
}
```
---
## 七、AI智能接口
### 7.1 AI智能分类
```
POST /api/v1/products/{product_id}/ai-classify
```
**响应示例:**
```json
{
"code": 0,
"data": {
"suggested_category": {
"id": 5,
"name": "电机类",
"path": "设备/动力设备/电机类",
"confidence": 0.92
},
"alternative_categories": [
{
"id": 6,
"name": "发电机类",
"confidence": 0.15
}
],
"classification_reason": "根据产品名称'智能电机'和规格参数,判断属于电机类"
}
}
```
### 7.2 AI相似产品推荐
```
GET /api/v1/products/{product_id}/ai-similar
```
**响应示例:**
```json
{
"code": 0,
"data": {
"similar_products": [
{
"id": 3,
"code": "P003",
"name": "智能电机B型",
"similarity": 0.88,
"match_details": {
"specifications_match": 0.95,
"category_match": 1.0,
"name_similarity": 0.85
}
}
]
}
}
```
### 7.3 AI智能补全
```
POST /api/v1/products/ai-autocomplete
```
**请求体:**
```json
{
"field": "specifications",
"partial_data": {
"power": "50kW",
"voltage": "380V"
}
}
```
**响应示例:**
```json
{
"code": 0,
"data": {
"suggestions": {
"speed": ["1500rpm", "3000rpm"],
"frequency": "50Hz",
"efficiency": "IE3"
}
}
}
```
### 7.4 AI智能搜索
```
POST /api/v1/products/ai-search
```
**请求体:**
```json
{
"query": "功率在30-50kW之间的三相电机",
"filters": {}
}
```
**响应示例:**
```json
{
"code": 0,
"data": {
"sql_equivalent": "SELECT * FROM products WHERE specifications->>'power' BETWEEN '30kW' AND '50kW' AND category_id = 5",
"results": [...],
"explanation": "已为您找到功率在30-50kW之间的电机类产品"
}
}
```
---
## 八、属性模板接口
### 8.1 获取属性模板列表
```
GET /api/v1/products/attribute-templates
```
### 8.2 获取模板详情
```
GET /api/v1/products/attribute-templates/{template_id}
```
**响应示例:**
```json
{
"code": 0,
"data": {
"id": 1,
"name": "电机属性模板",
"category_id": 5,
"attributes": [
{
"name": "power",
"label": "功率",
"type": "string",
"required": true,
"unit": "kW",
"validation": "^\\d+kW$"
},
{
"name": "voltage",
"label": "电压",
"type": "select",
"required": true,
"options": ["220V", "380V", "660V"]
}
]
}
}
```
### 8.3 创建属性模板
```
POST /api/v1/products/attribute-templates
```
---
## 九、gRPC接口
### 9.1 Proto定义
```protobuf
// proto/product.proto
syntax = "proto3";
package plm.product;
service ProductService {
rpc GetProduct(GetProductRequest) returns (ProductResponse);
rpc ListProducts(ListProductsRequest) returns (ListProductsResponse);
rpc CreateProduct(CreateProductRequest) returns (ProductResponse);
rpc UpdateProduct(UpdateProductRequest) returns (ProductResponse);
rpc DeleteProduct(DeleteProductRequest) returns (DeleteProductResponse);
// AI流式接口
rpc AIClassify(AIClassifyRequest) returns (stream AIClassifyResponse);
rpc FindSimilar(SimilarProductsRequest) returns (SimilarProductsResponse);
}
message Product {
int32 id = 1;
string code = 2;
string name = 3;
string description = 4;
int32 category_id = 5;
string status = 6;
map<string, string> specifications = 7;
}
message GetProductRequest {
int32 product_id = 1;
}
message ProductResponse {
Product product = 1;
}
message ListProductsRequest {
int32 page = 1;
int32 page_size = 2;
string keyword = 3;
int32 category_id = 4;
}
message ListProductsResponse {
repeated Product items = 1;
int32 total = 2;
}
```
---
## 十、错误码
### 10.1 产品相关错误码
| 错误码 | HTTP状态码 | 说明 |
|--------|------------|------|
| 40001 | 400 | 参数错误 |
| 40002 | 404 | 产品不存在 |
| 40003 | 409 | 产品编码已存在 |
| 40004 | 400 | 分类不存在 |
| 40005 | 400 | 状态转换不允许 |
### 10.2 AI相关错误码
| 错误码 | HTTP状态码 | 说明 |
|--------|------------|------|
| 50101 | 500 | AI服务不可用 |
| 50102 | 500 | AI分析超时 |
| 50103 | 500 | 向量嵌入失败 |
---
## 十一、调用示例
### 11.1 Python示例
```python
import requests
BASE_URL = "https://api.plm.example.com/v1"
TOKEN = "your-access-token"
headers = {"Authorization": f"Bearer {TOKEN}"}
# 获取产品列表
response = requests.get(f"{BASE_URL}/products", headers=headers)
products = response.json()["data"]["items"]
# 创建产品
new_product = {
"code": "P003",
"name": "智能电机C型",
"category_id": 5
}
response = requests.post(
f"{BASE_URL}/products",
headers=headers,
json=new_product
)
# AI分类
response = requests.post(
f"{BASE_URL}/products/{product_id}/ai-classify",
headers=headers
)
```
### 11.2 cURL示例
```bash
# 获取产品列表
curl -X GET "https://api.plm.example.com/v1/products?page=1&page_size=20" \
-H "Authorization: Bearer your-token"
# 创建产品
curl -X POST "https://api.plm.example.com/v1/products" \
-H "Authorization: Bearer your-token" \
-H "Content-Type: application/json" \
-d '{"code":"P003","name":"智能电机C型","category_id":5}'
# AI智能分类
curl -X POST "https://api.plm.example.com/v1/products/1/ai-classify" \
-H "Authorization: Bearer your-token"
```
---
## 十二、版本历史
| 版本 | 日期 | 变更内容 |
|------|------|----------|
| V2.0 | 2026-03-31 | 新增AI接口、版本管理接口 |
| V1.0 | 2026-03-01 | 初始版本 |
---
_创建时间2026-03-31 20:40_
_维护人笔杆子 (creator)_

View File

@@ -0,0 +1,774 @@
# BOM 服务技术文档
> **版本**V1.0
> **创建时间**2026-03-31
> **创建人**:笔杆子 (creator)
> **状态**:已发布
> **微服务**plm-bom-service
---
## 一、服务概述
### 1.1 服务定位
BOMBill of Materials服务负责管理产品的物料清单是PLM系统的核心服务之一。
**核心职责:**
- BOM创建与管理
- BOM层级结构维护
- BOM版本控制
- BOM展开与对比分析
- 物料需求计算
- AI智能优化建议
### 1.2 服务架构
```
plm-bom-service/
├── api/ # API层
│ ├── bom_router.py # BOM路由
│ └── bom_item_router.py # BOM明细路由
├── services/ # 业务层
│ ├── bom_service.py # BOM业务逻辑
│ └── bom_engine.py # C++引擎绑定
├── models/ # 数据层
│ ├── bom.py # BOM主表
│ └── bom_item.py # BOM明细表
├── schemas/ # 数据验证
│ └── bom_schemas.py
└── ai/ # AI模块
├── bom_optimizer.py # BOM优化
└── similarity.py # 相似检测
```
---
## 二、数据模型
### 2.1 BOM主表 (boms)
| 字段 | 类型 | 说明 |
|------|------|------|
| id | INTEGER | 主键 |
| product_id | INTEGER | 产品ID外键 |
| code | VARCHAR(50) | BOM编码 |
| name | VARCHAR(200) | BOM名称 |
| version | VARCHAR(20) | 版本号 |
| type | VARCHAR(20) | BOM类型 |
| status | VARCHAR(20) | 状态 |
| parent_bom_id | INTEGER | 父BOM ID |
| effective_date | DATE | 生效日期 |
| expiry_date | DATE | 失效日期 |
| ai_analysis_status | VARCHAR(20) | AI分析状态 |
| ai_recommendation | TEXT | AI推荐内容 |
| ai_confidence_score | FLOAT | AI置信度 |
| embedding_vector | VECTOR(1536) | 向量嵌入 |
| created_by | INTEGER | 创建人 |
| created_at | TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | 更新时间 |
### 2.2 BOM明细表 (bom_items)
| 字段 | 类型 | 说明 |
|------|------|------|
| id | INTEGER | 主键 |
| bom_id | INTEGER | BOM ID外键 |
| parent_item_id | INTEGER | 父项ID |
| level | INTEGER | 层级 |
| sequence | INTEGER | 序号 |
| material_id | INTEGER | 物料ID |
| material_code | VARCHAR(50) | 物料编码 |
| material_name | VARCHAR(200) | 物料名称 |
| quantity | DECIMAL(10,4) | 数量 |
| unit | VARCHAR(20) | 单位 |
| scrap_rate | DECIMAL(5,2) | 损耗率 |
| substitute_material_id | INTEGER | 替代物料ID |
| effective_date | DATE | 生效日期 |
| remark | TEXT | 备注 |
| created_at | TIMESTAMP | 创建时间 |
### 2.3 BOM版本差异表 (bom_version_diffs)
| 字段 | 类型 | 说明 |
|------|------|------|
| id | INTEGER | 主键 |
| bom_id | INTEGER | BOM ID |
| old_version | VARCHAR(20) | 旧版本 |
| new_version | VARCHAR(20) | 新版本 |
| diff_type | VARCHAR(20) | 差异类型 |
| diff_details | JSONB | 差异详情 |
| ai_impact_analysis | TEXT | AI影响分析 |
| created_at | TIMESTAMP | 创建时间 |
---
## 三、API接口
### 3.1 BOM管理接口
#### 3.1.1 获取BOM列表
```
GET /api/v1/boms
```
**查询参数:**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| product_id | int | 否 | 产品ID |
| status | string | 否 | 状态筛选 |
| type | string | 否 | 类型筛选 |
| keyword | string | 否 | 关键词 |
| page | int | 否 | 页码 |
| page_size | int | 否 | 每页数量 |
**响应示例:**
```json
{
"code": 0,
"data": {
"items": [
{
"id": 1,
"product_id": 1,
"code": "BOM-001",
"name": "产品A物料清单",
"version": "1.0",
"type": "manufacturing",
"status": "released",
"item_count": 15,
"created_at": "2026-03-31T10:00:00Z"
}
],
"pagination": {
"total": 10,
"page": 1,
"page_size": 20
}
}
}
```
#### 3.1.2 获取BOM详情
```
GET /api/v1/boms/{bom_id}
```
**响应示例:**
```json
{
"code": 0,
"data": {
"id": 1,
"product_id": 1,
"code": "BOM-001",
"name": "产品A物料清单",
"version": "1.0",
"type": "manufacturing",
"status": "released",
"items": [
{
"id": 1,
"level": 1,
"sequence": 1,
"material_code": "M001",
"material_name": "零件A",
"quantity": 10,
"unit": "pcs",
"scrap_rate": 0.05
}
],
"ai_analysis_status": "completed",
"ai_recommendation": "建议使用替代物料M002可降低成本15%"
}
}
```
#### 3.1.3 创建BOM
```
POST /api/v1/boms
```
**请求体:**
```json
{
"product_id": 1,
"code": "BOM-001",
"name": "产品A物料清单",
"type": "manufacturing",
"items": [
{
"material_code": "M001",
"quantity": 10,
"unit": "pcs",
"scrap_rate": 0.05
}
]
}
```
#### 3.1.4 更新BOM
```
PUT /api/v1/boms/{bom_id}
```
#### 3.1.5 删除BOM
```
DELETE /api/v1/boms/{bom_id}
```
### 3.2 BOM操作接口
#### 3.2.1 BOM展开
```
GET /api/v1/boms/{bom_id}/expand
```
**查询参数:**
| 参数 | 类型 | 说明 |
|------|------|------|
| level | int | 展开层级,-1为全部展开 |
**响应示例:**
```json
{
"code": 0,
"data": {
"bom_id": 1,
"expand_type": "full",
"items": [
{
"level": 1,
"material_code": "M001",
"material_name": "部件A",
"quantity": 1,
"children": [
{
"level": 2,
"material_code": "M101",
"material_name": "零件A1",
"quantity": 5,
"children": []
}
]
}
],
"total_items": 15,
"total_levels": 3
}
}
```
#### 3.2.2 BOM对比
```
POST /api/v1/boms/compare
```
**请求体:**
```json
{
"bom_id_1": 1,
"bom_id_2": 2
}
```
**响应示例:**
```json
{
"code": 0,
"data": {
"added": [
{
"material_code": "M005",
"material_name": "新增零件",
"quantity": 2
}
],
"removed": [
{
"material_code": "M003",
"material_name": "删除零件",
"quantity": 1
}
],
"modified": [
{
"material_code": "M001",
"old_quantity": 10,
"new_quantity": 15,
"change_percent": 50
}
],
"unchanged": 12
}
}
```
#### 3.2.3 BOM复制
```
POST /api/v1/boms/{bom_id}/copy
```
**请求体:**
```json
{
"new_code": "BOM-001-COPY",
"new_name": "产品A物料清单副本"
}
```
### 3.3 AI智能接口
#### 3.3.1 AI优化建议
```
POST /api/v1/boms/{bom_id}/ai-optimize
```
**响应示例:**
```json
{
"code": 0,
"data": {
"optimizations": [
{
"type": "material_substitution",
"priority": "high",
"original_material": "M001",
"suggested_material": "M002",
"reason": "成本降低15%,性能相当",
"confidence": 0.88,
"estimated_savings": 1500.00
},
{
"type": "quantity_optimization",
"material_code": "M003",
"current_quantity": 10,
"suggested_quantity": 8,
"reason": "根据历史数据分析可减少20%用量",
"confidence": 0.82
}
],
"similar_boms": [
{
"id": 5,
"product_name": "相似产品B",
"similarity": 0.85,
"common_items": 12
}
]
}
}
```
#### 3.3.2 相似BOM检测
```
POST /api/v1/boms/{bom_id}/similarity
```
**响应示例:**
```json
{
"code": 0,
"data": {
"similar_boms": [
{
"id": 3,
"product_name": "产品B",
"similarity_score": 0.92,
"matching_items": 15,
"total_items": 18
}
]
}
}
```
---
## 四、C++引擎层
### 4.1 BOM计算引擎
**服务名:** `plm-engine-bom`
**核心功能:**
- 高性能BOM层级展开
- BOM差异计算
- BOM成本估算ONNX模型推理
**pybind11绑定示例**
```cpp
// bom_engine.cpp
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <vector>
#include <unordered_map>
namespace py = pybind11;
struct BOMItem {
int id;
int parent_id;
std::string material_code;
double quantity;
int level;
};
class BOMEngine {
public:
// BOM展开
std::vector<BOMItem> expandBOM(
const std::vector<BOMItem>& items,
int max_level = -1
) {
// 实现BOM展开逻辑
}
// BOM差异计算
std::unordered_map<std::string, std::vector<BOMItem>> compareBOMs(
const std::vector<BOMItem>& bom1,
const std::vector<BOMItem>& bom2
) {
// 实现BOM对比逻辑
}
// BOM成本估算ONNX推理
double estimateCost(
const std::vector<BOMItem>& items,
const std::string& model_path
) {
// ONNX模型推理
}
};
PYBIND11_MODULE(bom_engine, m) {
py::class_<BOMItem>(m, "BOMItem")
.def(py::init<>())
.def_readwrite("id", &BOMItem::id)
.def_readwrite("parent_id", &BOMItem::parent_id)
.def_readwrite("material_code", &BOMItem::material_code)
.def_readwrite("quantity", &BOMItem::quantity)
.def_readwrite("level", &BOMItem::level);
py::class_<BOMEngine>(m, "BOMEngine")
.def(py::init<>())
.def("expand_bom", &BOMEngine::expandBOM)
.def("compare_boms", &BOMEngine::compareBOMs)
.def("estimate_cost", &BOMEngine::estimateCost);
}
```
### 4.2 Python调用示例
```python
# services/bom_engine.py
from bom_engine import BOMEngine, BOMItem
class BOMEngineService:
def __init__(self):
self.engine = BOMEngine()
def expand_bom(self, items: list, max_level: int = -1) -> list:
"""展开BOM"""
bom_items = [
BOMItem(
id=item['id'],
parent_id=item['parent_id'],
material_code=item['material_code'],
quantity=item['quantity'],
level=item['level']
)
for item in items
]
result = self.engine.expand_bom(bom_items, max_level)
return [
{
'id': item.id,
'parent_id': item.parent_id,
'material_code': item.material_code,
'quantity': item.quantity,
'level': item.level
}
for item in result
]
```
---
## 五、AI模块
### 5.1 BOM优化器
```python
# ai/bom_optimizer.py
from openai import OpenAI
from app.core.config import settings
class BOMOptimizer:
def __init__(self):
self.client = OpenAI(api_key=settings.AI_API_KEY)
async def optimize_bom(self, bom_data: dict) -> dict:
"""AI优化BOM"""
prompt = f"""
分析以下BOM数据提供优化建议
BOM名称{bom_data['name']}
物料清单:
{self._format_items(bom_data['items'])}
请从以下角度分析:
1. 物料替代建议(成本更低/性能更好)
2. 数量优化建议
3. 层级结构优化建议
"""
response = await self.client.chat.completions.create(
model=settings.AI_MODEL,
messages=[
{"role": "system", "content": "你是PLM系统的BOM优化专家"},
{"role": "user", "content": prompt}
]
)
return self._parse_optimization(response.choices[0].message.content)
def _format_items(self, items: list) -> str:
return "\n".join([
f"- {item['material_code']}: {item['material_name']} x {item['quantity']} {item['unit']}"
for item in items
])
```
### 5.2 相似度检测
```python
# ai/similarity.py
from pgvector.sqlalchemy import Vector
from sqlalchemy import text
from app.core.database import engine
class BOMSimilarityService:
def __init__(self):
self.dimension = 1536 # OpenAI embedding维度
async def find_similar_boms(
self,
bom_id: int,
threshold: float = 0.8,
limit: int = 5
) -> list:
"""查找相似BOM"""
query = text("""
SELECT
b.id,
b.name,
b.code,
1 - (b.embedding_vector <=> (
SELECT embedding_vector FROM boms WHERE id = :bom_id
)) as similarity
FROM boms b
WHERE b.id != :bom_id
AND b.status = 'released'
AND 1 - (b.embedding_vector <=> (
SELECT embedding_vector FROM boms WHERE id = :bom_id
)) >= :threshold
ORDER BY similarity DESC
LIMIT :limit
""")
async with engine.begin() as conn:
result = await conn.execute(
query,
{"bom_id": bom_id, "threshold": threshold, "limit": limit}
)
return result.fetchall()
```
---
## 六、业务流程
### 6.1 BOM创建流程
```
1. 创建BOM主记录
2. 添加BOM明细项
3. 校验物料有效性
4. 计算层级结构
5. 生成向量嵌入
6. AI分析异步
7. 返回创建结果
```
### 6.2 BOM审批流程
```
草稿 → 提交审批 → 审批中 → 已批准/已拒绝
发布
```
### 6.3 BOM版本管理
```
1. 创建新版本
2. 复制当前BOM
3. 修改内容
4. 生成版本差异
5. AI影响分析
6. 提交审批
```
---
## 七、性能指标
### 7.1 响应时间要求
| 操作 | 响应时间 | 说明 |
|------|----------|------|
| 获取BOM列表 | < 200ms | 含分页 |
| 获取BOM详情 | < 300ms | 含明细 |
| 创建BOM | < 500ms | 含校验 |
| BOM展开 | < 1s | 5层以内 |
| BOM对比 | < 2s | 100项以内 |
| AI优化 | < 5s | 含推理 |
### 7.2 缓存策略
| 数据 | 缓存时间 | 缓存键 |
|------|----------|--------|
| BOM详情 | 5分钟 | bom:{id} |
| BOM展开结果 | 10分钟 | bom:{id}:expand:{level} |
| AI优化结果 | 1小时 | bom:{id}:optimize |
---
## 八、错误处理
### 8.1 错误码定义
| 错误码 | 说明 |
|--------|------|
| 50001 | BOM不存在 |
| 50002 | BOM版本冲突 |
| 50003 | 物料不存在 |
| 50004 | 层级超限 |
| 50005 | AI分析失败 |
### 8.2 异常处理示例
```python
from fastapi import HTTPException, status
class BOMNotFoundError(Exception):
pass
class BOMVersionConflictError(Exception):
pass
@router.get("/boms/{bom_id}")
async def get_bom(bom_id: int):
try:
bom = await bom_service.get_bom(bom_id)
if not bom:
raise BOMNotFoundError(f"BOM {bom_id} not found")
return bom
except BOMNotFoundError as e:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=str(e)
)
```
---
## 九、部署配置
### 9.1 Docker配置
```yaml
# docker-compose.yml
services:
plm-bom-service:
build:
context: .
dockerfile: Dockerfile
ports:
- "8003:8000"
- "50053:50051"
environment:
DATABASE_URL: postgresql://plm:plm123@postgres:5432/plm_db
REDIS_URL: redis://redis:6379/0
AI_API_KEY: ${AI_API_KEY}
depends_on:
- postgres
- redis
```
### 9.2 环境变量
```bash
# BOM服务配置
BOM_SERVICE_PORT=8003
BOM_GRPC_PORT=50053
BOM_MAX_LEVELS=10
BOM_MAX_ITEMS=1000
# AI配置
AI_OPTIMIZATION_ENABLED=true
AI_SIMILARITY_THRESHOLD=0.8
```
---
## 十、附录
### 10.1 BOM类型枚举
| 类型 | 说明 |
|------|------|
| design | 设计BOM |
| manufacturing | 制造BOM |
| service | 服务BOM |
| sales | 销售BOM |
### 10.2 BOM状态枚举
| 状态 | 说明 |
|------|------|
| draft | 草稿 |
| submitted | 已提交 |
| approved | 已批准 |
| rejected | 已拒绝 |
| released | 已发布 |
| frozen | 已冻结 |
| obsolete | 已废弃 |
---
_创建时间2026-03-31 20:35_
_维护人笔杆子 (creator)_

View File

@@ -0,0 +1,246 @@
# PLM 系统技术文档摘要
> **版本**V1.0
> **创建时间**2026-03-31
> **创建人**:笔杆子 (creator)
> **状态**:已发布
---
## 一、项目概述
### 1.1 项目名称
PLM System - 产品生命周期管理系统
### 1.2 项目周期
- **总周期**48周
- **当前进度**M0完成100%M1进行中5%
### 1.3 项目规模
- **任务总数**198项
- **里程碑数**7个M0-M6
---
## 二、团队组织
### 2.1 团队规模
- **总人数**14人
- **工作模式**7×24自主运行心跳30分钟
### 2.2 架构分层
| 层级 | 角色 | 人数 | 汇报对象 |
|------|------|------|----------|
| 私人助理 | 小哈 | 1人 | 老大 |
| C-Level高管 | CEO/COO/CTO/CMO/参谋 | 5人 | 老大 |
| 研发体系 | 研发总监+前端+后端+测试+产品 | 5人 | CTO |
| 支撑体系 | 文档总监+运维总监+知识工程师 | 3人 | COO/CTO |
---
## 三、技术架构
### 3.1 统一技术栈
| 层级 | 技术 | 版本 |
|------|------|------|
| 后端语言 | Python | 3.11 |
| Web框架 | FastAPI | 0.100+ |
| ORM | SQLAlchemy | 2.0 |
| 数据验证 | Pydantic | 2.0 |
| 微服务通信 | gRPC + Protobuf | - |
| 数据库 | PostgreSQL + pgvector | 16 |
| 缓存 | Redis | 7 |
| 消息队列 | RabbitMQ | 3.12 |
| 对象存储 | MinIO | - |
| 搜索引擎 | OpenSearch | - |
| 前端框架 | Vue 3 + TypeScript | 3.4+ |
| UI组件 | Element Plus | 2.5 |
| 状态管理 | Pinia | 2.1 |
| C++引擎 | C++17/20 + pybind11 | - |
### 3.2 架构特点10大特点
1. **前后端分离** - Vue 3 + FastAPI
2. **C++引擎层** - 高性能计算核心
3. **gRPC通信** - 高效服务间通信
4. **pybind11绑定** - C++/Python无缝集成
5. **AI原生架构** - 每个服务都有AI集成点
6. **向量搜索** - pgvector语义搜索
7. **异步处理** - FastAPI async + RabbitMQ
8. **类型安全** - TypeScript + Pydantic
9. **容器化部署** - Docker + Kubernetes
10. **微服务架构** - 业务导向服务拆分
### 3.3 微服务清单11个
| 服务名 | 职责 | AI能力 |
|--------|------|--------|
| plm-auth-service | 系统管理 | 智能权限推荐 |
| plm-product-service | 产品管理 | AI分类/智能推荐 |
| plm-bom-service | BOM管理 | AI优化建议/相似检测 |
| plm-route-service | 工艺管理 | AI工艺推荐 |
| plm-document-service | 文档管理 | AI智能标签/内容摘要 |
| plm-change-service | 变更管理 | AI风险预测/影响分析 |
| plm-notification-service | 通知管理 | AI智能推送策略 |
| plm-report-service | 报表管理 | AI报表生成/智能分析 |
| plm-workflow-service | 工作流管理 | AI流程推荐/智能审批 |
| plm-search-service | 搜索服务 | 向量搜索+NLP查询 |
| plm-ai-service | AI核心服务 | 模型管理/向量嵌入 |
---
## 四、AI原生能力
### 4.1 AI能力清单12项
| # | 能力 | 说明 |
|---|------|------|
| 1 | 智能BOM推荐 | AI分析相似产品 |
| 2 | 自然语言查询 | NL2SQL转换 |
| 3 | 智能文档生成 | AI辅助编写 |
| 4 | 变更风险预测 | AI分析影响范围 |
| 5 | 智能分类标签 | AI自动分类 |
| 6 | 智能数据校验 | AI检测异常 |
| 7 | 向量搜索引擎 | pgvector语义搜索 |
| 8 | AI搜索助手 | 智能补全/建议 |
| 9 | 多模态搜索 | 图片/CAD/文档搜索 |
| 10 | AI性能监控 | 推理延迟/Token统计 |
| 11 | 模型版本管理 | A/B测试/灰度发布 |
| 12 | 代码生成助手 | AI辅助开发 |
### 4.2 AI架构原则
1. 每个服务都有AI集成点
2. 数据模型支持AI分析字段
3. API支持AI调用方式流式/批量/异步)
4. 前端支持AI交互组件
---
## 五、数据库设计
### 5.1 数据库选型
| 组件 | 技术 | 说明 |
|------|------|------|
| 主数据库 | PostgreSQL 16 | 企业级关系数据库 |
| 向量扩展 | pgvector | AI向量搜索 |
| 缓存 | Redis 7 | 高性能缓存 |
### 5.2 AI相关表结构
| 表名 | 说明 |
|------|------|
| embeddings | 向量嵌入表 |
| ai_analysis_results | AI分析结果表 |
| ai_models | AI模型配置表 |
| ai_prompts | Prompt模板表 |
| ai_call_logs | AI调用日志表 |
| ai_recommendation_cache | 推荐缓存表 |
### 5.3 业务表AI字段
每个业务表新增:
- `ai_analysis_status` - AI分析状态
- `ai_recommendation` - AI推荐内容
- `embedding_vector` - 向量嵌入
- `ai_confidence_score` - AI置信度
---
## 六、里程碑规划
| 里程碑 | 周期 | 任务数 | 重点内容 |
|--------|------|--------|----------|
| M0 | 1-6周 | 11项 | 项目启动、基础设施 |
| M1 | 7-18周 | 60项 | 核心PLM功能模块 |
| M2 | 19-28周 | 34项 | 服务集成与扩展 |
| M3 | 29-36周 | 27项 | AI集成、高级功能 |
| M4 | 37-40周 | 15项 | 性能优化、安全加固 |
| M5 | 41-44周 | 13项 | 全面测试与QA |
| M6 | 45-48周 | 16项 | 生产部署与上线 |
---
## 七、仓库命名规范
### 7.1 当前仓库数量
**19个仓库**
### 7.2 命名架构
| 层级 | 命名格式 | 示例 |
|------|----------|------|
| C++引擎层 | plm-engine-* | plm-engine-bom |
| Python微服务 | plm-*-service | plm-auth-service |
| gRPC通信层 | plm-grpc-proto | plm-grpc-proto |
| 前端应用 | plm-web-* | plm-web-frontend |
| 基础设施 | plm-infra-* | plm-infra-k8s |
| 开发工作区 | workspace-dev* | workspace-dev1 |
---
## 八、业务模块
### 8.1 核心模块P0
| 模块 | AI能力 |
|------|--------|
| 系统管理 | 智能权限推荐 |
| 产品管理 | AI分类/语义搜索 |
| BOM管理 | AI优化/相似检测 |
### 8.2 重要模块P1
| 模块 | AI能力 |
|------|--------|
| AI服务 | LLM/向量核心能力 |
| 工艺管理 | AI工艺推荐 |
| 文档管理 | AI标签/语义搜索 |
| 变更管理 | AI风险预测 |
---
## 九、开发环境
### 9.1 服务端口
| 服务 | 端口 |
|------|------|
| PostgreSQL | 5432 |
| Redis | 6379 |
| Nacos | 8848 |
| RabbitMQ | 5672 |
| MinIO | 9000 |
| OpenSearch | 9200 |
| 后端服务HTTP | 8001-8010 |
| 后端服务gRPC | 50051-50060 |
| 前端服务 | 5173 |
### 9.2 默认管理员
```
用户名: admin
密码: Admin@123456
```
---
## 十、相关链接
| 资源 | 链接 |
|------|------|
| 任务清单 | https://www.kdocs.cn/l/cnW2jdHWgNib |
| 组织架构 | https://www.kdocs.cn/l/cd45R9zosieP |
| 技术架构 | https://www.kdocs.cn/l/cvWwrJysIbiu |
| 仓库规范 | https://www.kdocs.cn/l/ccHxw48bJQPH |
| 业务模块 | https://www.kdocs.cn/l/cphkaiMTu4lo |
| 数据库设计 | https://www.kdocs.cn/l/coHA4F8KEk2U |
| 问题清单 | https://www.kdocs.cn/l/cdEAQy9VT7yo |
---
_创建时间2026-03-31 20:10_
_维护人笔杆子 (creator)_

View File

@@ -0,0 +1,973 @@
# M1-S4 开发手册 - 产品数据管理(进阶)
> **版本**V1.0
> **创建时间**2026-03-31
> **创建人**:笔杆子 (creator)
> **状态**:已发布
> **里程碑**M1 核心PLM功能模块
> **阶段**S4 产品数据管理-进阶
> **周期**第9-10周
---
## 一、阶段概述
### 1.1 阶段目标
完成产品数据管理进阶功能开发包括BOM管理、属性模板、批量导入导出、数据校验等核心功能。
### 1.2 任务清单
| 任务编号 | 任务名称 | 负责人 | 预计工时 | 状态 |
|----------|----------|--------|----------|------|
| M1-007 | BOM物料清单数据模型 | 后端工程师 | 2天 | 🔄 进行中 |
| M1-008 | BOM管理API开发 | 后端工程师 | 3天 | ⏳ 待开始 |
| M1-009 | BOM树形展示页面 | 前端工程师 | 2天 | ⏳ 待开始 |
| M1-010 | 产品属性自定义模板 | 后端工程师 | 2天 | ⏳ 待开始 |
| M1-011 | 批量导入导出功能 | 后端工程师 | 2天 | ⏳ 待开始 |
| M1-012 | 数据校验规则引擎 | 后端工程师 | 3天 | ⏳ 待开始 |
**总计14天2周**
---
## 二、M1-007BOM数据模型
### 2.1 数据库设计
#### 2.1.1 BOM主表 DDL
```sql
-- BOM主表
CREATE TABLE boms (
id SERIAL PRIMARY KEY,
product_id INTEGER NOT NULL REFERENCES products(id),
code VARCHAR(50) UNIQUE NOT NULL,
name VARCHAR(200) NOT NULL,
version VARCHAR(20) NOT NULL DEFAULT '1.0',
type VARCHAR(20) NOT NULL DEFAULT 'manufacturing',
status VARCHAR(20) NOT NULL DEFAULT 'draft',
parent_bom_id INTEGER REFERENCES boms(id),
effective_date DATE,
expiry_date DATE,
-- AI字段
ai_analysis_status VARCHAR(20) DEFAULT 'pending',
ai_recommendation TEXT,
ai_confidence_score FLOAT,
embedding_vector VECTOR(1536),
-- 审计字段
created_by INTEGER REFERENCES users(id),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT uk_bom_product_version UNIQUE (product_id, version)
);
-- 索引
CREATE INDEX idx_boms_product_id ON boms(product_id);
CREATE INDEX idx_boms_status ON boms(status);
CREATE INDEX idx_boms_code ON boms(code);
```
#### 2.1.2 BOM明细表 DDL
```sql
-- BOM明细表
CREATE TABLE bom_items (
id SERIAL PRIMARY KEY,
bom_id INTEGER NOT NULL REFERENCES boms(id) ON DELETE CASCADE,
parent_item_id INTEGER REFERENCES bom_items(id),
level INTEGER NOT NULL DEFAULT 1,
sequence INTEGER NOT NULL DEFAULT 0,
-- 物料信息
material_id INTEGER REFERENCES materials(id),
material_code VARCHAR(50) NOT NULL,
material_name VARCHAR(200) NOT NULL,
-- 数量信息
quantity DECIMAL(10,4) NOT NULL,
unit VARCHAR(20) NOT NULL,
scrap_rate DECIMAL(5,2) DEFAULT 0,
-- 替代物料
substitute_material_id INTEGER REFERENCES materials(id),
-- 有效期
effective_date DATE,
expiry_date DATE,
-- 其他
remark TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 索引
CREATE INDEX idx_bom_items_bom_id ON bom_items(bom_id);
CREATE INDEX idx_bom_items_material_code ON bom_items(material_code);
CREATE INDEX idx_bom_items_parent_id ON bom_items(parent_item_id);
```
#### 2.1.3 BOM版本差异表 DDL
```sql
-- BOM版本差异表
CREATE TABLE bom_version_diffs (
id SERIAL PRIMARY KEY,
bom_id INTEGER NOT NULL REFERENCES boms(id),
old_version VARCHAR(20) NOT NULL,
new_version VARCHAR(20) NOT NULL,
diff_type VARCHAR(20) NOT NULL,
diff_details JSONB NOT NULL,
ai_impact_analysis TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```
### 2.2 ORM模型
```python
# models/bom.py
from sqlalchemy import Column, Integer, String, Numeric, Date, Text, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
from pgvector.sqlalchemy import Vector
from app.core.database import Base
class BOM(Base):
__tablename__ = "boms"
id = Column(Integer, primary_key=True, index=True)
product_id = Column(Integer, ForeignKey("products.id"), nullable=False)
code = Column(String(50), unique=True, nullable=False)
name = Column(String(200), nullable=False)
version = Column(String(20), nullable=False, default="1.0")
type = Column(String(20), nullable=False, default="manufacturing")
status = Column(String(20), nullable=False, default="draft")
parent_bom_id = Column(Integer, ForeignKey("boms.id"))
effective_date = Column(Date)
expiry_date = Column(Date)
# AI字段
ai_analysis_status = Column(String(20), default="pending")
ai_recommendation = Column(Text)
ai_confidence_score = Column(Numeric(5, 4))
embedding_vector = Column(Vector(1536))
# 审计字段
created_by = Column(Integer, ForeignKey("users.id"))
created_at = Column(DateTime, server_default=func.now())
updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now())
# 关系
product = relationship("Product", back_populates="boms")
items = relationship("BOMItem", back_populates="bom", cascade="all, delete-orphan")
parent_bom = relationship("BOM", remote_side=[id], backref="child_boms")
class BOMItem(Base):
__tablename__ = "bom_items"
id = Column(Integer, primary_key=True, index=True)
bom_id = Column(Integer, ForeignKey("boms.id"), nullable=False)
parent_item_id = Column(Integer, ForeignKey("bom_items.id"))
level = Column(Integer, nullable=False, default=1)
sequence = Column(Integer, nullable=False, default=0)
material_id = Column(Integer, ForeignKey("materials.id"))
material_code = Column(String(50), nullable=False)
material_name = Column(String(200), nullable=False)
quantity = Column(Numeric(10, 4), nullable=False)
unit = Column(String(20), nullable=False)
scrap_rate = Column(Numeric(5, 2), default=0)
substitute_material_id = Column(Integer, ForeignKey("materials.id"))
effective_date = Column(Date)
expiry_date = Column(Date)
remark = Column(Text)
created_at = Column(DateTime, server_default=func.now())
updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now())
# 关系
bom = relationship("BOM", back_populates="items")
children = relationship("BOMItem", backref="parent_item", remote_side=[id])
```
---
## 三、M1-008BOM管理API开发
### 3.1 API路由设计
```python
# api/bom_router.py
from fastapi import APIRouter, Depends, HTTPException, status
from typing import List, Optional
from app.schemas.bom_schemas import (
BOMCreate, BOMUpdate, BOMResponse, BOMDetailResponse,
BOMExpandResponse, BOMCompareRequest, BOMCompareResponse
)
from app.services.bom_service import BOMService
router = APIRouter(prefix="/boms", tags=["BOMs"])
@router.get("/", response_model=List[BOMResponse])
async def list_boms(
product_id: Optional[int] = None,
status: Optional[str] = None,
type: Optional[str] = None,
keyword: Optional[str] = None,
page: int = 1,
page_size: int = 20,
service: BOMService = Depends()
):
"""获取BOM列表"""
return await service.get_boms(
product_id=product_id,
status=status,
type=type,
keyword=keyword,
page=page,
page_size=page_size
)
@router.get("/{bom_id}", response_model=BOMDetailResponse)
async def get_bom(
bom_id: int,
service: BOMService = Depends()
):
"""获取BOM详情"""
bom = await service.get_bom(bom_id)
if not bom:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"BOM {bom_id} not found"
)
return bom
@router.post("/", response_model=BOMResponse, status_code=status.HTTP_201_CREATED)
async def create_bom(
bom: BOMCreate,
service: BOMService = Depends()
):
"""创建BOM"""
return await service.create_bom(bom)
@router.put("/{bom_id}", response_model=BOMResponse)
async def update_bom(
bom_id: int,
bom: BOMUpdate,
service: BOMService = Depends()
):
"""更新BOM"""
return await service.update_bom(bom_id, bom)
@router.delete("/{bom_id}")
async def delete_bom(
bom_id: int,
service: BOMService = Depends()
):
"""删除BOM"""
await service.delete_bom(bom_id)
return {"message": "删除成功"}
@router.get("/{bom_id}/expand", response_model=BOMExpandResponse)
async def expand_bom(
bom_id: int,
level: int = -1,
service: BOMService = Depends()
):
"""展开BOM"""
return await service.expand_bom(bom_id, level)
@router.post("/compare", response_model=BOMCompareResponse)
async def compare_boms(
request: BOMCompareRequest,
service: BOMService = Depends()
):
"""对比BOM"""
return await service.compare_boms(request.bom_id_1, request.bom_id_2)
@router.post("/{bom_id}/copy", response_model=BOMResponse)
async def copy_bom(
bom_id: int,
new_code: str,
new_name: str,
service: BOMService = Depends()
):
"""复制BOM"""
return await service.copy_bom(bom_id, new_code, new_name)
```
### 3.2 业务逻辑实现
```python
# services/bom_service.py
from typing import List, Optional, Dict
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func
from app.models.bom import BOM, BOMItem
from app.schemas.bom_schemas import BOMCreate, BOMUpdate
from app.services.bom_engine import BOMEngineService
from app.ai.bom_optimizer import BOMOptimizer
class BOMService:
def __init__(self, db: AsyncSession):
self.db = db
self.engine = BOMEngineService()
self.optimizer = BOMOptimizer()
async def create_bom(self, bom_data: BOMCreate) -> BOM:
"""创建BOM"""
# 1. 创建BOM主记录
bom = BOM(
product_id=bom_data.product_id,
code=bom_data.code,
name=bom_data.name,
type=bom_data.type
)
self.db.add(bom)
await self.db.flush()
# 2. 添加BOM明细
for item_data in bom_data.items:
item = BOMItem(
bom_id=bom.id,
material_code=item_data.material_code,
material_name=item_data.material_name,
quantity=item_data.quantity,
unit=item_data.unit,
level=item_data.level or 1
)
self.db.add(item)
await self.db.commit()
# 3. 触发AI分析异步
await self._trigger_ai_analysis(bom.id)
return bom
async def expand_bom(self, bom_id: int, max_level: int = -1) -> Dict:
"""展开BOM"""
# 获取所有明细项
result = await self.db.execute(
select(BOMItem).where(BOMItem.bom_id == bom_id)
)
items = result.scalars().all()
# 调用C++引擎展开
expanded_items = self.engine.expand_bom(items, max_level)
return {
"bom_id": bom_id,
"expand_type": "full" if max_level == -1 else f"level_{max_level}",
"items": expanded_items
}
async def compare_boms(self, bom_id_1: int, bom_id_2: int) -> Dict:
"""对比BOM"""
# 获取两个BOM的明细
result1 = await self.db.execute(
select(BOMItem).where(BOMItem.bom_id == bom_id_1)
)
items1 = result1.scalars().all()
result2 = await self.db.execute(
select(BOMItem).where(BOMItem.bom_id == bom_id_2)
)
items2 = result2.scalars().all()
# 调用C++引擎对比
diff = self.engine.compare_boms(items1, items2)
return diff
```
---
## 四、M1-009BOM树形展示页面
### 4.1 组件设计
```vue
<!-- views/BOM/BOMTree.vue -->
<template>
<div class="bom-tree-container">
<div class="bom-tree-header">
<h3>{{ bomInfo.name }} - 物料清单</h3>
<div class="bom-tree-actions">
<el-button @click="expandAll">全部展开</el-button>
<el-button @click="collapseAll">全部折叠</el-button>
<el-button type="primary" @click="exportBOM">导出</el-button>
</div>
</div>
<el-tree
ref="treeRef"
:data="treeData"
:props="treeProps"
node-key="id"
:expand-on-click-node="false"
:default-expand-all="false"
>
<template #default="{ node, data }">
<div class="bom-item">
<span class="item-code">{{ data.material_code }}</span>
<span class="item-name">{{ data.material_name }}</span>
<span class="item-quantity">
{{ data.quantity }} {{ data.unit }}
</span>
<span class="item-level">L{{ data.level }}</span>
<div class="item-actions">
<el-button size="small" @click="editItem(data)">编辑</el-button>
<el-button size="small" type="danger" @click="deleteItem(data)">
删除
</el-button>
</div>
</div>
</template>
</el-tree>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useRoute } from 'vue-router'
import { getBOMDetail, expandBOM } from '@/api/boms'
interface BOMItem {
id: number
material_code: string
material_name: string
quantity: number
unit: string
level: number
children?: BOMItem[]
}
const route = useRoute()
const treeRef = ref()
const bomInfo = ref<any>({})
const treeData = ref<BOMItem[]>([])
const treeProps = {
children: 'children',
label: 'material_name'
}
onMounted(async () => {
const bomId = route.params.id as string
await loadBOMTree(Number(bomId))
})
async function loadBOMTree(bomId: number) {
// 获取BOM详情
const detail = await getBOMDetail(bomId)
bomInfo.value = detail.data
// 获取展开数据
const expand = await expandBOM(bomId, -1)
treeData.value = buildTree(expand.data.items)
}
function buildTree(items: any[]): BOMItem[] {
const map = new Map()
const roots: BOMItem[] = []
// 构建映射
items.forEach(item => {
map.set(item.id, { ...item, children: [] })
})
// 构建树
items.forEach(item => {
const node = map.get(item.id)
if (item.parent_item_id) {
const parent = map.get(item.parent_item_id)
if (parent) {
parent.children.push(node)
}
} else {
roots.push(node)
}
})
return roots
}
function expandAll() {
const nodes = treeRef.value?.store?.nodesMap
for (const key in nodes) {
nodes[key].expanded = true
}
}
function collapseAll() {
const nodes = treeRef.value?.store?.nodesMap
for (const key in nodes) {
nodes[key].expanded = false
}
}
</script>
<style scoped>
.bom-tree-container {
padding: 20px;
}
.bom-item {
display: flex;
align-items: center;
gap: 16px;
width: 100%;
}
.item-code {
font-weight: bold;
color: #409eff;
}
.item-quantity {
color: #67c23a;
}
.item-level {
background: #f4f4f5;
padding: 2px 8px;
border-radius: 4px;
font-size: 12px;
}
</style>
```
---
## 五、M1-010产品属性自定义模板
### 5.1 数据模型
```sql
-- 属性模板表
CREATE TABLE attribute_templates (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
description TEXT,
category_id INTEGER REFERENCES product_categories(id),
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 属性定义表
CREATE TABLE attribute_definitions (
id SERIAL PRIMARY KEY,
template_id INTEGER REFERENCES attribute_templates(id) ON DELETE CASCADE,
name VARCHAR(50) NOT NULL,
label VARCHAR(100) NOT NULL,
type VARCHAR(20) NOT NULL, -- string, number, select, date, etc.
required BOOLEAN DEFAULT false,
default_value TEXT,
validation_rule TEXT,
options JSONB, -- 用于select类型的选项
sort_order INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```
### 5.2 模板服务
```python
# services/attribute_template_service.py
from typing import List, Dict
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from app.models.attribute_template import AttributeTemplate, AttributeDefinition
class AttributeTemplateService:
def __init__(self, db: AsyncSession):
self.db = db
async def get_template(self, template_id: int) -> Dict:
"""获取模板及其属性定义"""
result = await self.db.execute(
select(AttributeTemplate)
.where(AttributeTemplate.id == template_id)
)
template = result.scalar_one()
result = await self.db.execute(
select(AttributeDefinition)
.where(AttributeDefinition.template_id == template_id)
.order_by(AttributeDefinition.sort_order)
)
definitions = result.scalars().all()
return {
"id": template.id,
"name": template.name,
"attributes": [
{
"name": d.name,
"label": d.label,
"type": d.type,
"required": d.required,
"default_value": d.default_value,
"validation_rule": d.validation_rule,
"options": d.options
}
for d in definitions
]
}
async def validate_attributes(
self,
template_id: int,
attributes: Dict
) -> Dict:
"""验证属性值"""
template = await self.get_template(template_id)
errors = []
for attr_def in template["attributes"]:
name = attr_def["name"]
value = attributes.get(name)
# 必填校验
if attr_def["required"] and not value:
errors.append(f"{attr_def['label']} 不能为空")
continue
# 类型校验
if value:
try:
if attr_def["type"] == "number":
float(value)
elif attr_def["type"] == "select":
if value not in (attr_def["options"] or []):
errors.append(f"{attr_def['label']} 值无效")
except ValueError:
errors.append(f"{attr_def['label']} 类型错误")
return {"valid": len(errors) == 0, "errors": errors}
```
---
## 六、M1-011批量导入导出功能
### 6.1 导入服务
```python
# services/import_export_service.py
import pandas as pd
from io import BytesIO
from typing import List, Dict
from fastapi import UploadFile
class ImportExportService:
def __init__(self, db: AsyncSession):
self.db = db
async def import_products(
self,
file: UploadFile,
update_existing: bool = False
) -> Dict:
"""导入产品"""
# 读取Excel
content = await file.read()
df = pd.read_excel(BytesIO(content))
results = {
"total": len(df),
"success": 0,
"failed": 0,
"errors": []
}
for index, row in df.iterrows():
try:
# 验证数据
validation = self._validate_row(row)
if not validation["valid"]:
results["errors"].append({
"row": index + 2,
"code": row.get("code"),
"error": validation["error"]
})
results["failed"] += 1
continue
# 创建或更新产品
await self._create_or_update_product(row, update_existing)
results["success"] += 1
except Exception as e:
results["errors"].append({
"row": index + 2,
"code": row.get("code"),
"error": str(e)
})
results["failed"] += 1
await self.db.commit()
return results
async def export_products(
self,
product_ids: List[int] = None,
category_id: int = None,
format: str = "xlsx"
) -> BytesIO:
"""导出产品"""
# 查询产品
query = select(Product)
if product_ids:
query = query.where(Product.id.in_(product_ids))
if category_id:
query = query.where(Product.category_id == category_id)
result = await self.db.execute(query)
products = result.scalars().all()
# 转换为DataFrame
data = [
{
"编码": p.code,
"名称": p.name,
"描述": p.description,
"分类": p.category.name if p.category else "",
"状态": p.status,
"规格": str(p.specifications) if p.specifications else ""
}
for p in products
]
df = pd.DataFrame(data)
# 导出
output = BytesIO()
if format == "xlsx":
df.to_excel(output, index=False)
else:
df.to_csv(output, index=False)
output.seek(0)
return output
```
---
## 七、M1-012数据校验规则引擎
### 7.1 规则引擎设计
```python
# services/validation_engine.py
from typing import Dict, List, Any
import re
class ValidationRule:
def __init__(self, rule_type: str, params: Dict):
self.rule_type = rule_type
self.params = params
def validate(self, value: Any) -> Dict:
"""执行校验"""
pass
class RequiredRule(ValidationRule):
def validate(self, value: Any) -> Dict:
if value is None or value == "":
return {"valid": False, "error": "字段不能为空"}
return {"valid": True}
class PatternRule(ValidationRule):
def validate(self, value: Any) -> Dict:
pattern = self.params.get("pattern")
if not re.match(pattern, str(value)):
return {
"valid": False,
"error": self.params.get("message", "格式不正确")
}
return {"valid": True}
class RangeRule(ValidationRule):
def validate(self, value: Any) -> Dict:
min_val = self.params.get("min")
max_val = self.params.get("max")
try:
num = float(value)
if min_val is not None and num < min_val:
return {"valid": False, "error": f"值不能小于{min_val}"}
if max_val is not None and num > max_val:
return {"valid": False, "error": f"值不能大于{max_val}"}
return {"valid": True}
except ValueError:
return {"valid": False, "error": "不是有效的数字"}
class ValidationEngine:
RULE_TYPES = {
"required": RequiredRule,
"pattern": PatternRule,
"range": RangeRule
}
def __init__(self):
self.rules: Dict[str, List[ValidationRule]] = {}
def add_rule(self, field: str, rule_type: str, params: Dict = None):
"""添加校验规则"""
if field not in self.rules:
self.rules[field] = []
rule_class = self.RULE_TYPES.get(rule_type)
if rule_class:
self.rules[field].append(rule_class(rule_type, params or {}))
def validate(self, data: Dict) -> Dict:
"""校验数据"""
errors = {}
for field, rules in self.rules.items():
value = data.get(field)
for rule in rules:
result = rule.validate(value)
if not result["valid"]:
if field not in errors:
errors[field] = []
errors[field].append(result["error"])
return {
"valid": len(errors) == 0,
"errors": errors
}
# 使用示例
engine = ValidationEngine()
engine.add_rule("code", "required")
engine.add_rule("code", "pattern", {
"pattern": r"^P\d{3,}$",
"message": "编码格式P开头+至少3位数字"
})
engine.add_rule("weight", "range", {"min": 0, "max": 10000})
result = engine.validate({
"code": "P001",
"weight": 150
})
```
---
## 八、测试用例
### 8.1 BOM服务测试
```python
# tests/test_bom_service.py
import pytest
from httpx import AsyncClient
from app.main import app
@pytest.mark.asyncio
async def test_create_bom():
async with AsyncClient(app=app, base_url="http://test") as client:
response = await client.post(
"/api/v1/boms",
json={
"product_id": 1,
"code": "BOM-TEST-001",
"name": "测试BOM",
"type": "manufacturing",
"items": [
{
"material_code": "M001",
"material_name": "测试物料",
"quantity": 10,
"unit": "pcs",
"level": 1
}
]
}
)
assert response.status_code == 201
data = response.json()
assert data["code"] == "BOM-TEST-001"
@pytest.mark.asyncio
async def test_expand_bom():
async with AsyncClient(app=app, base_url="http://test") as client:
# 先创建BOM
# ...
# 测试展开
response = await client.get("/api/v1/boms/1/expand?level=-1")
assert response.status_code == 200
data = response.json()
assert "items" in data
```
---
## 九、交付清单
### 9.1 代码交付
- [ ] BOM数据模型models/bom.py
- [ ] BOM API路由api/bom_router.py
- [ ] BOM业务服务services/bom_service.py
- [ ] BOM树形组件views/BOM/BOMTree.vue
- [ ] 属性模板服务
- [ ] 导入导出服务
- [ ] 校验规则引擎
### 9.2 文档交付
- [ ] API接口文档
- [ ] 数据库设计文档
- [ ] 组件使用文档
- [ ] 测试报告
### 9.3 验收标准
| 验收项 | 标准 |
|--------|------|
| 功能完整性 | 6项任务全部完成 |
| API测试覆盖率 | > 80% |
| 前端组件可运行 | 无报错 |
| 数据校验有效 | 所有规则生效 |
---
## 十、风险与应对
| 风险 | 影响 | 应对措施 |
|------|------|----------|
| BOM层级过深 | 性能问题 | 使用C++引擎优化 |
| 导入数据量大 | 内存溢出 | 分批处理+流式导入 |
| 校验规则复杂 | 维护困难 | 规则配置化管理 |
---
_创建时间2026-03-31 20:45_
_维护人笔杆子 (creator)_

View File

@@ -0,0 +1,743 @@
# PLM 系统开发手册
> **版本**V1.0
> **创建时间**2026-03-31
> **创建人**:笔杆子 (creator)
> **状态**:已发布
---
## 第一章 快速开始
### 1.1 项目概述
PLMProduct Lifecycle Management系统是一套产品生命周期管理系统采用AI原生架构设计。
**项目位置:** `/home/serveradmin/plm-system/`
**技术栈:**
- 后端Python 3.11 + FastAPI
- 前端Vue 3 + TypeScript
- 数据库PostgreSQL 16 + pgvector
- 通信gRPC + Protobuf
### 1.2 环境要求
| 软件 | 版本 | 说明 |
|------|------|------|
| Python | 3.11+ | 后端运行环境 |
| Node.js | 18+ | 前端运行环境 |
| PostgreSQL | 16 | 主数据库 |
| Redis | 7 | 缓存服务 |
| Docker | 24+ | 容器化部署 |
### 1.3 快速启动
```bash
# 1. 克隆代码
git clone http://192.168.3.36:3000/plm-team/plm-backend-service.git
# 2. 进入项目目录
cd plm-backend-service
# 3. 创建虚拟环境
python3 -m venv venv
source venv/bin/activate
# 4. 安装依赖
pip install -r requirements.txt
# 5. 配置环境变量
cp .env.example .env
# 编辑 .env 文件
# 6. 启动服务
python3 -m app.main
# 7. 访问API文档
open http://localhost:8000/docs
```
---
## 第二章 项目结构
### 2.1 后端项目结构
```
plm-backend-service/
├── app/
│ ├── __init__.py
│ ├── main.py # FastAPI应用入口
│ ├── init_db.py # 数据库初始化
│ ├── core/ # 核心模块
│ │ ├── __init__.py
│ │ ├── config.py # 配置管理
│ │ ├── database.py # 数据库连接
│ │ ├── security.py # 安全认证
│ │ └── redis.py # Redis缓存
│ ├── models/ # ORM模型
│ │ ├── __init__.py
│ │ ├── user.py # 用户模型
│ │ ├── product.py # 产品模型
│ │ ├── bom.py # BOM模型
│ │ └── document.py # 文档模型
│ ├── schemas/ # Pydantic模型
│ │ ├── __init__.py
│ │ ├── common.py # 公共模型
│ │ ├── user.py # 用户Schema
│ │ ├── product.py # 产品Schema
│ │ └── bom.py # BOM Schema
│ ├── api/ # API路由
│ │ ├── __init__.py
│ │ ├── auth.py # 认证路由
│ │ ├── users.py # 用户路由
│ │ ├── products.py # 产品路由
│ │ └── boms.py # BOM路由
│ └── services/ # 业务逻辑
│ ├── __init__.py
│ ├── user_service.py
│ ├── product_service.py
│ └── bom_service.py
├── tests/ # 测试用例
│ ├── __init__.py
│ ├── conftest.py # 测试配置
│ └── test_api.py # API测试
├── alembic/ # 数据库迁移
│ ├── versions/
│ └── env.py
├── .env.example # 环境变量模板
├── requirements.txt # Python依赖
├── Dockerfile # Docker构建
├── docker-compose.yml # 容器编排
├── .drone.yml # CI/CD配置
└── README.md # 项目说明
```
### 2.2 前端项目结构
```
plm-web-frontend/
├── src/
│ ├── main.ts # 应用入口
│ ├── App.vue # 根组件
│ ├── router/ # 路由配置
│ │ └── index.ts
│ ├── store/ # 状态管理
│ │ ├── index.ts
│ │ └── modules/
│ ├── views/ # 页面组件
│ │ ├── Login.vue
│ │ ├── Dashboard.vue
│ │ ├── Products/
│ │ ├── BOMs/
│ │ └── Documents/
│ ├── components/ # 公共组件
│ │ ├── common/
│ │ └── ai/ # AI交互组件
│ ├── api/ # API调用
│ │ ├── auth.ts
│ │ ├── products.ts
│ │ └── boms.ts
│ ├── utils/ # 工具函数
│ │ ├── request.ts # HTTP封装
│ │ └── auth.ts # 认证工具
│ └── styles/ # 样式文件
├── public/ # 静态资源
├── package.json # 依赖配置
├── vite.config.ts # Vite配置
├── tsconfig.json # TS配置
└── README.md
```
---
## 第三章 环境配置
### 3.1 环境变量配置
创建 `.env` 文件:
```bash
# 应用配置
APP_NAME=PLM System
APP_ENV=development
APP_DEBUG=true
APP_PORT=8000
# 数据库配置
DATABASE_URL=postgresql://plm:plm123@localhost:5432/plm_db
DATABASE_POOL_SIZE=10
DATABASE_MAX_OVERFLOW=20
# Redis配置
REDIS_URL=redis://localhost:6379/0
# JWT配置
JWT_SECRET_KEY=your-secret-key-change-in-production
JWT_ALGORITHM=HS256
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30
JWT_REFRESH_TOKEN_EXPIRE_DAYS=7
# AI服务配置
AI_API_KEY=your-openai-api-key
AI_MODEL=gpt-4
AI_EMBEDDING_MODEL=text-embedding-3-small
# 文件存储配置
STORAGE_TYPE=minio
MINIO_ENDPOINT=localhost:9000
MINIO_ACCESS_KEY=minioadmin
MINIO_SECRET_KEY=minioadmin
MINIO_BUCKET=plm-documents
# gRPC配置
GRPC_PORT=50051
# 日志配置
LOG_LEVEL=INFO
LOG_FILE=logs/app.log
```
### 3.2 Docker Compose配置
`docker-compose.yml`:
```yaml
version: '3.8'
services:
postgres:
image: postgres:16
environment:
POSTGRES_USER: plm
POSTGRES_PASSWORD: plm123
POSTGRES_DB: plm_db
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7
ports:
- "6379:6379"
minio:
image: minio/minio
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
ports:
- "9000:9000"
- "9001:9001"
volumes:
- minio_data:/data
backend:
build: .
ports:
- "8000:8000"
environment:
DATABASE_URL: postgresql://plm:plm123@postgres:5432/plm_db
REDIS_URL: redis://redis:6379/0
depends_on:
- postgres
- redis
volumes:
postgres_data:
minio_data:
```
---
## 第四章 编码规范
### 4.1 Python编码规范
#### 4.1.1 命名规范
```python
# 模块名snake_case
# user_service.py
# 类名PascalCase
class UserService:
pass
# 函数/方法名snake_case
def get_user_by_id(user_id: int) -> User:
pass
# 变量名snake_case
user_name = "admin"
# 常量UPPER_SNAKE_CASE
MAX_RETRY_COUNT = 3
DEFAULT_PAGE_SIZE = 20
# 私有属性_前缀
class User:
def __init__(self):
self._internal_id = None
```
#### 4.1.2 类型注解
```python
from typing import List, Optional, Dict, Any
from datetime import datetime
def create_user(
username: str,
email: str,
role: str = "user",
department_id: Optional[int] = None
) -> User:
"""创建用户"""
pass
def get_users(
page: int = 1,
page_size: int = 20
) -> Dict[str, Any]:
"""获取用户列表"""
return {
"items": [],
"total": 0
}
```
#### 4.1.3 文档字符串
```python
def calculate_bom_cost(bom_id: int) -> float:
"""
计算BOM成本
Args:
bom_id: BOM ID
Returns:
float: 总成本
Raises:
ValueError: BOM不存在时
Example:
>>> cost = calculate_bom_cost(1)
>>> print(cost)
1234.56
"""
pass
```
#### 4.1.4 异常处理
```python
from fastapi import HTTPException, status
def get_product(product_id: int) -> Product:
product = product_repo.get(product_id)
if not product:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Product {product_id} not found"
)
return product
```
### 4.2 TypeScript编码规范
#### 4.2.1 命名规范
```typescript
// 文件名kebab-case
// user-service.ts
// 接口/类名PascalCase
interface UserInfo {
id: number;
name: string;
}
class UserService {
// ...
}
// 函数/变量camelCase
function getUserById(userId: number): Promise<UserInfo> {
// ...
}
const userName = "admin";
// 常量UPPER_SNAKE_CASE
export const MAX_PAGE_SIZE = 20;
// 枚举PascalCase
enum UserStatus {
Active = 'active',
Inactive = 'inactive'
}
```
#### 4.2.2 组件规范
```vue
<template>
<div class="user-list">
<el-table :data="users">
<el-table-column prop="name" label="用户名" />
</el-table>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { getUsers } from '@/api/users'
interface User {
id: number
name: string
}
const users = ref<User[]>([])
onMounted(async () => {
const res = await getUsers()
users.value = res.data.items
})
</script>
<style scoped>
.user-list {
padding: 20px;
}
</style>
```
---
## 第五章 API开发指南
### 5.1 创建新API
#### 步骤1定义Schema
```python
# app/schemas/product.py
from pydantic import BaseModel, Field
from datetime import datetime
from typing import Optional
class ProductBase(BaseModel):
code: str = Field(..., description="产品编码")
name: str = Field(..., description="产品名称")
description: Optional[str] = Field(None, description="产品描述")
category_id: int = Field(..., description="分类ID")
class ProductCreate(ProductBase):
pass
class ProductUpdate(BaseModel):
name: Optional[str] = None
description: Optional[str] = None
status: Optional[str] = None
class ProductResponse(ProductBase):
id: int
status: str
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True
```
#### 步骤2定义Model
```python
# app/models/product.py
from sqlalchemy import Column, Integer, String, DateTime, Text
from sqlalchemy.sql import func
from app.core.database import Base
class Product(Base):
__tablename__ = "products"
id = Column(Integer, primary_key=True, index=True)
code = Column(String(50), unique=True, index=True)
name = Column(String(200), nullable=False)
description = Column(Text)
category_id = Column(Integer, index=True)
status = Column(String(20), default="draft")
created_at = Column(DateTime, server_default=func.now())
updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now())
```
#### 步骤3创建路由
```python
# app/api/products.py
from fastapi import APIRouter, Depends, HTTPException
from typing import List
from app.schemas.product import ProductCreate, ProductResponse
from app.services.product_service import ProductService
router = APIRouter(prefix="/products", tags=["Products"])
@router.get("/", response_model=List[ProductResponse])
async def list_products(
page: int = 1,
page_size: int = 20,
service: ProductService = Depends()
):
"""获取产品列表"""
return await service.get_products(page, page_size)
@router.post("/", response_model=ProductResponse)
async def create_product(
product: ProductCreate,
service: ProductService = Depends()
):
"""创建产品"""
return await service.create_product(product)
@router.get("/{product_id}", response_model=ProductResponse)
async def get_product(
product_id: int,
service: ProductService = Depends()
):
"""获取产品详情"""
product = await service.get_product(product_id)
if not product:
raise HTTPException(status_code=404, detail="Product not found")
return product
```
#### 步骤4注册路由
```python
# app/main.py
from fastapi import FastAPI
from app.api import products, users, auth
app = FastAPI(title="PLM System")
app.include_router(auth.router)
app.include_router(users.router)
app.include_router(products.router)
```
### 5.2 认证中间件
```python
# app/core/security.py
from fastapi import Depends, HTTPException
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from jose import JWTError, jwt
security = HTTPBearer()
async def get_current_user(
credentials: HTTPAuthorizationCredentials = Depends(security)
):
try:
payload = jwt.decode(
credentials.credentials,
settings.JWT_SECRET_KEY,
algorithms=[settings.JWT_ALGORITHM]
)
user_id = payload.get("sub")
if user_id is None:
raise HTTPException(status_code=401, detail="Invalid token")
return user_id
except JWTError:
raise HTTPException(status_code=401, detail="Invalid token")
```
---
## 第六章 测试指南
### 6.1 单元测试
```python
# tests/test_products.py
import pytest
from httpx import AsyncClient
from app.main import app
@pytest.mark.asyncio
async def test_list_products():
async with AsyncClient(app=app, base_url="http://test") as client:
response = await client.get("/products")
assert response.status_code == 200
data = response.json()
assert "items" in data
@pytest.mark.asyncio
async def test_create_product():
async with AsyncClient(app=app, base_url="http://test") as client:
response = await client.post(
"/products",
json={
"code": "P001",
"name": "Test Product",
"category_id": 1
}
)
assert response.status_code == 201
```
### 6.2 运行测试
```bash
# 运行所有测试
pytest
# 运行指定测试文件
pytest tests/test_products.py
# 带覆盖率
pytest --cov=app tests/
# 生成HTML报告
pytest --cov=app --cov-report=html tests/
```
---
## 第七章 部署指南
### 7.1 Docker部署
```bash
# 构建镜像
docker build -t plm-backend:latest .
# 运行容器
docker run -d \
--name plm-backend \
-p 8000:8000 \
--env-file .env \
plm-backend:latest
# 查看日志
docker logs -f plm-backend
```
### 7.2 Kubernetes部署
```yaml
# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: plm-backend
spec:
replicas: 3
selector:
matchLabels:
app: plm-backend
template:
metadata:
labels:
app: plm-backend
spec:
containers:
- name: plm-backend
image: plm-backend:latest
ports:
- containerPort: 8000
envFrom:
- configMapRef:
name: plm-config
- secretRef:
name: plm-secrets
```
---
## 第八章 常见问题
### 8.1 数据库连接问题
```bash
# 检查PostgreSQL状态
sudo systemctl status postgresql
# 检查连接
psql -h localhost -U plm -d plm_db
# 常见错误
# 1. Connection refused -> 检查PostgreSQL是否启动
# 2. Authentication failed -> 检查用户名密码
# 3. Database not found -> 检查数据库是否创建
```
### 8.2 JWT Token问题
```python
# Token过期
# 解决刷新Token或重新登录
# Token无效
# 解决检查JWT_SECRET_KEY是否一致
```
### 8.3 CORS问题
```python
# app/main.py
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:5173"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
```
---
## 第九章 附录
### 9.1 常用命令
```bash
# 后端
uvicorn app.main:app --reload # 开发模式
pytest # 运行测试
alembic revision --autogenerate # 生成迁移
alembic upgrade head # 执行迁移
# 前端
npm run dev # 开发模式
npm run build # 构建生产版本
npm run lint # 代码检查
npm run test # 运行测试
# Docker
docker-compose up -d # 启动服务
docker-compose down # 停止服务
docker-compose logs -f # 查看日志
```
### 9.2 联系方式
| 角色 | 姓名 | 职责 |
|------|------|------|
| CTO | 进化官 | 技术决策 |
| 研发总监 | tech-lead | 代码审核 |
| 文档总监 | 笔杆子 | 文档维护 |
---
_创建时间2026-03-31 20:20_
_维护人笔杆子 (creator)_

View File

@@ -0,0 +1,354 @@
# PLM 开发文档
> **版本**V1.0
> **创建时间**2026-03-31
> **创建人**:笔杆子
> **状态**:草稿
---
## 一、技术栈
### 1.1 后端技术栈
| 技术 | 版本 | 说明 |
|------|------|------|
| Python | 3.11 | 主要开发语言 |
| FastAPI | 0.100+ | Web框架 |
| SQLAlchemy | 2.0 | ORM框架 |
| Pydantic | 2.0 | 数据验证 |
| gRPC | - | 微服务通信 |
| PostgreSQL | 16 | 主数据库 |
| Redis | 7 | 缓存 |
| RabbitMQ | 3.12 | 消息队列 |
### 1.2 前端技术栈
| 技术 | 版本 | 说明 |
|------|------|------|
| Vue | 3.4+ | 前端框架 |
| TypeScript | 5.0 | 类型支持 |
| Element Plus | 2.5 | UI组件库 |
| Pinia | 2.1 | 状态管理 |
| Axios | 1.6 | HTTP客户端 |
| ECharts | 5.4 | 数据可视化 |
### 1.3 C++ 引擎层
| 技术 | 版本 | 说明 |
|------|------|------|
| C++ | 17/20 | 高性能计算 |
| pybind11 | - | Python绑定 |
---
## 二、开发环境搭建
### 2.1 系统要求
- OS: Ubuntu 22.04 / Windows 11
- Python: 3.11+
- Node.js: 18+
- Docker: 24+
- PostgreSQL: 16
### 2.2 后端环境配置
```bash
# 克隆代码
git clone http://192.168.3.36:3000/plm-team/plm-backend-service.git
# 创建虚拟环境
cd plm-backend-service
python3 -m venv venv
source venv/bin/activate
# 安装依赖
pip install -r requirements.txt
# 配置环境变量
cp .env.example .env
# 编辑 .env 文件
# 启动服务
python3 -m app.main
```
### 2.3 前端环境配置
```bash
# 克隆代码
git clone http://192.168.3.36:3000/plm-team/plm-web-frontend.git
# 安装依赖
cd plm-web-frontend
npm install
# 启动开发服务器
npm run dev
```
### 2.4 Docker 环境配置
```bash
# 启动所有服务
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看日志
docker-compose logs -f
```
---
## 三、项目结构
### 3.1 后端项目结构
```
plm-backend-service/
├── app/
│ ├── main.py # 应用入口
│ ├── core/ # 核心配置
│ │ ├── config.py # 配置管理
│ │ ├── database.py # 数据库连接
│ │ └── security.py # 安全认证
│ ├── models/ # 数据模型
│ ├── schemas/ # 数据验证
│ ├── api/ # API路由
│ └── services/ # 业务逻辑
├── tests/ # 测试用例
├── .env.example # 环境变量模板
├── requirements.txt # Python依赖
├── Dockerfile # Docker构建
└── docker-compose.yml # 容器编排
```
### 3.2 前端项目结构
```
plm-web-frontend/
├── src/
│ ├── main.ts # 应用入口
│ ├── App.vue # 根组件
│ ├── router/ # 路由配置
│ ├── store/ # 状态管理
│ ├── views/ # 页面组件
│ ├── components/ # 公共组件
│ ├── api/ # API调用
│ └── utils/ # 工具函数
├── public/ # 静态资源
├── package.json # 依赖配置
└── vite.config.ts # Vite配置
```
---
## 四、编码规范
### 4.1 Python 编码规范
```python
# 文件命名snake_case
# 类名PascalCase
# 函数/变量snake_case
# 常量UPPER_SNAKE_CASE
# 示例
class UserService:
def get_user_by_id(self, user_id: int) -> User:
pass
MAX_RETRY_COUNT = 3
```
### 4.2 TypeScript 编码规范
```typescript
// 文件命名kebab-case
// 类名/接口PascalCase
// 函数/变量camelCase
// 常量UPPER_SNAKE_CASE
// 示例
interface UserInfo {
id: number;
name: string;
}
export function getUserById(userId: number): Promise<UserInfo> {
// ...
}
export const MAX_PAGE_SIZE = 20;
```
---
## 五、Git 工作流
### 5.1 分支策略
```
main # 生产分支,稳定版本
develop # 开发分支,集成测试
feature/* # 功能分支,开发新功能
bugfix/* # 修复分支修复Bug
release/* # 发布分支,版本发布
```
### 5.2 提交规范
```
<type>(<scope>): <subject>
type:
- feat: 新功能
- fix: 修复Bug
- docs: 文档更新
- style: 代码格式
- refactor: 重构
- test: 测试
- chore: 构建/工具
示例:
feat(auth): add JWT authentication
fix(api): resolve pagination issue
docs(readme): update installation guide
```
---
## 六、代码审查规范
### 6.1 审查清单
- [ ] 代码是否符合编码规范
- [ ] 是否有足够的注释
- [ ] 是否有单元测试
- [ ] 是否有安全风险
- [ ] 性能是否可接受
- [ ] 是否有重复代码
### 6.2 审查流程
1. 开发者提交 Pull Request
2. 自动运行 CI 测试
3. 至少1人审核通过
4. 合并到目标分支
---
## 七、测试规范
### 7.1 单元测试
```python
# tests/test_user.py
import pytest
from app.services.user_service import UserService
def test_create_user():
service = UserService()
user = service.create_user(
username="test",
email="test@example.com"
)
assert user.username == "test"
```
### 7.2 测试覆盖率
- 目标覆盖率80%+
- 核心模块覆盖率90%+
---
## 八、部署规范
### 8.1 环境变量
```bash
# 数据库
DATABASE_URL=postgresql://user:pass@localhost:5432/plm
# Redis
REDIS_URL=redis://localhost:6379/0
# JWT
JWT_SECRET_KEY=your-secret-key
JWT_ALGORITHM=HS256
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30
# AI服务
AI_API_KEY=your-api-key
AI_MODEL=gpt-4
```
### 8.2 Docker 部署
```bash
# 构建镜像
docker build -t plm-backend:latest .
# 运行容器
docker run -d \
--name plm-backend \
-p 8000:8000 \
--env-file .env \
plm-backend:latest
```
---
## 九、常用命令
### 9.1 后端命令
```bash
# 启动开发服务器
uvicorn app.main:app --reload
# 运行测试
pytest
# 生成API文档
# 自动生成,访问 /docs
# 数据库迁移
alembic revision --autogenerate -m "message"
alembic upgrade head
```
### 9.2 前端命令
```bash
# 启动开发服务器
npm run dev
# 构建生产版本
npm run build
# 运行测试
npm run test
# 代码格式化
npm run lint
```
---
## 十、联系方式
| 角色 | 姓名 | 职责 |
|------|------|------|
| CTO | 进化官 | 技术决策 |
| 研发总监 | tech-lead | 代码审核 |
| 文档总监 | 笔杆子 | 文档维护 |
---
_创建时间2026-03-31 18:06_
_维护人笔杆子 (creator)_