软件(Application)定义编写指南¶
目标:Agent 直接生成/修改 workspace 软件定义。知识以本文为准。不写原理;不依赖外链。
术语:软件 = Application(产品文档中「软件」「应用」同义)。下层是模块 → 表单/视图/流程等。
产出物¶
| 部分 | 落盘 | 形态 |
|---|---|---|
| 软件元数据 | {软件名}.application |
JAXB XML 根 application;id 为 XML 属性 |
| 默认数据源 | datasource/{数据源名}.datasource |
XML 根 dataSource |
| 角色 | role/{角色名}.role |
XML 根 role |
| 索引空文件 | pid.index、url.index |
新建时创建空文件即可 |
| 模块等 | module/ 等(见目录树) |
属模块/表单/视图技能;本文只给路径约定 |
storage/workspace/{软件名}.application/
storage/workspace/{软件名}.application/{软件名}.application
storage/workspace/{软件名}.application/datasource/{数据源名}.datasource
storage/workspace/{软件名}.application/role/{角色名}.role
storage/workspace/{软件名}.application/module/{模块名}.module/
新建最低配置(常规业务软件 type=0):
- 目录
{name}.application/+ 同名{name}.application文件:id、name、type=0、activated=true;applicationid必须等于id - 至少一个
.datasource:defaultDataSource=true+ JDBC/JNDI;落盘后投递*.init_default_datasource并确认.sync/.done/(见 DATASOURCE_SKILL);parentId/applicationid=软件 id - (常用)至少一个有效角色
.role:status=1;企业域绑定该软件后,前台用户靠角色可见非系统软件 - (常用)
pid.index、url.index空文件
约定:
- XML:JAXB;根元素小写/约定名见下;脚本/长文本用 CDATA;布尔
true/false id:统一__+ 短 UUID。示例:__MpEzTToulqZtNEFisw6;全局/库内唯一;applicationid=同值- 软件
name:workspace 全局唯一;即目录名{name}.application;禁止含/%\(系统会转义) - 改
name= 改目录名;激活保存时会重建数据源连接并同步动态表——不要随意改名 - 子资源一律:
parentId=软件 id,applicationid=软件 id - 勿再往
.application写datasourceId(历史字段;当前以数据源defaultDataSource为准)
1. Application 属性 → .application¶
属性表¶
| 属性 | XML | 类型 | 默认 | 说明 |
|---|---|---|---|---|
id |
属性 | string | 须生成 | __ + 短 UUID;applicationid 同值 |
name |
子元素 | string | — | 必填;文件名/目录名;全库唯一 |
description |
子元素 | string/CDATA | 描述 | |
remark |
子元素 | string/CDATA | 备注(基类字段,少用) | |
type |
子元素 | int | 0 | 见 type 表;保存后慎改 |
orderNo |
子元素 | int | 0 | 软件列表排序(升序) |
activated |
子元素 | bool | false | true 才参与运行初始化/前台列表 |
category |
子元素 | string | 分类标签(列表过滤) | |
brief |
子元素 | string | 简介 | |
ico |
子元素 | string | 图标 JSON,见下 | |
homePage |
子元素 | string | 自定义首页路径,如 /static/kms/kmspc/index.html |
|
dependencies |
子元素 | string | 依赖的其他软件 name(可逗号等分隔,样例多为单名) | |
createDate |
子元素 | datetime | 可选;2023-09-06T08:00:00.000+08:00 |
|
url / token / encodingAESkey |
子元素 | string | 仅 type=1 BPM 更新时写入 | |
weixinAgentId / WeixinSecret |
子元素 | string | 微信;注意 Secret 字段名历史大写 W | |
dingdingAgentId / dingdingAppSecret / dingdingAppKey |
子元素 | string | 钉钉 | |
feishuAgentId / feishuAppSecret / feishuAppKey |
子元素 | string | 飞书 | |
systemWidgetSetting |
子元素 | string | 系统 widget 设置串 | |
debugging |
— | bool | false | 调试中;一般不落盘 |
edit |
— | bool | true | 是否可改;一般不落盘 |
isEncrypt |
— | bool | 加密包标记;一般不落盘 |
不落盘/运行期解析:
modules、默认DataSource:从子目录读,不写进.application- API 详情可能返回
datasourceName(默认库名称),不是 XML 字段
type¶
| 值 | 常量 | 含义 |
|---|---|---|
0 |
NORMAL_TYPE | 常规软件(业务默认) |
1 |
BPM_PLATFORM_TYPE | BPM 平台软件;可配 url/token/encodingAESkey |
2 |
SYSTEM_TYPE | 系统自带软件;前台对用户**无需本软件角色**即可出现在列表(仍须域绑定+activated) |
ico 格式¶
字符串形式 JSON(不是嵌套 XML):
| 键 | 说明 |
|---|---|
icon |
图片路径或字体类 |
icontype |
img / font / 空 |
.application XML 骨架(常规)¶
文件:LeaveOA.application/LeaveOA.application
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<application id="__a1b2c3d4e5f6g7h8i9j">
<name>LeaveOA</name>
<description><![CDATA[请假办公]]></description>
<type>0</type>
<orderNo>0</orderNo>
<activated>true</activated>
<category>demo</category>
<brief>请假与考勤</brief>
<ico>{"icon":"/uploads/lib/icon/p14_label.png","icontype":"img"}</ico>
</application>
BPM(type=1)增量元素¶
系统软件 / 自定义首页示例要点¶
- type=2:如
admintools、km homePage:指向应用内static/或产品静态资源路径;运行期魔术静态:/obpm/magic-static/{软件名}/...对应目录{软件名}.application/static/
保存时运行副作用(写文件后若走平台 save API)¶
当 activated=true:
- 解析默认数据源(见 §2)
- 初始化该库上的平台静态表(T_DOCUMENT 等工作表)
- 对该软件下所有表单执行动态表 createOrUpdate(TLK_…)
- 若 name 变更:销毁并重建 DataSourceEnv
仅手写 workspace 文件时:依赖下次启动/导入/设计器保存触发同步。
2. 数据源 → datasource/{name}.datasource¶
完整字段、dbType/驱动、读写分离、脚本按名以 DATASOURCE_SKILL 为准;本节仅保证软件可激活的最小约定。
软件层**不再**保存默认库 id。运行时:
- 列出该软件下全部 DataSource
- 优先
defaultDataSource=true的项 - 若都未标记 → 取列表第一项(兼容旧包)
历史 .application 里可能仍有 <datasourceId>…</datasourceId>:新写忽略;以 .datasource 的 defaultDataSource 为准。
属性表¶
| 属性 | 类型 | 默认 | 说明 |
|---|---|---|---|
id |
attr | 须生成 | __ + 短 UUID |
name |
string | — | 必填;文件名 |
parentId |
string | — | = 软件 id |
applicationid |
string | = 软件 id(建议写) | |
description |
CDATA | ||
defaultDataSource |
bool | false | 默认库须 true;同软件建议仅一个 true |
useType |
string | JDBC | JDBC / JNDI |
driverClass |
string | JDBC 驱动类 | |
url |
CDATA | JDBC URL;可含 ${DB_HOST:localhost} 占位 |
|
username |
string | 可含占位 | |
password |
CDATA | 可含占位 | |
dbType |
int | — | 见下表 |
poolsize |
string | 如 20 |
|
timeout |
string | 如 3600 |
|
jndiName 等 |
string | useType=JNDI 时 | |
readonly |
bool | false | 读写分离 |
readonlyUseType / readonlyDriverClass / readonlyUrl / readonlyUsername / readonlyPassword / readonlyDbType / readonlyPoolsize / readonlyTimeout / readonlyJndi* |
只读库;readonly=true 时配 |
dbType¶
| 值 | 库 |
|---|---|
| 1 | Oracle |
| 2 | SQL Server |
| 3 | DB2 |
| 4 | MySQL(最常见) |
| 5 | HSQL |
| 6 | PostgreSQL |
| 7 | 达梦 DM |
| 8 | 人大金仓 KingBase |
| 9 | OceanBase |
| 10 | 神通 Oscar |
JDBC MySQL 骨架¶
文件:LeaveOA.application/datasource/main.datasource
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<dataSource id="__dsLeaveOAmain001">
<name>main</name>
<parentId>__a1b2c3d4e5f6g7h8i9j</parentId>
<applicationid>__a1b2c3d4e5f6g7h8i9j</applicationid>
<defaultDataSource>true</defaultDataSource>
<useType>JDBC</useType>
<driverClass>com.mysql.jdbc.Driver</driverClass>
<url><![CDATA[jdbc:mysql://localhost:3307/obpm_leave?useUnicode=true&characterEncoding=utf8&useSSL=false]]></url>
<username>root</username>
<password><![CDATA[password]]></password>
<dbType>4</dbType>
<poolsize>20</poolsize>
<timeout>3600</timeout>
<readonly>false</readonly>
<readonlyUseType>JDBC</readonlyUseType>
<readonlyDbType>0</readonlyDbType>
</dataSource>
路径:/{软件名}.application/datasource/{数据源名}.datasource
无默认数据源时:激活软件不会初始化 RT 表,表单动态表同步也会跳过。
3. 角色 → role/{name}.role¶
前台用户能看见非 SYSTEM 软件的条件:
- 企业域
BIND_APPLICATIONS绑定该软件 id - 软件
activated=true - 用户拥有该软件下
status=1的角色(SYSTEM_TYPE 软件跳过角色检查)
最小骨架(字段/permissions/用户绑定/RBAC 以 ROLE_SKILL 为准):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<role id="__roleAdmin000000001">
<name>管理员</name>
<parentId>__a1b2c3d4e5f6g7h8i9j</parentId>
<applicationid>__a1b2c3d4e5f6g7h8i9j</applicationid>
<roleNo>1</roleNo>
<status>1</status>
<defaultRole>true</defaultRole>
<orderNo>0</orderNo>
</role>
路径:/{软件名}.application/role/{角色名}.role
4. Workspace 目录树(应用级子资源)¶
相对 storage/workspace/{软件名}.application/:
| 路径 | 后缀/根 | 说明 |
|---|---|---|
{软件名}.application |
application |
软件本体 |
pid.index / url.index |
空文件 | 设计态索引占位;新建时创建 |
module/{模块名}.module/ |
module |
一级模块(parent=Application 时走 /module/) |
{子模块名}.module/(在父模块目录下) |
module |
子模块 path 不再插 /module |
datasource/*.datasource |
dataSource |
数据源 |
role/*.role |
role |
角色 |
menu/*.menu |
菜单 ResourceVO | PC 菜单 |
mobilemenu/*.mobilemenu |
移动菜单 | |
widget/ |
widget / widgetgroup | 首页小组件 |
macro/*.macro |
脚本库 | |
valid/*.valid |
校验库 | |
style/*.style |
样式库 | |
task/*.task |
定时任务 | |
excelconfig/*.excelconfig |
Excel 导入配置 | |
mulitlang/*.mulitlang |
多语言(历史拼写 mulitlang) | |
api/ |
apigroup / api | API 中心 |
links/*.link |
链接(FILE_GROUP=/links) |
|
statelabel / statelabels |
状态标签 | 以实际落盘为准 |
bigscreen/ |
大屏 | |
datamodel/ |
数据模型 | |
extinterface/ |
外部接口 | |
database/ |
库相关附属 | 样例可能存在 |
resources/ |
资源文件 | |
static/ |
静态托管 | URL:…/magic-static/{软件名}/… |
README.md |
可选说明 | 设计器 readme API 可读 |
模块内(简述;详见表单/视图/模块 skill):
子资源 parentId:
- 挂在软件下:= 软件 id
- 挂在模块下:= 模块 id;
applicationid仍=软件 id
模块路径硬规则¶
- parent 是 Application:
/{app}.application/module/{name}.module - parent 是 Module:
/{父路径}/{name}.module(不再套一层module/) - 模块字段:
orderNo、superior(上级模块 id,可选)
5. 企业域与前台可见¶
企业域表字段 BIND_APPLICATIONS(TEXT)存绑定的应用。前台列表逻辑概要:
- 取用户所属域绑定的 Application 集合
activated==true- 若
type != SYSTEM_TYPE:用户须有该 app 下有效 Role(status=1且role.applicationid==app.id) - SYSTEM_TYPE:跳过角色检查
仅写 workspace **不会**自动改域绑定;域配置在运行库/管理端,不在 .application 文件内。
开发者账号与软件的可见关系由超级用户配置中的 applications 列表维护(设计器创建时若当前用户是 developer 会挂上)。
6. 命名与 id¶
| 规则 | 要求 |
|---|---|
| 软件 name | 非空;全 workspace 唯一;作目录名;英数/连字符稳妥 |
| 软件 id | 统一 __ + 短 UUID;applicationid=id |
| 子资源 name | 同目录不重名;/ % \ 避免 |
| 重命名软件 | 改文件夹名 + 文件内 <name> + 重建索引/连接;高风险 |
id 生成:统一 __ + 短 UUID。示例:__MpEzTToulqZtNEFisw6。须不与现有冲突。
7. 新建清单(Agent 落盘顺序)¶
1. 生成 appId;确定 name、type、activated
2. 建目录 storage/workspace/{name}.application/
3. 写 {name}.application(id=appId,无 datasourceId)
4. 写空 pid.index、url.index
5. 写 datasource/{dsName}.datasource(defaultDataSource=true,parentId=appId)
6. (推荐)写 role/….role(status=1)
7. (业务)写 module/….module 及表单/视图等
8. (部署)企业域绑定 appId;用户分配角色
完整最小包示例结构¶
LeaveOA.application/
LeaveOA.application
pid.index
url.index
datasource/
main.datasource
role/
管理员.role
module/
leave.module/
leave.module # 模块元数据另见 MODULE_SKILL
LeaveRequest.form/…
LeaveList.view/…
8. 校验与常见错误¶
| 问题 | 处理 |
|---|---|
| 软件名称已存在 | 换 name / 目录名 |
| 软件名称不能为空 | 写非空 name |
| 前台看不到软件 | 查 activated、域绑定、角色、type |
| 表单无表/连接失败 | 查 defaultDataSource、JDBC、dbType |
| 旧包 datasourceId 无效 | 改用 .datasource+defaultDataSource |
| 根元素错误 | 软件=application;数据源=dataSource;角色=role |
| id 写成子元素 | 基类为 @XmlAttribute → <application id="…"> |
9. 与其它技能边界¶
| 内容 | 本文 | 其它 |
|---|---|---|
| 软件元数据、应用目录、默认数据源路径与最小骨架 | ✓ | |
.datasource 字段、dbType、JDBC/JNDI、读写分离、脚本按名 |
最小骨架 | DATASOURCE_SKILL |
.role 字段、permissions、用户绑定 |
最小骨架 | ROLE_SKILL |
| 模块字段与嵌套 | 路径约定 | MODULE_SKILL |
.form / JsonTemplate / activity |
FORM_SKILL | |
.view / column / activity |
VIEW_SKILL | |
| 流程/报表字段细节 | 仅路径 | 对应手册/后续 skill |
.menu / .mobilemenu / linkType |
仅路径 | MENU_SKILL |
生成业务功能时:先保证本节软件+默认数据源(细节见 DATASOURCE_SKILL)+角色,再在 module/ 下落表单视图。