关于 convert-ui5-to-fiori-elements
此工作流技能从旧版 UI5 JavaScript 应用提取界面特征,生成 Fiori Elements V4 注解及列表报表和对象页。适用于迁移到注解驱动界面的场景,并可用扩展实现模板无法表达的行为。
主要功能
- 01从旧应用特征推导 UI 注解
- 02将注解应用于 RAP 投影
- 03生成列表报表和对象页
- 04用扩展实现自定义行为
- 05查询 SAP 注解参考资料
适用场景
- 01将旧版 UI5 应用重建为 Fiori Elements V4
- 02复现旧界面的列、搜索、排序和操作
MCP 相关
该技能使用 SAP Fiori MCP server 生成 Fiori Elements 项目,并介绍使用 sap-docs MCP 查询注解模式。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ arc-mcp/ arc-1 --skill convert-ui5-to-fiori-elements安装后在 Claude Code 中输入/convert-ui5-to-fiori-elements确认已加载。
详细介绍
将旧版 UI5 JS 应用转换为 Fiori Elements V4(注解优先)
生成一个由 RAP CDS 投影上的 @UI.* 注解驱动的 Fiori Elements V4 列表报表 + 对象页面应用。后端注解根据旧版 UI5 应用的实际功能(列、搜索、排序、格式化程序、操作按钮、标签页结构)生成,使 FE 应用复现用户可见的功能约定。FE 模板无法表达的自定义行为通过扩展 API 接入。
此技能是 RAP 后端就绪后两条并行 UI 路径中的一条。如果目标架构是 Fiori Elements V4(注解驱动;自定义代码最少),请选择此路径。如果目标架构是自由式 TypeScript(自定义控制器、手动绑定),请改用 modernize-ui5-app.md。两条路径都从同一个旧版 JS 应用和同一个 V4 RAP 服务开始。
migrate-segw-to-rap.md (backend: SEGW V2 → RAP V4)
│
┌─────────────┴─────────────┐
▼ ▼
modernize-ui5-app.md convert-ui5-to-fiori-elements.md
(freestyle TS) (Fiori Elements V4)
此技能依赖于:
migrate-segw-to-rap.md已生成一个可用的 V4 RAP 服务(CDS 根视图和投影、BDEF、SRVD、SRVB 已发布,且已在/n/IWFND/MAINT_SERVICE中注册 V4 路由组)。- 旧版应用(
<source_app>/)仍可读取——第 1 阶段会梳理其功能,但不会修改旧版应用本身。
独立于
modernize-ui5-app.md。 此技能不要求现代 TS 应用已经存在。旧版应用是用户可见功能的唯一事实来源;FE 应用通过注解和扩展直接复现这些功能。
领域示例。 注解模板使用示例领域
Project → Tasks → TimeEntries。请在各处替换为用户的实体——LLM 会重写每个投影、实体和字段标识符,使其与 V4 服务相符。
规范注解参考。 此技能将 ABAP RAP Fiori Feature Showcase(
SAP-samples/abap-platform-fiori-feature-showcase)作为@UI.*、@ObjectModel.*和@Common.*注解模式的权威来源。当不确定如何将旧版 UI 功能表示为注解时,请使用该功能的搜索词(例如#OPHeaderAction、#LineItemHighlight、#HeaderInfo、#ActionInLineItem)通过mcp__sap-docs__search搜索 showcase。showcase 是本技能中每个注解所对应的权威目录。
使用 mcp__sap-docs__search 查找注解(请先阅读)
此技能在文中列出了一些规范注解模式。请将其视为起点,而非完整目录。 对于未明确涵盖的内容——其他可视化表示、动态功能控制、图表、值帮助、语义键、多级 OP 路由、草稿专属 UI 行为,或 7.58 特定语法问题——请先通过 mcp__sap-docs__search 查询,再做判断。该 MCP 会索引 SAP 维护的权威参考资料,提供最新的 showcase 标签,并包含特定版本的文档(758 新功能、云端差异等);本技能文本无法自行保持这些内容的时效性。
值得了解的标准库
| 库 ID | 内容 |
|---|---|
/abap-fiori-showcase | SAP-samples/abap-platform-fiori-feature-showcase — 本地部署的 RAP + FE V4 目录。每种模式都带有一个 Search Term 标签,例如 #HeaderInfo、#LineItemHighlight、#OPHeaderAction、#OPTable、#DataFieldForAction、#SemanticKey。这是此技能以 7.58 为准的基线。 |
/cap-fiori-showcase | SAP-samples/fiori-elements-feature-showcase — CAP/CDS V4 对应目录。包含 CAP 侧的相同概念模式;当 ABAP 展示库标签未包含所需变体时很有用,尤其是 FE 清单布局(layouts_ChildEntities*.cds、#Subpages、#InboundNav)。 |
/abap-docs-standard | 官方 ABAP 关键字文档(本地部署)。是语法(FOR BEHAVIOR OF、虚拟元素、投影 BDEF 规则)、特定版本功能(ABENNEWS-758-RESTFUL,用于确认 7.58 提供的功能)以及 RAP 构造深层理论的权威资料。 |
/abap-docs-cloud | 云/BTP 版的同类文档。遇到看似仅适用于云的内容时很有用 — 在用于本地部署的 7.58 之前,请先核实。 |
/sap-help(在线) | SAP Help 全部内容。最适用于 SAPUI5 清单配置、FE 模板运行时细节和 配置内部导航。需要 includeOnline=true。 |
/abap-cheat-sheets | 包含当前语法变体的实用 RAP / ABAP 代码片段。 |
搜索方法 — 每个注解问题都按此操作
- 确认用户看到的内容:“带颜色标记的状态”、“点击行 → 子级详情页”、“使用固定值筛选”。
- 按主题标签搜索展示库 — 大多数模式都在 Markdown 中使用字面标签:
mcp__sap-docs__search(query="#TagName") // exact tag lookup mcp__sap-docs__search(query="<visual description>") // semantic fallback - 获取最相关结果的完整模式:
mcp__sap-docs__fetch(id="/abap-fiori-showcase/<section>#<tag>") - 适配用户的实体 — 展示库使用
/DMO/FSA_R_RootTP等;请替换为用户的投影名称。 - 如果目标版本不接受本地部署模式,请换个方向重新搜索:
- 搜索
/abap-docs-standard/ABENCDS_PROJ_VIEW_VIRTUAL_ELEMENT(以及示例ABENCDS_PROJ_VIEW_VIRTEL_ABEXA),查找通过 ABAP 类计算的虚拟元素 - 搜索
/abap-docs-standard/ABENNEWS-<release>-RESTFUL,查找特定版本的功能(例如ABENNEWS-758-RESTFUL) - 搜索
/cap-fiori-showcase,查找相同概念的 CAP 替代表述 - 如果 DDLS 投影不接受实体级注解,可将 DDLX
annotate view作为后备方案(Run 7 证据:7.58 通过 DDLX 处理@UI.facet、@UI.selectionFields和标头FOR_ACTION)
- 搜索
入门标签指引(非穷尽,欢迎继续搜索)
可解析到展示示例中具体注解模式的搜索词参考。每项都是入口;请获取完整内容,以了解适用于你所用版本的规范语法。
| 需求 | 起始搜索词 / 文档 |
|---|---|
| 列表行上的彩色状态 / 关键性 | #LineItemHighlight、criticality: 'CriticalityCode'、@UI.Criticality |
| 带计算逻辑的关键性(非真实列) | /abap-docs-standard/ABENCDS_PROJ_VIEW_VIRTUAL_ELEMENT;示例 ABENCDS_PROJ_VIEW_VIRTEL_ABEXA。另见 @ObjectModel.virtualElementCalculatedBy: 'ABAP:<class>' |
| 标题数据点 / 状态指示器 | #HeaderFacet、#KeyValue、#DataPointProgress、@UI.dataPoint |
| 子实体的对象页表格 | #OPTable、子投影上的 @UI.lineItem、含 type: #LINEITEM_REFERENCE 和 targetElement: '_AssocName' 的 @UI.facet |
| 从一个对象页跳转到另一个对象页(例如 Project → Task → TimeEntry) | #OPTable(入口);cap-fiori-showcase/app/listreport-objectpage/layouts_ChildEntities1.cds 等(子页面布局);SAPUI5 “Configuring Internal Navigation”(sap-help),了解清单路由结构 |
| 分面之间的页内导航 | #InboundNav、targetSections、@UI.facet 上的 navigation 属性 |
| 操作按钮 — 对象页标题 | #OPHeaderAction、type: #FOR_ACTION、DataFieldForAction |
| 操作按钮 — 列表报告表格工具栏 | #ActionInLineItem、#WithAction |
| 排序 + 筛选栏 | #SelectionFields、#PresentationVariant、@UI.selectionFields |
| 跨字段搜索 | #Search、@Search.searchable、@Search.defaultSearchElement |
| 语义键(在表格中突出显示 / 加粗) | #SemanticKey、@ObjectModel.semanticKey |
| 值帮助 / 固定值列表 | #ValueHelp、@Consumption.valueHelpDefault、@ObjectModel.text.element |
| 动态 CRUD(按行状态隐藏 / 显示编辑 / 删除) | #DynamicCRUD、@UI.updateHidden、@UI.deleteHidden、BDEF features: instance |
| 草稿 + UI 细节 | #DraftHandling、@UI.lineItem 可编辑限定符、操作关键字 ( precheck ) |
| 副作用 / 操作后重新读取 | #SideEffects、@Common.SideEffects |
| BDEF 操作签名变体(预检查、工厂、复制) | /abap-docs-standard/ABENBDL_ACTION、#OPCopyAction、action ( precheck ) <name> |
| 7.58 功能边界 | /abap-docs-standard/ABENNEWS-758-RESTFUL + ABENNEWS-758-CDS_BDL |
反模式
- 不要把本技能中的示例代码奉为圭臬。 这只是一个特定时期编写的教学示例。展示示例才是事实依据。
- 未经验证,不要直接套用其他版本的展示示例。 来自 BTP-Cloud 分支的
#DataFieldForAction示例可能会使用仅适用于云端的关键字;对于 7.58,on-premmain分支是安全的基准。 - 查阅 SAPUI5 内部导航文档之前,不要手动编写 FE 路由 / 清单条目。 结构因模板和版本而异;从
sap-help推导比根据运行时故障反向推理更容易。 - 不要把首次激活失败的症状当作最终答案。 第 7 次运行中,一个润色项在四个不同层面遇到了四种不同的阻碍;每次只要再通过
mcp__sap-docs__search搜索一次,就能在回滚之前找到替代方案。多搜一次只需 5 秒;不必要的回滚则要耗费 10 分钟以上。
为什么它是一项独立技能
Fiori Elements 并不是代码转换,而是删除 + 迁移。大部分自由样式应用都会被 FE 模板取代,这些模板会解析 CDS 注解。这项技能实际有三项工作:
- 根据旧版应用中用户可见的功能,推导出合适的
@UI.*注解,让 FE 呈现等效的用户体验。 - 将这些注解应用到 RAP CDS 投影中(即 SRVB 暴露的服务)。
- 通过 SAP Fiori MCP 服务
(
@sap-ux/fiori-mcp-server)生成 FE 列表报表 + 对象页项目,并为 FE 模板无法表达的内容接入扩展。
智能默认值(静默应用——研究前不要询问)
| 设置 | 默认值 | 原因 |
|---|---|---|
| 旧版应用 | <source_app>/ | 自由样式 JS 应用——只读;在阶段 1 中用于提取功能清单。它是 FE 应用必须复现的所有用户可见行为的权威来源。 |
| 目标 FE 应用 | <fe_app>/——如果用户未提供路径,默认名称为 modern-fe-app/(遵循工作区模式 legacy-ui5-app/ → modern-ui5-app/ → modern-fe-app/) | Fiori MCP 会在此处生成项目;该文件夹必须存在且为空(或仅包含空子文件夹) |
| FE 页面布局 | 当 BO 具有明确的根节点和子节点分面时,使用列表报表 + 对象页(LROP V4) | 与典型的 RAP 组合根节点 + 子节点映射清晰。仅在用户明确要求时使用 OVP。 |
| 模板 | lropv4 | 默认值,除非用户另有要求 |
| 生成器 | 通过 list_functionalities → get_functionality_details → execute_functionality 调用 SAP Fiori MCP 服务(@sap-ux/fiori-mcp-server) | SAP 官方工具;原生支持 FE V4 模式 |
| 应用命名空间 | <source_namespace>.fe | 便于区分旧版应用与 FE 应用(如果也运行了 modernize-ui5-app 作为替代路径,也能区分现代 TS 应用) |
| UI5 版本 | 最新的 1.x 版本(例如 1.147.2),除非用户另行指定 | LTS 轨道;可用最新的 FE V4 功能 |
| 语言 | TypeScript | 现代默认选项;扩展文件使用类型安全的 API |
| OData V4 服务 URL | 优先使用系统 HTTPS 端口上的 SRVD 直连路径:https://<host>:<https-port>/sap/opu/odata4/sap/<srvb>/srvd/sap/<srvb>/0001(例如 https://a4h.marianzeis.de:50001/sap/opu/odata4/sap/zui_dm_projects_o4/srvd/sap/zui_dm_projects_o4/0001)。仅当 SRVD 直连不可达时,才回退到 Gateway 中心路径 http://<host>:<http-port>/sap/opu/odata4/sap/<srvb>/srvd_a2x/sap/<service>/0001。 | 第 5 次和第 6 次运行已验证,在 7.5x 系统上,SRVD 直连路径无需通过 /n/IWFND/MAINT_SERVICE 注册即可工作。中心路径需要手动设置路由组。 |
| 主实体 | SRVB 暴露的根实体别名(例如 define root view entity ... alias <X> 中的别名) | LR+OP 页面布局以单个实体为根 |
| 注解位置 | 通过 SAPWrite update DDLS 在 CDS 中定义——不要放在 FE 应用的本地注解文件中 | 注解属于服务;FE 应用通过 $metadata 读取注解。本地注解文件不适用于绑定 RAP 的应用。 |
| 扩展语言 | TypeScript(控制器扩展) | 与链路的其余部分保持一致 |
| 验证 | mcp__SAPUI5_MCP_Server__run_ui5_linter + run_manifest_validation + tsc --noEmit 全部通过 | 硬性验收标准 |
| 验收标准 | FE 应用能够端到端地对接 V4 服务并运行。浏览器冒烟测试覆盖阶段 1 中清点的每项功能——通过注解或扩展钩子复现。 | 明确的交付成果 |
输入
用户提供:
- 用于挖掘功能的旧版应用路径(默认:
<source_app>/)。只读。 - FE 应用的路径 / 名称(默认:
<fe_app>/)。 - OData V4 服务 URL——从
migrate-segw-to-rap的 SRVB 输出中获取。必填。 - 根实体别名(例如:
Project)。默认:从 SRVB 的$metadata推断。 - 应用命名空间(默认:
<source_namespace>.fe)。 - 传输,用于写入 CDS 注解(默认:与
migrate-segw-to-rap使用相同的传输,或通过SAPTransport(action="create")自动创建)。 - UI5 版本(默认:最新的 1.x)。
如果只提供旧版应用路径和 V4 URL,则应用智能默认值,并在第 3 阶段向用户展示计划,等待用户确认 ok 后再进行任何写入。
阶段 0 — 预检
0a. RAP V4 服务处于运行状态且可绑定
SAPManage(action="probe")
断言 rap.available == true。
SAPRead(type="SRVB", name="<V4_SRVB>")
断言 SRVB 存在且处于激活状态。否则,停止并提示 "V4 服务绑定 <V4_SRVB> 缺失或未激活——请先运行 migrate-segw-to-rap.md。"
Bash: curl -s -o /tmp/svc_metadata.xml -w "%{http_code}\n" "<V4_service_URL>/\$metadata?sap-client=<client>"
断言返回 200 OK。先尝试 SRVD 直连路径(HTTPS 端口 + /srvd/sap/<srvb>/0001/)。
如果返回 403,且错误为 IWBEP/CM_V4_COS/136,则说明 URL 使用的是 Gateway 集线器路径,且路由组尚未注册。停止前切换到 SRVD 直连 URL 格式——直连路径可绕过集线器注册。只有两种 URL 格式都失败时,才回退到 "通过 /n/IWFND/MAINT_SERVICE 注册服务组"。
如果返回 503,且错误为 IWBEP/CM_V4_RUNTIME/000("服务别名缓存已过期"),则重试一次——这是暂时的 Gateway 缓存问题。如果重试后仍然存在,则按 403 处理并切换 URL 格式。
0b. CDS 投影可读写
SAPRead(type="DDLS", name="<root_projection>")
断言返回活动版本。否则,停止并提示 "缺少根投影——请重新运行 migrate-segw-to-rap.md 阶段 6 步骤 3。"
0c. 旧版应用存在且可读
Bash: ls <source_app>/webapp/controller/ <source_app>/webapp/view/
断言两个文件夹均已填充内容。如果任一文件夹缺失,则说明具体原因并停止——旧版应用是注解计划(阶段 1 + 2)和扩展列表(阶段 2b)的唯一事实来源。
0d. SAP Fiori MCP 服务可访问
mcp__fiori-mcp__list_functionalities
如果此调用失败,说明此聊天中未配置 Fiori MCP 服务。展示配置代码块并停止:
// .cursor/mcp.json (or equivalent)
{
"mcpServers": {
"fiori-mcp": {
"type": "stdio",
"timeout": 600,
"command": "npx",
"args": ["--yes", "@sap-ux/fiori-mcp-server@latest", "fiori-mcp"]
}
}
}
(来源:GitHub 上 @sap-ux/fiori-mcp-server 的 README。)
可选配套服务:用于生成后的 lint 检查和 manifest 验证的 mcp__SAPUI5_MCP_Server__*。
0e. Connection Manager(可选)
对于使用已保存的 BTP / 本地系统连接,而非直接服务 URL 的场景,Fiori MCP 服务依赖 SAP Systems Connection Manager VS Code 扩展。对于此技能使用的直连 URL 流程,该扩展并非必需——服务 URL 会直接传递给 execute_functionality。
阶段 1 — 清点旧版应用中用户可见的功能
这是注解计划的核心。FE 应用必须复现旧版应用中所有用户可见的行为。读取所有相关旧版文件,并生成一份功能清单。
1a. 读取旧版 manifest
Read: <source_app>/webapp/manifest.json
提取:sap.ui5.routing.routes(用户可访问的 URL)、sap.ui5.rootView、sap.app.dataSources、i18n。路由可帮助你了解导航树;数据源则会告诉你旧版应用预期的服务结构。
1b. 阅读每个旧版视图
Bash: ls <source_app>/webapp/view/
Read: <source_app>/webapp/view/<each>.view.xml
对于每个视图,盘点:
- 页面标题(来自
<Page title=...>)。 - 页眉内容 — 按钮及其条件(例如
enabled="{= ${Status} === 'D'}")。 - 列表/表格列 — 每个
<Column>的绑定字段、排序方向和对齐方式。 - 搜索字段 — 带有
liveChange和placeholder的<SearchField>。 - 默认排序 — 列表绑定上的
sorter子句(路径 + 升序/降序)。 - 条目结构 —
ObjectListItem/ColumnListItem/ObjectHeader及其属性、状态字段和格式化器调用。 - 标签页结构 —
IconTabBar+IconTabFilter条目(哪些实体以标签页形式展示、每个标签页是否有计数器)。 - 导航处理器 —
press/selectionChange回调(点击行 → 导航)。 - 计数器、页脚 — 信息性组件(条目数、总计)。
1c. 阅读每个旧版控制器
Bash: ls <source_app>/webapp/controller/
Read: <source_app>/webapp/controller/<each>.controller.js
对于每个控制器,盘点:
- 操作处理器 — 每个
on<Action>方法执行什么操作?(调用 OData 函数导入?筛选?重新绑定?显示 MessageBox?) - 筛选/搜索逻辑 — 使用哪些字段、
FilterOperator和绑定路径? - 函数导入调用 —
oModel.callFunction(...)调用及其参数结构。 - 自定义验证 — 函数导入/提交前的检查。
- 自定义导航 — 任何绕过 manifest 路由器的操作。
- 自定义客户端状态 — 为纯 UI 状态创建的 JSONModels(例如从非 OData 来源获取的标签页计数器)。
1d. 阅读每个旧版格式化器
Read: <source_app>/webapp/model/formatter.js
对于每个格式化器函数,盘点:
- 格式化内容 — 状态代码 → 文本、状态代码 → 语义状态(Success/Warning/Error)、日期 → 短格式、小时 → 小数等。
- 代码→文本映射 — 记录确切的值(例如
D → "Draft"、A → "Active"、C → "Closed")。
这些可直接映射到 CDS 注解模式 — @Common.Text + @UI.TextArrangement、@UI.Criticality、值帮助集合等。
1e. 构建功能清单
向用户输出结构化清单:
Feature inventory — <source_app>:
ROOT ENTITY (Project):
Display name (header): Title
Description (sub): ProjectId
Status (criticality): Status field — values D=Draft (Warning) / A=Active (Success) / C=Closed (Neutral)
Sort default: StartDate descending
Search (master): ProjectId, Title (Contains, OR-joined)
Audit fields: Erdat (Created), Ernam (Created by), Aedat (Changed), Aenam (Changed by)
Header button: Approve — enabled when Status == 'D', calls /ApproveProject(ProjectId)
Count footer: "<n> projects" displayed below the list
CHILD ENTITY (Task):
Tab in detail: "Tasks"
Counter: from binding length
Columns: TaskId, Title+Description, Status, Priority, DueDate, AssignedTo, EstimatedHours
Status criticality: Status: D/IP/D/C (Draft/InProgress/Done/Cancelled) — see formatter
Priority criticality: L/M/H (Low/Medium/High) — see formatter
Click behavior: Selecting a task populates the TimeEntries tab
CHILD-OF-CHILD ENTITY (TimeEntry):
Tab in detail: "Time Entries"
Counter: from selected task's TimeEntries length
Columns: EntryId, TaskId, WorkDate, WorkHours, Description, Username
FORMATTERS:
statusText: D → "Draft", A → "Active", C → "Closed"
statusState: D → Warning, A → Success, C → Neutral
taskStatusText: D → "Draft", IP → "In Progress", DN → "Done", CN → "Cancelled"
taskStatusState: same scheme
priorityText: L → "Low", M → "Medium", H → "High"
priorityState: L → Neutral, M → Warning, H → Error
dateShort: custom YYYY-MM-DD
hoursDecimal: two decimal places
FUNCTION IMPORT (V2):
ApproveProject(ProjectId) → translates to RAP action approve_project (already in BDEF)
此清单是第 2 阶段的约定。
第 2 阶段 — 将功能映射到注解和扩展
将清单中的每项归类为以下类别之一:
- STANDARD — FE 模板可原生呈现(分页、行点击导航、按键搜索、基本编辑、基本创建、基本删除、草稿支持)。
- ANNOTATION — 需要在 CDS 投影上使用特定的
@UI.*/@Common.*/@ObjectModel.*注解。大多数旧版功能都归入此类。 - EXTENSION — FE 模板无法表达的真正自定义行为;需要在 FE 应用端使用控制器扩展。
2a. 注解对照表——入门参考(通过 sap-docs 验证各模式)
下表是速查参考,并非权威目录。请按照上文“使用 mcp__sap-docs__search”一节中的搜索步骤,确认适用于你所用版本的当前规范语法,尤其是以下标记为 ⚠ 的内容。
| 旧版功能 | 入门注解 + 示例标签 |
|---|---|
标题 = Title | @UI.HeaderInfo.title.value: 'Title' — #HeaderInfo |
标题描述 = ProjectId | @UI.HeaderInfo.description.value: 'ProjectId' — #HeaderInfo |
| 标题类型标签 | @UI.HeaderInfo.typeName: 'Project', typeNamePlural: 'Projects' — #HeaderInfo |
| 列表列(主列表) | 每个字段使用 @UI.lineItem: [{ position: N, importance: #HIGH }] — 含关键性属性的变体请参见 #LineItemHighlight |
| ⚠ 状态代码 → 文本 + 颜色 | 有多种有效模式,请根据版本和草稿限制选择。 搜索 #LineItemHighlight,查找通过实际列设置关键性的路径。若要在没有持久化列的情况下计算关键性,请参见 /abap-docs-standard/ABENCDS_PROJ_VIEW_VIRTUAL_ELEMENT + @ObjectModel.virtualElementCalculatedBy: 'ABAP:<class>'。在 7.58 + 草稿场景中,两种方式都存在已知限制(Run 7 §1 中有详细说明)。采用前请先搜索。 |
| 默认排序 | @UI.presentationVariant.sortOrder: [{ by: '<field>', direction: #DESC }] — #PresentationVariant |
| 跨字段搜索 | 在视图级别设置 @Search.searchable: true,并对每个字段设置 @Search.defaultSearchElement: true — #Search |
| 筛选栏 | @UI.selectionFields: [...] — #SelectionFields |
| 审计字段显示 | @UI.fieldGroup + #FIELDGROUP_REFERENCE 的 @UI.facet — #HeaderFieldGroup |
| 批准按钮(标题栏) | @UI.identification: [{ type: #FOR_ACTION, dataAction: 'approve_project', label: 'Approve', criticality: 3, criticalityRepresentation: #WITH_ICON }] — #OPHeaderAction。该操作不会根据 BDEF 自动呈现。 投影 BDEF 必须已公开 use action approve_project;。 |
| LR 工具栏操作 | 在 @UI.lineItem 上使用相同形式 — #ActionInLineItem、#WithAction |
| 子实体的 OP 表格 | 在父实体上设置 @UI.facet: [{ type: #LINEITEM_REFERENCE, targetElement: '_AssocName', label: '...' }],并在子投影上设置 @UI.lineItem — #OPTable |
| ⚠ 多级导航(Project → Task → TimeEntry) | 有两种有效形式——选择前先调研。(a) 从根投影引用 _Tasks._TimeEntries 的嵌套 LineItem facet(取决于版本的 FE 支持情况)。(b) 单独的 Task OP 路由——为 ZC_DM_TASK 添加 @UI.headerInfo 和其自身的 _TimeEntries facet,然后在 FE 应用的 manifest 中添加 Task 路由目标。请搜索 #OPTable、#Subpages、#InboundNav(cap-fiori-showcase);另请参阅 SAPUI5(sap-help)中的 “Configuring Internal Navigation”,了解 manifest 路由形式。 |
| 语义键加粗显示 | @ObjectModel.semanticKey: ['ProjectId'] — #SemanticKey |
| 动态 CRUD(根据行状态隐藏按钮) | 将 @UI.updateHidden + @UI.deleteHidden 绑定到字段 — #DynamicCRUD |
7.58 上 DDLS 与 DDLX 的适用范围。 在 Run 7 中,若干实体级注解 (
@UI.facet、@UI.selectionFields、通过@UI.identification设置的标题栏FOR_ACTION)在投影 DDLS 中 会报错,但移至 DDLX 元数据扩展(annotate view <ZC_*> with @UI.facet: [...]等)后则可成功。如果 DDLS 实体级注解报错,提示“wrong scope” / “unknown”,请改用 DDLX。 请通过/abap-fiori-showcase中对应的#Tag确认——在需要支持本地部署版本的地方,示例模式已 分别放在 DDLS 和 DDLX 中。
2b. 扩展映射(典型情况)
| 旧功能 | 扩展挂钩 |
|---|---|
Approve 上的 Status === 'D' 守卫 | FE 的 BDEF 操作按钮会根据 BDEF 的 precheck 启用。如果旧应用的启用规则与 BDEF 不同,请在 BDEF 上添加 precheck(步骤 2c),而不是在 JS 中覆盖。 |
| Approve 前的自定义验证(例如要求填写 Description) | ObjectPage 上的 editFlow.onBeforeAction 控制器扩展 |
| 自定义客户端计数页脚措辞 | 跳过 — FE 列表报表会显示原生计数 |
| 自定义导航模式 | 几乎不需要;FE 的行 → OP 导航是默认行为 |
| 审批失败时显示 MessageBox | FE 原生错误提示已会处理此情况 |
2c. BDEF 侧准备(在 2b 之后、Phase 4 之前运行)
如果清单中发现类似“仅当 Status === 'D' 时才显示 Approve 按钮”的守卫,这属于
前置条件,而非 UI 关注点。请在 BDEF 侧通过操作的 precheck
子句对其进行编码,然后重新激活。(此步骤属于 migrate-segw-to-rap.md 的步骤 5,但当旧守卫尚未迁移时,请在此处明确指出。)示例:
action approve_project precheck result [1] $self;
在行为池中使用 precheck 方法填充 %cid / %key,并断言
Status == 'D'。如有需要,技能会将实际的 precheck 方法体交由 edit_method 处理。
Phase 3 — 制定计划并获得用户批准
请按以下确切格式打印计划,然后暂停,等待用户回复 ok / edit / 提问:
Plan — generate FE app at <fe_app>:
Floorplan: List Report + Object Page (LROP V4)
Namespace: <source_namespace>.fe
UI5 version: <user-provided, default latest 1.x>
V4 service: <V4_service_URL>
Main entity: <root_alias> (alias on the root projection)
Generator: SAP Fiori MCP server (@sap-ux/fiori-mcp-server)
Backend annotation writes (via SAPWrite update DDLS on the projection):
<root_projection>:
@UI.HeaderInfo, @UI.SelectionFields, @UI.LineItem (root columns),
@UI.Identification, @UI.PresentationVariant.SortOrder,
@UI.FieldGroup.Audit, @UI.Facet (Identification + Tasks)
@Common.Text + virtual <field>Criticality (Status)
<child_projection_task>:
@UI.LineItem (Task columns), @UI.HeaderInfo,
@UI.Facet (Task identification + TimeEntries),
@Common.Text + virtual fields for Status, Priority
<child_projection_timeentry>:
@UI.LineItem (TimeEntry columns), @UI.HeaderInfo
BDEF-side adjustments (via SAPWrite update BDEF / edit_method):
<list precheck additions, if any>
FE app generation (via Fiori MCP):
Step 1: list_functionalities → enumerate supported FE app creations
Step 2: get_functionality_details → "create FE V4 list-report+OP for external OData service"
Step 3: execute_functionality → pass service URL, root entity, namespace, target folder
Extension scaffold (post-generation):
- <controller-extension list per Phase 2b>
Validation:
- ui5-linter clean
- manifest validation clean
- tsc --noEmit clean
- browser smoke against every Phase 1 inventory item
Type `ok` to proceed, `edit` to revise, or ask any question.
在获得 ok 之前,请勿修改 SAP 系统中的任何内容,也不要生成 FE 应用。
Phase 4 — 将 @UI.* 注解写入 CDS 投影(后端准备)
这一步是“在后端准备注解”。请在调用 Fiori MCP 生成器之前完成所有 CDS 写入——生成器会读取带注解的 $metadata,因此运行生成器前,注解必须处于激活状态,且 SRVB 必须已重新发布。
4a. 为根投影添加注解
SAPRead(type="DDLS", name="<root_projection>")
插入规划好的注解。具体形式如下(替换为你的实体):
@Metadata.allowExtensions: true
@UI.headerInfo: {
typeName: 'Project',
typeNamePlural: 'Projects',
title: { value: 'Title' },
description: { value: 'ProjectId' }
}
@UI.selectionFields: [ 'ProjectId', 'Title', 'Status' ]
@UI.presentationVariant: [{
qualifier: 'DefaultSort',
sortOrder: [{ by: 'StartDate', direction: #DESC }]
}]
@UI.facet: [
{ id: 'GeneralInfo', purpose: #STANDARD, type: #IDENTIFICATION_REFERENCE, label: 'General' },
{ id: 'AuditInfo', purpose: #STANDARD, type: #FIELDGROUP_REFERENCE, label: 'Audit',
targetQualifier: 'Audit' },
{ id: 'Tasks', purpose: #STANDARD, type: #LINEITEM_REFERENCE, label: 'Tasks',
targetElement: '_Tasks' }
]
// Header action — renders as an "Approve" button on the OP header (showcase #OPHeaderAction).
// criticality 3 = green (success), 0 = neutral, 1 = red.
@UI.identification: [
{ type: #FOR_ACTION,
dataAction: 'approve_project',
label: 'Approve',
criticality: 3,
criticalityRepresentation: #WITH_ICON }
]
@Search.searchable: true
define root view entity <root_projection>
provider contract transactional_query
as projection on <root_view>
{
key @UI.lineItem: [{ position: 10, importance: #HIGH }]
@UI.identification: [{ position: 10 }]
@UI.selectionField: [{ position: 10 }]
@Search.defaultSearchElement: true
ProjectId,
@UI.lineItem: [{ position: 20, importance: #HIGH }]
@UI.identification: [{ position: 20 }]
@UI.selectionField: [{ position: 20 }]
@Search.defaultSearchElement: true
Title,
@UI.lineItem: [{ position: 30, criticality: 'StatusCriticality' }]
@UI.identification: [{ position: 30 }]
@UI.selectionField: [{ position: 30 }]
Status,
@UI.lineItem: [{ position: 40 }]
@UI.identification: [{ position: 40 }]
StartDate,
@UI.lineItem: [{ position: 50 }]
@UI.identification: [{ position: 50 }]
EndDate,
@UI.identification: [{ position: 60 }]
Description,
@UI.fieldGroup: [{ qualifier: 'Audit', position: 10, label: 'Created at' }]
Erdat,
@UI.fieldGroup: [{ qualifier: 'Audit', position: 20, label: 'Created by' }]
Ernam,
@UI.fieldGroup: [{ qualifier: 'Audit', position: 30, label: 'Changed at' }]
Aedat,
@UI.fieldGroup: [{ qualifier: 'Audit', position: 40, label: 'Changed by' }]
Aenam,
// virtual criticality field (computed from Status code)
@ObjectModel.virtualElementCalculatedBy: 'ABAP:<root_class>' // OR via case-when below
virtual StatusCriticality : abap.int1,
/* associations */
_Tasks
}
对于虚拟关键性,跨 7.58 版本兼容性最简单的选项是在投影中直接使用 case-when:
case Status
when 'D' then 2 // Critical (Warning)
when 'A' then 3 // Positive (Success)
when 'C' then 0 // Neutral
else 0
end as StatusCriticality,
写入插入后的源代码:
SAPWrite(action="update", type="DDLS", name="<root_projection>",
source="<spliced source>", transport="<transport>")
SAPActivate(type="DDLS", name="<root_projection>")
4b. 为每个子投影添加注解
对每个 <child_projection_X> 重复此模式。每个子项都需要:
@UI.headerInfo(标题/描述)- 为旧视图显示的每一列添加
@UI.lineItem - 如果该子项还有子项,则添加
@UI.facet(例如 Task 下的_TimeEntries) - 为清单中列出的任何带颜色代码字段添加虚拟关键性字段
4c. 发布 SRVB
需要重新发布 SRVB,才能在 $metadata 中显示新增注解:
SAPWrite(action="publish_srvb", name="<V4_SRVB>")
4d. 验证注解是否写入 $metadata
Bash: curl -s "<base>/<V4_service_URL>/$metadata" | grep -oE 'UI\.(LineItem|HeaderInfo|Facets|SelectionFields|PresentationVariant|FieldGroup|Identification)' | sort -u
预期输出:你编写的每种注解都应出现在列表中。如果列表为空,说明 SRVB 未获取到更改——请重新运行 publish_srvb。如果只显示部分注解,说明投影未能正确重新激活——请运行 SAPDiagnose(action="object_state", type="DDLS", name="<root_projection>") 进行检查。
第 5 阶段 — 通过 SAP Fiori MCP 服务生成 FE 应用
这是“使用 Fiori MCP 创建应用”这一步。Fiori MCP 服务提供了一套由三个工具组成的流程——list_functionalities → get_functionality_details → execute_functionality。
每一步都会缩小范围。即使你认为自己知道参数,也不要跳过任何步骤。
参考:
- SAP/open-ux-tools — fiori-mcp-server README
- npm: @sap-ux/fiori-mcp-server
- SAP Community: SAP Fiori MCP Server 首次发布
编写此技能时,Fiori MCP 服务仍处于实验性阶段。工具签名可能会发生变化。如果
list_functionalities返回的结构与预期不同,请遵循实时响应——以上 README 是权威信息来源。
5a. 了解服务的功能
mcp__fiori-mcp__list_functionalities
检查响应,寻找与“为外部 OData V4 服务创建新的 Fiori elements 应用”匹配的功能。响应中的确切名称取决于服务版本——查找 create、fiori-elements、list-report、lropv4、external-service 等关键词。
如果服务没有匹配的功能:
- 它可能需要 CAP 项目。在这种情况下,请通过旧版备用方案生成(
@sap/generator-fioriCLI——见 5d),并将这一缺口记录为下一次迭代的运行记录。 - 或者,用户的 Fiori MCP 版本可能比预期的旧。再次运行以下命令进行检查:
并指导用户更新 MCP 配置,以固定到最新版本。Bash: npx --yes @sap-ux/fiori-mcp-server@latest --version
5b. 获取所选功能的参数要求
mcp__fiori-mcp__get_functionality_details(name="<the-functionality-name-from-5a>")
响应会列出必需参数和可选参数。对于面向外部服务的 LROP 流程,典型的必需参数包括:
serviceUrl—<V4_service_URL>(第 0a 阶段中由$metadata支持的端点)mainEntity或entitySet— SRVB 中的根实体别名(例如Project)targetPath—<fe_app>/(用于生成应用的文件夹)namespace—<source_namespace>.feappId/appName— 应用标识符ui5Version— 用户提供(默认值:最新的 1.x)language—typescript
将用户提供的输入映射到必需参数。如果某个必需参数没有对应值,请停止并询问用户。不要编造值。
5c. 执行生成器
mcp__fiori-mcp__execute_functionality(
name="<the-functionality-name-from-5a>",
parameters={
serviceUrl: "<V4_service_URL>",
mainEntity: "<root_alias>",
targetPath: "<fe_app>",
namespace: "<source_namespace>.fe",
appName: "<short-app-id>",
ui5Version: "<ui5-version>",
language: "typescript"
}
)
等待生成器完成。验证目录结构:
Bash: ls <fe_app>/webapp/ && cat <fe_app>/webapp/manifest.json | head -40
预期内容:
webapp/Component.tswebapp/manifest.json,其中包含sap.ui.generic.app/sap.fe.templates配置webapp/i18n/i18n.propertieswebapp/ext/(扩展文件夹,可能为空)package.json/ui5.yaml/tsconfig.json
5d. MCP 服务无法完成生成时的备用方案
如果 list_functionalities 没有提供外部服务路径,请改用 @sap/generator-fiori CLI:
Bash: cd <workspace> && npx --yes @sap/generator-fiori --no-deploy
依次完成提示步骤(或使用明确的参数传入 --skip-install)。MCP 服务封装的正是这个生成器——由于需要交互操作,速度较慢,但始终可用。
5e. 已知的 Fiori MCP 问题(跟踪上游进展)
Fiori MCP 服务处于实验阶段。请注意以下两个已知问题,并采取相应的规避措施:
- 当
@sap-ux/store中没有目标系统的条目时,fetch-service-metadata会返回 MCP 框架错误,而不是结构化响应。规避方法:自行使用curl $metadata将元数据下载到本地文件(例如<fe_app>/metadata.xml),然后让execute_functionality使用该文件。上游跟踪: SAP/open-ux-tools#4652 — 此问题关闭后,即可不再使用 curl 规避方法。 fetch-service-metadata要求配置 Connection Manager,才能使用已存储的系统条目;将 URL 直接传给execute_functionality则可绕过这一要求。技能的 Phase 0e 已说明直接使用 URL 的方式。
请将任何新发现的问题记录在 RUN-NOTES.md 中,以便下一轮迭代能够采取规避措施,或向上游提交后续问题。
Phase 6 — 为 Phase 2b 中的 EXTENSION 列表配置扩展
对于 Phase 2b 扩展映射中的每一行,搭建一个 TS 控制器扩展。FE V4 扩展有两种形式:
- 控制器扩展 — 通过
editFlow/routing/appComponentAPI 扩展 LR 或 OP 控制器。 - 扩展点 — 在指定位置(页眉、页脚、某个分区之前或之后)插入自定义 XML/Fragment。
对于演示中常见的扩展(审批前进行 BDEF 尚未实现的预检查):
Write: <fe_app>/webapp/ext/ObjectPageExt.ts
import ControllerExtension from "sap/ui/core/mvc/ControllerExtension";
import MessageBox from "sap/m/MessageBox";
/**
* @namespace <source_namespace>.fe.ext
*/
export default class ObjectPageExt extends ControllerExtension {
public static overrides = {
editFlow: {
onBeforeAction: async function (
this: ObjectPageExt,
mParameters: { actionName: string; context: any }
) {
if (!mParameters.actionName.endsWith(".approve_project")) return;
const description = mParameters.context.getProperty("Description");
if (!description) {
MessageBox.error("Cannot approve a project without a description.");
throw new Error("Approval blocked by extension");
}
}
}
};
}
在 <fe_app>/webapp/manifest.json 中注册扩展:
"sap.ui5": {
"extends": {
"extensions": {
"sap.ui.controllerExtensions": {
"sap.fe.templates.ObjectPage.ObjectPageController": {
"controllerName": "<source_namespace>.fe.ext.ObjectPageExt"
}
}
}
}
}
每搭建一个扩展后,都运行一次代码检查工具:
mcp__SAPUI5_MCP_Server__run_ui5_linter(files=["<fe_app>/webapp/ext/ObjectPageExt.ts"])
对扩展映射中的每个条目重复以上步骤。扩展应保持精简——每个类只处理一项职责。
如果功能分类不明确(注解?扩展?),请使用 Fiori MCP 的文档搜索功能进行确认:
mcp__fiori-mcp__search_docs(query="custom validation before action Fiori elements V4")
这会获取 SAP 的权威指导,避免凭空推测。
Phase 7 — 验证与冒烟测试
7a. 静态检查
mcp__SAPUI5_MCP_Server__run_ui5_linter
mcp__SAPUI5_MCP_Server__run_manifest_validation
Bash: cd <fe_app> && npx tsc --noEmit
这三项检查都必须通过。
7b. 开发服务器
在空闲端口上重启开发服务器(默认端口为 8082;如果旧应用的开发服务器或其他正在运行的工具已占用该端口,请选择其他端口):
Bash: cd <fe_app> && pkill -f "ui5 serve" ; (npm start -- --port 8082 &)
等待约 5 秒,让服务器启动。检查入口点:
Bash: curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8082/index.html
7c. 对照 Phase 1 清单进行浏览器冒烟测试
在浏览器中打开 http://localhost:8082,验证 Phase 1 清单中的每一项。验收标准:FE 应用通过注解或扩展,复现旧应用中所有用户可见的功能。
参考检查清单(根据用户的清单调整):
- 列表报表能够渲染,且列顺序与
@UI.LineItem中的定义一致。 - 筛选栏显示
@UI.SelectionFields中的字段。 - 搜索可在标记为
@Search.defaultSearchElement的字段上正常工作。 - 默认排序与
@UI.PresentationVariant.SortOrder一致。 - 单击行会打开 OP。
- OP 页眉显示来自
@UI.HeaderInfo的正确标题和说明。 - 行中的状态字段显示正确的颜色(criticality)。
- 选项卡/切面会渲染每个由
@UI.Facet引用的关联。 - 嵌套切面可以逐级查看孙级实体(例如 Tasks 下的 TimeEntries)。
- 操作按钮会针对 BDEF 操作进行渲染(来自
@UI.identificationDataFieldForAction);单击后会通过框架的标准 CSRF/etag 流程执行,无需扩展即可完成往返操作。 - 对于 Phase 2b 中列出的情况,扩展钩子会触发(验证、自定义提示词)。
- 审计字段会显示在 OP 的审计切面中。
- 列表报表页眉中的原生 FE 计数与旧应用页脚的表述相符(允许存在“X 个项目”与“正在显示 X 个,共 Y 个”之间的用户体验差异)。
7c.1 — V4 草稿场景的实际情况(已在 Run 6 中验证)
在草稿场景下,V4 服务会将 IsActiveEntity 作为每个实体键的一部分公开。
这会对测试产生两种影响:
- 带键读取必须包含
IsActiveEntity:Project(ProjectId='PRJ-0001',IsActiveEntity=true)返回 200;旧式的Project('PRJ-0001')返回 400。 - 调用操作需要完整的 CSRF 流程:先通过
X-CSRF-Token: Fetch获取<service-root>/?sap-client=<n>→ 再使用返回的X-CSRF-Token、会话 Cookie 和If-Match: <etag>POST 到操作 URL。省略If-Match会返回 428(CX_OD_PRECOND_REQUIRED)。
任何 V4 + 草稿服务都会有这些正常行为;FE 模板会在运行时自动处理。这里的说明仅供手动执行 curl 冒烟测试时参考。
如果任何步骤失败:
- 对于注解问题,返回 Phase 4 并调整 CDS,重新激活,执行
publish_srvb, 然后重新运行冒烟测试步骤。 - 对于扩展问题,通过浏览器 DevTools 调试控制器扩展。
- 对于看起来像工具错误的 FE 渲染问题,运行
mcp__fiori-mcp__search_docs(query="<exact symptom>")查找权威参考。
7d. 最终报告
Fiori Elements conversion complete — <fe_app>
Floorplan: LROP V4 (TS)
UI5: <version>
V4 service: <V4_service_URL>
Annotations: <n> @UI.* annotations written across <m> projections
Extensions: <n> controller extensions
Linter: clean
Manifest: clean
TypeCheck: clean
Browser smoke: <12+/12+> inventory items reproduced
What just happened (3 sentences):
- Mined the legacy app's user-visible feature set (columns, sort, search, actions,
tab structure, formatters).
- Wrote the equivalent @UI.* / @Common.* / @Search.* annotations onto the RAP CDS
projections via ARC-1.
- Generated the FE app on top of the now-annotated $metadata via the SAP Fiori MCP
server, with extension hooks for the few cases FE templates can't express natively.
ARC-1 calls used:
- SAPManage(action=probe)
- SAPRead(type=DDLS, name=<root_projection>)
- SAPRead(type=SRVB, name=<V4_SRVB>)
- SAPWrite(action=update, type=DDLS, ...) × <m> projections
- SAPActivate(type=DDLS, ...)
- SAPWrite(action=publish_srvb, name=<V4_SRVB>)
- (Optional) SAPWrite(action=update, type=BDEF, ...) + SAPActivate for BDEF precheck
Fiori MCP calls used:
- mcp__fiori-mcp__list_functionalities
- mcp__fiori-mcp__get_functionality_details(name=<chosen>)
- mcp__fiori-mcp__execute_functionality(...)
- mcp__fiori-mcp__search_docs(...) × <n> (during extension scaffolding)
UI5 MCP calls used:
- mcp__SAPUI5_MCP_Server__run_ui5_linter × <n>
- mcp__SAPUI5_MCP_Server__run_manifest_validation
错误处理 — 已知情况
| 症状 | 原因 | 修复方法 |
|---|---|---|
SAPWrite update DDLS 后,$metadata 中没有注解 | DDLS 已重新激活,但 SRVB 未重新发布 | SAPWrite(action="publish_srvb", name="<V4_SRVB>") |
mcp__fiori-mcp__list_functionalities 返回空结果 / 失败 | 服务未注册,或 npx 缓存已过时 | 检查 .cursor/mcp.json;在新的 Shell 中,npx --yes @sap-ux/fiori-mcp-server@latest fiori-mcp 应输出服务就绪日志 |
| 生成器因“service unreachable”而失败 | 由于 V4 路由组限制,<V4_service_URL> 被 403 拒绝访问 | 按照 migrate-segw-to-rap.md Phase 6,执行 /n/IWFND/MAINT_SERVICE 手动步骤 |
| 生成器成功,但 FE 应用显示空白外壳 | 传入的 mainEntity 没有关联带注解的 CDS | 重新检查 Phase 4——@UI.Facet 链中的每个实体都至少需要 @UI.LineItem,且(对于 OP 根实体)需要 @UI.HeaderInfo |
| 列表报表没有显示列 | @UI.LineItem 注解位于根视图,而非投影中 | 将注解移到投影中;FE 会从 SRVB 公开的投影中读取注解 |
| 操作按钮不可见 | 操作未在投影 BDEF 上公开,或投影 BDEF 缺少 use action approve_project | 检查投影 BDEF(define behavior for <root_projection> { ... use action approve_project; })并重新发布 |
| 筛选栏为空 | 缺少 @UI.SelectionFields 注解,或其指向的字段在视图级别未标记为 @Search.searchable | 在视图级别添加 @Search.searchable: true,并在正确的字段上添加 @Search.defaultSearchElement: true |
| 状态字段没有颜色 | 未绑定重要性 | 在 @UI.LineItem 条目中添加 criticality: '<field>Criticality' 引用,并添加一个虚拟的 <field>Criticality 投影字段,将代码映射到 FE 重要性(0=中性,1=负面,2=关键,3=正面) |
| 未渲染嵌套区段(Tasks 下的 TimeEntries) | 某些 7.5x 版本不支持 _Tasks._TimeEntries LineItem 区段路径 | 如果必须使用,将 TimeEntries 渲染为单独的 OP——从 Task LineItem 进入;请在用户使用的版本上验证 |
| 控制器扩展抛出“Override target not found” | manifest 中的控制器路径错误 | LR:sap.fe.templates.ListReport.ListReportController;OP:sap.fe.templates.ObjectPage.ObjectPageController |
MCP server timed out | 缓慢的 $metadata 获取阻塞了长时间运行的 execute_functionality | 增大 .cursor/mcp.json 中的 MCP timeout(目前为 600s);对于 talk-demo 的服务规模,默认值通常已足够 |
| 生成器停在确认提示上 | MCP 服务尝试以交互方式确认覆盖操作 | 重新运行前预先删除 <fe_app>/,或在 functionality details 中列出该选项时传入 overwrite: true |
此技能明确不涵盖的内容
- 多楼层平面图组合(Overview Page + LRO + ALP)。单个 LRO+OP 是演示的范围。组合功能将在后续实现。
- 确实无法用 FE 构建块实现的复杂自定义渲染。如果用户有此需求,应改用自由形式路径(
modernize-ui5-app.md)。 - 模拟/本地服务模式。 此技能面向实时 V4 RAP 服务。Fiori MCP 可以为 CAP 项目生成应用,但那是另一种流程。
- 授权策略。 FE 按照服务授权内容进行渲染。PFCG / S_DEVELOP 的更改发生在 SAP 端,与此技能无关。
- 超出 CDS
@EndUserText.label所提供内容的翻译/本地化。 FE 从服务元数据中读取标签;其他 i18n 内容存放在 FE 应用的 i18n 文件中。 - CAP 端生成。 此技能假设后端使用 RAP;对于仅使用 CAP 的流程,请直接使用 Fiori MCP 服务面向 CAP 的提示词。
使用此技能的 LLM 注意事项
- 注解优先是此技能的核心原则。绝不要让 FE 生成器针对未添加注解的
$metadata运行——结果只会是一个无用的空壳。 - Fiori MCP 服务仍处于实验阶段。自编写此技能以来,工具名称和参数结构可能已有变化。始终先调用
list_functionalities,再据此调整。 - 注解应放在投影上,而不是根视图上。SRVB 暴露的是投影;FE 从那里读取数据。
- 每次 CDS 更改影响已暴露的注解后,都要重新发布 SRVB。ADT 不会自动执行此操作。
- “分面引用关联”模式最棘手:只有当
_Tasks是投影上已暴露的关联时,类型为#LINEITEM_REFERENCE且targetElement: '_Tasks'的分面才有效。请检查投影中的use association _Tasks { ... }块。 - 控制器扩展是应急手段——不确定某项功能是否需要扩展时,请询问用户。FE 模板能表达的内容比很多人预想的更多;只有在确实必要时才升级处理。
- 在猜测注解语法之前,请先查阅
mcp__fiori-mcp__search_docs(或使用topic="fiori-elements"调用mcp__sap-docs__search)。SAP 的注解参考文档是权威来源。 - 如果
mcp__fiori-mcp__list_functionalities返回了意料之外的能力(例如“向现有应用添加页面”“修改 manifest”),请在计划中说明——它们可能简化第 6 阶段的扩展工作。 - 如果 Fiori MCP 可以通过
execute_functionality添加页面或更改路由,不要手动编辑manifest.json。MCP 的编辑能识别架构,并且在重新生成后仍会保留;手动编辑则可能被覆盖。