mirror of
https://github.com/whyour/qinglong.git
synced 2025-12-13 07:25:05 +08:00
Add comprehensive architecture documentation
Co-authored-by: whyour <22700758+whyour@users.noreply.github.com>
This commit is contained in:
parent
e6b36b0a1b
commit
f026242ff2
324
ARCHITECTURE.md
Normal file
324
ARCHITECTURE.md
Normal file
|
|
@ -0,0 +1,324 @@
|
||||||
|
# Scenario Mode - Architecture Diagram
|
||||||
|
|
||||||
|
## System Overview
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ Qinglong Application │
|
||||||
|
├─────────────────────────────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ ┌─────────────────────┐ ┌─────────────────────┐ │
|
||||||
|
│ │ Navigation Menu │ │ API Layer │ │
|
||||||
|
│ │ ┌──────────────┐ │ │ /api/scenarios/ │ │
|
||||||
|
│ │ │ 定时任务 │ │ │ - GET (list) │ │
|
||||||
|
│ │ │ 订阅管理 │ │ │ - POST (create) │ │
|
||||||
|
│ │ │ 场景管理 ⭐ │◄──┼─────────┤ - PUT (update) │ │
|
||||||
|
│ │ │ 环境变量 │ │ │ - DELETE (delete) │ │
|
||||||
|
│ │ │ ... │ │ │ - PUT /enable │ │
|
||||||
|
│ │ └──────────────┘ │ │ - PUT /disable │ │
|
||||||
|
│ └─────────────────────┘ │ - GET /:id │ │
|
||||||
|
│ └─────────────────────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ ▼ │
|
||||||
|
│ ┌──────────────────────────────────────────────────────┐ │
|
||||||
|
│ │ Scenario Management Page │ │
|
||||||
|
│ │ /scenario │ │
|
||||||
|
│ │ ┌────────────────────────────────────────────────┐ │ │
|
||||||
|
│ │ │ Toolbar: │ │ │
|
||||||
|
│ │ │ [新建场景] [启用] [禁用] [删除] [搜索] │ │ │
|
||||||
|
│ │ └────────────────────────────────────────────────┘ │ │
|
||||||
|
│ │ ┌────────────────────────────────────────────────┐ │ │
|
||||||
|
│ │ │ Table: │ │ │
|
||||||
|
│ │ │ ┌─────┬────────┬──────┬──────┬────────────┐ │ │ │
|
||||||
|
│ │ │ │名称 │描述 │状态 │节点数│操作 │ │ │ │
|
||||||
|
│ │ │ ├─────┼────────┼──────┼──────┼────────────┤ │ │ │
|
||||||
|
│ │ │ │场景1│... │启用 │5节点 │[编辑工作流]│ │ │ │
|
||||||
|
│ │ │ │场景2│... │禁用 │3节点 │[编辑工作流]│ │ │ │
|
||||||
|
│ │ │ └─────┴────────┴──────┴──────┴────────────┘ │ │ │
|
||||||
|
│ │ └────────────────────────────────────────────────┘ │ │
|
||||||
|
│ └──────────────────────────────────────────────────────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ │ Click "编辑工作流" │
|
||||||
|
│ ▼ │
|
||||||
|
│ ┌──────────────────────────────────────────────────────────────┐ │
|
||||||
|
│ │ Workflow Editor Modal (Full Screen) │ │
|
||||||
|
│ │ ┌────────────────────────────────────────────────────────┐ │ │
|
||||||
|
│ │ │ Canvas Area (Left) │ Edit Panel (Right 400px) │ │ │
|
||||||
|
│ │ ├─────────────────────────────┼──────────────────────────┤ │ │
|
||||||
|
│ │ │ Toolbar: │ Node Configuration │ │ │
|
||||||
|
│ │ │ [+HTTP] [+Script] │ ┌────────────────────┐ │ │ │
|
||||||
|
│ │ │ [+Condition] [+Delay] │ │ Label: [______] │ │ │ │
|
||||||
|
│ │ │ [+Loop] [Validate] │ │ Type: [HTTP▼] │ │ │ │
|
||||||
|
│ │ │ │ │ │ │ │ │
|
||||||
|
│ │ │ Nodes Grid: │ │ URL: [______] │ │ │ │
|
||||||
|
│ │ │ ┌──────┐ ┌──────┐ ┌──────┐ │ │ Method:[GET ▼] │ │ │ │
|
||||||
|
│ │ │ │Node 1│ │Node 2│ │Node 3│ │ │ Headers:[____] │ │ │ │
|
||||||
|
│ │ │ │HTTP │ │Script│ │Cond. │ │ │ Body: [____] │ │ │ │
|
||||||
|
│ │ │ └──────┘ └──────┘ └──────┘ │ │ │ │ │ │
|
||||||
|
│ │ │ ┌──────┐ ┌──────┐ │ │ [Save] [Delete] │ │ │ │
|
||||||
|
│ │ │ │Node 4│ │Node 5│ │ └────────────────────┘ │ │ │
|
||||||
|
│ │ │ │Delay │ │Loop │ │ │ │ │
|
||||||
|
│ │ │ └──────┘ └──────┘ │ │ │ │
|
||||||
|
│ │ └─────────────────────────────┴──────────────────────────┘ │ │
|
||||||
|
│ │ [Cancel] [Save Workflow] │ │
|
||||||
|
│ └──────────────────────────────────────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
└─────────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## Data Flow
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────┐
|
||||||
|
│ Browser │
|
||||||
|
└──────┬──────┘
|
||||||
|
│
|
||||||
|
│ 1. Navigate to /scenario
|
||||||
|
▼
|
||||||
|
┌─────────────────┐
|
||||||
|
│ Scenario Page │
|
||||||
|
│ (React) │
|
||||||
|
└──────┬──────────┘
|
||||||
|
│
|
||||||
|
│ 2. GET /api/scenarios
|
||||||
|
▼
|
||||||
|
┌─────────────────┐
|
||||||
|
│ Scenario API │
|
||||||
|
│ (Express) │
|
||||||
|
└──────┬──────────┘
|
||||||
|
│
|
||||||
|
│ 3. Query database
|
||||||
|
▼
|
||||||
|
┌─────────────────┐
|
||||||
|
│ Scenario Model │
|
||||||
|
│ (Sequelize) │
|
||||||
|
└──────┬──────────┘
|
||||||
|
│
|
||||||
|
│ 4. Read from SQLite
|
||||||
|
▼
|
||||||
|
┌─────────────────┐
|
||||||
|
│ Database.db │
|
||||||
|
│ Scenarios │
|
||||||
|
│ Table │
|
||||||
|
└─────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## Workflow Editor Data Flow
|
||||||
|
|
||||||
|
```
|
||||||
|
User Action Flow:
|
||||||
|
┌──────────────────────────────────────────────────────────────┐
|
||||||
|
│ │
|
||||||
|
│ Click "编辑工作流" │
|
||||||
|
│ │ │
|
||||||
|
│ ▼ │
|
||||||
|
│ Open WorkflowEditorModal │
|
||||||
|
│ │ │
|
||||||
|
│ ├──► Load existing workflowGraph │
|
||||||
|
│ │ (if scenario has one) │
|
||||||
|
│ │ │
|
||||||
|
│ ▼ │
|
||||||
|
│ Display Canvas & Edit Panel │
|
||||||
|
│ │ │
|
||||||
|
│ ├──► Click [+HTTP] button │
|
||||||
|
│ │ └──► Create new HTTP node │
|
||||||
|
│ │ └──► Add to localGraph.nodes │
|
||||||
|
│ │ │
|
||||||
|
│ ├──► Click node card │
|
||||||
|
│ │ └──► Set selectedNodeId │
|
||||||
|
│ │ └──► Populate form in Edit Panel │
|
||||||
|
│ │ │
|
||||||
|
│ ├──► Edit form fields │
|
||||||
|
│ │ └──► Update node.config │
|
||||||
|
│ │ └──► Save to localGraph │
|
||||||
|
│ │ │
|
||||||
|
│ ├──► Click [Delete] button │
|
||||||
|
│ │ └──► Remove node from localGraph.nodes │
|
||||||
|
│ │ │
|
||||||
|
│ ▼ │
|
||||||
|
│ Click "保存工作流" │
|
||||||
|
│ │ │
|
||||||
|
│ ├──► Validate workflow │
|
||||||
|
│ │ └──► Check nodes.length > 0 │
|
||||||
|
│ │ │
|
||||||
|
│ ▼ │
|
||||||
|
│ Call onOk(localGraph) │
|
||||||
|
│ │ │
|
||||||
|
│ ▼ │
|
||||||
|
│ PUT /api/scenarios │
|
||||||
|
│ │ │
|
||||||
|
│ └──► Update scenario.workflowGraph │
|
||||||
|
│ └──► Save to database │
|
||||||
|
│ └──► Success message │
|
||||||
|
│ └──► Close modal │
|
||||||
|
│ └──► Refresh list │
|
||||||
|
│ │
|
||||||
|
└──────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## Node Type Configurations
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ Node Types │
|
||||||
|
├─────────────────────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ 1. HTTP Request Node │
|
||||||
|
│ ┌──────────────────────────────────────────┐ │
|
||||||
|
│ │ type: 'http' │ │
|
||||||
|
│ │ config: │ │
|
||||||
|
│ │ - url: string │ │
|
||||||
|
│ │ - method: GET|POST|PUT|DELETE │ │
|
||||||
|
│ │ - headers: Record<string, string> │ │
|
||||||
|
│ │ - body: string │ │
|
||||||
|
│ └──────────────────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ 2. Script Execution Node │
|
||||||
|
│ ┌──────────────────────────────────────────┐ │
|
||||||
|
│ │ type: 'script' │ │
|
||||||
|
│ │ config: │ │
|
||||||
|
│ │ - scriptPath: string │ │
|
||||||
|
│ │ - scriptContent: string │ │
|
||||||
|
│ └──────────────────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ 3. Condition Node │
|
||||||
|
│ ┌──────────────────────────────────────────┐ │
|
||||||
|
│ │ type: 'condition' │ │
|
||||||
|
│ │ config: │ │
|
||||||
|
│ │ - condition: string │ │
|
||||||
|
│ │ - trueNext: string │ │
|
||||||
|
│ │ - falseNext: string │ │
|
||||||
|
│ └──────────────────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ 4. Delay Node │
|
||||||
|
│ ┌──────────────────────────────────────────┐ │
|
||||||
|
│ │ type: 'delay' │ │
|
||||||
|
│ │ config: │ │
|
||||||
|
│ │ - delayMs: number │ │
|
||||||
|
│ └──────────────────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ 5. Loop Node │
|
||||||
|
│ ┌──────────────────────────────────────────┐ │
|
||||||
|
│ │ type: 'loop' │ │
|
||||||
|
│ │ config: │ │
|
||||||
|
│ │ - iterations: number │ │
|
||||||
|
│ │ - loopBody: string[] │ │
|
||||||
|
│ └──────────────────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## Database Schema
|
||||||
|
|
||||||
|
```
|
||||||
|
Table: Scenarios
|
||||||
|
┌──────────────┬──────────────┬──────────────┬───────────────┐
|
||||||
|
│ Column │ Type │ Nullable │ Default │
|
||||||
|
├──────────────┼──────────────┼──────────────┼───────────────┤
|
||||||
|
│ id │ INTEGER │ NO │ AUTO_INCREMENT│
|
||||||
|
│ name │ STRING │ NO │ - │
|
||||||
|
│ description │ TEXT │ YES │ NULL │
|
||||||
|
│ status │ INTEGER │ YES │ 0 │
|
||||||
|
│ workflowGraph│ JSON │ YES │ NULL │
|
||||||
|
│ createdAt │ DATETIME │ NO │ NOW() │
|
||||||
|
│ updatedAt │ DATETIME │ NO │ NOW() │
|
||||||
|
└──────────────┴──────────────┴──────────────┴───────────────┘
|
||||||
|
|
||||||
|
workflowGraph JSON structure:
|
||||||
|
{
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"id": "node_1234567890",
|
||||||
|
"type": "http",
|
||||||
|
"label": "HTTP请求 1",
|
||||||
|
"x": 100,
|
||||||
|
"y": 100,
|
||||||
|
"config": {
|
||||||
|
"url": "https://api.example.com",
|
||||||
|
"method": "GET",
|
||||||
|
"headers": {},
|
||||||
|
"body": ""
|
||||||
|
},
|
||||||
|
"next": "node_1234567891"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"startNode": "node_1234567890"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Component Hierarchy
|
||||||
|
|
||||||
|
```
|
||||||
|
App
|
||||||
|
└── Layout
|
||||||
|
└── Scenario Page (/scenario)
|
||||||
|
├── Toolbar
|
||||||
|
│ ├── Button (新建场景)
|
||||||
|
│ ├── Button (启用)
|
||||||
|
│ ├── Button (禁用)
|
||||||
|
│ ├── Button (删除)
|
||||||
|
│ └── Search (搜索场景)
|
||||||
|
├── Table
|
||||||
|
│ └── Columns
|
||||||
|
│ ├── 场景名称
|
||||||
|
│ ├── 场景描述
|
||||||
|
│ ├── 状态
|
||||||
|
│ ├── 工作流
|
||||||
|
│ ├── 创建时间
|
||||||
|
│ └── 操作
|
||||||
|
│ └── Button (编辑工作流)
|
||||||
|
├── ScenarioModal
|
||||||
|
│ └── Form
|
||||||
|
│ ├── Input (名称)
|
||||||
|
│ └── TextArea (描述)
|
||||||
|
└── WorkflowEditorModal
|
||||||
|
├── Canvas (Left)
|
||||||
|
│ ├── Toolbar
|
||||||
|
│ │ ├── Button (+ HTTP)
|
||||||
|
│ │ ├── Button (+ Script)
|
||||||
|
│ │ ├── Button (+ Condition)
|
||||||
|
│ │ ├── Button (+ Delay)
|
||||||
|
│ │ ├── Button (+ Loop)
|
||||||
|
│ │ └── Button (Validate)
|
||||||
|
│ └── Nodes Grid
|
||||||
|
│ └── NodeCard (×N)
|
||||||
|
│ ├── Type Badge
|
||||||
|
│ └── Label
|
||||||
|
└── Edit Panel (Right)
|
||||||
|
└── Form (Dynamic)
|
||||||
|
├── Input (Label)
|
||||||
|
├── Select (Type)
|
||||||
|
├── [Node-specific fields]
|
||||||
|
└── Buttons
|
||||||
|
├── Save
|
||||||
|
└── Delete
|
||||||
|
```
|
||||||
|
|
||||||
|
## File Organization
|
||||||
|
|
||||||
|
```
|
||||||
|
qinglong/
|
||||||
|
├── back/
|
||||||
|
│ ├── api/
|
||||||
|
│ │ ├── index.ts (modified: +scenario route)
|
||||||
|
│ │ └── scenario.ts (new: API endpoints)
|
||||||
|
│ ├── data/
|
||||||
|
│ │ └── scenario.ts (new: Model definition)
|
||||||
|
│ └── services/
|
||||||
|
│ └── scenario.ts (new: Business logic)
|
||||||
|
├── src/
|
||||||
|
│ ├── layouts/
|
||||||
|
│ │ └── defaultProps.tsx (modified: +scenario nav)
|
||||||
|
│ ├── locales/
|
||||||
|
│ │ ├── zh-CN.json (modified: +53 keys)
|
||||||
|
│ │ └── en-US.json (modified: +53 keys)
|
||||||
|
│ └── pages/
|
||||||
|
│ └── scenario/
|
||||||
|
│ ├── index.tsx (new: Main page)
|
||||||
|
│ ├── index.less (new: Page styles)
|
||||||
|
│ ├── modal.tsx (new: Create/Edit modal)
|
||||||
|
│ ├── workflowEditorModal.tsx (new: Editor)
|
||||||
|
│ ├── workflowEditor.less (new: Editor styles)
|
||||||
|
│ └── type.ts (new: TypeScript types)
|
||||||
|
└── SCENARIO_MODE.md (new: Documentation)
|
||||||
|
```
|
||||||
Loading…
Reference in New Issue
Block a user