Skip to content

Commit 5b92276

Browse files
xlorneclaude
andcommitted
feat: add title expression interactive UI design
Add design specification and Pencil mockups for title expression UI: - TitleGroovyRequest Java object structure - Variable syntax (${request.xxx} for UI, request.getXxx() for Groovy) - Dual mode: visual configuration vs advanced Groovy script - // @title comment for identifying title configurations - Variable picker modal with request properties Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent a16aa94 commit 5b92276

2 files changed

Lines changed: 1661 additions & 0 deletions

File tree

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
# 标题表达式交互式UI设计
2+
3+
## 1. 需求概述
4+
5+
将节点标题表达式的配置从"直接编写Groovy脚本"改为"交互式可视化配置",同时保留高级用户直接编写脚本的能力。
6+
7+
### 核心功能
8+
- 文字内容用户直接输入
9+
- 变量(request属性)通过选择方式插入
10+
- 复杂场景可开启"高级配置"直接编辑Groovy脚本
11+
- 支持重置配置回到初始状态
12+
13+
### 设计原则
14+
- **所有标题本质都是Groovy脚本**,只是提供不同的配置方式
15+
- **普通模式**:通过UI交互选择变量插入
16+
- **高级模式**:直接编写Groovy代码
17+
- 高级模式下无法解析回可视化,预览区域显示提示
18+
- 通过固定注释区分标题配置
19+
20+
---
21+
22+
## 2. request对象设计
23+
24+
### 2.1 Java对象结构
25+
26+
统一提供 `TitleGroovyRequest` 对象给所有Groovy脚本使用:
27+
28+
```java
29+
public class TitleGroovyRequest {
30+
// 操作人信息
31+
private String operatorName; // 当前操作人姓名
32+
private Integer operatorId; // 当前操作人ID
33+
private Boolean isFlowManager; // 是否流程管理员
34+
35+
// 流程信息
36+
private String workflowTitle; // 流程标题
37+
private String workflowCode; // 流程编码
38+
39+
// 节点信息
40+
private String nodeName; // 当前节点名称
41+
private String nodeType; // 当前节点类型
42+
43+
// 创建人信息
44+
private String creatorName; // 流程创建人姓名
45+
46+
// 表单数据
47+
private Map<String, Object> formData; // 表单字段值
48+
49+
// 流程编号
50+
private String workCode; // 流程编号
51+
52+
// Getters
53+
public String getOperatorName();
54+
public Integer getOperatorId();
55+
public Boolean getIsFlowManager();
56+
public String getWorkflowTitle();
57+
public String getWorkflowCode();
58+
public String getNodeName();
59+
public String getNodeType();
60+
public String getCreatorName();
61+
public Object getFormData(String key);
62+
public String getWorkCode();
63+
}
64+
```
65+
66+
### 2.2 可用变量列表
67+
68+
| 变量路径 | 说明 | 示例 |
69+
|---------|------|------|
70+
| `request.operatorName` | 当前操作人姓名 | "张三" |
71+
| `request.operatorId` | 当前操作人ID | 1001 |
72+
| `request.isFlowManager` | 是否流程管理员 | true/false |
73+
| `request.workflowTitle` | 流程标题 | "请假审批" |
74+
| `request.workflowCode` | 流程编码 | "LEAVE_001" |
75+
| `request.nodeName` | 当前节点名称 | "部门审批" |
76+
| `request.nodeType` | 当前节点类型 | "approval" |
77+
| `request.creatorName` | 流程创建人 | "李四" |
78+
| `request.formData("字段名")` | 表单字段值 | 任意 |
79+
| `request.workCode` | 流程编号 | "WORK_20260226" |
80+
81+
---
82+
83+
## 3. 语法规范
84+
85+
### 3.1 用户界面显示语法(预览/输入)
86+
87+
使用 `${}` 包裹变量:
88+
89+
```
90+
${request.operatorName}
91+
${request.formData("amount")}
92+
${request.workflowTitle}
93+
```
94+
95+
**完整示例:**
96+
```
97+
你好,${request.operatorName},有一笔 ${request.formData("amount")} 元的审批
98+
```
99+
100+
### 3.2 实际Groovy脚本语法
101+
102+
```groovy
103+
return "你好," + request.getOperatorName() + ",有一笔 " + request.getFormData("amount") + " 元的审批"
104+
```
105+
106+
### 3.3 语法转换规则
107+
108+
| 界面语法 | Groovy语法 |
109+
|---------|-----------|
110+
| `${request.operatorName}` | `request.getOperatorName()` |
111+
| `${request.formData("key")}` | `request.getFormData("key")` |
112+
| `${request.workflowTitle}` | `request.getWorkflowTitle()` |
113+
114+
### 3.4 通过注释区分标题配置
115+
116+
在Groovy脚本中添加固定注释来标识这是标题配置:
117+
118+
```groovy
119+
// @TITLE
120+
return "审批:" + request.getOperatorName()
121+
```
122+
123+
系统通过检测 `// @TITLE` 注释来识别标题表达式配置。
124+
125+
---
126+
127+
## 4. 界面设计
128+
129+
### 4.1 界面清单
130+
131+
| 界面 | 用途 | 位置 |
132+
|------|------|------|
133+
| 节点属性面板 | 展示标题内容 + 编辑按钮 | 节点属性面板中 |
134+
| 标题配置面板 | 点击编辑后的配置界面 | 弹框 |
135+
| 变量选择器 | 插入request变量 | 弹框 |
136+
| 高级配置 | Groovy代码编辑 | 弹框 |
137+
138+
### 4.2 节点属性面板
139+
140+
```
141+
┌─────────────────────────────────────┐
142+
│ 节点标题 │
143+
├─────────────────────────────────────┤
144+
│ 当前:部门经理审批 [编辑] │
145+
└─────────────────────────────────────┘
146+
```
147+
148+
- 展示当前配置的标题内容
149+
- 点击"编辑"按钮进入标题配置面板
150+
151+
### 4.3 标题配置面板
152+
153+
#### 普通模式
154+
```
155+
┌─────────────────────────────────────────────────────────┐
156+
│ 标题配置 │
157+
├─────────────────────────────────────────────────────────┤
158+
│ 预览 │
159+
│ 你好,${request.operatorName},有一笔${request.formData("amount")}元的审批
160+
│ ───────────────────────────────────────────────────── │
161+
│ [插入变量] [高级配置] │
162+
│ ───────────────────────────────────────────────────── │
163+
│ 内容 │
164+
│ ┌─────────────────────────────────────────────────────┐│
165+
│ │ 你好,${request.operatorName},有一笔${request.formData("amount")}元的审批
166+
│ └─────────────────────────────────────────────────────┘│
167+
│ 使用 ${request.xxx} 插入变量,点击上方按钮插入 │
168+
│ ───────────────────────────────────────────────────── │
169+
│ [取消] [确定] │
170+
└─────────────────────────────────────────────────────────┘
171+
```
172+
173+
#### 高级模式
174+
```
175+
┌─────────────────────────────────────────────────────────┐
176+
│ 标题配置 │
177+
├─────────────────────────────────────────────────────────┤
178+
│ 预览 │
179+
│ ⚠ 用户自定义配置,无法预览 │
180+
│ ───────────────────────────────────────────────────── │
181+
│ [重置] [高级配置] │
182+
│ ───────────────────────────────────────────────────── │
183+
│ 内容 │
184+
│ ┌─────────────────────────────────────────────────────┐│
185+
│ │ // @TITLE ││
186+
│ │ return "审批:" + request.getOperatorName() ││
187+
│ └─────────────────────────────────────────────────────┘│
188+
│ ───────────────────────────────────────────────────── │
189+
│ [取消] [确定] │
190+
└─────────────────────────────────────────────────────────┘
191+
```
192+
193+
**关键设计说明:**
194+
- 高级模式下预览区域显示"⚠ 用户自定义配置,无法预览"提示
195+
- 高级模式下"高级配置"按钮变为"重置"按钮
196+
- 点击"重置"可清除高级配置,回到普通模式
197+
198+
### 4.4 变量选择器(弹框)
199+
200+
```
201+
┌─────────────────────────────┐
202+
│ 选择变量 │
203+
├─────────────────────────────┤
204+
│ ┌─────────────────────────┐│
205+
│ │ 🔍 搜索变量... ││
206+
│ └─────────────────────────┘│
207+
│ ▶ 操作人相关 │
208+
│ ● request.operatorName - 当前操作人姓名
209+
│ ● request.operatorId - 当前操作人ID
210+
│ ● request.creatorName - 流程创建人
211+
212+
│ ▶ 流程相关 │
213+
│ ● request.workflowTitle - 流程标题
214+
│ ● request.workflowCode - 流程编码
215+
│ ● request.nodeName - 当前节点名称
216+
│ ● request.nodeType - 当前节点类型
217+
218+
│ ▶ 表单函数 │
219+
│ ● request.formData("key") - 获取表单字段值
220+
221+
│ ▶ 流程编号 │
222+
│ ● request.workCode - 流程编号
223+
└─────────────────────────────┘
224+
```
225+
226+
---
227+
228+
## 5. 实现方案
229+
230+
### 5.1 涉及文件
231+
232+
**后端(Java):**
233+
- 创建 `TitleRequest` 对象封装所需数据
234+
235+
**前端(frontend):**
236+
- `packages/flow-pc/flow-pc-design/src/components/design-editor/node-components/strategy/node-title.tsx` - 修改现有组件
237+
- 新增 `VariablePicker.tsx` - 变量选择器
238+
239+
### 5.2 核心逻辑
240+
241+
1. **界面显示**:使用 `${request.xxx}` 语法显示和输入
242+
2. **保存转换**:将 `${request.xxx}` 转换为 `request.getXxx()``request.getFormData("xxx")`
243+
3. **加载识别**:通过 `// @TITLE` 注释识别标题配置
244+
4. **预览**:直接替换 `${request.xxx}` 为实际值(在有数据时)
245+
246+
---
247+
248+
## 6. 设计文件位置
249+
250+
`designs/title-expression-ui/`

0 commit comments

Comments
 (0)