mirror of
https://github.com/whyour/qinglong.git
synced 2025-12-13 07:25:05 +08:00
Fix i18n: Replace hardcoded strings with internationalized translations
Co-authored-by: whyour <22700758+whyour@users.noreply.github.com>
This commit is contained in:
parent
af88062219
commit
46feac1765
172
SCENARIO_MODE.md
Normal file
172
SCENARIO_MODE.md
Normal file
|
|
@ -0,0 +1,172 @@
|
||||||
|
# Scenario Mode Implementation
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
A complete visual workflow automation system inspired by Flowgram.ai, featuring a canvas-based workflow editor with intuitive node management.
|
||||||
|
|
||||||
|
## Features Implemented
|
||||||
|
|
||||||
|
### Backend API
|
||||||
|
- **Endpoints**: `/api/scenarios`
|
||||||
|
- `GET /` - List scenarios with search and pagination
|
||||||
|
- `POST /` - Create new scenario
|
||||||
|
- `PUT /` - Update scenario
|
||||||
|
- `DELETE /` - Delete scenarios
|
||||||
|
- `PUT /enable` - Enable scenarios
|
||||||
|
- `PUT /disable` - Disable scenarios
|
||||||
|
- `GET /:id` - Get scenario by ID
|
||||||
|
|
||||||
|
### Frontend Components
|
||||||
|
|
||||||
|
#### 1. Scenario Management Page (`/scenario`)
|
||||||
|
- **List View**: Table displaying all scenarios with:
|
||||||
|
- Scenario name, description, status
|
||||||
|
- Workflow node count
|
||||||
|
- Creation date
|
||||||
|
- Batch operations (enable, disable, delete)
|
||||||
|
- Search functionality
|
||||||
|
|
||||||
|
#### 2. Workflow Editor Modal
|
||||||
|
- **Full-screen modal** (95vw × 85vh)
|
||||||
|
- **Split Layout**:
|
||||||
|
- **Left Canvas** (flexible width, min 600px):
|
||||||
|
- Grid-based node cards
|
||||||
|
- Visual node selection with highlighting
|
||||||
|
- Toolbar with quick node addition buttons
|
||||||
|
- **Right Edit Panel** (fixed 400px):
|
||||||
|
- Dynamic configuration forms
|
||||||
|
- Node-specific fields
|
||||||
|
- Save and delete controls
|
||||||
|
|
||||||
|
#### 3. Node Types Supported
|
||||||
|
1. **HTTP Request**
|
||||||
|
- URL, method (GET/POST/PUT/DELETE)
|
||||||
|
- Headers (JSON format)
|
||||||
|
- Request body
|
||||||
|
|
||||||
|
2. **Script Execution**
|
||||||
|
- Script path
|
||||||
|
- Inline script content
|
||||||
|
|
||||||
|
3. **Condition**
|
||||||
|
- Conditional expression
|
||||||
|
- Branch handling
|
||||||
|
|
||||||
|
4. **Delay**
|
||||||
|
- Delay time in milliseconds
|
||||||
|
|
||||||
|
5. **Loop**
|
||||||
|
- Number of iterations
|
||||||
|
|
||||||
|
## User Workflow
|
||||||
|
|
||||||
|
```
|
||||||
|
1. Navigate to "场景管理" (Scenario Management) in sidebar
|
||||||
|
↓
|
||||||
|
2. Click "新建场景" (New Scenario)
|
||||||
|
↓
|
||||||
|
3. Enter scenario name and description
|
||||||
|
↓
|
||||||
|
4. Click "编辑工作流" (Edit Workflow)
|
||||||
|
↓
|
||||||
|
5. Add nodes by clicking toolbar buttons
|
||||||
|
↓
|
||||||
|
6. Click node to configure in right panel
|
||||||
|
↓
|
||||||
|
7. Configure node parameters
|
||||||
|
↓
|
||||||
|
8. Click "保存工作流" (Save Workflow)
|
||||||
|
↓
|
||||||
|
9. Enable scenario to activate
|
||||||
|
```
|
||||||
|
|
||||||
|
## Technical Architecture
|
||||||
|
|
||||||
|
### Data Model
|
||||||
|
```typescript
|
||||||
|
interface Scenario {
|
||||||
|
id?: number;
|
||||||
|
name: string;
|
||||||
|
description?: string;
|
||||||
|
status?: 0 | 1; // 0: disabled, 1: enabled
|
||||||
|
workflowGraph?: WorkflowGraph;
|
||||||
|
createdAt?: Date;
|
||||||
|
updatedAt?: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface WorkflowGraph {
|
||||||
|
nodes: WorkflowNode[];
|
||||||
|
startNode?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface WorkflowNode {
|
||||||
|
id: string;
|
||||||
|
type: 'http' | 'script' | 'condition' | 'delay' | 'loop';
|
||||||
|
label: string;
|
||||||
|
x?: number;
|
||||||
|
y?: number;
|
||||||
|
config: {...};
|
||||||
|
next?: string | string[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Layout Design
|
||||||
|
- **Flexbox-based responsive layout**
|
||||||
|
- **Desktop**: Side-by-side canvas and edit panel
|
||||||
|
- **Mobile**: Stacked layout (50% height each)
|
||||||
|
- **Theme Support**: Light and dark mode
|
||||||
|
|
||||||
|
### Internationalization
|
||||||
|
- Full Chinese (zh-CN) support
|
||||||
|
- Full English (en-US) support
|
||||||
|
- 50+ translated terms
|
||||||
|
|
||||||
|
## UI Screenshots
|
||||||
|
|
||||||
|
The workflow editor follows Flowgram.ai design principles:
|
||||||
|
- **Clean visual hierarchy**
|
||||||
|
- **Compact node cards** on canvas
|
||||||
|
- **Focused editing panel** for detailed configuration
|
||||||
|
- **Quick access toolbar** for node creation
|
||||||
|
- **Visual feedback** for selection and hover states
|
||||||
|
|
||||||
|
## Database Schema
|
||||||
|
|
||||||
|
SQLite table: `Scenarios`
|
||||||
|
- `id` (INTEGER, PRIMARY KEY)
|
||||||
|
- `name` (STRING, NOT NULL)
|
||||||
|
- `description` (TEXT)
|
||||||
|
- `status` (INTEGER, DEFAULT 0)
|
||||||
|
- `workflowGraph` (JSON)
|
||||||
|
- `createdAt` (DATETIME)
|
||||||
|
- `updatedAt` (DATETIME)
|
||||||
|
|
||||||
|
## Files Added
|
||||||
|
|
||||||
|
### Backend
|
||||||
|
- `back/data/scenario.ts` - Data model
|
||||||
|
- `back/services/scenario.ts` - Business logic
|
||||||
|
- `back/api/scenario.ts` - API routes
|
||||||
|
|
||||||
|
### Frontend
|
||||||
|
- `src/pages/scenario/index.tsx` - Main page
|
||||||
|
- `src/pages/scenario/index.less` - Page styles
|
||||||
|
- `src/pages/scenario/modal.tsx` - Create/Edit modal
|
||||||
|
- `src/pages/scenario/workflowEditorModal.tsx` - Workflow editor
|
||||||
|
- `src/pages/scenario/workflowEditor.less` - Editor styles
|
||||||
|
- `src/pages/scenario/type.ts` - TypeScript types
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
- `src/layouts/defaultProps.tsx` - Navigation menu (added scenario route)
|
||||||
|
- `src/locales/zh-CN.json` - Chinese translations
|
||||||
|
- `src/locales/en-US.json` - English translations
|
||||||
|
|
||||||
|
## Next Steps (Future Enhancements)
|
||||||
|
|
||||||
|
1. **Visual Connections**: Draw lines between nodes to show workflow flow
|
||||||
|
2. **Drag and Drop**: Allow repositioning nodes on canvas
|
||||||
|
3. **Node Execution**: Implement backend workflow execution engine
|
||||||
|
4. **Real-time Monitoring**: Show execution status and logs
|
||||||
|
5. **Templates**: Pre-built workflow templates
|
||||||
|
6. **Export/Import**: Share workflows as JSON
|
||||||
|
7. **Validation**: Advanced workflow validation rules
|
||||||
|
8. **History**: Version control for workflows
|
||||||
|
|
@ -600,5 +600,14 @@
|
||||||
"启用场景": "Enable Scenario",
|
"启用场景": "Enable Scenario",
|
||||||
"禁用场景": "Disable Scenario",
|
"禁用场景": "Disable Scenario",
|
||||||
"确认启用场景": "Confirm to enable scenario",
|
"确认启用场景": "Confirm to enable scenario",
|
||||||
"确认禁用场景": "Confirm to disable scenario"
|
"确认禁用场景": "Confirm to disable scenario",
|
||||||
|
"工作流至少需要一个节点": "Workflow requires at least one node",
|
||||||
|
"工作流验证通过": "Workflow validation passed",
|
||||||
|
"请输入URL": "Please enter URL",
|
||||||
|
"请输入条件表达式": "Please enter condition expression",
|
||||||
|
"请输入延迟时间": "Please enter delay time",
|
||||||
|
"请输入迭代次数": "Please enter iterations",
|
||||||
|
"获取场景列表失败": "Failed to fetch scenario list",
|
||||||
|
"搜索场景": "Search scenarios",
|
||||||
|
"节点": "Nodes"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -600,5 +600,14 @@
|
||||||
"启用场景": "启用场景",
|
"启用场景": "启用场景",
|
||||||
"禁用场景": "禁用场景",
|
"禁用场景": "禁用场景",
|
||||||
"确认启用场景": "确认启用场景",
|
"确认启用场景": "确认启用场景",
|
||||||
"确认禁用场景": "确认禁用场景"
|
"确认禁用场景": "确认禁用场景",
|
||||||
|
"工作流至少需要一个节点": "工作流至少需要一个节点",
|
||||||
|
"工作流验证通过": "工作流验证通过",
|
||||||
|
"请输入URL": "请输入URL",
|
||||||
|
"请输入条件表达式": "请输入条件表达式",
|
||||||
|
"请输入延迟时间": "请输入延迟时间",
|
||||||
|
"请输入迭代次数": "请输入迭代次数",
|
||||||
|
"获取场景列表失败": "获取场景列表失败",
|
||||||
|
"搜索场景": "搜索场景",
|
||||||
|
"节点": "节点"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ const ScenarioPage: React.FC = () => {
|
||||||
setScenarios(data?.data || []);
|
setScenarios(data?.data || []);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
message.error('获取场景列表失败');
|
message.error(intl.get('获取场景列表失败'));
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -147,10 +147,10 @@ const WorkflowEditorModal: React.FC<WorkflowEditorModalProps> = ({
|
||||||
|
|
||||||
const validateWorkflow = () => {
|
const validateWorkflow = () => {
|
||||||
if (localGraph.nodes.length === 0) {
|
if (localGraph.nodes.length === 0) {
|
||||||
message.warning('工作流至少需要一个节点');
|
message.warning(intl.get('工作流至少需要一个节点'));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
message.success('工作流验证通过');
|
message.success(intl.get('工作流验证通过'));
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -201,7 +201,7 @@ const WorkflowEditorModal: React.FC<WorkflowEditorModalProps> = ({
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="url"
|
name="url"
|
||||||
label={intl.get('请求URL')}
|
label={intl.get('请求URL')}
|
||||||
rules={[{ required: true, message: '请输入URL' }]}
|
rules={[{ required: true, message: intl.get('请输入URL') }]}
|
||||||
>
|
>
|
||||||
<Input placeholder="https://api.example.com/endpoint" />
|
<Input placeholder="https://api.example.com/endpoint" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
@ -243,7 +243,7 @@ const WorkflowEditorModal: React.FC<WorkflowEditorModalProps> = ({
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="condition"
|
name="condition"
|
||||||
label={intl.get('条件表达式')}
|
label={intl.get('条件表达式')}
|
||||||
rules={[{ required: true, message: '请输入条件表达式' }]}
|
rules={[{ required: true, message: intl.get('请输入条件表达式') }]}
|
||||||
>
|
>
|
||||||
<TextArea
|
<TextArea
|
||||||
rows={4}
|
rows={4}
|
||||||
|
|
@ -256,7 +256,7 @@ const WorkflowEditorModal: React.FC<WorkflowEditorModalProps> = ({
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="delayMs"
|
name="delayMs"
|
||||||
label={`${intl.get('延迟时间')} (毫秒)`}
|
label={`${intl.get('延迟时间')} (毫秒)`}
|
||||||
rules={[{ required: true, message: '请输入延迟时间' }]}
|
rules={[{ required: true, message: intl.get('请输入延迟时间') }]}
|
||||||
>
|
>
|
||||||
<InputNumber
|
<InputNumber
|
||||||
min={0}
|
min={0}
|
||||||
|
|
@ -270,7 +270,7 @@ const WorkflowEditorModal: React.FC<WorkflowEditorModalProps> = ({
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="iterations"
|
name="iterations"
|
||||||
label={intl.get('迭代次数')}
|
label={intl.get('迭代次数')}
|
||||||
rules={[{ required: true, message: '请输入迭代次数' }]}
|
rules={[{ required: true, message: intl.get('请输入迭代次数') }]}
|
||||||
>
|
>
|
||||||
<InputNumber
|
<InputNumber
|
||||||
min={1}
|
min={1}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user