☰ Java 复习 · C8 实战总图更新 10-13 15:41

④ Site.xml 全讲

课件 5 全部:NodeRef、Heading、Card、View、Action、Rule、Path、视图、Site.css

全部来自课件《5、前端开发 xml》48 页 + 知识库里虚拟机跑通的例子。XML 先记住三条规矩:

1 · 五个概念(课件第 4 页)

词课件原话大白话
Class系统模型一类东西的「模具」:款式、材料、BOM
NodeClass 的实例一条具体数据:HB-XXXXX 这个款
NodeRef系统模型 Class 的实例化,也是类型在 Site.xml 里「引用并扩展」一个已有对象的页面
Relationship连接两个 Class,会作为属性定义在 Class 上两类东西之间的线:款式 → 客户
Path连接 Class 之间的 Relationship顺着线走的路线,见第 9 节
NodeRef 和 Node 的区别(课件 24 页 + 知识库):原文件里的 <Node> 是完整定义(「类」);Site.xml 只写 <NodeRef>,表示「继承原来的,只加我改的部分」。不要在 Site.xml 里用 Node 覆盖整页,知识库踩过坑。

2 · NodeRef 里能放什么(课件第 5 页)

<NodeRef Type="Style">
    <Headings> … </Headings>   ← 字段(可多个)
    <Card Id="…"> … </Card>     ← 一组字段打包(可多个)
    <View Id="…"> … </View>     ← 页面/表格/标签页(可多个)
</NodeRef>

课件原话:「系统页面都是由 View XML 显示,都是基于 Node 实例。页面中显示系统的 Node 都需要使用 NodeRef。」

3 · Heading / Headings(课件第 6 页)

Heading = 显示当前对象的一个属性(或关联对象的属性);Headings = 一组 Heading。

课件里的例子,逐行

代码(一行一行)这一行在干什么
<Headings>开始一组字段
<Heading Id="__Parent__" Path="Child:Previous" Name="MerchSeason_Previous__Parent__" />显示「上一季」的父对象。Path = 顺着 Previous 这条线走过去;Name = 给这列另起名字
<Heading Id="ApparelSeason">季节字段,ref 类型,所以不自闭合
<Relationship Type="Season">它引用的是 Season(季节)对象
<Filter>下拉里只列出符合条件的季节
<Attribute ID="C8_BusinessType" Op="EQ" SValue="csi.session.getCurrentUser().C8_BusinessType" />条件:季节的业务类型 等于(EQ)当前登录用户的业务类型
</Filter>条件结束
</Relationship>
</Heading>
</Headings>一组字段结束

其他写法(同一页)

代码(一行一行)这一行在干什么
<Heading Id="Node Name" />对象名称(C8 自带字段,Id 里可以有空格)
<Heading Id="Description" />描述
<Heading Id="Subtype" />子类型
<Heading Id="LT_SpecDS_ProcessMan" Path="Child:CurrentRevision">走到「当前版本」上取这个字段——版本化对象(如 BOM)的字段常这样取

4 · Card(课件第 7 页)

Card = 一组 Heading 起个名字,多个 View 里重复用,不用每次重写。

代码(一行一行)这一行在干什么
<Node Type="Shape">(课件例子用的是 Node;我们自己写时用 NodeRef)版型对象
<Card Id="ShapeAttributes">定义一张卡,名字叫 ShapeAttributes
<Heading Id="Node Name" />卡里的字段 1:名称
<Heading Id="ShapeSeasons" />字段 2:季节
<Heading Id="ShapeSizeRange" />字段 3:尺码范围
<Heading Id="Images" />字段 4:图片
</Card>卡定义结束
<View Id="ShapeProperty" xsi:type="Property">详情页(Property 类型)
<Image Id="Images"/>放一张图
<Card Id="ShapeAttributes" />引用上面那张卡 → 四个字段全出来
</View>
<View Id="AllShapes" xsi:type="Table">列表页(Table 类型)
<Relationship Type="Shape" />列表里列的是 Shape
<Card Id="ShapeAttributes" />同一张卡又用一次 → 列表的列跟详情页一致
</View>
</Node>

5 · View 的八种类型(课件第 8 页)

xsi:type课件原话在 C8 里你见过的样子
Form创建或编辑对象的弹出框点「新建款式」弹出的表单
Html基于 HTML 模板,用于自定义视图—
PhaseTable版本化对象的工具栏BOM 页上冻结、审批那排按钮
Property节点属性点进一个款看到的详情页
SlicerExcel 数据透视表—
Table查询显示Home → Style → Styles 那个列表(AllStyles)
Tabs标签页款式页顶上「款式 / 采购 / 日历 / 产品工艺」那排
Wizard引导视图一步一步填的向导

Tabs 例子(课件第 6 页截图,逐行)

