状态标签(StateLabel)定义编写指南¶
目标:Agent 直接生成/修改 workspace 状态标签,并正确接到流程节点、按钮可见性、表单脚本。知识以本文为准。不写原理;不依赖外链。
术语:实体类 cn.myapps.core.common.model.statelabel.StateLabel;产品「状态标签 / 常用工具-状态标签」;设计器路由 statuslabellist / statuslabel。是软件级 流程状态名字典,供按钮 stateToShow 勾选与流程节点 statelabel 对齐;不是 Document 运行时字段本体,**不是**流程节点配置文件,**不是**角色/权限。
依赖:挂在**软件(Application)下;parentId=applicationid=软件 id。运行匹配靠**字符串相等(文档当前状态串 ⊇ / 相交 配置串),不是靠 StateLabel 的 id。
产出物一览¶
| 部分 | 落盘 | 形态 |
|---|---|---|
| 状态标签 | 见下路径 | JAXB 根 stateLabel;id 为根属性 |
# 现行样例/存量软件(几乎全部):目录组 + 目录型落盘
storage/workspace/{软件名}.application/statelabels/{标签名}.statelabel/{标签名}.statelabel
# ModelSuffix 常量定义的落盘组(新建 API theoretically 走这条,扁平单文件):
storage/workspace/{软件名}.application/statelabel/{标签名}.statelabel
路径相对 storage/workspace。
常量(ModelSuffix) |
值 |
|---|---|
STATELABEL_PATH_SUFFIX / STATELABEL_FILE_SUFFIX |
statelabel |
STATELABEL_FILE_GROUP |
/statelabel |
现实:当前工作区里所有应用目录组名均为 statelabels(复数);无单独 statelabel/。DAO 保存有路径兼容:已存在旧组名/目录型时**保持原 uri**,不全量迁到 /statelabel。设计态索引(url.index)按 id→相对路径;加载靠后缀 .statelabel + 缓存。
新建最低配置:
- 目标软件若已有
statelabels/→ 写入该组;目录{name}.statelabel/+ 同名文件 - 全新软件:优先仍用
statelabels/目录型(与存量一致);或扁平statelabel/{name}.statelabel(对齐常量) - 写 XML:
id、name、value、parentId=软件 id、applicationid=软件 id、orderNo、description - 推荐
name≡value(同中文态名),并与流程节点statelabel、按钮stateToShow使用同一字符串 - 同软件
name不重名(设计态校验「该名称已存在,请重新命名再保存!」)
约定:
- JAXB;根
stateLabel(camelCase L);id在 根属性 description用 CDATA(基类);可空- 文件名 =
name+.statelabel;目录型则「目录名 = 文件名」 name/value勿含/\:*?"<>|(设计器nameCheck/validateSpecial);name另有落盘替换/%\→=47/=37/=92name长度设计器 UI ≤40parentId= 软件 id;applicationid样例常写;缺则靠路径归属 / API save set- **勿**放到
module/下;永远在应用级statelabel(s)/ orderNo:模型类型为 String;比较按整数(NumberUtils.toInt,空→Integer.MAX_VALUE);UI/JSON 常传数字再转字符串- 无
color字段(designer-api.md若写 color 为过时/错误)
1. 心智模型¶
软件 Application
└─ statelabels/*.statelabel ← 本文:字典条目(name/value/orderNo)
│
│ 设计器勾选 / 人工抄写 **同一字符串**
▼
流程 .flow 节点属性 Node.statelabel ← 设计盘内嵌 XML 字符串(必填)
│
▼ 流转 / 启动
Document.STATELABEL / FlowStateRT / NodeRT.statelabel
│ getStateLabel() 聚合当前实例标签(多节点常逗号或冒号拼接)
▼
按钮 Activity.stateToShow(逗号分隔) ← 设计器 state_select 写入的是字典 **name**
isStateToHidden(doc):当前标签列表含任一 show 值 → 显示,否则隐藏
表单字段 hiddenScript / readonlyScript
CURDOC.getStateLabel() / getStateLabel() equals / indexOf 判断
| 概念 | 说明 |
|---|---|
字典 StateLabel |
应用下可维护名录;**运行引擎不强制**走字典表;无条目也能手写节点/按钮态名 |
name |
显示名;按钮勾选 stateToShow 写入的是 name;应用内唯一 |
value |
「值」;JSR @NotEmpty;常与 name 相同;按钮选择器不写入 value |
节点 statelabel |
流程设计属性;校验「请输入节点名称和状态标签」;写入运行态 NodeRT |
文档 stateLabel |
运行列 STATELABEL;当前流程态展示/脚本读取源 |
stateLabelInfo |
运行列 STATELABELINFO(CLOB/JSON);审批人等扩展信息 UI |
stateToShow |
Activity / ButtonField:空=不限态;非空=逗号列表,与文档态 字符串匹配 才显示 |
三层易混对象:
| 对象 | 位置 | 用途 |
|---|---|---|
.statelabel |
应用 statelabels/ |
字典定义(本文) |
Node.statelabel |
.flow 节点 |
该节点对外状态名 |
Document.stateLabel |
运行库 | 当前单据所处状态名(由节点拷贝/聚合) |
2. StateLabel 属性 → .statelabel XML¶
属性表¶
| 属性 | XML | 类型 | 默认/样例 | 说明 |
|---|---|---|---|---|
id |
根属性 | string | 须生成 | __ + 短 UUID |
name |
子元素 | string | — | 必填;文件名;应用内唯一;stateToShow 勾选键 |
parentId |
子元素 | string | — | = 软件 id |
applicationid |
子元素 | string | = 软件 id | 样例常写;API create/update 会 set |
description |
CDATA | string | 可空 | 列表/概览描述 |
remark |
CDATA | string | 基类备注;少用 | |
value |
子元素 | string | — | 必填(@NotEmpty,i18n page.value.notexist) |
orderNo |
子元素 | string | "0"/"1" |
排序;compareTo 按 int |
基类还有 uri(运行算路径,一般不手写进文件)。
完整 XML 样例(目录型,对齐存量)¶
路径:…/statelabels/人事.statelabel/人事.statelabel
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<stateLabel id="3vx33GoJUElQdo0VuWA">
<name>人事</name>
<parentId>sOZu9kthmxyP8qQfq0e</parentId>
<applicationid>sOZu9kthmxyP8qQfq0e</applicationid>
<description><![CDATA[]]></description>
<value>人事</value>
<orderNo>1</orderNo>
</stateLabel>
扁平单文件样例(对齐 STATELABEL_FILE_GROUP)¶
路径:…/statelabel/草稿.statelabel
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<stateLabel id="NEW_STATELABEL_ID">
<name>草稿</name>
<parentId>APP_ID</parentId>
<applicationid>APP_ID</applicationid>
<description><![CDATA[未启动或首节点]]></description>
<value>草稿</value>
<orderNo>0</orderNo>
</stateLabel>
API JSON(设计器 Commontools)¶
POST/PUT …/api/designtime/applications/{applicationId}/statelabels[/{id}]
{
"id": "可选;空则服务端生成",
"name": "人事",
"value": "人事",
"description": "",
"orderNo": "1",
"parentId": "软件id",
"applicationid": "软件id"
}
Controller 强制:applicationid/parentId=路径上的 applicationId;name 非空;同名校验。返回新建 { id }。
3. 与流程节点联动¶
流程设计(.flow)每个节点有属性 statelabel(开始/完成/人工/自动/网关/子流程等)。默认文案示例:开始=开始,完成=完成,网关=网关(见 workflow nodeTypes.defaultStateLabel)。
节点 XML 片段(HTML 转义嵌在 flow 文本里常见):
规则:
- 节点 name 与 statelabel 均必填(
flowValidation:请输入节点名称和状态标签!) - 流转时
NodeRT/FlowStateRT/Document拷贝该字符串为当前态 - 多活动节点:
FlowStateRT.getStateLabel()常把多个NodeRT.statelabel用 **逗号**拼;Document 聚合主/子流程时可能用 **冒号**拼接路径 - 多分支展示可前缀
(多分支) - 字典条目**不会自动**写入节点;须在流程设计里填**相同字符串**(或 UI 手输)
实践:
若字典 name≠value:按钮勾选写 name;流程节点须写成 与 stateToShow 相同的串(通常是 name),否则按钮永远隐藏。
4. 与按钮 / Activity.stateToShow¶
Activity 字段:<stateToShow>…</stateToShow>(可空)。
stateToShow |
行为(Activity.isStateToHidden) |
|---|---|
| 空 / 仅空白 | 不按状态隐藏(其它 hiddenScript 仍可隐藏) |
A,B,C |
文档当前态列表与 {A,B,C} 有交集 → 显示;否则隐藏 |
匹配细节:
- 有
doc.stateid:用doc.getStateLableList()(注意方法名拼写 Lable)=stateLabel.split(",") - 无
stateid但表单配置了onActionFlow:取该流程 首节点 的statelabel列表再比 - 当前标签列表为空且已配置 show 列表:代码路径返回 不隐藏(
return false)——边界场景勿依赖 - 设计器
state_select.vue:勾选字典后拼接item.name(不是 value、不是 id)
表单内嵌按钮控件 ButtonField.stateToShow 同语义,转成 Activity 时 act.setStateToShow。
空示例:
仅「人事」「财务审批」可见:
视图工具栏 Activity 同样有 stateToShow;逻辑同源。
5. 与文档 / 脚本 / 视图¶
Document 与库列¶
动态单表头常见列(DDL):
| 列 | 含义 |
|---|---|
STATELABEL |
当前状态标签字符串 |
STATELABELINFO |
状态扩展 JSON(审批人信息等) |
IDocument / AbstractDocument:
getStateLabel()/setStateLabelgetStateLableList()(拼写 Lable)getStateLabelInfo()/setStateLabelInfo
getStateLabel():字段已有值直接返回;否则从流程实例聚合未完成主/子流程的 FlowStateRT.stateLabel。
iScript¶
// 隐藏/只读脚本常见写法
var st = CURDOC.getStateLabel();
// 或全局别名 getStateLabel()
if (st && st === "流程登记") {
// ...
}
| API | 说明 |
|---|---|
CURDOC.getStateLabel() |
当前文档状态标签 String |
doc.getStateLabel() |
Document 实例同义 |
getStateLabel() |
旧全局别名 → CURDOC |
多态逗号串时用 indexOf / split,勿只 === 单节点名。
历史/上一节点:常查流程历史表 state_label 字段(脚本合集 get-previous-node-state);那是**运行历史**,不是读 .statelabel 文件。
视图系统字段¶
| 列名 | 说明 |
|---|---|
$StateLabel / $stateLabel |
绑定文档状态;导出/列渲染特殊处理;JSON info 可影响展示 |
| 回退样式 | flowReturnCss 等用 backstatelabel*.gif 图标 |
DQL/SQL 视图脚本里常见 fs.state_label 别名「流程状态」。
6. 生成清单(Agent)¶
- 确认软件 id、目录名;检查是否已有
statelabels/ - 选定态名串
S(中文业务态);name=value=S;orderNo递增字符串 - 生成 id(
__+ 短 UUID);写文件到约定路径;文件名=name - 流程各节点:需要该态时
statelabel=S(勿用字典 id) - 需按态显隐的 Activity:
stateToShow含S(多选用逗号、无空格或与存量一致) - 字段权限脚本:
getStateLabel()与S比较时注意多标签逗号串 - 纯落盘后:设计器刷新/重建索引后列表可见;运行匹配**不依赖**文件是否在字典——但勾选 UI 依赖字典 list API
批量建字典示例(同一软件):
| name=value | orderNo |
|---|---|
| 开始 | 0 |
| 申请 | 1 |
| 部门审批 | 2 |
| 财务审批 | 3 |
| 完成 | 9 |
然后 flow 节点与按钮按表对齐。
7. 与其它技能边界¶
| 内容 | 本文 | 其它 |
|---|---|---|
.statelabel 字段、路径、name/value |
✓ | |
软件下 statelabel(s)/ 分组存在性 |
交汇 | APPLICATION_SKILL |
Activity.stateToShow、表单按钮 |
语义在此;XML 字段在 FORM | FORM_SKILL |
流程节点 statelabel、流转写 Document |
字符串契约在此 | 流程设计 / FLOW(无独立 SKILL 时写在本文) |
视图 $StateLabel 列 |
简述在此 | VIEW_SKILL |
iScript getStateLabel 全量 API |
要点在此 | iscript 文档 |
| 角色权限、菜单 | 否 | ROLE / MENU |
附录 A:匹配算法伪代码¶
# Activity.isStateToHidden(doc) → true 表示隐藏
if blank(stateToShow): return false
labels =
if blank(doc.stateid) && form.onActionFlow:
firstNodes(form.onActionFlow).map(n => n.statelabel)
else:
doc.stateLableList # stateLabel.split(",")
show[] = stateToShow.split(",")
if labels 非空:
if any(s in labels for s in show): return false # 显示
else: return true # 隐藏
else:
return false # 无当前标签时不隐藏
附录 B:URI 计算(代码)¶
StateLabel 不在「目录后缀再拼文件名」白名单(form/view/module/flow…)中:
getPath()=parentPath + "/statelabel/" + name + ".statelabel"getUri()=getPath()→ **扁平单文件**路径
存量文件多为:
parentPath + "/statelabels/" + name + ".statelabel/" + name + ".statelabel"
保存兼容:若磁盘已是「同名目录+同名文件」布局,更新时按 folder 重命名,不强制改成扁平。
附录 C:常见失败¶
| 现象 | 原因 |
|---|---|
| 按钮勾了态仍不显示 | stateToShow 用了 name,节点 statelabel 写成了 value 或别字;或文档当前态是逗号串未包含该项 |
| 勾选器无选项 | 未建 .statelabel 或索引未加载;API list 空 |
| 保存名称已存在 | 同应用另一条目同 name |
| 保存值不存在 | value 空(@NotEmpty) |
| 文件在列表仍没有 | 落在错误应用目录;后缀不是 .statelabel;未进 url.index/缓存 |
| 脚本 equals 永远 false | 多节点态为 "A,B" 或 "A:B";或首尾空格 |
| 改名丢文件 | 文件名/<name>/目录名三者不一致 |
| 按 id 配 stateToShow | 无效;只认状态字符串 |
| API 文档写 color | 模型无此字段;忽略 |
附录 D:类与包¶
| 项 | 值 |
|---|---|
| 模型 | cn.myapps.core.common.model.statelabel.StateLabel |
| DAO | FileSystemStateLabelDAO / StateLabelDAO |
| Service | StateLabelService / StateLabelServiceImpl |
| Controller | cn.myapps.designtime.statelabel.controller.StateLabelController |
| 后缀映射 | ModelSuffixEx:statelabel → StateLabel.class |
| 父服务 | applicationDesignTimeService(parent=Application) |