首页 > 其他分享 >逻辑升级,深度解析如何实现业务中的且或组件

逻辑升级,深度解析如何实现业务中的且或组件

时间:2024-05-20 16:43:37浏览次数:36  
标签:逻辑 const level children item key 组件 解析 节点

在业务实现的过程中,时常会出现且或关系逻辑的拼接。逻辑运算的组合使用,是实现复杂业务规则和决策支持系统的关键技术。

目前袋鼠云的指标管理平台客户数据洞察平台数据资产平台都有在使用。并且,且或组件已经在 RC 5.0 中添加到组件库,企业现在可以更加灵活地构建和实施复杂的业务规则。

file

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

前期分析

01 确定好数据结构

因为是嵌套结构,可以通过 ➕➖ 来增加层级或者数据,因此采用树形结构来存储数据。

export interface IFilterValue<T> {
  key: string;
  level?: number; // 当前节点的层级,用于判断一些按钮的展示
  type?: number; // 当前节点的条件关系,1 | 2
  rowValues?: T; // Form 节点的相关的信息(子节点无条件节点时才有)
  children?: IFilterValue<T>[]; // 子节点的信息(子节点存在条件节点时才有)
}

上述的图片的数据为:

 {
    "key": "qTipLrlUt",
    "level": 1,
    "children": [
        {
            "key": "B6Jrbqcfof",
            "type": 2,
            "level": 2,
            "children": [
                {
                    "rowValues": {
                        "condition": 1,
                        "rowPermission": ""
                    },
                    "key": "deg8x8UgZ",
                    "level": 2
                },
                {
                    "key": "_sczw_1h8H",
                    "type": 1,
                    "level": 3,
                    "children": [
                        {
                            "key": "Z5UkUPJoA",
                            "rowValues": {
                                "condition": 1,
                                "rowPermission": ""
                            },
                            "level": 3
                        },
                        {
                            "key": "MbpJILqHGx",
                            "rowValues": {
                                "condition": 1,
                                "rowPermission": ""
                            },
                            "level": 3
                        }
                    ]
                }
            ]
        },
        {
            "rowValues": {
                "condition": 1,
                "rowPermission": ""
            },
            "key": "qx6bG0o5H",
            "level": 1
        }
    ],
    "type": 1
}

02 明确每个操作按钮的实现

03 明确组件的封装

· 组件只希望实现条件节点/线条/操作按钮的展示,因此后面的组件需要作为参数 component 传入

· 组件对层级有一个控制,支持 maxLevel 来控制

· 每一次新增数据的时候,默认值需要传入 initValues

· 支持两种模式:「编辑状态」和「查看状态」

· 支持受控和非受控两种模式

组件封装

01 FilterRules

提供给用户使用的组件,实现数据的增删改查操作,可以采用受控和非受控两种模式。它接受的参数如下:

interface IProps<T> {
  value?: IFilterValue<T>;
  disabled?: boolean;
  maxLevel?: number;
  initValues: T;
  notEmpty?: { data: boolean; message?: string };
  component: (props: IComponentProps<T>) => React.ReactNode;
  onChange?: (value: IFilterValue<T> | undefined) => void;
}
export const FilterRules = <T>(props: IProps<T>) => {
  const {
    component,
    maxLevel = 5,
    disabled = false,
    notEmpty = { data: true, message: '必须有一条数据' },
    value,
    initValues,
    onChange,
  } = props;
  // 查找当前操作的节点
  const finRelationNode = (
    parentData: IFilterValue<T>,
    targetKey: string,
    needCurrent?: boolean,
  ): IFilterValue<T> | null | undefined => {};
  const handleAddCondition = (keyObj: { key: string; isOut?: boolean }) => {};
  // 增加新的数据,判断是在当前节点下新增或者新生成一个条件节点
  const addCondition = (
    treeNode: any,
    keyObj: { key: string; isOut?: boolean },
    initRowValue: T,
  ) => {};
  const handleDeleteCondition = (key: string) => {};
  // 删除节点,删除当前节点下的一条数据或者是删除一个条件节点
  const deleteCondition = (parentData: IFilterValue<T>, key: string) => {};
  // 删除一个条件节点时,更新当前数据的层级
  const updateLevel = (node: IFilterValue<T>) => {};
  // 更改条件节点的条件
  const handleChangeCondition = (
    key: string,
    type: ROW_PERMISSION_RELATION,
  ) => {};
  // 改变节点的的数据
  const handleChangeRowValues = (key: string, values: T) => {};
  return (
    <RulesController<T>
      maxLevel={maxLevel}
      disabled={disabled}
      value={value}
      component={component}
      onAddCondition={handleAddCondition}
      onDeleteCondition={handleDeleteCondition}
      onChangeCondition={handleChangeCondition}
      onChangeRowValues={handleChangeRowValues}
    />
  );
};

● 编辑情况

· 非受控组件使用

<Form form={form}>
  <Form.Item name={'condition'}>
    <FilterRules<IRowValue>
      component={(props) => (
        <RowColumnConfig columns={record?.columns ?? []} {...props} />
      )}
      maxLevel={MAX_LEVEL}
      initValues={INIT_ROW_VALUES}
    />
  </Form.Item>
</Form>;

// RowColumnConfig 实现,name 可能是 children[0].formValues
<Form.Item
  name={['condition', ...name, 'column']}
  rules={[{ message: '请选择字段', required: true }]}
  initialValue={column}
