ToB企服应用市场:ToB评测及商务社交产业平台

标题: 逻辑升级,深度剖析如何实现业务中的且或组件 [打印本页]

作者: 莫张周刘王    时间: 2024-5-20 23:43
标题: 逻辑升级,深度剖析如何实现业务中的且或组件
在业务实现的过程中,时常会出现且或关系逻辑的拼接。逻辑运算的组合使用,是实现复杂业务规则和决议支持系统的关键技能。
目前袋鼠云的指标管理平台客户数据洞察平台数据资产平台都有在使用。并且,且或组件已经在 RC 5.0中添加到组件库,企业现在可以更加机动地构建和实施复杂的业务规则。

本文将从前期分析、组件封装、具体实现三个维度深入探究如何实现业务中的且或组件
前期分析

01 确定好数据结构

因为是嵌套结构,可以通过 ➕➖ 来增长层级大概数据,因此采用树形结构来存储数据。
  1. export interface IFilterValue<T> {
  2.   key: string;
  3.   level?: number; // 当前节点的层级,用于判断一些按钮的展示
  4.   type?: number; // 当前节点的条件关系,1 | 2
  5.   rowValues?: T; // Form 节点的相关的信息(子节点无条件节点时才有)
  6.   children?: IFilterValue<T>[]; // 子节点的信息(子节点存在条件节点时才有)
  7. }
复制代码
上述的图片的数据为:
  1. {
  2.     "key": "qTipLrlUt",
  3.     "level": 1,
  4.     "children": [
  5.         {
  6.             "key": "B6Jrbqcfof",
  7.             "type": 2,
  8.             "level": 2,
  9.             "children": [
  10.                 {
  11.                     "rowValues": {
  12.                         "condition": 1,
  13.                         "rowPermission": ""
  14.                     },
  15.                     "key": "deg8x8UgZ",
  16.                     "level": 2
  17.                 },
  18.                 {
  19.                     "key": "_sczw_1h8H",
  20.                     "type": 1,
  21.                     "level": 3,
  22.                     "children": [
  23.                         {
  24.                             "key": "Z5UkUPJoA",
  25.                             "rowValues": {
  26.                                 "condition": 1,
  27.                                 "rowPermission": ""
  28.                             },
  29.                             "level": 3
  30.                         },
  31.                         {
  32.                             "key": "MbpJILqHGx",
  33.                             "rowValues": {
  34.                                 "condition": 1,
  35.                                 "rowPermission": ""
  36.                             },
  37.                             "level": 3
  38.                         }
  39.                     ]
  40.                 }
  41.             ]
  42.         },
  43.         {
  44.             "rowValues": {
  45.                 "condition": 1,
  46.                 "rowPermission": ""
  47.             },
  48.             "key": "qx6bG0o5H",
  49.             "level": 1
  50.         }
  51.     ],
  52.     "type": 1
  53. }
复制代码
02 明确每个使用按钮的实现

03 明确组件的封装

· 组件只希望实现条件节点/线条/使用按钮的展示,因今后面的组件需要作为参数 component 传入
· 组件对层级有一个控制,支持 maxLevel 来控制
· 每一次新增数据的时候,默认值需要传入 initValues
· 支持两种模式:「编辑状态」和「查看状态」
· 支持受控和非受控两种模式
组件封装

01 FilterRules

提供给用户使用的组件,实现数据的增删改查使用,可以采用受控和非受控两种模式。它担当的参数如下:
  1. interface IProps<T> {
  2.   value?: IFilterValue<T>;
  3.   disabled?: boolean;
  4.   maxLevel?: number;
  5.   initValues: T;
  6.   notEmpty?: { data: boolean; message?: string };
  7.   component: (props: IComponentProps<T>) => React.ReactNode;
  8.   onChange?: (value: IFilterValue<T> | undefined) => void;
  9. }
