跳转至

模块定义编写指南

目标:让 Agent 直接生成/修改 workspace 模块定义。知识以本文为准。不写实现原理;不依赖外链。

模块 = 应用内的**资源容器**(表单/视图/流程/报表/图表 + 子模块)。本身几乎无业务逻辑,属性极少。

产出物一览

部分 落盘 形态
模块目录 {模块名}.module/ 目录;内放元数据与全部子资源
模块元数据 {模块名}.module/{模块名}.module JAXB XML 根 module(小写)
/{应用名}.application/module/{模块名}.module/{模块名}.module
/{应用名}.application/module/{父模块}.module/{子模块}.module/{子模块}.module

路径相对 storage/workspace。应用目录本身是 /{应用名}.application/,应用元数据文件同名 /{应用名}.application/{应用名}.application

新建最低配置:

  1. 建目录 {name}.module/
  2. 写同名元数据文件 {name}.module/{name}.moduleidnameparentIdorderNosuperior
  3. 之后在该目录下再放 .form / .view / .flow 等(各自再有同名元数据文件)

约定:

  • JAXB XML;根元素 moduleid 写在 根属性
  • 脚本/长文本用 <![CDATA[...]]>description/remark
  • 目录名 = 文件名 = name = {name}.module,三者必须一致
  • 子资源的 parentId = 本模块 id(不是应用 id)
  • 菜单/角色/数据源/样式库/脚本库等 落在模块目录(见「非模块资源」)

1. 模块属性 → .module XML

属性表

属性 XML 类型 默认 说明
id 根属性 id string 须生成 __ + 短 UUID(见下)
name 子元素 string 必填;目录名与元数据文件名
parentId 子元素 string 文件系统父:顶层=应用 id;子模块=上级模块 id
superior 子元素 string "" 逻辑上级模块 id;顶层留空;子模块=上级模块 id
orderNo 子元素 int 0 同级排序;越小越前;比较用
description 子元素 CDATA string 模块描述
remark 子元素 CDATA string 可省略 备注;样例中常不写
applicationid string 不进 XML;仅 API/运行时;写盘时靠路径归属应用
uri string 推导 不进 XML;运行时 = getPath()+"/"+name+".module"

parentIdsuperior(必一致规则)

创建/更新时约定(与设计态 Controller 一致):

场景 superior parentId 磁盘路径
顶层模块 ""(空) 应用 id /{应用}.application/module/{name}.module/
子模块 上级模块 id 上级模块 id(= superior) /{…}/{上级}.module/{name}.module/

校验失败条件(设计态):

  • name 为空 →「模块名称不能为空」
  • 同级(相同 parentId)重名 →「同级模块名称已存在」
  • name 与上级模块 name 相同 →「名称不可以跟上级相同」
  • 改名时与已有下级模块 name 冲突 →「下级存在相同名称」

name 含路径危险字符时落盘替换(读写时再还原):/=47%=37\=92尽量用中文或英文,勿自带 / \%

id 生成

统一规则:__ + 短 UUID。示例:__MpEzTToulqZtNEFisw6。须全局/库内不冲突。

顶层模块 XML 示例

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<module id="__MpEzTToulqZtNEFisw6">
  <name>事件模块</name>
  <parentId>__l7pzNG6dR2wuVJ1kOGV</parentId>
  <description><![CDATA[售后事件]]></description>
  <orderNo>0</orderNo>
  <superior></superior>
</module>

其中 parentId = 应用 afterservice 的 id;磁盘:

/afterservice.application/module/事件模块.module/事件模块.module

子模块 XML 示例

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<module id="__yV15cDXVn1xnPHSBvcT">
  <name>付款管理</name>
  <parentId>__c7cEpnBnGHGKH7X3MK4</parentId>
  <description><![CDATA[]]></description>
  <orderNo>90</orderNo>
  <superior>__c7cEpnBnGHGKH7X3MK4</superior>
</module>

磁盘(父为 合同执行):

/contract.application/module/合同执行.module/付款管理.module/付款管理.module

父模块元数据仍可 superior 为空、parentId=应用 id;子资源与子模块同目录并列。

目录内容示意(付款管理)

付款管理.module/
  付款管理.module          ← 元数据
  payment_application.form/
  payment_withdraw.form/
  payment_application.view/
  付款申请流程.flow/
  资金付款通知单.report/

2. 模块内可挂资源

仅列 模块目录下直接子项(后缀 = 目录名最后一段)。子项自身常再是「目录 + 同名元数据文件」。

