前几年第一次在 SPRO 里看到 LPD_CUST 这个名字,我第一反应是"这又是哪个模块的配置表"。后来做 SAP Fiori Launchpad(FLP)项目的次数多了,才意识到这张表才是很多“导航目标”问题的真正源头。不管你是想让一个外部网页在 FLP 里能点开,还是想把 Web Dynpro 老应用包装成 Fiori 入口,又或者是用户反馈“换个设备就看不到入口”,最后大概率都要回到 LPD_CUST 的字段级调试上。这篇就把 LPD_CUST 从表结构、配置步骤到常见坑一次讲清楚,适合刚接手 Fiori 定制项目的顾问,也适合被业务方追问“为什么我配了没反应”的 ABAP 开发。
1. 先搞清楚 LPD_CUST 是干嘛的:一张表背后的导航机制
1.1 名字里的信息:Launchpad Customizing 从哪来
LPD_CUST 全称 Launchpad Customizing,意思是“启动板自定义”。它在 SAP NetWeaver 的 Fiori 体系里承担一个朴素但重要的角色:把导航目标(Navigation Target)维护到一张可被 FLP 运行时读取的配置表里。你可以把它理解成一个“总机接线表”——用户在前端点某个入口,FLP 根据这张表去决定跳到哪里、给谁看、用什么设备打开。
为什么会有这张表?Fiori 这套东西刚出来的时候,SAP 希望大家用“语义对象 + 动作”的方式来描述导航意图,而不是直接拿 URL 写死。一个入口的完整描述是:语义对象(Semantic Object)+ 动作(Action),组合成 Intent,比如ZOrder-Display。LPD_CUST 就是用来维护这套“意图 + 落地地址 + 可见性”映射关系的表。换句话说,它比 Launchpad Designer 更早,是 FLP 定制能力的老前辈,但到现在仍然被大量项目沿用。
1.2 LPD_CUST 和 Standard Launchpad、Custom Launchpad 的关系
很多同事在这里栽过跟头,所以先把这个关系讲清楚。Fiori Launchpad 有两种展示视图:Standard Launchpad 和 Custom Launchpad。
Standard Launchpad 就是我们通常看到的磁贴(tile)界面,它基于目录(Catalog)和分组(Group)模型,配置存放在/UI2/开头的一系列表里,通过 Launchpad Designer 或 Fiori 管理员 App 维护。
Custom Launchpad 则是一个类似经典 SAP Easy Access 的树形菜单视图。用户在 FLP 右上角可以对视图做切换,而 Custom Launchpad 的目录树正是由 LPD_CUST 驱动。每条 LPD_CUST 记录可以是一个文件夹,也可以是一个具体导航目标;通过 PARENT 字段挂接父节点,就形成了一棵树。
这解释了一个常见现象:业务方说“我在 SPRO 里配好了,Fiori 前端怎么看不到”。答案往往是——你看的是 Standard Launchpad,而 LPD_CUST 的入口在 Custom Launchpad 视图里;或者你配了 Custom Launchpad 的文件夹,但用户角色根本没触发该条记录的可见性。两种视图差异是 LPD_CUST 调试时第一件要确认的事。
1.3 核心字段一次讲透
我平时维护 LPD_CUST 主要通过 SM30 输入 V_LPD_CUST 这个维护视图。不同 NetWeaver 版本显示的字段会略有差异,但核心逻辑基本一致。下表列出项目里最常用、也是排查时最先会盯住的字段。
| 字段 | 作用 | 填法/注意点 |
|---|---|---|
| SEQNR | 记录序号,同一 Client 内唯一 | 建议用 1000、2000 这样的步长,后续插入记录不用大改 |
| FOLDER | 是否文件夹(X = 是) | 文件夹本身不打开页面,只作为树节点容器 |
| PARENT | 父节点 SEQNR | 空表示根节点;子节点填父文件夹的 SEQNR |
| SEMANTIC_OBJECT | 语义对象 | 建议大写开头,如 ZZMaterial;自定义对象要先注册 |
| SEMANTIC_ACTION | 动作 | 如 Display、Create、Launch;与语义对象一起定位意图 |
| INTENT | 意图,即 语义对象-动作 | FLP 解析导航时按这个值匹配 |
| DEVICE_TYPE | 设备类型 | Desktop/Tablet/Phone,注意多端覆盖 |
| ROLES | 可见角色过滤 | 留空对所有用户可见;填写角色关键字做白名单 |
| ITEM_TEXT | 节点/入口显示文本 | 用户看到的名称,要短、可辨识 |
| URL | 实际跳转地址 | 外部地址带协议;内部路径注意编码 |
| ICON | 图标名 | 配合前端图标库使用,可选 |
| DESCRIPTION | 描述 | 给顾问自己看的说明,不影响运行 |
这里最容易被忽略的是 DEVICE_TYPE。很多项目只在 Desktop 上配了入口,结果同事用平板开 FLP,发现某个菜单没了,查半天最后发现是设备类型没配。建议如果业务上不区分设备,就三种都配上,或者直接确认当前版本支持通配符。
字段里还有一层业务逻辑:SEMANTIC_OBJECT 和 SEMANTIC_ACTION 是“意图层”,URL 是“落地层”。FLP 导航时先拿 INTENT 找入口,再按设备类型挑 URL。意图相同但 URL 不同,是完全允许的,这正是设备分流的基础。表格里 FOLDER 和 PARENT 则决定了入口在树上的位置,配合 ROLES 就能做到“不同角色看到不同层级树”。
2. 什么场景下才值得动 LPD_CUST:选型思路和典型使用场景
2.1 场景一:外部页面、老系统、Web Dynpro 快速接入 FLP
最常见的一个需求:公司有一个自研门户页面、一套老 Web Dynpro 应用,或者另一个系统(比如 BI 报表、客户门户)的 URL,希望能在 Fiori Launchpad 里给用户一个入口,点开就在新页面看到它。这种场景不需要做复杂的 Fiori 应用开发,也不需要把页面做成 OData 服务,用 LPD_CUST 配一条记录加一个图标就够了。
我在一个制造客户那边干过类似的事:他们把车间的 MES 看板页面直接嵌到 FLP 里,用的就是 LPD_CUST。配置上只做了三件事:定语义对象 ZZMesBoard,动作 Launch;URL 填车间看板的 HTTPS 地址;角色限定到 MES 相关工厂角色。从提出需求到上线不到半小时,这比走一遍 Fiori 应用发布流程省太多了。
为什么不用 Launchpad Designer 的“外部链接”方案?也可以,但 LPD_CUST 在角色条件控制和树形组织上更接近业务习惯。尤其当外部页面数量多、需要按模块归类时,用 PARENT 搭文件夹比做一堆 Catalog、Group 再来回调样式要直观。
2.2 场景二:同一入口按设备分流到不同地址
移动场景下,一套桌面端页面直接甩给手机用户,体验基本是灾难。LPD_CUST 的 DEVICE_TYPE 字段就是为这个准备的。可以给同一个 INTENT 维护多条记录,分别指定 Desktop、Tablet、Phone 的 URL。桌面端打开完整 BI 报表,手机端打开同一个报表的移动版地址。
这里有个实操细节:一旦你打算做设备分流,URL 之间最好保持“同一业务功能、不同终端体验”的关系,而不是完全不同的内容。否则用户从手机切到电脑,发现入口还在但内容对不上,业务方会认为导航目标配置有 bug。我习惯在 DESCRIPTION 里写清楚每个设备 URL 对应的版本,避免后任顾问接手时靠猜。
2.3 场景三:旧菜单树迁移 / 轻量级“类 Easy Access”导航
有些客户是从经典 SAP GUI 界面迁移过来的,用户习惯了树形菜单:点开“生产制造”,下面是一排事务码入口。FLP 的标准磁贴界面虽然好看,但老用户不见得买账。Custom Launchpad 配合 LPD_CUST 的文件夹层级,能快速复刻这种树形体验,而且角色过滤玩熟了以后,比 PFCG 菜单还容易维护。
我在项目里见过最狠的用法是:把 SAP 标准事务码(比如 MM03、ME23N)也用 LPD_CUST 包了一层,入口文本写成业务人员看得懂的“查询物料”“查看采购订单”,URL 指向事务码对应的 GUI 启动地址或 ICF 服务。这样既保住了业务既有习惯,又用 Fiori 外壳统一了入口。注意这种用法本质上是“把旧入口换个壳”,不是标准 Fiori 应用,后期做 S/4 迁移时要评估是否要替换成新一代应用。
2.4 什么时候别用它:与 Launchpad Designer 的边界
LPD_CUST 再好用,也不是万能。如果你要做的入口需要:
- 运行时动态参数(比如用户点一个订单,带着订单号跳到另一个 App);
- App 到 App 的跨应用导航、参数回传;
- 复杂的目标映射(Target Mapping),按条件选不同应用地址;
- 在 Standard Launchpad 上以磁贴方式呈现并参与目录/分组管理;
那就老老实实用 Launchpad Designer 做 Tile + Target Mapping。LPD_CUST 适合的定位是“轻量、静态、以角色和设备为维度”的导航入口。选型错误是 LPD_CUST 项目里最隐蔽的风险,因为它表面看起来什么都能配,配到后面发现无法表达业务动态跳转需求,返工成本比一开始就用对方案高得多。
3. 实操:从计划到落地的完整配置步骤
3.1 配置前先定三件事:意图、命名规范、入库入口
动手前先花十分钟做三个约定,能省掉后面大量返工。
第一,语义对象和动作的命名。自开发对象建议遵循 Z 前缀,比如 ZMaterial、ZBpmTask。动作尽量用标准英文动词:Display、Create、Launch、Manage。命名一旦上线,后面改起来会牵连角色、菜单、甚至已打开的 FLP 缓存,所以第一次就定严谨。
第二,SEQNR 规划。虽然字段只是数字序号,但层级树的可维护性全靠它。我习惯按模块分区间:1000 起步做根文件夹,1100 到 1999 放该模块下的入口,2000 开始另一个模块。中间留出冗余,下次插入不用改别人序号。
第三,确定维护入口。SPRO 路径一般可以在 SAP NetWeaver 相关章节里找到 Fiori Launchpad 的 Customizing 节点,具体活动名称是 Define Navigation Targets 一类;但实际项目里大部分人直接用 SM30 + 视图 V_LPD_CUST 维护。两种方式本质一样,SPRO 的好处是带了文档链接,SM30 的好处是快。我推荐日常用 SM30,上线前用 SPRO 过一遍配置审查。
3.2 用 SM30 维护 V_LPD_CUST:字段填写与层级设计
现在演示一个完整例子。假设要加一个模块:工厂能耗看板外部页面。规划如下:
- 根文件夹:SEQNR=1000,FOLDER=X,ITEM_TEXT=生产运营,ROLES 留空,DEVICE_TYPE 三种都配;
- 子入口:SEQNR=1010,FOLDER 空,PARENT=1000,SEMANTIC_OBJECT=ZEnergy,SEMANTIC_ACTION=Launch,INTENT=ZEnergy-Launch,ITEM_TEXT=能耗看板,URL=https://ies.example.com/board/energy,ROLES=Z_ENERGY_VIEWER,DEVICE_TYPE 三种都配。
操作步骤:
- 进入 SM30,输入 V_LPD_CUST,点 Maintain(维护);
- 如果系统提示弹窗或维护对话框,按提示进入表内容维护界面;
- 新建一条记录,按上面字段填;
- 保存前确认 Client 是你希望生效的逻辑层(比如开发/生产配置请求);
- 保存后系统会要求生成/更新一个配置请求(Customizing Request),按公司传输规则填写;