视图定义编写指南¶
目标:让 Agent 直接生成/修改 workspace XML 文件(.view + .column + .activity)。
不写实现原理。不写 REST。只描述:属性表 + 可粘贴的 XML 片段;知识以本文为准。
iScript:写 filterScript / sqlFilterScript / procedureFilterScript / scriptDataFilterScript / 列 valueScript / hiddenScript / 操作脚本等时,先读 iscript-usage(含 GraalVM 差异) → view.md、activity.md;本文只定属性名与落盘。
产出物一览¶
| 部分 | 落盘路径 | XML 根 |
|---|---|---|
| 视图元数据 | {视图名}.view |
ListView / TreeView / …(具体类名);**不含**列/操作 |
| 列 | {视图名}.view/{列名}.column |
column |
| 工具栏操作 | {视图名}.view/{操作名}.activity |
activity |
| 事件(可选) | {视图名}.view/{事件名}.event |
event |
workspace 路径(相对 storage/workspace):
/{应用名}.application/module/{模块名}.module/{视图名}.view
/{应用名}.application/module/{模块名}.module/{视图名}.view/{列名}.column
/{应用名}.application/module/{模块名}.module/{视图名}.view/{操作名}.activity
新建最低配置:
{name}.view:根元素对应当前类型;name、editMode+对应字段、relatedForm(设计模式)- 至少一个
{列名}.column(parentId/parentView= 视图 id) - (常用)创建+删除:
type=2、type=3的.activity
约定:
- JAXB XML;空字段可省略;脚本字段用
<![CDATA[...]]> - 布尔写
true/false;editMode写00/01/02/03/04(无引号) - Column 表单 id 标签为
<formid>(全小写) id(.view/.column/.activity)统一__+ 短 UUID;全局/库内不冲突。示例:__MpEzTToulqZtNEFisw6expandQueryForm默认false(展开查询表单=否);即便配置了searchFormId也不自动展开,需展开时显式true
硬规则(落盘前必查,否则索引/平台关联失败)¶
id一律写在根元素的「属性」上,不要写成子元素<id>。 重建索引脚本(rebuild_index.py)用root.get("id")取 id;写成子元素<id>→ 该文件**不会进url.index**,等于不存在。- ✅
<ListView id="...">、<column id="...">、<activity id="..."> - ❌
<ListView><id>...</id>、<column><id>...、<activity><id>... - 列与操作必须同时写
<parentId>= 视图 id 和<applicationid>= 应用 id(外加<parentView>)。pid.index的父子关系**只认<parentId>,不认<parentView>**;只写parentView→ 列/操作在索引里成「孤儿」,表现为「没关联到视图」、工具栏按钮不出现。 - 三者同值:列/操作的
<parentId>=<parentView>= 所属视图 id。 - 映射表(
relatedForm的.formtype=65536)列表/选择视图:普通列禁止COLUMN_TYPE_FIELD。 列表单元格按表单字段名取值会对不上物理列 Item 名而显示空白;双击打开表单却有值。细则见「硬规则:映射表列表列」。事务表(type=1)列表仍用 FIELD。 - 下文所有示例均已按 1、2 修正;直接照抄即可,勿自行把
id改回子元素或省略<parentId>。
1. 视图属性 → .view XML¶
必填 / 常用(AbstractView → 子元素)¶
| 元素 | 类型 | 默认 | 说明 |
|---|---|---|---|
id |
根属性 | 须生成 | __ + 短 UUID;<ListView id="...">;列/操作的 parentId/parentView |
name |
string | — | 必填;文件名 {name}.view |
parentId |
string | — | 所属模块 id |
applicationid |
string | — | 应用 id |
description / remark |
string | — | CDATA |
editMode |
string | 00 |
数据查询模式 |
relatedForm |
string | — | 数据来源表单 id;不是 formId |
searchFormId |
string | — | 查询表单 id(表单 type=256) |
openType |
int | 1 |
打开方式 |
displayType |
string | — | relatedForm | templateForm |
templateForm |
string | — | 模板表单 id |
permissionType |
string | public |
public / private |
styleId |
string | — | 样式库 id |
pagination |
boolean | true | 折叠视图须 false |
pageLines |
string | — | 每页行数 |
showTotalRow |
boolean | — | 总记录数 |
readonly |
boolean | false | 只读 |
selectCheckbox |
boolean | — | 选择复选框 |
expandQueryForm |
boolean | false | 展开查询表单;默认否(有 searchFormId 也不自动展开;需展开时显式写 true) |
autoCompose |
boolean | — | 自动排版 |
isAllowDrag |
boolean | — | 允许拖动列 |
showWaterMark / waterMarkScript |
bool / CDATA | — | 水印 |
mobileDisplayMode |
string | — | 手机 list/card |
collapsibleShowMode |
string | normal |
折叠 normal/card |
width / height |
int | — | 弹出层(openType=277) |
orderno |
int | — | 排序 |
filterCondition |
CDATA | — | 设计模式(editMode=00)过滤;须为 **JSON 数组**字符串,见下「filterCondition 格式」 |
commonFilterCondition |
CDATA | — | 常用查询字段配置;须为 JSON 数组;无则写 [] |
authorityCondition |
string | — | 权限/系统过滤 |
filterScript |
CDATA | — | DQL(editMode=01),须返回 DQL 字符串;不是 filterCondition |
sqlFilterScript |
CDATA | — | SQL(editMode=02),须返回 SQL 字符串 |
procedureFilterScript |
CDATA | — | 存储过程(editMode=03),如 call xxx |
scriptDataFilterScript |
CDATA | — | 脚本数据(editMode=04),须返回行数据 JSON(或纯 JSON 字面量);见下 |
dataSourceId |
string | — | 数据源 |
relatedMap |
CDATA | — | 列映射串 |
auth_user / auth_role / auth_fields / authFieldScope / departments |
string | — | 私有权限 |
editableScript / readonlyScript |
CDATA | — | 可编辑/只读脚本 |
showActivityColumnType |
int | — | 网格操作列 |
removeActivityScript / confirmActivityScript |
CDATA | — | 网格脚本 |
orderField / orderType |
string | — | 默认排序 |
XML 根 ↔ 视图类型¶
| XML 根 | 含义 | 内部类型值(仅文档用) |
|---|---|---|
ListView |
列表(默认) | 1 |
CalendarView |
日历 | 16 |
TreeView |
树形 | 17 |
MapView |
地图 | 18 |
GanttView |
甘特 | 19 |
CollapsibleView |
折叠 | 20 |
SheetView |
Sheet | 21 |
CardView |
卡片 | 22 |
读盘按 根元素名 选型(id 写在该根元素的属性上)。历史根 view/NormalView → ListView。改类型 = 改根标签。
openType¶
| 值 | 含义 |
|---|---|
1 |
当前页 |
16 |
弹出窗口 |
256 |
父窗口区域 |
272 |
OWN |
277 |
弹出层 |
288 |
网格(仅 ListView;另配 .activity type=34) |
293 |
新页签 |
editMode(数据来源)¶
| 值 | 含义(设计器「数据来源」) | 必配元素 |
|---|---|---|
00 |
设计 | relatedForm;条件:filterCondition / commonFilterCondition / authorityCondition(JSON 数组,见下) |
01 |
DQL | filterScript;系统字段前加 $ |
02 |
SQL | sqlFilterScript;查平台表常带 DOMAINID |
03 |
存储过程 | procedureFilterScript |
04 |
脚本数据 | scriptDataFilterScript;脚本**直接返回行数据**(不经 DB 查询) |
Design 模式业务表:TLK_ + 表单 name;业务列 ITEM_ + 字段名大写;系统字段条件不加 ITEM_。
注意:ITEM_xxx = '值' 这类 SQL/DQL 文本只能写在 filterScript/sqlFilterScript(editMode=01/02),**禁止**写入 editMode=00 的 filterCondition。
filterCondition / commonFilterCondition 格式(editMode=00 硬规则)¶
运行时会把二者按 JSONArray 解析。写成 ITEM_DOC_STATUS = '作废' 等裸 SQL 会报:
A JSONArray text must start with '[' at character 1 of …
| 元素 | 无条件时 | 有条件时 |
|---|---|---|
filterCondition |
<![CDATA[[]]]> |
JSON 对象数组(见下) |
commonFilterCondition |
<![CDATA[[]]]> |
常用查询字段 JSON 数组;无查询同 [] |
禁止: 空 CDATA、裸 SQL/ITEM_ 条件串、DQL 串塞进 filterCondition。
固定值过滤(最常见,type=00;ipField/match=常量):
<filterCondition><![CDATA[[{"field":"doc_status","operator":"=","type":"00","ipField":"作废","numField":0,"daField":"","sfField":"","syField":"","match":"作废"}]]]></filterCondition>
<commonFilterCondition><![CDATA[[]]]></commonFilterCondition>
仅流程**已办结**可选(选单视图常见,字段用系统态 $StateLabel,对齐 CompleteNode statelabel,本仓库默认可为「已完成」):
<filterCondition><![CDATA[[{"field":"$StateLabel","operator":"=","type":"00","ipField":"已完成","numField":0,"daField":"","sfField":"","syField":"","match":"已完成"}]]]></filterCondition>
| 键 | 说明 |
|---|---|
field |
表单字段 name(英文标识,如 doc_status),不是 ITEM_DOC_STATUS;系统态用 $StateLabel |
operator |
= / <> / LIKE 等 |
type |
00=固定值(用 ipField);03=绑定查询表单字段(用 sfField) |
ipField |
type=00 时的比较常量 |
sfField |
type=03 时查询表单字段 name |
match |
常与比较值或绑定字段同文案 |
numField / daField / syField |
数字/日期/系统类占位;无则 0 / "" |
绑定查询表单字段示例(type=03):
[{"field":"doc_name","operator":"LIKE","type":"03","ipField":"","numField":0,"daField":"","sfField":"doc_name","syField":"","match":"doc_name"}]
多条件:JSON 数组内多项,运行时按 AND 组合(与设计器一致)。
类型专有元素¶
| 根 | 额外元素 | 列 mappingField |
|---|---|---|
ListView |
mobileDisplayMode;网格:showActivityColumnType 等 |
无 |
CalendarView |
— | ≥1:CldViewDateColum |
TreeView |
innerType=FORM|VIEW|LINK;nodeLinkId |
≥3:superior_Node、current_Node、name_Node |
MapView |
mapType、mapDisplayType、isSateMap、defaultCenterAddress、level、mapDataSourceField |
常用 titlecolumn/addresscolumn/detailcolumn |
GanttView |
— | ≥4:name/start/end/complete(另有 color/parent) |
CollapsibleView |
collapsibleShowMode;pagination=false |
无;首列路径 AA\BB |
SheetView |
— | 无;建议配保存 activity |
CardView |
cardStyle |
— |
地图 mapDisplayType:PointMarker / MarkerCluster / Heatmap / 线面类;mapDataSourceField = MapField 的 name。
ListView 完整示例(设计模式)¶
文件:LeaveList.view
<?xml version="1.0" encoding="UTF-8"?>
<ListView id="view-uuid">
<name>LeaveList</name>
<parentId>module-uuid</parentId>
<applicationid>app-uuid</applicationid>
<description><![CDATA[请假列表]]></description>
<remark><![CDATA[]]></remark>
<editMode>00</editMode>
<relatedForm>form-uuid</relatedForm>
<searchFormId></searchFormId>
<filterCondition><![CDATA[[]]]></filterCondition>
<commonFilterCondition><![CDATA[[]]]></commonFilterCondition>
<authorityCondition></authorityCondition>
<openType>1</openType>
<displayType>relatedForm</displayType>
<templateForm></templateForm>
<permissionType>public</permissionType>
<styleId></styleId>
<pagination>true</pagination>
<pageLines>15</pageLines>
<showTotalRow>true</showTotalRow>
<readonly>false</readonly>
<selectCheckbox>true</selectCheckbox>
<expandQueryForm>false</expandQueryForm>
<autoCompose>false</autoCompose>
<showWaterMark>false</showWaterMark>
<waterMarkScript><![CDATA[]]></waterMarkScript>
<mobileDisplayMode>list</mobileDisplayMode>
<orderno>1</orderno>
</ListView>
DQL / SQL 模式片段¶
在上述文件中把数据段换成:
<editMode>01</editMode>
<relatedForm>form-uuid</relatedForm>
<filterScript><![CDATA[(function(){ return "$formname = 'tlk_LeaveRequest'"; })()]]></filterScript>
<editMode>02</editMode>
<sqlFilterScript><![CDATA[(function(){ return "select * from TLK_LeaveRequest where DOMAINID='"+getDomainId()+"'"; })()]]></sqlFilterScript>
存储过程:<editMode>03</editMode> + <procedureFilterScript><![CDATA[(function(){ return "call procName"; })()]]></procedureFilterScript>。
脚本数据模式(editMode=04)¶
数据来源选「脚本数据」时:editMode=04,条件脚本写在 scriptDataFilterScript(不是 filterScript/sqlFilterScript)。运行时执行脚本,把返回 JSON 转成文档包再走列渲染;服务端不再切片,分页须由脚本自行处理。
| 项 | 约定 |
|---|---|
editMode |
04 |
| 脚本元素 | scriptDataFilterScript(CDATA) |
relatedForm |
设计器侧「无数据来源表单」;列 COLUMN_TYPE_FIELD 仍可写 formid/fieldName 供映射。若落盘写了 relatedForm,运行时会把行 formid 设为该值 |
displayType |
**不要**用 relatedForm 呈现;设计器切到 04 时会改成 readonly。落盘建议 displayType=readonly(或非 relatedForm) |
| 树/列过滤下拉/总计 | 04 下不保证可用(getSumTotal/getFilterColumnDatas 等为空实现) |
脚本返回结构(对象或 JSON.stringify 后的同形字符串;也可用以 { 开头的**纯 JSON 字面量**,不走 JS):
{
"row_count": 1,
"data": [
{
"id": "docId",
"parentId": "",
"items": [
{ "columnName": "名称", "value": "测试" },
{ "columnName": "说明", "value": "" }
]
}
]
}
| 键 | 说明 |
|---|---|
row_count |
总行数(分页总数);缺省则用当前页 data.length |
data |
**当前页**行列表 |
id / parentId |
文档 id / 父 id;id 可空 |
items[].columnName |
匹配视图列 Column.name(列显示名),写入该列 fieldName;匹配不到则忽略 |
items[].value |
单元格值(转字符串) |
分页与请求参数(运行时写入 params,脚本可读):
| 参数 | 说明 |
|---|---|
_currpage |
当前页 |
lines |
每页行数 |
| 其它 | URL query + 请求体已合并;可用 $WEB.getParameterAsString(key)、params / $PARAMS、paramMap |
脚本示例(IIFE;以 ( 开头时运行时会外包 JSON.stringify):
<editMode>04</editMode>
<relatedForm></relatedForm>
<displayType>readonly</displayType>
<scriptDataFilterScript><![CDATA[(function () {
var page = Number($WEB.getParameterAsString("_currpage") || "1");
var lines = Number($WEB.getParameterAsString("lines") || "15");
var name = $WEB.getParameterAsString("name") || "";
var all = [
{ id: "r1", parentId: "", items: [
{ columnName: "名称", value: "甲" },
{ columnName: "说明", value: name }
]},
{ id: "r2", parentId: "", items: [
{ columnName: "名称", value: "乙" },
{ columnName: "说明", value: "" }
]}
];
var start = Math.max(0, (page - 1) * lines);
return { row_count: all.length, data: all.slice(start, start + lines) };
})()]]></scriptDataFilterScript>
列侧:为每个要展示的字段建 COLUMN_TYPE_FIELD 列,name 必须与脚本 items[].columnName 一致,并填 fieldName(及可选 formid)。
iScript 细节见 iscript-usage/view.md「脚本数据」。
TreeView 示例¶
文件:OrgTree.view;另需三列带 mappingField。
<?xml version="1.0" encoding="UTF-8"?>
<TreeView id="view-tree-uuid">
<name>OrgTree</name>
<parentId>module-uuid</parentId>
<applicationid>app-uuid</applicationid>
<editMode>00</editMode>
<relatedForm>form-uuid</relatedForm>
<innerType>FORM</innerType>
<openType>1</openType>
<pagination>false</pagination>
<permissionType>public</permissionType>
<orderno>1</orderno>
</TreeView>
MapView 示例¶
<?xml version="1.0" encoding="UTF-8"?>
<MapView id="view-map-uuid">
<name>StoreMap</name>
<parentId>module-uuid</parentId>
<applicationid>app-uuid</applicationid>
<editMode>00</editMode>
<relatedForm>form-uuid</relatedForm>
<mapType>tianditu</mapType>
<mapDisplayType>PointMarker</mapDisplayType>
<defaultCenterAddress>广东省广州市天河区</defaultCenterAddress>
<level>4</level>
<mapDataSourceField>location</mapDataSourceField>
<pagination>false</pagination>
<readonly>false</readonly>
<permissionType>public</permissionType>
<orderno>1</orderno>
</MapView>
CollapsibleView / 网格 ListView 要点¶
<CollapsibleView id="view-uuid">
<!-- 公共元素同 ListView -->
<collapsibleShowMode>normal</collapsibleShowMode>
<pagination>false</pagination>
</CollapsibleView>
<ListView id="view-uuid">
<!-- … -->
<openType>288</openType>
<!-- 同目录另写 type=34 的 .activity -->
</ListView>
2. 列属性 → .column XML¶
与 .view 分文件。路径:{视图名}.view/{列名}.column。根:<column id="...">。
通用元素¶
| 元素 | 类型 | 默认 | 说明 |
|---|---|---|---|
id |
根属性 | 须生成 | __ + 短 UUID;<column id="..."> |
name |
string | — | 必填;AA$B 可表头合并 |
parentId |
string | — | = 视图 id(pid.index 父子关系只认此字段;必写) |
applicationid |
string | — | = 应用 id(必写) |
parentView |
string | — | = 视图 id(与 parentId 同值;平台额外用) |
type |
string | COLUMN_TYPE_FIELD |
见下表 |
width |
string | — | 列宽 |
orderno |
int | — | 顺序 |
labelScript / label |
CDATA / string | — | 动态/静态标签 |
multiLanguageLabel |
string | — | 多语言 |
visible |
boolean | true | 视图可见 |
visible4ExpExcel |
boolean | true | Excel |
visible4Print / visible4PagePrint |
boolean | true | 打印 |
hiddenScript |
CDATA | — | true=隐藏 |
hiddenColumn |
boolean | false | 静态隐藏 |
formatType |
string | simple |
simple/number/currency |
displayType / displayLength |
string | 00 / -1 |
截断 |
sum / total |
boolean | — | 小计/总计 |
clickSorting |
boolean | true | 点表头排序 |
showAsLabel / showAsButton / showIcon |
boolean | — | 展示形态 |
mappingField |
string | — | 类型角色 |
type(原样写入文本)¶
| type | 含义 | 额外元素 |
|---|---|---|
COLUMN_TYPE_FIELD |
字段 | formid、fieldName、showType、isOrderByField、orderType、sortStandard、mappingField |
COLUMN_TYPE_SCRIPT |
脚本(计算输出) | valueScript;可返回纯文本或 HTML 片段(平台按 HTML 渲染) |
COLUMN_TYPE_OPERATE |
行内按钮 | buttonType、buttonName、actionScript/beforeScript/afterScript、templateForm、跳转相关 |
COLUMN_TYPE_LOGO |
图标 | 图标相关 |
COLUMN_TYPE_ROWNUM |
序号 | — |
硬规则:状态类列 → 脚本列 + HTML tag¶
凡列语义为**状态 / 签收状态 / 启用停用 / 所在库 / 复审结论 / 批次状态 / 来源类型**等枚举展示(列名常含「状态」「库」「结论」「来源」,或字段名 status / *Status / library / originType / enabled / conclusion),**禁止**用 COLUMN_TYPE_FIELD 纯文本展示;必须:
type=COLUMN_TYPE_SCRIPTvalueScript计算输出 HTML 片段,用 Element Plusel-tag做 tag 样式(门户已加载,勿只写裸文字或过时的<font>)- 按业务值映射
el-tag--success|warning|danger|info|primary;未知值用info - 推荐加
el-tag--light el-tag--small;空值返回-(纯文本即可) - 库存英文码时,tag 内文本须映射为中文(与表单「存英文、显中文」一致);禁止把
DRAFT/INTERNAL原文塞进 tag 当最终展示(除非业务明确要求显码) - 批量落盘优先
view_template_builder.render_status_column_xml/status_columns=(可传label_map) - **映射表**上的状态列:取值须兼容表单字段名与物理列名(见下节);字段名大写碰巧等于列名(
status→STATUS)时能显示,**不要**据此把其它列写成 FIELD。
色义约定(可按业务微调,但同一应用内保持一致):
| 语义倾向 | el-tag 修饰 |
示例值(库存码 / 显示) |
|---|---|---|
| 成功/生效/通过/已签收/启用 | --success |
EFFECTIVE→已生效、Y→是 |
| 进行中/待处理/草稿 | --warning |
DRAFT→草稿、REVIEWING→审批中 |
| 失败/作废/驳回/停用 | --danger |
OBSOLETE→已作废、N→否 |
| 中性/归档/其它 | --info |
ARCHIVED→已归档 |
| 强调进行中 | --primary |
进行中、借阅中 |
硬规则:映射表列表列(type=65536 → MD_* / 手工业务表)¶
现象: 列表若干列空白;双击行打开表单字段有值。status 等「字段名大写 = 物理列名」的列可能仍有字。
规则: relatedForm 为映射表单时,普通展示列必须 COLUMN_TYPE_SCRIPT,禁止 COLUMN_TYPE_FIELD。valueScript 用 IIFE,先读表单字段名,空则读 mappingStr.columnMappings 的物理列名。列上下文用裸 getItemValueAsString(勿依赖 getCurrentDocument)。
(function(){
var v = getItemValueAsString("deptCode");
if (v == null || v === "") v = getItemValueAsString("DEPT_CODE");
return v == null ? "" : v;
})();
批量:write_view_bundle(..., mapping_columns=True)(render_mapping_text_column_xml)。改已有列时**保留列 id**(viewdialog mapping 键是列 id)。
状态类列仍走上一节 el-tag;取值同样双读,例如 empStatus 再读 EMP_STATUS。
事务表(type=1,TLK_* / ITEM_)列表继续用 FIELD。
| 借口 | 实际 |
|---|---|
| 「状态列有字,所以 FIELD 没问题」 | status.toUpperCase() 碰巧等于列 STATUS;deptCode 查找 DEPTCODE,对不上 DEPT_CODE |
| 「表单有值,是库没数据 / 列 fieldName 写错」 | 打开表单会先绑 formid 再hydrate,mapping 生效;列表查询不带表单 id |
| 「给映射表加 FORMID,或改 relatedForm/displayType」 | 工作区用脚本列即可;不要为修列表改库结构或平台 Java(除非用户明确要求) |
FIELD 专用¶
| 元素 | 取值 | 说明 |
|---|---|---|
formid |
表单 id | 全小写标签 |
fieldName |
字段 name | 事务表 → ITEM_{FIELDNAME};映射表禁止靠 FIELD 取数(Item 名是物理列,见上节) |
showType |
00 真实值 / 01 显示值 |
|
isOrderByField |
string | 默认排序列 |
orderType / sortStandard |
— | 升降 / 库默认 |
mappingField |
见下 |
mappingField¶
| 视图 | 值 | 含义 |
|---|---|---|
| 日历 | CldViewDateColum |
过滤日期(拼写 Colum) |
| 树 | superior_Node / current_Node / name_Node |
父/编号/名称 |
| 地图 | titlecolumn / addresscolumn / detailcolumn |
标题/地址/内容 |
| 甘特 | name / start / end / complete / color / parent |
任务 |
OPERATE buttonType¶
| 值 | 含义 |
|---|---|
00 |
删除 |
01 |
提交流程 |
03 |
模板表单打开(templateForm) |
04 |
脚本 |
05 |
跳转 |
字段列示例¶
文件:LeaveList.view/标题.column
<?xml version="1.0" encoding="UTF-8"?>
<column id="col-title">
<name>标题</name>
<parentId>view-uuid</parentId>
<applicationid>app-uuid</applicationid>
<parentView>view-uuid</parentView>
<type>COLUMN_TYPE_FIELD</type>
<formid>form-uuid</formid>
<fieldName>title</fieldName>
<showType>01</showType>
<width>150</width>
<formatType>simple</formatType>
<visible>true</visible>
<visible4ExpExcel>true</visible4ExpExcel>
<visible4Print>true</visible4Print>
<hiddenScript><![CDATA[]]></hiddenScript>
<isOrderByField>false</isOrderByField>
<mappingField></mappingField>
<orderno>1</orderno>
</column>
日历日期映射列¶
<?xml version="1.0" encoding="UTF-8"?>
<column id="col-date">
<name>开始日期</name>
<parentId>view-cal-uuid</parentId>
<applicationid>app-uuid</applicationid>
<parentView>view-cal-uuid</parentView>
<type>COLUMN_TYPE_FIELD</type>
<formid>form-uuid</formid>
<fieldName>startDate</fieldName>
<mappingField>CldViewDateColum</mappingField>
<showType>01</showType>
<orderno>1</orderno>
</column>
树三列(三个文件)¶
<!-- 父节点.column -->
<column id="col-sup">
<name>父节点</name>
<parentId>view-tree-uuid</parentId>
<applicationid>app-uuid</applicationid>
<parentView>view-tree-uuid</parentView>
<type>COLUMN_TYPE_FIELD</type>
<formid>form-uuid</formid>
<fieldName>parentCode</fieldName>
<mappingField>superior_Node</mappingField>
<showType>01</showType>
<orderno>1</orderno>
</column>
<!-- 节点编号.column -->
<column id="col-cur">
<name>节点编号</name>
<parentId>view-tree-uuid</parentId>
<applicationid>app-uuid</applicationid>
<parentView>view-tree-uuid</parentView>
<type>COLUMN_TYPE_FIELD</type>
<formid>form-uuid</formid>
<fieldName>code</fieldName>
<mappingField>current_Node</mappingField>
<showType>01</showType>
<orderno>2</orderno>
</column>
<!-- 节点名称.column -->
<column id="col-name">
<name>节点名称</name>
<parentId>view-tree-uuid</parentId>
<applicationid>app-uuid</applicationid>
<parentView>view-tree-uuid</parentView>
<type>COLUMN_TYPE_FIELD</type>
<formid>form-uuid</formid>
<fieldName>nodeName</fieldName>
<mappingField>name_Node</mappingField>
<showType>01</showType>
<orderno>3</orderno>
</column>
脚本列(普通计算)¶
非状态展示、只需拼接/换算文本时,valueScript 返回纯字符串即可:
<?xml version="1.0" encoding="UTF-8"?>
<column id="col-script">
<name>全名</name>
<parentId>view-uuid</parentId>
<applicationid>app-uuid</applicationid>
<parentView>view-uuid</parentView>
<type>COLUMN_TYPE_SCRIPT</type>
<valueScript><![CDATA[(function(){
var v = getCurrentDocument().getItemValueAsString("name");
return (v == null || v === "") ? "-" : v;
})()]]></valueScript>
<width>100</width>
<orderno>2</orderno>
</column>
状态类脚本列(HTML tag · 推荐照抄)¶
文件:DocList.view/状态.column(**不要**再写同名字段的 COLUMN_TYPE_FIELD 状态列)
<?xml version="1.0" encoding="UTF-8"?>
<column id="col-status">
<name>状态</name>
<parentId>view-uuid</parentId>
<applicationid>app-uuid</applicationid>
<parentView>view-uuid</parentView>
<type>COLUMN_TYPE_SCRIPT</type>
<formid>form-uuid</formid>
<fieldName>status</fieldName>
<valueScript><![CDATA[(function(){
var v = getItemValueAsString("status");
if (v == null || v === "") return "-";
var tone = "info";
if (v === "生效" || v === "已完成" || v === "已签收" || v === "Y" || v === "启用") tone = "success";
else if (v === "草稿" || v === "审批中" || v === "待签收" || v === "待审批") tone = "warning";
else if (v === "作废" || v === "驳回" || v === "停用" || v === "N") tone = "danger";
else if (v === "进行中" || v === "借阅中") tone = "primary";
return "<span class=\"el-tag el-tag--" + tone + " el-tag--light el-tag--small\">" + v + "</span>";
})();]]></valueScript>
<width>100</width>
<formatType>simple</formatType>
<visible>true</visible>
<visible4ExpExcel>true</visible4ExpExcel>
<visible4Print>true</visible4Print>
<orderno>2</orderno>
</column>
说明:
- 字段名按表单改(如
receiptStatus、library);映射表按业务枚举补全 - 视图列值脚本用裸
getItemValueAsString;列 XML 建议带齐 afterservice 式完整壳(hiddenScript/showAsLabel等) - 批量改盘后须
rebuild-index+clear_cache,否则运行时可能仍按空脚本渲染(状态格空白) - 存库编码(如
CONTROLLED/Y)**须在脚本内映射为中文**再写入 tag 文本(与表单「库存英文、界面中文」一致) - Excel 导出可能带 HTML;若业务忌讳,可对该列
visible4ExpExcel=false
hiddenScript:返回 true 隐藏、false 显示。
3. 操作属性 → .activity XML¶
与表单 Activity 同模型。路径:{视图名}.view/{操作名}.activity。根:<activity id="...">(id 是根属性,**不要**写子元素 <id>)。type 为整数。
必写关联三件套:<parentId> = 视图 id、<applicationid> = 应用 id、<parentView> = 视图 id。pid.index 只按 <parentId> 建父子关系 —— 漏写 <parentId> → 操作不挂到视图、工具栏按钮不显示。
通用元素¶
| 元素 | 类型 | 说明 |
|---|---|---|
id |
根属性 | __ + 短 UUID;<activity id="..."> |
name |
string | 必填 |
applicationid |
string | = 应用 id(必写) |
parentId |
string | = 视图 id(pid.index 父子关系只认此字段;必写) |
label |
CDATA | 名称标签脚本 |
multiLanguageLabel |
string | 多语言 |
type |
int | **必填**动作类型 |
parentView |
string | = 视图 id(与 parentId 同值) |
icontype |
string | img / font / 空 |
icon / iconurl / fontUrl |
string | 图标 |
colorType |
string | 颜色 |
beforeActionScript |
CDATA | 执行前;有返回串则中断默认动作 |
afterActionScript |
CDATA | 执行后 |
readonlyScript |
CDATA | true=只读 |
hiddenScript |
CDATA | true=隐藏 |
orderno |
int | 排序 |
onActionForm |
string | 作用表单(创建/清空) |
onActionView |
string | 作用视图(载入) |
impmappingconfigid |
string | 导入 Excel 映射 |
视图常用 type¶
| type | 含义 | 额外元素 |
|---|---|---|
2 |
创建 | onActionForm |
3 |
删除 | — |
34 |
保存 | 网格 openType=288、Sheet 建议必配 |
18 |
清空所有数据 | onActionForm |
1 |
查询 | — |
20 |
批量提交 | — |
16 |
导出 Excel | — |
27 |
导入 Excel | 映射配置 id |
26 |
文件下载 | fileNameScript |
36 |
网页打印 | — |
39 |
载入视图 | onActionView |
43 |
跳转 | jumpMode、dispatcherUrl、jumpActOpenType 等 |
29 |
批量签章 | — |
创建¶
文件:LeaveList.view/新建.activity
<?xml version="1.0" encoding="UTF-8"?>
<activity id="act-create">
<name>新建</name>
<applicationid>app-uuid</applicationid>
<parentId>view-uuid</parentId>
<type>2</type>
<parentView>view-uuid</parentView>
<onActionForm>form-uuid</onActionForm>
<icontype>font</icontype>
<fontUrl>fa fa-plus</fontUrl>
<beforeActionScript><![CDATA[]]></beforeActionScript>
<afterActionScript><![CDATA[]]></afterActionScript>
<readonlyScript><![CDATA[]]></readonlyScript>
<hiddenScript><![CDATA[]]></hiddenScript>
<orderno>1</orderno>
</activity>
删除¶
<?xml version="1.0" encoding="UTF-8"?>
<activity id="act-delete">
<name>删除</name>
<applicationid>app-uuid</applicationid>
<parentId>view-uuid</parentId>
<type>3</type>
<parentView>view-uuid</parentView>
<beforeActionScript><![CDATA[]]></beforeActionScript>
<afterActionScript><![CDATA[]]></afterActionScript>
<readonlyScript><![CDATA[]]></readonlyScript>
<hiddenScript><![CDATA[]]></hiddenScript>
<orderno>2</orderno>
</activity>
网格/Sheet 保存¶
<?xml version="1.0" encoding="UTF-8"?>
<activity id="act-save">
<name>保存</name>
<applicationid>app-uuid</applicationid>
<parentId>view-uuid</parentId>
<type>34</type>
<parentView>view-uuid</parentView>
<orderno>3</orderno>
</activity>
导出 Excel¶
<?xml version="1.0" encoding="UTF-8"?>
<activity id="act-export">
<name>导出Excel</name>
<applicationid>app-uuid</applicationid>
<parentId>view-uuid</parentId>
<type>16</type>
<parentView>view-uuid</parentView>
<orderno>4</orderno>
</activity>
只读视图运行时会去掉创建/删除/导入等写操作。
4. 脚本库 scripts/view_template_builder.py¶
Agent 批量或程序化**生成多个 ListView 时,**优先 import 本库,勿手写简化版 XML 或裸 SQL 过滤。
路径(相对 workspace 根):
用法¶
import sys
from pathlib import Path
WORKSPACE = Path("<workspace-root>")
sys.path.insert(0, str(WORKSPACE / ".cursor" / "skills" / "generate-view-file" / "scripts"))
import view_template_builder as vtb
vtb.write_view_bundle(
Path("MyApp.application/module/mod.module/document_valid.view"),
view_id="__View_document_valid",
view_name="document_valid",
module_id="__ModuleId",
application_id="__AppId",
form_id="__Form_document_form",
columns=[("文件编号", "doc_no", 140), ("文件名称", "doc_name", 220)],
status_columns=[("状态", "status", 100)], # → COLUMN_TYPE_SCRIPT + el-tag HTML
filter_key="doc_status",
filter_presets={"doc_status": ("doc_status", "有效")},
acts="ro",
column_id_prefix="__Col_",
activity_id_prefix="__VAct_",
)
应用内薄脚本(如 {app}.application/_gen_views.py)只保留:模块/应用 id、视图规格表、filter_presets、main();通用落盘逻辑 import 本库。
API 摘要¶
| 类别 | 函数 |
|---|---|
| 过滤 | eq_filter_entry(field, value)、filter_condition_cdata(key, presets=...) |
| XML | render_listview_xml(...)、render_column_xml(...)、render_mapping_text_column_xml(...)、render_status_column_xml(...)、render_view_activity_xml(...) |
| 脚本 | status_tag_value_script(field_name, tone_map=None, label_map=None) → 状态列 valueScript(label_map 码→中文);mapping_text_value_script(field_name, db_column=None) |
| 落盘 | write_view_bundle(..., columns=..., status_columns=..., mapping_columns=False);映射表视图 mapping_columns=True;status_columns 项为 (标题, 字段名, 宽) / (…, tone_map) / (…, tone_map, label_map) |
| acts | "crud" / "crud_no_del" / "select" / "ro" |
批量生成收尾¶
- 运行应用内
_gen_views.py落盘全部.view/.column/.activity rebuild-index+verify-workspace
参考实现:iso_doc.application/_gen_views.py(iso_doc 视图规格 + import 本库)。
5. 正确性检查清单¶
- [ ] 直接写 XML 文件;根标签与类型一致(ListView/CalendarView/…)
- [ ] id 统一 `__` + 短 UUID;写在根元素属性上:<ListView id> / <column id> / <activity id>(不要子元素 <id>)
- [ ] name 非空;路径模块下 {name}.view;列/操作在该目录下独立文件
- [ ] 列与操作都带:<parentId>=视图 id、<applicationid>=应用 id、<parentView>=视图 id(三者齐;pid.index 只认 parentId)
- [ ] editMode:00 必填 relatedForm;01/02/03 填对应 *Script(CDATA,返回字符串);**04 填 `scriptDataFilterScript`(返回行数据 JSON,自行分页)**
- [ ] editMode=04:`items[].columnName` = 列 `name`;`displayType` 勿用 `relatedForm`;树/总计等能力不保证
- [ ] editMode=00:`filterCondition`/`commonFilterCondition` 必须是 JSON 数组(无条件写 `[]`);禁止写 `ITEM_xxx = '…'` 裸 SQL(会 JSONArray 解析失败)
- [ ] Column 用 <formid>(小写);type 写 COLUMN_TYPE_* 全文
- [ ] **状态类列**用 `COLUMN_TYPE_SCRIPT` + `valueScript` 返回 `el-tag` HTML;禁止 FIELD 纯文本凑合
- [ ] **映射表视图**(relatedForm type=65536):普通列 `COLUMN_TYPE_SCRIPT` 双读字段名/物理列;禁止 FIELD;改列保留 id;批量 `mapping_columns=True`
- [ ] **选择用视图**:须含业务编码列(`code` 等)供 viewdialog mapping;**勿**默认以隐藏 ID 脚本列(`doc.getId()`)作为唯一回写业务键(见 plan-application「业务引用键」)
- [ ] 日历 mappingField=CldViewDateColum;树三字段;甘特 name/start/end/complete
- [ ] 折叠 pagination=false;首列路径用 \
- [ ] 网格 = ListView + openType=288 + activity type=34;Sheet 也建议 type=34
- [ ] searchFormId 指向查询表单,不是 relatedForm
- [ ] expandQueryForm **默认 false**(展开查询表单=否);仅当业务要求默认展开时显式 true
- [ ] 创建/删除 activity type=2/3;脚本用 CDATA
- [ ] 业务表 TLK_{表单名};列 ITEM_{字段};系统字段无 ITEM_
- [ ] 落盘后跑 rebuild-index:视图/列/操作都进 url.index,且 pid.index 里列、操作均挂在视图 id 下
最低可运行列表视图配方(三文件起)¶
LeaveList.view:根<ListView id="...">,editMode=00,relatedForm,openType=1LeaveList.view/标题.column:<column id="...">+parentId/applicationid/parentView=视图 id +COLUMN_TYPE_FIELD+formid+fieldNameLeaveList.view/新建.activity(type=2)+LeaveList.view/删除.activity(type=3),均带parentId/applicationid/parentView=视图 id
常见错误¶
| 现象 | 原因 | 处理 |
|---|---|---|
列/操作在 pid.index 里成孤儿、工具栏按钮不出现 |
只写了 <parentView>,缺 <parentId> |
补 <parentId> = 视图 id(并加 <applicationid>),重建索引 |
视图/列/操作没进 url.index |
id 写成了子元素 <id> |
改为根属性 <column id="..."> 等,重建索引 |
ClassCastException / 打开空白 |
列 formid/fieldName 与表单不符;或 relatedForm 填错 |
核对为 .form 根 id 与字段 name |
| 树/日历/甘特列不生效 | 缺 mappingField 角色 |
按 §mappingField 表补齐 |
A JSONArray text must start with '[' … ITEM_xxx = '…' |
editMode=00 的 filterCondition 写成了 SQL/DQL 串 |
改为 JSON 数组(type=00 固定值或 type=03 绑查询字段);无过滤写 []。SQL 过滤改用 editMode=02 + sqlFilterScript |
脚本数据视图空白 / scriptDataFilterScript is blank |
未写 scriptDataFilterScript,或 editMode 不是 04 |
设 editMode=04 + 非空 scriptDataFilterScript |
| 映射表列表多列空白、双击表单有值;仅状态列有字 | 列表 Item 名是物理列(DEPT_CODE),FIELD 按表单字段(deptCode→DEPTCODE)取 |
普通列改 SCRIPT 双读;状态列取值也双读;保留列 id |
| 分页总数错 / 每页重复 | 脚本未按 _currpage/lines 切片却写了错误 row_count |
脚本自行分页:data=当前页,row_count=总数 |