复制代码
  1. export const FilterRules = <T>(props: IProps<T>) => {
  2.   const {
  3.     component,
  4.     maxLevel = 5,
  5.     disabled = false,
  6.     notEmpty = { data: true, message: '必须有一条数据' },
  7.     value,
  8.     initValues,
  9.     onChange,
  10.   } = props;
  11.   // 查找当前操作的节点
  12.   const finRelationNode = (
  13.     parentData: IFilterValue<T>,
  14.     targetKey: string,
  15.     needCurrent?: boolean,
  16.   ): IFilterValue<T> | null | undefined => {};
  17.   const handleAddCondition = (keyObj: { key: string; isOut?: boolean }) => {};
  18.   // 增加新的数据,判断是在当前节点下新增或者新生成一个条件节点
  19.   const addCondition = (
  20.     treeNode: any,
  21.     keyObj: { key: string; isOut?: boolean },
  22.     initRowValue: T,
  23.   ) => {};
  24.   const handleDeleteCondition = (key: string) => {};
  25.   // 删除节点,删除当前节点下的一条数据或者是删除一个条件节点
  26.   const deleteCondition = (parentData: IFilterValue<T>, key: string) => {};
  27.   // 删除一个条件节点时,更新当前数据的层级
  28.   const updateLevel = (node: IFilterValue<T>) => {};
  29.   // 更改条件节点的条件
  30.   const handleChangeCondition = (
  31.     key: string,
  32.     type: ROW_PERMISSION_RELATION,
  33.   ) => {};
  34.   // 改变节点的的数据
  35.   const handleChangeRowValues = (key: string, values: T) => {};
  36.   return (
  37.     <RulesController<T>
  38.       maxLevel={maxLevel}
  39.       disabled={disabled}
  40.       value={value}
  41.       component={component}
  42.       onAddCondition={handleAddCondition}
  43.       onDeleteCondition={handleDeleteCondition}
  44.       onChangeCondition={handleChangeCondition}
  45.       onChangeRowValues={handleChangeRowValues}
  46.     />
  47.   );
  48. };
复制代码
● 编辑情况
· 非受控组件使用
  1. <Form form={form}>
  2.   <Form.Item name={'condition'}>
  3.     <FilterRules<IRowValue>
  4.       component={(props) => (
  5.         <RowColumnConfig columns={record?.columns ?? []} {...props} />
  6.       )}
  7.       maxLevel={MAX_LEVEL}
  8.       initValues={INIT_ROW_VALUES}
  9.     />
  10.   </Form.Item>
  11. </Form>;
  12. // RowColumnConfig 实现,name 可能是 children[0].formValues
  13. <Form.Item
  14.   name={['condition', ...name, 'column']}
  15.   rules={[{ message: '请选择字段', required: true }]}
  16.   initialValue={column}
  17. >
  18.   <Select placeholder="请选择字段">
  19.     {columns.map((item) => (
  20.       <Option key={item} value={item}>
  21.         {item}
  22.       </Option>
  23.     ))}
  24.   </Select>
  25. </Form.Item>;
  26. // 最后通过 form.validateFields() 拿到的和上述的数据结构一致
复制代码
· 受控组件使用
  1. const [ruleData, setRuleData] = useState({
  2.   key: shortid(),
  3.   level: 0,
  4.   rowValues: {
  5.     column: first.column,
  6.     condition: first.condition,
  7.     rowPermission: first?.value,
  8.   },
  9. });
  10. <FilterRules<IRowValue>
  11.   value={ruleData}
  12.   component={(props) => (
  13.     <RowColumnConfig columns={record?.columns ?? []} {...props} />
  14.   )}
  15.   maxLevel={MAX_LEVEL}
  16.   initValues={INIT_ROW_VALUES}
  17.   onChange={setRuleData}
  18. />;
  19. // 通过 ruleData 就能够拿到最后的结果
复制代码
● 查看使用
  1. <FilterRules
  2.   component={(props) => <RowColumnConfig columns={[]} {...props} />}
  3.   disabled
  4.   value={value}
  5. />
复制代码
● 编辑查看使用(后续新增)

上图为最后实现的结果,适用于部门数据禁用且可以编辑其他数据。常见业务情景:上一次生存的数据不可修改,但需要在当前底子上继承新增数据。
在这种使用模式下,FilterRules 组件上的 props 依旧为 false,通过设置 value 中每一个节点的 disabled 属性来实现上述功能。
[code]// 修改 IFilterValue 的类型//
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4