Files
smart-project-pricing/规划文档/02_系统架构设计.md
2026-01-31 21:33:06 +08:00

749 lines
34 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 智能项目定价模型 - 系统架构设计
> **版本**v1.0
> **创建日期**2026-01-19
> **最后更新**2026-01-19
> **负责人**:待定
---
## 1. 架构概述
### 1.1 设计原则
| 原则 | 说明 |
|------|------|
| **前后端分离** | 前端 Vue 3 + 后端 FastAPI独立部署 |
| **容器化部署** | 所有服务运行在 Docker 容器中 |
| **统一 AI 服务** | 通过 `shared_backend.AIService` 调用 AI 能力 |
| **配置集中管理** | API Key 等配置从门户系统统一获取 |
### 1.2 技术选型
遵循《瑞小美系统技术栈标准与字符标准》:
**后端技术栈**
| 技术 | 版本/说明 |
|------|-----------|
| Python | 3.11 |
| FastAPI | 异步 Web 框架 |
| SQLAlchemy | ORM |
| MySQL | 8.0 |
| Pydantic | 数据验证 |
**前端技术栈**
| 技术 | 说明 |
|------|------|
| Vue 3 | 前端框架 |
| TypeScript | 类型安全 |
| Vite | 构建工具 |
| pnpm | 包管理器 |
| Element Plus | UI 组件库 |
| Tailwind CSS | 样式方案 |
| Axios | HTTP 客户端 |
| Pinia | 状态管理 |
| ESLint | 代码规范(**必须配置** |
| ECharts | 图表可视化 |
**基础设施**
| 技术 | 说明 |
|------|------|
| Docker | 容器运行时 |
| Docker Compose | 服务编排 |
| Nginx | 反向代理 |
---
## 2. 系统架构图
### 2.1 整体架构
```
┌─────────────────────────────────┐
│ 用户浏览器 │
└────────────────┬────────────────┘
│ HTTPS
┌──────────────────────────────────────────────────────────────────────────────┐
│ Nginx 反向代理容器 │
│ - SSL 终止 │
│ - 路由分发pricing.xxx.com → 对应服务 │
│ - 静态资源缓存 │
└────────────────┬──────────────────────────────────────┬──────────────────────┘
│ │
│ / │ /api/*
▼ ▼
┌────────────────────────────────┐ ┌────────────────────────────────────────┐
│ 前端容器 (Vue 3) │ │ 后端容器 (FastAPI) │
│ │ │ │
│ - 定价系统 SPA 应用 │ │ - RESTful API │
│ - 端口80 │ │ - 业务逻辑处理 │
│ │ │ - 端口8000 │
└────────────────────────────────┘ └──────────────────┬─────────────────────┘
┌───────────────────────────────────────┼───────────────────┐
│ │ │
▼ ▼ ▼
┌────────────────────────────┐ ┌──────────────────────────────┐ ┌─────────────┐
│ MySQL 数据库容器 │ │ 门户系统 (SCRM) │ │ AI 服务商 │
│ │ │ │ │ │
│ - 业务数据存储 │ │ GET /api/ai/internal/config │ │ 4sapi.com │
│ - AI 调用日志 │ │ - API Key 配置 │ │ OpenRouter │
│ - 端口3306 │ │ - AI 配置管理 │ │ │
└────────────────────────────┘ └──────────────────────────────┘ └─────────────┘
```
### 2.2 后端架构(分层设计)
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ API Layer (FastAPI Routers) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ /cost/* │ │ /market/* │ │ /pricing/* │ │ /profit/* │ │
│ │ 成本核算 │ │ 市场行情 │ │ 智能定价 │ │ 利润模拟 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
└────────────────────────────────────────┬────────────────────────────────────┘
┌────────────────────────────────────────▼────────────────────────────────────┐
│ Service Layer (业务逻辑) │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ CostService │ │ MarketService │ │ PricingService │ │
│ │ 成本计算服务 │ │ 市场分析服务 │ │ 定价建议服务 │ │
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
│ ┌─────────────────┐ ┌─────────────────────────────────────┐ │
│ │ ProfitService │ │ shared_backend.AIService │ │
│ │ 利润模拟服务 │ │ AI 服务(统一调用) │ │
│ └─────────────────┘ └─────────────────────────────────────┘ │
└────────────────────────────────────────┬────────────────────────────────────┘
┌────────────────────────────────────────▼────────────────────────────────────┐
│ Repository Layer (数据访问) │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ CostRepository │ │MarketRepository │ │PricingRepository│ │
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
└────────────────────────────────────────┬────────────────────────────────────┘
┌────────────────────────────────────────▼────────────────────────────────────┐
│ Model Layer (SQLAlchemy Models) │
│ Project | Material | Equipment | FixedCost | Competitor | PricingPlan ... │
└────────────────────────────────────────┬────────────────────────────────────┘
┌─────────────────────┐
│ MySQL Database │
└─────────────────────┘
```
### 2.3 前端架构
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ Vue 3 Application │
├─────────────────────────────────────────────────────────────────────────────┤
│ Views (页面组件) │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │ Dashboard │ │ Cost │ │ Market │ │ Pricing │ │ Profit │ │
│ │ 仪表盘 │ │ 成本核算 │ │ 市场行情 │ │ 智能定价 │ │ 利润模拟 │ │
│ └───────────┘ └───────────┘ └───────────┘ └───────────┘ └───────────┘ │
├─────────────────────────────────────────────────────────────────────────────┤
│ Components (通用组件) │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │ Charts │ │ Forms │ │ Tables │ │ Dialogs │ ... │
│ └───────────┘ └───────────┘ └───────────┘ └───────────┘ │
├─────────────────────────────────────────────────────────────────────────────┤
│ Composables (组合式函数) │
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │
│ │ useCost() │ │ useMarket() │ │ usePricing() │ │
│ └──────────────────┘ └──────────────────┘ └──────────────────┘ │
├─────────────────────────────────────────────────────────────────────────────┤
│ Stores (Pinia 状态管理) │
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │
│ │ costStore │ │ marketStore │ │ pricingStore │ │
│ └──────────────────┘ └──────────────────┘ └──────────────────┘ │
├─────────────────────────────────────────────────────────────────────────────┤
│ API (Axios 封装) │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ api/cost.ts | api/market.ts | api/pricing.ts | api/profit.ts │ │
│ └──────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
```
---
## 3. 目录结构
### 3.1 项目根目录
```
智能项目定价模型/
├── 规划文档/ # 规划文档目录
│ ├── 01_产品需求文档(PRD).md
│ ├── 02_系统架构设计.md
│ ├── 03_数据库设计.md
│ ├── 04_开发计划与进度.md
│ └── 05_API接口设计.md
├── 后端服务/ # FastAPI 后端
│ ├── app/
│ │ ├── __init__.py
│ │ ├── main.py # 应用入口
│ │ ├── config.py # 配置管理
│ │ ├── database.py # 数据库连接
│ │ │
│ │ ├── models/ # SQLAlchemy 模型
│ │ │ ├── __init__.py
│ │ │ ├── project.py
│ │ │ ├── cost.py
│ │ │ ├── market.py
│ │ │ └── pricing.py
│ │ │
│ │ ├── schemas/ # Pydantic 模型
│ │ │ ├── __init__.py
│ │ │ ├── project.py
│ │ │ ├── cost.py
│ │ │ ├── market.py
│ │ │ └── pricing.py
│ │ │
│ │ ├── routers/ # API 路由
│ │ │ ├── __init__.py
│ │ │ ├── cost.py
│ │ │ ├── market.py
│ │ │ ├── pricing.py
│ │ │ └── profit.py
│ │ │
│ │ ├── services/ # 业务逻辑
│ │ │ ├── __init__.py
│ │ │ ├── cost_service.py
│ │ │ ├── market_service.py
│ │ │ ├── pricing_service.py
│ │ │ └── profit_service.py
│ │ │
│ │ └── repositories/ # 数据访问
│ │ ├── __init__.py
│ │ └── ...
│ │
│ ├── prompts/ # AI 提示词(必须)
│ │ ├── pricing_advice_prompts.py
│ │ ├── market_analysis_prompts.py
│ │ └── profit_forecast_prompts.py
│ │
│ ├── tests/ # 测试
│ │ └── ...
│ │
│ ├── Dockerfile
│ ├── requirements.txt
│ └── .env.example
├── 前端应用/ # Vue 3 前端
│ ├── src/
│ │ ├── main.ts
│ │ ├── App.vue
│ │ │
│ │ ├── views/ # 页面组件
│ │ │ ├── Dashboard.vue
│ │ │ ├── cost/
│ │ │ ├── market/
│ │ │ ├── pricing/
│ │ │ └── profit/
│ │ │
│ │ ├── components/ # 通用组件
│ │ │ └── ...
│ │ │
│ │ ├── composables/ # 组合式函数
│ │ │ └── ...
│ │ │
│ │ ├── stores/ # Pinia 状态管理
│ │ │ └── ...
│ │ │
│ │ ├── api/ # API 封装
│ │ │ └── ...
│ │ │
│ │ ├── router/ # 路由配置
│ │ │ └── index.ts
│ │ │
│ │ ├── styles/ # 样式
│ │ │ └── ...
│ │ │
│ │ └── types/ # TypeScript 类型
│ │ └── ...
│ │
│ ├── public/
│ ├── index.html
│ ├── vite.config.ts
│ ├── tailwind.config.js
│ ├── tsconfig.json
│ ├── eslint.config.js # ESLint 配置(必须)
│ ├── package.json
│ ├── Dockerfile
│ └── .env.example
├── docker-compose.yml # 服务编排
├── nginx.conf # Nginx 配置
├── .env.example # 环境变量模板
└── .gitignore # Git 忽略配置(含 .env
```
---
## 4. 部署架构
### 4.1 Docker Compose 服务定义
```yaml
version: '3.8'
services:
# 前端服务
pricing-frontend:
build: ./前端应用
container_name: pricing-frontend
restart: unless-stopped
networks:
- pricing_network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80"]
interval: 30s
timeout: 10s
retries: 3
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
deploy:
resources:
limits:
memory: 256M
# 后端服务
pricing-backend:
build: ./后端服务
container_name: pricing-backend
restart: unless-stopped
env_file:
- .env
environment:
- DATABASE_URL=${DATABASE_URL}
- PORTAL_CONFIG_API=${PORTAL_CONFIG_API}
depends_on:
pricing-mysql:
condition: service_healthy
networks:
- pricing_network
- scrm_network # 连接门户系统网络
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
deploy:
resources:
limits:
memory: 512M
# 数据库服务
pricing-mysql:
image: mysql:8.0.36
container_name: pricing-mysql
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: pricing_model
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- pricing_mysql_data:/var/lib/mysql
networks:
- pricing_network
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 30s
timeout: 10s
retries: 3
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
networks:
pricing_network:
driver: bridge
scrm_network:
external: true # 连接已存在的 SCRM 网络
volumes:
pricing_mysql_data:
```
### 4.2 Nginx 配置示例
```nginx
# pricing.xxx.com
server {
listen 443 ssl http2;
server_name pricing.xxx.com;
ssl_certificate /etc/nginx/ssl/xxx.com.pem;
ssl_certificate_key /etc/nginx/ssl/xxx.com.key;
# 前端静态资源
location / {
proxy_pass http://pricing-frontend:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 后端 API
location /api/ {
proxy_pass http://pricing-backend:8000/api/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket 支持(如需流式输出)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 300s;
}
}
# HTTP 重定向
server {
listen 80;
server_name pricing.xxx.com;
return 301 https://$server_name$request_uri;
}
```
### 4.3 环境变量配置
```bash
# .env.example
# 数据库配置
DATABASE_URL=mysql+pymysql://pricing_user:password@pricing-mysql:3306/pricing_model?charset=utf8mb4
MYSQL_ROOT_PASSWORD=root_password
MYSQL_USER=pricing_user
MYSQL_PASSWORD=password
# 门户系统配置
PORTAL_CONFIG_API=http://portal-backend:8000/api/ai/internal/config
# 应用配置
APP_ENV=production
DEBUG=false
SECRET_KEY=your-secret-key
```
**⚠️ 敏感信息管理规范**
- `.env` 文件权限必须设置为 600`chmod 600 .env`
- `.env` 文件禁止提交到 Git已在 `.gitignore` 中排除)
- 生产环境建议使用 Docker Secrets 管理敏感数据
### 4.4 镜像源配置(强制)
遵循《瑞小美系统技术栈标准》Dockerfile 中必须配置国内镜像源:
**后端 Dockerfile 示例**
```dockerfile
FROM python:3.11.9-slim
# 配置阿里云 APT 源
RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list.d/debian.sources
# 配置阿里云 pip 源
RUN pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/
# ... 其余配置
```
**前端 Dockerfile 示例**
```dockerfile
FROM node:20.11-alpine
# 配置阿里云 npm 源
RUN npm config set registry https://registry.npmmirror.com
# 使用 pnpm
RUN npm install -g pnpm
RUN pnpm config set registry https://registry.npmmirror.com
# ... 其余配置
```
**Docker 镜像源**(在 `/etc/docker/daemon.json` 配置):
```json
{
"registry-mirrors": [
"https://kjphlxn2.mirror.aliyuncs.com",
"https://docker.m.daocloud.io"
]
}
```
> ⚠️ **禁用 latest 标签**:必须使用具体版本号,如 `python:3.11.9-slim`、`node:20.11-alpine`、`mysql:8.0.36`
### 4.5 网络配置补充说明
**DNS 刷新(重要)**
后端容器重启后Nginx 可能缓存旧的 DNS 解析,需执行以下命令刷新:
```bash
docker exec nginx_proxy nginx -s reload
```
建议在部署脚本中自动执行此操作。
### 4.6 前端 ESLint 配置(必须)
遵循《瑞小美系统技术栈标准》,前端**必须配置 ESLint**
**eslint.config.js 示例**
```javascript
import js from '@eslint/js'
import vue from 'eslint-plugin-vue'
import typescript from '@typescript-eslint/eslint-plugin'
import typescriptParser from '@typescript-eslint/parser'
import vueParser from 'vue-eslint-parser'
export default [
js.configs.recommended,
...vue.configs['flat/recommended'],
{
files: ['**/*.{ts,tsx,vue}'],
languageOptions: {
parser: vueParser,
parserOptions: {
parser: typescriptParser,
ecmaVersion: 'latest',
sourceType: 'module',
},
},
plugins: {
'@typescript-eslint': typescript,
},
rules: {
'vue/multi-word-component-names': 'off',
'@typescript-eslint/no-unused-vars': 'warn',
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
},
},
]
```
**package.json scripts**
```json
{
"scripts": {
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx",
"lint:fix": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx --fix"
}
}
```
> ⚠️ 提交代码前必须执行 `pnpm lint` 检查
---
## 5. AI 服务集成架构
### 5.1 集成方式
遵循《瑞小美 AI 接入规范》,通过 `shared_backend.AIService` 统一调用:
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ 定价系统后端 │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ PricingService │ │
│ │ │ │
│ │ # 调用 AI 生成定价建议 │ │
│ │ ai = AIService(module_code="pricing_model", db_session=db) │ │
│ │ response = await ai.chat(messages, prompt_name="pricing_advice") │ │
│ │ │ │
│ └──────────────────────────────────┬───────────────────────────────────┘ │
└─────────────────────────────────────┼───────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ shared_backend.AIService │
│ │
│ 1. 从门户系统获取 API Key 配置 │
│ 2. 降级策略4sapi.com → OpenRouter.ai │
│ 3. 模型名称自动转换 │
│ 4. 调用日志记录到 ai_call_logs 表 │
│ │
└──────────────────────────────────────┬──────────────────────────────────────┘
┌────────────────────────┴────────────────────────┐
│ │
▼ ▼
┌─────────────────────────────────┐ ┌─────────────────────────────────┐
│ 4sapi.com首选 │ │ OpenRouter.ai备选
│ https://4sapi.com/v1/chat/... │ │ https://openrouter.ai/api/... │
└─────────────────────────────────┘ └─────────────────────────────────┘
```
### 5.2 提示词文件规范
**文件位置**`后端服务/prompts/`
**示例pricing_advice_prompts.py**
```python
"""定价建议生成提示词"""
PROMPT_META = {
"name": "pricing_advice",
"display_name": "智能定价建议",
"description": "综合成本、市场、目标利润率,生成项目定价建议",
"module": "pricing_model",
"variables": ["project_name", "cost_data", "market_data", "target_margin"],
}
SYSTEM_PROMPT = """你是一位专业的医美行业定价分析师。你需要根据提供的成本数据、市场行情数据,
结合目标利润率,给出专业的定价建议。
分析时请考虑:
1. 成本结构的合理性
2. 市场竞争态势
3. 目标客群定位
4. 不同定价策略的适用场景
输出格式要求:
- 定价建议区间
- 推荐价格及理由
- 不同策略下的建议价格(引流款/利润款/高端款)
- 风险提示"""
USER_PROMPT = """请为以下项目生成定价建议:
## 项目信息
项目名称:{project_name}
## 成本数据
{cost_data}
## 市场行情
{market_data}
## 目标利润率
{target_margin}%
请给出详细的定价分析和建议。"""
```
---
## 6. 安全架构
### 6.1 网络安全
```
┌──────────────────────────────────────┐
│ 公网 │
└───────────────────┬──────────────────┘
│ 443 (HTTPS)
┌───────────────────────────────────────────────────────────────────────────────┐
│ Nginx 容器 │
│ - SSL 终止 │
│ - 仅暴露 80/443 端口 │
│ - 请求过滤 │
└───────────────────────────────────────────┬───────────────────────────────────┘
│ Docker 内网
┌───────────────────────────────────────────────────────────────────────────────┐
│ Docker Bridge Network (pricing_network) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Frontend │ │ Backend │ │ MySQL │ │
│ │ 内网端口 │ │ 内网端口 │ │ 内网端口 │ │
│ │ 不暴露公网 │ │ 不暴露公网 │ │ 不暴露公网 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└───────────────────────────────────────────────────────────────────────────────┘
```
### 6.2 认证授权
- 使用 OAuth 认证,与瑞小美 SCRM 系统统一
- JWT Token 进行 API 认证
- 基于角色的访问控制RBAC
### 6.3 敏感数据保护
| 数据类型 | 保护措施 |
|----------|----------|
| API Key | 从门户系统获取,禁止硬编码 |
| 数据库密码 | 环境变量,.env 文件权限 600 |
| 业务数据 | MySQL 加密传输,敏感字段脱敏 |
---
## 7. 监控与日志
### 7.1 健康检查
所有服务配置健康检查端点:
| 服务 | 端点 | 检查内容 |
|------|------|----------|
| 后端 | `/health` | 应用运行状态、数据库连接 |
| 前端 | `/` | Nginx 响应状态 |
| 数据库 | `mysqladmin ping` | MySQL 服务状态 |
### 7.2 日志管理
- **格式**JSON 格式,便于收集分析
- **轮转**max-size 10MB保留 3 个文件
- **AI 调用日志**:记录到 `ai_call_logs`
### 7.3 监控指标
| 指标类型 | 监控内容 |
|----------|----------|
| 应用指标 | 请求量、响应时间、错误率 |
| AI 调用 | Token 消耗、成本、延迟、降级频率 |
| 资源指标 | CPU、内存、磁盘使用率 |
---
## 8. 扩展性设计
### 8.1 水平扩展
- 后端服务可多实例部署,通过 Nginx 负载均衡
- 前端静态资源可部署 CDN
### 8.2 功能扩展
- 模块化设计,新功能以独立模块形式添加
- AI 能力扩展通过新增提示词文件实现
---
## 9. 附录
### 9.1 参考文档
- 《瑞小美 AI 接入规范》
- 《瑞小美系统技术栈标准与字符标准》
- [FastAPI 官方文档](https://fastapi.tiangolo.com/)
- [Vue 3 官方文档](https://vuejs.org/)
---
*瑞小美技术团队 · 2026-01-19*