代码(一行一行)这一行在干什么
<View Id="ProductSpec" xsi:type="Tabs">款式页里「产品工艺」这个标签页,本身又是一组子标签
<DependencyPath Path="Child:ProductType/Child:ProductionConfig"/>依赖:要顺着「产品类型 → 生产配置」去判断
<ViewRef Id="ProductSpecSummary"/>子标签 1:摘要(引用别处定义好的 View)
<ViewRef Id="BOMs">子标签:BOM
<Rule Exp="module('Apparel/ProductType').hasTDS(currentNode(), 'ApparelBOM')"/>规则:只有这个款的产品类型配了 BOM 才显示这个标签
</ViewRef>
<ViewRef Id="Reviews"> … ReviewStyle …评审标签,同理:配了才显示

看懂这个,你就明白为什么同样是款式,有的显示 BOM 标签、有的不显示——是 Rule 在控制。

6 · Action:按钮(课件第 9 页)

系统自带 Action意思
Copy复制
Delete删除
Edit编辑
MoveUp / MoveDown上移 / 下移
New新建
NewFrom从……新建(复制一份再改)

课件第 14 页截图里的 Actions,逐行

代码(一行一行)这一行在干什么
<Actions>这一组按钮出现在列表的「操作」栏(课件 17 页)
<Action Id="ReplaceColorSpecifications" MaterialIcon="merge_type" PostAction="csi.action.postActionRefreshView">自定义按钮「替换颜色」;图标 merge_type;做完后刷新视图
<ViewRef Id="ColorSpecifications" />点了弹出颜色列表让你选
<Filter><Node Parameter="URL" Op="NE" Value="thisNode()" /></Filter>列表里排除自己(URL 不等于当前这条)
<Request Module="Apparel" Operation="ReplaceColorSpecifications" />选完后调用系统内置的「替换颜色」操作
</Action>
<Copy />系统自带:复制
<Delete>系统自带:删除,但加条件 ↓
<Rule Exp="attr('C8_Sync_SendStatus')=='C8_Sync_SendStatus:NOTSEND' &amp;&amp; attr('C8_Sync_DataStatus')=='C8_Sync_DataStatus:NEW'" />只有「还没发送」并且「是新数据」才允许删。&amp;&amp; 是 XML 里 &&(并且)的写法
</Delete>
</Actions>

7 · Action 的三个阶段:OnAction / PostAction(课件第 11–13 页)

阶段课件原话能挂什么
事前页面展示及用户输入,可以通过 OnAction 对数据做预先处理OnAction="Site.函数名"
事中传递请求到系统服务(系统自己做)
事后结果返回页面,可以通过 PostAction 做进一步处理PostAction="Site.函数名"

OnAction:Site.xml 和 Site.js 两边要对上

代码(一行一行)这一行在干什么
<Action OnAction="Site.onActionDoSomething" />Site.xml:点这个按钮时,去 Site.js 找 onActionDoSomething
return {Site.js 文件最后的 return 块(第 ⑤ 页讲)
onActionDoSomething : function(ac) {名字必须一模一样(课件原话:「两处的方法名定义需要保持一致」)
ac.m_writer.changeNode(ac.m_urlNode)要改的是:当前点的这一条
.changeAttribute("DateX", xml.ATTR_TIME, types.getDateTime());把日期字段 DateX 改成现在时间
ac.bRefreshNode = true;改完刷新页面
}
};

PostAction:挂在字段上

代码(一行一行)这一行在干什么
<NodeRef Type="StyleAttributes">
<Headings><Heading Id="X">字段 X
<Action PostAction="Site.postActionStyleAttributesX" />X 改完、系统处理完之后,调 Site.js 的这个函数
</Heading></Headings>
</NodeRef>
postActionStyleAttributesX: function(ac) {Site.js 里同名函数
var secondView = ac.widget.viewParent.getChildView("ViewIdOfSecondView");找到同一页上的另一个视图
if (secondView) { secondView.redraw(); }找到了就让它重画(数据刷新)
}

课件 6 补充:PostAction 里要自己提交:ac.m_writer.execute({sync:true})。

8 · Rule:条件(课件第 14 页)

属性意思
Class满足条件时套用的 CSS 样式名(非必填)→ 用来标颜色
Path表达式从哪个对象算
Exp一个表达式,结果是 true / false
Id1左边的字段
OpEQ 等于、NE 不等于、GT 大于、GE 大于等于、LT 小于、LE 小于等于
Id2 / Value右边:另一个字段,或一个固定值
代码(一行一行)这一行在干什么
<Heading Id="C8_Style_Status">款式状态字段
<Rule Class="Red" Id1="C8_Style_Status" Op="EQ" Value="C8_StyleStatus:紧急"/>状态 = 紧急 → 套用 Red 样式(标红)。注意值是 枚举名:Key 完整写法
<Rule Class="Black" Id1="C8_Style_Status" Op="EQ" Value="C8_StyleStatus:非常紧急"/>状态 = 非常紧急 → 套用 Black
</Heading>

Rule 用在三个地方:控制显示(ViewRef 里,第 5 节)、控制能不能操作(Action/Delete 里,第 6 节)、控制颜色(带 Class,第 12 节)。

9 · Path:顺着线走(课件第 4 页)

写法方向课件例子
Child:属性从我出发,沿我身上的引用字段走过去Child:__Parent__ = 去我的父对象
Parent:属性反着走:谁引用了我配色上写 Parent:ProductColors = 找到这个配色属于哪个款式
Index:n多个里取第 n 个(从 0 数)Child:ProductColors/Index:0 = 款式的第一个配色