后缀 含义 子项 parentId
module 子模块 父模块 id(+ superior
form 表单 本模块 id
view 视图 本模块 id
flow 流程 本模块 id
report 套打/报表模板 本模块 id
chart 统计图 本模块 id

设计态/其它扩展也可能出现在模块下(按需):echartsreportcrossreportexcelconfig、打印模板等;规则同样:parentId=模块 id,路径挂在本模块目录下。

非模块资源(勿塞进 .module

落在 应用目录(或全局)其它 group,常见:

后缀/group 位置 说明
menu / mobilemenu /{应用}.application/menu/ 入口;链接时 选择模块 再选表单/视图
role 应用下 权限;可授「模块资源」
datasource 应用下 库连接
style / macro / valid / task / widget / statelabel / api 应用下对应 group 与模块无父子目录关系

模块 不是 前台菜单。无菜单则用户无法从导航打开模块内视图/表单(可用表单/视图上的「创建菜单」或手写 .menu 并指定模块 id)。

跨模块引用

  • 视图「数据来源表单」、多数设计器下拉:默认本模块;部分操作强调同模块(如某些视图间配置)
  • 表单控件(视图选择框 module=、包含元素选其它模块视图等)**可以**引用他模块资源 id
  • Agent 生成资源时:新建表单/视图的 parentId 必须是其物理所在模块的 id,与目录一致

表单/视图/统计图细节 → generate-form-file / generate-view-file / generate-chart-file。路径模板复用:

/{应用}.application/module/{模块}.module/{表单}.form
/{应用}.application/module/{模块}.module/{视图}.view
/{应用}.application/module/{模块}.module/{图表}.chart
/{应用}.application/module/{模块}.module/{流程}.flow

嵌套模块时把路径中的 {模块}.module 换成完整链,例如:

/.../module/合同执行.module/付款管理.module/payment_application.form

3. 与子资源的关系(写入检查)

对象 字段指向模块
Form / View / Flow / Report / Chart parentId = 模块 id
子 Module parentId = superior = 父模块 id
PC/移动菜单 配置里选模块 id,再选该模块下的表单/视图/报表等
打印/Excel 设计器数据源 moduleId + formId/viewId

删除模块(设计态):按 uri整个模块目录 做逻辑删除(含其下表单/视图/子模块等)。改模块前确认无未备份依赖。

重命名模块:须同步改 目录名、元数据文件名、XML <name>;并更新缓存/索引(经设计态 API 改名会处理 uri;纯改文件时三者必须一致)。

排序:同级按 orderNo 升序(Module.compareTo)。


4. 设计态 API(可选;优先直接写文件)

Base:/api/designtime(设计器常再加 /designer 前缀)。{appId} = 应用 id。

方法 路径 作用
GET /applications/{appId}/modules?parentId= 按父列子模块;parentId 空则当应用 id
GET /applications/{appId}/modules/{moduleId} 详情:id/name/orderNo/description/uri/superior/superiorName
POST /applications/{appId}/modules 新建;body=Module JSON;服务端分配 id
PUT /applications/{appId}/modules/{moduleId} 更新 name/description/orderNo/superior(并重算 parentId)
DELETE /applications/{appId}/modules body= id 字符串数组
GET /applications/{appId}/allmodules?currentModuleId= 树形下拉;排除当前;返回 {id,value}

列表项字段注意:

  • hasChild有子模块时为 false,叶子为 true(前端树控件约定,语义反直觉)
  • 列表含 urisuperiorapplicationId

新建 JSON 要点:

{
  "name": "事件模块",
  "description": "",
  "orderNo": 0,
  "superior": ""
}
  • superior 空 → parentId=applicationId
  • superior 非空 → parentId=superior
  • 响应通常只回 { "id": "..." }

模块下资源 REST(供对照,细节见对应 Skill):

GET/POST  .../modules/{moduleId}/forms
GET/PUT   .../modules/{moduleId}/forms/{formId}
GET/POST  .../modules/{moduleId}/views?viewType=
GET/PUT   .../modules/{moduleId}/views/{viewId}?viewType=

打印等:.../modules/{moduleId}/print/templates

宿主桥常用:getModules(){id,name}getModuleForms / getModuleViews


5. 概念位置(Agent 心智模型)

企业域 Domain
  └─ 软件 Application(/{name}.application)
       ├─ 数据源 / 角色 / 菜单 / 样式库 / …
       └─ module/
            └─ 业务模块 Module(可嵌套)
                 ├─ Form(→ 动态表 TLK_*)
                 ├─ View
                 ├─ Flow
                 ├─ Report / Chart
                 └─ 子 Module …
  • 软件:应用集合边界;角色把域用户接到软件
  • 模块:开发与资源分组单位;可多人分模块开发
  • 表单/视图/流程:业务能力;须挂在某一模块下
  • 菜单:运行入口;绑定模块内某一表单/视图等

6. 正确性检查清单

- [ ] 目录 {name}.module/ 与元数据文件 {name}.module/{name}.module 同名
- [ ] XML 根为 module;id 在根属性;含 name、parentId、orderNo、superior
- [ ] 顶层:superior 空且 parentId=应用 id;路径在 .../module/ 下
- [ ] 子模块:superior=parentId=父模块 id;目录嵌在父 .module 下
- [ ] 同级 name 不重复;不等于上级 name
- [ ] 模块下每个 .form/.view/.flow 等 parentId=本模块 id
- [ ] 未把 menu/role/datasource 放进模块目录
- [ ] 需要前台入口时另配菜单并选中本模块
- [ ] 删模块等于删整棵目录树(含下级)——确认后再删

最低可运行空模块(两步)

  1. 确认应用 id(读 /{应用}.application/{应用}.application 根属性 id
  2. 写:
/{应用}.application/module/DemoModule.module/DemoModule.module
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<module id="__YourModuleIdHere00001">
  <name>DemoModule</name>
  <parentId>应用id填这里</parentId>
  <description><![CDATA[]]></description>
  <orderNo>1</orderNo>
  <superior></superior>
</module>

随后在同目录按 FORM_SKILL / VIEW_SKILL 添加表单与视图。