openxiangda-skill-kit 2.3.57 → 2.3.89
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/skills/openxiangda-v2/references/administration.md +40 -1
- package/skills/openxiangda-v2/references/backend.md +189 -3
- package/skills/openxiangda-v2/references/data-authz.md +72 -2
- package/skills/openxiangda-v2/references/declarations-cheatsheet.md +11 -1
- package/skills/openxiangda-v2/references/development.md +7 -0
- package/skills/openxiangda-v2/references/field-components.md +80 -0
- package/skills/openxiangda-v2/references/frontend.md +8 -0
- package/skills/openxiangda-v2/references/getting-started.md +53 -0
- package/skills/openxiangda-v2/references/managed-concurrency-frontend.md +10 -4
- package/skills/openxiangda-v2/references/testing.md +17 -0
- package/skills/openxiangda-v2/references/workflow-events.md +403 -9
|
@@ -94,6 +94,60 @@ events: {
|
|
|
94
94
|
时长,十年内,如 `-PT1H` 表示提前一小时)到达时触发。适合到期提醒、超期升级等场景;
|
|
95
95
|
同一条记录的字段更新后按新值重算。`code` 唯一,`eventType` 同样引用已声明应用事件。
|
|
96
96
|
|
|
97
|
+
日期事件自动带上 `triggerCode`、`resourceCode`、`recordId`、`recordRevision`、`field`
|
|
98
|
+
和 `dueAt`;`payload` 显式写普通对象(无自定义内容时写 `{}`),不能覆盖这些字段或
|
|
99
|
+
`projection`。需要申请人、提醒正文等记录资料时,复用订阅的 `payload.fields`:平台
|
|
100
|
+
取同一事件修订中、事件类型及资源匹配的字段并集,和日期、记录修订一起读取真实
|
|
101
|
+
Native 值,写入事件 `projection`。每个消费者收到的投影再按自身字段声明裁剪。
|
|
102
|
+
|
|
103
|
+
例如,应用代码为 `reference-app`、资源 `bookings` 包含 `owner`(user.single)、
|
|
104
|
+
`reminderText`(text.long)、`expiresAt`(datetime)时,可以声明:
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
events: {
|
|
108
|
+
schemas: [{
|
|
109
|
+
eventType: 'reference-app.booking.expiry.v1', dataSchemaVersion: '1.0.0',
|
|
110
|
+
jsonSchema: {
|
|
111
|
+
type: 'object', additionalProperties: false,
|
|
112
|
+
required: ['triggerCode', 'resourceCode', 'recordId', 'recordRevision', 'field', 'dueAt', 'projection'],
|
|
113
|
+
properties: {
|
|
114
|
+
triggerCode: { const: 'booking-expiry' }, resourceCode: { const: 'bookings' },
|
|
115
|
+
recordId: { type: 'string', format: 'uuid' }, recordRevision: { type: 'integer', minimum: 1 },
|
|
116
|
+
field: { const: 'expiresAt' }, dueAt: { type: 'string', format: 'date-time' },
|
|
117
|
+
projection: {
|
|
118
|
+
type: 'object', additionalProperties: false, required: ['owner', 'reminderText'],
|
|
119
|
+
properties: {
|
|
120
|
+
owner: { type: 'object', additionalProperties: false, required: ['value', 'label'],
|
|
121
|
+
properties: { value: { type: 'string', format: 'uuid' }, label: { type: 'string' } } },
|
|
122
|
+
reminderText: { type: 'string', minLength: 1, maxLength: 2000 },
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
}],
|
|
128
|
+
dateTriggers: [{ code: 'booking-expiry', resourceCode: 'bookings', field: 'expiresAt',
|
|
129
|
+
offset: '-PT1H', eventType: 'reference-app.booking.expiry.v1', payload: {} }],
|
|
130
|
+
subscriptions: [{ code: 'booking-expiry-notice', eventTypes: ['reference-app.booking.expiry.v1'],
|
|
131
|
+
filter: { resourceCodes: ['bookings'] }, payload: { includeChanges: false, fields: ['owner', 'reminderText'] },
|
|
132
|
+
platformAccess: { notification: { mode: 'business-standard' } },
|
|
133
|
+
}],
|
|
134
|
+
},
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
订阅处理器照常实现。通知的 `sendFromEvent` 使用 `recipientPaths: ['projection.owner.value']`
|
|
138
|
+
等路径,由平台从已认证事件取得收件人;应用不在发送请求中复制人员 ID。
|
|
139
|
+
|
|
140
|
+
投影只接受资源声明的顶层字段,禁止子表、路径/SQL表达式及 `mask: 'omit'` 的敏感字段。
|
|
141
|
+
单订阅最多32字段,同事件投影并集最多64字段,扫描最多100订阅,完整事件不超过
|
|
142
|
+
64 KiB。投影 JSON Schema 必须是关闭额外属性的 object、声明全部已选字段,不能
|
|
143
|
+
要求未投影字段。编译阶段检查固定日期封套和结构,运行时才校验真实资料的类型、
|
|
144
|
+
必填、长度等约束;不生成虚构人员让编译检查通过。资料不满足 schema、来源版本
|
|
145
|
+
漂移或字段不合法时,该调度意图取消并保留错误,不发送不完整提醒。
|
|
146
|
+
|
|
147
|
+
有资料投影的日期声明要求平台能力 `events.date-source-projection:1.0.0`;连接旧平台
|
|
148
|
+
会在能力协商时拒绝。无字段投影的既有日期事件保持原形态及原能力要求。日期事件
|
|
149
|
+
不自动筛选批准状态;要限定业务状态,应显式设计条件,不能从审批名称推断。
|
|
150
|
+
|
|
97
151
|
两类触发器各最多 100 条。事件 Schema 用 `events.schemas` 声明
|
|
98
152
|
(`{ eventType, dataSchemaVersion, jsonSchema, sensitiveFields? }`),`eventType` 遵循
|
|
99
153
|
`xxx.yyy.v1` 版本后缀模式;触发器只发事件,不直接写数据或调用流程。
|
|
@@ -106,6 +160,13 @@ events: {
|
|
|
106
160
|
|
|
107
161
|
标准任务和实例详情的“返回”由应用 Router 使用同一份 route manifest 中对应设备的流程中心路径;没有中心条目时返回已声明门户。普通用户无需管理后台权限。应用独立消费 `WorkflowTaskPage` 或 `WorkflowInstancePage` 时,可以传入本应用已声明的 `returnPath`,例如 `<WorkflowInstancePage variant="mobile" returnPath="/m/work-center" />`。抽屉的 `onDismiss` 仍负责关闭当前抽屉;返回导航不授予目标页面权限。
|
|
108
162
|
|
|
163
|
+
会签第一票或转交成功后,节点可能继续等待其他人,但原用户的办理席位已经结束。
|
|
164
|
+
标准页面确认旧任务不可读时重新核验实例访问,再显示当前进度;不重投原命令。
|
|
165
|
+
嵌入任务面板的 `onCommandCompleted(result, context)` 保留原平台结果,第二参数
|
|
166
|
+
`taskSurfaceUnavailable` 为 SDK 的成功后读取事实,供宿主关闭旧办理面并读取实例。
|
|
167
|
+
通用网络错误或无关权限拒绝仍显示读取失败;已确认成功的读取失败允许返回,
|
|
168
|
+
未知写入继续要求先查询原结果。`advanced` 仍只表示流程推进,不表示个人席位状态。
|
|
169
|
+
|
|
109
170
|
抄送由动态 Surface 提供 `cc` 操作,使用 `user_select` 多选组件收集 1 至 20 位人员。任务 Surface 可以正式包含实例抄送命令;前端按 `operation.execute.href` 和该 Surface 的 token 提交,不另造任务命令或 token。公共事件为 `openxiangda.workflow.instance.cc_added.v2`。
|
|
110
171
|
|
|
111
172
|
## 钉钉卡片已读查询
|
|
@@ -254,14 +315,18 @@ fields: [{ code: 'startsAt', label: '开始时间', type: 'datetime', required:
|
|
|
254
315
|
所声明精确 capability 的用户;capability 必须在同一应用显式声明,不支持
|
|
255
316
|
通配符。该授权同时允许读取对应流程实例的详情及时间线,包括完成后查阅;
|
|
256
317
|
不授予审批、抄送、改派、删除、普通数据读取或管理后台权限。撤销 capability
|
|
257
|
-
|
|
318
|
+
后读取和终止权限都失效。撤回默认要求填写原因;固定定义显式声明
|
|
319
|
+
`instanceCommands: { withdraw: { reasonRequired: false } }` 时允许省略、空串或空白,
|
|
320
|
+
仍拒绝已提供的非字符串及超过4000字符。该选项自动要求
|
|
321
|
+
`workflow.optional-withdrawal-reason@1.0.0`,旧平台不能激活。`beforeFact` 可独立
|
|
322
|
+
声明或与选填组合,空策略无效。终止仍必填原因;超级管理员也遵守已声明时限。
|
|
258
323
|
|
|
259
324
|
不声明 `instanceCommands` 时沿用既有行为;只为终止授权时可以省略其
|
|
260
325
|
`beforeFact`。声明策略的交付包自动要求平台能力
|
|
261
326
|
`workflow.instance-cancellation-policy`,旧平台无法激活该应用版本。
|
|
262
327
|
已经固定该策略的实例存在期间,平台回滚也必须保留策略执行能力。
|
|
263
328
|
发布新 definition 不会改写旧实例固定的 definition 版本,因此不会给旧实例
|
|
264
|
-
|
|
329
|
+
补上截止时间、选填原因或业务管理员终止授权。升级前应盘点存量实例,按各自原定义完成
|
|
265
330
|
或由原有授权主体处置;不要通过重发事件或改写事实迁移策略。已使用新策略的
|
|
266
331
|
实例在截止后及终态仍允许当前被授权的业务管理员查阅,撤销其 capability
|
|
267
332
|
也会撤销这些存量实例的详情读取权限。
|
|
@@ -392,8 +457,10 @@ Workflow instance-scoped preview/content 路由,平台在每次文件读取时
|
|
|
392
457
|
`/m/workflows/:workflowCode/start`。definition 必须显式声明
|
|
393
458
|
`launch: { mode: 'standalone' | 'hidden-handoff' | ... }`,缺失会被编译器拒绝;
|
|
394
459
|
factProjection 把 option/user/department/resource-ref/cascade 字段投影为
|
|
395
|
-
`{ label, value }` 对象,对应 inputSchema
|
|
396
|
-
|
|
460
|
+
`{ label, value }` 对象,对应 inputSchema 属性声明为 `type: 'object'`;
|
|
461
|
+
允许尚未填写的单值引用显式使用 `type: ['object', 'null']`,数组顺序无关。
|
|
462
|
+
Native必填校验仍执行;multiple类字段保持array + object items(cascade.multiple
|
|
463
|
+
为array + array + object)。条件表达式用 `path: '<fact>.value'`
|
|
397
464
|
比较;声明成标量会在运行时 INPUT_SCHEMA_MISMATCH 并无限重试,编译器现已拦截。`standalone`/`hidden-handoff` 缺省使用同一个
|
|
398
465
|
compiler-owned `processOperationCode`、subject declaration 和标准 process commit;平台在一个
|
|
399
466
|
事务中写业务数据和 durable command。action-owned 资源改为声明
|
|
@@ -404,6 +471,51 @@ processCommand 路径和 allowlisted context 预填。标准页调用原 Named A
|
|
|
404
471
|
`ProcessCommandSurface`;`awaiting_input` 只回答已生成 requirement,`started` 再进入 pinned
|
|
405
472
|
instance entry。浏览器不再导出 prepare/start 发起协议。
|
|
406
473
|
|
|
474
|
+
### 标准提交页的业务表单扩展
|
|
475
|
+
|
|
476
|
+
应用读取获授权的业务资料后,可将 canonical 预填值和同步字段规则传给公开
|
|
477
|
+
`WorkflowSubmissionPage` 的 `formOptions`。PC和手机复用同一个组件及Field Kit;
|
|
478
|
+
上传、具名动作、幂等操作和未知结果恢复继续由标准页处理,应用不要复制提交生命周期。
|
|
479
|
+
|
|
480
|
+
```tsx
|
|
481
|
+
import { WorkflowSubmissionPage, type WorkflowSubmissionFormOptions } from 'openxiangda/react';
|
|
482
|
+
|
|
483
|
+
const formOptions: WorkflowSubmissionFormOptions = {
|
|
484
|
+
initialValues: { phone: profile.phone, className: profile.className },
|
|
485
|
+
fieldState: values => {
|
|
486
|
+
const medical = (values.reason as { value?: string } | undefined)?.value === 'illness';
|
|
487
|
+
return {
|
|
488
|
+
recoveryEvidence: { visible: medical, required: medical, hiddenValue: [] },
|
|
489
|
+
medicalReviewer: { visible: medical, required: medical, hiddenValue: null },
|
|
490
|
+
};
|
|
491
|
+
},
|
|
492
|
+
intro: <p>请核对预填资料;因病申请需要康复证明。</p>,
|
|
493
|
+
};
|
|
494
|
+
return <WorkflowSubmissionPage workflowCode="reinstatement" variant="mobile" formOptions={formOptions} />;
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
初值仅在当前匹配的发起合同内应用到未触碰字段,每字段一次;后到资料和父组件重新渲染
|
|
498
|
+
不会覆盖已填写或手动清空的内容。日期和范围使用canonical值,标准页通过原codec转换。
|
|
499
|
+
`fieldState`读取canonical值,`required`只能增加校验,不能撤销原必填或隐藏原必填字段;
|
|
500
|
+
可选字段隐藏时清为`hiddenValue`或undefined,提交也使用同一投影,不发送旧材料/人员。
|
|
501
|
+
初值或规则引用范围外字段会阻断表单。`intro`只提供页面说明,不拥有身份、授权或提交。
|
|
502
|
+
资料加载/失败或业务资格提示可传`preparation`内容,它仅阻断尚未提交的表单;原请求查询
|
|
503
|
+
及已接受命令的展示优先于该提示。应用应始终挂载标准页,避免当前资格变化遮蔽原结果恢复。
|
|
504
|
+
这些规则属于应用代码,不能通过管理员节点配置修改;服务器仍独立校验实际业务资格与字段。
|
|
505
|
+
|
|
506
|
+
`valueLinkage(changed, values)`在用户输入后同步返回canonical字段patch,例如
|
|
507
|
+
`Object.hasOwn(changed, 'owner') ? { specialist: values.owner ?? null } : {}`。
|
|
508
|
+
改负责人复制专员,手改专员保留;再次改负责人重新复制,清空用null。回调只能改当前
|
|
509
|
+
可见、可编辑且匹配launch的字段,不能改系统/只读/隐藏字段或返回Promise。输入是副本,
|
|
510
|
+
写回沿用codec并标记已触碰,迟到预填不会覆盖联动值。预填、草稿、恢复、程序写回不触发
|
|
511
|
+
联动;PC/手机规则一致。异常保留输入并阻断新提交,下一次成功输入可恢复,原提交结果
|
|
512
|
+
查询及已接受命令仍优先。异步资料读取放准备阶段,服务器仍校验资格和业务不变量。
|
|
513
|
+
|
|
514
|
+
具名owned新建表单可传`subtableReadonlyFields: { lines: ['employeeNumber'] }`,
|
|
515
|
+
把当前子行的派生值显示为只读,并从提交输入排除。表名与字段必须属于当前sealed
|
|
516
|
+
owned闭包;配置错误会拒绝新表单。值仍可供应用联动展示,Server应重新计算可信值。
|
|
517
|
+
此选项只收窄页面交互,不授予读写权限,也不改变普通CRUD或审批任务的字段规则。
|
|
518
|
+
|
|
407
519
|
通用应用待办页通过 `frontend.user.applicationTodoCenter: true` 启用,平台同时提供
|
|
408
520
|
`/todos` 和 `/m/todos`。它只投影当前登录用户的 Notification Hub 收件人数据,
|
|
409
521
|
`查看详情` 使用上述统一导航解析;待办页不常驻业务详情,审批命令仍在目标 Workflow
|
|
@@ -521,6 +633,50 @@ outbox容量等事务故障会回滚,处理器按原键核对后重交,不
|
|
|
521
633
|
系统、流水号和隐藏字段不可作为补填入口。根附件、图片复用平台托管文件;
|
|
522
634
|
签名和富文本同样保留 Native 字段协议;普通 owned 子行以固定页面白名单和行 CAS 提交。
|
|
523
635
|
|
|
636
|
+
### 任务内的资源引用选择
|
|
637
|
+
|
|
638
|
+
任务页面中的 `resource-ref.single` / `resource-ref.multiple` 自动使用当前任务的选择接口。
|
|
639
|
+
当前办理人不需要业务资料的普通 `update` 权限,但必须拥有目标字典的 `read` 权限;
|
|
640
|
+
字段来源、读取投影、行权限和有界分页继续由 Native Data 执行。
|
|
641
|
+
仅当前固定 taskPage 中可见且可填写的根字段能够查询,隐藏、只读、条件尚未生效的字段
|
|
642
|
+
和子表字段拒绝查询。字段显隐与填写规则仍归页面声明。
|
|
643
|
+
|
|
644
|
+
自定义任务表单使用公开 `searchResource` 时传入当前 Surface 的 task ID、业务资料修订及
|
|
645
|
+
任务版本;不能把 task 与普通 create、launch 或管理员 record edit 上下文混用:
|
|
646
|
+
|
|
647
|
+
```ts
|
|
648
|
+
await searchResource(resourceCode, fieldCode, {
|
|
649
|
+
operation: 'update', keyword: '司机',
|
|
650
|
+
task: { taskId, expectedRevision: businessDetail.sourceRevision, expectedTaskVersion: task.version },
|
|
651
|
+
});
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
底层请求使用 `workflow-task-field-source-query/v2`,返回已有的
|
|
655
|
+
`data-field-source-page/v2`。依赖字段的过滤仅使用声明的 bindings:当前可填写的依赖
|
|
656
|
+
可取表单值,显式清空会返回空选项;只读或不在当前页面的依赖取已保存资料。
|
|
657
|
+
游标绑定当前任务、版本、页面、定义和资料修订。409 时刷新任务并保留用户输入,
|
|
658
|
+
403 时展示实际拒绝,不扩大普通 CRUD 权限。标准 PC 和移动任务组件自动传递这些上下文。
|
|
659
|
+
|
|
660
|
+
### 前后端共享的表达式计算
|
|
661
|
+
|
|
662
|
+
PC、手机与 Nest 共用的业务模块从纯入口导入,应用仍只声明统一根包精确依赖:
|
|
663
|
+
|
|
664
|
+
```ts
|
|
665
|
+
import { evaluateWorkflowTaskPageExpression, type WorkflowExpression } from 'openxiangda/expressions';
|
|
666
|
+
|
|
667
|
+
const when: WorkflowExpression = {
|
|
668
|
+
op: 'gt',
|
|
669
|
+
left: { op: 'path', path: 'values.amount' },
|
|
670
|
+
right: { op: 'literal', value: 1000 },
|
|
671
|
+
};
|
|
672
|
+
const needsReview = Boolean(evaluateWorkflowTaskPageExpression(when, { amount: 1500 }));
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
路径以 `values.` 开始,第二参数直接传字段值对象。此入口复用原任务页计算器,
|
|
676
|
+
支持浏览器打包器和原生 Node ESM;共享模块不要导入浏览器传输入口
|
|
677
|
+
`openxiangda/core`,也不直接依赖内部物理包。计算结果不授予审批或数据权限,
|
|
678
|
+
真实流转和写入继续由平台固定定义与当前用户授权核验。
|
|
679
|
+
|
|
524
680
|
### 标准流程的主子表发起
|
|
525
681
|
|
|
526
682
|
标准发起页复用 Field Kit 的 PC/手机子表,通过原 `standard-commands` 的
|
|
@@ -532,8 +688,35 @@ outbox容量等事务故障会回滚,处理器按原键核对后重交,不
|
|
|
532
688
|
发起仍执行当前用户的父、子资源及字段授权。拥有主表权限不会自动得到通用子表权限。
|
|
533
689
|
已有记录提交核对父 CAS 和完整已读子行集合,包括未修改行;删除显式保留原 id/revision,
|
|
534
690
|
跨单、遗漏、重复或陈旧行均拒绝。原命令已提交时先返回同一回执,再也不重新展开当前行。
|
|
535
|
-
|
|
536
|
-
|
|
691
|
+
每表最多500/累计500、完整意图双倍、整请求2MiB及展开后1016操作与 Native 预算一致。
|
|
692
|
+
超过原单表100或累计400的声明自动要求 `data.extended-owned-subtable-capacity@1.0.0`;
|
|
693
|
+
较小声明及默认20行不自动扩容,新能力由支持的Server自动开启。
|
|
694
|
+
普通显式 Named Action 的16个业务操作预算不变。
|
|
695
|
+
|
|
696
|
+
具名发起操作需要标准页填写一层子表时,在该操作声明固定的创建闭包:
|
|
697
|
+
|
|
698
|
+
```ts
|
|
699
|
+
platformAccess: {
|
|
700
|
+
workflow: { codes: ['expense-approval'] },
|
|
701
|
+
ownedSubject: {
|
|
702
|
+
mode: 'create', resourceCode: 'expense-requests',
|
|
703
|
+
subtables: [{ fieldCode: 'items', fieldCodes: ['description', 'amount', 'evidence'] }],
|
|
704
|
+
},
|
|
705
|
+
managedFiles: [{ resourceCode: 'expense-items', fieldCodes: ['evidence'], intents: ['create'] }],
|
|
706
|
+
}
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
`items` 必须是主体模型声明的一层 owned 关系。子字段清单不含外键、排序字段、嵌套子表或序号。
|
|
710
|
+
含文件、图片、签名或富文本的字段同时声明该操作的 `managedFiles` 创建权限。平台自动核验
|
|
711
|
+
`workflow.named-owned-create@1.0.0` 能力,无需手动开关。
|
|
712
|
+
|
|
713
|
+
标准 PC/移动页从发起 Surface 读取此闭包,填写新的子行,上传通过原具名操作执行。
|
|
714
|
+
申请人不需要子资源的普通 create/update/delete 权限。应用后端完成业务校验后,
|
|
715
|
+
`BusinessProcess.commit` 只传一个主体 create,其 `data` 包含上述行结构,subject 指向此操作。
|
|
716
|
+
平台在同一 Native 事务内展开子行、维护外键与顺序并接受流程命令;原回执恢复先于子行规划。
|
|
717
|
+
这一契约只支持新建,拒绝 existing/update、混合显式操作以及 decimal reservation;
|
|
718
|
+
原有不声明 `ownedSubject` 的具名操作继续使用显式事务。最多16张子表、合计500行,
|
|
719
|
+
仍执行原事务字节、字段、文件与授权检查。
|
|
537
720
|
|
|
538
721
|
### 任务 owned 子表
|
|
539
722
|
|
|
@@ -549,11 +732,11 @@ outbox容量等事务故障会回滚,处理器按原键核对后重交,不
|
|
|
549
732
|
|
|
550
733
|
关系沿用模型的 `resourceCode/foreignKey/orderField/maxRows`,不接受任务调用者自报。
|
|
551
734
|
子字段可声明同样的只读、可见和条件必填规则;这些属于页面代码,管理员不能覆盖。
|
|
552
|
-
`create/delete/reorder` 省略时关闭。仅一层,每表 maxRows 最多
|
|
553
|
-
声明总量最多
|
|
735
|
+
`create/delete/reorder` 省略时关闭。仅一层,每表 maxRows 最多500,父资源及任务页
|
|
736
|
+
声明总量最多500;默认仍20。完整意图最多为每表 maxRows 的两倍,可在一次提交中
|
|
554
737
|
删除满表旧行并新增同等数量,仍按有效行数校验上限。整个 form/任务私有草稿值限1MiB,
|
|
555
738
|
页面定义仍64KiB/64根字段;系统、隐藏、关系键和顺序字段不进入子字段白名单。
|
|
556
|
-
标准主子表提交复用同一个 Native 原子事务,最多
|
|
739
|
+
标准主子表提交复用同一个 Native 原子事务,最多1016操作/2MiB(500行全量替换加主表为1001操作),
|
|
557
740
|
任一行失败全单回滚,不静默截断或分批提交。普通表单草稿values最多2MiB,含原值与当前值;
|
|
558
741
|
状态字段的独立配额不变。附件上传数量/字节与详情读取预算仍独立执行,行数容量不豁免文件配额。
|
|
559
742
|
子行支持 file/image/signature/text.rich,使用同一个任务上传入口并绑定准确行;普通
|
|
@@ -607,6 +790,16 @@ approve/resubmit 携带 `form: { expectedRevision, values }` 时,Native 业务
|
|
|
607
790
|
多人补填与管理纠错使用 Native 记录 CAS,冲突保留输入。首次请求的明确拒绝会只读刷新,
|
|
608
791
|
修订变化时对照最新已保存值和本人输入,核对前锁住字段与操作;可选择保留输入或采用最新值。
|
|
609
792
|
拒绝后的读取失败明确提示本次未提交,锁住旧操作,恢复读取后再核对;未知结果仍只能恢复原请求。
|
|
793
|
+
操作确认表单使用同一 Surface 的必填、字符数与非空白规则校验意见和原因。
|
|
794
|
+
拒绝意见默认必填。固定节点显式设置 `operationPolicy.reject.commentRequired: false` 时允许省略或空意见,目标须具备 `workflow.optional-rejection-comment@1.0.0`;已进入任务使用冻结规则,后续配置不追溯。选填仍限制为最多4000字符的字符串,不写入假意见。
|
|
795
|
+
`commentRequired` 只配置同意/拒绝的 `comment`。转交、委托、加签、退回使用 `reason`,
|
|
796
|
+
默认必填;固定节点可显式声明如 `operationPolicy.transfer: { reasonRequired: false }`,
|
|
797
|
+
目标须具备 `workflow.optional-operation-reason@1.0.0`,平台自动提供,无需初始化开关。
|
|
798
|
+
选填允许省略、空字符串或空白,仍拒绝非字符串和超过4000字符的值,不生成代替原因。
|
|
799
|
+
开放对应 `administration.operations` 后,管理员可以收紧选填规则,不能放宽代码必填规则;
|
|
800
|
+
已进入的任务保留冻结规则。管理员改派始终必填,不用再填写第二份审批意见。
|
|
801
|
+
明确拒绝后,实例、任务版本及操作签名仍一致且操作仍可用时,对话框保留输入供人工核对;
|
|
802
|
+
任务、权限、字段规则或版本变化时不能沿用旧操作。刷新和保留输入都不会自动重发请求。
|
|
610
803
|
补填刷新固定事实投影;
|
|
611
804
|
修改已计算步骤的输入时清除当前失效输出及依赖输出。仅退回 replay 且所有前向
|
|
612
805
|
审批路径确定重经生产者时允许;resume_current 或后置补填跳过重算会返回
|
|
@@ -702,3 +895,204 @@ PC/手机保留格式、图片和前后文字;插图未知时锁住编辑,
|
|
|
702
895
|
自定义 Field Kit 上传 renderer 的第四参数为可选 `onRecovered(file)`,仅在恢复原任务上传
|
|
703
896
|
时采用完整字段值;正常上传仍返回 `DataFileRef`。非数组字段必须提供该回调;不能用文件数组
|
|
704
897
|
append 处理签名或 HTML。当前任务、实例、记录或字段改变时清理旧图片预览,重新按范围读取。
|
|
898
|
+
|
|
899
|
+
### 发起人同时参与审批
|
|
900
|
+
|
|
901
|
+
审批节点可声明 `initiatorApprovalPolicy: 'auto_approve'`;省略或声明 `manual` 时由本人办理。
|
|
902
|
+
该策略由流程代码固定,管理员可以调整已开放的审批方式与人员,不能修改此策略。
|
|
903
|
+
仅当前已激活、由原人员解析或授权解析重试产生的发起人直接席位自动同意。
|
|
904
|
+
单人/或签按正常同意规则完成;会签仍等待其他席位;依次审批只有轮到本人时才自动处理。
|
|
905
|
+
发起人代理给他人、他人代理给发起人、转交、加签、管理员重分配及退回补正均需人工。
|
|
906
|
+
|
|
907
|
+
带 `taskPageCode`、可写字段或强制同意意见的节点不能使用自动同意。需要补选负责人等
|
|
908
|
+
业务输入的节点继续采用人工办理;配置也不能给自动节点增加强制同意意见。
|
|
909
|
+
实际自动票使用原审批依赖与事务,历史显示“发起人自动同意”,事件包含 `automatic: true`
|
|
910
|
+
及流程内核主体;没有伪造人工意见。后续解析失败会回滚本次自动票、任务与事件。
|
|
911
|
+
每个事务最多进入 200 个节点、处理 200 个自动席位,业务步骤仍等待原业务结果。
|
|
912
|
+
前一办理人来源保留原发起人;重启或原命令重放不重复自动票。
|
|
913
|
+
|
|
914
|
+
此声明要求 `workflow.initiator-approval-policy@1.0.0`,缺少实现的目标平台会拒绝应用。
|
|
915
|
+
|
|
916
|
+
### 审批人为空时的节点策略
|
|
917
|
+
|
|
918
|
+
审批节点可声明 `emptyPolicy: 'skip'`,省略或声明 `block` 时保持阻塞。第一版 skip 支持 fixed_users、input_users、form_field_users、app_role、app_role_in_scope;编译器拒绝其他来源与 skip 组合。表单人员明确为 `[]`,或存在的角色在有效范围内没有成员,且解析成功、没有警告,才允许自动继续到 `onApprove`。缺失/null 字段、不存在的角色、无效账号、缺少范围、解析失败和非零人数不满足 min/max 都不能跳过。
|
|
919
|
+
|
|
920
|
+
该策略由代码固定。每次实际跳过记录节点访问、当时配置、解析依据和 `openxiangda.workflow.node.skipped.v2` 事件;图和 PC/手机历史显示“已跳过”。连续节点推进受 200 节点上限约束,业务步骤仍等待其正式结果。后续失败与业务变更在原事务一起回滚,重试沿用原命令。
|
|
921
|
+
|
|
922
|
+
退回补正(return_review)必须有人实际处理,不能靠空人跳过;重提后的正常 replay/resume 流转继续采用原节点策略。使用此声明时,生成契约要求目标平台支持 `workflow.approval-empty-policy@1.0.0`,缺少该能力的旧服务端不能接收。
|
|
923
|
+
|
|
924
|
+
## 审批通过后整批授权代理 {#approved-delegation}
|
|
925
|
+
|
|
926
|
+
`subject.factProjection`可以引用主体已声明的owned子表。平台在Native创建事务中按真实
|
|
927
|
+
父记录读取明细,输出带持久行`key`的扁平业务对象;外键、排序和系统字段不进入事实。
|
|
928
|
+
日期、数字和人员引用采用Native规范值,按声明排序字段及id稳定排序。所有本次创建行
|
|
929
|
+
必须经原RLS可见;权限不足、修订或集合变化、单表超限均回滚,不接受客户端自报数组。
|
|
930
|
+
空的可选子表保留`[]`,单表最大500行,完整流程事实仍限256KiB;初期不支持嵌套子表。
|
|
931
|
+
声明自动要求`workflow.owned-initial-facts@1.0.0`,平台初始化自动提供,无额外开关。
|
|
932
|
+
这是初始冻结能力;任务修改owned明细后的事实更新应另行确认,不能用初始快照代替。
|
|
933
|
+
|
|
934
|
+
代理申请使用固定定义的 `approvedDelegation`:
|
|
935
|
+
|
|
936
|
+
```ts
|
|
937
|
+
approvedDelegation: {
|
|
938
|
+
confirmationNodeId: 'confirm',
|
|
939
|
+
confirmer: 'delegate', // 或 initiator:由发起人本人确认
|
|
940
|
+
requestsField: 'requests',
|
|
941
|
+
maxRequests: 500,
|
|
942
|
+
},
|
|
943
|
+
```
|
|
944
|
+
|
|
945
|
+
`requests` 必须是 Native 主体投影到实例的闭合、有界明细数组;只读取固定实例
|
|
946
|
+
`fact_snapshot.data`,每行采用 `WorkflowApprovedDelegationRequest`,保存本人和代理人的
|
|
947
|
+
职责键及修订、代理人引用、流程/可选节点范围、起止时间与原因。最多500行、整批256KiB。
|
|
948
|
+
代理人确认的整批必须为同一代理人;同一流程不同节点的明细分别保留。
|
|
949
|
+
|
|
950
|
+
所有批准路径必须经过声明的单人、人工、非空确认节点。自动处理、超时、管理员跳过、
|
|
951
|
+
转交和代理确认不能产生确认证据;明细变化或再次退回后必须在当前周期重新确认。
|
|
952
|
+
最终批准在同一事务核验真实人工任务和双方当前账号、职责、窗口、修订与冲突,
|
|
953
|
+
然后调用已有平台代理所有者整批授权。任一行失败时,批准、全部授权和批次回执一起回滚。
|
|
954
|
+
创建、审核中、拒绝、退回和撤回不授权;原命令恢复不重新创建或激活已撤销的授权。
|
|
955
|
+
|
|
956
|
+
声明自动要求 `workflow.approved-delegation@1.0.0`,无需增加默认关闭的开关。
|
|
957
|
+
不提供 HTTP/system 代建入口,不授予代理人额外资料权限。图通过 `readability.logic`
|
|
958
|
+
说明确认、当前职责核验及授权处理;这些逻辑和连线由代码固定。
|
|
959
|
+
|
|
960
|
+
## 按业务资料权限查看办理历史 {#record-history-read}
|
|
961
|
+
|
|
962
|
+
发起人、审批人、抄送人使用既有 Workflow 详情。业务查看人员需要根据当前资料范围读取办理记录时,模型可显式声明:
|
|
963
|
+
|
|
964
|
+
```ts
|
|
965
|
+
workflowHistory: { read: ['app:my-app:history:read'] },
|
|
966
|
+
```
|
|
967
|
+
|
|
968
|
+
`read: true` 绑定本资源的 read 能力,`false` 关闭入口;省略也关闭。能力数组引用已声明能力,最多20项,必须由同一角色成员全部持有,同时具备资源read。ALL资料读取角色与本人历史角色组合时,历史仍限本人行;Perspective和Native RLS继续收窄范围。此声明不授予审批、转交、后台或流程图管理能力,且独立于 `audit.read` 的资料变更记录。
|
|
969
|
+
|
|
970
|
+
标准Native详情按声明提供折叠的“流程办理记录”。自定义用户端PC/手机页面可复用 `WorkflowRecordHistoryPanel`(`openxiangda/react`),传入 `resourceCode`、`recordId` 和 `variant`。通过 `loadWorkflowRecordHistory`(`openxiangda/core` 或 `openxiangda/react`)直接读取时,可传 `instanceId` 查看该记录的原固定实例,以及 `limit`(默认20、最多100)、`offset`(最多500)。环境来自当前平台runtime;接口不提供办理Surface或操作令牌。
|
|
971
|
+
|
|
972
|
+
结果仅包含原流程版本、实际节点访问、人员、操作时间和意见,不返回条件事实、业务字段、代码、角色席位、原始log detail或授权摘要。每次请求重新授权;无权、没有可读实例、容量超限及读取中资料/实例变化分别保留明确失败。组件清除失败后的旧数据并提供手动重试,不自动重放写入。单实例最多500操作、200访问、1000审批/自动抄送席位,响应最多2MiB;历史较大时返回413,不静默截断。
|
|
973
|
+
|
|
974
|
+
本能力要求平台 `workflow.record-history-read@1.0.0`。只读历史不提供评论发布、源系统打印或删除;这些行为需分别声明、授权和验收。
|
|
975
|
+
|
|
976
|
+
## 拒绝通知的修改人 {#workflow-rejection-notification}
|
|
977
|
+
|
|
978
|
+
当业务要求“申请被拒绝时通知最后修改人”,在固定流程定义中声明:
|
|
979
|
+
|
|
980
|
+
```ts
|
|
981
|
+
rejectionNotification: {
|
|
982
|
+
recipient: 'record_last_modifier',
|
|
983
|
+
title: '审批拒绝',
|
|
984
|
+
summary: '您有一个审批被拒绝,请查看',
|
|
985
|
+
},
|
|
986
|
+
```
|
|
987
|
+
|
|
988
|
+
最后修改人是拒绝事务读取的 Native 主记录 `updated_by`,即最后一次成功业务写入所归属的用户。
|
|
989
|
+
例如 A 发起、B 成功补填、C 拒绝时,专用拒绝通知发给 B。审批意见、拒绝操作和未成功的
|
|
990
|
+
业务写入不会替换修改人。平台在原事务锁定主记录、冻结当前资料 revision 和收件人,
|
|
991
|
+
通知队列恢复时使用原事实;之后的编辑不会改变这次通知的对象。
|
|
992
|
+
|
|
993
|
+
标题最多160、摘要最多500字符,都是固定文本;不支持客户端收件人、任意字段路径、
|
|
994
|
+
默认兜底人或节点管理员修改。缺失记录、空修改人或当前租户内无有效普通用户时,
|
|
995
|
+
事实明确记录跳过原因;数据库或资源绑定失败沿原命令回滚,不产生部分拒绝事实。
|
|
996
|
+
|
|
997
|
+
能力 `workflow.rejection-notification@1.0.0` 和 Notification Hub 由声明自动推导,平台
|
|
998
|
+
初始化无需增加开关。省略声明或旧固定实例继续原行为。消息只读且没有审批按钮;
|
|
999
|
+
点击仍认证并核验当前详情权限,收到消息不产生资料查看或流程办理权。
|
|
1000
|
+
实例原参与消息继续更新终态,专用消息另以实例为键去重。发送仍采用既有 outbox 的
|
|
1001
|
+
至少一次语义,沿原回执恢复;本地验证使用站内或 fake 渠道。
|
|
1002
|
+
|
|
1003
|
+
应用无需后端或自建事件订阅。可编译例子见
|
|
1004
|
+
`examples/workflow-administration/rejection-notification.ts`。
|
|
1005
|
+
|
|
1006
|
+
### 提交前检查必需审批人
|
|
1007
|
+
|
|
1008
|
+
需要在保存业务资料前确认特定审批节点有人时,可在固定 definition 中声明:
|
|
1009
|
+
|
|
1010
|
+
```ts
|
|
1011
|
+
launchPreflight: { requiredApprovalNodes: ['departmentReview', 'finalReview'] }
|
|
1012
|
+
```
|
|
1013
|
+
|
|
1014
|
+
节点必须为实际 approval,最多20个且不能重复;本版只支持 fixed_users、initiator、app_role、app_role_in_scope,不能依赖未来任务补填、外部 provider 或候选字段。BusinessProcess.commit 在业务写入的同一事务内,按当前有效节点配置和真实成员/范围解析这些节点;空人、失效账号、超限或需要尚未提供的交互输入时整笔回滚。emptyPolicy:skip 不能绕过该准入。命中原提交回执时不会重新执行检查。
|
|
1015
|
+
|
|
1016
|
+
这是提交准入,不预先冻结未来审批人;实际进入节点仍重新解析。声明要求目标具备 workflow.launch-preflight@1.0.0,未声明的流程保持原提交行为。实际角色与事务回滚需在目标平台验收。
|
|
1017
|
+
|
|
1018
|
+
## 审批自动完成期限
|
|
1019
|
+
|
|
1020
|
+
可选评价等允许不填写内容的审批节点,可以声明固定期限:
|
|
1021
|
+
|
|
1022
|
+
```ts
|
|
1023
|
+
completionDeadline: { afterSeconds: 600, action: 'approve' }
|
|
1024
|
+
```
|
|
1025
|
+
|
|
1026
|
+
此声明需要 `workflow.completion-deadline@1.0.0`。平台在正常任务进入事务中保存
|
|
1027
|
+
期限,以数据库创建时间计时,默认每30秒扫描,到期可能有扫描及排队延迟。
|
|
1028
|
+
期限支持1秒至30天,由应用代码拥有,管理员不能改变期限、条件或连接。
|
|
1029
|
+
没有声明的节点继续人工办理;退回补正和恢复源任务仍须人工处理。
|
|
1030
|
+
|
|
1031
|
+
到期是整个节点自动完成,剩余审批席位取消,保留已提交内容与真实人工意见,
|
|
1032
|
+
历史标记“超时自动同意”,不会给申请人或未处理人员伪造审批票。
|
|
1033
|
+
只允许可选任务输入;必填字段、条件必填、子表必填、`edit_required`、同意意见
|
|
1034
|
+
必填和自定义 approve handler 与期限冲突,编译及平台注册都会拒绝。
|
|
1035
|
+
节点配置不能把此类节点改成必须填写同意意见。
|
|
1036
|
+
|
|
1037
|
+
人工处理与后台执行共用实例锁,先完成者生效。任务离开、退回、撤回、终止或
|
|
1038
|
+
删除时,在同一事务取消期限。下游失败回滚整次流转,保存脱敏错误码并有界退避;
|
|
1039
|
+
最多12次失败后停止自动重试,保留人工办理。PC/手机任务详情显示截止时间或
|
|
1040
|
+
失败提示,管理流程图显示固定规则,实例轨迹显示实际自动完成证据。
|
|
1041
|
+
本批没有管理员重试或改期限入口。
|
|
1042
|
+
|
|
1043
|
+
平台重启后继续处理原持久期限,无需额外启用开关。已有期限的版本回滚时,
|
|
1044
|
+
必须保留兼容的平台后台,或先完成/明确取消在途任务;不能删除期限与历史。
|
|
1045
|
+
|
|
1046
|
+
|
|
1047
|
+
## 退回发起人补正 {#initiator-correction}
|
|
1048
|
+
|
|
1049
|
+
数据更正使用独立的固定节点,不作为本人审批票:
|
|
1050
|
+
|
|
1051
|
+
```ts
|
|
1052
|
+
startAt: 'calculate',
|
|
1053
|
+
taskPages: { correction: { title: '补正申请', fields: [{ code: 'amount', required: true }] } },
|
|
1054
|
+
nodes: {
|
|
1055
|
+
// calculate 和 review 沿应用已声明的代码步骤及审批节点。
|
|
1056
|
+
correct: { id: 'correct', kind: 'correction', title: '发起人补正',
|
|
1057
|
+
taskPageCode: 'correction', next: 'calculate' },
|
|
1058
|
+
// review.returnTargets 声明 ['correct'];其他正向边不能进入 correct。
|
|
1059
|
+
},
|
|
1060
|
+
```
|
|
1061
|
+
|
|
1062
|
+
`next` 必须等于固定 `startAt`。该节点只能由声明的审批退回进入,包括第一个审批节点;
|
|
1063
|
+
退回到其他审批节点仍需真实人工办理历史。补正沿当前任务页、Native授权和资料修订,
|
|
1064
|
+
仅原发起人直接办理,只有保存补填和重新提交,不代理、转交、加签或管理员代填。
|
|
1065
|
+
原职责失效或修订改变时拒绝,不换身份继续。
|
|
1066
|
+
|
|
1067
|
+
保存不推进。重新提交在同一事务更新标量资料与事实、关闭补正任务及退回会话,
|
|
1068
|
+
从固定起点重新执行条件与代码步骤。补正重提记录 `resubmitted`,不产生同意票或
|
|
1069
|
+
代理申请的人工批准确认。只支持 `replay`,请求 `resume_current` 明确拒绝。
|
|
1070
|
+
初期补正页不支持 owned 子表;创建时的 owned 事实快照不能代替补正后的事实刷新。
|
|
1071
|
+
|
|
1072
|
+
图显示旁侧补正节点、直角虚线退回/重提路径,正向分支的层级保持;拓扑和代码仍固定。
|
|
1073
|
+
声明自动要求 `workflow.initiator-correction@1.0.0`,无需增加默认关闭的开关。
|
|
1074
|
+
结果未知使用当前任务原命令回执恢复,不重建申请;数据、任务或事件失败一起回滚。
|
|
1075
|
+
|
|
1076
|
+
### 补正重提的业务校验 {#correction-business-command}
|
|
1077
|
+
|
|
1078
|
+
补正涉及年限资格、培训日期、报销上限或当前主数据时,字段 Schema 之外还要重新执行
|
|
1079
|
+
业务规则。在固定定义声明 `commandHandlers.resubmit: { operationCode: 'requests.resubmit' }`,
|
|
1080
|
+
把该操作的 `platformAccess.workflow` 声明为
|
|
1081
|
+
`{ codes: ['request-approval'], businessCommands: ['resubmit'] }`。
|
|
1082
|
+
操作必须是受控、强制幂等的 POST,绑定同一父资源的 `recordId`;请求 Schema 使用
|
|
1083
|
+
`openxiangda/config` 导出的 `workflowBusinessCommandInvocationSchema`。
|
|
1084
|
+
响应使用完整、闭合的实际结果 Schema,不能以开放的顶层对象绕过受控操作检查。
|
|
1085
|
+
|
|
1086
|
+
标准 PC/手机任务页根据当前 Surface 调用该具名操作;应用不复制审批流转或预测下游
|
|
1087
|
+
动态人员。处理器先调用 `businessProcess.resolveOriginalTaskCommand(invocation)` 查询原结果,
|
|
1088
|
+
再合并受限任务字段、重验当前业务规则和资料,最后调用 `commandWithData`,
|
|
1089
|
+
使用 `expectedTransition: { kind: 'correction-replay' }`。平台验证真实本人补正、原任务与
|
|
1090
|
+
资料修订,在同一事务保存字段、刷新事实、核验 Native guards、关闭退回会话并重新计算。
|
|
1091
|
+
业务 mutation 仅写非事实的可信快照或审计字段,不能直接改变 `factProjection` 字段。
|
|
1092
|
+
|
|
1093
|
+
`save_form` 仍可保存未填完的资料;只有通过业务重校验才能重提。直接调用原 Workflow
|
|
1094
|
+
重提入口会被拒绝,管理员不能替原发起人绕过该处理器。仅声明 resubmit 的流程可保留
|
|
1095
|
+
普通审批的退回和自动策略;包含 approve/reject/withdraw 业务 handler 的既有限制不变。
|
|
1096
|
+
自动协商 `workflow.correction-business-command@1.0.0`,无需额外开启功能。
|
|
1097
|
+
本人标量补正支持 Native 写入,owned 子表补正仍不支持;原已成功结果先于当前资料重验
|
|
1098
|
+
恢复,不因日期推移或资料后来停用而被误报为失败。接入方法见[后端](backend.md#correction-business-command)。
|