多段用 / 连:Child:__Parent__/Child:__Parent__/Child:Category1 = 往上走两层父对象,再取 Category1。跟 Java 里 a.getParent().getParent().getCategory1() 一个意思。

10 · 表格视图 = 一条 SQL(课件第 16–34 页)

课件用 SQL 打比方,这是理解视图最好的一把钥匙:

View 里的SQL 里的
<Relationship Type="Style">FROM 款式
<Filter>WHERE …
Heading / Card 里的字段SELECT 字段1, 字段2…
一对一的关联字段(ref)LEFT JOIN
一对多的关联字段(reflist)RIGHT JOIN(只能用在 Table 视图)
<Actions>列表最右的「操作」栏

Left Join 两种方法(课件 21–27 页)

  1. 在 FROM 里加关联:Relationship 里加 <PreferencePath Path="Child:POColor/Child:ProductColor"/>,每段前加 Child:,段之间用 /
  2. 直接在 SELECT 里点过去:Heading 用 Path 取关联对象的字段,相当于 a.品类编号.品类

步骤:①找到 ref 类型的外键字段 ②把原视图定义复制进 Site.xml(用 NodeRef)③往 Relationship 里加路径 ④列名会带上路径名,去 en.js 的 "Path" 里把它清空或改中文(第 ⑥ 页)。

Right Join 一对多(课件 28–34 页)

代码(一行一行)这一行在干什么
<Heading Id="POColors" Path="…到POColors的路径" IsMatrixGroup="1" Hidden="1"/>Id = 路径上最后一个 reflist 字段;IsMatrixGroup="1" = 一对多展开;Hidden = 默认视图里不显示

前提:关联字段是 reflist / refvector。展开后每个配色一行,再往后的一对一字段按 Left Join 方法二加。

11 · ref / reflist 下拉的两种样子(课件 35–37 页)

  1. 下拉里只显示对象名称:普通 <Heading><Relationship Type="…"/></Heading>
  2. 下拉还能点「进入对话」弹出选择窗口:
    <AggregateInline>
        <ViewRef Id="SelectMaterials" URL="centric://APPAREL/Views" />   ← 弹出框用哪个视图
    </AggregateInline>

12 · Site.css:标颜色(课件 42–45 页)

整行底色

.stateGrey { background-color: #f17543; }

某个格子按条件变红,逐行

代码(一行一行)这一行在干什么
<Heading Id="C8_Order_PlanTime">订单的「计划时间」字段
<Action>谁能改这个字段 ↓
<Rule Exp="currentRoleName()=='管理员' || rightstr(currentRoleName(),5)=='材料供应商' || …" />当前角色是管理员,或角色名后 5 个字是「材料供应商」……才能改
<Rule Id1="C8_Order_Sent" Op="EQ" Value="false"/>并且「已发送」= false
</Action>
<Rule Class="C8_Order_Background-red" Exp="(nowTime() &gt; attr('C8_Order_DiaoLiaoTime')+2*86400) &amp;&amp; attr('C8_Order_PlanTime')==date(0)" />现在时间 > 调料时间 + 2 天(86400 秒 = 1 天),并且计划时间还没填 → 套红色
</Heading>
.C8_Order_Background-red { background-color: #f17543; }Site.css 里定义这个红色

表头变黄

<Heading Id="C8_MerchFD_MaxSKU" Class="Merchandise-alert"> … </Heading>
.tableView>thead>tr>th.Merchandise-alert { background-color: #fff798; }

13 · 虚拟机里验证过的完整例子:列表每行加「审核通过」按钮 已验证 08-05

知识库确认的挂载路径(之前试过别的路径按钮不出现):

NodeRef Type="_CS_ApparelViews"
└─ View Id="AllStyles" xsi:type="Table"
   └─ Relationship Type="Style"
      └─ Actions
代码(一行一行)这一行在干什么
<NodeRef Type="_CS_ApparelViews">引用「服装视图集合」这个系统对象(AllStyles 列表定义在它下面)
<View Id="AllStyles" xsi:type="Table">Home → Style → Styles 那个列表
<Relationship Type="Style">列表的每一行是 Style
<Actions>每行的操作按钮
<Action一个按钮开始
Id="C8_ReviewApproval"按钮 Id,同时是 en.js 的翻译 Key
Type="Style"每行操作的对象是 Style
MaterialIcon="done"图标:打勾
Control="Icon"以图标形式显示
OnAction="Site.C8_onActionReviewApproval"点了调 Site.js 的这个函数
/>按钮结束(自闭合)
</Actions>
</Relationship>
</View>
</NodeRef>

结果:按钮出现在每行末尾「三个点」菜单里;没翻译时显示 C8_ReviewApproval,en.js 保存 + Update 后显示「审核通过」。

← ③ 四个厂对比⑤ Site.js 全讲 →

出处:带教同事《箱包属性信息整理 V1.0》、H厂.zip、会议纪要 10-08、课件 5《前端开发 xml》、课件 6《js》、知识库 C8配置规则_7.8.1。