>
  <Select placeholder="请选择字段">
    {columns.map((item) => (
      <Option key={item} value={item}>
        {item}
      </Option>
    ))}
  </Select>
</Form.Item>;

// 最后通过 form.validateFields() 拿到的和上述的数据结构一致

· 受控组件使用

const [ruleData, setRuleData] = useState({
  key: shortid(),
  level: 0,
  rowValues: {
    column: first.column,
    condition: first.condition,
    rowPermission: first?.value,
  },
});

<FilterRules<IRowValue>
  value={ruleData}
  component={(props) => (
    <RowColumnConfig columns={record?.columns ?? []} {...props} />
  )}
  maxLevel={MAX_LEVEL}
  initValues={INIT_ROW_VALUES}
  onChange={setRuleData}
/>;
// 通过 ruleData 就能够拿到最后的结果

● 查看使用

<FilterRules
  component={(props) => <RowColumnConfig columns={[]} {...props} />}
  disabled
  value={value}
/>

● 编辑查看使用(后续新增)

file

上图为最后实现的效果,适用于部分数据禁用且可以编辑其他数据。常见业务情景:上一次保存的数据不可修改,但需要在当前基础上继续新增数据。

在这种使用模式下,FilterRules 组件上的 props 依旧为 false,通过设置 value 中每一个节点的 disabled 属性来实现上述功能。

// 修改 IFilterValue 的类型
// 

标签:逻辑,const,level,children,item,key,组件,解析,节点
From: https://www.cnblogs.com/DTinsight/p/18202298

相关文章

  • 深入解析xLSTM:LSTM架构的演进及PyTorch代码实现详解
    xLSTM的新闻大家可能前几天都已经看过了,原作者提出更强的xLSTM,可以将LSTM扩展到数十亿参数规模,我们今天就来将其与原始的lstm进行一个详细的对比,然后再使用Pytorch实现一个简单的xLSTM。xLSTMxLSTM是对传统LSTM的一种扩展,它通过引入新的门控机制和记忆结构来改进LSTM,旨在提......
  • lodash已死?radash库方法介绍及源码解析 —— 函数柯里化 + Number篇
    写在前面tips:点赞+收藏=学会!主页有更多其他篇章的方法,欢迎访问查看。本篇我们继续介绍radash中函数柯里化和Number相关的方法使用和源码解析。函数柯里化chain:创建一个函数链并依次执行使用说明功能描述:用于创建一个函数链,该链依次执行一系列函数,每个函数的输出......
  • 11个国内外免费域名解析服务
    11个国内外免费域名解析服务 一般域名使用注册商提供的域名解析服务虽然方便,但功能大多有限,特别是目前国内还会针对某些DNS服务器进行屏蔽,造成网站无法解析的情况出现,因此,使用第三方域名解析服务也是中国网站的必要选择,这里就介绍一些常见的免费域名解析服务。域名注册......
  • ASP.NET Core应用程序7:使用视图组件
      视图组件是类,为支持分部视图或者在父视图中注入少量Html或Json数据提供了应用程序逻辑。1准备工作  Models文件夹中添加City.cs类和CitiesData类,为CitiesData添加服务。publicclassCity{publicstringName{get;set;}publicstringCo......
  • php 异步并行后续--兼容FPM使用的组件
    上次给人推荐了这篇文章,关于PHP异步并行的文章,之后有人评论问这个组件能不能给fpm用,我测试了一下发现不行,于是又找到一个可以给fpm用的http请求组件.安装很简单,就这样  composerrequireguzzlehttp/guzzle 进行安装一下.然后代码示例如下:我们先建一个文件作为一个长......
  • 微信小程序------功能组件------轮播图
    页面结构<swiperclass="content-info-slide"indicator-color="rgba(255,255,255,.5)"indicator-active-color="#fff"indicator-dotscircularautoplay><swiper-item><imagesrc="/pages/images/test.png"......
  • XML Schema 复杂元素类型详解:定义及示例解析
    在XMLSchema(XSD)中,复杂元素是指包含其他元素和/或属性的XML元素。复杂元素可以分为四种类型:空元素:仅包含其他元素和/或属性的元素。仅包含其他元素的元素:不包含文本内容,只包含其他子元素的元素。仅包含文本的元素:不包含其他子元素,只包含文本内容的元素。既包含其他元素......
  • PyQt5 GUI编程(组件使用)
    一.简介PyQt5是一个用于创建图形用户界面(GUI)应用程序的Python绑定,它基于Qt库。PyQt5提供了大量的组件(也称为控件或部件),用于构建复杂的用户界面。以下是一些常用的PyQt5组件二.组件用法1.数字组件(QLCDNumber)classFileChooserApp(QWidget):def__init__(self):......
  • Qt学习第二篇(基本小组件的使用)
    Qt_2小部件是GUI的基本元素。它也称为UI控件。它接受来自底层平台的不同用户事件,如鼠标和键盘事件(以及其他事件)。我们使用不同的小部件创建UI。曾经有一段时间,所有的GUI控件都是从头开始编写的。Qt小部件通过开发具有现成的GUI控件的桌面GUI来缩短时间,并且Qt......
  • 项目管理案例-关于第三方公司提供的组件质量欠佳的问题
    项目管理案例-关于第三方公司提供的组件质量欠佳的问题背景     商用密码应用安全性评估(简称密评),是指按照有关法律法规和标准规范,对网络与信息系统使用商用密码技术、产品和服务的合规性、正确性、有效性进行检测分析和评估验证的活动。依据《密码法》、《商用密码管理条例......