• 单据架构—实现页面可配置化


    本篇是对以前工作中的单据架构实现做的总结,目前工作中我负责的系统也从零开始实现了这套架构功能。

    👉“单据”:金融、外贸行业术语,货运单据

    👀以前做外贸行业的SaaS软件,表单字段数量之多,没接触过的人肯定难以想象😮。现在在金融行业工作(也有物联网、互联网服务行业工作经验),觉得外贸、财务、金融行业的业务相对来说复杂度更高🎨,技术实现上也更加复杂(👉没有接触过的请先了解一下再发表意见😊)。就比如本篇要讲的表单,不是想象的几个表单字段提交那么简单,除了核心的业务数据字段还涉及到非常多的行业术语字段,整体复杂度一下子提升很多,而且单据类型多样,传统的在页面上堆字段的开发方式显然不适用了🤔。所以,就开始在基础业务架构上进行探索创新,创意需要想象力,感兴趣请看下文👇

    1、使用场景及功能

    1.1、使用场景

    可用于常见任何表单性质的页面,筛选字段组件等。

    1.2、功能

    1. 页面可配置化(整体效果)

    2. 样式排版可控制(horizontal / vertical)

    3. 增查修功能三位一体

    4. 碎片化修改

    5. 字段联动展示

    6. 字段参数预置

    7. ……

    2、前置思考

    最根本的还是组件开发,并在此基础上给组件赋能,采用自下而上的设计。

    1. 复合组件+扩展组件+自定义组件

    2. 组件开发三要素:属性、事件、方法

    3. 组件的关系:依赖、联动

    4. 数据字典:业务字段+业务字典

      • 业务字段设置: 用于配置页面需要显示的字段信息

      • 业务字典设置: 用于字段枚举值获取显示

    5. 业务组件: -> 架构

      • 相似的业务活动

      • 使用类似的数据

      • 具有通用的处理流程

      • 通用的业务目标

      • 是密切联系的组织单元

    6. 最后, 模块划分, 后端采用RESTful接口设计风格, 实现 CRUD

    3、开发流程拆解

    1. 基础控件开发(“小池子”)

      • 初始化数据填入(带入值回显): initVal()

      • 更新: updata()

      • 修改事件: change()

        • 联动数据标记: $emit(‘handleReletedFields’, xxx, xxx)
        • 修改 controlData 得值,用于收集输入值。值类型一般是字符串、数字、布尔值、数组(多选时)
      • 重置数据: reset()

      • 移除校验: initVal 方法里 执行 clearVerfy() - this.$refs.form.clearValidate()

      • 必填项校验: verifyForm() prop属性

      • 控件数据获取:

        • 获取码值配置数据 - 业务字典
        • 普通接口获取业务数据
        • vuex 存储的码值数据
      • 收集控件并暴露给收发组件使用

      • 排版样式处理

    2. 控件收发控制 (“三通”)

      • 以动态组件方式实现数据流的收发

      • 初始化数据: initData(),调用基础控件的 initVal()方法,或者 updata()方法

      • 重置数据: reset() 调用基础控件的 reset()方法

      • 提交数据: submit()

        • 调用基础控件的 verifyForm()方法验证必填项,如果没有填写,则进行滚动定位到需要填写的组件(offsetTop)
        • 控件输入值收集: 提取各个业务字段的 controlData 值,组装表单信息
      • 数据联动: handleReletedFields()

        • 调用联动控件的 initVal()方法实现数据联动
    3. 具体业务组件 (数据流“主管道”,总线)

      • 业务字段信息组装,props传递给收发控制组件

      • 提交数据: submitForm() 调用收发控制组件的 submit() 方法,拿到业务字段输入信息。

    4、控件参数(业务字段配置)

    下面是单个控件的参数配置, 🧨要实现整个页面的可配置化, 需要配置业务字段

    {
      "fieldLabel": "控件名称""showLabel": true, // 是否显示label
      "fieldName": "appId",
      "controlName": "SingleSelectDownBox",
      "controlData": "",
      "defaultValue": "",
      "defaultOptions": "",
      "localVuexDictData": true, // 控件数据是否从vuex里获取
      "remoteDictOptionsData": false, // 控件数据是否从接口里获取
      "remoteOtherApi": "", // 单独接口获取,在api里面定义的名称,采用策略模式使用
      "labelWidth": "100px",
      "rightWidth": "220px",
      "labelPosition": "right",
      "isNotNull": 0,
      "placeholder": "",
      "dictKey": "OperateTypeEnum",
      "keyCode": "dictCode",
      "controlSize": "100%",
      "column": "1",
      "readonly": false,
      "relatedFields": "platformCheckStatus=platformCheckStatus;" // 多个关联字段用;分割
      "clearable": false,
      "editable": false
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    4.1、页面业务字段配置示例

    在这里插入图片描述

    5、联动字段配置说明

    "relatedFields": "platformCheckStatus=aaa;customField=bbb"
    
    // 或者
    "relatedFields": "platformCheckStatus=platformCheckStatus;customField=customField"
    
    • 1
    • 2
    • 3
    • 4

    platformCheckStatus=aaa

    • ”=“左边的platformCheckStatus,表示当前字段要关联的字段名称,

    • ”=“右边的aaa,表示回传信息的键名,用于确定关联字段要显示的值。

    const info = {
      aaa: 'xiao',
      bbb: 'xixi',
      // platformCheckStatus: '',
      // customField: '',
    }
    this.$emit('handleReletedFields', info, this.itemData.relatedFields);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    6、字典值配置

    多用于单选、多选、级联框备选项数据,以下是字典数据结构👇

    data: [{
        "alias": "scale",
        "dictCode": 2,
        "dictItems": [
            {
                "dictItem": [],
                "dictItemCode": 1,
                "id": 512323,
                "inUse": 1,
                "itemEnName": "1-5 people",
                "itemName": "1-5人",
                "itemValue": ""
            },
            {
                "dictItem": [],
                "dictItemCode": 2,
                "id": 512324,
                "inUse": 1,
                "itemEnName": "6-10 people",
                "itemName": "6-10人",
                "itemValue": ""
            }
        ],
        "dictName": "规模",
        "id": 2,
        "moduleCode": "A001",
        "sortOrder": 0
    }]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    最后

    架构设计要遵循三个设计原则:

    1. 不多也不少 (架构都是适合当时的情况, 解决当时的问题, 重要的是不做过多设计, 这是一个陷阱)

    2. 演进式 (根据变化及时改进和调整架构)

    3. 持续性 (自身的能力也是逐步提升的, 设计的时候需要为未来改进留下一定的空间)


    我是 甜点cc

    热爱前端开发,也喜欢专研各种跟本职工作关系不大的技术,技术、产品兴趣广泛且浓厚。本号主要致力于分享个人经验总结,希望可以给一小部分人一些微小帮助。

    希望能和大家一起努力营造一个良好的学习氛围,为了个人和家庭、为了我国的互联网物联网技术、数字化转型、数字经济发展做一点点贡献。数风流人物还看中国、看今朝、看你我。

  • 相关阅读:
    CSS的伪类选择器:nth-child()
    计算机网络4小时速成:网络层,虚电路和数据包服务,ipv4,ABC类地址,地址解析协议ARP,子网掩码,ICMP忘记控制报文协议,路由选择协议,路由器
    bash例子-source进程替换、alias不生效处理
    poj1521
    MySQL驱动jar包的下载--保姆教程
    gitlab安装和使用
    抖音小店怎么运营?这五个步骤你需要知道!
    基于JavaWeb的图书售卖网站(源码+部署+LW)
    安装java编译器
    GD32F303固件库开发(13)----定时器TIM捕获PWM测量频率与占空比
  • 原文地址:https://blog.csdn.net/heyYouU/article/details/127617110