9.1. 公共业务组件
9.1.1. 字段钻取组件(DrillComponent
)
简介
钻取组件用于业务对象查找与当前对象关联的字段信息的组件,可以通过参数控制向上还或向下查找关联字段,并且可以通过关系字段继续查找与之关联的字段信息。
参数
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
title | 自定义弹窗标题 | string 或 ReactElement | - |
renderer | 组件自定义渲染 | `Function: (arg: { drillText: string }) => string | ReactElement` |
onOk | 弹窗关闭回调,自己去写前端回写的逻辑 | Function: (params) => void; | - |
onClear | 弹窗关闭回调 | Function: () => void; | - |
initValue | 后端返回的初始值 | - | |
isWriteBack | 是否需要回写 | boolean | true |
curFieldCode | 当前字段的code,用于排除当前字段(不可选)取 businessObjectFieldCode | string | - |
readOnly | 是否只读(默认false) | boolean | false |
getInitRes | 初始化获取字段信息 | Function: (res) => void; | - |
drillMainKeyType | 是否钻取主键 | 枚举类型 EDrillMainKeyType,可选择 none 不钻取主键;all 全部钻取主键;exclude_first 除了第一层外其余均钻取主键 | none |
drillSet | 是否开始钻取集合 默认不开启钻取单值或对象 | boolean | false |
drillDownFlag | 控制是否向下钻取 默认是false | boolean | false |
componentTypeList | 前端自定义钻取参数 拼接到drill接口路径后 | - | |
initDrillParams | 初始化时钻取接口需要添加的查询参数 拼接在接口后 | [propName: string]: any; | - |
getReferenceInfo | 初始化掉解析接口reference-info后的回调 参数为解析接口返回值 | - | |
selectObjectCheckFlag | 选择对象后,是否需要校验下一个框有没有选择 默认不校验可以只选对象保存 | boolean | false |
onChange | 选中下拉选项的回调 | Function: (res) => void; | - |
showTooltip | 是否展示悬浮提示 | boolean | true |
drillPublishType | 是否钻取已发布字段 | none : 不钻取拟定态(只钻取发布态)all : 全部钻取拟定态exclude_first : 第一层不钻取,其余钻取only_first : 第一层钻取拟定态和发布态,其余钻取发布态 | none |
excludeComponentTypeList | 下拉选项中需要排除显示的字段的类型 (componentType) | string[] | [] |
placeholder | 提示文字 | string | 请选择 |
excludeFieldList | 排除的字段(code)集合 拼接到drill接口路径后 | string[] | [] |
excludeFieldListLevel | 需要排除字段(code)集合的层级 不传默认所有层级 | `undefined | number |
使用
import React, {useMemo, useState} from 'react';
import {Header, Content} from 'components/Page';
import {Button, DataSet, Form, Output} from 'choerodon-ui/pro';
import {FieldType} from 'choerodon-ui/pro/lib/data-set/enum';
import {DataSetProps} from 'choerodon-ui/pro/lib/data-set/DataSet';
import DrillComponent from '@apaas/businessComponents/DrillComponent';
import {ButtonColor} from 'choerodon-ui/pro/lib/button/enum';
const demo = () => {
const [value, setValue] = useState('');
const drillRenderer = () => {
return (
<DrillComponent
onOk={handleOk}
text={value}
businessObjectCode="=xCdh0kUeLzhOhEHxu_zUD0t6woOxZImbQ5QnzCkPyLI=="
/>
);
};
const demoDs = useMemo(() => {
return new DataSet({
autoCreate: true,
fields: [
{
name: 'drill-1',
type: FieldType.string,
label: '钻取 - 自定义渲染',
},
{
name: 'drill',
type: FieldType.string,
label: '钻取 - 初始',
},
],
} as DataSetProps);
}, []);
/**
* 弹窗关闭回调
* @param dataSet 当前钻取组件的dataSet
*/
const handleOk = (dataSet) => {
// demo测试的log
console.log(
'字段选择的数据',
dataSet?.current?.toData(),
'获取某个字段的下拉框options',
dataSet?.current?.getField('1')?.options?.toData()
);
// 设置前端显示的值
setValue('前端显示的值');
demoDs?.current?.set('drill', '传给后端的值');
};
const handleSave = () => {
console.log('传给后端的值', demoDs?.current?.toData());
};
return (
<>
<Header title="钻取">
<Button onClick={handleSave} color={ButtonColor.primary}>保存</Button>
</Header>
<Content>
<Form dataSet={demoDs} labelWidth={200} columns={3}>
<Output name='drill' renderer={drillRenderer} />
</Form>
</Content>
</>
);
};
export default demo;
页面效果
9.1.2. 关系透视图组件(RelationalPivot
)
简介
关系透视图公用组件用于统一展示关系透视图的样式,包括透视图的标题、Tabs 、弹框样式等。通过定义不同模板组件的形式进行交叉引用。
参数
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
modules | 需要展示的模板 | Record<RelationalModule.KEY, ModuleProps>[] | - |
modal(可选) | 弹框传入的实例 | modalChildrenProps | - |
otherProps(可选) | 需要传入到每个子模板的参数 | any | - |
navs(可选) | 渲染面包屑 | string[] | - |
使用
Modal.open({
children: (
<RelationalPivot
modules={[
{
[RelationalModule.SCRIPT_EVENT]: {
targetKey: "123",
}, // 引用脚本事件的模板
},
]}
otherProps={{name: 'aPaaS'}}
navs={["业务对象-XXX对象", "业务对象-XXX字段"]}
/>
),
});
弹框样式
弹框样式分为默认属性
(可被外部 modal 传参覆盖)和共用属性
(不可覆盖)。一般情况下 modal 参数只需要传 title
和 children
即可。
默认属性
参数 | 类型 | 默认值 |
---|---|---|
title | string | 依赖查询 |
bodyStyle | React.CSSProperties | { height: 600 } |
style | React.CSSProperties | { width: 957 } |
共用属性
参数 | 类型 | 默认值 |
---|---|---|
closable | boolean | true |
cancelText | string | 关闭 |
destroyOnClose | boolean | true |
footer | (okBtn, cancelBtn, modal) => ReactNode | (_, cancelBtn) => {cancelBtn} |
如果需要修改共用属性
,请提出需求后再统一修改。
新增一个模板流程
- 维护模块的 key 值,在
constants/code.ts
下RelationalModule
变量新增一个 key。 - 维护模块的名称,在
constants/code.ts
下RelationalModuleMeans
变量新增一个对应 key 的名称。 - 维护模块组件所需的类型, 在
types/relationPivot.ts
新增模块组件的类型。 - 把新增模块类型,维护进
RelationalPivot
组件的modules
类型中。 - 新增一个模块组件,强制要求
模块组件的 Props 类型继承自上面新增模块的类型
。
9.1.3. 用户指引组件(Intro
)
简介
基于 intro.js
封装的用户指引组件,用于引导用户操作。
基础指引演示
Intro
组件必须接收一个 introJs.Step
类型的数组,数组中的每一项都是一个指引步骤。
待指引元素需要和 steps
中的 element
对应,element
可以是一个 string
类型的选择器,也可以是一个 HTMLElement
类型的元素。
参数
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
steps | 指引步骤 | introJs.Step[] | - |
onExit | 监听指引退出 | Function | - |
options(可选) | 指引配置项 | introJs.Options | - |
initialStep(可选) | 初始化时的所在步骤 | number | 0 |
onBeforeExit(可选) | 监听指引退出前,返回 false 阻止指引弹窗关闭 | () => boolean ⎮ void | - |
onChange(可选) | 监听每次步骤变化 | (element: HTMLElement) => any | - |
onBeforeChange(可选) | 监听每次步骤变化前 | (element: HTMLElement) => any | - |
onAfterChange(可选) | 监听每次步骤变化后 | (element: HTMLElement) => any | - |
onComplete(可选) | 监听步骤完成后 | Function | - |
9.1.4. 操作符系列组件
Operator
操作符组件
简介
用于根据业务对象、事务流出入参、系统变量、表达式的类型渲染不同的操作符组件。
接口请求说明
- 默认点击操作符组件才会触发接口请求,可通过
isAllRequestByQueryParams
配置调整为随参数变化而请求。 - 操作符接口请求带缓存效果,如果传参仅为
componentType
,则为永久缓存,其余缓存时间为 5 分钟。 - 回显初始化时尽可能不调接口,如遇到下拉、Lov、引用等必须要有数据源的类型,则会必须调接口。
使用
操作符组件必须搭配 DataSet
进行使用,需要在DataSet
的 fields
字段中配置一个字段用于绑定操作符。例:
import {FieldType} from 'choerodon-ui/pro/lib/data-set/enum';
enum FN {
operatorType = 'operatorType'
}
const demoDS = ()=> ({
// ... 忽略其他 DataSet 配置
fields: [
{
name: FN.operatorType,
type: FieldType.string,
}
]
})
定义好DataSet
配置之后,直接在组件中进行绑定。确定好接口查询参数的数据( queryParams
字段)。例:
import { Select, useDataSet, Form } from 'choerodon-ui/pro';
import {FieldType} from 'choerodon-ui/pro/lib/data-set/enum';
enum FN {
operatorType = 'operatorType'
}
const Demo = ({businessObjectCode,businessObjectFieldCode})=>{
const dataSet = useDataSet(()=>({
fields: [
{
name: FN.operatorType,
type: FieldType.string,
}
]
}),[]);
return (
<Form
dataSet={dataSet}
>
<Operator
record={dataSet.current}
name={FN.operatorType}
queryParams={{
boQuery: {
businessObjectCode,
businessObjectFieldCode,
},
}}
fillComponentType
/>
</Form>
)
}
如果 record 允许存储 componentType
字段,推荐使用 fillComponentType
配置,会有利于优化接口缓存,减少接口请求次数。
参数
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
record | DataSet 单条记录 | DataSet | - |
name | DataSet 的 fields 中配置的名称 | string | - |
queryParams | 操作符查询参数 | OperatorQueryParams ⎮ null | - |
fillComponentType(可选) | 是否在 record 上回填 componentType 参数 | boolean ⎮ string | - |
isAllRequestByQueryParams(可选) | 查询参数变化是否都需要请求接口 | boolean | - |
OperatorQueryParams
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
componentType(可选) | 操作符组件类型(参照 OperatorComponentType ) | string ⎮ null | - |
formula | 系统变量或无法确定返回类型的表达式 | string ⎮ null | - |
boQuery | 业务对象查询参数 | 参考下面示例 | - |
{
// businessObjectCode 或 businessObjectId 必传其一
businessObjectCode?: string;
businessObjectId?: string;
// businessObjectFieldCode 或 businessObjectFieldId 必传其一
businessObjectFieldCode?: string;
businessObjectFieldId?: string;
// 以下选填
draftFieldFlag?: boolean; // 是否是拟定态
includeValueCount?: string; // 指定操作符
}
OperatorDynamicComponent
操作符动态渲染固定值组件
简介
根据组件类型和选择的操作符动态渲染固定值组件。
使用
操作符组件必须搭配 DataSet
进行使用,需要在DataSet
的 fields
字段中配置一个字段用于绑定操作符。而且该字段无需多余配置,例:
import {FieldType} from 'choerodon-ui/pro/lib/data-set/enum';
enum FN {
value = 'value'
}
const demoDS = ()=> ({
// ... 忽略其他 DataSet 配置
fields: [
{
name: FN.value,
type: FieldType.auto,
}
]
})
定义好DataSet
配置之后,直接在组件中进行绑定。确定好接口查询参数的数据( queryParams
字段)。如果使用了操作符(Operator)组件,则 queryParams
参数两个组件需保持一致。
import { Select, useDataSet, Form } from 'choerodon-ui/pro';
import {FieldType} from 'choerodon-ui/pro/lib/data-set/enum';
enum FN {
operatorType = 'operatorType',
value = 'value'
}
const Demo = ({businessObjectCode,businessObjectFieldCode})=>{
const operatorQueryParams = {
boQuery: {
businessObjectCode,
businessObjectFieldCode,
},
}
const dataSet = useDataSet(()=>({
fields: [
{
name: FN.operatorType,
type: FieldType.string,
},
{
name: FN.value,
type: FieldType.auto,
},
{
name: FN.componentType,
type: FieldType.string,
}
]
}),[]);
return (
<Form
dataSet={dataSet}
>
<Operator
record={dataSet.current}
name={FN.operatorType}
queryParams={operatorQueryParams}
fillComponentType
/>
<OperatorDynamicComponent
record={dataSet.current}
name={FN.value}
queryParams={operatorQueryParams}
componentType={dataSet.current?.get(FN.COMPONENT_TYPE)}
selectedOperator={dataSet.current?.get(FN.OPETATOR_TYPE)}
lovDisplayName="constantLovDisplayName"
isRangeValue
/>
</Form>
)
}
参数
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
record | DataSet 单条记录 | DataSet | - |
name | DataSet 的 fields 中配置的名称 | string | - |
queryParams | 操作符查询参数 | OperatorQueryParams ⎮ null | - |
selectedOperator | 已选择的操作符 | FieldOperatorType ⎮ null | - |
componentType | 组件类型 | OperatorComponentType ⎮ null | - |
lovDisplayName | 用于在 record 上存储 lov 的显示字段 | string | - |
onComponentNameChange(可选) | 渲染的动态组件类型发生变化的回调 | (name: OperatorDynamicComponentType ⎮ null) => void | - |
isRangeValue(可选) | 介于组件类型是否额外存储在 record 的 rangeValue 字段中 | boolean | - |
扩展:在事务流中,动态生成 queryParams 方案
操作符固定值组件会经常与自定义变量、入参、节点结果、来源数据、当前循环变量、系统变量和表达式这些公共组件一起搭配使用。
以下提供一个方便生成 queryParams 的示例。
例如在选择变量类型的时候,可能会出现多种选项,根据不同选项选择了变量以后,需要动态生成 queryParams
。
主要分为3种情况:
表达式
选择表达式可能会出现2种情况,一种是有返回值类型,一种是无返回值类型。
- 针对有返回值类型的情况,一般返回值类型会存储在
componentType
字段中,可以直接把componentType
值传给queryParams
。 - 针对无返回值类型的情况,则直接把表达式内容,以
formula
参数传给queryParams
。
- 针对有返回值类型的情况,一般返回值类型会存储在
系统变量
直接把选择系统变量的值,以formula
参数传给queryParams
。自定义变量、入参、节点结果、来源数据、当前循环变量等公共组件
以上所有的公共组件都会有一个
onRenderTreeNodeChange
属性,当公共组件选项内容渲染会触发该回调。该方法的入参会包含该选项下所有的选项树形 ReactNode 数据结构。 可以从该数据结构中根据选择的变量筛选出业务数据部分,再把业务数据部分作为queryParams
的参数。 例:<NodeResultTreeSelect
//...其余参数
onRenderTreeNodeChange={(treeNode) => {
// 只有在节点树形结构数据发生变化时才处理
if (
treeNode &&
!isEqual(toJS(record.getState(RecordState.variableTreeNode)), treeNode)
) {
// 在 record 上使用 state 存储树形节点结构
record.setState(RecordState.variableTreeNode, treeNode);
}
}}
/>
生成 queryParams
示例:
const [operatorQueryParams, setOperatorQueryParams] = useState<null | OperatorQueryParams>(null);
useEffect(() => {
// 变量类型
const leftvalueType = record.get(FN.LEFT_VALUE_TYPE);
// 变量
const leftValue = record.get(FN.LEFT_VALUE);
// 1. 从表达式(含返回类型)中获取
if (leftvalueType === EXPRESSION) {
// 组件类型
const componentType = record.get(FN.COMPONENT_TYPE);
setOperatorQueryParams(getOperatorQueryParamsByExpress(curRecord.get(FN.COMPONENT_TYPE)));
} else if (leftvalueType === SYSTEM_VARIABLE) {
setOperatorQueryParams(getOperatorQueryParamsBySystemVariable(leftValue))
} else if ([CURRENT_LOOP_DATA, NODE_RESULT, INPUT_PARAM, CUSTOM_VARIABLE].includes(leftValueType)) {
const variableTreeNode = toJS(curRecord.getState(RecordState.variableTreeNode));
if (variableTreeNode) {
const item = findTreeNodeTargetItem(variableTreeNode, leftValue);
setOperatorQueryParams(getOperatorQueryParamsByLoopData(item));
}
}else {
setOperatorQueryParams(null);
}
}, [
record.get(FN.LEFT_VALUE_TYPE),
record.get(FN.LEFT_VALUE),
record.get(FN.COMPONENT_TYPE),
record.getState(RecordState.variableTreeNode)
]);
这里提供了一些公共方法,用于从业务数据转为 queryParams
。
getOperatorQueryParamsByNodeResult
: 从节点结果中获取操作符查询参数getOperatorQueryParamsByInputAndCustomParam
: 从入参/自定义变量中获取查询参数getOperatorQueryParamsByExpress
: 从表达式中获取操作符查询参数getOperatorQueryParamsBySystemVariable
: 从系统变量中获取操作符查询参数getOperatorQueryParamsByLoopData
: 获取当前循环主数据查询参数(目前汇总入参/自定义变量/节点结果三种情况)